mirror of
https://github.com/RustAudio/rodio
synced 2025-03-02 22:17:16 +00:00
Handle variable channels and sample rate
This commit is contained in:
parent
e1108abe71
commit
0e6d5a1da2
1 changed files with 43 additions and 8 deletions
|
@ -8,14 +8,22 @@ use super::SeekError;
|
||||||
pub fn trackable<I>(source: I) -> TrackPosition<I> {
|
pub fn trackable<I>(source: I) -> TrackPosition<I> {
|
||||||
TrackPosition {
|
TrackPosition {
|
||||||
input: source,
|
input: source,
|
||||||
samples_elapsed: 0,
|
samples_collected: 0,
|
||||||
|
offset_duration: 0.0,
|
||||||
|
current_frame_sample_rate: 0,
|
||||||
|
current_frame_channels: 0,
|
||||||
|
current_frame_len: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug)]
|
#[derive(Clone, Debug)]
|
||||||
pub struct TrackPosition<I> {
|
pub struct TrackPosition<I> {
|
||||||
input: I,
|
input: I,
|
||||||
samples_elapsed: usize,
|
samples_collected: usize,
|
||||||
|
offset_duration: f64,
|
||||||
|
current_frame_sample_rate: u32,
|
||||||
|
current_frame_channels: u16,
|
||||||
|
current_frame_len: Option<usize>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<I> TrackPosition<I> {
|
impl<I> TrackPosition<I> {
|
||||||
|
@ -43,10 +51,20 @@ where
|
||||||
I: Source,
|
I: Source,
|
||||||
I::Item: Sample,
|
I::Item: Sample,
|
||||||
{
|
{
|
||||||
/// Returns the inner source.
|
/// Returns the position of the source.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_pos(&self) -> f64 {
|
pub fn get_pos(&self) -> f64 {
|
||||||
self.samples_elapsed as f64 / self.input.sample_rate() as f64 / self.input.channels() as f64
|
self.samples_collected as f64
|
||||||
|
/ self.input.sample_rate() as f64
|
||||||
|
/ self.input.channels() as f64
|
||||||
|
+ self.offset_duration
|
||||||
|
}
|
||||||
|
|
||||||
|
#[inline]
|
||||||
|
fn set_current_frame(&mut self) {
|
||||||
|
self.current_frame_len = self.current_frame_len();
|
||||||
|
self.current_frame_sample_rate = self.sample_rate();
|
||||||
|
self.current_frame_channels = self.channels();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -59,9 +77,28 @@ where
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn next(&mut self) -> Option<I::Item> {
|
fn next(&mut self) -> Option<I::Item> {
|
||||||
|
// This should only be executed once at the first call to next.
|
||||||
|
if self.current_frame_len.is_none() {
|
||||||
|
self.set_current_frame();
|
||||||
|
}
|
||||||
|
|
||||||
let item = self.input.next();
|
let item = self.input.next();
|
||||||
if item.is_some() {
|
if item.is_some() {
|
||||||
self.samples_elapsed += 1;
|
self.samples_collected += 1;
|
||||||
|
|
||||||
|
// At the end of a frame add the duration of this frame to
|
||||||
|
// offset_duration and start collecting samples again.
|
||||||
|
if let Some(frame_len) = self.current_frame_len() {
|
||||||
|
if self.samples_collected == frame_len {
|
||||||
|
self.offset_duration += self.samples_collected as f64
|
||||||
|
/ self.current_frame_sample_rate as f64
|
||||||
|
/ self.current_frame_channels as f64;
|
||||||
|
|
||||||
|
// Reset.
|
||||||
|
self.samples_collected = 0;
|
||||||
|
self.set_current_frame();
|
||||||
|
};
|
||||||
|
};
|
||||||
};
|
};
|
||||||
item
|
item
|
||||||
}
|
}
|
||||||
|
@ -101,9 +138,7 @@ where
|
||||||
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
|
fn try_seek(&mut self, pos: Duration) -> Result<(), SeekError> {
|
||||||
let result = self.input.try_seek(pos);
|
let result = self.input.try_seek(pos);
|
||||||
if result.is_ok() {
|
if result.is_ok() {
|
||||||
self.samples_elapsed = (pos.as_secs_f64()
|
self.offset_duration = pos.as_secs_f64();
|
||||||
* self.input.sample_rate() as f64
|
|
||||||
* self.input.channels() as f64) as usize;
|
|
||||||
}
|
}
|
||||||
result
|
result
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Reference in a new issue