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