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