2011-05-16 86 views
1

我想通過iPhone上的麥克風計算給定聲音過程的頻率。將AudioQueueBufferRef數據傳遞給FFT函數!

我已閱讀所有關於FFT的文章(包括所有蘋果代碼示例,例如aurioTouch,SpeakHere),但沒有解決這個問題。

我使用AudioQueue,但我怎麼從AudioQueue回調函數(MyInputBufferHandler)inBuffer-> mAudioData將原始數據「AudioQueueBufferRef」。到實際的FFT「DSPSplitComplex」數據類型,所以我可以計算它。所有這些使用Accelerate框架。

// 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]); 
}  
} 

FFT函數。

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); 
} 

我還沒有找到任何地方如何做到這一點。請幫忙!

回答

2

您必須知道音頻緩衝區中數據的C數據類型以及FFT支持的數據類型。如果它們不相同(通常是16位有符號整數與短浮點數),那麼在解包和複製PCM數據數組(在for循環中)時,您將不得不進行轉換。給定實際數據,可以將FFT輸入的虛數陣列歸零。

此外,音頻隊列緩衝區的長度可能與FFT長度不同,因此您可能必須將音頻隊列回調中的數據保存到應用程序內部的另一個隊列中,並讓其他工作線程通過將數據作爲隊列填充到分析/ FFT例程中。

+0

的答案十分感謝 – 2011-05-25 22:24:46

0

幅度值:使用後vdsp_fft_zrip

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

打印......