From 4f1abb65bbce23ffc14117e27afa7d92d960c9da Mon Sep 17 00:00:00 2001 From: Fabian Lippold Date: Thu, 16 Nov 2023 22:33:36 +0100 Subject: [PATCH] fix audio decoding --- src/player/loader.rs | 14 +++++++++++++ src/player/mod.rs | 50 +++++++++++++++++++------------------------- 2 files changed, 35 insertions(+), 29 deletions(-) diff --git a/src/player/loader.rs b/src/player/loader.rs index 8d99bd4..9d9bd6f 100644 --- a/src/player/loader.rs +++ b/src/player/loader.rs @@ -1,5 +1,6 @@ use anyhow::Context; +use log::{debug, trace}; use symphonia::core::{ audio::{SampleBuffer, SignalSpec}, codecs::{DecoderOptions, CODEC_TYPE_NULL}, @@ -48,6 +49,7 @@ impl LoadedSong { .ok_or(anyhow::anyhow!("No audio tracks found"))?; let codec_params = track.codec_params.clone(); + debug!("Codec params: {:?}", codec_params); let track_id = track.id; let mut decoder = symphonia::default::get_codecs() @@ -61,6 +63,7 @@ impl LoadedSong { .channels .ok_or(anyhow::anyhow!("No channels"))?, ); + debug!("Signal spec: {:?}", signal_spec); let signal_spec2 = signal_spec.clone(); let decoder = move || match format_reader.next_packet() { @@ -76,8 +79,19 @@ impl LoadedSong { let mut sample_buffer = SampleBuffer::new(data.capacity() as u64, signal_spec2); sample_buffer.copy_interleaved_ref(data); + trace!( + "Decoded packet for track {} ({} bytes)", + packet.track_id(), + packet.data.len() + ); + Ok((Some(sample_buffer), false)) } else { + trace!( + "Skipping packet for track {} ({} bytes)", + packet.track_id(), + packet.data.len() + ); Ok((None, false)) } } diff --git a/src/player/mod.rs b/src/player/mod.rs index 314d811..09b0d8b 100644 --- a/src/player/mod.rs +++ b/src/player/mod.rs @@ -7,7 +7,7 @@ use cpal::{ traits::{DeviceTrait, HostTrait}, Stream, StreamConfig, }; -use log::warn; +use log::{debug, warn}; use souvlaki::{MediaControls, MediaMetadata, MediaPlayback, MediaPosition, PlatformConfig}; use std::{ collections::VecDeque, @@ -172,6 +172,7 @@ impl Player { sample_rate: cpal::SampleRate(song.signal_spec.rate), buffer_size: cpal::BufferSize::Default, }; + debug!("Stream config: {:?}", config); let mut buffer = VecDeque::::new(); @@ -196,39 +197,30 @@ impl Player { let mut duration = playing_duration2.write().unwrap(); - let mut n = buffer.len().min(dest.len()); - buffer.drain(0..n).enumerate().for_each(|(i, s)| { - dest[i] = s * gain_factor; - }); - - *duration += Duration::from_secs_f64( - n as f64 - / song.signal_spec.rate as f64 - / song.signal_spec.channels.count() as f64, - ); - - let (samples, eof) = (song.decoder)().expect("Failed to decode packet"); + let mut byte_count = 0; + while byte_count < dest.len() { + if buffer.len() < dest.len() { + let (sample_buffer, end_of_stream) = (song.decoder)().unwrap(); + if let Some(sample_buffer) = sample_buffer { + buffer.extend(sample_buffer.samples()); + } - if let Some(samples) = samples { - buffer.extend(samples.samples()); + if end_of_stream { + command_tx.send(Command::Skip).unwrap(); + } + } - if n < dest.len() { - n = buffer.len().min(dest.len() - n); - buffer.drain(0..n).enumerate().for_each(|(i, s)| { - dest[i] = s * gain_factor; + buffer + .drain(..(dest.len() - byte_count).min(buffer.len())) + .for_each(|sample| { + dest[byte_count] = sample * gain_factor; + byte_count += 1; }); - - *duration += Duration::from_secs_f64( - n as f64 - / song.signal_spec.rate as f64 - / song.signal_spec.channels.count() as f64, - ); - } } - if eof && buffer.is_empty() { - command_tx.send(Command::Skip).unwrap(); - } + *duration += Duration::from_secs_f64( + dest.len() as f64 / config.channels as f64 / config.sample_rate.0 as f64, + ); }, |e| { warn!("Error in playback stream: {:?}", e);