use crate::base::*;
use crate::frames::{Frames, FramesMut};
use miniaudio_sys as sys;
#[repr(transparent)]
#[derive(Clone)]
pub struct BiquadConfig(sys::ma_biquad_config);
impl BiquadConfig {
#[inline]
pub fn new(
format: Format,
channels: u32,
numerators: [f64; 3],
denominators: [f64; 3],
) -> BiquadConfig {
unsafe {
BiquadConfig(sys::ma_biquad_config_init(
format as _,
channels,
numerators[0],
numerators[1],
numerators[2],
denominators[0],
denominators[1],
denominators[2],
))
}
}
#[inline]
pub fn format(&self) -> Format {
Format::from_c(self.0.format)
}
#[inline]
pub fn set_format(&mut self, format: Format) {
self.0.format = format as _;
}
#[inline]
pub fn channels(&self) -> u32 {
self.0.channels
}
#[inline]
pub fn set_channels(&mut self, channels: u32) {
self.0.channels = channels;
}
#[inline]
pub fn b(&self, index: usize) -> f64 {
match index {
0 => self.0.b0,
1 => self.0.b1,
2 => self.0.b2,
_ => panic!("Numerator out of range."),
}
}
#[inline]
pub fn set_b(&mut self, index: usize, value: f64) {
match index {
0 => self.0.b0 = value,
1 => self.0.b1 = value,
2 => self.0.b2 = value,
_ => panic!("Numerator out of range."),
}
}
#[inline]
pub fn a(&self, index: usize) -> f64 {
match index {
0 => self.0.a0,
1 => self.0.a1,
2 => self.0.a2,
_ => panic!("Denominator out of range."),
}
}
#[inline]
pub fn set_a(&mut self, index: usize, value: f64) {
match index {
0 => self.0.a0 = value,
1 => self.0.a1 = value,
2 => self.0.a2 = value,
_ => panic!("Denominator out of range."),
}
}
}
#[repr(transparent)]
#[derive(Clone)]
pub struct Biquad(sys::ma_biquad);
impl Biquad {
#[inline]
pub fn new(config: &BiquadConfig) -> Result<Biquad, Error> {
let mut biquad = std::mem::MaybeUninit::uninit();
unsafe {
let result = sys::ma_biquad_init(&config.0, biquad.as_mut_ptr());
map_result!(result, Biquad(biquad.assume_init()))
}
}
#[inline]
pub fn reinit(&mut self, config: &BiquadConfig) -> Result<(), Error> {
let result = unsafe { sys::ma_biquad_reinit(&config.0, &mut self.0) };
Error::from_c_result(result)
}
#[inline]
pub fn process_pcm_frames(
&mut self,
output: &mut FramesMut,
input: &Frames,
) -> Result<(), Error> {
if output.format() != input.format() {
ma_debug_panic!(
"output and input format did not match (output: {:?}, input: {:?}",
output.format(),
input.format()
);
return Err(Error::InvalidArgs);
}
if output.frame_count() != input.frame_count() {
ma_debug_panic!("output and input buffers did not have the same frame count (output: {}, input: {})", output.frame_count(), input.frame_count());
return Err(Error::InvalidArgs);
}
let result = unsafe {
sys::ma_biquad_process_pcm_frames(
&mut self.0,
output.as_mut_ptr() as *mut _,
input.as_ptr() as *const _,
output.frame_count() as u64,
)
};
Error::from_c_result(result)
}
#[inline]
pub fn format(&self) -> Format {
Format::from_c(self.0.format)
}
#[inline]
pub fn channels(&self) -> u32 {
self.0.channels
}
#[inline]
pub fn latency(&mut self) -> u32 {
unsafe { sys::ma_biquad_get_latency(&mut self.0) }
}
}