すっかり更新が空いてしまっていましたが、この前アップデートした「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ではそろそろ怪しいかもしれないので、このあたりも古いコードは見直していくのが無難かもしれません。