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 后的值的主要内容,如果未能解决你的问题,请参考以下文章