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 <stdint.h>
34 : #include "math.h"
35 : #include "options.h"
36 : #include "basop_util.h"
37 : #include "ivas_stat_com.h"
38 : #include "prot_fx.h"
39 : #include "rom_com.h"
40 : #include "ivas_rom_com.h"
41 : #include "cnst.h"
42 : #include <assert.h>
43 : #include "wmc_auto.h"
44 : #include "basop_util.h"
45 : #include "basop32.h"
46 : #include "ivas_prot_fx.h"
47 :
48 :
49 : /*------------------------------------------------------------------------------------------*
50 : * Local constants
51 : *------------------------------------------------------------------------------------------*/
52 :
53 : #define IVAS_FIX_EPS ( 1 )
54 : #define IVAS_FIX_EPS_Q40 ( 110 )
55 :
56 :
57 : #define IVAS_ACTIVEW_DM_F_Q30 ( ONE_IN_Q30 ) /*1 Q30*/
58 : #define IVAS_ACTIVEW_DM_F_DTX_Q30 ( 268435456 ) /*0.25 Q30*/
59 : #define IVAS_ACTIVEW_DM_F_VLBR_Q30 ( 268435456 ) /*0.25 Q30*/
60 : #define IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH_Q29 ( 1610612736 ) /*3 Q29*/
61 :
62 : #define IVAS_P_NORM_SCALING_FX ( ONE_IN_Q31 ) // 1 Q31
63 : #define IVAS_P_NORM_SCALING_DTX_FX ( 1610612736 ) // 0.75 Q31
64 :
65 : #define IVAS_MAT_DIM_3 ( 3 )
66 : #define IVAS_MAT_DIM_2 ( 2 )
67 : #define IVAS_MAT_DIM_1 ( 1 )
68 : #define MAX_MAT_DIM ( FOA_CHANNELS - 1 )
69 :
70 : /*------------------------------------------------------------------------------------------*
71 : * Static functions declaration
72 : *------------------------------------------------------------------------------------------*/
73 :
74 : static void ivas_get_pred_coeffs_enc_fx(
75 : Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_cov_real*/
76 : Word16 *q_cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],
77 : Word32 ppPred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_pred_coeffs*/
78 : Word16 *q_pred_coeffs,
79 : Word32 ppDM_Fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_dm_fv_re*/
80 : Word16 *q_dm_fv_re,
81 : const Word16 in_chans,
82 : const Word16 start_band,
83 : const Word16 end_band,
84 : const Word16 active_w,
85 : const Word16 active_w_vlbr,
86 : const Word16 dtx_vad,
87 : const Word16 from_dirac,
88 : const Word16 dyn_active_w_flag,
89 : const Word16 res_ind );
90 :
91 : static void ivas_get_Wscaling_factor_enc_fx(
92 : Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_cov_real*/
93 : Word16 *q_cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],
94 : Word32 pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_pred_coeffs_re*/
95 : Word16 q_pred_coeffs_re,
96 : Word32 ***mixer_mat, /*q_mixer_mat*/
97 : Word16 q_mixer_mat,
98 : const Word16 start_band,
99 : const Word16 end_band,
100 : const Word16 dtx_vad,
101 : const Word16 num_ch,
102 : const Word16 *pNum_dmx,
103 : const Word16 bands_bw,
104 : const Word16 active_w,
105 : const Word16 active_w_vlbr,
106 : Word32 *pWscale, /*q_pWscale*/
107 : Word16 *q_pWscale,
108 : const Word16 dyn_active_w_flag );
109 :
110 : static void ivas_calc_post_pred_per_band_enc_fx(
111 : Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_cov_real*/
112 : Word16 *q_cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],
113 : Word32 ***mixer_mat, /*q_mixer_mat*/
114 : Word16 q_mixer_mat,
115 : const Word16 num_ch,
116 : const Word16 band_idx,
117 : Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_postpred_cov_re*/
118 : Word16 *q_postpred_cov_re );
119 :
120 : static void ivas_get_pred_coeffs_fx(
121 : Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*Q30*/
122 : Word32 ppPred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_pred_coeffs*/
123 : Word32 ppDM_Fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_dm_fv_re*/
124 : const Word16 in_chans,
125 : const Word16 start_band,
126 : const Word16 end_band,
127 : const Word16 active_w,
128 : const Word16 active_w_vlbr,
129 : const Word16 dtx_vad,
130 : const Word16 from_dirac,
131 : const Word16 dyn_active_w_flag,
132 : const Word16 res_ind,
133 : Word16 *q_pred_coeffs,
134 : Word16 *q_dm_fv_re );
135 : static void ivas_reorder_array_fx( Word32 in_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS] /*qx*/, const Word16 in_chans, const Word16 order[IVAS_SPAR_MAX_CH], Word32 ***mixer_mat /*qx*/, const Word16 start_band, const Word16 end_band );
136 : static void ivas_get_Wscaling_factor_fx( Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH] /*q_cov_real*/, Word16 q_cov_real, Word32 pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS] /*q_pred_coeffs_re*/, Word16 q_pred_coeffs_re, Word32 ***mixer_mat /*q_mixer_mat*/, Word16 q_mixer_mat, const Word16 start_band, const Word16 end_band, const Word16 dtx_vad, const Word16 num_ch, const Word16 *pNum_dmx, const Word16 bands_bw, const Word16 active_w, const Word16 active_w_vlbr, Word32 *pWscale /*q_pWscale*/, Word16 *q_pWscale, const Word16 dyn_active_w_flag );
137 : static void ivas_calc_post_pred_per_band_fx( Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH] /*q_cov_real*/, Word16 q_cov_real, Word32 ***mixer_mat /*q_mixer_mat*/, Word16 q_mixer_mat, const Word16 num_ch, const Word16 band_idx, Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH] /*q_postpred_cov_re*/, Word16 *q_postpred_cov_re );
138 : static Word16 ivas_is_mat_inv_fx( Word32 in_re[MAX_MAT_DIM][MAX_MAT_DIM] /*q_in_re*/, Word16 q_in_re, const Word16 dim );
139 : static void ivas_calc_mat_inv_fx( Word32 in_re[MAX_MAT_DIM][MAX_MAT_DIM] /*q_in_re*/, Word16 q_in_re, const Word16 dim, Word32 out_re[MAX_MAT_DIM][MAX_MAT_DIM] /*q_out_re*/, Word16 *q_out_re );
140 :
141 : /*-----------------------------------------------------------------------------------------*
142 : * Function ivas_get_bw_idx_from_sample_rate()
143 : *
144 : * Get bwidth index from sample rate.
145 : *-----------------------------------------------------------------------------------------*/
146 :
147 : /*! r: audio BW index */
148 161646 : Word16 ivas_get_bw_idx_from_sample_rate_fx(
149 : const Word32 sampling_rate /* i : sampling rate */
150 : )
151 : {
152 161646 : Word16 bwidth = 0;
153 161646 : move16();
154 :
155 161646 : SWITCH( sampling_rate )
156 : {
157 12160 : case 16000:
158 12160 : bwidth = WB;
159 12160 : move16();
160 12160 : BREAK;
161 70962 : case 32000:
162 70962 : bwidth = SWB;
163 70962 : move16();
164 70962 : BREAK;
165 78524 : case 48000:
166 78524 : bwidth = FB;
167 78524 : move16();
168 78524 : BREAK;
169 0 : default:
170 0 : assert( !"Unsupported sample rate!" );
171 : }
172 :
173 161646 : return bwidth;
174 : }
175 :
176 : /*-------------------------------------------------------------------------
177 : * ivas_spar_config()
178 : *
179 : * SPAR configuration function
180 : *------------------------------------------------------------------------*/
181 :
182 6450 : void ivas_spar_config_fx(
183 : Word32 ivas_total_brate, /* i : codec total bitrate */
184 : const Word16 sba_order, /* i : Ambisonic (SBA) order */
185 : Word16 *nchan_transport, /* o : number of transport channels */
186 : Word16 *nSCE, /* o : number of SCEs */
187 : Word16 *nCPE, /* o : number of CPEs */
188 : Word32 *core_nominal_brate, /* o : core-coding nominal bitrate */
189 : const Word16 sid_format /* i : IVAS format indicator from SID frame */
190 : )
191 : {
192 6450 : IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) )
193 : {
194 0 : IF( EQ_16( sid_format, SID_SBA_1TC ) )
195 : {
196 0 : *nchan_transport = 1;
197 0 : move16();
198 : }
199 : ELSE
200 : {
201 0 : *nchan_transport = 2;
202 0 : move16();
203 : }
204 : }
205 : ELSE
206 : {
207 6450 : *nchan_transport = ivas_get_sba_num_TCs_fx( ivas_total_brate, sba_order );
208 6450 : move16();
209 : }
210 :
211 6450 : IF( GT_16( *nchan_transport, 1 ) )
212 : {
213 4176 : *nCPE = shr( add( *nchan_transport, 1 ), 1 );
214 4176 : move16();
215 : }
216 : ELSE
217 : {
218 2274 : *nCPE = 0;
219 2274 : move16();
220 : }
221 :
222 6450 : *nSCE = s_max( 0, sub( *nchan_transport, shl( *nCPE, 1 ) ) );
223 6450 : move16();
224 :
225 6450 : IF( EQ_16( *nchan_transport, 1 ) )
226 : {
227 : /* map SPAR SID bitrate to SPAR active bitrate */
228 2274 : if ( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) )
229 : {
230 0 : ivas_total_brate = IVAS_32k;
231 0 : move32();
232 : }
233 2274 : assert( ivas_total_brate == IVAS_32k || ivas_total_brate == IVAS_24k4 || ivas_total_brate == IVAS_16k4 || ivas_total_brate == IVAS_13k2 );
234 2274 : IF( EQ_32( ivas_total_brate, IVAS_32k ) )
235 : {
236 487 : *core_nominal_brate = ACELP_24k40;
237 487 : move32();
238 : }
239 1787 : ELSE IF( EQ_32( ivas_total_brate, IVAS_24k4 ) )
240 : {
241 466 : *core_nominal_brate = ACELP_16k40;
242 466 : move32();
243 : }
244 1321 : ELSE IF( EQ_32( ivas_total_brate, IVAS_16k4 ) )
245 : {
246 690 : *core_nominal_brate = ACELP_13k20;
247 690 : move32();
248 : }
249 631 : ELSE IF( EQ_32( ivas_total_brate, IVAS_13k2 ) )
250 : {
251 631 : *core_nominal_brate = ACELP_9k60;
252 631 : move32();
253 : }
254 : }
255 :
256 6450 : return;
257 : }
258 :
259 : /*-----------------------------------------------------------------------------------------*
260 : * Function ivas_get_spar_table_idx()
261 : *
262 : * Get SPAR table index
263 : *-----------------------------------------------------------------------------------------*/
264 :
265 : /*! r: config. table index */
266 647286 : Word16 ivas_get_spar_table_idx_fx(
267 : const Word32 ivas_total_brate, /* i : IVAS total bitrate */
268 : const Word16 sba_order, /* i : Ambisonic (SBA) order */
269 : const Word16 bwidth, /* i : audio bandwidth */
270 : Word16 *bitlen, /* o : number of bits */
271 : Word16 *ind /* o : indice */
272 : )
273 : {
274 647286 : Word16 table_idx = 0, ind1[IVAS_SPAR_BR_TABLE_LEN];
275 647286 : Word16 i, j = 0, ind2 = -1;
276 647286 : move16();
277 647286 : move16();
278 647286 : move16();
279 :
280 13593006 : FOR( i = 0; i < IVAS_SPAR_BR_TABLE_LEN; i++ )
281 : {
282 12945720 : ind1[j] = 0;
283 12945720 : move16();
284 12945720 : test();
285 12945720 : IF( ( EQ_32( ivas_spar_br_table_consts[i].ivas_total_brate, ivas_total_brate ) ) &&
286 : ( EQ_16( ivas_spar_br_table_consts[i].sba_order, sba_order ) ) )
287 : {
288 647286 : ind1[j] = i;
289 647286 : j++;
290 647286 : move16();
291 : }
292 : }
293 :
294 647286 : FOR( i = 0; i < j; i++ )
295 : {
296 647286 : IF( EQ_16( ivas_spar_br_table_consts[ind1[i]].bwidth, bwidth ) )
297 : {
298 647286 : ind2 = i;
299 647286 : move16();
300 647286 : BREAK;
301 : }
302 : }
303 647286 : assert( j > 0 ); /* to check if bitrate entry is present */
304 647286 : assert( ind2 >= 0 ); /* to check if bw entry is present */
305 :
306 647286 : table_idx = ind1[ind2];
307 647286 : move16();
308 :
309 647286 : if ( ind != NULL )
310 : {
311 5453 : *ind = ind2;
312 5453 : move16();
313 : }
314 :
315 647286 : IF( bitlen != NULL )
316 : {
317 30103 : *bitlen = ivas_get_bits_to_encode( sub( j, 1 ) );
318 30103 : move16();
319 : }
320 :
321 647286 : return table_idx;
322 : }
323 : /*-------------------------------------------------------------------*
324 : * ivas_get_sba_num_TCs()
325 : *
326 : * Return number of TCs in SBA format
327 : *-------------------------------------------------------------------*/
328 :
329 : /*! r: number of transport channels */
330 451533 : Word16 ivas_get_sba_num_TCs_fx(
331 : const Word32 ivas_total_brate, /* i : IVAS total bitrate */
332 : const Word16 sba_order /* i : Ambisonic (SBA) order */
333 : )
334 : {
335 : Word16 table_idx, nchan_transport;
336 :
337 451533 : table_idx = ivas_get_spar_table_idx_fx( ivas_total_brate, sba_order, SPAR_CONFIG_BW, NULL, NULL );
338 :
339 451533 : nchan_transport = ivas_spar_br_table_consts[table_idx].nchan_transport;
340 451533 : move16();
341 :
342 451533 : return nchan_transport;
343 : }
344 :
345 : /*-----------------------------------------------------------------------------------------*
346 : * Function ivas_get_pred_coeffs()
347 : *
348 : * Calculation of prediction coefficients
349 : *-----------------------------------------------------------------------------------------*/
350 :
351 : /*-----------------------------------------------------------------------------------------*
352 : * Function ivas_get_pred_coeffs_fx()
353 : *
354 : * Calculation of prediction coefficients
355 : *-----------------------------------------------------------------------------------------*/
356 :
357 311060 : static void ivas_get_pred_coeffs_enc_fx(
358 : Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_cov_real*/
359 : Word16 *q_cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],
360 : Word32 ppPred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_pred_coeffs*/
361 : Word16 *q_pred_coeffs,
362 : Word32 ppDM_Fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_dm_fv_re*/
363 : Word16 *q_dm_fv_re,
364 : const Word16 in_chans,
365 : const Word16 start_band,
366 : const Word16 end_band,
367 : const Word16 active_w,
368 : const Word16 active_w_vlbr,
369 : const Word16 dtx_vad,
370 : const Word16 from_dirac,
371 : const Word16 dyn_active_w_flag,
372 : const Word16 res_ind )
373 : {
374 : Word16 i, j, k, b;
375 : Word32 abs_value;
376 : Word32 w_norm_fac;
377 : Word32 L_tmp;
378 : Word16 q_tmp, e_tmp;
379 : Word64 abs_value64, tmp64;
380 : Word16 q_ppPred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS];
381 : Word16 div_factor[IVAS_MAX_NUM_BANDS];
382 : Word16 div_factor_e[IVAS_MAX_NUM_BANDS];
383 311060 : Word16 pred_dim = sub( in_chans, 1 );
384 : Word16 tmp_shift, s_div, div_shift;
385 :
386 311060 : IF( EQ_16( from_dirac, 1 ) )
387 : {
388 150560 : w_norm_fac = 1;
389 150560 : move32();
390 : }
391 : ELSE
392 : {
393 160500 : w_norm_fac = 3;
394 160500 : move32();
395 : }
396 :
397 311060 : IF( active_w == 0 )
398 : {
399 : Word64 pPred_temp[IVAS_MAX_NUM_BANDS];
400 : Word16 q_pPred_temp[IVAS_MAX_NUM_BANDS];
401 :
402 222558 : set64_fx( pPred_temp, 0, IVAS_MAX_NUM_BANDS );
403 222558 : set16_fx( q_pPred_temp, 31, IVAS_MAX_NUM_BANDS );
404 1711768 : FOR( k = start_band; k < end_band; k++ )
405 : {
406 1489210 : div_factor[k] = BASOP_Util_Divide3232_Scale( ONE_IN_Q31 /*1 in q31*/, L_max( 1, cov_real[0][0][k] ), &s_div ); /*Q=15-(s_div-(31-q_cov_real))*/
407 1489210 : move16();
408 :
409 1489210 : div_factor_e[k] = sub( add( s_div, q_cov_real[0][0][k] ), 31 );
410 1489210 : move16();
411 : }
412 :
413 992432 : FOR( i = 0; i < pred_dim; i++ )
414 : {
415 6463904 : FOR( k = start_band; k < end_band; k++ )
416 : {
417 5694030 : tmp64 = W_mult_32_16( cov_real[i + 1][0][k], div_factor[k] ); /*q_cov_real+15-div_factor_e[k]+1*/
418 5694030 : tmp_shift = W_norm( tmp64 );
419 5694030 : IF( tmp64 != 0 )
420 : {
421 5223796 : ppPred_coeffs_re[i][k] = W_extract_h( W_shl( tmp64, tmp_shift ) ); // 1 + q_cov_real[i+1][0][k] + tmp_shift + 15 - div_factor_e[k] - 32
422 5223796 : move32();
423 5223796 : q_ppPred_coeffs_re[i][k] = add( sub( add( q_cov_real[i + 1][0][k], tmp_shift ), div_factor_e[k] ), 1 + 15 - 32 );
424 5223796 : move16();
425 : }
426 : ELSE
427 : {
428 470234 : ppPred_coeffs_re[i][k] = 0;
429 470234 : move32();
430 470234 : q_ppPred_coeffs_re[i][k] = 31;
431 470234 : move16();
432 : }
433 :
434 : // IVAS_CALCULATE_SQ_ABS_N( ppPred_coeffs_re[i][k], abs_value );
435 5694030 : abs_value = Mpy_32_32( ppPred_coeffs_re[i][k], ppPred_coeffs_re[i][k] ); // Q = 2*q_ppPred_coeffs_re[i][k] - 31
436 5694030 : q_tmp = sub( shl( q_ppPred_coeffs_re[i][k], 1 ), 31 );
437 :
438 5694030 : IF( GE_16( q_tmp, q_pPred_temp[k] ) )
439 : {
440 5686048 : abs_value = L_shr( abs_value, sub( q_tmp, q_pPred_temp[k] ) ); // q_tmp -> q_pPred_temp[k]
441 : }
442 : ELSE
443 : {
444 7982 : pPred_temp[k] = W_shr( pPred_temp[k], sub( q_pPred_temp[k], q_tmp ) ); // q_pPred_temp[k]->q_tmp
445 7982 : move64();
446 7982 : q_pPred_temp[k] = q_tmp;
447 7982 : move16();
448 : }
449 :
450 5694030 : pPred_temp[k] = W_add( pPred_temp[k], abs_value ); // Q = q_pPred_temp[k]
451 5694030 : move64();
452 : }
453 : }
454 :
455 1711768 : FOR( k = start_band; k < end_band; k++ )
456 : {
457 1489210 : tmp_shift = W_norm( pPred_temp[k] );
458 1489210 : e_tmp = sub( 31, sub( add( q_pPred_temp[k], tmp_shift ), 32 ) );
459 1489210 : L_tmp = Sqrt32( W_extract_h( W_shl( pPred_temp[k], tmp_shift ) ), &e_tmp ); // Q=31-e_tmp
460 :
461 1489210 : IF( BASOP_Util_Cmp_Mant32Exp( L_tmp, e_tmp, ONE_IN_Q31, 0 ) <= 0 )
462 : {
463 1417051 : L_tmp = ONE_IN_Q31;
464 1417051 : move32();
465 1417051 : e_tmp = 0;
466 1417051 : move16();
467 : }
468 :
469 1489210 : div_factor[k] = BASOP_Util_Divide3232_Scale( 1, L_tmp, &s_div ); // exp(0-e_tmp+s_div)
470 1489210 : move16();
471 1489210 : div_factor[k] = shl( div_factor[k], sub( add( s_div, 30 ), e_tmp ) ); // Q = Q14
472 1489210 : move16();
473 : }
474 :
475 222558 : tmp_shift = Q30; // To avoid saturation for Q31
476 222558 : move16();
477 992432 : FOR( i = 0; i < pred_dim; i++ )
478 : {
479 6463904 : FOR( k = start_band; k < end_band; k++ )
480 : {
481 5694030 : IF( NE_16( div_factor[k], ONE_IN_Q14 /*1 in Q14*/ ) )
482 : {
483 475478 : ppPred_coeffs_re[i][k] = L_shl( Mpy_32_16_1( ppPred_coeffs_re[i][k], div_factor[k] ), 1 ); // Q = q_ppPred_coeffs_re[i][k]
484 475478 : move32();
485 : }
486 5694030 : ppDM_Fv_re[i][k] = 0;
487 5694030 : move32();
488 :
489 5694030 : IF( ppPred_coeffs_re[i][k] != 0 )
490 : {
491 5223796 : tmp_shift = s_min( tmp_shift, add( norm_l( ppPred_coeffs_re[i][k] ), q_ppPred_coeffs_re[i][k] ) );
492 : }
493 : }
494 : }
495 992432 : FOR( i = 0; i < pred_dim; i++ )
496 : {
497 6463904 : FOR( k = start_band; k < end_band; k++ )
498 : {
499 5694030 : ppPred_coeffs_re[i][k] = L_shr( ppPred_coeffs_re[i][k], sub( q_ppPred_coeffs_re[i][k], tmp_shift ) ); // Q=tmp_shift
500 5694030 : move32();
501 : }
502 : }
503 222558 : *q_pred_coeffs = tmp_shift;
504 222558 : move16();
505 222558 : *q_dm_fv_re = 30; // To avoid saturation in Q31
506 222558 : move16();
507 : }
508 : ELSE
509 : {
510 : Word64 real64[IVAS_SPAR_MAX_CH - 1];
511 : Word64 re, dm_y;
512 : Word16 dm_beta_re_q;
513 : Word16 dm_alpha_q[IVAS_MAX_NUM_BANDS];
514 : Word16 dm_v_re_q[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS];
515 : Word32 dm_alpha[IVAS_MAX_NUM_BANDS], dm_v_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS];
516 : Word32 dm_g[IVAS_MAX_NUM_BANDS];
517 : Word16 real64_q[IVAS_SPAR_MAX_CH - 1];
518 : Word32 dm_f_local, dm_w, DM_F[IVAS_MAX_NUM_BANDS];
519 : Word16 DM_F_q[IVAS_MAX_NUM_BANDS], dm_g_q[IVAS_MAX_NUM_BANDS];
520 : Word32 num_f, den_f, passive_g, dm_beta_re /*, inv_den_f*/;
521 : Word32 activew_quad_thresh, g_th_sq;
522 : Word32 L_tmp1, L_tmp2;
523 : Word16 L_tmp1_q, L_tmp2_q;
524 : Word16 den_f_e, s_dm_f;
525 : Word16 guard_bits;
526 :
527 88502 : IF( EQ_16( dyn_active_w_flag, 1 ) )
528 : {
529 0 : activew_quad_thresh = ONE_IN_Q29; /*1 in Q29*/
530 0 : move32();
531 : }
532 : ELSE
533 : {
534 88502 : activew_quad_thresh = IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH_Q29; /*3.0f Q29*/
535 88502 : move32();
536 : }
537 88502 : g_th_sq = Mpy_32_32( activew_quad_thresh, activew_quad_thresh ); // Q27
538 :
539 88502 : guard_bits = sub( find_guarded_bits_fx( in_chans ), 1 );
540 560986 : FOR( k = start_band; k < end_band; k++ )
541 : {
542 472484 : IF( cov_real[1][0][k] == 0 )
543 : {
544 45820 : tmp64 = 0;
545 45820 : move64();
546 45820 : dm_alpha_q[k] = 127;
547 45820 : move16();
548 : }
549 : ELSE
550 : {
551 426664 : tmp64 = W_shr( W_mult0_32_32( cov_real[1][0][k], cov_real[1][0][k] ), guard_bits ); // Q = 2 * q_cov_real[1][0][k] - guard_bits
552 426664 : dm_alpha_q[k] = sub( shl( q_cov_real[1][0][k], 1 ), guard_bits );
553 426664 : move16();
554 : }
555 1417452 : FOR( i = 2; i < in_chans; i++ )
556 : {
557 : // IVAS_CALCULATE_SQ_ABS_N( cov_real[i][0][k], abs_value );
558 944968 : IF( cov_real[i][0][k] != 0 )
559 : {
560 885785 : abs_value64 = W_shr( W_mult0_32_32( cov_real[i][0][k], cov_real[i][0][k] ), guard_bits ); // Q = 2 * q_cov_real[i][0][k] - guard_bits
561 885785 : q_tmp = sub( shl( q_cov_real[i][0][k], 1 ), guard_bits );
562 885785 : tmp_shift = sub( q_tmp, dm_alpha_q[k] );
563 :
564 885785 : IF( tmp_shift < 0 )
565 : {
566 179652 : IF( LE_16( tmp_shift, -63 ) )
567 : {
568 45640 : tmp64 = abs_value64;
569 45640 : move64();
570 : }
571 : ELSE
572 : {
573 134012 : tmp64 = W_add( W_shl( tmp64, tmp_shift ), abs_value64 ); // Q=q_tmp
574 : }
575 179652 : dm_alpha_q[k] = q_tmp;
576 179652 : move16();
577 : }
578 : ELSE
579 : {
580 706133 : IF( LE_16( tmp_shift, 63 ) )
581 : {
582 706133 : tmp64 = W_add( tmp64, W_shr( abs_value64, tmp_shift ) ); // Q=dm_alpha_q[k]
583 : }
584 : }
585 : }
586 : }
587 472484 : IF( tmp64 != 0 )
588 : {
589 472304 : tmp_shift = W_norm( tmp64 );
590 472304 : e_tmp = sub( 63, add( dm_alpha_q[k], tmp_shift ) );
591 472304 : dm_alpha[k] = Sqrt32( W_extract_h( W_shl( tmp64, tmp_shift ) ), &e_tmp ); // Q=31-e_tmp
592 472304 : move32();
593 472304 : dm_alpha_q[k] = sub( 31, e_tmp );
594 472304 : move16();
595 :
596 472304 : div_factor[k] = BASOP_Util_Divide3232_Scale( ONE_IN_Q31 /*1 Q31*/, dm_alpha[k], &s_div ); // Q=15-(dm_alpha_q[k]+ s_div-31)
597 472304 : move16();
598 :
599 472304 : div_factor_e[k] = sub( add( dm_alpha_q[k], s_div ), 31 );
600 472304 : move16();
601 : }
602 : ELSE
603 : {
604 180 : dm_alpha[k] = 0;
605 180 : move32();
606 180 : dm_alpha_q[k] = 31;
607 180 : move16();
608 :
609 180 : div_factor[k] = 22204;
610 180 : move16();
611 :
612 180 : div_factor_e[k] = -37;
613 180 : move16();
614 : }
615 : }
616 :
617 354008 : FOR( i = 0; i < pred_dim; i++ )
618 : {
619 1682958 : FOR( k = start_band; k < end_band; k++ )
620 : {
621 1417452 : tmp64 = W_mult_32_16( cov_real[i + 1][0][k], div_factor[k] ); // Q=(15-div_factor_e[k]+q_cov_real[i+1][0][k])+1
622 1417452 : tmp_shift = W_norm( tmp64 );
623 1417452 : IF( tmp64 != 0 )
624 : {
625 1312449 : dm_v_re[i][k] = W_extract_h( W_shl( tmp64, tmp_shift ) ); // 1 + q_cov_real[i+1][0][k] + tmp_shift + 15 - div_factor_e[k] - 32
626 1312449 : move32();
627 1312449 : dm_v_re_q[i][k] = add( sub( add( q_cov_real[i + 1][0][k], tmp_shift ), div_factor_e[k] ), 1 + 15 - 32 );
628 1312449 : move16();
629 : }
630 : ELSE
631 : {
632 105003 : dm_v_re[i][k] = 0;
633 105003 : move32();
634 105003 : dm_v_re_q[i][k] = 31;
635 105003 : move16();
636 : }
637 : }
638 : }
639 :
640 88502 : IF( dtx_vad == 0 )
641 : {
642 1684 : dm_f_local = IVAS_ACTIVEW_DM_F_DTX_Q30; // q30
643 1684 : move32();
644 : }
645 : ELSE
646 : {
647 86818 : IF( active_w_vlbr )
648 : {
649 26738 : dm_f_local = IVAS_ACTIVEW_DM_F_VLBR_Q30; // q30
650 26738 : move32();
651 : }
652 : ELSE
653 : {
654 60080 : dm_f_local = IVAS_ACTIVEW_DM_F_Q30; // q30
655 60080 : move32();
656 : }
657 : }
658 :
659 560986 : FOR( b = start_band; b < end_band; b++ )
660 : {
661 472484 : set64_fx( real64, 0, pred_dim );
662 472484 : set16_fx( real64_q, 31, pred_dim );
663 :
664 1889936 : FOR( j = 0; j < pred_dim; j++ )
665 : {
666 5669808 : FOR( k = 1; k < in_chans; k++ )
667 : {
668 : // IVAS_RMULT_FLOAT( cov_real[j + 1][k][b], dm_v_re[k - 1][b], re );
669 4252356 : re = W_mult0_32_32( cov_real[j + 1][k][b], dm_v_re[k - 1][b] ); // Q=q_cov_real[j+1][k][b]+dm_v_re_q[k-1][b]
670 4252356 : tmp_shift = W_norm( re );
671 4252356 : IF( re != 0 )
672 : {
673 3748719 : q_tmp = sub( add( add( q_cov_real[j + 1][k][b], dm_v_re_q[k - 1][b] ), tmp_shift ), 32 );
674 : }
675 : ELSE
676 : {
677 503637 : q_tmp = 31;
678 503637 : move16();
679 : }
680 :
681 4252356 : IF( LT_16( q_tmp, real64_q[j] ) )
682 : {
683 1351321 : real64[j] = W_add( W_shr( real64[j], sub( real64_q[j], q_tmp ) ), W_extract_h( W_shl( re, tmp_shift ) ) ); // Q=q_tmp
684 1351321 : move64();
685 1351321 : real64_q[j] = q_tmp;
686 1351321 : move16();
687 : }
688 : ELSE
689 : {
690 2901035 : tmp_shift = sub( add( q_tmp, sub( 32, tmp_shift ) ), real64_q[j] );
691 2901035 : IF( LT_16( tmp_shift, 63 ) )
692 : {
693 2895763 : real64[j] = W_add( real64[j], W_shr( re, tmp_shift ) ); // Q=real64_q[j]
694 2895763 : move64();
695 : }
696 : }
697 : }
698 : }
699 :
700 472484 : tmp64 = 0;
701 472484 : move64();
702 472484 : dm_beta_re_q = 31;
703 472484 : move16();
704 1889936 : FOR( k = 0; k < pred_dim; k++ )
705 : {
706 : // IVAS_RMULT_FLOAT( real[k], dm_v_re[k][b], re );
707 1417452 : tmp_shift = W_norm( real64[k] );
708 1417452 : re = W_mult0_32_32( W_extract_h( W_shl( real64[k], tmp_shift ) ), dm_v_re[k][b] ); // Q=(real64[k]+tmp_shift-32)+dm_v_re_q
709 1417452 : q_tmp = sub( add( add( real64_q[k], dm_v_re_q[k][b] ), tmp_shift ), 32 );
710 1417452 : tmp_shift = W_norm( re );
711 1417452 : IF( re != 0 )
712 : {
713 1312449 : q_tmp = sub( add( q_tmp, tmp_shift ), 32 );
714 : }
715 : ELSE
716 : {
717 105003 : q_tmp = 31;
718 105003 : move16();
719 : }
720 :
721 1417452 : IF( LT_16( q_tmp, dm_beta_re_q ) )
722 : {
723 447443 : tmp64 = W_add( W_shr( tmp64, sub( dm_beta_re_q, q_tmp ) ), W_extract_h( W_shl( re, tmp_shift ) ) ); // Q=q_tmp
724 447443 : dm_beta_re_q = q_tmp;
725 447443 : move16();
726 : }
727 : ELSE
728 : {
729 970009 : tmp_shift = sub( add( q_tmp, sub( 32, tmp_shift ) ), dm_beta_re_q );
730 970009 : IF( LT_16( tmp_shift, 63 ) )
731 : {
732 923664 : tmp64 = W_add( tmp64, W_shr( re, tmp_shift ) ); // Q=dm_beta_re_q
733 : }
734 : }
735 : }
736 472484 : tmp_shift = W_norm( tmp64 );
737 472484 : dm_beta_re = W_extract_h( W_shl( tmp64, tmp_shift ) ); // Q=dm_beta_re_q+tmp_shift-32
738 472484 : IF( tmp64 != 0 )
739 : {
740 472304 : dm_beta_re_q = sub( add( dm_beta_re_q, tmp_shift ), 32 );
741 : }
742 : ELSE
743 : {
744 180 : dm_beta_re_q = 31;
745 180 : move16();
746 : }
747 :
748 472484 : dm_w = cov_real[0][0][b]; // q_cov_real[0][0][b]
749 472484 : move32();
750 472484 : den_f = L_max( dm_w, 1 ); // q_cov_real[0][0][b]
751 472484 : passive_g = L_deposit_l( BASOP_Util_Divide3232_Scale( dm_alpha[b], den_f, &s_div ) ); // dm_alpha_q[b] - q_cov_real[0][0][b] + 15 - s_div
752 :
753 472484 : div_shift = sub( Q29, add( sub( dm_alpha_q[b], q_cov_real[0][0][b] ), sub( 15, s_div ) ) );
754 472484 : passive_g = L_shl_sat( passive_g, div_shift ); // Q = 29
755 :
756 472484 : IF( EQ_16( dyn_active_w_flag, 1 ) )
757 : {
758 0 : dm_alpha[b] = 0;
759 0 : move32();
760 0 : dm_alpha_q[b] = 0;
761 0 : move16();
762 0 : dm_w = 0;
763 0 : move32();
764 0 : FOR( i = 0; i < pred_dim; i++ )
765 : {
766 0 : dm_v_re[i][b] = 0;
767 0 : move32();
768 0 : dm_v_re_q[i][b] = 31;
769 0 : move16();
770 : }
771 0 : dm_v_re[res_ind - 1][b] = MAX_32; /*1 Q31*/
772 0 : move32();
773 0 : dm_v_re_q[i][b] = 31;
774 0 : move16();
775 :
776 0 : passive_g = activew_quad_thresh; // q29
777 0 : move32();
778 : }
779 :
780 472484 : IF( LT_32( passive_g, activew_quad_thresh ) ) // q29
781 : {
782 : /*linear activeW*/
783 472484 : dm_y = 0;
784 472484 : move32();
785 472484 : q_tmp = 31;
786 472484 : move16();
787 :
788 1889936 : FOR( k = 1; k < in_chans; k++ )
789 : {
790 1417452 : IF( GT_16( q_tmp, q_cov_real[k][k][b] ) )
791 : {
792 585958 : dm_y = W_add( W_shr( dm_y, sub( q_tmp, q_cov_real[k][k][b] ) ), cov_real[k][k][b] ); // q_cov_real[k][k][b]
793 585958 : q_tmp = q_cov_real[k][k][b];
794 585958 : move16();
795 : }
796 : ELSE
797 : {
798 831494 : dm_y = W_add( dm_y, L_shr( cov_real[k][k][b], sub( q_cov_real[k][k][b], q_tmp ) ) ); // q_tmp
799 : }
800 : }
801 472484 : tmp64 = W_mult0_32_32( w_norm_fac, dm_w ); // Q=q_tmp
802 472484 : IF( LT_16( q_tmp, q_cov_real[0][0][b] ) )
803 : {
804 9067 : tmp64 = W_shr( tmp64, s_min( 63, sub( q_cov_real[0][0][b], q_tmp ) ) ); // Q=q_tmp
805 : }
806 : ELSE
807 : {
808 463417 : q_tmp = q_cov_real[0][0][b];
809 463417 : move16();
810 463417 : dm_y = W_shr( dm_y, sub( q_tmp, q_cov_real[0][0][b] ) ); // Q=q_cov_real[0][0][b]
811 : }
812 :
813 472484 : if ( GT_64( tmp64, dm_y ) )
814 : {
815 434650 : dm_y = tmp64; // Q=q_tmp
816 434650 : move16();
817 : }
818 :
819 472484 : tmp_shift = W_norm( dm_y );
820 472484 : IF( dm_y == 0 )
821 : {
822 180 : tmp_shift = 32;
823 180 : move16();
824 180 : den_f = W_extract_l( dm_y );
825 : }
826 : ELSE
827 : {
828 472304 : den_f = W_extract_h( W_shl( dm_y, tmp_shift ) ); // q_tmp + tmp_shift - 32
829 : }
830 :
831 472484 : den_f = L_max( den_f, 1 ); // q_tmp + tmp_shift - 32
832 :
833 472484 : DM_F[b] = L_deposit_l( BASOP_Util_Divide3232_Scale( Mpy_32_32( dm_f_local, dm_alpha[b] ), den_f, &s_div ) ); // Q30 + dm_alpha_q[b] - 31 - q_tmp - tmp_shift + 32 + 15 - s_div
834 472484 : move32();
835 :
836 472484 : DM_F_q[b] = add( sub( sub( dm_alpha_q[b], add( q_tmp, tmp_shift ) ), s_div ), ( 30 - 31 + 32 + 15 ) );
837 472484 : move16();
838 :
839 472484 : IF( LT_32( ONE_IN_Q30, L_shl_sat( DM_F[b], sub( Q30, DM_F_q[b] ) ) ) ) // q30
840 : {
841 0 : DM_F[b] = ONE_IN_Q31; /*1 Q31*/
842 0 : move32();
843 0 : DM_F_q[b] = Q31;
844 0 : move16();
845 : }
846 :
847 472484 : tmp64 = W_mult0_32_32( DM_F[b], DM_F[b] ); /*Q=(2*DM_F_q[b])*/
848 472484 : tmp_shift = W_norm( tmp64 );
849 472484 : IF( tmp64 == 0 )
850 : {
851 180 : tmp_shift = 32;
852 180 : move16();
853 : }
854 : ELSE
855 : {
856 472304 : tmp64 = W_shl( tmp64, tmp_shift ); /*Q=(2*DM_F_q[b]+tmp_shift)*/
857 : }
858 472484 : tmp64 = W_mult0_32_32( W_extract_h( tmp64 ), dm_beta_re ); // 2 * DM_F_q[b] + tmp_shift - 32 + dm_beta_re_q
859 472484 : q_tmp = sub( add( add( shl( DM_F_q[b], 1 ), tmp_shift ), dm_beta_re_q ), 32 );
860 472484 : tmp_shift = sub( W_norm( tmp64 ), 2 );
861 472484 : IF( tmp64 == 0 )
862 : {
863 180 : tmp_shift = 32;
864 180 : move16();
865 : }
866 : ELSE
867 : {
868 472304 : tmp64 = W_shl( tmp64, tmp_shift ); // Q=q_tmp+tmp_shift
869 : }
870 472484 : L_tmp2 = W_extract_h( tmp64 ); // Q=q_tmp+tmp_shift-32
871 472484 : L_tmp2_q = sub( add( q_tmp, tmp_shift ), 32 );
872 :
873 472484 : tmp64 = W_shl( W_mult0_32_32( dm_alpha[b], DM_F[b] ), 1 ); // Q=dm_alpha_q[b]+DM_F_q[b]
874 472484 : tmp_shift = sub( W_norm( tmp64 ), 2 );
875 472484 : IF( tmp64 == 0 )
876 : {
877 180 : tmp_shift = 32;
878 180 : move16();
879 : }
880 : ELSE
881 : {
882 472304 : tmp64 = W_shl( tmp64, tmp_shift ); // Q=dm_alpha_q[b]+DM_F_q[b]+tmp_shift
883 : }
884 472484 : L_tmp1 = W_extract_h( tmp64 ); // DM_F_q[b] + dm_alpha_q[b] + tmp_shift - 32
885 472484 : L_tmp1_q = sub( add( add( DM_F_q[b], dm_alpha_q[b] ), tmp_shift ), 32 );
886 :
887 472484 : IF( LT_16( L_tmp2_q, L_tmp1_q ) )
888 : {
889 180 : L_tmp1 = L_add( L_shr( L_tmp1, sub( L_tmp1_q, L_tmp2_q ) ), L_tmp2 ); // Q=L_tmp2_q
890 180 : L_tmp1_q = L_tmp2_q;
891 180 : move16();
892 : }
893 : ELSE
894 : {
895 472304 : L_tmp1 = L_add( L_tmp1, L_shr( L_tmp2, sub( L_tmp2_q, L_tmp1_q ) ) ); // Q=L_tmp1_q
896 : }
897 :
898 472484 : tmp_shift = sub( norm_l( dm_w ), 1 );
899 472484 : L_tmp2 = L_shl( dm_w, tmp_shift ); // Q=q_cov_real[0][0][b]+ tmp_shift
900 472484 : L_tmp2_q = add( q_cov_real[0][0][b], tmp_shift );
901 :
902 472484 : IF( LT_16( L_tmp2_q, L_tmp1_q ) )
903 : {
904 360401 : den_f = L_add( L_shr( L_tmp1, sub( L_tmp1_q, L_tmp2_q ) ), L_tmp2 ); // Q=L_tmp2_q
905 360401 : den_f_e = sub( 31, L_tmp2_q );
906 : }
907 : ELSE
908 : {
909 112083 : den_f = L_add( L_tmp1, L_shr( L_tmp2, sub( L_tmp2_q, L_tmp1_q ) ) ); // Q=L_tmp2_q
910 112083 : den_f_e = sub( 31, L_tmp1_q );
911 : }
912 :
913 472484 : den_f = L_max( den_f, 1 ); // Q=31-den_f_e
914 :
915 472484 : tmp64 = W_mult0_32_32( DM_F[b], dm_beta_re ); // Q= DM_F_q[b]+dm_beta_re_q
916 472484 : tmp_shift = sub( W_norm( tmp64 ), 1 );
917 472484 : IF( tmp64 == 0 )
918 : {
919 180 : tmp_shift = 32;
920 180 : move16();
921 : }
922 : ELSE
923 : {
924 472304 : tmp64 = W_shl( tmp64, tmp_shift ); // Q= DM_F_q[b]+dm_beta_re_q+tmp_shift
925 : }
926 472484 : L_tmp2_q = sub( add( add( DM_F_q[b], dm_beta_re_q ), tmp_shift ), 32 );
927 472484 : L_tmp2 = W_extract_h( tmp64 ); // Q= DM_F_q[b]+dm_beta_re_q+tmp_shift-32
928 :
929 472484 : tmp_shift = sub( norm_l( dm_alpha[b] ), 1 );
930 :
931 472484 : IF( LT_16( L_tmp2_q, add( dm_alpha_q[b], tmp_shift ) ) )
932 : {
933 1388 : L_tmp1 = L_add( L_shr( dm_alpha[b], sub( dm_alpha_q[b], L_tmp2_q ) ), L_tmp2 ); // Q=L_tmp2_q
934 1388 : L_tmp1_q = L_tmp2_q;
935 1388 : move16();
936 : }
937 : ELSE
938 : {
939 471096 : L_tmp1_q = add( dm_alpha_q[b], tmp_shift );
940 471096 : L_tmp1 = L_add( L_shl( dm_alpha[b], tmp_shift ), L_shr( L_tmp2, sub( L_tmp2_q, L_tmp1_q ) ) ); // Q=L_tmp1_q
941 : }
942 :
943 472484 : dm_g[b] = L_deposit_l( BASOP_Util_Divide3232_Scale( L_tmp1, den_f, &s_div ) ); // L_tmp1_q - (31 - den_f_e) + (15 - s_div)
944 472484 : move32();
945 472484 : dm_g_q[b] = add( sub( add( L_tmp1_q, den_f_e ), s_div ), 15 - 31 );
946 472484 : move16();
947 : }
948 : ELSE
949 : {
950 : Word32 sqrt_val;
951 : Word16 val_e;
952 : Word16 num_f_e;
953 :
954 : /* quadratic activeW */
955 0 : tmp64 = W_shl( W_mult0_32_32( dm_alpha[b], activew_quad_thresh ), 1 ); // Q=dm_alpha_q[b]+29
956 0 : tmp_shift = sub( W_norm( tmp64 ), 1 );
957 0 : IF( tmp64 == 0 )
958 : {
959 0 : tmp_shift = 32;
960 0 : move16();
961 : }
962 : ELSE
963 : {
964 0 : tmp64 = W_shl( tmp64, tmp_shift ); // Q=dm_alpha_q+29+tmp_shift
965 : }
966 0 : L_tmp1 = W_extract_h( tmp64 ); // Q29 + dm_alpha_q[b] + tmp_shift - 32
967 0 : L_tmp1_q = sub( add( add( Q29, dm_alpha_q[b] ), tmp_shift ), 32 ); // Q=dm_alpha_q+29+1+tmp_shift-32
968 :
969 0 : num_f = BASOP_Util_Add_Mant32Exp( dm_beta_re, sub( 31, dm_beta_re_q ), L_negate( L_tmp1 ), sub( 31, L_tmp1_q ), &num_f_e ); // Q=31-num_f_e
970 :
971 0 : sqrt_val = Mpy_32_32( Mpy_32_32( dm_alpha[b], dm_alpha[b] ), g_th_sq ); //((2*dm_alpha_q[b]-31)+27-31)-2 ,reducing the Q by 2 instead of multiplication by 4
972 0 : val_e = sub( 31, sub( sub( add( sub( shl( dm_alpha_q[b], 1 ), 31 ), 27 ), 31 ), 2 ) ); // reducing the Q by 2 instead of multiplication by 4
973 0 : sqrt_val = BASOP_Util_Add_Mant32Exp( sqrt_val, val_e, Mpy_32_32( dm_beta_re, dm_beta_re ), sub( 31, sub( shl( dm_beta_re_q, 1 ), 31 ) ), &val_e ); // q=31-val_e
974 0 : sqrt_val = BASOP_Util_Add_Mant32Exp( sqrt_val, val_e, L_negate( Mpy_32_32( Mpy_32_32( dm_beta_re, g_th_sq ), dm_w ) ), sub( 31, sub( sub( add( sub( add( dm_beta_re_q, 27 ), 31 ), q_cov_real[0][0][b] ), 31 ), 2 ) ) /* reducing the Q by 2 instead of multiplication by 4*/, &val_e ); // q=31-val_e
975 : // val_e = norm_l( sqrt_val );
976 0 : sqrt_val = Sqrt32( sqrt_val, &val_e ); // q=31-val_e
977 :
978 0 : num_f = BASOP_Util_Add_Mant32Exp( num_f, num_f_e, sqrt_val, val_e, &num_f_e ); // q=31-num_f_e
979 :
980 0 : den_f = Mpy_32_32( dm_beta_re, g_th_sq ); // Q=dm_beta_re_q+27-31-1
981 0 : den_f_e = add( add( sub( 31, dm_beta_re_q ), 4 ), 1 ); // adding the exp with 1 instead of multiplication by 2
982 0 : den_f = L_max( den_f, 1 ); // q=31-den_f_e
983 0 : dm_g[b] = activew_quad_thresh; // Q29
984 0 : move32();
985 0 : dm_g_q[b] = Q29;
986 0 : move16();
987 0 : DM_F[b] = BASOP_Util_Divide3232_Scale_newton( Mpy_32_32( dm_g[b], num_f ), den_f, &s_dm_f ); // Q=(31-(s_dm_f+2+num_f_e-den_f_e))
988 0 : move32();
989 0 : DM_F_q[b] = sub( 31, add( s_dm_f, sub( add( 2, num_f_e ), den_f_e ) ) );
990 0 : move16();
991 : }
992 : }
993 :
994 88502 : *q_pred_coeffs = 30; // To avoid saturation in Q31
995 88502 : move16();
996 88502 : *q_dm_fv_re = 30; // To avoid saturation in Q31
997 88502 : move16();
998 :
999 354008 : FOR( i = 0; i < pred_dim; i++ )
1000 : {
1001 1682958 : FOR( b = start_band; b < end_band; b++ )
1002 : {
1003 1417452 : tmp64 = W_mult0_32_32( dm_v_re[i][b], dm_g[b] ); // dm_v_re_q[i][b]+dm_g_q[b]
1004 1417452 : tmp_shift = W_norm( tmp64 );
1005 1417452 : IF( tmp64 == 0 )
1006 : {
1007 105003 : tmp_shift = 32;
1008 105003 : move16();
1009 : }
1010 : ELSE
1011 : {
1012 1312449 : tmp64 = W_shl( tmp64, tmp_shift ); // dm_v_re_q[i][b]+dm_g_q[b]+tmp_shift
1013 : }
1014 1417452 : ppPred_coeffs_re[i][b] = W_extract_h( tmp64 ); // Q = dm_v_re_q[i][b] + dm_g_q[b] + tmp_shift - 32
1015 1417452 : move32();
1016 1417452 : q_ppPred_coeffs_re[i][b] = sub( add( add( dm_v_re_q[i][b], dm_g_q[b] ), tmp_shift ), 32 );
1017 1417452 : move16();
1018 :
1019 1417452 : tmp64 = W_mult0_32_32( dm_v_re[i][b], DM_F[b] ); // Q = dm_v_re_q[i][b] + DM_F_q[b]
1020 1417452 : tmp_shift = W_norm( tmp64 );
1021 1417452 : IF( tmp64 == 0 )
1022 : {
1023 105003 : tmp_shift = 32;
1024 105003 : move16();
1025 : }
1026 : ELSE
1027 : {
1028 1312449 : tmp64 = W_shl( tmp64, tmp_shift ); // Q = dm_v_re_q[i][b] + DM_F_q[b] + tmp_shift
1029 : }
1030 1417452 : ppDM_Fv_re[i][b] = W_extract_h( tmp64 ); // Q = dm_v_re_q[i][b] + DM_F_q[b] + tmp_shift - 32
1031 1417452 : move32();
1032 1417452 : dm_v_re_q[i][b] = sub( add( add( dm_v_re_q[i][b], DM_F_q[b] ), tmp_shift ), 32 );
1033 1417452 : move16();
1034 : // if ( ppDM_Fv_re[i][b] == 0 )
1035 : //{
1036 : // dm_v_re_q[i][b] = Q31;
1037 : // move16();
1038 : // }
1039 :
1040 1417452 : IF( ppPred_coeffs_re[i][b] )
1041 : {
1042 1312449 : *q_pred_coeffs = s_min( *q_pred_coeffs, q_ppPred_coeffs_re[i][b] );
1043 1312449 : move16();
1044 : }
1045 1417452 : IF( ppDM_Fv_re[i][b] )
1046 : {
1047 1312449 : *q_dm_fv_re = s_min( *q_dm_fv_re, dm_v_re_q[i][b] );
1048 1312449 : move16();
1049 : }
1050 : }
1051 : }
1052 354008 : FOR( i = 0; i < pred_dim; i++ )
1053 : {
1054 1682958 : FOR( b = start_band; b < end_band; b++ )
1055 : {
1056 1417452 : ppPred_coeffs_re[i][b] = L_shr( ppPred_coeffs_re[i][b], sub( q_ppPred_coeffs_re[i][b], *q_pred_coeffs ) ); // Q=*q_pred_coeffs
1057 1417452 : move32();
1058 1417452 : ppDM_Fv_re[i][b] = L_shr( ppDM_Fv_re[i][b], sub( dm_v_re_q[i][b], *q_dm_fv_re ) ); // Q=*q_dm_fv_re
1059 1417452 : move32();
1060 : }
1061 : }
1062 : }
1063 :
1064 311060 : return;
1065 : }
1066 :
1067 619367 : static void ivas_get_pred_coeffs_fx(
1068 : Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*Q30*/
1069 : Word32 ppPred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_pred_coeffs*/
1070 : Word32 ppDM_Fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_dm_fv_re*/
1071 : const Word16 in_chans,
1072 : const Word16 start_band,
1073 : const Word16 end_band,
1074 : const Word16 active_w,
1075 : const Word16 active_w_vlbr,
1076 : const Word16 dtx_vad,
1077 : const Word16 from_dirac,
1078 : const Word16 dyn_active_w_flag,
1079 : const Word16 res_ind,
1080 : Word16 *q_pred_coeffs,
1081 : Word16 *q_dm_fv_re )
1082 : {
1083 : Word16 i, j, k, b, p;
1084 : Word32 abs_value;
1085 : Word32 w_norm_fac;
1086 : Word32 one_in_q;
1087 : Word32 div_factor[IVAS_MAX_NUM_BANDS];
1088 619367 : Word16 pred_dim = sub( in_chans, 1 );
1089 : Word16 tmp_shift, prev_tmp_shift, s_div, div_shift;
1090 :
1091 619367 : IF( EQ_16( from_dirac, 1 ) )
1092 : {
1093 619367 : w_norm_fac = ONE_IN_Q29; /*1 q29*/
1094 619367 : move32();
1095 : }
1096 : ELSE
1097 : {
1098 0 : w_norm_fac = 3 * ONE_IN_Q29; /* 3 q29*/
1099 0 : move32();
1100 : }
1101 619367 : tmp_shift = Q30;
1102 619367 : move16();
1103 619367 : IF( active_w == 0 )
1104 : {
1105 : Word32 pPred_temp[IVAS_MAX_NUM_BANDS];
1106 : Word16 q_pred_temp;
1107 499325 : prev_tmp_shift = 31;
1108 499325 : move16();
1109 :
1110 499325 : set32_fx( pPred_temp, 0, IVAS_MAX_NUM_BANDS );
1111 2419925 : FOR( k = start_band; k < end_band; k++ )
1112 : {
1113 1920600 : div_factor[k] = L_max( 1, cov_real[0][0][k] ); // q30
1114 1920600 : move32();
1115 1920600 : tmp_shift = Q30;
1116 1920600 : move16();
1117 1920600 : IF( NE_32( cov_real[0][0][k], ONE_IN_Q30 ) ) // q30
1118 : {
1119 0 : div_factor[k] = L_deposit_l( BASOP_Util_Divide3232_Scale( ONE_IN_Q31 /*1 q31*/, div_factor[k], &s_div ) ); // Q=15-(s_div-(31-30))
1120 0 : move32();
1121 0 : IF( s_div < 0 )
1122 : {
1123 0 : div_shift = add( 15, s_div );
1124 0 : tmp_shift = Q30;
1125 0 : move16();
1126 : }
1127 : ELSE
1128 : {
1129 0 : div_shift = 15;
1130 0 : move16();
1131 0 : tmp_shift = sub( Q30, s_div );
1132 : }
1133 0 : div_factor[k] = L_shl( div_factor[k], div_shift ); // Q = tmp_shift
1134 0 : move16();
1135 :
1136 0 : IF( LT_16( tmp_shift, prev_tmp_shift ) )
1137 : {
1138 0 : FOR( p = start_band; p < k; p++ )
1139 : {
1140 0 : div_factor[p] = L_shr( div_factor[p], sub( prev_tmp_shift, tmp_shift ) ); // tmp_shift
1141 0 : move32();
1142 : }
1143 0 : prev_tmp_shift = tmp_shift;
1144 0 : move16();
1145 : }
1146 0 : ELSE IF( GT_16( tmp_shift, prev_tmp_shift ) )
1147 : {
1148 0 : div_factor[k] = L_shr( div_factor[k], sub( tmp_shift, prev_tmp_shift ) ); // prev_tmp_shift
1149 0 : move32();
1150 0 : tmp_shift = prev_tmp_shift;
1151 0 : move16();
1152 : }
1153 : }
1154 : }
1155 :
1156 1997300 : FOR( i = 0; i < pred_dim; i++ )
1157 : {
1158 7259775 : FOR( k = start_band; k < end_band; k++ )
1159 : {
1160 5761800 : ppPred_coeffs_re[i][k] = Mpy_32_32( cov_real[i + 1][0][k], div_factor[k] ); // Q30 + temp_shift - 31 => tmp_shift - 1
1161 5761800 : move32();
1162 :
1163 : // IVAS_CALCULATE_SQ_ABS_N( ppPred_coeffs_re[i][k], abs_value );
1164 5761800 : abs_value = Mpy_32_32( ppPred_coeffs_re[i][k], ppPred_coeffs_re[i][k] ); // Q = 2*tmp_shift - 2 - 31
1165 :
1166 5761800 : pPred_temp[k] = L_add( pPred_temp[k], abs_value ); // Q= 2*tmp_shift - 2 - 31
1167 5761800 : move32();
1168 : }
1169 : }
1170 499325 : *q_pred_coeffs = sub( tmp_shift, 1 );
1171 499325 : move16();
1172 :
1173 2419925 : FOR( k = start_band; k < end_band; k++ )
1174 : {
1175 1920600 : q_pred_temp = sub( 31, sub( shl( *q_pred_coeffs, 1 ), 31 ) );
1176 1920600 : pPred_temp[k] = Sqrt32( pPred_temp[k], &q_pred_temp ); // q=31-q_pred_temp
1177 1920600 : move32();
1178 :
1179 1920600 : IF( LT_16( q_pred_temp, 1 ) )
1180 : {
1181 1847713 : pPred_temp[k] = L_shr( pPred_temp[k], add( abs_s( q_pred_temp ), 1 ) ); // Q30
1182 1847713 : move32();
1183 1847713 : q_pred_temp = 1;
1184 1847713 : move16();
1185 : }
1186 72887 : ELSE IF( GT_16( q_pred_temp, 1 ) )
1187 : {
1188 1840 : pPred_temp[k] = L_shl( pPred_temp[k], sub( abs_s( q_pred_temp ), 1 ) ); // Q30
1189 1840 : move32();
1190 1840 : q_pred_temp = 1;
1191 1840 : move16();
1192 : }
1193 :
1194 1920600 : one_in_q = L_shl( 1, sub( 31, q_pred_temp ) ); /*Q=q_pred_temp*/
1195 :
1196 1920600 : IF( LT_32( one_in_q, pPred_temp[k] ) )
1197 : {
1198 5067 : div_factor[k] = pPred_temp[k]; /*Q=q_pred_temp*/
1199 5067 : move32();
1200 :
1201 5067 : div_factor[k] = L_deposit_l( BASOP_Util_Divide3232_Scale( one_in_q, div_factor[k], &s_div ) ); // q=15-s_div
1202 5067 : move32();
1203 5067 : IF( s_div < 0 )
1204 : {
1205 0 : div_shift = add( 15, s_div );
1206 0 : tmp_shift = Q30;
1207 0 : move16();
1208 : }
1209 : ELSE
1210 : {
1211 5067 : div_shift = 15;
1212 5067 : move16();
1213 5067 : tmp_shift = sub( Q30, s_div );
1214 : }
1215 5067 : div_factor[k] = L_shl( div_factor[k], div_shift ); // Q = tmp_shift
1216 5067 : move32();
1217 : }
1218 : ELSE
1219 : {
1220 1915533 : div_factor[k] = one_in_q; // q=31-q_pred_temp
1221 1915533 : move32();
1222 1915533 : tmp_shift = sub( 31, q_pred_temp );
1223 : }
1224 :
1225 1920600 : IF( LT_16( tmp_shift, prev_tmp_shift ) )
1226 : {
1227 500549 : FOR( p = start_band; p < k; p++ )
1228 : {
1229 672 : div_factor[p] = L_shr( div_factor[p], sub( prev_tmp_shift, tmp_shift ) ); // q=tmp_shift
1230 672 : move32();
1231 : }
1232 499877 : prev_tmp_shift = tmp_shift;
1233 499877 : move16();
1234 : }
1235 1420723 : ELSE IF( GT_16( tmp_shift, prev_tmp_shift ) )
1236 : {
1237 685 : div_factor[k] = L_shr( div_factor[k], sub( tmp_shift, prev_tmp_shift ) ); // q=prev_tmp_shift
1238 685 : move32();
1239 685 : tmp_shift = prev_tmp_shift;
1240 685 : move16();
1241 : }
1242 : }
1243 :
1244 1997300 : FOR( i = 0; i < pred_dim; i++ )
1245 : {
1246 7259775 : FOR( k = start_band; k < end_band; k++ )
1247 : {
1248 5761800 : ppPred_coeffs_re[i][k] = Mpy_32_32( ppPred_coeffs_re[i][k], div_factor[k] ); // Q = q_pred_coeffs + tmp_shift -31
1249 5761800 : move32();
1250 5761800 : ppDM_Fv_re[i][k] = 0;
1251 5761800 : move32();
1252 : }
1253 : }
1254 499325 : *q_pred_coeffs = sub( add( *q_pred_coeffs, tmp_shift ), 31 );
1255 499325 : *q_dm_fv_re = 0;
1256 499325 : move16();
1257 : }
1258 : ELSE
1259 : {
1260 : Word32 dm_alpha[IVAS_MAX_NUM_BANDS], dm_v_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS];
1261 120042 : Word32 real[IVAS_SPAR_MAX_CH - 1], dm_beta_re = 0, dm_g[IVAS_MAX_NUM_BANDS];
1262 : Word32 dm_f_local, dm_w, dm_y, DM_F[IVAS_MAX_NUM_BANDS];
1263 : Word32 num_f, den_f, passive_g /*, inv_den_f*/;
1264 : Word32 activew_quad_thresh, g_th_sq;
1265 : Word32 L_tmp1, L_tmp2;
1266 : Word16 L_tmp2_q;
1267 : Word16 dm_alpha_e, den_f_e, s_dm_f;
1268 120042 : prev_tmp_shift = 31;
1269 120042 : dm_alpha_e = 0;
1270 120042 : Word16 dm_beta_re_e = 0;
1271 120042 : move32();
1272 120042 : move16();
1273 120042 : move16();
1274 120042 : move16();
1275 :
1276 :
1277 120042 : IF( EQ_16( dyn_active_w_flag, 1 ) )
1278 : {
1279 0 : activew_quad_thresh = ONE_IN_Q29; // 1 q29
1280 0 : move32();
1281 : }
1282 : ELSE
1283 : {
1284 120042 : activew_quad_thresh = IVAS_LIN_ACTIVEW_QUAD_ACTIVEW_THRESH_Q29; // 3 q29
1285 120042 : move32();
1286 : }
1287 120042 : g_th_sq = Mpy_32_32( activew_quad_thresh, activew_quad_thresh ); // Q27
1288 :
1289 120042 : set32_fx( dm_alpha, 0, IVAS_MAX_NUM_BANDS );
1290 :
1291 480168 : FOR( i = 1; i < in_chans; i++ )
1292 : {
1293 1704690 : FOR( k = start_band; k < end_band; k++ )
1294 : {
1295 : // IVAS_CALCULATE_SQ_ABS_N( cov_real[i][0][k], abs_value );
1296 1344564 : abs_value = Mpy_32_32( cov_real[i][0][k], cov_real[i][0][k] ); // Q29
1297 1344564 : dm_alpha[k] = L_add( dm_alpha[k], abs_value ); // Q29
1298 1344564 : move32();
1299 : }
1300 : }
1301 :
1302 568230 : FOR( k = start_band; k < end_band; k++ )
1303 : {
1304 448188 : dm_alpha_e = 31 - Q29;
1305 448188 : dm_alpha[k] = Sqrt32( dm_alpha[k], &dm_alpha_e ); // q=31-dm_alpha_e
1306 448188 : move32();
1307 :
1308 448188 : div_factor[k] = L_max( dm_alpha[k], 1 ); // q=31-dm_alpha_e
1309 448188 : move32();
1310 :
1311 448188 : div_factor[k] = L_deposit_l( BASOP_Util_Divide3232_Scale( ONE_IN_Q31, div_factor[k], &s_div ) ); // q=15-(s_div+(0-dm_alpha_e))
1312 448188 : move32();
1313 448188 : IF( s_div < 0 )
1314 : {
1315 0 : div_shift = add( 15, sub( s_div, dm_alpha_e ) );
1316 0 : tmp_shift = Q30;
1317 0 : move16();
1318 : }
1319 : ELSE
1320 : {
1321 448188 : div_shift = 15;
1322 448188 : move16();
1323 448188 : tmp_shift = sub( Q30, sub( s_div, dm_alpha_e ) );
1324 : }
1325 448188 : div_factor[k] = L_shl( div_factor[k], div_shift ); // Q = tmp_shift
1326 448188 : move32();
1327 :
1328 448188 : IF( LT_16( tmp_shift, prev_tmp_shift ) )
1329 : {
1330 223935 : FOR( p = start_band; p < k; p++ )
1331 : {
1332 61946 : div_factor[p] = L_shr( div_factor[p], sub( prev_tmp_shift, tmp_shift ) ); // q=tmp_shift
1333 61946 : move32();
1334 : }
1335 161989 : prev_tmp_shift = tmp_shift;
1336 161989 : move16();
1337 : }
1338 286199 : ELSE IF( GT_16( tmp_shift, prev_tmp_shift ) )
1339 : {
1340 26760 : div_factor[k] = L_shr( div_factor[k], sub( tmp_shift, prev_tmp_shift ) ); // q=prev_tmp_shift
1341 26760 : move32();
1342 26760 : tmp_shift = prev_tmp_shift;
1343 26760 : move16();
1344 : }
1345 : }
1346 :
1347 480168 : FOR( i = 0; i < pred_dim; i++ )
1348 : {
1349 1704690 : FOR( k = start_band; k < end_band; k++ )
1350 : {
1351 1344564 : dm_v_re[i][k] = Mpy_32_32( cov_real[i + 1][0][k], div_factor[k] ); // Q30 + Qb - 31 = tmp_shift - 1
1352 1344564 : move32();
1353 : }
1354 : }
1355 :
1356 120042 : IF( dtx_vad == 0 )
1357 : {
1358 440 : dm_f_local = IVAS_ACTIVEW_DM_F_DTX_Q30; // q30
1359 440 : move32();
1360 : }
1361 : ELSE
1362 : {
1363 119602 : IF( active_w_vlbr )
1364 : {
1365 11258 : dm_f_local = IVAS_ACTIVEW_DM_F_VLBR_Q30; // q30
1366 11258 : move32();
1367 : }
1368 : ELSE
1369 : {
1370 108344 : dm_f_local = IVAS_ACTIVEW_DM_F_Q30; // q30
1371 108344 : move32();
1372 : }
1373 : }
1374 :
1375 568230 : FOR( b = start_band; b < end_band; b++ )
1376 : {
1377 448188 : set32_fx( real, 0, pred_dim );
1378 :
1379 1792752 : FOR( j = 0; j < pred_dim; j++ )
1380 : {
1381 5378256 : FOR( k = 1; k < in_chans; k++ )
1382 : {
1383 : Word32 re;
1384 :
1385 : // IVAS_RMULT_FLOAT( cov_real[j + 1][k][b], dm_v_re[k - 1][b], re );
1386 4033692 : re = Mpy_32_32( cov_real[j + 1][k][b], dm_v_re[k - 1][b] ); // Q30 + Q_div_factor - 1 - 31
1387 4033692 : real[j] = L_add( real[j], re ); // tmp_shift - 2
1388 4033692 : move32();
1389 : }
1390 : }
1391 448188 : dm_beta_re = 0;
1392 448188 : move32();
1393 1792752 : FOR( k = 0; k < pred_dim; k++ )
1394 : {
1395 : Word32 re;
1396 : // IVAS_RMULT_FLOAT( real[k], dm_v_re[k][b], re );
1397 1344564 : re = Mpy_32_32( real[k], dm_v_re[k][b] ); // Q = 2*tmp_shift - 3 - 31
1398 1344564 : dm_beta_re = L_add( dm_beta_re, re ); // Q = 2*tmp_shift - 3 - 31
1399 : }
1400 :
1401 448188 : dm_beta_re_e = sub( 31, ( sub( sub( shl( tmp_shift, 1 ), 3 ), 31 ) ) );
1402 448188 : dm_w = cov_real[0][0][b]; // Q30
1403 448188 : move32();
1404 448188 : den_f = L_max( dm_w, 1 ); // Q30
1405 448188 : passive_g = L_deposit_l( BASOP_Util_Divide3232_Scale( dm_alpha[b], den_f, &s_div ) ); // Q=15-(s_div+dm_alpha_e-1)
1406 :
1407 448188 : div_shift = add( ( sub( 15, ( sub( ( sub( 31, dm_alpha_e ) ), Q30 ) ) ) ), sub( s_div, 1 ) );
1408 448188 : passive_g = L_shl( passive_g, div_shift ); // Q = 29
1409 :
1410 448188 : IF( EQ_16( dyn_active_w_flag, 1 ) )
1411 : {
1412 0 : dm_alpha[b] = 0;
1413 0 : move32();
1414 0 : dm_w = 0;
1415 0 : move32();
1416 0 : FOR( i = 0; i < pred_dim; i++ )
1417 : {
1418 0 : dm_v_re[i][b] = 0;
1419 0 : move32();
1420 : }
1421 0 : IF( NE_16( sub( tmp_shift, 1 ), 31 ) )
1422 : {
1423 0 : dm_v_re[res_ind - 1][b] = L_shl( 1, sub( tmp_shift, 1 ) ); // Q=tmp_shift-1
1424 0 : move32();
1425 : }
1426 : ELSE
1427 : {
1428 0 : dm_v_re[res_ind - 1][b] = MAX_32; // Q=tmp_shift-1
1429 0 : move32();
1430 : }
1431 0 : passive_g = activew_quad_thresh; // q29
1432 0 : move32();
1433 : }
1434 :
1435 448188 : IF( LT_32( passive_g, activew_quad_thresh ) )
1436 : {
1437 : /*linear activeW*/
1438 448188 : dm_y = 0;
1439 448188 : move32();
1440 :
1441 1792752 : FOR( k = 1; k < in_chans; k++ )
1442 : {
1443 1344564 : dm_y = L_add( dm_y, L_shr( cov_real[k][k][b], 2 ) ); // Q28
1444 : }
1445 448188 : den_f = L_max( dm_y, 1 ); // Q28
1446 448188 : den_f = L_max( den_f, Mpy_32_32( w_norm_fac, dm_w ) ); // Q28
1447 :
1448 448188 : DM_F[b] = L_deposit_l( BASOP_Util_Divide3232_Scale( Mpy_32_32( dm_f_local, dm_alpha[b] ), den_f, &s_div ) ); // Q30 + 31 - dm_alpha_e - 31 + den_f_e - 31 => den_f_e - dm_alpha_e - 1
1449 448188 : move32();
1450 :
1451 448188 : div_shift = add( ( sub( 15, ( sub( ( sub( 30, dm_alpha_e ) ), 28 ) ) ) ), s_div );
1452 :
1453 448188 : DM_F[b] = L_shl( DM_F[b], div_shift ); // Q30
1454 448188 : move32();
1455 :
1456 448188 : DM_F[b] = L_min( ONE_IN_Q30, DM_F[b] ); // q30
1457 448188 : move32();
1458 :
1459 448188 : L_tmp1 = L_add( L_shr( dm_w, 1 ), Mpy_32_32( dm_alpha[b], DM_F[b] ) ); /* Q 29*/
1460 448188 : L_tmp2 = Mpy_32_32( Mpy_32_32( DM_F[b], DM_F[b] ), dm_beta_re ); // Q=(Q29-dm_beta_re_e)
1461 448188 : L_tmp2_q = add( 29, sub( shl( tmp_shift, 1 ), 65 ) ); // simplified equation for calculating Q of L_tmp2
1462 448188 : L_tmp2 = L_shl( L_tmp2, sub( 29, L_tmp2_q ) ); // Q29
1463 :
1464 448188 : den_f = L_add( L_tmp1, L_tmp2 ); // Q29
1465 448188 : den_f = L_max( den_f, 1 ); // Q29
1466 :
1467 448188 : den_f_e = 31 - 29;
1468 448188 : move16();
1469 448188 : L_tmp2 = Mpy_32_32( DM_F[b], dm_beta_re ); // Q=30-dm_beta_re_e
1470 448188 : L_tmp2_q = add( 30, sub( ( sub( shl( tmp_shift, 1 ), 34 ) ), 31 ) );
1471 448188 : L_tmp2 = L_shl( L_tmp2, ( sub( ( sub( 29, dm_alpha_e ) ), L_tmp2_q ) ) ); // Q=29
1472 448188 : L_tmp1 = L_shr( dm_alpha[b], ( sub( ( sub( 31, dm_alpha_e ) ), 29 ) ) ); // Q=29
1473 448188 : L_tmp1 = L_add( L_tmp1, L_tmp2 ); // Q29
1474 :
1475 448188 : dm_g[b] = L_deposit_l( BASOP_Util_Divide3232_Scale( L_tmp1, den_f, &s_div ) ); // Q29 + den_f_e - 31 + 15 - s_div
1476 448188 : move32();
1477 448188 : div_shift = add( sub( 15, ( sub( 29, sub( 31, den_f_e ) ) ) ), s_div );
1478 448188 : dm_g[b] = L_shl( dm_g[b], div_shift ); // Q30
1479 448188 : move32();
1480 : }
1481 : ELSE
1482 : {
1483 : Word32 sqrt_val;
1484 : Word16 val_e;
1485 : Word16 num_f_e;
1486 :
1487 : /* quadratic activeW */
1488 :
1489 0 : num_f = BASOP_Util_Add_Mant32Exp( dm_beta_re, dm_beta_re_e, L_negate( L_shl( Mpy_32_32( dm_alpha[b], activew_quad_thresh ), 1 ) ), add( dm_alpha_e, ( 31 - Q29 ) ), &num_f_e ); // Q=31-num_f_e
1490 :
1491 0 : sqrt_val = L_shl( Mpy_32_32( Mpy_32_32( dm_alpha[b], dm_alpha[b] ), g_th_sq ), 2 ); /*Q27*/
1492 0 : val_e = 4;
1493 0 : move16();
1494 :
1495 0 : sqrt_val = BASOP_Util_Add_Mant32Exp( sqrt_val, 4, Mpy_32_32( dm_beta_re, dm_beta_re ), 2 * dm_beta_re_e, &val_e ); // Q=31-val_e
1496 0 : sqrt_val = BASOP_Util_Add_Mant32Exp( sqrt_val, val_e, L_negate( L_shl( Mpy_32_32( Mpy_32_32( dm_beta_re, g_th_sq ), dm_w ), 2 ) ), add( dm_beta_re_e, 4 + 1 ), &val_e ); // Q=31-val_e
1497 : // val_e = norm_l( sqrt_val );
1498 0 : sqrt_val = Sqrt32( sqrt_val, &val_e ); // Q=31-val_e
1499 0 : IF( val_e < 0 )
1500 : {
1501 0 : sqrt_val = L_shr( sqrt_val, abs_s( val_e ) ); // Q31
1502 : }
1503 0 : ELSE IF( val_e > 0 )
1504 : {
1505 0 : sqrt_val = L_shl( sqrt_val, abs_s( val_e ) ); // Q31
1506 0 : val_e = 0;
1507 0 : move16();
1508 : }
1509 0 : num_f = BASOP_Util_Add_Mant32Exp( num_f, num_f_e, sqrt_val, 0, &num_f_e ); // Q=31-num_f_e
1510 :
1511 0 : den_f = L_shl( Mpy_32_32( dm_beta_re, g_th_sq ), 1 ); // Q=31-dm_beta_re_e+27-31=>-dm_beta_re_e+27
1512 0 : den_f_e = add( dm_beta_re_e, 4 );
1513 0 : den_f = L_max( den_f, 1 ); // Q=31-den_f_e
1514 0 : dm_g[b] = activew_quad_thresh; // Q29
1515 0 : move32();
1516 0 : DM_F[b] = BASOP_Util_Divide3232_Scale_newton( Mpy_32_32( dm_g[b], num_f ), den_f, &s_dm_f ); // s_dm_f+2+num_f_e-den_f_e
1517 0 : move32();
1518 0 : s_dm_f = add( s_dm_f, sub( add( 2, num_f_e ), den_f_e ) ); /*Resultant exp for DM_F s_dm_f +( 2 + num_f_e ) - den_f_e*/
1519 0 : div_shift = sub( s_dm_f, 1 );
1520 0 : DM_F[b] = L_shl( DM_F[b], div_shift ); // Q30
1521 0 : move32();
1522 : }
1523 : }
1524 :
1525 480168 : FOR( i = 0; i < pred_dim; i++ )
1526 : {
1527 1704690 : FOR( b = start_band; b < end_band; b++ )
1528 : {
1529 1344564 : ppPred_coeffs_re[i][b] = Mpy_32_32( dm_v_re[i][b], dm_g[b] ); // Q = tmp_shift - 1 + 30 - 31
1530 1344564 : move32();
1531 1344564 : ppDM_Fv_re[i][b] = Mpy_32_32( dm_v_re[i][b], DM_F[b] ); // Q = tmp_shift - 1 + 30 -31
1532 1344564 : move32();
1533 : }
1534 : }
1535 120042 : *q_pred_coeffs = sub( tmp_shift, 2 );
1536 120042 : move16();
1537 120042 : *q_dm_fv_re = sub( tmp_shift, 2 );
1538 120042 : move16();
1539 : }
1540 :
1541 619367 : return;
1542 : }
1543 :
1544 :
1545 : /*-----------------------------------------------------------------------------------------*
1546 : * Function ivas_get_Wscaling_factor()
1547 : *
1548 : * Calculation of scaling factor for post predicted W channel
1549 : *-----------------------------------------------------------------------------------------*/
1550 :
1551 :
1552 311060 : static void ivas_get_Wscaling_factor_enc_fx(
1553 : Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_cov_real*/
1554 : Word16 *q_cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],
1555 : Word32 pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_pred_coeffs_re*/
1556 : Word16 q_pred_coeffs_re,
1557 : Word32 ***mixer_mat, /*q_mixer_mat*/
1558 : Word16 q_mixer_mat,
1559 : const Word16 start_band,
1560 : const Word16 end_band,
1561 : const Word16 dtx_vad,
1562 : const Word16 num_ch,
1563 : const Word16 *pNum_dmx,
1564 : const Word16 bands_bw,
1565 : const Word16 active_w,
1566 : const Word16 active_w_vlbr,
1567 : Word32 *pWscale, /*q_pWscale*/
1568 : Word16 *q_pWscale,
1569 : const Word16 dyn_active_w_flag )
1570 : {
1571 : Word16 b, ch, q_tmp, q_postpred_cov_re;
1572 : Word32 dm_f_local, abs_val;
1573 : Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
1574 :
1575 311060 : q_postpred_cov_re = 0;
1576 311060 : move16();
1577 :
1578 3732720 : FOR( ch = 0; ch < IVAS_SPAR_MAX_CH; ch++ )
1579 : {
1580 3421660 : set32_fx( postpred_cov_re[ch], 0, IVAS_SPAR_MAX_CH );
1581 : }
1582 :
1583 311060 : IF( dtx_vad == 0 )
1584 : {
1585 3210 : dm_f_local = IVAS_ACTIVEW_DM_F_SCALE_DTX_FX; // Q31
1586 3210 : move32();
1587 : }
1588 307850 : ELSE IF( active_w_vlbr != 0 )
1589 : {
1590 26738 : dm_f_local = IVAS_ACTIVEW_DM_F_SCALE_VLBR_FX; // Q31
1591 26738 : move32();
1592 : }
1593 : ELSE
1594 : {
1595 281112 : dm_f_local = IVAS_ACTIVEW_DM_F_SCALE_FX; // Q31
1596 281112 : move32();
1597 : }
1598 :
1599 2272754 : FOR( b = start_band; b < end_band; b++ )
1600 : {
1601 1961694 : pWscale[b] = ONE_IN_Q31;
1602 1961694 : move32();
1603 1961694 : q_pWscale[b] = Q31;
1604 1961694 : move16();
1605 :
1606 1961694 : test();
1607 1961694 : IF( EQ_16( active_w, 1 ) && ( dyn_active_w_flag == 0 ) )
1608 : {
1609 : Word16 shift, guard_bits, q_Gw_sq, q_g_sq, q_min, tmp_exp;
1610 : Word32 Gw_sq, g_sq, tmp;
1611 :
1612 472484 : g_sq = 0;
1613 472484 : move32();
1614 :
1615 472484 : IF( NE_16( num_ch, pNum_dmx[b * bands_bw] ) )
1616 : {
1617 472484 : ivas_calc_post_pred_per_band_enc_fx( cov_real, q_cov_real, mixer_mat, q_mixer_mat, num_ch, b, postpred_cov_re, &q_postpred_cov_re );
1618 : }
1619 :
1620 472484 : tmp = L_shl_sat( IVAS_FIX_EPS_Q40, sub( q_postpred_cov_re, 40 ) );
1621 :
1622 472484 : IF( LE_32( postpred_cov_re[0][0], tmp ) )
1623 : {
1624 180 : Gw_sq = Mpy_32_32( cov_real[0][0][b], 1250000000 ); /*1/1e-10 = 1250000000 Q(-4)*/
1625 180 : q_Gw_sq = add( q_cov_real[0][0][b], -4 - 31 );
1626 : }
1627 : ELSE
1628 : {
1629 472304 : Gw_sq = BASOP_Util_Divide3232_Scale( cov_real[0][0][b], postpred_cov_re[0][0], &tmp_exp ); // 15-(tmp_exp-(q_cov_real[0][0][b]- q_postpred_cov_re))
1630 472304 : q_Gw_sq = add( sub( 15, tmp_exp ), sub( q_cov_real[0][0][b], q_postpred_cov_re ) );
1631 : }
1632 :
1633 472484 : shift = MAX16B;
1634 472484 : move16();
1635 :
1636 1889936 : FOR( ch = 0; ch < ( num_ch - 1 ); ch++ )
1637 : {
1638 1417452 : IF( pred_coeffs_re[ch][b] != 0 )
1639 : {
1640 1312449 : shift = s_min( shift, norm_l( pred_coeffs_re[ch][b] ) );
1641 : }
1642 : }
1643 472484 : guard_bits = find_guarded_bits_fx( num_ch );
1644 472484 : if ( EQ_16( shift, MAX16B ) )
1645 : {
1646 180 : shift = 0;
1647 180 : move16();
1648 : }
1649 1889936 : FOR( ch = 0; ch < ( num_ch - 1 ); ch++ )
1650 : {
1651 1417452 : abs_val = L_shr( Mpy_32_32( L_shl( pred_coeffs_re[ch][b], shift ), L_shl( pred_coeffs_re[ch][b], shift ) ), guard_bits ); // q=2*q_pred_coeffs_re-guard_bits-31
1652 1417452 : g_sq = L_add( g_sq, abs_val ); // q=2*q_pred_coeffs_re-guard_bits-31
1653 : }
1654 472484 : q_g_sq = sub( shl( add( q_pred_coeffs_re, shift ), 1 ), add( 31, guard_bits ) );
1655 :
1656 472484 : tmp = Mpy_32_32( ONE_IN_Q30 /*4 in Q28*/, Mpy_32_32( dm_f_local, g_sq ) ); // q_g_sq+28-31
1657 472484 : q_tmp = sub( q_g_sq, 3 );
1658 :
1659 472484 : q_min = s_min( q_Gw_sq, q_tmp );
1660 472484 : tmp = L_shr( tmp, sub( q_tmp, q_min ) ); // Q=q_min
1661 472484 : tmp = L_add( L_shr( Gw_sq, sub( q_Gw_sq, q_min ) ), tmp ); // Q=q_min
1662 :
1663 472484 : tmp_exp = sub( 31, q_min );
1664 472484 : tmp = Sqrt32( tmp, &tmp_exp ); // q=31-tmp_exp
1665 472484 : q_tmp = sub( 31, tmp_exp );
1666 :
1667 472484 : tmp_exp = sub( 31, q_Gw_sq );
1668 472484 : Gw_sq = Sqrt32( Gw_sq, &tmp_exp ); // q=31-tmp_exp
1669 472484 : q_Gw_sq = sub( 31, tmp_exp );
1670 :
1671 472484 : q_min = s_min( q_Gw_sq, q_tmp );
1672 472484 : Gw_sq = L_shr( Gw_sq, sub( q_Gw_sq, q_min ) ); // q=q_min
1673 472484 : q_Gw_sq = q_min;
1674 472484 : move16();
1675 :
1676 472484 : tmp = L_shr( tmp, sub( q_tmp, q_min ) ); // q=q_min
1677 :
1678 472484 : pWscale[b] = L_add( Mpy_32_32( Gw_sq, ONE_IN_Q30 /* 0.5 in Q31*/ ), Mpy_32_32( tmp, ONE_IN_Q30 /* 0.5 in Q31*/ ) ); // q=q_Gw_sq
1679 472484 : move32();
1680 472484 : q_pWscale[b] = q_Gw_sq;
1681 472484 : move16();
1682 : }
1683 : }
1684 :
1685 311060 : return;
1686 : }
1687 :
1688 619367 : static void ivas_get_Wscaling_factor_fx(
1689 : Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_cov_real*/
1690 : Word16 q_cov_real,
1691 : Word32 pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_pred_coeffs_re*/
1692 : Word16 q_pred_coeffs_re,
1693 : Word32 ***mixer_mat, /*q_mixer_mat*/
1694 : Word16 q_mixer_mat,
1695 : const Word16 start_band,
1696 : const Word16 end_band,
1697 : const Word16 dtx_vad,
1698 : const Word16 num_ch,
1699 : const Word16 *pNum_dmx,
1700 : const Word16 bands_bw,
1701 : const Word16 active_w,
1702 : const Word16 active_w_vlbr,
1703 : Word32 *pWscale, /*q_pWscale*/
1704 : Word16 *q_pWscale,
1705 : const Word16 dyn_active_w_flag )
1706 : {
1707 : Word16 b, ch, q_tmp, q_postpred_cov_re;
1708 : Word32 dm_f_local, abs_val;
1709 : Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
1710 :
1711 619367 : q_postpred_cov_re = 0;
1712 619367 : move16();
1713 :
1714 7432404 : FOR( ch = 0; ch < IVAS_SPAR_MAX_CH; ch++ )
1715 : {
1716 6813037 : set32_fx( postpred_cov_re[ch], 0, IVAS_SPAR_MAX_CH );
1717 : }
1718 :
1719 619367 : IF( dtx_vad == 0 )
1720 : {
1721 2395 : dm_f_local = IVAS_ACTIVEW_DM_F_SCALE_DTX_FX; // Q31
1722 2395 : move32();
1723 : }
1724 616972 : ELSE IF( active_w_vlbr != 0 )
1725 : {
1726 11258 : dm_f_local = IVAS_ACTIVEW_DM_F_SCALE_VLBR_FX; // Q31
1727 11258 : move32();
1728 : }
1729 : ELSE
1730 : {
1731 605714 : dm_f_local = IVAS_ACTIVEW_DM_F_SCALE_FX; // Q31
1732 605714 : move32();
1733 : }
1734 :
1735 2988155 : FOR( b = start_band; b < end_band; b++ )
1736 : {
1737 2368788 : pWscale[b] = 1;
1738 2368788 : move32();
1739 2368788 : q_pWscale[b] = 0;
1740 2368788 : move16();
1741 :
1742 2368788 : test();
1743 2368788 : IF( EQ_16( active_w, 1 ) && ( dyn_active_w_flag == 0 ) )
1744 : {
1745 : Word16 guard_bits, q_Gw_sq, q_g_sq, q_min, tmp_exp;
1746 : Word32 Gw_sq, g_sq, tmp;
1747 :
1748 448188 : g_sq = 0;
1749 448188 : move32();
1750 :
1751 448188 : IF( NE_16( num_ch, pNum_dmx[b * bands_bw] ) )
1752 : {
1753 448188 : ivas_calc_post_pred_per_band_fx( cov_real, q_cov_real, mixer_mat, q_mixer_mat, num_ch, b, postpred_cov_re, &q_postpred_cov_re );
1754 : }
1755 :
1756 448188 : Gw_sq = BASOP_Util_Divide3232_Scale( cov_real[0][0][b], L_max( postpred_cov_re[0][0], IVAS_FIX_EPS ), &tmp_exp ); /*15-(tmp_exp-(q_cov_real-q_postpred_cov_re))*/
1757 448188 : q_Gw_sq = add( sub( 15, tmp_exp ), sub( q_cov_real, q_postpred_cov_re ) );
1758 :
1759 448188 : guard_bits = find_guarded_bits_fx( num_ch );
1760 :
1761 1792752 : FOR( ch = 0; ch < sub( num_ch, 1 ); ch++ )
1762 : {
1763 1344564 : abs_val = L_shr( Mpy_32_32( pred_coeffs_re[ch][b], pred_coeffs_re[ch][b] ), guard_bits ); /*q=2*q_pred_coeffs_re-guard_bits-31*/
1764 1344564 : g_sq = L_add( g_sq, abs_val ); /*q=2*q_pred_coeffs_re-guard_bits-31*/
1765 : }
1766 448188 : q_g_sq = sub( add( q_pred_coeffs_re, q_pred_coeffs_re ), add( 31, guard_bits ) );
1767 :
1768 448188 : tmp = Mpy_32_32( ONE_IN_Q30 /*4 in Q28*/, Mpy_32_32( dm_f_local, g_sq ) ); /*q=q_g_sq-3*/
1769 448188 : q_tmp = sub( q_g_sq, 3 );
1770 :
1771 448188 : q_min = s_min( q_Gw_sq, q_tmp );
1772 448188 : tmp = L_shr( tmp, sub( q_tmp, q_min ) ); // q=q_min
1773 448188 : tmp = L_add( L_shr( Gw_sq, sub( q_Gw_sq, q_min ) ), tmp ); // q=q_min
1774 :
1775 448188 : tmp_exp = sub( 31, q_min );
1776 448188 : tmp = Sqrt32( tmp, &tmp_exp ); // q=31-tmp_exp
1777 448188 : q_tmp = sub( 31, tmp_exp );
1778 :
1779 448188 : tmp_exp = sub( 31, q_Gw_sq );
1780 448188 : Gw_sq = Sqrt32( Gw_sq, &tmp_exp ); // q=31-tmp_exp
1781 448188 : q_Gw_sq = sub( 31, tmp_exp );
1782 :
1783 448188 : q_min = s_min( q_Gw_sq, q_tmp );
1784 448188 : Gw_sq = L_shr( Gw_sq, sub( q_Gw_sq, q_min ) ); // q=q_min
1785 448188 : q_Gw_sq = q_min;
1786 448188 : move16();
1787 :
1788 448188 : tmp = L_shr( tmp, sub( q_tmp, q_min ) ); // q=q_min
1789 :
1790 448188 : pWscale[b] = L_add( L_shr( Gw_sq, 1 /* Gw_sq * 0.5 */ ), L_shr( tmp, 1 /* tmp * 0.5 */ ) ); // q=q_Gw_sq
1791 448188 : move32();
1792 448188 : q_pWscale[b] = q_Gw_sq;
1793 448188 : move16();
1794 : }
1795 : }
1796 :
1797 619367 : return;
1798 : }
1799 :
1800 :
1801 : /*-----------------------------------------------------------------------------------------*
1802 : * Function ivas_create_fullr_dmx_mat()
1803 : *
1804 : * Calculation of downmix matrix
1805 : *-----------------------------------------------------------------------------------------*/
1806 :
1807 :
1808 1092048 : void ivas_create_fullr_dmx_mat_fx(
1809 : Word32 pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_pred_coeffs_re*/
1810 : Word16 q_pred_coeffs_re,
1811 : Word32 dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_dm_fv_re*/
1812 : Word16 q_dm_fv_re,
1813 : Word32 ***mixer_mat, /*q_mixer_mat*/
1814 : Word16 *q_mixer_mat,
1815 : const Word16 in_chans,
1816 : const Word16 start_band,
1817 : const Word16 end_band,
1818 : const Word16 active_w,
1819 : ivas_spar_md_com_cfg *hMdCfg )
1820 : {
1821 : Word16 i, j, k, b;
1822 : const Word16 *order;
1823 : Word32 max_val_tmp_p2;
1824 : Word32 tmp_p1_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS];
1825 : Word32 tmp_p2_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS];
1826 : Word32 down_mix_mat1_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS];
1827 : Word16 remix_unmix_order;
1828 : Word16 nbands;
1829 :
1830 1092048 : max_val_tmp_p2 = 0;
1831 1092048 : move32();
1832 :
1833 1092048 : nbands = sub( end_band, start_band );
1834 1092048 : remix_unmix_order = hMdCfg->remix_unmix_order;
1835 1092048 : move16();
1836 :
1837 1092048 : order = remix_order_set[remix_unmix_order];
1838 1092048 : move16();
1839 :
1840 5664640 : FOR( i = 0; i < in_chans; i++ )
1841 : {
1842 24798280 : FOR( j = 0; j < in_chans; j++ )
1843 : {
1844 20225688 : set32_fx( &tmp_p1_re[i][j][start_band], 0, nbands );
1845 20225688 : set32_fx( &tmp_p2_re[i][j][start_band], 0, nbands );
1846 20225688 : set32_fx( &down_mix_mat1_re[i][j][start_band], 0, nbands );
1847 : }
1848 : }
1849 :
1850 5664640 : FOR( j = 0; j < in_chans; j++ )
1851 : {
1852 29613408 : FOR( b = start_band; b < end_band; b++ )
1853 : {
1854 25040816 : tmp_p2_re[j][j][b] = L_shl( 1, q_pred_coeffs_re ); // q=q_pred_coeffs_re
1855 25040816 : move32();
1856 : }
1857 : }
1858 1092048 : max_val_tmp_p2 = L_shl( 1, q_pred_coeffs_re ); // q=q_pred_coeffs_re
1859 :
1860 4572592 : FOR( j = 1; j < in_chans; j++ )
1861 : {
1862 22874356 : FOR( b = start_band; b < end_band; b++ )
1863 : {
1864 19393812 : tmp_p2_re[j][0][b] = L_negate( pred_coeffs_re[j - 1][b] ); // q=q_pred_coeffs_re
1865 19393812 : move32();
1866 19393812 : max_val_tmp_p2 = L_max( max_val_tmp_p2, L_abs( tmp_p2_re[j][0][b] ) ); // q=q_pred_coeffs_re
1867 : }
1868 : }
1869 :
1870 1092048 : IF( EQ_16( active_w, 1 ) )
1871 : {
1872 : Word16 guard_bits;
1873 : Word32 max_val, tmp_re;
1874 :
1875 253655 : max_val = 0;
1876 253655 : move32();
1877 :
1878 1268275 : FOR( j = 0; j < in_chans; j++ )
1879 : {
1880 5900748 : FOR( b = start_band; b < end_band; b++ )
1881 : {
1882 4886128 : tmp_p1_re[j][j][b] = L_shl( 1, q_dm_fv_re ); // q=q_dm_fv_re
1883 4886128 : move32();
1884 : }
1885 : }
1886 253655 : max_val = L_shl( 1, q_dm_fv_re ); // q=q_dm_fv_re
1887 :
1888 1014620 : FOR( j = 1; j < in_chans; j++ )
1889 : {
1890 4425561 : FOR( b = start_band; b < end_band; b++ )
1891 : {
1892 3664596 : tmp_p1_re[0][j][b] = dm_fv_re[j - 1][b]; // q=q_dm_fv_re
1893 3664596 : move32();
1894 3664596 : max_val = L_max( max_val, L_abs( tmp_p1_re[0][j][b] ) ); // q=q_dm_fv_re
1895 : }
1896 : }
1897 :
1898 253655 : guard_bits = add( norm_l( max_val ), norm_l( max_val_tmp_p2 ) );
1899 253655 : guard_bits = s_max( sub( find_guarded_bits_fx( sub( end_band, start_band ) ), guard_bits ), 0 );
1900 : /* 4x4 mult */
1901 1268275 : FOR( i = 0; i < in_chans; i++ )
1902 : {
1903 5073100 : FOR( j = 0; j < in_chans; j++ )
1904 : {
1905 20292400 : FOR( k = 0; k < in_chans; k++ )
1906 : {
1907 94411968 : FOR( b = start_band; b < end_band; b++ )
1908 : {
1909 78178048 : tmp_re = L_shr( Mpy_32_32( tmp_p2_re[i][k][b], tmp_p1_re[k][j][b] ), guard_bits ); // q= q_dm_fv_re+ q_pred_coeffs_re-31-guard_bits
1910 78178048 : down_mix_mat1_re[i][j][b] = L_add( down_mix_mat1_re[i][j][b], tmp_re ); // q= q_dm_fv_re+ q_pred_coeffs_re-31-guard_bits
1911 78178048 : move32();
1912 : }
1913 : }
1914 : }
1915 : }
1916 253655 : *q_mixer_mat = sub( add( q_dm_fv_re, q_pred_coeffs_re ), add( 31, guard_bits ) );
1917 253655 : move16();
1918 : }
1919 : ELSE
1920 : {
1921 4396365 : FOR( j = 0; j < in_chans; j++ )
1922 : {
1923 19725180 : FOR( k = 0; k < in_chans; k++ )
1924 : {
1925 120009800 : FOR( b = start_band; b < end_band; b++ )
1926 : {
1927 103842592 : down_mix_mat1_re[j][k][b] = tmp_p2_re[j][k][b]; // q=q_pred_coeffs_re
1928 103842592 : move32();
1929 : }
1930 : }
1931 : }
1932 838393 : *q_mixer_mat = q_pred_coeffs_re;
1933 838393 : move16();
1934 : }
1935 :
1936 1092048 : IF( NE_16( remix_unmix_order, 3 ) )
1937 : {
1938 1092048 : ivas_reorder_array_fx( down_mix_mat1_re, in_chans, order, mixer_mat, start_band, end_band );
1939 : }
1940 :
1941 1092048 : return;
1942 : }
1943 :
1944 :
1945 : /*-----------------------------------------------------------------------------------------*
1946 : * Function ivas_reorder_array()
1947 : *
1948 : * reorders the input matrix based on order
1949 : *-----------------------------------------------------------------------------------------*/
1950 :
1951 1092048 : static void ivas_reorder_array_fx(
1952 : Word32 in_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS], /*qx*/
1953 : const Word16 in_chans,
1954 : const Word16 order[IVAS_SPAR_MAX_CH],
1955 : Word32 ***mixer_mat, /*qx*/
1956 : const Word16 start_band,
1957 : const Word16 end_band )
1958 : {
1959 : Word16 i, j, b, idx;
1960 :
1961 5664640 : FOR( i = 0; i < in_chans; i++ )
1962 : {
1963 4572592 : idx = order[i];
1964 4572592 : move16();
1965 :
1966 24798280 : FOR( j = 0; j < in_chans; j++ )
1967 : {
1968 143612792 : FOR( b = start_band; b < end_band; b++ )
1969 : {
1970 123387104 : mixer_mat[i][j][b] = in_re[idx][j][b]; /*qx*/
1971 123387104 : move32();
1972 : }
1973 : }
1974 : }
1975 :
1976 1092048 : return;
1977 : }
1978 :
1979 : /*-----------------------------------------------------------------------------------------*
1980 : * Function ivas_calc_post_pred_per_band()
1981 : *
1982 : * Calculate post pred mat per band
1983 : *-----------------------------------------------------------------------------------------*/
1984 :
1985 :
1986 2968440 : static void ivas_calc_post_pred_per_band_enc_fx(
1987 : Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_cov_real*/
1988 : Word16 *q_cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],
1989 : Word32 ***mixer_mat, /*q_mixer_mat*/
1990 : Word16 q_mixer_mat,
1991 : const Word16 num_ch,
1992 : const Word16 band_idx,
1993 : Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_postpred_cov_re*/
1994 : Word16 *q_postpred_cov_re )
1995 : {
1996 : Word16 i, j, k;
1997 : Word16 max_val;
1998 : Word16 temp;
1999 : Word32 temp_add;
2000 : Word16 e_postpred_cov_re_buf[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
2001 : Word32 temp_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
2002 : Word16 temp_mat_e[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
2003 : Word32 tmp_re;
2004 : Word16 tmp_q;
2005 : Word16 tmp_e;
2006 :
2007 :
2008 2968440 : max_val = MIN16B;
2009 2968440 : move16();
2010 2968440 : temp = sub( 62, q_mixer_mat );
2011 :
2012 : /* num_ch x num_ch mult */
2013 17295000 : FOR( i = 0; i < num_ch; i++ )
2014 : {
2015 94856640 : FOR( j = 0; j < num_ch; j++ )
2016 : {
2017 80530080 : temp_add = 0;
2018 80530080 : move32();
2019 80530080 : temp_mat_e[i][j] = 0;
2020 80530080 : move16();
2021 :
2022 630216960 : FOR( k = 0; k < num_ch; k++ )
2023 : {
2024 549686880 : tmp_re = Mpy_32_32( cov_real[i][k][band_idx], mixer_mat[j][k][band_idx] );
2025 549686880 : tmp_e = sub( temp, q_cov_real[i][k][band_idx] );
2026 549686880 : IF( tmp_re )
2027 : {
2028 156325089 : temp_add = BASOP_Util_Add_Mant32Exp( temp_add, temp_mat_e[i][j], tmp_re, tmp_e, &temp_mat_e[i][j] );
2029 : }
2030 : }
2031 80530080 : temp_mat[i][j] = temp_add;
2032 80530080 : move32();
2033 : }
2034 : }
2035 :
2036 2968440 : tmp_e = sub( Q31, q_mixer_mat );
2037 : /* num_ch x num_ch mult */
2038 17295000 : FOR( i = 0; i < num_ch; i++ )
2039 : {
2040 61754880 : FOR( j = i; j < num_ch; j++ )
2041 : {
2042 47428320 : temp_add = 0;
2043 47428320 : move32();
2044 47428320 : e_postpred_cov_re_buf[i][j] = sub( 31, *q_postpred_cov_re );
2045 47428320 : move16();
2046 362536800 : FOR( k = 0; k < num_ch; k++ )
2047 : {
2048 315108480 : tmp_re = Mpy_32_32( mixer_mat[i][k][band_idx], temp_mat[k][j] );
2049 315108480 : tmp_q = add( tmp_e, temp_mat_e[k][j] );
2050 315108480 : IF( tmp_re )
2051 : {
2052 91017406 : temp_add = BASOP_Util_Add_Mant32Exp( temp_add, e_postpred_cov_re_buf[i][j], tmp_re, tmp_q, &e_postpred_cov_re_buf[i][j] );
2053 : }
2054 : }
2055 47428320 : if ( temp_add )
2056 : {
2057 44259951 : max_val = s_max( max_val, e_postpred_cov_re_buf[i][j] );
2058 : }
2059 47428320 : postpred_cov_re[i][j] = temp_add;
2060 47428320 : move32();
2061 : }
2062 : }
2063 :
2064 : /*Changing Q of postpred_cov_re to min_val*/
2065 17295000 : FOR( i = 0; i < num_ch; i++ )
2066 : {
2067 61754880 : FOR( j = i; j < num_ch; j++ )
2068 : {
2069 47428320 : IF( postpred_cov_re[i][j] )
2070 : {
2071 44259951 : postpred_cov_re[i][j] = L_shr( postpred_cov_re[i][j], sub( max_val, e_postpred_cov_re_buf[i][j] ) );
2072 44259951 : move32();
2073 : }
2074 : }
2075 : }
2076 :
2077 :
2078 17295000 : FOR( i = 0; i < num_ch; i++ )
2079 : {
2080 47428320 : FOR( j = 0; j < i; j++ )
2081 : {
2082 33101760 : postpred_cov_re[i][j] = postpred_cov_re[j][i]; //*q_postpred_cov_re
2083 33101760 : move32();
2084 : }
2085 : }
2086 2968440 : if ( EQ_16( max_val, MIN16B ) )
2087 : {
2088 6720 : max_val = 0;
2089 6720 : move16();
2090 : }
2091 2968440 : *q_postpred_cov_re = sub( Q31, max_val );
2092 2968440 : move16();
2093 :
2094 2968440 : return;
2095 : }
2096 :
2097 2257516 : static void ivas_calc_post_pred_per_band_fx(
2098 : Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_cov_real*/
2099 : Word16 q_cov_real,
2100 : Word32 ***mixer_mat, /*q_mixer_mat*/
2101 : Word16 q_mixer_mat,
2102 : const Word16 num_ch,
2103 : const Word16 band_idx,
2104 : Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_postpred_cov_re*/
2105 : Word16 *q_postpred_cov_re )
2106 : {
2107 : Word16 i, j, k, guard_bits, tmp, q_temp_mat;
2108 : Word32 dmx_mat_conj[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
2109 : Word32 temp_mat[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
2110 : Word32 max_val;
2111 : Word64 tmp_re;
2112 :
2113 11287580 : FOR( i = 0; i < num_ch; i++ )
2114 : {
2115 45150320 : FOR( j = 0; j < num_ch; j++ )
2116 : {
2117 36120256 : dmx_mat_conj[i][j] = mixer_mat[j][i][band_idx]; /*q_mixer_mat*/
2118 36120256 : move32();
2119 : }
2120 : }
2121 :
2122 2257516 : guard_bits = find_guarded_bits_fx( num_ch );
2123 :
2124 11287580 : FOR( i = 0; i < num_ch; i++ )
2125 : {
2126 9030064 : set32_fx( temp_mat[i], 0, num_ch );
2127 9030064 : set32_fx( postpred_cov_re[i], 0, num_ch );
2128 : }
2129 :
2130 2257516 : max_val = 1;
2131 2257516 : move32();
2132 : /* num_ch x num_ch mult */
2133 11287580 : FOR( i = 0; i < num_ch; i++ )
2134 : {
2135 45150320 : FOR( j = 0; j < num_ch; j++ )
2136 : {
2137 36120256 : tmp_re = 0;
2138 36120256 : move64();
2139 180601280 : FOR( k = 0; k < num_ch; k++ )
2140 : {
2141 144481024 : tmp_re = W_add( tmp_re, W_shr( W_mult0_32_32( cov_real[i][k][band_idx], dmx_mat_conj[k][j] ), guard_bits ) ); /*q_cov_real+q_mixer_mat-guard_bits*/
2142 : }
2143 36120256 : if ( LT_64( W_abs( tmp_re ), L_shl( IVAS_FIX_EPS, guard_bits ) ) )
2144 : {
2145 6096023 : tmp_re = 0;
2146 6096023 : move64();
2147 : }
2148 36120256 : temp_mat[i][j] = W_extract_l( W_shr( tmp_re, q_mixer_mat ) ); // Q = (q_cov_real - guard_bits)
2149 36120256 : move32();
2150 36120256 : max_val = L_max( max_val, L_abs( temp_mat[i][j] ) ); // Q = (q_cov_real - guard_bits)
2151 : }
2152 : }
2153 2257516 : q_temp_mat = sub( q_cov_real, guard_bits );
2154 :
2155 2257516 : guard_bits = find_guarded_bits_fx( num_ch );
2156 :
2157 2257516 : tmp = norm_l( max_val );
2158 2257516 : IF( LT_16( tmp, guard_bits ) )
2159 : {
2160 12945 : guard_bits = sub( guard_bits, tmp );
2161 : }
2162 : ELSE
2163 : {
2164 2244571 : guard_bits = 0;
2165 2244571 : move16();
2166 : }
2167 :
2168 : /* num_ch x num_ch mult */
2169 11287580 : FOR( i = 0; i < num_ch; i++ )
2170 : {
2171 31605224 : FOR( j = i; j < num_ch; j++ )
2172 : {
2173 22575160 : tmp_re = 0;
2174 22575160 : move64();
2175 112875800 : FOR( k = 0; k < num_ch; k++ )
2176 : {
2177 90300640 : tmp_re = W_add( tmp_re, W_shr( W_mult0_32_32( mixer_mat[i][k][band_idx], temp_mat[k][j] ), guard_bits ) ); /*q_mixer_mat+q_temp_mat-guard_bits*/
2178 : }
2179 :
2180 22575160 : if ( LT_64( W_abs( tmp_re ), L_shl( IVAS_FIX_EPS, guard_bits ) ) )
2181 : {
2182 5978454 : tmp_re = 0;
2183 5978454 : move64();
2184 : }
2185 :
2186 22575160 : postpred_cov_re[i][j] = W_extract_l( W_shr( tmp_re, q_mixer_mat ) ); /*q_temp_mat-guard_bits*/
2187 22575160 : move32();
2188 : }
2189 : }
2190 :
2191 2257516 : *q_postpred_cov_re = sub( q_temp_mat, guard_bits );
2192 2257516 : move16();
2193 :
2194 11287580 : FOR( i = 0; i < num_ch; i++ )
2195 : {
2196 22575160 : FOR( j = 0; j < i; j++ )
2197 : {
2198 13545096 : postpred_cov_re[i][j] = postpred_cov_re[j][i]; /* *q_postpred_cov_re */
2199 13545096 : move32();
2200 : }
2201 : }
2202 :
2203 2257516 : return;
2204 : }
2205 :
2206 :
2207 : /*-----------------------------------------------------------------------------------------*
2208 : * Function ivas_calc_p_coeffs_per_band()
2209 : *
2210 : * Calculate P coeffs per band
2211 : *-----------------------------------------------------------------------------------------*/
2212 :
2213 1633334 : static void ivas_calc_p_coeffs_per_band_enc_fx(
2214 : ivas_spar_md_t *pSparMd,
2215 : const Word16 i_ts,
2216 : Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_postpred_cov_re*/
2217 : Word16 q_postpred_cov_re,
2218 : const Word16 num_ch,
2219 : const Word16 dtx_vad,
2220 : const Word16 num_dmx,
2221 : const Word16 band_idx )
2222 : {
2223 : Word16 i, j, k;
2224 : Word16 m;
2225 : Word32 factor;
2226 : Word32 recon_uu_re[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS][IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS];
2227 : Word16 q_recon_uu_re[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS][IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS];
2228 : Word64 trace, W_tmp;
2229 : Word16 q_factor, q_tmp, q_tmp1;
2230 : Word32 tmp;
2231 : Word32 p_norm_scaling;
2232 : Word16 q_cov_uu_re, q_cov_dd_re;
2233 : Word32 cov_dd_re[IVAS_SPAR_MAX_CH - 1][IVAS_SPAR_MAX_CH - 1];
2234 : Word32 cov_uu_re[IVAS_SPAR_MAX_CH - 1][IVAS_SPAR_MAX_CH - 1];
2235 : Word16 q_cov_uu_re_per_value[IVAS_SPAR_MAX_CH - 1][IVAS_SPAR_MAX_CH - 1];
2236 : Word16 b_ts_idx;
2237 :
2238 1633334 : b_ts_idx = add( band_idx, imult1616( i_ts, IVAS_MAX_NUM_BANDS ) );
2239 :
2240 1633334 : IF( NE_16( num_dmx, num_ch ) )
2241 : {
2242 1633334 : set32_fx( pSparMd->band_coeffs[b_ts_idx].P_re_fx, 0, IVAS_SPAR_MAX_CH - 1 );
2243 1633334 : pSparMd->band_coeffs[b_ts_idx].q_P_re_fx = 0;
2244 1633334 : move16();
2245 13066672 : FOR( i = 0; i < sub( IVAS_SPAR_MAX_CH, IVAS_SPAR_MAX_DMX_CHS ); i++ )
2246 : {
2247 11433338 : set32_fx( recon_uu_re[i], 0, sub( IVAS_SPAR_MAX_CH, IVAS_SPAR_MAX_DMX_CHS ) );
2248 : }
2249 :
2250 5665058 : FOR( i = num_dmx; i < num_ch; i++ )
2251 : {
2252 17361276 : FOR( j = num_dmx; j < num_ch; j++ )
2253 : {
2254 13329552 : cov_uu_re[i - num_dmx][j - num_dmx] = postpred_cov_re[i][j]; // q_postpred_cov_re
2255 13329552 : move32();
2256 : }
2257 : }
2258 1633334 : q_cov_uu_re = q_postpred_cov_re;
2259 1633334 : move16();
2260 :
2261 1633334 : IF( EQ_16( dtx_vad, 1 ) )
2262 : {
2263 3713804 : FOR( i = 1; i < num_dmx; i++ )
2264 : {
2265 6576816 : FOR( j = 1; j < num_dmx; j++ )
2266 : {
2267 4486716 : cov_dd_re[i - 1][j - 1] = postpred_cov_re[i][j]; // q_postpred_cov_re
2268 4486716 : move32();
2269 : }
2270 : }
2271 1623704 : q_cov_dd_re = q_postpred_cov_re;
2272 1623704 : move16();
2273 :
2274 1623704 : Word16 q_C_re = pSparMd->band_coeffs[b_ts_idx].q_C_re_fx;
2275 1623704 : move16();
2276 :
2277 1623704 : IF( EQ_16( num_dmx, 2 ) )
2278 : {
2279 : Word32 re1, re2;
2280 :
2281 486924 : W_tmp = W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], cov_dd_re[0][0] ); /*q_cov_dd_re+ pSparMd->band_coeffs[b_ts_idx].q_C_re_fx*/
2282 486924 : q_tmp1 = sub( W_norm( W_tmp ), 32 );
2283 486924 : re1 = W_shl_sat_l( W_tmp, q_tmp1 ); /*q_cov_dd_re+ q_C_re+q_tmp1*/
2284 486924 : q_tmp1 = add( add( q_C_re, q_tmp1 ), q_cov_dd_re );
2285 486924 : if ( W_tmp == 0 )
2286 : {
2287 47926 : q_tmp1 = 31;
2288 47926 : move16();
2289 : }
2290 486924 : W_tmp = W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[1][0], cov_dd_re[0][0] ); /*q_cov_dd_re+ q_C_re*/
2291 486924 : q_tmp = sub( W_norm( W_tmp ), 32 );
2292 486924 : re2 = W_shl_sat_l( W_tmp, q_tmp ); /*q_cov_dd_re+ q_C_re+q_tmp*/
2293 486924 : q_tmp = add( add( q_C_re, q_tmp ), q_cov_dd_re );
2294 486924 : if ( W_tmp == 0 )
2295 : {
2296 96583 : q_tmp = 31;
2297 96583 : move16();
2298 : }
2299 :
2300 486924 : W_tmp = W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], re1 ); // q_tmp1+q_C_re
2301 486924 : q_factor = sub( W_norm( W_tmp ), 32 );
2302 486924 : recon_uu_re[0][0] = W_shl_sat_l( W_tmp, q_factor ); // q_tmp1+q_C_re+q_recon_uu_re[0][0]
2303 486924 : move32();
2304 486924 : q_recon_uu_re[0][0] = add( add( q_C_re, q_factor ), q_tmp1 );
2305 486924 : move16();
2306 486924 : if ( W_tmp == 0 )
2307 : {
2308 47926 : q_recon_uu_re[0][0] = 31;
2309 47926 : move16();
2310 : }
2311 :
2312 486924 : W_tmp = W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[1][0], re1 ); // q_C_re+q_tmp1
2313 486924 : q_factor = sub( W_norm( W_tmp ), 32 );
2314 486924 : recon_uu_re[0][1] = W_shl_sat_l( W_tmp, q_factor ); // q_C_re+q_tmp1+q_recon_uu_re[0][1]
2315 486924 : move32();
2316 486924 : q_recon_uu_re[0][1] = add( add( q_C_re, q_factor ), q_tmp1 );
2317 486924 : move16();
2318 486924 : if ( W_tmp == 0 )
2319 : {
2320 98779 : q_recon_uu_re[0][1] = 31;
2321 98779 : move16();
2322 : }
2323 :
2324 486924 : W_tmp = W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], re2 ); // q_C_re+q_tmp
2325 486924 : q_factor = sub( W_norm( W_tmp ), 32 );
2326 486924 : recon_uu_re[1][0] = W_shl_sat_l( W_tmp, q_factor ); // q_C_re+q_tmp+q_recon_uu_re[1][0]
2327 486924 : move32();
2328 486924 : q_recon_uu_re[1][0] = add( add( q_C_re, q_factor ), q_tmp );
2329 486924 : move16();
2330 486924 : if ( W_tmp == 0 )
2331 : {
2332 98779 : q_recon_uu_re[1][0] = 31;
2333 98779 : move16();
2334 : }
2335 :
2336 486924 : W_tmp = W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[1][0], re2 ); // q_C_re+q_tmp
2337 486924 : q_factor = sub( W_norm( W_tmp ), 32 );
2338 486924 : recon_uu_re[1][1] = W_shl_sat_l( W_tmp, q_factor ); // q_C_re+q_tmp+q_recon_uu_re[1][1]
2339 486924 : move32();
2340 486924 : q_recon_uu_re[1][1] = add( add( q_C_re, q_factor ), q_tmp );
2341 486924 : move16();
2342 486924 : if ( W_tmp == 0 )
2343 : {
2344 96583 : q_recon_uu_re[1][1] = 31;
2345 96583 : move16();
2346 : }
2347 :
2348 486924 : q_tmp = 31;
2349 486924 : move16();
2350 1460772 : FOR( i = 0; i < 2; i++ )
2351 : {
2352 2921544 : FOR( j = 0; j < 2; j++ )
2353 : {
2354 1947696 : q_tmp = s_min( q_tmp, q_recon_uu_re[i][j] );
2355 : }
2356 : }
2357 486924 : q_tmp = sub( s_min( q_tmp, q_cov_uu_re ), 1 );
2358 486924 : q_factor = sub( q_cov_uu_re, q_tmp );
2359 1460772 : FOR( i = 0; i < 2; i++ )
2360 : {
2361 2921544 : FOR( j = 0; j < 2; j++ )
2362 : {
2363 1947696 : cov_uu_re[i][j] = L_sub( L_shr( cov_uu_re[i][j], q_factor ), L_shr( recon_uu_re[i][j], sub( q_recon_uu_re[i][j], q_tmp ) ) ); // q_tmp
2364 1947696 : move32();
2365 : }
2366 : }
2367 486924 : q_cov_uu_re = q_tmp;
2368 486924 : move16();
2369 : }
2370 1136780 : ELSE IF( EQ_16( num_dmx, 3 ) )
2371 : {
2372 : #ifdef FIX_1970_SBA_CRASH
2373 : Word64 re64[2];
2374 : Word32 re32[2], re32_2;
2375 : Word16 qtmp2;
2376 404868 : set64_fx( re64, 0, 2 );
2377 404868 : q_tmp = 63;
2378 1214604 : FOR( j = 0; j < 2; j++ )
2379 : {
2380 2429208 : FOR( k = 0; k < 2; k++ )
2381 : {
2382 1619472 : W_tmp = W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][k], cov_dd_re[k][j] ); // q_C_re+q_cov_dd_re
2383 1619472 : re64[j] = W_add( re64[j], W_tmp );
2384 1619472 : move64();
2385 : }
2386 809736 : q_tmp = s_min( q_tmp, sub( W_norm( re64[j] ), 33 ) );
2387 : }
2388 1214604 : FOR( j = 0; j < 2; j++ )
2389 : {
2390 809736 : re32[j] = W_shl_sat_l( re64[j], q_tmp ); // q_C_re+q_cov_dd_re+q_tmp
2391 809736 : move32();
2392 : }
2393 404868 : qtmp2 = add( add( q_C_re, q_tmp ), q_cov_dd_re );
2394 404868 : W_tmp = W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], re32[0] ); // q_C_re+qtmp2
2395 404868 : W_tmp = W_add( W_tmp, W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][1], re32[1] ) ); // q_C_re+qtmp2
2396 404868 : q_tmp = sub( W_norm( W_tmp ), 33 );
2397 404868 : re32_2 = W_shl_sat_l( W_tmp, q_tmp ); // q_C_re+qtmp2+q_tmp
2398 404868 : qtmp2 = add( add( q_C_re, q_tmp ), qtmp2 );
2399 404868 : q_tmp = s_min( 63, qtmp2 );
2400 404868 : recon_uu_re[0][0] = L_max( 0, re32_2 );
2401 404868 : move32();
2402 : #else
2403 : Word32 re1[2], re2;
2404 : Word16 q_re1[2];
2405 : set32_fx( re1, 0, 2 );
2406 : set16_fx( q_re1, 31, 2 );
2407 :
2408 : FOR( j = 0; j < 2; j++ )
2409 : {
2410 : FOR( k = 0; k < 2; k++ )
2411 : {
2412 : Word32 re;
2413 : W_tmp = W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][k], cov_dd_re[k][j] ); // q_C_re+q_cov_dd_re
2414 : q_tmp = sub( W_norm( W_tmp ), 33 );
2415 : re = W_shl_sat_l( W_tmp, q_tmp ); // q_C_re+q_cov_dd_re+q_tmp
2416 : q_tmp = add( add( q_C_re, q_tmp ), q_cov_dd_re );
2417 : if ( W_tmp == 0 )
2418 : {
2419 : q_tmp = 31;
2420 : move16();
2421 : }
2422 :
2423 : IF( LT_16( q_tmp, q_re1[j] ) )
2424 : {
2425 : re1[j] = L_shr( re1[j], sub( q_re1[j], q_tmp ) ); // q_tmp
2426 : move32();
2427 : q_re1[j] = q_tmp;
2428 : move16();
2429 : }
2430 : ELSE
2431 : {
2432 : re = L_shr( re, sub( q_tmp, q_re1[j] ) ); // q_re1[j]
2433 : }
2434 : re1[j] = L_add( re1[j], re ); // q_re1[j]
2435 : move32();
2436 : }
2437 : }
2438 :
2439 : W_tmp = W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], re1[0] ); // q_C_re+q_re1[0]
2440 : q_tmp = sub( W_norm( W_tmp ), 33 );
2441 : re2 = W_shl_sat_l( W_tmp, q_tmp ); // q_C_re+q_re1[0]+q_tmp
2442 : q_tmp = add( add( q_C_re, q_tmp ), q_re1[0] );
2443 : if ( W_tmp == 0 )
2444 : {
2445 : q_tmp = 31;
2446 : move16();
2447 : }
2448 : recon_uu_re[0][0] = re2; // q_C_re+q_re1[0]+q_tmp-32
2449 : move32();
2450 :
2451 : W_tmp = W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][1], re1[1] ); // q_C_re+q_re1[1]
2452 : q_tmp1 = sub( W_norm( W_tmp ), 33 );
2453 : re2 = W_shl_sat_l( W_tmp, q_tmp1 ); // q_C_re+q_re1[1]+q_tmp1
2454 : q_tmp1 = add( add( q_C_re, q_tmp1 ), q_re1[1] );
2455 : if ( W_tmp == 0 )
2456 : {
2457 : q_tmp1 = 31;
2458 : move16();
2459 : }
2460 :
2461 : IF( LT_16( q_tmp, q_tmp1 ) )
2462 : {
2463 : re2 = L_shr( re2, sub( q_tmp1, q_tmp ) ); // q_tmp
2464 : }
2465 : ELSE
2466 : {
2467 : recon_uu_re[0][0] = L_shr( recon_uu_re[0][0], sub( q_tmp, q_tmp1 ) ); // q_tmp1
2468 : move32();
2469 : q_tmp = q_tmp1;
2470 : move16();
2471 : }
2472 :
2473 : recon_uu_re[0][0] = L_add( recon_uu_re[0][0], re2 ); // q_tmp
2474 : move32();
2475 : #endif
2476 :
2477 404868 : IF( LT_16( q_cov_uu_re, q_tmp ) )
2478 : {
2479 389340 : recon_uu_re[0][0] = L_shr( recon_uu_re[0][0], sub( q_tmp, q_cov_uu_re ) ); // q_cov_uu_re
2480 389340 : move32();
2481 : }
2482 : ELSE
2483 : {
2484 31056 : FOR( i = num_dmx; i < num_ch; i++ )
2485 : {
2486 31056 : FOR( j = num_dmx; j < num_ch; j++ )
2487 : {
2488 15528 : cov_uu_re[i - num_dmx][j - num_dmx] = L_shr( cov_uu_re[i - num_dmx][j - num_dmx], sub( q_cov_uu_re, q_tmp ) ); // q_tmp
2489 15528 : move32();
2490 : }
2491 : }
2492 15528 : q_cov_uu_re = q_tmp;
2493 15528 : move16();
2494 : }
2495 :
2496 404868 : IF( recon_uu_re[0][0] != 0 )
2497 : {
2498 343769 : test();
2499 343769 : IF( W_norm( recon_uu_re[0][0] ) == 0 || W_norm( cov_uu_re[0][0] ) == 0 )
2500 : {
2501 30 : FOR( i = num_dmx; i < num_ch; i++ )
2502 : {
2503 30 : FOR( j = num_dmx; j < num_ch; j++ )
2504 : {
2505 15 : cov_uu_re[i - num_dmx][j - num_dmx] = L_shr( cov_uu_re[i - num_dmx][j - num_dmx], 1 ); // q_cov_uu_re-1
2506 15 : move32();
2507 : }
2508 : }
2509 15 : q_cov_uu_re = sub( q_cov_uu_re, 1 );
2510 15 : recon_uu_re[0][0] = L_shr( recon_uu_re[0][0], 1 ); // q_cov_uu_re
2511 15 : move32();
2512 : }
2513 : }
2514 :
2515 404868 : cov_uu_re[0][0] = L_sub( cov_uu_re[0][0], recon_uu_re[0][0] ); // q_cov_uu_re
2516 404868 : move32();
2517 : }
2518 731912 : ELSE IF( EQ_16( num_dmx, 4 ) )
2519 : {
2520 : /* Step 1: Multiply C * cov_dd * C' */
2521 : Word32 re1[3], re;
2522 : Word16 q_re1[3];
2523 :
2524 1490880 : FOR( i = 0; i < num_ch - num_dmx; i++ )
2525 : {
2526 1226400 : set32_fx( re1, 0, 3 );
2527 1226400 : set16_fx( q_re1, 31, 3 );
2528 1226400 : set16_fx( q_recon_uu_re[i], 31, IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS );
2529 4905600 : FOR( m = 0; m < num_dmx - 1; m++ )
2530 : {
2531 14716800 : FOR( k = 0; k < num_dmx - 1; k++ )
2532 : {
2533 11037600 : W_tmp = W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[i][k], cov_dd_re[k][m] ); // q_C_re+q_cov_dd_re
2534 11037600 : q_tmp = sub( W_norm( W_tmp ), 34 );
2535 11037600 : re = W_shl_sat_l( W_tmp, q_tmp ); // q_C_re+q_cov_dd_re+q_tmp
2536 11037600 : q_tmp = add( add( q_C_re, q_tmp ), q_cov_dd_re );
2537 11037600 : if ( W_tmp == 0 )
2538 : {
2539 1198684 : q_tmp = 31;
2540 1198684 : move16();
2541 : }
2542 :
2543 11037600 : IF( LT_16( q_tmp, q_re1[m] ) )
2544 : {
2545 5052196 : re1[m] = L_shr( re1[m], sub( q_re1[m], q_tmp ) ); // q_tmp
2546 5052196 : move32();
2547 5052196 : q_re1[m] = q_tmp;
2548 5052196 : move16();
2549 : }
2550 : ELSE
2551 : {
2552 5985404 : re = L_shr( re, sub( q_tmp, q_re1[m] ) ); // q_re1[m]
2553 : }
2554 11037600 : IF( re != 0 )
2555 : {
2556 9838896 : test();
2557 9838896 : IF( W_norm( re ) == 0 || W_norm( re1[m] ) == 0 )
2558 : {
2559 3337912 : re1[m] = L_shr( re1[m], 1 ); // q_re1[m]-1
2560 3337912 : move32();
2561 3337912 : q_re1[m] = sub( q_re1[m], 1 );
2562 3337912 : move16();
2563 3337912 : re = L_shr( re, 1 ); // q_re1[m]
2564 : }
2565 : }
2566 :
2567 11037600 : re1[m] = L_add( re1[m], re ); // q_re1[m]
2568 11037600 : move32();
2569 : }
2570 : }
2571 7932720 : FOR( j = 0; j < num_ch - num_dmx; j++ )
2572 : {
2573 26825280 : FOR( m = 0; m < num_dmx - 1; m++ )
2574 : {
2575 20118960 : W_tmp = W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[j][m], re1[m] ); // q_C_re+q_re1[m]
2576 20118960 : q_tmp = sub( W_norm( W_tmp ), 34 );
2577 20118960 : re = W_shl_sat_l( W_tmp, q_tmp ); // q_C_re+q_re1[m]+q_tmp
2578 20118960 : q_tmp = add( add( q_C_re, q_tmp ), q_re1[m] );
2579 20118960 : if ( W_tmp == 0 )
2580 : {
2581 2460892 : q_tmp = 31;
2582 2460892 : move16();
2583 : }
2584 :
2585 20118960 : IF( LT_16( q_tmp, q_recon_uu_re[i][j] ) )
2586 : {
2587 8540628 : recon_uu_re[i][j] = L_shr( recon_uu_re[i][j], sub( q_recon_uu_re[i][j], q_tmp ) ); // q_tmp
2588 8540628 : move32();
2589 8540628 : q_recon_uu_re[i][j] = q_tmp;
2590 8540628 : move16();
2591 : }
2592 : ELSE
2593 : {
2594 11578332 : re = L_shr( re, sub( q_tmp, q_recon_uu_re[i][j] ) ); // q_recon_uu_re[i][j]
2595 : }
2596 20118960 : IF( re != 0 )
2597 : {
2598 17658024 : test();
2599 17658024 : IF( W_norm( re ) == 0 || W_norm( recon_uu_re[i][j] ) == 0 )
2600 : {
2601 5986546 : recon_uu_re[i][j] = L_shr( recon_uu_re[i][j], 1 ); // q_recon_uu_re[i][j] - 1
2602 5986546 : move32();
2603 5986546 : q_recon_uu_re[i][j] = sub( q_recon_uu_re[i][j], 1 );
2604 5986546 : move16();
2605 5986546 : re = L_shr( re, 1 ); // q_recon_uu_re[i][j]
2606 : }
2607 : }
2608 20118960 : recon_uu_re[i][j] = L_add( recon_uu_re[i][j], re ); // q_recon_uu_re[i][j]
2609 20118960 : move32();
2610 : }
2611 : }
2612 : }
2613 :
2614 264480 : q_tmp = 31;
2615 264480 : move16();
2616 1490880 : FOR( i = 0; i < num_ch - num_dmx; i++ )
2617 : {
2618 7932720 : FOR( j = 0; j < num_ch - num_dmx; j++ )
2619 : {
2620 6706320 : q_tmp = s_min( q_tmp, q_recon_uu_re[i][j] );
2621 : }
2622 : }
2623 264480 : q_tmp = sub( s_min( q_tmp, q_cov_uu_re ), 1 );
2624 :
2625 : /* Step 2: cov_uu - recon_uu */
2626 1490880 : FOR( i = 0; i < sub( num_ch, num_dmx ); i++ )
2627 : {
2628 7932720 : FOR( j = 0; j < num_ch - num_dmx; j++ )
2629 : {
2630 6706320 : cov_uu_re[i][j] = L_sub( L_shr( cov_uu_re[i][j], sub( q_cov_uu_re, q_tmp ) ), L_shr( recon_uu_re[i][j], sub( q_recon_uu_re[i][j], q_tmp ) ) ); // q_tmp
2631 6706320 : move32();
2632 : }
2633 : }
2634 264480 : q_cov_uu_re = q_tmp;
2635 264480 : move16();
2636 : }
2637 : }
2638 :
2639 1633334 : p_norm_scaling = IVAS_P_NORM_SCALING_FX; // q31
2640 1633334 : move32();
2641 :
2642 1633334 : test();
2643 1633334 : if ( ( dtx_vad == 0 ) && EQ_16( num_dmx, 1 ) )
2644 : {
2645 5052 : p_norm_scaling = IVAS_P_NORM_SCALING_DTX_FX; // q31
2646 5052 : move32();
2647 : }
2648 :
2649 1633334 : trace = 0;
2650 1633334 : move64();
2651 :
2652 5665058 : FOR( i = num_dmx; i < num_ch; i++ )
2653 : {
2654 4031724 : trace = W_add( trace, W_deposit32_l( L_abs( cov_uu_re[i - num_dmx][i - num_dmx] ) ) ); // q_cov_uu_re
2655 : }
2656 :
2657 1633334 : factor = postpred_cov_re[0][0]; // q_postpred_cov_re
2658 1633334 : move32();
2659 1633334 : q_factor = q_postpred_cov_re;
2660 1633334 : move16();
2661 1633334 : IF( trace != 0 )
2662 : {
2663 1591878 : q_factor = sub( W_norm( trace ), 32 );
2664 1591878 : tmp = Mpy_32_32( p_norm_scaling, W_shl_sat_l( trace, q_factor ) ); // q_cov_uu_re+q_factor
2665 1591878 : q_factor = add( q_cov_uu_re, q_factor );
2666 1591878 : IF( GT_16( q_factor, q_postpred_cov_re ) )
2667 : {
2668 1312625 : tmp = L_shr( tmp, sub( q_factor, q_postpred_cov_re ) ); // q_postpred_cov_re
2669 1312625 : q_factor = q_postpred_cov_re;
2670 1312625 : move16();
2671 : }
2672 : ELSE
2673 : {
2674 279253 : factor = L_shr( factor, sub( q_postpred_cov_re, q_factor ) ); // q_factor
2675 : }
2676 1591878 : factor = L_max( factor, tmp ); // q_factor
2677 : }
2678 :
2679 1633334 : tmp = L_shl_sat( 189 /* 1e-20 in Q74 */, sub( q_factor, 74 ) );
2680 :
2681 1633334 : Word16 factor_exp = 0;
2682 1633334 : move16();
2683 1633334 : IF( LE_32( factor, tmp ) )
2684 : {
2685 3573 : factor = 22204; // (1 / 1e-20) in Q(-52)
2686 3573 : factor_exp = Q15 - ( -52 );
2687 3573 : move32();
2688 3573 : move16();
2689 : }
2690 : ELSE
2691 : {
2692 1629761 : factor = BASOP_Util_Divide3232_Scale( 1, factor, &factor_exp ); // q=15-(factor_exp+31-(31-q_factor))
2693 1629761 : factor_exp = add( factor_exp, q_factor );
2694 : }
2695 :
2696 : /* normalise Hermitian (except for rounding) cov_uu */
2697 5665058 : FOR( i = num_dmx; i < num_ch; i++ )
2698 : {
2699 17361276 : FOR( j = num_dmx; j < num_ch; j++ )
2700 : {
2701 13329552 : IF( EQ_16( i, j ) )
2702 : {
2703 : /* force diagonal to be real */
2704 4031724 : W_tmp = W_mult0_32_32( cov_uu_re[i - num_dmx][j - num_dmx], factor ); /*q_cov_uu_re+15-factor_exp*/
2705 4031724 : q_tmp = 32;
2706 4031724 : move16();
2707 4031724 : if ( W_tmp != 0 )
2708 : {
2709 3831916 : q_tmp = W_norm( W_tmp );
2710 : }
2711 4031724 : cov_uu_re[i - num_dmx][j - num_dmx] = W_extract_h( W_shl( W_tmp, q_tmp ) ); /*q_cov_uu_re+15-factor_exp+q_tmp-32*/
2712 4031724 : move32();
2713 4031724 : q_cov_uu_re_per_value[i - num_dmx][j - num_dmx] = sub( add( add( q_cov_uu_re, sub( 15, factor_exp ) ), q_tmp ), 32 );
2714 4031724 : move16();
2715 : }
2716 : ELSE
2717 : {
2718 : /* set off-diag elements to zero */
2719 9297828 : cov_uu_re[i - num_dmx][j - num_dmx] = 0;
2720 9297828 : move32();
2721 9297828 : q_cov_uu_re_per_value[i - num_dmx][j - num_dmx] = 0;
2722 9297828 : move16();
2723 : }
2724 : }
2725 : }
2726 :
2727 : Word16 cov_uu_re_exp;
2728 1633334 : q_tmp = 31;
2729 1633334 : move16();
2730 : /* take sqrt of max of diags and zero */
2731 5665058 : FOR( i = num_dmx; i < num_ch; i++ )
2732 : {
2733 4031724 : cov_uu_re_exp = sub( 31, q_cov_uu_re_per_value[i - num_dmx][i - num_dmx] );
2734 4031724 : cov_uu_re[i - num_dmx][i - num_dmx] = Sqrt32( L_max( 0, cov_uu_re[i - num_dmx][i - num_dmx] ), &cov_uu_re_exp ); // q=31-cov_uu_re_exp
2735 4031724 : move32();
2736 4031724 : q_cov_uu_re_per_value[i - num_dmx][i - num_dmx] = sub( 31, cov_uu_re_exp );
2737 4031724 : move16();
2738 4031724 : q_tmp = s_min( q_tmp, q_cov_uu_re_per_value[i - num_dmx][i - num_dmx] );
2739 : }
2740 :
2741 : /* save into MD struct */
2742 5665058 : FOR( i = num_dmx; i < num_ch; i++ )
2743 : {
2744 17361276 : FOR( j = num_dmx; j < num_ch; j++ )
2745 : {
2746 13329552 : IF( EQ_16( i, j ) )
2747 : {
2748 4031724 : pSparMd->band_coeffs[b_ts_idx].P_re_fx[j - num_dmx] = L_shr( cov_uu_re[i - num_dmx][j - num_dmx], sub( q_cov_uu_re_per_value[i - num_dmx][j - num_dmx], Q28 ) ); // Q28
2749 4031724 : move32();
2750 : }
2751 : }
2752 : }
2753 1633334 : pSparMd->band_coeffs[b_ts_idx].q_P_re_fx = Q28;
2754 1633334 : move16();
2755 : }
2756 :
2757 1633334 : return;
2758 : }
2759 :
2760 1809328 : static void ivas_calc_p_coeffs_per_band_fx(
2761 : ivas_spar_md_t *pSparMd,
2762 : const Word16 i_ts,
2763 : Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], // q_postpred_cov_re
2764 : Word16 q_postpred_cov_re,
2765 : const Word16 num_ch,
2766 : const Word16 dtx_vad,
2767 : const Word16 num_dmx,
2768 : const Word16 band_idx )
2769 : {
2770 : Word16 i, j, k;
2771 : Word16 m;
2772 : Word32 factor;
2773 : Word32 recon_uu_re[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS][IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS];
2774 : Word32 trace;
2775 : Word32 p_norm_scaling;
2776 : Word16 q_cov_uu_re;
2777 : Word32 cov_dd_re[IVAS_SPAR_MAX_CH - 1][IVAS_SPAR_MAX_CH - 1];
2778 : Word32 cov_uu_re[IVAS_SPAR_MAX_CH - 1][IVAS_SPAR_MAX_CH - 1];
2779 : Word16 b_ts_idx;
2780 : Word16 tmp;
2781 :
2782 1809328 : b_ts_idx = add( band_idx, imult1616( i_ts, IVAS_MAX_NUM_BANDS ) );
2783 :
2784 1809328 : IF( NE_16( num_dmx, num_ch ) )
2785 : {
2786 1809328 : set32_fx( pSparMd->band_coeffs[b_ts_idx].P_re_fx, 0, IVAS_SPAR_MAX_CH - 1 );
2787 1809328 : pSparMd->band_coeffs[b_ts_idx].q_P_re_fx = 0;
2788 1809328 : move16();
2789 14474624 : FOR( i = 0; i < sub( IVAS_SPAR_MAX_CH, IVAS_SPAR_MAX_DMX_CHS ); i++ )
2790 : {
2791 12665296 : set32_fx( recon_uu_re[i], 0, sub( IVAS_SPAR_MAX_CH, IVAS_SPAR_MAX_DMX_CHS ) );
2792 : }
2793 :
2794 5265572 : FOR( i = num_dmx; i < num_ch; i++ )
2795 : {
2796 11102696 : FOR( j = num_dmx; j < num_ch; j++ )
2797 : {
2798 7646452 : cov_uu_re[i - num_dmx][j - num_dmx] = postpred_cov_re[i][j]; // q=q_postpred_cov_re
2799 7646452 : move32();
2800 : }
2801 : }
2802 1809328 : q_cov_uu_re = q_postpred_cov_re;
2803 1809328 : move16();
2804 :
2805 1809328 : IF( EQ_16( dtx_vad, 1 ) )
2806 : {
2807 3769492 : FOR( i = 1; i < num_dmx; i++ )
2808 : {
2809 5154560 : FOR( j = 1; j < num_dmx; j++ )
2810 : {
2811 3187880 : cov_dd_re[i - 1][j - 1] = postpred_cov_re[i][j]; // q=q_postpred_cov_re
2812 3187880 : move32();
2813 : }
2814 : }
2815 :
2816 1802812 : Word16 q_C_re = pSparMd->band_coeffs[b_ts_idx].q_C_re_fx;
2817 1802812 : move16();
2818 :
2819 1802812 : IF( EQ_16( num_dmx, 2 ) )
2820 : {
2821 : Word32 re1, re2;
2822 :
2823 745480 : re1 = W_extract_l( W_shr( W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], cov_dd_re[0][0] ), q_C_re ) ); // q_cov_uu_re
2824 745480 : re2 = W_extract_l( W_shr( W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[1][0], cov_dd_re[0][0] ), q_C_re ) ); // q_cov_uu_re
2825 :
2826 745480 : recon_uu_re[0][0] = W_extract_l( W_shr( W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], re1 ), q_C_re ) ); // q_cov_uu_re
2827 745480 : recon_uu_re[0][1] = W_extract_l( W_shr( W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[1][0], re1 ), q_C_re ) ); // q_cov_uu_re
2828 745480 : recon_uu_re[1][0] = W_extract_l( W_shr( W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], re2 ), q_C_re ) ); // q_cov_uu_re
2829 745480 : recon_uu_re[1][1] = W_extract_l( W_shr( W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[1][0], re2 ), q_C_re ) ); // q_cov_uu_re
2830 745480 : move32();
2831 745480 : move32();
2832 745480 : move32();
2833 745480 : move32();
2834 :
2835 2236440 : FOR( i = 0; i < 2; i++ )
2836 : {
2837 4472880 : FOR( j = 0; j < 2; j++ )
2838 : {
2839 2981920 : cov_uu_re[i][j] = L_sub( cov_uu_re[i][j], recon_uu_re[i][j] ); // q_cov_uu_re
2840 2981920 : move32();
2841 : }
2842 : }
2843 : }
2844 1057332 : ELSE IF( EQ_16( num_dmx, 3 ) )
2845 : {
2846 : Word32 re1[2], re2;
2847 610600 : set32_fx( re1, 0, 2 );
2848 :
2849 1831800 : FOR( j = 0; j < 2; j++ )
2850 : {
2851 3663600 : FOR( k = 0; k < 2; k++ )
2852 : {
2853 : Word32 re;
2854 2442400 : re = W_extract_l( W_shr( W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][k], cov_dd_re[k][j] ), q_C_re ) ); // q_cov_uu_re
2855 2442400 : re1[j] = L_add( re1[j], re ); // q_cov_uu_re
2856 2442400 : move32();
2857 : }
2858 : }
2859 :
2860 610600 : re2 = W_extract_l( W_shr( W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], re1[0] ), q_C_re ) ); // q_cov_uu_re
2861 610600 : recon_uu_re[0][0] = re2; // q_cov_uu_re
2862 610600 : move32();
2863 610600 : re2 = W_extract_l( W_shr( W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][1], re1[1] ), q_C_re ) ); // q_cov_uu_re
2864 610600 : recon_uu_re[0][0] = L_add( recon_uu_re[0][0], re2 ); // q_cov_uu_re
2865 610600 : move32();
2866 :
2867 610600 : cov_uu_re[0][0] = L_sub( cov_uu_re[0][0], recon_uu_re[0][0] ); // q_cov_uu_re
2868 610600 : move32();
2869 : }
2870 446732 : ELSE IF( EQ_16( num_dmx, 4 ) )
2871 : {
2872 : /* Step 1: Multiply C * cov_dd * C' */
2873 : Word32 re1[3], re;
2874 :
2875 0 : FOR( i = 0; i < num_ch - num_dmx; i++ )
2876 : {
2877 0 : set32_fx( re1, 0, 3 );
2878 0 : FOR( m = 0; m < num_dmx - 1; m++ )
2879 : {
2880 0 : FOR( k = 0; k < num_dmx - 1; k++ )
2881 : {
2882 0 : re = W_extract_l( W_shr( W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[i][k], cov_dd_re[k][m] ), q_C_re ) ); // q_cov_uu_re
2883 0 : re1[m] = L_add( re1[m], re ); // q_cov_uu_re
2884 0 : move32();
2885 : }
2886 : }
2887 0 : FOR( j = 0; j < num_ch - num_dmx; j++ )
2888 : {
2889 0 : FOR( m = 0; m < num_dmx - 1; m++ )
2890 : {
2891 0 : re = W_extract_l( W_shr( W_mult0_32_32( pSparMd->band_coeffs[b_ts_idx].C_re_fx[j][m], re1[m] ), q_C_re ) ); // q_cov_uu_re
2892 0 : recon_uu_re[i][j] = L_add( recon_uu_re[i][j], re ); // q_cov_uu_re
2893 0 : move32();
2894 : }
2895 : }
2896 : }
2897 :
2898 : /* Step 2: cov_uu - recon_uu */
2899 0 : FOR( i = 0; i < sub( num_ch, num_dmx ); i++ )
2900 : {
2901 0 : FOR( j = 0; j < num_ch - num_dmx; j++ )
2902 : {
2903 0 : cov_uu_re[i][j] = L_sub( cov_uu_re[i][j], recon_uu_re[i][j] ); // q_cov_uu_re
2904 0 : move32();
2905 : }
2906 : }
2907 : }
2908 : }
2909 :
2910 1809328 : p_norm_scaling = IVAS_P_NORM_SCALING_FX; /*q31*/
2911 1809328 : move32();
2912 :
2913 1809328 : test();
2914 1809328 : if ( ( dtx_vad == 0 ) && EQ_16( num_dmx, 1 ) )
2915 : {
2916 1456 : p_norm_scaling = IVAS_P_NORM_SCALING_DTX_FX; /*q31*/
2917 1456 : move32();
2918 : }
2919 :
2920 1809328 : trace = 0;
2921 1809328 : move32();
2922 :
2923 5265572 : FOR( i = num_dmx; i < num_ch; i++ )
2924 : {
2925 3456244 : trace = L_add( trace, L_abs( cov_uu_re[i - num_dmx][i - num_dmx] ) ); // q_cov_uu_re
2926 : }
2927 :
2928 1809328 : factor = L_max( IVAS_FIX_EPS, postpred_cov_re[0][0] ); // q=q_postpred_cov_re
2929 1809328 : factor = L_max( factor, Mpy_32_32( p_norm_scaling, trace ) ); // q=q_postpred_cov_re
2930 :
2931 1809328 : Word16 factor_exp = 0;
2932 1809328 : move16();
2933 1809328 : factor = BASOP_Util_Divide3232_Scale( L_shl( 1, q_postpred_cov_re ), factor, &factor_exp ); // q=15-factor_exp
2934 1809328 : tmp = sub( 15, factor_exp );
2935 :
2936 : /* normalise Hermitian (except for rounding) cov_uu */
2937 5265572 : FOR( i = num_dmx; i < num_ch; i++ )
2938 : {
2939 11102696 : FOR( j = num_dmx; j < num_ch; j++ )
2940 : {
2941 7646452 : IF( EQ_16( i, j ) )
2942 : {
2943 : /* force diagonal to be real */
2944 3456244 : cov_uu_re[i - num_dmx][j - num_dmx] = W_extract_l( W_shr( W_mult0_32_32( cov_uu_re[i - num_dmx][j - num_dmx], factor ), tmp ) ); // q_cov_uu_re
2945 3456244 : move32();
2946 : }
2947 : ELSE
2948 : {
2949 : /* set off-diag elements to zero */
2950 4190208 : cov_uu_re[i - num_dmx][j - num_dmx] = 0;
2951 4190208 : move32();
2952 : }
2953 : }
2954 : }
2955 :
2956 : Word16 cov_uu_re_exp;
2957 : /* take sqrt of max of diags and zero */
2958 5265572 : FOR( i = num_dmx; i < num_ch; i++ )
2959 : {
2960 3456244 : cov_uu_re_exp = sub( 31, q_cov_uu_re );
2961 3456244 : cov_uu_re[i - num_dmx][i - num_dmx] = Sqrt32( L_max( 0, cov_uu_re[i - num_dmx][i - num_dmx] ), &cov_uu_re_exp ); // q=31-cov_uu_re_exp
2962 3456244 : cov_uu_re[i - num_dmx][i - num_dmx] = L_shl( cov_uu_re[i - num_dmx][i - num_dmx], sub( q_cov_uu_re, sub( 31, cov_uu_re_exp ) ) ); // q_cov_uu_re
2963 3456244 : move32();
2964 3456244 : move32();
2965 : }
2966 :
2967 : /* save into MD struct */
2968 5265572 : FOR( i = num_dmx; i < num_ch; i++ )
2969 : {
2970 11102696 : FOR( j = num_dmx; j < num_ch; j++ )
2971 : {
2972 7646452 : IF( EQ_16( i, j ) )
2973 : {
2974 3456244 : pSparMd->band_coeffs[b_ts_idx].P_re_fx[j - num_dmx] = cov_uu_re[i - num_dmx][j - num_dmx]; // q_cov_uu_re
2975 3456244 : move32();
2976 : }
2977 : }
2978 : }
2979 1809328 : pSparMd->band_coeffs[b_ts_idx].q_P_re_fx = q_cov_uu_re;
2980 1809328 : move16();
2981 : }
2982 :
2983 1809328 : return;
2984 : }
2985 :
2986 :
2987 : /*-----------------------------------------------------------------------------------------*
2988 : * Function ivas_calc_c_coeffs_per_band()
2989 : *
2990 : * Calculate C coeffs per band
2991 : *-----------------------------------------------------------------------------------------*/
2992 :
2993 2023472 : static void ivas_calc_c_coeffs_per_band_enc_fx(
2994 : ivas_spar_md_t *pSparMd,
2995 : const Word16 i_ts,
2996 : Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], // q_post_pred_cov_re
2997 : Word16 q_post_pred_cov_re,
2998 : const Word16 num_ch,
2999 : const Word16 num_dmx,
3000 : const Word16 band_idx,
3001 : const Word16 dtx_vad )
3002 : {
3003 : Word16 i, j, k;
3004 :
3005 : /* worst case for cov_ud is actually 12 x 3 */
3006 : Word32 cov_ud_re[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS][IVAS_SPAR_MAX_DMX_CHS - 1];
3007 : Word32 cov_dd_re[FOA_CHANNELS - 1][FOA_CHANNELS - 1];
3008 : Word32 cov_dd_re_inv[FOA_CHANNELS - 1][FOA_CHANNELS - 1];
3009 : Word16 q_cov_dd_re_inv;
3010 : Word32 trace_cov_dd_re, max_val;
3011 : Word16 q_tmp;
3012 : Word32 abs_trace;
3013 : Word16 b_ts_idx;
3014 :
3015 2023472 : b_ts_idx = add( band_idx, imult1616( i_ts, IVAS_MAX_NUM_BANDS ) );
3016 :
3017 2023472 : IF( dtx_vad == 0 )
3018 : {
3019 6104 : set32_fx( &pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], 0, imult1616( sub( IVAS_SPAR_MAX_CH, IVAS_SPAR_MAX_DMX_CHS ), sub( IVAS_SPAR_MAX_DMX_CHS, 1 ) ) );
3020 6104 : pSparMd->band_coeffs[b_ts_idx].q_C_re_fx = 0;
3021 6104 : move16();
3022 6104 : return;
3023 : }
3024 :
3025 6772204 : FOR( i = num_dmx; i < num_ch; i++ )
3026 : {
3027 15090052 : FOR( j = 1; j < num_dmx; j++ )
3028 : {
3029 10335216 : cov_ud_re[i - num_dmx][j - 1] = postpred_cov_re[i][j]; // q_post_pred_cov_re
3030 10335216 : move32();
3031 : }
3032 : }
3033 :
3034 2017368 : max_val = 0;
3035 2017368 : move32();
3036 :
3037 5767436 : FOR( i = 1; i < num_dmx; i++ )
3038 : {
3039 12023456 : FOR( j = 1; j < num_dmx; j++ )
3040 : {
3041 8273388 : IF( EQ_16( i, j ) )
3042 : {
3043 3750068 : max_val = L_max( max_val, postpred_cov_re[i][j] ); // q_post_pred_cov_re
3044 : }
3045 8273388 : cov_dd_re[i - 1][j - 1] = postpred_cov_re[i][j]; // q_post_pred_cov_re
3046 8273388 : move32();
3047 : }
3048 : }
3049 :
3050 2017368 : trace_cov_dd_re = 0;
3051 2017368 : move32();
3052 :
3053 5767436 : FOR( i = 0; i < sub( num_dmx, 1 ); i++ )
3054 : {
3055 3750068 : trace_cov_dd_re = L_add( trace_cov_dd_re, Mpy_32_32( cov_dd_re[i][i], 10737418 /* 0.005f in Q31*/ ) ); // q_post_pred_cov_re
3056 : }
3057 :
3058 2017368 : abs_trace = L_abs( trace_cov_dd_re ); // q_post_pred_cov_re
3059 :
3060 2017368 : IF( LE_32( abs_trace, IVAS_FIX_EPS ) )
3061 : {
3062 : /* protection from cases when variance of residual channels is very small */
3063 32228 : set32_fx( &pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], 0, imult1616( sub( IVAS_SPAR_MAX_CH, IVAS_SPAR_MAX_DMX_CHS ), sub( IVAS_SPAR_MAX_DMX_CHS, 1 ) ) );
3064 32228 : pSparMd->band_coeffs[b_ts_idx].q_C_re_fx = 0;
3065 32228 : move16();
3066 : }
3067 : ELSE
3068 : {
3069 1985140 : q_tmp = 1;
3070 1985140 : move16();
3071 1985140 : if ( norm_l( max_val ) > 0 )
3072 : {
3073 1890271 : q_tmp = 0;
3074 1890271 : move16();
3075 : }
3076 1985140 : trace_cov_dd_re = L_shr( trace_cov_dd_re, q_tmp ); // q_post_pred_cov_re - q_tmp
3077 5677516 : FOR( i = 0; i < sub( num_dmx, 1 ); i++ )
3078 : {
3079 11843704 : FOR( j = 0; j < sub( num_dmx, 1 ); j++ )
3080 : {
3081 8151328 : cov_dd_re[i][j] = L_shr( cov_dd_re[i][j], q_tmp ); // q_post_pred_cov_re - q_tmp
3082 8151328 : move32();
3083 : }
3084 : }
3085 :
3086 5677516 : FOR( i = 0; i < sub( num_dmx, 1 ); i++ )
3087 : {
3088 3692376 : cov_dd_re[i][i] = L_add( trace_cov_dd_re, cov_dd_re[i][i] ); // q_post_pred_cov_re - q_tmp
3089 3692376 : move32();
3090 : }
3091 1985140 : test();
3092 1985140 : IF( EQ_16( ivas_is_mat_inv_fx( cov_dd_re, q_post_pred_cov_re, sub( num_dmx, 1 ) ), 1 ) && LT_16( num_dmx, FOA_CHANNELS ) )
3093 : {
3094 51 : set32_fx( &pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], 0, imult1616( sub( IVAS_SPAR_MAX_CH, IVAS_SPAR_MAX_DMX_CHS ), sub( IVAS_SPAR_MAX_DMX_CHS, 1 ) ) );
3095 51 : pSparMd->band_coeffs[b_ts_idx].q_C_re_fx = 0;
3096 51 : move16();
3097 : }
3098 : ELSE
3099 : {
3100 1985089 : ivas_calc_mat_inv_fx( cov_dd_re, sub( q_post_pred_cov_re, q_tmp ), sub( num_dmx, 1 ), cov_dd_re_inv, &q_cov_dd_re_inv );
3101 :
3102 : Word16 tmp;
3103 1985089 : Word64 W_max_val = 1;
3104 1985089 : move64();
3105 : Word64 C_re_fx[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS][IVAS_SPAR_MAX_DMX_CHS - 1];
3106 :
3107 6680642 : FOR( i = 0; i < sub( num_ch, num_dmx ); i++ )
3108 : {
3109 14918931 : FOR( j = 0; j < sub( num_dmx, 1 ); j++ )
3110 : {
3111 10223378 : C_re_fx[i][j] = 0;
3112 10223378 : move64();
3113 36367526 : FOR( k = 0; k < sub( num_dmx, 1 ); k++ )
3114 : {
3115 26144148 : C_re_fx[i][j] = W_add_nosat( C_re_fx[i][j], W_mult0_32_32( cov_ud_re[i][k], cov_dd_re_inv[k][j] ) ); // q_post_pred_cov_re+q_cov_dd_re_inv
3116 26144148 : move64();
3117 : }
3118 10223378 : if ( LT_64( W_max_val, W_abs( C_re_fx[i][j] ) ) )
3119 : {
3120 3311358 : W_max_val = W_abs( C_re_fx[i][j] ); // q_post_pred_cov_re+q_cov_dd_re_inv
3121 : }
3122 : }
3123 : }
3124 :
3125 1985089 : tmp = s_max( sub( 32, W_norm( W_max_val ) ), 0 );
3126 :
3127 6680642 : FOR( i = 0; i < sub( num_ch, num_dmx ); i++ )
3128 : {
3129 14918931 : FOR( j = 0; j < sub( num_dmx, 1 ); j++ )
3130 : {
3131 10223378 : pSparMd->band_coeffs[b_ts_idx].C_re_fx[i][j] = W_extract_l( W_shr( C_re_fx[i][j], tmp ) ); // q_post_pred_cov_re+q_cov_dd_re_inv-tmp
3132 10223378 : move32();
3133 : }
3134 : }
3135 1985089 : pSparMd->band_coeffs[b_ts_idx].q_C_re_fx = sub( add( q_cov_dd_re_inv, q_post_pred_cov_re ), tmp );
3136 1985089 : move16();
3137 : }
3138 : }
3139 :
3140 2017368 : return;
3141 : }
3142 :
3143 1361140 : static void ivas_calc_c_coeffs_per_band_fx(
3144 : ivas_spar_md_t *pSparMd,
3145 : const Word16 i_ts,
3146 : Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_post_pred_cov_re*/
3147 : Word16 q_post_pred_cov_re,
3148 : const Word16 num_ch,
3149 : const Word16 num_dmx,
3150 : const Word16 band_idx,
3151 : const Word16 dtx_vad )
3152 : {
3153 : Word16 i, j, k;
3154 :
3155 : /* worst case for cov_ud is actually 12 x 3 */
3156 : Word32 cov_ud_re[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS][IVAS_SPAR_MAX_DMX_CHS - 1];
3157 : Word32 cov_dd_re[FOA_CHANNELS - 1][FOA_CHANNELS - 1];
3158 : Word32 cov_dd_re_inv[FOA_CHANNELS - 1][FOA_CHANNELS - 1];
3159 : Word16 q_cov_dd_re_inv;
3160 : Word32 trace_cov_dd_re;
3161 : Word32 abs_trace;
3162 : Word16 b_ts_idx;
3163 :
3164 1361140 : b_ts_idx = add( band_idx, imult1616( i_ts, IVAS_MAX_NUM_BANDS ) );
3165 :
3166 1361140 : IF( dtx_vad == 0 )
3167 : {
3168 5060 : set32_fx( &pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], 0, imult1616( sub( IVAS_SPAR_MAX_CH, IVAS_SPAR_MAX_DMX_CHS ), sub( IVAS_SPAR_MAX_DMX_CHS, 1 ) ) );
3169 5060 : pSparMd->band_coeffs[b_ts_idx].q_C_re_fx = 0;
3170 5060 : move16();
3171 5060 : return;
3172 : }
3173 :
3174 3457640 : FOR( i = num_dmx; i < num_ch; i++ )
3175 : {
3176 4813720 : FOR( j = 1; j < num_dmx; j++ )
3177 : {
3178 2712160 : cov_ud_re[i - num_dmx][j - 1] = postpred_cov_re[i][j]; // q_post_pred_cov_re
3179 2712160 : move32();
3180 : }
3181 : }
3182 :
3183 3322760 : FOR( i = 1; i < num_dmx; i++ )
3184 : {
3185 5154560 : FOR( j = 1; j < num_dmx; j++ )
3186 : {
3187 3187880 : cov_dd_re[i - 1][j - 1] = postpred_cov_re[i][j]; // q_post_pred_cov_re
3188 3187880 : move32();
3189 : }
3190 : }
3191 :
3192 1356080 : trace_cov_dd_re = 0;
3193 1356080 : move32();
3194 :
3195 3322760 : FOR( i = 0; i < num_dmx - 1; i++ )
3196 : {
3197 1966680 : trace_cov_dd_re = L_add( trace_cov_dd_re, cov_dd_re[i][i] ); // q_post_pred_cov_re
3198 : }
3199 1356080 : trace_cov_dd_re = Mpy_32_32( trace_cov_dd_re, 10737418 /* 0.005f in Q31*/ ); // q_post_pred_cov_re
3200 :
3201 1356080 : abs_trace = L_abs( trace_cov_dd_re ); // q_post_pred_cov_re
3202 :
3203 1356080 : IF( LE_32( abs_trace, IVAS_FIX_EPS ) )
3204 : {
3205 : /* protection from cases when variance of residual channels is very small */
3206 89555 : set32_fx( &pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], 0, imult1616( sub( IVAS_SPAR_MAX_CH, IVAS_SPAR_MAX_DMX_CHS ), sub( IVAS_SPAR_MAX_DMX_CHS, 1 ) ) );
3207 89555 : pSparMd->band_coeffs[b_ts_idx].q_C_re_fx = 0;
3208 89555 : move16();
3209 : }
3210 : ELSE
3211 : {
3212 3101590 : FOR( i = 0; i < sub( num_dmx, 1 ); i++ )
3213 : {
3214 1835065 : cov_dd_re[i][i] = L_add( trace_cov_dd_re, cov_dd_re[i][i] ); // q_post_pred_cov_re
3215 1835065 : move32();
3216 : }
3217 1266525 : test();
3218 1266525 : IF( EQ_16( ivas_is_mat_inv_fx( cov_dd_re, q_post_pred_cov_re, sub( num_dmx, 1 ) ), 1 ) && LT_16( num_dmx, FOA_CHANNELS ) )
3219 : {
3220 0 : set32_fx( &pSparMd->band_coeffs[b_ts_idx].C_re_fx[0][0], 0, imult1616( sub( IVAS_SPAR_MAX_CH, IVAS_SPAR_MAX_DMX_CHS ), sub( IVAS_SPAR_MAX_DMX_CHS, 1 ) ) );
3221 0 : pSparMd->band_coeffs[b_ts_idx].q_C_re_fx = 0;
3222 0 : move16();
3223 : }
3224 : ELSE
3225 : {
3226 1266525 : ivas_calc_mat_inv_fx( cov_dd_re, q_post_pred_cov_re, sub( num_dmx, 1 ), cov_dd_re_inv, &q_cov_dd_re_inv );
3227 :
3228 : Word16 tmp;
3229 1266525 : Word64 max_val = 1;
3230 1266525 : move64();
3231 : Word64 C_re_fx[IVAS_SPAR_MAX_CH - IVAS_SPAR_MAX_DMX_CHS][IVAS_SPAR_MAX_DMX_CHS - 1];
3232 :
3233 3231035 : FOR( i = 0; i < sub( num_ch, num_dmx ); i++ )
3234 : {
3235 4497560 : FOR( j = 0; j < sub( num_dmx, 1 ); j++ )
3236 : {
3237 2533050 : C_re_fx[i][j] = 0;
3238 2533050 : move64();
3239 6203180 : FOR( k = 0; k < sub( num_dmx, 1 ); k++ )
3240 : {
3241 3670130 : C_re_fx[i][j] = W_add_nosat( C_re_fx[i][j], W_mult0_32_32( cov_ud_re[i][k], cov_dd_re_inv[k][j] ) ); // q_post_pred_cov_re+q_cov_dd_re_inv
3242 3670130 : move64();
3243 : }
3244 2533050 : if ( LT_64( max_val, W_abs( C_re_fx[i][j] ) ) )
3245 : {
3246 1363862 : max_val = W_abs( C_re_fx[i][j] ); // q_post_pred_cov_re+q_cov_dd_re_inv
3247 : }
3248 : }
3249 : }
3250 :
3251 1266525 : tmp = s_max( sub( 32, W_norm( max_val ) ), 0 );
3252 :
3253 3231035 : FOR( i = 0; i < sub( num_ch, num_dmx ); i++ )
3254 : {
3255 4497560 : FOR( j = 0; j < sub( num_dmx, 1 ); j++ )
3256 : {
3257 2533050 : pSparMd->band_coeffs[b_ts_idx].C_re_fx[i][j] = W_extract_l( W_shr( C_re_fx[i][j], tmp ) ); // q_post_pred_cov_re+q_cov_dd_re_inv-tmp
3258 2533050 : move32();
3259 : }
3260 : }
3261 1266525 : pSparMd->band_coeffs[b_ts_idx].q_C_re_fx = sub( add( q_cov_dd_re_inv, q_post_pred_cov_re ), tmp );
3262 1266525 : move16();
3263 : }
3264 : }
3265 :
3266 1356080 : return;
3267 : }
3268 :
3269 :
3270 : /*-----------------------------------------------------------------------------------------*
3271 : * Function ivas_calc_c_p_coeffs()
3272 : *
3273 : * Calculation of C and P coeffs
3274 : *-----------------------------------------------------------------------------------------*/
3275 :
3276 :
3277 2495956 : void ivas_calc_c_p_coeffs_enc_fx(
3278 : ivas_spar_md_t *pSparMd,
3279 : Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_cov_real*/
3280 : Word16 *q_cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],
3281 : const Word16 i_ts,
3282 : Word32 ***mixer_mat, /*q_mixer_mat*/
3283 : Word16 q_mixer_mat,
3284 : const Word16 num_ch,
3285 : const Word16 num_dmx,
3286 : const Word16 band_idx,
3287 : const Word16 dtx_vad,
3288 : const Word16 compute_p_flag,
3289 : const Word16 dyn_active_w_flag )
3290 : {
3291 : Word16 i, j, q_postpred_cov_re;
3292 : Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
3293 :
3294 2495956 : q_postpred_cov_re = 0;
3295 2495956 : move16();
3296 :
3297 29951472 : FOR( i = 0; i < IVAS_SPAR_MAX_CH; i++ )
3298 : {
3299 27455516 : set_zero_fx( postpred_cov_re[i], IVAS_SPAR_MAX_CH );
3300 : }
3301 2495956 : IF( NE_16( num_dmx, num_ch ) )
3302 : {
3303 2495956 : ivas_calc_post_pred_per_band_enc_fx( cov_real, q_cov_real, mixer_mat, q_mixer_mat, num_ch, band_idx, postpred_cov_re, &q_postpred_cov_re );
3304 :
3305 2495956 : IF( NE_16( num_dmx, 1 ) )
3306 : {
3307 2023472 : ivas_calc_c_coeffs_per_band_enc_fx( pSparMd, i_ts, postpred_cov_re, q_postpred_cov_re, num_ch, num_dmx, band_idx, dtx_vad );
3308 : }
3309 :
3310 2495956 : IF( dyn_active_w_flag )
3311 : {
3312 0 : FOR( i = 0; i < sub( num_ch, num_dmx ); i++ )
3313 : {
3314 0 : FOR( j = 0; j < sub( num_dmx, 1 ); j++ )
3315 : {
3316 0 : pSparMd->band_coeffs[band_idx + ( i_ts * IVAS_MAX_NUM_BANDS )].C_re_fx[i][j] = 0;
3317 0 : move32();
3318 : }
3319 : }
3320 0 : pSparMd->band_coeffs[band_idx + ( i_ts * IVAS_MAX_NUM_BANDS )].q_C_re_fx = 0;
3321 0 : move16();
3322 : }
3323 2495956 : IF( EQ_16( compute_p_flag, 1 ) )
3324 : {
3325 1633334 : ivas_calc_p_coeffs_per_band_enc_fx( pSparMd, i_ts, postpred_cov_re, q_postpred_cov_re, num_ch, dtx_vad, num_dmx, band_idx );
3326 : }
3327 :
3328 2495956 : IF( dyn_active_w_flag )
3329 : {
3330 0 : FOR( i = num_dmx; i < num_ch; i++ )
3331 : {
3332 0 : pSparMd->band_coeffs[band_idx + ( i_ts * IVAS_MAX_NUM_BANDS )].P_re_fx[i - num_dmx] = 0;
3333 0 : move32();
3334 : }
3335 0 : pSparMd->band_coeffs[band_idx + ( i_ts * IVAS_MAX_NUM_BANDS )].q_P_re_fx = 0;
3336 0 : move16();
3337 : }
3338 : }
3339 :
3340 2495956 : return;
3341 : }
3342 :
3343 1809328 : void ivas_calc_c_p_coeffs_fx(
3344 : ivas_spar_md_t *pSparMd,
3345 : Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_cov_real*/
3346 : Word16 q_cov_real,
3347 : const Word16 i_ts,
3348 : Word32 ***mixer_mat, /*q_mixer_mat*/
3349 : Word16 q_mixer_mat,
3350 : const Word16 num_ch,
3351 : const Word16 num_dmx,
3352 : const Word16 band_idx,
3353 : const Word16 dtx_vad,
3354 : const Word16 compute_p_flag,
3355 : const Word16 dyn_active_w_flag )
3356 : {
3357 : Word16 i, j, q_postpred_cov_re;
3358 : Word32 postpred_cov_re[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
3359 :
3360 1809328 : IF( NE_16( num_dmx, num_ch ) )
3361 : {
3362 1809328 : ivas_calc_post_pred_per_band_fx( cov_real, q_cov_real, mixer_mat, q_mixer_mat, num_ch, band_idx, postpred_cov_re, &q_postpred_cov_re );
3363 :
3364 1809328 : IF( NE_16( num_dmx, 1 ) )
3365 : {
3366 1361140 : ivas_calc_c_coeffs_per_band_fx( pSparMd, i_ts, postpred_cov_re, q_postpred_cov_re, num_ch, num_dmx, band_idx, dtx_vad );
3367 : }
3368 :
3369 1809328 : IF( dyn_active_w_flag )
3370 : {
3371 0 : FOR( i = 0; i < sub( num_ch, num_dmx ); i++ )
3372 : {
3373 0 : FOR( j = 0; j < sub( num_dmx, 1 ); j++ )
3374 : {
3375 0 : pSparMd->band_coeffs[band_idx + ( i_ts * IVAS_MAX_NUM_BANDS )].C_re_fx[i][j] = 0;
3376 0 : move32();
3377 : }
3378 : }
3379 0 : pSparMd->band_coeffs[band_idx + ( i_ts * IVAS_MAX_NUM_BANDS )].q_C_re_fx = 0;
3380 0 : move16();
3381 : }
3382 1809328 : IF( EQ_16( compute_p_flag, 1 ) )
3383 : {
3384 1809328 : ivas_calc_p_coeffs_per_band_fx( pSparMd, i_ts, postpred_cov_re, q_postpred_cov_re, num_ch, dtx_vad, num_dmx, band_idx );
3385 : }
3386 :
3387 1809328 : IF( dyn_active_w_flag )
3388 : {
3389 0 : FOR( i = num_dmx; i < num_ch; i++ )
3390 : {
3391 0 : pSparMd->band_coeffs[band_idx + ( i_ts * IVAS_MAX_NUM_BANDS )].P_re_fx[i - num_dmx] = 0;
3392 0 : move32();
3393 : }
3394 0 : pSparMd->band_coeffs[band_idx + ( i_ts * IVAS_MAX_NUM_BANDS )].q_P_re_fx = 0;
3395 0 : move16();
3396 : }
3397 : }
3398 :
3399 1809328 : return;
3400 : }
3401 :
3402 :
3403 9705310 : static void ivas_calc_mat_det_fx(
3404 : Word32 in_re[MAX_MAT_DIM][MAX_MAT_DIM], /*q_in_re*/
3405 : Word16 q_in_re,
3406 : const Word16 dim,
3407 : Word64 *det_re, /*q_det_re*/
3408 : Word16 *q_det_re )
3409 : {
3410 9705310 : IF( EQ_16( dim, IVAS_MAT_DIM_3 ) )
3411 : {
3412 : Word64 re1, re2, re;
3413 1044480 : re1 = W_mult0_32_32( in_re[1][1], in_re[2][2] ); /* 2*q_in_re */
3414 1044480 : re2 = W_mult0_32_32( in_re[1][2], in_re[2][1] ); /* 2*q_in_re */
3415 1044480 : re = W_sub_nosat( re1, re2 ); /* 2*q_in_re */
3416 :
3417 1044480 : re1 = W_mult0_32_32( in_re[0][0], W_extract_h( re ) ); /* 3*q_in_re - 32 */
3418 :
3419 1044480 : *det_re = re1; /* 3*q_in_re - 32 */
3420 1044480 : move64();
3421 :
3422 1044480 : re1 = W_mult0_32_32( in_re[1][0], in_re[2][2] ); /* 2*q_in_re */
3423 1044480 : re2 = W_mult0_32_32( in_re[1][2], in_re[2][0] ); /* 2*q_in_re */
3424 1044480 : re = W_sub_nosat( re1, re2 ); /* 2*q_in_re */
3425 :
3426 1044480 : re1 = W_mult0_32_32( in_re[0][1], W_extract_h( re ) ); /* 3*q_in_re - 32 */
3427 :
3428 1044480 : *det_re = W_sub_nosat( *det_re, re1 ); /* 3*q_in_re - 32 */
3429 1044480 : move64();
3430 :
3431 1044480 : re1 = W_mult0_32_32( in_re[1][0], in_re[2][1] ); /* 2*q_in_re */
3432 1044480 : re2 = W_mult0_32_32( in_re[1][1], in_re[2][0] ); /* 2*q_in_re */
3433 1044480 : re = W_sub_nosat( re1, re2 ); /* 2*q_in_re */
3434 :
3435 1044480 : re1 = W_mult0_32_32( in_re[0][2], W_extract_h( re ) ); /* 3*q_in_re - 32 */
3436 :
3437 1044480 : *det_re = W_add_nosat( *det_re, re1 ); /* 3*q_in_re - 32 */
3438 1044480 : move64();
3439 :
3440 1044480 : *q_det_re = add( q_in_re, sub( add( q_in_re, q_in_re ), 32 ) );
3441 1044480 : move16();
3442 : }
3443 8660830 : ELSE IF( EQ_16( dim, IVAS_MAT_DIM_2 ) )
3444 : {
3445 : Word64 re1, re2;
3446 7162701 : re1 = W_mult0_32_32( in_re[0][0], in_re[1][1] ); /* 2*q_in_re */
3447 7162701 : re2 = W_mult0_32_32( in_re[0][1], in_re[1][0] ); /* 2*q_in_re */
3448 7162701 : *det_re = W_sub_nosat( re1, re2 ); /* 2*q_in_re */
3449 7162701 : move64();
3450 7162701 : *q_det_re = add( q_in_re, q_in_re );
3451 7162701 : move16();
3452 : }
3453 1498129 : ELSE IF( EQ_16( dim, IVAS_MAT_DIM_1 ) )
3454 : {
3455 1498129 : *det_re = in_re[0][0]; /*q_in_re*/
3456 1498129 : move32();
3457 1498129 : *q_det_re = q_in_re;
3458 1498129 : move16();
3459 : }
3460 : ELSE
3461 : {
3462 0 : assert( !"matrix dimention not supported!" );
3463 : }
3464 :
3465 9705310 : return;
3466 : }
3467 :
3468 :
3469 : /*-----------------------------------------------------------------------------------------*
3470 : * Function ivas_get_mat_cofactor()
3471 : *
3472 : * Calculate cofactor for invert matrix
3473 : *-----------------------------------------------------------------------------------------*/
3474 :
3475 :
3476 4700160 : static void ivas_get_mat_cofactor_fx(
3477 : Word32 in_re[MAX_MAT_DIM][MAX_MAT_DIM], /*qx*/
3478 : Word32 out_re[MAX_MAT_DIM][MAX_MAT_DIM], /*qx*/
3479 : const Word16 row,
3480 : const Word16 col )
3481 : {
3482 : Word16 i, j;
3483 4700160 : Word16 r = 0, c = 0;
3484 4700160 : move16();
3485 4700160 : move16();
3486 :
3487 18800640 : FOR( i = 0; i < MAX_MAT_DIM; i++ )
3488 : {
3489 56401920 : FOR( j = 0; j < MAX_MAT_DIM; j++ )
3490 : {
3491 42301440 : test();
3492 42301440 : IF( NE_16( i, row ) && NE_16( j, col ) )
3493 : {
3494 18800640 : out_re[r][c] = in_re[i][j]; /*qx*/
3495 18800640 : move64();
3496 18800640 : c = add( c, 1 );
3497 : }
3498 : }
3499 14100480 : IF( EQ_16( c, 2 ) )
3500 : {
3501 9400320 : r = add( r, 1 );
3502 9400320 : c = 0;
3503 9400320 : move16();
3504 : }
3505 : }
3506 :
3507 4700160 : return;
3508 : }
3509 :
3510 :
3511 : /*-----------------------------------------------------------------------------------------*
3512 : * Function ivas_calc_mat_inv()
3513 : *
3514 : * Calculate Invert of a matrix
3515 : *-----------------------------------------------------------------------------------------*/
3516 :
3517 :
3518 3251614 : static void ivas_calc_mat_inv_fx(
3519 : Word32 in_re[MAX_MAT_DIM][MAX_MAT_DIM], /*q_in_re*/
3520 : Word16 q_in_re,
3521 : const Word16 dim,
3522 : Word32 out_re[MAX_MAT_DIM][MAX_MAT_DIM], /*q_out_re*/
3523 : Word16 *q_out_re )
3524 : {
3525 : Word64 det;
3526 : Word16 one_by_det, q_one_by_det;
3527 : Word16 i, j, q_tmp;
3528 :
3529 3251614 : IF( EQ_16( dim, IVAS_MAT_DIM_1 ) )
3530 : {
3531 1498129 : det = W_mult0_32_32( in_re[0][0], in_re[0][0] ); /* 2*q_in_re */
3532 : /* assert to catch cases when input is singular matrix*/
3533 1498129 : assert( det > 0 );
3534 :
3535 : // det = (dbl_in_re[0][0] * dbl_in_re[0][0]);
3536 : // det = 1 / det = 1 / (dbl_in_re[0][0] * dbl_in_re[0][0]);
3537 : // dbl_out_re[0][0] = dbl_in_re[0][0] * det = dbl_in_re[0][0] * (1 / (dbl_in_re[0][0] * dbl_in_re[0][0]));
3538 : // dbl_out_re[0][0] = 1 / dbl_in_re[0][0];
3539 :
3540 1498129 : one_by_det = BASOP_Util_Divide3232_Scale( 1, in_re[0][0], &q_tmp ); /*q=15-(q_tmp-(0-q_in_re))*/
3541 1498129 : q_one_by_det = sub( 15, add( q_tmp, q_in_re ) );
3542 :
3543 1498129 : out_re[0][0] = one_by_det; /*q=q_one_by_det*/
3544 1498129 : move32();
3545 1498129 : *q_out_re = q_one_by_det;
3546 1498129 : move16();
3547 : }
3548 1753485 : ELSE IF( EQ_16( dim, IVAS_MAT_DIM_2 ) )
3549 : {
3550 : Word64 det_re;
3551 : Word16 q_det_re;
3552 :
3553 1231245 : ivas_calc_mat_det_fx( in_re, q_in_re, dim, &det_re, &q_det_re );
3554 1231245 : q_tmp = W_norm( det_re );
3555 1231245 : q_tmp = s_max( sub( 32, q_tmp ), 0 );
3556 :
3557 1231245 : det_re = W_shr( det_re, q_tmp ); /*q_det_re-q_tmp*/
3558 1231245 : q_det_re = sub( q_det_re, q_tmp );
3559 :
3560 1231245 : det = W_mult0_32_32( W_extract_l( det_re ), W_extract_l( det_re ) ); /* 2*q_det_re */
3561 : /* assert to catch cases when input is singular matrix*/
3562 1231245 : assert( det > 0 );
3563 :
3564 1231245 : one_by_det = BASOP_Util_Divide3232_Scale( 1, W_extract_l( det_re ), &q_tmp ); // Q = (15 - (q_tmp + q_det_re))
3565 :
3566 1231245 : out_re[0][0] = Mpy_32_16_1( in_re[1][1], one_by_det ); /*q_in_re+(15 - (q_tmp + q_det_re)) -15=>q_in_re-(q_tmp + q_det_re)*/
3567 :
3568 1231245 : out_re[0][1] = L_negate( Mpy_32_16_1( in_re[0][1], one_by_det ) ); /*q_in_re-(q_tmp + q_det_re)*/
3569 :
3570 1231245 : out_re[1][0] = L_negate( Mpy_32_16_1( in_re[1][0], one_by_det ) ); /*q_in_re-(q_tmp + q_det_re)*/
3571 :
3572 1231245 : out_re[1][1] = Mpy_32_16_1( in_re[0][0], one_by_det ); /*q_in_re-(q_tmp + q_det_re)*/
3573 1231245 : move32();
3574 1231245 : move32();
3575 1231245 : move32();
3576 1231245 : move32();
3577 :
3578 1231245 : *q_out_re = sub( q_in_re, add( q_tmp, q_det_re ) ); // Q = (15-(q_tmp + q_det_re)) + q_in_re - 15
3579 1231245 : move16();
3580 : }
3581 522240 : ELSE IF( EQ_16( dim, IVAS_MAT_DIM_3 ) )
3582 : {
3583 : Word32 fac_re[IVAS_MAT_DIM_3][IVAS_MAT_DIM_3];
3584 : Word64 det_re, W_tmp;
3585 522240 : Word16 q_det_re, q_W_tmp = 0;
3586 522240 : move16();
3587 522240 : Word16 sign = 1;
3588 522240 : move16();
3589 :
3590 522240 : ivas_calc_mat_det_fx( in_re, q_in_re, dim, &det_re, &q_det_re );
3591 522240 : q_tmp = W_norm( det_re );
3592 522240 : q_tmp = s_max( sub( 32, q_tmp ), 0 );
3593 :
3594 522240 : det_re = W_shr( det_re, q_tmp ); /*q_det_re-q_tmp*/
3595 522240 : q_det_re = sub( q_det_re, q_tmp );
3596 :
3597 522240 : if ( det_re == 0 )
3598 : {
3599 226 : det_re = 1;
3600 226 : move64();
3601 : }
3602 :
3603 522240 : one_by_det = BASOP_Util_Divide3232_Scale( 1, W_extract_l( det_re ), &q_tmp ); /*15-(q_tmp-(0-q_det_re))*/
3604 522240 : q_one_by_det = sub( 15, add( q_tmp, q_det_re ) );
3605 :
3606 2088960 : FOR( i = 0; i < dim; i++ )
3607 : {
3608 6266880 : FOR( j = 0; j < dim; j++ )
3609 : {
3610 4700160 : ivas_get_mat_cofactor_fx( in_re, fac_re, i, j );
3611 4700160 : ivas_calc_mat_det_fx( fac_re, q_in_re, IVAS_MAT_DIM_2, &W_tmp, &q_W_tmp );
3612 :
3613 4700160 : out_re[j][i] = Mpy_32_16_1( W_extract_h( W_tmp ), one_by_det ); /*q_W_tmp-32+q_one_by_det-15*/
3614 4700160 : move32();
3615 4700160 : out_re[j][i] = W_extract_l( W_mult0_32_32( out_re[j][i], sign ) ); /*q_W_tmp-32+q_one_by_det-15*/
3616 4700160 : move32();
3617 :
3618 4700160 : IF( s_and( add( i, j ), 1 ) == 0 )
3619 : {
3620 2611200 : sign = -1;
3621 2611200 : move16();
3622 : }
3623 : ELSE
3624 : {
3625 2088960 : sign = 1;
3626 2088960 : move16();
3627 : }
3628 : }
3629 : }
3630 522240 : *q_out_re = sub( add( sub( q_W_tmp, 32 ), q_one_by_det ), 15 );
3631 522240 : move16();
3632 : }
3633 : ELSE
3634 : {
3635 0 : assert( !"matrix dimension not supported!" );
3636 : }
3637 :
3638 3251614 : return;
3639 : }
3640 :
3641 :
3642 : /*-----------------------------------------------------------------------------------------*
3643 : * Function ivas_is_mat_inv()
3644 : *
3645 : * Check if matrix is invertible or not by checking if determinant is 0 or very close to 0
3646 : *-----------------------------------------------------------------------------------------*/
3647 :
3648 :
3649 3251665 : static Word16 ivas_is_mat_inv_fx(
3650 : Word32 in_re[MAX_MAT_DIM][MAX_MAT_DIM], /*q_in_re*/
3651 : Word16 q_in_re,
3652 : const Word16 dim )
3653 : {
3654 3251665 : Word16 is_det_zero = 0, q_det_re = 0, tmp;
3655 3251665 : move16();
3656 3251665 : move16();
3657 : Word64 det, det_re;
3658 :
3659 3251665 : ivas_calc_mat_det_fx( in_re, q_in_re, dim, &det_re, &q_det_re );
3660 :
3661 3251665 : tmp = W_norm( det_re );
3662 3251665 : tmp = s_max( sub( 32, tmp ), 0 );
3663 :
3664 3251665 : det_re = W_shr( det_re, tmp ); /*q_det_re-tmp*/
3665 3251665 : q_det_re = sub( q_det_re, tmp );
3666 :
3667 3251665 : det = W_mult0_32_32( W_extract_l( det_re ), W_extract_l( det_re ) ); /*2*q_det_re*/
3668 :
3669 3251665 : if ( LE_64( det, IVAS_FIX_EPS ) )
3670 : {
3671 277 : is_det_zero = 1;
3672 277 : move16();
3673 : }
3674 :
3675 3251665 : return is_det_zero;
3676 : }
3677 :
3678 :
3679 : /*-----------------------------------------------------------------------------------------*
3680 : * Function ivas_compute_spar_params()
3681 : *
3682 : *
3683 : *-----------------------------------------------------------------------------------------*/
3684 :
3685 :
3686 311060 : void ivas_compute_spar_params_enc_fx(
3687 : Word32 *cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_cov_real*/
3688 : Word16 *q_cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH],
3689 : Word32 dm_fv_re_fx[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_dm_fv_re*/
3690 : Word16 *q_dm_fv_re,
3691 : const Word16 i_ts,
3692 : Word32 ***mixer_mat_fx, /*q_mixer_mat*/
3693 : Word16 *q_mixer_mat,
3694 : const Word16 start_band,
3695 : const Word16 end_band,
3696 : const Word16 dtx_vad,
3697 : const Word16 num_ch,
3698 : const Word16 bands_bw,
3699 : const Word16 active_w,
3700 : const Word16 active_w_vlbr,
3701 : ivas_spar_md_com_cfg *hSparCfg,
3702 : ivas_spar_md_t *hSparMd,
3703 : Word32 *pWscale, /*q_Wscale*/
3704 : Word16 *q_Wscale,
3705 : const Word16 from_dirac,
3706 : const Word16 dyn_active_w_flag )
3707 : {
3708 : Word16 b, i, ndm;
3709 : Word16 q_pred_coeffs_re;
3710 : Word32 pred_coeffs_re_fx[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS];
3711 :
3712 311060 : ivas_get_pred_coeffs_enc_fx( cov_real_fx, q_cov_real, pred_coeffs_re_fx, &q_pred_coeffs_re, dm_fv_re_fx, q_dm_fv_re, num_ch, start_band, end_band, active_w, active_w_vlbr, dtx_vad, from_dirac, dyn_active_w_flag, hSparMd->res_ind );
3713 :
3714 311060 : ivas_create_fullr_dmx_mat_fx( pred_coeffs_re_fx, q_pred_coeffs_re, dm_fv_re_fx, *q_dm_fv_re, mixer_mat_fx, q_mixer_mat, num_ch, start_band, end_band, active_w, hSparCfg );
3715 :
3716 311060 : ivas_get_Wscaling_factor_enc_fx( cov_real_fx, q_cov_real, pred_coeffs_re_fx, q_pred_coeffs_re, mixer_mat_fx, *q_mixer_mat, start_band, end_band, dtx_vad, num_ch, hSparCfg->num_dmx_chans_per_band, bands_bw, active_w, active_w_vlbr, pWscale, q_Wscale, dyn_active_w_flag );
3717 :
3718 2272754 : FOR( b = start_band; b < end_band; b++ )
3719 : {
3720 : Word16 tmp_exp, q_tmp, tmp;
3721 1961694 : IF( pWscale[b] == 0 )
3722 : {
3723 0 : pWscale[b] = 1;
3724 0 : move32();
3725 0 : q_Wscale[b] = Q31;
3726 0 : move16();
3727 : }
3728 :
3729 1961694 : Word16 onebyscale_fx = BASOP_Util_Divide3232_Scale( 1, pWscale[b], &tmp_exp ); /*q=15-(tmp_exp+(15-(15-q_Wscale)))=>15-(tmp_exp+q_Wscale)*/
3730 1961694 : q_tmp = sub( sub( 15, tmp_exp ), q_Wscale[b] );
3731 :
3732 1961694 : tmp = sub( add( q_pred_coeffs_re, q_tmp ), 15 );
3733 9073176 : FOR( i = 0; i < sub( num_ch, 1 ); i++ )
3734 : {
3735 7111482 : hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i] = L_shl( Mpy_32_16_1( pred_coeffs_re_fx[i][b], onebyscale_fx ), sub( Q28, tmp ) ); // Q28
3736 7111482 : move32();
3737 : }
3738 : // hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].q_pred_re_fx = sub(add(q_pred_coeffs, q_tmp), 15);
3739 1961694 : hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].q_pred_re_fx = Q28;
3740 1961694 : move16();
3741 :
3742 11034870 : FOR( i = 0; i < num_ch; i++ )
3743 : {
3744 9073176 : mixer_mat_fx[0][i][b] = W_extract_l( W_shr( W_mult0_32_32( mixer_mat_fx[0][i][b], pWscale[b] ), q_Wscale[b] ) ); /*q_mixer_mat*/
3745 9073176 : move32();
3746 : }
3747 : }
3748 :
3749 2272754 : FOR( b = start_band; b < end_band; b++ )
3750 : {
3751 1961694 : ndm = hSparCfg->num_dmx_chans_per_band[( b * bands_bw )];
3752 1961694 : move16();
3753 :
3754 1961694 : IF( NE_16( ndm, num_ch ) )
3755 : {
3756 1633334 : ivas_calc_c_p_coeffs_enc_fx( hSparMd, cov_real_fx, q_cov_real, i_ts, mixer_mat_fx, *q_mixer_mat, num_ch, ndm, b, dtx_vad, 1, dyn_active_w_flag );
3757 : }
3758 : }
3759 :
3760 311060 : return;
3761 : }
3762 :
3763 :
3764 619367 : void ivas_compute_spar_params_fx(
3765 : Word32 *cov_real[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH], /*q_cov_real*/
3766 : Word16 q_cov_real,
3767 : Word32 dm_fv_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS], /*q_dm_fv_re*/
3768 : Word16 *q_dm_fv_re,
3769 : const Word16 i_ts,
3770 : Word32 ***mixer_mat_fx, /*q_mixer_mat*/
3771 : Word16 *q_mixer_mat,
3772 : const Word16 start_band,
3773 : const Word16 end_band,
3774 : const Word16 dtx_vad,
3775 : const Word16 num_ch,
3776 : const Word16 bands_bw,
3777 : const Word16 active_w,
3778 : const Word16 active_w_vlbr,
3779 : ivas_spar_md_com_cfg *hSparCfg,
3780 : ivas_spar_md_t *hSparMd,
3781 : Word32 *pWscale_fx, /*q_pWscale*/
3782 : Word16 *q_pWscale,
3783 : const Word16 from_dirac,
3784 : const Word16 dyn_active_w_flag )
3785 : {
3786 : Word32 pred_coeffs_re[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS];
3787 :
3788 : Word16 b, i, ndm, j;
3789 : Word16 q_pred_coeffs;
3790 :
3791 619367 : ivas_get_pred_coeffs_fx( cov_real, pred_coeffs_re, dm_fv_re, num_ch, start_band, end_band, active_w, active_w_vlbr, dtx_vad, from_dirac, dyn_active_w_flag, hSparMd->res_ind, &q_pred_coeffs, q_dm_fv_re );
3792 :
3793 619367 : ivas_create_fullr_dmx_mat_fx( pred_coeffs_re, q_pred_coeffs, dm_fv_re, *q_dm_fv_re, mixer_mat_fx, q_mixer_mat, num_ch, start_band, end_band, active_w, hSparCfg );
3794 :
3795 619367 : ivas_get_Wscaling_factor_fx( cov_real, q_cov_real, pred_coeffs_re, q_pred_coeffs, mixer_mat_fx, *q_mixer_mat, start_band, end_band, dtx_vad, num_ch, hSparCfg->num_dmx_chans_per_band, bands_bw, active_w, active_w_vlbr, pWscale_fx, q_pWscale, dyn_active_w_flag );
3796 :
3797 2988155 : FOR( b = start_band; b < end_band; b++ )
3798 : {
3799 : Word16 tmp_exp, q_tmp, tmp;
3800 2368788 : Word16 onebyscale_fx = BASOP_Util_Divide3232_Scale( 1, pWscale_fx[b], &tmp_exp ); /*15-(tmp_exp+q_pWscale[b])*/
3801 2368788 : q_tmp = sub( sub( 15, tmp_exp ), q_pWscale[b] );
3802 :
3803 2368788 : tmp = sub( add( q_pred_coeffs, q_tmp ), 15 );
3804 9475152 : FOR( i = 0; i < sub( num_ch, 1 ); i++ )
3805 : {
3806 7106364 : hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i] = Mpy_32_16_1( pred_coeffs_re[i][b], onebyscale_fx ); // q=tmp
3807 7106364 : move32();
3808 7106364 : IF( tmp < 0 )
3809 : {
3810 0 : tmp = negate( tmp );
3811 0 : hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i] = L_shl( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i], add( tmp, 22 ) ); // q22
3812 0 : move32();
3813 : }
3814 : ELSE
3815 : {
3816 7106364 : hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i] = L_shr_r( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].pred_re_fx[i], sub( tmp, 22 ) ); // q22
3817 7106364 : move32();
3818 : }
3819 : }
3820 : // hSparMd->band_coeffs[b + i_ts * IVAS_MAX_NUM_BANDS].q_pred_re_fx = sub(add(q_pred_coeffs, q_tmp), 15);
3821 2368788 : hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].q_pred_re_fx = Q22;
3822 2368788 : move16();
3823 :
3824 11843940 : FOR( i = 0; i < num_ch; i++ )
3825 : {
3826 9475152 : mixer_mat_fx[0][i][b] = W_extract_l( W_shr( W_mult0_32_32( mixer_mat_fx[0][i][b], pWscale_fx[b] ), q_pWscale[b] ) ); /*q_mixer_mat*/
3827 9475152 : move32();
3828 : }
3829 : }
3830 :
3831 2988155 : FOR( b = start_band; b < end_band; b++ )
3832 : {
3833 2368788 : ndm = hSparCfg->num_dmx_chans_per_band[b * bands_bw];
3834 2368788 : move16();
3835 :
3836 2368788 : IF( NE_16( ndm, num_ch ) )
3837 : {
3838 1809328 : ivas_calc_c_p_coeffs_fx( hSparMd, cov_real, q_cov_real, i_ts, mixer_mat_fx, *q_mixer_mat, num_ch, ndm, b, dtx_vad, 1, dyn_active_w_flag );
3839 :
3840 1809328 : Word16 q_tmp = hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].q_C_re_fx;
3841 1809328 : IF( NE_16( ndm, 1 ) )
3842 : {
3843 3472820 : FOR( i = 0; i < ( num_ch - ndm ); i++ )
3844 : {
3845 4833960 : FOR( j = 0; j < sub( ndm, 1 ); j++ )
3846 : {
3847 2722280 : hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].C_re_fx[i][j] = L_shr( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].C_re_fx[i][j], sub( q_tmp, 22 ) ); // q22
3848 2722280 : move32();
3849 : }
3850 : }
3851 1361140 : hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].q_C_re_fx = Q22;
3852 1361140 : move16();
3853 : }
3854 :
3855 1809328 : q_tmp = hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].q_P_re_fx;
3856 1809328 : move16();
3857 :
3858 19902608 : FOR( j = 0; j < sub( IVAS_SPAR_MAX_CH, 1 ); j++ )
3859 : {
3860 18093280 : hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].P_re_fx[j] = L_shr( hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].P_re_fx[j], sub( q_tmp, 22 ) ); // q22
3861 18093280 : move32();
3862 : }
3863 1809328 : hSparMd->band_coeffs[b + ( i_ts * IVAS_MAX_NUM_BANDS )].q_P_re_fx = Q22;
3864 1809328 : move16();
3865 : }
3866 : }
3867 :
3868 619367 : return;
3869 : }
3870 :
3871 :
3872 : /*-----------------------------------------------------------------------------------------*
3873 : * Function ivas_get_spar_md_from_dirac_fx()
3874 : *
3875 : *
3876 : *-----------------------------------------------------------------------------------------*/
3877 : Word32 diff_norm_order1_table[4] = { 0, 805306368, 402653184, 268435456 }; // q28
3878 : Word32 diff_norm_order2_table[6] = { 0, 1342177280, 671088640, 447392416, 335544320, 268435456 }; // q28
3879 : Word32 diff_norm_order3_table[8] = { 0, 1879048192, 939524096, 626349376, 469762048, 375809632, 313174688, 268435456 }; // q28
3880 : #define EPSILON_FX_SHIFT 6
3881 : #define EPSILON_FX_THR ( 1 << EPSILON_FX_SHIFT )
3882 : #define ONE_BY_THREE_Q31 715827882
3883 : #define ONE_BY_FIVE_Q31 429496729
3884 : #define ONE_BY_SEVEN_Q31 306783378
3885 :
3886 150560 : void ivas_get_spar_md_from_dirac_enc_fx(
3887 : Word32 azi_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], // Q22
3888 : Word32 ele_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], // Q22
3889 : Word32 diffuseness_fx[IVAS_MAX_NUM_BANDS], // Q30
3890 : const Word16 n_ts,
3891 : Word32 ***mixer_mat_fx, /*q_mixer_mat_fx*/
3892 : Word16 *q_mixer_mat_fx,
3893 : ivas_spar_md_t *hSpar_md,
3894 : ivas_spar_md_com_cfg *hSpar_md_cfg,
3895 : const Word16 start_band,
3896 : const Word16 end_band,
3897 : const Word16 order,
3898 : const Word16 dtx_vad,
3899 : Word32 Wscale_d[IVAS_MAX_NUM_BANDS], // Q29
3900 : const UWord8 useLowerRes,
3901 : const Word16 active_w_vlbr,
3902 : const Word16 dyn_active_w_flag )
3903 : {
3904 :
3905 : Word16 num_ch, band, i, j;
3906 : Word16 block, ch;
3907 : Word16 azimuth, elevation;
3908 :
3909 : Word32 response_avg_fx[MAX_OUTPUT_CHANNELS];
3910 : Word32 response_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MAX_OUTPUT_CHANNELS];
3911 : Word32 cov_real_dirac_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS];
3912 : Word16 q_cov_real_dirac_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS];
3913 : Word32 *pCov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
3914 : Word16 *p_q_Cov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
3915 : Word32 dm_fv_re_fx[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS];
3916 150560 : Word16 q_dm_fv_re_fx = 0;
3917 : Word16 q_Wscale[IVAS_MAX_NUM_BANDS];
3918 : Word32 Wscale_fx[IVAS_MAX_NUM_BANDS];
3919 : Word32 mixer_mat_local_fx[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH][IVAS_MAX_NUM_BANDS];
3920 : Word32 **ppMixer_mat_fx[IVAS_MAX_FB_MIXER_OUT_CH];
3921 : Word32 *pMixer_mat_fx[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH];
3922 150560 : Word16 q_ppMixer_mat = 0;
3923 : Word32 en_ratio_fac_fx, diff_norm_order1_fx, diff_norm_order2_fx, diff_norm_order3_fx;
3924 : Word16 active_w;
3925 150560 : move16();
3926 150560 : move16();
3927 :
3928 : Word16 ndm, foa_ch, hoa2_ch;
3929 : Word32 P_dir_fact_fx[IVAS_SPAR_MAX_CH - 1];
3930 : const Word16 *remix_order;
3931 :
3932 150560 : set16_fx( q_Wscale, 0, IVAS_MAX_NUM_BANDS );
3933 150560 : set32_fx( Wscale_fx, 0, IVAS_MAX_NUM_BANDS );
3934 150560 : remix_order = remix_order_set[hSpar_md_cfg->remix_unmix_order];
3935 :
3936 150560 : num_ch = ivas_sba_get_nchan_metadata_fx( order, IVAS_256k /*dummy value as order is always 1 in this function*/ );
3937 :
3938 150560 : hoa2_ch = ivas_sba_get_nchan_metadata_fx( SBA_HOA2_ORDER, IVAS_256k /*dummy value as order is always 1 in this function*/ );
3939 150560 : foa_ch = FOA_CHANNELS;
3940 150560 : move16();
3941 150560 : diff_norm_order1_fx = 3;
3942 150560 : move32();
3943 150560 : diff_norm_order2_fx = 5;
3944 150560 : move32();
3945 150560 : diff_norm_order3_fx = 7;
3946 150560 : move32();
3947 :
3948 1806720 : FOR( i = 0; i < IVAS_MAX_FB_MIXER_OUT_CH; i++ )
3949 : {
3950 19873920 : FOR( j = 0; j < IVAS_MAX_SPAR_FB_MIXER_IN_CH; j++ )
3951 : {
3952 18217760 : pMixer_mat_fx[i][j] = mixer_mat_local_fx[i][j];
3953 : }
3954 1656160 : ppMixer_mat_fx[i] = pMixer_mat_fx[i];
3955 : }
3956 :
3957 150560 : test();
3958 150560 : test();
3959 150560 : test();
3960 150560 : test();
3961 150560 : test();
3962 150560 : test();
3963 150560 : IF( ( GE_16( start_band, 6 ) && LE_16( hSpar_md_cfg->nchan_transport, 2 ) && ( EQ_16( dtx_vad, 1 ) ) ) || ( useLowerRes && GE_16( start_band, 3 ) && LE_16( hSpar_md_cfg->nchan_transport, 2 ) && ( EQ_16( dtx_vad, 1 ) ) ) )
3964 : {
3965 : Word32 P_norm_fx[3];
3966 : Word16 idx;
3967 :
3968 83986 : ndm = hSpar_md_cfg->num_dmx_chans_per_band[start_band - 1];
3969 83986 : move16();
3970 83986 : P_norm_fx[0] = 0;
3971 83986 : move32();
3972 83986 : Word16 len = s_max( 0, sub( foa_ch, ndm ) );
3973 295367 : FOR( i = 0; i < len; i++ )
3974 : {
3975 211381 : P_norm_fx[0] = L_add( P_norm_fx[0], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31
3976 211381 : move32();
3977 : }
3978 83986 : P_norm_fx[0] = Mpy_32_32( L_shl( P_norm_fx[0], 3 ), diff_norm_order1_table[min( diff_norm_order1_fx, max( 0, sub( foa_ch, ndm ) ) )] ); // 2*q_P_re - 31
3979 83986 : move32();
3980 :
3981 83986 : P_norm_fx[1] = 0;
3982 83986 : move32();
3983 83986 : len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) );
3984 83986 : FOR( ; i < len; i++ ) // max( 0, ( min( num_ch, hoa2_ch ) - ndm ) )
3985 : {
3986 0 : P_norm_fx[1] = L_add( P_norm_fx[1], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31
3987 0 : move32();
3988 : }
3989 83986 : P_norm_fx[1] = Mpy_32_32( L_shl( P_norm_fx[1], 3 ), diff_norm_order2_table[min( diff_norm_order2_fx, max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) )] ); // 2*q_P_re - 31
3990 83986 : move32();
3991 :
3992 83986 : P_norm_fx[2] = 0;
3993 83986 : move32();
3994 83986 : FOR( ; i < ( num_ch - ndm ); i++ )
3995 : {
3996 0 : P_norm_fx[2] = L_add( P_norm_fx[2], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31
3997 0 : move32();
3998 : }
3999 83986 : P_norm_fx[2] = Mpy_32_32( L_shl( P_norm_fx[2], 3 ), diff_norm_order3_table[min( diff_norm_order3_fx, max( 0, ( num_ch - ndm ) ) )] ); // 2*q_P_re - 31
4000 83986 : move32();
4001 83986 : len = s_max( 0, sub( foa_ch, ndm ) );
4002 295367 : FOR( i = 0; i < len; i++ ) // i < max( 0, ( foa_ch - ndm ) )
4003 : {
4004 211381 : idx = sub( remix_order[i + ndm], ndm );
4005 211381 : P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31
4006 211381 : move32();
4007 211381 : IF( P_dir_fact_fx[idx] != 0 )
4008 : {
4009 193681 : P_dir_fact_fx[idx] = divide3232( P_dir_fact_fx[idx], L_max( P_norm_fx[0], IVAS_FIX_EPS ) ); // q15
4010 193681 : move32();
4011 193681 : P_dir_fact_fx[idx] = L_shl( P_dir_fact_fx[idx], 15 ); // q30
4012 193681 : move32();
4013 : }
4014 : }
4015 83986 : len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) );
4016 83986 : FOR( ; i < len; i++ ) // i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) )
4017 : {
4018 0 : idx = sub( remix_order[i + ndm], ndm );
4019 0 : P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31
4020 0 : IF( P_dir_fact_fx[idx] != 0 )
4021 : {
4022 0 : P_dir_fact_fx[idx] = divide3232( P_dir_fact_fx[idx], L_max( P_norm_fx[1], IVAS_FIX_EPS ) ); // q15
4023 0 : move32();
4024 0 : P_dir_fact_fx[idx] = L_shl( P_dir_fact_fx[idx], 15 ); // q30
4025 0 : move32();
4026 : }
4027 : }
4028 :
4029 83986 : FOR( ; i < ( num_ch - ndm ); i++ )
4030 : {
4031 0 : idx = sub( remix_order[i + ndm], ndm );
4032 0 : P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31
4033 0 : move32();
4034 0 : IF( P_dir_fact_fx[idx] != 0 )
4035 : {
4036 0 : P_dir_fact_fx[idx] = divide3232( P_dir_fact_fx[idx], L_max( P_norm_fx[2], IVAS_FIX_EPS ) ); // q15
4037 0 : move32();
4038 0 : P_dir_fact_fx[idx] = L_shl( P_dir_fact_fx[idx], 15 ); // q30
4039 0 : move32();
4040 : }
4041 : }
4042 : }
4043 :
4044 301120 : FOR( Word16 i_ts = 0; i_ts < n_ts; i_ts++ )
4045 : {
4046 803200 : FOR( band = start_band; band < end_band; band++ )
4047 : {
4048 652640 : ndm = hSpar_md_cfg->num_dmx_chans_per_band[band];
4049 652640 : move16();
4050 :
4051 : /*SPAR from DirAC*/
4052 652640 : set32_fx( response_avg_fx, 0, MAX_OUTPUT_CHANNELS );
4053 :
4054 652640 : IF( GT_16( n_ts, 1 ) )
4055 : {
4056 0 : IF( ele_dirac_fx[band][i_ts] < 0 )
4057 : {
4058 0 : elevation = negate( extract_l( L_shr( L_negate( ele_dirac_fx[band][i_ts] ), Q22 ) ) ); // q0
4059 : }
4060 : ELSE
4061 : {
4062 0 : elevation = extract_l( L_shr( ele_dirac_fx[band][i_ts], Q22 ) ); // q0
4063 : }
4064 0 : IF( azi_dirac_fx[band][i_ts] < 0 )
4065 : {
4066 0 : azimuth = negate( extract_l( L_shr( L_negate( azi_dirac_fx[band][i_ts] ), Q22 ) ) ); // q0
4067 : }
4068 : ELSE
4069 : {
4070 0 : azimuth = extract_l( L_shr( azi_dirac_fx[band][i_ts], Q22 ) ); // q0
4071 : }
4072 0 : ivas_dirac_dec_get_response_fx( azimuth, elevation, response_avg_fx, order, Q30 );
4073 : }
4074 652640 : ELSE IF( useLowerRes )
4075 : {
4076 54212 : IF( ele_dirac_fx[band][0] < 0 )
4077 : {
4078 13092 : elevation = negate( extract_l( L_shr( L_negate( ele_dirac_fx[band][0] ), Q22 ) ) ); // q0
4079 : }
4080 : ELSE
4081 : {
4082 41120 : elevation = extract_l( L_shr( ele_dirac_fx[band][0], Q22 ) ); // q0
4083 : }
4084 54212 : IF( azi_dirac_fx[band][0] < 0 )
4085 : {
4086 31774 : azimuth = negate( extract_l( L_shr( L_negate( azi_dirac_fx[band][0] ), Q22 ) ) ); // q0
4087 : }
4088 : ELSE
4089 : {
4090 22438 : azimuth = extract_l( L_shr( azi_dirac_fx[band][0], Q22 ) ); // q0
4091 : }
4092 54212 : ivas_dirac_dec_get_response_fx( azimuth, elevation, response_avg_fx, order, Q30 );
4093 : }
4094 : ELSE
4095 : {
4096 2992140 : FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
4097 : {
4098 2393712 : IF( ele_dirac_fx[band][block] < 0 )
4099 : {
4100 479326 : elevation = negate( extract_l( L_shr( L_negate( ele_dirac_fx[band][block] ), Q22 ) ) ); // q0
4101 : }
4102 : ELSE
4103 : {
4104 1914386 : elevation = extract_l( L_shr( ele_dirac_fx[band][block], Q22 ) ); // q0
4105 : }
4106 2393712 : IF( azi_dirac_fx[band][block] < 0 )
4107 : {
4108 1156534 : azimuth = negate( extract_l( L_shr( L_negate( azi_dirac_fx[band][block] ), Q22 ) ) ); // q0
4109 : }
4110 : ELSE
4111 : {
4112 1237178 : azimuth = extract_l( L_shr( azi_dirac_fx[band][block], Q22 ) ); // q0
4113 : }
4114 2393712 : ivas_dirac_dec_get_response_fx( azimuth, elevation, &( response_fx[block][0] ), order, Q30 );
4115 : }
4116 :
4117 : /* average responses in all subframes*/
4118 : {
4119 : Word32 norm_fx;
4120 : Word16 norm_q;
4121 :
4122 : Word16 num_ch_order, norm_t;
4123 : Word32 tmp_norm_out;
4124 :
4125 598428 : num_ch_order = ivas_sba_get_nchan_fx( order, 0 );
4126 598428 : assert( order == 1 );
4127 :
4128 2992140 : FOR( ch = 0; ch < num_ch_order; ch++ )
4129 : {
4130 2393712 : Word64 temp = 0;
4131 2393712 : move64();
4132 11968560 : FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
4133 : {
4134 9574848 : temp = W_add( temp, W_deposit32_l( response_fx[block][ch] ) ); // q30
4135 : }
4136 2393712 : response_avg_fx[ch] = W_extract_l( W_shr( temp, 2 ) ); // q30
4137 2393712 : move32();
4138 : }
4139 :
4140 : /*normalize 1st order*/
4141 598428 : norm_t = L_norm_arr( &response_avg_fx[1], sub( foa_ch, 1 ) );
4142 598428 : norm_t = sub( norm_t, 1 );
4143 598428 : scale_sig32( &response_avg_fx[1], sub( foa_ch, 1 ), norm_t );
4144 598428 : norm_fx = 0;
4145 598428 : move32();
4146 2393712 : FOR( ch = 1; ch < foa_ch; ch++ )
4147 : {
4148 1795284 : norm_fx = L_add( norm_fx, Mpy_32_32( response_avg_fx[ch], response_avg_fx[ch] ) ); // q29
4149 : }
4150 :
4151 598428 : norm_q = sub( 31, ( sub( add( 30, 30 ), 31 ) ) );
4152 598428 : norm_fx = Sqrt32( norm_fx, &norm_q ); // q=31-norm_q
4153 598428 : IF( norm_q <= 0 )
4154 : {
4155 492314 : norm_fx = L_shr( norm_fx, ( negate( norm_q ) ) ); // q=31
4156 492314 : norm_q = 0;
4157 492314 : move16();
4158 : }
4159 598428 : norm_fx = L_shr( norm_fx, sub( 1, norm_q ) ); // q30
4160 :
4161 598428 : IF( LT_32( norm_fx, EPSILON_FX_THR ) )
4162 : {
4163 0 : FOR( ch = 1; ch < foa_ch; ch++ )
4164 : {
4165 : /*when control comes here, response_avg_fx[ch] should be less than EPSILON*/
4166 0 : response_avg_fx[ch] = L_shl( response_avg_fx[ch], Q30 - EPSILON_FX_SHIFT ); // q30
4167 0 : move32();
4168 : }
4169 : }
4170 : ELSE
4171 : {
4172 2393712 : FOR( ch = 1; ch < foa_ch; ch++ )
4173 : {
4174 1795284 : tmp_norm_out = divide3232( response_avg_fx[ch], L_max( norm_fx, L_abs( response_avg_fx[ch] ) ) ); // q15
4175 1795284 : response_avg_fx[ch] = L_shl( tmp_norm_out, 15 ); // q30
4176 1795284 : move32();
4177 : }
4178 : }
4179 : }
4180 : }
4181 :
4182 652640 : FOR( i = add( FOA_CHANNELS, 1 ); i < num_ch; i++ )
4183 : {
4184 0 : response_avg_fx[i] = response_avg_fx[HOA_keep_ind[i]]; // q30
4185 0 : move32();
4186 : }
4187 :
4188 :
4189 652640 : en_ratio_fac_fx = L_shl( L_sub( ONE_IN_Q30 - EPSILON_FX /* Guard to prevent overflow if diffuseness_fx is 0 */, diffuseness_fx[band] ), 1 ); // assuming q of dissusion 30=>q31
4190 652640 : en_ratio_fac_fx = L_max( en_ratio_fac_fx, 0 ); // q31
4191 :
4192 3263200 : FOR( i = 0; i < num_ch; i++ )
4193 : {
4194 13052800 : FOR( j = 0; j < num_ch; j++ )
4195 : {
4196 10442240 : IF( EQ_16( i, j ) )
4197 : {
4198 2610560 : IF( i == 0 )
4199 : {
4200 652640 : cov_real_dirac_fx[i][i][band] = ONE_IN_Q30; // 1 q30
4201 652640 : move32();
4202 : }
4203 : ELSE
4204 : {
4205 1957920 : Word32 en_ratio_fac_sq = 0;
4206 1957920 : move32();
4207 1957920 : cov_real_dirac_fx[i][j][band] = Mpy_32_32( L_shl_sat( Mpy_32_32( en_ratio_fac_fx, response_avg_fx[i] ), 1 ), response_avg_fx[j] ); // q30
4208 1957920 : move32();
4209 :
4210 1957920 : IF( LE_16( hSpar_md_cfg->nchan_transport, 2 ) )
4211 : {
4212 1027092 : cov_real_dirac_fx[i][j][band] = Mpy_32_32( cov_real_dirac_fx[i][j][band], en_ratio_fac_fx ); // q30
4213 1027092 : move32();
4214 1027092 : test();
4215 1027092 : IF( ( GE_16( i, ndm ) ) && ( EQ_16( dtx_vad, 1 ) ) )
4216 : {
4217 845524 : en_ratio_fac_sq = Mpy_32_32( en_ratio_fac_fx, en_ratio_fac_fx ); // q31
4218 845524 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], Mpy_32_32( L_sub( ONE_IN_Q31, en_ratio_fac_sq ), P_dir_fact_fx[i - ndm] ) ); // q30
4219 845524 : move32();
4220 : }
4221 : ELSE
4222 : {
4223 181568 : IF( LT_16( i, foa_ch ) )
4224 : {
4225 181568 : en_ratio_fac_sq = Mpy_32_32( en_ratio_fac_fx, en_ratio_fac_fx ); // q31
4226 181568 : Word32 temp = Mpy_32_32( L_sub( ONE_IN_Q31 /*1 q31*/, en_ratio_fac_sq ), ONE_BY_THREE_Q31 /*1/3 q31*/ ); // q31
4227 181568 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], L_shr( temp, 1 ) ); // q30
4228 181568 : move32();
4229 : }
4230 0 : ELSE IF( LT_16( i, hoa2_ch ) )
4231 : {
4232 0 : en_ratio_fac_sq = Mpy_32_32( en_ratio_fac_fx, en_ratio_fac_fx ); // q31
4233 0 : Word32 temp = Mpy_32_32( L_sub( ONE_IN_Q31, en_ratio_fac_sq ), ONE_BY_FIVE_Q31 /*1/5 q31*/ ); // q31
4234 0 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], L_shr( temp, 1 ) ); // q30
4235 0 : move32();
4236 : }
4237 : ELSE
4238 : {
4239 0 : en_ratio_fac_sq = Mpy_32_32( en_ratio_fac_fx, en_ratio_fac_fx ); // q31
4240 0 : Word32 temp = Mpy_32_32( L_sub( ONE_IN_Q31, en_ratio_fac_sq ), ONE_BY_SEVEN_Q31 /*1/7 q31*/ ); // q31
4241 0 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], L_shr( temp, 1 ) ); // q30
4242 0 : move32();
4243 : }
4244 : }
4245 : }
4246 : ELSE
4247 : {
4248 930828 : IF( LT_16( i, foa_ch ) )
4249 : {
4250 930828 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], L_shr( Mpy_32_32( L_sub( ONE_IN_Q31, en_ratio_fac_fx ), ONE_BY_THREE_Q31 /*1/3 q31*/ ), 1 ) ); // q30
4251 930828 : move32();
4252 : }
4253 0 : ELSE IF( LT_16( i, hoa2_ch ) )
4254 : {
4255 0 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], L_shr( Mpy_32_32( L_sub( ONE_IN_Q31, en_ratio_fac_fx ), ONE_BY_FIVE_Q31 /*1/5 q31*/ ), 1 ) ); // q30
4256 0 : move32();
4257 : }
4258 : ELSE
4259 : {
4260 0 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], L_shr( Mpy_32_32( L_sub( ONE_IN_Q31, en_ratio_fac_fx ), ONE_BY_SEVEN_Q31 /*1/7 q31*/ ), 1 ) ); // q30
4261 0 : move32();
4262 : }
4263 : }
4264 : }
4265 : }
4266 : ELSE
4267 : {
4268 7831680 : cov_real_dirac_fx[i][j][band] = L_shl( Mpy_32_32( Mpy_32_32( en_ratio_fac_fx, response_avg_fx[i] ), response_avg_fx[j] ), 1 ); // q30
4269 7831680 : move32();
4270 : }
4271 : }
4272 : }
4273 : }
4274 :
4275 752800 : FOR( i = 0; i < num_ch; i++ )
4276 : {
4277 3011200 : FOR( j = 0; j < num_ch; j++ )
4278 : {
4279 2408960 : pCov_real_fx[i][j] = cov_real_dirac_fx[i][j]; // q30
4280 2408960 : p_q_Cov_real_fx[i][j] = q_cov_real_dirac_fx[i][j]; // q30
4281 2408960 : set16_fx( q_cov_real_dirac_fx[i][j], Q30, IVAS_MAX_NUM_BANDS );
4282 : }
4283 : }
4284 :
4285 150560 : test();
4286 150560 : active_w = ( EQ_16( dyn_active_w_flag, 1 ) ) || ( EQ_16( hSpar_md_cfg->active_w, 1 ) );
4287 150560 : ivas_compute_spar_params_enc_fx( pCov_real_fx, p_q_Cov_real_fx, dm_fv_re_fx, &q_dm_fv_re_fx, i_ts, ppMixer_mat_fx, &q_ppMixer_mat, start_band, end_band, dtx_vad, num_ch, 1, active_w, active_w_vlbr, hSpar_md_cfg, hSpar_md, Wscale_fx, q_Wscale, 1, dyn_active_w_flag );
4288 :
4289 150560 : IF( mixer_mat_fx != NULL )
4290 : {
4291 150560 : if ( *q_mixer_mat_fx == 0 )
4292 : {
4293 164 : *q_mixer_mat_fx = q_ppMixer_mat;
4294 164 : move16();
4295 : }
4296 803200 : FOR( band = start_band; band < end_band; band++ )
4297 : {
4298 652640 : ndm = hSpar_md_cfg->num_dmx_chans_per_band[band];
4299 652640 : move16();
4300 :
4301 2266512 : FOR( i = 0; i < ndm; i++ )
4302 : {
4303 8069360 : FOR( j = 0; j < num_ch; j++ )
4304 : {
4305 6455488 : mixer_mat_fx[i][j][band + ( i_ts * IVAS_MAX_NUM_BANDS )] = L_shl( ppMixer_mat_fx[i][j][band], sub( *q_mixer_mat_fx, q_ppMixer_mat ) ); // q_mixer_mat_fx
4306 6455488 : move32();
4307 : }
4308 : }
4309 :
4310 1649328 : FOR( i = ndm; i < num_ch; i++ )
4311 : {
4312 4983440 : FOR( j = 0; j < num_ch; j++ )
4313 : {
4314 3986752 : mixer_mat_fx[i][j][band + ( i_ts * IVAS_MAX_NUM_BANDS )] = 0;
4315 3986752 : move32();
4316 : }
4317 : }
4318 :
4319 652640 : test();
4320 652640 : IF( ( EQ_16( ndm, 1 ) ) && ( Wscale_d != NULL ) )
4321 : {
4322 885020 : FOR( j = 0; j < num_ch; j++ )
4323 : {
4324 708016 : mixer_mat_fx[0][j][band + ( i_ts * IVAS_MAX_NUM_BANDS )] = Mpy_32_32( L_shl( mixer_mat_fx[0][j][band + ( i_ts * IVAS_MAX_NUM_BANDS )], 2 ), Wscale_d[band] ); // q_mixer_mat_fx
4325 708016 : move32();
4326 : }
4327 : }
4328 : }
4329 : }
4330 : }
4331 :
4332 150560 : return;
4333 : }
4334 :
4335 :
4336 238184 : void ivas_get_spar_md_from_dirac_fx(
4337 : Word32 azi_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], // Q22
4338 : Word32 ele_dirac_fx[IVAS_MAX_NUM_BANDS][MAX_PARAM_SPATIAL_SUBFRAMES], // Q22
4339 : Word32 diffuseness_fx[IVAS_MAX_NUM_BANDS], // Q30
4340 : const Word16 n_ts,
4341 : Word32 ***mixer_mat_fx, /*q_mixer_mat_fx*/
4342 : Word16 *q_mixer_mat_fx,
4343 : ivas_spar_md_t *hSpar_md,
4344 : ivas_spar_md_com_cfg *hSpar_md_cfg,
4345 : const Word16 start_band,
4346 : const Word16 end_band,
4347 : const Word16 order,
4348 : const Word16 dtx_vad,
4349 : Word32 Wscale_d[IVAS_MAX_NUM_BANDS], // Q29
4350 : const UWord8 useLowerRes,
4351 : const Word16 active_w_vlbr,
4352 : const Word16 dyn_active_w_flag )
4353 : {
4354 :
4355 : Word16 num_ch, band, i, j;
4356 : Word16 block, ch;
4357 : Word16 azimuth, elevation;
4358 :
4359 : Word32 response_avg_fx[MAX_OUTPUT_CHANNELS];
4360 : Word32 response_fx[MAX_PARAM_SPATIAL_SUBFRAMES][MAX_OUTPUT_CHANNELS];
4361 : Word32 cov_real_dirac_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH][IVAS_MAX_NUM_BANDS];
4362 : Word32 *pCov_real_fx[IVAS_SPAR_MAX_CH][IVAS_SPAR_MAX_CH];
4363 : Word32 dm_fv_re_fx[IVAS_SPAR_MAX_CH - 1][IVAS_MAX_NUM_BANDS];
4364 238184 : Word16 q_dm_fv_re_fx = 0;
4365 : Word16 q_Wscale[IVAS_MAX_NUM_BANDS];
4366 : Word32 Wscale_fx[IVAS_MAX_NUM_BANDS];
4367 : Word32 mixer_mat_local_fx[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH][IVAS_MAX_NUM_BANDS];
4368 : Word32 **ppMixer_mat_fx[IVAS_MAX_FB_MIXER_OUT_CH];
4369 : Word32 *pMixer_mat_fx[IVAS_MAX_FB_MIXER_OUT_CH][IVAS_MAX_SPAR_FB_MIXER_IN_CH];
4370 238184 : Word16 q_ppMixer_mat = 0;
4371 : Word32 en_ratio_fac_fx, diff_norm_order1_fx, diff_norm_order2_fx, diff_norm_order3_fx;
4372 : Word16 active_w;
4373 238184 : move16();
4374 238184 : move16();
4375 :
4376 : Word16 ndm, foa_ch, hoa2_ch;
4377 : Word32 P_dir_fact_fx[IVAS_SPAR_MAX_CH - 1];
4378 : const Word16 *remix_order;
4379 :
4380 238184 : set16_fx( q_Wscale, 0, IVAS_MAX_NUM_BANDS );
4381 238184 : set32_fx( Wscale_fx, 0, IVAS_MAX_NUM_BANDS );
4382 238184 : remix_order = remix_order_set[hSpar_md_cfg->remix_unmix_order];
4383 :
4384 238184 : num_ch = ivas_sba_get_nchan_metadata_fx( order, IVAS_256k /*dummy value as order is always 1 in this function*/ );
4385 :
4386 238184 : hoa2_ch = ivas_sba_get_nchan_metadata_fx( SBA_HOA2_ORDER, IVAS_256k /*dummy value as order is always 1 in this function*/ );
4387 238184 : foa_ch = FOA_CHANNELS;
4388 238184 : move16();
4389 238184 : diff_norm_order1_fx = 3;
4390 238184 : move32();
4391 238184 : diff_norm_order2_fx = 5;
4392 238184 : move32();
4393 238184 : diff_norm_order3_fx = 7;
4394 238184 : move32();
4395 :
4396 2858208 : FOR( i = 0; i < IVAS_MAX_FB_MIXER_OUT_CH; i++ )
4397 : {
4398 31440288 : FOR( j = 0; j < IVAS_MAX_SPAR_FB_MIXER_IN_CH; j++ )
4399 : {
4400 28820264 : pMixer_mat_fx[i][j] = mixer_mat_local_fx[i][j];
4401 : }
4402 2620024 : ppMixer_mat_fx[i] = pMixer_mat_fx[i];
4403 : }
4404 :
4405 238184 : test();
4406 238184 : test();
4407 238184 : test();
4408 238184 : test();
4409 238184 : test();
4410 238184 : test();
4411 238184 : IF( ( GE_16( start_band, 6 ) && LE_16( hSpar_md_cfg->nchan_transport, 2 ) && ( EQ_16( dtx_vad, 1 ) ) ) || ( useLowerRes && GE_16( start_band, 3 ) && LE_16( hSpar_md_cfg->nchan_transport, 2 ) && ( EQ_16( dtx_vad, 1 ) ) ) )
4412 : {
4413 : Word32 P_norm_fx[3];
4414 : Word16 idx;
4415 :
4416 115306 : ndm = hSpar_md_cfg->num_dmx_chans_per_band[start_band - 1];
4417 115306 : move16();
4418 115306 : P_norm_fx[0] = 0;
4419 115306 : move32();
4420 115306 : Word16 len = s_max( 0, sub( foa_ch, ndm ) );
4421 384262 : FOR( i = 0; i < len; i++ ) // i < max( 0, sub( foa_ch, ndm ) )
4422 : {
4423 268956 : P_norm_fx[0] = L_add( P_norm_fx[0], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31
4424 268956 : move32();
4425 : }
4426 115306 : P_norm_fx[0] = Mpy_32_32( L_shl( P_norm_fx[0], 3 ), diff_norm_order1_table[min( diff_norm_order1_fx, max( 0, sub( foa_ch, ndm ) ) )] ); // 2*q_P_re - 31
4427 115306 : move32();
4428 :
4429 115306 : P_norm_fx[1] = 0;
4430 115306 : move32();
4431 115306 : len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) );
4432 115306 : FOR( ; i < len; i++ ) // i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) )
4433 : {
4434 0 : P_norm_fx[1] = L_add( P_norm_fx[1], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31
4435 0 : move32();
4436 : }
4437 115306 : P_norm_fx[1] = Mpy_32_32( L_shl( P_norm_fx[1], 3 ), diff_norm_order2_table[min( diff_norm_order2_fx, max( 0, ( min( num_ch, hoa2_ch ) - ndm ) ) )] ); // 2*q_P_re - 31
4438 115306 : move32();
4439 :
4440 115306 : P_norm_fx[2] = 0;
4441 115306 : move32();
4442 115306 : FOR( ; i < ( num_ch - ndm ); i++ )
4443 : {
4444 0 : P_norm_fx[2] = L_add( P_norm_fx[2], Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ) ); // 2*q_P_re - 31
4445 0 : move32();
4446 : }
4447 115306 : P_norm_fx[2] = Mpy_32_32( L_shl( P_norm_fx[2], 3 ), diff_norm_order3_table[min( diff_norm_order3_fx, max( 0, ( num_ch - ndm ) ) )] ); // 2*q_P_re - 31
4448 115306 : move32();
4449 115306 : len = s_max( 0, sub( foa_ch, ndm ) );
4450 384262 : FOR( i = 0; i < len; i++ ) // i < max( 0, ( foa_ch - ndm ) )
4451 : {
4452 268956 : idx = sub( remix_order[i + ndm], ndm );
4453 268956 : P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31
4454 268956 : move32();
4455 268956 : IF( P_dir_fact_fx[idx] != 0 )
4456 : {
4457 237369 : P_dir_fact_fx[idx] = divide3232( P_dir_fact_fx[idx], L_max( P_norm_fx[0], IVAS_FIX_EPS ) ); // q15
4458 237369 : move32();
4459 237369 : P_dir_fact_fx[idx] = L_shl( P_dir_fact_fx[idx], 15 ); // q30
4460 237369 : move32();
4461 : }
4462 : }
4463 115306 : len = s_max( 0, sub( s_min( num_ch, hoa2_ch ), ndm ) );
4464 115306 : FOR( ; i < len; i++ ) // i < max( 0, ( min( num_ch, hoa2_ch ) - ndm ) )
4465 : {
4466 0 : idx = sub( remix_order[i + ndm], ndm );
4467 0 : P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31
4468 0 : IF( P_dir_fact_fx[idx] != 0 )
4469 : {
4470 0 : P_dir_fact_fx[idx] = divide3232( P_dir_fact_fx[idx], L_max( P_norm_fx[1], IVAS_FIX_EPS ) ); // q15
4471 0 : move32();
4472 0 : P_dir_fact_fx[idx] = L_shl( P_dir_fact_fx[idx], 15 ); // q30
4473 0 : move32();
4474 : }
4475 : }
4476 115306 : FOR( ; i < ( num_ch - ndm ); i++ )
4477 : {
4478 0 : idx = sub( remix_order[i + ndm], ndm );
4479 0 : P_dir_fact_fx[idx] = Mpy_32_32( hSpar_md->band_coeffs[start_band - 1].P_re_fx[i], hSpar_md->band_coeffs[start_band - 1].P_re_fx[i] ); // 2*q_P_re - 31
4480 0 : move32();
4481 0 : IF( P_dir_fact_fx[idx] != 0 )
4482 : {
4483 0 : P_dir_fact_fx[idx] = divide3232( P_dir_fact_fx[idx], L_max( P_norm_fx[2], IVAS_FIX_EPS ) ); // q15
4484 0 : move32();
4485 0 : P_dir_fact_fx[idx] = L_shl( P_dir_fact_fx[idx], 15 ); // q30
4486 0 : move32();
4487 : }
4488 : }
4489 : }
4490 :
4491 857551 : FOR( Word16 i_ts = 0; i_ts < n_ts; i_ts++ )
4492 : {
4493 2988155 : FOR( band = start_band; band < end_band; band++ )
4494 : {
4495 2368788 : ndm = hSpar_md_cfg->num_dmx_chans_per_band[band];
4496 2368788 : move16();
4497 :
4498 : /*SPAR from DirAC*/
4499 2368788 : set32_fx( response_avg_fx, 0, MAX_OUTPUT_CHANNELS );
4500 :
4501 2368788 : IF( GT_16( n_ts, 1 ) )
4502 : {
4503 1940088 : IF( ele_dirac_fx[band][i_ts] < 0 )
4504 : {
4505 384942 : elevation = negate( extract_l( L_shr( L_negate( ele_dirac_fx[band][i_ts] ), Q22 ) ) ); // q0
4506 : }
4507 : ELSE
4508 : {
4509 1555146 : elevation = extract_l( L_shr( ele_dirac_fx[band][i_ts], Q22 ) ); // q0
4510 : }
4511 1940088 : IF( azi_dirac_fx[band][i_ts] < 0 )
4512 : {
4513 0 : azimuth = negate( extract_l( L_shr( L_negate( azi_dirac_fx[band][i_ts] ), Q22 ) ) ); // q0
4514 : }
4515 : ELSE
4516 : {
4517 1940088 : azimuth = extract_l( L_shr( azi_dirac_fx[band][i_ts], Q22 ) ); // q0
4518 : }
4519 1940088 : ivas_dirac_dec_get_response_fx( azimuth, elevation, response_avg_fx, order, Q30 );
4520 : }
4521 428700 : ELSE IF( useLowerRes )
4522 : {
4523 44580 : IF( ele_dirac_fx[band][0] < 0 )
4524 : {
4525 10610 : elevation = negate( extract_l( L_shr( L_negate( ele_dirac_fx[band][0] ), Q22 ) ) ); // q0
4526 : }
4527 : ELSE
4528 : {
4529 33970 : elevation = extract_l( L_shr( ele_dirac_fx[band][0], Q22 ) ); // q0
4530 : }
4531 44580 : IF( azi_dirac_fx[band][0] < 0 )
4532 : {
4533 0 : azimuth = negate( extract_l( L_shr( L_negate( azi_dirac_fx[band][0] ), Q22 ) ) ); // q0
4534 : }
4535 : ELSE
4536 : {
4537 44580 : azimuth = extract_l( L_shr( azi_dirac_fx[band][0], Q22 ) ); // q0
4538 : }
4539 44580 : ivas_dirac_dec_get_response_fx( azimuth, elevation, response_avg_fx, order, Q30 );
4540 : }
4541 : ELSE
4542 : {
4543 1920600 : FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
4544 : {
4545 1536480 : IF( ele_dirac_fx[band][block] < 0 )
4546 : {
4547 303853 : elevation = negate( extract_l( L_shr( L_negate( ele_dirac_fx[band][block] ), Q22 ) ) ); // q0
4548 : }
4549 : ELSE
4550 : {
4551 1232627 : elevation = extract_l( L_shr( ele_dirac_fx[band][block], Q22 ) ); // q0
4552 : }
4553 1536480 : IF( azi_dirac_fx[band][block] < 0 )
4554 : {
4555 0 : azimuth = negate( extract_l( L_shr( L_negate( azi_dirac_fx[band][block] ), Q22 ) ) ); // q0
4556 : }
4557 : ELSE
4558 : {
4559 1536480 : azimuth = extract_l( L_shr( azi_dirac_fx[band][block], Q22 ) ); // q0
4560 : }
4561 1536480 : ivas_dirac_dec_get_response_fx( azimuth, elevation, &( response_fx[block][0] ), order, Q30 );
4562 : }
4563 :
4564 : /* average responses in all subframes*/
4565 : {
4566 : Word32 norm_fx;
4567 : Word16 norm_q;
4568 : Word16 num_ch_order, norm_t;
4569 : Word32 tmp_norm_out;
4570 :
4571 384120 : num_ch_order = ivas_sba_get_nchan_fx( order, 0 );
4572 384120 : assert( order == 1 );
4573 :
4574 1920600 : FOR( ch = 0; ch < num_ch_order; ch++ )
4575 : {
4576 1536480 : Word64 temp = 0;
4577 1536480 : move64();
4578 7682400 : FOR( block = 0; block < MAX_PARAM_SPATIAL_SUBFRAMES; block++ )
4579 : {
4580 6145920 : temp = W_add( temp, W_deposit32_l( response_fx[block][ch] ) ); // q30
4581 : }
4582 1536480 : response_avg_fx[ch] = W_extract_l( W_shr( temp, 2 ) ); // q30
4583 1536480 : move32();
4584 : }
4585 :
4586 : /*normalize 1st order*/
4587 384120 : norm_t = L_norm_arr( &response_avg_fx[1], sub( foa_ch, 1 ) );
4588 384120 : norm_t = sub( norm_t, 1 );
4589 384120 : scale_sig32( &response_avg_fx[1], sub( foa_ch, 1 ), norm_t );
4590 384120 : norm_fx = 0;
4591 384120 : move32();
4592 1536480 : FOR( ch = 1; ch < foa_ch; ch++ )
4593 : {
4594 1152360 : norm_fx = L_add( norm_fx, Mpy_32_32( response_avg_fx[ch], response_avg_fx[ch] ) ); // q29
4595 : }
4596 :
4597 384120 : norm_q = sub( 31, ( sub( add( 30, 30 ), 31 ) ) );
4598 :
4599 384120 : norm_fx = Sqrt32( norm_fx, &norm_q ); // q=31-norm_q
4600 :
4601 384120 : IF( norm_q <= 0 )
4602 : {
4603 310628 : norm_fx = L_shr( norm_fx, ( negate( norm_q ) ) ); // q=31
4604 310628 : norm_q = 0;
4605 310628 : move16();
4606 : }
4607 384120 : norm_fx = L_shr( norm_fx, sub( 1, norm_q ) ); // q30
4608 :
4609 384120 : IF( LT_32( norm_fx, EPSILON_FX_THR ) )
4610 : {
4611 0 : FOR( ch = 1; ch < foa_ch; ch++ )
4612 : {
4613 : /*when control comes here, response_avg_fx[ch] should be less than EPSILON*/
4614 0 : response_avg_fx[ch] = L_shl( response_avg_fx[ch], Q30 - EPSILON_FX_SHIFT ); // q30
4615 0 : move32();
4616 : }
4617 : }
4618 : ELSE
4619 : {
4620 1536480 : FOR( ch = 1; ch < foa_ch; ch++ )
4621 : {
4622 1152360 : tmp_norm_out = divide3232( response_avg_fx[ch], L_max( norm_fx, L_abs( response_avg_fx[ch] ) ) ); // q15
4623 1152360 : response_avg_fx[ch] = L_shl( tmp_norm_out, 15 ); // q30
4624 1152360 : move32();
4625 : }
4626 : }
4627 : }
4628 : }
4629 :
4630 2368788 : FOR( i = add( FOA_CHANNELS, 1 ); i < num_ch; i++ )
4631 : {
4632 0 : response_avg_fx[i] = response_avg_fx[HOA_keep_ind[i]]; // q30
4633 0 : move32();
4634 : }
4635 :
4636 :
4637 2368788 : en_ratio_fac_fx = L_shl( L_sub( ONE_IN_Q30 - EPSILON_FX /* Guard to prevent overflow if diffuseness_fx is 0 */, diffuseness_fx[band] ), 1 ); // assuming q of dissusion 30=>q31
4638 2368788 : en_ratio_fac_fx = L_max( en_ratio_fac_fx, 0 ); // q31
4639 :
4640 11843940 : FOR( i = 0; i < num_ch; i++ )
4641 : {
4642 47375760 : FOR( j = 0; j < num_ch; j++ )
4643 : {
4644 37900608 : IF( EQ_16( i, j ) )
4645 : {
4646 9475152 : IF( i == 0 )
4647 : {
4648 2368788 : cov_real_dirac_fx[i][i][band] = ONE_IN_Q30; // 1 q30
4649 2368788 : move32();
4650 : }
4651 : ELSE
4652 : {
4653 7106364 : Word32 en_ratio_fac_sq = 0;
4654 7106364 : move32();
4655 7106364 : cov_real_dirac_fx[i][j][band] = Mpy_32_32( L_shl( Mpy_32_32( en_ratio_fac_fx, response_avg_fx[i] ), 1 ), response_avg_fx[j] ); // q30
4656 7106364 : move32();
4657 :
4658 7106364 : IF( LE_16( hSpar_md_cfg->nchan_transport, 2 ) )
4659 : {
4660 3596184 : cov_real_dirac_fx[i][j][band] = Mpy_32_32( cov_real_dirac_fx[i][j][band], en_ratio_fac_fx ); // q30
4661 3596184 : move32();
4662 3596184 : test();
4663 3596184 : IF( ( GE_16( i, ndm ) ) && ( EQ_16( dtx_vad, 1 ) ) )
4664 : {
4665 2831156 : en_ratio_fac_sq = Mpy_32_32( en_ratio_fac_fx, en_ratio_fac_fx ); // q31
4666 2831156 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], Mpy_32_32( L_sub( ONE_IN_Q31, en_ratio_fac_sq ), P_dir_fact_fx[i - ndm] ) ); // q30
4667 2831156 : move32();
4668 : }
4669 : ELSE
4670 : {
4671 765028 : IF( LT_16( i, foa_ch ) )
4672 : {
4673 765028 : en_ratio_fac_sq = Mpy_32_32( en_ratio_fac_fx, en_ratio_fac_fx ); // q31
4674 765028 : Word32 temp = Mpy_32_32( L_sub( ONE_IN_Q31 /*1 q31*/, en_ratio_fac_sq ), ONE_BY_THREE_Q31 /*1/3 q31*/ ); // q31
4675 765028 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], L_shr( temp, 1 ) ); // q30
4676 765028 : move32();
4677 : }
4678 0 : ELSE IF( LT_16( i, hoa2_ch ) )
4679 : {
4680 0 : en_ratio_fac_sq = Mpy_32_32( en_ratio_fac_fx, en_ratio_fac_fx ); // q31
4681 0 : Word32 temp = Mpy_32_32( L_sub( ONE_IN_Q31, en_ratio_fac_sq ), ONE_BY_FIVE_Q31 /*1/5 q31*/ ); // q31
4682 0 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], L_shr( temp, 1 ) ); // q30
4683 0 : move32();
4684 : }
4685 : ELSE
4686 : {
4687 0 : en_ratio_fac_sq = Mpy_32_32( en_ratio_fac_fx, en_ratio_fac_fx ); // q31
4688 0 : Word32 temp = Mpy_32_32( L_sub( ONE_IN_Q31, en_ratio_fac_sq ), ONE_BY_SEVEN_Q31 /*1/7 q31*/ ); // q31
4689 0 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], L_shr( temp, 1 ) ); // q30
4690 0 : move32();
4691 : }
4692 : }
4693 : }
4694 : ELSE
4695 : {
4696 3510180 : IF( LT_16( i, foa_ch ) )
4697 : {
4698 3510180 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], L_shr( Mpy_32_32( L_sub( ONE_IN_Q31, en_ratio_fac_fx ), ONE_BY_THREE_Q31 /*1/3 q31*/ ), 1 ) ); // q30
4699 3510180 : move32();
4700 : }
4701 0 : ELSE IF( LT_16( i, hoa2_ch ) )
4702 : {
4703 0 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], L_shr( Mpy_32_32( L_sub( ONE_IN_Q31, en_ratio_fac_fx ), ONE_BY_FIVE_Q31 /*1/5 q31*/ ), 1 ) ); // q30
4704 0 : move32();
4705 : }
4706 : ELSE
4707 : {
4708 0 : cov_real_dirac_fx[i][j][band] = L_add( cov_real_dirac_fx[i][j][band], L_shr( Mpy_32_32( L_sub( ONE_IN_Q31, en_ratio_fac_fx ), ONE_BY_SEVEN_Q31 /*1/7 q31*/ ), 1 ) ); // q30
4709 0 : move32();
4710 : }
4711 : }
4712 : }
4713 : }
4714 : ELSE
4715 : {
4716 28425456 : cov_real_dirac_fx[i][j][band] = L_shl( Mpy_32_32( Mpy_32_32( en_ratio_fac_fx, response_avg_fx[i] ), response_avg_fx[j] ), 1 ); // q30
4717 28425456 : move32();
4718 : }
4719 : }
4720 : }
4721 : }
4722 :
4723 3096835 : FOR( i = 0; i < num_ch; i++ )
4724 : {
4725 12387340 : FOR( j = 0; j < num_ch; j++ )
4726 : {
4727 9909872 : pCov_real_fx[i][j] = cov_real_dirac_fx[i][j]; // q30
4728 9909872 : move32();
4729 : }
4730 : }
4731 :
4732 619367 : test();
4733 619367 : active_w = ( EQ_16( dyn_active_w_flag, 1 ) ) || ( EQ_16( hSpar_md_cfg->active_w, 1 ) );
4734 619367 : ivas_compute_spar_params_fx( pCov_real_fx, Q30, dm_fv_re_fx, &q_dm_fv_re_fx, i_ts, ppMixer_mat_fx, &q_ppMixer_mat, start_band, end_band, dtx_vad, num_ch, 1, active_w, active_w_vlbr, hSpar_md_cfg, hSpar_md, Wscale_fx, q_Wscale, 1, dyn_active_w_flag );
4735 :
4736 619367 : IF( mixer_mat_fx != NULL )
4737 : {
4738 0 : if ( *q_mixer_mat_fx == 0 )
4739 : {
4740 0 : *q_mixer_mat_fx = q_ppMixer_mat;
4741 0 : move16();
4742 : }
4743 0 : FOR( band = start_band; band < end_band; band++ )
4744 : {
4745 0 : ndm = hSpar_md_cfg->num_dmx_chans_per_band[band];
4746 0 : move16();
4747 :
4748 0 : FOR( i = 0; i < ndm; i++ )
4749 : {
4750 0 : FOR( j = 0; j < num_ch; j++ )
4751 : {
4752 0 : mixer_mat_fx[i][j][band + ( i_ts * IVAS_MAX_NUM_BANDS )] = L_shl( ppMixer_mat_fx[i][j][band], sub( *q_mixer_mat_fx, q_ppMixer_mat ) ); // q_mixer_mat_fx
4753 0 : move32();
4754 : }
4755 : }
4756 :
4757 0 : FOR( i = ndm; i < num_ch; i++ )
4758 : {
4759 0 : FOR( j = 0; j < num_ch; j++ )
4760 : {
4761 0 : mixer_mat_fx[i][j][band + ( i_ts * IVAS_MAX_NUM_BANDS )] = 0;
4762 0 : move32();
4763 : }
4764 : }
4765 :
4766 0 : test();
4767 0 : IF( ( EQ_16( ndm, 1 ) ) && ( Wscale_d != NULL ) )
4768 : {
4769 0 : FOR( j = 0; j < num_ch; j++ )
4770 : {
4771 0 : mixer_mat_fx[0][j][band + ( i_ts * IVAS_MAX_NUM_BANDS )] = Mpy_32_32( L_shl( mixer_mat_fx[0][j][band + ( i_ts * IVAS_MAX_NUM_BANDS )], 2 ), Wscale_d[band] ); // q_mixer_mat_fx
4772 0 : move32();
4773 : }
4774 : }
4775 : }
4776 : }
4777 : }
4778 :
4779 238184 : return;
4780 : }
4781 :
4782 : /*-------------------------------------------------------------------------
4783 : * ivas_dirac_dec_get_response_fx()
4784 : *
4785 : * Block Q of 29 is maintained
4786 : * calculate reponse, 1 degree resolution
4787 : * Input azimuth and elevation are expected in Q0
4788 : *------------------------------------------------------------------------*/
4789 :
4790 : Word32 local_result_table[91][9] /*q30*/ = {
4791 : {
4792 : -1518500224,
4793 : 0,
4794 : 1518500224,
4795 : 0,
4796 : 0,
4797 : -1518500224,
4798 : 0,
4799 : 0,
4800 : 0,
4801 : },
4802 : {
4803 : -1518268928,
4804 : 18739168,
4805 : 1517806336,
4806 : -32452256,
4807 : 283224,
4808 : -1517112832,
4809 : 45883920,
4810 : -633213,
4811 : 4512,
4812 : },
4813 : {
4814 : -1517575296,
4815 : 37472840,
4816 : 1515726208,
4817 : -64865308,
4818 : 1132567,
4819 : -1512954368,
4820 : 91649576,
4821 : -2530954,
4822 : 36081,
4823 : },
4824 : {
4825 : -1516419072,
4826 : 56195504,
4827 : 1512261120,
4828 : -97200048,
4829 : 2547029,
4830 : -1506034816,
4831 : 137178960,
4832 : -5687523,
4833 : 121687,
4834 : },
4835 : {
4836 : -1514801280,
4837 : 74899824,
4838 : 1507416960,
4839 : -129414272,
4840 : 4524729,
4841 : -1496374144,
4842 : 182350416,
4843 : -10092950,
4844 : 288126,
4845 : },
4846 : {
4847 : -1512721920,
4848 : 93582472,
4849 : 1501198336,
4850 : -161472816,
4851 : 7063499,
4852 : -1483994752,
4853 : 227052672,
4854 : -15734350,
4855 : 561983,
4856 : },
4857 : {
4858 : -1510181888,
4859 : 112236512,
4860 : 1493612928,
4861 : -193334368,
4862 : 10160129,
4863 : -1468930304,
4864 : 271167360,
4865 : -22594280,
4866 : 969488,
4867 : },
4868 : {
4869 : -1507181440,
4870 : 130856376,
4871 : 1484670848,
4872 : -224960416,
4873 : 13810849,
4874 : -1451219200,
4875 : 314580448,
4876 : -30651802,
4877 : 1536471,
4878 : },
4879 : {
4880 : -1503722368,
4881 : 149436080,
4882 : 1474381824,
4883 : -256312016,
4884 : 18011172,
4885 : -1430907520,
4886 : 357179712,
4887 : -39882252,
4888 : 2288268,
4889 : },
4890 : {
4891 : -1499805056,
4892 : 167970048,
4893 : 1462759808,
4894 : -287350848,
4895 : 22755934,
4896 : -1408048256,
4897 : 398855200,
4898 : -50257348,
4899 : 3249646,
4900 : },
4901 : {
4902 : -1495430784,
4903 : 186453552,
4904 : 1449817472,
4905 : -318040608,
4906 : 28039610,
4907 : -1382698496,
4908 : 439501280,
4909 : -61745920,
4910 : 4444797,
4911 : },
4912 : {
4913 : -1490601216,
4914 : 204879712,
4915 : 1435571584,
4916 : -348342304,
4917 : 33855484,
4918 : -1354926336,
4919 : 479011360,
4920 : -74312248,
4921 : 5897082,
4922 : },
4923 : {
4924 : -1485317248,
4925 : 223243280,
4926 : 1420039296,
4927 : -378219040,
4928 : 40196448,
4929 : -1324801792,
4930 : 517284416,
4931 : -87917840,
4932 : 7629140,
4933 : },
4934 : {
4935 : -1479581312,
4936 : 241539296,
4937 : 1403239552,
4938 : -407635936,
4939 : 47055084,
4940 : -1292403328,
4941 : 554224000,
4942 : -102521616,
4943 : 9662823,
4944 : },
4945 : {
4946 : -1473394304,
4947 : 259761664,
4948 : 1385192192,
4949 : -436555904,
4950 : 54422836,
4951 : -1257814016,
4952 : 589734528,
4953 : -118078312,
4954 : 12018922,
4955 : },
4956 : {
4957 : -1466758528,
4958 : 277904896,
4959 : 1365919872,
4960 : -464943936,
4961 : 62290712,
4962 : -1221123072,
4963 : 623725376,
4964 : -134540160,
4965 : 14717325,
4966 : },
4967 : {
4968 : -1459675904,
4969 : 295963392,
4970 : 1345445888,
4971 : -492765408,
4972 : 70649128,
4973 : -1182425216,
4974 : 656109568,
4975 : -151856528,
4976 : 17776824,
4977 : },
4978 : {
4979 : -1452148992,
4980 : 313931616,
4981 : 1323795328,
4982 : -519986432,
4983 : 79487904,
4984 : -1141820288,
4985 : 686806528,
4986 : -169973952,
4987 : 21215122,
4988 : },
4989 : {
4990 : -1444179456,
4991 : 331804576,
4992 : 1300994176,
4993 : -546574464,
4994 : 88796448,
4995 : -1099412096,
4996 : 715738304,
4997 : -188836864,
4998 : 25048834,
4999 : },
5000 : {
5001 : -1435770240,
5002 : 349576096,
5003 : 1277071104,
5004 : -572495872,
5005 : 98563056,
5006 : -1055310848,
5007 : 742831168,
5008 : -208386384,
5009 : 29293104,
5010 : },
5011 : {
5012 : -1426923392,
5013 : 367241408,
5014 : 1252053888,
5015 : -597720320,
5016 : 108776240,
5017 : -1009627456,
5018 : 768018944,
5019 : -228562448,
5020 : 33962144,
5021 : },
5022 : {
5023 : -1417641984,
5024 : 384794496,
5025 : 1225974400,
5026 : -622216320,
5027 : 119423168,
5028 : -962481536,
5029 : 791238528,
5030 : -249301712,
5031 : 39068520,
5032 : },
5033 : {
5034 : -1407929088,
5035 : 402230560,
5036 : 1198863744,
5037 : -645953856,
5038 : 130491136,
5039 : -913992384,
5040 : 812432896,
5041 : -270540160,
5042 : 44623688,
5043 : },
5044 : {
5045 : -1397786880,
5046 : 419544320,
5047 : 1170754432,
5048 : -668905408,
5049 : 141966720,
5050 : -864283712,
5051 : 831550336,
5052 : -292211648,
5053 : 50637684,
5054 : },
5055 : {
5056 : -1387219200,
5057 : 436730112,
5058 : 1141681280,
5059 : -691041088,
5060 : 153835648,
5061 : -813483968,
5062 : 848545344,
5063 : -314247680,
5064 : 57118880,
5065 : },
5066 : {
5067 : -1376228736,
5068 : 453783040,
5069 : 1111679744,
5070 : -712335552,
5071 : 166083808,
5072 : -761721216,
5073 : 863377472,
5074 : -336579712,
5075 : 64074440,
5076 : },
5077 : {
5078 : -1364819072,
5079 : 470697504,
5080 : 1080786560,
5081 : -732761408,
5082 : 178695840,
5083 : -709128192,
5084 : 876011648,
5085 : -359136416,
5086 : 71509840,
5087 : },
5088 : {
5089 : -1352993664,
5090 : 487468704,
5091 : 1049038720,
5092 : -752295232,
5093 : 191656864,
5094 : -655838272,
5095 : 886421184,
5096 : -381847712,
5097 : 79429264,
5098 : },
5099 : {
5100 : -1340756224,
5101 : 504091296,
5102 : 1016475840,
5103 : -770911616,
5104 : 204950624,
5105 : -601987264,
5106 : 894582912,
5107 : -404640384,
5108 : 87835088,
5109 : },
5110 : {
5111 : -1328110336,
5112 : 520560224,
5113 : 983137344,
5114 : -788589376,
5115 : 218561056,
5116 : -547711936,
5117 : 900480064,
5118 : -427441888,
5119 : 96728224,
5120 : },
5121 : {
5122 : -1315059712,
5123 : 536870912,
5124 : 949062848,
5125 : -805306304,
5126 : 232471968,
5127 : -493147392,
5128 : 904103488,
5129 : -450179904,
5130 : 106108432,
5131 : },
5132 : {
5133 : -1301608576,
5134 : 553017920,
5135 : 914294592,
5136 : -821041856,
5137 : 246665952,
5138 : -438433216,
5139 : 905449280,
5140 : -472780672,
5141 : 115973296,
5142 : },
5143 : {
5144 : -1287761024,
5145 : 568996608,
5146 : 878874816,
5147 : -835777472,
5148 : 261126064,
5149 : -383705856,
5150 : 904519040,
5151 : -495171488,
5152 : 126319176,
5153 : },
5154 : {
5155 : -1273521536,
5156 : 584801792,
5157 : 842847360,
5158 : -849494592,
5159 : 275834208,
5160 : -329104384,
5161 : 901322112,
5162 : -517278496,
5163 : 137140640,
5164 : },
5165 : {
5166 : -1258893952,
5167 : 600428672,
5168 : 806255552,
5169 : -862177024,
5170 : 290772768,
5171 : -274764416,
5172 : 895873408,
5173 : -539030016,
5174 : 148430976,
5175 : },
5176 : {
5177 : -1243882624,
5178 : 615873088,
5179 : 769143424,
5180 : -873808640,
5181 : 305923776,
5182 : -220820592,
5183 : 888192128,
5184 : -560354240,
5185 : 160182032,
5186 : },
5187 : {
5188 : -1228492672,
5189 : 631129536,
5190 : 731557056,
5191 : -884375872,
5192 : 321268192,
5193 : -167408576,
5194 : 878306816,
5195 : -581179712,
5196 : 172383520,
5197 : },
5198 : {
5199 : -1212728192,
5200 : 646193920,
5201 : 693541568,
5202 : -893865664,
5203 : 336788032,
5204 : -114659368,
5205 : 866249088,
5206 : -601437056,
5207 : 185024416,
5208 : },
5209 : {
5210 : -1196594560,
5211 : 661061376,
5212 : 655143872,
5213 : -902266304,
5214 : 352463776,
5215 : -62704428,
5216 : 852058240,
5217 : -621057088,
5218 : 198091488,
5219 : },
5220 : {
5221 : -1180096256,
5222 : 675727744,
5223 : 616410112,
5224 : -909567168,
5225 : 368276832,
5226 : -11670283,
5227 : 835778240,
5228 : -639973248,
5229 : 211570704,
5230 : },
5231 : {
5232 : -1163238528,
5233 : 690187904,
5234 : 577388480,
5235 : -915760192,
5236 : 384207328,
5237 : 38316972,
5238 : 817459904,
5239 : -658119040,
5240 : 225445952,
5241 : },
5242 : {
5243 : -1146026752,
5244 : 704437888,
5245 : 538126144,
5246 : -920838016,
5247 : 400236128,
5248 : 87136208,
5249 : 797158016,
5250 : -675430976,
5251 : 239700208,
5252 : },
5253 : {
5254 : -1128465792,
5255 : 718473536,
5256 : 498670016,
5257 : -924793792,
5258 : 416343968,
5259 : 134670400,
5260 : 774934400,
5261 : -691848064,
5262 : 254315376,
5263 : },
5264 : {
5265 : -1110560896,
5266 : 732290176,
5267 : 459069056,
5268 : -927622464,
5269 : 432511008,
5270 : 180804176,
5271 : 750854336,
5272 : -707309760,
5273 : 269271168,
5274 : },
5275 : {
5276 : -1092317568,
5277 : 745883904,
5278 : 419370880,
5279 : -929321088,
5280 : 448717696,
5281 : 225428032,
5282 : 724989312,
5283 : -721759040,
5284 : 284546880,
5285 : },
5286 : {
5287 : -1073741823,
5288 : 759250176,
5289 : 379625056,
5290 : -929887680,
5291 : 464943936,
5292 : 268435456,
5293 : 697415552,
5294 : -735140736,
5295 : 300119968,
5296 : },
5297 : {
5298 : -1054839104,
5299 : 772385152,
5300 : 339879232,
5301 : -929321088,
5302 : 481170176,
5303 : 309726208,
5304 : 668213824,
5305 : -747403200,
5306 : 315967200,
5307 : },
5308 : {
5309 : -1035614656,
5310 : 785285184,
5311 : 300180928,
5312 : -927622464,
5313 : 497376864,
5314 : 349204928,
5315 : 637467712,
5316 : -758496960,
5317 : 332064416,
5318 : },
5319 : {
5320 : -1016075072,
5321 : 797945664,
5322 : 260580400,
5323 : -924793792,
5324 : 513543616,
5325 : 386779488,
5326 : 605268032,
5327 : -768375104,
5328 : 348385536,
5329 : },
5330 : {
5331 : -996225600,
5332 : 810363264,
5333 : 221124000,
5334 : -920838016,
5335 : 529651744,
5336 : 422366560,
5337 : 571706432,
5338 : -776995008,
5339 : 364904864,
5340 : },
5341 : {
5342 : -976073088,
5343 : 822533888,
5344 : 181861520,
5345 : -915760768,
5346 : 545680512,
5347 : 455884896,
5348 : 536880512,
5349 : -784315776,
5350 : 381594208,
5351 : },
5352 : {
5353 : -955623040,
5354 : 834454272,
5355 : 142839376,
5356 : -909567168,
5357 : 561611328,
5358 : 487262400,
5359 : 500889568,
5360 : -790300992,
5361 : 398426144,
5362 : },
5363 : {
5364 : -934881920,
5365 : 846120128,
5366 : 104106176,
5367 : -902266304,
5368 : 577424064,
5369 : 516431136,
5370 : 463836896,
5371 : -794917120,
5372 : 415371168,
5373 : },
5374 : {
5375 : -913856384,
5376 : 857528256,
5377 : 65708784,
5378 : -893865664,
5379 : 593099520,
5380 : 543330048,
5381 : 425828896,
5382 : -798133760,
5383 : 432399904,
5384 : },
5385 : {
5386 : -892551936,
5387 : 868675520,
5388 : 27693010,
5389 : -884375872,
5390 : 608619648,
5391 : 567905408,
5392 : 386972736,
5393 : -799925440,
5394 : 449482624,
5395 : },
5396 : {
5397 : -870975872,
5398 : 879557760,
5399 : -9893141,
5400 : -873808640,
5401 : 623964096,
5402 : 590108032,
5403 : 347380800,
5404 : -800268608,
5405 : 466587840,
5406 : },
5407 : {
5408 : -849134336,
5409 : 890172352,
5410 : -47005296,
5411 : -862177024,
5412 : 639115008,
5413 : 609897856,
5414 : 307164128,
5415 : -799144896,
5416 : 483684960,
5417 : },
5418 : {
5419 : -827034624,
5420 : 900515712,
5421 : -83597168,
5422 : -849494592,
5423 : 654053696,
5424 : 627240256,
5425 : 266438224,
5426 : -796539136,
5427 : 500742080,
5428 : },
5429 : {
5430 : -804682624,
5431 : 910584576,
5432 : -119624760,
5433 : -835777472,
5434 : 668762048,
5435 : 642107520,
5436 : 225317632,
5437 : -792439552,
5438 : 517727488,
5439 : },
5440 : {
5441 : -782085312,
5442 : 920376512,
5443 : -155044640,
5444 : -821041856,
5445 : 683222080,
5446 : 654480128,
5447 : 183918624,
5448 : -786839296,
5449 : 534609632,
5450 : },
5451 : {
5452 : -759250304,
5453 : 929887616,
5454 : -189812384,
5455 : -805306304,
5456 : 697415936,
5457 : 664343872,
5458 : 142359552,
5459 : -779734528,
5460 : 551355584,
5461 : },
5462 : {
5463 : -736183296,
5464 : 939115776,
5465 : -223886912,
5466 : -788589376,
5467 : 711326720,
5468 : 671693120,
5469 : 100756408,
5470 : -771125696,
5471 : 567933632,
5472 : },
5473 : {
5474 : -712892608,
5475 : 948057792,
5476 : -257225888,
5477 : -770911616,
5478 : 724937152,
5479 : 676528896,
5480 : 59227880,
5481 : -761017408,
5482 : 584311680,
5483 : },
5484 : {
5485 : -689384832,
5486 : 956710976,
5487 : -289788768,
5488 : -752295232,
5489 : 738231168,
5490 : 678858752,
5491 : 17890716,
5492 : -749417856,
5493 : 600457728,
5494 : },
5495 : {
5496 : -665666624,
5497 : 965072704,
5498 : -321536480,
5499 : -732761408,
5500 : 751191936,
5501 : 678698240,
5502 : -23139272,
5503 : -736339008,
5504 : 616340032,
5505 : },
5506 : {
5507 : -641745984,
5508 : 973140608,
5509 : -352429632,
5510 : -712335552,
5511 : 763803968,
5512 : 676069440,
5513 : -63745280,
5514 : -721797248,
5515 : 631926912,
5516 : },
5517 : {
5518 : -617629760,
5519 : 980911936,
5520 : -382431072,
5521 : -691041088,
5522 : 776052160,
5523 : 671001088,
5524 : -103813880,
5525 : -705812224,
5526 : 647187904,
5527 : },
5528 : {
5529 : -593325248,
5530 : 988384512,
5531 : -411504000,
5532 : -668905408,
5533 : 787920960,
5534 : 663529280,
5535 : -143232048,
5536 : -688407552,
5537 : 662091712,
5538 : },
5539 : {
5540 : -568840192,
5541 : 995556160,
5542 : -439613248,
5543 : -645954560,
5544 : 799396736,
5545 : 653696896,
5546 : -181889024,
5547 : -669611072,
5548 : 676608512,
5549 : },
5550 : {
5551 : -544181696,
5552 : 1002424320,
5553 : -466724288,
5554 : -622216320,
5555 : 810464576,
5556 : 641552832,
5557 : -219676144,
5558 : -649453696,
5559 : 690709312,
5560 : },
5561 : {
5562 : -519357600,
5563 : 1008987328,
5564 : -492803904,
5565 : -597720256,
5566 : 821111744,
5567 : 627153216,
5568 : -256487184,
5569 : -627969792,
5570 : 704364160,
5571 : },
5572 : {
5573 : -494375232,
5574 : 1015242880,
5575 : -517820864,
5576 : -572495872,
5577 : 831324672,
5578 : 610560128,
5579 : -292219008,
5580 : -605198016,
5581 : 717546496,
5582 : },
5583 : {
5584 : -469242400,
5585 : 1021189056,
5586 : -541744064,
5587 : -546574272,
5588 : 841091328,
5589 : 591841984,
5590 : -326770816,
5591 : -581179840,
5592 : 730228608,
5593 : },
5594 : {
5595 : -443966464,
5596 : 1026824384,
5597 : -564545152,
5598 : -519986624,
5599 : 850399808,
5600 : 571072896,
5601 : -360046304,
5602 : -555960000,
5603 : 742384384,
5604 : },
5605 : {
5606 : -418555424,
5607 : 1032146880,
5608 : -586195904,
5609 : -492765472,
5610 : 859238720,
5611 : 548332736,
5612 : -391952064,
5613 : -529586400,
5614 : 753988416,
5615 : },
5616 : {
5617 : -393016736,
5618 : 1037154944,
5619 : -606669696,
5620 : -464943776,
5621 : 867597120,
5622 : 523707360,
5623 : -422398496,
5624 : -502110496,
5625 : 765017472,
5626 : },
5627 : {
5628 : -367358464,
5629 : 1041847104,
5630 : -625942016,
5631 : -436555712,
5632 : 875464896,
5633 : 497287264,
5634 : -451300416,
5635 : -473585952,
5636 : 775447168,
5637 : },
5638 : {
5639 : -341588128,
5640 : 1046221952,
5641 : -643989248,
5642 : -407635840,
5643 : 882832768,
5644 : 469168768,
5645 : -478576512,
5646 : -444069824,
5647 : 785256768,
5648 : },
5649 : {
5650 : -315714112,
5651 : 1050278016,
5652 : -660789184,
5653 : -378219488,
5654 : 889691264,
5655 : 439452448,
5656 : -504150464,
5657 : -413621792,
5658 : 794425024,
5659 : },
5660 : {
5661 : -289743520,
5662 : 1054014208,
5663 : -676321600,
5664 : -348342080,
5665 : 896032512,
5666 : 408242848,
5667 : -527951296,
5668 : -382302944,
5669 : 802933568,
5670 : },
5671 : {
5672 : -263684816,
5673 : 1057429248,
5674 : -690567552,
5675 : -318040352,
5676 : 901848320,
5677 : 375649632,
5678 : -549911936,
5679 : -350177888,
5680 : 810763520,
5681 : },
5682 : {
5683 : -237545680,
5684 : 1060522240,
5685 : -703509440,
5686 : -287351040,
5687 : 907131648,
5688 : 341785696,
5689 : -569970496,
5690 : -317312864,
5691 : 817899072,
5692 : },
5693 : {
5694 : -211334384,
5695 : 1063292288,
5696 : -715132096,
5697 : -256311760,
5698 : 911876928,
5699 : 306768160,
5700 : -588071424,
5701 : -283776384,
5702 : 824324416,
5703 : },
5704 : {
5705 : -185058560,
5706 : 1065738240,
5707 : -725420672,
5708 : -224960096,
5709 : 916077184,
5710 : 270716544,
5711 : -604163840,
5712 : -249638288,
5713 : 830026560,
5714 : },
5715 : {
5716 : -158726560,
5717 : 1067859776,
5718 : -734362944,
5719 : -193334624,
5720 : 919727616,
5721 : 233754128,
5722 : -618202944,
5723 : -214970528,
5724 : 834993024,
5725 : },
5726 : {
5727 : -132346048,
5728 : 1069655936,
5729 : -741948032,
5730 : -161473376,
5731 : 922824448,
5732 : 196005872,
5733 : -630149440,
5734 : -179845728,
5735 : 839213568,
5736 : },
5737 : {
5738 : -105925224,
5739 : 1071126272,
5740 : -748166720,
5741 : -129415376,
5742 : 925363072,
5743 : 157599216,
5744 : -639969344,
5745 : -144338352,
5746 : 842679232,
5747 : },
5748 : {
5749 : -79472136,
5750 : 1072270272,
5751 : -753011392,
5752 : -97199672,
5753 : 927340864,
5754 : 118664000,
5755 : -647635776,
5756 : -108523640,
5757 : 845382016,
5758 : },
5759 : {
5760 : -52994836,
5761 : 1073087808,
5762 : -756475840,
5763 : -64865616,
5764 : 928755264,
5765 : 79330888,
5766 : -653127424,
5767 : -72477792,
5768 : 847316864,
5769 : },
5770 : {
5771 : -26501398,
5772 : 1073578432,
5773 : -758556288,
5774 : -32452510,
5775 : 929604544,
5776 : 39731924,
5777 : -656428672,
5778 : -36277476,
5779 : 848479808,
5780 : },
5781 : {
5782 : -66,
5783 : 1073741823,
5784 : -759250112,
5785 : -81,
5786 : 929887872,
5787 : 99,
5788 : -657529856,
5789 : -90,
5790 : 848867456,
5791 : }
5792 : };
5793 :
5794 : Word32 local_result_table_2[91][9] /*q30*/ = {
5795 : {
5796 : -1073741823,
5797 : 0,
5798 : 1073741823,
5799 : 0,
5800 : 0,
5801 : -1073741823,
5802 : 0,
5803 : 0,
5804 : 0,
5805 : },
5806 : {
5807 : -1073578304,
5808 : 13250594,
5809 : 1073251200,
5810 : -22947212,
5811 : 200270,
5812 : -1072760832,
5813 : 32444832,
5814 : -447749,
5815 : 3190,
5816 : },
5817 : {
5818 : -1073087808,
5819 : 26497302,
5820 : 1071780288,
5821 : -45866700,
5822 : 800846,
5823 : -1069820288,
5824 : 64806036,
5825 : -1789655,
5826 : 25513,
5827 : },
5828 : {
5829 : -1072270272,
5830 : 39736224,
5831 : 1069330112,
5832 : -68730816,
5833 : 1801021,
5834 : -1064927488,
5835 : 97000176,
5836 : -4021686,
5837 : 86045,
5838 : },
5839 : {
5840 : -1071126272,
5841 : 52962176,
5842 : 1065904768,
5843 : -91509712,
5844 : 3199466,
5845 : -1058096320,
5846 : 128941216,
5847 : -7136793,
5848 : 203735,
5849 : },
5850 : {
5851 : -1069655936,
5852 : 66172804,
5853 : 1061507520,
5854 : -114178536,
5855 : 4994649,
5856 : -1049342784,
5857 : 160550480,
5858 : -11125865,
5859 : 397382,
5860 : },
5861 : {
5862 : -1067859840,
5863 : 79363208,
5864 : 1056143808,
5865 : -136708048,
5866 : 7184296,
5867 : -1038690624,
5868 : 191744288,
5869 : -15976569,
5870 : 685532,
5871 : },
5872 : {
5873 : -1065738240,
5874 : 92529440,
5875 : 1049820800,
5876 : -159071040,
5877 : 9765746,
5878 : -1026166912,
5879 : 222441968,
5880 : -21674096,
5881 : 1086449,
5882 : },
5883 : {
5884 : -1063292288,
5885 : 105667272,
5886 : 1042545408,
5887 : -181239968,
5888 : 12735822,
5889 : -1011804416,
5890 : 252564208,
5891 : -28201010,
5892 : 1618050,
5893 : },
5894 : {
5895 : -1060522368,
5896 : 118772768,
5897 : 1034327424,
5898 : -203187744,
5899 : 16090877,
5900 : -995640448,
5901 : 282033216,
5902 : -35537312,
5903 : 2297847,
5904 : },
5905 : {
5906 : -1057429248,
5907 : 131842576,
5908 : 1025175744,
5909 : -224888688,
5910 : 19827000,
5911 : -977715456,
5912 : 310774336,
5913 : -43660960,
5914 : 3142946,
5915 : },
5916 : {
5917 : -1054014208,
5918 : 144871840,
5919 : 1015102400,
5920 : -246315216,
5921 : 23939442,
5922 : -958077632,
5923 : 338712160,
5924 : -52546696,
5925 : 4169866,
5926 : },
5927 : {
5928 : -1050277888,
5929 : 157856848,
5930 : 1004119424,
5931 : -267441264,
5932 : 28423184,
5933 : -936776384,
5934 : 365775328,
5935 : -62167296,
5936 : 5394616,
5937 : },
5938 : {
5939 : -1046221952,
5940 : 170794080,
5941 : 992240192,
5942 : -288242144,
5943 : 33272972,
5944 : -913867136,
5945 : 391895552,
5946 : -72493728,
5947 : 6832647,
5948 : },
5949 : {
5950 : -1041847104,
5951 : 183679248,
5952 : 979478784,
5953 : -308691648,
5954 : 38482756,
5955 : -889408832,
5956 : 417005280,
5957 : -83493976,
5958 : 8498661,
5959 : },
5960 : {
5961 : -1037154944,
5962 : 196508448,
5963 : 965851264,
5964 : -328765024,
5965 : 44046188,
5966 : -863464384,
5967 : 441040416,
5968 : -95134256,
5969 : 10406720,
5970 : },
5971 : {
5972 : -1032146752,
5973 : 209277728,
5974 : 951373888,
5975 : -348437760,
5976 : 49956480,
5977 : -836100864,
5978 : 463939520,
5979 : -107378776,
5980 : 12570113,
5981 : },
5982 : {
5983 : -1026824448,
5984 : 221983184,
5985 : 936064704,
5986 : -367685952,
5987 : 56206436,
5988 : -807388864,
5989 : 485645568,
5990 : -120189736,
5991 : 15001357,
5992 : },
5993 : {
5994 : -1021189120,
5995 : 234621280,
5996 : 919941824,
5997 : -386486528,
5998 : 62788576,
5999 : -777401728,
6000 : 506103424,
6001 : -133527832,
6002 : 17712200,
6003 : },
6004 : {
6005 : -1015242880,
6006 : 247187648,
6007 : 903025664,
6008 : -404815744,
6009 : 69694608,
6010 : -746217472,
6011 : 525260928,
6012 : -147351424,
6013 : 20713352,
6014 : },
6015 : {
6016 : -1008987264,
6017 : 259678912,
6018 : 885335808,
6019 : -422652128,
6020 : 76916424,
6021 : -713914432,
6022 : 543071424,
6023 : -161618048,
6024 : 24014862,
6025 : },
6026 : {
6027 : -1002424320,
6028 : 272090816,
6029 : 866894784,
6030 : -439973408,
6031 : 84444936,
6032 : -680577216,
6033 : 559490112,
6034 : -176282928,
6035 : 27625616,
6036 : },
6037 : {
6038 : -995556224,
6039 : 284419968,
6040 : 847724672,
6041 : -456758400,
6042 : 92271176,
6043 : -646290240,
6044 : 574476800,
6045 : -191300784,
6046 : 31553712,
6047 : },
6048 : {
6049 : -988384640,
6050 : 296662656,
6051 : 827848384,
6052 : -472987584,
6053 : 100385640,
6054 : -611140864,
6055 : 587994880,
6056 : -206624832,
6057 : 35806248,
6058 : },
6059 : {
6060 : -980912128,
6061 : 308814848,
6062 : 807290624,
6063 : -488639872,
6064 : 108778240,
6065 : -575220032,
6066 : 600012160,
6067 : -222206672,
6068 : 40389148,
6069 : },
6070 : {
6071 : -973140672,
6072 : 320873088,
6073 : 786076288,
6074 : -503697312,
6075 : 117438992,
6076 : -538618240,
6077 : 610500032,
6078 : -237997792,
6079 : 45307472,
6080 : },
6081 : {
6082 : -965072832,
6083 : 332833408,
6084 : 764231552,
6085 : -518140608,
6086 : 126357048,
6087 : -501429376,
6088 : 619433792,
6089 : -253947792,
6090 : 50565096,
6091 : },
6092 : {
6093 : -956710976,
6094 : 344692448,
6095 : 741782400,
6096 : -531953120,
6097 : 135521872,
6098 : -463747712,
6099 : 626794432,
6100 : -270007104,
6101 : 56164972,
6102 : },
6103 : {
6104 : -948057792,
6105 : 356446400,
6106 : 718756992,
6107 : -545116864,
6108 : 144921984,
6109 : -425669280,
6110 : 632565632,
6111 : -286123936,
6112 : 62108788,
6113 : },
6114 : {
6115 : -939115840,
6116 : 368091680,
6117 : 695183104,
6118 : -557616896,
6119 : 154546016,
6120 : -387290848,
6121 : 636735552,
6122 : -302247040,
6123 : 68397184,
6124 : },
6125 : {
6126 : -929887616,
6127 : 379625088,
6128 : 671088768,
6129 : -569437568,
6130 : 164382512,
6131 : -348707872,
6132 : 639297728,
6133 : -318325280,
6134 : 75029992,
6135 : },
6136 : {
6137 : -920376256,
6138 : 391042752,
6139 : 646503936,
6140 : -580564288,
6141 : 174419184,
6142 : -310019104,
6143 : 640249344,
6144 : -334306432,
6145 : 82005504,
6146 : },
6147 : {
6148 : -910584576,
6149 : 402341376,
6150 : 621458368,
6151 : -590983936,
6152 : 184644016,
6153 : -271321024,
6154 : 639591552,
6155 : -350139136,
6156 : 89321144,
6157 : },
6158 : {
6159 : -900515712,
6160 : 413517344,
6161 : 595983104,
6162 : -600683392,
6163 : 195044256,
6164 : -232711952,
6165 : 637331008,
6166 : -365771136,
6167 : 96973080,
6168 : },
6169 : {
6170 : -890172480,
6171 : 424567200,
6172 : 570108800,
6173 : -609651264,
6174 : 205607392,
6175 : -194287792,
6176 : 633478144,
6177 : -381151776,
6178 : 104956552,
6179 : },
6180 : {
6181 : -879557888,
6182 : 435488064,
6183 : 543866560,
6184 : -617876032,
6185 : 216320784,
6186 : -156143744,
6187 : 628046656,
6188 : -396230272,
6189 : 113265800,
6190 : },
6191 : {
6192 : -868675520,
6193 : 446276000,
6194 : 517288960,
6195 : -625348224,
6196 : 227170944,
6197 : -118375744,
6198 : 621056704,
6199 : -410956128,
6200 : 121893560,
6201 : },
6202 : {
6203 : -857528320,
6204 : 456928128,
6205 : 490407968,
6206 : -632058496,
6207 : 238145120,
6208 : -81076416,
6209 : 612530560,
6210 : -425280224,
6211 : 130832024,
6212 : },
6213 : {
6214 : -846120128,
6215 : 467441024,
6216 : 463256672,
6217 : -637998656,
6218 : 249229552,
6219 : -44338728,
6220 : 602496192,
6221 : -439153664,
6222 : 140071840,
6223 : },
6224 : {
6225 : -834454080,
6226 : 477811712,
6227 : 435867776,
6228 : -643161152,
6229 : 260411056,
6230 : -8252136,
6231 : 590984448,
6232 : -452529440,
6233 : 149603072,
6234 : },
6235 : {
6236 : -822533888,
6237 : 488036576,
6238 : 408275296,
6239 : -647540288,
6240 : 271675616,
6241 : 27094190,
6242 : 578031424,
6243 : -465360448,
6244 : 159414368,
6245 : },
6246 : {
6247 : -810363264,
6248 : 498112832,
6249 : 380512640,
6250 : -651130816,
6251 : 283009696,
6252 : 61614604,
6253 : 563675840,
6254 : -477601824,
6255 : 169493648,
6256 : },
6257 : {
6258 : -797945792,
6259 : 508037536,
6260 : 352612960,
6261 : -653928000,
6262 : 294399648,
6263 : 95226360,
6264 : 547961344,
6265 : -489210464,
6266 : 179828128,
6267 : },
6268 : {
6269 : -785285184,
6270 : 517807392,
6271 : 324610848,
6272 : -655928192,
6273 : 305831488,
6274 : 127847864,
6275 : 530934208,
6276 : -500143520,
6277 : 190403472,
6278 : },
6279 : {
6280 : -772385152,
6281 : 527419616,
6282 : 296540000,
6283 : -657129280,
6284 : 317291360,
6285 : 159401696,
6286 : 512644864,
6287 : -510360704,
6288 : 201205024,
6289 : },
6290 : {
6291 : -759250176,
6292 : 536870976,
6293 : 268435456,
6294 : -657529920,
6295 : 328765024,
6296 : 189812544,
6297 : 493147264,
6298 : -519823008,
6299 : 212216864,
6300 : },
6301 : {
6302 : -745883904,
6303 : 546158784,
6304 : 240330912,
6305 : -657129280,
6306 : 340238720,
6307 : 219009504,
6308 : 472498528,
6309 : -528493856,
6310 : 223422560,
6311 : },
6312 : {
6313 : -732290176,
6314 : 555280512,
6315 : 212259968,
6316 : -655928192,
6317 : 351698592,
6318 : 246925184,
6319 : 450757760,
6320 : -536338336,
6321 : 234805008,
6322 : },
6323 : {
6324 : -718473600,
6325 : 564232832,
6326 : 184258176,
6327 : -653928000,
6328 : 363130208,
6329 : 273494400,
6330 : 427989120,
6331 : -543323264,
6332 : 246345792,
6333 : },
6334 : {
6335 : -704437888,
6336 : 573013376,
6337 : 156358288,
6338 : -651130816,
6339 : 374520352,
6340 : 298658272,
6341 : 404257472,
6342 : -549418432,
6343 : 258026704,
6344 : },
6345 : {
6346 : -690187904,
6347 : 581619328,
6348 : 128595512,
6349 : -647540736,
6350 : 385854432,
6351 : 322359296,
6352 : 379631872,
6353 : -554595008,
6354 : 269827872,
6355 : },
6356 : {
6357 : -675727552,
6358 : 590048320,
6359 : 101002688,
6360 : -643161152,
6361 : 397119232,
6362 : 344546560,
6363 : 354182432,
6364 : -558827200,
6365 : 281729824,
6366 : },
6367 : {
6368 : -661061376,
6369 : 598297344,
6370 : 73614184,
6371 : -637998656,
6372 : 408300512,
6373 : 365171968,
6374 : 327982208,
6375 : -562091264,
6376 : 293711776,
6377 : },
6378 : {
6379 : -646194048,
6380 : 606364096,
6381 : 46463128,
6382 : -632058496,
6383 : 419384736,
6384 : 384192352,
6385 : 301106496,
6386 : -564365760,
6387 : 305752896,
6388 : },
6389 : {
6390 : -631129536,
6391 : 614246400,
6392 : 19581916,
6393 : -625348224,
6394 : 430359136,
6395 : 401569792,
6396 : 273631040,
6397 : -565632704,
6398 : 317832192,
6399 : },
6400 : {
6401 : -615872960,
6402 : 621941312,
6403 : -6995507,
6404 : -617876032,
6405 : 441209248,
6406 : 417269376,
6407 : 245635312,
6408 : -565875392,
6409 : 329927424,
6410 : },
6411 : {
6412 : -600428672,
6413 : 629446976,
6414 : -33237764,
6415 : -609651264,
6416 : 451922592,
6417 : 431262912,
6418 : 217197840,
6419 : -565080768,
6420 : 342016896,
6421 : },
6422 : {
6423 : -584801792,
6424 : 636760832,
6425 : -59112128,
6426 : -600683392,
6427 : 462485824,
6428 : 443525824,
6429 : 188400272,
6430 : -563238208,
6431 : 354078112,
6432 : },
6433 : {
6434 : -568996544,
6435 : 643880576,
6436 : -84587480,
6437 : -590983936,
6438 : 472886208,
6439 : 454038592,
6440 : 159323616,
6441 : -560339392,
6442 : 366088608,
6443 : },
6444 : {
6445 : -553017856,
6446 : 650804544,
6447 : -109633120,
6448 : -580564288,
6449 : 483110976,
6450 : 462787328,
6451 : 130050112,
6452 : -556379392,
6453 : 378026112,
6454 : },
6455 : {
6456 : -536871040,
6457 : 657529856,
6458 : -134217624,
6459 : -569437568,
6460 : 493147552,
6461 : 469762048,
6462 : 100663400,
6463 : -551355584,
6464 : 389867264,
6465 : },
6466 : {
6467 : -520560224,
6468 : 664055168,
6469 : -158311952,
6470 : -557616896,
6471 : 502983968,
6472 : 474958752,
6473 : 71245536,
6474 : -545268160,
6475 : 401589760,
6476 : },
6477 : {
6478 : -504091200,
6479 : 670378112,
6480 : -181886176,
6481 : -545116864,
6482 : 512608032,
6483 : 478378176,
6484 : 41880432,
6485 : -538120576,
6486 : 413170752,
6487 : },
6488 : {
6489 : -487468704,
6490 : 676496896,
6491 : -204911600,
6492 : -531953120,
6493 : 522008320,
6494 : 480025632,
6495 : 12650646,
6496 : -529918464,
6497 : 424587712,
6498 : },
6499 : {
6500 : -470697376,
6501 : 682409472,
6502 : -227360640,
6503 : -518140608,
6504 : 531172928,
6505 : 479912128,
6506 : -16361936,
6507 : -520670304,
6508 : 435818208,
6509 : },
6510 : {
6511 : -453782944,
6512 : 688114368,
6513 : -249205392,
6514 : -503697312,
6515 : 540091008,
6516 : 478053280,
6517 : -45074720,
6518 : -510387712,
6519 : 446839808,
6520 : },
6521 : {
6522 : -436730208,
6523 : 693609536,
6524 : -270419616,
6525 : -488639872,
6526 : 548751808,
6527 : 474469440,
6528 : -73407496,
6529 : -499084608,
6530 : 457630944,
6531 : },
6532 : {
6533 : -419544320,
6534 : 698893440,
6535 : -290977280,
6536 : -472987584,
6537 : 557144256,
6538 : 469186080,
6539 : -101280352,
6540 : -486777664,
6541 : 468169568,
6542 : },
6543 : {
6544 : -402230784,
6545 : 703964544,
6546 : -310853504,
6547 : -456758880,
6548 : 565258880,
6549 : 462233504,
6550 : -128614952,
6551 : -473486528,
6552 : 478434464,
6553 : },
6554 : {
6555 : -384794592,
6556 : 708821056,
6557 : -330023904,
6558 : -439973408,
6559 : 573084992,
6560 : 453646368,
6561 : -155334496,
6562 : -459233120,
6563 : 488405216,
6564 : },
6565 : {
6566 : -367241280,
6567 : 713461824,
6568 : -348464992,
6569 : -422652096,
6570 : 580613696,
6571 : 443464288,
6572 : -181363824,
6573 : -444041664,
6574 : 498060704,
6575 : },
6576 : {
6577 : -349576096,
6578 : 717885184,
6579 : -366154656,
6580 : -404815744,
6581 : 587835392,
6582 : 431731200,
6583 : -206630032,
6584 : -427939616,
6585 : 507382016,
6586 : },
6587 : {
6588 : -331804480,
6589 : 722089728,
6590 : -383070912,
6591 : -386486400,
6592 : 594741440,
6593 : 418495488,
6594 : -231061856,
6595 : -410956224,
6596 : 516349600,
6597 : },
6598 : {
6599 : -313931712,
6600 : 726074560,
6601 : -399193696,
6602 : -367686080,
6603 : 601323520,
6604 : 403809504,
6605 : -254591184,
6606 : -393123104,
6607 : 524945024,
6608 : },
6609 : {
6610 : -295963392,
6611 : 729838080,
6612 : -414503104,
6613 : -348437824,
6614 : 607573568,
6615 : 387729792,
6616 : -277151968,
6617 : -374474112,
6618 : 533150336,
6619 : },
6620 : {
6621 : -277904800,
6622 : 733379328,
6623 : -428980256,
6624 : -328764896,
6625 : 613483840,
6626 : 370317024,
6627 : -298680832,
6628 : -355045728,
6629 : 540949056,
6630 : },
6631 : {
6632 : -259761664,
6633 : 736697216,
6634 : -442607872,
6635 : -308691520,
6636 : 619047232,
6637 : 351635200,
6638 : -319117568,
6639 : -334875840,
6640 : 548323968,
6641 : },
6642 : {
6643 : -241539296,
6644 : 739790656,
6645 : -455369184,
6646 : -288242080,
6647 : 624257088,
6648 : 331752416,
6649 : -338404704,
6650 : -314004800,
6651 : 555260352,
6652 : },
6653 : {
6654 : -223243600,
6655 : 742658752,
6656 : -467248512,
6657 : -267441568,
6658 : 629106752,
6659 : 310739808,
6660 : -356488192,
6661 : -292474784,
6662 : 561743360,
6663 : },
6664 : {
6665 : -204879600,
6666 : 745300672,
6667 : -478231616,
6668 : -246315056,
6669 : 633590720,
6670 : 288671296,
6671 : -373317920,
6672 : -270328992,
6673 : 567759744,
6674 : },
6675 : {
6676 : -186453328,
6677 : 747715456,
6678 : -488305024,
6679 : -224888512,
6680 : 637703104,
6681 : 265624400,
6682 : -388846464,
6683 : -247613152,
6684 : 573296384,
6685 : },
6686 : {
6687 : -167970160,
6688 : 749902528,
6689 : -497456320,
6690 : -203187888,
6691 : 641438976,
6692 : 241678992,
6693 : -403030016,
6694 : -224374080,
6695 : 578342016,
6696 : },
6697 : {
6698 : -149435984,
6699 : 751861248,
6700 : -505674752,
6701 : -181239792,
6702 : 644794368,
6703 : 216917856,
6704 : -415829312,
6705 : -200660208,
6706 : 582885376,
6707 : },
6708 : {
6709 : -130856168,
6710 : 753590784,
6711 : -512949888,
6712 : -159070816,
6713 : 647764480,
6714 : 191425504,
6715 : -427208320,
6716 : -176520928,
6717 : 586917440,
6718 : },
6719 : {
6720 : -112236624,
6721 : 755090944,
6722 : -519273024,
6723 : -136708240,
6724 : 650345664,
6725 : 165289136,
6726 : -437135488,
6727 : -152007120,
6728 : 590429248,
6729 : },
6730 : {
6731 : -93582792,
6732 : 756361024,
6733 : -524636480,
6734 : -114178928,
6735 : 652535424,
6736 : 138597088,
6737 : -445582912,
6738 : -127170136,
6739 : 593413568,
6740 : },
6741 : {
6742 : -74900448,
6743 : 757400704,
6744 : -529033792,
6745 : -91510496,
6746 : 654330560,
6747 : 111439480,
6748 : -452526688,
6749 : -102062624,
6750 : 595864192,
6751 : },
6752 : {
6753 : -56195288,
6754 : 758209600,
6755 : -532459456,
6756 : -68730552,
6757 : 655729088,
6758 : 83908120,
6759 : -457947648,
6760 : -76737800,
6761 : 597775360,
6762 : },
6763 : {
6764 : -37473008,
6765 : 758787712,
6766 : -534909184,
6767 : -45866920,
6768 : 656729216,
6769 : 56095408,
6770 : -461830816,
6771 : -51249536,
6772 : 599143488,
6773 : },
6774 : {
6775 : -18739318,
6776 : 759134656,
6777 : -536380320,
6778 : -22947390,
6779 : 657329728,
6780 : 28094712,
6781 : -464165184,
6782 : -25652050,
6783 : 599965824,
6784 : },
6785 : {
6786 : -46,
6787 : 759250176,
6788 : -536870912,
6789 : -57,
6790 : 657530048,
6791 : 70,
6792 : -464943808,
6793 : -64,
6794 : 600239936,
6795 : }
6796 : };
6797 14958254 : void ivas_dirac_dec_get_response_fx(
6798 : const Word16 azimuth,
6799 : const Word16 elevation,
6800 : Word32 *response_fx, /*Q_out*/
6801 : const Word16 ambisonics_order,
6802 : Word16 Q_out )
6803 : {
6804 : Word16 index_azimuth, index_elevation;
6805 : Word16 el, e, az, q_diff;
6806 : Word32 cos_1_fx, cos_2_fx, sin_1_fx, cos_az_fx[3];
6807 : Word32 sin_az_fx[3];
6808 : Word32 f_fx;
6809 : Word32 c_fx_better;
6810 : Word16 l, m;
6811 : Word16 b, b1, b_2, b1_2, a;
6812 :
6813 14958254 : index_azimuth = add( azimuth, 180 ) % 360;
6814 14958254 : move16();
6815 14958254 : index_elevation = add( elevation, 90 );
6816 :
6817 14958254 : e = 1;
6818 14958254 : move16();
6819 :
6820 14958254 : if ( GT_16( index_elevation, 90 ) )
6821 : {
6822 4757175 : e = -1;
6823 : }
6824 :
6825 14958254 : el = index_elevation;
6826 14958254 : move16();
6827 :
6828 14958254 : if ( GT_16( index_elevation, 90 ) )
6829 : {
6830 4757175 : el = sub( 180, index_elevation );
6831 : }
6832 :
6833 14958254 : az = index_azimuth;
6834 14958254 : move16();
6835 :
6836 14958254 : if ( GT_16( index_azimuth, 180 ) )
6837 : {
6838 5063614 : az = sub( 360, index_azimuth );
6839 : }
6840 :
6841 14958254 : f_fx = 1;
6842 14958254 : move16();
6843 :
6844 14958254 : if ( GT_16( index_azimuth, 180 ) )
6845 : {
6846 5063614 : f_fx = -1;
6847 : }
6848 :
6849 14958254 : cos_1_fx = L_shr( dirac_gains_trg_term_fx[az][0], 1 ); // q30
6850 14958254 : cos_2_fx = L_shl( Mpy_32_32( cos_1_fx, cos_1_fx ), 1 ); // q30
6851 14958254 : sin_1_fx = L_shr( dirac_gains_trg_term_fx[az][1], 1 ); // q30
6852 :
6853 14958254 : if ( EQ_32( f_fx, -1 ) )
6854 : {
6855 5063614 : sin_1_fx = L_negate( sin_1_fx ); // q30
6856 : }
6857 14958254 : cos_az_fx[0] = cos_1_fx; // q30
6858 14958254 : move32();
6859 14958254 : cos_az_fx[1] = L_shl( L_sub( cos_2_fx, ONE_IN_Q29 /*0.5 q30*/ ), 1 ); /*q30*/
6860 14958254 : move32();
6861 14958254 : cos_az_fx[2] = L_sub( L_shl( Mpy_32_32( cos_1_fx, cos_az_fx[1] ), 2 ), cos_az_fx[0] /* cos_az_fx[0] q30*/ ); /*q30*/
6862 14958254 : move32();
6863 14958254 : sin_az_fx[0] = sin_1_fx; /*q30*/
6864 14958254 : move32();
6865 14958254 : sin_az_fx[1] = L_shl( Mpy_32_32( sin_1_fx, cos_1_fx ), 2 ); /*q30*/
6866 14958254 : move32();
6867 14958254 : sin_az_fx[2] = L_shl( Mpy_32_32( sin_1_fx, L_sub( cos_2_fx, ONE_IN_Q28 /*1/4 q30*/ ) ), 3 ); /*q30*/
6868 14958254 : move32();
6869 :
6870 14958254 : response_fx[0] = L_shl_sat( 1, Q_out ); // Q_out
6871 14958254 : move32();
6872 :
6873 14958254 : q_diff = sub( Q_out, 29 );
6874 :
6875 45838346 : FOR( l = 1; l <= ambisonics_order; l++ )
6876 : {
6877 30880092 : b_2 = imult1616( l, l );
6878 30880092 : b1_2 = add( b_2, shl( l, 1 ) );
6879 69581759 : FOR( m = 0; m < l; m += 2 )
6880 : {
6881 38701667 : b = b_2 + m;
6882 38701667 : a = dirac_gains_P_idx[b];
6883 :
6884 38701667 : c_fx_better = local_result_table[el][a]; // q30
6885 38701667 : move32();
6886 38701667 : response_fx[b] = L_shl( Mpy_32_32( c_fx_better, sin_az_fx[l - m - 1] ), q_diff ); // Q_out
6887 38701667 : move32();
6888 :
6889 38701667 : b1 = b1_2 - m;
6890 38701667 : response_fx[b1] = L_shl( Mpy_32_32( c_fx_better, cos_az_fx[l - m - 1] ), q_diff ); // Q_out
6891 38701667 : move32();
6892 : }
6893 :
6894 46801930 : FOR( m = 1; m < l; m += 2 )
6895 : {
6896 15921838 : b = b_2 + m;
6897 15921838 : a = dirac_gains_P_idx[b];
6898 15921838 : c_fx_better = local_result_table[el][a]; // q30
6899 15921838 : move32();
6900 15921838 : if ( EQ_16( e, -1 ) )
6901 : {
6902 5880724 : c_fx_better = L_negate( c_fx_better ); // q30
6903 : }
6904 15921838 : response_fx[b] = L_shl( Mpy_32_32( c_fx_better, sin_az_fx[l - m - 1] ), q_diff ); // Q_out
6905 15921838 : move32();
6906 :
6907 15921838 : b1 = b1_2 - m;
6908 15921838 : response_fx[b1] = L_shl( Mpy_32_32( c_fx_better, cos_az_fx[l - m - 1] ), q_diff ); // Q_out
6909 15921838 : move32();
6910 : }
6911 :
6912 30880092 : b = add( b_2, l );
6913 30880092 : a = dirac_gains_P_idx[b];
6914 30880092 : c_fx_better = local_result_table_2[el][a]; // q30
6915 30880092 : move32();
6916 30880092 : IF( EQ_16( s_and( l, 0x01 ), 1 ) )
6917 : {
6918 22779829 : if ( EQ_16( e, -1 ) )
6919 : {
6920 7643543 : c_fx_better = L_negate( c_fx_better ); // q30
6921 : }
6922 : }
6923 30880092 : response_fx[b] = L_shl( c_fx_better, sub( Q_out, 30 ) ); // Q_out
6924 30880092 : move32();
6925 : }
6926 :
6927 14958254 : return;
6928 : }
6929 :
6930 : /*This is a derivate to ivas_dirac_dec_get_response_fx with fixed Q_out=29*/
6931 67224604 : void ivas_dirac_dec_get_response_fx_29(
6932 : const Word16 azimuth,
6933 : const Word16 elevation,
6934 : Word32 *response_fx, /*Q_out*/
6935 : const Word16 ambisonics_order )
6936 : {
6937 : Word16 index_azimuth, index_elevation;
6938 : Word16 el, az;
6939 : Word32 cos_1_fx, cos_2_fx, sin_1_fx, cos_az_fx[3];
6940 : Word32 sin_az_fx[3];
6941 : Word32 f_fx;
6942 : Word32 c_fx_better;
6943 : Word16 l, m;
6944 : Word16 b, b1, b_2, b1_2;
6945 : // Word16 Q_out = 29;
6946 :
6947 67224604 : index_azimuth = add( azimuth, 180 ) % 360;
6948 67224604 : move16();
6949 67224604 : index_elevation = add( elevation, 90 );
6950 :
6951 67224604 : Word32 e_fac = L_add( 0x7FFFFFFF, 0 );
6952 :
6953 67224604 : if ( GT_16( index_elevation, 90 ) )
6954 : {
6955 20679472 : e_fac = MIN_32;
6956 : }
6957 :
6958 :
6959 67224604 : el = index_elevation;
6960 67224604 : move16();
6961 :
6962 67224604 : if ( GT_16( index_elevation, 90 ) )
6963 : {
6964 20679472 : el = sub( 180, index_elevation );
6965 : }
6966 :
6967 67224604 : az = index_azimuth;
6968 67224604 : move16();
6969 :
6970 67224604 : if ( GT_16( index_azimuth, 180 ) )
6971 : {
6972 27575365 : az = sub( 360, index_azimuth );
6973 : }
6974 :
6975 67224604 : f_fx = 1;
6976 67224604 : move16();
6977 :
6978 67224604 : if ( GT_16( index_azimuth, 180 ) )
6979 : {
6980 27575365 : f_fx = -1;
6981 : }
6982 :
6983 67224604 : cos_1_fx = L_shr( dirac_gains_trg_term_fx[az][0], 1 ); // q30
6984 67224604 : cos_2_fx = L_shl( Mpy_32_32( cos_1_fx, cos_1_fx ), 1 ); // q30
6985 67224604 : sin_1_fx = L_shr( dirac_gains_trg_term_fx[az][1], 1 ); // q30
6986 :
6987 67224604 : if ( EQ_32( f_fx, -1 ) )
6988 : {
6989 27575365 : sin_1_fx = L_negate( sin_1_fx ); // q30
6990 : }
6991 67224604 : cos_az_fx[0] = cos_1_fx; // q30
6992 67224604 : move32();
6993 67224604 : cos_az_fx[1] = L_shl( L_sub( cos_2_fx, ONE_IN_Q29 /*0.5 q30*/ ), 1 ); /*q30*/
6994 67224604 : move32();
6995 67224604 : cos_az_fx[2] = L_sub( L_shl( Mpy_32_32( cos_1_fx, cos_az_fx[1] ), 2 ), cos_az_fx[0] /* cos_az_fx[0] q30*/ ); /*q30*/
6996 67224604 : move32();
6997 67224604 : sin_az_fx[0] = sin_1_fx; /*q30*/
6998 67224604 : move32();
6999 67224604 : sin_az_fx[1] = L_shl( Mpy_32_32( sin_1_fx, cos_1_fx ), 2 ); /*q30*/
7000 67224604 : move32();
7001 67224604 : sin_az_fx[2] = L_shl( Mpy_32_32( sin_1_fx, L_sub( cos_2_fx, ONE_IN_Q28 /*1/4 q30*/ ) ), 3 ); /*q30*/
7002 67224604 : move32();
7003 :
7004 67224604 : response_fx[0] = 0x20000000;
7005 67224604 : move32();
7006 :
7007 260590288 : FOR( l = 1; l <= ambisonics_order; l++ )
7008 : {
7009 : Word16 a;
7010 193365684 : b_2 = imult1616( l, l );
7011 193365684 : b1_2 = add( b_2, shl( l, 1 ) );
7012 445929408 : FOR( m = 0; m < l; m += 2 )
7013 : {
7014 252563724 : b = b_2 + m;
7015 252563724 : a = dirac_gains_P_idx[b];
7016 :
7017 252563724 : c_fx_better = local_result_table[el][a]; // q30
7018 252563724 : move32();
7019 252563724 : response_fx[b] = Mpy_32_32( c_fx_better, sin_az_fx[l - m - 1] ); // Q_out
7020 252563724 : move32();
7021 :
7022 252563724 : b1 = b1_2 - m;
7023 252563724 : response_fx[b1] = Mpy_32_32( c_fx_better, cos_az_fx[l - m - 1] ); // Q_out
7024 252563724 : move32();
7025 : }
7026 :
7027 319506764 : FOR( m = 1; m < l; m += 2 )
7028 : {
7029 126141080 : b = b_2 + m;
7030 126141080 : a = dirac_gains_P_idx[b];
7031 126141080 : c_fx_better = local_result_table[el][a]; // q30
7032 126141080 : move32();
7033 126141080 : c_fx_better = Mpy_32_32( c_fx_better, e_fac ); // q30
7034 126141080 : response_fx[b] = Mpy_32_32( c_fx_better, sin_az_fx[l - m - 1] ); // Q_out
7035 126141080 : move32();
7036 :
7037 126141080 : b1 = b1_2 - m;
7038 126141080 : response_fx[b1] = Mpy_32_32( c_fx_better, cos_az_fx[l - m - 1] ); // Q_out
7039 126141080 : move32();
7040 : }
7041 :
7042 193365684 : b = add( b_2, l );
7043 193365684 : a = dirac_gains_P_idx[b];
7044 193365684 : c_fx_better = local_result_table_2[el][a]; // q30
7045 193365684 : move32();
7046 193365684 : if ( s_and( l, 0x01 ) )
7047 : {
7048 126422644 : c_fx_better = Mpy_32_32( c_fx_better, e_fac ); // q30
7049 : }
7050 193365684 : response_fx[b] = L_shl( c_fx_better, -1 ); // Q_out
7051 193365684 : move32();
7052 : }
7053 67224604 : return;
7054 : }
7055 : /*-----------------------------------------------------------------------------------------*
7056 : * Function ivas_get_bits_to_encode
7057 : *
7058 : * Get number of bits required to encode the input value
7059 : *-----------------------------------------------------------------------------------------*/
7060 :
7061 264950 : Word16 ivas_get_bits_to_encode(
7062 : Word32 val )
7063 : {
7064 264950 : Word16 bits_req = 0;
7065 264950 : move16();
7066 :
7067 264950 : assert( val >= 0 );
7068 :
7069 482124 : WHILE( val )
7070 : {
7071 217174 : bits_req = add( bits_req, 1 );
7072 217174 : val = L_shr( val, 1 );
7073 : }
7074 :
7075 264950 : return bits_req;
7076 : }
7077 :
7078 :
7079 : /*-----------------------------------------------------------------------------------------*
7080 : * Function ivas_spar_set_bitrate_config()
7081 : *
7082 : * Set SPAR bitrate config
7083 : *-----------------------------------------------------------------------------------------*/
7084 :
7085 5453 : void ivas_spar_set_bitrate_config_fx(
7086 : ivas_spar_md_com_cfg *pSpar_md_cfg, /* i/o: SPAR MD config. handle */
7087 : const Word16 table_idx, /* i : config. table index */
7088 : const Word16 num_bands, /* i : number of bands */
7089 : const Word16 dirac2spar_md_flag,
7090 : const Word16 enc_flag,
7091 : const Word16 pca_flag,
7092 : const Word16 agc_flag )
7093 : {
7094 : Word32 ivas_total_brate;
7095 : Word16 i, total_bits, max_bits, code, length;
7096 : Word16 sba_order;
7097 : Word16 md_coding_bits_header;
7098 : Word16 agc_bits, pca_bits, num_PR_bits_dirac_bands;
7099 : Word16 bits_PR, bits_C, bits_P;
7100 : Word16 wc_coarse_strat;
7101 : Word16 n_input, n_dmx, n_dec;
7102 : Word16 quant_strat;
7103 : Word16 bands_bw;
7104 :
7105 5453 : pSpar_md_cfg->nchan_transport = ivas_spar_br_table_consts[table_idx].nchan_transport;
7106 5453 : move16();
7107 :
7108 17855 : FOR( i = 0; i < pSpar_md_cfg->nchan_transport; i++ )
7109 : {
7110 12402 : pSpar_md_cfg->max_freq_per_chan[i] = ivas_spar_br_table_consts[table_idx].fpcs;
7111 12402 : move16();
7112 : }
7113 :
7114 5453 : pSpar_md_cfg->active_w = ivas_spar_br_table_consts[table_idx].active_w;
7115 5453 : move16();
7116 5453 : pSpar_md_cfg->agc_bits_ch_idx = ivas_spar_br_table_consts[table_idx].agc_bits_ch_idx;
7117 5453 : move16();
7118 :
7119 5453 : ivas_spar_get_uniform_quant_strat_fx( pSpar_md_cfg, table_idx );
7120 :
7121 5453 : pSpar_md_cfg->quant_strat_bits = ivas_get_bits_to_encode( MAX_QUANT_STRATS );
7122 5453 : move16();
7123 :
7124 : /* BLOCK: getEntropyCoderModels */
7125 :
7126 5453 : pSpar_md_cfg->remix_unmix_order = ivas_spar_br_table_consts[table_idx].dmx_str;
7127 5453 : move16();
7128 :
7129 : /* bits per block*/
7130 5453 : total_bits = 0;
7131 5453 : move16();
7132 5453 : max_bits = 0;
7133 5453 : move16();
7134 :
7135 5453 : ivas_total_brate = ivas_spar_br_table_consts[table_idx].ivas_total_brate;
7136 5453 : move32();
7137 5453 : sba_order = ivas_spar_br_table_consts[table_idx].sba_order;
7138 5453 : move16();
7139 5453 : ivas_get_spar_table_idx_fx( ivas_total_brate, sba_order, ivas_spar_br_table_consts[table_idx].bwidth, &length, &code );
7140 : Word16 temp;
7141 : Word16 div1;
7142 17855 : FOR( i = 0; i < pSpar_md_cfg->nchan_transport; i++ )
7143 : {
7144 12402 : total_bits = add( total_bits, extract_l( Mpy_32_32( ivas_spar_br_table_consts[table_idx].core_brs[i][0], ONE_BY_FRAMES_PER_SEC_Q31 ) ) );
7145 12402 : max_bits = add( max_bits, extract_l( Mpy_32_32( ivas_spar_br_table_consts[table_idx].core_brs[i][1], ONE_BY_FRAMES_PER_SEC_Q31 ) ) );
7146 : }
7147 :
7148 : /* (int16_t) ( ivas_total_brate / FRAMES_PER_SEC ) */
7149 5453 : div1 = extract_l( Mpy_32_32( ivas_total_brate, ONE_BY_FRAMES_PER_SEC_Q31 /*1/FRAMES_PER_SEC Q31*/ ) ); /*31-31=>0*/
7150 5453 : pSpar_md_cfg->tgt_bits_per_blk = sub( div1, add( add( add( add( add( IVAS_FORMAT_SIGNALING_NBITS_EXTENDED, SBA_PLANAR_BITS ), 0 ), SBA_ORDER_BITS ), length ), total_bits ) );
7151 5453 : pSpar_md_cfg->max_bits_per_blk = sub( div1, add( add( add( add( add( IVAS_FORMAT_SIGNALING_NBITS_EXTENDED, SBA_PLANAR_BITS ), 0 ), SBA_ORDER_BITS ), length ), max_bits ) );
7152 5453 : move16();
7153 5453 : move16();
7154 :
7155 5453 : md_coding_bits_header = add( SPAR_NUM_CODING_STRAT_BITS, pSpar_md_cfg->quant_strat_bits );
7156 :
7157 5453 : pSpar_md_cfg->tgt_bits_per_blk = sub( pSpar_md_cfg->tgt_bits_per_blk, md_coding_bits_header );
7158 5453 : pSpar_md_cfg->max_bits_per_blk = sub( pSpar_md_cfg->max_bits_per_blk, md_coding_bits_header );
7159 5453 : move16();
7160 5453 : move16();
7161 :
7162 5453 : IF( LT_32( ivas_total_brate, IVAS_24k4 ) )
7163 : {
7164 1091 : bands_bw = 2;
7165 1091 : move16();
7166 : }
7167 : ELSE
7168 : {
7169 4362 : bands_bw = 1;
7170 4362 : move16();
7171 : }
7172 :
7173 5453 : pSpar_md_cfg->tgt_bits_per_blk = extract_l( Mpy_32_32( i_mult( pSpar_md_cfg->tgt_bits_per_blk, num_bands ), 178956971 /* 1 / IVAS_MAX_NUM_BANDS in Q31 */ ) ); /*Q0*/
7174 5453 : pSpar_md_cfg->max_bits_per_blk = extract_l( Mpy_32_32( i_mult( pSpar_md_cfg->max_bits_per_blk, num_bands ), 178956971 /* 1 / IVAS_MAX_NUM_BANDS in Q31 */ ) ); /*Q0*/
7175 :
7176 5453 : pSpar_md_cfg->tgt_bits_per_blk = add( pSpar_md_cfg->tgt_bits_per_blk, md_coding_bits_header );
7177 5453 : pSpar_md_cfg->max_bits_per_blk = add( pSpar_md_cfg->max_bits_per_blk, md_coding_bits_header );
7178 5453 : move16();
7179 5453 : move16();
7180 5453 : move16();
7181 5453 : move16();
7182 :
7183 5453 : IF( enc_flag )
7184 : {
7185 : /*calculate the actual worst case bits*/
7186 3592 : IF( GE_32( ivas_total_brate, BRATE_SPAR_Q_STRAT ) )
7187 : {
7188 708 : quant_strat = QUANT_STRAT_0;
7189 708 : move16();
7190 : }
7191 : ELSE
7192 : {
7193 2884 : quant_strat = QUANT_STRAT_2;
7194 2884 : move16();
7195 : }
7196 :
7197 3592 : IF( EQ_16( dirac2spar_md_flag, 1 ) )
7198 : {
7199 3402 : num_PR_bits_dirac_bands = sub( num_bands, SPAR_DIRAC_SPLIT_START_BAND );
7200 3402 : move16();
7201 : }
7202 : ELSE
7203 : {
7204 190 : num_PR_bits_dirac_bands = 0;
7205 190 : move16();
7206 : }
7207 3592 : div1 = BASOP_Util_Divide3232_Scale( num_PR_bits_dirac_bands, bands_bw, &temp ); /*15-temp*/
7208 3592 : num_PR_bits_dirac_bands = shr( div1, sub( 15, temp ) ); /*q0*/
7209 3592 : num_PR_bits_dirac_bands = s_max( 0, num_PR_bits_dirac_bands );
7210 3592 : num_PR_bits_dirac_bands = i_mult( num_PR_bits_dirac_bands, DIRAC_TO_SPAR_HBR_PRED_CHS );
7211 :
7212 3592 : n_input = ivas_sba_get_nchan_metadata_fx( sba_order, ivas_total_brate );
7213 3592 : n_dmx = ivas_spar_br_table_consts[table_idx].nchan_transport;
7214 3592 : move16();
7215 3592 : n_dec = sub( n_input, n_dmx );
7216 3592 : bits_PR = ivas_spar_br_table_consts_fx[table_idx].q_lvls[quant_strat][0];
7217 3592 : move16();
7218 3592 : num_PR_bits_dirac_bands = i_mult( num_PR_bits_dirac_bands, bits_PR );
7219 3592 : bits_PR = i_mult( bits_PR, sub( n_input, 1 ) );
7220 3592 : bits_C = i_mult( ivas_spar_br_table_consts_fx[table_idx].q_lvls[quant_strat][1], i_mult( sub( n_dmx, 1 ), n_dec ) );
7221 3592 : bits_P = i_mult( ivas_spar_br_table_consts_fx[table_idx].q_lvls[quant_strat][2], n_dec );
7222 :
7223 3592 : wc_coarse_strat = add( add( bits_PR, bits_C ), bits_P );
7224 3592 : wc_coarse_strat = i_mult( wc_coarse_strat, num_bands );
7225 3592 : div1 = BASOP_Util_Divide3232_Scale( wc_coarse_strat, bands_bw, &temp ); // q=15-temp
7226 3592 : wc_coarse_strat = shr( div1, sub( 15, temp ) ); // q0
7227 3592 : wc_coarse_strat = sub( wc_coarse_strat, num_PR_bits_dirac_bands );
7228 3592 : wc_coarse_strat = add( wc_coarse_strat, md_coding_bits_header );
7229 :
7230 3592 : if ( LT_16( pSpar_md_cfg->max_bits_per_blk, wc_coarse_strat ) )
7231 : {
7232 0 : assert( 0 );
7233 : }
7234 :
7235 3592 : IF( agc_flag )
7236 : {
7237 1278 : IF( EQ_16( pSpar_md_cfg->nchan_transport, 1 ) )
7238 : {
7239 1278 : agc_bits = AGC_BITS_PER_CH;
7240 1278 : move16();
7241 : }
7242 : ELSE
7243 : {
7244 0 : agc_bits = add( i_mult( AGC_BITS_PER_CH, pSpar_md_cfg->nchan_transport ), AGC_SIGNALLING_BITS );
7245 : }
7246 : }
7247 : ELSE
7248 : {
7249 2314 : agc_bits = AGC_SIGNALLING_BITS;
7250 2314 : move16();
7251 : }
7252 :
7253 3592 : test();
7254 3592 : IF( EQ_32( ivas_total_brate, PCA_BRATE ) && EQ_32( sba_order, SBA_FOA_ORDER ) )
7255 : {
7256 74 : pca_bits = 1;
7257 74 : move16();
7258 74 : IF( pca_flag )
7259 : {
7260 8 : pca_bits = add( pca_bits, sub( add( IVAS_PCA_QBITS, IVAS_PCA_QBITS ), 1 ) );
7261 : }
7262 : }
7263 : ELSE
7264 : {
7265 3518 : pca_bits = 0;
7266 3518 : move16();
7267 : }
7268 :
7269 3592 : pSpar_md_cfg->max_md_bits_spar = add( add( pSpar_md_cfg->max_bits_per_blk, agc_bits ), pca_bits );
7270 3592 : move16();
7271 : }
7272 :
7273 5453 : return;
7274 : }
7275 : /*-----------------------------------------------------------------------------------------*
7276 : * Function ivas_spar_bitrate_dist()
7277 : *
7278 : * Set SPAR bitrate distribution
7279 : *-----------------------------------------------------------------------------------------*/
7280 :
7281 24650 : void ivas_spar_bitrate_dist_fx(
7282 : Word32 core_brates_act[], /* o : bitrates per core-coder */
7283 : const Word16 nAvailBits, /* i : number of available bits */
7284 : const Word32 ivas_total_brate, /* i : IVAS total bitrate */
7285 : const Word16 sba_order, /* i : Ambisonic (SBA) order */
7286 : const Word16 bwidth /* i : audio bandwidth */
7287 : )
7288 : {
7289 : Word16 i, nchan_transport, table_idx, bitlen;
7290 : Word16 core_bits_act[FOA_CHANNELS], core_range_bits[FOA_CHANNELS];
7291 : Word16 sum_core_act_bits, residual_bits, overflow_bits;
7292 :
7293 24650 : table_idx = ivas_get_spar_table_idx_fx( ivas_total_brate, sba_order, bwidth, &bitlen, NULL );
7294 :
7295 24650 : nchan_transport = ivas_spar_br_table_consts[table_idx].nchan_transport;
7296 24650 : move16();
7297 :
7298 24650 : sum_core_act_bits = 0;
7299 24650 : move16();
7300 123250 : FOR( i = 0; i < nchan_transport; i++ )
7301 : {
7302 98600 : core_bits_act[i] = extract_l( Mpy_32_16_1( ivas_spar_br_table_consts[table_idx].core_brs[i][0], INV_FRAME_PER_SEC_Q15 /*1/FRAMES_PER_SEC Q15*/ ) ); /*q0*/
7303 98600 : move16();
7304 :
7305 98600 : sum_core_act_bits = add( sum_core_act_bits, core_bits_act[i] );
7306 : }
7307 :
7308 24650 : residual_bits = sub( nAvailBits, sum_core_act_bits );
7309 :
7310 : /* First compute core-coder bits as per bitrate distribution table and MD bitrate*/
7311 24650 : IF( residual_bits > 0 )
7312 : {
7313 3874 : FOR( i = 0; i < nchan_transport; i++ )
7314 : {
7315 3874 : core_range_bits[i] = extract_l( Mpy_32_16_1( L_sub( ivas_spar_br_table_consts[table_idx].core_brs[i][2], ivas_spar_br_table_consts[table_idx].core_brs[i][0] ), INV_FRAME_PER_SEC_Q15 /*1/FRAMES_PER_SEC Q15*/ ) ); /*q0*/
7316 3874 : move16();
7317 3874 : core_bits_act[i] = add( core_bits_act[i], s_min( residual_bits, core_range_bits[i] ) );
7318 3874 : move16();
7319 3874 : residual_bits = sub( residual_bits, core_range_bits[i] );
7320 :
7321 3874 : if ( residual_bits <= 0 )
7322 : {
7323 2628 : BREAK;
7324 : }
7325 : }
7326 : }
7327 : ELSE
7328 : {
7329 110110 : FOR( i = 0; i < nchan_transport; i++ )
7330 : {
7331 88088 : core_range_bits[i] = extract_l( Mpy_32_16_1( L_sub( ivas_spar_br_table_consts[table_idx].core_brs[i][0], ivas_spar_br_table_consts[table_idx].core_brs[i][1] ), INV_FRAME_PER_SEC_Q15 /*1/FRAMES_PER_SEC Q15*/ ) ); /*q0*/
7332 88088 : move16();
7333 : }
7334 :
7335 22022 : overflow_bits = negate( residual_bits );
7336 :
7337 104339 : FOR( i = 0; i < nchan_transport; i++ )
7338 : {
7339 84604 : core_bits_act[nchan_transport - 1 - i] = sub( core_bits_act[nchan_transport - 1 - i], s_min( overflow_bits, core_range_bits[nchan_transport - 1 - i] ) );
7340 84604 : move16();
7341 84604 : overflow_bits = sub( overflow_bits, core_range_bits[nchan_transport - 1 - i] );
7342 :
7343 84604 : if ( overflow_bits <= 0 )
7344 : {
7345 2287 : BREAK;
7346 : }
7347 : }
7348 :
7349 22022 : IF( overflow_bits > 0 )
7350 : {
7351 : Word16 overflow_bits_ch;
7352 19735 : overflow_bits_ch = idiv1616( overflow_bits, nchan_transport );
7353 :
7354 98675 : FOR( i = 0; i < nchan_transport; i++ )
7355 : {
7356 78940 : core_bits_act[i] = sub( core_bits_act[i], overflow_bits_ch );
7357 78940 : move16();
7358 78940 : overflow_bits = sub( overflow_bits, overflow_bits_ch );
7359 : }
7360 :
7361 19735 : core_bits_act[nchan_transport - 1] = sub( core_bits_act[nchan_transport - 1], s_max( 0, overflow_bits ) );
7362 19735 : move16();
7363 : }
7364 : }
7365 :
7366 123250 : FOR( i = 0; i < nchan_transport; i++ )
7367 : {
7368 98600 : core_brates_act[i] = L_mult0( core_bits_act[i], FRAMES_PER_SEC );
7369 98600 : move32();
7370 : }
7371 :
7372 24650 : return;
7373 : }
|