Skip to content

Beat Cancel (BC) — Radio-side heterodyne/carrier interference cancellation #529

Description

@OH6PP

Request preparation

  • I used an AI assistant to help structure this request
  • I checked for existing issues covering the same feature

What would you like?

What

Add a Beat Cancel (BC) toggle to the RxApplet DSP row, exposing the
FLEX-6000/8000 series radio-side beat (heterodyne) cancellation DSP.
Beat Cancel detects and suppresses periodic in-band interference tones —
most commonly unwanted carriers and CW heterodynes — without affecting the
desired signal around them.

Two modes should be available where the radio firmware supports them:

Mode Purpose
BC1 Tracks and cancels relatively weak, stable beats
BC2 Cancels stronger or intermittent interference bursts

Both modes should be independently toggle-able, or exposed as a 3-state
control (OFF / BC1 / BC2), mirroring how the Kenwood TS-890 exposes them.


Why

Operators regularly encounter heterodyne interference — a second station's
carrier beating against the desired signal producing an audible tone, or
CW QRM producing a second pitch on top of the signal being copied.

The FLEX radio's DSP engine already has the processing power to detect and
cancel these narrowband beats in real time. Today in AetherSDR there is no
way to engage this feature; the existing DSP row in RxApplet already has
NB / NR / ANF toggles, and BC is the natural fourth member of that group.

Without BC, the only mitigation available to the user is to manually add a
TNF (Tracking Notch Filter) — which requires identifying the exact beat
frequency by ear and dragging it into place, and re-doing this every time
conditions change. BC automates this entirely.

⚠️ Digital-mode note: Like NB, NR, and ANF, Beat Cancel applies
non-linear DSP to the audio chain. It should be disabled when using
digital modes (FT8, JS8, PSK31, etc.) that rely on software demodulators,
to avoid distorting the constellation. A tooltip warning is appropriate.


How Other Clients Do It

Kenwood TS-890S

The TS-890 implements BC as a front-panel DSP option accessible via the
context-sensitive screen buttons. Key behaviours:

  • BC1 targets weak, relatively stable carrier beats; processing is
    continuous and adaptive.
  • BC2 targets stronger or intermittent beats; uses a higher-agression
    cancellation algorithm.
  • The two modes can be toggled independently (both ON simultaneously is
    valid — they target different interference profiles).
  • The BC buttons appear in the same DSP panel row as NR (Noise Reduction)
    and NB (Noise Blanker), which is exactly how the existing RxApplet
    DSP row is already structured in AetherSDR.
  • The display shows which modes are active with a highlighted button state.

FlexRadio SmartSDR (Windows)

SmartSDR exposes the equivalent via the slice DSP panel. The exact control
label in SmartSDR's UI is not confirmed by this author — needs verification
against the Windows client.


Suggested Behavior

RxApplet DSP Row

Extend the existing NB / NR / ANF toggle row with a BC button (or
two separate BC1 / BC2 buttons):

[ NB ] [ NR ] [ ANF ] [ BC1 ] [ BC2 ]

Alternatively a single BC button that cycles OFF → BC1 → BC2 → BOTH → OFF
with the current state shown on the button label — whichever approach maps more
naturally to the underlying protocol command.

Interaction:

  1. User clicks BC1 — button highlights (same active style as existing NB/NR
    buttons), AetherSDR sends the enable command to the radio.
  2. Radio echoes state change via S status message → SliceModel updates →
    RxApplet reflects confirmed state (standard GUI↔Radio sync pattern).
  3. Second click disables BC1, button returns to inactive style.
  4. BC2 behaves identically and independently.

Tooltip on hover:

"Beat Cancel — suppresses heterodyne/carrier interference tones.
BC1: weak/stable beats. BC2: strong/intermittent beats.
Disable for digital modes (FT8, JS8, PSK31, etc.)."

Persistence:

State is held by the radio per-slice and restored automatically on reconnect
(same as NB/NR/ANF — no client-side AppSettings persistence needed unless
the radio doesn't persist it across power cycles, which should be tested).

SliceModel additions:

// SliceModel.h
bool beatCancelMode1() const;
bool beatCancelMode2() const;
void setBeatCancelMode1(bool enable);  // emits commandReady()
void setBeatCancelMode2(bool enable);  // emits commandReady()
// signals
void beatCancelMode1Changed(bool);
void beatCancelMode2Changed(bool);

Protocol Hints

The FlexLib (C#) Slice class is the reference. Likely key=value pairs
in the SmartSDR protocol (needs verification by inspecting TCP traffic or
the FlexLib source):

# Enable BC1 on slice 0
C42|slice set 0 beat_cancel_1=1

# Enable BC2 on slice 0
C43|slice set 0 beat_cancel_2=1

# Expected status echo
S<handle>|slice 0 beat_cancel_1=1
S<handle>|slice 0 beat_cancel_2=1

Exact key names are unconfirmed — the actual token names used by firmware
v1.4.0.0 need to be verified by:

  1. Enabling Beat Cancel in SmartSDR (Windows) while capturing TCP traffic with
    Wireshark on port 4992, or
  2. Grepping the FlexLib source for beat_cancel or bc in Slice.cs.

If the firmware does not support BC natively via the slice command API
(possible on older firmware like v1.4.0.0), a client-side TNF-based
approximation could be offered as a fallback — but the radio-native path
should be attempted first.

Tag: protocol — needs Wireshark capture or FlexLib source confirmation
before implementation.

Metadata

Metadata

Assignees

No one assigned

    Labels

    GUIUser interfaceNew FeatureNew feature requestaudioAudio engine and streamingawaiting-responseWaiting for reporter to provide additional informationenhancementImprovement to existing featurepriority: lowLow priorityprotocolSmartSDR protocol

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions