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