FFT噩梦)

时间:2013-08-09 17:47:28

标签: c++ fft

我正在使用Ooura的FFT来分析一些白噪声(持续时间为75368 smp,有44100个噪声样本)。我得到的结果很奇怪:即使除以样本数量,我的数据还不到1.0?

我正在使用RDFT和反RDFT

实际上我的结果如下:

m1 3.47157
m1 8.50726
m1 29.0233
m1 9.64618
m1 43.2969
m1 60.7396
m1 48.3495
m1 35.8336
m1 32.7611
m1 24.1925
m1 26.8244
m1 17.9448
m1 29.7936
m1 23.1585
m1 15.1243
m1 8.89132
m1 14.6676
m1 18.1515
m1 27.5357
m1 5.6661
m1 19.0589

,FFT大小为4096,峰值为:79.119

我希望结果只接近一个数字(如1.0或其他)

如果我对音量应用简单的乘法(如音量),声音会像奇怪的滤波器那样改变 ......

这里是我用来从re / im转换为幅度/阶段的函数:

double SuperFFT::_GetPhase(double real, double imaginary)
 {
      return atan2(imaginary, real);
 }

 double SuperFFT::_GetMagnitude(double real, double imaginary)
 {
    return sqrt((real * real) + (imaginary * imaginary));
 } 

阶段似乎很好(保持在-PI和PI之间)

如果我在240hz(持续75368个样本)传递一个简单的正弦,我有这些幅度

m1 0.262643
m1 0.369384
m1 0.543982
m1 0.851133
m1 1.44518
m1 2.76168
m1 6.37861
m1 21.2081
m1 239.998
m1 775.211
m1 585.819
m1 63.0807
m1 12.06
m1 4.37815
m1 2.07803
m1 1.14897
m1 0.701917
m1 0.460003
m1 0.317885
m1 0.228747

如果我除以持续时间,则接近1,乘以100是正常的吗?

当我乘以幅度时,为什么声音会被破坏?我的FFT坏了还是我遗失了什么?

感谢您的帮助

编辑:我当然使用OLA

杰夫

1 个答案:

答案 0 :(得分:2)

FFT实现通常忽略缩放,允许在FFT期间发生值的一些“自然”乘法。这是因为缩放通常并不重要(例如,您计算的相位不随缩放而变化,并且信号的某些方面之间的关系不依赖于比例),并且因为调整缩放比例可能更有效操作中的一个点而不是每个FFT,逆FFT和其他操作。

通过在第一个元素中将输入数组设置为1,在所有其他元素中将输入数组设置为0,执行FFT并检查结果,可以找到由您使用的FFT引起的缩放。很可能每个输出元素的实部都会有1。在这种情况下,输入的总“能量”乘以N,其中N是输入元素的数量。

(因为你似乎正在做一个真实到复杂的变换,这里有一些微妙之处:N个实数输入产生N个复数输出。但是,它们是对称的。对于其中两个,元素是它自己的复共轭对于剩下的N-2,其中一半是另一半的共轭。因此,大多数FFT实现只返回两个实数和N / 2-1复数元素。剩下的结果是暗示:两个缺失的虚部是零,缺失的N / 2-1复数元素是返回元素的共轭。当计算信号的总能量时,我的意思是从所有N个结果计算的能量,而不仅仅是明确返回的那些。)

任何一个输出元素可以具有的最大可能幅度是所有输入的总能量。当输入是一个完美的正弦波(任何相位)时会发生这种情况:它的所有能量都是一个频率,没有任何其他能量。

因此,要计算任何输出元素可能具有的最大值,请将输入可能具有的最大能量乘以FFT的缩放。然后,为了使输出标准化,使得没有输出超过一个,请乘以该乘积的倒数。