opus-rs 0.1.1

Rust implementation of Opus codec
Documentation
use once_cell::sync::Lazy;

use crate::mdct::MdctLookup;

pub const BAND_ALLOCATION: [u8; 11 * 21] = [
    0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 90, 80, 75, 69, 63, 56, 49, 40,
    34, 29, 20, 18, 10, 0, 0, 0, 0, 0, 0, 0, 0, 110, 100, 90, 84, 78, 71, 65, 58, 51, 45, 39, 32,
    26, 20, 12, 0, 0, 0, 0, 0, 0, 0, 118, 110, 103, 93, 86, 80, 75, 70, 65, 59, 53, 47, 40, 31, 23,
    15, 4, 0, 0, 0, 0, 126, 119, 112, 104, 95, 89, 83, 78, 72, 66, 60, 54, 47, 39, 32, 25, 17, 12,
    1, 0, 0, 134, 127, 120, 114, 103, 97, 91, 85, 78, 72, 66, 60, 54, 47, 41, 35, 29, 23, 16, 10,
    1, 144, 137, 130, 124, 113, 107, 101, 95, 88, 82, 76, 70, 64, 57, 51, 45, 39, 33, 26, 15, 1,
    152, 145, 138, 132, 123, 117, 111, 105, 98, 92, 86, 80, 74, 67, 61, 55, 49, 43, 36, 20, 1, 162,
    155, 148, 142, 133, 127, 121, 115, 108, 102, 96, 90, 84, 77, 71, 65, 59, 53, 46, 30, 1, 172,
    165, 158, 152, 143, 137, 131, 125, 118, 112, 106, 100, 94, 87, 81, 75, 69, 63, 56, 45, 20, 200,
    200, 200, 200, 200, 200, 200, 198, 193, 188, 183, 178, 173, 168, 163, 158, 153, 148, 129, 104,
];

pub const CACHE_INDEX50: [i16; 105] = [
    -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 41, 41, 41, 82, 82, 123, 164, 200, 222, 0, 0, 0, 0,
    0, 0, 0, 0, 41, 41, 41, 41, 123, 123, 123, 164, 164, 240, 266, 283, 295, 41, 41, 41, 41, 41,
    41, 41, 41, 123, 123, 123, 123, 240, 240, 240, 266, 266, 305, 318, 328, 336, 123, 123, 123,
    123, 123, 123, 123, 123, 240, 240, 240, 240, 305, 305, 305, 318, 318, 343, 351, 358, 364, 240,
    240, 240, 240, 240, 240, 240, 240, 305, 305, 305, 305, 343, 343, 343, 351, 351, 370, 376, 382,
    387,
];

pub const CACHE_BITS50: [u8; 392] = [
    40, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7,
    7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 40, 15, 23, 28, 31, 34, 36, 38, 39, 41, 42, 43, 44, 45, 46, 47,
    47, 49, 50, 51, 52, 53, 54, 55, 55, 57, 58, 59, 60, 61, 62, 63, 63, 65, 66, 67, 68, 69, 70, 71,
    71, 40, 20, 33, 41, 48, 53, 57, 61, 64, 66, 69, 71, 73, 75, 76, 78, 80, 82, 85, 87, 89, 91, 92,
    94, 96, 98, 101, 103, 105, 107, 108, 110, 112, 114, 117, 119, 121, 123, 124, 126, 128, 40, 23,
    39, 51, 60, 67, 73, 79, 83, 87, 91, 94, 97, 100, 102, 105, 107, 111, 115, 118, 121, 124, 126,
    129, 131, 135, 139, 142, 145, 148, 150, 153, 155, 159, 163, 166, 169, 172, 174, 177, 179, 35,
    28, 49, 65, 78, 89, 99, 107, 114, 120, 126, 132, 136, 141, 145, 149, 153, 159, 165, 171, 176,
    180, 185, 189, 192, 199, 205, 211, 216, 220, 225, 229, 232, 239, 245, 251, 21, 33, 58, 79, 97,
    112, 125, 137, 148, 157, 166, 174, 182, 189, 195, 201, 207, 217, 227, 235, 243, 251, 17, 35,
    63, 86, 106, 123, 139, 152, 165, 177, 187, 197, 206, 214, 222, 230, 237, 250, 25, 31, 55, 75,
    91, 105, 117, 128, 138, 146, 154, 161, 168, 174, 180, 185, 190, 200, 208, 215, 222, 229, 235,
    240, 245, 255, 16, 36, 65, 89, 110, 128, 144, 159, 173, 185, 196, 207, 217, 226, 234, 242, 250,
    11, 41, 74, 103, 128, 151, 172, 191, 209, 225, 241, 255, 9, 43, 79, 110, 138, 163, 186, 207,
    227, 246, 12, 39, 71, 99, 123, 144, 164, 182, 198, 214, 228, 241, 253, 9, 44, 81, 113, 142,
    168, 192, 214, 235, 255, 7, 49, 90, 127, 160, 191, 220, 247, 6, 51, 95, 134, 170, 203, 234, 7,
    47, 87, 123, 155, 184, 212, 237, 6, 52, 97, 137, 174, 208, 240, 5, 57, 106, 151, 192, 231, 5,
    59, 111, 158, 202, 243, 5, 55, 103, 147, 187, 224, 5, 60, 113, 161, 206, 248, 4, 65, 122, 175,
    224, 4, 67, 127, 182, 234,
];

