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 "options.h"
34 : #include <stdlib.h>
35 : #include "ivas_cnst.h"
36 : #include "ivas_prot_fx.h"
37 : #include "prot_fx.h"
38 : #include "ivas_rom_com.h"
39 : #include "rom_com.h"
40 : #include <math.h>
41 :
42 : /*---------------------------------------------------------------
43 : * Local constants
44 : *---------------------------------------------------------------*/
45 :
46 : #define GAMMA_ISM_LOW_IMP_FX 26215 /*0.8f in Q15*/
47 : #define GAMMA_ISM_MEDIUM_IMP_FX 39322 /*1.2f in Q15*/
48 : #define GAMMA_ISM_HIGH_IMP_FX 45876 /*1.4f in Q15*/
49 :
50 : #define GAMMA_ISM_LOW_IMP2_FX 29492 /*0.9f in Q15*/
51 : #define GAMMA_ISM_MEDIUM_IMP2_FX 39322 /*1.2f in Q15*/
52 : #define GAMMA_ISM_HIGH_IMP2_FX 44237 /*1.35f in Q15*/
53 :
54 : #define GAMMA_ISM_LOW_IMP3_FX 27853 /*0.85f in Q15*/
55 : #define GAMMA_ISM_MEDIUM_IMP3_FX 37684 /*1.15f in Q15*/
56 : #define GAMMA_ISM_HIGH_IMP3_FX 42599 /*1.3f in Q15*/
57 :
58 : #define GAMMA_ISM_LOW_IMP4_FX 26215 /*0.8f in Q15*/
59 : #define GAMMA_ISM_MEDIUM_IMP4_FX 32768 /*1.0f in Q15*/
60 : #define GAMMA_ISM_HIGH_IMP4_FX 39322 /*1.2f in Q15*/
61 :
62 : /*---------------------------------------------------------------
63 : * ivas_omasa_ism_mode_select()
64 : *
65 : * selects the ISM mode base on IVAS total bit-rate and
66 : * the number of objects in the combined ISM MASA format mode
67 : * ---------------------------------------------------------------*/
68 :
69 : /*! r : ISM format mode */
70 18320 : ISM_MODE ivas_omasa_ism_mode_select_fx(
71 : const Word32 ivas_total_brate, /* i : IVAS total bitrate */
72 : const Word16 nchan_ism /* i : number of input ISM's */
73 : )
74 : {
75 18320 : ISM_MODE ism_mode = ISM_MODE_NONE;
76 18320 : move32();
77 :
78 18320 : SWITCH( nchan_ism )
79 : {
80 1720 : case 1:
81 1720 : IF( GE_32( ivas_total_brate, IVAS_24k4 ) )
82 : {
83 1422 : ism_mode = ISM_MASA_MODE_DISC;
84 1422 : move32();
85 : }
86 : ELSE
87 : {
88 298 : ism_mode = ISM_MODE_NONE;
89 298 : move32();
90 : }
91 1720 : BREAK;
92 1752 : case 2:
93 1752 : IF( GE_32( ivas_total_brate, IVAS_48k ) )
94 : {
95 957 : ism_mode = ISM_MASA_MODE_DISC;
96 957 : move32();
97 : }
98 795 : ELSE IF( GE_32( ivas_total_brate, IVAS_32k ) )
99 : {
100 495 : ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
101 495 : move32();
102 : }
103 : ELSE
104 : {
105 300 : ism_mode = ISM_MODE_NONE;
106 300 : move32();
107 : }
108 1752 : BREAK;
109 7369 : case 3:
110 7369 : IF( GE_32( ivas_total_brate, IVAS_96k ) )
111 : {
112 2326 : ism_mode = ISM_MASA_MODE_DISC;
113 2326 : move32();
114 : }
115 5043 : ELSE IF( GE_32( ivas_total_brate, IVAS_64k ) )
116 : {
117 1684 : ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
118 1684 : move32();
119 : }
120 3359 : ELSE IF( GE_32( ivas_total_brate, IVAS_32k ) )
121 : {
122 2303 : ism_mode = ISM_MASA_MODE_MASA_ONE_OBJ;
123 2303 : move32();
124 : }
125 : ELSE
126 : {
127 1056 : ism_mode = ISM_MODE_NONE;
128 1056 : move32();
129 : }
130 7369 : BREAK;
131 7479 : case 4:
132 7479 : IF( GE_32( ivas_total_brate, IVAS_128k ) )
133 : {
134 1975 : ism_mode = ISM_MASA_MODE_DISC;
135 1975 : move32();
136 : }
137 5504 : ELSE IF( GE_32( ivas_total_brate, IVAS_64k ) )
138 : {
139 2002 : ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
140 2002 : move32();
141 : }
142 3502 : ELSE IF( GE_32( ivas_total_brate, IVAS_32k ) )
143 : {
144 2410 : ism_mode = ISM_MASA_MODE_MASA_ONE_OBJ;
145 2410 : move32();
146 : }
147 : ELSE
148 : {
149 1092 : ism_mode = ISM_MODE_NONE;
150 1092 : move32();
151 : }
152 7479 : BREAK;
153 : }
154 :
155 18320 : return ism_mode;
156 : }
157 :
158 : /*---------------------------------------------------------------
159 : * ivas_set_omasa_TC()
160 : *
161 : * set number of transport channels in OMASA format
162 : * ---------------------------------------------------------------*/
163 :
164 3138 : void ivas_set_omasa_TC_fx(
165 : const ISM_MODE ism_mode, /* i : ISM mode */
166 : const Word16 nchan_ism, /* i : number of input ISMs */
167 : Word16 *nSCE, /* o : number of SCEs */
168 : Word16 *nCPE /* o : number of CPEs */
169 : )
170 : {
171 3138 : SWITCH( ism_mode )
172 : {
173 1446 : case ISM_MASA_MODE_MASA_ONE_OBJ:
174 : case ISM_MASA_MODE_PARAM_ONE_OBJ:
175 1446 : *nCPE = 1;
176 1446 : move16();
177 1446 : *nSCE = 1;
178 1446 : move16();
179 1446 : BREAK;
180 847 : case ISM_MASA_MODE_DISC:
181 847 : *nCPE = 1;
182 847 : move16();
183 847 : *nSCE = nchan_ism;
184 847 : move16();
185 847 : BREAK;
186 845 : case ISM_MODE_NONE:
187 845 : *nCPE = 1;
188 845 : move16();
189 845 : *nSCE = 0;
190 845 : move16();
191 845 : BREAK;
192 0 : default:
193 0 : BREAK;
194 : }
195 :
196 3138 : return;
197 : }
198 :
199 : /*---------------------------------------------------------------
200 : * ivas_interformat_brate()
201 : *
202 : * Bit-budget distribution in case of combined-format coding
203 : * ---------------------------------------------------------------*/
204 :
205 : /*! r: adjusted bitrate */
206 25221 : Word32 ivas_interformat_brate_fx(
207 : const ISM_MODE ism_mode, /* i : ISM mode */
208 : const Word16 nchan_ism, /* i : number of ISM channels */
209 : const Word32 element_brate, /* i : element bitrate */
210 : const Word16 ism_imp, /* i : ISM importance flag */
211 : const Word16 limit_flag /* i : flag to limit the bitrate increase */
212 : )
213 : {
214 : Word32 element_brate_out;
215 : Word16 nBits, limit_low, limit_high;
216 :
217 25221 : nBits = extract_l( Mpy_32_32( element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */
218 :
219 25221 : IF( ism_imp == ISM_INACTIVE_IMP )
220 : {
221 0 : nBits = BITS_ISM_INACTIVE;
222 0 : move16();
223 : }
224 : ELSE
225 : {
226 25221 : test();
227 25221 : test();
228 25221 : test();
229 25221 : test();
230 25221 : test();
231 25221 : test();
232 25221 : test();
233 25221 : test();
234 25221 : test();
235 25221 : IF( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) && ( ( EQ_16( nchan_ism, 4 ) && EQ_32( element_brate, 24000 ) ) || ( EQ_16( nchan_ism, 3 ) && LE_32( element_brate, 24000 ) ) || ( EQ_16( nchan_ism, 2 ) && LE_32( element_brate, 11000 ) ) ) ) /* for border case in DISC mode */
236 : {
237 3491 : test();
238 3491 : test();
239 3491 : test();
240 3491 : test();
241 3491 : test();
242 3491 : test();
243 3491 : IF( EQ_16( limit_flag, 1 ) && ( ( EQ_16( nchan_ism, 4 ) && EQ_32( element_brate, 24000 ) ) || ( EQ_16( nchan_ism, 3 ) && EQ_32( element_brate, 20000 ) ) || ( EQ_16( nchan_ism, 2 ) && LE_32( element_brate, 11000 ) ) ) )
244 : {
245 3006 : return element_brate;
246 : }
247 :
248 485 : IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
249 : {
250 36 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP4_FX, nBits ) );
251 : }
252 449 : ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
253 : {
254 152 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP4_FX, nBits ) );
255 152 : IF( EQ_16( limit_flag, -1 ) )
256 : {
257 0 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP4_FX, nBits ) );
258 : }
259 : }
260 : ELSE /* ISM_HIGH_IMP */
261 : {
262 297 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP4_FX, nBits ) );
263 297 : IF( EQ_16( limit_flag, -1 ) )
264 : {
265 0 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP4_FX, nBits ) );
266 : }
267 : }
268 : }
269 21730 : ELSE IF( EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) ||
270 : ( EQ_16( ism_mode, ISM_MASA_MODE_DISC ) && EQ_32( element_brate, 9600 ) ) /* this condition corresponds to the ivas_total_brate = 24400 and 1 object */
271 : )
272 : {
273 5363 : test();
274 5363 : IF( EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) && EQ_32( element_brate, IVAS_13k2 ) )
275 : {
276 702 : IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
277 : {
278 20 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP3_FX, nBits ) );
279 : }
280 682 : ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
281 : {
282 172 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP3_FX, nBits ) );
283 : }
284 : ELSE /* ISM_HIGH_IMP */
285 : {
286 510 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP4_FX, nBits ) );
287 : }
288 : }
289 : ELSE
290 : {
291 4661 : IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
292 : {
293 116 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP3_FX, nBits ) );
294 : }
295 4545 : ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
296 : {
297 1282 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP3_FX, nBits ) );
298 : }
299 : ELSE /* ISM_HIGH_IMP */
300 : {
301 3263 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP3_FX, nBits ) );
302 : }
303 : }
304 : }
305 16367 : ELSE IF( EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) && EQ_32( element_brate, 16000 ) )
306 : {
307 1875 : IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
308 : {
309 56 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP_FX, nBits ) );
310 : }
311 1819 : ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
312 : {
313 545 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP_FX, nBits ) );
314 : }
315 : ELSE /* ISM_HIGH_IMP */
316 : {
317 1274 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP3_FX, nBits ) );
318 : }
319 : }
320 : ELSE
321 : {
322 14492 : IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
323 : {
324 626 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP_FX, nBits ) );
325 : }
326 13866 : ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
327 : {
328 3740 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP_FX, nBits ) );
329 : }
330 : ELSE /* ISM_HIGH_IMP */
331 : {
332 10126 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP_FX, nBits ) );
333 : }
334 : }
335 : }
336 :
337 22215 : limit_low = MIN_BRATE_SWB_BWE / FRAMES_PER_SEC;
338 22215 : move16();
339 22215 : IF( ism_imp == ISM_INACTIVE_IMP )
340 : {
341 0 : limit_low = BITS_ISM_INACTIVE;
342 0 : move16();
343 : }
344 22215 : ELSE IF( GE_32( element_brate, SCE_CORE_16k_LOW_LIMIT ) )
345 : {
346 15441 : limit_low = SCE_CORE_16k_LOW_LIMIT / FRAMES_PER_SEC;
347 15441 : move16();
348 : }
349 :
350 22215 : limit_high = IVAS_512k / FRAMES_PER_SEC;
351 22215 : move16();
352 22215 : IF( LE_32( element_brate, SCE_CORE_16k_LOW_LIMIT ) )
353 : {
354 6774 : limit_high = ACELP_12k8_HIGH_LIMIT / FRAMES_PER_SEC;
355 6774 : move16();
356 : }
357 :
358 22215 : nBits = check_bounds_s_fx( nBits, limit_low, limit_high );
359 :
360 22215 : element_brate_out = L_mult0( nBits, FRAMES_PER_SEC );
361 :
362 22215 : return element_brate_out;
363 : }
364 :
365 : /*---------------------------------------------------------------
366 : * ivas_combined_format_brate_sanity()
367 : *
368 : * Sanity check in combined format coding
369 : * ---------------------------------------------------------------*/
370 :
371 228 : void ivas_combined_format_brate_sanity_fx(
372 : const Word32 element_brate, /* i : element bitrate */
373 : const Word16 core, /* i : core */
374 : const Word32 total_brate, /* i : total bitrate */
375 : Word32 *core_brate, /* i/o: core bitrate */
376 : Word16 *inactive_coder_type_flag, /* o : inactive coder_type flag */
377 : Word16 *diff_nBits /* o : number of differential bits */
378 : )
379 : {
380 : Word16 limit_high, nBits;
381 : Word32 brate_diff;
382 :
383 228 : brate_diff = L_sub( total_brate, *core_brate );
384 :
385 : /* sanity check: at lowest IVAS bit-rates and one ISM channel coded by
386 : low-rate core-coder mode, it can happen that the CPE (MASA) bit-budget
387 : for ACELP core-coding @12.8 kHz is too high */
388 :
389 228 : IF( LT_32( element_brate, ACELP_12k8_HIGH_LIMIT ) )
390 : {
391 70 : limit_high = ACELP_12k8_HIGH_LIMIT / FRAMES_PER_SEC;
392 70 : move16();
393 70 : nBits = extract_l( Mpy_32_32( *core_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
394 :
395 70 : *diff_nBits = sub( nBits, limit_high );
396 70 : move16();
397 70 : IF( *diff_nBits > 0 )
398 : {
399 0 : test();
400 0 : IF( EQ_16( core, TCX_20_CORE ) || EQ_16( core, TCX_10_CORE ) )
401 : {
402 0 : *diff_nBits = 0;
403 0 : move16();
404 : }
405 : ELSE /* ACELP core */
406 : {
407 0 : *core_brate = L_sub( *core_brate, L_mult0( *diff_nBits, FRAMES_PER_SEC ) );
408 0 : move32();
409 : }
410 : }
411 : }
412 :
413 : /*-----------------------------------------------------------------*
414 : * set inactive coder_type flag in ACELP core
415 : *-----------------------------------------------------------------*/
416 :
417 228 : IF( core == ACELP_CORE )
418 : {
419 96 : *inactive_coder_type_flag = 0; /* AVQ by default */
420 96 : move16();
421 96 : if ( LE_32( L_add( *core_brate, brate_diff ), MAX_GSC_INACTIVE_BRATE ) )
422 : {
423 74 : *inactive_coder_type_flag = 1; /* GSC */
424 74 : move16();
425 : }
426 : }
427 :
428 228 : return;
429 : }
430 :
431 :
432 : /*---------------------------------------------------------------
433 : * bits_index_ism_ratio()
434 : *
435 : *
436 : * ---------------------------------------------------------------*/
437 :
438 : /*!r : number of bits for ISM ratio index */
439 3415 : Word16 bits_index_ism_ratio_fx(
440 : const Word16 nchan_ism /* i : number of objects */
441 : )
442 : {
443 : Word16 bits_index;
444 :
445 3415 : bits_index = 0;
446 3415 : move16();
447 3415 : IF( EQ_16( nchan_ism, 2 ) )
448 : {
449 404 : bits_index = 3;
450 404 : move16();
451 : }
452 3011 : ELSE IF( EQ_16( nchan_ism, 3 ) )
453 : {
454 1318 : bits_index = 6;
455 1318 : move16();
456 : }
457 1693 : ELSE IF( EQ_16( nchan_ism, 4 ) )
458 : {
459 1693 : bits_index = 7;
460 1693 : move16();
461 : }
462 : ELSE
463 : {
464 0 : assert( ( nchan_ism >= 2 && nchan_ism <= 4 ) && "Wrong number of objects for MASA_ISM." );
465 : }
466 :
467 3415 : return bits_index;
468 : }
469 :
470 : /*---------------------------------------------------------------
471 : * calculate_nbits_meta()
472 : *
473 : *
474 : * ---------------------------------------------------------------*/
475 :
476 11626 : static Word16 get_bits_ism_fx(
477 : Word32 val // Q29
478 : )
479 : {
480 : Word16 res;
481 11626 : test();
482 11626 : test();
483 11626 : test();
484 11626 : test();
485 11626 : test();
486 11626 : test();
487 : /* Considering only 3 points after decimal point, and replacing the other digits with 9 after that*/
488 11626 : IF( LE_32( val, 536870912 /*1 (in Q29)*/ ) && GT_32( val, 447750340 /*5/6 (in Q29)*/ ) )
489 : {
490 : // 1 (in Q29) <= val <= 5/6 (in Q29) => res = 0
491 3977 : res = 0;
492 3977 : move16();
493 : }
494 7649 : ELSE IF( LE_32( val, 447750340 /* 5/6 (in Q29)*/ ) && GT_32( val, 358092870 /*4/6 (in Q29)*/ ) )
495 : {
496 : // 5/6 (in Q29) <= val <= 4/6 (in Q29) => res = 1
497 1337 : res = 1;
498 1337 : move16();
499 : }
500 6312 : ELSE IF( LE_32( val, 358092870 /*4/6 (in Q29)*/ ) && GT_32( val, 268972326 /*3/6 (in Q29)*/ ) )
501 : {
502 : // 4/6 (in Q29) <= val <= 3/6 (in Q29) => res = 2
503 1333 : res = 2;
504 1333 : move16();
505 : }
506 4979 : ELSE IF( LE_32( val, 268972326 /*3/6 (in Q29)*/ ) && GT_32( val, 179314884 /* 2/6 (in Q29) */ ) )
507 : {
508 : // 3/6 (in Q29) <= val <= 2/6 (in Q29) => res = 3
509 1364 : res = 3;
510 1364 : move16();
511 : }
512 3615 : ELSE IF( LE_32( val, 179314884 /* 2/6 (in Q29) */ ) && GT_32( val, 89657442 /* 1/6 => res (in Q29) */ ) )
513 : {
514 : // 2/6 (in Q29) <= val <= 1/6 => res (in Q29) = 4
515 1387 : res = 4;
516 1387 : move16();
517 : }
518 2228 : ELSE IF( LE_32( val, 89657442 /* 1/6 => res (in Q29) */ ) && GT_32( val, 536870 /* 0.0009999999 ( in Q29 )*/ ) )
519 : {
520 : // 1/6 (in Q29) <= val <= 0 (in Q29) => res = 5
521 : // 0.0009999999 in Q29-> 536870
522 2153 : res = 5;
523 2153 : move16();
524 : }
525 : ELSE
526 : {
527 75 : res = 6;
528 75 : move16();
529 : }
530 11626 : return res;
531 : }
532 :
533 :
534 3459 : void calculate_nbits_meta_fx(
535 : const Word16 nchan_ism,
536 : Word32 q_energy_ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS], // Q30
537 : Word32 masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS], // Q30
538 : const Word16 numSf,
539 : const Word16 numCodingBands,
540 : Word16 *bits_ism,
541 : const Word16 idx_sep_obj,
542 : const Word16 ism_imp )
543 : {
544 : Word16 sf, band, obj;
545 : Word32 priority[MAX_NUM_OBJECTS], max_p; /* Q29 */
546 :
547 3459 : IF( GT_16( nchan_ism, 1 ) )
548 : {
549 3459 : set32_fx( priority, 0, nchan_ism );
550 13872 : FOR( sf = 0; sf < numSf; sf++ )
551 : {
552 66961 : FOR( band = 0; band < numCodingBands; band++ )
553 : {
554 254292 : FOR( obj = 0; obj < nchan_ism; obj++ )
555 : {
556 197744 : priority[obj] = L_max( priority[obj], ( Mpy_32_32( q_energy_ratio_ism[sf][band][obj], L_sub( ONE_IN_Q30 /* 1.0f in Q30 */, masa_to_total_energy_ratio[sf][band] ) ) ) ); // Qx - 1
557 197744 : move32();
558 : }
559 : }
560 : }
561 : }
562 : ELSE
563 : {
564 0 : priority[0] = ONE_IN_Q29; /* 1.0f in Q29 */
565 0 : move32();
566 : }
567 :
568 : /* decide parameters for ISM metadata quantization */
569 3459 : maximum_32_fx( priority, nchan_ism, &max_p );
570 15085 : FOR( obj = 0; obj < nchan_ism; obj++ )
571 : {
572 11626 : IF( EQ_16( obj, idx_sep_obj ) )
573 : {
574 3459 : IF( EQ_16( ism_imp, 3 ) )
575 : {
576 2428 : priority[obj] = ONE_IN_Q29; /* 1.0f in Q29 */
577 2428 : move32();
578 : }
579 1031 : ELSE IF( EQ_16( ism_imp, 2 ) )
580 : {
581 943 : priority[obj] = L_shr( L_add( ONE_IN_Q29, max_p ), 1 ); // Q29
582 943 : move32();
583 : }
584 : ELSE
585 : {
586 88 : priority[obj] = max_p; /* Q29 */
587 88 : move32();
588 : }
589 : }
590 11626 : bits_ism[obj] = sub( bits_direction_masa[0], get_bits_ism_fx( priority[obj] ) );
591 11626 : move16();
592 : }
593 3459 : return;
594 : }
595 :
596 :
597 : /*---------------------------------------------------------------
598 : * ivas_get_stereo_panning_gains()
599 : *
600 : *
601 : *---------------------------------------------------------------*/
602 :
603 : #define SIN_NEG_30_DEGREES_Q15 ( (Word16) 0xC000 )
604 : #define SIN_30_DEGREES_Q15 ( (Word16) 0x4000 )
605 :
606 113723 : void get_panning_gain_fx(
607 : const Word16 sinAngleMapped, // Q15
608 : Word16 *panningGains // Q15
609 : )
610 : {
611 : Word16 tbl_len, idx, lim_l, lim_r;
612 113723 : const Word16 *ptr_sin = &ivas_sine_panning_tbl_fx[0]; // Q15
613 113723 : const Word16 *ptr_tan_0 = ivas_tan_panning_gain_tbl_fx; // Q15
614 :
615 113723 : tbl_len = 601;
616 113723 : move16();
617 113723 : idx = shr( tbl_len, 1 );
618 113723 : lim_l = 0;
619 113723 : move16();
620 113723 : lim_r = tbl_len;
621 113723 : move16();
622 :
623 : WHILE( 1 )
624 : {
625 845572 : idx = shr( add( lim_l, lim_r ), 1 );
626 845572 : test();
627 845572 : IF( GE_16( idx, tbl_len ) )
628 : {
629 0 : panningGains[0] = ptr_tan_0[tbl_len - 1]; // Q15
630 0 : move16();
631 0 : panningGains[1] = ptr_tan_0[0]; // Q15
632 0 : move16();
633 0 : BREAK;
634 : }
635 845572 : ELSE IF( idx < 0 )
636 : {
637 0 : panningGains[0] = ptr_tan_0[0]; // Q15
638 0 : move16();
639 0 : panningGains[1] = ptr_tan_0[tbl_len - 1]; // Q15
640 0 : move16();
641 0 : BREAK;
642 : }
643 845572 : ELSE IF( LE_16( sinAngleMapped, ptr_sin[idx + 1] ) && GE_16( sinAngleMapped, ptr_sin[idx] ) )
644 : {
645 113723 : IF( EQ_16( sinAngleMapped, ptr_sin[idx + 1] ) )
646 : {
647 8682 : panningGains[0] = ptr_tan_0[idx + 1]; // Q15
648 8682 : move16();
649 8682 : panningGains[1] = ptr_tan_0[tbl_len - idx - 2]; // Q15
650 8682 : move16();
651 8682 : BREAK;
652 : }
653 105041 : ELSE IF( EQ_16( sinAngleMapped, ptr_sin[idx] ) )
654 : {
655 20720 : panningGains[0] = ptr_tan_0[idx]; // Q15
656 20720 : move16();
657 20720 : panningGains[1] = ptr_tan_0[tbl_len - idx - 1]; // Q15
658 20720 : move16();
659 20720 : BREAK;
660 : }
661 : ELSE
662 : {
663 : Word16 mid;
664 84321 : mid = extract_l( L_shr( L_add( L_deposit_l( ptr_sin[idx] ), L_deposit_l( ptr_sin[idx + 1] ) ), 1 ) );
665 84321 : IF( LE_16( sinAngleMapped, mid ) )
666 : {
667 41798 : panningGains[0] = ptr_tan_0[idx]; // Q15
668 41798 : move16();
669 41798 : panningGains[1] = ptr_tan_0[tbl_len - idx - 1]; // Q15
670 41798 : move16();
671 : }
672 : ELSE
673 : {
674 42523 : panningGains[0] = ptr_tan_0[idx + 1]; // Q15
675 42523 : move16();
676 42523 : panningGains[1] = ptr_tan_0[tbl_len - idx - 2]; // Q15
677 42523 : move16();
678 : }
679 84321 : BREAK;
680 : }
681 : }
682 731849 : ELSE IF( GT_16( sinAngleMapped, ptr_sin[idx] ) )
683 : {
684 384084 : lim_l = add( idx, 1 );
685 384084 : move16();
686 : }
687 347765 : ELSE IF( LT_16( sinAngleMapped, ptr_sin[idx] ) )
688 : {
689 347765 : lim_r = sub( idx, 1 );
690 347765 : move16();
691 : }
692 : }
693 113723 : }
694 :
695 :
696 19440 : void ivas_get_stereo_panning_gains_fx(
697 : const Word16 aziDeg, // Q0
698 : const Word16 eleDeg, // Q0
699 : Word16 panningGains[2] // Q15
700 : )
701 : {
702 : /* Convert azi and ele to an azi value of the cone of confusion */
703 19440 : Word16 azAddEl = add( aziDeg, eleDeg ); // Q0
704 19440 : Word16 azSubEl = sub( aziDeg, eleDeg ); // Q0
705 :
706 19440 : const Word16 *ptr_sin_az = ivas_sin_az_fx; // Q15
707 :
708 20503 : WHILE( GT_16( azAddEl, 180 ) )
709 : {
710 1063 : azAddEl = sub( azAddEl, 360 ); // Q0
711 : }
712 20595 : WHILE( LT_16( azAddEl, -180 ) )
713 : {
714 1155 : azAddEl = add( azAddEl, 360 ); // Q0
715 : }
716 20294 : WHILE( GT_16( azSubEl, 180 ) )
717 : {
718 854 : azSubEl = sub( azSubEl, 360 ); // Q0
719 : }
720 20298 : WHILE( LT_16( azSubEl, -180 ) )
721 : {
722 858 : azSubEl = add( azSubEl, 360 ); // Q0
723 : }
724 : // sin_az_cos_el = (ptr_sin_az[azAddEl] + ptr_sin_az[azSubEl])/2;
725 : Word16 sin_az_cos_el;
726 19440 : sin_az_cos_el = extract_l( L_shr( L_add( L_deposit_l( ptr_sin_az[azAddEl + 180] ), L_deposit_l( ptr_sin_az[azSubEl + 180] ) ), 1 ) ); // Q15
727 :
728 19440 : IF( GE_16( sin_az_cos_el, SIN_30_DEGREES_Q15 ) )
729 : { /* Left side */
730 2999 : panningGains[0] = (Word16) 0x7fff; // Q15
731 2999 : move16();
732 2999 : panningGains[1] = 0; // Q15
733 2999 : move16();
734 : }
735 16441 : ELSE IF( LE_16( sin_az_cos_el, SIN_NEG_30_DEGREES_Q15 ) )
736 : { /* Right side */
737 3285 : panningGains[0] = 0; // Q15
738 3285 : move16();
739 3285 : panningGains[1] = (Word16) 0x7fff; // Q15
740 3285 : move16();
741 : }
742 : ELSE /* Tangent panning law */
743 : {
744 13156 : get_panning_gain_fx( sin_az_cos_el, panningGains );
745 : }
746 :
747 19440 : return;
748 : }
749 :
750 :
751 : /*---------------------------------------------------------------
752 : * calculate_brate_limit_flag()
753 : *
754 : *
755 : *---------------------------------------------------------------*/
756 :
757 : /*! r: limitation flag */
758 7962 : Word16 calculate_brate_limit_flag_fx(
759 : const Word16 ism_imp[], /* i : ISM importance flags */
760 : const Word16 nchan_ism /* i : number of objects */
761 : )
762 : {
763 : Word16 n;
764 : Word16 brate_limit_flag;
765 : Word16 nzeros;
766 : Word16 nchan_ism_sat;
767 :
768 7962 : brate_limit_flag = 0;
769 7962 : move16();
770 7962 : nzeros = 0;
771 7962 : move16();
772 25807 : FOR( n = 0; n < nchan_ism; n++ )
773 : {
774 17845 : brate_limit_flag = add( brate_limit_flag, ism_imp[n] );
775 17845 : IF( ism_imp[n] == 0 )
776 : {
777 0 : nzeros = add( nzeros, 1 );
778 : }
779 : }
780 7962 : nchan_ism_sat = nchan_ism;
781 7962 : move16();
782 7962 : IF( EQ_16( s_and( nchan_ism, 1 ), 1 ) )
783 : {
784 5373 : nchan_ism_sat = sub( nchan_ism, 1 );
785 : }
786 :
787 :
788 : /* brate_limit_flag >= (int16_t) ( nchan_ism * 2.5f ) */
789 7962 : IF( GE_16( i_mult( 2, brate_limit_flag ), add( i_mult( 4, nchan_ism ), nchan_ism_sat ) ) )
790 : {
791 7256 : brate_limit_flag = 1;
792 7256 : move16();
793 : }
794 : ELSE
795 : {
796 706 : if ( GE_16( i_mult( 2, nzeros ), nchan_ism ) )
797 : {
798 0 : brate_limit_flag = -1; /* there is no limitation, on the contrary */
799 0 : move16();
800 : }
801 : }
802 :
803 7962 : return brate_limit_flag;
804 : }
|