1#![cfg_attr(not(feature = "std"), no_std)]
2#![allow(unsafe_op_in_unsafe_fn)]
3#![allow(clippy::too_many_arguments)]
4#![allow(clippy::needless_range_loop)]
5
6mod compat;
7mod fixedvec;
8
9pub mod bands;
10pub mod celt;
11pub mod celt_lpc;
12pub mod hp_cutoff;
13pub mod kiss_fft;
14pub mod mdct;
15pub mod modes;
16#[cfg(feature = "std")]
20pub mod multistream;
21pub mod pitch;
22pub mod pvq;
23pub mod quant_bands;
24pub mod range_coder;
25pub mod rate;
26pub mod silk;
27
28pub use silk::{SilkResampler, SilkResamplerDown1_3, SilkResamplerDown1_6};
29
30use crate::fixedvec::FixedVec;
31pub use celt::{CeltDecoder, CeltEncoder};
32use hp_cutoff::{dc_reject_float, hp_cutoff, hp_cutoff_float, hp_cutoff_i16};
33use range_coder::RangeCoder;
34use silk::control_codec::{silk_control_encoder, silk_setup_lbrr};
35use silk::enc_api::{silk_encode, silk_encode_prefill};
36use silk::init_encoder::silk_init_encoder;
37use silk::lin2log::silk_lin2log;
38use silk::log2lin::silk_log2lin;
39use silk::macros::*;
40use silk::structs::SilkEncoderState;
41
42const OPUS_MAX_CHANNELS: usize = 2;
44const OPUS_MAX_FRAME: usize = 5760;
47const OPUS_MAX_SUBFRAME: usize = 2880;
51const OPUS_SUBFRAME_SCRATCH: usize = OPUS_MAX_SUBFRAME * OPUS_MAX_CHANNELS;
53const OPUS_HP_MEM: usize = OPUS_MAX_CHANNELS * 2;
55const OPUS_PCM_I16: usize = 960 * OPUS_MAX_CHANNELS;
57const OPUS_PCM_TAIL: usize = 240 * OPUS_MAX_CHANNELS;
59const OPUS_MAX_PACKET_FRAMES: usize = 48;
62const OPUS_MAX_PACKET_BYTES: usize = 1276;
64const OPUS_DELAY_BUF: usize = 480 * OPUS_MAX_CHANNELS;
67const OPUS_PCM_BUF: usize = (192 + OPUS_MAX_SUBFRAME) * OPUS_MAX_CHANNELS;
70
71#[derive(Debug, Clone, Copy, PartialEq, Eq)]
72pub enum Application {
73 Voip = 2048,
74 Audio = 2049,
75 RestrictedLowDelay = 2051,
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq)]
79pub enum Bandwidth {
80 Auto = -1000,
81 Narrowband = 1101,
82 Mediumband = 1102,
83 Wideband = 1103,
84 Superwideband = 1104,
85 Fullband = 1105,
86}
87
88#[derive(Debug, Clone, Copy, PartialEq, Eq)]
89enum OpusMode {
90 SilkOnly,
91 Hybrid,
92 CeltOnly,
93}
94
95pub struct OpusEncoder {
96 #[cfg(not(feature = "heap"))]
97 celt_enc: CeltEncoder,
98 #[cfg(feature = "heap")]
99 celt_enc: Box<CeltEncoder>,
100 #[cfg(not(feature = "heap"))]
101 silk_enc: SilkEncoderState,
102 #[cfg(feature = "heap")]
103 silk_enc: Box<SilkEncoderState>,
104 application: Application,
105 sampling_rate: i32,
106 channels: usize,
107 bandwidth: Bandwidth,
108 pub bitrate_bps: i32,
109 pub complexity: i32,
110 pub use_cbr: bool,
111
112 pub use_inband_fec: bool,
113
114 pub packet_loss_perc: i32,
115 silk_initialized: bool,
116 mode: OpusMode,
117 prev_enc_mode: Option<OpusMode>,
118 forced_mode: Option<OpusMode>,
122
123 variable_hp_smth2_q15: i32,
124 hp_mem: FixedVec<i32, OPUS_HP_MEM>,
125
126 #[cfg(not(feature = "heap"))]
127 buf_filtered: FixedVec<i16, OPUS_MAX_FRAME>,
128 #[cfg(feature = "heap")]
129 buf_filtered: Box<FixedVec<i16, OPUS_MAX_FRAME>>,
130 #[cfg(not(feature = "heap"))]
131 buf_silk_input: FixedVec<i16, OPUS_MAX_FRAME>,
132 #[cfg(feature = "heap")]
133 buf_silk_input: Box<FixedVec<i16, OPUS_MAX_FRAME>>,
134 #[cfg(not(feature = "heap"))]
135 buf_stereo_mid: FixedVec<i16, OPUS_MAX_FRAME>,
136 #[cfg(feature = "heap")]
137 buf_stereo_mid: Box<FixedVec<i16, OPUS_MAX_FRAME>>,
138 #[cfg(not(feature = "heap"))]
139 buf_stereo_side: FixedVec<i16, OPUS_MAX_FRAME>,
140 #[cfg(feature = "heap")]
141 buf_stereo_side: Box<FixedVec<i16, OPUS_MAX_FRAME>>,
142 #[cfg(not(feature = "heap"))]
143 buf_celt_input: FixedVec<f32, OPUS_MAX_FRAME>,
144 #[cfg(feature = "heap")]
145 buf_celt_input: Box<FixedVec<f32, OPUS_MAX_FRAME>>,
146 #[cfg(not(feature = "heap"))]
149 delay_buffer: FixedVec<f32, OPUS_DELAY_BUF>,
150 #[cfg(feature = "heap")]
151 delay_buffer: Box<FixedVec<f32, OPUS_DELAY_BUF>>,
152 #[cfg(not(feature = "heap"))]
155 buf_celt_pcm: FixedVec<f32, OPUS_PCM_BUF>,
156 #[cfg(feature = "heap")]
157 buf_celt_pcm: Box<FixedVec<f32, OPUS_PCM_BUF>>,
158 #[cfg(not(feature = "heap"))]
161 buf_f32_frame: FixedVec<f32, OPUS_MAX_FRAME>,
162 #[cfg(feature = "heap")]
163 buf_f32_frame: Box<FixedVec<f32, OPUS_MAX_FRAME>>,
164 encoder_buffer: usize,
167 delay_compensation: usize,
170 hp_mem_float: [f32; 4],
173 silk_resampler_enc: silk::resampler::SilkResampler,
178 silk_resampler_enc_side: silk::resampler::SilkResampler,
179
180 rc: RangeCoder,
181}
182
183#[derive(Clone, Copy)]
187enum PcmInput<'a> {
188 F32(&'a [f32]),
189 I16(&'a [i16]),
190}
191
192impl PcmInput<'_> {
193 fn len(&self) -> usize {
194 match self {
195 PcmInput::F32(s) => s.len(),
196 PcmInput::I16(s) => s.len(),
197 }
198 }
199}
200
201fn compute_equiv_rate(
202 bitrate: i32,
203 channels: usize,
204 frame_rate: i32,
205 vbr: bool,
206 complexity: i32,
207 loss: i32,
208) -> i32 {
209 let mut equiv = bitrate;
210 if frame_rate > 50 {
211 equiv -= (40 * channels as i32 + 20) * (frame_rate - 50);
212 }
213 if !vbr {
214 equiv -= equiv / 12;
215 }
216 equiv = equiv * (90 + complexity) / 100;
217 if loss > 0 {
218 equiv -= equiv * loss / (12 * loss + 20);
219 }
220 equiv
221}
222
223const FEC_THRESHOLDS: [i32; 10] = [
226 12000, 1000, 14000, 1000, 16000, 1000, 20000, 1000, 22000, 1000, ];
232
233fn bandwidth_fec_index(bw: Bandwidth) -> usize {
234 match bw {
235 Bandwidth::Narrowband => 0,
236 Bandwidth::Mediumband => 1,
237 Bandwidth::Wideband => 2,
238 Bandwidth::Superwideband => 3,
239 Bandwidth::Fullband | Bandwidth::Auto => 4,
240 }
241}
242
243fn bandwidth_from_fec_index(idx: usize) -> Bandwidth {
244 match idx {
245 0 => Bandwidth::Narrowband,
246 1 => Bandwidth::Mediumband,
247 2 => Bandwidth::Wideband,
248 3 => Bandwidth::Superwideband,
249 _ => Bandwidth::Fullband,
250 }
251}
252
253fn decide_fec(
258 use_in_band_fec: i32,
259 packet_loss_perc: i32,
260 last_fec: i32,
261 mode: OpusMode,
262 bandwidth: &mut Bandwidth,
263 rate: i32,
264) -> i32 {
265 if use_in_band_fec == 0 || packet_loss_perc == 0 || mode == OpusMode::CeltOnly {
266 return 0;
267 }
268 let orig_bandwidth = *bandwidth;
269 loop {
270 let idx = bandwidth_fec_index(*bandwidth);
271 let mut lbrr_rate_thres_bps = FEC_THRESHOLDS[2 * idx];
272 let hysteresis = FEC_THRESHOLDS[2 * idx + 1];
273 if last_fec == 1 {
274 lbrr_rate_thres_bps -= hysteresis;
275 }
276 if last_fec == 0 {
277 lbrr_rate_thres_bps += hysteresis;
278 }
279 lbrr_rate_thres_bps = silk_smulwb(
281 lbrr_rate_thres_bps * (125 - packet_loss_perc.min(25)),
282 655,
283 );
284 if rate > lbrr_rate_thres_bps {
287 return 1;
288 } else if packet_loss_perc <= 5 {
289 return 0;
290 } else if bandwidth_fec_index(*bandwidth) > 0 {
291 let lower = bandwidth_fec_index(*bandwidth) - 1;
292 *bandwidth = bandwidth_from_fec_index(lower);
293 } else {
294 break;
295 }
296 }
297 *bandwidth = orig_bandwidth;
299 0
300}
301
302fn compute_mode_threshold(
303 application: Application,
304 channels: usize,
305 prev_was_celt: bool,
306 has_prev_mode: bool,
307 voice_est: i32,
308) -> i32 {
309 let mode_voice = if channels == 1 { 64000 } else { 44000 };
310 let mode_music = 10000;
311
312 let diff = mode_voice - mode_music;
313 let offset = (voice_est * voice_est * diff) >> 14;
314 let mut threshold = mode_music + offset;
315
316 if application == Application::Voip {
317 threshold += 8000;
318 }
319
320 if has_prev_mode {
321 if prev_was_celt {
322 threshold -= 4000;
323 } else {
324 threshold += 4000;
325 }
326 }
327
328 if application == Application::RestrictedLowDelay {
329 threshold = 0;
330 }
331
332 threshold
333}
334
335fn compute_silk_rate_for_hybrid(rate_bps: i32, frame20ms: bool) -> i32 {
336 const RATE_TABLE: &[(i32, i32, i32)] = &[
337 (0, 0, 0),
338 (12000, 10000, 10000),
339 (16000, 13500, 13500),
340 (20000, 16000, 16000),
341 (24000, 18000, 18000),
342 (32000, 22000, 22000),
343 (64000, 38000, 38000),
344 ];
345 let n = RATE_TABLE.len();
346 let mut i = 1;
347 while i < n && RATE_TABLE[i].0 <= rate_bps {
348 i += 1;
349 }
350 if i == n {
351 let (x_last, r10_last, r20_last) = RATE_TABLE[n - 1];
352 let base = if frame20ms { r20_last } else { r10_last };
353 base + (rate_bps - x_last) / 2
354 } else {
355 let (x0, lo10, lo20) = RATE_TABLE[i - 1];
356 let (x1, hi10, hi20) = RATE_TABLE[i];
357 let (lo, hi) = if frame20ms {
358 (lo20, hi20)
359 } else {
360 (lo10, hi10)
361 };
362 (lo * (x1 - rate_bps) + hi * (rate_bps - x0)) / (x1 - x0)
363 }
364}
365
366#[cfg(all(test, feature = "std"))]
367mod silk_rate_tests {
368 use super::compute_silk_rate_for_hybrid;
369
370 #[test]
371 fn test_reference_table_exact_entries() {
372 assert_eq!(compute_silk_rate_for_hybrid(12000, true), 10000);
373 assert_eq!(compute_silk_rate_for_hybrid(16000, true), 13500);
374 assert_eq!(compute_silk_rate_for_hybrid(20000, true), 16000);
375 assert_eq!(compute_silk_rate_for_hybrid(24000, true), 18000);
376 assert_eq!(compute_silk_rate_for_hybrid(32000, true), 22000);
377 assert_eq!(compute_silk_rate_for_hybrid(64000, true), 38000);
378 }
379
380 #[test]
381 fn test_32kbps_gives_22kbps_silk() {
382 assert_eq!(compute_silk_rate_for_hybrid(32000, true), 22000);
383 }
384
385 #[test]
386 fn test_interpolation_between_table_entries() {
387 let r = compute_silk_rate_for_hybrid(18000, true);
388 assert_eq!(r, 14750);
389 }
390
391 #[test]
392 fn test_above_table_max_gives_half_extra() {
393 let r = compute_silk_rate_for_hybrid(72000, true);
394 assert_eq!(r, 38000 + (72000 - 64000) / 2);
395 }
396}
397
398#[cfg(feature = "heap")]
407#[inline(always)]
408fn state_ref<T: core::ops::Deref>(b: &T) -> &T::Target {
409 b
410}
411#[cfg(not(feature = "heap"))]
412#[inline(always)]
413fn state_ref<T: ?Sized>(b: &T) -> &T {
414 b
415}
416
417#[cfg(feature = "heap")]
418#[inline(always)]
419fn state_mut<T: core::ops::DerefMut>(b: &mut T) -> &mut T::Target {
420 b
421}
422#[cfg(not(feature = "heap"))]
423#[inline(always)]
424fn state_mut<T: ?Sized>(b: &mut T) -> &mut T {
425 b
426}
427
428impl OpusEncoder {
429 pub fn new(
430 sampling_rate: i32,
431 channels: usize,
432 application: Application,
433 ) -> Result<Self, &'static str> {
434 if ![8000, 12000, 16000, 24000, 48000].contains(&sampling_rate) {
435 return Err("Invalid sampling rate");
436 }
437 if ![1, 2].contains(&channels) {
438 return Err("Invalid number of channels");
439 }
440
441 let mode = modes::default_mode();
442 #[cfg(feature = "heap")]
443 let celt_enc = Box::new(CeltEncoder::with_sampling_rate(mode, channels, sampling_rate));
444 #[cfg(not(feature = "heap"))]
445 let celt_enc = CeltEncoder::with_sampling_rate(mode, channels, sampling_rate);
446
447 #[cfg(feature = "heap")]
448 let mut silk_enc = Box::new(SilkEncoderState::default());
449 #[cfg(not(feature = "heap"))]
450 let mut silk_enc = SilkEncoderState::default();
451 if silk_init_encoder(state_mut(&mut silk_enc), 0) != 0 {
452 return Err("SILK encoder initialization failed");
453 }
454
455 let (opus_mode, bw) = match application {
456 Application::Voip => {
457 let bw = match sampling_rate {
458 8000 => Bandwidth::Narrowband,
459 12000 => Bandwidth::Mediumband,
460 16000 => Bandwidth::Wideband,
461 24000 => Bandwidth::Superwideband,
462 48000 => Bandwidth::Fullband,
463 _ => Bandwidth::Narrowband,
464 };
465
466 let mode = if sampling_rate > 16000 {
467 OpusMode::Hybrid
468 } else {
469 OpusMode::SilkOnly
470 };
471 (mode, bw)
472 }
473 Application::RestrictedLowDelay => {
474 let bw = match sampling_rate {
475 8000 => Bandwidth::Narrowband,
476 12000 => Bandwidth::Mediumband,
477 16000 => Bandwidth::Wideband,
478 24000 => Bandwidth::Superwideband,
479 _ => Bandwidth::Fullband,
480 };
481 (OpusMode::CeltOnly, bw)
482 }
483 Application::Audio => {
484 if sampling_rate <= 16000 {
485 let bw = match sampling_rate {
486 8000 => Bandwidth::Narrowband,
487 12000 => Bandwidth::Mediumband,
488 _ => Bandwidth::Wideband,
489 };
490 (OpusMode::SilkOnly, bw)
491 } else {
492 let bw = match sampling_rate {
493 24000 => Bandwidth::Superwideband,
494 _ => Bandwidth::Fullband,
495 };
496 (OpusMode::Hybrid, bw)
497 }
498 }
499 };
500
501 use silk::lin2log::silk_lin2log;
502 let variable_hp_smth2_q15 = silk_lin2log(60) << 8;
503
504 Ok(Self {
505 celt_enc,
506 silk_enc,
507 application,
508 sampling_rate,
509 channels,
510 bandwidth: bw,
511 bitrate_bps: 64000,
512 complexity: 9,
513 use_cbr: false,
514 use_inband_fec: false,
515 packet_loss_perc: 0,
516 silk_initialized: false,
517 prev_enc_mode: None,
518 forced_mode: None,
519 mode: opus_mode,
520 variable_hp_smth2_q15,
521 hp_mem: FixedVec::from_value(0, channels * 2),
522
523 #[cfg(not(feature = "heap"))]
524 buf_filtered: FixedVec::new(),
525 #[cfg(feature = "heap")]
526 buf_filtered: Box::new(FixedVec::new()),
527 #[cfg(not(feature = "heap"))]
528 buf_silk_input: FixedVec::new(),
529 #[cfg(feature = "heap")]
530 buf_silk_input: Box::new(FixedVec::new()),
531 #[cfg(not(feature = "heap"))]
532 buf_stereo_mid: FixedVec::new(),
533 #[cfg(feature = "heap")]
534 buf_stereo_mid: Box::new(FixedVec::new()),
535 #[cfg(not(feature = "heap"))]
536 buf_stereo_side: FixedVec::new(),
537 #[cfg(feature = "heap")]
538 buf_stereo_side: Box::new(FixedVec::new()),
539 #[cfg(not(feature = "heap"))]
540 buf_celt_input: FixedVec::new(),
541 #[cfg(feature = "heap")]
542 buf_celt_input: Box::new(FixedVec::new()),
543 #[cfg(not(feature = "heap"))]
544 delay_buffer: FixedVec::from_value(0.0, OPUS_DELAY_BUF),
545 #[cfg(feature = "heap")]
546 delay_buffer: Box::new(FixedVec::from_value(0.0, OPUS_DELAY_BUF)),
547 #[cfg(not(feature = "heap"))]
548 buf_celt_pcm: FixedVec::new(),
549 #[cfg(feature = "heap")]
550 buf_celt_pcm: Box::new(FixedVec::new()),
551 #[cfg(not(feature = "heap"))]
552 buf_f32_frame: FixedVec::new(),
553 #[cfg(feature = "heap")]
554 buf_f32_frame: Box::new(FixedVec::new()),
555 encoder_buffer: if matches!(application, Application::RestrictedLowDelay) {
556 0
557 } else {
558 (sampling_rate / 100) as usize
559 },
560 delay_compensation: if matches!(application, Application::RestrictedLowDelay) {
561 0
562 } else {
563 (sampling_rate / 250) as usize
564 },
565 hp_mem_float: [0.0; 4],
566 silk_resampler_enc: silk::resampler::SilkResampler::default(),
567 silk_resampler_enc_side: silk::resampler::SilkResampler::default(),
568 rc: RangeCoder::new_encoder(1),
569 })
570 }
571
572 pub fn enable_hybrid_mode(&mut self) -> Result<(), &'static str> {
573 if self.sampling_rate != 24000 && self.sampling_rate != 48000 {
574 return Err("Hybrid mode requires 24kHz or 48kHz sampling rate");
575 }
576 let bw = if self.sampling_rate == 48000 {
577 Bandwidth::Fullband
578 } else {
579 Bandwidth::Superwideband
580 };
581 self.mode = OpusMode::Hybrid;
582 self.bandwidth = bw;
583 self.silk_initialized = false;
584 Ok(())
585 }
586
587 pub fn encode(
591 &mut self,
592 input: &[f32],
593 frame_size: usize,
594 output: &mut [u8],
595 ) -> Result<usize, &'static str> {
596 self.encode_impl(PcmInput::F32(input), frame_size, output)
597 }
598
599 pub fn encode_i16(
606 &mut self,
607 input: &[i16],
608 frame_size: usize,
609 output: &mut [u8],
610 ) -> Result<usize, &'static str> {
611 self.encode_impl(PcmInput::I16(input), frame_size, output)
612 }
613
614 fn encode_impl(
615 &mut self,
616 input: PcmInput<'_>,
617 frame_size: usize,
618 output: &mut [u8],
619 ) -> Result<usize, &'static str> {
620 if output.len() < 2 {
621 return Err("Output buffer too small");
622 }
623
624 let frame_rate = frame_rate_from_params(self.sampling_rate, frame_size)
625 .ok_or("Invalid frame size for sampling rate")?;
626
627 self.bitrate_bps = self.bitrate_bps.clamp(500, 3_000_000);
633 self.complexity = self.complexity.clamp(0, 10);
634 self.packet_loss_perc = self.packet_loss_perc.clamp(0, 100);
635
636 if input.len() < frame_size * self.channels {
640 return Err("Input buffer too small for frame");
641 }
642
643 let mut mode = if let Some(forced) = self.forced_mode {
647 forced
648 } else if self.application == Application::RestrictedLowDelay {
649 OpusMode::CeltOnly
650 } else {
651 let equiv = compute_equiv_rate(
652 self.bitrate_bps,
653 self.channels,
654 frame_rate,
655 !self.use_cbr,
656 self.complexity,
657 self.packet_loss_perc,
658 );
659 let prev_was_celt = self.prev_enc_mode == Some(OpusMode::CeltOnly);
660 let has_prev_mode = self.prev_enc_mode.is_some();
661 let voice_est = match self.application {
662 Application::Voip => 115,
663 Application::Audio => 48,
664 Application::RestrictedLowDelay => 0,
665 };
666 let threshold = compute_mode_threshold(
667 self.application,
668 self.channels,
669 prev_was_celt,
670 has_prev_mode,
671 voice_est,
672 );
673 if equiv >= threshold && self.sampling_rate >= 24000 {
674 OpusMode::CeltOnly
675 } else {
676 OpusMode::SilkOnly
677 }
678 };
679
680 if self.forced_mode.is_none() {
681 let curr_bw = self.bandwidth;
682 if mode == OpusMode::SilkOnly
683 && (curr_bw == Bandwidth::Superwideband || curr_bw == Bandwidth::Fullband)
684 {
685 mode = OpusMode::Hybrid;
686 }
687 if mode == OpusMode::Hybrid
688 && (curr_bw == Bandwidth::Narrowband
689 || curr_bw == Bandwidth::Mediumband
690 || curr_bw == Bandwidth::Wideband)
691 {
692 mode = OpusMode::SilkOnly;
693 }
694 }
695
696 let target_bits =
699 (self.bitrate_bps as i64 * frame_size as i64 / self.sampling_rate as i64) as i32;
700 let cbr_bytes = ((target_bits + 4) / 8) as usize;
701 let max_data_bytes = output.len();
702
703 let mut n_bytes = if self.use_cbr {
708 cbr_bytes
709 .min(max_data_bytes)
710 .clamp(1, OPUS_MAX_PACKET_BYTES)
711 } else {
712 max_data_bytes.clamp(1, OPUS_MAX_PACKET_BYTES)
713 };
714
715 let tiny_budget_rate: i64 = if frame_rate > 50 { 9000 } else { 6000 };
720 if ((n_bytes as i64) * 8 * (self.sampling_rate as i64))
721 < (tiny_budget_rate * (frame_size as i64))
722 {
723 mode = OpusMode::CeltOnly;
724 }
725
726 if self.forced_mode.is_none()
731 && mode != OpusMode::SilkOnly
732 && frame_size > self.sampling_rate as usize / 50
733 {
734 return self.encode_multiframe(input, frame_size, mode, output);
735 }
736
737 let mut frame_bandwidth = self.bandwidth;
744 let equiv_rate = compute_equiv_rate(
745 self.bitrate_bps,
746 self.channels,
747 frame_rate,
748 !self.use_cbr,
749 self.complexity,
750 self.packet_loss_perc,
751 );
752 let lbrr_coded = decide_fec(
753 if self.use_inband_fec { 1 } else { 0 },
754 self.packet_loss_perc,
755 self.silk_enc.s_cmn.lbrr_enabled,
756 mode,
757 &mut frame_bandwidth,
758 equiv_rate,
759 );
760 if mode == OpusMode::CeltOnly {
761 self.silk_enc.s_cmn.lbrr_enabled = 0;
764 }
765
766 if mode == OpusMode::CeltOnly {
767 match frame_rate {
768 400 | 200 | 100 | 50 => {}
769 _ => return Err("Unsupported frame size for CELT-only mode"),
770 }
771 }
772
773 if mode == OpusMode::Hybrid {
774 match frame_rate {
775 100 | 50 => {}
776 _ => return Err("Unsupported frame size for Hybrid mode"),
777 }
778 }
779
780 if mode == OpusMode::SilkOnly {
781 match frame_rate {
782 100 | 50 | 25 | 16 => {}
783 _ => return Err("Unsupported frame size for SILK-only mode"),
787 }
788 }
789
790 let toc = gen_toc(mode, frame_rate, frame_bandwidth, self.channels);
791 output[0] = toc;
792
793 let sub_3_bytes_per_frame =
799 (self.bitrate_bps as i64) < 3 * frame_rate as i64 * 8;
800 let tiny_long_frame =
801 frame_rate < 50
802 && (n_bytes * (frame_rate as usize) < 300 || self.bitrate_bps < 2400);
803 if n_bytes < 3 || sub_3_bytes_per_frame || tiny_long_frame {
804 let mut toc_mode = mode;
805 let mut packet_code = 0u8;
806 let mut num_multiframes = 0u8;
807 let mut frame_rate_adj = frame_rate;
808 if frame_rate > 100 {
809 toc_mode = OpusMode::CeltOnly;
810 }
811 if frame_rate == 25 && toc_mode != OpusMode::SilkOnly {
813 frame_rate_adj = 50;
814 packet_code = 1;
815 }
816 if frame_rate <= 16 {
818 if n_bytes == 1 || (toc_mode == OpusMode::SilkOnly && frame_rate != 10) {
819 toc_mode = OpusMode::SilkOnly;
820 packet_code = if frame_rate <= 12 { 1 } else { 0 };
821 frame_rate_adj = if frame_rate == 12 { 25 } else { 16 };
822 } else {
823 num_multiframes = (50 / frame_rate) as u8;
824 frame_rate_adj = 50;
825 packet_code = 3;
826 }
827 }
828 let mut plc_bw = frame_bandwidth;
829 if toc_mode == OpusMode::SilkOnly && bandwidth_fec_index(plc_bw) > 2 {
830 plc_bw = Bandwidth::Wideband;
832 }
833 output[0] = gen_toc(toc_mode, frame_rate_adj, plc_bw, self.channels) | packet_code;
834 let mut ret = if packet_code <= 1 { 1 } else { 2 };
835 if packet_code == 3 {
836 output[1] = num_multiframes;
837 }
838 if self.use_cbr {
839 let target_total = n_bytes.min(output.len());
840 if target_total >= 2 {
841 let m: usize = if packet_code == 3 {
844 num_multiframes as usize
845 } else if packet_code == 1 {
846 2
847 } else {
848 1
849 };
850 output[0] = (output[0] & 0xFC) | 0x03;
851 output[1] = 0x40 | m as u8; if target_total > 2 {
853 let pad_amount = target_total - 2;
854 let nb_255s = (pad_amount - 1) / 255;
855 let mut ptr = 2;
856 for _ in 0..nb_255s {
857 output[ptr] = 255;
858 ptr += 1;
859 }
860 output[ptr] = (pad_amount - 255 * nb_255s - 1) as u8;
861 ptr += 1;
862 for b in &mut output[ptr..target_total] {
863 *b = 0;
864 }
865 }
866 ret = target_total;
867 }
868 }
869 return Ok(ret);
871 }
872
873 let init_rc_size = n_bytes - 1;
874 self.rc.reset_for_encode(init_rc_size as u32);
875
876 let hp_freq_smth1 = if mode == OpusMode::CeltOnly {
881 silk_lin2log(60) << 8
882 } else {
883 self.silk_enc.s_cmn.variable_hp_smth1_q15
884 };
885
886 const VARIABLE_HP_SMTH_COEF2_Q16: i32 = 984;
887 self.variable_hp_smth2_q15 = silk_smlawb(
888 self.variable_hp_smth2_q15,
889 hp_freq_smth1 - self.variable_hp_smth2_q15,
890 VARIABLE_HP_SMTH_COEF2_Q16,
891 );
892
893 let cutoff_hz = silk_log2lin(silk_rshift(self.variable_hp_smth2_q15, 8));
894
895 if mode == OpusMode::SilkOnly || mode == OpusMode::Hybrid {
896 let silk_fs_khz = if mode == OpusMode::Hybrid {
897 16
898 } else {
899 self.sampling_rate.min(16000) / 1000
900 };
901
902 let frame_ms = (frame_size as i32 * 1000) / self.sampling_rate;
903 let silk_restart_after_celt =
907 self.prev_enc_mode == Some(OpusMode::CeltOnly);
908 if silk_restart_after_celt {
909 silk_init_encoder(state_mut(&mut self.silk_enc), 0);
910 self.silk_initialized = false;
911 }
912 if !self.silk_initialized || self.silk_enc.s_cmn.fs_khz != silk_fs_khz {
913 let silk_init_bitrate = (((n_bytes - 1) * 8) as i64 * self.sampling_rate as i64
914 / frame_size as i64) as i32;
915 silk_control_encoder(
916 state_mut(&mut self.silk_enc),
917 silk_fs_khz,
918 frame_ms,
919 silk_init_bitrate,
920 self.complexity,
921 );
922 self.silk_enc.s_cmn.use_cbr = if self.use_cbr { 1 } else { 0 };
923
924 self.silk_enc.s_cmn.n_channels = self.channels as i32;
925 self.silk_initialized = true;
926 let ret = self
930 .silk_resampler_enc
931 .init_for_enc(self.sampling_rate as i32, silk_fs_khz * 1000);
932 if ret != 0 {
933 return Err("Unsupported SILK resampling ratio");
934 }
935 self.silk_resampler_enc_side = self.silk_resampler_enc.clone();
936 }
937
938 self.silk_enc.s_cmn.use_in_band_fec = if self.use_inband_fec { 1 } else { 0 };
939 self.silk_enc.s_cmn.packet_loss_perc = self.packet_loss_perc.clamp(0, 100);
940
941 silk_setup_lbrr(state_mut(&mut self.silk_enc), lbrr_coded);
945
946 if silk_restart_after_celt && self.encoder_buffer > 0 && self.delay_compensation > 0
951 {
952 let ch = self.channels;
953 let f2_5 = self.sampling_rate / 400;
954 let eb = self.encoder_buffer;
955 let offset = eb - self.delay_compensation.min(eb) - f2_5 as usize;
956 let mut pre = [0i16; 480];
961 let pre = &mut pre[..eb];
962 if offset < eb {
963 for i in offset..eb {
964 let fade = (((i - offset) as f32) / f2_5 as f32).min(1.0);
965 let mut acc = 0f32;
966 for c in 0..ch {
967 acc += self.delay_buffer[i * ch + c];
968 }
969 pre[i] = (acc / ch as f32 * fade * 32768.0) as i16;
970 }
971 }
972 let silk_rate = self.sampling_rate.min(16000);
973 let pre_resampled_len = eb * silk_rate as usize / self.sampling_rate as usize;
974 let mut pre_internal = [0i16; 480];
975 let pre_internal = &mut pre_internal[..pre_resampled_len];
976 self.silk_resampler_enc
977 .process(pre_internal, pre, eb as i32);
978 silk_encode_prefill(state_mut(&mut self.silk_enc), pre_internal, 1);
979 }
980
981 let required_size = frame_size * self.channels;
982 self.buf_filtered.resize(required_size, 0);
983 let voip = self.application == Application::Voip;
984 match input {
985 PcmInput::I16(samples) => {
986 if voip {
987 hp_cutoff_i16(
991 samples,
992 cutoff_hz,
993 state_mut(&mut self.buf_filtered),
994 &mut self.hp_mem,
995 frame_size,
996 self.channels,
997 self.sampling_rate,
998 );
999 } else {
1000 let filtered = state_mut(&mut self.buf_filtered);
1001 filtered[..required_size].copy_from_slice(&samples[..required_size]);
1002 }
1003 }
1004 PcmInput::F32(samples) => {
1005 if voip {
1006 hp_cutoff(
1007 samples,
1008 cutoff_hz,
1009 state_mut(&mut self.buf_filtered),
1010 &mut self.hp_mem,
1011 frame_size,
1012 self.channels,
1013 self.sampling_rate,
1014 );
1015 } else {
1016 let filtered = state_mut(&mut self.buf_filtered);
1017 for (i, &x) in samples.iter().enumerate().take(required_size) {
1018 filtered[i] = (x * 32768.0).clamp(-32768.0, 32767.0) as i16;
1019 }
1020 }
1021 }
1022 }
1023
1024 let input_i16 = state_ref(&self.buf_filtered);
1025
1026 let is_stereo_silk = mode == OpusMode::SilkOnly && self.channels == 2;
1030 if is_stereo_silk {
1031 let frame_length = input_i16.len() / 2;
1032 self.buf_stereo_mid.resize(frame_length, 0);
1033 self.buf_stereo_side.resize(frame_length, 0);
1034 for i in 0..frame_length {
1035 let l = input_i16[2 * i] as i32;
1036 let r = input_i16[2 * i + 1] as i32;
1037 self.buf_stereo_mid[i] = ((l + r) / 2) as i16;
1038 self.buf_stereo_side[i] = (l - r) as i16;
1039 }
1040 }
1041
1042 let silk_frame_len_samples =
1046 frame_size * silk_fs_khz as usize / (self.sampling_rate.max(1000) / 1000) as usize;
1047 let needs_resampler = mode == OpusMode::SilkOnly || mode == OpusMode::Hybrid;
1048 let silk_input: &[i16] = if needs_resampler {
1049 self.buf_silk_input.resize(silk_frame_len_samples, 0);
1050 if is_stereo_silk {
1051 self.buf_stereo_side.resize(silk_frame_len_samples, 0);
1052 }
1053 let mid_src: &[i16] = if is_stereo_silk {
1054 state_ref(&self.buf_stereo_mid)
1055 } else {
1056 input_i16
1057 };
1058 let got = self.silk_resampler_enc.process(
1059 state_mut(&mut self.buf_silk_input),
1060 mid_src,
1061 frame_size as i32,
1062 );
1063 if got != 0 {
1064 return Err("SILK input resampling failed");
1065 }
1066 if is_stereo_silk {
1067 let side_src: &[i16] = state_ref(&self.buf_stereo_side);
1070 self.silk_enc.stereo.side.resize(silk_frame_len_samples, 0);
1071 let side_dst: &mut [i16] = state_mut(&mut self.silk_enc.stereo.side);
1072 let got = self
1073 .silk_resampler_enc_side
1074 .process(side_dst, side_src, frame_size as i32);
1075 if got != 0 {
1076 return Err("SILK input resampling failed");
1077 }
1078 }
1079 state_ref(&self.buf_silk_input)
1080 } else if is_stereo_silk {
1081 let frame_length = input_i16.len() / 2;
1082 self.silk_enc.stereo.side.resize(frame_length, 0);
1083 self.silk_enc
1084 .stereo
1085 .side
1086 .copy_from_slice(&self.buf_stereo_side[..frame_length]);
1087 state_ref(&self.buf_stereo_mid)
1088 } else {
1089 input_i16
1090 };
1091
1092 let mut pn_bytes = 0;
1093
1094 let silk_rate_for_calc = if mode == OpusMode::Hybrid {
1095 16000
1096 } else {
1097 self.sampling_rate
1098 };
1099 let silk_frame_len = silk_input.len();
1100
1101 let silk_bitrate = if mode == OpusMode::Hybrid {
1102 let frame_duration_ms = frame_size as i32 * 1000 / self.sampling_rate;
1103 let frame20ms = frame_duration_ms >= 20;
1104 compute_silk_rate_for_hybrid(self.bitrate_bps, frame20ms)
1105 } else {
1106 (8i64 * (n_bytes - 1) as i64 * silk_rate_for_calc as i64 / silk_frame_len as i64)
1107 as i32
1108 };
1109 let silk_max_bits = if mode == OpusMode::Hybrid {
1110 let total_max_bits = ((n_bytes - 1) * 8) as i32;
1111 if self.use_cbr {
1112 let silk_bits = (silk_bitrate as i64 * silk_frame_len as i64
1113 / silk_rate_for_calc as i64) as i32;
1114 let other_bits = 0i32.max(total_max_bits - silk_bits);
1115 0i32.max(total_max_bits - other_bits * 3 / 4)
1116 } else {
1117 let frame_duration_ms = frame_size as i32 * 1000 / self.sampling_rate;
1118 let frame20ms = frame_duration_ms >= 20;
1119 let max_bit_rate = compute_silk_rate_for_hybrid(
1120 total_max_bits * self.sampling_rate / frame_size as i32,
1121 frame20ms,
1122 );
1123 max_bit_rate * frame_size as i32 / self.sampling_rate
1124 }
1125 } else {
1126 ((n_bytes - 1) * 8) as i32
1127 };
1128 let silk_use_cbr = if mode == OpusMode::Hybrid && self.use_cbr {
1129 0
1130 } else if self.use_cbr {
1131 1
1132 } else {
1133 0
1134 };
1135 let ret = silk_encode(
1136 state_mut(&mut self.silk_enc),
1137 silk_input,
1138 silk_input.len(),
1139 &mut self.rc,
1140 &mut pn_bytes,
1141 silk_bitrate,
1142 silk_max_bits,
1143 silk_use_cbr,
1144 1,
1145 );
1146 if ret != 0 {
1147 return Err("SILK encoding failed");
1148 }
1149 }
1150
1151 if mode == OpusMode::Hybrid {
1152 self.rc.encode_bit_logp(false, 12); }
1154
1155 if mode == OpusMode::Hybrid {
1156 let nb_compr_bytes = (n_bytes - 1) as u32;
1157 self.rc.shrink(nb_compr_bytes);
1158 }
1159
1160 let silk_ret_bytes = if mode == OpusMode::SilkOnly {
1161 ((self.rc.tell() + 7) >> 3) as usize
1162 } else {
1163 0
1164 };
1165
1166 if mode != OpusMode::SilkOnly && self.use_cbr {
1172 let tell = self.rc.tell();
1173 if tell > 1 {
1174 let tmp = self.bitrate_bps as i64 * frame_size as i64
1175 + tell as i64 * self.sampling_rate as i64;
1176 let adjusted = ((tmp + 4 * self.sampling_rate as i64)
1177 / (8 * self.sampling_rate as i64)) as usize;
1178 let new_n = adjusted.clamp(1, OPUS_MAX_PACKET_BYTES).min(max_data_bytes);
1179 if new_n < n_bytes {
1180 n_bytes = new_n;
1181 let new_payload = n_bytes - 1;
1183 self.rc.shrink(new_payload as u32);
1184 }
1185 }
1186 }
1187 if mode == OpusMode::CeltOnly || mode == OpusMode::Hybrid {
1188 self.celt_enc.complexity = self.complexity;
1189 let start_band = if mode == OpusMode::Hybrid { 17 } else { 0 };
1190 let end_band = match frame_bandwidth {
1193 Bandwidth::Narrowband => 13,
1194 Bandwidth::Mediumband | Bandwidth::Wideband => 17,
1195 Bandwidth::Superwideband => 19,
1196 Bandwidth::Fullband | Bandwidth::Auto => 21,
1197 };
1198 self.celt_enc.set_end_band(end_band);
1199 let total_packet_bits = ((n_bytes - 1) * 8) as i32;
1200 let celt_bitrate = if mode == OpusMode::Hybrid {
1202 let frame_ms = frame_size as i32 * 1000 / self.sampling_rate;
1203 let frame20ms = frame_ms >= 20;
1204 let silk_rate = compute_silk_rate_for_hybrid(self.bitrate_bps, frame20ms);
1205 (self.bitrate_bps - silk_rate).max(8000)
1206 } else {
1207 self.bitrate_bps
1208 };
1209 self.celt_enc.set_bitrate(celt_bitrate);
1210 self.celt_enc.set_vbr(!self.use_cbr);
1211 self.celt_enc
1213 .set_constrained_vbr(mode == OpusMode::CeltOnly);
1214
1215 let input_f32: &[f32] = match input {
1221 PcmInput::F32(samples) => samples,
1222 PcmInput::I16(samples) => {
1223 let n = frame_size * self.channels;
1224 self.buf_f32_frame.resize(n, 0.0);
1225 let staging = state_mut(&mut self.buf_f32_frame);
1226 for (dst, &src) in staging[..n].iter_mut().zip(samples[..n].iter()) {
1227 *dst = src as f32 / 32768.0;
1228 }
1229 state_ref(&self.buf_f32_frame)
1230 }
1231 };
1232
1233 let celt_input: &[f32] = if self.delay_compensation > 0 {
1240 let delay = self.delay_compensation;
1241 let ebuf = self.encoder_buffer;
1242 let ch = self.channels;
1243 let total = (delay + frame_size) * ch;
1244 self.buf_celt_pcm.resize(total, 0.0);
1245 let prefix = delay * ch;
1247 let src_start = (ebuf - delay) * ch;
1248 self.buf_celt_pcm[..prefix]
1249 .copy_from_slice(&self.delay_buffer[src_start..src_start + prefix]);
1250 let out = &mut self.buf_celt_pcm[prefix..];
1252 if self.application == Application::Voip {
1253 hp_cutoff_float(
1254 input_f32,
1255 cutoff_hz,
1256 out,
1257 &mut self.hp_mem_float,
1258 frame_size,
1259 ch,
1260 self.sampling_rate,
1261 );
1262 } else {
1263 dc_reject_float(
1264 input_f32,
1265 3,
1266 out,
1267 &mut self.hp_mem_float,
1268 frame_size,
1269 ch,
1270 self.sampling_rate,
1271 );
1272 }
1273 let mut sum = 0.0f32;
1275 for &v in &self.buf_celt_pcm[prefix..] {
1276 sum += v * v;
1277 }
1278 #[allow(clippy::neg_cmp_op_on_partial_ord)]
1281 if !(sum < 1e9) || sum.is_nan() {
1282 self.buf_celt_pcm[prefix..].fill(0.0);
1283 self.hp_mem_float = [0.0; 4];
1284 }
1285 let keep = ebuf as i64 - (frame_size as i64 + delay as i64);
1287 if keep > 0 {
1288 let keep = keep as usize;
1289 self.delay_buffer
1290 .copy_within(ch * frame_size..ch * (frame_size + keep), 0);
1291 let dst = ch * keep;
1292 let n = (frame_size + delay) * ch;
1293 self.delay_buffer[dst..dst + n].copy_from_slice(&self.buf_celt_pcm[..n]);
1294 } else {
1295 let n = ebuf * ch;
1296 let src = (frame_size + delay - ebuf) * ch;
1297 self.delay_buffer[..n].copy_from_slice(&self.buf_celt_pcm[src..src + n]);
1298 }
1299 let n = frame_size * ch;
1302 self.buf_celt_input.resize(n, 0.0);
1303 for i in 0..frame_size {
1304 for c in 0..ch {
1305 self.buf_celt_input[c * frame_size + i] = self.buf_celt_pcm[i * ch + c];
1306 }
1307 }
1308 state_ref(&self.buf_celt_input)
1309 } else if self.channels == 1 {
1310 input_f32
1311 } else {
1312 let n = frame_size * self.channels;
1313 self.buf_celt_input.resize(n, 0.0);
1314 for i in 0..frame_size {
1315 for ch in 0..self.channels {
1316 self.buf_celt_input[ch * frame_size + i] =
1317 input_f32[i * self.channels + ch];
1318 }
1319 }
1320 state_ref(&self.buf_celt_input)
1321 };
1322
1323 if self.rc.tell() <= total_packet_bits {
1324 let is_vbr = !self.use_cbr;
1325 self.celt_enc.encode_with_budget_vbr(
1326 celt_input,
1327 frame_size,
1328 &mut self.rc,
1329 start_band,
1330 total_packet_bits,
1331 is_vbr,
1332 );
1333 }
1334 }
1335
1336 self.rc.done();
1337
1338 if self.rc.error != 0 || self.rc.tell() > (n_bytes as i32 - 1) * 8 {
1347 if output.len() < 2 {
1348 return Err("Output buffer too small");
1349 }
1350 let mut ret = 2usize;
1351 if self.use_cbr && n_bytes >= 2 {
1352 let target_total = n_bytes.min(output.len());
1355 if target_total > 2 {
1356 output[0] = toc | 0x03;
1357 output[1] = 0x41; let pad_amount = target_total - 2;
1359 let nb_255s = (pad_amount - 1) / 255;
1360 let mut ptr = 2;
1361 for _ in 0..nb_255s {
1362 output[ptr] = 255;
1363 ptr += 1;
1364 }
1365 output[ptr] = (pad_amount - 255 * nb_255s - 1) as u8;
1366 ptr += 1;
1367 for b in &mut output[ptr..target_total] {
1368 *b = 0;
1369 }
1370 self.prev_enc_mode = Some(mode);
1371 return Ok(target_total);
1372 }
1373 ret = target_total.max(1);
1374 }
1375 output[0] = toc;
1377 output[1] = 0;
1378 self.prev_enc_mode = Some(mode);
1379 return Ok(ret);
1380 }
1381
1382 if mode == OpusMode::SilkOnly {
1383 let mut ret = silk_ret_bytes.min(self.rc.storage as usize);
1384 while ret > 2 && self.rc.buf[ret - 1] == 0 {
1385 ret -= 1;
1386 }
1387
1388 let target_total = if self.use_cbr {
1389 n_bytes.min(output.len())
1390 } else {
1391 (ret + 1).min(output.len())
1392 };
1393
1394 let silk_len = ret;
1395
1396 if !self.use_cbr || silk_len + 1 >= target_total {
1397 output[0] = toc;
1399 let copy_len = silk_len.min(target_total - 1);
1400 output[1..1 + copy_len].copy_from_slice(&self.rc.buf[..copy_len]);
1401 return Ok((copy_len + 1).min(output.len()));
1402 }
1403
1404 output[0] = toc | 0x03;
1405
1406 if silk_len + 2 >= target_total {
1407 output[1] = 0x01;
1408 let copy_len = (target_total - 2).min(silk_len);
1409 output[2..2 + copy_len].copy_from_slice(&self.rc.buf[..copy_len]);
1410 self.prev_enc_mode = Some(mode);
1411 return Ok(target_total.min(output.len()));
1412 }
1413
1414 let pad_amount = target_total - silk_len - 2;
1415 output[1] = 0x41;
1416
1417 let nb_255s = (pad_amount - 1) / 255;
1418 let mut ptr = 2;
1419 for _ in 0..nb_255s {
1420 output[ptr] = 255;
1421 ptr += 1;
1422 }
1423 output[ptr] = (pad_amount - 255 * nb_255s - 1) as u8;
1424 ptr += 1;
1425
1426 output[ptr..ptr + silk_len].copy_from_slice(&self.rc.buf[..silk_len]);
1427 ptr += silk_len;
1428
1429 let fill_end = target_total.min(output.len());
1430 for byte in output[ptr..fill_end].iter_mut() {
1431 *byte = 0;
1432 }
1433
1434 self.prev_enc_mode = Some(mode);
1435 return Ok(target_total.min(output.len()));
1436 }
1437
1438 let payload_len = (self.rc.storage as usize).min(output.len() - 1);
1440 output[1..1 + payload_len].copy_from_slice(&self.rc.buf[..payload_len]);
1441 self.prev_enc_mode = Some(mode);
1442 Ok(payload_len + 1)
1443 }
1444
1445 fn encode_multiframe(
1449 &mut self,
1450 input: PcmInput<'_>,
1451 frame_size: usize,
1452 mode: OpusMode,
1453 output: &mut [u8],
1454 ) -> Result<usize, &'static str> {
1455 const MAX_SUB: usize = 3; let ch = self.channels;
1457 let enc_frame = (self.sampling_rate / 50) as usize; if enc_frame == 0 || !frame_size.is_multiple_of(enc_frame) {
1459 return Err("Invalid multi-frame size");
1460 }
1461 let nb = frame_size / enc_frame;
1462 if !(2..=MAX_SUB).contains(&nb) {
1463 return Err("Unsupported multi-frame size");
1464 }
1465
1466 fn put_size(out: &mut [u8], pos: &mut usize, len: usize) -> Result<(), &'static str> {
1468 if len < 252 {
1469 if *pos >= out.len() {
1470 return Err("Output buffer too small");
1471 }
1472 out[*pos] = len as u8;
1473 *pos += 1;
1474 } else {
1475 if *pos + 1 >= out.len() {
1476 return Err("Output buffer too small");
1477 }
1478 let first = 252 + (len & 3);
1479 out[*pos] = first as u8;
1480 out[*pos + 1] = ((len - first) >> 2) as u8;
1481 *pos += 2;
1482 }
1483 Ok(())
1484 }
1485
1486 let mut sub = [[0u8; 1276]; MAX_SUB];
1487 let mut lens = [0usize; MAX_SUB];
1488 self.forced_mode = Some(mode);
1489 let enc_res = (|| -> Result<(), &'static str> {
1490 for i in 0..nb {
1491 let start = i * enc_frame * ch;
1492 let end = start + enc_frame * ch;
1493 let sub_input = match input {
1494 PcmInput::F32(s) => PcmInput::F32(&s[start..end]),
1495 PcmInput::I16(s) => PcmInput::I16(&s[start..end]),
1496 };
1497 let n = self.encode_impl(sub_input, enc_frame, &mut sub[i])?;
1498 if n == 0 {
1499 return Err("Empty sub-frame");
1500 }
1501 lens[i] = n - 1;
1502 }
1503 Ok(())
1504 })();
1505 self.forced_mode = None;
1506 enc_res?;
1507
1508 let toc = sub[0][0] & 0xFC;
1509 let mut pos = 0usize;
1510 let push =
1511 |out: &mut [u8], pos: &mut usize, byte: u8| -> Result<(), &'static str> {
1512 if *pos >= out.len() {
1513 return Err("Output buffer too small");
1514 }
1515 out[*pos] = byte;
1516 *pos += 1;
1517 Ok(())
1518 };
1519 if nb == 2 {
1523 push(output, &mut pos, toc | 0x02)?;
1524 put_size(output, &mut pos, lens[0])?;
1525 } else {
1526 push(output, &mut pos, toc | 0x03)?;
1527 push(output, &mut pos, nb as u8 | 0x80)?;
1528 for i in 0..nb - 1 {
1529 put_size(output, &mut pos, lens[i])?;
1530 }
1531 }
1532
1533 for i in 0..nb {
1534 let payload = &sub[i][1..1 + lens[i]];
1535 if pos + payload.len() > output.len() {
1536 return Err("Output buffer too small");
1537 }
1538 output[pos..pos + payload.len()].copy_from_slice(payload);
1539 pos += payload.len();
1540 }
1541 self.prev_enc_mode = Some(mode);
1542 Ok(pos)
1543 }
1544}
1545
1546pub struct OpusDecoder {
1547 #[cfg(not(feature = "heap"))]
1548 celt_dec: CeltDecoder,
1549 #[cfg(feature = "heap")]
1550 celt_dec: Box<CeltDecoder>,
1551 #[cfg(not(feature = "heap"))]
1552 silk_dec: silk::dec_api::SilkDecoder,
1553 #[cfg(feature = "heap")]
1554 silk_dec: Box<silk::dec_api::SilkDecoder>,
1555 sampling_rate: i32,
1556 channels: usize,
1557
1558 prev_mode: Option<OpusMode>,
1559
1560 prev_redundancy: bool,
1562 frame_size: usize,
1563
1564 bandwidth: Bandwidth,
1565
1566 stream_channels: usize,
1567
1568 silk_resampler: silk::resampler::SilkResampler,
1569
1570 silk_resampler_2: silk::resampler::SilkResampler,
1572
1573 prev_internal_rate: i32,
1574
1575 pub hybrid_skip_celt: bool,
1576
1577 #[cfg(not(feature = "heap"))]
1578 w_pcm_i16: FixedVec<i16, OPUS_PCM_I16>,
1579 #[cfg(feature = "heap")]
1580 w_pcm_i16: Box<FixedVec<i16, OPUS_PCM_I16>>,
1581 #[cfg(not(feature = "heap"))]
1582 w_silk_out: FixedVec<f32, OPUS_SUBFRAME_SCRATCH>,
1583 #[cfg(feature = "heap")]
1584 w_silk_out: Box<FixedVec<f32, OPUS_SUBFRAME_SCRATCH>>,
1585 #[cfg(not(feature = "heap"))]
1586 w_pcm_resampled: FixedVec<i16, OPUS_SUBFRAME_SCRATCH>,
1587 #[cfg(feature = "heap")]
1588 w_pcm_resampled: Box<FixedVec<i16, OPUS_SUBFRAME_SCRATCH>>,
1589 #[cfg(not(feature = "heap"))]
1590 w_celt_planar: FixedVec<f32, OPUS_SUBFRAME_SCRATCH>,
1591 #[cfg(feature = "heap")]
1592 w_celt_planar: Box<FixedVec<f32, OPUS_SUBFRAME_SCRATCH>>,
1593 #[cfg(not(feature = "heap"))]
1594 w_celt_out: FixedVec<f32, OPUS_SUBFRAME_SCRATCH>,
1595 #[cfg(feature = "heap")]
1596 w_celt_out: Box<FixedVec<f32, OPUS_SUBFRAME_SCRATCH>>,
1597
1598 #[cfg(not(feature = "heap"))]
1601 prev_pcm_tail: FixedVec<f32, OPUS_PCM_TAIL>,
1602 #[cfg(feature = "heap")]
1603 prev_pcm_tail: Box<FixedVec<f32, OPUS_PCM_TAIL>>,
1604}
1605
1606impl OpusDecoder {
1607 pub fn new(sampling_rate: i32, channels: usize) -> Result<Self, &'static str> {
1608 if ![8000, 12000, 16000, 24000, 48000].contains(&sampling_rate) {
1609 return Err("Invalid sampling rate");
1610 }
1611 if ![1, 2].contains(&channels) {
1612 return Err("Invalid number of channels");
1613 }
1614
1615 let mode = modes::default_mode();
1616 #[cfg(feature = "heap")]
1617 let celt_dec = Box::new(CeltDecoder::new(mode, channels, sampling_rate));
1618 #[cfg(not(feature = "heap"))]
1619 let celt_dec = CeltDecoder::new(mode, channels, sampling_rate);
1620
1621 #[cfg(feature = "heap")]
1622 let mut silk_dec = Box::new(silk::dec_api::SilkDecoder::new());
1623 #[cfg(not(feature = "heap"))]
1624 let mut silk_dec = silk::dec_api::SilkDecoder::new();
1625 silk_dec.init(sampling_rate.min(16000), channels as i32);
1626 silk_dec.channel_state[0].fs_api_hz = sampling_rate;
1627
1628 Ok(Self {
1629 celt_dec,
1630 silk_dec,
1631 sampling_rate,
1632 channels,
1633 prev_mode: None,
1634 prev_redundancy: false,
1635 frame_size: 0,
1636 bandwidth: Bandwidth::Auto,
1637 stream_channels: channels,
1638 silk_resampler: silk::resampler::SilkResampler::default(),
1639 silk_resampler_2: silk::resampler::SilkResampler::default(),
1640 prev_internal_rate: 0,
1641 hybrid_skip_celt: false,
1642
1643 #[cfg(not(feature = "heap"))]
1644 w_pcm_i16: FixedVec::from_value(0i16, 960 * channels),
1645 #[cfg(feature = "heap")]
1646 w_pcm_i16: Box::new(FixedVec::from_value(0i16, 960 * channels)),
1647
1648 #[cfg(not(feature = "heap"))]
1649 w_silk_out: FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels),
1650 #[cfg(feature = "heap")]
1651 w_silk_out: Box::new(FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels)),
1652 #[cfg(not(feature = "heap"))]
1653 w_pcm_resampled: FixedVec::from_value(0i16, OPUS_MAX_SUBFRAME * channels),
1654 #[cfg(feature = "heap")]
1655 w_pcm_resampled: Box::new(FixedVec::from_value(0i16, OPUS_MAX_SUBFRAME * channels)),
1656 #[cfg(not(feature = "heap"))]
1657 w_celt_planar: FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels),
1658 #[cfg(feature = "heap")]
1659 w_celt_planar: Box::new(FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels)),
1660 #[cfg(not(feature = "heap"))]
1661 w_celt_out: FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels),
1662 #[cfg(feature = "heap")]
1663 w_celt_out: Box::new(FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels)),
1664
1665 #[cfg(not(feature = "heap"))]
1666 prev_pcm_tail: FixedVec::from_value(0.0f32, 240 * channels),
1667 #[cfg(feature = "heap")]
1668 prev_pcm_tail: Box::new(FixedVec::from_value(0.0f32, 240 * channels)),
1669 })
1670 }
1671
1672 pub fn decode(
1681 &mut self,
1682 input: &[u8],
1683 frame_size: usize,
1684 output: &mut [f32],
1685 ) -> Result<usize, &'static str> {
1686 if input.len() <= 1 {
1689 return self.decode_lost(input.first().copied(), frame_size, output);
1690 }
1691
1692 let toc = input[0];
1693 let mode = mode_from_toc(toc);
1694 let packet_channels = channels_from_toc(toc);
1695 let bandwidth = bandwidth_from_toc(toc);
1696 let frame_duration_ms = frame_duration_ms_from_toc(toc);
1697
1698 if packet_channels != self.channels {
1699 return Err("Channel count mismatch between packet and decoder");
1700 }
1701
1702 let code = toc & 0x03;
1703 let frame_count: usize;
1704 let frame_payloads: FixedVec<&[u8], OPUS_MAX_PACKET_FRAMES>;
1705
1706 match code {
1707 0 => {
1708 frame_count = 1;
1709 frame_payloads = FixedVec::from_slice(&[&input[1..]]);
1710 }
1711 1 => {
1712 frame_count = 2;
1713 let data_len = input.len() - 1;
1714 if !data_len.is_multiple_of(2) {
1717 return Err("Code 1: payload length must be even");
1718 }
1719 let half = data_len / 2;
1720 if half == 0 {
1721 return Err("Code 1: empty frame");
1722 }
1723 frame_payloads = FixedVec::from_slice(&[&input[1..1 + half], &input[1 + half..]]);
1724 }
1725 2 => {
1726 frame_count = 2;
1727 let data = &input[1..];
1728 if data.is_empty() {
1729 return Err("Code 2 packet has no data");
1730 }
1731 let (first_len, header_size) = parse_frame_size(data)?;
1732 if header_size + first_len > data.len() {
1733 return Err("Code 2: first frame size exceeds packet");
1734 }
1735 frame_payloads = FixedVec::from_slice(&[
1736 &data[header_size..header_size + first_len],
1737 &data[header_size + first_len..],
1738 ]);
1739 }
1740 3 => {
1741 if input.len() < 2 {
1742 return Err("Code 3 packet too short");
1743 }
1744 let count_byte = input[1];
1745 let n_frames = (count_byte & 0x3F) as usize;
1746 if !(1..=48).contains(&n_frames) {
1747 return Err("Code 3: invalid frame count");
1748 }
1749 frame_count = n_frames;
1750 let padding_flag = (count_byte & 0x40) != 0;
1752 let vbr = (count_byte & 0x80) != 0;
1753
1754 let mut ptr = 2usize;
1758 let mut pad_len = 0usize;
1759 if padding_flag {
1760 loop {
1761 if ptr >= input.len() {
1762 return Err("Code 3: padding overflow");
1763 }
1764 let p = input[ptr] as usize;
1765 ptr += 1;
1766 if p == 255 {
1767 pad_len += 254;
1768 } else {
1769 pad_len += p;
1770 break;
1771 }
1772 }
1773 }
1774 if ptr + pad_len > input.len() {
1775 return Err("Code 3: padding exceeds packet");
1776 }
1777 let payload_end = input.len() - pad_len;
1778 let payload = &input[ptr..payload_end];
1779
1780 let mut payloads: FixedVec<&[u8], OPUS_MAX_PACKET_FRAMES> = FixedVec::new();
1781 if frame_count == 1 {
1782 payloads.push(payload);
1785 } else if vbr {
1786 let mut cursor = 0usize;
1792 let mut frame_bytes = 0usize;
1793 let mut sizes = [0usize; OPUS_MAX_PACKET_FRAMES];
1794 for i in 0..frame_count - 1 {
1795 if cursor >= payload.len() {
1796 return Err("Code 3: unexpected end in VBR header");
1797 }
1798 let (frame_len, header_bytes) = parse_frame_size(&payload[cursor..])?;
1799 cursor += header_bytes;
1800 sizes[i] = frame_len;
1801 frame_bytes += frame_len;
1802 }
1803 if frame_bytes > payload.len() - cursor {
1804 return Err("Code 3: frame length exceeds packet");
1805 }
1806 sizes[frame_count - 1] = payload.len() - cursor - frame_bytes;
1807 let mut data_pos = cursor;
1808 for i in 0..frame_count {
1809 payloads.push(&payload[data_pos..data_pos + sizes[i]]);
1810 data_pos += sizes[i];
1811 }
1812 } else {
1813 if !payload.len().is_multiple_of(frame_count) {
1817 return Err("Code 3 CBR: payload not divisible by frame count");
1818 }
1819 let frame_len = payload.len() / frame_count;
1820 for i in 0..frame_count {
1821 payloads.push(&payload[i * frame_len..(i + 1) * frame_len]);
1822 }
1823 }
1824 frame_payloads = payloads;
1825 }
1826 _ => unreachable!(),
1827 }
1828
1829 self.frame_size = frame_size;
1830 self.bandwidth = bandwidth;
1831 self.stream_channels = packet_channels;
1832
1833 let toc_frame_size = frame_samples_from_toc(toc, self.sampling_rate)
1838 .ok_or("Invalid TOC for sampling rate")?;
1839 let decoded_total = toc_frame_size * frame_count;
1840 if frame_size < decoded_total {
1841 return Err("frame_size too small for packet");
1842 }
1843 if output.len() < decoded_total * self.channels {
1844 return Err("Output buffer too small for packet");
1845 }
1846 if output.len() > decoded_total * self.channels {
1849 for v in &mut output[decoded_total * self.channels..] {
1850 *v = 0.0;
1851 }
1852 }
1853 let sub_frame_size = toc_frame_size;
1854 let sub_output_len = sub_frame_size * self.channels;
1855
1856 let mode_transition = matches!(
1862 self.prev_mode,
1863 Some(prev) if prev != mode && !self.prev_redundancy
1864 );
1865 if mode_transition {
1866 self.celt_dec.reset_state();
1867 }
1868
1869 let f5_bridge = self.sampling_rate as usize / 200; if mode_transition
1875 && f5_bridge > 0
1876 && matches!(
1877 self.prev_mode,
1878 Some(OpusMode::SilkOnly) | Some(OpusMode::Hybrid)
1879 )
1880 && self.prev_internal_rate > 0
1881 {
1882 let internal_rate = self.prev_internal_rate;
1883 let plc_internal_len = (10 * internal_rate / 1000) as usize;
1884 let mut plc_rc = RangeCoder::new_decoder(&[]);
1885 let mut plc_i16: FixedVec<i16, OPUS_PCM_I16> =
1886 FixedVec::from_value(0i16, plc_internal_len * self.channels);
1887 let n = self.silk_dec.decode(
1888 &mut plc_rc,
1889 &mut plc_i16,
1890 silk::decode_frame::FLAG_PACKET_LOST,
1891 true,
1892 10,
1893 internal_rate,
1894 );
1895 if n > 0 {
1896 let bridge_ch = f5_bridge * self.channels;
1897 let bridge_len = bridge_ch.min(self.prev_pcm_tail.len());
1898 if internal_rate == self.sampling_rate {
1899 let n_us = n as usize;
1901 for ch in 0..self.channels {
1902 let src_base = ch * n_us;
1903 for i in 0..(bridge_len / self.channels).min(n_us) {
1904 let dst = i * self.channels + ch;
1905 if dst < bridge_len {
1906 self.prev_pcm_tail[dst] = plc_i16[src_base + i] as f32 / 32768.0;
1907 }
1908 }
1909 }
1910 } else if self.silk_resampler.is_initialized() {
1911 let ratio = self.sampling_rate as f64 / internal_rate as f64;
1917 let full_len = ((n as f64 * ratio) as usize).max(1);
1918 let out_len = full_len.min(f5_bridge);
1919 let n_us = n as usize;
1920 let mut resampled: FixedVec<i16, OPUS_MAX_FRAME> =
1921 FixedVec::from_value(0i16, full_len);
1922 self.silk_resampler
1923 .process(&mut resampled, &plc_i16[..n_us], n);
1924 for i in 0..out_len {
1925 if i < bridge_len / self.channels {
1926 for ch in 0..self.channels {
1927 self.prev_pcm_tail[i * self.channels + ch] =
1928 resampled[i] as f32 / 32768.0;
1929 }
1930 }
1931 }
1932 }
1933 }
1934 }
1935
1936 let mut has_redundancy = false;
1938
1939 match mode {
1940 OpusMode::SilkOnly => {
1941 let internal_sample_rate = match bandwidth {
1942 Bandwidth::Narrowband => 8000,
1943 Bandwidth::Mediumband => 12000,
1944 Bandwidth::Wideband => 16000,
1945 _ => 16000,
1946 };
1947 if internal_sample_rate != self.prev_internal_rate
1948 || !self.silk_resampler.is_initialized()
1949 {
1950 self.silk_resampler
1951 .init(internal_sample_rate, self.sampling_rate);
1952 self.silk_resampler_2
1953 .init(internal_sample_rate, self.sampling_rate);
1954 }
1955 self.prev_internal_rate = internal_sample_rate;
1959
1960 for (fi, payload) in frame_payloads.iter().enumerate() {
1961 let out_start = fi * sub_output_len;
1962 let flag = if payload.is_empty() {
1966 silk::decode_frame::FLAG_PACKET_LOST
1967 } else {
1968 silk::decode_frame::FLAG_DECODE_NORMAL
1969 };
1970 let mut rc = RangeCoder::new_decoder(payload);
1971 self.decode_silk_frames(
1972 &mut rc,
1973 flag,
1974 frame_duration_ms,
1975 internal_sample_rate,
1976 sub_frame_size,
1977 )?;
1978 output[out_start..out_start + sub_output_len]
1979 .copy_from_slice(&self.w_silk_out[..sub_output_len]);
1980 }
1981 decoded_total
1982 }
1983
1984 OpusMode::CeltOnly => {
1985 let celt_end_band = self.celt_end_band_from_toc(toc);
1986
1987 for (fi, payload) in frame_payloads.iter().enumerate() {
1988 let mut rc = RangeCoder::new_decoder(payload);
1989 let total_bits = (payload.len() * 8) as i32;
1990 let needed = sub_frame_size * self.channels;
1991 let out_start = fi * needed;
1992 let out_end = (out_start + needed).min(output.len());
1993
1994 if output.len() < out_end {
1995 return Err("Output buffer too small");
1996 }
1997
1998 if self.channels == 1 {
1999 self.celt_dec.decode_from_range_coder_with_band_range(
2000 &mut rc,
2001 total_bits,
2002 sub_frame_size,
2003 &mut output[out_start..out_end],
2004 0,
2005 celt_end_band,
2006 );
2007 for sample in &mut output[out_start..out_end] {
2008 *sample = sample.clamp(-1.0, 1.0);
2009 }
2010 } else {
2011 self.celt_dec.decode_from_range_coder_with_band_range(
2012 &mut rc,
2013 total_bits,
2014 sub_frame_size,
2015 &mut self.w_celt_planar[..needed],
2016 0,
2017 celt_end_band,
2018 );
2019 for i in 0..sub_frame_size {
2020 for ch in 0..self.channels {
2021 let idx = out_start + i * self.channels + ch;
2022 output[idx] =
2023 self.w_celt_planar[ch * sub_frame_size + i].clamp(-1.0, 1.0);
2024 }
2025 }
2026 }
2027 }
2028 decoded_total
2029 }
2030
2031 OpusMode::Hybrid => {
2032 let internal_sample_rate = 16000;
2033 let celt_end_band = self.celt_end_band_from_toc(toc);
2034
2035 if internal_sample_rate != self.prev_internal_rate
2036 || !self.silk_resampler.is_initialized()
2037 {
2038 self.silk_resampler
2039 .init(internal_sample_rate, self.sampling_rate);
2040 self.silk_resampler_2
2041 .init(internal_sample_rate, self.sampling_rate);
2042 }
2043 self.prev_internal_rate = internal_sample_rate;
2044
2045 for (fi, payload) in frame_payloads.iter().enumerate() {
2046 let mut rc = RangeCoder::new_decoder(payload);
2047 let flag = if payload.is_empty() {
2051 silk::decode_frame::FLAG_PACKET_LOST
2052 } else {
2053 silk::decode_frame::FLAG_DECODE_NORMAL
2054 };
2055 self.decode_silk_frames(
2056 &mut rc,
2057 flag,
2058 frame_duration_ms,
2059 internal_sample_rate,
2060 sub_frame_size,
2061 )?;
2062 let silk_out_len = sub_frame_size * self.channels;
2063
2064 let total_bits = (payload.len() * 8) as i32;
2065 let redundancy = rc.decode_bit_logp(12);
2066 let skip_celt = if redundancy {
2067 let _celt_to_silk = rc.decode_bit_logp(1);
2068 has_redundancy = true;
2069 true
2075 } else {
2076 false
2077 };
2078
2079 if skip_celt {
2080 self.w_celt_out[..silk_out_len].fill(0.0);
2081 } else {
2082 let (celt_dec, celt_planar) = (
2083 state_mut(&mut self.celt_dec),
2084 state_mut(&mut self.w_celt_planar),
2085 );
2086 celt_dec.decode_from_range_coder_with_band_range(
2087 &mut rc,
2088 total_bits,
2089 sub_frame_size,
2090 &mut celt_planar[..silk_out_len],
2091 17,
2092 celt_end_band,
2093 );
2094
2095 if self.channels == 1 {
2096 self.w_celt_out[..silk_out_len]
2097 .copy_from_slice(&self.w_celt_planar[..silk_out_len]);
2098 } else {
2099 for i in 0..sub_frame_size {
2100 for ch in 0..self.channels {
2101 self.w_celt_out[i * self.channels + ch] =
2102 self.w_celt_planar[ch * sub_frame_size + i];
2103 }
2104 }
2105 }
2106 }
2107
2108 let out_start = fi * silk_out_len;
2109 let total = silk_out_len.min(output.len() - out_start);
2110 for j in 0..total {
2111 output[out_start + j] =
2112 (self.w_silk_out[j] + self.w_celt_out[j]).clamp(-1.0, 1.0);
2113 }
2114 }
2115 decoded_total
2116 }
2117 };
2118
2119 let f2_5 = self.sampling_rate as usize / 400;
2125 let f5 = f2_5 * 2;
2126 if mode_transition && f5 > 0 && decoded_total >= f5 {
2127 let window = modes::default_mode().window;
2128 let inc = (48000 / self.sampling_rate) as usize;
2129 let f2_5_ch = f2_5 * self.channels;
2130 let f5_ch = f5 * self.channels;
2131 output[..f2_5_ch].copy_from_slice(&self.prev_pcm_tail[..f2_5_ch]);
2133 let new_mid: FixedVec<f32, OPUS_PCM_TAIL> =
2135 FixedVec::from_slice(&output[f2_5_ch..f5_ch]);
2136 smooth_fade(
2137 &self.prev_pcm_tail[f2_5_ch..f5_ch],
2138 &new_mid,
2139 &mut output[f2_5_ch..f5_ch],
2140 f2_5,
2141 self.channels,
2142 window,
2143 inc,
2144 );
2145 }
2146
2147 self.save_pcm_tail(output, decoded_total);
2148 self.prev_mode = Some(mode);
2149 self.prev_redundancy = has_redundancy;
2150 Ok(decoded_total)
2151 }
2152
2153 fn decode_lost(
2161 &mut self,
2162 toc: Option<u8>,
2163 frame_size: usize,
2164 output: &mut [f32],
2165 ) -> Result<usize, &'static str> {
2166 let f2_5 = self.sampling_rate as usize / 400;
2167 let (f5, f10, f20) = (2 * f2_5, 4 * f2_5, 8 * f2_5);
2168
2169 let total = match toc {
2170 None => {
2171 if frame_size == 0 || !frame_size.is_multiple_of(f2_5) {
2172 return Err("Lost frame: frame_size must be a multiple of 2.5 ms");
2173 }
2174 frame_size
2175 }
2176 Some(toc) => {
2177 let count = match toc & 0x03 {
2180 0 => 1,
2181 1 | 2 => 2,
2182 _ => return Err("Code 3 packet too short"),
2183 };
2184 let per_frame = frame_samples_from_toc(toc, self.sampling_rate)
2185 .ok_or("Invalid TOC for sampling rate")?;
2186 let total = per_frame * count;
2187 if frame_size < total {
2188 return Err("frame_size too small for packet");
2189 }
2190 total
2191 }
2192 };
2193 let channels = self.channels;
2194 if output.len() < total * channels {
2195 return Err("Output buffer too small for packet");
2196 }
2197 output[total * channels..].fill(0.0);
2198
2199 let mut pos = 0usize;
2200 while pos < total {
2201 let remaining = total - pos;
2202 let dst = &mut output[pos * channels..total * channels];
2203 let produced = match self.prev_mode {
2204 None => {
2205 dst.fill(0.0);
2206 remaining
2207 }
2208 Some(OpusMode::CeltOnly) => {
2209 let n = [f20, f10, f5, f2_5]
2212 .into_iter()
2213 .find(|&c| c <= remaining)
2214 .unwrap_or(f2_5);
2215 self.conceal_celt(n, 0)?;
2216 for (d, s) in dst.iter_mut().zip(&self.w_celt_out[..n * channels]) {
2217 *d = s.clamp(-1.0, 1.0);
2218 }
2219 n
2220 }
2221 Some(prev @ (OpusMode::SilkOnly | OpusMode::Hybrid)) => {
2222 let (ms, n) = if remaining >= f20 {
2225 (20, f20)
2226 } else {
2227 (10, f10)
2228 };
2229 let hybrid = prev == OpusMode::Hybrid;
2230 let rate = if hybrid {
2231 16000
2232 } else {
2233 self.prev_internal_rate
2234 };
2235 let mut rc = RangeCoder::new_decoder(&[]);
2236 self.decode_silk_frames(
2237 &mut rc,
2238 silk::decode_frame::FLAG_PACKET_LOST,
2239 ms,
2240 rate,
2241 n,
2242 )?;
2243 if hybrid {
2244 self.conceal_celt(n, 17)?;
2245 } else {
2246 self.w_celt_out[..n * channels].fill(0.0);
2247 }
2248 let take = n.min(remaining);
2249 for (i, d) in dst[..take * channels].iter_mut().enumerate() {
2250 *d = (self.w_silk_out[i] + self.w_celt_out[i]).clamp(-1.0, 1.0);
2251 }
2252 take
2253 }
2254 };
2255 pos += produced;
2256 }
2257
2258 self.save_pcm_tail(output, total);
2259 Ok(total)
2260 }
2261
2262 fn conceal_celt(&mut self, n: usize, start_band: usize) -> Result<(), &'static str> {
2267 let len = n * self.channels;
2268 let end_band = modes::default_mode().eff_ebands;
2269 let mut rc = RangeCoder::new_decoder(&[]);
2270 let decoded = {
2271 let (celt_dec, planar) = (
2272 state_mut(&mut self.celt_dec),
2273 state_mut(&mut self.w_celt_planar),
2274 );
2275 celt_dec.decode_from_range_coder_with_band_range(
2276 &mut rc,
2277 0,
2278 n,
2279 &mut planar[..len],
2280 start_band,
2281 end_band,
2282 )
2283 };
2284 if decoded != n {
2285 return Err("CELT concealment failed");
2286 }
2287 for i in 0..n {
2288 for ch in 0..self.channels {
2289 self.w_celt_out[i * self.channels + ch] = self.w_celt_planar[ch * n + i];
2290 }
2291 }
2292 Ok(())
2293 }
2294
2295 fn save_pcm_tail(&mut self, output: &[f32], decoded: usize) {
2297 let tail_len = (self.sampling_rate as usize / 200) * self.channels;
2298 let out_total = decoded * self.channels;
2299 if out_total >= tail_len && tail_len <= self.prev_pcm_tail.len() {
2300 self.prev_pcm_tail[..tail_len]
2301 .copy_from_slice(&output[out_total - tail_len..out_total]);
2302 }
2303 }
2304}
2305
2306impl OpusDecoder {
2307 fn decode_silk_frames(
2315 &mut self,
2316 rc: &mut RangeCoder,
2317 lost_flag: i32,
2318 duration_ms: i32,
2319 internal_rate: i32,
2320 api_len: usize,
2321 ) -> Result<(), &'static str> {
2322 let internal_frame_size = (duration_ms * internal_rate / 1000) as usize;
2323 let pcm_i16_len = internal_frame_size * self.channels;
2324 debug_assert!(pcm_i16_len <= self.w_pcm_i16.len());
2325 let out_len = api_len * self.channels;
2326 self.w_silk_out[..out_len].fill(0.0);
2327
2328 let mut frame_pos = 0usize; let mut new_packet = true;
2330 while frame_pos < internal_frame_size {
2331 let ret = {
2332 let (silk_dec, pcm_i16) = (
2333 state_mut(&mut self.silk_dec),
2334 state_mut(&mut self.w_pcm_i16),
2335 );
2336 silk_dec.decode(
2337 rc,
2338 &mut pcm_i16[..pcm_i16_len],
2339 lost_flag,
2340 new_packet,
2341 duration_ms,
2342 internal_rate,
2343 )
2344 };
2345 new_packet = false;
2346
2347 if ret < 0 {
2348 return Err("SILK decoding failed");
2349 }
2350 let decoded_samples = ret as usize;
2351 if decoded_samples == 0 {
2352 break;
2353 }
2354
2355 let resampled_len =
2364 decoded_samples * self.sampling_rate as usize / internal_rate as usize;
2365 let api_pos = frame_pos * self.sampling_rate as usize / internal_rate as usize;
2366 let copy_len = resampled_len.min(api_len - api_pos);
2367 debug_assert!(resampled_len * self.channels <= self.w_pcm_resampled.len());
2368 {
2370 let (res, inp, out) = (
2371 &mut self.silk_resampler,
2372 state_ref(&self.w_pcm_i16),
2373 state_mut(&mut self.w_pcm_resampled),
2374 );
2375 res.process(
2376 &mut out[..resampled_len],
2377 &inp[..decoded_samples],
2378 decoded_samples as i32,
2379 );
2380 }
2381 if self.channels == 2 {
2383 let (res, inp, out) = (
2384 &mut self.silk_resampler_2,
2385 state_ref(&self.w_pcm_i16),
2386 state_mut(&mut self.w_pcm_resampled),
2387 );
2388 res.process(
2389 &mut out[resampled_len..2 * resampled_len],
2390 &inp[decoded_samples..2 * decoded_samples],
2391 decoded_samples as i32,
2392 );
2393 }
2394 for i in 0..copy_len {
2395 for ch in 0..self.channels {
2396 let v = self.w_pcm_resampled[ch * resampled_len + i] as f32 / 32768.0;
2397 let idx = (api_pos + i) * self.channels + ch;
2398 if idx < out_len {
2399 self.w_silk_out[idx] = v;
2400 }
2401 }
2402 }
2403 frame_pos += decoded_samples;
2404 }
2405 Ok(())
2406 }
2407
2408 #[inline(always)]
2409 fn celt_end_band_from_toc(&self, toc: u8) -> usize {
2410 let mode = modes::default_mode();
2411 let top = mode.eff_ebands;
2412 if mode_from_toc(toc) == OpusMode::CeltOnly && toc >= 0x80 {
2413 const FROM_OPUS_TABLE: [u8; 16] = [
2414 0x80, 0x88, 0x90, 0x98, 0x40, 0x48, 0x50, 0x58, 0x20, 0x28, 0x30, 0x38, 0x00, 0x08,
2415 0x10, 0x18,
2416 ];
2417 let idx = ((toc >> 3) - 16) as usize;
2418 let data0 = FROM_OPUS_TABLE[idx] | (toc & 0x7);
2419 let trim = (data0 >> 5) as usize;
2420 return top.saturating_sub(2 * trim).max(1);
2421 }
2422 top
2423 }
2424}
2425
2426fn frame_rate_from_params(sampling_rate: i32, frame_size: usize) -> Option<i32> {
2427 let frame_size = frame_size as i32;
2428 if frame_size <= 0 {
2429 return None;
2430 }
2431 let fs = sampling_rate;
2437 let valid = frame_size == fs / 400
2438 || frame_size == fs / 200
2439 || frame_size == fs / 100
2440 || frame_size == fs / 50
2441 || frame_size == fs / 25
2442 || 50 * frame_size == 3 * fs;
2443 if !valid {
2444 return None;
2445 }
2446 Some(fs / frame_size)
2447}
2448
2449fn gen_toc(mode: OpusMode, frame_rate: i32, bandwidth: Bandwidth, channels: usize) -> u8 {
2450 let mut rate = frame_rate;
2451 let mut period = 0;
2452 while rate < 400 {
2453 rate <<= 1;
2454 period += 1;
2455 }
2456
2457 let mut toc = match mode {
2458 OpusMode::SilkOnly => {
2459 let bw = (bandwidth as i32 - Bandwidth::Narrowband as i32) << 5;
2460 let per = (period - 2) << 3;
2461 (bw | per) as u8
2462 }
2463 OpusMode::CeltOnly => {
2464 let mut tmp = bandwidth as i32 - Bandwidth::Mediumband as i32;
2465 if tmp < 0 {
2466 tmp = 0;
2467 }
2468 let per = period << 3;
2469 (0x80 | (tmp << 5) | per) as u8
2470 }
2471 OpusMode::Hybrid => {
2472 let base_config = if bandwidth == Bandwidth::Superwideband {
2473 12
2474 } else {
2475 14
2476 };
2477 let period_offset = if frame_rate >= 100 { 0 } else { 1 };
2478 ((base_config + period_offset) << 3) as u8
2479 }
2480 };
2481
2482 if channels == 2 {
2483 toc |= 0x04;
2484 }
2485 toc
2486}
2487
2488fn mode_from_toc(toc: u8) -> OpusMode {
2489 if toc & 0x80 != 0 {
2490 OpusMode::CeltOnly
2491 } else if toc & 0x60 == 0x60 {
2492 OpusMode::Hybrid
2493 } else {
2494 OpusMode::SilkOnly
2495 }
2496}
2497
2498fn bandwidth_from_toc(toc: u8) -> Bandwidth {
2499 let mode = mode_from_toc(toc);
2500 match mode {
2501 OpusMode::SilkOnly => {
2502 let bw_bits = (toc >> 5) & 0x03;
2503 match bw_bits {
2504 0 => Bandwidth::Narrowband,
2505 1 => Bandwidth::Mediumband,
2506 2 => Bandwidth::Wideband,
2507 _ => Bandwidth::Wideband,
2508 }
2509 }
2510 OpusMode::Hybrid => {
2511 let bw_bit = (toc >> 4) & 0x01;
2512 if bw_bit == 0 {
2513 Bandwidth::Superwideband
2514 } else {
2515 Bandwidth::Fullband
2516 }
2517 }
2518 OpusMode::CeltOnly => {
2519 let bw_bits = (toc >> 5) & 0x03;
2520 match bw_bits {
2521 0 => Bandwidth::Mediumband,
2522 1 => Bandwidth::Wideband,
2523 2 => Bandwidth::Superwideband,
2524 3 => Bandwidth::Fullband,
2525 _ => Bandwidth::Fullband,
2526 }
2527 }
2528 }
2529}
2530
2531fn frame_duration_ms_from_toc(toc: u8) -> i32 {
2532 let mode = mode_from_toc(toc);
2533 match mode {
2534 OpusMode::SilkOnly => {
2535 let config = (toc >> 3) & 0x03;
2536 match config {
2537 0 => 10,
2538 1 => 20,
2539 2 => 40,
2540 3 => 60,
2541 _ => 20,
2542 }
2543 }
2544 OpusMode::Hybrid => {
2545 let config = (toc >> 3) & 0x01;
2546 if config == 0 { 10 } else { 20 }
2547 }
2548 OpusMode::CeltOnly => {
2549 let config = (toc >> 3) & 0x03;
2550 match config {
2551 0 => 2,
2552 1 => 5,
2553 2 => 10,
2554 3 => 20,
2555 _ => 20,
2556 }
2557 }
2558 }
2559}
2560
2561fn frame_samples_from_toc(toc: u8, sampling_rate: i32) -> Option<usize> {
2565 let mode = mode_from_toc(toc);
2566 match mode {
2567 OpusMode::CeltOnly => {
2568 let period = ((toc >> 3) & 0x03) as i32;
2569 let frame_rate = 400 >> period;
2570 if frame_rate == 0 || sampling_rate % frame_rate != 0 {
2571 return None;
2572 }
2573 Some((sampling_rate / frame_rate) as usize)
2574 }
2575 OpusMode::SilkOnly | OpusMode::Hybrid => {
2576 let duration_ms = frame_duration_ms_from_toc(toc);
2577 Some((sampling_rate as i64 * duration_ms as i64 / 1000) as usize)
2578 }
2579 }
2580}
2581
2582fn channels_from_toc(toc: u8) -> usize {
2583 if toc & 0x04 != 0 { 2 } else { 1 }
2584}
2585
2586fn smooth_fade(
2589 in1: &[f32],
2590 in2: &[f32],
2591 out: &mut [f32],
2592 overlap: usize,
2593 channels: usize,
2594 window: &[f32],
2595 inc: usize,
2596) {
2597 for c in 0..channels {
2598 for i in 0..overlap {
2599 let wi = i * inc;
2600 if wi >= window.len() {
2601 break;
2602 }
2603 let w = window[wi] * window[wi];
2604 out[i * channels + c] = w * in2[i * channels + c] + (1.0 - w) * in1[i * channels + c];
2605 }
2606 }
2607}
2608
2609pub(crate) fn parse_frame_size(data: &[u8]) -> Result<(usize, usize), &'static str> {
2617 let first = *data.first().ok_or("truncated frame length")? as usize;
2618 if first < 252 {
2619 Ok((first, 1))
2620 } else {
2621 let second = *data.get(1).ok_or("truncated frame length")? as usize;
2622 Ok((second * 4 + first, 2))
2623 }
2624}
2625
2626#[cfg(all(test, feature = "std"))]
2627mod tests {
2628 use super::*;
2629
2630 fn frame_size_from_toc(toc: u8, sampling_rate: i32) -> Option<usize> {
2631 let mode = mode_from_toc(toc);
2632 match mode {
2633 OpusMode::CeltOnly => {
2634 let period = ((toc >> 3) & 0x03) as i32;
2635 let frame_rate = 400 >> period;
2636 if frame_rate == 0 || sampling_rate % frame_rate != 0 {
2637 return None;
2638 }
2639 Some((sampling_rate / frame_rate) as usize)
2640 }
2641 OpusMode::SilkOnly => {
2642 let duration_ms = frame_duration_ms_from_toc(toc);
2643 Some((sampling_rate as i64 * duration_ms as i64 / 1000) as usize)
2644 }
2645 OpusMode::Hybrid => {
2646 let duration_ms = frame_duration_ms_from_toc(toc);
2647 Some((sampling_rate as i64 * duration_ms as i64 / 1000) as usize)
2648 }
2649 }
2650 }
2651
2652 #[test]
2653 fn gen_toc_matches_celt_reference_values() {
2654 let sampling_rate = 48_000;
2655 let cases = [
2656 (120usize, 0xE0u8),
2657 (240usize, 0xE8u8),
2658 (480usize, 0xF0u8),
2659 (960usize, 0xF8u8),
2660 ];
2661
2662 for (frame_size, expected_toc) in cases {
2663 let frame_rate = frame_rate_from_params(sampling_rate, frame_size).unwrap();
2664 let toc = gen_toc(OpusMode::CeltOnly, frame_rate, Bandwidth::Fullband, 1);
2665 assert_eq!(
2666 toc, expected_toc,
2667 "frame_size {} expected TOC {:02X} got {:02X}",
2668 frame_size, expected_toc, toc
2669 );
2670 let decoded_size = frame_size_from_toc(toc, sampling_rate).unwrap();
2671 assert_eq!(decoded_size, frame_size);
2672 }
2673
2674 let stereo_toc = gen_toc(
2675 OpusMode::CeltOnly,
2676 frame_rate_from_params(sampling_rate, 960).unwrap(),
2677 Bandwidth::Fullband,
2678 2,
2679 );
2680 assert_eq!(channels_from_toc(stereo_toc), 2);
2681 }
2682
2683 #[test]
2684 fn test_celt_decoder_large_frame_sizes() {
2685 let sampling_rate = 48000;
2686 let channels = 1;
2687
2688 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
2689
2690 let frame_sizes = [120, 240, 480, 960];
2691
2692 for frame_size in frame_sizes {
2693 let toc = gen_toc(
2694 OpusMode::CeltOnly,
2695 frame_rate_from_params(sampling_rate, frame_size).unwrap(),
2696 Bandwidth::Fullband,
2697 channels,
2698 );
2699 let packet = [toc, 0, 0, 0, 0];
2700
2701 let mut output = vec![0.0f32; frame_size * channels];
2702
2703 let _ = decoder.decode(&packet, frame_size, &mut output);
2704 }
2705
2706 let channels = 2;
2707 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
2708
2709 for frame_size in frame_sizes {
2710 let toc = gen_toc(
2711 OpusMode::CeltOnly,
2712 frame_rate_from_params(sampling_rate, frame_size).unwrap(),
2713 Bandwidth::Fullband,
2714 channels,
2715 );
2716 let packet = [toc, 0, 0, 0, 0];
2717
2718 let mut output = vec![0.0f32; frame_size * channels];
2719 let _ = decoder.decode(&packet, frame_size, &mut output);
2720 }
2721 }
2722
2723 #[test]
2724 fn test_celt_decoder_edge_case_frame_sizes() {
2725 let sampling_rate = 48000;
2726 let channels = 1;
2727 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
2728
2729 let edge_sizes = [2048, 2167, 2168, 2169, 2880, 3072];
2730
2731 for frame_size in edge_sizes {
2732 let mut output = vec![0.0f32; frame_size * channels];
2733
2734 let _ = decoder.decode(&[0x80, 0, 0, 0], frame_size, &mut output);
2735 }
2736 }
2737
2738 #[test]
2745 fn test_invalid_small_frame_size_returns_error_not_panic() {
2746 let mut enc = OpusEncoder::new(48000, 2, Application::Voip).unwrap();
2747 enc.bitrate_bps = 64000;
2748 enc.complexity = 5;
2749 enc.use_cbr = true;
2750
2751 let input = vec![0.0f32; 48 * 2]; let mut output = vec![0u8; 256];
2754
2755 let result = enc.encode(&input, 48, &mut output);
2756 assert!(
2757 result.is_err(),
2758 "encode with invalid frame_size=48 should return Err, not panic"
2759 );
2760 }
2761
2762 #[test]
2765 fn test_invalid_small_frame_size_audio_application_returns_error() {
2766 let mut enc = OpusEncoder::new(48000, 1, Application::Audio).unwrap();
2767 let input = vec![0.0f32; 48];
2768 let mut output = vec![0u8; 256];
2769
2770 let result = enc.encode(&input, 48, &mut output);
2771 assert!(
2772 result.is_err(),
2773 "Audio/48kHz encoder with frame_size=48 should return Err"
2774 );
2775 }
2776}