1*9a19cd78SMatthias Ringwald /****************************************************************************** 2*9a19cd78SMatthias Ringwald * 3*9a19cd78SMatthias Ringwald * Copyright 2021 Google, Inc. 4*9a19cd78SMatthias Ringwald * 5*9a19cd78SMatthias Ringwald * Licensed under the Apache License, Version 2.0 (the "License"); 6*9a19cd78SMatthias Ringwald * you may not use this file except in compliance with the License. 7*9a19cd78SMatthias Ringwald * You may obtain a copy of the License at: 8*9a19cd78SMatthias Ringwald * 9*9a19cd78SMatthias Ringwald * http://www.apache.org/licenses/LICENSE-2.0 10*9a19cd78SMatthias Ringwald * 11*9a19cd78SMatthias Ringwald * Unless required by applicable law or agreed to in writing, software 12*9a19cd78SMatthias Ringwald * distributed under the License is distributed on an "AS IS" BASIS, 13*9a19cd78SMatthias Ringwald * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 14*9a19cd78SMatthias Ringwald * See the License for the specific language governing permissions and 15*9a19cd78SMatthias Ringwald * limitations under the License. 16*9a19cd78SMatthias Ringwald * 17*9a19cd78SMatthias Ringwald ******************************************************************************/ 18*9a19cd78SMatthias Ringwald 19*9a19cd78SMatthias Ringwald #include "tns.h" 20*9a19cd78SMatthias Ringwald #include "tables.h" 21*9a19cd78SMatthias Ringwald 22*9a19cd78SMatthias Ringwald 23*9a19cd78SMatthias Ringwald /* ---------------------------------------------------------------------------- 24*9a19cd78SMatthias Ringwald * Filter Coefficients 25*9a19cd78SMatthias Ringwald * -------------------------------------------------------------------------- */ 26*9a19cd78SMatthias Ringwald 27*9a19cd78SMatthias Ringwald /** 28*9a19cd78SMatthias Ringwald * Resolve LPC Weighting indication according bitrate 29*9a19cd78SMatthias Ringwald * dt, nbytes Duration and size of the frame 30*9a19cd78SMatthias Ringwald * return True when LPC Weighting enabled 31*9a19cd78SMatthias Ringwald */ 32*9a19cd78SMatthias Ringwald static bool resolve_lpc_weighting(enum lc3_dt dt, int nbytes) 33*9a19cd78SMatthias Ringwald { 34*9a19cd78SMatthias Ringwald return nbytes < (dt == LC3_DT_7M5 ? 360/8 : 480/8); 35*9a19cd78SMatthias Ringwald } 36*9a19cd78SMatthias Ringwald 37*9a19cd78SMatthias Ringwald /** 38*9a19cd78SMatthias Ringwald * Return dot product of 2 vectors 39*9a19cd78SMatthias Ringwald * a, b, n The 2 vectors of size `n` 40*9a19cd78SMatthias Ringwald * return sum( a[i] * b[i] ), i = [0..n-1] 41*9a19cd78SMatthias Ringwald */ 42*9a19cd78SMatthias Ringwald static inline float dot(const float *a, const float *b, int n) 43*9a19cd78SMatthias Ringwald { 44*9a19cd78SMatthias Ringwald float v = 0; 45*9a19cd78SMatthias Ringwald 46*9a19cd78SMatthias Ringwald while (n--) 47*9a19cd78SMatthias Ringwald v += *(a++) * *(b++); 48*9a19cd78SMatthias Ringwald 49*9a19cd78SMatthias Ringwald return v; 50*9a19cd78SMatthias Ringwald } 51*9a19cd78SMatthias Ringwald 52*9a19cd78SMatthias Ringwald /** 53*9a19cd78SMatthias Ringwald * LPC Coefficients 54*9a19cd78SMatthias Ringwald * dt, bw Duration and bandwidth of the frame 55*9a19cd78SMatthias Ringwald * x Spectral coefficients 56*9a19cd78SMatthias Ringwald * gain, a Output the prediction gains and LPC coefficients 57*9a19cd78SMatthias Ringwald */ 58*9a19cd78SMatthias Ringwald static void compute_lpc_coeffs(enum lc3_dt dt, enum lc3_bandwidth bw, 59*9a19cd78SMatthias Ringwald const float *x, float *gain, float (*a)[9]) 60*9a19cd78SMatthias Ringwald { 61*9a19cd78SMatthias Ringwald static const int sub_7m5_nb[] = { 9, 26, 43, 60 }; 62*9a19cd78SMatthias Ringwald static const int sub_7m5_wb[] = { 9, 46, 83, 120 }; 63*9a19cd78SMatthias Ringwald static const int sub_7m5_sswb[] = { 9, 66, 123, 180 }; 64*9a19cd78SMatthias Ringwald static const int sub_7m5_swb[] = { 9, 46, 82, 120, 159, 200, 240 }; 65*9a19cd78SMatthias Ringwald static const int sub_7m5_fb[] = { 9, 56, 103, 150, 200, 250, 300 }; 66*9a19cd78SMatthias Ringwald 67*9a19cd78SMatthias Ringwald static const int sub_10m_nb[] = { 12, 34, 57, 80 }; 68*9a19cd78SMatthias Ringwald static const int sub_10m_wb[] = { 12, 61, 110, 160 }; 69*9a19cd78SMatthias Ringwald static const int sub_10m_sswb[] = { 12, 88, 164, 240 }; 70*9a19cd78SMatthias Ringwald static const int sub_10m_swb[] = { 12, 61, 110, 160, 213, 266, 320 }; 71*9a19cd78SMatthias Ringwald static const int sub_10m_fb[] = { 12, 74, 137, 200, 266, 333, 400 }; 72*9a19cd78SMatthias Ringwald 73*9a19cd78SMatthias Ringwald /* --- Normalized autocorrelation --- */ 74*9a19cd78SMatthias Ringwald 75*9a19cd78SMatthias Ringwald static const float lag_window[] = { 76*9a19cd78SMatthias Ringwald 1.00000000e+00, 9.98028026e-01, 9.92135406e-01, 9.82391584e-01, 77*9a19cd78SMatthias Ringwald 9.68910791e-01, 9.51849807e-01, 9.31404933e-01, 9.07808230e-01, 78*9a19cd78SMatthias Ringwald 8.81323137e-01 79*9a19cd78SMatthias Ringwald }; 80*9a19cd78SMatthias Ringwald 81*9a19cd78SMatthias Ringwald const int *sub = (const int * const [LC3_NUM_DT][LC3_NUM_SRATE]){ 82*9a19cd78SMatthias Ringwald { sub_7m5_nb, sub_7m5_wb, sub_7m5_sswb, sub_7m5_swb, sub_7m5_fb }, 83*9a19cd78SMatthias Ringwald { sub_10m_nb, sub_10m_wb, sub_10m_sswb, sub_10m_swb, sub_10m_fb }, 84*9a19cd78SMatthias Ringwald }[dt][bw]; 85*9a19cd78SMatthias Ringwald 86*9a19cd78SMatthias Ringwald int nfilters = 1 + (bw >= LC3_BANDWIDTH_SWB); 87*9a19cd78SMatthias Ringwald 88*9a19cd78SMatthias Ringwald const float *xs, *xe = x + *sub; 89*9a19cd78SMatthias Ringwald float r[2][9]; 90*9a19cd78SMatthias Ringwald 91*9a19cd78SMatthias Ringwald for (int f = 0; f < nfilters; f++) { 92*9a19cd78SMatthias Ringwald float c[9][3]; 93*9a19cd78SMatthias Ringwald 94*9a19cd78SMatthias Ringwald for (int s = 0; s < 3; s++) { 95*9a19cd78SMatthias Ringwald xs = xe, xe = x + *(++sub); 96*9a19cd78SMatthias Ringwald 97*9a19cd78SMatthias Ringwald for (int k = 0; k < 9; k++) 98*9a19cd78SMatthias Ringwald c[k][s] = dot(xs, xs + k, (xe - xs) - k); 99*9a19cd78SMatthias Ringwald } 100*9a19cd78SMatthias Ringwald 101*9a19cd78SMatthias Ringwald float e0 = c[0][0], e1 = c[0][1], e2 = c[0][2]; 102*9a19cd78SMatthias Ringwald 103*9a19cd78SMatthias Ringwald r[f][0] = 3; 104*9a19cd78SMatthias Ringwald for (int k = 1; k < 9; k++) 105*9a19cd78SMatthias Ringwald r[f][k] = e0 == 0 || e1 == 0 || e2 == 0 ? 0 : 106*9a19cd78SMatthias Ringwald (c[k][0]/e0 + c[k][1]/e1 + c[k][2]/e2) * lag_window[k]; 107*9a19cd78SMatthias Ringwald } 108*9a19cd78SMatthias Ringwald 109*9a19cd78SMatthias Ringwald /* --- Levinson-Durbin recursion --- */ 110*9a19cd78SMatthias Ringwald 111*9a19cd78SMatthias Ringwald for (int f = 0; f < nfilters; f++) { 112*9a19cd78SMatthias Ringwald float *a0 = a[f], a1[9]; 113*9a19cd78SMatthias Ringwald float err = r[f][0], rc; 114*9a19cd78SMatthias Ringwald 115*9a19cd78SMatthias Ringwald gain[f] = err; 116*9a19cd78SMatthias Ringwald 117*9a19cd78SMatthias Ringwald a0[0] = 1; 118*9a19cd78SMatthias Ringwald for (int k = 1; k < 9; ) { 119*9a19cd78SMatthias Ringwald 120*9a19cd78SMatthias Ringwald rc = -r[f][k]; 121*9a19cd78SMatthias Ringwald for (int i = 1; i < k; i++) 122*9a19cd78SMatthias Ringwald rc -= a0[i] * r[f][k-i]; 123*9a19cd78SMatthias Ringwald 124*9a19cd78SMatthias Ringwald rc /= err; 125*9a19cd78SMatthias Ringwald err *= 1 - rc * rc; 126*9a19cd78SMatthias Ringwald 127*9a19cd78SMatthias Ringwald for (int i = 1; i < k; i++) 128*9a19cd78SMatthias Ringwald a1[i] = a0[i] + rc * a0[k-i]; 129*9a19cd78SMatthias Ringwald a1[k++] = rc; 130*9a19cd78SMatthias Ringwald 131*9a19cd78SMatthias Ringwald rc = -r[f][k]; 132*9a19cd78SMatthias Ringwald for (int i = 1; i < k; i++) 133*9a19cd78SMatthias Ringwald rc -= a1[i] * r[f][k-i]; 134*9a19cd78SMatthias Ringwald 135*9a19cd78SMatthias Ringwald rc /= err; 136*9a19cd78SMatthias Ringwald err *= 1 - rc * rc; 137*9a19cd78SMatthias Ringwald 138*9a19cd78SMatthias Ringwald for (int i = 1; i < k; i++) 139*9a19cd78SMatthias Ringwald a0[i] = a1[i] + rc * a1[k-i]; 140*9a19cd78SMatthias Ringwald a0[k++] = rc; 141*9a19cd78SMatthias Ringwald } 142*9a19cd78SMatthias Ringwald 143*9a19cd78SMatthias Ringwald gain[f] /= err; 144*9a19cd78SMatthias Ringwald } 145*9a19cd78SMatthias Ringwald } 146*9a19cd78SMatthias Ringwald 147*9a19cd78SMatthias Ringwald /** 148*9a19cd78SMatthias Ringwald * LPC Weighting 149*9a19cd78SMatthias Ringwald * gain, a Prediction gain and LPC coefficients, weighted as output 150*9a19cd78SMatthias Ringwald */ 151*9a19cd78SMatthias Ringwald static void lpc_weighting(float pred_gain, float *a) 152*9a19cd78SMatthias Ringwald { 153*9a19cd78SMatthias Ringwald float gamma = 1. - (1. - 0.85) * (2. - pred_gain) / (2. - 1.5), g = 1; 154*9a19cd78SMatthias Ringwald for (int i = 1; i < 9; i++) 155*9a19cd78SMatthias Ringwald a[i] *= (g *= gamma); 156*9a19cd78SMatthias Ringwald } 157*9a19cd78SMatthias Ringwald 158*9a19cd78SMatthias Ringwald /** 159*9a19cd78SMatthias Ringwald * LPC reflection 160*9a19cd78SMatthias Ringwald * a LPC coefficients 161*9a19cd78SMatthias Ringwald * rc Output refelection coefficients 162*9a19cd78SMatthias Ringwald */ 163*9a19cd78SMatthias Ringwald static void lpc_reflection(const float *a, float *rc) 164*9a19cd78SMatthias Ringwald { 165*9a19cd78SMatthias Ringwald float e, b[2][7], *b0, *b1; 166*9a19cd78SMatthias Ringwald 167*9a19cd78SMatthias Ringwald rc[7] = a[1+7]; 168*9a19cd78SMatthias Ringwald e = 1 - rc[7] * rc[7]; 169*9a19cd78SMatthias Ringwald 170*9a19cd78SMatthias Ringwald b1 = b[1]; 171*9a19cd78SMatthias Ringwald for (int i = 0; i < 7; i++) 172*9a19cd78SMatthias Ringwald b1[i] = (a[1+i] - rc[7] * a[7-i]) / e; 173*9a19cd78SMatthias Ringwald 174*9a19cd78SMatthias Ringwald for (int k = 6; k > 0; k--) { 175*9a19cd78SMatthias Ringwald b0 = b1, b1 = b[k & 1]; 176*9a19cd78SMatthias Ringwald 177*9a19cd78SMatthias Ringwald rc[k] = b0[k]; 178*9a19cd78SMatthias Ringwald e = 1 - rc[k] * rc[k]; 179*9a19cd78SMatthias Ringwald 180*9a19cd78SMatthias Ringwald for (int i = 0; i < k; i++) 181*9a19cd78SMatthias Ringwald b1[i] = (b0[i] - rc[k] * b0[k-1-i]) / e; 182*9a19cd78SMatthias Ringwald } 183*9a19cd78SMatthias Ringwald 184*9a19cd78SMatthias Ringwald rc[0] = b1[0]; 185*9a19cd78SMatthias Ringwald } 186*9a19cd78SMatthias Ringwald 187*9a19cd78SMatthias Ringwald /** 188*9a19cd78SMatthias Ringwald * Quantization of RC coefficients 189*9a19cd78SMatthias Ringwald * rc Refelection coefficients 190*9a19cd78SMatthias Ringwald * rc_order Return order of coefficients 191*9a19cd78SMatthias Ringwald * rc_i Return quantized coefficients 192*9a19cd78SMatthias Ringwald */ 193*9a19cd78SMatthias Ringwald static void quantize_rc(const float *rc, int *rc_order, int *rc_q) 194*9a19cd78SMatthias Ringwald { 195*9a19cd78SMatthias Ringwald /* Quantization table, sin(delta * (i + 0.5)), delta = Pi / 17 */ 196*9a19cd78SMatthias Ringwald 197*9a19cd78SMatthias Ringwald static float q_thr[] = { 198*9a19cd78SMatthias Ringwald 9.22683595e-02, 2.73662990e-01, 4.45738356e-01, 6.02634636e-01, 199*9a19cd78SMatthias Ringwald 7.39008917e-01, 8.50217136e-01, 9.32472229e-01, 9.82973100e-01 200*9a19cd78SMatthias Ringwald }; 201*9a19cd78SMatthias Ringwald 202*9a19cd78SMatthias Ringwald *rc_order = 8; 203*9a19cd78SMatthias Ringwald 204*9a19cd78SMatthias Ringwald for (int i = 0; i < 8; i++) { 205*9a19cd78SMatthias Ringwald float rc_m = fabsf(rc[i]); 206*9a19cd78SMatthias Ringwald 207*9a19cd78SMatthias Ringwald rc_q[i] = 4 * (rc_m >= q_thr[4]); 208*9a19cd78SMatthias Ringwald for (int j = 0; j < 4 && rc_m >= q_thr[rc_q[i]]; j++, rc_q[i]++); 209*9a19cd78SMatthias Ringwald 210*9a19cd78SMatthias Ringwald if (rc[i] < 0) 211*9a19cd78SMatthias Ringwald rc_q[i] = -rc_q[i]; 212*9a19cd78SMatthias Ringwald 213*9a19cd78SMatthias Ringwald *rc_order = rc_q[i] != 0 ? 8 : *rc_order - 1; 214*9a19cd78SMatthias Ringwald } 215*9a19cd78SMatthias Ringwald } 216*9a19cd78SMatthias Ringwald 217*9a19cd78SMatthias Ringwald /** 218*9a19cd78SMatthias Ringwald * Unquantization of RC coefficients 219*9a19cd78SMatthias Ringwald * rc_q Quantized coefficients 220*9a19cd78SMatthias Ringwald * rc_order Order of coefficients 221*9a19cd78SMatthias Ringwald * rc Return refelection coefficients 222*9a19cd78SMatthias Ringwald */ 223*9a19cd78SMatthias Ringwald static void unquantize_rc(const int *rc_q, int rc_order, float rc[8]) 224*9a19cd78SMatthias Ringwald { 225*9a19cd78SMatthias Ringwald /* Quantization table, sin(delta * i), delta = Pi / 17 */ 226*9a19cd78SMatthias Ringwald 227*9a19cd78SMatthias Ringwald static float q_inv[] = { 228*9a19cd78SMatthias Ringwald 0.00000000e+00, 1.83749517e-01, 3.61241664e-01, 5.26432173e-01, 229*9a19cd78SMatthias Ringwald 6.73695641e-01, 7.98017215e-01, 8.95163302e-01, 9.61825645e-01, 230*9a19cd78SMatthias Ringwald 9.95734176e-01 231*9a19cd78SMatthias Ringwald }; 232*9a19cd78SMatthias Ringwald 233*9a19cd78SMatthias Ringwald int i; 234*9a19cd78SMatthias Ringwald 235*9a19cd78SMatthias Ringwald for (i = 0; i < rc_order; i++) { 236*9a19cd78SMatthias Ringwald float rc_m = q_inv[LC3_ABS(rc_q[i])]; 237*9a19cd78SMatthias Ringwald rc[i] = rc_q[i] < 0 ? -rc_m : rc_m; 238*9a19cd78SMatthias Ringwald } 239*9a19cd78SMatthias Ringwald } 240*9a19cd78SMatthias Ringwald 241*9a19cd78SMatthias Ringwald 242*9a19cd78SMatthias Ringwald /* ---------------------------------------------------------------------------- 243*9a19cd78SMatthias Ringwald * Filtering 244*9a19cd78SMatthias Ringwald * -------------------------------------------------------------------------- */ 245*9a19cd78SMatthias Ringwald 246*9a19cd78SMatthias Ringwald /** 247*9a19cd78SMatthias Ringwald * Forward filtering 248*9a19cd78SMatthias Ringwald * dt, bw Duration and bandwidth of the frame 249*9a19cd78SMatthias Ringwald * rc_order, rc Order of coefficients, and coefficients 250*9a19cd78SMatthias Ringwald * x Spectral coefficients, filtered as output 251*9a19cd78SMatthias Ringwald */ 252*9a19cd78SMatthias Ringwald static void forward_filtering( 253*9a19cd78SMatthias Ringwald enum lc3_dt dt, enum lc3_bandwidth bw, 254*9a19cd78SMatthias Ringwald const int rc_order[2], const float rc[2][8], float *x) 255*9a19cd78SMatthias Ringwald { 256*9a19cd78SMatthias Ringwald int nfilters = 1 + (bw >= LC3_BANDWIDTH_SWB); 257*9a19cd78SMatthias Ringwald int nf = LC3_NE(dt, bw) >> (nfilters - 1); 258*9a19cd78SMatthias Ringwald int i0, ie = 3*(3 + dt); 259*9a19cd78SMatthias Ringwald 260*9a19cd78SMatthias Ringwald float s[8] = { 0 }; 261*9a19cd78SMatthias Ringwald 262*9a19cd78SMatthias Ringwald for (int f = 0; f < nfilters; f++) { 263*9a19cd78SMatthias Ringwald 264*9a19cd78SMatthias Ringwald i0 = ie; 265*9a19cd78SMatthias Ringwald ie = nf * (1 + f); 266*9a19cd78SMatthias Ringwald 267*9a19cd78SMatthias Ringwald if (!rc_order[f]) 268*9a19cd78SMatthias Ringwald continue; 269*9a19cd78SMatthias Ringwald 270*9a19cd78SMatthias Ringwald for (int i = i0; i < ie; i++) { 271*9a19cd78SMatthias Ringwald float xi = x[i]; 272*9a19cd78SMatthias Ringwald float s0, s1 = xi; 273*9a19cd78SMatthias Ringwald 274*9a19cd78SMatthias Ringwald for (int k = 0; k < rc_order[f]; k++) { 275*9a19cd78SMatthias Ringwald s0 = s[k]; 276*9a19cd78SMatthias Ringwald s[k] = s1; 277*9a19cd78SMatthias Ringwald 278*9a19cd78SMatthias Ringwald s1 = rc[f][k] * xi + s0; 279*9a19cd78SMatthias Ringwald xi += rc[f][k] * s0; 280*9a19cd78SMatthias Ringwald } 281*9a19cd78SMatthias Ringwald 282*9a19cd78SMatthias Ringwald x[i] = xi; 283*9a19cd78SMatthias Ringwald } 284*9a19cd78SMatthias Ringwald } 285*9a19cd78SMatthias Ringwald } 286*9a19cd78SMatthias Ringwald 287*9a19cd78SMatthias Ringwald /** 288*9a19cd78SMatthias Ringwald * Inverse filtering 289*9a19cd78SMatthias Ringwald * dt, bw Duration and bandwidth of the frame 290*9a19cd78SMatthias Ringwald * rc_order, rc Order of coefficients, and unquantized coefficients 291*9a19cd78SMatthias Ringwald * x Spectral coefficients, filtered as output 292*9a19cd78SMatthias Ringwald */ 293*9a19cd78SMatthias Ringwald static void inverse_filtering( 294*9a19cd78SMatthias Ringwald enum lc3_dt dt, enum lc3_bandwidth bw, 295*9a19cd78SMatthias Ringwald const int rc_order[2], const float rc[2][8], float *x) 296*9a19cd78SMatthias Ringwald { 297*9a19cd78SMatthias Ringwald int nfilters = 1 + (bw >= LC3_BANDWIDTH_SWB); 298*9a19cd78SMatthias Ringwald int nf = LC3_NE(dt, bw) >> (nfilters - 1); 299*9a19cd78SMatthias Ringwald int i0, ie = 3*(3 + dt); 300*9a19cd78SMatthias Ringwald 301*9a19cd78SMatthias Ringwald float s[8] = { 0 }; 302*9a19cd78SMatthias Ringwald 303*9a19cd78SMatthias Ringwald for (int f = 0; f < nfilters; f++) { 304*9a19cd78SMatthias Ringwald 305*9a19cd78SMatthias Ringwald i0 = ie; 306*9a19cd78SMatthias Ringwald ie = nf * (1 + f); 307*9a19cd78SMatthias Ringwald 308*9a19cd78SMatthias Ringwald if (!rc_order[f]) 309*9a19cd78SMatthias Ringwald continue; 310*9a19cd78SMatthias Ringwald 311*9a19cd78SMatthias Ringwald for (int i = i0; i < ie; i++) { 312*9a19cd78SMatthias Ringwald float xi = x[i]; 313*9a19cd78SMatthias Ringwald 314*9a19cd78SMatthias Ringwald xi -= s[7] * rc[f][7]; 315*9a19cd78SMatthias Ringwald for (int k = 6; k >= 0; k--) { 316*9a19cd78SMatthias Ringwald xi -= s[k] * rc[f][k]; 317*9a19cd78SMatthias Ringwald s[k+1] = s[k] + rc[f][k] * xi; 318*9a19cd78SMatthias Ringwald } 319*9a19cd78SMatthias Ringwald s[0] = xi; 320*9a19cd78SMatthias Ringwald x[i] = xi; 321*9a19cd78SMatthias Ringwald } 322*9a19cd78SMatthias Ringwald 323*9a19cd78SMatthias Ringwald for (int k = 7; k >= rc_order[f]; k--) 324*9a19cd78SMatthias Ringwald s[k] = 0; 325*9a19cd78SMatthias Ringwald } 326*9a19cd78SMatthias Ringwald } 327*9a19cd78SMatthias Ringwald 328*9a19cd78SMatthias Ringwald 329*9a19cd78SMatthias Ringwald /* ---------------------------------------------------------------------------- 330*9a19cd78SMatthias Ringwald * Interface 331*9a19cd78SMatthias Ringwald * -------------------------------------------------------------------------- */ 332*9a19cd78SMatthias Ringwald 333*9a19cd78SMatthias Ringwald /** 334*9a19cd78SMatthias Ringwald * TNS analysis 335*9a19cd78SMatthias Ringwald */ 336*9a19cd78SMatthias Ringwald void lc3_tns_analyze(enum lc3_dt dt, enum lc3_bandwidth bw, 337*9a19cd78SMatthias Ringwald bool nn_flag, int nbytes, struct lc3_tns_data *data, float *x) 338*9a19cd78SMatthias Ringwald { 339*9a19cd78SMatthias Ringwald /* Processing steps : 340*9a19cd78SMatthias Ringwald * - Determine the LPC (Linear Predictive Coding) Coefficients 341*9a19cd78SMatthias Ringwald * - Check is the filtering is disabled 342*9a19cd78SMatthias Ringwald * - The coefficients are weighted on low bitrates and predicition gain 343*9a19cd78SMatthias Ringwald * - Convert to reflection coefficients and quantize 344*9a19cd78SMatthias Ringwald * - Finally filter the spectral coefficients */ 345*9a19cd78SMatthias Ringwald 346*9a19cd78SMatthias Ringwald float pred_gain[2], a[2][9]; 347*9a19cd78SMatthias Ringwald float rc[2][8]; 348*9a19cd78SMatthias Ringwald 349*9a19cd78SMatthias Ringwald data->nfilters = 1 + (bw >= LC3_BANDWIDTH_SWB); 350*9a19cd78SMatthias Ringwald data->lpc_weighting = resolve_lpc_weighting(dt, nbytes); 351*9a19cd78SMatthias Ringwald 352*9a19cd78SMatthias Ringwald compute_lpc_coeffs(dt, bw, x, pred_gain, a); 353*9a19cd78SMatthias Ringwald 354*9a19cd78SMatthias Ringwald for (int f = 0; f < data->nfilters; f++) { 355*9a19cd78SMatthias Ringwald 356*9a19cd78SMatthias Ringwald data->rc_order[f] = 0; 357*9a19cd78SMatthias Ringwald if (nn_flag || pred_gain[f] <= 1.5) 358*9a19cd78SMatthias Ringwald continue; 359*9a19cd78SMatthias Ringwald 360*9a19cd78SMatthias Ringwald if (data->lpc_weighting && pred_gain[f] < 2) 361*9a19cd78SMatthias Ringwald lpc_weighting(pred_gain[f], a[f]); 362*9a19cd78SMatthias Ringwald 363*9a19cd78SMatthias Ringwald lpc_reflection(a[f], rc[f]); 364*9a19cd78SMatthias Ringwald 365*9a19cd78SMatthias Ringwald quantize_rc(rc[f], &data->rc_order[f], data->rc[f]); 366*9a19cd78SMatthias Ringwald unquantize_rc(data->rc[f], data->rc_order[f], rc[f]); 367*9a19cd78SMatthias Ringwald } 368*9a19cd78SMatthias Ringwald 369*9a19cd78SMatthias Ringwald forward_filtering(dt, bw, data->rc_order, rc, x); 370*9a19cd78SMatthias Ringwald } 371*9a19cd78SMatthias Ringwald 372*9a19cd78SMatthias Ringwald /** 373*9a19cd78SMatthias Ringwald * TNS synthesis 374*9a19cd78SMatthias Ringwald */ 375*9a19cd78SMatthias Ringwald void lc3_tns_synthesize(enum lc3_dt dt, enum lc3_bandwidth bw, 376*9a19cd78SMatthias Ringwald const struct lc3_tns_data *data, float *x) 377*9a19cd78SMatthias Ringwald { 378*9a19cd78SMatthias Ringwald float rc[2][8] = { }; 379*9a19cd78SMatthias Ringwald 380*9a19cd78SMatthias Ringwald for (int f = 0; f < data->nfilters; f++) 381*9a19cd78SMatthias Ringwald if (data->rc_order[f]) 382*9a19cd78SMatthias Ringwald unquantize_rc(data->rc[f], data->rc_order[f], rc[f]); 383*9a19cd78SMatthias Ringwald 384*9a19cd78SMatthias Ringwald inverse_filtering(dt, bw, data->rc_order, rc, x); 385*9a19cd78SMatthias Ringwald } 386*9a19cd78SMatthias Ringwald 387*9a19cd78SMatthias Ringwald /** 388*9a19cd78SMatthias Ringwald * Bit consumption of bitstream data 389*9a19cd78SMatthias Ringwald */ 390*9a19cd78SMatthias Ringwald int lc3_tns_get_nbits(const struct lc3_tns_data *data) 391*9a19cd78SMatthias Ringwald { 392*9a19cd78SMatthias Ringwald int nbits = 0; 393*9a19cd78SMatthias Ringwald 394*9a19cd78SMatthias Ringwald for (int f = 0; f < data->nfilters; f++) { 395*9a19cd78SMatthias Ringwald 396*9a19cd78SMatthias Ringwald int nbits_2048 = 2048; 397*9a19cd78SMatthias Ringwald int rc_order = data->rc_order[f]; 398*9a19cd78SMatthias Ringwald 399*9a19cd78SMatthias Ringwald nbits_2048 += rc_order > 0 ? lc3_tns_order_bits 400*9a19cd78SMatthias Ringwald [data->lpc_weighting][rc_order-1] : 0; 401*9a19cd78SMatthias Ringwald 402*9a19cd78SMatthias Ringwald for (int i = 0; i < rc_order; i++) 403*9a19cd78SMatthias Ringwald nbits_2048 += lc3_tns_coeffs_bits[i][8 + data->rc[f][i]]; 404*9a19cd78SMatthias Ringwald 405*9a19cd78SMatthias Ringwald nbits += (nbits_2048 + (1 << 11) - 1) >> 11; 406*9a19cd78SMatthias Ringwald } 407*9a19cd78SMatthias Ringwald 408*9a19cd78SMatthias Ringwald return nbits; 409*9a19cd78SMatthias Ringwald } 410*9a19cd78SMatthias Ringwald 411*9a19cd78SMatthias Ringwald /** 412*9a19cd78SMatthias Ringwald * Put bitstream data 413*9a19cd78SMatthias Ringwald */ 414*9a19cd78SMatthias Ringwald void lc3_tns_put_data(lc3_bits_t *bits, const struct lc3_tns_data *data) 415*9a19cd78SMatthias Ringwald { 416*9a19cd78SMatthias Ringwald for (int f = 0; f < data->nfilters; f++) { 417*9a19cd78SMatthias Ringwald int rc_order = data->rc_order[f]; 418*9a19cd78SMatthias Ringwald 419*9a19cd78SMatthias Ringwald lc3_put_bits(bits, rc_order > 0, 1); 420*9a19cd78SMatthias Ringwald if (rc_order <= 0) 421*9a19cd78SMatthias Ringwald continue; 422*9a19cd78SMatthias Ringwald 423*9a19cd78SMatthias Ringwald lc3_put_symbol(bits, 424*9a19cd78SMatthias Ringwald lc3_tns_order_models + data->lpc_weighting, rc_order-1); 425*9a19cd78SMatthias Ringwald 426*9a19cd78SMatthias Ringwald for (int i = 0; i < rc_order; i++) 427*9a19cd78SMatthias Ringwald lc3_put_symbol(bits, 428*9a19cd78SMatthias Ringwald lc3_tns_coeffs_models + i, 8 + data->rc[f][i]); 429*9a19cd78SMatthias Ringwald } 430*9a19cd78SMatthias Ringwald } 431*9a19cd78SMatthias Ringwald 432*9a19cd78SMatthias Ringwald /** 433*9a19cd78SMatthias Ringwald * Get bitstream data 434*9a19cd78SMatthias Ringwald */ 435*9a19cd78SMatthias Ringwald void lc3_tns_get_data(lc3_bits_t *bits, 436*9a19cd78SMatthias Ringwald enum lc3_dt dt, enum lc3_bandwidth bw, int nbytes, lc3_tns_data_t *data) 437*9a19cd78SMatthias Ringwald { 438*9a19cd78SMatthias Ringwald data->nfilters = 1 + (bw >= LC3_BANDWIDTH_SWB); 439*9a19cd78SMatthias Ringwald data->lpc_weighting = resolve_lpc_weighting(dt, nbytes); 440*9a19cd78SMatthias Ringwald 441*9a19cd78SMatthias Ringwald for (int f = 0; f < data->nfilters; f++) { 442*9a19cd78SMatthias Ringwald 443*9a19cd78SMatthias Ringwald data->rc_order[f] = lc3_get_bit(bits); 444*9a19cd78SMatthias Ringwald if (!data->rc_order[f]) 445*9a19cd78SMatthias Ringwald continue; 446*9a19cd78SMatthias Ringwald 447*9a19cd78SMatthias Ringwald data->rc_order[f] += lc3_get_symbol(bits, 448*9a19cd78SMatthias Ringwald lc3_tns_order_models + data->lpc_weighting); 449*9a19cd78SMatthias Ringwald 450*9a19cd78SMatthias Ringwald for (int i = 0; i < data->rc_order[f]; i++) 451*9a19cd78SMatthias Ringwald data->rc[f][i] = (int)lc3_get_symbol(bits, 452*9a19cd78SMatthias Ringwald lc3_tns_coeffs_models + i) - 8; 453*9a19cd78SMatthias Ringwald } 454*9a19cd78SMatthias Ringwald } 455