1pub(crate) mod decoder;
9pub(crate) mod encoder;
10
11use std::error::Error;
12use std::ffi::c_void;
13use std::fmt::Display;
14
15pub use decoder::{DynamicDecoder, SpeexDecoder};
16pub use encoder::{DynamicEncoder, SpeexEncoder};
17use speex_sys::{SpeexMode, SPEEX_MODEID_NB, SPEEX_MODEID_UWB, SPEEX_MODEID_WB};
18
19#[repr(i32)]
21#[derive(Copy, Clone, PartialEq, Eq, Debug)]
22pub enum ModeId {
23 NarrowBand = SPEEX_MODEID_NB,
24 WideBand = SPEEX_MODEID_WB,
25 UltraWideBand = SPEEX_MODEID_UWB,
26}
27
28impl From<i32> for ModeId {
29 fn from(value: i32) -> Self {
30 match value {
31 SPEEX_MODEID_NB => ModeId::NarrowBand,
32 SPEEX_MODEID_WB => ModeId::WideBand,
33 SPEEX_MODEID_UWB => ModeId::UltraWideBand,
34 _ => panic!("Invalid mode id"),
35 }
36 }
37}
38
39#[repr(i32)]
44#[derive(Copy, Clone, PartialEq, Eq, Debug)]
45pub enum NbSubmodeId {
46 VocoderLike = 1,
48 ExtremeLow = 8,
50 VeryLow = 2,
52 Low = 3,
54 Medium = 4,
56 High = 5,
58 VeryHigh = 6,
60 ExtremeHigh = 7,
62}
63
64impl From<i32> for NbSubmodeId {
65 fn from(value: i32) -> Self {
66 match value {
67 1 => NbSubmodeId::VocoderLike,
68 2 => NbSubmodeId::VeryLow,
69 3 => NbSubmodeId::Low,
70 4 => NbSubmodeId::Medium,
71 5 => NbSubmodeId::High,
72 6 => NbSubmodeId::VeryHigh,
73 7 => NbSubmodeId::ExtremeHigh,
74 8 => NbSubmodeId::ExtremeLow,
75 _ => panic!("Invalid submode id"),
76 }
77 }
78}
79
80#[repr(i32)]
82#[derive(Copy, Clone, PartialEq, Eq, Debug)]
83pub enum WbSubmodeId {
84 NoQuantize = 1,
86 QuantizedLow = 2,
88 QuantizedMedium = 3,
90 QuantizedHigh = 4,
92}
93
94impl From<i32> for WbSubmodeId {
95 fn from(value: i32) -> Self {
96 match value {
97 1 => WbSubmodeId::NoQuantize,
98 2 => WbSubmodeId::QuantizedLow,
99 3 => WbSubmodeId::QuantizedMedium,
100 4 => WbSubmodeId::QuantizedHigh,
101 _ => panic!("Invalid submode id"),
102 }
103 }
104}
105
106#[repr(i32)]
111#[derive(Copy, Clone, PartialEq, Eq, Debug)]
112pub enum UwbSubmodeId {
113 Only = WbSubmodeId::NoQuantize as i32,
114}
115
116impl From<i32> for UwbSubmodeId {
117 fn from(value: i32) -> Self {
118 match value {
119 1 => UwbSubmodeId::Only,
120 _ => panic!("Invalid submode id"),
121 }
122 }
123}
124
125impl ModeId {
126 pub fn get_mode(self) -> &'static SpeexMode {
127 unsafe {
128 let ptr = speex_sys::speex_lib_get_mode(self as i32);
129 let reference: &'static SpeexMode = &*ptr;
132 reference
133 }
134 }
135
136 pub fn get_frame_size(self) -> i32 {
137 unsafe {
138 let ptr = speex_sys::speex_lib_get_mode(self as i32);
139 let mut frame_size = 0;
140 let frame_size_ptr = &mut frame_size as *mut i32;
141 speex_sys::speex_mode_query(
142 ptr,
143 speex_sys::SPEEX_MODE_FRAME_SIZE,
144 frame_size_ptr as *mut c_void,
145 );
146 frame_size
147 }
148 }
149}
150
151#[derive(Copy, Clone, PartialEq, Eq, Debug)]
153pub enum ControlError {
154 UnknownRequest(i32),
157 InvalidParameter,
160}
161
162impl Display for ControlError {
163 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
164 match self {
165 ControlError::UnknownRequest(id) => {
166 write!(
167 f,
168 "Unknown request type passed to a control function ({id})"
169 )
170 }
171 ControlError::InvalidParameter => write!(f, "Invalid parameter"),
172 }
173 }
174}
175
176impl Error for ControlError {}
177
178mod private {
179 pub trait Sealed {}
180}
181
182pub trait ControlFunctions: private::Sealed {
192 fn check_error(err_code: i32, param: Option<i32>) -> Result<(), ControlError> {
195 match err_code {
196 0 => Ok(()),
197 -1 => Err(ControlError::UnknownRequest(param.unwrap())),
198 -2 => Err(ControlError::InvalidParameter),
199 _ => panic!("Unknown error code passed to make_error(), this is a bug"),
200 }
201 }
202
203 unsafe fn ctl(&mut self, request: i32, ptr: *mut c_void) -> Result<(), ControlError>;
211
212 fn get_frame_size(&mut self) -> i32 {
214 let mut state = 0;
215 let ptr = &mut state as *mut i32 as *mut c_void;
216 unsafe {
217 self.ctl(speex_sys::SPEEX_GET_FRAME_SIZE, ptr).unwrap();
218 }
219 state
220 }
221
222 fn set_vbr(&mut self, vbr: bool) {
224 let state = if vbr { 1 } else { 0 };
225 let ptr = &state as *const i32 as *mut c_void;
226 unsafe {
227 self.ctl(speex_sys::SPEEX_SET_VBR, ptr).unwrap();
228 }
229 }
230
231 fn get_vbr(&mut self) -> bool {
233 let mut state = 0;
234 let ptr = &mut state as *mut i32 as *mut c_void;
235 unsafe {
236 self.ctl(speex_sys::SPEEX_GET_VBR, ptr).unwrap();
237 }
238 state != 0
239 }
240
241 fn set_vbr_quality(&mut self, quality: f32) {
245 let ptr = &quality as *const f32 as *mut c_void;
246 unsafe {
247 self.ctl(speex_sys::SPEEX_SET_VBR_QUALITY, ptr).unwrap();
248 }
249 }
250
251 fn get_vbr_quality(&mut self) -> f32 {
253 let mut state = 0.0;
254 let ptr = &mut state as *mut f32 as *mut c_void;
255 unsafe {
256 self.ctl(speex_sys::SPEEX_GET_VBR_QUALITY, ptr).unwrap();
257 }
258 state
259 }
260
261 fn set_vad(&mut self, vad: bool) {
263 let state = if vad { 1 } else { 0 };
264 let ptr = &state as *const i32 as *mut c_void;
265 unsafe {
266 self.ctl(speex_sys::SPEEX_SET_VAD, ptr).unwrap();
267 }
268 }
269
270 fn get_vad(&mut self) -> bool {
272 let mut state = 0;
273 let ptr = &mut state as *mut i32 as *mut c_void;
274 unsafe {
275 self.ctl(speex_sys::SPEEX_GET_VAD, ptr).unwrap();
276 }
277 state != 0
278 }
279
280 fn set_abr(&mut self, abr: i32) {
282 let ptr = &abr as *const i32 as *mut c_void;
283 unsafe {
284 self.ctl(speex_sys::SPEEX_SET_ABR, ptr).unwrap();
285 }
286 }
287
288 fn get_abr(&mut self) -> i32 {
290 let mut state = 0;
291 let ptr = &mut state as *mut i32 as *mut c_void;
292 unsafe {
293 self.ctl(speex_sys::SPEEX_GET_ABR, ptr).unwrap();
294 }
295 state
296 }
297
298 fn set_quality(&mut self, quality: i32) {
302 let ptr = &quality as *const i32 as *mut c_void;
303 unsafe {
304 self.ctl(speex_sys::SPEEX_SET_QUALITY, ptr).unwrap();
305 }
306 }
307
308 fn set_bitrate(&mut self, bitrate: i32) {
310 let ptr = &bitrate as *const i32 as *mut c_void;
311 unsafe {
312 self.ctl(speex_sys::SPEEX_SET_BITRATE, ptr).unwrap();
313 }
314 }
315
316 fn get_bitrate(&mut self) -> i32 {
318 let mut state = 0;
319 let ptr = &mut state as *mut i32 as *mut c_void;
320 unsafe {
321 self.ctl(speex_sys::SPEEX_GET_BITRATE, ptr).unwrap();
322 }
323 state
324 }
325
326 fn set_sampling_rate(&mut self, samplingrate: i32) {
328 let ptr = &samplingrate as *const i32 as *mut c_void;
329 unsafe {
330 self.ctl(speex_sys::SPEEX_SET_SAMPLING_RATE, ptr).unwrap();
331 }
332 }
333
334 fn get_sampling_rate(&mut self) -> i32 {
336 let mut state = 0;
337 let ptr = &mut state as *mut i32 as *mut c_void;
338 unsafe {
339 self.ctl(speex_sys::SPEEX_GET_SAMPLING_RATE, ptr).unwrap();
340 }
341 state
342 }
343
344 fn reset_state(&mut self) {
346 unsafe {
347 self.ctl(speex_sys::SPEEX_RESET_STATE, std::ptr::null_mut())
348 .unwrap();
349 }
350 }
351
352 fn set_submode_encoding(&mut self, submode: bool) {
356 let state = if submode { 1 } else { 0 };
357 let ptr = &state as *const i32 as *mut c_void;
358 unsafe {
359 self.ctl(speex_sys::SPEEX_SET_SUBMODE_ENCODING, ptr)
360 .unwrap();
361 }
362 }
363
364 fn get_submode_encoding(&mut self) -> bool {
366 let mut state = 0;
367 let ptr = &mut state as *mut i32 as *mut c_void;
368 unsafe {
369 self.ctl(speex_sys::SPEEX_GET_SUBMODE_ENCODING, ptr)
370 .unwrap();
371 }
372 state != 0
373 }
374
375 fn get_lookahead(&mut self) -> i32 {
380 let mut state = 0;
381 let ptr = &mut state as *mut i32 as *mut c_void;
382 unsafe {
383 self.ctl(speex_sys::SPEEX_GET_LOOKAHEAD, ptr).unwrap();
384 }
385 state
386 }
387
388 fn set_plc_tuning(&mut self, tuning: i32) {
390 let ptr = &tuning as *const i32 as *mut c_void;
391 unsafe {
392 self.ctl(speex_sys::SPEEX_SET_PLC_TUNING, ptr).unwrap();
393 }
394 }
395
396 fn get_plc_tuning(&mut self) -> i32 {
398 let mut state = 0;
399 let ptr = &mut state as *mut i32 as *mut c_void;
400 unsafe {
401 self.ctl(speex_sys::SPEEX_GET_PLC_TUNING, ptr).unwrap();
402 }
403 state
404 }
405
406 fn set_vbr_max_bitrate(&mut self, max_bitrate: i32) {
408 let ptr = &max_bitrate as *const i32 as *mut c_void;
409 unsafe {
410 self.ctl(speex_sys::SPEEX_SET_VBR_MAX_BITRATE, ptr).unwrap();
411 }
412 }
413
414 fn get_vbr_max_bitrate(&mut self) -> i32 {
416 let mut state = 0;
417 let ptr = &mut state as *mut i32 as *mut c_void;
418 unsafe {
419 self.ctl(speex_sys::SPEEX_GET_VBR_MAX_BITRATE, ptr).unwrap();
420 }
421 state
422 }
423
424 fn set_highpass(&mut self, highpass: bool) {
426 let state = if highpass { 1 } else { 0 };
427 let ptr = &state as *const i32 as *mut c_void;
428 unsafe {
429 self.ctl(speex_sys::SPEEX_SET_HIGHPASS, ptr).unwrap();
430 }
431 }
432
433 fn get_highpass(&mut self) -> bool {
435 let mut state = 0;
436 let ptr = &mut state as *mut i32 as *mut c_void;
437 unsafe {
438 self.ctl(speex_sys::SPEEX_GET_HIGHPASS, ptr).unwrap();
439 }
440 state != 0
441 }
442}
443
444#[macro_export]
445macro_rules! dynamic_mapping {
446 ($name:expr, $enum_name:ident, $inner:pat => $action:expr) => {
447 match $name {
448 $enum_name::Nb($inner) => $action,
449 $enum_name::Wb($inner) => $action,
450 $enum_name::Uwb($inner) => $action,
451 }
452 };
453}
454
455#[macro_export]
456macro_rules! shared_functions {
457 ($enum_name:ident) => {
458 pub fn get_frame_size(&mut self) -> i32 {
460 dynamic_mapping!(self, $enum_name, inner => inner.get_frame_size())
461 }
462
463 pub fn set_vbr(&mut self, vbr: bool) {
465 dynamic_mapping!(self, $enum_name, inner => inner.set_vbr(vbr))
466 }
467
468 pub fn get_vbr(&mut self) -> bool {
470 dynamic_mapping!(self, $enum_name, inner => inner.get_vbr())
471 }
472
473 pub fn set_vbr_quality(&mut self, quality: f32) {
477 dynamic_mapping!(self, $enum_name, inner => inner.set_vbr_quality(quality))
478 }
479
480 pub fn get_vbr_quality(&mut self) -> f32 {
482 dynamic_mapping!(self, $enum_name, inner => inner.get_vbr_quality())
483 }
484
485 pub fn set_vad(&mut self, vad: bool) {
487 dynamic_mapping!(self, $enum_name, inner => inner.set_vad(vad))
488 }
489
490 pub fn get_vad(&mut self) -> bool {
492 dynamic_mapping!(self, $enum_name, inner => inner.get_vad())
493 }
494
495 pub fn set_abr(&mut self, abr: i32) {
497 dynamic_mapping!(self, $enum_name, inner => inner.set_abr(abr))
498 }
499
500 pub fn get_abr(&mut self) -> i32 {
502 dynamic_mapping!(self, $enum_name, inner => inner.get_abr())
503 }
504
505 pub fn set_quality(&mut self, quality: i32) {
509 dynamic_mapping!(self, $enum_name, inner => inner.set_quality(quality))
510 }
511
512 pub fn set_bitrate(&mut self, bitrate: i32) {
514 dynamic_mapping!(self, $enum_name, inner => inner.set_bitrate(bitrate))
515 }
516
517 pub fn get_bitrate(&mut self) -> i32 {
519 dynamic_mapping!(self, $enum_name, inner => inner.get_bitrate())
520 }
521
522 pub fn set_sampling_rate(&mut self, samplingrate: i32) {
524 dynamic_mapping!(self, $enum_name, inner => inner.set_sampling_rate(samplingrate))
525 }
526
527 pub fn get_sampling_rate(&mut self) -> i32 {
529 dynamic_mapping!(self, $enum_name, inner => inner.get_sampling_rate())
530 }
531
532 pub fn reset_state(&mut self) {
534 dynamic_mapping!(self, $enum_name, inner => inner.reset_state())
535 }
536
537 pub fn set_submode_encoding(&mut self, submode: bool) {
541 dynamic_mapping!(self, $enum_name, inner => inner.set_submode_encoding(submode))
542 }
543
544 pub fn get_submode_encoding(&mut self) -> bool {
546 dynamic_mapping!(self, $enum_name, inner => inner.get_submode_encoding())
547 }
548
549 pub fn get_lookahead(&mut self) -> i32 {
554 dynamic_mapping!(self, $enum_name, inner => inner.get_lookahead())
555 }
556
557 pub fn set_plc_tuning(&mut self, tuning: i32) {
559 dynamic_mapping!(self, $enum_name, inner => inner.set_plc_tuning(tuning))
560 }
561
562 pub fn get_plc_tuning(&mut self) -> i32 {
564 dynamic_mapping!(self, $enum_name, inner => inner.get_plc_tuning())
565 }
566
567 pub fn set_vbr_max_bitrate(&mut self, max_bitrate: i32) {
569 dynamic_mapping!(self, $enum_name, inner => inner.set_vbr_max_bitrate(max_bitrate))
570 }
571
572 pub fn get_vbr_max_bitrate(&mut self) -> i32 {
574 dynamic_mapping!(self, $enum_name, inner => inner.get_vbr_max_bitrate())
575 }
576
577 pub fn set_highpass(&mut self, highpass: bool) {
579 dynamic_mapping!(self, $enum_name, inner => inner.set_highpass(highpass))
580 }
581
582 pub fn get_highpass(&mut self) -> bool {
584 dynamic_mapping!(self, $enum_name, inner => inner.get_highpass())
585 }
586 };
587}
588
589pub trait CoderMode {}
591
592pub enum NbMode {}
596impl CoderMode for NbMode {}
597pub enum WbMode {}
601impl CoderMode for WbMode {}
602pub enum UwbMode {}
606impl CoderMode for UwbMode {}