1use crate::bindings::{
4 OPUS_AUTO, OPUS_BANDWIDTH_FULLBAND, OPUS_BANDWIDTH_MEDIUMBAND, OPUS_BANDWIDTH_NARROWBAND,
5 OPUS_BANDWIDTH_SUPERWIDEBAND, OPUS_BANDWIDTH_WIDEBAND, OPUS_BITRATE_MAX,
6 OPUS_GET_BANDWIDTH_REQUEST, OPUS_GET_BITRATE_REQUEST, OPUS_GET_COMPLEXITY_REQUEST,
7 OPUS_GET_DTX_REQUEST, OPUS_GET_FINAL_RANGE_REQUEST, OPUS_GET_FORCE_CHANNELS_REQUEST,
8 OPUS_GET_GAIN_REQUEST, OPUS_GET_IN_DTX_REQUEST, OPUS_GET_INBAND_FEC_REQUEST,
9 OPUS_GET_LAST_PACKET_DURATION_REQUEST, OPUS_GET_LOOKAHEAD_REQUEST,
10 OPUS_GET_MAX_BANDWIDTH_REQUEST, OPUS_GET_PACKET_LOSS_PERC_REQUEST,
11 OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_GET_PITCH_REQUEST,
12 OPUS_GET_SAMPLE_RATE_REQUEST, OPUS_GET_SIGNAL_REQUEST, OPUS_GET_VBR_CONSTRAINT_REQUEST,
13 OPUS_GET_VBR_REQUEST, OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST,
14 OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST, OPUS_RESET_STATE, OPUS_SET_BANDWIDTH_REQUEST,
15 OPUS_SET_BITRATE_REQUEST, OPUS_SET_COMPLEXITY_REQUEST, OPUS_SET_DTX_REQUEST,
16 OPUS_SET_FORCE_CHANNELS_REQUEST, OPUS_SET_GAIN_REQUEST, OPUS_SET_INBAND_FEC_REQUEST,
17 OPUS_SET_MAX_BANDWIDTH_REQUEST, OPUS_SET_PACKET_LOSS_PERC_REQUEST,
18 OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST, OPUS_SET_SIGNAL_REQUEST,
19 OPUS_SET_VBR_CONSTRAINT_REQUEST, OPUS_SET_VBR_REQUEST, OPUS_SIGNAL_MUSIC, OPUS_SIGNAL_VOICE,
20 OpusDecoder, OpusEncoder, OpusMSDecoder, OpusMSEncoder, opus_multistream_decode,
21 opus_multistream_decode_float, opus_multistream_decoder_create, opus_multistream_decoder_ctl,
22 opus_multistream_decoder_destroy, opus_multistream_decoder_get_size,
23 opus_multistream_decoder_init, opus_multistream_encode, opus_multistream_encode_float,
24 opus_multistream_encoder_create, opus_multistream_encoder_ctl,
25 opus_multistream_encoder_destroy, opus_multistream_encoder_get_size,
26 opus_multistream_encoder_init, opus_multistream_surround_encoder_create,
27 opus_multistream_surround_encoder_get_size, opus_multistream_surround_encoder_init,
28};
29use crate::constants::max_frame_samples_for;
30use crate::error::{Error, Result};
31use crate::types::{Application, Bandwidth, Bitrate, Channels, Complexity, SampleRate, Signal};
32use crate::{AlignedBuffer, Ownership, RawHandle};
33use std::marker::PhantomData;
34use std::num::{NonZeroU8, NonZeroUsize};
35use std::ops::{Deref, DerefMut};
36use std::ptr::NonNull;
37
38#[derive(Debug, Clone, Copy)]
40pub struct Mapping<'a> {
41 pub channels: u8,
43 pub streams: u8,
45 pub coupled_streams: u8,
47 pub mapping: &'a [u8],
49}
50
51impl Mapping<'_> {
52 fn validate_common(&self) -> Result<(usize, usize, usize)> {
53 let channel_count = NonZeroU8::new(self.channels).ok_or(Error::BadArg)?;
54 let channel_count = usize::from(channel_count.get());
55 if self.mapping.len() != channel_count {
56 return Err(Error::BadArg);
57 }
58
59 let streams = NonZeroU8::new(self.streams).ok_or(Error::BadArg)?;
60 let streams = usize::from(streams.get());
61 let coupled = usize::from(self.coupled_streams);
62 if coupled > streams {
63 return Err(Error::BadArg);
64 }
65 if streams + coupled > u8::MAX as usize {
66 return Err(Error::BadArg);
67 }
68 let total_streams = streams + coupled;
69 for &entry in self.mapping {
70 if entry == u8::MAX {
71 continue;
72 }
73 if usize::from(entry) >= total_streams {
74 return Err(Error::BadArg);
75 }
76 }
77 Ok((channel_count, streams, coupled))
78 }
79
80 fn validate_for_decoder(&self) -> Result<()> {
82 self.validate_common()?;
83 Ok(())
84 }
85
86 fn validate_for_encoder(&self) -> Result<()> {
88 let (channel_count, streams, coupled) = self.validate_common()?;
89 if streams + coupled > channel_count {
90 return Err(Error::BadArg);
91 }
92
93 let mut has_left = vec![false; coupled];
94 let mut has_right = vec![false; coupled];
95 let mut has_mono = vec![false; streams.saturating_sub(coupled)];
96 for &entry in self.mapping {
97 if entry == u8::MAX {
98 continue;
99 }
100 let idx = usize::from(entry);
101 if idx < 2 * coupled {
102 let stream = idx / 2;
103 if idx % 2 == 0 {
104 has_left[stream] = true;
105 } else {
106 has_right[stream] = true;
107 }
108 } else {
109 let stream = idx - coupled;
110 if stream >= coupled && stream < streams {
111 has_mono[stream - coupled] = true;
112 }
113 }
114 }
115
116 if has_left.iter().any(|has| !has) || has_right.iter().any(|has| !has) {
117 return Err(Error::BadArg);
118 }
119 if has_mono.iter().any(|has| !has) {
120 return Err(Error::BadArg);
121 }
122 Ok(())
123 }
124}
125
126pub struct MultistreamEncoder {
128 raw: RawHandle<OpusMSEncoder>,
129 sample_rate: SampleRate,
130 channels: u8,
131 streams: u8,
132 coupled_streams: u8,
133}
134
135unsafe impl Send for MultistreamEncoder {}
136unsafe impl Sync for MultistreamEncoder {}
137
138pub struct MultistreamEncoderRef<'a> {
140 inner: MultistreamEncoder,
141 _marker: PhantomData<&'a mut OpusMSEncoder>,
142}
143
144unsafe impl Send for MultistreamEncoderRef<'_> {}
145unsafe impl Sync for MultistreamEncoderRef<'_> {}
146
147impl MultistreamEncoder {
148 fn from_raw(
149 ptr: NonNull<OpusMSEncoder>,
150 sample_rate: SampleRate,
151 channels: u8,
152 streams: u8,
153 coupled_streams: u8,
154 ownership: Ownership,
155 ) -> Self {
156 Self {
157 raw: RawHandle::new(ptr, ownership, opus_multistream_encoder_destroy),
158 sample_rate,
159 channels,
160 streams,
161 coupled_streams,
162 }
163 }
164
165 pub fn size(streams: u8, coupled_streams: u8) -> Result<usize> {
171 let raw = unsafe {
172 opus_multistream_encoder_get_size(i32::from(streams), i32::from(coupled_streams))
173 };
174 if raw <= 0 {
175 return Err(Error::BadArg);
176 }
177 usize::try_from(raw).map_err(|_| Error::InternalError)
178 }
179
180 pub fn surround_size(channels: u8, mapping_family: i32) -> Result<usize> {
185 let raw = unsafe {
186 opus_multistream_surround_encoder_get_size(i32::from(channels), mapping_family)
187 };
188 if raw <= 0 {
189 return Err(Error::BadArg);
190 }
191 usize::try_from(raw).map_err(|_| Error::InternalError)
192 }
193
194 pub unsafe fn init_in_place(
204 ptr: *mut OpusMSEncoder,
205 sr: SampleRate,
206 app: Application,
207 mapping: Mapping<'_>,
208 ) -> Result<()> {
209 if ptr.is_null() {
210 return Err(Error::BadArg);
211 }
212 if !crate::opus_ptr_is_aligned(ptr.cast()) {
213 return Err(Error::BadArg);
214 }
215 mapping.validate_for_encoder()?;
216 let r = unsafe {
217 opus_multistream_encoder_init(
218 ptr,
219 sr as i32,
220 i32::from(mapping.channels),
221 i32::from(mapping.streams),
222 i32::from(mapping.coupled_streams),
223 mapping.mapping.as_ptr(),
224 app as i32,
225 )
226 };
227 if r != 0 {
228 return Err(Error::from_code(r));
229 }
230 Ok(())
231 }
232
233 pub unsafe fn init_surround_in_place(
242 ptr: *mut OpusMSEncoder,
243 sr: SampleRate,
244 channels: u8,
245 mapping_family: i32,
246 app: Application,
247 ) -> Result<(u8, u8, Vec<u8>)> {
248 if ptr.is_null() || channels == 0 {
249 return Err(Error::BadArg);
250 }
251 if !crate::opus_ptr_is_aligned(ptr.cast()) {
252 return Err(Error::BadArg);
253 }
254 let mut streams = 0i32;
255 let mut coupled = 0i32;
256 let mut mapping = vec![0u8; channels as usize];
257 let r = unsafe {
258 opus_multistream_surround_encoder_init(
259 ptr,
260 sr as i32,
261 i32::from(channels),
262 mapping_family,
263 std::ptr::addr_of_mut!(streams),
264 std::ptr::addr_of_mut!(coupled),
265 mapping.as_mut_ptr(),
266 app as i32,
267 )
268 };
269 if r != 0 {
270 return Err(Error::from_code(r));
271 }
272 Ok((
273 u8::try_from(streams).map_err(|_| Error::BadArg)?,
274 u8::try_from(coupled).map_err(|_| Error::BadArg)?,
275 mapping,
276 ))
277 }
278
279 pub fn new(sr: SampleRate, app: Application, mapping: Mapping<'_>) -> Result<Self> {
288 mapping.validate_for_encoder()?;
289 let mut err = 0i32;
290 let enc = unsafe {
291 opus_multistream_encoder_create(
292 sr as i32,
293 i32::from(mapping.channels),
294 i32::from(mapping.streams),
295 i32::from(mapping.coupled_streams),
296 mapping.mapping.as_ptr(),
297 app as i32,
298 std::ptr::addr_of_mut!(err),
299 )
300 };
301 if err != 0 {
302 return Err(Error::from_code(err));
303 }
304 let enc = NonNull::new(enc).ok_or(Error::AllocFail)?;
305 Ok(Self::from_raw(
306 enc,
307 sr,
308 mapping.channels,
309 mapping.streams,
310 mapping.coupled_streams,
311 Ownership::Owned,
312 ))
313 }
314
315 #[allow(clippy::missing_panics_doc)]
321 pub fn encode(
322 &mut self,
323 pcm: &[i16],
324 frame_size_per_ch: usize,
325 out: &mut [u8],
326 ) -> Result<usize> {
327 let frame_size_per_ch = NonZeroUsize::new(frame_size_per_ch).ok_or(Error::BadArg)?;
328 if frame_size_per_ch.get() > max_frame_samples_for(self.sample_rate) {
329 return Err(Error::BadArg);
330 }
331 if pcm.len() != frame_size_per_ch.get() * self.channels as usize {
332 return Err(Error::BadArg);
333 }
334 if out.is_empty() || out.len() > i32::MAX as usize {
335 return Err(Error::BadArg);
336 }
337 let n = unsafe {
338 opus_multistream_encode(
339 self.raw.as_ptr(),
340 pcm.as_ptr(),
341 i32::try_from(frame_size_per_ch.get()).map_err(|_| Error::BadArg)?,
342 out.as_mut_ptr(),
343 i32::try_from(out.len()).map_err(|_| Error::BadArg)?,
344 )
345 };
346 if n < 0 {
347 return Err(Error::from_code(n));
348 }
349 usize::try_from(n).map_err(|_| Error::InternalError)
350 }
351
352 pub fn encode_float(
358 &mut self,
359 pcm: &[f32],
360 frame_size_per_ch: usize,
361 out: &mut [u8],
362 ) -> Result<usize> {
363 let frame_size_per_ch = NonZeroUsize::new(frame_size_per_ch).ok_or(Error::BadArg)?;
364 if frame_size_per_ch.get() > max_frame_samples_for(self.sample_rate) {
365 return Err(Error::BadArg);
366 }
367 if pcm.len() != frame_size_per_ch.get() * self.channels as usize {
368 return Err(Error::BadArg);
369 }
370 if out.is_empty() || out.len() > i32::MAX as usize {
371 return Err(Error::BadArg);
372 }
373 let n = unsafe {
374 opus_multistream_encode_float(
375 self.raw.as_ptr(),
376 pcm.as_ptr(),
377 i32::try_from(frame_size_per_ch.get()).map_err(|_| Error::BadArg)?,
378 out.as_mut_ptr(),
379 i32::try_from(out.len()).map_err(|_| Error::BadArg)?,
380 )
381 };
382 if n < 0 {
383 return Err(Error::from_code(n));
384 }
385 usize::try_from(n).map_err(|_| Error::InternalError)
386 }
387
388 pub fn final_range(&mut self) -> Result<u32> {
394 let mut v: u32 = 0;
395 let r = unsafe {
396 opus_multistream_encoder_ctl(
397 self.raw.as_ptr(),
398 OPUS_GET_FINAL_RANGE_REQUEST as i32,
399 &mut v,
400 )
401 };
402 if r != 0 {
403 return Err(Error::from_code(r));
404 }
405 Ok(v)
406 }
407
408 pub fn set_bitrate(&mut self, bitrate: Bitrate) -> Result<()> {
414 self.simple_ctl(OPUS_SET_BITRATE_REQUEST as i32, bitrate.value())
415 }
416
417 pub fn bitrate(&mut self) -> Result<Bitrate> {
424 let v = self.get_int_ctl(OPUS_GET_BITRATE_REQUEST as i32)?;
425 Ok(match v {
426 x if x == OPUS_AUTO => Bitrate::Auto,
427 x if x == OPUS_BITRATE_MAX => Bitrate::Max,
428 other => Bitrate::Custom(other),
429 })
430 }
431
432 pub fn set_complexity(&mut self, complexity: Complexity) -> Result<()> {
438 self.simple_ctl(
439 OPUS_SET_COMPLEXITY_REQUEST as i32,
440 complexity.value() as i32,
441 )
442 }
443
444 pub fn complexity(&mut self) -> Result<Complexity> {
450 let v = self.get_int_ctl(OPUS_GET_COMPLEXITY_REQUEST as i32)?;
451 Ok(Complexity::new(
452 u32::try_from(v).map_err(|_| Error::InternalError)?,
453 ))
454 }
455
456 pub fn set_dtx(&mut self, enabled: bool) -> Result<()> {
462 self.simple_ctl(OPUS_SET_DTX_REQUEST as i32, i32::from(enabled))
463 }
464
465 pub fn dtx(&mut self) -> Result<bool> {
471 self.get_bool_ctl(OPUS_GET_DTX_REQUEST as i32)
472 }
473
474 pub fn in_dtx(&mut self) -> Result<bool> {
480 self.get_bool_ctl(OPUS_GET_IN_DTX_REQUEST as i32)
481 }
482
483 pub fn set_inband_fec(&mut self, enabled: bool) -> Result<()> {
489 self.simple_ctl(OPUS_SET_INBAND_FEC_REQUEST as i32, i32::from(enabled))
490 }
491
492 pub fn inband_fec(&mut self) -> Result<bool> {
498 self.get_bool_ctl(OPUS_GET_INBAND_FEC_REQUEST as i32)
499 }
500
501 pub fn set_packet_loss_perc(&mut self, perc: i32) -> Result<()> {
507 if !(0..=100).contains(&perc) {
508 return Err(Error::BadArg);
509 }
510 self.simple_ctl(OPUS_SET_PACKET_LOSS_PERC_REQUEST as i32, perc)
511 }
512
513 pub fn packet_loss_perc(&mut self) -> Result<i32> {
519 self.get_int_ctl(OPUS_GET_PACKET_LOSS_PERC_REQUEST as i32)
520 }
521
522 pub fn set_vbr(&mut self, enabled: bool) -> Result<()> {
528 self.simple_ctl(OPUS_SET_VBR_REQUEST as i32, i32::from(enabled))
529 }
530
531 pub fn vbr(&mut self) -> Result<bool> {
537 self.get_bool_ctl(OPUS_GET_VBR_REQUEST as i32)
538 }
539
540 pub fn set_vbr_constraint(&mut self, constrained: bool) -> Result<()> {
546 self.simple_ctl(
547 OPUS_SET_VBR_CONSTRAINT_REQUEST as i32,
548 i32::from(constrained),
549 )
550 }
551
552 pub fn vbr_constraint(&mut self) -> Result<bool> {
558 self.get_bool_ctl(OPUS_GET_VBR_CONSTRAINT_REQUEST as i32)
559 }
560
561 pub fn set_max_bandwidth(&mut self, bw: Bandwidth) -> Result<()> {
567 self.simple_ctl(OPUS_SET_MAX_BANDWIDTH_REQUEST as i32, bw as i32)
568 }
569
570 pub fn max_bandwidth(&mut self) -> Result<Bandwidth> {
576 self.get_bandwidth_ctl(OPUS_GET_MAX_BANDWIDTH_REQUEST as i32)
577 }
578
579 pub fn set_bandwidth(&mut self, bw: Bandwidth) -> Result<()> {
585 self.simple_ctl(OPUS_SET_BANDWIDTH_REQUEST as i32, bw as i32)
586 }
587
588 pub fn bandwidth(&mut self) -> Result<Bandwidth> {
594 self.get_bandwidth_ctl(OPUS_GET_BANDWIDTH_REQUEST as i32)
595 }
596
597 pub fn set_force_channels(&mut self, channels: Option<Channels>) -> Result<()> {
603 let value = match channels {
604 Some(Channels::Mono) => 1,
605 Some(Channels::Stereo) => 2,
606 None => OPUS_AUTO,
607 };
608 self.simple_ctl(OPUS_SET_FORCE_CHANNELS_REQUEST as i32, value)
609 }
610
611 pub fn force_channels(&mut self) -> Result<Option<Channels>> {
617 let v = self.get_int_ctl(OPUS_GET_FORCE_CHANNELS_REQUEST as i32)?;
618 Ok(match v {
619 1 => Some(Channels::Mono),
620 2 => Some(Channels::Stereo),
621 x if x == OPUS_AUTO => None,
622 _ => None,
623 })
624 }
625
626 pub fn set_signal(&mut self, signal: Signal) -> Result<()> {
632 self.simple_ctl(OPUS_SET_SIGNAL_REQUEST as i32, signal as i32)
633 }
634
635 pub fn signal(&mut self) -> Result<Signal> {
641 let v = self.get_int_ctl(OPUS_GET_SIGNAL_REQUEST as i32)?;
642 match v {
643 x if x == OPUS_AUTO => Ok(Signal::Auto),
644 x if x == OPUS_SIGNAL_VOICE as i32 => Ok(Signal::Voice),
645 x if x == OPUS_SIGNAL_MUSIC as i32 => Ok(Signal::Music),
646 _ => Err(Error::InternalError),
647 }
648 }
649
650 pub fn lookahead(&mut self) -> Result<i32> {
656 self.get_int_ctl(OPUS_GET_LOOKAHEAD_REQUEST as i32)
657 }
658
659 pub fn reset(&mut self) -> Result<()> {
665 let r = unsafe { opus_multistream_encoder_ctl(self.raw.as_ptr(), OPUS_RESET_STATE as i32) };
666 if r != 0 {
667 return Err(Error::from_code(r));
668 }
669 Ok(())
670 }
671
672 #[must_use]
674 pub const fn channels(&self) -> u8 {
675 self.channels
676 }
677 #[must_use]
679 pub const fn sample_rate(&self) -> SampleRate {
680 self.sample_rate
681 }
682 #[must_use]
684 pub const fn streams(&self) -> u8 {
685 self.streams
686 }
687 #[must_use]
689 pub const fn coupled_streams(&self) -> u8 {
690 self.coupled_streams
691 }
692
693 pub fn new_surround(
699 sr: SampleRate,
700 channels: u8,
701 mapping_family: i32,
702 app: Application,
703 ) -> Result<(Self, Vec<u8>)> {
704 if channels == 0 {
705 return Err(Error::BadArg);
706 }
707 let mut err = 0i32;
708 let mut streams = 0i32;
709 let mut coupled = 0i32;
710 let mut mapping = vec![0u8; channels as usize];
711 let enc = unsafe {
712 opus_multistream_surround_encoder_create(
713 sr as i32,
714 i32::from(channels),
715 mapping_family,
716 std::ptr::addr_of_mut!(streams),
717 std::ptr::addr_of_mut!(coupled),
718 mapping.as_mut_ptr(),
719 app as i32,
720 std::ptr::addr_of_mut!(err),
721 )
722 };
723 if err != 0 {
724 return Err(Error::from_code(err));
725 }
726 let enc = NonNull::new(enc).ok_or(Error::AllocFail)?;
727 let streams_u8 = u8::try_from(streams).map_err(|_| Error::BadArg)?;
728 let coupled_u8 = u8::try_from(coupled).map_err(|_| Error::BadArg)?;
729 Ok((
730 Self::from_raw(enc, sr, channels, streams_u8, coupled_u8, Ownership::Owned),
731 mapping,
732 ))
733 }
734
735 pub unsafe fn encoder_state_ptr(&mut self, stream_index: i32) -> Result<*mut OpusEncoder> {
745 let mut state: *mut OpusEncoder = std::ptr::null_mut();
746 let r = unsafe {
747 opus_multistream_encoder_ctl(
748 self.raw.as_ptr(),
749 OPUS_MULTISTREAM_GET_ENCODER_STATE_REQUEST as i32,
750 stream_index,
751 &mut state,
752 )
753 };
754 if r != 0 {
755 return Err(Error::from_code(r));
756 }
757 if state.is_null() {
758 return Err(Error::InternalError);
759 }
760 Ok(state)
761 }
762
763 fn simple_ctl(&mut self, req: i32, val: i32) -> Result<()> {
764 let r = unsafe { opus_multistream_encoder_ctl(self.raw.as_ptr(), req, val) };
765 if r != 0 {
766 return Err(Error::from_code(r));
767 }
768 Ok(())
769 }
770
771 fn get_int_ctl(&mut self, req: i32) -> Result<i32> {
772 let mut v: i32 = 0;
773 let r = unsafe { opus_multistream_encoder_ctl(self.raw.as_ptr(), req, &mut v) };
774 if r != 0 {
775 return Err(Error::from_code(r));
776 }
777 Ok(v)
778 }
779
780 fn get_bool_ctl(&mut self, req: i32) -> Result<bool> {
781 Ok(self.get_int_ctl(req)? != 0)
782 }
783
784 fn get_bandwidth_ctl(&mut self, req: i32) -> Result<Bandwidth> {
785 let v = u32::try_from(self.get_int_ctl(req)?).map_err(|_| Error::InternalError)?;
786 match v {
787 x if x == OPUS_BANDWIDTH_NARROWBAND => Ok(Bandwidth::Narrowband),
788 x if x == OPUS_BANDWIDTH_MEDIUMBAND => Ok(Bandwidth::Mediumband),
789 x if x == OPUS_BANDWIDTH_WIDEBAND => Ok(Bandwidth::Wideband),
790 x if x == OPUS_BANDWIDTH_SUPERWIDEBAND => Ok(Bandwidth::SuperWideband),
791 x if x == OPUS_BANDWIDTH_FULLBAND => Ok(Bandwidth::Fullband),
792 _ => Err(Error::InternalError),
793 }
794 }
795}
796
797impl<'a> MultistreamEncoderRef<'a> {
798 #[must_use]
808 pub unsafe fn from_raw(ptr: *mut OpusMSEncoder, sr: SampleRate, mapping: Mapping<'_>) -> Self {
809 debug_assert!(!ptr.is_null(), "from_raw called with null ptr");
810 debug_assert!(crate::opus_ptr_is_aligned(ptr.cast()));
811 debug_assert!(mapping.validate_for_encoder().is_ok());
812 let encoder = MultistreamEncoder::from_raw(
813 unsafe { NonNull::new_unchecked(ptr) },
814 sr,
815 mapping.channels,
816 mapping.streams,
817 mapping.coupled_streams,
818 Ownership::Borrowed,
819 );
820 Self {
821 inner: encoder,
822 _marker: PhantomData,
823 }
824 }
825
826 pub fn init_in(
831 buf: &'a mut AlignedBuffer,
832 sr: SampleRate,
833 app: Application,
834 mapping: Mapping<'_>,
835 ) -> Result<Self> {
836 let required = MultistreamEncoder::size(mapping.streams, mapping.coupled_streams)?;
837 if buf.capacity_bytes() < required {
838 return Err(Error::BadArg);
839 }
840 let ptr = buf.as_mut_ptr::<OpusMSEncoder>();
841 unsafe { MultistreamEncoder::init_in_place(ptr, sr, app, mapping)? };
842 Ok(unsafe { Self::from_raw(ptr, sr, mapping) })
843 }
844
845 pub fn init_in_surround(
850 buf: &'a mut AlignedBuffer,
851 sr: SampleRate,
852 channels: u8,
853 mapping_family: i32,
854 app: Application,
855 ) -> Result<(Self, Vec<u8>)> {
856 let required = MultistreamEncoder::surround_size(channels, mapping_family)?;
857 if buf.capacity_bytes() < required {
858 return Err(Error::BadArg);
859 }
860 let ptr = buf.as_mut_ptr::<OpusMSEncoder>();
861 let (streams, coupled, mapping) = unsafe {
862 MultistreamEncoder::init_surround_in_place(ptr, sr, channels, mapping_family, app)?
863 };
864 let mapping_ref = Mapping {
865 channels,
866 streams,
867 coupled_streams: coupled,
868 mapping: &mapping,
869 };
870 let encoder = unsafe { Self::from_raw(ptr, sr, mapping_ref) };
871 Ok((encoder, mapping))
872 }
873}
874
875impl Deref for MultistreamEncoderRef<'_> {
876 type Target = MultistreamEncoder;
877
878 fn deref(&self) -> &Self::Target {
879 &self.inner
880 }
881}
882
883impl DerefMut for MultistreamEncoderRef<'_> {
884 fn deref_mut(&mut self) -> &mut Self::Target {
885 &mut self.inner
886 }
887}
888
889pub struct MultistreamDecoder {
891 raw: RawHandle<OpusMSDecoder>,
892 sample_rate: SampleRate,
893 channels: u8,
894}
895
896unsafe impl Send for MultistreamDecoder {}
897unsafe impl Sync for MultistreamDecoder {}
898
899pub struct MultistreamDecoderRef<'a> {
901 inner: MultistreamDecoder,
902 _marker: PhantomData<&'a mut OpusMSDecoder>,
903}
904
905unsafe impl Send for MultistreamDecoderRef<'_> {}
906unsafe impl Sync for MultistreamDecoderRef<'_> {}
907
908impl MultistreamDecoder {
909 fn from_raw(
910 ptr: NonNull<OpusMSDecoder>,
911 sample_rate: SampleRate,
912 channels: u8,
913 ownership: Ownership,
914 ) -> Self {
915 Self {
916 raw: RawHandle::new(ptr, ownership, opus_multistream_decoder_destroy),
917 sample_rate,
918 channels,
919 }
920 }
921
922 pub fn size(streams: u8, coupled_streams: u8) -> Result<usize> {
928 let raw = unsafe {
929 opus_multistream_decoder_get_size(i32::from(streams), i32::from(coupled_streams))
930 };
931 if raw <= 0 {
932 return Err(Error::BadArg);
933 }
934 usize::try_from(raw).map_err(|_| Error::InternalError)
935 }
936
937 pub unsafe fn init_in_place(
947 ptr: *mut OpusMSDecoder,
948 sr: SampleRate,
949 mapping: Mapping<'_>,
950 ) -> Result<()> {
951 if ptr.is_null() {
952 return Err(Error::BadArg);
953 }
954 if !crate::opus_ptr_is_aligned(ptr.cast()) {
955 return Err(Error::BadArg);
956 }
957 mapping.validate_for_decoder()?;
958 let r = unsafe {
959 opus_multistream_decoder_init(
960 ptr,
961 sr as i32,
962 i32::from(mapping.channels),
963 i32::from(mapping.streams),
964 i32::from(mapping.coupled_streams),
965 mapping.mapping.as_ptr(),
966 )
967 };
968 if r != 0 {
969 return Err(Error::from_code(r));
970 }
971 Ok(())
972 }
973
974 pub fn new(sr: SampleRate, mapping: Mapping<'_>) -> Result<Self> {
980 mapping.validate_for_decoder()?;
981 let mut err = 0i32;
982 let dec = unsafe {
983 opus_multistream_decoder_create(
984 sr as i32,
985 i32::from(mapping.channels),
986 i32::from(mapping.streams),
987 i32::from(mapping.coupled_streams),
988 mapping.mapping.as_ptr(),
989 std::ptr::addr_of_mut!(err),
990 )
991 };
992 if err != 0 {
993 return Err(Error::from_code(err));
994 }
995 let dec = NonNull::new(dec).ok_or(Error::AllocFail)?;
996 Ok(Self::from_raw(dec, sr, mapping.channels, Ownership::Owned))
997 }
998
999 pub fn decode(
1005 &mut self,
1006 packet: &[u8],
1007 out: &mut [i16],
1008 frame_size_per_ch: usize,
1009 fec: bool,
1010 ) -> Result<usize> {
1011 let frame_size_per_ch = NonZeroUsize::new(frame_size_per_ch).ok_or(Error::BadArg)?;
1012 if frame_size_per_ch.get() > max_frame_samples_for(self.sample_rate) {
1013 return Err(Error::BadArg);
1014 }
1015 if out.len() != frame_size_per_ch.get() * self.channels as usize {
1016 return Err(Error::BadArg);
1017 }
1018 let n = unsafe {
1019 opus_multistream_decode(
1020 self.raw.as_ptr(),
1021 if packet.is_empty() {
1022 std::ptr::null()
1023 } else {
1024 packet.as_ptr()
1025 },
1026 if packet.is_empty() {
1027 0
1028 } else {
1029 i32::try_from(packet.len()).map_err(|_| Error::BadArg)?
1030 },
1031 out.as_mut_ptr(),
1032 i32::try_from(frame_size_per_ch.get()).map_err(|_| Error::BadArg)?,
1033 i32::from(fec),
1034 )
1035 };
1036 if n < 0 {
1037 return Err(Error::from_code(n));
1038 }
1039 usize::try_from(n).map_err(|_| Error::InternalError)
1040 }
1041
1042 pub fn decode_float(
1048 &mut self,
1049 packet: &[u8],
1050 out: &mut [f32],
1051 frame_size_per_ch: usize,
1052 fec: bool,
1053 ) -> Result<usize> {
1054 let frame_size_per_ch = NonZeroUsize::new(frame_size_per_ch).ok_or(Error::BadArg)?;
1055 if frame_size_per_ch.get() > max_frame_samples_for(self.sample_rate) {
1056 return Err(Error::BadArg);
1057 }
1058 if out.len() != frame_size_per_ch.get() * self.channels as usize {
1059 return Err(Error::BadArg);
1060 }
1061 let n = unsafe {
1062 opus_multistream_decode_float(
1063 self.raw.as_ptr(),
1064 if packet.is_empty() {
1065 std::ptr::null()
1066 } else {
1067 packet.as_ptr()
1068 },
1069 if packet.is_empty() {
1070 0
1071 } else {
1072 i32::try_from(packet.len()).map_err(|_| Error::BadArg)?
1073 },
1074 out.as_mut_ptr(),
1075 i32::try_from(frame_size_per_ch.get()).map_err(|_| Error::BadArg)?,
1076 i32::from(fec),
1077 )
1078 };
1079 if n < 0 {
1080 return Err(Error::from_code(n));
1081 }
1082 usize::try_from(n).map_err(|_| Error::InternalError)
1083 }
1084
1085 pub fn final_range(&mut self) -> Result<u32> {
1091 let mut v: u32 = 0;
1092 let r = unsafe {
1093 opus_multistream_decoder_ctl(
1094 self.raw.as_ptr(),
1095 OPUS_GET_FINAL_RANGE_REQUEST as i32,
1096 &mut v,
1097 )
1098 };
1099 if r != 0 {
1100 return Err(Error::from_code(r));
1101 }
1102 Ok(v)
1103 }
1104
1105 pub fn reset(&mut self) -> Result<()> {
1111 let r = unsafe { opus_multistream_decoder_ctl(self.raw.as_ptr(), OPUS_RESET_STATE as i32) };
1112 if r != 0 {
1113 return Err(Error::from_code(r));
1114 }
1115 Ok(())
1116 }
1117
1118 pub fn set_gain(&mut self, q8_db: i32) -> Result<()> {
1124 self.simple_ctl(OPUS_SET_GAIN_REQUEST as i32, q8_db)
1125 }
1126
1127 pub fn gain(&mut self) -> Result<i32> {
1133 self.get_int_ctl(OPUS_GET_GAIN_REQUEST as i32)
1134 }
1135
1136 pub fn set_phase_inversion_disabled(&mut self, disabled: bool) -> Result<()> {
1142 self.simple_ctl(
1143 OPUS_SET_PHASE_INVERSION_DISABLED_REQUEST as i32,
1144 i32::from(disabled),
1145 )
1146 }
1147
1148 pub fn phase_inversion_disabled(&mut self) -> Result<bool> {
1154 self.get_bool_ctl(OPUS_GET_PHASE_INVERSION_DISABLED_REQUEST as i32)
1155 }
1156
1157 pub fn get_sample_rate(&mut self) -> Result<i32> {
1163 self.get_int_ctl(OPUS_GET_SAMPLE_RATE_REQUEST as i32)
1164 }
1165
1166 pub fn get_pitch(&mut self) -> Result<i32> {
1172 self.get_int_ctl(OPUS_GET_PITCH_REQUEST as i32)
1173 }
1174
1175 pub fn get_last_packet_duration(&mut self) -> Result<i32> {
1181 self.get_int_ctl(OPUS_GET_LAST_PACKET_DURATION_REQUEST as i32)
1182 }
1183
1184 #[must_use]
1186 pub const fn channels(&self) -> u8 {
1187 self.channels
1188 }
1189 #[must_use]
1191 pub const fn sample_rate(&self) -> SampleRate {
1192 self.sample_rate
1193 }
1194
1195 pub fn new_surround(
1201 sr: SampleRate,
1202 channels: u8,
1203 mapping_family: i32,
1204 ) -> Result<(Self, Vec<u8>, u8, u8)> {
1205 if channels == 0 {
1206 return Err(Error::BadArg);
1207 }
1208 let mut err = 0i32;
1209 let mut streams = 0i32;
1210 let mut coupled = 0i32;
1211 let mut mapping = vec![0u8; channels as usize];
1212 let enc = unsafe {
1215 opus_multistream_surround_encoder_create(
1216 sr as i32,
1217 i32::from(channels),
1218 mapping_family,
1219 std::ptr::addr_of_mut!(streams),
1220 std::ptr::addr_of_mut!(coupled),
1221 mapping.as_mut_ptr(),
1222 Application::Audio as i32,
1223 std::ptr::addr_of_mut!(err),
1224 )
1225 };
1226 if !enc.is_null() {
1227 unsafe { opus_multistream_encoder_destroy(enc) };
1228 }
1229 if err != 0 {
1230 return Err(Error::from_code(err));
1231 }
1232 let dec = unsafe {
1233 opus_multistream_decoder_create(
1234 sr as i32,
1235 i32::from(channels),
1236 streams,
1237 coupled,
1238 mapping.as_ptr(),
1239 std::ptr::addr_of_mut!(err),
1240 )
1241 };
1242 if err != 0 {
1243 return Err(Error::from_code(err));
1244 }
1245 let dec = NonNull::new(dec).ok_or(Error::AllocFail)?;
1246 Ok((
1247 Self::from_raw(dec, sr, channels, Ownership::Owned),
1248 mapping,
1249 u8::try_from(streams).map_err(|_| Error::BadArg)?,
1250 u8::try_from(coupled).map_err(|_| Error::BadArg)?,
1251 ))
1252 }
1253
1254 pub unsafe fn decoder_state_ptr(&mut self, stream_index: i32) -> Result<*mut OpusDecoder> {
1264 let mut state: *mut OpusDecoder = std::ptr::null_mut();
1265 let r = unsafe {
1266 opus_multistream_decoder_ctl(
1267 self.raw.as_ptr(),
1268 OPUS_MULTISTREAM_GET_DECODER_STATE_REQUEST as i32,
1269 stream_index,
1270 &mut state,
1271 )
1272 };
1273 if r != 0 {
1274 return Err(Error::from_code(r));
1275 }
1276 if state.is_null() {
1277 return Err(Error::InternalError);
1278 }
1279 Ok(state)
1280 }
1281
1282 fn simple_ctl(&mut self, req: i32, val: i32) -> Result<()> {
1283 let r = unsafe { opus_multistream_decoder_ctl(self.raw.as_ptr(), req, val) };
1284 if r != 0 {
1285 return Err(Error::from_code(r));
1286 }
1287 Ok(())
1288 }
1289
1290 fn get_int_ctl(&mut self, req: i32) -> Result<i32> {
1291 let mut v: i32 = 0;
1292 let r = unsafe { opus_multistream_decoder_ctl(self.raw.as_ptr(), req, &mut v) };
1293 if r != 0 {
1294 return Err(Error::from_code(r));
1295 }
1296 Ok(v)
1297 }
1298
1299 fn get_bool_ctl(&mut self, req: i32) -> Result<bool> {
1300 Ok(self.get_int_ctl(req)? != 0)
1301 }
1302}
1303
1304impl<'a> MultistreamDecoderRef<'a> {
1305 #[must_use]
1315 pub unsafe fn from_raw(ptr: *mut OpusMSDecoder, sr: SampleRate, mapping: Mapping<'_>) -> Self {
1316 debug_assert!(!ptr.is_null(), "from_raw called with null ptr");
1317 debug_assert!(crate::opus_ptr_is_aligned(ptr.cast()));
1318 debug_assert!(mapping.validate_for_decoder().is_ok());
1319 let decoder = MultistreamDecoder::from_raw(
1320 unsafe { NonNull::new_unchecked(ptr) },
1321 sr,
1322 mapping.channels,
1323 Ownership::Borrowed,
1324 );
1325 Self {
1326 inner: decoder,
1327 _marker: PhantomData,
1328 }
1329 }
1330
1331 pub fn init_in(
1336 buf: &'a mut AlignedBuffer,
1337 sr: SampleRate,
1338 mapping: Mapping<'_>,
1339 ) -> Result<Self> {
1340 let required = MultistreamDecoder::size(mapping.streams, mapping.coupled_streams)?;
1341 if buf.capacity_bytes() < required {
1342 return Err(Error::BadArg);
1343 }
1344 let ptr = buf.as_mut_ptr::<OpusMSDecoder>();
1345 unsafe { MultistreamDecoder::init_in_place(ptr, sr, mapping)? };
1346 Ok(unsafe { Self::from_raw(ptr, sr, mapping) })
1347 }
1348}
1349
1350impl Deref for MultistreamDecoderRef<'_> {
1351 type Target = MultistreamDecoder;
1352
1353 fn deref(&self) -> &Self::Target {
1354 &self.inner
1355 }
1356}
1357
1358impl DerefMut for MultistreamDecoderRef<'_> {
1359 fn deref_mut(&mut self) -> &mut Self::Target {
1360 &mut self.inner
1361 }
1362}
1363
1364#[cfg(test)]
1365mod tests {
1366 use super::*;
1367
1368 #[test]
1369 fn mapping_allows_dropped_channels() {
1370 let mapping = Mapping {
1371 channels: 6,
1372 streams: 2,
1373 coupled_streams: 1,
1374 mapping: &[0, 1, 2, u8::MAX, u8::MAX, u8::MAX],
1375 };
1376 assert!(mapping.validate_for_encoder().is_ok());
1377 }
1378
1379 #[test]
1380 fn mapping_requires_encoder_stream_coverage() {
1381 let mapping = Mapping {
1382 channels: 2,
1383 streams: 1,
1384 coupled_streams: 1,
1385 mapping: &[0, 0],
1386 };
1387 assert!(mapping.validate_for_decoder().is_ok());
1388 assert!(mapping.validate_for_encoder().is_err());
1389 }
1390}