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 "options.h"
36 : #include <math.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 : /*-------------------------------------------------------------------------
46 : * ivas_qmetadata_reorder_generic()
47 : *
48 : *------------------------------------------------------------------------*/
49 :
50 22074223 : uint16_t ivas_qmetadata_reorder_generic(
51 : const int16_t signed_value )
52 : {
53 : uint16_t unsigned_value;
54 :
55 22074223 : if ( signed_value < 0 )
56 : {
57 8863650 : unsigned_value = ( ( uint16_t ) - ( signed_value + 1 ) << 1 ) + 1;
58 : }
59 : else
60 : {
61 13210573 : unsigned_value = (uint16_t) signed_value << 1;
62 : }
63 :
64 22074223 : return unsigned_value;
65 : }
66 :
67 :
68 : /*-------------------------------------------------------------------------
69 : * ivas_qmetadata_dereorder_generic()
70 : *
71 : * Returns the original value of the array "folded" by ReorderGeneric
72 : *------------------------------------------------------------------------*/
73 :
74 : /*! r: "Unfolded" value, positive or negative depending on the value of the input */
75 20850591 : int16_t ivas_qmetadata_dereorder_generic(
76 : const uint16_t uns_value /* i : unsigned value result of ReorderGeneric */
77 : )
78 : {
79 20850591 : if ( ( uns_value & 1 ) != 0 )
80 : {
81 8388803 : return -(int16_t) ( uns_value >> 1 ) - 1;
82 : }
83 : else
84 : {
85 12461788 : return (int16_t) ( uns_value >> 1 );
86 : }
87 : }
88 :
89 :
90 : /*-------------------------------------------------------------------------
91 : * ivas_dirac_project_elevation_index()
92 : *
93 : *
94 : *------------------------------------------------------------------------*/
95 :
96 : /*! r: projected elevation index */
97 11907774 : int16_t ivas_dirac_project_elevation_index(
98 : const int16_t el_idx, /* i : elevation index */
99 : const int16_t el_alph, /* i : number of elevation symbols */
100 : const int16_t el_alph_proj /* i : size of projected alphabet */
101 : )
102 : {
103 : int16_t el_idx_proj;
104 : #ifdef DEBUGGING
105 : assert( ( el_idx >= 0 ) && ( el_idx < el_alph ) );
106 : assert( el_alph == 2 * ( el_alph >> 1 ) + 1 ); /* el_alph of the form 2 * n_points + 1 */
107 : assert( el_alph_proj == 2 * ( el_alph_proj >> 1 ) + 1 );
108 : #endif
109 :
110 : /* evaluate floor((el_idx / (el_alph - 1)) * (el_alph_proj - 1) + 0.5) using only integer */
111 11907774 : el_idx_proj = ( 2 * el_idx * ( el_alph_proj - 1 ) + ( el_alph - 1 ) ) / ( 2 * ( el_alph - 1 ) );
112 :
113 : #ifdef DEBUGGING
114 : assert( ( 0 <= el_idx_proj ) && ( el_idx_proj < el_alph_proj ) );
115 : #endif
116 11907774 : return el_idx_proj;
117 : }
118 :
119 :
120 : /*-------------------------------------------------------------------------
121 : * ivas_chan_project_elevation_index()
122 : *
123 : *
124 : *------------------------------------------------------------------------*/
125 :
126 : /*! r: projected index in channel mode */
127 104289 : int16_t ivas_chan_project_elevation_index(
128 : const int16_t el_idx, /* i : elevation index */
129 : const int16_t el_alph, /* i : number of elevation symbols */
130 : const int16_t el_alph_proj /* i : size of projected alphabet */
131 : )
132 : {
133 : int16_t el_idx_proj;
134 : #ifdef DEBUGGING
135 : assert( ( el_idx >= 0 ) && ( el_idx < el_alph ) );
136 : #endif
137 :
138 : /* evaluate floor((el_idx / (el_alph - 1)) * (el_alph_proj - 1) + 0.5) using only integer */
139 104289 : if ( el_idx == el_alph - 1 )
140 : {
141 9168 : el_idx_proj = el_alph_proj - 1;
142 : }
143 : else
144 : {
145 95121 : el_idx_proj = ( 2 * el_idx * el_alph_proj + el_alph ) / ( 2 * el_alph );
146 : }
147 :
148 : #ifdef DEBUGGING
149 : assert( ( 0 <= el_idx_proj ) && ( el_idx_proj < el_alph_proj ) );
150 : #endif
151 104289 : return el_idx_proj;
152 : }
153 :
154 :
155 : /*-------------------------------------------------------------------------
156 : * ivas_dirac_project_azimuth_index()
157 : *
158 : *
159 : *------------------------------------------------------------------------*/
160 :
161 : /*! r: projected azimuth index */
162 14113794 : int16_t ivas_dirac_project_azimuth_index(
163 : const int16_t az_idx, /* i : azimuth index */
164 : const int16_t az_alph, /* i : number of azimuth symbols */
165 : const int16_t az_alph_proj /* i : size of projected alphabet */
166 : )
167 : {
168 : int16_t az_idx_proj;
169 : #ifdef DEBUGGING
170 : assert( ( az_idx >= 0 ) && ( az_idx < az_alph ) );
171 : #endif
172 :
173 14113794 : if ( az_alph_proj == 1 )
174 : {
175 6114 : return 0;
176 : }
177 :
178 : /* evaluate floor((az_idx / az_alph) * az_alph_proj + 0.5) using only integer */
179 14107680 : az_idx_proj = ( 2 * az_idx * az_alph_proj + az_alph ) / ( 2 * az_alph );
180 :
181 14107680 : if ( az_idx_proj == az_alph_proj )
182 : {
183 274135 : az_idx_proj = 0;
184 : }
185 :
186 : #ifdef DEBUGGING
187 : assert( ( 0 <= az_idx_proj ) && ( az_idx_proj < az_alph_proj ) );
188 : #endif
189 14107680 : return az_idx_proj;
190 : }
191 :
192 :
193 : /*-------------------------------------------------------------------------
194 : * small_reduction_direction()
195 : *
196 : * Compute the allocated bit reduction in spherical indexing for bit budget
197 : * is exceeded by diff. bits
198 : *------------------------------------------------------------------------*/
199 :
200 12046 : void small_reduction_direction(
201 : IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */
202 : uint16_t bits_dir[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
203 : const int16_t raw_flag[MASA_MAXIMUM_CODING_SUBBANDS],
204 : int16_t *diff )
205 : {
206 : int16_t i, j, k;
207 :
208 29766 : for ( k = 0; ( k < 2 ) && ( *diff > 0 ); k++ )
209 : {
210 83724 : for ( i = q_direction->cfg.start_band; ( i < q_direction->cfg.nbands ) && ( *diff > 0 ); i++ )
211 : {
212 66004 : if ( raw_flag[i] == 1 )
213 : {
214 168744 : for ( j = 0; ( j < q_direction->cfg.nblocks ) && ( *diff > 0 ); j++ )
215 : {
216 133777 : if ( bits_dir[i][j] > MASA_MIN_BITS_TF )
217 : {
218 90205 : bits_dir[i][j] -= 1;
219 90205 : ( *diff )--;
220 : }
221 : }
222 : }
223 : }
224 : }
225 :
226 12046 : return;
227 : }
228 :
229 :
230 : /*-----------------------------------------------------------------------*
231 : * quantize_phi()
232 : *
233 : * Quantize azimuth.
234 : * Input phi expected to be an angle in degree between 0 and 360.
235 : *-----------------------------------------------------------------------*/
236 :
237 : /*! r: index azimuth */
238 6640316 : int16_t quantize_phi(
239 : float phi, /* i : azimuth value */
240 : const int16_t flag_delta, /* i : flag indicating if the azimuth codebook is translated or not */
241 : float *phi_hat, /* o : quantized azimuth */
242 : const int16_t n /* i : azimuth codebook size */
243 : )
244 : {
245 : int16_t id_phi;
246 : float dd;
247 : float delta_phi;
248 :
249 : #ifdef DEBUGGING
250 : assert( ( phi >= 0.f ) && ( phi <= 360.f ) );
251 : #endif
252 :
253 6640316 : delta_phi = 360.0f / (float) n;
254 :
255 6640316 : if ( n == 1 )
256 : {
257 0 : *phi_hat = 0;
258 :
259 0 : return 0;
260 : }
261 :
262 6640316 : if ( ( flag_delta == 1 ) && ( n > 2 ) )
263 : {
264 1563509 : dd = delta_phi / 2.0f;
265 : }
266 : else
267 : {
268 5076807 : dd = 0;
269 : }
270 6640316 : id_phi = (int16_t) round_f( ( ( phi - 180 - dd ) / (float) delta_phi ) );
271 6640316 : assert( fabsf( ( phi - 180 - dd ) / (float) delta_phi ) - abs( id_phi ) <= 0.5 );
272 :
273 6640316 : if ( id_phi + ( n >> 1 ) < 0 )
274 : {
275 29147 : id_phi += 1;
276 : }
277 :
278 6640316 : if ( id_phi - ( n >> 1 ) >= 0 )
279 : {
280 512963 : id_phi = -( n >> 1 );
281 : }
282 :
283 6640316 : if ( id_phi == -( ( n >> 1 ) + ( n % 2 ) ) )
284 : {
285 869065 : id_phi += ( n % 2 );
286 : }
287 : else
288 : {
289 5771251 : if ( id_phi == ( ( n >> 1 ) + ( n % 2 ) ) )
290 : {
291 0 : if ( n % 2 )
292 : {
293 0 : id_phi -= 1;
294 : }
295 : else
296 : {
297 0 : id_phi = -id_phi;
298 : }
299 : }
300 : }
301 :
302 6640316 : *phi_hat = id_phi * delta_phi + dd + 180;
303 :
304 6640316 : id_phi += ( n >> 1 );
305 :
306 6640316 : return id_phi;
307 : }
308 :
309 :
310 : /*-----------------------------------------------------------------------*
311 : * companding_azimuth()
312 : *
313 : * Compand azimuth based on the format
314 : *-----------------------------------------------------------------------*/
315 :
316 : /*! r: companded azimuth value */
317 557543 : float companding_azimuth(
318 : const float azi, /* i : input azimuth value */
319 : const MC_LS_SETUP mc_format, /* i : input channel format */
320 : const int16_t theta_flag, /* i : zero/non zero elevation flag */
321 : const int16_t direction /* i : direction of companding (direct or inverse)*/
322 : )
323 : {
324 557543 : const float pointsA[] = { 0.0f, 60.0f, 110.0f, 150.0f, 180.0f, 0.0f, 50.0f, 90.0f, 150.0f, 180.0f, 0.0f, 30.0f, 80.0f, 150.0f, 180.0f };
325 557543 : const float pointsB[] = { 0.0f, 90.0f, 110.0f, 170.0f, 180.0f, 0.0f, 90.0f, 110.0f, 170.0f, 180.0f, 0.0f, 10.0f, 100.0f, 170.0f, 180.0f };
326 : const float *pA, *pB;
327 : int16_t no_points;
328 : float comp_azi;
329 : int16_t i, not_done, start;
330 : float abs_azi;
331 :
332 557543 : if ( mc_format == MC_LS_SETUP_5_1 || mc_format == MC_LS_SETUP_5_1_2 || mc_format == MC_LS_SETUP_5_1_4 ) /* 5.1, 5.1+2 or 5.1+4*/
333 : {
334 454733 : start = 5;
335 : }
336 : else
337 : {
338 102810 : start = 0;
339 : }
340 :
341 : /* theta flag 1 is for non zero, larger than a threshold elevation */
342 557543 : if ( ( theta_flag == 1 ) && ( ( mc_format == MC_LS_SETUP_5_1_2 ) || ( mc_format == MC_LS_SETUP_5_1_4 ) || ( mc_format == MC_LS_SETUP_7_1_4 ) ) ) /* 5.1+2, 5.1+4 or 7.1+4*/
343 : {
344 46747 : start = 10;
345 : }
346 557543 : no_points = 5;
347 :
348 557543 : pA = &pointsA[start];
349 557543 : pB = &pointsB[start];
350 :
351 557543 : if ( direction == -1 ) /* inverse companding */
352 : {
353 438379 : pA = &pointsB[start];
354 438379 : pB = &pointsA[start];
355 : }
356 : else
357 : {
358 119164 : if ( direction != 1 )
359 : {
360 0 : printf( "Wrong direction in companding" );
361 : }
362 : }
363 :
364 557543 : not_done = 1;
365 557543 : abs_azi = fabsf( azi );
366 :
367 557543 : comp_azi = azi;
368 557543 : i = 0;
369 1217152 : while ( not_done && ( i < no_points - 1 ) )
370 : {
371 659609 : if ( abs_azi <= pA[i + 1] )
372 : {
373 557543 : not_done = 0;
374 : /* calculate companding */
375 557543 : comp_azi = pB[i] + ( pB[i + 1] - pB[i] ) / ( pA[i + 1] - pA[i] ) * ( abs_azi - pA[i] );
376 : }
377 : else
378 : {
379 102066 : i++;
380 : }
381 : }
382 :
383 557543 : if ( azi < 0 )
384 : {
385 236347 : comp_azi = -comp_azi;
386 : }
387 :
388 557543 : if ( not_done == 1 )
389 : {
390 0 : comp_azi = azi;
391 : }
392 :
393 557543 : return comp_azi;
394 : }
395 :
396 :
397 : /*-----------------------------------------------------------------------*
398 : * quantize_phi_chan_lbr()
399 : *
400 : * Quantize azimuth in low-bitrate channel mode.
401 : * Input phi expected to be an angle in degree between 0 and 360.
402 : *-----------------------------------------------------------------------*/
403 :
404 : /*! r: index azimuth */
405 2284 : int16_t quantize_phi_chan_lbr(
406 : const float phi, /* i : azimuth value */
407 : float *phi_hat, /* o : quantized azimuth */
408 : const int16_t n /* i : azimuth codebook size */
409 : )
410 : {
411 : int16_t id_phi;
412 :
413 : #ifdef DEBUGGING
414 : assert( ( phi >= -180.f ) && ( phi <= 180.f ) );
415 : assert( n <= 9 );
416 : #endif
417 :
418 2284 : if ( n <= 1 )
419 : {
420 0 : *phi_hat = 0;
421 :
422 0 : return 0;
423 : }
424 :
425 2284 : id_phi = squant( fabsf( phi ), phi_hat, cb_azi_chan, n >> 1 );
426 :
427 2284 : if ( phi < 0 && id_phi > 0 )
428 : {
429 909 : id_phi = 2 * id_phi - 1;
430 909 : *phi_hat = -*phi_hat;
431 : }
432 : else
433 : {
434 1375 : id_phi *= 2;
435 : }
436 :
437 2284 : return id_phi;
438 : }
439 :
440 :
441 : /*-----------------------------------------------------------------------*
442 : * quantize_phi_chan_compand()
443 : *
444 : * Quantize azimuth.
445 : * Input phi expected to be an angle in degree between 0 and 360.
446 : *-----------------------------------------------------------------------*/
447 :
448 : /*! r: index azimuth */
449 119164 : int16_t quantize_phi_chan_compand(
450 : float phi, /* i : azimuth value */
451 : float *phi_hat, /* o : quantized azimuth */
452 : const int16_t n, /* i : azimuth codebook size */
453 : const int16_t theta_flag, /* i : flag signaling high elevation */
454 : const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */
455 : )
456 : {
457 : int16_t id_phi;
458 : float delta_phi;
459 :
460 : #ifdef DEBUGGING
461 : assert( ( phi >= 0.f ) && ( phi <= 360.f ) );
462 : #endif
463 :
464 119164 : if ( n <= 1 )
465 : {
466 0 : *phi_hat = 0;
467 :
468 0 : return 0;
469 : }
470 :
471 119164 : phi = companding_azimuth( phi - 180, mc_format, theta_flag, 1 );
472 :
473 : /* quantize companded value */
474 119164 : delta_phi = 360.0f / (float) n;
475 119164 : id_phi = (int16_t) round_f( ( phi / (float) delta_phi ) );
476 :
477 119164 : if ( id_phi + ( n >> 1 ) < 0 )
478 : {
479 0 : id_phi += 1;
480 : }
481 119164 : if ( id_phi - ( n >> 1 ) >= 0 )
482 : {
483 775 : id_phi = -( n >> 1 );
484 : }
485 :
486 119164 : if ( id_phi == -( ( n >> 1 ) + ( n % 2 ) ) )
487 : {
488 919 : id_phi += ( n % 2 );
489 : }
490 : else
491 : {
492 118245 : if ( id_phi == ( ( n >> 1 ) + ( n % 2 ) ) )
493 : {
494 0 : if ( n % 2 )
495 : {
496 0 : id_phi -= 1;
497 : }
498 : else
499 : {
500 0 : id_phi = -id_phi;
501 : }
502 : }
503 : }
504 119164 : *phi_hat = id_phi * delta_phi;
505 :
506 119164 : id_phi += ( n >> 1 );
507 :
508 :
509 119164 : *phi_hat = companding_azimuth( *phi_hat, mc_format, theta_flag, -1 ) + 180;
510 :
511 119164 : return id_phi;
512 : }
|