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};
19use crate::constants::max_frame_samples_for;
20use crate::error::{Error, Result};
21use crate::types::{
22 Application, Bandwidth, Bitrate, Channels, Complexity, ExpertFrameDuration, SampleRate, Signal,
23};
24
25pub struct Encoder {
27 raw: *mut OpusEncoder,
28 sample_rate: SampleRate,
29 channels: Channels,
30}
31
32unsafe impl Send for Encoder {}
33unsafe impl Sync for Encoder {}
34
35impl Encoder {
36 pub fn new(
41 sample_rate: SampleRate,
42 channels: Channels,
43 application: Application,
44 ) -> Result<Self> {
45 if !sample_rate.is_valid() {
47 return Err(Error::BadArg);
48 }
49
50 let mut error = 0i32;
51 let encoder = unsafe {
52 opus_encoder_create(
53 sample_rate.as_i32(),
54 channels.as_i32(),
55 application as i32,
56 std::ptr::addr_of_mut!(error),
57 )
58 };
59
60 if error != 0 {
61 return Err(Error::from_code(error));
62 }
63
64 if encoder.is_null() {
65 return Err(Error::AllocFail);
66 }
67
68 Ok(Self {
69 raw: encoder,
70 sample_rate,
71 channels,
72 })
73 }
74
75 pub fn encode(&mut self, input: &[i16], output: &mut [u8]) -> Result<usize> {
81 if self.raw.is_null() {
82 return Err(Error::InvalidState);
83 }
84
85 if input.is_empty() {
87 return Err(Error::BadArg);
88 }
89
90 if !input.len().is_multiple_of(self.channels.as_usize()) {
92 return Err(Error::BadArg);
93 }
94
95 let frame_size = input.len() / self.channels.as_usize();
96 if frame_size == 0 || frame_size > max_frame_samples_for(self.sample_rate) {
98 return Err(Error::BadArg);
99 }
100
101 if output.is_empty() {
103 return Err(Error::BadArg);
104 }
105 if output.len() > i32::MAX as usize {
106 return Err(Error::BadArg);
107 }
108
109 let frame_size_i32 = i32::try_from(frame_size).map_err(|_| Error::BadArg)?;
110 let out_len_i32 = i32::try_from(output.len()).map_err(|_| Error::BadArg)?;
111 let result = unsafe {
112 opus_encode(
113 self.raw,
114 input.as_ptr(),
115 frame_size_i32,
116 output.as_mut_ptr(),
117 out_len_i32,
118 )
119 };
120
121 if result < 0 {
122 return Err(Error::from_code(result));
123 }
124
125 usize::try_from(result).map_err(|_| Error::InternalError)
126 }
127
128 pub fn encode_limited(
137 &mut self,
138 input: &[i16],
139 output: &mut [u8],
140 max_data_bytes: usize,
141 ) -> Result<usize> {
142 if self.raw.is_null() {
143 return Err(Error::InvalidState);
144 }
145
146 if input.is_empty() {
148 return Err(Error::BadArg);
149 }
150
151 if !input.len().is_multiple_of(self.channels.as_usize()) {
153 return Err(Error::BadArg);
154 }
155
156 let frame_size = input.len() / self.channels.as_usize();
157 if frame_size == 0 || frame_size > max_frame_samples_for(self.sample_rate) {
159 return Err(Error::BadArg);
160 }
161
162 if output.is_empty() {
164 return Err(Error::BadArg);
165 }
166 if output.len() > i32::MAX as usize {
167 return Err(Error::BadArg);
168 }
169 if max_data_bytes == 0 || max_data_bytes > output.len() {
171 return Err(Error::BadArg);
172 }
173
174 let frame_size_i32 = i32::try_from(frame_size).map_err(|_| Error::BadArg)?;
175 let max_bytes_i32 = i32::try_from(max_data_bytes).map_err(|_| Error::BadArg)?;
176 let result = unsafe {
177 opus_encode(
178 self.raw,
179 input.as_ptr(),
180 frame_size_i32,
181 output.as_mut_ptr(),
182 max_bytes_i32,
183 )
184 };
185
186 if result < 0 {
187 return Err(Error::from_code(result));
188 }
189
190 usize::try_from(result).map_err(|_| Error::InternalError)
191 }
192
193 #[deprecated(
199 note = "Renamed to encode_limited; enabling FEC requires set_inband_fec + set_packet_loss_perc"
200 )]
201 pub fn encode_with_fec(
202 &mut self,
203 input: &[i16],
204 output: &mut [u8],
205 max_data_bytes: usize,
206 ) -> Result<usize> {
207 self.encode_limited(input, output, max_data_bytes)
208 }
209
210 pub fn encode_float(&mut self, input: &[f32], output: &mut [u8]) -> Result<usize> {
216 if self.raw.is_null() {
217 return Err(Error::InvalidState);
218 }
219 if input.is_empty() {
220 return Err(Error::BadArg);
221 }
222 if !input.len().is_multiple_of(self.channels.as_usize()) {
223 return Err(Error::BadArg);
224 }
225 let frame_size = input.len() / self.channels.as_usize();
226 if frame_size == 0 || frame_size > max_frame_samples_for(self.sample_rate) {
227 return Err(Error::BadArg);
228 }
229 if output.is_empty() || output.len() > i32::MAX as usize {
230 return Err(Error::BadArg);
231 }
232 let frame_i32 = i32::try_from(frame_size).map_err(|_| Error::BadArg)?;
233 let out_len_i32 = i32::try_from(output.len()).map_err(|_| Error::BadArg)?;
234 let n = unsafe {
235 opus_encode_float(
236 self.raw,
237 input.as_ptr(),
238 frame_i32,
239 output.as_mut_ptr(),
240 out_len_i32,
241 )
242 };
243 if n < 0 {
244 return Err(Error::from_code(n));
245 }
246 usize::try_from(n).map_err(|_| Error::InternalError)
247 }
248
249 pub fn set_inband_fec(&mut self, enabled: bool) -> Result<()> {
256 self.simple_ctl(OPUS_SET_INBAND_FEC_REQUEST as i32, i32::from(enabled))
257 }
258 pub fn inband_fec(&mut self) -> Result<bool> {
263 self.get_bool_ctl(OPUS_GET_INBAND_FEC_REQUEST as i32)
264 }
265
266 pub fn set_packet_loss_perc(&mut self, perc: i32) -> Result<()> {
272 if !(0..=100).contains(&perc) {
273 return Err(Error::BadArg);
274 }
275 self.simple_ctl(OPUS_SET_PACKET_LOSS_PERC_REQUEST as i32, perc)
276 }
277 pub fn packet_loss_perc(&mut self) -> Result<i32> {
282 self.get_int_ctl(OPUS_GET_PACKET_LOSS_PERC_REQUEST as i32)
283 }
284
285 pub fn set_dtx(&mut self, enabled: bool) -> Result<()> {
290 self.simple_ctl(OPUS_SET_DTX_REQUEST as i32, i32::from(enabled))
291 }
292 pub fn dtx(&mut self) -> Result<bool> {
297 self.get_bool_ctl(OPUS_GET_DTX_REQUEST as i32)
298 }
299 pub fn in_dtx(&mut self) -> Result<bool> {
304 self.get_bool_ctl(OPUS_GET_IN_DTX_REQUEST as i32)
305 }
306
307 pub fn set_vbr_constraint(&mut self, constrained: bool) -> Result<()> {
312 self.simple_ctl(
313 OPUS_SET_VBR_CONSTRAINT_REQUEST as i32,
314 i32::from(constrained),
315 )
316 }
317 pub fn vbr_constraint(&mut self) -> Result<bool> {
322 self.get_bool_ctl(OPUS_GET_VBR_CONSTRAINT_REQUEST as i32)
323 }
324
325 pub fn set_max_bandwidth(&mut self, bw: Bandwidth) -> Result<()> {
330 self.simple_ctl(OPUS_SET_MAX_BANDWIDTH_REQUEST as i32, bw as i32)
331 }
332 pub fn max_bandwidth(&mut self) -> Result<Bandwidth> {
337 self.get_bandwidth_ctl(OPUS_GET_MAX_BANDWIDTH_REQUEST as i32)
338 }
339
340 pub fn set_bandwidth(&mut self, bw: Bandwidth) -> Result<()> {
345 self.simple_ctl(OPUS_SET_BANDWIDTH_REQUEST as i32, bw as i32)
346 }
347 pub fn bandwidth(&mut self) -> Result<Bandwidth> {
352 self.get_bandwidth_ctl(OPUS_GET_BANDWIDTH_REQUEST as i32)
353 }
354
355 pub fn set_force_channels(&mut self, channels: Option<Channels>) -> Result<()> {
360 let val = match channels {
361 Some(Channels::Mono) => 1,
362 Some(Channels::Stereo) => 2,
363 None => crate::bindings::OPUS_AUTO,
364 };
365 self.simple_ctl(OPUS_SET_FORCE_CHANNELS_REQUEST as i32, val)
366 }
367 pub fn force_channels(&mut self) -> Result<Option<Channels>> {
372 let v = self.get_int_ctl(OPUS_GET_FORCE_CHANNELS_REQUEST as i32)?;
373 Ok(match v {
374 1 => Some(Channels::Mono),
375 2 => Some(Channels::Stereo),
376 _ => None,
377 })
378 }
379
380 pub fn set_signal(&mut self, signal: Signal) -> Result<()> {
385 self.simple_ctl(OPUS_SET_SIGNAL_REQUEST as i32, signal as i32)
386 }
387 pub fn signal(&mut self) -> Result<Signal> {
392 let v = self.get_int_ctl(OPUS_GET_SIGNAL_REQUEST as i32)?;
393 match v {
394 x if x == crate::bindings::OPUS_SIGNAL_VOICE as i32 => Ok(Signal::Voice),
395 x if x == crate::bindings::OPUS_SIGNAL_MUSIC as i32 => Ok(Signal::Music),
396 _ => Err(Error::InternalError),
397 }
398 }
399
400 pub fn lookahead(&mut self) -> Result<i32> {
405 self.get_int_ctl(OPUS_GET_LOOKAHEAD_REQUEST as i32)
406 }
407 pub fn final_range(&mut self) -> Result<u32> {
412 let mut val: u32 = 0;
413 let r =
414 unsafe { opus_encoder_ctl(self.raw, OPUS_GET_FINAL_RANGE_REQUEST as i32, &mut val) };
415 if r != 0 {
416 return Err(Error::from_code(r));
417 }
418 Ok(val)
419 }
420
421 pub fn set_lsb_depth(&mut self, bits: i32) -> Result<()> {
427 if !(8..=24).contains(&bits) {
428 return Err(Error::BadArg);
429 }
430 self.simple_ctl(OPUS_SET_LSB_DEPTH_REQUEST as i32, bits)
431 }
432 pub fn lsb_depth(&mut self) -> Result<i32> {
437 self.get_int_ctl(OPUS_GET_LSB_DEPTH_REQUEST as i32)
438 }
439
440 pub fn set_expert_frame_duration(&mut self, dur: ExpertFrameDuration) -> Result<()> {
445 self.simple_ctl(OPUS_SET_EXPERT_FRAME_DURATION_REQUEST as i32, dur as i32)
446 }
447 pub fn expert_frame_duration(&mut self) -> Result<ExpertFrameDuration> {
452 let v = self.get_int_ctl(OPUS_GET_EXPERT_FRAME_DURATION_REQUEST as i32)?;
453 let vu = u32::try_from(v).map_err(|_| Error::InternalError)?;
454 Ok(match vu {
455 x if x == crate::bindings::OPUS_FRAMESIZE_2_5_MS => ExpertFrameDuration::Ms2_5,
456 x if x == crate::bindings::OPUS_FRAMESIZE_5_MS => ExpertFrameDuration::Ms5,
457 x if x == crate::bindings::OPUS_FRAMESIZE_10_MS => ExpertFrameDuration::Ms10,
458 x if x == crate::bindings::OPUS_FRAMESIZE_20_MS => ExpertFrameDuration::Ms20,
459 x if x == crate::bindings::OPUS_FRAMESIZE_40_MS => ExpertFrameDuration::Ms40,
460 x if x == crate::bindings::OPUS_FRAMESIZE_60_MS => ExpertFrameDuration::Ms60,
461 x if x == crate::bindings::OPUS_FRAMESIZE_80_MS => ExpertFrameDuration::Ms80,
462 x if x == crate::bindings::OPUS_FRAMESIZE_100_MS => ExpertFrameDuration::Ms100,
463 _ => ExpertFrameDuration::Ms120,
464 })
465 }
466
467 pub fn set_prediction_disabled(&mut self, disabled: bool) -> Result<()> {
472 self.simple_ctl(
473 OPUS_SET_PREDICTION_DISABLED_REQUEST as i32,
474 i32::from(disabled),
475 )
476 }
477 pub fn prediction_disabled(&mut self) -> Result<bool> {
482 self.get_bool_ctl(OPUS_GET_PREDICTION_DISABLED_REQUEST as i32)
483 }
484
485 pub fn set_phase_inversion_disabled(&mut self, disabled: bool) -> Result<()> {
490 self.simple_ctl(
491 OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST as i32,
492 i32::from(disabled),
493 )
494 }
495 pub fn phase_inversion_disabled(&mut self) -> Result<bool> {
500 self.get_bool_ctl(OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST as i32)
501 }
502
503 fn simple_ctl(&mut self, req: i32, val: i32) -> Result<()> {
505 if self.raw.is_null() {
506 return Err(Error::InvalidState);
507 }
508 let r = unsafe { opus_encoder_ctl(self.raw, req, val) };
509 if r != 0 {
510 return Err(Error::from_code(r));
511 }
512 Ok(())
513 }
514 fn get_bool_ctl(&mut self, req: i32) -> Result<bool> {
515 Ok(self.get_int_ctl(req)? != 0)
516 }
517 fn get_int_ctl(&mut self, req: i32) -> Result<i32> {
518 if self.raw.is_null() {
519 return Err(Error::InvalidState);
520 }
521 let mut v: i32 = 0;
522 let r = unsafe { opus_encoder_ctl(self.raw, req, &mut v) };
523 if r != 0 {
524 return Err(Error::from_code(r));
525 }
526 Ok(v)
527 }
528 fn get_bandwidth_ctl(&mut self, req: i32) -> Result<Bandwidth> {
529 let v = self.get_int_ctl(req)?;
530 let vu = u32::try_from(v).map_err(|_| Error::InternalError)?;
531 match vu {
532 x if x == crate::bindings::OPUS_BANDWIDTH_NARROWBAND => Ok(Bandwidth::Narrowband),
533 x if x == crate::bindings::OPUS_BANDWIDTH_MEDIUMBAND => Ok(Bandwidth::Mediumband),
534 x if x == crate::bindings::OPUS_BANDWIDTH_WIDEBAND => Ok(Bandwidth::Wideband),
535 x if x == crate::bindings::OPUS_BANDWIDTH_SUPERWIDEBAND => Ok(Bandwidth::SuperWideband),
536 x if x == OPUS_BANDWIDTH_FULLBAND => Ok(Bandwidth::Fullband),
537 _ => Err(Error::InternalError),
538 }
539 }
540
541 pub fn set_bitrate(&mut self, bitrate: Bitrate) -> Result<()> {
546 if self.raw.is_null() {
547 return Err(Error::InvalidState);
548 }
549
550 let result =
551 unsafe { opus_encoder_ctl(self.raw, OPUS_SET_BITRATE_REQUEST as i32, bitrate.value()) };
552
553 if result != 0 {
554 return Err(Error::from_code(result));
555 }
556
557 Ok(())
558 }
559
560 pub fn bitrate(&mut self) -> Result<Bitrate> {
565 if self.raw.is_null() {
566 return Err(Error::InvalidState);
567 }
568
569 let mut bitrate = 0i32;
570 let result =
571 unsafe { opus_encoder_ctl(self.raw, OPUS_GET_BITRATE_REQUEST as i32, &mut bitrate) };
572
573 if result != 0 {
574 return Err(Error::from_code(result));
575 }
576
577 match bitrate {
578 OPUS_AUTO => Ok(Bitrate::Auto),
579 OPUS_BITRATE_MAX => Ok(Bitrate::Max),
580 bps => Ok(Bitrate::Custom(bps)),
581 }
582 }
583
584 pub fn set_complexity(&mut self, complexity: Complexity) -> Result<()> {
589 if self.raw.is_null() {
590 return Err(Error::InvalidState);
591 }
592
593 let result = unsafe {
594 opus_encoder_ctl(
595 self.raw,
596 OPUS_SET_COMPLEXITY_REQUEST as i32,
597 complexity.value() as i32,
598 )
599 };
600
601 if result != 0 {
602 return Err(Error::from_code(result));
603 }
604
605 Ok(())
606 }
607
608 pub fn complexity(&mut self) -> Result<Complexity> {
613 if self.raw.is_null() {
614 return Err(Error::InvalidState);
615 }
616
617 let mut complexity = 0i32;
618 let result = unsafe {
619 opus_encoder_ctl(
620 self.raw,
621 OPUS_GET_COMPLEXITY_REQUEST as i32,
622 &mut complexity,
623 )
624 };
625
626 if result != 0 {
627 return Err(Error::from_code(result));
628 }
629
630 Ok(Complexity::new(
631 u32::try_from(complexity).map_err(|_| Error::InternalError)?,
632 ))
633 }
634
635 pub fn set_vbr(&mut self, enabled: bool) -> Result<()> {
640 if self.raw.is_null() {
641 return Err(Error::InvalidState);
642 }
643
644 let vbr = i32::from(enabled);
645 let result = unsafe { opus_encoder_ctl(self.raw, OPUS_SET_VBR_REQUEST as i32, vbr) };
646
647 if result != 0 {
648 return Err(Error::from_code(result));
649 }
650
651 Ok(())
652 }
653
654 pub fn vbr(&mut self) -> Result<bool> {
659 if self.raw.is_null() {
660 return Err(Error::InvalidState);
661 }
662
663 let mut vbr = 0i32;
664 let result = unsafe { opus_encoder_ctl(self.raw, OPUS_GET_VBR_REQUEST as i32, &mut vbr) };
665
666 if result != 0 {
667 return Err(Error::from_code(result));
668 }
669
670 Ok(vbr != 0)
671 }
672
673 #[must_use]
675 pub const fn sample_rate(&self) -> SampleRate {
676 self.sample_rate
677 }
678
679 #[must_use]
681 pub const fn channels(&self) -> Channels {
682 self.channels
683 }
684
685 pub fn reset(&mut self) -> Result<()> {
690 if self.raw.is_null() {
691 return Err(Error::InvalidState);
692 }
693 let r = unsafe { opus_encoder_ctl(self.raw, crate::bindings::OPUS_RESET_STATE as i32) };
694 if r != 0 {
695 return Err(Error::from_code(r));
696 }
697 Ok(())
698 }
699}
700
701impl Drop for Encoder {
702 fn drop(&mut self) {
703 unsafe {
704 opus_encoder_destroy(self.raw);
705 }
706 }
707}