unsafe-libopus 0.2.0

libopus transpiled to rust by c2rust
Documentation
pub mod tuning_parameters_h {
    pub const FIND_LPC_COND_FAC: f32 = 1e-5f32;
}
pub use self::tuning_parameters_h::FIND_LPC_COND_FAC;
use crate::externs::{memcpy, memset};
use crate::silk::float::energy_FLP::silk_energy_FLP;
use crate::silk::float::inner_product_FLP::silk_inner_product_FLP;

pub unsafe fn silk_burg_modified_FLP(
    A: *mut f32,
    x: *const f32,
    minInvGain: f32,
    subfr_length: i32,
    nb_subfr: i32,
    D: i32,
) -> f32 {
    let mut k: i32 = 0;
    let mut n: i32 = 0;
    let mut s: i32 = 0;
    let mut reached_max_gain: i32 = 0;
    let mut C0: f64 = 0.;
    let mut invGain: f64 = 0.;
    let mut num: f64 = 0.;
    let mut nrg_f: f64 = 0.;
    let mut nrg_b: f64 = 0.;
    let mut rc: f64 = 0.;
    let mut Atmp: f64 = 0.;
    let mut tmp1: f64 = 0.;
    let mut tmp2: f64 = 0.;
    let mut x_ptr: *const f32 = 0 as *const f32;
    let mut C_first_row: [f64; 24] = [0.; 24];
    let mut C_last_row: [f64; 24] = [0.; 24];
    let mut CAf: [f64; 25] = [0.; 25];
    let mut CAb: [f64; 25] = [0.; 25];
    let mut Af: [f64; 24] = [0.; 24];
    assert!(subfr_length * nb_subfr <= 384);
    C0 = silk_energy_FLP(x, nb_subfr * subfr_length);
    memset(
        C_first_row.as_mut_ptr() as *mut core::ffi::c_void,
        0,
        24_u64.wrapping_mul(::core::mem::size_of::<f64>() as u64),
    );
    s = 0;
    while s < nb_subfr {
        x_ptr = x.offset((s * subfr_length) as isize);
        n = 1;
        while n < D + 1 {
            C_first_row[(n - 1) as usize] +=
                silk_inner_product_FLP(x_ptr, x_ptr.offset(n as isize), subfr_length - n);
            n += 1;
        }
        s += 1;
    }
    memcpy(
        C_last_row.as_mut_ptr() as *mut core::ffi::c_void,
        C_first_row.as_mut_ptr() as *const core::ffi::c_void,
        24_u64.wrapping_mul(::core::mem::size_of::<f64>() as u64),
    );
    CAf[0 as usize] = C0 + FIND_LPC_COND_FAC as f64 * C0 + 1e-9f32 as f64;
    CAb[0 as usize] = CAf[0 as usize];
    invGain = 1.0f32 as f64;
    reached_max_gain = 0;
    n = 0;
    while n < D {
        s = 0;
        while s < nb_subfr {
            x_ptr = x.offset((s * subfr_length) as isize);
            tmp1 = *x_ptr.offset(n as isize) as f64;
            tmp2 = *x_ptr.offset((subfr_length - n - 1) as isize) as f64;
            k = 0;
            while k < n {
                C_first_row[k as usize] -=
                    (*x_ptr.offset(n as isize) * *x_ptr.offset((n - k - 1) as isize)) as f64;
                C_last_row[k as usize] -= (*x_ptr.offset((subfr_length - n - 1) as isize)
                    * *x_ptr.offset((subfr_length - n + k) as isize))
                    as f64;
                Atmp = Af[k as usize];
                tmp1 += *x_ptr.offset((n - k - 1) as isize) as f64 * Atmp;
                tmp2 += *x_ptr.offset((subfr_length - n + k) as isize) as f64 * Atmp;
                k += 1;
            }
            k = 0;
            while k <= n {
                CAf[k as usize] -= tmp1 * *x_ptr.offset((n - k) as isize) as f64;
                CAb[k as usize] -= tmp2 * *x_ptr.offset((subfr_length - n + k - 1) as isize) as f64;
                k += 1;
            }
            s += 1;
        }
        tmp1 = C_first_row[n as usize];
        tmp2 = C_last_row[n as usize];
        k = 0;
        while k < n {
            Atmp = Af[k as usize];
            tmp1 += C_last_row[(n - k - 1) as usize] * Atmp;
            tmp2 += C_first_row[(n - k - 1) as usize] * Atmp;
            k += 1;
        }
        CAf[(n + 1) as usize] = tmp1;
        CAb[(n + 1) as usize] = tmp2;
        num = CAb[(n + 1) as usize];
        nrg_b = CAb[0 as usize];
        nrg_f = CAf[0 as usize];
        k = 0;
        while k < n {
            Atmp = Af[k as usize];
            num += CAb[(n - k) as usize] * Atmp;
            nrg_b += CAb[(k + 1) as usize] * Atmp;
            nrg_f += CAf[(k + 1) as usize] * Atmp;
            k += 1;
        }
        rc = -2.0f64 * num / (nrg_f + nrg_b);
        tmp1 = invGain * (1.0f64 - rc * rc);
        if tmp1 <= minInvGain as f64 {
            rc = (1.0f64 - minInvGain as f64 / invGain).sqrt();
            if num > 0 as f64 {
                rc = -rc;
            }
            invGain = minInvGain as f64;
            reached_max_gain = 1;
        } else {
            invGain = tmp1;
        }
        k = 0;
        while k < n + 1 >> 1 {
            tmp1 = Af[k as usize];
            tmp2 = Af[(n - k - 1) as usize];
            Af[k as usize] = tmp1 + rc * tmp2;
            Af[(n - k - 1) as usize] = tmp2 + rc * tmp1;
            k += 1;
        }
        Af[n as usize] = rc;
        if reached_max_gain != 0 {
            k = n + 1;
            while k < D {
                Af[k as usize] = 0.0f64;
                k += 1;
            }
            break;
        } else {
            k = 0;
            while k <= n + 1 {
                tmp1 = CAf[k as usize];
                CAf[k as usize] += rc * CAb[(n - k + 1) as usize];
                CAb[(n - k + 1) as usize] += rc * tmp1;
                k += 1;
            }
            n += 1;
        }
    }
    if reached_max_gain != 0 {
        k = 0;
        while k < D {
            *A.offset(k as isize) = -Af[k as usize] as f32;
            k += 1;
        }
        s = 0;
        while s < nb_subfr {
            C0 -= silk_energy_FLP(x.offset((s * subfr_length) as isize), D);
            s += 1;
        }
        nrg_f = C0 * invGain;
    } else {
        nrg_f = CAf[0 as usize];
        tmp1 = 1.0f64;
        k = 0;
        while k < D {
            Atmp = Af[k as usize];
            nrg_f += CAf[(k + 1) as usize] * Atmp;
            tmp1 += Atmp * Atmp;
            *A.offset(k as isize) = -Atmp as f32;
            k += 1;
        }
        nrg_f -= FIND_LPC_COND_FAC as f64 * C0 * tmp1;
    }
    return nrg_f as f32;
}