Assuming the background noise you have removed is effectively constant, or at least periodic throughout your signal, one of the most effective ways to remove noise is using an LMS/NLMS adaptive filter.
Adaptive filters constantly modify their parameters to provide the best estimate possible for a desired signal. For noise cancellation we actually want to model our noise, with the error being our desired signal. Check out: http://en.wikipedia.org/wiki/Echo_suppression_and_cancellation for more on this.
Matlab conveniently has an adaptive LMS filter as part of the DSP toolbox.
Under the documentation for the dsp.LMSFilterObject
is an example piece of code which can be used for noise reduction with a given noise signal. You can find the example here: http://au.mathworks.com/help/dsp/ref/dsp.lmsfilter-class.html
We can further improve this example by placing the filter in a for
loop, and giving the filter its previously calculated coefficients as its starting coefficients, allowing the filter to converge faster and to a better solution.
One of the most important parameters to your filter is theorder
. You want this to be large enough to capture all the features of your signal, but not too large to avoid unnecessary computation. Start with a large order
and plot your filter coefficients once the filter is finished. When the coefficients go to 0, thats the maximum order of the filter you need.
Note: In the following code my noise sample vector is the same dimension as my audio signal. You'll have to implement this.
clearvars;
[sigdata,Fs]=audioread('noisy_signal.wav'); %//import my noisy signal
[n1data,Fs1]=audioread('NoiseRef1.wav'); %//import my noise
stepsize1=0.05; %//stepsize for my adaptive filter. Smaller is more accurate but longer converging times
maxn=5; %//how many times do I want to loop my adaptive filter. For smaller stepsize maxn needs to be larger.
order = 220; %//set this large - maybe 500. Experiment - and see where the coefficients go to 0. That's the order you need.
initialh = 0; %//initialize my filter coefficients to 0
for n=1:maxn
hlms0 = dsp.LMSFilter('Length',order, ...
'Method','Normalized LMS',...
'InitialConditions',initialh,...
'StepSizeSource','Input port');
x = n1data; %// Noise
d = sigdata; % //Noise + Signal
mu = stepsize1; % //step size
[y, out0, wts0] = step(hlms0,x,d,mu);
%//y is the filters best estimate for your noise. You don't usually want this
%//out0 is the residual error. Since the filter is trying to model your noise, the error is your desired signal.
%//wts0 is your filter coefficients
release(hlms0);
initialh=wts0; %//set your initial coefficients to the calculated filter coefficients and re-run
end
desired_signal = out0;
sound(desired_signal,Fs);
If you like you can add in your SNR calculation within the loop and make the loop terminate at a certain SNR threshold. Note: you want to make your loop run at least twice, so that you do not have the initial adaptive period in your signal.
For more information look up "Noise Cancellation LMS". Best of luck!
audio-background
noise is doing what you expect it to do. You can't take noise from one part of a signal and subtract it from another part and expect it to just go away. Noise is non-correlated. – jaket