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 w_pcm_i16: Vec<i16>,
1583 w_silk_out: Vec<f32>,
1584 w_pcm_resampled: Vec<i16>,
1585 w_celt_planar: Vec<f32>,
1586 w_celt_out: Vec<f32>,
1587
1588 silk_s_mid: [i16; 2],
1594
1595 pub last_range: u32,
1598
1599 aux: Option<Box<OpusDecoder>>,
1604 prev_used_aux: bool,
1609 prev_redundancy: bool,
1613}
1614
1615impl OpusDecoder {
1616 pub fn new(sampling_rate: i32, channels: usize) -> Result<Self, &'static str> {
1617 if ![8000, 12000, 16000, 24000, 48000].contains(&sampling_rate) {
1618 return Err("Invalid sampling rate");
1619 }
1620 if ![1, 2].contains(&channels) {
1621 return Err("Invalid number of channels");
1622 }
1623
1624 let mode = modes::default_mode();
1625 let celt_dec = CeltDecoder::new(mode, channels);
1626
1627 let mut silk_dec = silk::dec_api::SilkDecoder::new();
1628 silk_dec.init(sampling_rate.min(16000), channels as i32);
1629 silk_dec.channel_state[0].fs_api_hz = sampling_rate;
1630
1631 Ok(Self {
1632 celt_dec,
1633 silk_dec,
1634 sampling_rate,
1635 channels,
1636 prev_mode: None,
1637 frame_size: 0,
1638 bandwidth: Bandwidth::Auto,
1639 stream_channels: channels,
1640 silk_resampler: silk::resampler::SilkResampler::default(),
1641 silk_resampler_r: silk::resampler::SilkResampler::default(),
1642 prev_internal_rate: 0,
1643
1644 w_pcm_i16: vec![0i16; 5760 * channels],
1649
1650 w_silk_out: vec![0.0f32; 5760 * channels],
1651 w_pcm_resampled: vec![0i16; 5760 * channels],
1652 w_celt_planar: vec![0.0f32; 5760 * channels],
1653 w_celt_out: vec![0.0f32; 5760 * channels],
1654 silk_s_mid: [0; 2],
1655 last_range: 0,
1656 aux: None,
1657 prev_used_aux: false,
1658 prev_redundancy: false,
1659 })
1660 }
1661
1662 fn decode_plc(
1669 &mut self,
1670 frame_size: usize,
1671 output: &mut [f32],
1672 ) -> Result<usize, &'static str> {
1673 let out_samples = frame_size * self.channels;
1674 for v in output.iter_mut().take(out_samples) {
1675 *v = 0.0;
1676 }
1677 let mode = self.prev_mode.unwrap_or(OpusMode::SilkOnly);
1678 if mode == OpusMode::CeltOnly {
1679 self.celt_dec.conceal_lost(frame_size, output);
1682 self.prev_mode = Some(mode);
1683 return Ok(frame_size);
1684 }
1685
1686 let frame_ms = (frame_size as i32 * 1000 / self.sampling_rate).max(1);
1687 let internal_rate = if mode == OpusMode::Hybrid {
1688 16000
1689 } else {
1690 match self.bandwidth {
1691 Bandwidth::Narrowband => 8000,
1692 Bandwidth::Mediumband => 12000,
1693 _ => 16000,
1694 }
1695 };
1696 if self.sampling_rate != internal_rate && internal_rate != self.prev_internal_rate {
1697 self.silk_resampler.init(internal_rate, self.sampling_rate);
1698 self.prev_internal_rate = internal_rate;
1699 }
1700 let n_silk = match frame_ms {
1701 40 => 2,
1702 60 => 3,
1703 _ => 1,
1704 };
1705 let internal_frame = (frame_ms * internal_rate / 1000) as usize;
1706 let internal_sub = internal_frame / n_silk.max(1);
1707 let ratio = self.sampling_rate as f64 / internal_rate as f64;
1708 self.silk_dec.produce_lr = false;
1710 self.silk_dec.n_channels_internal = 1;
1711
1712 let mut off = 0usize; for sf in 0..n_silk {
1714 let mut rc = RangeCoder::new_decoder(&[]);
1715 let n16 = internal_sub;
1716 if n16 + 2 > self.w_pcm_i16.len() {
1717 return Err("opus PLC: frame exceeds buffer");
1718 }
1719 self.w_pcm_i16[0] = self.silk_s_mid[0];
1720 self.w_pcm_i16[1] = self.silk_s_mid[1];
1721 let ret = self.silk_dec.decode(
1722 &mut rc,
1723 &mut self.w_pcm_i16[2..n16 + 2],
1724 silk::decode_frame::FLAG_PACKET_LOST,
1725 sf == 0,
1726 frame_ms,
1727 internal_rate,
1728 );
1729 if ret < 0 {
1730 return Err("SILK PLC failed");
1731 }
1732 let dec = ret as usize;
1733 if dec >= 2 {
1734 self.silk_s_mid[0] = self.w_pcm_i16[dec];
1735 self.silk_s_mid[1] = self.w_pcm_i16[dec + 1];
1736 }
1737 let base = off * self.channels;
1738 let out_len = if self.sampling_rate == internal_rate {
1739 for i in 0..dec {
1740 let v = self.w_pcm_i16[1 + i] as f32 / 32768.0;
1741 for ch in 0..self.channels {
1742 let idx = base + i * self.channels + ch;
1743 if idx < output.len() {
1744 output[idx] = v;
1745 }
1746 }
1747 }
1748 dec
1749 } else {
1750 let out_len = (dec as f64 * ratio) as usize;
1751 let src: Vec<i16> = self.w_pcm_i16[1..1 + dec].to_vec();
1752 self.silk_resampler
1753 .process(&mut self.w_pcm_resampled[..out_len], &src, dec as i32);
1754 for i in 0..out_len {
1755 let v = self.w_pcm_resampled[i] as f32 / 32768.0;
1756 for ch in 0..self.channels {
1757 let idx = base + i * self.channels + ch;
1758 if idx < output.len() {
1759 output[idx] = v;
1760 }
1761 }
1762 }
1763 out_len
1764 };
1765 off += out_len;
1766 }
1767 self.prev_mode = Some(mode);
1768 Ok(frame_size)
1769 }
1770
1771 pub fn decode_fec(
1779 &mut self,
1780 packet: &[u8],
1781 frame_size: usize,
1782 output: &mut [f32],
1783 ) -> Result<usize, &'static str> {
1784 if packet.is_empty() {
1785 return self.decode_plc(frame_size, output);
1786 }
1787 let toc = packet[0];
1788 let mode = mode_from_toc(toc);
1789 if mode == OpusMode::CeltOnly || (toc & 0x03) != 0 {
1791 return self.decode_plc(frame_size, output);
1792 }
1793 let bandwidth = bandwidth_from_toc(toc);
1794 let payload = &packet[1..];
1795
1796 let out_samples = frame_size * self.channels;
1797 for v in output.iter_mut().take(out_samples) {
1798 *v = 0.0;
1799 }
1800 let frame_ms = (frame_size as i32 * 1000 / self.sampling_rate).max(1);
1801 let internal_rate = if mode == OpusMode::Hybrid {
1802 16000
1803 } else {
1804 match bandwidth {
1805 Bandwidth::Narrowband => 8000,
1806 Bandwidth::Mediumband => 12000,
1807 _ => 16000,
1808 }
1809 };
1810 if self.sampling_rate != internal_rate && internal_rate != self.prev_internal_rate {
1811 self.silk_resampler.init(internal_rate, self.sampling_rate);
1812 self.prev_internal_rate = internal_rate;
1813 }
1814 let internal_frame = (frame_ms * internal_rate / 1000) as usize;
1815 let ratio = self.sampling_rate as f64 / internal_rate as f64;
1816 self.silk_dec.produce_lr = false;
1817 self.silk_dec.n_channels_internal = 1;
1818
1819 let mut rc = RangeCoder::new_decoder(payload);
1820 let n16 = internal_frame;
1821 if n16 + 2 > self.w_pcm_i16.len() {
1822 return Err("opus FEC: frame exceeds buffer");
1823 }
1824 self.w_pcm_i16[0] = self.silk_s_mid[0];
1825 self.w_pcm_i16[1] = self.silk_s_mid[1];
1826 let ret = self.silk_dec.decode(
1827 &mut rc,
1828 &mut self.w_pcm_i16[2..n16 + 2],
1829 silk::decode_frame::FLAG_DECODE_LBRR,
1830 true,
1831 frame_ms,
1832 internal_rate,
1833 );
1834 if ret < 0 {
1835 return Err("SILK FEC failed");
1836 }
1837 let dec = ret as usize;
1838 if dec >= 2 {
1839 self.silk_s_mid[0] = self.w_pcm_i16[dec];
1840 self.silk_s_mid[1] = self.w_pcm_i16[dec + 1];
1841 }
1842 if self.sampling_rate == internal_rate {
1843 for i in 0..dec {
1844 let v = self.w_pcm_i16[1 + i] as f32 / 32768.0;
1845 for ch in 0..self.channels {
1846 let idx = i * self.channels + ch;
1847 if idx < output.len() {
1848 output[idx] = v;
1849 }
1850 }
1851 }
1852 } else {
1853 let out_len = (dec as f64 * ratio) as usize;
1854 let src: Vec<i16> = self.w_pcm_i16[1..1 + dec].to_vec();
1855 self.silk_resampler
1856 .process(&mut self.w_pcm_resampled[..out_len], &src, dec as i32);
1857 for i in 0..out_len {
1858 let v = self.w_pcm_resampled[i] as f32 / 32768.0;
1859 for ch in 0..self.channels {
1860 let idx = i * self.channels + ch;
1861 if idx < output.len() {
1862 output[idx] = v;
1863 }
1864 }
1865 }
1866 }
1867 self.prev_mode = Some(mode);
1868 Ok(frame_size)
1869 }
1870
1871 pub fn decode(
1872 &mut self,
1873 input: &[u8],
1874 frame_size: usize,
1875 output: &mut [f32],
1876 ) -> Result<usize, &'static str> {
1877 if input.is_empty() {
1879 return self.decode_plc(frame_size, output);
1880 }
1881
1882 let toc = input[0];
1883 let mode = mode_from_toc(toc);
1884 let packet_channels = channels_from_toc(toc);
1885 let bandwidth = bandwidth_from_toc(toc);
1886 let frame_duration_ms = frame_duration_ms_from_toc(toc);
1887
1888 let mono_in_stereo = packet_channels == 1 && self.channels == 2;
1899
1900 if packet_channels != self.channels && !mono_in_stereo {
1901 if self
1906 .aux
1907 .as_ref()
1908 .map(|a| a.channels != packet_channels)
1909 .unwrap_or(true)
1910 {
1911 self.aux = Some(Box::new(OpusDecoder::new(
1912 self.sampling_rate,
1913 packet_channels,
1914 )?));
1915 }
1916 if !self.prev_used_aux
1921 && packet_channels == 1
1922 && self.channels == 2
1923 && (mode == OpusMode::CeltOnly || mode == OpusMode::Hybrid)
1924 {
1925 let (aux_opt, primary) = (&mut self.aux, &self.celt_dec);
1926 if let Some(aux) = aux_opt.as_mut() {
1927 aux.celt_dec.seed_from(primary);
1928 }
1929 }
1930 let aux = self.aux.as_mut().unwrap();
1931 let mut buf = vec![0.0f32; frame_size * packet_channels];
1932 let n = aux.decode(input, frame_size, &mut buf)?;
1933 self.last_range = aux.last_range;
1934 if packet_channels == 1 && self.channels == 2 {
1935 for i in 0..n {
1936 let v = buf[i];
1937 output[2 * i] = v;
1938 output[2 * i + 1] = v;
1939 }
1940 } else if packet_channels == 2 && self.channels == 1 {
1941 for i in 0..n {
1942 output[i] = 0.5 * (buf[2 * i] + buf[2 * i + 1]);
1943 }
1944 } else {
1945 let m = (n * self.channels).min(output.len()).min(buf.len());
1946 output[..m].copy_from_slice(&buf[..m]);
1947 }
1948 self.prev_mode = Some(mode);
1949 self.prev_used_aux = true;
1950 return Ok(n);
1951 }
1952
1953 if self.prev_used_aux {
1959 self.prev_used_aux = false;
1960 if (mode == OpusMode::CeltOnly || mode == OpusMode::Hybrid) && self.channels == 2 {
1961 if let Some(aux) = self.aux.as_ref() {
1962 self.celt_dec.seed_from(&aux.celt_dec);
1963 }
1964 }
1965 }
1966
1967 let code = toc & 0x03;
1968 let frame_count: usize;
1969 let frame_payloads: Vec<&[u8]>;
1970
1971 match code {
1972 0 => {
1973 frame_count = 1;
1974 frame_payloads = vec![&input[1..]];
1975 }
1976 1 => {
1977 frame_count = 2;
1978 let half = (input.len() - 1) / 2;
1979 if half == 0 {
1980 return Err("Code 1: empty frame");
1981 }
1982 frame_payloads = vec![&input[1..1 + half], &input[1 + half..]];
1983 }
1984 2 => {
1985 frame_count = 2;
1986 let data = &input[1..];
1987 if data.is_empty() {
1988 return Err("Code 2 packet has no data");
1989 }
1990 let (first_len, header_size) = read_opus_frame_len(data, 0)?;
1991 if header_size + first_len > data.len() {
1992 return Err("Code 2: first frame size exceeds packet");
1993 }
1994 frame_payloads = vec![
1995 &data[header_size..header_size + first_len],
1996 &data[header_size + first_len..],
1997 ];
1998 }
1999 3 => {
2000 if input.len() < 2 {
2006 return Err("Code 3 packet too short");
2007 }
2008 let count_byte = input[1];
2009 let m = (count_byte & 0x3F) as usize;
2010 if m < 1 || m > 48 {
2011 return Err("Code 3: invalid frame count");
2012 }
2013 if m as i32 * repacketizer::samples_per_frame(toc, 48000) > 5760 {
2020 return Err("Code 3: packet duration exceeds 120 ms");
2021 }
2022 frame_count = m;
2023 let vbr = (count_byte & 0x80) != 0;
2024 let padding = (count_byte & 0x40) != 0;
2025
2026 let mut ptr = 2usize;
2029 let mut pad_len = 0usize;
2030 if padding {
2031 loop {
2032 let p = *input.get(ptr).ok_or("Code 3: padding overflow")? as usize;
2033 ptr += 1;
2034 if p == 255 {
2035 pad_len += 254;
2036 } else {
2037 pad_len += p;
2038 break;
2039 }
2040 }
2041 }
2042 let end = input
2043 .len()
2044 .checked_sub(pad_len)
2045 .ok_or("Code 3: padding exceeds packet")?;
2046 if ptr > end {
2047 return Err("Code 3: padding exceeds packet");
2048 }
2049 let region = &input[ptr..end];
2052
2053 if vbr {
2054 let mut lens = Vec::with_capacity(m.saturating_sub(1));
2057 let mut hp = 0usize;
2058 for _ in 0..m - 1 {
2059 let (l, nb) = read_opus_frame_len(region, hp)?;
2060 hp += nb;
2061 lens.push(l);
2062 }
2063 let mut payloads = Vec::with_capacity(m);
2064 let mut fp = hp;
2065 for &l in &lens {
2066 if fp + l > region.len() {
2067 return Err("Code 3 VBR: frame length exceeds packet");
2068 }
2069 payloads.push(®ion[fp..fp + l]);
2070 fp += l;
2071 }
2072 if fp > region.len() {
2073 return Err("Code 3 VBR: no data for last frame");
2074 }
2075 payloads.push(®ion[fp..]);
2076 frame_payloads = payloads;
2077 } else {
2078 if region.len() % m != 0 {
2081 return Err("Code 3 CBR: frame data not divisible by frame count");
2082 }
2083 let frame_len = region.len() / m;
2084 frame_payloads = (0..m)
2085 .map(|i| ®ion[i * frame_len..(i + 1) * frame_len])
2086 .collect();
2087 }
2088 }
2089 _ => unreachable!(),
2090 }
2091
2092 let packet_frame_samples =
2103 repacketizer::samples_per_frame(toc, self.sampling_rate) as usize;
2104 if frame_count * packet_frame_samples > frame_size {
2105 return Err("Output buffer too small");
2106 }
2107
2108 self.frame_size = frame_size;
2109 self.bandwidth = bandwidth;
2110 self.stream_channels = packet_channels;
2111
2112 let sub_frame_size = frame_size / frame_count;
2113 let sub_output_len = sub_frame_size * self.channels;
2114
2115 match mode {
2116 OpusMode::SilkOnly => {
2117 let internal_sample_rate = match bandwidth {
2118 Bandwidth::Narrowband => 8000,
2119 Bandwidth::Mediumband => 12000,
2120 Bandwidth::Wideband => 16000,
2121 _ => 16000,
2122 };
2123 let internal_frame_size =
2124 (frame_duration_ms * internal_sample_rate / 1000) as usize;
2125
2126 if self.sampling_rate != internal_sample_rate
2127 && internal_sample_rate != self.prev_internal_rate
2128 {
2129 self.silk_resampler
2130 .init(internal_sample_rate, self.sampling_rate);
2131 self.silk_resampler_r
2132 .init(internal_sample_rate, self.sampling_rate);
2133 self.prev_internal_rate = internal_sample_rate;
2134 }
2135
2136 let silk_lr = self.channels == 2 && packet_channels == 2;
2139 self.silk_dec.produce_lr = silk_lr;
2140
2141 let prev_internal_ch = self.silk_dec.n_channels_internal;
2143 if packet_channels as i32 > prev_internal_ch {
2144 silk::init_decoder::silk_init_decoder(
2146 &mut self.silk_dec.channel_state[1],
2147 );
2148 }
2149 if self.channels == 2 && packet_channels == 2 && prev_internal_ch == 1 {
2150 self.silk_dec.s_stereo_pred_prev_q13 = [0; 2];
2153 self.silk_dec.s_stereo_side = [0; 2];
2154 self.silk_resampler_r = self.silk_resampler.clone();
2155 }
2156 self.silk_dec.n_channels_internal = packet_channels as i32;
2157
2158 let n_silk = match frame_duration_ms {
2164 40 => 2,
2165 60 => 3,
2166 _ => 1,
2167 };
2168 let internal_sub_frame_size = internal_frame_size / n_silk;
2169 let ratio = self.sampling_rate as f64 / internal_sample_rate as f64;
2170 let mut prev_mode_frame = self.prev_mode;
2173
2174 for (fi, payload) in frame_payloads.iter().enumerate() {
2175 let mut rc = RangeCoder::new_decoder(payload);
2176 let pcm_i16_len = internal_sub_frame_size * self.channels;
2177 if pcm_i16_len + 2 > self.w_pcm_i16.len() {
2181 return Err("opus: SILK frame size exceeds buffer");
2182 }
2183 let out_start = fi * sub_output_len;
2184 let mut silk_off = 0usize; for sf in 0..n_silk {
2187 let s_mid = self.silk_s_mid;
2188 let ret = {
2189 let (silk_dec, pcm_i16) = (&mut self.silk_dec, &mut self.w_pcm_i16);
2190 pcm_i16[0] = s_mid[0];
2194 pcm_i16[1] = s_mid[1];
2195 silk_dec.decode(
2196 &mut rc,
2197 &mut pcm_i16[2..pcm_i16_len + 2],
2198 silk::decode_frame::FLAG_DECODE_NORMAL,
2199 sf == 0,
2200 frame_duration_ms,
2201 internal_sample_rate,
2202 )
2203 };
2204
2205 if ret < 0 {
2206 return Err("SILK decoding failed");
2207 }
2208
2209 let decoded_samples = ret as usize;
2210 if decoded_samples >= 2 {
2212 self.silk_s_mid[0] = self.w_pcm_i16[decoded_samples];
2213 self.silk_s_mid[1] = self.w_pcm_i16[decoded_samples + 1];
2214 }
2215 let base = out_start + silk_off * self.channels;
2216
2217 let out_len = if silk_lr {
2221 if self.sampling_rate == internal_sample_rate {
2222 for i in 0..decoded_samples {
2223 let l = self.silk_dec.l_out[i] as f32 / 32768.0;
2224 let r = self.silk_dec.r_out[i] as f32 / 32768.0;
2225 let idx = base + i * 2;
2226 if idx + 1 < output.len() {
2227 output[idx] = l;
2228 output[idx + 1] = r;
2229 }
2230 }
2231 decoded_samples
2232 } else {
2233 let out_len = (decoded_samples as f64 * ratio) as usize;
2234 self.silk_resampler.process(
2236 &mut self.w_pcm_resampled[..out_len],
2237 &self.silk_dec.l_out[..decoded_samples],
2238 decoded_samples as i32,
2239 );
2240 for i in 0..out_len {
2241 let idx = base + i * 2;
2242 if idx < output.len() {
2243 output[idx] = self.w_pcm_resampled[i] as f32 / 32768.0;
2244 }
2245 }
2246 self.silk_resampler_r.process(
2248 &mut self.w_pcm_resampled[..out_len],
2249 &self.silk_dec.r_out[..decoded_samples],
2250 decoded_samples as i32,
2251 );
2252 for i in 0..out_len {
2253 let idx = base + i * 2 + 1;
2254 if idx < output.len() {
2255 output[idx] = self.w_pcm_resampled[i] as f32 / 32768.0;
2256 }
2257 }
2258 out_len
2259 }
2260 } else if self.sampling_rate == internal_sample_rate {
2261 let frames = decoded_samples;
2262 for i in 0..frames {
2263 let v = self.w_pcm_i16[1 + i] as f32 / 32768.0;
2264 for ch in 0..self.channels {
2265 let idx = base + i * self.channels + ch;
2266 if idx < output.len() {
2267 output[idx] = v;
2268 }
2269 }
2270 }
2271 frames
2272 } else {
2273 let out_len = (decoded_samples as f64 * ratio) as usize;
2274 debug_assert!(out_len <= self.w_pcm_resampled.len());
2275 {
2276 let (silk_res, pcm_i16, pcm_out) = (
2277 &mut self.silk_resampler,
2278 &self.w_pcm_i16,
2279 &mut self.w_pcm_resampled,
2280 );
2281 silk_res.process(
2282 &mut pcm_out[..out_len],
2283 &pcm_i16[1..1 + decoded_samples],
2284 decoded_samples as i32,
2285 );
2286 }
2287 for i in 0..out_len {
2288 let v = self.w_pcm_resampled[i] as f32 / 32768.0;
2289 for ch in 0..self.channels {
2290 let idx = base + i * self.channels + ch;
2291 if idx < output.len() {
2292 output[idx] = v;
2293 }
2294 }
2295 }
2296 if self.channels == 2 {
2302 self.silk_resampler_r.process(
2303 &mut self.w_pcm_resampled[..out_len],
2304 &self.w_pcm_i16[1..1 + decoded_samples],
2305 decoded_samples as i32,
2306 );
2307 for i in 0..out_len {
2308 let idx = base + i * 2 + 1;
2309 if idx < output.len() {
2310 output[idx] = self.w_pcm_resampled[i] as f32 / 32768.0;
2311 }
2312 }
2313 }
2314 out_len
2315 };
2316 silk_off += out_len;
2317 }
2318
2319 let mut redundant_rng = 0u32;
2324 let mut redundancy = false;
2325 let mut celt_to_silk = false;
2326 let plen = payload.len();
2327 let f5 = (self.sampling_rate / 200) as usize;
2328 let f2_5 = f5 / 2;
2329 let red_end_band = celt_endband_for_bandwidth(bandwidth);
2330 let mut red_buf = [0.0f32; 480]; let mut red_bytes = 0usize;
2332 if self.sampling_rate == 48000 && rc.tell() + 17 <= (plen as i32) * 8 {
2333 redundancy = true;
2334 celt_to_silk = rc.decode_bit_logp(1);
2335 red_bytes = plen - (((rc.tell() + 7) >> 3) as usize);
2336 if red_bytes < 2 || red_bytes >= plen {
2337 redundancy = false;
2338 red_bytes = 0;
2339 }
2340 }
2341 if redundancy && celt_to_silk {
2345 redundant_rng = self.decode_redundant_celt(
2346 &payload[plen - red_bytes..],
2347 false,
2348 packet_channels,
2349 red_end_band,
2350 &mut red_buf[..f5 * self.channels],
2351 );
2352 }
2353 if self.sampling_rate == 48000
2358 && prev_mode_frame == Some(OpusMode::Hybrid)
2359 && !(redundancy && celt_to_silk && self.prev_redundancy)
2360 {
2361 let silence = [0xFFu8, 0xFF];
2362 let mut sil_buf = [0.0f32; 240]; self.celt_dec.set_stream_channels(packet_channels);
2364 let mut src = RangeCoder::new_decoder(&silence);
2365 self.celt_dec.decode_from_range_coder_with_band_range(
2366 &mut src,
2367 16,
2368 f2_5,
2369 &mut sil_buf[..f2_5 * self.channels],
2370 0,
2371 red_end_band,
2372 );
2373 let region = &mut output[out_start..out_start + sub_output_len];
2374 for i in 0..f2_5 {
2375 for c in 0..self.channels {
2376 region[i * self.channels + c] += sil_buf[c * f2_5 + i];
2377 }
2378 }
2379 }
2380 if redundancy && !celt_to_silk {
2384 redundant_rng = self.decode_redundant_celt(
2385 &payload[plen - red_bytes..],
2386 true,
2387 packet_channels,
2388 red_end_band,
2389 &mut red_buf[..f5 * self.channels],
2390 );
2391 }
2392 if redundancy {
2393 let window = modes::default_mode().window;
2394 let region = &mut output[out_start..out_start + sub_output_len];
2395 if celt_to_silk {
2396 redundancy_fade_start(
2397 region,
2398 &red_buf,
2399 f5,
2400 f2_5,
2401 self.channels,
2402 window,
2403 );
2404 } else {
2405 redundancy_fade_end(
2406 region,
2407 sub_frame_size,
2408 &red_buf,
2409 f5,
2410 f2_5,
2411 self.channels,
2412 window,
2413 );
2414 }
2415 }
2416 self.prev_redundancy = redundancy && !celt_to_silk;
2417 prev_mode_frame = Some(OpusMode::SilkOnly);
2418 self.last_range = rc.rng ^ redundant_rng;
2419 }
2420 self.prev_mode = Some(OpusMode::SilkOnly);
2421 Ok(frame_size)
2422 }
2423
2424 OpusMode::CeltOnly => {
2425 let celt_end_band = self.celt_end_band_from_toc(toc);
2426 if let Some(pm) = self.prev_mode {
2430 if pm != OpusMode::CeltOnly && !self.prev_redundancy {
2431 self.celt_dec.reset();
2432 }
2433 }
2434 self.prev_redundancy = false;
2435 self.celt_dec.set_stream_channels(packet_channels);
2437
2438 for (fi, payload) in frame_payloads.iter().enumerate() {
2439 let mut rc = RangeCoder::new_decoder(payload);
2440 let total_bits = (payload.len() * 8) as i32;
2441 let needed = sub_frame_size * self.channels;
2442 let out_start = fi * needed;
2443 let out_end = (out_start + needed).min(output.len());
2444
2445 if output.len() < out_end {
2446 return Err("Output buffer too small");
2447 }
2448
2449 if self.channels == 1 {
2450 self.celt_dec.decode_from_range_coder_with_band_range(
2451 &mut rc,
2452 total_bits,
2453 sub_frame_size,
2454 &mut output[out_start..out_end],
2455 0,
2456 celt_end_band,
2457 );
2458 for sample in &mut output[out_start..out_end] {
2459 *sample = sample.clamp(-1.0, 1.0);
2460 }
2461 } else {
2462 self.celt_dec.decode_from_range_coder_with_band_range(
2463 &mut rc,
2464 total_bits,
2465 sub_frame_size,
2466 &mut self.w_celt_planar[..needed],
2467 0,
2468 celt_end_band,
2469 );
2470 for i in 0..sub_frame_size {
2471 for ch in 0..self.channels {
2472 let idx = out_start + i * self.channels + ch;
2473 output[idx] =
2474 self.w_celt_planar[ch * sub_frame_size + i].clamp(-1.0, 1.0);
2475 }
2476 }
2477 }
2478 self.last_range = rc.rng;
2479 }
2480 self.prev_mode = Some(OpusMode::CeltOnly);
2481 Ok(frame_size)
2482 }
2483
2484 OpusMode::Hybrid => {
2485 let internal_sample_rate = 16000;
2486 let internal_frame_size =
2487 (frame_duration_ms * internal_sample_rate / 1000) as usize;
2488 let celt_end_band = self.celt_end_band_from_toc(toc);
2489
2490 if self.sampling_rate != internal_sample_rate
2491 && internal_sample_rate != self.prev_internal_rate
2492 {
2493 self.silk_resampler
2494 .init(internal_sample_rate, self.sampling_rate);
2495 self.silk_resampler_r
2496 .init(internal_sample_rate, self.sampling_rate);
2497 self.prev_internal_rate = internal_sample_rate;
2498 }
2499
2500 let silk_lr = self.channels == 2 && packet_channels == 2;
2504 self.silk_dec.produce_lr = silk_lr;
2505 let prev_internal_ch = self.silk_dec.n_channels_internal;
2506 if packet_channels as i32 > prev_internal_ch {
2507 silk::init_decoder::silk_init_decoder(&mut self.silk_dec.channel_state[1]);
2508 }
2509 if self.channels == 2 && packet_channels == 2 && prev_internal_ch == 1 {
2510 self.silk_dec.s_stereo_pred_prev_q13 = [0; 2];
2511 self.silk_dec.s_stereo_side = [0; 2];
2512 self.silk_resampler_r = self.silk_resampler.clone();
2513 }
2514 self.silk_dec.n_channels_internal = packet_channels as i32;
2515
2516 for (fi, payload) in frame_payloads.iter().enumerate() {
2517 let mut rc = RangeCoder::new_decoder(payload);
2518 let pcm_silk_i16_len = internal_frame_size * self.channels;
2519 if pcm_silk_i16_len + 2 > self.w_pcm_i16.len() {
2520 return Err("opus: SILK frame size exceeds buffer");
2521 }
2522
2523 let s_mid = self.silk_s_mid;
2529 let ret = {
2530 let (silk_dec, pcm_i16) = (&mut self.silk_dec, &mut self.w_pcm_i16);
2531 pcm_i16[0] = s_mid[0];
2532 pcm_i16[1] = s_mid[1];
2533 silk_dec.decode(
2534 &mut rc,
2535 &mut pcm_i16[2..pcm_silk_i16_len + 2],
2536 silk::decode_frame::FLAG_DECODE_NORMAL,
2537 true,
2538 frame_duration_ms,
2539 internal_sample_rate,
2540 )
2541 };
2542
2543 if ret < 0 {
2544 return Err("SILK decoding failed");
2545 }
2546
2547 let silk_out_len = sub_frame_size * self.channels;
2548 self.w_silk_out[..silk_out_len].fill(0.0);
2549 if ret > 0 {
2550 let decoded_samples = ret as usize;
2551 if decoded_samples >= 2 {
2552 self.silk_s_mid[0] = self.w_pcm_i16[decoded_samples];
2553 self.silk_s_mid[1] = self.w_pcm_i16[decoded_samples + 1];
2554 }
2555 let ratio = self.sampling_rate as f64 / internal_sample_rate as f64;
2556 let out_len =
2557 ((decoded_samples as f64 * ratio) as usize).min(sub_frame_size);
2558 debug_assert!(out_len <= self.w_pcm_resampled.len());
2559 if silk_lr {
2560 self.silk_resampler.process(
2563 &mut self.w_pcm_resampled[..out_len],
2564 &self.silk_dec.l_out[..decoded_samples],
2565 decoded_samples as i32,
2566 );
2567 for i in 0..out_len {
2568 self.w_silk_out[i * 2] = self.w_pcm_resampled[i] as f32 / 32768.0;
2569 }
2570 self.silk_resampler_r.process(
2571 &mut self.w_pcm_resampled[..out_len],
2572 &self.silk_dec.r_out[..decoded_samples],
2573 decoded_samples as i32,
2574 );
2575 for i in 0..out_len {
2576 self.w_silk_out[i * 2 + 1] =
2577 self.w_pcm_resampled[i] as f32 / 32768.0;
2578 }
2579 } else {
2580 self.silk_resampler.process(
2581 &mut self.w_pcm_resampled[..out_len],
2582 &self.w_pcm_i16[1..1 + decoded_samples],
2583 decoded_samples as i32,
2584 );
2585 for i in 0..out_len {
2586 let v = self.w_pcm_resampled[i] as f32 / 32768.0;
2587 for ch in 0..self.channels {
2588 self.w_silk_out[i * self.channels + ch] = v;
2589 }
2590 }
2591 if self.channels == 2 {
2594 self.silk_resampler_r.process(
2595 &mut self.w_pcm_resampled[..out_len],
2596 &self.w_pcm_i16[1..1 + decoded_samples],
2597 decoded_samples as i32,
2598 );
2599 for i in 0..out_len {
2600 self.w_silk_out[i * 2 + 1] =
2601 self.w_pcm_resampled[i] as f32 / 32768.0;
2602 }
2603 }
2604 }
2605 }
2606
2607 let plen = payload.len();
2614 let mut redundancy = false;
2615 let mut celt_to_silk = false;
2616 let mut red_bytes = 0usize;
2617 let mut effective_len = plen;
2618 if rc.tell() + 37 <= (plen as i32) * 8 {
2619 redundancy = rc.decode_bit_logp(12);
2620 if redundancy {
2621 celt_to_silk = rc.decode_bit_logp(1);
2622 red_bytes = rc.dec_uint(256) as usize + 2;
2623 if red_bytes <= effective_len {
2624 effective_len -= red_bytes;
2625 } else {
2626 red_bytes = 0;
2627 redundancy = false;
2628 }
2629 if redundancy && (effective_len as i32) * 8 < rc.tell() {
2630 effective_len = plen;
2631 red_bytes = 0;
2632 redundancy = false;
2633 }
2634 if redundancy {
2635 rc.storage -= red_bytes as u32;
2636 }
2637 }
2638 }
2639 let f5 = (self.sampling_rate / 200) as usize;
2640 let f2_5 = f5 / 2;
2641 let red_end_band = celt_endband_for_bandwidth(bandwidth);
2642 let mut red_buf = [0.0f32; 480];
2643 let mut redundant_rng = 0u32;
2644 let do_red = redundancy && self.sampling_rate == 48000;
2645 if do_red && celt_to_silk {
2648 redundant_rng = self.decode_redundant_celt(
2649 &payload[plen - red_bytes..],
2650 false,
2651 packet_channels,
2652 red_end_band,
2653 &mut red_buf[..f5 * self.channels],
2654 );
2655 }
2656
2657 if fi == 0 {
2660 if let Some(pm) = self.prev_mode {
2661 if pm != OpusMode::Hybrid && !self.prev_redundancy {
2662 self.celt_dec.reset();
2663 }
2664 }
2665 }
2666 self.celt_dec.set_stream_channels(packet_channels);
2667 let total_bits = (effective_len * 8) as i32;
2668 {
2669 let (celt_dec, celt_planar) = (&mut self.celt_dec, &mut self.w_celt_planar);
2670 celt_dec.decode_from_range_coder_with_band_range(
2671 &mut rc,
2672 total_bits,
2673 sub_frame_size,
2674 &mut celt_planar[..silk_out_len],
2675 17,
2676 celt_end_band,
2677 );
2678
2679 if self.channels == 1 {
2680 self.w_celt_out[..silk_out_len]
2681 .copy_from_slice(&self.w_celt_planar[..silk_out_len]);
2682 } else {
2683 for i in 0..sub_frame_size {
2684 for ch in 0..self.channels {
2685 self.w_celt_out[i * self.channels + ch] =
2686 self.w_celt_planar[ch * sub_frame_size + i];
2687 }
2688 }
2689 }
2690 }
2691
2692 let out_start = fi * silk_out_len;
2693 let total = silk_out_len.min(output.len() - out_start);
2694 for j in 0..total {
2695 output[out_start + j] =
2696 (self.w_silk_out[j] + self.w_celt_out[j]).clamp(-1.0, 1.0);
2697 }
2698
2699 if do_red && !celt_to_silk {
2702 redundant_rng = self.decode_redundant_celt(
2703 &payload[plen - red_bytes..],
2704 true,
2705 packet_channels,
2706 red_end_band,
2707 &mut red_buf[..f5 * self.channels],
2708 );
2709 }
2710 if do_red {
2711 let window = modes::default_mode().window;
2712 let region = &mut output[out_start..out_start + silk_out_len];
2713 if celt_to_silk {
2714 redundancy_fade_start(
2715 region,
2716 &red_buf,
2717 f5,
2718 f2_5,
2719 self.channels,
2720 window,
2721 );
2722 } else {
2723 redundancy_fade_end(
2724 region,
2725 sub_frame_size,
2726 &red_buf,
2727 f5,
2728 f2_5,
2729 self.channels,
2730 window,
2731 );
2732 }
2733 }
2734 self.prev_redundancy = redundancy && !celt_to_silk;
2735 self.last_range = rc.rng ^ redundant_rng;
2736 }
2737 self.prev_mode = Some(OpusMode::Hybrid);
2738 Ok(frame_size)
2739 }
2740 }
2741 }
2742}
2743
2744impl OpusDecoder {
2745 #[inline(always)]
2746 fn celt_end_band_from_toc(&self, toc: u8) -> usize {
2747 let mode = modes::default_mode();
2748 let top = mode.eff_ebands;
2749 if mode_from_toc(toc) == OpusMode::CeltOnly && toc >= 0x80 {
2750 const FROM_OPUS_TABLE: [u8; 16] = [
2751 0x80, 0x88, 0x90, 0x98, 0x40, 0x48, 0x50, 0x58, 0x20, 0x28, 0x30, 0x38, 0x00, 0x08,
2752 0x10, 0x18,
2753 ];
2754 let idx = ((toc >> 3) - 16) as usize;
2755 let data0 = FROM_OPUS_TABLE[idx] | (toc & 0x7);
2756 let trim = (data0 >> 5) as usize;
2757 return top.saturating_sub(2 * trim).max(1);
2758 }
2759 if mode_from_toc(toc) == OpusMode::Hybrid
2763 && bandwidth_from_toc(toc) == Bandwidth::Superwideband
2764 {
2765 return 19.min(top);
2766 }
2767 top
2768 }
2769
2770 fn decode_redundant_celt(
2775 &mut self,
2776 red: &[u8],
2777 reset_first: bool,
2778 packet_channels: usize,
2779 end_band: usize,
2780 buf: &mut [f32],
2781 ) -> u32 {
2782 if reset_first {
2783 self.celt_dec.reset();
2784 }
2785 self.celt_dec.set_stream_channels(packet_channels);
2786 let f5 = (self.sampling_rate / 200) as usize;
2787 let mut rrc = RangeCoder::new_decoder(red);
2788 let total_bits = (red.len() * 8) as i32;
2789 self.celt_dec.decode_from_range_coder_with_band_range(
2790 &mut rrc, total_bits, f5, buf, 0, end_band,
2791 );
2792 rrc.rng
2793 }
2794}
2795
2796fn celt_endband_for_bandwidth(bw: Bandwidth) -> usize {
2798 match bw {
2799 Bandwidth::Narrowband => 13,
2800 Bandwidth::Mediumband | Bandwidth::Wideband => 17,
2801 Bandwidth::Superwideband => 19,
2802 _ => 21,
2803 }
2804}
2805
2806fn redundancy_fade_start(
2819 out: &mut [f32],
2820 red: &[f32],
2821 f5: usize,
2822 f2_5: usize,
2823 channels: usize,
2824 window: &[f32],
2825) {
2826 for i in 0..f2_5 {
2827 for c in 0..channels {
2828 out[i * channels + c] = red[c * f5 + i];
2829 }
2830 }
2831 for i in 0..f2_5 {
2832 let w = window[i] * window[i];
2833 for c in 0..channels {
2834 let idx = (f2_5 + i) * channels + c;
2835 out[idx] = (1.0 - w) * red[c * f5 + f2_5 + i] + w * out[idx];
2836 }
2837 }
2838}
2839
2840fn redundancy_fade_end(
2852 out: &mut [f32],
2853 frame_samples: usize,
2854 red: &[f32],
2855 f5: usize,
2856 f2_5: usize,
2857 channels: usize,
2858 window: &[f32],
2859) {
2860 for i in 0..f2_5 {
2861 let w = window[i] * window[i];
2862 for c in 0..channels {
2863 let idx = (frame_samples - f2_5 + i) * channels + c;
2864 out[idx] = (1.0 - w) * out[idx] + w * red[c * f5 + f2_5 + i];
2865 }
2866 }
2867}
2868
2869fn frame_rate_from_params(sampling_rate: i32, frame_size: usize) -> Option<i32> {
2870 let frame_size = frame_size as i32;
2871 if frame_size == 0 || sampling_rate % frame_size != 0 {
2872 return None;
2873 }
2874 Some(sampling_rate / frame_size)
2875}
2876
2877fn gen_toc(mode: OpusMode, frame_rate: i32, bandwidth: Bandwidth, channels: usize) -> u8 {
2878 let mut rate = frame_rate;
2879 let mut period = 0;
2880 while rate < 400 {
2881 rate <<= 1;
2882 period += 1;
2883 }
2884
2885 let mut toc = match mode {
2886 OpusMode::SilkOnly => {
2887 let bw = (bandwidth as i32 - Bandwidth::Narrowband as i32) << 5;
2888 let per = (period - 2) << 3;
2889 (bw | per) as u8
2890 }
2891 OpusMode::CeltOnly => {
2892 let mut tmp = bandwidth as i32 - Bandwidth::Mediumband as i32;
2893 if tmp < 0 {
2894 tmp = 0;
2895 }
2896 let per = period << 3;
2897 (0x80 | (tmp << 5) | per) as u8
2898 }
2899 OpusMode::Hybrid => {
2900 let base_config = if bandwidth == Bandwidth::Superwideband {
2901 12
2902 } else {
2903 14
2904 };
2905 let period_offset = if frame_rate >= 100 { 0 } else { 1 };
2906 ((base_config + period_offset) << 3) as u8
2907 }
2908 };
2909
2910 if channels == 2 {
2911 toc |= 0x04;
2912 }
2913 toc
2914}
2915
2916fn mode_from_toc(toc: u8) -> OpusMode {
2917 if toc & 0x80 != 0 {
2918 OpusMode::CeltOnly
2919 } else if toc & 0x60 == 0x60 {
2920 OpusMode::Hybrid
2921 } else {
2922 OpusMode::SilkOnly
2923 }
2924}
2925
2926fn bandwidth_from_toc(toc: u8) -> Bandwidth {
2927 let mode = mode_from_toc(toc);
2928 match mode {
2929 OpusMode::SilkOnly => {
2930 let bw_bits = (toc >> 5) & 0x03;
2931 match bw_bits {
2932 0 => Bandwidth::Narrowband,
2933 1 => Bandwidth::Mediumband,
2934 2 => Bandwidth::Wideband,
2935 _ => Bandwidth::Wideband,
2936 }
2937 }
2938 OpusMode::Hybrid => {
2939 let bw_bit = (toc >> 4) & 0x01;
2940 if bw_bit == 0 {
2941 Bandwidth::Superwideband
2942 } else {
2943 Bandwidth::Fullband
2944 }
2945 }
2946 OpusMode::CeltOnly => {
2947 let bw_bits = (toc >> 5) & 0x03;
2948 match bw_bits {
2949 0 => Bandwidth::Mediumband,
2950 1 => Bandwidth::Wideband,
2951 2 => Bandwidth::Superwideband,
2952 3 => Bandwidth::Fullband,
2953 _ => Bandwidth::Fullband,
2954 }
2955 }
2956 }
2957}
2958
2959fn frame_duration_ms_from_toc(toc: u8) -> i32 {
2960 let mode = mode_from_toc(toc);
2961 match mode {
2962 OpusMode::SilkOnly => {
2963 let config = (toc >> 3) & 0x03;
2964 match config {
2965 0 => 10,
2966 1 => 20,
2967 2 => 40,
2968 3 => 60,
2969 _ => 20,
2970 }
2971 }
2972 OpusMode::Hybrid => {
2973 let config = (toc >> 3) & 0x01;
2974 if config == 0 { 10 } else { 20 }
2975 }
2976 OpusMode::CeltOnly => {
2977 let config = (toc >> 3) & 0x03;
2978 match config {
2979 0 => 2,
2980 1 => 5,
2981 2 => 10,
2982 3 => 20,
2983 _ => 20,
2984 }
2985 }
2986 }
2987}
2988
2989fn channels_from_toc(toc: u8) -> usize {
2990 if toc & 0x04 != 0 { 2 } else { 1 }
2991}
2992
2993fn read_opus_frame_len(data: &[u8], ptr: usize) -> Result<(usize, usize), &'static str> {
2997 let b0 = *data.get(ptr).ok_or("Opus frame length: truncated")? as usize;
2998 if b0 < 252 {
2999 Ok((b0, 1))
3000 } else {
3001 let b1 = *data.get(ptr + 1).ok_or("Opus frame length: truncated 2-byte")? as usize;
3002 Ok((b1 * 4 + b0, 2))
3003 }
3004}
3005
3006#[cfg(test)]
3007mod tests {
3008 use super::*;
3009
3010 fn frame_size_from_toc(toc: u8, sampling_rate: i32) -> Option<usize> {
3011 let mode = mode_from_toc(toc);
3012 match mode {
3013 OpusMode::CeltOnly => {
3014 let period = ((toc >> 3) & 0x03) as i32;
3015 let frame_rate = 400 >> period;
3016 if frame_rate == 0 || sampling_rate % frame_rate != 0 {
3017 return None;
3018 }
3019 Some((sampling_rate / frame_rate) as usize)
3020 }
3021 OpusMode::SilkOnly => {
3022 let duration_ms = frame_duration_ms_from_toc(toc);
3023 Some((sampling_rate as i64 * duration_ms as i64 / 1000) as usize)
3024 }
3025 OpusMode::Hybrid => {
3026 let duration_ms = frame_duration_ms_from_toc(toc);
3027 Some((sampling_rate as i64 * duration_ms as i64 / 1000) as usize)
3028 }
3029 }
3030 }
3031
3032 #[test]
3033 fn gen_toc_matches_celt_reference_values() {
3034 let sampling_rate = 48_000;
3035 let cases = [
3036 (120usize, 0xE0u8),
3037 (240usize, 0xE8u8),
3038 (480usize, 0xF0u8),
3039 (960usize, 0xF8u8),
3040 ];
3041
3042 for (frame_size, expected_toc) in cases {
3043 let frame_rate = frame_rate_from_params(sampling_rate, frame_size).unwrap();
3044 let toc = gen_toc(OpusMode::CeltOnly, frame_rate, Bandwidth::Fullband, 1);
3045 assert_eq!(
3046 toc, expected_toc,
3047 "frame_size {} expected TOC {:02X} got {:02X}",
3048 frame_size, expected_toc, toc
3049 );
3050 let decoded_size = frame_size_from_toc(toc, sampling_rate).unwrap();
3051 assert_eq!(decoded_size, frame_size);
3052 }
3053
3054 let stereo_toc = gen_toc(
3055 OpusMode::CeltOnly,
3056 frame_rate_from_params(sampling_rate, 960).unwrap(),
3057 Bandwidth::Fullband,
3058 2,
3059 );
3060 assert_eq!(channels_from_toc(stereo_toc), 2);
3061 }
3062
3063 #[test]
3064 fn test_celt_decoder_large_frame_sizes() {
3065 let sampling_rate = 48000;
3066 let channels = 1;
3067
3068 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
3069
3070 let frame_sizes = [120, 240, 480, 960];
3071
3072 for frame_size in frame_sizes {
3073 let toc = gen_toc(
3074 OpusMode::CeltOnly,
3075 frame_rate_from_params(sampling_rate, frame_size).unwrap(),
3076 Bandwidth::Fullband,
3077 channels,
3078 );
3079 let packet = [toc, 0, 0, 0, 0];
3080
3081 let mut output = vec![0.0f32; frame_size * channels];
3082
3083 let _ = decoder.decode(&packet, frame_size, &mut output);
3084 }
3085
3086 let channels = 2;
3087 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
3088
3089 for frame_size in frame_sizes {
3090 let toc = gen_toc(
3091 OpusMode::CeltOnly,
3092 frame_rate_from_params(sampling_rate, frame_size).unwrap(),
3093 Bandwidth::Fullband,
3094 channels,
3095 );
3096 let packet = [toc, 0, 0, 0, 0];
3097
3098 let mut output = vec![0.0f32; frame_size * channels];
3099 let _ = decoder.decode(&packet, frame_size, &mut output);
3100 }
3101 }
3102
3103 #[test]
3104 fn test_celt_decoder_edge_case_frame_sizes() {
3105 let sampling_rate = 48000;
3106 let channels = 1;
3107 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
3108
3109 let edge_sizes = [2048, 2167, 2168, 2169, 2880, 3072];
3110
3111 for frame_size in edge_sizes {
3112 let mut output = vec![0.0f32; frame_size * channels];
3113
3114 let _ = decoder.decode(&[0x80, 0, 0, 0], frame_size, &mut output);
3115 }
3116 }
3117
3118 #[test]
3125 fn test_invalid_small_frame_size_returns_error_not_panic() {
3126 let mut enc = OpusEncoder::new(48000, 2, Application::Voip).unwrap();
3127 enc.bitrate_bps = 64000;
3128 enc.complexity = 5;
3129 enc.use_cbr = true;
3130
3131 let input = vec![0.0f32; 48 * 2]; let mut output = vec![0u8; 256];
3134
3135 let result = enc.encode(&input, 48, &mut output);
3136 assert!(
3137 result.is_err(),
3138 "encode with invalid frame_size=48 should return Err, not panic"
3139 );
3140 }
3141
3142 #[test]
3145 fn test_invalid_small_frame_size_audio_application_returns_error() {
3146 let mut enc = OpusEncoder::new(48000, 1, Application::Audio).unwrap();
3147 let input = vec![0.0f32; 48];
3148 let mut output = vec![0u8; 256];
3149
3150 let result = enc.encode(&input, 48, &mut output);
3151 assert!(
3152 result.is_err(),
3153 "Audio/48kHz encoder with frame_size=48 should return Err"
3154 );
3155 }
3156}