mirror of
https://github.com/librespot-org/librespot.git
synced 2025-01-07 17:24:04 +00:00
5435ab3270
fe37186
added the restriction that `Sink`s must be `Send`. It turned
out later that this restrictions was unnecessary, and since some
`Sink`s aren't `Send` yet, this restriction is lifted again.
librespot-org/librespot#601 refactored the `RodioSink` in order to make
it `Send`. These changes are partly reverted in favour of the initial
simpler design.
Furthermore, there were some compile errors in the gstreamer backend
which are hereby fixed.
94 lines
2.4 KiB
Rust
94 lines
2.4 KiB
Rust
use crate::audio::AudioPacket;
|
|
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, packet: &AudioPacket) -> io::Result<()>;
|
|
}
|
|
|
|
pub type SinkBuilder = fn(Option<String>) -> Box<dyn Sink>;
|
|
|
|
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(any(feature = "rodio-backend", feature = "rodiojack-backend"))]
|
|
mod rodio;
|
|
|
|
#[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: &[(&str, SinkBuilder)] = &[
|
|
#[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", rodio::mk_rodio),
|
|
#[cfg(feature = "rodiojack-backend")]
|
|
("rodiojack", rodio::mk_rodiojack),
|
|
#[cfg(feature = "sdl-backend")]
|
|
("sdl", mk_sink::<SdlSink>),
|
|
("pipe", mk_sink::<StdoutSink>),
|
|
("subprocess", mk_sink::<SubprocessSink>),
|
|
];
|
|
|
|
pub fn find(name: Option<String>) -> Option<SinkBuilder> {
|
|
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,
|
|
)
|
|
}
|
|
}
|