我正在使用Matlab来获取信号的FFT,而我却陷入了规范化的困境。具体来说,如何将频谱归一化为dBm单位。我知道0.316228是正确的归一化因子,但我的问题与如何正确地归一化二进制数有关。
我创建了以下程序来提出我的问题。只需将其剪切并粘贴到Matlab中即可自行运行。在线查看问题。
特别是,我很困惑如何规范箱子。例如,如果FFT具有索引1:end,其中end是偶数,当我计算FFT幅度谱时,我应该乘以(2 / N)索引2:(end / 2)?同样,奈奎斯特频率(位于索引末端/ 2 + 1)的bin是否归一化为(1 / N)?我知道有很多方法可以根据个人的兴趣进行标准化。假设我正在使用的信号(下面的St)是从ADC捕获的电压。
非常感谢任何反馈。提前谢谢!
%% 1. Create an Example Signal
N = 2^21 ; % N = number of points in time-domain signal (St)
St = 1 + rand(N,1,'single'); % St = example broadband signal (e.g. random noise)
% take FFT
Sf = fft(St, N);
Sf_mag = (2/N)*abs(Sf(1: N/2 + 1));
Sf_dBm = 20*log10(Sf_mag / 0.316228); % 0.316338 is peak voltage of 1 mW into 50 Ohms
% Q: Are Sf_mag and Sf_dBm normalized correctly? (assume 0.316338 is correct
% peak voltage to get 1mW in 50 Ohms)
% Q: Should Sf_mag(fftpoints/2 + 1) = (1/N)*abs(Sf(fftpoints/2 + 1) for correct normalization
% of Nyquist frequency? (since Nyquist frequency is not folded in frequency
% like the others are)
%% 2. Plot Result
% create FFT spectrum x-axis
samplerate = 20e9; % 20 Gsamples/sec
fft_xaxis = single(0 : 1 : N/2)';
fft_xaxis = fft_xaxis * single(samplerate/N);
semilogx(fft_xaxis, Sf_dBm, 'b-')
xlabel('Frequency (Hz)');
ylabel('FFT Magnitude (dBm)');
title('Spectrum of Signal (Blue) vs Frequency (Hz)');
xlim([1e4 1e10]);
grid on;
答案 0 :(得分:5)
我并不完全清楚你想要完成什么,但是这里有一些技巧可以让你调试你自己的程序。
fft([1 1 1 1])
。做fft([1 1 1 1 1 1 1 1])
。特别是,观察输出幅度。这是你期望的吗?
然后做fft([1 -1 1 -1])
。做fft([1 -1 1 -1 1 -1 1 -1])
。重复各种信号长度和频率。这应该允许您相应地标准化您的信号。
此外,对ifft
而不是fft
执行相同的操作。这些是对各种FFT实现的良好健全性检查,因为虽然大多数实现可能会将1/N
置于逆变换之前,但其他实现可能会将1/sqrt(N)
置于正向和反向变换之前。
答案 1 :(得分:0)
看到这个答案: FFT normalization
有些软件包和参考文件对傅立叶系数的归一化有些不了解。
假设有一个真实信号,那么归一化步骤是:
1)频域中的功率必须等于时域中的功率。
2)除了DC项和奈奎斯特项之外,傅里叶系数的大小是重复的(x2)。 DC和奈奎斯特术语仅出现一次。根据数组索引的开始/停止方式,您需要小心。简单地将功率加倍以获得单侧频谱是错误的。
3)要获得功率密度(dBm / Hz),您需要将其标准化为各个频率仓大小。