将 AudioQueueBufferRef 数据传递给 FFT 函数!

发布于 2024-11-07 22:20:52 字数 2010 浏览 0 评论 0原文

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

我没有找到任何关于如何执行此操作的地方。请帮忙!

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!

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

森林迷了鹿 2024-11-14 22:20:52

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

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

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.

怪我入戏太深 2024-11-14 22:20:52

幅度值为:

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

使用vdsp_fft_zrip后打印......

Amplitude values are:

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

Print it after using vdsp_fft_zrip......

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文