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}