#[cfg(feature = "log")]
extern crate log;
#[allow(unused)]
macro_rules! trace { ($($x:tt)*) => (
#[cfg(feature = "log")] {
log::trace!($($x)*)
}
) }
#[allow(unused)]
macro_rules! debug { ($($x:tt)*) => (
#[cfg(feature = "log")] {
log::debug!($($x)*)
}
) }
#[allow(unused)]
macro_rules! info { ($($x:tt)*) => (
#[cfg(feature = "log")] {
log::info!($($x)*)
}
) }
#[allow(unused)]
macro_rules! warn { ($($x:tt)*) => (
#[cfg(feature = "log")] {
log::warn!($($x)*)
}
) }
#[allow(unused)]
macro_rules! error { ($($x:tt)*) => (
#[cfg(feature = "log")] {
log::error!($($x)*)
}
) }
mod asynchro;
mod error;
mod interpolation;
mod sample;
mod sinc;
mod synchro;
mod windows;
pub use crate::asynchro::{ScalarInterpolator, SincFixedIn, SincFixedOut};
pub use crate::error::{
CpuFeature, MissingCpuFeature, ResampleError, ResampleResult, ResamplerConstructionError,
};
pub use crate::sample::Sample;
pub use crate::synchro::{FftFixedIn, FftFixedInOut, FftFixedOut};
pub use crate::windows::WindowFunction;
macro_rules! interpolator {
(
#[cfg($($cond:tt)*)]
mod $mod:ident;
trait $trait:ident;
) => {
#[cfg($($cond)*)]
pub mod $mod;
#[cfg($($cond)*)]
use self::$mod::$trait;
#[cfg(not($($cond)*))]
pub trait $trait {
}
#[cfg(not($($cond)*))]
impl<T> $trait for T where T: Sample {
}
}
}
interpolator! {
#[cfg(target_arch = "x86_64")]
mod interpolator_avx;
trait AvxSample;
}
interpolator! {
#[cfg(target_arch = "x86_64")]
mod interpolator_sse;
trait SseSample;
}
interpolator! {
#[cfg(target_arch = "aarch64")]
mod interpolator_neon;
trait NeonSample;
}
#[derive(Debug)]
pub struct InterpolationParameters {
pub sinc_len: usize,
pub f_cutoff: f32,
pub oversampling_factor: usize,
pub interpolation: InterpolationType,
pub window: WindowFunction,
}
#[derive(Debug)]
pub enum InterpolationType {
Cubic,
Linear,
Nearest,
}
pub trait Resampler<T>: Send {
fn process<V: AsRef<[T]>>(
&mut self,
wave_in: &[V],
active_channels_mask: Option<&[bool]>,
) -> ResampleResult<Vec<Vec<T>>> {
let frames = self.output_frames_next();
let channels = self.nbr_channels();
let mut wave_out = Vec::with_capacity(channels);
for _ in 0..channels {
wave_out.push(Vec::with_capacity(frames));
}
self.process_into_buffer(wave_in, &mut wave_out, active_channels_mask)?;
Ok(wave_out)
}
fn process_into_buffer<V: AsRef<[T]>>(
&mut self,
wave_in: &[V],
wave_out: &mut [Vec<T>],
active_channels_mask: Option<&[bool]>,
) -> ResampleResult<()>;
fn input_buffer_allocate(&self) -> Vec<Vec<T>> {
let frames = self.input_frames_max();
let channels = self.nbr_channels();
let mut buffer = Vec::with_capacity(channels);
for _ in 0..channels {
buffer.push(Vec::with_capacity(frames));
}
buffer
}
fn input_frames_max(&self) -> usize;
fn input_frames_next(&self) -> usize;
fn nbr_channels(&self) -> usize;
fn output_buffer_allocate(&self) -> Vec<Vec<T>> {
let frames = self.output_frames_max();
let channels = self.nbr_channels();
let mut buffer = Vec::with_capacity(channels);
for _ in 0..channels {
buffer.push(Vec::with_capacity(frames));
}
buffer
}
fn output_frames_max(&self) -> usize;
fn output_frames_next(&self) -> usize;
fn set_resample_ratio(&mut self, new_ratio: f64) -> ResampleResult<()>;
fn set_resample_ratio_relative(&mut self, rel_ratio: f64) -> ResampleResult<()>;
}
pub trait VecResampler<T>: Send {
fn process(
&mut self,
wave_in: &[Vec<T>],
active_channels_mask: Option<&[bool]>,
) -> ResampleResult<Vec<Vec<T>>>;
fn process_into_buffer(
&mut self,
wave_in: &[Vec<T>],
wave_out: &mut [Vec<T>],
active_channels_mask: Option<&[bool]>,
) -> ResampleResult<()>;
fn input_buffer_allocate(&self) -> Vec<Vec<T>>;
fn input_frames_max(&self) -> usize;
fn input_frames_next(&self) -> usize;
fn nbr_channels(&self) -> usize;
fn output_buffer_allocate(&self) -> Vec<Vec<T>>;
fn output_frames_max(&self) -> usize;
fn output_frames_next(&self) -> usize;
fn set_resample_ratio(&mut self, new_ratio: f64) -> ResampleResult<()>;
fn set_resample_ratio_relative(&mut self, rel_ratio: f64) -> ResampleResult<()>;
}
impl<T, U> VecResampler<T> for U
where
U: Resampler<T>,
{
fn process(
&mut self,
wave_in: &[Vec<T>],
active_channels_mask: Option<&[bool]>,
) -> ResampleResult<Vec<Vec<T>>> {
Resampler::process(self, wave_in, active_channels_mask)
}
fn process_into_buffer(
&mut self,
wave_in: &[Vec<T>],
wave_out: &mut [Vec<T>],
active_channels_mask: Option<&[bool]>,
) -> ResampleResult<()> {
Resampler::process_into_buffer(self, wave_in, wave_out, active_channels_mask)
}
fn output_buffer_allocate(&self) -> Vec<Vec<T>> {
Resampler::output_buffer_allocate(self)
}
fn output_frames_next(&self) -> usize {
Resampler::output_frames_next(self)
}
fn output_frames_max(&self) -> usize {
Resampler::output_frames_max(self)
}
fn input_frames_next(&self) -> usize {
Resampler::input_frames_next(self)
}
fn nbr_channels(&self) -> usize {
Resampler::nbr_channels(self)
}
fn input_frames_max(&self) -> usize {
Resampler::input_frames_max(self)
}
fn input_buffer_allocate(&self) -> Vec<Vec<T>> {
Resampler::input_buffer_allocate(self)
}
fn set_resample_ratio(&mut self, new_ratio: f64) -> ResampleResult<()> {
Resampler::set_resample_ratio(self, new_ratio)
}
fn set_resample_ratio_relative(&mut self, rel_ratio: f64) -> ResampleResult<()> {
Resampler::set_resample_ratio_relative(self, rel_ratio)
}
}
fn update_mask_from_buffers<T, V: AsRef<[T]>>(wave_in: &[V], mask: &mut [bool]) {
for (wave, active) in wave_in.iter().zip(mask.iter_mut()) {
let wave = wave.as_ref();
*active = !wave.is_empty();
}
}
pub(crate) fn validate_buffers<T, V: AsRef<[T]>>(
wave_in: &[V],
wave_out: &mut [Vec<T>],
mask: &[bool],
channels: usize,
needed_len: usize,
) -> ResampleResult<()> {
if wave_in.len() != channels {
return Err(ResampleError::WrongNumberOfInputChannels {
expected: channels,
actual: wave_in.len(),
});
}
if mask.len() != channels {
return Err(ResampleError::WrongNumberOfMaskChannels {
expected: channels,
actual: wave_in.len(),
});
}
for (chan, wave) in wave_in.iter().enumerate() {
let wave = wave.as_ref();
if wave.len() != needed_len && mask[chan] {
return Err(ResampleError::WrongNumberOfInputFrames {
channel: chan,
expected: needed_len,
actual: wave.len(),
});
}
}
if wave_out.len() != channels {
return Err(ResampleError::WrongNumberOfOutputChannels {
expected: channels,
actual: wave_out.len(),
});
}
Ok(())
}
#[cfg(test)]
mod tests {
use crate::VecResampler;
use crate::{FftFixedIn, FftFixedInOut, FftFixedOut};
use crate::{SincFixedIn, SincFixedOut};
#[test]
fn boxed_resampler() {
let boxed: Box<dyn VecResampler<f64>> =
Box::new(FftFixedIn::<f64>::new(44100, 88200, 1024, 2, 2).unwrap());
let result = process_with_boxed(boxed);
assert_eq!(result.len(), 2);
assert_eq!(result[0].len(), 2048);
assert_eq!(result[1].len(), 2048);
}
fn process_with_boxed(mut resampler: Box<dyn VecResampler<f64>>) -> Vec<Vec<f64>> {
let frames = resampler.input_frames_next();
let waves = vec![vec![0.0f64; frames]; 2];
resampler.process(&waves, None).unwrap()
}
fn impl_send<T: Send>() {
fn is_send<T: Send>() {}
is_send::<SincFixedOut<T>>();
is_send::<SincFixedIn<T>>();
is_send::<FftFixedOut<T>>();
is_send::<FftFixedIn<T>>();
is_send::<FftFixedInOut<T>>();
}
#[test]
fn test_impl_send() {
impl_send::<f32>();
impl_send::<f64>();
}
}