The final trick to make iPhone audio analysis work

I am writing an iPhone app for fun.

I love to play trumpet, and would like to play better.
But when it comes to music, my grade seems pretty bad.

Say, is this C or G?, then I would make a mistake.
So I think, I would be a kind of handicapped one in music.

Every morning, I look for G, hoping to see G again.
After some daily practice, I end up with finding her. But she is so difficult.

I have a decent eyes instead. And teeth. I don't need dental clinic.
I'm not sure if it's the reason, but that's why, I'm working on the app.

Here's the one.
I upload videos on YouTube.
http://www.youtube.com/user/TheBlessingOfG



I have had a very weird noise until an hour ago, which is like a filter to improve the voice communication. It happens only on device, iPhone, not on simulator.
When I gave it beeps from C3 up to C5, then the result waves up and down around certain frequency as if it had been amplified by filter.

Last night, I kept talking to the mic, and saw how's it doing. It was like a doctor checking a patient.
One strange phenomenon I realized was that I can hear my voice when I said something, but with a kind of delay.
I tried several times, and confirmed aurioTouch sample app provided Apple was OK.
What's wrong with mine?



Then, this morning, one thing hit my head.
There might be a problem to make silence.
In aurioTouch(FFTBufferManager), it's like this.

void SilenceData(AudioBufferList *inData)
{
for (UInt32 i=0; i < inData->mNumberBuffers; i++)
memset(inData->mBuffers[i].mData, 0, inData->mBuffers[i].mDataByteSize);
}

Nothing interesting. Just put silence(0) onto audioBuffer before sending to output.
I confirmed that I called such a method correctly.
But for some reasons, it didn't keep quite, but said something with delay!

Having taken a cloooser look at the audio processing in aurioTouch,
I noticed there's one I didn't care that much.

void GrabAudioData(AudioBufferList *inBL);
Boolean ComputeFFT(int32_t *outFFTData);

FFT is computed at *drawing*, not at audio processing callback.
The callback is called at 80Hz(512/44100), but drawing at 20Hz.
This means, unless you have a 4 times bigger buffer, you can't draw all of them.
But FFTBufferManager holds the same size as audioBuffer.



Here's why.
Not only drawing is slower, but also FFT may take more time than allowed.
"Allowed" means before the next callback is called.
If it takes more time than allowed, the callback is skipped.
In other words, "Allowed" == delay.

The point was, do your job as quickly as possible in the callback,
and do it later in an appropriate thread.