Opt-in channel-power squelch for AM audio RX (#3315)

* AM: add opt-in channel-power squelch for AM audio RX

Add an SDR++-style power squelch on the complex channel signal for the
Analog Audio RX app in AM modes (DSB/SSB/CW). The squelch measures the
mean channel power, converts it to dBFS, and mutes the demodulated audio
when the signal is below a user-set threshold. Being carrier-based it
keys on the AM carrier (e.g. airband/ATC) rather than on audio-band
noise, which the existing FM squelch could not do for AM.

A new 'SQ' field (0-99, 0 = off) is added to the AM options view and is
persisted per app via app_settings. Default is 0, so existing AM
behaviour is unchanged unless the user enables it. Threshold maps 1..99
to -80..-20 dBFS.

Touches: message (AMConfigureMessage.squelch_level), baseband_api
(AMConfig::apply), receiver_model (am_squelch_level get/set),
app_settings (persistence), proc_am_audio (DSP), analog_audio_app (UI).

* Refactor audio power calculation to use magnitude squared

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>

---------

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
This commit is contained in:
Mo
2026-09-14 20:54:54 +02:00
committed by GitHub
parent d72b5ed0b1
commit b8ad44c431
11 changed files with 78 additions and 10 deletions
@@ -72,8 +72,15 @@ AMOptionsView::AMOptionsView(
&label_config,
&options_config,
&zoom_config,
&label_squelch,
&field_squelch,
});
field_squelch.set_value(receiver_model.am_squelch_level());
field_squelch.on_change = [](int32_t v) {
receiver_model.set_am_squelch_level(v);
};
zoom_config.on_change = [this, view](size_t, OptionsField::value_t n) {
receiver_model.set_am_configuration(
view->get_previous_AM_mode_option() + zoom_filter_offset(n),
@@ -100,6 +100,17 @@ class AMOptionsView : public View {
{"ZOOM x2", (int)AMSpectrumZoomOption::X2},
{"ZOOM x3", (int)AMSpectrumZoomOption::X3},
{"ZOOM x4", (int)AMSpectrumZoomOption::X4}}};
Text label_squelch{
{UI_POS_X(10), UI_POS_Y(0), UI_POS_WIDTH(2), UI_POS_HEIGHT(1)},
"SQ"};
NumberField field_squelch{
{UI_POS_X(13), UI_POS_Y(0)},
2,
{0, 99},
1,
' ',
};
};
class AMFMAptOptionsView : public View {