aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorsalmonik <raisersoft@proton.me>2026-05-09 17:14:39 +0200
committersalmonik <raisersoft@proton.me>2026-05-09 17:14:39 +0200
commit898ebd930e0c5bb8b3f092d4c462bc38130adccf (patch)
treeba5c53dfcd11af604ccad47e5166753acd4d72c5 /src
parentMajor rewrite: play command, queue display, and shuffle modes (diff)
downloadrsplayer-898ebd930e0c5bb8b3f092d4c462bc38130adccf.tar.gz
rsplayer-898ebd930e0c5bb8b3f092d4c462bc38130adccf.zip
Fix buffer underrun - pre-decode samples before playback
Diffstat (limited to '')
-rw-r--r--src/audio.rs31
-rw-r--r--src/daemon.rs9
2 files changed, 35 insertions, 5 deletions
diff --git a/src/audio.rs b/src/audio.rs
index 7218f84..386c041 100644
--- a/src/audio.rs
+++ b/src/audio.rs
@@ -197,6 +197,37 @@ fn audio_thread(
197 Some(device_sample_rate as f64 / data.sample_rate as f64); 197 Some(device_sample_rate as f64 / data.sample_rate as f64);
198 } 198 }
199 199
200 // Pre-decode some samples before starting playback to prevent buffer underrun
201 let channels = data.channels as usize;
202 for _ in 0..50 {
203 match data.format.next_packet() {
204 Ok(packet) => {
205 match data.decoder.decode(&packet) {
206 Ok(decoded) => {
207 let spec = *decoded.spec();
208 let mut sample_buf =
209 symphonia::core::audio::SampleBuffer::<f32>::new(
210 decoded.capacity() as u64, spec
211 );
212 sample_buf.copy_interleaved_ref(decoded);
213 let samples = sample_buf.samples();
214
215 let resampled = if let Some(ratio) = data.resample_ratio {
216 resample_linear(samples, ratio, channels)
217 } else {
218 samples.to_vec()
219 };
220
221 data.sample_buffer.extend(resampled);
222 }
223 Err(_) => break,
224 }
225 }
226 Err(_) => break,
227 }
228 }
229 data.buffer_pos = 0;
230
200 let stream_config: cpal::StreamConfig = 231 let stream_config: cpal::StreamConfig =
201 device.default_output_config().unwrap().into(); 232 device.default_output_config().unwrap().into();
202 233
diff --git a/src/daemon.rs b/src/daemon.rs
index f4a72b7..7488fc2 100644
--- a/src/daemon.rs
+++ b/src/daemon.rs
@@ -400,8 +400,9 @@ fn process_command(
400 } 400 }
401 _ => { 401 _ => {
402 let was_empty = q.is_empty(); 402 let was_empty = q.is_empty();
403 let was_playing = audio.is_playing();
403 q.add_track(path.clone()); 404 q.add_track(path.clone());
404 if was_empty && audio.is_playing() { 405 if was_empty && !was_playing {
405 let track = Track::from_path(path.clone()); 406 let track = Track::from_path(path.clone());
406 audio.play(path); 407 audio.play(path);
407 notification::notify_track(&track); 408 notification::notify_track(&track);
@@ -449,13 +450,11 @@ fn process_command(
449 ) 450 )
450 } 451 }
451 _ => { 452 _ => {
453 let was_playing = audio.is_playing();
452 for file in &files { 454 for file in &files {
453 q.add_track(file.clone()); 455 q.add_track(file.clone());
454 } 456 }
455 if was_empty 457 if was_empty && !was_playing && let Some(track) = q.current() {
456 && audio.is_playing()
457 && let Some(track) = q.current()
458 {
459 audio.play(track.path.clone()); 458 audio.play(track.path.clone());
460 notification::notify_track(track); 459 notification::notify_track(track);
461 } 460 }