Also known as: xlating FIR, frequency xlating FIR filter, translating FIR
A frequency-translating FIR filter (an xlating FIR) does three jobs in one block: it mixes a chosen channel down to baseband, low-pass filters it with an FIR, and decimates to a lower sample rate.1 It is the workhorse of channel selection in an SDR receiver — the compact, efficient realisation of a digital down converter that picks one narrow channel out of a wide IQ capture.
How it works
Naively, three operations run in sequence. The input x[n] is multiplied by a complex
exponential e^{-jω₀n} from a numerically-controlled oscillator
to slide the channel at frequency ω₀ down to 0 Hz; the result passes through a low-pass FIR
that keeps only the wanted channel’s bandwidth; and the filtered stream is decimated by M,
keeping one sample in M since the bandwidth is now small enough that a lower rate is legal.
The algorithm’s value is that these can be fused. Multiplying before the filter is the same
as filtering with frequency-shifted taps: pre-rotate the FIR coefficients by e^{jω₀k},
and a single complex FIR both mixes and filters. Better still, because decimation throws away
M−1 of every M outputs, a decimating FIR never computes them — the mix-filter-decimate
block costs only as much as the output rate demands, not the input rate. That efficiency is
why it is the standard channel-select primitive.
Variants
- Rotate-input vs rotate-taps. Rotating the input needs a running oscillator but keeps the taps real; rotating the taps bakes the frequency in at design time (fixed offset only).
- Polyphase decimating form. Reorganising the taps into a polyphase structure computes only the retained outputs, the efficient realisation used in practice.
- Bank of xlating FIRs → channelizer. Running many at different
ω₀extracts several channels at once; when the offsets are uniform this becomes an FFT-based channelizer that shares work across all channels.
Relevance to SDR
The xlating FIR is how GNU Radio’s freq_xlating_fir_filter and most SDR channelisers tune
within a captured band — you set a centre offset and a decimation, and it hands back one
baseband channel. It is the natural first block of a receiver chain.
GopherTrunk applies exactly this idea, though its two down-converters realise it
differently. The single-channel Downconverter in internal/scanner/ccdecoder/ddc.go mixes
with an NCO and decimates to a fixed channel rate (48 kHz, or 144 kHz for TETRA), while the
wideband DDCBank in internal/dsp/tuner extracts many taps at once — the multi-channel,
channelizer-style form of the same mix-filter-decimate operation. Both are the frequency-
translating FIR at work, selecting a channel out of a wide capture before demodulation.
Sources
-
Digital down converter — Wikipedia, on combining a complex mixer, low-pass filter, and decimator to select a channel. ↩