I'm trying to create an iterator that wraps around the simplemad library so I can iterate over individual samples in an mp3 file, outputting them as f32 values rather than the fixed point format used by simplemad. Here is my code so far:
extern crate simplemad;
use std::fs::File;
use std::path::Path;
use std::fmt;
use std::option;
use std::vec::Vec;
struct SimplemadSampleIter<'a, R: 'a> where R: std::io::Read {
decoder: &'a mut simplemad::Decoder<R>,
currentFrame: Option<simplemad::Frame>,
endOfFile: bool,
currentFramePos: usize,
}
impl<'a, R: 'a> SimplemadSampleIter<'a, R> where R: std::io::Read {
fn new(decoder: &'a mut simplemad::Decoder<R>) -> SimplemadSampleIter<R> {
SimplemadSampleIter {decoder: decoder, currentFrame: None, endOfFile: false, currentFramePos: 0}
}
}
impl<'a, R: 'a> std::iter::Iterator for SimplemadSampleIter<'a, R> where R: std::io::Read {
type Item = Vec<f32>;
fn next(&mut self) -> Option<Vec<f32>> {
if self.endOfFile {
return None;
}
while self.currentFrame.is_none() || self.currentFramePos >= self.currentFrame.unwrap().samples.len() {
let result = self.decoder.get_frame();
match result {
Err(error) => {
match error {
simplemad::SimplemadError::EOF => {
self.endOfFile = true;
self.currentFrame = None;
break;
}
simplemad::SimplemadError::Read(Error) => {
self.endOfFile = true;
self.currentFrame = None;
break;
}
simplemad::SimplemadError::Mad(MadError) => {
self.currentFrame = None;
}
}
}
Ok(frame) => {
self.currentFrame = Some(frame);
}
}
}
if self.currentFrame.is_none() {
return None;
}
let sample = self.currentFrame.unwrap().samples[self.currentFramePos].into_iter().map(|sample: simplemad::MadFixed32| sample.to_f32()).collect::<Vec<f32>>();
self.currentFramePos += 1;
return Some(sample);
}
}
fn main() {
let path = Path::new("furioso_melodia.mp3");
let file = File::open(&path).unwrap();
let mut decoder = simplemad::Decoder::decode(file).unwrap();
let mut samples = SimplemadSampleIter::new(&mut decoder);
for i in 0..100 {
let sample = samples.next().unwrap();
println!("{}, {}, {}", i, sample[0], sample[1]);
}
}
However, I am having problems with the compiler telling me "cannot move out of borrowed/indexed context" at parts in the code:
src\main.rs:30:72: 30:76 error: cannot move out of borrowed content [E0507]
src\main.rs:30 while self.currentFrame.is_none() || self.currentFramePos >= { self.currentFrame.unwrap().samples.len() } {
^~~~
src\main.rs:58:22: 58:78 error: cannot move out of indexed content [E0507]
src\main.rs:58 let sample = self.currentFrame.unwrap().samples[self.currentFramePos].into_iter().map(|sample: simplemad::MadFixed32| sample.to_f32()).collect::<Vec<f32>>();
^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
src\main.rs:58:22: 58:26 error: cannot move out of borrowed content [E0507]
src\main.rs:58 let sample = self.currentFrame.unwrap().samples[self.currentFramePos].into_iter().map(|sample: simplemad::MadFixed32| sample.to_f32()).collect::<Vec<f32>>();
^~~~
I don't get what is wrong in the first error, as self.currentFrame.unwrap().samples.len() results in a usize value that is not even being bound to any variable name. I also don't understand the latter two errors.