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 993858 : 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 3512256 : FOR( i = 0; i < N; i++ )
78 : {
79 2518398 : y[i] = L_mult0( FRAMES_PER_SEC, x[i] );
80 2518398 : move32();
81 : }
82 :
83 993858 : return;
84 : }
85 :
86 :
87 : /*-------------------------------------------------------------------*
88 : * ivas_ism_config()
89 : *
90 : * Configure audio objects coding
91 : *-------------------------------------------------------------------*/
92 :
93 257680 : 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 257680 : 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 257680 : error = IVAS_ERR_OK;
117 257680 : move32();
118 257680 : IF( combined_format_flag )
119 : {
120 49772 : n_ISms = nchan_ism;
121 49772 : move16();
122 : }
123 : ELSE
124 : {
125 207908 : n_ISms = nchan_transport;
126 207908 : move16();
127 : }
128 :
129 : /* initialization */
130 257680 : ism_metadata_flag_global = 0;
131 257680 : move16();
132 257680 : bits_side = 0;
133 257680 : move16();
134 257680 : IF( hIsmMeta != NULL )
135 : {
136 881131 : FOR( ch = 0; ch < n_ISms; ch++ )
137 : {
138 630505 : ism_metadata_flag_global = s_or( ism_metadata_flag_global, ism_imp[ch] );
139 : }
140 : }
141 :
142 : /* decision about bitrates per channel */
143 257680 : 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 49772 : bits_ism = extract_l( Mpy_32_32_r( ONE_BY_FRAMES_PER_SEC_Q31, ism_total_brate ) ); // Q0
148 49772 : tmp1 = extract_h( Mpy_32_16_r( one_by_q_level[n_ISms], bits_ism ) );
149 49772 : set16_fx( bits_element, tmp1, n_ISms );
150 49772 : bits_element[n_ISms - 1] = add( bits_element[n_ISms - 1], bits_ism % n_ISms ); // Q0
151 49772 : 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 207908 : bits_ism = extract_l( Mpy_32_32_r( ONE_BY_FRAMES_PER_SEC_Q31, ism_total_brate ) ); // Q0
160 207908 : tmp1 = extract_h( Mpy_32_16_r( one_by_q_level[n_ISms], bits_ism ) );
161 207908 : set16_fx( bits_element, tmp1, n_ISms );
162 207908 : bits_element[n_ISms - 1] = add( bits_element[n_ISms - 1], bits_ism % n_ISms ); // Q0
163 207908 : move16();
164 207908 : bitbudget_to_brate( bits_element, element_brate, n_ISms );
165 :
166 : /* count ISm common signaling bits */
167 207908 : IF( hIsmMeta != NULL )
168 : {
169 204946 : nb_bits_metadata[0] = add( nb_bits_metadata[0], add( imult1616( n_ISms, ISM_METADATA_FLAG_BITS ), nchan_ism ) );
170 204946 : move16();
171 :
172 204946 : IF( GE_32( ism_total_brate, ISM_EXTENDED_METADATA_BRATE ) )
173 : {
174 117299 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_EXTENDED_METADATA_BITS );
175 117299 : move16();
176 :
177 117299 : IF( ism_extended_metadata_flag )
178 : {
179 16182 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_IS_NDP_BITS );
180 16182 : move16();
181 : }
182 : }
183 :
184 739813 : FOR( ch = 0; ch < n_ISms; ch++ )
185 : {
186 534867 : IF( null_metadata_flag[ch] )
187 : {
188 9340 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_MD_FLAG_BITS );
189 9340 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_FLAG_BITS );
190 :
191 9340 : move16();
192 9340 : move16();
193 : }
194 : ELSE
195 : {
196 525527 : IF( ism_imp[ch] == ISM_NO_META )
197 : {
198 13622 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_MD_FLAG_BITS );
199 13622 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_INACTIVE_FLAG_BITS );
200 :
201 13622 : move16();
202 13622 : move16();
203 : }
204 : }
205 : }
206 : }
207 : }
208 :
209 : /* split metadata bitbudget equally between channels */
210 257680 : IF( nb_bits_metadata != NULL )
211 : {
212 250626 : bits_side = sum16_fx( nb_bits_metadata, n_ISms );
213 250626 : tmp1 = BASOP_Util_Divide1616_Scale( bits_side, n_ISms, &exp ); // Q15 - exp
214 250626 : set16_fx( nb_bits_metadata, shr( tmp1, sub( 15, exp ) ), n_ISms );
215 250626 : nb_bits_metadata[n_ISms - 1] = add( nb_bits_metadata[n_ISms - 1], bits_side % n_ISms ); // Q0
216 250626 : move16();
217 250626 : v_sub_16( bits_element, nb_bits_metadata, bits_CoreCoder, n_ISms );
218 250626 : bitbudget_to_brate( bits_CoreCoder, total_brate, n_ISms );
219 :
220 250626 : Copy( nb_bits_metadata, nb_bits_metadata, n_ISms );
221 : }
222 :
223 : /* assign less CoreCoder bit-budget to inactive streams (at least one stream must be active) */
224 257680 : IF( ism_metadata_flag_global )
225 : {
226 : Word16 diff, n_higher, flag_higher[MAX_NUM_OBJECTS];
227 :
228 249656 : set16_fx( flag_higher, 1, MAX_NUM_OBJECTS );
229 :
230 249656 : diff = 0;
231 249656 : move16();
232 878327 : FOR( ch = 0; ch < n_ISms; ch++ )
233 : {
234 628671 : IF( EQ_16( ism_imp[ch], ISM_NO_META ) )
235 : {
236 16086 : diff = add( diff, sub( bits_CoreCoder[ch], BITS_ISM_INACTIVE ) );
237 16086 : bits_CoreCoder[ch] = BITS_ISM_INACTIVE;
238 16086 : flag_higher[ch] = 0;
239 16086 : move16();
240 16086 : move16();
241 : }
242 : }
243 :
244 249656 : n_higher = sum16_fx( flag_higher, n_ISms );
245 :
246 249656 : test();
247 249656 : IF( diff > 0 && n_higher > 0 )
248 : {
249 15258 : tmp = BASOP_Util_Divide1616_Scale( diff, n_higher, &exp );
250 15258 : tmp = shr( tmp, sub( 15, exp ) );
251 71666 : FOR( ch = 0; ch < n_ISms; ch++ )
252 : {
253 56408 : IF( flag_higher[ch] )
254 : {
255 40322 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], tmp );
256 40322 : move16();
257 : }
258 : }
259 :
260 15258 : tmp = diff % n_higher;
261 15258 : move16();
262 15258 : ch = 0;
263 15258 : move16();
264 15582 : WHILE( flag_higher[ch] == 0 )
265 : {
266 324 : ch = add( ch, 1 );
267 : }
268 15258 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], tmp );
269 15258 : move16();
270 : }
271 :
272 249656 : bitbudget_to_brate( bits_CoreCoder, total_brate, n_ISms );
273 :
274 249656 : diff = 0;
275 249656 : move16();
276 878327 : FOR( ch = 0; ch < n_ISms; ch++ )
277 : {
278 : Word16 limit;
279 :
280 628671 : limit = BITS_MIN_BRATE_SWB_BWE;
281 628671 : move16();
282 628671 : IF( LT_32( element_brate[ch], MIN_BRATE_SWB_STEREO ) ) /* replicate function set_bw() -> check the coded audio band-width */
283 : {
284 59896 : limit = BITS_MIN_BRATE_WB_BWE;
285 59896 : move16();
286 : }
287 568775 : 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 */
288 : {
289 : /*limit = SCE_CORE_16k_LOW_LIMIT;*/
290 440925 : limit = BITS_ACELP_16k_LOW_LIMIT_1k6;
291 440925 : move16();
292 : }
293 :
294 628671 : IF( EQ_16( ism_imp[ch], ISM_NO_META ) )
295 : {
296 16086 : tmp = BITS_ISM_INACTIVE;
297 16086 : move16();
298 : }
299 612585 : ELSE IF( EQ_16( ism_imp[ch], ISM_LOW_IMP ) )
300 : {
301 : // tmp = (Word16) ( BETA_ISM_LOW_IMP * bits_CoreCoder[ch] );
302 77728 : tmp = extract_l( Mpy_32_32( BETA_ISM_LOW_IMP_Q31, bits_CoreCoder[ch] ) );
303 77728 : tmp = s_max( limit, tmp );
304 : }
305 534857 : ELSE IF( EQ_16( ism_imp[ch], ISM_MEDIUM_IMP ) )
306 : {
307 : // tmp = (Word16) ( BETA_ISM_MEDIUM_IMP * bits_CoreCoder[ch] );
308 170203 : tmp = extract_l( Mpy_32_32( BETA_ISM_MEDIUM_IMP_BY_8_Q31, L_shl( bits_CoreCoder[ch], Q3 ) ) ); // Q0
309 170203 : tmp = s_max( limit, tmp );
310 : }
311 : ELSE /* ism_imp[ch] == ISM_HIGH_IMP */
312 : {
313 364654 : tmp = bits_CoreCoder[ch];
314 364654 : move16();
315 : }
316 :
317 628671 : diff = add( diff, sub( bits_CoreCoder[ch], tmp ) ); // Q0
318 628671 : bits_CoreCoder[ch] = tmp;
319 628671 : move16();
320 : }
321 :
322 249656 : test();
323 249656 : IF( diff > 0 && n_higher > 0 )
324 : {
325 151877 : tmp = BASOP_Util_Divide1616_Scale( diff, n_higher, &exp ); // Q15-exp
326 151877 : tmp = shr( tmp, sub( 15, exp ) ); // Q0
327 586027 : FOR( ch = 0; ch < n_ISms; ch++ )
328 : {
329 434150 : IF( flag_higher[ch] )
330 : {
331 422863 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], tmp );
332 422863 : move16();
333 : }
334 : }
335 :
336 151877 : tmp = diff % n_higher;
337 151877 : move16();
338 151877 : ch = 0;
339 151877 : move16();
340 152043 : WHILE( flag_higher[ch] == 0 )
341 : {
342 166 : ch = add( ch, 1 );
343 : }
344 151877 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], tmp );
345 151877 : move16();
346 : }
347 :
348 : /* verify for the maximum bitrate @12.8kHz core */
349 249656 : diff = 0;
350 249656 : move16();
351 878327 : FOR( ch = 0; ch < n_ISms; ch++ )
352 : {
353 628671 : limit_high = BITS_IVAS_512k;
354 628671 : move16();
355 628671 : 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 */
356 : {
357 187746 : limit_high = BITS_ACELP_12k8_HIGH_LIMIT;
358 187746 : move16();
359 : }
360 :
361 628671 : tmp = s_min( bits_CoreCoder[ch], limit_high );
362 :
363 628671 : diff = add( diff, sub( bits_CoreCoder[ch], tmp ) );
364 628671 : bits_CoreCoder[ch] = tmp;
365 628671 : move16();
366 : }
367 :
368 : /* limitation to avoid too high bitrate in one active TCX channel */
369 249656 : test();
370 249656 : IF( GE_32( element_brate[0], SCE_CORE_16k_LOW_LIMIT ) && LE_32( element_brate[0], IVAS_32k ) )
371 : {
372 62460 : diff = 0;
373 62460 : move16();
374 62460 : limit_high = BITS_MAX_BRATE_TCX_32k;
375 62460 : move16();
376 250647 : FOR( ch = 0; ch < n_ISms; ch++ )
377 : {
378 188187 : tmp = s_min( bits_CoreCoder[ch], limit_high );
379 :
380 188187 : diff = add( diff, sub( bits_CoreCoder[ch], tmp ) );
381 188187 : bits_CoreCoder[ch] = tmp;
382 188187 : move16();
383 : }
384 : }
385 :
386 249656 : IF( diff > 0 )
387 : {
388 1462 : ch = 0;
389 1462 : move16();
390 3766 : FOR( ch = 0; ch < n_ISms; ch++ )
391 : {
392 3766 : IF( flag_higher[ch] == 0 )
393 : {
394 1462 : IF( GT_16( diff, limit_high ) )
395 : {
396 0 : diff = add( diff, sub( bits_CoreCoder[ch], limit_high ) );
397 0 : bits_CoreCoder[ch] = limit_high;
398 0 : move16();
399 : }
400 : ELSE
401 : {
402 1462 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], diff );
403 1462 : move16();
404 :
405 1462 : if ( combined_format_flag )
406 : {
407 0 : diff = 0;
408 0 : move16();
409 : }
410 1462 : BREAK;
411 : }
412 : }
413 : }
414 : }
415 :
416 249656 : IF( combined_format_flag )
417 : {
418 45064 : IF( diff > 0 )
419 : {
420 0 : FOR( ch = 0; ch < n_ISms; ch++ )
421 : {
422 0 : IF( LE_16( ism_imp[ch], ISM_MEDIUM_IMP ) )
423 : {
424 0 : IF( GT_16( diff, limit_high ) )
425 : {
426 0 : diff = add( diff, sub( bits_CoreCoder[ch], limit_high ) );
427 0 : bits_CoreCoder[ch] = limit_high;
428 0 : move16();
429 : }
430 : ELSE
431 : {
432 0 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], diff );
433 0 : BREAK;
434 : }
435 : }
436 : }
437 : }
438 : }
439 :
440 249656 : bitbudget_to_brate( bits_CoreCoder, total_brate, n_ISms );
441 : }
442 :
443 :
444 257680 : return error;
445 : }
446 :
447 : /*-------------------------------------------------------------------*
448 : * ivas_ism_reset_metadata()
449 : *
450 : * Reset ISM metadata parameters
451 : *-------------------------------------------------------------------*/
452 :
453 25275 : void ivas_ism_reset_metadata(
454 : ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */
455 : )
456 : {
457 25275 : hIsmMeta->azimuth_fx = 0;
458 25275 : move32();
459 25275 : hIsmMeta->elevation_fx = 0;
460 25275 : move32();
461 25275 : hIsmMeta->yaw_fx = 0;
462 25275 : move32();
463 25275 : hIsmMeta->pitch_fx = 0;
464 25275 : move32();
465 25275 : hIsmMeta->radius_fx = ONE_IN_Q9; // Q9
466 25275 : move16();
467 :
468 25275 : hIsmMeta->ism_metadata_flag = 0;
469 25275 : move16();
470 25275 : hIsmMeta->non_diegetic_flag = 0;
471 25275 : move16();
472 :
473 25275 : hIsmMeta->edited_gain_fx = ONE_IN_Q29;
474 25275 : move32();
475 25275 : hIsmMeta->edited_azimuth_fx = 0;
476 25275 : move32();
477 25275 : hIsmMeta->edited_elevation_fx = 0;
478 25275 : move32();
479 25275 : hIsmMeta->edited_pitch_fx = 0;
480 25275 : move32();
481 25275 : hIsmMeta->edited_yaw_fx = 0;
482 25275 : move32();
483 25275 : hIsmMeta->edited_radius_fx = ONE_IN_Q9;
484 25275 : move32();
485 25275 : hIsmMeta->gain_fx = ONE_IN_Q29;
486 25275 : move32();
487 25275 : hIsmMeta->non_diegetic_flag = 0;
488 25275 : move16();
489 :
490 25275 : return;
491 : }
492 :
493 6474 : void ivas_ism_reset_metadata_enc(
494 : ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */
495 : )
496 : {
497 6474 : hIsmMeta->azimuth_fx = 0;
498 6474 : move32();
499 6474 : hIsmMeta->elevation_fx = 0;
500 6474 : move32();
501 6474 : hIsmMeta->yaw_fx = 0;
502 6474 : move32();
503 6474 : hIsmMeta->pitch_fx = 0;
504 6474 : move32();
505 6474 : hIsmMeta->radius_fx = ONE_IN_Q9; // Q9
506 6474 : move16();
507 6474 : hIsmMeta->ism_metadata_flag = 0;
508 6474 : move16();
509 6474 : hIsmMeta->non_diegetic_flag = 0;
510 6474 : move16();
511 :
512 6474 : return;
513 : }
514 :
515 :
516 : /*-------------------------------------------------------------------*
517 : * ivas_ism_reset_metadata_API()
518 : *
519 : * Reset ISM metadata parameters
520 : *-------------------------------------------------------------------*/
521 :
522 6000 : void ivas_ism_reset_metadata_API(
523 : ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */
524 : )
525 : {
526 6000 : ivas_ism_reset_metadata_enc( hIsmMeta );
527 :
528 6000 : return;
529 : }
530 :
531 :
532 : /*-------------------------------------------------------------------*
533 : * ism_quant_meta()
534 : *
535 : * three-level uniform scalar quantizer for ISM metadata
536 : *-------------------------------------------------------------------*/
537 :
538 : /*! r: index of the winning codeword */
539 888143 : Word16 ism_quant_meta_fx(
540 : const Word32 val, /* i : scalar value to quantize Q22 */
541 : Word32 *valQ, /* o : quantized value Q22 */
542 : const Word32 borders_fx[], /* i : level borders Q22 */
543 : const Word32 q_step_fx, /* i : quantization step Q22 */
544 : const Word32 q_step_border_fx, /* i : quantization step at the border Q22 */
545 : const Word16 cbsize /* i : codebook size */
546 : )
547 : {
548 : Word16 idx, idx_start;
549 : Word32 qlow_fx, step_fx;
550 : Word16 tmp, tmp_e;
551 :
552 888143 : IF( LE_32( val, borders_fx[1] ) )
553 : {
554 68373 : qlow_fx = borders_fx[0];
555 68373 : move32();
556 68373 : idx_start = 0;
557 68373 : move32();
558 68373 : step_fx = q_step_border_fx;
559 68373 : move32();
560 : }
561 819770 : ELSE IF( LE_32( val, borders_fx[2] ) )
562 : {
563 742273 : qlow_fx = borders_fx[1];
564 742273 : move32();
565 742273 : tmp = BASOP_Util_Divide3232_Scale( L_sub( borders_fx[1], borders_fx[0] ), q_step_border_fx, &tmp_e ); // Q15-tmp_e
566 742273 : idx_start = shr( tmp, sub( 15, tmp_e ) ); // Q0
567 742273 : step_fx = q_step_fx;
568 742273 : move32();
569 : }
570 : ELSE
571 : {
572 77497 : qlow_fx = borders_fx[2];
573 77497 : move32();
574 77497 : 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
575 77497 : idx_start = sub( cbsize, add( 1, shr( tmp, sub( 15, tmp_e ) ) ) ); // Q0
576 77497 : step_fx = q_step_border_fx;
577 77497 : move32();
578 : }
579 :
580 :
581 888143 : tmp = BASOP_Util_Divide3232_Scale( L_sub( val, qlow_fx ), step_fx, &tmp_e ); // Q15-tmp_e
582 888143 : tmp = shl( tmp, sub( Q1, sub( 15, tmp_e ) ) ); // Q0
583 888143 : tmp = add( tmp, 1 );
584 888143 : tmp = shr( tmp, 1 );
585 888143 : idx = add( idx_start, s_max( 0, s_min( sub( cbsize, 1 ), tmp ) ) ); // Q0
586 :
587 : // idx = idx_start + (int16_t) max( 0.f, min( cbsize - 1, ( ( val - qlow_fx ) / step_fx + 0.5f ) ) );
588 888143 : *valQ = L_add( imult3216( step_fx, sub( idx, idx_start ) ), qlow_fx ); // Q0
589 888143 : move32();
590 :
591 888143 : return idx;
592 : }
593 :
594 :
595 : /*-------------------------------------------------------------------*
596 : * ism_dequant_meta()
597 : *
598 : * three-level uniform scalar dequantizer for ISM metadata
599 : *-------------------------------------------------------------------*/
600 :
601 : /*! r: dequantized value */
602 924077 : Word32 ism_dequant_meta_fx( /* o : Q22*/
603 : const Word16 idx, /* i : quantizer index */
604 : const Word32 borders_fx[], /* i : level borders Q22*/
605 : const Word32 q_step_fx, /* i : quantization step Q22 */
606 : const Word32 q_step_border_fx, /* i : quantization step at the border Q22*/
607 : const Word16 cbsize /* i : codebook size */
608 : )
609 : {
610 : Word16 idx_start, tmp1, tmp2, exp1, exp2;
611 : Word32 qlow_fx, step_fx, valQ_fx;
612 :
613 924077 : tmp1 = BASOP_Util_Divide3232_Scale( L_shr( L_sub( borders_fx[1], borders_fx[0] ), 21 ), L_shr( q_step_border_fx, 21 ), &exp1 );
614 924077 : tmp1 = shr( tmp1, sub( 15, exp1 ) ); // Q0
615 :
616 924077 : tmp2 = BASOP_Util_Divide3232_Scale( L_shr( L_sub( borders_fx[3], borders_fx[2] ), 21 ), L_shr( q_step_border_fx, 21 ), &exp2 );
617 924077 : tmp2 = shr( tmp2, sub( 15, exp2 ) ); // Q0
618 :
619 :
620 924077 : IF( LE_16( idx, tmp1 ) )
621 : {
622 91886 : qlow_fx = borders_fx[0]; // Q22
623 91886 : idx_start = 0;
624 91886 : step_fx = q_step_border_fx; // Q22
625 :
626 91886 : move32();
627 91886 : move32();
628 91886 : move16();
629 : }
630 832191 : ELSE IF( LE_16( idx, sub( sub( cbsize, 1 ), tmp2 ) ) )
631 : {
632 767064 : qlow_fx = borders_fx[1]; // Q22
633 767064 : idx_start = tmp1;
634 767064 : step_fx = q_step_fx; // Q22
635 :
636 767064 : move32();
637 767064 : move32();
638 767064 : move16();
639 : }
640 : ELSE
641 : {
642 65127 : qlow_fx = borders_fx[2];
643 65127 : idx_start = (Word16) sub( sub( cbsize, 1 ), tmp2 );
644 65127 : step_fx = q_step_border_fx; // Q22
645 :
646 65127 : move32();
647 65127 : move32();
648 65127 : move16();
649 : }
650 :
651 924077 : valQ_fx = L_add( sub( idx, idx_start ) * step_fx, qlow_fx ); // Q22
652 :
653 924077 : return valQ_fx;
654 : }
655 :
656 :
657 : /*---------------------------------------------------------------
658 : * ivas_param_ism_config()
659 : *
660 : *
661 : * ---------------------------------------------------------------*/
662 :
663 696 : void ivas_param_ism_config_fx(
664 : PARAM_ISM_CONFIG_HANDLE hParamIsm, /* i/o: IVAS Param ISM Config Structure */
665 : const Word16 nchan_obj /* i : number of ISM channels */
666 : )
667 : {
668 : Word16 i;
669 :
670 696 : hParamIsm->nbands = MAX_PARAM_ISM_NBANDS;
671 696 : move16();
672 :
673 8352 : FOR( i = 0; i < hParamIsm->nbands; i++ )
674 : {
675 7656 : hParamIsm->nblocks[i] = MAX_PARAM_ISM_NBLOCKS;
676 7656 : move16();
677 : }
678 :
679 : /* for elevation zero compute the max azi quantization indices */
680 3322 : FOR( i = 0; i < nchan_obj; i++ )
681 : {
682 2626 : hParamIsm->last_az_diff[i] = 0;
683 2626 : move16();
684 2626 : hParamIsm->last_az_sgn[i] = 1;
685 2626 : move16();
686 2626 : hParamIsm->last_el_diff[i] = 0;
687 2626 : move16();
688 2626 : hParamIsm->last_el_sgn[i] = 1;
689 2626 : move16();
690 : }
691 :
692 696 : hParamIsm->last_dmx_gain_fx = (Word16) 16384; // 15-1 = Q14
693 696 : move16();
694 696 : hParamIsm->last_dmx_gain_e = 1;
695 696 : move16();
696 696 : set16_fx( hParamIsm->last_cardioid_left_fx, (Word16) 16384, MAX_NUM_OBJECTS ); // Q14
697 :
698 696 : return;
699 : }
700 :
701 : /*---------------------------------------------------------------
702 : * ivas_ism_mode_select()
703 : *
704 : * selects the ISM mode base on bitrate and number of objects
705 : * ---------------------------------------------------------------*/
706 :
707 : /*! r : ISM format mode */
708 410612 : ISM_MODE ivas_ism_mode_select(
709 : const Word16 nchan_inp, /* i : number of input objects */
710 : const Word32 ivas_total_brate /* i : IVAS total bitrate */
711 : )
712 : {
713 410612 : ISM_MODE ism_mode = ISM_MODE_NONE;
714 410612 : move32();
715 :
716 410612 : test();
717 410612 : IF( GT_16( nchan_inp, 2 ) && LE_32( ivas_total_brate, ACELP_32k ) )
718 : {
719 81875 : ism_mode = ISM_MODE_PARAM;
720 81875 : move32();
721 : }
722 : ELSE
723 : {
724 328737 : ism_mode = ISM_MODE_DISC;
725 328737 : move32();
726 : }
727 :
728 410612 : return ism_mode;
729 : }
730 :
731 : /*---------------------------------------------------------------
732 : * ivas_ism_metadata_close()
733 : *
734 : * Deallocate ISM metadata handles
735 : * ---------------------------------------------------------------*/
736 :
737 1488 : void ivas_ism_metadata_close(
738 : ISM_METADATA_HANDLE hIsmMetaData[], /* i/o: object metadata handles */
739 : const Word16 first_idx /* i : index of first handle to deallocate */
740 : )
741 : {
742 : Word16 n;
743 :
744 1488 : test();
745 1488 : IF( hIsmMetaData == NULL || *hIsmMetaData == NULL )
746 : {
747 984 : return;
748 : }
749 :
750 2520 : FOR( n = first_idx; n < MAX_NUM_OBJECTS; n++ )
751 : {
752 2016 : IF( hIsmMetaData[n] != NULL )
753 : {
754 1551 : free( hIsmMetaData[n] );
755 1551 : hIsmMetaData[n] = NULL;
756 : }
757 : }
758 :
759 504 : return;
760 : }
761 :
762 :
763 : /*-------------------------------------------------------------------*
764 : * update_last_metadata()
765 : *
766 : * Store last metadata values
767 : *-------------------------------------------------------------------*/
768 301828 : void update_last_metadata_fx(
769 : const Word16 nchan_ism, /* i : number of objects */
770 : ISM_METADATA_HANDLE hIsmMeta[], /* i/o: ISM metadata handles */
771 : const Word16 updt_flag[] /* i : last metadata update flag */
772 : )
773 : {
774 : Word16 ch;
775 1158293 : FOR( ch = 0; ch < nchan_ism; ch++ )
776 : {
777 856465 : IF( EQ_16( updt_flag[ch], 1 ) )
778 : {
779 851319 : hIsmMeta[ch]->last_azimuth_fx = hIsmMeta[ch]->azimuth_fx; // Q22
780 851319 : move32();
781 851319 : hIsmMeta[ch]->last_elevation_fx = hIsmMeta[ch]->elevation_fx; // Q22
782 851319 : move32();
783 : }
784 : }
785 :
786 301828 : return;
787 : }
788 :
789 : /*----------------------------------------------------------------*
790 : * ivas_get_ism_sid_quan_bitbudget()
791 : *
792 : * Set quantization bits based on the number of coded objects
793 : *----------------------------------------------------------------*/
794 :
795 3510 : void ivas_get_ism_sid_quan_bitbudget_fx(
796 : const Word16 nchan_ism, /* i : number of objects */
797 : Word16 *nBits_azimuth, /* o : number of Q bits for azimuth */
798 : Word16 *nBits_elevation, /* o : number of Q bits for elevation */
799 : Word32 *q_step_fx, /* o : quantization step Q22*/
800 : Word32 *q_step_border_fx, /* o : quantization step at the border Q22*/
801 : Word16 *nBits_coh, /* o : number of Q bits for coherence */
802 : Word16 *nBits_sce_id /* o : number of Q bits for sce_id_dtx */
803 : )
804 : {
805 3510 : *nBits_azimuth = ISM_DTX_AZI_BITS_HIGH;
806 3510 : *nBits_elevation = ISM_DTX_ELE_BITS_HIGH;
807 3510 : *q_step_fx = ISM_Q_STEP_HIGH_FX; // Q22
808 3510 : *q_step_border_fx = ISM_Q_STEP_BORDER_HIGH_FX; // Q22
809 3510 : *nBits_coh = ISM_DTX_COH_SCA_BITS;
810 3510 : *nBits_sce_id = 1;
811 :
812 3510 : move16();
813 3510 : move16();
814 3510 : move16();
815 3510 : move16();
816 3510 : move32();
817 3510 : move32();
818 :
819 3510 : IF( GE_16( nchan_ism, 3 ) )
820 : {
821 2046 : *nBits_azimuth = ISM_DTX_AZI_BITS_LOW;
822 2046 : *nBits_elevation = ISM_DTX_ELE_BITS_LOW;
823 2046 : *q_step_fx = ISM_Q_STEP_LOW_FX; // Q22
824 2046 : *q_step_border_fx = ISM_Q_STEP_BORDER_LOW_FX; // Q22
825 2046 : *nBits_sce_id = 2;
826 :
827 2046 : move16();
828 2046 : move16();
829 2046 : move16();
830 2046 : move16();
831 2046 : move32();
832 : }
833 :
834 3510 : return;
835 : }
|