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 <stdint.h>
34 : #include "options.h"
35 : #include "cnst.h"
36 : #include "ivas_cnst.h"
37 : #include "rom_com.h"
38 : #include "prot_fx.h"
39 : #include "ivas_stat_com.h"
40 : #include "ivas_rom_com.h"
41 : #include "wmc_auto.h"
42 : #include "ivas_prot_fx.h"
43 :
44 :
45 : /*-----------------------------------------------------------------------*
46 : * Local constants
47 : *-----------------------------------------------------------------------*/
48 :
49 : #define BITS_ISM_INACTIVE ( BRATE_ISM_INACTIVE / FRAMES_PER_SEC )
50 : #define BETA_ISM_LOW_IMP_Q31 ( 1288490189 ) // 0.6 in Q31
51 : #define BETA_ISM_MEDIUM_IMP_Q31 ( 1717986918 ) // 0.8 in Q31
52 : #define BETA_ISM_MEDIUM_IMP_BY_8_Q31 ( 214748365 ) // 0.8 in Q29
53 :
54 : #define MAX_BRATE_TCX_32k 48000
55 : #define BITS_IVAS_512k ( IVAS_512k / FRAMES_PER_SEC )
56 : #define BITS_ACELP_12k8_HIGH_LIMIT ( ACELP_12k8_HIGH_LIMIT / FRAMES_PER_SEC )
57 : #define BITS_MIN_BRATE_SWB_BWE ( MIN_BRATE_SWB_BWE / FRAMES_PER_SEC )
58 : #define BITS_MIN_BRATE_WB_BWE ( MIN_BRATE_WB_BWE / FRAMES_PER_SEC )
59 : #define BITS_ACELP_16k_LOW_LIMIT_1k6 ( ACELP_16k_LOW_LIMIT + SWB_TBE_1k6 ) / FRAMES_PER_SEC
60 : #define BITS_MAX_BRATE_TCX_32k ( MAX_BRATE_TCX_32k / FRAMES_PER_SEC )
61 :
62 :
63 : /*-------------------------------------------------------------------*
64 : * bitbudget_to_brate()
65 : *
66 : * Convert bit-budget to bitrate
67 : *-------------------------------------------------------------------*/
68 :
69 381624 : void bitbudget_to_brate(
70 : const Word16 x[], /* i : bitbudgets Q0 */
71 : Word32 y[], /* o : bitrates Q0 */
72 : const Word16 N /* i : number of entries to be converted */
73 : )
74 : {
75 : Word16 i;
76 :
77 1349758 : FOR( i = 0; i < N; i++ )
78 : {
79 968134 : y[i] = L_mult0( FRAMES_PER_SEC, x[i] );
80 968134 : move32();
81 : }
82 :
83 381624 : return;
84 : }
85 :
86 :
87 : /*-------------------------------------------------------------------*
88 : * ivas_ism_config()
89 : *
90 : * Configure audio objects coding
91 : *-------------------------------------------------------------------*/
92 :
93 96847 : ivas_error ivas_ism_config_fx(
94 : const Word32 ism_total_brate, /* i : ISM total bitrate */
95 : const Word16 nchan_transport, /* i : number of transport channels */
96 : const Word16 nchan_ism, /* i : number of objects */
97 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
98 : const Word16 ism_extended_metadata_flag, /* i : extended metadata flag */
99 : const Word16 null_metadata_flag[MAX_NUM_OBJECTS], /* i : NULL MD flag */
100 : const Word16 ism_imp[], /* i : ISM importance flags */
101 : Word32 element_brate[], /* o : element bitrate per object */
102 : Word32 total_brate[], /* o : total bitrate per object */
103 : Word16 nb_bits_metadata[], /* i/o: number of metadata bits */
104 : const Word16 combined_format_flag /* i : flag indicating combined format */
105 : )
106 : {
107 : Word16 ch;
108 : Word16 bits_element[MAX_NUM_OBJECTS], bits_CoreCoder[MAX_NUM_OBJECTS];
109 : Word16 bits_ism, bits_side;
110 96847 : Word16 limit_high = 0; /* just to avoid compilation warning */
111 : Word16 tmp, tmp1, exp;
112 : Word16 ism_metadata_flag_global;
113 : Word16 n_ISms;
114 : ivas_error error;
115 :
116 96847 : error = IVAS_ERR_OK;
117 96847 : move32();
118 96847 : IF( combined_format_flag )
119 : {
120 4714 : n_ISms = nchan_ism;
121 4714 : move16();
122 : }
123 : ELSE
124 : {
125 92133 : n_ISms = nchan_transport;
126 92133 : move16();
127 : }
128 :
129 : /* initialization */
130 96847 : ism_metadata_flag_global = 0;
131 96847 : move16();
132 96847 : bits_side = 0;
133 96847 : move16();
134 96847 : IF( hIsmMeta != NULL )
135 : {
136 337496 : FOR( ch = 0; ch < n_ISms; ch++ )
137 : {
138 241831 : ism_metadata_flag_global = s_or( ism_metadata_flag_global, ism_imp[ch] );
139 : }
140 : }
141 :
142 : /* decision about bitrates per channel */
143 96847 : IF( combined_format_flag )
144 : {
145 : /* combined format: decision about bitrates per channel - variable during the session (at one ivas_total_brate) */
146 : // bits_ism = (Word16) ( ism_total_brate / FRAMES_PER_SEC );
147 4714 : bits_ism = extract_l( Mpy_32_32( 42949673, ism_total_brate ) ); // 42949673 is 1/FRAMES_PER_SEC in Q31
148 4714 : tmp1 = BASOP_Util_Divide1616_Scale( bits_ism, n_ISms, &exp ); // Q15 - exp
149 4714 : set16_fx( bits_element, shr( tmp1, sub( 15, exp ) ), n_ISms );
150 4714 : bits_element[n_ISms - 1] = add( bits_element[n_ISms - 1], bits_ism % n_ISms ); // Q0
151 4714 : move16();
152 :
153 : /* ISM common signaling bits are counted in MASA MD bit-budget */
154 : }
155 : ELSE
156 : {
157 : /* ISM format: decision about bitrates per channel - constant during the session (at one ivas_total_brate) */
158 : // bits_ism = (Word16) ( ism_total_brate / FRAMES_PER_SEC );
159 : // 1 / 50 * 2 ^ 31 -- > 42949673, --> Q31,
160 : //(Q31 +Q0) - Q31 --> Q0
161 92133 : bits_ism = extract_l( Mpy_32_32( 42949673, ism_total_brate ) ); // 42949673 is 1/FRAMES_PER_SEC in Q31
162 92133 : tmp1 = BASOP_Util_Divide1616_Scale( bits_ism, n_ISms, &exp ); // Q15 - exp
163 92133 : set16_fx( bits_element, shr( tmp1, sub( 15, exp ) ), n_ISms );
164 92133 : bits_element[n_ISms - 1] = add( bits_element[n_ISms - 1], bits_ism % n_ISms ); // Q0
165 92133 : move16();
166 92133 : bitbudget_to_brate( bits_element, element_brate, n_ISms );
167 :
168 : /* count ISm common signaling bits */
169 92133 : IF( hIsmMeta != NULL )
170 : {
171 90951 : nb_bits_metadata[0] = add( nb_bits_metadata[0], add( imult1616( n_ISms, ISM_METADATA_FLAG_BITS ), nchan_ism ) );
172 90951 : move16();
173 :
174 90951 : IF( GE_32( ism_total_brate, ISM_EXTENDED_METADATA_BRATE ) )
175 : {
176 53647 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_EXTENDED_METADATA_BITS );
177 53647 : move16();
178 :
179 53647 : IF( ism_extended_metadata_flag )
180 : {
181 7080 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_IS_NDP_BITS );
182 7080 : move16();
183 : }
184 : }
185 :
186 323561 : FOR( ch = 0; ch < n_ISms; ch++ )
187 : {
188 232610 : IF( null_metadata_flag[ch] )
189 : {
190 4670 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_MD_FLAG_BITS );
191 4670 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_FLAG_BITS );
192 :
193 4670 : move16();
194 4670 : move16();
195 : }
196 : ELSE
197 : {
198 227940 : IF( ism_imp[ch] == ISM_NO_META )
199 : {
200 5621 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_MD_FLAG_BITS );
201 5621 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_INACTIVE_FLAG_BITS );
202 :
203 5621 : move16();
204 5621 : move16();
205 : }
206 : }
207 : }
208 : }
209 : }
210 :
211 : /* split metadata bitbudget equally between channels */
212 96847 : IF( nb_bits_metadata != NULL )
213 : {
214 95665 : bits_side = sum16_fx( nb_bits_metadata, n_ISms );
215 95665 : tmp1 = BASOP_Util_Divide1616_Scale( bits_side, n_ISms, &exp ); // Q15 - exp
216 95665 : set16_fx( nb_bits_metadata, shr( tmp1, sub( 15, exp ) ), n_ISms );
217 95665 : nb_bits_metadata[n_ISms - 1] = add( nb_bits_metadata[n_ISms - 1], bits_side % n_ISms ); // Q0
218 95665 : move16();
219 95665 : v_sub_16( bits_element, nb_bits_metadata, bits_CoreCoder, n_ISms );
220 95665 : bitbudget_to_brate( bits_CoreCoder, total_brate, n_ISms );
221 :
222 95665 : Copy( nb_bits_metadata, nb_bits_metadata, n_ISms );
223 : }
224 :
225 : /* assign less CoreCoder bit-budget to inactive streams (at least one stream must be active) */
226 96847 : IF( ism_metadata_flag_global )
227 : {
228 : Word16 diff, n_higher, flag_higher[MAX_NUM_OBJECTS];
229 :
230 95530 : set16_fx( flag_higher, 1, MAX_NUM_OBJECTS );
231 :
232 95530 : diff = 0;
233 95530 : move16();
234 336920 : FOR( ch = 0; ch < n_ISms; ch++ )
235 : {
236 241390 : IF( EQ_16( ism_imp[ch], ISM_NO_META ) )
237 : {
238 6931 : diff = add( diff, sub( bits_CoreCoder[ch], BITS_ISM_INACTIVE ) );
239 6931 : bits_CoreCoder[ch] = BITS_ISM_INACTIVE;
240 6931 : flag_higher[ch] = 0;
241 6931 : move16();
242 6931 : move16();
243 : }
244 : }
245 :
246 95530 : n_higher = sum16_fx( flag_higher, n_ISms );
247 :
248 95530 : test();
249 95530 : IF( diff > 0 && n_higher > 0 )
250 : {
251 6533 : tmp = BASOP_Util_Divide1616_Scale( diff, n_higher, &exp );
252 6533 : tmp = shr( tmp, sub( 15, exp ) );
253 30433 : FOR( ch = 0; ch < n_ISms; ch++ )
254 : {
255 23900 : IF( flag_higher[ch] )
256 : {
257 16969 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], tmp );
258 16969 : move16();
259 : }
260 : }
261 :
262 6533 : tmp = diff % n_higher;
263 6533 : move16();
264 6533 : ch = 0;
265 6533 : move16();
266 6627 : WHILE( flag_higher[ch] == 0 )
267 : {
268 94 : ch = add( ch, 1 );
269 : }
270 6533 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], tmp );
271 6533 : move16();
272 : }
273 :
274 95530 : bitbudget_to_brate( bits_CoreCoder, total_brate, n_ISms );
275 :
276 95530 : diff = 0;
277 95530 : move16();
278 336920 : FOR( ch = 0; ch < n_ISms; ch++ )
279 : {
280 : Word16 limit;
281 :
282 241390 : limit = BITS_MIN_BRATE_SWB_BWE;
283 241390 : move16();
284 241390 : IF( LT_32( element_brate[ch], MIN_BRATE_SWB_STEREO ) ) /* replicate function set_bw() -> check the coded audio band-width */
285 : {
286 19828 : limit = BITS_MIN_BRATE_WB_BWE;
287 19828 : move16();
288 : }
289 221562 : ELSE IF( GE_32( element_brate[ch], SCE_CORE_16k_LOW_LIMIT ) ) /* replicate function set_ACELP_flag() -> it is not intended to switch the ACELP internal sampling rate within an object */
290 : {
291 : /*limit = SCE_CORE_16k_LOW_LIMIT;*/
292 172472 : limit = BITS_ACELP_16k_LOW_LIMIT_1k6;
293 172472 : move16();
294 : }
295 :
296 241390 : IF( EQ_16( ism_imp[ch], ISM_NO_META ) )
297 : {
298 6931 : tmp = BITS_ISM_INACTIVE;
299 6931 : move16();
300 : }
301 234459 : ELSE IF( EQ_16( ism_imp[ch], ISM_LOW_IMP ) )
302 : {
303 : // tmp = (Word16) ( BETA_ISM_LOW_IMP * bits_CoreCoder[ch] );
304 26343 : tmp = extract_l( Mpy_32_32( BETA_ISM_LOW_IMP_Q31, bits_CoreCoder[ch] ) );
305 26343 : tmp = s_max( limit, tmp );
306 : }
307 208116 : ELSE IF( EQ_16( ism_imp[ch], ISM_MEDIUM_IMP ) )
308 : {
309 : // tmp = (Word16) ( BETA_ISM_MEDIUM_IMP * bits_CoreCoder[ch] );
310 67748 : tmp = extract_l( Mpy_32_32( BETA_ISM_MEDIUM_IMP_BY_8_Q31, L_shl( bits_CoreCoder[ch], Q3 ) ) ); // Q0
311 67748 : tmp = s_max( limit, tmp );
312 : }
313 : ELSE /* ism_imp[ch] == ISM_HIGH_IMP */
314 : {
315 140368 : tmp = bits_CoreCoder[ch];
316 140368 : move16();
317 : }
318 :
319 241390 : diff = add( diff, sub( bits_CoreCoder[ch], tmp ) ); // Q0
320 241390 : bits_CoreCoder[ch] = tmp;
321 241390 : move16();
322 : }
323 :
324 95530 : test();
325 95530 : IF( diff > 0 && n_higher > 0 )
326 : {
327 57797 : tmp = BASOP_Util_Divide1616_Scale( diff, n_higher, &exp ); // Q15-exp
328 57797 : tmp = shr( tmp, sub( 15, exp ) ); // Q0
329 224983 : FOR( ch = 0; ch < n_ISms; ch++ )
330 : {
331 167186 : IF( flag_higher[ch] )
332 : {
333 162515 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], tmp );
334 162515 : move16();
335 : }
336 : }
337 :
338 57797 : tmp = diff % n_higher;
339 57797 : move16();
340 57797 : ch = 0;
341 57797 : move16();
342 57834 : WHILE( flag_higher[ch] == 0 )
343 : {
344 37 : ch = add( ch, 1 );
345 : }
346 57797 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], tmp );
347 57797 : move16();
348 : }
349 :
350 : /* verify for the maximum bitrate @12.8kHz core */
351 95530 : diff = 0;
352 95530 : move16();
353 336920 : FOR( ch = 0; ch < n_ISms; ch++ )
354 : {
355 241390 : limit_high = BITS_IVAS_512k;
356 241390 : move16();
357 241390 : if ( LT_32( element_brate[ch], SCE_CORE_16k_LOW_LIMIT ) ) /* replicate function set_ACELP_flag() -> it is not intended to switch the ACELP internal sampling rate within an object */
358 : {
359 68918 : limit_high = BITS_ACELP_12k8_HIGH_LIMIT;
360 68918 : move16();
361 : }
362 :
363 241390 : tmp = s_min( bits_CoreCoder[ch], limit_high );
364 :
365 241390 : diff = add( diff, sub( bits_CoreCoder[ch], tmp ) );
366 241390 : bits_CoreCoder[ch] = tmp;
367 241390 : move16();
368 : }
369 :
370 : /* limitation to avoid too high bitrate in one active TCX channel */
371 95530 : test();
372 95530 : IF( GE_32( element_brate[0], SCE_CORE_16k_LOW_LIMIT ) && LE_32( element_brate[0], IVAS_32k ) )
373 : {
374 21593 : diff = 0;
375 21593 : move16();
376 21593 : limit_high = BITS_MAX_BRATE_TCX_32k;
377 21593 : move16();
378 83137 : FOR( ch = 0; ch < n_ISms; ch++ )
379 : {
380 61544 : tmp = s_min( bits_CoreCoder[ch], limit_high );
381 :
382 61544 : diff = add( diff, sub( bits_CoreCoder[ch], tmp ) );
383 61544 : bits_CoreCoder[ch] = tmp;
384 61544 : move16();
385 : }
386 : }
387 :
388 95530 : IF( diff > 0 )
389 : {
390 632 : ch = 0;
391 632 : move16();
392 1608 : FOR( ch = 0; ch < n_ISms; ch++ )
393 : {
394 1608 : IF( flag_higher[ch] == 0 )
395 : {
396 632 : IF( GT_16( diff, limit_high ) )
397 : {
398 0 : diff = add( diff, sub( bits_CoreCoder[ch], limit_high ) );
399 0 : bits_CoreCoder[ch] = limit_high;
400 0 : move16();
401 : }
402 : ELSE
403 : {
404 632 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], diff );
405 632 : move16();
406 :
407 632 : if ( combined_format_flag )
408 : {
409 0 : diff = 0;
410 0 : move16();
411 : }
412 632 : BREAK;
413 : }
414 : }
415 : }
416 : }
417 :
418 95530 : IF( combined_format_flag )
419 : {
420 4714 : IF( diff > 0 )
421 : {
422 0 : FOR( ch = 0; ch < n_ISms; ch++ )
423 : {
424 0 : IF( LE_16( ism_imp[ch], ISM_MEDIUM_IMP ) )
425 : {
426 0 : IF( GT_16( diff, limit_high ) )
427 : {
428 0 : diff = add( diff, sub( bits_CoreCoder[ch], limit_high ) );
429 0 : bits_CoreCoder[ch] = limit_high;
430 0 : move16();
431 : }
432 : ELSE
433 : {
434 0 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], diff );
435 0 : BREAK;
436 : }
437 : }
438 : }
439 : }
440 : }
441 :
442 95530 : bitbudget_to_brate( bits_CoreCoder, total_brate, n_ISms );
443 : }
444 :
445 :
446 96847 : return error;
447 : }
448 :
449 : /*-------------------------------------------------------------------*
450 : * ivas_ism_reset_metadata()
451 : *
452 : * Reset ISM metadata parameters
453 : *-------------------------------------------------------------------*/
454 :
455 3240 : void ivas_ism_reset_metadata(
456 : ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */
457 : )
458 : {
459 3240 : hIsmMeta->azimuth_fx = 0;
460 3240 : move32();
461 3240 : hIsmMeta->elevation_fx = 0;
462 3240 : move32();
463 3240 : hIsmMeta->yaw_fx = 0;
464 3240 : move32();
465 3240 : hIsmMeta->pitch_fx = 0;
466 3240 : move32();
467 3240 : hIsmMeta->radius_fx = ONE_IN_Q9; // Q9
468 3240 : move16();
469 :
470 3240 : hIsmMeta->ism_metadata_flag = 0;
471 3240 : move16();
472 3240 : hIsmMeta->non_diegetic_flag = 0;
473 3240 : move16();
474 :
475 3240 : return;
476 : }
477 :
478 0 : void ivas_ism_reset_metadata_enc(
479 : ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */
480 : )
481 : {
482 0 : hIsmMeta->azimuth_fx = 0;
483 0 : move32();
484 0 : hIsmMeta->elevation_fx = 0;
485 0 : move32();
486 0 : hIsmMeta->yaw_fx = 0;
487 0 : move32();
488 0 : hIsmMeta->pitch_fx = 0;
489 0 : move32();
490 0 : hIsmMeta->radius_fx = ONE_IN_Q9; // Q9
491 0 : move16();
492 0 : hIsmMeta->ism_metadata_flag = 0;
493 0 : move16();
494 0 : hIsmMeta->non_diegetic_flag = 0;
495 0 : move16();
496 :
497 0 : return;
498 : }
499 :
500 :
501 : /*-------------------------------------------------------------------*
502 : * ivas_ism_reset_metadata_API()
503 : *
504 : * Reset ISM metadata parameters
505 : *-------------------------------------------------------------------*/
506 :
507 0 : void ivas_ism_reset_metadata_API(
508 : ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */
509 : )
510 : {
511 0 : ivas_ism_reset_metadata_enc( hIsmMeta );
512 :
513 0 : return;
514 : }
515 :
516 :
517 : /*-------------------------------------------------------------------*
518 : * ism_quant_meta()
519 : *
520 : * three-level uniform scalar quantizer for ISM metadata
521 : *-------------------------------------------------------------------*/
522 :
523 : /*! r: index of the winning codeword */
524 0 : Word16 ism_quant_meta_fx(
525 : const Word32 val, /* i : scalar value to quantize Q22 */
526 : Word32 *valQ, /* o : quantized value Q22 */
527 : const Word32 borders_fx[], /* i : level borders Q22 */
528 : const Word32 q_step_fx, /* i : quantization step Q22 */
529 : const Word32 q_step_border_fx, /* i : quantization step at the border Q22 */
530 : const Word16 cbsize /* i : codebook size */
531 : )
532 : {
533 : Word16 idx, idx_start;
534 : Word32 qlow_fx, step_fx;
535 : Word16 tmp, tmp_e;
536 :
537 0 : IF( LE_32( val, borders_fx[1] ) )
538 : {
539 0 : qlow_fx = borders_fx[0];
540 0 : move32();
541 0 : idx_start = 0;
542 0 : move32();
543 0 : step_fx = q_step_border_fx;
544 0 : move32();
545 : }
546 0 : ELSE IF( LE_32( val, borders_fx[2] ) )
547 : {
548 0 : qlow_fx = borders_fx[1];
549 0 : move32();
550 0 : tmp = BASOP_Util_Divide3232_Scale( L_sub( borders_fx[1], borders_fx[0] ), q_step_border_fx, &tmp_e ); // Q15-tmp_e
551 0 : idx_start = shr( tmp, sub( 15, tmp_e ) ); // Q0
552 0 : step_fx = q_step_fx;
553 0 : move32();
554 : }
555 : ELSE
556 : {
557 0 : qlow_fx = borders_fx[2];
558 0 : move32();
559 0 : tmp = BASOP_Util_Divide3232_Scale( L_add( L_sub( borders_fx[3], borders_fx[2] ), L_sub( q_step_border_fx, ONE_IN_Q22 ) ), q_step_border_fx, &tmp_e ); // Q15-tmp_e
560 0 : idx_start = sub( cbsize, add( 1, shr( tmp, sub( 15, tmp_e ) ) ) ); // Q0
561 0 : step_fx = q_step_border_fx;
562 0 : move32();
563 : }
564 :
565 :
566 0 : tmp = BASOP_Util_Divide3232_Scale( L_sub( val, qlow_fx ), step_fx, &tmp_e ); // Q15-tmp_e
567 0 : tmp = shl( tmp, sub( Q1, sub( 15, tmp_e ) ) ); // Q0
568 0 : tmp = add( tmp, 1 );
569 0 : tmp = shr( tmp, 1 );
570 0 : idx = add( idx_start, s_max( 0, s_min( sub( cbsize, 1 ), tmp ) ) ); // Q0
571 :
572 : // idx = idx_start + (int16_t) max( 0.f, min( cbsize - 1, ( ( val - qlow_fx ) / step_fx + 0.5f ) ) );
573 0 : *valQ = L_add( imult3216( step_fx, sub( idx, idx_start ) ), qlow_fx ); // Q0
574 0 : move32();
575 :
576 0 : return idx;
577 : }
578 :
579 :
580 : /*-------------------------------------------------------------------*
581 : * ism_dequant_meta()
582 : *
583 : * three-level uniform scalar dequantizer for ISM metadata
584 : *-------------------------------------------------------------------*/
585 :
586 : /*! r: dequantized value */
587 637419 : Word32 ism_dequant_meta_fx( /* o : Q22*/
588 : const Word16 idx, /* i : quantizer index */
589 : const Word32 borders_fx[], /* i : level borders Q22*/
590 : const Word32 q_step_fx, /* i : quantization step Q22 */
591 : const Word32 q_step_border_fx, /* i : quantization step at the border Q22*/
592 : const Word16 cbsize /* i : codebook size */
593 : )
594 : {
595 : Word16 idx_start, tmp1, tmp2, exp1, exp2;
596 : Word32 qlow_fx, step_fx, valQ_fx;
597 :
598 637419 : tmp1 = BASOP_Util_Divide3232_Scale( L_shr( L_sub( borders_fx[1], borders_fx[0] ), 21 ), L_shr( q_step_border_fx, 21 ), &exp1 );
599 637419 : tmp1 = shr( tmp1, sub( 15, exp1 ) ); // Q0
600 :
601 637419 : tmp2 = BASOP_Util_Divide3232_Scale( L_shr( L_sub( borders_fx[3], borders_fx[2] ), 21 ), L_shr( q_step_border_fx, 21 ), &exp2 );
602 637419 : tmp2 = shr( tmp2, sub( 15, exp2 ) ); // Q0
603 :
604 :
605 637419 : IF( LE_16( idx, tmp1 ) )
606 : {
607 65414 : qlow_fx = borders_fx[0]; // Q22
608 65414 : idx_start = 0;
609 65414 : step_fx = q_step_border_fx; // Q22
610 :
611 65414 : move32();
612 65414 : move32();
613 65414 : move16();
614 : }
615 572005 : ELSE IF( LE_16( idx, sub( sub( cbsize, 1 ), tmp2 ) ) )
616 : {
617 528075 : qlow_fx = borders_fx[1]; // Q22
618 528075 : idx_start = tmp1;
619 528075 : step_fx = q_step_fx; // Q22
620 :
621 528075 : move32();
622 528075 : move32();
623 528075 : move16();
624 : }
625 : ELSE
626 : {
627 43930 : qlow_fx = borders_fx[2];
628 43930 : idx_start = (Word16) sub( sub( cbsize, 1 ), tmp2 );
629 43930 : step_fx = q_step_border_fx; // Q22
630 :
631 43930 : move32();
632 43930 : move32();
633 43930 : move16();
634 : }
635 :
636 637419 : valQ_fx = L_add( sub( idx, idx_start ) * step_fx, qlow_fx ); // Q22
637 :
638 637419 : return valQ_fx;
639 : }
640 :
641 :
642 : /*---------------------------------------------------------------
643 : * ivas_param_ism_config()
644 : *
645 : *
646 : * ---------------------------------------------------------------*/
647 :
648 168 : void ivas_param_ism_config_fx(
649 : PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i/o: IVAS Param ISM Config Structure */
650 : const Word16 nchan_obj /* i : number of ISM channels */
651 : )
652 : {
653 : Word16 i;
654 :
655 168 : hParamIsm->nbands = MAX_PARAM_ISM_NBANDS;
656 168 : move16();
657 :
658 2016 : FOR( i = 0; i < hParamIsm->nbands; i++ )
659 : {
660 1848 : hParamIsm->nblocks[i] = MAX_PARAM_ISM_NBLOCKS;
661 1848 : move16();
662 : }
663 :
664 : /* for elevation zero compute the max azi quantization indices */
665 762 : FOR( i = 0; i < nchan_obj; i++ )
666 : {
667 594 : hParamIsm->last_az_diff[i] = 0;
668 594 : move16();
669 594 : hParamIsm->last_az_sgn[i] = 1;
670 594 : move16();
671 594 : hParamIsm->last_el_diff[i] = 0;
672 594 : move16();
673 594 : hParamIsm->last_el_sgn[i] = 1;
674 594 : move16();
675 : }
676 :
677 168 : hParamIsm->last_dmx_gain_fx = (Word16) 16384; // 15-1 = Q14
678 168 : move16();
679 168 : hParamIsm->last_dmx_gain_e = 1;
680 168 : move16();
681 168 : set16_fx( hParamIsm->last_cardioid_left_fx, (Word16) 16384, MAX_NUM_OBJECTS ); // Q14
682 :
683 168 : return;
684 : }
685 :
686 : /*---------------------------------------------------------------
687 : * ivas_ism_mode_select()
688 : *
689 : * selects the ISM mode base on bitrate and number of objects
690 : * ---------------------------------------------------------------*/
691 :
692 : /*! r : ISM format mode */
693 181902 : ISM_MODE ivas_ism_mode_select(
694 : const Word16 nchan_inp, /* i : number of input objects */
695 : const Word32 ivas_total_brate /* i : IVAS total bitrate */
696 : )
697 : {
698 181902 : ISM_MODE ism_mode = ISM_MODE_NONE;
699 181902 : move32();
700 :
701 181902 : test();
702 181902 : IF( GT_16( nchan_inp, 2 ) && LE_32( ivas_total_brate, ACELP_32k ) )
703 : {
704 31298 : ism_mode = ISM_MODE_PARAM;
705 31298 : move32();
706 : }
707 : ELSE
708 : {
709 150604 : ism_mode = ISM_MODE_DISC;
710 150604 : move32();
711 : }
712 :
713 181902 : return ism_mode;
714 : }
715 :
716 : /*---------------------------------------------------------------
717 : * ivas_ism_metadata_close()
718 : *
719 : * Deallocate ISM metadata handles
720 : * ---------------------------------------------------------------*/
721 :
722 2525 : void ivas_ism_metadata_close(
723 : ISM_METADATA_HANDLE hIsmMetaData[], /* i/o: object metadata handles */
724 : const Word16 first_idx /* i : index of first handle to deallocate */
725 : )
726 : {
727 : Word16 n;
728 :
729 2525 : test();
730 2525 : IF( hIsmMetaData == NULL || *hIsmMetaData == NULL )
731 : {
732 650 : return;
733 : }
734 :
735 7481 : FOR( n = first_idx; n < MAX_NUM_OBJECTS; n++ )
736 : {
737 5606 : IF( hIsmMetaData[n] != NULL )
738 : {
739 3240 : free( hIsmMetaData[n] );
740 3240 : hIsmMetaData[n] = NULL;
741 : }
742 : }
743 :
744 1875 : return;
745 : }
746 :
747 :
748 : /*-------------------------------------------------------------------*
749 : * update_last_metadata()
750 : *
751 : * Store last metadata values
752 : *-------------------------------------------------------------------*/
753 111732 : void update_last_metadata_fx(
754 : const Word16 nchan_ism, /* i : number of objects */
755 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
756 : const Word16 updt_flag[] /* i : last metadata update flag */
757 : )
758 : {
759 : Word16 ch;
760 431517 : FOR( ch = 0; ch < nchan_ism; ch++ )
761 : {
762 319785 : IF( EQ_16( updt_flag[ch], 1 ) )
763 : {
764 319785 : hIsmMeta[ch]->last_azimuth_fx = hIsmMeta[ch]->azimuth_fx; // Q22
765 319785 : move32();
766 319785 : hIsmMeta[ch]->last_elevation_fx = hIsmMeta[ch]->elevation_fx; // Q22
767 319785 : move32();
768 : }
769 : }
770 :
771 111732 : return;
772 : }
773 :
774 : /*----------------------------------------------------------------*
775 : * ivas_get_ism_sid_quan_bitbudget()
776 : *
777 : * Set quantization bits based on the number of coded objects
778 : *----------------------------------------------------------------*/
779 :
780 550 : void ivas_get_ism_sid_quan_bitbudget_fx(
781 : const Word16 nchan_ism, /* i : number of objects */
782 : Word16 *nBits_azimuth, /* o : number of Q bits for azimuth */
783 : Word16 *nBits_elevation, /* o : number of Q bits for elevation */
784 : Word32 *q_step_fx, /* o : quantization step Q22*/
785 : Word32 *q_step_border_fx, /* o : quantization step at the border Q22*/
786 : Word16 *nBits_coh, /* o : number of Q bits for coherence */
787 : Word16 *nBits_sce_id /* o : number of Q bits for sce_id_dtx */
788 : )
789 : {
790 550 : *nBits_azimuth = ISM_DTX_AZI_BITS_HIGH;
791 550 : *nBits_elevation = ISM_DTX_ELE_BITS_HIGH;
792 550 : *q_step_fx = ISM_Q_STEP_HIGH_FX; // Q22
793 550 : *q_step_border_fx = ISM_Q_STEP_BORDER_HIGH_FX; // Q22
794 550 : *nBits_coh = ISM_DTX_COH_SCA_BITS;
795 550 : *nBits_sce_id = 1;
796 :
797 550 : move16();
798 550 : move16();
799 550 : move16();
800 550 : move16();
801 550 : move32();
802 550 : move32();
803 :
804 550 : IF( GE_16( nchan_ism, 3 ) )
805 : {
806 385 : *nBits_azimuth = ISM_DTX_AZI_BITS_LOW;
807 385 : *nBits_elevation = ISM_DTX_ELE_BITS_LOW;
808 385 : *q_step_fx = ISM_Q_STEP_LOW_FX; // Q22
809 385 : *q_step_border_fx = ISM_Q_STEP_BORDER_LOW_FX; // Q22
810 385 : *nBits_sce_id = 2;
811 :
812 385 : move16();
813 385 : move16();
814 385 : move16();
815 385 : move16();
816 385 : move32();
817 : }
818 :
819 550 : return;
820 : }
|