style: apply cargo fmt across the crate (A20)
The repo never enforced rustfmt, so formatting had drifted broadly. This is a single mechanical `cargo fmt` pass over the whole crate (no behavioral change; lib suite green, 493 passed). Going forward fmt should be enforced (planned CI fmt --check step). Part of the 0.6.1 hygiene pass. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+66
-44
@@ -1,13 +1,16 @@
|
||||
use crate::audio::{AudioBackend, AudioError};
|
||||
use std::sync::mpsc::{Sender, Receiver, RecvTimeoutError};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
|
||||
use std::thread::{self, JoinHandle};
|
||||
use std::time::Duration;
|
||||
use pipewire as pw;
|
||||
use pw::{properties::properties, spa};
|
||||
use ringbuf::{
|
||||
HeapRb,
|
||||
traits::{Consumer, Producer, Split},
|
||||
};
|
||||
use spa::pod::Pod;
|
||||
use ringbuf::{HeapRb, traits::{Consumer, Producer, Split}};
|
||||
use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
|
||||
use std::sync::mpsc::{Receiver, RecvTimeoutError, Sender};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::thread::{self, JoinHandle};
|
||||
use std::time::Duration;
|
||||
|
||||
pub struct PipeWireBackend {
|
||||
capture_state: Mutex<Option<CaptureState>>,
|
||||
@@ -41,7 +44,11 @@ impl PipeWireBackend {
|
||||
}
|
||||
|
||||
impl AudioBackend for PipeWireBackend {
|
||||
fn start_capture(&self, tx: Sender<Vec<i16>>, target_node: Option<String>) -> Result<(), AudioError> {
|
||||
fn start_capture(
|
||||
&self,
|
||||
tx: Sender<Vec<i16>>,
|
||||
target_node: Option<String>,
|
||||
) -> Result<(), AudioError> {
|
||||
let mut capture_guard = self.capture_state.lock().unwrap();
|
||||
if capture_guard.is_some() {
|
||||
return Err(AudioError::Stream("Capture already started".to_string()));
|
||||
@@ -108,12 +115,17 @@ impl AudioBackend for PipeWireBackend {
|
||||
}
|
||||
}
|
||||
|
||||
fn run_capture(cmd_rx: pw::channel::Receiver<()>, tx: Sender<Vec<i16>>, target_node: Option<String>) -> Result<(), AudioError> {
|
||||
let mainloop = pw::main_loop::MainLoopRc::new(None)
|
||||
.map_err(|e| AudioError::Init(e.to_string()))?;
|
||||
fn run_capture(
|
||||
cmd_rx: pw::channel::Receiver<()>,
|
||||
tx: Sender<Vec<i16>>,
|
||||
target_node: Option<String>,
|
||||
) -> Result<(), AudioError> {
|
||||
let mainloop =
|
||||
pw::main_loop::MainLoopRc::new(None).map_err(|e| AudioError::Init(e.to_string()))?;
|
||||
let context = pw::context::ContextRc::new(&mainloop, None)
|
||||
.map_err(|e| AudioError::Init(e.to_string()))?;
|
||||
let core = context.connect_rc(None)
|
||||
let core = context
|
||||
.connect_rc(None)
|
||||
.map_err(|e| AudioError::Init(e.to_string()))?;
|
||||
|
||||
// Ring buffer setup: 9600 samples (200ms capacity for mono 48kHz)
|
||||
@@ -181,15 +193,16 @@ fn run_capture(cmd_rx: pw::channel::Receiver<()>, tx: Sender<Vec<i16>>, target_n
|
||||
|
||||
let mut params = [Pod::from_bytes(&values).unwrap()];
|
||||
|
||||
stream.connect(
|
||||
spa::utils::Direction::Input,
|
||||
None,
|
||||
pw::stream::StreamFlags::AUTOCONNECT
|
||||
| pw::stream::StreamFlags::MAP_BUFFERS
|
||||
| pw::stream::StreamFlags::RT_PROCESS,
|
||||
&mut params,
|
||||
)
|
||||
.map_err(|e| AudioError::Stream(e.to_string()))?;
|
||||
stream
|
||||
.connect(
|
||||
spa::utils::Direction::Input,
|
||||
None,
|
||||
pw::stream::StreamFlags::AUTOCONNECT
|
||||
| pw::stream::StreamFlags::MAP_BUFFERS
|
||||
| pw::stream::StreamFlags::RT_PROCESS,
|
||||
&mut params,
|
||||
)
|
||||
.map_err(|e| AudioError::Stream(e.to_string()))?;
|
||||
|
||||
// Spawn the worker thread to pop from consumer and send Vec<i16> frames
|
||||
let running = Arc::new(AtomicBool::new(true));
|
||||
@@ -257,11 +270,7 @@ const WORKER_POLL: Duration = Duration::from_millis(100);
|
||||
/// every `WORKER_POLL` even when no frames arrive — this is what lets `stop()`
|
||||
/// join the worker promptly instead of hanging on a parked blocking `recv()`
|
||||
/// (bug A7). Pure w.r.t. its inputs (no PipeWire), so it's unit-testable.
|
||||
fn drain_loop(
|
||||
rx: &Receiver<Vec<i16>>,
|
||||
running: &AtomicBool,
|
||||
mut on_frame: impl FnMut(Vec<i16>),
|
||||
) {
|
||||
fn drain_loop(rx: &Receiver<Vec<i16>>, running: &AtomicBool, mut on_frame: impl FnMut(Vec<i16>)) {
|
||||
while running.load(Ordering::Relaxed) {
|
||||
match rx.recv_timeout(WORKER_POLL) {
|
||||
Ok(frame) => on_frame(frame),
|
||||
@@ -293,7 +302,11 @@ fn publish_frame<P: Producer<Item = i16>>(
|
||||
fn frames_to_produce(requested: usize, mapped_frames: usize) -> usize {
|
||||
/// Safe per-cycle fallback when the graph doesn't report a quantum.
|
||||
const FALLBACK_FRAMES: usize = 1024;
|
||||
let want = if requested > 0 { requested } else { FALLBACK_FRAMES };
|
||||
let want = if requested > 0 {
|
||||
requested
|
||||
} else {
|
||||
FALLBACK_FRAMES
|
||||
};
|
||||
want.min(mapped_frames)
|
||||
}
|
||||
|
||||
@@ -303,11 +316,12 @@ fn run_playback(
|
||||
target_node: Option<String>,
|
||||
fill_gauge: Arc<AtomicUsize>,
|
||||
) -> Result<(), AudioError> {
|
||||
let mainloop = pw::main_loop::MainLoopRc::new(None)
|
||||
.map_err(|e| AudioError::Init(e.to_string()))?;
|
||||
let mainloop =
|
||||
pw::main_loop::MainLoopRc::new(None).map_err(|e| AudioError::Init(e.to_string()))?;
|
||||
let context = pw::context::ContextRc::new(&mainloop, None)
|
||||
.map_err(|e| AudioError::Init(e.to_string()))?;
|
||||
let core = context.connect_rc(None)
|
||||
let core = context
|
||||
.connect_rc(None)
|
||||
.map_err(|e| AudioError::Init(e.to_string()))?;
|
||||
|
||||
// Ring buffer setup: 19200 interleaved samples (200ms capacity for stereo
|
||||
@@ -428,7 +442,9 @@ fn run_playback(
|
||||
}
|
||||
if starved > 0 {
|
||||
// One wait-free atomic add per quantum — RT-safe.
|
||||
user_data.underrun_samples.fetch_add(starved, Ordering::Relaxed);
|
||||
user_data
|
||||
.underrun_samples
|
||||
.fetch_add(starved, Ordering::Relaxed);
|
||||
}
|
||||
// Decrement the exact occupancy counter by the samples we
|
||||
// actually pulled (excluding underruns, which removed
|
||||
@@ -493,7 +509,11 @@ fn run_playback(
|
||||
pw::spa::pod::Value::Choice(pw::spa::pod::ChoiceValue::Int(
|
||||
pw::spa::utils::Choice(
|
||||
pw::spa::utils::ChoiceFlags::empty(),
|
||||
pw::spa::utils::ChoiceEnum::Range { default: 8, min: 2, max: 64 },
|
||||
pw::spa::utils::ChoiceEnum::Range {
|
||||
default: 8,
|
||||
min: 2,
|
||||
max: 64,
|
||||
},
|
||||
),
|
||||
)),
|
||||
),
|
||||
@@ -524,15 +544,16 @@ fn run_playback(
|
||||
Pod::from_bytes(&buffers_values).unwrap(),
|
||||
];
|
||||
|
||||
stream.connect(
|
||||
spa::utils::Direction::Output,
|
||||
None,
|
||||
pw::stream::StreamFlags::AUTOCONNECT
|
||||
| pw::stream::StreamFlags::MAP_BUFFERS
|
||||
| pw::stream::StreamFlags::RT_PROCESS,
|
||||
&mut params,
|
||||
)
|
||||
.map_err(|e| AudioError::Stream(e.to_string()))?;
|
||||
stream
|
||||
.connect(
|
||||
spa::utils::Direction::Output,
|
||||
None,
|
||||
pw::stream::StreamFlags::AUTOCONNECT
|
||||
| pw::stream::StreamFlags::MAP_BUFFERS
|
||||
| pw::stream::StreamFlags::RT_PROCESS,
|
||||
&mut params,
|
||||
)
|
||||
.map_err(|e| AudioError::Stream(e.to_string()))?;
|
||||
|
||||
// Spawn a worker thread to read from rx and push to producer
|
||||
let running = Arc::new(AtomicBool::new(true));
|
||||
@@ -607,7 +628,10 @@ fn run_playback(
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::{drain_loop, for_each_capture_sample, frames_to_produce, publish_frame};
|
||||
use ringbuf::{HeapRb, traits::{Consumer, Producer, Split}};
|
||||
use ringbuf::{
|
||||
HeapRb,
|
||||
traits::{Consumer, Producer, Split},
|
||||
};
|
||||
use std::sync::atomic::{AtomicBool, AtomicU64, AtomicUsize, Ordering};
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::time::Duration;
|
||||
@@ -647,9 +671,7 @@ mod tests {
|
||||
#[test]
|
||||
fn capture_size_larger_than_mapping_is_clamped() {
|
||||
let mut samples = Vec::new();
|
||||
for_each_capture_sample(&[1, 0, 2, 0, 3], usize::MAX, |sample| {
|
||||
samples.push(sample)
|
||||
});
|
||||
for_each_capture_sample(&[1, 0, 2, 0, 3], usize::MAX, |sample| samples.push(sample));
|
||||
assert_eq!(samples, vec![1, 2]);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user