2016-03-14 02:16:59 +00:00
|
|
|
use super::{Open, Sink};
|
2018-02-26 01:50:41 +00:00
|
|
|
use alsa::{Access, Format, Mode, Stream, PCM};
|
2016-03-14 02:16:59 +00:00
|
|
|
use std::io;
|
|
|
|
|
|
|
|
pub struct AlsaSink(Option<PCM>, String);
|
|
|
|
|
|
|
|
impl Open for AlsaSink {
|
2018-02-26 01:50:41 +00:00
|
|
|
fn open(device: Option<String>) -> AlsaSink {
|
2017-01-06 14:21:44 +00:00
|
|
|
info!("Using alsa sink");
|
2016-03-14 02:16:59 +00:00
|
|
|
|
2017-01-18 18:41:22 +00:00
|
|
|
let name = device.unwrap_or("default".to_string());
|
2016-03-14 02:16:59 +00:00
|
|
|
|
|
|
|
AlsaSink(None, name)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Sink for AlsaSink {
|
|
|
|
fn start(&mut self) -> io::Result<()> {
|
2018-02-04 23:33:17 +00:00
|
|
|
if self.0.is_none() {
|
2018-02-26 01:50:41 +00:00
|
|
|
match PCM::open(
|
|
|
|
&*self.1,
|
|
|
|
Stream::Playback,
|
|
|
|
Mode::Blocking,
|
|
|
|
Format::Signed16,
|
|
|
|
Access::Interleaved,
|
|
|
|
2,
|
|
|
|
44100,
|
|
|
|
) {
|
2018-01-26 00:42:24 +00:00
|
|
|
Ok(f) => self.0 = Some(f),
|
|
|
|
Err(e) => {
|
2018-02-26 01:50:41 +00:00
|
|
|
error!("Alsa error PCM open {}", e);
|
|
|
|
return Err(io::Error::new(
|
|
|
|
io::ErrorKind::Other,
|
|
|
|
"Alsa error: PCM open failed",
|
|
|
|
));
|
2018-01-26 00:42:24 +00:00
|
|
|
}
|
|
|
|
}
|
2016-03-14 02:16:59 +00:00
|
|
|
}
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn stop(&mut self) -> io::Result<()> {
|
|
|
|
self.0 = None;
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
|
|
|
|
fn write(&mut self, data: &[i16]) -> io::Result<()> {
|
|
|
|
self.0.as_mut().unwrap().write_interleaved(&data).unwrap();
|
|
|
|
Ok(())
|
|
|
|
}
|
|
|
|
}
|