mirror of
https://github.com/oSumAtrIX/free-librespot.git
synced 2025-12-20 02:14:22 +00:00
Usage: `--format {F32|S16}`. Default is F32.
- Implemented for all backends, except for JACK audio which itself
only supports 32-bit output at this time. Setting JACK audio to S16
will panic and instruct the user to set output to F32.
- The F32 default works fine for Rodio on macOS, but not on Raspian 10
with Alsa as host. Therefore users on Linux systems are warned to set
output to S16 in case of garbled sound with Rodio. This seems an issue
with cpal incorrectly detecting the output stream format.
- While at it, DRY up lots of code in the backends and by that virtue,
also enable OggData passthrough on the subprocess backend.
- I tested Rodio, ALSA, pipe and subprocess quite a bit, and call on
others to join in and test the other backends.
62 lines
1.6 KiB
Rust
62 lines
1.6 KiB
Rust
use super::{Open, Sink, SinkAsBytes};
|
|
use crate::audio::AudioPacket;
|
|
use crate::config::AudioFormat;
|
|
use shell_words::split;
|
|
use std::io::{self, Write};
|
|
use std::process::{Child, Command, Stdio};
|
|
|
|
pub struct SubprocessSink {
|
|
shell_command: String,
|
|
child: Option<Child>,
|
|
format: AudioFormat,
|
|
}
|
|
|
|
impl Open for SubprocessSink {
|
|
fn open(shell_command: Option<String>, format: AudioFormat) -> SubprocessSink {
|
|
info!("Using subprocess sink with format: {:?}", format);
|
|
|
|
if let Some(shell_command) = shell_command {
|
|
SubprocessSink {
|
|
shell_command: shell_command,
|
|
child: None,
|
|
format: format,
|
|
}
|
|
} else {
|
|
panic!("subprocess sink requires specifying a shell command");
|
|
}
|
|
}
|
|
}
|
|
|
|
impl Sink for SubprocessSink {
|
|
fn start(&mut self) -> io::Result<()> {
|
|
let args = split(&self.shell_command).unwrap();
|
|
self.child = Some(
|
|
Command::new(&args[0])
|
|
.args(&args[1..])
|
|
.stdin(Stdio::piped())
|
|
.spawn()?,
|
|
);
|
|
Ok(())
|
|
}
|
|
|
|
fn stop(&mut self) -> io::Result<()> {
|
|
if let Some(child) = &mut self.child.take() {
|
|
child.kill()?;
|
|
child.wait()?;
|
|
}
|
|
Ok(())
|
|
}
|
|
|
|
sink_as_bytes!();
|
|
}
|
|
|
|
impl SinkAsBytes for SubprocessSink {
|
|
fn write_bytes(&mut self, data: &[u8]) -> io::Result<()> {
|
|
if let Some(child) = &mut self.child {
|
|
let child_stdin = child.stdin.as_mut().unwrap();
|
|
child_stdin.write_all(data)?;
|
|
child_stdin.flush()?;
|
|
}
|
|
Ok(())
|
|
}
|
|
}
|