docs: explain why mono streams aren't link-enforced
The `pair_count < 2` early-return in `apply_pending_routes` looked arbitrary from the outside (and Codex+self-review both flagged it as a possible bug). It's actually a deliberate choice: WP's source-side upmix adapter handles mono → stereo cleanly today, and broadcasting one source port to N target ports via link-factory fanout requires the limiter's stereo-link semantics and the BS.1770 multichannel weights to make sense for N=1 — neither generalises trivially. The proper fix lives in the v1 multichannel pipeline. Replaces the old "PipeWire's adapter is responsible for any downmix" comment with the actual reasoning + the contract caveat (`route.set` on a mono app won't move it; the metadata write is a hint, not enforcement) so a future contributor doesn't accidentally "fix" it without weighing the trade-offs. No code change beyond the comment + the debug-log message.
This commit is contained in:
parent
ec49206660
commit
4a80a16d79
1 changed files with 19 additions and 10 deletions
|
|
@ -1114,22 +1114,31 @@ impl RoutingState {
|
|||
};
|
||||
// Pair by ordinal up to whichever side has fewer
|
||||
// channels. For stereo→stereo this is the original
|
||||
// `take(2)`. For wider streams (surround) routed
|
||||
// Bypass to a wide sink we pair all N channels — fixes
|
||||
// the F3 bug where the old `take(2)` silently dropped
|
||||
// the centre, LFE, and surround channels of a 5.1
|
||||
// stream. If the wider side has more channels than the
|
||||
// narrower side, the extra ports are left unlinked
|
||||
// here; the destruction pass below also leaves them
|
||||
// alone (they don't land on the target sink at all).
|
||||
// PipeWire's adapter is responsible for any downmix.
|
||||
// `take(2)`. For wider streams (surround) routed Bypass
|
||||
// to a wide sink we pair all N channels — fixes the F3
|
||||
// bug where the old `take(2)` silently dropped the
|
||||
// centre, LFE, and surround channels of a 5.1 stream.
|
||||
//
|
||||
// **Mono streams are intentionally not enforced.** A
|
||||
// single-port source needs broadcast (1→N fanout) to
|
||||
// play on both channels of a stereo sink, and the
|
||||
// limiter's stereo-link semantics + the BS.1770
|
||||
// multichannel weights don't generalise cleanly to
|
||||
// `N=1`. WP's source-side upmix adapter handles mono
|
||||
// → stereo correctly today, so we let it. The cost is
|
||||
// a small contract leak (`route.set` on a mono app
|
||||
// won't actually move it; the metadata write is a
|
||||
// hint, not enforcement) — acceptable for v0, the
|
||||
// proper fix is part of the v1 multichannel pipeline.
|
||||
// See PLAN §11 "Filter rate matching" and the
|
||||
// multichannel-deferral memory.
|
||||
let pair_count = src_outs.len().min(target_ins.len());
|
||||
if pair_count < 2 {
|
||||
tracing::debug!(
|
||||
node_id,
|
||||
src_outs = src_outs.len(),
|
||||
target_ins = target_ins.len(),
|
||||
"pending route: not enough ports yet"
|
||||
"pending route: not enough ports for stereo+ pairing (mono left to WP)"
|
||||
);
|
||||
continue;
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue