stage 3: daemon core
Phase 3 — bring up the daemon end-to-end through six checkpoints:
3a Module skeleton (error, profile, routing, runtime, pw/*)
3b Pure routing engine + 13 tests (no PipeWire dep)
3c PwContext: main loop, sigprocmask-block SIGTERM/SIGINT before
add_signal_local so signalfd actually picks them up
3d headroom-processed virtual sink via the adapter factory with
factory.name=support.null-audio-sink
3e Filter: two pw_streams (capture from monitor / playback to real
sink) with an rtrb SPSC ring between them. DSP chain
(Compressor → two-tier Limiter) runs in the playback callback.
Allocation-free; #![forbid(unsafe_code)] preserved via
bytemuck::try_cast_slice for the byte↔f32 reinterpretation.
3f Registry watcher binds the default metadata, evaluates new
Stream/Output/Audio nodes against profile rules, writes
target.object for processed routes. Self-stream guard skips
anything whose node.name starts with 'headroom-filter'.
Workspace deps added: pipewire = { features = ["v0_3_44"] } for the
modern TARGET_OBJECT key, libspa, rtrb, nix (sigprocmask), bytemuck.
Tests: 65 passing (28 dsp, 20 ipc, 4 client, 13 core). Clippy clean
at default level under -D warnings.
PLAN.md §5 renumbered to fix stale subsection labels (was 4.1–4.4
from before the per-app insertion).
Known limitations punted to Phase 4 (documented in commit history
and team memory):
- WirePlumber doesn't always honor late target.object writes once
a stream is already linked (timing race).
- preferred_real_sink dynamic tracking stubbed.
- No auto-promote of headroom-processed to system default.
- application.process.binary occasionally arrives in late metadata
updates after the global registers; routing logs show '?' until
we add a re-read.
This commit is contained in:
parent
ca1910de60
commit
ae83310772
14 changed files with 2280 additions and 39 deletions
|
|
@ -41,6 +41,7 @@ clap = { version = "4.5", features = ["derive"] }
|
|||
crossbeam-channel = "0.5"
|
||||
parking_lot = "0.12"
|
||||
signal-hook = "0.3"
|
||||
nix = { version = "0.27", features = ["signal"] }
|
||||
|
||||
# Realtime audio
|
||||
rtrb = "0.3"
|
||||
|
|
@ -51,10 +52,13 @@ assert_no_alloc = "1.1"
|
|||
ebur128 = "0.1"
|
||||
fundsp = "0.20"
|
||||
|
||||
# PipeWire
|
||||
pipewire = "0.8"
|
||||
# PipeWire. `v0_3_44` exposes target.object key + related modern APIs.
|
||||
pipewire = { version = "0.8", features = ["v0_3_44"] }
|
||||
libspa = "0.8"
|
||||
|
||||
# Safe byte<->POD casts for audio buffers.
|
||||
bytemuck = "1.18"
|
||||
|
||||
# Profile hot-reload
|
||||
notify = "6.1"
|
||||
notify-debouncer-mini = "0.4"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue