audioio: report a failed sound card instead of dying quietly - #173
Open
rafael2k wants to merge 1 commit into
Open
audioio: report a failed sound card instead of dying quietly#173rafael2k wants to merge 1 commit into
rafael2k wants to merge 1 commit into
Conversation
22050 and 44100 are refused, and should be: neither is an integer multiple of the 8 kHz modem rate, and approximating with the nearest integer ratio transmits off-frequency at the correct level and spectrally pure -- a 1 kHz tone measured 166.8 Hz on a device pinned to 8 kHz. Nothing about that looks wrong until you count cycles. The rejection is right and stays. What was wrong is what happens next. The check runs inside the capture and playback threads, after pthread_create has already returned 0, so audioio_init_internal reports success and the engine starts normally. The thread logs an error and exits. Mercury then runs with TCP ports open, the UI attached and the status payload describing a perfectly healthy station -- while hearing nothing and transmitting nothing. The one place an operator would look says everything is fine. Not fixed by exiting. A wrong sound card is exactly the case where the operator needs mercury alive: audioio_restart() and the UI device list exist so they can pick another one, and a process that quits leaves them nothing to pick with. So the threads now record health (audio_health_t: STOPPED/RUNNING/FAILED plus a reason) and the status carries audio_ok and audio_error. A failed card becomes visible in the UI, mercury stays up, and the operator can choose another device. Wired at the two failure classes that actually happen: an unsupported rate, and a device that will not open (wrong card, or busy). The rate message now names the fix rather than just the problem -- "try plughw:X,Y instead of hw:X,Y so ALSA converts". That is the operator's actual remedy, it is what mercury.ini.example already recommends, and it is why almost nobody hits this: ALSA's plug layer converts 44100/22050 transparently and mercury only ever sees 48000. Also: test_ui_status had a build rule but was NOT in TEST_BINS, so the test whose entire purpose is to catch drift between the status struct and the JSON on the wire has never run in CI. It caught this change only because I ran it by hand. Added to the suite -- it was the only orphan; the other 18 rules are all listed. Not implemented: rational resampling for the 44.1 kHz family. It is a real option (441:80 polyphase, ~30 MACs per output sample) but plughw already covers it, and widening what the audio path accepts deserves its own change rather than riding along with a bug fix. Gate: unit suite green (19 binaries), integration go test -count=1 green (257 s). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
When a capture or playback device fails to open, mercury gave no usable signal
about it — the operator sees a station that is up but deaf or mute, with
nothing in the UI to say which.
Adds an
audio_health_tstate per direction, set at the point of failure, andplain-typed accessors (
audioio_capture_health(),audioio_playback_health(),audioio_health_reason(),audioio_health_ok(char*, size_t)) so callers needno audioio header. Surfaced through
ui_status.Deliberately does not exit: picking the wrong sound card should let the
operator pick another one, not kill the process — per @rafael2k.
History, for the reviewer
This is
a9effec, written during the #162 audio work. I pushed it into #163by mistake, where it had nothing to do with FFT acquisition; it was stripped
back out so #163 stayed single-purpose, which left this stranded in reflog.
Recovered and landed on its own here.
It cherry-picks onto trunk cleanly now — the
tests/Makefileconflict it hitearlier was against a trunk that predated #163's changes to the same file.
Testing
Full build clean, unit suite green (
All Tests Passed) from a clean tests treeon current trunk
cb4ab1b.Relevant to #162: the reporter was selecting sound cards while diagnosing, which
is exactly the case where a silent failure costs the most time.