将AudioQueueBufferRef数据传递给FFT函数!

时间:2011-05-16 18:39:20

标签: iphone fft audioqueueservices frequency-analysis

我正试图通过iphone上的麦克风计算给定声音过程的频率。

我已经阅读了有关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 个答案:

答案 0 :(得分:2)

您必须知道音频缓冲区中数据的C数据类型以及FFT支持的数据类型。如果它们不相同(通常是16位有符号整数与短浮点数),则必须在解包和复制PCM数据数组时进行转换(在for循环中)。给定实际数据,您可以将输入的虚数组清零。

此外,音频队列缓冲区的长度可能与FFT长度不同,因此您可能必须将数据从音频队列回调保存到应用程序内部的另一个队列,并让另一个工作线程通过当队列填满时,数据到您的分析/ FFT例程。

答案 1 :(得分:0)

振幅值为:

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

使用vdsp_fft_zrip ......

后打印