Adding a Controlled Amount of Noise to a Noise-Free Signal

Rick Lyons January 3, 201221 comments Coded in Matlab

The following gives two snippets of Matlab code. The first snippet is a function whose inputs are: (1) a real-valued signal, and (2) a desired signal-to-noise ratio (SNR) measured in dB. That 'SNR_Set()' function returns the real-valued input 'Signal' contaminated with normally-distributed, zero-mean, random noise.  The signal-to-noise ratio (SNR in dB) of the output 'Noisy_Signal' signal is controlled by the input 'Desired_SNR_dB' argument measured in dB.

The second snippet of code is a short routine that tests the 'SNR_Set()' function code. Be aware that you're dealing with random signals. So a single output signal's SNR will not be exactly equal to the desired SNR. But if you run the code 100 times, the 'average' of the SNRs of your results will be quite close to your desired SNR.

function [Noisy_Signal] = SNR_Set(Signal, Desired_SNR_dB)
%
%   SNR_Set(x, Desired_SNR_dB) returns the real-valued 
%   input 'Signal' contaminated with normally-distributed, 
%   zero-mean, random noise.  The signal-to-noise ratio   
%   (SNR in dB) of the output 'Noisy_Signal' signal is  
%   controlled by the input 'Desired_SNR_dB' argument measured 
%   in dB.

%   Example:
% 	Npts = 128;                  % Number of time samples
% 	n = 0:Npts-1;                % Time-domain index
% 	Signal = 3*sin(2*pi*3*n/Npts); % Real-valued signal
% 	Desired_SNR_dB = 3;      % Set SNR of output 'Noisy_Signal' to +3 dB
% 	[Noisy_Signal] = SNR_Set(Signal, Desired_SNR_dB);
%
%   Author: Richard Lyons [December 2011]
%******************************************

Npts = length(Signal); % Number of input time samples
Noise = randn(1,Npts); % Generate initial noise; mean zero, variance one

Signal_Power = sum(abs(Signal).*abs(Signal))/Npts;
Noise_Power = sum(abs(Noise).*abs(Noise))/Npts;
	%Initial_SNR = 10*(log10(Signal_Power/Noise_Power));

K = (Signal_Power/Noise_Power)*10^(-Desired_SNR_dB/10);  % Scale factor

New_Noise = sqrt(K)*Noise; % Change Noise level
	%New_Noise_Power = sum(abs(New_Noise).*abs(New_Noise))/Npts
	%New_SNR = 10*(log10(Signal_Power/New_Noise_Power))

Noisy_Signal = Signal + New_Noise;

'SNR_Set()' Function Test Code:
%  Filename SNR_Set_test.m
%
%  Tests the 'SNR_Set()" function.  Adds a predefined 
%  amount of random noise to a noise-free signal such that  
%  the noisy signal has a desired signal-to-noise ratio (SNR).
%
%  Author: Richard Lyons [December 2011]

clear, clc

% Create a noise-free signal
Npts = 128; % Number of time samples
n = 0:Npts-1; % Time-domain index
Cycles = 5;  % Integer number of cycles in noise-free sinwave signal
Signal = 3*sin(2*pi*Cycles*n/Npts); % Real-valued noise-free signal

Desired_SNR_dB = 3 % Set desired SNR in dB

[Noisy_Signal] = SNR_Set(Signal, Desired_SNR_dB); % Generate noisy signal

% Plot original and 'noisy' signals
    figure(1)
    subplot(2,1,1)
    plot(n, Signal, '-bo', 'markersize', 2)
    title('Original Signal')
    grid on, zoom on
    subplot(2,1,2)
    plot(n, Noisy_Signal, '-bo', 'markersize', 2)
    title('Noisy Signal')
    xlabel('Time-samples')
    grid on, zoom on

% Measure SNR in freq domain
Spec = fft(Noisy_Signal);
Spec_Mag = abs(Spec); % Spectral magnitude
    figure(2)
    plot(Spec_Mag, '-bo', 'markersize', 2)
    title('Spec Mag of Noisy Signal')
    xlabel('Freq-samples'), ylabel('Linear')
    grid on, zoom on
Signal_Power = Spec_Mag(Cycles+1)^2 + Spec_Mag(Npts-Cycles+1)^2;
Noise_Power = sum(Spec_Mag.^2) -Signal_Power;
Measured_SNR = 10*log10(Signal_Power/Noise_Power)

Comments:

