use anyhow::Result;
use cpal::{traits::DeviceTrait, BufferSize, SizedSample, Stream, StreamConfig, StreamError};
use super::OutputDevice;
pub fn stream_audio<T, E, S>(
device: OutputDevice,
error_callback: E,
mut samples: S,
) -> Result<Stream>
where
T: SizedSample + Send + Sync + cpal::FromSample<f32> + 'static,
S: Iterator<Item = T> + Send + 'static + Clone,
E: FnMut(StreamError) + Send + 'static,
{
let supported_config = device.default_output_config()?;
let channel_count = supported_config.channels();
let stream: Stream = device.build_output_stream(
&StreamConfig {
channels: channel_count,
sample_rate: supported_config.sample_rate(),
buffer_size: {
match supported_config.buffer_size() {
cpal::SupportedBufferSize::Range { min, max: _ } => BufferSize::Fixed(*min),
cpal::SupportedBufferSize::Unknown => BufferSize::Default,
}
},
},
move |data: &mut [T], _info: &cpal::OutputCallbackInfo| {
for frame in data {
*frame = if let Some(sample) = samples.next() {
sample
} else {
T::from_sample(0.0)
};
}
},
error_callback,
None,
)?;
Ok(stream)
}