Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implement an owning stream iterator #10

Closed
wants to merge 1 commit into from
Closed
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
54 changes: 44 additions & 10 deletions src/stream.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ use utility::{
many_metadata,
};

use std::marker;
use std::io;
use std::usize;
use std::fs::File;
Expand Down Expand Up @@ -113,7 +114,7 @@ impl<P> Stream<P> where P: StreamProducer {

/// Returns an iterator over the decoded samples.
#[inline]
pub fn iter<S: SampleSize>(&mut self) -> Iter<P, S::Extended> {
pub fn iter<S: SampleSize>(&mut self) -> Iter<P, S::Extended, &mut Self> {
let samples_left = self.info.total_samples;
let channels = self.info.channels as usize;
let block_size = self.info.max_block_size as usize;
Expand All @@ -125,7 +126,27 @@ impl<P> Stream<P> where P: StreamProducer {
block_size: 0,
sample_index: 0,
samples_left: samples_left,
buffer: vec![S::Extended::from_i8(0); buffer_size]
buffer: vec![S::Extended::from_i8(0); buffer_size],
ph: marker::PhantomData,
}
}

/// Takes ownership of the stream and returns an iterator over the decoded samples.
#[inline]
pub fn into_iter<S: SampleSize>(self) -> Iter<P, S::Extended, Self> {
let samples_left = self.info.total_samples;
let channels = self.info.channels as usize;
let block_size = self.info.max_block_size as usize;
let buffer_size = block_size * channels;

Iter {
stream: self,
channel: 0,
block_size: 0,
sample_index: 0,
samples_left: samples_left,
buffer: vec![S::Extended::from_i8(0); buffer_size],
ph: marker::PhantomData,
}
}

Expand Down Expand Up @@ -160,35 +181,38 @@ impl<P> Stream<P> where P: StreamProducer {
}

/// An iterator over a reference of the decoded FLAC stream.
pub struct Iter<'a, P, S>
where P: 'a + StreamProducer,
S: Sample{
stream: &'a mut Stream<P>,
pub struct Iter<P, S, T>
where P: StreamProducer,
S: Sample,
T: AsRef<Stream<P>> + AsMut<Stream<P>> {
stream: T,
channel: usize,
block_size: usize,
sample_index: usize,
samples_left: u64,
buffer: Vec<S>,
ph: marker::PhantomData<P>,
}

impl<'a, P, S> Iterator for Iter<'a, P, S>
impl<P, S, T> Iterator for Iter<P, S, T>
where P: StreamProducer,
S: Sample {
S: Sample,
T: AsRef<Stream<P>> + AsMut<Stream<P>> {
type Item = S::Normal;

fn next(&mut self) -> Option<Self::Item> {
if self.sample_index == self.block_size {
let buffer = &mut self.buffer;

if let Some(block_size) = self.stream.next_frame(buffer) {
if let Some(block_size) = self.stream.as_mut().next_frame(buffer) {
self.sample_index = 0;
self.block_size = block_size;
} else {
return None;
}
}

let channels = self.stream.info.channels as usize;
let channels = self.stream.as_ref().info.channels as usize;
let index = self.sample_index + (self.channel * self.block_size);
let sample = unsafe { *self.buffer.get_unchecked(index) };

Expand Down Expand Up @@ -218,6 +242,16 @@ impl<'a, P, S> Iterator for Iter<'a, P, S>
}
}

impl<P> AsRef<Stream<P>> for Stream<P>
where P: StreamProducer {
fn as_ref(&self) -> &Stream<P> { &self }
}

impl<P> AsMut<Stream<P>> for Stream<P>
where P: StreamProducer {
fn as_mut(&mut self) -> &mut Stream<P> { self }
}

//impl<'a, P, S> IntoIterator for &'a mut Stream<P>
// where P: StreamProducer,
// S: Sample {
Expand Down