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