//! Windows audio backend (cpal/WASAPI) — **Phase 0 stub**. //! //! This is a compile-and-run placeholder so the Windows build links and the app //! starts up (networking, UI, and text chat all functional) while the real //! capture/playback implementation lands in Phase 1. Every method satisfies the //! [`AudioBackend`] contract as a no-op: no microphone is captured and nothing is //! played. It deliberately pulls in no extra dependency — `cpal` is added only //! when the real implementation arrives. //! //! Phase 1 will replace this with cpal streams on the WASAPI host, mapping: //! - `start_capture` → input stream, f32→i16, mono 48 kHz, into `tx`; //! - `start_playback` → output stream draining a `ringbuf`, keeping `ring_fill` //! updated so the existing hardware-clock pacing in the mixer keeps working; //! - `stop` → drop the streams. use std::sync::Arc; use std::sync::atomic::AtomicUsize; use std::sync::mpsc::{Receiver, Sender}; use super::{AudioBackend, AudioError}; /// No-op Windows audio backend (Phase 0). See module docs. pub struct CpalBackend; impl CpalBackend { pub fn new() -> Self { crate::log_msg("CpalBackend: Phase 0 stub active (no audio I/O yet)"); CpalBackend } } impl Default for CpalBackend { fn default() -> Self { Self::new() } } impl AudioBackend for CpalBackend { fn start_capture( &self, _tx: Sender>, _target_node: Option, ) -> Result<(), AudioError> { // No capture stream yet: dropping `_tx` simply means no samples are ever // produced (silent mic), which is the intended Phase 0 behaviour. crate::log_msg("CpalBackend::start_capture: not yet implemented (Phase 1) — capturing silence"); Ok(()) } fn start_playback( &self, rx: Receiver>, _target_node: Option, _ring_fill: Arc, ) -> Result<(), AudioError> { // Drain and discard incoming audio on a detached thread so the mixer's // producer never blocks or sees a closed channel. This keeps the rest of // the pipeline running normally while output is silent. std::thread::spawn(move || while rx.recv().is_ok() {}); crate::log_msg("CpalBackend::start_playback: not yet implemented (Phase 1) — discarding output"); Ok(()) } fn stop(&self) -> Result<(), AudioError> { Ok(()) } }