Expand description
Native audio playback.
Break sounds used to play through the webview’s HTMLAudioElement. That
works on macOS (WKWebView) and Windows (WebView2), which decode MP3
natively, but not on Linux: WebKitGTK delegates media to GStreamer and
cannot decode MP3 without system codecs that aren’t installed by default,
so every chime and ambient track fell silent (#114).
Playback now runs in-process through rodio, which decodes with
Symphonia regardless of the OS or webview, and plays via CoreAudio /
WASAPI / ALSA. The frontend just tells us what to play and when.
rodio’s device handle (MixerDeviceSink) and Players are !Send, so
they live on one dedicated thread fed by a command channel. Everything
the unit tests can reach — the sound catalogue lookup and the volume
clamp — is pulled out as plain functions; the thread that touches the
audio device is the thin, untestable shim.
Structs§
- Audio
Player - Handle to the audio thread. Cloneable-by-reference through Tauri state; every method is fire-and-forget — a dropped thread (no output device) silently swallows commands rather than erroring up the call stack.
- Catalog
Entry 🔒 - The bundled sound catalogue, embedded at compile time. Only
idandfilematter here; the frontend owns the rest (titles, attribution).
Enums§
- Audio
Cmd 🔒
Constants§
- CATALOG_
JSON 🔒 - PREVIEW_
MAX 🔒 - How long an ambient preview plays before it is cut off. Auditions on the Settings page shouldn’t loop forever.
Functions§
- catalog 🔒
- clamp_
volume - Clamp a volume to the playable
[0, 1]range. Matches the frontend’s oldclampVolumeso behaviour is identical across the IPC boundary. - custom_
path 🔒 - A user-supplied path, or
Nonefor empty input — keeps the empty-string short-circuit out of every custom-sound command. - decode 🔒
- Decode a sound file into a
rodiosource, logging (not panicking) on a missing file or an unsupported codec. - dispatch_
ambient 🔒 - Start (or preview) an ambient loop once
pathhas been resolved.Nonepath or non-positive volume is a no-op. - dispatch_
once 🔒 - Play a one-shot once
pathhas been resolved (bundled id or custom file).Nonepath or non-positive volume is a no-op. Shared by the bundled and custom command shims so the guard logic is tested once. - file_
for_ id - Resolve a catalogue
sound_idto its bundled file name, orNonewhen the id isn’t in the catalogue. The file name is then resolved against the app’s resource directory by the Tauri command layer. - play_
custom_ sound - play_
sound - preview_
ambient - preview_
custom_ ambient - resource_
sound_ 🔒path - Resolve a bundled
sound_idto its file inside the app’s resource dir. - run 🔒
- start_
ambient - start_
custom_ ambient - stop_
all_ sounds - stop_
ambient