morse-wip/test/addnoise.m

77 wiersze
2.7 KiB
Matlab

function [ noisy, noise ] = addnoise( signal, noise, snr )
% ADDNOISE Add noise to signal at a prescribed SNR level.
%
% [NOISY,NOISE]=ADDNOISE(SIGNAL,NOISE,SNR) adds NOISE to SIGNAL
% at a prescribed SNR level. Returns the mixture signal as well
% as scaled noise such that NOISY=SIGNAL+NOISE.
%
% Inputs
% SIGNAL is a target signal as vector.
%
% NOISE is a masker signal as vector, such that
% length(NOISE)>=length(SIGNAL). Note that
% in the case that length(NOISE)>length(SIGNAL),
% a vector of length length(SIGNAL) is selected
% from NOISE starting at a random sample number.
%
% SNR is the desired signal-to-noise ratio level (dB).
%
% Outputs
% NOISY is a mixture signal of SIGNAL and NOISE at given SNR.
%
% NOISE is a scaled masker signal, such that the mixture
% NOISY=SIGNAL+NOISE has the desired SNR.
%
% Example
% % inline function for SNR calculation
% SNR = @(signal,noisy)( 20*log10(norm(signal)/norm(signal-noisy)) );
%
% fs = 16000; % sampling frequency (Hz)
% freq = 1000; % sinusoid frequency (Hz)
% time = [ 0:1/fs:2 ]; % time vector (s)
% signal = sin( 2*pi*freq*time ); % signal vector (s)
% noise = randn( size(signal) ); % noise vector (s)
% snr = -5; % desired SNR level (dB)
%
% % generate mixture signal: noisy = signal + noise
% [ noisy, noise ] = addnoise( signal, noise, snr );
%
% % check the resulting signal-to-noise ratio
% fprintf( 'SNR: %0.2f dB\n', SNR(signal,noisy) );
%
% See also TEST_ADDNOISE_SINUSOID, TEST_ADDNOISE_SPEECH.
% Author: Kamil Wojcicki, UTD, July 2011
% inline function for SNR calculation
SNR = @(signal,noisy)( 20*log10(norm(signal)/norm(signal-noisy)) );
% needed for older realases of MATLAB
randi = @(n)( round(1+(n-1)*rand) );
% ensure masker is at least as long as the target
S = length( signal );
N = length( noise );
if( S>N ), error( 'Error: length(signal)>length(noise)' ); end;
% generate a random start location in the masker signal
R = randi(1+N-S);
% extract random section of the masker signal
noise = noise(R:R+S-1);
% scale the masker w.r.t. to target at a desired SNR level
noise = noise / norm(noise) * norm(signal) / 10.0^(0.05*snr);
% generate the mixture signal
noisy = signal + noise;
% plot(signal,noisy,noise);
% sanity check
%assert( abs(SNR(signal,noisy)-snr) < 1E10*eps(snr) );
%%% EOF