Androidのサウンド処理については、Andoroid 2.2 まではかなりひどい状況であり、再生の指示をだしてから、実際に再生されるまでの時間がひどいと体感で0.5秒近くの遅延が発生する。それらをふまえた上で、サウンド再生における方法を説明したい。
Java上で利用するMediaPlayerクラスは、端末メーカーが独自に実装を行い、ライブラリとして提供しているクラスと思われ、端末によって挙動に大きな差が存在している。
公式ページ
このページで、MediaPlayerのクラス説明を行っているが、簡単な利用方法としては、以下の通り。
private MediaPlayer mp; mp = MediaPlayer.create(this, R.raw.music); mp.start();
このサンプルは、MediaPlayerクラスのインスタンスを作成し、そのインスタンスにバンドルされたリソースファイルを指定することで、音の再生を行う。音の長さやファイルの種類などは、mp3ファイルなどの圧縮された音楽ファイルなども扱え、利便性が高いが先の説明の通り、遅延が非常に大きい。
AUdioTrackは、Androidにおける一番底辺にあたるであろうAPIであり、この先はハードウェアに直結しているクラスでもある。逆にこのレベルでAndroidで、すでに遅延が発生しているため、ユーザーが遅延の無い効果音などを鳴らすためには非常に苦労するだろう。
公式ページ
このページで、AudioTrackのクラス説明を行っているが、簡単な利用方法としては、以下の通り。
private AudioTrack at; at = AudioTrack(int streamType, int sampleRateInHz, int channelConfig, int audioFormat, int bufferSizeInBytes, int mode); at.write(short[] audioData, int offsetInShorts, int sizeInShorts); // 再生する音データ(バイト配列) at.play();
このサインプルでは、実際の値を記載せずに方だけを示しているが、実際のデータなどにはバイト配列の音を渡すだけのため、mp3やwavフォーマットの音ファイルは利用できず、音のファイルを解析し、バイト配列にしたデータを、AudioTrackクラスに渡す事で作成される。その後はplayやstopという形で、MediaPlayerと同じようなコマンドで再生できる。
実際の実装としては、このAudioTrackを低レベルAPIとして、MediaPlayerなどが実装されるため、ある意味、このAudioTrackが端末メーカーの実装に依存するともいえる。
これもAndroidのサウンドAPIのひとつだが、この特徴はサウンドデータをあらかじめデコードし、Nativeヒープ領域に一時展開しておくことで、再生の遅延を減らすという物であり、MediaPlayerと、AudioTrackの中間に位置するAPIと考えられる。
特に注意するべきポイントは、エンコードが別スレッドによって行われる為に、再生するタイミングを自分で正しくコントロールしておく必要がある。通常の使い方としては、Viewが作成されたタイミングで、利用される音データをあらかじめエンコードして、登録しておき、実際の発音時には再生のみを行うようにすることである。
但し音の長さが10秒。またNative領域のメモリがJavaから管理できないため、メモリーオーバーなどの落ちバグに悩まされる事になるだろう。
公式ページ
このページで、SoundPoolのクラス説明を行っているが、簡単な利用方法としては、以下の通り。
SoundPool sp; sp = new SoundPool(10, AudioManager.STREAM_MUSIC, 0); // コンストラクタ int sid = sp.load(context, sound_001, 1); // エンコード&ストア sp.play( sid, 100, 100, 1, 0, 1); // 発音
基本的には、sid を配列で持ち、複数の効果音などを登録して利用する方法が一般的と思われる。(サンプルでは配列を利用していない)