Field Guide · algorithm

Also known as: fractional delay line, interpolating delay line

A fractional-delay filter delays a sampled signal by a non-integer number of samples — 2.60 samples, say — by interpolating new sample values between the ones that were captured.1 An integer delay is free (read the buffer later), but the moment two streams must be aligned to a fraction of a sample period, a filter has to reconstruct what the signal was doing between sampling instants. The sampling theorem guarantees this is possible for a band-limited signal: the ideal fractional delay is a shifted sinc, and practical filters are finite approximations of it.

branch 0 (early) branch 1 (late by 0.3 samples) delay by 0.3 aligned
Delaying the early stream by the measured fractional offset re-times its samples onto the other stream's grid, so the two can be summed sample-for-sample.

How it works

The ideal delay-by-D filter has impulse response sinc(n − D) — for integer D that collapses to a single unit tap, for fractional D it spreads over all n and must be truncated. Practical structures trade accuracy for cost:

  • Windowed-sinc FIR. Take a dozen or so taps of the shifted sinc under a window; accurate across most of the band, with the usual FIR latency.
  • Lagrange / polynomial interpolation. Fit a low-order polynomial through neighbouring samples and read it off at the fractional position. Linear interpolation is the 1st-order case — cheap, but it low-pass filters the signal noticeably.
  • Farrow structure. Factors a polynomial interpolator so the fractional delay is a runtime parameter rather than baked into the taps — the standard choice inside timing-recovery loops, where the delay changes every symbol.

A fractional-delay filter is a resampler evaluated at a constant offset: same mathematics, different intent. Where a resampler changes the rate, a fractional delay keeps the rate and moves the sampling phase.

Measuring the delay to apply

Alignment jobs pair the filter with an estimator. Cross-correlating the two streams over a range of integer lags finds the coarse offset; fitting a parabola through the correlation peak and its two neighbours refines it to a fraction of a sample. The frequency-domain signature of a pure delay is distinctive and worth recognising: per-frequency coherence stays near 1 while broadband coherence is diluted (each frequency sees a different phase slope, so the wideband average partially cancels), and group delay is flat.

Relevance to SDR

Fractional delays are everywhere timing matters: inside every symbol-timing loop, in beamforming (a steering delay per element), and in multi-channel alignment. GopherTrunk’s sharpest lesson came from diversity combining: on an X310 with two daughterboards, branch 0 lagged branch 1 by a constant 2.60 samples (13 µs at 200 kS/s), and since a single complex gain cannot represent a delay, MRC on the skewed branches decoded 22% fewer CRC-clean frames than the best branch alone — the combiner was hurting. The SoapyRemote driver now measures the skew per stream (±16-lag correlation scan with parabolic refinement, DC-removed, latched behind a coherence gate) and delays the early branch through an interpolating delay line (internal/sdr/soapyremote/align.go); the identical combine after alignment matched the best branch exactly. The diagnostic — “other lags ref by N±f samples” — is printed by the diversity replay harness, and the wider story lives in MRC diversity gotchas.

Sources

  1. Whittaker–Shannon interpolation formula — Wikipedia, on ideal sinc reconstruction between samples, the basis of fractional-delay filtering. 

See also