unsafe_libopus/silk/float/
pitch_analysis_core_FLP.rs

1pub mod arch_h {
2    pub type opus_val32 = f32;
3}
4pub mod xmmintrin_h {
5    #[cfg(target_arch = "x86")]
6    pub use core::arch::x86::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss};
7    #[cfg(target_arch = "x86_64")]
8    pub use core::arch::x86_64::{__m128, _mm_cvt_ss2si, _mm_cvtss_si32, _mm_set_ss};
9}
10pub mod SigProc_FLP_h {
11    #[inline]
12    pub unsafe fn silk_float2short_array(out: *mut i16, in_0: *const f32, length: i32) {
13        let mut k: i32 = 0;
14        k = length - 1;
15        while k >= 0 {
16            *out.offset(k as isize) = (if float2int(*in_0.offset(k as isize)) > silk_int16_MAX {
17                silk_int16_MAX
18            } else if float2int(*in_0.offset(k as isize)) < silk_int16_MIN {
19                silk_int16_MIN
20            } else {
21                float2int(*in_0.offset(k as isize))
22            }) as i16;
23            k -= 1;
24        }
25    }
26    #[inline]
27    pub unsafe fn silk_short2float_array(out: *mut f32, in_0: *const i16, length: i32) {
28        let mut k: i32 = 0;
29        k = length - 1;
30        while k >= 0 {
31            *out.offset(k as isize) = *in_0.offset(k as isize) as f32;
32            k -= 1;
33        }
34    }
35    #[inline]
36    pub unsafe fn silk_log2(x: f64) -> f32 {
37        return (3.32192809488736f64 * x.log10()) as f32;
38    }
39    use super::typedef_h::{silk_int16_MAX, silk_int16_MIN};
40    use crate::celt::float_cast::float2int;
41}
42pub mod typedef_h {
43    pub const silk_int16_MAX: i32 = i16::MAX as i32;
44    pub const silk_int16_MIN: i32 = i16::MIN as i32;
45}
46
47use self::arch_h::opus_val32;
48pub use self::typedef_h::{silk_int16_MAX, silk_int16_MIN};
49pub use self::SigProc_FLP_h::{silk_float2short_array, silk_log2, silk_short2float_array};
50use crate::celt::pitch::celt_pitch_xcorr_c;
51use crate::externs::memset;
52use crate::silk::float::energy_FLP::silk_energy_FLP;
53use crate::silk::float::inner_product_FLP::silk_inner_product_FLP;
54use crate::silk::float::sort_FLP::silk_insertion_sort_decreasing_FLP;
55use crate::silk::pitch_est_tables::{
56    silk_CB_lags_stage2, silk_CB_lags_stage2_10_ms, silk_CB_lags_stage3, silk_CB_lags_stage3_10_ms,
57    silk_Lag_range_stage3, silk_Lag_range_stage3_10_ms, silk_nb_cbk_searchs_stage3,
58    PE_FLATCONTOUR_BIAS, PE_LTP_MEM_LENGTH_MS, PE_MAX_LAG_MS, PE_MAX_NB_SUBFR, PE_MIN_LAG_MS,
59    PE_NB_CBKS_STAGE2, PE_NB_CBKS_STAGE2_10MS, PE_NB_CBKS_STAGE2_EXT, PE_NB_CBKS_STAGE3_10MS,
60    PE_NB_CBKS_STAGE3_MAX, PE_NB_STAGE3_LAGS, PE_PREVLAG_BIAS, PE_SHORTLAG_BIAS,
61    PE_SUBFR_LENGTH_MS, SILK_PE_MIN_COMPLEX,
62};
63use crate::silk::resampler::{silk_resampler_down2, silk_resampler_down2_3};
64use crate::silk::SigProc_FIX::{silk_max_int, silk_min_int};
65use arrayref::array_mut_ref;
66
67pub unsafe fn silk_pitch_analysis_core_FLP(
68    frame: *const f32,
69    pitch_out: *mut i32,
70    lagIndex: *mut i16,
71    contourIndex: *mut i8,
72    LTPCorr: *mut f32,
73    mut prevLag: i32,
74    search_thres1: f32,
75    search_thres2: f32,
76    Fs_kHz: i32,
77    complexity: i32,
78    nb_subfr: i32,
79    arch: i32,
80) -> i32 {
81    let mut i: i32 = 0;
82    let mut k: i32 = 0;
83    let mut d: i32 = 0;
84    let mut j: i32 = 0;
85    let mut frame_8kHz: [f32; 320] = [0.; 320];
86    let mut frame_4kHz: [f32; 160] = [0.; 160];
87    let mut frame_8_FIX: [i16; 320] = [0; 320];
88    let mut frame_4_FIX: [i16; 160] = [0; 160];
89    let mut filt_state: [i32; 6] = [0; 6];
90    let mut threshold: f32 = 0.;
91    let mut contour_bias: f32 = 0.;
92    let mut C: [[f32; 149]; 4] = [[0.; 149]; 4];
93    let mut xcorr: [opus_val32; 65] = [0.; 65];
94    let mut CC: [f32; 11] = [0.; 11];
95    let mut target_ptr: *const f32 = 0 as *const f32;
96    let mut basis_ptr: *const f32 = 0 as *const f32;
97    let mut cross_corr: f64 = 0.;
98    let mut normalizer: f64 = 0.;
99    let mut energy: f64 = 0.;
100    let mut energy_tmp: f64 = 0.;
101    let mut d_srch: [i32; 24] = [0; 24];
102    let mut d_comp: [i16; 149] = [0; 149];
103    let mut length_d_srch: i32 = 0;
104    let mut length_d_comp: i32 = 0;
105    let mut Cmax: f32 = 0.;
106    let mut CCmax: f32 = 0.;
107    let mut CCmax_b: f32 = 0.;
108    let mut CCmax_new_b: f32 = 0.;
109    let mut CCmax_new: f32 = 0.;
110    let mut CBimax: i32 = 0;
111    let mut CBimax_new: i32 = 0;
112    let mut lag: i32 = 0;
113    let mut start_lag: i32 = 0;
114    let mut end_lag: i32 = 0;
115    let mut lag_new: i32 = 0;
116    let mut cbk_size: i32 = 0;
117    let mut lag_log2: f32 = 0.;
118    let mut prevLag_log2: f32 = 0.;
119    let mut delta_lag_log2_sqr: f32 = 0.;
120    let mut energies_st3: [[[f32; 5]; 34]; 4] = [[[0.; 5]; 34]; 4];
121    let mut cross_corr_st3: [[[f32; 5]; 34]; 4] = [[[0.; 5]; 34]; 4];
122    let mut lag_counter: i32 = 0;
123    let mut frame_length: i32 = 0;
124    let mut frame_length_8kHz: i32 = 0;
125    let mut frame_length_4kHz: i32 = 0;
126    let mut sf_length: i32 = 0;
127    let mut sf_length_8kHz: i32 = 0;
128    let mut sf_length_4kHz: i32 = 0;
129    let mut min_lag: i32 = 0;
130    let mut min_lag_8kHz: i32 = 0;
131    let mut min_lag_4kHz: i32 = 0;
132    let mut max_lag: i32 = 0;
133    let mut max_lag_8kHz: i32 = 0;
134    let mut max_lag_4kHz: i32 = 0;
135    let mut nb_cbk_search: i32 = 0;
136    let mut Lag_CB_ptr: *const i8 = 0 as *const i8;
137    assert!(Fs_kHz == 8 || Fs_kHz == 12 || Fs_kHz == 16);
138    assert!(complexity >= 0);
139    assert!(complexity <= 2);
140    frame_length = (PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS) * Fs_kHz;
141    frame_length_4kHz = (PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS) * 4;
142    frame_length_8kHz = (PE_LTP_MEM_LENGTH_MS + nb_subfr * PE_SUBFR_LENGTH_MS) * 8;
143    sf_length = PE_SUBFR_LENGTH_MS * Fs_kHz;
144    sf_length_4kHz = PE_SUBFR_LENGTH_MS * 4;
145    sf_length_8kHz = PE_SUBFR_LENGTH_MS * 8;
146    min_lag = PE_MIN_LAG_MS * Fs_kHz;
147    min_lag_4kHz = PE_MIN_LAG_MS * 4;
148    min_lag_8kHz = PE_MIN_LAG_MS * 8;
149    max_lag = PE_MAX_LAG_MS * Fs_kHz - 1;
150    max_lag_4kHz = PE_MAX_LAG_MS * 4;
151    max_lag_8kHz = PE_MAX_LAG_MS * 8 - 1;
152    if Fs_kHz == 16 {
153        let mut frame_16_FIX: [i16; 640] = [0; 640];
154        silk_float2short_array(frame_16_FIX.as_mut_ptr(), frame, frame_length);
155        let filt_state = array_mut_ref![filt_state, 0, 2];
156        filt_state.fill(0);
157        silk_resampler_down2(
158            filt_state,
159            &mut frame_8_FIX[..frame_length_8kHz as usize],
160            &frame_16_FIX[..frame_length as usize],
161        );
162        silk_short2float_array(
163            frame_8kHz.as_mut_ptr(),
164            frame_8_FIX.as_mut_ptr(),
165            frame_length_8kHz,
166        );
167    } else if Fs_kHz == 12 {
168        let mut frame_12_FIX: [i16; 480] = [0; 480];
169        silk_float2short_array(frame_12_FIX.as_mut_ptr(), frame, frame_length);
170        filt_state.fill(0);
171        silk_resampler_down2_3(
172            &mut filt_state,
173            &mut frame_8_FIX[..frame_length_8kHz as usize],
174            &frame_12_FIX[..frame_length as usize],
175        );
176        silk_short2float_array(
177            frame_8kHz.as_mut_ptr(),
178            frame_8_FIX.as_mut_ptr(),
179            frame_length_8kHz,
180        );
181    } else {
182        assert!(Fs_kHz == 8);
183        silk_float2short_array(frame_8_FIX.as_mut_ptr(), frame, frame_length_8kHz);
184    }
185    {
186        let filt_state = array_mut_ref![filt_state, 0, 2];
187        filt_state.fill(0);
188        silk_resampler_down2(
189            filt_state,
190            &mut frame_4_FIX[..frame_length_4kHz as usize],
191            &frame_8_FIX[..frame_length_8kHz as usize],
192        );
193    }
194    silk_short2float_array(
195        frame_4kHz.as_mut_ptr(),
196        frame_4_FIX.as_mut_ptr(),
197        frame_length_4kHz,
198    );
199    i = frame_length_4kHz - 1;
200    while i > 0 {
201        frame_4kHz[i as usize] = (if frame_4kHz[i as usize] as i32 as f32
202            + frame_4kHz[(i - 1) as usize]
203            > silk_int16_MAX as f32
204        {
205            silk_int16_MAX as f32
206        } else if frame_4kHz[i as usize] as i32 as f32 + frame_4kHz[(i - 1) as usize]
207            < silk_int16_MIN as f32
208        {
209            silk_int16_MIN as f32
210        } else {
211            frame_4kHz[i as usize] as i32 as f32 + frame_4kHz[(i - 1) as usize]
212        }) as i16 as f32;
213        i -= 1;
214    }
215    memset(
216        C.as_mut_ptr() as *mut core::ffi::c_void,
217        0,
218        (::core::mem::size_of::<f32>() as u64)
219            .wrapping_mul(nb_subfr as u64)
220            .wrapping_mul(((18 * 16 >> 1) + 5) as u64),
221    );
222    target_ptr = &mut *frame_4kHz
223        .as_mut_ptr()
224        .offset(((sf_length_4kHz as u32) << 2) as i32 as isize) as *mut f32;
225    k = 0;
226    while k < nb_subfr >> 1 {
227        assert!(target_ptr >= frame_4kHz.as_mut_ptr() as *const f32);
228        assert!(
229            target_ptr.offset(sf_length_8kHz as isize)
230                <= frame_4kHz.as_mut_ptr().offset(frame_length_4kHz as isize) as *const f32
231        );
232        basis_ptr = target_ptr.offset(-(min_lag_4kHz as isize));
233        assert!(basis_ptr >= frame_4kHz.as_mut_ptr() as *const f32);
234        assert!(
235            basis_ptr.offset(sf_length_8kHz as isize)
236                <= frame_4kHz.as_mut_ptr().offset(frame_length_4kHz as isize) as *const f32
237        );
238        celt_pitch_xcorr_c(
239            target_ptr,
240            target_ptr.offset(-(max_lag_4kHz as isize)),
241            xcorr.as_mut_ptr(),
242            sf_length_8kHz,
243            max_lag_4kHz - min_lag_4kHz + 1,
244            arch,
245        );
246        cross_corr = xcorr[(max_lag_4kHz - min_lag_4kHz) as usize] as f64;
247        normalizer = silk_energy_FLP(target_ptr, sf_length_8kHz)
248            + silk_energy_FLP(basis_ptr, sf_length_8kHz)
249            + (sf_length_8kHz as f32 * 4000.0f32) as f64;
250        C[0 as usize][min_lag_4kHz as usize] += (2 as f64 * cross_corr / normalizer) as f32;
251        d = min_lag_4kHz + 1;
252        while d <= max_lag_4kHz {
253            basis_ptr = basis_ptr.offset(-1);
254            cross_corr = xcorr[(max_lag_4kHz - d) as usize] as f64;
255            normalizer += *basis_ptr.offset(0 as isize) as f64
256                * *basis_ptr.offset(0 as isize) as f64
257                - *basis_ptr.offset(sf_length_8kHz as isize) as f64
258                    * *basis_ptr.offset(sf_length_8kHz as isize) as f64;
259            C[0 as usize][d as usize] += (2 as f64 * cross_corr / normalizer) as f32;
260            d += 1;
261        }
262        target_ptr = target_ptr.offset(sf_length_8kHz as isize);
263        k += 1;
264    }
265    i = max_lag_4kHz;
266    while i >= min_lag_4kHz {
267        C[0 as usize][i as usize] -= C[0 as usize][i as usize] * i as f32 / 4096.0f32;
268        i -= 1;
269    }
270    length_d_srch = 4 + 2 * complexity;
271    assert!(3 * length_d_srch <= 24);
272    silk_insertion_sort_decreasing_FLP(
273        &mut *(*C.as_mut_ptr().offset(0 as isize))
274            .as_mut_ptr()
275            .offset(min_lag_4kHz as isize),
276        d_srch.as_mut_ptr(),
277        max_lag_4kHz - min_lag_4kHz + 1,
278        length_d_srch,
279    );
280    Cmax = C[0 as usize][min_lag_4kHz as usize];
281    if Cmax < 0.2f32 {
282        memset(
283            pitch_out as *mut core::ffi::c_void,
284            0,
285            (nb_subfr as u64).wrapping_mul(::core::mem::size_of::<i32>() as u64),
286        );
287        *LTPCorr = 0.0f32;
288        *lagIndex = 0;
289        *contourIndex = 0;
290        return 1;
291    }
292    threshold = search_thres1 * Cmax;
293    i = 0;
294    while i < length_d_srch {
295        if C[0 as usize][(min_lag_4kHz + i) as usize] > threshold {
296            d_srch[i as usize] = (((d_srch[i as usize] + min_lag_4kHz) as u32) << 1) as i32;
297            i += 1;
298        } else {
299            length_d_srch = i;
300            break;
301        }
302    }
303    assert!(length_d_srch > 0);
304    i = min_lag_8kHz - 5;
305    while i < max_lag_8kHz + 5 {
306        d_comp[i as usize] = 0;
307        i += 1;
308    }
309    i = 0;
310    while i < length_d_srch {
311        d_comp[d_srch[i as usize] as usize] = 1;
312        i += 1;
313    }
314    i = max_lag_8kHz + 3;
315    while i >= min_lag_8kHz {
316        d_comp[i as usize] = (d_comp[i as usize] as i32
317            + (d_comp[(i - 1) as usize] as i32 + d_comp[(i - 2) as usize] as i32))
318            as i16;
319        i -= 1;
320    }
321    length_d_srch = 0;
322    i = min_lag_8kHz;
323    while i < max_lag_8kHz + 1 {
324        if d_comp[(i + 1) as usize] as i32 > 0 {
325            d_srch[length_d_srch as usize] = i;
326            length_d_srch += 1;
327        }
328        i += 1;
329    }
330    i = max_lag_8kHz + 3;
331    while i >= min_lag_8kHz {
332        d_comp[i as usize] = (d_comp[i as usize] as i32
333            + (d_comp[(i - 1) as usize] as i32
334                + d_comp[(i - 2) as usize] as i32
335                + d_comp[(i - 3) as usize] as i32)) as i16;
336        i -= 1;
337    }
338    length_d_comp = 0;
339    i = min_lag_8kHz;
340    while i < max_lag_8kHz + 4 {
341        if d_comp[i as usize] as i32 > 0 {
342            d_comp[length_d_comp as usize] = (i - 2) as i16;
343            length_d_comp += 1;
344        }
345        i += 1;
346    }
347    memset(
348        C.as_mut_ptr() as *mut core::ffi::c_void,
349        0,
350        ((4 * ((18 * 16 >> 1) + 5)) as u64).wrapping_mul(::core::mem::size_of::<f32>() as u64),
351    );
352    if Fs_kHz == 8 {
353        target_ptr = &*frame.offset((PE_LTP_MEM_LENGTH_MS * 8) as isize) as *const f32;
354    } else {
355        target_ptr = &mut *frame_8kHz
356            .as_mut_ptr()
357            .offset((PE_LTP_MEM_LENGTH_MS * 8) as isize) as *mut f32;
358    }
359    k = 0;
360    while k < nb_subfr {
361        energy_tmp = silk_energy_FLP(target_ptr, sf_length_8kHz) + 1.0f64;
362        j = 0;
363        while j < length_d_comp {
364            d = d_comp[j as usize] as i32;
365            basis_ptr = target_ptr.offset(-(d as isize));
366            cross_corr = silk_inner_product_FLP(basis_ptr, target_ptr, sf_length_8kHz);
367            if cross_corr > 0.0f32 as f64 {
368                energy = silk_energy_FLP(basis_ptr, sf_length_8kHz);
369                C[k as usize][d as usize] = (2 as f64 * cross_corr / (energy + energy_tmp)) as f32;
370            } else {
371                C[k as usize][d as usize] = 0.0f32;
372            }
373            j += 1;
374        }
375        target_ptr = target_ptr.offset(sf_length_8kHz as isize);
376        k += 1;
377    }
378    CCmax = 0.0f32;
379    CCmax_b = -1000.0f32;
380    CBimax = 0;
381    lag = -1;
382    if prevLag > 0 {
383        if Fs_kHz == 12 {
384            prevLag = ((prevLag as u32) << 1) as i32 / 3;
385        } else if Fs_kHz == 16 {
386            prevLag = prevLag >> 1;
387        }
388        prevLag_log2 = silk_log2(prevLag as f32 as f64);
389    } else {
390        prevLag_log2 = 0 as f32;
391    }
392    if nb_subfr == PE_MAX_NB_SUBFR {
393        cbk_size = PE_NB_CBKS_STAGE2_EXT;
394        Lag_CB_ptr = &*(*silk_CB_lags_stage2.as_ptr().offset(0 as isize))
395            .as_ptr()
396            .offset(0 as isize) as *const i8;
397        if Fs_kHz == 8 && complexity > SILK_PE_MIN_COMPLEX {
398            nb_cbk_search = PE_NB_CBKS_STAGE2_EXT;
399        } else {
400            nb_cbk_search = PE_NB_CBKS_STAGE2;
401        }
402    } else {
403        cbk_size = PE_NB_CBKS_STAGE2_10MS;
404        Lag_CB_ptr = &*(*silk_CB_lags_stage2_10_ms.as_ptr().offset(0 as isize))
405            .as_ptr()
406            .offset(0 as isize) as *const i8;
407        nb_cbk_search = PE_NB_CBKS_STAGE2_10MS;
408    }
409    k = 0;
410    while k < length_d_srch {
411        d = d_srch[k as usize];
412        j = 0;
413        while j < nb_cbk_search {
414            CC[j as usize] = 0.0f32;
415            i = 0;
416            while i < nb_subfr {
417                CC[j as usize] += C[i as usize]
418                    [(d + *Lag_CB_ptr.offset((i * cbk_size + j) as isize) as i32) as usize];
419                i += 1;
420            }
421            j += 1;
422        }
423        CCmax_new = -1000.0f32;
424        CBimax_new = 0;
425        i = 0;
426        while i < nb_cbk_search {
427            if CC[i as usize] > CCmax_new {
428                CCmax_new = CC[i as usize];
429                CBimax_new = i;
430            }
431            i += 1;
432        }
433        lag_log2 = silk_log2(d as f32 as f64);
434        CCmax_new_b = CCmax_new - PE_SHORTLAG_BIAS * nb_subfr as f32 * lag_log2;
435        if prevLag > 0 {
436            delta_lag_log2_sqr = lag_log2 - prevLag_log2;
437            delta_lag_log2_sqr *= delta_lag_log2_sqr;
438            CCmax_new_b -= PE_PREVLAG_BIAS * nb_subfr as f32 * *LTPCorr * delta_lag_log2_sqr
439                / (delta_lag_log2_sqr + 0.5f32);
440        }
441        if CCmax_new_b > CCmax_b && CCmax_new > nb_subfr as f32 * search_thres2 {
442            CCmax_b = CCmax_new_b;
443            CCmax = CCmax_new;
444            lag = d;
445            CBimax = CBimax_new;
446        }
447        k += 1;
448    }
449    if lag == -1 {
450        memset(
451            pitch_out as *mut core::ffi::c_void,
452            0,
453            4_u64.wrapping_mul(::core::mem::size_of::<i32>() as u64),
454        );
455        *LTPCorr = 0.0f32;
456        *lagIndex = 0;
457        *contourIndex = 0;
458        return 1;
459    }
460    *LTPCorr = CCmax / nb_subfr as f32;
461    if Fs_kHz > 8 {
462        if Fs_kHz == 12 {
463            lag = if 1 == 1 {
464                (lag as i16 as i32 * 3 >> 1) + (lag as i16 as i32 * 3 & 1)
465            } else {
466                (lag as i16 as i32 * 3 >> 1 - 1) + 1 >> 1
467            };
468        } else {
469            lag = ((lag as u32) << 1) as i32;
470        }
471        lag = if min_lag > max_lag {
472            if lag > min_lag {
473                min_lag
474            } else if lag < max_lag {
475                max_lag
476            } else {
477                lag
478            }
479        } else if lag > max_lag {
480            max_lag
481        } else if lag < min_lag {
482            min_lag
483        } else {
484            lag
485        };
486        start_lag = silk_max_int(lag - 2, min_lag);
487        end_lag = silk_min_int(lag + 2, max_lag);
488        lag_new = lag;
489        CBimax = 0;
490        CCmax = -1000.0f32;
491        silk_P_Ana_calc_corr_st3(
492            cross_corr_st3.as_mut_ptr(),
493            frame,
494            start_lag,
495            sf_length,
496            nb_subfr,
497            complexity,
498            arch,
499        );
500        silk_P_Ana_calc_energy_st3(
501            energies_st3.as_mut_ptr(),
502            frame,
503            start_lag,
504            sf_length,
505            nb_subfr,
506            complexity,
507        );
508        lag_counter = 0;
509        contour_bias = PE_FLATCONTOUR_BIAS / lag as f32;
510        if nb_subfr == PE_MAX_NB_SUBFR {
511            nb_cbk_search = silk_nb_cbk_searchs_stage3[complexity as usize] as i32;
512            cbk_size = PE_NB_CBKS_STAGE3_MAX;
513            Lag_CB_ptr = &*(*silk_CB_lags_stage3.as_ptr().offset(0 as isize))
514                .as_ptr()
515                .offset(0 as isize) as *const i8;
516        } else {
517            nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
518            cbk_size = PE_NB_CBKS_STAGE3_10MS;
519            Lag_CB_ptr = &*(*silk_CB_lags_stage3_10_ms.as_ptr().offset(0 as isize))
520                .as_ptr()
521                .offset(0 as isize) as *const i8;
522        }
523        target_ptr = &*frame.offset((PE_LTP_MEM_LENGTH_MS * Fs_kHz) as isize) as *const f32;
524        energy_tmp = silk_energy_FLP(target_ptr, nb_subfr * sf_length) + 1.0f64;
525        d = start_lag;
526        while d <= end_lag {
527            j = 0;
528            while j < nb_cbk_search {
529                cross_corr = 0.0f64;
530                energy = energy_tmp;
531                k = 0;
532                while k < nb_subfr {
533                    cross_corr +=
534                        cross_corr_st3[k as usize][j as usize][lag_counter as usize] as f64;
535                    energy += energies_st3[k as usize][j as usize][lag_counter as usize] as f64;
536                    k += 1;
537                }
538                if cross_corr > 0.0f64 {
539                    CCmax_new = (2 as f64 * cross_corr / energy) as f32;
540                    CCmax_new *= 1.0f32 - contour_bias * j as f32;
541                } else {
542                    CCmax_new = 0.0f32;
543                }
544                if CCmax_new > CCmax
545                    && d + silk_CB_lags_stage3[0 as usize][j as usize] as i32 <= max_lag
546                {
547                    CCmax = CCmax_new;
548                    lag_new = d;
549                    CBimax = j;
550                }
551                j += 1;
552            }
553            lag_counter += 1;
554            d += 1;
555        }
556        k = 0;
557        while k < nb_subfr {
558            *pitch_out.offset(k as isize) =
559                lag_new + *Lag_CB_ptr.offset((k * cbk_size + CBimax) as isize) as i32;
560            *pitch_out.offset(k as isize) = if min_lag > 18 * Fs_kHz {
561                if *pitch_out.offset(k as isize) > min_lag {
562                    min_lag
563                } else if *pitch_out.offset(k as isize) < 18 * Fs_kHz {
564                    18 * Fs_kHz
565                } else {
566                    *pitch_out.offset(k as isize)
567                }
568            } else if *pitch_out.offset(k as isize) > 18 * Fs_kHz {
569                18 * Fs_kHz
570            } else if *pitch_out.offset(k as isize) < min_lag {
571                min_lag
572            } else {
573                *pitch_out.offset(k as isize)
574            };
575            k += 1;
576        }
577        *lagIndex = (lag_new - min_lag) as i16;
578        *contourIndex = CBimax as i8;
579    } else {
580        k = 0;
581        while k < nb_subfr {
582            *pitch_out.offset(k as isize) =
583                lag + *Lag_CB_ptr.offset((k * cbk_size + CBimax) as isize) as i32;
584            *pitch_out.offset(k as isize) = if min_lag_8kHz > 18 * 8 {
585                if *pitch_out.offset(k as isize) > min_lag_8kHz {
586                    min_lag_8kHz
587                } else if *pitch_out.offset(k as isize) < 18 * 8 {
588                    18 * 8
589                } else {
590                    *pitch_out.offset(k as isize)
591                }
592            } else if *pitch_out.offset(k as isize) > 18 * 8 {
593                18 * 8
594            } else if *pitch_out.offset(k as isize) < min_lag_8kHz {
595                min_lag_8kHz
596            } else {
597                *pitch_out.offset(k as isize)
598            };
599            k += 1;
600        }
601        *lagIndex = (lag - min_lag_8kHz) as i16;
602        *contourIndex = CBimax as i8;
603    }
604    assert!(*lagIndex as i32 >= 0);
605    return 0;
606}
607unsafe fn silk_P_Ana_calc_corr_st3(
608    cross_corr_st3: *mut [[f32; 5]; 34],
609    frame: *const f32,
610    start_lag: i32,
611    sf_length: i32,
612    nb_subfr: i32,
613    complexity: i32,
614    arch: i32,
615) {
616    let mut target_ptr: *const f32 = 0 as *const f32;
617    let mut i: i32 = 0;
618    let mut j: i32 = 0;
619    let mut k: i32 = 0;
620    let mut lag_counter: i32 = 0;
621    let mut lag_low: i32 = 0;
622    let mut lag_high: i32 = 0;
623    let mut nb_cbk_search: i32 = 0;
624    let mut delta: i32 = 0;
625    let mut idx: i32 = 0;
626    let mut cbk_size: i32 = 0;
627    let mut scratch_mem: [f32; 22] = [0.; 22];
628    let mut xcorr: [opus_val32; 22] = [0.; 22];
629    let mut Lag_range_ptr: *const i8 = 0 as *const i8;
630    let mut Lag_CB_ptr: *const i8 = 0 as *const i8;
631    assert!(complexity >= 0);
632    assert!(complexity <= 2);
633    if nb_subfr == PE_MAX_NB_SUBFR {
634        Lag_range_ptr = &*(*(*silk_Lag_range_stage3.as_ptr().offset(complexity as isize))
635            .as_ptr()
636            .offset(0 as isize))
637        .as_ptr()
638        .offset(0 as isize) as *const i8;
639        Lag_CB_ptr = &*(*silk_CB_lags_stage3.as_ptr().offset(0 as isize))
640            .as_ptr()
641            .offset(0 as isize) as *const i8;
642        nb_cbk_search = silk_nb_cbk_searchs_stage3[complexity as usize] as i32;
643        cbk_size = PE_NB_CBKS_STAGE3_MAX;
644    } else {
645        assert!(nb_subfr == 4 >> 1);
646        Lag_range_ptr = &*(*silk_Lag_range_stage3_10_ms.as_ptr().offset(0 as isize))
647            .as_ptr()
648            .offset(0 as isize) as *const i8;
649        Lag_CB_ptr = &*(*silk_CB_lags_stage3_10_ms.as_ptr().offset(0 as isize))
650            .as_ptr()
651            .offset(0 as isize) as *const i8;
652        nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
653        cbk_size = PE_NB_CBKS_STAGE3_10MS;
654    }
655    target_ptr = &*frame.offset(((sf_length as u32) << 2) as i32 as isize) as *const f32;
656    k = 0;
657    while k < nb_subfr {
658        lag_counter = 0;
659        lag_low = *Lag_range_ptr.offset((k * 2 + 0) as isize) as i32;
660        lag_high = *Lag_range_ptr.offset((k * 2 + 1) as isize) as i32;
661        celt_pitch_xcorr_c(
662            target_ptr,
663            target_ptr
664                .offset(-(start_lag as isize))
665                .offset(-(lag_high as isize)),
666            xcorr.as_mut_ptr(),
667            sf_length,
668            lag_high - lag_low + 1,
669            arch,
670        );
671        j = lag_low;
672        while j <= lag_high {
673            scratch_mem[lag_counter as usize] = xcorr[(lag_high - j) as usize];
674            lag_counter += 1;
675            j += 1;
676        }
677        delta = *Lag_range_ptr.offset((k * 2 + 0) as isize) as i32;
678        i = 0;
679        while i < nb_cbk_search {
680            idx = *Lag_CB_ptr.offset((k * cbk_size + i) as isize) as i32 - delta;
681            j = 0;
682            while j < PE_NB_STAGE3_LAGS {
683                (*cross_corr_st3.offset(k as isize))[i as usize][j as usize] =
684                    scratch_mem[(idx + j) as usize];
685                j += 1;
686            }
687            i += 1;
688        }
689        target_ptr = target_ptr.offset(sf_length as isize);
690        k += 1;
691    }
692}
693unsafe fn silk_P_Ana_calc_energy_st3(
694    energies_st3: *mut [[f32; 5]; 34],
695    frame: *const f32,
696    start_lag: i32,
697    sf_length: i32,
698    nb_subfr: i32,
699    complexity: i32,
700) {
701    let mut target_ptr: *const f32 = 0 as *const f32;
702    let mut basis_ptr: *const f32 = 0 as *const f32;
703    let mut energy: f64 = 0.;
704    let mut k: i32 = 0;
705    let mut i: i32 = 0;
706    let mut j: i32 = 0;
707    let mut lag_counter: i32 = 0;
708    let mut nb_cbk_search: i32 = 0;
709    let mut delta: i32 = 0;
710    let mut idx: i32 = 0;
711    let mut cbk_size: i32 = 0;
712    let mut lag_diff: i32 = 0;
713    let mut scratch_mem: [f32; 22] = [0.; 22];
714    let mut Lag_range_ptr: *const i8 = 0 as *const i8;
715    let mut Lag_CB_ptr: *const i8 = 0 as *const i8;
716    assert!(complexity >= 0);
717    assert!(complexity <= 2);
718    if nb_subfr == PE_MAX_NB_SUBFR {
719        Lag_range_ptr = &*(*(*silk_Lag_range_stage3.as_ptr().offset(complexity as isize))
720            .as_ptr()
721            .offset(0 as isize))
722        .as_ptr()
723        .offset(0 as isize) as *const i8;
724        Lag_CB_ptr = &*(*silk_CB_lags_stage3.as_ptr().offset(0 as isize))
725            .as_ptr()
726            .offset(0 as isize) as *const i8;
727        nb_cbk_search = silk_nb_cbk_searchs_stage3[complexity as usize] as i32;
728        cbk_size = PE_NB_CBKS_STAGE3_MAX;
729    } else {
730        assert!(nb_subfr == 4 >> 1);
731        Lag_range_ptr = &*(*silk_Lag_range_stage3_10_ms.as_ptr().offset(0 as isize))
732            .as_ptr()
733            .offset(0 as isize) as *const i8;
734        Lag_CB_ptr = &*(*silk_CB_lags_stage3_10_ms.as_ptr().offset(0 as isize))
735            .as_ptr()
736            .offset(0 as isize) as *const i8;
737        nb_cbk_search = PE_NB_CBKS_STAGE3_10MS;
738        cbk_size = PE_NB_CBKS_STAGE3_10MS;
739    }
740    target_ptr = &*frame.offset(((sf_length as u32) << 2) as i32 as isize) as *const f32;
741    k = 0;
742    while k < nb_subfr {
743        lag_counter = 0;
744        basis_ptr = target_ptr
745            .offset(-((start_lag + *Lag_range_ptr.offset((k * 2 + 0) as isize) as i32) as isize));
746        energy = silk_energy_FLP(basis_ptr, sf_length) + 1e-3f64;
747        scratch_mem[lag_counter as usize] = energy as f32;
748        lag_counter += 1;
749        lag_diff = *Lag_range_ptr.offset((k * 2 + 1) as isize) as i32
750            - *Lag_range_ptr.offset((k * 2 + 0) as isize) as i32
751            + 1;
752        i = 1;
753        while i < lag_diff {
754            energy -= *basis_ptr.offset((sf_length - i) as isize) as f64
755                * *basis_ptr.offset((sf_length - i) as isize) as f64;
756            energy += *basis_ptr.offset(-i as isize) as f64 * *basis_ptr.offset(-i as isize) as f64;
757            scratch_mem[lag_counter as usize] = energy as f32;
758            lag_counter += 1;
759            i += 1;
760        }
761        delta = *Lag_range_ptr.offset((k * 2 + 0) as isize) as i32;
762        i = 0;
763        while i < nb_cbk_search {
764            idx = *Lag_CB_ptr.offset((k * cbk_size + i) as isize) as i32 - delta;
765            j = 0;
766            while j < PE_NB_STAGE3_LAGS {
767                (*energies_st3.offset(k as isize))[i as usize][j as usize] =
768                    scratch_mem[(idx + j) as usize];
769                j += 1;
770            }
771            i += 1;
772        }
773        target_ptr = target_ptr.offset(sf_length as isize);
774        k += 1;
775    }
776}