Mixer plot
The Mixer plot (web /plots/mixer, or /mixer) shows the power
spectrum of the channel baseband two ways — GopherTrunk’s take on
OP25’s Raw Mixer and Tuned Mixer tabs. It answers “where is the
carrier sitting, and is the receiver pulling it onto centre?”
The daemon runs a parallel P25 receiver on the selected channel (the same engine the other Plots use) and FFTs its channelized baseband, so the plot reflects exactly what the production demod is working with — not a re-implementation.
What you see
Two stacked spectra, both Power (dBFS) vs Frequency, spanning the channel baseband (±½ the DDC output rate, ~±24 kHz on P25):
- Raw mixer — the channelized baseband as the receiver first sees it. The carrier sits wherever its residual frequency offset leaves it; the amber marker flags the loop’s carrier-offset estimate.
- Tuned mixer — the same window re-mixed by that carrier-offset estimate, so a locked loop pulls the carrier onto the centre (0 Hz) line.
Comparing the two is the whole point: the shift from the raw peak to the centred tuned peak is the carrier-recovery correction.
| Symptom | Reading |
|---|---|
| Raw peak off-centre, tuned peak centred | Healthy lock — the loop is correcting the offset |
| Raw peak near centre already | Little tuner error on this channel |
| Tuned peak still off-centre | Loop hasn’t acquired — weak signal or wrong Mode |
| No peak, just noise floor | No active signal at this Offset, or wrong channel |
A large, steady raw offset is your tuner’s PPM error (a 420 MHz / 50 ppm RTL-SDR can sit ~20 kHz off); the tuned view should still recentre it once the loop locks.
Controls
Pick the receiver with Mode (C4FM or CQPSK — match the site), and use the Offset / Hold / Centre controls (shared with the other scopes) to point the receiver at a locked control or voice channel. With Hold off, the Offset follows the newest active call on the SDR. See the Constellation panel for the DC-spike explanation of why off-centre channels are mixed down before channelizing.
How it works
- The panel opens
WS /api/v1/diag/mixer?device=...&proto=<…>&offset=<hz>. The daemon runs a symbolscope engine with its FFT taps enabled. - Each frame carries two FFT-shifted dBFS arrays:
raw_bins(the DDC output) andtuned_bins(that window multiplied byexp(-j·2π·f_off·n/Fs), wheref_offis the receiver’s owncarrier_offset_hz). Reconstructing the tuned view from the loop’s estimate needs no extra receiver tap and works identically for C4FM and CQPSK. - The FFT math is the same
spectrum.PowerDBhelper the wideband Spectrum waterfall uses, so the two views are normalized consistently.
The numeric side of the same loop state — the carrier-error trend, AGC and clock meters — lives on the Tuning panel; the Mixer plot is its graphical FFT counterpart.
Implementation
| Path | Role |
|---|---|
internal/dsp/spectrum/spectrum.go |
PowerDB — shared windowed-FFT dBFS helper |
internal/scanner/symbolscope/mixer.go |
Baseband accumulator → raw/tuned FFT frames |
internal/scanner/symbolscope/scope.go |
Feeds the accumulator with the channelized baseband + carrier estimate |
internal/api/mixer.go |
MixerProvider interface + WS /api/v1/diag/mixer handler |
cmd/gophertrunk/mixer_provider.go |
Daemon provider over the iqtap broker |
web/src/panels/Mixer.tsx |
Two stacked FFT line plots (raw + tuned) |