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 9232 : 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 9232 : ISM_MODE ism_mode = ISM_MODE_NONE;
76 9232 : move32();
77 :
78 9232 : SWITCH( nchan_ism )
79 : {
80 812 : case 1:
81 812 : IF( GE_32( ivas_total_brate, IVAS_24k4 ) )
82 : {
83 740 : ism_mode = ISM_MASA_MODE_DISC;
84 740 : move32();
85 : }
86 : ELSE
87 : {
88 72 : ism_mode = ISM_MODE_NONE;
89 72 : move32();
90 : }
91 812 : BREAK;
92 690 : case 2:
93 690 : IF( GE_32( ivas_total_brate, IVAS_48k ) )
94 : {
95 399 : ism_mode = ISM_MASA_MODE_DISC;
96 399 : move32();
97 : }
98 291 : ELSE IF( GE_32( ivas_total_brate, IVAS_32k ) )
99 : {
100 243 : ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
101 243 : move32();
102 : }
103 : ELSE
104 : {
105 48 : ism_mode = ISM_MODE_NONE;
106 48 : move32();
107 : }
108 690 : BREAK;
109 4041 : case 3:
110 4041 : IF( GE_32( ivas_total_brate, IVAS_96k ) )
111 : {
112 1338 : ism_mode = ISM_MASA_MODE_DISC;
113 1338 : move32();
114 : }
115 2703 : ELSE IF( GE_32( ivas_total_brate, IVAS_64k ) )
116 : {
117 1012 : ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
118 1012 : move32();
119 : }
120 1691 : ELSE IF( GE_32( ivas_total_brate, IVAS_32k ) )
121 : {
122 1321 : ism_mode = ISM_MASA_MODE_MASA_ONE_OBJ;
123 1321 : move32();
124 : }
125 : ELSE
126 : {
127 370 : ism_mode = ISM_MODE_NONE;
128 370 : move32();
129 : }
130 4041 : BREAK;
131 3689 : case 4:
132 3689 : IF( GE_32( ivas_total_brate, IVAS_128k ) )
133 : {
134 1027 : ism_mode = ISM_MASA_MODE_DISC;
135 1027 : move32();
136 : }
137 2662 : ELSE IF( GE_32( ivas_total_brate, IVAS_64k ) )
138 : {
139 1046 : ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
140 1046 : move32();
141 : }
142 1616 : ELSE IF( GE_32( ivas_total_brate, IVAS_32k ) )
143 : {
144 1316 : ism_mode = ISM_MASA_MODE_MASA_ONE_OBJ;
145 1316 : move32();
146 : }
147 : ELSE
148 : {
149 300 : ism_mode = ISM_MODE_NONE;
150 300 : move32();
151 : }
152 3689 : BREAK;
153 : }
154 :
155 9232 : return ism_mode;
156 : }
157 :
158 : /*---------------------------------------------------------------
159 : * ivas_set_omasa_TC()
160 : *
161 : * set number of transport channels in OMASA format
162 : * ---------------------------------------------------------------*/
163 :
164 1460 : 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 1460 : SWITCH( ism_mode )
172 : {
173 675 : case ISM_MASA_MODE_MASA_ONE_OBJ:
174 : case ISM_MASA_MODE_PARAM_ONE_OBJ:
175 675 : *nCPE = 1;
176 675 : move16();
177 675 : *nSCE = 1;
178 675 : move16();
179 675 : BREAK;
180 391 : case ISM_MASA_MODE_DISC:
181 391 : *nCPE = 1;
182 391 : move16();
183 391 : *nSCE = nchan_ism;
184 391 : move16();
185 391 : BREAK;
186 394 : case ISM_MODE_NONE:
187 394 : *nCPE = 1;
188 394 : move16();
189 394 : *nSCE = 0;
190 394 : move16();
191 394 : BREAK;
192 0 : default:
193 0 : BREAK;
194 : }
195 :
196 1460 : 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 10983 : 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 10983 : nBits = extract_l( Mpy_32_32( element_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) ); /* Q0 */
218 :
219 10983 : IF( ism_imp == ISM_INACTIVE_IMP )
220 : {
221 0 : nBits = BITS_ISM_INACTIVE;
222 0 : move16();
223 : }
224 : ELSE
225 : {
226 10983 : test();
227 10983 : test();
228 10983 : test();
229 10983 : test();
230 10983 : test();
231 10983 : test();
232 10983 : test();
233 10983 : test();
234 10983 : test();
235 10983 : 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 1719 : test();
238 1719 : test();
239 1719 : test();
240 1719 : test();
241 1719 : test();
242 1719 : test();
243 1719 : 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 1475 : return element_brate;
246 : }
247 :
248 244 : IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
249 : {
250 18 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP4_FX, nBits ) );
251 : }
252 226 : ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
253 : {
254 76 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP4_FX, nBits ) );
255 76 : 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 150 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP4_FX, nBits ) );
263 150 : 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 9264 : 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 1631 : test();
274 1631 : IF( EQ_16( ism_mode, ISM_MASA_MODE_PARAM_ONE_OBJ ) && EQ_32( element_brate, IVAS_13k2 ) )
275 : {
276 202 : IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
277 : {
278 6 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP3_FX, nBits ) );
279 : }
280 196 : ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
281 : {
282 50 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP3_FX, nBits ) );
283 : }
284 : ELSE /* ISM_HIGH_IMP */
285 : {
286 146 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP4_FX, nBits ) );
287 : }
288 : }
289 : ELSE
290 : {
291 1429 : IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
292 : {
293 34 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP3_FX, nBits ) );
294 : }
295 1395 : ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
296 : {
297 392 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP3_FX, nBits ) );
298 : }
299 : ELSE /* ISM_HIGH_IMP */
300 : {
301 1003 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP3_FX, nBits ) );
302 : }
303 : }
304 : }
305 7633 : ELSE IF( EQ_16( ism_mode, ISM_MASA_MODE_MASA_ONE_OBJ ) && EQ_32( element_brate, 16000 ) )
306 : {
307 933 : IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
308 : {
309 28 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP_FX, nBits ) );
310 : }
311 905 : ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
312 : {
313 272 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP_FX, nBits ) );
314 : }
315 : ELSE /* ISM_HIGH_IMP */
316 : {
317 633 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP3_FX, nBits ) );
318 : }
319 : }
320 : ELSE
321 : {
322 6700 : IF( EQ_16( ism_imp, ISM_LOW_IMP ) )
323 : {
324 282 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_LOW_IMP_FX, nBits ) );
325 : }
326 6418 : ELSE IF( EQ_16( ism_imp, ISM_MEDIUM_IMP ) )
327 : {
328 1763 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_MEDIUM_IMP_FX, nBits ) );
329 : }
330 : ELSE /* ISM_HIGH_IMP */
331 : {
332 4655 : nBits = extract_l( Mpy_32_16_1( GAMMA_ISM_HIGH_IMP_FX, nBits ) );
333 : }
334 : }
335 : }
336 :
337 9508 : limit_low = MIN_BRATE_SWB_BWE / FRAMES_PER_SEC;
338 9508 : move16();
339 9508 : IF( ism_imp == ISM_INACTIVE_IMP )
340 : {
341 0 : limit_low = BITS_ISM_INACTIVE;
342 0 : move16();
343 : }
344 9508 : ELSE IF( GE_32( element_brate, SCE_CORE_16k_LOW_LIMIT ) )
345 : {
346 6608 : limit_low = SCE_CORE_16k_LOW_LIMIT / FRAMES_PER_SEC;
347 6608 : move16();
348 : }
349 :
350 9508 : limit_high = IVAS_512k / FRAMES_PER_SEC;
351 9508 : move16();
352 9508 : IF( LE_32( element_brate, SCE_CORE_16k_LOW_LIMIT ) )
353 : {
354 2900 : limit_high = ACELP_12k8_HIGH_LIMIT / FRAMES_PER_SEC;
355 2900 : move16();
356 : }
357 :
358 9508 : nBits = check_bounds_s_fx( nBits, limit_low, limit_high );
359 :
360 9508 : element_brate_out = L_mult0( nBits, FRAMES_PER_SEC );
361 :
362 9508 : return element_brate_out;
363 : }
364 :
365 : /*---------------------------------------------------------------
366 : * ivas_combined_format_brate_sanity()
367 : *
368 : * Sanity check in combined format coding
369 : * ---------------------------------------------------------------*/
370 :
371 95 : 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 95 : 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 95 : IF( LT_32( element_brate, ACELP_12k8_HIGH_LIMIT ) )
390 : {
391 34 : limit_high = ACELP_12k8_HIGH_LIMIT / FRAMES_PER_SEC;
392 34 : move16();
393 34 : nBits = extract_l( Mpy_32_32( *core_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
394 :
395 34 : *diff_nBits = sub( nBits, limit_high );
396 34 : move16();
397 34 : 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 95 : IF( core == ACELP_CORE )
418 : {
419 47 : *inactive_coder_type_flag = 0; /* AVQ by default */
420 47 : move16();
421 47 : if ( LE_32( L_add( *core_brate, brate_diff ), MAX_GSC_INACTIVE_BRATE ) )
422 : {
423 36 : *inactive_coder_type_flag = 1; /* GSC */
424 36 : move16();
425 : }
426 : }
427 :
428 95 : return;
429 : }
430 :
431 :
432 : /*---------------------------------------------------------------
433 : * bits_index_ism_ratio()
434 : *
435 : *
436 : * ---------------------------------------------------------------*/
437 :
438 : /*!r : number of bits for ISM ratio index */
439 1553 : Word16 bits_index_ism_ratio_fx(
440 : const Word16 nchan_ism /* i : number of objects */
441 : )
442 : {
443 : Word16 bits_index;
444 :
445 1553 : bits_index = 0;
446 1553 : move16();
447 1553 : IF( EQ_16( nchan_ism, 2 ) )
448 : {
449 154 : bits_index = 3;
450 154 : move16();
451 : }
452 1399 : ELSE IF( EQ_16( nchan_ism, 3 ) )
453 : {
454 650 : bits_index = 6;
455 650 : move16();
456 : }
457 749 : ELSE IF( EQ_16( nchan_ism, 4 ) )
458 : {
459 749 : bits_index = 7;
460 749 : move16();
461 : }
462 : ELSE
463 : {
464 0 : assert( ( nchan_ism >= 2 && nchan_ism <= 4 ) && "Wrong number of objects for MASA_ISM." );
465 : }
466 :
467 1553 : return bits_index;
468 : }
469 :
470 : /*---------------------------------------------------------------
471 : * calculate_nbits_meta()
472 : *
473 : *
474 : * ---------------------------------------------------------------*/
475 :
476 5346 : static Word16 get_bits_ism_fx(
477 : Word32 val // Q29
478 : )
479 : {
480 : Word16 res;
481 5346 : test();
482 5346 : test();
483 5346 : test();
484 5346 : test();
485 5346 : test();
486 5346 : test();
487 : /* Considering only 3 points after decimal point, and replacing the other digits with 9 after that*/
488 5346 : 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 1857 : res = 0;
492 1857 : move16();
493 : }
494 3489 : 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 628 : res = 1;
498 628 : move16();
499 : }
500 2861 : 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 611 : res = 2;
504 611 : move16();
505 : }
506 2250 : 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 644 : res = 3;
510 644 : move16();
511 : }
512 1606 : 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 633 : res = 4;
516 633 : move16();
517 : }
518 973 : 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 938 : res = 5;
523 938 : move16();
524 : }
525 : ELSE
526 : {
527 35 : res = 6;
528 35 : move16();
529 : }
530 5346 : return res;
531 : }
532 :
533 :
534 1597 : 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 1597 : IF( GT_16( nchan_ism, 1 ) )
548 : {
549 1597 : set32_fx( priority, 0, nchan_ism );
550 6374 : FOR( sf = 0; sf < numSf; sf++ )
551 : {
552 30883 : FOR( band = 0; band < numCodingBands; band++ )
553 : {
554 116678 : FOR( obj = 0; obj < nchan_ism; obj++ )
555 : {
556 90572 : 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 90572 : 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 1597 : maximum_32_fx( priority, nchan_ism, &max_p );
570 6943 : FOR( obj = 0; obj < nchan_ism; obj++ )
571 : {
572 5346 : IF( EQ_16( obj, idx_sep_obj ) )
573 : {
574 1597 : IF( EQ_16( ism_imp, 3 ) )
575 : {
576 1120 : priority[obj] = ONE_IN_Q29; /* 1.0f in Q29 */
577 1120 : move32();
578 : }
579 477 : ELSE IF( EQ_16( ism_imp, 2 ) )
580 : {
581 437 : priority[obj] = L_shr( L_add( ONE_IN_Q29, max_p ), 1 ); // Q29
582 437 : move32();
583 : }
584 : ELSE
585 : {
586 40 : priority[obj] = max_p; /* Q29 */
587 40 : move32();
588 : }
589 : }
590 5346 : bits_ism[obj] = sub( bits_direction_masa[0], get_bits_ism_fx( priority[obj] ) );
591 5346 : move16();
592 : }
593 1597 : 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 100567 : 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 100567 : const Word16 *ptr_sin = &ivas_sine_panning_tbl_fx[0]; // Q15
613 100567 : const Word16 *ptr_tan_0 = ivas_tan_panning_gain_tbl_fx; // Q15
614 :
615 100567 : tbl_len = 601;
616 100567 : move16();
617 100567 : idx = shr( tbl_len, 1 );
618 100567 : lim_l = 0;
619 100567 : move16();
620 100567 : lim_r = tbl_len;
621 100567 : move16();
622 :
623 : WHILE( 1 )
624 : {
625 760978 : idx = shr( add( lim_l, lim_r ), 1 );
626 760978 : test();
627 760978 : 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 760978 : 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 760978 : ELSE IF( LE_16( sinAngleMapped, ptr_sin[idx + 1] ) && GE_16( sinAngleMapped, ptr_sin[idx] ) )
644 : {
645 100567 : IF( EQ_16( sinAngleMapped, ptr_sin[idx + 1] ) )
646 : {
647 7740 : panningGains[0] = ptr_tan_0[idx + 1]; // Q15
648 7740 : move16();
649 7740 : panningGains[1] = ptr_tan_0[tbl_len - idx - 2]; // Q15
650 7740 : move16();
651 7740 : BREAK;
652 : }
653 92827 : ELSE IF( EQ_16( sinAngleMapped, ptr_sin[idx] ) )
654 : {
655 16678 : panningGains[0] = ptr_tan_0[idx]; // Q15
656 16678 : move16();
657 16678 : panningGains[1] = ptr_tan_0[tbl_len - idx - 1]; // Q15
658 16678 : move16();
659 16678 : BREAK;
660 : }
661 : ELSE
662 : {
663 : Word16 mid;
664 76149 : mid = extract_l( L_shr( L_add( L_deposit_l( ptr_sin[idx] ), L_deposit_l( ptr_sin[idx + 1] ) ), 1 ) );
665 76149 : IF( LE_16( sinAngleMapped, mid ) )
666 : {
667 37784 : panningGains[0] = ptr_tan_0[idx]; // Q15
668 37784 : move16();
669 37784 : panningGains[1] = ptr_tan_0[tbl_len - idx - 1]; // Q15
670 37784 : move16();
671 : }
672 : ELSE
673 : {
674 38365 : panningGains[0] = ptr_tan_0[idx + 1]; // Q15
675 38365 : move16();
676 38365 : panningGains[1] = ptr_tan_0[tbl_len - idx - 2]; // Q15
677 38365 : move16();
678 : }
679 76149 : BREAK;
680 : }
681 : }
682 660411 : ELSE IF( GT_16( sinAngleMapped, ptr_sin[idx] ) )
683 : {
684 345690 : lim_l = add( idx, 1 );
685 345690 : move16();
686 : }
687 314721 : ELSE IF( LT_16( sinAngleMapped, ptr_sin[idx] ) )
688 : {
689 314721 : lim_r = sub( idx, 1 );
690 314721 : move16();
691 : }
692 : }
693 100567 : }
694 :
695 :
696 0 : 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 0 : Word16 azAddEl = add( aziDeg, eleDeg ); // Q0
704 0 : Word16 azSubEl = sub( aziDeg, eleDeg ); // Q0
705 :
706 0 : const Word16 *ptr_sin_az = ivas_sin_az_fx; // Q15
707 :
708 0 : WHILE( GT_16( azAddEl, 180 ) )
709 : {
710 0 : azAddEl = sub( azAddEl, 360 ); // Q0
711 : }
712 0 : WHILE( LT_16( azAddEl, -180 ) )
713 : {
714 0 : azAddEl = add( azAddEl, 360 ); // Q0
715 : }
716 0 : WHILE( GT_16( azSubEl, 180 ) )
717 : {
718 0 : azSubEl = sub( azSubEl, 360 ); // Q0
719 : }
720 0 : WHILE( LT_16( azSubEl, -180 ) )
721 : {
722 0 : 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 0 : 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 0 : IF( GE_16( sin_az_cos_el, SIN_30_DEGREES_Q15 ) )
729 : { /* Left side */
730 0 : panningGains[0] = (Word16) 0x7fff; // Q15
731 0 : move16();
732 0 : panningGains[1] = 0; // Q15
733 0 : move16();
734 : }
735 0 : ELSE IF( LE_16( sin_az_cos_el, SIN_NEG_30_DEGREES_Q15 ) )
736 : { /* Right side */
737 0 : panningGains[0] = 0; // Q15
738 0 : move16();
739 0 : panningGains[1] = (Word16) 0x7fff; // Q15
740 0 : move16();
741 : }
742 : ELSE /* Tangent panning law */
743 : {
744 0 : get_panning_gain_fx( sin_az_cos_el, panningGains );
745 : }
746 :
747 0 : return;
748 : }
749 :
750 :
751 : /*---------------------------------------------------------------
752 : * calculate_brate_limit_flag()
753 : *
754 : *
755 : *---------------------------------------------------------------*/
756 :
757 : /*! r: limitation flag */
758 2766 : 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 2766 : brate_limit_flag = 0;
769 2766 : move16();
770 2766 : nzeros = 0;
771 2766 : move16();
772 10097 : FOR( n = 0; n < nchan_ism; n++ )
773 : {
774 7331 : brate_limit_flag = add( brate_limit_flag, ism_imp[n] );
775 7331 : IF( ism_imp[n] == 0 )
776 : {
777 0 : nzeros = add( nzeros, 1 );
778 : }
779 : }
780 2766 : nchan_ism_sat = nchan_ism;
781 2766 : move16();
782 2766 : IF( EQ_16( s_and( nchan_ism, 1 ), 1 ) )
783 : {
784 1663 : nchan_ism_sat = sub( nchan_ism, 1 );
785 : }
786 :
787 :
788 : /* brate_limit_flag >= (int16_t) ( nchan_ism * 2.5f ) */
789 2766 : IF( GE_16( i_mult( 2, brate_limit_flag ), add( i_mult( 4, nchan_ism ), nchan_ism_sat ) ) )
790 : {
791 2468 : brate_limit_flag = 1;
792 2468 : move16();
793 : }
794 : ELSE
795 : {
796 298 : 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 2766 : return brate_limit_flag;
804 : }
|