Sign in

username:

password:



Not a member?

Search audiodsp



Search tips

Subscribe to audiodsp



audiodsp by Keywords

AAC | ADPCM | Convolution | DAFx | FFT | IIR | Mixer | MP3 | MPEG | MPEG-4

Sponsor

NEW! TMS320C6474: 3x the performance. 1/3 the cost. Three 1 GHz cores on 1 chip.

Discussion Groups

Discussion Groups | Audio Signal Processing | Extracting SNR from FFT

Technical discussions related to Audio Signal Processing (digital effects, acoustics, noise reduction, musical signal processing, etc).

  

Post a new Thread

Extracting SNR from FFT - je0062002 - Aug 8 9:35:42 2007



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



(You need to be a member of audiodsp -- send a blank email to audiodsp-subscribe@yahoogroups.com )

Re: Extracting SNR from FFT - Pradeep Hegde - Aug 9 13:27:21 2007

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 <h...@hotmail.com> 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...



(You need to be a member of audiodsp -- send a blank email to audiodsp-subscribe@yahoogroups.com )

Re: Extracting SNR from FFT - mnen...@elisanet.fi - Aug 13 8:50:39 2007

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;
N=65536;

% 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;

% ... and normalize
ea=sum(a .* conj(a)) / N;
eb=sum(b .* conj(b)) / N;
a=a/sqrt(ea);
b=b/sqrt(eb);

% crosscorrelation
corr=ifft(fft(a) .* conj(fft(b)))/N;

% find peak (should be 1234+1)
maxBin=find(abs(corr)==abs(max(corr)));
c=abs(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=10*log10(SNR);
x=[x, SNR_in_dB];
y=[y, SNR_out_dB];
end

plot(x, y, '+-');
xlabel('SNR in/dB'); ylabel('SNR out/dB');



(You need to be a member of audiodsp -- send a blank email to audiodsp-subscribe@yahoogroups.com )