Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : #include <assert.h>
34 : #include <stdint.h>
35 : #include "options.h"
36 : #include <math.h>
37 : #include "cnst.h"
38 : #include "prot_fx.h"
39 : #include "ivas_prot_fx.h"
40 : #include "rom_com.h"
41 : #include "ivas_rom_com.h"
42 : #include "ivas_rom_com_fx.h"
43 : #include "ivas_cnst.h"
44 : #include "wmc_auto.h"
45 : #include "prot_fx_enc.h"
46 :
47 : /*-------------------------------------------------------------------
48 : * sns_1st_cod()
49 : *
50 : *
51 : *-------------------------------------------------------------------*/
52 :
53 : /* r : codebook index */
54 341159 : static Word16 sns_1st_cod_fx(
55 : const Word32 *sns_fx, /* i : vector to quantize */
56 : Word16 exp_sns,
57 : const Word16 L_frame,
58 : const Word16 core,
59 : Word32 *snsq_fx /* o : quantized sns Q16 */
60 : )
61 : {
62 341159 : IF( exp_sns == Q15 )
63 : {
64 : Word16 index;
65 157080 : const Word16 split_len = M / 2;
66 157080 : move16();
67 : const Word16 *means;
68 157080 : const Word16 means_fix = 2; // Q15
69 157080 : move16();
70 : /* remove means */
71 157080 : means = NULL;
72 157080 : SWITCH( L_frame )
73 : {
74 11865 : case L_FRAME16k:
75 11865 : means = &sns_1st_means_16k[core - 1][0]; // Q14
76 11865 : break;
77 46872 : case L_FRAME25_6k:
78 46872 : means = &sns_1st_means_25k6[core - 1][0]; // Q14
79 46872 : break;
80 98343 : case L_FRAME32k:
81 98343 : means = &sns_1st_means_32k[core - 1][0]; // Q14
82 98343 : break;
83 0 : default:
84 0 : assert( !"illegal frame length in sns_1st_cod" );
85 : }
86 2670360 : FOR( Word16 i = 0; i < M; ++i )
87 : {
88 2513280 : Word32 tmp = L_mult( means[i], means_fix ); // Q14->Q16
89 2513280 : snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16
90 2513280 : move32();
91 : }
92 :
93 157080 : index = 0;
94 157080 : move16();
95 471240 : FOR( Word16 split = 0; split < 2; ++split )
96 : {
97 : const Word16 *cdbk_ptr;
98 : Word16 j0, j1;
99 : Word16 index_split;
100 : Word32 dist_min_fx;
101 314160 : const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15
102 314160 : move16();
103 314160 : const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; // Q12
104 :
105 314160 : j0 = imult1616( split, split_len );
106 314160 : j1 = add( j0, split_len );
107 :
108 314160 : cdbk_ptr = cdbk;
109 314160 : dist_min_fx = MAXVAL_WORD32;
110 314160 : index_split = 0;
111 314160 : move32();
112 314160 : move16();
113 10367280 : FOR( Word16 i = 0; i < 32; ++i )
114 : {
115 10053120 : Word32 dist_fx = 0;
116 10053120 : move32();
117 90478080 : FOR( Word16 j = j0; j < j1; ++j ) // j1-j0=split_len. split_len=M/2. M=16
118 : {
119 : Word32 tmp;
120 : Word32 dist;
121 :
122 80424960 : tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12->Q16
123 80424960 : dist = L_sub( snsq_fx[j], tmp ); // Q16
124 80424960 : dist = L_shl( dist, 11 ); // cdbk_ptr is a 16 bit LUT with 3.12 values, used as 3.16. assumption: snsq_fx has the same representation. thus, the subtraction results are in 4.16, which leaves 11 bit headroom.
125 80424960 : dist = Mpy_32_32( dist, dist );
126 80424960 : dist = L_shr( dist, 3 ); // make sure that the sum of 8 values does not overflow
127 80424960 : dist_fx = L_add( dist_fx, dist );
128 : }
129 :
130 10053120 : IF( LT_32( dist_fx, dist_min_fx ) )
131 : {
132 1545905 : dist_min_fx = dist_fx;
133 1545905 : move32();
134 1545905 : index_split = i;
135 1545905 : move16();
136 : }
137 : }
138 :
139 : /* set quantized vector */
140 314160 : cdbk_ptr = &cdbk[imult1616( index_split, split_len )];
141 2827440 : FOR( Word16 j = j0; j < j1; ++j )
142 : {
143 2513280 : Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16
144 2513280 : Word32 tmp_4 = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16
145 2513280 : snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16
146 2513280 : move32();
147 : }
148 :
149 : /* for second split shift by five bits to store both indices as one 10 bit value */
150 314160 : if ( EQ_16( split, 1 ) )
151 : {
152 157080 : index_split = shl( index_split, 5 );
153 : }
154 :
155 314160 : index = add( index, index_split );
156 : }
157 157080 : return index;
158 : }
159 : ELSE
160 : {
161 : Word16 index, i;
162 184079 : const Word16 split_len = M / 2;
163 184079 : move16();
164 : const Word16 *means;
165 184079 : const Word16 means_fix = 2; // Q15
166 184079 : move16();
167 : /* remove means */
168 184079 : means = NULL;
169 184079 : SWITCH( L_frame )
170 : {
171 22038 : case L_FRAME16k:
172 22038 : means = &sns_1st_means_16k[core - 1][0];
173 22038 : break;
174 50865 : case L_FRAME25_6k:
175 50865 : means = &sns_1st_means_25k6[core - 1][0];
176 50865 : break;
177 111176 : case L_FRAME32k:
178 111176 : means = &sns_1st_means_32k[core - 1][0];
179 111176 : break;
180 0 : default:
181 0 : assert( !"illegal frame length in sns_1st_cod" );
182 : }
183 184079 : Word16 exp_snsq_buffer[M] = { 0 }, exp_snsq = 0;
184 184079 : move16();
185 184079 : move16();
186 3129343 : FOR( i = 0; i < M; ++i )
187 : {
188 2945264 : Word32 tmp = L_mult( means[i], means_fix ); // Q16
189 2945264 : exp_snsq_buffer[i] = 0;
190 2945264 : move16();
191 2945264 : snsq_fx[i] = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( tmp ), 15, &exp_snsq_buffer[i] );
192 2945264 : move32();
193 : }
194 3129343 : FOR( i = 0; i < M; i++ )
195 : {
196 2945264 : exp_snsq = s_max( exp_snsq_buffer[i], exp_snsq );
197 : }
198 3129343 : FOR( i = 0; i < M; i++ )
199 : {
200 2945264 : snsq_fx[i] = L_shr( snsq_fx[i], exp_snsq - exp_snsq_buffer[i] );
201 2945264 : move32();
202 : }
203 :
204 184079 : index = 0;
205 184079 : move16();
206 552237 : FOR( Word16 split = 0; split < 2; ++split )
207 : {
208 : const Word16 *cdbk_ptr;
209 : Word16 j0, j1, index_split;
210 : Word32 dist_min_fx;
211 368158 : const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15
212 368158 : move16();
213 368158 : const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0];
214 :
215 368158 : j0 = imult1616( split, split_len );
216 368158 : j1 = add( j0, split_len );
217 :
218 368158 : cdbk_ptr = cdbk;
219 368158 : dist_min_fx = MAXVAL_WORD32;
220 368158 : Word16 exp_dist_min = 31;
221 368158 : index_split = 0;
222 12149214 : FOR( i = 0; i < 32; ++i )
223 : {
224 11781056 : Word32 dist_fx = 0;
225 11781056 : move32();
226 11781056 : Word16 exp_dist = 0;
227 11781056 : move16();
228 106029504 : FOR( Word16 j = j0; j < j1; ++j )
229 : {
230 : Word32 tmp_fx;
231 94248448 : Word16 exp_tmp = 0;
232 94248448 : move16();
233 94248448 : Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16
234 94248448 : tmp_fx = BASOP_Util_Add_Mant32Exp( snsq_fx[j], exp_snsq, L_negate( tmp_1 ), 15, &exp_tmp );
235 94248448 : Word32 tmp_2 = Mpy_32_32( tmp_fx, tmp_fx ); // exp_tmp*2
236 94248448 : dist_fx = BASOP_Util_Add_Mant32Exp( dist_fx, exp_dist, tmp_2, exp_tmp * 2, &exp_dist ); // exp_tmp*2
237 : }
238 :
239 11781056 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( dist_fx, exp_dist, dist_min_fx, exp_dist_min ), -1 ) )
240 : {
241 1827307 : dist_min_fx = dist_fx;
242 1827307 : move32();
243 1827307 : exp_dist_min = exp_dist;
244 1827307 : move16();
245 1827307 : index_split = i;
246 1827307 : move16();
247 : }
248 : }
249 :
250 : /* set quantized vector */
251 368158 : cdbk_ptr = &cdbk[imult1616( index_split, split_len )];
252 3313422 : FOR( Word16 j = j0; j < j1; ++j )
253 : {
254 2945264 : Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16
255 2945264 : Word32 tmp_4 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16
256 2945264 : snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16
257 2945264 : move32();
258 : }
259 :
260 : /* for second split shift by five bits to store both indices as one 10 bit value */
261 368158 : IF( EQ_16( split, 1 ) )
262 : {
263 184079 : index_split = shl( index_split, 5 );
264 : }
265 :
266 368158 : index = add( index, index_split );
267 : }
268 :
269 184079 : return index;
270 : }
271 : }
272 :
273 : /*-------------------------------------------------------------------
274 : * sns_2st_cod()
275 : *
276 : *
277 : *-------------------------------------------------------------------*/
278 :
279 : /* r : number of allocated bits */
280 536209 : static Word16 sns_2st_cod_fx(
281 : const Word32 *sns_fx, /* i : normalized vector to quantize */
282 : Word16 exp_sns,
283 : Word32 *snsq_fx, /* i/o: i:1st stage o:1st+2nd stage Q16 */
284 : Word16 exp_snsq,
285 : Word16 *indx /* o : index[] (4 bits per words) */
286 : )
287 : {
288 : Word16 i, nbits;
289 :
290 536209 : Word16 x_fx[M] = { 0 };
291 536209 : move16();
292 : Word16 xq_fx[M];
293 536209 : Word16 exp_x_buff[M] = { 0 }, exp_x = 0;
294 536209 : move16();
295 536209 : move16();
296 536209 : Word32 scale_fx = 858993472; // Q31
297 536209 : move32();
298 : Word16 nq;
299 :
300 9115553 : FOR( i = 0; i < M; i++ )
301 : {
302 8579344 : Word16 exp_tmp = 0;
303 8579344 : move16();
304 8579344 : Word32 tmp = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( snsq_fx[i] ), exp_snsq, &exp_tmp );
305 8579344 : x_fx[i] = BASOP_Util_Divide3232_Scale( tmp, scale_fx, &exp_x_buff[i] );
306 8579344 : move16();
307 8579344 : exp_x_buff[i] = add( exp_x_buff[i], exp_tmp );
308 8579344 : move16();
309 : }
310 9115553 : FOR( i = 0; i < M; i++ )
311 : {
312 8579344 : exp_x = s_max( exp_x, exp_x_buff[i] );
313 : }
314 9115553 : FOR( i = 0; i < M; i++ )
315 : {
316 8579344 : x_fx[i] = shr( x_fx[i], sub( ( 15 - Q10 ), exp_x_buff[i] ) );
317 8579344 : move16();
318 : }
319 :
320 : /* quantize */
321 536209 : AVQ_cod_lpc_fx( x_fx, xq_fx, indx, 2 );
322 9115553 : FOR( i = 0; i < M; i++ )
323 : {
324 8579344 : Word32 tmp_1 = Mpy_32_16_1( scale_fx, xq_fx[i] ); // Q31 + Q10 - 15
325 8579344 : tmp_1 = L_shr( tmp_1, 10 ); // Q16
326 8579344 : snsq_fx[i] = L_add( snsq_fx[i], tmp_1 ); // Q16
327 8579344 : move32();
328 : }
329 :
330 : /* total number of bits using entropic code to index the quantizer number */
331 536209 : nbits = 0;
332 536209 : move16();
333 1608627 : FOR( i = 0; i < 2; i++ )
334 : {
335 1072418 : nq = indx[i];
336 1072418 : move16();
337 1072418 : nbits = add( nbits, ( add( 2, ( shl( nq, 2 ) ) ) ) ); /* 2 bits to specify Q2,Q3,Q4,ext */
338 :
339 1072418 : IF( GT_16( nq, 6 ) )
340 : {
341 338 : nbits = add( nbits, sub( nq, 3 ) ); /* unary code (Q7=1110, ...) */
342 : }
343 1072080 : ELSE IF( GT_16( nq, 4 ) )
344 : {
345 36308 : nbits = add( nbits, sub( nq, 4 ) ); /* Q5=0, Q6=10 */
346 : }
347 1035772 : ELSE IF( nq == 0 )
348 : {
349 111060 : nbits = add( nbits, 3 ); /* Q0=110 */
350 : }
351 : }
352 :
353 536209 : return ( nbits );
354 : }
355 :
356 : /*-------------------------------------------------------------------
357 : * sns_avq_cod()
358 : *
359 : * Stereo noise-shaping AVQ encoder for 1 channel
360 : *-------------------------------------------------------------------*/
361 72781 : void sns_avq_cod_fx(
362 : const Word32 *sns_fx, /* i : Input sns vectors */
363 : Word16 exp_sns,
364 : const Word32 *snsmid_fx, /* i : Input mid-sns vectors */
365 : Word16 exp_snsmid,
366 : Word32 *sns_q_fx, /* o : Quantized LFS vectors Q16 */
367 : Word32 *snsmid_q_fx, /* o : Quantized mid-LFS vectors Q16 */
368 : Word16 *index, /* o : Quantization indices */
369 : const Word16 core, /* i : core */
370 : const Word16 L_frame,
371 : const Word16 low_brate_mode /* i : flag low bit operating mode */
372 : )
373 : {
374 : Word16 i;
375 : Word16 indxt[256], nbits, nbt, nit;
376 : Word32 snsmid_q0_fx[M];
377 :
378 72781 : index[0] = sns_1st_cod_fx( sns_fx, exp_sns, L_frame, core, sns_q_fx );
379 72781 : move16();
380 72781 : nit = 1 + 2;
381 72781 : move16();
382 72781 : IF( !low_brate_mode )
383 : {
384 72619 : nbt = sns_2st_cod_fx( sns_fx, exp_sns, sns_q_fx, 31 - Q16, &index[1] );
385 72619 : nit = add( nit, add( index[1], index[2] ) );
386 : }
387 : ELSE
388 : {
389 162 : index[1] = SNS_LOW_BR_MODE;
390 162 : move16();
391 162 : index[2] = 0;
392 162 : move16();
393 : }
394 :
395 72781 : index += nit;
396 72781 : nit = 0;
397 72781 : move16();
398 72781 : *index = 0;
399 72781 : move16();
400 :
401 72781 : IF( EQ_16( core, TCX_10_CORE ) )
402 : {
403 11399 : index++;
404 :
405 11399 : index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx );
406 11399 : move16();
407 11399 : nit = 1 + 2;
408 11399 : move16();
409 11399 : IF( !low_brate_mode )
410 : {
411 11266 : nbits = sns_2st_cod_fx( snsmid_fx, exp_snsmid, snsmid_q_fx, 31 - Q16, &index[1] );
412 11266 : nit = add( nit, add( index[1], index[2] ) );
413 : }
414 : ELSE
415 : {
416 133 : index[1] = SNS_LOW_BR_MODE;
417 133 : move16();
418 133 : index[2] = 0;
419 133 : move16();
420 133 : nbits = 0;
421 133 : move16();
422 : }
423 :
424 :
425 11399 : nbt = add( 10, nbits );
426 :
427 11399 : IF( !low_brate_mode )
428 : {
429 191522 : FOR( i = 0; i < M; i++ )
430 : {
431 180256 : snsmid_q0_fx[i] = sns_q_fx[i];
432 180256 : move32();
433 : }
434 11266 : nbits = sns_2st_cod_fx( snsmid_fx, exp_snsmid, snsmid_q0_fx, 31 - Q16, indxt );
435 :
436 11266 : IF( LT_16( nbits, nbt ) )
437 : {
438 7179 : nbt = nbits;
439 7179 : move16();
440 7179 : nit = add( 2, add( indxt[0], indxt[1] ) );
441 7179 : index[-1] = 1;
442 7179 : move16();
443 :
444 122043 : FOR( i = 0; i < M; i++ )
445 : {
446 114864 : snsmid_q_fx[i] = snsmid_q0_fx[i];
447 114864 : move32();
448 : }
449 :
450 61796 : FOR( i = 0; i < nit; i++ )
451 : {
452 54617 : index[i] = indxt[i];
453 54617 : move16();
454 : }
455 : }
456 : }
457 11399 : index += nit;
458 : }
459 72781 : return;
460 : }
461 :
462 : /*-------------------------------------------------------------------
463 : * sns_avq_cod_stereo()
464 : *
465 : * Stereo noise-shaping AVQ encoder for 2 channels
466 : *-------------------------------------------------------------------*/
467 :
468 220529 : void sns_avq_cod_stereo_fx(
469 : const Word32 *snsl_fx, /* i : Input sns vector (left channel) */
470 : Word16 exp_snl,
471 : const Word32 *snsr_fx, /* i : Input sns vector (right channel) */
472 : Word16 exp_snr,
473 : const Word16 L_frame,
474 : Word32 *snsl_q_fx, /* o : Quantized sns vector (left channel) Q16 */
475 : Word32 *snsr_q_fx, /* o : Quantized sns vector (right channel) Q16 */
476 : Word16 *indexl, /* o : Quantization indices (left channel) */
477 : Word16 *indexr /* o : Quantization indices (right channel) */
478 : )
479 : {
480 : Word16 i, flag_zero;
481 : Word32 mid_fx[M], side_fx[M], mid_q_fx[M], side_q_fx[M], ener_side_fx;
482 220529 : Word16 exp_ener_side = 0, exp_side_buffer[M] = { 0 }, exp_side = MIN16B;
483 220529 : move16();
484 220529 : move16();
485 220529 : move16();
486 :
487 : /* Compute side */
488 220529 : ener_side_fx = 0;
489 220529 : move16();
490 3748993 : FOR( i = 0; i < M; i++ )
491 : {
492 3528464 : side_fx[i] = BASOP_Util_Add_Mant32Exp( snsl_fx[i], exp_snl, L_negate( snsr_fx[i] ), exp_snr, &exp_side_buffer[i] );
493 3528464 : move32();
494 3528464 : Word32 tmp = Mpy_32_32( side_fx[i], side_fx[i] ); // exp_side[i] * 2
495 3528464 : ener_side_fx = BASOP_Util_Add_Mant32Exp( ener_side_fx, exp_ener_side, tmp, shl( exp_side_buffer[i], 1 ), &exp_ener_side );
496 : }
497 3748993 : FOR( i = 0; i < M; i++ )
498 : {
499 3528464 : exp_side = s_max( exp_side, exp_side_buffer[i] );
500 : }
501 3748993 : FOR( i = 0; i < M; i++ )
502 : {
503 3528464 : side_fx[i] = L_shr( side_fx[i], exp_side - exp_side_buffer[i] );
504 3528464 : move32();
505 : }
506 :
507 220529 : Word16 flag = BASOP_Util_Cmp_Mant32Exp( ener_side_fx, exp_ener_side, 24576, 31 - Q11 );
508 220529 : IF( EQ_16( flag, -1 ) )
509 : {
510 : /* MS coding */
511 184079 : *indexl++ = 2;
512 184079 : move16();
513 184079 : *indexr++ = 3;
514 184079 : move16();
515 :
516 : /* Compute mid */
517 184079 : Word16 exp_mid_buffer[M] = { 0 };
518 184079 : move16();
519 3129343 : FOR( i = 0; i < M; i++ )
520 : {
521 2945264 : mid_fx[i] = BASOP_Util_Add_Mant32Exp( snsl_fx[i], exp_snl, snsr_fx[i], exp_snr, &exp_mid_buffer[i] );
522 2945264 : move32();
523 2945264 : mid_fx[i] = L_shr( mid_fx[i], 1 );
524 2945264 : move32();
525 : }
526 :
527 : /* Quantize mid */
528 184079 : Word16 exp_mid = 0;
529 184079 : move16();
530 3129343 : FOR( i = 0; i < M; i++ )
531 : {
532 2945264 : exp_mid = s_max( exp_mid, exp_mid_buffer[i] );
533 : }
534 3129343 : FOR( i = 0; i < M; i++ )
535 : {
536 2945264 : mid_fx[i] = L_shr( mid_fx[i], exp_mid - exp_mid_buffer[i] );
537 2945264 : move32();
538 : }
539 184079 : indexl[0] = sns_1st_cod_fx( mid_fx, exp_mid, L_frame, TCX_20_CORE, mid_q_fx );
540 184079 : move16();
541 184079 : sns_2st_cod_fx( mid_fx, exp_mid, mid_q_fx, ( 31 - Q16 ), &indexl[1] );
542 :
543 : /* Quantize side */
544 184079 : indexr[0] = -1;
545 184079 : move16();
546 3129343 : FOR( i = 0; i < M; i++ )
547 : {
548 2945264 : side_q_fx[i] = 0;
549 2945264 : move32();
550 : }
551 184079 : sns_2st_cod_fx( side_fx, exp_side, side_q_fx, 31 - Q16, &indexr[1] );
552 :
553 : /* Detect zero side */
554 184079 : flag_zero = 1;
555 184079 : move16();
556 615598 : FOR( i = 0; i < M; i++ )
557 : {
558 595805 : if ( side_q_fx[i] != 0 )
559 : {
560 164286 : flag_zero = 0;
561 164286 : move16();
562 164286 : break;
563 : }
564 : }
565 184079 : if ( flag_zero )
566 : {
567 19793 : indexr[0] = -2;
568 19793 : move16();
569 : }
570 :
571 : /* Go back to LR */
572 3129343 : FOR( i = 0; i < M; i++ )
573 : {
574 2945264 : Word32 a = L_shr( side_q_fx[i], 1 );
575 2945264 : snsl_q_fx[i] = L_add( mid_q_fx[i], a );
576 2945264 : move32();
577 2945264 : snsr_q_fx[i] = L_sub( mid_q_fx[i], a );
578 2945264 : move32();
579 : }
580 : }
581 : ELSE
582 : {
583 : /* LR coding */
584 36450 : *indexl++ = 0;
585 36450 : move16();
586 36450 : *indexr++ = 1;
587 36450 : move16();
588 :
589 : /* Quantize left */
590 36450 : indexl[0] = sns_1st_cod_fx( snsl_fx, exp_snl, L_frame, TCX_20_CORE, snsl_q_fx );
591 36450 : move16();
592 36450 : sns_2st_cod_fx( snsl_fx, exp_snl, snsl_q_fx, ( 31 - Q16 ), &indexl[1] );
593 :
594 : /* Quantize right */
595 36450 : indexr[0] = sns_1st_cod_fx( snsr_fx, exp_snr, L_frame, TCX_20_CORE, snsr_q_fx );
596 36450 : move16();
597 36450 : sns_2st_cod_fx( snsr_fx, exp_snr, snsr_q_fx, ( 31 - Q16 ), &indexr[1] );
598 : }
599 220529 : return;
600 : }
601 48382 : Word16 quantize_sns_fx(
602 : Word32 sns_in_fx[CPE_CHANNELS][NB_DIV][M], /* sns_e */
603 : Word32 snsQ_out_fx[CPE_CHANNELS][NB_DIV][M], /* sns_e */
604 : Word16 sns_e,
605 : Encoder_State **sts,
606 : Word16 *indices, /* Q0 */
607 : Word16 *zero_side_flag, /* Q0 */
608 : Word16 *sns_stereo_mode ) /* Q0 */
609 : {
610 48382 : Word16 nSubframes = 0, k, ch, i;
611 : Word16 nbits, idxIndices;
612 : Encoder_State *st;
613 :
614 : Word16 weights_fx[M];
615 : Word16 sns_e_tmp[CPE_CHANNELS][NB_DIV];
616 :
617 48382 : nbits = 0;
618 48382 : move16();
619 48382 : idxIndices = 0;
620 48382 : move16();
621 48382 : set16_fx( weights_fx, ONE_IN_Q8, M );
622 :
623 48382 : sns_stereo_mode[0] = SNS_STEREO_MODE_LR;
624 48382 : move16();
625 48382 : sns_stereo_mode[1] = SNS_STEREO_MODE_LR;
626 48382 : move16();
627 48382 : zero_side_flag[0] = 0;
628 48382 : move16();
629 48382 : zero_side_flag[1] = 0;
630 48382 : move16();
631 :
632 : /* use snsQ_out as buffer, move input vectors */
633 145146 : FOR( ch = 0; ch < CPE_CHANNELS; ++ch )
634 : {
635 96764 : IF( EQ_16( sts[ch]->core, TCX_20_CORE ) )
636 : {
637 94418 : nSubframes = 1;
638 : }
639 : ELSE
640 : {
641 2346 : nSubframes = NB_DIV;
642 : }
643 96764 : move16();
644 :
645 195874 : FOR( k = 0; k < nSubframes; ++k )
646 : {
647 99110 : Copy32( sns_in_fx[ch][k], snsQ_out_fx[ch][k], M ); // sns_e
648 : }
649 :
650 96764 : sns_e_tmp[ch][0] = sns_e;
651 96764 : move16();
652 96764 : sns_e_tmp[ch][1] = sns_e;
653 96764 : move16();
654 : }
655 :
656 : /* stereo mode decision */
657 48382 : IF( EQ_16( sts[0]->core, sts[1]->core ) )
658 : {
659 48058 : IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
660 : {
661 47047 : nSubframes = 1;
662 : }
663 : ELSE
664 : {
665 1011 : nSubframes = NB_DIV;
666 : }
667 48058 : move16();
668 :
669 97127 : FOR( k = 0; k < nSubframes; ++k )
670 : {
671 : Word32 side_fx[M];
672 : Word32 ener_side_fx;
673 : Word16 ener_side_q;
674 :
675 49069 : v_sub_fixed_no_hdrm( snsQ_out_fx[0][k], snsQ_out_fx[1][k], side_fx, M );
676 :
677 : Word64 L64_sum;
678 49069 : L64_sum = 1;
679 49069 : move64();
680 834173 : FOR( i = 0; i < M; i++ )
681 : {
682 785104 : L64_sum = W_mac_32_32( L64_sum, side_fx[i], side_fx[i] );
683 : }
684 49069 : i = W_norm( L64_sum );
685 49069 : L64_sum = W_shl( L64_sum, i );
686 49069 : ener_side_fx = W_extract_h( L64_sum ); // ener_side_q
687 49069 : ener_side_q = sub( add( shl( sub( 31, sns_e ), 1 ), add( 1, i ) ), 32 );
688 :
689 49069 : sns_stereo_mode[k] = 0;
690 49069 : move16();
691 49069 : zero_side_flag[k] = 0;
692 49069 : move16();
693 :
694 49069 : IF( LT_32( L_shl( ener_side_fx, sub( s_min( Q27, ener_side_q ), ener_side_q ) ), L_shl( 1610612736 /* 12.0 if Q27*/, sub( s_min( Q27, ener_side_q ), Q27 ) ) ) )
695 : {
696 45900 : sns_stereo_mode[k] = 1;
697 45900 : move16();
698 : }
699 :
700 49069 : IF( LT_32( L_shl( ener_side_fx, sub( s_min( Q30, ener_side_q ), ener_side_q ) ), L_shl( 1, s_min( Q30, ener_side_q ) ) ) )
701 : {
702 9499 : zero_side_flag[k] = 1;
703 9499 : move16();
704 : }
705 :
706 :
707 49069 : IF( EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS ) )
708 : {
709 45900 : convertToMS_fx( M, snsQ_out_fx[0][k], snsQ_out_fx[1][k], ONE_IN_Q30 );
710 : }
711 : }
712 : }
713 :
714 : /* run MSVQ */
715 145146 : FOR( ch = 0; ch < CPE_CHANNELS; ++ch )
716 : {
717 96764 : st = sts[ch];
718 96764 : IF( EQ_16( st->core, TCX_20_CORE ) )
719 : {
720 94418 : nSubframes = 1;
721 : }
722 : ELSE
723 : {
724 2346 : nSubframes = NB_DIV;
725 : }
726 96764 : move16();
727 :
728 195874 : FOR( k = 0; k < nSubframes; ++k )
729 : {
730 99110 : Word16 is_side = 0;
731 99110 : move16();
732 99110 : IF( EQ_16( ch, 1 ) && EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS ) )
733 : {
734 45900 : is_side = 1;
735 45900 : move16();
736 : }
737 :
738 : const Word16 *const *cdbks_fx;
739 : const Word16 *levels;
740 : const Word16 *bits;
741 : Word16 nStages;
742 99110 : IF( EQ_16( nSubframes, 1 ) )
743 : {
744 94418 : cdbks_fx = ivas_sns_cdbks_tcx20_fx;
745 94418 : levels = ivas_sns_cdbks_tcx20_levels;
746 94418 : bits = ivas_sns_cdbks_tcx20_bits;
747 94418 : nStages = SNS_MSVQ_NSTAGES_TCX20;
748 : }
749 : ELSE
750 : {
751 4692 : cdbks_fx = ivas_sns_cdbks_tcx10_fx;
752 4692 : levels = ivas_sns_cdbks_tcx10_levels;
753 4692 : bits = ivas_sns_cdbks_tcx10_bits;
754 4692 : nStages = SNS_MSVQ_NSTAGES_TCX10;
755 : }
756 99110 : move16();
757 :
758 99110 : Word32 *snsQ_fx = snsQ_out_fx[ch][k];
759 99110 : const Word32 *sns_ptr_fx = snsQ_out_fx[ch][k];
760 :
761 99110 : IF( is_side )
762 : {
763 : const Word16 *const *side_cdbks_fx;
764 : const Word16 *side_levels;
765 :
766 45900 : IF( EQ_16( st->core, TCX_20_CORE ) )
767 : {
768 44060 : side_cdbks_fx = ivas_sns_cdbks_side_tcx20_fx;
769 44060 : side_levels = ivas_sns_cdbks_side_tcx20_levels;
770 44060 : bits = ivas_sns_cdbks_side_tcx20_bits;
771 : }
772 : ELSE
773 : {
774 1840 : side_cdbks_fx = ivas_sns_cdbks_side_tcx10_fx;
775 1840 : side_levels = ivas_sns_cdbks_side_tcx10_levels;
776 1840 : bits = ivas_sns_cdbks_side_tcx10_bits;
777 : }
778 :
779 :
780 45900 : IF( zero_side_flag[k] )
781 : {
782 9499 : set32_fx( snsQ_fx, 0, M );
783 9499 : CONTINUE;
784 : }
785 :
786 36401 : nStages = SNS_MSVQ_NSTAGES_SIDE;
787 36401 : move16();
788 :
789 36401 : msvq_enc_ivas_fx( side_cdbks_fx, Q15, NULL, NULL, snsQ_fx, sns_e, side_levels, 3, nStages, weights_fx, M, M, 0, NULL, &indices[idxIndices] );
790 36401 : msvq_dec_fx( side_cdbks_fx, NULL, NULL, nStages, M, M, &indices[idxIndices], 0, NULL, snsQ_fx, NULL, Q15 );
791 : }
792 : ELSE
793 : {
794 53210 : msvq_enc_ivas_fx( cdbks_fx, Q12, NULL, NULL, sns_ptr_fx, sns_e, levels, 3, nStages, weights_fx, M, M, 0, NULL, &indices[idxIndices] );
795 53210 : msvq_dec_fx( cdbks_fx, NULL, NULL, nStages, M, M, &indices[idxIndices], 0, NULL, snsQ_fx, NULL, Q12 );
796 : }
797 89611 : Word16 shift = find_guarded_bits_fx( M );
798 89611 : sns_e_tmp[ch][k] = sub( 31, sub( 20, shift ) );
799 89611 : move16();
800 89611 : idxIndices = add( idxIndices, nStages );
801 :
802 372401 : FOR( i = 0; i < nStages; ++i )
803 : {
804 282790 : nbits = add( nbits, bits[i] );
805 : }
806 : }
807 : }
808 : /* Re-Scaling Buffers*/
809 48382 : sns_e = sns_e_tmp[0][0];
810 48382 : move16();
811 :
812 145146 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
813 : {
814 96764 : sns_e = s_max( sns_e, sns_e_tmp[ch][0] );
815 96764 : sns_e = s_max( sns_e, sns_e_tmp[ch][1] );
816 : }
817 :
818 145146 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
819 : {
820 195874 : FOR( k = 0; k < nSubframes; k++ )
821 : {
822 99110 : scale_sig32( snsQ_out_fx[ch][k], M, sub( sns_e_tmp[ch][k], sns_e ) ); // Q(31-sns_e_tmp[ch][k])
823 : }
824 : }
825 : /* get back to L/F representation */
826 48382 : test();
827 48382 : IF( EQ_16( sns_stereo_mode[0], SNS_STEREO_MODE_MS ) || EQ_16( sns_stereo_mode[1], SNS_STEREO_MODE_MS ) )
828 : {
829 45028 : IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
830 : {
831 44060 : nSubframes = 1;
832 : }
833 : ELSE
834 : {
835 968 : nSubframes = NB_DIV;
836 : }
837 45028 : move16();
838 :
839 91024 : FOR( k = 0; k < nSubframes; ++k )
840 : {
841 45996 : IF( EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS ) )
842 : {
843 45900 : convertToMS_fx( M, snsQ_out_fx[0][k], snsQ_out_fx[1][k], ONE_IN_Q31 );
844 : }
845 : }
846 : }
847 :
848 48382 : return nbits;
849 : }
|