OS X 环境中的音频文件 FFT

发布于 2024-08-15 20:27:07 字数 154 浏览 1 评论 0原文

我希望在 OS X 上对线性 PCM 音频文件(可能具有多个音频通道)执行 FFT。解决此问题的最佳方法是什么?

多个消息来源表明 Apple 的 Accelerate Framework 正是我所需要的。如果是这样,我应该如何提取并正确准备浮点数据以供这些 FFT 函数使用?

I'm looking to perform an FFT on a linear PCM audio file (with potentially more than one audio channel) on OS X. What is the best way to go about this?

Several sources have indicated that Apple's Accelerate Framework is what I need. If so, how should I extract and properly prepare the floating point data for use in those FFT functions?

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

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

发布评论

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

评论(3

诺曦 2024-08-22 20:27:07

这大致就是您想要做的事情。填写您自己的输入和输出函数。

    // Stick new data into inData, a (float*) array
    fetchFreshData(inData); 

    // (You might want to window the signal here... )
    doSomeWindowing(inData);

    // Convert the data into a DSPSplitComplex 
    // Pardon the C++ here. Also, you should pre-allocate this, and NOT
    // make a fresh one each time you do an FFT. 
    mComplexData = new DSPSplitComplex;
    float *realpart = (float *)calloc(mNumFrequencies, sizeof(float));
    float *imagpart = (float *)calloc(mNumFrequencies, sizeof(float));
    mComplexData->realp = realpart;
    mComplexData->imagp = imagpart;

    vDSP_ctoz((DSPComplex *)inData, 2, mComplexData, 1, mNumFrequencies);

    // Calculate the FFT
    // ( I'm assuming here you've already called vDSP_create_fftsetup() )
    vDSP_fft_zrip(mFFTSetup, mComplexData, 1, log2f(mNumFrequencies), FFT_FORWARD);

    // Don't need that frequency
    mComplexData->imagp[0] = 0.0;

    // Scale the data
    float scale = (float) 1.0 / (2 * (float)mSignalLength);
    vDSP_vsmul(mComplexData->realp, 1, &scale, mComplexData->realp, 1, mNumFrequencies);
    vDSP_vsmul(mComplexData->imagp, 1, &scale, mComplexData->imagp, 1, mNumFrequencies);

    // Convert the complex data into something usable
    // spectrumData is also a (float*) of size mNumFrequencies
    vDSP_zvabs(mComplexData, 1, spectrumData, 1, mNumFrequencies);

    // All done!
    doSomethingWithYourSpectrumData(spectrumData);

希望有帮助。

Here's roughly what you want to do. Fill in your own input and output functions.

    // Stick new data into inData, a (float*) array
    fetchFreshData(inData); 

    // (You might want to window the signal here... )
    doSomeWindowing(inData);

    // Convert the data into a DSPSplitComplex 
    // Pardon the C++ here. Also, you should pre-allocate this, and NOT
    // make a fresh one each time you do an FFT. 
    mComplexData = new DSPSplitComplex;
    float *realpart = (float *)calloc(mNumFrequencies, sizeof(float));
    float *imagpart = (float *)calloc(mNumFrequencies, sizeof(float));
    mComplexData->realp = realpart;
    mComplexData->imagp = imagpart;

    vDSP_ctoz((DSPComplex *)inData, 2, mComplexData, 1, mNumFrequencies);

    // Calculate the FFT
    // ( I'm assuming here you've already called vDSP_create_fftsetup() )
    vDSP_fft_zrip(mFFTSetup, mComplexData, 1, log2f(mNumFrequencies), FFT_FORWARD);

    // Don't need that frequency
    mComplexData->imagp[0] = 0.0;

    // Scale the data
    float scale = (float) 1.0 / (2 * (float)mSignalLength);
    vDSP_vsmul(mComplexData->realp, 1, &scale, mComplexData->realp, 1, mNumFrequencies);
    vDSP_vsmul(mComplexData->imagp, 1, &scale, mComplexData->imagp, 1, mNumFrequencies);

    // Convert the complex data into something usable
    // spectrumData is also a (float*) of size mNumFrequencies
    vDSP_zvabs(mComplexData, 1, spectrumData, 1, mNumFrequencies);

    // All done!
    doSomethingWithYourSpectrumData(spectrumData);

Hope that helps.

绮筵 2024-08-22 20:27:07

对音频数据进行 FFT 时,样本应进入实部,虚部应为零。

大多数 FFT 库(包括 Apple 的 vDSP)都包含一种称为“真实 FFT”的方法,其中输入是真实的(没有虚数分量)并且输出是复数。

When doing an FFT on audio data, the samples should go into the real portion and the imaginary portion should be zero.

Most FFT libraries, including Apple's vDSP, include a method called a "real FFT", where the input is real (no imaginary component) and the output is complex.

ゞ记忆︶ㄣ 2024-08-22 20:27:07

在我看来,您应该研究 Core Audio...我对它不是很熟悉,但看起来它应该已经为您提供了通道解交错,并且它直接与 PCM 数据一起工作。由于我不太熟悉,对此持保留态度,但我会尝试将 FFT 放入音频单元中,将单个通道的 PCM 数据作为输入,将 FFT 的结果存储在可访问的地方,然后传递输入一直到输出。

就实际执行 FFT 而言,对我来说,主要挑战似乎是将 PCM 输入强制为 FFT 例程想要操作的双 * 向量。查看 vDSP.h (加速框架的一部分),我看到像 vDSP_vflt16D (将 16 位整数向量转换为双精度实数向量)这样的函数,它看起来可以解决你的问题。

核心音频简介

It seems to me that you should be looking into Core Audio... I'm not very familiar with it, but it looks like it should get the channel deinterleaving for you already, and it works directly with PCM data. Because of my low familiarity, take this with a grain of salt, but I'd try putting the FFT in an Audio Unit, taking a single channel of PCM data as input, storing the results of the FFT somewhere accessible, and passing the input through to the output.

As far as actually performing the FFT, the main challenge seems, to me, to be in coercing the PCM input to the double * vector that the FFT routine wants to operate against. Looking through vDSP.h (part of the accelerate framework), I see functions like vDSP_vflt16D (to convert a vector of 16-bit integers to a vector of double-precision real numbers), which looks like it'd solve your problem.

Core Audio Introduction

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