diff --git a/crates/headroom-core/src/pw/registry.rs b/crates/headroom-core/src/pw/registry.rs index c4f5904..13dee0f 100644 --- a/crates/headroom-core/src/pw/registry.rs +++ b/crates/headroom-core/src/pw/registry.rs @@ -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; }