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.h"
37 : #include "prot.h"
38 : #include "ivas_rom_com.h"
39 : #include <math.h>
40 : #ifdef DEBUGGING
41 : #include "debug.h"
42 : #endif
43 :
44 : /*---------------------------------------------------------------
45 : * Local constants
46 : *---------------------------------------------------------------*/
47 :
48 : #define GAMMA_ISM_LOW_IMP 0.8f
49 : #define GAMMA_ISM_MEDIUM_IMP 1.2f
50 : #define GAMMA_ISM_HIGH_IMP 1.4f
51 :
52 : #define GAMMA_ISM_LOW_IMP2 0.9f
53 : #define GAMMA_ISM_MEDIUM_IMP2 1.2f
54 : #define GAMMA_ISM_HIGH_IMP2 1.35f
55 :
56 : #define GAMMA_ISM_LOW_IMP3 0.85f
57 : #define GAMMA_ISM_MEDIUM_IMP3 1.15f
58 : #define GAMMA_ISM_HIGH_IMP3 1.3f
59 :
60 : #define GAMMA_ISM_LOW_IMP4 0.8f
61 : #define GAMMA_ISM_MEDIUM_IMP4 1.0f
62 : #define GAMMA_ISM_HIGH_IMP4 1.2f
63 :
64 :
65 : /*---------------------------------------------------------------
66 : * ivas_omasa_ism_mode_select()
67 : *
68 : * selects the ISM mode base on IVAS total bit-rate and
69 : * the number of objects in the combined ISM MASA format mode
70 : * ---------------------------------------------------------------*/
71 :
72 : /*! r : ISM format mode */
73 60388 : ISM_MODE ivas_omasa_ism_mode_select(
74 : const int32_t ivas_total_brate, /* i : IVAS total bitrate */
75 : const int16_t nchan_ism /* i : number of input ISM's */
76 : )
77 : {
78 60388 : ISM_MODE ism_mode = ISM_MODE_NONE;
79 :
80 60388 : switch ( nchan_ism )
81 : {
82 5312 : case 1:
83 5312 : if ( ivas_total_brate >= IVAS_24k4 )
84 : {
85 4870 : ism_mode = ISM_MASA_MODE_DISC;
86 : }
87 : else
88 : {
89 442 : ism_mode = ISM_MODE_NONE;
90 : }
91 5312 : break;
92 6690 : case 2:
93 6690 : if ( ivas_total_brate >= IVAS_48k )
94 : {
95 4134 : ism_mode = ISM_MASA_MODE_DISC;
96 : }
97 2556 : else if ( ivas_total_brate >= IVAS_32k )
98 : {
99 2010 : ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
100 : }
101 : else
102 : {
103 546 : ism_mode = ISM_MODE_NONE;
104 : }
105 6690 : break;
106 23122 : case 3:
107 23122 : if ( ivas_total_brate >= IVAS_96k )
108 : {
109 7858 : ism_mode = ISM_MASA_MODE_DISC;
110 : }
111 15264 : else if ( ivas_total_brate >= IVAS_64k )
112 : {
113 5640 : ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
114 : }
115 9624 : else if ( ivas_total_brate >= IVAS_32k )
116 : {
117 7828 : ism_mode = ISM_MASA_MODE_MASA_ONE_OBJ;
118 : }
119 : else
120 : {
121 1796 : ism_mode = ISM_MODE_NONE;
122 : }
123 23122 : break;
124 25264 : case 4:
125 25264 : if ( ivas_total_brate >= IVAS_128k )
126 : {
127 7458 : ism_mode = ISM_MASA_MODE_DISC;
128 : }
129 17806 : else if ( ivas_total_brate >= IVAS_64k )
130 : {
131 7598 : ism_mode = ISM_MASA_MODE_PARAM_ONE_OBJ;
132 : }
133 10208 : else if ( ivas_total_brate >= IVAS_32k )
134 : {
135 8402 : ism_mode = ISM_MASA_MODE_MASA_ONE_OBJ;
136 : }
137 : else
138 : {
139 1806 : ism_mode = ISM_MODE_NONE;
140 : }
141 25264 : break;
142 : }
143 :
144 60388 : return ism_mode;
145 : }
146 :
147 :
148 : /*---------------------------------------------------------------
149 : * ivas_set_omasa_TC()
150 : *
151 : * set number of transport channels in OMASA format
152 : * ---------------------------------------------------------------*/
153 :
154 6496 : void ivas_set_omasa_TC(
155 : const ISM_MODE ism_mode, /* i : ISM mode */
156 : const int16_t nchan_ism, /* i : number of input ISMs */
157 : int16_t *nSCE, /* o : number of SCEs */
158 : int16_t *nCPE /* o : number of CPEs */
159 : )
160 : {
161 6496 : switch ( ism_mode )
162 : {
163 2979 : case ISM_MASA_MODE_MASA_ONE_OBJ:
164 : case ISM_MASA_MODE_PARAM_ONE_OBJ:
165 2979 : *nCPE = 1;
166 2979 : *nSCE = 1;
167 2979 : break;
168 1752 : case ISM_MASA_MODE_DISC:
169 1752 : *nCPE = 1;
170 1752 : *nSCE = nchan_ism;
171 1752 : break;
172 1765 : case ISM_MODE_NONE:
173 1765 : *nCPE = 1;
174 1765 : *nSCE = 0;
175 1765 : break;
176 0 : default:
177 0 : break;
178 : }
179 :
180 6496 : return;
181 : }
182 :
183 :
184 : /*---------------------------------------------------------------
185 : * ivas_interformat_brate()
186 : *
187 : * Bit-budget distribution in case of combined-format coding
188 : * ---------------------------------------------------------------*/
189 :
190 : /*! r: adjusted bitrate */
191 51450 : int32_t ivas_interformat_brate(
192 : const ISM_MODE ism_mode, /* i : ISM mode */
193 : const int16_t nchan_ism, /* i : number of ISM channels */
194 : const int32_t element_brate, /* i : element bitrate */
195 : const int16_t ism_imp, /* i : ISM importance flag */
196 : const int16_t limit_flag /* i : flag to limit the bitrate increase */
197 : )
198 : {
199 : int32_t element_brate_out;
200 : int16_t nBits, limit_low, limit_high;
201 :
202 51450 : nBits = (int16_t) ( element_brate / FRAMES_PER_SEC );
203 :
204 51450 : if ( ism_imp == ISM_INACTIVE_IMP )
205 : {
206 0 : nBits = BITS_ISM_INACTIVE;
207 : }
208 : else
209 : {
210 51450 : if ( ism_mode == ISM_MASA_MODE_DISC && ( ( nchan_ism == 4 && element_brate == 24000 ) || ( nchan_ism == 3 && element_brate <= 24000 ) || ( nchan_ism == 2 && element_brate <= 11000 ) ) ) /* for border case in DISC mode */
211 : {
212 7064 : if ( limit_flag == 1 && ( ( nchan_ism == 4 && element_brate == 24000 ) || ( nchan_ism == 3 && element_brate == 20000 ) || ( nchan_ism == 2 && element_brate <= 11000 ) ) )
213 : {
214 6112 : return element_brate;
215 : }
216 :
217 952 : if ( ism_imp == ISM_LOW_IMP )
218 : {
219 75 : nBits = (int16_t) ( nBits * GAMMA_ISM_LOW_IMP4 );
220 : }
221 877 : else if ( ism_imp == ISM_MEDIUM_IMP )
222 : {
223 295 : nBits = (int16_t) ( nBits * GAMMA_ISM_MEDIUM_IMP4 );
224 295 : if ( limit_flag == -1 )
225 : {
226 0 : nBits = (int16_t) ( nBits * GAMMA_ISM_HIGH_IMP4 );
227 : }
228 : }
229 : else /* ISM_HIGH_IMP */
230 : {
231 582 : nBits = (int16_t) ( nBits * GAMMA_ISM_HIGH_IMP4 );
232 582 : if ( limit_flag == -1 )
233 : {
234 0 : nBits = (int16_t) ( nBits * GAMMA_ISM_HIGH_IMP4 );
235 : }
236 : }
237 : }
238 44386 : else if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ ||
239 26803 : ( ism_mode == ISM_MASA_MODE_DISC && element_brate == 9600 ) /* this condition corresponds to the ivas_total_brate = 24400 and 1 object */
240 : )
241 : {
242 9357 : if ( ism_mode == ISM_MASA_MODE_PARAM_ONE_OBJ && element_brate == IVAS_13k2 )
243 : {
244 1253 : if ( ism_imp == ISM_LOW_IMP )
245 : {
246 35 : nBits = (int16_t) ( nBits * GAMMA_ISM_LOW_IMP3 );
247 : }
248 1218 : else if ( ism_imp == ISM_MEDIUM_IMP )
249 : {
250 305 : nBits = (int16_t) ( nBits * GAMMA_ISM_MEDIUM_IMP3 );
251 : }
252 : else /* ISM_HIGH_IMP */
253 : {
254 913 : nBits = (int16_t) ( nBits * GAMMA_ISM_HIGH_IMP4 );
255 : }
256 : }
257 : else
258 : {
259 8104 : if ( ism_imp == ISM_LOW_IMP )
260 : {
261 202 : nBits = (int16_t) ( nBits * GAMMA_ISM_LOW_IMP3 );
262 : }
263 7902 : else if ( ism_imp == ISM_MEDIUM_IMP )
264 : {
265 2222 : nBits = (int16_t) ( nBits * GAMMA_ISM_MEDIUM_IMP3 );
266 : }
267 : else /* ISM_HIGH_IMP */
268 : {
269 5680 : nBits = (int16_t) ( nBits * GAMMA_ISM_HIGH_IMP3 );
270 : }
271 : }
272 : }
273 35029 : else if ( ism_mode == ISM_MASA_MODE_MASA_ONE_OBJ && element_brate == 16000 )
274 : {
275 3789 : if ( ism_imp == ISM_LOW_IMP )
276 : {
277 112 : nBits = (int16_t) ( nBits * GAMMA_ISM_LOW_IMP );
278 : }
279 3677 : else if ( ism_imp == ISM_MEDIUM_IMP )
280 : {
281 1104 : nBits = (int16_t) ( nBits * GAMMA_ISM_MEDIUM_IMP );
282 : }
283 : else /* ISM_HIGH_IMP */
284 : {
285 2573 : nBits = (int16_t) ( nBits * GAMMA_ISM_HIGH_IMP3 );
286 : }
287 : }
288 : else
289 : {
290 31240 : if ( ism_imp == ISM_LOW_IMP )
291 : {
292 1397 : nBits = (int16_t) ( nBits * GAMMA_ISM_LOW_IMP );
293 : }
294 29843 : else if ( ism_imp == ISM_MEDIUM_IMP )
295 : {
296 7992 : nBits = (int16_t) ( nBits * GAMMA_ISM_MEDIUM_IMP );
297 : }
298 : else /* ISM_HIGH_IMP */
299 : {
300 21851 : nBits = (int16_t) ( nBits * GAMMA_ISM_HIGH_IMP );
301 : }
302 : }
303 : }
304 :
305 45338 : limit_low = MIN_BRATE_SWB_BWE / FRAMES_PER_SEC;
306 45338 : if ( ism_imp == ISM_INACTIVE_IMP )
307 : {
308 0 : limit_low = BITS_ISM_INACTIVE;
309 : }
310 45338 : else if ( element_brate >= SCE_CORE_16k_LOW_LIMIT )
311 : {
312 32347 : limit_low = SCE_CORE_16k_LOW_LIMIT / FRAMES_PER_SEC;
313 : }
314 :
315 45338 : limit_high = IVAS_512k / FRAMES_PER_SEC;
316 45338 : if ( element_brate < SCE_CORE_16k_LOW_LIMIT )
317 : {
318 12991 : limit_high = ACELP_12k8_HIGH_LIMIT / FRAMES_PER_SEC;
319 : }
320 :
321 45338 : nBits = check_bounds_s( nBits, limit_low, limit_high );
322 :
323 45338 : element_brate_out = nBits * FRAMES_PER_SEC;
324 :
325 45338 : return element_brate_out;
326 : }
327 :
328 :
329 : /*---------------------------------------------------------------
330 : * ivas_combined_format_brate_sanity()
331 : *
332 : * Sanity check in combined format coding
333 : * ---------------------------------------------------------------*/
334 :
335 407 : void ivas_combined_format_brate_sanity(
336 : const int32_t element_brate, /* i : element bitrate */
337 : const int16_t core, /* i : core */
338 : const int32_t total_brate, /* i : total bitrate */
339 : int32_t *core_brate, /* i/o: core bitrate */
340 : int16_t *inactive_coder_type_flag, /* o : inactive coder_type flag */
341 : int16_t *diff_nBits /* o : number of differential bits */
342 : )
343 : {
344 : int16_t limit_high, nBits;
345 : int32_t brate_diff;
346 :
347 407 : brate_diff = total_brate - *core_brate;
348 :
349 : /* sanity check: at lowest IVAS bit-rates and one ISM channel coded by
350 : low-rate core-coder mode, it can happen that the CPE (MASA) bit-budget
351 : for ACELP core-coding @12.8 kHz is too high */
352 :
353 407 : if ( element_brate < ACELP_12k8_HIGH_LIMIT )
354 : {
355 144 : limit_high = ACELP_12k8_HIGH_LIMIT / FRAMES_PER_SEC;
356 144 : nBits = (int16_t) ( *core_brate / FRAMES_PER_SEC );
357 :
358 144 : *diff_nBits = nBits - limit_high;
359 144 : if ( *diff_nBits > 0 )
360 : {
361 0 : if ( core == TCX_20_CORE || core == TCX_10_CORE )
362 : {
363 0 : *diff_nBits = 0;
364 : }
365 : else /* ACELP core */
366 : {
367 0 : *core_brate -= ( *diff_nBits * FRAMES_PER_SEC );
368 : }
369 : }
370 : }
371 :
372 : /*-----------------------------------------------------------------*
373 : * set inactive coder_type flag in ACELP core
374 : *-----------------------------------------------------------------*/
375 :
376 407 : if ( core == ACELP_CORE )
377 : {
378 199 : *inactive_coder_type_flag = 0; /* AVQ by default */
379 199 : if ( *core_brate + brate_diff <= MAX_GSC_INACTIVE_BRATE )
380 : {
381 155 : *inactive_coder_type_flag = 1; /* GSC */
382 : }
383 : }
384 :
385 407 : return;
386 : }
387 :
388 :
389 : /*---------------------------------------------------------------
390 : * bits_index_ism_ratio()
391 : *
392 : *
393 : * ---------------------------------------------------------------*/
394 :
395 : /*!r : number of bits for ISM ratio index */
396 7202 : int16_t bits_index_ism_ratio(
397 : const int16_t nchan_ism /* i : number of objects */
398 : )
399 : {
400 : int16_t bits_index;
401 :
402 7202 : bits_index = 0;
403 7202 : if ( nchan_ism == 2 )
404 : {
405 832 : bits_index = 3;
406 : }
407 6370 : else if ( nchan_ism == 3 )
408 : {
409 2606 : bits_index = 6;
410 : }
411 3764 : else if ( nchan_ism == 4 )
412 : {
413 3764 : bits_index = 7;
414 : }
415 : else
416 : {
417 0 : assert( ( nchan_ism >= 2 && nchan_ism <= 4 ) && "Wrong number of objects for MASA_ISM." );
418 : }
419 :
420 7202 : return bits_index;
421 : }
422 :
423 :
424 : /*---------------------------------------------------------------
425 : * calculate_nbits_meta()
426 : *
427 : *
428 : * ---------------------------------------------------------------*/
429 :
430 7364 : void calculate_nbits_meta(
431 : const int16_t nchan_ism,
432 : float q_energy_ratio_ism[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS][MAX_NUM_OBJECTS],
433 : float masa_to_total_energy_ratio[MAX_PARAM_SPATIAL_SUBFRAMES][MASA_FREQUENCY_BANDS],
434 : const int16_t numSf,
435 : const int16_t numCodingBands,
436 : int16_t *bits_ism,
437 : const int16_t idx_sep_obj,
438 : const int16_t ism_imp )
439 : {
440 : int16_t sf, band, obj;
441 : float priority[MAX_NUM_OBJECTS], max_p;
442 :
443 7364 : if ( nchan_ism > 1 )
444 : {
445 7364 : set_f( priority, 0.0f, nchan_ism );
446 29779 : for ( sf = 0; sf < numSf; sf++ )
447 : {
448 143208 : for ( band = 0; band < numCodingBands; band++ )
449 : {
450 546499 : for ( obj = 0; obj < nchan_ism; obj++ )
451 : {
452 425706 : priority[obj] = max( priority[obj], ( q_energy_ratio_ism[sf][band][obj] * ( 1 - masa_to_total_energy_ratio[sf][band] ) ) );
453 : }
454 : }
455 : }
456 : }
457 : else
458 : {
459 0 : priority[0] = 1;
460 : }
461 :
462 : /* decide parameters for ISM metadata quantization */
463 7364 : maximum( priority, nchan_ism, &max_p );
464 32238 : for ( obj = 0; obj < nchan_ism; obj++ )
465 : {
466 24874 : if ( obj == idx_sep_obj )
467 : {
468 7364 : if ( ism_imp == 3 )
469 : {
470 5184 : priority[obj] = 1;
471 : }
472 2180 : else if ( ism_imp == 2 )
473 : {
474 1991 : priority[obj] = ( 1 + max_p ) * 0.5f;
475 : }
476 : else
477 : {
478 189 : priority[obj] = max_p;
479 : }
480 : }
481 24874 : bits_ism[obj] = bits_direction_masa[0] - (int16_t) ( ( 1 - ( (int16_t) ( priority[obj] * 1000.0f ) ) * 0.001f ) * 6 );
482 : }
483 :
484 7364 : return;
485 : }
486 :
487 :
488 : /*---------------------------------------------------------------
489 : * ivas_get_stereo_panning_gains()
490 : *
491 : *
492 : *---------------------------------------------------------------*/
493 :
494 341988 : void ivas_get_stereo_panning_gains(
495 : const float aziDeg,
496 : const float eleDeg,
497 : float panningGains[2] )
498 : {
499 : float aziRad, eleRad;
500 : float y, mappedX, aziRadMapped, A, A2, A3;
501 341988 : const float LsAngleRad = 30.0f * PI_OVER_180;
502 : /* Convert azi and ele to an azi value of the cone of confusion */
503 341988 : aziRad = aziDeg * PI_OVER_180;
504 341988 : eleRad = eleDeg * PI_OVER_180;
505 341988 : y = ( sinf( aziRad ) * cosf( eleRad ) );
506 341988 : mappedX = sqrtf( max( 0.0f, 1.0f - ( y * y ) ) );
507 341988 : aziRadMapped = atan2f( y, mappedX );
508 :
509 341988 : if ( aziRadMapped >= LsAngleRad )
510 : { /* Left side */
511 51956 : panningGains[0] = 1.0f;
512 51956 : panningGains[1] = 0.0f;
513 : }
514 290032 : else if ( aziRadMapped <= -LsAngleRad )
515 : { /* Right side */
516 50194 : panningGains[0] = 0.0f;
517 50194 : panningGains[1] = 1.0f;
518 : }
519 : else /* Tangent panning law */
520 : {
521 239838 : A = tanf( aziRadMapped ) / tanf( LsAngleRad );
522 239838 : A2 = ( A - 1.0f ) / max( 0.001f, A + 1.0f );
523 239838 : A3 = 1.0f / ( A2 * A2 + 1.0f );
524 239838 : panningGains[0] = sqrtf( A3 );
525 239838 : panningGains[1] = sqrtf( 1.0f - A3 );
526 : }
527 :
528 341988 : return;
529 : }
530 :
531 :
532 : /*---------------------------------------------------------------
533 : * calculate_brate_limit_flag()
534 : *
535 : *
536 : *---------------------------------------------------------------*/
537 :
538 : /*! r: limitation flag */
539 14643 : int16_t calculate_brate_limit_flag(
540 : const int16_t ism_imp[], /* i : ISM importance flags */
541 : const int16_t nchan_ism /* i : number of objects */
542 : )
543 : {
544 : int16_t n;
545 : int16_t brate_limit_flag;
546 : int16_t nzeros;
547 :
548 14643 : brate_limit_flag = 0;
549 14643 : nzeros = 0;
550 50564 : for ( n = 0; n < nchan_ism; n++ )
551 : {
552 35921 : brate_limit_flag += ism_imp[n];
553 35921 : if ( ism_imp[n] == 0 )
554 : {
555 0 : nzeros++;
556 : }
557 : }
558 :
559 14643 : if ( brate_limit_flag >= (int16_t) ( nchan_ism * 2.5f ) )
560 : {
561 13156 : brate_limit_flag = 1;
562 : }
563 : else
564 : {
565 1487 : if ( nzeros / (float) nchan_ism >= 0.5f )
566 : {
567 0 : brate_limit_flag = -1; /* there is no limitation, on the contrary */
568 : }
569 : }
570 :
571 14643 : return brate_limit_flag;
572 : }
|