【问题标题】:Values after FFTFFT 后的值
【发布时间】: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)?

【问题讨论】:

    标签: ios objective-c fft accelerate-framework


    【解决方案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) 标志

    希望有帮助

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-10-11
      • 2016-11-06
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多