mirror of
https://github.com/librespot-org/librespot.git
synced 2025-10-03 17:59:24 +02:00
Add command-line option to set F32 or S16 bit output
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.
This commit is contained in:
parent
1672eb87ab
commit
5257be7824
15 changed files with 504 additions and 314 deletions
|
@ -1,22 +1,25 @@
|
|||
use super::{Open, Sink};
|
||||
use super::{Open, Sink, SinkAsBytes};
|
||||
use crate::audio::AudioPacket;
|
||||
use crate::config::AudioFormat;
|
||||
use shell_words::split;
|
||||
use std::io::{self, Write};
|
||||
use std::mem;
|
||||
use std::process::{Child, Command, Stdio};
|
||||
use std::slice;
|
||||
|
||||
pub struct SubprocessSink {
|
||||
shell_command: String,
|
||||
child: Option<Child>,
|
||||
format: AudioFormat,
|
||||
}
|
||||
|
||||
impl Open for SubprocessSink {
|
||||
fn open(shell_command: Option<String>) -> 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");
|
||||
|
@ -44,16 +47,15 @@ impl Sink for SubprocessSink {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
fn write(&mut self, packet: &AudioPacket) -> io::Result<()> {
|
||||
let data: &[u8] = unsafe {
|
||||
slice::from_raw_parts(
|
||||
packet.samples().as_ptr() as *const u8,
|
||||
packet.samples().len() * mem::size_of::<f32>(),
|
||||
)
|
||||
};
|
||||
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(())
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue