蟒蛇啁啾的fft幅度

时间:2015-04-01 09:58:42

标签: python signal-processing fft dft

我见过类似的问题,但我似乎无法做到这一点。如果我在概念上或代码方面误解某些东西,希望你能猜对。 基本上我正在从1khz到10khz的持续时间1s与48khz fs进行啁啾。 我只是想用正确的幅度绘制这个啁啾的频率spetrum / fft。代码是:

from scipy.fftpack import fft

N = 48000
fs = 48000.0
sine_list_x = []
K = (10000.0 - 1000.0)/(48000.0)
for x in range(N):
    sine_list_x.append(sin(2*pi*(1000.0*(x/48000.0)+(K/2.0)*(x**2)/(48000.0))))

xf = np.linspace(0.0, fs/2.0, N/2)
yf = fft(sine_list_x)
yf = yf / sqrt(N)
#yf = yf / N

fig3 = pl.figure()
ax3 = fig3.add_subplot(111)
ax3.plot(xf, abs(yf[0:N/2]))

上面代码中的图表我在这里显示 enter image description here

我知道fft函数没有正常化,但是我从类似的问题中得到了相互矛盾的信息,这些问题通过sqrt(N),N和其他东西进行归一化..

如果我正确归一化,我期望在图中看到的是幅度为1,因为这是啁啾的幅度。这是一个错误的假设吗?或者我只是在规范化中做错了什么?

2 个答案:

答案 0 :(得分:2)

你希望在这对之间保持的是总功率,它是。因此,如果在sqrt(N)标准化后,您执行以下操作:

print sum(abs(yf*yf)), sum(np.array(sine_list_x)**2)

你得到了

23999.9986331 23999.9986331

应该是。

由于你没有看到纯正弦波,因此很难比较振幅,但功率应始终有效。

答案 1 :(得分:2)

在时域和频率缓慢变化的扫描中,整数个周期(或足够大的周期数)的平方样本总和可近似为

     0.5*N*At*At

其中N是样本数,At是扫描幅度。 对于您给定的参数(N=48000At=1),这将是24000,非常接近@tom10's answer中提供的~23999.9986331的确切值。

另一方面,在频域(查看频谱图)中,完整的频谱可以近似为2个框(通过线性频率扫描可以预期):

  • 您在图表上显示的1000到10000之一
  • 和38000到47000之间的另一个由真实信号的频谱的埃尔米特对称性产生。

在这种情况下,平方(频域)样本的总和可以近似为

     2*((10000-1000)+(47000-38000))*Af*Af == 18000*Af*Af 

现在Parseval's theorem for the disrete Fourier transform声明:

\sum_{n=0}^{N-1} \left|x[n]\right|^2 = \frac{1}{N} \sum_{n=0}^{N-1} \left|X[k]\right|^2

在考虑1/sqrt(N)归一化并替换上述近似值后得到:

     24000 = 18000*Af*Af

因此Af应大约等于sqrt(24000/18000) = 1.1547...,这与您绘制的图表一致。