Skip to main content

Module audio

Module audio 

Source
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§

AudioPlayer
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.
CatalogEntry 🔒
The bundled sound catalogue, embedded at compile time. Only id and file matter here; the frontend owns the rest (titles, attribution).

Enums§

AudioCmd 🔒

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 old clampVolume so behaviour is identical across the IPC boundary.
custom_path 🔒
A user-supplied path, or None for empty input — keeps the empty-string short-circuit out of every custom-sound command.
decode 🔒
Decode a sound file into a rodio source, logging (not panicking) on a missing file or an unsupported codec.
dispatch_ambient 🔒
Start (or preview) an ambient loop once path has been resolved. None path or non-positive volume is a no-op.
dispatch_once 🔒
Play a one-shot once path has been resolved (bundled id or custom file). None path 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_id to its bundled file name, or None when 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_id to its file inside the app’s resource dir.
run 🔒
start_ambient
start_custom_ambient
stop_all_sounds
stop_ambient