1#![warn(missing_docs)]
14
15use libopus_sys as ffi;
16
17use std::convert::TryFrom;
18use std::ffi::CStr;
19use std::marker::PhantomData;
20use std::os::raw::c_int;
21
22#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
27#[repr(i32)]
28pub enum Application {
29 Voip = ffi::OPUS_APPLICATION_VOIP as i32,
32 Audio = ffi::OPUS_APPLICATION_AUDIO as i32,
35 LowDelay = ffi::OPUS_APPLICATION_RESTRICTED_LOWDELAY as i32,
37}
38
39impl Application {
40 fn from_raw(raw: i32, what: &'static str) -> Result<Application> {
41 let casted_raw = raw as u32;
42 match casted_raw {
43 ffi::OPUS_APPLICATION_VOIP => Ok(Application::Voip),
44 ffi::OPUS_APPLICATION_AUDIO => Ok(Application::Audio),
45 ffi::OPUS_APPLICATION_RESTRICTED_LOWDELAY => Ok(Application::LowDelay),
46 _ => Err(Error::bad_arg(what)),
47 }
48 }
49}
50
51#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
53pub enum Channels {
54 Mono = 1,
56 Stereo = 2,
58}
59
60#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
62#[repr(i32)]
63#[derive(Default)]
64pub enum Bandwidth {
65 #[default]
67 Auto = ffi::OPUS_AUTO,
68 Narrowband = ffi::OPUS_BANDWIDTH_NARROWBAND as i32,
70 Mediumband = ffi::OPUS_BANDWIDTH_MEDIUMBAND as i32,
72 Wideband = ffi::OPUS_BANDWIDTH_WIDEBAND as i32,
74 Superwideband = ffi::OPUS_BANDWIDTH_SUPERWIDEBAND as i32,
76 Fullband = ffi::OPUS_BANDWIDTH_FULLBAND as i32,
78}
79
80impl Bandwidth {
81 fn from_int(value: i32) -> Option<Bandwidth> {
82 if value == ffi::OPUS_AUTO {
83 Some(Bandwidth::Auto)
84 } else if (value as u32) == ffi::OPUS_BANDWIDTH_NARROWBAND {
85 Some(Bandwidth::Narrowband)
86 } else if (value as u32) == ffi::OPUS_BANDWIDTH_MEDIUMBAND {
87 Some(Bandwidth::Mediumband)
88 } else if (value as u32) == ffi::OPUS_BANDWIDTH_WIDEBAND {
89 Some(Bandwidth::Wideband)
90 } else if (value as u32) == ffi::OPUS_BANDWIDTH_SUPERWIDEBAND {
91 Some(Bandwidth::Superwideband)
92 } else if (value as u32) == ffi::OPUS_BANDWIDTH_FULLBAND {
93 Some(Bandwidth::Fullband)
94 } else {
95 None
96 }
97 }
98
99 fn decode(value: i32, what: &'static str) -> Result<Bandwidth> {
100 match Bandwidth::from_int(value) {
101 Some(bandwidth) => Ok(bandwidth),
102 None => Err(Error::bad_arg(what)),
103 }
104 }
105
106 fn raw(self) -> i32 {
107 self as i32
108 }
109}
110
111#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
113#[repr(i32)]
114pub enum ErrorCode {
115 BadArg = ffi::OPUS_BAD_ARG,
117 BufferTooSmall = ffi::OPUS_BUFFER_TOO_SMALL,
119 InternalError = ffi::OPUS_INTERNAL_ERROR,
121 InvalidPacket = ffi::OPUS_INVALID_PACKET,
123 Unimplemented = ffi::OPUS_UNIMPLEMENTED,
125 InvalidState = ffi::OPUS_INVALID_STATE,
127 AllocFail = ffi::OPUS_ALLOC_FAIL,
129 Unknown = -8,
131}
132
133impl ErrorCode {
134 fn from_int(value: c_int) -> ErrorCode {
135 use ErrorCode::*;
136 match value {
137 ffi::OPUS_BAD_ARG => BadArg,
138 ffi::OPUS_BUFFER_TOO_SMALL => BufferTooSmall,
139 ffi::OPUS_INTERNAL_ERROR => InternalError,
140 ffi::OPUS_INVALID_PACKET => InvalidPacket,
141 ffi::OPUS_UNIMPLEMENTED => Unimplemented,
142 ffi::OPUS_INVALID_STATE => InvalidState,
143 ffi::OPUS_ALLOC_FAIL => AllocFail,
144 _ => Unknown,
145 }
146 }
147
148 pub fn description(self) -> &'static str {
150 unsafe { CStr::from_ptr(ffi::opus_strerror(self as c_int)) }.to_str().unwrap()
152 }
153}
154
155#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
157pub enum Bitrate {
158 Bits(i32),
160 Max,
162 Auto,
164}
165
166impl Bitrate {
167 fn from_raw(raw: c_int) -> Result<Bitrate> {
168 Ok(match raw {
169 ffi::OPUS_AUTO => Bitrate::Auto,
170 ffi::OPUS_BITRATE_MAX => Bitrate::Max,
171 _ => Bitrate::Bits(raw),
172 })
173 }
174
175 fn raw(self) -> c_int {
176 match self {
177 Bitrate::Auto => ffi::OPUS_AUTO,
178 Bitrate::Max => ffi::OPUS_BITRATE_MAX,
179 Bitrate::Bits(raw) => raw,
180 }
181 }
182}
183
184#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
186#[repr(i32)]
187#[derive(Default)]
188pub enum Signal {
189 #[default]
191 Auto = ffi::OPUS_AUTO,
192 Voice = ffi::OPUS_SIGNAL_VOICE as i32,
194 Music = ffi::OPUS_SIGNAL_MUSIC as i32,
196}
197
198impl Signal {
199 fn from_raw(raw: i32, what: &'static str) -> Result<Signal> {
200 if raw == ffi::OPUS_AUTO {
201 Ok(Signal::Auto)
202 } else if (raw as u32) == ffi::OPUS_SIGNAL_VOICE {
203 Ok(Signal::Voice)
204 } else if (raw as u32) == ffi::OPUS_SIGNAL_MUSIC {
205 Ok(Signal::Music)
206 } else {
207 Err(Error::bad_arg(what))
208 }
209 }
210
211 fn raw(self) -> i32 {
212 self as i32
213 }
214}
215
216#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
218#[repr(i32)]
219#[derive(Default)]
220pub enum FrameSize {
221 #[default]
223 Arg = ffi::OPUS_FRAMESIZE_ARG as i32,
224 Ms2_5 = ffi::OPUS_FRAMESIZE_2_5_MS as i32,
226 Ms5 = ffi::OPUS_FRAMESIZE_5_MS as i32,
228 Ms10 = ffi::OPUS_FRAMESIZE_10_MS as i32,
230 Ms20 = ffi::OPUS_FRAMESIZE_20_MS as i32,
232 Ms40 = ffi::OPUS_FRAMESIZE_40_MS as i32,
234 Ms60 = ffi::OPUS_FRAMESIZE_60_MS as i32,
236 Ms80 = ffi::OPUS_FRAMESIZE_80_MS as i32,
238 Ms100 = ffi::OPUS_FRAMESIZE_100_MS as i32,
240 Ms120 = ffi::OPUS_FRAMESIZE_120_MS as i32,
242}
243
244impl FrameSize {
245 fn from_raw(raw: i32, what: &'static str) -> Result<FrameSize> {
246 if (raw as u32) == ffi::OPUS_FRAMESIZE_ARG {
247 Ok(FrameSize::Arg)
248 } else if (raw as u32) == ffi::OPUS_FRAMESIZE_2_5_MS {
249 Ok(FrameSize::Ms2_5)
250 } else if (raw as u32) == ffi::OPUS_FRAMESIZE_5_MS {
251 Ok(FrameSize::Ms5)
252 } else if (raw as u32) == ffi::OPUS_FRAMESIZE_10_MS {
253 Ok(FrameSize::Ms10)
254 } else if (raw as u32) == ffi::OPUS_FRAMESIZE_20_MS {
255 Ok(FrameSize::Ms20)
256 } else if (raw as u32) == ffi::OPUS_FRAMESIZE_40_MS {
257 Ok(FrameSize::Ms40)
258 } else if (raw as u32) == ffi::OPUS_FRAMESIZE_60_MS {
259 Ok(FrameSize::Ms60)
260 } else if (raw as u32) == ffi::OPUS_FRAMESIZE_80_MS {
261 Ok(FrameSize::Ms80)
262 } else if (raw as u32) == ffi::OPUS_FRAMESIZE_100_MS {
263 Ok(FrameSize::Ms100)
264 } else if (raw as u32) == ffi::OPUS_FRAMESIZE_120_MS {
265 Ok(FrameSize::Ms120)
266 } else {
267 Err(Error::bad_arg(what))
268 }
269 }
270
271 fn raw(self) -> i32 {
272 self as i32
273 }
274}
275
276pub fn version() -> &'static str {
282 unsafe { CStr::from_ptr(ffi::opus_get_version_string()) }.to_str().unwrap()
284}
285
286macro_rules! ffi {
287 ($f:ident $(, $rest:expr)*) => {
288 match unsafe { ffi::$f($($rest),*) } {
289 code if code < 0 => return Err(Error::from_code(stringify!($f), code)),
290 code => code,
291 }
292 }
293}
294
295macro_rules! ctl {
299 ($f:ident, $this:ident, $ctl:path $(, $rest:expr)*) => {
300 match unsafe { ffi::$f($this.ptr, $ctl as c_int $(, $rest)*) } {
301 code if code < 0 => return Err(Error::from_code(
302 concat!(stringify!($f), "(", stringify!($ctl), ")"),
303 code,
304 )),
305 _ => (),
306 }
307 }
308}
309
310macro_rules! generic_ctls {
311 ($t:ty, $fn:ident) => {
312 impl $t {
314 pub fn reset_state(&mut self) -> Result<()> {
316 ctl!($fn, self, ffi::OPUS_RESET_STATE);
317 Ok(())
318 }
319
320 pub fn get_final_range(&mut self) -> Result<u32> {
322 let mut value: u32 = 0;
323 ctl!($fn, self, ffi::OPUS_GET_FINAL_RANGE_REQUEST, &mut value);
324 Ok(value)
325 }
326
327 pub fn get_bandwidth(&mut self) -> Result<Bandwidth> {
329 let mut value: i32 = 0;
330 ctl!($fn, self, ffi::OPUS_GET_BANDWIDTH_REQUEST, &mut value);
331 Bandwidth::decode(value, concat!(stringify!($fn), "(OPUS_GET_BANDWIDTH)"))
332 }
333
334 pub fn get_sample_rate(&mut self) -> Result<u32> {
336 let mut value: i32 = 0;
337 ctl!($fn, self, ffi::OPUS_GET_SAMPLE_RATE_REQUEST, &mut value);
338 Ok(value as u32)
339 }
340
341 pub fn set_phase_inversion_disabled(&mut self, disabled: bool) -> Result<()> {
343 let value: i32 = if disabled { 1 } else { 0 };
344 ctl!($fn, self, ffi::OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, value);
345 Ok(())
346 }
347
348 pub fn get_phase_inversion_disabled(&mut self) -> Result<bool> {
350 let mut value: i32 = 0;
351 ctl!($fn, self, ffi::OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, &mut value);
352 Ok(value != 0)
353 }
354 }
355 };
356}
357
358macro_rules! encoder_dtx_ctls {
359 ($t:ty, $fn:ident) => {
360 impl $t {
361 pub fn get_in_dtx(&mut self) -> Result<bool> {
363 let mut value: i32 = 0;
364 ctl!($fn, self, ffi::OPUS_GET_IN_DTX_REQUEST, &mut value);
365 Ok(value != 0)
366 }
367 }
368 };
369}
370
371#[derive(Debug)]
376pub struct Encoder {
377 ptr: *mut ffi::OpusEncoder,
378 channels: Channels,
379}
380
381impl Drop for Encoder {
382 fn drop(&mut self) {
383 unsafe { ffi::opus_encoder_destroy(self.ptr) }
384 }
385}
386
387unsafe impl Send for Encoder {}
398
399impl Encoder {
400 pub fn new(sample_rate: u32, channels: Channels, mode: Application) -> Result<Encoder> {
402 let mut error = 0;
403 let ptr = unsafe {
404 ffi::opus_encoder_create(
405 sample_rate as i32,
406 channels as c_int,
407 mode as c_int,
408 &mut error,
409 )
410 };
411 if error != (ffi::OPUS_OK as c_int) || ptr.is_null() {
412 Err(Error::from_code("opus_encoder_create", error))
413 } else {
414 Ok(Encoder { ptr, channels })
415 }
416 }
417
418 pub fn encode(&mut self, input: &[i16], output: &mut [u8]) -> Result<usize> {
420 let len = ffi!(
421 opus_encode,
422 self.ptr,
423 input.as_ptr(),
424 len(input) / self.channels as c_int,
425 output.as_mut_ptr(),
426 len(output)
427 );
428 Ok(len as usize)
429 }
430
431 pub fn encode_float(&mut self, input: &[f32], output: &mut [u8]) -> Result<usize> {
433 let len = ffi!(
434 opus_encode_float,
435 self.ptr,
436 input.as_ptr(),
437 len(input) / self.channels as c_int,
438 output.as_mut_ptr(),
439 len(output)
440 );
441 Ok(len as usize)
442 }
443
444 pub fn encode_vec(&mut self, input: &[i16], max_size: usize) -> Result<Vec<u8>> {
446 let mut output: Vec<u8> = vec![0; max_size];
447 let result = self.encode(input, output.as_mut_slice())?;
448 output.truncate(result);
449 Ok(output)
450 }
451
452 pub fn encode_vec_float(&mut self, input: &[f32], max_size: usize) -> Result<Vec<u8>> {
454 let mut output: Vec<u8> = vec![0; max_size];
455 let result = self.encode_float(input, output.as_mut_slice())?;
456 output.truncate(result);
457 Ok(output)
458 }
459}
460
461macro_rules! encoder_ctls {
462 ($t:ty, $fn:ident) => {
463 impl $t {
465 pub fn set_complexity(&mut self, value: i32) -> Result<()> {
467 ctl!($fn, self, ffi::OPUS_SET_COMPLEXITY_REQUEST, value);
468 Ok(())
469 }
470
471 pub fn get_complexity(&mut self) -> Result<i32> {
473 let mut value: i32 = 0;
474 ctl!($fn, self, ffi::OPUS_GET_COMPLEXITY_REQUEST, &mut value);
475 Ok(value)
476 }
477
478 pub fn set_bitrate(&mut self, value: Bitrate) -> Result<()> {
480 ctl!($fn, self, ffi::OPUS_SET_BITRATE_REQUEST, value.raw());
481 Ok(())
482 }
483
484 pub fn get_bitrate(&mut self) -> Result<Bitrate> {
486 let mut value: i32 = 0;
487 ctl!($fn, self, ffi::OPUS_GET_BITRATE_REQUEST, &mut value);
488 Bitrate::from_raw(value)
489 }
490
491 pub fn set_vbr(&mut self, vbr: bool) -> Result<()> {
493 let value: i32 = if vbr { 1 } else { 0 };
494 ctl!($fn, self, ffi::OPUS_SET_VBR_REQUEST, value);
495 Ok(())
496 }
497
498 pub fn get_vbr(&mut self) -> Result<bool> {
500 let mut value: i32 = 0;
501 ctl!($fn, self, ffi::OPUS_GET_VBR_REQUEST, &mut value);
502 Ok(value != 0)
503 }
504
505 pub fn set_vbr_constraint(&mut self, vbr: bool) -> Result<()> {
507 let value: i32 = if vbr { 1 } else { 0 };
508 ctl!($fn, self, ffi::OPUS_SET_VBR_CONSTRAINT_REQUEST, value);
509 Ok(())
510 }
511
512 pub fn get_vbr_constraint(&mut self) -> Result<bool> {
514 let mut value: i32 = 0;
515 ctl!($fn, self, ffi::OPUS_GET_VBR_CONSTRAINT_REQUEST, &mut value);
516 Ok(value != 0)
517 }
518
519 pub fn set_force_channels(&mut self, value: Option<Channels>) -> Result<()> {
526 let value: i32 = match value {
527 None => ffi::OPUS_AUTO,
528 Some(Channels::Mono) => 1,
529 Some(Channels::Stereo) => 2,
530 };
531 ctl!($fn, self, ffi::OPUS_SET_FORCE_CHANNELS_REQUEST, value);
532 Ok(())
533 }
534
535 pub fn get_force_channels(&mut self) -> Result<Option<Channels>> {
537 let mut value: i32 = 0;
538 ctl!($fn, self, ffi::OPUS_GET_FORCE_CHANNELS_REQUEST, &mut value);
539 match value {
540 ffi::OPUS_AUTO => Ok(None),
541 1 => Ok(Some(Channels::Mono)),
542 2 => Ok(Some(Channels::Stereo)),
543 _ => Err(Error::bad_arg(concat!(stringify!($fn), "(OPUS_GET_FORCE_CHANNELS)"))),
544 }
545 }
546
547 pub fn set_max_bandwidth(&mut self, bandwidth: Bandwidth) -> Result<()> {
549 let value: i32 = bandwidth.raw();
550 ctl!($fn, self, ffi::OPUS_SET_MAX_BANDWIDTH_REQUEST, value);
551 Ok(())
552 }
553
554 pub fn get_max_bandwidth(&mut self) -> Result<Bandwidth> {
556 let mut value: i32 = 0;
557 ctl!($fn, self, ffi::OPUS_GET_MAX_BANDWIDTH_REQUEST, &mut value);
558 Bandwidth::decode(value, concat!(stringify!($fn), "(OPUS_GET_MAX_BANDWIDTH)"))
559 }
560
561 pub fn set_bandwidth(&mut self, bandwidth: Bandwidth) -> Result<()> {
563 let value: i32 = bandwidth.raw();
564 ctl!($fn, self, ffi::OPUS_SET_BANDWIDTH_REQUEST, value);
565 Ok(())
566 }
567
568 pub fn set_signal(&mut self, signal: Signal) -> Result<()> {
570 let value: i32 = signal.raw();
571 ctl!($fn, self, ffi::OPUS_SET_SIGNAL_REQUEST, value);
572 Ok(())
573 }
574
575 pub fn get_signal(&mut self) -> Result<Signal> {
577 let mut value: i32 = 0;
578 ctl!($fn, self, ffi::OPUS_GET_SIGNAL_REQUEST, &mut value);
579 Signal::from_raw(value, concat!(stringify!($fn), "(OPUS_GET_SIGNAL)"))
580 }
581
582 pub fn set_application(&mut self, application: Application) -> Result<()> {
584 let value: i32 = application as i32;
585 ctl!($fn, self, ffi::OPUS_SET_APPLICATION_REQUEST, value);
586 Ok(())
587 }
588
589 pub fn get_application(&mut self) -> Result<Application> {
591 let mut value: i32 = 0;
592 ctl!($fn, self, ffi::OPUS_GET_APPLICATION_REQUEST, &mut value);
593 Application::from_raw(value, concat!(stringify!($fn), "(OPUS_GET_APPLICATION)"))
594 }
595
596 pub fn get_lookahead(&mut self) -> Result<i32> {
598 let mut value: i32 = 0;
599 ctl!($fn, self, ffi::OPUS_GET_LOOKAHEAD_REQUEST, &mut value);
600 Ok(value)
601 }
602
603 pub fn set_inband_fec(&mut self, value: bool) -> Result<()> {
605 let value: i32 = if value { 1 } else { 0 };
606 ctl!($fn, self, ffi::OPUS_SET_INBAND_FEC_REQUEST, value);
607 Ok(())
608 }
609
610 pub fn get_inband_fec(&mut self) -> Result<bool> {
612 let mut value: i32 = 0;
613 ctl!($fn, self, ffi::OPUS_GET_INBAND_FEC_REQUEST, &mut value);
614 Ok(value != 0)
615 }
616
617 pub fn set_packet_loss_perc(&mut self, value: i32) -> Result<()> {
619 ctl!($fn, self, ffi::OPUS_SET_PACKET_LOSS_PERC_REQUEST, value);
620 Ok(())
621 }
622
623 pub fn get_packet_loss_perc(&mut self) -> Result<i32> {
625 let mut value: i32 = 0;
626 ctl!($fn, self, ffi::OPUS_GET_PACKET_LOSS_PERC_REQUEST, &mut value);
627 Ok(value)
628 }
629
630 pub fn set_dtx(&mut self, value: bool) -> Result<()> {
632 let value: i32 = if value { 1 } else { 0 };
633 ctl!($fn, self, ffi::OPUS_SET_DTX_REQUEST, value);
634 Ok(())
635 }
636
637 pub fn get_dtx(&mut self) -> Result<bool> {
639 let mut value: i32 = 0;
640 ctl!($fn, self, ffi::OPUS_GET_DTX_REQUEST, &mut value);
641 Ok(value != 0)
642 }
643
644 pub fn set_lsb_depth(&mut self, depth: i32) -> Result<()> {
648 ctl!($fn, self, ffi::OPUS_SET_LSB_DEPTH_REQUEST, depth);
649 Ok(())
650 }
651
652 pub fn get_lsb_depth(&mut self) -> Result<i32> {
654 let mut value: i32 = 0;
655 ctl!($fn, self, ffi::OPUS_GET_LSB_DEPTH_REQUEST, &mut value);
656 Ok(value)
657 }
658
659 pub fn set_expert_frame_duration(&mut self, framesize: FrameSize) -> Result<()> {
663 let value: i32 = framesize.raw();
664 ctl!($fn, self, ffi::OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, value);
665 Ok(())
666 }
667
668 pub fn get_expert_frame_duration(&mut self) -> Result<FrameSize> {
670 let mut value: i32 = 0;
671 ctl!($fn, self, ffi::OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, &mut value);
672 FrameSize::from_raw(
673 value,
674 concat!(stringify!($fn), "(OPUS_GET_EXPERT_FRAME_DURATION)"),
675 )
676 }
677
678 pub fn set_prediction_disabled(&mut self, disabled: bool) -> Result<()> {
680 let value: i32 = if disabled { 1 } else { 0 };
681 ctl!($fn, self, ffi::OPUS_SET_PREDICTION_DISABLED_REQUEST, value);
682 Ok(())
683 }
684
685 pub fn get_prediction_disabled(&mut self) -> Result<bool> {
687 let mut value: i32 = 0;
688 ctl!($fn, self, ffi::OPUS_GET_PREDICTION_DISABLED_REQUEST, &mut value);
689 Ok(value != 0)
690 }
691
692 pub fn set_dred_duration(&mut self, duration_ms: i32) -> Result<()> {
698 ctl!($fn, self, ffi::OPUS_SET_DRED_DURATION_REQUEST, duration_ms);
699 Ok(())
700 }
701
702 pub fn get_dred_duration(&mut self) -> Result<i32> {
707 let mut value: i32 = 0;
708 ctl!($fn, self, ffi::OPUS_GET_DRED_DURATION_REQUEST, &mut value);
709 Ok(value)
710 }
711
712 pub fn set_dnn_blob(&mut self, blob: &[u8]) -> Result<()> {
718 ctl!($fn, self, ffi::OPUS_SET_DNN_BLOB_REQUEST, blob.as_ptr(), len(blob));
719 Ok(())
720 }
721 }
722 };
723}
724
725generic_ctls!(Encoder, opus_encoder_ctl);
726encoder_dtx_ctls!(Encoder, opus_encoder_ctl);
727encoder_ctls!(Encoder, opus_encoder_ctl);
728
729#[derive(Debug)]
734pub struct Decoder {
735 ptr: *mut ffi::OpusDecoder,
736 channels: Channels,
737}
738
739impl Drop for Decoder {
740 fn drop(&mut self) {
741 unsafe { ffi::opus_decoder_destroy(self.ptr) }
742 }
743}
744
745unsafe impl Send for Decoder {}
747
748impl Decoder {
749 pub fn new(sample_rate: u32, channels: Channels) -> Result<Decoder> {
751 let mut error = 0;
752 let ptr =
753 unsafe { ffi::opus_decoder_create(sample_rate as i32, channels as c_int, &mut error) };
754 if error != (ffi::OPUS_OK as c_int) || ptr.is_null() {
755 Err(Error::from_code("opus_decoder_create", error))
756 } else {
757 Ok(Decoder { ptr, channels })
758 }
759 }
760
761 pub fn decode(&mut self, input: &[u8], output: &mut [i16], fec: bool) -> Result<usize> {
768 let ptr = match input.len() {
769 0 => std::ptr::null(),
770 _ => input.as_ptr(),
771 };
772 let len = ffi!(
773 opus_decode,
774 self.ptr,
775 ptr,
776 len(input),
777 output.as_mut_ptr(),
778 len(output) / self.channels as c_int,
779 fec as c_int
780 );
781 Ok(len as usize)
782 }
783
784 pub fn decode_float(&mut self, input: &[u8], output: &mut [f32], fec: bool) -> Result<usize> {
791 let ptr = match input.len() {
792 0 => std::ptr::null(),
793 _ => input.as_ptr(),
794 };
795 let len = ffi!(
796 opus_decode_float,
797 self.ptr,
798 ptr,
799 len(input),
800 output.as_mut_ptr(),
801 len(output) / self.channels as c_int,
802 fec as c_int
803 );
804 Ok(len as usize)
805 }
806
807 pub fn get_nb_samples(&self, packet: &[u8]) -> Result<usize> {
809 let len = ffi!(opus_decoder_get_nb_samples, self.ptr, packet.as_ptr(), packet.len() as i32);
810 Ok(len as usize)
811 }
812}
813
814macro_rules! decoder_ctls {
815 ($t:ty, $fn:ident) => {
816 impl $t {
818 pub fn set_gain(&mut self, gain: i32) -> Result<()> {
827 ctl!($fn, self, ffi::OPUS_SET_GAIN_REQUEST, gain);
828 Ok(())
829 }
830
831 pub fn get_gain(&mut self) -> Result<i32> {
833 let mut value: i32 = 0;
834 ctl!($fn, self, ffi::OPUS_GET_GAIN_REQUEST, &mut value);
835 Ok(value)
836 }
837
838 pub fn get_last_packet_duration(&mut self) -> Result<u32> {
841 let mut value: i32 = 0;
842 ctl!($fn, self, ffi::OPUS_GET_LAST_PACKET_DURATION_REQUEST, &mut value);
843 Ok(value as u32)
844 }
845
846 pub fn get_pitch(&mut self) -> Result<i32> {
853 let mut value: i32 = 0;
854 ctl!($fn, self, ffi::OPUS_GET_PITCH_REQUEST, &mut value);
855 Ok(value)
856 }
857 }
858 };
859}
860
861generic_ctls!(Decoder, opus_decoder_ctl);
862decoder_ctls!(Decoder, opus_decoder_ctl);
863
864pub mod packet {
869 use super::ffi;
870 use super::*;
871 use std::{ptr, slice};
872
873 pub fn get_bandwidth(packet: &[u8]) -> Result<Bandwidth> {
875 if packet.is_empty() {
876 return Err(Error::bad_arg("opus_packet_get_bandwidth"));
877 }
878 let bandwidth = ffi!(opus_packet_get_bandwidth, packet.as_ptr());
879 Bandwidth::decode(bandwidth, "opus_packet_get_bandwidth")
880 }
881
882 pub fn get_nb_channels(packet: &[u8]) -> Result<Channels> {
884 if packet.is_empty() {
885 return Err(Error::bad_arg("opus_packet_get_nb_channels"));
886 }
887 let channels = ffi!(opus_packet_get_nb_channels, packet.as_ptr());
888 match channels {
889 1 => Ok(Channels::Mono),
890 2 => Ok(Channels::Stereo),
891 _ => Err(Error::bad_arg("opus_packet_get_nb_channels")),
892 }
893 }
894
895 pub fn get_nb_frames(packet: &[u8]) -> Result<usize> {
897 let frames = ffi!(opus_packet_get_nb_frames, packet.as_ptr(), len(packet));
898 Ok(frames as usize)
899 }
900
901 pub fn get_nb_samples(packet: &[u8], sample_rate: u32) -> Result<usize> {
903 let frames =
904 ffi!(opus_packet_get_nb_samples, packet.as_ptr(), len(packet), sample_rate as c_int);
905 Ok(frames as usize)
906 }
907
908 pub fn get_samples_per_frame(packet: &[u8], sample_rate: u32) -> Result<usize> {
910 if packet.is_empty() {
911 return Err(Error::bad_arg("opus_packet_get_samples_per_frame"));
912 }
913 let samples =
914 ffi!(opus_packet_get_samples_per_frame, packet.as_ptr(), sample_rate as c_int);
915 Ok(samples as usize)
916 }
917
918 pub fn parse(packet: &[u8]) -> Result<Packet<'_>> {
920 let mut toc: u8 = 0;
921 let mut frames = [ptr::null(); 48];
922 let mut sizes = [0i16; 48];
923 let mut payload_offset: i32 = 0;
924 let num_frames = ffi!(
925 opus_packet_parse,
926 packet.as_ptr(),
927 len(packet),
928 &mut toc,
929 frames.as_mut_ptr(),
930 sizes.as_mut_ptr(),
931 &mut payload_offset
932 );
933
934 let mut frames_vec = Vec::with_capacity(num_frames as usize);
935 for i in 0..num_frames as usize {
936 frames_vec.push(unsafe { slice::from_raw_parts(frames[i], sizes[i] as usize) });
937 }
938
939 Ok(Packet {
940 toc,
941 frames: frames_vec,
942 payload_offset: payload_offset as usize,
943 })
944 }
945
946 #[derive(Debug)]
948 pub struct Packet<'a> {
949 pub toc: u8,
951 pub frames: Vec<&'a [u8]>,
953 pub payload_offset: usize,
955 }
956
957 pub fn pad(packet: &mut [u8], prev_len: usize) -> Result<usize> {
962 let result = ffi!(opus_packet_pad, packet.as_mut_ptr(), check_len(prev_len), len(packet));
963 Ok(result as usize)
964 }
965
966 pub fn unpad(packet: &mut [u8]) -> Result<usize> {
969 let result = ffi!(opus_packet_unpad, packet.as_mut_ptr(), len(packet));
970 Ok(result as usize)
971 }
972
973 pub fn multistream_pad(packet: &mut [u8], prev_len: usize, nb_streams: u8) -> Result<usize> {
978 let result = ffi!(
979 opus_multistream_packet_pad,
980 packet.as_mut_ptr(),
981 check_len(prev_len),
982 len(packet),
983 nb_streams as c_int
984 );
985 Ok(result as usize)
986 }
987
988 pub fn multistream_unpad(packet: &mut [u8], nb_streams: u8) -> Result<usize> {
991 let result = ffi!(
992 opus_multistream_packet_unpad,
993 packet.as_mut_ptr(),
994 len(packet),
995 nb_streams as c_int
996 );
997 Ok(result as usize)
998 }
999}
1000
1001#[derive(Debug)]
1006pub struct SoftClip {
1007 channels: Channels,
1008 memory: [f32; 2],
1009}
1010
1011impl SoftClip {
1012 pub fn new(channels: Channels) -> SoftClip {
1014 SoftClip { channels, memory: [0.0; 2] }
1015 }
1016
1017 pub fn apply(&mut self, signal: &mut [f32]) {
1019 unsafe {
1020 ffi::opus_pcm_soft_clip(
1021 signal.as_mut_ptr(),
1022 len(signal) / self.channels as c_int,
1023 self.channels as c_int,
1024 self.memory.as_mut_ptr(),
1025 )
1026 };
1027 }
1028}
1029
1030#[derive(Debug)]
1035pub struct Repacketizer {
1036 ptr: *mut ffi::OpusRepacketizer,
1037}
1038
1039impl Drop for Repacketizer {
1040 fn drop(&mut self) {
1041 unsafe { ffi::opus_repacketizer_destroy(self.ptr) }
1042 }
1043}
1044
1045unsafe impl Send for Repacketizer {}
1047
1048impl Repacketizer {
1049 pub fn new() -> Result<Repacketizer> {
1051 let ptr = unsafe { ffi::opus_repacketizer_create() };
1052 if ptr.is_null() {
1053 Err(Error::from_code("opus_repacketizer_create", ffi::OPUS_ALLOC_FAIL))
1054 } else {
1055 Ok(Repacketizer { ptr })
1056 }
1057 }
1058
1059 pub fn combine(&mut self, input: &[&[u8]], output: &mut [u8]) -> Result<usize> {
1061 let mut state = self.begin();
1062 for &packet in input {
1063 state.cat(packet)?;
1064 }
1065 state.out(output)
1066 }
1067
1068 #[allow(clippy::needless_lifetimes)]
1070 pub fn begin<'rp, 'buf>(&'rp mut self) -> RepacketizerState<'rp, 'buf> {
1071 unsafe {
1072 ffi::opus_repacketizer_init(self.ptr);
1073 }
1074 RepacketizerState { ptr: self.ptr, phantom: PhantomData }
1075 }
1076}
1077
1078#[derive(Debug)]
1086pub struct RepacketizerState<'rp, 'buf> {
1087 ptr: *mut ffi::OpusRepacketizer,
1088 phantom: PhantomData<(&'rp mut Repacketizer, &'buf [u8])>,
1089}
1090
1091unsafe impl<'rp, 'buf> Send for RepacketizerState<'rp, 'buf> {}
1093
1094impl<'rp, 'buf> RepacketizerState<'rp, 'buf> {
1095 pub fn cat(&mut self, packet: &'buf [u8]) -> Result<()> {
1097 ffi!(opus_repacketizer_cat, self.ptr, packet.as_ptr(), len(packet));
1098 Ok(())
1099 }
1100
1101 #[inline]
1103 pub fn cat_move<'b2>(self, packet: &'b2 [u8]) -> Result<RepacketizerState<'rp, 'b2>>
1104 where
1105 'buf: 'b2,
1106 {
1107 let mut shorter = self;
1108 shorter.cat(packet)?;
1109 Ok(shorter)
1110 }
1111
1112 pub fn get_nb_frames(&mut self) -> usize {
1115 unsafe { ffi::opus_repacketizer_get_nb_frames(self.ptr) as usize }
1116 }
1117
1118 pub fn out(&mut self, buffer: &mut [u8]) -> Result<usize> {
1122 let result = ffi!(opus_repacketizer_out, self.ptr, buffer.as_mut_ptr(), len(buffer));
1123 Ok(result as usize)
1124 }
1125
1126 pub fn out_range(&mut self, begin: usize, end: usize, buffer: &mut [u8]) -> Result<usize> {
1131 let result = ffi!(
1132 opus_repacketizer_out_range,
1133 self.ptr,
1134 check_len(begin),
1135 check_len(end),
1136 buffer.as_mut_ptr(),
1137 len(buffer)
1138 );
1139 Ok(result as usize)
1140 }
1141}
1142
1143#[derive(Debug)]
1150pub struct MSEncoder {
1151 ptr: *mut ffi::OpusMSEncoder,
1152 channels: c_int,
1153}
1154
1155#[derive(Debug)]
1160pub struct SurroundEncoder {
1161 pub encoder: MSEncoder,
1163 pub streams: u8,
1165 pub coupled_streams: u8,
1167 pub mapping: Vec<u8>,
1169}
1170
1171impl Drop for MSEncoder {
1172 fn drop(&mut self) {
1173 unsafe { ffi::opus_multistream_encoder_destroy(self.ptr) }
1174 }
1175}
1176
1177unsafe impl Send for MSEncoder {}
1179
1180impl MSEncoder {
1181 pub fn new(
1183 sample_rate: u32,
1184 streams: u8,
1185 coupled_streams: u8,
1186 mapping: &[u8],
1187 application: Application,
1188 ) -> Result<MSEncoder> {
1189 let mut error = 0;
1190 let ptr = unsafe {
1191 ffi::opus_multistream_encoder_create(
1192 sample_rate as i32,
1193 len(mapping),
1194 streams as c_int,
1195 coupled_streams as c_int,
1196 mapping.as_ptr(),
1197 application as c_int,
1198 &mut error,
1199 )
1200 };
1201 if error != (ffi::OPUS_OK as c_int) || ptr.is_null() {
1202 Err(Error::from_code("opus_multistream_encoder_create", error))
1203 } else {
1204 Ok(MSEncoder { ptr, channels: len(mapping) })
1205 }
1206 }
1207
1208 pub fn new_surround(
1231 sample_rate: u32,
1232 channels: u8,
1233 mapping_family: i32,
1234 application: Application,
1235 ) -> Result<SurroundEncoder> {
1236 let mut error = 0;
1237 let mut streams: c_int = 0;
1238 let mut coupled_streams: c_int = 0;
1239 let mut mapping = vec![0u8; channels as usize];
1240
1241 let ptr = unsafe {
1242 ffi::opus_multistream_surround_encoder_create(
1243 sample_rate as i32,
1244 channels as c_int,
1245 mapping_family,
1246 &mut streams,
1247 &mut coupled_streams,
1248 mapping.as_mut_ptr(),
1249 application as c_int,
1250 &mut error,
1251 )
1252 };
1253 if error != (ffi::OPUS_OK as c_int) || ptr.is_null() {
1254 Err(Error::from_code("opus_multistream_surround_encoder_create", error))
1255 } else {
1256 Ok(SurroundEncoder {
1257 encoder: MSEncoder { ptr, channels: channels as c_int },
1258 streams: streams as u8,
1259 coupled_streams: coupled_streams as u8,
1260 mapping,
1261 })
1262 }
1263 }
1264
1265 pub fn encode(&mut self, input: &[i16], output: &mut [u8]) -> Result<usize> {
1267 let len = ffi!(
1268 opus_multistream_encode,
1269 self.ptr,
1270 input.as_ptr(),
1271 len(input) / self.channels as c_int,
1272 output.as_mut_ptr(),
1273 len(output)
1274 );
1275 Ok(len as usize)
1276 }
1277
1278 pub fn encode_float(&mut self, input: &[f32], output: &mut [u8]) -> Result<usize> {
1280 let len = ffi!(
1281 opus_multistream_encode_float,
1282 self.ptr,
1283 input.as_ptr(),
1284 len(input) / self.channels as c_int,
1285 output.as_mut_ptr(),
1286 len(output)
1287 );
1288 Ok(len as usize)
1289 }
1290
1291 pub fn encode_vec(&mut self, input: &[i16], max_size: usize) -> Result<Vec<u8>> {
1293 let mut output: Vec<u8> = vec![0; max_size];
1294 let result = self.encode(input, output.as_mut_slice())?;
1295 output.truncate(result);
1296 Ok(output)
1297 }
1298
1299 pub fn encode_vec_float(&mut self, input: &[f32], max_size: usize) -> Result<Vec<u8>> {
1301 let mut output: Vec<u8> = vec![0; max_size];
1302 let result = self.encode_float(input, output.as_mut_slice())?;
1303 output.truncate(result);
1304 Ok(output)
1305 }
1306}
1307
1308generic_ctls!(MSEncoder, opus_multistream_encoder_ctl);
1309encoder_dtx_ctls!(MSEncoder, opus_multistream_encoder_ctl);
1310encoder_ctls!(MSEncoder, opus_multistream_encoder_ctl);
1311
1312#[derive(Debug)]
1316pub struct MSDecoder {
1317 ptr: *mut ffi::OpusMSDecoder,
1318 channels: c_int,
1319}
1320
1321impl Drop for MSDecoder {
1322 fn drop(&mut self) {
1323 unsafe { ffi::opus_multistream_decoder_destroy(self.ptr) }
1324 }
1325}
1326
1327unsafe impl Send for MSDecoder {}
1329
1330impl MSDecoder {
1331 pub fn new(
1333 sample_rate: u32,
1334 streams: u8,
1335 coupled_streams: u8,
1336 mapping: &[u8],
1337 ) -> Result<MSDecoder> {
1338 let mut error = 0;
1339 let ptr = unsafe {
1340 ffi::opus_multistream_decoder_create(
1341 sample_rate as i32,
1342 len(mapping),
1343 streams as c_int,
1344 coupled_streams as c_int,
1345 mapping.as_ptr(),
1346 &mut error,
1347 )
1348 };
1349 if error != (ffi::OPUS_OK as c_int) || ptr.is_null() {
1350 Err(Error::from_code("opus_multistream_decoder_create", error))
1351 } else {
1352 Ok(MSDecoder { ptr, channels: len(mapping) })
1353 }
1354 }
1355
1356 pub fn decode(&mut self, input: &[u8], output: &mut [i16], fec: bool) -> Result<usize> {
1360 let ptr = match input.len() {
1361 0 => std::ptr::null(),
1362 _ => input.as_ptr(),
1363 };
1364 let len = ffi!(
1365 opus_multistream_decode,
1366 self.ptr,
1367 ptr,
1368 len(input),
1369 output.as_mut_ptr(),
1370 len(output) / self.channels as c_int,
1371 fec as c_int
1372 );
1373 Ok(len as usize)
1374 }
1375
1376 pub fn decode_float(&mut self, input: &[u8], output: &mut [f32], fec: bool) -> Result<usize> {
1378 let ptr = match input.len() {
1379 0 => std::ptr::null(),
1380 _ => input.as_ptr(),
1381 };
1382 let len = ffi!(
1383 opus_multistream_decode_float,
1384 self.ptr,
1385 ptr,
1386 len(input),
1387 output.as_mut_ptr(),
1388 len(output) / self.channels as c_int,
1389 fec as c_int
1390 );
1391 Ok(len as usize)
1392 }
1393}
1394
1395generic_ctls!(MSDecoder, opus_multistream_decoder_ctl);
1396decoder_ctls!(MSDecoder, opus_multistream_decoder_ctl);
1397
1398pub type Result<T> = std::result::Result<T, Error>;
1403
1404#[derive(Debug)]
1406pub struct Error {
1407 function: &'static str,
1408 code: ErrorCode,
1409}
1410
1411impl Error {
1412 fn bad_arg(what: &'static str) -> Error {
1413 Error { function: what, code: ErrorCode::BadArg }
1414 }
1415
1416 fn from_code(what: &'static str, code: c_int) -> Error {
1417 Error {
1418 function: what,
1419 code: ErrorCode::from_int(code),
1420 }
1421 }
1422
1423 #[inline]
1425 pub fn function(&self) -> &'static str {
1426 self.function
1427 }
1428
1429 #[inline]
1431 pub fn description(&self) -> &'static str {
1432 self.code.description()
1433 }
1434
1435 #[inline]
1437 pub fn code(&self) -> ErrorCode {
1438 self.code
1439 }
1440}
1441
1442impl std::fmt::Display for Error {
1443 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1444 write!(f, "{}: {}", self.function, self.description())
1445 }
1446}
1447
1448impl std::error::Error for Error {
1449 fn description(&self) -> &str {
1450 self.code.description()
1451 }
1452}
1453
1454fn check_len(val: usize) -> c_int {
1455 match c_int::try_from(val) {
1456 Ok(val2) => val2,
1457 Err(_) => panic!("length out of range: {}", val),
1458 }
1459}
1460
1461#[inline]
1462fn len<T>(slice: &[T]) -> c_int {
1463 check_len(slice.len())
1464}