Added a pulse audio sink

This commit is contained in:
Sebastian 2020-06-23 22:22:45 +02:00
parent 7186738a22
commit b4fd91ea13
5 changed files with 103 additions and 7 deletions

View File

@ -8,3 +8,5 @@ edition = "2018"
[dependencies]
num = "*"
libpulse-binding = "2.16.0"
libpulse-simple-binding = "*"

View File

@ -0,0 +1,15 @@
extern crate rusty_dsp;
use std::io;
use rusty_dsp::multiply::MultiplyConst;
use rusty_dsp::sinks::SoundCardSink;
use rusty_dsp::sources::SinSource;
fn main() {
let source = SinSource::new(440.0, 48000.0);
let mult = MultiplyConst::from(source, 0.3);
let mut sink = SoundCardSink::from(mult, 48000);
sink.start().unwrap();
}

View File

@ -5,3 +5,7 @@ pub enum DspError {
WouldBlock,
Error(String),
}
pub fn new_error(msg: &str) -> DspError {
DspError::Error(msg.to_string())
}

View File

@ -1,7 +1,8 @@
mod amdemod;
mod error;
mod fillers;
mod firfilter;
mod multiply;
mod resamplers;
mod sources;
pub mod amdemod;
pub mod error;
pub mod fillers;
pub mod firfilter;
pub mod multiply;
pub mod resamplers;
pub mod sinks;
pub mod sources;

74
src/sinks.rs Normal file
View File

@ -0,0 +1,74 @@
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()))?;
}
}
}