# Matlab: if given nothing but an audio file, how do I modify it to produce incrementally lower signal to noise ratios?

I have an audio file with a high sampling rate of 250khz. It contains animal noises. I've built a program which counts all the animal noises.

However, I want to find out how robust the program is and find what the minimum signal to noise is for the program to still work.

Hence the plan was to modify my audio file to produce different (incrementally lower) signal to noise ratios.

I would run the program for all of them and since I know how many the program should count, when I start getting lower counts, I will what the minimum signal to noise ratio is.

however I have no idea how to go about doing this. I still don't even know how to find the signal to noise of my audio as it is. my guess was to assume the background noise is similar throughout and hence, copy a section of the audio which has no animal calls, just noise, then use matlabs snr command:

r=snr(audio,backgroundnoise);

can anyone help with how to program this?

It is not enough to just randomly add noise, I need to know the actual signal to noise values in order to be able to quantify the minimum SNR needed for the program to still work

• Many algorithms will depend on the type of noise you add -- white noise, 1/f noise, etc. – Batman May 13 '15 at 23:35
• I believe this is white gaussian noise, because noise produced will likely just be from nature (audio recorded with animals in their cages, at night). Is it possible to just use the backgroundnoise variable instead as this will probably represent the noise better – CaptainObv May 14 '15 at 5:22

I like your noise model, I think that is really the best way to find SNR if you only have access to recordings. Using this same model couldn't you take your backgroundnoise scale it (duplicate it or trim it as necessary) and then add it to the signal? In this sense the noise wouldn't be entirely random but somewhat system specific

edit

in order to calculate your new noise value you would simply rearrange the SNR calculation solving for noise. Then scale the original noise accordingly. you can use some code like this

desired_snr_db = 10;    %change this value

est_signal = audio - backgroundnoise;

%the original matlab equation for SNR is:
%r = 10 * log10(signalPow / noisePow);
%solving for noisePow we get
noisePow = rssq(est_signal(:)).^2 / (10^(desired_snr_db / 10));

new_noise = scale_factor * backgroundnoise;

%add noise to our estimated signal
new_signal = est_signal + new_noise; %you may need to do stretching
%trimming to get the right sizes

new_snr = snr(new_signal - new_noise, new_noise)


if you want you can double check the snr by finding a lull in the new signal and comparing it to the known sounds just as before

• I have also thought about this. First as an update, In the help snr section example, they use a pure signal as their first argument, whereas in my example above, the audio already has noise in it. My assumption is that r=snr(audio-backgroundnoise,backgroundnoise); will find the ACTUAL signal to noise (estimate). I have trimmed backgroundnoise to size, but I don't know what to do next. assuming the snr above is correct, I want to know the snr of this new nosier signal. I assume that simply adding noise will increase energy of audio which will interfere with detection results – CaptainObv May 13 '15 at 20:54
• Please check my edit. I think this method should work to figure out exactly how to scale the signal, let me know what you think – andrew May 13 '15 at 21:39
• I don't know what difference this has but when i open the actual snr.m file I get this for the snr equation with 2 basic arguments: signalPow = rssq(x(:)).^2; noisePow = rssq(y(:)).^2; r = 10 * log10(signalPow / noisePow); While I somewhat understand how your code works, I'm not quite sure if the snr is correct.... original snr is r=snr(audio - backgroundnoise,backgroundnoise); ... r is calculated as 6.4762....Using your code, with 5 as the desired snr, I tried to calculate the new snr ..... r2=snr(new_signal - backgroundnoise,backgroundnoise);..... which gave 6.1385 not 5. any advice? – CaptainObv May 13 '15 at 22:32
• Thanks for that info. I wrote the code from memory, and when I opened matlab (2012) it doens't even have the snr function! I guess it must be a newer addition. In any event I updated the code to use the formulas you found. My code was producing a different result because I was using the Root Mean Square method for calculating signal power, while matlab is using the Root sum square squared (basically rms uses an extra 1/N normalizing factor). The confusing step is calculating rms_new. if you write the equation for rms on paper and solve for NoisePow (instead of r) you will see it agrees – andrew May 13 '15 at 23:04
• I can just about understand the math, which is just simple arrangement, although despite agreeing with it, I don't quite understand why I get different snr values once I check it using r=snr(new_signal - backgroundnoise,backgroundnoise). this should give the same value as desired_snr_db. However, using the data from the link, r=snr(audio - backgroundnoise,backgroundnoise); gives 6.4762 then, if you use desired_snr_db = 5 then 4, then 3, then 2, then 1, you will see that the snr goes down but eventually goes up again expirebox.com/download/bb9997de2dc5bae12fc7184dd2a0eb0f.html – CaptainObv May 13 '15 at 23:32