use anyhow::{Context, Result};
use hound::WavReader;
use rubato::{FftFixedIn, Resampler};
pub fn read_audio_file_mono(audio_file_path: &str) -> Result<(Vec<f32>, u32)> {
let mut reader =
WavReader::open(audio_file_path).with_context(|| "Failed to open audio file")?;
let spec = reader.spec();
let sr = spec.sample_rate;
let channels = spec.channels as usize;
let bits_per_sample = spec.bits_per_sample;
if channels > 2 {
return Err(anyhow::anyhow!(
"Unsupported number of channels: {}. Only mono and stereo are supported.",
channels
));
}
let mut samples: Vec<f32> = Vec::new();
let max_value = 2_f64.powi(bits_per_sample as i32 - 1);
let mut acc = 0_i64;
reader
.samples::<i32>()
.map(|s| s.with_context(|| "Couldn't read samples"))
.collect::<Result<Vec<_>, _>>()?
.iter()
.enumerate()
.for_each(|(i, &sample)| {
if channels == 2 {
acc += sample as i64;
if i % 2 != 0 {
samples.push(acc as f32 / 2.0 / max_value as f32);
acc = 0_i64;
}
} else if channels == 1 {
samples.push(sample as f32 / max_value as f32);
}
});
Ok((samples, sr))
}
pub fn resample(samples: Vec<f32>, original_sr: u32, target_sr: u32) -> Result<Vec<f32>> {
let mut resampler = FftFixedIn::<f32>::new(
original_sr as usize,
target_sr as usize,
samples.len(), 1024,
1, )
.with_context(|| "Can't initiate resampler")?;
let mut resampled = resampler
.process(&[samples], None)
.with_context(|| "Can't resample file")?;
Ok(resampled.swap_remove(0))
}