1use num_traits::Zero;
2
3pub mod arch_h {
4 pub type opus_val32 = f32;
5 pub type opus_val64 = f32;
6}
7
8#[derive(Copy, Clone)]
9#[repr(C)]
10pub struct AnalysisInfo {
11 pub valid: i32,
12 pub tonality: f32,
13 pub tonality_slope: f32,
14 pub noisiness: f32,
15 pub activity: f32,
16 pub music_prob: f32,
17 pub music_prob_min: f32,
18 pub music_prob_max: f32,
19 pub bandwidth: i32,
20 pub activity_probability: f32,
21 pub max_pitch_ratio: f32,
22 pub leak_boost: [u8; 19],
23}
24pub const LEAK_BANDS: i32 = 19;
25
26pub type downmix_func =
27 Option<unsafe fn(*const core::ffi::c_void, *mut opus_val32, i32, i32, i32, i32, i32) -> ()>;
28
29#[derive(Copy, Clone)]
30#[repr(C)]
31pub struct TonalityAnalysisState {
32 pub arch: i32,
33 pub application: i32,
34 pub Fs: i32,
35 pub angle: [f32; 240],
36 pub d_angle: [f32; 240],
37 pub d2_angle: [f32; 240],
38 pub inmem: [opus_val32; 720],
39 pub mem_fill: i32,
40 pub prev_band_tonality: [f32; 18],
41 pub prev_tonality: f32,
42 pub prev_bandwidth: i32,
43 pub E: [[f32; 18]; 8],
44 pub logE: [[f32; 18]; 8],
45 pub lowE: [f32; 18],
46 pub highE: [f32; 18],
47 pub meanE: [f32; 19],
48 pub mem: [f32; 32],
49 pub cmean: [f32; 8],
50 pub std: [f32; 9],
51 pub Etracker: f32,
52 pub lowECount: f32,
53 pub E_count: i32,
54 pub count: i32,
55 pub analysis_offset: i32,
56 pub write_pos: i32,
57 pub read_pos: i32,
58 pub read_subframe: i32,
59 pub hp_ener_accum: f32,
60 pub initialized: i32,
61 pub rnn_state: [f32; 32],
62 pub downmix_state: [opus_val32; 3],
63 pub info: [AnalysisInfo; 100],
64}
65pub const ANALYSIS_BUF_SIZE: i32 = 720;
66pub const DETECT_SIZE: i32 = 100;
67pub const NB_FRAMES: i32 = 8;
68pub const NB_TBANDS: i32 = 18;
69pub mod xmmintrin_h {
70 #[cfg(target_arch = "x86")]
71 pub use core::arch::x86::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss};
72
73}
74pub mod math_h {
75 pub const M_PI: f64 = 3.14159265358979323846f64;
76}
77pub mod cpu_support_h {
78 #[inline]
79 pub unsafe fn opus_select_arch() -> i32 {
80 return 0;
81 }
82}
83pub use self::arch_h::{opus_val32, opus_val64};
84pub use self::cpu_support_h::opus_select_arch;
85pub use self::math_h::M_PI;
86use crate::celt::float_cast::float2int;
87use crate::celt::kiss_fft::{kiss_fft_cpx, opus_fft_c};
88use crate::celt::mathops::fast_atan2f;
89use crate::celt::modes::OpusCustomMode;
90
91use crate::externs::{memcpy, memmove, memset};
92use crate::src::mlp::{compute_dense, compute_gru};
93use crate::src::mlp_data::{layer0, layer1, layer2};
94use crate::src::opus_encoder::is_digital_silence;
95
96static mut dct_table: [f32; 128] = [
97 0.250000f32,
98 0.250000f32,
99 0.250000f32,
100 0.250000f32,
101 0.250000f32,
102 0.250000f32,
103 0.250000f32,
104 0.250000f32,
105 0.250000f32,
106 0.250000f32,
107 0.250000f32,
108 0.250000f32,
109 0.250000f32,
110 0.250000f32,
111 0.250000f32,
112 0.250000f32,
113 0.351851f32,
114 0.338330f32,
115 0.311806f32,
116 0.273300f32,
117 0.224292f32,
118 0.166664f32,
119 0.102631f32,
120 0.034654f32,
121 -0.034654f32,
122 -0.102631f32,
123 -0.166664f32,
124 -0.224292f32,
125 -0.273300f32,
126 -0.311806f32,
127 -0.338330f32,
128 -0.351851f32,
129 0.346760f32,
130 0.293969f32,
131 0.196424f32,
132 0.068975f32,
133 -0.068975f32,
134 -0.196424f32,
135 -0.293969f32,
136 -0.346760f32,
137 -0.346760f32,
138 -0.293969f32,
139 -0.196424f32,
140 -0.068975f32,
141 0.068975f32,
142 0.196424f32,
143 0.293969f32,
144 0.346760f32,
145 0.338330f32,
146 0.224292f32,
147 0.034654f32,
148 -0.166664f32,
149 -0.311806f32,
150 -0.351851f32,
151 -0.273300f32,
152 -0.102631f32,
153 0.102631f32,
154 0.273300f32,
155 0.351851f32,
156 0.311806f32,
157 0.166664f32,
158 -0.034654f32,
159 -0.224292f32,
160 -0.338330f32,
161 0.326641f32,
162 0.135299f32,
163 -0.135299f32,
164 -0.326641f32,
165 -0.326641f32,
166 -0.135299f32,
167 0.135299f32,
168 0.326641f32,
169 0.326641f32,
170 0.135299f32,
171 -0.135299f32,
172 -0.326641f32,
173 -0.326641f32,
174 -0.135299f32,
175 0.135299f32,
176 0.326641f32,
177 0.311806f32,
178 0.034654f32,
179 -0.273300f32,
180 -0.338330f32,
181 -0.102631f32,
182 0.224292f32,
183 0.351851f32,
184 0.166664f32,
185 -0.166664f32,
186 -0.351851f32,
187 -0.224292f32,
188 0.102631f32,
189 0.338330f32,
190 0.273300f32,
191 -0.034654f32,
192 -0.311806f32,
193 0.293969f32,
194 -0.068975f32,
195 -0.346760f32,
196 -0.196424f32,
197 0.196424f32,
198 0.346760f32,
199 0.068975f32,
200 -0.293969f32,
201 -0.293969f32,
202 0.068975f32,
203 0.346760f32,
204 0.196424f32,
205 -0.196424f32,
206 -0.346760f32,
207 -0.068975f32,
208 0.293969f32,
209 0.273300f32,
210 -0.166664f32,
211 -0.338330f32,
212 0.034654f32,
213 0.351851f32,
214 0.102631f32,
215 -0.311806f32,
216 -0.224292f32,
217 0.224292f32,
218 0.311806f32,
219 -0.102631f32,
220 -0.351851f32,
221 -0.034654f32,
222 0.338330f32,
223 0.166664f32,
224 -0.273300f32,
225];
226static mut analysis_window: [f32; 240] = [
227 0.000043f32,
228 0.000171f32,
229 0.000385f32,
230 0.000685f32,
231 0.001071f32,
232 0.001541f32,
233 0.002098f32,
234 0.002739f32,
235 0.003466f32,
236 0.004278f32,
237 0.005174f32,
238 0.006156f32,
239 0.007222f32,
240 0.008373f32,
241 0.009607f32,
242 0.010926f32,
243 0.012329f32,
244 0.013815f32,
245 0.015385f32,
246 0.017037f32,
247 0.018772f32,
248 0.020590f32,
249 0.022490f32,
250 0.024472f32,
251 0.026535f32,
252 0.028679f32,
253 0.030904f32,
254 0.033210f32,
255 0.035595f32,
256 0.038060f32,
257 0.040604f32,
258 0.043227f32,
259 0.045928f32,
260 0.048707f32,
261 0.051564f32,
262 0.054497f32,
263 0.057506f32,
264 0.060591f32,
265 0.063752f32,
266 0.066987f32,
267 0.070297f32,
268 0.073680f32,
269 0.077136f32,
270 0.080665f32,
271 0.084265f32,
272 0.087937f32,
273 0.091679f32,
274 0.095492f32,
275 0.099373f32,
276 0.103323f32,
277 0.107342f32,
278 0.111427f32,
279 0.115579f32,
280 0.119797f32,
281 0.124080f32,
282 0.128428f32,
283 0.132839f32,
284 0.137313f32,
285 0.141849f32,
286 0.146447f32,
287 0.151105f32,
288 0.155823f32,
289 0.160600f32,
290 0.165435f32,
291 0.170327f32,
292 0.175276f32,
293 0.180280f32,
294 0.185340f32,
295 0.190453f32,
296 0.195619f32,
297 0.200838f32,
298 0.206107f32,
299 0.211427f32,
300 0.216797f32,
301 0.222215f32,
302 0.227680f32,
303 0.233193f32,
304 0.238751f32,
305 0.244353f32,
306 0.250000f32,
307 0.255689f32,
308 0.261421f32,
309 0.267193f32,
310 0.273005f32,
311 0.278856f32,
312 0.284744f32,
313 0.290670f32,
314 0.296632f32,
315 0.302628f32,
316 0.308658f32,
317 0.314721f32,
318 0.320816f32,
319 0.326941f32,
320 0.333097f32,
321 0.339280f32,
322 0.345492f32,
323 0.351729f32,
324 0.357992f32,
325 0.364280f32,
326 0.370590f32,
327 0.376923f32,
328 0.383277f32,
329 0.389651f32,
330 0.396044f32,
331 0.402455f32,
332 0.408882f32,
333 0.415325f32,
334 0.421783f32,
335 0.428254f32,
336 0.434737f32,
337 0.441231f32,
338 0.447736f32,
339 0.454249f32,
340 0.460770f32,
341 0.467298f32,
342 0.473832f32,
343 0.480370f32,
344 0.486912f32,
345 0.493455f32,
346 0.500000f32,
347 0.506545f32,
348 0.513088f32,
349 0.519630f32,
350 0.526168f32,
351 0.532702f32,
352 0.539230f32,
353 0.545751f32,
354 0.552264f32,
355 0.558769f32,
356 0.565263f32,
357 0.571746f32,
358 0.578217f32,
359 0.584675f32,
360 0.591118f32,
361 0.597545f32,
362 0.603956f32,
363 0.610349f32,
364 0.616723f32,
365 0.623077f32,
366 0.629410f32,
367 0.635720f32,
368 0.642008f32,
369 0.648271f32,
370 0.654508f32,
371 0.660720f32,
372 0.666903f32,
373 0.673059f32,
374 0.679184f32,
375 0.685279f32,
376 0.691342f32,
377 0.697372f32,
378 0.703368f32,
379 0.709330f32,
380 0.715256f32,
381 0.721144f32,
382 0.726995f32,
383 0.732807f32,
384 0.738579f32,
385 0.744311f32,
386 0.750000f32,
387 0.755647f32,
388 0.761249f32,
389 0.766807f32,
390 0.772320f32,
391 0.777785f32,
392 0.783203f32,
393 0.788573f32,
394 0.793893f32,
395 0.799162f32,
396 0.804381f32,
397 0.809547f32,
398 0.814660f32,
399 0.819720f32,
400 0.824724f32,
401 0.829673f32,
402 0.834565f32,
403 0.839400f32,
404 0.844177f32,
405 0.848895f32,
406 0.853553f32,
407 0.858151f32,
408 0.862687f32,
409 0.867161f32,
410 0.871572f32,
411 0.875920f32,
412 0.880203f32,
413 0.884421f32,
414 0.888573f32,
415 0.892658f32,
416 0.896677f32,
417 0.900627f32,
418 0.904508f32,
419 0.908321f32,
420 0.912063f32,
421 0.915735f32,
422 0.919335f32,
423 0.922864f32,
424 0.926320f32,
425 0.929703f32,
426 0.933013f32,
427 0.936248f32,
428 0.939409f32,
429 0.942494f32,
430 0.945503f32,
431 0.948436f32,
432 0.951293f32,
433 0.954072f32,
434 0.956773f32,
435 0.959396f32,
436 0.961940f32,
437 0.964405f32,
438 0.966790f32,
439 0.969096f32,
440 0.971321f32,
441 0.973465f32,
442 0.975528f32,
443 0.977510f32,
444 0.979410f32,
445 0.981228f32,
446 0.982963f32,
447 0.984615f32,
448 0.986185f32,
449 0.987671f32,
450 0.989074f32,
451 0.990393f32,
452 0.991627f32,
453 0.992778f32,
454 0.993844f32,
455 0.994826f32,
456 0.995722f32,
457 0.996534f32,
458 0.997261f32,
459 0.997902f32,
460 0.998459f32,
461 0.998929f32,
462 0.999315f32,
463 0.999615f32,
464 0.999829f32,
465 0.999957f32,
466 1.000000f32,
467];
468static mut tbands: [i32; 19] = [
469 4, 8, 12, 16, 20, 24, 28, 32, 40, 48, 56, 64, 80, 96, 112, 136, 160, 192, 240,
470];
471pub const NB_TONAL_SKIP_BANDS: i32 = 9;
472unsafe fn silk_resampler_down2_hp(
473 S: *mut opus_val32,
474 out: *mut opus_val32,
475 in_0: *const opus_val32,
476 inLen: i32,
477) -> opus_val32 {
478 let mut k: i32 = 0;
479 let len2: i32 = inLen / 2;
480 let mut in32: opus_val32 = 0.;
481 let mut out32: opus_val32 = 0.;
482 let mut out32_hp: opus_val32 = 0.;
483 let mut Y: opus_val32 = 0.;
484 let mut X: opus_val32 = 0.;
485 let mut hp_ener: opus_val64 = 0 as opus_val64;
486 k = 0;
487 while k < len2 {
488 in32 = *in_0.offset((2 * k) as isize);
489 Y = in32 - *S.offset(0 as isize);
490 X = 0.6074371f32 * Y;
491 out32 = *S.offset(0 as isize) + X;
492 *S.offset(0 as isize) = in32 + X;
493 out32_hp = out32;
494 in32 = *in_0.offset((2 * k + 1) as isize);
495 Y = in32 - *S.offset(1 as isize);
496 X = 0.15063f32 * Y;
497 out32 = out32 + *S.offset(1 as isize);
498 out32 = out32 + X;
499 *S.offset(1 as isize) = in32 + X;
500 Y = -in32 - *S.offset(2 as isize);
501 X = 0.15063f32 * Y;
502 out32_hp = out32_hp + *S.offset(2 as isize);
503 out32_hp = out32_hp + X;
504 *S.offset(2 as isize) = -in32 + X;
505 hp_ener += out32_hp * out32_hp;
506 *out.offset(k as isize) = 0.5f32 * out32;
507 k += 1;
508 }
509 return hp_ener;
510}
511unsafe fn downmix_and_resample(
512 downmix: downmix_func,
513 mut _x: *const core::ffi::c_void,
514 y: *mut opus_val32,
515 S: *mut opus_val32,
516 mut subframe: i32,
517 mut offset: i32,
518 c1: i32,
519 c2: i32,
520 C: i32,
521 Fs: i32,
522) -> opus_val32 {
523 let mut scale: opus_val32 = 0.;
524 let mut j: i32 = 0;
525 let mut ret: opus_val32 = 0 as opus_val32;
526 if subframe == 0 {
527 return 0 as opus_val32;
528 }
529 if Fs == 48000 {
530 subframe *= 2;
531 offset *= 2;
532 } else if Fs == 16000 {
533 subframe = subframe * 2 / 3;
534 offset = offset * 2 / 3;
535 }
536 let vla = subframe as usize;
537 let mut tmp: Vec<opus_val32> = ::std::vec::from_elem(0., vla);
538 downmix.expect("non-null function pointer")(_x, tmp.as_mut_ptr(), subframe, offset, c1, c2, C);
539 scale = 1.0f32 / 32768 as f32;
540 if c2 == -(2) {
541 scale /= C as f32;
542 } else if c2 > -1 {
543 scale /= 2 as f32;
544 }
545 j = 0;
546 while j < subframe {
547 let ref mut fresh0 = *tmp.as_mut_ptr().offset(j as isize);
548 *fresh0 *= scale;
549 j += 1;
550 }
551 if Fs == 48000 {
552 ret = silk_resampler_down2_hp(S, y, tmp.as_mut_ptr(), subframe);
553 } else if Fs == 24000 {
554 memcpy(
555 y as *mut core::ffi::c_void,
556 tmp.as_mut_ptr() as *const core::ffi::c_void,
557 (subframe as u64)
558 .wrapping_mul(::core::mem::size_of::<opus_val32>() as u64)
559 .wrapping_add((0 * y.offset_from(tmp.as_mut_ptr()) as i64) as u64),
560 );
561 } else if Fs == 16000 {
562 let vla_0 = (3 * subframe) as usize;
563 let mut tmp3x: Vec<opus_val32> = ::std::vec::from_elem(0., vla_0);
564 j = 0;
565 while j < subframe {
566 *tmp3x.as_mut_ptr().offset((3 * j) as isize) = *tmp.as_mut_ptr().offset(j as isize);
567 *tmp3x.as_mut_ptr().offset((3 * j + 1) as isize) = *tmp.as_mut_ptr().offset(j as isize);
568 *tmp3x.as_mut_ptr().offset((3 * j + 2) as isize) = *tmp.as_mut_ptr().offset(j as isize);
569 j += 1;
570 }
571 silk_resampler_down2_hp(S, y, tmp3x.as_mut_ptr(), 3 * subframe);
572 }
573 return ret;
574}
575pub unsafe fn tonality_analysis_init(tonal: *mut TonalityAnalysisState, Fs: i32) {
576 (*tonal).arch = opus_select_arch();
577 (*tonal).Fs = Fs;
578 tonality_analysis_reset(tonal);
579}
580pub unsafe fn tonality_analysis_reset(tonal: *mut TonalityAnalysisState) {
581 let start: *mut i8 = &mut (*tonal).angle as *mut [f32; 240] as *mut i8;
582 memset(
583 start as *mut core::ffi::c_void,
584 0,
585 (::core::mem::size_of::<TonalityAnalysisState>() as u64)
586 .wrapping_sub(start.offset_from(tonal as *mut i8) as i64 as u64)
587 .wrapping_mul(::core::mem::size_of::<i8>() as u64),
588 );
589}
590pub unsafe fn tonality_get_info(
591 tonal: *mut TonalityAnalysisState,
592 info_out: *mut AnalysisInfo,
593 len: i32,
594) {
595 let mut pos: i32 = 0;
596 let mut curr_lookahead: i32 = 0;
597 let mut tonality_max: f32 = 0.;
598 let mut tonality_avg: f32 = 0.;
599 let mut tonality_count: i32 = 0;
600 let mut i: i32 = 0;
601 let mut pos0: i32 = 0;
602 let mut prob_avg: f32 = 0.;
603 let mut prob_count: f32 = 0.;
604 let mut prob_min: f32 = 0.;
605 let mut prob_max: f32 = 0.;
606 let mut vad_prob: f32 = 0.;
607 let mut mpos: i32 = 0;
608 let mut vpos: i32 = 0;
609 let mut bandwidth_span: i32 = 0;
610 pos = (*tonal).read_pos;
611 curr_lookahead = (*tonal).write_pos - (*tonal).read_pos;
612 if curr_lookahead < 0 {
613 curr_lookahead += DETECT_SIZE;
614 }
615 (*tonal).read_subframe += len / ((*tonal).Fs / 400);
616 while (*tonal).read_subframe >= 8 {
617 (*tonal).read_subframe -= 8;
618 (*tonal).read_pos += 1;
619 }
620 if (*tonal).read_pos >= DETECT_SIZE {
621 (*tonal).read_pos -= DETECT_SIZE;
622 }
623 if len > (*tonal).Fs / 50 && pos != (*tonal).write_pos {
624 pos += 1;
625 if pos == DETECT_SIZE {
626 pos = 0;
627 }
628 }
629 if pos == (*tonal).write_pos {
630 pos -= 1;
631 }
632 if pos < 0 {
633 pos = DETECT_SIZE - 1;
634 }
635 pos0 = pos;
636 memcpy(
637 info_out as *mut core::ffi::c_void,
638 &mut *((*tonal).info).as_mut_ptr().offset(pos as isize) as *mut AnalysisInfo
639 as *const core::ffi::c_void,
640 1_u64
641 .wrapping_mul(::core::mem::size_of::<AnalysisInfo>() as u64)
642 .wrapping_add(
643 (0 * info_out.offset_from(&mut *((*tonal).info).as_mut_ptr().offset(pos as isize))
644 as i64) as u64,
645 ),
646 );
647 if (*info_out).valid == 0 {
648 return;
649 }
650 tonality_avg = (*info_out).tonality;
651 tonality_max = tonality_avg;
652 tonality_count = 1;
653 bandwidth_span = 6;
654 i = 0;
655 while i < 3 {
656 pos += 1;
657 if pos == DETECT_SIZE {
658 pos = 0;
659 }
660 if pos == (*tonal).write_pos {
661 break;
662 }
663 tonality_max = if tonality_max > (*tonal).info[pos as usize].tonality {
664 tonality_max
665 } else {
666 (*tonal).info[pos as usize].tonality
667 };
668 tonality_avg += (*tonal).info[pos as usize].tonality;
669 tonality_count += 1;
670 (*info_out).bandwidth = if (*info_out).bandwidth > (*tonal).info[pos as usize].bandwidth {
671 (*info_out).bandwidth
672 } else {
673 (*tonal).info[pos as usize].bandwidth
674 };
675 bandwidth_span -= 1;
676 i += 1;
677 }
678 pos = pos0;
679 i = 0;
680 while i < bandwidth_span {
681 pos -= 1;
682 if pos < 0 {
683 pos = DETECT_SIZE - 1;
684 }
685 if pos == (*tonal).write_pos {
686 break;
687 }
688 (*info_out).bandwidth = if (*info_out).bandwidth > (*tonal).info[pos as usize].bandwidth {
689 (*info_out).bandwidth
690 } else {
691 (*tonal).info[pos as usize].bandwidth
692 };
693 i += 1;
694 }
695 (*info_out).tonality = if tonality_avg / tonality_count as f32 > tonality_max - 0.2f32 {
696 tonality_avg / tonality_count as f32
697 } else {
698 tonality_max - 0.2f32
699 };
700 vpos = pos0;
701 mpos = vpos;
702 if curr_lookahead > 15 {
703 mpos += 5;
704 if mpos >= DETECT_SIZE {
705 mpos -= DETECT_SIZE;
706 }
707 vpos += 1;
708 if vpos >= DETECT_SIZE {
709 vpos -= DETECT_SIZE;
710 }
711 }
712 prob_min = 1.0f32;
713 prob_max = 0.0f32;
714 vad_prob = (*tonal).info[vpos as usize].activity_probability;
715 prob_count = if 0.1f32 > vad_prob { 0.1f32 } else { vad_prob };
716 prob_avg = (if 0.1f32 > vad_prob { 0.1f32 } else { vad_prob })
717 * (*tonal).info[mpos as usize].music_prob;
718 loop {
719 let mut pos_vad: f32 = 0.;
720 mpos += 1;
721 if mpos == DETECT_SIZE {
722 mpos = 0;
723 }
724 if mpos == (*tonal).write_pos {
725 break;
726 }
727 vpos += 1;
728 if vpos == DETECT_SIZE {
729 vpos = 0;
730 }
731 if vpos == (*tonal).write_pos {
732 break;
733 }
734 pos_vad = (*tonal).info[vpos as usize].activity_probability;
735 prob_min = if (prob_avg - 10 as f32 * (vad_prob - pos_vad)) / prob_count < prob_min {
736 (prob_avg - 10 as f32 * (vad_prob - pos_vad)) / prob_count
737 } else {
738 prob_min
739 };
740 prob_max = if (prob_avg + 10 as f32 * (vad_prob - pos_vad)) / prob_count > prob_max {
741 (prob_avg + 10 as f32 * (vad_prob - pos_vad)) / prob_count
742 } else {
743 prob_max
744 };
745 prob_count += if 0.1f32 > pos_vad { 0.1f32 } else { pos_vad };
746 prob_avg += (if 0.1f32 > pos_vad { 0.1f32 } else { pos_vad })
747 * (*tonal).info[mpos as usize].music_prob;
748 }
749 (*info_out).music_prob = prob_avg / prob_count;
750 prob_min = if prob_avg / prob_count < prob_min {
751 prob_avg / prob_count
752 } else {
753 prob_min
754 };
755 prob_max = if prob_avg / prob_count > prob_max {
756 prob_avg / prob_count
757 } else {
758 prob_max
759 };
760 prob_min = if prob_min > 0.0f32 { prob_min } else { 0.0f32 };
761 prob_max = if prob_max < 1.0f32 { prob_max } else { 1.0f32 };
762 if curr_lookahead < 10 {
763 let mut pmin: f32 = 0.;
764 let mut pmax: f32 = 0.;
765 pmin = prob_min;
766 pmax = prob_max;
767 pos = pos0;
768 i = 0;
769 while i
770 < (if ((*tonal).count - 1) < 15 {
771 (*tonal).count - 1
772 } else {
773 15
774 })
775 {
776 pos -= 1;
777 if pos < 0 {
778 pos = DETECT_SIZE - 1;
779 }
780 pmin = if pmin < (*tonal).info[pos as usize].music_prob {
781 pmin
782 } else {
783 (*tonal).info[pos as usize].music_prob
784 };
785 pmax = if pmax > (*tonal).info[pos as usize].music_prob {
786 pmax
787 } else {
788 (*tonal).info[pos as usize].music_prob
789 };
790 i += 1;
791 }
792 pmin = if 0.0f32 > pmin - 0.1f32 * vad_prob {
793 0.0f32
794 } else {
795 pmin - 0.1f32 * vad_prob
796 };
797 pmax = if 1.0f32 < pmax + 0.1f32 * vad_prob {
798 1.0f32
799 } else {
800 pmax + 0.1f32 * vad_prob
801 };
802 prob_min += (1.0f32 - 0.1f32 * curr_lookahead as f32) * (pmin - prob_min);
803 prob_max += (1.0f32 - 0.1f32 * curr_lookahead as f32) * (pmax - prob_max);
804 }
805 (*info_out).music_prob_min = prob_min;
806 (*info_out).music_prob_max = prob_max;
807}
808static mut std_feature_bias: [f32; 9] = [
809 5.684947f32,
810 3.475288f32,
811 1.770634f32,
812 1.599784f32,
813 3.773215f32,
814 2.163313f32,
815 1.260756f32,
816 1.116868f32,
817 1.918795f32,
818];
819pub const LEAKAGE_OFFSET: f32 = 2.5f32;
820pub const LEAKAGE_SLOPE: f32 = 2.0f32;
821unsafe fn tonality_analysis(
822 tonal: *mut TonalityAnalysisState,
823 celt_mode: *const OpusCustomMode,
824 x: *const core::ffi::c_void,
825 mut len: i32,
826 mut offset: i32,
827 c1: i32,
828 c2: i32,
829 C: i32,
830 lsb_depth: i32,
831 downmix: downmix_func,
832) {
833 let mut i: i32 = 0;
834 let mut b: i32 = 0;
835 let N: i32 = 480;
836 let N2: i32 = 240;
837 let A: *mut f32 = ((*tonal).angle).as_mut_ptr();
838 let dA: *mut f32 = ((*tonal).d_angle).as_mut_ptr();
839 let d2A: *mut f32 = ((*tonal).d2_angle).as_mut_ptr();
840 let mut band_tonality: [f32; 18] = [0.; 18];
841 let mut logE: [f32; 18] = [0.; 18];
842 let mut BFCC: [f32; 8] = [0.; 8];
843 let mut features: [f32; 25] = [0.; 25];
844 let mut frame_tonality: f32 = 0.;
845 let mut max_frame_tonality: f32 = 0.;
846 let mut frame_noisiness: f32 = 0.;
847 let pi4: f32 = (M_PI * M_PI * M_PI * M_PI) as f32;
848 let mut slope: f32 = 0 as f32;
849 let mut frame_stationarity: f32 = 0.;
850 let mut relativeE: f32 = 0.;
851 let mut frame_probs: [f32; 2] = [0.; 2];
852 let mut alpha: f32 = 0.;
853 let mut alphaE: f32 = 0.;
854 let mut alphaE2: f32 = 0.;
855 let mut frame_loudness: f32 = 0.;
856 let mut bandwidth_mask: f32 = 0.;
857 let mut is_masked: [i32; 19] = [0; 19];
858 let mut bandwidth: i32 = 0;
859 let mut maxE: f32 = 0 as f32;
860 let mut noise_floor: f32 = 0.;
861 let mut remaining: i32 = 0;
862 let mut info: *mut AnalysisInfo = 0 as *mut AnalysisInfo;
863 let mut hp_ener: f32 = 0.;
864 let mut tonality2: [f32; 240] = [0.; 240];
865 let mut midE: [f32; 8] = [0.; 8];
866 let mut spec_variability: f32 = 0 as f32;
867 let mut band_log2: [f32; 19] = [0.; 19];
868 let mut leakage_from: [f32; 19] = [0.; 19];
869 let mut leakage_to: [f32; 19] = [0.; 19];
870 let mut layer_out: [f32; 32] = [0.; 32];
871 let mut below_max_pitch: f32 = 0.;
872 let mut above_max_pitch: f32 = 0.;
873 let mut is_silence: i32 = 0;
874 if (*tonal).initialized == 0 {
875 (*tonal).mem_fill = 240;
876 (*tonal).initialized = 1;
877 }
878 alpha = 1.0f32
879 / (if (10) < 1 + (*tonal).count {
880 10
881 } else {
882 1 + (*tonal).count
883 }) as f32;
884 alphaE = 1.0f32
885 / (if (25) < 1 + (*tonal).count {
886 25
887 } else {
888 1 + (*tonal).count
889 }) as f32;
890 alphaE2 = 1.0f32
891 / (if (100) < 1 + (*tonal).count {
892 100
893 } else {
894 1 + (*tonal).count
895 }) as f32;
896 if (*tonal).count <= 1 {
897 alphaE2 = 1 as f32;
898 }
899 if (*tonal).Fs == 48000 {
900 len /= 2;
901 offset /= 2;
902 } else if (*tonal).Fs == 16000 {
903 len = 3 * len / 2;
904 offset = 3 * offset / 2;
905 }
906 let kfft = (*celt_mode).mdct.kfft[0];
907 (*tonal).hp_ener_accum += downmix_and_resample(
908 downmix,
909 x,
910 &mut *((*tonal).inmem)
911 .as_mut_ptr()
912 .offset((*tonal).mem_fill as isize),
913 ((*tonal).downmix_state).as_mut_ptr(),
914 if len < 720 - (*tonal).mem_fill {
915 len
916 } else {
917 720 - (*tonal).mem_fill
918 },
919 offset,
920 c1,
921 c2,
922 C,
923 (*tonal).Fs,
924 );
925 if (*tonal).mem_fill + len < ANALYSIS_BUF_SIZE {
926 (*tonal).mem_fill += len;
927 return;
928 }
929 hp_ener = (*tonal).hp_ener_accum;
930 let fresh1 = (*tonal).write_pos;
931 (*tonal).write_pos = (*tonal).write_pos + 1;
932 info = &mut *((*tonal).info).as_mut_ptr().offset(fresh1 as isize) as *mut AnalysisInfo;
933 if (*tonal).write_pos >= DETECT_SIZE {
934 (*tonal).write_pos -= DETECT_SIZE;
935 }
936 is_silence = is_digital_silence(((*tonal).inmem).as_mut_ptr(), 720, 1, lsb_depth);
937 let mut in_0: [kiss_fft_cpx; 480] = [kiss_fft_cpx::zero(); 480];
938 let mut out: [kiss_fft_cpx; 480] = [kiss_fft_cpx::zero(); 480];
939 let mut tonality: [f32; 240] = [0.; 240];
940 let mut noisiness: [f32; 240] = [0.; 240];
941 i = 0;
942 while i < N2 {
943 let w: f32 = analysis_window[i as usize];
944 in_0[i as usize].re = w * (*tonal).inmem[i as usize];
945 in_0[i as usize].im = w * (*tonal).inmem[(N2 + i) as usize];
946 in_0[(N - i - 1) as usize].re = w * (*tonal).inmem[(N - i - 1) as usize];
947 in_0[(N - i - 1) as usize].im = w * (*tonal).inmem[(N + N2 - i - 1) as usize];
948 i += 1;
949 }
950 memmove(
951 ((*tonal).inmem).as_mut_ptr() as *mut core::ffi::c_void,
952 ((*tonal).inmem)
953 .as_mut_ptr()
954 .offset(720 as isize)
955 .offset(-(240 as isize)) as *const core::ffi::c_void,
956 240_u64
957 .wrapping_mul(::core::mem::size_of::<opus_val32>() as u64)
958 .wrapping_add(
959 (0 * ((*tonal).inmem).as_mut_ptr().offset_from(
960 ((*tonal).inmem)
961 .as_mut_ptr()
962 .offset(720 as isize)
963 .offset(-(240 as isize)),
964 ) as i64) as u64,
965 ),
966 );
967 remaining = len - (ANALYSIS_BUF_SIZE - (*tonal).mem_fill);
968 (*tonal).hp_ener_accum = downmix_and_resample(
969 downmix,
970 x,
971 &mut *((*tonal).inmem).as_mut_ptr().offset(240 as isize),
972 ((*tonal).downmix_state).as_mut_ptr(),
973 remaining,
974 offset + ANALYSIS_BUF_SIZE - (*tonal).mem_fill,
975 c1,
976 c2,
977 C,
978 (*tonal).Fs,
979 );
980 (*tonal).mem_fill = 240 + remaining;
981 if is_silence != 0 {
982 let mut prev_pos: i32 = (*tonal).write_pos - 2;
983 if prev_pos < 0 {
984 prev_pos += DETECT_SIZE;
985 }
986 memcpy(
987 info as *mut core::ffi::c_void,
988 &mut *((*tonal).info).as_mut_ptr().offset(prev_pos as isize) as *mut AnalysisInfo
989 as *const core::ffi::c_void,
990 1_u64
991 .wrapping_mul(::core::mem::size_of::<AnalysisInfo>() as u64)
992 .wrapping_add(
993 (0 * info
994 .offset_from(&mut *((*tonal).info).as_mut_ptr().offset(prev_pos as isize))
995 as i64) as u64,
996 ),
997 );
998 return;
999 }
1000 opus_fft_c(kfft, &in_0, &mut out);
1001 if out[0].re != out[0].re {
1002 (*info).valid = 0;
1003 return;
1004 }
1005 i = 1;
1006 while i < N2 {
1007 let mut X1r: f32 = 0.;
1008 let mut X2r: f32 = 0.;
1009 let mut X1i: f32 = 0.;
1010 let mut X2i: f32 = 0.;
1011 let mut angle: f32 = 0.;
1012 let mut d_angle: f32 = 0.;
1013 let mut d2_angle: f32 = 0.;
1014 let mut angle2: f32 = 0.;
1015 let mut d_angle2: f32 = 0.;
1016 let mut d2_angle2: f32 = 0.;
1017 let mut mod1: f32 = 0.;
1018 let mut mod2: f32 = 0.;
1019 let mut avg_mod: f32 = 0.;
1020 X1r = out[i as usize].re + out[(N - i) as usize].re;
1021 X1i = out[i as usize].im - out[(N - i) as usize].im;
1022 X2r = out[i as usize].im + out[(N - i) as usize].im;
1023 X2i = out[(N - i) as usize].re - out[i as usize].re;
1024 angle = (0.5f32 as f64 / M_PI) as f32 * fast_atan2f(X1i, X1r);
1025 d_angle = angle - *A.offset(i as isize);
1026 d2_angle = d_angle - *dA.offset(i as isize);
1027 angle2 = (0.5f32 as f64 / M_PI) as f32 * fast_atan2f(X2i, X2r);
1028 d_angle2 = angle2 - angle;
1029 d2_angle2 = d_angle2 - d_angle;
1030 mod1 = d2_angle - float2int(d2_angle) as f32;
1031 noisiness[i as usize] = (mod1).abs();
1032 mod1 *= mod1;
1033 mod1 *= mod1;
1034 mod2 = d2_angle2 - float2int(d2_angle2) as f32;
1035 noisiness[i as usize] += (mod2).abs();
1036 mod2 *= mod2;
1037 mod2 *= mod2;
1038 avg_mod = 0.25f32 * (*d2A.offset(i as isize) + mod1 + 2 as f32 * mod2);
1039 tonality[i as usize] = 1.0f32 / (1.0f32 + 40.0f32 * 16.0f32 * pi4 * avg_mod) - 0.015f32;
1040 tonality2[i as usize] = 1.0f32 / (1.0f32 + 40.0f32 * 16.0f32 * pi4 * mod2) - 0.015f32;
1041 *A.offset(i as isize) = angle2;
1042 *dA.offset(i as isize) = d_angle2;
1043 *d2A.offset(i as isize) = mod2;
1044 i += 1;
1045 }
1046 i = 2;
1047 while i < N2 - 1 {
1048 let tt: f32 = if tonality2[i as usize]
1049 < (if tonality2[(i - 1) as usize] > tonality2[(i + 1) as usize] {
1050 tonality2[(i - 1) as usize]
1051 } else {
1052 tonality2[(i + 1) as usize]
1053 }) {
1054 tonality2[i as usize]
1055 } else if tonality2[(i - 1) as usize] > tonality2[(i + 1) as usize] {
1056 tonality2[(i - 1) as usize]
1057 } else {
1058 tonality2[(i + 1) as usize]
1059 };
1060 tonality[i as usize] = 0.9f32
1061 * (if tonality[i as usize] > tt - 0.1f32 {
1062 tonality[i as usize]
1063 } else {
1064 tt - 0.1f32
1065 });
1066 i += 1;
1067 }
1068 frame_tonality = 0 as f32;
1069 max_frame_tonality = 0 as f32;
1070 (*info).activity = 0 as f32;
1071 frame_noisiness = 0 as f32;
1072 frame_stationarity = 0 as f32;
1073 if (*tonal).count == 0 {
1074 b = 0;
1075 while b < NB_TBANDS {
1076 (*tonal).lowE[b as usize] = 1e10f64 as f32;
1077 (*tonal).highE[b as usize] = -1e10f64 as f32;
1078 b += 1;
1079 }
1080 }
1081 relativeE = 0 as f32;
1082 frame_loudness = 0 as f32;
1083 let mut E: f32 = 0 as f32;
1084 let mut X1r_0: f32 = 0.;
1085 let mut X2r_0: f32 = 0.;
1086 X1r_0 = 2 as f32 * out[0 as usize].re;
1087 X2r_0 = 2 as f32 * out[0 as usize].im;
1088 E = X1r_0 * X1r_0 + X2r_0 * X2r_0;
1089 i = 1;
1090 while i < 4 {
1091 let binE: f32 = out[i as usize].re * out[i as usize].re
1092 + out[(N - i) as usize].re * out[(N - i) as usize].re
1093 + out[i as usize].im * out[i as usize].im
1094 + out[(N - i) as usize].im * out[(N - i) as usize].im;
1095 E += binE;
1096 i += 1;
1097 }
1098 E = E;
1099 band_log2[0 as usize] = 0.5f32 * std::f32::consts::LOG2_E * (E + 1e-10f32).ln();
1100 b = 0;
1101 while b < NB_TBANDS {
1102 let mut E_0: f32 = 0 as f32;
1103 let mut tE: f32 = 0 as f32;
1104 let mut nE: f32 = 0 as f32;
1105 let mut L1: f32 = 0.;
1106 let mut L2: f32 = 0.;
1107 let mut stationarity: f32 = 0.;
1108 i = tbands[b as usize];
1109 while i < tbands[(b + 1) as usize] {
1110 let mut binE_0: f32 = out[i as usize].re * out[i as usize].re
1111 + out[(N - i) as usize].re * out[(N - i) as usize].re
1112 + out[i as usize].im * out[i as usize].im
1113 + out[(N - i) as usize].im * out[(N - i) as usize].im;
1114 binE_0 = binE_0;
1115 E_0 += binE_0;
1116 tE += binE_0
1117 * (if 0 as f32 > tonality[i as usize] {
1118 0 as f32
1119 } else {
1120 tonality[i as usize]
1121 });
1122 nE += binE_0 * 2.0f32 * (0.5f32 - noisiness[i as usize]);
1123 i += 1;
1124 }
1125 if !(E_0 < 1e9f32) || E_0 != E_0 {
1126 (*info).valid = 0;
1127 return;
1128 }
1129 (*tonal).E[(*tonal).E_count as usize][b as usize] = E_0;
1130 frame_noisiness += nE / (1e-15f32 + E_0);
1131 frame_loudness += (E_0 + 1e-10f32).sqrt();
1132 logE[b as usize] = (E_0 + 1e-10f32).ln();
1133 band_log2[(b + 1) as usize] = 0.5f32 * std::f32::consts::LOG2_E * (E_0 + 1e-10f32).ln();
1134 (*tonal).logE[(*tonal).E_count as usize][b as usize] = logE[b as usize];
1135 if (*tonal).count == 0 {
1136 (*tonal).lowE[b as usize] = logE[b as usize];
1137 (*tonal).highE[b as usize] = (*tonal).lowE[b as usize];
1138 }
1139 if (*tonal).highE[b as usize] as f64 > (*tonal).lowE[b as usize] as f64 + 7.5f64 {
1140 if (*tonal).highE[b as usize] - logE[b as usize]
1141 > logE[b as usize] - (*tonal).lowE[b as usize]
1142 {
1143 (*tonal).highE[b as usize] -= 0.01f32;
1144 } else {
1145 (*tonal).lowE[b as usize] += 0.01f32;
1146 }
1147 }
1148 if logE[b as usize] > (*tonal).highE[b as usize] {
1149 (*tonal).highE[b as usize] = logE[b as usize];
1150 (*tonal).lowE[b as usize] =
1151 if (*tonal).highE[b as usize] - 15 as f32 > (*tonal).lowE[b as usize] {
1152 (*tonal).highE[b as usize] - 15 as f32
1153 } else {
1154 (*tonal).lowE[b as usize]
1155 };
1156 } else if logE[b as usize] < (*tonal).lowE[b as usize] {
1157 (*tonal).lowE[b as usize] = logE[b as usize];
1158 (*tonal).highE[b as usize] =
1159 if ((*tonal).lowE[b as usize] + 15 as f32) < (*tonal).highE[b as usize] {
1160 (*tonal).lowE[b as usize] + 15 as f32
1161 } else {
1162 (*tonal).highE[b as usize]
1163 };
1164 }
1165 relativeE += (logE[b as usize] - (*tonal).lowE[b as usize])
1166 / (1e-5f32 + ((*tonal).highE[b as usize] - (*tonal).lowE[b as usize]));
1167 L2 = 0 as f32;
1168 L1 = L2;
1169 i = 0;
1170 while i < NB_FRAMES {
1171 L1 += ((*tonal).E[i as usize][b as usize]).sqrt();
1172 L2 += (*tonal).E[i as usize][b as usize];
1173 i += 1;
1174 }
1175 stationarity = if 0.99f32 < L1 / (1e-15 + (8 as f32 * L2)).sqrt() {
1176 0.99f32
1177 } else {
1178 L1 / (1e-15 + (8 as f32 * L2)).sqrt()
1179 };
1180 stationarity *= stationarity;
1181 stationarity *= stationarity;
1182 frame_stationarity += stationarity;
1183 band_tonality[b as usize] =
1184 if tE / (1e-15f32 + E_0) > stationarity * (*tonal).prev_band_tonality[b as usize] {
1185 tE / (1e-15f32 + E_0)
1186 } else {
1187 stationarity * (*tonal).prev_band_tonality[b as usize]
1188 };
1189 frame_tonality += band_tonality[b as usize];
1190 if b >= NB_TBANDS - NB_TONAL_SKIP_BANDS {
1191 frame_tonality -= band_tonality[(b - NB_TBANDS + NB_TONAL_SKIP_BANDS) as usize];
1192 }
1193 max_frame_tonality =
1194 if max_frame_tonality > (1.0f32 + 0.03f32 * (b - 18) as f32) * frame_tonality {
1195 max_frame_tonality
1196 } else {
1197 (1.0f32 + 0.03f32 * (b - 18) as f32) * frame_tonality
1198 };
1199 slope += band_tonality[b as usize] * (b - 8) as f32;
1200 (*tonal).prev_band_tonality[b as usize] = band_tonality[b as usize];
1201 b += 1;
1202 }
1203 leakage_from[0 as usize] = band_log2[0 as usize];
1204 leakage_to[0 as usize] = band_log2[0 as usize] - LEAKAGE_OFFSET;
1205 b = 1;
1206 while b < NB_TBANDS + 1 {
1207 let leak_slope: f32 =
1208 LEAKAGE_SLOPE * (tbands[b as usize] - tbands[(b - 1) as usize]) as f32 / 4 as f32;
1209 leakage_from[b as usize] =
1210 if leakage_from[(b - 1) as usize] + leak_slope < band_log2[b as usize] {
1211 leakage_from[(b - 1) as usize] + leak_slope
1212 } else {
1213 band_log2[b as usize]
1214 };
1215 leakage_to[b as usize] =
1216 if leakage_to[(b - 1) as usize] - leak_slope > band_log2[b as usize] - 2.5f32 {
1217 leakage_to[(b - 1) as usize] - leak_slope
1218 } else {
1219 band_log2[b as usize] - 2.5f32
1220 };
1221 b += 1;
1222 }
1223 b = NB_TBANDS - 2;
1224 while b >= 0 {
1225 let leak_slope_0: f32 =
1226 LEAKAGE_SLOPE * (tbands[(b + 1) as usize] - tbands[b as usize]) as f32 / 4 as f32;
1227 leakage_from[b as usize] =
1228 if leakage_from[(b + 1) as usize] + leak_slope_0 < leakage_from[b as usize] {
1229 leakage_from[(b + 1) as usize] + leak_slope_0
1230 } else {
1231 leakage_from[b as usize]
1232 };
1233 leakage_to[b as usize] =
1234 if leakage_to[(b + 1) as usize] - leak_slope_0 > leakage_to[b as usize] {
1235 leakage_to[(b + 1) as usize] - leak_slope_0
1236 } else {
1237 leakage_to[b as usize]
1238 };
1239 b -= 1;
1240 }
1241 assert!(18 + 1 <= 19);
1242 b = 0;
1243 while b < NB_TBANDS + 1 {
1244 let boost: f32 =
1245 (if 0 as f32 > leakage_to[b as usize] - band_log2[b as usize] {
1246 0 as f32
1247 } else {
1248 leakage_to[b as usize] - band_log2[b as usize]
1249 }) + (if 0 as f32 > band_log2[b as usize] - (leakage_from[b as usize] + 2.5f32) {
1250 0 as f32
1251 } else {
1252 band_log2[b as usize] - (leakage_from[b as usize] + 2.5f32)
1253 });
1254 (*info).leak_boost[b as usize] = (if (255) < (0.5 + (64.0 * boost)).floor() as i32 {
1255 255
1256 } else {
1257 (0.5 + (64.0 * boost)).floor() as i32
1258 }) as u8;
1259 b += 1;
1260 }
1261 while b < LEAK_BANDS {
1262 (*info).leak_boost[b as usize] = 0;
1263 b += 1;
1264 }
1265 i = 0;
1266 while i < NB_FRAMES {
1267 let mut j: i32 = 0;
1268 let mut mindist: f32 = 1e15f32;
1269 j = 0;
1270 while j < NB_FRAMES {
1271 let mut k: i32 = 0;
1272 let mut dist: f32 = 0 as f32;
1273 k = 0;
1274 while k < NB_TBANDS {
1275 let mut tmp: f32 = 0.;
1276 tmp = (*tonal).logE[i as usize][k as usize] - (*tonal).logE[j as usize][k as usize];
1277 dist += tmp * tmp;
1278 k += 1;
1279 }
1280 if j != i {
1281 mindist = if mindist < dist { mindist } else { dist };
1282 }
1283 j += 1;
1284 }
1285 spec_variability += mindist;
1286 i += 1;
1287 }
1288 spec_variability = (spec_variability / NB_FRAMES as f32 / NB_TBANDS as f32).sqrt();
1289 bandwidth_mask = 0 as f32;
1290 bandwidth = 0;
1291 maxE = 0 as f32;
1292 noise_floor = 5.7e-4f32 / ((1) << (if 0 > lsb_depth - 8 { 0 } else { lsb_depth - 8 })) as f32;
1293 noise_floor *= noise_floor;
1294 below_max_pitch = 0 as f32;
1295 above_max_pitch = 0 as f32;
1296 b = 0;
1297 while b < NB_TBANDS {
1298 let mut E_1: f32 = 0 as f32;
1299 let mut Em: f32 = 0.;
1300 let mut band_start: i32 = 0;
1301 let mut band_end: i32 = 0;
1302 band_start = tbands[b as usize];
1303 band_end = tbands[(b + 1) as usize];
1304 i = band_start;
1305 while i < band_end {
1306 let binE_1: f32 = out[i as usize].re * out[i as usize].re
1307 + out[(N - i) as usize].re * out[(N - i) as usize].re
1308 + out[i as usize].im * out[i as usize].im
1309 + out[(N - i) as usize].im * out[(N - i) as usize].im;
1310 E_1 += binE_1;
1311 i += 1;
1312 }
1313 E_1 = E_1;
1314 maxE = if maxE > E_1 { maxE } else { E_1 };
1315 if band_start < 64 {
1316 below_max_pitch += E_1;
1317 } else {
1318 above_max_pitch += E_1;
1319 }
1320 (*tonal).meanE[b as usize] = if (1 as f32 - alphaE2) * (*tonal).meanE[b as usize] > E_1 {
1321 (1 as f32 - alphaE2) * (*tonal).meanE[b as usize]
1322 } else {
1323 E_1
1324 };
1325 Em = if E_1 > (*tonal).meanE[b as usize] {
1326 E_1
1327 } else {
1328 (*tonal).meanE[b as usize]
1329 };
1330 if E_1 * 1e9f32 > maxE
1331 && (Em > 3 as f32 * noise_floor * (band_end - band_start) as f32
1332 || E_1 > noise_floor * (band_end - band_start) as f32)
1333 {
1334 bandwidth = b + 1;
1335 }
1336 is_masked[b as usize] = (E_1
1337 < (if (*tonal).prev_bandwidth >= b + 1 {
1338 0.01f32
1339 } else {
1340 0.05f32
1341 }) * bandwidth_mask) as i32;
1342 bandwidth_mask = if 0.05f32 * bandwidth_mask > E_1 {
1343 0.05f32 * bandwidth_mask
1344 } else {
1345 E_1
1346 };
1347 b += 1;
1348 }
1349 if (*tonal).Fs == 48000 {
1350 let mut noise_ratio: f32 = 0.;
1351 let mut Em_0: f32 = 0.;
1352 let E_2: f32 = hp_ener * (1.0f32 / (60 * 60) as f32);
1353 noise_ratio = if (*tonal).prev_bandwidth == 20 {
1354 10.0f32
1355 } else {
1356 30.0f32
1357 };
1358 above_max_pitch += E_2;
1359 (*tonal).meanE[b as usize] = if (1 as f32 - alphaE2) * (*tonal).meanE[b as usize] > E_2 {
1360 (1 as f32 - alphaE2) * (*tonal).meanE[b as usize]
1361 } else {
1362 E_2
1363 };
1364 Em_0 = if E_2 > (*tonal).meanE[b as usize] {
1365 E_2
1366 } else {
1367 (*tonal).meanE[b as usize]
1368 };
1369 if Em_0 > 3 as f32 * noise_ratio * noise_floor * 160 as f32
1370 || E_2 > noise_ratio * noise_floor * 160 as f32
1371 {
1372 bandwidth = 20;
1373 }
1374 is_masked[b as usize] = (E_2
1375 < (if (*tonal).prev_bandwidth == 20 {
1376 0.01f32
1377 } else {
1378 0.05f32
1379 }) * bandwidth_mask) as i32;
1380 }
1381 if above_max_pitch > below_max_pitch {
1382 (*info).max_pitch_ratio = below_max_pitch / above_max_pitch;
1383 } else {
1384 (*info).max_pitch_ratio = 1 as f32;
1385 }
1386 if bandwidth == 20 && is_masked[NB_TBANDS as usize] != 0 {
1387 bandwidth -= 2;
1388 } else if bandwidth > 0 && bandwidth <= NB_TBANDS && is_masked[(bandwidth - 1) as usize] != 0 {
1389 bandwidth -= 1;
1390 }
1391 if (*tonal).count <= 2 {
1392 bandwidth = 20;
1393 }
1394 frame_loudness = 20 as f32 * frame_loudness.log10();
1395 (*tonal).Etracker = if (*tonal).Etracker - 0.003f32 > frame_loudness {
1396 (*tonal).Etracker - 0.003f32
1397 } else {
1398 frame_loudness
1399 };
1400 (*tonal).lowECount *= 1 as f32 - alphaE;
1401 if frame_loudness < (*tonal).Etracker - 30 as f32 {
1402 (*tonal).lowECount += alphaE;
1403 }
1404 i = 0;
1405 while i < 8 {
1406 let mut sum: f32 = 0 as f32;
1407 b = 0;
1408 while b < 16 {
1409 sum += dct_table[(i * 16 + b) as usize] * logE[b as usize];
1410 b += 1;
1411 }
1412 BFCC[i as usize] = sum;
1413 i += 1;
1414 }
1415 i = 0;
1416 while i < 8 {
1417 let mut sum_0: f32 = 0 as f32;
1418 b = 0;
1419 while b < 16 {
1420 sum_0 += dct_table[(i * 16 + b) as usize]
1421 * 0.5f32
1422 * ((*tonal).highE[b as usize] + (*tonal).lowE[b as usize]);
1423 b += 1;
1424 }
1425 midE[i as usize] = sum_0;
1426 i += 1;
1427 }
1428 frame_stationarity /= NB_TBANDS as f32;
1429 relativeE /= NB_TBANDS as f32;
1430 if (*tonal).count < 10 {
1431 relativeE = 0.5f32;
1432 }
1433 frame_noisiness /= NB_TBANDS as f32;
1434 (*info).activity = frame_noisiness + (1 as f32 - frame_noisiness) * relativeE;
1435 frame_tonality = max_frame_tonality / (NB_TBANDS - NB_TONAL_SKIP_BANDS) as f32;
1436 frame_tonality = if frame_tonality > (*tonal).prev_tonality * 0.8f32 {
1437 frame_tonality
1438 } else {
1439 (*tonal).prev_tonality * 0.8f32
1440 };
1441 (*tonal).prev_tonality = frame_tonality;
1442 slope /= (8 * 8) as f32;
1443 (*info).tonality_slope = slope;
1444 (*tonal).E_count = ((*tonal).E_count + 1) % NB_FRAMES;
1445 (*tonal).count = if ((*tonal).count + 1) < 10000 {
1446 (*tonal).count + 1
1447 } else {
1448 10000
1449 };
1450 (*info).tonality = frame_tonality;
1451 i = 0;
1452 while i < 4 {
1453 features[i as usize] = -0.12299f32 * (BFCC[i as usize] + (*tonal).mem[(i + 24) as usize])
1454 + 0.49195f32 * ((*tonal).mem[i as usize] + (*tonal).mem[(i + 16) as usize])
1455 + 0.69693f32 * (*tonal).mem[(i + 8) as usize]
1456 - 1.4349f32 * (*tonal).cmean[i as usize];
1457 i += 1;
1458 }
1459 i = 0;
1460 while i < 4 {
1461 (*tonal).cmean[i as usize] =
1462 (1 as f32 - alpha) * (*tonal).cmean[i as usize] + alpha * BFCC[i as usize];
1463 i += 1;
1464 }
1465 i = 0;
1466 while i < 4 {
1467 features[(4 + i) as usize] = 0.63246f32
1468 * (BFCC[i as usize] - (*tonal).mem[(i + 24) as usize])
1469 + 0.31623f32 * ((*tonal).mem[i as usize] - (*tonal).mem[(i + 16) as usize]);
1470 i += 1;
1471 }
1472 i = 0;
1473 while i < 3 {
1474 features[(8 + i) as usize] = 0.53452f32
1475 * (BFCC[i as usize] + (*tonal).mem[(i + 24) as usize])
1476 - 0.26726f32 * ((*tonal).mem[i as usize] + (*tonal).mem[(i + 16) as usize])
1477 - 0.53452f32 * (*tonal).mem[(i + 8) as usize];
1478 i += 1;
1479 }
1480 if (*tonal).count > 5 {
1481 i = 0;
1482 while i < 9 {
1483 (*tonal).std[i as usize] = (1 as f32 - alpha) * (*tonal).std[i as usize]
1484 + alpha * features[i as usize] * features[i as usize];
1485 i += 1;
1486 }
1487 }
1488 i = 0;
1489 while i < 4 {
1490 features[i as usize] = BFCC[i as usize] - midE[i as usize];
1491 i += 1;
1492 }
1493 i = 0;
1494 while i < 8 {
1495 (*tonal).mem[(i + 24) as usize] = (*tonal).mem[(i + 16) as usize];
1496 (*tonal).mem[(i + 16) as usize] = (*tonal).mem[(i + 8) as usize];
1497 (*tonal).mem[(i + 8) as usize] = (*tonal).mem[i as usize];
1498 (*tonal).mem[i as usize] = BFCC[i as usize];
1499 i += 1;
1500 }
1501 i = 0;
1502 while i < 9 {
1503 features[(11 + i) as usize] =
1504 ((*tonal).std[i as usize]).sqrt() - std_feature_bias[i as usize];
1505 i += 1;
1506 }
1507 features[18 as usize] = spec_variability - 0.78f32;
1508 features[20 as usize] = (*info).tonality - 0.154723f32;
1509 features[21 as usize] = (*info).activity - 0.724643f32;
1510 features[22 as usize] = frame_stationarity - 0.743717f32;
1511 features[23 as usize] = (*info).tonality_slope + 0.069216f32;
1512 features[24 as usize] = (*tonal).lowECount - 0.067930f32;
1513 compute_dense(&layer0, layer_out.as_mut_ptr(), features.as_mut_ptr());
1514 compute_gru(
1515 &layer1,
1516 ((*tonal).rnn_state).as_mut_ptr(),
1517 layer_out.as_mut_ptr(),
1518 );
1519 compute_dense(
1520 &layer2,
1521 frame_probs.as_mut_ptr(),
1522 ((*tonal).rnn_state).as_mut_ptr(),
1523 );
1524 (*info).activity_probability = frame_probs[1 as usize];
1525 (*info).music_prob = frame_probs[0 as usize];
1526 (*info).bandwidth = bandwidth;
1527 (*tonal).prev_bandwidth = bandwidth;
1528 (*info).noisiness = frame_noisiness;
1529 (*info).valid = 1;
1530}
1531pub unsafe fn run_analysis(
1532 analysis: *mut TonalityAnalysisState,
1533 celt_mode: *const OpusCustomMode,
1534 analysis_pcm: *const core::ffi::c_void,
1535 mut analysis_frame_size: i32,
1536 frame_size: i32,
1537 c1: i32,
1538 c2: i32,
1539 C: i32,
1540 Fs: i32,
1541 lsb_depth: i32,
1542 downmix: downmix_func,
1543 analysis_info: *mut AnalysisInfo,
1544) {
1545 let mut offset: i32 = 0;
1546 let mut pcm_len: i32 = 0;
1547 analysis_frame_size -= analysis_frame_size & 1;
1548 if !analysis_pcm.is_null() {
1549 analysis_frame_size = if ((100 - 5) * Fs / 50) < analysis_frame_size {
1550 (100 - 5) * Fs / 50
1551 } else {
1552 analysis_frame_size
1553 };
1554 pcm_len = analysis_frame_size - (*analysis).analysis_offset;
1555 offset = (*analysis).analysis_offset;
1556 while pcm_len > 0 {
1557 tonality_analysis(
1558 analysis,
1559 celt_mode,
1560 analysis_pcm,
1561 if (Fs / 50) < pcm_len {
1562 Fs / 50
1563 } else {
1564 pcm_len
1565 },
1566 offset,
1567 c1,
1568 c2,
1569 C,
1570 lsb_depth,
1571 downmix,
1572 );
1573 offset += Fs / 50;
1574 pcm_len -= Fs / 50;
1575 }
1576 (*analysis).analysis_offset = analysis_frame_size;
1577 (*analysis).analysis_offset -= frame_size;
1578 }
1579 tonality_get_info(analysis, analysis_info, frame_size);
1580}