2013-02-15 259 views
2

我试图创建一个音频可视化器。FFT后的值

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

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

出于这个原因,FFT的幅度输出通常在decibels中可视化。当存在大型组件时,分贝允许仍然可以看到非常小的组件。转换很简单。由于vDSP_zvmags给人的平方大小,就可以转换为分贝:

dbval = 10 * log10(mag2val); 

或看到vDSP_vdbcon

这可以通过除以dB值的最大值在0和1之间进行归一化,但您可能不希望动态更改此参考点,因为它会导致恒定量值的可视化跳转。只需找出哪些范围是典型的并且归一化为固定值就可能会更好。

+0

CoreAudio中的浮点采样应该将输入的满量程值1.0标准化为1.0。 – iluvcapra 2013-02-15 21:18:05

+0

我对音频内容相当陌生,而且我对理解如何从FFT获得分贝有点麻烦。你能否有机会解释这些步骤,或指出一个好的解释? =) – Joe 2015-03-22 23:17:16

1

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

按照苹果的文档: vDSP_zvmags计算复杂的矢量A的平方值

我的意思是大小为每Pitagora定理,你应该使用 vDSP_vpythg ;

(矢量毕达哥拉斯单精度)。

之后,你可以使用带有标志 __vDSP_F到 功率(0)或幅度(1)标志

希望这有助于分贝转换vDSP_vdbcon