今回は、iPhoneオーディオのIOバッファサイズについてです。とりあえず、前回までのコードに、以下のようなsetIOBufferSizeメソッドを追加して、initにその呼び出しを加えてください。
- (void)setIOBufferSize
{
Float64 sampleRate;
UInt32 size = sizeof(sampleRate);
AudioSessionGetProperty(kAudioSessionProperty_CurrentHardwareSampleRate, &size, &sampleRate);
Float32 bufferSize = 256./sampleRate;
size = sizeof(bufferSize);
AudioSessionSetProperty(kAudioSessionProperty_PreferredHardwareIOBufferDuration, size, &bufferSize);
}
- (id) init
{
self = [super init];
if (self != nil) {
[self setupAudioSession];
[self setIOBufferSize];
[self setupOutputUnit];
}
return self;
}
前回までのコードのコールバック内は、フレーム数に応じてサイン波の周波数がかわるようになっていましたので、変更を加えないときより高い音が再生されると思います。bufferSizeの256の所がバッファサイズのフレーム数ですので、そこを変更すれば任意のフレーム数に設定できます。コールバック内にprintfとかでinNumberFramesをログに出すようにすれば、ちゃんと変わっているのが分かると思います。
IOバッファサイズは秒数で指定しますので、今回のコードではハードウェアのサンプリング周波数を取得して、目的のフレーム数を割って値を求めています。プロパティの名前にPreferredってついているので指定した秒数の近いところに設定されるという感じでしょうか。Appleのサンプルでは、256に変更するときにちょっと少なめの0.005秒を指定していました。
ちなみにAudioSessionのプロパティのゲットは、AudioSessionがアクティブになっていないと出来ないようです。セットはいつでも大丈夫みたいです。Appleのサンプルをみると、プロパティをセットして、AudioSessionをアクティブにして、プロパティをゲットするというのがセオリーっぽいです。
IOバッファサイズはデフォルトの状態では1024フレームです。ロックしてスリープすると強制的に4096フレームになります。ただしOS 3.0では、今回のサンプルのようにAudioSessionSetPropertyでIOバッファサイズを一度設定すると、ロックしてもIOバッファサイズが変わらなくなったようです。また、カテゴリをPlayAndRecordなどにするだけでも変わりません。
いつもお世話になってます。
RemoteIOの記事から読ませていただきました。
これってbufferSizeが小さくなった分、1秒間に呼ばれるコールバック
回数が多くなったと考えてよいでしょうか?
ちなみに22kHz16bitモノラルのPCMで行う場合はどのように設定すれば
良いのでしょうか?