1#![warn(missing_docs)]
14
15extern crate opus_cmake_sys;
16
17use std::ffi::CStr;
18use std::marker::PhantomData;
19use std::os::raw::c_int;
20
21const OPUS_RESET_STATE: c_int = 4028; const OPUS_GET_FINAL_RANGE: c_int = 4031; const OPUS_GET_BANDWIDTH: c_int = 4009; const OPUS_GET_SAMPLE_RATE: c_int = 4029; const OPUS_SET_BITRATE: c_int = 4002; const OPUS_GET_BITRATE: c_int = 4003; const OPUS_SET_VBR: c_int = 4006; const OPUS_GET_VBR: c_int = 4007; const OPUS_SET_VBR_CONSTRAINT: c_int = 4020; const OPUS_GET_VBR_CONSTRAINT: c_int = 4021; const OPUS_SET_INBAND_FEC: c_int = 4012; const OPUS_GET_INBAND_FEC: c_int = 4013; const OPUS_SET_PACKET_LOSS_PERC: c_int = 4014; const OPUS_GET_PACKET_LOSS_PERC: c_int = 4015; const OPUS_GET_LOOKAHEAD: c_int = 4027; const OPUS_SET_GAIN: c_int = 4034; const OPUS_GET_GAIN: c_int = 4045; const OPUS_GET_LAST_PACKET_DURATION: c_int = 4039; const OPUS_GET_PITCH: c_int = 4033; const OPUS_AUTO: c_int = -1000;
49const OPUS_BITRATE_MAX: c_int = -1;
50
51pub mod ffi {
53 pub use opus_cmake_sys::*;
54}
55
56#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
58pub enum Application {
59 Voip = 2048,
62 Audio = 2049,
65 LowDelay = 2051,
67}
68
69#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
71pub enum Channels {
72 Mono = 1,
74 Stereo = 2,
76}
77
78#[derive(Debug, Clone, Copy, Eq, PartialEq, Hash)]
80pub enum Bandwidth {
81 Auto = -1000,
83 Narrowband = 1101,
85 Mediumband = 1102,
87 Wideband = 1103,
89 Superwideband = 1104,
91 Fullband = 1105,
93}
94
95impl Bandwidth {
96 fn from_int(value: i32) -> Option<Bandwidth> {
97 Some(match value {
98 -1000 => Bandwidth::Auto,
99 1101 => Bandwidth::Narrowband,
100 1102 => Bandwidth::Mediumband,
101 1103 => Bandwidth::Wideband,
102 1104 => Bandwidth::Superwideband,
103 1105 => Bandwidth::Fullband,
104 _ => return None,
105 })
106 }
107
108 fn decode(value: i32, what: &'static str) -> Result<Bandwidth> {
109 match Bandwidth::from_int(value) {
110 Some(bandwidth) => Ok(bandwidth),
111 None => Err(Error::bad_arg(what)),
112 }
113 }
114}
115
116#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
118pub enum ErrorCode {
119 BadArg = -1,
121 BufferTooSmall = -2,
123 InternalError = -3,
125 InvalidPacket = -4,
127 Unimplemented = -5,
129 InvalidState = -6,
131 AllocFail = -7,
133 Unknown = -8,
135}
136
137impl ErrorCode {
138 fn from_int(value: c_int) -> ErrorCode {
139 use ErrorCode::*;
140 match value {
141 ffi::OPUS_BAD_ARG => BadArg,
142 ffi::OPUS_BUFFER_TOO_SMALL => BufferTooSmall,
143 ffi::OPUS_INTERNAL_ERROR => InternalError,
144 ffi::OPUS_INVALID_PACKET => InvalidPacket,
145 ffi::OPUS_UNIMPLEMENTED => Unimplemented,
146 ffi::OPUS_INVALID_STATE => InvalidState,
147 ffi::OPUS_ALLOC_FAIL => AllocFail,
148 _ => Unknown,
149 }
150 }
151
152 pub fn description(self) -> &'static str {
154 unsafe { CStr::from_ptr(ffi::opus_strerror(self as c_int)) }.to_str().unwrap()
156 }
157}
158
159#[derive(Debug, Copy, Clone, Eq, PartialEq, Hash)]
161pub enum Bitrate {
162 Bits(i32),
164 Max,
166 Auto,
168}
169
170pub fn version() -> &'static str {
176 unsafe { CStr::from_ptr(ffi::opus_get_version_string()) }.to_str().unwrap()
178}
179
180macro_rules! ffi {
181 ($f:ident $(, $rest:expr)*) => {
182 match unsafe { ffi::$f($($rest),*) } {
183 code if code < 0 => return Err(Error::from_code(stringify!($f), code)),
184 code => code,
185 }
186 }
187}
188
189macro_rules! ctl {
190 ($f:ident, $this:ident, $ctl:ident, $($rest:expr),*) => {
191 match unsafe { ffi::$f($this.ptr, $ctl, $($rest),*) } {
192 code if code < 0 => return Err(Error::from_code(
193 concat!(stringify!($f), "(", stringify!($ctl), ")"),
194 code,
195 )),
196 _ => (),
197 }
198 }
199}
200
201macro_rules! enc_ctl {
205 ($this:ident, $ctl:ident $(, $rest:expr)*) => {
206 ctl!(opus_encoder_ctl, $this, $ctl, $($rest),*)
207 }
208}
209
210#[derive(Debug)]
212pub struct Encoder {
213 ptr: *mut ffi::OpusEncoder,
214 channels: Channels,
215}
216
217impl Encoder {
218 pub fn new(sample_rate: u32, channels: Channels, mode: Application) -> Result<Encoder> {
220 let mut error = 0;
221 let ptr = unsafe {
222 ffi::opus_encoder_create(
223 sample_rate as i32,
224 channels as c_int,
225 mode as c_int,
226 &mut error)
227 };
228 if error != ffi::OPUS_OK || ptr.is_null() {
229 Err(Error::from_code("opus_encoder_create", error))
230 } else {
231 Ok(Encoder { ptr: ptr, channels: channels })
232 }
233 }
234
235 pub fn encode(&mut self, input: &[i16], output: &mut [u8]) -> Result<usize> {
237 let len = ffi!(opus_encode, self.ptr,
238 input.as_ptr(), len(input) / self.channels as c_int,
239 output.as_mut_ptr(), len(output));
240 Ok(len as usize)
241 }
242
243 pub fn encode_float(&mut self, input: &[f32], output: &mut [u8]) -> Result<usize> {
245 let len = ffi!(opus_encode_float, self.ptr,
246 input.as_ptr(), len(input) / self.channels as c_int,
247 output.as_mut_ptr(), len(output));
248 Ok(len as usize)
249 }
250
251 pub fn encode_vec(&mut self, input: &[i16], max_size: usize) -> Result<Vec<u8>> {
253 let mut output: Vec<u8> = vec![0; max_size];
254 let result = self.encode(input, output.as_mut_slice())?;
255 output.truncate(result);
256 Ok(output)
257 }
258
259 pub fn encode_vec_float(&mut self, input: &[f32], max_size: usize) -> Result<Vec<u8>> {
261 let mut output: Vec<u8> = vec![0; max_size];
262 let result = self.encode_float(input, output.as_mut_slice())?;
263 output.truncate(result);
264 Ok(output)
265 }
266
267 pub fn reset_state(&mut self) -> Result<()> {
272 enc_ctl!(self, OPUS_RESET_STATE);
273 Ok(())
274 }
275
276 pub fn get_final_range(&mut self) -> Result<u32> {
278 let mut value: u32 = 0;
279 enc_ctl!(self, OPUS_GET_FINAL_RANGE, &mut value);
280 Ok(value)
281 }
282
283 pub fn get_bandwidth(&mut self) -> Result<Bandwidth> {
285 let mut value: i32 = 0;
286 enc_ctl!(self, OPUS_GET_BANDWIDTH, &mut value);
287 Bandwidth::decode(value, "opus_encoder_ctl(OPUS_GET_BANDWIDTH)")
288 }
289
290 pub fn get_sample_rate(&mut self) -> Result<u32> {
292 let mut value: i32 = 0;
293 enc_ctl!(self, OPUS_GET_SAMPLE_RATE, &mut value);
294 Ok(value as u32)
295 }
296
297 pub fn set_bitrate(&mut self, value: Bitrate) -> Result<()> {
302 let value: i32 = match value {
303 Bitrate::Auto => OPUS_AUTO,
304 Bitrate::Max => OPUS_BITRATE_MAX,
305 Bitrate::Bits(b) => b,
306 };
307 enc_ctl!(self, OPUS_SET_BITRATE, value);
308 Ok(())
309 }
310
311 pub fn get_bitrate(&mut self) -> Result<Bitrate> {
313 let mut value: i32 = 0;
314 enc_ctl!(self, OPUS_GET_BITRATE, &mut value);
315 Ok(match value {
316 OPUS_AUTO => Bitrate::Auto,
317 OPUS_BITRATE_MAX => Bitrate::Max,
318 _ => Bitrate::Bits(value),
319 })
320 }
321
322 pub fn set_vbr(&mut self, vbr: bool) -> Result<()> {
324 let value: i32 = if vbr { 1 } else { 0 };
325 enc_ctl!(self, OPUS_SET_VBR, value);
326 Ok(())
327 }
328
329 pub fn get_vbr(&mut self) -> Result<bool> {
331 let mut value: i32 = 0;
332 enc_ctl!(self, OPUS_GET_VBR, &mut value);
333 Ok(value != 0)
334 }
335
336 pub fn set_vbr_constraint(&mut self, vbr: bool) -> Result<()> {
338 let value: i32 = if vbr { 1 } else { 0 };
339 enc_ctl!(self, OPUS_SET_VBR_CONSTRAINT, value);
340 Ok(())
341 }
342
343 pub fn get_vbr_constraint(&mut self) -> Result<bool> {
345 let mut value: i32 = 0;
346 enc_ctl!(self, OPUS_GET_VBR_CONSTRAINT, &mut value);
347 Ok(value != 0)
348 }
349
350 pub fn set_inband_fec(&mut self, value: bool) -> Result<()> {
352 let value: i32 = if value { 1 } else { 0 };
353 enc_ctl!(self, OPUS_SET_INBAND_FEC, value);
354 Ok(())
355 }
356
357 pub fn get_inband_fec(&mut self) -> Result<bool> {
359 let mut value: i32 = 0;
360 enc_ctl!(self, OPUS_GET_INBAND_FEC, &mut value);
361 Ok(value != 0)
362 }
363
364 pub fn set_packet_loss_perc(&mut self, value: i32) -> Result<()> {
366 enc_ctl!(self, OPUS_SET_PACKET_LOSS_PERC, value);
367 Ok(())
368 }
369
370 pub fn get_packet_loss_perc(&mut self) -> Result<i32> {
372 let mut value: i32 = 0;
373 enc_ctl!(self, OPUS_GET_PACKET_LOSS_PERC, &mut value);
374 Ok(value)
375 }
376
377 pub fn get_lookahead(&mut self) -> Result<i32> {
379 let mut value: i32 = 0;
380 enc_ctl!(self, OPUS_GET_LOOKAHEAD, &mut value);
381 Ok(value)
382 }
383
384 }
386
387impl Drop for Encoder {
388 fn drop(&mut self) {
389 unsafe { ffi::opus_encoder_destroy(self.ptr) }
390 }
391}
392
393unsafe impl Send for Encoder {}
404
405macro_rules! dec_ctl {
409 ($this:ident, $ctl:ident $(, $rest:expr)*) => {
410 ctl!(opus_decoder_ctl, $this, $ctl, $($rest),*)
411 }
412}
413
414#[derive(Debug)]
416pub struct Decoder {
417 ptr: *mut ffi::OpusDecoder,
418 channels: Channels,
419}
420
421impl Decoder {
422 pub fn new(sample_rate: u32, channels: Channels) -> Result<Decoder> {
424 let mut error = 0;
425 let ptr = unsafe { ffi::opus_decoder_create(
426 sample_rate as i32,
427 channels as c_int,
428 &mut error) };
429 if error != ffi::OPUS_OK || ptr.is_null() {
430 Err(Error::from_code("opus_decoder_create", error))
431 } else {
432 Ok(Decoder { ptr: ptr, channels: channels })
433 }
434 }
435
436 pub fn decode(&mut self, input: &[u8], output: &mut [i16], fec: bool) -> Result<usize> {
438 let ptr = match input.len() {
439 0 => std::ptr::null(),
440 _ => input.as_ptr(),
441 };
442 let len = ffi!(opus_decode, self.ptr,
443 ptr, len(input),
444 output.as_mut_ptr(), len(output) / self.channels as c_int,
445 fec as c_int);
446 Ok(len as usize)
447 }
448
449 pub fn decode_float(&mut self, input: &[u8], output: &mut [f32], fec: bool) -> Result<usize> {
451 let ptr = match input.len() {
452 0 => std::ptr::null(),
453 _ => input.as_ptr(),
454 };
455 let len = ffi!(opus_decode_float, self.ptr,
456 ptr, len(input),
457 output.as_mut_ptr(), len(output) / self.channels as c_int,
458 fec as c_int);
459 Ok(len as usize)
460 }
461
462 pub fn get_nb_samples(&self, packet: &[u8]) -> Result<usize> {
464 let len = ffi!(opus_decoder_get_nb_samples, self.ptr,
465 packet.as_ptr(), packet.len() as i32);
466 Ok(len as usize)
467 }
468
469 pub fn reset_state(&mut self) -> Result<()> {
474 dec_ctl!(self, OPUS_RESET_STATE);
475 Ok(())
476 }
477
478 pub fn get_final_range(&mut self) -> Result<u32> {
480 let mut value: u32 = 0;
481 dec_ctl!(self, OPUS_GET_FINAL_RANGE, &mut value);
482 Ok(value)
483 }
484
485 pub fn get_bandwidth(&mut self) -> Result<Bandwidth> {
487 let mut value: i32 = 0;
488 dec_ctl!(self, OPUS_GET_BANDWIDTH, &mut value);
489 Bandwidth::decode(value, "opus_decoder_ctl(OPUS_GET_BANDWIDTH)")
490 }
491
492 pub fn get_sample_rate(&mut self) -> Result<u32> {
494 let mut value: i32 = 0;
495 dec_ctl!(self, OPUS_GET_SAMPLE_RATE, &mut value);
496 Ok(value as u32)
497 }
498
499 pub fn set_gain(&mut self, gain: i32) -> Result<()> {
511 dec_ctl!(self, OPUS_SET_GAIN, gain);
512 Ok(())
513 }
514
515 pub fn get_gain(&mut self) -> Result<i32> {
517 let mut value: i32 = 0;
518 dec_ctl!(self, OPUS_GET_GAIN, &mut value);
519 Ok(value)
520 }
521
522 pub fn get_last_packet_duration(&mut self) -> Result<u32> {
525 let mut value: i32 = 0;
526 dec_ctl!(self, OPUS_GET_LAST_PACKET_DURATION, &mut value);
527 Ok(value as u32)
528 }
529
530 pub fn get_pitch(&mut self) -> Result<i32> {
537 let mut value: i32 = 0;
538 dec_ctl!(self, OPUS_GET_PITCH, &mut value);
539 Ok(value)
540 }
541}
542
543impl Drop for Decoder {
544 fn drop(&mut self) {
545 unsafe { ffi::opus_decoder_destroy(self.ptr) }
546 }
547}
548
549unsafe impl Send for Decoder {}
551
552pub mod packet {
557 use super::*;
558 use super::ffi;
559 use std::{ptr, slice};
560
561 pub fn get_bandwidth(packet: &[u8]) -> Result<Bandwidth> {
563 if packet.len() < 1 {
564 return Err(Error::bad_arg("opus_packet_get_bandwidth"));
565 }
566 let bandwidth = ffi!(opus_packet_get_bandwidth, packet.as_ptr());
567 Bandwidth::decode(bandwidth, "opus_packet_get_bandwidth")
568 }
569
570 pub fn get_nb_channels(packet: &[u8]) -> Result<Channels> {
572 if packet.len() < 1 {
573 return Err(Error::bad_arg("opus_packet_get_nb_channels"));
574 }
575 let channels = ffi!(opus_packet_get_nb_channels, packet.as_ptr());
576 match channels {
577 1 => Ok(Channels::Mono),
578 2 => Ok(Channels::Stereo),
579 _ => Err(Error::bad_arg("opus_packet_get_nb_channels")),
580 }
581 }
582
583 pub fn get_nb_frames(packet: &[u8]) -> Result<usize> {
585 let frames = ffi!(opus_packet_get_nb_frames, packet.as_ptr(), len(packet));
586 Ok(frames as usize)
587 }
588
589 pub fn get_nb_samples(packet: &[u8], sample_rate: u32) -> Result<usize> {
591 let frames = ffi!(opus_packet_get_nb_samples,
592 packet.as_ptr(), len(packet),
593 sample_rate as c_int);
594 Ok(frames as usize)
595 }
596
597 pub fn get_samples_per_frame(packet: &[u8], sample_rate: u32) -> Result<usize> {
599 if packet.len() < 1 {
600 return Err(Error::bad_arg("opus_packet_get_samples_per_frame"))
601 }
602 let samples = ffi!(opus_packet_get_samples_per_frame,
603 packet.as_ptr(), sample_rate as c_int);
604 Ok(samples as usize)
605 }
606
607 pub fn parse(packet: &[u8]) -> Result<Packet> {
609 let mut toc: u8 = 0;
610 let mut frames = [ptr::null(); 48];
611 let mut sizes = [0i16; 48];
612 let mut payload_offset: i32 = 0;
613 let num_frames = ffi!(opus_packet_parse,
614 packet.as_ptr(), len(packet),
615 &mut toc, frames.as_mut_ptr(),
616 sizes.as_mut_ptr(), &mut payload_offset);
617
618 let mut frames_vec = Vec::with_capacity(num_frames as usize);
619 for i in 0..num_frames as usize {
620 frames_vec.push(unsafe { slice::from_raw_parts(frames[i], sizes[i] as usize) });
621 }
622
623 Ok(Packet {
624 toc: toc,
625 frames: frames_vec,
626 payload_offset: payload_offset as usize,
627 })
628 }
629
630 #[derive(Debug)]
632 pub struct Packet<'a> {
633 pub toc: u8,
635 pub frames: Vec<&'a [u8]>,
637 pub payload_offset: usize,
639 }
640
641 pub fn pad(packet: &mut [u8], prev_len: usize) -> Result<usize> {
646 let result = ffi!(opus_packet_pad, packet.as_mut_ptr(),
647 check_len(prev_len), len(packet));
648 Ok(result as usize)
649 }
650
651 pub fn unpad(packet: &mut [u8]) -> Result<usize> {
654 let result = ffi!(opus_packet_unpad, packet.as_mut_ptr(), len(packet));
655 Ok(result as usize)
656 }
657}
658
659#[derive(Debug)]
664pub struct SoftClip {
665 channels: Channels,
666 memory: [f32; 2],
667}
668
669impl SoftClip {
670 pub fn new(channels: Channels) -> SoftClip {
672 SoftClip { channels: channels, memory: [0.0; 2] }
673 }
674
675 pub fn apply(&mut self, signal: &mut [f32]) {
677 unsafe { ffi::opus_pcm_soft_clip(
678 signal.as_mut_ptr(),
679 len(signal) / self.channels as c_int,
680 self.channels as c_int,
681 self.memory.as_mut_ptr()) };
682 }
683}
684
685#[derive(Debug)]
690pub struct Repacketizer {
691 ptr: *mut ffi::OpusRepacketizer,
692}
693
694impl Repacketizer {
695 pub fn new() -> Result<Repacketizer> {
697 let ptr = unsafe { ffi::opus_repacketizer_create() };
698 if ptr.is_null() {
699 Err(Error::from_code("opus_repacketizer_create", ffi::OPUS_ALLOC_FAIL))
700 } else {
701 Ok(Repacketizer { ptr: ptr })
702 }
703 }
704
705 pub fn combine(&mut self, input: &[&[u8]], output: &mut [u8]) -> Result<usize> {
707 let mut state = self.begin();
708 for &packet in input {
709 state.cat(packet)?;
710 }
711 state.out(output)
712 }
713
714 pub fn begin<'rp, 'buf>(&'rp mut self) -> RepacketizerState<'rp, 'buf> {
716 unsafe { ffi::opus_repacketizer_init(self.ptr); }
717 RepacketizerState { rp: self, phantom: PhantomData }
718 }
719}
720
721impl Drop for Repacketizer {
722 fn drop(&mut self) {
723 unsafe { ffi::opus_repacketizer_destroy(self.ptr) }
724 }
725}
726
727unsafe impl Send for Repacketizer {}
729
730#[derive(Debug)]
738pub struct RepacketizerState<'rp, 'buf> {
739 rp: &'rp mut Repacketizer,
740 phantom: PhantomData<&'buf [u8]>,
741}
742
743impl<'rp, 'buf> RepacketizerState<'rp, 'buf> {
744 pub fn cat(&mut self, packet: &'buf [u8]) -> Result<()> {
746 ffi!(opus_repacketizer_cat, self.rp.ptr,
747 packet.as_ptr(), len(packet));
748 Ok(())
749 }
750
751 #[inline]
753 pub fn cat_move<'b2>(self, packet: &'b2 [u8]) -> Result<RepacketizerState<'rp, 'b2>> where 'buf: 'b2 {
754 let mut shorter = self;
755 shorter.cat(packet)?;
756 Ok(shorter)
757 }
758
759 pub fn get_nb_frames(&mut self) -> usize {
762 unsafe { ffi::opus_repacketizer_get_nb_frames(self.rp.ptr) as usize }
763 }
764
765 pub fn out(&mut self, buffer: &mut [u8]) -> Result<usize> {
769 let result = ffi!(opus_repacketizer_out, self.rp.ptr,
770 buffer.as_mut_ptr(), len(buffer));
771 Ok(result as usize)
772 }
773
774 pub fn out_range(&mut self, begin: usize, end: usize, buffer: &mut [u8]) -> Result<usize> {
779 let result = ffi!(opus_repacketizer_out_range, self.rp.ptr,
780 check_len(begin), check_len(end),
781 buffer.as_mut_ptr(), len(buffer));
782 Ok(result as usize)
783 }
784}
785
786pub type Result<T> = std::result::Result<T, Error>;
794
795#[derive(Debug)]
797pub struct Error {
798 function: &'static str,
799 code: ErrorCode,
800}
801
802impl Error {
803 fn bad_arg(what: &'static str) -> Error {
804 Error { function: what, code: ErrorCode::BadArg }
805 }
806
807 fn from_code(what: &'static str, code: c_int) -> Error {
808 Error { function: what, code: ErrorCode::from_int(code) }
809 }
810
811 #[inline]
813 pub fn function(&self) -> &'static str { self.function }
814
815 #[inline]
817 pub fn description(&self) -> &'static str { self.code.description() }
818
819 #[inline]
821 pub fn code(&self) -> ErrorCode { self.code }
822}
823
824impl std::fmt::Display for Error {
825 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
826 write!(f, "{}: {}", self.function, self.description())
827 }
828}
829
830impl std::error::Error for Error {
831 fn description(&self) -> &str {
832 self.code.description()
833 }
834}
835
836fn check_len(val: usize) -> c_int {
837 let len = val as c_int;
838 if len as usize != val {
839 panic!("length out of range: {}", val);
840 }
841 len
842}
843
844#[inline]
845fn len<T>(slice: &[T]) -> c_int {
846 check_len(slice.len())
847}