1#![cfg_attr(not(feature = "std"), no_std)]
2#![allow(unsafe_op_in_unsafe_fn)]
3#![allow(clippy::too_many_arguments)]
4#![allow(clippy::needless_range_loop)]
5
6mod compat;
7mod fixedvec;
8
9pub mod bands;
10pub mod celt;
11pub mod celt_lpc;
12pub mod hp_cutoff;
13pub mod kiss_fft;
14pub mod mdct;
15pub mod modes;
16#[cfg(feature = "std")]
20pub mod multistream;
21pub mod pitch;
22pub mod pvq;
23pub mod quant_bands;
24pub mod range_coder;
25pub mod rate;
26pub mod silk;
27
28pub use silk::{SilkResampler, SilkResamplerDown1_3, SilkResamplerDown1_6};
29
30use crate::fixedvec::FixedVec;
31use core::mem::MaybeUninit;
32pub use celt::{CeltDecoder, CeltEncoder};
33use hp_cutoff::{dc_reject_float, hp_cutoff, hp_cutoff_float, hp_cutoff_i16};
34use range_coder::RangeCoder;
35use silk::control_codec::{silk_control_encoder, silk_setup_lbrr};
36use silk::enc_api::{
37 silk_encode, silk_encode_prefill, silk_encode_prefill_stereo, silk_encode_stereo_packet,
38};
39use silk::init_encoder::silk_init_encoder;
40use silk::lin2log::silk_lin2log;
41use silk::log2lin::silk_log2lin;
42use silk::macros::*;
43use silk::structs::SilkEncoderState;
44
45const OPUS_MAX_CHANNELS: usize = 2;
47const OPUS_MAX_FRAME: usize = 5760;
50const SILK_MAX_PACKET_SAMPLES: usize = 3 * silk::define::MAX_FRAME_LENGTH;
52const OPUS_MAX_SUBFRAME: usize = 2880;
56const OPUS_SUBFRAME_SCRATCH: usize = OPUS_MAX_SUBFRAME * OPUS_MAX_CHANNELS;
58const OPUS_HP_MEM: usize = OPUS_MAX_CHANNELS * 2;
60const OPUS_PCM_I16: usize = 960 * OPUS_MAX_CHANNELS;
62const OPUS_PCM_TAIL: usize = 240 * OPUS_MAX_CHANNELS;
64const OPUS_MAX_PACKET_FRAMES: usize = 48;
67const OPUS_MAX_PACKET_BYTES: usize = 1276;
69const OPUS_DELAY_BUF: usize = 480 * OPUS_MAX_CHANNELS;
72const OPUS_PCM_BUF: usize = (192 + OPUS_MAX_SUBFRAME) * OPUS_MAX_CHANNELS;
75
76#[derive(Debug, Clone, Copy, PartialEq, Eq)]
77pub enum Application {
78 Voip = 2048,
79 Audio = 2049,
80 RestrictedLowDelay = 2051,
81}
82
83#[derive(Debug, Clone, Copy, PartialEq, Eq)]
84pub enum Bandwidth {
85 Auto = -1000,
86 Narrowband = 1101,
87 Mediumband = 1102,
88 Wideband = 1103,
89 Superwideband = 1104,
90 Fullband = 1105,
91}
92
93#[derive(Debug, Clone, Copy, PartialEq, Eq)]
94enum OpusMode {
95 SilkOnly,
96 Hybrid,
97 CeltOnly,
98}
99
100pub struct OpusEncoder {
101 #[cfg(not(feature = "heap"))]
102 celt_enc: CeltEncoder,
103 #[cfg(feature = "heap")]
104 celt_enc: Box<CeltEncoder>,
105 #[cfg(not(feature = "heap"))]
108 silk_enc: SilkEncoderState,
109 #[cfg(feature = "heap")]
110 silk_enc: Box<SilkEncoderState>,
111 #[cfg(not(feature = "heap"))]
113 silk_enc_side: SilkEncoderState,
114 #[cfg(feature = "heap")]
115 silk_enc_side: Box<SilkEncoderState>,
116 application: Application,
117 sampling_rate: i32,
118 channels: usize,
119 bandwidth: Bandwidth,
120 pub bitrate_bps: i32,
121 pub complexity: i32,
122 pub use_cbr: bool,
123
124 pub use_inband_fec: bool,
125
126 pub packet_loss_perc: i32,
127 silk_initialized: bool,
128 mode: OpusMode,
129 prev_enc_mode: Option<OpusMode>,
130 forced_mode: Option<OpusMode>,
134
135 variable_hp_smth2_q15: i32,
136 hp_mem: FixedVec<i32, OPUS_HP_MEM>,
137
138 #[cfg(not(feature = "heap"))]
139 buf_filtered: FixedVec<i16, OPUS_MAX_FRAME>,
140 #[cfg(feature = "heap")]
141 buf_filtered: Box<FixedVec<i16, OPUS_MAX_FRAME>>,
142 #[cfg(not(feature = "heap"))]
143 buf_silk_input: FixedVec<i16, OPUS_MAX_FRAME>,
144 #[cfg(feature = "heap")]
145 buf_silk_input: Box<FixedVec<i16, OPUS_MAX_FRAME>>,
146 #[cfg(not(feature = "heap"))]
149 buf_silk_input_right: FixedVec<i16, SILK_MAX_PACKET_SAMPLES>,
150 #[cfg(feature = "heap")]
151 buf_silk_input_right: Box<FixedVec<i16, SILK_MAX_PACKET_SAMPLES>>,
152 #[cfg(not(feature = "heap"))]
155 buf_silk_api_channel: FixedVec<i16, OPUS_MAX_FRAME>,
156 #[cfg(feature = "heap")]
157 buf_silk_api_channel: Box<FixedVec<i16, OPUS_MAX_FRAME>>,
158 #[cfg(not(feature = "heap"))]
159 buf_celt_input: FixedVec<f32, OPUS_MAX_FRAME>,
160 #[cfg(feature = "heap")]
161 buf_celt_input: Box<FixedVec<f32, OPUS_MAX_FRAME>>,
162 #[cfg(not(feature = "heap"))]
165 delay_buffer: FixedVec<f32, OPUS_DELAY_BUF>,
166 #[cfg(feature = "heap")]
167 delay_buffer: Box<FixedVec<f32, OPUS_DELAY_BUF>>,
168 #[cfg(not(feature = "heap"))]
171 buf_celt_pcm: FixedVec<f32, OPUS_PCM_BUF>,
172 #[cfg(feature = "heap")]
173 buf_celt_pcm: Box<FixedVec<f32, OPUS_PCM_BUF>>,
174 #[cfg(not(feature = "heap"))]
177 buf_f32_frame: FixedVec<f32, OPUS_MAX_FRAME>,
178 #[cfg(feature = "heap")]
179 buf_f32_frame: Box<FixedVec<f32, OPUS_MAX_FRAME>>,
180 encoder_buffer: usize,
183 delay_compensation: usize,
186 hp_mem_float: [f32; 4],
189 silk_resampler_enc: silk::resampler::SilkResampler,
194 silk_resampler_enc_right: silk::resampler::SilkResampler,
197
198 rc: RangeCoder,
199}
200
201#[derive(Clone, Copy)]
205enum PcmInput<'a> {
206 F32(&'a [f32]),
207 I16(&'a [i16]),
208}
209
210impl PcmInput<'_> {
211 fn len(&self) -> usize {
212 match self {
213 PcmInput::F32(s) => s.len(),
214 PcmInput::I16(s) => s.len(),
215 }
216 }
217}
218
219fn compute_equiv_rate(
220 bitrate: i32,
221 channels: usize,
222 frame_rate: i32,
223 vbr: bool,
224 complexity: i32,
225 loss: i32,
226) -> i32 {
227 let mut equiv = bitrate;
228 if frame_rate > 50 {
229 equiv -= (40 * channels as i32 + 20) * (frame_rate - 50);
230 }
231 if !vbr {
232 equiv -= equiv / 12;
233 }
234 equiv = equiv * (90 + complexity) / 100;
235 if loss > 0 {
236 equiv -= equiv * loss / (12 * loss + 20);
237 }
238 equiv
239}
240
241const FEC_THRESHOLDS: [i32; 10] = [
244 12000, 1000, 14000, 1000, 16000, 1000, 20000, 1000, 22000, 1000, ];
250
251fn bandwidth_fec_index(bw: Bandwidth) -> usize {
252 match bw {
253 Bandwidth::Narrowband => 0,
254 Bandwidth::Mediumband => 1,
255 Bandwidth::Wideband => 2,
256 Bandwidth::Superwideband => 3,
257 Bandwidth::Fullband | Bandwidth::Auto => 4,
258 }
259}
260
261fn bandwidth_from_fec_index(idx: usize) -> Bandwidth {
262 match idx {
263 0 => Bandwidth::Narrowband,
264 1 => Bandwidth::Mediumband,
265 2 => Bandwidth::Wideband,
266 3 => Bandwidth::Superwideband,
267 _ => Bandwidth::Fullband,
268 }
269}
270
271fn decide_fec(
276 use_in_band_fec: i32,
277 packet_loss_perc: i32,
278 last_fec: i32,
279 mode: OpusMode,
280 bandwidth: &mut Bandwidth,
281 rate: i32,
282) -> i32 {
283 if use_in_band_fec == 0 || packet_loss_perc == 0 || mode == OpusMode::CeltOnly {
284 return 0;
285 }
286 let orig_bandwidth = *bandwidth;
287 loop {
288 let idx = bandwidth_fec_index(*bandwidth);
289 let mut lbrr_rate_thres_bps = FEC_THRESHOLDS[2 * idx];
290 let hysteresis = FEC_THRESHOLDS[2 * idx + 1];
291 if last_fec == 1 {
292 lbrr_rate_thres_bps -= hysteresis;
293 }
294 if last_fec == 0 {
295 lbrr_rate_thres_bps += hysteresis;
296 }
297 lbrr_rate_thres_bps = silk_smulwb(
299 lbrr_rate_thres_bps * (125 - packet_loss_perc.min(25)),
300 655,
301 );
302 if rate > lbrr_rate_thres_bps {
305 return 1;
306 } else if packet_loss_perc <= 5 {
307 return 0;
308 } else if bandwidth_fec_index(*bandwidth) > 0 {
309 let lower = bandwidth_fec_index(*bandwidth) - 1;
310 *bandwidth = bandwidth_from_fec_index(lower);
311 } else {
312 break;
313 }
314 }
315 *bandwidth = orig_bandwidth;
317 0
318}
319
320fn compute_mode_threshold(
321 application: Application,
322 channels: usize,
323 prev_was_celt: bool,
324 has_prev_mode: bool,
325 voice_est: i32,
326) -> i32 {
327 let mode_voice = if channels == 1 { 64000 } else { 44000 };
328 let mode_music = 10000;
329
330 let diff = mode_voice - mode_music;
331 let offset = (voice_est * voice_est * diff) >> 14;
332 let mut threshold = mode_music + offset;
333
334 if application == Application::Voip {
335 threshold += 8000;
336 }
337
338 if has_prev_mode {
339 if prev_was_celt {
340 threshold -= 4000;
341 } else {
342 threshold += 4000;
343 }
344 }
345
346 if application == Application::RestrictedLowDelay {
347 threshold = 0;
348 }
349
350 threshold
351}
352
353fn bits_to_bitrate(bits: i32, fs: i32, frame_size: usize) -> i32 {
356 (bits as i64 * (6 * fs as i64 / frame_size as i64) / 6) as i32
357}
358
359fn bitrate_to_bits(bitrate: i32, fs: i32, frame_size: usize) -> i32 {
361 (bitrate as i64 * 6 / (6 * fs as i64 / frame_size as i64)) as i32
362}
363
364fn compute_silk_rate_for_hybrid(rate_bps: i32, frame20ms: bool, channels: usize) -> i32 {
369 let channels = channels as i32;
370 let rate_bps = rate_bps / channels;
371 let silk_rate = silk_rate_for_hybrid_per_channel(rate_bps, frame20ms) * channels;
372 if channels == 2 && rate_bps >= 12000 {
374 silk_rate - 1000
375 } else {
376 silk_rate
377 }
378}
379
380fn silk_rate_for_hybrid_per_channel(rate_bps: i32, frame20ms: bool) -> i32 {
381 const RATE_TABLE: &[(i32, i32, i32)] = &[
382 (0, 0, 0),
383 (12000, 10000, 10000),
384 (16000, 13500, 13500),
385 (20000, 16000, 16000),
386 (24000, 18000, 18000),
387 (32000, 22000, 22000),
388 (64000, 38000, 38000),
389 ];
390 let n = RATE_TABLE.len();
391 let mut i = 1;
392 while i < n && RATE_TABLE[i].0 <= rate_bps {
393 i += 1;
394 }
395 if i == n {
396 let (x_last, r10_last, r20_last) = RATE_TABLE[n - 1];
397 let base = if frame20ms { r20_last } else { r10_last };
398 base + (rate_bps - x_last) / 2
399 } else {
400 let (x0, lo10, lo20) = RATE_TABLE[i - 1];
401 let (x1, hi10, hi20) = RATE_TABLE[i];
402 let (lo, hi) = if frame20ms {
403 (lo20, hi20)
404 } else {
405 (lo10, hi10)
406 };
407 (lo * (x1 - rate_bps) + hi * (rate_bps - x0)) / (x1 - x0)
408 }
409}
410
411#[cfg(all(test, feature = "std"))]
412mod silk_rate_tests {
413 use super::compute_silk_rate_for_hybrid;
414
415 #[test]
416 fn test_reference_table_exact_entries() {
417 assert_eq!(compute_silk_rate_for_hybrid(12000, true, 1), 10000);
418 assert_eq!(compute_silk_rate_for_hybrid(16000, true, 1), 13500);
419 assert_eq!(compute_silk_rate_for_hybrid(20000, true, 1), 16000);
420 assert_eq!(compute_silk_rate_for_hybrid(24000, true, 1), 18000);
421 assert_eq!(compute_silk_rate_for_hybrid(32000, true, 1), 22000);
422 assert_eq!(compute_silk_rate_for_hybrid(64000, true, 1), 38000);
423 }
424
425 #[test]
426 fn test_32kbps_gives_22kbps_silk() {
427 assert_eq!(compute_silk_rate_for_hybrid(32000, true, 1), 22000);
428 }
429
430 #[test]
431 fn test_interpolation_between_table_entries() {
432 let r = compute_silk_rate_for_hybrid(18000, true, 1);
433 assert_eq!(r, 14750);
434 }
435
436 #[test]
437 fn test_above_table_max_gives_half_extra() {
438 let r = compute_silk_rate_for_hybrid(72000, true, 1);
439 assert_eq!(r, 38000 + (72000 - 64000) / 2);
440 }
441
442 #[test]
445 fn test_stereo_allocates_per_channel() {
446 let stereo = |rate| compute_silk_rate_for_hybrid(rate, true, 2);
447 assert_eq!(stereo(32000), 2 * 13500 - 1000);
448 assert_eq!(stereo(24000), 2 * 10000 - 1000);
449 assert_eq!(stereo(20000), 2 * 8333);
450 assert_eq!(stereo(64000), 2 * 22000 - 1000);
451 }
452}
453
454#[cfg(feature = "heap")]
463#[inline(always)]
464fn state_ref<T: core::ops::Deref>(b: &T) -> &T::Target {
465 b
466}
467#[cfg(not(feature = "heap"))]
468#[inline(always)]
469fn state_ref<T: ?Sized>(b: &T) -> &T {
470 b
471}
472
473#[cfg(feature = "heap")]
474#[inline(always)]
475fn state_mut<T: core::ops::DerefMut>(b: &mut T) -> &mut T::Target {
476 b
477}
478#[cfg(not(feature = "heap"))]
479#[inline(always)]
480fn state_mut<T: ?Sized>(b: &mut T) -> &mut T {
481 b
482}
483
484impl OpusEncoder {
485 pub fn new(
486 sampling_rate: i32,
487 channels: usize,
488 application: Application,
489 ) -> Result<Self, &'static str> {
490 if ![8000, 12000, 16000, 24000, 48000].contains(&sampling_rate) {
491 return Err("Invalid sampling rate");
492 }
493 if ![1, 2].contains(&channels) {
494 return Err("Invalid number of channels");
495 }
496
497 let mode = modes::default_mode();
498 #[cfg(feature = "heap")]
499 let celt_enc = Box::new(CeltEncoder::with_sampling_rate(mode, channels, sampling_rate));
500 #[cfg(not(feature = "heap"))]
501 let celt_enc = CeltEncoder::with_sampling_rate(mode, channels, sampling_rate);
502
503 #[cfg(feature = "heap")]
504 let mut silk_enc = Box::new(SilkEncoderState::default());
505 #[cfg(not(feature = "heap"))]
506 let mut silk_enc = SilkEncoderState::default();
507 if silk_init_encoder(state_mut(&mut silk_enc), 0) != 0 {
508 return Err("SILK encoder initialization failed");
509 }
510 #[cfg(feature = "heap")]
511 let mut silk_enc_side = Box::new(SilkEncoderState::default());
512 #[cfg(not(feature = "heap"))]
513 let mut silk_enc_side = SilkEncoderState::default();
514 if silk_init_encoder(state_mut(&mut silk_enc_side), 0) != 0 {
515 return Err("SILK encoder initialization failed");
516 }
517
518 let (opus_mode, bw) = match application {
519 Application::Voip => {
520 let bw = match sampling_rate {
521 8000 => Bandwidth::Narrowband,
522 12000 => Bandwidth::Mediumband,
523 16000 => Bandwidth::Wideband,
524 24000 => Bandwidth::Superwideband,
525 48000 => Bandwidth::Fullband,
526 _ => Bandwidth::Narrowband,
527 };
528
529 let mode = if sampling_rate > 16000 {
530 OpusMode::Hybrid
531 } else {
532 OpusMode::SilkOnly
533 };
534 (mode, bw)
535 }
536 Application::RestrictedLowDelay => {
537 let bw = match sampling_rate {
538 8000 => Bandwidth::Narrowband,
539 12000 => Bandwidth::Mediumband,
540 16000 => Bandwidth::Wideband,
541 24000 => Bandwidth::Superwideband,
542 _ => Bandwidth::Fullband,
543 };
544 (OpusMode::CeltOnly, bw)
545 }
546 Application::Audio => {
547 if sampling_rate <= 16000 {
548 let bw = match sampling_rate {
549 8000 => Bandwidth::Narrowband,
550 12000 => Bandwidth::Mediumband,
551 _ => Bandwidth::Wideband,
552 };
553 (OpusMode::SilkOnly, bw)
554 } else {
555 let bw = match sampling_rate {
556 24000 => Bandwidth::Superwideband,
557 _ => Bandwidth::Fullband,
558 };
559 (OpusMode::Hybrid, bw)
560 }
561 }
562 };
563
564 use silk::lin2log::silk_lin2log;
565 let variable_hp_smth2_q15 = silk_lin2log(60) << 8;
566
567 Ok(Self {
568 celt_enc,
569 silk_enc,
570 silk_enc_side,
571 application,
572 sampling_rate,
573 channels,
574 bandwidth: bw,
575 bitrate_bps: 64000,
576 complexity: 9,
577 use_cbr: false,
578 use_inband_fec: false,
579 packet_loss_perc: 0,
580 silk_initialized: false,
581 prev_enc_mode: None,
582 forced_mode: None,
583 mode: opus_mode,
584 variable_hp_smth2_q15,
585 hp_mem: FixedVec::from_value(0, channels * 2),
586
587 #[cfg(not(feature = "heap"))]
588 buf_filtered: FixedVec::new(),
589 #[cfg(feature = "heap")]
590 buf_filtered: Box::new(FixedVec::new()),
591 #[cfg(not(feature = "heap"))]
592 buf_silk_input: FixedVec::new(),
593 #[cfg(feature = "heap")]
594 buf_silk_input: Box::new(FixedVec::new()),
595 #[cfg(not(feature = "heap"))]
596 buf_silk_input_right: FixedVec::new(),
597 #[cfg(feature = "heap")]
598 buf_silk_input_right: Box::new(FixedVec::new()),
599 #[cfg(not(feature = "heap"))]
600 buf_silk_api_channel: FixedVec::new(),
601 #[cfg(feature = "heap")]
602 buf_silk_api_channel: Box::new(FixedVec::new()),
603 #[cfg(not(feature = "heap"))]
604 buf_celt_input: FixedVec::new(),
605 #[cfg(feature = "heap")]
606 buf_celt_input: Box::new(FixedVec::new()),
607 #[cfg(not(feature = "heap"))]
608 delay_buffer: FixedVec::from_value(0.0, OPUS_DELAY_BUF),
609 #[cfg(feature = "heap")]
610 delay_buffer: Box::new(FixedVec::from_value(0.0, OPUS_DELAY_BUF)),
611 #[cfg(not(feature = "heap"))]
612 buf_celt_pcm: FixedVec::new(),
613 #[cfg(feature = "heap")]
614 buf_celt_pcm: Box::new(FixedVec::new()),
615 #[cfg(not(feature = "heap"))]
616 buf_f32_frame: FixedVec::new(),
617 #[cfg(feature = "heap")]
618 buf_f32_frame: Box::new(FixedVec::new()),
619 encoder_buffer: if matches!(application, Application::RestrictedLowDelay) {
620 0
621 } else {
622 (sampling_rate / 100) as usize
623 },
624 delay_compensation: if matches!(application, Application::RestrictedLowDelay) {
625 0
626 } else {
627 (sampling_rate / 250) as usize
628 },
629 hp_mem_float: [0.0; 4],
630 silk_resampler_enc: silk::resampler::SilkResampler::default(),
631 silk_resampler_enc_right: silk::resampler::SilkResampler::default(),
632 rc: RangeCoder::new_encoder(1),
633 })
634 }
635
636 pub fn enable_hybrid_mode(&mut self) -> Result<(), &'static str> {
637 if self.sampling_rate != 24000 && self.sampling_rate != 48000 {
638 return Err("Hybrid mode requires 24kHz or 48kHz sampling rate");
639 }
640 let bw = if self.sampling_rate == 48000 {
641 Bandwidth::Fullband
642 } else {
643 Bandwidth::Superwideband
644 };
645 self.mode = OpusMode::Hybrid;
646 self.bandwidth = bw;
647 self.silk_initialized = false;
648 Ok(())
649 }
650
651 pub fn encode(
655 &mut self,
656 input: &[f32],
657 frame_size: usize,
658 output: &mut [u8],
659 ) -> Result<usize, &'static str> {
660 self.encode_impl(PcmInput::F32(input), frame_size, output)
661 }
662
663 pub fn encode_i16(
670 &mut self,
671 input: &[i16],
672 frame_size: usize,
673 output: &mut [u8],
674 ) -> Result<usize, &'static str> {
675 self.encode_impl(PcmInput::I16(input), frame_size, output)
676 }
677
678 fn encode_impl(
679 &mut self,
680 input: PcmInput<'_>,
681 frame_size: usize,
682 output: &mut [u8],
683 ) -> Result<usize, &'static str> {
684 if output.len() < 2 {
685 return Err("Output buffer too small");
686 }
687
688 let frame_rate = frame_rate_from_params(self.sampling_rate, frame_size)
689 .ok_or("Invalid frame size for sampling rate")?;
690
691 self.bitrate_bps = self.bitrate_bps.clamp(500, 3_000_000);
697 self.complexity = self.complexity.clamp(0, 10);
698 self.packet_loss_perc = self.packet_loss_perc.clamp(0, 100);
699
700 if input.len() < frame_size * self.channels {
704 return Err("Input buffer too small for frame");
705 }
706
707 let mut mode = if let Some(forced) = self.forced_mode {
711 forced
712 } else if self.application == Application::RestrictedLowDelay {
713 OpusMode::CeltOnly
714 } else {
715 let equiv = compute_equiv_rate(
716 self.bitrate_bps,
717 self.channels,
718 frame_rate,
719 !self.use_cbr,
720 self.complexity,
721 self.packet_loss_perc,
722 );
723 let prev_was_celt = self.prev_enc_mode == Some(OpusMode::CeltOnly);
724 let has_prev_mode = self.prev_enc_mode.is_some();
725 let voice_est = match self.application {
726 Application::Voip => 115,
727 Application::Audio => 48,
728 Application::RestrictedLowDelay => 0,
729 };
730 let threshold = compute_mode_threshold(
731 self.application,
732 self.channels,
733 prev_was_celt,
734 has_prev_mode,
735 voice_est,
736 );
737 if equiv >= threshold && self.sampling_rate >= 24000 {
738 OpusMode::CeltOnly
739 } else {
740 OpusMode::SilkOnly
741 }
742 };
743
744 if self.forced_mode.is_none() {
745 let curr_bw = self.bandwidth;
746 if mode == OpusMode::SilkOnly
747 && (curr_bw == Bandwidth::Superwideband || curr_bw == Bandwidth::Fullband)
748 {
749 mode = OpusMode::Hybrid;
750 }
751 if mode == OpusMode::Hybrid
752 && (curr_bw == Bandwidth::Narrowband
753 || curr_bw == Bandwidth::Mediumband
754 || curr_bw == Bandwidth::Wideband)
755 {
756 mode = OpusMode::SilkOnly;
757 }
758 }
759
760 let target_bits =
763 (self.bitrate_bps as i64 * frame_size as i64 / self.sampling_rate as i64) as i32;
764 let cbr_bytes = ((target_bits + 4) / 8) as usize;
765 let max_data_bytes = output.len();
766
767 let mut n_bytes = if self.use_cbr {
772 cbr_bytes
773 .min(max_data_bytes)
774 .clamp(1, OPUS_MAX_PACKET_BYTES)
775 } else {
776 max_data_bytes.clamp(1, OPUS_MAX_PACKET_BYTES)
777 };
778
779 let tiny_budget_rate: i64 = if frame_rate > 50 { 9000 } else { 6000 };
784 if ((n_bytes as i64) * 8 * (self.sampling_rate as i64))
785 < (tiny_budget_rate * (frame_size as i64))
786 {
787 mode = OpusMode::CeltOnly;
788 }
789
790 if self.forced_mode.is_none()
795 && mode != OpusMode::SilkOnly
796 && frame_size > self.sampling_rate as usize / 50
797 {
798 return self.encode_multiframe(input, frame_size, mode, output);
799 }
800
801 let mut frame_bandwidth = self.bandwidth;
808 let equiv_rate = compute_equiv_rate(
809 self.bitrate_bps,
810 self.channels,
811 frame_rate,
812 !self.use_cbr,
813 self.complexity,
814 self.packet_loss_perc,
815 );
816 let lbrr_coded = decide_fec(
817 if self.use_inband_fec { 1 } else { 0 },
818 self.packet_loss_perc,
819 self.silk_enc.s_cmn.lbrr_enabled,
820 mode,
821 &mut frame_bandwidth,
822 equiv_rate,
823 );
824 if mode == OpusMode::CeltOnly {
825 self.silk_enc.s_cmn.lbrr_enabled = 0;
828 self.silk_enc_side.s_cmn.lbrr_enabled = 0;
829 }
830
831 if mode == OpusMode::CeltOnly {
832 match frame_rate {
833 400 | 200 | 100 | 50 => {}
834 _ => return Err("Unsupported frame size for CELT-only mode"),
835 }
836 }
837
838 if mode == OpusMode::Hybrid {
839 match frame_rate {
840 100 | 50 => {}
841 _ => return Err("Unsupported frame size for Hybrid mode"),
842 }
843 }
844
845 if mode == OpusMode::SilkOnly {
846 match frame_rate {
847 100 | 50 | 25 | 16 => {}
848 _ => return Err("Unsupported frame size for SILK-only mode"),
852 }
853 }
854
855 let toc = gen_toc(mode, frame_rate, frame_bandwidth, self.channels);
856 output[0] = toc;
857
858 let sub_3_bytes_per_frame =
864 (self.bitrate_bps as i64) < 3 * frame_rate as i64 * 8;
865 let tiny_long_frame =
866 frame_rate < 50
867 && (n_bytes * (frame_rate as usize) < 300 || self.bitrate_bps < 2400);
868 if n_bytes < 3 || sub_3_bytes_per_frame || tiny_long_frame {
869 let mut toc_mode = mode;
870 let mut packet_code = 0u8;
871 let mut num_multiframes = 0u8;
872 let mut frame_rate_adj = frame_rate;
873 if frame_rate > 100 {
874 toc_mode = OpusMode::CeltOnly;
875 }
876 if frame_rate == 25 && toc_mode != OpusMode::SilkOnly {
878 frame_rate_adj = 50;
879 packet_code = 1;
880 }
881 if frame_rate <= 16 {
883 if n_bytes == 1 || (toc_mode == OpusMode::SilkOnly && frame_rate != 10) {
884 toc_mode = OpusMode::SilkOnly;
885 packet_code = if frame_rate <= 12 { 1 } else { 0 };
886 frame_rate_adj = if frame_rate == 12 { 25 } else { 16 };
887 } else {
888 num_multiframes = (50 / frame_rate) as u8;
889 frame_rate_adj = 50;
890 packet_code = 3;
891 }
892 }
893 let mut plc_bw = frame_bandwidth;
894 if toc_mode == OpusMode::SilkOnly && bandwidth_fec_index(plc_bw) > 2 {
895 plc_bw = Bandwidth::Wideband;
897 }
898 output[0] = gen_toc(toc_mode, frame_rate_adj, plc_bw, self.channels) | packet_code;
899 let mut ret = if packet_code <= 1 { 1 } else { 2 };
900 if packet_code == 3 {
901 output[1] = num_multiframes;
902 }
903 if self.use_cbr {
904 let target_total = n_bytes.min(output.len());
905 if target_total >= 2 {
906 let m: usize = if packet_code == 3 {
909 num_multiframes as usize
910 } else if packet_code == 1 {
911 2
912 } else {
913 1
914 };
915 output[0] = (output[0] & 0xFC) | 0x03;
916 output[1] = 0x40 | m as u8; if target_total > 2 {
918 let pad_amount = target_total - 2;
919 let nb_255s = (pad_amount - 1) / 255;
920 let mut ptr = 2;
921 for _ in 0..nb_255s {
922 output[ptr] = 255;
923 ptr += 1;
924 }
925 output[ptr] = (pad_amount - 255 * nb_255s - 1) as u8;
926 ptr += 1;
927 for b in &mut output[ptr..target_total] {
928 *b = 0;
929 }
930 }
931 ret = target_total;
932 }
933 }
934 return Ok(ret);
936 }
937
938 let init_rc_size = n_bytes - 1;
939 self.rc.reset_for_encode(init_rc_size as u32);
940
941 let hp_freq_smth1 = if mode == OpusMode::CeltOnly {
946 silk_lin2log(60) << 8
947 } else {
948 self.silk_enc.s_cmn.variable_hp_smth1_q15
949 };
950
951 const VARIABLE_HP_SMTH_COEF2_Q16: i32 = 984;
952 self.variable_hp_smth2_q15 = silk_smlawb(
953 self.variable_hp_smth2_q15,
954 hp_freq_smth1 - self.variable_hp_smth2_q15,
955 VARIABLE_HP_SMTH_COEF2_Q16,
956 );
957
958 let cutoff_hz = silk_log2lin(silk_rshift(self.variable_hp_smth2_q15, 8));
959
960 if mode == OpusMode::SilkOnly || mode == OpusMode::Hybrid {
961 let silk_fs_khz = if mode == OpusMode::Hybrid {
962 16
963 } else {
964 self.sampling_rate.min(16000) / 1000
965 };
966
967 let frame_ms = (frame_size as i32 * 1000) / self.sampling_rate;
968
969 let rate_bps = if self.use_cbr {
976 bits_to_bitrate(8 * n_bytes as i32, self.sampling_rate, frame_size)
977 } else {
978 self.bitrate_bps
979 };
980 let rate_bits = bitrate_to_bits(rate_bps, self.sampling_rate, frame_size);
981 let bits_target = (8 * n_bytes as i32).min(rate_bits) - 8;
982 let total_bitrate = bits_to_bitrate(bits_target, self.sampling_rate, frame_size);
983
984 let silk_restart_after_celt =
988 self.prev_enc_mode == Some(OpusMode::CeltOnly);
989 if silk_restart_after_celt {
990 silk_init_encoder(state_mut(&mut self.silk_enc), 0);
991 self.silk_enc.n_bits_used_lbrr = 0;
993 self.silk_enc.n_bits_exceeded = 0;
994 if self.channels == 2 {
995 *state_mut(&mut self.silk_enc_side) = SilkEncoderState::default();
998 silk_init_encoder(state_mut(&mut self.silk_enc_side), 0);
999 self.silk_enc.stereo.reset();
1000 }
1001 self.silk_initialized = false;
1002 }
1003 if !self.silk_initialized || self.silk_enc.s_cmn.fs_khz != silk_fs_khz {
1004 silk_control_encoder(
1005 state_mut(&mut self.silk_enc),
1006 silk_fs_khz,
1007 frame_ms,
1008 total_bitrate,
1009 self.complexity,
1010 );
1011 self.silk_enc.s_cmn.use_cbr = if self.use_cbr { 1 } else { 0 };
1012
1013 self.silk_enc.s_cmn.n_channels = self.channels as i32;
1014 self.silk_initialized = true;
1015 let ret = self
1019 .silk_resampler_enc
1020 .init_for_enc(self.sampling_rate as i32, silk_fs_khz * 1000);
1021 if ret != 0 {
1022 return Err("Unsupported SILK resampling ratio");
1023 }
1024 if self.channels == 2 {
1025 self.silk_resampler_enc_right = self.silk_resampler_enc.clone();
1026 let side = state_mut(&mut self.silk_enc_side);
1029 silk_control_encoder(
1030 side,
1031 silk_fs_khz,
1032 frame_ms,
1033 total_bitrate,
1034 self.complexity,
1035 );
1036 side.s_cmn.use_cbr = self.silk_enc.s_cmn.use_cbr;
1037 side.s_cmn.n_channels = 2;
1038 }
1039 }
1040
1041 for enc in [&mut self.silk_enc, &mut self.silk_enc_side]
1045 .into_iter()
1046 .take(self.channels)
1047 {
1048 enc.s_cmn.use_in_band_fec = if self.use_inband_fec { 1 } else { 0 };
1049 enc.s_cmn.packet_loss_perc = self.packet_loss_perc.clamp(0, 100);
1050 silk_setup_lbrr(state_mut(enc), lbrr_coded);
1051 }
1052
1053 let silk_frame_len_samples =
1054 frame_size * silk_fs_khz as usize / (self.sampling_rate.max(1000) / 1000) as usize;
1055 let silk_bitrate = if mode == OpusMode::Hybrid {
1056 let frame_duration_ms = frame_size as i32 * 1000 / self.sampling_rate;
1057 let frame20ms = frame_duration_ms >= 20;
1058 compute_silk_rate_for_hybrid(self.bitrate_bps, frame20ms, self.channels)
1059 } else {
1060 total_bitrate
1062 };
1063
1064 if silk_restart_after_celt && self.encoder_buffer > 0 && self.delay_compensation > 0
1069 {
1070 let ch = self.channels;
1071 let f2_5 = self.sampling_rate / 400;
1072 let eb = self.encoder_buffer;
1073 let offset = eb - self.delay_compensation.min(eb) - f2_5 as usize;
1074 let silk_rate = self.sampling_rate.min(16000);
1075 let pre_resampled_len = eb * silk_rate as usize / self.sampling_rate as usize;
1076 if ch == 2 {
1081 let (mut pre_l, mut pre_r) = ([0i16; 480], [0i16; 480]);
1085 if offset < eb {
1086 for i in offset..eb {
1087 let fade = (((i - offset) as f32) / f2_5 as f32).min(1.0);
1088 pre_l[i] = (self.delay_buffer[2 * i] * fade * 32768.0) as i16;
1089 pre_r[i] = (self.delay_buffer[2 * i + 1] * fade * 32768.0) as i16;
1090 }
1091 }
1092 let (mut int_l, mut int_r) = ([0i16; 480], [0i16; 480]);
1093 let int_l = &mut int_l[..pre_resampled_len];
1094 let int_r = &mut int_r[..pre_resampled_len];
1095 self.silk_resampler_enc
1096 .process(int_l, &pre_l[..eb], eb as i32);
1097 self.silk_resampler_enc_right
1098 .process(int_r, &pre_r[..eb], eb as i32);
1099 silk_encode_prefill_stereo(
1100 state_mut(&mut self.silk_enc),
1101 state_mut(&mut self.silk_enc_side),
1102 int_l,
1103 int_r,
1104 silk_bitrate,
1105 1,
1106 );
1107 } else {
1108 let mut pre = [0i16; 480];
1109 let pre = &mut pre[..eb];
1110 if offset < eb {
1111 for i in offset..eb {
1112 let fade = (((i - offset) as f32) / f2_5 as f32).min(1.0);
1113 pre[i] = (self.delay_buffer[i] * fade * 32768.0) as i16;
1114 }
1115 }
1116 let mut pre_internal = [0i16; 480];
1117 let pre_internal = &mut pre_internal[..pre_resampled_len];
1118 self.silk_resampler_enc
1119 .process(pre_internal, pre, eb as i32);
1120 silk_encode_prefill(state_mut(&mut self.silk_enc), pre_internal, 1);
1121 }
1122 }
1123
1124 let required_size = frame_size * self.channels;
1125 self.buf_filtered.resize(required_size, 0);
1126 let voip = self.application == Application::Voip;
1127 match input {
1128 PcmInput::I16(samples) => {
1129 if voip {
1130 hp_cutoff_i16(
1134 samples,
1135 cutoff_hz,
1136 state_mut(&mut self.buf_filtered),
1137 &mut self.hp_mem,
1138 frame_size,
1139 self.channels,
1140 self.sampling_rate,
1141 );
1142 } else {
1143 let filtered = state_mut(&mut self.buf_filtered);
1144 filtered[..required_size].copy_from_slice(&samples[..required_size]);
1145 }
1146 }
1147 PcmInput::F32(samples) => {
1148 if voip {
1149 hp_cutoff(
1150 samples,
1151 cutoff_hz,
1152 state_mut(&mut self.buf_filtered),
1153 &mut self.hp_mem,
1154 frame_size,
1155 self.channels,
1156 self.sampling_rate,
1157 );
1158 } else {
1159 let filtered = state_mut(&mut self.buf_filtered);
1160 for (i, &x) in samples.iter().enumerate().take(required_size) {
1161 filtered[i] = (x * 32768.0).clamp(-32768.0, 32767.0) as i16;
1162 }
1163 }
1164 }
1165 }
1166
1167 let input_i16 = state_ref(&self.buf_filtered);
1168
1169 self.buf_silk_input.resize(silk_frame_len_samples, 0);
1176 if self.channels == 2 {
1177 self.buf_silk_input_right.resize(silk_frame_len_samples, 0);
1178 for c in 0..2 {
1179 self.buf_silk_api_channel.resize(frame_size, 0);
1180 for (s, lr) in self
1181 .buf_silk_api_channel
1182 .iter_mut()
1183 .zip(input_i16.chunks_exact(2))
1184 {
1185 *s = lr[c];
1186 }
1187 let (resampler, out) = if c == 0 {
1188 (
1189 &mut self.silk_resampler_enc,
1190 state_mut(&mut self.buf_silk_input).as_mut_slice(),
1191 )
1192 } else {
1193 (
1194 &mut self.silk_resampler_enc_right,
1195 state_mut(&mut self.buf_silk_input_right).as_mut_slice(),
1196 )
1197 };
1198 if resampler.process(out, &self.buf_silk_api_channel, frame_size as i32) != 0 {
1199 return Err("SILK input resampling failed");
1200 }
1201 }
1202 } else {
1203 let got = self.silk_resampler_enc.process(
1204 state_mut(&mut self.buf_silk_input),
1205 input_i16,
1206 frame_size as i32,
1207 );
1208 if got != 0 {
1209 return Err("SILK input resampling failed");
1210 }
1211 }
1212 let silk_input: &[i16] = state_ref(&self.buf_silk_input);
1213
1214 let mut pn_bytes = 0;
1215
1216 let silk_max_bits = if mode == OpusMode::Hybrid {
1217 let total_max_bits = ((n_bytes - 1) * 8) as i32;
1218 if self.use_cbr {
1219 let silk_bits = (silk_bitrate as i64 * frame_size as i64
1220 / self.sampling_rate as i64) as i32;
1221 let other_bits = 0i32.max(total_max_bits - silk_bits);
1222 0i32.max(total_max_bits - other_bits * 3 / 4)
1223 } else {
1224 let frame_duration_ms = frame_size as i32 * 1000 / self.sampling_rate;
1225 let frame20ms = frame_duration_ms >= 20;
1226 let max_bit_rate = compute_silk_rate_for_hybrid(
1227 total_max_bits * self.sampling_rate / frame_size as i32,
1228 frame20ms,
1229 self.channels,
1230 );
1231 max_bit_rate * frame_size as i32 / self.sampling_rate
1232 }
1233 } else {
1234 ((n_bytes - 1) * 8) as i32
1235 };
1236 let silk_use_cbr = if mode == OpusMode::Hybrid && self.use_cbr {
1237 0
1238 } else if self.use_cbr {
1239 1
1240 } else {
1241 0
1242 };
1243 let ret = if self.channels == 2 {
1244 silk_encode_stereo_packet(
1245 state_mut(&mut self.silk_enc),
1246 state_mut(&mut self.silk_enc_side),
1247 silk_input,
1248 state_ref(&self.buf_silk_input_right),
1249 silk_input.len(),
1250 &mut self.rc,
1251 &mut pn_bytes,
1252 silk_bitrate,
1253 silk_max_bits,
1254 silk_use_cbr,
1255 1,
1256 )
1257 } else {
1258 silk_encode(
1259 state_mut(&mut self.silk_enc),
1260 silk_input,
1261 silk_input.len(),
1262 &mut self.rc,
1263 &mut pn_bytes,
1264 silk_bitrate,
1265 silk_max_bits,
1266 silk_use_cbr,
1267 1,
1268 )
1269 };
1270 if ret != 0 {
1271 return Err("SILK encoding failed");
1272 }
1273 }
1274
1275 if mode == OpusMode::Hybrid {
1276 self.rc.encode_bit_logp(false, 12); }
1278
1279 if mode == OpusMode::Hybrid {
1280 let nb_compr_bytes = (n_bytes - 1) as u32;
1281 self.rc.shrink(nb_compr_bytes);
1282 }
1283
1284 let silk_ret_bytes = if mode == OpusMode::SilkOnly {
1285 ((self.rc.tell() + 7) >> 3) as usize
1286 } else {
1287 0
1288 };
1289
1290 if mode != OpusMode::SilkOnly && self.use_cbr {
1296 let tell = self.rc.tell();
1297 if tell > 1 {
1298 let tmp = self.bitrate_bps as i64 * frame_size as i64
1299 + tell as i64 * self.sampling_rate as i64;
1300 let adjusted = ((tmp + 4 * self.sampling_rate as i64)
1301 / (8 * self.sampling_rate as i64)) as usize;
1302 let new_n = adjusted.clamp(1, OPUS_MAX_PACKET_BYTES).min(max_data_bytes);
1303 if new_n < n_bytes {
1304 n_bytes = new_n;
1305 let new_payload = n_bytes - 1;
1307 self.rc.shrink(new_payload as u32);
1308 }
1309 }
1310 }
1311 if mode == OpusMode::CeltOnly || mode == OpusMode::Hybrid {
1312 self.celt_enc.complexity = self.complexity;
1313 let start_band = if mode == OpusMode::Hybrid { 17 } else { 0 };
1314 let end_band = match frame_bandwidth {
1317 Bandwidth::Narrowband => 13,
1318 Bandwidth::Mediumband | Bandwidth::Wideband => 17,
1319 Bandwidth::Superwideband => 19,
1320 Bandwidth::Fullband | Bandwidth::Auto => 21,
1321 };
1322 self.celt_enc.set_end_band(end_band);
1323 let total_packet_bits = ((n_bytes - 1) * 8) as i32;
1324 let celt_bitrate = if mode == OpusMode::Hybrid {
1326 let frame_ms = frame_size as i32 * 1000 / self.sampling_rate;
1327 let frame20ms = frame_ms >= 20;
1328 let silk_rate =
1329 compute_silk_rate_for_hybrid(self.bitrate_bps, frame20ms, self.channels);
1330 (self.bitrate_bps - silk_rate).max(8000)
1331 } else {
1332 self.bitrate_bps
1333 };
1334 self.celt_enc.set_bitrate(celt_bitrate);
1335 self.celt_enc.set_vbr(!self.use_cbr);
1336 self.celt_enc
1338 .set_constrained_vbr(mode == OpusMode::CeltOnly);
1339
1340 let input_f32: &[f32] = match input {
1346 PcmInput::F32(samples) => samples,
1347 PcmInput::I16(samples) => {
1348 let n = frame_size * self.channels;
1349 self.buf_f32_frame.resize(n, 0.0);
1350 let staging = state_mut(&mut self.buf_f32_frame);
1351 for (dst, &src) in staging[..n].iter_mut().zip(samples[..n].iter()) {
1352 *dst = src as f32 / 32768.0;
1353 }
1354 state_ref(&self.buf_f32_frame)
1355 }
1356 };
1357
1358 let celt_input: &[f32] = if self.delay_compensation > 0 {
1365 let delay = self.delay_compensation;
1366 let ebuf = self.encoder_buffer;
1367 let ch = self.channels;
1368 let total = (delay + frame_size) * ch;
1369 self.buf_celt_pcm.resize(total, 0.0);
1370 let prefix = delay * ch;
1372 let src_start = (ebuf - delay) * ch;
1373 self.buf_celt_pcm[..prefix]
1374 .copy_from_slice(&self.delay_buffer[src_start..src_start + prefix]);
1375 let out = &mut self.buf_celt_pcm[prefix..];
1377 if self.application == Application::Voip {
1378 hp_cutoff_float(
1379 input_f32,
1380 cutoff_hz,
1381 out,
1382 &mut self.hp_mem_float,
1383 frame_size,
1384 ch,
1385 self.sampling_rate,
1386 );
1387 } else {
1388 dc_reject_float(
1389 input_f32,
1390 3,
1391 out,
1392 &mut self.hp_mem_float,
1393 frame_size,
1394 ch,
1395 self.sampling_rate,
1396 );
1397 }
1398 let mut sum = 0.0f32;
1400 for &v in &self.buf_celt_pcm[prefix..] {
1401 sum += v * v;
1402 }
1403 #[allow(clippy::neg_cmp_op_on_partial_ord)]
1406 if !(sum < 1e9) || sum.is_nan() {
1407 self.buf_celt_pcm[prefix..].fill(0.0);
1408 self.hp_mem_float = [0.0; 4];
1409 }
1410 let keep = ebuf as i64 - (frame_size as i64 + delay as i64);
1412 if keep > 0 {
1413 let keep = keep as usize;
1414 self.delay_buffer
1415 .copy_within(ch * frame_size..ch * (frame_size + keep), 0);
1416 let dst = ch * keep;
1417 let n = (frame_size + delay) * ch;
1418 self.delay_buffer[dst..dst + n].copy_from_slice(&self.buf_celt_pcm[..n]);
1419 } else {
1420 let n = ebuf * ch;
1421 let src = (frame_size + delay - ebuf) * ch;
1422 self.delay_buffer[..n].copy_from_slice(&self.buf_celt_pcm[src..src + n]);
1423 }
1424 let n = frame_size * ch;
1427 self.buf_celt_input.resize(n, 0.0);
1428 for i in 0..frame_size {
1429 for c in 0..ch {
1430 self.buf_celt_input[c * frame_size + i] = self.buf_celt_pcm[i * ch + c];
1431 }
1432 }
1433 state_ref(&self.buf_celt_input)
1434 } else if self.channels == 1 {
1435 input_f32
1436 } else {
1437 let n = frame_size * self.channels;
1438 self.buf_celt_input.resize(n, 0.0);
1439 for i in 0..frame_size {
1440 for ch in 0..self.channels {
1441 self.buf_celt_input[ch * frame_size + i] =
1442 input_f32[i * self.channels + ch];
1443 }
1444 }
1445 state_ref(&self.buf_celt_input)
1446 };
1447
1448 if self.rc.tell() <= total_packet_bits {
1449 let is_vbr = !self.use_cbr;
1450 self.celt_enc.encode_with_budget_vbr(
1451 celt_input,
1452 frame_size,
1453 &mut self.rc,
1454 start_band,
1455 total_packet_bits,
1456 is_vbr,
1457 );
1458 }
1459 }
1460
1461 self.rc.done();
1462
1463 if self.rc.error != 0 || self.rc.tell() > (n_bytes as i32 - 1) * 8 {
1472 if output.len() < 2 {
1473 return Err("Output buffer too small");
1474 }
1475 let mut ret = 2usize;
1476 if self.use_cbr && n_bytes >= 2 {
1477 let target_total = n_bytes.min(output.len());
1480 if target_total > 2 {
1481 output[0] = toc | 0x03;
1482 output[1] = 0x41; let pad_amount = target_total - 2;
1484 let nb_255s = (pad_amount - 1) / 255;
1485 let mut ptr = 2;
1486 for _ in 0..nb_255s {
1487 output[ptr] = 255;
1488 ptr += 1;
1489 }
1490 output[ptr] = (pad_amount - 255 * nb_255s - 1) as u8;
1491 ptr += 1;
1492 for b in &mut output[ptr..target_total] {
1493 *b = 0;
1494 }
1495 self.prev_enc_mode = Some(mode);
1496 return Ok(target_total);
1497 }
1498 ret = target_total.max(1);
1499 }
1500 output[0] = toc;
1502 output[1] = 0;
1503 self.prev_enc_mode = Some(mode);
1504 return Ok(ret);
1505 }
1506
1507 if mode == OpusMode::SilkOnly {
1508 let mut ret = silk_ret_bytes.min(self.rc.storage as usize);
1509 while ret > 2 && self.rc.buf[ret - 1] == 0 {
1510 ret -= 1;
1511 }
1512
1513 let target_total = if self.use_cbr {
1514 n_bytes.min(output.len())
1515 } else {
1516 (ret + 1).min(output.len())
1517 };
1518
1519 let silk_len = ret;
1520
1521 if !self.use_cbr || silk_len + 1 >= target_total {
1522 output[0] = toc;
1524 let copy_len = silk_len.min(target_total - 1);
1525 output[1..1 + copy_len].copy_from_slice(&self.rc.buf[..copy_len]);
1526 return Ok((copy_len + 1).min(output.len()));
1527 }
1528
1529 output[0] = toc | 0x03;
1530
1531 if silk_len + 2 >= target_total {
1532 output[1] = 0x01;
1533 let copy_len = (target_total - 2).min(silk_len);
1534 output[2..2 + copy_len].copy_from_slice(&self.rc.buf[..copy_len]);
1535 self.prev_enc_mode = Some(mode);
1536 return Ok(target_total.min(output.len()));
1537 }
1538
1539 let pad_amount = target_total - silk_len - 2;
1540 output[1] = 0x41;
1541
1542 let nb_255s = (pad_amount - 1) / 255;
1543 let mut ptr = 2;
1544 for _ in 0..nb_255s {
1545 output[ptr] = 255;
1546 ptr += 1;
1547 }
1548 output[ptr] = (pad_amount - 255 * nb_255s - 1) as u8;
1549 ptr += 1;
1550
1551 output[ptr..ptr + silk_len].copy_from_slice(&self.rc.buf[..silk_len]);
1552 ptr += silk_len;
1553
1554 let fill_end = target_total.min(output.len());
1555 for byte in output[ptr..fill_end].iter_mut() {
1556 *byte = 0;
1557 }
1558
1559 self.prev_enc_mode = Some(mode);
1560 return Ok(target_total.min(output.len()));
1561 }
1562
1563 let payload_len = (self.rc.storage as usize).min(output.len() - 1);
1565 output[1..1 + payload_len].copy_from_slice(&self.rc.buf[..payload_len]);
1566 self.prev_enc_mode = Some(mode);
1567 Ok(payload_len + 1)
1568 }
1569
1570 fn encode_multiframe(
1574 &mut self,
1575 input: PcmInput<'_>,
1576 frame_size: usize,
1577 mode: OpusMode,
1578 output: &mut [u8],
1579 ) -> Result<usize, &'static str> {
1580 const MAX_SUB: usize = 3; let ch = self.channels;
1582 let enc_frame = (self.sampling_rate / 50) as usize; if enc_frame == 0 || !frame_size.is_multiple_of(enc_frame) {
1584 return Err("Invalid multi-frame size");
1585 }
1586 let nb = frame_size / enc_frame;
1587 if !(2..=MAX_SUB).contains(&nb) {
1588 return Err("Unsupported multi-frame size");
1589 }
1590
1591 fn put_size(out: &mut [u8], pos: &mut usize, len: usize) -> Result<(), &'static str> {
1593 if len < 252 {
1594 if *pos >= out.len() {
1595 return Err("Output buffer too small");
1596 }
1597 out[*pos] = len as u8;
1598 *pos += 1;
1599 } else {
1600 if *pos + 1 >= out.len() {
1601 return Err("Output buffer too small");
1602 }
1603 let first = 252 + (len & 3);
1604 out[*pos] = first as u8;
1605 out[*pos + 1] = ((len - first) >> 2) as u8;
1606 *pos += 2;
1607 }
1608 Ok(())
1609 }
1610
1611 let mut sub = [[0u8; 1276]; MAX_SUB];
1612 let mut lens = [0usize; MAX_SUB];
1613 self.forced_mode = Some(mode);
1614 let enc_res = (|| -> Result<(), &'static str> {
1615 for i in 0..nb {
1616 let start = i * enc_frame * ch;
1617 let end = start + enc_frame * ch;
1618 let sub_input = match input {
1619 PcmInput::F32(s) => PcmInput::F32(&s[start..end]),
1620 PcmInput::I16(s) => PcmInput::I16(&s[start..end]),
1621 };
1622 let n = self.encode_impl(sub_input, enc_frame, &mut sub[i])?;
1623 if n == 0 {
1624 return Err("Empty sub-frame");
1625 }
1626 lens[i] = n - 1;
1627 }
1628 Ok(())
1629 })();
1630 self.forced_mode = None;
1631 enc_res?;
1632
1633 let toc = sub[0][0] & 0xFC;
1634 let mut pos = 0usize;
1635 let push =
1636 |out: &mut [u8], pos: &mut usize, byte: u8| -> Result<(), &'static str> {
1637 if *pos >= out.len() {
1638 return Err("Output buffer too small");
1639 }
1640 out[*pos] = byte;
1641 *pos += 1;
1642 Ok(())
1643 };
1644 if nb == 2 {
1648 push(output, &mut pos, toc | 0x02)?;
1649 put_size(output, &mut pos, lens[0])?;
1650 } else {
1651 push(output, &mut pos, toc | 0x03)?;
1652 push(output, &mut pos, nb as u8 | 0x80)?;
1653 for i in 0..nb - 1 {
1654 put_size(output, &mut pos, lens[i])?;
1655 }
1656 }
1657
1658 for i in 0..nb {
1659 let payload = &sub[i][1..1 + lens[i]];
1660 if pos + payload.len() > output.len() {
1661 return Err("Output buffer too small");
1662 }
1663 output[pos..pos + payload.len()].copy_from_slice(payload);
1664 pos += payload.len();
1665 }
1666 self.prev_enc_mode = Some(mode);
1667 Ok(pos)
1668 }
1669}
1670
1671pub struct OpusDecoder {
1672 #[cfg(not(feature = "heap"))]
1673 celt_dec: CeltDecoder,
1674 #[cfg(feature = "heap")]
1675 celt_dec: Box<CeltDecoder>,
1676 #[cfg(not(feature = "heap"))]
1677 silk_dec: silk::dec_api::SilkDecoder,
1678 #[cfg(feature = "heap")]
1679 silk_dec: Box<silk::dec_api::SilkDecoder>,
1680 sampling_rate: i32,
1681 channels: usize,
1682
1683 prev_mode: Option<OpusMode>,
1684
1685 prev_redundancy: bool,
1687 frame_size: usize,
1688
1689 bandwidth: Bandwidth,
1690
1691 stream_channels: usize,
1692
1693 silk_resampler: silk::resampler::SilkResampler,
1694
1695 silk_resampler_2: silk::resampler::SilkResampler,
1697
1698 prev_internal_rate: i32,
1699
1700 pub hybrid_skip_celt: bool,
1701
1702 #[cfg(not(feature = "heap"))]
1703 w_pcm_i16: FixedVec<i16, OPUS_PCM_I16>,
1704 #[cfg(feature = "heap")]
1705 w_pcm_i16: Box<FixedVec<i16, OPUS_PCM_I16>>,
1706 #[cfg(not(feature = "heap"))]
1707 w_silk_out: FixedVec<f32, OPUS_SUBFRAME_SCRATCH>,
1708 #[cfg(feature = "heap")]
1709 w_silk_out: Box<FixedVec<f32, OPUS_SUBFRAME_SCRATCH>>,
1710 #[cfg(not(feature = "heap"))]
1711 w_pcm_resampled: FixedVec<i16, OPUS_SUBFRAME_SCRATCH>,
1712 #[cfg(feature = "heap")]
1713 w_pcm_resampled: Box<FixedVec<i16, OPUS_SUBFRAME_SCRATCH>>,
1714 #[cfg(not(feature = "heap"))]
1715 w_celt_planar: FixedVec<f32, OPUS_SUBFRAME_SCRATCH>,
1716 #[cfg(feature = "heap")]
1717 w_celt_planar: Box<FixedVec<f32, OPUS_SUBFRAME_SCRATCH>>,
1718 #[cfg(not(feature = "heap"))]
1719 w_celt_out: FixedVec<f32, OPUS_SUBFRAME_SCRATCH>,
1720 #[cfg(feature = "heap")]
1721 w_celt_out: Box<FixedVec<f32, OPUS_SUBFRAME_SCRATCH>>,
1722
1723 #[cfg(not(feature = "heap"))]
1726 prev_pcm_tail: FixedVec<f32, OPUS_PCM_TAIL>,
1727 #[cfg(feature = "heap")]
1728 prev_pcm_tail: Box<FixedVec<f32, OPUS_PCM_TAIL>>,
1729}
1730
1731impl OpusDecoder {
1732 pub fn new(sampling_rate: i32, channels: usize) -> Result<Self, &'static str> {
1733 let mut decoder = MaybeUninit::uninit();
1734 Self::init(&mut decoder, sampling_rate, channels)?;
1735 Ok(unsafe { decoder.assume_init() })
1736 }
1737
1738 pub fn init(
1744 slot: &mut MaybeUninit<Self>,
1745 sampling_rate: i32,
1746 channels: usize,
1747 ) -> Result<&mut Self, &'static str> {
1748 if ![8000, 12000, 16000, 24000, 48000].contains(&sampling_rate) {
1749 return Err("Invalid sampling rate");
1750 }
1751 if ![1, 2].contains(&channels) {
1752 return Err("Invalid number of channels");
1753 }
1754
1755 let mode = modes::default_mode();
1756 let this = slot.as_mut_ptr();
1757 unsafe {
1758 #[cfg(feature = "heap")]
1759 {
1760 (&raw mut (*this).celt_dec).write(Box::new(CeltDecoder::new(mode, channels, sampling_rate)));
1761 (&raw mut (*this).silk_dec).write(Box::new(silk::dec_api::SilkDecoder::new()));
1762 }
1763 #[cfg(not(feature = "heap"))]
1764 {
1765 CeltDecoder::write_new(&raw mut (*this).celt_dec, mode, channels, sampling_rate);
1766 silk::dec_api::SilkDecoder::write_new(&raw mut (*this).silk_dec);
1767 }
1768 (&raw mut (*this).sampling_rate).write(sampling_rate);
1769 (&raw mut (*this).channels).write(channels);
1770 (&raw mut (*this).prev_mode).write(None);
1771 (&raw mut (*this).prev_redundancy).write(false);
1772 (&raw mut (*this).frame_size).write(0);
1773 (&raw mut (*this).bandwidth).write(Bandwidth::Auto);
1774 (&raw mut (*this).stream_channels).write(channels);
1775 (&raw mut (*this).silk_resampler).write(silk::resampler::SilkResampler::default());
1776 (&raw mut (*this).silk_resampler_2).write(silk::resampler::SilkResampler::default());
1777 (&raw mut (*this).prev_internal_rate).write(0);
1778 (&raw mut (*this).hybrid_skip_celt).write(false);
1779 #[cfg(feature = "heap")]
1780 {
1781 (&raw mut (*this).w_pcm_i16).write(Box::new(FixedVec::from_value(0i16, 960 * channels)));
1782 (&raw mut (*this).w_silk_out).write(Box::new(FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels)));
1783 (&raw mut (*this).w_pcm_resampled).write(Box::new(FixedVec::from_value(0i16, OPUS_MAX_SUBFRAME * channels)));
1784 (&raw mut (*this).w_celt_planar).write(Box::new(FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels)));
1785 (&raw mut (*this).w_celt_out).write(Box::new(FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels)));
1786 (&raw mut (*this).prev_pcm_tail).write(Box::new(FixedVec::from_value(0.0f32, 240 * channels)));
1787 }
1788 #[cfg(not(feature = "heap"))]
1789 {
1790 FixedVec::write_from_value(&raw mut (*this).w_pcm_i16, 0i16, 960 * channels);
1791 FixedVec::write_from_value(&raw mut (*this).w_silk_out, 0.0f32, OPUS_MAX_SUBFRAME * channels);
1792 FixedVec::write_from_value(&raw mut (*this).w_pcm_resampled, 0i16, OPUS_MAX_SUBFRAME * channels);
1793 FixedVec::write_from_value(&raw mut (*this).w_celt_planar, 0.0f32, OPUS_MAX_SUBFRAME * channels);
1794 FixedVec::write_from_value(&raw mut (*this).w_celt_out, 0.0f32, OPUS_MAX_SUBFRAME * channels);
1795 FixedVec::write_from_value(&raw mut (*this).prev_pcm_tail, 0.0f32, 240 * channels);
1796 }
1797 }
1798
1799 let decoder = unsafe { slot.assume_init_mut() };
1800 decoder.silk_dec.init(sampling_rate.min(16000), channels as i32);
1801 decoder.silk_dec.channel_state[0].fs_api_hz = sampling_rate;
1802 Ok(decoder)
1803 }
1804
1805 pub fn decode(
1819 &mut self,
1820 input: &[u8],
1821 frame_size: usize,
1822 output: &mut [f32],
1823 ) -> Result<usize, &'static str> {
1824 if input.len() <= 1 {
1827 return self.decode_lost(input.first().copied(), frame_size, output);
1828 }
1829
1830 let toc = input[0];
1831 let mode = mode_from_toc(toc);
1832 let packet_channels = channels_from_toc(toc);
1833 let bandwidth = bandwidth_from_toc(toc);
1834 let frame_duration_ms = frame_duration_ms_from_toc(toc);
1835
1836 let code = toc & 0x03;
1837 let frame_count: usize;
1838 let frame_payloads: FixedVec<&[u8], OPUS_MAX_PACKET_FRAMES>;
1839
1840 match code {
1841 0 => {
1842 frame_count = 1;
1843 frame_payloads = FixedVec::from_slice(&[&input[1..]]);
1844 }
1845 1 => {
1846 frame_count = 2;
1847 let data_len = input.len() - 1;
1848 if !data_len.is_multiple_of(2) {
1851 return Err("Code 1: payload length must be even");
1852 }
1853 let half = data_len / 2;
1854 if half == 0 {
1855 return Err("Code 1: empty frame");
1856 }
1857 frame_payloads = FixedVec::from_slice(&[&input[1..1 + half], &input[1 + half..]]);
1858 }
1859 2 => {
1860 frame_count = 2;
1861 let data = &input[1..];
1862 if data.is_empty() {
1863 return Err("Code 2 packet has no data");
1864 }
1865 let (first_len, header_size) = parse_frame_size(data)?;
1866 if header_size + first_len > data.len() {
1867 return Err("Code 2: first frame size exceeds packet");
1868 }
1869 frame_payloads = FixedVec::from_slice(&[
1870 &data[header_size..header_size + first_len],
1871 &data[header_size + first_len..],
1872 ]);
1873 }
1874 3 => {
1875 if input.len() < 2 {
1876 return Err("Code 3 packet too short");
1877 }
1878 let count_byte = input[1];
1879 let n_frames = (count_byte & 0x3F) as usize;
1880 if !(1..=48).contains(&n_frames) {
1881 return Err("Code 3: invalid frame count");
1882 }
1883 frame_count = n_frames;
1884 let padding_flag = (count_byte & 0x40) != 0;
1886 let vbr = (count_byte & 0x80) != 0;
1887
1888 let mut ptr = 2usize;
1892 let mut pad_len = 0usize;
1893 if padding_flag {
1894 loop {
1895 if ptr >= input.len() {
1896 return Err("Code 3: padding overflow");
1897 }
1898 let p = input[ptr] as usize;
1899 ptr += 1;
1900 if p == 255 {
1901 pad_len += 254;
1902 } else {
1903 pad_len += p;
1904 break;
1905 }
1906 }
1907 }
1908 if ptr + pad_len > input.len() {
1909 return Err("Code 3: padding exceeds packet");
1910 }
1911 let payload_end = input.len() - pad_len;
1912 let payload = &input[ptr..payload_end];
1913
1914 let mut payloads: FixedVec<&[u8], OPUS_MAX_PACKET_FRAMES> = FixedVec::new();
1915 if frame_count == 1 {
1916 payloads.push(payload);
1919 } else if vbr {
1920 let mut cursor = 0usize;
1926 let mut frame_bytes = 0usize;
1927 let mut sizes = [0usize; OPUS_MAX_PACKET_FRAMES];
1928 for i in 0..frame_count - 1 {
1929 if cursor >= payload.len() {
1930 return Err("Code 3: unexpected end in VBR header");
1931 }
1932 let (frame_len, header_bytes) = parse_frame_size(&payload[cursor..])?;
1933 cursor += header_bytes;
1934 sizes[i] = frame_len;
1935 frame_bytes += frame_len;
1936 }
1937 if frame_bytes > payload.len() - cursor {
1938 return Err("Code 3: frame length exceeds packet");
1939 }
1940 sizes[frame_count - 1] = payload.len() - cursor - frame_bytes;
1941 let mut data_pos = cursor;
1942 for i in 0..frame_count {
1943 payloads.push(&payload[data_pos..data_pos + sizes[i]]);
1944 data_pos += sizes[i];
1945 }
1946 } else {
1947 if !payload.len().is_multiple_of(frame_count) {
1951 return Err("Code 3 CBR: payload not divisible by frame count");
1952 }
1953 let frame_len = payload.len() / frame_count;
1954 for i in 0..frame_count {
1955 payloads.push(&payload[i * frame_len..(i + 1) * frame_len]);
1956 }
1957 }
1958 frame_payloads = payloads;
1959 }
1960 _ => unreachable!(),
1961 }
1962
1963 self.frame_size = frame_size;
1964 self.bandwidth = bandwidth;
1965
1966 let toc_frame_size = frame_samples_from_toc(toc, self.sampling_rate)
1971 .ok_or("Invalid TOC for sampling rate")?;
1972 let decoded_total = toc_frame_size * frame_count;
1973 if frame_size < decoded_total {
1974 return Err("frame_size too small for packet");
1975 }
1976 if output.len() < decoded_total * self.channels {
1977 return Err("Output buffer too small for packet");
1978 }
1979 self.stream_channels = packet_channels;
1981 self.celt_dec.set_stream_channels(packet_channels);
1982 if output.len() > decoded_total * self.channels {
1985 for v in &mut output[decoded_total * self.channels..] {
1986 *v = 0.0;
1987 }
1988 }
1989 let sub_frame_size = toc_frame_size;
1990 let sub_output_len = sub_frame_size * self.channels;
1991
1992 let mode_transition = matches!(
1998 self.prev_mode,
1999 Some(prev) if prev != mode && !self.prev_redundancy
2000 );
2001 let mut transition = match self.prev_mode {
2005 Some(prev) => {
2006 (mode == OpusMode::CeltOnly && prev != OpusMode::CeltOnly && !self.prev_redundancy)
2007 || (mode != OpusMode::CeltOnly && prev == OpusMode::CeltOnly)
2008 }
2009 None => false,
2010 };
2011 let from_celt = self.prev_mode == Some(OpusMode::CeltOnly) && mode != OpusMode::CeltOnly;
2012 if from_celt {
2013 self.silk_dec.reset();
2016 self.prev_internal_rate = 0;
2017 }
2018 if mode_transition && mode == OpusMode::CeltOnly {
2028 self.celt_dec.reset_state();
2029 }
2030
2031 let f5_bridge = self.sampling_rate as usize / 200; if transition
2037 && mode == OpusMode::CeltOnly
2038 && f5_bridge > 0
2039 && matches!(
2040 self.prev_mode,
2041 Some(OpusMode::SilkOnly) | Some(OpusMode::Hybrid)
2042 )
2043 && self.prev_internal_rate > 0
2044 {
2045 let internal_rate = self.prev_internal_rate;
2046 let plc_internal_len = (10 * internal_rate / 1000) as usize;
2047 let mut plc_rc = RangeCoder::new_decoder(&[]);
2048 let mut plc_i16: FixedVec<i16, OPUS_PCM_I16> =
2049 FixedVec::from_value(0i16, plc_internal_len * self.channels);
2050 let n = self.silk_dec.decode(
2051 &mut plc_rc,
2052 &mut plc_i16,
2053 silk::decode_frame::FLAG_PACKET_LOST,
2054 true,
2055 10,
2056 internal_rate,
2057 );
2058 if n > 0 {
2059 let bridge_ch = f5_bridge * self.channels;
2060 let bridge_len = bridge_ch.min(self.prev_pcm_tail.len());
2061 if internal_rate == self.sampling_rate {
2062 let n_us = n as usize;
2065 let silk_channels = self
2066 .channels
2067 .min(self.silk_dec.n_channels_internal as usize);
2068 for ch in 0..self.channels {
2069 let src_base = ch.min(silk_channels - 1) * n_us;
2070 for i in 0..(bridge_len / self.channels).min(n_us) {
2071 let dst = i * self.channels + ch;
2072 if dst < bridge_len {
2073 self.prev_pcm_tail[dst] = plc_i16[src_base + i] as f32 / 32768.0;
2074 }
2075 }
2076 }
2077 } else if self.silk_resampler.is_initialized() {
2078 let ratio = self.sampling_rate as f64 / internal_rate as f64;
2084 let full_len = ((n as f64 * ratio) as usize).max(1);
2085 let out_len = full_len.min(f5_bridge);
2086 let n_us = n as usize;
2087 let mut resampled: FixedVec<i16, OPUS_MAX_FRAME> =
2088 FixedVec::from_value(0i16, full_len);
2089 self.silk_resampler
2090 .process(&mut resampled, &plc_i16[..n_us], n);
2091 for i in 0..out_len {
2092 if i < bridge_len / self.channels {
2093 for ch in 0..self.channels {
2094 self.prev_pcm_tail[i * self.channels + ch] =
2095 resampled[i] as f32 / 32768.0;
2096 }
2097 }
2098 }
2099 }
2100 }
2101 }
2102
2103 let mut has_redundancy = false;
2105
2106 match mode {
2107 OpusMode::SilkOnly => {
2108 let internal_sample_rate = match bandwidth {
2109 Bandwidth::Narrowband => 8000,
2110 Bandwidth::Mediumband => 12000,
2111 Bandwidth::Wideband => 16000,
2112 _ => 16000,
2113 };
2114 if internal_sample_rate != self.prev_internal_rate
2115 || !self.silk_resampler.is_initialized()
2116 {
2117 self.silk_resampler
2118 .init(internal_sample_rate, self.sampling_rate);
2119 self.silk_resampler_2
2120 .init(internal_sample_rate, self.sampling_rate);
2121 }
2122 self.prev_internal_rate = internal_sample_rate;
2126
2127 let f5 = self.sampling_rate as usize / 200;
2132 let f2_5 = f5 / 2;
2133 let redundant_end_band = match bandwidth {
2134 Bandwidth::Narrowband => 13,
2135 Bandwidth::Mediumband | Bandwidth::Wideband => 17,
2136 _ => 21,
2137 };
2138 let window = modes::default_mode().window;
2139 let inc = (48000 / self.sampling_rate) as usize;
2140
2141 for (fi, payload) in frame_payloads.iter().enumerate() {
2142 let out_start = fi * sub_output_len;
2143 let flag = if payload.is_empty() {
2147 silk::decode_frame::FLAG_PACKET_LOST
2148 } else {
2149 silk::decode_frame::FLAG_DECODE_NORMAL
2150 };
2151 let mut rc = RangeCoder::new_decoder(payload);
2152 self.decode_silk_frames(
2153 &mut rc,
2154 flag,
2155 frame_duration_ms,
2156 internal_sample_rate,
2157 sub_frame_size,
2158 )?;
2159 output[out_start..out_start + sub_output_len]
2160 .copy_from_slice(&self.w_silk_out[..sub_output_len]);
2161
2162 let len = payload.len();
2175 let mut redundancy_bytes = 0usize;
2176 let mut celt_to_silk = false;
2177 let mut redundant = [0.0f32; REDUNDANT_MAX];
2178 let has_tail = !payload.is_empty() && rc.tell() + 17 <= (8 * len) as i32;
2179 if has_tail {
2180 celt_to_silk = rc.decode_bit_logp(1);
2181 redundancy_bytes = len - ((rc.tell() as usize + 7) >> 3);
2184 rc.storage -= redundancy_bytes as u32;
2187 if celt_to_silk {
2188 self.decode_redundant(
2191 &payload[len - redundancy_bytes..],
2192 redundant_end_band,
2193 f5,
2194 &mut redundant,
2195 );
2196 }
2197 }
2198 if fi == 0 {
2199 if has_tail {
2200 transition = false;
2202 } else if from_celt {
2203 self.conceal_celt_bridge()?;
2209 }
2210 }
2211 let ch = self.channels;
2212 if has_tail && !celt_to_silk && f5 > 0 && sub_output_len >= f5 * ch {
2213 self.celt_dec.reset_state();
2218 self.decode_redundant(
2219 &payload[len - redundancy_bytes..],
2220 redundant_end_band,
2221 f5,
2222 &mut redundant,
2223 );
2224 let at = out_start + (sub_frame_size - f2_5) * ch;
2225 let mut tail = [0.0f32; REDUNDANT_MAX];
2226 tail[..f2_5 * ch].copy_from_slice(&output[at..at + f2_5 * ch]);
2227 smooth_fade(
2228 &tail[..f2_5 * ch],
2229 &redundant[f2_5 * ch..f5 * ch],
2230 &mut output[at..at + f2_5 * ch],
2231 f2_5,
2232 ch,
2233 window,
2234 inc,
2235 );
2236 } else if has_tail
2237 && celt_to_silk
2238 && (self.prev_mode != Some(OpusMode::SilkOnly) || self.prev_redundancy)
2239 && f5 > 0
2240 && sub_output_len >= f5 * ch
2241 {
2242 output[out_start..out_start + f2_5 * ch]
2246 .copy_from_slice(&redundant[..f2_5 * ch]);
2247 let at = out_start + f2_5 * ch;
2248 let mut next = [0.0f32; REDUNDANT_MAX];
2249 next[..f2_5 * ch].copy_from_slice(&output[at..at + f2_5 * ch]);
2250 smooth_fade(
2251 &redundant[f2_5 * ch..f5 * ch],
2252 &next[..f2_5 * ch],
2253 &mut output[at..at + f2_5 * ch],
2254 f2_5,
2255 ch,
2256 window,
2257 inc,
2258 );
2259 }
2260 has_redundancy = has_tail && !celt_to_silk;
2261 }
2262 decoded_total
2263 }
2264
2265 OpusMode::CeltOnly => {
2266 let celt_end_band = self.celt_end_band_from_toc(toc);
2267
2268 for (fi, payload) in frame_payloads.iter().enumerate() {
2269 let mut rc = RangeCoder::new_decoder(payload);
2270 let total_bits = (payload.len() * 8) as i32;
2271 let needed = sub_frame_size * self.channels;
2272 let out_start = fi * needed;
2273 let out_end = (out_start + needed).min(output.len());
2274
2275 if output.len() < out_end {
2276 return Err("Output buffer too small");
2277 }
2278
2279 if self.channels == 1 {
2280 self.celt_dec.decode_from_range_coder_with_band_range(
2281 &mut rc,
2282 total_bits,
2283 sub_frame_size,
2284 &mut output[out_start..out_end],
2285 0,
2286 celt_end_band,
2287 );
2288 for sample in &mut output[out_start..out_end] {
2289 *sample = sample.clamp(-1.0, 1.0);
2290 }
2291 } else {
2292 self.celt_dec.decode_from_range_coder_with_band_range(
2293 &mut rc,
2294 total_bits,
2295 sub_frame_size,
2296 &mut self.w_celt_planar[..needed],
2297 0,
2298 celt_end_band,
2299 );
2300 for i in 0..sub_frame_size {
2301 for ch in 0..self.channels {
2302 let idx = out_start + i * self.channels + ch;
2303 output[idx] =
2304 self.w_celt_planar[ch * sub_frame_size + i].clamp(-1.0, 1.0);
2305 }
2306 }
2307 }
2308 }
2309 decoded_total
2310 }
2311
2312 OpusMode::Hybrid => {
2313 let internal_sample_rate = 16000;
2314 let celt_end_band = self.celt_end_band_from_toc(toc);
2315
2316 if internal_sample_rate != self.prev_internal_rate
2317 || !self.silk_resampler.is_initialized()
2318 {
2319 self.silk_resampler
2320 .init(internal_sample_rate, self.sampling_rate);
2321 self.silk_resampler_2
2322 .init(internal_sample_rate, self.sampling_rate);
2323 }
2324 self.prev_internal_rate = internal_sample_rate;
2325
2326 for (fi, payload) in frame_payloads.iter().enumerate() {
2327 let mut rc = RangeCoder::new_decoder(payload);
2328 let flag = if payload.is_empty() {
2332 silk::decode_frame::FLAG_PACKET_LOST
2333 } else {
2334 silk::decode_frame::FLAG_DECODE_NORMAL
2335 };
2336 self.decode_silk_frames(
2337 &mut rc,
2338 flag,
2339 frame_duration_ms,
2340 internal_sample_rate,
2341 sub_frame_size,
2342 )?;
2343 let silk_out_len = sub_frame_size * self.channels;
2344
2345 let mut len = payload.len();
2353 let mut redundancy = false;
2354 let mut celt_to_silk = false;
2355 let mut redundancy_bytes = 0usize;
2356 if !payload.is_empty() && rc.tell() + 17 + 20 <= (8 * len) as i32 {
2357 redundancy = rc.decode_bit_logp(12);
2358 if redundancy {
2359 celt_to_silk = rc.decode_bit_logp(1);
2360 redundancy_bytes = rc.dec_uint(256) as usize + 2;
2361 if redundancy_bytes > len
2362 || ((len - redundancy_bytes) * 8) < rc.tell() as usize
2363 {
2364 len = 0;
2365 redundancy_bytes = 0;
2366 redundancy = false;
2367 } else {
2368 len -= redundancy_bytes;
2369 rc.storage -= redundancy_bytes as u32;
2370 }
2371 }
2372 }
2373 has_redundancy = redundancy && !celt_to_silk;
2376 let f5 = self.sampling_rate as usize / 200;
2377 let f2_5 = f5 / 2;
2378 let mut redundant = [0.0f32; REDUNDANT_MAX];
2379 if fi == 0 {
2380 if redundancy {
2381 transition = false;
2382 } else if from_celt {
2383 self.conceal_celt_bridge()?;
2384 }
2385 }
2386 if redundancy && celt_to_silk {
2387 self.decode_redundant(
2388 &payload[len..len + redundancy_bytes],
2389 celt_end_band,
2390 f5,
2391 &mut redundant,
2392 );
2393 }
2394 if fi == 0 && mode_transition {
2395 self.celt_dec.reset_state();
2396 }
2397
2398 let total_bits = (len * 8) as i32;
2399 if len <= 1 {
2400 self.w_celt_out[..silk_out_len].fill(0.0);
2401 } else {
2402 let (celt_dec, celt_planar) = (
2403 state_mut(&mut self.celt_dec),
2404 state_mut(&mut self.w_celt_planar),
2405 );
2406 celt_dec.decode_from_range_coder_with_band_range(
2407 &mut rc,
2408 total_bits,
2409 sub_frame_size,
2410 &mut celt_planar[..silk_out_len],
2411 17,
2412 celt_end_band,
2413 );
2414
2415 if self.channels == 1 {
2416 self.w_celt_out[..silk_out_len]
2417 .copy_from_slice(&self.w_celt_planar[..silk_out_len]);
2418 } else {
2419 for i in 0..sub_frame_size {
2420 for ch in 0..self.channels {
2421 self.w_celt_out[i * self.channels + ch] =
2422 self.w_celt_planar[ch * sub_frame_size + i];
2423 }
2424 }
2425 }
2426 }
2427
2428 let out_start = fi * silk_out_len;
2429 let total = silk_out_len.min(output.len() - out_start);
2430 for j in 0..total {
2431 output[out_start + j] =
2432 (self.w_silk_out[j] + self.w_celt_out[j]).clamp(-1.0, 1.0);
2433 }
2434
2435 let ch = self.channels;
2442 let use_redundant = !celt_to_silk
2443 || self.prev_mode != Some(OpusMode::SilkOnly)
2444 || self.prev_redundancy;
2445 if redundancy && use_redundant && f5 > 0 && total >= f5 * ch {
2446 let window = modes::default_mode().window;
2447 let inc = (48000 / self.sampling_rate) as usize;
2448 if !celt_to_silk {
2449 self.celt_dec.reset_state();
2450 self.decode_redundant(
2451 &payload[len..len + redundancy_bytes],
2452 celt_end_band,
2453 f5,
2454 &mut redundant,
2455 );
2456 let at = out_start + (sub_frame_size - f2_5) * ch;
2457 let mut tail = [0.0f32; REDUNDANT_MAX];
2458 tail[..f2_5 * ch].copy_from_slice(&output[at..at + f2_5 * ch]);
2459 smooth_fade(
2460 &tail[..f2_5 * ch],
2461 &redundant[f2_5 * ch..f5 * ch],
2462 &mut output[at..at + f2_5 * ch],
2463 f2_5,
2464 ch,
2465 window,
2466 inc,
2467 );
2468 } else {
2469 output[out_start..out_start + f2_5 * ch]
2470 .copy_from_slice(&redundant[..f2_5 * ch]);
2471 let at = out_start + f2_5 * ch;
2472 let mut next = [0.0f32; REDUNDANT_MAX];
2473 next[..f2_5 * ch].copy_from_slice(&output[at..at + f2_5 * ch]);
2474 smooth_fade(
2475 &redundant[f2_5 * ch..f5 * ch],
2476 &next[..f2_5 * ch],
2477 &mut output[at..at + f2_5 * ch],
2478 f2_5,
2479 ch,
2480 window,
2481 inc,
2482 );
2483 }
2484 }
2485 }
2486 decoded_total
2487 }
2488 };
2489
2490 let f2_5 = self.sampling_rate as usize / 400;
2496 let f5 = f2_5 * 2;
2497 if transition && f5 > 0 && decoded_total >= f5 {
2498 let window = modes::default_mode().window;
2499 let inc = (48000 / self.sampling_rate) as usize;
2500 let f2_5_ch = f2_5 * self.channels;
2501 let f5_ch = f5 * self.channels;
2502 output[..f2_5_ch].copy_from_slice(&self.prev_pcm_tail[..f2_5_ch]);
2504 let new_mid: FixedVec<f32, OPUS_PCM_TAIL> =
2506 FixedVec::from_slice(&output[f2_5_ch..f5_ch]);
2507 smooth_fade(
2508 &self.prev_pcm_tail[f2_5_ch..f5_ch],
2509 &new_mid,
2510 &mut output[f2_5_ch..f5_ch],
2511 f2_5,
2512 self.channels,
2513 window,
2514 inc,
2515 );
2516 }
2517
2518 self.save_pcm_tail(output, decoded_total);
2519 self.prev_mode = Some(mode);
2520 self.prev_redundancy = has_redundancy;
2521 Ok(decoded_total)
2522 }
2523
2524 fn decode_lost(
2532 &mut self,
2533 toc: Option<u8>,
2534 frame_size: usize,
2535 output: &mut [f32],
2536 ) -> Result<usize, &'static str> {
2537 let f2_5 = self.sampling_rate as usize / 400;
2538 let (f5, f10, f20) = (2 * f2_5, 4 * f2_5, 8 * f2_5);
2539
2540 let total = match toc {
2541 None => {
2542 if frame_size == 0 || !frame_size.is_multiple_of(f2_5) {
2543 return Err("Lost frame: frame_size must be a multiple of 2.5 ms");
2544 }
2545 frame_size
2546 }
2547 Some(toc) => {
2548 let count = match toc & 0x03 {
2551 0 => 1,
2552 1 | 2 => 2,
2553 _ => return Err("Code 3 packet too short"),
2554 };
2555 let per_frame = frame_samples_from_toc(toc, self.sampling_rate)
2556 .ok_or("Invalid TOC for sampling rate")?;
2557 let total = per_frame * count;
2558 if frame_size < total {
2559 return Err("frame_size too small for packet");
2560 }
2561 total
2562 }
2563 };
2564 let channels = self.channels;
2565 if output.len() < total * channels {
2566 return Err("Output buffer too small for packet");
2567 }
2568 output[total * channels..].fill(0.0);
2569
2570 let mut pos = 0usize;
2571 while pos < total {
2572 let remaining = total - pos;
2573 let dst = &mut output[pos * channels..total * channels];
2574 let produced = match self.prev_mode {
2575 None => {
2576 dst.fill(0.0);
2577 remaining
2578 }
2579 Some(OpusMode::CeltOnly) => {
2580 let n = [f20, f10, f5, f2_5]
2583 .into_iter()
2584 .find(|&c| c <= remaining)
2585 .unwrap_or(f2_5);
2586 self.conceal_celt(n, 0)?;
2587 for (d, s) in dst.iter_mut().zip(&self.w_celt_out[..n * channels]) {
2588 *d = s.clamp(-1.0, 1.0);
2589 }
2590 n
2591 }
2592 Some(prev @ (OpusMode::SilkOnly | OpusMode::Hybrid)) => {
2593 let (ms, n) = if remaining >= f20 {
2596 (20, f20)
2597 } else {
2598 (10, f10)
2599 };
2600 let hybrid = prev == OpusMode::Hybrid;
2601 let rate = if hybrid {
2602 16000
2603 } else {
2604 self.prev_internal_rate
2605 };
2606 let mut rc = RangeCoder::new_decoder(&[]);
2607 self.decode_silk_frames(
2608 &mut rc,
2609 silk::decode_frame::FLAG_PACKET_LOST,
2610 ms,
2611 rate,
2612 n,
2613 )?;
2614 if hybrid {
2615 self.conceal_celt(n, 17)?;
2616 } else {
2617 self.w_celt_out[..n * channels].fill(0.0);
2618 }
2619 let take = n.min(remaining);
2620 for (i, d) in dst[..take * channels].iter_mut().enumerate() {
2621 *d = (self.w_silk_out[i] + self.w_celt_out[i]).clamp(-1.0, 1.0);
2622 }
2623 take
2624 }
2625 };
2626 pos += produced;
2627 }
2628
2629 self.save_pcm_tail(output, total);
2630 Ok(total)
2631 }
2632
2633 fn conceal_celt_bridge(&mut self) -> Result<(), &'static str> {
2636 let f5 = self.sampling_rate as usize / 200;
2637 if f5 == 0 {
2638 return Ok(());
2639 }
2640 self.conceal_celt(f5, 0)?;
2641 let n = (f5 * self.channels).min(self.prev_pcm_tail.len());
2642 for i in 0..n {
2643 self.prev_pcm_tail[i] = self.w_celt_out[i].clamp(-1.0, 1.0);
2644 }
2645 Ok(())
2646 }
2647
2648 fn conceal_celt(&mut self, n: usize, start_band: usize) -> Result<(), &'static str> {
2653 let len = n * self.channels;
2654 let end_band = modes::default_mode().eff_ebands;
2655 let mut rc = RangeCoder::new_decoder(&[]);
2656 let decoded = {
2657 let (celt_dec, planar) = (
2658 state_mut(&mut self.celt_dec),
2659 state_mut(&mut self.w_celt_planar),
2660 );
2661 celt_dec.decode_from_range_coder_with_band_range(
2662 &mut rc,
2663 0,
2664 n,
2665 &mut planar[..len],
2666 start_band,
2667 end_band,
2668 )
2669 };
2670 if decoded != n {
2671 return Err("CELT concealment failed");
2672 }
2673 for i in 0..n {
2674 for ch in 0..self.channels {
2675 self.w_celt_out[i * self.channels + ch] = self.w_celt_planar[ch * n + i];
2676 }
2677 }
2678 Ok(())
2679 }
2680
2681 fn save_pcm_tail(&mut self, output: &[f32], decoded: usize) {
2683 let tail_len = (self.sampling_rate as usize / 200) * self.channels;
2684 let out_total = decoded * self.channels;
2685 if out_total >= tail_len && tail_len <= self.prev_pcm_tail.len() {
2686 self.prev_pcm_tail[..tail_len]
2687 .copy_from_slice(&output[out_total - tail_len..out_total]);
2688 }
2689 }
2690}
2691
2692impl OpusDecoder {
2693 fn decode_silk_frames(
2701 &mut self,
2702 rc: &mut RangeCoder,
2703 lost_flag: i32,
2704 duration_ms: i32,
2705 internal_rate: i32,
2706 api_len: usize,
2707 ) -> Result<(), &'static str> {
2708 let internal_frame_size = (duration_ms * internal_rate / 1000) as usize;
2709 let pcm_i16_len = internal_frame_size * self.channels;
2710 debug_assert!(pcm_i16_len <= self.w_pcm_i16.len());
2711 let out_len = api_len * self.channels;
2712 self.w_silk_out[..out_len].fill(0.0);
2713
2714 let mut frame_pos = 0usize; let mut new_packet = true;
2716 while frame_pos < internal_frame_size {
2717 let prev_channels = self.silk_dec.n_channels_internal as usize;
2720 let stream_channels = if lost_flag == silk::decode_frame::FLAG_PACKET_LOST {
2721 prev_channels
2722 } else {
2723 self.stream_channels
2724 };
2725 if self.channels == 2 && stream_channels == 2 && prev_channels == 1 {
2731 self.silk_resampler_2 = self.silk_resampler.clone();
2732 }
2733 let stereo_to_mono = stream_channels == 1
2734 && prev_channels == 2
2735 && internal_rate == self.silk_dec.sample_rate()
2736 && matches!(
2737 self.prev_mode,
2738 Some(OpusMode::SilkOnly) | Some(OpusMode::Hybrid)
2739 );
2740 let ret = {
2741 let (silk_dec, pcm_i16) = (
2742 state_mut(&mut self.silk_dec),
2743 state_mut(&mut self.w_pcm_i16),
2744 );
2745 silk_dec.decode_with_channels(
2746 rc,
2747 &mut pcm_i16[..pcm_i16_len],
2748 lost_flag,
2749 new_packet,
2750 duration_ms,
2751 internal_rate,
2752 stream_channels as i32,
2753 )
2754 };
2755 new_packet = false;
2756
2757 if ret < 0 {
2758 return Err("SILK decoding failed");
2759 }
2760 let decoded_samples = ret as usize;
2761 if decoded_samples == 0 {
2762 break;
2763 }
2764
2765 let resampled_len =
2774 decoded_samples * self.sampling_rate as usize / internal_rate as usize;
2775 let api_pos = frame_pos * self.sampling_rate as usize / internal_rate as usize;
2776 let copy_len = resampled_len.min(api_len - api_pos);
2777 debug_assert!(resampled_len * self.channels <= self.w_pcm_resampled.len());
2778 {
2780 let (res, inp, out) = (
2781 &mut self.silk_resampler,
2782 state_ref(&self.w_pcm_i16),
2783 state_mut(&mut self.w_pcm_resampled),
2784 );
2785 res.process(
2786 &mut out[..resampled_len],
2787 &inp[..decoded_samples],
2788 decoded_samples as i32,
2789 );
2790 }
2791 if self.channels == 2 {
2794 let (res, inp, out) = (
2795 &mut self.silk_resampler_2,
2796 state_ref(&self.w_pcm_i16),
2797 state_mut(&mut self.w_pcm_resampled),
2798 );
2799 if stream_channels == 2 || stereo_to_mono {
2800 let src = if stream_channels == 2 {
2801 &inp[decoded_samples..2 * decoded_samples]
2802 } else {
2803 &inp[..decoded_samples]
2804 };
2805 res.process(
2806 &mut out[resampled_len..2 * resampled_len],
2807 src,
2808 decoded_samples as i32,
2809 );
2810 } else {
2811 out.copy_within(..resampled_len, resampled_len);
2812 }
2813 }
2814 for i in 0..copy_len {
2815 for ch in 0..self.channels {
2816 let v = self.w_pcm_resampled[ch * resampled_len + i] as f32 / 32768.0;
2817 let idx = (api_pos + i) * self.channels + ch;
2818 if idx < out_len {
2819 self.w_silk_out[idx] = v;
2820 }
2821 }
2822 }
2823 frame_pos += decoded_samples;
2824 }
2825 Ok(())
2826 }
2827
2828 #[inline(always)]
2829 fn celt_end_band_from_toc(&self, toc: u8) -> usize {
2830 let mode = modes::default_mode();
2831 let top = mode.eff_ebands;
2832 if mode_from_toc(toc) == OpusMode::CeltOnly && toc >= 0x80 {
2833 const FROM_OPUS_TABLE: [u8; 16] = [
2834 0x80, 0x88, 0x90, 0x98, 0x40, 0x48, 0x50, 0x58, 0x20, 0x28, 0x30, 0x38, 0x00, 0x08,
2835 0x10, 0x18,
2836 ];
2837 let idx = ((toc >> 3) - 16) as usize;
2838 let data0 = FROM_OPUS_TABLE[idx] | (toc & 0x7);
2839 let trim = (data0 >> 5) as usize;
2840 return top.saturating_sub(2 * trim).max(1);
2841 }
2842 if mode_from_toc(toc) == OpusMode::Hybrid && (toc >> 3) < 14 {
2845 return top.saturating_sub(2).max(1);
2846 }
2847 top
2848 }
2849}
2850
2851fn frame_rate_from_params(sampling_rate: i32, frame_size: usize) -> Option<i32> {
2852 let frame_size = frame_size as i32;
2853 if frame_size <= 0 {
2854 return None;
2855 }
2856 let fs = sampling_rate;
2862 let valid = frame_size == fs / 400
2863 || frame_size == fs / 200
2864 || frame_size == fs / 100
2865 || frame_size == fs / 50
2866 || frame_size == fs / 25
2867 || 50 * frame_size == 3 * fs;
2868 if !valid {
2869 return None;
2870 }
2871 Some(fs / frame_size)
2872}
2873
2874fn gen_toc(mode: OpusMode, frame_rate: i32, bandwidth: Bandwidth, channels: usize) -> u8 {
2875 let mut rate = frame_rate;
2876 let mut period = 0;
2877 while rate < 400 {
2878 rate <<= 1;
2879 period += 1;
2880 }
2881
2882 let mut toc = match mode {
2883 OpusMode::SilkOnly => {
2884 let bw = (bandwidth as i32 - Bandwidth::Narrowband as i32) << 5;
2885 let per = (period - 2) << 3;
2886 (bw | per) as u8
2887 }
2888 OpusMode::CeltOnly => {
2889 let mut tmp = bandwidth as i32 - Bandwidth::Mediumband as i32;
2890 if tmp < 0 {
2891 tmp = 0;
2892 }
2893 let per = period << 3;
2894 (0x80 | (tmp << 5) | per) as u8
2895 }
2896 OpusMode::Hybrid => {
2897 let base_config = if bandwidth == Bandwidth::Superwideband {
2898 12
2899 } else {
2900 14
2901 };
2902 let period_offset = if frame_rate >= 100 { 0 } else { 1 };
2903 ((base_config + period_offset) << 3) as u8
2904 }
2905 };
2906
2907 if channels == 2 {
2908 toc |= 0x04;
2909 }
2910 toc
2911}
2912
2913fn mode_from_toc(toc: u8) -> OpusMode {
2914 if toc & 0x80 != 0 {
2915 OpusMode::CeltOnly
2916 } else if toc & 0x60 == 0x60 {
2917 OpusMode::Hybrid
2918 } else {
2919 OpusMode::SilkOnly
2920 }
2921}
2922
2923fn bandwidth_from_toc(toc: u8) -> Bandwidth {
2924 let mode = mode_from_toc(toc);
2925 match mode {
2926 OpusMode::SilkOnly => {
2927 let bw_bits = (toc >> 5) & 0x03;
2928 match bw_bits {
2929 0 => Bandwidth::Narrowband,
2930 1 => Bandwidth::Mediumband,
2931 2 => Bandwidth::Wideband,
2932 _ => Bandwidth::Wideband,
2933 }
2934 }
2935 OpusMode::Hybrid => {
2936 let bw_bit = (toc >> 4) & 0x01;
2937 if bw_bit == 0 {
2938 Bandwidth::Superwideband
2939 } else {
2940 Bandwidth::Fullband
2941 }
2942 }
2943 OpusMode::CeltOnly => {
2944 let bw_bits = (toc >> 5) & 0x03;
2945 match bw_bits {
2946 0 => Bandwidth::Mediumband,
2947 1 => Bandwidth::Wideband,
2948 2 => Bandwidth::Superwideband,
2949 3 => Bandwidth::Fullband,
2950 _ => Bandwidth::Fullband,
2951 }
2952 }
2953 }
2954}
2955
2956fn frame_duration_ms_from_toc(toc: u8) -> i32 {
2957 let mode = mode_from_toc(toc);
2958 match mode {
2959 OpusMode::SilkOnly => {
2960 let config = (toc >> 3) & 0x03;
2961 match config {
2962 0 => 10,
2963 1 => 20,
2964 2 => 40,
2965 3 => 60,
2966 _ => 20,
2967 }
2968 }
2969 OpusMode::Hybrid => {
2970 let config = (toc >> 3) & 0x01;
2971 if config == 0 { 10 } else { 20 }
2972 }
2973 OpusMode::CeltOnly => {
2974 let config = (toc >> 3) & 0x03;
2975 match config {
2976 0 => 2,
2977 1 => 5,
2978 2 => 10,
2979 3 => 20,
2980 _ => 20,
2981 }
2982 }
2983 }
2984}
2985
2986fn frame_samples_from_toc(toc: u8, sampling_rate: i32) -> Option<usize> {
2990 let mode = mode_from_toc(toc);
2991 match mode {
2992 OpusMode::CeltOnly => {
2993 let period = ((toc >> 3) & 0x03) as i32;
2994 let frame_rate = 400 >> period;
2995 if frame_rate == 0 || sampling_rate % frame_rate != 0 {
2996 return None;
2997 }
2998 Some((sampling_rate / frame_rate) as usize)
2999 }
3000 OpusMode::SilkOnly | OpusMode::Hybrid => {
3001 let duration_ms = frame_duration_ms_from_toc(toc);
3002 Some((sampling_rate as i64 * duration_ms as i64 / 1000) as usize)
3003 }
3004 }
3005}
3006
3007fn channels_from_toc(toc: u8) -> usize {
3008 if toc & 0x04 != 0 { 2 } else { 1 }
3009}
3010
3011const REDUNDANT_MAX: usize = 480;
3013
3014impl OpusDecoder {
3015 fn decode_redundant(&mut self, data: &[u8], end_band: usize, f5: usize, out: &mut [f32]) {
3019 let n = f5 * self.channels;
3020 if data.is_empty() || n > REDUNDANT_MAX {
3021 return;
3022 }
3023 let mut planar = [0.0f32; REDUNDANT_MAX];
3024 let mut rrc = RangeCoder::new_decoder(data);
3025 self.celt_dec.decode_from_range_coder_with_band_range(
3026 &mut rrc,
3027 (data.len() * 8) as i32,
3028 f5,
3029 &mut planar[..n],
3030 0,
3031 end_band,
3032 );
3033 if self.channels == 1 {
3034 out[..n].copy_from_slice(&planar[..n]);
3035 } else {
3036 for i in 0..f5 {
3037 for c in 0..self.channels {
3038 out[i * self.channels + c] = planar[c * f5 + i];
3039 }
3040 }
3041 }
3042 }
3043}
3044
3045fn smooth_fade(
3048 in1: &[f32],
3049 in2: &[f32],
3050 out: &mut [f32],
3051 overlap: usize,
3052 channels: usize,
3053 window: &[f32],
3054 inc: usize,
3055) {
3056 for c in 0..channels {
3057 for i in 0..overlap {
3058 let wi = i * inc;
3059 if wi >= window.len() {
3060 break;
3061 }
3062 let w = window[wi] * window[wi];
3063 out[i * channels + c] = w * in2[i * channels + c] + (1.0 - w) * in1[i * channels + c];
3064 }
3065 }
3066}
3067
3068pub(crate) fn parse_frame_size(data: &[u8]) -> Result<(usize, usize), &'static str> {
3076 let first = *data.first().ok_or("truncated frame length")? as usize;
3077 if first < 252 {
3078 Ok((first, 1))
3079 } else {
3080 let second = *data.get(1).ok_or("truncated frame length")? as usize;
3081 Ok((second * 4 + first, 2))
3082 }
3083}
3084
3085#[cfg(all(test, feature = "std"))]
3086mod tests {
3087 use super::*;
3088
3089 fn frame_size_from_toc(toc: u8, sampling_rate: i32) -> Option<usize> {
3090 let mode = mode_from_toc(toc);
3091 match mode {
3092 OpusMode::CeltOnly => {
3093 let period = ((toc >> 3) & 0x03) as i32;
3094 let frame_rate = 400 >> period;
3095 if frame_rate == 0 || sampling_rate % frame_rate != 0 {
3096 return None;
3097 }
3098 Some((sampling_rate / frame_rate) as usize)
3099 }
3100 OpusMode::SilkOnly => {
3101 let duration_ms = frame_duration_ms_from_toc(toc);
3102 Some((sampling_rate as i64 * duration_ms as i64 / 1000) as usize)
3103 }
3104 OpusMode::Hybrid => {
3105 let duration_ms = frame_duration_ms_from_toc(toc);
3106 Some((sampling_rate as i64 * duration_ms as i64 / 1000) as usize)
3107 }
3108 }
3109 }
3110
3111 #[test]
3112 fn gen_toc_matches_celt_reference_values() {
3113 let sampling_rate = 48_000;
3114 let cases = [
3115 (120usize, 0xE0u8),
3116 (240usize, 0xE8u8),
3117 (480usize, 0xF0u8),
3118 (960usize, 0xF8u8),
3119 ];
3120
3121 for (frame_size, expected_toc) in cases {
3122 let frame_rate = frame_rate_from_params(sampling_rate, frame_size).unwrap();
3123 let toc = gen_toc(OpusMode::CeltOnly, frame_rate, Bandwidth::Fullband, 1);
3124 assert_eq!(
3125 toc, expected_toc,
3126 "frame_size {} expected TOC {:02X} got {:02X}",
3127 frame_size, expected_toc, toc
3128 );
3129 let decoded_size = frame_size_from_toc(toc, sampling_rate).unwrap();
3130 assert_eq!(decoded_size, frame_size);
3131 }
3132
3133 let stereo_toc = gen_toc(
3134 OpusMode::CeltOnly,
3135 frame_rate_from_params(sampling_rate, 960).unwrap(),
3136 Bandwidth::Fullband,
3137 2,
3138 );
3139 assert_eq!(channels_from_toc(stereo_toc), 2);
3140 }
3141
3142 #[test]
3143 fn test_celt_decoder_large_frame_sizes() {
3144 let sampling_rate = 48000;
3145 let channels = 1;
3146
3147 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
3148
3149 let frame_sizes = [120, 240, 480, 960];
3150
3151 for frame_size in frame_sizes {
3152 let toc = gen_toc(
3153 OpusMode::CeltOnly,
3154 frame_rate_from_params(sampling_rate, frame_size).unwrap(),
3155 Bandwidth::Fullband,
3156 channels,
3157 );
3158 let packet = [toc, 0, 0, 0, 0];
3159
3160 let mut output = vec![0.0f32; frame_size * channels];
3161
3162 let _ = decoder.decode(&packet, frame_size, &mut output);
3163 }
3164
3165 let channels = 2;
3166 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
3167
3168 for frame_size in frame_sizes {
3169 let toc = gen_toc(
3170 OpusMode::CeltOnly,
3171 frame_rate_from_params(sampling_rate, frame_size).unwrap(),
3172 Bandwidth::Fullband,
3173 channels,
3174 );
3175 let packet = [toc, 0, 0, 0, 0];
3176
3177 let mut output = vec![0.0f32; frame_size * channels];
3178 let _ = decoder.decode(&packet, frame_size, &mut output);
3179 }
3180 }
3181
3182 #[test]
3183 fn test_celt_decoder_edge_case_frame_sizes() {
3184 let sampling_rate = 48000;
3185 let channels = 1;
3186 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
3187
3188 let edge_sizes = [2048, 2167, 2168, 2169, 2880, 3072];
3189
3190 for frame_size in edge_sizes {
3191 let mut output = vec![0.0f32; frame_size * channels];
3192
3193 let _ = decoder.decode(&[0x80, 0, 0, 0], frame_size, &mut output);
3194 }
3195 }
3196
3197 #[test]
3204 fn test_invalid_small_frame_size_returns_error_not_panic() {
3205 let mut enc = OpusEncoder::new(48000, 2, Application::Voip).unwrap();
3206 enc.bitrate_bps = 64000;
3207 enc.complexity = 5;
3208 enc.use_cbr = true;
3209
3210 let input = vec![0.0f32; 48 * 2]; let mut output = vec![0u8; 256];
3213
3214 let result = enc.encode(&input, 48, &mut output);
3215 assert!(
3216 result.is_err(),
3217 "encode with invalid frame_size=48 should return Err, not panic"
3218 );
3219 }
3220
3221 #[test]
3224 fn test_invalid_small_frame_size_audio_application_returns_error() {
3225 let mut enc = OpusEncoder::new(48000, 1, Application::Audio).unwrap();
3226 let input = vec![0.0f32; 48];
3227 let mut output = vec![0u8; 256];
3228
3229 let result = enc.encode(&input, 48, &mut output);
3230 assert!(
3231 result.is_err(),
3232 "Audio/48kHz encoder with frame_size=48 should return Err"
3233 );
3234 }
3235}