mirror of
https://github.com/RustAudio/rodio
synced 2025-03-04 15:07:18 +00:00
Fix Sink playback after stop (#464)
Addressing issues #462 and #315 and #171 Given how the sink's queue is drained on stop I made some modifications in sink.append(). I added a check to ensure the sink was flushed completely (not sure this is necessary? I think it is, to avoid race conditions) and to restart the sink on append (when stopped.) I added a test demonstrating correctness, as well as performing some trials on my own.
This commit is contained in:
parent
0c0e086b6a
commit
44b92d43e9
1 changed files with 37 additions and 0 deletions
37
src/sink.rs
37
src/sink.rs
|
@ -65,6 +65,14 @@ impl Sink {
|
|||
f32: FromSample<S::Item>,
|
||||
S::Item: Sample + Send,
|
||||
{
|
||||
// Wait for queue to flush then resume stopped playback
|
||||
if self.controls.stopped.load(Ordering::SeqCst) {
|
||||
if self.sound_count.load(Ordering::SeqCst) > 0 {
|
||||
self.sleep_until_end();
|
||||
}
|
||||
self.controls.stopped.store(false, Ordering::SeqCst);
|
||||
}
|
||||
|
||||
let controls = self.controls.clone();
|
||||
|
||||
let source = source
|
||||
|
@ -201,6 +209,7 @@ impl Drop for Sink {
|
|||
mod tests {
|
||||
use crate::buffer::SamplesBuffer;
|
||||
use crate::{Sink, Source};
|
||||
use std::sync::atomic::Ordering;
|
||||
|
||||
#[test]
|
||||
fn test_pause_and_stop() {
|
||||
|
@ -233,6 +242,34 @@ mod tests {
|
|||
assert_eq!(sink.empty(), true);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_stop_and_start() {
|
||||
let (sink, mut queue_rx) = Sink::new_idle();
|
||||
|
||||
let v = vec![10i16, -10, 20, -20, 30, -30];
|
||||
|
||||
sink.append(SamplesBuffer::new(1, 1, v.clone()));
|
||||
let mut src = SamplesBuffer::new(1, 1, v.clone()).convert_samples();
|
||||
|
||||
assert_eq!(queue_rx.next(), src.next());
|
||||
assert_eq!(queue_rx.next(), src.next());
|
||||
|
||||
sink.stop();
|
||||
|
||||
assert!(sink.controls.stopped.load(Ordering::SeqCst));
|
||||
assert_eq!(queue_rx.next(), Some(0.0));
|
||||
|
||||
src = SamplesBuffer::new(1, 1, v.clone()).convert_samples();
|
||||
sink.append(SamplesBuffer::new(1, 1, v));
|
||||
|
||||
assert!(!sink.controls.stopped.load(Ordering::SeqCst));
|
||||
// Flush silence
|
||||
let mut queue_rx = queue_rx.skip_while(|v| *v == 0.0);
|
||||
|
||||
assert_eq!(queue_rx.next(), src.next());
|
||||
assert_eq!(queue_rx.next(), src.next());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_volume() {
|
||||
let (sink, mut queue_rx) = Sink::new_idle();
|
||||
|
|
Loading…
Add table
Reference in a new issue