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