speexdsp/
preprocess.rs

1#![allow(non_camel_case_types)]
2
3#[cfg(feature = "sys")]
4mod sys {
5    use crate::echo::SpeexEcho;
6    use speexdsp_sys::preprocess::*;
7    use std::convert::From;
8    use std::ffi::c_void;
9    use std::fmt;
10
11    #[derive(Clone, Copy, Debug)]
12    pub enum SpeexPreprocessConst {
13        SPEEX_PREPROCESS_SET_DENOISE = 0,
14        SPEEX_PREPROCESS_GET_DENOISE = 1,
15        SPEEX_PREPROCESS_SET_AGC = 2,
16        SPEEX_PREPROCESS_GET_AGC = 3,
17        SPEEX_PREPROCESS_SET_VAD = 4,
18        SPEEX_PREPROCESS_GET_VAD = 5,
19        SPEEX_PREPROCESS_SET_AGC_LEVEL = 6,
20        SPEEX_PREPROCESS_GET_AGC_LEVEL = 7,
21        SPEEX_PREPROCESS_SET_DEREVERB = 8,
22        SPEEX_PREPROCESS_GET_DEREVERB = 9,
23        SPEEX_PREPROCESS_SET_DEREVERB_LEVEL = 10,
24        SPEEX_PREPROCESS_GET_DEREVERB_LEVEL = 11,
25        SPEEX_PREPROCESS_SET_DEREVERB_DECAY = 12,
26        SPEEX_PREPROCESS_GET_DEREVERB_DECAY = 13,
27        SPEEX_PREPROCESS_SET_PROB_START = 14,
28        SPEEX_PREPROCESS_GET_PROB_START = 15,
29        SPEEX_PREPROCESS_SET_PROB_CONTINUE = 16,
30        SPEEX_PREPROCESS_GET_PROB_CONTINUE = 17,
31        SPEEX_PREPROCESS_SET_NOISE_SUPPRESS = 18,
32        SPEEX_PREPROCESS_GET_NOISE_SUPPRESS = 19,
33        SPEEX_PREPROCESS_SET_ECHO_SUPPRESS = 20,
34        SPEEX_PREPROCESS_GET_ECHO_SUPPRESS = 21,
35        SPEEX_PREPROCESS_SET_ECHO_SUPPRESS_ACTIVE = 22,
36        SPEEX_PREPROCESS_GET_ECHO_SUPPRESS_ACTIVE = 23,
37        SPEEX_PREPROCESS_SET_ECHO_STATE = 24,
38        SPEEX_PREPROCESS_GET_ECHO_STATE = 25,
39        SPEEX_PREPROCESS_SET_AGC_INCREMENT = 26,
40        SPEEX_PREPROCESS_GET_AGC_INCREMENT = 27,
41        SPEEX_PREPROCESS_SET_AGC_DECREMENT = 28,
42        SPEEX_PREPROCESS_GET_AGC_DECREMENT = 29,
43        SPEEX_PREPROCESS_SET_AGC_MAX_GAIN = 30,
44        SPEEX_PREPROCESS_GET_AGC_MAX_GAIN = 31,
45        SPEEX_PREPROCESS_GET_AGC_LOUDNESS = 33,
46        SPEEX_PREPROCESS_GET_AGC_GAIN = 35,
47        SPEEX_PREPROCESS_GET_PSD_SIZE = 37,
48        SPEEX_PREPROCESS_GET_PSD = 39,
49        SPEEX_PREPROCESS_GET_NOISE_PSD_SIZE = 41,
50        SPEEX_PREPROCESS_GET_NOISE_PSD = 43,
51        SPEEX_PREPROCESS_GET_PROB = 45,
52        SPEEX_PREPROCESS_SET_AGC_TARGET = 46,
53        SPEEX_PREPROCESS_GET_AGC_TARGET = 47,
54    }
55
56    #[derive(Clone, Copy, Debug)]
57    pub enum Error {
58        FailedInit,
59        UnknownRequest,
60    }
61
62    impl fmt::Display for Error {
63        fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
64            let v = match self {
65                Error::FailedInit => "Failed to initialize",
66                Error::UnknownRequest => "The request is unknown",
67            };
68
69            write!(f, "{}", v)
70        }
71    }
72
73    pub enum Variant {
74        U32(u32),
75        F32(f32),
76        Echo(SpeexEcho),
77    }
78
79    impl From<u32> for Variant {
80        fn from(item: u32) -> Self {
81            Variant::U32(item)
82        }
83    }
84
85    impl From<f32> for Variant {
86        fn from(item: f32) -> Self {
87            Variant::F32(item)
88        }
89    }
90
91    impl From<&SpeexEcho> for Variant {
92        fn from(item: &SpeexEcho) -> Self {
93            Variant::Echo(item.clone())
94        }
95    }
96
97    pub struct SpeexPreprocess {
98        st: *mut SpeexPreprocessState,
99    }
100
101    impl SpeexPreprocess {
102        pub fn new(
103            frame_size: usize,
104            sampling_rate: usize,
105        ) -> Result<Self, Error> {
106            let st = unsafe {
107                speex_preprocess_state_init(
108                    frame_size as i32,
109                    sampling_rate as i32,
110                )
111            };
112
113            if st.is_null() {
114                Err(Error::FailedInit)
115            } else {
116                Ok(SpeexPreprocess { st })
117            }
118        }
119
120        pub fn preprocess_run(&mut self, x: &mut [i16]) -> usize {
121            unsafe { speex_preprocess_run(self.st, x.as_mut_ptr()) as usize }
122        }
123
124        pub fn preprocess(&mut self, x: &mut [i16], echo: usize) -> usize {
125            unsafe {
126                speex_preprocess(self.st, x.as_mut_ptr(), echo as *mut i32)
127                    as usize
128            }
129        }
130
131        pub fn preprocess_estimate_update(&mut self, x: &mut [i16]) {
132            unsafe {
133                speex_preprocess_estimate_update(self.st, x.as_mut_ptr())
134            };
135        }
136
137        pub fn preprocess_ctl<T: Into<Variant>>(
138            &mut self,
139            request: SpeexPreprocessConst,
140            value: T,
141        ) -> Result<(), Error> {
142            let ptr_v = match (request, value.into()) {
143                (
144                    SpeexPreprocessConst::SPEEX_PREPROCESS_SET_DEREVERB_DECAY,
145                    Variant::F32(val),
146                )
147                | (
148                    SpeexPreprocessConst::SPEEX_PREPROCESS_SET_DEREVERB_LEVEL,
149                    Variant::F32(val),
150                ) => &val as *const f32 as *mut c_void,
151                (
152                    SpeexPreprocessConst::SPEEX_PREPROCESS_SET_ECHO_STATE,
153                    Variant::Echo(val),
154                ) => val.get_ptr() as *mut c_void,
155                (_, Variant::U32(val)) => &val as *const u32 as *mut c_void,
156                _ => panic!("This type is not accepted"),
157            };
158            let ret = unsafe {
159                speex_preprocess_ctl(self.st, request as i32, ptr_v) as usize
160            };
161            if ret != 0 {
162                Err(Error::UnknownRequest)
163            } else {
164                Ok(())
165            }
166        }
167    }
168
169    impl Drop for SpeexPreprocess {
170        fn drop(&mut self) {
171            unsafe { speex_preprocess_state_destroy(self.st) };
172        }
173    }
174}
175
176#[cfg(feature = "sys")]
177pub use self::sys::{Error, SpeexPreprocess, SpeexPreprocessConst};