diff --git a/playback/src/lib.rs b/playback/src/lib.rs index d6b7ea3f..e56b2cae 100644 --- a/playback/src/lib.rs +++ b/playback/src/lib.rs @@ -14,6 +14,7 @@ pub mod mixer; pub mod normaliser; pub mod player; pub mod resampler; +pub mod sample_pipeline; pub const DB_VOLTAGE_RATIO: f64 = 20.0; pub const PCM_AT_0DBFS: f64 = 1.0; diff --git a/playback/src/sample_pipeline.rs b/playback/src/sample_pipeline.rs new file mode 100644 index 00000000..4be796ce --- /dev/null +++ b/playback/src/sample_pipeline.rs @@ -0,0 +1,78 @@ +use crate::{ + audio_backend::{Sink, SinkResult}, + config::PlayerConfig, + convert::Converter, + decoder::AudioPacket, + mixer::VolumeGetter, + normaliser::Normaliser, + player::NormalisationData, + resampler::StereoInterleavedResampler, +}; + +pub struct SamplePipeline { + resampler: StereoInterleavedResampler, + normaliser: Normaliser, + converter: Converter, + sink: Box, +} + +impl SamplePipeline { + pub fn new( + config: &PlayerConfig, + sink: Box, + volume_getter: Box, + ) -> Self { + let resampler = + StereoInterleavedResampler::new(config.sample_rate, config.interpolation_quality); + + let normaliser = Normaliser::new(config, volume_getter); + let converter = Converter::new(config.ditherer); + + Self { + resampler, + normaliser, + converter, + sink, + } + } + + pub fn get_latency_pcm(&mut self) -> u64 { + self.sink.get_latency_pcm() + self.resampler.get_latency_pcm() + } + + pub fn start(&mut self) -> SinkResult<()> { + self.sink.start()?; + + Ok(()) + } + + pub fn stop(&mut self) -> SinkResult<()> { + self.resampler.stop(); + self.normaliser.stop(); + self.sink.stop()?; + + Ok(()) + } + + pub fn set_normalisation_factor( + &mut self, + auto_normalise_as_album: bool, + data: NormalisationData, + ) { + self.normaliser.set_factor(auto_normalise_as_album, data); + } + + pub fn write(&mut self, packet: AudioPacket) -> SinkResult<()> { + if let AudioPacket::Samples(samples) = packet { + self.resampler + .process(&samples) + .map(|processed_samples| self.normaliser.normalise(&processed_samples)) + .map(|new_packet| self.sink.write(new_packet, &mut self.converter)) + .transpose()?; + } else { + self.sink.write(packet, &mut self.converter)?; + } + + Ok(()) + } +}