From 4fe5811fd220bf37731fc6f5a97ce250f07fadfe Mon Sep 17 00:00:00 2001 From: rouggy Date: Fri, 31 Jul 2026 18:55:48 +0200 Subject: [PATCH] fix: a playback that never starts no longer fails silently MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit From an operator's log, playing a recording on the air repeatedly: 18:52:40.148 play → 18:52:48.420 PTT released 8.2 s, the whole take 18:52:57.759 play → 18:52:57.879 PTT released 0.12 s, nothing came out Those 120 ms are the PTT release tail alone: the render device refused to start and playPCM returned an error that was thrown away. The call reported success every time, which is what "it plays once and then never again" looks like from the outside — and why the search went to the recorder, which was innocent. The error is now logged with the device name. --- changelog.json | 6 ++++-- internal/audio/manager.go | 8 +++++++- 2 files changed, 11 insertions(+), 3 deletions(-) diff --git a/changelog.json b/changelog.json index d5f0cd1..efd212e 100644 --- a/changelog.json +++ b/changelog.json @@ -3,10 +3,12 @@ "version": "0.22.5", "date": "", "en": [ - "Cluster filters gain NEW POTA and NEW COUNTY, alongside the existing status chips." + "Cluster filters gain NEW POTA and NEW COUNTY, alongside the existing status chips.", + "A playback that fails to start now says so in the log instead of ending silently after a tenth of a second." ], "fr": [ - "Les filtres du cluster gagnent NEW POTA et NEW COUNTY, à côté des pastilles de statut existantes." + "Les filtres du cluster gagnent NEW POTA et NEW COUNTY, à côté des pastilles de statut existantes.", + "Une lecture qui ne démarre pas le signale désormais dans le journal, au lieu de s'arrêter en silence au bout d'un dixième de seconde." ] }, { diff --git a/internal/audio/manager.go b/internal/audio/manager.go index 48b918c..c0febe1 100644 --- a/internal/audio/manager.go +++ b/internal/audio/manager.go @@ -131,7 +131,13 @@ func (m *Manager) Play(deviceID, path string, gainPct int) error { m.playStop = stop m.mu.Unlock() go func() { - _ = playPCM(deviceID, pcm, rate, ch, bits, stop) + // The error was discarded. A device that refuses to start returns here + // instantly, the PTT is released 120 ms later, and NOTHING says why — + // which is exactly what a station heard as "it plays once, then never + // again": the call succeeded, the sound did not. + if err := playPCM(deviceID, pcm, rate, ch, bits, stop); err != nil { + LogSink("audio: playback on %q failed: %v", DeviceName(deviceID), err) + } m.mu.Lock() if m.playStop == stop { m.playStop = nil