// SPDX-FileCopyrightText: 2026 Stan Grams // // SPDX-License-Identifier: GPL-2.0-or-later import assert from "node:assert/strict"; import test from "node:test"; import vm from "node:vm"; import { build } from "esbuild"; async function loadEstimator() { const result = await build({ entryPoints: [new URL("../src/features/radio/auto-bandwidth.ts", import.meta.url).pathname], bundle: true, format: "cjs", platform: "browser", target: "es2022", write: false, }); const module = { exports: {} }; vm.runInNewContext(result.outputFiles[0].text, { module, exports: module.exports, Array, ArrayBuffer, Number, Math, }); return module.exports.estimateOccupiedBandwidth; } function wfmFrame(signalHalfWidthHz, signalDb = -70) { const sampleRate = 400_000; const bins = Array.from({ length: 1025 }, (_, index) => { const offsetHz = (index / 1024 - 0.5) * sampleRate; return Math.abs(offsetHz) <= signalHalfWidthHz ? signalDb : -100; }); return { bins, center_hz: 100_000_000, sample_rate: sampleRate }; } test("weak WFM falls back to the 60 kHz intelligibility floor", async () => { const estimate = await loadEstimator(); const weak = wfmFrame(90_000, -97); assert.equal(estimate(weak, 100_000_000, "WFM", [180_000, 60_000, 300_000, 5_000]), 60_000); }); test("WFM ACI and CCI cap an otherwise wide occupied estimate", async () => { const estimate = await loadEstimator(); const frame = wfmFrame(95_000); const limits = [180_000, 60_000, 300_000, 5_000]; const clear = estimate(frame, 100_000_000, "WFM", limits); const adjacent = estimate(frame, 100_000_000, "WFM", limits, { aci: 100 }); const cochannel = estimate(frame, 100_000_000, "WFM", limits, { cci: 100 }); assert.ok(clear > adjacent); assert.equal(adjacent, 60_000); assert.ok(cochannel >= 135_000 && cochannel < clear); });