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