mirror of
https://github.com/librespot-org/librespot.git
synced 2024-12-18 17:11:53 +00:00
Fix output on big-endian systems (#778)
This commit is contained in:
parent
fe2d5ca7c6
commit
bae1834988
5 changed files with 25 additions and 10 deletions
|
@ -36,8 +36,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
|
||||||
- [connect] Fix step size on volume up/down events
|
- [connect] Fix step size on volume up/down events
|
||||||
- [playback] Incorrect `PlayerConfig::default().normalisation_threshold` caused distortion when using dynamic volume normalisation downstream
|
- [playback] Incorrect `PlayerConfig::default().normalisation_threshold` caused distortion when using dynamic volume normalisation downstream
|
||||||
- [playback] Fix `log` and `cubic` volume controls to be mute at zero volume
|
- [playback] Fix `log` and `cubic` volume controls to be mute at zero volume
|
||||||
|
- [playback] Fix `S24_3` format on big-endian systems
|
||||||
- [playback] `alsamixer`: make `cubic` consistent between cards that report minimum volume as mute, and cards that report some dB value
|
- [playback] `alsamixer`: make `cubic` consistent between cards that report minimum volume as mute, and cards that report some dB value
|
||||||
- [playback] `alsamixer`: make `--volume-ctrl {linear|log}` work as expected
|
- [playback] `alsamixer`: make `--volume-ctrl {linear|log}` work as expected
|
||||||
|
- [playback] `alsa`, `gstreamer`, `pulseaudio`: always output in native endianness
|
||||||
|
|
||||||
## [0.2.0] - 2021-05-04
|
## [0.2.0] - 2021-05-04
|
||||||
|
|
||||||
|
|
|
@ -45,8 +45,12 @@ fn open_device(dev_name: &str, format: AudioFormat) -> Result<(PCM, Frames), Box
|
||||||
AudioFormat::F32 => Format::float(),
|
AudioFormat::F32 => Format::float(),
|
||||||
AudioFormat::S32 => Format::s32(),
|
AudioFormat::S32 => Format::s32(),
|
||||||
AudioFormat::S24 => Format::s24(),
|
AudioFormat::S24 => Format::s24(),
|
||||||
AudioFormat::S24_3 => Format::S243LE,
|
|
||||||
AudioFormat::S16 => Format::s16(),
|
AudioFormat::S16 => Format::s16(),
|
||||||
|
|
||||||
|
#[cfg(target_endian = "little")]
|
||||||
|
AudioFormat::S24_3 => Format::S243LE,
|
||||||
|
#[cfg(target_endian = "big")]
|
||||||
|
AudioFormat::S24_3 => Format::S243BE,
|
||||||
};
|
};
|
||||||
|
|
||||||
// http://www.linuxjournal.com/article/6735?page=0,1#N0x19ab2890.0x19ba78d8
|
// http://www.linuxjournal.com/article/6735?page=0,1#N0x19ab2890.0x19ba78d8
|
||||||
|
|
|
@ -34,9 +34,14 @@ impl Open for GstreamerSink {
|
||||||
let sample_size = format.size();
|
let sample_size = format.size();
|
||||||
let gst_bytes = 2048 * sample_size;
|
let gst_bytes = 2048 * sample_size;
|
||||||
|
|
||||||
|
#[cfg(target_endian = "little")]
|
||||||
|
const ENDIANNESS: &str = "LE";
|
||||||
|
#[cfg(target_endian = "big")]
|
||||||
|
const ENDIANNESS: &str = "BE";
|
||||||
|
|
||||||
let pipeline_str_preamble = format!(
|
let pipeline_str_preamble = format!(
|
||||||
"appsrc caps=\"audio/x-raw,format={}LE,layout=interleaved,channels={},rate={}\" block=true max-bytes={} name=appsrc0 ",
|
"appsrc caps=\"audio/x-raw,format={}{},layout=interleaved,channels={},rate={}\" block=true max-bytes={} name=appsrc0 ",
|
||||||
gst_format, NUM_CHANNELS, SAMPLE_RATE, gst_bytes
|
gst_format, ENDIANNESS, NUM_CHANNELS, SAMPLE_RATE, gst_bytes
|
||||||
);
|
);
|
||||||
// no need to dither twice; use librespot dithering instead
|
// no need to dither twice; use librespot dithering instead
|
||||||
let pipeline_str_rest = r#" ! audioconvert dithering=none ! autoaudiosink"#;
|
let pipeline_str_rest = r#" ! audioconvert dithering=none ! autoaudiosink"#;
|
||||||
|
|
|
@ -23,11 +23,11 @@ impl Open for PulseAudioSink {
|
||||||
|
|
||||||
// PulseAudio calls S24 and S24_3 different from the rest of the world
|
// PulseAudio calls S24 and S24_3 different from the rest of the world
|
||||||
let pulse_format = match format {
|
let pulse_format = match format {
|
||||||
AudioFormat::F32 => pulse::sample::Format::F32le,
|
AudioFormat::F32 => pulse::sample::Format::FLOAT32NE,
|
||||||
AudioFormat::S32 => pulse::sample::Format::S32le,
|
AudioFormat::S32 => pulse::sample::Format::S32NE,
|
||||||
AudioFormat::S24 => pulse::sample::Format::S24_32le,
|
AudioFormat::S24 => pulse::sample::Format::S24_32NE,
|
||||||
AudioFormat::S24_3 => pulse::sample::Format::S24le,
|
AudioFormat::S24_3 => pulse::sample::Format::S24NE,
|
||||||
AudioFormat::S16 => pulse::sample::Format::S16le,
|
AudioFormat::S16 => pulse::sample::Format::S16NE,
|
||||||
_ => {
|
_ => {
|
||||||
unimplemented!("PulseAudio currently does not support {:?} output", format)
|
unimplemented!("PulseAudio currently does not support {:?} output", format)
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,8 +8,12 @@ pub struct i24([u8; 3]);
|
||||||
impl i24 {
|
impl i24 {
|
||||||
fn from_s24(sample: i32) -> Self {
|
fn from_s24(sample: i32) -> Self {
|
||||||
// trim the padding in the most significant byte
|
// trim the padding in the most significant byte
|
||||||
let [a, b, c, _d] = sample.to_le_bytes();
|
#[allow(unused_variables)]
|
||||||
i24([a, b, c])
|
let [a, b, c, d] = sample.to_ne_bytes();
|
||||||
|
#[cfg(target_endian = "little")]
|
||||||
|
return Self([a, b, c]);
|
||||||
|
#[cfg(target_endian = "big")]
|
||||||
|
return Self([b, c, d]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue