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