Reply by mnen...@elisanet.fi●August 13, 20072007-08-13
Hello,
below a short example program that I hope does what you expect.
It calculates SNR from the normalized crosscorrelation coefficient, obtained via
FFT.
c^2 is the amount of power in a explained by b (and vice versa). The remainder
1-c^2 is uncorrelated (=noise).
SNR follows as c^2/(1-c^2).
Cheers
Markus
% SNR detection via FFT / correlation
% Markus Nentwig 2007
% this program is in the public domain, provided without any warranty
close all; clear all;
Ne536;
% transmitted signal
a=randn(1, N);
x=[];
y=[];
for SNR_in_dB=-30:5:60
vRatio=power(10, -SNR_in_dB/20);
% construct time shifted, noisy "received" signal
b=circshift(a, [0, -1234])+vRatio*randn(1, N);
% scale to arbitrary amplitude...
a=a*12345;
b=b*23456;
% find peak (should be 1234+1)
maxBin=find(abs(corr)=s(max(corr)));
cs(corr(maxBin));
% c is the ratio of "voltage" in a explained by b and vice versa
% c^2 is the ratio of power => signal
% 1-c^2 is the remaining part unexplained by signal => noise
% note, low SNRs require a longer signal, because part of the noise will
randomly correlate with the reference signal.
SNR=c^2/(1-c^2);
SNR_out_dB*log10(SNR);
x=[x, SNR_in_dB];
y=[y, SNR_out_dB];
end
plot(x, y, '+-');
xlabel('SNR in/dB'); ylabel('SNR out/dB');
Reply by Pradeep Hegde●August 9, 20072007-08-09
hello,
As far as my knowledge goes,
InBandSignalLeft += fft[i] * fft[i];
also,
InBandNoiseLeft += fft[i] * fft[i];
and then you can convert it to the dB scale,
SNR = 20*log10(sqrt(InBandSignalLeft)/sqrt(InBandNoiseLeft));
you are assuming that every signal component which is not around the
viccinity of the peak is noise, you are also assuming that noise is not
present in the viccinity of the peak, these may not be necessarily true....
hope this helps...
Pradeep
On 8/7/07, je0062002 wrote: >
> Dear All
> Does anyone here already coded a SNR computation from FFT bins ?
> I already coded a FFT algo in C, it is ok, but I cannot succeed in
> coding a SNR extraction from the FFT bins.
>
> I use a blackman harris 7 windows (7 bins in signal)
> My FFT table fft[] represents all fft bins in dB
>
> - I search the max bin value from FFT table fft[]
>
> - for(-3 bins to +3 bins around the above max bin) I do :
>
> InBandSignalLeft += (pow(pow(10,(fft[i])/20)),2.0)) );
>
> - for all other FFT bins (all exept DC and the 7 above bins) I do :
>
> InBandNoiseLeft += (pow(pow(10,(fft[i])/20)),2.0)) );
>
> Then : SNR = 20*log10(sqrt(InBandSignalLeft)/sqrt(InBandNoiseLeft))
>
> The above SNR does not provide similar results than spectralab for
> instance
>
> Any help would be greatly appreciated !
> Thanks
>
--
It ain't how hard u can hit, its about how hard u can get hit and keep
moving forward, thats how winning is done...
Reply by je0062002●August 8, 20072007-08-08
Dear All
Does anyone here already coded a SNR computation from FFT bins ?
I already coded a FFT algo in C, it is ok, but I cannot succeed in
coding a SNR extraction from the FFT bins.
I use a blackman harris 7 windows (7 bins in signal)
My FFT table fft[] represents all fft bins in dB
- I search the max bin value from FFT table fft[]
- for(-3 bins to +3 bins around the above max bin) I do :