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 opus_decoder_get_size, opus_decoder_init,
14};
15use crate::constants::max_frame_samples_for;
16use crate::error::{Error, Result};
17use crate::packet;
18use crate::types::{Bandwidth, Channels, SampleRate};
19use crate::{AlignedBuffer, Ownership, RawHandle};
20use std::marker::PhantomData;
21use std::num::NonZeroUsize;
22use std::ops::{Deref, DerefMut};
23use std::ptr::{self, NonNull};
24
25pub struct Decoder {
27 raw: RawHandle<OpusDecoder>,
28 sample_rate: SampleRate,
29 channels: Channels,
30}
31
32unsafe impl Send for Decoder {}
33unsafe impl Sync for Decoder {}
34
35pub struct DecoderRef<'a> {
37 inner: Decoder,
38 _marker: PhantomData<&'a mut OpusDecoder>,
39}
40
41unsafe impl Send for DecoderRef<'_> {}
42unsafe impl Sync for DecoderRef<'_> {}
43
44impl Decoder {
45 fn from_raw(
46 ptr: NonNull<OpusDecoder>,
47 sample_rate: SampleRate,
48 channels: Channels,
49 ownership: Ownership,
50 ) -> Self {
51 Self {
52 raw: RawHandle::new(ptr, ownership, opus_decoder_destroy),
53 sample_rate,
54 channels,
55 }
56 }
57
58 pub fn size(channels: Channels) -> Result<usize> {
64 let raw = unsafe { opus_decoder_get_size(channels.as_i32()) };
65 if raw <= 0 {
66 return Err(Error::BadArg);
67 }
68 usize::try_from(raw).map_err(|_| Error::InternalError)
69 }
70
71 pub unsafe fn init_in_place(
80 ptr: *mut OpusDecoder,
81 sample_rate: SampleRate,
82 channels: Channels,
83 ) -> Result<()> {
84 if ptr.is_null() {
85 return Err(Error::BadArg);
86 }
87 if !crate::opus_ptr_is_aligned(ptr.cast()) {
88 return Err(Error::BadArg);
89 }
90 let r = unsafe { opus_decoder_init(ptr, sample_rate.as_i32(), channels.as_i32()) };
91 if r != 0 {
92 return Err(Error::from_code(r));
93 }
94 Ok(())
95 }
96
97 pub fn new(sample_rate: SampleRate, channels: Channels) -> Result<Self> {
102 if !sample_rate.is_valid() {
104 return Err(Error::BadArg);
105 }
106
107 let mut error = 0i32;
108 let decoder = unsafe {
109 opus_decoder_create(
110 sample_rate.as_i32(),
111 channels.as_i32(),
112 std::ptr::addr_of_mut!(error),
113 )
114 };
115
116 if error != 0 {
117 return Err(Error::from_code(error));
118 }
119
120 let decoder = NonNull::new(decoder).ok_or(Error::AllocFail)?;
121
122 Ok(Self::from_raw(
123 decoder,
124 sample_rate,
125 channels,
126 Ownership::Owned,
127 ))
128 }
129
130 pub fn decode(&mut self, input: &[u8], output: &mut [i16], fec: bool) -> Result<usize> {
141 if !input.is_empty() && input.len() > i32::MAX as usize {
144 return Err(Error::BadArg);
145 }
146 if output.is_empty() {
147 return Err(Error::BadArg);
148 }
149 if !output.len().is_multiple_of(self.channels.as_usize()) {
150 return Err(Error::BadArg);
151 }
152 let frame_size = output.len() / self.channels.as_usize();
153 let frame_size = NonZeroUsize::new(frame_size).ok_or(Error::BadArg)?;
154 let max_frame = max_frame_samples_for(self.sample_rate);
155 if frame_size.get() > max_frame {
156 return Err(Error::BadArg);
157 }
158
159 let input_len_i32 = if input.is_empty() {
160 0
161 } else {
162 i32::try_from(input.len()).map_err(|_| Error::BadArg)?
163 };
164 let frame_size_i32 = i32::try_from(frame_size.get()).map_err(|_| Error::BadArg)?;
165
166 let result = unsafe {
167 opus_decode(
168 self.raw.as_ptr(),
169 if input.is_empty() {
170 ptr::null()
171 } else {
172 input.as_ptr()
173 },
174 input_len_i32,
175 output.as_mut_ptr(),
176 frame_size_i32,
177 i32::from(fec),
178 )
179 };
180
181 if result < 0 {
182 return Err(Error::from_code(result));
183 }
184
185 usize::try_from(result).map_err(|_| Error::InternalError)
186 }
187
188 pub fn decode_float(&mut self, input: &[u8], output: &mut [f32], fec: bool) -> Result<usize> {
197 if !input.is_empty() && input.len() > i32::MAX as usize {
199 return Err(Error::BadArg);
200 }
201 if output.is_empty() {
202 return Err(Error::BadArg);
203 }
204 if !output.len().is_multiple_of(self.channels.as_usize()) {
205 return Err(Error::BadArg);
206 }
207 let frame_size = output.len() / self.channels.as_usize();
208 let frame_size = NonZeroUsize::new(frame_size).ok_or(Error::BadArg)?;
209 let max_frame = max_frame_samples_for(self.sample_rate);
210 if frame_size.get() > max_frame {
211 return Err(Error::BadArg);
212 }
213
214 let input_len_i32 = if input.is_empty() {
215 0
216 } else {
217 i32::try_from(input.len()).map_err(|_| Error::BadArg)?
218 };
219 let frame_size_i32 = i32::try_from(frame_size.get()).map_err(|_| Error::BadArg)?;
220
221 let result = unsafe {
222 opus_decode_float(
223 self.raw.as_ptr(),
224 if input.is_empty() {
225 ptr::null()
226 } else {
227 input.as_ptr()
228 },
229 input_len_i32,
230 output.as_mut_ptr(),
231 frame_size_i32,
232 i32::from(fec),
233 )
234 };
235
236 if result < 0 {
237 return Err(Error::from_code(result));
238 }
239
240 usize::try_from(result).map_err(|_| Error::InternalError)
241 }
242
243 pub fn packet_samples(&self, packet: &[u8]) -> Result<usize> {
249 if packet.len() > i32::MAX as usize {
251 return Err(Error::BadArg);
252 }
253 let len_i32 = i32::try_from(packet.len()).map_err(|_| Error::BadArg)?;
254 let result =
255 unsafe { opus_decoder_get_nb_samples(self.raw.as_ptr(), packet.as_ptr(), len_i32) };
256
257 if result < 0 {
258 return Err(Error::from_code(result));
259 }
260
261 usize::try_from(result).map_err(|_| Error::InternalError)
262 }
263
264 pub fn packet_bandwidth(&self, packet: &[u8]) -> Result<Bandwidth> {
270 packet::packet_bandwidth(packet)
272 }
273
274 pub fn packet_channels(&self, packet: &[u8]) -> Result<Channels> {
280 packet::packet_channels(packet)
282 }
283
284 pub fn reset(&mut self) -> Result<()> {
290 let result = unsafe { opus_decoder_ctl(self.raw.as_ptr(), OPUS_RESET_STATE as i32) };
293
294 if result != 0 {
295 return Err(Error::from_code(result));
296 }
297
298 Ok(())
299 }
300
301 #[must_use]
303 pub const fn sample_rate(&self) -> SampleRate {
304 self.sample_rate
305 }
306
307 #[must_use]
309 pub const fn channels(&self) -> Channels {
310 self.channels
311 }
312
313 #[cfg_attr(not(feature = "dred"), allow(dead_code))]
314 pub(crate) fn as_mut_ptr(&mut self) -> *mut OpusDecoder {
315 self.raw.as_ptr()
316 }
317
318 pub fn get_sample_rate(&mut self) -> Result<i32> {
323 self.get_int_ctl(OPUS_GET_SAMPLE_RATE_REQUEST as i32)
324 }
325
326 pub fn get_pitch(&mut self) -> Result<i32> {
331 self.get_int_ctl(OPUS_GET_PITCH_REQUEST as i32)
332 }
333
334 pub fn get_last_packet_duration(&mut self) -> Result<i32> {
339 self.get_int_ctl(OPUS_GET_LAST_PACKET_DURATION_REQUEST as i32)
340 }
341
342 pub fn final_range(&mut self) -> Result<u32> {
347 let mut v: u32 = 0;
348 let r = unsafe {
349 opus_decoder_ctl(
350 self.raw.as_ptr(),
351 OPUS_GET_FINAL_RANGE_REQUEST as i32,
352 &mut v,
353 )
354 };
355 if r != 0 {
356 return Err(Error::from_code(r));
357 }
358 Ok(v)
359 }
360
361 pub fn set_gain(&mut self, q8_db: i32) -> Result<()> {
366 self.simple_ctl(OPUS_SET_GAIN_REQUEST as i32, q8_db)
367 }
368 pub fn gain(&mut self) -> Result<i32> {
373 self.get_int_ctl(OPUS_GET_GAIN_REQUEST as i32)
374 }
375
376 pub fn phase_inversion_disabled(&mut self) -> Result<bool> {
381 Ok(self.get_int_ctl(OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST as i32)? != 0)
382 }
383
384 pub fn set_phase_inversion_disabled(&mut self, disabled: bool) -> Result<()> {
389 self.simple_ctl(
390 OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST as i32,
391 i32::from(disabled),
392 )
393 }
394
395 #[cfg(feature = "dred")]
396 pub fn set_dred_duration(&mut self, ms: i32) -> Result<()> {
401 self.simple_ctl(OPUS_SET_DRED_DURATION_REQUEST as i32, ms)
402 }
403 #[cfg(feature = "dred")]
404 pub fn dred_duration(&mut self) -> Result<i32> {
409 self.get_int_ctl(OPUS_GET_DRED_DURATION_REQUEST as i32)
410 }
411 #[cfg(feature = "dred")]
412 pub unsafe fn set_dnn_blob(&mut self, ptr: *const u8, len: i32) -> Result<()> {
421 if ptr.is_null() || len <= 0 {
422 return Err(Error::BadArg);
423 }
424 let r = unsafe {
425 opus_decoder_ctl(
426 self.raw.as_ptr(),
427 OPUS_SET_DNN_BLOB_REQUEST as i32,
428 ptr,
429 len,
430 )
431 };
432 if r != 0 {
433 return Err(Error::from_code(r));
434 }
435 Ok(())
436 }
437
438 fn simple_ctl(&mut self, req: i32, val: i32) -> Result<()> {
440 let r = unsafe { opus_decoder_ctl(self.raw.as_ptr(), req, val) };
441 if r != 0 {
442 return Err(Error::from_code(r));
443 }
444 Ok(())
445 }
446 fn get_int_ctl(&mut self, req: i32) -> Result<i32> {
447 let mut v: i32 = 0;
448 let r = unsafe { opus_decoder_ctl(self.raw.as_ptr(), req, &mut v) };
449 if r != 0 {
450 return Err(Error::from_code(r));
451 }
452 Ok(v)
453 }
454}
455
456impl<'a> DecoderRef<'a> {
457 #[must_use]
467 pub unsafe fn from_raw(
468 ptr: *mut OpusDecoder,
469 sample_rate: SampleRate,
470 channels: Channels,
471 ) -> Self {
472 debug_assert!(!ptr.is_null(), "from_raw called with null ptr");
473 debug_assert!(crate::opus_ptr_is_aligned(ptr.cast()));
474 let decoder = Decoder::from_raw(
475 unsafe { NonNull::new_unchecked(ptr) },
476 sample_rate,
477 channels,
478 Ownership::Borrowed,
479 );
480 Self {
481 inner: decoder,
482 _marker: PhantomData,
483 }
484 }
485
486 pub fn init_in(
491 buf: &'a mut AlignedBuffer,
492 sample_rate: SampleRate,
493 channels: Channels,
494 ) -> Result<Self> {
495 let required = Decoder::size(channels)?;
496 if buf.capacity_bytes() < required {
497 return Err(Error::BadArg);
498 }
499 let ptr = buf.as_mut_ptr::<OpusDecoder>();
500 unsafe { Decoder::init_in_place(ptr, sample_rate, channels)? };
501 Ok(unsafe { Self::from_raw(ptr, sample_rate, channels) })
502 }
503}
504
505impl Deref for DecoderRef<'_> {
506 type Target = Decoder;
507
508 fn deref(&self) -> &Self::Target {
509 &self.inner
510 }
511}
512
513impl DerefMut for DecoderRef<'_> {
514 fn deref_mut(&mut self) -> &mut Self::Target {
515 &mut self.inner
516 }
517}