From 7490a0b59adcfb34c670d9b76e8b90184c02d422 Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Sun, 22 Mar 2026 21:59:07 +0100 Subject: [PATCH 1/2] fix: report exhaustion for Stoppable and Skippable --- CHANGELOG.md | 1 + src/queue.rs | 40 ++++++++++++++++++++++++++++++++++++++++ src/source/skippable.rs | 6 +++++- src/source/stoppable.rs | 6 +++++- 4 files changed, 51 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 34bb8750..a2ab0172 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -39,6 +39,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixed `Brownian` and `Red` noise generators to reset after seeking. - Fixed sources to correctly handle sample rate and channel count changes at span boundaries. - Fixed sources to detect parameter updates after mid-span seeks. +- Fixed `Stoppable` and `Skippable` not signaling exhaustion. ## Version [0.22.2] (2026-02-22) diff --git a/src/queue.rs b/src/queue.rs index 927ebeea..3dc5ee71 100644 --- a/src/queue.rs +++ b/src/queue.rs @@ -350,6 +350,46 @@ mod tests { assert_eq!(rx.next(), Some(-10.0)); } + #[test] + fn sample_rate_correct_after_stopped_source() { + let (tx, mut rx) = queue::queue(true); + + let mut stopped_source = + SamplesBuffer::new(nz!(1), nz!(48000), vec![0.0f32; 100]).stoppable(); + stopped_source.stop(); + + let new_source = SamplesBuffer::new(nz!(1), nz!(22050), vec![0.5f32; 100]); + assert_ne!(stopped_source.sample_rate(), new_source.sample_rate()); + let new_sample_rate = new_source.sample_rate(); + + // Pull one sample so keep-alive behavior is triggered. + tx.append(stopped_source); + let _ = rx.next(); + + tx.append(new_source); + assert_eq!(rx.sample_rate(), new_sample_rate); + } + + #[test] + fn sample_rate_correct_after_skipped_source() { + let (tx, mut rx) = queue::queue(true); + + let mut skipped_source = + SamplesBuffer::new(nz!(1), nz!(48000), vec![0.0f32; 100]).skippable(); + crate::source::Skippable::skip(&mut skipped_source); + + let new_source = SamplesBuffer::new(nz!(1), nz!(22050), vec![0.5f32; 100]); + assert_ne!(skipped_source.sample_rate(), new_source.sample_rate()); + let new_sample_rate = new_source.sample_rate(); + + // Pull one sample so keep-alive behavior is triggered. + tx.append(skipped_source); + let _ = rx.next(); + + tx.append(new_source); + assert_eq!(rx.sample_rate(), new_sample_rate); + } + #[test] fn append_updates_metadata() { for keep_alive in [false, true] { diff --git a/src/source/skippable.rs b/src/source/skippable.rs index 1ce33218..bfa97399 100644 --- a/src/source/skippable.rs +++ b/src/source/skippable.rs @@ -84,7 +84,11 @@ where { #[inline] fn current_span_len(&self) -> Option { - self.input.current_span_len() + if self.do_skip { + Some(0) + } else { + self.input.current_span_len() + } } #[inline] diff --git a/src/source/stoppable.rs b/src/source/stoppable.rs index 44f21940..f89e0017 100644 --- a/src/source/stoppable.rs +++ b/src/source/stoppable.rs @@ -74,7 +74,11 @@ where { #[inline] fn current_span_len(&self) -> Option { - self.input.current_span_len() + if self.stopped { + Some(0) + } else { + self.input.current_span_len() + } } #[inline] From 2da28291864320dffad7ecace34af9ac7bd1eb1a Mon Sep 17 00:00:00 2001 From: Roderick van Domburg Date: Sun, 22 Mar 2026 22:10:38 +0100 Subject: [PATCH 2/2] fix: pass CI with 64bit --- src/queue.rs | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/queue.rs b/src/queue.rs index 3dc5ee71..18ef70b1 100644 --- a/src/queue.rs +++ b/src/queue.rs @@ -354,11 +354,10 @@ mod tests { fn sample_rate_correct_after_stopped_source() { let (tx, mut rx) = queue::queue(true); - let mut stopped_source = - SamplesBuffer::new(nz!(1), nz!(48000), vec![0.0f32; 100]).stoppable(); + let mut stopped_source = SamplesBuffer::new(nz!(1), nz!(48000), vec![0.0; 100]).stoppable(); stopped_source.stop(); - let new_source = SamplesBuffer::new(nz!(1), nz!(22050), vec![0.5f32; 100]); + let new_source = SamplesBuffer::new(nz!(1), nz!(22050), vec![0.5; 100]); assert_ne!(stopped_source.sample_rate(), new_source.sample_rate()); let new_sample_rate = new_source.sample_rate(); @@ -374,11 +373,10 @@ mod tests { fn sample_rate_correct_after_skipped_source() { let (tx, mut rx) = queue::queue(true); - let mut skipped_source = - SamplesBuffer::new(nz!(1), nz!(48000), vec![0.0f32; 100]).skippable(); + let mut skipped_source = SamplesBuffer::new(nz!(1), nz!(48000), vec![0.0; 100]).skippable(); crate::source::Skippable::skip(&mut skipped_source); - let new_source = SamplesBuffer::new(nz!(1), nz!(22050), vec![0.5f32; 100]); + let new_source = SamplesBuffer::new(nz!(1), nz!(22050), vec![0.5; 100]); assert_ne!(skipped_source.sample_rate(), new_source.sample_rate()); let new_sample_rate = new_source.sample_rate();