extern crate libpulse_binding as pulse; extern crate libpulse_simple_binding as psimple; use psimple::Simple; use pulse::sample; use pulse::stream::Direction; use super::error::{new_error, DspError}; pub struct SoundCardSink<'a> { iterator: Box> + 'a>, sampling_rate: u32, } impl<'a> SoundCardSink<'a> { pub fn from(iterator1: I, sampling_rate: u32) -> SoundCardSink<'a> where I: Iterator> + 'a, { SoundCardSink { iterator: Box::new(iterator1), sampling_rate: sampling_rate, } } pub fn start(&mut self) -> Result<(), DspError> { let spec = sample::Spec { format: sample::SAMPLE_FLOAT32NE, channels: 1, rate: self.sampling_rate, }; if !spec.is_valid() { return Err(new_error("Sample spec is invalid.")); } let stream = Simple::new( None, // Use the default server "Rusty DSP", // Our application’s name Direction::Playback, // We want a playback stream None, // Use the default device "Sound Card Sink", // Description of our stream &spec, // Our sample format None, // Use default channel map None, // Use default buffering attributes ) .map_err(|e| DspError::Error(e.to_string().unwrap()))?; loop { let mut chunk = Vec::new(); while chunk.len() < 64 { let mut sample = Some(Err(DspError::WouldBlock)); while sample == Some(Err(DspError::WouldBlock)) { sample = self.iterator.next(); } let value = match sample { Some(Ok(f)) => f, None => return Ok(()), Some(Err(DspError::WouldBlock)) => { return Err(new_error("Unexpected WouldBlock.")) } Some(Err(e)) => return Err(e), }; chunk.extend_from_slice(value.to_ne_bytes().as_ref()); } stream .write(chunk.as_slice()) .map_err(|e| DspError::Error(e.to_string().unwrap()))?; } } }