use crate::sample::SampleTransform;
use super::{
TrackResult,
MonoTrack,
};
use minimp3::Decoder;
use cpal::Sample;
use std::{
fs::File,
path::Path,
};
#[derive(Clone,Debug)]
struct Track<T:Clone+SampleTransform>{
data:Vec<T>,
channels:u16,
sample_rate:u32,
}
impl Track<i16>{
pub fn new<P:AsRef<Path>>(path:P)->TrackResult<Track<i16>>{
let mut data=Vec::new();
let file=match File::open(path){
Ok(file)=>file,
Err(e)=>return TrackResult::FileError(e),
};
let mut decoder=Decoder::new(file);
let (channels,sample_rate)=match decoder.next_frame(){
Ok(mut frame)=>{
data.append(&mut frame.data);
(
frame.channels,
frame.sample_rate as u32,
)
}
Err(_)=>return TrackResult::NoData
};
while let Ok(mut frame)=decoder.next_frame(){
data.append(&mut frame.data);
}
TrackResult::Ok(Self{
data,
channels:channels as u16,
sample_rate,
})
}
}
impl<T:Clone+SampleTransform> Track<T>{
pub fn raw(data:Vec<T>,channels:u16,sample_rate:u32)->Track<T>{
Self{
data,
channels,
sample_rate,
}
}
pub fn data(&self)->&Vec<T>{
&self.data
}
pub fn channels(&self)->u16{
self.channels
}
pub fn sample_rate(&self)->u32{
self.sample_rate
}
pub fn len(&self)->usize{
self.data.len()
}
pub fn to_mono_tracks(&self)->Vec<MonoTrack>{
let channels=self.channels as usize;
let len=self.len()/channels;
let mut tracks=Vec::with_capacity(channels);
for c in 0..channels{
let mut channel=Vec::with_capacity(len);
for &s in self.data()[c..].iter().step_by(channels){
channel.push(s.into_f32());
}
tracks.push(MonoTrack{
sample_rate:self.sample_rate,
data:channel,
})
}
tracks
}
}
impl Into<Track<u16>> for Track<i16>{
fn into(self)->Track<u16>{
let mut track=Vec::<u16>::with_capacity(self.len());
for sample in self.data.into_iter(){
let sample=Sample::to_u16(&sample);
track.push(sample);
}
Track::<u16>{
data:track,
channels:self.channels,
sample_rate:self.sample_rate,
}
}
}
impl Into<Track<f32>> for Track<i16>{
fn into(self)->Track<f32>{
let mut track=Vec::<f32>::with_capacity(self.len());
for sample in self.data.into_iter(){
let sample=Sample::to_f32(&sample);
track.push(sample);
}
Track::<f32>{
data:track,
channels:self.channels,
sample_rate:self.sample_rate,
}
}
}
#[derive(Debug,Clone)]
pub struct ChanneledTrack{
channels:Vec<Vec<f32>>,
output_channels:Vec<Vec<usize>>,
sample_rate:u32,
}
impl ChanneledTrack{
pub fn new<P:AsRef<Path>>(path:P)->TrackResult<ChanneledTrack>{
let track=match Track::new(path){
TrackResult::Ok(track)=>track,
TrackResult::NoData=>return TrackResult::NoData,
TrackResult::FileError(err)=>return TrackResult::FileError(err),
};
let monos=track.to_mono_tracks();
let sample_rate=track.sample_rate();
let channels_amount=track.channels() as usize;
let mut channels:Vec<Vec<f32>>=Vec::with_capacity(channels_amount);
let mut output_channels:Vec<Vec<usize>>=Vec::with_capacity(channels_amount);
for (c,mono) in monos.into_iter().enumerate(){
let output_channel=vec![c];
output_channels.push(output_channel);
channels.push(mono.data);
}
TrackResult::Ok(Self{
channels,
output_channels,
sample_rate
})
}
pub fn channels(&self)->usize{
self.channels.len()
}
pub fn sample_rate(&self)->u32{
self.sample_rate
}
pub fn get_channel(&self,index:usize)->Option<&Vec<f32>>{
self.channels.get(index)
}
pub fn get_mut_channel(&mut self,index:usize)->Option<&mut Vec<f32>>{
self.channels.get_mut(index)
}
pub fn into_iter(self)->std::iter::Zip<std::vec::IntoIter<Vec<f32>>,std::vec::IntoIter<Vec<usize>>>{
self.channels.into_iter().zip(self.output_channels.into_iter())
}
}