我使用 awgn() 生成具有给定量 SNR 的信号“x”,在本例中为 10 [第 19 行]。
我正在尝试使用自己的代码准确评估它创建的信号的 SNR,但我计算的本底噪声信号增益比应有的要多得多[第 44 行]。
f = 1000;
t = 0:.0001:1;
x = cos(2*pi*f*t);
len = length(x);
fs = (0:len-1)/t;
plot(t,x)
xlim([0 .01])
title('Signal "x"')
%fft of x
X = fftshift(abs(fft(x)));
TF = (-len/2:len/2-1)*fs/len;
plot(TF,X)
title('FFT of "x"')
%add noise
y = awgn(x,10);
plot(t,y)
xlim([0 .01])
title('Signal "y"')
%fft of y
Y = 10*log(abs(fftshift(fft(y)/length(y))));
plot(TF,Y)
grid
title('FFT of "y"')
xlim([500 1500])
%Finding power of signal
MinH = max(Y) -10;
[pks,locs] = findpeaks(Y,"MinPeakHeight",MinH)
Peaks = tf(locs);
fcSig1 = 0.5*(Peaks(1,1) + Peaks(1,2))
S = (pks(1,1)+pks(1,2))/2
%Finding power of white noise
[negpks,neglocs] = findpeaks(-(abs(Y)));
avgN = sum(negpks)/length(negpks);
N = avgN
SNR = S-N %in dB
我尝试对信号的平均功率、本底噪声的平均功率进行采样,将这些功率转换为 dB 单位,然后从信号 dBm 中减去噪声 dBm。
我的结果在这里: 如果无法打开: [S = -7.1313,N = -55.5702,SNR = 48.4389(比我的输入 10 高 38dB)]
我的想法是我对本底噪声的采样不准确,或者我需要考虑带宽,但我不知道该怎么做。
如有任何建议或意见,我们将不胜感激!
这可能不是您正在寻找的答案,但 Matlab 确实有一个名为
snr
的函数。定义在这里:https://au.mathworks.com/help/signal/ref/snr.html。它的计算方式是使用信号的和平方根,因此它是使用时域而不是频域来计算的。例如:
%%
f = 100;
fs = 1000;
t = 0:1/fs:1-1/fs;
x = cos(2*pi*f*t);
% fft of x
X = 10*log(abs(fft(x)/length(x)));
TF = linspace(0,fs,length(x));
%add noise
%y = awgn(x,10);
% I don't have 2023, so no awgn, but 10dB is about 3*amplitude
n = rand(size(x));
n = n*2;
n = n-1;
n = n / 3;
y = x+n;
%fft of y
figure;
subplot(2,1,1)
plot(TF,X)
grid
title('magnitude spectrum of "x"')
xlim([0 fs/2])
subplot(2,1,2)
Y = 10*log(abs(fft(y)/length(y)));
plot(TF,Y)
grid
title('magnitude spectrum of "y"')
xlim([0 fs/2])
s = snr(x,y-x)
% or:
r = mag2db(rssq(x)/rssq(x-y))
输出:
s =
11.3894
r =
11.3894
所以,不完全是 10,但我只是使用了粗略估计(6dB ~= 双振幅,因此 *3 约为 10dB)来计算噪声等级。
我把事情整理了一下。例如。我首先定义采样率,然后用它来确定向量长度等。对于 1D DFT,您实际上并不需要
fftshift
。这样,频率仓的定义就更加简单。