use crate::*; impl Sample { /// Read WAV from file pub fn read_data (src: &str) -> Usually<(usize, Vec>)> { let mut channels: Vec> = vec![]; for channel in wavers::Wav::from_path(src)?.channels() { channels.push(channel); } let mut end = 0; let mut data: Vec> = vec![]; for samples in channels.iter() { let channel = Vec::from(samples.as_ref()); end = end.max(channel.len()); data.push(channel); } Ok((end, data)) } pub fn from_file (path: &PathBuf) -> Usually { let name = path.file_name().unwrap().to_string_lossy().into(); let mut sample = Self { name, ..Default::default() }; // Use file extension if present let mut hint = Hint::new(); if let Some(ext) = path.extension() { hint.with_extension(&ext.to_string_lossy()); } let probed = symphonia::default::get_probe().format( &hint, MediaSourceStream::new( Box::new(File::open(path)?), Default::default(), ), &Default::default(), &Default::default() )?; let mut format = probed.format; let params = &format.tracks().iter() .find(|t| t.codec_params.codec != CODEC_TYPE_NULL) .expect("no tracks found") .codec_params; let mut decoder = get_codecs().make(params, &Default::default())?; loop { match format.next_packet() { Ok(packet) => sample.decode_packet(&mut decoder, packet)?, Err(symphonia::core::errors::Error::IoError(_)) => break decoder.last_decoded(), Err(err) => return Err(err.into()), }; }; sample.end = sample.channels.iter().fold(0, |l, c|l + c.len()); Ok(sample) } fn decode_packet ( &mut self, decoder: &mut Box, packet: Packet ) -> Usually<()> { // Decode a packet let decoded = decoder .decode(&packet) .map_err(|e|Box::::from(e))?; // Determine sample rate let spec = *decoded.spec(); if let Some(rate) = self.rate { if rate != spec.rate as usize { panic!("sample rate changed"); } } else { self.rate = Some(spec.rate as usize); } // Determine channel count while self.channels.len() < spec.channels.count() { self.channels.push(vec![]); } // Load sample let mut samples = SampleBuffer::new( decoded.frames() as u64, spec ); if samples.capacity() > 0 { samples.copy_interleaved_ref(decoded); for frame in samples.samples().chunks(spec.channels.count()) { for (chan, frame) in frame.iter().enumerate() { self.channels[chan].push(*frame) } } } Ok(()) } }