xref: /btstack/3rd-party/lc3-google/src/tns.c (revision 9a19cd786042b1fc78813d984efdd045e84593df)
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