use std::io::Cursor; use std::time::Duration; use std::vec; use rodio::Source; pub struct TestSource { samples: vec::IntoIter, channels: u16, sample_rate: u32, total_duration: Duration, } impl Iterator for TestSource { type Item = T; fn next(&mut self) -> Option { self.samples.next() } } impl ExactSizeIterator for TestSource { fn len(&self) -> usize { self.samples.len() } } impl Source for TestSource { fn current_frame_len(&self) -> Option { None // forever } fn channels(&self) -> u16 { self.channels } fn sample_rate(&self) -> u32 { self.sample_rate } fn total_duration(&self) -> Option { Some(self.total_duration) } } impl TestSource { pub fn music_wav() -> Self { let data = include_bytes!("../assets/music.wav"); let cursor = Cursor::new(data); let duration = Duration::from_secs(10); let sound = rodio::Decoder::new(cursor) .expect("music.wav is correctly encoded & wav is supported") .take_duration(duration); TestSource { channels: sound.channels(), sample_rate: sound.sample_rate(), total_duration: duration, samples: sound.into_iter().collect::>().into_iter(), } } #[allow(unused, reason = "not everything from shared is used in all libs")] pub fn to_f32s(self) -> TestSource { let TestSource { samples, channels, sample_rate, total_duration, } = self; let samples = samples .map(|s| cpal::Sample::from_sample(s)) .collect::>() .into_iter(); TestSource { samples, channels, sample_rate, total_duration, } } }