diff --git a/Cargo.lock b/Cargo.lock index 7e472b98..97d858c5 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -2,6 +2,7 @@ name = "librespot" version = "0.1.0" dependencies = [ + "alsa 0.0.1 (git+https://github.com/plietar/rust-alsa)", "bit-set 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)", "byteorder 0.5.3 (registry+https://github.com/rust-lang/crates.io-index)", "clippy 0.0.78 (registry+https://github.com/rust-lang/crates.io-index)", @@ -46,6 +47,14 @@ dependencies = [ "memchr 0.1.11 (registry+https://github.com/rust-lang/crates.io-index)", ] +[[package]] +name = "alsa" +version = "0.0.1" +source = "git+https://github.com/plietar/rust-alsa#8c63543fa0ccd971cf15f5675293d19febd6f79e" +dependencies = [ + "libc 0.2.13 (registry+https://github.com/rust-lang/crates.io-index)", +] + [[package]] name = "aster" version = "0.20.0" diff --git a/Cargo.toml b/Cargo.toml index ca55b027..54288a6f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -48,6 +48,7 @@ shannon = { git = "https://github.com/plietar/rust-shannon" } vorbis = "~0.0.14" tremor = { git = "https://github.com/plietar/rust-tremor", optional = true } +alsa = { git = "https://github.com/plietar/rust-alsa", optional = true } portaudio = { git = "https://github.com/mvdnes/portaudio-rs", optional = true } libpulse-sys = { git = "https://github.com/astro/libpulse-sys", optional = true } @@ -72,6 +73,7 @@ nightly = ["serde_macros"] with-tremor = ["tremor"] facebook = ["hyper/ssl", "openssl"] +alsa-backend = ["alsa"] portaudio-backend = ["portaudio"] pulseaudio-backend= ["libpulse-sys"] default = ["with-syntex", "portaudio-backend"] diff --git a/README.md b/README.md index f61df478..44ebadae 100644 --- a/README.md +++ b/README.md @@ -66,6 +66,7 @@ target/release/librespot [...] --backend portaudio ``` The following backends are currently available : +- ALSA - PortAudio - PulseAudio diff --git a/src/audio_backend/alsa.rs b/src/audio_backend/alsa.rs new file mode 100644 index 00000000..a5bbe720 --- /dev/null +++ b/src/audio_backend/alsa.rs @@ -0,0 +1,38 @@ +use super::{Open, Sink}; +use std::io; +use alsa::{PCM, Stream, Mode, Format, Access}; + +pub struct AlsaSink(Option, String); + +impl Open for AlsaSink { + fn open(device: Option<&str>) -> AlsaSink { + println!("Using alsa sink"); + + let name = device.unwrap_or("default").to_string(); + + AlsaSink(None, name) + } +} + +impl Sink for AlsaSink { + fn start(&mut self) -> io::Result<()> { + if self.0.is_some() { + } else { + self.0 = Some(PCM::open(&*self.1, + Stream::Playback, Mode::Blocking, + Format::Signed16, Access::Interleaved, + 2, 44100).ok().unwrap()); + } + 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(()) + } +} diff --git a/src/audio_backend/mod.rs b/src/audio_backend/mod.rs index 617d25d9..4dc85124 100644 --- a/src/audio_backend/mod.rs +++ b/src/audio_backend/mod.rs @@ -54,6 +54,11 @@ fn mk_sink(device: Option<&str>) -> Box { Box::new(S::open(device)) } +#[cfg(feature = "alsa-backend")] +mod alsa; +#[cfg(feature = "alsa-backend")] +use self::alsa::AlsaSink; + #[cfg(feature = "portaudio-backend")] mod portaudio; #[cfg(feature = "portaudio-backend")] @@ -70,6 +75,8 @@ declare_backends! { (&'static str, &'static (Fn(Option<&str>) -> Box + Sync + Send + 'static)) ] = &[ + #[cfg(feature = "alsa-backend")] + ("alsa", &mk_sink::), #[cfg(feature = "portaudio-backend")] ("portaudio", &mk_sink::), #[cfg(feature = "pulseaudio-backend")] diff --git a/src/lib.rs b/src/lib.rs index a5b8a978..42e2ed5a 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -42,6 +42,9 @@ extern crate tremor as vorbis; #[cfg(feature = "openssl")] extern crate openssl; +#[cfg(feature = "alsa-backend")] +extern crate alsa; + #[cfg(feature = "portaudio")] extern crate portaudio;