Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 :
6 : #include <assert.h>
7 : #include "typedef.h"
8 : #include <stdint.h>
9 : #include "options.h"
10 : #include "rom_com.h"
11 : #include "stat_dec.h"
12 : #include "prot_fx.h"
13 : #include "ivas_prot_fx.h"
14 : #include "basop_util.h"
15 : #include "rom_basop_util.h"
16 : #include "ivas_rom_dec.h"
17 : #include "ivas_prot_fx.h"
18 : #ifdef DEBUGGING
19 : #include "debug.h"
20 : #endif
21 :
22 :
23 : #define CNA_ACT_DN_LARGE_PARTITION 50 /* index of the first larger partition */
24 : #define ST_PERIODOG_FACT_Q15 29491 /* 0.9 in Q15, short-term filter factor for periodogram */
25 : #define CNA_ACT_DN_FACT_Q15 22938 /* 0.7 in Q15, downward updating factor for CNA during active frames */
26 : #define FIRST_CNA_NOISE_UPD_FRAMES 5 /* minimum number of CN initialization frames */
27 : #define DELTA_MASKING_NOISE_Q15 0
28 : #define LOG_10_BASE_2 1783446566 /* Q29 */
29 : #define GAIN_Q_OFFSET_IVAS_FX 45
30 : #define LOG_10_BASE_2_BY_10_Q31 713378606
31 : #define TWO_BY_THREE_Q31 1431655765
32 : #define ONE_BY_FRAMES_PER_SEC_Q15 656
33 : #define NB_LAST_BAND_SCALE_Q31 1717986918
34 : #define SWB_13k2_LAST_BAND_SCALE_Q31 1717986918
35 :
36 : /********************************
37 : * External tables *
38 : ********************************/
39 :
40 : extern const Word16 T_DIV_L_Frame[]; /* format: 0Q15 * 2^-7 */
41 :
42 : const Word16 maxN_37bits = FD_CNG_maxN_37bits;
43 : const Word16 maxC_37bits = FD_CNG_maxC_37bits;
44 : const Word16 stages_37bits = FD_CNG_stages_37bits;
45 : /*
46 : createFdCngDec_fx
47 :
48 : Parameters:
49 :
50 : hFdCngDec i/0 : pointer to cng decoder structure
51 :
52 : Function:
53 : create an instance of type FD_CNG
54 : */
55 7135 : ivas_error createFdCngDec_fx( HANDLE_FD_CNG_DEC *hFdCngDec )
56 : {
57 : HANDLE_FD_CNG_DEC hs;
58 : ivas_error error;
59 7135 : error = IVAS_ERR_OK;
60 :
61 : /* Allocate memory */
62 7135 : hs = (HANDLE_FD_CNG_DEC) malloc( sizeof( FD_CNG_DEC ) );
63 :
64 7135 : IF( hs == NULL )
65 : {
66 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FD CNG DEC structure" );
67 : }
68 7135 : IF( ( error = createFdCngCom_fx( &( hs->hFdCngCom ) ) ) != IVAS_ERR_OK )
69 : {
70 0 : return error;
71 : }
72 :
73 7135 : *hFdCngDec = hs;
74 7135 : return error;
75 : }
76 :
77 7132 : void initFdCngDec_ivas_fx(
78 : DEC_CORE_HANDLE st, /* i/o: decoder state structure */
79 : Word16 scale /*Q15*/ )
80 : {
81 : /* Initialize common */
82 : HANDLE_FD_CNG_DEC hFdCngDec;
83 :
84 7132 : hFdCngDec = st->hFdCngDec;
85 :
86 7132 : ivas_initFdCngCom_fx( hFdCngDec->hFdCngCom, scale );
87 7132 : set16_fx( hFdCngDec->olapBufferAna, 0, FFTLEN );
88 7132 : hFdCngDec->hFdCngCom->olapBufferAna = hFdCngDec->olapBufferAna;
89 7132 : set16_fx( hFdCngDec->olapBufferSynth2, 0, FFTLEN );
90 7132 : hFdCngDec->hFdCngCom->olapBufferSynth2 = hFdCngDec->olapBufferSynth2;
91 :
92 : /* Set some counters and flags */
93 :
94 7132 : hFdCngDec->flag_dtx_mode = 0;
95 7132 : move16();
96 7132 : hFdCngDec->lp_noise = -167772160l /*-20.f Q23*/; /* format: Q8.24 */
97 7132 : move32();
98 7132 : hFdCngDec->lp_speech = 209715200l /* 25.f Q23*/; /* format: Q8.24 */
99 7132 : move32();
100 :
101 : /* Initialization of the noise estimation algorithm */
102 :
103 7132 : set32_fx( hFdCngDec->bandNoiseShape, 0, FFTLEN2 );
104 7132 : set16_fx( &hFdCngDec->bandNoiseShape_exp, 0, 1 );
105 :
106 7132 : set32_fx( hFdCngDec->partNoiseShape, 0, NPART );
107 7132 : set16_fx( &hFdCngDec->partNoiseShape_exp, 0, 1 );
108 :
109 7132 : set32_fx( hFdCngDec->msPeriodog, 0, NPART_SHAPING );
110 7132 : set16_fx( &hFdCngDec->msPeriodog_exp, 0, 1 );
111 :
112 7132 : set32_fx( hFdCngDec->msAlpha, 0, NPART_SHAPING );
113 :
114 7132 : set32_fx( hFdCngDec->msBminWin, 0, NPART_SHAPING );
115 :
116 7132 : set32_fx( hFdCngDec->msBminSubWin, 0, NPART_SHAPING );
117 :
118 7132 : set16_fx( hFdCngDec->msPsd, 0, NPART_SHAPING );
119 7132 : set32_fx( hFdCngDec->msPsd_fx, 0, NPART_SHAPING );
120 7132 : set32_fx( hFdCngDec->msNoiseFloor_32fx, 0, NPART_SHAPING );
121 :
122 7132 : set32_fx( hFdCngDec->msNoiseEst, 0, NPART_SHAPING );
123 7132 : set16_fx( &hFdCngDec->msNoiseEst_exp, 0, 1 );
124 :
125 7132 : set32_fx( hFdCngDec->msMinBuf, 2147483647l /*1.0 Q31*/, MSNUMSUBFR * NPART_SHAPING );
126 :
127 7132 : set32_fx( hFdCngDec->msCurrentMin, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
128 :
129 7132 : set32_fx( hFdCngDec->msCurrentMinOut, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
130 :
131 7132 : set32_fx( hFdCngDec->msCurrentMinSubWindow, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
132 :
133 7132 : set16_fx( hFdCngDec->msLocalMinFlag, 0, NPART_SHAPING );
134 7132 : set16_fx( hFdCngDec->msNewMinFlag, 0, NPART_SHAPING );
135 :
136 7132 : set16_fx( hFdCngDec->msPsdFirstMoment, 0, NPART_SHAPING );
137 :
138 7132 : set32_fx( hFdCngDec->msPsdSecondMoment, 0, NPART_SHAPING );
139 7132 : set16_fx( hFdCngDec->msPeriodogBuf, 0, MSBUFLEN * NPART_SHAPING );
140 :
141 7132 : hFdCngDec->msPeriodogBufPtr = 0;
142 7132 : move16();
143 :
144 7132 : set16_fx( hFdCngDec->msLogPeriodog, 0, NPART_SHAPING );
145 7132 : set32_fx( hFdCngDec->msLogNoiseEst_32fx, 0, NPART_SHAPING );
146 :
147 7132 : set16_fx( hFdCngDec->psize_shaping, 0, NPART_SHAPING );
148 7132 : hFdCngDec->nFFTpart_shaping = 0;
149 7132 : move16();
150 7132 : set32_fx( hFdCngDec->msPeriodog_ST_fx, 0, NPART_SHAPING );
151 7132 : hFdCngDec->msPeriodog_ST_exp = 0;
152 7132 : move16();
153 7132 : hFdCngDec->hFdCngCom->fftBuffer_exp = 0;
154 7132 : move16();
155 7132 : hFdCngDec->hFdCngCom->periodog_exp = 0;
156 7132 : move16();
157 7132 : set32_fx( hFdCngDec->smoothed_psd_fx, 0, L_FRAME16k );
158 7132 : hFdCngDec->smoothed_psd_exp = 0;
159 7132 : move16();
160 7132 : set32_fx( hFdCngDec->hFdCngCom->sidNoiseEstLp, 0, NPART );
161 :
162 7132 : hFdCngDec->ms_last_inactive_bwidth = NB;
163 7132 : move16();
164 7132 : hFdCngDec->ms_cnt_bw_up = 0;
165 7132 : move16();
166 :
167 7132 : hFdCngDec->cna_LR_LT_fx = 16384; /* 0.5 in Q15 */
168 7132 : move16();
169 7132 : hFdCngDec->cna_ILD_LT_fx = 0;
170 7132 : move16();
171 7132 : hFdCngDec->first_cna_noise_updated = 0;
172 7132 : move16();
173 7132 : hFdCngDec->first_cna_noise_update_cnt = 0;
174 7132 : move16();
175 7132 : hFdCngDec->cna_nbands = CNA_INIT_NBANDS;
176 7132 : move16();
177 7132 : Copy( cna_init_bands, hFdCngDec->cna_band_limits, CNA_INIT_NBANDS + 1 );
178 7132 : hFdCngDec->cna_act_fact_fx = 32767; /* 1.0f in Q15 */
179 7132 : move16();
180 7132 : hFdCngDec->cna_rescale_fact_fx = 0;
181 7132 : move16();
182 7132 : hFdCngDec->cna_seed = 5687; /*Q0*/
183 7132 : move16();
184 7132 : set16_fx( hFdCngDec->cna_cm_fx, 0, STEREO_DFT_BAND_MAX );
185 7132 : set16_fx( hFdCngDec->cna_g_state_fx, 0, STEREO_DFT_BAND_MAX );
186 :
187 7132 : st->CNG_mode = -1;
188 7132 : move16();
189 7132 : Copy( st->lsp_old_fx, st->lspCNG_fx, M ); /*Q15*/
190 7132 : hFdCngDec->hFdCngCom->sid_frame_counter = 0;
191 7132 : return;
192 : }
193 :
194 3 : void initFdCngDec_fx(
195 : DEC_CORE_HANDLE st, /* i/o: decoder state structure */
196 : Word16 scale /*Q15*/ )
197 : {
198 : /* Initialize common */
199 : HANDLE_FD_CNG_DEC hFdCngDec;
200 :
201 3 : hFdCngDec = st->hFdCngDec;
202 :
203 3 : initFdCngCom( hFdCngDec->hFdCngCom, scale );
204 3 : set16_fx( hFdCngDec->olapBufferAna, 0, 320 );
205 3 : hFdCngDec->hFdCngCom->olapBufferAna = hFdCngDec->olapBufferAna;
206 3 : move16();
207 3 : set16_fx( hFdCngDec->olapBufferSynth2, 0, FFTLEN );
208 3 : hFdCngDec->hFdCngCom->olapBufferSynth2 = hFdCngDec->olapBufferSynth2;
209 3 : move16();
210 :
211 : /* Set some counters and flags */
212 :
213 3 : hFdCngDec->flag_dtx_mode = 0;
214 3 : move16();
215 3 : hFdCngDec->lp_noise = -167772160l /*-20.f Q23*/; /* format: Q8.24 */
216 3 : move32();
217 3 : hFdCngDec->lp_speech = 209715200l /* 25.f Q23*/; /* format: Q8.24 */
218 3 : move32();
219 :
220 : /* Initialization of the noise estimation algorithm */
221 :
222 3 : set32_fx( hFdCngDec->bandNoiseShape, 0, FFTLEN2 );
223 3 : set16_fx( &hFdCngDec->bandNoiseShape_exp, 0, 1 );
224 :
225 3 : set32_fx( hFdCngDec->partNoiseShape, 0, NPART );
226 3 : set16_fx( &hFdCngDec->partNoiseShape_exp, 0, 1 );
227 :
228 3 : set32_fx( hFdCngDec->msPeriodog, 0, NPART_SHAPING );
229 3 : set16_fx( &hFdCngDec->msPeriodog_exp, 0, 1 );
230 :
231 3 : set32_fx( hFdCngDec->msAlpha, 0, NPART_SHAPING );
232 :
233 3 : set32_fx( hFdCngDec->msBminWin, 0, NPART_SHAPING );
234 :
235 3 : set32_fx( hFdCngDec->msBminSubWin, 0, NPART_SHAPING );
236 :
237 3 : set16_fx( hFdCngDec->msPsd, 0, NPART_SHAPING );
238 3 : set32_fx( hFdCngDec->msPsd_fx, 0, NPART_SHAPING );
239 3 : set16_fx( hFdCngDec->msNoiseFloor, 0, NPART_SHAPING );
240 :
241 3 : set32_fx( hFdCngDec->msNoiseEst, 0, NPART_SHAPING );
242 3 : set16_fx( &hFdCngDec->msNoiseEst_exp, 0, 1 );
243 :
244 3 : set32_fx( hFdCngDec->msMinBuf, 2147483647l /*1.0 Q31*/, MSNUMSUBFR * NPART_SHAPING );
245 :
246 3 : set32_fx( hFdCngDec->msCurrentMin, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
247 :
248 3 : set32_fx( hFdCngDec->msCurrentMinOut, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
249 :
250 3 : set32_fx( hFdCngDec->msCurrentMinSubWindow, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
251 :
252 3 : set16_fx( hFdCngDec->msLocalMinFlag, 0, NPART_SHAPING );
253 3 : set16_fx( hFdCngDec->msNewMinFlag, 0, NPART_SHAPING );
254 :
255 3 : set16_fx( hFdCngDec->msPsdFirstMoment, 0, NPART_SHAPING );
256 :
257 3 : set32_fx( hFdCngDec->msPsdSecondMoment, 0, NPART_SHAPING );
258 3 : set16_fx( hFdCngDec->msPeriodogBuf, 0, MSBUFLEN * NPART_SHAPING );
259 :
260 3 : hFdCngDec->msPeriodogBufPtr = 0;
261 3 : move16();
262 :
263 3 : set16_fx( hFdCngDec->msLogPeriodog, 0, NPART_SHAPING );
264 3 : set16_fx( hFdCngDec->msLogNoiseEst, 0, NPART_SHAPING );
265 :
266 3 : set16_fx( hFdCngDec->psize_shaping, 0, NPART_SHAPING );
267 3 : hFdCngDec->nFFTpart_shaping = 0;
268 3 : move16();
269 3 : set32_fx( hFdCngDec->msPeriodog_ST_fx, 0, NPART_SHAPING );
270 3 : hFdCngDec->msPeriodog_ST_exp = 0;
271 3 : move16();
272 3 : hFdCngDec->hFdCngCom->fftBuffer_exp = 0;
273 3 : move16();
274 3 : hFdCngDec->hFdCngCom->periodog_exp = 0;
275 3 : move16();
276 3 : set32_fx( hFdCngDec->smoothed_psd_fx, 0, L_FRAME16k );
277 3 : hFdCngDec->smoothed_psd_exp = 0;
278 3 : move16();
279 :
280 3 : return;
281 : }
282 : /*
283 : configureFdCngDec_fx
284 :
285 : Parameters:
286 :
287 : hs i/o: Contains the variables related to the FD-based CNG process
288 : numSlots i : Number of time slots in CLDFB matrix
289 : numCoreBands i : Number of core bands
290 : regularStopBand i : Number of CLDFB bands to be considered
291 : CLDFBscale i : cldfb scale factor
292 :
293 : Function:
294 : configure FD_CNG
295 :
296 : Returns:
297 : void
298 : */
299 5510 : void configureFdCngDec_fx(
300 : HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the CLDFB-based CNG process */
301 : Word16 bwidth, /*Q0*/
302 : Word32 total_brate, /*Q0*/
303 : Word16 L_frame, /*Q0*/
304 : const Word16 Last_L_frame, /*Q0*/
305 : const Word16 element_mode /*Q0*/ )
306 : {
307 : Word16 j, stopBandFR;
308 5510 : HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom;
309 :
310 :
311 5510 : hsCom->CngBandwidth = bwidth; /*Q0*/
312 5510 : move16();
313 5510 : if ( EQ_16( hsCom->CngBandwidth, FB ) )
314 : {
315 789 : hsCom->CngBandwidth = SWB;
316 789 : move16();
317 : }
318 5510 : test();
319 5510 : IF( total_brate != FRAME_NO_DATA && NE_32( total_brate, SID_2k40 ) )
320 : {
321 5510 : hsCom->CngBitrate = total_brate; /*Q0*/
322 5510 : move32();
323 : }
324 0 : ELSE IF( EQ_32( hsCom->CngBitrate, -1 ) )
325 : {
326 : /* set minimum active CBR bitrate if CngBitrate is uninitialized */
327 0 : hsCom->CngBitrate = ACELP_7k20;
328 0 : move32();
329 0 : if ( element_mode > EVS_MONO )
330 : {
331 0 : hsCom->CngBitrate = IVAS_13k2;
332 0 : move32();
333 : }
334 : }
335 :
336 : /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */
337 : /* This may need adjustment in the future if 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */
338 5510 : if ( EQ_16( element_mode, IVAS_CPE_MDCT ) )
339 : {
340 0 : hsCom->CngBitrate = IVAS_48k;
341 0 : move32();
342 : }
343 :
344 5510 : hsCom->numSlots = 16;
345 5510 : move16();
346 :
347 : /* NB configuration */
348 5510 : IF( bwidth == NB )
349 : {
350 0 : hsCom->FdCngSetup = FdCngSetup_nb;
351 0 : hsCom->numCoreBands = 16;
352 0 : move16();
353 0 : hsCom->regularStopBand = 16;
354 0 : move16();
355 : }
356 :
357 : /* WB configuration */
358 5510 : ELSE IF( EQ_16( bwidth, WB ) )
359 : {
360 : /* FFT 6.4kHz, no CLDFB */
361 1643 : test();
362 1643 : test();
363 1643 : IF( LE_32( hsCom->CngBitrate, ACELP_8k00 ) && EQ_16( L_frame, L_FRAME ) )
364 : {
365 0 : hsCom->FdCngSetup = FdCngSetup_wb1;
366 0 : hsCom->numCoreBands = 16;
367 0 : move16();
368 0 : hsCom->regularStopBand = 16;
369 0 : move16();
370 : }
371 : /* FFT 6.4kHz, CLDFB 8.0kHz */
372 1643 : ELSE IF( LE_32( hsCom->CngBitrate, ACELP_13k20 ) || EQ_16( L_frame, L_FRAME ) )
373 : {
374 699 : hsCom->FdCngSetup = FdCngSetup_wb2;
375 699 : hsCom->numCoreBands = 16;
376 699 : move16();
377 699 : hsCom->regularStopBand = 20;
378 699 : move16();
379 699 : IF(
380 : EQ_16( L_frame, L_FRAME16k ) )
381 : {
382 0 : hsCom->FdCngSetup = FdCngSetup_wb2;
383 0 : hsCom->numCoreBands = 20;
384 0 : move16();
385 0 : hsCom->regularStopBand = 20;
386 0 : move16();
387 0 : hsCom->FdCngSetup.fftlen = 640;
388 0 : move16();
389 0 : hsCom->FdCngSetup.stopFFTbin = 256;
390 0 : move16();
391 : }
392 : }
393 : /* FFT 8.0kHz, no CLDFB */
394 : ELSE
395 : {
396 944 : hsCom->FdCngSetup = FdCngSetup_wb3;
397 944 : hsCom->numCoreBands = 20;
398 944 : move16();
399 944 : hsCom->regularStopBand = 20;
400 944 : move16();
401 : }
402 : }
403 :
404 : /* SWB/FB configuration */
405 : ELSE
406 : {
407 : /* FFT 6.4kHz, CLDFB 14kHz */
408 3867 : IF(
409 : EQ_16( L_frame, L_FRAME ) )
410 : {
411 1809 : hsCom->FdCngSetup = FdCngSetup_swb1;
412 1809 : hsCom->numCoreBands = 16;
413 1809 : move16();
414 1809 : hsCom->regularStopBand = 35;
415 1809 : move16();
416 : }
417 : /* FFT 8.0kHz, CLDFB 16kHz */
418 : ELSE
419 : {
420 2058 : hsCom->FdCngSetup = FdCngSetup_swb2;
421 2058 : hsCom->numCoreBands = 20;
422 2058 : move16();
423 2058 : hsCom->regularStopBand = 40;
424 2058 : move16();
425 2058 : test();
426 2058 : if ( EQ_16( Last_L_frame, L_FRAME ) && EQ_16( element_mode, IVAS_CPE_DFT ) )
427 : {
428 3 : hsCom->regularStopBand = 35;
429 3 : move16();
430 : }
431 : }
432 : }
433 5510 : hsCom->fftlen = hsCom->FdCngSetup.fftlen; /*Q0*/
434 5510 : move16();
435 5510 : hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin; /*Q0*/
436 5510 : move16();
437 :
438 : /* Configure the SID quantizer and the Confort Noise Generator */
439 :
440 5510 : hsCom->startBand = 2;
441 5510 : move16();
442 5510 : hsCom->stopBand = add( hsCom->FdCngSetup.sidPartitions[( hsCom->FdCngSetup.numPartitions - 1 )], 1 ); /*Q0*/
443 5510 : move16();
444 5510 : initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part,
445 5510 : &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 );
446 :
447 5510 : hsCom->nFFTpart = 21;
448 5510 : move16();
449 5510 : if ( EQ_16( hsCom->stopFFTbin, 256 ) )
450 : {
451 2508 : hsCom->nFFTpart = 20;
452 2508 : move16();
453 : }
454 5510 : if ( EQ_16( hsCom->stopFFTbin, 160 ) )
455 : {
456 0 : hsCom->nFFTpart = 17;
457 0 : move16();
458 : }
459 :
460 5510 : hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart );
461 5510 : move16();
462 19619 : FOR( j = 0; j < hsCom->nCLDFBpart; j++ )
463 : {
464 14109 : hsCom->CLDFBpart[j] = sub( hsCom->part[( j + hsCom->nFFTpart )], sub( hsCom->stopFFTbin, hsCom->startBand ) ); /*Q0*/
465 14109 : move16();
466 14109 : hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[( j + hsCom->nFFTpart )]; /*Q15*/
467 14109 : move16();
468 : }
469 :
470 5510 : stopBandFR = 1000 / 25;
471 5510 : move16();
472 5510 : if ( GT_16( stopBandFR, hsCom->stopFFTbin ) )
473 : {
474 0 : stopBandFR = hsCom->stopFFTbin; /*Q0*/
475 0 : move16();
476 : }
477 5510 : initPartitions( hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions,
478 5510 : hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping,
479 5510 : hFdCngDec->psize_shaping, hFdCngDec->psize_shaping_norm, &hFdCngDec->psize_shaping_norm_exp, hFdCngDec->psize_inv_shaping,
480 : stopBandFR );
481 5510 : hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; /*Q0*/
482 5510 : move16();
483 :
484 5510 : SWITCH( hsCom->fftlen )
485 : {
486 2508 : case 512:
487 2508 : hsCom->fftlenShift = 8;
488 2508 : move16();
489 2508 : hsCom->fftlenFac = 32767 /*1.0 Q15*/;
490 2508 : move16();
491 2508 : BREAK;
492 3002 : case 640:
493 3002 : hsCom->fftlenShift = 9;
494 3002 : move16();
495 3002 : hsCom->fftlenFac = 20480 /*0.625 Q15*/;
496 3002 : move16();
497 3002 : BREAK;
498 0 : default:
499 0 : assert( !"Unsupported FFT length for FD-based CNG" );
500 : BREAK;
501 : }
502 5510 : BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) );
503 5510 : BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) );
504 5510 : hsCom->frameSize = shr( hsCom->fftlen, 1 );
505 5510 : move16();
506 5510 : }
507 :
508 :
509 : /*
510 : deleteFdCngDec_fx
511 :
512 : Parameters:
513 :
514 : hFdCngDec i/0 : pointer to cng decoder structure
515 :
516 : Function:
517 : delete the instance of type FD_CNG
518 :
519 : Returns:
520 : void
521 : */
522 184364 : void deleteFdCngDec_fx( HANDLE_FD_CNG_DEC *hFdCngDec )
523 : {
524 184364 : HANDLE_FD_CNG_DEC hsDec = *hFdCngDec;
525 :
526 184364 : IF( hsDec != NULL )
527 : {
528 7135 : deleteFdCngCom_fx( &( hsDec->hFdCngCom ) );
529 7135 : free( hsDec );
530 7135 : *hFdCngDec = NULL;
531 : }
532 184364 : }
533 :
534 :
535 : /*
536 : ApplyFdCng_fx
537 :
538 : Parameters:
539 :
540 : timeDomainInput, i : pointer to time domain input
541 : cldfbBufferReal i/o: real part of the CLDFB buffer
542 : cldfbBufferImag i/o: imaginary part of the CLDFB buffer
543 : cldfbBufferScale o : pointer to the scalefactor for real and imaginary part of the CLDFB buffer
544 : st i/o: pointer to FD_CNG structure containing all buffers and variables
545 : m_frame_type i : type of frame at the decoder side
546 : stcod i : pointer to Coder_State structure
547 : st i : pointer to Decoder_State structure
548 : bitrate i : bitrate
549 : concealWholeFrame i : binary flag indicating frame loss
550 :
551 : Function:
552 : apply the CLDFB-based CNG at the decoder
553 :
554 : Returns:
555 : error
556 : */
557 :
558 267270 : Word16 ApplyFdCng_fx(
559 : Word16 *timeDomainInput, /* i : pointer to time domain input Q*/
560 : Word16 Q,
561 : Word32 *powerSpectrum, /*Q_power_spectrum*/
562 : Word16 Q_power_spectrum,
563 : Word32 **cldfbBufferReal, /* i/o: real part of the CLDFB buffer cldfbBufferScale*/
564 : Word32 **cldfbBufferImag, /* i/o: imaginary part of the CLDFB buffer cldfbBufferScale*/
565 : Word16 *cldfbBufferScale, /* o : pointer to the scalefactor for real and imaginary part of the CLDFB buffer */
566 : Decoder_State *st,
567 : const Word16 concealWholeFrame, /* i : binary flag indicating frame loss Q0*/
568 : Word16 is_music /*Q0*/ )
569 : {
570 : Word16 j, k, nBins;
571 : Word16 s, s1, s2, num, denom;
572 : Word32 *cngNoiseLevel;
573 : Word16 *cngNoiseLevel_exp;
574 : Word32 L_tmp;
575 : Word16 L_tmp_exp;
576 : Word16 facTab[NPART];
577 : Word16 facTabExp[NPART];
578 : Word16 tmp_loop;
579 : #ifndef FIX_ISSUE_1817_REPLACE_CARRY_OVERFLOW
580 : Word32 L_c;
581 : #endif
582 : Word16 lsp_cng[M];
583 : HANDLE_FD_CNG_DEC hFdCngDec;
584 : HANDLE_FD_CNG_COM hFdCngCom;
585 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
586 : #if !defined( ISSUE_1866_replace_overflow_libdec ) && !defined( FIX_ISSUE_1817_REPLACE_CARRY_OVERFLOW )
587 : Flag Overflow = 0;
588 : #endif
589 : #ifndef FIX_ISSUE_1817_REPLACE_CARRY_OVERFLOW
590 : Flag Carry = 0;
591 : #endif
592 267270 : move16();
593 267270 : move16();
594 : #endif
595 : Word16 L_frame, last_L_frame;
596 :
597 267270 : hFdCngDec = st->hFdCngDec;
598 267270 : hFdCngCom = hFdCngDec->hFdCngCom;
599 :
600 267270 : Word32 *sidNoiseEst = hFdCngCom->sidNoiseEst; /*Q31 - hFdCngCom->sidNoiseEstExp*/
601 :
602 : /* limit L_frame and core fs values for MDCT-Stereo modes which can have higher core sampling than 16kHz, but use a downsampled buffer */
603 267270 : L_frame = s_min( st->L_frame, L_FRAME16k );
604 267270 : last_L_frame = s_min( st->last_L_frame, L_FRAME16k );
605 :
606 267270 : if ( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) )
607 : {
608 247352 : hFdCngCom->inactive_frame_counter = 0;
609 247352 : move16();
610 : }
611 267270 : IF( EQ_16( st->element_mode, IVAS_CPE_TD ) )
612 : {
613 3686 : hFdCngDec->flag_dtx_mode = hFdCngDec->flag_dtx_mode || st->first_CNG;
614 3686 : move16();
615 : }
616 267270 : cngNoiseLevel = hFdCngCom->cngNoiseLevel;
617 267270 : move32();
618 267270 : cngNoiseLevel_exp = &hFdCngCom->cngNoiseLevelExp;
619 267270 : move16();
620 267270 : nBins = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
621 :
622 267270 : SWITCH( st->m_frame_type )
623 : {
624 248599 : case ACTIVE_FRAME:
625 :
626 : /**************************
627 : * ACTIVE_FRAME at DECODER *
628 : **************************/
629 :
630 248599 : hFdCngCom->inactive_frame_counter = 0;
631 248599 : move16();
632 248599 : hFdCngCom->sid_frame_counter = 0;
633 248599 : move16();
634 :
635 : /* set noise estimation inactive during concealment, as no update with noise generated by concealment should be performed. */
636 : /* set noise estimation inactive during concealment, no update with noise generated by concealment should be performed. */
637 :
638 248599 : test();
639 248599 : test();
640 248599 : test();
641 248599 : test();
642 248599 : test();
643 248599 : test();
644 248599 : test();
645 248599 : test();
646 248599 : test();
647 248599 : test();
648 248599 : test();
649 248599 : test();
650 248599 : test();
651 248599 : test();
652 248599 : test();
653 248599 : test();
654 248599 : test();
655 248599 : IF( EQ_16( concealWholeFrame, 0 ) &&
656 : ( timeDomainInput == NULL ||
657 : ( LT_16( *timeDomainInput, MAXVAL_WORD16 ) && GT_16( *timeDomainInput, MINVAL_WORD16 ) &&
658 : LT_16( *( timeDomainInput + sub( hFdCngCom->frameSize, 1 ) ), MAXVAL_WORD16 ) &&
659 : GT_16( *( timeDomainInput + sub( hFdCngCom->frameSize, 1 ) ), MINVAL_WORD16 ) ) ) &&
660 : ( ( ( ( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) && hFdCngDec->flag_dtx_mode ) || !st->VAD || ( LT_16( st->ini_frame, 100 ) && st->is_ism_format ) ) &&
661 : !( st->cng_type == LP_CNG && hFdCngDec->flag_dtx_mode ) && ( is_music == 0 ) ) ||
662 : EQ_16( st->element_mode, IVAS_CPE_TD ) ) &&
663 : ( !st->BER_detect ) )
664 : {
665 : /* Perform noise estimation at the decoder */
666 50767 : IF( EQ_16( st->element_mode, EVS_MONO ) )
667 : {
668 15 : perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec );
669 : }
670 : ELSE
671 : {
672 50752 : perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD );
673 : }
674 :
675 : /* Update the shaping parameters */
676 50767 : test();
677 50767 : IF( EQ_16( st->element_mode, EVS_MONO ) )
678 : {
679 15 : scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 );
680 : }
681 50752 : ELSE IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) )
682 : {
683 44303 : scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, nBins, hFdCngDec->bandNoiseShape, 1 );
684 : }
685 50767 : hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp;
686 50767 : move16();
687 :
688 :
689 : /* Update CNG levels */
690 50767 : test();
691 50767 : IF( hFdCngDec->flag_dtx_mode != 0 && EQ_16( st->cng_type, FD_CNG ) )
692 : {
693 : /* This needs to be done only once per inactive phase */
694 3337 : bandcombinepow(
695 3337 : hFdCngDec->bandNoiseShape,
696 3337 : hFdCngDec->bandNoiseShape_exp,
697 : nBins,
698 3337 : hFdCngCom->part,
699 3337 : hFdCngCom->nFFTpart,
700 3337 : hFdCngCom->psize_inv,
701 3337 : hFdCngDec->partNoiseShape,
702 : &hFdCngDec->partNoiseShape_exp );
703 :
704 :
705 3337 : j = 0;
706 3337 : move16();
707 : // s2 = -( WORD32_BITS - 1 );
708 3337 : s2 = -( WORD32_BITS - 1 );
709 3337 : move16();
710 71616 : FOR( k = 0; k < hFdCngCom->nFFTpart; k++ )
711 : {
712 68279 : assert( hFdCngDec->partNoiseShape[k] >= 0 );
713 68279 : assert( hFdCngCom->sidNoiseEst[k] >= 0 );
714 :
715 : /* add DELTA as it is done in FLC version, in order to avoid num > denom */
716 68279 : facTab[k] = 0;
717 68279 : move16();
718 68279 : IF( hFdCngDec->partNoiseShape[k] != 0 )
719 : {
720 68279 : s1 = norm_l( hFdCngCom->sidNoiseEst[k] );
721 68279 : L_tmp = L_shl( hFdCngCom->sidNoiseEst[k], s1 ); /*Q31 - hFdCngCom->sidNoiseEstExp + s1*/
722 68279 : L_tmp_exp = sub( hFdCngCom->sidNoiseEstExp, s1 );
723 68279 : L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
724 68279 : L_tmp = L_shr( L_tmp, 1 );
725 68279 : s = add( L_tmp_exp, 1 );
726 68279 : num = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
727 :
728 68279 : s1 = norm_l( hFdCngDec->partNoiseShape[k] );
729 68279 : L_tmp = L_shl( hFdCngDec->partNoiseShape[k], s1 ); /*Q31 - hFdCngDec->partNoiseShape_exp + s1*/
730 68279 : L_tmp_exp = sub( hFdCngDec->partNoiseShape_exp, s1 );
731 68279 : L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
732 68279 : s = sub( s, L_tmp_exp );
733 68279 : denom = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
734 :
735 68279 : facTab[k] = div_s( num, denom ); /*Q15 - s*/
736 68279 : move16();
737 68279 : facTabExp[k] = s;
738 68279 : move16();
739 : }
740 : /* Set unique exponent, if mantissa is equal to zero */
741 68279 : IF( EQ_16( facTab[k], 0 ) )
742 : {
743 0 : facTabExp[k] = -( ( WORD32_BITS - 1 ) );
744 0 : move16();
745 : }
746 68279 : s2 = s_max( s2, facTabExp[k] );
747 : }
748 :
749 71616 : FOR( k = 0; k < hFdCngCom->nFFTpart; k++ )
750 : {
751 68279 : s = sub( facTabExp[k], s2 );
752 68279 : s = s_max( s_min( s, ( WORD32_BITS - 1 ) ), -( ( WORD32_BITS - 1 ) ) );
753 1014373 : FOR( ; j <= hFdCngCom->part[k]; j++ )
754 : {
755 946094 : cngNoiseLevel[j] = L_shl( Mpy_32_16_1( hFdCngDec->bandNoiseShape[j], facTab[k] ), s ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/
756 946094 : move32();
757 : }
758 : }
759 :
760 : /* adapt scaling for rest of the buffer */
761 3337 : IF( NE_16( s2, -( WORD32_BITS - 1 ) ) )
762 : {
763 2462 : s = sub( *cngNoiseLevel_exp, add( hFdCngDec->bandNoiseShape_exp, s2 ) );
764 2462 : Word16 e_shift = 0;
765 2462 : move16();
766 2462 : IF( s > 0 )
767 : {
768 45 : Word16 q_norm = L_norm_arr( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ) );
769 45 : IF( GT_16( s, q_norm ) )
770 : {
771 0 : scale_sig32( cngNoiseLevel, j, sub( q_norm, s ) ); /*q_norm*/
772 0 : e_shift = sub( s, q_norm );
773 : }
774 : }
775 144498 : FOR( ; j < FFTCLDFBLEN; j++ )
776 : {
777 142036 : cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], sub( s, e_shift ) ); /*Q: s*/
778 142036 : move32();
779 : }
780 :
781 2462 : *cngNoiseLevel_exp = add( add( hFdCngDec->bandNoiseShape_exp, s2 ), e_shift );
782 2462 : move16();
783 : }
784 : }
785 : ELSE
786 : {
787 : /* This sets the new CNG levels until a SID update overwrites it */
788 47430 : test();
789 47430 : test();
790 47430 : test();
791 47430 : IF( !( EQ_16( st->element_mode, IVAS_CPE_TD ) ) || ( EQ_16( st->element_mode, IVAS_CPE_TD ) && !hFdCngDec->flag_dtx_mode && !st->VAD ) )
792 : {
793 45360 : Copy32( hFdCngDec->bandNoiseShape, cngNoiseLevel, nBins ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/
794 45360 : *cngNoiseLevel_exp = hFdCngDec->bandNoiseShape_exp;
795 45360 : move16();
796 : }
797 : }
798 :
799 50767 : IF( ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && timeDomainInput == NULL ) )
800 : {
801 :
802 6072 : tmp_loop = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
803 : #ifndef FIX_ISSUE_1817_REPLACE_CARRY_OVERFLOW
804 : L_tmp = L_deposit_h( 0 );
805 : L_c = L_deposit_h( 0 );
806 : FOR( j = 0; j < tmp_loop; j++ )
807 : {
808 :
809 : Carry = 0;
810 : move16();
811 : L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31*/
812 : Overflow = 0;
813 : move16();
814 :
815 : IF( *( cngNoiseLevel + j ) < 0 )
816 : {
817 : L_c = L_msuNs( L_c, 0, 0 ); /*Q-1*/
818 : }
819 : IF( *( cngNoiseLevel + j ) >= 0 )
820 : {
821 : L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/
822 : }
823 : }
824 : L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/
825 : L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 );
826 :
827 : L_tmp = Mpy_32_16_1( L_tmp, 1 ); /*Q16 - L_tmp_exp*/
828 :
829 : L_tmp = Mpy_32_16_1( L_tmp, shr( T_DIV_L_Frame[L_shl( L_mac( -28000, NORM_MDCT_FACTOR, 95 ), 1 - 15 )], 1 ) ); /*Q16,exp -7*/
830 : L_tmp_exp = add( L_tmp_exp, -7 ); /*->Q16, L_tmp_exp */
831 : L_tmp_exp = add( L_tmp_exp, 31 - 16 ); /*->Q31, L_tmp_exp*/
832 :
833 : st->hTcxDec->conCngLevelBackgroundTrace = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/
834 : move16();
835 : L_tmp_exp = add( L_tmp_exp, 1 );
836 : #else
837 6072 : L_tmp = sum_array_norm( cngNoiseLevel, tmp_loop, &L_tmp_exp ); /*Q31 - L_tmp_exp*/
838 6072 : L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 );
839 :
840 6072 : L_tmp = L_shr( L_tmp, 15 ); /*Q16 - L_tmp_exp*/
841 :
842 6072 : L_tmp = Mpy_32_16_1( L_tmp, shr( T_DIV_L_Frame[L_shl( L_mac( -28000, NORM_MDCT_FACTOR, 95 ), 1 - 15 )], 1 ) ); /*Q16,exp -7*/
843 6072 : L_tmp_exp = add( L_tmp_exp, -7 + ( 31 - 16 ) ); /*->Q31, L_tmp_exp*/
844 :
845 6072 : st->hTcxDec->conCngLevelBackgroundTrace = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/
846 6072 : move16();
847 6072 : L_tmp_exp = add( L_tmp_exp, 1 );
848 : #endif
849 6072 : st->hTcxDec->conCngLevelBackgroundTrace_e = L_tmp_exp;
850 6072 : move16();
851 : }
852 : ELSE
853 : {
854 :
855 44695 : tmp_loop = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
856 : #ifndef FIX_ISSUE_1817_REPLACE_CARRY_OVERFLOW
857 : L_tmp = L_deposit_h( 0 );
858 : L_c = L_deposit_h( 0 );
859 : FOR( j = 0; j < tmp_loop; j++ )
860 : {
861 :
862 : Carry = 0;
863 : move16();
864 : L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31 - L_tmp_exp*/
865 : Overflow = 0;
866 : move16();
867 :
868 : IF( *( cngNoiseLevel + j ) < 0 )
869 : {
870 : L_c = L_msuNs( L_c, 0, 0 ); /*Q-1*/
871 : }
872 : IF( *( cngNoiseLevel + j ) >= 0 )
873 : {
874 : L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/
875 : }
876 : }
877 : L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/
878 : L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 );
879 :
880 : L_tmp = Mpy_32_16_1( L_tmp, hFdCngCom->fftlen ); /*Q16 - L_tmp_exp*/
881 :
882 : L_tmp = Mpy_32_16_1( L_tmp, T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )] ); /*Q16,exp -7*/
883 : L_tmp_exp = add( L_tmp_exp, -7 ); /*->Q16, L_tmp_exp */
884 : L_tmp_exp = add( L_tmp_exp, 31 - 16 ); /*->Q31, L_tmp_exp*/
885 :
886 : st->hTcxDec->conCngLevelBackgroundTrace = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/
887 : #else
888 44695 : L_tmp = sum_array_norm( cngNoiseLevel, tmp_loop, &L_tmp_exp );
889 44695 : L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 );
890 :
891 44695 : L_tmp = Mpy_32_16_1( L_tmp, hFdCngCom->fftlen ); /*Q16 - L_tmp_exp*/
892 :
893 44695 : L_tmp = Mpy_32_16_1( L_tmp, T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )] ); /*Q16,exp -7*/
894 44695 : L_tmp_exp = add( L_tmp_exp, -7 + ( 31 - 16 ) ); /*->Q31, L_tmp_exp*/
895 :
896 :
897 44695 : st->hTcxDec->conCngLevelBackgroundTrace = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/
898 : #endif
899 44695 : move16();
900 44695 : st->hTcxDec->conCngLevelBackgroundTrace_e = L_tmp_exp;
901 44695 : move16();
902 : }
903 :
904 50767 : tmp_loop = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
905 : #ifndef FIX_ISSUE_1817_REPLACE_CARRY_OVERFLOW
906 : L_tmp = L_deposit_h( 0 );
907 : L_c = L_deposit_h( 0 );
908 : FOR( j = 0; j < tmp_loop; j++ )
909 : {
910 :
911 : Carry = 0;
912 : move16();
913 : L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31 - L_tmp_exp*/
914 : Overflow = 0;
915 : move16();
916 :
917 : IF( *( cngNoiseLevel + j ) < 0 )
918 : {
919 : L_c = L_msuNs( L_c, 0, 0 ); /*Q-1*/
920 : }
921 : IF( *( cngNoiseLevel + j ) >= 0 )
922 : {
923 : L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/
924 : }
925 : }
926 : L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/
927 : L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 );
928 :
929 : L_tmp = Mpy_32_16_1( L_tmp, hFdCngCom->fftlen ); /*Q16 - L_tmp_exp*/
930 :
931 : L_tmp = Mpy_32_16_1( L_tmp, T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )] ); /*Q16,exp -7*/
932 : L_tmp_exp = add( L_tmp_exp, -7 ); /*->Q16, L_tmp_exp */
933 : L_tmp_exp = add( L_tmp_exp, 31 - 16 ); /*->Q31, L_tmp_exp*/
934 :
935 : st->cngTDLevel = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/
936 : move16();
937 : #else
938 50767 : L_tmp = sum_array_norm( cngNoiseLevel, tmp_loop, &L_tmp_exp ); /*Q31 - L_tmp_exp*/
939 50767 : L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 );
940 :
941 50767 : L_tmp = Mpy_32_16_1( L_tmp, hFdCngCom->fftlen ); /*Q16 - L_tmp_exp*/
942 :
943 50767 : L_tmp = Mpy_32_16_1( L_tmp, T_DIV_L_Frame[L_shr( L_mac( -28000, st->L_frame, 95 ), 15 - 1 )] ); /*Q16,exp -7*/
944 50767 : L_tmp_exp = add( L_tmp_exp, -7 + ( 31 - 16 ) ); /*->Q31, L_tmp_exp */
945 :
946 50767 : st->cngTDLevel = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/
947 50767 : move16();
948 :
949 : #endif
950 50767 : st->cngTDLevel_e = L_tmp_exp;
951 50767 : move16();
952 : }
953 197832 : ELSE IF( EQ_16( st->element_mode, IVAS_CPE_TD ) || EQ_16( st->element_mode, IVAS_CPE_DFT ) )
954 : {
955 45229 : IF( hFdCngCom->active_frame_counter > 0 )
956 : {
957 : /* Perform noise estimation in active frames in the decoder for downward updates */
958 44832 : IF( EQ_16( st->element_mode, EVS_MONO ) )
959 : {
960 0 : perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec );
961 : }
962 : ELSE
963 : {
964 44832 : perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD );
965 : }
966 : }
967 : }
968 :
969 248599 : test();
970 248599 : IF( EQ_16( concealWholeFrame, 1 ) && EQ_16( st->nbLostCmpt, 1 ) )
971 : {
972 : /* always set psychParameters for MDCT-Stereo ... */
973 3160 : test();
974 3160 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && st->hTonalMDCTConc != NULL )
975 : {
976 2006 : st->hTonalMDCTConc->psychParams = EQ_16( st->core, TCX_20_CORE ) ? &st->hTonalMDCTConc->psychParamsTCX20 : &st->hTonalMDCTConc->psychParamsTCX10;
977 : }
978 : /* update isf cng estimate for concealment. Do that during concealment, in order to avoid addition clean channel complexity*/
979 :
980 3160 : L_tmp = 0;
981 3160 : move32();
982 982056 : FOR( j = hFdCngCom->startBand; j < hFdCngCom->stopFFTbin; j++ )
983 : {
984 978896 : L_tmp = L_add_sat( L_tmp, L_shl_sat( cngNoiseLevel[j], sub( 31, *cngNoiseLevel_exp ) ) ); /*Q31*/
985 : }
986 3160 : L_tmp_exp = 0;
987 3160 : move16();
988 : #ifdef ISSUE_1866_replace_overflow_libdec
989 3160 : IF( GT_32( L_tmp, 21474836 ) /*0.01f Q31*/ )
990 : #else
991 : IF( GT_32( L_shl_o( L_tmp, L_tmp_exp, &Overflow ), 21474836 ) /*0.01f Q31*/ )
992 : #endif
993 : {
994 1039 : test();
995 1039 : test();
996 1039 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && NE_16( st->core, ACELP_CORE ) )
997 : {
998 304 : TonalMdctConceal_whiten_noise_shape_ivas_fx( st, L_frame, ON_FIRST_LOST_FRAME );
999 : }
1000 735 : ELSE IF( NE_16( st->element_mode, IVAS_CPE_MDCT ) || EQ_16( st->core, ACELP_CORE ) )
1001 : {
1002 735 : lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, 0 );
1003 735 : E_LPC_a_lsp_conversion( hFdCngCom->A_cng, lsp_cng, st->lspold_cng, M );
1004 735 : Copy( lsp_cng, st->lspold_cng, M ); /*Q15*/
1005 :
1006 735 : lsp2lsf_fx( lsp_cng, st->lsf_cng, M, st->sr_core ); /*x2.56*/
1007 : }
1008 :
1009 1039 : st->plcBackgroundNoiseUpdated = 1;
1010 1039 : move16();
1011 : }
1012 : }
1013 248599 : BREAK;
1014 :
1015 2573 : case SID_FRAME:
1016 :
1017 2573 : hFdCngDec->flag_dtx_mode = 1;
1018 2573 : move16();
1019 : /* no break */
1020 :
1021 18671 : case ZERO_FRAME:
1022 :
1023 18671 : test();
1024 18671 : IF( st != NULL && EQ_16( st->cng_type, LP_CNG ) )
1025 : {
1026 : /* Perform noise estimation on inactive phase at the decoder */
1027 1141 : IF( EQ_16( st->element_mode, EVS_MONO ) )
1028 : {
1029 0 : perform_noise_estimation_dec_fx( timeDomainInput, Q, hFdCngDec );
1030 : }
1031 : ELSE
1032 : {
1033 1141 : perform_noise_estimation_dec_ivas_fx( timeDomainInput, Q, powerSpectrum, Q_power_spectrum, hFdCngDec, st->element_mode, st->bwidth, L_frame, last_L_frame, st->last_core_brate, st->VAD );
1034 : }
1035 :
1036 : /* Update the shaping parameters */
1037 1141 : test();
1038 1141 : IF( EQ_16( st->element_mode, EVS_MONO ) )
1039 : {
1040 0 : scalebands( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 );
1041 : }
1042 1141 : ELSE IF( NE_16( st->element_mode, IVAS_CPE_TD ) && NE_16( st->element_mode, IVAS_CPE_DFT ) )
1043 : {
1044 0 : scalebands_fx( hFdCngDec->msNoiseEst, hFdCngDec->part_shaping, hFdCngDec->nFFTpart_shaping, hFdCngDec->midband_shaping, hFdCngDec->nFFTpart_shaping, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), hFdCngDec->bandNoiseShape, 1 );
1045 : }
1046 1141 : hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp;
1047 1141 : move16();
1048 :
1049 : /* This sets the new CNG levels until a SID update overwrites it */
1050 1141 : Copy32( hFdCngDec->bandNoiseShape, cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ); /* This sets the new CNG levels until a SID update overwrites it */ /*Q31 - hFdCngDec->bandNoiseShape_exp*/
1051 :
1052 1141 : IF( EQ_16( st->element_mode, EVS_MONO ) )
1053 : {
1054 0 : *cngNoiseLevel_exp = hFdCngDec->bandNoiseShape_exp;
1055 0 : move16();
1056 : }
1057 : ELSE
1058 : {
1059 1141 : Word16 shift1 = L_norm_arr( cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) );
1060 1141 : Word16 shift2 = L_norm_arr( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ) );
1061 1141 : Word16 shift = s_max( sub( hFdCngDec->bandNoiseShape_exp, shift1 ), sub( *cngNoiseLevel_exp, shift2 ) );
1062 :
1063 1141 : scale_sig32( cngNoiseLevel, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( hFdCngDec->bandNoiseShape_exp, shift ) );
1064 1141 : scale_sig32( cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ) ), sub( *cngNoiseLevel_exp, shift ) );
1065 :
1066 1141 : *cngNoiseLevel_exp = shift;
1067 1141 : move16();
1068 : }
1069 :
1070 : /*st->cngTDLevel = (float)sqrt( (sumFLOAT(cngNoiseLevel, hFdCngCom->stopFFTbin - hFdCngCom->startBand) / 2 * hFdCngCom->fftlen) / st->Mode2_L_frame);*/
1071 1141 : tmp_loop = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
1072 : #ifndef FIX_ISSUE_1817_REPLACE_CARRY_OVERFLOW
1073 : L_tmp = L_deposit_h( 0 );
1074 : L_c = L_deposit_h( 0 );
1075 : FOR( j = 0; j < tmp_loop; j++ )
1076 : {
1077 :
1078 : Carry = 0;
1079 : move16();
1080 : L_tmp = L_add_co( L_tmp, *( cngNoiseLevel + j ), &Carry, &Overflow ); /*Q31 - L_tmp_exp*/
1081 : Overflow = 0;
1082 : move16();
1083 :
1084 : IF( *( cngNoiseLevel + j ) < 0 )
1085 : {
1086 : L_c = L_msuNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/
1087 : }
1088 : IF( *( cngNoiseLevel + j ) >= 0 )
1089 : {
1090 : L_c = L_macNs_co( L_c, 0, 0, &Carry, &Overflow ); /*Q-1*/
1091 : }
1092 : }
1093 : L_tmp = norm_llQ31( L_c, L_tmp, &L_tmp_exp ); /*Q31 - L_tmp_exp*/
1094 : L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 );
1095 :
1096 : L_tmp = Mpy_32_16_1( L_tmp, hFdCngCom->fftlen ); /*Q16 - L_tmp_exp*/
1097 :
1098 : L_tmp = Mpy_32_16_1( L_tmp, T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )] ); /*Q16,exp -7*/
1099 : L_tmp_exp = add( L_tmp_exp, -7 ); /*->Q16, L_tmp_exp */
1100 : L_tmp_exp = add( L_tmp_exp, 31 - 16 ); /*->Q31, L_tmp_exp*/
1101 :
1102 : #ifdef ISSUE_1866_replace_overflow_libdec
1103 : st->cngTDLevel = round_fx_sat( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/
1104 : #else
1105 : st->cngTDLevel = round_fx_o( Sqrt32( L_tmp, &L_tmp_exp ), &Overflow ); /*Q15 - L_tmp_exp*/
1106 : #endif
1107 : move16();
1108 : #else
1109 1141 : L_tmp = sum_array_norm( cngNoiseLevel, tmp_loop, &L_tmp_exp ); /*Q31 - L_tmp_exp*/
1110 1141 : L_tmp_exp = sub( add( L_tmp_exp, *cngNoiseLevel_exp ), 1 );
1111 :
1112 1141 : L_tmp = Mpy_32_16_1( L_tmp, hFdCngCom->fftlen ); /*Q16 - L_tmp_exp*/
1113 :
1114 1141 : L_tmp = Mpy_32_16_1( L_tmp, T_DIV_L_Frame[L_shl( L_mac( -28000, st->L_frame, 95 ), 1 - 15 )] ); /*Q16,exp -7*/
1115 1141 : L_tmp_exp = add( L_tmp_exp, -7 + ( 31 - 16 ) ); /*->Q31, L_tmp_exp*/
1116 :
1117 1141 : st->cngTDLevel = round_fx( Sqrt32( L_tmp, &L_tmp_exp ) ); /*Q15 - L_tmp_exp*/
1118 1141 : move16();
1119 : #endif
1120 1141 : st->cngTDLevel_e = L_tmp_exp;
1121 1141 : move16();
1122 1141 : BREAK;
1123 : }
1124 17530 : hFdCngCom->inactive_frame_counter = add( hFdCngCom->inactive_frame_counter, 1 );
1125 17530 : move16();
1126 :
1127 : /*************************************
1128 : * SID_FRAME or ZERO_FRAME at DECODER *
1129 : *************************************/
1130 :
1131 : /* Detect first non-active frame */
1132 17530 : IF( EQ_16( hFdCngCom->inactive_frame_counter, 1 ) )
1133 : {
1134 : /* Compute the fine spectral structure of the comfort noise shape using the decoder-side noise estimates */
1135 451 : bandcombinepow(
1136 451 : hFdCngDec->bandNoiseShape,
1137 451 : hFdCngDec->bandNoiseShape_exp,
1138 : nBins,
1139 451 : hFdCngCom->part,
1140 451 : hFdCngCom->nFFTpart,
1141 451 : hFdCngCom->psize_inv,
1142 451 : hFdCngDec->partNoiseShape,
1143 : &hFdCngDec->partNoiseShape_exp );
1144 451 : IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) )
1145 : {
1146 384 : Copy32( hFdCngDec->hFdCngCom->sidNoiseEst, hFdCngDec->hFdCngCom->sidNoiseEstLp, NPART ); /*Q31 - hFdCngDec->sidNoiseEstExp*/
1147 : }
1148 : }
1149 :
1150 17530 : IF( EQ_16( st->m_frame_type, SID_FRAME ) )
1151 : {
1152 2371 : IF( LT_32( hFdCngCom->msFrCnt_init_counter, L_deposit_l( hFdCngCom->msFrCnt_init_thresh ) ) )
1153 : {
1154 : /* At initialization, interpolate the bin/band-wise levels from the partition levels */
1155 54 : IF( EQ_16( st->element_mode, EVS_MONO ) )
1156 : {
1157 0 : scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 );
1158 : }
1159 : ELSE
1160 : {
1161 54 : scalebands_fx( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 1 );
1162 : }
1163 :
1164 54 : *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp;
1165 54 : move16();
1166 : }
1167 : ELSE
1168 : {
1169 2317 : if ( EQ_16( st->element_mode, IVAS_CPE_DFT ) )
1170 : {
1171 2083 : sidNoiseEst = hFdCngCom->sidNoiseEstLp; /*Q31 - hFdCngDec->sidNoiseEstExp*/
1172 : }
1173 : /* Interpolate the CLDFB band levels from the SID (partition) levels */
1174 2317 : IF( GT_16( hFdCngCom->regularStopBand, hFdCngCom->numCoreBands ) )
1175 : {
1176 1995 : IF( EQ_16( st->element_mode, EVS_MONO ) )
1177 : {
1178 0 : scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 );
1179 : }
1180 : ELSE
1181 : {
1182 1995 : scalebands_fx( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), cngNoiseLevel, 0 );
1183 : }
1184 :
1185 1995 : *cngNoiseLevel_exp = hFdCngCom->sidNoiseEstExp;
1186 1995 : move16();
1187 : }
1188 :
1189 2317 : s2 = -( ( WORD32_BITS - 1 ) );
1190 2317 : move16();
1191 : /* Shape the SID noise levels in each FFT bin */
1192 2317 : j = 0;
1193 2317 : move16();
1194 50095 : FOR( k = 0; k < hFdCngCom->nFFTpart; k++ )
1195 : {
1196 47778 : assert( hFdCngDec->partNoiseShape[k] >= 0 );
1197 :
1198 : /* add DELTA as it is done in FLC version, in order to avoid num > denom */
1199 47778 : facTab[k] = 0;
1200 47778 : move16();
1201 47778 : IF( hFdCngDec->partNoiseShape[k] != 0 )
1202 : {
1203 47778 : s1 = norm_l( sidNoiseEst[k] );
1204 47778 : L_tmp = L_shl( sidNoiseEst[k], s1 ); /*Q31 - ( hFdCngCom->sidNoiseEstExp - s1 )*/
1205 47778 : L_tmp_exp = sub( hFdCngCom->sidNoiseEstExp, s1 );
1206 47778 : L_tmp = BASOP_Util_Add_Mant32Exp( sidNoiseEst[k], hFdCngCom->sidNoiseEstExp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
1207 47778 : L_tmp = L_shr( L_tmp, 1 );
1208 47778 : s = add( L_tmp_exp, 1 );
1209 47778 : num = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
1210 :
1211 47778 : s1 = norm_l( hFdCngDec->partNoiseShape[k] );
1212 47778 : L_tmp = L_shl( hFdCngDec->partNoiseShape[k], s1 ); /*Q31 - ( hFdCngDec->partNoiseShape_ex - s1 )*/
1213 47778 : L_tmp_exp = sub( hFdCngDec->partNoiseShape_exp, s1 );
1214 47778 : L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
1215 47778 : s = sub( s, L_tmp_exp );
1216 47778 : denom = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
1217 :
1218 47778 : facTab[k] = div_s( num, denom ); /*Q15 - s*/
1219 47778 : move16();
1220 47778 : facTabExp[k] = s;
1221 47778 : move16();
1222 : }
1223 : /* Set unique exponent, IF mantissa is equal to zero */
1224 47778 : IF( EQ_16( facTab[k], 0 ) )
1225 : {
1226 278 : facTabExp[k] = -( ( WORD32_BITS - 1 ) );
1227 278 : move16();
1228 : }
1229 47778 : s2 = s_max( s2, facTabExp[k] );
1230 : }
1231 2317 : if ( EQ_16( s2, -31 ) )
1232 : {
1233 306 : s2 = 0;
1234 306 : move16();
1235 : }
1236 50095 : FOR( k = 0; k < hFdCngCom->nFFTpart; k++ )
1237 : {
1238 47778 : s = sub( facTabExp[k], s2 );
1239 47778 : s = s_max( s_min( s, ( WORD32_BITS - 1 ) ), -( ( WORD32_BITS - 1 ) ) );
1240 728328 : FOR( ; j <= hFdCngCom->part[k]; j++ )
1241 : {
1242 680550 : cngNoiseLevel[j] = L_shl( Mpy_32_16_1( hFdCngDec->bandNoiseShape[j], facTab[k] ), s ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/
1243 680550 : move32();
1244 : }
1245 : }
1246 :
1247 2317 : IF( EQ_16( st->element_mode, EVS_MONO ) )
1248 : {
1249 : /* adapt scaling for rest of the buffer */
1250 0 : s = sub( *cngNoiseLevel_exp, add( hFdCngDec->bandNoiseShape_exp, s2 ) );
1251 0 : FOR( ; k < hFdCngCom->npart; k++ )
1252 : {
1253 0 : FOR( ; j <= hFdCngCom->part[k]; j++ )
1254 : {
1255 0 : cngNoiseLevel[j] = L_shl( cngNoiseLevel[j], s ); /*Q31 - hFdCngDec->bandNoiseShape_exp + s*/
1256 0 : move32();
1257 : }
1258 : }
1259 0 : *cngNoiseLevel_exp = add( hFdCngDec->bandNoiseShape_exp, s2 );
1260 0 : move16();
1261 : }
1262 : ELSE
1263 : {
1264 2317 : Word16 shift1 = L_norm_arr( cngNoiseLevel, j );
1265 2317 : Word16 shift2 = L_norm_arr( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ) );
1266 2317 : Word16 shift = s_max( sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift1 ), sub( *cngNoiseLevel_exp, shift2 ) );
1267 :
1268 2317 : scale_sig32( cngNoiseLevel, j, sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift ) );
1269 2317 : scale_sig32( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ), sub( *cngNoiseLevel_exp, shift ) );
1270 :
1271 2317 : *cngNoiseLevel_exp = shift;
1272 2317 : move16();
1273 : }
1274 : }
1275 : }
1276 15159 : ELSE IF( EQ_16( st->element_mode, IVAS_CPE_DFT ) )
1277 : {
1278 13370 : IF( !( LT_16( hFdCngCom->msFrCnt_init_counter, hFdCngCom->msFrCnt_init_thresh ) ) )
1279 : {
1280 13370 : s2 = -( ( WORD32_BITS - 1 ) );
1281 : /* Shape the SID noise levels in each FFT bin */
1282 13370 : j = 0;
1283 13370 : move16();
1284 288976 : FOR( k = 0; k < hFdCngCom->nFFTpart; k++ )
1285 : {
1286 275606 : assert( hFdCngDec->partNoiseShape[k] >= 0 );
1287 :
1288 : /* add DELTA as it is done in FLC version, in order to avoid num > denom */
1289 275606 : facTab[k] = 0;
1290 275606 : move16();
1291 275606 : IF( hFdCngDec->partNoiseShape[k] != 0 )
1292 : {
1293 275606 : s1 = norm_l( hFdCngCom->sidNoiseEstLp[k] );
1294 275606 : L_tmp = L_shl( hFdCngCom->sidNoiseEstLp[k], s1 ); /*Q31 - ( hFdCngCom->sidNoiseEstExp - s1 )*/
1295 275606 : L_tmp_exp = sub( hFdCngCom->sidNoiseEstExp, s1 );
1296 275606 : L_tmp = BASOP_Util_Add_Mant32Exp( hFdCngCom->sidNoiseEstLp[k], hFdCngCom->sidNoiseEstExp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
1297 275606 : L_tmp = L_shr( L_tmp, 1 );
1298 275606 : s = add( L_tmp_exp, 1 );
1299 275606 : num = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
1300 :
1301 275606 : s1 = norm_l( hFdCngDec->partNoiseShape[k] );
1302 275606 : L_tmp = L_shl( hFdCngDec->partNoiseShape[k], s1 ); /*Q31 - ( hFdCngDec->partNoiseShape_exp - s1 )*/
1303 275606 : L_tmp_exp = sub( hFdCngDec->partNoiseShape_exp, s1 );
1304 275606 : L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
1305 275606 : s = sub( s, L_tmp_exp );
1306 275606 : denom = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
1307 :
1308 275606 : facTab[k] = div_s( num, denom ); /*Q15 - s*/
1309 275606 : move16();
1310 275606 : facTabExp[k] = s;
1311 275606 : move16();
1312 : }
1313 : /* Set unique exponent, IF mantissa is equal to zero */
1314 275606 : if ( facTab[k] == 0 )
1315 : {
1316 1178 : facTabExp[k] = -( WORD32_BITS - 1 );
1317 1178 : move16();
1318 : }
1319 275606 : s2 = s_max( s2, facTabExp[k] );
1320 : }
1321 13370 : IF( EQ_16( s2, -31 ) )
1322 : {
1323 3189 : s2 = 0;
1324 3189 : move16();
1325 : }
1326 288976 : FOR( k = 0; k < hFdCngCom->nFFTpart; k++ )
1327 : {
1328 275606 : s = sub( facTabExp[k], s2 );
1329 275606 : s = s_max( s_min( s, sub( WORD32_BITS, 1 ) ), negate( sub( WORD32_BITS, 1 ) ) );
1330 4196770 : FOR( ; j <= hFdCngCom->part[k]; j++ )
1331 : {
1332 3921164 : cngNoiseLevel[j] = L_shl( Mpy_32_16_1( hFdCngDec->bandNoiseShape[j], facTab[k] ), s ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/
1333 3921164 : move32();
1334 : }
1335 : }
1336 :
1337 13370 : Word16 shift1 = L_norm_arr( cngNoiseLevel, j );
1338 13370 : Word16 shift2 = L_norm_arr( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ) );
1339 13370 : Word16 shift = s_max( sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift1 ), sub( *cngNoiseLevel_exp, shift2 ) );
1340 :
1341 13370 : scale_sig32( cngNoiseLevel, j, sub( add( hFdCngDec->bandNoiseShape_exp, s2 ), shift ) );
1342 13370 : scale_sig32( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ), sub( *cngNoiseLevel_exp, shift ) );
1343 :
1344 13370 : *cngNoiseLevel_exp = shift;
1345 13370 : move16();
1346 : }
1347 : }
1348 17530 : IF( EQ_16( st->codec_mode, MODE2 ) )
1349 : {
1350 : /* Generate comfort noise during SID or zero frames */
1351 0 : IF( EQ_16( st->element_mode, EVS_MONO ) )
1352 : {
1353 0 : generate_comfort_noise_dec_fx( cldfbBufferReal, cldfbBufferImag, cldfbBufferScale, st, &( st->Q_exc ), 2, -1 );
1354 : }
1355 : ELSE
1356 : {
1357 0 : generate_comfort_noise_dec_ivas_fx( cldfbBufferReal, cldfbBufferImag, cldfbBufferScale, st, &( st->Q_exc ), 2, -1 );
1358 : }
1359 : }
1360 :
1361 17530 : BREAK;
1362 :
1363 0 : default:
1364 0 : return -1;
1365 : }
1366 :
1367 :
1368 267270 : return 0;
1369 : }
1370 :
1371 : /*
1372 : perform_noise_estimation_dec_fx
1373 :
1374 : Parameters:
1375 :
1376 : timeDomainInput, i: pointer to time domain input
1377 : bitrate, i: bitrate
1378 : st i/o: FD_CNG structure containing all buffers and variables
1379 :
1380 : Function:
1381 : perform noise estimation
1382 :
1383 : Returns:
1384 : void
1385 : */
1386 15 : void perform_noise_estimation_dec_fx(
1387 : const Word16 *timeDomainInput, /* i: pointer to time domain input Q*/
1388 : const Word16 Q,
1389 : HANDLE_FD_CNG_DEC hFdCngDec /* i/o: FD_CNG structure containing all buffers and variables */
1390 : )
1391 : {
1392 : Word16 i, tmp_r, tmp_i, fac, fftBuffer_exp;
1393 : Word16 s, len, npart, nFFTpart;
1394 : Word16 startBand, stopFFTbin;
1395 :
1396 : Word16 *part, *psize_inv, *psize_norm;
1397 : Word32 tmp, *fftBuffer, *periodog, *ptr_per, *ptr_r, *ptr_i;
1398 :
1399 : /* pointer initialization */
1400 15 : periodog = hFdCngDec->hFdCngCom->periodog; /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1401 15 : fftBuffer = hFdCngDec->hFdCngCom->fftBuffer; /*Q31 - hFdCngDec->hFdCngCom->fftBuffer_exp*/
1402 :
1403 15 : part = hFdCngDec->part_shaping; /*Q0*/
1404 15 : psize_inv = hFdCngDec->psize_inv_shaping; /*Q15*/
1405 15 : psize_norm = hFdCngDec->psize_shaping_norm; /*Q15 - hFdCngDec->psize_shaping_norm_exp*/
1406 :
1407 : /* variable initialization */
1408 15 : startBand = hFdCngDec->hFdCngCom->startBand; /*Q0*/
1409 15 : move16();
1410 15 : stopFFTbin = hFdCngDec->hFdCngCom->stopFFTbin; /*Q0*/
1411 15 : move16();
1412 :
1413 15 : npart = hFdCngDec->npart_shaping; /*Q0*/
1414 15 : move16();
1415 15 : nFFTpart = hFdCngDec->nFFTpart_shaping; /*Q0*/
1416 15 : move16();
1417 :
1418 : /* Perform STFT analysis */
1419 : /* Perform STFT analysis */
1420 15 : AnalysisSTFT( timeDomainInput, Q, fftBuffer, &fftBuffer_exp, hFdCngDec->hFdCngCom );
1421 15 : fftBuffer_exp = add( fftBuffer_exp, WORD16_BITS - 1 );
1422 :
1423 : {
1424 15 : assert( startBand != 0 );
1425 :
1426 15 : len = sub( stopFFTbin, startBand );
1427 :
1428 15 : s = getScaleFactor32( &fftBuffer[( startBand * 2 )], shl( len, 1 ) );
1429 15 : s = sub( s, 1 );
1430 :
1431 15 : ptr_per = periodog;
1432 15 : IF( startBand == 0 )
1433 : {
1434 : /* DC component */
1435 0 : tmp_r = extract_h( L_shl( fftBuffer[0], s ) ); /*Q15 - fftBuffer_exp + s*/
1436 :
1437 0 : tmp = L_mult( tmp_r, tmp_r ); /*Q31 - 2*(fftBuffer_exp - s)*/
1438 0 : *ptr_per = tmp; /*Q31 - 2*(fftBuffer_exp - s)*/
1439 0 : move32();
1440 :
1441 0 : ptr_per++;
1442 0 : ptr_r = fftBuffer + 2; /*Q31 - fftBuffer_exp*/
1443 0 : len = sub( len, 1 );
1444 : }
1445 : ELSE
1446 : {
1447 15 : ptr_r = fftBuffer + shl( startBand, 1 ); /*fftBuffer_exp*/
1448 : }
1449 :
1450 15 : ptr_i = ptr_r + 1;
1451 4337 : FOR( i = 0; i < len; i++ )
1452 : {
1453 4322 : tmp_r = extract_h( L_shl( *ptr_r, s ) ); /*Q15 - fftBuffer_exp + s*/
1454 4322 : tmp_i = extract_h( L_shl( *ptr_i, s ) ); /*Q15 - fftBuffer_exp + s*/
1455 :
1456 4322 : tmp = L_mac( L_mult( tmp_r, tmp_r ), tmp_i, tmp_i ); /*Q31 - 2*(fftBuffer_exp - s)*/
1457 4322 : *ptr_per = tmp; /*Q31 - 2*(fftBuffer_exp - s)*/
1458 4322 : move32();
1459 :
1460 4322 : ptr_r += 2;
1461 4322 : ptr_i += 2;
1462 4322 : ptr_per++;
1463 : }
1464 :
1465 15 : hFdCngDec->hFdCngCom->periodog_exp = shl( sub( fftBuffer_exp, s ), 1 );
1466 15 : move16();
1467 :
1468 : /* Rescale */
1469 15 : assert( ( hFdCngDec->hFdCngCom->fftlen == 640 ) || ( hFdCngDec->hFdCngCom->fftlen == 512 ) || ( hFdCngDec->hFdCngCom->fftlen == 320 ) );
1470 :
1471 15 : fac = 20972 /*0.64 Q15*/;
1472 15 : move16();
1473 15 : if ( EQ_16( hFdCngDec->hFdCngCom->fftlen, 512 ) )
1474 : {
1475 7 : fac = 16384 /*0.5 Q15*/;
1476 7 : move16();
1477 : }
1478 :
1479 15 : if ( EQ_16( hFdCngDec->hFdCngCom->fftlen, 640 ) )
1480 : {
1481 8 : s = 18;
1482 8 : move16();
1483 : }
1484 15 : if ( EQ_16( hFdCngDec->hFdCngCom->fftlen, 512 ) )
1485 : {
1486 7 : s = 17;
1487 7 : move16();
1488 : }
1489 15 : if ( EQ_16( hFdCngDec->hFdCngCom->fftlen, 320 ) )
1490 : {
1491 0 : s = 16;
1492 0 : move16();
1493 : }
1494 :
1495 15 : len = sub( stopFFTbin, startBand );
1496 4337 : FOR( i = 0; i < len; i++ )
1497 : {
1498 4322 : hFdCngDec->hFdCngCom->periodog[i] = Mpy_32_16_1( hFdCngDec->hFdCngCom->periodog[i], fac ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1499 4322 : move32();
1500 : }
1501 15 : hFdCngDec->hFdCngCom->periodog_exp = add( hFdCngDec->hFdCngCom->periodog_exp, sub( 2, s ) );
1502 15 : move16();
1503 :
1504 : /* Adjust to the desired frequency resolution by averaging over spectral partitions for SID transmission */
1505 15 : bandcombinepow( periodog, hFdCngDec->hFdCngCom->periodog_exp, sub( stopFFTbin, startBand ), part, npart, psize_inv, hFdCngDec->msPeriodog, &hFdCngDec->msPeriodog_exp );
1506 :
1507 :
1508 15 : hFdCngDec->msPeriodog_exp_fft = hFdCngDec->msPeriodog_exp;
1509 15 : move16();
1510 15 : hFdCngDec->msPeriodog_exp_cldfb = hFdCngDec->msPeriodog_exp;
1511 15 : move16();
1512 :
1513 :
1514 : /* Compress MS inputs */
1515 15 : compress_range( hFdCngDec->msPeriodog, hFdCngDec->msPeriodog_exp, hFdCngDec->msLogPeriodog, npart );
1516 :
1517 : /* Call the minimum statistics routine for noise estimation */
1518 15 : minimum_statistics(
1519 : npart,
1520 : nFFTpart,
1521 : psize_norm,
1522 15 : hFdCngDec->msLogPeriodog,
1523 15 : hFdCngDec->msNoiseFloor,
1524 15 : hFdCngDec->msLogNoiseEst,
1525 15 : hFdCngDec->msAlpha,
1526 15 : hFdCngDec->msPsd,
1527 15 : hFdCngDec->msPsdFirstMoment,
1528 15 : hFdCngDec->msPsdSecondMoment,
1529 15 : hFdCngDec->msMinBuf,
1530 15 : hFdCngDec->msBminWin,
1531 15 : hFdCngDec->msBminSubWin,
1532 15 : hFdCngDec->msCurrentMin,
1533 15 : hFdCngDec->msCurrentMinOut,
1534 15 : hFdCngDec->msCurrentMinSubWindow,
1535 15 : hFdCngDec->msLocalMinFlag,
1536 15 : hFdCngDec->msNewMinFlag,
1537 15 : hFdCngDec->msPeriodogBuf,
1538 : &( hFdCngDec->msPeriodogBufPtr ),
1539 : hFdCngDec->hFdCngCom );
1540 :
1541 : /* Expand MS outputs */
1542 15 : expand_range( hFdCngDec->msLogNoiseEst, hFdCngDec->msNoiseEst, &hFdCngDec->msNoiseEst_exp, npart );
1543 : }
1544 15 : }
1545 :
1546 96725 : void perform_noise_estimation_dec_ivas_fx(
1547 : const Word16 *timeDomainInput, /* i: pointer to time domain input Q*/
1548 : const Word16 Q,
1549 : Word32 *power_spectrum, /*Q_power_spectrum*/
1550 : Word16 Q_power_spectrum,
1551 : HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure containing all buffers and variables */
1552 : const Word16 element_mode, /* i : element mode Q0*/
1553 : const Word16 bwidth, /* i : audio bandwidth Q0*/
1554 : const Word16 L_frame, /* i : frame length at internal Fs Q0*/
1555 : const Word16 last_L_frame, /* i : frame length of the last frame at internal Fs Q0*/
1556 : const Word32 last_core_brate, /* i : previous frame core bitrate Q0*/
1557 : const Word16 VAD /* i : VAD flag in the decoder Q0*/
1558 : )
1559 : {
1560 96725 : Word16 i, p, fftBuffer_exp = 0;
1561 : Word16 npart, nFFTpart;
1562 : Word16 startBand, stopFFTbin;
1563 :
1564 : Word16 *part, *psize_inv, *psize_norm;
1565 : Word32 *fftBuffer, *periodog, *ptr_per, *ptr_r, *ptr_i;
1566 : Word32 temp, ftemp, delta, L_tmp;
1567 : Word16 e_temp, wght, periodog_exp;
1568 : Word32 enr, enr_tot, enr_tot0;
1569 : Word16 enr_e, enr_ratio, alpha;
1570 : Word32 *msPeriodog;
1571 : Word32 msPeriodog_floor;
1572 : Word32 *msNoiseEst;
1573 : Word32 *reIter;
1574 96725 : Word32 rescale_fac = 0;
1575 : Word64 W_tmp;
1576 96725 : Word16 tmp_s, tmp_q, min_q = 31;
1577 : Word16 q_shift;
1578 : Word32 max_l;
1579 : Word16 norm_shift;
1580 96725 : Word16 check = 0;
1581 96725 : move16();
1582 :
1583 : /* pointer initialization */
1584 96725 : periodog = hFdCngDec->hFdCngCom->periodog; /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1585 96725 : fftBuffer = hFdCngDec->hFdCngCom->fftBuffer; /*Q31 - hFdCngDec->hFdCngCom->fftBuffer_exp*/
1586 96725 : ptr_per = periodog; /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1587 96725 : msPeriodog = hFdCngDec->msPeriodog; /*Q31 - hFdCngDec->msPeriodog_exp*/
1588 96725 : msNoiseEst = hFdCngDec->msNoiseEst; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1589 :
1590 96725 : part = hFdCngDec->part_shaping; /*Q0*/
1591 96725 : psize_inv = hFdCngDec->psize_inv_shaping; /*Q15*/
1592 96725 : psize_norm = hFdCngDec->psize_shaping_norm; /*Q15 - hFdCngDec->psize_shaping_norm_exp*/
1593 :
1594 : /* variable initialization */
1595 96725 : startBand = hFdCngDec->hFdCngCom->startBand;
1596 96725 : move16();
1597 96725 : stopFFTbin = hFdCngDec->hFdCngCom->stopFFTbin;
1598 96725 : move16();
1599 :
1600 96725 : npart = hFdCngDec->npart_shaping;
1601 96725 : move16();
1602 96725 : nFFTpart = hFdCngDec->nFFTpart_shaping;
1603 96725 : move16();
1604 :
1605 : /* Perform STFT analysis */
1606 96725 : test();
1607 96725 : IF( !( EQ_16( element_mode, IVAS_CPE_MDCT ) && power_spectrum != NULL ) )
1608 : {
1609 : /* Perform STFT analysis */
1610 90653 : AnalysisSTFT_fx( timeDomainInput, Q, fftBuffer, &fftBuffer_exp, hFdCngDec->hFdCngCom );
1611 : }
1612 :
1613 96725 : test();
1614 96725 : IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_DFT ) )
1615 : {
1616 52422 : SWITCH( hFdCngDec->hFdCngCom->fftlen )
1617 : {
1618 28345 : case 640:
1619 28345 : rescale_fac = 335544; // 4/(640 * 640) in Q35
1620 28345 : move32();
1621 28345 : BREAK;
1622 24077 : case 512:
1623 24077 : rescale_fac = 524288; // 4/(512 * 512) in Q35
1624 24077 : move32();
1625 24077 : BREAK;
1626 0 : case 320:
1627 0 : rescale_fac = 1342177; // 4/(320 * 320) in Q35
1628 0 : move32();
1629 0 : BREAK;
1630 0 : default:
1631 0 : assert( 0 );
1632 : }
1633 : /* Calculate periodogram (squared magnitude in each FFT bin) */
1634 52422 : IF( startBand == 0 )
1635 : {
1636 0 : W_tmp = W_mult0_32_32( fftBuffer[0], fftBuffer[0] ); /*Q31 - 2*fftBuffer_exp*/
1637 0 : tmp_s = W_norm( W_tmp );
1638 0 : ( *ptr_per ) = W_extract_h( W_shl( W_tmp, tmp_s ) ); /*tmp_q*/
1639 0 : tmp_q = sub( add( i_mult( sub( 31, fftBuffer_exp ), 2 ), tmp_s ), 32 );
1640 0 : min_q = tmp_q;
1641 0 : move16();
1642 0 : ptr_per++;
1643 0 : ptr_r = fftBuffer + 2; /*Q31 - fftBuffer_exp*/
1644 : }
1645 : ELSE
1646 : {
1647 52422 : ptr_r = fftBuffer + i_mult( 2, startBand ); /*Q31 - fftBuffer_exp*/
1648 : }
1649 :
1650 52422 : ptr_i = ptr_r + 1; /*Q31 - fftBuffer_exp*/
1651 :
1652 15177914 : FOR( ; ptr_per < periodog + sub( stopFFTbin, startBand ); ptr_per++ )
1653 : {
1654 15125492 : W_tmp = W_add( W_mult0_32_32( ( *ptr_r ), ( *ptr_r ) ), W_mult0_32_32( ( *ptr_i ), ( *ptr_i ) ) ); /*Q31 - 2*(fftBuffer_exp)*/
1655 :
1656 15125492 : tmp_s = W_norm( W_tmp );
1657 15125492 : tmp_q = sub( add( i_mult( sub( 31, fftBuffer_exp ), 2 ), tmp_s ), 32 );
1658 15125492 : *ptr_per = W_extract_h( W_shl( W_tmp, tmp_s ) ); /*tmp_q*/
1659 15125492 : IF( LT_16( tmp_q, min_q ) )
1660 : {
1661 180355 : reIter = ptr_per; /*tmp_q*/
1662 : Word16 diff;
1663 180355 : diff = sub( min_q, tmp_q );
1664 :
1665 1826337 : WHILE( reIter > periodog )
1666 : {
1667 1645982 : reIter--;
1668 1645982 : *reIter = L_shr( *reIter, diff ); /*tmp_q*/
1669 1645982 : move32();
1670 : }
1671 180355 : min_q = tmp_q;
1672 180355 : move16();
1673 : }
1674 : ELSE
1675 : {
1676 : Word16 diff;
1677 14945137 : diff = sub( tmp_q, min_q );
1678 14945137 : ( *ptr_per ) = L_shr( ( *ptr_per ), diff ); /*min_q*/
1679 : }
1680 :
1681 : /* Rescale to get energy/sample: it should be 2*(1/N)*(2/N), parseval relation with 1/N,*2 for nrg computed till Nyquist only, 2/N as windowed samples correspond to half a frame*/
1682 15125492 : ( *ptr_per ) = Mpy_32_32_r( ( *ptr_per ), rescale_fac ); // Q = min_q+36-31=min_q+5
1683 15125492 : move32();
1684 :
1685 15125492 : ptr_r += 2;
1686 15125492 : ptr_i += 2;
1687 : }
1688 :
1689 52422 : hFdCngDec->hFdCngCom->periodog_exp = sub( 31 - 4, min_q );
1690 52422 : hFdCngDec->hFdCngCom->fftBuffer_exp = fftBuffer_exp;
1691 52422 : move16();
1692 52422 : move16();
1693 :
1694 52422 : tmp_s = getScaleFactor32( periodog, sub( stopFFTbin, startBand ) );
1695 52422 : IF( GT_16( tmp_s, 7 ) )
1696 : {
1697 52315 : tmp_s = sub( tmp_s, 7 );
1698 52315 : hFdCngDec->hFdCngCom->periodog_exp = sub( hFdCngDec->hFdCngCom->periodog_exp, tmp_s );
1699 52315 : move16();
1700 15145701 : FOR( p = 0; p < stopFFTbin - startBand; p++ )
1701 : {
1702 15093386 : periodog[p] = L_shl( periodog[p], tmp_s ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1703 15093386 : move32();
1704 : }
1705 : }
1706 :
1707 : /* Combine bins of power spectrum into partitions */
1708 52422 : i = 0;
1709 52422 : move16();
1710 3274300 : FOR( p = 0; p < npart; p++ )
1711 : {
1712 :
1713 : /* calculate mean over all bins in power partition */
1714 3221878 : temp = 0;
1715 3221878 : move16();
1716 18347370 : FOR( ; i <= part[p]; i++ )
1717 : {
1718 15125492 : temp = L_add( temp, periodog[i] ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1719 : }
1720 3221878 : msPeriodog[p] = Mpy_32_16_1( temp, psize_inv[p] ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1721 3221878 : move32();
1722 : }
1723 :
1724 52422 : hFdCngDec->msPeriodog_exp = hFdCngDec->hFdCngCom->periodog_exp;
1725 52422 : move16();
1726 :
1727 : /* compensate for the loss of variance - don't do when first noise update is not completed yet due to risk of msPeriodog[p] < 0 */
1728 52422 : IF( hFdCngDec->first_cna_noise_updated )
1729 : {
1730 20860 : i = 0;
1731 20860 : move16();
1732 :
1733 : /* This is done to avoid overflow when checking "if ( msPeriodog[p] < 1e-5f )" */
1734 20860 : IF( LT_16( hFdCngDec->msPeriodog_exp, -16 ) )
1735 : {
1736 0 : FOR( p = 0; p < NPART_SHAPING; p++ )
1737 : {
1738 0 : msPeriodog[p] = L_shr( msPeriodog[p], sub( -16, hFdCngDec->msPeriodog_exp ) ); /*Q31 - (-16)*/
1739 0 : move32();
1740 : }
1741 0 : hFdCngDec->msPeriodog_exp = -16;
1742 0 : move16();
1743 : }
1744 :
1745 1303070 : FOR( p = 0; p < npart; p++ )
1746 : {
1747 : /* calculate variance over all bins in power partition */
1748 1282210 : temp = 0;
1749 1282210 : move32();
1750 1282210 : W_tmp = 0;
1751 1282210 : move64();
1752 7291690 : FOR( ; i <= part[p]; i++ )
1753 : {
1754 6009480 : delta = L_sub( periodog[i], msPeriodog[p] ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1755 6009480 : W_tmp = W_add( W_tmp, W_mult0_32_32( delta, delta ) ); /*Q31 - 2*(hFdCngDec->hFdCngCom->periodog_exp)*/
1756 : }
1757 1282210 : tmp_s = W_norm( W_tmp );
1758 1282210 : temp = W_extract_h( W_shl( W_tmp, tmp_s ) ); // Q = 63 - 2*(31-exp) - tmp_s
1759 :
1760 1282210 : temp = Mpy_32_16_1( temp, psize_inv[p] ); // Qtemp
1761 :
1762 : /* compensate for the loss of variance */
1763 1282210 : e_temp = sub( 63, add( i_mult( sub( 31, hFdCngDec->hFdCngCom->periodog_exp ), 2 ), tmp_s ) );
1764 1282210 : temp = Sqrt32( temp, &e_temp ); /*Q31 - e_temp*/
1765 1282210 : IF( LT_16( e_temp, 0 ) )
1766 : {
1767 746583 : temp = L_shr( temp, abs_s( e_temp ) ); /*Q31*/
1768 746583 : e_temp = 0;
1769 746583 : move16();
1770 : }
1771 :
1772 1282210 : ftemp = rand_gauss( &hFdCngDec->cna_seed ); /*Q29*/
1773 :
1774 1282210 : L_tmp = Mpy_32_32( temp, ftemp ); /*Q29*/
1775 1282210 : L_tmp = L_shr( L_tmp, sub( sub( hFdCngDec->hFdCngCom->periodog_exp, e_temp ), 2 ) ); /*Q31 - hFdCngDec->msPeriodog_exp*/
1776 :
1777 1282210 : msPeriodog[p] = L_add( msPeriodog[p], L_tmp ); /*Q31 - hFdCngDec->msPeriodog_exp*/
1778 1282210 : move32();
1779 :
1780 1282210 : msPeriodog_floor = L_max( 1, L_shr( 21474 /*Q31*/, hFdCngDec->msPeriodog_exp ) ); /*Q31 - hFdCngDec->msPeriodog_exp*/
1781 1282210 : IF( LT_32( msPeriodog[p], msPeriodog_floor ) )
1782 : {
1783 105132 : msPeriodog[p] = msPeriodog_floor;
1784 105132 : move32();
1785 : }
1786 : }
1787 25049 : FOR( p = 0; p < npart; p++ )
1788 : {
1789 24981 : IF( GT_32( msPeriodog[p], 1 ) )
1790 : {
1791 20792 : check = 1;
1792 20792 : move16();
1793 20792 : BREAK;
1794 : }
1795 : }
1796 20860 : IF( check == 0 )
1797 : {
1798 68 : hFdCngDec->msPeriodog_exp = 14; /* msPeriodog buffer will have minimum value as 1e-5f */
1799 68 : move16();
1800 : }
1801 : }
1802 :
1803 : /* calculate total energy (short-term and long-term) */
1804 52422 : tmp_s = getScaleFactor32( msPeriodog, npart );
1805 52422 : IF( LT_16( tmp_s, 5 ) )
1806 : {
1807 2419 : FOR( p = 0; p < npart; p++ )
1808 : {
1809 2380 : msPeriodog[p] = L_shr( msPeriodog[p], sub( 5, tmp_s ) ); /*Q31 - hFdCngDec->msPeriodog_exp - 5 + tmp_s*/
1810 2380 : move32();
1811 : }
1812 39 : hFdCngDec->msPeriodog_exp = add( hFdCngDec->msPeriodog_exp, sub( 5, tmp_s ) );
1813 39 : move16();
1814 : }
1815 52422 : enr_tot = 1;
1816 52422 : move32();
1817 52422 : enr_tot0 = 1;
1818 52422 : move32();
1819 52422 : IF( GE_16( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) )
1820 : {
1821 461 : enr_tot = L_add_sat( L_shr( sum32_fx( msPeriodog, npart ), sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) ), 1 ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1822 461 : enr_tot0 = L_add_sat( sum32_fx( msNoiseEst, npart ), 1 );
1823 : }
1824 51961 : ELSE IF( LT_16( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) )
1825 : {
1826 51961 : enr_tot = L_add_sat( sum32_fx( msPeriodog, npart ), 1 );
1827 51961 : enr_tot0 = L_add_sat( L_shr( sum32_fx( msNoiseEst, npart ), sub( hFdCngDec->msPeriodog_exp, hFdCngDec->msNoiseEst_exp ) ), 1 ); /*Q31 - hFdCngDec->msPeriodog_exp*/
1828 : }
1829 :
1830 : /* update short-term periodogram on larger partitions */
1831 52422 : maximum_32_fx( &msPeriodog[CNA_ACT_DN_LARGE_PARTITION], sub( npart, CNA_ACT_DN_LARGE_PARTITION ), &max_l );
1832 52422 : q_shift = sub( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msPeriodog_ST_exp );
1833 52422 : norm_shift = norm_l( max_l );
1834 52422 : test();
1835 52422 : IF( max_l && GT_16( q_shift, norm_shift ) )
1836 : {
1837 3972 : scale_sig32( hFdCngDec->msPeriodog_ST_fx, NPART_SHAPING, sub( norm_shift, q_shift ) ); /*Q31 - hFdCngDec->msPeriodog_ST_exp + ( norm_shift - q_shift )*/
1838 3972 : hFdCngDec->msPeriodog_ST_exp = sub( hFdCngDec->msPeriodog_ST_exp, sub( norm_shift, q_shift ) );
1839 3972 : move16();
1840 3972 : q_shift = norm_shift;
1841 3972 : move16();
1842 : }
1843 653200 : FOR( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ )
1844 : {
1845 600778 : test();
1846 600778 : q_shift = sub( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msPeriodog_ST_exp );
1847 600778 : IF( NE_16( L_frame, last_L_frame ) || LE_32( last_core_brate, SID_2k40 ) )
1848 : {
1849 : /* core Fs has changed or last frame was SID/NO_DATA -> re-initialize short-term periodogram */
1850 21104 : hFdCngDec->msPeriodog_ST_fx[p] = L_shl( msPeriodog[p], q_shift ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1851 21104 : move32();
1852 : }
1853 : ELSE
1854 : {
1855 579674 : temp = L_shl( msPeriodog[p], q_shift ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1856 579674 : hFdCngDec->msPeriodog_ST_fx[p] = Madd_32_16( Mpy_32_16_1( hFdCngDec->msPeriodog_ST_fx[p], ST_PERIODOG_FACT_Q15 ), temp, MAX_16 - ST_PERIODOG_FACT_Q15 ); /*Q31 - hFdCngDec->msPeriodog_ST_exp*/
1857 579674 : move32();
1858 : }
1859 : }
1860 52422 : maximum_32_fx( hFdCngDec->msPeriodog_ST_fx, NPART_SHAPING, &max_l );
1861 52422 : IF( max_l )
1862 : {
1863 52422 : q_shift = sub( norm_l( max_l ), 2 );
1864 52422 : scale_sig32( hFdCngDec->msPeriodog_ST_fx, NPART_SHAPING, q_shift ); /*Q31 - hFdCngDec->msPeriodog_ST_exp + q_shift*/
1865 52422 : hFdCngDec->msPeriodog_ST_exp = sub( hFdCngDec->msPeriodog_ST_exp, q_shift );
1866 52422 : move16();
1867 : }
1868 :
1869 : /* core Fs has changed -> partitions have changed -> re-calculate long-term periodogram */
1870 : /* part L_FRAME16k L_FRAME */
1871 : /* ... */
1872 : /* [55] 146 146 */
1873 : /* [56] 174 160 */
1874 : /* [57] 210 174 */
1875 : /* [58] 254 190 */
1876 : /* [59] 306 210 */
1877 : /* [60] 317 230 */
1878 : /* [61] 253 */
1879 :
1880 52422 : test();
1881 52422 : test();
1882 52422 : IF( EQ_16( last_L_frame, L_FRAME16k ) && EQ_16( L_frame, L_FRAME ) )
1883 : {
1884 577 : msNoiseEst[61] = msNoiseEst[58]; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1885 577 : move32();
1886 577 : msNoiseEst[60] = L_min( msNoiseEst[58], msNoiseEst[57] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1887 577 : move32();
1888 577 : msNoiseEst[59] = msNoiseEst[57]; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1889 577 : move32();
1890 577 : msNoiseEst[58] = msNoiseEst[56]; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1891 577 : move32();
1892 577 : msNoiseEst[57] = msNoiseEst[56]; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1893 577 : move32();
1894 577 : msNoiseEst[56] = L_min( msNoiseEst[56], msNoiseEst[55] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1895 577 : move32();
1896 : }
1897 51845 : ELSE IF( EQ_16( last_L_frame, L_FRAME ) && EQ_16( L_frame, L_FRAME16k ) )
1898 : {
1899 137 : msNoiseEst[56] = L_min( msNoiseEst[56], msNoiseEst[57] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1900 137 : move32();
1901 137 : msNoiseEst[57] = L_min( msNoiseEst[58], msNoiseEst[59] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1902 137 : move32();
1903 137 : msNoiseEst[58] = L_min( msNoiseEst[60], msNoiseEst[61] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1904 137 : move32();
1905 137 : msNoiseEst[59] = 0; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1906 137 : move32();
1907 137 : msNoiseEst[60] = 0; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1908 137 : move32();
1909 137 : msNoiseEst[61] = 0; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1910 137 : move32();
1911 :
1912 137 : hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES;
1913 137 : move16();
1914 : }
1915 :
1916 : /* Smooth with IIR filter */
1917 52422 : IF( !hFdCngDec->first_cna_noise_updated )
1918 : {
1919 31562 : IF( !VAD )
1920 : {
1921 906 : Word16 e = 15;
1922 906 : move16();
1923 : /* background noise update with moving average */
1924 906 : IF( hFdCngDec->first_cna_noise_update_cnt != 0 )
1925 : {
1926 639 : alpha = Inv16( add( hFdCngDec->first_cna_noise_update_cnt, 1 ), &e ); /*Q15*/
1927 639 : alpha = shl_sat( alpha, e ); // Q15
1928 639 : maximum_32_fx( msPeriodog, npart, &max_l );
1929 639 : q_shift = sub( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msNoiseEst_exp );
1930 639 : norm_shift = norm_l( max_l );
1931 639 : test();
1932 639 : IF( max_l && GT_16( q_shift, norm_shift ) )
1933 : {
1934 20 : scale_sig32( msNoiseEst, NPART_SHAPING, sub( norm_shift, q_shift ) ); /*Q31 - hFdCngDec->msNoiseEst_exp + ( norm_shift - q_shift )*/
1935 20 : hFdCngDec->msNoiseEst_exp = sub( hFdCngDec->msNoiseEst_exp, sub( norm_shift, q_shift ) );
1936 20 : move16();
1937 20 : q_shift = norm_shift;
1938 20 : move16();
1939 : }
1940 40011 : FOR( p = 0; p < npart; p++ )
1941 : {
1942 39372 : temp = L_shl( msPeriodog[p], q_shift );
1943 39372 : msNoiseEst[p] = Madd_32_16( Mpy_32_16_1( msNoiseEst[p], sub( MAX_16, alpha ) ), temp, alpha ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1944 39372 : move32();
1945 : }
1946 : }
1947 : ELSE
1948 : {
1949 267 : Copy32( msPeriodog, msNoiseEst, npart );
1950 :
1951 267 : Word16 shift1 = L_norm_arr( msNoiseEst, npart );
1952 267 : Word16 shift2 = L_norm_arr( &msNoiseEst[npart], sub( NPART_SHAPING, npart ) );
1953 267 : Word16 shift = s_max( sub( hFdCngDec->msPeriodog_exp, shift1 ), sub( hFdCngDec->msNoiseEst_exp, shift2 ) );
1954 :
1955 267 : scale_sig32( msNoiseEst, npart, sub( hFdCngDec->msPeriodog_exp, shift ) );
1956 267 : scale_sig32( &msNoiseEst[npart], sub( NPART_SHAPING, npart ), sub( hFdCngDec->msNoiseEst_exp, shift ) );
1957 :
1958 267 : hFdCngDec->msNoiseEst_exp = shift;
1959 267 : move16();
1960 : }
1961 :
1962 : /* check, if we reached the required number of first CNA noise update frames */
1963 906 : IF( LT_16( hFdCngDec->first_cna_noise_update_cnt, FIRST_CNA_NOISE_UPD_FRAMES - 1 ) )
1964 : {
1965 767 : hFdCngDec->first_cna_noise_update_cnt = add( hFdCngDec->first_cna_noise_update_cnt, 1 ); /*Q0*/
1966 767 : move16();
1967 : }
1968 : ELSE
1969 : {
1970 139 : hFdCngDec->first_cna_noise_updated = 1;
1971 139 : move16();
1972 139 : if ( EQ_16( hFdCngDec->hFdCngCom->msFrCnt_init_counter, 0 ) )
1973 : {
1974 49 : hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1;
1975 49 : move16();
1976 : }
1977 : }
1978 : }
1979 : ELSE
1980 : {
1981 30656 : hFdCngDec->first_cna_noise_update_cnt = 0;
1982 30656 : move16();
1983 : }
1984 : }
1985 : ELSE
1986 : {
1987 20860 : hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1;
1988 20860 : move16();
1989 20860 : IF( VAD )
1990 : {
1991 : Word16 scale;
1992 : /* no updates during active frames except for significant energy drops */
1993 17434 : enr_ratio = BASOP_Util_Divide3232_Scale( enr_tot, enr_tot0, &scale ); /*Q15 - scale*/
1994 17434 : IF( scale <= 0 )
1995 : {
1996 927 : enr_ratio = shl( enr_ratio, scale ); /*Q15*/
1997 927 : scale = 15;
1998 927 : move16();
1999 : }
2000 : ELSE
2001 : {
2002 16507 : scale = sub( 15, scale );
2003 : }
2004 17434 : IF( LT_16( enr_ratio, shl( 1, sub( scale, 1 ) ) ) )
2005 : {
2006 : /* total energy significantly decreases during active frames -> downward update */
2007 728 : wght = lin_interp_fx( enr_ratio, 0, shr( 26214, sub( 15, scale ) ) /*0.8f in Q15*/, shr( 16384, sub( 15, scale ) ) /*0.5f in Q15*/, shr( 31130, sub( 15, scale ) ) /*0.95f in Q15*/, shr( 32767, sub( 15, scale ) ) /*1 in Q15*/ ); /*scale*/
2008 : Word16 temp_q_msNoiseEst[NPART_SHAPING];
2009 728 : Word16 min_q_msNoiseEst = MAX_16;
2010 728 : move16();
2011 45864 : FOR( p = 0; p < NPART_SHAPING; p++ )
2012 : {
2013 45136 : temp_q_msNoiseEst[p] = hFdCngDec->msNoiseEst_exp;
2014 45136 : move16();
2015 : }
2016 45484 : FOR( p = 0; p < npart; p++ )
2017 : {
2018 44756 : L_tmp = L_shr( msPeriodog[p], sub( sub( 31, hFdCngDec->hFdCngCom->periodog_exp ), 4 ) );
2019 44756 : IF( LT_32( L_tmp, msNoiseEst[p] ) )
2020 : {
2021 43205 : msNoiseEst[p] = Madd_32_16( Mpy_32_16_1( msNoiseEst[p], wght ), L_tmp, (Word16) L_sub( shr( MAX_16, sub( 15, scale ) ), wght ) ); /*temp_q_msNoiseEst[p]*/
2022 43205 : move32();
2023 43205 : temp_q_msNoiseEst[p] = sub( add( hFdCngDec->msNoiseEst_exp, scale ), 15 );
2024 43205 : move16();
2025 : }
2026 44756 : min_q_msNoiseEst = s_min( temp_q_msNoiseEst[p], min_q_msNoiseEst );
2027 : }
2028 45864 : FOR( p = 0; p < NPART_SHAPING; p++ )
2029 : {
2030 45136 : msNoiseEst[p] = L_shl( msNoiseEst[p], sub( min_q_msNoiseEst, temp_q_msNoiseEst[p] ) ); /*min_q_msNoiseEst*/
2031 45136 : move32();
2032 : }
2033 728 : hFdCngDec->msNoiseEst_exp = min_q_msNoiseEst;
2034 728 : move16();
2035 : }
2036 : ELSE
2037 : {
2038 : /* energy significantly decreases in one of the larger partitions during active frames -> downward update */
2039 208497 : FOR( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ )
2040 : {
2041 191791 : L_tmp = L_shr_sat( hFdCngDec->msPeriodog_ST_fx[p], sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_ST_exp ) ); /*Q31 - hFdCngDec->msPeriodog_ST_exp*/
2042 191791 : IF( LT_32( L_tmp, msNoiseEst[p] ) )
2043 : {
2044 14075 : msNoiseEst[p] = Madd_32_16( Mpy_32_16_1( msNoiseEst[p], CNA_ACT_DN_FACT_Q15 ), L_tmp, ONE_IN_Q15 - CNA_ACT_DN_FACT_Q15 ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
2045 14075 : move32();
2046 : }
2047 : }
2048 : }
2049 : }
2050 : ELSE
2051 : {
2052 3426 : test();
2053 3426 : if ( GE_16( bwidth, WB ) && hFdCngDec->ms_last_inactive_bwidth == NB )
2054 : {
2055 : /* bandwidth increased -> set counter for fast initilization */
2056 54 : hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES;
2057 54 : move16();
2058 : }
2059 3426 : hFdCngDec->ms_last_inactive_bwidth = bwidth;
2060 3426 : move16();
2061 : /* update background noise during inactive frames */
2062 3426 : ptr_per = msNoiseEst; /*Q31 - hFdCngDec->msNoiseEst_exp*/
2063 213789 : FOR( p = 0; p < npart; p++ )
2064 : {
2065 210363 : Word16 i_e = 15;
2066 210363 : move16();
2067 210363 : enr = msPeriodog[p]; /*Q31 - hFdCngDec->msPeriodog_exp*/
2068 210363 : move32();
2069 210363 : enr_e = hFdCngDec->msPeriodog_exp;
2070 210363 : move16();
2071 210363 : alpha = 31130; // 0.95f in Q15
2072 210363 : move16();
2073 : /* bandwidth increased -> do fast re-initilization */
2074 210363 : test();
2075 210363 : IF( GT_16( hFdCngDec->ms_cnt_bw_up, 0 ) && GT_16( p, 55 ) )
2076 : {
2077 1970 : alpha = Inv16( add( hFdCngDec->ms_cnt_bw_up, 1 ), &i_e ); /*Q15 - i_e*/
2078 1970 : IF( i_e < 0 )
2079 : {
2080 1970 : alpha = shr( alpha, negate( i_e ) ); // Q15
2081 : }
2082 : }
2083 208393 : ELSE IF( ( BASOP_Util_Cmp_Mant32Exp( enr, enr_e, *ptr_per, hFdCngDec->msNoiseEst_exp ) < 0 ) && EQ_16( part[p], 1 ) )
2084 : {
2085 : /* faster downward update for single-bin partitions */
2086 1318 : alpha = 26214; // 0.8f in Q15
2087 1318 : move16();
2088 : }
2089 207075 : ELSE IF( BASOP_Util_Cmp_Mant32Exp( enr, enr_e, *ptr_per, add( hFdCngDec->msNoiseEst_exp, 1 ) ) > 0 )
2090 : {
2091 : /* prevent abrupt upward updates */
2092 61701 : test();
2093 61701 : IF( ( norm_l( *ptr_per ) == 0 ) && *ptr_per )
2094 : {
2095 0 : enr = *ptr_per; /*Q31 - hFdCngDec->msNoiseEst_exp*/
2096 0 : scale_sig32( msNoiseEst, NPART_SHAPING, -1 );
2097 0 : hFdCngDec->msNoiseEst_exp = add( hFdCngDec->msNoiseEst_exp, 1 );
2098 0 : move16();
2099 : }
2100 : ELSE
2101 : {
2102 61701 : enr = L_shl( *ptr_per, 1 ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
2103 : }
2104 61701 : enr_e = hFdCngDec->msNoiseEst_exp;
2105 61701 : move16();
2106 : }
2107 :
2108 : /* IIR smoothing */
2109 210363 : test();
2110 210363 : IF( *ptr_per != 0 && alpha != 0 )
2111 : {
2112 210246 : *ptr_per = Mpy_32_16_1( ( *ptr_per ), alpha ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
2113 210246 : move32();
2114 210246 : if ( *ptr_per == 0 )
2115 : {
2116 0 : *ptr_per = 1;
2117 0 : move32();
2118 : }
2119 : }
2120 : ELSE
2121 : {
2122 117 : *ptr_per = 0;
2123 117 : move32();
2124 : }
2125 210363 : IF( enr )
2126 : {
2127 210295 : q_shift = sub( enr_e, hFdCngDec->msNoiseEst_exp );
2128 210295 : norm_shift = norm_l( enr );
2129 210295 : IF( LE_16( q_shift, norm_shift ) )
2130 : {
2131 210295 : enr = L_shl( enr, q_shift ); /*Q31 - hFdCngDec->msNoiseEst_exp + q_shift*/
2132 210295 : move32();
2133 : }
2134 : ELSE
2135 : {
2136 0 : enr_e = sub( enr_e, norm_shift );
2137 0 : enr = L_shl( enr, norm_shift ); /*Q31 - hFdCngDec->msNoiseEst_exp + norm_shift*/
2138 0 : scale_sig32( msNoiseEst, NPART_SHAPING, sub( norm_shift, q_shift ) ); /*Q31 - ( hFdCngDec->msNoiseEst_exp - ( norm_shift - q_shift ) )*/
2139 0 : hFdCngDec->msNoiseEst_exp = sub( hFdCngDec->msNoiseEst_exp, sub( norm_shift, q_shift ) );
2140 0 : move16();
2141 : }
2142 : }
2143 210363 : *ptr_per = Madd_32_16( ( *ptr_per ), enr, sub( MAX_16, alpha ) ); /*Q31 - enr_e*/
2144 210363 : move32();
2145 210363 : ptr_per++;
2146 : }
2147 :
2148 3426 : IF( hFdCngDec->ms_cnt_bw_up > 0 )
2149 : {
2150 369 : hFdCngDec->ms_cnt_bw_up = sub( hFdCngDec->ms_cnt_bw_up, 1 );
2151 369 : move16();
2152 : }
2153 : }
2154 : }
2155 52422 : maximum_32_fx( msNoiseEst, NPART_SHAPING, &max_l );
2156 52422 : IF( max_l )
2157 : {
2158 25115 : q_shift = sub( norm_l( max_l ), 2 );
2159 25115 : scale_sig32( msNoiseEst, NPART_SHAPING, q_shift ); /*Q31 - ( hFdCngDec->msNoiseEst_exp - q_shift )*/
2160 25115 : hFdCngDec->msNoiseEst_exp = sub( hFdCngDec->msNoiseEst_exp, q_shift );
2161 25115 : move16();
2162 : }
2163 :
2164 52422 : Copy32( msNoiseEst, hFdCngDec->msPsd_fx, npart ); /*Q31 - ( hFdCngDec->msNoiseEst_exp )*/
2165 52422 : hFdCngDec->msPsd_exp_fft = hFdCngDec->msNoiseEst_exp;
2166 52422 : move16();
2167 :
2168 : /* Expand partitions into bins of power spectrum */
2169 52422 : scalebands_fx( msNoiseEst, part, nFFTpart, hFdCngDec->midband_shaping, nFFTpart, sub( stopFFTbin, startBand ), hFdCngDec->bandNoiseShape, 1 );
2170 52422 : hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp;
2171 52422 : move16();
2172 52422 : Copy32( hFdCngDec->bandNoiseShape, &hFdCngDec->smoothed_psd_fx[startBand], sub( stopFFTbin, startBand ) ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/
2173 52422 : hFdCngDec->smoothed_psd_exp = hFdCngDec->bandNoiseShape_exp;
2174 52422 : move16();
2175 52422 : set32_fx( &hFdCngDec->smoothed_psd_fx[stopFFTbin], 0, sub( L_FRAME16k, stopFFTbin ) );
2176 : }
2177 : ELSE
2178 : {
2179 44303 : test();
2180 44303 : IF( EQ_16( element_mode, IVAS_CPE_MDCT ) && power_spectrum != NULL )
2181 : {
2182 : /* use power spectrum calculated in the MDCT-domain instead of calculating new power spectrum */
2183 6072 : periodog = power_spectrum; /*Q_power_spectrum*/
2184 6072 : periodog_exp = sub( 31, Q_power_spectrum );
2185 : }
2186 : ELSE
2187 : {
2188 : /* Compute the squared magnitude in each FFT bin */
2189 38231 : IF( startBand == 0 )
2190 : {
2191 0 : W_tmp = W_mult0_32_32( fftBuffer[0], fftBuffer[0] ); /* DC component */ /*Q31 - 2*fftBuffer_exp*/
2192 0 : min_q = 2;
2193 0 : move16();
2194 0 : ( *ptr_per ) = W_extract_l( W_shr( W_tmp, sub( i_mult( sub( 31, fftBuffer_exp ), 2 ), min_q ) ) );
2195 0 : move32();
2196 0 : ptr_per++;
2197 0 : ptr_r = fftBuffer + 2; /*Q31 - fftBuffer_exp*/
2198 : }
2199 : ELSE
2200 : {
2201 38231 : ptr_r = fftBuffer + i_mult( 2, startBand ); /*Q31 - fftBuffer_exp*/
2202 : }
2203 :
2204 38231 : ptr_i = ptr_r + 1; /*Q31 - fftBuffer_exp*/
2205 :
2206 38231 : SWITCH( hFdCngDec->hFdCngCom->fftlen )
2207 : {
2208 18946 : case 640:
2209 18946 : rescale_fac = 20972; // 4/(640 * 640) in Q31
2210 18946 : move32();
2211 18946 : BREAK;
2212 19285 : case 512:
2213 19285 : rescale_fac = 32768; // 4/(512 * 512) in Q31
2214 19285 : move32();
2215 19285 : BREAK;
2216 0 : case 320:
2217 0 : rescale_fac = 83886; // 4/(320 * 320) in Q31
2218 0 : move32();
2219 0 : BREAK;
2220 0 : default:
2221 0 : assert( 0 );
2222 : }
2223 :
2224 10961449 : FOR( ; ptr_per < periodog + stopFFTbin - startBand; ptr_per++ )
2225 : {
2226 10923218 : W_tmp = W_add( W_mult0_32_32( ( *ptr_r ), ( *ptr_r ) ), W_mult0_32_32( ( *ptr_i ), ( *ptr_i ) ) ); /*Q31 - 2*(fftBuffer_exp)*/
2227 :
2228 10923218 : tmp_s = W_norm( W_tmp ); /*tmp_q*/
2229 10923218 : tmp_q = sub( add( i_mult( sub( 31, fftBuffer_exp ), 2 ), tmp_s ), 32 );
2230 10923218 : IF( tmp_q < 0 )
2231 : {
2232 206395 : W_tmp = W_shr( W_tmp, negate( tmp_q ) ); /*Q31 - 2*(fftBuffer_exp) + tmp_q*/
2233 : }
2234 10923218 : IF( LT_16( tmp_q, min_q ) )
2235 : {
2236 259804 : reIter = ptr_per; /*tmp_q*/
2237 : Word16 diff;
2238 259804 : IF( ( tmp_q <= 0 ) )
2239 : {
2240 211176 : diff = min_q;
2241 211176 : move16();
2242 : }
2243 : ELSE
2244 : {
2245 48628 : diff = sub( min_q, tmp_q );
2246 : }
2247 5421156 : WHILE( reIter > periodog )
2248 : {
2249 5161352 : reIter--;
2250 5161352 : *reIter = L_shr( *reIter, diff ); /*tmp_q*/
2251 5161352 : move32();
2252 : }
2253 259804 : IF( tmp_q >= 0 )
2254 : {
2255 53409 : min_q = tmp_q;
2256 53409 : move16();
2257 : }
2258 206395 : ELSE IF( tmp_q < 0 )
2259 : {
2260 206395 : min_q = 0;
2261 206395 : move16();
2262 : }
2263 : }
2264 10923218 : ( *ptr_per ) = W_extract_l( W_shr( W_tmp, sub( i_mult( sub( 31, fftBuffer_exp ), 2 ), min_q ) ) ); // Q = min_q
2265 10923218 : move32();
2266 :
2267 : /* Rescale to get energy/sample: it should be 2*(1/N)*(2/N), parseval relation with 1/N,*2 for nrg computed till Nyquist only, 2/N as windowed samples correspond to half a frame*/
2268 10923218 : ( *ptr_per ) = Mpy_32_32_r( ( *ptr_per ), rescale_fac ); // Q = min_q
2269 10923218 : move32();
2270 10923218 : IF( tmp_q <= 0 )
2271 : {
2272 278799 : ( *ptr_per ) = L_shl( ( *ptr_per ), negate( tmp_q ) );
2273 278799 : move32();
2274 : }
2275 :
2276 10923218 : ptr_r += 2;
2277 10923218 : ptr_i += 2;
2278 : }
2279 :
2280 38231 : hFdCngDec->hFdCngCom->periodog_exp = sub( 31, min_q );
2281 38231 : move16();
2282 38231 : hFdCngDec->hFdCngCom->fftBuffer_exp = fftBuffer_exp;
2283 38231 : move16();
2284 :
2285 38231 : tmp_s = getScaleFactor32( periodog, L_frame );
2286 38231 : IF( GT_16( tmp_s, 3 ) )
2287 : {
2288 25571 : tmp_s = sub( tmp_s, 3 );
2289 25571 : hFdCngDec->hFdCngCom->periodog_exp = sub( hFdCngDec->hFdCngCom->periodog_exp, tmp_s );
2290 25571 : move16();
2291 6924765 : FOR( p = 0; p < stopFFTbin - startBand; p++ )
2292 : {
2293 6899194 : periodog[p] = L_shl( periodog[p], tmp_s ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp + tmp_s*/
2294 6899194 : move32();
2295 : }
2296 : }
2297 38231 : periodog_exp = hFdCngDec->hFdCngCom->periodog_exp;
2298 38231 : move16();
2299 : }
2300 :
2301 : /* Adjust to the desired frequency resolution by averaging over spectral partitions for SID transmission */
2302 44303 : bandcombinepow( periodog, periodog_exp, sub( stopFFTbin, startBand ), part, npart, psize_inv, hFdCngDec->msPeriodog, &hFdCngDec->msPeriodog_exp );
2303 :
2304 :
2305 44303 : hFdCngDec->msPeriodog_exp_fft = hFdCngDec->msPeriodog_exp;
2306 44303 : move16();
2307 44303 : hFdCngDec->msPeriodog_exp_cldfb = hFdCngDec->msPeriodog_exp;
2308 44303 : move16();
2309 :
2310 :
2311 : /* Compress MS inputs */
2312 44303 : compress_range( hFdCngDec->msPeriodog, hFdCngDec->msPeriodog_exp, hFdCngDec->msLogPeriodog, npart );
2313 :
2314 : /* Call the minimum statistics routine for noise estimation */
2315 44303 : minimum_statistics_fx(
2316 : npart,
2317 : nFFTpart,
2318 : psize_norm,
2319 44303 : hFdCngDec->msLogPeriodog,
2320 44303 : hFdCngDec->msNoiseFloor_32fx,
2321 44303 : hFdCngDec->msLogNoiseEst_32fx,
2322 44303 : hFdCngDec->msAlpha,
2323 44303 : hFdCngDec->msPsd,
2324 44303 : hFdCngDec->msPsdFirstMoment,
2325 44303 : hFdCngDec->msPsdSecondMoment,
2326 44303 : hFdCngDec->msMinBuf,
2327 44303 : hFdCngDec->msBminWin,
2328 44303 : hFdCngDec->msBminSubWin,
2329 44303 : hFdCngDec->msCurrentMin,
2330 44303 : hFdCngDec->msCurrentMinOut,
2331 44303 : hFdCngDec->msCurrentMinSubWindow,
2332 44303 : hFdCngDec->msLocalMinFlag,
2333 44303 : hFdCngDec->msNewMinFlag,
2334 44303 : hFdCngDec->msPeriodogBuf,
2335 : &( hFdCngDec->msPeriodogBufPtr ),
2336 : hFdCngDec->hFdCngCom,
2337 : DEC, element_mode );
2338 :
2339 2766071 : FOR( i = 0; i < hFdCngDec->npart_shaping; i++ )
2340 : {
2341 2721768 : hFdCngDec->msPsd_fx[i] = (Word32) hFdCngDec->msPsd[i];
2342 2721768 : move32();
2343 : }
2344 44303 : hFdCngDec->msPsd_exp_fft = 6 + WORD16_BITS;
2345 44303 : move16();
2346 :
2347 : /* Expand MS outputs */
2348 44303 : expand_range_fx( hFdCngDec->msLogNoiseEst_32fx, hFdCngDec->msNoiseEst, &hFdCngDec->msNoiseEst_exp, npart );
2349 : }
2350 96725 : }
2351 :
2352 :
2353 : /*
2354 : FdCng_decodeSID_fx
2355 :
2356 : Parameters:
2357 :
2358 : st i/o: FD_CNG structure containing all buffers and variables
2359 : bs_word16 i : Bitstream
2360 : amrwb_io i : amr wideband mode
2361 : preemph_fac i : preemphase factor
2362 :
2363 : Function:
2364 : decode the FD-CNG bitstream
2365 :
2366 : Returns:
2367 : void
2368 : */
2369 0 : void FdCng_decodeSID_fx( HANDLE_FD_CNG_COM st, Decoder_State *corest )
2370 : {
2371 : Word16 i, N, index;
2372 : Word32 *sidNoiseEst;
2373 :
2374 : Word16 indices[32], v16[32];
2375 : Word32 v[32], gain;
2376 :
2377 : Word32 tmp, maxVal, E_ExpLd64;
2378 : Word16 sidNoiseEst_Exp;
2379 :
2380 : Word16 preemph_fac;
2381 : Word32 *invTrfMatrix_fx;
2382 : Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
2383 0 : invTrfMatrix_fx = (Word32 *) tmpRAM_fx;
2384 :
2385 :
2386 0 : sidNoiseEst = st->sidNoiseEst; /*Q31 - st->sidNoiseEstExp*/
2387 0 : move16();
2388 0 : preemph_fac = corest->preemph_fac; /*Q15*/
2389 0 : move16();
2390 :
2391 0 : N = st->npart; /*Q0*/
2392 0 : move16();
2393 :
2394 0 : st->sid_frame_counter = add( st->sid_frame_counter, 1 ); /*Q15*/
2395 0 : move16();
2396 :
2397 : /* Read bitstream */
2398 0 : FOR( i = 0; i < stages_37bits; i++ )
2399 : {
2400 0 : indices[i] = get_next_indice_fx( corest, bits_37bits[i] ); /*Q0*/
2401 0 : move16();
2402 : }
2403 0 : index = get_next_indice_fx( corest, 7 ); /*Q0*/
2404 :
2405 : /* MSVQ decoder */
2406 0 : IF( corest->element_mode != EVS_MONO )
2407 : {
2408 0 : create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC );
2409 0 : msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages_37bits, N, maxN_37bits, indices, 1, invTrfMatrix_fx, v, NULL, 7 );
2410 : }
2411 : ELSE
2412 : {
2413 0 : msvq_decoder(
2414 : cdk_37bits,
2415 : stages_37bits,
2416 : N,
2417 : maxN_37bits,
2418 : indices,
2419 : v16 );
2420 :
2421 0 : FOR( i = 0; i < N; i++ )
2422 : {
2423 0 : v[i] = L_deposit_h( v16[i] ); /*Q23*/
2424 0 : move32();
2425 : }
2426 : }
2427 :
2428 :
2429 : /* decode gain, format gain: Q9.23 */
2430 0 : gain = L_shl( L_deposit_l( index ), WORD32_BITS - 1 - 8 );
2431 0 : gain = L_sub( gain, 503316480l /*60.0 Q23*/ ); /*Q23*/
2432 0 : gain = Mpy_32_16_1( gain, 21845 /*2.0f/3.0f Q15*/ ); /*Q23*/
2433 :
2434 :
2435 : /* Apply gain and undo log */
2436 :
2437 : /* calculate worst case for scaling */
2438 0 : maxVal = L_add( 0x80000000 /*-1.0 Q31*/, 0 );
2439 0 : FOR( i = 0; i < N; i++ )
2440 : {
2441 0 : maxVal = L_max( maxVal, v[i] ); /*Q23*/
2442 : }
2443 :
2444 0 : maxVal = L_add( maxVal, gain ); /*Q23*/
2445 0 : maxVal = L_shl( Mpy_32_16_1( maxVal, 21771 /*0.66438561897 Q15*/ ), 1 ); /*Q23*/
2446 :
2447 0 : sidNoiseEst_Exp = 0;
2448 0 : move16();
2449 0 : FOR( ; maxVal >= 0; maxVal -= 33554432l /*0.015625 Q31*/ )
2450 : {
2451 0 : sidNoiseEst_Exp = add( sidNoiseEst_Exp, 1 );
2452 : }
2453 0 : st->sidNoiseEstExp = sidNoiseEst_Exp;
2454 0 : move16();
2455 0 : E_ExpLd64 = L_shl( sidNoiseEst_Exp, WORD32_BITS - 1 - LD_DATA_SCALE );
2456 :
2457 : /* format v: Q9.23, format sidNoiseEst: Q6.26, 0.66438561897 = log10(10)/log10(2.0) / 10.0 * 2.0 */
2458 0 : FOR( i = 0; i < N; i++ )
2459 : {
2460 0 : tmp = L_add( v[i], gain ); /*Q23*/
2461 0 : tmp = L_shl( Mpy_32_16_1( tmp, 21771 /*0.66438561897 Q15*/ ), 1 ); /*Q23*/
2462 0 : tmp = L_sub( tmp, E_ExpLd64 );
2463 0 : assert( tmp < 0 );
2464 0 : st->sidNoiseEst[i] = BASOP_Util_InvLog2( tmp ); /*Q31 - st->sidNoiseEstExp*/
2465 0 : move32();
2466 : }
2467 :
2468 : /* NB last band energy compensation */
2469 0 : IF( st->CngBandwidth == NB )
2470 : {
2471 0 : st->sidNoiseEst[( N - 1 )] = Mpy_32_16_1( st->sidNoiseEst[( N - 1 )], NB_LAST_BAND_SCALE ); /*Q31 - st->sidNoiseEstExp*/
2472 0 : move32();
2473 : }
2474 :
2475 0 : test();
2476 0 : IF( EQ_16( st->CngBandwidth, SWB ) && LE_32( st->CngBitrate, ACELP_13k20 ) )
2477 : {
2478 0 : st->sidNoiseEst[( N - 1 )] = Mpy_32_16_1( st->sidNoiseEst[( N - 1 )], SWB_13k2_LAST_BAND_SCALE ); /*Q31 - st->sidNoiseEstExp*/
2479 0 : move32();
2480 : }
2481 :
2482 :
2483 0 : scalebands( sidNoiseEst, st->part, st->npart, st->midband, st->nFFTpart, sub( st->stopBand, st->startBand ), st->cngNoiseLevel, 1 );
2484 0 : st->cngNoiseLevelExp = st->sidNoiseEstExp;
2485 0 : move16();
2486 :
2487 :
2488 0 : lpc_from_spectrum( st, st->startBand, st->stopFFTbin, preemph_fac );
2489 0 : }
2490 :
2491 : /*
2492 : noisy_speech_detection_fx
2493 :
2494 : Parameters:
2495 :
2496 : vad i : VAD decision
2497 : Etot i : total channel E
2498 : Etot_exp i : exponent for total channel E
2499 : totalNoise i : noise estimate over all critical bands
2500 : totalNoise_exp i : exponent for noise estimate over all critical bands
2501 : lp_noise i/o: pointer to long term total Noise energy average
2502 : lp_speech i/o: pointer to long term active speech energy average
2503 :
2504 : Function:
2505 : detector for noisy speech, lp_noise and lp_speech are scaled by LD_DATA_SCALE+2 bits
2506 :
2507 : Returns: flag, that indicates whether noisy speech has been detected
2508 :
2509 : void
2510 : */
2511 407785 : void noisy_speech_detection_fx(
2512 : HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure */
2513 : const Word16 vad, /*Q0*/
2514 : const Word16 *syn, /* i : input time-domain frame Q*/
2515 : const Word16 Q )
2516 : {
2517 : Word16 i;
2518 : Word32 tmp;
2519 : Word32 Etot;
2520 : Word16 Etot_exp;
2521 : Word32 logEtot;
2522 : Word32 logEtotExp;
2523 : Word32 totalNoise;
2524 : Word16 totalNoise_exp;
2525 : Word32 logTotalNoise;
2526 : Word32 logTotalNoiseExp;
2527 :
2528 :
2529 407785 : IF( vad == 0 )
2530 : {
2531 40062 : totalNoise = dotWord32_16_Mant32Exp( hFdCngDec->msNoiseEst, hFdCngDec->msNoiseEst_exp, hFdCngDec->psize_shaping_norm, hFdCngDec->psize_shaping_norm_exp, hFdCngDec->nFFTpart_shaping, &totalNoise_exp ); /*Q31 - totalNoise_exp*/
2532 :
2533 : /*
2534 : - logTotalNoise is scaled by LD_DATA_SCALE+2
2535 : - logTotalNoise = 10.0 * log10(totalNoise + DELTA);
2536 : - constant: -0.78125 = 10.0*log10(DELTA)/(1<<(LD_DATA_SCALE+2))
2537 : - constant: 0.75257498916 = 10.0 * log10(2.0)/log10(10.0)/(1<<2)
2538 : */
2539 40062 : IF( totalNoise == 0 )
2540 : {
2541 569 : logTotalNoise = L_add( -1677721600l /*-0.78125 Q31*/, 0 ); /*Q31*/
2542 : }
2543 : ELSE
2544 : {
2545 39493 : logTotalNoise = BASOP_Util_Log2( totalNoise ); /*Q25*/
2546 39493 : logTotalNoiseExp = L_shl( L_deposit_l( totalNoise_exp ), WORD32_BITS - 1 - LD_DATA_SCALE );
2547 39493 : logTotalNoise = Mpy_32_16_1( L_add( logTotalNoise, logTotalNoiseExp ), 24660 /*0.75257498916 Q15*/ ); /*Q31 - logTotalNoiseExp*/
2548 : }
2549 :
2550 40062 : hFdCngDec->lp_noise = L_add( Mpy_32_16_1( hFdCngDec->lp_noise, 32604 /*0.995 Q15*/ ), L_shr( Mpy_32_16_1( logTotalNoise, 20972 /*0.64 Q15*/ ), 7 ) ); /*hFdCngDec->q_lp_noise*/
2551 40062 : move32();
2552 : }
2553 : ELSE
2554 : {
2555 367723 : Etot = 0;
2556 367723 : move32();
2557 367723 : Etot_exp = 31;
2558 367723 : move16();
2559 111427563 : FOR( i = 0; i < hFdCngDec->hFdCngCom->frameSize; i++ )
2560 : {
2561 111059840 : tmp = L_shr_r( L_mult0( syn[i], syn[i] ), sub( Etot_exp, 31 ) ); /*2*(Q) - (Etot_exp - 31)*/
2562 111059840 : IF( LT_32( L_sub( maxWord32, tmp ), Etot ) )
2563 : {
2564 49343 : Etot_exp = add( Etot_exp, 1 );
2565 49343 : Etot = L_shr_r( Etot, 1 ); /*Q31 - Etot_exp*/
2566 49343 : tmp = L_shr_r( tmp, 1 );
2567 : }
2568 111059840 : Etot = L_add( Etot, tmp );
2569 : }
2570 367723 : Etot_exp = sub( Etot_exp, shl( Q, 1 ) );
2571 :
2572 : /*
2573 : - logEtot is scaled by LD_DATA_SCALE+2
2574 : - logEtot = 10.0 * log10(totalNoise + DELTA);
2575 : - constant: -0.78125 = 10.0*log10(DELTA)/(1<<(LD_DATA_SCALE+2))
2576 : - constant: 0.75257498916 = 10.0 * log10(2.0)/log10(10.0)/(1<<2)
2577 : */
2578 367723 : IF( Etot == 0 )
2579 : {
2580 3696 : logEtot = L_add( -1677721600l /*-0.78125 Q31*/, 0 ); /*Q31*/
2581 : }
2582 : ELSE
2583 : {
2584 364027 : logEtot = BASOP_Util_Log2( Etot ); /*Q25*/
2585 364027 : logEtotExp = L_shl( L_deposit_l( Etot_exp ), WORD32_BITS - 1 - LD_DATA_SCALE );
2586 364027 : logEtot = Mpy_32_16_1( L_add( logEtot, logEtotExp ), 24660 /*0.75257498916 Q15*/ ); /*Q31 - logEtotExp*/
2587 364027 : IF( EQ_16( hFdCngDec->hFdCngCom->frameSize, L_FRAME16k ) )
2588 : {
2589 260731 : logEtot = L_add( logEtot, -184894985l /*-0.086098436822497 Q31*/ ); /*Q31 - logEtotExp*/
2590 : }
2591 : ELSE
2592 : {
2593 103296 : logEtot = L_add( logEtot, -176765584l /*-0.082312889439370 Q31*/ ); /*Q31 - logEtotExp*/
2594 : }
2595 : }
2596 :
2597 367723 : hFdCngDec->lp_speech = L_add( Mpy_32_16_1( hFdCngDec->lp_speech, 32604 /*0.995 Q15*/ ), L_shr( Mpy_32_16_1( logEtot, 20972 /*0.64 Q15*/ ), 7 ) ); /*hFdCngDec->q_lp_speech*/
2598 367723 : move32();
2599 : }
2600 :
2601 407785 : tmp = L_sub( hFdCngDec->lp_speech, 377487360l /*45.0 Q23*/ ); /*Q23*/
2602 :
2603 407785 : if ( LT_32( hFdCngDec->lp_noise, tmp ) )
2604 : {
2605 182434 : hFdCngDec->lp_noise = tmp; /*Q23*/
2606 182434 : move32();
2607 : }
2608 :
2609 407785 : hFdCngDec->hFdCngCom->flag_noisy_speech = 0;
2610 407785 : move16();
2611 407785 : if ( LT_32( L_sub( hFdCngDec->lp_speech, hFdCngDec->lp_noise ), 234881024l /*28.0 Q23*/ ) )
2612 : {
2613 35020 : hFdCngDec->hFdCngCom->flag_noisy_speech = 1;
2614 35020 : move16();
2615 : }
2616 :
2617 :
2618 407785 : return;
2619 : }
2620 :
2621 0 : void generate_comfort_noise_dec_fx(
2622 : Word32 **bufferReal, /* o : matrix to real part of input bands bufferScale*/
2623 : Word32 **bufferImag, /* o : matrix to imaginary part of input bands bufferScale*/
2624 : Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */
2625 : Decoder_State *st,
2626 : Word16 *Q_new,
2627 : Word16 gen_exc, /*Q0*/
2628 : const Word16 nchan_out /* i : number of output channels Q0*/
2629 : )
2630 : {
2631 : Word16 i, j, s, sc, sn, cnt;
2632 : Word16 startBand2;
2633 : Word16 stopFFTbin2;
2634 : Word16 scaleCLDFB;
2635 : Word16 preemph_fac;
2636 : Word32 sqrtNoiseLevel;
2637 : Word16 randGaussExp;
2638 : Word16 fftBufferExp;
2639 : Word16 cngNoiseLevelExp;
2640 : Word16 *seed;
2641 : Word16 *timeDomainOutput;
2642 : Word32 *ptr_r, *ptr_i;
2643 : Word32 *cngNoiseLevel;
2644 : Word32 *ptr_level;
2645 : Word32 *fftBuffer;
2646 : Word16 old_syn_pe_tmp[16];
2647 0 : Word16 tcx_transition = 0;
2648 0 : HANDLE_FD_CNG_DEC hFdCngDec = st->hFdCngDec;
2649 0 : HANDLE_FD_CNG_COM hFdCngCom = hFdCngDec->hFdCngCom;
2650 : TCX_DEC_HANDLE hTcxDec;
2651 0 : move16();
2652 :
2653 0 : hTcxDec = st->hTcxDec;
2654 :
2655 : /* Warning fix */
2656 0 : s = 0;
2657 0 : move16();
2658 : // PMTE(); /*IVAS CODE need to be added */
2659 :
2660 : /* pointer initialization */
2661 :
2662 0 : cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
2663 0 : cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
2664 0 : ptr_level = cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
2665 0 : seed = &( hFdCngCom->seed );
2666 0 : fftBuffer = hFdCngCom->fftBuffer; /*Q31 - hFdCngCom->fftBuffer_exp*/
2667 0 : timeDomainOutput = hFdCngCom->timeDomainBuffer;
2668 :
2669 : /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
2670 0 : scaleCLDFB = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); /*CLDFBinvScalingFactor_EXP + 1*/
2671 :
2672 : /*
2673 : Generate Gaussian random noise in real and imaginary parts of the FFT bins
2674 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
2675 : scaling Gaussian random noise: format Q3.29
2676 : */
2677 0 : sn = 0;
2678 0 : move16();
2679 0 : IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
2680 : {
2681 0 : sn = add( sn, 1 );
2682 0 : cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
2683 0 : move16();
2684 : }
2685 :
2686 0 : randGaussExp = CNG_RAND_GAUSS_SHIFT;
2687 0 : move16();
2688 0 : cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
2689 0 : IF( hFdCngCom->startBand == 0 )
2690 : {
2691 : /* DC component in FFT */
2692 0 : s = 0;
2693 0 : move16();
2694 0 : sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s ); /*Q31 - s*/
2695 :
2696 0 : fftBuffer[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*Q31 - hFdCngCom->fftBuffer_exp*/
2697 0 : move32();
2698 :
2699 : /* Nyquist frequency is discarded */
2700 0 : fftBuffer[1] = L_deposit_l( 0 );
2701 :
2702 0 : ptr_level = ptr_level + 1;
2703 0 : ptr_r = fftBuffer + 2; /*Q31 - hFdCngCom->fftBuffer_exp*/
2704 0 : cnt = sub( cnt, 1 );
2705 : }
2706 : ELSE
2707 : {
2708 0 : startBand2 = shl( hFdCngCom->startBand, 1 ); /*Q0*/
2709 0 : set32_fx( fftBuffer, 0, startBand2 );
2710 0 : ptr_r = fftBuffer + startBand2; /*Q31 - hFdCngCom->fftBuffer_exp*/
2711 : }
2712 :
2713 0 : sn = add( sn, 1 );
2714 0 : ptr_i = ptr_r + 1; /*Q31 - hFdCngCom->fftBuffer_exp*/
2715 0 : FOR( i = 0; i < cnt; i++ )
2716 : {
2717 0 : s = 0;
2718 0 : move16();
2719 0 : sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s ); /*Q31 - s*/
2720 :
2721 : /* Real part in FFT bins */
2722 0 : *ptr_r = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
2723 0 : move32();
2724 :
2725 : /* Imaginary part in FFT bins */
2726 0 : *ptr_i = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
2727 0 : move32();
2728 :
2729 0 : ptr_r = ptr_r + 2;
2730 0 : ptr_i = ptr_i + 2;
2731 0 : ptr_level = ptr_level + 1;
2732 : }
2733 :
2734 : /* Remaining FFT bins are set to zero */
2735 0 : stopFFTbin2 = shl( hFdCngCom->stopFFTbin, 1 );
2736 0 : set32_fx( fftBuffer + stopFFTbin2, 0, sub( hFdCngCom->fftlen, stopFFTbin2 ) );
2737 :
2738 0 : fftBufferExp = add( shr( cngNoiseLevelExp, 1 ), randGaussExp );
2739 :
2740 : /* If previous frame is active, reset the overlap-add buffer */
2741 0 : IF( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) )
2742 : {
2743 0 : set16_fx( hFdCngCom->olapBufferSynth, 0, hFdCngCom->fftlen );
2744 0 : test();
2745 0 : test();
2746 0 : if ( ( st->last_core_bfi > ACELP_CORE && EQ_16( st->codec_mode, MODE2 ) ) || EQ_16( st->codec_mode, MODE1 ) )
2747 : {
2748 0 : tcx_transition = 1;
2749 0 : move16();
2750 : }
2751 : }
2752 :
2753 : /* Perform STFT synthesis */
2754 0 : SynthesisSTFT( fftBuffer, fftBufferExp, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn,
2755 0 : tcx_transition, hFdCngCom, gen_exc, Q_new, st->element_mode, nchan_out );
2756 :
2757 : {
2758 : Word32 Lener, att;
2759 : Word16 exp;
2760 : /* update CNG excitation energy for LP_CNG */
2761 :
2762 : /* calculate the residual signal energy */
2763 : /*enr = dotp( hFdCngCom->exc_cng, hFdCngCom->exc_cng, hFdCngCom->frameSize ) / hFdCngCom->frameSize;*/
2764 0 : Lener = Dot_productSq16HQ( 1, hFdCngCom->exc_cng, st->L_frame, &exp ); /*Q31 - exp*/
2765 0 : exp = add( sub( shl( sub( 15, *Q_new ), 1 ), 8 ), exp ); /*8 = log2(256)*/
2766 :
2767 : /* convert log2 of residual signal energy */
2768 : /*(float)log10( enr + 0.1f ) / (float)log10( 2.0f );*/
2769 0 : Lener = BASOP_Util_Log2( Lener ); /*Q25*/
2770 0 : Lener = L_add( Lener, L_shl( L_deposit_l( exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/
2771 0 : if ( EQ_16( st->L_frame, L_FRAME16k ) )
2772 : {
2773 0 : Lener = L_sub( Lener, 10802114l /*0.3219280949f Q25*/ ); /*log2(320) = 8.3219280949f Q25*/
2774 : }
2775 : /* decrease the energy in case of WB input */
2776 0 : IF( st->bwidth != NB )
2777 : {
2778 0 : IF( EQ_16( st->bwidth, WB ) )
2779 : {
2780 0 : IF( st->CNG_mode >= 0 )
2781 : {
2782 : /* Bitrate adapted attenuation */
2783 0 : att = L_shl( L_deposit_l( ENR_ATT_fx[st->CNG_mode] ), 17 ); /*Q23*/
2784 : }
2785 : ELSE
2786 : {
2787 : /* Use least attenuation for higher bitrates */
2788 0 : att = L_shl( L_deposit_l( ENR_ATT_fx[4] ), 17 ); /*Q23*/
2789 : }
2790 : }
2791 : ELSE
2792 : {
2793 0 : att = 384 << 17; /*1.5 Q8<<17=Q25*/
2794 0 : move16();
2795 : }
2796 0 : Lener = L_sub( Lener, att ); /*Q23*/
2797 : }
2798 : /*st->lp_ener = 0.8f * stcod->lp_ener + 0.2f * pow( 2.0f, enr );*/
2799 0 : Lener = BASOP_util_Pow2( Lener, 6, &exp ); /*Q31 - exp*/
2800 0 : Lener = Mult_32_16( Lener, 6554 /*0.2f Q15*/ ); /*Q31 - exp*/
2801 0 : exp = sub( 25, exp );
2802 0 : Lener = L_shr( Lener, exp ); /*Q6*/
2803 0 : st->lp_ener_fx = L_add( Mult_32_16( st->lp_ener_fx, 26214 /*0.8f Q15*/ ), Lener ); /*Q6*/
2804 0 : move32();
2805 : }
2806 :
2807 : /*
2808 : Generate Gaussian random noise in real and imaginary parts of the CLDFB bands
2809 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each band
2810 : */
2811 0 : test();
2812 0 : IF( bufferReal != NULL && ( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) ) )
2813 : {
2814 :
2815 0 : sn = sub( sn, 1 );
2816 0 : sc = add( shr( add( cngNoiseLevelExp, CLDFBinvScalingFactor_EXP + 1 - 1 ), 1 ), randGaussExp );
2817 0 : move16();
2818 0 : assert( ( ( cngNoiseLevelExp + CLDFBinvScalingFactor_EXP + 1 - 1 ) & 1 ) == 0 );
2819 :
2820 0 : FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
2821 : {
2822 : /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
2823 0 : s = 0;
2824 0 : move16();
2825 0 : sqrtNoiseLevel = Sqrt32( L_shr( Mpy_32_16_1( *ptr_level, scaleCLDFB ), sn ), &s ); /*Q31 - s*/
2826 :
2827 0 : FOR( i = 0; i < hFdCngCom->numSlots; i++ )
2828 : {
2829 : /* Real part in CLDFB band */
2830 0 : bufferReal[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*bufferScale*/
2831 0 : move32();
2832 : /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferReal[i][j],sc));*/
2833 :
2834 : /* Imaginary part in CLDFB band */
2835 0 : bufferImag[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*bufferScale*/
2836 0 : move32();
2837 : /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferImag[i][j],sc));*/
2838 : }
2839 0 : ptr_level = ptr_level + 1;
2840 : }
2841 0 : *bufferScale = sub( sc, 15 );
2842 0 : move16();
2843 : }
2844 :
2845 : /* Overlap-add when previous frame is active */
2846 0 : test();
2847 0 : IF( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) && EQ_16( st->codec_mode, MODE2 ) )
2848 : {
2849 : Word32 old_exc_ener, gain, noise32;
2850 : Word16 seed_loc, lpcorder, old_syn, tmp, gain16, N, N2, N4, N8;
2851 : Word16 old_exc_ener_exp, gain_exp;
2852 : Word16 normFacE, normShiftE, normShiftEM1;
2853 : Word16 normFacG, normShiftG, normShiftGM1;
2854 : Word16 noiseExp, *old_exc, *old_Aq, *old_syn_pe;
2855 : Word16 noise[640], normShiftP2;
2856 : Word16 Q_exc, Q_syn;
2857 :
2858 :
2859 0 : assert( hFdCngCom->frameSize <= 640 );
2860 :
2861 0 : seed_loc = hFdCngCom->seed;
2862 0 : move16();
2863 0 : N = hFdCngCom->frameSize; /*Q0*/
2864 0 : move16();
2865 0 : N2 = shr( hFdCngCom->frameSize, 1 );
2866 :
2867 0 : IF( st->last_core_bfi > ACELP_CORE )
2868 : {
2869 : Word16 left_overlap_mode;
2870 0 : left_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode; /*Q0*/
2871 0 : move16();
2872 0 : if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
2873 : {
2874 0 : left_overlap_mode = FULL_OVERLAP;
2875 0 : move16();
2876 : }
2877 0 : tcx_windowing_synthesis_current_frame( timeDomainOutput, st->hTcxCfg->tcx_mdct_window, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length,
2878 0 : st->hTcxCfg->tcx_mdct_window_min_length, 0, left_overlap_mode, NULL, NULL, NULL, NULL, NULL, shr( N, 1 ), shr( sub( abs_s( st->hTcxCfg->tcx_offset ), st->hTcxCfg->tcx_offset ), 1 ), 1, 0, 0 );
2879 :
2880 0 : IF( st->hTcxCfg->last_aldo != 0 )
2881 : {
2882 0 : FOR( i = 0; i < hFdCngCom->frameSize - NS2SA( st->sr_core, N_ZERO_MDCT_NS ); i++ )
2883 : {
2884 0 : timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( st->hHQ_core->old_out_LB_fx[i + NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS )], st->hHQ_core->Q_old_wtda_LB ) ); /*st->q_old_outLB_fx*/
2885 0 : move16();
2886 : }
2887 : }
2888 : ELSE
2889 : {
2890 0 : tcx_windowing_synthesis_past_frame( hTcxDec->syn_Overl, st->hTcxCfg->tcx_mdct_window, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum,
2891 0 : st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_last_overlap_mode );
2892 :
2893 0 : FOR( i = 0; i < st->hTcxCfg->tcx_mdct_window_length; i++ )
2894 : {
2895 0 : timeDomainOutput[i] = add( timeDomainOutput[i], shl( hTcxDec->syn_Overl[i], TCX_IMDCT_HEADROOM ) ); /*st->q_old_outLB_fx*/
2896 0 : move16();
2897 : }
2898 : }
2899 : }
2900 : ELSE
2901 : {
2902 :
2903 : /*
2904 : - the scaling of the LPCs (e.g. old_Aq) is always Q12 (encoder or decoder)
2905 :
2906 : - the scaling of the deemphasized signals (e.g. old_syn) is always Q0 (encoder or decoder)
2907 :
2908 : - the scaling of the excitation signals in the encoder (e.g. old_exc) is Q_new
2909 : - the scaling of the preemphasized signals in the encoder (e.g. old_syn_pe) is Q_new-1
2910 :
2911 : - the scaling of the excitation signals in the decoder (e.g. old_exc) is Q_exc (or stdec->Q_exc)
2912 : - the scaling of the preemphasized signals in the decoder (e.g. old_syn_pe) is Q_syn (or stdec->Q_syn)
2913 : */
2914 :
2915 0 : lpcorder = M;
2916 0 : move16();
2917 0 : old_Aq = st->old_Aq_12_8_fx; /*Q12*/
2918 0 : old_exc = st->old_exc_fx + sub( L_EXC_MEM_DEC, N2 ); /*Q_exc*/
2919 0 : old_syn_pe = st->mem_syn2_fx; /*Q_syn*/
2920 0 : old_syn = st->syn[lpcorder]; /*Q_syn*/
2921 0 : move16();
2922 0 : preemph_fac = st->preemph_fac; /*Q15*/
2923 0 : move16();
2924 0 : Q_exc = st->Q_exc;
2925 0 : move16();
2926 0 : Q_syn = st->Q_syn;
2927 0 : move16();
2928 :
2929 : /* shift to be in the range of values supported by getNormReciprocalWord16() */
2930 0 : N8 = shr( N2, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
2931 :
2932 0 : assert( N2 == ( N8 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
2933 :
2934 0 : normFacE = getNormReciprocalWord16( N8 );
2935 0 : normShiftE = BASOP_util_norm_s_bands2shift( N8 );
2936 0 : normShiftEM1 = sub( normShiftE, 1 );
2937 0 : normShiftP2 = add( normShiftE, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
2938 :
2939 0 : old_exc_ener = L_shr( L_mult( old_exc[0], old_exc[0] ), normShiftP2 ); /*2*(Q_exc)+1+normShiftP2*/
2940 0 : FOR( i = 1; i < N2; i++ )
2941 : {
2942 0 : old_exc_ener = L_add( old_exc_ener, L_shr( L_mult( old_exc[i], old_exc[i] ), normShiftP2 ) ); /*2*(Q_exc)+1+normShiftP2*/
2943 : }
2944 0 : old_exc_ener = L_shl( Mpy_32_16_1( old_exc_ener, shl( normFacE, normShiftEM1 ) ), 1 ); /*Q31*/
2945 :
2946 0 : old_exc_ener_exp = 0;
2947 0 : move16();
2948 0 : old_exc_ener = Sqrt32( old_exc_ener, &old_exc_ener_exp ); /*Q31 - old_exc_ener_exp*/
2949 0 : old_exc_ener_exp = add( old_exc_ener_exp, ( sub( 15, Q_exc ) ) );
2950 :
2951 : /* shift to be in the range of values supported by getNormReciprocalWord16() */
2952 0 : N4 = shr( N, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
2953 :
2954 0 : assert( N == ( N4 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
2955 :
2956 0 : normFacG = getNormReciprocalWord16( N4 );
2957 0 : normShiftG = BASOP_util_norm_s_bands2shift( N4 );
2958 0 : normShiftGM1 = sub( normShiftG, 1 );
2959 0 : normShiftP2 = add( normShiftG, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
2960 :
2961 0 : gain = L_deposit_l( 0 );
2962 0 : FOR( i = 0; i < N; i++ )
2963 : {
2964 0 : noise32 = rand_gauss( &seed_loc );
2965 0 : noise[i] = extract_h( noise32 );
2966 0 : move16();
2967 0 : gain = L_add( gain, L_shr( L_mult( noise[i], noise[i] ), normShiftP2 ) );
2968 : }
2969 0 : gain = L_shl( Mpy_32_16_1( gain, shl( normFacG, normShiftGM1 ) ), 1 ); /*Q31 - gain_exp*/
2970 :
2971 0 : gain_exp = 2 * CNG_RAND_GAUSS_SHIFT;
2972 0 : move16();
2973 0 : gain = ISqrt32( gain, &gain_exp ); /*Q31 - gain_exp*/
2974 :
2975 0 : gain = Mpy_32_32( old_exc_ener, gain ); /*Q31 - old_exc_ener_exp - gain_exp*/
2976 0 : gain16 = extract_h( gain ); /*Q15 - old_exc_ener_exp - gain_exp*/
2977 :
2978 0 : gain_exp = add( old_exc_ener_exp, gain_exp );
2979 0 : noiseExp = add( CNG_RAND_GAUSS_SHIFT, gain_exp );
2980 :
2981 0 : s = sub( 15 - NOISE_HEADROOM, noiseExp );
2982 0 : FOR( i = 0; i < N; i++ )
2983 : {
2984 0 : noise[i] = shr_sat( mult( noise[i], gain16 ), s ); /*Q15 - noiseExp*/
2985 0 : move16();
2986 : }
2987 :
2988 0 : assert( lpcorder <= 16 );
2989 :
2990 0 : s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) );
2991 0 : FOR( i = 0; i < lpcorder; i++ )
2992 : {
2993 0 : old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s ); /*Q0*/
2994 0 : move16();
2995 : }
2996 :
2997 0 : E_UTIL_synthesis(
2998 : 0, /* i : scaling to apply for a[0] Q0 */
2999 : old_Aq, /* i : LP filter coefficients Q12 */
3000 : noise, /* i : input signal Qx */
3001 : noise, /* o : output signal Qx-s */
3002 : N, /* i : size of filtering Q0 */
3003 : old_syn_pe_tmp, /* i/o: memory associated with this filtering. Q0 */
3004 : 0, /* i : 0=no update, 1=update of memory. Q0 */
3005 : lpcorder /* i : order of LP filter Q0 */
3006 : );
3007 :
3008 0 : tmp = old_syn;
3009 0 : move16();
3010 :
3011 0 : E_UTIL_deemph2(
3012 : NOISE_HEADROOM,
3013 : noise, /* I/O: signal Qx */
3014 : preemph_fac, /* I: deemphasis factor Qx */
3015 : N, /* I: vector size */
3016 : &tmp /* I/O: memory (signal[-1]) Qx */
3017 : );
3018 :
3019 0 : FOR( i = 0; i < N4; i++ )
3020 : {
3021 0 : tmp = mult( noise[i], hFdCngCom->olapWinSyn[i].v.re ); /*Q15 - noiseExp*/
3022 0 : timeDomainOutput[i] = add( timeDomainOutput[i], tmp );
3023 0 : move16();
3024 0 : tmp = mult( noise[( i + N4 )], hFdCngCom->olapWinSyn[( ( N4 - 1 ) - i )].v.im ); /*Q15 - noiseExp*/
3025 0 : timeDomainOutput[( i + N4 )] = add( timeDomainOutput[( i + N4 )], tmp );
3026 0 : move16();
3027 : }
3028 : }
3029 : }
3030 0 : }
3031 :
3032 18381 : void generate_comfort_noise_dec_ivas_fx(
3033 : Word32 **bufferReal, /* o : Real part of input bands bufferScale*/
3034 : Word32 **bufferImag, /* o : Imaginary part of input bands bufferScale*/
3035 : Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */
3036 : Decoder_State *st, /* i/o: decoder state structure */
3037 : Word16 *Q_new,
3038 : Word16 gen_exc, /*Q0*/
3039 : const Word16 nchan_out /* i : number of output channels Q0*/
3040 : )
3041 : {
3042 : Word16 i, j, s;
3043 : Word32 *ptr_r, *ptr_i;
3044 18381 : HANDLE_FD_CNG_DEC hFdCngDec = st->hFdCngDec;
3045 18381 : HANDLE_FD_CNG_COM hFdCngCom = hFdCngDec->hFdCngCom;
3046 18381 : Word32 *cngNoiseLevel = hFdCngCom->cngNoiseLevel;
3047 18381 : Word16 cngNoiseLevel_exp = hFdCngCom->cngNoiseLevelExp;
3048 18381 : move16();
3049 :
3050 18381 : Word32 *ptr_level = cngNoiseLevel;
3051 18381 : Word16 *seed = &( hFdCngCom->seed );
3052 : Word16 *seed2;
3053 : Word16 c1, c2;
3054 : Word32 tmp1, tmp2;
3055 : Word16 scaleCldfb;
3056 18381 : Word32 *fftBuffer = hFdCngCom->fftBuffer; /*hFdCngCom->fftBuffer_exp*/
3057 : Word16 fftBuffer_exp, fftBuffer_exp2;
3058 18381 : fftBuffer_exp = hFdCngCom->fftBuffer_exp;
3059 18381 : move16();
3060 : Word16 fftBuffer_temp_exp[FFTLEN];
3061 18381 : Word16 *timeDomainOutput = hFdCngCom->timeDomainBuffer;
3062 : Word16 temp;
3063 : Word32 sqrtNoiseLevel;
3064 : Word16 sqrtNoiseLevel_exp;
3065 18381 : Word16 idx = 0;
3066 18381 : move16();
3067 : Word16 preemph_fac;
3068 : Word16 old_syn_pe_tmp[16];
3069 18381 : Word16 tcx_transition = 0;
3070 : TCX_DEC_HANDLE hTcxDec;
3071 18381 : move16();
3072 :
3073 18381 : hTcxDec = st->hTcxDec;
3074 :
3075 18381 : scaleCldfb = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); /*CLDFBinvScalingFactor_EXP + 1*/
3076 :
3077 18381 : temp = 0;
3078 18381 : move16();
3079 18381 : c1 = Sqrt16( hFdCngCom->coherence_fx, &temp ); /*Q15 - temp*/
3080 18381 : c1 = shl( c1, temp ); /*Q15*/
3081 18381 : temp = 0;
3082 18381 : move16();
3083 18381 : c2 = Sqrt16( sub( MAX_16, hFdCngCom->coherence_fx ), &temp ); /*Q15 - temp*/
3084 18381 : c2 = shl( c2, temp ); /*Q15*/
3085 :
3086 18381 : temp = getScaleFactor32( fftBuffer, FFTLEN );
3087 18381 : scale_sig32( fftBuffer, FFTLEN, temp ); /*Q31 - hFdCngCom->fftBuffer_exp + temp*/
3088 18381 : fftBuffer_exp = sub( fftBuffer_exp, temp );
3089 18381 : hFdCngCom->fftBuffer_exp = fftBuffer_exp;
3090 18381 : move16();
3091 18381 : set16_fx( fftBuffer_temp_exp, fftBuffer_exp, FFTLEN );
3092 18381 : fftBuffer_exp2 = fftBuffer_exp;
3093 18381 : move16();
3094 18381 : fftBuffer_exp = 0;
3095 18381 : move16();
3096 :
3097 18381 : seed2 = &( hFdCngCom->seed2 );
3098 18381 : test();
3099 18381 : if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( st->idchan, 1 ) )
3100 : {
3101 3082 : seed2 = &( hFdCngCom->seed3 );
3102 : }
3103 :
3104 : /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
3105 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */
3106 :
3107 18381 : IF( hFdCngCom->startBand == 0 )
3108 : {
3109 0 : test();
3110 0 : test();
3111 0 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
3112 : {
3113 0 : rand_gauss_fx( &tmp1, seed, Q15 );
3114 0 : rand_gauss_fx( &tmp2, seed2, Q15 );
3115 0 : fftBuffer[0] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q0*/
3116 0 : move32();
3117 0 : fftBuffer_temp_exp[0] = Q16 + Q15;
3118 0 : move16();
3119 : }
3120 : ELSE
3121 : {
3122 0 : rand_gauss_fx( &fftBuffer[0], seed, Q15 );
3123 0 : fftBuffer_temp_exp[0] = Q16;
3124 0 : move16();
3125 : }
3126 0 : sqrtNoiseLevel_exp = cngNoiseLevel_exp;
3127 0 : move16();
3128 0 : sqrtNoiseLevel = Sqrt32( *ptr_level, &sqrtNoiseLevel_exp ); /*Q31 - sqrtNoiseLevel_exp*/
3129 0 : fftBuffer[0] = Mpy_32_32( fftBuffer[0], sqrtNoiseLevel ); /*Q31 - (sqrtNoiseLevel_exp + fftBuffer_temp_exp[0])*/
3130 0 : move32();
3131 0 : fftBuffer_temp_exp[0] = add( sqrtNoiseLevel_exp, fftBuffer_temp_exp[0] );
3132 0 : move16();
3133 0 : ptr_level++;
3134 0 : ptr_r = fftBuffer + 2; /*Q31 - (fftBuffer_temp_exp)*/
3135 0 : idx = 2;
3136 : }
3137 : ELSE
3138 : {
3139 18381 : fftBuffer[0] = 0;
3140 18381 : move16();
3141 18381 : set32_fx( fftBuffer + 2, 0, shl( sub( hFdCngCom->startBand, 1 ), 1 ) );
3142 18381 : ptr_r = fftBuffer + shl( hFdCngCom->startBand, 1 ); /*Q31 - fftBuffer_exp*/
3143 18381 : idx = shl( hFdCngCom->startBand, 1 ); /*Q0*/
3144 : }
3145 :
3146 18381 : ptr_i = ptr_r + 1; /*Q31 - fftBuffer_exp*/
3147 5423539 : FOR( ; ptr_level < cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); ptr_level++ )
3148 : {
3149 : /* Real part in FFT bins */
3150 5405158 : test();
3151 5405158 : test();
3152 5405158 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
3153 : {
3154 3683416 : rand_gauss_fx( &tmp1, seed, Q15 ); /*Q15*/
3155 3683416 : rand_gauss_fx( &tmp2, seed2, Q15 ); /*Q15*/
3156 3683416 : *ptr_r = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q15*/
3157 3683416 : move32();
3158 3683416 : fftBuffer_temp_exp[idx] = Q16;
3159 3683416 : move16();
3160 : }
3161 : ELSE
3162 : {
3163 1721742 : rand_gauss_fx( ptr_r, seed, Q15 ); /*Q15*/
3164 1721742 : fftBuffer_temp_exp[idx] = Q16;
3165 1721742 : move16();
3166 : }
3167 :
3168 5405158 : sqrtNoiseLevel_exp = sub( cngNoiseLevel_exp, 1 );
3169 5405158 : sqrtNoiseLevel = Sqrt32( *ptr_level, &sqrtNoiseLevel_exp ); /*Q31 - sqrtNoiseLevel_exp*/
3170 5405158 : ( *ptr_r ) = Mpy_32_32( ( *ptr_r ), sqrtNoiseLevel ); /*Q15 - sqrtNoiseLevel_exp*/
3171 5405158 : move32();
3172 5405158 : fftBuffer_temp_exp[idx] = add( fftBuffer_temp_exp[idx], sqrtNoiseLevel_exp );
3173 5405158 : move16();
3174 5405158 : idx = add( idx, 1 );
3175 5405158 : ptr_r += 2;
3176 :
3177 : /* Imaginary part in FFT bins */
3178 5405158 : test();
3179 5405158 : test();
3180 5405158 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
3181 : {
3182 3683416 : rand_gauss_fx( &tmp1, seed, Q15 ); /*Q15*/
3183 3683416 : rand_gauss_fx( &tmp2, seed2, Q15 ); /*Q15*/
3184 3683416 : *ptr_i = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q15*/
3185 3683416 : move32();
3186 3683416 : fftBuffer_temp_exp[idx] = Q16;
3187 3683416 : move16();
3188 : }
3189 : ELSE
3190 : {
3191 1721742 : rand_gauss_fx( ptr_i, seed, Q15 ); /*Q15*/
3192 1721742 : fftBuffer_temp_exp[idx] = Q16;
3193 1721742 : move16();
3194 : }
3195 5405158 : sqrtNoiseLevel_exp = sub( cngNoiseLevel_exp, 1 );
3196 5405158 : sqrtNoiseLevel = Sqrt32( *ptr_level, &sqrtNoiseLevel_exp ); /*Q31 - sqrtNoiseLevel_exp*/
3197 5405158 : ( *ptr_i ) = Mpy_32_32( ( *ptr_i ), sqrtNoiseLevel ); /*Q15 - sqrtNoiseLevel_exp*/
3198 5405158 : move32();
3199 5405158 : fftBuffer_temp_exp[idx] = add( fftBuffer_temp_exp[idx], sqrtNoiseLevel_exp );
3200 5405158 : move16();
3201 5405158 : idx = add( idx, 1 );
3202 5405158 : ptr_i += 2;
3203 : }
3204 :
3205 : /* Remaining FFT bins are set to zero */
3206 18381 : set32_fx( fftBuffer + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) );
3207 18381 : set16_fx( fftBuffer_temp_exp + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) );
3208 :
3209 : /* Nyquist frequency is discarded */
3210 18381 : fftBuffer[1] = 0;
3211 18381 : move32();
3212 :
3213 18381 : fftBuffer_exp = MAX_16;
3214 18381 : move16();
3215 10905293 : FOR( i = 0; i < hFdCngCom->fftlen; i++ )
3216 : {
3217 10886912 : IF( fftBuffer[i] != 0 )
3218 : {
3219 9048217 : fftBuffer_exp = s_min( fftBuffer_exp, add( sub( 31, fftBuffer_temp_exp[i] ), norm_l( fftBuffer[i] ) ) );
3220 : }
3221 : }
3222 18381 : if ( EQ_16( fftBuffer_exp, MAX_16 ) )
3223 : {
3224 1286 : fftBuffer_exp = 0;
3225 1286 : move16();
3226 : }
3227 18381 : fftBuffer_exp = sub( 31, fftBuffer_exp );
3228 10905293 : FOR( i = 0; i < hFdCngCom->fftlen; i++ )
3229 : {
3230 10886912 : fftBuffer[i] = L_shr( fftBuffer[i], sub( fftBuffer_exp, fftBuffer_temp_exp[i] ) ); /*Q31 - fftBuffer_temp_exp[i]*/
3231 10886912 : move32();
3232 : }
3233 :
3234 : /* If previous frame is active, reset the overlap-add buffer */
3235 18381 : tcx_transition = 0;
3236 18381 : move16();
3237 18381 : IF( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) )
3238 : {
3239 1772 : set16_fx( hFdCngCom->olapBufferSynth, 0, hFdCngCom->fftlen );
3240 1772 : test();
3241 1772 : test();
3242 1772 : if ( ( st->last_core_bfi > ACELP_CORE && EQ_16( st->codec_mode, MODE2 ) ) || EQ_16( st->codec_mode, MODE1 ) )
3243 : {
3244 1772 : tcx_transition = 1;
3245 1772 : move16();
3246 : }
3247 : }
3248 :
3249 : /* Perform STFT synthesis */
3250 18381 : SynthesisSTFT_ivas_fx( fftBuffer, fftBuffer_exp, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn,
3251 18381 : tcx_transition, hFdCngCom, gen_exc, Q_new, st->element_mode, nchan_out ); /* fftBuffer in hfDCngCom->fftBuffer_exp */
3252 : /* fftBuffer now in different Qs [0 to fftlen - 1] = hfDCngCom->fftBuffer_exp and [fftlen to FFTLEN(640)] = fftBuffer_exp2, bringing it in common exponent */
3253 18381 : Word16 shift1 = L_norm_arr( fftBuffer, hFdCngCom->fftlen );
3254 18381 : Word16 shift2 = L_norm_arr( fftBuffer + hFdCngCom->fftlen, sub( FFTLEN, hFdCngCom->fftlen ) );
3255 18381 : Word16 shift = s_max( sub( hFdCngCom->fftBuffer_exp, shift1 ), sub( fftBuffer_exp2, shift2 ) );
3256 :
3257 18381 : scale_sig32( fftBuffer, hFdCngCom->fftlen, sub( hFdCngCom->fftBuffer_exp, shift ) );
3258 18381 : scale_sig32( fftBuffer + hFdCngCom->fftlen, sub( FFTLEN, hFdCngCom->fftlen ), sub( fftBuffer_exp2, shift ) );
3259 18381 : hFdCngCom->fftBuffer_exp = shift;
3260 18381 : move16();
3261 : {
3262 : Word32 Lener, att;
3263 : Word16 exp;
3264 : /* update CNG excitation energy for LP_CNG */
3265 :
3266 : /* calculate the residual signal energy */
3267 : /*enr = dotp( hFdCngCom->exc_cng, hFdCngCom->exc_cng, hFdCngCom->frameSize ) / hFdCngCom->frameSize;*/
3268 18381 : Lener = Dot_productSq16HQ( 1, hFdCngCom->exc_cng, st->L_frame, &exp ); /*Q31 - exp*/
3269 18381 : exp = add( sub( shl( sub( 15, *Q_new ), 1 ), 8 ), exp ); /*8 = log2(256)*/
3270 :
3271 : /* convert log2 of residual signal energy */
3272 : /*(float)log10( enr + 0.1f ) / (float)log10( 2.0f );*/
3273 18381 : Lener = BASOP_Util_Log2( Lener ); /*Q25*/
3274 18381 : Lener = L_add( Lener, L_shl( L_deposit_l( exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/
3275 18381 : if ( EQ_16( st->L_frame, L_FRAME16k ) )
3276 : {
3277 11530 : Lener = L_sub( Lener, 10802114l /*0.3219280949f Q25*/ ); /*log2(320) = 8.3219280949f*/
3278 : }
3279 : /* decrease the energy in case of WB input */
3280 18381 : IF( st->bwidth != NB )
3281 : {
3282 18381 : IF( EQ_16( st->bwidth, WB ) )
3283 : {
3284 4090 : IF( st->CNG_mode >= 0 )
3285 : {
3286 : /* Bitrate adapted attenuation */
3287 1 : att = L_shl( L_deposit_l( ENR_ATT_fx[st->CNG_mode] ), 17 ); /*Q25*/
3288 : }
3289 : ELSE
3290 : {
3291 : /* Use least attenuation for higher bitrates */
3292 4089 : att = L_shl( L_deposit_l( ENR_ATT_fx[4] ), 17 ); /*Q25*/
3293 : }
3294 : }
3295 : ELSE
3296 : {
3297 14291 : att = 384 << 17; /*1.5 Q8<<17=Q25*/
3298 14291 : move16();
3299 : }
3300 18381 : Lener = L_sub( Lener, att );
3301 : }
3302 : /*st->lp_ener = 0.8f * stcod->lp_ener + 0.2f * pow( 2.0f, enr );*/
3303 18381 : Lener = BASOP_util_Pow2( Lener, 6, &exp ); /*Q31 - exp*/
3304 18381 : Lener = Mult_32_16( Lener, 6554 /*0.2f Q15*/ ); /*Q31 - exp*/
3305 18381 : exp = sub( 25, exp );
3306 18381 : Lener = L_shr( Lener, exp ); /*Q6*/
3307 18381 : st->lp_ener_fx = L_add( Mult_32_16( st->lp_ener_fx, 26214 /*0.8f Q15*/ ), Lener ); /*Q6*/
3308 18381 : move32();
3309 : }
3310 :
3311 : /* Generate Gaussian random noise in real and imaginary parts of the CLDFB bands
3312 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each band */
3313 :
3314 18381 : test();
3315 18381 : IF( bufferReal != NULL && ( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) ) )
3316 : {
3317 : Word16 bufferReal_exp[CLDFB_NO_COL_MAX];
3318 : Word16 bufferImag_exp[CLDFB_NO_COL_MAX];
3319 0 : *bufferScale = 0;
3320 0 : move16();
3321 0 : FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
3322 : {
3323 0 : sqrtNoiseLevel_exp = add( CLDFBinvScalingFactor_EXP, sub( cngNoiseLevel_exp, 1 ) );
3324 0 : sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *ptr_level, scaleCldfb ), &sqrtNoiseLevel_exp ); /*Q31 - sqrtNoiseLevel_exp*/
3325 :
3326 0 : FOR( i = 0; i < hFdCngCom->numSlots; i++ )
3327 : {
3328 : /* Real part in CLDFB band */
3329 0 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
3330 : {
3331 0 : rand_gauss_fx( &tmp1, seed, Q15 ); /*Q15*/
3332 0 : rand_gauss_fx( &tmp2, seed2, Q15 ); /*Q15*/
3333 0 : bufferReal[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q15*/
3334 0 : move32();
3335 0 : bufferReal_exp[j] = Q16;
3336 0 : move16();
3337 : }
3338 : ELSE
3339 : {
3340 0 : rand_gauss_fx( &bufferReal[i][j], seed, Q15 ); /*Q15*/
3341 0 : move32();
3342 0 : bufferReal_exp[j] = Q16;
3343 0 : move16();
3344 : }
3345 :
3346 0 : bufferReal[i][j] = Mpy_32_32( bufferReal[i][j], sqrtNoiseLevel ); /*Q31 - ( bufferReal_exp[j] + sqrtNoiseLevel_exp )*/
3347 0 : move32();
3348 0 : bufferReal_exp[j] = add( bufferReal_exp[j], sqrtNoiseLevel_exp );
3349 0 : move16();
3350 :
3351 : /* Imaginary part in CLDFB band */
3352 0 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
3353 : {
3354 0 : rand_gauss_fx( &tmp1, seed, Q15 ); /*Q15*/
3355 0 : rand_gauss_fx( &tmp2, seed2, Q15 ); /*Q15*/
3356 0 : bufferImag[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q15*/
3357 0 : move32();
3358 0 : bufferImag_exp[j] = Q16;
3359 0 : move16();
3360 : }
3361 : ELSE
3362 : {
3363 0 : rand_gauss_fx( &bufferImag[i][j], seed, Q15 ); /*Q15*/
3364 0 : bufferImag_exp[j] = Q16;
3365 0 : move16();
3366 : }
3367 0 : bufferImag[i][j] = Mpy_32_32( bufferImag[i][j], sqrtNoiseLevel ); /*Q31 - ( bufferReal_exp[j] + sqrtNoiseLevel_exp )*/
3368 0 : bufferImag_exp[j] = add( bufferImag_exp[j], sqrtNoiseLevel_exp );
3369 0 : move16();
3370 :
3371 0 : move32();
3372 : }
3373 0 : ptr_level++;
3374 : }
3375 :
3376 0 : FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
3377 : {
3378 0 : *bufferScale = s_max( *bufferScale, bufferReal_exp[j] );
3379 0 : move16();
3380 0 : *bufferScale = s_max( *bufferScale, bufferImag_exp[j] );
3381 0 : move16();
3382 : }
3383 :
3384 0 : FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
3385 : {
3386 0 : FOR( i = 0; i < hFdCngCom->numSlots; i++ )
3387 : {
3388 0 : bufferImag[i][j] = L_shr( bufferImag[i][j], sub( *bufferScale, bufferImag_exp[j] ) ); /*bufferImag_exp*/
3389 0 : move32();
3390 0 : bufferReal[i][j] = L_shr( bufferReal[i][j], sub( *bufferScale, bufferReal_exp[j] ) ); /*bufferReal_exp*/
3391 0 : move32();
3392 : }
3393 : }
3394 : }
3395 :
3396 18381 : test();
3397 18381 : IF( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) && EQ_16( st->codec_mode, MODE2 ) )
3398 : {
3399 : Word32 old_exc_ener, gain, noise32;
3400 : Word16 seed_loc, lpcorder, old_syn, tmp, gain16, N, N2, N4, N8;
3401 : Word16 old_exc_ener_exp, gain_exp;
3402 : Word16 normFacE, normShiftE, normShiftEM1;
3403 : Word16 normFacG, normShiftG, normShiftGM1;
3404 : Word16 noiseExp, *old_exc, *old_Aq, *old_syn_pe;
3405 : Word16 noise[640], normShiftP2;
3406 : Word16 Q_exc, Q_syn;
3407 :
3408 :
3409 0 : assert( hFdCngCom->frameSize <= 640 );
3410 :
3411 0 : seed_loc = hFdCngCom->seed; /*Q0*/
3412 0 : move16();
3413 0 : N = hFdCngCom->frameSize; /*Q0*/
3414 0 : move16();
3415 0 : N2 = shr( hFdCngCom->frameSize, 1 );
3416 :
3417 0 : IF( st->last_core_bfi > ACELP_CORE )
3418 : {
3419 : Word16 left_overlap_mode;
3420 0 : left_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode;
3421 0 : move16();
3422 0 : if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
3423 : {
3424 0 : left_overlap_mode = FULL_OVERLAP;
3425 0 : move16();
3426 : }
3427 0 : tcx_windowing_synthesis_current_frame( timeDomainOutput, st->hTcxCfg->tcx_mdct_window, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum, st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length,
3428 0 : st->hTcxCfg->tcx_mdct_window_min_length, 0, left_overlap_mode, NULL, NULL, NULL, NULL, NULL, shr( N, 1 ), shr( sub( abs_s( st->hTcxCfg->tcx_offset ), st->hTcxCfg->tcx_offset ), 1 ), 1, 0, 0 );
3429 :
3430 0 : IF( st->hTcxCfg->last_aldo != 0 )
3431 : {
3432 0 : FOR( i = 0; i < hFdCngCom->frameSize - NS2SA( st->sr_core, N_ZERO_MDCT_NS ); i++ )
3433 : {
3434 0 : timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( st->hHQ_core->old_out_LB_fx[i + NS2SA_FX2( st->sr_core, N_ZERO_MDCT_NS )], st->hHQ_core->Q_old_wtda_LB ) ); /*st->q_old_outLB_fx*/
3435 0 : move16();
3436 : }
3437 : }
3438 : ELSE
3439 : {
3440 0 : tcx_windowing_synthesis_past_frame( hTcxDec->syn_Overl, st->hTcxCfg->tcx_mdct_window, st->hTcxCfg->tcx_mdct_window_half, st->hTcxCfg->tcx_mdct_window_minimum,
3441 0 : st->hTcxCfg->tcx_mdct_window_length, st->hTcxCfg->tcx_mdct_window_half_length, st->hTcxCfg->tcx_mdct_window_min_length, st->hTcxCfg->tcx_last_overlap_mode );
3442 :
3443 0 : FOR( i = 0; i < st->hTcxCfg->tcx_mdct_window_length; i++ )
3444 : {
3445 0 : timeDomainOutput[i] = add( timeDomainOutput[i], shl( hTcxDec->syn_Overl[i], TCX_IMDCT_HEADROOM ) ); /*st->q_old_outLB_fx*/
3446 0 : move16();
3447 : }
3448 : }
3449 : }
3450 : ELSE
3451 : {
3452 :
3453 : /*
3454 : - the scaling of the LPCs (e.g. old_Aq) is always Q12 (encoder or decoder)
3455 :
3456 : - the scaling of the deemphasized signals (e.g. old_syn) is always Q0 (encoder or decoder)
3457 :
3458 : - the scaling of the excitation signals in the encoder (e.g. old_exc) is Q_new
3459 : - the scaling of the preemphasized signals in the encoder (e.g. old_syn_pe) is Q_new-1
3460 :
3461 : - the scaling of the excitation signals in the decoder (e.g. old_exc) is Q_exc (or stdec->Q_exc)
3462 : - the scaling of the preemphasized signals in the decoder (e.g. old_syn_pe) is Q_syn (or stdec->Q_syn)
3463 : */
3464 :
3465 0 : lpcorder = M;
3466 0 : move16();
3467 0 : old_Aq = st->old_Aq_12_8_fx; /*Q12*/
3468 0 : old_exc = st->old_exc_fx + sub( L_EXC_MEM_DEC, N2 ); /*Q_exc*/
3469 0 : old_syn_pe = st->mem_syn2_fx; /*Q_syn*/
3470 0 : old_syn = st->syn[lpcorder]; /*Q_syn*/
3471 0 : move16();
3472 0 : preemph_fac = st->preemph_fac; /*Q15*/
3473 0 : move16();
3474 0 : Q_exc = st->Q_exc;
3475 0 : move16();
3476 0 : Q_syn = st->Q_syn;
3477 0 : move16();
3478 :
3479 : /* shift to be in the range of values supported by getNormReciprocalWord16() */
3480 0 : N8 = shr( N2, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
3481 :
3482 0 : assert( N2 == ( N8 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
3483 :
3484 0 : normFacE = getNormReciprocalWord16( N8 );
3485 0 : normShiftE = BASOP_util_norm_s_bands2shift( N8 );
3486 0 : normShiftEM1 = sub( normShiftE, 1 );
3487 0 : normShiftP2 = add( normShiftE, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
3488 :
3489 0 : old_exc_ener = L_shr( L_mult( old_exc[0], old_exc[0] ), normShiftP2 ); /*2*(Q_exc)+1+normShiftP2*/
3490 0 : FOR( i = 1; i < N2; i++ )
3491 : {
3492 0 : old_exc_ener = L_add( old_exc_ener, L_shr( L_mult( old_exc[i], old_exc[i] ), normShiftP2 ) ); /*2*(Q_exc)+1+normShiftP2*/
3493 : }
3494 0 : old_exc_ener = L_shl( Mpy_32_16_1( old_exc_ener, shl( normFacE, normShiftEM1 ) ), 1 ); /*Q31*/
3495 :
3496 0 : old_exc_ener_exp = 0;
3497 0 : move16();
3498 0 : old_exc_ener = Sqrt32( old_exc_ener, &old_exc_ener_exp ); /*Q31 - old_exc_ener_exp*/
3499 0 : old_exc_ener_exp = add( old_exc_ener_exp, ( sub( 15, Q_exc ) ) );
3500 :
3501 : /* shift to be in the range of values supported by getNormReciprocalWord16() */
3502 0 : N4 = shr( N, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
3503 :
3504 0 : assert( N == ( N4 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
3505 :
3506 0 : normFacG = getNormReciprocalWord16( N4 );
3507 0 : normShiftG = BASOP_util_norm_s_bands2shift( N4 );
3508 0 : normShiftGM1 = sub( normShiftG, 1 );
3509 0 : normShiftP2 = add( normShiftG, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
3510 :
3511 0 : gain = L_deposit_l( 0 );
3512 0 : FOR( i = 0; i < N; i++ )
3513 : {
3514 0 : noise32 = rand_gauss( &seed_loc );
3515 0 : noise[i] = extract_h( noise32 );
3516 0 : move16();
3517 0 : gain = L_add( gain, L_shr( L_mult( noise[i], noise[i] ), normShiftP2 ) );
3518 : }
3519 0 : gain = L_shl( Mpy_32_16_1( gain, shl( normFacG, normShiftGM1 ) ), 1 ); /*Q31 - gain_exp*/
3520 :
3521 0 : gain_exp = 2 * CNG_RAND_GAUSS_SHIFT;
3522 0 : move16();
3523 0 : gain = ISqrt32( gain, &gain_exp ); /*Q31 - gain_exp*/
3524 :
3525 0 : gain = Mpy_32_32( old_exc_ener, gain ); /*Q31 - old_exc_ener_exp - gain_exp*/
3526 0 : gain16 = extract_h( gain ); /*Q15 - old_exc_ener_exp - gain_exp*/
3527 :
3528 0 : gain_exp = add( old_exc_ener_exp, gain_exp );
3529 0 : noiseExp = add( CNG_RAND_GAUSS_SHIFT, gain_exp );
3530 :
3531 0 : s = sub( 15 - NOISE_HEADROOM, noiseExp );
3532 0 : FOR( i = 0; i < N; i++ )
3533 : {
3534 0 : noise[i] = shr_sat( mult( noise[i], gain16 ), s ); /*Q15 - noiseExp*/
3535 0 : move16();
3536 : }
3537 :
3538 0 : assert( lpcorder <= 16 );
3539 :
3540 0 : s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) );
3541 0 : FOR( i = 0; i < lpcorder; i++ )
3542 : {
3543 0 : old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s ); /*Q0*/
3544 0 : move16();
3545 : }
3546 :
3547 0 : E_UTIL_synthesis(
3548 : 0, /* i : scaling to apply for a[0] Q0 */
3549 : old_Aq, /* i : LP filter coefficients Q12 */
3550 : noise, /* i : input signal Qx */
3551 : noise, /* o : output signal Qx-s */
3552 : N, /* i : size of filtering Q0 */
3553 : old_syn_pe_tmp, /* i/o: memory associated with this filtering. Q0 */
3554 : 0, /* i : 0=no update, 1=update of memory. Q0 */
3555 : lpcorder /* i : order of LP filter Q0 */
3556 : );
3557 :
3558 0 : tmp = old_syn;
3559 0 : move16();
3560 :
3561 0 : E_UTIL_deemph2(
3562 : NOISE_HEADROOM,
3563 : noise, /* I/O: signal Qx */
3564 : preemph_fac, /* I: deemphasis factor Qx */
3565 : N, /* I: vector size */
3566 : &tmp /* I/O: memory (signal[-1]) Qx */
3567 : );
3568 :
3569 0 : FOR( i = 0; i < N4; i++ )
3570 : {
3571 0 : tmp = mult( noise[i], hFdCngCom->olapWinSyn[i].v.re ); /*Q15 - noiseExp*/
3572 0 : timeDomainOutput[i] = add( timeDomainOutput[i], tmp );
3573 0 : move16();
3574 0 : tmp = mult( noise[( i + N4 )], hFdCngCom->olapWinSyn[( ( N4 - 1 ) - i )].v.im ); /*Q15 - noiseExp*/
3575 0 : timeDomainOutput[( i + N4 )] = add( timeDomainOutput[( i + N4 )], tmp );
3576 0 : move16();
3577 0 : move16();
3578 : }
3579 : }
3580 : }
3581 18381 : return;
3582 : }
3583 :
3584 0 : void generate_comfort_noise_dec_hf_fx(
3585 : Word32 **bufferReal, /* o : matrix to real part of input bands bufferScale*/
3586 : Word32 **bufferImag, /* o : matrix to imaginary part of input bands bufferScale*/
3587 : Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */
3588 : Decoder_State *st )
3589 : {
3590 : Word16 i, j, s, sc, sn;
3591 : Word16 scaleCLDFB;
3592 : Word32 sqrtNoiseLevel;
3593 : Word16 randGaussExp;
3594 : Word16 cngNoiseLevelExp;
3595 : Word16 *seed;
3596 : Word32 *cngNoiseLevel;
3597 : Word32 *ptr_level;
3598 0 : HANDLE_FD_CNG_COM hFdCngCom = st->hFdCngDec->hFdCngCom;
3599 :
3600 0 : cngNoiseLevel = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3601 0 : cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
3602 0 : move16();
3603 0 : ptr_level = cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3604 0 : seed = &( hFdCngCom->seed );
3605 :
3606 : /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
3607 0 : scaleCLDFB = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); /*CLDFBinvScalingFactor_EXP + 1*/
3608 :
3609 0 : sn = 0;
3610 0 : move16();
3611 0 : IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
3612 : {
3613 0 : sn = add( sn, 1 );
3614 0 : cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
3615 : }
3616 :
3617 0 : randGaussExp = CNG_RAND_GAUSS_SHIFT;
3618 0 : move16();
3619 :
3620 0 : IF( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) )
3621 : {
3622 :
3623 0 : sc = add( shr( add( cngNoiseLevelExp, CLDFBinvScalingFactor_EXP + 1 - 1 ), 1 ), randGaussExp );
3624 0 : move16();
3625 0 : assert( ( ( cngNoiseLevelExp + CLDFBinvScalingFactor_EXP + 1 - 1 ) & 1 ) == 0 );
3626 :
3627 0 : FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
3628 : {
3629 : /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
3630 0 : s = 0;
3631 0 : move16();
3632 0 : sqrtNoiseLevel = Sqrt32( L_shr( Mpy_32_16_1( *ptr_level, scaleCLDFB ), sn ), &s ); /*Q31 - s*/
3633 :
3634 0 : FOR( i = 0; i < hFdCngCom->numSlots; i++ )
3635 : {
3636 : /* Real part in CLDFB band */
3637 0 : bufferReal[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*bufferScale*/
3638 0 : move32();
3639 : /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferReal[i][j],sc));*/
3640 :
3641 : /* Imaginary part in CLDFB band */
3642 0 : bufferImag[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*bufferScale*/
3643 0 : move32();
3644 : /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferImag[i][j],sc));*/
3645 : }
3646 0 : ptr_level = ptr_level + 1; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3647 : }
3648 0 : *bufferScale = sub( sc, 15 );
3649 0 : move16();
3650 : }
3651 0 : }
3652 :
3653 15059 : void generate_comfort_noise_dec_hf_ivas_fx(
3654 : Word32 **bufferReal, /* o : matrix to real part of input bands bufferScale*/
3655 : Word32 **bufferImag, /* o : matrix to imaginary part of input bands bufferScale*/
3656 : Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */
3657 : HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
3658 : const Word16 cng_coh_flag /* i : CNG Flag for coherence handling Q0*/
3659 : )
3660 : {
3661 : Word16 i, j, s, sc, sn;
3662 : Word16 scaleCLDFB;
3663 : Word32 sqrtNoiseLevel;
3664 : Word16 randGaussExp;
3665 : Word16 cngNoiseLevelExp;
3666 : Word16 *seed;
3667 : Word16 *seed2;
3668 : Word16 c1, c2;
3669 : Word32 *ptr_level;
3670 : Word32 *cngNoiseLevel;
3671 : Word32 tmp1, tmp2;
3672 :
3673 15059 : cngNoiseLevel = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3674 15059 : cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
3675 15059 : move16();
3676 15059 : ptr_level = cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3677 :
3678 15059 : seed = &( hFdCngCom->seed );
3679 :
3680 : /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
3681 15059 : scaleCLDFB = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); /*CLDFBinvScalingFactor_EXP + 1*/
3682 :
3683 15059 : seed2 = &( hFdCngCom->seed );
3684 :
3685 15059 : c1 = 0;
3686 15059 : move16();
3687 15059 : c2 = 0;
3688 15059 : move16();
3689 15059 : sc = 0;
3690 15059 : move16();
3691 :
3692 15059 : IF( cng_coh_flag )
3693 : {
3694 5310 : seed2 = &( hFdCngCom->seed2 );
3695 :
3696 5310 : s = 0;
3697 5310 : move16();
3698 :
3699 5310 : c1 = Sqrt16( hFdCngCom->coherence_fx, &s ); /*Q15 - s*/
3700 5310 : c1 = shl( c1, s ); // Q15
3701 :
3702 5310 : s = 0;
3703 5310 : move16();
3704 5310 : c2 = Sqrt16( sub( MAX16B, hFdCngCom->coherence_fx ), &s ); /*Q15 - s*/
3705 5310 : c2 = shl( c2, s ); // Q15
3706 : }
3707 :
3708 15059 : sn = 0;
3709 15059 : move16();
3710 15059 : IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
3711 : {
3712 6784 : sn = add( sn, 1 );
3713 6784 : cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
3714 6784 : move16();
3715 : }
3716 :
3717 15059 : randGaussExp = CNG_RAND_GAUSS_SHIFT + 1;
3718 15059 : move16();
3719 :
3720 : /*
3721 : Generate Gaussian random noise in real and imaginary parts of the CLDFB bands
3722 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each band
3723 : */
3724 15059 : IF( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) )
3725 : {
3726 13446 : sc = add( shr( add( cngNoiseLevelExp, CLDFBinvScalingFactor_EXP + 1 - 1 ), 1 ), randGaussExp );
3727 13446 : move16();
3728 13446 : assert( ( ( cngNoiseLevelExp + CLDFBinvScalingFactor_EXP + 1 - 1 ) & 1 ) == 0 );
3729 :
3730 269894 : FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
3731 : {
3732 4359616 : FOR( i = 0; i < hFdCngCom->numSlots; i++ )
3733 : {
3734 : /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
3735 4103168 : s = 0;
3736 4103168 : move16();
3737 4103168 : sqrtNoiseLevel = Sqrt32( L_shr( Mpy_32_16_1( *ptr_level, scaleCLDFB ), sn ), &s ); /*Q31 - s*/
3738 :
3739 4103168 : IF( cng_coh_flag )
3740 : {
3741 1549808 : rand_gauss_fx( &tmp1, seed, Q28 ); /*Q28*/
3742 1549808 : rand_gauss_fx( &tmp2, seed2, Q28 ); /*Q28*/
3743 :
3744 1549808 : bufferReal[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*bufferScale*/
3745 1549808 : move32();
3746 1549808 : bufferReal[i][j] = L_shl( Mpy_32_32( bufferReal[i][j], sqrtNoiseLevel ), s ); /*bufferScale*/
3747 1549808 : move32();
3748 :
3749 1549808 : rand_gauss_fx( &tmp1, seed, Q28 ); /*Q28*/
3750 1549808 : rand_gauss_fx( &tmp2, seed2, Q28 ); /*Q28*/
3751 :
3752 1549808 : bufferImag[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*bufferScale*/
3753 1549808 : move32();
3754 1549808 : bufferImag[i][j] = L_shl( Mpy_32_32( bufferImag[i][j], sqrtNoiseLevel ), s ); /*bufferScale*/
3755 1549808 : move32();
3756 : }
3757 : ELSE
3758 : {
3759 : /* Real part in CLDFB band */
3760 2553360 : bufferReal[i][j] = L_shl( Mpy_32_32( L_shr( rand_gauss( seed ), 1 ), sqrtNoiseLevel ), s ); /*bufferScale*/
3761 2553360 : move32();
3762 :
3763 : /* Imaginary part in CLDFB band */
3764 2553360 : bufferImag[i][j] = L_shl( Mpy_32_32( L_shr( rand_gauss( seed ), 1 ), sqrtNoiseLevel ), s ); /*bufferScale*/
3765 2553360 : move32();
3766 : }
3767 : }
3768 256448 : ptr_level = ptr_level + 1; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3769 : }
3770 13446 : *bufferScale = sub( sc, 15 );
3771 13446 : move16();
3772 : }
3773 :
3774 15059 : return;
3775 : }
3776 :
3777 :
3778 : /*
3779 : generate_masking_noise_fx
3780 :
3781 : Parameters:
3782 :
3783 : timeDomainBuffer i/o : pointer to time domain output buffer 15Q0
3784 : st i/o : pointer to FD_CNG_COM structure
3785 : bitrate i : bitrate
3786 :
3787 : Function:
3788 : Generate additional comfort noise (kind of noise filling)
3789 :
3790 : Returns: none
3791 :
3792 : void
3793 : */
3794 1021 : void generate_masking_noise_fx(
3795 : Word16 *timeDomainBuffer, /* i/o : pointer to time domain output buffer 15Q0 */
3796 : Word16 Q,
3797 : HANDLE_FD_CNG_COM hFdCngCom /* i/o : pointer to FD_CNG_COM structure */
3798 : ,
3799 : Word16 length, /*Q0*/
3800 : Word16 core /*Q0*/ )
3801 : {
3802 : Word16 i, s, s1, s2, sq, cnt, startBand2, stopFFTbin2;
3803 : Word16 scaleExp, fftBufferExp, cngNoiseLevelExp;
3804 : Word16 scale, scaleTableSize;
3805 : Word16 maskingNoise[L_FRAME16k];
3806 : Word32 sqrtNoiseLevel;
3807 : Word32 *cngNoiseLevel;
3808 : Word32 *fftBuffer;
3809 : Word16 *seed;
3810 :
3811 : // PMTE(); /*IVAS CODE need to be added */
3812 :
3813 : /* pointer initializations */
3814 1021 : cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3815 1021 : fftBuffer = hFdCngCom->fftBuffer; /*Q31 - hFdCngCom->fftBuffer_exp*/
3816 1021 : seed = &( hFdCngCom->seed );
3817 :
3818 : /* Compute additional CN level */
3819 1021 : cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
3820 1021 : move16();
3821 :
3822 1021 : IF( NE_16( core, AMR_WB_CORE ) )
3823 : {
3824 1021 : scaleTableSize = 18;
3825 1021 : move16();
3826 1021 : assert( scaleTableSize == ( sizeof( scaleTable_cn_only ) / sizeof( scaleTable_cn_only[0] ) ) );
3827 :
3828 1021 : scale = -1;
3829 1021 : move16();
3830 15315 : FOR( i = 0; i < scaleTableSize; i++ )
3831 : {
3832 15315 : test();
3833 15315 : test();
3834 15315 : IF( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) ) && ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) ) && ( LT_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) ) )
3835 :
3836 : {
3837 1021 : scale = scaleTable_cn_only[i].scale; /*Q14*/
3838 1021 : move16();
3839 1021 : BREAK;
3840 : }
3841 : }
3842 1021 : assert( scale >= 0 );
3843 : }
3844 : ELSE
3845 : {
3846 0 : scaleTableSize = 3;
3847 0 : move16();
3848 0 : assert( scaleTableSize == ( sizeof( scaleTable_cn_only_amrwbio ) / sizeof( scaleTable_cn_only_amrwbio[0] ) ) );
3849 :
3850 0 : scale = 0;
3851 0 : move16();
3852 0 : FOR( i = 0; i < scaleTableSize; i++ )
3853 : {
3854 0 : IF( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only_amrwbio[i][0] ) )
3855 : {
3856 0 : scale = scaleTable_cn_only_amrwbio[i][1]; /*Q14*/
3857 0 : move16();
3858 0 : BREAK;
3859 : }
3860 : }
3861 : }
3862 :
3863 : /* Exclude clean speech */
3864 :
3865 1021 : s1 = norm_s( scale );
3866 1021 : s2 = norm_s( hFdCngCom->likelihood_noisy_speech );
3867 :
3868 : /* scaleTable_cn_only[i].scale is scaled by 1 bit */
3869 1021 : scaleExp = sub( 1, add( s1, s2 ) );
3870 1021 : scale = mult_r( shl( scale, s1 ), shl( hFdCngCom->likelihood_noisy_speech, s2 ) ); /*Q15 - scaleExp*/
3871 :
3872 : {
3873 : /* add exponent of scale and cngNoiseLevel */
3874 1021 : fftBufferExp = add( scaleExp, cngNoiseLevelExp );
3875 :
3876 : /* even scalefactor needed for sqrt calculation */
3877 1021 : s = s_and( fftBufferExp, 1 );
3878 1021 : fftBufferExp = add( fftBufferExp, s );
3879 :
3880 : /* sqrt calculation => shift exponent */
3881 1021 : fftBufferExp = shr( fftBufferExp, 1 );
3882 :
3883 : /* consider scaling of random noise */
3884 1021 : fftBufferExp = add( fftBufferExp, CNG_RAND_GAUSS_SHIFT );
3885 :
3886 1021 : cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q0*/
3887 : /*
3888 : Generate Gaussian random noise in real and imaginary parts of the FFT bins
3889 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
3890 : */
3891 1021 : IF( hFdCngCom->startBand == 0 )
3892 : {
3893 : /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
3894 :
3895 : /* DC component in FFT */
3896 :
3897 : /* -s => consider scalefactor adaptation for sqrt calculation */
3898 0 : sq = sub( 0, s );
3899 0 : sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *cngNoiseLevel, scale ), &sq ); /*Q31 - sq*/
3900 0 : hFdCngCom->fftBuffer[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*q31 - hFdCngCom->fftBuffer_exp*/
3901 0 : move32();
3902 0 : hFdCngCom->fftBuffer[1] = 0;
3903 0 : move32();
3904 :
3905 0 : fftBuffer = hFdCngCom->fftBuffer + 2;
3906 0 : cngNoiseLevel++;
3907 :
3908 0 : cnt = sub( cnt, 1 );
3909 : }
3910 : ELSE
3911 : {
3912 1021 : startBand2 = shl( hFdCngCom->startBand, 1 );
3913 1021 : set32_fx( hFdCngCom->fftBuffer, 0, startBand2 );
3914 1021 : fftBuffer = hFdCngCom->fftBuffer + startBand2; /*Q31 - hFdCngCom->fftBuffer_exp*/
3915 : }
3916 :
3917 260355 : FOR( i = 0; i < cnt; i++ )
3918 : {
3919 : /* -1 => weighting with 0.5, -s => consider scalefactor adaptation for sqrt calculation */
3920 259334 : sq = sub( -1, s );
3921 259334 : sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *cngNoiseLevel, scale ), &sq ); /*Q31 - sq*/
3922 :
3923 : /* real part in FFT bins */
3924 :
3925 : /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
3926 259334 : *fftBuffer = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*Q31 - hFdCngCom->fftBuffer_exp*/
3927 259334 : move32();
3928 259334 : fftBuffer++;
3929 :
3930 : /* imaginary part in FFT bins */
3931 :
3932 : /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
3933 259334 : *fftBuffer = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*Q31 - hFdCngCom->fftBuffer_exp*/
3934 259334 : move32();
3935 259334 : fftBuffer++;
3936 :
3937 259334 : cngNoiseLevel++;
3938 : }
3939 :
3940 : /* remaining FFT bins are set to zero */
3941 1021 : stopFFTbin2 = shl( hFdCngCom->stopFFTbin, 1 );
3942 1021 : set32_fx( hFdCngCom->fftBuffer + stopFFTbin2, 0, sub( hFdCngCom->fftlen, stopFFTbin2 ) );
3943 :
3944 :
3945 : /* perform STFT synthesis */
3946 1021 : assert( hFdCngCom->olapBufferSynth2 != NULL );
3947 1021 : SynthesisSTFT( hFdCngCom->fftBuffer, fftBufferExp, maskingNoise, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn,
3948 : 0, hFdCngCom, 0, NULL, -1 /*st->element_mode*/, -1 /*nchan_out*/ );
3949 : // PMT("parameters need update")
3950 :
3951 :
3952 : /* add some comfort noise on top of decoded signal */
3953 1021 : IF( hFdCngCom->frameSize > length )
3954 : {
3955 645 : FOR( i = 0; i < length; i++ )
3956 : {
3957 640 : timeDomainBuffer[i] = add( timeDomainBuffer[i], shr_r( maskingNoise[i], -Q ) ); /*Q0*/
3958 640 : move16();
3959 : }
3960 : }
3961 : ELSE
3962 : {
3963 261112 : FOR( i = 0; i < hFdCngCom->frameSize; i++ )
3964 : {
3965 260096 : timeDomainBuffer[i] = add_sat( timeDomainBuffer[i], shr_r_sat( maskingNoise[i], -Q ) ); /*Q0*/
3966 260096 : move16();
3967 : }
3968 : }
3969 : }
3970 1021 : }
3971 :
3972 : /*-------------------------------------------------------------------
3973 : * generate_masking_noise_update_seed_fx()
3974 : *
3975 : * Update seed for scenarios where generate_masking_noise_fx() is
3976 : * not called based on signal statistics
3977 : *-------------------------------------------------------------------*/
3978 :
3979 58689 : void generate_masking_noise_update_seed_fx(
3980 : HANDLE_FD_CNG_COM hFdCngCom /* i/o : pointer to FD_CNG_COM structure */
3981 : )
3982 : {
3983 : Word16 *seed;
3984 : Word16 cnt, i;
3985 :
3986 : /* pointer initializations */
3987 58689 : seed = &( hFdCngCom->seed );
3988 :
3989 58689 : cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q0*/
3990 :
3991 58689 : IF( hFdCngCom->startBand == 0 )
3992 : {
3993 0 : rand_gauss( seed ); /*Q15*/
3994 0 : cnt = sub( cnt, 1 );
3995 : }
3996 :
3997 16756159 : FOR( i = 0; i < cnt; i++ )
3998 : {
3999 16697470 : rand_gauss( seed ); /*Q15*/
4000 16697470 : rand_gauss( seed ); /*Q15*/
4001 : }
4002 :
4003 :
4004 58689 : return;
4005 : }
4006 :
4007 : /************************************************************
4008 : * Generate additional comfort noise (kind of noise filling) *
4009 : ************************************************************/
4010 275 : void generate_masking_noise_mdct_fx(
4011 : Word32 *mdctBuffer, /* i/o: time-domain signal Q31 - mdctBuffer_e*/
4012 : Word16 *mdctBuffer_e, /* i/o: exponent time-domain signal */
4013 : HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
4014 : ,
4015 : Word16 L_frame )
4016 : {
4017 : Word16 i, s, s1, s2, sq, cnt;
4018 : Word16 scaleExp, maskingNoiseExp, cngNoiseLevelExp;
4019 : Word16 scale, scaleTableSize;
4020 : Word32 noise;
4021 : Word32 sqrtNoiseLevel;
4022 : Word32 maskingNoise[2 * L_FRAME16k];
4023 : Word32 *pMaskingNoise;
4024 : Word32 *cngNoiseLevel;
4025 : Word16 *seed;
4026 :
4027 : // PMTE(); /*IVAS CODE need to be added */
4028 : /* pointer initializations */
4029 275 : cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
4030 275 : seed = &( hFdCngCom->seed );
4031 :
4032 : /* Compute additional CN level */
4033 275 : cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
4034 275 : move16();
4035 :
4036 : /* Compute additional CN level */
4037 275 : scaleTableSize = 18;
4038 275 : move16();
4039 275 : assert( scaleTableSize == ( sizeof( scaleTable_cn_only ) / sizeof( scaleTable_cn_only[0] ) ) );
4040 :
4041 275 : scale = -1;
4042 275 : move16();
4043 4125 : FOR( i = 0; i < scaleTableSize; i++ )
4044 : {
4045 4125 : test();
4046 4125 : test();
4047 4125 : IF( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) ) && ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) ) && ( LT_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) ) )
4048 : {
4049 275 : scale = scaleTable_cn_only[i].scale; /*Q14*/
4050 275 : move16();
4051 275 : BREAK;
4052 : }
4053 : }
4054 275 : assert( scale >= 0 );
4055 :
4056 : /* Exclude clean speech */
4057 275 : s1 = norm_s( scale );
4058 275 : s2 = norm_s( hFdCngCom->likelihood_noisy_speech );
4059 :
4060 : /* scaleTable_cn_only[i].scale is scaled by 1 bit */
4061 275 : scaleExp = sub( 1, add( s1, s2 ) );
4062 275 : scale = mult_r( shl( scale, s1 ), shl( hFdCngCom->likelihood_noisy_speech, s2 ) ); /*Q15 - scaleExp*/
4063 :
4064 : /* add exponent of scale and cngNoiseLevel */
4065 275 : maskingNoiseExp = add( scaleExp, cngNoiseLevelExp );
4066 :
4067 : /* even scalefactor needed for sqrt calculation */
4068 275 : s = s_and( maskingNoiseExp, 1 );
4069 275 : maskingNoiseExp = add( maskingNoiseExp, s );
4070 :
4071 : /* sqrt calculation => shift exponent */
4072 275 : maskingNoiseExp = shr( maskingNoiseExp, 1 );
4073 :
4074 : /* consider scaling of random noise */
4075 275 : maskingNoiseExp = add( maskingNoiseExp, CNG_RAND_GAUSS_SHIFT );
4076 :
4077 275 : cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q0*/
4078 :
4079 : /*
4080 : Generate Gaussian random noise in real and imaginary parts of the FFT bins
4081 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
4082 : */
4083 275 : IF( hFdCngCom->startBand == 0 )
4084 : {
4085 : /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
4086 :
4087 : /* DC component in FFT */
4088 :
4089 : /* -1 => weighting with 0.5, -s => consider scalefactor adaptation for sqrt calculation */
4090 0 : sq = sub( -1, s );
4091 0 : sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *cngNoiseLevel, scale ), &sq ); /*Q31 - sq*/
4092 0 : maskingNoise[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*Q15*/
4093 0 : move32();
4094 :
4095 0 : pMaskingNoise = &maskingNoise[1]; /*Q15*/
4096 0 : cngNoiseLevel++;
4097 :
4098 0 : cnt = sub( cnt, 1 );
4099 : }
4100 : ELSE
4101 : {
4102 275 : set32_fx( maskingNoise, 0, hFdCngCom->startBand );
4103 275 : pMaskingNoise = maskingNoise + hFdCngCom->startBand; /*Q15*/
4104 : }
4105 :
4106 70125 : FOR( i = 0; i < cnt; i++ )
4107 : {
4108 : /* -1 => weighting with 0.5, -s => consider scalefactor adaptation for sqrt calculation */
4109 69850 : sq = sub( -1, s );
4110 69850 : sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *cngNoiseLevel, scale ), &sq ); /*Q31 - sq*/
4111 :
4112 : /* real part in FFT bins */
4113 :
4114 : /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
4115 69850 : *pMaskingNoise = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*Q15*/
4116 69850 : move32();
4117 69850 : pMaskingNoise++;
4118 :
4119 69850 : cngNoiseLevel++;
4120 : }
4121 :
4122 : /* re-normalization of energy level
4123 : 16 * 0.79056941504 = sqrt(NORM_MDCT_FACTOR)
4124 : */
4125 : assert( NORM_MDCT_FACTOR == 160 );
4126 :
4127 : /* do weighting with factor 0.79056941504 later */
4128 275 : maskingNoiseExp = add( maskingNoiseExp, 4 );
4129 :
4130 275 : s = s_max( *mdctBuffer_e, maskingNoiseExp );
4131 275 : s1 = sub( s, *mdctBuffer_e );
4132 275 : s2 = sub( s, maskingNoiseExp );
4133 :
4134 : /* avoid rescaling of mdct samples if no comfort noise is added */
4135 275 : IF( scale != 0 )
4136 : {
4137 : /* Add some comfort noise on top of decoded signal */
4138 0 : IF( s1 == 0 )
4139 : {
4140 0 : FOR( i = 0; i < hFdCngCom->stopFFTbin; i++ )
4141 : {
4142 : /* If shifting negative noise values the lowest result is -1 but never 0.
4143 : Shift positive noise values to avoid unwanted amplification of these small values later */
4144 0 : noise = L_shr( Mpy_32_16_1( L_abs( maskingNoise[i] ), 25905 /*0.79056941504 Q15*/ ), s2 ); /*Q31 - maskingNoiseExp - s2*/
4145 :
4146 0 : if ( maskingNoise[i] < 0 )
4147 : {
4148 0 : noise = L_negate( noise );
4149 : }
4150 :
4151 0 : mdctBuffer[i] = L_add( mdctBuffer[i], noise ); /*Q31 - s*/
4152 0 : move32();
4153 : }
4154 : }
4155 : ELSE
4156 : {
4157 0 : FOR( i = 0; i < hFdCngCom->stopFFTbin; i++ )
4158 : {
4159 0 : mdctBuffer[i] = L_add( L_shr( mdctBuffer[i], s1 ),
4160 : Mpy_32_16_1( maskingNoise[i], 25905 /*0.79056941504 Q15*/ ) ); /*Q31 - s*/
4161 0 : move32();
4162 : }
4163 0 : FOR( i = hFdCngCom->stopFFTbin; i < L_frame; i++ )
4164 : {
4165 0 : mdctBuffer[i] = L_shr( mdctBuffer[i], s1 ); /*Q31 - s*/
4166 0 : move32();
4167 : }
4168 0 : *mdctBuffer_e = s;
4169 0 : move16();
4170 : }
4171 : }
4172 275 : }
4173 :
4174 22605 : void generate_masking_noise_mdct_ivas_fx(
4175 : Word32 *mdctBuffer, /* i/o: time-domain signal Q31 - mdctBuffer_e*/
4176 : Word16 *mdctBuffer_e, /* i/o: exponent time-domain signal */
4177 : HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ )
4178 : {
4179 : Word16 i, sq, cnt;
4180 : Word16 cngNoiseLevelExp;
4181 : Word32 scale, temp;
4182 : Word32 sqrtNoiseLevel;
4183 : Word32 maskingNoise[2 * L_FRAME16k];
4184 : Word32 *pMaskingNoise;
4185 : Word32 *cngNoiseLevel;
4186 : Word16 *seed;
4187 :
4188 : // PMTE(); /*IVAS CODE need to be added */
4189 : /* pointer initializations */
4190 22605 : cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
4191 22605 : seed = &( hFdCngCom->seed );
4192 :
4193 : /* Compute additional CN level */
4194 22605 : cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
4195 22605 : move16();
4196 :
4197 22605 : scale = ONE_IN_Q30;
4198 22605 : move32();
4199 :
4200 22605 : cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
4201 :
4202 : /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
4203 22605 : IF( hFdCngCom->likelihood_noisy_speech > 0 )
4204 : {
4205 9850 : FOR( i = 0; i < SIZE_SCALE_TABLE_CN; i++ )
4206 : {
4207 9850 : test();
4208 9850 : test();
4209 9850 : IF( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) &&
4210 : GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) &&
4211 : LE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) )
4212 : {
4213 713 : BREAK;
4214 : }
4215 : }
4216 :
4217 : /* Exclude clean speech */
4218 713 : scale = L_mult( scaleTable_cn_only[i].scale, hFdCngCom->likelihood_noisy_speech ); // Q30 (14 + 15 + 1)
4219 :
4220 : /*
4221 : Generate Gaussian random noise in real and imaginary parts of the FFT bins
4222 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
4223 : */
4224 713 : IF( hFdCngCom->startBand == 0 )
4225 : {
4226 : /* *cngNoiseLevel * scale * 0.5 */
4227 0 : temp = Mpy_32_32( *cngNoiseLevel, scale ); // exp = cngNoiseLevelExp (cngNoiseLevelExp + Q30(scale) + 1(0.5f) - 31)
4228 0 : sq = cngNoiseLevelExp;
4229 0 : move16();
4230 :
4231 0 : sqrtNoiseLevel = Sqrt32( temp, &sq ); /*Q31 - sq*/
4232 :
4233 0 : rand_gauss_fx( &temp, seed, Q15 ); // Q15
4234 :
4235 0 : maskingNoise[0] = L_shl( Mpy_32_32( temp, sqrtNoiseLevel ), sq ); // Q15
4236 0 : move32();
4237 :
4238 0 : pMaskingNoise = &maskingNoise[1]; /*Q15*/
4239 0 : cngNoiseLevel++;
4240 0 : cnt = sub( cnt, 1 );
4241 : }
4242 : ELSE
4243 : {
4244 713 : set32_fx( maskingNoise, 0, hFdCngCom->startBand );
4245 713 : pMaskingNoise = maskingNoise + hFdCngCom->startBand; /*Q15*/
4246 : }
4247 :
4248 202167 : FOR( i = 0; i < cnt; i++ )
4249 : {
4250 : /* MDCT bins */
4251 : /* *cngNoiseLevel * scale * 0.5 */
4252 201454 : temp = Mpy_32_32( *cngNoiseLevel, scale ); // exp = cngNoiseLevelExp (cngNoiseLevelExp + Q30(scale) + 1(0.5f) - 31)
4253 201454 : sq = cngNoiseLevelExp;
4254 201454 : move16();
4255 :
4256 201454 : sqrtNoiseLevel = Sqrt32( temp, &sq ); /*Q31 - sq*/
4257 :
4258 201454 : rand_gauss_fx( &temp, seed, Q15 ); // Q15
4259 :
4260 201454 : *pMaskingNoise = L_shl( Mpy_32_32( temp, sqrtNoiseLevel ), sq ); // Q15
4261 201454 : move32();
4262 :
4263 201454 : pMaskingNoise++;
4264 201454 : cngNoiseLevel++;
4265 : }
4266 :
4267 : /*re-normalization of energy level: M/sqrt(2)*/
4268 713 : v_multc_fixed( maskingNoise, SQRT_NORM_MDCT_FACTOR_Q27, maskingNoise, hFdCngCom->stopFFTbin ); // Q11
4269 :
4270 713 : scale_sig32( maskingNoise, hFdCngCom->stopFFTbin, sub( 20, *mdctBuffer_e ) ); // exp = *mdctBuffer_e
4271 :
4272 : /* Add some comfort noise on top of decoded signal */
4273 713 : v_add_fixed( maskingNoise, mdctBuffer, mdctBuffer, hFdCngCom->stopFFTbin, 1 );
4274 713 : *mdctBuffer_e = sub( *mdctBuffer_e, 1 );
4275 713 : move16();
4276 : }
4277 : ELSE
4278 : {
4279 : /* very low level case - just update random seeds */
4280 21892 : IF( hFdCngCom->startBand == 0 )
4281 : {
4282 0 : rand_gauss_fx( &maskingNoise[0], seed, Q15 ); // Q15
4283 0 : cngNoiseLevel++;
4284 0 : cnt = sub( cnt, 1 );
4285 : }
4286 :
4287 6260924 : FOR( i = 0; i < cnt; i++ )
4288 : {
4289 6239032 : rand_gauss_fx( &maskingNoise[0], seed, Q15 ); // Q15
4290 6239032 : move32();
4291 : }
4292 : }
4293 :
4294 22605 : return;
4295 : }
4296 :
4297 :
4298 : /*-------------------------------------------------------------------
4299 : * initFdCngDec()
4300 : *
4301 : * Initialize an instance of type FD_CNG
4302 : *-------------------------------------------------------------------*/
4303 557157 : void configureFdCngDec_ivas_fx(
4304 : HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */
4305 : const Word16 bwidth, /*Q0*/
4306 : const Word32 total_brate, /*Q0*/
4307 : const Word16 L_frame, /*Q0*/
4308 : const Word16 last_L_frame, /*Q0*/
4309 : const Word16 element_mode /*Q0*/ )
4310 : {
4311 : Word16 j, stopBandFR;
4312 557157 : HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom;
4313 :
4314 557157 : hsCom->CngBandwidth = bwidth; /*Q0*/
4315 557157 : move16();
4316 557157 : if ( EQ_16( hsCom->CngBandwidth, FB ) )
4317 : {
4318 376380 : hsCom->CngBandwidth = SWB;
4319 376380 : move16();
4320 : }
4321 557157 : test();
4322 557157 : IF( NE_32( total_brate, FRAME_NO_DATA ) && NE_32( total_brate, SID_2k40 ) )
4323 : {
4324 556859 : hsCom->CngBitrate = total_brate; /*Q0*/
4325 556859 : move32();
4326 : }
4327 298 : ELSE IF( EQ_32( hsCom->CngBitrate, -1 ) )
4328 : {
4329 : /* set minimum active CBR bitrate IF CngBitrate is uninitialized */
4330 0 : IF( element_mode > EVS_MONO )
4331 : {
4332 0 : hsCom->CngBitrate = IVAS_13k2;
4333 0 : move32();
4334 : }
4335 : ELSE
4336 : {
4337 0 : hsCom->CngBitrate = ACELP_7k20;
4338 0 : move32();
4339 : }
4340 : }
4341 :
4342 : /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */
4343 : /* This may need adjustment in the future IF 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */
4344 557157 : if ( EQ_16( element_mode, IVAS_CPE_MDCT ) )
4345 : {
4346 449225 : hsCom->CngBitrate = IVAS_48k;
4347 449225 : move32();
4348 : }
4349 557157 : hsCom->numSlots = 16;
4350 557157 : move32();
4351 :
4352 : /* NB configuration */
4353 557157 : IF( EQ_16( bwidth, NB ) )
4354 : {
4355 0 : hsCom->FdCngSetup = FdCngSetup_nb;
4356 0 : hsCom->numCoreBands = 16;
4357 0 : move16();
4358 0 : hsCom->regularStopBand = 16;
4359 0 : move16();
4360 : }
4361 :
4362 : /* WB configuration */
4363 557157 : ELSE IF( EQ_16( bwidth, WB ) )
4364 : {
4365 : /* FFT 6.4kHz, no CLDFB */
4366 1253 : test();
4367 1253 : test();
4368 1253 : IF( LE_32( hsCom->CngBitrate, ACELP_8k00 ) && EQ_16( L_frame, L_FRAME ) )
4369 : {
4370 314 : hsCom->FdCngSetup = FdCngSetup_wb1;
4371 314 : hsCom->numCoreBands = 16;
4372 314 : move16();
4373 314 : hsCom->regularStopBand = 16;
4374 314 : move16();
4375 : }
4376 : /* FFT 6.4kHz, CLDFB 8.0kHz */
4377 939 : ELSE IF( LE_32( hsCom->CngBitrate, ACELP_13k20 ) || EQ_16( L_frame, L_FRAME ) )
4378 : {
4379 156 : hsCom->FdCngSetup = FdCngSetup_wb2;
4380 156 : hsCom->numCoreBands = 16;
4381 156 : move16();
4382 156 : hsCom->regularStopBand = 20;
4383 156 : move16();
4384 156 : IF( EQ_16( L_frame, L_FRAME16k ) )
4385 : {
4386 8 : hsCom->FdCngSetup = FdCngSetup_wb2;
4387 8 : hsCom->numCoreBands = 20;
4388 8 : move16();
4389 8 : hsCom->regularStopBand = 20;
4390 8 : move16();
4391 8 : hsCom->FdCngSetup.fftlen = 640;
4392 8 : move16();
4393 8 : hsCom->FdCngSetup.stopFFTbin = 256;
4394 8 : move16();
4395 : }
4396 : }
4397 : /* FFT 8.0kHz, no CLDFB */
4398 : ELSE
4399 : {
4400 783 : hsCom->FdCngSetup = FdCngSetup_wb3;
4401 783 : hsCom->numCoreBands = 20;
4402 783 : move16();
4403 783 : hsCom->regularStopBand = 20;
4404 783 : move16();
4405 : }
4406 : }
4407 :
4408 : /* SWB/FB configuration */
4409 : ELSE
4410 : {
4411 : /* FFT 6.4kHz, CLDFB 14kHz */
4412 555904 : IF( EQ_16( L_frame, L_FRAME ) )
4413 : {
4414 2749 : hsCom->FdCngSetup = FdCngSetup_swb1;
4415 2749 : hsCom->numCoreBands = 16;
4416 2749 : move16();
4417 2749 : hsCom->regularStopBand = 35;
4418 2749 : move16();
4419 : }
4420 : /* FFT 8.0kHz, CLDFB 16kHz */
4421 : ELSE
4422 : {
4423 553155 : hsCom->FdCngSetup = FdCngSetup_swb2;
4424 553155 : hsCom->numCoreBands = 20;
4425 553155 : move16();
4426 553155 : hsCom->regularStopBand = 40;
4427 553155 : move16();
4428 553155 : test();
4429 553155 : if ( EQ_16( last_L_frame, L_FRAME ) && EQ_16( element_mode, IVAS_CPE_DFT ) )
4430 : {
4431 154 : hsCom->regularStopBand = 35;
4432 154 : move16();
4433 : }
4434 : }
4435 : }
4436 :
4437 :
4438 557157 : hsCom->fftlen = hsCom->FdCngSetup.fftlen;
4439 557157 : move16();
4440 557157 : hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin;
4441 557157 : move16();
4442 :
4443 : /* Configure the SID quantizer and the Comfort Noise Generator */
4444 :
4445 557157 : hsCom->startBand = 2;
4446 557157 : move16();
4447 557157 : hsCom->stopBand = add( hsCom->FdCngSetup.sidPartitions[( hsCom->FdCngSetup.numPartitions - 1 )], 1 ); /*Q0*/
4448 557157 : initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 );
4449 :
4450 557157 : IF( EQ_16( hsCom->stopFFTbin, 160 ) )
4451 : {
4452 0 : hsCom->nFFTpart = 17;
4453 0 : move16();
4454 : }
4455 557157 : ELSE IF( EQ_16( hsCom->stopFFTbin, 256 ) )
4456 : {
4457 3219 : hsCom->nFFTpart = 20;
4458 3219 : move16();
4459 : }
4460 : ELSE
4461 : {
4462 553938 : hsCom->nFFTpart = 21;
4463 553938 : move16();
4464 : }
4465 557157 : hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); /*Q0*/
4466 557157 : move16();
4467 2227774 : FOR( j = 0; j < hsCom->nCLDFBpart; j++ )
4468 : {
4469 1670617 : hsCom->CLDFBpart[j] = sub( hsCom->part[( j + hsCom->nFFTpart )], sub( hsCom->stopFFTbin, hsCom->startBand ) ); /*Q0*/
4470 1670617 : move16();
4471 1670617 : hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[( j + hsCom->nFFTpart )];
4472 1670617 : move16();
4473 : }
4474 :
4475 557157 : stopBandFR = 40; //(Word16)floor(1000.f /*Hz*/ / 25.f /*Hz/Bin*/);
4476 557157 : move16();
4477 557157 : if ( GT_16( stopBandFR, hsCom->stopFFTbin ) )
4478 : {
4479 0 : stopBandFR = hsCom->stopFFTbin; /*Q0*/
4480 0 : move16();
4481 : }
4482 :
4483 557157 : initPartitions( hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions, hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping, hFdCngDec->psize_shaping, hFdCngDec->psize_shaping_norm, &hFdCngDec->psize_shaping_norm_exp, hFdCngDec->psize_inv_shaping, stopBandFR );
4484 :
4485 557157 : hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; /*Q0*/
4486 557157 : move16();
4487 :
4488 557157 : BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) );
4489 557157 : BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) );
4490 :
4491 557157 : SWITCH( hsCom->fftlen )
4492 : {
4493 3211 : case 512:
4494 3211 : hsCom->olapWinAna_fx = olapWinAna512_fx; /*Q30*/
4495 3211 : hsCom->fftSineTab_fx = NULL;
4496 3211 : hsCom->olapWinSyn_fx = olapWinSyn256_fx; /*Q15*/
4497 3211 : hsCom->fftlenShift = 8;
4498 3211 : move16();
4499 3211 : hsCom->fftlenFac = 32767 /*1.0 Q15*/;
4500 3211 : move16();
4501 3211 : BREAK;
4502 553946 : case 640:
4503 553946 : hsCom->olapWinAna_fx = olapWinAna640_fx; /*Q30*/
4504 553946 : hsCom->fftSineTab_fx = fftSineTab640_fx; /*Q15*/
4505 553946 : hsCom->olapWinSyn_fx = olapWinSyn320_fx; /*Q15*/
4506 553946 : hsCom->fftlenShift = 9;
4507 553946 : move16();
4508 553946 : hsCom->fftlenFac = 20480 /*0.625 Q15*/;
4509 553946 : move16();
4510 553946 : BREAK;
4511 0 : default:
4512 0 : assert( !"Unsupported FFT length for FD-based CNG" );
4513 : BREAK;
4514 : }
4515 557157 : BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) );
4516 557157 : BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) );
4517 557157 : hsCom->frameSize = shr( hsCom->fftlen, 1 );
4518 :
4519 557157 : return;
4520 : }
4521 :
4522 : /*-------------------------------------------------------------------
4523 : * FdCng_decodeSID_ivas_fx()
4524 : *
4525 : * Decode the FD-CNG bitstream
4526 : *-------------------------------------------------------------------*/
4527 :
4528 1913 : void FdCng_decodeSID_ivas_fx(
4529 : Decoder_State *st /* i/o: decoder state structure */
4530 : )
4531 : {
4532 : Word16 N;
4533 : Word32 *sidNoiseEst;
4534 : Word32 gain;
4535 : Word16 i, index;
4536 : Word32 v[32];
4537 : Word16 indices[32];
4538 : HANDLE_FD_CNG_COM hFdCngCom;
4539 : Word32 *invTrfMatrix_fx;
4540 : Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
4541 : Word16 tmp16;
4542 :
4543 1913 : IF( st->element_mode == EVS_MONO )
4544 : {
4545 0 : tmp16 = GAIN_Q_OFFSET_EVS_FX_Q0;
4546 0 : move16();
4547 : }
4548 : ELSE
4549 : {
4550 1913 : tmp16 = GAIN_Q_OFFSET_IVAS_FX_Q0;
4551 1913 : move16();
4552 : }
4553 :
4554 1913 : const Word16 gain_q_offset = tmp16; /* Q0 */
4555 1913 : move16();
4556 :
4557 1913 : invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /*Q31*/
4558 :
4559 1913 : hFdCngCom = ( st->hFdCngDec )->hFdCngCom;
4560 :
4561 1913 : sidNoiseEst = hFdCngCom->sidNoiseEst; /*Q16*/
4562 :
4563 1913 : N = hFdCngCom->npart; /*Q0*/
4564 1913 : move16();
4565 1913 : gain = 0;
4566 1913 : move32();
4567 1913 : hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 );
4568 1913 : move16();
4569 :
4570 : /* Read bitstream */
4571 13391 : FOR( i = 0; i < FD_CNG_stages_37bits; i++ )
4572 : {
4573 11478 : indices[i] = get_next_indice_fx( st, bits_37bits[i] ); /*Q0*/
4574 11478 : move16();
4575 : }
4576 :
4577 1913 : index = get_next_indice_fx( st, 7 );
4578 :
4579 : /* MSVQ decoder */
4580 :
4581 1913 : IF( st->element_mode != EVS_MONO )
4582 : {
4583 1913 : create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC );
4584 1913 : msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v, NULL, 7 );
4585 : }
4586 : ELSE
4587 : { /* Legacy EVS_MONO MSVQ tables */
4588 0 : msvq_dec_fx( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL, 7 );
4589 : }
4590 :
4591 :
4592 : /* Decode gain */
4593 : // gain = ((float)index - gain_q_offset) / 1.5f;
4594 1913 : gain = L_mult0( sub( index, gain_q_offset ), 21845 ); // Q15
4595 :
4596 : /* Apply gain and undo log */
4597 : Word16 res_exp[NPART];
4598 1913 : Word16 max_res_exp = 0;
4599 1913 : move16();
4600 46554 : FOR( i = 0; i < N; i++ )
4601 : {
4602 44641 : sidNoiseEst[i] = BASOP_util_Pow2( Mpy_32_32( L_add( v[i], gain ), LOG_10_BASE_2_BY_10_Q31 ), Q16, &res_exp[i] ); /*Q31 - res_exp[i]*/
4603 44641 : move32();
4604 44641 : if ( LT_16( max_res_exp, res_exp[i] ) )
4605 : {
4606 1299 : max_res_exp = res_exp[i];
4607 1299 : move16();
4608 : }
4609 : }
4610 :
4611 46554 : FOR( i = 0; i < N; i++ )
4612 : {
4613 44641 : sidNoiseEst[i] = L_shr( sidNoiseEst[i], sub( max_res_exp, res_exp[i] ) ); /*Q31 - max_res_exp*/
4614 44641 : move32();
4615 : }
4616 :
4617 1913 : hFdCngCom->sidNoiseEstExp = max_res_exp;
4618 1913 : move16();
4619 :
4620 : /* NB last band energy compensation */
4621 :
4622 1913 : IF( hFdCngCom->CngBandwidth == NB )
4623 : {
4624 0 : sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], NB_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/
4625 0 : move32();
4626 : }
4627 :
4628 1913 : test();
4629 1913 : IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) )
4630 : {
4631 475 : sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], SWB_13k2_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/
4632 475 : move32();
4633 : }
4634 :
4635 1913 : scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 );
4636 1913 : Word16 shift1 = L_norm_arr( hFdCngCom->cngNoiseLevel, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) );
4637 1913 : Word16 shift2 = L_norm_arr( hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ) );
4638 1913 : Word16 shift = s_max( sub( hFdCngCom->sidNoiseEstExp, shift1 ), sub( hFdCngCom->cngNoiseLevelExp, shift2 ) );
4639 :
4640 1913 : scale_sig32( hFdCngCom->cngNoiseLevel, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( hFdCngCom->sidNoiseEstExp, shift ) );
4641 1913 : scale_sig32( hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ), sub( hFdCngCom->cngNoiseLevelExp, shift ) );
4642 :
4643 1913 : hFdCngCom->cngNoiseLevelExp = shift;
4644 1913 : move16();
4645 :
4646 1913 : lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac );
4647 :
4648 1913 : return;
4649 : }
4650 :
4651 : /*-------------------------------------------------------------------
4652 : * generate_masking_noise_ivas_fx()
4653 : *
4654 : * Generate additional comfort noise (kind of noise filling)
4655 : *-------------------------------------------------------------------*/
4656 :
4657 59265 : void generate_masking_noise_ivas_fx(
4658 : Word32 *timeDomainBuffer, /* i/o: time-domain signal Q31 - *exp_out*/
4659 : Word16 *exp_out, /* o : time-domain signal exp */
4660 : HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
4661 : const Word16 length, /* i : frame size Q0*/
4662 : const Word16 core, /* i : core Q0*/
4663 : const Word16 return_noise, /* i : noise is returned instead of added Q0*/
4664 : const Word16 secondary, /* i : flag to indicate secondary noise generation Q0*/
4665 : const Word16 element_mode, /* i : element mode Q0*/
4666 : STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */
4667 : const Word16 nchan_out /* i : number of output channels Q0*/
4668 : )
4669 : {
4670 59265 : Word32 *cngNoiseLevel_fx = hFdCngCom->cngNoiseLevel;
4671 59265 : Word32 *ptr_level_fx = cngNoiseLevel_fx;
4672 59265 : Word32 *fftBuffer_fx = hFdCngCom->fftBuffer;
4673 : Word16 i;
4674 : Word32 maskingNoise_fx[L_FRAME16k];
4675 : Word32 *ptr_r_fx;
4676 : Word32 *ptr_i_fx;
4677 : Word16 startBand;
4678 59265 : Word16 *seed = &( hFdCngCom->seed );
4679 : Word32 scale_fx;
4680 : Word16 shift;
4681 59265 : scale_fx = 0x40000000; // 1.0 in Q30
4682 59265 : move32();
4683 59265 : startBand = hFdCngCom->startBand; /*Q0*/
4684 59265 : move16();
4685 59265 : shift = getScaleFactor32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN );
4686 59265 : if ( LT_16( sub( hFdCngCom->cngNoiseLevelExp, shift ), 4 ) )
4687 : {
4688 5639 : shift = sub( hFdCngCom->cngNoiseLevelExp, 4 ); /*Q0*/
4689 : }
4690 59265 : scale_sig32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); /*hFdCngCom->cngNoiseLevelExp*/
4691 59265 : hFdCngCom->cngNoiseLevelExp = sub( hFdCngCom->cngNoiseLevelExp, shift );
4692 59265 : move16();
4693 :
4694 : /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
4695 59265 : *exp_out = Q15;
4696 59265 : move16();
4697 59265 : IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) )
4698 : {
4699 3262 : IF( NE_16( core, AMR_WB_CORE ) )
4700 : {
4701 : /* Compute additional CN level */
4702 43507 : FOR( i = 0; i < SIZE_SCALE_TABLE_CN; i++ )
4703 : {
4704 43507 : test();
4705 43507 : test();
4706 55278 : if ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) &&
4707 23542 : GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) &&
4708 11771 : LT_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) )
4709 : {
4710 3262 : BREAK;
4711 : }
4712 : }
4713 :
4714 3262 : scale_fx = L_deposit_h( scaleTable_cn_only[i].scale_ivas ); /* Q30 */
4715 : }
4716 : ELSE
4717 : {
4718 : /* Compute additional CN level */
4719 0 : FOR( i = 0; i < SIZE_SCALE_TABLE_CN_AMRWB; i++ )
4720 : {
4721 0 : if ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only_amrwbio[i][0] ) )
4722 : {
4723 0 : BREAK;
4724 : }
4725 : }
4726 :
4727 0 : IF( LT_16( i, SIZE_SCALE_TABLE_CN_AMRWB ) )
4728 : {
4729 0 : scale_fx = L_deposit_h( scaleTable_cn_only_amrwbio[i][1] ); /* Q30 */
4730 : }
4731 : ELSE
4732 : {
4733 0 : scale_fx = 0;
4734 0 : move32();
4735 : }
4736 : }
4737 :
4738 : /* Exclude clean speech */
4739 3262 : scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); // Q30
4740 :
4741 : /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
4742 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */
4743 3262 : IF( startBand == 0 )
4744 : {
4745 0 : rand_gauss_fx( &fftBuffer_fx[0], seed, *exp_out ); // Q15
4746 0 : ptr_r_fx = fftBuffer_fx + 2; /*Q31 - hFdCngCom->fftBuffer_exp*/
4747 : Word16 exp1;
4748 0 : exp1 = add( hFdCngCom->cngNoiseLevelExp, 1 );
4749 : Word32 mpy1;
4750 0 : mpy1 = Sqrt32( Mpy_32_32( scale_fx, *ptr_level_fx ), &exp1 ); /*Q31 - exp1*/
4751 0 : mpy1 = L_shl( mpy1, exp1 ); // Q31
4752 0 : fftBuffer_fx[0] = Mpy_32_32( fftBuffer_fx[0], mpy1 ); /* DC component in FFT */ // Q = Q15
4753 0 : ptr_level_fx++;
4754 : }
4755 : ELSE
4756 : {
4757 3262 : fftBuffer_fx[0] = 0;
4758 3262 : move32();
4759 3262 : set32_fx( fftBuffer_fx + 2, 0, shl( sub( startBand, 1 ), 1 ) );
4760 3262 : ptr_r_fx = fftBuffer_fx + shl( startBand, 1 ); /*Q31 - hFdCngCom->fftBuffer_exp*/
4761 : }
4762 3262 : ptr_i_fx = ptr_r_fx + 1;
4763 890370 : FOR( ; ptr_level_fx < cngNoiseLevel_fx + hFdCngCom->stopFFTbin - startBand; ptr_level_fx++ )
4764 : {
4765 : /* Real part in FFT bins */
4766 887108 : rand_gauss_fx( ptr_r_fx, seed, *exp_out ); // Q15
4767 : Word16 exp2;
4768 887108 : exp2 = add( hFdCngCom->cngNoiseLevelExp, 1 );
4769 : Word32 mpy2;
4770 887108 : mpy2 = Sqrt32( L_shr( Mpy_32_32( scale_fx, *ptr_level_fx ), 1 ), &exp2 ); /*Q31 - exp2*/
4771 887108 : ( *ptr_r_fx ) = L_shl( Mpy_32_32( *ptr_r_fx, mpy2 ), exp2 ); // Q = Q15
4772 887108 : move32();
4773 887108 : ptr_r_fx += 2;
4774 :
4775 : /* Imaginary part in FFT bins */
4776 887108 : rand_gauss_fx( ptr_i_fx, seed, *exp_out ); // Q15
4777 887108 : ( *ptr_i_fx ) = L_shl( Mpy_32_32( *ptr_i_fx, mpy2 ), exp2 ); // Q = Q15
4778 887108 : ptr_i_fx += 2;
4779 : }
4780 :
4781 : /* Remaining FFT bins are set to zero */
4782 3262 : set32_fx( fftBuffer_fx + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) );
4783 : /* Nyquist frequency is discarded */
4784 3262 : fftBuffer_fx[1] = 0;
4785 3262 : move32();
4786 : }
4787 : ELSE
4788 : {
4789 : /* very low level case - update random seeds and reset FFT buffer; don't fully skip SynthesisSTFT_flt(), because of the buffer updates done there... */
4790 56003 : generate_masking_noise_update_seed_fx( hFdCngCom );
4791 :
4792 56003 : set32_fx( fftBuffer_fx, 0, hFdCngCom->fftlen );
4793 : }
4794 :
4795 : /* Perform STFT synthesis */
4796 59265 : IF( secondary )
4797 : {
4798 445 : SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out );
4799 : }
4800 : ELSE
4801 : {
4802 58820 : SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out );
4803 : }
4804 59265 : *exp_out = sub( *exp_out, Q9 );
4805 59265 : move16();
4806 :
4807 : /* Add some comfort noise on top of decoded signal */
4808 59265 : IF( return_noise )
4809 : {
4810 890 : Copy32( maskingNoise_fx, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ) ); /*Q31 - *exp_out*/
4811 : }
4812 : ELSE
4813 : {
4814 58375 : v_add_fixed_no_hdrm( maskingNoise_fx, timeDomainBuffer, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ) ); /*Q31 - *exp_out*/
4815 : }
4816 :
4817 59265 : return;
4818 : }
4819 :
4820 : /*-------------------------------------------------------------------
4821 : * generate_stereo_masking_noise_fx()
4822 : *
4823 : * Generate additional comfort noise (kind of noise filling)
4824 : *-------------------------------------------------------------------*/
4825 :
4826 902 : void generate_stereo_masking_noise_fx(
4827 : Word16 *syn, /* i/o: time-domain signal Q_syn*/
4828 : Word16 Q_syn,
4829 : Decoder_State *st, /* i/o: decoder state structure */
4830 : STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */
4831 : const Word16 flag_sec_CNA, /* i : CNA flag for secondary channel Q0*/
4832 : const Word16 fadeOut, /* i : only fade out of previous state Q0*/
4833 : STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */
4834 : const Word16 nchan_out /* i : number of output channels Q0*/
4835 : )
4836 : {
4837 : HANDLE_FD_CNG_COM hFdCngCom;
4838 : Word32 gamma_fx, scale_fx /*, SP_ratio_fx needs to be integrated*/;
4839 : Word32 Np_fx[L_FRAME16k];
4840 : Word32 Ns_fx[L_FRAME16k];
4841 : Word32 N1_fx[L_FRAME16k];
4842 : Word32 N2_fx[L_FRAME16k];
4843 : Word16 N1_fx_exp, N2_fx_exp;
4844 : Word16 i;
4845 :
4846 902 : IF( st->idchan == 0 )
4847 : {
4848 445 : hFdCngCom = st->hFdCngDec->hFdCngCom;
4849 445 : Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/
4850 445 : Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/
4851 :
4852 445 : set32_fx( &Np_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) );
4853 445 : set32_fx( &Ns_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) );
4854 :
4855 445 : IF( !fadeOut )
4856 : {
4857 445 : Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/
4858 445 : generate_masking_noise_ivas_fx( N1_fx, &N1_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 0, st->element_mode, hStereoCng, nchan_out ); // N1_fx Q6
4859 : /* Generate masking noise for secondary channel */
4860 445 : IF( flag_sec_CNA )
4861 : {
4862 445 : generate_masking_noise_ivas_fx( N2_fx, &N2_fx_exp, hFdCngCom, hFdCngCom->frameSize, 0, 1, 1, st->element_mode, hStereoCng, nchan_out ); // N2_fx Q6
4863 445 : gamma_fx = L_shr( Mpy_32_32( hStereoCng->c_PS_LT_fx, hStereoCng->c_PS_LT_fx ), 1 ); /*Q30*/
4864 445 : scale_fx = ONE_IN_Q30;
4865 445 : move32();
4866 445 : IF( LT_32( gamma_fx, 966367642 /* 0.9 in Q30 */ ) )
4867 : {
4868 : Word16 exp_gamma;
4869 445 : exp_gamma = 0;
4870 445 : move16();
4871 : Word16 divisor1;
4872 445 : divisor1 = Inv16( (Word16) L_shr( L_sub( ONE_IN_Q30, gamma_fx ), Q15 ), &exp_gamma ); // Q15-exp_gamma
4873 445 : gamma_fx = L_shl( Mpy_32_16_1( gamma_fx, divisor1 ), exp_gamma ); // Q30
4874 : Word16 exp_gamma1, exp_gamma2, exp_gamma3;
4875 445 : exp_gamma1 = Q1;
4876 445 : exp_gamma2 = Q1;
4877 445 : exp_gamma3 = Q1;
4878 445 : move16();
4879 445 : move16();
4880 445 : move16();
4881 445 : gamma_fx = Sqrt32( L_add( gamma_fx, ONE_IN_Q30 ), &exp_gamma1 ); /*Q31 - exp_gamma1*/
4882 : Word32 temp;
4883 445 : temp = Sqrt32( gamma_fx, &exp_gamma2 ); // Q31-exp_gamma1
4884 445 : gamma_fx = L_sub( gamma_fx, L_shl( temp, sub( exp_gamma2, exp_gamma1 ) ) ); // Q31-exp_gamma1
4885 445 : gamma_fx = L_shl( gamma_fx, sub( exp_gamma1, Q1 ) ); // Q30
4886 : Word32 divisor2;
4887 445 : divisor2 = Sqrt32( L_add( ONE_IN_Q30, L_shl( Mpy_32_32( gamma_fx, gamma_fx ), Q1 ) ), &exp_gamma3 ); // Q31 - exp_gamma3
4888 445 : scale_fx = L_shl( divide3232( ONE_IN_Q30, divisor2 ), add( Q15, exp_gamma3 ) ); // Q30
4889 : }
4890 : ELSE
4891 : {
4892 0 : gamma_fx = 0;
4893 0 : move16();
4894 : }
4895 :
4896 57405 : FOR( i = 0; i < 2 * hFdCngCom->frameSize / 4; i++ )
4897 : {
4898 56960 : Np_fx[i] = L_add( Np_fx[i],
4899 : Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ) ); // Q6
4900 56960 : move32();
4901 : Word32 add2;
4902 56960 : add2 = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6
4903 56960 : if ( hStereoCng->c_PS_LT_fx < 0 )
4904 : {
4905 35200 : add2 = L_negate( add2 ); /*Q6*/
4906 : }
4907 56960 : Ns_fx[i] = L_add( Ns_fx[i], add2 ); /*Q6*/
4908 56960 : move32();
4909 : }
4910 57405 : FOR( ; i < hFdCngCom->frameSize; i++ )
4911 : {
4912 56960 : Np_fx[i] = Mpy_32_32( scale_fx, L_shl( L_add( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6
4913 56960 : move32();
4914 56960 : Ns_fx[i] = Mpy_32_32( scale_fx, L_shl( L_sub( N1_fx[i], Mpy_32_32( gamma_fx, L_shl( N2_fx[i], Q1 ) ) ), Q1 ) ); // Q6
4915 56960 : move32();
4916 56960 : IF( hStereoCng->c_PS_LT_fx < 0 )
4917 : {
4918 35200 : Ns_fx[i] = L_negate( Ns_fx[i] );
4919 35200 : move32();
4920 : }
4921 : }
4922 : /* Below code to be converted */
4923 445 : Word32 scale_fx_tmp = Mpy_32_32( scale_fx, L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ) ); // Q21
4924 57405 : FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ )
4925 : {
4926 56960 : hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp,
4927 56960 : L_add( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ),
4928 56960 : Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ),
4929 : Q14 ); // Q_olap
4930 56960 : move16();
4931 56960 : hStereoCng->olapBufferSynth22_fx[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp,
4932 56960 : L_sub( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ),
4933 56960 : Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ),
4934 : Q14 ); // Q_olap
4935 56960 : move16();
4936 : }
4937 : }
4938 : ELSE
4939 : {
4940 0 : FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ )
4941 : {
4942 0 : Np_fx[i] = L_add( Np_fx[i], N1_fx[i] ); // Q6
4943 0 : move32();
4944 : }
4945 0 : Copy32( &N1_fx[( hFdCngCom->frameSize / 2 )], &Np_fx[( hFdCngCom->frameSize / 2 )], shr( hFdCngCom->frameSize, 1 ) ); /*Q6*/
4946 0 : scale_fx = L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ); // Q21
4947 0 : FOR( i = 0; i < hFdCngCom->frameSize; i++ )
4948 : {
4949 0 : hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_16_1( scale_fx, hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ), Q6 ); // Q_olap
4950 0 : move16();
4951 : }
4952 : }
4953 :
4954 445 : Copy_Scale_sig_32_16( hStereoCng->olapBufferSynth22_32fx, hStereoCng->olapBufferSynth22_fx, hFdCngCom->fftlen, sub( st->Q_syn, 15 ) ); /*st->Q_syn*/
4955 : }
4956 : ELSE
4957 : {
4958 0 : set16_fx( hFdCngCom->olapBufferSynth2, 0, shr( hFdCngCom->frameSize, 1 ) );
4959 0 : set16_fx( hStereoCng->olapBufferSynth22_fx, 0, shr( hFdCngCom->frameSize, 1 ) );
4960 : }
4961 445 : IF( flag_sec_CNA )
4962 : {
4963 445 : Copy_Scale_sig_32_16( Ns_fx, hStereoCng->maskingNoiseS_fx, hFdCngCom->frameSize, 0 ); // Q6
4964 445 : hStereoCng->enableSecCNA = 1;
4965 445 : move16();
4966 : }
4967 : ELSE
4968 : {
4969 0 : set16_fx( hStereoCng->olapBufferSynth22_fx, 0, hFdCngCom->frameSize );
4970 : }
4971 :
4972 : /* add masking noise */
4973 114365 : FOR( i = 0; i < hFdCngCom->frameSize; i++ )
4974 : {
4975 113920 : syn[i] = add( syn[i], (Word16) L_shr( Np_fx[i], sub( Q16 + Q6, Q_syn ) ) ); // Q_syn
4976 113920 : move16();
4977 : }
4978 : }
4979 457 : ELSE IF( hStereoCng->enableSecCNA )
4980 : {
4981 : Word16 SP_ratio_fx;
4982 445 : SP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /* Use long-term SP ratio based on L/R synthesis Q15*/
4983 : Word16 prevSP_ratio_fx;
4984 445 : prevSP_ratio_fx = hStereoTD->prevSP_ratio_fx; /* Use long-term SP ratio based on L/R synthesis Q15*/
4985 445 : move16();
4986 : /* scale and add masking noise */
4987 28925 : FOR( i = 0; i < shr( *hStereoCng->frameSize, 2 ); i++ )
4988 : {
4989 : Word16 s;
4990 : Word16 scale_fx_tmp;
4991 28480 : scale_fx_tmp = BASOP_Util_Divide3216_Scale( L_add( L_mult0( prevSP_ratio_fx, sub( shr( *hStereoCng->frameSize, 2 ), i ) ), L_mult0( SP_ratio_fx, i ) ), shr( *hStereoCng->frameSize, 2 ), &s ); // Q15
4992 28480 : scale_fx_tmp = shl( scale_fx_tmp, s );
4993 28480 : syn[i] = add( syn[i], mult( scale_fx_tmp, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/
4994 28480 : move16();
4995 : }
4996 28925 : FOR( ; i < *hStereoCng->frameSize / 2; i++ )
4997 : {
4998 28480 : syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/
4999 28480 : move16();
5000 : }
5001 57405 : FOR( ; i < *hStereoCng->frameSize; i++ )
5002 : {
5003 56960 : syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/
5004 56960 : move16();
5005 : }
5006 445 : hStereoTD->prevSP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /*Q15*/
5007 445 : move16();
5008 : }
5009 :
5010 902 : return;
5011 : }
5012 18831 : void generate_masking_noise_lb_dirac_fx(
5013 : HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
5014 : Word32 *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA Q11*/
5015 : const Word16 nCldfbTs, /* i : number of CLDFB slots that will be rendered Q0*/
5016 : SPAT_PARAM_REND_COMMON_DATA_HANDLE hSpatParamRendCom, /* i : common spatial rendering parameters handle */
5017 : const Word16 cna_flag /* i : CNA flag for LB and HB Q0*/
5018 : )
5019 : {
5020 : Word16 i;
5021 18831 : Word32 *cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/
5022 18831 : Word32 *fftBuffer = hFdCngCom->fftBuffer; /*hFdCngCom->fftBuffer_exp*/
5023 : Word32 *ptr_r;
5024 : Word32 *ptr_i;
5025 : Word32 *ptr_level;
5026 18831 : Word16 *seed = &( hFdCngCom->seed );
5027 : Word32 scale;
5028 : Word16 n_samples_out, n_samples_start, n_samples_out_loop;
5029 :
5030 18831 : push_wmops( "fd_cng_dirac" );
5031 :
5032 : /* Init */
5033 18831 : scale = 0;
5034 18831 : move32();
5035 18831 : n_samples_out = i_mult( shr( hFdCngCom->frameSize, 4 /* DEFAULT_JBM_CLDFB_TIMESLOTS */ ), nCldfbTs );
5036 18831 : n_samples_start = 0;
5037 18831 : move16();
5038 18831 : Word16 exp_out = Q11;
5039 18831 : move16();
5040 : /*LB CLDFB - CNA from STFT*/
5041 18831 : IF( cna_flag )
5042 : {
5043 : /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
5044 4395 : IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) )
5045 : {
5046 : /* Compute additional CN level */
5047 21523 : FOR( i = 0; i < 15; i++ )
5048 : {
5049 21523 : test();
5050 21523 : test();
5051 25956 : if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) &&
5052 8866 : GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) &&
5053 4433 : LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) )
5054 : {
5055 1709 : BREAK;
5056 : }
5057 : }
5058 :
5059 1709 : scale = L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ); /* Q30 */
5060 1709 : scale = Mpy_32_16_1( scale, hFdCngCom->likelihood_noisy_speech ); /* Q30 */
5061 : }
5062 : }
5063 :
5064 : /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/
5065 18831 : test();
5066 18831 : IF( cna_flag && tdBuffer != NULL )
5067 : {
5068 : Word16 cur_subframe;
5069 : Word16 cur_subframe_start_outfs;
5070 : Word16 cur_subframe_start_cngfs;
5071 : Word16 slot_size_cng;
5072 :
5073 8790 : WHILE( n_samples_out > 0 )
5074 : {
5075 4395 : n_samples_out_loop = s_min( hFdCngCom->frameSize, n_samples_out );
5076 4395 : IF( scale != 0 )
5077 : {
5078 : /*Generate LF comfort noise only at first slot, for the whole frame*/
5079 1709 : ptr_level = cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/
5080 :
5081 : /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
5082 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */
5083 1709 : IF( EQ_16( hFdCngCom->startBand, 0 ) )
5084 : {
5085 0 : rand_gauss_fx( &fftBuffer[0], seed, exp_out );
5086 0 : ptr_r = fftBuffer + 2; /*hFdCngCom->fftBuffer_exp*/
5087 :
5088 0 : Word16 exp2 = sub( 31, hFdCngCom->cngNoiseLevelExp );
5089 0 : Word32 sqr = Sqrt32( L_shr( Mpy_32_32( scale, *ptr_level ), 1 ), &exp2 ); /* DC component in FFT Q31 - exp2*/
5090 0 : sqr = L_shl( sqr, exp2 ); /*Q31*/
5091 0 : fftBuffer[0] = Mpy_32_32( fftBuffer[0], sqr ); /* DC component in FFT Q31 - hFdCngCom->fftBuffer_exp*/
5092 0 : move32();
5093 0 : ptr_level++;
5094 : }
5095 : ELSE
5096 : {
5097 1709 : fftBuffer[0] = 0;
5098 1709 : move32();
5099 1709 : set32_fx( fftBuffer + 2, 0, shl( sub( hFdCngCom->startBand, 1 ), 1 ) );
5100 1709 : ptr_r = fftBuffer + shl( hFdCngCom->startBand, 1 ); /*hFdCngCom->fftBuffer_exp*/
5101 : }
5102 1709 : ptr_i = ptr_r + 1; /*hFdCngCom->fftBuffer_exp*/
5103 :
5104 508691 : FOR( ; ptr_level < cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); ptr_level++ )
5105 : {
5106 506982 : rand_gauss_fx( ptr_r, seed, exp_out );
5107 506982 : Word16 exp2 = hFdCngCom->cngNoiseLevelExp;
5108 506982 : Word32 mpy2 = Sqrt32( Mpy_32_32( scale, *ptr_level ), &exp2 ); /*Q31 - exp2*/
5109 506982 : ( *ptr_r ) = L_shl( Mpy_32_32( *ptr_r, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/
5110 506982 : move32();
5111 506982 : ptr_r += 2;
5112 :
5113 : /* Imaginary part in FFT bins */
5114 506982 : rand_gauss_fx( ptr_i, seed, exp_out );
5115 506982 : ( *ptr_i ) = L_shl( Mpy_32_32( *ptr_i, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/
5116 506982 : move32();
5117 506982 : ptr_i += 2;
5118 : }
5119 : /* Remaining FFT bins are set to zero */
5120 1709 : set32_fx( fftBuffer + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) );
5121 : /* Nyquist frequency is discarded */
5122 1709 : fftBuffer[1] = 0;
5123 1709 : move32();
5124 :
5125 : /* Perform STFT synthesis */
5126 1709 : SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom );
5127 1709 : scale_sig32( tdBuffer + n_samples_start, n_samples_out_loop, Q9 ); // Q2 -> Q11
5128 : }
5129 :
5130 : ELSE
5131 : {
5132 : /* very low level case - update random seeds */
5133 2686 : generate_masking_noise_update_seed_fx( hFdCngCom );
5134 :
5135 2686 : set32_fx( fftBuffer, 0, hFdCngCom->fftlen );
5136 : /* Perform STFT synthesis */
5137 2686 : SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom );
5138 : }
5139 4395 : hFdCngCom->fftBuffer_exp = 31 - 11;
5140 4395 : move16();
5141 4395 : n_samples_out = sub( n_samples_out, hFdCngCom->frameSize );
5142 4395 : n_samples_start = add( n_samples_start, hFdCngCom->frameSize );
5143 : }
5144 :
5145 : /* move generated noise to the 5ms subframe starts in the tc buffer according to the output sampling frequency to avoid
5146 : overwriting it with the synthesis in case of shared tc and synth channel memory, i.e. non-TSM mode */
5147 4395 : slot_size_cng = shr( hFdCngCom->frameSize, 4 /* DEFAULT_JBM_CLDFB_TIMESLOTS */ );
5148 : /* move start indices forward to the end of the last subframe */
5149 4395 : cur_subframe_start_outfs = mult( nCldfbTs, hSpatParamRendCom->slot_size );
5150 4395 : cur_subframe_start_cngfs = mult( nCldfbTs, slot_size_cng );
5151 :
5152 : /* go from the last subframe back and move the LB noise */
5153 21975 : FOR( cur_subframe = sub( hSpatParamRendCom->nb_subframes, 1 ); cur_subframe >= 0; cur_subframe-- )
5154 : {
5155 : Word16 move_size, subframe_size_outfs;
5156 17580 : move_size = mult( slot_size_cng, hSpatParamRendCom->subframe_nbslots[cur_subframe] );
5157 17580 : subframe_size_outfs = mult( hSpatParamRendCom->subframe_nbslots[cur_subframe], hSpatParamRendCom->slot_size );
5158 17580 : cur_subframe_start_outfs = sub( cur_subframe_start_outfs, mult( hSpatParamRendCom->subframe_nbslots[cur_subframe], hSpatParamRendCom->slot_size ) );
5159 17580 : cur_subframe_start_cngfs = sub( cur_subframe_start_cngfs, mult( hSpatParamRendCom->subframe_nbslots[cur_subframe], slot_size_cng ) );
5160 : /* move cna */
5161 17580 : Copy32( tdBuffer + cur_subframe_start_cngfs, tdBuffer + cur_subframe_start_outfs, move_size );
5162 :
5163 : /* set everything else to zero */
5164 17580 : set_zero_fx( tdBuffer + cur_subframe_start_outfs + move_size, sub( subframe_size_outfs, move_size ) );
5165 : }
5166 : }
5167 :
5168 18831 : pop_wmops();
5169 :
5170 18831 : return;
5171 : }
5172 568048 : void generate_masking_noise_dirac_ivas_fx(
5173 : HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
5174 : HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */
5175 : Word32 *tdBuffer_fx, /* i/o: time-domain signal, if NULL no LB-CNA q_input*/
5176 : Word32 *Cldfb_RealBuffer_fx, /* o : CLDFD real buffer q_cldfb*/
5177 : Word32 *Cldfb_ImagBuffer_fx, /* o : CLDFD imaginary buffer q_cldfb*/
5178 : const Word16 slot_index, /* i : CLDFB slot index Q0*/
5179 : const Word16 cna_flag, /* i : CNA flag for LB and HB Q0*/
5180 : const Word16 fd_cng_flag, /* i : FD-CNG flag for HB Q0*/
5181 : Word16 q_input,
5182 : Word16 *q_cldfb )
5183 : {
5184 : Word16 i;
5185 : Word32 *ptr_level_fx;
5186 568048 : Word16 *seed = &( hFdCngCom->seed );
5187 : Word32 scale_fx;
5188 : Word16 q_scale, q_shift, q_ptr_level;
5189 :
5190 568048 : push_wmops( "fd_cng_dirac" );
5191 :
5192 : /* Init */
5193 568048 : scale_fx = 0;
5194 568048 : move32();
5195 :
5196 : /* Resample CLDFB memories if necessary*/
5197 568048 : IF( NE_16( i_mult( h_cldfb->no_channels, h_cldfb->no_col ), hFdCngCom->frameSize ) )
5198 : {
5199 642 : resampleCldfb_ivas_fx( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC );
5200 : }
5201 :
5202 568048 : set32_fx( Cldfb_RealBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX );
5203 568048 : set32_fx( Cldfb_ImagBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX );
5204 :
5205 : /*LB CLDFB - CNA from STFT*/
5206 568048 : IF( cna_flag != 0 )
5207 : {
5208 : /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
5209 123344 : IF( hFdCngCom->likelihood_noisy_speech > 0 )
5210 : {
5211 : /* Compute additional CN level */
5212 600000 : FOR( i = 0; i < 15; i++ )
5213 : {
5214 600000 : test();
5215 600000 : test();
5216 724800 : if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) &&
5217 249600 : ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) ) &&
5218 124800 : ( LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) )
5219 : {
5220 47520 : BREAK;
5221 : }
5222 : }
5223 :
5224 47520 : scale_fx = L_shr( L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ), Q3 ); /* Q27 */
5225 47520 : scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech );
5226 : }
5227 : }
5228 : /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/
5229 568048 : IF( cna_flag && tdBuffer_fx != NULL )
5230 : {
5231 70320 : *q_cldfb = q_input;
5232 70320 : move16();
5233 70320 : IF( scale_fx != 0 )
5234 : {
5235 : /* LF CLDFB*/
5236 27344 : cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb );
5237 : }
5238 : ELSE
5239 : {
5240 : /* LB ana CLDFB*/
5241 42976 : cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb );
5242 : }
5243 : }
5244 :
5245 : /*HF CLDFB - CNA and/or FD-CNG*/
5246 568048 : if ( fd_cng_flag )
5247 : {
5248 9696 : scale_fx = L_add( scale_fx, ONE_IN_Q27 ); // 1 in Q27
5249 : }
5250 568048 : IF( scale_fx != 0 )
5251 : {
5252 50560 : q_scale = 27;
5253 50560 : move16();
5254 50560 : q_shift = norm_l( scale_fx );
5255 50560 : scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/
5256 50560 : q_scale = add( q_scale, q_shift );
5257 50560 : scale_fx = Mpy_32_32( scale_fx, Mpy_32_16_1( L_mult( h_cldfb->scale, h_cldfb->scale ), CLDFB_SCALING ) ); // Q = q_scale + 2 * Q8 - 34
5258 50560 : q_scale = sub( add( q_scale, 2 * Q8 ), 31 + 3 );
5259 50560 : ptr_level_fx = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/
5260 50560 : q_ptr_level = sub( 31, hFdCngCom->cngNoiseLevelExp );
5261 :
5262 1047168 : FOR( i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++ )
5263 : {
5264 : Word32 num;
5265 : Word16 exp, q_num;
5266 996608 : q_shift = norm_l( scale_fx );
5267 996608 : scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/
5268 996608 : q_scale = add( q_scale, q_shift );
5269 996608 : num = Mpy_32_32( scale_fx, *ptr_level_fx ); /*q_num*/
5270 996608 : q_num = sub( add( q_scale, q_ptr_level ), 31 - 1 ); // num = ( scale * *ptr_level ) * 0.5f
5271 996608 : exp = sub( 31, q_num );
5272 996608 : num = Sqrt32( num, &exp ); /*Q31 - exp*/
5273 : /* Real part in CLDFB band */
5274 996608 : rand_gauss_fx( &Cldfb_RealBuffer_fx[i], seed, *q_cldfb );
5275 996608 : Cldfb_RealBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_RealBuffer_fx[i], num ), exp );
5276 996608 : move32();
5277 : /* Imaginary part in CLDFB band */
5278 996608 : rand_gauss_fx( &Cldfb_ImagBuffer_fx[i], seed, *q_cldfb );
5279 996608 : Cldfb_ImagBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_ImagBuffer_fx[i], num ), exp );
5280 996608 : move32();
5281 :
5282 996608 : ptr_level_fx++;
5283 : }
5284 : }
5285 :
5286 568048 : pop_wmops();
5287 :
5288 568048 : return;
5289 : }
5290 :
5291 :
5292 : /*-------------------------------------------------------------------
5293 : * FdCngDecodeMDCTStereoSID()
5294 : *
5295 : * Decode FD-Cng parameters for CNG in MDCT-Stereo mode from the bitstream
5296 : *
5297 : *-------------------------------------------------------------------*/
5298 :
5299 410 : void FdCngDecodeMDCTStereoSID_fx(
5300 : CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */
5301 : )
5302 : {
5303 : DEC_CORE_HANDLE sts[CPE_CHANNELS];
5304 : HANDLE_FD_CNG_COM hFdCngCom;
5305 : Word32 *ms_ptr_fx[CPE_CHANNELS];
5306 : Word32 *lr_ptr_fx[CPE_CHANNELS];
5307 : Word32 logNoiseEst_fx[CPE_CHANNELS][NPART];
5308 : Word32 gain_fx[CPE_CHANNELS];
5309 : Word16 indices[FD_CNG_stages_37bits];
5310 : Word16 N, i, ch, p, stages;
5311 : Word16 is_out_ms;
5312 : Word32 *invTrfMatrix_fx;
5313 : Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
5314 : Word16 shift, exp_diff, max_exp_idx;
5315 : Word16 exp_arr[NPART];
5316 : Word32 tmp32, tmp32_arr[NPART];
5317 :
5318 410 : invTrfMatrix_fx = (Word32 *) tmpRAM_fx;
5319 410 : create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31
5320 :
5321 410 : is_out_ms = 0;
5322 410 : move16();
5323 410 : if ( hCPE->hCoreCoder[0]->cng_sba_flag )
5324 : {
5325 0 : is_out_ms = 1;
5326 0 : move16();
5327 : }
5328 :
5329 410 : N = 0; /* to avoid compilation warning */
5330 410 : move16();
5331 :
5332 1230 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
5333 : {
5334 820 : sts[ch] = hCPE->hCoreCoder[ch];
5335 820 : ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/
5336 820 : lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q18*/
5337 : }
5338 :
5339 : /* decode noise shapes and gains */
5340 1230 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
5341 : {
5342 820 : sts[ch] = hCPE->hCoreCoder[ch];
5343 820 : hFdCngCom = ( sts[ch]->hFdCngDec )->hFdCngCom;
5344 820 : N = hFdCngCom->npart;
5345 820 : move16();
5346 820 : hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); /*Q0*/
5347 820 : move16();
5348 :
5349 820 : IF( ch )
5350 : {
5351 410 : stages = FD_CNG_JOINT_stages_25bits;
5352 410 : move16();
5353 : }
5354 : ELSE
5355 : {
5356 410 : stages = FD_CNG_stages_37bits;
5357 410 : move16();
5358 : }
5359 :
5360 : /* read bitstream */
5361 4920 : FOR( i = 0; i < stages; i++ )
5362 : {
5363 4100 : indices[i] = get_next_indice_fx( sts[ch], bits_37bits[i] ); /*Q0*/
5364 4100 : move16();
5365 : }
5366 : {
5367 820 : gain_fx[ch] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[ch], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20
5368 820 : move32();
5369 : }
5370 :
5371 : /* MSVQ decoder */
5372 820 : shift = find_guarded_bits_fx( N );
5373 820 : msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 ); // Q20 - shift
5374 :
5375 820 : Scale_sig32( ms_ptr_fx[ch], N, shift ); // Q20
5376 : }
5377 :
5378 410 : dtx_read_padding_bits_fx( sts[1], mult( sub( IVAS_SID_5k2, 4400 ), ONE_BY_FRAMES_PER_SEC_Q15 ) );
5379 :
5380 410 : IF( sts[0]->hFdCngDec->hFdCngCom->no_side_flag )
5381 : {
5382 12 : set32_fx( ms_ptr_fx[1], 0, NPART );
5383 : }
5384 :
5385 410 : IF( EQ_16( is_out_ms, 0 ) )
5386 : {
5387 410 : inverseMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 );
5388 : }
5389 :
5390 1230 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
5391 : {
5392 820 : max_exp_idx = 0;
5393 820 : move16();
5394 820 : hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom;
5395 19504 : FOR( p = 0; p < N; p++ )
5396 : {
5397 18684 : tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20
5398 18684 : tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/
5399 18684 : move32();
5400 18684 : if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) )
5401 : {
5402 75 : max_exp_idx = p; /*Q0*/
5403 75 : move16();
5404 : }
5405 : }
5406 :
5407 : // Bringing in same exponent
5408 19504 : FOR( p = 0; p < N; p++ )
5409 : {
5410 18684 : lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q31 - exp_arr[max_exp_idx]*/
5411 18684 : move32();
5412 : }
5413 :
5414 820 : hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx];
5415 820 : move16();
5416 :
5417 820 : scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 );
5418 :
5419 820 : hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp;
5420 820 : move16();
5421 :
5422 820 : lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac );
5423 : }
5424 :
5425 410 : test();
5426 410 : IF( EQ_16( hCPE->nchan_out, 1 ) && LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
5427 : {
5428 : /* create proper M noise shape in channel zero after gains have been applied */
5429 120 : exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp );
5430 120 : move16();
5431 2883 : FOR( p = 0; p < N; p++ )
5432 : {
5433 2763 : IF( GT_16( exp_diff, 0 ) )
5434 : {
5435 159 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/
5436 159 : move32();
5437 : }
5438 : ELSE
5439 : {
5440 2604 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/
5441 2604 : move32();
5442 : }
5443 : }
5444 120 : IF( LT_16( exp_diff, 0 ) )
5445 : {
5446 44 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) );
5447 44 : move16();
5448 : }
5449 : }
5450 :
5451 410 : return;
5452 : }
5453 :
5454 :
5455 : /*-------------------------------------------------------------------
5456 : * FdCngDecodeDiracMDCTStereoSID_fx()
5457 : *
5458 : * Decode FD-CNG parameters for CNG in 2TC DirAC mode from the bitstream
5459 : *-------------------------------------------------------------------*/
5460 :
5461 167 : void FdCngDecodeDiracMDCTStereoSID_fx(
5462 : CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */
5463 : )
5464 : {
5465 : DEC_CORE_HANDLE sts[CPE_CHANNELS];
5466 : HANDLE_FD_CNG_COM hFdCngCom;
5467 : Word32 *ms_ptr_fx[CPE_CHANNELS];
5468 : Word32 *lr_ptr_fx[CPE_CHANNELS];
5469 : Word32 logNoiseEst_fx[CPE_CHANNELS][NPART];
5470 : Word32 gain_fx[CPE_CHANNELS];
5471 : Word16 indices[FD_CNG_stages_37bits];
5472 : Word16 N, i, ch, p;
5473 : Word32 *invTrfMatrix_fx;
5474 : Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
5475 : Word16 shift, exp_diff, max_exp_idx;
5476 : Word16 exp_arr[NPART];
5477 : Word32 tmp32, tmp32_arr[NPART];
5478 :
5479 167 : invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */
5480 167 : create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC ); // Q31
5481 :
5482 501 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
5483 : {
5484 334 : sts[ch] = hCPE->hCoreCoder[ch];
5485 334 : ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/
5486 334 : lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q20*/
5487 334 : ( sts[ch]->hFdCngDec )->hFdCngCom->sid_frame_counter++; /*Q18*/
5488 : }
5489 :
5490 : /* decode noise shapes and gains */
5491 167 : hFdCngCom = ( sts[0]->hFdCngDec )->hFdCngCom;
5492 167 : N = hFdCngCom->npart; /*Q0*/
5493 167 : move16();
5494 :
5495 : /* read bitstream */
5496 1169 : FOR( i = 0; i < FD_CNG_stages_37bits; i++ )
5497 : {
5498 1002 : indices[i] = get_next_indice_fx( sts[0], bits_37bits[i] ); /*Q0*/
5499 1002 : move16();
5500 : }
5501 167 : gain_fx[0] = Mpy_32_32( L_shl( L_sub( get_next_indice_fx( sts[0], 7 ), GAIN_Q_OFFSET_IVAS_FX ), Q20 ), TWO_BY_THREE_Q31 /* 2/3 in Q31 */ ); // Q20
5502 167 : move32();
5503 :
5504 167 : gain_fx[1] = gain_fx[0]; /*Q20*/
5505 167 : move32();
5506 :
5507 : /* MSVQ decoder */
5508 167 : shift = find_guarded_bits_fx( N );
5509 167 : msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 ); // Q20 - shift
5510 :
5511 167 : Scale_sig32( ms_ptr_fx[0], N, shift ); // Q20
5512 :
5513 167 : Copy32( ms_ptr_fx[0], ms_ptr_fx[1], N ); /*Q20*/
5514 :
5515 501 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
5516 : {
5517 334 : max_exp_idx = 0;
5518 334 : move16();
5519 334 : hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom;
5520 :
5521 8350 : FOR( p = 0; p < N; p++ )
5522 : {
5523 8016 : tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20
5524 8016 : tmp32_arr[p] = BASOP_util_Pow2( Mpy_32_32( tmp32, LOG_10_BASE_2_BY_10_Q31 ), Q11, &exp_arr[p] ); /*Q31 - exp_arr[p]*/
5525 8016 : move32();
5526 8016 : if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) )
5527 : {
5528 26 : max_exp_idx = p; /*Q0*/
5529 26 : move16();
5530 : }
5531 : }
5532 :
5533 : // Bringing in same exponent
5534 8350 : FOR( p = 0; p < N; p++ )
5535 : {
5536 8016 : lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q20*/
5537 8016 : move32();
5538 : }
5539 :
5540 334 : hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; /*Q0*/
5541 334 : move16();
5542 :
5543 : /* NB last band energy compensation */
5544 334 : test();
5545 334 : IF( hFdCngCom->CngBandwidth == NB )
5546 : {
5547 0 : lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], NB_LAST_BAND_SCALE_Q31 ); /*Q20*/
5548 0 : move32();
5549 : }
5550 334 : ELSE IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) )
5551 : {
5552 0 : lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], SWB_13k2_LAST_BAND_SCALE_Q31 ); /*Q20*/
5553 0 : move32();
5554 : }
5555 :
5556 334 : scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 );
5557 :
5558 334 : hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp;
5559 334 : move16();
5560 :
5561 334 : lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac );
5562 : }
5563 167 : sts[0]->hFdCngDec->hFdCngCom->coherence_fx = 0;
5564 167 : move16();
5565 167 : sts[1]->hFdCngDec->hFdCngCom->coherence_fx = 0;
5566 167 : move16();
5567 :
5568 167 : IF( EQ_16( hCPE->nchan_out, 1 ) )
5569 : {
5570 : /* create proper M noise shape in channel zero after gains have been applied */
5571 0 : exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp );
5572 0 : FOR( p = 0; p < N; p++ )
5573 : {
5574 0 : IF( exp_diff > 0 )
5575 : {
5576 0 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], add( exp_diff, 1 ) ) ); /*Q18*/
5577 0 : move32();
5578 : }
5579 : ELSE
5580 : {
5581 0 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p] = L_add( L_shr( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEst[p], sub( 1, exp_diff ) ), L_shr( sts[1]->hFdCngDec->hFdCngCom->sidNoiseEst[p], 1 ) ); /*Q18*/
5582 0 : move32();
5583 : }
5584 : }
5585 0 : IF( exp_diff < 0 )
5586 : {
5587 0 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) );
5588 0 : move16();
5589 : }
5590 : }
5591 :
5592 167 : return;
5593 : }
|