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