1use crate::bands::{
2 SPREAD_NONE, SPREAD_NORMAL, compute_band_energies, denormalise_bands, haar1, log2amp,
3 normalise_bands, quant_all_bands, spreading_decision,
4};
5use crate::modes::{CeltMode, SPREAD_ICDF, TAPSET_ICDF, TF_SELECT_TABLE, TRIM_ICDF};
6use crate::quant_bands::{
7 quant_coarse_energy_advanced, quant_energy_finalise, quant_fine_energy, unquant_coarse_energy,
8 unquant_energy_finalise, unquant_fine_energy,
9};
10use crate::range_coder::RangeCoder;
11use crate::rate::{BITRES, clt_compute_allocation};
12use core::mem::MaybeUninit;
13
14#[cfg(not(feature = "std"))]
15use crate::compat::Math;
16use crate::fixedvec::FixedVec;
17#[inline]
18fn bitrate_to_bits(bitrate: i32, fs: i32, frame_size: i32) -> i32 {
19 bitrate * 6 / (6 * fs / frame_size)
20}
21
22const OPUS_BITRATE_MAX: i32 = -1;
23#[allow(clippy::too_many_arguments)]
24fn compute_vbr(
25 mode: &CeltMode,
26 analysis: &AnalysisInfo,
27 base_target: i32,
28 lm: i32,
29 bitrate: i32,
30 last_coded_bands: i32,
31 c: i32,
32 intensity: i32,
33 constrained_vbr: bool,
34 stereo_saving: f32,
35 tot_boost: i32,
36 tf_estimate: f32,
37 pitch_change: i32,
38 max_depth: f32,
39 lfe: bool,
40 has_surround_mask: bool,
41 surround_masking: f32,
42 temporal_vbr: f32,
43) -> i32 {
44 let nb_ebands = mode.nb_ebands as i32;
45 let mut coded_bands = if last_coded_bands != 0 {
46 last_coded_bands
47 } else {
48 nb_ebands
49 };
50 coded_bands = coded_bands.clamp(0, nb_ebands);
51 let mut coded_bins = mode.e_bands[coded_bands as usize] as i32 * (1 << lm);
52 if c == 2 {
53 let idx = intensity.min(coded_bands) as usize;
54 coded_bins += mode.e_bands[idx] as i32 * (1 << lm);
55 }
56 let mut target = base_target;
57 if analysis.valid && analysis.activity < 0.4 {
58 target -= ((coded_bins << BITRES) as f32 * (0.4 - analysis.activity)) as i32;
59 }
60 if c == 2 {
61 let coded_stereo_bands = intensity.min(coded_bands);
62 let coded_stereo_dof =
63 mode.e_bands[coded_stereo_bands as usize] as i32 * (1 << lm) - coded_stereo_bands;
64 let max_frac = (0.8 * coded_stereo_dof as f32) / coded_bins as f32;
65 let ss = stereo_saving.min(1.0);
66 let adjust = ((ss - 0.1).max(0.0) * coded_stereo_dof as f32 * (1 << BITRES) as f32) as i32;
67 let save = (max_frac * target as f32) as i32;
68 target -= save.min(adjust);
69 }
70 target += tot_boost - (19 << lm);
71 target += ((tf_estimate - 0.044) * target as f32) as i32;
73 if analysis.valid && !lfe {
74 let tonal = (analysis.tonality - 0.15).max(0.0) - 0.12;
75 let mut tonal_target = target + ((coded_bins << BITRES) as f32 * 1.2 * tonal) as i32;
76 if pitch_change != 0 {
77 tonal_target += ((coded_bins << BITRES) as f32 * 0.8) as i32;
78 }
79 target = tonal_target;
80 }
81 if has_surround_mask && !lfe {
82 let surround_target =
83 target + (surround_masking * coded_bins as f32 * (1 << BITRES) as f32) as i32;
84 target = (target / 4).max(surround_target);
85 }
86 if max_depth > 0.0 {
88 let bins = mode.e_bands[(nb_ebands - 2) as usize] as i32 * (1 << lm);
89 let floor_depth = ((c * bins * (1 << BITRES)) as f32 * max_depth) as i32;
90 let floor_depth = floor_depth.max(target >> 2);
91 target = target.min(floor_depth);
92 }
93 if (!has_surround_mask || lfe) && constrained_vbr {
94 target = base_target + ((target - base_target) as f32 * 0.67) as i32;
95 }
96 if !has_surround_mask && tf_estimate < 0.2 {
97 let amount = 0.0000031 * (32000.min((96000 - bitrate).max(0)) as f32);
98 let tvbr_factor = temporal_vbr * amount;
99 target += (tvbr_factor * target as f32) as i32;
100 }
101 target.min(2 * base_target)
102}
103const EMEANS_F: [f32; 25] = [
104 6.4375, 6.25, 5.75, 5.3125, 5.0625, 4.8125, 4.5, 4.375, 4.875, 4.6875, 4.5625, 4.4375, 4.875,
105 4.625, 4.3125, 4.5, 4.375, 4.625, 4.75, 4.4375, 3.75, 3.75, 3.75, 3.75, 3.75,
106];
107fn compute_max_depth(
108 mode: &CeltMode,
109 band_log_e: &[f32],
110 nb_ebands: usize,
111 c: usize,
112 end: usize,
113 lsb_depth: i32,
114) -> f32 {
115 let mut max_depth: f32 = -31.9;
116 for ch in 0..c {
117 for i in 0..end {
118 let log_n = mode.log_n[i] as f32;
119 let e_mean = if i < EMEANS_F.len() { EMEANS_F[i] } else { 0.0 };
120 let noise_floor = 0.0625 * log_n + 0.5 + (9 - lsb_depth) as f32 - e_mean
121 + 0.0062 * ((i + 5) * (i + 5)) as f32;
122 let v = band_log_e[ch * nb_ebands + i] - noise_floor;
123 if v > max_depth {
124 max_depth = v;
125 }
126 }
127 }
128 max_depth
129}
130
131const CELT_MAX_CHANNELS: usize = 2;
136const CELT_NB_EBANDS: usize = 21;
138const CELT_NB_X_CH: usize = CELT_NB_EBANDS * CELT_MAX_CHANNELS;
140const CELT_OVERLAP: usize = 120;
142const CELT_CHANNEL_MEM: usize = 2048 + CELT_OVERLAP;
144const CELT_SYN_MEM: usize = CELT_MAX_CHANNELS * CELT_CHANNEL_MEM;
146const CELT_PREFILTER_MEM: usize = CELT_MAX_CHANNELS * COMBFILTER_MAXPERIOD;
148const CELT_BUFSTRIDE: usize = (MAX_FRAME_SIZE + CELT_OVERLAP) * CELT_MAX_CHANNELS;
150const CELT_FRAME_X_CH: usize = MAX_FRAME_SIZE * CELT_MAX_CHANNELS;
152const CELT_W_FREQ: usize = CELT_FRAME_X_CH + 4;
154const CELT_W_X_ENC: usize = CELT_FRAME_X_CH + STRIDE_ACCESS_PAD;
156const CELT_PREFILTER_PRE: usize = CELT_MAX_CHANNELS * (COMBFILTER_MAXPERIOD + MAX_FRAME_SIZE);
158const CELT_PREFILTER_PITCH: usize = (COMBFILTER_MAXPERIOD + MAX_FRAME_SIZE) >> 1;
160const CELT_W_X_DEC: usize = DECODE_BUFFER_SIZE * CELT_MAX_CHANNELS + STRIDE_ACCESS_PAD;
162const CELT_W_FREQ_DEC: usize = DECODE_BUFFER_SIZE * CELT_MAX_CHANNELS + 4;
164const CELT_DECODE_MEM: usize = CELT_MAX_CHANNELS * (DECODE_BUFFER_SIZE + CELT_OVERLAP);
166
167fn resampling_factor(sampling_rate: i32) -> usize {
171 match sampling_rate {
172 48000 => 1,
173 24000 => 2,
174 16000 => 3,
175 12000 => 4,
176 8000 => 6,
177 _ => 1,
178 }
179}
180
181fn upsample_scale_zero(freq: &mut [f32], frame_size: usize, upsample: usize, channels: usize) {
185 if upsample <= 1 {
186 return;
187 }
188 let bound = frame_size / upsample;
189 for c in 0..channels {
190 let base = c * frame_size;
191 for v in freq[base..base + bound].iter_mut() {
192 *v *= upsample as f32;
193 }
194 freq[base + bound..base + frame_size].fill(0.0);
195 }
196}
197
198#[cfg(target_arch = "aarch64")]
199use core::arch::aarch64::*;
200
201#[cfg(target_arch = "aarch64")]
202#[inline(always)]
203#[allow(unsafe_op_in_unsafe_fn)]
204unsafe fn sum_abs_neon(x: &[f32], n: usize) -> f32 {
205 let mut sum_vec = vdupq_n_f32(0.0);
206 let mut i = 0;
207
208 while i + 16 <= n {
209 let x0 = vld1q_f32(x.as_ptr().add(i));
210 let x1 = vld1q_f32(x.as_ptr().add(i + 4));
211 let x2 = vld1q_f32(x.as_ptr().add(i + 8));
212 let x3 = vld1q_f32(x.as_ptr().add(i + 12));
213
214 sum_vec = vfmaq_f32(sum_vec, vabsq_f32(x0), vdupq_n_f32(1.0));
215 sum_vec = vfmaq_f32(sum_vec, vabsq_f32(x1), vdupq_n_f32(1.0));
216 sum_vec = vfmaq_f32(sum_vec, vabsq_f32(x2), vdupq_n_f32(1.0));
217 sum_vec = vfmaq_f32(sum_vec, vabsq_f32(x3), vdupq_n_f32(1.0));
218
219 i += 16;
220 }
221
222 while i + 8 <= n {
223 let x0 = vld1q_f32(x.as_ptr().add(i));
224 let x1 = vld1q_f32(x.as_ptr().add(i + 4));
225 sum_vec = vfmaq_f32(sum_vec, vabsq_f32(x0), vdupq_n_f32(1.0));
226 sum_vec = vfmaq_f32(sum_vec, vabsq_f32(x1), vdupq_n_f32(1.0));
227 i += 8;
228 }
229
230 while i + 4 <= n {
231 let x0 = vld1q_f32(x.as_ptr().add(i));
232 sum_vec = vfmaq_f32(sum_vec, vabsq_f32(x0), vdupq_n_f32(1.0));
233 i += 4;
234 }
235
236 let mut sum = vaddvq_f32(sum_vec);
237
238 for j in i..n {
239 sum += x[j].abs();
240 }
241
242 sum
243}
244
245#[inline(always)]
246fn sum_abs(x: &[f32]) -> f32 {
247 #[cfg(target_arch = "x86_64")]
248 unsafe {
249 if crate::compat::x86_has_avx() {
250 return sum_abs_avx(x, x.len());
251 }
252 }
253 #[cfg(target_arch = "aarch64")]
254 unsafe {
255 sum_abs_neon(x, x.len())
256 }
257 #[cfg(not(target_arch = "aarch64"))]
258 {
259 x.iter().map(|&v| v.abs()).sum()
260 }
261}
262
263const MAX_FRAME_SIZE: usize = 2880;
264
265const DECODE_BUFFER_SIZE: usize = 2048;
270
271const INV_TABLE: [u8; 128] = [
272 255, 255, 156, 110, 86, 70, 59, 51, 45, 40, 37, 33, 31, 28, 26, 25, 23, 22, 21, 20, 19, 18, 17,
273 16, 16, 15, 15, 14, 13, 13, 12, 12, 12, 12, 11, 11, 11, 10, 10, 10, 9, 9, 9, 9, 9, 9, 8, 8, 8,
274 8, 8, 7, 7, 7, 7, 7, 7, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5,
275 5, 5, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3,
276 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2,
277];
278
279const MAX_TRANSIENT_LEN: usize = 3000;
280
281#[derive(Debug, Clone, Copy)]
282pub struct AnalysisInfo {
283 pub valid: bool,
284 pub tonality: f32,
285 pub tonality_slope: f32,
286 pub noisiness: f32,
287 pub activity: f32,
288 pub music_prob: f32,
289 pub music_prob_min: f32,
290 pub music_prob_max: f32,
291 pub bandwidth: i32,
292 pub activity_probability: f32,
293 pub max_pitch_ratio: f32,
294 pub leak_boost: [u8; 19], }
296
297impl Default for AnalysisInfo {
298 fn default() -> Self {
299 Self {
300 valid: false,
301 tonality: 0.0,
302 tonality_slope: 0.0,
303 noisiness: 0.0,
304 activity: 0.0,
305 music_prob: 0.0,
306 music_prob_min: 0.0,
307 music_prob_max: 0.0,
308 bandwidth: 0,
309 activity_probability: 0.0,
310 max_pitch_ratio: 1.0,
311 leak_boost: [0; 19],
312 }
313 }
314}
315
316#[allow(clippy::too_many_arguments)]
317fn transient_analysis(
318 input: &[f32],
319 len: usize,
320 channels: usize,
321 tf_estimate: &mut f32,
322 tf_chan: &mut usize,
323 allow_weak_transients: bool,
324 weak_transient: &mut bool,
325 _tone_freq: f32,
326 toneishness: f32,
327 tmp: &mut [f32],
328 tmp2: &mut [f32],
329) -> bool {
330 let mut mask_metric = 0.0f32;
331 let mut forward_decay = 0.0625f32;
332
333 *weak_transient = false;
334 if allow_weak_transients {
335 forward_decay = 0.03125f32;
336 }
337
338 let len2 = len / 2;
339 debug_assert!(len <= MAX_TRANSIENT_LEN);
340
341 for c in 0..channels {
342 let mut mem0 = 0.0f32;
343 let mut mem1 = 0.0f32;
344
345 for i in 0..len {
346 let x = input[c * len + i];
347 let y = mem0 + x;
348 let mem00 = mem0;
349 mem0 = mem0 - x + 0.5 * mem1;
350 mem1 = x - mem00;
351 tmp[i] = y;
352 }
353
354 tmp[..12].fill(0.0);
355
356 let mut mean = 0.0f32;
357 mem0 = 0.0f32;
358 for i in 0..len2 {
359 let x2 = (tmp[2 * i] * tmp[2 * i] + tmp[2 * i + 1] * tmp[2 * i + 1]) / 16.0;
360 mean += x2;
362 mem0 = x2 + (1.0 - forward_decay) * mem0;
363 tmp2[i] = forward_decay * mem0;
364 }
365
366 mem0 = 0.0f32;
367 let mut max_e = 0.0f32;
368 for i in (0..len2).rev() {
369 mem0 = tmp2[i] + 0.875 * mem0;
370 tmp2[i] = 0.125 * mem0;
371 if tmp2[i] > max_e {
372 max_e = tmp2[i];
373 }
374 }
375
376 mean = (mean * max_e * 0.5 * (len2 as f32)).sqrt();
377 let norm = (len2 as f32) / (1e-15 + mean);
379
380 let mut unmask: i32 = 0;
383 for i in (12..(len2 - 5)).step_by(4) {
384 let id = (64.0 * norm * (tmp2[i] + 1e-15)).floor() as i32;
385 let id = id.clamp(0, 127) as usize;
386 unmask += INV_TABLE[id] as i32;
387 }
388
389 unmask = 64 * unmask * 4 / (6 * (len2 as i32 - 17));
390 if (unmask as f32) > mask_metric {
391 *tf_chan = c;
392 mask_metric = unmask as f32;
393 }
394 }
395
396 let mut is_transient = mask_metric > 200.0;
397
398 if toneishness > 0.98 && _tone_freq < 0.026 {
399 is_transient = false;
400 mask_metric = 0.0;
401 }
402
403 let tf_max = ((27.0 * mask_metric).sqrt() - 42.0).max(0.0);
406 *tf_estimate = (0.0069 * tf_max.min(163.0) - 0.139).max(0.0).sqrt();
407
408 is_transient
409}
410
411fn l1_metric(tmp: &[f32], n: usize, lm: i32, bias: f32) -> f32 {
412 #[cfg(target_arch = "x86_64")]
413 unsafe {
414 if n >= 16 && crate::compat::x86_has_avx() {
415 return l1_metric_avx(tmp, n, lm, bias);
416 }
417 }
418 #[cfg(target_arch = "aarch64")]
419 {
420 if n >= 16 {
421 return unsafe { l1_metric_neon(tmp, n, lm, bias) };
422 }
423 }
424
425 let mut l1 = 0.0f32;
426 for &tv in tmp[..n].iter() {
427 l1 += tv.abs();
428 }
429 l1 + (lm as f32) * bias * l1
430}
431
432#[cfg(target_arch = "x86_64")]
433#[target_feature(enable = "avx")]
434unsafe fn sum_abs_avx(x: &[f32], n: usize) -> f32 {
435 #[cfg(target_arch = "x86")]
436 use core::arch::x86::*;
437 #[cfg(target_arch = "x86_64")]
438 use core::arch::x86_64::*;
439
440 let mut sum0 = _mm256_setzero_ps();
441 let mut sum1 = _mm256_setzero_ps();
442 let mut i = 0usize;
443 let sign_mask = _mm256_set1_ps(-0.0);
444
445 while i + 16 <= n {
446 let v0 = _mm256_loadu_ps(x.as_ptr().add(i));
447 let v1 = _mm256_loadu_ps(x.as_ptr().add(i + 8));
448 sum0 = _mm256_add_ps(sum0, _mm256_andnot_ps(sign_mask, v0));
449 sum1 = _mm256_add_ps(sum1, _mm256_andnot_ps(sign_mask, v1));
450 i += 16;
451 }
452
453 while i + 8 <= n {
454 let v = _mm256_loadu_ps(x.as_ptr().add(i));
455 sum0 = _mm256_add_ps(sum0, _mm256_andnot_ps(sign_mask, v));
456 i += 8;
457 }
458
459 let sum = _mm256_add_ps(sum0, sum1);
460 let hi = _mm256_extractf128_ps(sum, 1);
461 let lo = _mm256_castps256_ps128(sum);
462 let s4 = _mm_add_ps(lo, hi);
463 let t1 = _mm_movehl_ps(s4, s4);
464 let s2 = _mm_add_ps(s4, t1);
465 let t2 = _mm_shuffle_ps(s2, s2, 0x55);
466 let mut out = _mm_cvtss_f32(_mm_add_ss(s2, t2));
467
468 for j in i..n {
469 out += x[j].abs();
470 }
471
472 out
473}
474
475#[cfg(target_arch = "x86_64")]
476#[target_feature(enable = "avx")]
477unsafe fn l1_metric_avx(tmp: &[f32], n: usize, lm: i32, bias: f32) -> f32 {
478 let l1 = sum_abs_avx(tmp, n);
479 l1 + (lm as f32) * bias * l1
480}
481
482#[cfg(target_arch = "aarch64")]
483#[target_feature(enable = "neon")]
484unsafe fn l1_metric_neon(tmp: &[f32], n: usize, lm: i32, bias: f32) -> f32 {
485 unsafe {
486 let mut sum4 = vdupq_n_f32(0.0);
487 let mut i = 0;
488
489 while i + 15 < n {
490 let v0 = vld1q_f32(tmp.as_ptr().add(i));
491 let v1 = vld1q_f32(tmp.as_ptr().add(i + 4));
492 let v2 = vld1q_f32(tmp.as_ptr().add(i + 8));
493 let v3 = vld1q_f32(tmp.as_ptr().add(i + 12));
494
495 sum4 = vaddq_f32(sum4, vabsq_f32(v0));
496 sum4 = vaddq_f32(sum4, vabsq_f32(v1));
497 sum4 = vaddq_f32(sum4, vabsq_f32(v2));
498 sum4 = vaddq_f32(sum4, vabsq_f32(v3));
499
500 i += 16;
501 }
502
503 while i + 3 < n {
504 let v = vld1q_f32(tmp.as_ptr().add(i));
505 sum4 = vaddq_f32(sum4, vabsq_f32(v));
506 i += 4;
507 }
508
509 let sum2 = vpaddq_f32(sum4, sum4);
510 let sum1 = vpaddq_f32(sum2, sum2);
511 let mut l1 = vgetq_lane_f32(sum1, 0);
512
513 while i < n {
514 l1 += tmp[i].abs();
515 i += 1;
516 }
517
518 l1 + (lm as f32) * bias * l1
519 }
520}
521
522const MAX_NB_EBANDS: usize = 21;
523
524const MAX_TF_TMP: usize = 176;
525
526#[allow(clippy::too_many_arguments)]
527fn tf_analysis(
528 mode: &CeltMode,
529 len: usize,
530 is_transient: bool,
531 tf_res: &mut [i32],
532 lambda: i32,
533 x: &[f32],
534 n0: usize,
535 lm: i32,
536 tf_estimate: f32,
537 tf_chan: usize,
538 importance: &[i32],
539) -> i32 {
540 debug_assert!(len <= MAX_NB_EBANDS);
541 let mut metric = [0i32; MAX_NB_EBANDS];
542 let mut tmp = [0.0f32; MAX_TF_TMP];
543 let mut tmp_1 = [0.0f32; MAX_TF_TMP];
544
545 let bias = 0.04 * (-0.25f32).max(0.5 - tf_estimate);
546
547 for (i, metric_i) in metric[..len].iter_mut().enumerate() {
548 let n = ((mode.e_bands[i + 1] - mode.e_bands[i]) as usize) << lm;
549 let narrow = (mode.e_bands[i + 1] - mode.e_bands[i]) == 1;
550 let offset = tf_chan * n0 + ((mode.e_bands[i] as usize) << lm);
551 tmp[..n].copy_from_slice(&x[offset..offset + n]);
552
553 let mut l1 = l1_metric(&tmp[..n], n, if is_transient { lm } else { 0 }, bias);
554 let mut best_l1 = l1;
555 let mut best_level = 0;
556
557 if is_transient && !narrow {
558 tmp_1[..n].copy_from_slice(&tmp[..n]);
559 haar1(&mut tmp_1[..n], n >> lm, 1 << lm);
560 l1 = l1_metric(&tmp_1[..n], n, lm + 1, bias);
561 if l1 < best_l1 {
562 best_l1 = l1;
563 best_level = -1;
564 }
565 }
566
567 for k in 0..(lm + if is_transient || narrow { 0 } else { 1 }) {
568 let b = if is_transient { lm - k - 1 } else { k + 1 };
569
570 haar1(&mut tmp[..n], n >> k, 1 << k);
571 l1 = l1_metric(&tmp[..n], n, b, bias);
572
573 if l1 < best_l1 {
574 best_l1 = l1;
575 best_level = k + 1;
576 }
577 }
578
579 if is_transient {
580 *metric_i = 2 * best_level;
581 } else {
582 *metric_i = -2 * best_level;
583 }
584
585 if narrow && (*metric_i == 0 || *metric_i == -2 * lm) {
586 *metric_i -= 1;
587 }
588 }
589
590 let mut tf_select = 0;
591 let mut selcost = [0i32; 2];
592
593 for sel in 0..2 {
594 let mut cost0 = importance[0]
595 * (metric[0]
596 - 2 * TF_SELECT_TABLE[lm as usize][4 * (is_transient as usize) + 2 * sel] as i32)
597 .abs();
598 let mut cost1 = importance[0]
599 * (metric[0]
600 - 2 * TF_SELECT_TABLE[lm as usize][4 * (is_transient as usize) + 2 * sel + 1]
601 as i32)
602 .abs()
603 + if is_transient { 0 } else { lambda };
604
605 for i in 1..len {
606 let curr0 = cost0.min(cost1 + lambda);
607 let curr1 = (cost0 + lambda).min(cost1);
608 cost0 = curr0
609 + importance[i]
610 * (metric[i]
611 - 2 * TF_SELECT_TABLE[lm as usize][4 * (is_transient as usize) + 2 * sel]
612 as i32)
613 .abs();
614 cost1 = curr1
615 + importance[i]
616 * (metric[i]
617 - 2 * TF_SELECT_TABLE[lm as usize]
618 [4 * (is_transient as usize) + 2 * sel + 1]
619 as i32)
620 .abs();
621 }
622 selcost[sel] = cost0.min(cost1);
623 }
624
625 if selcost[1] < selcost[0] && is_transient {
627 tf_select = 1;
628 }
629
630 let sel = tf_select as usize;
633 let mut cost0 = importance[0]
634 * (metric[0]
635 - 2 * TF_SELECT_TABLE[lm as usize][4 * (is_transient as usize) + 2 * sel] as i32)
636 .abs();
637 let mut cost1 = importance[0]
638 * (metric[0]
639 - 2 * TF_SELECT_TABLE[lm as usize][4 * (is_transient as usize) + 2 * sel + 1] as i32)
640 .abs()
641 + if is_transient { 0 } else { lambda };
642
643 let mut path0 = [0i32; MAX_NB_EBANDS];
644 let mut path1 = [0i32; MAX_NB_EBANDS];
645 for i in 1..len {
646 let from0 = cost0;
647 let from1 = cost1 + lambda;
648 let curr0 = if from0 < from1 {
649 path0[i] = 0;
650 from0
651 } else {
652 path0[i] = 1;
653 from1
654 };
655
656 let from0 = cost0 + lambda;
657 let from1 = cost1;
658 let curr1 = if from0 < from1 {
659 path1[i] = 0;
660 from0
661 } else {
662 path1[i] = 1;
663 from1
664 };
665
666 cost0 = curr0
667 + importance[i]
668 * (metric[i]
669 - 2 * TF_SELECT_TABLE[lm as usize][4 * (is_transient as usize) + 2 * sel]
670 as i32)
671 .abs();
672 cost1 = curr1
673 + importance[i]
674 * (metric[i]
675 - 2 * TF_SELECT_TABLE[lm as usize][4 * (is_transient as usize) + 2 * sel + 1]
676 as i32)
677 .abs();
678 }
679 tf_res[len - 1] = if cost0 < cost1 { 0 } else { 1 };
680 for i in (0..len - 1).rev() {
681 tf_res[i] = if tf_res[i + 1] == 1 {
682 path1[i + 1]
683 } else {
684 path0[i + 1]
685 };
686 }
687
688 tf_select
689}
690
691fn tf_encode(
692 start: usize,
693 end: usize,
694 is_transient: bool,
695 tf_res: &mut [i32],
696 lm: i32,
697 mut tf_select: i32,
698 rc: &mut RangeCoder,
699) -> i32 {
700 let mut curr = 0;
701 let mut tf_changed = 0;
702 let mut logp = if is_transient { 2 } else { 4 };
703 let mut budget = rc.storage as i32 * 8;
704 let mut tell = rc.tell();
705
706 let tf_select_rsv = if lm > 0 && tell + logp < budget { 1 } else { 0 };
707 budget -= tf_select_rsv;
708
709 for tf_res_i in tf_res[start..end].iter_mut() {
710 if tell + logp <= budget {
711 rc.encode_bit_logp(*tf_res_i ^ curr != 0, logp as u32);
712 tell = rc.tell();
713 curr = *tf_res_i;
714 tf_changed |= curr;
715 } else {
716 *tf_res_i = curr;
717 }
718 logp = if is_transient { 4 } else { 5 };
719 }
720
721 if tf_select_rsv != 0
722 && TF_SELECT_TABLE[lm as usize][4 * (is_transient as usize) + (tf_changed as usize)]
723 != TF_SELECT_TABLE[lm as usize][4 * (is_transient as usize) + 2 + (tf_changed as usize)]
724 {
725 rc.encode_bit_logp(tf_select != 0, 1);
726 } else {
727 tf_select = 0;
728 }
729
730 for tf_res_i in tf_res[start..end].iter_mut() {
731 *tf_res_i = TF_SELECT_TABLE[lm as usize]
732 [4 * (is_transient as usize) + 2 * (tf_select as usize) + (*tf_res_i as usize)]
733 as i32;
734 }
735
736 tf_changed
737}
738
739fn tf_decode(
740 start: usize,
741 end: usize,
742 is_transient: bool,
743 tf_res: &mut [i32],
744 lm: i32,
745 rc: &mut RangeCoder,
746) {
747 let mut curr = 0;
748 let mut tf_changed = 0;
749 let mut logp = if is_transient { 2 } else { 4 };
750 let budget = rc.storage as i32 * 8;
751 let mut tell = rc.tell();
752
753 let tf_select_rsv = if lm > 0 && tell + logp < budget { 1 } else { 0 };
754 let budget = budget - tf_select_rsv;
755
756 for tf_res_i in tf_res[start..end].iter_mut() {
757 if tell + logp <= budget {
758 curr ^= if rc.decode_bit_logp(logp as u32) {
759 1
760 } else {
761 0
762 };
763 tell = rc.tell();
764 tf_changed |= curr;
765 }
766 *tf_res_i = curr;
767 logp = if is_transient { 4 } else { 5 };
768 }
769
770 let mut tf_select = 0;
771 let _budget = budget + tf_select_rsv;
772 if tf_select_rsv > 0
773 && TF_SELECT_TABLE[lm as usize][4 * (is_transient as usize) + (tf_changed as usize)]
774 != TF_SELECT_TABLE[lm as usize][4 * (is_transient as usize) + 2 + (tf_changed as usize)]
775 {
776 tf_select = if rc.decode_bit_logp(1) { 1 } else { 0 };
777 }
778
779 for tf_res_i in tf_res[start..end].iter_mut() {
780 *tf_res_i = TF_SELECT_TABLE[lm as usize]
781 [4 * (is_transient as usize) + 2 * (tf_select as usize) + (*tf_res_i as usize)]
782 as i32;
783 }
784}
785
786fn stereo_analysis(m: &CeltMode, x: &[f32], lm: i32, n0: usize) -> bool {
787 let mut sum_lr = 1e-9f32;
788 let mut sum_ms = 1e-9f32;
789
790 for i in 0..13 {
791 let start = (m.e_bands[i] as usize) << lm;
792 let end = (m.e_bands[i + 1] as usize) << lm;
793 for j in start..end {
794 let l = x[j];
795 let r = x[n0 + j];
796 let m_val = l + r;
797 let s_val = l - r;
798 sum_lr += l.abs() + r.abs();
799 sum_ms += m_val.abs() + s_val.abs();
800 }
801 }
802
803 sum_ms *= core::f32::consts::FRAC_1_SQRT_2;
804 let mut thetas = 13;
805 if lm <= 1 {
806 thetas -= 8;
807 }
808
809 let left = (((m.e_bands[13] as usize) << (lm + 1)) + thetas) as f32 * sum_ms;
810 let right = ((m.e_bands[13] as usize) << (lm + 1)) as f32 * sum_lr;
811
812 left > right
813}
814
815const COMBFILTER_MINPERIOD: usize = 15;
816const COMBFILTER_MAXPERIOD: usize = 1024;
817
818const PREFILTER_GAINS: [[f32; 3]; 3] = [
819 [0.306_640_6, 0.217_041, 0.129_638_7],
820 [0.463_867_2, 0.268_066_4, 0.0],
821 [0.799_804_7, 0.100_097_7, 0.0],
822];
823
824#[allow(clippy::too_many_arguments)]
825fn comb_filter_const(
826 y: &mut [f32],
827 x: &[f32],
828 y_idx: usize,
829 x_idx: usize,
830 t: usize,
831 n: usize,
832 g10: f32,
833 g11: f32,
834 g12: f32,
835) {
836 #[cfg(target_arch = "aarch64")]
837 {
838 comb_filter_const_neon(y, x, y_idx, x_idx, t, n, g10, g11, g12);
839 }
840 #[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
841 unsafe {
842 if crate::compat::x86_has_avx_fma() {
843 comb_filter_const_avx(y, x, y_idx, x_idx, t, n, g10, g11, g12);
844 return;
845 }
846 }
847 #[cfg(all(target_arch = "x86_64", target_feature = "sse"))]
848 unsafe {
849 comb_filter_const_sse(y, x, y_idx, x_idx, t, n, g10, g11, g12);
850 #[allow(clippy::needless_return)]
851 return;
852 }
853 #[cfg(not(any(
854 target_arch = "aarch64",
855 all(target_arch = "x86_64", target_feature = "sse")
856 )))]
857 {
858 comb_filter_const_scalar(y, x, y_idx, x_idx, t, n, g10, g11, g12);
859 }
860}
861
862#[inline]
863#[allow(dead_code)]
864fn comb_filter_const_scalar(
865 y: &mut [f32],
866 x: &[f32],
867 y_idx: usize,
868 x_idx: usize,
869 t: usize,
870 n: usize,
871 g10: f32,
872 g11: f32,
873 g12: f32,
874) {
875 let mut x1;
876 let mut x2;
877 let mut x3;
878 let mut x4;
879 let mut x0;
880
881 x4 = x[x_idx - t - 2];
882 x3 = x[x_idx - t - 1];
883 x2 = x[x_idx - t];
884 x1 = x[x_idx - t + 1];
885
886 for i in 0..n {
887 x0 = x[x_idx + i - t + 2];
888 y[y_idx + i] = x[x_idx + i] + g10 * x2 + g11 * (x1 + x3) + g12 * (x0 + x4);
889 x4 = x3;
890 x3 = x2;
891 x2 = x1;
892 x1 = x0;
893 }
894}
895
896#[cfg(target_arch = "aarch64")]
897fn comb_filter_const_neon(
898 y: &mut [f32],
899 x: &[f32],
900 y_idx: usize,
901 x_idx: usize,
902 t: usize,
903 n: usize,
904 g10: f32,
905 g11: f32,
906 g12: f32,
907) {
908 unsafe { comb_filter_const_neon_impl(y, x, y_idx, x_idx, t, n, g10, g11, g12) }
909}
910
911#[cfg(target_arch = "aarch64")]
912#[inline(always)]
913#[allow(unsafe_op_in_unsafe_fn)]
914unsafe fn comb_filter_const_neon_impl(
915 y: &mut [f32],
916 x: &[f32],
917 y_idx: usize,
918 x_idx: usize,
919 t: usize,
920 n: usize,
921 g10: f32,
922 g11: f32,
923 g12: f32,
924) {
925 use core::arch::aarch64::*;
926
927 let g10v = vdupq_n_f32(g10);
928 let g11v = vdupq_n_f32(g11);
929 let g12v = vdupq_n_f32(g12);
930
931 let xbase = x.as_ptr().add(x_idx);
932 let ybase = y.as_mut_ptr().add(y_idx);
933
934 let mut x0v = vld1q_f32(xbase.sub(t + 2));
935
936 let mut i = 0;
937 while i + 4 <= n {
938 let x4v = vld1q_f32(xbase.add(i).sub(t - 2));
939
940 let x2v = vextq_f32(x0v, x4v, 2);
941
942 let x1v = vextq_f32(x0v, x4v, 1);
943
944 let x3v = vextq_f32(x0v, x4v, 3);
945
946 let xi = vld1q_f32(xbase.add(i));
947
948 let mut yi = xi;
949 yi = vfmaq_f32(yi, g10v, x2v);
950 yi = vfmaq_f32(yi, g11v, vaddq_f32(x1v, x3v));
951 yi = vfmaq_f32(yi, g12v, vaddq_f32(x4v, x0v));
952 vst1q_f32(ybase.add(i), yi);
953
954 x0v = x4v;
955 i += 4;
956 }
957
958 let x0v_arr: [f32; 4] = core::mem::transmute(x0v);
959 let mut sx4 = x0v_arr[0];
960 let mut sx3 = x0v_arr[1];
961 let mut sx2 = x0v_arr[2];
962 let mut sx1 = x0v_arr[3];
963
964 while i < n {
965 let sx0 = x[x_idx + i - t + 2];
966 y[y_idx + i] = x[x_idx + i] + g10 * sx2 + g11 * (sx1 + sx3) + g12 * (sx0 + sx4);
967 sx4 = sx3;
968 sx3 = sx2;
969 sx2 = sx1;
970 sx1 = sx0;
971 i += 1;
972 }
973}
974
975#[cfg(all(target_arch = "x86_64", target_feature = "sse"))]
976#[inline(always)]
977#[allow(unsafe_op_in_unsafe_fn)]
978unsafe fn comb_filter_const_sse(
979 y: &mut [f32],
980 x: &[f32],
981 y_idx: usize,
982 x_idx: usize,
983 t: usize,
984 n: usize,
985 g10: f32,
986 g11: f32,
987 g12: f32,
988) {
989 #[cfg(target_arch = "x86")]
990 use core::arch::x86::*;
991 #[cfg(target_arch = "x86_64")]
992 use core::arch::x86_64::*;
993
994 let g10v = _mm_set1_ps(g10);
995 let g11v = _mm_set1_ps(g11);
996 let g12v = _mm_set1_ps(g12);
997
998 let xbase = x.as_ptr().add(x_idx);
999 let ybase = y.as_mut_ptr().add(y_idx);
1000 let mut x0v = _mm_loadu_ps(xbase.sub(t + 2));
1001
1002 let mut i = 0;
1003 while i + 4 <= n {
1004 let x4v = _mm_loadu_ps(xbase.add(i).sub(t - 2));
1005
1006 let x2v = _mm_shuffle_ps(x0v, x4v, 0x4e);
1007
1008 let x1v = _mm_shuffle_ps(x0v, x2v, 0x99);
1009
1010 let x3v = _mm_shuffle_ps(x2v, x4v, 0x99);
1011
1012 let xi = _mm_loadu_ps(xbase.add(i));
1013
1014 let mut yi = xi;
1015 yi = _mm_add_ps(yi, _mm_mul_ps(g10v, x2v));
1016 let yi2 = _mm_add_ps(
1017 _mm_mul_ps(g11v, _mm_add_ps(x3v, x1v)),
1018 _mm_mul_ps(g12v, _mm_add_ps(x4v, x0v)),
1019 );
1020 yi = _mm_add_ps(yi, yi2);
1021 _mm_storeu_ps(ybase.add(i), yi);
1022
1023 x0v = x4v;
1024 i += 4;
1025 }
1026
1027 let x0v_arr: [f32; 4] = core::mem::transmute(x0v);
1028 let mut sx4 = x0v_arr[0];
1029 let mut sx3 = x0v_arr[1];
1030 let mut sx2 = x0v_arr[2];
1031 let mut sx1 = x0v_arr[3];
1032
1033 while i < n {
1034 let sx0 = x[x_idx + i - t + 2];
1035 y[y_idx + i] = x[x_idx + i] + g10 * sx2 + g11 * (sx1 + sx3) + g12 * (sx0 + sx4);
1036 sx4 = sx3;
1037 sx3 = sx2;
1038 sx2 = sx1;
1039 sx1 = sx0;
1040 i += 1;
1041 }
1042}
1043
1044#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
1045#[target_feature(enable = "avx,fma")]
1046#[allow(unsafe_op_in_unsafe_fn)]
1047unsafe fn comb_filter_const_avx(
1048 y: &mut [f32],
1049 x: &[f32],
1050 y_idx: usize,
1051 x_idx: usize,
1052 t: usize,
1053 n: usize,
1054 g10: f32,
1055 g11: f32,
1056 g12: f32,
1057) {
1058 #[cfg(target_arch = "x86")]
1059 use core::arch::x86::*;
1060 #[cfg(target_arch = "x86_64")]
1061 use core::arch::x86_64::*;
1062
1063 let g10v = _mm256_set1_ps(g10);
1064 let g11v = _mm256_set1_ps(g11);
1065 let g12v = _mm256_set1_ps(g12);
1066
1067 let xbase = x.as_ptr().add(x_idx);
1068 let ybase = y.as_mut_ptr().add(y_idx);
1069
1070 let mut i = 0;
1071
1072 while i + 16 <= n {
1073 let xi_a = _mm256_loadu_ps(xbase.add(i));
1074 let x0_a = _mm256_loadu_ps(xbase.add(i).sub(t + 2));
1075 let x4_a = _mm256_loadu_ps(xbase.add(i).sub(t - 2));
1076
1077 let x2_a = _mm256_loadu_ps(xbase.add(i).sub(t));
1078 let x1x3_a = _mm256_add_ps(
1079 _mm256_loadu_ps(xbase.add(i).sub(t + 1)),
1080 _mm256_loadu_ps(xbase.add(i).sub(t - 1)),
1081 );
1082 let x0x4_a = _mm256_add_ps(x0_a, x4_a);
1083
1084 let mut yi_a = xi_a;
1085 yi_a = _mm256_fmadd_ps(g10v, x2_a, yi_a);
1086 yi_a = _mm256_fmadd_ps(g11v, x1x3_a, yi_a);
1087 yi_a = _mm256_fmadd_ps(g12v, x0x4_a, yi_a);
1088 _mm256_storeu_ps(ybase.add(i), yi_a);
1089
1090 let j = i + 8;
1091 let xi_b = _mm256_loadu_ps(xbase.add(j));
1092 let x0_b = _mm256_loadu_ps(xbase.add(j).sub(t + 2));
1093 let x4_b = _mm256_loadu_ps(xbase.add(j).sub(t - 2));
1094 let x2_b = _mm256_loadu_ps(xbase.add(j).sub(t));
1095 let x1x3_b = _mm256_add_ps(
1096 _mm256_loadu_ps(xbase.add(j).sub(t + 1)),
1097 _mm256_loadu_ps(xbase.add(j).sub(t - 1)),
1098 );
1099 let x0x4_b = _mm256_add_ps(x0_b, x4_b);
1100
1101 let mut yi_b = xi_b;
1102 yi_b = _mm256_fmadd_ps(g10v, x2_b, yi_b);
1103 yi_b = _mm256_fmadd_ps(g11v, x1x3_b, yi_b);
1104 yi_b = _mm256_fmadd_ps(g12v, x0x4_b, yi_b);
1105 _mm256_storeu_ps(ybase.add(j), yi_b);
1106
1107 i += 16;
1108 }
1109
1110 while i + 8 <= n {
1111 let xi = _mm256_loadu_ps(xbase.add(i));
1112 let x0 = _mm256_loadu_ps(xbase.add(i).sub(t + 2));
1113 let x4 = _mm256_loadu_ps(xbase.add(i).sub(t - 2));
1114 let x2 = _mm256_loadu_ps(xbase.add(i).sub(t));
1115 let x1x3 = _mm256_add_ps(
1116 _mm256_loadu_ps(xbase.add(i).sub(t + 1)),
1117 _mm256_loadu_ps(xbase.add(i).sub(t - 1)),
1118 );
1119 let x0x4 = _mm256_add_ps(x0, x4);
1120
1121 let mut yi = xi;
1122 yi = _mm256_fmadd_ps(g10v, x2, yi);
1123 yi = _mm256_fmadd_ps(g11v, x1x3, yi);
1124 yi = _mm256_fmadd_ps(g12v, x0x4, yi);
1125 _mm256_storeu_ps(ybase.add(i), yi);
1126
1127 i += 8;
1128 }
1129
1130 if i + 4 <= n {
1131 comb_filter_const_sse_fma(y, x, y_idx + i, x_idx + i, t, n - i, g10, g11, g12);
1132 return;
1133 }
1134
1135 let mut sx4 = x[x_idx + i - t - 2];
1136 let mut sx3 = x[x_idx + i - t - 1];
1137 let mut sx2 = x[x_idx + i - t];
1138 let mut sx1 = x[x_idx + i - t + 1];
1139 while i < n {
1140 let sx0 = x[x_idx + i - t + 2];
1141 y[y_idx + i] = x[x_idx + i] + g10 * sx2 + g11 * (sx1 + sx3) + g12 * (sx0 + sx4);
1142 sx4 = sx3;
1143 sx3 = sx2;
1144 sx2 = sx1;
1145 sx1 = sx0;
1146 i += 1;
1147 }
1148}
1149
1150#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
1151#[target_feature(enable = "avx,fma")]
1152#[allow(unsafe_op_in_unsafe_fn)]
1153unsafe fn comb_filter_const_sse_fma(
1154 y: &mut [f32],
1155 x: &[f32],
1156 y_idx: usize,
1157 x_idx: usize,
1158 t: usize,
1159 n: usize,
1160 g10: f32,
1161 g11: f32,
1162 g12: f32,
1163) {
1164 #[cfg(target_arch = "x86")]
1165 use core::arch::x86::*;
1166 #[cfg(target_arch = "x86_64")]
1167 use core::arch::x86_64::*;
1168
1169 let g10v = _mm_set1_ps(g10);
1170 let g11v = _mm_set1_ps(g11);
1171 let g12v = _mm_set1_ps(g12);
1172
1173 let xbase = x.as_ptr().add(x_idx);
1174 let ybase = y.as_mut_ptr().add(y_idx);
1175 let mut x0v = _mm_loadu_ps(xbase.sub(t + 2));
1176
1177 let mut i = 0;
1178 while i + 4 <= n {
1179 let x4v = _mm_loadu_ps(xbase.add(i).sub(t - 2));
1180 let x2v = _mm_shuffle_ps(x0v, x4v, 0x4e);
1181 let x1v = _mm_shuffle_ps(x0v, x2v, 0x99);
1182 let x3v = _mm_shuffle_ps(x2v, x4v, 0x99);
1183 let xi = _mm_loadu_ps(xbase.add(i));
1184
1185 let mut yi = xi;
1186 yi = _mm_fmadd_ps(g10v, x2v, yi);
1187 yi = _mm_fmadd_ps(g11v, _mm_add_ps(x1v, x3v), yi);
1188 yi = _mm_fmadd_ps(g12v, _mm_add_ps(x0v, x4v), yi);
1189 _mm_storeu_ps(ybase.add(i), yi);
1190
1191 x0v = x4v;
1192 i += 4;
1193 }
1194
1195 let x0v_arr: [f32; 4] = core::mem::transmute(x0v);
1196 let mut sx4 = x0v_arr[0];
1197 let mut sx3 = x0v_arr[1];
1198 let mut sx2 = x0v_arr[2];
1199 let mut sx1 = x0v_arr[3];
1200 while i < n {
1201 let sx0 = x[x_idx + i - t + 2];
1202 y[y_idx + i] = x[x_idx + i] + g10 * sx2 + g11 * (sx1 + sx3) + g12 * (sx0 + sx4);
1203 sx4 = sx3;
1204 sx3 = sx2;
1205 sx2 = sx1;
1206 sx1 = sx0;
1207 i += 1;
1208 }
1209}
1210
1211#[allow(clippy::too_many_arguments)]
1212fn comb_filter(
1213 y: &mut [f32],
1214 x: &[f32],
1215 y_idx: usize,
1216 x_idx: usize,
1217 t0: usize,
1218 t1: usize,
1219 n: usize,
1220 g0: f32,
1221 g1: f32,
1222 tapset0: i32,
1223 tapset1: i32,
1224 window: &[f32],
1225 overlap: usize,
1226) {
1227 if g0 == 0.0 && g1 == 0.0 {
1228 if x_idx != y_idx || !core::ptr::eq(x.as_ptr(), y.as_ptr()) {
1229 y[y_idx..y_idx + n].copy_from_slice(&x[x_idx..x_idx + n]);
1230 }
1231 return;
1232 }
1233
1234 let t0 = t0.clamp(
1235 COMBFILTER_MINPERIOD,
1236 x_idx.saturating_sub(2).max(COMBFILTER_MINPERIOD),
1237 );
1238 let t1 = t1.clamp(
1239 COMBFILTER_MINPERIOD,
1240 x_idx.saturating_sub(2).max(COMBFILTER_MINPERIOD),
1241 );
1242
1243 let g00 = g0 * PREFILTER_GAINS[tapset0 as usize][0];
1244 let g01 = g0 * PREFILTER_GAINS[tapset0 as usize][1];
1245 let g02 = g0 * PREFILTER_GAINS[tapset0 as usize][2];
1246
1247 let g10 = g1 * PREFILTER_GAINS[tapset1 as usize][0];
1248 let g11 = g1 * PREFILTER_GAINS[tapset1 as usize][1];
1249 let g12 = g1 * PREFILTER_GAINS[tapset1 as usize][2];
1250
1251 let mut x1 = x[x_idx - t1 + 1];
1252 let mut x2 = x[x_idx - t1];
1253 let mut x3 = x[x_idx - t1 - 1];
1254 let mut x4 = x[x_idx - t1 - 2];
1255
1256 let mut inner_overlap = overlap;
1257 if g0 == g1 && t0 == t1 && tapset0 == tapset1 {
1258 inner_overlap = 0;
1259 }
1260
1261 let mut i = 0;
1262 while i < inner_overlap && i < n {
1263 let x0 = x[x_idx + i - t1 + 2];
1264 let f = window[i] * window[i];
1265 y[y_idx + i] = x[x_idx + i]
1266 + (1.0 - f)
1267 * (g00 * x[x_idx + i - t0]
1268 + g01 * (x[x_idx + i - t0 + 1] + x[x_idx + i - t0 - 1])
1269 + g02 * (x[x_idx + i - t0 + 2] + x[x_idx + i - t0 - 2]))
1270 + f * (g10 * x2 + g11 * (x1 + x3) + g12 * (x0 + x4));
1271
1272 x4 = x3;
1273 x3 = x2;
1274 x2 = x1;
1275 x1 = x0;
1276 i += 1;
1277 }
1278
1279 if i < n {
1280 if g1 == 0.0 {
1281 y[y_idx + i..y_idx + n].copy_from_slice(&x[x_idx + i..x_idx + n]);
1282 } else {
1283 comb_filter_const(y, x, y_idx + i, x_idx + i, t1, n - i, g10, g11, g12);
1284 }
1285 }
1286}
1287
1288fn comb_filter_inplace(
1292 buf: &mut [f32],
1293 y_idx: usize,
1294 t0: usize,
1295 t1: usize,
1296 n: usize,
1297 g0: f32,
1298 g1: f32,
1299 tapset0: i32,
1300 tapset1: i32,
1301 window: &[f32],
1302 overlap: usize,
1303) {
1304 if g0 == 0.0 && g1 == 0.0 {
1305 return;
1307 }
1308
1309 let t0 = t0.clamp(COMBFILTER_MINPERIOD, y_idx - 2);
1310 let t1 = t1.clamp(COMBFILTER_MINPERIOD, y_idx - 2);
1311
1312 let g00 = g0 * PREFILTER_GAINS[tapset0 as usize][0];
1313 let g01 = g0 * PREFILTER_GAINS[tapset0 as usize][1];
1314 let g02 = g0 * PREFILTER_GAINS[tapset0 as usize][2];
1315
1316 let g10 = g1 * PREFILTER_GAINS[tapset1 as usize][0];
1317 let g11 = g1 * PREFILTER_GAINS[tapset1 as usize][1];
1318 let g12 = g1 * PREFILTER_GAINS[tapset1 as usize][2];
1319
1320 let mut inner_overlap = overlap;
1321 if g0 == g1 && t0 == t1 && tapset0 == tapset1 {
1322 inner_overlap = 0;
1323 }
1324
1325 let mut i = 0;
1326 while i < inner_overlap && i < n {
1327 let idx = y_idx + i;
1328 let f = window[i] * window[i];
1329 let s = buf[idx]; let r0 = buf[idx - t0];
1331 let r0p1 = buf[idx - t0 + 1];
1332 let r0m1 = buf[idx - t0 - 1];
1333 let r0p2 = buf[idx - t0 + 2];
1334 let r0m2 = buf[idx - t0 - 2];
1335 let r1 = buf[idx - t1];
1336 let r1p1 = buf[idx - t1 + 1];
1337 let r1m1 = buf[idx - t1 - 1];
1338 let r1p2 = buf[idx - t1 + 2];
1339 let r1m2 = buf[idx - t1 - 2];
1340 buf[idx] = s
1341 + (1.0 - f) * (g00 * r0 + g01 * (r0p1 + r0m1) + g02 * (r0p2 + r0m2))
1342 + f * (g10 * r1 + g11 * (r1p1 + r1m1) + g12 * (r1p2 + r1m2));
1343 i += 1;
1344 }
1345
1346 while i < n {
1348 let idx = y_idx + i;
1349 let s = buf[idx];
1350 let r1 = buf[idx - t1];
1351 let r1p1 = buf[idx - t1 + 1];
1352 let r1m1 = buf[idx - t1 - 1];
1353 let r1p2 = buf[idx - t1 + 2];
1354 let r1m2 = buf[idx - t1 - 2];
1355 buf[idx] = s + g10 * r1 + g11 * (r1p1 + r1m1) + g12 * (r1p2 + r1m2);
1356 i += 1;
1357 }
1358}
1359
1360#[allow(clippy::approx_constant)]
1362fn run_prefilter(
1363 in_buf: &mut [f32],
1364 prefilter_mem: &mut [f32],
1365 prefilter_period: usize,
1366 prefilter_gain: f32,
1367 prefilter_tapset: i32,
1368 tapset_decision: i32,
1369 window: &[f32],
1370 channels: usize,
1371 frame_size: usize,
1372 overlap: usize,
1373
1374 pre: &mut [f32],
1375 pitch_buf: &mut [f32],
1376 before: &mut [f32],
1377 after: &mut [f32],
1378
1379 analysis: &AnalysisInfo,
1380 loss_rate: i32,
1381 tf_estimate: f32,
1382 nb_available_bytes: usize,
1383 tone_freq: f32,
1384 toneishness: f32,
1385 complexity: i32,
1386) -> (bool, f32, usize) {
1387 let max_period = COMBFILTER_MAXPERIOD;
1388 let min_period = COMBFILTER_MINPERIOD;
1389 let buf_stride = frame_size + overlap;
1390 let pre_size = max_period + frame_size;
1391
1392 for c in 0..channels {
1393 pre[c * pre_size..c * pre_size + max_period]
1394 .copy_from_slice(&prefilter_mem[c * max_period..(c + 1) * max_period]);
1395 pre[c * pre_size + max_period..c * pre_size + pre_size].copy_from_slice(
1396 &in_buf[c * buf_stride + overlap..c * buf_stride + overlap + frame_size],
1397 );
1398 }
1399
1400 let enabled = true;
1401 let mut pitch_index: usize;
1402 let mut gain1: f32;
1403 if enabled && toneishness > 0.99 {
1404 let mut multiple = 1.0f32;
1406 let mut tone_freq = tone_freq;
1407 if tone_freq >= 3.1416 {
1408 tone_freq = 3.141593 - tone_freq;
1409 }
1410 while tone_freq >= multiple * 0.39 {
1411 multiple += 1.0;
1412 }
1413 if tone_freq > 0.006148 {
1414 pitch_index = ((0.5 + 2.0 * core::f32::consts::PI * multiple / tone_freq) as usize)
1415 .min(COMBFILTER_MAXPERIOD - 2);
1416 } else {
1417 pitch_index = COMBFILTER_MINPERIOD;
1418 }
1419 gain1 = 0.75;
1420 } else if enabled && complexity >= 5 {
1421 let pitch_buf_len = (max_period + frame_size) >> 1;
1422 {
1423 let mut pre_slices: FixedVec<&[f32], 2> = FixedVec::new();
1424 for c in 0..channels {
1425 pre_slices.push(&pre[c * pre_size..c * pre_size + pre_size]);
1426 }
1427 crate::pitch::pitch_downsample(&pre_slices, pitch_buf, pitch_buf_len, channels, 2);
1428 }
1429
1430 let search_max = max_period - 3 * min_period;
1431 let pitch_result = crate::pitch::pitch_search(
1432 &pitch_buf[max_period >> 1..],
1433 pitch_buf,
1434 frame_size,
1435 search_max,
1436 );
1437 pitch_index = (max_period - pitch_result).min(max_period - 2);
1438
1439 gain1 = crate::pitch::remove_doubling(
1440 pitch_buf,
1441 max_period,
1442 min_period,
1443 frame_size,
1444 &mut pitch_index,
1445 prefilter_period,
1446 prefilter_gain,
1447 );
1448 if pitch_index > max_period - 2 {
1449 pitch_index = max_period - 2;
1450 }
1451 gain1 *= 0.7;
1452 if loss_rate > 2 {
1454 gain1 *= 0.5;
1455 }
1456 if loss_rate > 4 {
1457 gain1 *= 0.5;
1458 }
1459 if loss_rate > 8 {
1460 gain1 = 0.0;
1461 }
1462 } else {
1463 gain1 = 0.0;
1464 pitch_index = COMBFILTER_MINPERIOD;
1465 }
1466
1467 if analysis.valid {
1468 gain1 *= analysis.max_pitch_ratio;
1469 }
1470
1471 let mut pf_threshold = 0.2f32;
1472 if (pitch_index as i32 - prefilter_period as i32).unsigned_abs() as usize * 10 > pitch_index {
1473 pf_threshold += 0.2;
1474 if tf_estimate > 0.98 {
1476 gain1 = 0.0;
1477 }
1478 }
1479 if nb_available_bytes < 25 {
1480 pf_threshold += 0.1;
1481 }
1482 if nb_available_bytes < 35 {
1483 pf_threshold += 0.1;
1484 }
1485 if prefilter_gain > 0.4 {
1486 pf_threshold -= 0.1;
1487 }
1488 if prefilter_gain > 0.55 {
1489 pf_threshold -= 0.1;
1490 }
1491 pf_threshold = pf_threshold.max(0.2);
1492
1493 let pf_on;
1494 if gain1 < pf_threshold {
1495 gain1 = 0.0;
1496 pf_on = false;
1497 } else {
1498 if (gain1 - prefilter_gain).abs() < 0.1 {
1499 gain1 = prefilter_gain;
1500 }
1501 let qg = ((gain1 * 32.0 / 3.0 + 0.5).floor() as i32 - 1).clamp(0, 7);
1502 gain1 = 0.09375 * (qg + 1) as f32;
1503 pf_on = true;
1504 }
1505
1506 let before = &mut before[..channels];
1507 for c in 0..channels {
1508 let start = c * buf_stride + overlap;
1509 before[c] = sum_abs(&in_buf[start..start + frame_size]);
1510 }
1511
1512 let offset = 0usize;
1513 let prev_period = prefilter_period.clamp(COMBFILTER_MINPERIOD, max_period - 2);
1514
1515 for c in 0..channels {
1516 if offset > 0 {
1517 let pre_c = &pre[c * pre_size..];
1518 comb_filter(
1519 in_buf,
1520 pre_c,
1521 c * buf_stride + overlap,
1522 max_period,
1523 prev_period,
1524 prev_period,
1525 offset,
1526 -prefilter_gain,
1527 -prefilter_gain,
1528 prefilter_tapset,
1529 prefilter_tapset,
1530 window,
1531 0,
1532 );
1533 }
1534
1535 {
1536 let pre_c = &pre[c * pre_size..];
1537 comb_filter(
1538 in_buf,
1539 pre_c,
1540 c * buf_stride + overlap + offset,
1541 max_period + offset,
1542 prev_period,
1543 pitch_index,
1544 frame_size - offset,
1545 -prefilter_gain,
1546 -gain1,
1547 prefilter_tapset,
1548 tapset_decision,
1549 window,
1550 overlap,
1551 );
1552 }
1553 }
1554
1555 let after = &mut after[..channels];
1556 for c in 0..channels {
1557 let start = c * buf_stride + overlap;
1558 after[c] = sum_abs(&in_buf[start..start + frame_size]);
1559 }
1560
1561 let cancel_pitch = (0..channels).any(|c| after[c] > before[c]);
1562
1563 if cancel_pitch {
1568 for c in 0..channels {
1569 let body = c * buf_stride + overlap;
1570 in_buf[body..body + frame_size].copy_from_slice(
1571 &pre[c * pre_size + max_period..c * pre_size + max_period + frame_size],
1572 );
1573 comb_filter(
1574 in_buf,
1575 &pre[c * pre_size..],
1576 body + offset,
1577 max_period + offset,
1578 prev_period,
1579 pitch_index,
1580 overlap,
1581 -prefilter_gain,
1582 0.0,
1583 prefilter_tapset,
1584 tapset_decision,
1585 window,
1586 overlap,
1587 );
1588 }
1589 }
1590
1591 for c in 0..channels {
1592 push_prefilter_history(
1593 &mut prefilter_mem[c * max_period..(c + 1) * max_period],
1594 &pre[c * pre_size + max_period..c * pre_size + pre_size],
1595 );
1596 }
1597
1598 if cancel_pitch {
1599 (false, 0.0, pitch_index)
1600 } else {
1601 (pf_on, gain1, pitch_index)
1602 }
1603}
1604
1605fn push_prefilter_history(mem: &mut [f32], frame: &[f32]) {
1609 let (n, max_period) = (frame.len(), mem.len());
1610 if n >= max_period {
1611 mem.copy_from_slice(&frame[n - max_period..]);
1612 } else {
1613 mem.copy_within(n.., 0);
1614 mem[max_period - n..].copy_from_slice(frame);
1615 }
1616}
1617
1618const STRIDE_ACCESS_PAD: usize = crate::pvq::MAX_PVQ_N;
1623
1624pub struct CeltEncoder {
1625 mode: &'static CeltMode,
1626 channels: usize,
1627 upsample: usize,
1630 end_band: usize,
1635 pub complexity: i32,
1636 syn_mem: FixedVec<f32, CELT_SYN_MEM>,
1637 enc_decode_mem: FixedVec<f32, CELT_SYN_MEM>,
1638 old_band_e: FixedVec<f32, CELT_NB_X_CH>,
1639 preemph_mem: FixedVec<f32, CELT_MAX_CHANNELS>,
1640 tonal_average: i32,
1641 hf_average: i32,
1642 tapset_decision: i32,
1643 spread_decision: i32,
1644 intensity: i32,
1645 last_coded_bands: i32,
1646 prefilter_mem: FixedVec<f32, CELT_PREFILTER_MEM>,
1647 prefilter_period: usize,
1648 prefilter_gain: f32,
1649 prefilter_tapset: i32,
1650 old_band_e2: FixedVec<f32, CELT_NB_X_CH>,
1651 old_band_e3: FixedVec<f32, CELT_NB_X_CH>,
1652 last_band_log_e: FixedVec<f32, CELT_NB_X_CH>,
1653 delayed_intra: f32,
1654 lsb_depth: i32,
1655 overlap_max: f32,
1656 bitrate: i32,
1657 vbr: bool,
1658 constrained_vbr: bool,
1659 vbr_reservoir: i32,
1660 vbr_drift: i32,
1661 vbr_offset: i32,
1662 vbr_count: i32,
1663
1664 w_in_buf: FixedVec<f32, CELT_BUFSTRIDE>,
1665 w_freq: FixedVec<f32, CELT_W_FREQ>,
1666 w_band_e: FixedVec<f32, CELT_NB_X_CH>,
1667 w_band_e2: FixedVec<f32, CELT_NB_X_CH>,
1668 w_x: FixedVec<f32, CELT_W_X_ENC>,
1669 w_band_log_e: FixedVec<f32, CELT_NB_X_CH>,
1670 w_band_log_e2: FixedVec<f32, CELT_NB_X_CH>,
1671 w_error: FixedVec<f32, CELT_NB_X_CH>,
1672 w_tf_res: FixedVec<i32, CELT_NB_EBANDS>,
1673 w_cap: FixedVec<i32, CELT_NB_EBANDS>,
1674 w_offsets: FixedVec<i32, CELT_NB_EBANDS>,
1675 w_pulses: FixedVec<i32, CELT_NB_EBANDS>,
1676 w_ebits: FixedVec<i32, CELT_NB_X_CH>,
1677 w_fine_priority: FixedVec<i32, CELT_NB_X_CH>,
1678 w_collapse_masks: FixedVec<u32, CELT_NB_X_CH>,
1679 w_band_amp_synth: FixedVec<f32, CELT_NB_X_CH>,
1680 consec_transient: i32,
1681
1682 w_prefilter_pre: FixedVec<f32, CELT_PREFILTER_PRE>,
1683 w_prefilter_pitch_buf: FixedVec<f32, CELT_PREFILTER_PITCH>,
1684 w_prefilter_before: FixedVec<f32, CELT_MAX_CHANNELS>,
1685 w_prefilter_after: FixedVec<f32, CELT_MAX_CHANNELS>,
1686
1687 w_transient_tmp: FixedVec<f32, MAX_TRANSIENT_LEN>,
1688 w_transient_tmp2: FixedVec<f32, { MAX_TRANSIENT_LEN / 2 }>,
1689
1690 analysis: AnalysisInfo,
1691 loss_rate: i32,
1692}
1693
1694const INTEN_THRESHOLDS: [i32; 21] = [
1695 1, 2, 3, 4, 5, 6, 7, 8, 16, 24, 36, 44, 50, 56, 62, 67, 72, 79, 88, 106, 134,
1696];
1697const INTEN_HYSTERESIS: [i32; 21] = [
1698 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4, 5, 6, 8, 8,
1699];
1700
1701fn hysteresis_decision(val: i32, thresholds: &[i32], hysteresis: &[i32], prev: i32) -> i32 {
1702 let mut i = 0;
1703 while i < thresholds.len() {
1704 if val < thresholds[i] {
1705 break;
1706 }
1707 i += 1;
1708 }
1709 let mut res = i as i32;
1710 if res > prev && val < thresholds[prev as usize] + hysteresis[prev as usize] {
1711 res = prev;
1712 }
1713 if res < prev && res > 0 && val > thresholds[prev as usize - 1] - hysteresis[prev as usize - 1]
1714 {
1715 res = prev;
1716 }
1717 res
1718}
1719
1720#[allow(clippy::too_many_arguments)]
1721fn alloc_trim_analysis(
1722 mode: &CeltMode,
1723 x: &[f32],
1724 band_log_e: &[f32],
1725 end: usize,
1726 lm: i32,
1727 channels: usize,
1728 n0: usize,
1729 stereo_saving: &mut f32,
1730 tf_estimate: f32,
1731 intensity: i32,
1732 surround_trim: f32,
1733 equiv_rate: i32,
1734) -> i32 {
1735 let mut trim = 5.0f32;
1736 if equiv_rate < 64000 {
1737 trim = 4.0;
1738 } else if equiv_rate < 80000 {
1739 let frac = (equiv_rate - 64000) as f32 / 1024.0;
1740 trim = 4.0 + (1.0 / 16.0) * frac;
1741 }
1742
1743 if channels == 2 {
1744 let mut sum = 0.0f32;
1745 for i in 0..8 {
1746 let offset = (mode.e_bands[i] as usize) << lm;
1747 let n = ((mode.e_bands[i + 1] - mode.e_bands[i]) as usize) << lm;
1748 let mut partial = 0.0f32;
1749 for j in 0..n {
1750 partial += x[offset + j] * x[n0 + offset + j];
1751 }
1752 sum += partial;
1753 }
1754 sum = (sum / 8.0).abs().min(1.0);
1755 let mut min_xc = sum;
1756 for i in 8..intensity as usize {
1757 let offset = (mode.e_bands[i] as usize) << lm;
1758 let n = ((mode.e_bands[i + 1] - mode.e_bands[i]) as usize) << lm;
1759 let mut partial = 0.0f32;
1760 for j in 0..n {
1761 partial += x[offset + j] * x[n0 + offset + j];
1762 }
1763 min_xc = min_xc.min(partial.abs());
1764 }
1765 min_xc = min_xc.min(1.0);
1766
1767 let log_xc = (1.001 - sum * sum).log2();
1768 let log_xc2 = (log_xc * 0.5).max((1.001 - min_xc * min_xc).log2());
1769
1770 trim += (-4.0f32).max(0.75 * log_xc);
1771 *stereo_saving = (*stereo_saving + 0.25).min(-0.5 * log_xc2);
1772 }
1773
1774 let mut diff = 0.0f32;
1775 for c in 0..channels {
1776 for i in 0..end - 1 {
1777 diff += band_log_e[c * mode.nb_ebands + i] * (2 + 2 * i as i32 - end as i32) as f32;
1778 }
1779 }
1780 diff /= (channels * (end - 1)) as f32;
1781 trim -= (-2.0f32).max(2.0f32.min((diff + 1.0) / 6.0));
1782 trim -= surround_trim;
1783 trim -= 2.0 * tf_estimate;
1784
1785 let trim_index = (trim + 0.5).floor() as i32;
1786 trim_index.clamp(0, 10)
1787}
1788
1789#[inline(always)]
1790fn median3(a: f32, b: f32, c: f32) -> f32 {
1791 let mut v = [a, b, c];
1792 crate::compat::sort_by(&mut v[..], |x, y| {
1793 x.partial_cmp(y).unwrap_or(core::cmp::Ordering::Equal)
1794 });
1795 v[1]
1796}
1797
1798#[inline(always)]
1799fn median5(v: &[f32]) -> f32 {
1800 let mut x = [v[0], v[1], v[2], v[3], v[4]];
1801 crate::compat::sort_by(&mut x[..], |a, b| {
1802 a.partial_cmp(b).unwrap_or(core::cmp::Ordering::Equal)
1803 });
1804 x[2]
1805}
1806
1807fn tone_lpc(x: &[f32], len: usize, delay: usize, lpc: &mut [f32; 2]) -> bool {
1809 if len <= 2 * delay {
1811 return true;
1812 }
1813 let mut r00 = 0.0f32;
1814 let mut r01 = 0.0f32;
1815 let mut r02 = 0.0f32;
1816 let mut r11: f32;
1817 let mut r12: f32;
1818
1819 for i in 0..len - 2 * delay {
1820 r00 += x[i] * x[i];
1821 r01 += x[i] * x[i + delay];
1822 r02 += x[i] * x[i + 2 * delay];
1823 }
1824 let mut edges = 0.0f32;
1825 for i in 0..delay {
1826 edges += x[len + i - 2 * delay] * x[len + i - 2 * delay] - x[i] * x[i];
1827 }
1828 r11 = r00 + edges;
1829 edges = 0.0;
1830 for i in 0..delay {
1831 edges += x[len + i - delay] * x[len + i - delay] - x[i + delay] * x[i + delay];
1832 }
1833 let r22: f32 = r11 + edges;
1834 edges = 0.0;
1835 for i in 0..delay {
1836 edges += x[len + i - 2 * delay] * x[len + i - delay] - x[i] * x[i + delay];
1837 }
1838 r12 = r01 + edges;
1839 let (rr00, rr01, rr11, rr02, rr12) = (
1841 r00 + r22,
1842 r01 + r12,
1843 2.0 * r11,
1844 2.0 * r02,
1845 r12 + r01,
1846 );
1847 r00 = rr00;
1848 r01 = rr01;
1849 r11 = rr11;
1850 r02 = rr02;
1851 r12 = rr12;
1852 let den = r00 * r11 - r01 * r01;
1853 if den < 0.001 * r00 * r11 {
1854 return true;
1855 }
1856 let mut lpc1 = (r02 * r11 - r01 * r12) / den;
1857 let mut lpc0 = (r00 * r12 - r02 * r01) / den;
1858 lpc1 = lpc1.clamp(-1.0, 1.0);
1860 lpc0 = lpc0.clamp(-1.999999, 1.999999);
1861 lpc[0] = lpc0;
1863 lpc[1] = lpc1;
1864 false
1865}
1866
1867fn tone_detect(in_buf: &[f32], cc: usize, n: usize, fs: i32) -> (f32, f32) {
1868 let mut x: FixedVec<f32, 2048> = FixedVec::from_value(0.0, n);
1872 if cc == 2 {
1873 for i in 0..n {
1874 x[i] = 0.5 * (in_buf[i] + in_buf[i + n]);
1875 }
1876 } else {
1877 for i in 0..n {
1878 x[i] = in_buf[i];
1879 }
1880 }
1881 let mut delay = 1usize;
1882 let mut lpc = [0.0f32; 2];
1883 let mut fail = tone_lpc(&x[..n], n, delay, &mut lpc);
1884 while delay <= (fs as usize / 3000) && (fail || (lpc[0] > 1.0 && lpc[1] < 0.0)) {
1885 delay *= 2;
1886 fail = tone_lpc(&x[..n], n, delay, &mut lpc);
1887 }
1888 if !fail && lpc[0] * lpc[0] + 3.999999 * lpc[1] < 0.0 {
1889 let toneishness = -lpc[1];
1890 #[cfg(feature = "std")]
1892 let freq = (0.5 * lpc[0]).acos() / delay as f32;
1893 #[cfg(not(feature = "std"))]
1894 let freq = crate::compat::Math::acos(0.5 * lpc[0]) / delay as f32;
1895 (freq, toneishness)
1896 } else {
1897 (-1.0, 0.0)
1898 }
1899}
1900
1901#[allow(clippy::too_many_arguments)]
1902fn dynalloc_analysis_simple(
1903 mode: &CeltMode,
1904 band_log_e: &[f32],
1905 band_log_e2: Option<&[f32]>,
1906 old_band_e: &[f32],
1907 start: usize,
1908 end: usize,
1909 channels: usize,
1910 lm: usize,
1911 effective_bytes: usize,
1912 is_transient: bool,
1913 offsets: &mut [i32],
1914 cap: &[i32],
1915 lsb_depth: i32,
1916 vbr: bool,
1917 constrained_vbr: bool,
1918 analysis: &AnalysisInfo,
1919 surround_dynalloc: &[f32],
1920 tone_freq: f32,
1921 toneishness: f32,
1922 importance: &mut [i32],
1923) {
1924 offsets.fill(0);
1925 if effective_bytes < (30 + 5 * lm) {
1926 for v in importance.iter_mut() {
1927 *v = 13;
1928 }
1929 return;
1930 }
1931
1932 let nb = mode.nb_ebands;
1933 let mut follower: FixedVec<f32, CELT_NB_X_CH> = FixedVec::from_value(0.0f32, nb * channels);
1934 for c in 0..channels {
1935 let base = c * nb;
1936 let src = if let Some(b2) = band_log_e2 {
1937 b2
1938 } else {
1939 band_log_e
1940 };
1941 let mut band_log_e3: FixedVec<f32, CELT_NB_EBANDS> = FixedVec::from_value(0.0f32, end);
1942 for i in 0..end {
1943 let mut e = src[base + i];
1944 if lm == 0 && i < 8 {
1945 e = e.max(old_band_e[base + i]);
1946 }
1947 band_log_e3[i] = e;
1948 }
1949
1950 let mut last = 0usize;
1951 follower[base] = band_log_e3[0];
1952 for i in 1..end {
1953 if band_log_e3[i] > band_log_e3[i - 1] + 0.5 {
1954 last = i;
1955 }
1956 follower[base + i] = (follower[base + i - 1] + 1.5).min(band_log_e3[i]);
1957 }
1958 for i in (0..last).rev() {
1959 follower[base + i] =
1960 follower[base + i].min((follower[base + i + 1] + 2.0).min(band_log_e3[i]));
1961 }
1962
1963 let offset = 1.0f32;
1964 if end >= 5 {
1965 for i in 2..end - 2 {
1966 follower[base + i] =
1967 follower[base + i].max(median5(&band_log_e3[i - 2..i + 3]) - offset);
1968 }
1969 }
1970 if end >= 3 {
1971 let l = median3(band_log_e3[0], band_log_e3[1], band_log_e3[2]) - offset;
1972 follower[base] = follower[base].max(l);
1973 follower[base + 1] = follower[base + 1].max(l);
1974
1975 let r = median3(
1976 band_log_e3[end - 3],
1977 band_log_e3[end - 2],
1978 band_log_e3[end - 1],
1979 ) - offset;
1980 follower[base + end - 2] = follower[base + end - 2].max(r);
1981 follower[base + end - 1] = follower[base + end - 1].max(r);
1982 }
1983 for i in 0..end {
1985 let log_n = if i < mode.log_n.len() {
1986 mode.log_n[i] as f32
1987 } else {
1988 0.0
1989 };
1990 let e_mean = if i < mode.e_means.len() {
1991 mode.e_means[i]
1992 } else {
1993 0.0
1994 };
1995 let noise_floor = 0.0625 * log_n + 0.5 + (9 - lsb_depth) as f32 - e_mean
1996 + 0.0062 * ((i + 5) * (i + 5)) as f32;
1997 follower[base + i] = follower[base + i].max(noise_floor);
1998 }
1999 }
2000 if channels == 2 {
2001 for i in start..end {
2002 let l = follower[i];
2003 let r = follower[nb + i];
2004 let r2 = r.max(l - 4.0);
2005 let l2 = l.max(r - 4.0);
2006 follower[i] =
2007 ((band_log_e[i] - l2).max(0.0) + (band_log_e[nb + i] - r2).max(0.0)) * 0.5;
2008 }
2009 } else {
2010 for i in start..end {
2011 follower[i] = (band_log_e[i] - follower[i]).max(0.0);
2012 }
2013 }
2014 for i in start..end {
2015 follower[i] = follower[i].max(surround_dynalloc[i]);
2017 }
2018 for i in start..end {
2020 let v = follower[i].min(4.0);
2021 importance[i] = (0.5 + 13.0 * (2.0f32).powf(v)).floor() as i32;
2022 }
2023 if (!vbr || constrained_vbr) && !is_transient {
2024 for i in start..end {
2025 follower[i] *= 0.5;
2026 }
2027 }
2028 for i in start..end {
2031 if i < 8 {
2032 follower[i] *= 2.0;
2033 }
2034 if i >= 12 {
2035 follower[i] *= 0.5;
2036 }
2037 }
2038 if toneishness > 0.98 {
2040 let freq_bin = (tone_freq * 120.0 / core::f32::consts::PI + 0.5).floor() as i32;
2041 for i in start..end {
2042 let lo = mode.e_bands[i] as i32;
2043 let hi = mode.e_bands[i + 1] as i32;
2044 if freq_bin >= lo && freq_bin <= hi {
2045 follower[i] += 2.0;
2046 }
2047 if freq_bin >= lo - 1 && freq_bin <= hi + 1 {
2048 follower[i] += 1.0;
2049 }
2050 if freq_bin >= lo - 2 && freq_bin <= hi + 2 {
2051 follower[i] += 1.0;
2052 }
2053 if freq_bin >= lo - 3 && freq_bin <= hi + 3 {
2054 follower[i] += 0.5;
2055 }
2056 }
2057 if freq_bin >= mode.e_bands[end] as i32 {
2058 if end >= 1 {
2059 follower[end - 1] += 2.0;
2060 }
2061 if end >= 2 {
2062 follower[end - 2] += 1.0;
2063 }
2064 }
2065 }
2066 if analysis.valid {
2067 for i in start..end.min(19) {
2069 follower[i] += (1.0 / 64.0) * analysis.leak_boost[i] as f32;
2070 }
2071 }
2072 if effective_bytes > 320 {
2074 let add = (1.5f32).min(1e-3 * (effective_bytes as f32 - 320.0));
2075 if start < end {
2076 follower[start] += add;
2077 }
2078 }
2079
2080 let mut tot_boost = 0i32;
2081 for i in start..end {
2082 let f = follower[i].min(4.0);
2083
2084 let width = channels as i32 * (mode.e_bands[i + 1] - mode.e_bands[i]) as i32 * (1 << lm);
2085 let (boost, boost_bits) = if width < 6 {
2086 let b = f.floor().max(0.0) as i32;
2087 (b, (b * width) << BITRES)
2088 } else if width > 48 {
2089 let b = (f * 8.0).floor().max(0.0) as i32;
2090 (b, ((b * width) << BITRES) / 8)
2091 } else {
2092 let b = (f * width as f32 / 6.0).floor().max(0.0) as i32;
2093 (b, (b * 6) << BITRES)
2094 };
2095
2096 if !vbr || (constrained_vbr && !is_transient) {
2098 let cap_bits = ((2 * effective_bytes as i32) / 3) << (BITRES + 3);
2099 if tot_boost + boost_bits > cap_bits {
2100 offsets[i] = ((cap_bits - tot_boost) >> BITRES).max(0);
2101 break;
2102 }
2103 }
2104
2105 let quanta = (width << BITRES).min((6 << BITRES).max(width));
2106 let mut boost_count = boost;
2107 let mut as_bits = boost_count * quanta;
2108 if as_bits > cap[i] {
2109 as_bits = cap[i];
2110 boost_count = as_bits / quanta;
2111 }
2112
2113 offsets[i] = boost_count.max(0);
2114 tot_boost += boost_bits.max(0);
2115 }
2116}
2117
2118impl CeltEncoder {
2119 pub fn new(mode: &'static CeltMode, channels: usize) -> Self {
2120 Self::with_sampling_rate(mode, channels, 48000)
2121 }
2122
2123 pub fn with_sampling_rate(
2128 mode: &'static CeltMode,
2129 channels: usize,
2130 sampling_rate: i32,
2131 ) -> Self {
2132 assert!(
2136 (1..=2).contains(&channels),
2137 "CeltEncoder::new: channels must be 1 or 2 (got {channels})"
2138 );
2139 let upsample = resampling_factor(sampling_rate);
2140 let overlap = mode.overlap;
2141 let channel_mem_size = 2048 + overlap;
2142 let syn_mem_size = channels * channel_mem_size;
2143 let nb_ebands = mode.nb_ebands;
2144 let nb_x_ch = nb_ebands * channels;
2145 let frame_x_ch = MAX_FRAME_SIZE * channels;
2146 let bufstride_x_ch = (MAX_FRAME_SIZE + overlap) * channels;
2147 Self {
2148 mode,
2149 channels,
2150 upsample,
2151 end_band: mode.nb_ebands,
2152 complexity: 9,
2153 syn_mem: FixedVec::from_value(0.0, syn_mem_size),
2154 enc_decode_mem: FixedVec::from_value(0.0, syn_mem_size),
2155 old_band_e: FixedVec::from_value(0.0, nb_x_ch),
2156 preemph_mem: FixedVec::from_value(0.0, channels),
2157 tonal_average: 256,
2158 hf_average: 0,
2159 tapset_decision: 0,
2160 spread_decision: SPREAD_NORMAL,
2161 intensity: 0,
2162 last_coded_bands: 0,
2163 prefilter_mem: FixedVec::from_value(0.0, channels * COMBFILTER_MAXPERIOD),
2164 prefilter_period: COMBFILTER_MINPERIOD,
2165 prefilter_gain: 0.0,
2166 prefilter_tapset: 0,
2167 old_band_e2: FixedVec::from_value(0.0, nb_x_ch),
2168 old_band_e3: FixedVec::from_value(0.0, nb_x_ch),
2169 last_band_log_e: FixedVec::from_value(0.0, nb_x_ch),
2170 delayed_intra: 0.0,
2171 lsb_depth: 24,
2172 overlap_max: 0.0,
2173 bitrate: OPUS_BITRATE_MAX,
2174 vbr: false,
2175 constrained_vbr: true,
2176 vbr_reservoir: 0,
2177 vbr_drift: 0,
2178 vbr_offset: 0,
2179 vbr_count: 0,
2180
2181 w_in_buf: FixedVec::from_value(0.0, bufstride_x_ch),
2182 w_freq: FixedVec::from_value(0.0, frame_x_ch + 4),
2183 w_band_e: FixedVec::from_value(0.0, nb_x_ch),
2184 w_band_e2: FixedVec::from_value(0.0, nb_x_ch),
2185
2186 w_x: FixedVec::from_value(0.0, frame_x_ch + STRIDE_ACCESS_PAD),
2187 w_band_log_e: FixedVec::from_value(0.0, nb_x_ch),
2188 w_band_log_e2: FixedVec::from_value(0.0, nb_x_ch),
2189 w_error: FixedVec::from_value(0.0, nb_x_ch),
2190 w_tf_res: FixedVec::from_value(0, nb_ebands),
2191 w_cap: FixedVec::from_value(0, nb_ebands),
2192 w_offsets: FixedVec::from_value(0, nb_ebands),
2193 w_pulses: FixedVec::from_value(0, nb_ebands),
2194 w_ebits: FixedVec::from_value(0, nb_x_ch),
2195 w_fine_priority: FixedVec::from_value(0, nb_x_ch),
2196 w_collapse_masks: FixedVec::from_value(0, nb_x_ch),
2197 w_band_amp_synth: FixedVec::from_value(0.0, nb_x_ch),
2198
2199 w_prefilter_pre: FixedVec::from_value(
2200 0.0,
2201 channels * (COMBFILTER_MAXPERIOD + MAX_FRAME_SIZE),
2202 ),
2203 w_prefilter_pitch_buf: FixedVec::from_value(
2204 0.0,
2205 (COMBFILTER_MAXPERIOD + MAX_FRAME_SIZE) >> 1,
2206 ),
2207 w_prefilter_before: FixedVec::from_value(0.0, channels),
2208 w_prefilter_after: FixedVec::from_value(0.0, channels),
2209 w_transient_tmp: FixedVec::from_value(0.0, MAX_TRANSIENT_LEN),
2210 w_transient_tmp2: FixedVec::from_value(0.0, MAX_TRANSIENT_LEN / 2),
2211 consec_transient: 0,
2212
2213 analysis: AnalysisInfo::default(),
2214 loss_rate: 0,
2215 }
2216 }
2217
2218 pub fn set_end_band(&mut self, end: usize) {
2221 self.end_band = end;
2222 }
2223
2224 pub fn encode(&mut self, pcm: &[f32], frame_size: usize, rc: &mut RangeCoder) {
2225 self.encode_impl(pcm, frame_size, rc, 0, None, false)
2226 }
2227
2228 pub fn encode_with_start_band(
2229 &mut self,
2230 pcm: &[f32],
2231 frame_size: usize,
2232 rc: &mut RangeCoder,
2233 start_band: usize,
2234 ) {
2235 self.encode_impl(pcm, frame_size, rc, start_band, None, false)
2236 }
2237
2238 pub fn encode_with_budget(
2239 &mut self,
2240 pcm: &[f32],
2241 frame_size: usize,
2242 rc: &mut RangeCoder,
2243 start_band: usize,
2244 total_bits: i32,
2245 ) {
2246 self.encode_impl(pcm, frame_size, rc, start_band, Some(total_bits), false)
2247 }
2248
2249 pub fn encode_with_budget_vbr(
2250 &mut self,
2251 pcm: &[f32],
2252 frame_size: usize,
2253 rc: &mut RangeCoder,
2254 start_band: usize,
2255 total_bits: i32,
2256 is_vbr: bool,
2257 ) {
2258 self.encode_impl(pcm, frame_size, rc, start_band, Some(total_bits), is_vbr)
2259 }
2260
2261 pub fn set_lsb_depth(&mut self, depth: i32) {
2262 self.lsb_depth = depth.clamp(8, 24);
2263 }
2264
2265 pub fn get_lsb_depth(&self) -> i32 {
2266 self.lsb_depth
2267 }
2268 pub fn set_bitrate(&mut self, bitrate: i32) {
2269 self.bitrate = bitrate;
2270 }
2271 pub fn set_vbr(&mut self, vbr: bool) {
2272 self.vbr = vbr;
2273 }
2274 pub fn set_constrained_vbr(&mut self, cvbr: bool) {
2275 self.constrained_vbr = cvbr;
2276 }
2277
2278 fn encode_impl(
2279 &mut self,
2280 pcm: &[f32],
2281 api_frame_size: usize,
2282 rc: &mut RangeCoder,
2283 start_band: usize,
2284 explicit_total_bits: Option<i32>,
2285 is_vbr: bool,
2286 ) {
2287 let mode = self.mode;
2288 let channels = self.channels;
2289 let upsample = self.upsample;
2290 let frame_size = api_frame_size * upsample;
2292 let nb_ebands = mode.nb_ebands;
2293 let end = self.end_band.clamp(1, nb_ebands).max(start_band);
2294 let overlap = mode.overlap;
2295
2296 assert!(
2302 (0..=mode.max_lm).any(|lm| mode.short_mdct_size << lm == frame_size),
2303 "CeltEncoder: invalid frame_size {} (valid: {}..={} kHz multiples of {})",
2304 frame_size,
2305 mode.short_mdct_size,
2306 mode.short_mdct_size << mode.max_lm,
2307 mode.short_mdct_size
2308 );
2309
2310 let mut lm = 0;
2311 while (mode.short_mdct_size << lm) != frame_size {
2312 lm += 1;
2313 if lm > mode.max_lm {
2314 break;
2315 }
2316 }
2317 if (mode.short_mdct_size << lm) != frame_size {
2318 lm = 0;
2319 }
2320
2321 let syn_mem_size = 2048 + overlap;
2322 for c in 0..channels {
2323 let channel_offset = c * syn_mem_size;
2324
2325 self.syn_mem.copy_within(
2326 channel_offset + frame_size..channel_offset + syn_mem_size,
2327 channel_offset,
2328 );
2329
2330 let mut m = self.preemph_mem[c];
2331 let coef = mode.preemph[0];
2332 for i in 0..frame_size {
2336 let x = if i % upsample == 0 {
2337 pcm[c * api_frame_size + i / upsample] * 32768.0
2338 } else {
2339 0.0
2340 };
2341 let val = x - m;
2342 self.syn_mem[channel_offset + syn_mem_size - frame_size + i] = val;
2343 m = x * coef;
2344 }
2345 self.preemph_mem[c] = m;
2346 }
2347
2348 let buf_stride = frame_size + overlap;
2349 let in_buf = &mut self.w_in_buf[..buf_stride * channels];
2350 for c in 0..channels {
2351 let channel_offset = c * syn_mem_size;
2352 let in_buf_offset = c * buf_stride;
2353
2354 let src_start = syn_mem_size - frame_size - overlap;
2355 in_buf[in_buf_offset..in_buf_offset + buf_stride].copy_from_slice(
2356 &self.syn_mem[channel_offset + src_start..channel_offset + syn_mem_size],
2357 );
2358 }
2359
2360 let max_period = COMBFILTER_MAXPERIOD;
2366 for c in 0..channels {
2367 in_buf[c * buf_stride..c * buf_stride + overlap].copy_from_slice(
2368 &self.prefilter_mem[(c + 1) * max_period - overlap..(c + 1) * max_period],
2369 );
2370 }
2371
2372 let (tone_freq, mut toneishness) = tone_detect(&*in_buf, channels, buf_stride, mode.fs);
2374 let mut tf_estimate = 0.0f32;
2375 let mut tf_chan = 0;
2376 let mut weak_transient = false;
2377
2378 let is_transient = if self.complexity >= 1 {
2379 transient_analysis(
2380 in_buf,
2381 buf_stride,
2382 channels,
2383 &mut tf_estimate,
2384 &mut tf_chan,
2385 false,
2386 &mut weak_transient,
2387 tone_freq,
2388 toneishness,
2389 &mut self.w_transient_tmp,
2390 &mut self.w_transient_tmp2,
2391 )
2392 } else {
2393 false
2394 };
2395 let in_mem_start = syn_mem_size - frame_size - overlap;
2398 for c in 0..channels {
2399 let src = c * syn_mem_size + in_mem_start;
2400 in_buf[c * buf_stride..c * buf_stride + overlap]
2401 .copy_from_slice(&self.syn_mem[src..src + overlap]);
2402 }
2403 toneishness = toneishness.min((1.0 - tf_estimate).clamp(0.0, 1.0));
2406
2407 let analysis_toneishness = if self.analysis.valid {
2410 self.analysis.tonality
2411 } else {
2412 0.0
2413 };
2414 let pf_enabled =
2416 start_band == 0 && self.complexity >= 5 && analysis_toneishness < 0.99 && channels == 1;
2417 let (pf_on, gain1, pitch_index) = if pf_enabled {
2418 let tell = rc.tell();
2419 let nb_filled = ((tell + 4) >> 3).max(0) as usize;
2420 let total = explicit_total_bits.unwrap_or_else(|| (rc.buf.len() * 8) as i32);
2421 let nb_available = ((total / 8) as usize).saturating_sub(nb_filled);
2422 run_prefilter(
2423 in_buf,
2424 &mut self.prefilter_mem,
2425 self.prefilter_period,
2426 self.prefilter_gain,
2427 self.prefilter_tapset,
2428 self.tapset_decision,
2429 mode.window,
2430 channels,
2431 frame_size,
2432 overlap,
2433 &mut self.w_prefilter_pre,
2434 &mut self.w_prefilter_pitch_buf,
2435 &mut self.w_prefilter_before,
2436 &mut self.w_prefilter_after,
2437 &self.analysis,
2438 self.loss_rate,
2439 tf_estimate,
2440 nb_available,
2441 tone_freq,
2442 toneishness,
2443 self.complexity,
2444 )
2445 } else {
2446 for c in 0..channels {
2450 let body = c * buf_stride + overlap;
2451 push_prefilter_history(
2452 &mut self.prefilter_mem[c * max_period..(c + 1) * max_period],
2453 &in_buf[body..body + frame_size],
2454 );
2455 }
2456 (false, 0.0f32, COMBFILTER_MINPERIOD)
2457 };
2458
2459 let syn_mem_size = 2048 + overlap;
2464 for c in 0..channels {
2465 let channel_offset = c * syn_mem_size;
2466 let in_buf_offset = c * buf_stride;
2467 self.syn_mem[channel_offset + syn_mem_size - overlap..channel_offset + syn_mem_size]
2468 .copy_from_slice(&in_buf[in_buf_offset + frame_size..in_buf_offset + buf_stride]);
2469 }
2470 let freq = &mut self.w_freq[..frame_size * channels];
2471 let band_e = &mut self.w_band_e[..nb_ebands * channels];
2472 let band_log_e = &mut self.w_band_log_e[..nb_ebands * channels];
2473 let x_pad_end = (frame_size * channels + STRIDE_ACCESS_PAD).min(self.w_x.len());
2474 let x = &mut self.w_x[..x_pad_end];
2475
2476 let mut total_bits = explicit_total_bits.unwrap_or_else(|| (rc.buf.len() * 8) as i32);
2477 self.w_error[..nb_ebands * channels].fill(0.0);
2478 let error = &mut self.w_error[..nb_ebands * channels];
2479
2480 let api_overlap = overlap / upsample;
2484 let mut sample_max = self.overlap_max;
2485 let n_nonoverlap = api_frame_size.saturating_sub(api_overlap);
2486 for c in 0..channels {
2487 let base = c * api_frame_size;
2488 for i in 0..n_nonoverlap {
2489 let v = pcm[base + i].abs();
2490 if v > sample_max {
2491 sample_max = v;
2492 }
2493 }
2494 }
2495 let mut new_overlap_max = 0.0f32;
2496 for c in 0..channels {
2497 let base = c * api_frame_size;
2498 for i in n_nonoverlap..api_frame_size {
2499 let v = pcm[base + i].abs();
2500 if v > new_overlap_max {
2501 new_overlap_max = v;
2502 }
2503 }
2504 }
2505 self.overlap_max = new_overlap_max;
2506 if new_overlap_max > sample_max {
2507 sample_max = new_overlap_max;
2508 }
2509 let threshold = 1.0 / ((1 << self.lsb_depth) as f32);
2510 let mut silence = sample_max <= threshold;
2511 let tell_initial = rc.tell();
2512 let tell_initial_frac = rc.tell_frac();
2513 let nb_filled_bytes_initial = ((tell_initial + 4) >> 3).max(0) as usize;
2514 let mut nb_compressed_bytes = (total_bits / 8) as usize;
2515 if tell_initial == 1 {
2516 rc.encode_bit_logp(silence, 15);
2517 } else {
2518 silence = false;
2519 }
2520 if silence {
2521 if is_vbr {
2522 let target_bytes = nb_filled_bytes_initial + 2;
2523 if target_bytes < nb_compressed_bytes {
2524 nb_compressed_bytes = target_bytes;
2525 total_bits = (nb_compressed_bytes * 8) as i32;
2526 rc.shrink(nb_compressed_bytes as u32);
2527 }
2528 }
2529 let cur_tell = rc.tell();
2530 let new_tell = (nb_compressed_bytes * 8) as i32;
2531 rc.nbits_total += new_tell - cur_tell;
2532 }
2533 if self.vbr && self.bitrate != OPUS_BITRATE_MAX {
2535 let vbr_rate = bitrate_to_bits(self.bitrate, mode.fs, frame_size as i32) << BITRES;
2536 let nb_available = nb_compressed_bytes.saturating_sub(nb_filled_bytes_initial);
2537 if self.constrained_vbr {
2538 let vbr_bound = vbr_rate;
2539 let max_allowed = core::cmp::min(
2540 core::cmp::max(
2541 if tell_initial == 1 { 2 } else { 0 },
2542 (vbr_rate + vbr_bound - self.vbr_reservoir) >> (BITRES + 3),
2543 ),
2544 nb_available as i32,
2545 );
2546 if (max_allowed as usize) < nb_available {
2547 nb_compressed_bytes = nb_filled_bytes_initial + max_allowed as usize;
2548 total_bits = (nb_compressed_bytes * 8) as i32;
2549 rc.shrink(nb_compressed_bytes as u32);
2550 }
2551 }
2552 }
2554
2555 if start_band == 0 && !silence && rc.tell() + 16 <= total_bits {
2556 rc.encode_bit_logp(pf_on, 1);
2557 if pf_on {
2558 let qg = (gain1 / 0.09375 - 1.0 + 0.5).floor() as i32;
2559 let qg = qg.clamp(0, 7);
2560 let pi = (pitch_index + 1) as u32;
2561 let octave = 32 - pi.leading_zeros();
2562 let octave = (octave as i32 - 5).max(0) as u32;
2563 rc.enc_uint(octave, 6);
2564 rc.enc_bits(pi - (16 << octave), 4 + octave);
2565 rc.enc_bits(qg as u32, 3);
2566 rc.encode_icdf(self.tapset_decision, &TAPSET_ICDF, 2);
2567 }
2568 }
2569
2570 let mut short_blocks = false;
2571 if lm > 0 && rc.tell() + 3 <= total_bits {
2572 rc.encode_bit_logp(is_transient, 3);
2573 if is_transient {
2574 short_blocks = true;
2575 }
2576 }
2577 let second_mdct = short_blocks && self.complexity >= 8;
2578 if second_mdct {
2579 for c in 0..channels {
2580 let c_buf = c * buf_stride;
2581 let c_freq = c * frame_size;
2582 mode.mdct.forward(
2583 &in_buf[c_buf..],
2584 &mut freq[c_freq..],
2585 mode.window,
2586 overlap,
2587 mode.max_lm - lm,
2588 1,
2589 );
2590 }
2591 upsample_scale_zero(freq, frame_size, upsample, channels);
2592 let band_e2 = &mut self.w_band_e2[..nb_ebands * channels];
2593 compute_band_energies(mode, freq, band_e2, end, channels, lm);
2594 let band_log_e2 = &mut self.w_band_log_e2[..nb_ebands * channels];
2595 crate::bands::amp2log2(mode, 0, end, band_e2, band_log_e2, channels);
2596 for c in 0..channels {
2597 for i in 0..end {
2598 band_log_e2[c * nb_ebands + i] += lm as f32 * 0.5;
2599 }
2600 }
2601 }
2602 if short_blocks {
2603 let b = 1 << lm;
2604 let n = frame_size / b;
2605 for c in 0..channels {
2606 let c_offset = c * buf_stride;
2607 for i in 0..b {
2608 mode.mdct.forward(
2609 &in_buf[c_offset + i * n..c_offset + buf_stride],
2610 &mut freq[c * frame_size + i..],
2611 mode.window,
2612 overlap,
2613 mode.max_lm,
2614 b,
2615 );
2616 }
2617 }
2618 upsample_scale_zero(freq, frame_size, upsample, channels);
2619
2620 compute_band_energies(mode, freq, band_e, end, channels, lm);
2621 normalise_bands(
2622 mode,
2623 freq,
2624 x,
2625 band_e,
2626 end,
2627 channels,
2628 (1 << lm) as usize,
2629 );
2630 crate::bands::amp2log2(mode, start_band, end, band_e, band_log_e, channels);
2631 } else {
2632 for c in 0..channels {
2634 let c_buf = c * buf_stride;
2635 let c_freq = c * frame_size;
2636 mode.mdct.forward(
2637 &in_buf[c_buf..],
2638 &mut freq[c_freq..],
2639 mode.window,
2640 overlap,
2641 mode.max_lm - lm,
2642 1,
2643 );
2644 }
2645 upsample_scale_zero(freq, frame_size, upsample, channels);
2646 compute_band_energies(mode, freq, band_e, end, channels, lm);
2647 normalise_bands(
2648 mode,
2649 freq,
2650 x,
2651 band_e,
2652 end,
2653 channels,
2654 (1 << lm) as usize,
2655 );
2656 crate::bands::amp2log2(mode, start_band, end, band_e, band_log_e, channels);
2657 }
2658
2659 quant_coarse_energy_advanced(
2662 mode,
2663 start_band,
2664 end,
2665 end,
2666 band_log_e,
2667 &mut self.old_band_e,
2668 total_bits as u32,
2669 error,
2670 rc,
2671 channels,
2672 lm,
2673 (total_bits / 8) as usize,
2674 false, &mut self.delayed_intra,
2676 self.complexity >= 4,
2677 0,
2678 false,
2679 );
2680 self.w_tf_res[..nb_ebands].fill(0);
2681 let tf_res = &mut self.w_tf_res[..nb_ebands];
2682 let effective_bytes = ((total_bits / 8) as usize).max(1);
2683 let lambda = 80.max(20480 / effective_bytes + 2) as i32;
2684
2685 self.w_cap[..nb_ebands].fill(0);
2688 let cap = &mut self.w_cap[..nb_ebands];
2689 for (i, cap_i) in cap.iter_mut().enumerate() {
2690 let n = (mode.e_bands[i + 1] - mode.e_bands[i]) << lm;
2691 *cap_i = ((mode.cache.caps[nb_ebands * (2 * lm + channels - 1) + i] as i32 + 64)
2692 * channels as i32
2693 * n as i32)
2694 >> 2;
2695 }
2696
2697 self.w_offsets[..nb_ebands].fill(0);
2698 let offsets = &mut self.w_offsets[..nb_ebands];
2699
2700 let band_log_e2_opt = if second_mdct {
2701 Some(&self.w_band_log_e2[..nb_ebands * channels] as &[f32])
2702 } else {
2703 None
2704 };
2705 let surround_dynalloc = [0.0f32; 21];
2706 let mut importance = [13i32; MAX_NB_EBANDS];
2707 dynalloc_analysis_simple(
2708 mode,
2709 band_log_e,
2710 band_log_e2_opt,
2711 &self.old_band_e,
2712 start_band,
2713 end,
2714 channels,
2715 lm,
2716 effective_bytes,
2717 is_transient,
2718 offsets,
2719 cap,
2720 self.lsb_depth,
2721 self.vbr,
2722 self.constrained_vbr,
2723 &self.analysis,
2724 &surround_dynalloc,
2725 tone_freq,
2726 toneishness,
2727 &mut importance,
2728 );
2729
2730 let tf_select = if self.complexity >= 2 && effective_bytes >= 15 * channels {
2731 tf_analysis(
2732 mode,
2733 end,
2734 is_transient,
2735 tf_res,
2736 lambda,
2737 x,
2738 frame_size,
2739 lm as i32,
2740 tf_estimate,
2741 tf_chan,
2742 &importance,
2743 )
2744 } else {
2745 0
2746 };
2747 tf_encode(
2748 start_band,
2749 end,
2750 is_transient,
2751 tf_res,
2752 lm as i32,
2753 tf_select,
2754 rc,
2755 );
2756
2757 let mut dual_stereo_val = if channels == 2 {
2758 stereo_analysis(mode, x, lm as i32, frame_size) as i32
2759 } else {
2760 0
2761 };
2762
2763 let mut stereo_saving = 0.0f32;
2764 let equiv_rate = (total_bits * 48000) / frame_size as i32;
2765 if channels == 2 {
2766 self.intensity = hysteresis_decision(
2767 equiv_rate / 1000,
2768 &INTEN_THRESHOLDS,
2769 &INTEN_HYSTERESIS,
2770 self.intensity,
2771 );
2772 self.intensity = self.intensity.clamp(0, end as i32);
2773 }
2774
2775 if self.complexity == 0 {
2776 self.spread_decision = SPREAD_NONE;
2777 if rc.tell() + 4 <= total_bits {
2778 rc.encode_icdf(self.spread_decision, &SPREAD_ICDF, 5);
2779 }
2780 } else if rc.tell() + 4 <= total_bits {
2781 if is_transient || self.complexity < 3 || effective_bytes < 10 * channels {
2782 self.spread_decision = SPREAD_NORMAL;
2783 } else {
2784 let update_hf = lm == mode.max_lm;
2785 let spread_weights = [32i32; 21];
2786 self.spread_decision = spreading_decision(
2787 mode,
2788 x,
2789 &mut self.tonal_average,
2790 self.spread_decision,
2791 &mut self.hf_average,
2792 &mut self.tapset_decision,
2793 update_hf,
2794 end,
2795 channels,
2796 (1 << lm) as usize,
2797 &spread_weights,
2798 );
2799 }
2800 rc.encode_icdf(self.spread_decision, &SPREAD_ICDF, 5);
2801 } else {
2802 self.spread_decision = SPREAD_NORMAL;
2803 }
2804
2805 let mut dynalloc_logp = 6i32;
2806 let total_bits_bitres = total_bits << BITRES;
2807 let mut total_boost = 0i32;
2808 let mut tell_frac = rc.tell_frac();
2809
2810 for i in start_band..end {
2811 let width =
2812 channels as i32 * (mode.e_bands[i + 1] - mode.e_bands[i]) as i32 * (1 << lm);
2813 let quanta = (width << BITRES).min((6 << BITRES).max(width));
2814 let mut dynalloc_loop_logp = dynalloc_logp;
2815 let mut boost = 0i32;
2816 let mut j = 0i32;
2817
2818 while tell_frac + (dynalloc_loop_logp << BITRES) < total_bits_bitres - total_boost
2819 && boost < cap[i]
2820 {
2821 let flag = j < offsets[i];
2822 rc.encode_bit_logp(flag, dynalloc_loop_logp as u32);
2823 tell_frac = rc.tell_frac();
2824 if !flag {
2825 break;
2826 }
2827 boost += quanta;
2828 total_boost += quanta;
2829 dynalloc_loop_logp = 1;
2830 j += 1;
2831 }
2832
2833 if j > 0 {
2834 dynalloc_logp = 2.max(dynalloc_logp - 1);
2835 }
2836 offsets[i] = boost;
2837 }
2838
2839 let alloc_trim = alloc_trim_analysis(
2840 mode,
2841 x,
2842 band_log_e,
2843 end,
2844 lm as i32,
2845 channels,
2846 frame_size,
2847 &mut stereo_saving,
2848 tf_estimate,
2849 self.intensity,
2850 0.0,
2851 equiv_rate,
2852 );
2853 if rc.tell_frac() + (6 << BITRES) <= total_bits_bitres - total_boost {
2854 rc.encode_icdf(alloc_trim, &TRIM_ICDF, 7);
2855 }
2856 if self.vbr && self.bitrate != OPUS_BITRATE_MAX {
2859 let vbr_rate = bitrate_to_bits(self.bitrate, mode.fs, frame_size as i32) << BITRES;
2860 let hybrid = start_band != 0;
2861 let lm_diff = mode.max_lm as i32 - lm as i32;
2862 let mut base_target = if !hybrid {
2863 vbr_rate - ((40 * channels as i32 + 20) << BITRES)
2864 } else {
2865 (0).max(vbr_rate - ((9 * channels as i32 + 4) << BITRES))
2866 };
2867 if self.constrained_vbr {
2868 base_target += self.vbr_offset >> lm_diff;
2869 }
2870 let tot_boost = total_boost;
2871 let cur_tell_frac = rc.tell_frac();
2872 let min_allowed = {
2875 let a = ((cur_tell_frac + tot_boost + (1 << (BITRES + 3)) - 1) >> (BITRES + 3)) + 2;
2876 if hybrid {
2877 let b = (tell_initial_frac + (37 << BITRES) + tot_boost
2878 + (1 << (BITRES + 3))
2879 - 1)
2880 >> (BITRES + 3);
2881 a.max(b)
2882 } else {
2883 a
2884 }
2885 };
2886 let max_depth = compute_max_depth(
2888 mode,
2889 band_log_e,
2890 nb_ebands,
2891 channels,
2892 end,
2893 self.lsb_depth,
2894 );
2895 let mut target = if !hybrid {
2896 compute_vbr(
2897 mode,
2898 &self.analysis,
2899 base_target,
2900 lm as i32,
2901 self.bitrate,
2902 self.last_coded_bands,
2903 channels as i32,
2904 self.intensity,
2905 self.constrained_vbr,
2906 stereo_saving,
2907 tot_boost,
2908 tf_estimate,
2909 0, max_depth,
2911 false,
2912 false,
2913 0.0,
2914 0.0, )
2916 } else {
2917 let mut t = base_target;
2918 t += ((tf_estimate - 0.25) * 50.0 * (1 << BITRES) as f32) as i32;
2919 if tf_estimate > 0.7 {
2920 t = t.max(50 << BITRES);
2921 }
2922 t
2923 };
2924 target += cur_tell_frac;
2925 let mut nb_available = ((target + (1 << (BITRES + 2))) >> (BITRES + 3)) as usize;
2926 nb_available = nb_available.max(min_allowed as usize);
2927 nb_available = nb_available.min(nb_compressed_bytes);
2928 let mut delta = target - vbr_rate;
2929 target = (nb_available as i32) << (BITRES + 3);
2930 if silence {
2931 nb_available = 2;
2932 target = (2 * 8) << BITRES;
2933 delta = 0;
2934 }
2935 if self.vbr_count < 970 {
2937 self.vbr_count += 1;
2938 }
2939 let alpha = if self.vbr_count < 970 {
2940 let v = self.vbr_count + 20;
2942 32768 / v } else {
2944 33 };
2946 if self.constrained_vbr {
2947 self.vbr_reservoir += target - vbr_rate;
2948 let delta_scaled = delta * (1 << lm_diff);
2950 let delta_minus = delta_scaled - self.vbr_offset - self.vbr_drift;
2951 self.vbr_drift += ((alpha as i64 * delta_minus as i64) >> 15) as i32;
2952 self.vbr_offset = -self.vbr_drift;
2953 }
2954 if self.constrained_vbr && self.vbr_reservoir < 0 {
2955 let adjust = (-self.vbr_reservoir) / (8 << BITRES);
2956 if !silence {
2957 nb_available = (nb_available as i32 + adjust) as usize;
2958 }
2959 self.vbr_reservoir = 0;
2960 }
2961 nb_compressed_bytes = nb_compressed_bytes.min(nb_available);
2962 total_bits = (nb_compressed_bytes * 8) as i32;
2963 rc.shrink(nb_compressed_bytes as u32);
2964 }
2965
2966 let mut intensity = self.intensity;
2967 self.w_pulses[..nb_ebands].fill(0);
2968 let pulses = &mut self.w_pulses[..nb_ebands];
2969
2970 let stereo = channels > 1;
2971 let ebands_stereo = if stereo {
2972 nb_ebands * channels
2973 } else {
2974 nb_ebands
2975 };
2976 self.w_fine_priority[..ebands_stereo].fill(0);
2977 let fine_priority = &mut self.w_fine_priority[..ebands_stereo];
2978 self.w_ebits[..ebands_stereo].fill(0);
2979 let ebits = &mut self.w_ebits[..ebands_stereo];
2980 let mut balance = 0;
2981
2982 let mut alloc_bits = (total_bits << BITRES) - rc.tell_frac() - 1;
2985 let anti_collapse_rsv = if is_transient && lm >= 2 {
2986 if alloc_bits >= ((lm as i32 + 2) << BITRES) {
2987 1i32 << BITRES
2988 } else {
2989 0
2990 }
2991 } else {
2992 0
2993 };
2994 alloc_bits -= anti_collapse_rsv;
2995
2996 self.last_coded_bands = clt_compute_allocation(
2997 mode,
2998 start_band,
2999 end,
3000 offsets,
3001 cap,
3002 alloc_trim,
3003 &mut intensity,
3004 &mut dual_stereo_val,
3005 alloc_bits,
3006 &mut balance,
3007 pulses,
3008 ebits,
3009 fine_priority,
3010 channels as i32,
3011 lm as i32,
3012 rc,
3013 true,
3014 0,
3015 nb_ebands as i32 - 1,
3016 );
3017
3018 quant_fine_energy(
3019 mode,
3020 start_band,
3021 end,
3022 &mut self.old_band_e,
3023 error,
3024 ebits,
3025 rc,
3026 channels,
3027 );
3028
3029 self.w_collapse_masks[..nb_ebands * channels].fill(0);
3030 let collapse_masks = &mut self.w_collapse_masks[..nb_ebands * channels];
3031 let (x_split, y_split) = x.split_at_mut(frame_size);
3032 let y_opt = if channels == 2 { Some(y_split) } else { None };
3033
3034 let mut dual_stereo = dual_stereo_val != 0;
3035
3036 let theta_rdo = channels == 2 && !dual_stereo && self.complexity >= 8;
3037 let resynth = theta_rdo;
3038
3039 quant_all_bands(
3040 true,
3041 mode,
3042 start_band,
3043 end,
3044 x_split,
3045 y_opt,
3046 collapse_masks,
3047 band_e,
3048 pulses,
3049 short_blocks,
3050 self.spread_decision,
3051 &mut dual_stereo,
3052 intensity as usize,
3053 tf_res,
3054 (total_bits << BITRES) - anti_collapse_rsv,
3055 &mut balance,
3056 rc,
3057 lm as i32,
3058 self.last_coded_bands,
3059 resynth,
3060 false,
3061 &mut 0u32,
3062 );
3063
3064 if anti_collapse_rsv > 0 {
3065 let anti_collapse_on = if self.consec_transient < 2 {
3066 1u32
3067 } else {
3068 0u32
3069 };
3070 rc.enc_bits(anti_collapse_on, 1);
3071 }
3072
3073 quant_energy_finalise(
3074 mode,
3075 start_band,
3076 end,
3077 &mut self.old_band_e,
3078 error,
3079 ebits,
3080 fine_priority,
3081 total_bits - rc.tell(),
3082 rc,
3083 channels,
3084 );
3085
3086 if silence {
3087 for v in self.old_band_e[..channels * nb_ebands].iter_mut() {
3088 *v = -28.0;
3089 }
3090 }
3091
3092 if resynth {
3093 let band_amp_synth = &mut self.w_band_amp_synth[..nb_ebands * channels];
3094 log2amp(mode, end, band_amp_synth, &self.old_band_e, channels);
3095 self.w_freq[..frame_size * channels].fill(0.0);
3098 let freq_synth = &mut self.w_freq[..frame_size * channels];
3099 denormalise_bands(
3100 mode,
3101 x,
3102 freq_synth,
3103 band_amp_synth,
3104 start_band,
3105 end,
3106 channels,
3107 (1 << lm) as usize,
3108 );
3109 let (syn_shift, syn_b) = if is_transient {
3110 (mode.max_lm, 1 << lm)
3111 } else {
3112 (mode.max_lm - lm, 1)
3113 };
3114 let syn_n = frame_size / syn_b;
3115 let decode_buf_size = 2048;
3116
3117 for c in 0..channels {
3118 let co = c * syn_mem_size;
3119 self.enc_decode_mem
3120 .copy_within(co + frame_size..co + decode_buf_size + overlap, co);
3121 }
3122
3123 for c in 0..channels {
3124 let co = c * syn_mem_size;
3125 let out_syn_idx = decode_buf_size - frame_size;
3126 for bi in 0..syn_b {
3127 let syn_stride = if is_transient {
3128 mode.short_mdct_size
3129 } else {
3130 syn_n
3131 };
3132 mode.mdct.backward(
3133 &freq_synth[c * frame_size + bi..],
3134 &mut self.enc_decode_mem[co + out_syn_idx + bi * syn_stride..],
3135 mode.window,
3136 overlap,
3137 syn_shift,
3138 syn_b,
3139 );
3140 }
3141 }
3142 }
3143
3144 self.last_band_log_e.copy_from_slice(&self.old_band_e);
3145
3146 if !is_transient {
3147 self.old_band_e3.copy_from_slice(&self.old_band_e2);
3148 self.old_band_e2.copy_from_slice(&self.old_band_e);
3149 } else {
3150 for i in 0..channels * nb_ebands {
3151 self.old_band_e2[i] = self.old_band_e2[i].min(self.old_band_e[i]);
3152 }
3153 }
3154
3155 rc.pad_to_bits(total_bits);
3156
3157 if pf_on {
3158 self.prefilter_period = pitch_index;
3159 self.prefilter_gain = gain1;
3160 self.prefilter_tapset = self.tapset_decision;
3161 } else {
3162 self.prefilter_period = COMBFILTER_MINPERIOD;
3163 self.prefilter_gain = 0.0;
3164 self.prefilter_tapset = self.tapset_decision;
3165 }
3166
3167 if is_transient {
3168 self.consec_transient += 1;
3169 } else {
3170 self.consec_transient = 0;
3171 }
3172 }
3173}
3174
3175pub struct CeltDecoder {
3176 mode: &'static CeltMode,
3177 channels: usize,
3178 stream_channels: usize,
3181 downsample: usize,
3184 decode_mem: FixedVec<f32, CELT_DECODE_MEM>,
3185 old_band_e: FixedVec<f32, CELT_NB_X_CH>,
3186 preemph_mem: FixedVec<f32, CELT_MAX_CHANNELS>,
3187 prefilter_mem: FixedVec<f32, CELT_PREFILTER_MEM>,
3188 prefilter_period: usize,
3189 prefilter_period_old: usize,
3190 prefilter_gain: f32,
3191 prefilter_gain_old: f32,
3192 prefilter_tapset: i32,
3193 prefilter_tapset_old: i32,
3194 old_band_e2: FixedVec<f32, CELT_NB_X_CH>,
3195 old_band_e3: FixedVec<f32, CELT_NB_X_CH>,
3196 rng: u32,
3197
3198 w_tf_res: FixedVec<i32, CELT_NB_EBANDS>,
3199 w_cap: FixedVec<i32, CELT_NB_EBANDS>,
3200 w_offsets: FixedVec<i32, CELT_NB_EBANDS>,
3201 w_pulses: FixedVec<i32, CELT_NB_EBANDS>,
3202 w_ebits: FixedVec<i32, CELT_NB_X_CH>,
3203 w_fine_priority: FixedVec<i32, CELT_NB_X_CH>,
3204 w_x: FixedVec<f32, CELT_W_X_DEC>,
3205 w_collapse_masks: FixedVec<u32, CELT_NB_X_CH>,
3206 w_freq: FixedVec<f32, CELT_W_FREQ_DEC>,
3207 w_band_amp: FixedVec<f32, CELT_NB_X_CH>,
3208 w_pcm_frame: FixedVec<f32, DECODE_BUFFER_SIZE>,
3209 w_post: FixedVec<f32, { DECODE_BUFFER_SIZE + COMBFILTER_MAXPERIOD }>,
3210}
3211
3212impl CeltDecoder {
3213 pub fn new(mode: &'static CeltMode, channels: usize, sampling_rate: i32) -> Self {
3217 let mut decoder = MaybeUninit::uninit();
3218 unsafe {
3219 Self::write_new(decoder.as_mut_ptr(), mode, channels, sampling_rate);
3220 decoder.assume_init()
3221 }
3222 }
3223
3224 pub(crate) unsafe fn write_new(
3225 this: *mut Self,
3226 mode: &'static CeltMode,
3227 channels: usize,
3228 sampling_rate: i32,
3229 ) {
3230 assert!(
3233 (1..=2).contains(&channels),
3234 "CeltDecoder::new: channels must be 1 or 2 (got {channels})"
3235 );
3236 let overlap = mode.overlap;
3237 let nb_ebands = mode.nb_ebands;
3238 let nb_x_ch = nb_ebands * CELT_MAX_CHANNELS;
3242 let dec_frame_x_ch = DECODE_BUFFER_SIZE * CELT_MAX_CHANNELS;
3243 unsafe {
3244 (&raw mut (*this).mode).write(mode);
3245 (&raw mut (*this).channels).write(channels);
3246 (&raw mut (*this).stream_channels).write(channels);
3247 (&raw mut (*this).downsample).write(resampling_factor(sampling_rate));
3248 FixedVec::write_from_value(
3249 &raw mut (*this).decode_mem,
3250 0.0,
3251 channels * (DECODE_BUFFER_SIZE + overlap),
3252 );
3253 FixedVec::write_from_value(&raw mut (*this).old_band_e, 0.0, nb_x_ch);
3254 FixedVec::write_from_value(&raw mut (*this).preemph_mem, 0.0, channels);
3255 FixedVec::write_from_value(
3256 &raw mut (*this).prefilter_mem,
3257 0.0,
3258 channels * COMBFILTER_MAXPERIOD,
3259 );
3260 (&raw mut (*this).prefilter_period).write(COMBFILTER_MINPERIOD);
3261 (&raw mut (*this).prefilter_period_old).write(COMBFILTER_MINPERIOD);
3262 (&raw mut (*this).prefilter_gain).write(0.0);
3263 (&raw mut (*this).prefilter_gain_old).write(0.0);
3264 (&raw mut (*this).prefilter_tapset).write(0);
3265 (&raw mut (*this).prefilter_tapset_old).write(0);
3266 FixedVec::write_from_value(&raw mut (*this).old_band_e2, -28.0, nb_x_ch);
3268 FixedVec::write_from_value(&raw mut (*this).old_band_e3, -28.0, nb_x_ch);
3269 (&raw mut (*this).rng).write(0);
3270 FixedVec::write_from_value(&raw mut (*this).w_tf_res, 0, nb_ebands);
3271 FixedVec::write_from_value(&raw mut (*this).w_cap, 0, nb_ebands);
3272 FixedVec::write_from_value(&raw mut (*this).w_offsets, 0, nb_ebands);
3273 FixedVec::write_from_value(&raw mut (*this).w_pulses, 0, nb_ebands);
3274 FixedVec::write_from_value(&raw mut (*this).w_ebits, 0, nb_x_ch);
3275 FixedVec::write_from_value(&raw mut (*this).w_fine_priority, 0, nb_x_ch);
3276 FixedVec::write_from_value(
3277 &raw mut (*this).w_x,
3278 0.0,
3279 dec_frame_x_ch + STRIDE_ACCESS_PAD,
3280 );
3281 FixedVec::write_from_value(&raw mut (*this).w_collapse_masks, 0, nb_x_ch);
3282 FixedVec::write_from_value(&raw mut (*this).w_freq, 0.0, dec_frame_x_ch + 4); FixedVec::write_from_value(&raw mut (*this).w_band_amp, 0.0, nb_x_ch);
3284 FixedVec::write_from_value(&raw mut (*this).w_pcm_frame, 0.0, DECODE_BUFFER_SIZE);
3285 FixedVec::write_from_value(
3286 &raw mut (*this).w_post,
3287 0.0,
3288 DECODE_BUFFER_SIZE + COMBFILTER_MAXPERIOD,
3289 );
3290 }
3291 }
3292
3293 pub fn decode(&mut self, compressed: &[u8], frame_size: usize, pcm: &mut [f32]) -> usize {
3294 self.decode_impl(compressed, frame_size, pcm, 0, self.mode.nb_ebands)
3295 }
3296
3297 pub fn set_stream_channels(&mut self, channels: usize) {
3301 assert!(
3302 (1..=CELT_MAX_CHANNELS).contains(&channels),
3303 "CeltDecoder::set_stream_channels: channels must be 1 or 2 (got {channels})"
3304 );
3305 self.stream_channels = channels;
3306 }
3307
3308 pub fn reset_state(&mut self) {
3311 self.decode_mem.fill(0.0);
3312 self.old_band_e.fill(0.0);
3313 self.preemph_mem.fill(0.0);
3314 self.prefilter_mem.fill(0.0);
3315 self.prefilter_period = COMBFILTER_MINPERIOD;
3316 self.prefilter_period_old = COMBFILTER_MINPERIOD;
3317 self.prefilter_gain = 0.0;
3318 self.prefilter_gain_old = 0.0;
3319 self.prefilter_tapset = 0;
3320 self.prefilter_tapset_old = 0;
3321 self.old_band_e2.fill(-28.0);
3323 self.old_band_e3.fill(-28.0);
3324 self.rng = 0;
3325 }
3326
3327 pub fn decode_with_start_band(
3328 &mut self,
3329 compressed: &[u8],
3330 frame_size: usize,
3331 pcm: &mut [f32],
3332 start_band: usize,
3333 ) -> usize {
3334 self.decode_impl(compressed, frame_size, pcm, start_band, self.mode.nb_ebands)
3335 }
3336
3337 pub fn decode_from_range_coder(
3338 &mut self,
3339 rc: &mut RangeCoder,
3340 total_bits: i32,
3341 frame_size: usize,
3342 pcm: &mut [f32],
3343 start_band: usize,
3344 ) -> usize {
3345 self.decode_impl_from_rc(
3346 rc,
3347 total_bits,
3348 frame_size,
3349 pcm,
3350 start_band,
3351 self.mode.nb_ebands,
3352 )
3353 }
3354
3355 pub fn decode_from_range_coder_with_band_range(
3356 &mut self,
3357 rc: &mut RangeCoder,
3358 total_bits: i32,
3359 frame_size: usize,
3360 pcm: &mut [f32],
3361 start_band: usize,
3362 end_band: usize,
3363 ) -> usize {
3364 self.decode_impl_from_rc(rc, total_bits, frame_size, pcm, start_band, end_band)
3365 }
3366
3367 fn decode_impl(
3368 &mut self,
3369 compressed: &[u8],
3370 frame_size: usize,
3371 pcm: &mut [f32],
3372 start_band: usize,
3373 end_band: usize,
3374 ) -> usize {
3375 let total_bits = (compressed.len() * 8) as i32;
3376 let mut rc = RangeCoder::new_decoder(compressed);
3377 self.decode_impl_from_rc(&mut rc, total_bits, frame_size, pcm, start_band, end_band)
3378 }
3379
3380 fn decode_impl_from_rc(
3381 &mut self,
3382 rc: &mut RangeCoder,
3383 total_bits: i32,
3384 frame_size: usize,
3385 pcm: &mut [f32],
3386 start_band: usize,
3387 end_band: usize,
3388 ) -> usize {
3389 let mode = self.mode;
3390 let channels = self.stream_channels;
3393 let out_channels = self.channels;
3394 let nb_ebands = mode.nb_ebands;
3395 let end_band = end_band.min(nb_ebands).max(start_band);
3396 let overlap = mode.overlap;
3397
3398 let api_frame_size = frame_size;
3402 let frame_size = frame_size * self.downsample;
3403
3404 let mut lm_matched = false;
3409 for cand in 0..=mode.max_lm {
3410 if mode.short_mdct_size << cand == frame_size {
3411 lm_matched = true;
3412 break;
3413 }
3414 }
3415 if !lm_matched || frame_size < mode.short_mdct_size {
3416 return 0;
3417 }
3418
3419 if pcm.len() < api_frame_size * out_channels {
3423 return 0;
3424 }
3425
3426 let mut lm = 0;
3427 while (mode.short_mdct_size << lm) != frame_size {
3428 lm += 1;
3429 if lm > mode.max_lm {
3430 break;
3431 }
3432 }
3433 if (mode.short_mdct_size << lm) != frame_size {
3434 lm = 0;
3435 }
3436
3437 if channels == 1 {
3440 let (first, second) = self.old_band_e.split_at_mut(nb_ebands);
3441 for (e, &e2) in first.iter_mut().zip(&second[..nb_ebands]) {
3442 *e = e.max(e2);
3443 }
3444 }
3445
3446 let mut tell = rc.tell();
3447 let mut silence = false;
3448 if tell >= total_bits {
3449 silence = true;
3450 } else if tell == 1 {
3451 silence = rc.decode_bit_logp(15);
3452 }
3453 if silence {
3454 tell = total_bits;
3458 rc.nbits_total += tell - rc.tell();
3459 }
3460
3461 let mut pf_on = false;
3462 let mut pitch_index = COMBFILTER_MINPERIOD;
3463 let mut gain1 = 0.0f32;
3464 let mut prefilter_tapset = 0;
3465
3466 if start_band == 0 && !silence && rc.tell() + 16 <= total_bits {
3467 pf_on = rc.decode_bit_logp(1);
3468 if pf_on {
3469 let octave = rc.dec_uint(6);
3470 pitch_index = ((16 << octave) + rc.dec_bits(4 + octave)) as usize - 1;
3471 let qg = rc.dec_bits(3);
3472 if rc.tell() + 2 <= total_bits {
3473 prefilter_tapset = rc.decode_icdf(&TAPSET_ICDF, 2) as usize;
3474 }
3475 gain1 = 0.09375 * (qg as f32 + 1.0);
3476 }
3477 }
3478 if start_band != 0 {
3479 self.prefilter_gain = 0.0;
3480 }
3481
3482 let mut is_transient = false;
3483 if lm > 0 && rc.tell() + 3 <= total_bits {
3484 is_transient = rc.decode_bit_logp(3);
3485 }
3486 let short_blocks = is_transient;
3487
3488 let intra_ener = if rc.tell() + 3 <= total_bits {
3489 rc.decode_bit_logp(3)
3490 } else {
3491 false
3492 };
3493
3494 unquant_coarse_energy(
3495 mode,
3496 start_band,
3497 end_band,
3498 &mut self.old_band_e,
3499 intra_ener,
3500 rc,
3501 channels,
3502 lm,
3503 );
3504 self.w_tf_res[..nb_ebands].fill(0);
3505 let tf_res = &mut self.w_tf_res[..nb_ebands];
3506 tf_decode(start_band, end_band, is_transient, tf_res, lm as i32, rc);
3507
3508 let spread_decision = if rc.tell() + 4 <= total_bits {
3509 rc.decode_icdf(&SPREAD_ICDF, 5)
3510 } else {
3511 SPREAD_NORMAL
3512 };
3513
3514 self.w_cap[..nb_ebands].fill(0);
3515 let cap = &mut self.w_cap[..nb_ebands];
3516 for (i, cap_i) in cap.iter_mut().enumerate() {
3517 let n = (mode.e_bands[i + 1] - mode.e_bands[i]) << lm;
3518 *cap_i = ((mode.cache.caps[nb_ebands * (2 * lm + channels - 1) + i] as i32 + 64)
3519 * channels as i32
3520 * n as i32)
3521 >> 2;
3522 }
3523
3524 self.w_offsets[..nb_ebands].fill(0);
3525 let offsets = &mut self.w_offsets[..nb_ebands];
3526 let mut dynalloc_logp = 6i32;
3527 let mut total_bits_bitres = total_bits << BITRES;
3528 let mut tell_frac = rc.tell_frac();
3529 for i in start_band..end_band {
3530 let width =
3531 channels as i32 * (mode.e_bands[i + 1] - mode.e_bands[i]) as i32 * (1 << lm);
3532 let quanta = (width << BITRES).min((6i32 << BITRES).max(width));
3533 let mut dynalloc_loop_logp = dynalloc_logp;
3534 let mut boost = 0i32;
3535 while tell_frac + (dynalloc_loop_logp << BITRES) < total_bits_bitres && boost < cap[i] {
3536 let flag = rc.decode_bit_logp(dynalloc_loop_logp as u32);
3537 tell_frac = rc.tell_frac();
3538 if !flag {
3539 break;
3540 }
3541 boost += quanta;
3542 total_bits_bitres -= quanta;
3543 dynalloc_loop_logp = 1;
3544 }
3545 offsets[i] = boost;
3546 if boost > 0 {
3547 dynalloc_logp = dynalloc_logp.max(2) - 1;
3548 dynalloc_logp = dynalloc_logp.max(2);
3549 }
3550 }
3551
3552 let alloc_trim = if rc.tell_frac() + (6 << BITRES) <= total_bits_bitres {
3553 rc.decode_icdf(&TRIM_ICDF, 7)
3554 } else {
3555 5
3556 };
3557 let anti_collapse_rsv = if is_transient && lm >= 2 {
3558 let remaining = (total_bits << BITRES) - rc.tell_frac() - 1;
3559 if remaining >= ((lm as i32 + 2) << BITRES) {
3560 1i32 << BITRES
3561 } else {
3562 0
3563 }
3564 } else {
3565 0
3566 };
3567
3568 let mut intensity = 0;
3569 let mut dual_stereo_val = if channels == 2 { 1 } else { 0 };
3570 let mut balance = 0;
3571 self.w_pulses[..nb_ebands].fill(0);
3572 let pulses = &mut self.w_pulses[..nb_ebands];
3573
3574 let ebands_stereo = if channels > 1 {
3575 nb_ebands * channels
3576 } else {
3577 nb_ebands
3578 };
3579 self.w_fine_priority[..ebands_stereo].fill(0);
3580 let fine_priority = &mut self.w_fine_priority[..ebands_stereo];
3581 self.w_ebits[..ebands_stereo].fill(0);
3582 let ebits = &mut self.w_ebits[..ebands_stereo];
3583
3584 let alloc_bits = (total_bits << BITRES) - rc.tell_frac() - 1 - anti_collapse_rsv;
3585 let coded_bands = clt_compute_allocation(
3586 mode,
3587 start_band,
3588 end_band,
3589 offsets,
3590 cap,
3591 alloc_trim,
3592 &mut intensity,
3593 &mut dual_stereo_val,
3594 alloc_bits,
3595 &mut balance,
3596 pulses,
3597 ebits,
3598 fine_priority,
3599 channels as i32,
3600 lm as i32,
3601 rc,
3602 false,
3603 0,
3604 end_band as i32 - 1,
3605 );
3606
3607 unquant_fine_energy(
3608 mode,
3609 start_band,
3610 end_band,
3611 &mut self.old_band_e,
3612 ebits,
3613 rc,
3614 channels,
3615 );
3616
3617 if frame_size > DECODE_BUFFER_SIZE {
3623 return 0;
3624 }
3625
3626 self.w_x[..frame_size * channels].fill(0.0);
3627
3628 let x_pad_end = (frame_size * channels + STRIDE_ACCESS_PAD).min(self.w_x.len());
3629 let x = &mut self.w_x[..x_pad_end];
3630 self.w_collapse_masks[..nb_ebands * channels].fill(0);
3631 let collapse_masks = &mut self.w_collapse_masks[..nb_ebands * channels];
3632
3633 let (x_split, y_split) = x.split_at_mut(frame_size);
3634 let y_opt = if channels == 2 { Some(y_split) } else { None };
3635
3636 let mut dual_stereo = dual_stereo_val != 0;
3637 self.w_band_amp[..nb_ebands * channels].fill(0.0);
3638 let band_amp = &mut self.w_band_amp[..nb_ebands * channels];
3639 log2amp(mode, nb_ebands, band_amp, &self.old_band_e, channels);
3640 quant_all_bands(
3641 false,
3642 mode,
3643 start_band,
3644 end_band,
3645 x_split,
3646 y_opt,
3647 collapse_masks,
3648 band_amp,
3649 pulses,
3650 short_blocks,
3651 spread_decision,
3652 &mut dual_stereo,
3653 intensity as usize,
3654 tf_res,
3655 (total_bits << BITRES) - anti_collapse_rsv,
3656 &mut balance,
3657 rc,
3658 lm as i32,
3659 coded_bands,
3660 true,
3661 false,
3662 &mut self.rng,
3663 );
3664 let mut anti_collapse_on = false;
3666 if anti_collapse_rsv > 0 {
3667 anti_collapse_on = rc.dec_bits(1) != 0;
3668 }
3669 unquant_energy_finalise(
3670 mode,
3671 start_band,
3672 end_band,
3673 &mut self.old_band_e,
3674 ebits,
3675 fine_priority,
3676 total_bits - rc.tell(),
3677 rc,
3678 channels,
3679 );
3680 if anti_collapse_on {
3681 self.rng = crate::bands::anti_collapse(
3682 mode,
3683 x,
3684 collapse_masks,
3685 lm as i32,
3686 channels,
3687 frame_size,
3688 start_band,
3689 nb_ebands,
3690 &self.old_band_e,
3691 &self.old_band_e2,
3692 &self.old_band_e3,
3693 pulses,
3694 self.rng,
3695 );
3696 }
3697 if silence {
3698 for v in self.old_band_e[..channels * nb_ebands].iter_mut() {
3704 *v = -28.0;
3705 }
3706 }
3707 let freq_len = frame_size * channels.max(out_channels);
3714 self.w_freq[..freq_len].fill(0.0);
3715 let freq = &mut self.w_freq[..freq_len];
3716 if !silence {
3717 log2amp(mode, nb_ebands, band_amp, &self.old_band_e, channels);
3720 denormalise_bands(
3721 mode,
3722 x,
3723 freq,
3724 band_amp,
3725 start_band,
3726 end_band,
3727 channels,
3728 (1 << lm) as usize,
3729 );
3730 if self.downsample > 1 {
3734 let bound = frame_size / self.downsample;
3735 for c in 0..channels {
3736 for i in bound..frame_size {
3737 freq[c * frame_size + i] = 0.0;
3738 }
3739 }
3740 }
3741 }
3742 if channels == 1 && out_channels == 2 {
3747 freq.copy_within(..frame_size, frame_size);
3748 } else if channels == 2 && out_channels == 1 {
3749 let (left, right) = freq.split_at_mut(frame_size);
3750 for (l, &r) in left.iter_mut().zip(&right[..frame_size]) {
3751 *l = 0.5 * *l + 0.5 * r;
3752 }
3753 }
3754
3755 let (shift, b) = if short_blocks {
3756 (mode.max_lm, 1 << lm)
3757 } else {
3758 (mode.max_lm - lm, 1)
3759 };
3760 let n = frame_size / b;
3761
3762 for c in 0..out_channels {
3763 let channel_mem_offset = c * (DECODE_BUFFER_SIZE + overlap);
3764
3765 let mem_size = DECODE_BUFFER_SIZE + overlap;
3766 self.decode_mem.copy_within(
3767 channel_mem_offset + frame_size..channel_mem_offset + mem_size,
3768 channel_mem_offset,
3769 );
3770
3771 let out_syn_idx = DECODE_BUFFER_SIZE - frame_size;
3772
3773 for i in 0..b {
3774 let block_freq_idx = c * frame_size + i;
3775 let block_stride = if short_blocks {
3779 mode.short_mdct_size
3780 } else {
3781 n
3782 };
3783 let block_out_idx = channel_mem_offset + out_syn_idx + i * block_stride;
3784 let available_len = self.decode_mem.len() - block_out_idx;
3785 if available_len < n + overlap {
3786 panic!(
3787 "MDCT backward buffer too small: need {}, have {} (out_syn_idx={}, n={}, overlap={})",
3788 n + overlap,
3789 available_len,
3790 out_syn_idx,
3791 n,
3792 overlap
3793 );
3794 }
3795 self.mode.mdct.backward(
3796 &freq[block_freq_idx..],
3797 &mut self.decode_mem[block_out_idx..],
3798 mode.window,
3799 overlap,
3800 shift,
3801 b,
3802 );
3803 }
3804
3805 const SIG_SAT: f32 = 536870911.0;
3806 for i in 0..frame_size {
3807 let v = &mut self.decode_mem[channel_mem_offset + out_syn_idx + i];
3808 *v = v.clamp(-SIG_SAT, SIG_SAT);
3809 }
3810
3811 self.w_pcm_frame[..frame_size].fill(0.0);
3812 let pcm_frame = &mut self.w_pcm_frame[..frame_size];
3813
3814 pcm_frame.copy_from_slice(
3815 &self.decode_mem[channel_mem_offset + out_syn_idx
3816 ..channel_mem_offset + out_syn_idx + frame_size],
3817 );
3818 if pf_on || self.prefilter_gain > 0.0 || self.prefilter_gain_old > 0.0 {
3819 self.w_post[..COMBFILTER_MAXPERIOD].copy_from_slice(
3824 &self.prefilter_mem[c * COMBFILTER_MAXPERIOD..(c + 1) * COMBFILTER_MAXPERIOD],
3825 );
3826 self.w_post[COMBFILTER_MAXPERIOD..COMBFILTER_MAXPERIOD + frame_size]
3827 .copy_from_slice(pcm_frame);
3828
3829 let short_n = mode.short_mdct_size;
3830 comb_filter_inplace(
3833 &mut self.w_post,
3834 COMBFILTER_MAXPERIOD,
3835 self.prefilter_period_old,
3836 self.prefilter_period,
3837 short_n,
3838 self.prefilter_gain_old,
3839 self.prefilter_gain,
3840 self.prefilter_tapset_old,
3841 self.prefilter_tapset,
3842 mode.window,
3843 overlap,
3844 );
3845 if lm != 0 {
3846 comb_filter_inplace(
3848 &mut self.w_post,
3849 COMBFILTER_MAXPERIOD + short_n,
3850 self.prefilter_period,
3851 pitch_index,
3852 frame_size - short_n,
3853 self.prefilter_gain,
3854 gain1,
3855 self.prefilter_tapset,
3856 prefilter_tapset as i32,
3857 mode.window,
3858 overlap,
3859 );
3860 }
3861
3862 pcm_frame.copy_from_slice(
3863 &self.w_post[COMBFILTER_MAXPERIOD..COMBFILTER_MAXPERIOD + frame_size],
3864 );
3865
3866 self.decode_mem[channel_mem_offset + out_syn_idx
3867 ..channel_mem_offset + out_syn_idx + frame_size]
3868 .copy_from_slice(pcm_frame);
3869 }
3870 let mut new_mem = [0.0f32; COMBFILTER_MAXPERIOD];
3871 if frame_size >= COMBFILTER_MAXPERIOD {
3872 new_mem.copy_from_slice(&pcm_frame[frame_size - COMBFILTER_MAXPERIOD..frame_size]);
3873 } else {
3874 new_mem[..COMBFILTER_MAXPERIOD - frame_size].copy_from_slice(
3875 &self.prefilter_mem
3876 [c * COMBFILTER_MAXPERIOD + frame_size..(c + 1) * COMBFILTER_MAXPERIOD],
3877 );
3878 new_mem[COMBFILTER_MAXPERIOD - frame_size..].copy_from_slice(pcm_frame);
3879 }
3880 self.prefilter_mem[c * COMBFILTER_MAXPERIOD..(c + 1) * COMBFILTER_MAXPERIOD]
3881 .copy_from_slice(&new_mem);
3882
3883 let coef = mode.preemph[0];
3884 let mut m = self.preemph_mem[c];
3885 const VERY_SMALL: f32 = 1e-30f32;
3886 let ds = self.downsample;
3887 if ds == 1 {
3888 for i in 0..frame_size {
3889 let x = pcm_frame[i];
3890 let val = (x + VERY_SMALL + m).clamp(-SIG_SAT, SIG_SAT);
3891 pcm[c * api_frame_size + i] = val * (1.0 / 32768.0);
3892 m = val * coef;
3893 }
3894 } else {
3895 for i in 0..frame_size {
3898 let x = pcm_frame[i];
3899 let val = (x + VERY_SMALL + m).clamp(-SIG_SAT, SIG_SAT);
3900 if i % ds == 0 {
3901 pcm[c * api_frame_size + i / ds] = val * (1.0 / 32768.0);
3902 }
3903 m = val * coef;
3904 }
3905 }
3906 self.preemph_mem[c] = m;
3907 }
3908
3909 self.prefilter_period_old = self.prefilter_period;
3910 self.prefilter_gain_old = self.prefilter_gain;
3911 self.prefilter_tapset_old = self.prefilter_tapset;
3912
3913 if pf_on {
3914 self.prefilter_period = pitch_index;
3915 self.prefilter_gain = gain1;
3916 self.prefilter_tapset = prefilter_tapset as i32;
3917 } else {
3918 self.prefilter_period = COMBFILTER_MINPERIOD;
3919 self.prefilter_gain = 0.0;
3920 self.prefilter_tapset = 0;
3921 }
3922
3923 if lm > 0 {
3924 self.prefilter_period_old = self.prefilter_period;
3925 self.prefilter_gain_old = self.prefilter_gain;
3926 self.prefilter_tapset_old = self.prefilter_tapset;
3927 }
3928
3929 if channels == 1 {
3930 self.old_band_e.copy_within(..nb_ebands, nb_ebands);
3931 }
3932 if !is_transient {
3934 self.old_band_e3.copy_from_slice(&self.old_band_e2);
3935 self.old_band_e2.copy_from_slice(&self.old_band_e);
3936 } else {
3937 for (e2, &e) in self.old_band_e2.iter_mut().zip(self.old_band_e.iter()) {
3938 *e2 = e2.min(e);
3939 }
3940 }
3941 for c in 0..CELT_MAX_CHANNELS {
3945 for i in (0..start_band).chain(end_band..nb_ebands) {
3946 self.old_band_e[c * nb_ebands + i] = 0.0;
3947 self.old_band_e2[c * nb_ebands + i] = -28.0;
3948 self.old_band_e3[c * nb_ebands + i] = -28.0;
3949 }
3950 }
3951
3952 self.rng = rc.rng;
3953
3954 api_frame_size
3955 }
3956}
3957
3958#[cfg(all(test, feature = "std"))]
3959mod tests {
3960 use super::*;
3961 use crate::{modes, range_coder::RangeCoder};
3962
3963 #[test]
3981 #[should_panic]
3982 fn test_celt_frame_size_48_panics_confirms_crash_path() {
3983 let mode = modes::default_mode();
3984 let mut enc = CeltEncoder::new(mode, 1);
3985 let pcm = vec![0.0f32; 48 + mode.overlap]; let mut rc = RangeCoder::new_encoder(100);
3990 enc.encode_with_budget(&pcm, 48, &mut rc, 0, 800);
3991 }
3992
3993 #[test]
3998 fn cancelled_prefilter_still_fades_out_previous_filter() {
3999 let mode = modes::default_mode();
4000 let (n, overlap, max_period) = (960, mode.overlap, COMBFILTER_MAXPERIOD);
4001 let mut mem: Vec<f32> = (0..max_period)
4002 .map(|i| (i as f32 * 0.3).sin() * 1000.0)
4003 .collect();
4004 let mut in_buf = vec![0.0f32; n + overlap];
4005 let mut pre = vec![0.0f32; max_period + n];
4006 let mut pitch_buf = vec![0.0f32; (max_period + n) >> 1];
4007 let (mut before, mut after) = ([0.0f32], [0.0f32]);
4008 let (pf_on, gain, _) = run_prefilter(
4009 &mut in_buf,
4010 &mut mem,
4011 100,
4012 0.5,
4013 0,
4014 0,
4015 mode.window,
4016 1,
4017 n,
4018 overlap,
4019 &mut pre,
4020 &mut pitch_buf,
4021 &mut before,
4022 &mut after,
4023 &AnalysisInfo::default(),
4024 0,
4025 0.0,
4026 100,
4027 -1.0,
4028 0.0,
4029 9,
4030 );
4031 assert!(!pf_on && gain == 0.0, "expected a cancelled filter");
4032 let body = &in_buf[overlap..];
4033 assert!(
4034 body[..overlap].iter().any(|&v| v.abs() > 1.0),
4035 "previous filter was not faded out over the overlap"
4036 );
4037 assert!(
4038 body[overlap..].iter().all(|&v| v == 0.0),
4039 "frame past the overlap must be the unfiltered input"
4040 );
4041 }
4042}