1#![warn(missing_docs)]
14
15extern crate audiopus_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,
32 Audio = ffi::OPUS_APPLICATION_AUDIO,
35 LowDelay = ffi::OPUS_APPLICATION_RESTRICTED_LOWDELAY,
37}
38
39impl Application {
40 fn from_raw(raw: i32, what: &'static str) -> Result<Application> {
41 match raw {
42 ffi::OPUS_APPLICATION_VOIP => Ok(Application::Voip),
43 ffi::OPUS_APPLICATION_AUDIO => Ok(Application::Audio),
44 ffi::OPUS_APPLICATION_RESTRICTED_LOWDELAY => Ok(Application::LowDelay),
45 _ => Err(Error::bad_arg(what)),
46 }
47 }
48}
49
50#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
52pub enum Channels {
53 Mono = 1,
55 Stereo = 2,
57}
58
59#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
61#[repr(i32)]
62#[derive(Default)]
63pub enum Bandwidth {
64 #[default]
66 Auto = ffi::OPUS_AUTO,
67 Narrowband = ffi::OPUS_BANDWIDTH_NARROWBAND,
69 Mediumband = ffi::OPUS_BANDWIDTH_MEDIUMBAND,
71 Wideband = ffi::OPUS_BANDWIDTH_WIDEBAND,
73 Superwideband = ffi::OPUS_BANDWIDTH_SUPERWIDEBAND,
75 Fullband = ffi::OPUS_BANDWIDTH_FULLBAND,
77}
78
79impl Bandwidth {
80 fn from_int(value: i32) -> Option<Bandwidth> {
81 Some(match value {
82 ffi::OPUS_AUTO => Bandwidth::Auto,
83 ffi::OPUS_BANDWIDTH_NARROWBAND => Bandwidth::Narrowband,
84 ffi::OPUS_BANDWIDTH_MEDIUMBAND => Bandwidth::Mediumband,
85 ffi::OPUS_BANDWIDTH_WIDEBAND => Bandwidth::Wideband,
86 ffi::OPUS_BANDWIDTH_SUPERWIDEBAND => Bandwidth::Superwideband,
87 ffi::OPUS_BANDWIDTH_FULLBAND => Bandwidth::Fullband,
88 _ => return None,
89 })
90 }
91
92 fn decode(value: i32, what: &'static str) -> Result<Bandwidth> {
93 match Bandwidth::from_int(value) {
94 Some(bandwidth) => Ok(bandwidth),
95 None => Err(Error::bad_arg(what)),
96 }
97 }
98
99 fn raw(self) -> i32 {
100 self as i32
101 }
102}
103
104#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
106#[repr(i32)]
107pub enum ErrorCode {
108 BadArg = ffi::OPUS_BAD_ARG,
110 BufferTooSmall = ffi::OPUS_BUFFER_TOO_SMALL,
112 InternalError = ffi::OPUS_INTERNAL_ERROR,
114 InvalidPacket = ffi::OPUS_INVALID_PACKET,
116 Unimplemented = ffi::OPUS_UNIMPLEMENTED,
118 InvalidState = ffi::OPUS_INVALID_STATE,
120 AllocFail = ffi::OPUS_ALLOC_FAIL,
122 Unknown = -8,
124}
125
126impl ErrorCode {
127 fn from_int(value: c_int) -> ErrorCode {
128 use ErrorCode::*;
129 match value {
130 ffi::OPUS_BAD_ARG => BadArg,
131 ffi::OPUS_BUFFER_TOO_SMALL => BufferTooSmall,
132 ffi::OPUS_INTERNAL_ERROR => InternalError,
133 ffi::OPUS_INVALID_PACKET => InvalidPacket,
134 ffi::OPUS_UNIMPLEMENTED => Unimplemented,
135 ffi::OPUS_INVALID_STATE => InvalidState,
136 ffi::OPUS_ALLOC_FAIL => AllocFail,
137 _ => Unknown,
138 }
139 }
140
141 pub fn description(self) -> &'static str {
143 unsafe { CStr::from_ptr(ffi::opus_strerror(self as c_int)) }.to_str().unwrap()
145 }
146}
147
148#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
150pub enum Bitrate {
151 Bits(i32),
153 Max,
155 Auto,
157}
158
159impl Bitrate {
160 fn from_raw(raw: c_int) -> Result<Bitrate> {
161 Ok(match raw {
162 ffi::OPUS_AUTO => Bitrate::Auto,
163 ffi::OPUS_BITRATE_MAX => Bitrate::Max,
164 _ => Bitrate::Bits(raw),
165 })
166 }
167
168 fn raw(self) -> c_int {
169 match self {
170 Bitrate::Auto => ffi::OPUS_AUTO,
171 Bitrate::Max => ffi::OPUS_BITRATE_MAX,
172 Bitrate::Bits(raw) => raw,
173 }
174 }
175}
176
177#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
179#[repr(i32)]
180#[derive(Default)]
181pub enum Signal {
182 #[default]
184 Auto = ffi::OPUS_AUTO,
185 Voice = ffi::OPUS_SIGNAL_VOICE,
187 Music = ffi::OPUS_SIGNAL_MUSIC,
189}
190
191impl Signal {
192 fn from_raw(raw: i32, what: &'static str) -> Result<Signal> {
193 match raw {
194 ffi::OPUS_AUTO => Ok(Signal::Auto),
195 ffi::OPUS_SIGNAL_VOICE => Ok(Signal::Voice),
196 ffi::OPUS_SIGNAL_MUSIC => Ok(Signal::Music),
197 _ => Err(Error::bad_arg(what)),
198 }
199 }
200
201 fn raw(self) -> i32 {
202 self as i32
203 }
204}
205
206#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
208#[repr(i32)]
209#[derive(Default)]
210pub enum FrameSize {
211 #[default]
213 Arg = ffi::OPUS_FRAMESIZE_ARG,
214 Ms2_5 = ffi::OPUS_FRAMESIZE_2_5_MS,
216 Ms5 = ffi::OPUS_FRAMESIZE_5_MS,
218 Ms10 = ffi::OPUS_FRAMESIZE_10_MS,
220 Ms20 = ffi::OPUS_FRAMESIZE_20_MS,
222 Ms40 = ffi::OPUS_FRAMESIZE_40_MS,
224 Ms60 = ffi::OPUS_FRAMESIZE_60_MS,
226 Ms80 = ffi::OPUS_FRAMESIZE_80_MS,
228 Ms100 = ffi::OPUS_FRAMESIZE_100_MS,
230 Ms120 = ffi::OPUS_FRAMESIZE_120_MS,
232}
233
234impl FrameSize {
235 fn from_raw(raw: i32, what: &'static str) -> Result<FrameSize> {
236 match raw {
237 ffi::OPUS_FRAMESIZE_ARG => Ok(FrameSize::Arg),
238 ffi::OPUS_FRAMESIZE_2_5_MS => Ok(FrameSize::Ms2_5),
239 ffi::OPUS_FRAMESIZE_5_MS => Ok(FrameSize::Ms5),
240 ffi::OPUS_FRAMESIZE_10_MS => Ok(FrameSize::Ms10),
241 ffi::OPUS_FRAMESIZE_20_MS => Ok(FrameSize::Ms20),
242 ffi::OPUS_FRAMESIZE_40_MS => Ok(FrameSize::Ms40),
243 ffi::OPUS_FRAMESIZE_60_MS => Ok(FrameSize::Ms60),
244 ffi::OPUS_FRAMESIZE_80_MS => Ok(FrameSize::Ms80),
245 ffi::OPUS_FRAMESIZE_100_MS => Ok(FrameSize::Ms100),
246 ffi::OPUS_FRAMESIZE_120_MS => Ok(FrameSize::Ms120),
247 _ => Err(Error::bad_arg(what)),
248 }
249 }
250
251 fn raw(self) -> i32 {
252 self as i32
253 }
254}
255
256pub fn version() -> &'static str {
262 unsafe { CStr::from_ptr(ffi::opus_get_version_string()) }.to_str().unwrap()
264}
265
266macro_rules! ffi {
267 ($f:ident $(, $rest:expr)*) => {
268 match unsafe { ffi::$f($($rest),*) } {
269 code if code < 0 => return Err(Error::from_code(stringify!($f), code)),
270 code => code,
271 }
272 }
273}
274
275macro_rules! ctl {
279 ($f:ident, $this:ident, $ctl:path $(, $rest:expr)*) => {
280 match unsafe { ffi::$f($this.ptr, $ctl $(, $rest)*) } {
281 code if code < 0 => return Err(Error::from_code(
282 concat!(stringify!($f), "(", stringify!($ctl), ")"),
283 code,
284 )),
285 _ => (),
286 }
287 }
288}
289
290macro_rules! generic_ctls {
291 ($t:ty, $fn:ident) => {
292 impl $t {
294 pub fn reset_state(&mut self) -> Result<()> {
296 ctl!($fn, self, ffi::OPUS_RESET_STATE);
297 Ok(())
298 }
299
300 pub fn get_final_range(&mut self) -> Result<u32> {
302 let mut value: u32 = 0;
303 ctl!($fn, self, ffi::OPUS_GET_FINAL_RANGE_REQUEST, &mut value);
304 Ok(value)
305 }
306
307 pub fn get_bandwidth(&mut self) -> Result<Bandwidth> {
309 let mut value: i32 = 0;
310 ctl!($fn, self, ffi::OPUS_GET_BANDWIDTH_REQUEST, &mut value);
311 Bandwidth::decode(value, concat!(stringify!($fn), "(OPUS_GET_BANDWIDTH)"))
312 }
313
314 pub fn get_sample_rate(&mut self) -> Result<u32> {
316 let mut value: i32 = 0;
317 ctl!($fn, self, ffi::OPUS_GET_SAMPLE_RATE_REQUEST, &mut value);
318 Ok(value as u32)
319 }
320
321 pub fn set_phase_inversion_disabled(&mut self, disabled: bool) -> Result<()> {
323 let value: i32 = if disabled { 1 } else { 0 };
324 ctl!($fn, self, ffi::OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, value);
325 Ok(())
326 }
327
328 pub fn get_phase_inversion_disabled(&mut self) -> Result<bool> {
330 let mut value: i32 = 0;
331 ctl!($fn, self, ffi::OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, &mut value);
332 Ok(value != 0)
333 }
334
335 pub fn get_in_dtx(&mut self) -> Result<bool> {
337 let mut value: i32 = 0;
338 ctl!($fn, self, ffi::OPUS_GET_IN_DTX_REQUEST, &mut value);
339 Ok(value != 0)
340 }
341 }
342 };
343}
344
345#[derive(Debug)]
350pub struct Encoder {
351 ptr: *mut ffi::OpusEncoder,
352 channels: Channels,
353}
354
355impl Drop for Encoder {
356 fn drop(&mut self) {
357 unsafe { ffi::opus_encoder_destroy(self.ptr) }
358 }
359}
360
361unsafe impl Send for Encoder {}
372
373impl Encoder {
374 pub fn new(sample_rate: u32, channels: Channels, mode: Application) -> Result<Encoder> {
376 let mut error = 0;
377 let ptr = unsafe {
378 ffi::opus_encoder_create(
379 sample_rate as i32,
380 channels as c_int,
381 mode as c_int,
382 &mut error,
383 )
384 };
385 if error != ffi::OPUS_OK || ptr.is_null() {
386 Err(Error::from_code("opus_encoder_create", error))
387 } else {
388 Ok(Encoder { ptr, channels })
389 }
390 }
391
392 pub fn encode(&mut self, input: &[i16], output: &mut [u8]) -> Result<usize> {
394 let len = ffi!(
395 opus_encode,
396 self.ptr,
397 input.as_ptr(),
398 len(input) / self.channels as c_int,
399 output.as_mut_ptr(),
400 len(output)
401 );
402 Ok(len as usize)
403 }
404
405 pub fn encode_float(&mut self, input: &[f32], output: &mut [u8]) -> Result<usize> {
407 let len = ffi!(
408 opus_encode_float,
409 self.ptr,
410 input.as_ptr(),
411 len(input) / self.channels as c_int,
412 output.as_mut_ptr(),
413 len(output)
414 );
415 Ok(len as usize)
416 }
417
418 pub fn encode_vec(&mut self, input: &[i16], max_size: usize) -> Result<Vec<u8>> {
420 let mut output: Vec<u8> = vec![0; max_size];
421 let result = self.encode(input, output.as_mut_slice())?;
422 output.truncate(result);
423 Ok(output)
424 }
425
426 pub fn encode_vec_float(&mut self, input: &[f32], max_size: usize) -> Result<Vec<u8>> {
428 let mut output: Vec<u8> = vec![0; max_size];
429 let result = self.encode_float(input, output.as_mut_slice())?;
430 output.truncate(result);
431 Ok(output)
432 }
433}
434
435macro_rules! encoder_ctls {
436 ($t:ty, $fn:ident) => {
437 impl $t {
439 pub fn set_complexity(&mut self, value: i32) -> Result<()> {
441 ctl!($fn, self, ffi::OPUS_SET_COMPLEXITY_REQUEST, value);
442 Ok(())
443 }
444
445 pub fn get_complexity(&mut self) -> Result<i32> {
447 let mut value: i32 = 0;
448 ctl!($fn, self, ffi::OPUS_GET_COMPLEXITY_REQUEST, &mut value);
449 Ok(value)
450 }
451
452 pub fn set_bitrate(&mut self, value: Bitrate) -> Result<()> {
454 ctl!($fn, self, ffi::OPUS_SET_BITRATE_REQUEST, value.raw());
455 Ok(())
456 }
457
458 pub fn get_bitrate(&mut self) -> Result<Bitrate> {
460 let mut value: i32 = 0;
461 ctl!($fn, self, ffi::OPUS_GET_BITRATE_REQUEST, &mut value);
462 Bitrate::from_raw(value)
463 }
464
465 pub fn set_vbr(&mut self, vbr: bool) -> Result<()> {
467 let value: i32 = if vbr { 1 } else { 0 };
468 ctl!($fn, self, ffi::OPUS_SET_VBR_REQUEST, value);
469 Ok(())
470 }
471
472 pub fn get_vbr(&mut self) -> Result<bool> {
474 let mut value: i32 = 0;
475 ctl!($fn, self, ffi::OPUS_GET_VBR_REQUEST, &mut value);
476 Ok(value != 0)
477 }
478
479 pub fn set_vbr_constraint(&mut self, vbr: bool) -> Result<()> {
481 let value: i32 = if vbr { 1 } else { 0 };
482 ctl!($fn, self, ffi::OPUS_SET_VBR_CONSTRAINT_REQUEST, value);
483 Ok(())
484 }
485
486 pub fn get_vbr_constraint(&mut self) -> Result<bool> {
488 let mut value: i32 = 0;
489 ctl!($fn, self, ffi::OPUS_GET_VBR_CONSTRAINT_REQUEST, &mut value);
490 Ok(value != 0)
491 }
492
493 pub fn set_force_channels(&mut self, value: Option<Channels>) -> Result<()> {
500 let value: i32 = match value {
501 None => ffi::OPUS_AUTO,
502 Some(Channels::Mono) => 1,
503 Some(Channels::Stereo) => 2,
504 };
505 ctl!($fn, self, ffi::OPUS_SET_FORCE_CHANNELS_REQUEST, value);
506 Ok(())
507 }
508
509 pub fn get_force_channels(&mut self) -> Result<Option<Channels>> {
511 let mut value: i32 = 0;
512 ctl!($fn, self, ffi::OPUS_GET_FORCE_CHANNELS_REQUEST, &mut value);
513 match value {
514 ffi::OPUS_AUTO => Ok(None),
515 1 => Ok(Some(Channels::Mono)),
516 2 => Ok(Some(Channels::Stereo)),
517 _ => Err(Error::bad_arg(concat!(stringify!($fn), "(OPUS_GET_FORCE_CHANNELS)"))),
518 }
519 }
520
521 pub fn set_max_bandwidth(&mut self, bandwidth: Bandwidth) -> Result<()> {
523 let value: i32 = bandwidth.raw();
524 ctl!($fn, self, ffi::OPUS_SET_MAX_BANDWIDTH_REQUEST, value);
525 Ok(())
526 }
527
528 pub fn get_max_bandwidth(&mut self) -> Result<Bandwidth> {
530 let mut value: i32 = 0;
531 ctl!($fn, self, ffi::OPUS_GET_MAX_BANDWIDTH_REQUEST, &mut value);
532 Bandwidth::decode(value, concat!(stringify!($fn), "(OPUS_GET_MAX_BANDWIDTH)"))
533 }
534
535 pub fn set_bandwidth(&mut self, bandwidth: Bandwidth) -> Result<()> {
537 let value: i32 = bandwidth.raw();
538 ctl!($fn, self, ffi::OPUS_SET_BANDWIDTH_REQUEST, value);
539 Ok(())
540 }
541
542 pub fn set_signal(&mut self, signal: Signal) -> Result<()> {
544 let value: i32 = signal.raw();
545 ctl!($fn, self, ffi::OPUS_SET_SIGNAL_REQUEST, value);
546 Ok(())
547 }
548
549 pub fn get_signal(&mut self) -> Result<Signal> {
551 let mut value: i32 = 0;
552 ctl!($fn, self, ffi::OPUS_GET_SIGNAL_REQUEST, &mut value);
553 Signal::from_raw(value, concat!(stringify!($fn), "(OPUS_GET_SIGNAL)"))
554 }
555
556 pub fn set_application(&mut self, application: Application) -> Result<()> {
558 let value: i32 = application as i32;
559 ctl!($fn, self, ffi::OPUS_SET_APPLICATION_REQUEST, value);
560 Ok(())
561 }
562
563 pub fn get_application(&mut self) -> Result<Application> {
565 let mut value: i32 = 0;
566 ctl!($fn, self, ffi::OPUS_GET_APPLICATION_REQUEST, &mut value);
567 Application::from_raw(value, concat!(stringify!($fn), "(OPUS_GET_APPLICATION)"))
568 }
569
570 pub fn get_lookahead(&mut self) -> Result<i32> {
572 let mut value: i32 = 0;
573 ctl!($fn, self, ffi::OPUS_GET_LOOKAHEAD_REQUEST, &mut value);
574 Ok(value)
575 }
576
577 pub fn set_inband_fec(&mut self, value: bool) -> Result<()> {
579 let value: i32 = if value { 1 } else { 0 };
580 ctl!($fn, self, ffi::OPUS_SET_INBAND_FEC_REQUEST, value);
581 Ok(())
582 }
583
584 pub fn get_inband_fec(&mut self) -> Result<bool> {
586 let mut value: i32 = 0;
587 ctl!($fn, self, ffi::OPUS_GET_INBAND_FEC_REQUEST, &mut value);
588 Ok(value != 0)
589 }
590
591 pub fn set_packet_loss_perc(&mut self, value: i32) -> Result<()> {
593 ctl!($fn, self, ffi::OPUS_SET_PACKET_LOSS_PERC_REQUEST, value);
594 Ok(())
595 }
596
597 pub fn get_packet_loss_perc(&mut self) -> Result<i32> {
599 let mut value: i32 = 0;
600 ctl!($fn, self, ffi::OPUS_GET_PACKET_LOSS_PERC_REQUEST, &mut value);
601 Ok(value)
602 }
603
604 pub fn set_dtx(&mut self, value: bool) -> Result<()> {
606 let value: i32 = if value { 1 } else { 0 };
607 ctl!($fn, self, ffi::OPUS_SET_DTX_REQUEST, value);
608 Ok(())
609 }
610
611 pub fn get_dtx(&mut self) -> Result<bool> {
613 let mut value: i32 = 0;
614 ctl!($fn, self, ffi::OPUS_GET_DTX_REQUEST, &mut value);
615 Ok(value != 0)
616 }
617
618 pub fn set_lsb_depth(&mut self, depth: i32) -> Result<()> {
622 ctl!($fn, self, ffi::OPUS_SET_LSB_DEPTH_REQUEST, depth);
623 Ok(())
624 }
625
626 pub fn get_lsb_depth(&mut self) -> Result<i32> {
628 let mut value: i32 = 0;
629 ctl!($fn, self, ffi::OPUS_GET_LSB_DEPTH_REQUEST, &mut value);
630 Ok(value)
631 }
632
633 pub fn set_expert_frame_duration(&mut self, framesize: FrameSize) -> Result<()> {
637 let value: i32 = framesize.raw();
638 ctl!($fn, self, ffi::OPUS_SET_EXPERT_FRAME_DURATION_REQUEST, value);
639 Ok(())
640 }
641
642 pub fn get_expert_frame_duration(&mut self) -> Result<FrameSize> {
644 let mut value: i32 = 0;
645 ctl!($fn, self, ffi::OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, &mut value);
646 FrameSize::from_raw(
647 value,
648 concat!(stringify!($fn), "(OPUS_GET_EXPERT_FRAME_DURATION)"),
649 )
650 }
651
652 pub fn set_prediction_disabled(&mut self, disabled: bool) -> Result<()> {
654 let value: i32 = if disabled { 1 } else { 0 };
655 ctl!($fn, self, ffi::OPUS_SET_PREDICTION_DISABLED_REQUEST, value);
656 Ok(())
657 }
658
659 pub fn get_prediction_disabled(&mut self) -> Result<bool> {
661 let mut value: i32 = 0;
662 ctl!($fn, self, ffi::OPUS_GET_PREDICTION_DISABLED_REQUEST, &mut value);
663 Ok(value != 0)
664 }
665
666 }
669 };
670}
671
672generic_ctls!(Encoder, opus_encoder_ctl);
673encoder_ctls!(Encoder, opus_encoder_ctl);
674
675#[derive(Debug)]
680pub struct Decoder {
681 ptr: *mut ffi::OpusDecoder,
682 channels: Channels,
683}
684
685impl Drop for Decoder {
686 fn drop(&mut self) {
687 unsafe { ffi::opus_decoder_destroy(self.ptr) }
688 }
689}
690
691unsafe impl Send for Decoder {}
693
694impl Decoder {
695 pub fn new(sample_rate: u32, channels: Channels) -> Result<Decoder> {
697 let mut error = 0;
698 let ptr =
699 unsafe { ffi::opus_decoder_create(sample_rate as i32, channels as c_int, &mut error) };
700 if error != ffi::OPUS_OK || ptr.is_null() {
701 Err(Error::from_code("opus_decoder_create", error))
702 } else {
703 Ok(Decoder { ptr, channels })
704 }
705 }
706
707 pub fn decode(&mut self, input: &[u8], output: &mut [i16], fec: bool) -> Result<usize> {
714 let ptr = match input.len() {
715 0 => std::ptr::null(),
716 _ => input.as_ptr(),
717 };
718 let len = ffi!(
719 opus_decode,
720 self.ptr,
721 ptr,
722 len(input),
723 output.as_mut_ptr(),
724 len(output) / self.channels as c_int,
725 fec as c_int
726 );
727 Ok(len as usize)
728 }
729
730 pub fn decode_float(&mut self, input: &[u8], output: &mut [f32], fec: bool) -> Result<usize> {
737 let ptr = match input.len() {
738 0 => std::ptr::null(),
739 _ => input.as_ptr(),
740 };
741 let len = ffi!(
742 opus_decode_float,
743 self.ptr,
744 ptr,
745 len(input),
746 output.as_mut_ptr(),
747 len(output) / self.channels as c_int,
748 fec as c_int
749 );
750 Ok(len as usize)
751 }
752
753 pub fn get_nb_samples(&self, packet: &[u8]) -> Result<usize> {
755 let len = ffi!(opus_decoder_get_nb_samples, self.ptr, packet.as_ptr(), packet.len() as i32);
756 Ok(len as usize)
757 }
758}
759
760macro_rules! decoder_ctls {
761 ($t:ty, $fn:ident) => {
762 impl $t {
764 pub fn set_gain(&mut self, gain: i32) -> Result<()> {
773 ctl!($fn, self, ffi::OPUS_SET_GAIN_REQUEST, gain);
774 Ok(())
775 }
776
777 pub fn get_gain(&mut self) -> Result<i32> {
779 let mut value: i32 = 0;
780 ctl!($fn, self, ffi::OPUS_GET_GAIN_REQUEST, &mut value);
781 Ok(value)
782 }
783
784 pub fn get_last_packet_duration(&mut self) -> Result<u32> {
787 let mut value: i32 = 0;
788 ctl!($fn, self, ffi::OPUS_GET_LAST_PACKET_DURATION_REQUEST, &mut value);
789 Ok(value as u32)
790 }
791
792 pub fn get_pitch(&mut self) -> Result<i32> {
799 let mut value: i32 = 0;
800 ctl!($fn, self, ffi::OPUS_GET_PITCH_REQUEST, &mut value);
801 Ok(value)
802 }
803 }
804 };
805}
806
807generic_ctls!(Decoder, opus_decoder_ctl);
808decoder_ctls!(Decoder, opus_decoder_ctl);
809
810pub mod packet {
815 use super::ffi;
816 use super::*;
817 use std::{ptr, slice};
818
819 pub fn get_bandwidth(packet: &[u8]) -> Result<Bandwidth> {
821 if packet.is_empty() {
822 return Err(Error::bad_arg("opus_packet_get_bandwidth"));
823 }
824 let bandwidth = ffi!(opus_packet_get_bandwidth, packet.as_ptr());
825 Bandwidth::decode(bandwidth, "opus_packet_get_bandwidth")
826 }
827
828 pub fn get_nb_channels(packet: &[u8]) -> Result<Channels> {
830 if packet.is_empty() {
831 return Err(Error::bad_arg("opus_packet_get_nb_channels"));
832 }
833 let channels = ffi!(opus_packet_get_nb_channels, packet.as_ptr());
834 match channels {
835 1 => Ok(Channels::Mono),
836 2 => Ok(Channels::Stereo),
837 _ => Err(Error::bad_arg("opus_packet_get_nb_channels")),
838 }
839 }
840
841 pub fn get_nb_frames(packet: &[u8]) -> Result<usize> {
843 let frames = ffi!(opus_packet_get_nb_frames, packet.as_ptr(), len(packet));
844 Ok(frames as usize)
845 }
846
847 pub fn get_nb_samples(packet: &[u8], sample_rate: u32) -> Result<usize> {
849 let frames =
850 ffi!(opus_packet_get_nb_samples, packet.as_ptr(), len(packet), sample_rate as c_int);
851 Ok(frames as usize)
852 }
853
854 pub fn get_samples_per_frame(packet: &[u8], sample_rate: u32) -> Result<usize> {
856 if packet.is_empty() {
857 return Err(Error::bad_arg("opus_packet_get_samples_per_frame"));
858 }
859 let samples =
860 ffi!(opus_packet_get_samples_per_frame, packet.as_ptr(), sample_rate as c_int);
861 Ok(samples as usize)
862 }
863
864 pub fn parse(packet: &[u8]) -> Result<Packet<'_>> {
866 let mut toc: u8 = 0;
867 let mut frames = [ptr::null(); 48];
868 let mut sizes = [0i16; 48];
869 let mut payload_offset: i32 = 0;
870 let num_frames = ffi!(
871 opus_packet_parse,
872 packet.as_ptr(),
873 len(packet),
874 &mut toc,
875 frames.as_mut_ptr(),
876 sizes.as_mut_ptr(),
877 &mut payload_offset
878 );
879
880 let mut frames_vec = Vec::with_capacity(num_frames as usize);
881 for i in 0..num_frames as usize {
882 frames_vec.push(unsafe { slice::from_raw_parts(frames[i], sizes[i] as usize) });
883 }
884
885 Ok(Packet {
886 toc,
887 frames: frames_vec,
888 payload_offset: payload_offset as usize,
889 })
890 }
891
892 #[derive(Debug)]
894 pub struct Packet<'a> {
895 pub toc: u8,
897 pub frames: Vec<&'a [u8]>,
899 pub payload_offset: usize,
901 }
902
903 pub fn pad(packet: &mut [u8], prev_len: usize) -> Result<usize> {
908 let result = ffi!(opus_packet_pad, packet.as_mut_ptr(), check_len(prev_len), len(packet));
909 Ok(result as usize)
910 }
911
912 pub fn unpad(packet: &mut [u8]) -> Result<usize> {
915 let result = ffi!(opus_packet_unpad, packet.as_mut_ptr(), len(packet));
916 Ok(result as usize)
917 }
918
919 pub fn multistream_pad(packet: &mut [u8], prev_len: usize, nb_streams: u8) -> Result<usize> {
924 let result = ffi!(
925 opus_multistream_packet_pad,
926 packet.as_mut_ptr(),
927 check_len(prev_len),
928 len(packet),
929 nb_streams as c_int
930 );
931 Ok(result as usize)
932 }
933
934 pub fn multistream_unpad(packet: &mut [u8], nb_streams: u8) -> Result<usize> {
937 let result = ffi!(
938 opus_multistream_packet_unpad,
939 packet.as_mut_ptr(),
940 len(packet),
941 nb_streams as c_int
942 );
943 Ok(result as usize)
944 }
945}
946
947#[derive(Debug)]
952pub struct SoftClip {
953 channels: Channels,
954 memory: [f32; 2],
955}
956
957impl SoftClip {
958 pub fn new(channels: Channels) -> SoftClip {
960 SoftClip { channels, memory: [0.0; 2] }
961 }
962
963 pub fn apply(&mut self, signal: &mut [f32]) {
965 unsafe {
966 ffi::opus_pcm_soft_clip(
967 signal.as_mut_ptr(),
968 len(signal) / self.channels as c_int,
969 self.channels as c_int,
970 self.memory.as_mut_ptr(),
971 )
972 };
973 }
974}
975
976#[derive(Debug)]
981pub struct Repacketizer {
982 ptr: *mut ffi::OpusRepacketizer,
983}
984
985impl Drop for Repacketizer {
986 fn drop(&mut self) {
987 unsafe { ffi::opus_repacketizer_destroy(self.ptr) }
988 }
989}
990
991unsafe impl Send for Repacketizer {}
993
994impl Repacketizer {
995 pub fn new() -> Result<Repacketizer> {
997 let ptr = unsafe { ffi::opus_repacketizer_create() };
998 if ptr.is_null() {
999 Err(Error::from_code("opus_repacketizer_create", ffi::OPUS_ALLOC_FAIL))
1000 } else {
1001 Ok(Repacketizer { ptr })
1002 }
1003 }
1004
1005 pub fn combine(&mut self, input: &[&[u8]], output: &mut [u8]) -> Result<usize> {
1007 let mut state = self.begin();
1008 for &packet in input {
1009 state.cat(packet)?;
1010 }
1011 state.out(output)
1012 }
1013
1014 #[allow(clippy::needless_lifetimes)]
1016 pub fn begin<'rp, 'buf>(&'rp mut self) -> RepacketizerState<'rp, 'buf> {
1017 unsafe {
1018 ffi::opus_repacketizer_init(self.ptr);
1019 }
1020 RepacketizerState { ptr: self.ptr, phantom: PhantomData }
1021 }
1022}
1023
1024#[derive(Debug)]
1032pub struct RepacketizerState<'rp, 'buf> {
1033 ptr: *mut ffi::OpusRepacketizer,
1034 phantom: PhantomData<(&'rp mut Repacketizer, &'buf [u8])>,
1035}
1036
1037unsafe impl<'rp, 'buf> Send for RepacketizerState<'rp, 'buf> {}
1039
1040impl<'rp, 'buf> RepacketizerState<'rp, 'buf> {
1041 pub fn cat(&mut self, packet: &'buf [u8]) -> Result<()> {
1043 ffi!(opus_repacketizer_cat, self.ptr, packet.as_ptr(), len(packet));
1044 Ok(())
1045 }
1046
1047 #[inline]
1049 pub fn cat_move<'b2>(self, packet: &'b2 [u8]) -> Result<RepacketizerState<'rp, 'b2>>
1050 where
1051 'buf: 'b2,
1052 {
1053 let mut shorter = self;
1054 shorter.cat(packet)?;
1055 Ok(shorter)
1056 }
1057
1058 pub fn get_nb_frames(&mut self) -> usize {
1061 unsafe { ffi::opus_repacketizer_get_nb_frames(self.ptr) as usize }
1062 }
1063
1064 pub fn out(&mut self, buffer: &mut [u8]) -> Result<usize> {
1068 let result = ffi!(opus_repacketizer_out, self.ptr, buffer.as_mut_ptr(), len(buffer));
1069 Ok(result as usize)
1070 }
1071
1072 pub fn out_range(&mut self, begin: usize, end: usize, buffer: &mut [u8]) -> Result<usize> {
1077 let result = ffi!(
1078 opus_repacketizer_out_range,
1079 self.ptr,
1080 check_len(begin),
1081 check_len(end),
1082 buffer.as_mut_ptr(),
1083 len(buffer)
1084 );
1085 Ok(result as usize)
1086 }
1087}
1088
1089#[derive(Debug)]
1096pub struct MSEncoder {
1097 ptr: *mut ffi::OpusMSEncoder,
1098 channels: c_int,
1099}
1100
1101impl Drop for MSEncoder {
1102 fn drop(&mut self) {
1103 unsafe { ffi::opus_multistream_encoder_destroy(self.ptr) }
1104 }
1105}
1106
1107unsafe impl Send for MSEncoder {}
1109
1110impl MSEncoder {
1111 pub fn new(
1113 sample_rate: u32,
1114 streams: u8,
1115 coupled_streams: u8,
1116 mapping: &[u8],
1117 application: Application,
1118 ) -> Result<MSEncoder> {
1119 let mut error = 0;
1120 let ptr = unsafe {
1121 ffi::opus_multistream_encoder_create(
1122 sample_rate as i32,
1123 len(mapping),
1124 streams as c_int,
1125 coupled_streams as c_int,
1126 mapping.as_ptr(),
1127 application as c_int,
1128 &mut error,
1129 )
1130 };
1131 if error != ffi::OPUS_OK || ptr.is_null() {
1132 Err(Error::from_code("opus_multistream_encoder_create", error))
1133 } else {
1134 Ok(MSEncoder { ptr, channels: len(mapping) })
1135 }
1136 }
1137
1138 pub fn encode(&mut self, input: &[i16], output: &mut [u8]) -> Result<usize> {
1143 let len = ffi!(
1144 opus_multistream_encode,
1145 self.ptr,
1146 input.as_ptr(),
1147 len(input) / self.channels as c_int,
1148 output.as_mut_ptr(),
1149 len(output)
1150 );
1151 Ok(len as usize)
1152 }
1153
1154 pub fn encode_float(&mut self, input: &[f32], output: &mut [u8]) -> Result<usize> {
1156 let len = ffi!(
1157 opus_multistream_encode_float,
1158 self.ptr,
1159 input.as_ptr(),
1160 len(input) / self.channels as c_int,
1161 output.as_mut_ptr(),
1162 len(output)
1163 );
1164 Ok(len as usize)
1165 }
1166
1167 pub fn encode_vec(&mut self, input: &[i16], max_size: usize) -> Result<Vec<u8>> {
1169 let mut output: Vec<u8> = vec![0; max_size];
1170 let result = self.encode(input, output.as_mut_slice())?;
1171 output.truncate(result);
1172 Ok(output)
1173 }
1174
1175 pub fn encode_vec_float(&mut self, input: &[f32], max_size: usize) -> Result<Vec<u8>> {
1177 let mut output: Vec<u8> = vec![0; max_size];
1178 let result = self.encode_float(input, output.as_mut_slice())?;
1179 output.truncate(result);
1180 Ok(output)
1181 }
1182}
1183
1184generic_ctls!(MSEncoder, opus_multistream_encoder_ctl);
1185encoder_ctls!(MSEncoder, opus_multistream_encoder_ctl);
1186
1187#[derive(Debug)]
1191pub struct MSDecoder {
1192 ptr: *mut ffi::OpusMSDecoder,
1193 channels: c_int,
1194}
1195
1196impl Drop for MSDecoder {
1197 fn drop(&mut self) {
1198 unsafe { ffi::opus_multistream_decoder_destroy(self.ptr) }
1199 }
1200}
1201
1202unsafe impl Send for MSDecoder {}
1204
1205impl MSDecoder {
1206 pub fn new(
1208 sample_rate: u32,
1209 streams: u8,
1210 coupled_streams: u8,
1211 mapping: &[u8],
1212 ) -> Result<MSDecoder> {
1213 let mut error = 0;
1214 let ptr = unsafe {
1215 ffi::opus_multistream_decoder_create(
1216 sample_rate as i32,
1217 len(mapping),
1218 streams as c_int,
1219 coupled_streams as c_int,
1220 mapping.as_ptr(),
1221 &mut error,
1222 )
1223 };
1224 if error != ffi::OPUS_OK || ptr.is_null() {
1225 Err(Error::from_code("opus_multistream_decoder_create", error))
1226 } else {
1227 Ok(MSDecoder { ptr, channels: len(mapping) })
1228 }
1229 }
1230
1231 pub fn decode(&mut self, input: &[u8], output: &mut [i16], fec: bool) -> Result<usize> {
1235 let ptr = match input.len() {
1236 0 => std::ptr::null(),
1237 _ => input.as_ptr(),
1238 };
1239 let len = ffi!(
1240 opus_multistream_decode,
1241 self.ptr,
1242 ptr,
1243 len(input),
1244 output.as_mut_ptr(),
1245 len(output) / self.channels as c_int,
1246 fec as c_int
1247 );
1248 Ok(len as usize)
1249 }
1250
1251 pub fn decode_float(&mut self, input: &[u8], output: &mut [f32], fec: bool) -> Result<usize> {
1253 let ptr = match input.len() {
1254 0 => std::ptr::null(),
1255 _ => input.as_ptr(),
1256 };
1257 let len = ffi!(
1258 opus_multistream_decode_float,
1259 self.ptr,
1260 ptr,
1261 len(input),
1262 output.as_mut_ptr(),
1263 len(output) / self.channels as c_int,
1264 fec as c_int
1265 );
1266 Ok(len as usize)
1267 }
1268}
1269
1270generic_ctls!(MSDecoder, opus_multistream_decoder_ctl);
1271decoder_ctls!(MSDecoder, opus_multistream_decoder_ctl);
1272
1273pub type Result<T> = std::result::Result<T, Error>;
1278
1279#[derive(Debug)]
1281pub struct Error {
1282 function: &'static str,
1283 code: ErrorCode,
1284}
1285
1286impl Error {
1287 fn bad_arg(what: &'static str) -> Error {
1288 Error { function: what, code: ErrorCode::BadArg }
1289 }
1290
1291 fn from_code(what: &'static str, code: c_int) -> Error {
1292 Error {
1293 function: what,
1294 code: ErrorCode::from_int(code),
1295 }
1296 }
1297
1298 #[inline]
1300 pub fn function(&self) -> &'static str {
1301 self.function
1302 }
1303
1304 #[inline]
1306 pub fn description(&self) -> &'static str {
1307 self.code.description()
1308 }
1309
1310 #[inline]
1312 pub fn code(&self) -> ErrorCode {
1313 self.code
1314 }
1315}
1316
1317impl std::fmt::Display for Error {
1318 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
1319 write!(f, "{}: {}", self.function, self.description())
1320 }
1321}
1322
1323impl std::error::Error for Error {
1324 fn description(&self) -> &str {
1325 self.code.description()
1326 }
1327}
1328
1329fn check_len(val: usize) -> c_int {
1330 match c_int::try_from(val) {
1331 Ok(val2) => val2,
1332 Err(_) => panic!("length out of range: {}", val),
1333 }
1334}
1335
1336#[inline]
1337fn len<T>(slice: &[T]) -> c_int {
1338 check_len(slice.len())
1339}