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