Expand description
AudioEngine subprocess: the main app spawns the audio-engine JUCE binary (audio-engine/ CMake target),
sends JSON lines on stdin, reads one JSON line per request. Keeps one child process alive
(stdin loop in the AudioEngine) so stream state and IPC stay cheap.
On app quit, shutdown_audio_engine_child runs from Tauri RunEvent::Exit / ExitRequested and from libc::atexit
so the AudioEngine is always terminated with the host. AUDIO_HAXOR_PARENT_PID is set at spawn so the AudioEngine can
exit if the host disappears without cleanup (e.g. macOS force quit / SIGKILL).
Shutdown must not take ENGINE_CHILD before killing the OS process. Another thread can
hold that mutex while blocked on stdout.read_line(); waiting on the mutex first deadlocks
quit (AudioEngine never receives kill). We keep the child PID in ENGINE_CHILD_PID and send
SIGKILL / taskkill /F first, then clear the slot.
Structsยง
- Audio
Engine Stub - Placeholder struct kept for serde stability / future prefs sync.
- Engine
Child ๐
Constantsยง
- EOF_
WATCHDOG_ ๐POLL_ MS - Only runs while the WebView poll is deferred โ ~1 Hz keeps idle CPU low; foreground-focused playback does not run this thread.
Staticsยง
- ENGINE_
CHILD ๐ - ENGINE_
CHILD_ ๐PID - OS PID of the current AudioEngine (
Child::id), or0if none. Used for kill-on-exit without waiting onENGINE_CHILD(see module comment). - EOF_
WATCHDOG_ ๐ACTIVE - Host-side
playback_statuspoll for library playback EOF when the WebView defers itssetIntervalpoll (isUiIdleHeavyCpuโ hidden, unfocused, minimized; seesyncEnginePlaybackEofWatchdoginaudio-engine.js). Throttled background timers can miss EOF for autoplay-next; this thread emitsaudio-engine-playback-eofon the sameloaded && eofrising edge as the UI poll.
Functionsยง
- audio_
engine_ child_ pid - OS PID of the current AudioEngine subprocess (
Child::id), or0if none has been spawned yet. - audio_
engine_ eof_ watchdog_ start - Start a background thread that polls
playback_statuseveryEOF_WATCHDOG_POLL_MSand emitsaudio-engine-playback-eofwhenloaded && eoftransitions to true (same edgeaudio-engine.jsuses for autoplay next). Idempotent โ if already running, returns immediately. - audio_
engine_ eof_ watchdog_ stop - Stop the host EOF poll (e.g. when library playback polling stops or the engine restarts).
- binary_
name ๐ - child_
dead ๐ - clear_
engine_ ๐pid - clear_
engine_ ๐slot_ after_ os_ kill - Reap
Childhandles after the OS process is gone. Never uses blockingMutex::lock(). Returnstrueif the slot was cleared;falseif we gave up waiting (~30s). - ensure_
engine_ ๐child - find_
audio_ ๐engine_ under_ target_ ancestors - Walk parents of
exeuntilaudio-engine-artifacts/โฆor legacytarget/โฆ/<binary>exists (workspace root). - format_
stderr_ ๐suffix - kill_
pid_ ๐raw - Hard-kill by PID so quit works even when no
Childhandle is available. - log_
ipc_ ๐failure - Log host-side IPC failure to
app.log, appending recent AudioEngine stderr when available. - normalize_
ipc_ ๐request_ payload - Tauri may pass
{ "request": { "cmd": ... } }frominvoke(..., { request: payload }); unwrap so stdin matches the audio-engine line protocol. If the top-level object already hascmd, it is left unchanged (even whenrequestis also present). - read_
engine_ ๐json_ line - One response is one JSON object/array per line. A linked library may print warnings to stdout
before the JSON line (e.g.
Warning: thread locking is not implemented), which would breakserde_json::from_stron the firstread_line. Skip lines until one starts with{or[. - record_
engine_ ๐pid - resolve_
audio_ engine_ binary - Resolve path to the
audio-engineexecutable. - restart_
audio_ engine_ child - Drop the long-lived
audio-enginechild so the next IPC spawns a fresh process. Use after a crash or when the AudioEngine stops responding. - shutdown_
audio_ engine_ child - Kill the JUCE AudioEngine when the host app exits. Idempotent (safe if no child was spawned).
- spawn_
audio_ engine_ request - Run one request against the audio-engine subprocess (stdin / stdout JSON lines).
- spawn_
audio_ ๐engine_ request_ at - spawn_
engine_ ๐child - take_
and_ ๐reap_ engine_ child - Drop the in-memory slot after the OS process is dead or being replaced. Caller must have
cleared or updated
ENGINE_CHILD_PIDappropriately.