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
