2

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

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

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)?

4

2 回答 2

4

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

dbval = 10 * log10(mag2val);

或见vDSP_vdbcon

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

于 2013-02-15T14:09:17.297 回答
1

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

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

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

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

希望这有帮助

于 2013-02-18T18:42:39.297 回答