unsafe-libopus 0.2.0

libopus transpiled to rust by c2rust
Documentation
pub mod SigProc_FLP_h {
    #[inline]
    pub unsafe fn silk_sigmoid(x: f32) -> f32 {
        return (1.0f64 / (1.0f64 + (-x as f64).exp())) as f32;
    }
    #[inline]
    pub unsafe fn silk_log2(x: f64) -> f32 {
        return (3.32192809488736f64 * x.log10()) as f32;
    }
}
pub mod tuning_parameters_h {
    pub const FIND_PITCH_WHITE_NOISE_FRACTION: f32 = 1e-3f32;
    pub const BG_SNR_DECR_dB: f32 = 2.0f32;
    pub const HARM_SNR_INCR_dB: f32 = 2.0f32;
    pub const ENERGY_VARIATION_THRESHOLD_QNT_OFFSET: f32 = 0.6f32;
    pub const SHAPE_WHITE_NOISE_FRACTION: f32 = 3e-5f32;
    pub const BANDWIDTH_EXPANSION: f32 = 0.94f32;
    pub const HARMONIC_SHAPING: f32 = 0.3f32;
    pub const HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING: f32 = 0.2f32;
    pub const HP_NOISE_COEF: f32 = 0.25f32;
    pub const HARM_HP_NOISE_COEF: f32 = 0.35f32;
    pub const LOW_FREQ_SHAPING: f32 = 4.0f32;
    pub const LOW_QUALITY_LOW_FREQ_SHAPING_DECR: f32 = 0.5f32;
    pub const SUBFR_SMTH_COEF: f32 = 0.4f32;
}

pub use self::tuning_parameters_h::{
    BG_SNR_DECR_dB, HARM_SNR_INCR_dB, BANDWIDTH_EXPANSION, ENERGY_VARIATION_THRESHOLD_QNT_OFFSET,
    FIND_PITCH_WHITE_NOISE_FRACTION, HARMONIC_SHAPING, HARM_HP_NOISE_COEF,
    HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING, HP_NOISE_COEF, LOW_FREQ_SHAPING,
    LOW_QUALITY_LOW_FREQ_SHAPING_DECR, SHAPE_WHITE_NOISE_FRACTION, SUBFR_SMTH_COEF,
};
use crate::celt::mathops::celt_sqrt;
use crate::silk::define::{MAX_SHAPE_LPC_ORDER, MIN_QGAIN_DB, TYPE_VOICED, USE_HARM_SHAPING};
use crate::silk::float::structs_FLP::{
    silk_encoder_control_FLP, silk_encoder_state_FLP, silk_shape_state_FLP,
};

pub use self::SigProc_FLP_h::{silk_log2, silk_sigmoid};
use crate::externs::memcpy;
use crate::silk::float::apply_sine_window_FLP::silk_apply_sine_window_FLP;
use crate::silk::float::autocorrelation_FLP::silk_autocorrelation_FLP;
use crate::silk::float::bwexpander_FLP::silk_bwexpander_FLP;
use crate::silk::float::energy_FLP::silk_energy_FLP;
use crate::silk::float::k2a_FLP::silk_k2a_FLP;
use crate::silk::float::schur_FLP::silk_schur_FLP;
use crate::silk::float::warped_autocorrelation_FLP::silk_warped_autocorrelation_FLP;
use crate::silk::mathops::silk_exp2;

