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_prot.h"
39 : #include "ivas_rom_com.h"
40 : #include "ivas_stat_enc.h"
41 : #include "wmc_auto.h"
42 : #include "prot.h"
43 :
44 :
45 : /*-----------------------------------------------------------------------*
46 : * Local function prototypes
47 : *-----------------------------------------------------------------------*/
48 :
49 : static float quantize_theta_phi( float *theta_cb, const int16_t no_th, const int16_t *no_phi_loc, const float abs_theta, int16_t *id_phi, int16_t *id_phi_remap, float *phi_hat, const float phi, const int16_t no_bits, int16_t *id_theta, float *phi_q, const int16_t remap, const MC_LS_SETUP mc_format );
50 :
51 : static float direction_distance_cp( float theta, float theta_hat, float theta_hat1, const float phi, const float phi_hat, const float phi_hat1, float *d1 );
52 :
53 : /*-------------------------------------------------------------------*
54 : * quantize_direction_frame()
55 : *
56 : *
57 : *----------------------------------------------------------------------*/
58 :
59 3748016 : void quantize_direction_frame(
60 : IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */
61 : float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
62 : float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
63 : const int16_t hrmasa_flag /* i : flag indicating high-rate MASA MD coding*/
64 : )
65 : {
66 : int16_t i, j;
67 : uint16_t idx;
68 :
69 : /* Quantize directions */
70 3748016 : q_direction->not_in_2D = 0;
71 22686137 : for ( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
72 : {
73 18938121 : idx = q_direction->band_data[i].energy_ratio_index_mod[0];
74 79237614 : for ( j = 0; j < q_direction->cfg.nblocks; j++ )
75 : {
76 60299493 : if ( azimuth_orig != NULL )
77 : {
78 60299493 : azimuth_orig[i][j] = q_direction->band_data[i].azimuth[j];
79 : }
80 :
81 60299493 : if ( elevation_orig != NULL )
82 : {
83 60299493 : elevation_orig[i][j] = q_direction->band_data[i].elevation[j];
84 : }
85 :
86 : /* requantize the direction */
87 120598986 : q_direction->band_data[i].spherical_index[j] = quantize_direction( q_direction->band_data[i].elevation[j],
88 60299493 : q_direction->band_data[i].azimuth[j],
89 60299493 : q_direction->band_data[i].bits_sph_idx[j],
90 60299493 : &q_direction->band_data[i].elevation[j],
91 60299493 : &q_direction->band_data[i].azimuth[j], &q_direction->band_data[i].elevation_index[j],
92 60299493 : &q_direction->band_data[i].azimuth_index[j],
93 : q_direction->cfg.mc_ls_setup );
94 :
95 60299493 : q_direction->not_in_2D += q_direction->band_data[i].elevation_index[j];
96 :
97 60299493 : if ( hrmasa_flag )
98 : {
99 3100497 : if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
100 : {
101 0 : q_direction->band_data[i].elevation_m_alphabet[j] = no_theta_masa[bits_direction_masa[0] - 3];
102 0 : q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[0] - 1][q_direction->band_data[i].elevation_index[j]];
103 : }
104 : else
105 : {
106 3100497 : q_direction->band_data[i].elevation_m_alphabet[j] = no_theta_masa[bits_direction_masa[0] - 3] * 2 - 1;
107 3100497 : q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[0] - 1][( q_direction->band_data[i].elevation_index[j] + 1 ) >> 1];
108 : }
109 : }
110 : else
111 : {
112 57198996 : if ( q_direction->cfg.mc_ls_setup != MC_LS_SETUP_INVALID )
113 : {
114 1517303 : q_direction->band_data[i].elevation_m_alphabet[j] = no_theta_masa[bits_direction_masa[idx] - 3];
115 1517303 : q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[idx] - 1][q_direction->band_data[i].elevation_index[j]];
116 : }
117 : else
118 : {
119 55681693 : q_direction->band_data[i].elevation_m_alphabet[j] = no_theta_masa[bits_direction_masa[idx] - 3] * 2 - 1;
120 55681693 : q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[idx] - 1][( q_direction->band_data[i].elevation_index[j] + 1 ) >> 1];
121 : }
122 : }
123 :
124 60299493 : if ( q_direction->band_data[i].azimuth_index[j] == MASA_NO_INDEX )
125 : {
126 148380 : q_direction->band_data[i].azimuth_index[j] = 0;
127 : }
128 :
129 60299493 : if ( q_direction->band_data[i].bits_sph_idx[j] <= 2 )
130 : {
131 0 : q_direction->band_data[i].elevation_index[j] = 0;
132 : }
133 : else
134 : {
135 60299493 : if ( q_direction->cfg.mc_ls_setup == MC_LS_SETUP_INVALID )
136 : {
137 : /*deorder elevation indexing*/
138 58782190 : if ( ( q_direction->band_data[i].elevation_index[j] & 1 ) != 0 )
139 : {
140 14479082 : q_direction->band_data[i].elevation_index[j] = ( ( q_direction->band_data[i].elevation_index[j] + 1 ) >> 1 ) + ( q_direction->band_data[i].elevation_m_alphabet[j] >> 1 );
141 : }
142 : else
143 : {
144 44303108 : q_direction->band_data[i].elevation_index[j] = -( ( q_direction->band_data[i].elevation_index[j] ) >> 1 ) + ( q_direction->band_data[i].elevation_m_alphabet[j] >> 1 );
145 : }
146 : }
147 : }
148 : }
149 : }
150 :
151 3748016 : if ( q_direction->not_in_2D > 0 )
152 : {
153 3108369 : q_direction->not_in_2D = 1 + MASA_LIMIT_2D;
154 : }
155 :
156 3748016 : return;
157 : }
158 :
159 :
160 : /*-------------------------------------------------------------------*
161 : * quantize_direction_frame2D()
162 : *
163 : *
164 : *----------------------------------------------------------------------*/
165 :
166 98776 : void quantize_direction_frame2D(
167 : IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */
168 : float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
169 : float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES] )
170 : {
171 : int16_t i, j;
172 : uint16_t idx;
173 : /* Quantize directions */
174 98776 : q_direction->not_in_2D = 0;
175 531872 : for ( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
176 : {
177 433096 : idx = q_direction->band_data[i].energy_ratio_index[0];
178 1261250 : for ( j = 0; j < q_direction->cfg.nblocks; j++ )
179 : {
180 828154 : if ( azimuth_orig != NULL )
181 : {
182 828154 : azimuth_orig[i][j] = q_direction->band_data[i].azimuth[j];
183 : }
184 828154 : if ( elevation_orig != NULL )
185 : {
186 828154 : elevation_orig[i][j] = q_direction->band_data[i].elevation[j];
187 : }
188 828154 : q_direction->band_data[i].azimuth_m_alphabet[j] = no_phi_masa[bits_direction_masa[idx] - 1][0];
189 :
190 : /* requantize the direction */
191 1656308 : q_direction->band_data[i].spherical_index[j] = quantize_direction2D( q_direction->band_data[i].azimuth[j],
192 828154 : q_direction->band_data[i].azimuth_m_alphabet[j],
193 828154 : &q_direction->band_data[i].azimuth[j],
194 828154 : &q_direction->band_data[i].azimuth_index[j],
195 : q_direction->cfg.mc_ls_setup );
196 :
197 828154 : q_direction->band_data[i].elevation_m_alphabet[j] = 1;
198 : }
199 : }
200 :
201 98776 : return;
202 : }
203 :
204 :
205 : /*-------------------------------------------------------------------*
206 : * small_requantize_direction_frame()
207 : *
208 : *
209 : *----------------------------------------------------------------------*/
210 :
211 118406 : void small_requantize_direction_frame(
212 : IVAS_QDIRECTION *q_direction, /* i/o: quantized direction structure */
213 : float azimuth_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
214 : float elevation_orig[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES],
215 : const int16_t raw_flag[MASA_MAXIMUM_CODING_SUBBANDS],
216 : int16_t bits_dir_bands[MASA_MAXIMUM_CODING_SUBBANDS],
217 : int16_t *diff )
218 : {
219 : int16_t i, j;
220 : uint16_t bits_dir[MASA_MAXIMUM_CODING_SUBBANDS][MAX_PARAM_SPATIAL_SUBFRAMES];
221 :
222 118406 : if ( ( *diff > 0 ) && ( q_direction->not_in_2D > 0 ) )
223 : {
224 556371 : for ( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
225 : {
226 2277940 : for ( j = 0; j < q_direction->cfg.nblocks; j++ )
227 : {
228 1822352 : bits_dir[i][j] = q_direction->band_data[i].bits_sph_idx[j];
229 : }
230 : }
231 :
232 100783 : small_reduction_direction( q_direction, bits_dir, raw_flag, diff );
233 :
234 100783 : if ( *diff <= 0 )
235 : {
236 124996 : for ( i = q_direction->cfg.start_band; i < q_direction->cfg.nbands; i++ )
237 : {
238 104074 : if ( raw_flag[i] == 1 )
239 : {
240 78812 : bits_dir_bands[i] = 0;
241 394060 : for ( j = 0; j < q_direction->cfg.nblocks; j++ )
242 : {
243 315248 : bits_dir_bands[i] += bits_dir[i][j];
244 315248 : q_direction->band_data[i].bits_sph_idx[j] = bits_dir[i][j];
245 :
246 : /* requantize the direction */
247 630496 : q_direction->band_data[i].spherical_index[j] = quantize_direction(
248 315248 : elevation_orig[i][j], azimuth_orig[i][j],
249 315248 : q_direction->band_data[i].bits_sph_idx[j],
250 315248 : &q_direction->band_data[i].elevation[j], &q_direction->band_data[i].azimuth[j],
251 315248 : &q_direction->band_data[i].elevation_index[j], &q_direction->band_data[i].azimuth_index[j],
252 : q_direction->cfg.mc_ls_setup );
253 :
254 315248 : if ( q_direction->band_data[i].azimuth_index[j] == MASA_NO_INDEX )
255 : {
256 547 : q_direction->band_data[i].azimuth_index[j] = 0;
257 : }
258 : }
259 : }
260 : }
261 : }
262 : }
263 :
264 118406 : return;
265 : }
266 :
267 :
268 : /*-------------------------------------------------------------------*
269 : * quantize_direction()
270 : *
271 : *
272 : *----------------------------------------------------------------------*/
273 :
274 : /*! r: quantized spherical index */
275 62564688 : uint16_t quantize_direction(
276 : const float theta, /* i : input elevation value */
277 : float phi, /* i : input azimuth value */
278 : const int16_t no_bits, /* i : number of bits */
279 : float *theta_q, /* o : quantized elevation */
280 : float *phi_q, /* o : quantized azimuth */
281 : uint16_t *index_theta, /* o : quantized elevation index */
282 : uint16_t *index_phi, /* o : quantized azimuth index */
283 : const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */
284 : )
285 : {
286 : float abs_theta, theta_hat, phi_hat;
287 : int16_t i, sign_th;
288 : int16_t cum_n[500];
289 : int16_t id_th, id_phi;
290 : float theta_cb[MAX_NO_THETA];
291 : int16_t no_th;
292 : uint16_t idx_sph;
293 : int16_t id_phi_remap;
294 :
295 62564688 : if ( no_bits == 0 )
296 : {
297 0 : *theta_q = 0;
298 0 : *phi_q = 0;
299 0 : *index_theta = MASA_NO_INDEX;
300 0 : *index_phi = MASA_NO_INDEX;
301 0 : return 0;
302 : }
303 :
304 62564688 : if ( no_bits == 1 )
305 : {
306 4 : *theta_q = 0;
307 4 : *index_theta = MASA_NO_INDEX;
308 4 : if ( ( phi < -90 ) || ( phi > 90 ) )
309 : {
310 0 : *phi_q = -180;
311 0 : *index_phi = 1;
312 :
313 0 : return 1;
314 : }
315 : else
316 : {
317 4 : *phi_q = 0;
318 4 : *index_phi = 0;
319 :
320 4 : return 0;
321 : }
322 : }
323 :
324 62564684 : if ( no_bits == 2 )
325 : {
326 14149 : *theta_q = 0;
327 14149 : *index_theta = MASA_NO_INDEX;
328 14149 : if ( mc_format != MC_LS_SETUP_INVALID )
329 : {
330 2198 : id_phi = quantize_phi_chan_lbr( phi, &phi_hat, no_phi_masa[no_bits - 1][0] );
331 2198 : phi_hat += 180;
332 2198 : idx_sph = id_phi;
333 2198 : *phi_q = phi_hat - 180;
334 2198 : id_phi_remap = id_phi;
335 2198 : *index_phi = id_phi_remap;
336 : }
337 : else
338 : {
339 11951 : id_phi = quantize_phi( phi + 180, 0, &phi_hat, no_phi_masa[no_bits - 1][0] );
340 11951 : idx_sph = id_phi;
341 11951 : *phi_q = phi_hat - 180;
342 11951 : id_phi_remap = ivas_qmetadata_reorder_generic( id_phi - ( no_phi_masa[no_bits - 1][0] >> 1 ) );
343 11951 : *index_phi = id_phi_remap;
344 : }
345 :
346 14149 : return idx_sph;
347 : }
348 :
349 62550535 : no_th = no_theta_masa[no_bits - 3];
350 :
351 530101623 : for ( i = 0; i < no_th; i++ )
352 : {
353 467551088 : theta_cb[i] = i * delta_theta_masa[no_bits - 3];
354 : }
355 :
356 62550535 : if ( theta_cb[i - 1] > 90 )
357 : {
358 27618204 : theta_cb[i - 1] = 90;
359 : }
360 :
361 62550535 : phi = phi + 180;
362 :
363 62550535 : if ( theta < 0 )
364 : {
365 22576503 : abs_theta = -theta;
366 22576503 : sign_th = -1;
367 : }
368 : else
369 : {
370 39974032 : abs_theta = theta;
371 39974032 : sign_th = 1;
372 : }
373 :
374 62550535 : theta_hat = quantize_theta_phi( theta_cb, no_th, no_phi_masa[no_bits - 1], abs_theta, &id_phi,
375 : &id_phi_remap, &phi_hat, phi, no_bits, &id_th, phi_q, 1, mc_format );
376 :
377 62550535 : if ( mc_format != MC_LS_SETUP_INVALID )
378 : {
379 : /* indexing only for upper hemisphere */
380 1994405 : cum_n[0] = no_phi_masa[no_bits - 1][0];
381 9704274 : for ( i = 1; i < no_th; i++ )
382 : {
383 7709869 : cum_n[i] = cum_n[i - 1] + no_phi_masa[no_bits - 1][i];
384 : }
385 :
386 1994405 : if ( id_phi < MASA_NO_INDEX )
387 : {
388 1981602 : if ( id_th == 0 )
389 : {
390 445158 : idx_sph = id_phi;
391 : }
392 : else
393 : {
394 1536444 : idx_sph = cum_n[id_th - 1] + id_phi;
395 : }
396 : }
397 : else
398 : {
399 12803 : if ( id_th == 0 )
400 : {
401 0 : idx_sph = 0;
402 : }
403 : else
404 : {
405 12803 : idx_sph = cum_n[id_th - 1];
406 : }
407 : }
408 1994405 : *theta_q = theta_hat;
409 1994405 : if ( theta_hat == 90 )
410 : {
411 12158 : *phi_q = 0;
412 12158 : id_phi = MASA_NO_INDEX;
413 : }
414 : else
415 : {
416 1982247 : *phi_q = phi_hat - 180;
417 : }
418 1994405 : *index_theta = id_th;
419 1994405 : *index_phi = id_phi_remap;
420 : }
421 : else
422 : {
423 : /* Starting from Equator, alternating positive and negative */
424 60556130 : cum_n[0] = no_phi_masa[no_bits - 1][0];
425 457846814 : for ( i = 1; i < no_th; i++ )
426 : {
427 397290684 : cum_n[2 * i - 1] = cum_n[2 * i - 2] + no_phi_masa[no_bits - 1][i];
428 397290684 : cum_n[2 * i] = cum_n[2 * i - 1] + no_phi_masa[no_bits - 1][i];
429 : }
430 :
431 60556130 : if ( no_th > 0 )
432 : {
433 60556130 : assert( abs( cum_n[2 * ( no_th - 1 )] ) < 32768 );
434 : }
435 :
436 60556130 : if ( id_th == 0 )
437 : {
438 34636176 : if ( id_phi < MASA_NO_INDEX )
439 : {
440 34636176 : idx_sph = id_phi;
441 : }
442 : else
443 : {
444 0 : idx_sph = 0;
445 : }
446 : }
447 : else
448 : {
449 25919954 : if ( sign_th > 0 )
450 : {
451 14897882 : if ( id_phi < MASA_NO_INDEX )
452 : {
453 14831173 : idx_sph = cum_n[2 * id_th - 2] + id_phi;
454 : }
455 : else
456 : {
457 66709 : idx_sph = cum_n[2 * id_th - 2];
458 : }
459 :
460 14897882 : id_th = 2 * id_th - 1;
461 : }
462 : else
463 : {
464 11022072 : if ( id_phi < MASA_NO_INDEX )
465 : {
466 10948493 : idx_sph = cum_n[2 * id_th - 1] + id_phi;
467 : }
468 : else
469 : {
470 73579 : idx_sph = cum_n[2 * id_th - 1];
471 : }
472 11022072 : id_th = 2 * id_th;
473 : }
474 : }
475 :
476 60556130 : *theta_q = sign_th * theta_hat;
477 60556130 : if ( theta_hat == 90 )
478 : {
479 131089 : *phi_q = 0;
480 131089 : id_phi = MASA_NO_INDEX;
481 : }
482 : else
483 : {
484 60425041 : *phi_q = phi_hat - 180;
485 : }
486 :
487 60556130 : *index_theta = id_th;
488 60556130 : *index_phi = id_phi_remap;
489 : }
490 :
491 62550535 : return idx_sph;
492 : }
493 :
494 :
495 : /*-------------------------------------------------------------------*
496 : * direction_distance_cp()
497 : *
498 : * quantization distortion calculated on the sphere
499 : *----------------------------------------------------------------------*/
500 :
501 : /*! r: distortion value */
502 33714126 : static float direction_distance_cp(
503 : float theta, /* i : elevation absolute value */
504 : float theta_hat, /* i : quantized elevation value in absolute value */
505 : float theta_hat1, /* i : quantized elevation value in absolute value */
506 : const float phi, /* i : azimuth value */
507 : const float phi_hat, /* i : quantized azimuth value */
508 : const float phi_hat1, /* i : quantized azimuth value */
509 : float *d1 )
510 : {
511 : float d, ct, st, st1, st2;
512 :
513 33714126 : theta *= PI_OVER_180;
514 33714126 : theta_hat *= PI_OVER_180;
515 33714126 : theta_hat1 *= PI_OVER_180;
516 33714126 : st = sinf( theta );
517 33714126 : ct = cosf( theta );
518 33714126 : st1 = sinf( theta_hat );
519 33714126 : st2 = sinf( theta_hat1 );
520 :
521 33714126 : d = st * st1 + ct * ( sqrtf( 1 - st1 * st1 ) ) * cosf( ( phi - phi_hat ) * PI_OVER_180 );
522 33714126 : *d1 = st * st2 + ct * ( sqrtf( 1 - st2 * st2 ) ) * cosf( ( phi - phi_hat1 ) * PI_OVER_180 );
523 :
524 33714126 : return d;
525 : }
526 :
527 :
528 : /*-------------------------------------------------------------------*
529 : * quantize_theta_phi()
530 : *
531 : * joint quantization of elevation and azimuth
532 : *----------------------------------------------------------------------*/
533 :
534 : /*! r: quantized elevation value */
535 62550535 : static float quantize_theta_phi(
536 : float *theta_cb, /* i : elevation codebook */
537 : const int16_t no_th, /* i : elevation codebook size */
538 : const int16_t *no_phi_loc, /* i : number of azimuth values for each elevation codeword*/
539 : const float abs_theta, /* i : absolute value of elevation to be quantized */
540 : int16_t *id_phi, /* o : azimuth index */
541 : int16_t *id_phi_remap, /* o : remapped azimuth index */
542 : float *phi_hat, /* o : quantized azimuth value */
543 : const float phi, /* i : input azimuth value; to be quantized */
544 : const int16_t no_bits, /* i : number of bits used for quantization */
545 : int16_t *id_theta, /* o : elevation index */
546 : float *phi_q, /* o : rotated quantized azimuth */
547 : const int16_t remap, /* i : flag for remapping */
548 : const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */
549 : )
550 : {
551 : float theta_hat, theta_hat1, phi_hat1;
552 : int16_t id_th, id_th1, id_th2, id_ph, id_ph1;
553 : float d, d1;
554 :
555 62550535 : id_th = (int16_t) ( abs_theta / delta_theta_masa[no_bits - 3] );
556 62550535 : if ( id_th >= no_th )
557 : {
558 7306 : id_th = no_th - 1;
559 : }
560 62550535 : theta_hat = theta_cb[id_th];
561 62550535 : if ( id_th < no_th - 1 )
562 : {
563 58605897 : id_th += squant( abs_theta, &theta_hat, &theta_cb[id_th], 2 );
564 : }
565 :
566 62550535 : if ( no_th > 1 )
567 : {
568 62550535 : if ( ( no_th < 6 ) && mc_format == MC_LS_SETUP_INVALID )
569 : {
570 34420852 : if ( id_th == 0 )
571 : {
572 18770804 : id_th1 = 1;
573 : }
574 15650048 : else if ( id_th == no_th - 1 )
575 : {
576 8658480 : id_th1 = no_th - 2;
577 : }
578 : else
579 : {
580 6991568 : id_th1 = id_th - 1;
581 6991568 : id_th2 = id_th + 1;
582 :
583 6991568 : if ( fabsf( abs_theta - theta_cb[id_th1] ) > fabsf( abs_theta - theta_cb[id_th2] ) )
584 : {
585 2651486 : id_th1 = id_th2;
586 : }
587 : }
588 : }
589 : else
590 : {
591 28129683 : id_th1 = id_th;
592 : }
593 :
594 62550535 : if ( no_phi_loc[id_th] > 1 )
595 : {
596 : /* Note: (id_th % 2 == 1) must be equal to id_th % 2 */
597 62397444 : if ( mc_format != MC_LS_SETUP_INVALID )
598 : {
599 1981602 : id_ph = quantize_phi_chan_compand( phi, phi_hat, no_phi_loc[id_th], ( theta_cb[id_th] > MC_MASA_THR_ELEVATION ), mc_format );
600 1981602 : *id_phi_remap = id_ph;
601 : }
602 : else
603 : {
604 60415842 : id_ph = quantize_phi( phi, ( id_th % 2 == 1 ), phi_hat, no_phi_loc[id_th] );
605 : }
606 : }
607 : else
608 : {
609 153091 : id_ph = MASA_NO_INDEX;
610 153091 : *id_phi_remap = MASA_NO_INDEX;
611 153091 : *phi_hat = 180;
612 153091 : *phi_q = 0;
613 : }
614 :
615 62550535 : if ( ( no_phi_loc[id_th1] > 1 ) && ( id_ph < MASA_NO_INDEX ) && ( no_th < 6 ) && ( mc_format == MC_LS_SETUP_INVALID ) )
616 : {
617 33714126 : theta_hat1 = theta_cb[id_th1];
618 :
619 33714126 : id_ph1 = quantize_phi( phi, ( id_th1 % 2 == 1 ), &phi_hat1, no_phi_loc[id_th1] );
620 :
621 33714126 : d = direction_distance_cp( abs_theta, theta_hat, theta_hat1, phi, *phi_hat, phi_hat1, &d1 );
622 :
623 33714126 : if ( d1 > d )
624 : {
625 3328393 : *phi_hat = phi_hat1;
626 3328393 : id_ph = id_ph1;
627 3328393 : theta_hat = theta_cb[id_th1];
628 3328393 : id_th = id_th1;
629 : }
630 : }
631 : }
632 : else
633 : {
634 0 : if ( mc_format != MC_LS_SETUP_INVALID )
635 : {
636 0 : id_ph = quantize_phi_chan_compand( phi, phi_hat, no_phi_loc[id_th], 0, mc_format );
637 0 : *id_phi_remap = id_ph;
638 : }
639 : else
640 : {
641 0 : id_ph = quantize_phi( phi, ( id_th % 2 == 1 ), phi_hat, no_phi_loc[id_th] );
642 : }
643 : }
644 :
645 62550535 : if ( remap )
646 : {
647 62550535 : if ( id_ph < MASA_NO_INDEX )
648 : {
649 62397444 : *id_phi_remap = ivas_qmetadata_reorder_generic( id_ph - ( no_phi_loc[id_th] >> 1 ) );
650 : }
651 : }
652 : else
653 : {
654 0 : *id_phi_remap = id_ph;
655 : }
656 :
657 62550535 : *id_phi = id_ph;
658 62550535 : *id_theta = id_th;
659 :
660 62550535 : return theta_hat;
661 : }
|