speexdsp 0.1.2

Bindings for the speexdsp library
Documentation
#![allow(non_camel_case_types)]
#![allow(unreachable_patterns)]

#[derive(Clone, Copy, Debug)]
pub enum Error {
    AllocFailed = 1,
    BadState = 2,
    InvalidArg = 3,
    PtrOverlap = 4,
}

use std::fmt;

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let v = match self {
            Error::AllocFailed => "Memory allocation failed.",
            Error::BadState => "Bad resampler state.",
            Error::InvalidArg => "Invalid argument.",
            Error::PtrOverlap => "Input and output buffers overlap.",
        };

        write!(f, "{}", v)
    }
}

pub trait Resampler: Sized {
    fn new(
        channels: usize,
        in_rate: usize,
        out_rate: usize,
        quality: usize,
    ) -> Result<Self, Error>;
    fn set_rate(
        &mut self,
        in_rate: usize,
        out_rate: usize,
    ) -> Result<(), Error>;
    fn get_rate(&self) -> (usize, usize);
    fn get_ratio(&self) -> (usize, usize);
    fn process_float(
        &mut self,
        index: usize,
        input: &[f32],
        output: &mut [f32],
    ) -> Result<(usize, usize), Error>;
    fn skip_zeros(&mut self);
    fn reset(&mut self);
    fn get_input_latency(&self) -> usize;
    fn get_output_latency(&self) -> usize;
    fn set_quality(&mut self, quality: usize) -> Result<(), Error>;
    fn get_quality(&self) -> usize;
}

#[cfg(feature = "sys")]
mod sys {
    use super::{Error, Resampler};
    use speexdsp_sys::resampler::*;

    impl From<i32> for Error {
        fn from(v: i32) -> Error {
            match v as u32 {
                RESAMPLER_ERR_ALLOC_FAILED => Error::AllocFailed,
                RESAMPLER_ERR_BAD_STATE => Error::BadState,
                RESAMPLER_ERR_INVALID_ARG => Error::InvalidArg,
                RESAMPLER_ERR_PTR_OVERLAP => Error::PtrOverlap,
                _ => unreachable!(),
            }
        }
    }

    pub struct State {
        st: *mut SpeexResamplerState,
    }

    impl Resampler for State {
        fn new(
            channels: usize,
            in_rate: usize,
            out_rate: usize,
            quality: usize,
        ) -> Result<Self, Error> {
            let mut err = 0;
            let st = unsafe {
                speex_resampler_init(
                    channels as u32,
                    in_rate as u32,
                    out_rate as u32,
                    quality as i32,
                    &mut err,
                )
            };

            if st.is_null() {
                Err(err.into())
            } else {
                Ok(State { st })
            }
        }

        fn set_rate(
            &mut self,
            in_rate: usize,
            out_rate: usize,
        ) -> Result<(), Error> {
            let ret = unsafe {
                speex_resampler_set_rate(
                    self.st,
                    in_rate as u32,
                    out_rate as u32,
                )
            };
            if ret != 0 {
                Err(ret.into())
            } else {
                Ok(())
            }
        }

        fn get_rate(&self) -> (usize, usize) {
            let mut in_rate = 0;
            let mut out_rate = 0;

            unsafe {
                speex_resampler_get_rate(self.st, &mut in_rate, &mut out_rate)
            };

            (in_rate as usize, out_rate as usize)
        }

        fn get_ratio(&self) -> (usize, usize) {
            let mut num = 0;
            let mut den = 0;

            unsafe { speex_resampler_get_ratio(self.st, &mut num, &mut den) };

            (num as usize, den as usize)
        }

        fn process_float(
            &mut self,
            index: usize,
            input: &[f32],
            output: &mut [f32],
        ) -> Result<(usize, usize), Error> {
            let mut in_len = input.len() as u32;
            let mut out_len = output.len() as u32;
            let ret = unsafe {
                speex_resampler_process_float(
                    self.st,
                    index as u32,
                    input.as_ptr(),
                    &mut in_len,
                    output.as_mut_ptr(),
                    &mut out_len,
                )
            };

            if ret != 0 {
                Err(ret.into())
            } else {
                Ok((in_len as usize, out_len as usize))
            }
        }

        fn skip_zeros(&mut self) {
            unsafe { speex_resampler_skip_zeros(self.st) };
        }

        fn reset(&mut self) {
            unsafe { speex_resampler_reset_mem(self.st) };
        }

        fn get_input_latency(&self) -> usize {
            unsafe { speex_resampler_get_input_latency(self.st) as usize }
        }

        fn get_output_latency(&self) -> usize {
            unsafe { speex_resampler_get_output_latency(self.st) as usize }
        }

        fn set_quality(&mut self, quality: usize) -> Result<(), Error> {
            let ret = unsafe {
                speex_resampler_set_quality(self.st, quality as i32)
            };
            if ret != 0 {
                Err(ret.into())
            } else {
                Ok(())
            }
        }

        fn get_quality(&self) -> usize {
            let mut c_get = 0;
            unsafe { speex_resampler_get_quality(self.st, &mut c_get) };
            c_get as usize
        }
    }

    impl Drop for State {
        fn drop(&mut self) {
            unsafe { speex_resampler_destroy(self.st) };
        }
    }
}

pub mod native {
    use super::{Error, Resampler};
    pub use speexdsp_resampler::State;

    impl From<speexdsp_resampler::Error> for Error {
        fn from(v: speexdsp_resampler::Error) -> Error {
            match v {
                speexdsp_resampler::Error::AllocFailed => Error::AllocFailed,
                speexdsp_resampler::Error::InvalidArg => Error::InvalidArg,
            }
        }
    }

    impl Resampler for State {
        fn new(
            channels: usize,
            in_rate: usize,
            out_rate: usize,
            quality: usize,
        ) -> Result<Self, Error> {
            State::new(channels, in_rate, out_rate, quality)
                .map_err(|e| e.into())
        }
        fn set_rate(
            &mut self,
            in_rate: usize,
            out_rate: usize,
        ) -> Result<(), Error> {
            State::set_rate(self, in_rate, out_rate).map_err(|e| e.into())
        }
        fn get_rate(&self) -> (usize, usize) {
            State::get_rate(self)
        }
        fn get_ratio(&self) -> (usize, usize) {
            State::get_ratio(self)
        }
        fn process_float(
            &mut self,
            index: usize,
            input: &[f32],
            output: &mut [f32],
        ) -> Result<(usize, usize), Error> {
            State::process(self, index, input, output).map_err(|e| e.into())
        }
        fn skip_zeros(&mut self) {
            State::skip_zeros(self);
        }
        fn reset(&mut self) {
            State::reset(self);
        }
        fn get_input_latency(&self) -> usize {
            State::get_input_latency(self)
        }
        fn get_output_latency(&self) -> usize {
            State::get_output_latency(self)
        }
        fn set_quality(&mut self, quality: usize) -> Result<(), Error> {
            State::set_quality(self, quality).map_err(|e| e.into())
        }
        fn get_quality(&self) -> usize {
            State::get_quality(self)
        }
    }
}

#[cfg(feature = "sys")]
pub use self::sys::*;

#[cfg(not(feature = "sys"))]
pub use self::native::*;