X-Git-Url: https://code.octet-stream.net/m17rt/blobdiff_plain/0ae30668b7142e60de9efcc6e2e2724f9ec77962..c74046ba58c5fed4c1efc2a4e06ea12325d1d4cd:/m17codec2/src/rx.rs diff --git a/m17codec2/src/rx.rs b/m17codec2/src/rx.rs index c6d3cdc..5649519 100644 --- a/m17codec2/src/rx.rs +++ b/m17codec2/src/rx.rs @@ -50,7 +50,6 @@ impl Codec2RxAdapter { pub fn new() -> Self { Self { state: Arc::new(Mutex::new(AdapterState { - tx: None, out_buf: VecDeque::new(), codec2: Codec2::new(Codec2Mode::MODE_3200), end_tx: None, @@ -63,6 +62,33 @@ impl Codec2RxAdapter { pub fn set_output_card>(&mut self, card_name: S) { self.output_card = Some(card_name.into()); } + + /// List sound cards supported for audio output. + /// + /// M17RT will handle any card with 1 or 2 channels and 16-bit output. + pub fn supported_output_cards() -> Vec { + let mut out = vec![]; + let host = cpal::default_host(); + let Ok(output_devices) = host.output_devices() else { + return out; + }; + for d in output_devices { + let Ok(mut configs) = d.supported_output_configs() else { + continue; + }; + if configs.any(|config| { + (config.channels() == 1 || config.channels() == 2) + && config.sample_format() == SampleFormat::I16 + }) { + let Ok(name) = d.name() else { + continue; + }; + out.push(name); + } + } + out.sort(); + out + } } impl Default for Codec2RxAdapter { @@ -72,7 +98,6 @@ impl Default for Codec2RxAdapter { } struct AdapterState { - tx: Option, /// Circular buffer of output samples for playback out_buf: VecDeque, codec2: Codec2, @@ -81,9 +106,7 @@ struct AdapterState { } impl StreamAdapter for Codec2RxAdapter { - fn start(&self, handle: TxHandle) -> Result<(), AdapterError> { - self.state.lock().unwrap().tx = Some(handle); - + fn start(&self, _handle: TxHandle) -> Result<(), AdapterError> { let (end_tx, end_rx) = channel(); let (setup_tx, setup_rx) = channel(); let state = self.state.clone(); @@ -92,7 +115,7 @@ impl StreamAdapter for Codec2RxAdapter { self.state.lock().unwrap().end_tx = Some(end_tx); // Propagate any errors arising in the thread let sample_rate = setup_rx.recv()??; - debug!("selected codec2 output sample rate {sample_rate}"); + debug!("selected codec2 speaker sample rate {sample_rate}"); if sample_rate != 8000 { let params = SincInterpolationParameters { sinc_len: 256, @@ -110,7 +133,6 @@ impl StreamAdapter for Codec2RxAdapter { fn close(&self) -> Result<(), AdapterError> { let mut state = self.state.lock().unwrap(); - state.tx = None; state.end_tx = None; Ok(()) }