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