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