Field Guide · algorithm

Also known as: resampler, resampling, sample-rate converter

A resampler converts a sample stream from one sample rate to another.1 SDRs rarely produce exactly the rate a decoder wants — a P25 channel needs a clean multiple of its 4800-baud symbol rate, say, while the radio delivers 2.4 or 10 MS/s — so a resampler bridges the two. It can do so by a whole-number ratio, a rational ratio L/M, or an entirely arbitrary (irrational, even time-varying) ratio.

input rate (6 samples) resample output rate (4 samples, same waveform)
A resampler changes the sample rate — here reducing it — by reconstructing the underlying continuous waveform and re-sampling it at the new grid, never simply dropping samples.

How it works

The correct mental model is reconstruct then re-sample: recover the underlying band-limited waveform implied by the input samples, then read off its value on the new sample grid. Done naively — dropping or duplicating samples — this folds energy across the band and creates aliasing, so a resampler always contains an anti-alias / anti-image filter that limits the signal to the lower of the two Nyquist bands.

For a rational rate change L/M, the textbook chain is:

  • Upsample by L — insert L−1 zeros between input samples, raising the rate.
  • Low-pass filter — remove the spectral images the zero-stuffing created (and pre-filter for the coming decimation), passing only the original band.
  • Downsample by M — keep every M-th filtered sample.

Because the low-pass filter runs at the high intermediate rate L·fs, the naive form is wasteful: it multiplies many zeros and computes many samples that decimation discards. A polyphase filter bank fixes both — it skips the zero multiplies and computes only the outputs that survive — turning the interpolate-filter-decimate chain into an efficient single stage. Large integer factors are peeled off first with cheap half-band stages, leaving the polyphase resampler to handle the small remaining ratio.

Variants: rational, fractional, and arbitrary

  • Integer decimation / interpolation. The simple L=1 or M=1 cases; one polyphase FIR and a rate change.
  • Rational L/M. Any ratio expressible as a fraction (e.g. 48/44.1 for audio, or matching a 4800-baud symbol grid) — a single polyphase resampler with L sub-filter phases.
  • Arbitrary / fractional resampling. When the ratio is irrational or drifts over time — as in symbol-timing recovery, where the wanted sample instant sits between input samples and moves — you need a continuously variable delay. The Farrow structure does this: it evaluates a low-order polynomial interpolation of the surrounding samples at a fractional offset µ, so the same hardware can produce a sample at any inter-sample position by adjusting µ.2 This is exactly how a timing loop pulls samples onto the symbol clock without changing the input rate.

In practice

Resampling appears wherever two clocks meet: matching an SDR’s native rate to a decoder’s required rate, converting between audio rates, and — via the Farrow / fractional form — inside the interpolators of clock- and symbol-timing recovery. The engineering choice is between a tidy rational polyphase resampler when the ratio is fixed and known, and an arbitrary Farrow resampler when the ratio is fractional or must be steered in real time.

Relevance to SDR

Rate conversion is unavoidable in SDR: the radio’s native rate almost never equals the per-protocol channel rate a decoder expects. GopherTrunk’s down-conversion normalises each capture to the per-protocol channel rate (for example 48 kHz for the 4800-baud C4FM family, 144 kHz for TETRA), and its timing recovery interpolates fractionally to land samples on the symbol instants — both concrete instances of resampling in the decode chain.

Sources

  1. Sample-rate conversion — Wikipedia, on rational L/M resampling, the interpolate-filter-decimate chain, and polyphase efficiency. 

  2. Farrow structure — Wikipedia, on polynomial-interpolation fractional-delay filters for arbitrary/continuously-variable resampling. 

See also