Question

I am trying to compute the frequency of a given sound process through the microphone on the iphone.

I've read all the post about FFT (including all apple code examples e.g aurioTouch,SpeakHere), but not solution to this problem.

I'm using AudioQueue, but how do I to pass the raw data "AudioQueueBufferRef" from the AudioQueue callback function (MyInputBufferHandler) inBuffer->mAudioData . To the Actual FFT "DSPSplitComplex" datatype, so I can compute it. All this using the Accelerate framework.

// AudioQueue callback function, called when an input buffers has been filled.
void AQRecorder::MyInputBufferHandler(  void      *                             inUserData,
                                     AudioQueueRef                      inAQ,
                                    AudioQueueBufferRef                 inBuffer,
                                    const AudioTimeStamp *              inStartTime,
                                    UInt32                              inNumPackets,
                                    const AudioStreamPacketDescription* inPacketDesc)
{

 for(int i=0; i<inNumPackets; i++) {
            printf("%d ",((int*)inBuffer->mAudioData)[i]);  
 }      
}

The FFT function.

RealFFTUsageAndTiming(){

COMPLEX_SPLIT   A; //DSPSplitComplex datatype 
FFTSetup        setupReal;  
uint32_t        log2n;  
uint32_t        n, nOver2;  
int32_t         stride; 
uint32_t        i;  
float          *originalReal, *obtainedReal;    
float           scale;

/* Set the size of FFT. */  
log2n = N;  
n = 1 << log2n; 
stride = 1; 
nOver2 = n / 2;     

/* Allocate memory for the input operands and check its availability,    
 * use the vector version to get 16-byte alignment. */

A.realp = (float *) malloc(nOver2 * sizeof(float)); 
A.imagp = (float *) malloc(nOver2 * sizeof(float)); 
originalReal = (float *) malloc(n * sizeof(float)); 
obtainedReal = (float *) malloc(n * sizeof(float));

//How do I pass the data from AudioQueue callback to function?
vDSP_fft_zrip(setupReal, &A, stride, log2n, FFT_FORWARD);

vDSP_fft_zrip(setupReal, &A, stride, log2n, FFT_INVERSE);
}

I haven't find anywhere on how to do this. Please help!

Was it helpful?

Solution

You have to know the C data type of the data in the audio buffer and the data types that the FFT supports. If they are not the same (commonly 16-bit signed int versus short float), then you will have to convert while unpacking and copying the arrays of PCM data (in a for loop). Given real data, you can zero out the imaginary array of the input to the FFT.

Also, the length of the Audio Queue buffer may not be the same as the FFT length, so you may have to save the data from the Audio Queue callback to another queue internal to your app, and have another worker thread pass that data to your analysis/FFT routines as the queue fills.

OTHER TIPS

Amplitude values are:

for(i=0;i<nover2;i++) {
    print log10(A.realp[i])
}

Print it after using vdsp_fft_zrip......

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top