Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include <assert.h>
7 : #include "options.h"
8 : //#include "prot_fx.h"
9 : #include "cnst.h"
10 : #include "rom_com_fx.h"
11 : #include "rom_com.h"
12 : #include "rom_enc.h"
13 : #include "basop_util.h"
14 : #include "prot_fx.h" /* Function prototypes */
15 : #include "prot_fx_enc.h" /* Function prototypes */
16 :
17 :
18 : /*-------------------------------------------------------------------*
19 : * Local constants
20 : *-------------------------------------------------------------------*/
21 :
22 : #define MAXINT32 2147483647
23 : #ifndef swap
24 : #define swap( x, y, type ) \
25 : { \
26 : type u__p; \
27 : u__p = x; \
28 : x = y; \
29 : y = u__p; \
30 : }
31 : #endif
32 :
33 : #define depack_4_values( cbp, val0, val1, val2, val3 ) \
34 : val0 = shr( ( cbp )[0], 4 ); \
35 : val1 = shr( ( cbp )[1], 4 ); \
36 : val2 = shr( ( cbp )[2], 4 ); \
37 : val3 = add( add( shr( lshl( ( cbp )[2], 12 ), 4 ), lshr( lshl( ( cbp )[1], 12 ), 8 ) ), s_and( ( cbp )[0], 0xF ) );
38 : /*--------------------------------------------------------------------------*
39 : * depack_mul_values_fx()
40 : *
41 : *--------------------------------------------------------------------------*/
42 1189660 : static Word32 depack_mul_values_fx( Word16 *Tmp, const Word16 *w, const Word16 *cbp, const Word16 N )
43 : {
44 : Word16 i, val0, val1, val2, val3;
45 : Word32 en;
46 :
47 1189660 : en = 0;
48 1189660 : move32();
49 4898600 : FOR( i = 0; i < N; i += 4 )
50 : {
51 3708940 : depack_4_values( cbp + i_mult( shr( i, 2 ), 3 ), val0, val1, val2, val3 )
52 3708940 : Tmp[i + 0] = mult_r( shl_sat( w[i + 0], 2 ), val0 );
53 3708940 : move16();
54 3708940 : en = L_mac_sat( en, val0, Tmp[i + 0] );
55 3708940 : Tmp[i + 1] = mult_r( shl_sat( w[i + 1], 2 ), val1 );
56 3708940 : move16();
57 3708940 : en = L_mac_sat( en, val1, Tmp[i + 1] );
58 3708940 : Tmp[i + 2] = mult_r( shl_sat( w[i + 2], 2 ), val2 );
59 3708940 : move16();
60 3708940 : en = L_mac_sat( en, val2, Tmp[i + 2] );
61 3708940 : Tmp[i + 3] = mult_r( shl_sat( w[i + 3], 2 ), val3 );
62 3708940 : move16();
63 3708940 : en = L_mac_sat( en, val3, Tmp[i + 3] );
64 : }
65 :
66 1189660 : return en;
67 : }
68 : /*--------------------------------------------------------------------------*
69 : * depack_sub_values()
70 : *
71 : *--------------------------------------------------------------------------*/
72 559840 : static void depack_sub_values_fx( Word16 *pTmp, const Word16 *p1, const Word16 *cbp, const Word16 N )
73 : {
74 : Word16 j, val0, val1, val2, val3;
75 :
76 1959440 : FOR( j = 0; j < N; j += 4 )
77 : {
78 1399600 : depack_4_values( cbp + i_mult( 3, shr( j, 2 ) ), val0, val1, val2, val3 )
79 :
80 : /*pTmp[i] = (p1[i] - cbp[i]);*/
81 1399600 : pTmp[j + 0] = sub( p1[j + 0], val0 );
82 1399600 : move16(); /*3Q12*1.28*/
83 1399600 : pTmp[j + 1] = sub( p1[j + 1], val1 );
84 1399600 : move16(); /*3Q12*1.28*/
85 1399600 : pTmp[j + 2] = sub( p1[j + 2], val2 );
86 1399600 : move16(); /*3Q12*1.28*/
87 1399600 : pTmp[j + 3] = sub( p1[j + 3], val3 );
88 1399600 : move16(); /*3Q12*1.28*/
89 : }
90 559840 : }
91 : /*--------------------------------------------------------------------------*
92 : * msvq_enc_find_p_max_8()
93 : *
94 : * Unroll of inner search loop for maxC == 8
95 : *--------------------------------------------------------------------------*/
96 1487414 : static Word16 msvq_enc_find_p_max_8_fx( Word32 dist[] )
97 : {
98 : Word16 p_max;
99 :
100 1487414 : p_max = 0;
101 1487414 : move16();
102 :
103 : BASOP_SATURATE_WARNING_OFF_EVS
104 1487414 : if ( GT_32( dist[1], dist[p_max] ) )
105 : {
106 700618 : p_max = 1;
107 700618 : move16();
108 : }
109 1487414 : if ( GT_32( dist[2], dist[p_max] ) )
110 : {
111 499659 : p_max = 2;
112 499659 : move16();
113 : }
114 1487414 : if ( GT_32( dist[3], dist[p_max] ) )
115 : {
116 394847 : p_max = 3;
117 394847 : move16();
118 : }
119 1487414 : if ( GT_32( dist[4], dist[p_max] ) )
120 : {
121 302139 : p_max = 4;
122 302139 : move16();
123 : }
124 1487414 : if ( GT_32( dist[5], dist[p_max] ) )
125 : {
126 238805 : p_max = 5;
127 238805 : move16();
128 : }
129 1487414 : if ( GT_32( dist[6], dist[p_max] ) )
130 : {
131 219163 : p_max = 6;
132 219163 : move16();
133 : }
134 1487414 : if ( GT_32( dist[7], dist[p_max] ) )
135 : {
136 186281 : p_max = 7;
137 186281 : move16();
138 : }
139 : BASOP_SATURATE_WARNING_ON_EVS
140 1487414 : return p_max;
141 : }
142 : /*--------------------------------------------------------------------------*
143 : * msvq_enc_find_p_max_6()
144 : *
145 : * Unroll of inner search loop for maxC == 6
146 : *--------------------------------------------------------------------------*/
147 0 : static Word16 msvq_enc_find_p_max_6_fx( Word32 dist[] )
148 : {
149 : Word16 p_max;
150 :
151 0 : p_max = 0;
152 0 : move16();
153 :
154 : BASOP_SATURATE_WARNING_OFF_EVS
155 0 : if ( GT_32( dist[1], dist[p_max] ) )
156 : {
157 0 : p_max = 1;
158 0 : move16();
159 : }
160 0 : if ( GT_32( dist[2], dist[p_max] ) )
161 : {
162 0 : p_max = 2;
163 0 : move16();
164 : }
165 0 : if ( GT_32( dist[3], dist[p_max] ) )
166 : {
167 0 : p_max = 3;
168 0 : move16();
169 : }
170 0 : if ( GT_32( dist[4], dist[p_max] ) )
171 : {
172 0 : p_max = 4;
173 0 : move16();
174 : }
175 0 : if ( GT_32( dist[5], dist[p_max] ) )
176 : {
177 0 : p_max = 5;
178 0 : move16();
179 : }
180 : BASOP_SATURATE_WARNING_ON_EVS
181 0 : return p_max;
182 : }
183 : /*--------------------------------------------------------------------------*
184 : * msvq_enc_fx()
185 : *
186 : * MSVQ encoder
187 : *--------------------------------------------------------------------------*/
188 34990 : void msvq_enc_fx(
189 : const Word16 *const *cb, /* i : Codebook (indexed cb[*stages][levels][p]) (0Q15) */
190 : const Word16 dims[], /* i : Dimension of each codebook stage (NULL: full dim.) */
191 : const Word16 offs[], /* i : Starting dimension of each codebook stage (NULL: 0) */
192 : const Word16 u[], /* i : Vector to be encoded (prediction and mean removed)(3Q12) */
193 : const Word16 *levels, /* i : Number of levels in each stage */
194 : const Word16 maxC, /* i : Tree search size (number of candidates kept from */
195 : /* one stage to the next == M-best) */
196 : const Word16 stages, /* i : Number of stages */
197 : const Word16 w[], /* i : Weights Q8*/
198 : const Word16 N, /* i : Vector dimension */
199 : const Word16 maxN, /* i : Codebook dimension */
200 : Word16 Idx[] /* o : Indices */
201 : )
202 : {
203 : Word16 j;
204 : const Word16 *cbp;
205 : Word16 p2i;
206 : Word16 resid_buf[2 * LSFMBEST_MAX * M_MAX], *resid[2];
207 : Word16 *pTmp, *p1;
208 : Word16 *indices[2], m, s, c, c2, p_max, i, Tmp[M_MAX];
209 : Word16 idx_buf[2 * LSFMBEST_MAX * MAX_VQ_STAGES_USED], parents[LSFMBEST_MAX];
210 : Word32 dist_buf[2 * LSFMBEST_MAX], *dist[2], t1, tmp, en, ss2;
211 : Word16 ( *func_ptr )( Word32 * );
212 : Word16 N34;
213 : Word16 n, maxn, start;
214 :
215 : /*----------------------------------------------------------------*
216 : * Allocate memory for previous (parent) and current nodes.
217 : * Parent node is indexed [0], current node is indexed [1].
218 : *----------------------------------------------------------------*/
219 34990 : indices[0] = idx_buf;
220 34990 : indices[1] = idx_buf + maxC * stages; /*move16();*/
221 : /*vr_iset(0, idx_buf, 2*stages*maxC);*/
222 34990 : set16_fx( idx_buf, 0, (Word16) ( 2 * stages * maxC ) );
223 :
224 34990 : resid[0] = resid_buf;
225 34990 : resid[1] = resid_buf + maxC * N; /*move16();*/
226 :
227 34990 : dist[0] = dist_buf;
228 34990 : dist[1] = dist_buf + maxC; /*move16();*/
229 :
230 : /*vr_iset(0, parents, maxC);*/
231 34990 : set16_fx( parents, 0, maxC );
232 :
233 :
234 34990 : func_ptr = msvq_enc_find_p_max_6_fx;
235 34990 : move16();
236 34990 : if ( EQ_16( maxC, 8 ) )
237 : {
238 34990 : func_ptr = msvq_enc_find_p_max_8_fx;
239 34990 : move16();
240 : }
241 :
242 : /*----------------------------------------------------------------*
243 : * LSF weights are normalized, so it is always better to multiply it first
244 : * Set up inital distance vector
245 : *----------------------------------------------------------------*/
246 : /* Q0/16 * Qw_norm/16 << 1 >> 16 => Qwnorm-15/16 * Q0/16 << 1 => Qwnorm-14/32 * 6.5536 */
247 34990 : ss2 = L_mult( mult( u[0], shl( w[0], 2 ) ), u[0] );
248 34990 : move16();
249 559840 : FOR( j = 1; j < N; j++ )
250 : {
251 524850 : ss2 = L_mac_sat( ss2, mult( u[j], shl_sat( w[j], 2 ) ), u[j] );
252 : }
253 :
254 : /* Set up inital error (residual) vectors */
255 34990 : pTmp = resid[1]; /*move16();*/
256 314910 : FOR( c = 0; c < maxC; c++ )
257 : {
258 279920 : Copy( u, pTmp + c * N, N );
259 279920 : dist[1][c] = ss2;
260 279920 : move32();
261 : }
262 :
263 : /* Loop over all stages */
264 34990 : m = 1;
265 34990 : move16();
266 104970 : FOR( s = 0; s < stages; s++ )
267 : {
268 : /* codebook pointer is set to point to first stage */
269 69980 : cbp = cb[s]; /*3Q12*1.28*/
270 69980 : move16();
271 :
272 : /* Set up pointers to parent and current nodes */
273 69980 : swap( indices[0], indices[1], Word16 * );
274 69980 : move16();
275 69980 : move16();
276 69980 : move16();
277 69980 : swap( resid[0], resid[1], Word16 * );
278 69980 : move16();
279 69980 : move16();
280 69980 : move16();
281 69980 : swap( dist[0], dist[1], Word32 * );
282 69980 : move32();
283 69980 : move32();
284 69980 : move32();
285 :
286 : /* p_max points to maximum distortion node (worst of best) */
287 69980 : p_max = 0;
288 69980 : move16();
289 :
290 69980 : n = N;
291 69980 : move16();
292 69980 : maxn = maxN;
293 69980 : move16();
294 69980 : if ( dims )
295 : {
296 69980 : n = dims[s];
297 69980 : move16();
298 : }
299 69980 : if ( dims )
300 : {
301 69980 : maxn = n;
302 69980 : move16();
303 : }
304 :
305 69980 : assert( ( maxn % 4 ) == 0 );
306 69980 : N34 = mult( maxn, 24576 /*0.75f Q15*/ );
307 :
308 69980 : start = 0;
309 69980 : move16();
310 69980 : if ( offs )
311 : {
312 69980 : start = offs[s];
313 69980 : move16();
314 : }
315 :
316 69980 : set16_fx( Tmp, 0, start );
317 69980 : set16_fx( Tmp + start + n, 0, sub( N, add( start, n ) ) );
318 :
319 : /* Set distortions to a large value */
320 629820 : FOR( j = 0; j < maxC; j++ )
321 : {
322 559840 : dist[1][j] = MAXINT32;
323 559840 : move32();
324 : }
325 :
326 1259640 : FOR( j = 0; j < levels[s]; j++ )
327 : {
328 : /* Compute weighted codebook element and its energy */
329 1189660 : en = depack_mul_values_fx( Tmp + start, w + start, cbp, n );
330 :
331 1189660 : cbp += N34; /* pointer is incremented */
332 :
333 : /* Iterate over all parent nodes */
334 6298200 : FOR( c = 0; c < m; c++ )
335 : {
336 5108540 : pTmp = &resid[0][c * N];
337 : /*tmp = (*pTmp++) * Tmp[0];*/
338 5108540 : t1 = L_mult( pTmp[0], Tmp[0] );
339 :
340 81736640 : FOR( i = 1; i < N; i++ )
341 : {
342 76628100 : t1 = L_mac( t1, pTmp[i], Tmp[i] );
343 : }
344 :
345 : BASOP_SATURATE_WARNING_OFF_EVS
346 : /*NOTE: as long as a shorter distance is found, saturation can be accepted.*/
347 5108540 : tmp = L_add_sat( dist[0][c], L_sub_sat( en, L_shl( t1, 1 ) ) );
348 5108540 : t1 = L_sub_sat( tmp, dist[1][p_max] );
349 : BASOP_SATURATE_WARNING_ON_EVS
350 :
351 5108540 : IF( t1 <= 0 )
352 : {
353 : /* Replace worst */
354 1487414 : dist[1][p_max] = tmp;
355 1487414 : move32();
356 1487414 : indices[1][p_max * stages + s] = j;
357 1487414 : move16();
358 1487414 : add( 0, 0 );
359 1487414 : mult( 0, 0 );
360 1487414 : parents[p_max] = c;
361 1487414 : move16();
362 :
363 1487414 : p_max = ( *func_ptr )( dist[1] );
364 :
365 : } /*IF (L_sub(tmp,dist[1][p_max]) < 0) */
366 : } /* FOR (c=0; c<m; c++) */
367 : } /* FOR (j=0; j<levels[s]; j++) */
368 :
369 : /*------------------------------------------------------------*
370 : * Compute error vectors for each node
371 : *------------------------------------------------------------*/
372 69980 : pTmp = resid[1];
373 629820 : FOR( c = 0; c < maxC; c++ )
374 : {
375 : /* Subtract codebook entry from residual vector of parent node and multiply with scale factor */
376 559840 : p1 = resid[0] + parents[c] * N;
377 559840 : p2i = indices[1][c * stages + s];
378 559840 : move16();
379 :
380 559840 : Copy( p1, pTmp, start );
381 559840 : depack_sub_values_fx( pTmp + start, p1 + start, &cb[s][p2i * N34], n );
382 559840 : Copy( p1 + start + n, pTmp + start + n, sub( N, add( start, n ) ) );
383 :
384 559840 : pTmp += N;
385 :
386 : /* Get indices that were used for parent node */
387 : /*mvs2s(indices[0]+parents[c]*stages, indices[1]+c*stages, s);*/
388 559840 : Copy( indices[0] + parents[c] * stages, indices[1] + c * stages, s );
389 : } /* for (c=0; c<maxC; c++) */
390 69980 : m = maxC;
391 69980 : move16();
392 : } /* for (m=1, s=0; s<stages; s++) */
393 :
394 : /* Find the optimum candidate */
395 34990 : c2 = findIndexOfMinWord32( dist[1], maxC );
396 : /*mvi2i (indices[1]+c2*stages, Idx, stages);*/
397 34990 : Copy( indices[1] + c2 * stages, Idx, stages );
398 :
399 :
400 34990 : return;
401 : }
402 :
403 : /*--------------------------------------------------------------------------*
404 : * midlsf_enc_fx()
405 : *
406 : *
407 : *--------------------------------------------------------------------------*/
408 :
409 734 : void midlsf_enc_fx(
410 : const Word16 qlsf0[], /* i: quantized lsf coefficients (3Q12) */
411 : const Word16 qlsf1[], /* i: quantized lsf coefficients (3Q12) */
412 : const Word16 lsf[], /* i: lsf coefficients (3Q12) */
413 : Word16 *idx, /* o: codebook index */
414 : const Word16 lpcorder, /* i: order of the lpc */
415 : const Word32 *Bin_Ener_128_fx, // Q_ener
416 : const Word16 Q_ener,
417 : const Word8 narrowBand,
418 : const Word32 sr_core,
419 : const Word16 coder_type )
420 : {
421 : Word32 err, err_min, L_tmp;
422 : Word16 k, k1, j, tmp, size, qlsf[M], wghts[M];
423 : const Word16 *ratio;
424 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
425 734 : Flag Overflow = 0;
426 : #endif
427 :
428 734 : IF( EQ_16( coder_type, UNVOICED ) )
429 : {
430 31 : ratio = tbl_mid_unv_wb_5b_fx;
431 : }
432 : ELSE
433 : {
434 703 : ratio = tbl_mid_gen_wb_5b_fx;
435 : }
436 734 : size = 32;
437 734 : move16();
438 :
439 : /* Weights */
440 734 : Unified_weighting_fx(
441 : Bin_Ener_128_fx, /* i : FFT Bin energy 128 bins in two sets Q_ener */
442 : Q_ener,
443 : lsf, /* i : LSF vector x2.56 */
444 : wghts, /* o : LP weighting filter (numerator) Q8 */
445 : narrowBand, /* i : flag for Narrowband */
446 734 : sub( coder_type, UNVOICED ) == 0, /* i : flag for Unvoiced frame */
447 : sr_core, /* i : sampling rate of core-coder */
448 : lpcorder /* i : LP order */
449 : );
450 734 : err_min = MAXINT32;
451 734 : move16();
452 734 : *idx = 0;
453 734 : move16();
454 734 : k1 = 0;
455 734 : move16();
456 24222 : FOR( k = 0; k < size; k++ )
457 : {
458 23488 : err = L_deposit_l( 0 );
459 :
460 399296 : FOR( j = 0; j < M; j++ )
461 : {
462 : /* qlsf[j] = (1.0f - ratio[k*M+j]) * qlsf0[j] + ratio[k*M+j] * qlsf1[j]; */
463 375808 : L_tmp = L_mult( sub( 0x2000, ratio[k1 + j] ), qlsf0[j] );
464 375808 : L_tmp = L_mac( L_tmp, ratio[k1 + j], qlsf1[j] );
465 375808 : qlsf[j] = round_fx( L_shl( L_tmp, 2 ) );
466 375808 : test();
467 375808 : test();
468 375808 : IF( j > 0 && LT_16( j, M ) && LT_16( qlsf[j], add( qlsf[j - 1], LSF_GAP_MID_FX ) ) )
469 : {
470 2333 : qlsf[j] = add( qlsf[j - 1], LSF_GAP_MID_FX );
471 : }
472 :
473 375808 : tmp = sub( lsf[j], qlsf[j] );
474 : /* err += wghts[j] * ftemp * ftemp; */
475 : /* tmp is usually very small, we can have some extra precision with very rare saturation */
476 375808 : tmp = shl_o( tmp, 4, &Overflow );
477 375808 : tmp = mult_ro( tmp, tmp, &Overflow );
478 375808 : err = L_mac( err, tmp, wghts[j] );
479 : }
480 23488 : err = L_shl_o( err, 2, &Overflow );
481 :
482 : /* err = L_shl(err,Wscale); */
483 23488 : err = Mult_32_16( err, LSF_1_OVER_256SQ );
484 : /* err = Mult_32_16(err,Wmult); */
485 :
486 23488 : IF( LT_32( err, err_min ) )
487 : {
488 2990 : err_min = L_add( err, 0 );
489 2990 : *idx = k;
490 2990 : move16();
491 : }
492 23488 : k1 += M;
493 23488 : move16();
494 : }
495 :
496 734 : return;
497 : }
498 :
499 : /*--------------------------------------------------------------------------*
500 : * Q_lsf_tcxlpc_fx()
501 : *
502 : * Returns: number of indices
503 : *--------------------------------------------------------------------------*/
504 0 : Word16 Q_lsf_tcxlpc_fx(
505 : /* const */ Word16 lsf[], /* i : original lsf 14Q1 * 1.28 */
506 : Word16 lsf_q[], /* o : quantized lsf (14Q1*1.28)*/
507 : Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */
508 : Word16 indices[], /* o : VQ indices */
509 : const Word16 lpcorder, /* i : LPC order */
510 : const Word16 narrowband, /* i : narrowband flag */
511 : const Word16 cdk, /* i : codebook selector */
512 : const Word16 mem_MA[], /* i : MA memory */
513 : const Word16 coder_type,
514 : const Word32 *Bin_Ener, // Q_ener
515 : const Word16 Q_ener )
516 : {
517 : Word16 weights[M + 1];
518 : Word16 pred[M16k];
519 : Word16 i;
520 : Word16 NumIndices;
521 : Word16 lsf_q_ind[M16k];
522 : const Word16 *means;
523 : Word16 lsf_rem[M];
524 : Word16 lsf_rem_q_ind[M];
525 :
526 0 : Unified_weighting_fx( Bin_Ener, Q_ener, lsf, weights, narrowband, (Word16) EQ_16( coder_type, UNVOICED ), 12800, M );
527 :
528 0 : move16();
529 0 : NumIndices = 0;
530 :
531 : /* Put disabled flag */
532 0 : indices[NumIndices] = 0;
533 0 : move16();
534 0 : NumIndices = add( NumIndices, 1 );
535 :
536 : /* Inter-frame prediction */
537 :
538 0 : means = lsf_means[narrowband]; /* 14Q1 * 1.28 */
539 :
540 0 : FOR( i = 0; i < lpcorder; ++i )
541 : {
542 0 : pred[i] = add( means[i], mult_r( MU_MA_FX, mem_MA[i] ) ); /* 14Q1 * 1.28 + ( 14Q1 * 1.28 * Q15 ) = 14Q1 * 1.28*/
543 : }
544 :
545 : /* Subtract prediction */
546 :
547 0 : FOR( i = 0; i < lpcorder; ++i )
548 : {
549 0 : lsf[i] = sub( lsf[i], pred[i] ); /* 14Q1 * 1.28 */
550 : }
551 :
552 :
553 0 : msvq_enc_fx(
554 0 : lsf_codebook[narrowband][cdk],
555 : lsf_dims,
556 : lsf_offs,
557 : lsf,
558 : lsf_numlevels,
559 : kMaxC,
560 : TCXLPC_NUMSTAGES,
561 : weights,
562 : lpcorder,
563 : lpcorder,
564 0 : indices + NumIndices );
565 0 : msvq_dec(
566 0 : lsf_codebook[narrowband][cdk],
567 : lsf_dims,
568 : lsf_offs,
569 : TCXLPC_NUMSTAGES,
570 : lpcorder,
571 : lpcorder,
572 0 : indices + NumIndices,
573 : #ifdef IVAS_MSVQ
574 : 0, NULL,
575 : #endif
576 : lsf_q );
577 0 : NumIndices = add( NumIndices, TCXLPC_NUMSTAGES );
578 :
579 0 : FOR( i = 0; i < lpcorder; ++i )
580 : {
581 0 : lsf_q_ind[i] = lsf_q[i]; /*(14Q1*1.28)*/
582 0 : move16();
583 : }
584 :
585 : /* Update flag */
586 0 : indices[0] = lsf_ind_is_active( lsf_q_ind, lsf_means[narrowband], narrowband, cdk );
587 0 : move16();
588 :
589 : /* Get residual vector */
590 0 : FOR( i = 0; i < lpcorder; ++i )
591 : {
592 0 : lsf_rem[i] = add( sub( pred[i], lsf_means[narrowband][i] ), sub( lsf[i], lsf_q_ind[i] ) );
593 : }
594 :
595 : /* Quantize using extra stage(s) */
596 0 : msvq_enc_fx(
597 0 : lsf_ind_codebook[narrowband][cdk],
598 : lsf_ind_dims,
599 : lsf_ind_offs,
600 : lsf_rem,
601 : lsf_ind_numlevels,
602 : kMaxC,
603 : TCXLPC_IND_NUMSTAGES,
604 : weights,
605 : lpcorder,
606 : lpcorder,
607 0 : indices + NumIndices );
608 : /* Only add contribution if flag is enabled */
609 0 : IF( indices[0] )
610 : {
611 : /* Decode */
612 0 : msvq_dec(
613 0 : lsf_ind_codebook[narrowband][cdk],
614 : lsf_ind_dims,
615 : lsf_ind_offs,
616 : TCXLPC_IND_NUMSTAGES,
617 : lpcorder,
618 : lpcorder,
619 0 : indices + NumIndices,
620 : #ifdef IVAS_MSVQ
621 : 0, NULL,
622 : #endif
623 : lsf_rem_q_ind );
624 0 : NumIndices = add( NumIndices, TCXLPC_IND_NUMSTAGES );
625 :
626 : /* Add to MA-removed vector */
627 0 : FOR( i = 0; i < lpcorder; ++i )
628 : {
629 0 : lsf_q_ind[i] = add( lsf_q_ind[i], lsf_rem_q_ind[i] );
630 : }
631 : }
632 :
633 : /* Add inter-frame prediction */
634 0 : FOR( i = 0; i < lpcorder; ++i )
635 : {
636 0 : lsf_q[i] = add( lsf_q[i], pred[i] );
637 0 : lsf[i] = add( lsf[i], pred[i] );
638 : }
639 :
640 0 : reorder_lsf_fx( lsf_q, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX );
641 :
642 0 : FOR( i = 0; i < lpcorder; ++i )
643 : {
644 0 : lsf_q_ind[i] = add( lsf_q_ind[i], lsf_means[narrowband][i] );
645 : }
646 0 : reorder_lsf_fx( lsf_q_ind, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX );
647 :
648 0 : IF( lsp_q_ind )
649 : {
650 0 : E_LPC_lsf_lsp_conversion /*lsf2lsp*/ ( lsf_q_ind, lsp_q_ind, lpcorder );
651 : }
652 :
653 0 : return NumIndices;
654 : }
655 :
656 17495 : Word16 Q_lsf_tcxlpc_ivas_fx(
657 : /* const */ Word16 lsf[], /* i : original lsf */
658 : Word16 lsf_q[], /* o : quantized lsf */
659 : Word16 lsp_q_ind[], /* o : quantized lsp (w/o MA prediction) */
660 : Word16 indices[], /* o : VQ indices */
661 : const Word16 lpcorder, /* i : LPC order */
662 : const Word16 narrowband, /* i : narrowband flag */
663 : const Word16 cdk, /* i : codebook selector */
664 : const Word16 mem_MA[], /* i : MA memory */
665 : const Word16 coder_type,
666 : const Word32 *Bin_Ener,
667 : const Word16 Q_ener )
668 : {
669 : Word16 weights[M + 1];
670 : Word16 pred[M16k];
671 : Word16 i;
672 : Word16 NumIndices;
673 : Word16 lsf_q_ind[M16k];
674 : const Word16 *means;
675 : Word16 lsf_rem[M];
676 : Word16 lsf_rem_q_ind[M];
677 :
678 17495 : Unified_weighting_fx( &Bin_Ener[L_FFT / 2], Q_ener, lsf, weights, narrowband, (Word16) EQ_16( coder_type, UNVOICED ), 12800, M );
679 :
680 17495 : move16();
681 17495 : NumIndices = 0;
682 :
683 : /* Put disabled flag */
684 17495 : indices[NumIndices] = 0;
685 17495 : move16();
686 17495 : NumIndices = add( NumIndices, 1 );
687 :
688 : /* Inter-frame prediction */
689 :
690 17495 : means = lsf_means[narrowband]; /* 14Q1 * 1.28 */
691 :
692 297415 : FOR( i = 0; i < lpcorder; ++i )
693 : {
694 279920 : pred[i] = add( means[i], mult_r( MU_MA_FX, mem_MA[i] ) ); /* 14Q1 * 1.28 + ( 14Q1 * 1.28 * Q15 ) = 14Q1 * 1.28*/
695 279920 : move16();
696 : }
697 :
698 : /* Subtract prediction */
699 :
700 297415 : FOR( i = 0; i < lpcorder; ++i )
701 : {
702 279920 : lsf[i] = sub( lsf[i], pred[i] ); /* 14Q1 * 1.28 */
703 279920 : move16();
704 : }
705 :
706 :
707 17495 : msvq_enc_fx(
708 17495 : lsf_codebook[narrowband][cdk],
709 : lsf_dims,
710 : lsf_offs,
711 : lsf,
712 : lsf_numlevels,
713 : kMaxC,
714 : TCXLPC_NUMSTAGES,
715 : weights,
716 : lpcorder,
717 : lpcorder,
718 17495 : indices + NumIndices );
719 17495 : msvq_dec(
720 17495 : lsf_codebook[narrowband][cdk],
721 : lsf_dims,
722 : lsf_offs,
723 : TCXLPC_NUMSTAGES,
724 : lpcorder,
725 : lpcorder,
726 17495 : indices + NumIndices,
727 : #ifdef IVAS_MSVQ
728 : 0, NULL,
729 : #endif
730 : lsf_q );
731 17495 : NumIndices = add( NumIndices, TCXLPC_NUMSTAGES );
732 :
733 297415 : FOR( i = 0; i < lpcorder; ++i )
734 : {
735 279920 : lsf_q_ind[i] = lsf_q[i];
736 279920 : move16();
737 : }
738 :
739 : /* Update flag */
740 17495 : indices[0] = lsf_ind_is_active( lsf_q_ind, lsf_means[narrowband], narrowband, cdk );
741 17495 : move16();
742 :
743 : /* Get residual vector */
744 297415 : FOR( i = 0; i < lpcorder; ++i )
745 : {
746 279920 : lsf_rem[i] = add( sub( pred[i], lsf_means[narrowband][i] ), sub( lsf[i], lsf_q_ind[i] ) );
747 279920 : move16();
748 : }
749 :
750 : /* Quantize using extra stage(s) */
751 17495 : msvq_enc_fx(
752 17495 : lsf_ind_codebook[narrowband][cdk],
753 : lsf_ind_dims,
754 : lsf_ind_offs,
755 : lsf_rem,
756 : lsf_ind_numlevels,
757 : kMaxC,
758 : TCXLPC_IND_NUMSTAGES,
759 : weights,
760 : lpcorder,
761 : lpcorder,
762 17495 : indices + NumIndices );
763 : /* Only add contribution if flag is enabled */
764 17495 : IF( indices[0] )
765 : {
766 : /* Decode */
767 4892 : msvq_dec(
768 4892 : lsf_ind_codebook[narrowband][cdk],
769 : lsf_ind_dims,
770 : lsf_ind_offs,
771 : TCXLPC_IND_NUMSTAGES,
772 : lpcorder,
773 : lpcorder,
774 4892 : indices + NumIndices,
775 : #ifdef IVAS_MSVQ
776 : 0, NULL,
777 : #endif
778 : lsf_rem_q_ind );
779 4892 : NumIndices = add( NumIndices, TCXLPC_IND_NUMSTAGES );
780 :
781 : /* Add to MA-removed vector */
782 83164 : FOR( i = 0; i < lpcorder; ++i )
783 : {
784 78272 : lsf_q_ind[i] = add( lsf_q_ind[i], lsf_rem_q_ind[i] );
785 78272 : move16();
786 : }
787 : }
788 :
789 : /* Add inter-frame prediction */
790 297415 : FOR( i = 0; i < lpcorder; ++i )
791 : {
792 279920 : lsf_q[i] = add( lsf_q[i], pred[i] );
793 279920 : lsf[i] = add( lsf[i], pred[i] );
794 279920 : move16();
795 279920 : move16();
796 : }
797 :
798 17495 : reorder_lsf_fx( lsf_q, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX );
799 :
800 297415 : FOR( i = 0; i < lpcorder; ++i )
801 : {
802 279920 : lsf_q_ind[i] = add( lsf_q_ind[i], lsf_means[narrowband][i] );
803 279920 : move16();
804 : }
805 17495 : reorder_lsf_fx( lsf_q_ind, TCXLPC_LSF_GAP, lpcorder, INT_FS_FX );
806 :
807 17495 : IF( lsp_q_ind )
808 : {
809 17495 : E_LPC_lsf_lsp_conversion /*lsf2lsp*/ ( lsf_q_ind, lsp_q_ind, lpcorder );
810 : }
811 :
812 17495 : return NumIndices;
813 : }
814 : /*--------------------------------------------------------------------------*
815 : * enc_lsf_tcxlpc_fx()
816 : *
817 : * Returns: number of bits written
818 : *--------------------------------------------------------------------------*/
819 0 : Word16 enc_lsf_tcxlpc_fx(
820 : Word16 **indices, /* i : Ptr to VQ indices */
821 : BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */
822 : )
823 : {
824 : Word16 i, NumBits;
825 :
826 : Word16 flag;
827 :
828 : /* Read flag */
829 0 : flag = ( *indices )[0];
830 0 : move16();
831 0 : ++*indices;
832 :
833 0 : NumBits = TCXLPC_NUMBITS;
834 0 : move16();
835 0 : FOR( i = 0; i < TCXLPC_NUMSTAGES; ++i )
836 : {
837 0 : push_next_indice( hBstr, **indices, lsf_numbits[i] );
838 0 : ++*indices;
839 : }
840 :
841 0 : IF( flag )
842 : {
843 0 : NumBits = add( NumBits, TCXLPC_IND_NUMBITS );
844 0 : FOR( i = 0; i < TCXLPC_IND_NUMSTAGES; ++i )
845 : {
846 0 : push_next_indice( hBstr, **indices, lsf_ind_numbits[i] );
847 0 : ++*indices;
848 : }
849 : }
850 0 : return NumBits;
851 : }
852 17495 : Word16 enc_lsf_tcxlpc_ivas_fx(
853 : const Word16 **indices, /* i : Ptr to VQ indices */
854 : BSTR_ENC_HANDLE hBstr /* i/o: encoder bitstream handle */
855 : )
856 : {
857 : Word16 i, NumBits;
858 :
859 : Word16 flag;
860 :
861 : /* Read flag */
862 17495 : flag = ( *indices )[0];
863 17495 : move16();
864 17495 : ++*indices;
865 :
866 17495 : NumBits = TCXLPC_NUMBITS;
867 17495 : move16();
868 69980 : FOR( i = 0; i < TCXLPC_NUMSTAGES; ++i )
869 : {
870 52485 : push_next_indice( hBstr, **indices, lsf_numbits[i] );
871 52485 : ++*indices;
872 : }
873 :
874 17495 : IF( flag )
875 : {
876 4892 : NumBits = add( NumBits, TCXLPC_IND_NUMBITS );
877 9784 : FOR( i = 0; i < TCXLPC_IND_NUMSTAGES; ++i )
878 : {
879 4892 : push_next_indice( hBstr, **indices, lsf_ind_numbits[i] );
880 4892 : ++*indices;
881 : }
882 : }
883 17495 : return NumBits;
884 : }
885 :
886 : /*--------------------------------------------------------------------------*
887 : * lsf_msvq_ma_encprm_fx()
888 : *
889 : *
890 : *--------------------------------------------------------------------------*/
891 :
892 1000 : Word16 lsf_msvq_ma_encprm_fx(
893 : BSTR_ENC_HANDLE hBstr,
894 : Word16 *param_lpc, // Q0
895 : Word16 core,
896 : Word16 acelp_mode,
897 : Word16 acelp_midLpc,
898 : Word16 *bits_param_lpc,
899 : Word16 no_indices )
900 : {
901 : Word16 i, nbits_lpc;
902 : Word16 bits_midlpc;
903 :
904 1000 : bits_midlpc = MIDLSF_NBITS;
905 1000 : move16();
906 1000 : nbits_lpc = 0;
907 1000 : move16();
908 :
909 4080 : FOR( i = 0; i < no_indices; i++ )
910 : {
911 :
912 3080 : push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] );
913 3080 : param_lpc++;
914 3080 : nbits_lpc = add( nbits_lpc, bits_param_lpc[i] );
915 : }
916 1000 : IF( NE_16( acelp_mode, VOICED ) )
917 : {
918 746 : test();
919 746 : IF( ( core == ACELP_CORE ) && acelp_midLpc )
920 : {
921 :
922 338 : push_next_indice( hBstr, *param_lpc, bits_midlpc );
923 338 : nbits_lpc = add( nbits_lpc, bits_midlpc );
924 : }
925 : }
926 :
927 1000 : return nbits_lpc;
928 : }
929 111410 : Word16 lsf_msvq_ma_encprm_ivas_fx(
930 : BSTR_ENC_HANDLE hBstr,
931 : const Word16 *param_lpc, // Q0
932 : const Word16 core,
933 : const Word16 acelp_mode,
934 : const Word16 acelp_midLpc,
935 : const Word16 *bits_param_lpc,
936 : const Word16 no_indices )
937 : {
938 : Word16 i, nbits_lpc;
939 : Word16 bits_midlpc;
940 :
941 111410 : bits_midlpc = MIDLSF_NBITS;
942 111410 : move16();
943 111410 : nbits_lpc = 0;
944 111410 : move16();
945 :
946 458238 : FOR( i = 0; i < no_indices; i++ )
947 : {
948 :
949 346828 : push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] );
950 346828 : param_lpc++;
951 346828 : nbits_lpc = add( nbits_lpc, bits_param_lpc[i] );
952 : }
953 111410 : IF( NE_16( acelp_mode, VOICED ) )
954 : {
955 87720 : test();
956 87720 : IF( ( core == ACELP_CORE ) && acelp_midLpc )
957 : {
958 :
959 0 : push_next_indice( hBstr, *param_lpc, bits_midlpc );
960 0 : nbits_lpc = add( nbits_lpc, bits_midlpc );
961 : }
962 : }
963 :
964 111410 : return nbits_lpc;
965 : }
966 :
967 : /*--------------------------------------------------------------------------*
968 : * lsf_bctcvq_encprm_fx()
969 : *
970 : *
971 : *--------------------------------------------------------------------------*/
972 266 : Word16 lsf_bctcvq_encprm_fx(
973 : BSTR_ENC_HANDLE hBstr,
974 : Word16 *param_lpc, // Q0
975 : Word16 *bits_param_lpc,
976 : Word16 no_indices )
977 : {
978 : Word16 i, nbits_lpc;
979 :
980 266 : nbits_lpc = 0;
981 :
982 2926 : FOR( i = 0; i < no_indices; i++ )
983 : {
984 2660 : push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] );
985 2660 : param_lpc++;
986 2660 : nbits_lpc = add( nbits_lpc, bits_param_lpc[i] );
987 : }
988 :
989 266 : return nbits_lpc;
990 : }
991 0 : Word16 lsf_bctcvq_encprm_ivas_fx(
992 : BSTR_ENC_HANDLE hBstr,
993 : const Word16 *param_lpc, // Q0
994 : const Word16 *bits_param_lpc,
995 : const Word16 no_indices )
996 : {
997 : Word16 i, nbits_lpc;
998 :
999 0 : nbits_lpc = 0;
1000 0 : move16();
1001 :
1002 0 : FOR( i = 0; i < no_indices; i++ )
1003 : {
1004 0 : push_next_indice( hBstr, *param_lpc, bits_param_lpc[i] );
1005 0 : param_lpc++;
1006 0 : nbits_lpc = add( nbits_lpc, bits_param_lpc[i] );
1007 : }
1008 :
1009 0 : return nbits_lpc;
1010 : }
|