#![allow(dead_code)]
use std::{any::TypeId, borrow::Cow, slice};
use resampler::Resampler;
use sampletypes::SampleType;
use downmixer::{Downmixer, DownmixerParams};
#[derive(Debug, Clone, PartialEq)]
pub enum AudioConvError {
InvalidArguments(String),
FrameChannelsNotSame,
ChannelsNotInSameSize,
TruncatedSamples,
}
pub fn stereos_to_dual_monos<S>(stereos: &[(S, S)]) -> (Vec<S>, Vec<S>)
where
S: SampleType,
{
let l = stereos.iter().map(|(l, _r): &(S, S)| -> S { *l }).collect();
let r = stereos.iter().map(|(_l, r): &(S, S)| -> S { *r }).collect();
(l, r)
}
pub fn is_same_len<S>(data: &[Vec<S>]) -> Option<(bool, usize)>
where
S: SampleType,
{
if data.is_empty() {
None
} else {
let lengths: Vec<usize> = data.iter().map(|item| item.len()).collect();
let first = lengths[0];
Some((lengths.iter().all(|&item| item == first), first))
}
}
pub fn frames_to_stereos<S>(channel_mask: u32, frames: &[Vec<S>]) -> Result<Vec<(S, S)>, AudioConvError>
where
S: SampleType,
{
match is_same_len(frames) {
None => Ok(Vec::<(S, S)>::new()),
Some((equal, _channels)) => match equal {
false => Err(AudioConvError::FrameChannelsNotSame),
true => {
let downmixer = Downmixer::new(channel_mask, DownmixerParams::default());
Ok(frames.iter().map(|frame: &Vec<S>| -> (S, S) {downmixer.downmix_frame_to_stereo(frame)}).collect())
}
},
}
}
pub fn frames_to_dual_mono<S>(channel_mask: u32, frames: &[Vec<S>]) -> Result<(Vec<S>, Vec<S>), AudioConvError>
where
S: SampleType,
{
Ok(stereos_to_dual_monos(&frames_to_stereos(channel_mask, frames)?))
}
pub fn frames_to_monos<S>(
frames: &[Vec<S>],
) -> Result<Vec<Vec<S>>, AudioConvError>
where
S: SampleType,
{
match is_same_len(frames) {
None => Ok(Vec::<Vec<S>>::new()),
Some((equal, length)) => match equal {
false => Err(AudioConvError::FrameChannelsNotSame),
true => Ok((0..length)
.map(|channel| -> Vec<S> {
frames
.iter()
.map(|frame: &Vec<S>| -> S { frame[channel] })
.collect()
})
.collect()),
},
}
}
pub fn monos_to_frames<S>(monos: &[Vec<S>]) -> Result<Vec<Vec<S>>, AudioConvError>
where
S: SampleType,
{
match is_same_len(monos) {
None => Ok(Vec::<Vec<S>>::new()),
Some((equal, length)) => match equal {
false => Err(AudioConvError::ChannelsNotInSameSize),
true => Ok((0..length)
.map(|position: usize| -> Vec<S> {
monos
.iter()
.map(|channel: &Vec<S>| -> S { channel[position] })
.collect()
})
.collect()),
},
}
}
pub fn monos_to_interleaved_samples<S>(monos: &[Vec<S>]) -> Result<Vec<S>, AudioConvError>
where
S: SampleType,
{
Ok(monos_to_frames(monos)?.into_iter().flatten().collect())
}
pub fn frames_to_interleaved_samples<S>(
frames: &[Vec<S>]
) -> Result<Vec<S>, AudioConvError>
where
S: SampleType,
{
monos_to_interleaved_samples(&frames_to_monos(frames)?)
}
pub fn interleaved_samples_to_frames<S>(
samples: &[S],
channels: u16,
) -> Result<Vec<Vec<S>>, AudioConvError>
where
S: SampleType,
{
monos_to_frames(&interleaved_samples_to_monos(samples, channels)?)
}
pub fn stereos_to_interleaved_samples<S>(stereos: &[(S, S)]) -> Vec<S>
where
S: SampleType,
{
stereos
.iter()
.flat_map(|(l, r): &(S, S)| -> [S; 2] { [*l, *r] })
.collect()
}
pub fn interleaved_samples_to_monos<S>(
samples: &[S],
channels: u16,
) -> Result<Vec<Vec<S>>, AudioConvError>
where
S: SampleType,
{
if channels == 0 {
Err(AudioConvError::InvalidArguments(
"Channels must not be zero".to_owned(),
))
} else {
Ok((0..channels)
.map(|channel| -> Vec<S> {
samples
.iter()
.skip(channel as usize)
.step_by(channels as usize)
.copied()
.collect()
})
.collect())
}
}
pub fn dual_monos_to_stereos<S>(
dual_monos: &(Vec<S>, Vec<S>),
) -> Result<Vec<(S, S)>, AudioConvError>
where
S: SampleType,
{
let (l, r) = dual_monos;
if l.len() != r.len() {
Err(AudioConvError::ChannelsNotInSameSize)
} else {
Ok(l.iter()
.zip(r)
.map(|(l, r): (&S, &S)| -> (S, S) { (*l, *r) })
.collect())
}
}
pub fn interleaved_samples_to_stereos<S>(samples: &[S]) -> Result<Vec<(S, S)>, AudioConvError>
where
S: SampleType,
{
if (samples.len() & 1) != 0 {
Err(AudioConvError::TruncatedSamples)
} else {
Ok((0..(samples.len() / 2))
.map(|position| -> (S, S) { (samples[position * 2], samples[position * 2 + 1]) })
.collect())
}
}
pub fn dual_monos_to_monos<S>(dual_monos: &(Vec<S>, Vec<S>)) -> Result<Vec<S>, AudioConvError>
where
S: SampleType,
{
let (l, r) = dual_monos;
if l.len() != r.len() {
Err(AudioConvError::ChannelsNotInSameSize)
} else {
Ok(l.iter()
.zip(r)
.map(|(l, r): (&S, &S)| -> S { S::average(*l, *r) })
.collect())
}
}
pub fn monos_to_dual_monos<S>(monos: &[S]) -> (Vec<S>, Vec<S>)
where
S: SampleType,
{
(monos.to_vec(), monos.to_vec())
}
pub fn stereos_to_mono_channel<S>(stereos: &[(S, S)]) -> Vec<S>
where
S: SampleType,
{
stereos
.iter()
.map(|(l, r): &(S, S)| -> S { S::average(*l, *r) })
.collect()
}
pub fn monos_to_stereos<S>(monos: &[S]) -> Vec<(S, S)>
where
S: SampleType,
{
monos.iter().map(|s| (*s, *s)).collect()
}
#[inline(always)]
pub fn stereo_conv<S, D>(frame: (S, S)) -> (D, D)
where
S: SampleType,
D: SampleType,
{
let (l, r) = frame;
(D::scale_from(l), D::scale_from(r))
}
pub fn sample_conv<S, D>(frame: &[S]) -> Cow<'_, [D]>
where
S: SampleType,
D: SampleType,
{
if TypeId::of::<S>() == TypeId::of::<D>() {
Cow::Borrowed(unsafe { slice::from_raw_parts(frame.as_ptr() as *const D, frame.len()) })
} else {
Cow::Owned(
frame
.iter()
.map(|sample: &S| -> D { D::scale_from(*sample) })
.collect(),
)
}
}
pub fn stereos_conv<S, D>(stereos: &[(S, S)]) -> Cow<'_, [(D, D)]>
where
S: SampleType,
D: SampleType,
{
if TypeId::of::<S>() == TypeId::of::<D>() {
Cow::Borrowed(unsafe {
slice::from_raw_parts(stereos.as_ptr() as *const (D, D), stereos.len())
})
} else {
Cow::Owned(
stereos
.iter()
.map(|stereo: &(S, S)| -> (D, D) { stereo_conv(*stereo) })
.collect(),
)
}
}
pub fn sample_conv_batch<S, D>(frames: &[Vec<S>]) -> Cow<'_, [Vec<D>]>
where
S: SampleType,
D: SampleType,
{
if TypeId::of::<S>() == TypeId::of::<D>() {
Cow::Borrowed(unsafe {
slice::from_raw_parts(frames.as_ptr() as *const Vec<D>, frames.len())
})
} else {
Cow::Owned(
frames
.iter()
.map(|frames: &Vec<S>| -> Vec<D> { sample_conv(frames).to_vec() })
.collect(),
)
}
}
pub fn do_resample_mono<S>(
resampler: &Resampler,
input: &[S],
src_sample_rate: u32,
dst_sample_rate: u32,
) -> Vec<S>
where
S: SampleType,
{
let input = sample_conv::<S, f32>(input);
let result = resampler
.resample(&input, src_sample_rate, dst_sample_rate)
.unwrap();
sample_conv::<f32, S>(&result).to_vec()
}
pub fn do_resample_stereo<S>(
resampler: &Resampler,
input: &[(S, S)],
src_sample_rate: u32,
dst_sample_rate: u32,
) -> Vec<(S, S)>
where
S: SampleType,
{
let block = stereos_to_dual_monos(input);
let l = do_resample_mono(resampler, &block.0, src_sample_rate, dst_sample_rate);
let r = do_resample_mono(resampler, &block.1, src_sample_rate, dst_sample_rate);
dual_monos_to_stereos(&(l, r)).unwrap()
}
pub fn do_resample_frames<S>(
resampler: &Resampler,
input: &[Vec<S>],
src_sample_rate: u32,
dst_sample_rate: u32,
) -> Vec<Vec<S>>
where
S: SampleType,
{
let monos = frames_to_monos(input).unwrap();
let monos: Vec<Vec<S>> = monos
.into_iter()
.map(|mono| do_resample_mono(resampler, &mono, src_sample_rate, dst_sample_rate))
.collect();
monos_to_frames(&monos).unwrap()
}