From 78bc621ebba467208358519f58e8bab7d9eafec8 Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Mon, 5 Apr 2021 21:30:40 +0200 Subject: [PATCH] Move SamplesConverter into convert.rs --- audio/src/convert.rs | 50 ++++++++++++++++++++++++++++++++++++++++++ audio/src/lib.rs | 52 ++------------------------------------------ 2 files changed, 52 insertions(+), 50 deletions(-) create mode 100644 audio/src/convert.rs diff --git a/audio/src/convert.rs b/audio/src/convert.rs new file mode 100644 index 0000000..74a4d8f --- /dev/null +++ b/audio/src/convert.rs @@ -0,0 +1,50 @@ +use zerocopy::AsBytes; + +#[derive(AsBytes, Copy, Clone, Debug)] +#[allow(non_camel_case_types)] +#[repr(transparent)] +pub struct i24([u8; 3]); +impl i24 { + fn pcm_from_i32(sample: i32) -> Self { + // drop the least significant byte + let [a, b, c, _d] = (sample >> 8).to_le_bytes(); + i24([a, b, c]) + } +} + +// Losslessly represent [-1.0, 1.0] to [$type::MIN, $type::MAX] while maintaining DC linearity. +macro_rules! convert_samples_to { + ($type: ident, $samples: expr) => { + convert_samples_to!($type, $samples, 0) + }; + ($type: ident, $samples: expr, $drop_bits: expr) => { + $samples + .iter() + .map(|sample| { + (*sample as f64 * (std::$type::MAX as f64 + 0.5) - 0.5) as $type >> $drop_bits + }) + .collect() + }; +} + +pub struct SamplesConverter {} +impl SamplesConverter { + pub fn to_s32(samples: &[f32]) -> Vec { + convert_samples_to!(i32, samples) + } + + pub fn to_s24(samples: &[f32]) -> Vec { + convert_samples_to!(i32, samples, 8) + } + + pub fn to_s24_3(samples: &[f32]) -> Vec { + Self::to_s32(samples) + .iter() + .map(|sample| i24::pcm_from_i32(*sample)) + .collect() + } + + pub fn to_s16(samples: &[f32]) -> Vec { + convert_samples_to!(i16, samples) + } +} diff --git a/audio/src/lib.rs b/audio/src/lib.rs index fe3b5c9..44f732b 100644 --- a/audio/src/lib.rs +++ b/audio/src/lib.rs @@ -13,6 +13,7 @@ extern crate tempfile; extern crate librespot_core; +mod convert; mod decrypt; mod fetch; @@ -24,6 +25,7 @@ mod passthrough_decoder; mod range_set; +pub use convert::{i24, SamplesConverter}; pub use decrypt::AudioDecrypt; pub use fetch::{AudioFile, AudioFileOpen, StreamLoaderController}; pub use fetch::{ @@ -31,7 +33,6 @@ pub use fetch::{ READ_AHEAD_DURING_PLAYBACK_ROUNDTRIPS, READ_AHEAD_DURING_PLAYBACK_SECONDS, }; use std::fmt; -use zerocopy::AsBytes; pub enum AudioPacket { Samples(Vec), @@ -61,55 +62,6 @@ impl AudioPacket { } } -#[derive(AsBytes, Copy, Clone, Debug)] -#[allow(non_camel_case_types)] -#[repr(transparent)] -pub struct i24([u8; 3]); -impl i24 { - fn pcm_from_i32(sample: i32) -> Self { - // drop the least significant byte - let [a, b, c, _d] = (sample >> 8).to_le_bytes(); - i24([a, b, c]) - } -} - -// Losslessly represent [-1.0, 1.0] to [$type::MIN, $type::MAX] while maintaining DC linearity. -macro_rules! convert_samples_to { - ($type: ident, $samples: expr) => { - convert_samples_to!($type, $samples, 0) - }; - ($type: ident, $samples: expr, $drop_bits: expr) => { - $samples - .iter() - .map(|sample| { - (*sample as f64 * (std::$type::MAX as f64 + 0.5) - 0.5) as $type >> $drop_bits - }) - .collect() - }; -} - -pub struct SamplesConverter {} -impl SamplesConverter { - pub fn to_s32(samples: &[f32]) -> Vec { - convert_samples_to!(i32, samples) - } - - pub fn to_s24(samples: &[f32]) -> Vec { - convert_samples_to!(i32, samples, 8) - } - - pub fn to_s24_3(samples: &[f32]) -> Vec { - Self::to_s32(samples) - .iter() - .map(|sample| i24::pcm_from_i32(*sample)) - .collect() - } - - pub fn to_s16(samples: &[f32]) -> Vec { - convert_samples_to!(i16, samples) - } -} - #[cfg(not(any(feature = "with-tremor", feature = "with-vorbis")))] pub use crate::lewton_decoder::{VorbisDecoder, VorbisError}; #[cfg(any(feature = "with-tremor", feature = "with-vorbis"))]