Active Noise Cancellation Using the Wiener Filter

Some situations arise where the signal of interest is corrupted by interference. A common example is air-to-ground communications. Consider the environment of a helicopter cockpit. Within the cockpit, audible noise is produced by the wind, the helicopter engine, and the pilot’s voice. In this case, the signal of interest is the pilot’s voice but this signal may be overwhelmed by the other noise sources. Simply creating a band-pass filter around the frequencies that lie within the human vocal range is insufficient to recover the signal of interest because the engine and wind interference may occupy the same frequencies. A better approach is to use an active noise cancellation system.

A noise canceling system requires two or more sensors, a primary sensor to measure the corrupted signal of interest and secondary sensors to measure the interference. It is important that the sensors measuring the interference be placed somewhere where it is possible to measure the interference but not the signal of interest. At this point, many assume that canceling the interference is simply a process of subtracting the interference measured at the secondary sensors from the signal containing both the desired signal and interference. In most cases, this approach fails or achieves little improvement. This is because the primary sensor rarely measures the interference with the exact same amplitude, phase, and distortion as the secondary sensors.

Going back to our helicopter example, the primary sensor may be a microphone located directly in front of the pilot’s mouth. The secondary sensors must be placed somewhere within the cockpit where they pick up the interference (the wind and engine noise) without picking up the pilot’s voice. Being spatially separated means that the sensors measure the noise from the wind and engine with different propagation delays, amplitudes, and may experience different distortions. However, because the unwanted noise measured at the primary and secondary sensors is generated by the same processes, the noise information between the two sensors is highly correlated. Thus it is possible to design a Wiener filter that filters the noise measured at the secondary sensors and produces an estimate of the noise measured at the primary sensor. This noise estimate is subtracted from the corrupted signal to produce an estimate of the signal of interest. Figure 1 is a block diagram that illustrates this concept.

Figure 1: Block diagram of noise-canceling system.

Post Notations

Before going on to the derivation, let’s define some notation so that we’re all on the same page. Let E\{\cdot\}, \hat{d} and r_d(k) represent the expectation operator, the estimate of d, and the autocorrelation function of d respectively. The expectation operator returns the expected value or mean of a random variable. The estimate of  \hat{v}_1 is found by filtering v_2 with our Wiener filter as follows

\hat{v}_1(n) = \sum_{\ell=0}^{p-1}w(\ell)v_2 (n-\ell)

where p is the number of filter coefficients.

The autocorrelation function for a wide sense stationary (WSS) signal is defined as

r_v_2(k) = E\{v_2(n)v_2^*(n-k)\}

The cross-correlation function for jointly WSS signals is defined as

r_{v_1 v_2} = E\{v_1(n)v_2^*(n-k)\}

Let the error be defined as the difference between the desired signal and the estimate of the desired signal

e(n) = x(n) - \hat{v}_1(n)

and the MSE be defined as 

\zeta = E\{e(n)^2\}.

Finally, let \cdot^* represent the complex conjugate operator. 

Deriving the Noise-Canceling Wiener Filter

The object of the Wiener filter is to minimize the mean squared error of the signal (check out this related Wiener filter post). For this derivation, it is assumed that the signal of interest and the interference are jointly wide sense stationary. A signal is wide sense stationary if the signal has constant mean, the autocorrelation depends only on the lag, and the variance is finite. As defined in the above diagram the error is the corrupted signal minus the estimate of the interference. With this definition, we derive the noise-cancelling Wiener filter.

    \begin{align*}\zeta &= E\{e(n)e(n)^*\}\\\frac{\partial \zeta}{\partial w(k)^*} &= E\{e(n)\frac{\partial e(n)^*}{ \partial w(k)^*}\}=0\\E\{e(n)\frac{\partial (x(n)^* -\hat{v}_1^*(n))}{\partial w(k)^*}\}&=0\\E\{e(n)\frac{\partial (x(n)^* - \sum_{\ell=0}^{p-1}w^*(\ell)v_2^* (n-\ell))} {\partial w(k)^*}\}&=0\\E\{e(n)v_2^* (n-k)\}&=0.\\\end{align*}

Now that the derivative is set to zero, we can solve for the filter coefficients that satisfy the equation.

    \begin{align*}E\{[x(n)-\hat{v}_1(n)]v_2^*(n-k)\} &= 0 \nonumber \\E\{[x(n)-\sum_{\ell=0}^{p-1}w(\ell)v_2(n-\ell)]v_2^*(n-k )\}&=0 \nonumber\\E\{x(n)v_2^*(n-k) - \sum_{\ell=0}^{p-1}w(\ell)v_2(n-\ell)v_2^*(n-k)\} &= 0 \nonumber \\E\{(d(n)+v_1(n))v_2^*(n-k)\} - E\{\sum_{\ell=0}^{p-1}w(\ell)v_2(n-\ell)v_2^*(n-k)\} &=0 \nonumber\\\sum_{\ell=0}^{p-1}w(\ell)E\{v_2(n-\ell)v_2^*(n-k)\} = E\{d(n)v_2^*(n-k)\} + E\{v_1(n)v_2^*(n-k)\} \nonumber\\ \end{align*}

