libspeex リサンプラーの使い勝手

 libspeexはXiph'sによって配布されている音声コーデックライブラリである。ロイヤリティフリーでBSDライセンス、且つコーデックだけでなくリサンプラーも実装されており申し分ないのだが、効率化のための実装によるものなのか、リサンプラーガーベジコレクションがやりづらい。
 このサンプルにあるように、確保しておいた入力用と出力用バッファを、リサンプラーで使用した後、同一関数スコープ内で開放するのが無難。というかそれ以外の開放タイミングだとバッファ領域が破壊されていますというエラーが出る。入力用と出力用のバッファにスマートポインタを使用しても問題ないが、開放タイミングをスマートポインタに任せるとこの問題が起こるため、先述の様にリサンプラーを使用したのと同一な関数スコープ内で明示的に開放してやることになる。これは、speex_resampler_process_interleaved_float等が、引数で渡されたバッファを処理中にいじっているために起こっていると考えられる。
 ガーベジコレクションの問題は上記方法で回避できるが、それとともに使い勝手に制約が出来るため、今時のガーベジコレクションに慣れていると鬱陶しく感じるだろう。連続してPCMを受け取ってリサンプルする処理を書く場合、バッファの確保と解放が一度で済むように工夫して記述しなければ非効率になるだろう。連続したPCMのリサンプリングをスレッド関数内で行う場合、スレッド開始でバッファ確保→ループ内でリサンプリングとその他処理→スレッド関数終了直前にバッファ解放、といったようにすると良いだろう。僅かな信号を断続的にリサンプリングする際は、バッファの確保と解放がその都度行われるようなケースが出てきても仕様がないかもしれないが、そもそもそういった用途が想定されていないので、このような作りになっているのかもしれない。
 肝心のリサンプルは無論行えている。クオリティも問題ないようだが、1.2beta3あたりでバグフィックスが報告されており、内部的にはイマイチなところもあったのだろう。

 C言語で記述されたライブラリには、この様な使い勝手のものが伝統的に数多くある。C言語自体がそういうものなのである程度は仕様が無いのだが、libspeexのケースは少し特殊なケースだと思う。