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 "prot_fx.h"
38 : #include "ivas_cnst.h"
39 : #include "ivas_rom_com.h"
40 : #include "ivas_stat_dec.h"
41 : #include "wmc_auto.h"
42 : #include "ivas_rom_com_fx.h"
43 : #include "ivas_prot_fx.h"
44 :
45 :
46 : /*---------------------------------------------------------------
47 : * Local constants
48 : *---------------------------------------------------------------*/
49 :
50 : #define MASA_EXTRA_BAND_META_BITS 40
51 :
52 : #define MASA_SMALL_INC_META_BITS 10
53 :
54 :
55 : /*---------------------------------------------------------------
56 : * Local prototypes
57 : *---------------------------------------------------------------*/
58 :
59 : static Word16 quantize_theta_masa_fx(
60 : const Word32 x_fx, /* i : theta value to be quantized Q22*/
61 : const Word16 no_cb, /* i : number of codewords */
62 : Word32 *xhat_fx /* o : quantized value Q22*/
63 : );
64 :
65 : static Word16 quantize_phi_masa_fx(
66 : const Word32 phi_fx, /* i : azimuth value Q22 */
67 : const Word16 flag_delta, /* i : flag indicating if the azimuth codebook is translated or not */
68 : Word32 *phi_hat_fx, /* o : quantized azimuth Q22 */
69 : const Word16 n /* i : azimuth codebook size */
70 : );
71 :
72 : static Word32 estim_round[MASA_NO_CIRCLES + 1] = {
73 : /* Q0 */
74 : -423,
75 : 0,
76 : 422,
77 : 845,
78 : 1267,
79 : 1689,
80 : 2111,
81 : 2532,
82 : 2953,
83 : 3373,
84 : 3793,
85 : 4212,
86 : 4630,
87 : 5047,
88 : 5464,
89 : 5880,
90 : 6294,
91 : 6708,
92 : 7120,
93 : 7532,
94 : 7941,
95 : 8350,
96 : 8757,
97 : 9163,
98 : 9567,
99 : 9969,
100 : 10370,
101 : 10769,
102 : 11166,
103 : 11561,
104 : 11955,
105 : 12346,
106 : 12735,
107 : 13122,
108 : 13507,
109 : 13890,
110 : 14270,
111 : 14648,
112 : 15023,
113 : 15396,
114 : 15766,
115 : 16134,
116 : 16499,
117 : 16861,
118 : 17220,
119 : 17576,
120 : 17930,
121 : 18280,
122 : 18627,
123 : 18971,
124 : 19312,
125 : 19650,
126 : 19984,
127 : 20315,
128 : 20643,
129 : 20967,
130 : 21288,
131 : 21605,
132 : 21918,
133 : 22228,
134 : 22534,
135 : 22836,
136 : 23135,
137 : 23429,
138 : 23720,
139 : 24007,
140 : 24289,
141 : 24568,
142 : 24842,
143 : 25112,
144 : 25378,
145 : 25640,
146 : 25898,
147 : 26151,
148 : 26400,
149 : 26644,
150 : 26884,
151 : 27119,
152 : 27350,
153 : 27576,
154 : 27798,
155 : 28015,
156 : 28227,
157 : 28435,
158 : 28637,
159 : 28835,
160 : 29029,
161 : 29217,
162 : 29400,
163 : 29579,
164 : 29752,
165 : 29921,
166 : 30084,
167 : 30243,
168 : 30396,
169 : 30544,
170 : 30688,
171 : 30826,
172 : 30959,
173 : 31086,
174 : 31209,
175 : 31326,
176 : 31438,
177 : 31545,
178 : 31647,
179 : 31743,
180 : 31834,
181 : 31919,
182 : 32000,
183 : 32075,
184 : 32144,
185 : 32208,
186 : 32267,
187 : 32320,
188 : 32368,
189 : 32411,
190 : 32448,
191 : 32480,
192 : 32506,
193 : 32527,
194 : 32542,
195 : 32552
196 : };
197 :
198 : static Word32 estim_ceil[MASA_NO_CIRCLES + 1] = {
199 : /* Q0 */
200 : -422,
201 : 0,
202 : 423,
203 : 845,
204 : 1268,
205 : 1690,
206 : 2111,
207 : 2532,
208 : 2953,
209 : 3374,
210 : 3793,
211 : 4212,
212 : 4630,
213 : 5048,
214 : 5465,
215 : 5880,
216 : 6295,
217 : 6708,
218 : 7121,
219 : 7532,
220 : 7942,
221 : 8350,
222 : 8758,
223 : 9163,
224 : 9567,
225 : 9970,
226 : 10371,
227 : 10770,
228 : 11167,
229 : 11562,
230 : 11955,
231 : 12347,
232 : 12736,
233 : 13123,
234 : 13508,
235 : 13890,
236 : 14270,
237 : 14648,
238 : 15024,
239 : 15396,
240 : 15767,
241 : 16134,
242 : 16499,
243 : 16861,
244 : 17220,
245 : 17577,
246 : 17930,
247 : 18280,
248 : 18628,
249 : 18972,
250 : 19313,
251 : 19650,
252 : 19985,
253 : 20316,
254 : 20644,
255 : 20968,
256 : 21288,
257 : 21605,
258 : 21919,
259 : 22229,
260 : 22535,
261 : 22837,
262 : 23135,
263 : 23430,
264 : 23720,
265 : 24007,
266 : 24290,
267 : 24568,
268 : 24843,
269 : 25113,
270 : 25379,
271 : 25641,
272 : 25898,
273 : 26151,
274 : 26400,
275 : 26644,
276 : 26884,
277 : 27120,
278 : 27350,
279 : 27577,
280 : 27798,
281 : 28015,
282 : 28228,
283 : 28435,
284 : 28638,
285 : 28836,
286 : 29029,
287 : 29217,
288 : 29401,
289 : 29579,
290 : 29753,
291 : 29921,
292 : 30085,
293 : 30243,
294 : 30397,
295 : 30545,
296 : 30688,
297 : 30826,
298 : 30959,
299 : 31087,
300 : 31210,
301 : 31327,
302 : 31439,
303 : 31546,
304 : 31647,
305 : 31743,
306 : 31834,
307 : 31920,
308 : 32000,
309 : 32075,
310 : 32145,
311 : 32209,
312 : 32268,
313 : 32321,
314 : 32369,
315 : 32411,
316 : 32449,
317 : 32480,
318 : 32506,
319 : 32527,
320 : 32543,
321 : 32552
322 : };
323 :
324 :
325 : /*---------------------------------------------------------------
326 : * ivas_masa_setup()
327 : *
328 : * Set-up MASA coding elements and bitrates
329 : *---------------------------------------------------------------*/
330 :
331 91345 : void ivas_masa_set_elements_fx(
332 : const Word32 ivas_total_brate, /* i : IVAS total bitrate */
333 : const Word16 mc_mode, /* i : MC format mode */
334 : const Word16 nchan_transport, /* i : number of MASA input/transport channels */
335 : IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */
336 : Word16 *element_mode, /* o : element mode */
337 : Word16 *nSCE, /* o : number of SCEs */
338 : Word16 *nCPE, /* o : number of CPEs */
339 : const Word16 ivas_format, /* i : IVAS format */
340 : const ISM_MODE ism_mode, /* i : ISM mode */
341 : const Word32 ism_total_brate /* i : initial ISM total bitrate */
342 : )
343 : {
344 : Word16 tmp;
345 :
346 91345 : IF( EQ_16( nchan_transport, 2 ) )
347 : {
348 53380 : test();
349 53380 : test();
350 53380 : IF( GE_32( ivas_total_brate, MCMASA_SEPARATE_BRATE ) && EQ_16( mc_mode, MC_MODE_MCMASA ) )
351 : {
352 610 : *nCPE = 1;
353 610 : move16();
354 610 : *nSCE = 1;
355 610 : move16();
356 :
357 610 : *element_mode = IVAS_SCE; /* This is needed for the initialization phase to initialize codec mode to SCE, since it is written first to the file*/
358 610 : move16();
359 : }
360 52770 : ELSE IF( EQ_16( ivas_format, MASA_ISM_FORMAT ) && ism_mode != ISM_MODE_NONE )
361 : {
362 14504 : *nCPE = 1;
363 14504 : move16();
364 :
365 14504 : if ( EQ_16( *element_mode, -1 ) )
366 : {
367 6311 : *element_mode = IVAS_CPE_DFT; /* To have it initialized in case it was not already. */
368 6311 : move16();
369 : }
370 14504 : IF( GT_32( ivas_total_brate, MIN_BRATE_MDCT_STEREO ) )
371 : {
372 9559 : *element_mode = IVAS_CPE_MDCT;
373 9559 : move16();
374 9559 : test();
375 9559 : test();
376 9559 : test();
377 9559 : if ( ( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) || EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) ) && LT_32( L_sub( ivas_total_brate, ism_total_brate ), MIN_BRATE_MDCT_STEREO ) )
378 : {
379 1081 : *element_mode = IVAS_CPE_DFT;
380 1081 : move16();
381 : }
382 : }
383 : }
384 : ELSE
385 : {
386 38266 : *nCPE = 1;
387 38266 : move16();
388 38266 : *nSCE = 0;
389 38266 : move16();
390 :
391 38266 : if ( GT_32( ivas_total_brate, MIN_BRATE_MDCT_STEREO ) )
392 : {
393 17878 : *element_mode = IVAS_CPE_MDCT;
394 17878 : move16();
395 : }
396 : }
397 : /* hQMetaData->bits_frame_nominal = (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ); */
398 53380 : hQMetaData->bits_frame_nominal = extract_l( Mpy_32_32( ivas_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
399 53380 : test();
400 53380 : test();
401 53380 : test();
402 53380 : if ( EQ_16( ivas_format, MASA_ISM_FORMAT ) && ( EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) || EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_16( ism_mode, ISM_MASA_MODE_DISC ) ) )
403 : {
404 : /* hQMetaData->bits_frame_nominal -= (int16_t) ( ism_total_brate / FRAMES_PER_SEC ); */
405 14504 : tmp = extract_l( Mpy_32_32( ism_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
406 14504 : hQMetaData->bits_frame_nominal = sub( hQMetaData->bits_frame_nominal, tmp );
407 : }
408 : }
409 37965 : ELSE IF( GE_16( nchan_transport, 1 ) )
410 : {
411 37965 : *nCPE = 0;
412 37965 : move16();
413 37965 : *nSCE = 1;
414 37965 : move16();
415 :
416 37965 : IF( EQ_32( ivas_total_brate, IVAS_13k2 ) )
417 : {
418 7415 : hQMetaData->bits_frame_nominal = ACELP_9k60 / FRAMES_PER_SEC;
419 7415 : move16();
420 : }
421 30550 : ELSE IF( LE_32( ivas_total_brate, IVAS_16k4 ) )
422 : {
423 2463 : hQMetaData->bits_frame_nominal = ACELP_13k20 / FRAMES_PER_SEC;
424 2463 : move16();
425 : }
426 28087 : ELSE IF( LE_32( ivas_total_brate, IVAS_24k4 ) )
427 : {
428 11397 : hQMetaData->bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC;
429 11397 : move16();
430 : }
431 16690 : ELSE IF( LE_32( ivas_total_brate, IVAS_32k ) )
432 : {
433 3388 : hQMetaData->bits_frame_nominal = ACELP_24k40 / FRAMES_PER_SEC;
434 3388 : move16();
435 : }
436 : ELSE
437 : {
438 13302 : hQMetaData->bits_frame_nominal = extract_l( Mpy_32_32( ivas_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
439 : }
440 37965 : *element_mode = IVAS_SCE;
441 37965 : move16();
442 : }
443 : ELSE
444 : {
445 0 : assert( !"MASA number of transport channels must be 1, or 2" );
446 : }
447 :
448 91345 : return;
449 : }
450 :
451 :
452 : /*---------------------------------------------------------------
453 : * generate_gridEq()
454 : *
455 : * generate Spherical grid
456 : *---------------------------------------------------------------*/
457 :
458 613 : void generate_gridEq_fx(
459 : SPHERICAL_GRID_DATA *data /* o : data structure for grid */
460 : )
461 : {
462 : /***************************************************************/
463 : /* NOTE: created LUT from float code. The lookup table depends */
464 : /* on the following macros: */
465 : /* - MASA_NO_CIRCLES */
466 : /* - MASA_NO_POINTS_EQUATOR */
467 : /* - MASA_ANGLE_AT_EQUATOR */
468 : /* - MASA_NTOT2_FAC */
469 : /* - MASA_ASIN_OFFSET */
470 : /***************************************************************/
471 :
472 613 : Copy( gridEq_Table, data->no_phi, NO_THETA16_MAX );
473 :
474 613 : data->no_theta = NO_THETA16_MAX;
475 613 : move16();
476 :
477 613 : return;
478 : }
479 :
480 :
481 : /*---------------------------------------------------------------
482 : * ivas_masa_set_coding_config()
483 : *
484 : * Sets MASA codec parameters based on bitrate, number of directions,
485 : * and other metadata properties.
486 : *---------------------------------------------------------------*/
487 :
488 86559 : void ivas_masa_set_coding_config_fx(
489 : MASA_CODEC_CONFIG *config, /* i/o: MASA coding config structure */
490 : Word16 *band_mapping, /* o : Band mapping used */
491 : const Word32 ivas_total_brate, /* i : IVAS total bitrate */
492 : const Word16 nchan_transport, /* i : number of transport channels (mono/stereo) */
493 : const UWord8 isMcMasa /* i : toggle for selecting mcMASA specific config */
494 : )
495 : {
496 : Word16 i;
497 : UWord8 nbands;
498 : UWord8 nTwoDirBands;
499 : const Word16 *masa_bits_table;
500 :
501 : /* When coming into this function, these values should be already set:
502 : * joinedSubframes;
503 : * useCoherence;
504 : * numberOfDirections;
505 : */
506 :
507 : /* Setup coding parameters based on the bitrate, transport channel count, subframe metadata information,
508 : * and number of directions in metadata. */
509 86559 : nbands = 0;
510 86559 : move16();
511 86559 : nTwoDirBands = 0;
512 86559 : move16();
513 86559 : i = 0;
514 86559 : move16();
515 :
516 : /* First select correct bit budget table */
517 86559 : masa_bits_table = masa_bits;
518 :
519 86559 : test();
520 86559 : IF( isMcMasa )
521 : {
522 10316 : masa_bits_table = mcmasa_bits;
523 : }
524 76243 : ELSE IF( LT_32( ivas_total_brate, IVAS_48k ) && EQ_16( nchan_transport, 2 ) )
525 : {
526 23101 : masa_bits_table = masa_bits_LR_stereo;
527 : }
528 :
529 551624 : WHILE( nbands == 0 && LT_16( i, IVAS_NUM_ACTIVE_BRATES ) )
530 : {
531 465065 : test();
532 465065 : IF( LE_32( ivas_total_brate, ivas_brate_tbl[i + SIZE_IVAS_BRATE_TBL - IVAS_NUM_ACTIVE_BRATES] ) )
533 : {
534 : Word16 idx_bands;
535 :
536 86559 : test();
537 86559 : test();
538 86559 : if ( LT_32( ivas_total_brate, IVAS_48k ) && EQ_16( nchan_transport, 2 ) && GT_16( i, 3 ) )
539 : {
540 : /* because it uses the bitallocation for the lower bit rates from 'masa_bits_LR_stereo' and it has 4 elements */
541 744 : i = 3;
542 744 : move16();
543 : }
544 86559 : idx_bands = i;
545 86559 : move16();
546 :
547 86559 : IF( GT_16( config->numberOfDirections, 1 ) )
548 : {
549 15153 : IF( config->joinedSubframes )
550 : {
551 2778 : nTwoDirBands = masa_twodir_bands_joined[i];
552 2778 : move16();
553 : }
554 : ELSE
555 : {
556 12375 : nTwoDirBands = masa_twodir_bands[i];
557 12375 : move16();
558 : }
559 :
560 15153 : test();
561 15153 : test();
562 15153 : test();
563 15153 : if ( ( GT_32( ivas_total_brate, IVAS_96k ) && !config->joinedSubframes ) || ( GT_32( ivas_total_brate, IVAS_80k ) && config->joinedSubframes ) )
564 : {
565 7597 : idx_bands = sub( idx_bands, 1 );
566 : }
567 : }
568 :
569 86559 : IF( config->joinedSubframes )
570 : {
571 11030 : nbands = masa_joined_nbands[idx_bands];
572 11030 : move16();
573 : }
574 : ELSE
575 : {
576 75529 : nbands = masa_nbands[idx_bands];
577 75529 : move16();
578 : }
579 :
580 86559 : config->max_metadata_bits = (UWord16) masa_bits_table[i];
581 86559 : move16();
582 :
583 86559 : test();
584 86559 : if ( EQ_32( ivas_total_brate, IVAS_64k ) && GT_16( config->numberOfDirections, 1 ) )
585 : {
586 : /* At 64k, we increase metadata bit budget when there is two directions present. */
587 1076 : config->max_metadata_bits = (UWord16) add( config->max_metadata_bits, MASA_EXTRA_BAND_META_BITS );
588 1076 : move16();
589 : }
590 :
591 86559 : test();
592 86559 : test();
593 86559 : test();
594 86559 : if ( ( ( EQ_32( ivas_total_brate, IVAS_32k ) && EQ_16( nchan_transport, 2 ) ) || EQ_32( ivas_total_brate, IVAS_48k ) ) && config->joinedSubframes )
595 : {
596 : /* At 32k and 48k, we increase metadata bit budget when joinedSubframes. */
597 2250 : config->max_metadata_bits = (UWord16) add( config->max_metadata_bits, MASA_SMALL_INC_META_BITS );
598 2250 : move16();
599 : }
600 : }
601 465065 : i = add( i, 1 );
602 : }
603 86559 : config->numCodingBands = nbands;
604 86559 : move16();
605 86559 : config->numTwoDirBands = nTwoDirBands;
606 86559 : move16();
607 :
608 86559 : IF( EQ_16( config->joinedSubframes, TRUE ) )
609 : {
610 11030 : config->mergeRatiosOverSubframes = FALSE;
611 11030 : move16();
612 : }
613 : ELSE
614 : {
615 75529 : config->mergeRatiosOverSubframes = TRUE;
616 75529 : move16();
617 : }
618 :
619 : /* Setup frequency band mapping based on the number of used coding bands */
620 86559 : SWITCH( config->numCodingBands )
621 : {
622 64382 : case 5:
623 64382 : Copy( MASA_band_mapping_24_to_5, band_mapping, 5 + 1 );
624 64382 : BREAK;
625 6864 : case 8:
626 6864 : Copy( MASA_band_mapping_24_to_8, band_mapping, 8 + 1 );
627 6864 : BREAK;
628 4002 : case 12:
629 4002 : Copy( MASA_band_mapping_24_to_12, band_mapping, 12 + 1 );
630 4002 : BREAK;
631 4377 : case 18:
632 4377 : Copy( MASA_band_mapping_24_to_18, band_mapping, 18 + 1 );
633 4377 : BREAK;
634 6934 : case MASA_FREQUENCY_BANDS:
635 : /* With input count of bands, no mapping is needed but for unified processing later, we store normal mapping */
636 180284 : FOR( i = 0; i < MASA_FREQUENCY_BANDS + 1; i++ )
637 : {
638 173350 : band_mapping[i] = i;
639 173350 : move16();
640 : }
641 6934 : BREAK;
642 0 : default:
643 0 : assert( 0 && "Error: The number of MASA coding bands is not supported" );
644 : }
645 :
646 86559 : config->useCoherence = TRUE;
647 86559 : move16();
648 86559 : test();
649 86559 : test();
650 86559 : test();
651 86559 : if ( ( !isMcMasa && LT_32( ivas_total_brate, IVAS_48k ) ) || ( isMcMasa && LT_32( ivas_total_brate, IVAS_16k4 ) ) )
652 : {
653 38712 : config->useCoherence = FALSE;
654 38712 : move16();
655 : }
656 :
657 86559 : return;
658 : }
659 :
660 :
661 : /*---------------------------------------------------------------
662 : * masa_sample_rate_band_correction()
663 : *
664 : *
665 : *---------------------------------------------------------------*/
666 :
667 86559 : void masa_sample_rate_band_correction_fx(
668 : MASA_CODEC_CONFIG *config, /* i/o: MASA codec config */
669 : Word16 *band_mapping, /* i/o: Band mapping used and modified */
670 : IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: QMetadata structure for modification */
671 : const UWord8 maxBand, /* i : max band */
672 : UWord8 is_encoder, /* i : signals if called at encoder */
673 : MASA_DECODER_EXT_OUT_META_HANDLE hExtOutMeta /* i/o: MASA decoder metadata ext out buffer */
674 : )
675 : {
676 : UWord8 band, sf;
677 : Word16 highBand;
678 : UWord8 numBands48k;
679 :
680 86559 : numBands48k = config->numCodingBands;
681 86559 : move16();
682 :
683 666613 : FOR( band = 1; band < config->numCodingBands + 1; band++ )
684 : {
685 666613 : highBand = band_mapping[band];
686 666613 : move16();
687 :
688 666613 : IF( GE_16( highBand, (Word16) maxBand ) )
689 : {
690 86559 : config->numCodingBands = band;
691 86559 : move16();
692 86559 : hQMetaData->numCodingBands = band;
693 86559 : move16();
694 :
695 86559 : IF( is_encoder )
696 : {
697 2276 : if ( GT_16( hQMetaData->q_direction->cfg.nbands, (Word16) band ) )
698 : {
699 300 : hQMetaData->q_direction->cfg.nbands = band;
700 300 : move16();
701 : }
702 2276 : test();
703 2276 : if ( EQ_16( (Word16) hQMetaData->no_directions, 2 ) && GT_16( hQMetaData->q_direction[1].cfg.nbands, (Word16) band ) )
704 : {
705 300 : hQMetaData->q_direction[1].cfg.nbands = band;
706 300 : move16();
707 : }
708 : }
709 :
710 86559 : band_mapping[band] = maxBand;
711 86559 : move16();
712 :
713 86559 : BREAK;
714 : }
715 : }
716 :
717 : /* Set rest of the bands to zero in qmetadata. */
718 89994 : FOR( ; band < numBands48k; band++ )
719 : {
720 17175 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
721 : {
722 13740 : hQMetaData->q_direction[0].band_data[band].azimuth_fx[sf] = 0;
723 13740 : move32();
724 13740 : hQMetaData->q_direction[0].band_data[band].elevation_fx[sf] = 0;
725 13740 : move32();
726 13740 : hQMetaData->q_direction[0].band_data[band].energy_ratio_fx[sf] = 0;
727 13740 : move32();
728 :
729 13740 : test();
730 13740 : if ( hQMetaData->coherence_flag && hQMetaData->q_direction[0].coherence_band_data != NULL )
731 : {
732 13740 : hQMetaData->q_direction[0].coherence_band_data[band].spread_coherence[sf] = 0u;
733 13740 : move16();
734 : }
735 :
736 13740 : IF( EQ_16( (Word16) hQMetaData->no_directions, 2 ) )
737 : {
738 2312 : hQMetaData->q_direction[1].band_data[band].azimuth_fx[sf] = 0;
739 2312 : move32();
740 2312 : hQMetaData->q_direction[1].band_data[band].elevation_fx[sf] = 0;
741 2312 : move32();
742 2312 : hQMetaData->q_direction[1].band_data[band].energy_ratio_fx[sf] = 0;
743 2312 : move32();
744 :
745 2312 : test();
746 2312 : if ( hQMetaData->coherence_flag && hQMetaData->q_direction[1].coherence_band_data != NULL )
747 : {
748 2312 : hQMetaData->q_direction[1].coherence_band_data[band].spread_coherence[sf] = 0u;
749 2312 : move16();
750 : }
751 : }
752 :
753 13740 : test();
754 13740 : if ( hQMetaData->coherence_flag && hQMetaData->surcoh_band_data != NULL )
755 : {
756 13740 : hQMetaData->surcoh_band_data[band].surround_coherence[sf] = 0u;
757 13740 : move16();
758 : }
759 : }
760 :
761 3435 : if ( EQ_16( (Word16) hQMetaData->no_directions, 2 ) )
762 : {
763 578 : hQMetaData->twoDirBands[band] = 0;
764 578 : move16();
765 : }
766 : }
767 :
768 86559 : IF( hExtOutMeta != NULL )
769 : {
770 : /* in decoder, zero the EXT out MASA meta buffer */
771 25685 : FOR( sf = 0; sf < MAX_PARAM_SPATIAL_SUBFRAMES; sf++ )
772 : {
773 337908 : FOR( band = hQMetaData->numCodingBands; band < MASA_FREQUENCY_BANDS; band++ )
774 : {
775 317360 : hExtOutMeta->directionIndex[0][sf][band] = SPH_IDX_FRONT;
776 317360 : move16();
777 317360 : hExtOutMeta->directToTotalRatio[0][sf][band] = 0u;
778 317360 : move16();
779 317360 : hExtOutMeta->spreadCoherence[0][sf][band] = 0u;
780 317360 : move16();
781 :
782 317360 : hExtOutMeta->directionIndex[1][sf][band] = SPH_IDX_FRONT;
783 317360 : move16();
784 317360 : hExtOutMeta->directToTotalRatio[1][sf][band] = 0u;
785 317360 : move16();
786 317360 : hExtOutMeta->spreadCoherence[1][sf][band] = 0u;
787 317360 : move16();
788 :
789 317360 : hExtOutMeta->surroundCoherence[sf][band] = 0u;
790 317360 : move16();
791 317360 : hExtOutMeta->diffuseToTotalRatio[sf][band] = UINT8_MAX;
792 317360 : move16();
793 : }
794 : }
795 : }
796 :
797 86559 : return;
798 : }
799 :
800 :
801 : /*-------------------------------------------------------------------------
802 : * index_theta_phi_16()
803 : *
804 : *
805 : *------------------------------------------------------------------------*/
806 :
807 : /*! r: output index for direction */
808 281894 : UWord16 index_theta_phi_16_fx(
809 : Word32 *p_theta, /* i/o: input elevation to be indexed Q22 */
810 : Word32 *p_phi, /* i/o: input azimuth to be indexed Q22 */
811 : const SPHERICAL_GRID_DATA *gridData /* i : generated grid data */
812 : )
813 : {
814 : Word32 abs_theta_fx;
815 : Word16 sign_th, id_phi, id_th;
816 : UWord16 idx_sph;
817 : UWord16 cum_n;
818 : Word32 theta_hat_fx, phi_hat_fx;
819 : Word32 theta_fx, phi_fx;
820 :
821 281894 : theta_fx = *p_theta; // Q22
822 281894 : move32();
823 281894 : phi_fx = *p_phi; // Q22
824 281894 : move32();
825 281894 : phi_hat_fx = 0;
826 281894 : move32();
827 281894 : theta_hat_fx = 0;
828 281894 : move32();
829 281894 : phi_fx = L_add( phi_fx, L_shl( 180, Q22 ) ); // Q22
830 :
831 281894 : IF( theta_fx < 0 )
832 : {
833 70920 : abs_theta_fx = L_negate( theta_fx ); // Q22
834 70920 : sign_th = -1;
835 70920 : move16();
836 : }
837 : ELSE
838 : {
839 210974 : abs_theta_fx = theta_fx; // Q22
840 210974 : move32();
841 210974 : sign_th = 1;
842 210974 : move16();
843 : }
844 :
845 281894 : id_th = quantize_theta_masa_fx( abs_theta_fx, gridData->no_theta, &theta_hat_fx );
846 281894 : IF( GT_16( gridData->no_theta, 1 ) )
847 : {
848 281894 : IF( GT_16( gridData->no_phi[id_th], 1 ) )
849 : {
850 276590 : id_phi = quantize_phi_masa_fx( phi_fx, (Word16) EQ_16( s_and( id_th, 1 ), 1 ), &phi_hat_fx, gridData->no_phi[id_th] );
851 : }
852 : ELSE
853 : {
854 5304 : id_phi = 0;
855 5304 : move16();
856 5304 : phi_hat_fx = L_shl( 180, Q22 ); // Q22
857 : }
858 : }
859 : ELSE
860 : {
861 0 : id_phi = quantize_phi_masa_fx( phi_fx, (Word16) EQ_16( s_and( id_th, 1 ), 1 ), &phi_hat_fx, gridData->no_phi[id_th] );
862 : }
863 :
864 281894 : *p_theta = theta_hat_fx;
865 281894 : move32();
866 281894 : if ( EQ_16( sign_th, -1 ) )
867 : {
868 70920 : *p_theta = L_negate( theta_hat_fx ); // Q22
869 70920 : move32();
870 : }
871 281894 : *p_phi = L_sub( phi_hat_fx, L_shl( 180, Q22 ) ); // Q22
872 281894 : move32();
873 :
874 : /* Starting from Equator, alternating positive and negative */
875 281894 : IF( id_th == 0 )
876 : {
877 146361 : idx_sph = id_phi;
878 146361 : move16();
879 : }
880 : ELSE
881 : {
882 135533 : IF( EQ_16( id_th, sub( gridData->no_theta, 1 ) ) )
883 : {
884 5304 : idx_sph = 65534; // Q0
885 5304 : move16();
886 5304 : if ( sign_th < 0 )
887 : {
888 2394 : idx_sph = 65535; // Q0
889 2394 : move16();
890 : }
891 : }
892 : ELSE
893 : {
894 130229 : cum_n = cum_n_for_id_th[id_th]; // Q0
895 130229 : move16();
896 :
897 130229 : cum_n = (UWord16) L_add( cum_n, gridData->no_phi[0] ); // Q0
898 :
899 130229 : IF( sign_th > 0 )
900 : {
901 61705 : cum_n = (UWord16) L_sub( cum_n, shl( gridData->no_phi[id_th], 1 ) ); // Q0
902 : }
903 : ELSE
904 : {
905 68524 : cum_n = (UWord16) L_sub( cum_n, gridData->no_phi[id_th] ); // Q0
906 : }
907 130229 : idx_sph = (UWord16) L_add( cum_n, id_phi ); // Q0
908 : }
909 : }
910 :
911 281894 : return idx_sph; // Q0
912 : }
913 :
914 :
915 : /*-------------------------------------------------------------------------
916 : * quantize_theta_masa()
917 : *
918 : *
919 : *------------------------------------------------------------------------*/
920 :
921 : /*! r: output index */
922 281894 : static Word16 quantize_theta_masa_fx(
923 : const Word32 x_fx, /* i : theta value to be quantized Q22*/
924 : const Word16 no_cb, /* i : number of codewords */
925 : Word32 *xhat_fx /* o : quantized value Q22*/
926 : )
927 : {
928 : Word16 imin;
929 : Word32 diff1_fx, diff2_fx;
930 :
931 281894 : imin = extract_l( L_shr( L_add( Mpy_32_32( x_fx, MASA_INV_ANGLE_AT_EQUATOR_DEG_Q30 ), ONE_IN_Q20 ), 21 ) ); // 22 + 30 - 31 = 21 -> Q21 - 21 = Q0
932 :
933 281894 : IF( GE_16( imin, sub( no_cb, 1 ) ) )
934 : {
935 5307 : imin = sub( no_cb, 1 );
936 5307 : diff1_fx = L_sub( x_fx, L_shl( 90, Q22 ) ); // Q22
937 5307 : diff2_fx = L_sub( x_fx, Mpy_32_16_1( MASA_ANGLE_AT_EQUATOR_DEG_Q31, shl( sub( imin, 1 ), 6 ) ) ); // q31 + q0+6 - 15 = q22
938 5307 : IF( GT_32( L_abs( diff1_fx ), L_abs( diff2_fx ) ) )
939 : {
940 3 : imin = sub( imin, 1 );
941 3 : *xhat_fx = Mpy_32_16_1( MASA_ANGLE_AT_EQUATOR_DEG_Q31, shl( imin, 6 ) ); // 31 + 6 - 15 = Q22
942 3 : move32();
943 : }
944 : ELSE
945 : {
946 5304 : *xhat_fx = L_shl( 90, Q22 ); // Q22
947 5304 : move32();
948 : }
949 : }
950 : ELSE
951 : {
952 276587 : *xhat_fx = Mpy_32_16_1( MASA_ANGLE_AT_EQUATOR_DEG_Q31, shl( imin, 6 ) ); // 31 + 6 - 15 = Q22
953 276587 : move32();
954 : }
955 :
956 281894 : return imin;
957 : }
958 :
959 :
960 : /*-------------------------------------------------------------------------
961 : * quantize_phi_masa()
962 : *
963 : *
964 : *------------------------------------------------------------------------*/
965 :
966 : /*! r: index azimuth */
967 276590 : static Word16 quantize_phi_masa_fx(
968 : const Word32 phi_fx, /* i : azimuth value Q22 */
969 : const Word16 flag_delta, /* i : flag indicating if the azimuth codebook is translated or not */
970 : Word32 *phi_hat_fx, /* o : quantized azimuth Q22 */
971 : const Word16 n /* i : azimuth codebook size */
972 : )
973 : {
974 : Word16 id_phi;
975 :
976 : Word32 dd_fx;
977 : Word32 delta_phi_fx;
978 : Word32 tmp32;
979 : Word16 tmp_e, delta_phi_e;
980 :
981 276590 : delta_phi_fx = L_deposit_h( BASOP_Util_Divide1616_Scale( 360, n, &delta_phi_e ) );
982 276590 : delta_phi_fx = L_shr( delta_phi_fx, sub( sub( 31, delta_phi_e ), 22 ) ); // Q22
983 :
984 276590 : IF( EQ_16( n, 1 ) )
985 : {
986 0 : *phi_hat_fx = 0;
987 0 : move32();
988 :
989 0 : return 0;
990 : }
991 :
992 276590 : IF( EQ_16( flag_delta, 1 ) )
993 : {
994 86243 : dd_fx = L_shr( delta_phi_fx, 1 ); // Q22
995 : }
996 : ELSE
997 : {
998 190347 : dd_fx = 0;
999 190347 : move32();
1000 : }
1001 :
1002 276590 : tmp32 = L_add( L_sub( phi_fx, dd_fx ), L_shr( delta_phi_fx, 1 ) );
1003 276590 : id_phi = BASOP_Util_Divide3232_Scale( tmp32, delta_phi_fx, &tmp_e );
1004 276590 : id_phi = shr( id_phi, sub( 15, tmp_e ) ); // Q0
1005 :
1006 276590 : if ( EQ_16( id_phi, n ) )
1007 : {
1008 18 : id_phi = 0;
1009 18 : move16();
1010 : }
1011 :
1012 276590 : if ( EQ_16( id_phi, -1 ) )
1013 : {
1014 1 : id_phi = sub( n, 1 );
1015 : }
1016 :
1017 276590 : *phi_hat_fx = L_add( L_shl( Mpy_32_16_1( delta_phi_fx, id_phi ), 15 ), dd_fx ); // q22 + q0 - 15 = q7 -> q7 + 15 = q22
1018 276590 : move32();
1019 :
1020 276590 : return id_phi; // Q0
1021 : }
1022 :
1023 :
1024 : /*-------------------------------------------------------------------------
1025 : * deindex_sph_idx()
1026 : *
1027 : * deindex the MASA metadata from the input metadata file
1028 : *------------------------------------------------------------------------*/
1029 :
1030 5932128 : void deindex_sph_idx_fx(
1031 : const UWord16 sphIndex, /* i : Spherical index */
1032 : const SPHERICAL_GRID_DATA *gridData, /* i : Prepared spherical grid */
1033 : Word32 *theta_fx, /* o : Elevation Q22*/
1034 : Word32 *phi_fx /* o : Azimuth Q22 */
1035 : )
1036 : {
1037 : Word32 ba_crt_fx, del_crt_fx, div_crt_fx, a4_crt_fx;
1038 : Word32 estim_fx;
1039 : Word32 base_low, base_up;
1040 : Word16 n_crt;
1041 : Word16 id_th;
1042 : Word16 sign_theta;
1043 : Word16 id_phi;
1044 5932128 : Word16 no_th = gridData->no_theta;
1045 5932128 : const Word16 *n = gridData->no_phi;
1046 : const Word32 ba_fx[3] = { 1793476992, 1044259584, 1030463872 }; /* Q23 */
1047 : const Word32 del_fx[3] = { 819022016, 1332105216, 1458249984 }; /* Q10 */
1048 : const Word32 div_fx[3] = { -510376000, -216763104, -197676320 }; /* Q31 */
1049 : const Word32 a4_fx[3] = { -564741248, -1329702144, -1458092544 }; /* Q26 */
1050 5932128 : const UWord16 limit_index1 = 64964, limit_index2 = 47870;
1051 : Word32 tmp32;
1052 : Word16 tmp16, tmp_e;
1053 5932128 : move16();
1054 5932128 : move16();
1055 5932128 : move16();
1056 5932128 : move32();
1057 5932128 : move32();
1058 5932128 : move32();
1059 5932128 : move32();
1060 5932128 : move32();
1061 5932128 : move32();
1062 5932128 : move32();
1063 5932128 : move32();
1064 5932128 : move32();
1065 5932128 : move32();
1066 5932128 : move32();
1067 5932128 : move32();
1068 :
1069 5932128 : IF( GE_32( sphIndex, limit_index1 ) )
1070 : {
1071 15725 : ba_crt_fx = ba_fx[2];
1072 15725 : move32();
1073 15725 : div_crt_fx = div_fx[2];
1074 15725 : move32();
1075 15725 : a4_crt_fx = a4_fx[2];
1076 15725 : move32();
1077 15725 : del_crt_fx = del_fx[2];
1078 15725 : move32();
1079 : }
1080 5916403 : ELSE IF( GE_32( sphIndex, limit_index2 ) )
1081 : {
1082 545325 : ba_crt_fx = ba_fx[1];
1083 545325 : move32();
1084 545325 : div_crt_fx = div_fx[1];
1085 545325 : move32();
1086 545325 : a4_crt_fx = a4_fx[1];
1087 545325 : move32();
1088 545325 : del_crt_fx = del_fx[1];
1089 545325 : move32();
1090 : }
1091 : ELSE
1092 : {
1093 5371078 : ba_crt_fx = ba_fx[0];
1094 5371078 : move32();
1095 5371078 : div_crt_fx = div_fx[0];
1096 5371078 : move32();
1097 5371078 : a4_crt_fx = a4_fx[0];
1098 5371078 : move32();
1099 5371078 : del_crt_fx = del_fx[0];
1100 5371078 : move32();
1101 : }
1102 5932128 : tmp32 = Mpy_32_32( a4_crt_fx, L_shl_sat( sphIndex, Q15 ) ); /* Q10 */
1103 5932128 : tmp32 = L_add( del_crt_fx, tmp32 ); /* Q10 */
1104 5932128 : tmp16 = Q31 - Q10;
1105 5932128 : move16();
1106 5932128 : tmp32 = Sqrt32( tmp32, &tmp16 ); // Q31-tmp16
1107 5932128 : tmp32 = Mpy_32_32( div_crt_fx, tmp32 ); // Q31-tmp16
1108 5932128 : tmp32 = L_shr( tmp32, sub( Q8, tmp16 ) ); /* Q23 */
1109 5932128 : estim_fx = L_add( ba_crt_fx, tmp32 ); /* Q23 */
1110 :
1111 5932128 : if ( GT_32( estim_fx, MASA_NO_CIRCLES_Q23 ) )
1112 : {
1113 640 : estim_fx = MASA_NO_CIRCLES_Q23; // Q23
1114 640 : move32();
1115 : }
1116 :
1117 5932128 : assert( estim_fx > 0 );
1118 5932128 : id_th = sub( extract_l( L_shr_r( estim_fx, Q23 ) ), 1 ); /* Q0 */
1119 5932128 : if ( id_th < 0 )
1120 : {
1121 0 : id_th = 0;
1122 0 : move16();
1123 : }
1124 :
1125 5932128 : IF( id_th == 0 )
1126 : {
1127 69242 : base_low = 0;
1128 69242 : move32();
1129 69242 : base_up = n[0];
1130 69242 : move32();
1131 : }
1132 : ELSE
1133 : {
1134 5862886 : base_low = n[0];
1135 5862886 : move32();
1136 5862886 : IF( GE_16( id_th, 2 ) )
1137 : {
1138 5574260 : IF( EQ_16( id_th, 2 ) )
1139 : {
1140 293745 : base_low = L_add( base_low, L_shl( estim_ceil[id_th], 1 ) ); /* Q0 */
1141 : }
1142 : ELSE
1143 : {
1144 5280515 : base_low = L_add( base_low, L_shl( estim_round[id_th], 1 ) ); /* Q0 */
1145 : }
1146 : }
1147 5862886 : base_up = L_add( base_low, L_shl( n[id_th], 1 ) );
1148 : }
1149 :
1150 5932128 : sign_theta = 1;
1151 5932128 : move16();
1152 :
1153 5932128 : n_crt = n[id_th];
1154 5932128 : move16();
1155 5932128 : IF( LT_32( sphIndex, base_low ) )
1156 : {
1157 299223 : id_th = sub( id_th, 1 );
1158 299223 : n_crt = n[id_th];
1159 299223 : move16();
1160 299223 : IF( id_th == 0 )
1161 : {
1162 74925 : base_low = 0;
1163 74925 : move32();
1164 74925 : base_up = n_crt;
1165 74925 : move32();
1166 : }
1167 : ELSE
1168 : {
1169 224298 : base_up = base_low;
1170 224298 : move32();
1171 224298 : base_low = L_sub( base_low, shl( n[id_th], 1 ) );
1172 : }
1173 299223 : assert( sphIndex >= base_low );
1174 : }
1175 5632905 : ELSE IF( GE_32( sphIndex, base_up ) )
1176 : {
1177 188634 : id_th = add( id_th, 1 );
1178 188634 : n_crt = n[id_th];
1179 188634 : move16();
1180 188634 : base_low = base_up;
1181 188634 : move32();
1182 188634 : base_up = L_add( base_up, shl( n_crt, 1 ) );
1183 188634 : assert( sphIndex < base_up );
1184 : }
1185 :
1186 5932128 : id_phi = extract_l( L_sub( sphIndex, base_low ) );
1187 5932128 : IF( GE_32( L_sub( sphIndex, base_low ), n_crt ) )
1188 : {
1189 3578178 : id_phi = sub( id_phi, n_crt );
1190 3578178 : sign_theta = -1;
1191 3578178 : move16();
1192 : }
1193 :
1194 5932128 : IF( id_th == 0 )
1195 : {
1196 144167 : *theta_fx = 0;
1197 144167 : move32();
1198 144167 : tmp32 = imult3216( sphIndex, 360 );
1199 144167 : tmp16 = BASOP_Util_Divide3232_Scale( tmp32, n_crt, &tmp_e );
1200 144167 : tmp32 = L_shl( tmp16, add( Q7, tmp_e ) ); /* Q22 */
1201 144167 : *phi_fx = L_sub( tmp32, 180 << Q22 ); /* Q22 */
1202 144167 : move32();
1203 : }
1204 : ELSE
1205 : {
1206 5787961 : IF( EQ_16( id_th, sub( no_th, 1 ) ) )
1207 : {
1208 273 : id_phi = 0;
1209 273 : move16();
1210 273 : *phi_fx = -754974720; /* -180 in Q22 */
1211 273 : move32();
1212 273 : *theta_fx = L_shl( L_mult0( 90, sign_theta ), Q22 ); /* Q22 */
1213 273 : move32();
1214 : }
1215 : ELSE
1216 : {
1217 5787688 : *theta_fx = Mpy_32_32( L_shl( id_th, Q22 ), MASA_ANGLE_AT_EQUATOR_DEG_Q31 ); /* Q22 */
1218 5787688 : move32();
1219 5787688 : if ( EQ_16( sign_theta, -1 ) )
1220 : {
1221 3577994 : *theta_fx = L_negate( *theta_fx ); /* Q22 */
1222 3577994 : move32();
1223 : }
1224 5787688 : IF( id_th % 2 == 0 )
1225 : {
1226 2826768 : tmp32 = L_mult0( id_phi, 360 );
1227 2826768 : tmp16 = BASOP_Util_Divide3232_Scale( tmp32, n_crt, &tmp_e );
1228 2826768 : tmp32 = L_shl( tmp16, add( Q7, tmp_e ) ); /* Q22 */
1229 2826768 : *phi_fx = L_sub( tmp32, 180 << Q22 ); /* Q22 */
1230 2826768 : move32();
1231 : }
1232 : ELSE
1233 : {
1234 2960920 : tmp32 = L_add( L_mult0( id_phi, 360 ), 180 );
1235 2960920 : tmp16 = BASOP_Util_Divide3232_Scale( tmp32, n_crt, &tmp_e );
1236 2960920 : tmp32 = L_shl( tmp16, add( Q7, tmp_e ) ); /* Q22 */
1237 2960920 : *phi_fx = L_sub( tmp32, 180 << Q22 ); /* Q22 */
1238 2960920 : move32();
1239 : }
1240 : }
1241 : }
1242 5932128 : return;
1243 : }
1244 : /*---------------------------------------------------------------
1245 : * valid_ratio_index()
1246 : *
1247 : * Checking validity of the index of an ISM ratio index vector,
1248 : * within the indexing function.
1249 : *---------------------------------------------------------------*/
1250 :
1251 : /*! r: valid or not 1/0 */
1252 1681984 : Word16 valid_ratio_index_fx(
1253 : Word16 index, /* i : index to be checked */
1254 : const Word16 K, /* i : L1 norm to check against */
1255 : const Word16 len /* i : vector length */
1256 : )
1257 : {
1258 : Word16 out;
1259 : Word16 i, sum, elem;
1260 : Word16 base[4];
1261 :
1262 1681984 : sum = 0;
1263 1681984 : move16();
1264 1681984 : set16_fx( base, 1, len );
1265 :
1266 5012245 : FOR( i = 1; i < len; i++ )
1267 : {
1268 3330261 : base[i] = i_mult( base[i - 1], 10 );
1269 3330261 : move16();
1270 : }
1271 1681984 : sum = 0;
1272 1681984 : move16();
1273 6694229 : FOR( i = len - 1; i >= 0; i-- )
1274 : {
1275 5012245 : IF( index == 0 )
1276 : {
1277 210520 : elem = 0;
1278 210520 : move16();
1279 : }
1280 : ELSE
1281 : {
1282 4801725 : elem = idiv1616( index, base[i] );
1283 : }
1284 5012245 : sum = add( sum, elem );
1285 5012245 : index = sub( index, i_mult( elem, base[i] ) );
1286 : }
1287 1681984 : IF( LE_16( sum, K ) )
1288 : {
1289 462706 : out = 1;
1290 462706 : move16();
1291 : }
1292 : ELSE
1293 : {
1294 1219278 : out = 0;
1295 1219278 : move16();
1296 : }
1297 :
1298 1681984 : return out;
1299 : }
1300 :
1301 :
1302 : /*---------------------------------------------------------------
1303 : * reconstruct_ism_ratios()
1304 : *
1305 : * Obtains ISM ratio values from the quantized indexes
1306 : *---------------------------------------------------------------*/
1307 :
1308 56548 : void reconstruct_ism_ratios_fx(
1309 : Word16 *ratio_ism_idx, /* i : index vector Q0 */
1310 : const Word16 nchan_ism, /* i : number of components/objects Q0 */
1311 : const Word16 step, /* i : quantization step Q15 */
1312 : Word32 *q_energy_ratio_ism /* o : reconstructed ISM values Q30 */
1313 : )
1314 : {
1315 : Word16 i;
1316 : Word32 sum;
1317 :
1318 56548 : sum = 0;
1319 56548 : move32();
1320 :
1321 197744 : FOR( i = 0; i < nchan_ism - 1; i++ )
1322 : {
1323 141196 : q_energy_ratio_ism[i] = L_shl( L_mult( ratio_ism_idx[i], step ), 14 ); // q0 + q15 + 1 + 14 = q30;
1324 141196 : move32();
1325 :
1326 141196 : sum = L_add( sum, q_energy_ratio_ism[i] ); // Q30
1327 : }
1328 :
1329 56548 : q_energy_ratio_ism[nchan_ism - 1] = L_sub( ONE_IN_Q30, sum );
1330 56548 : move32();
1331 :
1332 56548 : if ( q_energy_ratio_ism[nchan_ism - 1] < 0 )
1333 : {
1334 0 : q_energy_ratio_ism[nchan_ism - 1] = 0;
1335 0 : move32();
1336 : }
1337 :
1338 56548 : return;
1339 : }
1340 :
1341 :
1342 : /*---------------------------------------------------------------
1343 : * ivas_omasa_modify_masa_energy_ratios()
1344 : *
1345 : * Updates energy ratios by taking into account the MASA content contribution
1346 : * to the total audio scene
1347 : *---------------------------------------------------------------*/
1348 :
1349 3459 : void ivas_omasa_modify_masa_energy_ratios_fx(
1350 : IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */
1351 : Word32 masa_to_total_energy_ratio_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_MAXIMUM_CODING_SUBBANDS] /* Q30 */ )
1352 : {
1353 : Word16 i, m, d, b;
1354 :
1355 17295 : FOR( m = 0; m < MAX_PARAM_SPATIAL_SUBFRAMES; m++ )
1356 : {
1357 13836 : IF( EQ_16( hQMetaData->q_direction[0].cfg.nblocks, 1 ) )
1358 : {
1359 4564 : i = 0;
1360 4564 : move16();
1361 : }
1362 : ELSE
1363 : {
1364 9272 : i = m;
1365 9272 : move16();
1366 : }
1367 :
1368 103060 : FOR( b = 0; b < hQMetaData->q_direction[0].cfg.nbands; b++ )
1369 : {
1370 195828 : FOR( d = 0; d < hQMetaData->no_directions; d++ )
1371 : {
1372 106604 : hQMetaData->q_direction[d].band_data[b].energy_ratio_fx[m] = L_shl(
1373 106604 : Mpy_32_32( hQMetaData->q_direction[d].band_data[b].energy_ratio_fx[m],
1374 106604 : masa_to_total_energy_ratio_fx[i][b] ),
1375 : 1 ); // Q30 + Q30 - 31 = Q29 + 1 = Q30
1376 106604 : move32();
1377 : }
1378 : }
1379 : }
1380 :
1381 3459 : return;
1382 : }
1383 :
1384 :
1385 : /*---------------------------------------------------------------
1386 : * distribute_evenly_ism()
1387 : *
1388 : * Obtain ISM ratio indexes for even content distribution bbetween objects
1389 : *---------------------------------------------------------------*/
1390 :
1391 6596 : void distribute_evenly_ism_fx(
1392 : Word16 *idx, /* o : index values Q0 */
1393 : const Word16 K, /* i : sum of indexes Q0*/
1394 : const Word16 nchan_ism /* i : number of objects Q0 */
1395 : )
1396 : {
1397 : Word16 i;
1398 : Word16 sum;
1399 :
1400 6596 : sum = 0;
1401 6596 : move16();
1402 28643 : FOR( i = 0; i < nchan_ism; i++ )
1403 : {
1404 22047 : IF( K == 0 )
1405 : {
1406 0 : idx[i] = 0;
1407 0 : move16();
1408 : }
1409 : ELSE
1410 : {
1411 22047 : idx[i] = idiv1616( K, nchan_ism ); // Q0
1412 22047 : move16();
1413 : }
1414 22047 : sum = add( sum, idx[i] );
1415 : }
1416 :
1417 6596 : assert( LE_16( sum, K ) );
1418 :
1419 6596 : i = 0;
1420 6596 : move16();
1421 19212 : WHILE( LT_16( sum, K ) )
1422 : {
1423 12616 : if ( EQ_16( i, nchan_ism ) )
1424 : {
1425 0 : i = 0;
1426 0 : move16();
1427 : }
1428 12616 : idx[i] = add( idx[i], 1 );
1429 12616 : move16();
1430 12616 : sum = add( sum, 1 );
1431 12616 : i = add( i, 1 );
1432 : }
1433 :
1434 6596 : return;
1435 : }
1436 :
1437 :
1438 : /*---------------------------------------------------------------
1439 : * calculate_cpe_brate_MASA_ISM()
1440 : *
1441 : * Calculates bitrate for MASA_ISM mode that is not used for separated objects,
1442 : * * but for the CPE part (metadata included)
1443 : *---------------------------------------------------------------*/
1444 :
1445 : /*! r: CPE bitrate value */
1446 16931 : Word32 calculate_cpe_brate_MASA_ISM_fx(
1447 : const ISM_MODE ism_mode, /* i : ism mode */
1448 : const Word32 ivas_total_brate, /* i : IVAS total bitrate */
1449 : const Word16 nchan_ism /* i : number of objects */
1450 : )
1451 : {
1452 : Word32 cpe_brate;
1453 : Word16 k, sce_id;
1454 :
1455 16931 : k = 0;
1456 16931 : move16();
1457 :
1458 188907 : WHILE( LT_16( k, SIZE_IVAS_BRATE_TBL ) && NE_32( ivas_total_brate, ivas_brate_tbl[k] ) )
1459 : {
1460 171976 : test();
1461 171976 : k = add( k, 1 );
1462 : }
1463 :
1464 16931 : test();
1465 16931 : IF( EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) || EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) )
1466 : {
1467 4347 : cpe_brate = L_sub( ivas_total_brate, sep_object_brate[k - 2][0] ); /* take data from the first column */
1468 : }
1469 12584 : ELSE IF( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) )
1470 : {
1471 12183 : cpe_brate = ivas_total_brate;
1472 12183 : move32();
1473 :
1474 44933 : FOR( sce_id = 0; sce_id < nchan_ism; sce_id++ )
1475 : {
1476 32750 : cpe_brate = L_sub( cpe_brate, sep_object_brate[k - 2][nchan_ism - 1] );
1477 : }
1478 : }
1479 : ELSE
1480 : {
1481 401 : cpe_brate = ivas_total_brate;
1482 401 : move32();
1483 : }
1484 :
1485 16931 : return cpe_brate;
1486 : }
|