Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions src/buffer.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl SamplesBuffer {
impl Source for SamplesBuffer {
#[inline]
fn current_span_len(&self) -> Option<usize> {
None
Some(self.data.len() - self.pos)
}

#[inline]
Expand Down Expand Up @@ -126,7 +126,7 @@ impl Iterator for SamplesBuffer {

#[inline]
fn size_hint(&self) -> (usize, Option<usize>) {
(self.data.len(), Some(self.data.len()))
(self.data.len() - self.pos, Some(self.data.len() - self.pos))
}
}

Expand Down
29 changes: 25 additions & 4 deletions src/queue.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,6 +113,8 @@ pub struct SourcesQueueOutput {
}

const THRESHOLD: usize = 512;
const SILENCE_SAMPLE_RATE: SampleRate = nz!(44100);
const SILENCE_CHANNELS: ChannelCount = nz!(1);

impl Source for SourcesQueueOutput {
#[inline]
Expand Down Expand Up @@ -154,12 +156,28 @@ impl Source for SourcesQueueOutput {

#[inline]
fn channels(&self) -> ChannelCount {
self.current.channels()
// current_span_len() should never return 0 unless the source is empty, so this is a cheeky hint
if self.current.current_span_len() != Some(0) {
self.current.channels()
} else if let Some((next, _)) = self.input.next_sounds.lock().unwrap().first() {
next.channels()
} else {
// If keep_alive_if_empty is true, then it'll be mono 44.1khz silence -- otherwise it doesn't matter what it is
SILENCE_CHANNELS
}
}

#[inline]
fn sample_rate(&self) -> SampleRate {
self.current.sample_rate()
// current_span_len() should never return 0 unless the source is empty, so this is a cheeky hint
if self.current.current_span_len() != Some(0) {
self.current.sample_rate()
} else if let Some((next, _)) = self.input.next_sounds.lock().unwrap().first() {
next.sample_rate()
} else {
// If keep_alive_if_empty is true, then it'll be mono 44.1khz silence -- otherwise it doesn't matter what it is
SILENCE_SAMPLE_RATE
}
}

#[inline]
Expand Down Expand Up @@ -221,7 +239,11 @@ impl SourcesQueueOutput {
let mut next = self.input.next_sounds.lock().unwrap();

if next.is_empty() {
let silence = Box::new(Zero::new_samples(nz!(1), nz!(44100), THRESHOLD)) as Box<_>;
let silence = Box::new(Zero::new_samples(
SILENCE_CHANNELS,
SILENCE_SAMPLE_RATE,
THRESHOLD,
)) as Box<_>;
if self.input.keep_alive_if_empty.load(Ordering::Acquire) {
// Play a short silence in order to avoid spinlocking.
(silence, None)
Expand All @@ -247,7 +269,6 @@ mod tests {
use crate::source::Source;

#[test]
#[ignore] // FIXME: samples rate and channel not updated immediately after transition
fn basic() {
let (tx, mut rx) = queue::queue(false);

Expand Down
16 changes: 10 additions & 6 deletions src/source/skip.rs
Original file line number Diff line number Diff line change
Expand Up @@ -39,18 +39,22 @@ where
return;
}

let ns_per_sample: u128 =
NS_PER_SECOND / input.sample_rate().get() as u128 / input.channels().get() as u128;
let sample_rate = input.sample_rate().get() as u128;
let channels = input.channels().get() as u128;

let samples_per_channel = duration.as_nanos() * sample_rate / NS_PER_SECOND;
let samples_to_skip: u128 = samples_per_channel * channels;

// Check if we need to skip only part of the current span.
if span_len as u128 * ns_per_sample > duration.as_nanos() {
skip_samples(input, (duration.as_nanos() / ns_per_sample) as usize);
if span_len as u128 > samples_to_skip {
skip_samples(input, samples_to_skip as usize);
return;
}

duration -= Duration::from_nanos(
(NS_PER_SECOND * span_len as u128 / channels / sample_rate) as u64,
);
skip_samples(input, span_len);

duration -= Duration::from_nanos((span_len * ns_per_sample as usize) as u64);
}
}

Expand Down