1#[cfg(feature = "dred")]
4use crate::bindings::{
5 OPUS_GET_DRED_DURATION_REQUEST, OPUS_SET_DNN_BLOB_REQUEST, OPUS_SET_DRED_DURATION_REQUEST,
6};
7use crate::bindings::{
8 OPUS_GET_FINAL_RANGE_REQUEST, OPUS_GET_GAIN_REQUEST, OPUS_GET_LAST_PACKET_DURATION_REQUEST,
9 OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_GET_PITCH_REQUEST,
10 OPUS_GET_SAMPLE_RATE_REQUEST, OPUS_RESET_STATE, OPUS_SET_GAIN_REQUEST,
11 OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, OpusDecoder, opus_decode, opus_decode_float,
12 opus_decoder_create, opus_decoder_ctl, opus_decoder_destroy, opus_decoder_get_nb_samples,
13};
14use crate::constants::max_frame_samples_for;
15use crate::error::{Error, Result};
16use crate::packet;
17use crate::types::{Bandwidth, Channels, SampleRate};
18use std::ptr;
19
20pub struct Decoder {
22 raw: *mut OpusDecoder,
23 sample_rate: SampleRate,
24 channels: Channels,
25}
26
27unsafe impl Send for Decoder {}
28unsafe impl Sync for Decoder {}
29
30impl Decoder {
31 pub fn new(sample_rate: SampleRate, channels: Channels) -> Result<Self> {
36 if !sample_rate.is_valid() {
38 return Err(Error::BadArg);
39 }
40
41 let mut error = 0i32;
42 let decoder = unsafe {
43 opus_decoder_create(
44 sample_rate.as_i32(),
45 channels.as_i32(),
46 std::ptr::addr_of_mut!(error),
47 )
48 };
49
50 if error != 0 {
51 return Err(Error::from_code(error));
52 }
53
54 if decoder.is_null() {
55 return Err(Error::AllocFail);
56 }
57
58 Ok(Self {
59 raw: decoder,
60 sample_rate,
61 channels,
62 })
63 }
64
65 pub fn decode(&mut self, input: &[u8], output: &mut [i16], fec: bool) -> Result<usize> {
76 if self.raw.is_null() {
78 return Err(Error::InvalidState);
79 }
80
81 if !input.is_empty() && input.len() > i32::MAX as usize {
83 return Err(Error::BadArg);
84 }
85 if output.is_empty() {
86 return Err(Error::BadArg);
87 }
88 if !output.len().is_multiple_of(self.channels.as_usize()) {
89 return Err(Error::BadArg);
90 }
91 let frame_size = output.len() / self.channels.as_usize();
92 let max_frame = max_frame_samples_for(self.sample_rate);
93 if frame_size == 0 || frame_size > max_frame {
94 return Err(Error::BadArg);
95 }
96
97 let input_len_i32 = if input.is_empty() {
98 0
99 } else {
100 i32::try_from(input.len()).map_err(|_| Error::BadArg)?
101 };
102 let frame_size_i32 = i32::try_from(frame_size).map_err(|_| Error::BadArg)?;
103
104 let result = unsafe {
105 opus_decode(
106 self.raw,
107 if input.is_empty() {
108 ptr::null()
109 } else {
110 input.as_ptr()
111 },
112 input_len_i32,
113 output.as_mut_ptr(),
114 frame_size_i32,
115 i32::from(fec),
116 )
117 };
118
119 if result < 0 {
120 return Err(Error::from_code(result));
121 }
122
123 usize::try_from(result).map_err(|_| Error::InternalError)
124 }
125
126 pub fn decode_float(&mut self, input: &[u8], output: &mut [f32], fec: bool) -> Result<usize> {
135 if self.raw.is_null() {
136 return Err(Error::InvalidState);
137 }
138
139 if !input.is_empty() && input.len() > i32::MAX as usize {
141 return Err(Error::BadArg);
142 }
143 if output.is_empty() {
144 return Err(Error::BadArg);
145 }
146 if !output.len().is_multiple_of(self.channels.as_usize()) {
147 return Err(Error::BadArg);
148 }
149 let frame_size = output.len() / self.channels.as_usize();
150 let max_frame = max_frame_samples_for(self.sample_rate);
151 if frame_size == 0 || frame_size > max_frame {
152 return Err(Error::BadArg);
153 }
154
155 let input_len_i32 = if input.is_empty() {
156 0
157 } else {
158 i32::try_from(input.len()).map_err(|_| Error::BadArg)?
159 };
160 let frame_size_i32 = i32::try_from(frame_size).map_err(|_| Error::BadArg)?;
161
162 let result = unsafe {
163 opus_decode_float(
164 self.raw,
165 if input.is_empty() {
166 ptr::null()
167 } else {
168 input.as_ptr()
169 },
170 input_len_i32,
171 output.as_mut_ptr(),
172 frame_size_i32,
173 i32::from(fec),
174 )
175 };
176
177 if result < 0 {
178 return Err(Error::from_code(result));
179 }
180
181 usize::try_from(result).map_err(|_| Error::InternalError)
182 }
183
184 pub fn packet_samples(&self, packet: &[u8]) -> Result<usize> {
190 if self.raw.is_null() {
192 return Err(Error::InvalidState);
193 }
194
195 if packet.len() > i32::MAX as usize {
196 return Err(Error::BadArg);
197 }
198 let len_i32 = i32::try_from(packet.len()).map_err(|_| Error::BadArg)?;
199 let result = unsafe { opus_decoder_get_nb_samples(self.raw, packet.as_ptr(), len_i32) };
200
201 if result < 0 {
202 return Err(Error::from_code(result));
203 }
204
205 usize::try_from(result).map_err(|_| Error::InternalError)
206 }
207
208 pub fn packet_bandwidth(&self, packet: &[u8]) -> Result<Bandwidth> {
214 if self.raw.is_null() {
216 return Err(Error::InvalidState);
217 }
218
219 packet::packet_bandwidth(packet)
220 }
221
222 pub fn packet_channels(&self, packet: &[u8]) -> Result<Channels> {
228 if self.raw.is_null() {
230 return Err(Error::InvalidState);
231 }
232
233 packet::packet_channels(packet)
234 }
235
236 pub fn reset(&mut self) -> Result<()> {
242 if self.raw.is_null() {
244 return Err(Error::InvalidState);
245 }
246
247 let result = unsafe { opus_decoder_ctl(self.raw, OPUS_RESET_STATE as i32) };
249
250 if result != 0 {
251 return Err(Error::from_code(result));
252 }
253
254 Ok(())
255 }
256
257 #[must_use]
259 pub const fn sample_rate(&self) -> SampleRate {
260 self.sample_rate
261 }
262
263 #[must_use]
265 pub const fn channels(&self) -> Channels {
266 self.channels
267 }
268
269 #[cfg_attr(not(feature = "dred"), allow(dead_code))]
270 pub(crate) fn as_mut_ptr(&mut self) -> *mut OpusDecoder {
271 self.raw
272 }
273
274 pub fn get_sample_rate(&mut self) -> Result<i32> {
279 self.get_int_ctl(OPUS_GET_SAMPLE_RATE_REQUEST as i32)
280 }
281
282 pub fn get_pitch(&mut self) -> Result<i32> {
287 self.get_int_ctl(OPUS_GET_PITCH_REQUEST as i32)
288 }
289
290 pub fn get_last_packet_duration(&mut self) -> Result<i32> {
295 self.get_int_ctl(OPUS_GET_LAST_PACKET_DURATION_REQUEST as i32)
296 }
297
298 pub fn final_range(&mut self) -> Result<u32> {
303 if self.raw.is_null() {
304 return Err(Error::InvalidState);
305 }
306 let mut v: u32 = 0;
307 let r = unsafe { opus_decoder_ctl(self.raw, OPUS_GET_FINAL_RANGE_REQUEST as i32, &mut v) };
308 if r != 0 {
309 return Err(Error::from_code(r));
310 }
311 Ok(v)
312 }
313
314 pub fn set_gain(&mut self, q8_db: i32) -> Result<()> {
319 self.simple_ctl(OPUS_SET_GAIN_REQUEST as i32, q8_db)
320 }
321 pub fn gain(&mut self) -> Result<i32> {
326 self.get_int_ctl(OPUS_GET_GAIN_REQUEST as i32)
327 }
328
329 pub fn phase_inversion_disabled(&mut self) -> Result<bool> {
334 Ok(self.get_int_ctl(OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST as i32)? != 0)
335 }
336
337 pub fn set_phase_inversion_disabled(&mut self, disabled: bool) -> Result<()> {
342 self.simple_ctl(
343 OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST as i32,
344 i32::from(disabled),
345 )
346 }
347
348 #[cfg(feature = "dred")]
349 pub fn set_dred_duration(&mut self, ms: i32) -> Result<()> {
354 self.simple_ctl(OPUS_SET_DRED_DURATION_REQUEST as i32, ms)
355 }
356 #[cfg(feature = "dred")]
357 pub fn dred_duration(&mut self) -> Result<i32> {
362 self.get_int_ctl(OPUS_GET_DRED_DURATION_REQUEST as i32)
363 }
364 #[cfg(feature = "dred")]
365 pub unsafe fn set_dnn_blob(&mut self, ptr: *const u8, len: i32) -> Result<()> {
374 if self.raw.is_null() {
375 return Err(Error::InvalidState);
376 }
377 if ptr.is_null() || len <= 0 {
378 return Err(Error::BadArg);
379 }
380 let r = unsafe { opus_decoder_ctl(self.raw, OPUS_SET_DNN_BLOB_REQUEST as i32, ptr, len) };
381 if r != 0 {
382 return Err(Error::from_code(r));
383 }
384 Ok(())
385 }
386
387 fn simple_ctl(&mut self, req: i32, val: i32) -> Result<()> {
389 if self.raw.is_null() {
390 return Err(Error::InvalidState);
391 }
392 let r = unsafe { opus_decoder_ctl(self.raw, req, val) };
393 if r != 0 {
394 return Err(Error::from_code(r));
395 }
396 Ok(())
397 }
398 fn get_int_ctl(&mut self, req: i32) -> Result<i32> {
399 if self.raw.is_null() {
400 return Err(Error::InvalidState);
401 }
402 let mut v: i32 = 0;
403 let r = unsafe { opus_decoder_ctl(self.raw, req, &mut v) };
404 if r != 0 {
405 return Err(Error::from_code(r));
406 }
407 Ok(v)
408 }
409}
410
411impl Drop for Decoder {
412 fn drop(&mut self) {
413 unsafe {
414 opus_decoder_destroy(self.raw);
415 }
416 }
417}