サウンド再生について
サウンド再生について調べてみました.
複数音同時再生させたいんだけれども、CPUでミキシングをしているからなのか、いまいち非力な感じです.
そんなわけで、とりあえずのメモを...
再生の方法
サウンドを鳴らす場合には、いくつかの選択肢がある.
どれも一長一短あるようだが、実装が平易なのは、 SystemSoundService もしくは、AVFoundation だと
思われる.
System Sound Service
- ごく短い(30秒未満)のサウンドファイルを、レベル制御/再生位置設定などの制御を行わずに再生する.
- 再生が遅延する.(ゲームなどのリアルタイム処理にはむかない)
- 利用するのは楽
- リニア PCM
- IMA/ADPCM(IMA4)
- *.caf / *.aif / *.wav のいずれか
- サンプルの Metronome についている SoundEffect クラスがそのままサウンドのサンプルになっている
AVAudioPlayer
iPhone OS 2.2 以降では、 AVAudioPlayer を利用することができる.
利用方法も簡単だし十分な機能が実装されているので、単純なサウンド再生を行うのには便利だと思う.
(ただし、一応複数音の同時発音が行えるが、ミキシングをCPUで行っているようなので結構遅い.単音を利用する程度か?)
AVAuioPlayer でできることを以下に挙げる.
- 再生位置の変更
- 回数を指定したループ(無限ループ含む)
- 再生音量の指定
- ボリュームの調節
- 開始/終了の取得(Delegate)
- 複数音の同時再生
- ファイルからのインスタンス生成
- バイト列からのインスタンス生成
初期化の例を次に記す.
#include <UIKit/UIKit.h> #include <AVFoundation/AVFoundation.h> @interface SoundTestView : UIView { AVAudioPlayer* m_sound; } -(void) initSound; @end
- (void) initSound { NSString* a_file_path = [a_bundle pathForResource:@"test" ofType:@"wav"]; NSURL* a_file_url = [NSURL fileURLWithPath:a_file_path]; if( a_file_url ){ NSError* a_error = nil; m_sound = [[AVAudioPlayer alloc] initWithContentsOfURL:a_file_url error:&a_error]; } }
正常にファイルが読み込めていれば、 play メッセージを送信するだけで音が鳴る.
[m_sound play];
再生位置の設定には、プロパティ currentTime を用いればよい.
dultion プロパティを用いると、サウンド全体の長さが取得できるので、そこから再生位置を設定すればよい.
m_soundd.currentTime = m_sound.duration / 2.0f;
[m_sound play];
ループの指定には、numberOfLoops プロパティを用いる.
2回再生を行いたい場合には、次のように再生することになる.
m_sound.numberOfLoops = 2;
[m_sound play];
無限ループを行いたい場合には、-1 を設定すればよい.
注意点
AVAudioPlayer を利用する場合には、AVFoundation.framework の追加と AVFoundation/AVFoundation.h もしくは、 AVFoundation/AVAudioPlayer.h のインクルードが必要.
また、AVAudioPlayer は、 iPhone OS 2.2 以降に追加されている API なので、 アクティブな SDK を選択する場合に、「Device - iPhone OS 2.2」もしくは、「Simlator - iPhone OS 2.2」を選択している必要がある.
間違えて、 iPhone OS 2.1 等を選択してしまうと、ヘッダが見つからない旨を告げるエラーが発生する点に注意.
error: AVFoundation/AVAudioPlayer.h: No such file or directory
おまけ
フレームワークの追加は、Xcode 上の "Frameworks" フォルダを右クリックし、[追加] - [既存のフレームワーク]から行うことができる.
対応するフレームワークの一覧から選択が行えるが、AVFoundation.frameworkd が一覧に出ていない場合には、プロジェクトの設定にあるベース SDKの設定が 2.1(or 2.0)になっている可能性が考えられる.
[プロジェクト設定を編集]から、プロジェクト設定ダイアログを開き、[一般]タブから、"すべての構成のベースSDK"の項目を、「Device - iPhone OS 2.2」もしくは、「Simlator - iPhone OS 2.2」に選択しておくと、iPhone OS 2.2 に対応するフレームワークの一覧から選択することができる.
(私は、これがよく分からずに、長いパスをたどっていた...)
まとめ
AVFoundation は便利だけれども、私が望む利用用途としては少し非力に感じた.