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 367224 : 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 367224 : IF( exp_sns == Q15 )
63 : {
64 : Word16 index;
65 179646 : const Word16 split_len = M / 2;
66 179646 : move16();
67 : const Word16 *means;
68 179646 : const Word16 means_fix = 2; // Q15
69 179646 : move16();
70 : /* remove means */
71 179646 : means = NULL;
72 179646 : SWITCH( L_frame )
73 : {
74 16199 : case L_FRAME16k:
75 16199 : means = &sns_1st_means_16k[core - 1][0]; // Q14
76 16199 : break;
77 59552 : case L_FRAME25_6k:
78 59552 : means = &sns_1st_means_25k6[core - 1][0]; // Q14
79 59552 : break;
80 103895 : case L_FRAME32k:
81 103895 : means = &sns_1st_means_32k[core - 1][0]; // Q14
82 103895 : break;
83 0 : default:
84 0 : assert( !"illegal frame length in sns_1st_cod" );
85 : }
86 3053982 : FOR( Word16 i = 0; i < M; ++i )
87 : {
88 2874336 : Word32 tmp = L_mult( means[i], means_fix ); // Q14->Q16
89 2874336 : snsq_fx[i] = L_sub( sns_fx[i], tmp ); // Q16
90 2874336 : move32();
91 : }
92 :
93 179646 : index = 0;
94 179646 : move16();
95 538938 : 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 359292 : const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15
102 359292 : move16();
103 359292 : const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0]; // Q12
104 :
105 359292 : j0 = imult1616( split, split_len );
106 359292 : j1 = add( j0, split_len );
107 :
108 359292 : cdbk_ptr = cdbk;
109 359292 : dist_min_fx = MAXVAL_WORD32;
110 359292 : index_split = 0;
111 359292 : move32();
112 359292 : move16();
113 11856636 : FOR( Word16 i = 0; i < 32; ++i )
114 : {
115 11497344 : Word32 dist_fx = 0;
116 11497344 : move32();
117 103476096 : 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 91978752 : tmp = L_mult( *cdbk_ptr++, cdbk_fix ); // Q12->Q16
123 91978752 : dist = L_sub( snsq_fx[j], tmp ); // Q16
124 91978752 : 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 91978752 : dist = Mpy_32_32( dist, dist );
126 91978752 : dist = L_shr( dist, 3 ); // make sure that the sum of 8 values does not overflow
127 91978752 : dist_fx = L_add( dist_fx, dist );
128 : }
129 :
130 11497344 : IF( LT_32( dist_fx, dist_min_fx ) )
131 : {
132 1766214 : dist_min_fx = dist_fx;
133 1766214 : move32();
134 1766214 : index_split = i;
135 1766214 : move16();
136 : }
137 : }
138 :
139 : /* set quantized vector */
140 359292 : cdbk_ptr = &cdbk[imult1616( index_split, split_len )];
141 3233628 : FOR( Word16 j = j0; j < j1; ++j )
142 : {
143 2874336 : Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16
144 2874336 : Word32 tmp_4 = L_mult( *cdbk_ptr++, cdbk_fix ); // Q16
145 2874336 : snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16
146 2874336 : move32();
147 : }
148 :
149 : /* for second split shift by five bits to store both indices as one 10 bit value */
150 359292 : if ( EQ_16( split, 1 ) )
151 : {
152 179646 : index_split = shl( index_split, 5 );
153 : }
154 :
155 359292 : index = add( index, index_split );
156 : }
157 179646 : return index;
158 : }
159 : ELSE
160 : {
161 : Word16 index, i;
162 187578 : const Word16 split_len = M / 2;
163 187578 : move16();
164 : const Word16 *means;
165 187578 : const Word16 means_fix = 2; // Q15
166 187578 : move16();
167 : /* remove means */
168 187578 : means = NULL;
169 187578 : SWITCH( L_frame )
170 : {
171 23265 : case L_FRAME16k:
172 23265 : means = &sns_1st_means_16k[core - 1][0];
173 23265 : break;
174 52487 : case L_FRAME25_6k:
175 52487 : means = &sns_1st_means_25k6[core - 1][0];
176 52487 : break;
177 111826 : case L_FRAME32k:
178 111826 : means = &sns_1st_means_32k[core - 1][0];
179 111826 : break;
180 0 : default:
181 0 : assert( !"illegal frame length in sns_1st_cod" );
182 : }
183 187578 : Word16 exp_snsq_buffer[M] = { 0 }, exp_snsq = 0;
184 187578 : move16();
185 187578 : move16();
186 3188826 : FOR( i = 0; i < M; ++i )
187 : {
188 3001248 : Word32 tmp = L_mult( means[i], means_fix ); // Q16
189 3001248 : exp_snsq_buffer[i] = 0;
190 3001248 : move16();
191 3001248 : snsq_fx[i] = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( tmp ), 15, &exp_snsq_buffer[i] );
192 3001248 : move32();
193 : }
194 3188826 : FOR( i = 0; i < M; i++ )
195 : {
196 3001248 : exp_snsq = s_max( exp_snsq_buffer[i], exp_snsq );
197 : }
198 3188826 : FOR( i = 0; i < M; i++ )
199 : {
200 3001248 : snsq_fx[i] = L_shr( snsq_fx[i], exp_snsq - exp_snsq_buffer[i] );
201 3001248 : move32();
202 : }
203 :
204 187578 : index = 0;
205 187578 : move16();
206 562734 : 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 375156 : const Word16 cdbk_fix = 8; // 1.f / powf( 2, SNS_CDBKS_BITS_4_FRAC ) in Q15
212 375156 : move16();
213 375156 : const Word16 *const cdbk = &sns_1st_cdbk[split][core - 1][0];
214 :
215 375156 : j0 = imult1616( split, split_len );
216 375156 : j1 = add( j0, split_len );
217 :
218 375156 : cdbk_ptr = cdbk;
219 375156 : dist_min_fx = MAXVAL_WORD32;
220 375156 : Word16 exp_dist_min = 31;
221 375156 : index_split = 0;
222 12380148 : FOR( i = 0; i < 32; ++i )
223 : {
224 12004992 : Word32 dist_fx = 0;
225 12004992 : move32();
226 12004992 : Word16 exp_dist = 0;
227 12004992 : move16();
228 108044928 : FOR( Word16 j = j0; j < j1; ++j )
229 : {
230 : Word32 tmp_fx;
231 96039936 : Word16 exp_tmp = 0;
232 96039936 : move16();
233 96039936 : Word32 tmp_1 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16
234 96039936 : tmp_fx = BASOP_Util_Add_Mant32Exp( snsq_fx[j], exp_snsq, L_negate( tmp_1 ), 15, &exp_tmp );
235 96039936 : Word32 tmp_2 = Mpy_32_32( tmp_fx, tmp_fx ); // exp_tmp*2
236 96039936 : dist_fx = BASOP_Util_Add_Mant32Exp( dist_fx, exp_dist, tmp_2, exp_tmp * 2, &exp_dist ); // exp_tmp*2
237 : }
238 :
239 12004992 : IF( EQ_16( BASOP_Util_Cmp_Mant32Exp( dist_fx, exp_dist, dist_min_fx, exp_dist_min ), -1 ) )
240 : {
241 1864146 : dist_min_fx = dist_fx;
242 1864146 : move32();
243 1864146 : exp_dist_min = exp_dist;
244 1864146 : move16();
245 1864146 : index_split = i;
246 1864146 : move16();
247 : }
248 : }
249 :
250 : /* set quantized vector */
251 375156 : cdbk_ptr = &cdbk[imult1616( index_split, split_len )];
252 3376404 : FOR( Word16 j = j0; j < j1; ++j )
253 : {
254 3001248 : Word32 tmp_3 = L_mult( means[j], means_fix ); // Q16
255 3001248 : Word32 tmp_4 = L_mult( ( *cdbk_ptr++ ), cdbk_fix ); // Q16
256 3001248 : snsq_fx[j] = L_add( tmp_4, tmp_3 ); // Q16
257 3001248 : move32();
258 : }
259 :
260 : /* for second split shift by five bits to store both indices as one 10 bit value */
261 375156 : if ( EQ_16( split, 1 ) )
262 : {
263 187578 : index_split = shl( index_split, 5 );
264 : }
265 :
266 375156 : index = add( index, index_split );
267 : }
268 :
269 187578 : return index;
270 : }
271 : }
272 :
273 : /*-------------------------------------------------------------------
274 : * sns_2st_cod()
275 : *
276 : *
277 : *-------------------------------------------------------------------*/
278 :
279 : /* r : number of allocated bits */
280 566775 : 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 566775 : Word16 x_fx[M] = { 0 };
291 566775 : move16();
292 : Word16 xq_fx[M];
293 566775 : Word16 exp_x_buff[M] = { 0 }, exp_x = 0;
294 566775 : move16();
295 566775 : move16();
296 566775 : Word32 scale_fx = 858993472; // Q31
297 566775 : move32();
298 : Word16 nq;
299 :
300 9635175 : FOR( i = 0; i < M; i++ )
301 : {
302 9068400 : Word16 exp_tmp = 0;
303 9068400 : move16();
304 9068400 : Word32 tmp = BASOP_Util_Add_Mant32Exp( sns_fx[i], exp_sns, L_negate( snsq_fx[i] ), exp_snsq, &exp_tmp );
305 9068400 : x_fx[i] = BASOP_Util_Divide3232_Scale( tmp, scale_fx, &exp_x_buff[i] );
306 9068400 : move16();
307 9068400 : exp_x_buff[i] = add( exp_x_buff[i], exp_tmp );
308 9068400 : move16();
309 : }
310 9635175 : FOR( i = 0; i < M; i++ )
311 : {
312 9068400 : exp_x = s_max( exp_x, exp_x_buff[i] );
313 : }
314 9635175 : FOR( i = 0; i < M; i++ )
315 : {
316 9068400 : x_fx[i] = shr( x_fx[i], sub( ( 15 - Q10 ), exp_x_buff[i] ) );
317 9068400 : move16();
318 : }
319 :
320 : /* quantize */
321 566775 : AVQ_cod_lpc_fx( x_fx, xq_fx, indx, 2 );
322 9635175 : FOR( i = 0; i < M; i++ )
323 : {
324 9068400 : Word32 tmp_1 = Mpy_32_16_1( scale_fx, xq_fx[i] ); // Q31 + Q10 - 15
325 9068400 : tmp_1 = L_shr( tmp_1, 10 ); // Q16
326 9068400 : snsq_fx[i] = L_add( snsq_fx[i], tmp_1 ); // Q16
327 9068400 : move32();
328 : }
329 :
330 : /* total number of bits using entropic code to index the quantizer number */
331 566775 : nbits = 0;
332 566775 : move16();
333 1700325 : FOR( i = 0; i < 2; i++ )
334 : {
335 1133550 : nq = indx[i];
336 1133550 : move16();
337 1133550 : nbits = add( nbits, ( add( 2, ( shl( nq, 2 ) ) ) ) ); /* 2 bits to specify Q2,Q3,Q4,ext */
338 :
339 1133550 : IF( GT_16( nq, 6 ) )
340 : {
341 369 : nbits = add( nbits, sub( nq, 3 ) ); /* unary code (Q7=1110, ...) */
342 : }
343 1133181 : ELSE IF( GT_16( nq, 4 ) )
344 : {
345 39832 : nbits = add( nbits, sub( nq, 4 ) ); /* Q5=0, Q6=10 */
346 : }
347 1093349 : ELSE IF( nq == 0 )
348 : {
349 117863 : nbits = add( nbits, 3 ); /* Q0=110 */
350 : }
351 : }
352 :
353 566775 : return ( nbits );
354 : }
355 :
356 : /*-------------------------------------------------------------------
357 : * sns_avq_cod()
358 : *
359 : * Stereo noise-shaping AVQ encoder for 1 channel
360 : *-------------------------------------------------------------------*/
361 75611 : 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 75611 : index[0] = sns_1st_cod_fx( sns_fx, exp_sns, L_frame, core, sns_q_fx );
379 75611 : move16();
380 75611 : nit = 1 + 2;
381 75611 : move16();
382 75611 : IF( !low_brate_mode )
383 : {
384 75447 : nbt = sns_2st_cod_fx( sns_fx, exp_sns, sns_q_fx, 31 - Q16, &index[1] );
385 75447 : nit = add( nit, add( index[1], index[2] ) );
386 : }
387 : ELSE
388 : {
389 164 : index[1] = SNS_LOW_BR_MODE;
390 164 : move16();
391 164 : index[2] = 0;
392 164 : move16();
393 : }
394 :
395 75611 : index += nit;
396 75611 : nit = 0;
397 75611 : move16();
398 75611 : *index = 0;
399 75611 : move16();
400 :
401 75611 : IF( EQ_16( core, TCX_10_CORE ) )
402 : {
403 12407 : index++;
404 :
405 12407 : index[0] = sns_1st_cod_fx( snsmid_fx, exp_snsmid, L_frame, core, snsmid_q_fx );
406 12407 : move16();
407 12407 : nit = 1 + 2;
408 12407 : move16();
409 12407 : IF( !low_brate_mode )
410 : {
411 12272 : nbits = sns_2st_cod_fx( snsmid_fx, exp_snsmid, snsmid_q_fx, 31 - Q16, &index[1] );
412 12272 : nit = add( nit, add( index[1], index[2] ) );
413 : }
414 : ELSE
415 : {
416 135 : index[1] = SNS_LOW_BR_MODE;
417 135 : move16();
418 135 : index[2] = 0;
419 135 : move16();
420 135 : nbits = 0;
421 135 : move16();
422 : }
423 :
424 :
425 12407 : nbt = add( 10, nbits );
426 :
427 12407 : IF( !low_brate_mode )
428 : {
429 208624 : FOR( i = 0; i < M; i++ )
430 : {
431 196352 : snsmid_q0_fx[i] = sns_q_fx[i];
432 196352 : move32();
433 : }
434 12272 : nbits = sns_2st_cod_fx( snsmid_fx, exp_snsmid, snsmid_q0_fx, 31 - Q16, indxt );
435 :
436 12272 : IF( LT_16( nbits, nbt ) )
437 : {
438 7839 : nbt = nbits;
439 7839 : move16();
440 7839 : nit = add( 2, add( indxt[0], indxt[1] ) );
441 7839 : index[-1] = 1;
442 7839 : move16();
443 :
444 133263 : FOR( i = 0; i < M; i++ )
445 : {
446 125424 : snsmid_q_fx[i] = snsmid_q0_fx[i];
447 125424 : move32();
448 : }
449 :
450 67312 : FOR( i = 0; i < nit; i++ )
451 : {
452 59473 : index[i] = indxt[i];
453 59473 : move16();
454 : }
455 : }
456 : }
457 12407 : index += nit;
458 : }
459 75611 : return;
460 : }
461 :
462 : /*-------------------------------------------------------------------
463 : * sns_avq_cod_stereo()
464 : *
465 : * Stereo noise-shaping AVQ encoder for 2 channels
466 : *-------------------------------------------------------------------*/
467 :
468 233392 : 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 233392 : Word16 exp_ener_side = 0, exp_side_buffer[M] = { 0 }, exp_side = MIN16B;
483 233392 : move16();
484 233392 : move16();
485 233392 : move16();
486 :
487 : /* Compute side */
488 233392 : ener_side_fx = 0;
489 233392 : move16();
490 3967664 : FOR( i = 0; i < M; i++ )
491 : {
492 3734272 : side_fx[i] = BASOP_Util_Add_Mant32Exp( snsl_fx[i], exp_snl, L_negate( snsr_fx[i] ), exp_snr, &exp_side_buffer[i] );
493 3734272 : move32();
494 3734272 : Word32 tmp = Mpy_32_32( side_fx[i], side_fx[i] ); // exp_side[i] * 2
495 3734272 : 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 3967664 : FOR( i = 0; i < M; i++ )
498 : {
499 3734272 : exp_side = s_max( exp_side, exp_side_buffer[i] );
500 : }
501 3967664 : FOR( i = 0; i < M; i++ )
502 : {
503 3734272 : side_fx[i] = L_shr( side_fx[i], exp_side - exp_side_buffer[i] );
504 3734272 : move32();
505 : }
506 :
507 233392 : Word16 flag = BASOP_Util_Cmp_Mant32Exp( ener_side_fx, exp_ener_side, 24576, 31 - Q11 );
508 233392 : IF( EQ_16( flag, -1 ) )
509 : {
510 : /* MS coding */
511 187578 : *indexl++ = 2;
512 187578 : move16();
513 187578 : *indexr++ = 3;
514 187578 : move16();
515 :
516 : /* Compute mid */
517 187578 : Word16 exp_mid_buffer[M] = { 0 };
518 187578 : move16();
519 3188826 : FOR( i = 0; i < M; i++ )
520 : {
521 3001248 : mid_fx[i] = BASOP_Util_Add_Mant32Exp( snsl_fx[i], exp_snl, snsr_fx[i], exp_snr, &exp_mid_buffer[i] );
522 3001248 : move32();
523 3001248 : mid_fx[i] = L_shr( mid_fx[i], 1 );
524 3001248 : move32();
525 : }
526 :
527 : /* Quantize mid */
528 187578 : Word16 exp_mid = 0;
529 187578 : move16();
530 3188826 : FOR( i = 0; i < M; i++ )
531 : {
532 3001248 : exp_mid = s_max( exp_mid, exp_mid_buffer[i] );
533 : }
534 3188826 : FOR( i = 0; i < M; i++ )
535 : {
536 3001248 : mid_fx[i] = L_shr( mid_fx[i], exp_mid - exp_mid_buffer[i] );
537 3001248 : move32();
538 : }
539 187578 : indexl[0] = sns_1st_cod_fx( mid_fx, exp_mid, L_frame, TCX_20_CORE, mid_q_fx );
540 187578 : move16();
541 187578 : sns_2st_cod_fx( mid_fx, exp_mid, mid_q_fx, ( 31 - Q16 ), &indexl[1] );
542 :
543 : /* Quantize side */
544 187578 : indexr[0] = -1;
545 187578 : move16();
546 3188826 : FOR( i = 0; i < M; i++ )
547 : {
548 3001248 : side_q_fx[i] = 0;
549 3001248 : move32();
550 : }
551 187578 : sns_2st_cod_fx( side_fx, exp_side, side_q_fx, 31 - Q16, &indexr[1] );
552 :
553 : /* Detect zero side */
554 187578 : flag_zero = 1;
555 187578 : move16();
556 628825 : FOR( i = 0; i < M; i++ )
557 : {
558 608476 : if ( side_q_fx[i] != 0 )
559 : {
560 167229 : flag_zero = 0;
561 167229 : move16();
562 167229 : break;
563 : }
564 : }
565 187578 : if ( flag_zero )
566 : {
567 20349 : indexr[0] = -2;
568 20349 : move16();
569 : }
570 :
571 : /* Go back to LR */
572 3188826 : FOR( i = 0; i < M; i++ )
573 : {
574 3001248 : Word32 a = L_shr( side_q_fx[i], 1 );
575 3001248 : snsl_q_fx[i] = L_add( mid_q_fx[i], a );
576 3001248 : move32();
577 3001248 : snsr_q_fx[i] = L_sub( mid_q_fx[i], a );
578 3001248 : move32();
579 : }
580 : }
581 : ELSE
582 : {
583 : /* LR coding */
584 45814 : *indexl++ = 0;
585 45814 : move16();
586 45814 : *indexr++ = 1;
587 45814 : move16();
588 :
589 : /* Quantize left */
590 45814 : indexl[0] = sns_1st_cod_fx( snsl_fx, exp_snl, L_frame, TCX_20_CORE, snsl_q_fx );
591 45814 : move16();
592 45814 : sns_2st_cod_fx( snsl_fx, exp_snl, snsl_q_fx, ( 31 - Q16 ), &indexl[1] );
593 :
594 : /* Quantize right */
595 45814 : indexr[0] = sns_1st_cod_fx( snsr_fx, exp_snr, L_frame, TCX_20_CORE, snsr_q_fx );
596 45814 : move16();
597 45814 : sns_2st_cod_fx( snsr_fx, exp_snr, snsr_q_fx, ( 31 - Q16 ), &indexr[1] );
598 : }
599 233392 : return;
600 : }
601 49211 : 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 49211 : 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 49211 : nbits = 0;
618 49211 : move16();
619 49211 : idxIndices = 0;
620 49211 : move16();
621 49211 : set16_fx( weights_fx, ONE_IN_Q8, M );
622 :
623 49211 : sns_stereo_mode[0] = SNS_STEREO_MODE_LR;
624 49211 : move16();
625 49211 : sns_stereo_mode[1] = SNS_STEREO_MODE_LR;
626 49211 : move16();
627 49211 : zero_side_flag[0] = 0;
628 49211 : move16();
629 49211 : zero_side_flag[1] = 0;
630 49211 : move16();
631 :
632 : /* use snsQ_out as buffer, move input vectors */
633 147633 : FOR( ch = 0; ch < CPE_CHANNELS; ++ch )
634 : {
635 98422 : IF( EQ_16( sts[ch]->core, TCX_20_CORE ) )
636 : {
637 96041 : nSubframes = 1;
638 : }
639 : ELSE
640 : {
641 2381 : nSubframes = NB_DIV;
642 : }
643 98422 : move16();
644 :
645 199225 : FOR( k = 0; k < nSubframes; ++k )
646 : {
647 100803 : Copy32( sns_in_fx[ch][k], snsQ_out_fx[ch][k], M ); // sns_e
648 : }
649 :
650 98422 : sns_e_tmp[ch][0] = sns_e;
651 98422 : move16();
652 98422 : sns_e_tmp[ch][1] = sns_e;
653 98422 : move16();
654 : }
655 :
656 : /* stereo mode decision */
657 49211 : IF( EQ_16( sts[0]->core, sts[1]->core ) )
658 : {
659 48866 : IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
660 : {
661 47848 : nSubframes = 1;
662 : }
663 : ELSE
664 : {
665 1018 : nSubframes = NB_DIV;
666 : }
667 48866 : move16();
668 :
669 98750 : FOR( k = 0; k < nSubframes; ++k )
670 : {
671 : Word32 side_fx[M];
672 : Word32 ener_side_fx;
673 : Word16 ener_side_q;
674 :
675 49884 : v_sub_fixed_no_hdrm( snsQ_out_fx[0][k], snsQ_out_fx[1][k], side_fx, M );
676 :
677 : Word64 L64_sum;
678 49884 : L64_sum = 1;
679 49884 : move64();
680 848028 : FOR( i = 0; i < M; i++ )
681 : {
682 798144 : L64_sum = W_mac_32_32( L64_sum, side_fx[i], side_fx[i] );
683 : }
684 49884 : i = W_norm( L64_sum );
685 49884 : L64_sum = W_shl( L64_sum, i );
686 49884 : ener_side_fx = W_extract_h( L64_sum ); // ener_side_q
687 49884 : ener_side_q = sub( add( shl( sub( 31, sns_e ), 1 ), add( 1, i ) ), 32 );
688 :
689 49884 : sns_stereo_mode[k] = 0;
690 49884 : move16();
691 49884 : zero_side_flag[k] = 0;
692 49884 : move16();
693 :
694 49884 : 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 46563 : sns_stereo_mode[k] = 1;
697 46563 : move16();
698 : }
699 :
700 49884 : 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 9606 : zero_side_flag[k] = 1;
703 9606 : move16();
704 : }
705 :
706 :
707 49884 : IF( EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS ) )
708 : {
709 46563 : convertToMS_fx( M, snsQ_out_fx[0][k], snsQ_out_fx[1][k], ONE_IN_Q30 );
710 : }
711 : }
712 : }
713 :
714 : /* run MSVQ */
715 147633 : FOR( ch = 0; ch < CPE_CHANNELS; ++ch )
716 : {
717 98422 : st = sts[ch];
718 98422 : IF( EQ_16( st->core, TCX_20_CORE ) )
719 : {
720 96041 : nSubframes = 1;
721 : }
722 : ELSE
723 : {
724 2381 : nSubframes = NB_DIV;
725 : }
726 98422 : move16();
727 :
728 199225 : FOR( k = 0; k < nSubframes; ++k )
729 : {
730 100803 : Word16 is_side = 0;
731 100803 : move16();
732 100803 : IF( EQ_16( ch, 1 ) && EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS ) )
733 : {
734 46563 : is_side = 1;
735 46563 : move16();
736 : }
737 :
738 : const Word16 *const *cdbks_fx;
739 : const Word16 *levels;
740 : const Word16 *bits;
741 : Word16 nStages;
742 100803 : IF( EQ_16( nSubframes, 1 ) )
743 : {
744 96041 : cdbks_fx = ivas_sns_cdbks_tcx20_fx;
745 96041 : levels = ivas_sns_cdbks_tcx20_levels;
746 96041 : bits = ivas_sns_cdbks_tcx20_bits;
747 96041 : nStages = SNS_MSVQ_NSTAGES_TCX20;
748 : }
749 : ELSE
750 : {
751 4762 : cdbks_fx = ivas_sns_cdbks_tcx10_fx;
752 4762 : levels = ivas_sns_cdbks_tcx10_levels;
753 4762 : bits = ivas_sns_cdbks_tcx10_bits;
754 4762 : nStages = SNS_MSVQ_NSTAGES_TCX10;
755 : }
756 100803 : move16();
757 :
758 100803 : Word32 *snsQ_fx = snsQ_out_fx[ch][k];
759 100803 : const Word32 *sns_ptr_fx = snsQ_out_fx[ch][k];
760 :
761 100803 : IF( is_side )
762 : {
763 : const Word16 *const *side_cdbks_fx;
764 : const Word16 *side_levels;
765 :
766 46563 : IF( EQ_16( st->core, TCX_20_CORE ) )
767 : {
768 44709 : side_cdbks_fx = ivas_sns_cdbks_side_tcx20_fx;
769 44709 : side_levels = ivas_sns_cdbks_side_tcx20_levels;
770 44709 : bits = ivas_sns_cdbks_side_tcx20_bits;
771 : }
772 : ELSE
773 : {
774 1854 : side_cdbks_fx = ivas_sns_cdbks_side_tcx10_fx;
775 1854 : side_levels = ivas_sns_cdbks_side_tcx10_levels;
776 1854 : bits = ivas_sns_cdbks_side_tcx10_bits;
777 : }
778 :
779 :
780 46563 : IF( zero_side_flag[k] )
781 : {
782 9606 : set32_fx( snsQ_fx, 0, M );
783 9606 : CONTINUE;
784 : }
785 :
786 36957 : nStages = SNS_MSVQ_NSTAGES_SIDE;
787 36957 : move16();
788 :
789 36957 : 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 36957 : msvq_dec_fx( side_cdbks_fx, NULL, NULL, nStages, M, M, &indices[idxIndices], 0, NULL, snsQ_fx, NULL, Q15 );
791 : }
792 : ELSE
793 : {
794 54240 : 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 54240 : msvq_dec_fx( cdbks_fx, NULL, NULL, nStages, M, M, &indices[idxIndices], 0, NULL, snsQ_fx, NULL, Q12 );
796 : }
797 91197 : Word16 shift = find_guarded_bits_fx( M );
798 91197 : sns_e_tmp[ch][k] = sub( 31, sub( 20, shift ) );
799 91197 : move16();
800 91197 : idxIndices = add( idxIndices, nStages );
801 :
802 379163 : FOR( i = 0; i < nStages; ++i )
803 : {
804 287966 : nbits = add( nbits, bits[i] );
805 : }
806 : }
807 : }
808 : /* Re-Scaling Buffers*/
809 49211 : sns_e = sns_e_tmp[0][0];
810 49211 : move16();
811 :
812 147633 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
813 : {
814 98422 : sns_e = s_max( sns_e, sns_e_tmp[ch][0] );
815 98422 : sns_e = s_max( sns_e, sns_e_tmp[ch][1] );
816 : }
817 :
818 147633 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
819 : {
820 199226 : FOR( k = 0; k < nSubframes; k++ )
821 : {
822 100804 : 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 49211 : test();
827 49211 : IF( EQ_16( sns_stereo_mode[0], SNS_STEREO_MODE_MS ) || EQ_16( sns_stereo_mode[1], SNS_STEREO_MODE_MS ) )
828 : {
829 45684 : IF( EQ_16( sts[0]->core, TCX_20_CORE ) )
830 : {
831 44709 : nSubframes = 1;
832 : }
833 : ELSE
834 : {
835 975 : nSubframes = NB_DIV;
836 : }
837 45684 : move16();
838 :
839 92343 : FOR( k = 0; k < nSubframes; ++k )
840 : {
841 46659 : IF( EQ_16( sns_stereo_mode[k], SNS_STEREO_MODE_MS ) )
842 : {
843 46563 : convertToMS_fx( M, snsQ_out_fx[0][k], snsQ_out_fx[1][k], ONE_IN_Q31 );
844 : }
845 : }
846 : }
847 :
848 49211 : return nbits;
849 : }
|