Introduction

Every time you put on noise-cancelling headphones, a small algorithm is running dozens of thousands of times per second with one goal: subtract the hum before it reaches your ears. It does not have a recording of the noise. It does not know the signal it is protecting. It learns on the fly.

The key idea is correlation. Engine rumble, electrical hum, and ventilation roar share a crucial property: a microphone placed near the noise source picks up almost the same interference that will contaminate the signal microphone a moment later. If you can model how the noise travels from one point to the other — the so-called noise path — you can generate a near-perfect copy and subtract it.

The LMS (Least Mean Squares) algorithm, introduced by Bernard Widrow and Marcian Hoff in 1960, does exactly this. It maintains a short filter whose weights it nudges a tiny step in the direction that reduces the error between the combined signal and zero. Step by step, iteration by iteration, the filter converges — and the hum disappears. This is adaptive filtering: a solved problem with a clean algorithm that works in real time.

Try It

Below, a clean signal (a speech-like sine burst) is buried under a steady hum (50 Hz). A reference microphone provides a clean copy of the hum. The LMS filter learns the noise path and subtracts it in real time. Press Run to start, adjust the step size μ\mu to see how fast (or how unstably) the filter converges, and press Reset to start over.

<!-- {{c_intro}} -->
<div class="controls">
  <label>{{lbl_mu}} <input id="mu" type="range" min="0.001" max="0.05" step="0.001" value="0.01"></label>
  <span id="mu-val">0.010</span>
  <button id="run-btn" type="button">{{btn_run}}</button>
  <button id="reset-btn" type="button" class="ghost">{{btn_reset}}</button>
</div>
<canvas id="cnv" width="560" height="280" aria-label="{{canvas_aria}}"></canvas>
<div class="legend">
  <span class="leg-noisy">{{leg_noisy}}</span>
  <span class="leg-clean">{{leg_clean}}</span>
  <span class="leg-output">{{leg_output}}</span>
