ios - FFT 后的值

标签 ios objective-c fft accelerate-framework

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

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

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/

相关文章:

matlab - 计算信号的 fft 频谱并获得正确的幅度

ios - 使用 AVPlayer 播放的视频从 swift3 的容器 View 中消失

ios - 第二次加载 ViewController 时,self.navigationController 为 nil

ios - XCUITest、UIDatePicker、adjustToPickerWheelValue

iOS Paypal MPL 开发者错误

c++ - Windows 上的 FFT 库编译

python - 如何缩放基于 FFT 的互相关,使其峰值等于 Pearson's rho

ios - 带有 child 语音的 iOS 文本转语音框架

iphone - 我如何检测 rss 提要中的新项目

ios - 在iOS上的应用之间共享数据