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