1

我正在尝试通过 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);
}

我还没有找到关于如何做到这一点的任何地方。请帮忙!

4

2 回答 2

2

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

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

于 2011-05-16T19:07:43.313 回答
0

Amplitude values are:

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

Print it after using vdsp_fft_zrip......

于 2011-09-10T15:00:20.777 回答