</div>
<div class="status" id="status">{{status_idle}}</div>
* { box-sizing: border-box; }
body { font-family: system-ui, sans-serif; margin: 0; color: #222; }
.controls { display: flex; align-items: center; gap: .7rem; flex-wrap: wrap; margin-bottom: .6rem; }
label { font-size: .9rem; display: flex; align-items: center; gap: .4rem; }
input[type=range] { width: 120px; }
#mu-val { font-size: .9rem; font-weight: 700; width: 3.5ch; }
button { font: 600 14px system-ui, sans-serif; padding: .45rem .9rem;
         border: 1px solid #1d3557; background: #1d3557; color: #fff;
         border-radius: 8px; cursor: pointer; }
button.ghost { background: #fff; color: #1d3557; }
canvas { display: block; border: 1px solid #cdd9e3; border-radius: 8px;
         width: 100%; max-width: 560px; background: #f8fafc; }
.legend { display: flex; gap: 1rem; font-size: .82rem; margin-top: .4rem; flex-wrap: wrap; }
.legend span { display: flex; align-items: center; gap: .3rem; }
.leg-noisy::before { content: ""; display: inline-block; width: 20px; height: 3px; background: #e63946; border-radius: 2px; }
.leg-clean::before  { content: ""; display: inline-block; width: 20px; height: 3px; background: #457b9d; border-radius: 2px; }
.leg-output::before { content: ""; display: inline-block; width: 20px; height: 3px; background: #2a9d8f; border-radius: 2px; }
.status { font-size: .95rem; font-weight: 600; margin-top: .5rem; min-height: 1.4em; color: #444; }
.status.running { color: #0a7d33; }
.status.done    { color: #0a7d33; }
// Code not found

Notice: a larger μ\mu converges faster but risks overshooting and becoming unstable. A smaller μ\mu is rock-solid but slow. The sweet spot is the art — and the math — of adaptive filtering.

The Real Complexity

The goal of the filter is to minimize the mean squared error E[e2(n)]E[e^2(n)], where the error is:

e(n)=d(n)wT(n)x(n)e(n) = d(n) - \mathbf{w}^T(n)\,\mathbf{x}(n)

Here d(n)d(n) is the desired signal (contaminated microphone), x(n)\mathbf{x}(n) is the reference noise vector, and w(n)\mathbf{w}(n) is the filter weight vector of length LL.

True gradient descent on this surface would require computing expectations — expensive and off-line. The LMS trick is to use the instantaneous gradient instead, replacing the expectation with a single sample:

w(n+1)=w(n)+2μe(n)x(n)\mathbf{w}(n+1) = \mathbf{w}(n) + 2\mu\, e(n)\, \mathbf{x}(n)

This is stochastic gradient descent applied to filtering, and it is O(L)O(L) per sample — the same cost as running the filter itself.

Convergence is guaranteed when:

0<μ<1λmax0 < \mu < \frac{1}{\lambda_{\max}}

where λmax\lambda_{\max} is the largest eigenvalue of the input autocorrelation matrix R=E[x(n)xT(n)]\mathbf{R} = E[\mathbf{x}(n)\mathbf{x}^T(n)]. In practice, μ<1/(tr(R))\mu < 1/(\text{tr}(\mathbf{R})) is a safe bound that can be estimated from the signal power. The speed of convergence scales as O(12μλmin)O(1 - 2\mu\lambda_{\min}); choosing μ\mu well is the central engineering decision.

Variants like NLMS (normalized LMS) divide the update by x(n)2\|\mathbf{x}(n)\|^2, making it invariant to input power — a major practical improvement. RLS (Recursive Least Squares) converges in as few as LL steps but costs O(L2)O(L^2) per sample. For real-time audio on constrained hardware, LMS remains the dominant choice because of its simplicity and efficiency.

Where It Matters

"Track a correlated interference and subtract it" turns out to be one of the most broadly useful primitives in signal processing:

  • Noise-cancelling headphones: the ear-cup microphone picks up ambient noise; the LMS filter models the path to the speaker and injects the anti-noise before you hear it.
  • Telephone echo cancellation: your voice travels to the far end and leaks back through the loudspeaker; an adaptive filter models the echo path and removes it from the return channel.
  • ECG / EEG denoising: powerline hum at 50 or 60 Hz corrupts biomedical signals; a reference electrode near the power cable feeds an LMS filter that strips the interference while leaving brain or heart signals intact.
  • Active vibration control: accelerometers on an engine feed reference signals into LMS filters that drive actuators to cancel structural vibration in aircraft cabins and car bodies.
  • Acoustic feedback cancellation: hearing aids and PA systems use adaptive filters to prevent the squeal caused when amplified sound re-enters the microphone.

The algorithm also connects deeply to the theory studied elsewhere on this site: the LMS update is stochastic gradient descent — the same engine that trains neural networks. The only difference is scale: LMS updates a handful of weights in microseconds; a neural network updates millions over hours.

Conclusion

Adaptive noise cancellation is one of the few complete victories in applied mathematics. The problem — remove correlated interference without knowing the signal — looked daunting, but Widrow and Hoff's 1960 LMS rule reduced it to a single line: nudge the weights toward smaller error, repeat every microsecond. Convergence is provable, cost is O(L)O(L) per sample, and the algorithm fits on hardware with no floating-point unit.

What makes it especially satisfying is the feedback loop: the filter uses its own error to teach itself. Every sample is both a measurement and a lesson. By the time the hum has played for a second, the filter has already learned to erase it — and keeps re-learning as the noise path drifts with temperature, movement, or load. The hum never had a chance.

Share this article

Pick a channel — or use your device's native share sheet.

Comments

Loading comments...

https://www.kipuhub.com/en/article/adaptive-noise-cancellation/Content licensed under CC BY-NC 4.0.