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;
16pub mod pitch;
17pub mod pvq;
18pub mod quant_bands;
19pub mod range_coder;
20pub mod rate;
21pub mod silk;
22
23pub use silk::{SilkResampler, SilkResamplerDown1_3, SilkResamplerDown1_6};
24
25pub use celt::{CeltDecoder, CeltEncoder};
26use hp_cutoff::hp_cutoff;
27use range_coder::RangeCoder;
28use silk::control_codec::silk_control_encoder;
29use silk::enc_api::silk_encode;
30use silk::init_encoder::silk_init_encoder;
31use silk::lin2log::silk_lin2log;
32use silk::log2lin::silk_log2lin;
33use silk::macros::*;
34use silk::resampler::{silk_resampler_down2, silk_resampler_down2_3};
35use silk::structs::SilkEncoderState;
36use crate::fixedvec::FixedVec;
37
38const OPUS_MAX_CHANNELS: usize = 2;
40const OPUS_MAX_FRAME: usize = 5760;
43const OPUS_MAX_SUBFRAME: usize = 2880;
47const OPUS_SUBFRAME_SCRATCH: usize = OPUS_MAX_SUBFRAME * OPUS_MAX_CHANNELS;
49const OPUS_HP_MEM: usize = OPUS_MAX_CHANNELS * 2;
51const OPUS_PCM_I16: usize = 960 * OPUS_MAX_CHANNELS;
53const OPUS_PCM_TAIL: usize = 240 * OPUS_MAX_CHANNELS;
55const OPUS_MAX_PACKET_FRAMES: usize = 48;
58const OPUS_MAX_PACKET_BYTES: usize = 1276;
60
61#[derive(Debug, Clone, Copy, PartialEq, Eq)]
62pub enum Application {
63 Voip = 2048,
64 Audio = 2049,
65 RestrictedLowDelay = 2051,
66}
67
68#[derive(Debug, Clone, Copy, PartialEq, Eq)]
69pub enum Bandwidth {
70 Auto = -1000,
71 Narrowband = 1101,
72 Mediumband = 1102,
73 Wideband = 1103,
74 Superwideband = 1104,
75 Fullband = 1105,
76}
77
78#[derive(Debug, Clone, Copy, PartialEq, Eq)]
79enum OpusMode {
80 SilkOnly,
81 Hybrid,
82 CeltOnly,
83}
84
85pub struct OpusEncoder {
86 #[cfg(not(feature = "heap"))]
87 celt_enc: CeltEncoder,
88 #[cfg(feature = "heap")]
89 celt_enc: Box<CeltEncoder>,
90 #[cfg(not(feature = "heap"))]
91 silk_enc: SilkEncoderState,
92 #[cfg(feature = "heap")]
93 silk_enc: Box<SilkEncoderState>,
94 application: Application,
95 sampling_rate: i32,
96 channels: usize,
97 bandwidth: Bandwidth,
98 pub bitrate_bps: i32,
99 pub complexity: i32,
100 pub use_cbr: bool,
101
102 pub use_inband_fec: bool,
103
104 pub packet_loss_perc: i32,
105 silk_initialized: bool,
106 mode: OpusMode,
107 prev_enc_mode: Option<OpusMode>,
108
109 variable_hp_smth2_q15: i32,
110 hp_mem: FixedVec<i32, OPUS_HP_MEM>,
111
112 #[cfg(not(feature = "heap"))]
113 buf_filtered: FixedVec<i16, OPUS_MAX_FRAME>,
114 #[cfg(feature = "heap")]
115 buf_filtered: Box<FixedVec<i16, OPUS_MAX_FRAME>>,
116 #[cfg(not(feature = "heap"))]
117 buf_silk_input: FixedVec<i16, OPUS_MAX_FRAME>,
118 #[cfg(feature = "heap")]
119 buf_silk_input: Box<FixedVec<i16, OPUS_MAX_FRAME>>,
120 #[cfg(not(feature = "heap"))]
121 buf_stereo_mid: FixedVec<i16, OPUS_MAX_FRAME>,
122 #[cfg(feature = "heap")]
123 buf_stereo_mid: Box<FixedVec<i16, OPUS_MAX_FRAME>>,
124 #[cfg(not(feature = "heap"))]
125 buf_stereo_side: FixedVec<i16, OPUS_MAX_FRAME>,
126 #[cfg(feature = "heap")]
127 buf_stereo_side: Box<FixedVec<i16, OPUS_MAX_FRAME>>,
128 #[cfg(not(feature = "heap"))]
129 buf_celt_input: FixedVec<f32, OPUS_MAX_FRAME>,
130 #[cfg(feature = "heap")]
131 buf_celt_input: Box<FixedVec<f32, OPUS_MAX_FRAME>>,
132 down2_state_first: [i32; 2],
133 down2_state_second: [i32; 2],
134 down2_3_state: [i32; 6],
135 down_1_3_state: silk::resampler::SilkResamplerDown1_3,
136
137 rc: RangeCoder,
138}
139
140fn compute_equiv_rate(
141 bitrate: i32,
142 channels: usize,
143 frame_rate: i32,
144 vbr: bool,
145 complexity: i32,
146 loss: i32,
147) -> i32 {
148 let mut equiv = bitrate;
149 if frame_rate > 50 {
150 equiv -= (40 * channels as i32 + 20) * (frame_rate - 50);
151 }
152 if !vbr {
153 equiv -= equiv / 12;
154 }
155 equiv = equiv * (90 + complexity) / 100;
156 if loss > 0 {
157 equiv -= equiv * loss / (12 * loss + 20);
158 }
159 equiv
160}
161
162fn compute_mode_threshold(
163 application: Application,
164 channels: usize,
165 prev_was_celt: bool,
166 has_prev_mode: bool,
167 voice_est: i32,
168) -> i32 {
169 let mode_voice = if channels == 1 { 64000 } else { 44000 };
170 let mode_music = 10000;
171
172 let diff = mode_voice - mode_music;
173 let offset = (voice_est * voice_est * diff) >> 14;
174 let mut threshold = mode_music + offset;
175
176 if application == Application::Voip {
177 threshold += 8000;
178 }
179
180 if has_prev_mode {
181 if prev_was_celt {
182 threshold -= 4000;
183 } else {
184 threshold += 4000;
185 }
186 }
187
188 if application == Application::RestrictedLowDelay {
189 threshold = 0;
190 }
191
192 threshold
193}
194
195fn compute_silk_rate_for_hybrid(rate_bps: i32, frame20ms: bool) -> i32 {
196 const RATE_TABLE: &[(i32, i32, i32)] = &[
197 (0, 0, 0),
198 (12000, 10000, 10000),
199 (16000, 13500, 13500),
200 (20000, 16000, 16000),
201 (24000, 18000, 18000),
202 (32000, 22000, 22000),
203 (64000, 38000, 38000),
204 ];
205 let n = RATE_TABLE.len();
206 let mut i = 1;
207 while i < n && RATE_TABLE[i].0 <= rate_bps {
208 i += 1;
209 }
210 if i == n {
211 let (x_last, r10_last, r20_last) = RATE_TABLE[n - 1];
212 let base = if frame20ms { r20_last } else { r10_last };
213 base + (rate_bps - x_last) / 2
214 } else {
215 let (x0, lo10, lo20) = RATE_TABLE[i - 1];
216 let (x1, hi10, hi20) = RATE_TABLE[i];
217 let (lo, hi) = if frame20ms {
218 (lo20, hi20)
219 } else {
220 (lo10, hi10)
221 };
222 (lo * (x1 - rate_bps) + hi * (rate_bps - x0)) / (x1 - x0)
223 }
224}
225
226#[cfg(all(test, feature = "std"))]
227mod silk_rate_tests {
228 use super::compute_silk_rate_for_hybrid;
229
230 #[test]
231 fn test_reference_table_exact_entries() {
232 assert_eq!(compute_silk_rate_for_hybrid(12000, true), 10000);
233 assert_eq!(compute_silk_rate_for_hybrid(16000, true), 13500);
234 assert_eq!(compute_silk_rate_for_hybrid(20000, true), 16000);
235 assert_eq!(compute_silk_rate_for_hybrid(24000, true), 18000);
236 assert_eq!(compute_silk_rate_for_hybrid(32000, true), 22000);
237 assert_eq!(compute_silk_rate_for_hybrid(64000, true), 38000);
238 }
239
240 #[test]
241 fn test_32kbps_gives_22kbps_silk() {
242 assert_eq!(compute_silk_rate_for_hybrid(32000, true), 22000);
243 }
244
245 #[test]
246 fn test_interpolation_between_table_entries() {
247 let r = compute_silk_rate_for_hybrid(18000, true);
248 assert_eq!(r, 14750);
249 }
250
251 #[test]
252 fn test_above_table_max_gives_half_extra() {
253 let r = compute_silk_rate_for_hybrid(72000, true);
254 assert_eq!(r, 38000 + (72000 - 64000) / 2);
255 }
256}
257
258#[cfg(feature = "heap")]
267#[inline(always)]
268fn state_ref<T: core::ops::Deref>(b: &T) -> &T::Target {
269 b
270}
271#[cfg(not(feature = "heap"))]
272#[inline(always)]
273fn state_ref<T: ?Sized>(b: &T) -> &T {
274 b
275}
276
277#[cfg(feature = "heap")]
278#[inline(always)]
279fn state_mut<T: core::ops::DerefMut>(b: &mut T) -> &mut T::Target {
280 b
281}
282#[cfg(not(feature = "heap"))]
283#[inline(always)]
284fn state_mut<T: ?Sized>(b: &mut T) -> &mut T {
285 b
286}
287
288impl OpusEncoder {
289 pub fn new(
290 sampling_rate: i32,
291 channels: usize,
292 application: Application,
293 ) -> Result<Self, &'static str> {
294 if ![8000, 12000, 16000, 24000, 48000].contains(&sampling_rate) {
295 return Err("Invalid sampling rate");
296 }
297 if ![1, 2].contains(&channels) {
298 return Err("Invalid number of channels");
299 }
300
301 let mode = modes::default_mode();
302 #[cfg(feature = "heap")]
303 let celt_enc = Box::new(CeltEncoder::new(mode, channels));
304 #[cfg(not(feature = "heap"))]
305 let celt_enc = CeltEncoder::new(mode, channels);
306
307 #[cfg(feature = "heap")]
308 let mut silk_enc = Box::new(SilkEncoderState::default());
309 #[cfg(not(feature = "heap"))]
310 let mut silk_enc = SilkEncoderState::default();
311 if silk_init_encoder(state_mut(&mut silk_enc), 0) != 0 {
312 return Err("SILK encoder initialization failed");
313 }
314
315 let (opus_mode, bw) = match application {
316 Application::Voip => {
317 let bw = match sampling_rate {
318 8000 => Bandwidth::Narrowband,
319 12000 => Bandwidth::Mediumband,
320 16000 => Bandwidth::Wideband,
321 24000 => Bandwidth::Superwideband,
322 48000 => Bandwidth::Fullband,
323 _ => Bandwidth::Narrowband,
324 };
325
326 let mode = if sampling_rate > 16000 {
327 OpusMode::Hybrid
328 } else {
329 OpusMode::SilkOnly
330 };
331 (mode, bw)
332 }
333 Application::RestrictedLowDelay => {
334 let bw = match sampling_rate {
335 8000 => Bandwidth::Narrowband,
336 12000 => Bandwidth::Mediumband,
337 16000 => Bandwidth::Wideband,
338 24000 => Bandwidth::Superwideband,
339 _ => Bandwidth::Fullband,
340 };
341 (OpusMode::CeltOnly, bw)
342 }
343 Application::Audio => {
344 if sampling_rate <= 16000 {
345 let bw = match sampling_rate {
346 8000 => Bandwidth::Narrowband,
347 12000 => Bandwidth::Mediumband,
348 _ => Bandwidth::Wideband,
349 };
350 (OpusMode::SilkOnly, bw)
351 } else {
352 let bw = match sampling_rate {
353 24000 => Bandwidth::Superwideband,
354 _ => Bandwidth::Fullband,
355 };
356 (OpusMode::Hybrid, bw)
357 }
358 }
359 };
360
361 use silk::lin2log::silk_lin2log;
362 let variable_hp_smth2_q15 = silk_lin2log(60) << 8;
363
364 Ok(Self {
365 celt_enc,
366 silk_enc,
367 application,
368 sampling_rate,
369 channels,
370 bandwidth: bw,
371 bitrate_bps: 64000,
372 complexity: 9,
373 use_cbr: false,
374 use_inband_fec: false,
375 packet_loss_perc: 0,
376 silk_initialized: false,
377 prev_enc_mode: None,
378 mode: opus_mode,
379 variable_hp_smth2_q15,
380 hp_mem: FixedVec::from_value(0, channels * 2),
381
382 #[cfg(not(feature = "heap"))]
383 buf_filtered: FixedVec::new(),
384 #[cfg(feature = "heap")]
385 buf_filtered: Box::new(FixedVec::new()),
386 #[cfg(not(feature = "heap"))]
387 buf_silk_input: FixedVec::new(),
388 #[cfg(feature = "heap")]
389 buf_silk_input: Box::new(FixedVec::new()),
390 #[cfg(not(feature = "heap"))]
391 buf_stereo_mid: FixedVec::new(),
392 #[cfg(feature = "heap")]
393 buf_stereo_mid: Box::new(FixedVec::new()),
394 #[cfg(not(feature = "heap"))]
395 buf_stereo_side: FixedVec::new(),
396 #[cfg(feature = "heap")]
397 buf_stereo_side: Box::new(FixedVec::new()),
398 #[cfg(not(feature = "heap"))]
399 buf_celt_input: FixedVec::new(),
400 #[cfg(feature = "heap")]
401 buf_celt_input: Box::new(FixedVec::new()),
402 down2_state_first: [0; 2],
403 down2_state_second: [0; 2],
404 down2_3_state: [0; 6],
405 down_1_3_state: silk::resampler::SilkResamplerDown1_3::default(),
406 rc: RangeCoder::new_encoder(1),
407 })
408 }
409
410 pub fn enable_hybrid_mode(&mut self) -> Result<(), &'static str> {
411 if self.sampling_rate != 24000 && self.sampling_rate != 48000 {
412 return Err("Hybrid mode requires 24kHz or 48kHz sampling rate");
413 }
414 let bw = if self.sampling_rate == 48000 {
415 Bandwidth::Fullband
416 } else {
417 Bandwidth::Superwideband
418 };
419 self.mode = OpusMode::Hybrid;
420 self.bandwidth = bw;
421 self.silk_initialized = false;
422 Ok(())
423 }
424
425 pub fn encode(
426 &mut self,
427 input: &[f32],
428 frame_size: usize,
429 output: &mut [u8],
430 ) -> Result<usize, &'static str> {
431 if output.len() < 2 {
432 return Err("Output buffer too small");
433 }
434
435 let frame_rate = frame_rate_from_params(self.sampling_rate, frame_size)
436 .ok_or("Invalid frame size for sampling rate")?;
437
438 let mut mode = if self.application == Application::RestrictedLowDelay {
442 OpusMode::CeltOnly
443 } else {
444 let equiv = compute_equiv_rate(
445 self.bitrate_bps,
446 self.channels,
447 frame_rate,
448 !self.use_cbr,
449 self.complexity,
450 self.packet_loss_perc,
451 );
452 let prev_was_celt = self.prev_enc_mode == Some(OpusMode::CeltOnly);
453 let has_prev_mode = self.prev_enc_mode.is_some();
454 let voice_est = match self.application {
455 Application::Voip => 115,
456 Application::Audio => 48,
457 Application::RestrictedLowDelay => 0,
458 };
459 let threshold = compute_mode_threshold(
460 self.application,
461 self.channels,
462 prev_was_celt,
463 has_prev_mode,
464 voice_est,
465 );
466 if equiv >= threshold && self.sampling_rate >= 24000 {
467 OpusMode::CeltOnly
468 } else {
469 OpusMode::SilkOnly
470 }
471 };
472
473 let curr_bw = self.bandwidth;
474 if mode == OpusMode::SilkOnly
475 && (curr_bw == Bandwidth::Superwideband || curr_bw == Bandwidth::Fullband)
476 {
477 mode = OpusMode::Hybrid;
478 }
479 if mode == OpusMode::Hybrid
480 && (curr_bw == Bandwidth::Narrowband
481 || curr_bw == Bandwidth::Mediumband
482 || curr_bw == Bandwidth::Wideband)
483 {
484 mode = OpusMode::SilkOnly;
485 }
486
487 if mode == OpusMode::CeltOnly {
488 match frame_rate {
489 400 | 200 | 100 | 50 => {}
490 _ => return Err("Unsupported frame size for CELT-only mode"),
491 }
492 }
493
494 if mode == OpusMode::Hybrid {
495 match frame_rate {
496 100 | 50 => {}
497 _ => return Err("Unsupported frame size for Hybrid mode"),
498 }
499 }
500
501 if mode == OpusMode::SilkOnly {
502 match frame_rate {
503 400 | 200 | 100 | 50 | 25 => {}
504 _ => return Err("Unsupported frame size for SILK-only mode"),
505 }
506 }
507
508 let toc = gen_toc(mode, frame_rate, self.bandwidth, self.channels);
509 output[0] = toc;
510
511 let target_bits =
512 (self.bitrate_bps as i64 * frame_size as i64 / self.sampling_rate as i64) as i32;
513 let cbr_bytes = ((target_bits + 4) / 8) as usize;
514 let max_data_bytes = output.len();
515
516 let n_bytes = cbr_bytes
519 .min(max_data_bytes)
520 .max(1)
521 .min(OPUS_MAX_PACKET_BYTES);
522
523 let init_rc_size = n_bytes - 1;
524 self.rc.reset_for_encode(init_rc_size as u32);
525
526 if mode == OpusMode::SilkOnly || mode == OpusMode::Hybrid {
527 let silk_fs_khz = if mode == OpusMode::Hybrid {
528 16
529 } else {
530 self.sampling_rate.min(16000) / 1000
531 };
532
533 let frame_ms = (frame_size as i32 * 1000) / self.sampling_rate;
534 if !self.silk_initialized || self.silk_enc.s_cmn.fs_khz != silk_fs_khz {
535 let silk_init_bitrate = (((n_bytes - 1) * 8) as i64 * self.sampling_rate as i64
536 / frame_size as i64) as i32;
537 silk_control_encoder(
538 state_mut(&mut self.silk_enc),
539 silk_fs_khz,
540 frame_ms,
541 silk_init_bitrate,
542 self.complexity,
543 );
544 self.silk_enc.s_cmn.use_cbr = if self.use_cbr { 1 } else { 0 };
545
546 self.silk_enc.s_cmn.n_channels = self.channels as i32;
547 self.silk_initialized = true;
548 self.down2_state_first = [0; 2];
549 self.down2_state_second = [0; 2];
550 self.down2_3_state = [0; 6];
551 self.down_1_3_state = silk::resampler::SilkResamplerDown1_3::default();
552 }
553
554 self.silk_enc.s_cmn.use_in_band_fec = if self.use_inband_fec { 1 } else { 0 };
555 self.silk_enc.s_cmn.packet_loss_perc = self.packet_loss_perc.clamp(0, 100);
556
557 self.silk_enc.s_cmn.lbrr_enabled = if self.use_inband_fec { 1 } else { 0 };
558
559 if self.silk_enc.s_cmn.lbrr_gain_increases == 0 {
560 self.silk_enc.s_cmn.lbrr_gain_increases = 2;
561 }
562
563 let hp_freq_smth1 = if mode == OpusMode::CeltOnly {
564 silk_lin2log(60) << 8
565 } else {
566 self.silk_enc.s_cmn.variable_hp_smth1_q15
567 };
568
569 const VARIABLE_HP_SMTH_COEF2_Q16: i32 = 984;
570 self.variable_hp_smth2_q15 = silk_smlawb(
571 self.variable_hp_smth2_q15,
572 hp_freq_smth1 - self.variable_hp_smth2_q15,
573 VARIABLE_HP_SMTH_COEF2_Q16,
574 );
575
576 let cutoff_hz = silk_log2lin(silk_rshift(self.variable_hp_smth2_q15, 8));
577
578 let required_size = frame_size * self.channels;
579 self.buf_filtered.resize(required_size, 0);
580 if self.application == Application::Voip {
581 hp_cutoff(
582 input,
583 cutoff_hz,
584 state_mut(&mut self.buf_filtered),
585 &mut self.hp_mem,
586 frame_size,
587 self.channels,
588 self.sampling_rate,
589 );
590 } else {
591 for (i, &x) in input.iter().enumerate() {
592 self.buf_filtered[i] = (x * 32768.0).clamp(-32768.0, 32767.0) as i16;
593 }
594 }
595
596 let input_i16 = state_ref(&self.buf_filtered);
597
598 let silk_input: &[i16] = if mode == OpusMode::SilkOnly && self.sampling_rate > 16000 {
599 if self.sampling_rate == 48000 {
600 let stage1_size = frame_size / 2;
601 let mut stage1_buf = [0i16; 480];
602 silk_resampler_down2(
603 &mut self.down2_state_first,
604 &mut stage1_buf[..stage1_size],
605 input_i16,
606 frame_size as i32,
607 );
608 let silk_frame_size = stage1_size * 2 / 3;
609 self.buf_silk_input.resize(silk_frame_size, 0);
610 silk_resampler_down2_3(
611 &mut self.down2_3_state,
612 state_mut(&mut self.buf_silk_input),
613 &stage1_buf[..stage1_size],
614 stage1_size as i32,
615 );
616 state_ref(&self.buf_silk_input)
617 } else if self.sampling_rate == 24000 {
618 let silk_frame_size = frame_size * 2 / 3;
619 self.buf_silk_input.resize(silk_frame_size, 0);
620 silk_resampler_down2_3(
621 &mut self.down2_3_state,
622 state_mut(&mut self.buf_silk_input),
623 input_i16,
624 frame_size as i32,
625 );
626 state_ref(&self.buf_silk_input)
627 } else {
628 input_i16
629 }
630 } else if mode == OpusMode::SilkOnly && self.channels == 2 {
631 let frame_length = input_i16.len() / 2;
632 self.buf_stereo_mid.resize(frame_length, 0);
633 self.buf_stereo_side.resize(frame_length, 0);
634 for i in 0..frame_length {
635 let l = input_i16[2 * i] as i32;
636 let r = input_i16[2 * i + 1] as i32;
637 self.buf_stereo_mid[i] = ((l + r) / 2) as i16;
638 self.buf_stereo_side[i] = (l - r) as i16;
639 }
640
641 self.silk_enc.stereo.side.resize(frame_length, 0);
642 self.silk_enc
643 .stereo
644 .side
645 .copy_from_slice(&self.buf_stereo_side[..frame_length]);
646 state_ref(&self.buf_stereo_mid)
647 } else if mode == OpusMode::Hybrid && self.sampling_rate > 16000 {
648 if self.sampling_rate == 48000 {
649 let silk_frame_size = frame_size / 3;
650 self.buf_silk_input.resize(silk_frame_size, 0);
651 silk::resampler::silk_resampler_down_1_3(
652 &mut self.down_1_3_state,
653 state_mut(&mut self.buf_silk_input),
654 input_i16,
655 );
656 } else {
657 let silk_frame_size = frame_size * 2 / 3;
658 self.buf_silk_input.resize(silk_frame_size, 0);
659 silk_resampler_down2_3(
660 &mut self.down2_3_state,
661 state_mut(&mut self.buf_silk_input),
662 input_i16,
663 frame_size as i32,
664 );
665 }
666 state_ref(&self.buf_silk_input)
667 } else {
668 input_i16
669 };
670
671 let mut pn_bytes = 0;
672
673 let silk_rate_for_calc = if mode == OpusMode::Hybrid {
674 16000
675 } else {
676 self.sampling_rate
677 };
678 let silk_frame_len = silk_input.len();
679
680 let silk_bitrate = if mode == OpusMode::Hybrid {
681 let frame_duration_ms = frame_size as i32 * 1000 / self.sampling_rate;
682 let frame20ms = frame_duration_ms >= 20;
683 compute_silk_rate_for_hybrid(self.bitrate_bps, frame20ms)
684 } else {
685 (8i64 * (n_bytes - 1) as i64 * silk_rate_for_calc as i64 / silk_frame_len as i64)
686 as i32
687 };
688 let silk_max_bits = if mode == OpusMode::Hybrid {
689 let total_max_bits = ((n_bytes - 1) * 8) as i32;
690 if self.use_cbr {
691 let silk_bits = (silk_bitrate as i64 * silk_frame_len as i64
692 / silk_rate_for_calc as i64) as i32;
693 let other_bits = 0i32.max(total_max_bits - silk_bits);
694 0i32.max(total_max_bits - other_bits * 3 / 4)
695 } else {
696 let frame_duration_ms = frame_size as i32 * 1000 / self.sampling_rate;
697 let frame20ms = frame_duration_ms >= 20;
698 let max_bit_rate = compute_silk_rate_for_hybrid(
699 total_max_bits * self.sampling_rate / frame_size as i32,
700 frame20ms,
701 );
702 max_bit_rate * frame_size as i32 / self.sampling_rate
703 }
704 } else {
705 ((n_bytes - 1) * 8) as i32
706 };
707 let silk_use_cbr = if mode == OpusMode::Hybrid && self.use_cbr {
708 0
709 } else if self.use_cbr {
710 1
711 } else {
712 0
713 };
714 let ret = silk_encode(
715 state_mut(&mut self.silk_enc),
716 silk_input,
717 silk_input.len(),
718 &mut self.rc,
719 &mut pn_bytes,
720 silk_bitrate,
721 silk_max_bits,
722 silk_use_cbr,
723 1,
724 );
725 if ret != 0 {
726 return Err("SILK encoding failed");
727 }
728 }
729
730 if mode == OpusMode::Hybrid {
731 self.rc.encode_bit_logp(false, 12); }
733
734 if mode == OpusMode::Hybrid {
735 let nb_compr_bytes = (n_bytes - 1) as u32;
736 self.rc.shrink(nb_compr_bytes);
737 }
738
739 let silk_ret_bytes = if mode == OpusMode::SilkOnly {
740 ((self.rc.tell() + 7) >> 3) as usize
741 } else {
742 0
743 };
744
745 if mode == OpusMode::CeltOnly || mode == OpusMode::Hybrid {
746 self.celt_enc.complexity = self.complexity;
747 let start_band = if mode == OpusMode::Hybrid { 17 } else { 0 };
748 let total_packet_bits = ((n_bytes - 1) * 8) as i32;
749
750 let celt_input: &[f32] = if self.channels == 1 {
751 input
752 } else {
753 let n = frame_size * self.channels;
754 self.buf_celt_input.resize(n, 0.0);
755 for i in 0..frame_size {
756 for ch in 0..self.channels {
757 self.buf_celt_input[ch * frame_size + i] = input[i * self.channels + ch];
758 }
759 }
760 state_ref(&self.buf_celt_input)
761 };
762
763 if self.rc.tell() <= total_packet_bits {
764 self.celt_enc.encode_with_budget(
765 celt_input,
766 frame_size,
767 &mut self.rc,
768 start_band,
769 total_packet_bits,
770 );
771 }
772 }
773
774 self.rc.done();
775
776 if self.rc.error != 0 {
777 return Err("Range coder buffer overflow: encoded data exceeds packet budget");
778 }
779
780 if mode == OpusMode::SilkOnly {
781 let mut ret = silk_ret_bytes.min(self.rc.storage as usize);
782 while ret > 2 && self.rc.buf[ret - 1] == 0 {
783 ret -= 1;
784 }
785
786 let target_total = if self.use_cbr {
787 n_bytes.min(output.len())
788 } else {
789 (ret + 1).min(output.len())
790 };
791
792 let silk_len = ret;
793
794 if !self.use_cbr || silk_len + 1 >= target_total {
795 output[0] = toc;
797 let copy_len = silk_len.min(target_total - 1);
798 output[1..1 + copy_len].copy_from_slice(&self.rc.buf[..copy_len]);
799 return Ok((copy_len + 1).min(output.len()));
800 }
801
802 output[0] = toc | 0x03;
803
804 if silk_len + 2 >= target_total {
805 output[1] = 0x01;
806 let copy_len = (target_total - 2).min(silk_len);
807 output[2..2 + copy_len].copy_from_slice(&self.rc.buf[..copy_len]);
808 self.prev_enc_mode = Some(mode);
809 return Ok(target_total.min(output.len()));
810 }
811
812 let pad_amount = target_total - silk_len - 2;
813 output[1] = 0x41;
814
815 let nb_255s = (pad_amount - 1) / 255;
816 let mut ptr = 2;
817 for _ in 0..nb_255s {
818 output[ptr] = 255;
819 ptr += 1;
820 }
821 output[ptr] = (pad_amount - 255 * nb_255s - 1) as u8;
822 ptr += 1;
823
824 output[ptr..ptr + silk_len].copy_from_slice(&self.rc.buf[..silk_len]);
825 ptr += silk_len;
826
827 let fill_end = target_total.min(output.len());
828 for byte in output[ptr..fill_end].iter_mut() {
829 *byte = 0;
830 }
831
832 self.prev_enc_mode = Some(mode);
833 return Ok(target_total.min(output.len()));
834 }
835
836 let payload_len = n_bytes - 1;
837 output[1..1 + payload_len].copy_from_slice(&self.rc.buf[..payload_len]);
838 self.prev_enc_mode = Some(mode);
839 Ok(n_bytes)
840 }
841}
842
843pub struct OpusDecoder {
844 #[cfg(not(feature = "heap"))]
845 celt_dec: CeltDecoder,
846 #[cfg(feature = "heap")]
847 celt_dec: Box<CeltDecoder>,
848 #[cfg(not(feature = "heap"))]
849 silk_dec: silk::dec_api::SilkDecoder,
850 #[cfg(feature = "heap")]
851 silk_dec: Box<silk::dec_api::SilkDecoder>,
852 sampling_rate: i32,
853 channels: usize,
854
855 prev_mode: Option<OpusMode>,
856
857 prev_redundancy: bool,
859 frame_size: usize,
860
861 bandwidth: Bandwidth,
862
863 stream_channels: usize,
864
865 silk_resampler: silk::resampler::SilkResampler,
866
867 silk_resampler_2: silk::resampler::SilkResampler,
869
870 prev_internal_rate: i32,
871
872 pub hybrid_skip_celt: bool,
873
874 #[cfg(not(feature = "heap"))]
875 w_pcm_i16: FixedVec<i16, OPUS_PCM_I16>,
876 #[cfg(feature = "heap")]
877 w_pcm_i16: Box<FixedVec<i16, OPUS_PCM_I16>>,
878 #[cfg(not(feature = "heap"))]
879 w_silk_out: FixedVec<f32, OPUS_SUBFRAME_SCRATCH>,
880 #[cfg(feature = "heap")]
881 w_silk_out: Box<FixedVec<f32, OPUS_SUBFRAME_SCRATCH>>,
882 #[cfg(not(feature = "heap"))]
883 w_pcm_resampled: FixedVec<i16, OPUS_SUBFRAME_SCRATCH>,
884 #[cfg(feature = "heap")]
885 w_pcm_resampled: Box<FixedVec<i16, OPUS_SUBFRAME_SCRATCH>>,
886 #[cfg(not(feature = "heap"))]
887 w_celt_planar: FixedVec<f32, OPUS_SUBFRAME_SCRATCH>,
888 #[cfg(feature = "heap")]
889 w_celt_planar: Box<FixedVec<f32, OPUS_SUBFRAME_SCRATCH>>,
890 #[cfg(not(feature = "heap"))]
891 w_celt_out: FixedVec<f32, OPUS_SUBFRAME_SCRATCH>,
892 #[cfg(feature = "heap")]
893 w_celt_out: Box<FixedVec<f32, OPUS_SUBFRAME_SCRATCH>>,
894
895 #[cfg(not(feature = "heap"))]
898 prev_pcm_tail: FixedVec<f32, OPUS_PCM_TAIL>,
899 #[cfg(feature = "heap")]
900 prev_pcm_tail: Box<FixedVec<f32, OPUS_PCM_TAIL>>,
901}
902
903impl OpusDecoder {
904 pub fn new(sampling_rate: i32, channels: usize) -> Result<Self, &'static str> {
905 if ![8000, 12000, 16000, 24000, 48000].contains(&sampling_rate) {
906 return Err("Invalid sampling rate");
907 }
908 if ![1, 2].contains(&channels) {
909 return Err("Invalid number of channels");
910 }
911
912 let mode = modes::default_mode();
913 #[cfg(feature = "heap")]
914 let celt_dec = Box::new(CeltDecoder::new(mode, channels, sampling_rate));
915 #[cfg(not(feature = "heap"))]
916 let celt_dec = CeltDecoder::new(mode, channels, sampling_rate);
917
918 #[cfg(feature = "heap")]
919 let mut silk_dec = Box::new(silk::dec_api::SilkDecoder::new());
920 #[cfg(not(feature = "heap"))]
921 let mut silk_dec = silk::dec_api::SilkDecoder::new();
922 silk_dec.init(sampling_rate.min(16000), channels as i32);
923 silk_dec.channel_state[0].fs_api_hz = sampling_rate;
924
925 Ok(Self {
926 celt_dec,
927 silk_dec,
928 sampling_rate,
929 channels,
930 prev_mode: None,
931 prev_redundancy: false,
932 frame_size: 0,
933 bandwidth: Bandwidth::Auto,
934 stream_channels: channels,
935 silk_resampler: silk::resampler::SilkResampler::default(),
936 silk_resampler_2: silk::resampler::SilkResampler::default(),
937 prev_internal_rate: 0,
938 hybrid_skip_celt: false,
939
940 #[cfg(not(feature = "heap"))]
941 w_pcm_i16: FixedVec::from_value(0i16, 960 * channels),
942 #[cfg(feature = "heap")]
943 w_pcm_i16: Box::new(FixedVec::from_value(0i16, 960 * channels)),
944
945 #[cfg(not(feature = "heap"))]
946 w_silk_out: FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels),
947 #[cfg(feature = "heap")]
948 w_silk_out: Box::new(FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels)),
949 #[cfg(not(feature = "heap"))]
950 w_pcm_resampled: FixedVec::from_value(0i16, OPUS_MAX_SUBFRAME * channels),
951 #[cfg(feature = "heap")]
952 w_pcm_resampled: Box::new(FixedVec::from_value(0i16, OPUS_MAX_SUBFRAME * channels)),
953 #[cfg(not(feature = "heap"))]
954 w_celt_planar: FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels),
955 #[cfg(feature = "heap")]
956 w_celt_planar: Box::new(FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels)),
957 #[cfg(not(feature = "heap"))]
958 w_celt_out: FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels),
959 #[cfg(feature = "heap")]
960 w_celt_out: Box::new(FixedVec::from_value(0.0f32, OPUS_MAX_SUBFRAME * channels)),
961
962 #[cfg(not(feature = "heap"))]
963 prev_pcm_tail: FixedVec::from_value(0.0f32, 240 * channels),
964 #[cfg(feature = "heap")]
965 prev_pcm_tail: Box::new(FixedVec::from_value(0.0f32, 240 * channels)),
966 })
967 }
968
969 pub fn decode(
970 &mut self,
971 input: &[u8],
972 frame_size: usize,
973 output: &mut [f32],
974 ) -> Result<usize, &'static str> {
975 if input.is_empty() {
976 return Err("Input packet empty");
977 }
978
979 let toc = input[0];
980 let mode = mode_from_toc(toc);
981 let packet_channels = channels_from_toc(toc);
982 let bandwidth = bandwidth_from_toc(toc);
983 let frame_duration_ms = frame_duration_ms_from_toc(toc);
984
985 let lost_frame = input.len() <= 1;
989
990 if packet_channels != self.channels {
991 return Err("Channel count mismatch between packet and decoder");
992 }
993
994 let code = toc & 0x03;
995 let frame_count: usize;
996 let frame_payloads: FixedVec<&[u8], OPUS_MAX_PACKET_FRAMES>;
997
998 match code {
999 0 => {
1000 frame_count = 1;
1001 frame_payloads = FixedVec::from_slice(&[&input[1..]]);
1002 }
1003 1 => {
1004 frame_count = 2;
1005 let data_len = input.len() - 1;
1006 if data_len % 2 != 0 {
1009 return Err("Code 1: payload length must be even");
1010 }
1011 let half = data_len / 2;
1012 if half == 0 {
1013 return Err("Code 1: empty frame");
1014 }
1015 frame_payloads = FixedVec::from_slice(&[&input[1..1 + half], &input[1 + half..]]);
1016 }
1017 2 => {
1018 frame_count = 2;
1019 let data = &input[1..];
1020 if data.is_empty() {
1021 return Err("Code 2 packet has no data");
1022 }
1023 let (first_len, header_size) = parse_frame_size(data)?;
1024 if header_size + first_len > data.len() {
1025 return Err("Code 2: first frame size exceeds packet");
1026 }
1027 frame_payloads = FixedVec::from_slice(&[
1028 &data[header_size..header_size + first_len],
1029 &data[header_size + first_len..],
1030 ]);
1031 }
1032 3 => {
1033 if input.len() < 2 {
1034 return Err("Code 3 packet too short");
1035 }
1036 let count_byte = input[1];
1037 let n_frames = (count_byte & 0x3F) as usize;
1038 if n_frames < 1 || n_frames > 48 {
1039 return Err("Code 3: invalid frame count");
1040 }
1041 frame_count = n_frames;
1042 let padding_flag = (count_byte & 0x40) != 0;
1044 let vbr = (count_byte & 0x80) != 0;
1045
1046 let mut ptr = 2usize;
1050 let mut pad_len = 0usize;
1051 if padding_flag {
1052 loop {
1053 if ptr >= input.len() {
1054 return Err("Code 3: padding overflow");
1055 }
1056 let p = input[ptr] as usize;
1057 ptr += 1;
1058 if p == 255 {
1059 pad_len += 254;
1060 } else {
1061 pad_len += p;
1062 break;
1063 }
1064 }
1065 }
1066 if ptr + pad_len > input.len() {
1067 return Err("Code 3: padding exceeds packet");
1068 }
1069 let payload_end = input.len() - pad_len;
1070 let payload = &input[ptr..payload_end];
1071
1072 let mut payloads: FixedVec<&[u8], OPUS_MAX_PACKET_FRAMES> = FixedVec::new();
1073 if frame_count == 1 {
1074 payloads.push(payload);
1077 } else if vbr {
1078 let mut cursor = 0usize;
1081 for i in 0..frame_count {
1082 if i + 1 < frame_count {
1083 if cursor >= payload.len() {
1084 return Err("Code 3: unexpected end in VBR header");
1085 }
1086 let (frame_len, header_bytes) =
1087 parse_frame_size(&payload[cursor..])?;
1088 cursor += header_bytes;
1089 if cursor + frame_len > payload.len() {
1090 return Err("Code 3: frame length exceeds packet");
1091 }
1092 payloads.push(&payload[cursor..cursor + frame_len]);
1093 cursor += frame_len;
1094 } else {
1095 if cursor > payload.len() {
1097 return Err("Code 3: no data for last frame");
1098 }
1099 payloads.push(&payload[cursor..]);
1100 }
1101 }
1102 } else {
1103 if payload.len() % frame_count != 0 {
1107 return Err("Code 3 CBR: payload not divisible by frame count");
1108 }
1109 let frame_len = payload.len() / frame_count;
1110 for i in 0..frame_count {
1111 payloads.push(&payload[i * frame_len..(i + 1) * frame_len]);
1112 }
1113 }
1114 frame_payloads = payloads;
1115 }
1116 _ => unreachable!(),
1117 }
1118
1119 self.frame_size = frame_size;
1120 self.bandwidth = bandwidth;
1121 self.stream_channels = packet_channels;
1122
1123 let toc_frame_size = frame_samples_from_toc(toc, self.sampling_rate)
1128 .ok_or("Invalid TOC for sampling rate")?;
1129 let decoded_total = toc_frame_size * frame_count;
1130 if frame_size < decoded_total {
1131 return Err("frame_size too small for packet");
1132 }
1133 if output.len() < decoded_total * self.channels {
1134 return Err("Output buffer too small for packet");
1135 }
1136 if output.len() > decoded_total * self.channels {
1139 for v in &mut output[decoded_total * self.channels..] {
1140 *v = 0.0;
1141 }
1142 }
1143 let sub_frame_size = toc_frame_size;
1144 let sub_output_len = sub_frame_size * self.channels;
1145
1146 let mode_transition = match self.prev_mode {
1152 Some(prev) if prev != mode && !self.prev_redundancy => true,
1153 _ => false,
1154 };
1155 if mode_transition {
1156 self.celt_dec.reset_state();
1157 }
1158
1159 let f5_bridge = self.sampling_rate as usize / 200; if mode_transition
1165 && f5_bridge > 0
1166 && matches!(
1167 self.prev_mode,
1168 Some(OpusMode::SilkOnly) | Some(OpusMode::Hybrid)
1169 )
1170 && self.prev_internal_rate > 0
1171 {
1172 let internal_rate = self.prev_internal_rate;
1173 let plc_internal_len = (10 * internal_rate / 1000) as usize;
1174 let mut plc_rc = RangeCoder::new_decoder(&[]);
1175 let mut plc_i16: FixedVec<i16, OPUS_PCM_I16> =
1176 FixedVec::from_value(0i16, plc_internal_len * self.channels);
1177 let n = self.silk_dec.decode(
1178 &mut plc_rc,
1179 &mut plc_i16,
1180 silk::decode_frame::FLAG_PACKET_LOST,
1181 true,
1182 10,
1183 internal_rate,
1184 );
1185 if n > 0 {
1186 let bridge_ch = f5_bridge * self.channels;
1187 let bridge_len = bridge_ch.min(self.prev_pcm_tail.len());
1188 if internal_rate == self.sampling_rate {
1189 let n_us = n as usize;
1191 for ch in 0..self.channels {
1192 let src_base = ch * n_us;
1193 for i in 0..(bridge_len / self.channels).min(n_us) {
1194 let dst = i * self.channels + ch;
1195 if dst < bridge_len {
1196 self.prev_pcm_tail[dst] = plc_i16[src_base + i] as f32 / 32768.0;
1197 }
1198 }
1199 }
1200 } else if self.silk_resampler.is_initialized() {
1201 let ratio = self.sampling_rate as f64 / internal_rate as f64;
1203 let out_len = ((n as f64 * ratio) as usize).min(f5_bridge);
1204 let n_us = n as usize;
1205 let mut resampled: FixedVec<i16, OPUS_MAX_FRAME> = FixedVec::from_value(0i16, out_len);
1206 self.silk_resampler.process(
1207 &mut resampled,
1208 &plc_i16[..n_us],
1209 n,
1210 );
1211 for i in 0..out_len {
1212 if i < bridge_len / self.channels {
1213 for ch in 0..self.channels {
1214 self.prev_pcm_tail[i * self.channels + ch] =
1215 resampled[i] as f32 / 32768.0;
1216 }
1217 }
1218 }
1219 }
1220 }
1221 }
1222
1223 let mut has_redundancy = false;
1225
1226 match mode {
1227 OpusMode::SilkOnly => {
1228 let internal_sample_rate = match bandwidth {
1229 Bandwidth::Narrowband => 8000,
1230 Bandwidth::Mediumband => 12000,
1231 Bandwidth::Wideband => 16000,
1232 _ => 16000,
1233 };
1234 let internal_frame_size =
1235 (frame_duration_ms * internal_sample_rate / 1000) as usize;
1236
1237 if self.sampling_rate != internal_sample_rate
1238 && internal_sample_rate != self.prev_internal_rate
1239 {
1240 self.silk_resampler
1241 .init(internal_sample_rate, self.sampling_rate);
1242 self.silk_resampler_2
1243 .init(internal_sample_rate, self.sampling_rate);
1244 }
1245 self.prev_internal_rate = internal_sample_rate;
1249
1250 for (fi, payload) in frame_payloads.iter().enumerate() {
1251 let mut rc = RangeCoder::new_decoder(payload);
1252 let pcm_i16_len = internal_frame_size * self.channels;
1253 debug_assert!(pcm_i16_len <= self.w_pcm_i16.len());
1254
1255 let ret = {
1256 let (silk_dec, pcm_i16) =
1257 (state_mut(&mut self.silk_dec), state_mut(&mut self.w_pcm_i16));
1258 let lost_flag = if lost_frame {
1259 silk::decode_frame::FLAG_PACKET_LOST
1260 } else {
1261 silk::decode_frame::FLAG_DECODE_NORMAL
1262 };
1263 silk_dec.decode(
1264 &mut rc,
1265 &mut pcm_i16[..pcm_i16_len],
1266 lost_flag,
1267 true,
1268 frame_duration_ms,
1269 internal_sample_rate,
1270 )
1271 };
1272
1273 if ret < 0 {
1274 return Err("SILK decoding failed");
1275 }
1276
1277 let decoded_samples = ret as usize;
1278 let out_start = fi * sub_output_len;
1279
1280 if self.sampling_rate == internal_sample_rate {
1282 let frames = decoded_samples.min(sub_frame_size);
1283 for i in 0..frames {
1284 for ch in 0..self.channels {
1285 let src = if ch == 0 { i } else { internal_frame_size + i };
1286 let v = self.w_pcm_i16[src] as f32 / 32768.0;
1287 let idx = out_start + i * self.channels + ch;
1288 if idx < output.len() {
1289 output[idx] = v;
1290 }
1291 }
1292 }
1293 } else {
1294 let ratio = self.sampling_rate as f64 / internal_sample_rate as f64;
1295 let out_len =
1296 ((decoded_samples as f64 * ratio) as usize).min(sub_frame_size);
1297 debug_assert!(out_len * self.channels <= self.w_pcm_resampled.len());
1298 {
1300 let (res, inp, out) = (
1301 &mut self.silk_resampler,
1302 state_ref(&self.w_pcm_i16),
1303 state_mut(&mut self.w_pcm_resampled),
1304 );
1305 res.process(
1306 &mut out[..out_len],
1307 &inp[..decoded_samples],
1308 decoded_samples as i32,
1309 );
1310 }
1311 if self.channels == 2 {
1313 let (res, inp, out) = (
1314 &mut self.silk_resampler_2,
1315 state_ref(&self.w_pcm_i16),
1316 state_mut(&mut self.w_pcm_resampled),
1317 );
1318 res.process(
1319 &mut out[out_len..2 * out_len],
1320 &inp[internal_frame_size..internal_frame_size + decoded_samples],
1321 decoded_samples as i32,
1322 );
1323 }
1324 let frames = out_len.min(sub_frame_size);
1325 for i in 0..frames {
1326 for ch in 0..self.channels {
1327 let v = self.w_pcm_resampled[ch * out_len + i] as f32 / 32768.0;
1328 let idx = out_start + i * self.channels + ch;
1329 if idx < output.len() {
1330 output[idx] = v;
1331 }
1332 }
1333 }
1334 }
1335 }
1336 decoded_total
1337 }
1338
1339 OpusMode::CeltOnly => {
1340 let celt_end_band = self.celt_end_band_from_toc(toc);
1341
1342 for (fi, payload) in frame_payloads.iter().enumerate() {
1343 let mut rc = RangeCoder::new_decoder(payload);
1344 let total_bits = (payload.len() * 8) as i32;
1345 let needed = sub_frame_size * self.channels;
1346 let out_start = fi * needed;
1347 let out_end = (out_start + needed).min(output.len());
1348
1349 if output.len() < out_end {
1350 return Err("Output buffer too small");
1351 }
1352
1353 if self.channels == 1 {
1354 self.celt_dec.decode_from_range_coder_with_band_range(
1355 &mut rc,
1356 total_bits,
1357 sub_frame_size,
1358 &mut output[out_start..out_end],
1359 0,
1360 celt_end_band,
1361 );
1362 for sample in &mut output[out_start..out_end] {
1363 *sample = sample.clamp(-1.0, 1.0);
1364 }
1365 } else {
1366 self.celt_dec.decode_from_range_coder_with_band_range(
1367 &mut rc,
1368 total_bits,
1369 sub_frame_size,
1370 &mut self.w_celt_planar[..needed],
1371 0,
1372 celt_end_band,
1373 );
1374 for i in 0..sub_frame_size {
1375 for ch in 0..self.channels {
1376 let idx = out_start + i * self.channels + ch;
1377 output[idx] =
1378 self.w_celt_planar[ch * sub_frame_size + i].clamp(-1.0, 1.0);
1379 }
1380 }
1381 }
1382 }
1383 decoded_total
1384 }
1385
1386 OpusMode::Hybrid => {
1387 let internal_sample_rate = 16000;
1388 let internal_frame_size =
1389 (frame_duration_ms * internal_sample_rate / 1000) as usize;
1390 let celt_end_band = self.celt_end_band_from_toc(toc);
1391
1392 if self.sampling_rate != internal_sample_rate
1393 && internal_sample_rate != self.prev_internal_rate
1394 {
1395 self.silk_resampler
1396 .init(internal_sample_rate, self.sampling_rate);
1397 self.silk_resampler_2
1398 .init(internal_sample_rate, self.sampling_rate);
1399 }
1400 self.prev_internal_rate = internal_sample_rate;
1401
1402 for (fi, payload) in frame_payloads.iter().enumerate() {
1403 let mut rc = RangeCoder::new_decoder(payload);
1404 let pcm_silk_i16_len = internal_frame_size * self.channels;
1405 debug_assert!(pcm_silk_i16_len <= self.w_pcm_i16.len());
1406
1407 let ret = {
1408 let (silk_dec, pcm_i16) =
1409 (state_mut(&mut self.silk_dec), state_mut(&mut self.w_pcm_i16));
1410 let lost_flag = if lost_frame {
1411 silk::decode_frame::FLAG_PACKET_LOST
1412 } else {
1413 silk::decode_frame::FLAG_DECODE_NORMAL
1414 };
1415 silk_dec.decode(
1416 &mut rc,
1417 &mut pcm_i16[..pcm_silk_i16_len],
1418 lost_flag,
1419 true,
1420 frame_duration_ms,
1421 internal_sample_rate,
1422 )
1423 };
1424
1425 if ret < 0 {
1426 return Err("SILK decoding failed");
1427 }
1428
1429 let silk_out_len = sub_frame_size * self.channels;
1430 self.w_silk_out[..silk_out_len].fill(0.0);
1431 if ret > 0 {
1432 let decoded_samples = ret as usize;
1433 if self.sampling_rate == internal_sample_rate {
1435 let frames = decoded_samples.min(sub_frame_size);
1436 for i in 0..frames {
1437 for ch in 0..self.channels {
1438 let src = if ch == 0 { i } else { internal_frame_size + i };
1439 let v = self.w_pcm_i16[src] as f32 / 32768.0;
1440 let idx = i * self.channels + ch;
1441 if idx < silk_out_len {
1442 self.w_silk_out[idx] = v;
1443 }
1444 }
1445 }
1446 } else {
1447 let ratio = self.sampling_rate as f64 / internal_sample_rate as f64;
1448 let out_len =
1449 ((decoded_samples as f64 * ratio) as usize).min(sub_frame_size);
1450 debug_assert!(out_len * self.channels <= self.w_pcm_resampled.len());
1451 {
1453 let (res, inp, out) = (
1454 &mut self.silk_resampler,
1455 state_ref(&self.w_pcm_i16),
1456 state_mut(&mut self.w_pcm_resampled),
1457 );
1458 res.process(
1459 &mut out[..out_len],
1460 &inp[..decoded_samples],
1461 decoded_samples as i32,
1462 );
1463 }
1464 if self.channels == 2 {
1466 let (res, inp, out) = (
1467 &mut self.silk_resampler_2,
1468 state_ref(&self.w_pcm_i16),
1469 state_mut(&mut self.w_pcm_resampled),
1470 );
1471 res.process(
1472 &mut out[out_len..2 * out_len],
1473 &inp[internal_frame_size..internal_frame_size + decoded_samples],
1474 decoded_samples as i32,
1475 );
1476 }
1477 let frames = out_len.min(sub_frame_size);
1478 for i in 0..frames {
1479 for ch in 0..self.channels {
1480 let v = self.w_pcm_resampled[ch * out_len + i] as f32 / 32768.0;
1481 let idx = i * self.channels + ch;
1482 if idx < silk_out_len {
1483 self.w_silk_out[idx] = v;
1484 }
1485 }
1486 }
1487 }
1488 }
1489
1490 let total_bits = (payload.len() * 8) as i32;
1491 let redundancy = rc.decode_bit_logp(12);
1492 let skip_celt = if redundancy {
1493 let _celt_to_silk = rc.decode_bit_logp(1);
1494 has_redundancy = true;
1495 true
1501 } else {
1502 false
1503 };
1504
1505 if skip_celt {
1506 self.w_celt_out[..silk_out_len].fill(0.0);
1507 } else {
1508 let (celt_dec, celt_planar) =
1509 (state_mut(&mut self.celt_dec), state_mut(&mut self.w_celt_planar));
1510 celt_dec.decode_from_range_coder_with_band_range(
1511 &mut rc,
1512 total_bits,
1513 sub_frame_size,
1514 &mut celt_planar[..silk_out_len],
1515 17,
1516 celt_end_band,
1517 );
1518
1519 if self.channels == 1 {
1520 self.w_celt_out[..silk_out_len]
1521 .copy_from_slice(&self.w_celt_planar[..silk_out_len]);
1522 } else {
1523 for i in 0..sub_frame_size {
1524 for ch in 0..self.channels {
1525 self.w_celt_out[i * self.channels + ch] =
1526 self.w_celt_planar[ch * sub_frame_size + i];
1527 }
1528 }
1529 }
1530 }
1531
1532 let out_start = fi * silk_out_len;
1533 let total = silk_out_len.min(output.len() - out_start);
1534 for j in 0..total {
1535 output[out_start + j] =
1536 (self.w_silk_out[j] + self.w_celt_out[j]).clamp(-1.0, 1.0);
1537 }
1538 }
1539 decoded_total
1540 }
1541 };
1542
1543 let f2_5 = self.sampling_rate as usize / 400;
1549 let f5 = f2_5 * 2;
1550 if mode_transition && f5 > 0 && decoded_total >= f5 {
1551 let window = modes::default_mode().window;
1552 let inc = (48000 / self.sampling_rate) as usize;
1553 let f2_5_ch = f2_5 * self.channels;
1554 let f5_ch = f5 * self.channels;
1555 output[..f2_5_ch].copy_from_slice(&self.prev_pcm_tail[..f2_5_ch]);
1557 let new_mid: FixedVec<f32, OPUS_PCM_TAIL> = FixedVec::from_slice(&output[f2_5_ch..f5_ch]);
1559 smooth_fade(
1560 &self.prev_pcm_tail[f2_5_ch..f5_ch],
1561 &new_mid,
1562 &mut output[f2_5_ch..f5_ch],
1563 f2_5,
1564 self.channels,
1565 window,
1566 inc,
1567 );
1568 }
1569
1570 let tail_len = f5 * self.channels;
1572 let out_total = decoded_total * self.channels;
1573 if out_total >= tail_len && tail_len <= self.prev_pcm_tail.len() {
1574 self.prev_pcm_tail[..tail_len]
1575 .copy_from_slice(&output[out_total - tail_len..out_total]);
1576 }
1577
1578 self.prev_mode = Some(mode);
1579 self.prev_redundancy = has_redundancy;
1580 Ok(decoded_total)
1581 }
1582}
1583
1584impl OpusDecoder {
1585 #[inline(always)]
1586 fn celt_end_band_from_toc(&self, toc: u8) -> usize {
1587 let mode = modes::default_mode();
1588 let top = mode.eff_ebands;
1589 if mode_from_toc(toc) == OpusMode::CeltOnly && toc >= 0x80 {
1590 const FROM_OPUS_TABLE: [u8; 16] = [
1591 0x80, 0x88, 0x90, 0x98, 0x40, 0x48, 0x50, 0x58, 0x20, 0x28, 0x30, 0x38, 0x00, 0x08,
1592 0x10, 0x18,
1593 ];
1594 let idx = ((toc >> 3) - 16) as usize;
1595 let data0 = FROM_OPUS_TABLE[idx] | (toc & 0x7);
1596 let trim = (data0 >> 5) as usize;
1597 return top.saturating_sub(2 * trim).max(1);
1598 }
1599 top
1600 }
1601}
1602
1603fn frame_rate_from_params(sampling_rate: i32, frame_size: usize) -> Option<i32> {
1604 let frame_size = frame_size as i32;
1605 if frame_size == 0 || sampling_rate % frame_size != 0 {
1606 return None;
1607 }
1608 Some(sampling_rate / frame_size)
1609}
1610
1611fn gen_toc(mode: OpusMode, frame_rate: i32, bandwidth: Bandwidth, channels: usize) -> u8 {
1612 let mut rate = frame_rate;
1613 let mut period = 0;
1614 while rate < 400 {
1615 rate <<= 1;
1616 period += 1;
1617 }
1618
1619 let mut toc = match mode {
1620 OpusMode::SilkOnly => {
1621 let bw = (bandwidth as i32 - Bandwidth::Narrowband as i32) << 5;
1622 let per = (period - 2) << 3;
1623 (bw | per) as u8
1624 }
1625 OpusMode::CeltOnly => {
1626 let mut tmp = bandwidth as i32 - Bandwidth::Mediumband as i32;
1627 if tmp < 0 {
1628 tmp = 0;
1629 }
1630 let per = period << 3;
1631 (0x80 | (tmp << 5) | per) as u8
1632 }
1633 OpusMode::Hybrid => {
1634 let base_config = if bandwidth == Bandwidth::Superwideband {
1635 12
1636 } else {
1637 14
1638 };
1639 let period_offset = if frame_rate >= 100 { 0 } else { 1 };
1640 ((base_config + period_offset) << 3) as u8
1641 }
1642 };
1643
1644 if channels == 2 {
1645 toc |= 0x04;
1646 }
1647 toc
1648}
1649
1650fn mode_from_toc(toc: u8) -> OpusMode {
1651 if toc & 0x80 != 0 {
1652 OpusMode::CeltOnly
1653 } else if toc & 0x60 == 0x60 {
1654 OpusMode::Hybrid
1655 } else {
1656 OpusMode::SilkOnly
1657 }
1658}
1659
1660fn bandwidth_from_toc(toc: u8) -> Bandwidth {
1661 let mode = mode_from_toc(toc);
1662 match mode {
1663 OpusMode::SilkOnly => {
1664 let bw_bits = (toc >> 5) & 0x03;
1665 match bw_bits {
1666 0 => Bandwidth::Narrowband,
1667 1 => Bandwidth::Mediumband,
1668 2 => Bandwidth::Wideband,
1669 _ => Bandwidth::Wideband,
1670 }
1671 }
1672 OpusMode::Hybrid => {
1673 let bw_bit = (toc >> 4) & 0x01;
1674 if bw_bit == 0 {
1675 Bandwidth::Superwideband
1676 } else {
1677 Bandwidth::Fullband
1678 }
1679 }
1680 OpusMode::CeltOnly => {
1681 let bw_bits = (toc >> 5) & 0x03;
1682 match bw_bits {
1683 0 => Bandwidth::Mediumband,
1684 1 => Bandwidth::Wideband,
1685 2 => Bandwidth::Superwideband,
1686 3 => Bandwidth::Fullband,
1687 _ => Bandwidth::Fullband,
1688 }
1689 }
1690 }
1691}
1692
1693fn frame_duration_ms_from_toc(toc: u8) -> i32 {
1694 let mode = mode_from_toc(toc);
1695 match mode {
1696 OpusMode::SilkOnly => {
1697 let config = (toc >> 3) & 0x03;
1698 match config {
1699 0 => 10,
1700 1 => 20,
1701 2 => 40,
1702 3 => 60,
1703 _ => 20,
1704 }
1705 }
1706 OpusMode::Hybrid => {
1707 let config = (toc >> 3) & 0x01;
1708 if config == 0 { 10 } else { 20 }
1709 }
1710 OpusMode::CeltOnly => {
1711 let config = (toc >> 3) & 0x03;
1712 match config {
1713 0 => 2,
1714 1 => 5,
1715 2 => 10,
1716 3 => 20,
1717 _ => 20,
1718 }
1719 }
1720 }
1721}
1722
1723fn frame_samples_from_toc(toc: u8, sampling_rate: i32) -> Option<usize> {
1727 let mode = mode_from_toc(toc);
1728 match mode {
1729 OpusMode::CeltOnly => {
1730 let period = ((toc >> 3) & 0x03) as i32;
1731 let frame_rate = 400 >> period;
1732 if frame_rate == 0 || sampling_rate % frame_rate != 0 {
1733 return None;
1734 }
1735 Some((sampling_rate / frame_rate) as usize)
1736 }
1737 OpusMode::SilkOnly | OpusMode::Hybrid => {
1738 let duration_ms = frame_duration_ms_from_toc(toc);
1739 Some((sampling_rate as i64 * duration_ms as i64 / 1000) as usize)
1740 }
1741 }
1742}
1743
1744fn channels_from_toc(toc: u8) -> usize {
1745 if toc & 0x04 != 0 { 2 } else { 1 }
1746}
1747
1748fn smooth_fade(
1751 in1: &[f32],
1752 in2: &[f32],
1753 out: &mut [f32],
1754 overlap: usize,
1755 channels: usize,
1756 window: &[f32],
1757 inc: usize,
1758) {
1759 for c in 0..channels {
1760 for i in 0..overlap {
1761 let wi = i * inc;
1762 if wi >= window.len() {
1763 break;
1764 }
1765 let w = window[wi] * window[wi];
1766 out[i * channels + c] = w * in2[i * channels + c] + (1.0 - w) * in1[i * channels + c];
1767 }
1768 }
1769}
1770
1771fn parse_frame_size(data: &[u8]) -> Result<(usize, usize), &'static str> {
1779 let first = *data.first().ok_or("truncated frame length")? as usize;
1780 if first < 252 {
1781 Ok((first, 1))
1782 } else {
1783 let second = *data.get(1).ok_or("truncated frame length")? as usize;
1784 Ok((second * 4 + first, 2))
1785 }
1786}
1787
1788#[cfg(all(test, feature = "std"))]
1789mod tests {
1790 use super::*;
1791
1792 fn frame_size_from_toc(toc: u8, sampling_rate: i32) -> Option<usize> {
1793 let mode = mode_from_toc(toc);
1794 match mode {
1795 OpusMode::CeltOnly => {
1796 let period = ((toc >> 3) & 0x03) as i32;
1797 let frame_rate = 400 >> period;
1798 if frame_rate == 0 || sampling_rate % frame_rate != 0 {
1799 return None;
1800 }
1801 Some((sampling_rate / frame_rate) as usize)
1802 }
1803 OpusMode::SilkOnly => {
1804 let duration_ms = frame_duration_ms_from_toc(toc);
1805 Some((sampling_rate as i64 * duration_ms as i64 / 1000) as usize)
1806 }
1807 OpusMode::Hybrid => {
1808 let duration_ms = frame_duration_ms_from_toc(toc);
1809 Some((sampling_rate as i64 * duration_ms as i64 / 1000) as usize)
1810 }
1811 }
1812 }
1813
1814 #[test]
1815 fn gen_toc_matches_celt_reference_values() {
1816 let sampling_rate = 48_000;
1817 let cases = [
1818 (120usize, 0xE0u8),
1819 (240usize, 0xE8u8),
1820 (480usize, 0xF0u8),
1821 (960usize, 0xF8u8),
1822 ];
1823
1824 for (frame_size, expected_toc) in cases {
1825 let frame_rate = frame_rate_from_params(sampling_rate, frame_size).unwrap();
1826 let toc = gen_toc(OpusMode::CeltOnly, frame_rate, Bandwidth::Fullband, 1);
1827 assert_eq!(
1828 toc, expected_toc,
1829 "frame_size {} expected TOC {:02X} got {:02X}",
1830 frame_size, expected_toc, toc
1831 );
1832 let decoded_size = frame_size_from_toc(toc, sampling_rate).unwrap();
1833 assert_eq!(decoded_size, frame_size);
1834 }
1835
1836 let stereo_toc = gen_toc(
1837 OpusMode::CeltOnly,
1838 frame_rate_from_params(sampling_rate, 960).unwrap(),
1839 Bandwidth::Fullband,
1840 2,
1841 );
1842 assert_eq!(channels_from_toc(stereo_toc), 2);
1843 }
1844
1845 #[test]
1846 fn test_celt_decoder_large_frame_sizes() {
1847 let sampling_rate = 48000;
1848 let channels = 1;
1849
1850 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
1851
1852 let frame_sizes = [120, 240, 480, 960];
1853
1854 for frame_size in frame_sizes {
1855 let toc = gen_toc(
1856 OpusMode::CeltOnly,
1857 frame_rate_from_params(sampling_rate, frame_size).unwrap(),
1858 Bandwidth::Fullband,
1859 channels,
1860 );
1861 let packet = [toc, 0, 0, 0, 0];
1862
1863 let mut output = vec![0.0f32; frame_size * channels];
1864
1865 let _ = decoder.decode(&packet, frame_size, &mut output);
1866 }
1867
1868 let channels = 2;
1869 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
1870
1871 for frame_size in frame_sizes {
1872 let toc = gen_toc(
1873 OpusMode::CeltOnly,
1874 frame_rate_from_params(sampling_rate, frame_size).unwrap(),
1875 Bandwidth::Fullband,
1876 channels,
1877 );
1878 let packet = [toc, 0, 0, 0, 0];
1879
1880 let mut output = vec![0.0f32; frame_size * channels];
1881 let _ = decoder.decode(&packet, frame_size, &mut output);
1882 }
1883 }
1884
1885 #[test]
1886 fn test_celt_decoder_edge_case_frame_sizes() {
1887 let sampling_rate = 48000;
1888 let channels = 1;
1889 let mut decoder = OpusDecoder::new(sampling_rate, channels).unwrap();
1890
1891 let edge_sizes = [2048, 2167, 2168, 2169, 2880, 3072];
1892
1893 for frame_size in edge_sizes {
1894 let mut output = vec![0.0f32; frame_size * channels];
1895
1896 let _ = decoder.decode(&[0x80, 0, 0, 0], frame_size, &mut output);
1897 }
1898 }
1899
1900 #[test]
1907 fn test_invalid_small_frame_size_returns_error_not_panic() {
1908 let mut enc = OpusEncoder::new(48000, 2, Application::Voip).unwrap();
1909 enc.bitrate_bps = 64000;
1910 enc.complexity = 5;
1911 enc.use_cbr = true;
1912
1913 let input = vec![0.0f32; 48 * 2]; let mut output = vec![0u8; 256];
1916
1917 let result = enc.encode(&input, 48, &mut output);
1918 assert!(
1919 result.is_err(),
1920 "encode with invalid frame_size=48 should return Err, not panic"
1921 );
1922 }
1923
1924 #[test]
1927 fn test_invalid_small_frame_size_audio_application_returns_error() {
1928 let mut enc = OpusEncoder::new(48000, 1, Application::Audio).unwrap();
1929 let input = vec![0.0f32; 48];
1930 let mut output = vec![0u8; 256];
1931
1932 let result = enc.encode(&input, 48, &mut output);
1933 assert!(
1934 result.is_err(),
1935 "Audio/48kHz encoder with frame_size=48 should return Err"
1936 );
1937 }
1938}