月別アーカイブ: 2015年1月

センターキャンセル機能を追加しました

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