1use std::ffi::c_void;
9use std::marker::{PhantomData, PhantomPinned};
10
11use speex_sys::SpeexMode;
12
13use crate::mode::{CoderMode, ControlError, ControlFunctions, ModeId, NbMode, UwbMode, WbMode};
14use crate::{dynamic_mapping, mode, shared_functions, NbSubmodeId, SpeexBits, WbSubmodeId};
15
16#[repr(C)]
19pub struct SpeexEncoderHandle {
20 _data: [u8; 0],
21 _marker: PhantomData<(*mut u8, PhantomPinned)>,
22}
23
24impl SpeexEncoderHandle {
25 pub unsafe fn create(mode: &SpeexMode) -> *mut Self {
34 let ptr = unsafe {
35 let mode_ptr = mode as *const SpeexMode;
36 speex_sys::speex_encoder_init(mode_ptr)
37 };
38 ptr as *mut SpeexEncoderHandle
39 }
40
41 pub unsafe fn destroy(handle: *mut SpeexEncoderHandle) {
49 unsafe { speex_sys::speex_encoder_destroy(handle as *mut c_void) }
50 }
51}
52
53pub struct SpeexEncoder<T: CoderMode> {
55 encoder_handle: *mut SpeexEncoderHandle,
56 pub mode: &'static SpeexMode,
57 _phantom: PhantomData<T>,
58}
59
60impl<T: CoderMode> mode::private::Sealed for SpeexEncoder<T> {}
61
62impl<T: CoderMode> ControlFunctions for SpeexEncoder<T> {
63 unsafe fn ctl(&mut self, request: i32, ptr: *mut c_void) -> Result<(), ControlError> {
64 let result = speex_sys::speex_encoder_ctl(self.encoder_handle as *mut c_void, request, ptr);
65 Self::check_error(result, Some(request))
66 }
67}
68
69impl<T: CoderMode> SpeexEncoder<T> {
70 fn get_low_submode_internal(&mut self) -> NbSubmodeId {
71 let mut low_mode = 0;
72 let ptr = &mut low_mode as *mut i32 as *mut c_void;
73 unsafe {
74 self.ctl(speex_sys::SPEEX_GET_LOW_MODE, ptr).unwrap();
75 }
76 low_mode.into()
77 }
78
79 fn set_low_submode_internal(&mut self, low_mode: NbSubmodeId) {
80 let low_mode = low_mode as i32;
81 let ptr = &low_mode as *const i32 as *mut c_void;
82 unsafe {
83 self.ctl(speex_sys::SPEEX_SET_LOW_MODE, ptr).unwrap();
84 }
85 }
86
87 fn set_high_submode_internal(&mut self, high_mode: WbSubmodeId) {
88 let high_mode = high_mode as i32;
89 let ptr = &high_mode as *const i32 as *mut c_void;
90 unsafe {
91 self.ctl(speex_sys::SPEEX_SET_HIGH_MODE, ptr).unwrap();
92 }
93 }
94
95 fn get_high_submode_internal(&mut self) -> WbSubmodeId {
96 let mut high_mode = 0;
97 let ptr = &mut high_mode as *mut i32 as *mut c_void;
98 unsafe {
99 self.ctl(speex_sys::SPEEX_GET_HIGH_MODE, ptr).unwrap();
100 }
101 high_mode.into()
102 }
103
104 pub fn set_complexity(&mut self, complexity: i32) {
106 let ptr = &complexity as *const i32 as *mut c_void;
107 unsafe {
108 self.ctl(speex_sys::SPEEX_SET_COMPLEXITY, ptr).unwrap();
109 }
110 }
111
112 pub fn get_complexity(&mut self) -> i32 {
114 let mut state = 0;
115 let ptr = &mut state as *mut i32 as *mut c_void;
116 unsafe {
117 self.ctl(speex_sys::SPEEX_GET_COMPLEXITY, ptr).unwrap();
118 }
119 state
120 }
121
122 pub fn encode(&mut self, input: &mut [f32], bits: &mut SpeexBits) {
124 let input_ptr = input.as_mut_ptr();
125 unsafe {
126 speex_sys::speex_encode(
127 self.encoder_handle as *mut c_void,
128 input_ptr,
129 bits.backing_mut_ptr(),
130 );
131 }
132 }
133
134 pub fn encode_int(&mut self, input: &mut [i16], bits: &mut SpeexBits) {
137 let bits_ptr = bits.backing_mut_ptr();
138 let input_ptr = input.as_mut_ptr();
139 unsafe {
140 speex_sys::speex_encode_int(self.encoder_handle as *mut c_void, input_ptr, bits_ptr);
141 }
142 }
143}
144
145impl SpeexEncoder<NbMode> {
146 pub fn new() -> SpeexEncoder<NbMode> {
148 let mode = ModeId::NarrowBand.get_mode();
149 let encoder_handle = unsafe { SpeexEncoderHandle::create(mode) };
150 Self {
151 encoder_handle,
152 mode,
153 _phantom: PhantomData,
154 }
155 }
156
157 pub fn set_submode(&mut self, submode: NbSubmodeId) {
159 self.set_low_submode_internal(submode);
160 }
161
162 pub fn get_submode(&mut self) -> NbSubmodeId {
164 self.get_low_submode_internal()
165 }
166}
167
168impl Default for SpeexEncoder<NbMode> {
169 fn default() -> Self {
170 Self::new()
171 }
172}
173
174impl SpeexEncoder<WbMode> {
175 pub fn new() -> SpeexEncoder<WbMode> {
177 let mode = ModeId::WideBand.get_mode();
178 let encoder_handle = unsafe { SpeexEncoderHandle::create(mode) };
179 Self {
180 encoder_handle,
181 mode,
182 _phantom: PhantomData,
183 }
184 }
185
186 pub fn set_low_submode(&mut self, low_mode: NbSubmodeId) {
188 self.set_low_submode_internal(low_mode);
189 }
190
191 pub fn get_low_submode(&mut self) -> NbSubmodeId {
193 self.get_low_submode_internal()
194 }
195
196 pub fn set_high_submode(&mut self, high_mode: WbSubmodeId) {
198 self.set_high_submode_internal(high_mode);
199 }
200
201 pub fn get_high_submode(&mut self) -> WbSubmodeId {
203 self.get_high_submode_internal()
204 }
205}
206
207impl Default for SpeexEncoder<WbMode> {
208 fn default() -> Self {
209 Self::new()
210 }
211}
212
213impl SpeexEncoder<UwbMode> {
214 pub fn new() -> SpeexEncoder<UwbMode> {
216 let mode = ModeId::UltraWideBand.get_mode();
217 let encoder_handle = unsafe { SpeexEncoderHandle::create(mode) };
218 Self {
219 encoder_handle,
220 mode,
221 _phantom: PhantomData,
222 }
223 }
224
225 pub fn set_low_submode(&mut self, low_mode: NbSubmodeId) {
227 self.set_low_submode_internal(low_mode);
228 }
229
230 pub fn get_low_submode(&mut self) -> NbSubmodeId {
232 self.get_low_submode_internal()
233 }
234}
235
236impl Default for SpeexEncoder<UwbMode> {
237 fn default() -> Self {
238 Self::new()
239 }
240}
241
242impl<T: CoderMode> Drop for SpeexEncoder<T> {
243 fn drop(&mut self) {
244 unsafe {
245 SpeexEncoderHandle::destroy(self.encoder_handle);
246 }
247 }
248}
249
250pub enum DynamicEncoder {
253 Nb(SpeexEncoder<NbMode>),
254 Wb(SpeexEncoder<WbMode>),
255 Uwb(SpeexEncoder<UwbMode>),
256}
257
258impl DynamicEncoder {
259 shared_functions!(DynamicEncoder);
260
261 pub fn set_complexity(&mut self, complexity: i32) {
263 dynamic_mapping!(self, DynamicEncoder, inner => inner.set_complexity(complexity))
264 }
265
266 pub fn get_complexity(&mut self) -> i32 {
268 dynamic_mapping!(self, DynamicEncoder, inner => inner.get_complexity())
269 }
270
271 pub fn encode(&mut self, input: &mut [f32], bits: &mut SpeexBits) {
273 match self {
274 DynamicEncoder::Nb(inner) => inner.encode(input, bits),
275 DynamicEncoder::Wb(inner) => inner.encode(input, bits),
276 DynamicEncoder::Uwb(inner) => inner.encode(input, bits),
277 }
278 }
279
280 pub fn encode_int(&mut self, input: &mut [i16], bits: &mut SpeexBits) {
283 match self {
284 DynamicEncoder::Nb(inner) => inner.encode_int(input, bits),
285 DynamicEncoder::Wb(inner) => inner.encode_int(input, bits),
286 DynamicEncoder::Uwb(inner) => inner.encode_int(input, bits),
287 }
288 }
289
290 pub fn new(mode: ModeId) -> DynamicEncoder {
291 match mode {
292 ModeId::NarrowBand => DynamicEncoder::Nb(SpeexEncoder::<NbMode>::new()),
293 ModeId::WideBand => DynamicEncoder::Wb(SpeexEncoder::<WbMode>::new()),
294 ModeId::UltraWideBand => DynamicEncoder::Uwb(SpeexEncoder::<UwbMode>::new()),
295 }
296 }
297
298 pub fn into_nb(self) -> Option<SpeexEncoder<NbMode>> {
299 match self {
300 DynamicEncoder::Nb(nb) => Some(nb),
301 _ => None,
302 }
303 }
304
305 pub fn into_wb(self) -> Option<SpeexEncoder<WbMode>> {
306 match self {
307 DynamicEncoder::Wb(wb) => Some(wb),
308 _ => None,
309 }
310 }
311
312 pub fn into_uwb(self) -> Option<SpeexEncoder<UwbMode>> {
313 match self {
314 DynamicEncoder::Uwb(uwb) => Some(uwb),
315 _ => None,
316 }
317 }
318}
319
320
321#[cfg(test)]
322mod test {
323 use super::*;
324
325 macro_rules! set_get_test {
326 ($name:ident, $set:ident, $get:ident, $value:expr) => {
327 #[test]
328 fn $name() {
329 let mut encoder = SpeexEncoder::<WbMode>::new();
330 encoder.$set($value);
331 let result = encoder.$get();
332
333 assert_eq!(result, $value);
334 }
335 };
336 }
337
338 set_get_test!(
339 set_get_high_submode,
340 set_high_submode,
341 get_high_submode,
342 WbSubmodeId::NoQuantize
343 );
344
345 set_get_test!(set_get_vbr, set_vbr, get_vbr, true);
346
347 set_get_test!(set_get_vbr_quality, set_vbr_quality, get_vbr_quality, 8.0);
348
349 set_get_test!(set_get_vad, set_vad, get_vad, true);
350
351 set_get_test!(set_get_abr, set_abr, get_abr, 2000);
352
353 #[test]
354 fn set_quality() {
355 let mut encoder = SpeexEncoder::<WbMode>::new();
356 encoder.set_quality(10);
357 }
358
359 set_get_test!(set_get_bitrate, set_bitrate, get_bitrate, 3950);
360
361 set_get_test!(
362 set_get_sampling_rate,
363 set_sampling_rate,
364 get_sampling_rate,
365 3950
366 );
367
368 #[test]
369 fn get_frame_size() {
370 let mut encoder = SpeexEncoder::<WbMode>::new();
371 encoder.get_frame_size();
372 }
373
374 #[test]
375 fn encodes_frame_without_segfault() {
376 let mut encoder = SpeexEncoder::<NbMode>::new();
377 let mut bits = SpeexBits::new();
378 let frame_size = encoder.get_frame_size();
379 let mut input = vec![23i16; frame_size as usize];
380
381 encoder.encode_int(&mut input, &mut bits);
382 }
383}