use anyhow::Result;
use cpal::traits::DeviceTrait;
use cpal::{Device, Sample, SizedSample, StreamConfig};
use crate::buffer::SharedBuf;
use std::sync::{Arc, Mutex};
pub fn build_stream<T>(
device: &Device,
cfg: &StreamConfig,
shared: Arc<Mutex<SharedBuf>>,
) -> Result<cpal::Stream>
where
T: Sample + SizedSample,
f32: cpal::FromSample<T>,
{
let ch = cfg.channels as usize;
let err_fn = |err: cpal::StreamError| {
eprintln!("[lookas] audio stream error: {err}");
};
let stream = device.build_input_stream(
cfg,
move |data: &[T], _| {
if let Ok(mut buf) = shared.try_lock() {
for frame in data.chunks_exact(ch) {
let mut acc = 0.0f32;
for &s in frame {
acc += s.to_sample::<f32>();
}
#[allow(clippy::cast_precision_loss)]
buf.push(acc / ch as f32);
}
}
},
err_fn,
None,
)?;
Ok(stream)
}