However, if we let the desired signal, d(n) and the noise interference v_2(n) be uncorrelated (which in most cases is true) then E\{d(n)v_2^*(n-k)*\} = 0 and

    \begin{align*} \sum_{\ell=0}^{p-1}w(\ell)E\{v_2(n-\ell)v_2^*(n-k)\} &= E\{v_1(n)v_2^*(n-k)\}\\ \bold{R}_v_2 \bold{w} &= \bold{r}_{v_1 v_2} \end{align*}

Unfortunately, we don’t have a sensor that measures v_1 exclusively, we have a sensor that measures x which contains both the unwanted noise and the signal of interest. Basic algebra tells us that

    \begin{align*} x(n) &= v_1(n) +d(n) \\ v_1(n) &= x(n) -d(n) \end{align*}

Let’s see what happens when we substitute v_1(n) for x(n)-d(n) for the cross correlation term.

    \begin{align*} r_{v_1 v_2}(n) &=E\{v_1(n)v_2^*(n-k)\}\\ &= E\{[x(n)-d(n)]v_2^*(n-k)\} \\ &= E\{ x(n)v_2^*(n-k)-d(n)v_2^*(n-k)\} \\ &= E\{ x(n)v_2^*(n-k)\} -E\{d(n)v_2^*(n-k)\} \end{align*}

If the signal of interest is uncorrelated with v_2 (this should be true in most practical cases) then the term on the right goes to zero and

    \begin{align*} \bold{r}_{v_1 v_2} = \bold{r}_{xv_2} \end{align*}

This is much easier to work with because we have a sensor that records the signal x

Noise Canceling Example

To better illustrate noise canceling using the Wiener filter, I have added three audio files. The first audio file is the observed signal x. In this example, the unwanted noise interference, v_1, is a simple tone that should be clearly audible. The second audio file is after the unwanted signal, v_1, has been estimated from v_2 and removed, leaving the desired audio recording. The final file shows what would happen if the signal recorded from the secondary sensor, v_2, was simply subtracted from x

Observed signal, x, from the primary sensor.
Signal, e, after noise canceling is applied.
Subtracting v2 without first filtering.

The pure tone was generated in simulation, thus we have access to it even though real applications would not. Plotting v_1, v_2, and \hat{v}_1 can be helpful in understanding how the system works. Figure 2 plots these three signals. Notice that v_1 and v_2 are out of phase by nearly 180 degrees. It is now obvious why subtracting v_2 from x had no effect, in fact subtracting v_2 from x caused the tone to increase in power! Filtering v_2 with the Wiener filter produces \hat{v}_1, which now correctly matches v_1 in both phase and amplitude, allowing us to subtract it from x to get our desired signal.

Figure 2: The blue signal is v1, the unwanted noise interference. The red signal is the unwanted signal observed with the secondary sensor, v2. The black signal is the estimate of v1 by filtering v2 with the Wiener filter.

JOIN OUR NEWSLETTER
I agree to receive email updates when new content is posted and receive promotional emails when new courses are available
Enjoying the article? Receive free updates when new content is published and courses are available.
We hate spam. Your email address will not be sold or shared with anyone else.
Christopher Hogstrom
christopher.hogstrom@grittyengineer.com

4 thoughts on “Active Noise Cancellation Using the Wiener Filter”

  1. Hello, Nice Implementation of Active Noise cancellation using Wiener filter.
    I am trying to cancel Active noise from Drone so that I can record sounds from the ground. Do you have implementation of above in python or matlab? It would be really great Help for me.

    1. I’m glad you enjoyed the post! Just remember that in order for noise cancelation to work, you need to have one microphone that is positioned in such a way that it only picks up noise from the Drone and wind.
      I’m currently creating an online workshop that will go over the Wiener filter, active-noise cancellation with one auxiliary sensor and multiple auxiliary sensors, and ending with beamforming. Each section would include examples worked in Matlab or Octave (Octave is a free open source version of Matlab). The workshop is not yet available so if you’d really like to have the code to the example message me using the contacts page and we can discuss the details through email. Make sure in the subject line you write, Active-Noise Cancellation code.

  2. Hi Christopher,
    Your introduction is very clear and its so helpful. Could you please share me the mathlab code for noise cancellation using wiener filter??

    1. I’m glad you found the tutorial helpful. I am considering putting the code up for sale if there is enough interest. Currently, I’m not freely distributing it.

Leave a Reply

Your email address will not be published. Required fields are marked *