1use crate::bindings::{
4 OPUS_AUTO, OPUS_BANDWIDTH_FULLBAND, OPUS_BITRATE_MAX, OPUS_GET_BANDWIDTH_REQUEST,
5 OPUS_GET_BITRATE_REQUEST, OPUS_GET_COMPLEXITY_REQUEST, OPUS_GET_DTX_REQUEST,
6 OPUS_GET_EXPERT_FRAME_DURATION_REQUEST, OPUS_GET_FINAL_RANGE_REQUEST,
7 OPUS_GET_FORCE_CHANNELS_REQUEST, OPUS_GET_IN_DTX_REQUEST, OPUS_GET_INBAND_FEC_REQUEST,
8 OPUS_GET_LOOKAHEAD_REQUEST, OPUS_GET_LSB_DEPTH_REQUEST, OPUS_GET_MAX_BANDWIDTH_REQUEST,
9 OPUS_GET_PACKET_LOSS_PERC_REQUEST, OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST,
10 OPUS_GET_PREDICTION_DISABLED_REQUEST, OPUS_GET_SIGNAL_REQUEST, OPUS_GET_VBR_CONSTRAINT_REQUEST,
11 OPUS_GET_VBR_REQUEST, OPUS_SET_BANDWIDTH_REQUEST, OPUS_SET_BITRATE_REQUEST,
12 OPUS_SET_COMPLEXITY_REQUEST, OPUS_SET_DTX_REQUEST, OPUS_SET_EXPERT_FRAME_DURATION_REQUEST,
13 OPUS_SET_FORCE_CHANNELS_REQUEST, OPUS_SET_INBAND_FEC_REQUEST, OPUS_SET_LSB_DEPTH_REQUEST,
14 OPUS_SET_MAX_BANDWIDTH_REQUEST, OPUS_SET_PACKET_LOSS_PERC_REQUEST,
15 OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_SET_PREDICTION_DISABLED_REQUEST,
16 OPUS_SET_SIGNAL_REQUEST, OPUS_SET_VBR_CONSTRAINT_REQUEST, OPUS_SET_VBR_REQUEST, OpusEncoder,
17 opus_encode, opus_encode_float, opus_encoder_create, opus_encoder_ctl, opus_encoder_destroy,
18 opus_encoder_get_size, opus_encoder_init,
19};
20use crate::constants::max_frame_samples_for;
21use crate::error::{Error, Result};
22use crate::types::{
23 Application, Bandwidth, Bitrate, Channels, Complexity, ExpertFrameDuration, SampleRate, Signal,
24};
25use crate::{AlignedBuffer, Ownership, RawHandle};
26use std::marker::PhantomData;
27use std::num::NonZeroUsize;
28use std::ops::{Deref, DerefMut};
29use std::ptr::NonNull;
30
31pub struct Encoder {
33 raw: RawHandle<OpusEncoder>,
34 sample_rate: SampleRate,
35 channels: Channels,
36}
37
38unsafe impl Send for Encoder {}
39unsafe impl Sync for Encoder {}
40
41pub struct EncoderRef<'a> {
43 inner: Encoder,
44 _marker: PhantomData<&'a mut OpusEncoder>,
45}
46
47unsafe impl Send for EncoderRef<'_> {}
48unsafe impl Sync for EncoderRef<'_> {}
49
50impl Encoder {
51 fn from_raw(
52 ptr: NonNull<OpusEncoder>,
53 sample_rate: SampleRate,
54 channels: Channels,
55 ownership: Ownership,
56 ) -> Self {
57 Self {
58 raw: RawHandle::new(ptr, ownership, opus_encoder_destroy),
59 sample_rate,
60 channels,
61 }
62 }
63
64 pub fn size(channels: Channels) -> Result<usize> {
70 let raw = unsafe { opus_encoder_get_size(channels.as_i32()) };
71 if raw <= 0 {
72 return Err(Error::BadArg);
73 }
74 usize::try_from(raw).map_err(|_| Error::InternalError)
75 }
76
77 pub unsafe fn init_in_place(
86 ptr: *mut OpusEncoder,
87 sample_rate: SampleRate,
88 channels: Channels,
89 application: Application,
90 ) -> Result<()> {
91 if ptr.is_null() {
92 return Err(Error::BadArg);
93 }
94 if !crate::opus_ptr_is_aligned(ptr.cast()) {
95 return Err(Error::BadArg);
96 }
97 let r = unsafe {
98 opus_encoder_init(
99 ptr,
100 sample_rate.as_i32(),
101 channels.as_i32(),
102 application as i32,
103 )
104 };
105 if r != 0 {
106 return Err(Error::from_code(r));
107 }
108 Ok(())
109 }
110
111 pub fn new(
116 sample_rate: SampleRate,
117 channels: Channels,
118 application: Application,
119 ) -> Result<Self> {
120 if !sample_rate.is_valid() {
122 return Err(Error::BadArg);
123 }
124
125 let mut error = 0i32;
126 let encoder = unsafe {
127 opus_encoder_create(
128 sample_rate.as_i32(),
129 channels.as_i32(),
130 application as i32,
131 std::ptr::addr_of_mut!(error),
132 )
133 };
134
135 if error != 0 {
136 return Err(Error::from_code(error));
137 }
138
139 let encoder = NonNull::new(encoder).ok_or(Error::AllocFail)?;
140
141 Ok(Self::from_raw(
142 encoder,
143 sample_rate,
144 channels,
145 Ownership::Owned,
146 ))
147 }
148
149 pub fn encode(&mut self, input: &[i16], output: &mut [u8]) -> Result<usize> {
155 if input.is_empty() {
157 return Err(Error::BadArg);
158 }
159
160 if !input.len().is_multiple_of(self.channels.as_usize()) {
162 return Err(Error::BadArg);
163 }
164
165 let frame_size = input.len() / self.channels.as_usize();
166 let frame_size = NonZeroUsize::new(frame_size).ok_or(Error::BadArg)?;
167 if frame_size.get() > max_frame_samples_for(self.sample_rate) {
169 return Err(Error::BadArg);
170 }
171
172 if output.is_empty() {
174 return Err(Error::BadArg);
175 }
176 if output.len() > i32::MAX as usize {
177 return Err(Error::BadArg);
178 }
179
180 let frame_size_i32 = i32::try_from(frame_size.get()).map_err(|_| Error::BadArg)?;
181 let out_len_i32 = i32::try_from(output.len()).map_err(|_| Error::BadArg)?;
182 let result = unsafe {
183 opus_encode(
184 self.raw.as_ptr(),
185 input.as_ptr(),
186 frame_size_i32,
187 output.as_mut_ptr(),
188 out_len_i32,
189 )
190 };
191
192 if result < 0 {
193 return Err(Error::from_code(result));
194 }
195
196 usize::try_from(result).map_err(|_| Error::InternalError)
197 }
198
199 pub fn encode_limited(
208 &mut self,
209 input: &[i16],
210 output: &mut [u8],
211 max_data_bytes: usize,
212 ) -> Result<usize> {
213 if input.is_empty() {
215 return Err(Error::BadArg);
216 }
217
218 if !input.len().is_multiple_of(self.channels.as_usize()) {
220 return Err(Error::BadArg);
221 }
222
223 let frame_size = input.len() / self.channels.as_usize();
224 let frame_size = NonZeroUsize::new(frame_size).ok_or(Error::BadArg)?;
225 if frame_size.get() > max_frame_samples_for(self.sample_rate) {
227 return Err(Error::BadArg);
228 }
229
230 if output.is_empty() {
232 return Err(Error::BadArg);
233 }
234 if output.len() > i32::MAX as usize {
235 return Err(Error::BadArg);
236 }
237 if max_data_bytes == 0 || max_data_bytes > output.len() {
239 return Err(Error::BadArg);
240 }
241
242 let frame_size_i32 = i32::try_from(frame_size.get()).map_err(|_| Error::BadArg)?;
243 let max_bytes_i32 = i32::try_from(max_data_bytes).map_err(|_| Error::BadArg)?;
244 let result = unsafe {
245 opus_encode(
246 self.raw.as_ptr(),
247 input.as_ptr(),
248 frame_size_i32,
249 output.as_mut_ptr(),
250 max_bytes_i32,
251 )
252 };
253
254 if result < 0 {
255 return Err(Error::from_code(result));
256 }
257
258 usize::try_from(result).map_err(|_| Error::InternalError)
259 }
260
261 pub fn encode_float(&mut self, input: &[f32], output: &mut [u8]) -> Result<usize> {
267 if input.is_empty() {
268 return Err(Error::BadArg);
269 }
270 if !input.len().is_multiple_of(self.channels.as_usize()) {
271 return Err(Error::BadArg);
272 }
273 let frame_size = input.len() / self.channels.as_usize();
274 let frame_size = NonZeroUsize::new(frame_size).ok_or(Error::BadArg)?;
275 if frame_size.get() > max_frame_samples_for(self.sample_rate) {
276 return Err(Error::BadArg);
277 }
278 if output.is_empty() || output.len() > i32::MAX as usize {
279 return Err(Error::BadArg);
280 }
281 let frame_i32 = i32::try_from(frame_size.get()).map_err(|_| Error::BadArg)?;
282 let out_len_i32 = i32::try_from(output.len()).map_err(|_| Error::BadArg)?;
283 let n = unsafe {
284 opus_encode_float(
285 self.raw.as_ptr(),
286 input.as_ptr(),
287 frame_i32,
288 output.as_mut_ptr(),
289 out_len_i32,
290 )
291 };
292 if n < 0 {
293 return Err(Error::from_code(n));
294 }
295 usize::try_from(n).map_err(|_| Error::InternalError)
296 }
297
298 pub fn set_inband_fec(&mut self, enabled: bool) -> Result<()> {
305 self.simple_ctl(OPUS_SET_INBAND_FEC_REQUEST as i32, i32::from(enabled))
306 }
307 pub fn inband_fec(&mut self) -> Result<bool> {
312 self.get_bool_ctl(OPUS_GET_INBAND_FEC_REQUEST as i32)
313 }
314
315 pub fn set_packet_loss_perc(&mut self, perc: i32) -> Result<()> {
321 if !(0..=100).contains(&perc) {
322 return Err(Error::BadArg);
323 }
324 self.simple_ctl(OPUS_SET_PACKET_LOSS_PERC_REQUEST as i32, perc)
325 }
326 pub fn packet_loss_perc(&mut self) -> Result<i32> {
331 self.get_int_ctl(OPUS_GET_PACKET_LOSS_PERC_REQUEST as i32)
332 }
333
334 pub fn set_dtx(&mut self, enabled: bool) -> Result<()> {
339 self.simple_ctl(OPUS_SET_DTX_REQUEST as i32, i32::from(enabled))
340 }
341 pub fn dtx(&mut self) -> Result<bool> {
346 self.get_bool_ctl(OPUS_GET_DTX_REQUEST as i32)
347 }
348 pub fn in_dtx(&mut self) -> Result<bool> {
353 self.get_bool_ctl(OPUS_GET_IN_DTX_REQUEST as i32)
354 }
355
356 pub fn set_vbr_constraint(&mut self, constrained: bool) -> Result<()> {
361 self.simple_ctl(
362 OPUS_SET_VBR_CONSTRAINT_REQUEST as i32,
363 i32::from(constrained),
364 )
365 }
366 pub fn vbr_constraint(&mut self) -> Result<bool> {
371 self.get_bool_ctl(OPUS_GET_VBR_CONSTRAINT_REQUEST as i32)
372 }
373
374 pub fn set_max_bandwidth(&mut self, bw: Bandwidth) -> Result<()> {
379 self.simple_ctl(OPUS_SET_MAX_BANDWIDTH_REQUEST as i32, bw as i32)
380 }
381 pub fn max_bandwidth(&mut self) -> Result<Bandwidth> {
386 self.get_bandwidth_ctl(OPUS_GET_MAX_BANDWIDTH_REQUEST as i32)
387 }
388
389 pub fn set_bandwidth(&mut self, bw: Bandwidth) -> Result<()> {
394 self.simple_ctl(OPUS_SET_BANDWIDTH_REQUEST as i32, bw as i32)
395 }
396 pub fn bandwidth(&mut self) -> Result<Bandwidth> {
401 self.get_bandwidth_ctl(OPUS_GET_BANDWIDTH_REQUEST as i32)
402 }
403
404 pub fn set_force_channels(&mut self, channels: Option<Channels>) -> Result<()> {
409 let val = match channels {
410 Some(Channels::Mono) => 1,
411 Some(Channels::Stereo) => 2,
412 None => crate::bindings::OPUS_AUTO,
413 };
414 self.simple_ctl(OPUS_SET_FORCE_CHANNELS_REQUEST as i32, val)
415 }
416 pub fn force_channels(&mut self) -> Result<Option<Channels>> {
421 let v = self.get_int_ctl(OPUS_GET_FORCE_CHANNELS_REQUEST as i32)?;
422 Ok(match v {
423 1 => Some(Channels::Mono),
424 2 => Some(Channels::Stereo),
425 _ => None,
426 })
427 }
428
429 pub fn set_signal(&mut self, signal: Signal) -> Result<()> {
434 self.simple_ctl(OPUS_SET_SIGNAL_REQUEST as i32, signal as i32)
435 }
436 pub fn signal(&mut self) -> Result<Signal> {
442 let v = self.get_int_ctl(OPUS_GET_SIGNAL_REQUEST as i32)?;
443 match v {
444 x if x == OPUS_AUTO => Ok(Signal::Auto),
445 x if x == crate::bindings::OPUS_SIGNAL_VOICE as i32 => Ok(Signal::Voice),
446 x if x == crate::bindings::OPUS_SIGNAL_MUSIC as i32 => Ok(Signal::Music),
447 _ => Err(Error::InternalError),
448 }
449 }
450
451 pub fn lookahead(&mut self) -> Result<i32> {
456 self.get_int_ctl(OPUS_GET_LOOKAHEAD_REQUEST as i32)
457 }
458 pub fn final_range(&mut self) -> Result<u32> {
463 let mut val: u32 = 0;
464 let r = unsafe {
465 opus_encoder_ctl(
466 self.raw.as_ptr(),
467 OPUS_GET_FINAL_RANGE_REQUEST as i32,
468 &mut val,
469 )
470 };
471 if r != 0 {
472 return Err(Error::from_code(r));
473 }
474 Ok(val)
475 }
476
477 pub fn set_lsb_depth(&mut self, bits: i32) -> Result<()> {
483 if !(8..=24).contains(&bits) {
484 return Err(Error::BadArg);
485 }
486 self.simple_ctl(OPUS_SET_LSB_DEPTH_REQUEST as i32, bits)
487 }
488 pub fn lsb_depth(&mut self) -> Result<i32> {
493 self.get_int_ctl(OPUS_GET_LSB_DEPTH_REQUEST as i32)
494 }
495
496 pub fn set_expert_frame_duration(&mut self, dur: ExpertFrameDuration) -> Result<()> {
501 self.simple_ctl(OPUS_SET_EXPERT_FRAME_DURATION_REQUEST as i32, dur as i32)
502 }
503 pub fn expert_frame_duration(&mut self) -> Result<ExpertFrameDuration> {
509 let v = self.get_int_ctl(OPUS_GET_EXPERT_FRAME_DURATION_REQUEST as i32)?;
510 let vu = u32::try_from(v).map_err(|_| Error::InternalError)?;
511 match vu {
512 x if x == crate::bindings::OPUS_FRAMESIZE_ARG => Ok(ExpertFrameDuration::Auto),
513 x if x == crate::bindings::OPUS_FRAMESIZE_2_5_MS => Ok(ExpertFrameDuration::Ms2_5),
514 x if x == crate::bindings::OPUS_FRAMESIZE_5_MS => Ok(ExpertFrameDuration::Ms5),
515 x if x == crate::bindings::OPUS_FRAMESIZE_10_MS => Ok(ExpertFrameDuration::Ms10),
516 x if x == crate::bindings::OPUS_FRAMESIZE_20_MS => Ok(ExpertFrameDuration::Ms20),
517 x if x == crate::bindings::OPUS_FRAMESIZE_40_MS => Ok(ExpertFrameDuration::Ms40),
518 x if x == crate::bindings::OPUS_FRAMESIZE_60_MS => Ok(ExpertFrameDuration::Ms60),
519 x if x == crate::bindings::OPUS_FRAMESIZE_80_MS => Ok(ExpertFrameDuration::Ms80),
520 x if x == crate::bindings::OPUS_FRAMESIZE_100_MS => Ok(ExpertFrameDuration::Ms100),
521 x if x == crate::bindings::OPUS_FRAMESIZE_120_MS => Ok(ExpertFrameDuration::Ms120),
522 _ => Err(Error::InternalError),
523 }
524 }
525
526 pub fn set_prediction_disabled(&mut self, disabled: bool) -> Result<()> {
531 self.simple_ctl(
532 OPUS_SET_PREDICTION_DISABLED_REQUEST as i32,
533 i32::from(disabled),
534 )
535 }
536 pub fn prediction_disabled(&mut self) -> Result<bool> {
541 self.get_bool_ctl(OPUS_GET_PREDICTION_DISABLED_REQUEST as i32)
542 }
543
544 pub fn set_phase_inversion_disabled(&mut self, disabled: bool) -> Result<()> {
549 self.simple_ctl(
550 OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST as i32,
551 i32::from(disabled),
552 )
553 }
554 pub fn phase_inversion_disabled(&mut self) -> Result<bool> {
559 self.get_bool_ctl(OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST as i32)
560 }
561
562 fn simple_ctl(&mut self, req: i32, val: i32) -> Result<()> {
564 let r = unsafe { opus_encoder_ctl(self.raw.as_ptr(), req, val) };
565 if r != 0 {
566 return Err(Error::from_code(r));
567 }
568 Ok(())
569 }
570 fn get_bool_ctl(&mut self, req: i32) -> Result<bool> {
571 Ok(self.get_int_ctl(req)? != 0)
572 }
573 fn get_int_ctl(&mut self, req: i32) -> Result<i32> {
574 let mut v: i32 = 0;
575 let r = unsafe { opus_encoder_ctl(self.raw.as_ptr(), req, &mut v) };
576 if r != 0 {
577 return Err(Error::from_code(r));
578 }
579 Ok(v)
580 }
581 fn get_bandwidth_ctl(&mut self, req: i32) -> Result<Bandwidth> {
582 let v = self.get_int_ctl(req)?;
583 let vu = u32::try_from(v).map_err(|_| Error::InternalError)?;
584 match vu {
585 x if x == crate::bindings::OPUS_BANDWIDTH_NARROWBAND => Ok(Bandwidth::Narrowband),
586 x if x == crate::bindings::OPUS_BANDWIDTH_MEDIUMBAND => Ok(Bandwidth::Mediumband),
587 x if x == crate::bindings::OPUS_BANDWIDTH_WIDEBAND => Ok(Bandwidth::Wideband),
588 x if x == crate::bindings::OPUS_BANDWIDTH_SUPERWIDEBAND => Ok(Bandwidth::SuperWideband),
589 x if x == OPUS_BANDWIDTH_FULLBAND => Ok(Bandwidth::Fullband),
590 _ => Err(Error::InternalError),
591 }
592 }
593
594 pub fn set_bitrate(&mut self, bitrate: Bitrate) -> Result<()> {
599 let result = unsafe {
600 opus_encoder_ctl(
601 self.raw.as_ptr(),
602 OPUS_SET_BITRATE_REQUEST as i32,
603 bitrate.value(),
604 )
605 };
606
607 if result != 0 {
608 return Err(Error::from_code(result));
609 }
610
611 Ok(())
612 }
613
614 pub fn bitrate(&mut self) -> Result<Bitrate> {
619 let mut bitrate = 0i32;
620 let result = unsafe {
621 opus_encoder_ctl(
622 self.raw.as_ptr(),
623 OPUS_GET_BITRATE_REQUEST as i32,
624 &mut bitrate,
625 )
626 };
627
628 if result != 0 {
629 return Err(Error::from_code(result));
630 }
631
632 match bitrate {
633 OPUS_AUTO => Ok(Bitrate::Auto),
634 OPUS_BITRATE_MAX => Ok(Bitrate::Max),
635 bps => Ok(Bitrate::Custom(bps)),
636 }
637 }
638
639 pub fn set_complexity(&mut self, complexity: Complexity) -> Result<()> {
644 let result = unsafe {
645 opus_encoder_ctl(
646 self.raw.as_ptr(),
647 OPUS_SET_COMPLEXITY_REQUEST as i32,
648 complexity.value() as i32,
649 )
650 };
651
652 if result != 0 {
653 return Err(Error::from_code(result));
654 }
655
656 Ok(())
657 }
658
659 pub fn complexity(&mut self) -> Result<Complexity> {
664 let mut complexity = 0i32;
665 let result = unsafe {
666 opus_encoder_ctl(
667 self.raw.as_ptr(),
668 OPUS_GET_COMPLEXITY_REQUEST as i32,
669 &mut complexity,
670 )
671 };
672
673 if result != 0 {
674 return Err(Error::from_code(result));
675 }
676
677 Ok(Complexity::new(
678 u32::try_from(complexity).map_err(|_| Error::InternalError)?,
679 ))
680 }
681
682 pub fn set_vbr(&mut self, enabled: bool) -> Result<()> {
687 let vbr = i32::from(enabled);
688 let result =
689 unsafe { opus_encoder_ctl(self.raw.as_ptr(), OPUS_SET_VBR_REQUEST as i32, vbr) };
690
691 if result != 0 {
692 return Err(Error::from_code(result));
693 }
694
695 Ok(())
696 }
697
698 pub fn vbr(&mut self) -> Result<bool> {
703 let mut vbr = 0i32;
704 let result =
705 unsafe { opus_encoder_ctl(self.raw.as_ptr(), OPUS_GET_VBR_REQUEST as i32, &mut vbr) };
706
707 if result != 0 {
708 return Err(Error::from_code(result));
709 }
710
711 Ok(vbr != 0)
712 }
713
714 #[must_use]
716 pub const fn sample_rate(&self) -> SampleRate {
717 self.sample_rate
718 }
719
720 #[must_use]
722 pub const fn channels(&self) -> Channels {
723 self.channels
724 }
725
726 pub fn reset(&mut self) -> Result<()> {
731 let r = unsafe {
732 opus_encoder_ctl(self.raw.as_ptr(), crate::bindings::OPUS_RESET_STATE as i32)
733 };
734 if r != 0 {
735 return Err(Error::from_code(r));
736 }
737 Ok(())
738 }
739}
740
741impl<'a> EncoderRef<'a> {
742 #[must_use]
752 pub unsafe fn from_raw(
753 ptr: *mut OpusEncoder,
754 sample_rate: SampleRate,
755 channels: Channels,
756 ) -> Self {
757 debug_assert!(!ptr.is_null(), "from_raw called with null ptr");
758 debug_assert!(crate::opus_ptr_is_aligned(ptr.cast()));
759 let encoder = Encoder::from_raw(
760 unsafe { NonNull::new_unchecked(ptr) },
761 sample_rate,
762 channels,
763 Ownership::Borrowed,
764 );
765 Self {
766 inner: encoder,
767 _marker: PhantomData,
768 }
769 }
770
771 pub fn init_in(
776 buf: &'a mut AlignedBuffer,
777 sample_rate: SampleRate,
778 channels: Channels,
779 application: Application,
780 ) -> Result<Self> {
781 let required = Encoder::size(channels)?;
782 if buf.capacity_bytes() < required {
783 return Err(Error::BadArg);
784 }
785 let ptr = buf.as_mut_ptr::<OpusEncoder>();
786 unsafe { Encoder::init_in_place(ptr, sample_rate, channels, application)? };
787 Ok(unsafe { Self::from_raw(ptr, sample_rate, channels) })
788 }
789}
790
791impl Deref for EncoderRef<'_> {
792 type Target = Encoder;
793
794 fn deref(&self) -> &Self::Target {
795 &self.inner
796 }
797}
798
799impl DerefMut for EncoderRef<'_> {
800 fn deref_mut(&mut self) -> &mut Self::Target {
801 &mut self.inner
802 }
803}