我正在尝试创建一个音频可视化工具。
我使用快速傅立叶变换来查找频率。
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)?
最佳答案
FFT 的幅度输出通常在 decibels 中可视化正是因为这个原因。当存在大组件时,分贝允许仍然看到非常小的组件。转换很简单。由于 vDSP_zvmags
给出了平方幅度,因此您可以使用以下方法转换为 dB:
dbval = 10 * log10(mag2val);
或参见vDSP_vdbcon
。
可以通过除以 dB 值的最大值来将其标准化在 0 和 1 之间,但您可能不希望动态更改此引用点,因为这会导致恒定幅度的可视化跳跃。最好找出典型范围并标准化为该固定值。
关于ios - FFT 后的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/14891332/