さびのオーディオサンプルレート変換ライブラリ。
このライブラリは、チャンクでオーディオを処理するための再サンプラーを提供します。
入力と出力のサンプルレートの比率は完全に無料です。可変長さの出力を返しながら固定された長さの入力を受け入れる実装が利用可能であり、その逆も同様です。
Rubatoは、[Resampler]を事前に配置し、処理を開始する前にinput_buffer_allocateとoutput_buffer_alocateメソッドを使用して、処理中に割り当てなしでリアルタイムアプリケーションで使用できます。ログ機能は、リアルタイム使用のために無効にする必要があります(デフォルトでは無効になります)。
入力データと出力データは、非インテリア形式で保存されます。
入力データと出力データ&[AsRef<[f64]>]
&[AsRef<[f32]>]
参照のスライスとして保存されます。内部参照( AsRef<[f32]>
またはAsRef<[f64]>
)は、それぞれ1つのチャネルのサンプル値を保持します。
通常のベクトルはAsRef
特性を実装するため、 Vec<Vec<f32>>
およびVec<Vec<f64>>
入力と出力の両方に使用できます。
非同期再サンプラーは、アンチエイリアシングフィルターの有無にかかわらず利用できます。
アンチアリアシングによる再サンプリングは、SINC補間フィルターを使用したバンド制限補間に基づいています。 SINCの補間は調整可能な係数による補助をし、新しいサンプルポイントはこれらのポイント間の補間によって計算されます。再サンプリング比はいつでも更新できます。
アンチアリアシングなしの再サンプリングは、CPUが多いSINC補間を省略します。これははるかに速く実行されますが、より低い品質の結果が生成されます。
同期再サンプリングはFFTを介して実装されます。データはfft:ed、スペクトルの変更され、逆fft:ed:再サンプリングされたデータを取得します。このタイプの再サンプラーはかなり高速ですが、再サンプリング比の変更をサポートしていません。
このライブラリが提供する再サンプラーは、チャンクでオーディオを処理することを目的としています。最適なチャンクサイズはアプリケーションによって決定されますが、数百から数千のフレームの間に登場する可能性があります。これにより、効率とメモリの使用量の間に良い妥協が得られます。
Resampler::process_into_buffer()
メソッドを使用する場合、Rubatoはリアルタイムアプリケーションに適しています。これにより、出力は事前に割り当てられた出力バッファーに保存され、スレッドをブロックする可能性のある割り当てやその他の操作を実行しません。
既知の長さのオーディオクリップを新しいサンプルレートに再サンプリングするための推奨される簡単なプロセスは次のとおりです。ここでは、ソースデータはVECまたは一度に任意の数のフレームの読み取りをサポートする他の構造に保存されていると想定されています。簡単にするために、出力は再サンプリング中に一時的なバッファーに保存され、その後目的地にコピーされます。
準備:
Resampler::output_delay()
を呼び出して、Resamplerが与える遅延のフレーム数を知ります。番号をdelay
として保存します。new_length = original_length * new_rate / original_rate
として計算します。今度は、繰り返しプロセスコールでクリップの大部分を処理する時が来ました。ループ:
Resampler::input_frames_next()
を呼び出して、Resamplerの必要なフレームの数を学習します。Resampler::process()
またはResampler::process_into_buffer()
を呼び出します。次のステップは、最後の残りのフレームを処理することです。
Resampler::process_partial()
またはResampler::process_partial_into_buffer()
を呼び出します。この時点で、すべてのフレームが再サンプラーに送信されていますが、再サンプラーを介した遅延のため、内部バッファにいくつかのフレームがある場合があります。すべての必要なフレームが生成された場合、一時的な出力バッファーの長さは少なくともnew_length + delay
なければなりません。そうでない場合は、 Resampler::process_partial()
またはResampler::process_partial_into_buffer()
をNone
として呼び出し、出力を一時出力バッファーに追加します。必要に応じて、長さが十分になるまで繰り返します。
最後に、データを一時的な出力バッファーから目的の宛先にコピーします。最初のdelay
フレームをスキップし、 new_length
フレームをコピーします。
同じサンプルレートから往復するクリップが複数ある場合は、同じ再サンプラーを再利用する必要があります。新しい再サンプラーを作成することは高価な作業であり、可能であれば避ける必要があります。最初から手順を開始しますが、新しいResamplerを作成する代わりに、既存のジョブにResampler::reset()
を呼び出して、新しいジョブに向けて準備します。
ストリームを再sampする場合、プロセスは通常リアルタイムで実行され、出力の入力は、特定のレートでフレームを提供または消費するAPIです。
MACOS上のCoreaudioなどのオーディオAPI、またはクロスプラットフォームCPALクレートは、データ交換にコールバック関数を使用することがよくあります。
完全
これらからオーディオをキャプチャするとき、アプリケーションはオーディオAPIに関数を渡します。次に、APIはこの関数を定期的に呼び出し、新しいオーディオフレームを含むデータバッファーへのポインターを使用します。データバッファサイズは通常、すべての呼び出しで同じですが、APIによって異なります。これにより、APIの内部ループがブロックされ、一部のオーディオデータが失われるため、関数がブロックされないことが重要です。コールバックファンクションライトを保持することをお勧めします。理想的には、APIが提供するバッファーから提供されたオーディオデータを読み取り、オプションでサンプル形式変換などの軽い処理を実行する必要があります。ここでは、再サンプリングなどの重度の処理を実行する必要はありません。次に、オーディオデータを共有バッファーに保存する必要があります。バッファーはArc<Mutex<VecDeque<T>>>
、またはRingBufなどのより高度なものである場合があります。
メインまたは個別のスレッドで実行される別のループは、そのバッファーから読み取り、リサンプし、ファイルに保存する必要があります。オーディオAPIが固定バッファサイズを提供する場合、この数のフレームは再サンプラーチャンクサイズに適しています。サイズが異なる場合、共有バッファを使用して、オーディオAPIと再サンプラーのチャンクサイズを適応させることができます。再サンプラーチャンクサイズの良い出発点は、オーディオAPIの平均チャンクサイズの近くで「簡単な」値を使用することです。共有バッファーが、ディスクアクセスのためにループの場合に備えていっぱいにならないように十分に大きいことを確認してください。
ループは、クリップの再サンプリングと同様のプロセスに従う必要がありますが、入力は共有バッファになります。ループは、必要な数のフレームがバッファーで使用可能になるのを待つ必要があります。
また、一時的な出力バッファーを省略し、出力を宛先に直接書き込むことも適切です。ハウンドクレートは、非圧縮オーディオ形式を読み書きするための人気のある選択肢です。
非同期再サンプラーは、X86_64およびAARCH64でSIMDをサポートします。 CPUのSIMD機能は、実行時に決定されます。サポートされているSIMD命令セットが利用できない場合、スカラーの実装に戻ります。
x86_64では、AVXを使用しようとします。 AVXが利用できない場合、代わりにSSE3を試してみます。
Aarch64(64ビットアーム)では、利用可能な場合はNeonを使用します。
同期再サンプラーは、RustfftライブラリのSIMDサポートの恩恵を受けます。
fft_resampler
:FFTベースの同期再サンプラーを有効にしますこの機能はデフォルトで有効になっています。コンパイル時間を節約し、結果のバイナリサイズを縮小するために、FFTの再サンプラーが必要ない場合は無効にします。
log
:ロギングを有効にしますこの機能により、 log
クレートを介してロギングできます。これは、デバッグ目的を目的としています。ログの出力は[std :: string :: string]を割り当てることに注意してください。ほとんどのロギングの実装には、他のさまざまなシステム呼び出しが含まれます。これらの呼び出しは、返されるのに少し(予測不可能な)時間がかかる場合があり、その間にアプリケーションがブロックされます。これは、このライブラリをリアルタイムアプリケーションで使用する場合は、ロギングを避ける必要があることを意味します。
log
機能は、テストを実行するときに有効にすることができます。これは、デバッグ時に非常に便利です。ロギングレベルは、 RUST_LOG
環境変数を介して設定できます。
例:
RUST_LOG=trace cargo test --features log
44100〜48000 Hzのダミーオーディオファイルの単一のチャンクをリサンプします。ディスクからファイルを処理するために使用できる「process_f64」の例も参照してください。
use rubato :: { Resampler , SincFixedIn , SincInterpolationType , SincInterpolationParameters , WindowFunction } ;
let params = SincInterpolationParameters {
sinc_len : 256 ,
f_cutoff : 0.95 ,
interpolation : SincInterpolationType :: Linear ,
oversampling_factor : 256 ,
window : WindowFunction :: BlackmanHarris2 ,
} ;
let mut resampler = SincFixedIn :: < f64 > :: new (
48000 as f64 / 44100 as f64 ,
2.0 ,
params ,
1024 ,
2 ,
) . unwrap ( ) ;
let waves_in = vec ! [ vec! [ 0.0f64 ; 1024 ] ; 2 ] ;
let waves_out = resampler . process ( & waves_in , None ) . unwrap ( ) ;
examples
ディレクトリには、再サンプラーをテストするためのいくつかのサンプルアプリケーションが含まれています。また、単純なテスト信号を生成し、再サンプリング結果を分析するためのPythonスクリプトもあります。
この例では、64ビットのフロート形式で生のオーディオデータを読み書きします。ファイルが最初に正しい形式に変換された場合、ファイルを.wavファイルの処理に使用できます。 sox
を使用して.WAVを生のサンプルに変換します。
sox some_file.wav -e floating-point -b 64 some_file_f64.raw
処理後、結果はnew .wavに戻すことができます。この例は、44.1 kHzで16ビットに変換されます。
sox -e floating-point -b 64 -r 44100 -c 2 resampler_output.raw -e signed-integer -b 16 some_file_resampled.wav
Audacityなどの多くのオーディオエディターは、生のサンプルを直接インポートおよびエクスポートすることもできます。
rubato
Crateには、Rustcバージョン1.61以降が必要です。
fft_resampler
機能経由でFFT Resamplersをオプションにします。log
機能を備えた構築を修正します。input/output_buffer_allocate()
オプションでゼロを使用して事前に処理します。ライセンス:MIT