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 2596 : ivas_error ivas_qmetadata_open(
64 : IVAS_QMETADATA_HANDLE *hQMetaData /* i/o: q_metadata handle */
65 : )
66 : {
67 : /* allocate MetaData handle */
68 2596 : 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 2596 : ( *hQMetaData )->q_direction = NULL;
74 2596 : ( *hQMetaData )->surcoh_band_data = NULL;
75 2596 : ( *hQMetaData )->bandMap = NULL;
76 :
77 2596 : 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 199242 : 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 199242 : if ( hQMetaData->q_direction != NULL )
110 : {
111 196646 : do_realloc = nbands != hQMetaData->q_direction->cfg.nbands;
112 196646 : do_realloc |= ndirs != hQMetaData->no_directions;
113 196646 : do_realloc |= coherence_flag != hQMetaData->coherence_flag;
114 : }
115 : else
116 : {
117 2596 : do_realloc = TRUE;
118 : }
119 :
120 199242 : if ( do_realloc )
121 : {
122 16432 : ivas_qmetadata_free_memory( hQMetaData );
123 :
124 16432 : hQMetaData->numCodingBands = (uint8_t) nbands;
125 16432 : hQMetaData->no_directions = ndirs;
126 16432 : hQMetaData->coherence_flag = coherence_flag;
127 :
128 16432 : 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 34725 : for ( dir = 0; dir < hQMetaData->no_directions; dir++ )
134 : {
135 18293 : hQMetaData->q_direction[dir].cfg.nbands = nbands;
136 18293 : if ( nbands == 0 )
137 : {
138 0 : hQMetaData->q_direction[dir].band_data = NULL;
139 : }
140 : else
141 : {
142 18293 : 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 141295 : for ( j = 0; j < nbands; j++ )
148 : {
149 123002 : set_zero( hQMetaData->q_direction[dir].band_data[j].elevation, MAX_PARAM_SPATIAL_SUBFRAMES );
150 123002 : set_zero( hQMetaData->q_direction[dir].band_data[j].azimuth, MAX_PARAM_SPATIAL_SUBFRAMES );
151 123002 : set_zero( hQMetaData->q_direction[dir].band_data[j].energy_ratio, MAX_PARAM_SPATIAL_SUBFRAMES );
152 : }
153 : }
154 :
155 18293 : if ( coherence_flag )
156 : {
157 7001 : 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 11292 : 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 18293 : hQMetaData->q_direction[dir].cfg.nblocks = MAX_PARAM_SPATIAL_SUBFRAMES;
166 18293 : hQMetaData->q_direction[dir].cfg.search_effort = 3;
167 18293 : hQMetaData->q_direction[dir].cfg.start_band = 0;
168 18293 : hQMetaData->q_direction[dir].cfg.mc_ls_setup = MC_LS_SETUP_INVALID;
169 : }
170 :
171 16432 : if ( coherence_flag )
172 : {
173 5788 : 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 10644 : hQMetaData->surcoh_band_data = NULL;
181 : }
182 : }
183 :
184 :
185 199242 : 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 19028 : static void ivas_qmetadata_free_memory(
196 : IVAS_QMETADATA_HANDLE hQMetaData /* i/o: q_metadata handle */
197 : )
198 : {
199 : int16_t dir;
200 :
201 19028 : if ( hQMetaData == NULL )
202 : {
203 0 : return;
204 : }
205 :
206 19028 : if ( hQMetaData->q_direction != NULL )
207 : {
208 34725 : for ( dir = 0; dir < hQMetaData->no_directions; dir++ )
209 : {
210 18293 : if ( hQMetaData->q_direction[dir].band_data != NULL )
211 : {
212 18293 : free( hQMetaData->q_direction[dir].band_data );
213 18293 : hQMetaData->q_direction[dir].band_data = NULL;
214 : }
215 18293 : if ( hQMetaData->q_direction[dir].coherence_band_data != NULL )
216 : {
217 7001 : free( hQMetaData->q_direction[dir].coherence_band_data );
218 7001 : hQMetaData->q_direction[dir].coherence_band_data = NULL;
219 : }
220 : }
221 :
222 16432 : free( hQMetaData->q_direction );
223 16432 : hQMetaData->q_direction = NULL;
224 : }
225 :
226 19028 : if ( hQMetaData->surcoh_band_data != NULL )
227 : {
228 5788 : free( hQMetaData->surcoh_band_data );
229 5788 : hQMetaData->surcoh_band_data = NULL;
230 : }
231 :
232 19028 : return;
233 : }
234 :
235 :
236 : /*-----------------------------------------------------------------------*
237 : * ivas_qmetadata_close()
238 : *
239 : * close Q Metadata
240 : *-----------------------------------------------------------------------*/
241 :
242 5112 : void ivas_qmetadata_close(
243 : IVAS_QMETADATA_HANDLE *hQMetaData /* i/o: q_metadata handle */
244 : )
245 : {
246 5112 : if ( hQMetaData == NULL || *hQMetaData == NULL )
247 : {
248 2516 : return;
249 : }
250 :
251 2596 : ivas_qmetadata_free_memory( *hQMetaData );
252 :
253 2596 : free( *hQMetaData );
254 2596 : *hQMetaData = NULL;
255 :
256 2596 : return;
257 : }
258 :
259 :
260 : /*-------------------------------------------------------------------------
261 : * masa_sq()
262 : *
263 : * scalar quantization using partition
264 : *------------------------------------------------------------------------*/
265 :
266 : /*! r: codeword index */
267 6747597 : 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 40352363 : for ( i = 0; i < cb_sz; i++ )
276 : {
277 40352363 : if ( in < threshold[i + 1] )
278 : {
279 6747597 : return i;
280 : }
281 : }
282 :
283 0 : return -1;
284 : }
285 :
286 :
287 : /*-------------------------------------------------------------------------
288 : * only_reduce_bits_direction()
289 : *
290 : *
291 : *------------------------------------------------------------------------*/
292 :
293 35416 : 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 199428 : for ( j = 0; j < coding_subbands; j++ )
308 : {
309 616135 : for ( k = 0; k < no_subframes; k++ )
310 : {
311 452123 : bits_sph_idx_orig[j][k] = q_direction->band_data[j].bits_sph_idx[k];
312 : }
313 : }
314 35416 : n = 0;
315 35416 : delta = 1;
316 :
317 35416 : if ( reduce_bits > 0 )
318 : {
319 34022 : red_times = reduce_bits / ( coding_subbands * no_subframes ); /* number of complete reductions by 1 bit */
320 34022 : if ( red_times > 0 )
321 : {
322 155434 : for ( j = 0; j < coding_subbands; j++ )
323 : {
324 127775 : bits_dir0 = (int16_t *) q_direction->band_data[j].bits_sph_idx;
325 527944 : for ( k = 0; k < no_subframes; k++ )
326 : {
327 400169 : bits_dir0[k] -= red_times;
328 400169 : reduce_bits -= red_times;
329 :
330 400169 : if ( bits_dir0[k] < MASA_MIN_BITS_TF )
331 : {
332 59728 : reduce_bits += ( MASA_MIN_BITS_TF - bits_dir0[k] );
333 59728 : bits_dir0[k] = MASA_MIN_BITS_TF;
334 : }
335 : }
336 : }
337 : }
338 :
339 34022 : rem = reduce_bits; /* -coding_subbands*no_subframes*red_times; */
340 75745 : while ( n < rem )
341 : {
342 41723 : 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 221875 : for ( j = 0; j < coding_subbands; j++ )
350 : {
351 180152 : bits_dir0 = (int16_t *) q_direction->band_data[j].bits_sph_idx;
352 733225 : for ( k = 0; k < no_subframes; k++ )
353 : {
354 553073 : if ( ( n < rem ) && ( bits_dir0[k] > MASA_MIN_BITS_TF - delta ) )
355 : {
356 307579 : bits_dir0[k] -= 1;
357 307579 : n++;
358 : }
359 :
360 553073 : if ( max_nb < bits_dir0[k] )
361 : {
362 92667 : max_nb = bits_dir0[k];
363 : }
364 : }
365 : }
366 :
367 41723 : if ( max_nb <= MASA_MIN_BITS_TF )
368 : {
369 4105 : delta += 1;
370 : }
371 : }
372 :
373 34022 : reduce_bits = 0;
374 : }
375 :
376 35416 : if ( ind_order[0] == -1 )
377 : {
378 50935 : for ( j = 0; j < coding_subbands; j++ )
379 : {
380 38042 : ind_order[j] = j;
381 : }
382 : }
383 : else
384 : {
385 148493 : for ( j = 0; j < coding_subbands; j++ )
386 : {
387 125970 : penalty[j] = 0.0f;
388 429747 : for ( k = 0; k < no_subframes; k++ )
389 : {
390 303777 : if ( bits_sph_idx_orig[j][k] > 0 )
391 : {
392 303777 : 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 125970 : penalty[j] /= no_subframes;
396 : }
397 22523 : sort_desc_ind( penalty, coding_subbands, ind_order );
398 : }
399 :
400 35416 : *reduce_bits_out = -reduce_bits;
401 :
402 35416 : 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 104683 : 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 104683 : diff = *p_diff;
423 104683 : if ( diff < 0 )
424 : {
425 : /* increase bits for next subbands */
426 35533 : k = 0;
427 145436 : while ( ( diff < 0 ) && ( j < max_i ) && ( k < max_k ) )
428 : {
429 109903 : if ( q_direction->band_data[j].bits_sph_idx[k] < MASA_DIRECTION_MAX_BITS )
430 : {
431 109903 : q_direction->band_data[j].bits_sph_idx[k] += 1;
432 109903 : diff++;
433 : }
434 109903 : k++;
435 : }
436 : }
437 : else
438 : {
439 69150 : k = 0;
440 107689 : while ( ( diff > 0 ) && ( k < max_k ) )
441 : {
442 38539 : if ( q_direction->band_data[j].bits_sph_idx[k] > 0 )
443 : {
444 38539 : q_direction->band_data[j].bits_sph_idx[k] -= 1;
445 38539 : diff--;
446 : }
447 : }
448 : }
449 104683 : *p_diff = diff;
450 :
451 104683 : return;
452 : }
453 :
454 :
455 : /*---------------------------------------------------------------
456 : * invdct4_transform()
457 : *
458 : * Inverse DCT transform for 4D vector
459 : *---------------------------------------------------------------*/
460 :
461 587222 : 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 587222 : a = v[0] + v[2];
471 587222 : b = v[0] - v[2];
472 587222 : c = 1.306562964876376f * v[1] + 0.541196100146198f * v[3];
473 587222 : d = 0.541196100146198f * v[1] - 1.306562964876376f * v[3];
474 587222 : f_invdct_v[0] = 128 * ( a + c );
475 587222 : f_invdct_v[1] = 128 * ( b + d );
476 587222 : f_invdct_v[2] = 128 * ( b - d );
477 587222 : f_invdct_v[3] = 128 * ( a - c );
478 :
479 2936110 : for ( i = 0; i < 4; i++ )
480 : {
481 2348888 : if ( f_invdct_v[i] < 0.0 )
482 : {
483 252591 : invdct_v[i] = 0;
484 : }
485 : else
486 : {
487 2096297 : if ( f_invdct_v[i] > 255.0f )
488 : {
489 25 : f_invdct_v[i] = 255.0f;
490 : }
491 2096297 : invdct_v[i] = (uint8_t) f_invdct_v[i];
492 : }
493 : }
494 :
495 587222 : 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 766217 : 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 766217 : ratio1 = 1.0f - diffuseness_reconstructions[ratio_index_1];
520 766217 : ratio2 = 1.0f - diffuseness_reconstructions[ratio_index_2];
521 :
522 766217 : if ( !hodirac_flag )
523 : {
524 52284 : ratioSum = ratio1 + ratio2;
525 52284 : if ( ratio1 >= ratio2 )
526 : {
527 52284 : ratio2 = ratio2 / ratio1 * ratioSum;
528 52284 : ratio1 = ratioSum;
529 : }
530 : else
531 : {
532 0 : ratio1 = ratio1 / ratio2 * ratioSum;
533 0 : ratio2 = ratioSum;
534 : }
535 : }
536 :
537 766217 : *ratio_index_mod1 = masa_sq( 1.0f - ratio1, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
538 766217 : *ratio_index_mod2 = masa_sq( 1.0f - ratio2, diffuseness_thresholds, DIRAC_DIFFUSE_LEVELS );
539 :
540 : /* Limit maximum accuracy increase to conserve bits */
541 766217 : *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 766217 : *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 766217 : return;
545 : }
546 :
547 :
548 : /*---------------------------------------------------------------
549 : * set_qmetadata_maxbit_req()
550 : *
551 : * Sets proper value for qmetadata_max_bit_req limit
552 : *--------------------------------------------------------------*/
553 :
554 199242 : 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 199242 : if ( ivas_format == SBA_FORMAT )
560 : {
561 11851 : hQMetaData->qmetadata_max_bit_req = QMETADATA_MAXBIT_REQ_SBA;
562 : }
563 : else /* MASA_FORMAT */
564 : {
565 187391 : hQMetaData->qmetadata_max_bit_req = QMETADATA_MAXBIT_REQ_MASA;
566 : }
567 :
568 199242 : return;
569 : }
570 :
571 :
572 : /*-------------------------------------------------------------------------
573 : * ivas_qmetadata_azimuth_elevation_to_direction_vector()
574 : *
575 : *
576 : *------------------------------------------------------------------------*/
577 :
578 3269069 : 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 3269069 : dv[2] = sinf( el * PI_OVER_180 );
592 3269069 : radius_length = cosf( el * PI_OVER_180 );
593 3269069 : dv[0] = radius_length * cosf( az * PI_OVER_180 );
594 3269069 : dv[1] = radius_length * sinf( az * PI_OVER_180 );
595 :
596 3269069 : 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 2729983 : 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 2729983 : *el = atan2f( dv[2], sqrtf( dv[0] * dv[0] + dv[1] * dv[1] ) ) * _180_OVER_PI;
615 2729983 : *az = atan2f( dv[1], dv[0] ) * _180_OVER_PI;
616 :
617 2729983 : 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 713933 : 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 713933 : if ( index_diff >= DIFF_DFRATIO_1BIT_LIMIT_IDX )
635 : {
636 370497 : dfRatio_bits = 1;
637 : }
638 343436 : else if ( index_diff >= DIFF_DFRATIO_2BIT_LIMIT_IDX_HODIRAC )
639 : {
640 199325 : dfRatio_bits = 2;
641 : }
642 : else
643 : {
644 144111 : dfRatio_bits = 3;
645 : }
646 :
647 713933 : 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 52284 : 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 52284 : if ( index_diff >= DIFF_DFRATIO_1BIT_LIMIT_IDX )
666 : {
667 1075 : dfRatio_bits = 1;
668 : }
669 51209 : else if ( index_diff >= DIFF_DFRATIO_2BIT_LIMIT_IDX )
670 : {
671 43821 : dfRatio_bits = 2;
672 : }
673 : else
674 : {
675 7388 : dfRatio_bits = 3;
676 : }
677 :
678 52284 : return dfRatio_bits;
679 : }
|