RtAudio で Sine波

Chuck のソースを眺めていると、リアルタイムのオーディオ再生には RtAudio というライブラリを利用しています。RtAudio を少し調べてみました。

http://www.music.mcgill.ca/~gary/rtaudio/

RtAudio はオーディオデバイスの入出力の制御やデバイスの検出についてのプラットフォームや利用するバックエンドの差異を吸収してくれるライブラリです。RtAudio は C++ で書かれています。対応しているプラットフォームは以下の通り。

JACK は他の UNIX like なシステムでも使えるのかもしれません。Mac OS X でも使えるかも。

なおいつも通り ./configure して make でコンパイルまでできますが、make install がないので手動でヘッダとライブラリを適当にインストールします。rtaudio-config というコンパイル用のフラグを出力してくれるものもあるのですが、configure --prefix が効かないので単体のでインストールのしやすさはいまいちです。

わたしの環境が Mac OS X なので CoreAudio に対応する部分しか読んでいませんが、とても薄いラッパになっていて、せいぜいデータフォーマット(16bit signed とか 32bit float とか)の変換と、複数 channel の時の interleaved の変換をしてくれるくらいです。Mixingの機能もなく、シンプルにコールバック関数で1本のバッファにオーディオデータを詰める(出力時)だけになっています。とても小さいので、組み込んで利用するのにいいかもしれません。ライセンスも The MIT License のようなので著作権表示と使用許諾表示をしておけばいいはず。

そこで、Audio Programming における "Hello World!" である 正弦波 440Hz を鳴らすプログラムを作成。

ソースコードは Gist に置きました。

http://gist.github.com/165241

一見 C のコードですが C++コンパイラコンパイルします。

$ g++ -o sine sine.cpp `rtaudio-config --cppflags` \
      `rtaudio-config --cxxflags` -ltaudio `rtaudio-config --libs`

過去の自分の記事を参考に Soundflower で録音してみましたけど、特に代わり映えのしないただの正弦波なので音データは置きません。

あと Soundflower で録音する時にスピーカへのリダイレクトありにすると音飛びしてしまいました。そんなに重い処理していないし負荷のせいとも思えないので、何か問題があるのかもしれません。

[追記]
Soundflower でリダイレクトを利用した時の音飛びの解消ができました。最初はバッファ数を増やせばいいんじゃないかと思って RtAudio::StreamOptions の numberOfBuffers を増やそうかと思ったのですが、このパラメータはバックエンドが Windows(DS)やLinux(OSS, ALSA)のときしか有効ではなく、Mac OS X (Core Audio)では無意味でした。じゃぁどんなパラメータをセットしてるのかなと確認してみると、バッファサイズの設定だけのようです。
RtAudio はデバイスからバッファサイズの上限下限を取得して、範囲外のサイズが設定されたら範囲内にまるめてくれていたので、大きめにしておけばいいかと(固定のトーンを鳴らすだけでレイテンシを追求しなくていいので)大きな数値をしていして最大値に丸めてもらうようにしていたのですが、これがよくなかったようです。確か 0x1b00 くらいに丸められてたかな。ふとこれってちょっときりが悪いんじゃないかと思って 0x1000 = 4092 に設定してみたら音飛びがなくなりました。Gist のコードも修正しました。ちなみに Soundflower 側の Buffer Size は 512 に設定されています。
[/追記]