merge(audio): land feat/linux-stream-sink — Linux host-owned stream sink
Merges 44b71e74 (see its message for the full design: the "Punktfunk Stream
Speaker" Audio/Sink claimed as the session's default output — the crackle
root fix for hardware-sink churn — plus the core-error liveness fix and true
5.1/7.1 capture) across the W1–W8 refactor that landed since the branch
forked:
- punktfunk1.rs was split on main: the audio_thread idle()/drain() hunks are
hand-ported into native/audio.rs (same three sites: reuse-drain comment,
encoder-fail park, end-of-thread park).
- pwinit moved to pf-capture (W6.2): the branch's crate::pwinit calls in
pw_thread and stream_sink.rs become pf_capture::pwinit.
- Kept main's log-tier demotions (stream-state + setup lines at debug)
inside the restructured pw_thread.
Resolution verified on Linux (home-worker-5): clippy -D warnings clean +
173 punktfunk-host tests green at the 691c064a-based equivalent ba5973a2;
re-verified at this base before landing.
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -71,9 +71,9 @@ pub(super) fn audio_thread(
|
||||
// Reuse the cached capturer ONLY when its channel count matches this session's; a stereo
|
||||
// capturer left by a prior session must not feed a 5.1/7.1 session (the encoder + the client's
|
||||
// decoder are sized for `want`, so a mismatched capturer would garble/desync the audio).
|
||||
let capturer = match audio_cap.lock().unwrap().take() {
|
||||
let mut capturer = match audio_cap.lock().unwrap().take() {
|
||||
Some(mut c) if c.channels() == want as u32 => {
|
||||
c.drain(); // discard audio captured between sessions
|
||||
c.drain(); // discard audio captured between sessions (also re-claims routing)
|
||||
c
|
||||
}
|
||||
prev => {
|
||||
@@ -91,6 +91,7 @@ pub(super) fn audio_thread(
|
||||
Ok(e) => e,
|
||||
Err(e) => {
|
||||
tracing::warn!(error = %e, "opus encoder init failed — session continues without audio");
|
||||
capturer.idle(); // parked, not streaming — release the routing claim
|
||||
*audio_cap.lock().unwrap() = Some(capturer);
|
||||
return;
|
||||
}
|
||||
@@ -172,8 +173,10 @@ pub(super) fn audio_thread(
|
||||
}
|
||||
}
|
||||
}
|
||||
// Return the live capturer for the next session (None if it died and never reopened).
|
||||
if let Some(c) = capturer {
|
||||
// Return the live capturer for the next session (None if it died and never reopened),
|
||||
// releasing its session-scoped routing claim (Linux: the default sink moves back).
|
||||
if let Some(mut c) = capturer {
|
||||
c.idle();
|
||||
*audio_cap.lock().unwrap() = Some(c);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user