python 中线性调频的 fft 振幅
fft amplitude of chirp in python
我看到有人问过类似的问题,但我似乎无法正确回答这个问题。如果我在概念上或代码上误解了某些东西,希望你的猜测能有所帮助。
基本上我正在用 48khz fs 发出从 1khz 到 10khz 持续时间 1s 的线性调频。
我只是想用正确的振幅绘制此线性调频信号的频率 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]))
我在此处显示的上述代码的情节
我知道 fft 函数没有归一化,但我从类似的问题中得到了一些相互矛盾的信息,这些问题说通过 sqrt(N)、N 和其他东西进行归一化..
如果我正确归一化,我希望在图中看到的是 1 的振幅,因为这是线性调频信号的振幅。这是一个错误的假设吗?或者我只是在规范化中做错了什么?
你期望在这对之间守恒的是总功率,它是。因此,如果在 sqrt(N)
归一化后,您执行:
print sum(abs(yf*yf)), sum(np.array(sine_list_x)**2)
你得到
23999.9986331 23999.9986331
应该是。
由于您查看的不是纯正弦波,因此很难比较振幅,但功率应该始终有效。
在时域中,对于频率缓慢变化的扫描,整数个周期(或足够大的周期)的平方样本之和可以近似为
0.5*N*At*At
其中 N
是采样数,At
是扫描幅度。
对于给定的参数(N=48000
、At=1
),这将是 24000,非常接近 .
中提供的 ~23999.9986331 的精确值
另一方面,在频域中(查看频谱图),完整的频谱可以用 2 个框来近似(正如线性频率扫描所预期的那样):
- 您在图表上显示的 1000 到 10000 中的一个
- 和另一个从 38000 到 47000 的实数信号频谱的厄米特对称性。
这种情况下的平方(频域)样本之和可以近似为
((10000-1000)+(47000-38000))*Af*Af == 18000*Af*Af
现在 Parseval's theorem for the disrete Fourier transform 指出:
在考虑 1/sqrt(N)
归一化并代入上面找到的近似值后得出:
24000 = 18000*Af*Af
因此Af
应该约等于sqrt(24000/18000) = 1.1547...
,这与您绘制的图表一致。
我看到有人问过类似的问题,但我似乎无法正确回答这个问题。如果我在概念上或代码上误解了某些东西,希望你的猜测能有所帮助。 基本上我正在用 48khz fs 发出从 1khz 到 10khz 持续时间 1s 的线性调频。 我只是想用正确的振幅绘制此线性调频信号的频率 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]))
我在此处显示的上述代码的情节
我知道 fft 函数没有归一化,但我从类似的问题中得到了一些相互矛盾的信息,这些问题说通过 sqrt(N)、N 和其他东西进行归一化..
如果我正确归一化,我希望在图中看到的是 1 的振幅,因为这是线性调频信号的振幅。这是一个错误的假设吗?或者我只是在规范化中做错了什么?
你期望在这对之间守恒的是总功率,它是。因此,如果在 sqrt(N)
归一化后,您执行:
print sum(abs(yf*yf)), sum(np.array(sine_list_x)**2)
你得到
23999.9986331 23999.9986331
应该是。
由于您查看的不是纯正弦波,因此很难比较振幅,但功率应该始终有效。
在时域中,对于频率缓慢变化的扫描,整数个周期(或足够大的周期)的平方样本之和可以近似为
0.5*N*At*At
其中 N
是采样数,At
是扫描幅度。
对于给定的参数(N=48000
、At=1
),这将是 24000,非常接近
另一方面,在频域中(查看频谱图),完整的频谱可以用 2 个框来近似(正如线性频率扫描所预期的那样):
- 您在图表上显示的 1000 到 10000 中的一个
- 和另一个从 38000 到 47000 的实数信号频谱的厄米特对称性。
这种情况下的平方(频域)样本之和可以近似为
((10000-1000)+(47000-38000))*Af*Af == 18000*Af*Af
现在 Parseval's theorem for the disrete Fourier transform 指出:
在考虑 1/sqrt(N)
归一化并代入上面找到的近似值后得出:
24000 = 18000*Af*Af
因此Af
应该约等于sqrt(24000/18000) = 1.1547...
,这与您绘制的图表一致。