[fix](trx-backend): fix clippy warnings and improve code style

Fix useless vec! allocation in demod tests, improve loop iterator usage,
and reformat code for better readability across dummy and soapysdr
backends.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-26 23:33:40 +01:00
parent f8a683b312
commit 68944f7d78
4 changed files with 39 additions and 41 deletions
+16 -4
View File
@@ -157,21 +157,33 @@ mod tests {
let caps = &rig.info().capabilities; let caps = &rig.info().capabilities;
assert!(caps.tx, "dummy rig should have tx capability"); assert!(caps.tx, "dummy rig should have tx capability");
assert!(caps.tx_limit, "dummy rig should have tx_limit capability"); assert!(caps.tx_limit, "dummy rig should have tx_limit capability");
assert!(caps.vfo_switch, "dummy rig should have vfo_switch capability"); assert!(
assert!(caps.signal_meter, "dummy rig should have signal_meter capability"); caps.vfo_switch,
"dummy rig should have vfo_switch capability"
);
assert!(
caps.signal_meter,
"dummy rig should have signal_meter capability"
);
} }
#[test] #[test]
fn dummy_has_no_filter_controls() { fn dummy_has_no_filter_controls() {
let rig = DummyRig::new(); let rig = DummyRig::new();
let caps = &rig.info().capabilities; let caps = &rig.info().capabilities;
assert!(!caps.filter_controls, "dummy rig should not have filter_controls"); assert!(
!caps.filter_controls,
"dummy rig should not have filter_controls"
);
} }
#[test] #[test]
fn dummy_filter_state_is_none() { fn dummy_filter_state_is_none() {
let rig = DummyRig::new(); let rig = DummyRig::new();
assert!(rig.filter_state().is_none(), "dummy rig should return None for filter_state"); assert!(
rig.filter_state().is_none(),
"dummy rig should return None for filter_state"
);
} }
} }
@@ -94,11 +94,7 @@ fn demod_am(samples: &[Complex<f32>]) -> Vec<f32> {
let mut output: Vec<f32> = mag.iter().map(|&m| m - mean).collect(); let mut output: Vec<f32> = mag.iter().map(|&m| m - mean).collect();
// Normalise peak to ≤ 1.0 (only if max > 1.0, to avoid amplifying noise). // Normalise peak to ≤ 1.0 (only if max > 1.0, to avoid amplifying noise).
let max_abs = output let max_abs = output.iter().copied().map(f32::abs).fold(0.0_f32, f32::max);
.iter()
.copied()
.map(f32::abs)
.fold(0.0_f32, f32::max);
if max_abs > 1.0 { if max_abs > 1.0 {
let inv = 1.0 / max_abs; let inv = 1.0 / max_abs;
for sample in &mut output { for sample in &mut output {
@@ -241,7 +237,7 @@ mod tests {
Complex::new(0.0, 0.0), Complex::new(0.0, 0.0),
Complex::new(1.0, 0.0), Complex::new(1.0, 0.0),
]; ];
let expected = vec![-0.5_f32, 0.5, -0.5, 0.5]; let expected = [-0.5_f32, 0.5, -0.5, 0.5];
let out = Demodulator::Am.demodulate(&input); let out = Demodulator::Am.demodulate(&input);
assert_eq!(out.len(), 4); assert_eq!(out.len(), 4);
for (i, (&got, &exp)) in out.iter().zip(expected.iter()).enumerate() { for (i, (&got, &exp)) in out.iter().zip(expected.iter()).enumerate() {
@@ -259,8 +255,8 @@ mod tests {
// First sample is 0.0 by convention. // First sample is 0.0 by convention.
assert_approx_eq(out[0], 0.0, 1e-6, "FM tone sample 0 (zero by convention)"); assert_approx_eq(out[0], 0.0, 1e-6, "FM tone sample 0 (zero by convention)");
// Remaining samples should be approximately 0.5. // Remaining samples should be approximately 0.5.
for i in 1..out.len() { for (i, &sample) in out.iter().enumerate().skip(1) {
assert_approx_eq(out[i], 0.5, 0.01, &format!("FM tone sample {}", i)); assert_approx_eq(sample, 0.5, 0.01, &format!("FM tone sample {}", i));
} }
} }
@@ -300,8 +296,14 @@ mod tests {
assert_eq!(Demodulator::for_mode(&RigMode::WFM), Demodulator::Wfm); assert_eq!(Demodulator::for_mode(&RigMode::WFM), Demodulator::Wfm);
assert_eq!(Demodulator::for_mode(&RigMode::CW), Demodulator::Cw); assert_eq!(Demodulator::for_mode(&RigMode::CW), Demodulator::Cw);
assert_eq!(Demodulator::for_mode(&RigMode::CWR), Demodulator::Cw); assert_eq!(Demodulator::for_mode(&RigMode::CWR), Demodulator::Cw);
assert_eq!(Demodulator::for_mode(&RigMode::DIG), Demodulator::Passthrough); assert_eq!(
assert_eq!(Demodulator::for_mode(&RigMode::PKT), Demodulator::Passthrough); Demodulator::for_mode(&RigMode::DIG),
Demodulator::Passthrough
);
assert_eq!(
Demodulator::for_mode(&RigMode::PKT),
Demodulator::Passthrough
);
} }
// Test 9: All demodulators return an empty Vec for empty input without panicking. // Test 9: All demodulators return an empty Vec for empty input without panicking.
@@ -321,8 +321,7 @@ impl SdrPipeline {
) -> Self { ) -> Self {
// Broadcast channel capacity: 64 IQ blocks. // Broadcast channel capacity: 64 IQ blocks.
const IQ_BROADCAST_CAPACITY: usize = 64; const IQ_BROADCAST_CAPACITY: usize = 64;
let (iq_tx, _iq_rx) = let (iq_tx, _iq_rx) = broadcast::channel::<Vec<Complex<f32>>>(IQ_BROADCAST_CAPACITY);
broadcast::channel::<Vec<Complex<f32>>>(IQ_BROADCAST_CAPACITY);
// PCM broadcast capacity: enough for several frames of latency. // PCM broadcast capacity: enough for several frames of latency.
const PCM_BROADCAST_CAPACITY: usize = 32; const PCM_BROADCAST_CAPACITY: usize = 32;
@@ -468,13 +467,13 @@ mod tests {
fn channel_dsp_processes_silence() { fn channel_dsp_processes_silence() {
let (pcm_tx, _pcm_rx) = broadcast::channel::<Vec<f32>>(8); let (pcm_tx, _pcm_rx) = broadcast::channel::<Vec<f32>>(8);
let mut dsp = ChannelDsp::new( let mut dsp = ChannelDsp::new(
0.0, // channel_if_hz 0.0, // channel_if_hz
&RigMode::USB, &RigMode::USB,
48_000, // sdr_sample_rate 48_000, // sdr_sample_rate
8_000, // audio_sample_rate (decim = 6) 8_000, // audio_sample_rate (decim = 6)
20, // frame_duration_ms → frame_size = 160 20, // frame_duration_ms → frame_size = 160
3000, // audio_bandwidth_hz 3000, // audio_bandwidth_hz
31, // fir_taps 31, // fir_taps
pcm_tx, pcm_tx,
); );
@@ -486,16 +485,7 @@ mod tests {
#[test] #[test]
fn channel_dsp_set_mode() { fn channel_dsp_set_mode() {
let (pcm_tx, _) = broadcast::channel::<Vec<f32>>(8); let (pcm_tx, _) = broadcast::channel::<Vec<f32>>(8);
let mut dsp = ChannelDsp::new( let mut dsp = ChannelDsp::new(0.0, &RigMode::USB, 48_000, 8_000, 20, 3000, 31, pcm_tx);
0.0,
&RigMode::USB,
48_000,
8_000,
20,
3000,
31,
pcm_tx,
);
assert_eq!(dsp.demodulator, Demodulator::Usb); assert_eq!(dsp.demodulator, Demodulator::Usb);
dsp.set_mode(&RigMode::FM); dsp.set_mode(&RigMode::FM);
assert_eq!(dsp.demodulator, Demodulator::Fm); assert_eq!(dsp.demodulator, Demodulator::Fm);
@@ -516,13 +506,7 @@ mod tests {
#[test] #[test]
fn pipeline_empty_channels() { fn pipeline_empty_channels() {
let pipeline = SdrPipeline::start( let pipeline = SdrPipeline::start(Box::new(MockIqSource), 1_920_000, 48_000, 20, &[]);
Box::new(MockIqSource),
1_920_000,
48_000,
20,
&[],
);
assert_eq!(pipeline.pcm_senders.len(), 0); assert_eq!(pipeline.pcm_senders.len(), 0);
assert_eq!(pipeline.channel_dsps.len(), 0); assert_eq!(pipeline.channel_dsps.len(), 0);
} }
@@ -8,11 +8,11 @@ pub mod dsp;
use std::pin::Pin; use std::pin::Pin;
use trx_core::radio::freq::{Band, Freq}; use trx_core::radio::freq::{Band, Freq};
use trx_core::rig::response::RigError;
use trx_core::rig::state::RigFilterState;
use trx_core::rig::{ use trx_core::rig::{
AudioSource, Rig, RigAccessMethod, RigCapabilities, RigCat, RigInfo, RigStatusFuture, AudioSource, Rig, RigAccessMethod, RigCapabilities, RigCat, RigInfo, RigStatusFuture,
}; };
use trx_core::rig::response::RigError;
use trx_core::rig::state::RigFilterState;
use trx_core::{DynResult, RigMode}; use trx_core::{DynResult, RigMode};
/// RX-only backend for any SoapySDR-compatible device. /// RX-only backend for any SoapySDR-compatible device.