opusic_c/multistream/
decoder.rs

1use crate::{sys, mem, ErrorCode, SampleRate, Bandwidth};
2use super::Config;
3
4use core::ptr;
5
6use mem::alloc::vec::Vec;
7
8///OPUS multistream decoder
9///
10pub struct Decoder {
11    inner: mem::Unique<sys::OpusMSDecoder>,
12    channels: u8,
13}
14
15impl Decoder {
16    ///Creates new encoder instance
17    ///
18    ///## Notes
19    ///
20    ///### Mapping
21    ///
22    ///`config.mapping` table defines which decoded channel i should be used for each input/output (I/O) channel j.
23    ///
24    ///Let `i` = `mapping[j]` be the index for I/O channel `j`.
25    ///
26    ///If `i` < `2*coupled_streams`, then I/O channel `j` is encoded as the left channel of stream `(i/2)` if `i` is even,
27    ///or as the right channel of stream `(i/2)` if `i` is odd.
28    ///
29    ///Otherwise, I/O channel `j` is encoded as mono in stream `(i - coupled_streams)`,
30    ///unless it has the special value **255**,
31    ///in which case it is omitted from the encoding entirely (the decoder will reproduce it as silence).
32    ///
33    ///Each value `i` must either be the special value **255** or be less than `streams + coupled_streams`.
34    pub fn new<const CH: usize>(config: Config<CH>, rate: SampleRate) -> Result<Self, ErrorCode> {
35        let size = unsafe {
36            sys::opus_multistream_decoder_get_size(config.streams as _, config.coupled_streams as _)
37        };
38
39        if size == 0 {
40            return Err(ErrorCode::Internal);
41        }
42
43        let mut decoder = match mem::Unique::new(size as _) {
44            Some(inner) => Self {
45                inner,
46                channels: CH as _,
47            },
48            None => return Err(ErrorCode::AllocFail)
49        };
50
51        let result = unsafe {
52            sys::opus_multistream_decoder_init(decoder.inner.as_mut(), rate as _, CH as _, config.streams as _, config.coupled_streams as _, config.mapping.as_ptr() as _)
53        };
54
55        map_sys_error!(result => decoder)
56    }
57
58    #[inline]
59    ///Resets state to initial
60    pub fn reset(&mut self) -> Result<(), ErrorCode> {
61        let result = unsafe {
62            sys::opus_multistream_decoder_ctl(self.inner.as_mut(), sys::OPUS_RESET_STATE)
63        };
64
65        map_sys_error!(result => ())
66    }
67
68    ///Decodes input packet, returning number of decoded samples.
69    ///
70    ///If more than 1 channel is configured, then input must be interleaved.
71    ///
72    ///Output size must correspond to sampling rate.
73    ///For example, at 48 kHz allowed frame sizes are 120, 240, 480, 960, 1920, and 2880.
74    ///
75    ///Maximum packet duration is 120ms therefore maximum `frame size` must be
76    ///`frame_bytes_size(SampleRate::Hz48000, Channels::Stereo, 120)`
77    ///
78    ///When `input` size is 0, libopus shall treat it as packet loss, in which case `output` size must
79    ///match expected output of next packet to know how much frames is skipped
80    ///
81    ///When `decode_fec` is `true`, requests that any in-band forward error correction data be decoded.
82    ///If no such data is available, the frame is decoded as if it were lost.
83    pub fn decode_to(&mut self, input: &[u8], output: &mut [mem::MaybeUninit<u16>], decode_fec: bool) -> Result<usize, ErrorCode> {
84        let (input_ptr, input_len) = match input.len() {
85            0 => (ptr::null(), 0),
86            len => (input.as_ptr(), len as _)
87        };
88
89        let fec = match decode_fec {
90            true => 1,
91            false => 0,
92        };
93        let result = unsafe {
94            sys::opus_multistream_decode(self.inner.as_mut(),
95                                         input_ptr, input_len,
96                                         output.as_mut_ptr() as _, (output.len() / self.channels as usize) as _,
97                                         fec)
98        };
99
100        map_sys_error!(result => result as _)
101    }
102
103    #[inline(always)]
104    ///Decodes input packet, returning number of decoded samples.
105    ///
106    ///Refer to `decode_to` for details
107    pub fn decode_to_slice(&mut self, input: &[u8], output: &mut [u16], decode_fec: bool) -> Result<usize, ErrorCode> {
108        self.decode_to(input, unsafe { mem::transmute(output) }, decode_fec)
109    }
110
111    #[inline(always)]
112    ///Decodes input packet, returning number of decoded samples.
113    ///
114    ///Vector will be written into spare capacity, modifying its length on success.
115    ///
116    ///`decode_len` is used to reserve additional memory and will be passed exactly with this size to `decode_to`
117    ///
118    ///Refer to `decode_to` for details
119    pub fn decode_to_vec(&mut self, input: &[u8], output: &mut Vec<u16>, decode_len: usize, decode_fec: bool) -> Result<usize, ErrorCode> {
120        let initial_len = output.len();
121
122        if output.try_reserve(decode_len).is_err() {
123            return Err(ErrorCode::alloc_fail())
124        }
125
126        let result = self.decode_to(input, &mut output.spare_capacity_mut()[..decode_len], decode_fec)?;
127        unsafe {
128            output.set_len(initial_len + result);
129        }
130        Ok(result)
131    }
132
133    ///Decodes input packet, returning number of decoded samples.
134    ///
135    ///If more than 1 channel is configured, then input must be interleaved.
136    ///
137    ///Output size must correspond to sampling rate.
138    ///For example, at 48 kHz allowed frame sizes are 120, 240, 480, 960, 1920, and 2880.
139    ///
140    ///Maximum packet duration is 120ms therefore maximum `frame size` must be
141    ///`frame_bytes_size(SampleRate::Hz48000, Channels::Stereo, 120)`
142    ///
143    ///When `input` size is 0, libopus shall treat it as packet loss, in which case `output` size must
144    ///match expected output of next packet to know how much frames is skipped
145    ///
146    ///When `decode_fec` is `true`, requests that any in-band forward error correction data be decoded.
147    ///If no such data is available, the frame is decoded as if it were lost.
148    pub fn decode_float_to(&mut self, input: &[u8], output: &mut [mem::MaybeUninit<f32>], decode_fec: bool) -> Result<usize, ErrorCode> {
149        let (input_ptr, input_len) = match input.len() {
150            0 => (ptr::null(), 0),
151            len => (input.as_ptr(), len as _)
152        };
153        let fec = match decode_fec {
154            true => 1,
155            false => 0,
156        };
157
158        let result = unsafe {
159            sys::opus_multistream_decode_float(self.inner.as_mut(),
160                                               input_ptr, input_len,
161                                               output.as_mut_ptr() as _, (output.len() / self.channels as usize) as _,
162                                               fec)
163        };
164
165        map_sys_error!(result => result as _)
166    }
167
168    #[inline(always)]
169    ///Decodes input packet, returning number of decoded samples.
170    ///
171    ///Refer to `decode_to` for details
172    pub fn decode_float_to_slice(&mut self, input: &[u8], output: &mut [f32], decode_fec: bool) -> Result<usize, ErrorCode> {
173        self.decode_float_to(input, unsafe { mem::transmute(output) }, decode_fec)
174    }
175
176    #[inline(always)]
177    ///Decodes input packet, returning number of decoded samples.
178    ///
179    ///Vector will be written into spare capacity, modifying its length on success.
180    ///
181    ///`decode_len` is used to reserve additional memory and will be passed exactly with this size to `decode_to`
182    ///
183    ///Refer to `decode_to` for details
184    pub fn decode_float_to_vec(&mut self, input: &[u8], output: &mut Vec<f32>, decode_len: usize, decode_fec: bool) -> Result<usize, ErrorCode> {
185        let initial_len = output.len();
186
187        if output.try_reserve(decode_len).is_err() {
188            return Err(ErrorCode::alloc_fail())
189        }
190
191        let result = self.decode_float_to(input, &mut output.spare_capacity_mut()[..decode_len], decode_fec)?;
192        unsafe {
193            output.set_len(initial_len + result);
194        }
195        Ok(result)
196    }
197
198    #[inline]
199    ///Gets the duration (in samples) of the last packet successfully decoded or concealed.
200    pub fn get_last_packet_duration(&mut self) -> Result<u32, ErrorCode> {
201        let mut value: i32 = 0;
202        let result = unsafe {
203            sys::opus_multistream_decoder_ctl(self.inner.as_mut(), sys::OPUS_GET_LAST_PACKET_DURATION_REQUEST, &mut value)
204        };
205
206        map_sys_error!(result => value as _)
207    }
208
209    #[inline]
210    ///Gets the decoder's gain configuration
211    pub fn get_gain(&mut self) -> Result<i32, ErrorCode> {
212        let mut value: i32 = 0;
213        let result = unsafe {
214            sys::opus_multistream_decoder_ctl(self.inner.as_mut(), sys::OPUS_GET_GAIN_REQUEST, &mut value)
215        };
216
217        map_sys_error!(result => value)
218    }
219
220    #[inline]
221    ///Configures decoder gain adjustment.
222    ///
223    ///Scales the decoded output by a factor specified in Q8 dB units.
224    ///This has a maximum range of -32768 to 32767 inclusive, and returns `BadArg` otherwise.
225    ///
226    ///The default is zero indicating no adjustment.
227    ///
228    ///_This setting survives decoder reset_.
229    ///
230    ///Formula:
231    ///
232    ///`gain = pow(10, x/(20.0*256))`
233    pub fn set_gain(&mut self, value: i32) -> Result<(), ErrorCode> {
234        let result = unsafe {
235            sys::opus_multistream_decoder_ctl(self.inner.as_mut(), sys::OPUS_SET_GAIN_REQUEST, value)
236        };
237
238        map_sys_error!(result => ())
239    }
240
241    #[inline]
242    ///Gets the decoder's last bandpass
243    pub fn get_bandwidth(&mut self) -> Result<Bandwidth, ErrorCode> {
244        let mut value: i32 = 0;
245        let result = unsafe {
246            sys::opus_multistream_decoder_ctl(self.inner.as_mut(), sys::OPUS_GET_BANDWIDTH_REQUEST, &mut value)
247        };
248
249        map_sys_error!(result => value.into())
250    }
251
252    #[inline]
253    ///Gets configured sample rate of this instance
254    pub fn get_sample_rate(&mut self) -> Result<SampleRate, ErrorCode> {
255        let mut value: i32 = 0;
256        let result = unsafe {
257            sys::opus_multistream_decoder_ctl(self.inner.as_mut(), sys::OPUS_GET_SAMPLE_RATE_REQUEST, &mut value)
258        };
259
260        map_sys_error!(result => match value {
261            8000 => SampleRate::Hz8000,
262            12000 => SampleRate::Hz12000,
263            16000 => SampleRate::Hz16000,
264            24000 => SampleRate::Hz24000,
265            48000 => SampleRate::Hz48000,
266            _ => return Err(ErrorCode::unknown())
267        })
268    }
269
270    #[inline]
271    ///Gets the decoder's configured phase inversion status.
272    pub fn get_phase_inversion_disabled(&mut self) -> Result<bool, ErrorCode> {
273        let mut value: i32 = 0;
274        let result = unsafe {
275            sys::opus_multistream_decoder_ctl(self.inner.as_mut(), sys::OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, &mut value)
276        };
277
278        map_sys_error!(result => value == 1)
279    }
280
281    #[inline]
282    ///Configures phase inversion.
283    ///
284    ///If set to `true`, disables the use of phase inversion for intensity stereo, improving the quality
285    ///of mono downmixes, but slightly reducing normal stereo quality.
286    ///
287    ///Disabling phase inversion in the decoder does not comply with RFC 6716, although it does not
288    ///cause any interoperability issue and is expected to become part of the Opus standard once
289    ///RFC 6716 is updated by draft-ietf-codec-opus-update.
290    pub fn set_phase_inversion_disabled(&mut self, value: bool) -> Result<(), ErrorCode> {
291        let value: i32 = match value {
292            true => 1,
293            false => 0,
294        };
295
296        let result = unsafe {
297            sys::opus_multistream_decoder_ctl(self.inner.as_mut(), sys::OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, value)
298        };
299
300        map_sys_error!(result => ())
301    }
302}