rusty-dsp/src/sinks.rs

75 lines
2.4 KiB
Rust
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

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<dyn Iterator<Item = Result<f32, DspError>> + 'a>,
sampling_rate: u32,
}
impl<'a> SoundCardSink<'a> {
pub fn from<I>(iterator1: I, sampling_rate: u32) -> SoundCardSink<'a>
where
I: Iterator<Item = Result<f32, DspError>> + '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 applications 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()))?;
}
}
}