pub const CACHE_CAPS50: [u8; 168] = [
    224, 224, 224, 224, 224, 224, 224, 224, 160, 160, 160, 160, 185, 185, 185, 178, 178, 168, 134,
    61, 37, 224, 224, 224, 224, 224, 224, 224, 224, 240, 240, 240, 240, 207, 207, 207, 198, 198,
    183, 144, 66, 40, 160, 160, 160, 160, 160, 160, 160, 160, 185, 185, 185, 185, 193, 193, 193,
    183, 183, 172, 138, 64, 38, 240, 240, 240, 240, 240, 240, 240, 240, 207, 207, 207, 207, 204,
    204, 204, 193, 193, 180, 143, 66, 40, 185, 185, 185, 185, 185, 185, 185, 185, 193, 193, 193,
    193, 193, 193, 193, 183, 183, 172, 138, 65, 39, 207, 207, 207, 207, 207, 207, 207, 207, 204,
    204, 204, 204, 201, 201, 201, 188, 188, 176, 141, 66, 40, 193, 193, 193, 193, 193, 193, 193,
    193, 193, 193, 193, 193, 194, 194, 194, 184, 184, 173, 139, 65, 39, 204, 204, 204, 204, 204,
    204, 204, 204, 201, 201, 201, 201, 198, 198, 198, 187, 187, 175, 140, 66, 40,
];

pub struct PulseCache {
    pub size: usize,
    pub index: &'static [i16],
    pub bits: &'static [u8],
    pub caps: &'static [u8],
}

pub struct CeltMode {
    pub fs: i32,
    pub overlap: usize,
    pub nb_ebands: usize,
    pub eff_ebands: usize,
    pub preemph: [f32; 4],
    pub e_bands: &'static [i16],
    pub max_lm: usize,
    pub nb_short_mdcts: usize,
    pub short_mdct_size: usize,
    pub nb_alloc_vectors: usize,
    pub alloc_vectors: &'static [u8],
    pub alloc_stride: usize,
    pub log_n: &'static [i16],
    pub window: &'static [f32],
    pub mdct: MdctLookup,
    pub cache: PulseCache,
    pub e_means: &'static [f32],
}

pub const EBAND_5MS: [i16; 22] = [
    0, 1, 2, 3, 4, 5, 6, 7, 8, 10, 12, 14, 16, 20, 24, 28, 34, 40, 48, 60, 78, 100,
];

impl CeltMode {
    pub fn new_48000_960_120() -> Self {
        let short_mdct_size = 120;
        let nb_short_mdcts = 8;
        let max_lm = 3usize;
        let mdct = MdctLookup::new(2 * short_mdct_size * nb_short_mdcts, max_lm);
        Self {
            fs: 48000,
            overlap: 120,
            nb_ebands: 21,
            eff_ebands: 21,
            preemph: [0.85000610, 0.10000610, 1.5128347, 0.66101074],
            e_bands: &EBAND_5MS,
            max_lm,
            nb_short_mdcts,
            short_mdct_size,
            nb_alloc_vectors: 11,
            alloc_vectors: &BAND_ALLOCATION,
            alloc_stride: 21,
            log_n: &LOG_N_400,
            window: &WINDOW_120,
            mdct,
            cache: PulseCache {
                size: 392,
                index: &CACHE_INDEX50,
                bits: &CACHE_BITS50,
                caps: &CACHE_CAPS50,
            },
            e_means: &E_MEANS,
        }
    }
}

pub const E_MEANS: [f32; 25] = [
    6.437500, 6.250000, 5.750000, 5.312500, 5.062500, 4.812500, 4.500000, 4.375000, 4.875000,
    4.687500, 4.562500, 4.437500, 4.875000, 4.625000, 4.312500, 4.500000, 4.375000, 4.625000,
    4.750000, 4.437500, 3.750000, 3.750000, 3.750000, 3.750000, 3.750000,
];