#[inline]
unsafe fn warped_gain(coefs: *const f32, mut lambda: f32, order: i32) -> f32 {
    let mut i: i32 = 0;
    let mut gain: f32 = 0.;
    lambda = -lambda;
    gain = *coefs.offset((order - 1) as isize);
    i = order - 2;
    while i >= 0 {
        gain = lambda * gain + *coefs.offset(i as isize);
        i -= 1;
    }
    return 1.0f32 / (1.0f32 - lambda * gain);
}
#[inline]
unsafe fn warped_true2monic_coefs(coefs: *mut f32, lambda: f32, limit: f32, order: i32) {
    let mut i: i32 = 0;
    let mut iter: i32 = 0;
    let mut ind: i32 = 0;
    let mut tmp: f32 = 0.;
    let mut maxabs: f32 = 0.;
    let mut chirp: f32 = 0.;
    let mut gain: f32 = 0.;
    i = order - 1;
    while i > 0 {
        *coefs.offset((i - 1) as isize) -= lambda * *coefs.offset(i as isize);
        i -= 1;
    }
    gain = (1.0f32 - lambda * lambda) / (1.0f32 + lambda * *coefs.offset(0 as isize));
    i = 0;
    while i < order {
        *coefs.offset(i as isize) *= gain;
        i += 1;
    }
    iter = 0;
    while iter < 10 {
        maxabs = -1.0f32;
        i = 0;
        while i < order {
            tmp = (*coefs.offset(i as isize)).abs();
            if tmp > maxabs {
                maxabs = tmp;
                ind = i;
            }
            i += 1;
        }
        if maxabs <= limit {
            return;
        }
        i = 1;
        while i < order {
            *coefs.offset((i - 1) as isize) += lambda * *coefs.offset(i as isize);
            i += 1;
        }
        gain = 1.0f32 / gain;
        i = 0;
        while i < order {
            *coefs.offset(i as isize) *= gain;
            i += 1;
        }
        chirp = 0.99f32
            - (0.8f32 + 0.1f32 * iter as f32) * (maxabs - limit) / (maxabs * (ind + 1) as f32);
        silk_bwexpander_FLP(coefs, order, chirp);
        i = order - 1;
        while i > 0 {
            *coefs.offset((i - 1) as isize) -= lambda * *coefs.offset(i as isize);
            i -= 1;
        }
        gain = (1.0f32 - lambda * lambda) / (1.0f32 + lambda * *coefs.offset(0 as isize));
        i = 0;
        while i < order {
            *coefs.offset(i as isize) *= gain;
            i += 1;
        }
        iter += 1;
    }
}
#[inline]
unsafe fn limit_coefs(coefs: *mut f32, limit: f32, order: i32) {
    let mut i: i32 = 0;
    let mut iter: i32 = 0;
    let mut ind: i32 = 0;
    let mut tmp: f32 = 0.;
    let mut maxabs: f32 = 0.;
    let mut chirp: f32 = 0.;
    iter = 0;
    while iter < 10 {
        maxabs = -1.0f32;
        i = 0;
        while i < order {
            tmp = (*coefs.offset(i as isize)).abs();
            if tmp > maxabs {
                maxabs = tmp;
                ind = i;
            }
            i += 1;
        }
        if maxabs <= limit {
            return;
        }
        chirp = 0.99f32
            - (0.8f32 + 0.1f32 * iter as f32) * (maxabs - limit) / (maxabs * (ind + 1) as f32);
        silk_bwexpander_FLP(coefs, order, chirp);
        iter += 1;
    }
}
pub unsafe fn silk_noise_shape_analysis_FLP(
    psEnc: *mut silk_encoder_state_FLP,
    psEncCtrl: *mut silk_encoder_control_FLP,
    pitch_res: *const f32,
    x: *const f32,
) {
    let psShapeSt: *mut silk_shape_state_FLP = &mut (*psEnc).sShape;
    let mut k: i32 = 0;
    let mut nSamples: i32 = 0;
    let mut nSegs: i32 = 0;
    let mut SNR_adj_dB: f32 = 0.;
    let mut HarmShapeGain: f32 = 0.;
    let mut Tilt: f32 = 0.;
    let mut nrg: f32 = 0.;
    let mut log_energy: f32 = 0.;
    let mut log_energy_prev: f32 = 0.;
    let mut energy_variation: f32 = 0.;
    let mut BWExp: f32 = 0.;
    let mut gain_mult: f32 = 0.;
    let mut gain_add: f32 = 0.;
    let mut strength: f32 = 0.;
    let mut b: f32 = 0.;
    let mut warping: f32 = 0.;
    let mut x_windowed: [f32; 240] = [0.; 240];
    let mut auto_corr: [f32; 25] = [0.; 25];
    let mut rc: [f32; 25] = [0.; 25];
    let mut x_ptr: *const f32 = 0 as *const f32;
    let mut pitch_res_ptr: *const f32 = 0 as *const f32;
    x_ptr = x.offset(-((*psEnc).sCmn.la_shape as isize));
    SNR_adj_dB = (*psEnc).sCmn.SNR_dB_Q7 as f32 * (1 as f32 / 128.0f32);
    (*psEncCtrl).input_quality = 0.5f32
        * ((*psEnc).sCmn.input_quality_bands_Q15[0 as usize]
            + (*psEnc).sCmn.input_quality_bands_Q15[1 as usize]) as f32
        * (1.0f32 / 32768.0f32);
    (*psEncCtrl).coding_quality = silk_sigmoid(0.25f32 * (SNR_adj_dB - 20.0f32));
    if (*psEnc).sCmn.useCBR == 0 {
        b = 1.0f32 - (*psEnc).sCmn.speech_activity_Q8 as f32 * (1.0f32 / 256.0f32);
        SNR_adj_dB -= BG_SNR_DECR_dB
            * (*psEncCtrl).coding_quality
            * (0.5f32 + 0.5f32 * (*psEncCtrl).input_quality)
            * b
            * b;
    }
    if (*psEnc).sCmn.indices.signalType as i32 == TYPE_VOICED {
        SNR_adj_dB += HARM_SNR_INCR_dB * (*psEnc).LTPCorr;
    } else {
        SNR_adj_dB += (-0.4f32 * (*psEnc).sCmn.SNR_dB_Q7 as f32 * (1 as f32 / 128.0f32) + 6.0f32)
            * (1.0f32 - (*psEncCtrl).input_quality);
    }
    if (*psEnc).sCmn.indices.signalType as i32 == TYPE_VOICED {
        (*psEnc).sCmn.indices.quantOffsetType = 0;
    } else {
        nSamples = 2 * (*psEnc).sCmn.fs_kHz;
        energy_variation = 0.0f32;
        log_energy_prev = 0.0f32;
        pitch_res_ptr = pitch_res;
        nSegs = 5 * (*psEnc).sCmn.nb_subfr as i16 as i32 / 2;
        k = 0;
        while k < nSegs {
            nrg = nSamples as f32 + silk_energy_FLP(pitch_res_ptr, nSamples) as f32;
            log_energy = silk_log2(nrg as f64);
            if k > 0 {
                energy_variation += (log_energy - log_energy_prev).abs();
            }
            log_energy_prev = log_energy;
            pitch_res_ptr = pitch_res_ptr.offset(nSamples as isize);
            k += 1;
        }
        if energy_variation > ENERGY_VARIATION_THRESHOLD_QNT_OFFSET * (nSegs - 1) as f32 {
            (*psEnc).sCmn.indices.quantOffsetType = 0;
        } else {
            (*psEnc).sCmn.indices.quantOffsetType = 1;
        }
    }
    strength = FIND_PITCH_WHITE_NOISE_FRACTION * (*psEncCtrl).predGain;
    BWExp = BANDWIDTH_EXPANSION / (1.0f32 + strength * strength);
    warping = (*psEnc).sCmn.warping_Q16 as f32 / 65536.0f32 + 0.01f32 * (*psEncCtrl).coding_quality;
    k = 0;
    while k < (*psEnc).sCmn.nb_subfr {
        let mut shift: i32 = 0;
        let mut slope_part: i32 = 0;
        let mut flat_part: i32 = 0;
        flat_part = (*psEnc).sCmn.fs_kHz * 3;
        slope_part = ((*psEnc).sCmn.shapeWinLength - flat_part) / 2;
        silk_apply_sine_window_FLP(x_windowed.as_mut_ptr(), x_ptr, 1, slope_part);
        shift = slope_part;
        memcpy(
            x_windowed.as_mut_ptr().offset(shift as isize) as *mut core::ffi::c_void,
            x_ptr.offset(shift as isize) as *const core::ffi::c_void,
            (flat_part as u64).wrapping_mul(::core::mem::size_of::<f32>() as u64),
        );
        shift += flat_part;
        silk_apply_sine_window_FLP(
            x_windowed.as_mut_ptr().offset(shift as isize),
            x_ptr.offset(shift as isize),
            2,
            slope_part,
        );
        x_ptr = x_ptr.offset((*psEnc).sCmn.subfr_length as isize);
        if (*psEnc).sCmn.warping_Q16 > 0 {
            silk_warped_autocorrelation_FLP(
                auto_corr.as_mut_ptr(),
                x_windowed.as_mut_ptr(),
                warping,
                (*psEnc).sCmn.shapeWinLength,
                (*psEnc).sCmn.shapingLPCOrder,
            );
        } else {
            silk_autocorrelation_FLP(
                auto_corr.as_mut_ptr(),
                x_windowed.as_mut_ptr(),
                (*psEnc).sCmn.shapeWinLength,
                (*psEnc).sCmn.shapingLPCOrder + 1,
            );
        }
        auto_corr[0 as usize] += auto_corr[0 as usize] * SHAPE_WHITE_NOISE_FRACTION + 1.0f32;
        nrg = silk_schur_FLP(
            rc.as_mut_ptr(),
            auto_corr.as_mut_ptr() as *const f32,
            (*psEnc).sCmn.shapingLPCOrder,
        );
        silk_k2a_FLP(
            &mut *((*psEncCtrl).AR)
                .as_mut_ptr()
                .offset((k * MAX_SHAPE_LPC_ORDER) as isize),
            rc.as_mut_ptr(),
            (*psEnc).sCmn.shapingLPCOrder,
        );
        (*psEncCtrl).Gains[k as usize] = celt_sqrt(nrg);
        if (*psEnc).sCmn.warping_Q16 > 0 {
            (*psEncCtrl).Gains[k as usize] *= warped_gain(
                &mut *((*psEncCtrl).AR)
                    .as_mut_ptr()
                    .offset((k * MAX_SHAPE_LPC_ORDER) as isize),
                warping,
                (*psEnc).sCmn.shapingLPCOrder,
            );
        }
        silk_bwexpander_FLP(
            &mut *((*psEncCtrl).AR)
                .as_mut_ptr()
                .offset((k * MAX_SHAPE_LPC_ORDER) as isize),
            (*psEnc).sCmn.shapingLPCOrder,
            BWExp,
        );
        if (*psEnc).sCmn.warping_Q16 > 0 {
            warped_true2monic_coefs(
                &mut *((*psEncCtrl).AR)
                    .as_mut_ptr()
                    .offset((k * MAX_SHAPE_LPC_ORDER) as isize),
                warping,
                3.999f32,
                (*psEnc).sCmn.shapingLPCOrder,
            );
        } else {
            limit_coefs(
                &mut *((*psEncCtrl).AR)
                    .as_mut_ptr()
                    .offset((k * MAX_SHAPE_LPC_ORDER) as isize),
                3.999f32,
                (*psEnc).sCmn.shapingLPCOrder,
            );
        }
        k += 1;
    }
    gain_mult = silk_exp2(-0.16f32 * SNR_adj_dB);
    gain_add = silk_exp2(0.16f32 * MIN_QGAIN_DB as f32);
    k = 0;
    while k < (*psEnc).sCmn.nb_subfr {
        (*psEncCtrl).Gains[k as usize] *= gain_mult;
        (*psEncCtrl).Gains[k as usize] += gain_add;
        k += 1;
    }
    strength = LOW_FREQ_SHAPING
        * (1.0f32
            + LOW_QUALITY_LOW_FREQ_SHAPING_DECR
                * ((*psEnc).sCmn.input_quality_bands_Q15[0 as usize] as f32
                    * (1.0f32 / 32768.0f32)
                    - 1.0f32));
    strength *= (*psEnc).sCmn.speech_activity_Q8 as f32 * (1.0f32 / 256.0f32);
    if (*psEnc).sCmn.indices.signalType as i32 == TYPE_VOICED {
        k = 0;
        while k < (*psEnc).sCmn.nb_subfr {
            b = 0.2f32 / (*psEnc).sCmn.fs_kHz as f32
                + 3.0f32 / (*psEncCtrl).pitchL[k as usize] as f32;
            (*psEncCtrl).LF_MA_shp[k as usize] = -1.0f32 + b;
            (*psEncCtrl).LF_AR_shp[k as usize] = 1.0f32 - b - b * strength;
            k += 1;
        }
        Tilt = -HP_NOISE_COEF
            - (1 as f32 - HP_NOISE_COEF)
                * HARM_HP_NOISE_COEF
                * (*psEnc).sCmn.speech_activity_Q8 as f32
                * (1.0f32 / 256.0f32);
    } else {
        b = 1.3f32 / (*psEnc).sCmn.fs_kHz as f32;
        (*psEncCtrl).LF_MA_shp[0 as usize] = -1.0f32 + b;
        (*psEncCtrl).LF_AR_shp[0 as usize] = 1.0f32 - b - b * strength * 0.6f32;
        k = 1;
        while k < (*psEnc).sCmn.nb_subfr {
            (*psEncCtrl).LF_MA_shp[k as usize] = (*psEncCtrl).LF_MA_shp[0 as usize];
            (*psEncCtrl).LF_AR_shp[k as usize] = (*psEncCtrl).LF_AR_shp[0 as usize];
            k += 1;
        }
        Tilt = -HP_NOISE_COEF;
    }
    if USE_HARM_SHAPING != 0 && (*psEnc).sCmn.indices.signalType as i32 == TYPE_VOICED {
        HarmShapeGain = HARMONIC_SHAPING;
        HarmShapeGain += HIGH_RATE_OR_LOW_QUALITY_HARMONIC_SHAPING
            * (1.0f32 - (1.0f32 - (*psEncCtrl).coding_quality) * (*psEncCtrl).input_quality);
        HarmShapeGain *= celt_sqrt((*psEnc).LTPCorr);
    } else {
        HarmShapeGain = 0.0f32;
    }
    k = 0;
    while k < (*psEnc).sCmn.nb_subfr {
        (*psShapeSt).HarmShapeGain_smth +=
            SUBFR_SMTH_COEF * (HarmShapeGain - (*psShapeSt).HarmShapeGain_smth);
        (*psEncCtrl).HarmShapeGain[k as usize] = (*psShapeSt).HarmShapeGain_smth;
        (*psShapeSt).Tilt_smth += SUBFR_SMTH_COEF * (Tilt - (*psShapeSt).Tilt_smth);
        (*psEncCtrl).Tilt[k as usize] = (*psShapeSt).Tilt_smth;
        k += 1;
    }
}