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 809970 : 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 2876950 : FOR( i = 0; i < N; i++ )
78 : {
79 2066980 : y[i] = L_mult0( FRAMES_PER_SEC, x[i] );
80 2066980 : move32();
81 : }
82 :
83 809970 : return;
84 : }
85 :
86 :
87 : /*-------------------------------------------------------------------*
88 : * ivas_ism_config()
89 : *
90 : * Configure audio objects coding
91 : *-------------------------------------------------------------------*/
92 :
93 205689 : 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 205689 : 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 205689 : error = IVAS_ERR_OK;
117 205689 : move32();
118 205689 : IF( combined_format_flag )
119 : {
120 10789 : n_ISms = nchan_ism;
121 10789 : move16();
122 : }
123 : ELSE
124 : {
125 194900 : n_ISms = nchan_transport;
126 194900 : move16();
127 : }
128 :
129 : /* initialization */
130 205689 : ism_metadata_flag_global = 0;
131 205689 : move16();
132 205689 : bits_side = 0;
133 205689 : move16();
134 205689 : IF( hIsmMeta != NULL )
135 : {
136 718647 : FOR( ch = 0; ch < n_ISms; ch++ )
137 : {
138 516075 : ism_metadata_flag_global = s_or( ism_metadata_flag_global, ism_imp[ch] );
139 : }
140 : }
141 :
142 : /* decision about bitrates per channel */
143 205689 : 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 10789 : bits_ism = extract_l( Mpy_32_32( 42949673, ism_total_brate ) ); // 42949673 is 1/FRAMES_PER_SEC in Q31
148 10789 : tmp1 = BASOP_Util_Divide1616_Scale( bits_ism, n_ISms, &exp ); // Q15 - exp
149 10789 : set16_fx( bits_element, shr( tmp1, sub( 15, exp ) ), n_ISms );
150 10789 : bits_element[n_ISms - 1] = add( bits_element[n_ISms - 1], bits_ism % n_ISms ); // Q0
151 10789 : 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 194900 : bits_ism = extract_l( Mpy_32_32( 42949673, ism_total_brate ) ); // 42949673 is 1/FRAMES_PER_SEC in Q31
162 194900 : tmp1 = BASOP_Util_Divide1616_Scale( bits_ism, n_ISms, &exp ); // Q15 - exp
163 194900 : set16_fx( bits_element, shr( tmp1, sub( 15, exp ) ), n_ISms );
164 194900 : bits_element[n_ISms - 1] = add( bits_element[n_ISms - 1], bits_ism % n_ISms ); // Q0
165 194900 : move16();
166 194900 : bitbudget_to_brate( bits_element, element_brate, n_ISms );
167 :
168 : /* count ISm common signaling bits */
169 194900 : IF( hIsmMeta != NULL )
170 : {
171 192662 : nb_bits_metadata[0] = add( nb_bits_metadata[0], add( imult1616( n_ISms, ISM_METADATA_FLAG_BITS ), nchan_ism ) );
172 192662 : move16();
173 :
174 192662 : IF( GE_32( ism_total_brate, ISM_EXTENDED_METADATA_BRATE ) )
175 : {
176 111552 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_EXTENDED_METADATA_BITS );
177 111552 : move16();
178 :
179 111552 : IF( ism_extended_metadata_flag )
180 : {
181 15246 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_IS_NDP_BITS );
182 15246 : move16();
183 : }
184 : }
185 :
186 689002 : FOR( ch = 0; ch < n_ISms; ch++ )
187 : {
188 496340 : IF( null_metadata_flag[ch] )
189 : {
190 9340 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_MD_FLAG_BITS );
191 9340 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_FLAG_BITS );
192 :
193 9340 : move16();
194 9340 : move16();
195 : }
196 : ELSE
197 : {
198 487000 : IF( ism_imp[ch] == ISM_NO_META )
199 : {
200 12183 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_MD_FLAG_BITS );
201 12183 : nb_bits_metadata[0] = add( nb_bits_metadata[0], ISM_METADATA_INACTIVE_FLAG_BITS );
202 :
203 12183 : move16();
204 12183 : move16();
205 : }
206 : }
207 : }
208 : }
209 : }
210 :
211 : /* split metadata bitbudget equally between channels */
212 205689 : IF( nb_bits_metadata != NULL )
213 : {
214 202572 : bits_side = sum16_fx( nb_bits_metadata, n_ISms );
215 202572 : tmp1 = BASOP_Util_Divide1616_Scale( bits_side, n_ISms, &exp ); // Q15 - exp
216 202572 : set16_fx( nb_bits_metadata, shr( tmp1, sub( 15, exp ) ), n_ISms );
217 202572 : nb_bits_metadata[n_ISms - 1] = add( nb_bits_metadata[n_ISms - 1], bits_side % n_ISms ); // Q0
218 202572 : move16();
219 202572 : v_sub_16( bits_element, nb_bits_metadata, bits_CoreCoder, n_ISms );
220 202572 : bitbudget_to_brate( bits_CoreCoder, total_brate, n_ISms );
221 :
222 202572 : 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 205689 : IF( ism_metadata_flag_global )
227 : {
228 : Word16 diff, n_higher, flag_higher[MAX_NUM_OBJECTS];
229 :
230 202268 : set16_fx( flag_higher, 1, MAX_NUM_OBJECTS );
231 :
232 202268 : diff = 0;
233 202268 : move16();
234 717301 : FOR( ch = 0; ch < n_ISms; ch++ )
235 : {
236 515033 : IF( EQ_16( ism_imp[ch], ISM_NO_META ) )
237 : {
238 14644 : diff = add( diff, sub( bits_CoreCoder[ch], BITS_ISM_INACTIVE ) );
239 14644 : bits_CoreCoder[ch] = BITS_ISM_INACTIVE;
240 14644 : flag_higher[ch] = 0;
241 14644 : move16();
242 14644 : move16();
243 : }
244 : }
245 :
246 202268 : n_higher = sum16_fx( flag_higher, n_ISms );
247 :
248 202268 : test();
249 202268 : IF( diff > 0 && n_higher > 0 )
250 : {
251 13851 : tmp = BASOP_Util_Divide1616_Scale( diff, n_higher, &exp );
252 13851 : tmp = shr( tmp, sub( 15, exp ) );
253 64796 : FOR( ch = 0; ch < n_ISms; ch++ )
254 : {
255 50945 : IF( flag_higher[ch] )
256 : {
257 36301 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], tmp );
258 36301 : move16();
259 : }
260 : }
261 :
262 13851 : tmp = diff % n_higher;
263 13851 : move16();
264 13851 : ch = 0;
265 13851 : move16();
266 14014 : WHILE( flag_higher[ch] == 0 )
267 : {
268 163 : ch = add( ch, 1 );
269 : }
270 13851 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], tmp );
271 13851 : move16();
272 : }
273 :
274 202268 : bitbudget_to_brate( bits_CoreCoder, total_brate, n_ISms );
275 :
276 202268 : diff = 0;
277 202268 : move16();
278 717301 : FOR( ch = 0; ch < n_ISms; ch++ )
279 : {
280 : Word16 limit;
281 :
282 515033 : limit = BITS_MIN_BRATE_SWB_BWE;
283 515033 : move16();
284 515033 : IF( LT_32( element_brate[ch], MIN_BRATE_SWB_STEREO ) ) /* replicate function set_bw() -> check the coded audio band-width */
285 : {
286 48850 : limit = BITS_MIN_BRATE_WB_BWE;
287 48850 : move16();
288 : }
289 466183 : 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 361369 : limit = BITS_ACELP_16k_LOW_LIMIT_1k6;
293 361369 : move16();
294 : }
295 :
296 515033 : IF( EQ_16( ism_imp[ch], ISM_NO_META ) )
297 : {
298 14644 : tmp = BITS_ISM_INACTIVE;
299 14644 : move16();
300 : }
301 500389 : ELSE IF( EQ_16( ism_imp[ch], ISM_LOW_IMP ) )
302 : {
303 : // tmp = (Word16) ( BETA_ISM_LOW_IMP * bits_CoreCoder[ch] );
304 55816 : tmp = extract_l( Mpy_32_32( BETA_ISM_LOW_IMP_Q31, bits_CoreCoder[ch] ) );
305 55816 : tmp = s_max( limit, tmp );
306 : }
307 444573 : ELSE IF( EQ_16( ism_imp[ch], ISM_MEDIUM_IMP ) )
308 : {
309 : // tmp = (Word16) ( BETA_ISM_MEDIUM_IMP * bits_CoreCoder[ch] );
310 142861 : tmp = extract_l( Mpy_32_32( BETA_ISM_MEDIUM_IMP_BY_8_Q31, L_shl( bits_CoreCoder[ch], Q3 ) ) ); // Q0
311 142861 : tmp = s_max( limit, tmp );
312 : }
313 : ELSE /* ism_imp[ch] == ISM_HIGH_IMP */
314 : {
315 301712 : tmp = bits_CoreCoder[ch];
316 301712 : move16();
317 : }
318 :
319 515033 : diff = add( diff, sub( bits_CoreCoder[ch], tmp ) ); // Q0
320 515033 : bits_CoreCoder[ch] = tmp;
321 515033 : move16();
322 : }
323 :
324 202268 : test();
325 202268 : IF( diff > 0 && n_higher > 0 )
326 : {
327 122204 : tmp = BASOP_Util_Divide1616_Scale( diff, n_higher, &exp ); // Q15-exp
328 122204 : tmp = shr( tmp, sub( 15, exp ) ); // Q0
329 477132 : FOR( ch = 0; ch < n_ISms; ch++ )
330 : {
331 354928 : IF( flag_higher[ch] )
332 : {
333 344962 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], tmp );
334 344962 : move16();
335 : }
336 : }
337 :
338 122204 : tmp = diff % n_higher;
339 122204 : move16();
340 122204 : ch = 0;
341 122204 : move16();
342 122247 : WHILE( flag_higher[ch] == 0 )
343 : {
344 43 : ch = add( ch, 1 );
345 : }
346 122204 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], tmp );
347 122204 : move16();
348 : }
349 :
350 : /* verify for the maximum bitrate @12.8kHz core */
351 202268 : diff = 0;
352 202268 : move16();
353 717301 : FOR( ch = 0; ch < n_ISms; ch++ )
354 : {
355 515033 : limit_high = BITS_IVAS_512k;
356 515033 : move16();
357 515033 : 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 153664 : limit_high = BITS_ACELP_12k8_HIGH_LIMIT;
360 153664 : move16();
361 : }
362 :
363 515033 : tmp = s_min( bits_CoreCoder[ch], limit_high );
364 :
365 515033 : diff = add( diff, sub( bits_CoreCoder[ch], tmp ) );
366 515033 : bits_CoreCoder[ch] = tmp;
367 515033 : move16();
368 : }
369 :
370 : /* limitation to avoid too high bitrate in one active TCX channel */
371 202268 : test();
372 202268 : IF( GE_32( element_brate[0], SCE_CORE_16k_LOW_LIMIT ) && LE_32( element_brate[0], IVAS_32k ) )
373 : {
374 46041 : diff = 0;
375 46041 : move16();
376 46041 : limit_high = BITS_MAX_BRATE_TCX_32k;
377 46041 : move16();
378 180126 : FOR( ch = 0; ch < n_ISms; ch++ )
379 : {
380 134085 : tmp = s_min( bits_CoreCoder[ch], limit_high );
381 :
382 134085 : diff = add( diff, sub( bits_CoreCoder[ch], tmp ) );
383 134085 : bits_CoreCoder[ch] = tmp;
384 134085 : move16();
385 : }
386 : }
387 :
388 202268 : IF( diff > 0 )
389 : {
390 1334 : ch = 0;
391 1334 : move16();
392 3446 : FOR( ch = 0; ch < n_ISms; ch++ )
393 : {
394 3446 : IF( flag_higher[ch] == 0 )
395 : {
396 1334 : 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 1334 : bits_CoreCoder[ch] = add( bits_CoreCoder[ch], diff );
405 1334 : move16();
406 :
407 1334 : if ( combined_format_flag )
408 : {
409 0 : diff = 0;
410 0 : move16();
411 : }
412 1334 : BREAK;
413 : }
414 : }
415 : }
416 : }
417 :
418 202268 : IF( combined_format_flag )
419 : {
420 9910 : 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 202268 : bitbudget_to_brate( bits_CoreCoder, total_brate, n_ISms );
443 : }
444 :
445 :
446 205689 : 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 6459 : void ivas_ism_reset_metadata_enc(
479 : ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */
480 : )
481 : {
482 6459 : hIsmMeta->azimuth_fx = 0;
483 6459 : move32();
484 6459 : hIsmMeta->elevation_fx = 0;
485 6459 : move32();
486 6459 : hIsmMeta->yaw_fx = 0;
487 6459 : move32();
488 6459 : hIsmMeta->pitch_fx = 0;
489 6459 : move32();
490 6459 : hIsmMeta->radius_fx = ONE_IN_Q9; // Q9
491 6459 : move16();
492 6459 : hIsmMeta->ism_metadata_flag = 0;
493 6459 : move16();
494 6459 : hIsmMeta->non_diegetic_flag = 0;
495 6459 : move16();
496 :
497 6459 : return;
498 : }
499 :
500 :
501 : /*-------------------------------------------------------------------*
502 : * ivas_ism_reset_metadata_API()
503 : *
504 : * Reset ISM metadata parameters
505 : *-------------------------------------------------------------------*/
506 :
507 6000 : void ivas_ism_reset_metadata_API(
508 : ISM_METADATA_HANDLE hIsmMeta /* i/o: ISM metadata handle */
509 : )
510 : {
511 6000 : ivas_ism_reset_metadata_enc( hIsmMeta );
512 :
513 6000 : 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 763785 : 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 763785 : IF( LE_32( val, borders_fx[1] ) )
538 : {
539 60980 : qlow_fx = borders_fx[0];
540 60980 : move32();
541 60980 : idx_start = 0;
542 60980 : move32();
543 60980 : step_fx = q_step_border_fx;
544 60980 : move32();
545 : }
546 702805 : ELSE IF( LE_32( val, borders_fx[2] ) )
547 : {
548 635302 : qlow_fx = borders_fx[1];
549 635302 : move32();
550 635302 : tmp = BASOP_Util_Divide3232_Scale( L_sub( borders_fx[1], borders_fx[0] ), q_step_border_fx, &tmp_e ); // Q15-tmp_e
551 635302 : idx_start = shr( tmp, sub( 15, tmp_e ) ); // Q0
552 635302 : step_fx = q_step_fx;
553 635302 : move32();
554 : }
555 : ELSE
556 : {
557 67503 : qlow_fx = borders_fx[2];
558 67503 : move32();
559 67503 : 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 67503 : idx_start = sub( cbsize, add( 1, shr( tmp, sub( 15, tmp_e ) ) ) ); // Q0
561 67503 : step_fx = q_step_border_fx;
562 67503 : move32();
563 : }
564 :
565 :
566 763785 : tmp = BASOP_Util_Divide3232_Scale( L_sub( val, qlow_fx ), step_fx, &tmp_e ); // Q15-tmp_e
567 763785 : tmp = shl( tmp, sub( Q1, sub( 15, tmp_e ) ) ); // Q0
568 763785 : tmp = add( tmp, 1 );
569 763785 : tmp = shr( tmp, 1 );
570 763785 : 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 763785 : *valQ = L_add( imult3216( step_fx, sub( idx, idx_start ) ), qlow_fx ); // Q0
574 763785 : move32();
575 :
576 763785 : 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 488 : 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 488 : hParamIsm->nbands = MAX_PARAM_ISM_NBANDS;
656 488 : move16();
657 :
658 5856 : FOR( i = 0; i < hParamIsm->nbands; i++ )
659 : {
660 5368 : hParamIsm->nblocks[i] = MAX_PARAM_ISM_NBLOCKS;
661 5368 : move16();
662 : }
663 :
664 : /* for elevation zero compute the max azi quantization indices */
665 2283 : FOR( i = 0; i < nchan_obj; i++ )
666 : {
667 1795 : hParamIsm->last_az_diff[i] = 0;
668 1795 : move16();
669 1795 : hParamIsm->last_az_sgn[i] = 1;
670 1795 : move16();
671 1795 : hParamIsm->last_el_diff[i] = 0;
672 1795 : move16();
673 1795 : hParamIsm->last_el_sgn[i] = 1;
674 1795 : move16();
675 : }
676 :
677 488 : hParamIsm->last_dmx_gain_fx = (Word16) 16384; // 15-1 = Q14
678 488 : move16();
679 488 : hParamIsm->last_dmx_gain_e = 1;
680 488 : move16();
681 488 : set16_fx( hParamIsm->last_cardioid_left_fx, (Word16) 16384, MAX_NUM_OBJECTS ); // Q14
682 :
683 488 : 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 285802 : 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 285802 : ISM_MODE ism_mode = ISM_MODE_NONE;
699 285802 : move32();
700 :
701 285802 : test();
702 285802 : IF( GT_16( nchan_inp, 2 ) && LE_32( ivas_total_brate, ACELP_32k ) )
703 : {
704 52035 : ism_mode = ISM_MODE_PARAM;
705 52035 : move32();
706 : }
707 : ELSE
708 : {
709 233767 : ism_mode = ISM_MODE_DISC;
710 233767 : move32();
711 : }
712 :
713 285802 : return ism_mode;
714 : }
715 :
716 : /*---------------------------------------------------------------
717 : * ivas_ism_metadata_close()
718 : *
719 : * Deallocate ISM metadata handles
720 : * ---------------------------------------------------------------*/
721 :
722 3149 : 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 3149 : test();
730 3149 : IF( hIsmMetaData == NULL || *hIsmMetaData == NULL )
731 : {
732 1121 : return;
733 : }
734 :
735 8246 : FOR( n = first_idx; n < MAX_NUM_OBJECTS; n++ )
736 : {
737 6218 : IF( hIsmMetaData[n] != NULL )
738 : {
739 3699 : free( hIsmMetaData[n] );
740 3699 : hIsmMetaData[n] = NULL;
741 : }
742 : }
743 :
744 2028 : return;
745 : }
746 :
747 :
748 : /*-------------------------------------------------------------------*
749 : * update_last_metadata()
750 : *
751 : * Store last metadata values
752 : *-------------------------------------------------------------------*/
753 237064 : 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 922379 : FOR( ch = 0; ch < nchan_ism; ch++ )
761 : {
762 685315 : IF( EQ_16( updt_flag[ch], 1 ) )
763 : {
764 680175 : hIsmMeta[ch]->last_azimuth_fx = hIsmMeta[ch]->azimuth_fx; // Q22
765 680175 : move32();
766 680175 : hIsmMeta[ch]->last_elevation_fx = hIsmMeta[ch]->elevation_fx; // Q22
767 680175 : move32();
768 : }
769 : }
770 :
771 237064 : 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 3522 : 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 3522 : *nBits_azimuth = ISM_DTX_AZI_BITS_HIGH;
791 3522 : *nBits_elevation = ISM_DTX_ELE_BITS_HIGH;
792 3522 : *q_step_fx = ISM_Q_STEP_HIGH_FX; // Q22
793 3522 : *q_step_border_fx = ISM_Q_STEP_BORDER_HIGH_FX; // Q22
794 3522 : *nBits_coh = ISM_DTX_COH_SCA_BITS;
795 3522 : *nBits_sce_id = 1;
796 :
797 3522 : move16();
798 3522 : move16();
799 3522 : move16();
800 3522 : move16();
801 3522 : move32();
802 3522 : move32();
803 :
804 3522 : IF( GE_16( nchan_ism, 3 ) )
805 : {
806 2060 : *nBits_azimuth = ISM_DTX_AZI_BITS_LOW;
807 2060 : *nBits_elevation = ISM_DTX_ELE_BITS_LOW;
808 2060 : *q_step_fx = ISM_Q_STEP_LOW_FX; // Q22
809 2060 : *q_step_border_fx = ISM_Q_STEP_BORDER_LOW_FX; // Q22
810 2060 : *nBits_sce_id = 2;
811 :
812 2060 : move16();
813 2060 : move16();
814 2060 : move16();
815 2060 : move16();
816 2060 : move32();
817 : }
818 :
819 3522 : return;
820 : }
|