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 "prot_fx.h"
40 : #include "cnst.h"
41 : #include "wmc_auto.h"
42 : #include "ivas_prot_fx.h"
43 : #include "ivas_rom_com_fx.h"
44 :
45 : /*-----------------------------------------------------------------------*
46 : * Local function prototypes
47 : *-----------------------------------------------------------------------*/
48 :
49 :
50 : static UWord16 deindex_sph_idx_general_fx( const Word16 idx_sph, const Word16 no_bits, Word32 *theta_dec_fx, Word32 *phi_dec_fx, UWord16 *p_id_phi, const MC_LS_SETUP mc_format );
51 :
52 : /*-------------------------------------------------------------------------
53 : * ivas_get_hodirac_flag()
54 : *
55 : * Return flag for HO-DirAC method at high bitrates
56 : *------------------------------------------------------------------------*/
57 :
58 : /*! r: HO-DirAC flag */
59 872869 : Word16 ivas_get_hodirac_flag_fx(
60 : const Word32 ivas_total_brate, /* i : IVAS total bitrate */
61 : const Word16 sba_order /* i : Ambisonic (SBA) order */
62 : )
63 : {
64 872869 : test();
65 872869 : IF( GT_16( sba_order, 1 ) && GT_32( ivas_total_brate, IVAS_256k ) )
66 : {
67 127231 : return 1;
68 : }
69 : ELSE
70 : {
71 745638 : return 0;
72 : }
73 : }
74 : /*-------------------------------------------------------------------------
75 : * ivas_dirac_sba_config()
76 : *
77 : * DirAC Configuration function; used also in MASA decoder
78 : *------------------------------------------------------------------------*/
79 4466 : ivas_error ivas_dirac_config_fx(
80 : void *st_ivas, /* i/o: IVAS encoder/decoder state structure */
81 : const Word16 enc_dec /* i : encoder or decoder flag */
82 : )
83 : {
84 : IVAS_FORMAT ivas_format;
85 : Word16 sba_order;
86 : Word16 *element_mode;
87 : Word32 ivas_total_brate;
88 : DIRAC_CONFIG_DATA_HANDLE hConfig;
89 : IVAS_QMETADATA_HANDLE hQMetaData;
90 : Word32 Fs;
91 : Word16 *band_grouping;
92 : ivas_error error;
93 : Word16 spar_dirac_split_band;
94 : IVAS_FB_MIXER_HANDLE hFbMdft;
95 : Word16 *dirac_to_spar_md_bands;
96 :
97 4466 : error = IVAS_ERR_OK;
98 4466 : move32();
99 :
100 4466 : IF( enc_dec == ENC )
101 : {
102 0 : ivas_format = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->ivas_format;
103 0 : move32();
104 0 : element_mode = &( (Encoder_Struct *) st_ivas )->hEncoderConfig->element_mode_init;
105 0 : sba_order = ( (Encoder_Struct *) st_ivas )->sba_analysis_order;
106 0 : move16();
107 0 : ivas_total_brate = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->ivas_total_brate;
108 0 : move32();
109 0 : Fs = ( (Encoder_Struct *) st_ivas )->hEncoderConfig->input_Fs;
110 0 : move32();
111 0 : band_grouping = ( (Encoder_Struct *) st_ivas )->hDirAC->band_grouping;
112 0 : hConfig = ( (Encoder_Struct *) st_ivas )->hDirAC->hConfig;
113 0 : hQMetaData = ( (Encoder_Struct *) st_ivas )->hQMetaData;
114 0 : IF( ( (Encoder_Struct *) st_ivas )->hSpar != NULL )
115 : {
116 0 : hFbMdft = ( (Encoder_Struct *) st_ivas )->hSpar->hFbMixer;
117 0 : dirac_to_spar_md_bands = ( (Encoder_Struct *) st_ivas )->hSpar->dirac_to_spar_md_bands;
118 : }
119 : ELSE
120 : {
121 0 : hFbMdft = NULL;
122 0 : dirac_to_spar_md_bands = NULL;
123 : }
124 : }
125 : ELSE
126 : {
127 4466 : ivas_format = ( (Decoder_Struct *) st_ivas )->ivas_format;
128 4466 : element_mode = &( (Decoder_Struct *) st_ivas )->element_mode_init;
129 4466 : sba_order = ( (Decoder_Struct *) st_ivas )->sba_analysis_order;
130 4466 : move16();
131 4466 : ivas_total_brate = ( (Decoder_Struct *) st_ivas )->hDecoderConfig->ivas_total_brate;
132 4466 : move32();
133 4466 : Fs = ( (Decoder_Struct *) st_ivas )->hDecoderConfig->output_Fs;
134 4466 : move32();
135 4466 : band_grouping = ( (Decoder_Struct *) st_ivas )->hDirAC->band_grouping;
136 4466 : hConfig = ( (Decoder_Struct *) st_ivas )->hDirAC->hConfig;
137 4466 : hQMetaData = ( (Decoder_Struct *) st_ivas )->hQMetaData;
138 4466 : IF( ( (Decoder_Struct *) st_ivas )->hSpar != NULL )
139 : {
140 1252 : hFbMdft = ( (Decoder_Struct *) st_ivas )->hSpar->hFbMixer;
141 1252 : dirac_to_spar_md_bands = ( (Decoder_Struct *) st_ivas )->hSpar->dirac_to_spar_md_bands;
142 : }
143 : ELSE
144 : {
145 3214 : hFbMdft = NULL;
146 3214 : dirac_to_spar_md_bands = NULL;
147 : }
148 4466 : ( (Decoder_Struct *) st_ivas )->hDirAC->hFbMdft = hFbMdft;
149 : }
150 :
151 4466 : test();
152 4466 : IF( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) )
153 : {
154 1252 : hConfig->nbands = IVAS_MAX_NUM_BANDS;
155 1252 : move16();
156 :
157 1252 : spar_dirac_split_band = s_min( IVAS_MAX_NUM_BANDS, SPAR_DIRAC_SPLIT_START_BAND );
158 :
159 1252 : IF( ivas_get_hodirac_flag_fx( ivas_total_brate, sba_order ) ) // add call after merge of 100861_dirac_dec
160 : {
161 126 : spar_dirac_split_band = 0;
162 126 : move16();
163 : }
164 : }
165 : ELSE
166 : {
167 3214 : hConfig->nbands = 5;
168 3214 : spar_dirac_split_band = 0;
169 :
170 3214 : move16();
171 3214 : move16();
172 : }
173 4466 : hConfig->enc_param_start_band = 0;
174 4466 : hConfig->dec_param_estim = FALSE;
175 :
176 4466 : move16();
177 4466 : move16();
178 :
179 4466 : test();
180 4466 : IF( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) ) /* skip for MASA decoder */
181 : {
182 1252 : IF( NE_32( ( error = ivas_dirac_sba_config_fx( hQMetaData, element_mode, ivas_total_brate, sba_order, sub( hConfig->nbands, spar_dirac_split_band ), ivas_format ) ), IVAS_ERR_OK ) )
183 : {
184 0 : return error;
185 : }
186 :
187 1252 : IF( hQMetaData != NULL )
188 : {
189 1252 : if ( enc_dec == ENC )
190 : {
191 0 : hConfig->nbands = hQMetaData->q_direction[0].cfg.nbands;
192 0 : move16();
193 : }
194 1252 : hConfig->enc_param_start_band = add( hQMetaData->q_direction[0].cfg.start_band, spar_dirac_split_band );
195 1252 : move16();
196 : }
197 :
198 1252 : hConfig->dec_param_estim = TRUE;
199 1252 : move16();
200 1252 : if ( EQ_16( hConfig->dec_param_estim, TRUE ) )
201 : {
202 1252 : hConfig->enc_param_start_band = spar_dirac_split_band;
203 1252 : move16();
204 : }
205 :
206 1252 : IF( ivas_get_hodirac_flag_fx( ivas_total_brate, sba_order ) )
207 : {
208 126 : hConfig->dec_param_estim = FALSE;
209 126 : hConfig->enc_param_start_band = 0;
210 :
211 126 : move16();
212 126 : move16();
213 :
214 126 : set8_fx( (Word8 *) hQMetaData->twoDirBands, (Word8) 1, hQMetaData->q_direction[0].cfg.nbands );
215 126 : hQMetaData->numTwoDirBands = (UWord8) hQMetaData->q_direction[0].cfg.nbands;
216 126 : move16();
217 : }
218 : }
219 :
220 4466 : test();
221 4466 : IF( EQ_32( ivas_format, SBA_FORMAT ) || EQ_32( ivas_format, SBA_ISM_FORMAT ) )
222 : {
223 : // 100861_dirac_dec
224 1252 : ivas_dirac_config_bands_fx( band_grouping, IVAS_MAX_NUM_BANDS, (Word16) ( Fs * INV_CLDFB_BANDWIDTH + 0.5f ), dirac_to_spar_md_bands, hQMetaData->useLowerBandRes, hConfig->enc_param_start_band, hFbMdft, 1 );
225 : }
226 : ELSE
227 : {
228 3214 : ivas_dirac_config_bands_fx( band_grouping, hConfig->nbands, (Word16) ( Fs * INV_CLDFB_BANDWIDTH + 0.5f ), NULL, 0, 0, hFbMdft, 1 );
229 : }
230 :
231 4466 : return error;
232 : }
233 :
234 :
235 : /*-------------------------------------------------------------------------
236 : * ivas_dirac_config_bands_fx()
237 : *
238 : * DirAC Configuration freq. band function; used also in MASA decoder
239 : *------------------------------------------------------------------------*/
240 :
241 105318 : void ivas_dirac_config_bands_fx(
242 : Word16 *band_grouping, /* o : band grouping */
243 : const Word16 nbands, /* i : number of bands */
244 : const Word16 max_band, /* i : maximal band index +1 */
245 : Word16 *dirac_to_spar_md_bands, /* o : mapping of DirAC parameter band index to SPAR FB band index */
246 : const Word8 useLowerBandRes, /* i : flag indicating lower band resolution for DirAC */
247 : const Word16 enc_param_start_band, /* i : band index of first DirAC parameter band */
248 : IVAS_FB_MIXER_HANDLE hFbMdft,
249 : const Word8 BandGroupLowRes )
250 : {
251 : Word16 i;
252 : {
253 105318 : IF( EQ_16( nbands, 5 ) )
254 : {
255 4356 : Copy( DirAC_band_grouping_5, band_grouping, 5 + 1 );
256 : }
257 100962 : ELSE IF( EQ_16( nbands, 6 ) )
258 : {
259 0 : Copy( DirAC_band_grouping_6, band_grouping, 6 + 1 );
260 : }
261 100962 : ELSE IF( EQ_16( nbands, 12 ) )
262 : {
263 : Word16 band;
264 1312506 : FOR( band = 0; band < DIRAC_MAX_NBANDS; band++ )
265 : {
266 1211544 : dirac_to_spar_md_bands[band] = band;
267 1211544 : move16();
268 : }
269 100962 : IF( hFbMdft != NULL )
270 : {
271 : Word16 sb, idx1, idx2, b;
272 :
273 100354 : idx1 = -1;
274 100354 : move16();
275 100354 : sb = 0;
276 100354 : move16();
277 5047674 : FOR( b = 0; b < max_band; b++ )
278 : {
279 4947320 : idx2 = hFbMdft->pFb->fb_bin_to_band.p_cldfb_map_to_spar_band[b];
280 4947320 : move16();
281 4947320 : IF( GT_16( idx2, idx1 ) )
282 : {
283 1150552 : band_grouping[sb++] = b;
284 1150552 : move16();
285 1150552 : idx1 = idx2;
286 1150552 : move16();
287 : }
288 : }
289 100354 : band_grouping[sb] = max_band;
290 100354 : move16();
291 :
292 : /* set the remaining bands to max_band to avoid problems for the DirAC parameter estimation with bw < FB */
293 254404 : FOR( b = sb; b <= nbands; b++ )
294 : {
295 154050 : band_grouping[b] = max_band;
296 154050 : move16();
297 : }
298 : }
299 : ELSE
300 : {
301 608 : Copy( DirAC_band_grouping_12, band_grouping, 12 + 1 );
302 : }
303 :
304 100962 : IF( useLowerBandRes )
305 : {
306 8952 : Word16 step = DIRAC_LOW_BANDRES_STEP;
307 8952 : move16();
308 : Word16 reduced_band;
309 :
310 8952 : IF( BandGroupLowRes )
311 : {
312 1122 : FOR( ( band = enc_param_start_band + 2, reduced_band = enc_param_start_band + 1 ); band <= DIRAC_MAX_NBANDS; ( band += step, reduced_band++ ) )
313 : {
314 748 : band_grouping[reduced_band] = band_grouping[band];
315 748 : move16();
316 : }
317 1122 : FOR( ; reduced_band <= DIRAC_MAX_NBANDS; reduced_band++ )
318 : {
319 748 : band_grouping[reduced_band] = max_band;
320 748 : move16();
321 : }
322 : }
323 26856 : FOR( ( band = enc_param_start_band + ( DIRAC_MAX_NBANDS - enc_param_start_band ) / 2 - 1, reduced_band = DIRAC_MAX_NBANDS - 1 ); band >= enc_param_start_band; ( band--, reduced_band -= step ) )
324 : {
325 17904 : dirac_to_spar_md_bands[reduced_band] = dirac_to_spar_md_bands[band];
326 17904 : move16();
327 17904 : dirac_to_spar_md_bands[reduced_band - 1] = dirac_to_spar_md_bands[band];
328 17904 : move16();
329 : }
330 : }
331 : ELSE
332 : {
333 : /* always code the last two fb bands together */
334 92010 : band_grouping[DIRAC_MAX_NBANDS - 1] = max_band;
335 92010 : move16();
336 92010 : dirac_to_spar_md_bands[DIRAC_MAX_NBANDS - 1] = sub( DIRAC_MAX_NBANDS, 2 );
337 92010 : move16();
338 : }
339 : }
340 : ELSE
341 : {
342 0 : assert( 0 && "nbands must be 5 or 6!" );
343 : }
344 : }
345 :
346 : /* Limit the band range to band max */
347 1443960 : FOR( i = 0; i < nbands + 1; i++ )
348 : {
349 1338642 : IF( GT_16( band_grouping[i], max_band ) )
350 : {
351 1016 : band_grouping[i] = max_band;
352 1016 : move16();
353 : }
354 : }
355 :
356 105318 : return;
357 : }
358 :
359 :
360 : /*-------------------------------------------------------------------*
361 : * ivas_get_dirac_sba_max_md_bits()
362 : *
363 : * Return maximum SBA DirAC metadata bit-budget and nominal bit-budget
364 : *-------------------------------------------------------------------*/
365 :
366 3112 : void ivas_get_dirac_sba_max_md_bits_fx(
367 : const Word32 sba_total_brate,
368 : Word16 *bits_frame_nominal,
369 : Word16 *metadata_max_bits,
370 : Word16 *qmetadata_max_bit_req,
371 : const Word16 nbands,
372 : IVAS_FORMAT ivas_format )
373 : {
374 3112 : IF( LE_32( sba_total_brate, IVAS_13k2 ) )
375 : {
376 284 : *bits_frame_nominal = ACELP_9k60 / FRAMES_PER_SEC;
377 284 : *metadata_max_bits = 70;
378 :
379 284 : move16();
380 284 : move16();
381 : }
382 2828 : ELSE IF( LE_32( sba_total_brate, IVAS_16k4 ) )
383 : {
384 333 : *bits_frame_nominal = ACELP_13k20 / FRAMES_PER_SEC;
385 333 : *metadata_max_bits = 80;
386 :
387 333 : move16();
388 333 : move16();
389 : }
390 2495 : ELSE IF( LE_32( sba_total_brate, IVAS_24k4 ) )
391 : {
392 244 : *bits_frame_nominal = ACELP_16k40 / FRAMES_PER_SEC;
393 244 : *metadata_max_bits = 103;
394 :
395 244 : move16();
396 244 : move16();
397 : /* OSBA needs an additional 2-bits safety margin to avoid acelp crashes */
398 244 : IF( EQ_32( ivas_format, SBA_ISM_FORMAT ) )
399 : {
400 86 : ( *metadata_max_bits ) = sub( ( *metadata_max_bits ), 7 );
401 86 : move16();
402 : }
403 : }
404 2251 : ELSE IF( LE_32( sba_total_brate, IVAS_32k ) )
405 : {
406 242 : *bits_frame_nominal = ACELP_32k / FRAMES_PER_SEC;
407 242 : *metadata_max_bits = 214;
408 :
409 242 : move16();
410 242 : move16();
411 : }
412 2009 : ELSE IF( LE_32( sba_total_brate, IVAS_48k ) )
413 : {
414 144 : *bits_frame_nominal = IVAS_48k / FRAMES_PER_SEC;
415 144 : *metadata_max_bits = 240;
416 :
417 144 : move16();
418 144 : move16();
419 : }
420 1865 : ELSE IF( LE_32( sba_total_brate, IVAS_64k ) )
421 : {
422 212 : *bits_frame_nominal = IVAS_64k / FRAMES_PER_SEC;
423 212 : *metadata_max_bits = 200;
424 :
425 212 : move16();
426 212 : move16();
427 : }
428 1653 : ELSE IF( LE_32( sba_total_brate, IVAS_80k ) )
429 : {
430 265 : *bits_frame_nominal = IVAS_80k / FRAMES_PER_SEC;
431 265 : *metadata_max_bits = 200;
432 :
433 265 : move16();
434 265 : move16();
435 : }
436 1388 : ELSE IF( LE_32( sba_total_brate, IVAS_96k ) )
437 : {
438 227 : *bits_frame_nominal = IVAS_96k / FRAMES_PER_SEC;
439 227 : *metadata_max_bits = 200;
440 :
441 227 : move16();
442 227 : move16();
443 : }
444 1161 : ELSE IF( LE_32( sba_total_brate, IVAS_128k ) )
445 : {
446 197 : *bits_frame_nominal = IVAS_128k / FRAMES_PER_SEC;
447 197 : *metadata_max_bits = 250;
448 :
449 197 : move16();
450 197 : move16();
451 : }
452 : ELSE
453 : {
454 : /* *bits_frame_nominal = (int16_t) ( sba_total_brate / FRAMES_PER_SEC ); */
455 964 : *bits_frame_nominal = extract_l( Mpy_32_32( sba_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 ) );
456 964 : move16();
457 964 : *metadata_max_bits = MAX16B; /* no limit */
458 964 : move16();
459 : }
460 3112 : Word32 var1 = L_mult0( *metadata_max_bits, nbands );
461 3112 : Word16 exp = 0;
462 3112 : Word16 var2 = BASOP_Util_Divide3232_Scale( var1, 5, &exp );
463 3112 : Word32 var2_32 = L_deposit_h( var2 );
464 3112 : Word32 var4 = var2_32;
465 :
466 3112 : move16();
467 3112 : move32();
468 :
469 3112 : Word16 exp_res = 0;
470 3112 : move16();
471 3112 : IF( var1 % 5 != 0 )
472 : {
473 1450 : var4 = BASOP_Util_Add_Mant32Exp( var2_32, exp, ONE_IN_Q30, 1, &exp_res );
474 1450 : exp = exp_res;
475 1450 : move16();
476 : }
477 3112 : Word16 flag = BASOP_Util_Cmp_Mant32Exp( MAX16B, 31, var4, exp );
478 : Word32 tmp;
479 3112 : IF( EQ_16( flag, 1 ) )
480 : {
481 2814 : tmp = var4;
482 2814 : move32();
483 : }
484 : ELSE
485 : {
486 298 : tmp = MAX16B;
487 298 : exp = 31;
488 :
489 298 : move32();
490 298 : move16();
491 : }
492 3112 : *metadata_max_bits = (Word16) L_shr( tmp, 31 - exp );
493 3112 : *qmetadata_max_bit_req = QMETADATA_MAXBIT_REQ_SBA >> 1;
494 :
495 3112 : move16();
496 3112 : move16();
497 :
498 3112 : return;
499 : }
500 :
501 : /*-------------------------------------------------------------------------
502 : * ivas_dirac_sba_config()
503 : *
504 : * DirAC Configuration function for SBA
505 : *------------------------------------------------------------------------*/
506 3112 : ivas_error ivas_dirac_sba_config_fx(
507 : IVAS_QMETADATA_HANDLE hQMetaData, /* i/o: q_metadata handle */
508 : Word16 *element_mode, /* i/o: element mode of the core coder */
509 : Word32 sba_total_brate, /* i : SBA total bitrate */
510 : const Word16 sba_order, /* i : Ambisonic (SBA) order */
511 : const Word16 nbands /* i : number of frequency bands */
512 : ,
513 : IVAS_FORMAT ivas_format )
514 : {
515 : Word16 nbands_coded;
516 : Word16 hodirac_flag;
517 : ivas_error error;
518 :
519 3112 : Word32 tmp1 = IVAS_192k;
520 3112 : Word32 tmp2 = SPAR_DIRAC_SPLIT_START_BAND;
521 3112 : Word16 exp = 0;
522 :
523 3112 : move32();
524 3112 : move32();
525 3112 : move16();
526 3112 : Word16 tmp3 = BASOP_Util_Divide3232_Scale( tmp1, tmp2, &exp );
527 3112 : Word32 res = L_shr( L_deposit_h( tmp3 ), sub( 31, exp ) );
528 :
529 3112 : error = IVAS_ERR_OK;
530 3112 : hQMetaData->is_masa_ivas_format = 0;
531 3112 : move32();
532 3112 : move16();
533 :
534 3112 : hodirac_flag = ivas_get_hodirac_flag_fx( sba_total_brate, sba_order );
535 :
536 : /* map the bitrate for SID frame */
537 3112 : IF( EQ_32( sba_total_brate, IVAS_SID_5k2 ) )
538 : {
539 0 : IF( EQ_16( *element_mode, IVAS_SCE ) )
540 : {
541 0 : sba_total_brate = ACELP_24k40;
542 0 : move32();
543 : }
544 : ELSE
545 : {
546 0 : sba_total_brate = ACELP_48k;
547 0 : move32();
548 : }
549 : }
550 :
551 3112 : ivas_set_qmetadata_maxbit_req_fx( hQMetaData, SBA_FORMAT );
552 :
553 3112 : IF( LE_32( sba_total_brate, IVAS_16k4 ) )
554 : {
555 617 : hQMetaData->useLowerRes = 1;
556 617 : move16();
557 : }
558 : ELSE
559 : {
560 2495 : hQMetaData->useLowerRes = 0;
561 2495 : move16();
562 : }
563 :
564 3112 : nbands_coded = nbands;
565 3112 : move16();
566 :
567 3112 : IF( LE_32( sba_total_brate, res ) )
568 : {
569 617 : hQMetaData->useLowerBandRes = 1;
570 617 : Word16 tmp = s_and( nbands, 1 );
571 :
572 617 : move16();
573 617 : nbands_coded = add( shr( nbands, 1 ), tmp );
574 : }
575 : ELSE
576 : {
577 2495 : hQMetaData->useLowerBandRes = 0;
578 2495 : move16();
579 2495 : nbands_coded = sub( nbands, 1 ); /* always combine the last two bands */
580 : }
581 :
582 : {
583 3112 : Word16 no_dirs = 1;
584 3112 : move16();
585 3112 : IF( hodirac_flag )
586 : {
587 298 : no_dirs = 2;
588 298 : move16();
589 : }
590 :
591 3112 : IF( NE_32( ( error = ivas_qmetadata_allocate_memory_fx( hQMetaData, nbands_coded, no_dirs, 0 ) ), IVAS_ERR_OK ) ) // WIP
592 : {
593 0 : return error;
594 : }
595 : }
596 :
597 3112 : ivas_get_dirac_sba_max_md_bits_fx( sba_total_brate, &hQMetaData->bits_frame_nominal, &hQMetaData->metadata_max_bits, &hQMetaData->qmetadata_max_bit_req, hQMetaData->q_direction[0].cfg.nbands,
598 : ivas_format );
599 :
600 3112 : return error;
601 : }
602 :
603 :
604 7200 : void computeDirectionVectors_fixed(
605 : Word32 *intensity_real_x, /* i: exp = i_e */
606 : Word32 *intensity_real_y, /* i: exp = i_e */
607 : Word32 *intensity_real_z, /* i: exp = i_e */
608 : const Word16 enc_param_start_band,
609 : const Word16 num_frequency_bands,
610 : Word32 *direction_vector_x, /* o: Q30*/
611 : Word32 *direction_vector_y, /* o: Q30*/
612 : Word32 *direction_vector_z, /* o: Q30*/
613 : Word16 i_e, /*Exponent of all the intensity buffers*/
614 : Word16 *i_e_band )
615 : {
616 : Word16 i;
617 : Word32 intensityNorm;
618 : Word16 intensityNorm_e;
619 : Word32 temp1;
620 : Word16 exp1;
621 : Word16 norm_x, norm_y, norm_z;
622 : Word32 scaled_x, scaled_y, scaled_z;
623 : Word16 e_x, e_y, e_z;
624 180000 : FOR( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; ++i )
625 : {
626 172800 : norm_x = norm_l( *intensity_real_x );
627 172800 : norm_y = norm_l( *intensity_real_y );
628 172800 : norm_z = norm_l( *intensity_real_z );
629 172800 : scaled_x = L_shl( *intensity_real_x, norm_x );
630 172800 : scaled_y = L_shl( *intensity_real_y, norm_y );
631 172800 : scaled_z = L_shl( *intensity_real_z, norm_z );
632 172800 : IF( i_e_band != NULL )
633 : {
634 172800 : e_x = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_x ) );
635 172800 : e_y = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_y ) );
636 172800 : e_z = sub( Q31, add( i_e_band[i - enc_param_start_band], norm_z ) );
637 : }
638 : ELSE
639 : {
640 0 : e_x = sub( i_e, norm_x );
641 0 : e_y = sub( i_e, norm_y );
642 0 : e_z = sub( i_e, norm_z );
643 : }
644 172800 : temp1 = BASOP_Util_Add_Mant32Exp( Mult_32_32( scaled_x, scaled_x ), shl( e_x, 1 ), Mult_32_32( scaled_y, scaled_y ), shl( e_y, 1 ), &exp1 );
645 172800 : intensityNorm = BASOP_Util_Add_Mant32Exp( temp1, exp1, Mult_32_32( scaled_z, scaled_z ), shl( e_z, 1 ), &intensityNorm_e );
646 :
647 172800 : IF( LE_32( intensityNorm, EPSILON_FX ) )
648 : {
649 0 : intensityNorm = L_shl( 1, intensityNorm_e );
650 0 : *( direction_vector_x++ ) = ONE_IN_Q30;
651 0 : *( direction_vector_y++ ) = 0;
652 0 : *( direction_vector_z++ ) = 0;
653 :
654 0 : move32();
655 0 : move32();
656 0 : move32();
657 0 : intensity_real_x++;
658 0 : intensity_real_y++;
659 0 : intensity_real_z++;
660 : }
661 : ELSE
662 : {
663 172800 : intensityNorm = ISqrt32( intensityNorm, &intensityNorm_e ); /*Q31-intensityNorm_e*/
664 172800 : *( direction_vector_x++ ) = L_shl( Mult_32_32( scaled_x, intensityNorm ), sub( add( e_x, intensityNorm_e ), 1 ) ); /*Q30*/
665 172800 : intensity_real_x++;
666 172800 : *( direction_vector_y++ ) = L_shl( Mult_32_32( scaled_y, intensityNorm ), sub( add( e_y, intensityNorm_e ), 1 ) ); /*Q30*/
667 172800 : intensity_real_y++;
668 172800 : *( direction_vector_z++ ) = L_shl( Mult_32_32( scaled_z, intensityNorm ), sub( add( e_z, intensityNorm_e ), 1 ) ); /*Q30*/
669 172800 : intensity_real_z++;
670 :
671 172800 : move32();
672 172800 : move32();
673 172800 : move32();
674 : }
675 : }
676 :
677 7200 : return;
678 : }
679 : /*-------------------------------------------------------------------------
680 : * computeDirectionVectors()
681 : *
682 : *
683 : *------------------------------------------------------------------------*/
684 :
685 0 : void computeDirectionVectors_fx(
686 : Word32 *intensity_real_x, // i: Q( i_q )
687 : Word32 *intensity_real_y, // i: Q( i_q )
688 : Word32 *intensity_real_z, // i: Q( i_q )
689 : const Word16 enc_param_start_band,
690 : const Word16 num_frequency_bands,
691 : Word32 *direction_vector_x, // o: Q( i_q )
692 : Word32 *direction_vector_y, // o: Q( i_q )
693 : Word32 *direction_vector_z, // o: Q( i_q )
694 : Word16 *i_q /*input/output Q*/
695 : )
696 : {
697 : Word16 i;
698 : Word32 intensityNorm;
699 :
700 0 : Word16 sq = sub( 31, sub( shl( *i_q, 1 ), 31 ) );
701 0 : Word16 sq1 = sub( shl( *i_q, 1 ), 31 );
702 0 : Word16 exp = sq;
703 0 : Word16 local_i_q = sq1;
704 0 : Word16 min_factor = 30;
705 :
706 0 : move16();
707 0 : move16();
708 0 : move16();
709 :
710 0 : Word32 *init_x = intensity_real_x;
711 0 : Word32 *init_y = intensity_real_y;
712 0 : Word32 *init_z = intensity_real_z;
713 : // First loop to determine the Q for the direction vector
714 0 : FOR( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; ++i )
715 : {
716 0 : intensityNorm = L_add( L_add( Mpy_32_32_r( *( intensity_real_x ), *( intensity_real_x ) ),
717 : Mpy_32_32_r( *( intensity_real_y ), *( intensity_real_y ) ) ),
718 : Mpy_32_32_r( *( intensity_real_z ), *( intensity_real_z ) ) ); /*Q (2*i_q - 31) */
719 0 : exp = sq;
720 0 : move16();
721 0 : IF( LE_32( intensityNorm, EPSILON_FX ) )
722 : {
723 0 : intensity_real_x++;
724 0 : intensity_real_y++;
725 0 : intensity_real_z++;
726 : }
727 : ELSE
728 : {
729 0 : intensityNorm = ISqrt32( intensityNorm, &exp ); // Q31-exp
730 0 : intensity_real_x++; // i_q + Q31-exp -31 = i_q -exp
731 0 : intensity_real_y++; // i_q + Q31-exp -31 = i_q -exp
732 0 : intensity_real_z++; // i_q + Q31-exp-31 = i_q -exo
733 0 : local_i_q = sub( *i_q, exp );
734 0 : min_factor = s_min( min_factor, local_i_q );
735 : }
736 : }
737 0 : intensity_real_x = init_x;
738 0 : intensity_real_y = init_y;
739 0 : intensity_real_z = init_z;
740 : // Actual processing loop for the direction vector
741 0 : FOR( i = enc_param_start_band; i < enc_param_start_band + num_frequency_bands; ++i )
742 : {
743 0 : intensityNorm = L_add( L_add( Mpy_32_32_r( *( intensity_real_x ), *( intensity_real_x ) ),
744 : Mpy_32_32_r( *( intensity_real_y ), *( intensity_real_y ) ) ),
745 : Mpy_32_32_r( *( intensity_real_z ), *( intensity_real_z ) ) ); /*Q (2*i_q - 31) */
746 0 : exp = sq;
747 0 : move16();
748 0 : IF( LE_32( intensityNorm, EPSILON_FX ) )
749 : {
750 0 : intensityNorm = L_shl( 1, min_factor );
751 0 : *( direction_vector_x++ ) = L_shl( 1, min_factor ); // Q is min_factor
752 0 : *( direction_vector_y++ ) = 0;
753 0 : *( direction_vector_z++ ) = 0;
754 0 : intensity_real_x++;
755 0 : intensity_real_y++;
756 0 : intensity_real_z++;
757 :
758 0 : move32();
759 0 : move32();
760 0 : move32();
761 : }
762 : ELSE
763 : {
764 0 : intensityNorm = ISqrt32( intensityNorm, &exp ); // Q31-exp
765 0 : Word32 temp = L_shr( Mpy_32_32( *( intensity_real_x++ ), intensityNorm ), ( *i_q - exp - min_factor ) ); // Q is min_factor
766 0 : *( direction_vector_x++ ) = temp; // i_q + Q31-exp -31 = i_q -exp
767 0 : temp = L_shr( Mpy_32_32( *( intensity_real_y++ ), intensityNorm ), ( *i_q - exp - min_factor ) ); // Q is min_factor
768 0 : *( direction_vector_y++ ) = temp; // i_q + Q31-exp -31 = i_q -exp
769 0 : temp = L_shr( Mpy_32_32( *( intensity_real_z++ ), intensityNorm ), ( *i_q - exp - min_factor ) ); // Q is min_factor
770 0 : *( direction_vector_z++ ) = temp; // i_q + Q31-exp-31 = i_q -exp
771 :
772 0 : move32();
773 0 : move32();
774 0 : move32();
775 : }
776 : }
777 0 : *i_q = min_factor;
778 0 : move16();
779 0 : return;
780 : }
781 :
782 : /*-------------------------------------------------------------------------
783 : * computeDiffuseness()
784 : *
785 : *
786 : *------------------------------------------------------------------------*/
787 737503 : void computeDiffuseness_fixed(
788 : Word32 *buffer_intensity[DIRAC_NUM_DIMS][DIRAC_NO_COL_AVG_DIFF], // i: Q(q_factor_intensity)
789 : const Word32 *buffer_energy, // i: Q(q_factor_energy)
790 : const Word16 num_freq_bands,
791 : Word32 *diffuseness, // o: exp(out_exp)
792 : Word16 *q_factor_intensity,
793 : Word16 *q_factor_energy,
794 : Word16 *q_diffuseness /*Ouput Q*/
795 : )
796 : {
797 : Word32 intensity_slow[DIRAC_NUM_DIMS * CLDFB_NO_CHANNELS_MAX];
798 : Word32 intensity_slow_abs[CLDFB_NO_CHANNELS_MAX];
799 : Word64 intensity_slow_abs_64[CLDFB_NO_CHANNELS_MAX];
800 : Word16 intensity_slow_abs_q[CLDFB_NO_CHANNELS_MAX];
801 : Word32 energy_slow[CLDFB_NO_CHANNELS_MAX];
802 : Word16 i, j, k;
803 737503 : Word32 tmp = 0;
804 737503 : move32();
805 : Word32 *p_tmp;
806 : const Word32 *p_tmp_c;
807 : Word16 min_q_shift1, min_q_shift2, exp1, exp2, q_tmp;
808 : Word16 q_ene, q_intensity;
809 :
810 : /* Compute Intensity slow and energy slow buffer_intensity and buffer_energy */
811 :
812 737503 : set_zero_fx( intensity_slow, i_mult( DIRAC_NUM_DIMS, CLDFB_NO_CHANNELS_MAX ) );
813 737503 : set_zero_fx( intensity_slow_abs, CLDFB_NO_CHANNELS_MAX );
814 737503 : set_zero_fx( energy_slow, CLDFB_NO_CHANNELS_MAX );
815 :
816 : /* Calculate max possible shift for the buffer buffer_energy and buffer_intensity */
817 737503 : min_q_shift1 = Q31;
818 737503 : move16();
819 737503 : min_q_shift1 = s_min( min_q_shift1, getScaleFactor32( buffer_energy, i_mult( DIRAC_NO_COL_AVG_DIFF, num_freq_bands ) ) );
820 737503 : min_q_shift1 = sub( min_q_shift1, find_guarded_bits_fx( DIRAC_NO_COL_AVG_DIFF ) );
821 :
822 737503 : min_q_shift2 = Q31;
823 737503 : move16();
824 2950012 : FOR( i = 0; i < DIRAC_NUM_DIMS; i++ )
825 : {
826 73012797 : FOR( j = 0; j < DIRAC_NO_COL_AVG_DIFF; j++ )
827 : {
828 70800288 : min_q_shift2 = s_min( min_q_shift2, getScaleFactor32( buffer_intensity[i][j], num_freq_bands ) );
829 : }
830 : }
831 737503 : min_q_shift2 = sub( min_q_shift2, find_guarded_bits_fx( DIRAC_NO_COL_AVG_DIFF ) );
832 :
833 737503 : q_ene = add( q_factor_energy[0], min_q_shift1 );
834 737503 : move16();
835 737503 : q_intensity = add( q_factor_intensity[0], min_q_shift2 );
836 737503 : move16();
837 :
838 24337599 : FOR( i = 0; i < DIRAC_NO_COL_AVG_DIFF; ++i )
839 : {
840 : /* Energy slow */
841 23600096 : p_tmp_c = buffer_energy + i * num_freq_bands;
842 :
843 23600096 : q_tmp = add( q_factor_energy[i], min_q_shift1 );
844 :
845 :
846 23600096 : Word16 shift_q = sub( q_tmp, q_ene );
847 23600096 : Word32 shiftEquiv = L_add( 0, 0 );
848 : Word16 shift_qtotal;
849 23600096 : if ( shift_q < 0 )
850 : {
851 756959 : shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q );
852 : }
853 23600096 : if ( shift_q >= 0 )
854 : {
855 22843137 : shiftEquiv = L_add( 0x7FFFFFFF, 0 );
856 : }
857 23600096 : shift_qtotal = sub( min_q_shift1, s_max( shift_q, 0 ) );
858 :
859 286196352 : FOR( k = 0; k < num_freq_bands; k++ )
860 : {
861 262596256 : tmp = L_shl( p_tmp_c[k], shift_qtotal );
862 262596256 : energy_slow[k] = Madd_32_32_r( tmp, energy_slow[k], shiftEquiv );
863 262596256 : move32();
864 : }
865 :
866 :
867 23600096 : q_ene = s_min( q_ene, q_tmp );
868 :
869 : /* Intensity slow */
870 23600096 : q_tmp = add( q_factor_intensity[i], min_q_shift2 );
871 :
872 23600096 : shift_q = sub( q_tmp, q_intensity );
873 23600096 : if ( shift_q < 0 )
874 : {
875 753319 : shiftEquiv = L_lshl( (Word32) 0x80000000, shift_q );
876 : }
877 23600096 : if ( shift_q >= 0 )
878 : {
879 22846777 : shiftEquiv = L_lshl( 0x7FFFFFFF, 0 );
880 : }
881 23600096 : shift_qtotal = sub( min_q_shift2, s_max( shift_q, 0 ) );
882 :
883 94400384 : FOR( j = 0; j < DIRAC_NUM_DIMS; ++j )
884 : {
885 70800288 : p_tmp = buffer_intensity[j][i];
886 858589056 : FOR( k = 0; k < num_freq_bands; k++ )
887 : {
888 787788768 : tmp = L_shl( p_tmp[k], shift_qtotal );
889 787788768 : intensity_slow[j * num_freq_bands + k] = Madd_32_32_r( tmp, intensity_slow[j * num_freq_bands + k], shiftEquiv );
890 787788768 : move32();
891 : }
892 : }
893 :
894 23600096 : q_intensity = s_min( q_intensity, q_tmp );
895 : }
896 :
897 737503 : min_q_shift1 = getScaleFactor32( intensity_slow, i_mult( DIRAC_NUM_DIMS, num_freq_bands ) );
898 737503 : min_q_shift1 = sub( min_q_shift1, idiv1616( add( find_guarded_bits_fx( DIRAC_NUM_DIMS ), 1 ), 2 ) );
899 737503 : scale_sig32( intensity_slow, i_mult( DIRAC_NUM_DIMS, num_freq_bands ), min_q_shift1 );
900 737503 : q_intensity = add( q_intensity, min_q_shift1 );
901 8943636 : FOR( k = 0; k < num_freq_bands; k++ )
902 : {
903 8206133 : intensity_slow_abs_64[k] = 0;
904 8206133 : move64();
905 : }
906 :
907 : /* intensity_slow.^2 + intensity_slow_abs*/
908 2950012 : FOR( j = 0; j < DIRAC_NUM_DIMS; ++j )
909 : {
910 2212509 : p_tmp = intensity_slow + j * num_freq_bands;
911 26830908 : FOR( k = 0; k < num_freq_bands; k++ )
912 : {
913 24618399 : intensity_slow_abs_64[k] = W_add( intensity_slow_abs_64[k], W_mult_32_32( p_tmp[k], p_tmp[k] ) ); // 2*q_intensity+1
914 : }
915 : }
916 8943636 : FOR( k = 0; k < num_freq_bands; k++ )
917 : {
918 8206133 : Word16 shift = W_norm( intensity_slow_abs_64[k] );
919 8206133 : intensity_slow_abs[k] = W_extract_h( W_shl( intensity_slow_abs_64[k], shift ) );
920 8206133 : move32();
921 8206133 : intensity_slow_abs_q[k] = sub( add( add( q_intensity, q_intensity ), shift ), 31 );
922 8206133 : move16();
923 : }
924 :
925 : /* Compute Diffuseness */
926 737503 : p_tmp = intensity_slow_abs;
927 737503 : exp2 = 0;
928 737503 : move16();
929 8943636 : FOR( i = 0; i < num_freq_bands; ++i )
930 : {
931 8206133 : exp1 = sub( 31, intensity_slow_abs_q[i] );
932 8206133 : tmp = Sqrt32( p_tmp[i], &exp1 );
933 :
934 8206133 : tmp = BASOP_Util_Divide3232_Scale_newton( tmp, L_add( energy_slow[i], EPSILLON_FX ), &exp2 );
935 8206133 : q_tmp = add( sub( 31, exp2 ), sub( sub( 31, exp1 ), q_ene ) );
936 :
937 8206133 : IF( LT_16( q_tmp, Q30 ) )
938 : {
939 103705 : tmp = L_sub( L_shr( ONE_IN_Q30, sub( Q30, q_tmp ) ), tmp );
940 : }
941 : ELSE
942 : {
943 8102428 : tmp = L_sub( ONE_IN_Q30, L_shr( tmp, sub( q_tmp, Q30 ) ) );
944 8102428 : q_tmp = Q30;
945 8102428 : move16();
946 : }
947 :
948 8206133 : IF( GE_32( tmp, L_shl( 1, q_tmp ) ) )
949 : {
950 12774 : diffuseness[i] = ONE_IN_Q30;
951 12774 : move32();
952 : }
953 8193359 : ELSE IF( tmp <= 0 )
954 : {
955 478616 : diffuseness[i] = 0;
956 478616 : move32();
957 : }
958 : ELSE
959 : {
960 7714743 : diffuseness[i] = L_shl( tmp, sub( Q30, q_tmp ) );
961 7714743 : move32();
962 : }
963 : }
964 737503 : *q_diffuseness = Q30;
965 737503 : move16();
966 :
967 737503 : return;
968 : }
969 :
970 3746091 : Word32 deindex_azimuth_fx( /* o : output Q22 */
971 : Word16 id_phi, /* i : index */
972 : const Word16 no_bits, /* i : number of bits for the spherical grid */
973 : const Word16 id_th, /* i : elevation index */
974 : const Word16 remap, /* i : remapping flag */
975 : const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */
976 : )
977 : {
978 : Word16 flag_delta;
979 : Word32 dd_fx, delta_phi_fx;
980 : Word32 phi_hat_fx;
981 3746091 : test();
982 3746091 : IF( NE_32( mc_format, MC_LS_SETUP_INVALID ) && EQ_16( no_bits, 2 ) )
983 : {
984 10 : IF( s_and( id_phi, 1 ) == 0 )
985 : {
986 8 : phi_hat_fx = cb_azi_chan_fx[id_phi / 2]; // Q22
987 8 : move32();
988 : }
989 : ELSE
990 : {
991 2 : phi_hat_fx = L_negate( cb_azi_chan_fx[( id_phi + 1 ) / 2] ); // Q22
992 : }
993 10 : return phi_hat_fx;
994 : }
995 3746081 : flag_delta = extract_l( EQ_16( s_and( id_th, 1 ), 1 ) );
996 :
997 3746081 : IF( remap )
998 : {
999 229031 : id_phi = add( ivas_qmetadata_dereorder_generic_fx( id_phi ), shr( no_phi_masa[no_bits - 1][id_th], 1 ) );
1000 : }
1001 :
1002 3746081 : delta_phi_fx = Mpy_32_32( 1509949440, no_phi_masa_inv_fx[no_bits - 1][id_th] ); // q = 22
1003 3746081 : test();
1004 3746081 : test();
1005 3746081 : IF( EQ_16( flag_delta, 1 ) && GT_16( no_phi_masa[no_bits - 1][id_th], 2 ) && EQ_32( mc_format, MC_LS_SETUP_INVALID ) )
1006 : {
1007 907727 : dd_fx = Mpy_32_32( delta_phi_fx, 1073741824 ); // q = 22
1008 : }
1009 : ELSE
1010 : {
1011 2838354 : dd_fx = 0;
1012 2838354 : move32();
1013 : }
1014 :
1015 3746081 : id_phi = sub( id_phi, shr( no_phi_masa[no_bits - 1][id_th], 1 ) );
1016 3746081 : phi_hat_fx = L_add( imult3216( delta_phi_fx, id_phi ), dd_fx );
1017 3746081 : IF( NE_32( mc_format, MC_LS_SETUP_INVALID ) )
1018 : {
1019 103073 : Word32 a = L_shr( imult3216( delta_theta_masa_fx[no_bits - 3], id_th ), 22 ); // Q22 -> Q0
1020 103073 : move32();
1021 103073 : Word16 flag = 0;
1022 103073 : move16();
1023 103073 : if ( GT_32( a, MC_MASA_THR_ELEVATION ) )
1024 : {
1025 7917 : flag = 1;
1026 7917 : move16();
1027 : }
1028 103073 : phi_hat_fx = companding_azimuth_fx( phi_hat_fx, mc_format, flag, -1 );
1029 : }
1030 3746081 : return phi_hat_fx;
1031 : }
1032 :
1033 :
1034 : /*----------------------------------------------------------------
1035 : * deindex_spherical_component()
1036 : *
1037 : * decoding the spherical index for one tile
1038 : *-----------------------------------------------------------------*/
1039 :
1040 1765287 : void deindex_spherical_component_fx(
1041 : const UWord16 sph_idx, /* i : spherical index */
1042 : Word32 *az_fx, /* o : decoded azimuth value Q22 */
1043 : Word32 *el_fx, /* o : decoded elevation value Q22 */
1044 : UWord16 *az_idx, /* o : azimuth index */
1045 : UWord16 *el_idx, /* o : elevation index */
1046 : const UWord16 no_bits, /* i : number of bits for the spherical grid */
1047 : const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */
1048 : )
1049 : {
1050 1765287 : assert( sph_idx < ( 1 << no_bits ) );
1051 1765287 : SWITCH( no_bits )
1052 : {
1053 0 : case 0:
1054 0 : *az_fx = 0;
1055 0 : move32();
1056 0 : *el_fx = 0;
1057 0 : move32();
1058 0 : *az_idx = 0;
1059 0 : move16();
1060 0 : *el_idx = 0;
1061 0 : move16();
1062 0 : BREAK;
1063 0 : case 1:
1064 0 : *az_idx = sph_idx;
1065 0 : move16();
1066 0 : *az_fx = L_shl( ( *az_idx ) * ( -180 ), 22 );
1067 0 : *el_fx = 0;
1068 0 : move32();
1069 0 : *el_idx = 0;
1070 0 : move16();
1071 0 : BREAK;
1072 657 : case 2:
1073 657 : *el_fx = 0;
1074 657 : move32();
1075 657 : *el_idx = 0;
1076 657 : move16();
1077 657 : *az_idx = sph_idx;
1078 657 : move16();
1079 657 : *az_fx = deindex_azimuth_fx( *az_idx, no_bits, 0, 0, mc_format );
1080 657 : move16();
1081 657 : BREAK;
1082 1764630 : default:
1083 1764630 : *el_idx = deindex_sph_idx_general_fx( sph_idx, no_bits, el_fx, az_fx, az_idx, mc_format );
1084 1764630 : move16();
1085 1764630 : BREAK;
1086 : }
1087 :
1088 1765287 : return;
1089 : }
1090 :
1091 : /*----------------------------------------------------------------
1092 : * calculate_hodirac_sector_parameters()
1093 : *
1094 : *
1095 : *-----------------------------------------------------------------*/
1096 :
1097 0 : void calculate_hodirac_sector_parameters_fx(
1098 : DIRAC_ENC_HANDLE hDirAC, /* i : DirAC handle */
1099 : Word32 RealBuffer_fx[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : signal vector (L+1)^2 x N_bins, real part */
1100 : Word32 ImagBuffer_fx[DIRAC_MAX_ANA_CHANS][DIRAC_NO_FB_BANDS_MAX], /* i : signal vector, imaginary part */
1101 : Word16 Qfac, /* i : Q-factor of signal vector */
1102 : const Word32 beta_fx, /* i : forgetting factor for average filtering, Q30 */
1103 : const Word16 *band_grouping, /* i : indices of band groups */
1104 : const Word16 N_bands, /* i : number of bands (groups) */
1105 : const Word16 enc_param_start_band, /* i : first band to process */
1106 : Word32 *azi_fx, /* o : array of sector azimuth angles, flat, Q23 */
1107 : Word32 *ele_fx, /* o : array of sector elevation angles, flat, Q23 */
1108 : Word32 *diff_fx, /* o : array of sector diffuseness values, flat */
1109 : Word16 *diff_exp, /* o : array of sector diffuseness exponents, flat */
1110 : Word32 *ene_fx, /* o : array of sector energy values, flat */
1111 : Word16 *ene_exp /* o : array of sector energy exponents, flat */
1112 : )
1113 : {
1114 : Word16 i_sec, i_bin, i_band;
1115 : Word32 p_real_fx, p_imag_fx, normI_fx, energy_fx, tmp_diff_fx;
1116 : Word16 energy_exp, normI_exp, tmp_diff_exp;
1117 0 : Word16 tmp_exp_1 = sub( 33, shl( Qfac, 1 ) ); // 31 - (2 *Qfac - 2 )
1118 0 : Word16 tmp_exp_2 = sub( 35, shl( Qfac, 1 ) ); // 31 - (2 *Qfac - 4 )
1119 : Word32 tmp32_1, tmp32_2;
1120 0 : Word64 temp_x64 = 0, temp_y64 = 0, temp_z64 = 0;
1121 0 : Word16 tmp_scale = 0;
1122 0 : move64();
1123 0 : move64();
1124 0 : move64();
1125 0 : move16();
1126 :
1127 : Word32 sec_I_vec_x_fx[NUM_ANA_SECTORS];
1128 : Word32 sec_I_vec_y_fx[NUM_ANA_SECTORS];
1129 : Word32 sec_I_vec_z_fx[NUM_ANA_SECTORS];
1130 : Word16 sec_I_vec_x_exp[NUM_ANA_SECTORS];
1131 : Word16 sec_I_vec_y_exp[NUM_ANA_SECTORS];
1132 : Word16 sec_I_vec_z_exp[NUM_ANA_SECTORS];
1133 :
1134 0 : FOR( i_sec = 0; i_sec < NUM_ANA_SECTORS; i_sec++ )
1135 : {
1136 0 : Word32 *p_sec_I_vec_x_fx = &sec_I_vec_x_fx[i_sec];
1137 0 : Word32 *p_sec_I_vec_y_fx = &sec_I_vec_y_fx[i_sec];
1138 0 : Word32 *p_sec_I_vec_z_fx = &sec_I_vec_z_fx[i_sec];
1139 0 : Word16 *p_sec_I_vec_x_exp = &sec_I_vec_x_exp[i_sec];
1140 0 : Word16 *p_sec_I_vec_y_exp = &sec_I_vec_y_exp[i_sec];
1141 0 : Word16 *p_sec_I_vec_z_exp = &sec_I_vec_z_exp[i_sec];
1142 :
1143 0 : const Word32 *p_c_weights_fx = c_weights_fx; // Q30
1144 :
1145 0 : Word32 *p_ImagBuffer_0_fx = ImagBuffer_fx[0];
1146 0 : Word32 *p_ImagBuffer_1_fx = ImagBuffer_fx[1];
1147 0 : Word32 *p_ImagBuffer_2_fx = ImagBuffer_fx[2];
1148 0 : Word32 *p_ImagBuffer_3_fx = ImagBuffer_fx[3];
1149 0 : Word32 *p_ImagBuffer_4_fx = ImagBuffer_fx[4];
1150 0 : Word32 *p_ImagBuffer_5_fx = ImagBuffer_fx[5];
1151 0 : Word32 *p_ImagBuffer_6_fx = ImagBuffer_fx[6];
1152 0 : Word32 *p_ImagBuffer_8_fx = ImagBuffer_fx[8];
1153 :
1154 0 : Word32 *p_RealBuffer_0_fx = RealBuffer_fx[0];
1155 0 : Word32 *p_RealBuffer_1_fx = RealBuffer_fx[1];
1156 0 : Word32 *p_RealBuffer_2_fx = RealBuffer_fx[2];
1157 0 : Word32 *p_RealBuffer_3_fx = RealBuffer_fx[3];
1158 0 : Word32 *p_RealBuffer_4_fx = RealBuffer_fx[4];
1159 0 : Word32 *p_RealBuffer_5_fx = RealBuffer_fx[5];
1160 0 : Word32 *p_RealBuffer_6_fx = RealBuffer_fx[6];
1161 0 : Word32 *p_RealBuffer_8_fx = RealBuffer_fx[8];
1162 :
1163 0 : FOR( i_band = enc_param_start_band; i_band < N_bands; i_band++ )
1164 : {
1165 0 : Word32 *p_azi_fx = &azi_fx[i_sec * N_bands + i_band];
1166 0 : Word32 *p_ele_fx = &ele_fx[i_sec * N_bands + i_band];
1167 0 : Word32 *p_ene_fx = &ene_fx[i_sec * N_bands + i_band];
1168 0 : Word16 *p_ene_exp = &ene_exp[i_sec * N_bands + i_band];
1169 :
1170 0 : Word32 *p_diff_fx = &diff_fx[i_sec * N_bands + i_band];
1171 0 : Word16 *p_diff_exp = &diff_exp[i_sec * N_bands + i_band];
1172 0 : Word32 *p_azi_prev_fx = &hDirAC->azi_prev_fx[i_sec * N_bands + i_band];
1173 0 : Word32 *p_ele_prev_fx = &hDirAC->ele_prev_fx[i_sec * N_bands + i_band];
1174 :
1175 0 : Word32 *p_energy_smth_fx = &hDirAC->energy_smth_fx[i_sec][i_band];
1176 0 : Word16 *p_energy_smth_exp = &hDirAC->energy_smth_exp[i_sec][i_band];
1177 0 : Word32 *p_sec_I_vec_smth_x_fx = &hDirAC->sec_I_vec_smth_x_fx[i_sec][i_band];
1178 0 : Word32 *p_sec_I_vec_smth_y_fx = &hDirAC->sec_I_vec_smth_y_fx[i_sec][i_band];
1179 0 : Word32 *p_sec_I_vec_smth_z_fx = &hDirAC->sec_I_vec_smth_z_fx[i_sec][i_band];
1180 0 : Word16 *p_sec_I_vec_smth_x_exp = &hDirAC->sec_I_vec_smth_x_exp[i_sec][i_band];
1181 0 : Word16 *p_sec_I_vec_smth_y_exp = &hDirAC->sec_I_vec_smth_y_exp[i_sec][i_band];
1182 0 : Word16 *p_sec_I_vec_smth_z_exp = &hDirAC->sec_I_vec_smth_z_exp[i_sec][i_band];
1183 0 : *p_sec_I_vec_x_fx = 0;
1184 0 : move32();
1185 0 : *p_sec_I_vec_x_exp = 0;
1186 0 : move16();
1187 0 : *p_sec_I_vec_y_fx = 0;
1188 0 : move32();
1189 0 : *p_sec_I_vec_y_exp = 0;
1190 0 : move16();
1191 0 : *p_sec_I_vec_z_fx = 0;
1192 0 : move32();
1193 0 : *p_sec_I_vec_z_exp = 0;
1194 0 : move16();
1195 0 : energy_fx = 0;
1196 0 : move32();
1197 0 : energy_exp = 0;
1198 0 : move16();
1199 0 : Word64 sec_I_vec_x_64_fx = 0;
1200 0 : Word64 sec_I_vec_y_64_fx = 0;
1201 0 : Word64 sec_I_vec_z_64_fx = 0;
1202 0 : Word64 energy_64_fx = 0;
1203 0 : move64();
1204 0 : move64();
1205 0 : move64();
1206 0 : move64();
1207 0 : IF( i_sec == 0 )
1208 : {
1209 0 : FOR( i_bin = band_grouping[i_band]; i_bin < band_grouping[i_band + 1]; i_bin++ )
1210 : {
1211 0 : Word32 w_fx = *( p_c_weights_fx++ ); // Q30
1212 0 : move32();
1213 : Word32 sec_w_imag_fx, sec_x_imag_fx, sec_y_imag_fx, sec_z_imag_fx;
1214 : Word32 sec_w_real_fx, sec_x_real_fx, sec_y_real_fx, sec_z_real_fx;
1215 0 : sec_w_imag_fx = Madd_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_ImagBuffer_0_fx ) ), HODIRAC_FAC1, *( p_ImagBuffer_1_fx ) ); // Qfac - 2
1216 0 : sec_x_imag_fx = Madd_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_ImagBuffer_3_fx++ ) ), HODIRAC_FAC2, *( p_ImagBuffer_4_fx++ ) ); // Qfac - 2
1217 0 : sec_y_imag_fx = Msub_32_32( ( Msub_32_32( ( Madd_32_32( Mpy_32_32( HODIRAC_FAC3, *( p_ImagBuffer_0_fx++ ) ), HODIRAC_FAC1, *( p_ImagBuffer_1_fx++ ) ) ), HODIRAC_FAC3, *( p_ImagBuffer_6_fx++ ) ) ), HODIRAC_FAC2, *( p_ImagBuffer_8_fx++ ) ); // Qfac - 2
1218 0 : sec_z_imag_fx = Madd_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_ImagBuffer_2_fx++ ) ), HODIRAC_FAC2, *( p_ImagBuffer_5_fx++ ) ); // Qfac - 2
1219 :
1220 0 : sec_w_real_fx = Madd_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_RealBuffer_0_fx ) ), HODIRAC_FAC1, *( p_RealBuffer_1_fx ) ); // Qfac - 2
1221 0 : sec_x_real_fx = Madd_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_RealBuffer_3_fx++ ) ), HODIRAC_FAC2, *( p_RealBuffer_4_fx++ ) ); // Qfac - 2
1222 0 : sec_y_real_fx = Msub_32_32( ( Msub_32_32( Madd_32_32( Mpy_32_32( HODIRAC_FAC3, *( p_RealBuffer_0_fx++ ) ), HODIRAC_FAC1, *( p_RealBuffer_1_fx++ ) ), HODIRAC_FAC3, *( p_RealBuffer_6_fx++ ) ) ), HODIRAC_FAC2, *( p_RealBuffer_8_fx++ ) ); // Qfac - 2
1223 0 : sec_z_real_fx = Madd_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_RealBuffer_2_fx++ ) ), HODIRAC_FAC2, *( p_RealBuffer_5_fx++ ) ); // Qfac - 2
1224 :
1225 :
1226 0 : p_real_fx = Mpy_32_32( sec_w_real_fx, w_fx ); // ( Qfac - 2 ) + 30 - 31 = Qfac - 3
1227 0 : p_imag_fx = Mpy_32_32( sec_w_imag_fx, w_fx ); // ( Qfac - 2 ) + 30 - 31 = Qfac - 3
1228 :
1229 0 : temp_x64 = W_mac_32_32( W_mult_32_32( p_real_fx, sec_x_real_fx ), p_imag_fx, sec_x_imag_fx ); // ( Qfac - 3 ) + ( Qfac - 2 ) + 1 = 2 * Qfac - 4
1230 0 : temp_y64 = W_mac_32_32( W_mult_32_32( p_real_fx, sec_y_real_fx ), p_imag_fx, sec_y_imag_fx ); // ( Qfac - 3 ) + ( Qfac - 2 ) + 1 = 2 * Qfac - 4
1231 0 : temp_z64 = W_mac_32_32( W_mult_32_32( p_real_fx, sec_z_real_fx ), p_imag_fx, sec_z_imag_fx ); // ( Qfac - 3 ) + ( Qfac - 2 ) + 1 = 2 * Qfac - 4
1232 0 : sec_I_vec_x_64_fx = W_add( sec_I_vec_x_64_fx, temp_x64 );
1233 0 : sec_I_vec_y_64_fx = W_add( sec_I_vec_y_64_fx, temp_y64 );
1234 0 : sec_I_vec_z_64_fx = W_add( sec_I_vec_z_64_fx, temp_z64 );
1235 :
1236 : Word64 tmp1;
1237 : Word64 tmp2, tmp3, tmp4, sec_sum64;
1238 0 : tmp1 = W_mac_32_32( W_mult_32_32( p_real_fx, p_real_fx ), p_imag_fx, p_imag_fx ); // 2 * (Qfac - 3) + 1
1239 0 : tmp1 = W_shl( tmp1, 2 ); // 2 * (Qfac - 2) + 1
1240 0 : tmp2 = W_mac_32_32( W_mult_32_32( sec_x_real_fx, sec_x_real_fx ), sec_x_imag_fx, sec_x_imag_fx ); // 2 * (Qfac - 2) + 1
1241 0 : tmp3 = W_mac_32_32( W_mult_32_32( sec_y_real_fx, sec_y_real_fx ), sec_y_imag_fx, sec_y_imag_fx ); // 2 * (Qfac - 2) + 1
1242 0 : tmp4 = W_mac_32_32( W_mult_32_32( sec_z_real_fx, sec_z_real_fx ), sec_z_imag_fx, sec_z_imag_fx ); // 2 * (Qfac - 2) + 1
1243 0 : sec_sum64 = W_add( tmp1, W_add( W_add( tmp2, tmp3 ), tmp4 ) ); // 2 * (Qfac - 2) + 1
1244 :
1245 : // instead dividing changed Q//
1246 0 : energy_64_fx = W_add( energy_64_fx, sec_sum64 ); // 2 * (Qfac - 2) + 1 + 1
1247 : }
1248 0 : tmp_scale = sub( W_norm( energy_64_fx ), 32 );
1249 0 : energy_fx = W_shl_sat_l( energy_64_fx, tmp_scale );
1250 0 : energy_exp = sub( tmp_exp_1, tmp_scale );
1251 0 : if ( energy_fx == 0 )
1252 : {
1253 0 : energy_exp = 0;
1254 0 : move16();
1255 : }
1256 :
1257 0 : tmp_scale = sub( W_norm( sec_I_vec_x_64_fx ), 32 );
1258 0 : *p_sec_I_vec_x_fx = W_shl_sat_l( sec_I_vec_x_64_fx, tmp_scale );
1259 0 : move32();
1260 0 : *p_sec_I_vec_x_exp = sub( tmp_exp_2, tmp_scale );
1261 0 : move16();
1262 0 : if ( *p_sec_I_vec_x_fx == 0 )
1263 : {
1264 0 : *p_sec_I_vec_x_exp = 0;
1265 0 : move16();
1266 : }
1267 :
1268 0 : tmp_scale = sub( W_norm( sec_I_vec_y_64_fx ), 32 );
1269 0 : *p_sec_I_vec_y_fx = W_shl_sat_l( sec_I_vec_y_64_fx, tmp_scale );
1270 0 : move32();
1271 0 : *p_sec_I_vec_y_exp = sub( tmp_exp_2, tmp_scale );
1272 0 : move16();
1273 0 : if ( *p_sec_I_vec_y_fx == 0 )
1274 : {
1275 0 : *p_sec_I_vec_y_exp = 0;
1276 0 : move16();
1277 : }
1278 :
1279 0 : tmp_scale = sub( W_norm( sec_I_vec_z_64_fx ), 32 );
1280 0 : *p_sec_I_vec_z_fx = W_shl_sat_l( sec_I_vec_z_64_fx, tmp_scale );
1281 0 : move32();
1282 0 : *p_sec_I_vec_z_exp = sub( tmp_exp_2, tmp_scale );
1283 0 : move16();
1284 0 : if ( *p_sec_I_vec_z_fx == 0 )
1285 : {
1286 0 : *p_sec_I_vec_z_exp = 0;
1287 0 : move16();
1288 : }
1289 : }
1290 : ELSE
1291 : {
1292 0 : FOR( i_bin = band_grouping[i_band]; i_bin < band_grouping[i_band + 1]; i_bin++ )
1293 : {
1294 0 : Word32 w_fx = *( p_c_weights_fx++ ); // Q30
1295 0 : move32();
1296 : Word32 sec_w_imag_fx, sec_x_imag_fx, sec_y_imag_fx, sec_z_imag_fx;
1297 : Word32 sec_w_real_fx, sec_x_real_fx, sec_y_real_fx, sec_z_real_fx;
1298 :
1299 0 : sec_w_imag_fx = Msub_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_ImagBuffer_0_fx ) ), HODIRAC_FAC1, *( p_ImagBuffer_1_fx ) ); // Qfac - 2
1300 0 : sec_x_imag_fx = Msub_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_ImagBuffer_3_fx++ ) ), HODIRAC_FAC2, *( p_ImagBuffer_4_fx++ ) ); // Qfac - 2
1301 0 : sec_y_imag_fx = Madd_32_32( ( Madd_32_32( ( Madd_32_32( Mpy_32_32( -HODIRAC_FAC3, *( p_ImagBuffer_0_fx++ ) ), HODIRAC_FAC1, *( p_ImagBuffer_1_fx++ ) ) ), HODIRAC_FAC3, *( p_ImagBuffer_6_fx++ ) ) ), HODIRAC_FAC2, *( p_ImagBuffer_8_fx++ ) ); // Qfac - 2
1302 0 : sec_z_imag_fx = Msub_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_ImagBuffer_2_fx++ ) ), HODIRAC_FAC2, *( p_ImagBuffer_5_fx++ ) ); // Qfac - 2
1303 :
1304 0 : sec_w_real_fx = Msub_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_RealBuffer_0_fx ) ), HODIRAC_FAC1, *( p_RealBuffer_1_fx ) ); // Qfac - 2
1305 0 : sec_x_real_fx = Msub_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_RealBuffer_3_fx++ ) ), HODIRAC_FAC2, *( p_RealBuffer_4_fx++ ) ); // Qfac - 2
1306 0 : sec_y_real_fx = Madd_32_32( ( Madd_32_32( ( Madd_32_32( Mpy_32_32( -HODIRAC_FAC3, *( p_RealBuffer_0_fx++ ) ), HODIRAC_FAC1, *( p_RealBuffer_1_fx++ ) ) ), HODIRAC_FAC3, *( p_RealBuffer_6_fx++ ) ) ), HODIRAC_FAC2, *( p_RealBuffer_8_fx++ ) ); // Qfac - 2
1307 0 : sec_z_real_fx = Msub_32_32( Mpy_32_32( HODIRAC_FAC1, *( p_RealBuffer_2_fx++ ) ), HODIRAC_FAC2, *( p_RealBuffer_5_fx++ ) ); // Qfac - 2
1308 :
1309 :
1310 0 : p_real_fx = Mpy_32_32( sec_w_real_fx, w_fx ); // ( Qfac - 2 ) + 30 - 31 = Qfac - 3
1311 0 : p_imag_fx = Mpy_32_32( sec_w_imag_fx, w_fx ); // ( Qfac - 2 ) + 30 - 31 = Qfac - 3
1312 :
1313 0 : temp_x64 = W_mac_32_32( W_mult_32_32( p_real_fx, sec_x_real_fx ), p_imag_fx, sec_x_imag_fx ); // ( Qfac - 3 ) + ( Qfac - 2 ) + 1 = 2 * Qfac - 4
1314 0 : temp_y64 = W_mac_32_32( W_mult_32_32( p_real_fx, sec_y_real_fx ), p_imag_fx, sec_y_imag_fx ); // ( Qfac - 3 ) + ( Qfac - 2 ) + 1 = 2 * Qfac - 4
1315 0 : temp_z64 = W_mac_32_32( W_mult_32_32( p_real_fx, sec_z_real_fx ), p_imag_fx, sec_z_imag_fx ); // ( Qfac - 3 ) + ( Qfac - 2 ) + 1 = 2 * Qfac - 4
1316 0 : sec_I_vec_x_64_fx = W_add( sec_I_vec_x_64_fx, temp_x64 );
1317 0 : sec_I_vec_y_64_fx = W_add( sec_I_vec_y_64_fx, temp_y64 );
1318 0 : sec_I_vec_z_64_fx = W_add( sec_I_vec_z_64_fx, temp_z64 );
1319 :
1320 : Word64 tmp1;
1321 : Word64 tmp2, tmp3, tmp4, sec_sum64;
1322 0 : tmp1 = W_mac_32_32( W_mult_32_32( p_real_fx, p_real_fx ), p_imag_fx, p_imag_fx ); // 2 * (Qfac - 3) + 1
1323 0 : tmp1 = W_shl( tmp1, 2 ); // 2 * (Qfac - 2) + 1
1324 0 : tmp2 = W_mac_32_32( W_mult_32_32( sec_x_real_fx, sec_x_real_fx ), sec_x_imag_fx, sec_x_imag_fx ); // 2 * (Qfac - 2) + 1
1325 0 : tmp3 = W_mac_32_32( W_mult_32_32( sec_y_real_fx, sec_y_real_fx ), sec_y_imag_fx, sec_y_imag_fx ); // 2 * (Qfac - 2) + 1
1326 0 : tmp4 = W_mac_32_32( W_mult_32_32( sec_z_real_fx, sec_z_real_fx ), sec_z_imag_fx, sec_z_imag_fx ); // 2 * (Qfac - 2) + 1
1327 0 : sec_sum64 = W_add( tmp1, W_add( W_add( tmp2, tmp3 ), tmp4 ) ); // 2 * (Qfac - 2) + 1
1328 :
1329 : // instead dividing changed Q//
1330 0 : energy_64_fx = W_add( energy_64_fx, sec_sum64 ); // 2 * (Qfac - 2) + 1 + 1
1331 : }
1332 0 : tmp_scale = sub( W_norm( energy_64_fx ), 32 );
1333 0 : energy_fx = W_shl_sat_l( energy_64_fx, tmp_scale );
1334 0 : energy_exp = sub( tmp_exp_1, tmp_scale );
1335 0 : if ( energy_fx == 0 )
1336 : {
1337 0 : energy_exp = 0;
1338 0 : move16();
1339 : }
1340 :
1341 0 : tmp_scale = sub( W_norm( sec_I_vec_x_64_fx ), 32 );
1342 0 : *p_sec_I_vec_x_fx = W_shl_sat_l( sec_I_vec_x_64_fx, tmp_scale );
1343 0 : move32();
1344 0 : *p_sec_I_vec_x_exp = sub( tmp_exp_2, tmp_scale );
1345 0 : move16();
1346 0 : if ( *p_sec_I_vec_x_fx == 0 )
1347 : {
1348 0 : *p_sec_I_vec_x_exp = 0;
1349 0 : move16();
1350 : }
1351 :
1352 0 : tmp_scale = sub( W_norm( sec_I_vec_y_64_fx ), 32 );
1353 0 : *p_sec_I_vec_y_fx = W_shl_sat_l( sec_I_vec_y_64_fx, tmp_scale );
1354 0 : move32();
1355 0 : *p_sec_I_vec_y_exp = sub( tmp_exp_2, tmp_scale );
1356 0 : move16();
1357 0 : if ( *p_sec_I_vec_y_fx == 0 )
1358 : {
1359 0 : *p_sec_I_vec_y_exp = 0;
1360 0 : move16();
1361 : }
1362 :
1363 0 : tmp_scale = sub( W_norm( sec_I_vec_z_64_fx ), 32 );
1364 0 : *p_sec_I_vec_z_fx = W_shl_sat_l( sec_I_vec_z_64_fx, tmp_scale );
1365 0 : move32();
1366 0 : *p_sec_I_vec_z_exp = sub( tmp_exp_2, tmp_scale );
1367 0 : move16();
1368 0 : if ( *p_sec_I_vec_z_fx == 0 )
1369 : {
1370 0 : *p_sec_I_vec_z_exp = 0;
1371 0 : move16();
1372 : }
1373 : }
1374 :
1375 0 : IF( hDirAC->firstrun_sector_params )
1376 : {
1377 0 : *p_sec_I_vec_smth_x_fx = *p_sec_I_vec_x_fx;
1378 0 : move32();
1379 0 : *p_sec_I_vec_smth_y_fx = *p_sec_I_vec_y_fx;
1380 0 : move32();
1381 0 : *p_sec_I_vec_smth_z_fx = *p_sec_I_vec_z_fx;
1382 0 : move32();
1383 0 : *p_energy_smth_fx = energy_fx;
1384 0 : move32();
1385 0 : *p_sec_I_vec_smth_x_exp = *p_sec_I_vec_x_exp;
1386 0 : move16();
1387 0 : *p_sec_I_vec_smth_y_exp = *p_sec_I_vec_y_exp;
1388 0 : move16();
1389 0 : *p_sec_I_vec_smth_z_exp = *p_sec_I_vec_z_exp;
1390 0 : move16();
1391 0 : *p_energy_smth_exp = energy_exp;
1392 0 : move16();
1393 : }
1394 : ELSE
1395 : {
1396 0 : Word32 w_fx = L_sub( ONE_IN_Q30, beta_fx ); // Q30
1397 : Word32 tmp_1, tmp_2, tmp_3, tmp_sec_1, tmp_sec_2, tmp_sec_3;
1398 : Word16 e_x, e_y, e_z;
1399 0 : move16();
1400 :
1401 0 : e_x = s_max( *p_sec_I_vec_x_exp, *p_sec_I_vec_smth_x_exp );
1402 0 : e_y = s_max( *p_sec_I_vec_y_exp, *p_sec_I_vec_smth_y_exp );
1403 0 : e_z = s_max( *p_sec_I_vec_z_exp, *p_sec_I_vec_smth_z_exp );
1404 :
1405 0 : tmp_1 = L_shr( *p_sec_I_vec_x_fx, sub( e_x, *p_sec_I_vec_x_exp ) ); // e_x
1406 0 : tmp_2 = L_shr( *p_sec_I_vec_y_fx, sub( e_y, *p_sec_I_vec_y_exp ) ); // e_y
1407 0 : tmp_3 = L_shr( *p_sec_I_vec_z_fx, sub( e_z, *p_sec_I_vec_z_exp ) ); // e_z
1408 0 : tmp_sec_1 = L_shr( *p_sec_I_vec_smth_x_fx, sub( e_x, *p_sec_I_vec_smth_x_exp ) ); // e_x
1409 0 : tmp_sec_2 = L_shr( *p_sec_I_vec_smth_y_fx, sub( e_y, *p_sec_I_vec_smth_y_exp ) ); // e_y
1410 0 : tmp_sec_3 = L_shr( *p_sec_I_vec_smth_z_fx, sub( e_z, *p_sec_I_vec_smth_z_exp ) ); // e_z
1411 :
1412 :
1413 0 : temp_x64 = W_mac_32_32( W_mult_32_32( w_fx, tmp_1 ), beta_fx, tmp_sec_1 ); // 31-e_x+30+1=62-e_x
1414 0 : temp_y64 = W_mac_32_32( W_mult_32_32( w_fx, tmp_2 ), beta_fx, tmp_sec_2 ); // 31-e_y+30+1=62-e_y
1415 0 : temp_z64 = W_mac_32_32( W_mult_32_32( w_fx, tmp_3 ), beta_fx, tmp_sec_3 ); // 31-e_z+30+1=62-e_z
1416 :
1417 0 : tmp_scale = sub( W_norm( temp_x64 ), 32 );
1418 0 : *p_sec_I_vec_smth_x_fx = W_shl_sat_l( temp_x64, tmp_scale );
1419 0 : move32();
1420 0 : *p_sec_I_vec_smth_x_exp = sub( sub( e_x, 31 ), tmp_scale ); // 31-(62-e_x+tmp_scale)=e_x-tmp_scale-31
1421 0 : move16();
1422 0 : if ( *p_sec_I_vec_smth_x_fx == 0 )
1423 : {
1424 0 : *p_sec_I_vec_smth_x_exp = 0;
1425 0 : move16();
1426 : }
1427 :
1428 0 : tmp_scale = sub( W_norm( temp_y64 ), 32 );
1429 0 : *p_sec_I_vec_smth_y_fx = W_shl_sat_l( temp_y64, tmp_scale );
1430 0 : move32();
1431 0 : *p_sec_I_vec_smth_y_exp = sub( sub( e_y, 31 ), tmp_scale ); // 31-(62-e_z+tmp_scale)=e_x-tmp_scale-31
1432 0 : move16();
1433 0 : if ( *p_sec_I_vec_smth_y_fx == 0 )
1434 : {
1435 0 : *p_sec_I_vec_smth_y_exp = 0;
1436 0 : move16();
1437 : }
1438 :
1439 0 : tmp_scale = sub( W_norm( temp_z64 ), 32 );
1440 0 : *p_sec_I_vec_smth_z_fx = W_shl_sat_l( temp_z64, tmp_scale );
1441 0 : move32();
1442 0 : *p_sec_I_vec_smth_z_exp = sub( sub( e_z, 31 ), tmp_scale ); // 31-(62-e_z+tmp_scale)=e_x-tmp_scale-31
1443 0 : move16();
1444 0 : if ( *p_sec_I_vec_smth_z_fx == 0 )
1445 : {
1446 0 : *p_sec_I_vec_smth_z_exp = 0;
1447 0 : move16();
1448 : }
1449 :
1450 0 : *p_energy_smth_fx = BASOP_Util_Add_Mant32Exp( Mpy_32_32( w_fx, energy_fx ), add( energy_exp, 1 ), Mpy_32_32( beta_fx, *p_energy_smth_fx ), add( *p_energy_smth_exp, 1 ), p_energy_smth_exp );
1451 0 : move32();
1452 : }
1453 :
1454 0 : IF( LT_32( energy_fx, EPSILON_FX_SMALL ) )
1455 : {
1456 0 : *p_azi_fx = 0;
1457 0 : move32();
1458 0 : *p_ele_fx = 0;
1459 0 : move32();
1460 0 : *p_ene_fx = 0;
1461 0 : move32();
1462 0 : *p_ene_exp = 0;
1463 0 : move16();
1464 0 : *p_diff_fx = ONE_IN_Q30;
1465 0 : move32();
1466 0 : *p_diff_exp = 1;
1467 0 : move16();
1468 : }
1469 : ELSE
1470 : {
1471 : Word32 tmp_x, tmp_y, tmp_z, tmp_xy_hypo, tmp32;
1472 : Word16 tmp16, tmp_e;
1473 0 : tmp_x = Mpy_32_32( *p_sec_I_vec_smth_x_fx, *p_sec_I_vec_smth_x_fx );
1474 0 : tmp_y = Mpy_32_32( *p_sec_I_vec_smth_y_fx, *p_sec_I_vec_smth_y_fx );
1475 0 : tmp_z = Mpy_32_32( *p_sec_I_vec_smth_z_fx, *p_sec_I_vec_smth_z_fx );
1476 0 : tmp32 = BASOP_Util_Add_Mant32Exp( tmp_x, shl( *p_sec_I_vec_smth_x_exp, 1 ), tmp_y, shl( *p_sec_I_vec_smth_y_exp, 1 ), &tmp_e );
1477 0 : normI_fx = BASOP_Util_Add_Mant32Exp( tmp32, tmp_e, tmp_z, shl( *p_sec_I_vec_smth_z_exp, 1 ), &normI_exp );
1478 0 : normI_fx = Sqrt32( normI_fx, &normI_exp );
1479 :
1480 0 : tmp32 = BASOP_Util_Add_Mant32Exp( tmp32, tmp_e, 0, 0, &tmp_e ); // normalising value of tmp32
1481 0 : tmp_xy_hypo = Sqrt32( tmp32, &tmp_e ); // sqrt(x^2 + y^2)
1482 :
1483 0 : tmp16 = BASOP_util_atan2( *p_sec_I_vec_smth_y_fx, *p_sec_I_vec_smth_x_fx, sub( *p_sec_I_vec_smth_y_exp, *p_sec_I_vec_smth_x_exp ) ); // Q13
1484 0 : *p_azi_fx = Mpy_32_32( L_deposit_h( tmp16 ), _180_OVER_PI_Q25 ); // (Q13 + 16) + Q25 - 31 = 54 - 31 = Q23
1485 0 : move32();
1486 0 : tmp16 = BASOP_util_atan2( *p_sec_I_vec_smth_z_fx, L_add( tmp_xy_hypo, EPSILON_FX_SMALL ), sub( *p_sec_I_vec_smth_z_exp, tmp_e ) ); // Q13
1487 0 : *p_ele_fx = Mpy_32_32( L_deposit_h( tmp16 ), _180_OVER_PI_Q25 ); // (Q13 + 16) + Q25 - 31 = 54 - 31 = Q23
1488 0 : move32();
1489 0 : *p_ene_fx = *p_energy_smth_fx;
1490 0 : move32();
1491 0 : *p_ene_exp = *p_energy_smth_exp;
1492 0 : move16();
1493 :
1494 0 : tmp32 = L_deposit_h( BASOP_Util_Divide3232_Scale( normI_fx, L_add_sat( *p_energy_smth_fx, EPSILON_FX_SMALL ), &tmp_e ) );
1495 0 : tmp_e = add( tmp_e, sub( normI_exp, *p_energy_smth_exp ) );
1496 0 : tmp32 = BASOP_Util_Add_Mant32Exp( ONE_IN_Q30, 1, L_negate( tmp32 ), tmp_e, &tmp_e );
1497 0 : *p_diff_fx = tmp32;
1498 0 : move32();
1499 0 : *p_diff_exp = tmp_e;
1500 0 : move16();
1501 : }
1502 :
1503 0 : tmp_diff_fx = *p_diff_fx;
1504 0 : move32();
1505 0 : tmp_diff_exp = *p_diff_exp;
1506 0 : move16();
1507 0 : if ( tmp_diff_fx < 0 )
1508 : {
1509 0 : tmp_diff_fx = 0;
1510 0 : move32();
1511 : }
1512 :
1513 0 : tmp_diff_fx = L_shr( tmp_diff_fx, sub( 2, tmp_diff_exp ) ); // Q29
1514 0 : tmp_diff_exp = 2;
1515 0 : move16();
1516 :
1517 0 : IF( GT_32( tmp_diff_fx, ONE_IN_Q28 ) )
1518 : {
1519 0 : IF( hDirAC->firstrun_sector_params )
1520 : {
1521 0 : *p_azi_fx = 0;
1522 0 : move32();
1523 0 : *p_ele_fx = 0;
1524 0 : move32();
1525 : }
1526 : ELSE
1527 : {
1528 0 : tmp32_1 = L_sub( ONE_IN_Q29, tmp_diff_fx );
1529 0 : tmp32_2 = L_sub( tmp_diff_fx, ONE_IN_Q29 / 2 );
1530 :
1531 : // *p_azi = 2.f * (1.f - tmp_diff) * *p_azi + (2.f * tmp_diff - 1.f) * *p_azi_prev
1532 0 : *p_azi_fx = L_shl( Madd_32_32( Mpy_32_32( tmp32_1, *p_azi_fx ), tmp32_2, *p_azi_prev_fx ), 3 ); // Q29 + Q23 - 31 + 2 = Q23
1533 0 : move32();
1534 :
1535 : // *p_ele = 2.f * (1.f - tmp_diff) * *p_ele + (2.f * tmp_diff - 1.f) * *p_ele_prev
1536 0 : *p_ele_fx = L_shl( Madd_32_32( Mpy_32_32( tmp32_1, *p_ele_fx ), tmp32_2, *p_ele_prev_fx ), 3 ); // Q29 + Q23 - 31 + 2 = Q23
1537 0 : move32();
1538 : }
1539 : }
1540 : ELSE
1541 : {
1542 0 : *p_azi_prev_fx = *p_azi_fx;
1543 0 : move32();
1544 0 : *p_ele_prev_fx = *p_ele_fx;
1545 0 : move32();
1546 : }
1547 : }
1548 : }
1549 :
1550 0 : hDirAC->firstrun_sector_params = 0;
1551 0 : move16();
1552 :
1553 0 : return;
1554 : }
1555 :
1556 :
1557 : /*-----------------------------------------------------------------------*
1558 : * Local functions
1559 : *-----------------------------------------------------------------------*/
1560 :
1561 :
1562 : /*-------------------------------------------------------------------*
1563 : * deindex_sph_idx_general()
1564 : *
1565 : * deindex the spherical index for more than 2 bits for the spherical grid
1566 : *----------------------------------------------------------------------*/
1567 :
1568 1764630 : static UWord16 deindex_sph_idx_general_fx(
1569 : const Word16 idx_sph, /* i : spherical index */
1570 : const Word16 no_bits, /* i : number of bits in the spherical grid */
1571 : Word32 *theta_dec_fx, /* o : decoded elevation value Q22 */
1572 : Word32 *phi_dec_fx, /* o : decoded azimuth value Q22 */
1573 : UWord16 *p_id_phi, /* o : decoded azimuth index */
1574 : const MC_LS_SETUP mc_format /* i : channel format if in MC-mode */
1575 : )
1576 : {
1577 : Word16 i;
1578 : UWord16 id_th;
1579 : Word16 q_id_th;
1580 : Word32 id_th_fx;
1581 : Word16 sign_theta;
1582 : Word16 id_phi;
1583 : Word16 cum_n[250];
1584 : Word16 no_th;
1585 : const Word16 *n;
1586 :
1587 1764630 : id_th = 0;
1588 1764630 : move16();
1589 1764630 : id_phi = 0;
1590 1764630 : move16();
1591 1764630 : sign_theta = 1;
1592 1764630 : move16();
1593 :
1594 1764630 : no_th = no_theta_masa[no_bits - 3];
1595 1764630 : move16();
1596 1764630 : n = no_phi_masa[no_bits - 1];
1597 1764630 : IF( NE_32( mc_format, MC_LS_SETUP_INVALID ) )
1598 : {
1599 : /* indexing */
1600 :
1601 9710 : cum_n[0] = n[0];
1602 9710 : move16();
1603 9710 : IF( GE_16( idx_sph, cum_n[0] ) )
1604 : {
1605 11928 : FOR( i = 1; i < no_th; i++ )
1606 : {
1607 11928 : cum_n[i] = add( cum_n[i - 1], n[i] );
1608 11928 : move16();
1609 11928 : IF( LT_16( idx_sph, cum_n[i] ) )
1610 : {
1611 8170 : id_th = i;
1612 8170 : move16();
1613 8170 : id_phi = sub( idx_sph, cum_n[i - 1] );
1614 8170 : BREAK;
1615 : }
1616 : }
1617 : }
1618 : }
1619 : ELSE
1620 : {
1621 : /* Starting from Equator, alternating positive and negative */
1622 1754920 : cum_n[0] = n[0];
1623 1754920 : move16();
1624 1754920 : IF( GE_16( idx_sph, cum_n[0] ) )
1625 : {
1626 1394008 : FOR( i = 1; i < no_th; i++ )
1627 : {
1628 1394008 : cum_n[2 * i - 1] = add( cum_n[2 * i - 2], n[i] );
1629 1394008 : move16();
1630 :
1631 1394008 : IF( LT_16( idx_sph, cum_n[2 * i - 1] ) )
1632 : {
1633 408123 : id_th = i;
1634 408123 : move16();
1635 408123 : sign_theta = 1;
1636 408123 : move16();
1637 408123 : id_phi = sub( idx_sph, cum_n[2 * i - 2] );
1638 408123 : BREAK;
1639 : }
1640 :
1641 985885 : cum_n[2 * i] = add( cum_n[2 * i - 1], n[i] );
1642 985885 : move16();
1643 :
1644 985885 : IF( LT_16( idx_sph, cum_n[2 * i] ) )
1645 : {
1646 430173 : id_th = i;
1647 430173 : move16();
1648 430173 : sign_theta = -1;
1649 430173 : move16();
1650 430173 : id_phi = sub( idx_sph, cum_n[2 * i - 1] );
1651 430173 : BREAK;
1652 : }
1653 :
1654 555712 : IF( EQ_16( i, sub( no_th, 1 ) ) )
1655 : {
1656 0 : id_th = i;
1657 0 : move16();
1658 0 : sign_theta = -1;
1659 0 : move16();
1660 0 : id_phi = 0; /* idx_sph - cum_n[2*i-1]; */
1661 0 : move16();
1662 0 : BREAK;
1663 : }
1664 : }
1665 : }
1666 : }
1667 :
1668 1764630 : IF( id_th == 0 )
1669 : {
1670 918164 : id_phi = idx_sph;
1671 918164 : move16();
1672 : }
1673 : ELSE
1674 : {
1675 846466 : test();
1676 846466 : if ( EQ_32( id_th, sub( no_th, 1 ) ) && GT_16( no_bits, 4 ) )
1677 : {
1678 2568 : id_phi = 0;
1679 2568 : move16();
1680 : }
1681 : }
1682 :
1683 1764630 : q_id_th = norm_l( id_th );
1684 1764630 : id_th_fx = L_shl( id_th, q_id_th );
1685 1764630 : *theta_dec_fx = L_shl( Mpy_32_32( id_th_fx, delta_theta_masa_fx[no_bits - 3] ), sub( 31, q_id_th ) ); // Q22
1686 1764630 : move32();
1687 :
1688 1764630 : IF( GE_32( *theta_dec_fx, 90 << Q22 ) )
1689 : {
1690 2538 : *theta_dec_fx = ( 90 << 22 ) * sign_theta;
1691 2538 : move32();
1692 2538 : *phi_dec_fx = 0;
1693 2538 : move32();
1694 2538 : *p_id_phi = 0;
1695 2538 : move16();
1696 : }
1697 : ELSE
1698 : {
1699 1762092 : *theta_dec_fx *= sign_theta;
1700 :
1701 1762092 : *phi_dec_fx = deindex_azimuth_fx( id_phi, no_bits, id_th, 0, mc_format ); // Q22
1702 1762092 : move32();
1703 1762092 : *p_id_phi = id_phi;
1704 1762092 : move16();
1705 : }
1706 :
1707 1764630 : return id_th;
1708 : }
|