mod.rs 2.0 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879
  1. use std::io;
  2. pub trait Open {
  3. fn open(_: Option<String>) -> Self;
  4. }
  5. pub trait Sink {
  6. fn start(&mut self) -> io::Result<()>;
  7. fn stop(&mut self) -> io::Result<()>;
  8. fn write(&mut self, data: &[i16]) -> io::Result<()>;
  9. }
  10. fn mk_sink<S: Sink + Open + 'static>(device: Option<String>) -> Box<dyn Sink> {
  11. Box::new(S::open(device))
  12. }
  13. #[cfg(feature = "alsa-backend")]
  14. mod alsa;
  15. #[cfg(feature = "alsa-backend")]
  16. use self::alsa::AlsaSink;
  17. #[cfg(feature = "portaudio-backend")]
  18. mod portaudio;
  19. #[cfg(feature = "portaudio-backend")]
  20. use self::portaudio::PortAudioSink;
  21. #[cfg(feature = "pulseaudio-backend")]
  22. mod pulseaudio;
  23. #[cfg(feature = "pulseaudio-backend")]
  24. use self::pulseaudio::PulseAudioSink;
  25. #[cfg(feature = "jackaudio-backend")]
  26. mod jackaudio;
  27. #[cfg(feature = "jackaudio-backend")]
  28. use self::jackaudio::JackSink;
  29. #[cfg(feature = "rodio-backend")]
  30. mod rodio;
  31. #[cfg(feature = "rodio-backend")]
  32. use self::rodio::RodioSink;
  33. #[cfg(feature = "sdl-backend")]
  34. mod sdl;
  35. #[cfg(feature = "sdl-backend")]
  36. use self::sdl::SdlSink;
  37. mod pipe;
  38. use self::pipe::StdoutSink;
  39. pub const BACKENDS: &'static [(&'static str, fn(Option<String>) -> Box<dyn Sink>)] = &[
  40. #[cfg(feature = "alsa-backend")]
  41. ("alsa", mk_sink::<AlsaSink>),
  42. #[cfg(feature = "portaudio-backend")]
  43. ("portaudio", mk_sink::<PortAudioSink>),
  44. #[cfg(feature = "pulseaudio-backend")]
  45. ("pulseaudio", mk_sink::<PulseAudioSink>),
  46. #[cfg(feature = "jackaudio-backend")]
  47. ("jackaudio", mk_sink::<JackSink>),
  48. #[cfg(feature = "rodio-backend")]
  49. ("rodio", mk_sink::<RodioSink>),
  50. #[cfg(feature = "sdl-backend")]
  51. ("sdl", mk_sink::<SdlSink>),
  52. ("pipe", mk_sink::<StdoutSink>),
  53. ];
  54. pub fn find(name: Option<String>) -> Option<fn(Option<String>) -> Box<dyn Sink>> {
  55. if let Some(name) = name {
  56. BACKENDS
  57. .iter()
  58. .find(|backend| name == backend.0)
  59. .map(|backend| backend.1)
  60. } else {
  61. Some(
  62. BACKENDS
  63. .first()
  64. .expect("No backends were enabled at build time")
  65. .1,
  66. )
  67. }
  68. }