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 <assert.h>
34 : #include <stdint.h>
35 : #include <math.h>
36 : #include "options.h"
37 : #include "ivas_cnst.h"
38 : #include "ivas_rom_com.h"
39 : #include "ivas_prot.h"
40 : #include "prot.h"
41 : #include "cnst.h"
42 : #include "wmc_auto.h"
43 :
44 : /*-----------------------------------------------------------------------*
45 : * Local constants
46 : *-----------------------------------------------------------------------*/
47 :
48 : #define MASA_DIR_RATIO_COMP_MAX_IDX_STEPS 2
49 :
50 : /*-----------------------------------------------------------------------*
51 : * Local function prototypes
52 : *-----------------------------------------------------------------------*/
53 :
54 : static void ivas_qmetadata_free_memory( IVAS_QMETADATA_HANDLE hQMetaData );
55 :
56 :
57 : /*-----------------------------------------------------------------------*
58 : * ivas_qmetadata_open()
59 : *
60 : * Allocate Q Metadata handle
61 : *-----------------------------------------------------------------------*/
62 :
63 88973 : ivas_error ivas_qmetadata_open(
64 : IVAS_QMETADATA_HANDLE *hQMetaData /* i/o: q_metadata handle */
65 : )
66 : {
67 : /* allocate MetaData handle */
68 88973 : if ( ( *hQMetaData = (IVAS_QMETADATA_HANDLE) malloc( sizeof( IVAS_QMETADATA ) ) ) == NULL )
69 : {
70 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Q MetaData" );
71 : }
72 :
73 88973 : ( *hQMetaData )->q_direction = NULL;
74 88973 : ( *hQMetaData )->surcoh_band_data = NULL;
75 88973 : ( *hQMetaData )->bandMap = NULL;
76 :
77 88973 : return IVAS_ERR_OK;
78 : }
79 :
80 :
81 : /*-----------------------------------------------------------------------*
82 : * ivas_qmetadata_allocate_memory()
83 : *
84 : * Allocates dynamic memory for qmetadata. Also reallocates automatically
85 : * if relevant parameters have changed. To function properly, this function
86 : * assumes that qmetadata contains parameter values for nbands, ndirs and
87 : * coherence_flag corresponding to the currently reserved memory. This function
88 : * then compares them to provided new values given in call and allocates or
89 : * reallocates as necessary. The parameter values in qmetadata are updated
90 : * accordingly. In addition, parameters inside qdirection config are
91 : * set here to their default values out of practicality.
92 : *-----------------------------------------------------------------------*/
93 :
94 5239636 : ivas_error ivas_qmetadata_allocate_memory(
95 : IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */
96 : const int16_t nbands, /* i : new number of frequency bands */
97 : const int16_t ndirs, /* i : new number of directions */
98 : const int16_t coherence_flag /* i : new coherence coding status */
99 : )
100 : {
101 : int16_t j, dir;
102 : uint8_t do_realloc;
103 :
104 : #ifdef DEBUGGING
105 : assert( hQMetaData != NULL );
106 : #endif
107 :
108 : /* Check if we need to reallocate memory or do we need to do the first time allocation. */
109 5239636 : if ( hQMetaData->q_direction != NULL )
110 : {
111 5150663 : do_realloc = nbands != hQMetaData->q_direction->cfg.nbands;
112 5150663 : do_realloc |= ndirs != hQMetaData->no_directions;
113 5150663 : do_realloc |= coherence_flag != hQMetaData->coherence_flag;
114 : }
115 : else
116 : {
117 88973 : do_realloc = TRUE;
118 : }
119 :
120 5239636 : if ( do_realloc )
121 : {
122 526319 : ivas_qmetadata_free_memory( hQMetaData );
123 :
124 526319 : hQMetaData->numCodingBands = (uint8_t) nbands;
125 526319 : hQMetaData->no_directions = ndirs;
126 526319 : hQMetaData->coherence_flag = coherence_flag;
127 :
128 526319 : if ( ( hQMetaData->q_direction = (IVAS_QDIRECTION *) malloc( sizeof( IVAS_QDIRECTION ) * ndirs ) ) == NULL )
129 : {
130 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Q MetaData" );
131 : }
132 :
133 1164205 : for ( dir = 0; dir < hQMetaData->no_directions; dir++ )
134 : {
135 637886 : hQMetaData->q_direction[dir].cfg.nbands = nbands;
136 637886 : if ( nbands == 0 )
137 : {
138 0 : hQMetaData->q_direction[dir].band_data = NULL;
139 : }
140 : else
141 : {
142 637886 : if ( ( hQMetaData->q_direction[dir].band_data = (IVAS_QDIRECTION_BAND_DATA *) malloc( sizeof( IVAS_QDIRECTION_BAND_DATA ) * hQMetaData->q_direction[dir].cfg.nbands ) ) == NULL )
143 : {
144 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Q MetaData" );
145 : }
146 :
147 6257507 : for ( j = 0; j < nbands; j++ )
148 : {
149 5619621 : set_zero( hQMetaData->q_direction[dir].band_data[j].elevation, MAX_PARAM_SPATIAL_SUBFRAMES );
150 5619621 : set_zero( hQMetaData->q_direction[dir].band_data[j].azimuth, MAX_PARAM_SPATIAL_SUBFRAMES );
151 5619621 : set_zero( hQMetaData->q_direction[dir].band_data[j].energy_ratio, MAX_PARAM_SPATIAL_SUBFRAMES );
152 : }
153 : }
154 :
155 637886 : if ( coherence_flag )
156 : {
157 377028 : hQMetaData->q_direction[dir].coherence_band_data = (IVAS_QDIRECTION_BAND_COHERENCE_DATA *) malloc( sizeof( IVAS_QDIRECTION_BAND_COHERENCE_DATA ) * hQMetaData->q_direction[dir].cfg.nbands );
158 : }
159 : else
160 : {
161 260858 : hQMetaData->q_direction[dir].coherence_band_data = NULL;
162 : }
163 :
164 : /* These default values are set here to get them conveniently in one place */
165 637886 : hQMetaData->q_direction[dir].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES;
166 637886 : hQMetaData->q_direction[dir].cfg.search_effort = 3;
167 637886 : hQMetaData->q_direction[dir].cfg.start_band = 0;
168 637886 : hQMetaData->q_direction[dir].cfg.mc_ls_setup = MC_LS_SETUP_INVALID;
169 : }
170 :
171 526319 : if ( coherence_flag )
172 : {
173 277867 : if ( ( hQMetaData->surcoh_band_data = (IVAS_SURROUND_COHERENCE_BAND_DATA *) malloc( sizeof( IVAS_SURROUND_COHERENCE_BAND_DATA ) * hQMetaData->q_direction[0].cfg.nbands ) ) == NULL )
174 : {
175 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for Q MetaData" );
176 : }
177 : }
178 : else
179 : {
180 248452 : hQMetaData->surcoh_band_data = NULL;
181 : }
182 : }
183 :
184 :
185 5239636 : return IVAS_ERR_OK;
186 : }
187 :
188 :
189 : /*-----------------------------------------------------------------------*
190 : * ivas_qmetadata_free_memory()
191 : *
192 : * free dynamic part of Q Metadata memory
193 : *-----------------------------------------------------------------------*/
194 :
195 615292 : static void ivas_qmetadata_free_memory(
196 : IVAS_QMETADATA_HANDLE hQMetaData /* i/o: q_metadata handle */
197 : )
198 : {
199 : int16_t dir;
200 :
201 615292 : if ( hQMetaData == NULL )
202 : {
203 0 : return;
204 : }
205 :
206 615292 : if ( hQMetaData->q_direction != NULL )
207 : {
208 1164205 : for ( dir = 0; dir < hQMetaData->no_directions; dir++ )
209 : {
210 637886 : if ( hQMetaData->q_direction[dir].band_data != NULL )
211 : {
212 637886 : free( hQMetaData->q_direction[dir].band_data );
213 637886 : hQMetaData->q_direction[dir].band_data = NULL;
214 : }
215 637886 : if ( hQMetaData->q_direction[dir].coherence_band_data != NULL )
216 : {
217 377028 : free( hQMetaData->q_direction[dir].coherence_band_data );
218 377028 : hQMetaData->q_direction[dir].coherence_band_data = NULL;
219 : }
220 : }
221 :
222 526319 : free( hQMetaData->q_direction );
223 526319 : hQMetaData->q_direction = NULL;
224 : }
225 :
226 615292 : if ( hQMetaData->surcoh_band_data != NULL )
227 : {
228 277867 : free( hQMetaData->surcoh_band_data );
229 277867 : hQMetaData->surcoh_band_data = NULL;
230 : }
231 :
232 615292 : return;
233 : }
234 :
235 :
236 : /*-----------------------------------------------------------------------*
237 : * ivas_qmetadata_close()
238 : *
239 : * close Q Metadata
240 : *-----------------------------------------------------------------------*/
241 :
242 139957 : void ivas_qmetadata_close(
243 : IVAS_QMETADATA_HANDLE *hQMetaData /* i/o: q_metadata handle */
244 : )
245 : {
246 139957 : if ( hQMetaData == NULL || *hQMetaData == NULL )
247 : {
248 50984 : return;
249 : }
250 :
251 88973 : ivas_qmetadata_free_memory( *hQMetaData );
252 :
253 88973 : free( *hQMetaData );
254 88973 : *hQMetaData = NULL;
255 :
256 88973 : return;
257 : }
258 :
259 :
260 : /*-------------------------------------------------------------------------
261 : * masa_sq()
262 : *
263 : * scalar quantization using partition
264 : *------------------------------------------------------------------------*/
265 :
266 : /*! r: codeword index */
267 125622234 : int16_t masa_sq(
268 : const float in, /* i : input value */
269 : const float *threshold, /* i : partition */
270 : const int16_t cb_sz /* i : codebook size */
271 : )
272 : {
273 : int16_t i;
274 :
275 712108490 : for ( i = 0; i < cb_sz; i++ )
276 : {
277 712108490 : if ( in < threshold[i + 1] )
278 : {
279 125622234 : return i;
280 : }
281 : }
282 :
283 0 : return -1;
284 : }
285 :
286 :
287 : /*-------------------------------------------------------------------------
288 : * only_reduce_bits_direction()
289 : *
290 : *
291 : *------------------------------------------------------------------------*/
292 :
293 819304 : ivas_error only_reduce_bits_direction(
294 : int16_t *reduce_bits_out,
295 : IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */
296 : int16_t reduce_bits,
297 : const int16_t coding_subbands,
298 : const int16_t no_subframes,
299 : int16_t *ind_order )
300 : {
301 : int16_t j, k, red_times, rem, n;
302 : int16_t max_nb, delta;
303 : int16_t *bits_dir0;
304 :
305 : int16_t bits_sph_idx_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
306 : float penalty[MASA_MAXIMUM_CODING_SUBBANDS];
307 4808374 : for ( j = 0; j < coding_subbands; j++ )
308 : {
309 14455545 : for ( k = 0; k < no_subframes; k++ )
310 : {
311 10466475 : bits_sph_idx_orig[j][k] = q_direction->band_data[j].bits_sph_idx[k];
312 : }
313 : }
314 819304 : n = 0;
315 819304 : delta = 1;
316 :
317 819304 : if ( reduce_bits > 0 )
318 : {
319 798161 : red_times = reduce_bits / ( coding_subbands * no_subframes ); /* number of complete reductions by 1 bit */
320 798161 : if ( red_times > 0 )
321 : {
322 3937204 : for ( j = 0; j < coding_subbands; j++ )
323 : {
324 3267008 : bits_dir0 = (int16_t *) q_direction->band_data[j].bits_sph_idx;
325 12540148 : for ( k = 0; k < no_subframes; k++ )
326 : {
327 9273140 : bits_dir0[k] -= red_times;
328 9273140 : reduce_bits -= red_times;
329 :
330 9273140 : if ( bits_dir0[k] < MASA_MIN_BITS_TF )
331 : {
332 1259352 : reduce_bits += ( MASA_MIN_BITS_TF - bits_dir0[k] );
333 1259352 : bits_dir0[k] = MASA_MIN_BITS_TF;
334 : }
335 : }
336 : }
337 : }
338 :
339 798161 : rem = reduce_bits; /* -coding_subbands*no_subframes*red_times; */
340 1669251 : while ( n < rem )
341 : {
342 871090 : max_nb = 0;
343 : #ifdef DEBUGGING
344 : if ( delta > MASA_MIN_BITS_TF )
345 : {
346 : return IVAS_ERROR( IVAS_ERR_INTERNAL_FATAL, "Not enough bits for MASA param." );
347 : }
348 : #endif
349 4994141 : for ( j = 0; j < coding_subbands; j++ )
350 : {
351 4123051 : bits_dir0 = (int16_t *) q_direction->band_data[j].bits_sph_idx;
352 16242074 : for ( k = 0; k < no_subframes; k++ )
353 : {
354 12119023 : if ( ( n < rem ) && ( bits_dir0[k] > MASA_MIN_BITS_TF - delta ) )
355 : {
356 6668076 : bits_dir0[k] -= 1;
357 6668076 : n++;
358 : }
359 :
360 12119023 : if ( max_nb < bits_dir0[k] )
361 : {
362 1983992 : max_nb = bits_dir0[k];
363 : }
364 : }
365 : }
366 :
367 871090 : if ( max_nb <= MASA_MIN_BITS_TF )
368 : {
369 53576 : delta += 1;
370 : }
371 : }
372 :
373 798161 : reduce_bits = 0;
374 : }
375 :
376 819304 : if ( ind_order[0] == -1 )
377 : {
378 888301 : for ( j = 0; j < coding_subbands; j++ )
379 : {
380 661888 : ind_order[j] = j;
381 : }
382 : }
383 : else
384 : {
385 3920073 : for ( j = 0; j < coding_subbands; j++ )
386 : {
387 3327182 : penalty[j] = 0.0f;
388 11250211 : for ( k = 0; k < no_subframes; k++ )
389 : {
390 7923029 : if ( bits_sph_idx_orig[j][k] > 0 )
391 : {
392 7923029 : penalty[j] += ( bits_sph_idx_orig[j][k] - q_direction->band_data[j].bits_sph_idx[k] ) / (float) bits_sph_idx_orig[j][k];
393 : }
394 : }
395 3327182 : penalty[j] /= no_subframes;
396 : }
397 592891 : sort_desc_ind( penalty, coding_subbands, ind_order );
398 : }
399 :
400 819304 : *reduce_bits_out = -reduce_bits;
401 :
402 819304 : return IVAS_ERR_OK;
403 : }
404 :
405 :
406 : /*---------------------------------------------------------------
407 : * update_bits_next_block()
408 : *
409 : * Transfer the saved bits to the next subbands
410 : *---------------------------------------------------------------*/
411 :
412 2511424 : void update_bits_next_block(
413 : IVAS_QDIRECTION *q_direction, /* i/o: qdirection */
414 : int16_t *p_diff, /* i/o: bits to be transferred */
415 : const int16_t j, /* i : subband to update bit alloc to*/
416 : const int16_t max_i, /* i : number of subbands */
417 : const int16_t max_k /* i : n umber of subframes */
418 : )
419 : {
420 : int16_t diff;
421 : int16_t k;
422 2511424 : diff = *p_diff;
423 2511424 : if ( diff < 0 )
424 : {
425 : /* increase bits for next subbands */
426 796045 : k = 0;
427 3203519 : while ( ( diff < 0 ) && ( j < max_i ) && ( k < max_k ) )
428 : {
429 2407474 : if ( q_direction->band_data[j].bits_sph_idx[k] < MASA_DIRECTION_MAX_BITS )
430 : {
431 2407070 : q_direction->band_data[j].bits_sph_idx[k] += 1;
432 2407070 : diff++;
433 : }
434 2407474 : k++;
435 : }
436 : }
437 : else
438 : {
439 1715379 : k = 0;
440 2640516 : while ( ( diff > 0 ) && ( k < max_k ) )
441 : {
442 925137 : if ( q_direction->band_data[j].bits_sph_idx[k] > 0 )
443 : {
444 925137 : q_direction->band_data[j].bits_sph_idx[k] -= 1;
445 925137 : diff--;
446 : }
447 : }
448 : }
449 2511424 : *p_diff = diff;
450 :
451 2511424 : return;
452 : }
453 :
454 :
455 : /*---------------------------------------------------------------
456 : * invdct4_transform()
457 : *
458 : * Inverse DCT transform for 4D vector
459 : *---------------------------------------------------------------*/
460 :
461 17610800 : void invdct4_transform(
462 : float *v, /* i : input vector */
463 : uint8_t *invdct_v /* o : inverse transformed vector */
464 : )
465 : {
466 : float a, b, c, d;
467 : int16_t i;
468 : float f_invdct_v[4];
469 :
470 17610800 : a = v[0] + v[2];
471 17610800 : b = v[0] - v[2];
472 17610800 : c = 1.306562964876376f * v[1] + 0.541196100146198f * v[3];
473 17610800 : d = 0.541196100146198f * v[1] - 1.306562964876376f * v[3];
474 17610800 : f_invdct_v[0] = 128 * ( a + c );
475 17610800 : f_invdct_v[1] = 128 * ( b + d );
476 17610800 : f_invdct_v[2] = 128 * ( b - d );
477 17610800 : f_invdct_v[3] = 128 * ( a - c );
478 :
479 88054000 : for ( i = 0; i < 4; i++ )
480 : {
481 70443200 : if ( f_invdct_v[i] < 0.0 )
482 : {
483 8057259 : invdct_v[i] = 0;
484 : }
485 : else
486 : {
487 62385941 : if ( f_invdct_v[i] > 255.0f )
488 : {
489 61602 : f_invdct_v[i] = 255.0f;
490 : }
491 62385941 : invdct_v[i] = (uint8_t) f_invdct_v[i];
492 : }
493 : }
494 :
495 17610800 : return;
496 : }
497 :
498 :
499 : /*---------------------------------------------------------------
500 : * masa_compensate_two_dir_energy_ratio_index()
501 : *
502 : * Calculated compensated direct-to-total ratios for direction
503 : * quantization with two directions. This allows maintaining
504 : * direction accuracy while reusing one direction quantizers
505 : * separately for both directions.
506 : *--------------------------------------------------------------*/
507 :
508 11932093 : void masa_compensate_two_dir_energy_ratio_index(
509 : const int16_t ratio_index_1, /* i : Input ratio for direction 1 */
510 : const int16_t ratio_index_2, /* i : Input ratio for direction 2 */
511 : int16_t *ratio_index_mod1, /* o : Output modified ratio for direction 1 */
512 : int16_t *ratio_index_mod2, /* o : Output modified ratio for direction 2 */
513 : const int16_t hodirac_flag /* i : flag to indicate HO-DirAC mode */
514 : )
515 : {
516 : float ratio1, ratio2;
517 : float ratioSum;
518 :
519 11932093 : ratio1 = 1.0f - diffuseness_reconstructions[ratio_index_1];
520 11932093 : ratio2 = 1.0f - diffuseness_reconstructions[ratio_index_2];
521 :
522 11932093 : if ( !hodirac_flag )
523 : {
524 2144997 : ratioSum = ratio1 + ratio2;
525 2144997 : if ( ratio1 >= ratio2 )
526 : {
527 2144997 : ratio2 = ratio2 / ratio1 * ratioSum;
528 2144997 : ratio1 = ratioSum;
529 : }
530 : else
531 : {
532 0 : ratio1 = ratio1 / ratio2 * ratioSum;
533 0 : ratio2 = ratioSum;
534 : }
535 : }
536 :
537 11932093 : *ratio_index_mod1 = masa_sq( 1.0f - ratio1, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
538 11932093 : *ratio_index_mod2 = masa_sq( 1.0f - ratio2, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
539 :
540 : /* Limit maximum accuracy increase to conserve bits */
541 11932093 : *ratio_index_mod1 = ( ratio_index_1 - *ratio_index_mod1 ) > MASA_DIR_RATIO_COMP_MAX_IDX_STEPS ? ratio_index_1 - MASA_DIR_RATIO_COMP_MAX_IDX_STEPS : *ratio_index_mod1;
542 11932093 : *ratio_index_mod2 = ( ratio_index_2 - *ratio_index_mod2 ) > MASA_DIR_RATIO_COMP_MAX_IDX_STEPS ? ratio_index_2 - MASA_DIR_RATIO_COMP_MAX_IDX_STEPS : *ratio_index_mod2;
543 :
544 11932093 : return;
545 : }
546 :
547 :
548 : /*---------------------------------------------------------------
549 : * set_qmetadata_maxbit_req()
550 : *
551 : * Sets proper value for qmetadata_max_bit_req limit
552 : *--------------------------------------------------------------*/
553 :
554 5239636 : void ivas_set_qmetadata_maxbit_req(
555 : IVAS_QMETADATA_HANDLE hQMetaData, /* o : qmetadata structure where the requirement value is set */
556 : const IVAS_FORMAT ivas_format /* i : IVAS format */
557 : )
558 : {
559 5239636 : if ( ivas_format == SBA_FORMAT )
560 : {
561 215692 : hQMetaData->qmetadata_max_bit_req = QMETADATA_MAXBIT_REQ_SBA;
562 : }
563 : else /* MASA_FORMAT */
564 : {
565 5023944 : hQMetaData->qmetadata_max_bit_req = QMETADATA_MAXBIT_REQ_MASA;
566 : }
567 :
568 5239636 : return;
569 : }
570 :
571 :
572 : /*-------------------------------------------------------------------------
573 : * ivas_qmetadata_azimuth_elevation_to_direction_vector()
574 : *
575 : *
576 : *------------------------------------------------------------------------*/
577 :
578 58903387 : void ivas_qmetadata_azimuth_elevation_to_direction_vector(
579 : const float az, /* i : azimuth */
580 : const float el, /* i : elevation */
581 : float *dv /* o : direction vector */
582 : )
583 : {
584 : float radius_length;
585 :
586 : #ifdef DEBUGGING
587 : assert( fabsf( el ) <= 90.0f );
588 : /*assert((0.0f <= az) && (az <= 360.0f)); */
589 : #endif
590 :
591 58903387 : dv[2] = sinf( el * PI_OVER_180 );
592 58903387 : radius_length = cosf( el * PI_OVER_180 );
593 58903387 : dv[0] = radius_length * cosf( az * PI_OVER_180 );
594 58903387 : dv[1] = radius_length * sinf( az * PI_OVER_180 );
595 :
596 58903387 : return;
597 : }
598 :
599 : /*-------------------------------------------------------------------------
600 : * ivas_qmetadata_direction_vector_to_azimuth_elevation()
601 : *
602 : * azimuth between [-180, 180]
603 : * elevation between [-90 and 90]
604 : *------------------------------------------------------------------------*/
605 :
606 83424050 : void ivas_qmetadata_direction_vector_to_azimuth_elevation(
607 : const float *dv, /* i : direction vector */
608 : float *az, /* o : azimuth */
609 : float *el /* o : elevation */
610 : )
611 : {
612 : /* note: dv does not need to have unit L_2 norm, because the conversion is scale invariant */
613 :
614 83424050 : *el = atan2f( dv[2], sqrtf( dv[0] * dv[0] + dv[1] * dv[1] ) ) * _180_OVER_PI;
615 83424050 : *az = atan2f( dv[1], dv[0] ) * _180_OVER_PI;
616 :
617 83424050 : return;
618 : }
619 :
620 :
621 : /*-------------------------------------------------------------------------
622 : * ivas_get_df_ratio_bits_hodirac()
623 : *
624 : *
625 : *------------------------------------------------------------------------*/
626 :
627 : /*! r: bits to be used for quantizing ratio of ratios */
628 9787096 : int16_t ivas_get_df_ratio_bits_hodirac(
629 : const int16_t index_diff /* i : index of quantized diffuse-to-total ratio */
630 : )
631 : {
632 : int16_t dfRatio_bits;
633 :
634 9787096 : if ( index_diff >= DIFF_DFRATIO_1BIT_LIMIT_IDX )
635 : {
636 4034099 : dfRatio_bits = 1;
637 : }
638 5752997 : else if ( index_diff >= DIFF_DFRATIO_2BIT_LIMIT_IDX_HODIRAC )
639 : {
640 2956111 : dfRatio_bits = 2;
641 : }
642 : else
643 : {
644 2796886 : dfRatio_bits = 3;
645 : }
646 :
647 9787096 : return dfRatio_bits;
648 : }
649 :
650 : /*---------------------------------------------------------------
651 : * ivas_get_df_ratio_bits()
652 : *
653 : * Gives quantization accuracy for distribution factor of
654 : * direct-to-total ratios based on the diffuse-to-total ratio
655 : * index
656 : *--------------------------------------------------------------*/
657 :
658 : /*! r: bits to be used for quantizing ratio of ratios */
659 2144997 : int16_t ivas_get_df_ratio_bits(
660 : const int16_t index_diff /* i : index of quantized diffuse-to-total ratio */
661 : )
662 : {
663 : int16_t dfRatio_bits;
664 :
665 2144997 : if ( index_diff >= DIFF_DFRATIO_1BIT_LIMIT_IDX )
666 : {
667 188452 : dfRatio_bits = 1;
668 : }
669 1956545 : else if ( index_diff >= DIFF_DFRATIO_2BIT_LIMIT_IDX )
670 : {
671 1696796 : dfRatio_bits = 2;
672 : }
673 : else
674 : {
675 259749 : dfRatio_bits = 3;
676 : }
677 :
678 2144997 : return dfRatio_bits;
679 : }
|