Here, you can find the SNR of a received signal from periodogram / FFT bins using the Kaiser operator. The beta (β) parameter characterizes the Kaiser window, which controls the trade-off between the main lobe width and the side lobe level.
Steps
- Set up the sampling rate and time vector
- Compute the FFT and periodogram
- Calculate the frequency resolution and signal power
- Exclude the signal power from noise calculation
- Compute the noise power and SNR
MATLAB Code for Estimation of SNR from FFT bins
clc; clear; close all;
% Parameters
fs = 8000; f_tone = 1000; N = 8192;
t = (0:N-1)/fs;
% Generate signal + noise
signal = sin(2*pi*f_tone*t);
SNR_true_dB = 20;
signal_power = mean(signal.^2);
noise_power = signal_power / (10^(SNR_true_dB/10));
noisy_signal = signal + sqrt(noise_power) * randn(1, N);
% Apply window
w = hamming(N)';
windowed_signal = noisy_signal .* w;
U = sum(w.^2)/N;
% FFT and PSD
X = fft(windowed_signal);
f = (0:N-1)*fs/N;
Pxx = abs(X).^2 / (fs * N * U);
% Find signal bin
[~, signal_bin] = min(abs(f - f_tone));
signal_bins = signal_bin-1 : signal_bin+1;
signal_power_est = sum(Pxx(signal_bins));
% Noise estimation
noise_bins = setdiff(1:N/2, signal_bins);
noise_power_est = sum(Pxx(noise_bins));
% Estimate SNR
SNR_est_dB = 10 * log10(signal_power_est / noise_power_est);
fprintf('Estimated SNR from FFT: %.2f dB\n', SNR_est_dB);
MATLAB Code for SNR from PSD using Kaiser Window
clc; clear; close all;
fs = 32000;
t = 0:1/fs:1-1/fs;
x = sin(2*pi*3000*t) + 0.05*randn(size(t)); % Example Signal
N = length(x);
w = kaiser(N, 38);
[Pxx, F] = periodogram(x, w, N, fs);
% SNR Estimation
freq_resolution = abs(F(2)-F(1));
[~, target_idx] = min(abs(F - 3000)); % Find 3kHz index
% Signal Power (using bins around peak)
sig_idx = target_idx-2 : target_idx+2;
Sig_power_val = sum(Pxx(sig_idx)) * freq_resolution;
Sig_power_dB = 10*log10(Sig_power_val);
% Noise Power (excluding signal)
Noise_Pxx = Pxx;
Noise_Pxx(sig_idx) = 0;
N_avg = sum(Noise_Pxx) / (length(Pxx) - length(sig_idx));
N_power_dB = 10*log10(N_avg * fs/2);
SNR = Sig_power_dB - N_power_dB;
fprintf('SNR = %.4f dB\n', SNR);