generate signals with different SNR

Hello all
I need to generate random white Gaussian noise of 3 second length. I also need to add 03 sinusoidal (say 10 KHz) pulses of 100 ms duration and SNRs of 1 dB, -10 dB and -20 dB respectively at random locations in 3 sec length Gaussian noise.
Can any one kindly help me with MATLAB code?
Also how can i verify the results i.e. the required SNR has been generated?
Thanks

3 comentarios

Image Analyst
Image Analyst el 13 de En. de 2018
What's your sampling rate? How many elements do you want to use to represent this 3 second length?
nauman
nauman el 14 de En. de 2018
My sampling rate is 100 K samples/s. This will result in 300 K samples for 3s length signal
nauman
nauman el 3 de Feb. de 2018
Any help in this regard is highly appreciated plz.

Iniciar sesión para comentar.

 Respuesta aceptada

Shae Morgan
Shae Morgan el 7 de Ag. de 2020
Editada: Shae Morgan el 30 de Oct. de 2020
Here's a solution! Hope it's helpful
%setup
fs=100000;
noise_dur=3;
sine_freq=10000;
sine_dur=.1;
t=0:1/fs:sine_dur-1/fs;
snr=[1,-10,-20];
sine_samps=sine_dur*fs;
%generate noise
noise=randn(fs*noise_dur,1); %generate gaussian noise
norm_noise=noise./max(noise); %scale noise
rms_noise=rms(norm_noise); %get the rms amplitude to which the sines will be compared
%generate the 3 signals at the 3 SNRs and check
for i=1:length(snr)
amp=10^(snr(i)/20)*rms_noise;
x=sin(2*pi*sine_freq*t);
xt(i,:) = (x./rms(x)).*amp;
check_snr=20*log10(rms(xt(i,:))/rms_noise)
end
%set random location 1
a=1;
b=length(noise)-sine_samps;
idx1=round(rand()*(b-a)+a);
%get random location 2 that doesn't overlap with 1
overlap=1;
while overlap==1
idx2=rand()*(b-a)+a;
if idx2<=idx1-sine_samps || idx2>idx1+sine_samps
overlap=0;
end
end
idx2=round(idx2);
%get random location 3 that doesn't overlay 1 or 2
overlap=1;
while overlap==1
idx3=rand()*(b-a)+a;
if idx3<=idx1-sine_samps || idx3>idx1+sine_samps
if idx3<=idx2-sine_samps || idx3>idx2+sine_samps
idx3=round(idx3);
overlap=0;
end
end
end
%set the locations of the stimuli and pad zeros in between
[loc,idx]=sort([idx1 idx2,idx3]);
pad1=zeros(loc(1),1);
pad2=zeros(loc(2)-loc(1)-10000,1);
pad3=zeros(loc(3)-loc(2)-10000,1);
pad4=zeros(length(noise)-loc(3)-10000,1);
stim=[pad1; xt(idx(1),:)'; pad2; xt(idx(2),:)'; pad3; xt(idx(3),:)'; pad4];
%combine,play,and plot final sound
final=stim+norm_noise;
sound(final,fs)
plot(final) %stimulus is masked by the noise
plot(stim) %plot to see the stimuli

5 comentarios

nauman
nauman el 7 de Ag. de 2020
Thanks a lot for help. Kindly also tell how i can varify that these generated pulses are of required SNRs?
Thanks & Regards
That was included in the original answer. If you run the code, during the for-loop, it checks the SNR relative to the noise level and confirms each generated sine is of the appropriate level with reference to the noise.
%generate the 3 signals at the 3 SNRs and check
for i=1:length(snr)
amp=10^(snr(i)/20)*rms_noise;
x=sin(2*pi*sine_freq*t);
xt(i,:) = (x./rms(x)).*amp;
check_snr=20*log10(rms(xt(i,:))/rms_noise) %<----this line
end
If this answer has been useful, please accept.
Thanks!
Shae Morgan
Shae Morgan el 7 de Ag. de 2020
If you want to make sure that the local SNR is exact, you'll need to find the RMS of the samples of noise at the times where the tones are played, and then set the amplitude of the sine waves based on a comparison there.
Daniel May
Daniel May el 29 de Oct. de 2020
I believe:
final=stim+noise;
should be:
final=stim+norm_noise;
-Daniel
Shae Morgan
Shae Morgan el 30 de Oct. de 2020
@Daniel - thanks for catching! I updated to reflect this

Iniciar sesión para comentar.

Más respuestas (1)

Etiquetas

Preguntada:

el 13 de En. de 2018

Comentada:

el 30 de Oct. de 2020

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!

Translated by