Noise Cancellation using Auto and Cross-Correlation (xcorr & xcorr2)

Started by May 5, 2008

I'm trying to create an FIR filter to cancel some noise in an audio sample by looking back at the previous samples (some m samples back) to create the filter weight for the current sample and then incrementing (similar to a queue where a new sample enters).

I am using the auto and cross-correlation between the noise and the noisy signal to find the filter coefficients and not having any luck. I am using the following formulas:
-Cross-correlation between noise and noisy signal (p) is noisy(n-m:n)*noise(n-m:n)
-Autocorrelation for the noise (r) is noise(n-m:n)*noise(n-m:m)'
-Filter Weight (W) is r^-1 * p

I am then using the Filter Weight (W) to find out how much noise to subtract from the noisy signal with W' * noise(some range).

My MATLAB code is as follows:
% Load Wave File
[original, Fs, nbits] = wavread('Original.wav');
original = original(1:10); % Trying a small chunk first

% Generate noise and add it to the signal
noise = (0.04).*randn(1, length(original))';
noisy = original + noise;
wavwrite(noisy, Fs, nbits, 'Noisy_Output.wav');

m = 3; % How far in the past do we look to determine weight

% We loop through the entire audio sample, calculating new weights
% for the current sample by looking at the previous 3 samples, filtering
% and then repeating the process
for n = 1:8,
% Calculate Correlations p and r
temp = xcorr(noise(n:n+m-1), noisy(n:n+m-1), 'unbiased');
p = temp(m:m+m-1); % Take second half of matrix

r = xcorr2(noise(n:n+m-1), noise(n:n+m-1)');
r = fliplr(r);
R = pinv(r);

% Calculate Filter Weight
W = R * p;

% Find what to subtract and take it out of the noisy signal
to_subtract(m+n-1) = W'*noise(n:n+m-1);
filtered(n+m-1) = noisy(n+m-1) - to_subtract(n+m-1)';

Unfortunately the results are not correct (even for a small sample) and I think it might be due to my filter coefficient calculation (i.e. xcorr and xcorr2 not working). I already tried without the flips and using them unmodified, but reading the documentation, I believe this is correct. At the same time, it's not working and thus any help would be appreciated.

Hi Daniel,

since you have the noise available (separated from the noisy signal), why don't you denoise the noisy signal via a simple LMS adaptive filter? Do you know how to do that?