unopus/src/
analysis.rs

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}