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 "options.h"
35 : #include <math.h>
36 : #include "cnst.h"
37 : #include "prot_fx.h"
38 : #include "ivas_cnst.h"
39 : #include "ivas_rom_com.h"
40 : #include "wmc_auto.h"
41 : #include "ivas_prot_fx.h"
42 :
43 :
44 : /*-------------------------------------------------------------------
45 : * Local constants
46 : *-------------------------------------------------------------------*/
47 :
48 : #define A_GFILT_FX ( Word16 )( 0x6666 ) /* LP-filter coefficient for coherence and sidegain */
49 : #define ONE_MINUS_A_GFILT_FX ( Word16 )( 0x199A ) /* LP-filter coefficient for coherence and sidegain */
50 : #define SKIP_XFADE_FRAMES 2
51 :
52 : /* DTX/CNG */
53 : #define MAX_K 50
54 : #define ONE_BY_MAX_K ( Word16 )( 0x028F )
55 : #define STEREO_TD_PS_CORR_FILT_FX 1717986918
56 : #define STEREO_TD_PS_CORR_FILT_Q31 1717986944
57 : #define ONE_MINUS_STEREO_TD_PS_CORR_FILT_Q31 429496704
58 : #define MAX_XFADE_FX 50
59 : #define CM_INIT 50
60 : #define CORR_INIT 8
61 : #define SID_INIT 6
62 : #define STEREO_CNA_LR_CORR_LT_FILT_FX 2040109440 /* long-term averaging factor for L/R correlation estimation in stereo CNA */
63 : #define STEREO_CNA_ILD_LT_FILT_FX 1932735283 /* long-term averaging factor for ILD estimation in stereo CNA */
64 :
65 : /*-------------------------------------------------------------------
66 : * stereo_dft_dec_sid_coh()
67 : *
68 : * Decode coherence vector
69 : *-------------------------------------------------------------------*/
70 :
71 : /*-------------------------------------------------------------------
72 : * stereo_dft_generate_comfort_noise_fx()
73 : *
74 : * Generate the comfort noise based on the target noise level for the CLDFB part
75 : *-------------------------------------------------------------------*/
76 :
77 10992 : static void stereo_dft_generate_comfort_noise_fx(
78 : STEREO_DFT_DEC_DATA_HANDLE hStereoDft, /* i/o: DFT Stereo decoder handle */
79 : STEREO_CNG_DEC_HANDLE hStereoCng, /* i/o: Stereo CNG data structure */
80 : const Word16 last_element_mode, /* i : last element mode Q0*/
81 : Decoder_State *st, /* i/o: Core coder decoder state */
82 : Word32 DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i/o: DFT buffers q_dft*/
83 : Decoder_State *st1, /* i/o: Core coder decoder state secondary channel */
84 : const Word16 targetGain, /* i : ICA target gain Q13*/
85 : const Word16 chan, /* i : channel number Q0*/
86 : const Word16 output_frame, /* i : output frame size Q0*/
87 : Word16 q_dft /* i : Q of DFT */
88 : )
89 : {
90 : Word16 i, j, k;
91 : Word32 *ptr_level, *ptr_shb, *ptr_r, *ptr_i;
92 : HANDLE_FD_CNG_COM hFdCngCom;
93 : Word16 numSlots;
94 : Word16 scale, inv_scale, tmp_16;
95 : Word32 lp_noise;
96 : Word16 lp_noise_e;
97 : Word32 tmp, enr;
98 : Word16 q_enr;
99 : Word32 shb_shape[L_FRAME16k];
100 : Word16 q_shb_shape;
101 : Word32 *ptr0, *ptr1, *ptr2;
102 : Word16 dmpf[M + 2], Atmp[M + 2];
103 : Word32 cngNoiseLevel_upd[L_FRAME16k], cngNoiseLevel_hist[L_FRAME16k - 2];
104 : Word16 e_norm_temp[L_FRAME16k];
105 : Word32 *ptr_tmp, *ptr_cng;
106 : Word64 E0, E1;
107 : Word16 E0_e, E1_e;
108 : Word16 b, q_cngNoiseLevel_upd, q_cngNoiseLevel;
109 : Word32 *pSideGain;
110 : Word16 gamma;
111 : Word16 c, c_e;
112 : Word16 scaleMS;
113 : Word16 scaleAvg, scaleAvg_e;
114 : Word16 LR_ratio; /* Q15 */
115 : Word32 factor;
116 : Word16 alpha;
117 : Word32 ftmp;
118 : Word16 trigo_dec[STEREO_DFT32MS_N_16k / 2 + 1];
119 : const Word16 *pTrigo;
120 : Word16 trigo_step;
121 : Word32 tmp32_1, tmp32_2;
122 : Word16 q_div, q_sqrt1, q_sqrt2, q_sqrt, sqrt_res;
123 : Word16 q_shift, q_shift_1, q_shift_2, min_q;
124 :
125 10992 : hFdCngCom = st->hFdCngDec->hFdCngCom;
126 :
127 10992 : push_wmops( "DFT_CNG" );
128 :
129 10992 : set16_fx( dmpf, 0, M + 2 );
130 10992 : set16_fx( Atmp, 0, M + 2 );
131 :
132 10992 : set_zero_fx( DFT[chan], STEREO_DFT_BUF_MAX );
133 10992 : set32_fx( cngNoiseLevel_upd, 0, L_FRAME16k );
134 :
135 10992 : enr = 0; /* Eliminates compiler warning. They are always set before they are used */
136 10992 : move32();
137 10992 : q_enr = 0;
138 10992 : move16();
139 10992 : E0 = 0;
140 10992 : move64();
141 10992 : E0_e = 0;
142 10992 : move16();
143 10992 : E1 = 0;
144 10992 : move64();
145 10992 : E1_e = 0;
146 10992 : move16();
147 10992 : lp_noise = 0;
148 10992 : move32();
149 10992 : lp_noise_e = 0;
150 10992 : move16();
151 10992 : q_shb_shape = 0;
152 10992 : move16();
153 :
154 10992 : IF( chan == 0 )
155 : {
156 5496 : pSideGain = hStereoDft->side_gain_fx + STEREO_DFT_NBDIV * STEREO_DFT_BAND_MAX; /* Q31 */
157 37503 : FOR( b = 0; b < hStereoDft->nbands; b++ )
158 : {
159 32007 : IF( hStereoCng->xfade_frame_counter == 0 )
160 : {
161 610 : hStereoDft->g_state_fx[b] = extract_h( *pSideGain++ ); /* Q15 */
162 610 : move16();
163 : }
164 : ELSE
165 : {
166 31397 : hStereoDft->g_state_fx[b] = add( mult( ONE_MINUS_A_GFILT_FX, extract_h( *pSideGain++ ) ), mult( A_GFILT_FX, hStereoDft->g_state_fx[b] ) ); /* Q15 */
167 31397 : move16();
168 : }
169 :
170 32007 : test();
171 32007 : IF( hStereoCng->first_SID )
172 : {
173 86 : IF( hStereoCng->first_SID_after_TD )
174 : {
175 0 : hStereoCng->cm_fx[b] = extract_h( Mpy_32_32( hStereoCng->c_LR_LT_fx, hStereoCng->c_LR_LT_fx ) ); /* Q15 */
176 0 : move16();
177 : }
178 : ELSE
179 : {
180 86 : hStereoCng->cm_fx[b] = hStereoCng->coh_fx[b]; /* Q15 */
181 86 : move16();
182 : }
183 : }
184 31921 : ELSE IF( LT_16( hStereoCng->nr_dft_frames, CM_INIT ) && LT_16( hStereoCng->nr_sid_frames, SID_INIT ) )
185 : {
186 0 : IF( GT_16( hStereoCng->nr_corr_frames, CORR_INIT ) )
187 : {
188 0 : hStereoCng->cm_fx[b] = extract_h( Mpy_32_32( hStereoCng->c_LR_LT_fx, hStereoCng->c_LR_LT_fx ) ); /* Q15 */
189 0 : move16();
190 : }
191 : ELSE
192 : {
193 0 : hStereoCng->cm_fx[b] = add( mult( ONE_MINUS_A_GFILT_FX, hStereoCng->coh_fx[b] ), mult( A_GFILT_FX, hStereoCng->cm_fx[b] ) ); /* Q15 */
194 0 : move16();
195 : }
196 : }
197 : ELSE
198 : {
199 31921 : hStereoCng->cm_fx[b] = add( mult( ONE_MINUS_A_GFILT_FX, hStereoCng->coh_fx[b] ), mult( A_GFILT_FX, hStereoCng->cm_fx[b] ) ); /* Q15 */
200 31921 : move16();
201 : }
202 : }
203 :
204 5496 : IF( hStereoCng->first_SID_after_TD )
205 : {
206 14 : scaleAvg = 0;
207 14 : move16();
208 14 : scaleAvg_e = 15;
209 14 : move16();
210 93 : FOR( b = 0; b < hStereoDft->nbands; b++ )
211 : {
212 79 : IF( LT_16( hStereoCng->cm_fx[b], 0x7333 ) )
213 : {
214 79 : gamma = hStereoCng->cm_fx[b]; /* Q15 */
215 79 : move16();
216 79 : gamma = BASOP_Util_Divide1616_Scale( gamma, sub( 32767, gamma ), &q_div ); /* e(q_div) */
217 79 : q_sqrt2 = add( q_div, 16 );
218 79 : tmp32_1 = BASOP_Util_Add_Mant32Exp( gamma, add( q_div, 16 ), sub( 32767, mult_r( hStereoDft->g_state_fx[b], hStereoDft->g_state_fx[b] ) ), 16, &q_sqrt1 ); /* e(q_sqrt1) */
219 79 : tmp32_1 = Sqrt32( tmp32_1, &q_sqrt1 ); /* e(q_sqrt1) */
220 79 : tmp32_2 = Sqrt32( gamma, &q_sqrt2 ); /* e(q_sqrt2) */
221 79 : tmp32_1 = BASOP_Util_Add_Mant32Exp( tmp32_1, q_sqrt1, L_negate( tmp32_2 ), q_sqrt2, &q_sqrt1 ); /* e(q_sqrt1) */
222 79 : gamma = extract_h( L_shl( tmp32_1, q_sqrt1 ) ); /* Q15 */
223 : }
224 : ELSE
225 : {
226 0 : gamma = 0;
227 0 : move16();
228 : }
229 :
230 79 : LR_ratio = extract_h( tdm_ratio_tabl_fx[hStereoCng->last_tdm_idx] ); /* Q15 */
231 237 : c = BASOP_Util_Divide3232_Scale(
232 79 : L_add( L_mult( add( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ),
233 79 : add( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ) ),
234 : L_shr( L_mult( gamma, gamma ), 4 ) ),
235 79 : L_add( L_mult( sub( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ),
236 79 : sub( ONE_IN_Q13, shr( hStereoDft->g_state_fx[b], 2 ) ) ),
237 : L_shr( L_mult( gamma, gamma ), 4 ) ),
238 : &c_e );
239 79 : q_sqrt = c_e;
240 79 : move16();
241 79 : sqrt_res = Sqrt16( mult( c, hStereoCng->cm_fx[b] ), &q_sqrt );
242 79 : tmp32_1 = L_add( L_add( L_shl( 1, sub( Q15, c_e ) ), c ), L_shl( L_deposit_l( sqrt_res ), sub( add( q_sqrt, 1 ), c_e ) ) ); /* Q(15 - c_e) */ /* +1 to account for multiplication with 2 */
243 79 : move16();
244 : // scaleMS = (1 + c + 2 * sqrtf(c * hStereoCng->cm[b])) / (4 * (c * LR_ratio * LR_ratio + (1 - LR_ratio) * (1 - LR_ratio) * targetGain * targetGain + 2 * LR_ratio * (1 - LR_ratio) * targetGain * sqrtf(c * hStereoCng->cm[b])));
245 79 : sqrt_res = Sqrt16( mult( c, hStereoCng->cm_fx[b] ), &q_sqrt );
246 79 : tmp32_2 = L_deposit_l( mult( c, mult( LR_ratio, LR_ratio ) ) ); /* Q(15 - c_e) */
247 : /* (1 - LR_ratio) * (1 - LR_ratio) * targetGain * targetGain */
248 79 : tmp32_2 = L_add( tmp32_2, L_shl( mult( mult( sub( MAX_16, LR_ratio ), sub( MAX_16, LR_ratio ) ), mult( targetGain, targetGain ) ), sub( Q4, c_e ) ) ); /* Q(15 - c_e) */
249 : /* 2 * LR_ratio * (1 - LR_ratio) * targetGain * sqrtf(c * hStereoCng->cm[b]) */
250 79 : tmp32_2 = L_add( tmp32_2, L_shl( L_deposit_l( mult( mult( LR_ratio, sub( MAX_16, LR_ratio ) ), mult( targetGain, sqrt_res ) ) ), sub( add( q_sqrt, 3 ), c_e ) ) ); /* Q(15 - c_e) */ /* +1 to account for multiplication with 2 */
251 79 : tmp32_2 = L_shl( tmp32_2, 2 );
252 79 : scaleMS = BASOP_Util_Divide3232_Scale( tmp32_1, tmp32_2, &c_e );
253 79 : q_sqrt = c_e;
254 79 : move16();
255 79 : scaleMS = Sqrt16( scaleMS, &q_sqrt );
256 79 : scaleAvg_e = BASOP_Util_Add_MantExp( scaleAvg, scaleAvg_e, scaleMS, q_sqrt, &scaleAvg );
257 : }
258 14 : scaleAvg = BASOP_Util_Divide1616_Scale( scaleAvg, hStereoDft->nbands, &c_e );
259 14 : c_e = sub( add( c_e, scaleAvg_e ), 15 );
260 14 : hStereoDft->scale_fx = shl_sat( scaleAvg, c_e );
261 14 : move16();
262 : }
263 : }
264 :
265 10992 : IF( st->cng_type == LP_CNG )
266 : {
267 2526 : set32_fx( cngNoiseLevel_upd, 0, st->L_frame );
268 :
269 : /* Deemphasis */
270 2526 : dmpf[0] = MAX_16;
271 2526 : move16();
272 2526 : dmpf[1] = negate( st->preemph_fac );
273 2526 : move16();
274 2526 : Copy( st->Aq_cng, Atmp, M + 1 );
275 2526 : conv_fx_32( Atmp, dmpf, cngNoiseLevel_upd, M + 2 );
276 :
277 2526 : IF( EQ_16( st->L_frame, L_FRAME ) )
278 : {
279 766 : pTrigo = hStereoDft->dft_trigo_12k8_fx; /* Q15 */
280 766 : trigo_step = STEREO_DFT_TRIGO_SRATE_12k8_STEP * STEREO_DFT_TRIGO_DEC_STEP;
281 766 : move16();
282 : }
283 : ELSE
284 : {
285 1760 : pTrigo = hStereoDft->dft_trigo_16k_fx; /* Q15 */
286 1760 : trigo_step = STEREO_DFT_TRIGO_SRATE_16k_STEP * STEREO_DFT_TRIGO_DEC_STEP;
287 1760 : move16();
288 : }
289 :
290 192350 : FOR( i = 0; i < st->L_frame / 4; i++ )
291 : {
292 189824 : trigo_dec[i] = pTrigo[i * trigo_step]; /* Q15 */
293 189824 : move16();
294 189824 : trigo_dec[st->L_frame / 2 - i] = pTrigo[i * trigo_step]; /* Q15 */
295 189824 : move16();
296 : }
297 2526 : trigo_dec[st->L_frame / 4] = pTrigo[st->L_frame / 4 * trigo_step]; /* Q15 */
298 2526 : move16();
299 :
300 2526 : Word16 rshift_cng = sub( find_guarded_bits_fx( st->L_frame ), getScaleFactor32( cngNoiseLevel_upd, st->L_frame ) );
301 2526 : v_shr_32( cngNoiseLevel_upd, cngNoiseLevel_upd, st->L_frame, rshift_cng );
302 2526 : q_cngNoiseLevel_upd = sub( Q30, rshift_cng );
303 :
304 2526 : rfft_fx( cngNoiseLevel_upd, trigo_dec, st->L_frame, -1 );
305 :
306 2526 : Word16 shift = sub( getScaleFactor32( cngNoiseLevel_upd, st->L_frame ), 1 );
307 2526 : scale_sig32( cngNoiseLevel_upd, st->L_frame, shift );
308 2526 : q_cngNoiseLevel_upd = add( q_cngNoiseLevel_upd, shift );
309 2526 : set16_fx( e_norm_temp, q_cngNoiseLevel_upd, st->L_frame );
310 :
311 : /* Compute 1/|A| */
312 2526 : ptr0 = cngNoiseLevel_upd;
313 2526 : ptr1 = ptr0 + 2;
314 2526 : ptr2 = ptr1 + 1;
315 2526 : assert( st->lp_ener_fx > 0 );
316 :
317 : // lp_ener_fx will be in Q6 at this point.
318 : // So applying appropriate left shift on the denominator.
319 2526 : factor = L_shr( BASOP_Util_Divide3232_Scale_newton( st->lp_ener_fx, L_shl( st->L_frame, Q6 ), &q_div ), 1 ); /* fixed factor in the loop below */ /* q_div */
320 2526 : factor = Sqrt32( factor, &q_div );
321 2526 : q_div = add( q_div, 1 );
322 :
323 : Word16 q_tmp;
324 379648 : FOR( i = 0; i < st->L_frame / 2 - 1; i++ )
325 : {
326 377122 : ftmp = Madd_32_32( Mpy_32_32( *ptr1, *ptr1 ), *ptr2, *ptr2 ); /* q_cngNoiseLevel_upd */
327 377122 : assert( ftmp > 0 );
328 377122 : q_sqrt = sub( 62, shl( q_cngNoiseLevel_upd, 1 ) );
329 377122 : IF( ftmp == 0 )
330 : {
331 0 : ftmp = EPSILLON_FX;
332 0 : move32();
333 0 : q_sqrt = s_max( 0, q_sqrt );
334 : }
335 377122 : tmp = ISqrt32( ftmp, &q_sqrt );
336 377122 : e_norm_temp[i] = sub( 31, add( q_sqrt, q_div ) );
337 377122 : move16();
338 377122 : *ptr0++ = Mpy_32_32( factor, tmp ); /* 2 * q_div + q_sqrt - 31 */
339 377122 : move32();
340 377122 : ptr1 += 2;
341 377122 : ptr2 += 2;
342 : }
343 :
344 379648 : FOR( i = 0; i < st->L_frame / 2 - 1; i++ )
345 : {
346 377122 : q_cngNoiseLevel_upd = s_min( q_cngNoiseLevel_upd, add( e_norm_temp[i], norm_l( cngNoiseLevel_upd[i] ) ) );
347 : }
348 761822 : FOR( i = 0; i < st->L_frame; i++ )
349 : {
350 759296 : cngNoiseLevel_upd[i] = L_shl( cngNoiseLevel_upd[i], sub( q_cngNoiseLevel_upd, e_norm_temp[i] ) );
351 759296 : move32();
352 : }
353 :
354 2526 : IF( sub( s_min( output_frame, L_FRAME32k ), hFdCngCom->stopFFTbin ) > 0 )
355 : {
356 : /* Transform shb LP spectrum */
357 2172 : set32_fx( shb_shape, 0, L_FRAME16k );
358 2172 : Copy_Scale_sig_16_32_DEPREC( st->hTdCngDec->shb_lpcCNG_fx, shb_shape, LPC_SHB_ORDER + 1, Q15 ); // Q30
359 :
360 2172 : IF( NE_16( st->L_frame, L_FRAME16k ) )
361 : {
362 766 : pTrigo = hStereoDft->dft_trigo_16k_fx; /* Q15 */
363 766 : trigo_step = STEREO_DFT_TRIGO_SRATE_16k_STEP * STEREO_DFT_TRIGO_DEC_STEP;
364 766 : move16();
365 :
366 62046 : FOR( i = 0; i < L_FRAME16k / 4; i++ )
367 : {
368 61280 : trigo_dec[i] = pTrigo[i * trigo_step]; /* Q15 */
369 61280 : move16();
370 61280 : trigo_dec[L_FRAME16k / 2 - i] = pTrigo[i * trigo_step]; /* Q15 */
371 61280 : move16();
372 : }
373 766 : trigo_dec[L_FRAME16k / 4] = pTrigo[L_FRAME16k / 4 * trigo_step]; /* Q15 */
374 766 : move16();
375 : }
376 :
377 2172 : Word16 rshift_shb = sub( find_guarded_bits_fx( L_FRAME16k ), getScaleFactor32( shb_shape, L_FRAME16k ) );
378 2172 : v_shr_32( shb_shape, shb_shape, L_FRAME16k, rshift_shb );
379 2172 : q_shb_shape = sub( Q30, rshift_shb );
380 :
381 2172 : rfft_fx( shb_shape, trigo_dec, L_FRAME16k, -1 );
382 :
383 2172 : shift = sub( getScaleFactor32( shb_shape, L_FRAME16k ), 1 );
384 2172 : scale_sig32( shb_shape, L_FRAME16k, shift ); /* q_shb_shape + shift */
385 2172 : q_shb_shape = add( q_shb_shape, shift );
386 :
387 : /* Compute 1/|A| */
388 2172 : enr = Madd_32_32( Mpy_32_32( shb_shape[0], shb_shape[0] ), shb_shape[1], shb_shape[1] ); /* 62 - 2*q_shb_shape */
389 2172 : q_enr = sub( 62, shl( q_shb_shape, 1 ) );
390 2172 : ptr0 = shb_shape;
391 2172 : ptr1 = ptr0 + 2;
392 2172 : ptr2 = ptr1 + 1;
393 2172 : set16_fx( e_norm_temp, q_shb_shape, L_FRAME16k );
394 :
395 347520 : FOR( i = 0; i < L_FRAME16k / 2 - 1; i++ )
396 : {
397 345348 : ftmp = Madd_32_32( Mpy_32_32( *ptr1, *ptr1 ), *ptr2, *ptr2 ); /* 2*q_shape - 31 */
398 345348 : q_tmp = sub( shl( q_shb_shape, 1 ), 31 );
399 345348 : assert( ftmp > 0 );
400 345348 : q_div = 0;
401 345348 : move16();
402 345348 : ftmp = BASOP_Util_Divide3232_Scale_newton( L_shl( 1, q_tmp ), ftmp, &q_div ); /* q_div */
403 : /* in float:
404 : both a = "div"=(1/(x^2+y^2) and sqrt(a) is used and summed up in the same loop.
405 :
406 : in BASOP:
407 : sum up using inv_sqrt( *ptr1 * *ptr1 + *ptr2 * *ptr2 ), in this loop
408 : and then sum up enr = sum( *ptr0 * *ptr0 ), in a subsequent MAC loop */
409 345348 : enr = BASOP_Util_Add_Mant32Exp( enr, q_enr, ftmp, q_div, &q_enr ); /* q_enr */
410 345348 : tmp32_1 = Sqrt32( ftmp, &q_div ); /* q_div */
411 345348 : *ptr0++ = tmp32_1;
412 345348 : move32();
413 345348 : e_norm_temp[i] = sub( 31, q_div );
414 345348 : move16();
415 345348 : ptr1 += 2;
416 345348 : ptr2 += 2;
417 : }
418 2172 : q_shb_shape = MAX_16;
419 2172 : move16();
420 :
421 697212 : FOR( i = 0; i < L_FRAME16k; i++ )
422 : {
423 695040 : q_shb_shape = s_min( q_shb_shape, add( e_norm_temp[i], norm_l( shb_shape[i] ) ) );
424 : }
425 697212 : FOR( i = 0; i < L_FRAME16k; i++ )
426 : {
427 695040 : shb_shape[i] = L_shl( shb_shape[i], sub( q_shb_shape, e_norm_temp[i] ) ); /* q_shb_shape */
428 695040 : move32();
429 : }
430 : }
431 :
432 : /* Update CNG noise level from MS noise estimation */
433 2526 : Copy32( st->hFdCngDec->bandNoiseShape, cngNoiseLevel_hist, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ); /* exp(bandNoiseShape_exp)*/
434 2526 : ptr_cng = cngNoiseLevel_hist;
435 379648 : FOR( i = 0; i < ( st->last_L_frame - hFdCngCom->startBand ) / 2; i++ )
436 : {
437 377122 : tmp = L_shr( *( cngNoiseLevel_hist + shl( i, 1 ) ), 1 );
438 377122 : move32();
439 377122 : tmp = L_add( tmp, L_shr( *( cngNoiseLevel_hist + add( shl( i, 1 ), 1 ) ), 1 ) ); /* exp(bandNoiseShape_exp)*/
440 377122 : *ptr_cng++ = tmp;
441 377122 : move32();
442 : }
443 :
444 2526 : test();
445 2526 : test();
446 2526 : test();
447 2526 : IF( EQ_16( last_element_mode, IVAS_CPE_TD ) && ( chan == 0 ) && ( hStereoCng->xfade_frame_counter == 0 ) && GE_16( hFdCngCom->msFrCnt_init_counter, hFdCngCom->msFrCnt_init_thresh ) )
448 : {
449 7 : ptr_cng = cngNoiseLevel_hist + hFdCngCom->startBand;
450 7 : ptr_tmp = cngNoiseLevel_upd + hFdCngCom->startBand;
451 : Word32 temppp;
452 7 : Word16 shift_g = shr( find_guarded_bits_fx( shr( sub( st->last_L_frame, hFdCngCom->startBand ), 1 ) ), 1 );
453 1120 : FOR( i = 0; i < ( st->last_L_frame - hFdCngCom->startBand ) / 2; i++ )
454 : {
455 1113 : E0 = W_add( E0, *ptr_cng++ ); /* exp(bandNoiseShape_exp - E0_e) */
456 1113 : temppp = L_shr( ( *ptr_tmp ), shift_g );
457 1113 : E1 = W_mac_32_32( E1, temppp, temppp ); /* 2*(q_cngNoiseLevel_upd - shift_g) + 1*/
458 1113 : ptr_tmp++;
459 : }
460 7 : E0_e = W_norm( E0 );
461 7 : E0 = W_shl( E0, E0_e );
462 7 : E0_e = add( sub( st->hFdCngDec->bandNoiseShape_exp, E0_e ), 32 );
463 7 : E1_e = W_norm( E1 );
464 7 : E1 = W_shl( E1, E1_e );
465 7 : E1_e = sub( 63, add( E1_e, add( shl( sub( q_cngNoiseLevel_upd, shift_g ), 1 ), 1 ) ) );
466 :
467 7 : IF( BASOP_Util_Cmp_Mant32Exp( W_extract_h( E0 ), E0_e, W_extract_h( E1 ), E1_e ) < 0 )
468 : {
469 7 : tmp_16 = BASOP_Util_Divide3232_Scale( W_extract_h( E0 ), W_extract_h( E1 ), &q_div ); /* q_div + E0_e - E1_e */
470 7 : q_div = add( q_div, sub( E0_e, E1_e ) );
471 7 : tmp_16 = Sqrt16( tmp_16, &q_div );
472 7 : tmp_16 = shl( tmp_16, q_div );
473 7 : hStereoCng->xfade_length = sub( MAX_XFADE_FX, extract_l( L_shr( imult3216( MAX_XFADE_FX, tmp_16 ), Q15 ) ) ); /* Q0 */
474 7 : move16();
475 : }
476 : ELSE
477 : {
478 0 : tmp_16 = BASOP_Util_Divide3232_Scale( W_extract_h( E1 ), W_extract_h( E0 ), &q_div ); /* q_div + E0_e - E1_e */
479 0 : q_div = add( q_div, sub( E1_e, E0_e ) );
480 0 : tmp_16 = Sqrt16( tmp_16, &q_div );
481 0 : tmp_16 = shl( tmp_16, q_div );
482 0 : hStereoCng->xfade_length = sub( MAX_XFADE_FX, extract_l( L_shr( imult3216( MAX_XFADE_FX, tmp_16 ), Q15 ) ) ); /* Q0 */
483 0 : move16();
484 : }
485 : }
486 :
487 2526 : IF( LT_16( hStereoCng->xfade_frame_counter, hStereoCng->xfade_length ) )
488 : {
489 74 : ptr_cng = cngNoiseLevel_hist + hFdCngCom->startBand;
490 74 : ptr_tmp = cngNoiseLevel_upd + hFdCngCom->startBand;
491 11840 : FOR( i = 0; i < ( st->last_L_frame - hFdCngCom->startBand ) / 2; i++ )
492 : {
493 11766 : q_sqrt = st->hFdCngDec->bandNoiseShape_exp;
494 11766 : move16();
495 11766 : tmp_16 = BASOP_Util_Divide1616_Scale( hStereoCng->xfade_frame_counter, hStereoCng->xfade_length, &q_div ); /* Q0 */
496 11766 : tmp_16 = shl( tmp_16, q_div );
497 11766 : tmp = Sqrt32( *ptr_cng++, &q_sqrt );
498 11766 : tmp = L_shl( tmp, sub( add( q_cngNoiseLevel_upd, q_sqrt ), 31 ) );
499 11766 : *ptr_tmp = L_add( Mpy_32_16_1( *ptr_tmp, tmp_16 ), Mpy_32_16_1( Mpy_32_16_1( tmp, sub( MAX_16, tmp_16 ) ), hStereoDft->scale_fx ) ); /* q_cngNoiseLevel_upd + q_div */
500 11766 : move32();
501 11766 : ptr_tmp++;
502 : }
503 : }
504 :
505 7578 : FOR( k = 0; k < STEREO_DFT_NBDIV; k++ )
506 : {
507 : /* low band */
508 5052 : ptr_level = cngNoiseLevel_upd; // Q(q_cngNoiseLevel_upd)
509 5052 : ptr_r = DFT[chan] + add( hFdCngCom->startBand, i_mult( k, STEREO_DFT32MS_N_MAX ) ); // Q(q_dft)
510 5052 : ptr_i = ptr_r + 1;
511 5052 : scale = shr( output_frame, 1 );
512 :
513 759296 : FOR( i = 0; i < ( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2; i++ )
514 : {
515 : /* Real part in FFT bins */
516 754244 : rand_gauss_fx( ptr_r, &st->hTdCngDec->cng_seed, q_dft );
517 754244 : tmp32_1 = Mpy_32_16_1( *ptr_level, scale ); // Q(q_cngNoiseLevel_upd - 15)
518 754244 : q_shift = norm_l( tmp32_1 );
519 754244 : if ( GT_16( q_shift, sub( 46, q_cngNoiseLevel_upd ) ) )
520 : {
521 0 : q_shift = sub( 46, q_cngNoiseLevel_upd );
522 : }
523 754244 : tmp32_1 = L_shl( tmp32_1, q_shift );
524 754244 : q_shift = sub( sub( 46, q_cngNoiseLevel_upd ), q_shift );
525 :
526 754244 : ( *ptr_r ) = L_shl( Mpy_32_32( ( *ptr_r ), tmp32_1 ), q_shift ); /* q_dft */
527 754244 : move32();
528 754244 : ptr_r += 2;
529 :
530 : /* Imaginary part in FFT bins */
531 754244 : rand_gauss_fx( ptr_i, &st->hTdCngDec->cng_seed, q_dft );
532 754244 : ( *ptr_i ) = L_shl( Mpy_32_32( ( *ptr_i ), tmp32_1 ), q_shift ); /* q_dft */
533 754244 : move32();
534 754244 : ptr_i += 2;
535 754244 : ptr_level++;
536 : }
537 :
538 5052 : IF( sub( s_min( output_frame, L_FRAME32k ), hFdCngCom->stopFFTbin ) > 0 )
539 : {
540 : Word32 scale_32;
541 : Word16 q_res;
542 : /* high band generation, flipped spectrum */
543 4344 : assert( enr != 0 );
544 : // 10 ^ (0.1 * st->hTdCngDec->shb_cng_gain)
545 : // Above expression equivalent to 2 ^ (3.321928094 * 0.1 * st->hTdCngDec->shb_cng_gain)
546 : // 3.321928094 * 0.1 = 0.3321928094
547 : // st->hTdCngDec->shb_cng_gain_fx_32 Q is 11
548 4344 : scale_32 = BASOP_util_Pow2( Mpy_32_16_1( st->hTdCngDec->shb_cng_gain_fx_32, (Word16) 0x2A85 ), Q31 - Q11, &q_res );
549 : // Q of scale_32 is Q31 - q_res, Q of enr is
550 : // scale_32 = L_shl(scale_32, sub( q_enr, sub(Q31, q_res)));
551 4344 : q_div = 0;
552 4344 : move16();
553 4344 : scale = BASOP_Util_Divide3232_Scale( scale_32, enr, &q_div );
554 : // q_res = add(q_div, sub( q_enr, sub(Q31, q_res))); move16();
555 4344 : q_res = add( sub( q_res, q_enr ), q_div );
556 : // q_div = sub(Q15, q_res); move16();
557 4344 : q_div = q_res;
558 4344 : move16();
559 4344 : inv_scale = ISqrt16( scale, &q_res );
560 4344 : scale = Sqrt16( scale, &q_div );
561 4344 : ptr_shb = shb_shape + ( L_FRAME16k / 2 - 1 );
562 : /* Averaging for Nyquist frequency */
563 : Word16 q1, q2;
564 4344 : tmp32_1 = Mpy_32_16_1( cngNoiseLevel_upd[( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 - 1], inv_scale ); /* q_cngNoiseLevel_upd + 1 - q_res */
565 4344 : tmp32_2 = *( ptr_shb - 1 ); /* q_shb_shape */
566 4344 : move32();
567 4344 : q1 = sub( add( q_cngNoiseLevel_upd, 1 ), q_res );
568 4344 : q2 = q_shb_shape;
569 4344 : move16();
570 4344 : *ptr_shb = BASOP_Util_Add_Mant32Exp( tmp32_1, sub( Q31, q1 ), tmp32_2, sub( Q31, q2 ), &q_tmp );
571 4344 : move32();
572 4344 : q_tmp = sub( q_tmp, 1 );
573 4344 : IF( LT_16( sub( Q31, q_tmp ), q_shb_shape ) )
574 : {
575 162 : scale_sig32( shb_shape, L_FRAME16k, sub( sub( Q31, q_tmp ), q_shb_shape ) ); /* Q31 - q_tmp */
576 162 : q_shb_shape = sub( Q31, q_tmp );
577 : }
578 :
579 4344 : *ptr_shb = L_shl( *ptr_shb, sub( q_shb_shape, sub( Q31, q_tmp ) ) ); /* Q31 - q_tmp */
580 4344 : move32();
581 :
582 : // *ptr_shb = 0.5f * ( cngNoiseLevel_upd[( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2 - 1] / scale + *( ptr_shb - 1 ) );
583 :
584 4344 : ptr_r = DFT[chan] + add( hFdCngCom->stopFFTbin, i_mult( k, STEREO_DFT32MS_N_MAX ) ); /* q_dft */
585 4344 : ptr_i = ptr_r + 1;
586 :
587 4344 : Word16 len = shr( ( sub( s_min( output_frame, i_mult( hFdCngCom->regularStopBand, 16 ) ), hFdCngCom->stopFFTbin ) ), 1 );
588 523128 : FOR( i = 0; i < len; i++ )
589 : {
590 : /* Real part in FFT bins */
591 518784 : rand_gauss_fx( ptr_r, &st->hTdCngDec->cng_seed, q_dft );
592 518784 : tmp32_1 = *ptr_shb;
593 518784 : move32();
594 518784 : q_shift = norm_l( tmp32_1 );
595 518784 : IF( GT_16( q_shift, sub( 31, q_shb_shape ) ) )
596 : {
597 27508 : q_shift = sub( 31, q_shb_shape );
598 : }
599 518784 : tmp32_1 = L_shl( tmp32_1, q_shift );
600 518784 : q_shift = sub( sub( 31, q_shb_shape ), q_shift );
601 :
602 518784 : ( *ptr_r ) = L_shl( Mpy_32_32( ( *ptr_r ), tmp32_1 ), q_shift );
603 518784 : move32();
604 518784 : ptr_r += 2;
605 : /* Imaginary part in FFT bins */
606 518784 : rand_gauss_fx( ptr_i, &st->hTdCngDec->cng_seed, q_dft );
607 518784 : ( *ptr_i ) = L_shl( Mpy_32_32( ( *ptr_i ), tmp32_1 ), q_shift ); /* q_dft + q_shift */
608 518784 : move32();
609 518784 : ptr_i += 2;
610 518784 : ptr_shb--;
611 : }
612 :
613 : /* rescale */
614 4344 : tmp32_1 = L_mult0( scale, shr( output_frame, 1 ) );
615 4344 : q_shift = norm_l( tmp32_1 );
616 4344 : IF( GT_16( q_shift, add( Q16, q_div ) ) )
617 : {
618 236 : q_shift = add( Q16, q_div );
619 : }
620 4344 : tmp32_1 = L_shl( tmp32_1, q_shift );
621 4344 : q_shift = sub( add( Q16, q_div ), q_shift );
622 :
623 4344 : ptr_r = DFT[chan] + add( hFdCngCom->stopFFTbin, i_mult( k, STEREO_DFT32MS_N_MAX ) ); /* q_dft */
624 4344 : ptr_i = ptr_r + 1;
625 4344 : tmp = shr( sub( s_min( output_frame, i_mult( hFdCngCom->regularStopBand, 16 ) ), hFdCngCom->stopFFTbin ), 1 );
626 523128 : FOR( i = 0; i < tmp; i++ )
627 : {
628 518784 : ( *ptr_r ) = L_shl( Mpy_32_32( ( *ptr_r ), tmp32_1 ), q_shift ); /* q_dft + q_shift */
629 518784 : move32();
630 518784 : ( *ptr_i ) = L_shl( Mpy_32_32( ( *ptr_i ), tmp32_1 ), q_shift ); /* q_dft + q_shift */
631 518784 : move32();
632 518784 : ptr_r += 2;
633 518784 : ptr_i += 2;
634 : }
635 : }
636 : }
637 :
638 : /* Expand cngNoiseLevel_flt from 0-159 to 0-318, compute noise level */
639 2526 : lp_noise = 0;
640 2526 : move32();
641 2526 : lp_noise_e = 0;
642 2526 : move16();
643 2526 : ptr_level = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, add( hFdCngCom->startBand, 1 ) ); /* q_cngNoiseLevel */
644 2526 : ptr_tmp = cngNoiseLevel_upd + sub( shr( sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), 1 ), 1 ); /* q_cngNoiseLevel_upd */
645 :
646 2526 : q_tmp = s_max( hFdCngCom->cngNoiseLevelExp, shl( sub( Q31, q_cngNoiseLevel_upd ), 1 ) );
647 2526 : scale_sig32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, sub( hFdCngCom->cngNoiseLevelExp, q_tmp ) ); /* q_tmp */
648 2526 : hFdCngCom->cngNoiseLevelExp = q_tmp;
649 2526 : move16();
650 :
651 379648 : FOR( i = 0; i < ( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2; i++ )
652 : {
653 377122 : *ptr_level-- = L_shl( Mpy_32_32( *ptr_tmp, *ptr_tmp ), sub( shl( sub( Q31, q_cngNoiseLevel_upd ), 1 ), hFdCngCom->cngNoiseLevelExp ) ); /* q_cngNoiseLevel */
654 377122 : move32();
655 377122 : ptr_tmp--;
656 377122 : *ptr_level = *( ptr_level + 1 );
657 377122 : move32();
658 377122 : lp_noise = BASOP_Util_Add_Mant32Exp( lp_noise, lp_noise_e, *ptr_level--, add( hFdCngCom->cngNoiseLevelExp, 1 ), &lp_noise_e );
659 : }
660 : }
661 : ELSE
662 : {
663 : /* FD-CNG */
664 8466 : IF( !LT_16( hFdCngCom->msFrCnt_init_counter, hFdCngCom->msFrCnt_init_thresh ) )
665 : {
666 8466 : test();
667 8466 : test();
668 8466 : IF( LE_16( hStereoCng->xfade_frame_counter, (Word16) MAX_K ) && EQ_16( hStereoCng->last_act_element_mode, IVAS_CPE_TD ) && ( chan == 0 ) )
669 : {
670 : /* Fade MS -> SID/MS */
671 59 : j = 0;
672 59 : move16();
673 1180 : FOR( k = 0; k < ( hFdCngCom->nFFTpart - 2 ); k++ )
674 : {
675 1121 : factor = BASOP_Util_Divide3232_Scale_newton( L_add( hFdCngCom->sidNoiseEstLp[k], DELTA_FX ), L_add( st->hFdCngDec->partNoiseShape[k], DELTA_FX ), &q_div ); /* q_div */
676 1121 : q_div = add( q_div, sub( hFdCngCom->sidNoiseEstExp, st->hFdCngDec->partNoiseShape_exp ) );
677 1121 : IF( q_div < 0 )
678 : {
679 0 : factor = L_shl( factor, q_div ); // Q31
680 0 : q_div = 0;
681 0 : move16();
682 : }
683 1121 : factor = L_min( L_add( L_shl( hStereoDft->scale_fx, sub( 16, q_div ) ), W_extract_l( W_mult0_32_32( Mpy_32_16_1( L_sub( factor, L_shl( hStereoDft->scale_fx, sub( 16, q_div ) ) ), ONE_BY_MAX_K ), hStereoCng->xfade_frame_counter ) ) ), factor ); /* q_div */
684 13570 : FOR( ; j <= hFdCngCom->part[k]; j++ )
685 : {
686 : /* NOTE: saturation is added here as part of issue 1218 fix. After rescaling the fdcng noise estimation buffers, due to slight precision loss, values may slightly overflow */
687 12449 : hFdCngCom->cngNoiseLevel[j] = L_shl_sat( Mpy_32_32( st->hFdCngDec->bandNoiseShape[j], factor ), q_div ); /* exp(st->hFdCngDec->bandNoiseShape_exp) */
688 12449 : move32();
689 : }
690 : }
691 59 : hFdCngCom->cngNoiseLevelExp = st->hFdCngDec->bandNoiseShape_exp;
692 59 : move16();
693 : }
694 : }
695 8466 : scale = shr( output_frame, 1 );
696 8466 : numSlots = shr( hFdCngCom->numSlots, 1 );
697 25398 : FOR( k = 0; k < STEREO_DFT_NBDIV; k++ )
698 : {
699 16932 : ptr_level = hFdCngCom->cngNoiseLevel;
700 16932 : ptr_r = DFT[chan] + add( hFdCngCom->startBand, i_mult( k, STEREO_DFT32MS_N_MAX ) ); /* qDFT */
701 16932 : ptr_i = ptr_r + 1;
702 16932 : q_cngNoiseLevel = sub( Q31, hFdCngCom->cngNoiseLevelExp );
703 2436736 : FOR( i = 0; i < ( hFdCngCom->stopFFTbin - hFdCngCom->startBand ) / 2; i++ )
704 : {
705 : /* Real part in FFT bins */
706 2419804 : tmp = L_shr( *ptr_level++, 1 );
707 2419804 : tmp = L_add( tmp, L_shr( *ptr_level++, 1 ) );
708 2419804 : rand_gauss_fx( ptr_r, &st->hTdCngDec->cng_seed, q_dft );
709 2419804 : q_sqrt = sub( Q31, q_cngNoiseLevel );
710 2419804 : tmp = Sqrt32( tmp, &q_sqrt );
711 2419804 : *( ptr_r ) = imult3216( Mpy_32_32( *( ptr_r ), tmp ), scale ); /* qDFT */
712 2419804 : move32();
713 2419804 : ( *ptr_r ) = L_shl( ( *ptr_r ), q_sqrt ); /* qDFT */
714 2419804 : move32();
715 2419804 : ptr_r += 2;
716 : /* Imaginary part in FFT bins */
717 2419804 : rand_gauss_fx( ptr_i, &st->hTdCngDec->cng_seed, q_dft );
718 2419804 : ( *ptr_i ) = L_shl( imult3216( Mpy_32_32( ( *ptr_i ), tmp ), scale ), q_sqrt ); /* qDFT */
719 2419804 : move32();
720 2419804 : ptr_i += 2;
721 : }
722 16932 : ptr_level = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
723 16932 : ptr_r = DFT[chan] + add( hFdCngCom->stopFFTbin, i_mult( k, STEREO_DFT32MS_N_MAX ) ); /* qDFT */
724 16932 : ptr_i = ptr_r + 1;
725 249380 : FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
726 : {
727 2092032 : FOR( i = 0; i < numSlots; i++ )
728 : {
729 : /* Real part in FFT bins */
730 1859584 : rand_gauss_fx( ptr_r, &st->hTdCngDec->cng_seed, q_dft );
731 1859584 : q_sqrt = sub( Q31, q_cngNoiseLevel );
732 1859584 : tmp = Sqrt32( *ptr_level, &q_sqrt );
733 1859584 : tmp = Mpy_32_16_1( tmp, scale ); // 15 + q_sqrt
734 1859584 : ( *ptr_r ) = Mpy_32_32( *ptr_r, tmp ); // q_dft + 15 + q_sqrt - 31
735 1859584 : ( *ptr_r ) = L_shl_sat( ( *ptr_r ), add( 15, q_sqrt ) );
736 1859584 : move32();
737 1859584 : ptr_r += 2;
738 : /* Imaginary part in FFT bins */
739 1859584 : rand_gauss_fx( ptr_i, &st->hTdCngDec->cng_seed, q_dft );
740 1859584 : ( *ptr_i ) = Mpy_32_32( *ptr_i, tmp ); // q_dft + 15 + q_sqrt - 31
741 1859584 : ( *ptr_i ) = L_shl_sat( ( *ptr_i ), add( 15, q_sqrt ) );
742 1859584 : move32();
743 1859584 : ptr_i += 2;
744 : }
745 232448 : ptr_level++;
746 : }
747 : }
748 :
749 : /* Compute noise level */
750 8466 : lp_noise = 0;
751 8466 : move32();
752 8466 : lp_noise_e = 0;
753 8466 : move16();
754 8466 : ptr_level = hFdCngCom->cngNoiseLevel;
755 2428270 : FOR( i = 0; i < hFdCngCom->stopFFTbin - hFdCngCom->startBand; i++ )
756 : {
757 : // lp_noise = L_add( lp_noise, *ptr_level++ );
758 2419804 : lp_noise = BASOP_Util_Add_Mant32Exp( lp_noise, lp_noise_e, *ptr_level++, hFdCngCom->cngNoiseLevelExp, &lp_noise_e );
759 : }
760 : }
761 :
762 10992 : test();
763 10992 : IF( EQ_16( hStereoCng->last_act_element_mode, IVAS_CPE_TD ) && ( chan > 0 ) )
764 96 : {
765 96 : Word32 log_lp_noise = L_add( L_shl( lp_noise_e, Q25 ), BASOP_Util_Log2( L_add( lp_noise, DELTA_FX ) ) ); /* Q25 */
766 : // log10(x) is computed as log2(x) * log10(2)
767 : // log_lp_noise at this stage is in Q25. where as the structure value is in Q23
768 : // Hence the 16-bit constant log10(2) will be stored in Q13
769 96 : log_lp_noise = Mpy_32_16_1( log_lp_noise, 2466 /* log10(2) in Q13 */ ); /* Q23 */
770 96 : st1->lp_noise = L_add( Mpy_32_16_1( st1->lp_noise, 29491 /* 0.9f in Q15 */ ), log_lp_noise ); /* Q23 */
771 96 : move32();
772 : }
773 10896 : ELSE IF( ( chan == 0 ) )
774 : {
775 5496 : Word16 q_lp_noise = 0; // st->hFdCngDec->q_lp_noise; // to be populated appropriately.
776 5496 : move16();
777 5496 : Word32 log_lp_noise = L_add( L_shl( lp_noise_e, Q25 ), BASOP_Util_Log2( L_add( lp_noise, DELTA_FX ) ) ); /* Q25 */
778 : // log10(x) is computed as log2(x) * log10(2)
779 : // log_lp_noise at this stage is in Q25. where as the structure value is in Q23
780 : // Hence the 16-bit constant log10(2) will be stored in Q13
781 5496 : log_lp_noise = Mpy_32_16_1( log_lp_noise, 2466 /* log10(2) in Q13 */ ); /* Q23 */
782 5496 : st->hFdCngDec->lp_noise = L_add( Mpy_32_16_1( st->hFdCngDec->lp_noise, 29491 /* 0.9f in Q15 */ ), log_lp_noise ); /* Q23 */
783 5496 : move32();
784 5496 : st->lp_noise = st->hFdCngDec->lp_noise; /* Q23 */
785 5496 : move32();
786 5496 : st->hFdCngDec->hFdCngCom->flag_noisy_speech = extract_l( LT_32( L_shr( L_sub( st->hFdCngDec->lp_speech, st->hFdCngDec->lp_noise ), q_lp_noise ), 28 ) ); /* Q0 */
787 5496 : move16();
788 5496 : st->hFdCngDec->hFdCngCom->likelihood_noisy_speech = add( mult_r( 32440 /* 0.99 in Q15 */, st->hFdCngDec->hFdCngCom->likelihood_noisy_speech ),
789 5496 : mult_r( 328 /* 0.01 in Q15 */, st->hFdCngDec->hFdCngCom->flag_noisy_speech ) ); /* Q15 */
790 5496 : move16();
791 : }
792 :
793 10992 : test();
794 10992 : IF( ( chan == 0 ) && LE_32( st->core_brate, SID_2k40 ) )
795 : {
796 : /* update smoothed periodogram used by stereo CNA in SID and NO_DATA frames from cngNoiseLevel_flt */
797 5496 : q_shift_1 = L_norm_arr( st->hFdCngDec->smoothed_psd_fx, L_FRAME16k );
798 5496 : q_shift_2 = L_norm_arr( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN );
799 :
800 5496 : min_q = sub( s_min( add( q_shift_1, sub( Q31, st->hFdCngDec->smoothed_psd_exp ) ), add( q_shift_2, sub( Q31, hFdCngCom->cngNoiseLevelExp ) ) ), 1 /* Guard bit */ );
801 :
802 5496 : scale_sig32( st->hFdCngDec->smoothed_psd_fx, L_FRAME16k, sub( min_q, sub( Q31, st->hFdCngDec->smoothed_psd_exp ) ) ); /* Q31 - st->hFdCngDec->smoothed_psd_exp */
803 5496 : st->hFdCngDec->smoothed_psd_exp = sub( Q31, min_q );
804 5496 : move16();
805 5496 : scale_sig32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, sub( min_q, sub( Q31, hFdCngCom->cngNoiseLevelExp ) ) ); /* Q31 - hFdCngCom->cngNoiseLevelExp */
806 5496 : hFdCngCom->cngNoiseLevelExp = st->hFdCngDec->smoothed_psd_exp;
807 5496 : move16();
808 :
809 1592520 : FOR( i = hFdCngCom->startBand; i < hFdCngCom->stopFFTbin; i++ )
810 : {
811 1587024 : ftmp = hFdCngCom->cngNoiseLevel[i - hFdCngCom->startBand];
812 1587024 : move32();
813 1587024 : IF( !st->hFdCngDec->first_cna_noise_updated )
814 : {
815 : /* very first update */
816 3242 : alpha = 0;
817 3242 : move16();
818 : }
819 : ELSE
820 : {
821 1583782 : alpha = (Word16) ( 0x799A );
822 1583782 : move16();
823 1583782 : test();
824 1583782 : IF( ( st->hFdCngDec->smoothed_psd_fx[i] > 0 ) && GT_32( Mpy_32_16_1( ftmp, (Word16) 0x3333 ), st->hFdCngDec->smoothed_psd_fx[i] ) )
825 : {
826 : /* prevent abrupt upward update steps */
827 36966 : ftmp = L_add( L_shl( st->hFdCngDec->smoothed_psd_fx[i], 1 ), L_shr( st->hFdCngDec->smoothed_psd_fx[i], 1 ) ); /* st->hFdCngDec->smoothed_psd_exp */
828 36966 : move16();
829 : }
830 1546816 : ELSE IF( LT_32( ftmp, st->hFdCngDec->smoothed_psd_fx[i] ) )
831 : {
832 : /* faster downward updates */
833 363681 : alpha = (Word16) ( 0x599A );
834 363681 : move16();
835 : }
836 : }
837 :
838 : /* smoothing */
839 1587024 : st->hFdCngDec->smoothed_psd_fx[i] = L_add( Mpy_32_16_1( st->hFdCngDec->smoothed_psd_fx[i], alpha ), Mpy_32_16_1( ftmp, sub( MAX_16, alpha ) ) ); /* st->hFdCngDec->smoothed_psd_exp */
840 1587024 : move32();
841 : }
842 :
843 : /* update msNoiseEst in SID and NO_DATA frames */
844 5496 : bandcombinepow( &st->hFdCngDec->smoothed_psd_fx[hFdCngCom->startBand], st->hFdCngDec->smoothed_psd_exp, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), st->hFdCngDec->part_shaping, st->hFdCngDec->nFFTpart_shaping, st->hFdCngDec->psize_inv_shaping, st->hFdCngDec->msNoiseEst, &st->hFdCngDec->msNoiseEst_exp );
845 :
846 : Word32 max_l;
847 5496 : maximum_32_fx( st->hFdCngDec->msNoiseEst, NPART_SHAPING, &max_l );
848 5496 : IF( max_l )
849 : {
850 5496 : q_shift = sub( norm_l( max_l ), 2 );
851 5496 : scale_sig32( st->hFdCngDec->msNoiseEst, NPART_SHAPING, q_shift ); /* st->hFdCngDec->msNoiseEst_exp - q_shift */
852 5496 : st->hFdCngDec->msNoiseEst_exp = sub( st->hFdCngDec->msNoiseEst_exp, q_shift );
853 5496 : move16();
854 : }
855 5496 : st->hFdCngDec->first_cna_noise_updated = 1;
856 5496 : move16();
857 5496 : Copy32( st->hFdCngDec->msNoiseEst, st->hFdCngDec->msPeriodog_ST_fx, st->hFdCngDec->nFFTpart_shaping ); /* st->hFdCngDec->msNoiseEst_exp - q_shift */
858 5496 : st->hFdCngDec->msPeriodog_ST_exp = st->hFdCngDec->msNoiseEst_exp;
859 5496 : st->hFdCngDec->ms_last_inactive_bwidth = st->bwidth; /* Q0 */
860 5496 : move16();
861 : }
862 :
863 10992 : pop_wmops();
864 10992 : return;
865 : }
866 :
867 : /*-------------------------------------------------------------------
868 : * stereo_dtf_cng()
869 : *
870 : * DFT stereo CNG
871 : *-------------------------------------------------------------------*/
872 42543 : void stereo_dtf_cng_fx(
873 : CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
874 : const Word32 ivas_total_brate, /* i : IVAS total bitrate Q0*/
875 : Word32 DFT[CPE_CHANNELS][STEREO_DFT_BUF_MAX], /* i/o: DFT buffers q_dft*/
876 : const Word16 output_frame, /* i : output frame size Q0*/
877 : Word16 q_dft /* i : Q factor of the DFT data */
878 : )
879 : {
880 : Decoder_State **sts;
881 : Word16 n;
882 :
883 42543 : sts = hCPE->hCoreCoder;
884 :
885 42543 : IF( hCPE->hStereoCng != NULL )
886 : {
887 42543 : IF( LT_16( hCPE->hStereoCng->nr_dft_frames, CM_INIT ) )
888 : {
889 6102 : hCPE->hStereoCng->nr_dft_frames = add( hCPE->hStereoCng->nr_dft_frames, 1 ); /* Q0 */
890 6102 : move16();
891 : }
892 :
893 42543 : IF( LE_32( ivas_total_brate, IVAS_SID_5k2 ) )
894 : {
895 5496 : test();
896 5496 : IF( LT_16( hCPE->hStereoCng->nr_sid_frames, SID_INIT ) && EQ_32( ivas_total_brate, IVAS_SID_5k2 ) )
897 : {
898 90 : hCPE->hStereoCng->nr_sid_frames = add( hCPE->hStereoCng->nr_sid_frames, 1 ); /* Q0 */
899 90 : move16();
900 : }
901 :
902 16488 : FOR( n = 0; n < CPE_CHANNELS; n++ )
903 : {
904 10992 : stereo_dft_generate_comfort_noise_fx( hCPE->hStereoDft, hCPE->hStereoCng, hCPE->last_element_mode, sts[0], DFT, sts[1], extract_h( hCPE->hStereoTCA->targetGain_fx ), n, output_frame, q_dft );
905 : }
906 : }
907 : }
908 :
909 42543 : return;
910 : }
911 :
912 :
913 : /*-------------------------------------------------------------------
914 : * stereo_cng_dec_update()
915 : *
916 : * Update counters used for TD->DFT-CNG cross fade and stereo SID parameters
917 : *-------------------------------------------------------------------*/
918 :
919 63378 : void stereo_cng_dec_update(
920 : CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
921 : const Word32 ivas_total_brate /* i : IVAS total bitrate Q0*/
922 : )
923 : {
924 63378 : IF( GT_32( hCPE->hCoreCoder[0]->core_brate, SID_2k40 ) )
925 : {
926 52984 : hCPE->hStereoCng->last_act_element_mode = hCPE->element_mode;
927 52984 : move16();
928 52984 : IF( GT_16( hCPE->hStereoCng->active_frame_counter, SKIP_XFADE_FRAMES ) )
929 : {
930 50019 : hCPE->hStereoCng->xfade_frame_counter = 0;
931 50019 : move16();
932 50019 : hCPE->hStereoCng->xfade_length = 0;
933 50019 : move16();
934 : }
935 52984 : IF( LT_16( hCPE->hStereoCng->active_frame_counter, MAX_FRAME_COUNTER ) )
936 : {
937 34397 : hCPE->hStereoCng->active_frame_counter = add( hCPE->hStereoCng->active_frame_counter, 1 ); /* Q0 */
938 34397 : move16();
939 : }
940 : }
941 : ELSE
942 : {
943 10394 : hCPE->hStereoCng->active_frame_counter = 0;
944 10394 : move16();
945 10394 : IF( LT_16( hCPE->hStereoCng->xfade_frame_counter, MAX_FRAME_COUNTER ) )
946 : {
947 10394 : hCPE->hStereoCng->xfade_frame_counter = add( hCPE->hStereoCng->xfade_frame_counter, 1 ); /* Q0 */
948 10394 : move16();
949 : }
950 : }
951 :
952 63378 : IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) )
953 : {
954 59583 : test();
955 59583 : IF( EQ_32( ivas_total_brate, IVAS_SID_5k2 ) || ( ivas_total_brate == FRAME_NO_DATA ) )
956 : {
957 10394 : hCPE->hStereoCng->prev_sid_nodata = 1;
958 10394 : move16();
959 : }
960 : ELSE
961 : {
962 49189 : hCPE->hStereoCng->prev_sid_nodata = 0;
963 49189 : move16();
964 : }
965 : }
966 :
967 63378 : hCPE->hCoreCoder[0]->hFdCngDec->hFdCngCom->active_frame_counter = hCPE->hStereoCng->active_frame_counter; /* Q0 */
968 63378 : move16();
969 :
970 63378 : return;
971 : }
972 :
973 :
974 : /*-------------------------------------------------------------------*
975 : * Function stereo_cng_compute_PScorr()
976 : *
977 : * CNA for TD stereo, compute PS correlation
978 : *-------------------------------------------------------------------*/
979 3795 : void stereo_cng_compute_PScorr_fx(
980 : Word32 output_fx0[], /* i : Output signal Qx = 1 temp*/
981 : Word32 output_fx1[], /* i : Output signal Qx*/
982 : Word16 *output_Q,
983 : Word32 *c_PS_LT_fx,
984 : Word16 Q_c_PS_LT_fx,
985 : const Word16 L_frame_0, /* i : L_frame channel 0 Q0*/
986 : const Word16 L_frame_1 /* i : L_frame channel 1 Q0*/
987 : )
988 : {
989 : Word16 i;
990 3795 : Word32 enrP_fx = 0, enrS_fx = 0, dotPS_fx = 0, c_PS_fx;
991 3795 : move32();
992 3795 : move32();
993 3795 : move32();
994 : Word32 outputResamp_fx[L_FRAME16k];
995 : Word32 *outputPptr_fx, *outputSptr_fx;
996 3795 : Word16 outputPptr_Q = 0, outputSptr_Q = 0;
997 3795 : move16();
998 3795 : move16();
999 3795 : Word32 tmp1 = 0, tmp2 = 0, tmp3 = 0;
1000 3795 : move32();
1001 3795 : move32();
1002 3795 : move32();
1003 :
1004 3795 : IF( GT_16( L_frame_0, L_frame_1 ) )
1005 : {
1006 2082 : outputPptr_fx = output_fx0;
1007 2082 : L_lerp_fx( output_fx1, outputResamp_fx, L_frame_0, L_frame_1, output_Q );
1008 2082 : outputPptr_Q = *output_Q;
1009 2082 : move16();
1010 2082 : outputSptr_fx = outputResamp_fx;
1011 2082 : outputSptr_Q = 1;
1012 2082 : move16();
1013 : }
1014 1713 : ELSE IF( GT_16( L_frame_1, L_frame_0 ) )
1015 : {
1016 0 : outputSptr_fx = output_fx1;
1017 0 : L_lerp_fx( output_fx0, outputResamp_fx, L_frame_1, L_frame_0, output_Q );
1018 0 : outputSptr_Q = *output_Q;
1019 0 : move16();
1020 0 : outputPptr_fx = outputResamp_fx;
1021 0 : outputPptr_Q = 1;
1022 0 : move16();
1023 : }
1024 : ELSE
1025 : {
1026 1713 : outputPptr_fx = output_fx0;
1027 1713 : outputSptr_fx = output_fx1;
1028 1713 : outputPptr_Q = *output_Q;
1029 1713 : move16();
1030 1713 : outputSptr_Q = *output_Q;
1031 1713 : move16();
1032 : }
1033 :
1034 3795 : Word16 guard_bits = find_guarded_bits_fx( L_frame_0 );
1035 :
1036 1108563 : FOR( i = 0; i < L_frame_0; i++ )
1037 : {
1038 1104768 : tmp1 = Mpy_32_32( *outputPptr_fx, *outputPptr_fx ); // 2*outputPptr_Q - 31
1039 1104768 : tmp1 = L_shr( tmp1, guard_bits ); // 2*outputPptr_Q - 31 - guard_bits
1040 1104768 : enrP_fx = L_add( enrP_fx, tmp1 );
1041 1104768 : tmp2 = Mpy_32_32( *outputSptr_fx, *outputSptr_fx ); // 2*outputSptr_Q - 31
1042 1104768 : tmp2 = L_shr( tmp2, guard_bits ); // 2 * outputSptr_Q - 31 - guard_bits
1043 1104768 : enrS_fx = L_add( enrS_fx, tmp2 );
1044 :
1045 1104768 : tmp3 = Mpy_32_32( *outputPptr_fx++, *outputSptr_fx++ ); // outputSptr_Q + outputPptr_Q - 31
1046 1104768 : tmp3 = L_shr( tmp3, add( guard_bits, 1 ) ); // outputSptr_Q + outputPptr_Q - 31 - guard_bits
1047 1104768 : dotPS_fx = L_add( dotPS_fx, tmp3 );
1048 : }
1049 :
1050 3795 : Word32 Var1 = Mpy_32_32( enrP_fx, enrS_fx ); // 2*( outputPptr_Q - 31 - guard_bits + outputSptr_Q - 31 - guard_bits )
1051 3795 : Word16 exp = sub( 31, shl( add( sub( sub( outputPptr_Q, 31 ), guard_bits ), sub( sub( outputSptr_Q, 31 ), guard_bits ) ), 1 ) );
1052 :
1053 3795 : if ( Var1 == 0 )
1054 : {
1055 3752 : Var1 = 1;
1056 3752 : move32();
1057 : }
1058 :
1059 : Word32 Var2, Var3;
1060 3795 : Var2 = ISqrt32( Var1, &exp );
1061 3795 : Var3 = L_add( dotPS_fx, 1 ); /*adding one in order to make temp non-zero. q = Q_outputSptr + Q_outputPptr - guard_bits*/
1062 3795 : c_PS_fx = Mpy_32_32( Var3, Var2 ); /* outputSptr_Q + outputPptr_Q - guard_bits - exp */
1063 :
1064 3795 : Word16 c_PS_fx_Q = add( outputSptr_Q, sub( sub( sub( outputPptr_Q, guard_bits ), exp ), 31 ) );
1065 3795 : Word32 a = 0, b = 0;
1066 3795 : move32();
1067 3795 : move32();
1068 3795 : Word16 a_q = 0, b_q = 0, ab_q = 0;
1069 3795 : move16();
1070 3795 : move16();
1071 3795 : move16();
1072 :
1073 3795 : a = Mpy_32_32( c_PS_fx, ONE_MINUS_STEREO_TD_PS_CORR_FILT_Q31 ); // Q(c_PS_fx_Q)
1074 3795 : a_q = c_PS_fx_Q;
1075 3795 : move16();
1076 3795 : b = Mpy_32_32( STEREO_TD_PS_CORR_FILT_Q31, *c_PS_LT_fx ); // Q(Q_c_PS_LT_fx)
1077 3795 : b_q = Q_c_PS_LT_fx;
1078 3795 : move16();
1079 :
1080 3795 : IF( GT_16( a_q, b_q ) )
1081 : {
1082 3795 : ab_q = sub( a_q, b_q );
1083 3795 : *c_PS_LT_fx = L_add( L_shr( a, ab_q ), b );
1084 3795 : move32();
1085 3795 : Q_c_PS_LT_fx = b_q;
1086 3795 : move16();
1087 : }
1088 0 : ELSE IF( LT_16( b_q, a_q ) )
1089 : {
1090 0 : ab_q = sub( b_q, a_q );
1091 0 : *c_PS_LT_fx = L_add( a, L_shr( b, ab_q ) );
1092 0 : move32();
1093 0 : Q_c_PS_LT_fx = a_q;
1094 0 : move16();
1095 : }
1096 :
1097 3795 : return;
1098 : }
1099 :
1100 :
1101 : /*-------------------------------------------------------------------*
1102 : * Function stereo_cng_compute_LRcorr()
1103 : *
1104 : * CNA for TD stereo, compute LR correlation
1105 : *-------------------------------------------------------------------*/
1106 :
1107 3795 : static void stereo_cng_compute_LRcorr_fx(
1108 : CPE_DEC_HANDLE hCPE, /* i/o: CPE handle */
1109 : Word32 *output_fx[CPE_CHANNELS], /* i : Output signal OUTPUT_Q*/
1110 : const Word16 output_frame, /* i : Output frame length Q0*/
1111 : const Word16 tdm_ratio_idx /* i : TDM ratio index Q0*/
1112 : )
1113 : {
1114 : Word16 i;
1115 : Word32 c_LR_fx, c_fx, tmp_fx, sc_fx;
1116 : Word16 c_q;
1117 : Word64 enrL_fx, enrR_fx, dotLR_fx;
1118 : Word32 beta_fx;
1119 : Word16 enrL_q, enrR_q, dotLR_q;
1120 : Word16 enrL_inv_q, enrR_inv_q;
1121 : Word16 sc_q;
1122 : Word16 headroom_left_enrL, headroom_left_enrR, headroom_left_dotLR;
1123 : Word32 temp_x_inv, temp_y_inv, energy_xy_fx;
1124 : Word16 res_q;
1125 : Word32 numer_1, numer_2, numer_3, num;
1126 : Word16 numer_1_q, numer_2_q, numer_3_q, num_q;
1127 : Word32 denom_1, denom_2, denom_3, denom;
1128 : Word16 denom_1_q, denom_2_q, denom_3_q, denom_q;
1129 : Word32 beta_sqr, one_minus_beta_sqr;
1130 3795 : beta_fx = tdm_ratio_tabl_fx[tdm_ratio_idx];
1131 3795 : move32();
1132 :
1133 3795 : enrL_fx = 0;
1134 3795 : move64();
1135 3795 : enrR_fx = 0;
1136 3795 : move64();
1137 3795 : dotLR_fx = 0;
1138 3795 : move64();
1139 :
1140 2435475 : FOR( i = 0; i < output_frame; i++ )
1141 : {
1142 2431680 : enrL_fx = W_add( enrL_fx, W_mult0_32_32( output_fx[0][i], output_fx[0][i] ) ); /* 2 * OUTPUT_Q */
1143 2431680 : enrR_fx = W_add( enrR_fx, W_mult0_32_32( output_fx[1][i], output_fx[1][i] ) ); /* 2 * OUTPUT_Q */
1144 2431680 : dotLR_fx = W_add( dotLR_fx, W_mult0_32_32( output_fx[0][i], output_fx[1][i] ) ); /* 2 * OUTPUT_Q */
1145 : }
1146 3795 : dotLR_fx = W_add( dotLR_fx, EPSILON_FX_SMALL );
1147 3795 : if ( dotLR_fx < 0 )
1148 : {
1149 656 : dotLR_fx = W_neg( dotLR_fx );
1150 : }
1151 3795 : enrL_fx = W_add( enrL_fx, EPSILON_FX_SMALL );
1152 3795 : enrR_fx = W_add( enrR_fx, EPSILON_FX_SMALL );
1153 :
1154 3795 : headroom_left_enrL = W_norm( enrL_fx );
1155 3795 : headroom_left_enrR = W_norm( enrR_fx );
1156 :
1157 : {
1158 :
1159 3795 : IF( LT_16( headroom_left_enrL, 32 ) )
1160 : {
1161 3677 : enrL_fx = W_shr( enrL_fx, sub( 32, headroom_left_enrL ) );
1162 3677 : enrL_q = sub( 31, sub( ( 2 * OUTPUT_Q ), sub( 32, headroom_left_enrL ) ) );
1163 : }
1164 : ELSE
1165 : {
1166 118 : enrL_q = sub( 31, ( 2 * OUTPUT_Q ) );
1167 : }
1168 3795 : IF( LT_16( headroom_left_enrR, 32 ) )
1169 : {
1170 3731 : enrR_fx = W_shr( enrR_fx, sub( 32, headroom_left_enrR ) );
1171 3731 : enrR_q = sub( 31, sub( ( 2 * OUTPUT_Q ), sub( 32, headroom_left_enrR ) ) );
1172 : }
1173 : ELSE
1174 : {
1175 64 : enrR_q = sub( 31, ( 2 * OUTPUT_Q ) );
1176 : }
1177 :
1178 3795 : enrL_inv_q = enrL_q;
1179 3795 : move16();
1180 3795 : enrR_inv_q = enrR_q;
1181 3795 : move16();
1182 :
1183 3795 : temp_x_inv = ISqrt32( W_extract_l( enrL_fx ), &enrL_inv_q );
1184 3795 : temp_y_inv = ISqrt32( W_extract_l( enrR_fx ), &enrR_inv_q );
1185 3795 : energy_xy_fx = Mpy_32_32( temp_x_inv, temp_y_inv ); /* enrL_inv_q + enrR_inv_q - 31 */
1186 3795 : res_q = add( enrL_inv_q, enrR_inv_q );
1187 3795 : headroom_left_dotLR = W_norm( dotLR_fx );
1188 3795 : dotLR_q = OUTPUT_Q * 2;
1189 3795 : move16();
1190 3795 : IF( LT_16( headroom_left_dotLR, 32 ) )
1191 : {
1192 3704 : dotLR_fx = W_shr( dotLR_fx, sub( 32, headroom_left_dotLR ) );
1193 3704 : dotLR_q = sub( dotLR_q, sub( 32, headroom_left_dotLR ) );
1194 : }
1195 3795 : dotLR_fx = Mpy_32_32( W_extract_l( dotLR_fx ), energy_xy_fx );
1196 3795 : dotLR_q = add( dotLR_q, sub( sub( 31, res_q ), 31 ) );
1197 3795 : dotLR_fx = W_shl( dotLR_fx, sub( 31, dotLR_q ) );
1198 : }
1199 3795 : c_LR_fx = extract_h( W_extract_l( dotLR_fx ) );
1200 :
1201 3795 : Word16 div_q = 0;
1202 3795 : move16();
1203 3795 : c_fx = BASOP_Util_Divide3232_Scale( W_extract_l( enrL_fx ), W_extract_l( enrR_fx ), &div_q ); /* div_q */
1204 3795 : c_q = add( sub( 15, div_q ), sub( enrR_q, enrL_q ) );
1205 :
1206 3795 : hCPE->hStereoTD->c_LR_LT_fx = L_add( Mpy_32_32( STEREO_TD_PS_CORR_FILT_FX, hCPE->hStereoTD->c_LR_LT_fx ),
1207 3795 : Mpy_32_32( L_sub( ONE_IN_Q31, STEREO_TD_PS_CORR_FILT_FX ), L_deposit_h( extract_l( c_LR_fx ) ) ) ); /* Q31 */
1208 3795 : move32();
1209 3795 : hCPE->hStereoCng->c_LR_LT_fx = hCPE->hStereoTD->c_LR_LT_fx; /* Q31 */
1210 3795 : move32();
1211 :
1212 3795 : Word16 sqrt_q = sub( 31, c_q );
1213 3795 : Word32 sqrt_res = Sqrt32( c_fx, &sqrt_q );
1214 3795 : tmp_fx = Mpy_32_32( beta_fx, L_sub( ONE_IN_Q31, beta_fx ) );
1215 3795 : tmp_fx = Mpy_32_32( tmp_fx, hCPE->hStereoTD->c_LR_LT_fx );
1216 3795 : tmp_fx = Mpy_32_32( tmp_fx, sqrt_res );
1217 3795 : Word16 tmp_q = sub( sub( 31, sqrt_q ), 1 ); // *2 handled with q reduction
1218 :
1219 3795 : beta_sqr = Mpy_32_32( beta_fx, beta_fx ); /* Q31 */
1220 3795 : one_minus_beta_sqr = Mpy_32_32( L_sub( ONE_IN_Q31, beta_fx ), L_sub( ONE_IN_Q31, beta_fx ) ); /* Q31 */
1221 :
1222 3795 : numer_1 = Mpy_32_16_1( one_minus_beta_sqr, extract_l( c_fx ) ); // c_q+31-15
1223 3795 : numer_1_q = add( c_q, 31 - 15 );
1224 3795 : numer_2 = beta_sqr; // 31
1225 3795 : move32();
1226 3795 : numer_2_q = 31;
1227 3795 : move16();
1228 3795 : numer_3 = tmp_fx; // tmp_q
1229 3795 : move32();
1230 3795 : numer_3_q = tmp_q;
1231 3795 : move16();
1232 3795 : num_q = 31;
1233 3795 : move16();
1234 :
1235 3795 : num_q = s_min( num_q, numer_1_q );
1236 :
1237 3795 : num_q = s_min( num_q, numer_2_q );
1238 :
1239 3795 : num_q = s_min( num_q, numer_3_q );
1240 :
1241 3795 : denom_1 = Mpy_32_16_1( beta_sqr, extract_l( c_fx ) ); // c_q+31-15;
1242 3795 : denom_1_q = add( c_q, 31 - 15 );
1243 3795 : denom_2 = one_minus_beta_sqr; // 31
1244 3795 : move32();
1245 3795 : denom_2_q = 31;
1246 3795 : move16();
1247 3795 : denom_3 = tmp_fx; // tmp_q
1248 3795 : move32();
1249 3795 : denom_3_q = tmp_q;
1250 3795 : move16();
1251 3795 : denom_q = 31;
1252 3795 : move16();
1253 :
1254 3795 : denom_q = s_min( denom_q, denom_1_q );
1255 :
1256 3795 : denom_q = s_min( denom_q, denom_2_q );
1257 :
1258 3795 : denom_q = s_min( denom_q, denom_3_q );
1259 :
1260 3795 : num = L_add( L_add( L_shr( numer_1, sub( numer_1_q, num_q ) ), L_sub( L_shr( numer_2, sub( numer_2_q, num_q ) ), L_shr( numer_3, sub( numer_3_q, num_q ) ) ) ), DELTA_FX ); /* num_q */
1261 3795 : denom = L_add( L_add( L_shr( denom_1, sub( denom_1_q, denom_q ) ), L_add( L_shr( denom_2, sub( denom_2_q, denom_q ) ), L_shr( denom_3, sub( denom_3_q, denom_q ) ) ) ), DELTA_FX ); /* denom_q */
1262 3795 : Word16 q = 0;
1263 3795 : move16();
1264 3795 : sc_fx = BASOP_Util_Divide3232_Scale( num, denom, &q );
1265 3795 : sc_q = sub( sub( 15, sub( num_q, denom_q ) ), q );
1266 3795 : Word32 sc_thr = L_shr( sc_fx, sc_q );
1267 3795 : IF( GT_32( sc_thr, 4 ) )
1268 : {
1269 557 : sc_fx = MAX_WORD16;
1270 557 : move32();
1271 : }
1272 : ELSE
1273 : {
1274 3238 : sc_fx = L_shr( sc_fx, sub( sc_q, 13 ) );
1275 : }
1276 3795 : sqrt_q = 2;
1277 3795 : move16();
1278 3795 : sqrt_res = Sqrt32( L_shl_sat( sc_fx, 16 ), &sqrt_q );
1279 3795 : IF( sqrt_q < 0 )
1280 : {
1281 688 : sqrt_res = L_shr( sqrt_res, ( -sqrt_q ) );
1282 688 : sqrt_q = 0;
1283 688 : move16();
1284 : }
1285 3795 : hCPE->hStereoTD->SP_ratio_LT_fx = L_add_sat( Mpy_32_32( 1932735283, hCPE->hStereoTD->SP_ratio_LT_fx ),
1286 : L_shl_sat( Mpy_32_32( 214748364, sqrt_res ), sqrt_q ) ); /* sqrt_q */
1287 3795 : move32();
1288 :
1289 3795 : IF( LT_16( hCPE->hStereoCng->nr_corr_frames, CM_INIT ) )
1290 : {
1291 1780 : hCPE->hStereoCng->nr_corr_frames = add( hCPE->hStereoCng->nr_corr_frames, 1 ); /* Q0 */
1292 1780 : move16();
1293 : }
1294 :
1295 3795 : hCPE->hStereoCng->nr_dft_frames = 0;
1296 3795 : move16();
1297 :
1298 3795 : return;
1299 : }
1300 :
1301 :
1302 : /*-------------------------------------------------------------------*
1303 : * FindEmEs()
1304 : *
1305 : * Find the energie ratio between the mono and the side
1306 : *-------------------------------------------------------------------*/
1307 :
1308 :
1309 40990 : static void FindEmEs_fx(
1310 : const Word32 *ch1_fx, /* i : Left channel OUTPUT_Q*/
1311 : const Word32 *ch2_fx, /* i : right channel OUTPUT_Q*/
1312 : const Word16 len, /* i : length Q0*/
1313 : Word32 *lt_es_em_fx /* i/o: LT energy ratio Q24*/
1314 : )
1315 : {
1316 : Word16 i;
1317 : Word32 mono_i_fx;
1318 : Word32 es_em_fx;
1319 : Word32 side_i_fx;
1320 : Word64 ener_fx, ener_side_fx;
1321 : Word16 headroom_left_ener_fx, headroom_left_ener_side_fx;
1322 : Word16 ener_q, ener_side_q;
1323 40990 : ener_fx = 1;
1324 40990 : move64();
1325 40990 : ener_side_fx = 1;
1326 40990 : move64();
1327 : Word32 square_res, log_res, division_res;
1328 40990 : Word16 temp_q = 0;
1329 40990 : move16();
1330 26522590 : FOR( i = 0; i < len; i++ )
1331 : {
1332 26481600 : mono_i_fx = L_add( L_shr( ch1_fx[i], 1 ), L_shr( ch2_fx[i], 1 ) );
1333 26481600 : ener_fx = W_add( ener_fx, W_mult0_32_32( mono_i_fx, mono_i_fx ) ); /* 2 * OUTPUT_Q */
1334 26481600 : side_i_fx = L_sub( L_shr( ch1_fx[i], 1 ), L_shr( ch2_fx[i], 1 ) );
1335 26481600 : ener_side_fx = W_add( ener_side_fx, W_mult0_32_32( side_i_fx, side_i_fx ) ); /* 2 * OUTPUT_Q */
1336 : }
1337 40990 : headroom_left_ener_fx = W_norm( ener_fx );
1338 40990 : headroom_left_ener_side_fx = W_norm( ener_side_fx );
1339 :
1340 40990 : IF( LT_16( headroom_left_ener_fx, 32 ) )
1341 : {
1342 39619 : ener_fx = W_shr( ener_fx, sub( 32, headroom_left_ener_fx ) ); /* 2 * OUTPUT_Q - 32 * headroom_left_ener_fx */
1343 39619 : ener_q = sub( ( 2 * OUTPUT_Q ), sub( 32, headroom_left_ener_fx ) );
1344 : }
1345 : ELSE
1346 : {
1347 1371 : ener_q = ( 2 * OUTPUT_Q );
1348 1371 : move16();
1349 : }
1350 40990 : IF( LT_16( headroom_left_ener_side_fx, 32 ) )
1351 : {
1352 38418 : ener_side_fx = W_shr( ener_side_fx, sub( 32, headroom_left_ener_side_fx ) ); /* 2 * OUTPUT_Q - 32 * headroom_left_ener_fx */
1353 38418 : ener_side_q = sub( ( 2 * OUTPUT_Q ), sub( 32, headroom_left_ener_side_fx ) );
1354 : }
1355 : ELSE
1356 : {
1357 2572 : ener_side_q = ( 2 * OUTPUT_Q );
1358 2572 : move16();
1359 : }
1360 :
1361 : /**es_em = 10 * ( log10( sqrt( ener_side / len ) ) - log10( sqrt( ener / len ) ) ); */
1362 40990 : division_res = BASOP_Util_Divide3232_Scale( W_extract_l( ener_side_fx ), W_extract_l( ener_fx ), &temp_q );
1363 40990 : temp_q = sub( temp_q, sub( ener_side_q, ener_q ) );
1364 40990 : square_res = Sqrt32( L_deposit_h( extract_l( division_res ) ), &temp_q ); /* temp_q */
1365 40990 : IF( temp_q < 0 )
1366 : {
1367 20341 : square_res = L_shr( square_res, ( -temp_q ) );
1368 20341 : temp_q = 0;
1369 20341 : move16();
1370 : }
1371 40990 : log_res = L_add( BASOP_Util_Log2( square_res ), L_shl( temp_q, Q25 ) );
1372 40990 : es_em_fx = Mpy_32_32( log_res, 1616107501 /* 5 * (ln(2)/ln(10)) */ ); // 25+30-31
1373 : /* long-term estimate */
1374 40990 : *lt_es_em_fx = L_add( Mpy_32_32( 858993459, *lt_es_em_fx ), Mpy_32_32( 1288490188, es_em_fx ) ); /* Q24 */
1375 40990 : move32();
1376 :
1377 40990 : return;
1378 : }
1379 :
1380 :
1381 : /*-------------------------------------------------------------------*
1382 : * Function stereo_cna_update_params()
1383 : *
1384 : * compute LR correlation and update long-term parameters for stereo CNA
1385 : *-------------------------------------------------------------------*/
1386 :
1387 149278 : void stereo_cna_update_params_fx(
1388 : CPE_DEC_HANDLE hCPE, /* i/o: CPE decoder structure */
1389 : Word32 *output_fx[CPE_CHANNELS], /* i : Output signal OUTPUT_Q*/
1390 : const Word16 output_frame, /* i : Output frame length Q0*/
1391 : const Word16 tdm_ratio_idx /* i : TDM ratio index Q0*/
1392 : )
1393 : {
1394 : Word16 i;
1395 : Word64 enrL_fx, enrR_fx, dotLR_fx;
1396 : Word32 c_fx, c_LR_fx, c_ILD_fx;
1397 : Decoder_State **sts;
1398 : HANDLE_FD_CNG_DEC hFdCngDec;
1399 : Word16 dotLR_fx_q;
1400 : Word32 temp_x_inv, temp_y_inv, energy_xy_fx;
1401 : Word16 headroom_left_x, headroom_left_y;
1402 : Word16 headroom_left_dotLR_fx;
1403 : Word16 x_q, y_q, c_q;
1404 : Word16 x_inv_q, y_inv_q;
1405 : Word16 temp_res_q;
1406 149278 : sts = hCPE->hCoreCoder;
1407 :
1408 149278 : hFdCngDec = sts[0]->hFdCngDec;
1409 :
1410 149278 : IF( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) )
1411 : {
1412 59583 : IF( GT_16( hCPE->nchan_out, 1 ) )
1413 : {
1414 37195 : FindEmEs_fx( output_fx[0], output_fx[1], output_frame, &hCPE->lt_es_em_fx );
1415 : }
1416 : ELSE
1417 : {
1418 22388 : hCPE->lt_es_em_fx = 0;
1419 22388 : move32();
1420 : }
1421 : }
1422 89695 : ELSE IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) )
1423 : {
1424 3795 : FindEmEs_fx( output_fx[0], output_fx[1], output_frame, &hCPE->lt_es_em_fx );
1425 :
1426 3795 : hCPE->hStereoCng->first_SID_after_TD = 1; /* Q0 */
1427 3795 : move16();
1428 3795 : stereo_cng_compute_LRcorr_fx( hCPE, output_fx, output_frame, tdm_ratio_idx );
1429 : }
1430 : ELSE
1431 : {
1432 85900 : hFdCngDec->first_cna_noise_updated = 0;
1433 85900 : move16();
1434 :
1435 85900 : return;
1436 : }
1437 :
1438 63378 : enrL_fx = 0;
1439 63378 : move64();
1440 63378 : enrR_fx = 0;
1441 63378 : move64();
1442 63378 : dotLR_fx = 0;
1443 63378 : move64();
1444 :
1445 63378 : test();
1446 63378 : test();
1447 63378 : test();
1448 63378 : IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) || ( EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) && GT_32( sts[0]->core_brate, SID_2k40 ) && ( sts[0]->VAD == 0 ) ) )
1449 : {
1450 6948 : IF( EQ_16( hCPE->nchan_out, 1 ) )
1451 : {
1452 2854 : c_LR_fx = MAX_32;
1453 2854 : move32();
1454 2854 : c_ILD_fx = 0;
1455 2854 : move32();
1456 : }
1457 : ELSE
1458 : {
1459 2794814 : FOR( i = 0; i < output_frame; i++ )
1460 : {
1461 2790720 : enrL_fx = W_add( enrL_fx, W_mult0_32_32( output_fx[0][i], output_fx[0][i] ) ); /* 2 * OUTPUT_Q */
1462 2790720 : enrR_fx = W_add( enrR_fx, W_mult0_32_32( output_fx[1][i], output_fx[1][i] ) ); /* 2 * OUTPUT_Q */
1463 2790720 : dotLR_fx = W_add( dotLR_fx, W_mult0_32_32( output_fx[0][i], output_fx[1][i] ) ); /* 2 * OUTPUT_Q */
1464 : }
1465 4094 : dotLR_fx = W_add( dotLR_fx, EPSILON_FX_SMALL );
1466 4094 : if ( dotLR_fx < 0 )
1467 : {
1468 740 : dotLR_fx = W_neg( dotLR_fx );
1469 : }
1470 4094 : enrL_fx = W_add( enrL_fx, EPSILON_FX_SMALL );
1471 4094 : enrR_fx = W_add( enrR_fx, EPSILON_FX_SMALL );
1472 4094 : headroom_left_x = W_norm( enrL_fx );
1473 4094 : headroom_left_y = W_norm( enrR_fx );
1474 :
1475 4094 : IF( LT_16( headroom_left_x, 32 ) )
1476 : {
1477 4008 : enrL_fx = W_shr( enrL_fx, sub( 32, headroom_left_x ) ); /* 2 * OUTPUT_Q - 32 * headroom_left_x */
1478 4008 : x_q = sub( 31, sub( ( 2 * OUTPUT_Q ), sub( 32, headroom_left_x ) ) );
1479 : }
1480 : ELSE
1481 : {
1482 86 : x_q = sub( 31, ( 2 * OUTPUT_Q ) );
1483 : }
1484 4094 : IF( LT_16( headroom_left_y, 32 ) )
1485 : {
1486 4055 : enrR_fx = W_shr( enrR_fx, sub( 32, headroom_left_y ) ); /* 2 * OUTPUT_Q - 32 * headroom_left_x */
1487 4055 : y_q = sub( 31, sub( ( 2 * OUTPUT_Q ), sub( 32, headroom_left_y ) ) );
1488 : }
1489 : ELSE
1490 : {
1491 39 : y_q = sub( 31, ( 2 * OUTPUT_Q ) );
1492 : }
1493 :
1494 4094 : x_inv_q = x_q;
1495 4094 : move16();
1496 4094 : y_inv_q = y_q;
1497 4094 : move16();
1498 :
1499 4094 : temp_x_inv = ISqrt32( W_extract_l( enrL_fx ), &x_inv_q );
1500 4094 : temp_y_inv = ISqrt32( W_extract_l( enrR_fx ), &y_inv_q );
1501 4094 : energy_xy_fx = Mpy_32_32( temp_x_inv, temp_y_inv ); /* x_inv_q + y_inv_q */
1502 4094 : temp_res_q = add( x_inv_q, y_inv_q );
1503 4094 : headroom_left_dotLR_fx = W_norm( dotLR_fx );
1504 4094 : dotLR_fx_q = OUTPUT_Q * 2;
1505 4094 : move16();
1506 4094 : IF( LT_16( headroom_left_dotLR_fx, 32 ) )
1507 : {
1508 4035 : dotLR_fx = W_shr( dotLR_fx, sub( 32, headroom_left_dotLR_fx ) ); /* dotLR_fx_q - (32 * headroom_left_dotLR_fx) */
1509 4035 : dotLR_fx_q = sub( dotLR_fx_q, sub( 32, headroom_left_dotLR_fx ) );
1510 : }
1511 4094 : dotLR_fx = Mpy_32_32( W_extract_l( dotLR_fx ), energy_xy_fx ); /* dotLR_fx_q + ((31 - temp_res_q) - 31)) */
1512 4094 : dotLR_fx_q = add( dotLR_fx_q, sub( sub( 31, temp_res_q ), 31 ) );
1513 4094 : dotLR_fx = W_deposit32_l( L_shl_sat( W_extract_l( dotLR_fx ), sub( 31, dotLR_fx_q ) ) ); /* Q31 */
1514 : /* estimate L/R correlation factor and ILD in time domain */
1515 4094 : c_LR_fx = W_extract_l( dotLR_fx ); /* Q31 */
1516 :
1517 4094 : temp_res_q = 0;
1518 4094 : move16();
1519 4094 : c_fx = BASOP_Util_Divide3232_Scale( W_extract_l( enrL_fx ), W_extract_l( enrR_fx ), &temp_res_q );
1520 4094 : c_q = add( sub( 15, temp_res_q ), sub( y_q, x_q ) );
1521 :
1522 : Word32 one_in_c_q;
1523 4094 : IF( GT_16( c_q, 31 ) )
1524 : {
1525 66 : c_q = 31;
1526 66 : move16();
1527 66 : c_fx = L_shr_sat( c_fx, sub( c_q, 31 ) ); /* Q31 */
1528 66 : one_in_c_q = ONE_IN_Q31;
1529 66 : move32();
1530 : }
1531 : ELSE
1532 : {
1533 4028 : one_in_c_q = L_shl_sat( 1, c_q );
1534 : }
1535 :
1536 4094 : Word32 num_c_fx = L_sub_sat( c_fx, one_in_c_q );
1537 4094 : Word32 denom_c_fx = L_add_sat( c_fx, one_in_c_q );
1538 4094 : Word16 num_c_headroom = norm_l( L_sub_sat( c_fx, one_in_c_q ) );
1539 4094 : Word16 denom_c_headroom = norm_l( L_add_sat( c_fx, one_in_c_q ) );
1540 4094 : Word16 min_headroom_left = s_min( num_c_headroom, denom_c_headroom );
1541 4094 : move16();
1542 4094 : temp_res_q = 0;
1543 4094 : move16();
1544 4094 : c_ILD_fx = BASOP_Util_Divide3232_Scale( L_shl_sat( num_c_fx, min_headroom_left ), L_shl_sat( denom_c_fx, min_headroom_left ), &temp_res_q ); /* temp_res_q */
1545 4094 : IF( temp_res_q < 0 )
1546 : {
1547 2011 : c_ILD_fx = L_shr( c_ILD_fx, negate( temp_res_q ) );
1548 : }
1549 : }
1550 :
1551 : /* update of long-term ILD and LR correlation factors for stereo CNA */
1552 6948 : IF( !hFdCngDec->first_cna_noise_updated )
1553 : {
1554 2851 : hFdCngDec->cna_LR_LT_fx = extract_h( c_LR_fx );
1555 2851 : move16();
1556 2851 : hFdCngDec->cna_ILD_LT_fx = extract_l( c_ILD_fx );
1557 2851 : move16();
1558 : }
1559 : ELSE
1560 : {
1561 4097 : hFdCngDec->cna_LR_LT_fx = extract_h( L_add_sat( Mpy_32_16_1( STEREO_CNA_LR_CORR_LT_FILT_FX, hFdCngDec->cna_LR_LT_fx ),
1562 : Mpy_32_32( ONE_IN_Q31 - STEREO_CNA_LR_CORR_LT_FILT_FX, c_LR_fx ) ) ); /* Q31 */
1563 4097 : move16();
1564 :
1565 4097 : hFdCngDec->cna_ILD_LT_fx = extract_h( L_add_sat( Mpy_32_16_1( STEREO_CNA_ILD_LT_FILT_FX, hFdCngDec->cna_ILD_LT_fx ),
1566 4097 : Mpy_32_16_1( L_sub( ONE_IN_Q31, STEREO_CNA_ILD_LT_FILT_FX ), extract_l( c_ILD_fx ) ) ) ); /* Q31 */
1567 4097 : move16();
1568 : }
1569 :
1570 6948 : set16_fx( hFdCngDec->cna_g_state_fx, hFdCngDec->cna_ILD_LT_fx, hFdCngDec->cna_nbands );
1571 6948 : set16_fx( hFdCngDec->cna_cm_fx, hFdCngDec->cna_LR_LT_fx, hFdCngDec->cna_nbands );
1572 : }
1573 :
1574 : /* Soft VAD for stereo CNA */
1575 63378 : test();
1576 63378 : IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) || EQ_16( hCPE->element_mode, IVAS_CPE_DFT ) )
1577 : {
1578 63378 : IF( !hFdCngDec->first_cna_noise_updated )
1579 : {
1580 32797 : hFdCngDec->cna_act_fact_fx = 0;
1581 32797 : move16();
1582 : }
1583 : ELSE
1584 : {
1585 30581 : IF( EQ_16( hCPE->element_mode, IVAS_CPE_TD ) )
1586 : {
1587 : /* quickly decrease in TD stereo mode */
1588 1610 : hFdCngDec->cna_act_fact_fx = extract_h( Mpy_32_16_1( 1503238553, hFdCngDec->cna_act_fact_fx ) ); /* Q15 */
1589 1610 : move16();
1590 : }
1591 28971 : ELSE IF( GT_32( L_mult0( sts[0]->VAD, MAX_WORD16 ), hFdCngDec->cna_act_fact_fx ) ) // VAD is one bit
1592 : {
1593 : /* quickly increase during active frames in DFT stereo mode */
1594 16135 : hFdCngDec->cna_act_fact_fx = extract_h( L_add( Mpy_32_16_1( 1503238553, hFdCngDec->cna_act_fact_fx ), ( 644245094 * sts[0]->VAD ) ) ); /* Q15 */
1595 16135 : move16();
1596 : }
1597 : ELSE
1598 : {
1599 : /* slowly decrease during inactive frames in DFT stereo mode */
1600 12836 : hFdCngDec->cna_act_fact_fx = extract_h( L_add( Mpy_32_16_1( 2040109440, hFdCngDec->cna_act_fact_fx ), ( 107374184 * sts[0]->VAD ) ) ); /* Q15 */
1601 12836 : move16();
1602 : }
1603 : }
1604 : }
1605 :
1606 63378 : return;
1607 : }
1608 :
1609 :
1610 : /*-------------------------------------------------------------------
1611 : * stereo_cng_init_dec()
1612 : *
1613 : * Initialized stereo CNG
1614 : *-------------------------------------------------------------------*/
1615 :
1616 806 : void stereo_cng_init_dec_fx(
1617 : STEREO_CNG_DEC_HANDLE hStereoCng, /* i/o: stereo CNG decoder structure */
1618 : const Word16 *frameSize /* i : pointer to frameSize of channel 0 to be used for channel 1 Q0*/
1619 : )
1620 : {
1621 806 : hStereoCng->prev_sid_nodata = 0;
1622 806 : move16();
1623 806 : set16_fx( hStereoCng->coh_fx, 8192 /*0.5 in Q14*/, STEREO_DFT_BAND_MAX + 1 );
1624 806 : set16_fx( hStereoCng->cm_fx, 0, STEREO_DFT_BAND_MAX );
1625 806 : hStereoCng->first_SID = 1;
1626 806 : move16();
1627 806 : hStereoCng->first_SID_after_TD = 0;
1628 806 : move16();
1629 806 : hStereoCng->active_frame_counter = 0;
1630 806 : move16();
1631 806 : hStereoCng->xfade_frame_counter = 0;
1632 806 : move16();
1633 806 : hStereoCng->xfade_length = 0;
1634 806 : move16();
1635 806 : hStereoCng->nr_dft_frames = 0;
1636 806 : move16();
1637 806 : hStereoCng->nr_corr_frames = 0;
1638 806 : move16();
1639 806 : hStereoCng->nr_sid_frames = 0;
1640 806 : move16();
1641 806 : set16_fx( hStereoCng->olapBufferSynth22_fx, 0, FFTLEN );
1642 806 : hStereoCng->flag_cna_fade = 0;
1643 806 : move16();
1644 806 : set16_fx( hStereoCng->maskingNoiseS_fx, 0, L_FRAME16k );
1645 806 : hStereoCng->enableSecCNA = 0;
1646 806 : move16();
1647 806 : hStereoCng->c_PS_LT_fx = 16384; /* 0.5 in Q15 */
1648 806 : move16();
1649 806 : hStereoCng->frameSize = frameSize;
1650 806 : hStereoCng->last_act_element_mode = IVAS_CPE_DFT;
1651 806 : move16();
1652 :
1653 806 : return;
1654 : }
|