pub fn default_mode() -> &'static CeltMode {
    &MODE_48000_960_120
}

/*
const DEFAULT_FS: i32 = 48000;
const DEFAULT_OVERLAP: usize = 120;
const DEFAULT_NB_EBANDS: usize = 21;
const DEFAULT_EFF_EBANDS: usize = 21;
const DEFAULT_MAX_LM: usize = 3;
const DEFAULT_NB_SHORT_MDCTS: usize = 8;
const DEFAULT_SHORT_MDCT_SIZE: usize = 120;
const DEFAULT_MDCT_N: usize = 2 * DEFAULT_SHORT_MDCT_SIZE * DEFAULT_NB_SHORT_MDCTS;
*/

static MODE_48000_960_120: Lazy<CeltMode> = Lazy::new(|| CeltMode::new_48000_960_120());

// const PREEMPH_48000: [f32; 4] = [0.85000610, 0.0, 1.0, 1.0];

const LOG_N_400: [i16; 21] = [
    0, 0, 0, 0, 0, 0, 0, 0, 8, 8, 8, 8, 16, 16, 16, 21, 21, 24, 29, 34, 36,
];

const WINDOW_120: [f32; 120] = [
    6.7286966e-05,
    0.00060551348,
    0.001681597,
    0.0032947962,
    0.0054439943,
    0.0081276923,
    0.011344001,
    0.015090633,
    0.019364886,
    0.024163635,
    0.029483315,
    0.035319905,
    0.041668911,
    0.048525347,
    0.055883718,
    0.063737999,
    0.072081616,
    0.080907428,
    0.090207705,
    0.099974111,
    0.11019769,
    0.12086883,
    0.13197729,
    0.14351214,
    0.15546177,
    0.16781389,
    0.1805555,
    0.1936729,
    0.20715171,
    0.22097682,
    0.23513243,
    0.24960208,
    0.2643686,
    0.27941419,
    0.2947204,
    0.31026818,
    0.32603788,
    0.34200931,
    0.35816177,
    0.37447407,
    0.39092462,
    0.40749142,
    0.42415215,
    0.44088423,
    0.45766484,
    0.47447104,
    0.49127978,
    0.50806798,
    0.52481261,
    0.54149077,
    0.55807973,
    0.57455701,
    0.59090049,
    0.60708841,
    0.62309951,
    0.63891306,
    0.65450896,
    0.66986776,
    0.68497077,
    0.6998001,
    0.71433873,
    0.72857055,
    0.74248043,
    0.75605425,
    0.76927895,
    0.78214257,
    0.7946343,
    0.80674445,
    0.81846456,
    0.82978733,
    0.84070669,
    0.85121779,
    0.86131698,
    0.87100183,
    0.88027111,
    0.88912479,
    0.89756398,
    0.90559094,
    0.91320904,
    0.9204227,
    0.92723738,
    0.93365955,
    0.93969656,
    0.94535671,
    0.95064907,
    0.95558353,
    0.96017067,
    0.96442171,
    0.96834849,
    0.97196334,
    0.97527906,
    0.97830883,
    0.98106616,
    0.9835648,
    0.98581869,
    0.98784191,
    0.98964856,
    0.99125274,
    0.99266849,
    0.99390969,
    0.99499004,
    0.99592297,
    0.99672162,
    0.99739874,
    0.99796667,
    0.99843728,
    0.99882195,
    0.99913147,
    0.99937606,
    0.99956527,
    0.99970802,
    0.99981248,
    0.99988613,
    0.99993565,
    0.99996697,
    0.99998518,
    0.99999457,
    0.99999859,
    0.99999982,
    1.0,
];

pub const SPREAD_ICDF: [u8; 4] = [25, 23, 2, 0];
pub const TRIM_ICDF: [u8; 11] = [126, 124, 119, 109, 87, 41, 19, 9, 4, 2, 0];
pub const TAPSET_ICDF: [u8; 2] = [2, 0];

pub const TF_SELECT_TABLE: [[i8; 8]; 4] = [
    [0, -1, 0, -1, 0, -1, 0, -1], /* 2.5 ms */
    [0, -1, 0, -2, 1, 0, 1, -1],  /* 5 ms */
    [0, -2, 0, -3, 2, 0, 1, -1],  /* 10 ms */
    [0, -2, 0, -3, 3, 0, 1, -1],  /* 20 ms */
];