[fix](trx-frontend-http): add rx audio jitter buffer

Co-authored-by: Codex <codex@openai.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
2026-02-28 11:53:50 +01:00
parent f509500877
commit 2cd33386ef
@@ -2529,6 +2529,7 @@ let txTimeoutInterval = null;
const hasWebCodecs = typeof AudioDecoder !== "undefined" && typeof AudioEncoder !== "undefined"; const hasWebCodecs = typeof AudioDecoder !== "undefined" && typeof AudioEncoder !== "undefined";
const MAX_RX_BUFFER_SECS = 0.25; const MAX_RX_BUFFER_SECS = 0.25;
const TARGET_RX_BUFFER_SECS = 0.04; const TARGET_RX_BUFFER_SECS = 0.04;
const MIN_RX_JITTER_SAMPLES = 512;
if (wfmAudioModeEl) { if (wfmAudioModeEl) {
wfmAudioModeEl.value = loadSetting("wfmAudioMode", "stereo"); wfmAudioModeEl.value = loadSetting("wfmAudioMode", "stereo");
@@ -2666,10 +2667,16 @@ function startRxAudio() {
src.buffer = ab; src.buffer = ab;
src.connect(rxGainNode); src.connect(rxGainNode);
const now = audioCtx.currentTime; const now = audioCtx.currentTime;
const sampleRate = (streamInfo && streamInfo.sample_rate) || frame.sampleRate || 48000;
const minLeadSecs = Math.max(0, MIN_RX_JITTER_SAMPLES / Math.max(1, sampleRate));
const targetLeadSecs = Math.max(TARGET_RX_BUFFER_SECS, minLeadSecs);
if (nextPlayTime && nextPlayTime - now > MAX_RX_BUFFER_SECS) { if (nextPlayTime && nextPlayTime - now > MAX_RX_BUFFER_SECS) {
nextPlayTime = now + TARGET_RX_BUFFER_SECS; nextPlayTime = now + targetLeadSecs;
} }
const schedTime = Math.max(now, (nextPlayTime || now)); if (!nextPlayTime || nextPlayTime < now + minLeadSecs) {
nextPlayTime = now + targetLeadSecs;
}
const schedTime = nextPlayTime || (now + targetLeadSecs);
src.start(schedTime); src.start(schedTime);
nextPlayTime = schedTime + ab.duration; nextPlayTime = schedTime + ab.duration;
frame.close(); frame.close();
@@ -3181,7 +3188,7 @@ function updateRdsPsOverlay(rds) {
if (ps) { if (ps) {
rdsPsOverlay.textContent = ps; rdsPsOverlay.textContent = ps;
positionRdsPsOverlay(); positionRdsPsOverlay();
rdsPsOverlay.style.display = ""; rdsPsOverlay.style.display = "block";
} else { } else {
rdsPsOverlay.style.display = "none"; rdsPsOverlay.style.display = "none";
} }