[fix](trx-frontend-http): measure auto squelch from the meter
CI / frontend (push) Successful in 3m16s
CI / reuse (push) Successful in 2s
CI / lint (push) Successful in 2m18s
CI / test (push) Successful in 8m14s

Auto took the spectrum's noise floor and added 6 dB, but the threshold
is compared against the channel level the meter reports, and the two sit
a long way apart: the gap is set by the FFT size and window, the channel
bandwidth, the decimation, and peak-versus-mean statistics.  Measured on
white noise it runs +22.1 dB at 48k/8k/3k, +18.7 dB at 240k/24k/12k and
-1.2 dB at 1.92M/24k/12k — a 23 dB swing across ordinary configurations.
Only the last of those is anywhere near right, so on a narrow span Auto
set the gate some 20 dB below the noise and it never closed.

It now reads the same number the DSP compares: the 20th percentile of
the meter over the last ten seconds, plus 5 dB.  The percentile keeps a
burst of traffic inside the window from dragging the estimate up, and
5 dB clears the meter's own jitter, which measured 0.9-1.6 dB.  Nothing
in it converts between scales, so no part of the signal chain can put it
out again.  With no history yet — a fresh connection, a rig switch — it
listens for a moment rather than refusing.

The fixture gained a streaming /meter, without which there is nothing to
measure, and the spectrum test pins auto to the meter it serves.

Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
sjg
2026-08-03 23:32:18 +02:00
parent aefd36c4b1
commit 2c1df75d19
4 changed files with 128 additions and 23 deletions
@@ -35,11 +35,16 @@ const BANDPLAN = {
const BAND_WITH_CONTENT = 7074000;
const BAND_WITHOUT_CONTENT = 14074000;
// The meter sits well away from the spectrum's noise floor, so a squelch that
// took its level from the plot would land somewhere else entirely.
const METER_DB = -70;
const fixture = await startWebFixture({
spectrum: true,
bookmarks: BOOKMARKS,
bandplan: BANDPLAN,
bandplanEnabled: true,
meterDb: METER_DB,
});
const { browser, page, runtimeErrors } = await startBrowser(chromium);
@@ -125,10 +130,14 @@ try {
// row, with nothing on screen to relate the number to.
await page.locator("summary", { hasText: "Audio controls" }).click();
await page.locator("#sdr-squelch-toggle").click();
// Auto parks it just above the noise, which is mid-axis and leaves room to
// drag in either direction.
// Auto parks it just above the noise the meter reports — not above the
// spectrum's noise floor, which sits anywhere from 1 dB below to 22 dB above
// the meter depending on span, bandwidth and decimation.
await page.locator("#sdr-squelch-auto").click();
await page.waitForTimeout(300);
await page.waitForTimeout(400);
const auto = await page.evaluate(() => Number(document.getElementById("sdr-squelch-db").value));
assert.ok(Math.abs(auto - (METER_DB + 5)) <= 1,
`auto put the threshold at ${auto} dB with the meter at ${METER_DB} dB`);
const squelchOn = await page.evaluate(() => {
const line = document.getElementById("spectrum-squelch-line");
return {