• OpenSL ES でのMIDI再生

    2011年05月15日 00時49分
    OpenSL ESでMIDIの再生について聞かれましたので簡単に書いておきます。
    簡単にというのも、詳しく説明するほと知らないからです。

    MIDIは仕様上イベントを保持していたり、再生状態を制御したり出来るらしく、
    OpenSL ESもそれを扱うことが出来るようですが
    私の用途ではそこまで必要ではないため再生しか試していません。


    単純に再生する方法については、サンプルコードがドキュメントに書いてあります。
    VIVID Runtime SDKではドキュメントは「documentation/api/khronos/opensles1.0.20090316.pdf」にあり、
    MIDIの再生については「APPENDIX B.3」にあります。

    サンプルコードがそのまま乗っていますので、一連の流れが確認出来ます。
    ポイントはSLDataFormatの値で、
    mimeTypeに「audio/x-midi」を、containerTypeに「SL_CONTAINERTYPE_SMF」を設定します。


    VIVID Runtime SDK 1.3に付属のimplementation_notes.xlsを見ると
    MIDIの場合はMIMEに「audio/midi」と「audio/mobile-xmf」を使いなさいと書いて有るので
    こちらでも動くかもしれません。


    簡単に動作を試すならば、VIVID Runtime SDK付属の「simple3d」サンプルを改変すればよさそうです。
    ファイル名とファイルフォーマットの設定を変えれば動くのではないでしょうか。(未確認)

    変更前
    1uri.URI            = (SLchar *) "synth_22kHz_16b.wav";
    2
    3    mime.formatType    = SL_DATAFORMAT_MIME;
    4    mime.mimeType      = (SLchar *) "audio/x-wav";
    5    mime.containerType = SL_CONTAINERTYPE_WAV;



    変更後
    1uri.URI            = (SLchar *) "hoge.mid";
    2
    3    mime.formatType    = SL_DATAFORMAT_MIME;
    4    mime.mimeType      = (SLchar *) "audio/x-midi";
    5    mime.containerType = SL_CONTAINERTYPE_SMF;


  • OpenSL ES での複数音源再生

    2011年03月23日 04時56分
    以前の記事で、MIDIを複数再生するとおかしくなると書きましたが、使い方が悪かったようです。

    EngineとOutput Mixが1対1で、Output MixとPlayerが1対Nだと思っていましたが、
    正しくはEngineとOutput Mixが1対Nで、Output MixとPlayerが1対1のようです。

    リファレンスにもきちんと書いてありました。
    7.9 Output Mix
    Description
    The output mix object represents a set of audio output devices to which one audio output
    stream is sent. The application retrieves an output mix object from the engine and may
    specify that output mix as the sink for a media object. The engine must support at least
    one output mix, though it may support more. The API does not provide a direct audio
    output IO-device as a sink for media objects.

    実際そのように修正したところ、エミュレータ上の動作は正常になりました。

    ただ、Output Mixの数は最低1つが保証されているのみで、
    それ以上もたぶんあるんじゃないの的な記述なのが少々気になります。

    実際に使える数の上限は不明です。
    とりあえずエミュレータ上で2音まで確認しました。

    ランタイムの実装依存だとは思いますが、もしかしたら実機依存かもしれません。
  • OpenSL ES Tips (On VIVID Runtime)

    2011年03月09日 23時35分
    OpenSL ES自体はサンプルとリファレンス見ながら
    なんとなく使えるとは思います。

    なので、何点か引っかかったとこだけ記しておこうと思います。

    MIDI再生を使用していたときに調べたことなので、
    基本的にMIDI再生に関することだと思ってください。
    WaveとかMP3も当てはまるかもしれませんが未検証です。

    また、対象のVIVID Runtime SDKのバージョンは1.1です。
    最近1.2が出ているので、そちらでは改善されているかもしれません。

    音量について

    SLVolumeItfのSetVolumeLevelで設定するわけですが、
    この引数が「SL_MILLIBEL_MIN ~ 端末のサポートする最大値(多くの場合は0)」と書いてあるのですが、
    SL_MILLIBEL_MINを指定するとエラーが返ってきます。
    (エミュレータとXperiaで確認)

    エラーが出ない数値を探ると-2000でした。
    なので、-2000 ~ 0の間で指定しましょう。

    端末によってはこの数値も怪しいかもしれません。

    あと、SL_MILLIBEL_MAXというのが定義されていまして、
    これが最大値っぽいですが全然違うので気をつけましょう。

    プレイヤーの解放について

    MIDIのプレイヤーはCreateMidiPlayerで作成するわけですが、
    これを解放する前には手動でSLPlayItfのステータスをSL_PLAYSTATE_STOPPEDにしなければなりません。

    SL_PLAYSTATE_PAUSEDのままDestroyしてしまうと
    どうもきちんと解放されないようです。
    (実機が落ちたり、動作が不安定になりました。)

    MIDIの複数再生について

    CreateMidiPlayerで再生オブジェクトを2個作ると
    何故か再生速度が速くなります。

    2個作ってはいけないのかもしれません。

    CreateMidiPlayer & CreateAudioPlayerで2個作ると
    Xperiaは大丈夫でしたがエミュレータだと同じ現象です。

    これは未だ解決方法不明です。
  • VIVID Runtimeはじめました Ogg vorbis編

    2011年03月07日 23時00分
    VIVID Runtimeは音声再生にOpenALとOpenSL ESがありますが、
    公式にはOpenSL ESの方をプッシュしてきます。

    だったら最初から片方だけにしとけばいいんじゃとか思わないでもないですが、
    複雑な事情があるのでしょう。


    私は素直な人間なので、お勧めされるがままにOpenSL ESを使いました。

    しかしこのOpenSL ESですが、全く普及している気配がありません。
    私などは今回初めてこの単語を目にしたくらいです。

    ネット上を調べてみても情報がさっぱり出てきません。

    一応Kronos公式ドキュメントがSDKに含まれるので
    なんとかなるといえばなるのですが・・・
    たまに実装とドキュメントが違うこともあるので気が抜けません。



    今回ゲームのBGMにOgg vorbisを使えないかという相談を受けました。
    しかしOpenSL ESは対応していないようです。

    どうもOpenSL ES 1.1ならば対応している気配があるのですが、
    VIVID Runtime SDKに含まれるのは1.0です。

    1.0でもMP3ならば再生出来るのですが、MP3だとライセンス料が半端ないので使いにくいです。
    もしかしたらVIVID Runtime側でライセンス処理をしてるかもしれませんが、その辺り不明です。

    そこで今回はVIVID Runtime上で頑張ってOgg vorbisを再生してみます。


    そもそもWaveの再生はあるのです。
    SDKのサンプルにplaystreamというのがあり、これがメモリ上のWaveデータを再生しています。

    ということは、vorbisデータをデコードして
    このバッファにぶち込んでやれば再生出来るということになります。

    そこで早速libogg-1.2.2とlibvorbis-1.3.2を入手しました。

    私は未だにconfigureとかmakeとかよくわからんのですが、
    要はCコードをVIVID Runtime SDKに含まれるクロスコンパイル環境でコンパイルしてやればいいと思うのです。

    例えばoggならばこんな感じです。
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 src\framing.c -o framing.o
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 src\bitwise.c -o bitwise.o
    
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-ar.exe" rcs libogg.a framing.o bitwise.o

    ※config_types.hにconfigureでOS判定して埋め込む部分があったのでそこだけは手動で解決しています。

    同じ感じでvorbisの方も作成します。


    作成したライブラリとヘッダを次のフォルダに配置します。
    $VIVID_RUNTIME_SDK\tools\gcc_toolchain\arm-runtime-eabi\usr

    ※$VIVID_RUNTIME_SDKはVIVID Runtime SDKを展開したフォルダ


    こうするとビルド時に参照することが出来ます。


    あとはサンプルのコードにvorbisのデコード処理を入れて完了です。

    で、実行してみたのですが、デコードが追いつきません。
    エミュレータとはいえ、Phenom II 3GHzで足りないという状態です。
    中でどんな処理してるんだろう・・・


    これはもう少しなんとかならんかと調べてみたのですが、
    Tremorという整数演算で高速デコードするバージョンがありました。
    しかもARM用に最適化してあったりします。

    これをチェックアウトしてきておりゃおりゃっとビルドします。
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 mdct.c -o mdct.o
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 block.c -o block.o
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 window.c -o window.o
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 synthesis.c -o synthesis.o
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 info.c -o info.o
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 floor1.c -o floor1.o
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 floor0.c -o floor0.o
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 vorbisfile.c -o vorbisfile.o
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 res012.c -o res012.o
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 mapping0.c -o mapping0.o
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 registry.c -o registry.o
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 codebook.c -o codebook.o
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-gcc.exe" -I include -c -fpic -mno-thumb-interwork -Wall -O3 sharedbook.c -o sharedbook.o
    
    "C:\vivid_runtime_sdk_1_1\tools\gcc_toolchain\bin\arm-runtime-eabi-ar.exe" rcs libvorbisidec.a mdct.o block.o window.o synthesis.o info.o floor1.o floor0.o vorbisfile.o res012.o mapping0.o registry.o codebook.o sharedbook.o

    ※os.hのエンディアンの設定がよろしくないので調整しています。


    出来たlibvorbisidec.aでデコードしてみたところなんとか再生できました。
    本当になんとか・・・といった感じで、稀にデコードが追いついていません。

    あとはFPUを使って最適化でなんとかならんかなと思うのですが、
    ARMのFPUを使ったデコーダは見つけられませんでした。
    さすがに自分で書く気も起きません。


    エミュレータで厳しくても実機ならいけるんじゃないか?と思わなくもないのですが、
    今は手元に実機がないんですよねぇ・・・。Xperia arcでも買おうかしら。


    今回使ったファイル
  • VIVID Runtimeはじめました 実機編

    2011年03月01日 22時41分
    エミュレータでの実行は簡単ですが、実機での実行は一手間かかります。

    この辺りを覚えている限り書きたいと思います。
    かなり試行錯誤しつつ作業していたので、間違いがある可能性がありますがご容赦ください。
    前回書き忘れましたが、私の環境はWindows 7 64bit Ultimateです。



    実機での実行には次の2パターンがあります。
    • thrip.exeがadb.exeを使って転送し実行
    • rpkを作成してSDカードに転送し実行

    開発中には前者で行い、テスト終盤は後者で行うことになるかと思います。


    証明書の準備

    上記2パターンのどちらの場合でも証明書が必要になります。
    証明書は1実機につき1つ必要です。
    複数の実機で実行する場合は複数必要です。


    証明書を取得するための証明書署名要求(CSR)と秘密鍵ファイルを作成します。

    作成にはOpenSSLが必要です。OpenSSLは次のサイトからダウンロードしてインストールします。
    http://www.slproweb.com/products/Win32OpenSSL.html
    実行にはVisual C++ 2008の再配布パッケージが必要になるので、インストールしていない場合はこれもインストールします。


    作成はコマンドプロンプトから行います。

    VIVID Runtime SDKのcertificatesフォルダに移動
    (SDKのパスに合わせて調整してください。)
    cd C:\vivid_runtime_sdk_1_1\certificates


    環境変数PATHに一時的にOpenSSLのbinフォルダを追加。
    (これは64bitバージョンの例です。インストールしたパスに合わせて調整してください。)
    set PATH=%PATH%;C:\OpenSSL-Win64\bin


    gen_request.batを実行します。
    gen_request.bat


    IMEI Codeを入力します。
    IMEI Codes:IMEI:01234567890123

    IMEI:の文字列も自分で入力しなければならないので注意してください。
    また、IMEI Codeの最後の1文字はCheck Digitなのでここでは入力しません。(数字14桁を入力します。)

    IMEI Codeは動作させる実機から取得します。
    多くの機種では電話をかける画面で*#06#と入力すると表示されるようです。(Xperiaで確認)
    この辺りは機種毎に確認してください。

    @GMOゲームセンター デベロッパーサイトのログインIDを入力します。
    Developer portal login  []:hogehoge


    以上でcertificatesフォルダに、developer.csrdeveloper.keyファイルが作成されます。

    このdeveloper.csrを@GMOゲームセンター デベロッパーサイトにアップロードすると
    証明書(developer.cert)が取得出来ます。
    この手順はサイトにログインすればすぐわかるかと思います。

    取得したdeveloper.certはcertificatesに配置します。


    ※今回developer.csr, developer.key, developer.certはcertificatesフォルダに配置しましたが、
    実機が複数の場合はアプリのビルド時に個別に指定する必要があります。


    adb.exeの準備

    adb.exeは実機に対して色々な操作を行うツールです。
    実機へのファイルのやりとり、アプリのインストールに使用します。

    このツールはAndroid SDKをインストールした後、
    SDK Manager.exeを起動し、Android SDK Platform-toolsをインストールすると手に入ります。

    adb.exeについてはthrip.exeから呼び出される為、PATHを通しておく必要があります。
    環境変数PATHにAndroid SDKのplatform-toolsフォルダを追加してください。


    ランタイムのインストール

    VIVID Runtime SDKで作成したプログラムを実機で実行するには、
    予めランタイムと管理アプリを実機にインストールしておく必要があります。

    ランタイムについてですが、私の手元に実機が届いた時点で既にインストール済みだったため不正確ですが、Gゲーアプリのはずです。

    管理アプリは@GMOゲームセンター デベロッパーサイトで
    VIVID Runtime SDKと一緒に置いてありますので、adbを使ってインストールします。

    USBケーブルで実機を繋ぎ、次のコマンドを実行します。
    adb install VIVIDRuntimeManager.apk


    thrip.exeがadb.exeを使って転送し実行する場合

    thrip.exeはVIVID Runtime SDKのツールです。
    VIVID Runtime SDKをインストールしてあれば使うことが出来ます。

    一度thrip.exeで実行すると、タスクトレイに次のアイコンが出ます。
    アイコン

    これを選択し、次のダイアログでProfileをandroidにすると実機での実行になります。
    ダイアログ

    上記ダイアログを設定した後、thrip.exeで実行すると、
    Android上のVIVID Runtime Managerにアプリが表示されますので、そこから起動出来ます。

    rpkを作成してSDカードに転送し実行する場合

    rpkを作成するには、ビルド設定ファイル(hogehoge.vcproj.config)ファイルの次の項目にTrueを設定します。
    <use_package>True</use_package>


    これでビルドすればrpkファイルが作成されます。

    このrpkファイルをSDカードのルートにコピーします。
    実機をUSBケーブルで接続し、SDカードをマウントすれはコピー出来ます。

    VIVID Runtime Managerからインストールするためにはマウントを解除しなければならないのでご注意ください。

    SDカードを取り外してPCに刺してやってもいいと思いますがめんどくさいです。


    rpkファイルをコピーした後、Android上のVIVID Runtime Managerを起動します。
    メニューボタンを押し、installを選択するとコピーしたアプリが表示されるのでインストールしてください。