SNR Estimation Overview
In digital signal processing, estimating the Signal-to-Noise Ratio (SNR) accurately is crucial. Below, we demonstrate how to calculate SNR from periodogram and FFT bins using the Kaiser Window. The beta (β) parameter is the key—it allows you to control the trade-off between main-lobe width and side-lobe levels for precise spectral analysis.
1 Define Sampling rate and Time vector
2 Compute FFT and Periodogram PSD
3 Identify Signal Bin and Frequency resolution
4 Segment Signal Power from Noise floor
5 Logarithmic calculation of SNR in dB
Method 1: Estimation from FFT Bins
This approach uses a Hamming window to estimate SNR directly from the spectral bins.
MATLAB Source Code
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);
Method 2: Using Kaiser Window
Optimized spectral estimation using the Kaiser window (Beta=38) for better side-lobe suppression.
MATLAB Source Code
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);
Further Reading
Fourier Transform Main Page >
Online Signal Processing Simulations Main Page >