すっかり更新が空いてしまっていましたが、この前アップデートした「Tune Changer」「ピッチシフト」「タイムストレッチ」にセンターキャンセルの機能を追加したことについて書くことにします。
https://itunes.apple.com/jp/app/tune-changer-for-karaoke-instrument/id734191615?mt=8
https://itunes.apple.com/jp/app/realtime-pitch-shifter/id670120398?mt=8
https://itunes.apple.com/jp/app/time-stretcher/id637376117?mt=8
簡単な実装で実現してますので、説明しておきたいと思います。
まずはコードを載せます。AUGraph のコールバック部分の修正だけです。
OSStatus renderCallback(void *inRefCon, AudioUnitRenderActionFlags *ioActionFlags, const AudioTimeStamp *inTimeStamp, UInt32 inBusNumber, UInt32 inNumberFrames, AudioBufferList *ioData) { OSStatus err = noErr; AudioIO *def = (AudioIO *)inRefCon; UInt32 ioNumberFrames = inNumberFrames; err = ExtAudioFileRead(def.extAudioFile, &ioNumberFrames, ioData); if (err) { NSLog(@"ExtAudioFileRead err = %d", (int)err); return -1; } //////////////////////// // add if (def.isCenterCancel) { // only stereo if (def.outputFormat.mChannelsPerFrame > 1) { Float32 *outL = (Float32 *)ioData->mBuffers[0].mData; Float32 *outR = (Float32 *)ioData->mBuffers[1].mData; for (int i = 0; i < ioNumberFrames; i++) { Float64 tmpL = (Float64)outL[i] - (Float64)outR[i]; outL[i] = (Float32)tmpL; outR[i] = (Float32)tmpL; } } } //////////////////////// /* 略 */ return err; }
ExtAudioFileRead から読み込んだ ioData からデータを直接読み込み、LRの差分を求めて、結果を両チャンネルに入れています。それだけです。
「Center Cancel」ボタンを押下されている場合に処理されるようになっています。
最近の書籍で Core Audio の説明はほとんどないので、何げに知られていない(?)かもしれないのですが、iOS 5以降では、オーディオデータの型は Float32 になっています。
ただ、AudioStreamBasicDescription の mFormatFlags を指定してやれば、以前(iOS 2.x)の 8.24 固定小数点数でも動いていましたが、iOS 8 SDKではそろそろ怪しいかもしれないので、このあたりも古いコードは見直していくのが無難かもしれません。