FFT 后的值

Posted

技术标签:

【中文标题】FFT 后的值【英文标题】:Values after FFT 【发布时间】:2013-02-15 09:13:03 【问题描述】:

我正在尝试创建一个音频可视化工具。

我正在使用快速傅里叶变换来查找频率。

memset(_window, 0, sizeof(float)*_windowSize);
memset(_A.imagp, 0, nOver2 * sizeof(float));

vDSP_hann_window(_window, _windowSize, vDSP_HANN_NORM);

for (int i=0; i < _windowSize; i++) 
    if (player && ioData) 
        _inPutBuffer[i] = ((SInt16*) ioData->mBuffers[0].mData)[i];
    


vDSP_vmul(_inPutBuffer, 1, _window, 1, _transferBuffer, 1, _windowSize);

vDSP_ctoz((COMPLEX*)_transferBuffer, 2, &(_A), 1, nOver2);

vDSP_fft_zrip(_fftSetup, &_A, stride, log2n, FFT_FORWARD);

vDSP_vsmul(_A.realp, 1, &_scale, _A.realp, 1, nOver2);
vDSP_vsmul(_A.imagp, 1, &_scale, _A.imagp, 1, nOver2);

_A.imagp[0] = 0.0f;

vDSP_zvmags(&_A, 1, _obtainedReal, 1, nOver2);

float frequencyArray[n];

for (int i=1; i <=kIndicatorsCount; i++ ) 
    float res = 0;
    for (int j=0; j <=32; j++) 
        res += _obtainedReal[i*32+j];
    
    res = res / 32;
    OutputBuff[i] = res;

但是输出的值是非常不同的,例如,一种情况下输出值可以是0到1,另一种情况下输出值可以是0到5.0E+6。

是否可以将输出值带入一定范围(例如0到1)?

【问题讨论】:

【参考方案1】:

正因如此,FFT 的幅度输出通常在 decibels 中可视化。当存在大组件时,分贝允许仍然看到非常小的组件。转换很简单。由于vDSP_zvmags 给出平方幅度,您可以使用以下方法转换为 dB:

dbval = 10 * log10(mag2val);

或查看vDSP_vdbcon

这可以通过除以 dB 值的最大值在 0 和 1 之间进行归一化,但您可能不想动态更改此参考点,因为它会导致恒定幅度的可视化跳跃。最好只弄清楚哪些范围是典型的并将其标准化为该固定值。

【讨论】:

CoreAudio 中的浮点样本应该将 1.0 标准化为输入的满量程值。 我对音频很陌生,我在理解如何从 FFT 到分贝时遇到了一些麻烦。您能否稍微解释一下这些步骤,或者指出一个好的解释? =)【参考方案2】:

问题应该是vDSP_zvmags(&_A, 1, _obtainedReal, 1, nOver2);

根据 Apple 文档: vDSP_zvmags 计算复向量 A 的平方幅度。

我的意思是幅度是根据 Pitagora 定理,你应该使用 vDSP_vpythg (矢量毕达哥拉斯;单精度。)

之后,您可以使用带有标志的分贝转换 vDSP_vdbcon __vDSP_F 到 功率 (0) 或幅度 (1) 标志

希望有帮助

【讨论】:

以上是关于FFT 后的值的主要内容,如果未能解决你的问题,请参考以下文章

np.fft.fft()结果的物理意义

使用 FFT 的实时混响算法

什么是FFT算法?DSP是什么?

FFT 频率分析似乎得到了错误的值

信号处理中FFT后的意义及常用处理方法

怎样用C语言实现FFT算法啊?