speexdsp 0.1.2

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

#[cfg(feature = "sys")]
mod sys {
    use crate::echo::SpeexEcho;
    use speexdsp_sys::preprocess::*;
    use std::convert::From;
    use std::ffi::c_void;
    use std::fmt;

    #[derive(Clone, Copy, Debug)]
    pub enum SpeexPreprocessConst {
        SPEEX_PREPROCESS_SET_DENOISE = 0,
        SPEEX_PREPROCESS_GET_DENOISE = 1,
        SPEEX_PREPROCESS_SET_AGC = 2,
        SPEEX_PREPROCESS_GET_AGC = 3,
        SPEEX_PREPROCESS_SET_VAD = 4,
        SPEEX_PREPROCESS_GET_VAD = 5,
        SPEEX_PREPROCESS_SET_AGC_LEVEL = 6,
        SPEEX_PREPROCESS_GET_AGC_LEVEL = 7,
        SPEEX_PREPROCESS_SET_DEREVERB = 8,
        SPEEX_PREPROCESS_GET_DEREVERB = 9,
        SPEEX_PREPROCESS_SET_DEREVERB_LEVEL = 10,
        SPEEX_PREPROCESS_GET_DEREVERB_LEVEL = 11,
        SPEEX_PREPROCESS_SET_DEREVERB_DECAY = 12,
        SPEEX_PREPROCESS_GET_DEREVERB_DECAY = 13,
        SPEEX_PREPROCESS_SET_PROB_START = 14,
        SPEEX_PREPROCESS_GET_PROB_START = 15,
        SPEEX_PREPROCESS_SET_PROB_CONTINUE = 16,
        SPEEX_PREPROCESS_GET_PROB_CONTINUE = 17,
        SPEEX_PREPROCESS_SET_NOISE_SUPPRESS = 18,
        SPEEX_PREPROCESS_GET_NOISE_SUPPRESS = 19,
        SPEEX_PREPROCESS_SET_ECHO_SUPPRESS = 20,
        SPEEX_PREPROCESS_GET_ECHO_SUPPRESS = 21,
        SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE = 22,
        SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE = 23,
        SPEEX_PREPROCESS_SET_ECHO_STATE = 24,
        SPEEX_PREPROCESS_GET_ECHO_STATE = 25,
        SPEEX_PREPROCESS_SET_AGC_INCREMENT = 26,
        SPEEX_PREPROCESS_GET_AGC_INCREMENT = 27,
        SPEEX_PREPROCESS_SET_AGC_DECREMENT = 28,
        SPEEX_PREPROCESS_GET_AGC_DECREMENT = 29,
        SPEEX_PREPROCESS_SET_AGC_MAX_GAIN = 30,
        SPEEX_PREPROCESS_GET_AGC_MAX_GAIN = 31,
        SPEEX_PREPROCESS_GET_AGC_LOUDNESS = 33,
        SPEEX_PREPROCESS_GET_AGC_GAIN = 35,
        SPEEX_PREPROCESS_GET_PSD_SIZE = 37,
        SPEEX_PREPROCESS_GET_PSD = 39,
        SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE = 41,
        SPEEX_PREPROCESS_GET_NOISE_PSD = 43,
        SPEEX_PREPROCESS_GET_PROB = 45,
        SPEEX_PREPROCESS_SET_AGC_TARGET = 46,
        SPEEX_PREPROCESS_GET_AGC_TARGET = 47,
    }

    #[derive(Clone, Copy, Debug)]
    pub enum Error {
        FailedInit,
        UnknownRequest,
    }

    impl fmt::Display for Error {
        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
            let v = match self {
                Error::FailedInit => "Failed to initialize",
                Error::UnknownRequest => "The request is unknown",
            };

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

    pub enum Variant {
        U32(u32),
        F32(f32),
        Echo(SpeexEcho),
    }

    impl From<u32> for Variant {
        fn from(item: u32) -> Self {
            Variant::U32(item)
        }
    }

    impl From<f32> for Variant {
        fn from(item: f32) -> Self {
            Variant::F32(item)
        }
    }

    impl From<&SpeexEcho> for Variant {
        fn from(item: &SpeexEcho) -> Self {
            Variant::Echo(item.clone())
        }
    }

    pub struct SpeexPreprocess {
        st: *mut SpeexPreprocessState,
    }

    impl SpeexPreprocess {
        pub fn new(
            frame_size: usize,
            sampling_rate: usize,
        ) -> Result<Self, Error> {
            let st = unsafe {
                speex_preprocess_state_init(
                    frame_size as i32,
                    sampling_rate as i32,
                )
            };

            if st.is_null() {
                Err(Error::FailedInit)
            } else {
                Ok(SpeexPreprocess { st })
            }
        }

        pub fn preprocess_run(&mut self, x: &mut [i16]) -> usize {
            unsafe { speex_preprocess_run(self.st, x.as_mut_ptr()) as usize }
        }

        pub fn preprocess(&mut self, x: &mut [i16], echo: usize) -> usize {
            unsafe {
                speex_preprocess(self.st, x.as_mut_ptr(), echo as *mut i32)
                    as usize
            }
        }

        pub fn preprocess_estimate_update(&mut self, x: &mut [i16]) {
            unsafe {
                speex_preprocess_estimate_update(self.st, x.as_mut_ptr())
            };
        }

        pub fn preprocess_ctl<T: Into<Variant>>(
            &mut self,
            request: SpeexPreprocessConst,
            value: T,
        ) -> Result<(), Error> {
            let ptr_v = match (request, value.into()) {
                (
                    SpeexPreprocessConst::SPEEX_PREPROCESS_SET_DEREVERB_DECAY,
                    Variant::F32(val),
                )
                | (
                    SpeexPreprocessConst::SPEEX_PREPROCESS_SET_DEREVERB_LEVEL,
                    Variant::F32(val),
                ) => &val as *const f32 as *mut c_void,
                (
                    SpeexPreprocessConst::SPEEX_PREPROCESS_SET_ECHO_STATE,
                    Variant::Echo(val),
                ) => val.get_ptr() as *mut c_void,
                (_, Variant::U32(val)) => &val as *const u32 as *mut c_void,
                _ => panic!("This type is not accepted"),
            };
            let ret = unsafe {
                speex_preprocess_ctl(self.st, request as i32, ptr_v) as usize
            };
            if ret != 0 {
                Err(Error::UnknownRequest)
            } else {
                Ok(())
            }
        }
    }

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

#[cfg(feature = "sys")]
pub use self::sys::{Error, SpeexPreprocess, SpeexPreprocessConst};