2015年7月24日金曜日

Opus再生サンプル

OpusでエンコードされたサウンドのOggファイルを再生するライブラリ, サンプルを作成.
https://github.com/taqu/opus

opus, ogg, opusfile, speexDSPライブラリを使用した.
Windowsでは, WASAPIをバックグランドに,
Androidでは, OpenSL ESをバックグラウンドに使用する.

Unity5のサンプルも作成してみた.
Nexus5では再生遅延の差はほとんどないが,
Xperia Z1 f SO-02Fでは明らかにUnity 3Dの方が遅い.

VorbisとOpusの差なのか, Unity 3Dの処理がよほどXperiaと相性が悪いのか.

OpenSL ES

仕様を読む限り,
SL_IID_ENGINECAPABILITIES
の実装は必須に見えるが手持ちのデバイスではとれない.
とりあえず失敗するまでCreateAudioPlayerをするしかない.

初めは, BufferQueue::GetStateで未処理バッファ数をチェックして,
データを補充する方法をとったが, 十分間に合っていると思われるのに
ノイズが入る.
ポーリングでデータを準備して, BufferQueueのコールバックで
BufferQueue::Enqueueに引き渡せばノイズが入らなくなった.
また何か見落とした文章があるのだろう.

WASAPI

WASAPIは, Core Audio APIsの中の音声再生API.
User-Mode Audio Components

共有モードと排他モードがあるが, ゲーム等, 音声を複数再生する場合,
共有モードを使用する.

基本はサンプルとおり
Rendering a Stream

音声再生のプログラムは,
ドライバなりエンジンからの次データ要求や,
再生バッファの空きの検知をトリガーに,
音声データをドライバ・エンジンに引き渡す処理を繰り返す.

WASAPIの場合, ポーリングで未処理をデータサイズを調べるか, イベントで検知する.
イベントは, WindowsのEventを引き渡し, そのEventがセットされるかチェックする.
イベントを使う方法は, 複数音声の管理には向いていないと思われる.

Core Audio APIsは, エフェクトの機能はなく, 高位のMedia Foundation等が提供する.
サンプル周波数変換には, IAudioClockAdjustmentが共有モードで使用できるが,
品質のほどはわからない.

Speexの, 信号処理部分を纏めたSpeexDSPがある.
resamplerだけ抜き出すのも簡単.