kaz
Said:
Hi Rick, There is also a Matlab function "awgn" that adds white Gaussian noise in desired SNR in dB Kadhiem
7 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
hemanth27449
Said:
Does the above function add Desired_SNR_dB(dB) of noise signal or its the snr after adding noise to signal?
7 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
Rick Lyons
Said:
Hello hemanth, The value ''Desired_SNR_dB' is the signal to noise ratio, SNR, of the function's output sequence. [-Rick-]
6 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
shanthini
Said:
Yeah Kaz.. i have used awgn.. But here we can add noise in dB...
6 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
Varshavk
Said:
hello rick when i type and run d program it says not enough input arguments.what do i do? cud u help me? rasp
4 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
Rick Lyons
Said:
Hello Varshavk (rasp?), Ha ha. How can I help you if I can't see your Matlab code? If you insert your Matlab code in a 'Comment' box here I'll be happy to examine your code. (I'm sure we can figure out what went wrong.) [-Rick-]
4 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
Varshavk
Said:
function [ Noisy_Signal ] = SNR_Set(Signal,Desired_SNR_dB ) Npts=length(Signal); Noise=randn(1,Npts); Signal_Power=sum(abs(Signal).*abs(Signal))/Npts; Noise_Power=sum(abs(Noise).*abs(Noise))/Npts; k=(Signal_Power/Noise_Power)*10^(-Desired_SNR_dB/10); New_Noise=sqrt(k)*Noise; Noisy_Signal=Signal+New_Noise; end
4 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
Varshavk
Said:
d above ws d program d function program, and it says not enough input arguments....
4 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
Varshavk
Said:
clear all; clc; Npts=128; n=0:Npts-1; Cycles=5; Signal=3*sin(2*pi*Cycles*n/Npts); Desired_SNR_dB=3; [Noisy_Signal]=SNR_Set(Signal,Desired_SNR_dB); figure(1) subplot(2,1,1) plot(n,signal,'-bo','markersize',2); title('original signal'); grid on, zoom on; subplot(2,1,2) plot(n,Noisy_signal,'-bo','markersize',2); title('Noisy signal'); grid on, zoom on;
4 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
Varshavk
Said:
nd dis i blv is the main program
4 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
Varshavk
Said:
haha :D sry! i asked u to reply me as soon as possible coz i had to submit dis program in my college today....:D
4 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
Rick Lyons
Said:
Hello Varshavk (rasp?), When I replace your: plot(n,signal,'-bo','markersize',2); with: plot(n,Signal,'-bo','markersize',2); ('Signal' starts with a capital 'S'.) and I replace your: plot(n,Noisy_signal,'-bo','markersize',2); with plot(n,Noisy_Signal,'-bo','markersize',2); (Capital 'S' in 'Noisy_Signal', again.) then your code runs fine on my machine. [-Rick-]
4 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
Rick Lyons
Said:
Hello Varshavk (rasp?), Here's a suggestion from an old fart: When you're writing to an engineer, do NOT use that darned 'texting' gibberish in your text. Doing so makes it hard for the engineer to understand you, and you do NOT want that to happen! You'll be entering the world of "professionals" soon, so you should start writing like one. Write your text in full correct English words. Then check your text for correct grammar, proper punctuation, and correct spelling before you send your text to someone. I realize that in today's American culture it's normal for young people to ignore the advice of an older person. ("Old people. What do they know?") For your own good, do not ignore what I've written here. (By the way, what do the letters "dis" mean? Is it Ebonics?) Good Luck, [-Rick-]
4 years ago
+1
Reply
Sorry, you need javascript enabled to post any comments.
Anna Hultin
Said:
Hello Rick! I need to measure Speech Reception Thresholds of recorded sentences in speech-shaped noise, and the SNR need to be exact. Is there any way I can change this code so that I can adjust the SNR between a .wav file and speech-shaped noise? Or do you know where I can find such a code? I have code for generating speech-shaped noise. I should mention I know next to nothing about programming so whatever you answer, I will run it by my friend who is a programmer, but he tells me he's not so good at Matlab; he works with C.
4 years ago
0
Reply
Sorry, you need javascript enabled to post any comments.
umark468
Said:
Hi Rick
1 year ago
0
Reply
Sorry, you need javascript enabled to post any comments.
umark468
Said:
i have received signal in dbm without noise and would like to add noise with a standard deviation in dB.
1 year ago
0
Reply
Sorry, you need javascript enabled to post any comments.
Sorry, you need javascript enabled to post any comments.