libpdのJNI側のソースコードやAudio glueとサンプルプログラムを見比べてたら形が見えてきた.
libpdを使ってオーディオを記述する際の特徴として,PdBaseをスタートさせても,Pd内で流れる時間は明示的に進めてやる必要があることが挙げられます.PdBase.process() 等のprocess系メソッドに,引数として進める時間(ticks)や入力・出力バッファへのポインタを乗せて投げてやると,Pd内の時間がそのticks数だけ進み,バッファの中身が更新されて帰ってきます.
しかし結論からいうと,pd-for-androidやpd-for-iOS,libpd(-portaudio)あたりを使う場合においては,このことを意識する必要は基本的にはなさそうです.
samples/com/noisepages/nettoyeur/libpd/sample/JavaSoundSample.java
では上記の流れを愚直に実施し,PdBase.process(ticks, dummy, samples); でPdBase内の時間をticksだけ進め,出力信号を取ってきてJavaSoundに乗せることを繰り返しています.
他方,PortAudioやOpenSLが適用されたlibpdビルドでは,サウンドAPIがバッファを更新するたびに呼ばれる関数(callback関数)の中で,そのバッファの幅に応じて勝手にPdBase.process()を実行してくれるように作ってあります.
pd-for-androidをDesktop環境でシミュレートする
pd-for-androidは,libpdにAndroid向けの機能を付け足した開発キットのようなものです.Androidではこのpd-for-androidを利用させてもらおうと思っていますが,Desktopでのテスト環境においてもコードを共通化するために,Desktop上でpd-for-androidをシミュレートすることを考えます.
前回,「PdBase自体がオーディオを走らせるかどうかはlibpdのビルドによる」というような事を書きましたが,これはPdBase.implementsAudio() の返り値で判別することができます.pd-for-androidには,Audio glue(サウンドAPIとの橋渡し役)としてPdAudio.javaが用意されています.このPdAudioでは,PdBaseをどう走らせるかを前記の PdBase.implementsAudio() の値によって分岐させており,
- trueなら: 素直にPdBaseのオーディオを開始するだけ.サウンドAPIがバッファを更新するたびに,コールバック関数がPdBase内の時間も勝手に進めてくれる
- falseなら: PdBase.process() を自分で呼び,バッファを更新してAndroidのAudioTrackへ渡す
という風に実装してあることがわかりました.
PortAudioを利用可能なDesktop環境を前提とするなら,上記のtrueの部分だけを引っ張ってくれば良いか,ということでとりあえずテキトーに移植してみました.
pd-for-androidはPdAudio.java以外にも,Androidの環境設定を拾ってきたり,MIDIをひっぱってきたりと他の機能をいろいろ装備していますが,まぁ今は必要ないので無視で.
特にPdからの信号を待ち受けてAndroidのUIにアクセスするためのPdUiDispatcher.javaが移植未完なのが致命的なような気もしますが,幸いにしてlibGDXで絵を描いてる限りにおいては使いません.
他にも,ファイルのサーチパス関連の問題として
という2要素間で都合が合わないのを解決するために,libGDXさんのFileHandlerで曲を構成するデータ(submodulesやwavファイル)を適当な場所にコピーしてから使うなど色々と脇を固めてました.
ともかくこれで,libGDX + libpdによるハイパフォーマンスなクロスプラットフォーム開発環境が構築できたことになります!
ほぼ毎日弄りつづけて2ヶ月弱.まだまだ問題は山積みですが,とりあえず試作的なことができるようになったのでテンション上がりまくりです.
PortAudioを利用可能なDesktop環境を前提とするなら,上記のtrueの部分だけを引っ張ってくれば良いか,ということでとりあえずテキトーに移植してみました.
pd-for-androidはPdAudio.java以外にも,Androidの環境設定を拾ってきたり,MIDIをひっぱってきたりと他の機能をいろいろ装備していますが,まぁ今は必要ないので無視で.
特にPdからの信号を待ち受けてAndroidのUIにアクセスするためのPdUiDispatcher.javaが移植未完なのが致命的なような気もしますが,幸いにしてlibGDXで絵を描いてる限りにおいては使いません.
他にも,ファイルのサーチパス関連の問題として
- Android APKにおける assets ディレクトリは,実行時に展開され動的に配置されるためスタティックなローカル空間と対応できない.かといって res ディレクトリは取り回しが悪いのでヤダ.
- libpd内のPdはサーチパスとして絶対参照が必要.
という2要素間で都合が合わないのを解決するために,libGDXさんのFileHandlerで曲を構成するデータ(submodulesやwavファイル)を適当な場所にコピーしてから使うなど色々と脇を固めてました.
ともかくこれで,libGDX + libpdによるハイパフォーマンスなクロスプラットフォーム開発環境が構築できたことになります!
ほぼ毎日弄りつづけて2ヶ月弱.まだまだ問題は山積みですが,とりあえず試作的なことができるようになったのでテンション上がりまくりです.
0 件のコメント :
コメントを投稿