|
|
|
@ -1,4 +1,84 @@
|
|
|
|
|
use minimp3::{Decoder, Frame}
|
|
|
|
|
use std::io::Read;
|
|
|
|
|
use minimp3::{ Decoder };
|
|
|
|
|
use rubato::{ SincFixedIn, SincInterpolationParameters, SincInterpolationType, Resampler, WindowFunction };
|
|
|
|
|
|
|
|
|
|
struct Track {
|
|
|
|
|
sample_rate: i32,
|
|
|
|
|
samples: Vec<i16>,
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
impl Track {
|
|
|
|
|
pub fn from_decoder<T: Read>(mut decoder: Decoder<T>, target_sample_rate: i32) -> Self {
|
|
|
|
|
let frames = {
|
|
|
|
|
let mut accumulator = vec![];
|
|
|
|
|
while let Ok(frame) = decoder.next_frame() {
|
|
|
|
|
accumulator.push(frame);
|
|
|
|
|
}
|
|
|
|
|
accumulator
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
let mut output_buffer = Vec::with_capacity(frames.len() * minimp3::MAX_SAMPLES_PER_FRAME);
|
|
|
|
|
let mut resampler = SincFixedIn::new(
|
|
|
|
|
target_sample_rate as f64 / frames[0].sample_rate as f64,
|
|
|
|
|
10.0,
|
|
|
|
|
SincInterpolationParameters {
|
|
|
|
|
sinc_len: 256,
|
|
|
|
|
f_cutoff: 0.95,
|
|
|
|
|
oversampling_factor: 128,
|
|
|
|
|
interpolation: SincInterpolationType::Linear,
|
|
|
|
|
window: WindowFunction::BlackmanHarris2,
|
|
|
|
|
},
|
|
|
|
|
1152,
|
|
|
|
|
2
|
|
|
|
|
).unwrap();
|
|
|
|
|
|
|
|
|
|
for frame in frames.iter() {
|
|
|
|
|
let mut deinterlaced_left = [0f32; 1152];
|
|
|
|
|
let mut deinterlaced_right = [0f32; 1152];
|
|
|
|
|
match frame.channels {
|
|
|
|
|
1 => {
|
|
|
|
|
frame.data.iter()
|
|
|
|
|
.map(|&sample| sample as f32)
|
|
|
|
|
.enumerate()
|
|
|
|
|
.for_each(|(i, sample)| deinterlaced_left[i] = sample);
|
|
|
|
|
deinterlaced_right.copy_from_slice(&deinterlaced_left);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
2 => {
|
|
|
|
|
// if not fast enough, try the unsafe as_mut_ptr shit
|
|
|
|
|
// edit: unsafe stuff probably wont help actually bc iteration would have to
|
|
|
|
|
// happen anyway and also we still have to convert i32 to f32
|
|
|
|
|
let (d_left_vec, d_right_vec): (Vec<f32>, Vec<f32>)
|
|
|
|
|
= frame.data.as_slice()
|
|
|
|
|
.chunks(2)
|
|
|
|
|
.map(|c| (c[0] as f32, c[1] as f32))
|
|
|
|
|
.unzip();
|
|
|
|
|
|
|
|
|
|
deinterlaced_left[0..d_left_vec.len()]
|
|
|
|
|
.copy_from_slice(&d_left_vec);
|
|
|
|
|
deinterlaced_right[0..d_right_vec.len()]
|
|
|
|
|
.copy_from_slice(&d_right_vec);
|
|
|
|
|
},
|
|
|
|
|
|
|
|
|
|
_ => panic!("frame {} had {} channels, should only have 1 or 2", frames.len(), frame.channels)
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let mut frame_resampled = resampler
|
|
|
|
|
.process(&[deinterlaced_left, deinterlaced_right], None)
|
|
|
|
|
.unwrap();
|
|
|
|
|
let frame_resampled_right = frame_resampled.pop().unwrap();
|
|
|
|
|
let frame_resampled_left = frame_resampled.pop().unwrap();
|
|
|
|
|
|
|
|
|
|
let frame_resampled_interlaced = frame_resampled_left
|
|
|
|
|
.into_iter()
|
|
|
|
|
.zip(frame_resampled_right.into_iter())
|
|
|
|
|
.flat_map(|(l, r)| [l, r]);
|
|
|
|
|
|
|
|
|
|
output_buffer.extend(frame_resampled_interlaced);
|
|
|
|
|
}
|
|
|
|
|
todo!()
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
|
mod tests {
|
|
|
|
|