2011年6月4日土曜日

[Android] SoundPoolのオーディオ再生ミスをなくす

How to avoid failing to play audio-files.

AndroidのSoundPoolはロードしたオーディオファイルをすぐに再生できません。
ロードしたオーディオのデコード処理に時間がかかるためです。

Android 2.2以降はsetOnLoadCompleteListenerでロードが完了したことを知ることができます。
ここではAndroid 2.1以前を想定してsetOnLoadCompleteListenerを使わずに対策します。

起動したら音を鳴らすだけのアプリケーションを作ってみます。
※プロジェクトのresフォルダー配下にrawフォルダーにオーディオファイル「sample_sound.ogg」が保存されているものとします。
※パーミッションは設定不要のためマニフェストは省略します。レイアウト用xmlも使いません。

まずは音が鳴らない例です。
SoundPool#loadの直後にSoundPool#playで音を鳴らしたくても、どれだけ高速な端末でもデコードが間に合わないので音は鳴らないでしょう。

SoundPoolのリファレンスを見るとplayメソッドはオーディオの再生に失敗するとゼロを返すとされています。
実験したところ、デコード中は再生に失敗するのでゼロが返ってきました。
つまりゼロ以外の数値が返ってくるまでplayメソッドを繰り返し実行すればデコードが終わったことがわかります。
playメソッドをボリュームゼロで実行し、ゼロ以外が返るまで繰り返せば確実に音を鳴らすことができます。

再生テスト追加後のソースです。
これで確実に音声が再生されるようになりました。

今回のサンプルはロードしたらすぐに再生する仕様にしました。
実際のアプリケーションでは早いタイミングで複数のオーディオファイルをロードして、任意のタイミングで再生することが多いと思います。
Eye元気!はロードした直後にオーディオの再生テストをしています。
サウンドテストに時間がかかりすぎると「Application Not Responding」(ANR)の警告が出るので、サイズが大きいオーディオは要注意です。

以上、参考になれば幸いです。

0 件のコメント:

コメントを投稿