speex_safe/mode/
decoder.rs

1////////////////////////////////////////////////////////////////////////////////
2// Copyright (c) 2023.                                                         /
3// This Source Code Form is subject to the terms of the Mozilla Public License,/
4// v. 2.0. If a copy of the MPL was not distributed with this file, You can    /
5// obtain one at http://mozilla.org/MPL/2.0/.                                  /
6////////////////////////////////////////////////////////////////////////////////
7
8use std::ffi::c_void;
9use std::fmt::{Display, Formatter};
10use std::marker::{PhantomData, PhantomPinned};
11
12use speex_sys::SpeexMode;
13
14use crate::mode::{CoderMode, ControlFunctions, ModeId};
15use crate::{
16    dynamic_mapping,
17    mode,
18    shared_functions,
19    ControlError,
20    NbMode,
21    NbSubmodeId,
22    SpeexBits,
23    UwbMode,
24    WbMode,
25    WbSubmodeId,
26};
27
28/// Handle for the encoder, speex represents this as an opaque pointer so this
29/// is an unconstructable type that is always intended to be behind a pointer.
30#[repr(C)]
31pub struct SpeexDecoderHandle {
32    _data: [u8; 0],
33    _marker: PhantomData<(*mut u8, PhantomPinned)>,
34}
35
36impl SpeexDecoderHandle {
37    /// Create a new decoder handle for the given mode.
38    ///
39    /// # Safety
40    ///
41    /// This allocates, so you *must* call SpeexDecoderHandle::destroy with the
42    /// handle when created once you are done with the handle.
43    pub unsafe fn create(mode: &SpeexMode) -> *mut Self {
44        let ptr = unsafe {
45            let mode_ptr = mode as *const SpeexMode;
46            speex_sys::speex_decoder_init(mode_ptr)
47        };
48        ptr as *mut SpeexDecoderHandle
49    }
50
51    /// Destroys a SpeexDecoderHandle
52    ///
53    /// # Safety
54    ///
55    /// This function must *only* be called on a handle that was created with
56    /// `SpeexDecoderHandle::create`. It shouldn't be called on an already
57    /// destroyed handle.
58    pub unsafe fn destroy(handle: *mut SpeexDecoderHandle) {
59        unsafe {
60            speex_sys::speex_decoder_destroy(handle as *mut c_void);
61        }
62    }
63}
64
65/// A struct representing a speex decoder.
66pub struct SpeexDecoder<T: CoderMode> {
67    encoder_handle: *mut SpeexDecoderHandle,
68    pub mode: &'static SpeexMode,
69    _phantom: PhantomData<T>,
70}
71
72impl<T: CoderMode> mode::private::Sealed for SpeexDecoder<T> {}
73
74impl<T: CoderMode> ControlFunctions for SpeexDecoder<T> {
75    unsafe fn ctl(&mut self, request: i32, ptr: *mut c_void) -> Result<(), ControlError> {
76        let result = speex_sys::speex_decoder_ctl(self.encoder_handle as *mut c_void, request, ptr);
77        Self::check_error(result, Some(request))
78    }
79}
80
81#[derive(Copy, Clone, PartialEq, Eq, Debug)]
82pub enum DecoderError {
83    TooSmallBuffer,
84    EndOfStream,
85    CorruptStream,
86}
87
88impl Display for DecoderError {
89    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
90        match self {
91            DecoderError::TooSmallBuffer => write!(f, "Buffer is too small to decode into"),
92            DecoderError::EndOfStream => write!(f, "End of stream reached while decoding"),
93            DecoderError::CorruptStream => write!(f, "Corrupt stream was unable to be decoded"),
94        }
95    }
96}
97
98impl<T: CoderMode> SpeexDecoder<T> {
99    /// Set whether to use enhancement.
100    pub fn set_enhancement(&mut self, state: bool) {
101        let state = state as i32;
102        let ptr = &state as *const i32 as *mut c_void;
103        unsafe {
104            self.ctl(speex_sys::SPEEX_SET_ENH, ptr).unwrap();
105        }
106    }
107
108    /// Get whether enhancement is turned on or not.
109    pub fn get_enhancement(&mut self) -> bool {
110        let mut state = 0;
111        let ptr = &mut state as *mut i32 as *mut c_void;
112        unsafe {
113            self.ctl(speex_sys::SPEEX_GET_ENH, ptr).unwrap();
114        }
115        state != 0
116    }
117
118    /// Decode one frame of speex data from the bitstream
119    pub fn decode(&mut self, bits: &mut SpeexBits, out: &mut [f32]) -> Result<(), DecoderError> {
120        let frame_size = self.get_frame_size() as usize;
121        if out.len() < frame_size {
122            return Err(DecoderError::TooSmallBuffer);
123        }
124        let out_ptr = out.as_mut_ptr();
125        let bits_ptr = bits.backing_mut_ptr();
126        let result = unsafe {
127            speex_sys::speex_decode(self.encoder_handle as *mut c_void, bits_ptr, out_ptr)
128        };
129        match result {
130            0 => Ok(()),
131            -1 => Err(DecoderError::EndOfStream),
132            -2 => Err(DecoderError::CorruptStream),
133            _ => panic!("Unexpected return value from speex_decode"),
134        }
135    }
136
137    /// Decode one frame of speex data from the bitstream into a new Vec<f32>
138    pub fn decode_to_owned(&mut self, bits: &mut SpeexBits) -> Result<Vec<f32>, DecoderError> {
139        let frame_size = self.get_frame_size() as usize;
140        let mut out = vec![0.0; frame_size];
141        self.decode(bits, &mut out)?;
142        Ok(out)
143    }
144
145    /// Decode one frame of speex data from the bitstream, as i16
146    pub fn decode_int(
147        &mut self,
148        bits: &mut SpeexBits,
149        out: &mut [i16],
150    ) -> Result<(), DecoderError> {
151        let frame_size = self.get_frame_size() as usize;
152        if out.len() < frame_size {
153            return Err(DecoderError::TooSmallBuffer);
154        }
155        let out_ptr = out.as_mut_ptr();
156        let bits_ptr = bits.backing_mut_ptr();
157        let result = unsafe {
158            speex_sys::speex_decode_int(self.encoder_handle as *mut c_void, bits_ptr, out_ptr)
159        };
160        match result {
161            0 => Ok(()),
162            -1 => Err(DecoderError::EndOfStream),
163            -2 => Err(DecoderError::CorruptStream),
164            _ => panic!("Unexpected return value from speex_decode"),
165        }
166    }
167
168    /// Decode one frame of speex data from the bitstream into a new Vec<i16>
169    pub fn decode_int_to_owned(&mut self, bits: &mut SpeexBits) -> Result<Vec<i16>, DecoderError> {
170        let frame_size = self.get_frame_size() as usize;
171        let mut out = vec![0; frame_size];
172        self.decode_int(bits, &mut out)?;
173        Ok(out)
174    }
175
176    fn get_low_submode_internal(&mut self) -> NbSubmodeId {
177        let mut low_mode = 0;
178        let ptr = &mut low_mode as *mut i32 as *mut c_void;
179        unsafe {
180            self.ctl(speex_sys::SPEEX_GET_LOW_MODE, ptr).unwrap();
181        }
182        low_mode.into()
183    }
184
185    fn set_low_submode_internal(&mut self, low_mode: NbSubmodeId) {
186        let low_mode = low_mode as i32;
187        let ptr = &low_mode as *const i32 as *mut c_void;
188        unsafe {
189            self.ctl(speex_sys::SPEEX_SET_LOW_MODE, ptr).unwrap();
190        }
191    }
192
193    fn set_high_submode_internal(&mut self, high_mode: WbSubmodeId) {
194        let high_mode = high_mode as i32;
195        let ptr = &high_mode as *const i32 as *mut c_void;
196        unsafe {
197            self.ctl(speex_sys::SPEEX_SET_HIGH_MODE, ptr).unwrap();
198        }
199    }
200
201    fn get_high_submode_internal(&mut self) -> WbSubmodeId {
202        let mut high_mode = 0;
203        let ptr = &mut high_mode as *mut i32 as *mut c_void;
204        unsafe {
205            self.ctl(speex_sys::SPEEX_GET_HIGH_MODE, ptr).unwrap();
206        }
207        high_mode.into()
208    }
209}
210
211impl SpeexDecoder<NbMode> {
212    /// Create a new narrowband encoder.
213    pub fn new() -> SpeexDecoder<NbMode> {
214        let mode = ModeId::NarrowBand.get_mode();
215        let encoder_handle = unsafe { SpeexDecoderHandle::create(mode) };
216        Self {
217            encoder_handle,
218            mode,
219            _phantom: PhantomData,
220        }
221    }
222
223    /// Sets the submode to use for encoding.
224    pub fn set_submode(&mut self, submode: NbSubmodeId) {
225        self.set_low_submode_internal(submode);
226    }
227
228    /// Gets the submode currently in use for encoding.
229    pub fn get_submode(&mut self) -> NbSubmodeId {
230        self.get_low_submode_internal()
231    }
232}
233
234impl Default for SpeexDecoder<NbMode> {
235    fn default() -> Self {
236        Self::new()
237    }
238}
239
240impl SpeexDecoder<WbMode> {
241    /// Create a new WideBand encoder.
242    pub fn new() -> SpeexDecoder<WbMode> {
243        let mode = ModeId::WideBand.get_mode();
244        let encoder_handle = unsafe { SpeexDecoderHandle::create(mode) };
245        Self {
246            encoder_handle,
247            mode,
248            _phantom: PhantomData,
249        }
250    }
251
252    /// Sets the submode of the narrowband part of the encoder.
253    pub fn set_low_submode(&mut self, low_mode: NbSubmodeId) {
254        self.set_low_submode_internal(low_mode);
255    }
256
257    /// Gets the submode of the narrowband part of the encoder.
258    pub fn get_low_submode(&mut self) -> NbSubmodeId {
259        self.get_low_submode_internal()
260    }
261
262    /// Sets the submode of the wideband part of the encoder.
263    pub fn set_high_submode(&mut self, high_mode: WbSubmodeId) {
264        self.set_high_submode_internal(high_mode);
265    }
266
267    /// Gets the submode of the wideband part of the encoder.
268    pub fn get_high_submode(&mut self) -> WbSubmodeId {
269        self.get_high_submode_internal()
270    }
271}
272
273impl Default for SpeexDecoder<WbMode> {
274    fn default() -> Self {
275        Self::new()
276    }
277}
278
279impl SpeexDecoder<UwbMode> {
280    /// Create a new Ultra WideBand encoder.
281    pub fn new() -> SpeexDecoder<UwbMode> {
282        let mode = ModeId::UltraWideBand.get_mode();
283        let encoder_handle = unsafe { SpeexDecoderHandle::create(mode) };
284        Self {
285            encoder_handle,
286            mode,
287            _phantom: PhantomData,
288        }
289    }
290
291    /// Sets the submode of the narrowband part of the encoder.
292    pub fn set_low_submode(&mut self, low_mode: NbSubmodeId) {
293        self.set_low_submode_internal(low_mode);
294    }
295
296    /// Gets the submode of the narrowband part of the encoder.
297    pub fn get_low_submode(&mut self) -> NbSubmodeId {
298        self.get_low_submode_internal()
299    }
300}
301
302impl Default for SpeexDecoder<UwbMode> {
303    fn default() -> Self {
304        Self::new()
305    }
306}
307
308impl<T: CoderMode> Drop for SpeexDecoder<T> {
309    fn drop(&mut self) {
310        unsafe { SpeexDecoderHandle::destroy(self.encoder_handle) }
311    }
312}
313
314/// An enumeration over the different encoder modes.
315/// For usecases where the decoder mode is not known at compile time.
316pub enum DynamicDecoder {
317    Nb(SpeexDecoder<NbMode>),
318    Wb(SpeexDecoder<WbMode>),
319    Uwb(SpeexDecoder<UwbMode>),
320}
321
322impl DynamicDecoder {
323    shared_functions!(DynamicDecoder);
324
325    /// Set whether to use enhancement.
326    pub fn set_enhancement(&mut self, state: bool) {
327        dynamic_mapping!(self, DynamicDecoder, inner => inner.set_enhancement(state))
328    }
329
330    /// Get whether enhancement is turned on or not.
331    pub fn get_enhancement(&mut self) -> bool {
332        dynamic_mapping!(self, DynamicDecoder, inner => inner.get_enhancement())
333    }
334
335    /// Decode one frame of speex data from the bitstream
336    pub fn decode(&mut self, bits: &mut SpeexBits, out: &mut [f32]) -> Result<(), DecoderError> {
337        match self {
338            DynamicDecoder::Nb(inner) => inner.decode(bits, out),
339            DynamicDecoder::Wb(inner) => inner.decode(bits, out),
340            DynamicDecoder::Uwb(inner) => inner.decode(bits, out),
341        }
342    }
343
344    /// Decode one frame of speex data from the bitstream into a new Vec<f32>
345    pub fn decode_to_owned(&mut self, bits: &mut SpeexBits) -> Result<Vec<f32>, DecoderError> {
346        match self {
347            DynamicDecoder::Nb(inner) => inner.decode_to_owned(bits),
348            DynamicDecoder::Wb(inner) => inner.decode_to_owned(bits),
349            DynamicDecoder::Uwb(inner) => inner.decode_to_owned(bits),
350        }
351    }
352
353    /// Decode one frame of speex data from the bitstream, as i16
354    pub fn decode_int(
355        &mut self,
356        bits: &mut SpeexBits,
357        out: &mut [i16],
358    ) -> Result<(), DecoderError> {
359        match self {
360            DynamicDecoder::Nb(inner) => inner.decode_int(bits, out),
361            DynamicDecoder::Wb(inner) => inner.decode_int(bits, out),
362            DynamicDecoder::Uwb(inner) => inner.decode_int(bits, out),
363        }
364    }
365
366    /// Decode one frame of speex data from the bitstream into a new Vec<i16>
367    pub fn decode_int_to_owned(&mut self, bits: &mut SpeexBits) -> Result<Vec<i16>, DecoderError> {
368        match self {
369            DynamicDecoder::Nb(inner) => inner.decode_int_to_owned(bits),
370            DynamicDecoder::Wb(inner) => inner.decode_int_to_owned(bits),
371            DynamicDecoder::Uwb(inner) => inner.decode_int_to_owned(bits),
372        }
373    }
374
375    pub fn new(mode: ModeId) -> DynamicDecoder {
376        match mode {
377            ModeId::NarrowBand => DynamicDecoder::Nb(SpeexDecoder::<NbMode>::new()),
378            ModeId::WideBand => DynamicDecoder::Wb(SpeexDecoder::<WbMode>::new()),
379            ModeId::UltraWideBand => DynamicDecoder::Uwb(SpeexDecoder::<UwbMode>::new()),
380        }
381    }
382
383    pub fn into_nb(self) -> Option<SpeexDecoder<NbMode>> {
384        match self {
385            DynamicDecoder::Nb(nb) => Some(nb),
386            _ => None,
387        }
388    }
389
390    pub fn into_wb(self) -> Option<SpeexDecoder<WbMode>> {
391        match self {
392            DynamicDecoder::Wb(wb) => Some(wb),
393            _ => None,
394        }
395    }
396
397    pub fn into_uwb(self) -> Option<SpeexDecoder<UwbMode>> {
398        match self {
399            DynamicDecoder::Uwb(uwb) => Some(uwb),
400            _ => None,
401        }
402    }
403}