1#![cfg_attr(not(test), allow(dead_code))]
3
4use alloc::vec;
5use alloc::vec::Vec;
6
7use crate::celt::{CELT_SIG_SCALE, OpusRes, float2int, float2int16, isqrt32};
8use crate::opus_decoder::{
9 OpusDecodeError, OpusDecoder, OpusDecoderCtlError, OpusDecoderCtlRequest, OpusDecoderInitError,
10 opus_decode_native, opus_decoder_create, opus_decoder_ctl, opus_decoder_get_size,
11};
12use crate::opus_encoder::{
13 OPUS_FRAMESIZE_ARG, OpusEncodeError, OpusEncodeOptions, OpusEncoder, OpusEncoderCtlError,
14 OpusEncoderCtlRequest, OpusEncoderInitError, opus_encode_with_options, opus_encoder_create,
15 opus_encoder_ctl, opus_encoder_get_size,
16};
17use crate::packet::{PacketError, opus_packet_get_nb_samples, opus_packet_parse_impl};
18
19pub(crate) const OPUS_AUTO: i32 = -1000;
21pub(crate) const OPUS_BITRATE_MAX: i32 = -1;
23
24#[allow(dead_code)]
26#[derive(Debug, Clone, Copy, PartialEq, Eq)]
27pub(crate) enum MappingType {
28 None,
29 Surround,
30 Ambisonics,
31}
32
33#[derive(Debug, Clone, PartialEq, Eq)]
39pub struct ChannelLayout {
40 pub nb_channels: usize,
41 pub nb_streams: usize,
42 pub nb_coupled_streams: usize,
43 pub mapping: [u8; 256],
44}
45
46#[derive(Debug, Clone, PartialEq, Eq)]
48pub enum OpusMultistreamDecoderError {
49 BadArgument,
50 BufferTooSmall,
51 InternalError,
52 InvalidPacket,
53 Unimplemented,
54 DecoderInit(OpusDecoderInitError),
55 DecoderCtl(OpusDecoderCtlError),
56 DecoderDecode(OpusDecodeError),
57}
58
59impl OpusMultistreamDecoderError {
60 #[inline]
61 pub const fn code(&self) -> i32 {
62 match self {
63 Self::BadArgument => -1,
64 Self::BufferTooSmall => -2,
65 Self::InternalError => -3,
66 Self::InvalidPacket => -4,
67 Self::Unimplemented => -5,
68 Self::DecoderInit(OpusDecoderInitError::BadArgument) => -1,
69 Self::DecoderInit(_) => -3,
70 Self::DecoderCtl(OpusDecoderCtlError::BadArgument) => -1,
71 Self::DecoderCtl(OpusDecoderCtlError::Unimplemented) => -5,
72 Self::DecoderCtl(OpusDecoderCtlError::Silk(_)) => -3,
73 Self::DecoderDecode(err) => err.code(),
74 }
75 }
76}
77
78impl From<PacketError> for OpusMultistreamDecoderError {
79 #[inline]
80 fn from(value: PacketError) -> Self {
81 match value {
82 PacketError::BadArgument => Self::BadArgument,
83 PacketError::InvalidPacket => Self::InvalidPacket,
84 }
85 }
86}
87
88impl From<OpusDecoderInitError> for OpusMultistreamDecoderError {
89 #[inline]
90 fn from(value: OpusDecoderInitError) -> Self {
91 Self::DecoderInit(value)
92 }
93}
94
95impl From<OpusDecoderCtlError> for OpusMultistreamDecoderError {
96 #[inline]
97 fn from(value: OpusDecoderCtlError) -> Self {
98 Self::DecoderCtl(value)
99 }
100}
101
102impl From<OpusDecodeError> for OpusMultistreamDecoderError {
103 #[inline]
104 fn from(value: OpusDecodeError) -> Self {
105 Self::DecoderDecode(value)
106 }
107}
108
109#[repr(C)]
110struct ChannelLayoutLayout {
111 nb_channels: i32,
112 nb_streams: i32,
113 nb_coupled_streams: i32,
114 mapping: [u8; 256],
115}
116
117#[repr(C)]
118struct OpusMsDecoderLayout {
119 layout: ChannelLayoutLayout,
120}
121
122#[repr(C)]
123struct OpusMsEncoderLayout {
124 layout: ChannelLayoutLayout,
125}
126
127#[inline]
129fn align(value: usize) -> usize {
130 #[repr(C)]
131 struct AlignProbe {
132 _tag: u8,
133 _union: AlignUnion,
134 }
135
136 #[repr(C)]
137 union AlignUnion {
138 _ptr: *const (),
139 _i32: i32,
140 _f32: f32,
141 }
142
143 let alignment = core::mem::align_of::<AlignProbe>();
144 value.div_ceil(alignment) * alignment
145}
146
147#[must_use]
149pub fn opus_multistream_decoder_get_size(
150 nb_streams: usize,
151 nb_coupled_streams: usize,
152) -> Option<usize> {
153 if nb_streams == 0 || nb_coupled_streams > nb_streams {
154 return None;
155 }
156
157 let coupled_size = opus_decoder_get_size(2)?;
158 let mono_size = opus_decoder_get_size(1)?;
159 let header_size = align(core::mem::size_of::<OpusMsDecoderLayout>());
160
161 let coupled_total = nb_coupled_streams.checked_mul(align(coupled_size))?;
162 let mono_total = nb_streams
163 .checked_sub(nb_coupled_streams)?
164 .checked_mul(align(mono_size))?;
165
166 header_size
167 .checked_add(coupled_total)?
168 .checked_add(mono_total)
169}
170
171#[derive(Debug)]
173pub struct OpusMultistreamDecoder<'mode> {
174 layout: ChannelLayout,
175 decoders: Vec<OpusDecoder<'mode>>,
176}
177
178impl<'mode> OpusMultistreamDecoder<'mode> {
179 #[inline]
180 pub fn layout(&self) -> &ChannelLayout {
181 &self.layout
182 }
183
184 #[inline]
185 fn sample_rate(&self) -> Option<i32> {
186 self.decoders.first().map(|decoder| decoder.fs)
187 }
188
189 pub fn init(
191 &mut self,
192 sample_rate: i32,
193 channels: usize,
194 streams: usize,
195 coupled_streams: usize,
196 mapping: &[u8],
197 ) -> Result<(), OpusMultistreamDecoderError> {
198 let layout = build_layout(channels, streams, coupled_streams, mapping)?;
199 let decoders = build_stream_decoders(sample_rate, streams, coupled_streams)?;
200
201 self.layout = layout;
202 self.decoders = decoders;
203 Ok(())
204 }
205
206 pub fn decoder_state(&mut self, stream_id: usize) -> Option<&mut OpusDecoder<'mode>> {
209 self.decoders.get_mut(stream_id)
210 }
211}
212
213pub fn opus_multistream_decoder_create(
216 sample_rate: i32,
217 channels: usize,
218 streams: usize,
219 coupled_streams: usize,
220 mapping: &[u8],
221) -> Result<OpusMultistreamDecoder<'static>, OpusMultistreamDecoderError> {
222 let layout = build_layout(channels, streams, coupled_streams, mapping)?;
223 let decoders = build_stream_decoders(sample_rate, streams, coupled_streams)?;
224
225 Ok(OpusMultistreamDecoder { layout, decoders })
226}
227
228pub fn opus_multistream_decoder_init(
230 decoder: &mut OpusMultistreamDecoder<'_>,
231 sample_rate: i32,
232 channels: usize,
233 streams: usize,
234 coupled_streams: usize,
235 mapping: &[u8],
236) -> Result<(), OpusMultistreamDecoderError> {
237 decoder.init(sample_rate, channels, streams, coupled_streams, mapping)
238}
239
240fn build_layout(
241 channels: usize,
242 streams: usize,
243 coupled_streams: usize,
244 mapping: &[u8],
245) -> Result<ChannelLayout, OpusMultistreamDecoderError> {
246 if channels == 0
247 || channels > 255
248 || coupled_streams > streams
249 || streams == 0
250 || streams > 255 - coupled_streams
251 {
252 return Err(OpusMultistreamDecoderError::BadArgument);
253 }
254
255 if mapping.len() < channels {
256 return Err(OpusMultistreamDecoderError::BadArgument);
257 }
258
259 let mut layout = ChannelLayout {
260 nb_channels: channels,
261 nb_streams: streams,
262 nb_coupled_streams: coupled_streams,
263 mapping: [u8::MAX; 256],
264 };
265 layout.mapping[..channels].copy_from_slice(&mapping[..channels]);
266 if !validate_layout(&layout) {
267 return Err(OpusMultistreamDecoderError::BadArgument);
268 }
269
270 Ok(layout)
271}
272
273fn build_stream_decoders(
274 sample_rate: i32,
275 streams: usize,
276 coupled_streams: usize,
277) -> Result<Vec<OpusDecoder<'static>>, OpusMultistreamDecoderError> {
278 if sample_rate <= 0 {
279 return Err(OpusMultistreamDecoderError::BadArgument);
280 }
281
282 let mut decoders = Vec::with_capacity(streams);
283 for stream in 0..streams {
284 let channels: i32 = if stream < coupled_streams { 2 } else { 1 };
285 decoders.push(opus_decoder_create(sample_rate, channels)?);
286 }
287
288 Ok(decoders)
289}
290
291#[allow(dead_code)]
292#[derive(Debug, Clone, Copy, PartialEq, Eq)]
293struct VorbisLayout {
294 nb_streams: usize,
295 nb_coupled_streams: usize,
296 mapping: [u8; 8],
297}
298
299#[allow(dead_code)]
301const VORBIS_MAPPINGS: [VorbisLayout; 8] = [
302 VorbisLayout {
303 nb_streams: 1,
304 nb_coupled_streams: 0,
305 mapping: [0, 255, 255, 255, 255, 255, 255, 255],
306 }, VorbisLayout {
308 nb_streams: 1,
309 nb_coupled_streams: 1,
310 mapping: [0, 1, 255, 255, 255, 255, 255, 255],
311 }, VorbisLayout {
313 nb_streams: 2,
314 nb_coupled_streams: 1,
315 mapping: [0, 2, 1, 255, 255, 255, 255, 255],
316 }, VorbisLayout {
318 nb_streams: 2,
319 nb_coupled_streams: 2,
320 mapping: [0, 1, 2, 3, 255, 255, 255, 255],
321 }, VorbisLayout {
323 nb_streams: 3,
324 nb_coupled_streams: 2,
325 mapping: [0, 4, 1, 2, 3, 255, 255, 255],
326 }, VorbisLayout {
328 nb_streams: 4,
329 nb_coupled_streams: 2,
330 mapping: [0, 4, 1, 2, 3, 5, 255, 255],
331 }, VorbisLayout {
333 nb_streams: 4,
334 nb_coupled_streams: 3,
335 mapping: [0, 4, 1, 2, 3, 5, 6, 255],
336 }, VorbisLayout {
338 nb_streams: 5,
339 nb_coupled_streams: 3,
340 mapping: [0, 6, 1, 2, 3, 4, 5, 7],
341 }, ];
343
344#[must_use]
346pub(crate) fn validate_layout(layout: &ChannelLayout) -> bool {
347 let Some(max_channel) = layout.nb_streams.checked_add(layout.nb_coupled_streams) else {
348 return false;
349 };
350
351 if max_channel > u8::MAX as usize {
352 return false;
353 }
354
355 if layout.nb_channels > layout.mapping.len() {
356 return false;
357 }
358
359 layout
360 .mapping
361 .iter()
362 .take(layout.nb_channels)
363 .all(|&value| value == u8::MAX || usize::from(value) < max_channel)
364}
365
366#[must_use]
368pub(crate) fn validate_encoder_layout(layout: &ChannelLayout) -> bool {
369 for stream in 0..layout.nb_streams {
370 if stream < layout.nb_coupled_streams {
371 if get_left_channel(layout, stream, None).is_none() {
372 return false;
373 }
374 if get_right_channel(layout, stream, None).is_none() {
375 return false;
376 }
377 } else if get_mono_channel(layout, stream, None).is_none() {
378 return false;
379 }
380 }
381
382 true
383}
384
385#[must_use]
387pub(crate) fn validate_ambisonics(channels: usize) -> Option<(usize, usize)> {
388 if !(1..=227).contains(&channels) {
389 return None;
390 }
391
392 let order_plus_one = isqrt32(channels as u32) as usize;
393 let acn_channels = order_plus_one.checked_mul(order_plus_one)?;
394 let nondiegetic_channels = channels.checked_sub(acn_channels)?;
395
396 if nondiegetic_channels != 0 && nondiegetic_channels != 2 {
397 return None;
398 }
399
400 let streams = acn_channels + usize::from(nondiegetic_channels != 0);
401 let coupled_streams = usize::from(nondiegetic_channels != 0);
402 Some((streams, coupled_streams))
403}
404
405fn surround_rate_allocation(
406 layout: &ChannelLayout,
407 bitrate_bps: i32,
408 lfe_stream: Option<usize>,
409 frame_size: usize,
410 sample_rate: i32,
411 rates: &mut [i32],
412) -> Option<()> {
413 let nb_streams = layout.nb_streams;
414 let nb_coupled = layout.nb_coupled_streams;
415 let nb_lfe = usize::from(lfe_stream.is_some());
416 if nb_streams == 0 || nb_coupled > nb_streams || nb_streams < nb_coupled + nb_lfe {
417 return None;
418 }
419 if frame_size == 0 || sample_rate <= 0 {
420 return None;
421 }
422 if rates.len() < nb_streams {
423 return None;
424 }
425
426 let nb_uncoupled = nb_streams - nb_coupled - nb_lfe;
427 let nb_normal = 2 * nb_coupled + nb_uncoupled;
428 if nb_normal == 0 {
429 return None;
430 }
431
432 let frame_rate = sample_rate / frame_size as i32;
433 let channel_offset = 40 * frame_rate.max(50);
434 let bitrate = if bitrate_bps == OPUS_AUTO {
435 nb_normal as i32 * (channel_offset + sample_rate + 10_000) + 8000 * nb_lfe as i32
436 } else if bitrate_bps == OPUS_BITRATE_MAX {
437 nb_normal as i32 * 300_000 + nb_lfe as i32 * 128_000
438 } else {
439 bitrate_bps
440 };
441
442 let lfe_offset = bitrate
443 .checked_div(20)
444 .map(|value| value.min(3000))
445 .and_then(|value| value.checked_add(15 * frame_rate.max(50)))?;
446 let stream_offset =
447 (((bitrate - channel_offset * nb_normal as i32 - lfe_offset * nb_lfe as i32)
448 / nb_normal as i32)
449 / 2)
450 .clamp(0, 20_000);
451 let coupled_ratio = 512;
452 let lfe_ratio = 32;
453
454 let total = ((nb_uncoupled as i32) << 8)
455 + coupled_ratio * nb_coupled as i32
456 + lfe_ratio * nb_lfe as i32;
457 if total == 0 {
458 return None;
459 }
460 let channel_rate = 256
461 * (bitrate
462 - lfe_offset * nb_lfe as i32
463 - stream_offset * (nb_coupled as i32 + nb_uncoupled as i32)
464 - channel_offset * nb_normal as i32)
465 / total;
466
467 for (stream, slot) in rates.iter_mut().take(nb_streams).enumerate() {
468 let value = if stream < nb_coupled {
469 2 * channel_offset + (stream_offset + ((channel_rate * coupled_ratio) >> 8)).max(0)
470 } else if lfe_stream == Some(stream) {
471 (lfe_offset + ((channel_rate * lfe_ratio) >> 8)).max(0)
472 } else {
473 channel_offset + (stream_offset + channel_rate).max(0)
474 };
475 *slot = value;
476 }
477
478 Some(())
479}
480
481fn ambisonics_rate_allocation(
482 layout: &ChannelLayout,
483 bitrate_bps: i32,
484 frame_size: usize,
485 sample_rate: i32,
486 rates: &mut [i32],
487) -> Option<()> {
488 if frame_size == 0 || sample_rate <= 0 || layout.nb_streams == 0 {
489 return None;
490 }
491 if rates.len() < layout.nb_streams {
492 return None;
493 }
494
495 let nb_channels = layout.nb_streams + layout.nb_coupled_streams;
496 let total_rate = if bitrate_bps == OPUS_AUTO {
497 let term = sample_rate + 60 * sample_rate / frame_size as i32;
498 (layout.nb_coupled_streams + layout.nb_streams) as i32 * term
499 + layout.nb_streams as i32 * 15_000
500 } else if bitrate_bps == OPUS_BITRATE_MAX {
501 nb_channels as i32 * 320_000
502 } else {
503 bitrate_bps
504 };
505
506 let per_stream_rate = total_rate / layout.nb_streams as i32;
507 for slot in rates.iter_mut().take(layout.nb_streams) {
508 *slot = per_stream_rate;
509 }
510
511 Some(())
512}
513
514#[must_use]
516pub(crate) fn rate_allocation(
517 layout: &ChannelLayout,
518 mapping_type: MappingType,
519 bitrate_bps: i32,
520 lfe_stream: Option<usize>,
521 frame_size: usize,
522 sample_rate: i32,
523 rates: &mut [i32],
524) -> Option<i32> {
525 match mapping_type {
526 MappingType::Ambisonics => {
527 ambisonics_rate_allocation(layout, bitrate_bps, frame_size, sample_rate, rates)?
528 }
529 _ => surround_rate_allocation(
530 layout,
531 bitrate_bps,
532 lfe_stream,
533 frame_size,
534 sample_rate,
535 rates,
536 )?,
537 }
538
539 let mut sum = 0i64;
540 for rate in rates.iter_mut().take(layout.nb_streams) {
541 *rate = (*rate).max(500);
542 sum += i64::from(*rate);
543 }
544
545 i32::try_from(sum).ok()
546}
547
548fn next_index(prev: Option<usize>) -> Option<usize> {
549 match prev {
550 Some(idx) => idx.checked_add(1),
551 None => Some(0),
552 }
553}
554
555fn find_channel(layout: &ChannelLayout, start: usize, target: usize) -> Option<usize> {
556 let limit = layout.nb_channels.min(layout.mapping.len());
557 (start..limit).find(|&i| usize::from(layout.mapping[i]) == target)
558}
559
560#[must_use]
562pub(crate) fn get_left_channel(
563 layout: &ChannelLayout,
564 stream_id: usize,
565 prev: Option<usize>,
566) -> Option<usize> {
567 let target = stream_id.checked_mul(2)?;
568 let start = next_index(prev)?;
569 find_channel(layout, start, target)
570}
571
572#[must_use]
574pub(crate) fn get_right_channel(
575 layout: &ChannelLayout,
576 stream_id: usize,
577 prev: Option<usize>,
578) -> Option<usize> {
579 let target = stream_id.checked_mul(2)?.checked_add(1)?;
580 let start = next_index(prev)?;
581 find_channel(layout, start, target)
582}
583
584#[must_use]
586pub(crate) fn get_mono_channel(
587 layout: &ChannelLayout,
588 stream_id: usize,
589 prev: Option<usize>,
590) -> Option<usize> {
591 let target = stream_id.checked_add(layout.nb_coupled_streams)?;
592 let start = next_index(prev)?;
593 find_channel(layout, start, target)
594}
595
596pub enum OpusMultistreamDecoderCtlRequest<'req> {
598 SetGain(i32),
599 GetGain(&'req mut i32),
600 SetComplexity(i32),
601 GetComplexity(&'req mut i32),
602 GetBandwidth(&'req mut i32),
603 GetSampleRate(&'req mut i32),
604 GetFinalRange(&'req mut u32),
605 ResetState,
606 GetLastPacketDuration(&'req mut i32),
607 SetPhaseInversionDisabled(bool),
608 GetPhaseInversionDisabled(&'req mut bool),
609 SetDnnBlob(&'req [u8]),
610}
611
612pub fn opus_multistream_decoder_ctl<'req>(
614 decoder: &mut OpusMultistreamDecoder<'_>,
615 request: OpusMultistreamDecoderCtlRequest<'req>,
616) -> Result<(), OpusMultistreamDecoderError> {
617 if decoder.decoders.is_empty() {
618 return Err(OpusMultistreamDecoderError::InternalError);
619 }
620
621 match request {
622 OpusMultistreamDecoderCtlRequest::SetGain(value) => {
623 for dec in &mut decoder.decoders {
624 opus_decoder_ctl(dec, OpusDecoderCtlRequest::SetGain(value))?;
625 }
626 }
627 OpusMultistreamDecoderCtlRequest::GetGain(slot) => {
628 opus_decoder_ctl(
629 decoder
630 .decoders
631 .first_mut()
632 .ok_or(OpusMultistreamDecoderError::InternalError)?,
633 OpusDecoderCtlRequest::GetGain(slot),
634 )?;
635 }
636 OpusMultistreamDecoderCtlRequest::SetComplexity(value) => {
637 for dec in &mut decoder.decoders {
638 opus_decoder_ctl(dec, OpusDecoderCtlRequest::SetComplexity(value))?;
639 }
640 }
641 OpusMultistreamDecoderCtlRequest::GetComplexity(slot) => {
642 opus_decoder_ctl(
643 decoder
644 .decoders
645 .first_mut()
646 .ok_or(OpusMultistreamDecoderError::InternalError)?,
647 OpusDecoderCtlRequest::GetComplexity(slot),
648 )?;
649 }
650 OpusMultistreamDecoderCtlRequest::GetBandwidth(slot) => {
651 opus_decoder_ctl(
652 decoder
653 .decoders
654 .first_mut()
655 .ok_or(OpusMultistreamDecoderError::InternalError)?,
656 OpusDecoderCtlRequest::GetBandwidth(slot),
657 )?;
658 }
659 OpusMultistreamDecoderCtlRequest::GetSampleRate(slot) => {
660 opus_decoder_ctl(
661 decoder
662 .decoders
663 .first_mut()
664 .ok_or(OpusMultistreamDecoderError::InternalError)?,
665 OpusDecoderCtlRequest::GetSampleRate(slot),
666 )?;
667 }
668 OpusMultistreamDecoderCtlRequest::GetFinalRange(slot) => {
669 let mut acc = 0u32;
670 for dec in &mut decoder.decoders {
671 let mut value = 0u32;
672 opus_decoder_ctl(dec, OpusDecoderCtlRequest::GetFinalRange(&mut value))?;
673 acc ^= value;
674 }
675 *slot = acc;
676 }
677 OpusMultistreamDecoderCtlRequest::ResetState => {
678 for dec in &mut decoder.decoders {
679 opus_decoder_ctl(dec, OpusDecoderCtlRequest::ResetState)?;
680 }
681 }
682 OpusMultistreamDecoderCtlRequest::GetLastPacketDuration(slot) => {
683 opus_decoder_ctl(
684 decoder
685 .decoders
686 .first_mut()
687 .ok_or(OpusMultistreamDecoderError::InternalError)?,
688 OpusDecoderCtlRequest::GetLastPacketDuration(slot),
689 )?;
690 }
691 OpusMultistreamDecoderCtlRequest::SetPhaseInversionDisabled(value) => {
692 for dec in &mut decoder.decoders {
693 opus_decoder_ctl(dec, OpusDecoderCtlRequest::SetPhaseInversionDisabled(value))?;
694 }
695 }
696 OpusMultistreamDecoderCtlRequest::GetPhaseInversionDisabled(slot) => {
697 opus_decoder_ctl(
698 decoder
699 .decoders
700 .first_mut()
701 .ok_or(OpusMultistreamDecoderError::InternalError)?,
702 OpusDecoderCtlRequest::GetPhaseInversionDisabled(slot),
703 )?;
704 }
705 OpusMultistreamDecoderCtlRequest::SetDnnBlob(data) => {
706 for dec in &mut decoder.decoders {
707 opus_decoder_ctl(dec, OpusDecoderCtlRequest::SetDnnBlob(data))?;
708 }
709 }
710 }
711
712 Ok(())
713}
714
715fn opus_multistream_packet_validate(
716 data: &[u8],
717 len: usize,
718 nb_streams: usize,
719 sample_rate: i32,
720) -> Result<usize, OpusMultistreamDecoderError> {
721 if len > data.len() || nb_streams == 0 || sample_rate <= 0 {
722 return Err(OpusMultistreamDecoderError::BadArgument);
723 }
724
725 let mut remaining = len;
726 let mut cursor = data;
727 let mut samples: Option<usize> = None;
728
729 for stream in 0..nb_streams {
730 if remaining == 0 {
731 return Err(OpusMultistreamDecoderError::InvalidPacket);
732 }
733
734 let parsed = opus_packet_parse_impl(cursor, remaining, stream + 1 != nb_streams)?;
735 let tmp_samples =
736 opus_packet_get_nb_samples(cursor, parsed.packet_offset, sample_rate as u32)?;
737 if let Some(prev) = samples {
738 if prev != tmp_samples {
739 return Err(OpusMultistreamDecoderError::InvalidPacket);
740 }
741 } else {
742 samples = Some(tmp_samples);
743 }
744
745 cursor = &cursor[parsed.packet_offset..];
746 remaining = remaining
747 .checked_sub(parsed.packet_offset)
748 .ok_or(OpusMultistreamDecoderError::InvalidPacket)?;
749 }
750
751 samples.ok_or(OpusMultistreamDecoderError::InvalidPacket)
752}
753
754#[cfg(feature = "fixed_point")]
755const OPTIONAL_CLIP: bool = false;
756#[cfg(not(feature = "fixed_point"))]
757const OPTIONAL_CLIP: bool = true;
758
759fn opus_multistream_decode_native<T: PcmSample>(
760 decoder: &mut OpusMultistreamDecoder<'_>,
761 data: &[u8],
762 len: usize,
763 pcm: &mut [T],
764 frame_size: usize,
765 decode_fec: bool,
766 soft_clip: bool,
767) -> Result<usize, OpusMultistreamDecoderError> {
768 opus_multistream_decode_native_with_handler(
769 decoder,
770 data,
771 len,
772 pcm,
773 frame_size,
774 decode_fec,
775 soft_clip,
776 |dst, dst_stride, dst_channel, src, frame_size, src_offset| {
777 copy_channel_out(dst, dst_stride, dst_channel, src, frame_size, src_offset);
778 },
779 )
780}
781
782#[allow(clippy::too_many_arguments)]
783pub(crate) fn opus_multistream_decode_native_with_handler<T>(
784 decoder: &mut OpusMultistreamDecoder<'_>,
785 data: &[u8],
786 len: usize,
787 pcm: &mut [T],
788 mut frame_size: usize,
789 decode_fec: bool,
790 soft_clip: bool,
791 mut handler: impl FnMut(&mut [T], usize, usize, Option<(&[OpusRes], usize)>, usize, usize),
792) -> Result<usize, OpusMultistreamDecoderError> {
793 if frame_size == 0 {
794 return Err(OpusMultistreamDecoderError::BadArgument);
795 }
796
797 if len > data.len() {
798 return Err(OpusMultistreamDecoderError::BadArgument);
799 }
800
801 let nb_streams = decoder.layout.nb_streams;
802 if nb_streams == 0 {
803 return Err(OpusMultistreamDecoderError::BadArgument);
804 }
805
806 let sample_rate = decoder
807 .sample_rate()
808 .ok_or(OpusMultistreamDecoderError::InternalError)?;
809
810 let max_frame = sample_rate as usize / 25 * 3;
811 frame_size = frame_size.min(max_frame);
812
813 let required = frame_size
814 .checked_mul(decoder.layout.nb_channels)
815 .ok_or(OpusMultistreamDecoderError::BadArgument)?;
816 if pcm.len() < required {
817 return Err(OpusMultistreamDecoderError::BufferTooSmall);
818 }
819
820 let do_plc = len == 0;
821 if !do_plc {
822 let minimum = nb_streams
823 .checked_mul(2)
824 .and_then(|value| value.checked_sub(1))
825 .ok_or(OpusMultistreamDecoderError::BadArgument)?;
826 if len < minimum {
827 return Err(OpusMultistreamDecoderError::InvalidPacket);
828 }
829
830 let samples = opus_multistream_packet_validate(data, len, nb_streams, sample_rate)?;
831 if samples > frame_size {
832 return Err(OpusMultistreamDecoderError::BufferTooSmall);
833 }
834 }
835
836 let mut scratch = vec![OpusRes::default(); 2 * frame_size];
837 let mut cursor = data;
838 let mut remaining = len;
839 let mut decoded_frame_size = frame_size;
840
841 for stream in 0..nb_streams {
842 let self_delimited = stream + 1 != nb_streams;
843
844 let decoder_state = decoder
845 .decoders
846 .get_mut(stream)
847 .ok_or(OpusMultistreamDecoderError::InternalError)?;
848
849 let mut packet_offset = 0usize;
850 let decoded = if do_plc {
851 opus_decode_native(
852 decoder_state,
853 None,
854 0,
855 &mut scratch,
856 decoded_frame_size,
857 decode_fec,
858 self_delimited,
859 None,
860 soft_clip,
861 )?
862 } else {
863 if remaining == 0 {
864 return Err(OpusMultistreamDecoderError::InternalError);
865 }
866 opus_decode_native(
867 decoder_state,
868 Some(cursor),
869 remaining,
870 &mut scratch,
871 decoded_frame_size,
872 decode_fec,
873 self_delimited,
874 Some(&mut packet_offset),
875 soft_clip,
876 )?
877 };
878
879 if !do_plc {
880 if packet_offset > remaining {
881 return Err(OpusMultistreamDecoderError::InvalidPacket);
882 }
883 cursor = &cursor[packet_offset..];
884 remaining -= packet_offset;
885 }
886
887 if decoded == 0 {
888 return Err(OpusMultistreamDecoderError::InternalError);
889 }
890 decoded_frame_size = decoded;
891
892 if stream < decoder.layout.nb_coupled_streams {
893 let mut prev = None;
894 while let Some(chan) = get_left_channel(&decoder.layout, stream, prev) {
895 handler(
896 pcm,
897 decoder.layout.nb_channels,
898 chan,
899 Some((&scratch[..], 2)),
900 decoded_frame_size,
901 0,
902 );
903 prev = Some(chan);
904 }
905
906 let mut prev = None;
907 while let Some(chan) = get_right_channel(&decoder.layout, stream, prev) {
908 handler(
909 pcm,
910 decoder.layout.nb_channels,
911 chan,
912 Some((&scratch[1..], 2)),
913 decoded_frame_size,
914 0,
915 );
916 prev = Some(chan);
917 }
918 } else {
919 let mut prev = None;
920 while let Some(chan) = get_mono_channel(&decoder.layout, stream, prev) {
921 handler(
922 pcm,
923 decoder.layout.nb_channels,
924 chan,
925 Some((&scratch[..], 1)),
926 decoded_frame_size,
927 0,
928 );
929 prev = Some(chan);
930 }
931 }
932 }
933
934 for channel in 0..decoder.layout.nb_channels {
936 if decoder.layout.mapping[channel] == u8::MAX {
937 handler(
938 pcm,
939 decoder.layout.nb_channels,
940 channel,
941 None,
942 decoded_frame_size,
943 0,
944 );
945 }
946 }
947
948 Ok(decoded_frame_size)
949}
950
951pub fn opus_multistream_decode(
952 decoder: &mut OpusMultistreamDecoder<'_>,
953 data: &[u8],
954 len: usize,
955 pcm: &mut [i16],
956 frame_size: usize,
957 decode_fec: bool,
958) -> Result<usize, OpusMultistreamDecoderError> {
959 opus_multistream_decode_native(
960 decoder,
961 data,
962 len,
963 pcm,
964 frame_size,
965 decode_fec,
966 OPTIONAL_CLIP,
967 )
968}
969
970pub fn opus_multistream_decode24(
971 decoder: &mut OpusMultistreamDecoder<'_>,
972 data: &[u8],
973 len: usize,
974 pcm: &mut [i32],
975 frame_size: usize,
976 decode_fec: bool,
977) -> Result<usize, OpusMultistreamDecoderError> {
978 opus_multistream_decode_native(decoder, data, len, pcm, frame_size, decode_fec, false)
979}
980
981pub fn opus_multistream_decode_float(
982 decoder: &mut OpusMultistreamDecoder<'_>,
983 data: &[u8],
984 len: usize,
985 pcm: &mut [f32],
986 frame_size: usize,
987 decode_fec: bool,
988) -> Result<usize, OpusMultistreamDecoderError> {
989 opus_multistream_decode_native(decoder, data, len, pcm, frame_size, decode_fec, false)
990}
991
992trait PcmSample: Copy + Default {
993 fn from_opus_res(value: OpusRes) -> Self;
994}
995
996#[inline]
997fn res_to_int24(sample: OpusRes) -> i32 {
998 let scale = CELT_SIG_SCALE * 256.0;
999 let scaled = (sample * scale).clamp(-8_388_608.0, 8_388_607.0);
1000 float2int(scaled)
1001}
1002
1003impl PcmSample for i16 {
1004 #[inline]
1005 fn from_opus_res(value: OpusRes) -> Self {
1006 float2int16(value)
1007 }
1008}
1009
1010impl PcmSample for i32 {
1011 #[inline]
1012 fn from_opus_res(value: OpusRes) -> Self {
1013 res_to_int24(value)
1014 }
1015}
1016
1017impl PcmSample for f32 {
1018 #[inline]
1019 fn from_opus_res(value: OpusRes) -> Self {
1020 value
1021 }
1022}
1023
1024fn copy_channel_out<T: PcmSample>(
1025 dst: &mut [T],
1026 dst_stride: usize,
1027 dst_channel: usize,
1028 src: Option<(&[OpusRes], usize)>,
1029 frame_size: usize,
1030 src_offset: usize,
1031) {
1032 if dst_stride == 0 || frame_size == 0 {
1033 return;
1034 }
1035 for i in 0..frame_size {
1036 let dst_index = i * dst_stride + dst_channel;
1037 if dst_index >= dst.len() {
1038 break;
1039 }
1040 dst[dst_index] = match src {
1041 Some((src_data, src_stride)) => {
1042 let src_index = src_offset + i * src_stride;
1043 let value = src_data.get(src_index).copied().unwrap_or_default();
1044 T::from_opus_res(value)
1045 }
1046 None => T::default(),
1047 };
1048 }
1049}
1050
1051#[derive(Debug, Clone, PartialEq, Eq)]
1053pub enum OpusMultistreamEncoderError {
1054 BadArgument,
1055 BufferTooSmall,
1056 InternalError,
1057 Unimplemented,
1058 EncoderInit(OpusEncoderInitError),
1059 EncoderCtl(OpusEncoderCtlError),
1060 Encode(OpusEncodeError),
1061}
1062
1063impl OpusMultistreamEncoderError {
1064 #[inline]
1065 pub const fn code(&self) -> i32 {
1066 match self {
1067 Self::BadArgument => -1,
1068 Self::BufferTooSmall => -2,
1069 Self::InternalError => -3,
1070 Self::Unimplemented => -5,
1071 Self::EncoderInit(err) => err.code(),
1072 Self::EncoderCtl(err) => err.code(),
1073 Self::Encode(err) => err.code(),
1074 }
1075 }
1076}
1077
1078impl From<OpusEncoderInitError> for OpusMultistreamEncoderError {
1079 #[inline]
1080 fn from(value: OpusEncoderInitError) -> Self {
1081 Self::EncoderInit(value)
1082 }
1083}
1084
1085impl From<OpusEncoderCtlError> for OpusMultistreamEncoderError {
1086 #[inline]
1087 fn from(value: OpusEncoderCtlError) -> Self {
1088 Self::EncoderCtl(value)
1089 }
1090}
1091
1092impl From<OpusEncodeError> for OpusMultistreamEncoderError {
1093 #[inline]
1094 fn from(value: OpusEncodeError) -> Self {
1095 match value {
1096 OpusEncodeError::BadArgument => Self::BadArgument,
1097 OpusEncodeError::BufferTooSmall => Self::BufferTooSmall,
1098 OpusEncodeError::InternalError => Self::InternalError,
1099 OpusEncodeError::Unimplemented => Self::Unimplemented,
1100 OpusEncodeError::Silk(_) => Self::Encode(value),
1101 }
1102 }
1103}
1104
1105#[derive(Debug)]
1107pub struct OpusMultistreamEncoder<'mode> {
1108 layout: ChannelLayout,
1109 encoders: Vec<OpusEncoder<'mode>>,
1110 mapping_type: MappingType,
1111 lfe_stream: Option<usize>,
1112 sample_rate: i32,
1113 application: i32,
1114 bitrate_bps: i32,
1115 variable_duration: i32,
1116}
1117
1118#[derive(Debug, Clone, Copy, Default)]
1119pub struct OpusMultistreamEncodeOptions<'a> {
1120 pub stream_energy_masks: Option<&'a [Option<&'a [f32]>]>,
1121}
1122
1123impl<'mode> OpusMultistreamEncoder<'mode> {
1124 #[inline]
1125 pub fn layout(&self) -> &ChannelLayout {
1126 &self.layout
1127 }
1128
1129 pub fn init(
1131 &mut self,
1132 sample_rate: i32,
1133 channels: usize,
1134 streams: usize,
1135 coupled_streams: usize,
1136 mapping: &[u8],
1137 application: i32,
1138 ) -> Result<(), OpusMultistreamEncoderError> {
1139 let layout = build_encoder_layout(channels, streams, coupled_streams, mapping)?;
1140 let encoders = build_stream_encoders(sample_rate, streams, coupled_streams, application)?;
1141
1142 self.layout = layout;
1143 self.encoders = encoders;
1144 self.mapping_type = MappingType::None;
1145 self.lfe_stream = None;
1146 self.sample_rate = sample_rate;
1147 self.application = application;
1148 self.bitrate_bps = OPUS_AUTO;
1149 self.variable_duration = OPUS_FRAMESIZE_ARG;
1150 Ok(())
1151 }
1152
1153 pub fn encoder_state(&mut self, stream_id: usize) -> Option<&mut OpusEncoder<'mode>> {
1156 self.encoders.get_mut(stream_id)
1157 }
1158}
1159
1160pub fn opus_multistream_encoder_get_encoder_state<'a, 'mode>(
1163 encoder: &'a mut OpusMultistreamEncoder<'mode>,
1164 stream_id: usize,
1165) -> Result<&'a mut OpusEncoder<'mode>, OpusMultistreamEncoderError> {
1166 encoder
1167 .encoders
1168 .get_mut(stream_id)
1169 .ok_or(OpusMultistreamEncoderError::BadArgument)
1170}
1171
1172#[must_use]
1174pub fn opus_multistream_encoder_get_size(
1175 nb_streams: usize,
1176 nb_coupled_streams: usize,
1177) -> Option<usize> {
1178 if nb_streams == 0 || nb_coupled_streams > nb_streams {
1179 return None;
1180 }
1181
1182 let coupled_size = opus_encoder_get_size(2)?;
1183 let mono_size = opus_encoder_get_size(1)?;
1184 let header_size = align(core::mem::size_of::<OpusMsEncoderLayout>());
1185
1186 let coupled_total = nb_coupled_streams.checked_mul(align(coupled_size))?;
1187 let mono_total = nb_streams
1188 .checked_sub(nb_coupled_streams)?
1189 .checked_mul(align(mono_size))?;
1190
1191 header_size
1192 .checked_add(coupled_total)?
1193 .checked_add(mono_total)
1194}
1195
1196pub fn opus_multistream_encoder_create(
1199 sample_rate: i32,
1200 channels: usize,
1201 streams: usize,
1202 coupled_streams: usize,
1203 mapping: &[u8],
1204 application: i32,
1205) -> Result<OpusMultistreamEncoder<'static>, OpusMultistreamEncoderError> {
1206 let layout = build_encoder_layout(channels, streams, coupled_streams, mapping)?;
1207 let encoders = build_stream_encoders(sample_rate, streams, coupled_streams, application)?;
1208
1209 Ok(OpusMultistreamEncoder {
1210 layout,
1211 encoders,
1212 mapping_type: MappingType::None,
1213 lfe_stream: None,
1214 sample_rate,
1215 application,
1216 bitrate_bps: OPUS_AUTO,
1217 variable_duration: OPUS_FRAMESIZE_ARG,
1218 })
1219}
1220
1221fn build_encoder_layout(
1222 channels: usize,
1223 streams: usize,
1224 coupled_streams: usize,
1225 mapping: &[u8],
1226) -> Result<ChannelLayout, OpusMultistreamEncoderError> {
1227 let layout =
1228 build_layout(channels, streams, coupled_streams, mapping).map_err(|err| match err {
1229 OpusMultistreamDecoderError::BadArgument => OpusMultistreamEncoderError::BadArgument,
1230 _ => OpusMultistreamEncoderError::InternalError,
1231 })?;
1232 if streams
1233 .checked_add(coupled_streams)
1234 .is_none_or(|total| total > channels)
1235 {
1236 return Err(OpusMultistreamEncoderError::BadArgument);
1237 }
1238 if !validate_encoder_layout(&layout) {
1239 return Err(OpusMultistreamEncoderError::BadArgument);
1240 }
1241 Ok(layout)
1242}
1243
1244fn build_stream_encoders(
1245 sample_rate: i32,
1246 streams: usize,
1247 coupled_streams: usize,
1248 application: i32,
1249) -> Result<Vec<OpusEncoder<'static>>, OpusMultistreamEncoderError> {
1250 if sample_rate <= 0 {
1251 return Err(OpusMultistreamEncoderError::BadArgument);
1252 }
1253 let mut encoders = Vec::with_capacity(streams);
1254 for stream in 0..streams {
1255 let channels: i32 = if stream < coupled_streams { 2 } else { 1 };
1256 encoders.push(opus_encoder_create(sample_rate, channels, application)?);
1257 }
1258 Ok(encoders)
1259}
1260
1261pub enum OpusMultistreamEncoderCtlRequest<'req> {
1263 SetApplication(i32),
1264 GetApplication(&'req mut i32),
1265 SetBitrate(i32),
1266 GetBitrate(&'req mut i32),
1267 SetForceChannels(i32),
1268 GetForceChannels(&'req mut i32),
1269 SetMaxBandwidth(i32),
1270 GetMaxBandwidth(&'req mut i32),
1271 SetBandwidth(i32),
1272 GetBandwidth(&'req mut i32),
1273 SetVbr(bool),
1274 GetVbr(&'req mut bool),
1275 SetVbrConstraint(bool),
1276 GetVbrConstraint(&'req mut bool),
1277 SetComplexity(i32),
1278 GetComplexity(&'req mut i32),
1279 SetSignal(i32),
1280 GetSignal(&'req mut i32),
1281 GetVoiceRatio(&'req mut i32),
1282 SetPacketLossPerc(i32),
1283 GetPacketLossPerc(&'req mut i32),
1284 SetInbandFec(bool),
1285 GetInbandFec(&'req mut bool),
1286 SetDtx(bool),
1287 GetDtx(&'req mut bool),
1288 GetInDtx(&'req mut bool),
1289 SetLsbDepth(i32),
1290 GetLsbDepth(&'req mut i32),
1291 SetExpertFrameDuration(i32),
1292 GetExpertFrameDuration(&'req mut i32),
1293 SetPredictionDisabled(bool),
1294 GetPredictionDisabled(&'req mut bool),
1295 SetPhaseInversionDisabled(bool),
1296 GetPhaseInversionDisabled(&'req mut bool),
1297 SetDredDuration(i32),
1298 GetDredDuration(&'req mut i32),
1299 SetDnnBlob(&'req [u8]),
1300 SetForceMode(i32),
1301 GetSampleRate(&'req mut i32),
1302 GetLookahead(&'req mut i32),
1303 GetFinalRange(&'req mut u32),
1304 ResetState,
1305}
1306
1307pub fn opus_multistream_encoder_ctl<'req>(
1309 encoder: &mut OpusMultistreamEncoder<'_>,
1310 request: OpusMultistreamEncoderCtlRequest<'req>,
1311) -> Result<(), OpusMultistreamEncoderError> {
1312 if encoder.encoders.is_empty() {
1313 return Err(OpusMultistreamEncoderError::InternalError);
1314 }
1315
1316 match request {
1317 OpusMultistreamEncoderCtlRequest::SetApplication(value) => {
1318 for enc in &mut encoder.encoders {
1319 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetApplication(value)).map_err(
1320 |err| match err {
1321 OpusEncoderCtlError::BadArgument => {
1322 OpusMultistreamEncoderError::BadArgument
1323 }
1324 _ => OpusMultistreamEncoderError::EncoderCtl(err),
1325 },
1326 )?;
1327 }
1328 encoder.application = value;
1329 }
1330 OpusMultistreamEncoderCtlRequest::GetApplication(out) => {
1331 opus_encoder_ctl(
1332 encoder
1333 .encoders
1334 .first_mut()
1335 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1336 OpusEncoderCtlRequest::GetApplication(out),
1337 )?;
1338 }
1339 OpusMultistreamEncoderCtlRequest::SetBitrate(value) => {
1340 if value != OPUS_AUTO && value != OPUS_BITRATE_MAX && value <= 0 {
1341 return Err(OpusMultistreamEncoderError::BadArgument);
1342 }
1343 let clamped = if value == OPUS_AUTO || value == OPUS_BITRATE_MAX {
1344 value
1345 } else {
1346 let channels = i32::try_from(encoder.layout.nb_channels)
1347 .map_err(|_| OpusMultistreamEncoderError::BadArgument)?;
1348 let min_rate = 500i32.saturating_mul(channels);
1349 let max_rate = 300_000i32.saturating_mul(channels);
1350 value.clamp(min_rate, max_rate)
1351 };
1352 encoder.bitrate_bps = clamped;
1353 }
1354 OpusMultistreamEncoderCtlRequest::GetBitrate(out) => {
1355 let mut total = 0i64;
1356 for enc in &mut encoder.encoders {
1357 let mut rate = 0i32;
1358 opus_encoder_ctl(enc, OpusEncoderCtlRequest::GetBitrate(&mut rate))?;
1359 total += i64::from(rate);
1360 }
1361 *out = i32::try_from(total).map_err(|_| OpusMultistreamEncoderError::InternalError)?;
1362 }
1363 OpusMultistreamEncoderCtlRequest::SetForceChannels(value) => {
1364 for enc in &mut encoder.encoders {
1365 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetForceChannels(value))?;
1366 }
1367 }
1368 OpusMultistreamEncoderCtlRequest::GetForceChannels(out) => {
1369 opus_encoder_ctl(
1370 encoder
1371 .encoders
1372 .first_mut()
1373 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1374 OpusEncoderCtlRequest::GetForceChannels(out),
1375 )?;
1376 }
1377 OpusMultistreamEncoderCtlRequest::SetMaxBandwidth(value) => {
1378 for enc in &mut encoder.encoders {
1379 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetMaxBandwidth(value))?;
1380 }
1381 }
1382 OpusMultistreamEncoderCtlRequest::GetMaxBandwidth(out) => {
1383 opus_encoder_ctl(
1384 encoder
1385 .encoders
1386 .first_mut()
1387 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1388 OpusEncoderCtlRequest::GetMaxBandwidth(out),
1389 )?;
1390 }
1391 OpusMultistreamEncoderCtlRequest::SetBandwidth(value) => {
1392 for enc in &mut encoder.encoders {
1393 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetBandwidth(value))?;
1394 }
1395 }
1396 OpusMultistreamEncoderCtlRequest::GetBandwidth(out) => {
1397 opus_encoder_ctl(
1398 encoder
1399 .encoders
1400 .first_mut()
1401 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1402 OpusEncoderCtlRequest::GetBandwidth(out),
1403 )?;
1404 }
1405 OpusMultistreamEncoderCtlRequest::SetVbr(value) => {
1406 for enc in &mut encoder.encoders {
1407 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetVbr(value))?;
1408 }
1409 }
1410 OpusMultistreamEncoderCtlRequest::GetVbr(out) => {
1411 opus_encoder_ctl(
1412 encoder
1413 .encoders
1414 .first_mut()
1415 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1416 OpusEncoderCtlRequest::GetVbr(out),
1417 )?;
1418 }
1419 OpusMultistreamEncoderCtlRequest::SetVbrConstraint(value) => {
1420 for enc in &mut encoder.encoders {
1421 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetVbrConstraint(value))?;
1422 }
1423 }
1424 OpusMultistreamEncoderCtlRequest::GetVbrConstraint(out) => {
1425 opus_encoder_ctl(
1426 encoder
1427 .encoders
1428 .first_mut()
1429 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1430 OpusEncoderCtlRequest::GetVbrConstraint(out),
1431 )?;
1432 }
1433 OpusMultistreamEncoderCtlRequest::SetComplexity(value) => {
1434 for enc in &mut encoder.encoders {
1435 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetComplexity(value))?;
1436 }
1437 }
1438 OpusMultistreamEncoderCtlRequest::GetComplexity(out) => {
1439 opus_encoder_ctl(
1440 encoder
1441 .encoders
1442 .first_mut()
1443 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1444 OpusEncoderCtlRequest::GetComplexity(out),
1445 )?;
1446 }
1447 OpusMultistreamEncoderCtlRequest::SetSignal(value) => {
1448 for enc in &mut encoder.encoders {
1449 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetSignal(value))?;
1450 }
1451 }
1452 OpusMultistreamEncoderCtlRequest::GetSignal(out) => {
1453 opus_encoder_ctl(
1454 encoder
1455 .encoders
1456 .first_mut()
1457 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1458 OpusEncoderCtlRequest::GetSignal(out),
1459 )?;
1460 }
1461 OpusMultistreamEncoderCtlRequest::GetVoiceRatio(out) => {
1462 opus_encoder_ctl(
1463 encoder
1464 .encoders
1465 .first_mut()
1466 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1467 OpusEncoderCtlRequest::GetVoiceRatio(out),
1468 )?;
1469 }
1470 OpusMultistreamEncoderCtlRequest::SetPacketLossPerc(value) => {
1471 for enc in &mut encoder.encoders {
1472 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetPacketLossPerc(value))?;
1473 }
1474 }
1475 OpusMultistreamEncoderCtlRequest::GetPacketLossPerc(out) => {
1476 opus_encoder_ctl(
1477 encoder
1478 .encoders
1479 .first_mut()
1480 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1481 OpusEncoderCtlRequest::GetPacketLossPerc(out),
1482 )?;
1483 }
1484 OpusMultistreamEncoderCtlRequest::SetInbandFec(value) => {
1485 for enc in &mut encoder.encoders {
1486 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetInbandFec(value))?;
1487 }
1488 }
1489 OpusMultistreamEncoderCtlRequest::GetInbandFec(out) => {
1490 opus_encoder_ctl(
1491 encoder
1492 .encoders
1493 .first_mut()
1494 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1495 OpusEncoderCtlRequest::GetInbandFec(out),
1496 )?;
1497 }
1498 OpusMultistreamEncoderCtlRequest::SetDtx(value) => {
1499 for enc in &mut encoder.encoders {
1500 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetDtx(value))?;
1501 }
1502 }
1503 OpusMultistreamEncoderCtlRequest::GetDtx(out) => {
1504 opus_encoder_ctl(
1505 encoder
1506 .encoders
1507 .first_mut()
1508 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1509 OpusEncoderCtlRequest::GetDtx(out),
1510 )?;
1511 }
1512 OpusMultistreamEncoderCtlRequest::GetInDtx(out) => {
1513 opus_encoder_ctl(
1514 encoder
1515 .encoders
1516 .first_mut()
1517 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1518 OpusEncoderCtlRequest::GetInDtx(out),
1519 )?;
1520 }
1521 OpusMultistreamEncoderCtlRequest::SetLsbDepth(value) => {
1522 for enc in &mut encoder.encoders {
1523 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetLsbDepth(value))?;
1524 }
1525 }
1526 OpusMultistreamEncoderCtlRequest::GetLsbDepth(out) => {
1527 opus_encoder_ctl(
1528 encoder
1529 .encoders
1530 .first_mut()
1531 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1532 OpusEncoderCtlRequest::GetLsbDepth(out),
1533 )?;
1534 }
1535 OpusMultistreamEncoderCtlRequest::SetExpertFrameDuration(value) => {
1536 encoder.variable_duration = value;
1537 }
1538 OpusMultistreamEncoderCtlRequest::GetExpertFrameDuration(out) => {
1539 *out = encoder.variable_duration;
1540 }
1541 OpusMultistreamEncoderCtlRequest::SetPredictionDisabled(value) => {
1542 for enc in &mut encoder.encoders {
1543 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetPredictionDisabled(value))?;
1544 }
1545 }
1546 OpusMultistreamEncoderCtlRequest::GetPredictionDisabled(out) => {
1547 opus_encoder_ctl(
1548 encoder
1549 .encoders
1550 .first_mut()
1551 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1552 OpusEncoderCtlRequest::GetPredictionDisabled(out),
1553 )?;
1554 }
1555 OpusMultistreamEncoderCtlRequest::SetPhaseInversionDisabled(value) => {
1556 for enc in &mut encoder.encoders {
1557 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetPhaseInversionDisabled(value))?;
1558 }
1559 }
1560 OpusMultistreamEncoderCtlRequest::GetPhaseInversionDisabled(out) => {
1561 opus_encoder_ctl(
1562 encoder
1563 .encoders
1564 .first_mut()
1565 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1566 OpusEncoderCtlRequest::GetPhaseInversionDisabled(out),
1567 )?;
1568 }
1569 OpusMultistreamEncoderCtlRequest::SetDredDuration(value) => {
1570 for enc in &mut encoder.encoders {
1571 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetDredDuration(value))?;
1572 }
1573 }
1574 OpusMultistreamEncoderCtlRequest::GetDredDuration(out) => {
1575 opus_encoder_ctl(
1576 encoder
1577 .encoders
1578 .first_mut()
1579 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1580 OpusEncoderCtlRequest::GetDredDuration(out),
1581 )?;
1582 }
1583 OpusMultistreamEncoderCtlRequest::SetDnnBlob(data) => {
1584 for enc in &mut encoder.encoders {
1585 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetDnnBlob(data))?;
1586 }
1587 }
1588 OpusMultistreamEncoderCtlRequest::SetForceMode(value) => {
1589 for enc in &mut encoder.encoders {
1590 opus_encoder_ctl(enc, OpusEncoderCtlRequest::SetForceMode(value))?;
1591 }
1592 }
1593 OpusMultistreamEncoderCtlRequest::GetSampleRate(out) => {
1594 opus_encoder_ctl(
1595 encoder
1596 .encoders
1597 .first_mut()
1598 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1599 OpusEncoderCtlRequest::GetSampleRate(out),
1600 )?;
1601 }
1602 OpusMultistreamEncoderCtlRequest::GetLookahead(out) => {
1603 opus_encoder_ctl(
1604 encoder
1605 .encoders
1606 .first_mut()
1607 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1608 OpusEncoderCtlRequest::GetLookahead(out),
1609 )?;
1610 }
1611 OpusMultistreamEncoderCtlRequest::GetFinalRange(out) => {
1612 let mut acc = 0u32;
1613 for enc in &mut encoder.encoders {
1614 let mut value = 0u32;
1615 opus_encoder_ctl(enc, OpusEncoderCtlRequest::GetFinalRange(&mut value))?;
1616 acc ^= value;
1617 }
1618 *out = acc;
1619 }
1620 OpusMultistreamEncoderCtlRequest::ResetState => {
1621 for enc in &mut encoder.encoders {
1622 opus_encoder_ctl(enc, OpusEncoderCtlRequest::ResetState)?;
1623 }
1624 }
1625 }
1626
1627 Ok(())
1628}
1629
1630fn encode_size(size: usize, data: &mut [u8]) -> Option<usize> {
1631 if data.is_empty() {
1632 return None;
1633 }
1634 if size < 252 {
1635 data[0] = size as u8;
1636 Some(1)
1637 } else {
1638 if data.len() < 2 {
1639 return None;
1640 }
1641 data[0] = 252 + (size & 0x3) as u8;
1642 data[1] = ((size - usize::from(data[0])) >> 2) as u8;
1643 Some(2)
1644 }
1645}
1646
1647fn extract_i16_channel(
1648 input: &[i16],
1649 input_channels: usize,
1650 channel: usize,
1651 frame_size: usize,
1652 output: &mut [i16],
1653 output_stride: usize,
1654 output_offset: usize,
1655) -> Result<(), OpusMultistreamEncoderError> {
1656 for i in 0..frame_size {
1657 let src = i
1658 .checked_mul(input_channels)
1659 .and_then(|base| base.checked_add(channel))
1660 .ok_or(OpusMultistreamEncoderError::BadArgument)?;
1661 let dst = output_offset
1662 .checked_add(
1663 i.checked_mul(output_stride)
1664 .ok_or(OpusMultistreamEncoderError::BadArgument)?,
1665 )
1666 .ok_or(OpusMultistreamEncoderError::BadArgument)?;
1667 output[dst] = *input
1668 .get(src)
1669 .ok_or(OpusMultistreamEncoderError::BadArgument)?;
1670 }
1671 Ok(())
1672}
1673
1674pub fn opus_multistream_encode_with_options(
1675 encoder: &mut OpusMultistreamEncoder<'_>,
1676 pcm: &[i16],
1677 frame_size: usize,
1678 data: &mut [u8],
1679 options: OpusMultistreamEncodeOptions<'_>,
1680) -> Result<usize, OpusMultistreamEncoderError> {
1681 let channels = encoder.layout.nb_channels;
1682 if channels == 0 || frame_size == 0 {
1683 return Err(OpusMultistreamEncoderError::BadArgument);
1684 }
1685 let required_pcm = channels
1686 .checked_mul(frame_size)
1687 .ok_or(OpusMultistreamEncoderError::BadArgument)?;
1688 if pcm.len() < required_pcm {
1689 return Err(OpusMultistreamEncoderError::BadArgument);
1690 }
1691
1692 let nb_streams = encoder.layout.nb_streams;
1693 if nb_streams == 0 {
1694 return Err(OpusMultistreamEncoderError::BadArgument);
1695 }
1696 if let Some(masks) = options.stream_energy_masks
1697 && masks.len() != nb_streams
1698 {
1699 return Err(OpusMultistreamEncoderError::BadArgument);
1700 }
1701
1702 let smallest_packet = nb_streams
1703 .checked_mul(2)
1704 .and_then(|value| value.checked_sub(1))
1705 .ok_or(OpusMultistreamEncoderError::BadArgument)?;
1706 if data.len() < smallest_packet {
1707 return Err(OpusMultistreamEncoderError::BufferTooSmall);
1708 }
1709
1710 let mut rates = vec![0i32; nb_streams];
1711 let _ = rate_allocation(
1712 &encoder.layout,
1713 encoder.mapping_type,
1714 encoder.bitrate_bps,
1715 encoder.lfe_stream,
1716 frame_size,
1717 encoder.sample_rate,
1718 &mut rates,
1719 );
1720
1721 let mut total_written = 0usize;
1722 for stream in 0..nb_streams {
1723 let self_delimited = stream + 1 != nb_streams;
1724 let remaining_streams = nb_streams - stream - 1;
1725 let reserve_min = remaining_streams
1726 .checked_mul(2)
1727 .and_then(|value| value.checked_sub(1))
1728 .unwrap_or(0);
1729 let available = data
1730 .len()
1731 .checked_sub(total_written)
1732 .and_then(|value| value.checked_sub(reserve_min))
1733 .ok_or(OpusMultistreamEncoderError::BufferTooSmall)?;
1734
1735 let size_overhead = if self_delimited { 2 } else { 0 };
1737 if available <= size_overhead + 1 {
1738 return Err(OpusMultistreamEncoderError::BufferTooSmall);
1739 }
1740 let mut tmp = vec![0u8; available - size_overhead];
1741
1742 if let Some(rate) = rates.get(stream).copied() {
1743 let _ = opus_encoder_ctl(
1744 encoder
1745 .encoders
1746 .get_mut(stream)
1747 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1748 OpusEncoderCtlRequest::SetBitrate(rate),
1749 );
1750 }
1751 let encode_options = OpusEncodeOptions {
1752 energy_masking: options
1753 .stream_energy_masks
1754 .and_then(|masks| masks.get(stream))
1755 .copied()
1756 .flatten(),
1757 };
1758
1759 if stream < encoder.layout.nb_coupled_streams {
1760 let left = get_left_channel(&encoder.layout, stream, None)
1761 .ok_or(OpusMultistreamEncoderError::BadArgument)?;
1762 let right = get_right_channel(&encoder.layout, stream, None)
1763 .ok_or(OpusMultistreamEncoderError::BadArgument)?;
1764
1765 let mut coupled_pcm = vec![0i16; frame_size * 2];
1766 extract_i16_channel(pcm, channels, left, frame_size, &mut coupled_pcm, 2, 0)?;
1767 extract_i16_channel(pcm, channels, right, frame_size, &mut coupled_pcm, 2, 1)?;
1768
1769 let len = opus_encode_with_options(
1770 encoder
1771 .encoders
1772 .get_mut(stream)
1773 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1774 &coupled_pcm,
1775 frame_size,
1776 &mut tmp,
1777 encode_options,
1778 )?;
1779
1780 let written =
1781 write_stream_packet(&tmp[..len], self_delimited, &mut data[total_written..])
1782 .ok_or(OpusMultistreamEncoderError::BufferTooSmall)?;
1783 total_written += written;
1784 } else {
1785 let chan = get_mono_channel(&encoder.layout, stream, None)
1786 .ok_or(OpusMultistreamEncoderError::BadArgument)?;
1787 let mut mono_pcm = vec![0i16; frame_size];
1788 extract_i16_channel(pcm, channels, chan, frame_size, &mut mono_pcm, 1, 0)?;
1789
1790 let len = opus_encode_with_options(
1791 encoder
1792 .encoders
1793 .get_mut(stream)
1794 .ok_or(OpusMultistreamEncoderError::InternalError)?,
1795 &mono_pcm,
1796 frame_size,
1797 &mut tmp,
1798 encode_options,
1799 )?;
1800
1801 let written =
1802 write_stream_packet(&tmp[..len], self_delimited, &mut data[total_written..])
1803 .ok_or(OpusMultistreamEncoderError::BufferTooSmall)?;
1804 total_written += written;
1805 }
1806 }
1807
1808 Ok(total_written)
1809}
1810
1811pub fn opus_multistream_encode(
1812 encoder: &mut OpusMultistreamEncoder<'_>,
1813 pcm: &[i16],
1814 frame_size: usize,
1815 data: &mut [u8],
1816) -> Result<usize, OpusMultistreamEncoderError> {
1817 opus_multistream_encode_with_options(
1818 encoder,
1819 pcm,
1820 frame_size,
1821 data,
1822 OpusMultistreamEncodeOptions::default(),
1823 )
1824}
1825
1826fn write_stream_packet(
1827 stream_packet: &[u8],
1828 self_delimited: bool,
1829 out: &mut [u8],
1830) -> Option<usize> {
1831 if !self_delimited {
1832 if out.len() < stream_packet.len() {
1833 return None;
1834 }
1835 out[..stream_packet.len()].copy_from_slice(stream_packet);
1836 return Some(stream_packet.len());
1837 }
1838 if stream_packet.is_empty() {
1839 return None;
1840 }
1841 let toc = stream_packet[0];
1842 let frame = &stream_packet[1..];
1843 if out.is_empty() {
1844 return None;
1845 }
1846 out[0] = toc;
1847 let size_bytes = encode_size(frame.len(), &mut out[1..])?;
1848 let start = 1 + size_bytes;
1849 if out.len() < start + frame.len() {
1850 return None;
1851 }
1852 out[start..start + frame.len()].copy_from_slice(frame);
1853 Some(start + frame.len())
1854}
1855
1856pub fn opus_multistream_encode_float_with_options(
1857 encoder: &mut OpusMultistreamEncoder<'_>,
1858 pcm: &[f32],
1859 frame_size: usize,
1860 data: &mut [u8],
1861 options: OpusMultistreamEncodeOptions<'_>,
1862) -> Result<usize, OpusMultistreamEncoderError> {
1863 let channels = encoder.layout.nb_channels;
1864 let required_pcm = channels
1865 .checked_mul(frame_size)
1866 .ok_or(OpusMultistreamEncoderError::BadArgument)?;
1867 if pcm.len() < required_pcm {
1868 return Err(OpusMultistreamEncoderError::BadArgument);
1869 }
1870 let mut tmp = vec![0i16; required_pcm];
1871 for (dst, &sample) in tmp.iter_mut().zip(pcm.iter().take(required_pcm)) {
1872 let scaled = libm::roundf(sample * 32_768.0);
1873 *dst = scaled.clamp(f32::from(i16::MIN), f32::from(i16::MAX)) as i16;
1874 }
1875 opus_multistream_encode_with_options(encoder, &tmp, frame_size, data, options)
1876}
1877
1878pub fn opus_multistream_encode_float(
1879 encoder: &mut OpusMultistreamEncoder<'_>,
1880 pcm: &[f32],
1881 frame_size: usize,
1882 data: &mut [u8],
1883) -> Result<usize, OpusMultistreamEncoderError> {
1884 opus_multistream_encode_float_with_options(
1885 encoder,
1886 pcm,
1887 frame_size,
1888 data,
1889 OpusMultistreamEncodeOptions::default(),
1890 )
1891}
1892
1893pub fn opus_multistream_encode24_with_options(
1894 encoder: &mut OpusMultistreamEncoder<'_>,
1895 pcm: &[i32],
1896 frame_size: usize,
1897 data: &mut [u8],
1898 options: OpusMultistreamEncodeOptions<'_>,
1899) -> Result<usize, OpusMultistreamEncoderError> {
1900 let channels = encoder.layout.nb_channels;
1901 let required_pcm = channels
1902 .checked_mul(frame_size)
1903 .ok_or(OpusMultistreamEncoderError::BadArgument)?;
1904 if pcm.len() < required_pcm {
1905 return Err(OpusMultistreamEncoderError::BadArgument);
1906 }
1907 let mut tmp = vec![0i16; required_pcm];
1908 for (dst, &sample) in tmp.iter_mut().zip(pcm.iter().take(required_pcm)) {
1909 let shifted = (sample >> 8).clamp(i32::from(i16::MIN), i32::from(i16::MAX));
1910 *dst = shifted as i16;
1911 }
1912 opus_multistream_encode_with_options(encoder, &tmp, frame_size, data, options)
1913}
1914
1915pub fn opus_multistream_encode24(
1916 encoder: &mut OpusMultistreamEncoder<'_>,
1917 pcm: &[i32],
1918 frame_size: usize,
1919 data: &mut [u8],
1920) -> Result<usize, OpusMultistreamEncoderError> {
1921 opus_multistream_encode24_with_options(
1922 encoder,
1923 pcm,
1924 frame_size,
1925 data,
1926 OpusMultistreamEncodeOptions::default(),
1927 )
1928}
1929
1930#[derive(Debug, Clone, PartialEq, Eq)]
1931pub struct OpusMultistreamSurroundLayout {
1932 pub streams: usize,
1933 pub coupled_streams: usize,
1934 pub mapping: Vec<u8>,
1935}
1936
1937pub fn opus_multistream_surround_encoder_get_size(
1938 channels: usize,
1939 mapping_family: u8,
1940) -> Option<usize> {
1941 let (streams, coupled_streams, _) = surround_layout(channels, mapping_family).ok()?;
1942 let mut size = opus_multistream_encoder_get_size(streams, coupled_streams)?;
1943 if channels > 2 {
1944 size = size.checked_add(
1945 channels.checked_mul(
1946 120usize
1947 .checked_mul(core::mem::size_of::<crate::celt::OpusVal32>())?
1948 .checked_add(core::mem::size_of::<crate::celt::OpusVal32>())?,
1949 )?,
1950 )?;
1951 }
1952 Some(size)
1953}
1954
1955pub fn opus_multistream_surround_encoder_create(
1956 sample_rate: i32,
1957 channels: usize,
1958 mapping_family: u8,
1959 application: i32,
1960) -> Result<
1961 (
1962 OpusMultistreamEncoder<'static>,
1963 OpusMultistreamSurroundLayout,
1964 ),
1965 OpusMultistreamEncoderError,
1966> {
1967 let (streams, coupled_streams, mapping) = surround_layout(channels, mapping_family)?;
1968 let mut encoder = opus_multistream_encoder_create(
1969 sample_rate,
1970 channels,
1971 streams,
1972 coupled_streams,
1973 &mapping,
1974 application,
1975 )?;
1976
1977 let (mapping_type, lfe_stream) = surround_mapping_type(channels, mapping_family, streams);
1978 encoder.mapping_type = mapping_type;
1979 encoder.lfe_stream = lfe_stream;
1980
1981 Ok((
1982 encoder,
1983 OpusMultistreamSurroundLayout {
1984 streams,
1985 coupled_streams,
1986 mapping,
1987 },
1988 ))
1989}
1990
1991pub fn opus_multistream_surround_encoder_init(
1992 encoder: &mut OpusMultistreamEncoder<'_>,
1993 sample_rate: i32,
1994 channels: usize,
1995 mapping_family: u8,
1996 application: i32,
1997) -> Result<OpusMultistreamSurroundLayout, OpusMultistreamEncoderError> {
1998 let (streams, coupled_streams, mapping) = surround_layout(channels, mapping_family)?;
1999 encoder.init(
2000 sample_rate,
2001 channels,
2002 streams,
2003 coupled_streams,
2004 &mapping,
2005 application,
2006 )?;
2007
2008 let (mapping_type, lfe_stream) = surround_mapping_type(channels, mapping_family, streams);
2009 encoder.mapping_type = mapping_type;
2010 encoder.lfe_stream = lfe_stream;
2011
2012 Ok(OpusMultistreamSurroundLayout {
2013 streams,
2014 coupled_streams,
2015 mapping,
2016 })
2017}
2018
2019fn surround_mapping_type(
2020 channels: usize,
2021 mapping_family: u8,
2022 streams: usize,
2023) -> (MappingType, Option<usize>) {
2024 match mapping_family {
2025 1 if channels > 2 => (
2026 MappingType::Surround,
2027 if channels >= 6 {
2028 streams.checked_sub(1)
2029 } else {
2030 None
2031 },
2032 ),
2033 2 => (MappingType::Ambisonics, None),
2034 _ => (MappingType::None, None),
2035 }
2036}
2037
2038fn surround_layout(
2039 channels: usize,
2040 mapping_family: u8,
2041) -> Result<(usize, usize, Vec<u8>), OpusMultistreamEncoderError> {
2042 if channels == 0 || channels > 255 {
2043 return Err(OpusMultistreamEncoderError::BadArgument);
2044 }
2045
2046 let mut mapping = Vec::with_capacity(channels);
2047 match mapping_family {
2048 0 => match channels {
2049 1 => {
2050 mapping.push(0);
2051 Ok((1, 0, mapping))
2052 }
2053 2 => {
2054 mapping.extend_from_slice(&[0, 1]);
2055 Ok((1, 1, mapping))
2056 }
2057 _ => Err(OpusMultistreamEncoderError::Unimplemented),
2058 },
2059 1 => {
2060 if !(1..=8).contains(&channels) {
2061 return Err(OpusMultistreamEncoderError::Unimplemented);
2062 }
2063 let layout = &VORBIS_MAPPINGS[channels - 1];
2064 mapping.extend_from_slice(&layout.mapping[..channels]);
2065 Ok((layout.nb_streams, layout.nb_coupled_streams, mapping))
2066 }
2067 255 => {
2068 mapping.extend((0..channels).map(|v| v as u8));
2069 Ok((channels, 0, mapping))
2070 }
2071 2 => {
2072 let (streams, coupled_streams) =
2073 validate_ambisonics(channels).ok_or(OpusMultistreamEncoderError::BadArgument)?;
2074 let uncoupled_streams = streams - coupled_streams;
2075 for i in 0..uncoupled_streams {
2076 mapping.push((i + coupled_streams * 2) as u8);
2077 }
2078 for i in 0..coupled_streams * 2 {
2079 mapping.push(i as u8);
2080 }
2081 Ok((streams, coupled_streams, mapping))
2082 }
2083 _ => Err(OpusMultistreamEncoderError::Unimplemented),
2084 }
2085}
2086
2087#[cfg(test)]
2088mod tests {
2089 use super::*;
2090 use crate::opus_decoder::{opus_decode, opus_decoder_create};
2091 use crate::opus_encoder::opus_encode;
2092 use alloc::vec;
2093
2094 fn layout_from_mapping(
2095 nb_channels: usize,
2096 nb_streams: usize,
2097 nb_coupled_streams: usize,
2098 mapping_slice: &[u8],
2099 ) -> ChannelLayout {
2100 let mut mapping = [u8::MAX; 256];
2101 let count = mapping_slice.len().min(mapping.len());
2102 mapping[..count].copy_from_slice(&mapping_slice[..count]);
2103 ChannelLayout {
2104 nb_channels,
2105 nb_streams,
2106 nb_coupled_streams,
2107 mapping,
2108 }
2109 }
2110
2111 #[test]
2112 fn accepts_valid_layout() {
2113 let layout = layout_from_mapping(3, 2, 1, &[0, 1, 2]);
2114 assert!(validate_layout(&layout));
2115 }
2116
2117 #[test]
2118 fn rejects_out_of_range_stream_indices() {
2119 let layout = layout_from_mapping(1, 1, 0, &[1]);
2120 assert!(!validate_layout(&layout));
2121 }
2122
2123 #[test]
2124 fn rejects_when_stream_count_exceeds_byte_limit() {
2125 let layout = layout_from_mapping(2, 200, 60, &[0, 1]);
2126 assert!(!validate_layout(&layout));
2127 }
2128
2129 #[test]
2130 fn iterates_all_channels_for_a_stream() {
2131 let layout = layout_from_mapping(4, 3, 1, &[0, 0, 1, 2]);
2132
2133 assert_eq!(get_left_channel(&layout, 0, None), Some(0));
2134 assert_eq!(get_left_channel(&layout, 0, Some(0)), Some(1));
2135 assert_eq!(get_left_channel(&layout, 0, Some(1)), None);
2136
2137 assert_eq!(get_right_channel(&layout, 0, None), Some(2));
2138 assert_eq!(get_right_channel(&layout, 0, Some(2)), None);
2139
2140 assert_eq!(get_mono_channel(&layout, 1, None), Some(3));
2141 assert_eq!(get_mono_channel(&layout, 1, Some(3)), None);
2142 }
2143
2144 #[test]
2145 fn validate_encoder_layout_rejects_missing_channel() {
2146 let layout = layout_from_mapping(2, 1, 1, &[0, u8::MAX]);
2147 assert!(!validate_encoder_layout(&layout));
2148 }
2149
2150 #[test]
2151 fn validate_encoder_layout_accepts_complete_mapping() {
2152 let layout = layout_from_mapping(2, 1, 1, &[0, 1]);
2153 assert!(validate_encoder_layout(&layout));
2154 }
2155
2156 #[test]
2157 fn validate_ambisonics_computes_stream_and_coupling_counts() {
2158 assert_eq!(validate_ambisonics(1), Some((1, 0)));
2159 assert_eq!(validate_ambisonics(6), Some((5, 1)));
2160 assert_eq!(validate_ambisonics(7), None);
2161 assert_eq!(validate_ambisonics(228), None);
2162 }
2163
2164 #[test]
2165 fn rate_allocation_handles_stereo_surround_defaults() {
2166 let layout = layout_from_mapping(2, 1, 1, &[0, 1]);
2167 let mut rates = [0; 1];
2168
2169 let sum = rate_allocation(
2170 &layout,
2171 MappingType::Surround,
2172 OPUS_AUTO,
2173 None,
2174 960,
2175 48_000,
2176 &mut rates,
2177 )
2178 .expect("allocation");
2179
2180 assert_eq!(sum, 120_000);
2181 assert_eq!(rates, [120_000]);
2182 }
2183
2184 #[test]
2185 fn rate_allocation_accounts_for_lfe_stream() {
2186 let layout = layout_from_mapping(6, 4, 2, &[0, 4, 1, 2, 3, 5]);
2187 let mut rates = [0; 4];
2188
2189 let sum = rate_allocation(
2190 &layout,
2191 MappingType::Surround,
2192 256_000,
2193 Some(3),
2194 960,
2195 48_000,
2196 &mut rates,
2197 )
2198 .expect("allocation");
2199
2200 assert_eq!(sum, 255_995);
2201 assert_eq!(rates, [95_120, 95_120, 57_560, 8_195]);
2202 }
2203
2204 #[test]
2205 fn rate_allocation_splits_evenly_for_ambisonics() {
2206 let layout = layout_from_mapping(4, 4, 0, &[0, 1, 2, 3]);
2207 let mut rates = [0; 4];
2208
2209 let sum = rate_allocation(
2210 &layout,
2211 MappingType::Ambisonics,
2212 OPUS_AUTO,
2213 None,
2214 960,
2215 48_000,
2216 &mut rates,
2217 )
2218 .expect("allocation");
2219
2220 assert_eq!(sum, 264_000);
2221 assert_eq!(rates, [66_000; 4]);
2222 }
2223
2224 #[test]
2225 fn rate_allocation_rejects_insufficient_rate_storage() {
2226 let layout = layout_from_mapping(2, 1, 1, &[0, 1]);
2227 let mut rates: [i32; 0] = [];
2228
2229 assert!(
2230 rate_allocation(
2231 &layout,
2232 MappingType::Surround,
2233 64_000,
2234 None,
2235 960,
2236 48_000,
2237 &mut rates
2238 )
2239 .is_none()
2240 );
2241 }
2242
2243 #[test]
2244 fn multistream_decoder_size_matches_aligned_components() {
2245 let coupled = opus_decoder_get_size(2).expect("coupled size");
2246 let mono = opus_decoder_get_size(1).expect("mono size");
2247 let expected =
2248 align(core::mem::size_of::<OpusMsDecoderLayout>()) + align(coupled) + align(mono);
2249 let reported = opus_multistream_decoder_get_size(2, 1).expect("reported size");
2250
2251 assert_eq!(reported, expected);
2252 assert!(opus_multistream_decoder_get_size(0, 0).is_none());
2253 assert!(opus_multistream_decoder_get_size(2, 3).is_none());
2254 }
2255
2256 #[test]
2257 fn multistream_decoder_creation_validates_arguments() {
2258 let mapping = [0u8, 1];
2259 let err = opus_multistream_decoder_create(48_000, 0, 1, 0, &mapping).unwrap_err();
2260 assert_eq!(err, OpusMultistreamDecoderError::BadArgument);
2261
2262 let short_map = [0u8];
2263 let err = opus_multistream_decoder_create(48_000, 2, 1, 1, &short_map).unwrap_err();
2264 assert_eq!(err, OpusMultistreamDecoderError::BadArgument);
2265 }
2266
2267 #[test]
2268 fn multistream_decoder_ctl_round_trips_gain_and_complexity() {
2269 let mapping = [0u8, 1];
2270 let mut decoder =
2271 opus_multistream_decoder_create(48_000, 2, 1, 1, &mapping).expect("decoder");
2272
2273 opus_multistream_decoder_ctl(&mut decoder, OpusMultistreamDecoderCtlRequest::SetGain(-12))
2274 .unwrap();
2275
2276 let mut gain = 0;
2277 opus_multistream_decoder_ctl(
2278 &mut decoder,
2279 OpusMultistreamDecoderCtlRequest::GetGain(&mut gain),
2280 )
2281 .unwrap();
2282 assert_eq!(gain, -12);
2283
2284 opus_multistream_decoder_ctl(
2285 &mut decoder,
2286 OpusMultistreamDecoderCtlRequest::SetComplexity(5),
2287 )
2288 .unwrap();
2289 let mut complexity = 0;
2290 opus_multistream_decoder_ctl(
2291 &mut decoder,
2292 OpusMultistreamDecoderCtlRequest::GetComplexity(&mut complexity),
2293 )
2294 .unwrap();
2295 assert_eq!(complexity, 5);
2296
2297 let mut fs = 0;
2298 opus_multistream_decoder_ctl(
2299 &mut decoder,
2300 OpusMultistreamDecoderCtlRequest::GetSampleRate(&mut fs),
2301 )
2302 .unwrap();
2303 assert_eq!(fs, 48_000);
2304
2305 let err = opus_multistream_decoder_ctl(
2306 &mut decoder,
2307 OpusMultistreamDecoderCtlRequest::SetComplexity(11),
2308 )
2309 .unwrap_err();
2310 assert_eq!(
2311 err,
2312 OpusMultistreamDecoderError::DecoderCtl(OpusDecoderCtlError::BadArgument)
2313 );
2314 }
2315
2316 #[test]
2317 fn packet_validation_accepts_self_delimited_streams() {
2318 let packet = [0x00, 0x01, 0xAA, 0x00, 0xBB];
2320 let samples =
2321 opus_multistream_packet_validate(&packet, packet.len(), 2, 48_000).expect("packet");
2322 assert_eq!(samples, 480);
2323 }
2324
2325 #[test]
2326 fn packet_validation_rejects_mismatched_sample_counts() {
2327 let packet = [0x00, 0x01, 0xAA, 0x18, 0xBB];
2329 let err = opus_multistream_packet_validate(&packet, packet.len(), 2, 48_000).unwrap_err();
2330 assert_eq!(err, OpusMultistreamDecoderError::InvalidPacket);
2331 }
2332
2333 #[test]
2334 fn decode_returns_unimplemented_after_validation() {
2335 let mapping = [0u8, 1];
2336 let mut decoder =
2337 opus_multistream_decoder_create(48_000, 2, 1, 1, &mapping).expect("decoder");
2338 let packet = [0x00, 0xAA];
2339 let mut pcm = vec![0i16; 2 * 960];
2340
2341 let decoded =
2342 opus_multistream_decode(&mut decoder, &packet, packet.len(), &mut pcm, 960, false)
2343 .expect("decode");
2344 assert!(decoded > 0);
2345 }
2346
2347 #[test]
2348 fn multistream_decode_matches_single_stream_decoder_for_stereo() {
2349 let mapping = [0u8, 1];
2350 let mut encoder = opus_encoder_create(48_000, 2, 2048).expect("encoder");
2351 let pcm_in = vec![0i16; 2 * 960];
2352 let mut packet = vec![0u8; 1500];
2353 let len = opus_encode(&mut encoder, &pcm_in, 960, &mut packet).expect("encode");
2354
2355 let mut ms_decoder =
2356 opus_multistream_decoder_create(48_000, 2, 1, 1, &mapping).expect("ms decoder");
2357 let mut single = opus_decoder_create(48_000, 2).expect("single decoder");
2358
2359 let mut ms_out = vec![0i16; 2 * 960];
2360 let mut single_out = vec![0i16; 2 * 960];
2361
2362 let ms_decoded =
2363 opus_multistream_decode(&mut ms_decoder, &packet, len, &mut ms_out, 960, false)
2364 .expect("ms decode");
2365 let single_decoded = opus_decode(
2366 &mut single,
2367 Some(&packet[..len]),
2368 len,
2369 &mut single_out,
2370 960,
2371 false,
2372 )
2373 .expect("single decode");
2374 assert_eq!(ms_decoded, single_decoded);
2375 assert_eq!(ms_out[..ms_decoded * 2], single_out[..single_decoded * 2]);
2376 }
2377
2378 #[test]
2379 fn multistream_decode_routes_two_coupled_streams() {
2380 let mapping = [0u8, 1, 2, 3];
2381 let mut ms_encoder =
2382 opus_multistream_encoder_create(48_000, 4, 2, 2, &mapping, 2048).expect("ms encoder");
2383 let pcm_in = vec![0i16; 4 * 960];
2384 let mut packet = vec![0u8; 4000];
2385 let len =
2386 opus_multistream_encode(&mut ms_encoder, &pcm_in, 960, &mut packet).expect("encode");
2387
2388 let mut ms_decoder =
2389 opus_multistream_decoder_create(48_000, 4, 2, 2, &mapping).expect("ms decoder");
2390
2391 let mut ms_out = vec![0i16; 4 * 960];
2392 let decoded =
2393 opus_multistream_decode(&mut ms_decoder, &packet, len, &mut ms_out, 960, false)
2394 .expect("ms decode");
2395 assert!(decoded > 0);
2396
2397 let mut offset = 0usize;
2398 let mut remaining = len;
2399 let mut expected = vec![0i16; 4 * decoded];
2400 for stream in 0..2 {
2401 let self_delimited = stream == 0;
2402 let parsed = opus_packet_parse_impl(&packet[offset..], remaining, self_delimited)
2403 .expect("parse");
2404 let packet_offset = parsed.packet_offset;
2405 let mut dec = opus_decoder_create(48_000, 2).expect("decoder");
2406 let mut stream_out = vec![0i16; 2 * decoded];
2407 let stream_packet = if self_delimited {
2408 let toc = packet[offset];
2409 let payload_start = offset + parsed.payload_offset;
2410 let payload_end = offset + parsed.packet_offset;
2411 let mut reconstructed = vec![0u8; 1 + (payload_end - payload_start)];
2412 reconstructed[0] = toc;
2413 reconstructed[1..].copy_from_slice(&packet[payload_start..payload_end]);
2414 reconstructed
2415 } else {
2416 packet[offset..offset + packet_offset].to_vec()
2417 };
2418
2419 let stream_decoded = opus_decode(
2420 &mut dec,
2421 Some(&stream_packet),
2422 stream_packet.len(),
2423 &mut stream_out,
2424 decoded,
2425 false,
2426 )
2427 .expect("decode");
2428 assert_eq!(stream_decoded, decoded);
2429
2430 for i in 0..decoded {
2431 expected[i * 4 + stream * 2] = stream_out[i * 2];
2432 expected[i * 4 + stream * 2 + 1] = stream_out[i * 2 + 1];
2433 }
2434
2435 offset += packet_offset;
2436 remaining -= packet_offset;
2437 }
2438
2439 assert_eq!(ms_out[..decoded * 4], expected[..decoded * 4]);
2440 }
2441
2442 #[test]
2443 fn multistream_decode_zero_fills_muted_channel() {
2444 let mapping = [0u8, 1, u8::MAX];
2445 let mut encoder = opus_encoder_create(48_000, 2, 2048).expect("encoder");
2446 let pcm_in = vec![0i16; 2 * 960];
2447 let mut packet = vec![0u8; 1500];
2448 let len = opus_encode(&mut encoder, &pcm_in, 960, &mut packet).expect("encode");
2449
2450 let mut ms_decoder =
2451 opus_multistream_decoder_create(48_000, 3, 1, 1, &mapping).expect("ms decoder");
2452 let mut out = vec![0i16; 3 * 960];
2453 let decoded = opus_multistream_decode(&mut ms_decoder, &packet, len, &mut out, 960, false)
2454 .expect("decode");
2455
2456 for i in 0..decoded {
2457 assert_eq!(out[i * 3 + 2], 0);
2458 }
2459 }
2460
2461 #[test]
2462 fn multistream_encode_respects_minimum_packet_size() {
2463 let mapping = [0u8, 1];
2464 let mut ms_encoder =
2465 opus_multistream_encoder_create(48_000, 2, 1, 1, &mapping, 2048).expect("ms encoder");
2466 let pcm_in = vec![0i16; 2 * 960];
2467 let mut packet = vec![0u8; 2];
2468 let err = opus_multistream_encode(&mut ms_encoder, &pcm_in, 960, &mut packet).unwrap_err();
2469 assert_eq!(err, OpusMultistreamEncoderError::BufferTooSmall);
2470 }
2471
2472 #[test]
2473 fn multistream_encoder_ctl_round_trips_lsb_and_prediction() {
2474 let mapping = [0u8, 1];
2475 let mut encoder =
2476 opus_multistream_encoder_create(48_000, 2, 2, 0, &mapping, 2048).expect("ms encoder");
2477
2478 let mut lsb = 0;
2479 opus_multistream_encoder_ctl(
2480 &mut encoder,
2481 OpusMultistreamEncoderCtlRequest::GetLsbDepth(&mut lsb),
2482 )
2483 .unwrap();
2484 assert!(lsb >= 16);
2485
2486 opus_multistream_encoder_ctl(
2487 &mut encoder,
2488 OpusMultistreamEncoderCtlRequest::SetLsbDepth(12),
2489 )
2490 .unwrap();
2491 let mut updated = 0;
2492 opus_multistream_encoder_ctl(
2493 &mut encoder,
2494 OpusMultistreamEncoderCtlRequest::GetLsbDepth(&mut updated),
2495 )
2496 .unwrap();
2497 assert_eq!(updated, 12);
2498
2499 let mut pred = false;
2500 opus_multistream_encoder_ctl(
2501 &mut encoder,
2502 OpusMultistreamEncoderCtlRequest::GetPredictionDisabled(&mut pred),
2503 )
2504 .unwrap();
2505 opus_multistream_encoder_ctl(
2506 &mut encoder,
2507 OpusMultistreamEncoderCtlRequest::SetPredictionDisabled(!pred),
2508 )
2509 .unwrap();
2510 let mut pred_after = false;
2511 opus_multistream_encoder_ctl(
2512 &mut encoder,
2513 OpusMultistreamEncoderCtlRequest::GetPredictionDisabled(&mut pred_after),
2514 )
2515 .unwrap();
2516 assert_eq!(pred_after, !pred);
2517
2518 {
2519 let stream =
2520 opus_multistream_encoder_get_encoder_state(&mut encoder, 1).expect("stream");
2521 let mut stream_lsb = 0;
2522 opus_encoder_ctl(stream, OpusEncoderCtlRequest::GetLsbDepth(&mut stream_lsb)).unwrap();
2523 assert_eq!(stream_lsb, 12);
2524 }
2525
2526 assert_eq!(
2527 opus_multistream_encoder_get_encoder_state(&mut encoder, 2).unwrap_err(),
2528 OpusMultistreamEncoderError::BadArgument
2529 );
2530 }
2531
2532 #[cfg(feature = "dred")]
2533 #[test]
2534 fn multistream_encoder_ctl_round_trips_dred_duration() {
2535 let mapping = [0u8, 1];
2536 let mut encoder =
2537 opus_multistream_encoder_create(48_000, 2, 2, 0, &mapping, 2048).expect("ms encoder");
2538
2539 opus_multistream_encoder_ctl(
2540 &mut encoder,
2541 OpusMultistreamEncoderCtlRequest::SetDredDuration(8),
2542 )
2543 .unwrap();
2544 let mut duration = 0;
2545 opus_multistream_encoder_ctl(
2546 &mut encoder,
2547 OpusMultistreamEncoderCtlRequest::GetDredDuration(&mut duration),
2548 )
2549 .unwrap();
2550 assert_eq!(duration, 8);
2551 }
2552
2553 #[test]
2554 fn surround_encoder_layout_matches_vorbis_mapping() {
2555 let (encoder, layout) =
2556 opus_multistream_surround_encoder_create(48_000, 6, 1, 2048).expect("encoder");
2557
2558 assert_eq!(layout.streams, 4);
2559 assert_eq!(layout.coupled_streams, 2);
2560 assert_eq!(layout.mapping, vec![0, 4, 1, 2, 3, 5]);
2561 assert_eq!(encoder.layout.nb_channels, 6);
2562 assert_eq!(encoder.layout.nb_streams, 4);
2563 assert_eq!(encoder.layout.nb_coupled_streams, 2);
2564
2565 assert_eq!(encoder.lfe_stream, Some(3));
2567 assert_eq!(encoder.mapping_type, MappingType::Surround);
2568 }
2569
2570 #[test]
2571 fn surround_encoder_ambisonics_layout_matches_reference_ordering() {
2572 let (_encoder, layout) =
2573 opus_multistream_surround_encoder_create(48_000, 6, 2, 2048).expect("encoder");
2574 assert_eq!(layout.streams, 5);
2575 assert_eq!(layout.coupled_streams, 1);
2576 assert_eq!(layout.mapping, vec![2, 3, 4, 5, 0, 1]);
2577 }
2578
2579 #[test]
2580 fn surround_encoder_get_size_matches_reference_overhead() {
2581 let size = opus_multistream_surround_encoder_get_size(6, 1).expect("size");
2582 let base = opus_multistream_encoder_get_size(4, 2).expect("base");
2583 let overhead = 6
2584 * (120 * core::mem::size_of::<crate::celt::OpusVal32>()
2585 + core::mem::size_of::<crate::celt::OpusVal32>());
2586 assert_eq!(size, base + overhead);
2587 }
2588}