alsa.rs 1.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. use super::{Open, Sink};
  2. use alsa::{Access, Format, Mode, Stream, PCM};
  3. use std::io;
  4. pub struct AlsaSink(Option<PCM>, String);
  5. impl Open for AlsaSink {
  6. fn open(device: Option<String>) -> AlsaSink {
  7. info!("Using alsa sink");
  8. let name = device.unwrap_or("default".to_string());
  9. AlsaSink(None, name)
  10. }
  11. }
  12. impl Sink for AlsaSink {
  13. fn start(&mut self) -> io::Result<()> {
  14. if self.0.is_none() {
  15. match PCM::open(
  16. &*self.1,
  17. Stream::Playback,
  18. Mode::Blocking,
  19. Format::Signed16,
  20. Access::Interleaved,
  21. 2,
  22. 44100,
  23. ) {
  24. Ok(f) => self.0 = Some(f),
  25. Err(e) => {
  26. error!("Alsa error PCM open {}", e);
  27. return Err(io::Error::new(
  28. io::ErrorKind::Other,
  29. "Alsa error: PCM open failed",
  30. ));
  31. }
  32. }
  33. }
  34. Ok(())
  35. }
  36. fn stop(&mut self) -> io::Result<()> {
  37. self.0 = None;
  38. Ok(())
  39. }
  40. fn write(&mut self, data: &[i16]) -> io::Result<()> {
  41. self.0.as_mut().unwrap().write_interleaved(&data).unwrap();
  42. Ok(())
  43. }
  44. }