unsafe-libopus 0.2.0

libopus transpiled to rust by c2rust
Documentation
use crate::celt::bands::SPREAD_NONE;
use std::f32::consts::PI;

pub mod arch_h {
    pub type opus_val16 = f32;
    pub type opus_val32 = f32;
    pub type celt_norm = f32;
    pub const EPSILON: f32 = 1e-15f32;
}
use self::arch_h::{celt_norm, opus_val16, opus_val32, EPSILON};
use crate::celt::cwrs::{decode_pulses, encode_pulses};
use crate::celt::entcode::celt_udiv;
use crate::celt::entdec::ec_dec;
use crate::celt::entenc::ec_enc;
use crate::celt::mathops::{celt_cos_norm, celt_rsqrt_norm, celt_sqrt, fast_atan2f};
use crate::celt::pitch::celt_inner_prod_c;

unsafe fn exp_rotation1(X: *mut celt_norm, len: i32, stride: i32, c: opus_val16, s: opus_val16) {
    let mut i: i32 = 0;
    let mut ms: opus_val16 = 0.;
    let mut Xptr: *mut celt_norm = 0 as *mut celt_norm;
    Xptr = X;
    ms = -s;
    i = 0;
    while i < len - stride {
        let mut x1: celt_norm = 0.;
        let mut x2: celt_norm = 0.;
        x1 = *Xptr.offset(0 as isize);
        x2 = *Xptr.offset(stride as isize);
        *Xptr.offset(stride as isize) = c * x2 + s * x1;
        let fresh0 = Xptr;
        Xptr = Xptr.offset(1);
        *fresh0 = c * x1 + ms * x2;
        i += 1;
    }
    Xptr = &mut *X.offset((len - 2 * stride - 1) as isize) as *mut celt_norm;
    i = len - 2 * stride - 1;
    while i >= 0 {
        let mut x1_0: celt_norm = 0.;
        let mut x2_0: celt_norm = 0.;
        x1_0 = *Xptr.offset(0 as isize);
        x2_0 = *Xptr.offset(stride as isize);
        *Xptr.offset(stride as isize) = c * x2_0 + s * x1_0;
        let fresh1 = Xptr;
        Xptr = Xptr.offset(-1);
        *fresh1 = c * x1_0 + ms * x2_0;
        i -= 1;
    }
}
pub unsafe fn exp_rotation(
    X: *mut celt_norm,
    mut len: i32,
    dir: i32,
    stride: i32,
    K: i32,
    spread: i32,
) {
    static SPREAD_FACTOR: [i32; 3] = [15, 10, 5];
    let mut i: i32 = 0;
    let mut c: opus_val16 = 0.;
    let mut s: opus_val16 = 0.;
    let mut gain: opus_val16 = 0.;
    let mut theta: opus_val16 = 0.;
    let mut stride2: i32 = 0;
    let mut factor: i32 = 0;
    if 2 * K >= len || spread == SPREAD_NONE {
        return;
    }
    factor = SPREAD_FACTOR[(spread - 1) as usize];
    gain = 1.0f32 * len as opus_val32 / (len + factor * K) as opus_val32;
    theta = 0.5f32 * (gain * gain);
    c = celt_cos_norm(theta);
    s = celt_cos_norm(1.0f32 - theta);
    if len >= 8 * stride {
        stride2 = 1;
        while (stride2 * stride2 + stride2) * stride + (stride >> 2) < len {
            stride2 += 1;
        }
    }
    len = celt_udiv(len as u32, stride as u32) as i32;
    i = 0;
    while i < stride {
        if dir < 0 {
            if stride2 != 0 {
                exp_rotation1(X.offset((i * len) as isize), len, stride2, s, c);
            }
            exp_rotation1(X.offset((i * len) as isize), len, 1, c, s);
        } else {
            exp_rotation1(X.offset((i * len) as isize), len, 1, c, -s);
            if stride2 != 0 {
                exp_rotation1(X.offset((i * len) as isize), len, stride2, s, -c);
            }
        }
        i += 1;
    }
}
unsafe fn normalise_residual(
    iy: *mut i32,
    X: *mut celt_norm,
    N: i32,
    Ryy: opus_val32,
    gain: opus_val16,
) {
    let mut i: i32 = 0;
    let mut t: opus_val32 = 0.;
    let mut g: opus_val16 = 0.;
    t = Ryy;
    g = celt_rsqrt_norm(t) * gain;
    i = 0;
    loop {
        *X.offset(i as isize) = g * *iy.offset(i as isize) as opus_val32;
        i += 1;
        if !(i < N) {
            break;
        }
    }
}
unsafe fn extract_collapse_mask(iy: *mut i32, N: i32, B: i32) -> u32 {
    let mut collapse_mask: u32 = 0;
    let mut N0: i32 = 0;
    let mut i: i32 = 0;
    if B <= 1 {
        return 1;
    }
    N0 = celt_udiv(N as u32, B as u32) as i32;
    collapse_mask = 0;
    i = 0;
    loop {
        let mut j: i32 = 0;
        let mut tmp: u32 = 0;
        j = 0;
        loop {
            tmp |= *iy.offset((i * N0 + j) as isize) as u32;
            j += 1;
            if !(j < N0) {
                break;
            }
        }
        collapse_mask |= (((tmp != 0) as i32) << i) as u32;
        i += 1;
        if !(i < B) {
            break;
        }
    }
    return collapse_mask;
}
pub unsafe fn op_pvq_search_c(
    X: *mut celt_norm,
    iy: *mut i32,
    K: i32,
    N: i32,
    _arch: i32,
) -> opus_val16 {
    let mut i: i32 = 0;
    let mut j: i32 = 0;
    let mut pulsesLeft: i32 = 0;
    let mut sum: opus_val32 = 0.;
    let mut xy: opus_val32 = 0.;
    let mut yy: opus_val16 = 0.;
    let vla = N as usize;
    let mut y: Vec<celt_norm> = ::std::vec::from_elem(0., vla);
    let vla_0 = N as usize;
    let mut signx: Vec<i32> = ::std::vec::from_elem(0, vla_0);
    sum = 0 as opus_val32;
    j = 0;
    loop {
        *signx.as_mut_ptr().offset(j as isize) = (*X.offset(j as isize) < 0 as f32) as i32;
        *X.offset(j as isize) = (*X.offset(j as isize)).abs();
        *iy.offset(j as isize) = 0;
        *y.as_mut_ptr().offset(j as isize) = 0 as celt_norm;
        j += 1;
        if !(j < N) {
            break;
        }
    }
    yy = 0 as opus_val16;
    xy = yy;
    pulsesLeft = K;
    if K > N >> 1 {
        let mut rcp: opus_val16 = 0.;
        j = 0;
        loop {
            sum += *X.offset(j as isize);
            j += 1;
            if !(j < N) {
                break;
            }
        }
        if !(sum > EPSILON && sum < 64 as f32) {
            *X.offset(0 as isize) = 1.0f32;
            j = 1;
            loop {
                *X.offset(j as isize) = 0 as celt_norm;
                j += 1;
                if !(j < N) {
                    break;
                }
            }
            sum = 1.0f32;
        }
        rcp = (K as f32 + 0.8f32) * (1.0f32 / sum);
        j = 0;
        loop {
            *iy.offset(j as isize) = (rcp * *X.offset(j as isize)).floor() as i32;
            *y.as_mut_ptr().offset(j as isize) = *iy.offset(j as isize) as celt_norm;
            yy = yy + *y.as_mut_ptr().offset(j as isize) * *y.as_mut_ptr().offset(j as isize);
            xy = xy + *X.offset(j as isize) * *y.as_mut_ptr().offset(j as isize);
            let ref mut fresh2 = *y.as_mut_ptr().offset(j as isize);
            *fresh2 *= 2 as f32;
            pulsesLeft -= *iy.offset(j as isize);
            j += 1;
            if !(j < N) {
                break;
            }
        }
    }
    if pulsesLeft > N + 3 {
        let tmp: opus_val16 = pulsesLeft as opus_val16;
        yy = yy + tmp * tmp;
        yy = yy + tmp * *y.as_mut_ptr().offset(0 as isize);
        *iy.offset(0 as isize) += pulsesLeft;
        pulsesLeft = 0;
    }
    i = 0;
    while i < pulsesLeft {
        let mut Rxy: opus_val16 = 0.;
        let mut Ryy: opus_val16 = 0.;
        let mut best_id: i32 = 0;
        let mut best_num: opus_val32 = 0.;
        let mut best_den: opus_val16 = 0.;
        best_id = 0;
        yy = yy + 1 as f32;
        Rxy = xy + *X.offset(0 as isize);
        Ryy = yy + *y.as_mut_ptr().offset(0 as isize);
        Rxy = Rxy * Rxy;
        best_den = Ryy;
        best_num = Rxy;
        j = 1;
        loop {
            Rxy = xy + *X.offset(j as isize);
            Ryy = yy + *y.as_mut_ptr().offset(j as isize);
            Rxy = Rxy * Rxy;
            if (best_den * Rxy > Ryy * best_num) as i32 as i64 != 0 {
                best_den = Ryy;
                best_num = Rxy;
                best_id = j;
            }
            j += 1;
            if !(j < N) {
                break;
            }
        }
        xy = xy + *X.offset(best_id as isize);
        yy = yy + *y.as_mut_ptr().offset(best_id as isize);
        let ref mut fresh3 = *y.as_mut_ptr().offset(best_id as isize);
        *fresh3 += 2 as f32;
        let ref mut fresh4 = *iy.offset(best_id as isize);
        *fresh4 += 1;
        i += 1;
    }
    j = 0;
    loop {
        *iy.offset(j as isize) = (*iy.offset(j as isize) ^ -*signx.as_mut_ptr().offset(j as isize))
            + *signx.as_mut_ptr().offset(j as isize);
        j += 1;
        if !(j < N) {
            break;
        }
    }
    return yy;
}
pub unsafe fn alg_quant(
    X: *mut celt_norm,
    N: i32,
    K: i32,
    spread: i32,
    B: i32,
    enc: &mut ec_enc,
    gain: opus_val16,
    resynth: i32,
    arch: i32,
) -> u32 {
    let mut yy: opus_val16 = 0.;
    let mut collapse_mask: u32 = 0;
    assert!(K > 0);
    assert!(N > 1);
    let vla = (N + 3) as usize;
    let mut iy: Vec<i32> = ::std::vec::from_elem(0, vla);
    exp_rotation(X, N, 1, B, K, spread);
    yy = op_pvq_search_c(X, iy.as_mut_ptr(), K, N, arch);
    encode_pulses(iy.as_mut_ptr(), N, K, enc);
    if resynth != 0 {
        normalise_residual(iy.as_mut_ptr(), X, N, yy, gain);
        exp_rotation(X, N, -1, B, K, spread);
    }
    collapse_mask = extract_collapse_mask(iy.as_mut_ptr(), N, B);
    return collapse_mask;
}
pub unsafe fn alg_unquant(
    X: *mut celt_norm,
    N: i32,
    K: i32,
    spread: i32,
    B: i32,
    dec: &mut ec_dec,
    gain: opus_val16,
) -> u32 {
    let mut Ryy: opus_val32 = 0.;
    let mut collapse_mask: u32 = 0;
    assert!(K > 0);
    assert!(N > 1);
    let vla = N as usize;
    let mut iy: Vec<i32> = ::std::vec::from_elem(0, vla);
    Ryy = decode_pulses(iy.as_mut_ptr(), N, K, dec);
    normalise_residual(iy.as_mut_ptr(), X, N, Ryy, gain);
    exp_rotation(X, N, -1, B, K, spread);
    collapse_mask = extract_collapse_mask(iy.as_mut_ptr(), N, B);
    return collapse_mask;
}
pub unsafe fn renormalise_vector(X: *mut celt_norm, N: i32, gain: opus_val16, _arch: i32) {
    let mut i: i32 = 0;
    let mut E: opus_val32 = 0.;
    let mut g: opus_val16 = 0.;
    let mut t: opus_val32 = 0.;
    let mut xptr: *mut celt_norm = 0 as *mut celt_norm;
    E = EPSILON + celt_inner_prod_c(X, X, N);
    t = E;
    g = celt_rsqrt_norm(t) * gain;
    xptr = X;
    i = 0;
    while i < N {
        *xptr = g * *xptr;
        xptr = xptr.offset(1);
        i += 1;
    }
}
pub unsafe fn stereo_itheta(
    X: *const celt_norm,
    Y: *const celt_norm,
    stereo: i32,
    N: i32,
    _arch: i32,
) -> i32 {
    let mut i: i32 = 0;
    let mut itheta: i32 = 0;
    let mut mid: opus_val16 = 0.;
    let mut side: opus_val16 = 0.;
    let mut Emid: opus_val32 = 0.;
    let mut Eside: opus_val32 = 0.;
    Eside = EPSILON;
    Emid = Eside;
    if stereo != 0 {
        i = 0;
        while i < N {
            let mut m: celt_norm = 0.;
            let mut s: celt_norm = 0.;
            m = *X.offset(i as isize) + *Y.offset(i as isize);
            s = *X.offset(i as isize) - *Y.offset(i as isize);
            Emid = Emid + m * m;
            Eside = Eside + s * s;
            i += 1;
        }
    } else {
        Emid += celt_inner_prod_c(X, X, N);
        Eside += celt_inner_prod_c(Y, Y, N);
    }
    mid = celt_sqrt(Emid);
    side = celt_sqrt(Eside);
    itheta = (0.5f32 + 16384 as f32 * 0.63662f32 * fast_atan2f(side, mid)).floor() as i32;
    return itheta;
}