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 74743 : ivas_error ivas_qmetadata_open(
64 : IVAS_QMETADATA_HANDLE *hQMetaData /* i/o: q_metadata handle */
65 : )
66 : {
67 : /* allocate MetaData handle */
68 74743 : 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 74743 : ( *hQMetaData )->q_direction = NULL;
74 74743 : ( *hQMetaData )->surcoh_band_data = NULL;
75 74743 : ( *hQMetaData )->bandMap = NULL;
76 :
77 74743 : 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 2935571 : 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 2935571 : if ( hQMetaData->q_direction != NULL )
110 : {
111 2860828 : do_realloc = nbands != hQMetaData->q_direction->cfg.nbands;
112 2860828 : do_realloc |= ndirs != hQMetaData->no_directions;
113 2860828 : do_realloc |= coherence_flag != hQMetaData->coherence_flag;
114 : }
115 : else
116 : {
117 74743 : do_realloc = TRUE;
118 : }
119 :
120 2935571 : if ( do_realloc )
121 : {
122 311959 : ivas_qmetadata_free_memory( hQMetaData );
123 :
124 311959 : hQMetaData->numCodingBands = (uint8_t) nbands;
125 311959 : hQMetaData->no_directions = ndirs;
126 311959 : hQMetaData->coherence_flag = coherence_flag;
127 :
128 311959 : 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 682816 : for ( dir = 0; dir < hQMetaData->no_directions; dir++ )
134 : {
135 370857 : hQMetaData->q_direction[dir].cfg.nbands = nbands;
136 370857 : if ( nbands == 0 )
137 : {
138 0 : hQMetaData->q_direction[dir].band_data = NULL;
139 : }
140 : else
141 : {
142 370857 : 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 3475863 : for ( j = 0; j < nbands; j++ )
148 : {
149 3105006 : set_zero( hQMetaData->q_direction[dir].band_data[j].elevation, MAX_PARAM_SPATIAL_SUBFRAMES );
150 3105006 : set_zero( hQMetaData->q_direction[dir].band_data[j].azimuth, MAX_PARAM_SPATIAL_SUBFRAMES );
151 3105006 : set_zero( hQMetaData->q_direction[dir].band_data[j].energy_ratio, MAX_PARAM_SPATIAL_SUBFRAMES );
152 : }
153 : }
154 :
155 370857 : if ( coherence_flag )
156 : {
157 196793 : 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 174064 : 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 370857 : hQMetaData->q_direction[dir].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES;
166 370857 : hQMetaData->q_direction[dir].cfg.search_effort = 3;
167 370857 : hQMetaData->q_direction[dir].cfg.start_band = 0;
168 370857 : hQMetaData->q_direction[dir].cfg.mc_ls_setup = MC_LS_SETUP_INVALID;
169 : }
170 :
171 311959 : if ( coherence_flag )
172 : {
173 146974 : 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 164985 : hQMetaData->surcoh_band_data = NULL;
181 : }
182 : }
183 :
184 :
185 2935571 : 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 386702 : static void ivas_qmetadata_free_memory(
196 : IVAS_QMETADATA_HANDLE hQMetaData /* i/o: q_metadata handle */
197 : )
198 : {
199 : int16_t dir;
200 :
201 386702 : if ( hQMetaData == NULL )
202 : {
203 0 : return;
204 : }
205 :
206 386702 : if ( hQMetaData->q_direction != NULL )
207 : {
208 682816 : for ( dir = 0; dir < hQMetaData->no_directions; dir++ )
209 : {
210 370857 : if ( hQMetaData->q_direction[dir].band_data != NULL )
211 : {
212 370857 : free( hQMetaData->q_direction[dir].band_data );
213 370857 : hQMetaData->q_direction[dir].band_data = NULL;
214 : }
215 370857 : if ( hQMetaData->q_direction[dir].coherence_band_data != NULL )
216 : {
217 196793 : free( hQMetaData->q_direction[dir].coherence_band_data );
218 196793 : hQMetaData->q_direction[dir].coherence_band_data = NULL;
219 : }
220 : }
221 :
222 311959 : free( hQMetaData->q_direction );
223 311959 : hQMetaData->q_direction = NULL;
224 : }
225 :
226 386702 : if ( hQMetaData->surcoh_band_data != NULL )
227 : {
228 146974 : free( hQMetaData->surcoh_band_data );
229 146974 : hQMetaData->surcoh_band_data = NULL;
230 : }
231 :
232 386702 : return;
233 : }
234 :
235 :
236 : /*-----------------------------------------------------------------------*
237 : * ivas_qmetadata_close()
238 : *
239 : * close Q Metadata
240 : *-----------------------------------------------------------------------*/
241 :
242 111352 : void ivas_qmetadata_close(
243 : IVAS_QMETADATA_HANDLE *hQMetaData /* i/o: q_metadata handle */
244 : )
245 : {
246 111352 : if ( hQMetaData == NULL || *hQMetaData == NULL )
247 : {
248 36609 : return;
249 : }
250 :
251 74743 : ivas_qmetadata_free_memory( *hQMetaData );
252 :
253 74743 : free( *hQMetaData );
254 74743 : *hQMetaData = NULL;
255 :
256 74743 : return;
257 : }
258 :
259 :
260 : /*-------------------------------------------------------------------------
261 : * masa_sq()
262 : *
263 : * scalar quantization using partition
264 : *------------------------------------------------------------------------*/
265 :
266 : /*! r: codeword index */
267 83733470 : 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 478313062 : for ( i = 0; i < cb_sz; i++ )
276 : {
277 478313062 : if ( in < threshold[i + 1] )
278 : {
279 83733470 : return i;
280 : }
281 : }
282 :
283 0 : return -1;
284 : }
285 :
286 :
287 : /*-------------------------------------------------------------------------
288 : * only_reduce_bits_direction()
289 : *
290 : *
291 : *------------------------------------------------------------------------*/
292 :
293 492266 : 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 2755445 : for ( j = 0; j < coding_subbands; j++ )
308 : {
309 8091918 : for ( k = 0; k < no_subframes; k++ )
310 : {
311 5828739 : bits_sph_idx_orig[j][k] = q_direction->band_data[j].bits_sph_idx[k];
312 : }
313 : }
314 492266 : n = 0;
315 492266 : delta = 1;
316 :
317 492266 : if ( reduce_bits > 0 )
318 : {
319 479395 : red_times = reduce_bits / ( coding_subbands * no_subframes ); /* number of complete reductions by 1 bit */
320 479395 : if ( red_times > 0 )
321 : {
322 2237951 : for ( j = 0; j < coding_subbands; j++ )
323 : {
324 1836159 : bits_dir0 = (int16_t *) q_direction->band_data[j].bits_sph_idx;
325 6989232 : for ( k = 0; k < no_subframes; k++ )
326 : {
327 5153073 : bits_dir0[k] -= red_times;
328 5153073 : reduce_bits -= red_times;
329 :
330 5153073 : if ( bits_dir0[k] < MASA_MIN_BITS_TF )
331 : {
332 710647 : reduce_bits += ( MASA_MIN_BITS_TF - bits_dir0[k] );
333 710647 : bits_dir0[k] = MASA_MIN_BITS_TF;
334 : }
335 : }
336 : }
337 : }
338 :
339 479395 : rem = reduce_bits; /* -coding_subbands*no_subframes*red_times; */
340 997930 : while ( n < rem )
341 : {
342 518535 : 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 2807505 : for ( j = 0; j < coding_subbands; j++ )
350 : {
351 2288970 : bits_dir0 = (int16_t *) q_direction->band_data[j].bits_sph_idx;
352 8925900 : for ( k = 0; k < no_subframes; k++ )
353 : {
354 6636930 : if ( ( n < rem ) && ( bits_dir0[k] > MASA_MIN_BITS_TF - delta ) )
355 : {
356 3827879 : bits_dir0[k] -= 1;
357 3827879 : n++;
358 : }
359 :
360 6636930 : if ( max_nb < bits_dir0[k] )
361 : {
362 1177702 : max_nb = bits_dir0[k];
363 : }
364 : }
365 : }
366 :
367 518535 : if ( max_nb <= MASA_MIN_BITS_TF )
368 : {
369 24524 : delta += 1;
370 : }
371 : }
372 :
373 479395 : reduce_bits = 0;
374 : }
375 :
376 492266 : if ( ind_order[0] == -1 )
377 : {
378 612532 : for ( j = 0; j < coding_subbands; j++ )
379 : {
380 456096 : ind_order[j] = j;
381 : }
382 : }
383 : else
384 : {
385 2142913 : for ( j = 0; j < coding_subbands; j++ )
386 : {
387 1807083 : penalty[j] = 0.0f;
388 5890710 : for ( k = 0; k < no_subframes; k++ )
389 : {
390 4083627 : if ( bits_sph_idx_orig[j][k] > 0 )
391 : {
392 4083627 : 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 1807083 : penalty[j] /= no_subframes;
396 : }
397 335830 : sort_desc_ind( penalty, coding_subbands, ind_order );
398 : }
399 :
400 492266 : *reduce_bits_out = -reduce_bits;
401 :
402 492266 : 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 1410954 : 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 1410954 : diff = *p_diff;
423 1410954 : if ( diff < 0 )
424 : {
425 : /* increase bits for next subbands */
426 404598 : k = 0;
427 1574366 : while ( ( diff < 0 ) && ( j < max_i ) && ( k < max_k ) )
428 : {
429 1169768 : if ( q_direction->band_data[j].bits_sph_idx[k] < MASA_DIRECTION_MAX_BITS )
430 : {
431 1169564 : q_direction->band_data[j].bits_sph_idx[k] += 1;
432 1169564 : diff++;
433 : }
434 1169768 : k++;
435 : }
436 : }
437 : else
438 : {
439 1006356 : k = 0;
440 1550497 : while ( ( diff > 0 ) && ( k < max_k ) )
441 : {
442 544141 : if ( q_direction->band_data[j].bits_sph_idx[k] > 0 )
443 : {
444 544141 : q_direction->band_data[j].bits_sph_idx[k] -= 1;
445 544141 : diff--;
446 : }
447 : }
448 : }
449 1410954 : *p_diff = diff;
450 :
451 1410954 : return;
452 : }
453 :
454 :
455 : /*---------------------------------------------------------------
456 : * invdct4_transform()
457 : *
458 : * Inverse DCT transform for 4D vector
459 : *---------------------------------------------------------------*/
460 :
461 10449982 : 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 10449982 : a = v[0] + v[2];
471 10449982 : b = v[0] - v[2];
472 10449982 : c = 1.306562964876376f * v[1] + 0.541196100146198f * v[3];
473 10449982 : d = 0.541196100146198f * v[1] - 1.306562964876376f * v[3];
474 10449982 : f_invdct_v[0] = 128 * ( a + c );
475 10449982 : f_invdct_v[1] = 128 * ( b + d );
476 10449982 : f_invdct_v[2] = 128 * ( b - d );
477 10449982 : f_invdct_v[3] = 128 * ( a - c );
478 :
479 52249910 : for ( i = 0; i < 4; i++ )
480 : {
481 41799928 : if ( f_invdct_v[i] < 0.0 )
482 : {
483 4510252 : invdct_v[i] = 0;
484 : }
485 : else
486 : {
487 37289676 : if ( f_invdct_v[i] > 255.0f )
488 : {
489 31209 : f_invdct_v[i] = 255.0f;
490 : }
491 37289676 : invdct_v[i] = (uint8_t) f_invdct_v[i];
492 : }
493 : }
494 :
495 10449982 : 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 7660646 : 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 7660646 : ratio1 = 1.0f - diffuseness_reconstructions[ratio_index_1];
520 7660646 : ratio2 = 1.0f - diffuseness_reconstructions[ratio_index_2];
521 :
522 7660646 : if ( !hodirac_flag )
523 : {
524 996483 : ratioSum = ratio1 + ratio2;
525 996483 : if ( ratio1 >= ratio2 )
526 : {
527 996483 : ratio2 = ratio2 / ratio1 * ratioSum;
528 996483 : ratio1 = ratioSum;
529 : }
530 : else
531 : {
532 0 : ratio1 = ratio1 / ratio2 * ratioSum;
533 0 : ratio2 = ratioSum;
534 : }
535 : }
536 :
537 7660646 : *ratio_index_mod1 = masa_sq( 1.0f - ratio1, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
538 7660646 : *ratio_index_mod2 = masa_sq( 1.0f - ratio2, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
539 :
540 : /* Limit maximum accuracy increase to conserve bits */
541 7660646 : *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 7660646 : *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 7660646 : return;
545 : }
546 :
547 :
548 : /*---------------------------------------------------------------
549 : * set_qmetadata_maxbit_req()
550 : *
551 : * Sets proper value for qmetadata_max_bit_req limit
552 : *--------------------------------------------------------------*/
553 :
554 2935571 : 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 2935571 : if ( ivas_format == SBA_FORMAT )
560 : {
561 150571 : hQMetaData->qmetadata_max_bit_req = QMETADATA_MAXBIT_REQ_SBA;
562 : }
563 : else /* MASA_FORMAT */
564 : {
565 2785000 : hQMetaData->qmetadata_max_bit_req = QMETADATA_MAXBIT_REQ_MASA;
566 : }
567 :
568 2935571 : return;
569 : }
570 :
571 :
572 : /*-------------------------------------------------------------------------
573 : * ivas_qmetadata_azimuth_elevation_to_direction_vector()
574 : *
575 : *
576 : *------------------------------------------------------------------------*/
577 :
578 51214558 : 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 51214558 : dv[2] = sinf( el * PI_OVER_180 );
592 51214558 : radius_length = cosf( el * PI_OVER_180 );
593 51214558 : dv[0] = radius_length * cosf( az * PI_OVER_180 );
594 51214558 : dv[1] = radius_length * sinf( az * PI_OVER_180 );
595 :
596 51214558 : 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 49910009 : 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 49910009 : *el = atan2f( dv[2], sqrtf( dv[0] * dv[0] + dv[1] * dv[1] ) ) * _180_OVER_PI;
615 49910009 : *az = atan2f( dv[1], dv[0] ) * _180_OVER_PI;
616 :
617 49910009 : 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 6664163 : 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 6664163 : if ( index_diff >= DIFF_DFRATIO_1BIT_LIMIT_IDX )
635 : {
636 2462717 : dfRatio_bits = 1;
637 : }
638 4201446 : else if ( index_diff >= DIFF_DFRATIO_2BIT_LIMIT_IDX_HODIRAC )
639 : {
640 2123457 : dfRatio_bits = 2;
641 : }
642 : else
643 : {
644 2077989 : dfRatio_bits = 3;
645 : }
646 :
647 6664163 : 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 996483 : 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 996483 : if ( index_diff >= DIFF_DFRATIO_1BIT_LIMIT_IDX )
666 : {
667 91978 : dfRatio_bits = 1;
668 : }
669 904505 : else if ( index_diff >= DIFF_DFRATIO_2BIT_LIMIT_IDX )
670 : {
671 792475 : dfRatio_bits = 2;
672 : }
673 : else
674 : {
675 112030 : dfRatio_bits = 3;
676 : }
677 :
678 996483 : return dfRatio_bits;
679 : }
|