[fix](trx-backend-soapysdr): fix audio distortion from incorrect force_mono_pcm

Two bugs introduced by 60697bb:

1. dsp.rs passed `channel_idx == 0` as force_mono_pcm, which forced the
   primary pipeline channel to output mono samples. The Opus encoder was
   configured for stereo, so it received half the expected frame data,
   causing distortion for all connected audio clients.
   Fixed by passing `false` — hidden virtual channels already set
   force_mono_pcm=true via set_force_mono_pcm() in vchan_impl.rs.

2. main.rs short-circuited channel conversion when no audio clients were
   connected, sending raw frames to pcm_tx (decoders). When clients then
   connected, decoders switched to receiving stereo-interleaved frames,
   making decoder input format dependent on client presence.
   Fixed by always performing the channel conversion before sending to
   pcm_tx; the no-client skip now only bypasses Opus encode + rx_audio_tx.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Signed-off-by: Stan Grams <sjg@haxx.space>
This commit is contained in:
2026-03-14 08:53:08 +01:00
parent 945912adc1
commit 587ece9903
2 changed files with 4 additions and 7 deletions
+3 -6
View File
@@ -575,12 +575,6 @@ fn spawn_rig_audio_stack(
loop {
match sdr_rx.recv().await {
Ok(frame) => {
let has_audio_clients = rx_audio_tx_sdr.receiver_count() > 0;
if !has_audio_clients {
let _ = pcm_tx_clone.send(frame);
continue;
}
let pcm_frame = match sdr_channels {
1 => frame,
2 => {
@@ -598,6 +592,9 @@ fn spawn_rig_audio_stack(
_ => unreachable!("validated above"),
};
let _ = pcm_tx_clone.send(pcm_frame.clone());
if rx_audio_tx_sdr.receiver_count() == 0 {
continue;
}
match encoder.encode_float(&pcm_frame, &mut opus_buf) {
Ok(len) => {
let pkt = Bytes::copy_from_slice(&opus_buf[..len]);
@@ -155,7 +155,7 @@ impl SdrPipeline {
wfm_deemphasis_us,
wfm_stereo,
fir_taps,
channel_idx == 0,
false,
channel_squelch_cfg,
pcm_tx.clone(),
iq_tx.clone(),