1#![allow(unsafe_op_in_unsafe_fn)]
2#![allow(clippy::too_many_arguments)]
3#![allow(clippy::needless_range_loop)]
4
5pub mod analysis;
6pub mod analysis_data;
7pub mod bands;
8pub mod celt;
9pub mod celt_lpc;
10pub mod hp_cutoff;
11pub mod kiss_fft;
12pub mod mdct;
13pub mod modes;
14pub mod parallel;
15pub mod pitch;
16pub mod prof;
17pub mod pvq;
18pub mod quant_bands;
19pub mod range_coder;
20pub mod repacketizer;
21pub mod multistream;
22pub mod rate;
23pub mod silk;
24
25pub use silk::{SilkResampler, SilkResamplerDown1_3, SilkResamplerDown1_6};
26
27pub use celt::{CeltDecoder, CeltEncoder};
28use hp_cutoff::hp_cutoff;
29use range_coder::RangeCoder;
30use silk::control_codec::silk_control_encoder;
31use silk::enc_api::silk_encode;
32use silk::init_encoder::silk_init_encoder;
33use silk::lin2log::silk_lin2log;
34use silk::log2lin::silk_log2lin;
35use silk::macros::*;
36use silk::structs::SilkEncoderState;
37
38#[derive(Debug, Clone, Copy, PartialEq, Eq)]
39pub enum Application {
40 Voip = 2048,
41 Audio = 2049,
42 RestrictedLowDelay = 2051,
43}
44
45#[derive(Debug, Clone, Copy, PartialEq, Eq)]
48pub enum SignalType {
49 Voice,
50 Music,
51}
52
53#[derive(Debug, Clone, Copy, PartialEq, Eq)]
54pub enum Bandwidth {
55 Auto = -1000,
56 Narrowband = 1101,
57 Mediumband = 1102,
58 Wideband = 1103,
59 Superwideband = 1104,
60 Fullband = 1105,
61}
62
63#[derive(Debug, Clone, Copy, PartialEq, Eq)]
64enum OpusMode {
65 SilkOnly,
66 Hybrid,
67 CeltOnly,
68}
69
70pub struct OpusEncoder {
71 celt_enc: CeltEncoder,
72 silk_enc: Box<SilkEncoderState>,
73 application: Application,
74 sampling_rate: i32,
75 channels: usize,
76 bandwidth: Bandwidth,
77 pub bitrate_bps: i32,
78 pub complexity: i32,
79 pub use_cbr: bool,
80
81 pub use_inband_fec: bool,
82
83 pub use_dtx: bool,
86 nb_no_activity_ms_q1: i32,
88 range_final: u32,
91
92 pub packet_loss_perc: i32,
93 silk_initialized: bool,
94 mode: OpusMode,
95 prev_enc_mode: Option<OpusMode>,
96
97 variable_hp_smth2_q15: i32,
98 auto_bandwidth: i32,
101 first_frame: bool,
102 pub force_bandwidth: Option<Bandwidth>,
104 pub signal_type: Option<SignalType>,
106 pub max_bandwidth: Bandwidth,
108 tonality: analysis::TonalityAnalysisState,
111 analysis_kfft: Option<kiss_fft::KissFftState>,
112 pub lsb_depth: i32,
115 voice_ratio: i32,
117 detected_bandwidth: i32,
118 hp_mem: Vec<i32>,
119
120 buf_filtered: Vec<i16>,
121 buf_silk_input: Vec<i16>,
122 buf_stereo_mid: Vec<i16>,
123 buf_stereo_side: Vec<i16>,
124 buf_celt_input: Vec<f32>,
125 down2_state_first: [i32; 2],
126 down2_state_second: [i32; 2],
127 down2_3_state: [i32; 6],
128 down_1_3_state: silk::resampler::SilkResamplerDown1_3,
129 down2_3_state_r: [i32; 6],
130 down_1_3_state_r: silk::resampler::SilkResamplerDown1_3,
131 down_fir_l: Option<silk::resampler::SilkDownFirResampler>,
132 down_fir_r: Option<silk::resampler::SilkDownFirResampler>,
133 silk_prefill_tail: Vec<i16>,
136 silk_prefill_pending: bool,
137 buf_left: Vec<i16>,
138 buf_right: Vec<i16>,
139 celt_prefill_tail: Vec<f32>,
142
143 rc: RangeCoder,
144
145 gate_tap: Option<std::io::BufWriter<std::fs::File>>,
153 gate_clip: String,
155 gate_frame: u64,
157 force_mode: Option<OpusMode>,
161 pub mode_dwell: u32,
168 mode_dwell_run: u32,
170 analysis_warmup: u32,
182 analysis_frames: u32,
184}
185
186const MONO_VOICE_BANDWIDTH_THRESHOLDS: [i32; 8] = [9000, 700, 9000, 700, 13500, 1000, 14000, 2000];
189const MONO_MUSIC_BANDWIDTH_THRESHOLDS: [i32; 8] = [9000, 700, 9000, 700, 11000, 1000, 12000, 2000];
190const STEREO_VOICE_BANDWIDTH_THRESHOLDS: [i32; 8] = [9000, 700, 9000, 700, 13500, 1000, 14000, 2000];
191const STEREO_MUSIC_BANDWIDTH_THRESHOLDS: [i32; 8] = [9000, 700, 9000, 700, 11000, 1000, 12000, 2000];
192
193fn reconcile_bandwidth(mode: OpusMode, bw: Bandwidth) -> Bandwidth {
198 match mode {
199 OpusMode::CeltOnly if bw == Bandwidth::Mediumband => Bandwidth::Narrowband,
200 OpusMode::SilkOnly
201 if matches!(bw, Bandwidth::Superwideband | Bandwidth::Fullband) =>
202 {
203 Bandwidth::Wideband
204 }
205 OpusMode::Hybrid
206 if !matches!(bw, Bandwidth::Superwideband | Bandwidth::Fullband) =>
207 {
208 Bandwidth::Superwideband
209 }
210 _ => bw,
211 }
212}
213
214fn compute_equiv_rate(
215 bitrate: i32,
216 channels: usize,
217 frame_rate: i32,
218 vbr: bool,
219 complexity: i32,
220 loss: i32,
221) -> i32 {
222 let mut equiv = bitrate;
223 if frame_rate > 50 {
224 equiv -= (40 * channels as i32 + 20) * (frame_rate - 50);
225 }
226 if !vbr {
227 equiv -= equiv / 12;
228 }
229 equiv = equiv * (90 + complexity) / 100;
230 if loss > 0 {
231 equiv -= equiv * loss / (12 * loss + 20);
232 }
233 equiv
234}
235
236fn compute_mode_threshold(
237 application: Application,
238 channels: usize,
239 prev_was_celt: bool,
240 has_prev_mode: bool,
241 voice_est: i32,
242) -> i32 {
243 let mode_voice = if channels == 1 { 64000 } else { 44000 };
244 let mode_music = 10000;
245
246 let diff = mode_voice - mode_music;
247 let offset = (voice_est * voice_est * diff) >> 14;
248 let mut threshold = mode_music + offset;
249
250 if application == Application::Voip {
251 threshold += 8000;
252 }
253
254 if has_prev_mode {
255 if prev_was_celt {
256 threshold -= 4000;
257 } else {
258 threshold += 4000;
259 }
260 }
261
262 if application == Application::RestrictedLowDelay {
263 threshold = 0;
264 }
265
266 threshold
267}
268
269fn compute_silk_rate_for_hybrid(
270 rate_bps: i32,
271 bandwidth: Bandwidth,
272 frame20ms: bool,
273 vbr: bool,
274) -> i32 {
275 const RATE_TABLE: &[(i32, i32, i32)] = &[
276 (0, 0, 0),
277 (12000, 10000, 10000),
278 (16000, 13500, 13500),
279 (20000, 16000, 16000),
280 (24000, 18000, 18000),
281 (32000, 22000, 22000),
282 (64000, 38000, 38000),
283 ];
284 let n = RATE_TABLE.len();
285 let mut i = 1;
286 while i < n && RATE_TABLE[i].0 <= rate_bps {
287 i += 1;
288 }
289 let mut silk_rate = if i == n {
290 let (x_last, r10_last, r20_last) = RATE_TABLE[n - 1];
291 let base = if frame20ms { r20_last } else { r10_last };
292 base + (rate_bps - x_last) / 2
293 } else {
294 let (x0, lo10, lo20) = RATE_TABLE[i - 1];
295 let (x1, hi10, hi20) = RATE_TABLE[i];
296 let (lo, hi) = if frame20ms {
297 (lo20, hi20)
298 } else {
299 (lo10, hi10)
300 };
301 (lo * (x1 - rate_bps) + hi * (rate_bps - x0)) / (x1 - x0)
302 };
303 if !vbr {
307 silk_rate += 100;
308 }
309 if bandwidth == Bandwidth::Superwideband {
310 silk_rate += 300;
311 }
312 silk_rate
313}
314
315#[cfg(test)]
316mod reconcile_bandwidth_tests {
317 use super::{reconcile_bandwidth, Bandwidth, OpusMode};
318
319 #[test]
320 fn celt_maps_mediumband_down_to_narrowband() {
321 assert_eq!(
323 reconcile_bandwidth(OpusMode::CeltOnly, Bandwidth::Mediumband),
324 Bandwidth::Narrowband
325 );
326 }
327
328 #[test]
329 fn celt_leaves_every_other_bandwidth_alone() {
330 for bw in [
331 Bandwidth::Narrowband,
332 Bandwidth::Wideband,
333 Bandwidth::Superwideband,
334 Bandwidth::Fullband,
335 ] {
336 assert_eq!(reconcile_bandwidth(OpusMode::CeltOnly, bw), bw);
337 }
338 }
339
340 #[test]
341 fn silk_only_caps_at_wideband() {
342 assert_eq!(
343 reconcile_bandwidth(OpusMode::SilkOnly, Bandwidth::Superwideband),
344 Bandwidth::Wideband
345 );
346 assert_eq!(
347 reconcile_bandwidth(OpusMode::SilkOnly, Bandwidth::Fullband),
348 Bandwidth::Wideband
349 );
350 for bw in [Bandwidth::Narrowband, Bandwidth::Mediumband, Bandwidth::Wideband] {
352 assert_eq!(reconcile_bandwidth(OpusMode::SilkOnly, bw), bw);
353 }
354 }
355
356 #[test]
357 fn hybrid_floors_at_superwideband() {
358 for bw in [Bandwidth::Narrowband, Bandwidth::Mediumband, Bandwidth::Wideband] {
359 assert_eq!(
360 reconcile_bandwidth(OpusMode::Hybrid, bw),
361 Bandwidth::Superwideband
362 );
363 }
364 assert_eq!(
366 reconcile_bandwidth(OpusMode::Hybrid, Bandwidth::Superwideband),
367 Bandwidth::Superwideband
368 );
369 assert_eq!(
370 reconcile_bandwidth(OpusMode::Hybrid, Bandwidth::Fullband),
371 Bandwidth::Fullband
372 );
373 }
374}
375
376#[cfg(test)]
377mod silk_rate_tests {
378 use super::compute_silk_rate_for_hybrid;
379 use crate::Bandwidth;
380
381 #[test]
382 fn test_reference_table_exact_entries() {
383 assert_eq!(compute_silk_rate_for_hybrid(12000, Bandwidth::Fullband, true, true), 10000);
384 assert_eq!(compute_silk_rate_for_hybrid(16000, Bandwidth::Fullband, true, true), 13500);
385 assert_eq!(compute_silk_rate_for_hybrid(20000, Bandwidth::Fullband, true, true), 16000);
386 assert_eq!(compute_silk_rate_for_hybrid(24000, Bandwidth::Fullband, true, true), 18000);
387 assert_eq!(compute_silk_rate_for_hybrid(32000, Bandwidth::Fullband, true, true), 22000);
388 assert_eq!(compute_silk_rate_for_hybrid(64000, Bandwidth::Fullband, true, true), 38000);
389 }
390
391 #[test]
392 fn test_32kbps_gives_22kbps_silk() {
393 assert_eq!(compute_silk_rate_for_hybrid(32000, Bandwidth::Fullband, true, true), 22000);
394 }
395
396 #[test]
397 fn test_interpolation_between_table_entries() {
398 let r = compute_silk_rate_for_hybrid(18000, Bandwidth::Fullband, true, true);
399 assert_eq!(r, 14750);
400 }
401
402 #[test]
403 fn test_above_table_max_gives_half_extra() {
404 let r = compute_silk_rate_for_hybrid(72000, Bandwidth::Fullband, true, true);
405 assert_eq!(r, 38000 + (72000 - 64000) / 2);
406 }
407}
408
409impl OpusEncoder {
410 pub fn new(
411 sampling_rate: i32,
412 channels: usize,
413 application: Application,
414 ) -> Result<Self, &'static str> {
415 if ![8000, 12000, 16000, 24000, 48000].contains(&sampling_rate) {
416 return Err("Invalid sampling rate");
417 }
418 if ![1, 2].contains(&channels) {
419 return Err("Invalid number of channels");
420 }
421
422 let mode = modes::default_mode();
423 let celt_enc = CeltEncoder::new(mode, channels);
424
425 let mut silk_enc = Box::new(SilkEncoderState::default());
426 if silk_init_encoder(&mut silk_enc, 0) != 0 {
427 return Err("SILK encoder initialization failed");
428 }
429
430 let (opus_mode, bw) = match application {
431 Application::Voip => {
432 let bw = match sampling_rate {
433 8000 => Bandwidth::Narrowband,
434 12000 => Bandwidth::Mediumband,
435 16000 => Bandwidth::Wideband,
436 24000 => Bandwidth::Superwideband,
437 48000 => Bandwidth::Fullband,
438 _ => Bandwidth::Narrowband,
439 };
440
441 let mode = if sampling_rate > 16000 {
442 OpusMode::Hybrid
443 } else {
444 OpusMode::SilkOnly
445 };
446 (mode, bw)
447 }
448 Application::RestrictedLowDelay => {
449 let bw = match sampling_rate {
450 8000 => Bandwidth::Narrowband,
451 12000 => Bandwidth::Mediumband,
452 16000 => Bandwidth::Wideband,
453 24000 => Bandwidth::Superwideband,
454 _ => Bandwidth::Fullband,
455 };
456 (OpusMode::CeltOnly, bw)
457 }
458 Application::Audio => {
459 if sampling_rate <= 16000 {
460 let bw = match sampling_rate {
461 8000 => Bandwidth::Narrowband,
462 12000 => Bandwidth::Mediumband,
463 _ => Bandwidth::Wideband,
464 };
465 (OpusMode::SilkOnly, bw)
466 } else {
467 let bw = match sampling_rate {
468 24000 => Bandwidth::Superwideband,
469 _ => Bandwidth::Fullband,
470 };
471 (OpusMode::Hybrid, bw)
472 }
473 }
474 };
475
476 use silk::lin2log::silk_lin2log;
477 let variable_hp_smth2_q15 = silk_lin2log(60) << 8;
478
479 Ok(Self {
480 celt_enc,
481 silk_enc,
482 application,
483 sampling_rate,
484 channels,
485 bandwidth: bw,
486 bitrate_bps: 64000,
487 complexity: 9,
488 use_cbr: false,
489 use_inband_fec: false,
490 use_dtx: false,
491 nb_no_activity_ms_q1: 0,
492 range_final: 0,
493 packet_loss_perc: 0,
494 silk_initialized: false,
495 prev_enc_mode: None,
496 mode: opus_mode,
497 variable_hp_smth2_q15,
498 auto_bandwidth: 0,
499 first_frame: true,
500 force_bandwidth: None,
501 signal_type: None,
502 max_bandwidth: Bandwidth::Fullband,
503 tonality: analysis::TonalityAnalysisState::new(sampling_rate),
504 analysis_kfft: kiss_fft::KissFftState::new(480),
505 lsb_depth: std::env::var("RUSTY_OPUS_LSB_DEPTH")
510 .ok()
511 .and_then(|s| s.parse().ok())
512 .unwrap_or(24),
513 voice_ratio: -1,
514 detected_bandwidth: 0,
515 hp_mem: vec![0; channels * 2],
516
517 buf_filtered: Vec::new(),
518 buf_silk_input: Vec::new(),
519 buf_stereo_mid: Vec::new(),
520 buf_stereo_side: Vec::new(),
521 buf_celt_input: Vec::new(),
522 down2_state_first: [0; 2],
523 down2_state_second: [0; 2],
524 down2_3_state: [0; 6],
525 down_1_3_state: silk::resampler::SilkResamplerDown1_3::default(),
526 down2_3_state_r: [0; 6],
527 down_1_3_state_r: silk::resampler::SilkResamplerDown1_3::default(),
528 down_fir_l: None,
529 down_fir_r: None,
530 silk_prefill_tail: Vec::new(),
531 silk_prefill_pending: false,
532 buf_left: Vec::new(),
533 buf_right: Vec::new(),
534 celt_prefill_tail: Vec::new(),
535 rc: RangeCoder::new_encoder(1),
536 gate_tap: std::env::var("RUSTY_OPUS_GATE_HARVEST").ok().and_then(|p| {
537 use std::io::Write as _;
538 let mut f = std::fs::OpenOptions::new()
539 .create(true)
540 .append(true)
541 .open(&p)
542 .ok()?;
543 if f.metadata().map(|m| m.len()).unwrap_or(0) == 0 {
544 let _ = writeln!(
545 f,
546 "clip,frame,mode,bw,ch,bitrate,complexity,equiv,voice_est,\
547 is_silence,active,valid,tonality,tonality_slope,noisiness,\
548 activity_prob,music_prob,music_prob_min,music_prob_max,\
549 det_bw,max_pitch_ratio,bytes"
550 );
551 }
552 Some(std::io::BufWriter::new(f))
553 }),
554 gate_clip: std::env::var("RUSTY_OPUS_GATE_CLIP").unwrap_or_default(),
555 gate_frame: 0,
556 force_mode: match std::env::var("RUSTY_OPUS_FORCE_MODE").ok().as_deref() {
557 Some("silk") => Some(OpusMode::SilkOnly),
558 Some("celt") => Some(OpusMode::CeltOnly),
559 Some("hybrid") => Some(OpusMode::Hybrid),
560 _ => None,
561 },
562 mode_dwell: std::env::var("RUSTY_OPUS_MODE_DWELL")
563 .ok()
564 .and_then(|s| s.parse().ok())
565 .unwrap_or(1),
566 mode_dwell_run: 0,
567 analysis_warmup: std::env::var("RUSTY_OPUS_ANALYSIS_WARMUP")
572 .ok()
573 .and_then(|s| s.parse().ok())
574 .unwrap_or(10),
575 analysis_frames: 0,
576 })
577 }
578
579 pub fn enable_hybrid_mode(&mut self) -> Result<(), &'static str> {
580 if self.sampling_rate != 24000 && self.sampling_rate != 48000 {
581 return Err("Hybrid mode requires 24kHz or 48kHz sampling rate");
582 }
583 let bw = if self.sampling_rate == 48000 {
584 Bandwidth::Fullband
585 } else {
586 Bandwidth::Superwideband
587 };
588 self.mode = OpusMode::Hybrid;
589 self.bandwidth = bw;
590 self.silk_initialized = false;
591 Ok(())
592 }
593
594 pub fn final_range(&self) -> u32 {
598 self.range_final
599 }
600
601 fn compute_voice_est(&self) -> i32 {
604 match self.signal_type {
605 Some(SignalType::Voice) => return 127,
606 Some(SignalType::Music) => return 0,
607 None => {}
608 }
609 if self.voice_ratio >= 0 {
610 let mut v = self.voice_ratio * 327 >> 8;
611 if self.application == Application::Audio {
613 v = v.min(115);
614 }
615 v
616 } else {
617 match self.application {
618 Application::Voip => 115,
619 Application::Audio => 48,
620 Application::RestrictedLowDelay => 0,
621 }
622 }
623 }
624
625 pub fn encode(
626 &mut self,
627 input: &[f32],
628 frame_size: usize,
629 output: &mut [u8],
630 ) -> Result<usize, &'static str> {
631 let _prof_total = crate::prof::scope(crate::prof::Stage::Total);
632 if output.len() < 2 {
633 return Err("Output buffer too small");
634 }
635
636 let frame_rate = frame_rate_from_params(self.sampling_rate, frame_size)
637 .ok_or("Invalid frame size for sampling rate")?;
638
639 let mut analysis_info = analysis::AnalysisInfo::default();
641 if self.complexity >= 7 && self.sampling_rate >= 16000 {
642 if let Some(kfft) = &self.analysis_kfft {
643 analysis_info = analysis::run_analysis(
644 &mut self.tonality,
645 kfft,
646 input,
647 frame_size,
648 frame_size,
649 self.channels,
650 self.sampling_rate,
651 self.lsb_depth,
652 );
653 }
654 } else if self.tonality.initialized() {
655 self.tonality.reset();
656 }
657
658 let silence_thresh = 1.0f32 / (1i64 << self.lsb_depth) as f32;
660 let is_silence = input[..(frame_size * self.channels).min(input.len())]
661 .iter()
662 .fold(0.0f32, |m, &v| m.max(v.abs()))
663 <= silence_thresh;
664 if !is_silence {
665 self.voice_ratio = -1;
666 }
667 let activity = if is_silence {
672 false
673 } else if analysis_info.valid {
674 analysis_info.activity_probability >= 0.1
675 } else {
676 true
677 };
678 if analysis_info.valid {
686 self.analysis_frames = self.analysis_frames.saturating_add(1);
687 }
688 let analysis_converged = self.analysis_frames >= self.analysis_warmup;
689
690 self.detected_bandwidth = 0;
691 if analysis_info.valid && analysis_converged {
692 let prob = if self.prev_enc_mode.is_none() {
695 analysis_info.music_prob
696 } else if self.prev_enc_mode == Some(OpusMode::CeltOnly) {
697 analysis_info.music_prob_max
698 } else {
699 analysis_info.music_prob_min
700 };
701 self.voice_ratio = (0.5 + 100.0 * (1.0 - prob)).floor() as i32;
702 let ab = analysis_info.bandwidth;
703 self.detected_bandwidth = if ab <= 12 {
704 Bandwidth::Narrowband as i32
705 } else if ab <= 14 {
706 Bandwidth::Mediumband as i32
707 } else if ab <= 16 {
708 Bandwidth::Wideband as i32
709 } else if ab <= 18 {
710 Bandwidth::Superwideband as i32
711 } else {
712 Bandwidth::Fullband as i32
713 };
714 }
715
716 let mut mode = if self.application == Application::RestrictedLowDelay {
720 OpusMode::CeltOnly
721 } else {
722 let equiv = compute_equiv_rate(
723 self.bitrate_bps,
724 self.channels,
725 frame_rate,
726 !self.use_cbr,
727 self.complexity,
728 self.packet_loss_perc,
729 );
730 let prev_was_celt = self.prev_enc_mode == Some(OpusMode::CeltOnly);
731 let has_prev_mode = self.prev_enc_mode.is_some();
732 let voice_est = self.compute_voice_est();
733 let threshold = compute_mode_threshold(
734 self.application,
735 self.channels,
736 prev_was_celt,
737 has_prev_mode,
738 voice_est,
739 );
740 if equiv >= threshold && self.sampling_rate >= 24000 {
741 OpusMode::CeltOnly
742 } else {
743 OpusMode::SilkOnly
744 }
745 };
746
747 {
754 let equiv = compute_equiv_rate(
755 self.bitrate_bps,
756 self.channels,
757 frame_rate,
758 !self.use_cbr,
759 self.complexity,
760 self.packet_loss_perc,
761 );
762 let voice_est: i32 = self.compute_voice_est();
763 let (vt, mt) = if self.channels == 2 {
764 (
765 &STEREO_VOICE_BANDWIDTH_THRESHOLDS,
766 &STEREO_MUSIC_BANDWIDTH_THRESHOLDS,
767 )
768 } else {
769 (
770 &MONO_VOICE_BANDWIDTH_THRESHOLDS,
771 &MONO_MUSIC_BANDWIDTH_THRESHOLDS,
772 )
773 };
774 let mut th = [0i32; 8];
775 for i in 0..8 {
776 th[i] = mt[i] + ((voice_est * voice_est * (vt[i] - mt[i])) >> 14);
777 }
778 const NB: i32 = Bandwidth::Narrowband as i32; const MB: i32 = Bandwidth::Mediumband as i32; const FB: i32 = Bandwidth::Fullband as i32; let mut bw = FB;
782 while bw > NB {
783 let idx = (2 * (bw - MB)) as usize;
784 let mut threshold = th[idx];
785 let hysteresis = th[idx + 1];
786 if !self.first_frame {
787 if self.auto_bandwidth >= bw {
788 threshold -= hysteresis;
789 } else {
790 threshold += hysteresis;
791 }
792 }
793 if equiv >= threshold {
794 break;
795 }
796 bw -= 1;
797 }
798 if bw == MB {
800 bw = Bandwidth::Wideband as i32;
801 }
802 self.auto_bandwidth = bw;
803 if mode != OpusMode::CeltOnly && self.use_cbr && self.bitrate_bps < 15000 {
805 bw = bw.min(Bandwidth::Wideband as i32);
806 }
807 if mode != OpusMode::CeltOnly && self.sampling_rate > 16000 {
810 bw = bw.max(Bandwidth::Wideband as i32);
811 }
812 if self.sampling_rate <= 24000 {
814 bw = bw.min(Bandwidth::Superwideband as i32);
815 }
816 if self.sampling_rate <= 16000 {
817 bw = bw.min(Bandwidth::Wideband as i32);
818 }
819 if self.sampling_rate <= 12000 {
820 bw = bw.min(Bandwidth::Mediumband as i32);
821 }
822 if self.sampling_rate <= 8000 {
823 bw = bw.min(Bandwidth::Narrowband as i32);
824 }
825 if bw == Bandwidth::Mediumband as i32 && self.sampling_rate > 12000 {
828 bw = Bandwidth::Wideband as i32;
829 }
830 if self.detected_bandwidth != 0
846 && self.force_bandwidth.is_none()
847 && mode != OpusMode::CeltOnly
848 {
849 let ch = self.channels as i32;
850 let equiv2 = equiv; let min_det = if equiv2 <= 18000 * ch && mode == OpusMode::CeltOnly {
852 NB
853 } else if equiv2 <= 24000 * ch && mode == OpusMode::CeltOnly {
854 MB
855 } else if equiv2 <= 30000 * ch {
856 Bandwidth::Wideband as i32
857 } else if equiv2 <= 44000 * ch {
858 Bandwidth::Superwideband as i32
859 } else {
860 FB
861 };
862 bw = bw.min(self.detected_bandwidth.max(min_det));
863 }
864 let mut max_bw = self.max_bandwidth as i32;
870 if mode != OpusMode::CeltOnly && self.sampling_rate > 16000 {
871 max_bw = max_bw.max(Bandwidth::Wideband as i32);
872 }
873 bw = bw.min(max_bw);
874 if mode == OpusMode::CeltOnly && bw == MB {
876 bw = NB;
877 }
878 self.bandwidth = match self.force_bandwidth {
879 Some(f) => f,
880 None => match bw {
881 x if x == NB => Bandwidth::Narrowband,
882 x if x == MB => Bandwidth::Mediumband,
883 x if x == Bandwidth::Wideband as i32 => Bandwidth::Wideband,
884 x if x == Bandwidth::Superwideband as i32 => Bandwidth::Superwideband,
885 x if x == FB => Bandwidth::Fullband,
886 _ => Bandwidth::Wideband,
887 },
888 };
889 self.first_frame = false;
890 }
891
892 let curr_bw = self.bandwidth;
893 if mode == OpusMode::SilkOnly
894 && (curr_bw == Bandwidth::Superwideband || curr_bw == Bandwidth::Fullband)
895 {
896 mode = OpusMode::Hybrid;
897 }
898 if mode == OpusMode::Hybrid
899 && (curr_bw == Bandwidth::Narrowband
900 || curr_bw == Bandwidth::Mediumband
901 || curr_bw == Bandwidth::Wideband)
902 {
903 mode = OpusMode::SilkOnly;
904 }
905
906 if self.channels == 2 && mode == OpusMode::Hybrid && self.bitrate_bps > 28000 {
916 mode = OpusMode::CeltOnly;
917 self.bandwidth = Bandwidth::Fullband;
918 }
919
920 if self.mode_dwell > 1 {
934 match self.prev_enc_mode {
935 Some(prev) if mode != prev => {
936 self.mode_dwell_run += 1;
937 if self.mode_dwell_run < self.mode_dwell {
938 mode = prev;
942 self.bandwidth = reconcile_bandwidth(mode, self.bandwidth);
943 } else {
944 self.mode_dwell_run = 0;
946 }
947 }
948 _ => self.mode_dwell_run = 0,
949 }
950 }
951
952 if let Some(fm) = self.force_mode {
956 mode = fm;
957 self.bandwidth = reconcile_bandwidth(fm, self.bandwidth);
958 }
959
960 if mode == OpusMode::CeltOnly {
961 match frame_rate {
962 400 | 200 | 100 | 50 => {}
963 _ => return Err("Unsupported frame size for CELT-only mode"),
964 }
965 }
966
967 if mode == OpusMode::Hybrid {
968 match frame_rate {
969 100 | 50 => {}
970 _ => return Err("Unsupported frame size for Hybrid mode"),
971 }
972 }
973
974 if mode == OpusMode::SilkOnly {
975 match frame_rate {
976 400 | 200 | 100 | 50 | 25 => {}
977 _ => return Err("Unsupported frame size for SILK-only mode"),
978 }
979 }
980
981 let n400 = (self.sampling_rate / 400) as usize;
982
983 if let Some(prev) = self.prev_enc_mode {
988 if prev != mode {
989 if mode != OpusMode::SilkOnly {
990 let ch = self.channels;
991 self.celt_enc = CeltEncoder::new(modes::default_mode(), ch);
992 let n400 = (self.sampling_rate / 400) as usize;
995 if self.celt_prefill_tail.len() == n400 * ch {
996 let mut dummy = RangeCoder::new_encoder(2);
997 let tail = std::mem::take(&mut self.celt_prefill_tail);
998 self.celt_enc.encode_with_budget(&tail, n400, &mut dummy, 0, 21, 16);
999 self.celt_prefill_tail = tail;
1000 }
1001 }
1002 if mode != OpusMode::CeltOnly && prev == OpusMode::CeltOnly {
1003 self.silk_initialized = false;
1004 self.silk_prefill_pending = true;
1005 }
1006 }
1007 }
1008
1009 if self.channels == 1 {
1011 let n10 = (self.sampling_rate / 100) as usize;
1012 if frame_size >= n10 {
1013 self.silk_prefill_tail.resize(n10, 0);
1014 for i in 0..n10 {
1015 self.silk_prefill_tail[i] = (input[frame_size - n10 + i] * 32768.0)
1016 .clamp(-32768.0, 32767.0) as i16;
1017 }
1018 }
1019 }
1020
1021 {
1025 let ch = self.channels;
1026 self.celt_prefill_tail.resize(n400 * ch, 0.0);
1027 let base = frame_size - n400;
1028 for c in 0..ch {
1029 for i in 0..n400 {
1030 self.celt_prefill_tail[c * n400 + i] = input[(base + i) * ch + c];
1031 }
1032 }
1033 }
1034
1035 let toc = gen_toc(mode, frame_rate, self.bandwidth, self.channels);
1036 output[0] = toc;
1037
1038 if self.use_dtx && (analysis_info.valid || is_silence) {
1045 let frame_ms_q1 = 2 * 1000 * frame_size as i32 / self.sampling_rate;
1046 let dtx = if !activity {
1047 self.nb_no_activity_ms_q1 += frame_ms_q1;
1048 const LO: i32 = silk::define::NB_SPEECH_FRAMES_BEFORE_DTX * 20 * 2; const HI: i32 = (silk::define::NB_SPEECH_FRAMES_BEFORE_DTX + silk::define::MAX_CONSECUTIVE_DTX) * 20 * 2; if self.nb_no_activity_ms_q1 > LO {
1051 if self.nb_no_activity_ms_q1 <= HI {
1052 true
1053 } else {
1054 self.nb_no_activity_ms_q1 = LO;
1055 false
1056 }
1057 } else {
1058 false
1059 }
1060 } else {
1061 self.nb_no_activity_ms_q1 = 0;
1062 false
1063 };
1064 if dtx {
1065 self.prev_enc_mode = Some(mode);
1066 self.range_final = 0;
1067 return Ok(1);
1068 }
1069 } else {
1070 self.nb_no_activity_ms_q1 = 0;
1071 }
1072
1073 let target_bits =
1074 (self.bitrate_bps as i64 * frame_size as i64 / self.sampling_rate as i64) as i32;
1075 let cbr_bytes = ((target_bits + 4) / 8) as usize;
1076 let max_data_bytes = output.len();
1077
1078 let n_bytes = if self.use_cbr {
1083 cbr_bytes.min(max_data_bytes).max(1)
1084 } else {
1085 max_data_bytes.min(1276).max(cbr_bytes.min(max_data_bytes)).max(3)
1086 };
1087
1088 let init_rc_size = n_bytes - 1;
1089 self.rc.reset_for_encode(init_rc_size as u32);
1090
1091 if mode == OpusMode::SilkOnly || mode == OpusMode::Hybrid {
1092 let silk_fs_khz = if mode == OpusMode::Hybrid {
1093 16
1094 } else {
1095 self.sampling_rate.min(16000) / 1000
1096 };
1097
1098 let frame_ms = (frame_size as i32 * 1000) / self.sampling_rate;
1099 if !self.silk_initialized || self.silk_enc.s_cmn.fs_khz != silk_fs_khz {
1100 let silk_init_bitrate = if self.use_cbr {
1101 (((n_bytes - 1) * 8) as i64 * self.sampling_rate as i64 / frame_size as i64)
1102 as i32
1103 } else {
1104 self.bitrate_bps
1105 };
1106 silk_control_encoder(
1107 &mut self.silk_enc,
1108 silk_fs_khz,
1109 frame_ms,
1110 silk_init_bitrate,
1111 self.complexity,
1112 );
1113 self.silk_enc.s_cmn.use_cbr = if self.use_cbr { 1 } else { 0 };
1114
1115 self.silk_enc.s_cmn.n_channels = self.channels as i32;
1116 self.silk_initialized = true;
1117 self.down2_state_first = [0; 2];
1118 self.down2_state_second = [0; 2];
1119 self.down2_3_state = [0; 6];
1120 self.down_1_3_state = silk::resampler::SilkResamplerDown1_3::default();
1121 self.down2_3_state_r = [0; 6];
1122 self.down_1_3_state_r = silk::resampler::SilkResamplerDown1_3::default();
1123 self.down_fir_l =
1124 silk::resampler::SilkDownFirResampler::new(self.sampling_rate, 16000);
1125 self.down_fir_r =
1126 silk::resampler::SilkDownFirResampler::new(self.sampling_rate, 16000);
1127 }
1128
1129 if self.silk_prefill_pending {
1133 self.silk_prefill_pending = false;
1134 let n10 = (self.sampling_rate / 100) as usize;
1135 if self.channels == 1 && self.silk_prefill_tail.len() == n10 {
1136 let need = silk_fs_khz as usize * 10;
1137 let mut resampled = vec![0i16; need];
1138 if self.sampling_rate > 16000 {
1139 if let Some(r) = &mut self.down_fir_l {
1140 r.process(&mut resampled, &self.silk_prefill_tail);
1141 }
1142 } else {
1143 resampled.copy_from_slice(&self.silk_prefill_tail[..need]);
1144 }
1145 silk::enc_api::silk_encode_prefill(&mut self.silk_enc, &resampled, 0);
1146 }
1147 }
1148
1149 self.silk_enc.s_cmn.use_in_band_fec = if self.use_inband_fec { 1 } else { 0 };
1150 self.silk_enc.s_cmn.packet_loss_perc = self.packet_loss_perc.clamp(0, 100);
1151
1152 self.silk_enc.s_cmn.lbrr_enabled = if self.use_inband_fec { 1 } else { 0 };
1153
1154 self.silk_enc.s_cmn.lbrr_gain_increases =
1158 (7 - ((self.packet_loss_perc.clamp(0, 100) * 26214) >> 16)).max(2);
1159
1160 let hp_freq_smth1 = if mode == OpusMode::CeltOnly {
1161 silk_lin2log(60) << 8
1162 } else {
1163 self.silk_enc.s_cmn.variable_hp_smth1_q15
1164 };
1165
1166 const VARIABLE_HP_SMTH_COEF2_Q16: i32 = 984;
1167 self.variable_hp_smth2_q15 = silk_smlawb(
1168 self.variable_hp_smth2_q15,
1169 hp_freq_smth1 - self.variable_hp_smth2_q15,
1170 VARIABLE_HP_SMTH_COEF2_Q16,
1171 );
1172
1173 let cutoff_hz = silk_log2lin(silk_rshift(self.variable_hp_smth2_q15, 8));
1174
1175 let _prof_rs = crate::prof::scope(crate::prof::Stage::Resample);
1176 let required_size = frame_size * self.channels;
1177 self.buf_filtered.resize(required_size, 0);
1178 if self.application == Application::Voip {
1179 hp_cutoff(
1180 input,
1181 cutoff_hz,
1182 &mut self.buf_filtered,
1183 &mut self.hp_mem,
1184 frame_size,
1185 self.channels,
1186 self.sampling_rate,
1187 );
1188 } else {
1189 for (i, &x) in input.iter().enumerate() {
1190 self.buf_filtered[i] = (x * 32768.0).clamp(-32768.0, 32767.0) as i16;
1191 }
1192 }
1193
1194 let input_i16 = &self.buf_filtered;
1195
1196 let silk_input: &[i16] = if self.channels == 2 {
1197 let frame_length = input_i16.len() / 2;
1205 self.buf_left.resize(frame_length, 0);
1206 self.buf_right.resize(frame_length, 0);
1207 for i in 0..frame_length {
1208 self.buf_left[i] = input_i16[2 * i];
1209 self.buf_right[i] = input_i16[2 * i + 1];
1210 }
1211 let need_resample = self.sampling_rate > 16000;
1212 let ds_len = if !need_resample {
1213 frame_length
1214 } else if self.sampling_rate == 48000 {
1215 frame_length / 3
1216 } else {
1217 frame_length * 2 / 3
1218 };
1219 if need_resample {
1220 self.buf_stereo_mid.resize(ds_len, 0);
1221 self.buf_stereo_side.resize(ds_len, 0);
1222 if let (Some(rl), Some(rr)) = (&mut self.down_fir_l, &mut self.down_fir_r) {
1223 rl.process(&mut self.buf_stereo_mid, &self.buf_left);
1224 rr.process(&mut self.buf_stereo_side, &self.buf_right);
1225 }
1226 self.buf_left.resize(ds_len, 0);
1227 self.buf_right.resize(ds_len, 0);
1228 self.buf_left.copy_from_slice(&self.buf_stereo_mid[..ds_len]);
1229 self.buf_right.copy_from_slice(&self.buf_stereo_side[..ds_len]);
1230 }
1231 self.buf_stereo_mid.resize(ds_len, 0);
1232 self.buf_stereo_side.resize(ds_len, 0);
1233 for i in 0..ds_len {
1234 let l = self.buf_left[i] as i32;
1235 let r = self.buf_right[i] as i32;
1236 self.buf_stereo_mid[i] = ((l + r) / 2) as i16;
1237 self.buf_stereo_side[i] = (l - r) as i16;
1238 }
1239 self.silk_enc.stereo.side.resize(ds_len, 0);
1240 self.silk_enc
1241 .stereo
1242 .side
1243 .copy_from_slice(&self.buf_stereo_side[..ds_len]);
1244 &self.buf_stereo_mid
1245 } else if mode == OpusMode::SilkOnly && self.sampling_rate > 16000 {
1246 if self.sampling_rate == 48000 {
1247 let silk_frame_size = frame_size / 3;
1252 self.buf_silk_input.resize(silk_frame_size, 0);
1253 if let Some(r) = &mut self.down_fir_l {
1254 r.process(&mut self.buf_silk_input, input_i16);
1255 }
1256 &self.buf_silk_input
1257 } else if self.sampling_rate == 24000 {
1258 let silk_frame_size = frame_size * 2 / 3;
1259 self.buf_silk_input.resize(silk_frame_size, 0);
1260 if let Some(r) = &mut self.down_fir_l {
1261 r.process(&mut self.buf_silk_input, input_i16);
1262 }
1263 &self.buf_silk_input
1264 } else {
1265 input_i16
1266 }
1267 } else if mode == OpusMode::Hybrid && self.sampling_rate > 16000 {
1268 let silk_frame_size = if self.sampling_rate == 48000 {
1269 frame_size / 3
1270 } else {
1271 frame_size * 2 / 3
1272 };
1273 self.buf_silk_input.resize(silk_frame_size, 0);
1274 if let Some(r) = &mut self.down_fir_l {
1275 r.process(&mut self.buf_silk_input, input_i16);
1276 }
1277 &self.buf_silk_input
1278 } else {
1279 input_i16
1280 };
1281
1282 drop(_prof_rs);
1283
1284 let mut pn_bytes = 0;
1285
1286 let silk_rate_for_calc = if mode == OpusMode::Hybrid {
1292 16000
1293 } else {
1294 self.sampling_rate.min(16000)
1295 };
1296 let silk_frame_len = silk_input.len();
1297
1298 let silk_bitrate = if mode == OpusMode::Hybrid {
1299 let frame_duration_ms = frame_size as i32 * 1000 / self.sampling_rate;
1300 let frame20ms = frame_duration_ms >= 20;
1301 compute_silk_rate_for_hybrid(self.bitrate_bps, curr_bw, frame20ms, !self.use_cbr)
1302 } else if self.use_cbr {
1303 (8i64 * (n_bytes - 1) as i64 * silk_rate_for_calc as i64 / silk_frame_len as i64)
1304 as i32
1305 } else {
1306 self.bitrate_bps
1308 };
1309 let silk_max_bits = if mode == OpusMode::Hybrid {
1310 let total_max_bits = ((n_bytes - 1) * 8) as i32;
1311 if self.use_cbr {
1312 let silk_bits = (silk_bitrate as i64 * silk_frame_len as i64
1313 / silk_rate_for_calc as i64) as i32;
1314 let other_bits = 0i32.max(total_max_bits - silk_bits);
1315 0i32.max(total_max_bits - other_bits * 3 / 4)
1316 } else {
1317 let frame_duration_ms = frame_size as i32 * 1000 / self.sampling_rate;
1318 let frame20ms = frame_duration_ms >= 20;
1319 let max_bit_rate = compute_silk_rate_for_hybrid(
1320 total_max_bits * self.sampling_rate / frame_size as i32,
1321 curr_bw,
1322 frame20ms,
1323 !self.use_cbr,
1324 );
1325 max_bit_rate * frame_size as i32 / self.sampling_rate
1326 }
1327 } else {
1328 ((n_bytes - 1) * 8) as i32
1329 };
1330 let silk_use_cbr = if mode == OpusMode::Hybrid && self.use_cbr {
1331 0
1332 } else if self.use_cbr {
1333 1
1334 } else {
1335 0
1336 };
1337 let ret = silk_encode(
1338 &mut self.silk_enc,
1339 silk_input,
1340 silk_input.len(),
1341 &mut self.rc,
1342 &mut pn_bytes,
1343 silk_bitrate,
1344 silk_max_bits,
1345 silk_use_cbr,
1346 1,
1347 );
1348 if ret != 0 {
1349 return Err("SILK encoding failed");
1350 }
1351 }
1352
1353 if mode == OpusMode::Hybrid && self.rc.tell() + 37 <= ((n_bytes - 1) * 8) as i32 {
1358 self.rc.encode_bit_logp(false, 12); }
1360
1361 if mode == OpusMode::Hybrid {
1362 let nb_compr_bytes = (n_bytes - 1) as u32;
1363 self.rc.shrink(nb_compr_bytes);
1364 }
1365
1366 let silk_ret_bytes = if mode == OpusMode::SilkOnly {
1367 ((self.rc.tell() + 7) >> 3) as usize
1368 } else {
1369 0
1370 };
1371
1372 if mode == OpusMode::CeltOnly || mode == OpusMode::Hybrid {
1373 self.celt_enc.analysis = celt::AnalysisInfo {
1374 valid: analysis_info.valid,
1375 tonality: analysis_info.tonality,
1376 tonality_slope: analysis_info.tonality_slope,
1377 noisiness: analysis_info.noisiness,
1378 activity: analysis_info.activity,
1379 music_prob: analysis_info.music_prob,
1380 music_prob_min: analysis_info.music_prob_min,
1381 music_prob_max: analysis_info.music_prob_max,
1382 bandwidth: analysis_info.bandwidth,
1383 activity_probability: analysis_info.activity_probability,
1384 max_pitch_ratio: analysis_info.max_pitch_ratio,
1385 leak_boost: analysis_info.leak_boost,
1386 };
1387 self.celt_enc.complexity = self.complexity;
1388 self.celt_enc.lsb_depth = self.lsb_depth;
1389 self.celt_enc.loss_rate = self.packet_loss_perc;
1394 let start_band = if mode == OpusMode::Hybrid { 17 } else { 0 };
1395 let end_band = match self.bandwidth {
1398 Bandwidth::Narrowband => 13,
1399 Bandwidth::Mediumband | Bandwidth::Wideband => 17,
1400 Bandwidth::Superwideband => 19,
1401 _ => 21,
1402 };
1403 let total_packet_bits = ((n_bytes - 1) * 8) as i32;
1404 self.celt_enc.vbr_rate = if self.use_cbr {
1409 0
1410 } else {
1411 let den = self.sampling_rate >> 3; ((self.bitrate_bps as i64 * frame_size as i64 + (den >> 1) as i64)
1413 / den as i64) as i32
1414 };
1415
1416 let celt_input: &[f32] = if self.channels == 1 {
1417 input
1418 } else {
1419 let n = frame_size * self.channels;
1420 self.buf_celt_input.resize(n, 0.0);
1421 for i in 0..frame_size {
1422 for ch in 0..self.channels {
1423 self.buf_celt_input[ch * frame_size + i] = input[i * self.channels + ch];
1424 }
1425 }
1426 &self.buf_celt_input
1427 };
1428
1429 if self.rc.tell() <= total_packet_bits {
1430 self.celt_enc.encode_with_budget(
1431 celt_input,
1432 frame_size,
1433 &mut self.rc,
1434 start_band,
1435 end_band,
1436 total_packet_bits,
1437 );
1438 }
1439 }
1440
1441 self.rc.done();
1442 self.range_final = self.rc.rng;
1443
1444 if mode == OpusMode::SilkOnly {
1445 let mut ret = silk_ret_bytes.min(self.rc.storage as usize);
1446 while ret > 2 && self.rc.buf[ret - 1] == 0 {
1447 ret -= 1;
1448 }
1449
1450 let target_total = if self.use_cbr {
1451 n_bytes.min(output.len())
1452 } else {
1453 (ret + 1).min(output.len())
1454 };
1455
1456 let silk_len = ret;
1457
1458 if !self.use_cbr || silk_len + 1 >= target_total {
1459 output[0] = toc;
1461 let copy_len = silk_len.min(target_total - 1);
1462 output[1..1 + copy_len].copy_from_slice(&self.rc.buf[..copy_len]);
1463 return Ok((copy_len + 1).min(output.len()));
1464 }
1465
1466 output[0] = toc | 0x03;
1467
1468 if silk_len + 2 >= target_total {
1469 output[1] = 0x01;
1470 let copy_len = (target_total - 2).min(silk_len);
1471 output[2..2 + copy_len].copy_from_slice(&self.rc.buf[..copy_len]);
1472 self.prev_enc_mode = Some(mode);
1473 return Ok(target_total.min(output.len()));
1474 }
1475
1476 let pad_amount = target_total - silk_len - 2;
1477 output[1] = 0x41;
1478
1479 let nb_255s = (pad_amount - 1) / 255;
1480 let mut ptr = 2;
1481 for _ in 0..nb_255s {
1482 output[ptr] = 255;
1483 ptr += 1;
1484 }
1485 output[ptr] = (pad_amount - 255 * nb_255s - 1) as u8;
1486 ptr += 1;
1487
1488 output[ptr..ptr + silk_len].copy_from_slice(&self.rc.buf[..silk_len]);
1489 ptr += silk_len;
1490
1491 let fill_end = target_total.min(output.len());
1492 for byte in output[ptr..fill_end].iter_mut() {
1493 *byte = 0;
1494 }
1495
1496 self.prev_enc_mode = Some(mode);
1497 return Ok(target_total.min(output.len()));
1498 }
1499
1500 let payload_len = if self.use_cbr {
1503 n_bytes - 1
1504 } else {
1505 (self.rc.storage as usize).min(n_bytes - 1)
1506 };
1507 output[1..1 + payload_len].copy_from_slice(&self.rc.buf[..payload_len]);
1508 if self.gate_tap.is_some() {
1511 let equiv = compute_equiv_rate(
1512 self.bitrate_bps,
1513 self.channels,
1514 frame_rate,
1515 !self.use_cbr,
1516 self.complexity,
1517 self.packet_loss_perc,
1518 );
1519 let voice_est = self.compute_voice_est();
1520 let (clip, frame) = (self.gate_clip.clone(), self.gate_frame);
1521 if let Some(tap) = self.gate_tap.as_mut() {
1522 use std::io::Write as _;
1523 let mode_s = match mode {
1524 OpusMode::SilkOnly => "silk",
1525 OpusMode::CeltOnly => "celt",
1526 OpusMode::Hybrid => "hybrid",
1527 };
1528 let _ = writeln!(
1529 tap,
1530 "{},{},{},{},{},{},{},{},{},{},{},{},{:.4},{:.4},{:.4},{:.4},{:.4},{:.4},{:.4},{},{:.4},{}",
1531 clip,
1532 frame,
1533 mode_s,
1534 self.bandwidth as i32,
1535 self.channels,
1536 self.bitrate_bps,
1537 self.complexity,
1538 equiv,
1539 voice_est,
1540 is_silence as u8,
1541 activity as u8,
1542 analysis_info.valid as u8,
1543 analysis_info.tonality,
1544 analysis_info.tonality_slope,
1545 analysis_info.noisiness,
1546 analysis_info.activity_probability,
1547 analysis_info.music_prob,
1548 analysis_info.music_prob_min,
1549 analysis_info.music_prob_max,
1550 self.detected_bandwidth,
1551 analysis_info.max_pitch_ratio,
1552 1 + payload_len,
1553 );
1554 }
1555 }
1556 self.gate_frame += 1;
1557
1558 self.prev_enc_mode = Some(mode);
1559 Ok(1 + payload_len)
1560 }
1561}
1562
1563pub struct OpusDecoder {
1564 celt_dec: CeltDecoder,
1565 silk_dec: silk::dec_api::SilkDecoder,
1566 sampling_rate: i32,
1567 channels: usize,
1568
1569 prev_mode: Option<OpusMode>,
1570 frame_size: usize,
1571
1572 bandwidth: Bandwidth,
1573
1574 stream_channels: usize,
1575
1576 silk_resampler: silk::resampler::SilkResampler,
1577 silk_resampler_r: silk::resampler::SilkResampler,
1579
1580 prev_internal_rate: i32,
1581
1582 pub hybrid_skip_celt: bool,
1583
1584 w_pcm_i16: Vec<i16>,
1585 w_silk_out: Vec<f32>,
1586 w_pcm_resampled: Vec<i16>,
1587 w_celt_planar: Vec<f32>,
1588 w_celt_out: Vec<f32>,
1589
1590 silk_s_mid: [i16; 2],
1596
1597 pub last_range: u32,
1600
1601 aux: Option<Box<OpusDecoder>>,
1606 prev_used_aux: bool,
1611 prev_redundancy: bool,
1615}
1616
1617impl OpusDecoder {
1618 pub fn new(sampling_rate: i32, channels: usize) -> Result<Self, &'static str> {
1619 if ![8000, 12000, 16000, 24000, 48000].contains(&sampling_rate) {
1620 return Err("Invalid sampling rate");
1621 }
1622 if ![1, 2].contains(&channels) {
1623 return Err("Invalid number of channels");
1624 }
1625
1626 let mode = modes::default_mode();
1627 let celt_dec = CeltDecoder::new(mode, channels);
1628
1629 let mut silk_dec = silk::dec_api::SilkDecoder::new();
1630 silk_dec.init(sampling_rate.min(16000), channels as i32);
1631 silk_dec.channel_state[0].fs_api_hz = sampling_rate;
1632
1633 Ok(Self {
1634 celt_dec,
1635 silk_dec,
1636 sampling_rate,
1637 channels,
1638 prev_mode: None,
1639 frame_size: 0,
1640 bandwidth: Bandwidth::Auto,
1641 stream_channels: channels,
1642 silk_resampler: silk::resampler::SilkResampler::default(),
1643 silk_resampler_r: silk::resampler::SilkResampler::default(),
1644 prev_internal_rate: 0,
1645 hybrid_skip_celt: false,
1646
1647 w_pcm_i16: vec![0i16; 5760 * channels],
1652
1653 w_silk_out: vec![0.0f32; 5760 * channels],
1654 w_pcm_resampled: vec![0i16; 5760 * channels],
1655 w_celt_planar: vec![0.0f32; 5760 * channels],
1656 w_celt_out: vec![0.0f32; 5760 * channels],
1657 silk_s_mid: [0; 2],
1658 last_range: 0,
1659 aux: None,
1660 prev_used_aux: false,
1661 prev_redundancy: false,
1662 })
1663 }
1664
1665 fn decode_plc(
1672 &mut self,
1673 frame_size: usize,
1674 output: &mut [f32],
1675 ) -> Result<usize, &'static str> {
1676 let out_samples = frame_size * self.channels;
1677 for v in output.iter_mut().take(out_samples) {
1678 *v = 0.0;
1679 }
1680 let mode = self.prev_mode.unwrap_or(OpusMode::SilkOnly);
1681 if mode == OpusMode::CeltOnly {
1682 self.celt_dec.conceal_lost(frame_size, output);
1685 self.prev_mode = Some(mode);
1686 return Ok(frame_size);
1687 }
1688
1689 let frame_ms = (frame_size as i32 * 1000 / self.sampling_rate).max(1);
1690 let internal_rate = if mode == OpusMode::Hybrid {
1691 16000
1692 } else {
1693 match self.bandwidth {
1694 Bandwidth::Narrowband => 8000,
1695 Bandwidth::Mediumband => 12000,
1696 _ => 16000,
1697 }
1698 };
1699 if self.sampling_rate != internal_rate && internal_rate != self.prev_internal_rate {
1700 self.silk_resampler.init(internal_rate, self.sampling_rate);
1701 self.prev_internal_rate = internal_rate;
1702 }
1703 let n_silk = match frame_ms {
1704 40 => 2,
1705 60 => 3,
1706 _ => 1,
1707 };
1708 let internal_frame = (frame_ms * internal_rate / 1000) as usize;
1709 let internal_sub = internal_frame / n_silk.max(1);
1710 let ratio = self.sampling_rate as f64 / internal_rate as f64;
1711 self.silk_dec.produce_lr = false;
1713 self.silk_dec.n_channels_internal = 1;
1714
1715 let mut off = 0usize; for sf in 0..n_silk {
1717 let mut rc = RangeCoder::new_decoder(&[]);
1718 let n16 = internal_sub;
1719 if n16 + 2 > self.w_pcm_i16.len() {
1720 return Err("opus PLC: frame exceeds buffer");
1721 }
1722 self.w_pcm_i16[0] = self.silk_s_mid[0];
1723 self.w_pcm_i16[1] = self.silk_s_mid[1];
1724 let ret = self.silk_dec.decode(
1725 &mut rc,
1726 &mut self.w_pcm_i16[2..n16 + 2],
1727 silk::decode_frame::FLAG_PACKET_LOST,
1728 sf == 0,
1729 frame_ms,
1730 internal_rate,
1731 );
1732 if ret < 0 {
1733 return Err("SILK PLC failed");
1734 }
1735 let dec = ret as usize;
1736 if dec >= 2 {
1737 self.silk_s_mid[0] = self.w_pcm_i16[dec];
1738 self.silk_s_mid[1] = self.w_pcm_i16[dec + 1];
1739 }
1740 let base = off * self.channels;
1741 let out_len = if self.sampling_rate == internal_rate {
1742 for i in 0..dec {
1743 let v = self.w_pcm_i16[1 + i] as f32 / 32768.0;
1744 for ch in 0..self.channels {
1745 let idx = base + i * self.channels + ch;
1746 if idx < output.len() {
1747 output[idx] = v;
1748 }
1749 }
1750 }
1751 dec
1752 } else {
1753 let out_len = (dec as f64 * ratio) as usize;
1754 let src: Vec<i16> = self.w_pcm_i16[1..1 + dec].to_vec();
1755 self.silk_resampler
1756 .process(&mut self.w_pcm_resampled[..out_len], &src, dec as i32);
1757 for i in 0..out_len {
1758 let v = self.w_pcm_resampled[i] as f32 / 32768.0;
1759 for ch in 0..self.channels {
1760 let idx = base + i * self.channels + ch;
1761 if idx < output.len() {
1762 output[idx] = v;
1763 }
1764 }
1765 }
1766 out_len
1767 };
1768 off += out_len;
1769 }
1770 self.prev_mode = Some(mode);
1771 Ok(frame_size)
1772 }
1773
1774 pub fn decode_fec(
1782 &mut self,
1783 packet: &[u8],
1784 frame_size: usize,
1785 output: &mut [f32],
1786 ) -> Result<usize, &'static str> {
1787 if packet.is_empty() {
1788 return self.decode_plc(frame_size, output);
1789 }
1790 let toc = packet[0];
1791 let mode = mode_from_toc(toc);
1792 if mode == OpusMode::CeltOnly || (toc & 0x03) != 0 {
1794 return self.decode_plc(frame_size, output);
1795 }
1796 let bandwidth = bandwidth_from_toc(toc);
1797 let payload = &packet[1..];
1798
1799 let out_samples = frame_size * self.channels;
1800 for v in output.iter_mut().take(out_samples) {
1801 *v = 0.0;
1802 }
1803 let frame_ms = (frame_size as i32 * 1000 / self.sampling_rate).max(1);
1804 let internal_rate = if mode == OpusMode::Hybrid {
1805 16000
1806 } else {
1807 match bandwidth {
1808 Bandwidth::Narrowband => 8000,
1809 Bandwidth::Mediumband => 12000,
1810 _ => 16000,
1811 }
1812 };
1813 if self.sampling_rate != internal_rate && internal_rate != self.prev_internal_rate {
1814 self.silk_resampler.init(internal_rate, self.sampling_rate);
1815 self.prev_internal_rate = internal_rate;
1816 }
1817 let internal_frame = (frame_ms * internal_rate / 1000) as usize;
1818 let ratio = self.sampling_rate as f64 / internal_rate as f64;
1819 self.silk_dec.produce_lr = false;
1820 self.silk_dec.n_channels_internal = 1;
1821
1822 let mut rc = RangeCoder::new_decoder(payload);
1823 let n16 = internal_frame;
1824 if n16 + 2 > self.w_pcm_i16.len() {
1825 return Err("opus FEC: frame exceeds buffer");
1826 }
1827 self.w_pcm_i16[0] = self.silk_s_mid[0];
1828 self.w_pcm_i16[1] = self.silk_s_mid[1];
1829 let ret = self.silk_dec.decode(
1830 &mut rc,
1831 &mut self.w_pcm_i16[2..n16 + 2],
1832 silk::decode_frame::FLAG_DECODE_LBRR,
1833 true,
1834 frame_ms,
1835 internal_rate,
1836 );
1837 if ret < 0 {
1838 return Err("SILK FEC failed");
1839 }
1840 let dec = ret as usize;
1841 if dec >= 2 {
1842 self.silk_s_mid[0] = self.w_pcm_i16[dec];
1843 self.silk_s_mid[1] = self.w_pcm_i16[dec + 1];
1844 }
1845 if self.sampling_rate == internal_rate {
1846 for i in 0..dec {
1847 let v = self.w_pcm_i16[1 + i] as f32 / 32768.0;
1848 for ch in 0..self.channels {
1849 let idx = i * self.channels + ch;
1850 if idx < output.len() {
1851 output[idx] = v;
1852 }
1853 }
1854 }
1855 } else {
1856 let out_len = (dec as f64 * ratio) as usize;
1857 let src: Vec<i16> = self.w_pcm_i16[1..1 + dec].to_vec();
1858 self.silk_resampler
1859 .process(&mut self.w_pcm_resampled[..out_len], &src, dec as i32);
1860 for i in 0..out_len {
1861 let v = self.w_pcm_resampled[i] as f32 / 32768.0;
1862 for ch in 0..self.channels {
1863 let idx = i * self.channels + ch;
1864 if idx < output.len() {
1865 output[idx] = v;
1866 }
1867 }
1868 }
1869 }
1870 self.prev_mode = Some(mode);
1871 Ok(frame_size)
1872 }
1873
1874 pub fn decode(
1875 &mut self,
1876 input: &[u8],
1877 frame_size: usize,
1878 output: &mut [f32],
1879 ) -> Result<usize, &'static str> {
1880 if input.is_empty() {
1882 return self.decode_plc(frame_size, output);
1883 }
1884
1885 let toc = input[0];
1886 let mode = mode_from_toc(toc);
1887 let packet_channels = channels_from_toc(toc);
1888 let bandwidth = bandwidth_from_toc(toc);
1889 let frame_duration_ms = frame_duration_ms_from_toc(toc);
1890
1891 let mono_in_stereo = packet_channels == 1 && self.channels == 2;
1902
1903 if packet_channels != self.channels && !mono_in_stereo {
1904 if self
1909 .aux
1910 .as_ref()
1911 .map(|a| a.channels != packet_channels)
1912 .unwrap_or(true)
1913 {
1914 self.aux = Some(Box::new(OpusDecoder::new(
1915 self.sampling_rate,
1916 packet_channels,
1917 )?));
1918 }
1919 if !self.prev_used_aux
1924 && packet_channels == 1
1925 && self.channels == 2
1926 && (mode == OpusMode::CeltOnly || mode == OpusMode::Hybrid)
1927 {
1928 let (aux_opt, primary) = (&mut self.aux, &self.celt_dec);
1929 if let Some(aux) = aux_opt.as_mut() {
1930 aux.celt_dec.seed_from(primary);
1931 }
1932 }
1933 let aux = self.aux.as_mut().unwrap();
1934 let mut buf = vec![0.0f32; frame_size * packet_channels];
1935 let n = aux.decode(input, frame_size, &mut buf)?;
1936 self.last_range = aux.last_range;
1937 if packet_channels == 1 && self.channels == 2 {
1938 for i in 0..n {
1939 let v = buf[i];
1940 output[2 * i] = v;
1941 output[2 * i + 1] = v;
1942 }
1943 } else if packet_channels == 2 && self.channels == 1 {
1944 for i in 0..n {
1945 output[i] = 0.5 * (buf[2 * i] + buf[2 * i + 1]);
1946 }
1947 } else {
1948 let m = (n * self.channels).min(output.len()).min(buf.len());
1949 output[..m].copy_from_slice(&buf[..m]);
1950 }
1951 self.prev_mode = Some(mode);
1952 self.prev_used_aux = true;
1953 return Ok(n);
1954 }
1955
1956 if self.prev_used_aux {
1962 self.prev_used_aux = false;
1963 if (mode == OpusMode::CeltOnly || mode == OpusMode::Hybrid) && self.channels == 2 {
1964 if let Some(aux) = self.aux.as_ref() {
1965 self.celt_dec.seed_from(&aux.celt_dec);
1966 }
1967 }
1968 }
1969
1970 let code = toc & 0x03;
1971 let frame_count: usize;
1972 let frame_payloads: Vec<&[u8]>;
1973
1974 match code {
1975 0 => {
1976 frame_count = 1;
1977 frame_payloads = vec![&input[1..]];
1978 }
1979 1 => {
1980 frame_count = 2;
1981 let half = (input.len() - 1) / 2;
1982 if half == 0 {
1983 return Err("Code 1: empty frame");
1984 }
1985 frame_payloads = vec![&input[1..1 + half], &input[1 + half..]];
1986 }
1987 2 => {
1988 frame_count = 2;
1989 let data = &input[1..];
1990 if data.is_empty() {
1991 return Err("Code 2 packet has no data");
1992 }
1993 let (first_len, header_size) = read_opus_frame_len(data, 0)?;
1994 if header_size + first_len > data.len() {
1995 return Err("Code 2: first frame size exceeds packet");
1996 }
1997 frame_payloads = vec![
1998 &data[header_size..header_size + first_len],
1999 &data[header_size + first_len..],
2000 ];
2001 }
2002 3 => {
2003 if input.len() < 2 {
2009 return Err("Code 3 packet too short");
2010 }
2011 let count_byte = input[1];
2012 let m = (count_byte & 0x3F) as usize;
2013 if m < 1 || m > 48 {
2014 return Err("Code 3: invalid frame count");
2015 }
2016 if m as i32 * repacketizer::samples_per_frame(toc, 48000) > 5760 {
2023 return Err("Code 3: packet duration exceeds 120 ms");
2024 }
2025 frame_count = m;
2026 let vbr = (count_byte & 0x80) != 0;
2027 let padding = (count_byte & 0x40) != 0;
2028
2029 let mut ptr = 2usize;
2032 let mut pad_len = 0usize;
2033 if padding {
2034 loop {
2035 let p = *input.get(ptr).ok_or("Code 3: padding overflow")? as usize;
2036 ptr += 1;
2037 if p == 255 {
2038 pad_len += 254;
2039 } else {
2040 pad_len += p;
2041 break;
2042 }
2043 }
2044 }
2045 let end = input
2046 .len()
2047 .checked_sub(pad_len)
2048 .ok_or("Code 3: padding exceeds packet")?;
2049 if ptr > end {
2050 return Err("Code 3: padding exceeds packet");
2051 }
2052 let region = &input[ptr..end];
2055
2056 if vbr {
2057 let mut lens = Vec::with_capacity(m.saturating_sub(1));
2060 let mut hp = 0usize;
2061 for _ in 0..m - 1 {
2062 let (l, nb) = read_opus_frame_len(region, hp)?;
2063 hp += nb;
2064 lens.push(l);
2065 }
2066 let mut payloads = Vec::with_capacity(m);
2067 let mut fp = hp;
2068 for &l in &lens {
2069 if fp + l > region.len() {
2070 return Err("Code 3 VBR: frame length exceeds packet");
2071 }
2072 payloads.push(®ion[fp..fp + l]);
2073 fp += l;
2074 }
2075 if fp > region.len() {
2076 return Err("Code 3 VBR: no data for last frame");
2077 }
2078 payloads.push(®ion[fp..]);
2079 frame_payloads = payloads;
2080 } else {
2081 if region.len() % m != 0 {
2084 return Err("Code 3 CBR: frame data not divisible by frame count");
2085 }
2086 let frame_len = region.len() / m;
2087 frame_payloads = (0..m)
2088 .map(|i| ®ion[i * frame_len..(i + 1) * frame_len])
2089 .collect();
2090 }
2091 }
2092 _ => unreachable!(),
2093 }
2094
2095 let packet_frame_samples =
2106 repacketizer::samples_per_frame(toc, self.sampling_rate) as usize;
2107 if frame_count * packet_frame_samples > frame_size {
2108 return Err("Output buffer too small");
2109 }
2110
2111 self.frame_size = frame_size;
2112 self.bandwidth = bandwidth;
2113 self.stream_channels = packet_channels;
2114
2115 let sub_frame_size = frame_size / frame_count;
2116 let sub_output_len = sub_frame_size * self.channels;
2117
2118 match mode {
2119 OpusMode::SilkOnly => {
2120 let internal_sample_rate = match bandwidth {
2121 Bandwidth::Narrowband => 8000,
2122 Bandwidth::Mediumband => 12000,
2123 Bandwidth::Wideband => 16000,
2124 _ => 16000,
2125 };
2126 let internal_frame_size =
2127 (frame_duration_ms * internal_sample_rate / 1000) as usize;
2128
2129 if self.sampling_rate != internal_sample_rate
2130 && internal_sample_rate != self.prev_internal_rate
2131 {
2132 self.silk_resampler
2133 .init(internal_sample_rate, self.sampling_rate);
2134 self.silk_resampler_r
2135 .init(internal_sample_rate, self.sampling_rate);
2136 self.prev_internal_rate = internal_sample_rate;
2137 }
2138
2139 let silk_lr = self.channels == 2 && packet_channels == 2;
2142 self.silk_dec.produce_lr = silk_lr;
2143
2144 let prev_internal_ch = self.silk_dec.n_channels_internal;
2146 if packet_channels as i32 > prev_internal_ch {
2147 silk::init_decoder::silk_init_decoder(
2149 &mut self.silk_dec.channel_state[1],
2150 );
2151 }
2152 if self.channels == 2 && packet_channels == 2 && prev_internal_ch == 1 {
2153 self.silk_dec.s_stereo_pred_prev_q13 = [0; 2];
2156 self.silk_dec.s_stereo_side = [0; 2];
2157 self.silk_resampler_r = self.silk_resampler.clone();
2158 }
2159 self.silk_dec.n_channels_internal = packet_channels as i32;
2160
2161 let n_silk = match frame_duration_ms {
2167 40 => 2,
2168 60 => 3,
2169 _ => 1,
2170 };
2171 let internal_sub_frame_size = internal_frame_size / n_silk;
2172 let ratio = self.sampling_rate as f64 / internal_sample_rate as f64;
2173 let mut prev_mode_frame = self.prev_mode;
2176
2177 for (fi, payload) in frame_payloads.iter().enumerate() {
2178 let mut rc = RangeCoder::new_decoder(payload);
2179 let pcm_i16_len = internal_sub_frame_size * self.channels;
2180 if pcm_i16_len + 2 > self.w_pcm_i16.len() {
2184 return Err("opus: SILK frame size exceeds buffer");
2185 }
2186 let out_start = fi * sub_output_len;
2187 let mut silk_off = 0usize; for sf in 0..n_silk {
2190 let s_mid = self.silk_s_mid;
2191 let ret = {
2192 let (silk_dec, pcm_i16) = (&mut self.silk_dec, &mut self.w_pcm_i16);
2193 pcm_i16[0] = s_mid[0];
2197 pcm_i16[1] = s_mid[1];
2198 silk_dec.decode(
2199 &mut rc,
2200 &mut pcm_i16[2..pcm_i16_len + 2],
2201 silk::decode_frame::FLAG_DECODE_NORMAL,
2202 sf == 0,
2203 frame_duration_ms,
2204 internal_sample_rate,
2205 )
2206 };
2207
2208 if ret < 0 {
2209 return Err("SILK decoding failed");
2210 }
2211
2212 let decoded_samples = ret as usize;
2213 if decoded_samples >= 2 {
2215 self.silk_s_mid[0] = self.w_pcm_i16[decoded_samples];
2216 self.silk_s_mid[1] = self.w_pcm_i16[decoded_samples + 1];
2217 }
2218 let base = out_start + silk_off * self.channels;
2219
2220 let out_len = if silk_lr {
2224 if self.sampling_rate == internal_sample_rate {
2225 for i in 0..decoded_samples {
2226 let l = self.silk_dec.l_out[i] as f32 / 32768.0;
2227 let r = self.silk_dec.r_out[i] as f32 / 32768.0;
2228 let idx = base + i * 2;
2229 if idx + 1 < output.len() {
2230 output[idx] = l;
2231 output[idx + 1] = r;
2232 }
2233 }
2234 decoded_samples
2235 } else {
2236 let out_len = (decoded_samples as f64 * ratio) as usize;
2237 self.silk_resampler.process(
2239 &mut self.w_pcm_resampled[..out_len],
2240 &self.silk_dec.l_out[..decoded_samples],
2241 decoded_samples as i32,
2242 );
2243 for i in 0..out_len {
2244 let idx = base + i * 2;
2245 if idx < output.len() {
2246 output[idx] = self.w_pcm_resampled[i] as f32 / 32768.0;
2247 }
2248 }
2249 self.silk_resampler_r.process(
2251 &mut self.w_pcm_resampled[..out_len],
2252 &self.silk_dec.r_out[..decoded_samples],
2253 decoded_samples as i32,
2254 );
2255 for i in 0..out_len {
2256 let idx = base + i * 2 + 1;
2257 if idx < output.len() {
2258 output[idx] = self.w_pcm_resampled[i] as f32 / 32768.0;
2259 }
2260 }
2261 out_len
2262 }
2263 } else if self.sampling_rate == internal_sample_rate {
2264 let frames = decoded_samples;
2265 for i in 0..frames {
2266 let v = self.w_pcm_i16[1 + i] as f32 / 32768.0;
2267 for ch in 0..self.channels {
2268 let idx = base + i * self.channels + ch;
2269 if idx < output.len() {
2270 output[idx] = v;
2271 }
2272 }
2273 }
2274 frames
2275 } else {
2276 let out_len = (decoded_samples as f64 * ratio) as usize;
2277 debug_assert!(out_len <= self.w_pcm_resampled.len());
2278 {
2279 let (silk_res, pcm_i16, pcm_out) = (
2280 &mut self.silk_resampler,
2281 &self.w_pcm_i16,
2282 &mut self.w_pcm_resampled,
2283 );
2284 silk_res.process(
2285 &mut pcm_out[..out_len],
2286 &pcm_i16[1..1 + decoded_samples],
2287 decoded_samples as i32,
2288 );
2289 }
2290 for i in 0..out_len {
2291 let v = self.w_pcm_resampled[i] as f32 / 32768.0;
2292 for ch in 0..self.channels {
2293 let idx = base + i * self.channels + ch;
2294 if idx < output.len() {
2295 output[idx] = v;
2296 }
2297 }
2298 }
2299 if self.channels == 2 {
2305 self.silk_resampler_r.process(
2306 &mut self.w_pcm_resampled[..out_len],
2307 &self.w_pcm_i16[1..1 + decoded_samples],
2308 decoded_samples as i32,
2309 );
2310 for i in 0..out_len {
2311 let idx = base + i * 2 + 1;
2312 if idx < output.len() {
2313 output[idx] = self.w_pcm_resampled[i] as f32 / 32768.0;
2314 }
2315 }
2316 }
2317 out_len
2318 };
2319 silk_off += out_len;
2320 }
2321
2322 let mut redundant_rng = 0u32;
2327 let mut redundancy = false;
2328 let mut celt_to_silk = false;
2329 let plen = payload.len();
2330 let f5 = (self.sampling_rate / 200) as usize;
2331 let f2_5 = f5 / 2;
2332 let red_end_band = celt_endband_for_bandwidth(bandwidth);
2333 let mut red_buf = [0.0f32; 480]; let mut red_bytes = 0usize;
2335 if self.sampling_rate == 48000 && rc.tell() + 17 <= (plen as i32) * 8 {
2336 redundancy = true;
2337 celt_to_silk = rc.decode_bit_logp(1);
2338 red_bytes = plen - (((rc.tell() + 7) >> 3) as usize);
2339 if red_bytes < 2 || red_bytes >= plen {
2340 redundancy = false;
2341 red_bytes = 0;
2342 }
2343 }
2344 if redundancy && celt_to_silk {
2348 redundant_rng = self.decode_redundant_celt(
2349 &payload[plen - red_bytes..],
2350 false,
2351 packet_channels,
2352 red_end_band,
2353 &mut red_buf[..f5 * self.channels],
2354 );
2355 }
2356 if self.sampling_rate == 48000
2361 && prev_mode_frame == Some(OpusMode::Hybrid)
2362 && !(redundancy && celt_to_silk && self.prev_redundancy)
2363 {
2364 let silence = [0xFFu8, 0xFF];
2365 let mut sil_buf = [0.0f32; 240]; self.celt_dec.set_stream_channels(packet_channels);
2367 let mut src = RangeCoder::new_decoder(&silence);
2368 self.celt_dec.decode_from_range_coder_with_band_range(
2369 &mut src,
2370 16,
2371 f2_5,
2372 &mut sil_buf[..f2_5 * self.channels],
2373 0,
2374 red_end_band,
2375 );
2376 let region = &mut output[out_start..out_start + sub_output_len];
2377 for i in 0..f2_5 {
2378 for c in 0..self.channels {
2379 region[i * self.channels + c] += sil_buf[c * f2_5 + i];
2380 }
2381 }
2382 }
2383 if redundancy && !celt_to_silk {
2387 redundant_rng = self.decode_redundant_celt(
2388 &payload[plen - red_bytes..],
2389 true,
2390 packet_channels,
2391 red_end_band,
2392 &mut red_buf[..f5 * self.channels],
2393 );
2394 }
2395 if redundancy {
2396 let window = modes::default_mode().window;
2397 let region = &mut output[out_start..out_start + sub_output_len];
2398 if celt_to_silk {
2399 redundancy_fade_start(
2400 region,
2401 &red_buf,
2402 f5,
2403 f2_5,
2404 self.channels,
2405 window,
2406 );
2407 } else {
2408 redundancy_fade_end(
2409 region,
2410 sub_frame_size,
2411 &red_buf,
2412 f5,
2413 f2_5,
2414 self.channels,
2415 window,
2416 );
2417 }
2418 }
2419 self.prev_redundancy = redundancy && !celt_to_silk;
2420 prev_mode_frame = Some(OpusMode::SilkOnly);
2421 self.last_range = rc.rng ^ redundant_rng;
2422 }
2423 self.prev_mode = Some(OpusMode::SilkOnly);
2424 Ok(frame_size)
2425 }
2426
2427 OpusMode::CeltOnly => {
2428 let celt_end_band = self.celt_end_band_from_toc(toc);
2429 if let Some(pm) = self.prev_mode {
2433 if pm != OpusMode::CeltOnly && !self.prev_redundancy {
2434 self.celt_dec.reset();
2435 }
2436 }
2437 self.prev_redundancy = false;
2438 self.celt_dec.set_stream_channels(packet_channels);
2440
2441 for (fi, payload) in frame_payloads.iter().enumerate() {
2442 let mut rc = RangeCoder::new_decoder(payload);
2443 let total_bits = (payload.len() * 8) as i32;
2444 let needed = sub_frame_size * self.channels;
2445 let out_start = fi * needed;
2446 let out_end = (out_start + needed).min(output.len());
2447
2448 if output.len() < out_end {
2449 return Err("Output buffer too small");
2450 }
2451
2452 if self.channels == 1 {
2453 self.celt_dec.decode_from_range_coder_with_band_range(
2454 &mut rc,
2455 total_bits,
2456 sub_frame_size,
2457 &mut output[out_start..out_end],
2458 0,
2459 celt_end_band,
2460 );
2461 for sample in &mut output[out_start..out_end] {
2462 *sample = sample.clamp(-1.0, 1.0);
2463 }
2464 } else {
2465 self.celt_dec.decode_from_range_coder_with_band_range(
2466 &mut rc,
2467 total_bits,
2468 sub_frame_size,
2469 &mut self.w_celt_planar[..needed],
2470 0,
2471 celt_end_band,
2472 );
2473 for i in 0..sub_frame_size {
2474 for ch in 0..self.channels {
2475 let idx = out_start + i * self.channels + ch;
2476 output[idx] =
2477 self.w_celt_planar[ch * sub_frame_size + i].clamp(-1.0, 1.0);
2478 }
2479 }
2480 }
2481 self.last_range = rc.rng;
2482 }
2483 self.prev_mode = Some(OpusMode::CeltOnly);
2484 Ok(frame_size)
2485 }
2486
2487 OpusMode::Hybrid => {
2488 let internal_sample_rate = 16000;
2489 let internal_frame_size =
2490 (frame_duration_ms * internal_sample_rate / 1000) as usize;
2491 let celt_end_band = self.celt_end_band_from_toc(toc);
2492
2493 if self.sampling_rate != internal_sample_rate
2494 && internal_sample_rate != self.prev_internal_rate
2495 {
2496 self.silk_resampler
2497 .init(internal_sample_rate, self.sampling_rate);
2498 self.silk_resampler_r
2499 .init(internal_sample_rate, self.sampling_rate);
2500 self.prev_internal_rate = internal_sample_rate;
2501 }
2502
2503 let silk_lr = self.channels == 2 && packet_channels == 2;
2507 self.silk_dec.produce_lr = silk_lr;
2508 let prev_internal_ch = self.silk_dec.n_channels_internal;
2509 if packet_channels as i32 > prev_internal_ch {
2510 silk::init_decoder::silk_init_decoder(&mut self.silk_dec.channel_state[1]);
2511 }
2512 if self.channels == 2 && packet_channels == 2 && prev_internal_ch == 1 {
2513 self.silk_dec.s_stereo_pred_prev_q13 = [0; 2];
2514 self.silk_dec.s_stereo_side = [0; 2];
2515 self.silk_resampler_r = self.silk_resampler.clone();
2516 }
2517 self.silk_dec.n_channels_internal = packet_channels as i32;
2518
2519 for (fi, payload) in frame_payloads.iter().enumerate() {
2520 let mut rc = RangeCoder::new_decoder(payload);
2521 let pcm_silk_i16_len = internal_frame_size * self.channels;
2522 if pcm_silk_i16_len + 2 > self.w_pcm_i16.len() {
2523 return Err("opus: SILK frame size exceeds buffer");
2524 }
2525
2526 let s_mid = self.silk_s_mid;
2532 let ret = {
2533 let (silk_dec, pcm_i16) = (&mut self.silk_dec, &mut self.w_pcm_i16);
2534 pcm_i16[0] = s_mid[0];
2535 pcm_i16[1] = s_mid[1];
2536 silk_dec.decode(
2537 &mut rc,
2538 &mut pcm_i16[2..pcm_silk_i16_len + 2],
2539 silk::decode_frame::FLAG_DECODE_NORMAL,
2540 true,
2541 frame_duration_ms,
2542 internal_sample_rate,
2543 )
2544 };
2545
2546 if ret < 0 {
2547 return Err("SILK decoding failed");
2548 }
2549
2550 let silk_out_len = sub_frame_size * self.channels;
2551 self.w_silk_out[..silk_out_len].fill(0.0);
2552 if ret > 0 {
2553 let decoded_samples = ret as usize;
2554 if decoded_samples >= 2 {
2555 self.silk_s_mid[0] = self.w_pcm_i16[decoded_samples];
2556 self.silk_s_mid[1] = self.w_pcm_i16[decoded_samples + 1];
2557 }
2558 let ratio = self.sampling_rate as f64 / internal_sample_rate as f64;
2559 let out_len =
2560 ((decoded_samples as f64 * ratio) as usize).min(sub_frame_size);
2561 debug_assert!(out_len <= self.w_pcm_resampled.len());
2562 if silk_lr {
2563 self.silk_resampler.process(
2566 &mut self.w_pcm_resampled[..out_len],
2567 &self.silk_dec.l_out[..decoded_samples],
2568 decoded_samples as i32,
2569 );
2570 for i in 0..out_len {
2571 self.w_silk_out[i * 2] = self.w_pcm_resampled[i] as f32 / 32768.0;
2572 }
2573 self.silk_resampler_r.process(
2574 &mut self.w_pcm_resampled[..out_len],
2575 &self.silk_dec.r_out[..decoded_samples],
2576 decoded_samples as i32,
2577 );
2578 for i in 0..out_len {
2579 self.w_silk_out[i * 2 + 1] =
2580 self.w_pcm_resampled[i] as f32 / 32768.0;
2581 }
2582 } else {
2583 self.silk_resampler.process(
2584 &mut self.w_pcm_resampled[..out_len],
2585 &self.w_pcm_i16[1..1 + decoded_samples],
2586 decoded_samples as i32,
2587 );
2588 for i in 0..out_len {
2589 let v = self.w_pcm_resampled[i] as f32 / 32768.0;
2590 for ch in 0..self.channels {
2591 self.w_silk_out[i * self.channels + ch] = v;
2592 }
2593 }
2594 if self.channels == 2 {
2597 self.silk_resampler_r.process(
2598 &mut self.w_pcm_resampled[..out_len],
2599 &self.w_pcm_i16[1..1 + decoded_samples],
2600 decoded_samples as i32,
2601 );
2602 for i in 0..out_len {
2603 self.w_silk_out[i * 2 + 1] =
2604 self.w_pcm_resampled[i] as f32 / 32768.0;
2605 }
2606 }
2607 }
2608 }
2609
2610 let plen = payload.len();
2617 let mut redundancy = false;
2618 let mut celt_to_silk = false;
2619 let mut red_bytes = 0usize;
2620 let mut effective_len = plen;
2621 if rc.tell() + 37 <= (plen as i32) * 8 {
2622 redundancy = rc.decode_bit_logp(12);
2623 if redundancy {
2624 celt_to_silk = rc.decode_bit_logp(1);
2625 red_bytes = rc.dec_uint(256) as usize + 2;
2626 if red_bytes <= effective_len {
2627 effective_len -= red_bytes;
2628 } else {
2629 red_bytes = 0;
2630 redundancy = false;
2631 }
2632 if redundancy && (effective_len as i32) * 8 < rc.tell() {
2633 effective_len = plen;
2634 red_bytes = 0;
2635 redundancy = false;
2636 }
2637 if redundancy {
2638 rc.storage -= red_bytes as u32;
2639 }
2640 }
2641 }
2642 let f5 = (self.sampling_rate / 200) as usize;
2643 let f2_5 = f5 / 2;
2644 let red_end_band = celt_endband_for_bandwidth(bandwidth);
2645 let mut red_buf = [0.0f32; 480];
2646 let mut redundant_rng = 0u32;
2647 let do_red = redundancy && self.sampling_rate == 48000;
2648 if do_red && celt_to_silk {
2651 redundant_rng = self.decode_redundant_celt(
2652 &payload[plen - red_bytes..],
2653 false,
2654 packet_channels,
2655 red_end_band,
2656 &mut red_buf[..f5 * self.channels],
2657 );
2658 }
2659
2660 if fi == 0 {
2663 if let Some(pm) = self.prev_mode {
2664 if pm != OpusMode::Hybrid && !self.prev_redundancy {
2665 self.celt_dec.reset();
2666 }
2667 }
2668 }
2669 self.celt_dec.set_stream_channels(packet_channels);
2670 let total_bits = (effective_len * 8) as i32;
2671 {
2672 let (celt_dec, celt_planar) = (&mut self.celt_dec, &mut self.w_celt_planar);
2673 celt_dec.decode_from_range_coder_with_band_range(
2674 &mut rc,
2675 total_bits,
2676 sub_frame_size,
2677 &mut celt_planar[..silk_out_len],
2678 17,
2679 celt_end_band,
2680 );
2681
2682 if self.channels == 1 {
2683 self.w_celt_out[..silk_out_len]
2684 .copy_from_slice(&self.w_celt_planar[..silk_out_len]);
2685 } else {
2686 for i in 0..sub_frame_size {
2687 for ch in 0..self.channels {
2688 self.w_celt_out[i * self.channels + ch] =
2689 self.w_celt_planar[ch * sub_frame_size + i];
2690 }
2691 }
2692 }
2693 }
2694
2695 let out_start = fi * silk_out_len;
2696 let total = silk_out_len.min(output.len() - out_start);
2697 for j in 0..total {
2698 output[out_start + j] =
2699 (self.w_silk_out[j] + self.w_celt_out[j]).clamp(-1.0, 1.0);
2700 }
2701
2702 if do_red && !celt_to_silk {
2705 redundant_rng = self.decode_redundant_celt(
2706 &payload[plen - red_bytes..],
2707 true,
2708 packet_channels,
2709 red_end_band,
2710 &mut red_buf[..f5 * self.channels],
2711 );
2712 }
2713 if do_red {
2714 let window = modes::default_mode().window;
2715 let region = &mut output[out_start..out_start + silk_out_len];
2716 if celt_to_silk {
2717 redundancy_fade_start(
2718 region,
2719 &red_buf,
2720 f5,
2721 f2_5,
2722 self.channels,
2723 window,
2724 );
2725 } else {
2726 redundancy_fade_end(
2727 region,
2728 sub_frame_size,
2729 &red_buf,
2730 f5,
2731 f2_5,
2732 self.channels,
2733 window,
2734 );
2735 }
2736 }
2737 self.prev_redundancy = redundancy && !celt_to_silk;
2738 self.last_range = rc.rng ^ redundant_rng;
2739 }
2740 self.prev_mode = Some(OpusMode::Hybrid);
2741 Ok(frame_size)
2742 }
2743 }
2744 }
2745}
2746
2747impl OpusDecoder {
2748 #[inline(always)]
2749 fn celt_end_band_from_toc(&self, toc: u8) -> usize {
2750 let mode = modes::default_mode();
2751 let top = mode.eff_ebands;
2752 if mode_from_toc(toc) == OpusMode::CeltOnly && toc >= 0x80 {
2753 const FROM_OPUS_TABLE: [u8; 16] = [
2754 0x80, 0x88, 0x90, 0x98, 0x40, 0x48, 0x50, 0x58, 0x20, 0x28, 0x30, 0x38, 0x00, 0x08,
2755 0x10, 0x18,
2756 ];
2757 let idx = ((toc >> 3) - 16) as usize;
2758 let data0 = FROM_OPUS_TABLE[idx] | (toc & 0x7);
2759 let trim = (data0 >> 5) as usize;
2760 return top.saturating_sub(2 * trim).max(1);
2761 }
2762 if mode_from_toc(toc) == OpusMode::Hybrid
2766 && bandwidth_from_toc(toc) == Bandwidth::Superwideband
2767 {
2768 return 19.min(top);
2769 }
2770 top
2771 }
2772
2773 fn decode_redundant_celt(
2778 &mut self,
2779 red: &[u8],
2780 reset_first: bool,
2781 packet_channels: usize,
2782 end_band: usize,
2783 buf: &mut [f32],
2784 ) -> u32 {
2785 if reset_first {
2786 self.celt_dec.reset();
2787 }
2788 self.celt_dec.set_stream_channels(packet_channels);
2789 let f5 = (self.sampling_rate / 200) as usize;
2790 let mut rrc = RangeCoder::new_decoder(red);
2791 let total_bits = (red.len() * 8) as i32;
2792 self.celt_dec.decode_from_range_coder_with_band_range(
2793 &mut rrc, total_bits, f5, buf, 0, end_band,
2794 );
2795 rrc.rng
2796 }
2797}
2798
2799fn celt_endband_for_bandwidth(bw: Bandwidth) -> usize {
2801 match bw {
2802 Bandwidth::Narrowband => 13,
2803 Bandwidth::Mediumband | Bandwidth::Wideband => 17,
2804 Bandwidth::Superwideband => 19,
2805 _ => 21,
2806 }
2807}
2808
2809fn redundancy_fade_start(
2822 out: &mut [f32],
2823 red: &[f32],
2824 f5: usize,
2825 f2_5: usize,
2826 channels: usize,
2827 window: &[f32],
2828) {
2829 for i in 0..f2_5 {
2830 for c in 0..channels {
2831 out[i * channels + c] = red[c * f5 + i];
2832 }
2833 }
2834 for i in 0..f2_5 {
2835 let w = window[i] * window[i];
2836 for c in 0..channels {
2837 let idx = (f2_5 + i) * channels + c;
2838 out[idx] = (1.0 - w) * red[c * f5 + f2_5 + i] + w * out[idx];
2839 }
2840 }
2841}
2842
2843fn redundancy_fade_end(
2855 out: &mut [f32],
2856 frame_samples: usize,
2857 red: &[f32],
2858 f5: usize,
2859 f2_5: usize,
2860 channels: usize,
2861 window: &[f32],
2862) {
2863 for i in 0..f2_5 {
2864 let w = window[i] * window[i];
2865 for c in 0..channels {
2866 let idx = (frame_samples - f2_5 + i) * channels + c;
2867 out[idx] = (1.0 - w) * out[idx] + w * red[c * f5 + f2_5 + i];
2868 }
2869 }
2870}
2871
2872fn frame_rate_from_params(sampling_rate: i32, frame_size: usize) -> Option<i32> {
2873 let frame_size = frame_size as i32;
2874 if frame_size == 0 || sampling_rate % frame_size != 0 {
2875 return None;
2876 }
2877 Some(sampling_rate / frame_size)
2878}
2879
2880fn gen_toc(mode: OpusMode, frame_rate: i32, bandwidth: Bandwidth, channels: usize) -> u8 {
2881 let mut rate = frame_rate;
2882 let mut period = 0;
2883 while rate < 400 {
2884 rate <<= 1;
2885 period += 1;
2886 }
2887
2888 let mut toc = match mode {
2889 OpusMode::SilkOnly => {
2890 let bw = (bandwidth as i32 - Bandwidth::Narrowband as i32) << 5;
2891 let per = (period - 2) << 3;
2892 (bw | per) as u8
2893 }
2894 OpusMode::CeltOnly => {
2895 let mut tmp = bandwidth as i32 - Bandwidth::Mediumband as i32;
2896 if tmp < 0 {
2897 tmp = 0;
2898 }
2899 let per = period << 3;
2900 (0x80 | (tmp << 5) | per) as u8
2901 }
2902 OpusMode::Hybrid => {
2903 let base_config = if bandwidth == Bandwidth::Superwideband {
2904 12
2905 } else {
2906 14
2907 };
2908 let period_offset = if frame_rate >= 100 { 0 } else { 1 };
2909 ((base_config + period_offset) << 3) as u8
2910 }
2911 };
2912
2913 if channels == 2 {
2914 toc |= 0x04;
2915 }
2916 toc
2917}
2918
2919fn mode_from_toc(toc: u8) -> OpusMode {
2920 if toc & 0x80 != 0 {
2921 OpusMode::CeltOnly
2922 } else if toc & 0x60 == 0x60 {
2923 OpusMode::Hybrid
2924 } else {
2925 OpusMode::SilkOnly
2926 }
2927}
2928
2929fn bandwidth_from_toc(toc: u8) -> Bandwidth {
2930 let mode = mode_from_toc(toc);
2931 match mode {
2932 OpusMode::SilkOnly => {
2933 let bw_bits = (toc >> 5) & 0x03;
2934 match bw_bits {
2935 0 => Bandwidth::Narrowband,
2936 1 => Bandwidth::Mediumband,
2937 2 => Bandwidth::Wideband,
2938 _ => Bandwidth::Wideband,
2939 }
2940 }
2941 OpusMode::Hybrid => {
2942 let bw_bit = (toc >> 4) & 0x01;
2943 if bw_bit == 0 {
2944 Bandwidth::Superwideband
2945 } else {
2946 Bandwidth::Fullband
2947 }
2948 }
2949 OpusMode::CeltOnly => {
2950 let bw_bits = (toc >> 5) & 0x03;
2951 match bw_bits {
2952 0 => Bandwidth::Mediumband,
2953 1 => Bandwidth::Wideband,
2954 2 => Bandwidth::Superwideband,
2955 3 => Bandwidth::Fullband,
2956 _ => Bandwidth::Fullband,
2957 }
2958 }
2959 }
2960}
2961
2962fn frame_duration_ms_from_toc(toc: u8) -> i32 {
2963 let mode = mode_from_toc(toc);
2964 match mode {
2965 OpusMode::SilkOnly => {
2966 let config = (toc >> 3) & 0x03;
2967 match config {
2968 0 => 10,
2969 1 => 20,
2970 2 => 40,
2971 3 => 60,
2972 _ => 20,
2973 }
2974 }
2975 OpusMode::Hybrid => {
2976 let config = (toc >> 3) & 0x01;
2977 if config == 0 { 10 } else { 20 }
2978 }
2979 OpusMode::CeltOnly => {
2980 let config = (toc >> 3) & 0x03;
2981 match config {
2982 0 => 2,
2983 1 => 5,
2984 2 => 10,
2985 3 => 20,
2986 _ => 20,
2987 }
2988 }
2989 }
2990}
2991
2992fn channels_from_toc(toc: u8) -> usize {
2993 if toc & 0x04 != 0 { 2 } else { 1 }
2994}
2995
2996fn read_opus_frame_len(data: &[u8], ptr: usize) -> Result<(usize, usize), &'static str> {
3000 let b0 = *data.get(ptr).ok_or("Opus frame length: truncated")? as usize;
3001 if b0 < 252 {
3002 Ok((b0, 1))
3003 } else {
3004 let b1 = *data.get(ptr + 1).ok_or("Opus frame length: truncated 2-byte")? as usize;
3005 Ok((b1 * 4 + b0, 2))
3006 }
3007}
3008
3009#[cfg(test)]
3010mod tests {
3011 use super::*;
3012
3013 fn frame_size_from_toc(toc: u8, sampling_rate: i32) -> Option<usize> {
3014 let mode = mode_from_toc(toc);
3015 match mode {
3016 OpusMode::CeltOnly => {
3017 let period = ((toc >> 3) & 0x03) as i32;
3018 let frame_rate = 400 >> period;
3019 if frame_rate == 0 || sampling_rate % frame_rate != 0 {
3020 return None;
3021 }
3022 Some((sampling_rate / frame_rate) as usize)
3023 }
3024 OpusMode::SilkOnly => {
3025 let duration_ms = frame_duration_ms_from_toc(toc);
3026 Some((sampling_rate as i64 * duration_ms as i64 / 1000) as usize)
3027 }
3028 OpusMode::Hybrid => {
3029 let duration_ms = frame_duration_ms_from_toc(toc);
3030 Some((sampling_rate as i64 * duration_ms as i64 / 1000) as usize)
3031 }
3032 }
3033 }
3034
3035 #[test]
3036 fn gen_toc_matches_celt_reference_values() {
3037 let sampling_rate = 48_000;
3038 let cases = [
3039 (120usize, 0xE0u8),
3040 (240usize, 0xE8u8),
3041 (480usize, 0xF0u8),
3042 (960usize, 0xF8u8),
3043 ];
3044
3045 for (frame_size, expected_toc) in cases {
3046 let frame_rate = frame_rate_from_params(sampling_rate, frame_size).unwrap();
3047 let toc = gen_toc(OpusMode::CeltOnly, frame_rate, Bandwidth::Fullband, 1);
3048 assert_eq!(
3049 toc, expected_toc,
3050 "frame_size {} expected TOC {:02X} got {:02X}",
3051 frame_size, expected_toc, toc
3052 );
3053 let decoded_size = frame_size_from_toc(toc, sampling_rate).unwrap();
3054 assert_eq!(decoded_size, frame_size);
3055 }
3056
3057 let stereo_toc = gen_toc(
3058 OpusMode::CeltOnly,
3059 frame_rate_from_params(sampling_rate, 960).unwrap(),
3060 Bandwidth::Fullband,
3061 2,
3062 );
3063 assert_eq!(channels_from_toc(stereo_toc), 2);
3064 }
3065
3066 #[test]
3067 fn test_celt_decoder_large_frame_sizes() {
3068 let sampling_rate = 48000;
3069 let channels = 1;
3070
3071 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
3072
3073 let frame_sizes = [120, 240, 480, 960];
3074
3075 for frame_size in frame_sizes {
3076 let toc = gen_toc(
3077 OpusMode::CeltOnly,
3078 frame_rate_from_params(sampling_rate, frame_size).unwrap(),
3079 Bandwidth::Fullband,
3080 channels,
3081 );
3082 let packet = [toc, 0, 0, 0, 0];
3083
3084 let mut output = vec![0.0f32; frame_size * channels];
3085
3086 let _ = decoder.decode(&packet, frame_size, &mut output);
3087 }
3088
3089 let channels = 2;
3090 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
3091
3092 for frame_size in frame_sizes {
3093 let toc = gen_toc(
3094 OpusMode::CeltOnly,
3095 frame_rate_from_params(sampling_rate, frame_size).unwrap(),
3096 Bandwidth::Fullband,
3097 channels,
3098 );
3099 let packet = [toc, 0, 0, 0, 0];
3100
3101 let mut output = vec![0.0f32; frame_size * channels];
3102 let _ = decoder.decode(&packet, frame_size, &mut output);
3103 }
3104 }
3105
3106 #[test]
3107 fn test_celt_decoder_edge_case_frame_sizes() {
3108 let sampling_rate = 48000;
3109 let channels = 1;
3110 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
3111
3112 let edge_sizes = [2048, 2167, 2168, 2169, 2880, 3072];
3113
3114 for frame_size in edge_sizes {
3115 let mut output = vec![0.0f32; frame_size * channels];
3116
3117 let _ = decoder.decode(&[0x80, 0, 0, 0], frame_size, &mut output);
3118 }
3119 }
3120
3121 #[test]
3128 fn test_invalid_small_frame_size_returns_error_not_panic() {
3129 let mut enc = OpusEncoder::new(48000, 2, Application::Voip).unwrap();
3130 enc.bitrate_bps = 64000;
3131 enc.complexity = 5;
3132 enc.use_cbr = true;
3133
3134 let input = vec![0.0f32; 48 * 2]; let mut output = vec![0u8; 256];
3137
3138 let result = enc.encode(&input, 48, &mut output);
3139 assert!(
3140 result.is_err(),
3141 "encode with invalid frame_size=48 should return Err, not panic"
3142 );
3143 }
3144
3145 #[test]
3148 fn test_invalid_small_frame_size_audio_application_returns_error() {
3149 let mut enc = OpusEncoder::new(48000, 1, Application::Audio).unwrap();
3150 let input = vec![0.0f32; 48];
3151 let mut output = vec![0u8; 256];
3152
3153 let result = enc.encode(&input, 48, &mut output);
3154 assert!(
3155 result.is_err(),
3156 "Audio/48kHz encoder with frame_size=48 should return Err"
3157 );
3158 }
3159}