AUHALを使ってサウンドファイルを再生する [マックな開発]
AUHALでサウンドをキャプチャの仕方についての記事をずいぶん前に書いたんですが、今度は、ファイルを読み込んでAUHALを使って出力させてみたので、概要を書いてみます。PublicUtilityを使います。
ファイルの読み込み
PublicUtilityのフォルダの中にAudioFile-newというフォルダができてました。この中にあるクラスを使うととても簡単にファイルからの再生、録音ができるようです
今回は、CAAudioFileだけを使います。CAAudioFileを使うとフォーマット変換が簡単です。
- CAAudioFileでのファイルの読み込み
- Open()というメソッドを使います。引数がFSRefなので、NSStringからだと変換しなくてはなりません。
とりあえず、というふうにしてみました(この変換処理はあまり自信がない…)。NSString* filename; CAAudioFile* audioFile; FSRef fsRef; FSPathMakeRef( (UInt8*)[filename cStringUsingEncoding: NSUTF8StringEncoding], &fsRef, NULL); audioFile->Open(fsRef);
- 出力側のフォーマットの設定
- SetClientDataFormat()かSetClientFormat()メソッドでフォーマットを設定できます。AUHALの出力エレメントの入力スコープのフォーマットを設定すればよいです。
CAAudioUnit* audioUnit; CAAudioFile* audioFile; CAStreamBasicDescription asbdInput; //AUHALのフォーマットの取得 audioUnit -> GetFormat(kAudioUnitScope_Input, 0, asbdInput); //ファイルからデータを取り出すときのフォーマットを設定 audioFile -> SetClientFormat(asbdInput);
- コールバックの処理
- 順番的に前後してしまいますがCAAudioFileからの読み込みをするので、ここで説明します。
コールバックの関数引数は、キャプチャーするときと同じものです。こちらが本来の使い方なので、コールバックされたときに引数にちゃんと値がのっかってきます。
OSStatus renderProc(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList * ioData) { CAAudioFile* audioFile=;//inRefConから設定する //ファイルの終りかチェックする //NumberFrameはどこかに保存しておいたほうがいいかも if(audioFile -> Tell() >= audioFile -> GetNumberFrames()){ //再生を止めるか、最初に戻す } //CAAudioFileからデータを取り込む audioFile -> Read(inNumberFrames, ioData); }
AudioUnit関連
これでファイル関連の処理は完了です。audioFileを使わなくなったら、Close()を呼んでdeleteはしますけど。
あとの大まかな処理は、前に書いた記事とおなじですが、ADCにある「TN2091」のドキュメントとも同じです。違うところだけ簡単に説明すると…
- enableIOのところ
- enableIOは、スコープが逆になるようにします。
あと、サンプルレートを設定するところも同じようにエレメント0で設定します。UInt32 enableIO=1; audioUnit -> SetProperty( kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Output, 0, &enableIO, sizeof(enableIO)); enableIO=0; audioUnit -> SetProperty( kAudioOutputUnitProperty_EnableIO, kAudioUnitScope_Input, 1, &enableIO, sizeof(enableIO));
- コールバックの設定
- キャプチャするときには、「kAudioOutputUnitProperty_SetInputCallback」というプロパティ値に設定しましたが、「kAudioUnitProperty_SetRenderCallback」プロパティ値で設定します(ここだけしか違わないのでコードは書きません)。
あとは、AudioOutputUnitStart()とAudioOutputUnitStop()で再生と停止を制御できます。
※CAAudioUnitの場合、AU()メソッドでAudioUnitを取り出して引数に設定する
まとめ
キャプチャしてくるときもそうですが、単にファイルをからサウンドを再生するだけなら、わざわざこんなことをしなくてもよいです。CAAudioFileを使うとファイルのフォーマットに関わらず、PCMでデータが持って来れるので、再生しながらPCMデータで何かをするというときには、便利だと思います。
トラックバック 1
前回のAUHALを使ってファイルを再生する方法でファイルが終りに達しているかをチェックするところでCAAudioFileのTell()をいうメソッドを使っていました。 しかし、Tell()という再生位置を返すメソッドの動きが期待したようになっていない場合があるようなので、前記事の追…[続く]







コメント 0