iOS上でAudioUnitを使ってFloat32で鳴らす

今は買えないiPhone Core Audioプログラミングを読んでるんだけど、
今でもこの本以上に日本語で詳しく解説してある本はないんじゃないかなー。

サンプルコードのコメントも日本語だし。
http://www.sbcr.jp/products/4797355154.html

で、iOS8だとAVAudioEngineが使えるらしく、
こんな感じのサンプルコード(Gist)を見つけて喜んでたんだけど、
ちょっとサンプル数を詰めるとすぐ破綻してしまうので、
AudioUnitを使ってみることにした。

kAudioFormatFlagsAudioUnitCanonicalAudioUnitSampleTypeを使うと、
推奨されてない(CA_CANONICAL_DEPRECATED)って警告が出るので、
floatを使う方法を調べてみたらサクッとできた。

これを、

    AudioStreamBasicDescription audioFormat;
    audioFormat.mSampleRate         = sampleRate;
    audioFormat.mFormatID           = kAudioFormatLinearPCM;
    audioFormat.mFormatFlags        = kAudioFormatFlagsAudioUnitCanonical;
    audioFormat.mChannelsPerFrame   = 2;
    audioFormat.mBytesPerPacket     = sizeof(AudioUnitSampleType);
    audioFormat.mBytesPerFrame      = sizeof(AudioUnitSampleType);
    audioFormat.mFramesPerPacket    = 1;
    audioFormat.mBitsPerChannel     = 8 * sizeof(AudioUnitSampleType);
    audioFormat.mReserved           = 0;

こんな風にする。

    AudioStreamBasicDescription audioFormat;
    audioFormat.mSampleRate         = sampleRate;
    audioFormat.mFormatID           = kAudioFormatLinearPCM;
    audioFormat.mFormatFlags        = kAudioFormatFlagIsFloat | kAudioFormatFlagsNativeEndian | kAudioFormatFlagIsPacked | kAudioFormatFlagIsNonInterleaved;
    audioFormat.mChannelsPerFrame   = 2;
    audioFormat.mBytesPerPacket     = sizeof(Float32);
    audioFormat.mBytesPerFrame      = sizeof(Float32);
    audioFormat.mFramesPerPacket    = 1;
    audioFormat.mBitsPerChannel     = 8 * sizeof(Float32);
    audioFormat.mReserved           = 0;

あとは、コールバックの中で出力先をFloat32にキャストして、
そこに計算結果を格納すれば問題ない(たぶん)。

AVAudioEngineのところでも、
バッファの型がFloatだったので、出来るだろうと思ったら出来た。

これでいいのかな?どうなのかな?

ちなみに、AudioUnitにすることでサンプル数を詰められるかというと、
そんなことはないっぽくて、結局、体感でどうなの?って話になるんですが、
ちょっと引っかかる感じでした。(*1)

おしまい。

(*1) コールバックでデバッグ出力したサンプル数は512でした

Leave a Comment