Attempt to make audio and speech discovery more robust.
This commit is contained in:
1 parent
a27f274099
commit
dc945ff392
21 files changed
+1314
-60
No files matched your search
@@ -0,0 +1,111 @@
|
||||
# Audio startup and recovery
|
||||
|
||||
Fenrir handles speech and sound connections independently. The recovery code
|
||||
uses Linux processes, sockets and deadlines; it does not require systemd or a
|
||||
particular service manager. Explicit server, speech driver and sound driver
|
||||
choices remain authoritative. Failures never select a different audio driver.
|
||||
|
||||
## Speech
|
||||
|
||||
Before opening console keyboards or an X11 terminal session, Fenrir retries
|
||||
temporary speech connection failures for up to 20 seconds. Permission and
|
||||
configuration errors fail without waiting through that retry window. Speech
|
||||
Dispatcher's own configuration decides whether to allow daemon autostart.
|
||||
|
||||
When a running Speech Dispatcher connection fails, the speech worker attempts
|
||||
to reconnect for up to 20 seconds. Keyboard forwarding, interruption, mute and
|
||||
quit commands remain responsive. Pending speech is discarded during recovery;
|
||||
it is not replayed when the connection returns. Numeric speech settings and
|
||||
mute state survive recovery. Later output uses the restored connection.
|
||||
|
||||
If recovery fails, Fenrir reports the error and exits. Keyboard grabs are
|
||||
released before waiting for UI tasks, speech or sound shutdown. Native hardware
|
||||
speech drivers retain their existing failure handling; they do not start a
|
||||
Speech Dispatcher daemon or select a different synthesizer.
|
||||
|
||||
## Root at boot and sudo sessions
|
||||
|
||||
A boot service running as root without `SUDO_UID` uses root's Speech Dispatcher
|
||||
environment and configuration. It does not choose a logged-in user's daemon.
|
||||
Root's speech and sound connections receive the same retry/recovery handling.
|
||||
The audio server must be configured to start independently of graphical login
|
||||
and permit the required socket and output-device access.
|
||||
|
||||
For `sudo fenrir`, `SUDO_UID` identifies the invoking user. If the selected local
|
||||
Speech Dispatcher is missing, Fenrir looks up that account and starts only the
|
||||
daemon child with that account's UID, primary group and supplementary groups.
|
||||
The child receives the user's home and an owned runtime directory when present;
|
||||
it does not inherit root's session bus or unrelated environment variables.
|
||||
An owned `XDG_RUNTIME_DIR` is preferred for the default speech socket, followed
|
||||
by the user's owned `/run/user/UID` directory, or the user's cache directory
|
||||
when no runtime directory exists. Explicit speech socket/address settings
|
||||
still take precedence. Fenrir retains its own console/device privileges.
|
||||
|
||||
Logging out may stop user-owned Speech Dispatcher or audio services. Recovery
|
||||
can reconnect when the same services return; it does not keep a login session
|
||||
alive or migrate to another user's audio. No session-owned daemon is killed
|
||||
or restarted to force recovery.
|
||||
|
||||
## Sound effects
|
||||
|
||||
Sound effects retry failed initialization and disconnected playback in a
|
||||
background worker for up to 20 seconds per outage. While unavailable, sound
|
||||
cues are rejected so Fenrir can use their speech equivalents. Cues and progress
|
||||
tones from an outage are discarded. The latest sound volume is applied to a
|
||||
restored connection.
|
||||
|
||||
Each sound-driver open attempt has a three-second deadline. Some native/library
|
||||
calls cannot be interrupted: if an attempt remains stuck, Fenrir stops opening
|
||||
new connections for that player. At most one abandoned opener remains, and it
|
||||
closes its result if it eventually returns. Working speech and keyboard input
|
||||
continue. Exhausted sound recovery disables sound effects for that run.
|
||||
|
||||
## Limits
|
||||
|
||||
Retries cannot repair missing services, incorrect permissions, a wrong server,
|
||||
or a missing playback device. A successful Speech Dispatcher protocol exchange
|
||||
also does not prove audible output: an output module can accept a request and
|
||||
fail inside its own audio backend. PipeWire, PulseAudio and Speech Dispatcher
|
||||
still need appropriate configuration. In particular, PulseAudio's libpulse
|
||||
autospawn behavior does not imply that a PipeWire service will start itself.
|
||||
|
||||
## Verification
|
||||
|
||||
Automated checks use private sockets and fake audio backends, without taking
|
||||
over the active reader:
|
||||
|
||||
```sh
|
||||
go test -race ./internal/audio ./internal/speech ./internal/sound ./internal/app
|
||||
go test ./...
|
||||
```
|
||||
|
||||
For optional isolated Speech Dispatcher startup checks using its dummy module:
|
||||
|
||||
```sh
|
||||
FENRIR_NATIVE_SPEECH_STARTUP=1 go test ./internal/speech -run TestNativeSpeechDispatcherColdStart -count=1
|
||||
```
|
||||
|
||||
Before submission, review the diff and test on an affected machine with a
|
||||
recovery path, such as SSH or another accessible console. Keep only one reader
|
||||
on a console. Source tests do not prove installed behavior or audible output.
|
||||
|
||||
1. Boot without a GUI and before user login, with Fenrir started by the normal
|
||||
boot service. Verify speech, startup sounds, typing, review and quit. Repeat
|
||||
with the audio server delayed briefly: speech should recover if the required
|
||||
service becomes available inside the retry window.
|
||||
2. Check ordinary `sudo fenrir` startup with the user's Speech Dispatcher both
|
||||
already running and initially absent. Check daemon ownership and confirm
|
||||
speech and sound. No root-owned daemon should be created in the user's
|
||||
runtime directory. Test a console session without systemd as well.
|
||||
3. With a recovery connection available, interrupt the configured speech/audio
|
||||
service using that system's normal service controls. While it is unavailable,
|
||||
check ordinary typing, Control, mute and Fenrir's quit shortcut. Restore the
|
||||
service and check fresh review output, volume/rate/pitch and absence of old
|
||||
queued announcements. A permanent speech failure must release the keyboard;
|
||||
a sound-only failure must leave speech working.
|
||||
4. Repeat ordinary X11 terminal startup, review, interruption and exit, plus
|
||||
explicit ALSA sound output where available. Check settings changes during
|
||||
recovery and verify that saved settings are not silently rewritten.
|
||||
5. For user-owned audio, log out and back in with the recovery connection still
|
||||
available. Verify behavior against that machine's session-lifetime policy;
|
||||
this is separate from root-owned pre-login audio.
|
||||
Reference in new issue
Block a user