Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 :
6 : #include <assert.h>
7 : #include "typedef.h"
8 : #include <stdint.h>
9 : #include "options.h"
10 : #include "rom_com.h"
11 : #include "stat_dec.h"
12 : #include "prot_fx.h"
13 : #include "ivas_prot_fx.h"
14 : #include "basop_util.h"
15 : #include "rom_basop_util.h"
16 : #include "ivas_rom_dec.h"
17 : #include "ivas_prot_fx.h"
18 : #ifdef DEBUGGING
19 : #include "debug.h"
20 : #endif
21 :
22 :
23 : #define CNA_ACT_DN_LARGE_PARTITION 50 /* index of the first larger partition */
24 : #define ST_PERIODOG_FACT_Q15 29491 /* 0.9 in Q15, short-term filter factor for periodogram */
25 : #define CNA_ACT_DN_FACT_Q15 22938 /* 0.7 in Q15, downward updating factor for CNA during active frames */
26 : #define FIRST_CNA_NOISE_UPD_FRAMES 5 /* minimum number of CN initialization frames */
27 : #define DELTA_MASKING_NOISE_Q15 0
28 : #define LOG_10_BASE_2 1783446566 /* Q29 */
29 : #define GAIN_Q_OFFSET_IVAS_FX 45
30 : #define LOG_10_BASE_2_BY_10_Q31 713378606
31 : #define TWO_BY_THREE_Q31 1431655765
32 : #define ONE_BY_FRAMES_PER_SEC_Q15 656
33 : #define NB_LAST_BAND_SCALE_Q31 1717986918
34 : #define SWB_13k2_LAST_BAND_SCALE_Q31 1717986918
35 :
36 : /********************************
37 : * External tables *
38 : ********************************/
39 :
40 : extern const Word16 T_DIV_L_Frame[]; /* format: 0Q15 * 2^-7 */
41 :
42 : const Word16 maxN_37bits = FD_CNG_maxN_37bits;
43 : const Word16 maxC_37bits = FD_CNG_maxC_37bits;
44 : const Word16 stages_37bits = FD_CNG_stages_37bits;
45 : /*
46 : createFdCngDec_fx
47 :
48 : Parameters:
49 :
50 : hFdCngDec i/0 : pointer to cng decoder structure
51 :
52 : Function:
53 : create an instance of type FD_CNG
54 : */
55 6430 : ivas_error createFdCngDec_fx( HANDLE_FD_CNG_DEC *hFdCngDec )
56 : {
57 : HANDLE_FD_CNG_DEC hs;
58 : ivas_error error;
59 6430 : error = IVAS_ERR_OK;
60 :
61 : /* Allocate memory */
62 6430 : hs = (HANDLE_FD_CNG_DEC) malloc( sizeof( FD_CNG_DEC ) );
63 :
64 6430 : IF( hs == NULL )
65 : {
66 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Cannot allocate memory for FD CNG DEC structure" );
67 : }
68 6430 : IF( ( error = createFdCngCom_fx( &( hs->hFdCngCom ) ) ) != IVAS_ERR_OK )
69 : {
70 0 : return error;
71 : }
72 :
73 6430 : *hFdCngDec = hs;
74 6430 : return error;
75 : }
76 :
77 6427 : void initFdCngDec_ivas_fx(
78 : DEC_CORE_HANDLE st, /* i/o: decoder state structure */
79 : Word16 scale /*Q15*/ )
80 : {
81 : /* Initialize common */
82 : HANDLE_FD_CNG_DEC hFdCngDec;
83 :
84 6427 : hFdCngDec = st->hFdCngDec;
85 :
86 6427 : ivas_initFdCngCom_fx( hFdCngDec->hFdCngCom, scale );
87 6427 : set16_fx( hFdCngDec->olapBufferAna, 0, FFTLEN );
88 6427 : hFdCngDec->hFdCngCom->olapBufferAna = hFdCngDec->olapBufferAna;
89 6427 : set16_fx( hFdCngDec->olapBufferSynth2, 0, FFTLEN );
90 6427 : hFdCngDec->hFdCngCom->olapBufferSynth2 = hFdCngDec->olapBufferSynth2;
91 :
92 : /* Set some counters and flags */
93 :
94 6427 : hFdCngDec->flag_dtx_mode = 0;
95 6427 : move16();
96 6427 : hFdCngDec->lp_noise = -167772160l /*-20.f Q23*/; /* format: Q8.24 */
97 6427 : move32();
98 6427 : hFdCngDec->lp_speech = 209715200l /* 25.f Q23*/; /* format: Q8.24 */
99 6427 : move32();
100 :
101 : /* Initialization of the noise estimation algorithm */
102 :
103 6427 : set32_fx( hFdCngDec->bandNoiseShape, 0, FFTLEN2 );
104 6427 : set16_fx( &hFdCngDec->bandNoiseShape_exp, 0, 1 );
105 :
106 6427 : set32_fx( hFdCngDec->partNoiseShape, 0, NPART );
107 6427 : set16_fx( &hFdCngDec->partNoiseShape_exp, 0, 1 );
108 :
109 6427 : set32_fx( hFdCngDec->msPeriodog, 0, NPART_SHAPING );
110 6427 : set16_fx( &hFdCngDec->msPeriodog_exp, 0, 1 );
111 :
112 6427 : set32_fx( hFdCngDec->msAlpha, 0, NPART_SHAPING );
113 :
114 6427 : set32_fx( hFdCngDec->msBminWin, 0, NPART_SHAPING );
115 :
116 6427 : set32_fx( hFdCngDec->msBminSubWin, 0, NPART_SHAPING );
117 :
118 6427 : set16_fx( hFdCngDec->msPsd, 0, NPART_SHAPING );
119 6427 : set32_fx( hFdCngDec->msPsd_fx, 0, NPART_SHAPING );
120 6427 : set16_fx( hFdCngDec->msNoiseFloor, 0, NPART_SHAPING );
121 :
122 6427 : set32_fx( hFdCngDec->msNoiseEst, 0, NPART_SHAPING );
123 6427 : set16_fx( &hFdCngDec->msNoiseEst_exp, 0, 1 );
124 :
125 6427 : set32_fx( hFdCngDec->msMinBuf, 2147483647l /*1.0 Q31*/, MSNUMSUBFR * NPART_SHAPING );
126 :
127 6427 : set32_fx( hFdCngDec->msCurrentMin, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
128 :
129 6427 : set32_fx( hFdCngDec->msCurrentMinOut, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
130 :
131 6427 : set32_fx( hFdCngDec->msCurrentMinSubWindow, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
132 :
133 6427 : set16_fx( hFdCngDec->msLocalMinFlag, 0, NPART_SHAPING );
134 6427 : set16_fx( hFdCngDec->msNewMinFlag, 0, NPART_SHAPING );
135 :
136 6427 : set16_fx( hFdCngDec->msPsdFirstMoment, 0, NPART_SHAPING );
137 :
138 6427 : set32_fx( hFdCngDec->msPsdSecondMoment, 0, NPART_SHAPING );
139 6427 : set16_fx( hFdCngDec->msPeriodogBuf, 0, MSBUFLEN * NPART_SHAPING );
140 :
141 6427 : hFdCngDec->msPeriodogBufPtr = 0;
142 6427 : move16();
143 :
144 6427 : set16_fx( hFdCngDec->msLogPeriodog, 0, NPART_SHAPING );
145 6427 : set16_fx( hFdCngDec->msLogNoiseEst, 0, NPART_SHAPING );
146 :
147 6427 : set16_fx( hFdCngDec->psize_shaping, 0, NPART_SHAPING );
148 6427 : hFdCngDec->nFFTpart_shaping = 0;
149 6427 : move16();
150 6427 : set32_fx( hFdCngDec->msPeriodog_ST_fx, 0, NPART_SHAPING );
151 6427 : hFdCngDec->msPeriodog_ST_exp = 0;
152 6427 : move16();
153 6427 : hFdCngDec->hFdCngCom->fftBuffer_exp = 0;
154 6427 : move16();
155 6427 : hFdCngDec->hFdCngCom->periodog_exp = 0;
156 6427 : move16();
157 6427 : set32_fx( hFdCngDec->smoothed_psd_fx, 0, L_FRAME16k );
158 6427 : hFdCngDec->smoothed_psd_exp = 0;
159 6427 : move16();
160 6427 : set32_fx( hFdCngDec->hFdCngCom->sidNoiseEstLp, 0, NPART );
161 :
162 6427 : hFdCngDec->ms_last_inactive_bwidth = NB;
163 6427 : move16();
164 6427 : hFdCngDec->ms_cnt_bw_up = 0;
165 6427 : move16();
166 :
167 6427 : hFdCngDec->cna_LR_LT_fx = 16384; /* 0.5 in Q15 */
168 6427 : move16();
169 6427 : hFdCngDec->cna_ILD_LT_fx = 0;
170 6427 : move16();
171 6427 : hFdCngDec->first_cna_noise_updated = 0;
172 6427 : move16();
173 6427 : hFdCngDec->first_cna_noise_update_cnt = 0;
174 6427 : move16();
175 6427 : hFdCngDec->cna_nbands = CNA_INIT_NBANDS;
176 6427 : move16();
177 6427 : Copy( cna_init_bands, hFdCngDec->cna_band_limits, CNA_INIT_NBANDS + 1 );
178 6427 : hFdCngDec->cna_act_fact_fx = 32767; /* 1.0f in Q15 */
179 6427 : move16();
180 6427 : hFdCngDec->cna_rescale_fact_fx = 0;
181 6427 : move16();
182 6427 : hFdCngDec->cna_seed = 5687; /*Q0*/
183 6427 : move16();
184 6427 : set16_fx( hFdCngDec->cna_cm_fx, 0, STEREO_DFT_BAND_MAX );
185 6427 : set16_fx( hFdCngDec->cna_g_state_fx, 0, STEREO_DFT_BAND_MAX );
186 :
187 6427 : st->CNG_mode = -1;
188 6427 : move16();
189 6427 : Copy( st->lsp_old_fx, st->lspCNG_fx, M ); /*Q15*/
190 6427 : hFdCngDec->hFdCngCom->sid_frame_counter = 0;
191 6427 : return;
192 : }
193 :
194 3 : void initFdCngDec_fx(
195 : DEC_CORE_HANDLE st, /* i/o: decoder state structure */
196 : Word16 scale /*Q15*/ )
197 : {
198 : /* Initialize common */
199 : HANDLE_FD_CNG_DEC hFdCngDec;
200 :
201 3 : hFdCngDec = st->hFdCngDec;
202 :
203 3 : initFdCngCom( hFdCngDec->hFdCngCom, scale );
204 3 : set16_fx( hFdCngDec->olapBufferAna, 0, 320 );
205 3 : hFdCngDec->hFdCngCom->olapBufferAna = hFdCngDec->olapBufferAna;
206 3 : move16();
207 3 : set16_fx( hFdCngDec->olapBufferSynth2, 0, FFTLEN );
208 3 : hFdCngDec->hFdCngCom->olapBufferSynth2 = hFdCngDec->olapBufferSynth2;
209 3 : move16();
210 :
211 : /* Set some counters and flags */
212 :
213 3 : hFdCngDec->flag_dtx_mode = 0;
214 3 : move16();
215 3 : hFdCngDec->lp_noise = -167772160l /*-20.f Q23*/; /* format: Q8.24 */
216 3 : move32();
217 3 : hFdCngDec->lp_speech = 209715200l /* 25.f Q23*/; /* format: Q8.24 */
218 3 : move32();
219 :
220 : /* Initialization of the noise estimation algorithm */
221 :
222 3 : set32_fx( hFdCngDec->bandNoiseShape, 0, FFTLEN2 );
223 3 : set16_fx( &hFdCngDec->bandNoiseShape_exp, 0, 1 );
224 :
225 3 : set32_fx( hFdCngDec->partNoiseShape, 0, NPART );
226 3 : set16_fx( &hFdCngDec->partNoiseShape_exp, 0, 1 );
227 :
228 3 : set32_fx( hFdCngDec->msPeriodog, 0, NPART_SHAPING );
229 3 : set16_fx( &hFdCngDec->msPeriodog_exp, 0, 1 );
230 :
231 3 : set32_fx( hFdCngDec->msAlpha, 0, NPART_SHAPING );
232 :
233 3 : set32_fx( hFdCngDec->msBminWin, 0, NPART_SHAPING );
234 :
235 3 : set32_fx( hFdCngDec->msBminSubWin, 0, NPART_SHAPING );
236 :
237 3 : set16_fx( hFdCngDec->msPsd, 0, NPART_SHAPING );
238 3 : set32_fx( hFdCngDec->msPsd_fx, 0, NPART_SHAPING );
239 3 : set16_fx( hFdCngDec->msNoiseFloor, 0, NPART_SHAPING );
240 :
241 3 : set32_fx( hFdCngDec->msNoiseEst, 0, NPART_SHAPING );
242 3 : set16_fx( &hFdCngDec->msNoiseEst_exp, 0, 1 );
243 :
244 3 : set32_fx( hFdCngDec->msMinBuf, 2147483647l /*1.0 Q31*/, MSNUMSUBFR * NPART_SHAPING );
245 :
246 3 : set32_fx( hFdCngDec->msCurrentMin, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
247 :
248 3 : set32_fx( hFdCngDec->msCurrentMinOut, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
249 :
250 3 : set32_fx( hFdCngDec->msCurrentMinSubWindow, 2147483647l /*1.0 Q31*/, NPART_SHAPING );
251 :
252 3 : set16_fx( hFdCngDec->msLocalMinFlag, 0, NPART_SHAPING );
253 3 : set16_fx( hFdCngDec->msNewMinFlag, 0, NPART_SHAPING );
254 :
255 3 : set16_fx( hFdCngDec->msPsdFirstMoment, 0, NPART_SHAPING );
256 :
257 3 : set32_fx( hFdCngDec->msPsdSecondMoment, 0, NPART_SHAPING );
258 3 : set16_fx( hFdCngDec->msPeriodogBuf, 0, MSBUFLEN * NPART_SHAPING );
259 :
260 3 : hFdCngDec->msPeriodogBufPtr = 0;
261 3 : move16();
262 :
263 3 : set16_fx( hFdCngDec->msLogPeriodog, 0, NPART_SHAPING );
264 3 : set16_fx( hFdCngDec->msLogNoiseEst, 0, NPART_SHAPING );
265 :
266 3 : set16_fx( hFdCngDec->psize_shaping, 0, NPART_SHAPING );
267 3 : hFdCngDec->nFFTpart_shaping = 0;
268 3 : move16();
269 3 : set32_fx( hFdCngDec->msPeriodog_ST_fx, 0, NPART_SHAPING );
270 3 : hFdCngDec->msPeriodog_ST_exp = 0;
271 3 : move16();
272 3 : hFdCngDec->hFdCngCom->fftBuffer_exp = 0;
273 3 : move16();
274 3 : hFdCngDec->hFdCngCom->periodog_exp = 0;
275 3 : move16();
276 3 : set32_fx( hFdCngDec->smoothed_psd_fx, 0, L_FRAME16k );
277 3 : hFdCngDec->smoothed_psd_exp = 0;
278 3 : move16();
279 :
280 3 : return;
281 : }
282 : /*
283 : configureFdCngDec_fx
284 :
285 : Parameters:
286 :
287 : hs i/o: Contains the variables related to the FD-based CNG process
288 : numSlots i : Number of time slots in CLDFB matrix
289 : numCoreBands i : Number of core bands
290 : regularStopBand i : Number of CLDFB bands to be considered
291 : CLDFBscale i : cldfb scale factor
292 :
293 : Function:
294 : configure FD_CNG
295 :
296 : Returns:
297 : void
298 : */
299 5504 : void configureFdCngDec_fx(
300 : HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the CLDFB-based CNG process */
301 : Word16 bwidth, /*Q0*/
302 : Word32 total_brate, /*Q0*/
303 : Word16 L_frame, /*Q0*/
304 : const Word16 Last_L_frame, /*Q0*/
305 : const Word16 element_mode /*Q0*/ )
306 : {
307 : Word16 j, stopBandFR;
308 5504 : HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom;
309 :
310 :
311 5504 : hsCom->CngBandwidth = bwidth; /*Q0*/
312 5504 : move16();
313 5504 : if ( EQ_16( hsCom->CngBandwidth, FB ) )
314 : {
315 789 : hsCom->CngBandwidth = SWB;
316 789 : move16();
317 : }
318 5504 : test();
319 5504 : IF( total_brate != FRAME_NO_DATA && NE_32( total_brate, SID_2k40 ) )
320 : {
321 5504 : hsCom->CngBitrate = total_brate; /*Q0*/
322 5504 : move32();
323 : }
324 0 : ELSE IF( EQ_32( hsCom->CngBitrate, -1 ) )
325 : {
326 : /* set minimum active CBR bitrate if CngBitrate is uninitialized */
327 0 : hsCom->CngBitrate = ACELP_7k20;
328 0 : move32();
329 0 : if ( element_mode > EVS_MONO )
330 : {
331 0 : hsCom->CngBitrate = IVAS_13k2;
332 0 : move32();
333 : }
334 : }
335 :
336 : /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */
337 : /* This may need adjustment in the future if 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */
338 5504 : if ( EQ_16( element_mode, IVAS_CPE_MDCT ) )
339 : {
340 0 : hsCom->CngBitrate = IVAS_48k;
341 0 : move32();
342 : }
343 :
344 5504 : hsCom->numSlots = 16;
345 5504 : move16();
346 :
347 : /* NB configuration */
348 5504 : IF( bwidth == NB )
349 : {
350 0 : hsCom->FdCngSetup = FdCngSetup_nb;
351 0 : hsCom->numCoreBands = 16;
352 0 : move16();
353 0 : hsCom->regularStopBand = 16;
354 0 : move16();
355 : }
356 :
357 : /* WB configuration */
358 5504 : ELSE IF( EQ_16( bwidth, WB ) )
359 : {
360 : /* FFT 6.4kHz, no CLDFB */
361 1643 : test();
362 1643 : test();
363 1643 : IF( LE_32( hsCom->CngBitrate, ACELP_8k00 ) && EQ_16( L_frame, L_FRAME ) )
364 : {
365 0 : hsCom->FdCngSetup = FdCngSetup_wb1;
366 0 : hsCom->numCoreBands = 16;
367 0 : move16();
368 0 : hsCom->regularStopBand = 16;
369 0 : move16();
370 : }
371 : /* FFT 6.4kHz, CLDFB 8.0kHz */
372 1643 : ELSE IF( LE_32( hsCom->CngBitrate, ACELP_13k20 ) || EQ_16( L_frame, L_FRAME ) )
373 : {
374 699 : hsCom->FdCngSetup = FdCngSetup_wb2;
375 699 : hsCom->numCoreBands = 16;
376 699 : move16();
377 699 : hsCom->regularStopBand = 20;
378 699 : move16();
379 699 : IF(
380 : EQ_16( L_frame, L_FRAME16k ) )
381 : {
382 0 : hsCom->FdCngSetup = FdCngSetup_wb2;
383 0 : hsCom->numCoreBands = 20;
384 0 : move16();
385 0 : hsCom->regularStopBand = 20;
386 0 : move16();
387 0 : hsCom->FdCngSetup.fftlen = 640;
388 0 : move16();
389 0 : hsCom->FdCngSetup.stopFFTbin = 256;
390 0 : move16();
391 : }
392 : }
393 : /* FFT 8.0kHz, no CLDFB */
394 : ELSE
395 : {
396 944 : hsCom->FdCngSetup = FdCngSetup_wb3;
397 944 : hsCom->numCoreBands = 20;
398 944 : move16();
399 944 : hsCom->regularStopBand = 20;
400 944 : move16();
401 : }
402 : }
403 :
404 : /* SWB/FB configuration */
405 : ELSE
406 : {
407 : /* FFT 6.4kHz, CLDFB 14kHz */
408 3861 : IF(
409 : EQ_16( L_frame, L_FRAME ) )
410 : {
411 1805 : hsCom->FdCngSetup = FdCngSetup_swb1;
412 1805 : hsCom->numCoreBands = 16;
413 1805 : move16();
414 1805 : hsCom->regularStopBand = 35;
415 1805 : move16();
416 : }
417 : /* FFT 8.0kHz, CLDFB 16kHz */
418 : ELSE
419 : {
420 2056 : hsCom->FdCngSetup = FdCngSetup_swb2;
421 2056 : hsCom->numCoreBands = 20;
422 2056 : move16();
423 2056 : hsCom->regularStopBand = 40;
424 2056 : move16();
425 2056 : test();
426 2056 : if ( EQ_16( Last_L_frame, L_FRAME ) && EQ_16( element_mode, IVAS_CPE_DFT ) )
427 : {
428 3 : hsCom->regularStopBand = 35;
429 3 : move16();
430 : }
431 : }
432 : }
433 5504 : hsCom->fftlen = hsCom->FdCngSetup.fftlen; /*Q0*/
434 5504 : move16();
435 5504 : hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin; /*Q0*/
436 5504 : move16();
437 :
438 : /* Configure the SID quantizer and the Confort Noise Generator */
439 :
440 5504 : hsCom->startBand = 2;
441 5504 : move16();
442 5504 : hsCom->stopBand = add( hsCom->FdCngSetup.sidPartitions[( hsCom->FdCngSetup.numPartitions - 1 )], 1 ); /*Q0*/
443 5504 : move16();
444 5504 : initPartitions( hsCom->FdCngSetup.sidPartitions, hsCom->FdCngSetup.numPartitions, hsCom->startBand, hsCom->stopBand, hsCom->part,
445 5504 : &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 );
446 :
447 5504 : hsCom->nFFTpart = 21;
448 5504 : move16();
449 5504 : if ( EQ_16( hsCom->stopFFTbin, 256 ) )
450 : {
451 2504 : hsCom->nFFTpart = 20;
452 2504 : move16();
453 : }
454 5504 : if ( EQ_16( hsCom->stopFFTbin, 160 ) )
455 : {
456 0 : hsCom->nFFTpart = 17;
457 0 : move16();
458 : }
459 :
460 5504 : hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart );
461 5504 : move16();
462 19591 : FOR( j = 0; j < hsCom->nCLDFBpart; j++ )
463 : {
464 14087 : hsCom->CLDFBpart[j] = sub( hsCom->part[( j + hsCom->nFFTpart )], sub( hsCom->stopFFTbin, hsCom->startBand ) ); /*Q0*/
465 14087 : move16();
466 14087 : hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[( j + hsCom->nFFTpart )]; /*Q15*/
467 14087 : move16();
468 : }
469 :
470 5504 : stopBandFR = 1000 / 25;
471 5504 : move16();
472 5504 : if ( GT_16( stopBandFR, hsCom->stopFFTbin ) )
473 : {
474 0 : stopBandFR = hsCom->stopFFTbin; /*Q0*/
475 0 : move16();
476 : }
477 5504 : initPartitions( hsCom->FdCngSetup.shapingPartitions, hsCom->FdCngSetup.numShapingPartitions,
478 5504 : hsCom->startBand, hsCom->stopFFTbin, hFdCngDec->part_shaping, &hFdCngDec->npart_shaping, hFdCngDec->midband_shaping,
479 5504 : hFdCngDec->psize_shaping, hFdCngDec->psize_shaping_norm, &hFdCngDec->psize_shaping_norm_exp, hFdCngDec->psize_inv_shaping,
480 : stopBandFR );
481 5504 : hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; /*Q0*/
482 5504 : move16();
483 :
484 5504 : SWITCH( hsCom->fftlen )
485 : {
486 2504 : case 512:
487 2504 : hsCom->fftlenShift = 8;
488 2504 : move16();
489 2504 : hsCom->fftlenFac = 32767 /*1.0 Q15*/;
490 2504 : move16();
491 2504 : BREAK;
492 3000 : case 640:
493 3000 : hsCom->fftlenShift = 9;
494 3000 : move16();
495 3000 : hsCom->fftlenFac = 20480 /*0.625 Q15*/;
496 3000 : move16();
497 3000 : BREAK;
498 0 : default:
499 0 : assert( !"Unsupported FFT length for FD-based CNG" );
500 : BREAK;
501 : }
502 5504 : BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) );
503 5504 : BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) );
504 5504 : hsCom->frameSize = shr( hsCom->fftlen, 1 );
505 5504 : move16();
506 5504 : }
507 :
508 :
509 : /*
510 : deleteFdCngDec_fx
511 :
512 : Parameters:
513 :
514 : hFdCngDec i/0 : pointer to cng decoder structure
515 :
516 : Function:
517 : delete the instance of type FD_CNG
518 :
519 : Returns:
520 : void
521 : */
522 171883 : void deleteFdCngDec_fx( HANDLE_FD_CNG_DEC *hFdCngDec )
523 : {
524 171883 : HANDLE_FD_CNG_DEC hsDec = *hFdCngDec;
525 :
526 171883 : IF( hsDec != NULL )
527 : {
528 6430 : deleteFdCngCom_fx( &( hsDec->hFdCngCom ) );
529 6430 : free( hsDec );
530 6430 : *hFdCngDec = NULL;
531 : }
532 171883 : }
533 :
534 :
535 : /*
536 : ApplyFdCng_fx
537 :
538 : Parameters:
539 :
540 : timeDomainInput, i : pointer to time domain input
541 : cldfbBufferReal i/o: real part of the CLDFB buffer
542 : cldfbBufferImag i/o: imaginary part of the CLDFB buffer
543 : cldfbBufferScale o : pointer to the scalefactor for real and imaginary part of the CLDFB buffer
544 : st i/o: pointer to FD_CNG structure containing all buffers and variables
545 : m_frame_type i : type of frame at the decoder side
546 : stcod i : pointer to Coder_State structure
547 : st i : pointer to Decoder_State structure
548 : bitrate i : bitrate
549 : concealWholeFrame i : binary flag indicating frame loss
550 :
551 : Function:
552 : apply the CLDFB-based CNG at the decoder
553 :
554 : Returns:
555 : error
556 : */
557 :
558 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 68608 : s1 = norm_l( hFdCngCom->sidNoiseEst[k] );
715 68608 : L_tmp = L_shl( hFdCngCom->sidNoiseEst[k], s1 ); /*Q31 - hFdCngCom->sidNoiseEstExp + s1*/
716 68608 : L_tmp_exp = sub( hFdCngCom->sidNoiseEstExp, s1 );
717 68608 : L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
718 68608 : L_tmp = L_shr( L_tmp, 1 );
719 68608 : s = add( L_tmp_exp, 1 );
720 68608 : num = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
721 :
722 68608 : s1 = norm_l( hFdCngDec->partNoiseShape[k] );
723 68608 : L_tmp = L_shl( hFdCngDec->partNoiseShape[k], s1 ); /*Q31 - hFdCngDec->partNoiseShape_exp + s1*/
724 68608 : L_tmp_exp = sub( hFdCngDec->partNoiseShape_exp, s1 );
725 68608 : L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
726 68608 : s = sub( s, L_tmp_exp );
727 68608 : denom = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
728 :
729 68608 : facTab[k] = div_s( num, denom ); /*Q15 - s*/
730 68608 : move16();
731 68608 : facTabExp[k] = s;
732 68608 : move16();
733 : }
734 : /* Set unique exponent, if mantissa is equal to zero */
735 68652 : IF( EQ_16( facTab[k], 0 ) )
736 : {
737 44 : facTabExp[k] = -( ( WORD32_BITS - 1 ) );
738 44 : 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 52 : Word16 q_norm = L_norm_arr( &cngNoiseLevel[j], sub( FFTCLDFBLEN, j ) );
763 52 : 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 47448 : s1 = norm_l( sidNoiseEst[k] );
1136 47448 : L_tmp = L_shl( sidNoiseEst[k], s1 ); /*Q31 - ( hFdCngCom->sidNoiseEstExp - s1 )*/
1137 47448 : L_tmp_exp = sub( hFdCngCom->sidNoiseEstExp, s1 );
1138 47448 : L_tmp = BASOP_Util_Add_Mant32Exp( sidNoiseEst[k], hFdCngCom->sidNoiseEstExp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
1139 47448 : L_tmp = L_shr( L_tmp, 1 );
1140 47448 : s = add( L_tmp_exp, 1 );
1141 47448 : num = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
1142 :
1143 47448 : s1 = norm_l( hFdCngDec->partNoiseShape[k] );
1144 47448 : L_tmp = L_shl( hFdCngDec->partNoiseShape[k], s1 ); /*Q31 - ( hFdCngDec->partNoiseShape_ex - s1 )*/
1145 47448 : L_tmp_exp = sub( hFdCngDec->partNoiseShape_exp, s1 );
1146 47448 : L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
1147 47448 : s = sub( s, L_tmp_exp );
1148 47448 : denom = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
1149 :
1150 47448 : facTab[k] = div_s( num, denom ); /*Q15 - s*/
1151 47448 : move16();
1152 47448 : facTabExp[k] = s;
1153 47448 : move16();
1154 : }
1155 : /* Set unique exponent, IF mantissa is equal to zero */
1156 47736 : IF( EQ_16( facTab[k], 0 ) )
1157 : {
1158 566 : facTabExp[k] = -( ( WORD32_BITS - 1 ) );
1159 566 : 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 273728 : s1 = norm_l( hFdCngCom->sidNoiseEstLp[k] );
1226 273728 : L_tmp = L_shl( hFdCngCom->sidNoiseEstLp[k], s1 ); /*Q31 - ( hFdCngCom->sidNoiseEstExp - s1 )*/
1227 273728 : L_tmp_exp = sub( hFdCngCom->sidNoiseEstExp, s1 );
1228 273728 : L_tmp = BASOP_Util_Add_Mant32Exp( hFdCngCom->sidNoiseEstLp[k], hFdCngCom->sidNoiseEstExp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
1229 273728 : L_tmp = L_shr( L_tmp, 1 );
1230 273728 : s = add( L_tmp_exp, 1 );
1231 273728 : num = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
1232 :
1233 273728 : s1 = norm_l( hFdCngDec->partNoiseShape[k] );
1234 273728 : L_tmp = L_shl( hFdCngDec->partNoiseShape[k], s1 ); /*Q31 - ( hFdCngDec->partNoiseShape_exp - s1 )*/
1235 273728 : L_tmp_exp = sub( hFdCngDec->partNoiseShape_exp, s1 );
1236 273728 : L_tmp = BASOP_Util_Add_Mant32Exp( L_tmp, L_tmp_exp, DELTA_MANTISSA_W32, DELTA_EXPONENT, &L_tmp_exp );
1237 273728 : s = sub( s, L_tmp_exp );
1238 273728 : denom = extract_h( L_tmp ); /*Q15 - L_tmp_exp*/
1239 :
1240 273728 : facTab[k] = div_s( num, denom ); /*Q15 - s*/
1241 273728 : move16();
1242 273728 : facTabExp[k] = s;
1243 273728 : move16();
1244 : }
1245 : /* Set unique exponent, IF mantissa is equal to zero */
1246 275606 : if ( facTab[k] == 0 )
1247 : {
1248 3056 : facTabExp[k] = -( WORD32_BITS - 1 );
1249 3056 : 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 : Word32 *msNoiseEst;
1504 : Word32 *reIter;
1505 93989 : Word32 rescale_fac = 0;
1506 : Word64 W_tmp;
1507 93989 : Word16 tmp_s, tmp_q, min_q = 31;
1508 : Word16 q_shift;
1509 : Word32 max_l;
1510 : Word16 norm_shift;
1511 :
1512 : /* pointer initialization */
1513 93989 : periodog = hFdCngDec->hFdCngCom->periodog; /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1514 93989 : fftBuffer = hFdCngDec->hFdCngCom->fftBuffer; /*Q31 - hFdCngDec->hFdCngCom->fftBuffer_exp*/
1515 93989 : ptr_per = periodog; /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1516 93989 : msPeriodog = hFdCngDec->msPeriodog; /*Q31 - hFdCngDec->msPeriodog_exp*/
1517 93989 : msNoiseEst = hFdCngDec->msNoiseEst; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1518 :
1519 93989 : part = hFdCngDec->part_shaping; /*Q0*/
1520 93989 : psize_inv = hFdCngDec->psize_inv_shaping; /*Q15*/
1521 93989 : psize_norm = hFdCngDec->psize_shaping_norm; /*Q15 - hFdCngDec->psize_shaping_norm_exp*/
1522 :
1523 : /* variable initialization */
1524 93989 : startBand = hFdCngDec->hFdCngCom->startBand;
1525 93989 : move16();
1526 93989 : stopFFTbin = hFdCngDec->hFdCngCom->stopFFTbin;
1527 93989 : move16();
1528 :
1529 93989 : npart = hFdCngDec->npart_shaping;
1530 93989 : move16();
1531 93989 : nFFTpart = hFdCngDec->nFFTpart_shaping;
1532 93989 : move16();
1533 :
1534 : /* Perform STFT analysis */
1535 93989 : test();
1536 93989 : IF( !( EQ_16( element_mode, IVAS_CPE_MDCT ) && power_spectrum != NULL ) )
1537 : {
1538 : /* Perform STFT analysis */
1539 87961 : AnalysisSTFT_fx( timeDomainInput, Q, fftBuffer, &fftBuffer_exp, hFdCngDec->hFdCngCom );
1540 : }
1541 :
1542 93989 : test();
1543 93989 : IF( EQ_16( element_mode, IVAS_CPE_TD ) || EQ_16( element_mode, IVAS_CPE_DFT ) )
1544 : {
1545 51851 : SWITCH( hFdCngDec->hFdCngCom->fftlen )
1546 : {
1547 28061 : case 640:
1548 28061 : rescale_fac = 335544; // 4/(640 * 640) in Q35
1549 28061 : move32();
1550 28061 : BREAK;
1551 23790 : case 512:
1552 23790 : rescale_fac = 524288; // 4/(512 * 512) in Q35
1553 23790 : move32();
1554 23790 : BREAK;
1555 0 : case 320:
1556 0 : rescale_fac = 1342177; // 4/(320 * 320) in Q35
1557 0 : move32();
1558 0 : BREAK;
1559 0 : default:
1560 0 : assert( 0 );
1561 : }
1562 : /* Calculate periodogram (squared magnitude in each FFT bin) */
1563 51851 : IF( startBand == 0 )
1564 : {
1565 0 : W_tmp = W_mult0_32_32( fftBuffer[0], fftBuffer[0] ); /*Q31 - 2*fftBuffer_exp*/
1566 0 : tmp_s = W_norm( W_tmp );
1567 0 : ( *ptr_per ) = W_extract_h( W_shl( W_tmp, tmp_s ) ); /*tmp_q*/
1568 0 : tmp_q = sub( add( i_mult( sub( 31, fftBuffer_exp ), 2 ), tmp_s ), 32 );
1569 0 : min_q = tmp_q;
1570 0 : move16();
1571 0 : ptr_per++;
1572 0 : ptr_r = fftBuffer + 2; /*Q31 - fftBuffer_exp*/
1573 : }
1574 : ELSE
1575 : {
1576 51851 : ptr_r = fftBuffer + i_mult( 2, startBand ); /*Q31 - fftBuffer_exp*/
1577 : }
1578 :
1579 51851 : ptr_i = ptr_r + 1; /*Q31 - fftBuffer_exp*/
1580 :
1581 15014133 : FOR( ; ptr_per < periodog + sub( stopFFTbin, startBand ); ptr_per++ )
1582 : {
1583 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)*/
1584 :
1585 14962282 : tmp_s = W_norm( W_tmp );
1586 14962282 : tmp_q = sub( add( i_mult( sub( 31, fftBuffer_exp ), 2 ), tmp_s ), 32 );
1587 14962282 : *ptr_per = W_extract_h( W_shl( W_tmp, tmp_s ) ); /*tmp_q*/
1588 14962282 : IF( LT_16( tmp_q, min_q ) )
1589 : {
1590 178022 : reIter = ptr_per; /*tmp_q*/
1591 : Word16 diff;
1592 178022 : diff = sub( min_q, tmp_q );
1593 :
1594 1797549 : WHILE( reIter > periodog )
1595 : {
1596 1619527 : reIter--;
1597 1619527 : *reIter = L_shr( *reIter, diff ); /*tmp_q*/
1598 1619527 : move32();
1599 : }
1600 178022 : min_q = tmp_q;
1601 178022 : move16();
1602 : }
1603 : ELSE
1604 : {
1605 : Word16 diff;
1606 14784260 : diff = sub( tmp_q, min_q );
1607 14784260 : ( *ptr_per ) = L_shr( ( *ptr_per ), diff ); /*min_q*/
1608 : }
1609 :
1610 : /* 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*/
1611 14962282 : ( *ptr_per ) = Mpy_32_32_r( ( *ptr_per ), rescale_fac ); // Q = min_q+36-31=min_q+5
1612 14962282 : move32();
1613 :
1614 14962282 : ptr_r += 2;
1615 14962282 : ptr_i += 2;
1616 : }
1617 :
1618 51851 : hFdCngDec->hFdCngCom->periodog_exp = sub( 31 - 4, min_q );
1619 51851 : hFdCngDec->hFdCngCom->fftBuffer_exp = fftBuffer_exp;
1620 51851 : move16();
1621 51851 : move16();
1622 :
1623 51851 : tmp_s = getScaleFactor32( periodog, sub( stopFFTbin, startBand ) );
1624 51851 : IF( GT_16( tmp_s, 7 ) )
1625 : {
1626 51811 : tmp_s = sub( tmp_s, 7 );
1627 51811 : hFdCngDec->hFdCngCom->periodog_exp = sub( hFdCngDec->hFdCngCom->periodog_exp, tmp_s );
1628 51811 : move16();
1629 15001501 : FOR( p = 0; p < stopFFTbin - startBand; p++ )
1630 : {
1631 14949690 : periodog[p] = L_shl( periodog[p], tmp_s ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1632 14949690 : move32();
1633 : }
1634 : }
1635 :
1636 : /* Combine bins of power spectrum into partitions */
1637 51851 : i = 0;
1638 51851 : move16();
1639 3238611 : FOR( p = 0; p < npart; p++ )
1640 : {
1641 :
1642 : /* calculate mean over all bins in power partition */
1643 3186760 : temp = 0;
1644 3186760 : move16();
1645 18149042 : FOR( ; i <= part[p]; i++ )
1646 : {
1647 14962282 : temp = L_add( temp, periodog[i] ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1648 : }
1649 3186760 : msPeriodog[p] = Mpy_32_16_1( temp, psize_inv[p] ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1650 3186760 : move32();
1651 : }
1652 :
1653 51851 : hFdCngDec->msPeriodog_exp = hFdCngDec->hFdCngCom->periodog_exp;
1654 51851 : move16();
1655 :
1656 : /* compensate for the loss of variance - don't do when first noise update is not completed yet due to risk of msPeriodog[p] < 0 */
1657 51851 : IF( hFdCngDec->first_cna_noise_updated )
1658 : {
1659 22032 : i = 0;
1660 22032 : move16();
1661 :
1662 : /* This is done to avoid overflow when checking "if ( msPeriodog[p] < 1e-5f )" */
1663 22032 : IF( LT_16( hFdCngDec->msPeriodog_exp, -16 ) )
1664 : {
1665 0 : FOR( p = 0; p < NPART_SHAPING; p++ )
1666 : {
1667 0 : msPeriodog[p] = L_shr( msPeriodog[p], sub( -16, hFdCngDec->msPeriodog_exp ) ); /*Q31 - (-16)*/
1668 0 : move32();
1669 : }
1670 0 : hFdCngDec->msPeriodog_exp = -16;
1671 0 : move16();
1672 : }
1673 :
1674 1376515 : FOR( p = 0; p < npart; p++ )
1675 : {
1676 : /* calculate variance over all bins in power partition */
1677 1354483 : temp = 0;
1678 1354483 : move32();
1679 1354483 : W_tmp = 0;
1680 1354483 : move64();
1681 7686675 : FOR( ; i <= part[p]; i++ )
1682 : {
1683 6332192 : delta = L_sub( periodog[i], msPeriodog[p] ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1684 6332192 : W_tmp = W_add( W_tmp, W_mult0_32_32( delta, delta ) ); /*Q31 - 2*(hFdCngDec->hFdCngCom->periodog_exp)*/
1685 : }
1686 1354483 : tmp_s = W_norm( W_tmp );
1687 1354483 : temp = W_extract_h( W_shl( W_tmp, tmp_s ) ); // Q = 63 - 2*(31-exp) - tmp_s
1688 :
1689 1354483 : temp = Mpy_32_16_1( temp, psize_inv[p] ); // Qtemp
1690 :
1691 : /* compensate for the loss of variance */
1692 1354483 : e_temp = sub( 63, add( i_mult( sub( 31, hFdCngDec->hFdCngCom->periodog_exp ), 2 ), tmp_s ) );
1693 1354483 : temp = Sqrt32( temp, &e_temp ); /*Q31 - e_temp*/
1694 1354483 : IF( LT_16( e_temp, 0 ) )
1695 : {
1696 785901 : temp = L_shr( temp, abs_s( e_temp ) ); /*Q31*/
1697 785901 : e_temp = 0;
1698 785901 : move16();
1699 : }
1700 :
1701 1354483 : ftemp = rand_gauss( &hFdCngDec->cna_seed ); /*Q29*/
1702 :
1703 1354483 : L_tmp = Mpy_32_32( temp, ftemp ); /*Q29*/
1704 1354483 : L_tmp = L_shr( L_tmp, sub( sub( hFdCngDec->hFdCngCom->periodog_exp, e_temp ), 2 ) ); /*Q31 - hFdCngDec->msPeriodog_exp*/
1705 :
1706 1354483 : msPeriodog[p] = L_add( msPeriodog[p], L_tmp ); /*Q31 - hFdCngDec->msPeriodog_exp*/
1707 1354483 : move32();
1708 :
1709 1354483 : IF( LT_32( msPeriodog[p], L_shr( 21474 /*Q31*/, hFdCngDec->msPeriodog_exp ) ) )
1710 : {
1711 67030 : msPeriodog[p] = L_shr( 21474 /*Q31*/, hFdCngDec->msPeriodog_exp ); /*Q31 - hFdCngDec->msPeriodog_exp*/
1712 67030 : move32();
1713 : }
1714 : }
1715 : }
1716 :
1717 : /* calculate total energy (short-term and long-term) */
1718 51851 : tmp_s = getScaleFactor32( msPeriodog, npart );
1719 51851 : IF( LT_16( tmp_s, 5 ) )
1720 : {
1721 2482 : FOR( p = 0; p < npart; p++ )
1722 : {
1723 2442 : msPeriodog[p] = L_shr( msPeriodog[p], sub( 5, tmp_s ) ); /*Q31 - hFdCngDec->msPeriodog_exp - 5 + tmp_s*/
1724 2442 : move32();
1725 : }
1726 40 : hFdCngDec->msPeriodog_exp = add( hFdCngDec->msPeriodog_exp, sub( 5, tmp_s ) );
1727 40 : move16();
1728 : }
1729 51851 : enr_tot = 1;
1730 51851 : move32();
1731 51851 : enr_tot0 = 1;
1732 51851 : move32();
1733 51851 : IF( GE_16( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) )
1734 : {
1735 527 : enr_tot = L_add_sat( L_shr( sum32_fx( msPeriodog, npart ), sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) ), 1 ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1736 527 : enr_tot0 = L_add_sat( sum32_fx( msNoiseEst, npart ), 1 );
1737 : }
1738 51324 : ELSE IF( LT_16( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_exp ) )
1739 : {
1740 51324 : enr_tot = L_add_sat( sum32_fx( msPeriodog, npart ), 1 );
1741 51324 : enr_tot0 = L_add_sat( L_shr( sum32_fx( msNoiseEst, npart ), sub( hFdCngDec->msPeriodog_exp, hFdCngDec->msNoiseEst_exp ) ), 1 ); /*Q31 - hFdCngDec->msPeriodog_exp*/
1742 : }
1743 :
1744 : /* update short-term periodogram on larger partitions */
1745 51851 : maximum_32_fx( &msPeriodog[CNA_ACT_DN_LARGE_PARTITION], sub( npart, CNA_ACT_DN_LARGE_PARTITION ), &max_l );
1746 51851 : q_shift = sub( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msPeriodog_ST_exp );
1747 51851 : norm_shift = norm_l( max_l );
1748 51851 : test();
1749 51851 : IF( max_l && GT_16( q_shift, norm_shift ) )
1750 : {
1751 3782 : scale_sig32( hFdCngDec->msPeriodog_ST_fx, NPART_SHAPING, sub( norm_shift, q_shift ) ); /*Q31 - hFdCngDec->msPeriodog_ST_exp + ( norm_shift - q_shift )*/
1752 3782 : hFdCngDec->msPeriodog_ST_exp = sub( hFdCngDec->msPeriodog_ST_exp, sub( norm_shift, q_shift ) );
1753 3782 : move16();
1754 3782 : q_shift = norm_shift;
1755 3782 : move16();
1756 : }
1757 646061 : FOR( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ )
1758 : {
1759 594210 : test();
1760 594210 : q_shift = sub( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msPeriodog_ST_exp );
1761 594210 : IF( NE_16( L_frame, last_L_frame ) || LE_32( last_core_brate, SID_2k40 ) )
1762 : {
1763 : /* core Fs has changed or last frame was SID/NO_DATA -> re-initialize short-term periodogram */
1764 20578 : hFdCngDec->msPeriodog_ST_fx[p] = L_shl( msPeriodog[p], q_shift ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1765 20578 : move32();
1766 : }
1767 : ELSE
1768 : {
1769 573632 : temp = L_shl( msPeriodog[p], q_shift ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp*/
1770 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*/
1771 573632 : move32();
1772 : }
1773 : }
1774 51851 : maximum_32_fx( hFdCngDec->msPeriodog_ST_fx, NPART_SHAPING, &max_l );
1775 51851 : IF( max_l )
1776 : {
1777 51851 : q_shift = sub( norm_l( max_l ), 2 );
1778 51851 : scale_sig32( hFdCngDec->msPeriodog_ST_fx, NPART_SHAPING, q_shift ); /*Q31 - hFdCngDec->msPeriodog_ST_exp + q_shift*/
1779 51851 : hFdCngDec->msPeriodog_ST_exp = sub( hFdCngDec->msPeriodog_ST_exp, q_shift );
1780 51851 : move16();
1781 : }
1782 :
1783 : /* core Fs has changed -> partitions have changed -> re-calculate long-term periodogram */
1784 : /* part L_FRAME16k L_FRAME */
1785 : /* ... */
1786 : /* [55] 146 146 */
1787 : /* [56] 174 160 */
1788 : /* [57] 210 174 */
1789 : /* [58] 254 190 */
1790 : /* [59] 306 210 */
1791 : /* [60] 317 230 */
1792 : /* [61] 253 */
1793 :
1794 51851 : test();
1795 51851 : test();
1796 51851 : IF( EQ_16( last_L_frame, L_FRAME16k ) && EQ_16( L_frame, L_FRAME ) )
1797 : {
1798 546 : msNoiseEst[61] = msNoiseEst[58]; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1799 546 : move32();
1800 546 : msNoiseEst[60] = L_min( msNoiseEst[58], msNoiseEst[57] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1801 546 : move32();
1802 546 : msNoiseEst[59] = msNoiseEst[57]; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1803 546 : move32();
1804 546 : msNoiseEst[58] = msNoiseEst[56]; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1805 546 : move32();
1806 546 : msNoiseEst[57] = msNoiseEst[56]; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1807 546 : move32();
1808 546 : msNoiseEst[56] = L_min( msNoiseEst[56], msNoiseEst[55] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1809 546 : move32();
1810 : }
1811 51305 : ELSE IF( EQ_16( last_L_frame, L_FRAME ) && EQ_16( L_frame, L_FRAME16k ) )
1812 : {
1813 123 : msNoiseEst[56] = L_min( msNoiseEst[56], msNoiseEst[57] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1814 123 : move32();
1815 123 : msNoiseEst[57] = L_min( msNoiseEst[58], msNoiseEst[59] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1816 123 : move32();
1817 123 : msNoiseEst[58] = L_min( msNoiseEst[60], msNoiseEst[61] ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1818 123 : move32();
1819 123 : msNoiseEst[59] = 0; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1820 123 : move32();
1821 123 : msNoiseEst[60] = 0; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1822 123 : move32();
1823 123 : msNoiseEst[61] = 0; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1824 123 : move32();
1825 :
1826 123 : hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES;
1827 123 : move16();
1828 : }
1829 :
1830 : /* Smooth with IIR filter */
1831 51851 : IF( !hFdCngDec->first_cna_noise_updated )
1832 : {
1833 29819 : IF( !VAD )
1834 : {
1835 548 : Word16 e = 15;
1836 548 : move16();
1837 : /* background noise update with moving average */
1838 548 : IF( hFdCngDec->first_cna_noise_update_cnt != 0 )
1839 : {
1840 352 : alpha = Inv16( add( hFdCngDec->first_cna_noise_update_cnt, 1 ), &e ); /*Q15*/
1841 352 : alpha = shl_sat( alpha, e ); // Q15
1842 352 : maximum_32_fx( msPeriodog, npart, &max_l );
1843 352 : q_shift = sub( hFdCngDec->hFdCngCom->periodog_exp, hFdCngDec->msNoiseEst_exp );
1844 352 : norm_shift = norm_l( max_l );
1845 352 : test();
1846 352 : IF( max_l && GT_16( q_shift, norm_shift ) )
1847 : {
1848 10 : scale_sig32( msNoiseEst, NPART_SHAPING, sub( norm_shift, q_shift ) ); /*Q31 - hFdCngDec->msNoiseEst_exp + ( norm_shift - q_shift )*/
1849 10 : hFdCngDec->msNoiseEst_exp = sub( hFdCngDec->msNoiseEst_exp, sub( norm_shift, q_shift ) );
1850 10 : move16();
1851 10 : q_shift = norm_shift;
1852 10 : move16();
1853 : }
1854 21992 : FOR( p = 0; p < npart; p++ )
1855 : {
1856 21640 : temp = L_shl( msPeriodog[p], q_shift );
1857 21640 : msNoiseEst[p] = Madd_32_16( Mpy_32_16_1( msNoiseEst[p], sub( MAX_16, alpha ) ), temp, alpha ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
1858 21640 : move32();
1859 : }
1860 : }
1861 : ELSE
1862 : {
1863 196 : Copy32( msPeriodog, msNoiseEst, npart );
1864 :
1865 196 : Word16 shift1 = L_norm_arr( msNoiseEst, npart );
1866 196 : Word16 shift2 = L_norm_arr( &msNoiseEst[npart], sub( NPART_SHAPING, npart ) );
1867 196 : Word16 shift = s_max( sub( hFdCngDec->msPeriodog_exp, shift1 ), sub( hFdCngDec->msNoiseEst_exp, shift2 ) );
1868 :
1869 196 : scale_sig32( msNoiseEst, npart, sub( hFdCngDec->msPeriodog_exp, shift ) );
1870 196 : scale_sig32( &msNoiseEst[npart], sub( NPART_SHAPING, npart ), sub( hFdCngDec->msNoiseEst_exp, shift ) );
1871 :
1872 196 : hFdCngDec->msNoiseEst_exp = shift;
1873 196 : move16();
1874 : }
1875 :
1876 : /* check, if we reached the required number of first CNA noise update frames */
1877 548 : IF( LT_16( hFdCngDec->first_cna_noise_update_cnt, FIRST_CNA_NOISE_UPD_FRAMES - 1 ) )
1878 : {
1879 493 : hFdCngDec->first_cna_noise_update_cnt = add( hFdCngDec->first_cna_noise_update_cnt, 1 ); /*Q0*/
1880 493 : move16();
1881 : }
1882 : ELSE
1883 : {
1884 55 : hFdCngDec->first_cna_noise_updated = 1;
1885 55 : move16();
1886 55 : if ( EQ_16( hFdCngDec->hFdCngCom->msFrCnt_init_counter, 0 ) )
1887 : {
1888 47 : hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1;
1889 47 : move16();
1890 : }
1891 : }
1892 : }
1893 : ELSE
1894 : {
1895 29271 : hFdCngDec->first_cna_noise_update_cnt = 0;
1896 29271 : move16();
1897 : }
1898 : }
1899 : ELSE
1900 : {
1901 22032 : hFdCngDec->hFdCngCom->msFrCnt_init_counter = 1;
1902 22032 : move16();
1903 22032 : IF( VAD )
1904 : {
1905 : Word16 scale;
1906 : /* no updates during active frames except for significant energy drops */
1907 18287 : enr_ratio = BASOP_Util_Divide3232_Scale( enr_tot, enr_tot0, &scale ); /*Q15 - scale*/
1908 18287 : IF( scale <= 0 )
1909 : {
1910 912 : enr_ratio = shl( enr_ratio, scale ); /*Q15*/
1911 912 : scale = 15;
1912 912 : move16();
1913 : }
1914 : ELSE
1915 : {
1916 17375 : scale = sub( 15, scale );
1917 : }
1918 18287 : IF( LT_16( enr_ratio, shl( 1, sub( scale, 1 ) ) ) )
1919 : {
1920 : /* total energy significantly decreases during active frames -> downward update */
1921 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*/
1922 : Word16 temp_q_msNoiseEst[NPART_SHAPING];
1923 720 : Word16 min_q_msNoiseEst = MAX_16;
1924 720 : move16();
1925 45360 : FOR( p = 0; p < NPART_SHAPING; p++ )
1926 : {
1927 44640 : temp_q_msNoiseEst[p] = hFdCngDec->msNoiseEst_exp;
1928 44640 : move16();
1929 : }
1930 44983 : FOR( p = 0; p < npart; p++ )
1931 : {
1932 44263 : L_tmp = L_shr( msPeriodog[p], sub( sub( 31, hFdCngDec->hFdCngCom->periodog_exp ), 4 ) );
1933 44263 : IF( LT_32( L_tmp, msNoiseEst[p] ) )
1934 : {
1935 42915 : 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]*/
1936 42915 : move32();
1937 42915 : temp_q_msNoiseEst[p] = sub( add( hFdCngDec->msNoiseEst_exp, scale ), 15 );
1938 42915 : move16();
1939 : }
1940 44263 : min_q_msNoiseEst = s_min( temp_q_msNoiseEst[p], min_q_msNoiseEst );
1941 : }
1942 45360 : FOR( p = 0; p < NPART_SHAPING; p++ )
1943 : {
1944 44640 : msNoiseEst[p] = L_shl( msNoiseEst[p], sub( min_q_msNoiseEst, temp_q_msNoiseEst[p] ) ); /*min_q_msNoiseEst*/
1945 44640 : move32();
1946 : }
1947 720 : hFdCngDec->msNoiseEst_exp = min_q_msNoiseEst;
1948 720 : move16();
1949 : }
1950 : ELSE
1951 : {
1952 : /* energy significantly decreases in one of the larger partitions during active frames -> downward update */
1953 219348 : FOR( p = CNA_ACT_DN_LARGE_PARTITION; p < npart; p++ )
1954 : {
1955 201781 : L_tmp = L_shr_sat( hFdCngDec->msPeriodog_ST_fx[p], sub( hFdCngDec->msNoiseEst_exp, hFdCngDec->msPeriodog_ST_exp ) ); /*Q31 - hFdCngDec->msPeriodog_ST_exp*/
1956 201781 : IF( LT_32( L_tmp, msNoiseEst[p] ) )
1957 : {
1958 16330 : 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*/
1959 16330 : move32();
1960 : }
1961 : }
1962 : }
1963 : }
1964 : ELSE
1965 : {
1966 3745 : test();
1967 3745 : if ( GE_16( bwidth, WB ) && hFdCngDec->ms_last_inactive_bwidth == NB )
1968 : {
1969 : /* bandwidth increased -> set counter for fast initilization */
1970 52 : hFdCngDec->ms_cnt_bw_up = FIRST_CNA_NOISE_UPD_FRAMES;
1971 52 : move16();
1972 : }
1973 3745 : hFdCngDec->ms_last_inactive_bwidth = bwidth;
1974 3745 : move16();
1975 : /* update background noise during inactive frames */
1976 3745 : ptr_per = msNoiseEst; /*Q31 - hFdCngDec->msNoiseEst_exp*/
1977 233834 : FOR( p = 0; p < npart; p++ )
1978 : {
1979 230089 : Word16 i_e = 15;
1980 230089 : move16();
1981 230089 : enr = msPeriodog[p]; /*Q31 - hFdCngDec->msPeriodog_exp*/
1982 230089 : move32();
1983 230089 : enr_e = hFdCngDec->msPeriodog_exp;
1984 230089 : move16();
1985 230089 : alpha = 31130; // 0.95f in Q15
1986 230089 : move16();
1987 : /* bandwidth increased -> do fast re-initilization */
1988 230089 : test();
1989 230089 : IF( GT_16( hFdCngDec->ms_cnt_bw_up, 0 ) && GT_16( p, 55 ) )
1990 : {
1991 1905 : alpha = Inv16( add( hFdCngDec->ms_cnt_bw_up, 1 ), &i_e ); /*Q15 - i_e*/
1992 1905 : IF( i_e < 0 )
1993 : {
1994 1905 : alpha = shr( alpha, negate( i_e ) ); // Q15
1995 : }
1996 : }
1997 228184 : ELSE IF( ( BASOP_Util_Cmp_Mant32Exp( enr, enr_e, *ptr_per, hFdCngDec->msNoiseEst_exp ) < 0 ) && EQ_16( part[p], 1 ) )
1998 : {
1999 : /* faster downward update for single-bin partitions */
2000 1136 : alpha = 26214; // 0.8f in Q15
2001 1136 : move16();
2002 : }
2003 227048 : ELSE IF( BASOP_Util_Cmp_Mant32Exp( enr, enr_e, *ptr_per, add( hFdCngDec->msNoiseEst_exp, 1 ) ) > 0 )
2004 : {
2005 : /* prevent abrupt upward updates */
2006 98889 : test();
2007 98889 : IF( ( norm_l( *ptr_per ) == 0 ) && *ptr_per )
2008 : {
2009 18 : enr = *ptr_per; /*Q31 - hFdCngDec->msNoiseEst_exp*/
2010 18 : scale_sig32( msNoiseEst, NPART_SHAPING, -1 );
2011 18 : hFdCngDec->msNoiseEst_exp = add( hFdCngDec->msNoiseEst_exp, 1 );
2012 18 : move16();
2013 : }
2014 : ELSE
2015 : {
2016 98871 : enr = L_shl( *ptr_per, 1 ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
2017 : }
2018 98889 : enr_e = hFdCngDec->msNoiseEst_exp;
2019 98889 : move16();
2020 : }
2021 :
2022 : /* IIR smoothing */
2023 230089 : test();
2024 230089 : IF( *ptr_per != 0 && alpha != 0 )
2025 : {
2026 229361 : *ptr_per = Mpy_32_16_1( ( *ptr_per ), alpha ); /*Q31 - hFdCngDec->msNoiseEst_exp*/
2027 229361 : move32();
2028 229361 : if ( *ptr_per == 0 )
2029 : {
2030 62 : *ptr_per = 1;
2031 62 : move32();
2032 : }
2033 : }
2034 : ELSE
2035 : {
2036 728 : *ptr_per = 0;
2037 728 : move32();
2038 : }
2039 230089 : IF( enr )
2040 : {
2041 218868 : q_shift = sub( enr_e, hFdCngDec->msNoiseEst_exp );
2042 218868 : norm_shift = norm_l( enr );
2043 218868 : IF( LE_16( q_shift, norm_shift ) )
2044 : {
2045 218868 : enr = L_shl( enr, q_shift ); /*Q31 - hFdCngDec->msNoiseEst_exp + q_shift*/
2046 218868 : move32();
2047 : }
2048 : ELSE
2049 : {
2050 0 : enr_e = sub( enr_e, norm_shift );
2051 0 : enr = L_shl( enr, norm_shift ); /*Q31 - hFdCngDec->msNoiseEst_exp + norm_shift*/
2052 0 : scale_sig32( msNoiseEst, NPART_SHAPING, sub( norm_shift, q_shift ) ); /*Q31 - ( hFdCngDec->msNoiseEst_exp - ( norm_shift - q_shift ) )*/
2053 0 : hFdCngDec->msNoiseEst_exp = sub( hFdCngDec->msNoiseEst_exp, sub( norm_shift, q_shift ) );
2054 0 : move16();
2055 : }
2056 : }
2057 230089 : *ptr_per = Madd_32_16( ( *ptr_per ), enr, sub( MAX_16, alpha ) ); /*Q31 - enr_e*/
2058 230089 : move32();
2059 230089 : ptr_per++;
2060 : }
2061 :
2062 3745 : IF( hFdCngDec->ms_cnt_bw_up > 0 )
2063 : {
2064 357 : hFdCngDec->ms_cnt_bw_up = sub( hFdCngDec->ms_cnt_bw_up, 1 );
2065 357 : move16();
2066 : }
2067 : }
2068 : }
2069 51851 : maximum_32_fx( msNoiseEst, NPART_SHAPING, &max_l );
2070 51851 : IF( max_l )
2071 : {
2072 24631 : q_shift = sub( norm_l( max_l ), 2 );
2073 24631 : scale_sig32( msNoiseEst, NPART_SHAPING, q_shift ); /*Q31 - ( hFdCngDec->msNoiseEst_exp - q_shift )*/
2074 24631 : hFdCngDec->msNoiseEst_exp = sub( hFdCngDec->msNoiseEst_exp, q_shift );
2075 24631 : move16();
2076 : }
2077 :
2078 51851 : Copy32( msNoiseEst, hFdCngDec->msPsd_fx, npart ); /*Q31 - ( hFdCngDec->msNoiseEst_exp )*/
2079 51851 : hFdCngDec->msPsd_exp_fft = hFdCngDec->msNoiseEst_exp;
2080 51851 : move16();
2081 :
2082 : /* Expand partitions into bins of power spectrum */
2083 51851 : scalebands_fx( msNoiseEst, part, nFFTpart, hFdCngDec->midband_shaping, nFFTpart, sub( stopFFTbin, startBand ), hFdCngDec->bandNoiseShape, 1 );
2084 51851 : hFdCngDec->bandNoiseShape_exp = hFdCngDec->msNoiseEst_exp;
2085 51851 : move16();
2086 51851 : Copy32( hFdCngDec->bandNoiseShape, &hFdCngDec->smoothed_psd_fx[startBand], sub( stopFFTbin, startBand ) ); /*Q31 - hFdCngDec->bandNoiseShape_exp*/
2087 51851 : hFdCngDec->smoothed_psd_exp = hFdCngDec->bandNoiseShape_exp;
2088 51851 : move16();
2089 51851 : set32_fx( &hFdCngDec->smoothed_psd_fx[stopFFTbin], 0, sub( L_FRAME16k, stopFFTbin ) );
2090 : }
2091 : ELSE
2092 : {
2093 42138 : test();
2094 42138 : IF( EQ_16( element_mode, IVAS_CPE_MDCT ) && power_spectrum != NULL )
2095 : {
2096 : /* use power spectrum calculated in the MDCT-domain instead of calculating new power spectrum */
2097 6028 : periodog = power_spectrum; /*Q_power_spectrum*/
2098 6028 : periodog_exp = sub( 31, Q_power_spectrum );
2099 : }
2100 : ELSE
2101 : {
2102 : /* Compute the squared magnitude in each FFT bin */
2103 36110 : IF( startBand == 0 )
2104 : {
2105 0 : W_tmp = W_mult0_32_32( fftBuffer[0], fftBuffer[0] ); /* DC component */ /*Q31 - 2*fftBuffer_exp*/
2106 0 : min_q = 2;
2107 0 : move16();
2108 0 : ( *ptr_per ) = W_extract_l( W_shr( W_tmp, sub( i_mult( sub( 31, fftBuffer_exp ), 2 ), min_q ) ) );
2109 0 : move32();
2110 0 : ptr_per++;
2111 0 : ptr_r = fftBuffer + 2; /*Q31 - fftBuffer_exp*/
2112 : }
2113 : ELSE
2114 : {
2115 36110 : ptr_r = fftBuffer + i_mult( 2, startBand ); /*Q31 - fftBuffer_exp*/
2116 : }
2117 :
2118 36110 : ptr_i = ptr_r + 1; /*Q31 - fftBuffer_exp*/
2119 :
2120 36110 : SWITCH( hFdCngDec->hFdCngCom->fftlen )
2121 : {
2122 16851 : case 640:
2123 16851 : rescale_fac = 20972; // 4/(640 * 640) in Q31
2124 16851 : move32();
2125 16851 : BREAK;
2126 19259 : case 512:
2127 19259 : rescale_fac = 32768; // 4/(512 * 512) in Q31
2128 19259 : move32();
2129 19259 : BREAK;
2130 0 : case 320:
2131 0 : rescale_fac = 83886; // 4/(320 * 320) in Q31
2132 0 : move32();
2133 0 : BREAK;
2134 0 : default:
2135 0 : assert( 0 );
2136 : }
2137 :
2138 10286514 : FOR( ; ptr_per < periodog + stopFFTbin - startBand; ptr_per++ )
2139 : {
2140 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)*/
2141 :
2142 10250404 : tmp_s = W_norm( W_tmp ); /*tmp_q*/
2143 10250404 : tmp_q = sub( add( i_mult( sub( 31, fftBuffer_exp ), 2 ), tmp_s ), 32 );
2144 10250404 : IF( tmp_q < 0 )
2145 : {
2146 195471 : W_tmp = W_shr( W_tmp, negate( tmp_q ) ); /*Q31 - 2*(fftBuffer_exp) + tmp_q*/
2147 : }
2148 10250404 : IF( LT_16( tmp_q, min_q ) )
2149 : {
2150 244000 : reIter = ptr_per; /*tmp_q*/
2151 : Word16 diff;
2152 244000 : IF( ( tmp_q <= 0 ) )
2153 : {
2154 200048 : diff = min_q;
2155 200048 : move16();
2156 : }
2157 : ELSE
2158 : {
2159 43952 : diff = sub( min_q, tmp_q );
2160 : }
2161 4678436 : WHILE( reIter > periodog )
2162 : {
2163 4434436 : reIter--;
2164 4434436 : *reIter = L_shr( *reIter, diff ); /*tmp_q*/
2165 4434436 : move32();
2166 : }
2167 244000 : IF( tmp_q >= 0 )
2168 : {
2169 48529 : min_q = tmp_q;
2170 48529 : move16();
2171 : }
2172 195471 : ELSE IF( tmp_q < 0 )
2173 : {
2174 195471 : min_q = 0;
2175 195471 : move16();
2176 : }
2177 : }
2178 10250404 : ( *ptr_per ) = W_extract_l( W_shr( W_tmp, sub( i_mult( sub( 31, fftBuffer_exp ), 2 ), min_q ) ) ); // Q = min_q
2179 10250404 : move32();
2180 :
2181 : /* 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*/
2182 10250404 : ( *ptr_per ) = Mpy_32_32_r( ( *ptr_per ), rescale_fac ); // Q = min_q
2183 10250404 : move32();
2184 10250404 : IF( tmp_q <= 0 )
2185 : {
2186 266083 : ( *ptr_per ) = L_shl( ( *ptr_per ), negate( tmp_q ) );
2187 266083 : move32();
2188 : }
2189 :
2190 10250404 : ptr_r += 2;
2191 10250404 : ptr_i += 2;
2192 : }
2193 :
2194 36110 : hFdCngDec->hFdCngCom->periodog_exp = sub( 31, min_q );
2195 36110 : move16();
2196 36110 : hFdCngDec->hFdCngCom->fftBuffer_exp = fftBuffer_exp;
2197 36110 : move16();
2198 :
2199 36110 : tmp_s = getScaleFactor32( periodog, L_frame );
2200 36110 : IF( GT_16( tmp_s, 3 ) )
2201 : {
2202 24902 : tmp_s = sub( tmp_s, 3 );
2203 24902 : hFdCngDec->hFdCngCom->periodog_exp = sub( hFdCngDec->hFdCngCom->periodog_exp, tmp_s );
2204 24902 : move16();
2205 6712122 : FOR( p = 0; p < stopFFTbin - startBand; p++ )
2206 : {
2207 6687220 : periodog[p] = L_shl( periodog[p], tmp_s ); /*Q31 - hFdCngDec->hFdCngCom->periodog_exp + tmp_s*/
2208 6687220 : move32();
2209 : }
2210 : }
2211 36110 : periodog_exp = hFdCngDec->hFdCngCom->periodog_exp;
2212 36110 : move16();
2213 : }
2214 :
2215 : /* Adjust to the desired frequency resolution by averaging over spectral partitions for SID transmission */
2216 42138 : bandcombinepow( periodog, periodog_exp, sub( stopFFTbin, startBand ), part, npart, psize_inv, hFdCngDec->msPeriodog, &hFdCngDec->msPeriodog_exp );
2217 :
2218 :
2219 42138 : hFdCngDec->msPeriodog_exp_fft = hFdCngDec->msPeriodog_exp;
2220 42138 : move16();
2221 42138 : hFdCngDec->msPeriodog_exp_cldfb = hFdCngDec->msPeriodog_exp;
2222 42138 : move16();
2223 :
2224 :
2225 : /* Compress MS inputs */
2226 42138 : compress_range( hFdCngDec->msPeriodog, hFdCngDec->msPeriodog_exp, hFdCngDec->msLogPeriodog, npart );
2227 :
2228 : /* Call the minimum statistics routine for noise estimation */
2229 42138 : minimum_statistics_fx(
2230 : npart,
2231 : nFFTpart,
2232 : psize_norm,
2233 42138 : hFdCngDec->msLogPeriodog,
2234 42138 : hFdCngDec->msNoiseFloor,
2235 42138 : hFdCngDec->msLogNoiseEst,
2236 42138 : hFdCngDec->msAlpha,
2237 42138 : hFdCngDec->msPsd,
2238 42138 : hFdCngDec->msPsdFirstMoment,
2239 42138 : hFdCngDec->msPsdSecondMoment,
2240 42138 : hFdCngDec->msMinBuf,
2241 42138 : hFdCngDec->msBminWin,
2242 42138 : hFdCngDec->msBminSubWin,
2243 42138 : hFdCngDec->msCurrentMin,
2244 42138 : hFdCngDec->msCurrentMinOut,
2245 42138 : hFdCngDec->msCurrentMinSubWindow,
2246 42138 : hFdCngDec->msLocalMinFlag,
2247 42138 : hFdCngDec->msNewMinFlag,
2248 42138 : hFdCngDec->msPeriodogBuf,
2249 : &( hFdCngDec->msPeriodogBufPtr ),
2250 : hFdCngDec->hFdCngCom,
2251 : DEC, element_mode );
2252 :
2253 2631815 : FOR( i = 0; i < hFdCngDec->npart_shaping; i++ )
2254 : {
2255 2589677 : hFdCngDec->msPsd_fx[i] = (Word32) hFdCngDec->msPsd[i];
2256 2589677 : move32();
2257 : }
2258 42138 : hFdCngDec->msPsd_exp_fft = 6 + WORD16_BITS;
2259 42138 : move16();
2260 :
2261 : /* Expand MS outputs */
2262 42138 : expand_range( hFdCngDec->msLogNoiseEst, hFdCngDec->msNoiseEst, &hFdCngDec->msNoiseEst_exp, npart );
2263 : }
2264 93989 : }
2265 :
2266 :
2267 : /*
2268 : FdCng_decodeSID_fx
2269 :
2270 : Parameters:
2271 :
2272 : st i/o: FD_CNG structure containing all buffers and variables
2273 : bs_word16 i : Bitstream
2274 : amrwb_io i : amr wideband mode
2275 : preemph_fac i : preemphase factor
2276 :
2277 : Function:
2278 : decode the FD-CNG bitstream
2279 :
2280 : Returns:
2281 : void
2282 : */
2283 0 : void FdCng_decodeSID_fx( HANDLE_FD_CNG_COM st, Decoder_State *corest )
2284 : {
2285 : Word16 i, N, index;
2286 : Word32 *sidNoiseEst;
2287 :
2288 : Word16 indices[32], v16[32];
2289 : Word32 v[32], gain;
2290 :
2291 : Word32 tmp, maxVal, E_ExpLd64;
2292 : Word16 sidNoiseEst_Exp;
2293 :
2294 : Word16 preemph_fac;
2295 : Word32 *invTrfMatrix_fx;
2296 : Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
2297 0 : invTrfMatrix_fx = (Word32 *) tmpRAM_fx;
2298 :
2299 :
2300 0 : sidNoiseEst = st->sidNoiseEst; /*Q31 - st->sidNoiseEstExp*/
2301 0 : move16();
2302 0 : preemph_fac = corest->preemph_fac; /*Q15*/
2303 0 : move16();
2304 :
2305 0 : N = st->npart; /*Q0*/
2306 0 : move16();
2307 :
2308 0 : st->sid_frame_counter = add( st->sid_frame_counter, 1 ); /*Q15*/
2309 0 : move16();
2310 :
2311 : /* Read bitstream */
2312 0 : FOR( i = 0; i < stages_37bits; i++ )
2313 : {
2314 0 : indices[i] = get_next_indice_fx( corest, bits_37bits[i] ); /*Q0*/
2315 0 : move16();
2316 : }
2317 0 : index = get_next_indice_fx( corest, 7 ); /*Q0*/
2318 :
2319 : /* MSVQ decoder */
2320 0 : IF( corest->element_mode != EVS_MONO )
2321 : {
2322 0 : create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC );
2323 0 : msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages_37bits, N, maxN_37bits, indices, 1, invTrfMatrix_fx, v, NULL, 7 );
2324 : }
2325 : ELSE
2326 : {
2327 0 : msvq_decoder(
2328 : cdk_37bits,
2329 : stages_37bits,
2330 : N,
2331 : maxN_37bits,
2332 : indices,
2333 : v16 );
2334 :
2335 0 : FOR( i = 0; i < N; i++ )
2336 : {
2337 0 : v[i] = L_deposit_h( v16[i] ); /*Q23*/
2338 0 : move32();
2339 : }
2340 : }
2341 :
2342 :
2343 : /* decode gain, format gain: Q9.23 */
2344 0 : gain = L_shl( L_deposit_l( index ), WORD32_BITS - 1 - 8 );
2345 0 : gain = L_sub( gain, 503316480l /*60.0 Q23*/ ); /*Q23*/
2346 0 : gain = Mpy_32_16_1( gain, 21845 /*2.0f/3.0f Q15*/ ); /*Q23*/
2347 :
2348 :
2349 : /* Apply gain and undo log */
2350 :
2351 : /* calculate worst case for scaling */
2352 0 : maxVal = L_add( 0x80000000 /*-1.0 Q31*/, 0 );
2353 0 : FOR( i = 0; i < N; i++ )
2354 : {
2355 0 : maxVal = L_max( maxVal, v[i] ); /*Q23*/
2356 : }
2357 :
2358 0 : maxVal = L_add( maxVal, gain ); /*Q23*/
2359 0 : maxVal = L_shl( Mpy_32_16_1( maxVal, 21771 /*0.66438561897 Q15*/ ), 1 ); /*Q23*/
2360 :
2361 0 : sidNoiseEst_Exp = 0;
2362 0 : move16();
2363 0 : FOR( ; maxVal >= 0; maxVal -= 33554432l /*0.015625 Q31*/ )
2364 : {
2365 0 : sidNoiseEst_Exp = add( sidNoiseEst_Exp, 1 );
2366 : }
2367 0 : st->sidNoiseEstExp = sidNoiseEst_Exp;
2368 0 : move16();
2369 0 : E_ExpLd64 = L_shl( sidNoiseEst_Exp, WORD32_BITS - 1 - LD_DATA_SCALE );
2370 :
2371 : /* format v: Q9.23, format sidNoiseEst: Q6.26, 0.66438561897 = log10(10)/log10(2.0) / 10.0 * 2.0 */
2372 0 : FOR( i = 0; i < N; i++ )
2373 : {
2374 0 : tmp = L_add( v[i], gain ); /*Q23*/
2375 0 : tmp = L_shl( Mpy_32_16_1( tmp, 21771 /*0.66438561897 Q15*/ ), 1 ); /*Q23*/
2376 0 : tmp = L_sub( tmp, E_ExpLd64 );
2377 0 : assert( tmp < 0 );
2378 0 : st->sidNoiseEst[i] = BASOP_Util_InvLog2( tmp ); /*Q31 - st->sidNoiseEstExp*/
2379 0 : move32();
2380 : }
2381 :
2382 : /* NB last band energy compensation */
2383 0 : IF( st->CngBandwidth == NB )
2384 : {
2385 0 : st->sidNoiseEst[( N - 1 )] = Mpy_32_16_1( st->sidNoiseEst[( N - 1 )], NB_LAST_BAND_SCALE ); /*Q31 - st->sidNoiseEstExp*/
2386 0 : move32();
2387 : }
2388 :
2389 0 : test();
2390 0 : IF( EQ_16( st->CngBandwidth, SWB ) && LE_32( st->CngBitrate, ACELP_13k20 ) )
2391 : {
2392 0 : st->sidNoiseEst[( N - 1 )] = Mpy_32_16_1( st->sidNoiseEst[( N - 1 )], SWB_13k2_LAST_BAND_SCALE ); /*Q31 - st->sidNoiseEstExp*/
2393 0 : move32();
2394 : }
2395 :
2396 :
2397 0 : scalebands( sidNoiseEst, st->part, st->npart, st->midband, st->nFFTpart, sub( st->stopBand, st->startBand ), st->cngNoiseLevel, 1 );
2398 0 : st->cngNoiseLevelExp = st->sidNoiseEstExp;
2399 0 : move16();
2400 :
2401 :
2402 0 : lpc_from_spectrum( st, st->startBand, st->stopFFTbin, preemph_fac );
2403 0 : }
2404 :
2405 : /*
2406 : noisy_speech_detection_fx
2407 :
2408 : Parameters:
2409 :
2410 : vad i : VAD decision
2411 : Etot i : total channel E
2412 : Etot_exp i : exponent for total channel E
2413 : totalNoise i : noise estimate over all critical bands
2414 : totalNoise_exp i : exponent for noise estimate over all critical bands
2415 : lp_noise i/o: pointer to long term total Noise energy average
2416 : lp_speech i/o: pointer to long term active speech energy average
2417 :
2418 : Function:
2419 : detector for noisy speech, lp_noise and lp_speech are scaled by LD_DATA_SCALE+2 bits
2420 :
2421 : Returns: flag, that indicates whether noisy speech has been detected
2422 :
2423 : void
2424 : */
2425 395818 : void noisy_speech_detection_fx(
2426 : HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: FD_CNG structure */
2427 : const Word16 vad, /*Q0*/
2428 : const Word16 *syn, /* i : input time-domain frame Q*/
2429 : const Word16 Q )
2430 : {
2431 : Word16 i;
2432 : Word32 tmp;
2433 : Word32 Etot;
2434 : Word16 Etot_exp;
2435 : Word32 logEtot;
2436 : Word32 logEtotExp;
2437 : Word32 totalNoise;
2438 : Word16 totalNoise_exp;
2439 : Word32 logTotalNoise;
2440 : Word32 logTotalNoiseExp;
2441 :
2442 :
2443 395818 : IF( vad == 0 )
2444 : {
2445 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*/
2446 :
2447 : /*
2448 : - logTotalNoise is scaled by LD_DATA_SCALE+2
2449 : - logTotalNoise = 10.0 * log10(totalNoise + DELTA);
2450 : - constant: -0.78125 = 10.0*log10(DELTA)/(1<<(LD_DATA_SCALE+2))
2451 : - constant: 0.75257498916 = 10.0 * log10(2.0)/log10(10.0)/(1<<2)
2452 : */
2453 38198 : IF( totalNoise == 0 )
2454 : {
2455 562 : logTotalNoise = L_add( -1677721600l /*-0.78125 Q31*/, 0 ); /*Q31*/
2456 : }
2457 : ELSE
2458 : {
2459 37636 : logTotalNoise = BASOP_Util_Log2( totalNoise ); /*Q25*/
2460 37636 : logTotalNoiseExp = L_shl( L_deposit_l( totalNoise_exp ), WORD32_BITS - 1 - LD_DATA_SCALE );
2461 37636 : logTotalNoise = Mpy_32_16_1( L_add( logTotalNoise, logTotalNoiseExp ), 24660 /*0.75257498916 Q15*/ ); /*Q31 - logTotalNoiseExp*/
2462 : }
2463 :
2464 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*/
2465 38198 : move32();
2466 : }
2467 : ELSE
2468 : {
2469 357620 : Etot = 0;
2470 357620 : move32();
2471 357620 : Etot_exp = 31;
2472 357620 : move16();
2473 108222068 : FOR( i = 0; i < hFdCngDec->hFdCngCom->frameSize; i++ )
2474 : {
2475 107864448 : tmp = L_shr_r( L_mult0( syn[i], syn[i] ), sub( Etot_exp, 31 ) ); /*2*(Q) - (Etot_exp - 31)*/
2476 107864448 : IF( LT_32( L_sub( maxWord32, tmp ), Etot ) )
2477 : {
2478 48861 : Etot_exp = add( Etot_exp, 1 );
2479 48861 : Etot = L_shr_r( Etot, 1 ); /*Q31 - Etot_exp*/
2480 48861 : tmp = L_shr_r( tmp, 1 );
2481 : }
2482 107864448 : Etot = L_add( Etot, tmp );
2483 : }
2484 357620 : Etot_exp = sub( Etot_exp, shl( Q, 1 ) );
2485 :
2486 : /*
2487 : - logEtot is scaled by LD_DATA_SCALE+2
2488 : - logEtot = 10.0 * log10(totalNoise + DELTA);
2489 : - constant: -0.78125 = 10.0*log10(DELTA)/(1<<(LD_DATA_SCALE+2))
2490 : - constant: 0.75257498916 = 10.0 * log10(2.0)/log10(10.0)/(1<<2)
2491 : */
2492 357620 : IF( Etot == 0 )
2493 : {
2494 3639 : logEtot = L_add( -1677721600l /*-0.78125 Q31*/, 0 ); /*Q31*/
2495 : }
2496 : ELSE
2497 : {
2498 353981 : logEtot = BASOP_Util_Log2( Etot ); /*Q25*/
2499 353981 : logEtotExp = L_shl( L_deposit_l( Etot_exp ), WORD32_BITS - 1 - LD_DATA_SCALE );
2500 353981 : logEtot = Mpy_32_16_1( L_add( logEtot, logEtotExp ), 24660 /*0.75257498916 Q15*/ ); /*Q31 - logEtotExp*/
2501 353981 : IF( EQ_16( hFdCngDec->hFdCngCom->frameSize, L_FRAME16k ) )
2502 : {
2503 251267 : logEtot = L_add( logEtot, -184894985l /*-0.086098436822497 Q31*/ ); /*Q31 - logEtotExp*/
2504 : }
2505 : ELSE
2506 : {
2507 102714 : logEtot = L_add( logEtot, -176765584l /*-0.082312889439370 Q31*/ ); /*Q31 - logEtotExp*/
2508 : }
2509 : }
2510 :
2511 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*/
2512 357620 : move32();
2513 : }
2514 :
2515 395818 : tmp = L_sub( hFdCngDec->lp_speech, 377487360l /*45.0 Q23*/ ); /*Q23*/
2516 :
2517 395818 : if ( LT_32( hFdCngDec->lp_noise, tmp ) )
2518 : {
2519 177043 : hFdCngDec->lp_noise = tmp; /*Q23*/
2520 177043 : move32();
2521 : }
2522 :
2523 395818 : hFdCngDec->hFdCngCom->flag_noisy_speech = 0;
2524 395818 : move16();
2525 395818 : if ( LT_32( L_sub( hFdCngDec->lp_speech, hFdCngDec->lp_noise ), 234881024l /*28.0 Q23*/ ) )
2526 : {
2527 31179 : hFdCngDec->hFdCngCom->flag_noisy_speech = 1;
2528 31179 : move16();
2529 : }
2530 :
2531 :
2532 395818 : return;
2533 : }
2534 :
2535 0 : void generate_comfort_noise_dec_fx(
2536 : Word32 **bufferReal, /* o : matrix to real part of input bands bufferScale*/
2537 : Word32 **bufferImag, /* o : matrix to imaginary part of input bands bufferScale*/
2538 : Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */
2539 : Decoder_State *st,
2540 : Word16 *Q_new,
2541 : Word16 gen_exc, /*Q0*/
2542 : const Word16 nchan_out /* i : number of output channels Q0*/
2543 : )
2544 : {
2545 : Word16 i, j, s, sc, sn, cnt;
2546 : Word16 startBand2;
2547 : Word16 stopFFTbin2;
2548 : Word16 scaleCLDFB;
2549 : Word16 preemph_fac;
2550 : Word32 sqrtNoiseLevel;
2551 : Word16 randGaussExp;
2552 : Word16 fftBufferExp;
2553 : Word16 cngNoiseLevelExp;
2554 : Word16 *seed;
2555 : Word16 *timeDomainOutput;
2556 : Word32 *ptr_r, *ptr_i;
2557 : Word32 *cngNoiseLevel;
2558 : Word32 *ptr_level;
2559 : Word32 *fftBuffer;
2560 : Word16 old_syn_pe_tmp[16];
2561 0 : Word16 tcx_transition = 0;
2562 0 : HANDLE_FD_CNG_DEC hFdCngDec = st->hFdCngDec;
2563 0 : HANDLE_FD_CNG_COM hFdCngCom = hFdCngDec->hFdCngCom;
2564 : TCX_DEC_HANDLE hTcxDec;
2565 0 : move16();
2566 :
2567 0 : hTcxDec = st->hTcxDec;
2568 :
2569 : /* Warning fix */
2570 0 : s = 0;
2571 0 : move16();
2572 : // PMTE(); /*IVAS CODE need to be added */
2573 :
2574 : /* pointer initialization */
2575 :
2576 0 : cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
2577 0 : cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
2578 0 : ptr_level = cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
2579 0 : seed = &( hFdCngCom->seed );
2580 0 : fftBuffer = hFdCngCom->fftBuffer; /*Q31 - hFdCngCom->fftBuffer_exp*/
2581 0 : timeDomainOutput = hFdCngCom->timeDomainBuffer;
2582 :
2583 : /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
2584 0 : scaleCLDFB = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); /*CLDFBinvScalingFactor_EXP + 1*/
2585 :
2586 : /*
2587 : Generate Gaussian random noise in real and imaginary parts of the FFT bins
2588 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
2589 : scaling Gaussian random noise: format Q3.29
2590 : */
2591 0 : sn = 0;
2592 0 : move16();
2593 0 : IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
2594 : {
2595 0 : sn = add( sn, 1 );
2596 0 : cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
2597 0 : move16();
2598 : }
2599 :
2600 0 : randGaussExp = CNG_RAND_GAUSS_SHIFT;
2601 0 : move16();
2602 0 : cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
2603 0 : IF( hFdCngCom->startBand == 0 )
2604 : {
2605 : /* DC component in FFT */
2606 0 : s = 0;
2607 0 : move16();
2608 0 : sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s ); /*Q31 - s*/
2609 :
2610 0 : fftBuffer[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*Q31 - hFdCngCom->fftBuffer_exp*/
2611 0 : move32();
2612 :
2613 : /* Nyquist frequency is discarded */
2614 0 : fftBuffer[1] = L_deposit_l( 0 );
2615 :
2616 0 : ptr_level = ptr_level + 1;
2617 0 : ptr_r = fftBuffer + 2; /*Q31 - hFdCngCom->fftBuffer_exp*/
2618 0 : cnt = sub( cnt, 1 );
2619 : }
2620 : ELSE
2621 : {
2622 0 : startBand2 = shl( hFdCngCom->startBand, 1 ); /*Q0*/
2623 0 : set32_fx( fftBuffer, 0, startBand2 );
2624 0 : ptr_r = fftBuffer + startBand2; /*Q31 - hFdCngCom->fftBuffer_exp*/
2625 : }
2626 :
2627 0 : sn = add( sn, 1 );
2628 0 : ptr_i = ptr_r + 1; /*Q31 - hFdCngCom->fftBuffer_exp*/
2629 0 : FOR( i = 0; i < cnt; i++ )
2630 : {
2631 0 : s = 0;
2632 0 : move16();
2633 0 : sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s ); /*Q31 - s*/
2634 :
2635 : /* Real part in FFT bins */
2636 0 : *ptr_r = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
2637 0 : move32();
2638 :
2639 : /* Imaginary part in FFT bins */
2640 0 : *ptr_i = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
2641 0 : move32();
2642 :
2643 0 : ptr_r = ptr_r + 2;
2644 0 : ptr_i = ptr_i + 2;
2645 0 : ptr_level = ptr_level + 1;
2646 : }
2647 :
2648 : /* Remaining FFT bins are set to zero */
2649 0 : stopFFTbin2 = shl( hFdCngCom->stopFFTbin, 1 );
2650 0 : set32_fx( fftBuffer + stopFFTbin2, 0, sub( hFdCngCom->fftlen, stopFFTbin2 ) );
2651 :
2652 0 : fftBufferExp = add( shr( cngNoiseLevelExp, 1 ), randGaussExp );
2653 :
2654 : /* If previous frame is active, reset the overlap-add buffer */
2655 0 : IF( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) )
2656 : {
2657 0 : set16_fx( hFdCngCom->olapBufferSynth, 0, hFdCngCom->fftlen );
2658 0 : test();
2659 0 : test();
2660 0 : if ( ( st->last_core_bfi > ACELP_CORE && EQ_16( st->codec_mode, MODE2 ) ) || EQ_16( st->codec_mode, MODE1 ) )
2661 : {
2662 0 : tcx_transition = 1;
2663 0 : move16();
2664 : }
2665 : }
2666 :
2667 : /* Perform STFT synthesis */
2668 0 : SynthesisSTFT( fftBuffer, fftBufferExp, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn,
2669 0 : tcx_transition, hFdCngCom, gen_exc, Q_new, st->element_mode, nchan_out );
2670 :
2671 : {
2672 : Word32 Lener, att;
2673 : Word16 exp;
2674 : /* update CNG excitation energy for LP_CNG */
2675 :
2676 : /* calculate the residual signal energy */
2677 : /*enr = dotp( hFdCngCom->exc_cng, hFdCngCom->exc_cng, hFdCngCom->frameSize ) / hFdCngCom->frameSize;*/
2678 0 : Lener = Dot_productSq16HQ( 1, hFdCngCom->exc_cng, st->L_frame, &exp ); /*Q31 - exp*/
2679 0 : exp = add( sub( shl( sub( 15, *Q_new ), 1 ), 8 ), exp ); /*8 = log2(256)*/
2680 :
2681 : /* convert log2 of residual signal energy */
2682 : /*(float)log10( enr + 0.1f ) / (float)log10( 2.0f );*/
2683 0 : Lener = BASOP_Util_Log2( Lener ); /*Q25*/
2684 0 : Lener = L_add( Lener, L_shl( L_deposit_l( exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/
2685 0 : if ( EQ_16( st->L_frame, L_FRAME16k ) )
2686 : {
2687 0 : Lener = L_sub( Lener, 10802114l /*0.3219280949f Q25*/ ); /*log2(320) = 8.3219280949f Q25*/
2688 : }
2689 : /* decrease the energy in case of WB input */
2690 0 : IF( st->bwidth != NB )
2691 : {
2692 0 : IF( EQ_16( st->bwidth, WB ) )
2693 : {
2694 0 : IF( st->CNG_mode >= 0 )
2695 : {
2696 : /* Bitrate adapted attenuation */
2697 0 : att = L_shl( L_deposit_l( ENR_ATT_fx[st->CNG_mode] ), 17 ); /*Q23*/
2698 : }
2699 : ELSE
2700 : {
2701 : /* Use least attenuation for higher bitrates */
2702 0 : att = L_shl( L_deposit_l( ENR_ATT_fx[4] ), 17 ); /*Q23*/
2703 : }
2704 : }
2705 : ELSE
2706 : {
2707 0 : att = 384 << 17; /*1.5 Q8<<17=Q25*/
2708 0 : move16();
2709 : }
2710 0 : Lener = L_sub( Lener, att ); /*Q23*/
2711 : }
2712 : /*st->lp_ener = 0.8f * stcod->lp_ener + 0.2f * pow( 2.0f, enr );*/
2713 0 : Lener = BASOP_util_Pow2( Lener, 6, &exp ); /*Q31 - exp*/
2714 0 : Lener = Mult_32_16( Lener, 6554 /*0.2f Q15*/ ); /*Q31 - exp*/
2715 0 : exp = sub( 25, exp );
2716 0 : Lener = L_shr( Lener, exp ); /*Q6*/
2717 0 : st->lp_ener_fx = L_add( Mult_32_16( st->lp_ener_fx, 26214 /*0.8f Q15*/ ), Lener ); /*Q6*/
2718 0 : move32();
2719 : }
2720 :
2721 : /*
2722 : Generate Gaussian random noise in real and imaginary parts of the CLDFB bands
2723 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each band
2724 : */
2725 0 : test();
2726 0 : IF( bufferReal != NULL && ( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) ) )
2727 : {
2728 :
2729 0 : sn = sub( sn, 1 );
2730 0 : sc = add( shr( add( cngNoiseLevelExp, CLDFBinvScalingFactor_EXP + 1 - 1 ), 1 ), randGaussExp );
2731 0 : move16();
2732 0 : assert( ( ( cngNoiseLevelExp + CLDFBinvScalingFactor_EXP + 1 - 1 ) & 1 ) == 0 );
2733 :
2734 0 : FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
2735 : {
2736 : /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
2737 0 : s = 0;
2738 0 : move16();
2739 0 : sqrtNoiseLevel = Sqrt32( L_shr( Mpy_32_16_1( *ptr_level, scaleCLDFB ), sn ), &s ); /*Q31 - s*/
2740 :
2741 0 : FOR( i = 0; i < hFdCngCom->numSlots; i++ )
2742 : {
2743 : /* Real part in CLDFB band */
2744 0 : bufferReal[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*bufferScale*/
2745 0 : move32();
2746 : /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferReal[i][j],sc));*/
2747 :
2748 : /* Imaginary part in CLDFB band */
2749 0 : bufferImag[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*bufferScale*/
2750 0 : move32();
2751 : /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferImag[i][j],sc));*/
2752 : }
2753 0 : ptr_level = ptr_level + 1;
2754 : }
2755 0 : *bufferScale = sub( sc, 15 );
2756 0 : move16();
2757 : }
2758 :
2759 : /* Overlap-add when previous frame is active */
2760 0 : test();
2761 0 : IF( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) && EQ_16( st->codec_mode, MODE2 ) )
2762 : {
2763 : Word32 old_exc_ener, gain, noise32;
2764 : Word16 seed_loc, lpcorder, old_syn, tmp, gain16, N, N2, N4, N8;
2765 : Word16 old_exc_ener_exp, gain_exp;
2766 : Word16 normFacE, normShiftE, normShiftEM1;
2767 : Word16 normFacG, normShiftG, normShiftGM1;
2768 : Word16 noiseExp, *old_exc, *old_Aq, *old_syn_pe;
2769 : Word16 noise[640], normShiftP2;
2770 : Word16 Q_exc, Q_syn;
2771 :
2772 :
2773 0 : assert( hFdCngCom->frameSize <= 640 );
2774 :
2775 0 : seed_loc = hFdCngCom->seed;
2776 0 : move16();
2777 0 : N = hFdCngCom->frameSize; /*Q0*/
2778 0 : move16();
2779 0 : N2 = shr( hFdCngCom->frameSize, 1 );
2780 :
2781 0 : IF( st->last_core_bfi > ACELP_CORE )
2782 : {
2783 : Word16 left_overlap_mode;
2784 0 : left_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode; /*Q0*/
2785 0 : move16();
2786 0 : if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
2787 : {
2788 0 : left_overlap_mode = FULL_OVERLAP;
2789 0 : move16();
2790 : }
2791 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,
2792 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 );
2793 :
2794 0 : IF( st->hTcxCfg->last_aldo != 0 )
2795 : {
2796 0 : FOR( i = 0; i < hFdCngCom->frameSize - NS2SA( st->sr_core, N_ZERO_MDCT_NS ); i++ )
2797 : {
2798 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*/
2799 0 : move16();
2800 : }
2801 : }
2802 : ELSE
2803 : {
2804 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,
2805 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 );
2806 :
2807 0 : FOR( i = 0; i < st->hTcxCfg->tcx_mdct_window_length; i++ )
2808 : {
2809 0 : timeDomainOutput[i] = add( timeDomainOutput[i], shl( hTcxDec->syn_Overl[i], TCX_IMDCT_HEADROOM ) ); /*st->q_old_outLB_fx*/
2810 0 : move16();
2811 : }
2812 : }
2813 : }
2814 : ELSE
2815 : {
2816 :
2817 : /*
2818 : - the scaling of the LPCs (e.g. old_Aq) is always Q12 (encoder or decoder)
2819 :
2820 : - the scaling of the deemphasized signals (e.g. old_syn) is always Q0 (encoder or decoder)
2821 :
2822 : - the scaling of the excitation signals in the encoder (e.g. old_exc) is Q_new
2823 : - the scaling of the preemphasized signals in the encoder (e.g. old_syn_pe) is Q_new-1
2824 :
2825 : - the scaling of the excitation signals in the decoder (e.g. old_exc) is Q_exc (or stdec->Q_exc)
2826 : - the scaling of the preemphasized signals in the decoder (e.g. old_syn_pe) is Q_syn (or stdec->Q_syn)
2827 : */
2828 :
2829 0 : lpcorder = M;
2830 0 : move16();
2831 0 : old_Aq = st->old_Aq_12_8_fx; /*Q12*/
2832 0 : old_exc = st->old_exc_fx + sub( L_EXC_MEM_DEC, N2 ); /*Q_exc*/
2833 0 : old_syn_pe = st->mem_syn2_fx; /*Q_syn*/
2834 0 : old_syn = st->syn[lpcorder]; /*Q_syn*/
2835 0 : move16();
2836 0 : preemph_fac = st->preemph_fac; /*Q15*/
2837 0 : move16();
2838 0 : Q_exc = st->Q_exc;
2839 0 : move16();
2840 0 : Q_syn = st->Q_syn;
2841 0 : move16();
2842 :
2843 : /* shift to be in the range of values supported by getNormReciprocalWord16() */
2844 0 : N8 = shr( N2, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
2845 :
2846 0 : assert( N2 == ( N8 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
2847 :
2848 0 : normFacE = getNormReciprocalWord16( N8 );
2849 0 : normShiftE = BASOP_util_norm_s_bands2shift( N8 );
2850 0 : normShiftEM1 = sub( normShiftE, 1 );
2851 0 : normShiftP2 = add( normShiftE, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
2852 :
2853 0 : old_exc_ener = L_shr( L_mult( old_exc[0], old_exc[0] ), normShiftP2 ); /*2*(Q_exc)+1+normShiftP2*/
2854 0 : FOR( i = 1; i < N2; i++ )
2855 : {
2856 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*/
2857 : }
2858 0 : old_exc_ener = L_shl( Mpy_32_16_1( old_exc_ener, shl( normFacE, normShiftEM1 ) ), 1 ); /*Q31*/
2859 :
2860 0 : old_exc_ener_exp = 0;
2861 0 : move16();
2862 0 : old_exc_ener = Sqrt32( old_exc_ener, &old_exc_ener_exp ); /*Q31 - old_exc_ener_exp*/
2863 0 : old_exc_ener_exp = add( old_exc_ener_exp, ( sub( 15, Q_exc ) ) );
2864 :
2865 : /* shift to be in the range of values supported by getNormReciprocalWord16() */
2866 0 : N4 = shr( N, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
2867 :
2868 0 : assert( N == ( N4 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
2869 :
2870 0 : normFacG = getNormReciprocalWord16( N4 );
2871 0 : normShiftG = BASOP_util_norm_s_bands2shift( N4 );
2872 0 : normShiftGM1 = sub( normShiftG, 1 );
2873 0 : normShiftP2 = add( normShiftG, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
2874 :
2875 0 : gain = L_deposit_l( 0 );
2876 0 : FOR( i = 0; i < N; i++ )
2877 : {
2878 0 : noise32 = rand_gauss( &seed_loc );
2879 0 : noise[i] = extract_h( noise32 );
2880 0 : move16();
2881 0 : gain = L_add( gain, L_shr( L_mult( noise[i], noise[i] ), normShiftP2 ) );
2882 : }
2883 0 : gain = L_shl( Mpy_32_16_1( gain, shl( normFacG, normShiftGM1 ) ), 1 ); /*Q31 - gain_exp*/
2884 :
2885 0 : gain_exp = 2 * CNG_RAND_GAUSS_SHIFT;
2886 0 : move16();
2887 0 : gain = ISqrt32( gain, &gain_exp ); /*Q31 - gain_exp*/
2888 :
2889 0 : gain = Mpy_32_32( old_exc_ener, gain ); /*Q31 - old_exc_ener_exp - gain_exp*/
2890 0 : gain16 = extract_h( gain ); /*Q15 - old_exc_ener_exp - gain_exp*/
2891 :
2892 0 : gain_exp = add( old_exc_ener_exp, gain_exp );
2893 0 : noiseExp = add( CNG_RAND_GAUSS_SHIFT, gain_exp );
2894 :
2895 0 : s = sub( 15 - NOISE_HEADROOM, noiseExp );
2896 0 : FOR( i = 0; i < N; i++ )
2897 : {
2898 0 : noise[i] = shr_sat( mult( noise[i], gain16 ), s ); /*Q15 - noiseExp*/
2899 0 : move16();
2900 : }
2901 :
2902 0 : assert( lpcorder <= 16 );
2903 :
2904 0 : s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) );
2905 0 : FOR( i = 0; i < lpcorder; i++ )
2906 : {
2907 0 : old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s ); /*Q0*/
2908 0 : move16();
2909 : }
2910 :
2911 0 : E_UTIL_synthesis(
2912 : 0, /* i : scaling to apply for a[0] Q0 */
2913 : old_Aq, /* i : LP filter coefficients Q12 */
2914 : noise, /* i : input signal Qx */
2915 : noise, /* o : output signal Qx-s */
2916 : N, /* i : size of filtering Q0 */
2917 : old_syn_pe_tmp, /* i/o: memory associated with this filtering. Q0 */
2918 : 0, /* i : 0=no update, 1=update of memory. Q0 */
2919 : lpcorder /* i : order of LP filter Q0 */
2920 : );
2921 :
2922 0 : tmp = old_syn;
2923 0 : move16();
2924 :
2925 0 : E_UTIL_deemph2(
2926 : NOISE_HEADROOM,
2927 : noise, /* I/O: signal Qx */
2928 : preemph_fac, /* I: deemphasis factor Qx */
2929 : N, /* I: vector size */
2930 : &tmp /* I/O: memory (signal[-1]) Qx */
2931 : );
2932 :
2933 0 : FOR( i = 0; i < N4; i++ )
2934 : {
2935 0 : tmp = mult( noise[i], hFdCngCom->olapWinSyn[i].v.re ); /*Q15 - noiseExp*/
2936 0 : timeDomainOutput[i] = add( timeDomainOutput[i], tmp );
2937 0 : move16();
2938 0 : tmp = mult( noise[( i + N4 )], hFdCngCom->olapWinSyn[( ( N4 - 1 ) - i )].v.im ); /*Q15 - noiseExp*/
2939 0 : timeDomainOutput[( i + N4 )] = add( timeDomainOutput[( i + N4 )], tmp );
2940 0 : move16();
2941 : }
2942 : }
2943 : }
2944 0 : }
2945 :
2946 18381 : void generate_comfort_noise_dec_ivas_fx(
2947 : Word32 **bufferReal, /* o : Real part of input bands bufferScale*/
2948 : Word32 **bufferImag, /* o : Imaginary part of input bands bufferScale*/
2949 : Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */
2950 : Decoder_State *st, /* i/o: decoder state structure */
2951 : Word16 *Q_new,
2952 : Word16 gen_exc, /*Q0*/
2953 : const Word16 nchan_out /* i : number of output channels Q0*/
2954 : )
2955 : {
2956 : Word16 i, j, s;
2957 : Word32 *ptr_r, *ptr_i;
2958 18381 : HANDLE_FD_CNG_DEC hFdCngDec = st->hFdCngDec;
2959 18381 : HANDLE_FD_CNG_COM hFdCngCom = hFdCngDec->hFdCngCom;
2960 18381 : Word32 *cngNoiseLevel = hFdCngCom->cngNoiseLevel;
2961 18381 : Word16 cngNoiseLevel_exp = hFdCngCom->cngNoiseLevelExp;
2962 18381 : move16();
2963 :
2964 18381 : Word32 *ptr_level = cngNoiseLevel;
2965 18381 : Word16 *seed = &( hFdCngCom->seed );
2966 : Word16 *seed2;
2967 : Word16 c1, c2;
2968 : Word32 tmp1, tmp2;
2969 : Word16 scaleCldfb;
2970 18381 : Word32 *fftBuffer = hFdCngCom->fftBuffer; /*hFdCngCom->fftBuffer_exp*/
2971 18381 : Word16 fftBuffer_exp = hFdCngCom->fftBuffer_exp;
2972 : Word16 fftBuffer_temp_exp[FFTLEN];
2973 18381 : Word16 *timeDomainOutput = hFdCngCom->timeDomainBuffer;
2974 : Word16 temp;
2975 : Word32 sqrtNoiseLevel;
2976 : Word16 sqrtNoiseLevel_exp;
2977 18381 : Word16 idx = 0;
2978 18381 : move16();
2979 : Word16 preemph_fac;
2980 : Word16 old_syn_pe_tmp[16];
2981 18381 : Word16 tcx_transition = 0;
2982 : TCX_DEC_HANDLE hTcxDec;
2983 18381 : move16();
2984 :
2985 18381 : hTcxDec = st->hTcxDec;
2986 :
2987 18381 : scaleCldfb = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); /*CLDFBinvScalingFactor_EXP + 1*/
2988 :
2989 18381 : temp = 0;
2990 18381 : move16();
2991 18381 : c1 = Sqrt16( hFdCngCom->coherence_fx, &temp ); /*Q15 - temp*/
2992 18381 : c1 = shl( c1, temp ); /*Q15*/
2993 18381 : temp = 0;
2994 18381 : move16();
2995 18381 : c2 = Sqrt16( sub( MAX_16, hFdCngCom->coherence_fx ), &temp ); /*Q15 - temp*/
2996 18381 : c2 = shl( c2, temp ); /*Q15*/
2997 :
2998 18381 : temp = getScaleFactor32( fftBuffer, FFTLEN );
2999 18381 : scale_sig32( fftBuffer, FFTLEN, temp ); /*Q31 - hFdCngCom->fftBuffer_exp + temp*/
3000 18381 : fftBuffer_exp = sub( fftBuffer_exp, temp );
3001 18381 : hFdCngCom->fftBuffer_exp = fftBuffer_exp;
3002 18381 : move16();
3003 18381 : set16_fx( fftBuffer_temp_exp, fftBuffer_exp, FFTLEN );
3004 18381 : fftBuffer_exp = 0;
3005 18381 : move16();
3006 :
3007 18381 : seed2 = &( hFdCngCom->seed2 );
3008 18381 : test();
3009 18381 : if ( EQ_16( st->element_mode, IVAS_CPE_MDCT ) && EQ_16( st->idchan, 1 ) )
3010 : {
3011 3082 : seed2 = &( hFdCngCom->seed3 );
3012 : }
3013 :
3014 : /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
3015 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */
3016 :
3017 18381 : IF( hFdCngCom->startBand == 0 )
3018 : {
3019 0 : test();
3020 0 : test();
3021 0 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
3022 : {
3023 0 : rand_gauss_fx( &tmp1, seed, Q15 );
3024 0 : rand_gauss_fx( &tmp2, seed2, Q15 );
3025 0 : fftBuffer[0] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q0*/
3026 0 : move32();
3027 0 : fftBuffer_temp_exp[0] = Q16 + Q15;
3028 0 : move16();
3029 : }
3030 : ELSE
3031 : {
3032 0 : rand_gauss_fx( &fftBuffer[0], seed, Q15 );
3033 0 : fftBuffer_temp_exp[0] = Q16;
3034 0 : move16();
3035 : }
3036 0 : sqrtNoiseLevel_exp = cngNoiseLevel_exp;
3037 0 : move16();
3038 0 : sqrtNoiseLevel = Sqrt32( *ptr_level, &sqrtNoiseLevel_exp ); /*Q31 - sqrtNoiseLevel_exp*/
3039 0 : fftBuffer[0] = Mpy_32_32( fftBuffer[0], sqrtNoiseLevel ); /*Q31 - (sqrtNoiseLevel_exp + fftBuffer_temp_exp[0])*/
3040 0 : move32();
3041 0 : fftBuffer_temp_exp[0] = add( sqrtNoiseLevel_exp, fftBuffer_temp_exp[0] );
3042 0 : move16();
3043 0 : ptr_level++;
3044 0 : ptr_r = fftBuffer + 2; /*Q31 - (fftBuffer_temp_exp)*/
3045 0 : idx = 2;
3046 : }
3047 : ELSE
3048 : {
3049 18381 : fftBuffer[0] = 0;
3050 18381 : move16();
3051 18381 : set32_fx( fftBuffer + 2, 0, shl( sub( hFdCngCom->startBand, 1 ), 1 ) );
3052 18381 : ptr_r = fftBuffer + shl( hFdCngCom->startBand, 1 ); /*Q31 - fftBuffer_exp*/
3053 18381 : idx = shl( hFdCngCom->startBand, 1 ); /*Q0*/
3054 : }
3055 :
3056 18381 : ptr_i = ptr_r + 1; /*Q31 - fftBuffer_exp*/
3057 5423155 : FOR( ; ptr_level < cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); ptr_level++ )
3058 : {
3059 : /* Real part in FFT bins */
3060 5404774 : test();
3061 5404774 : test();
3062 5404774 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
3063 : {
3064 3683032 : rand_gauss_fx( &tmp1, seed, Q15 ); /*Q15*/
3065 3683032 : rand_gauss_fx( &tmp2, seed2, Q15 ); /*Q15*/
3066 3683032 : *ptr_r = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q15*/
3067 3683032 : move32();
3068 3683032 : fftBuffer_temp_exp[idx] = Q16;
3069 3683032 : move16();
3070 : }
3071 : ELSE
3072 : {
3073 1721742 : rand_gauss_fx( ptr_r, seed, Q15 ); /*Q15*/
3074 1721742 : fftBuffer_temp_exp[idx] = Q16;
3075 1721742 : move16();
3076 : }
3077 :
3078 5404774 : sqrtNoiseLevel_exp = sub( cngNoiseLevel_exp, 1 );
3079 5404774 : sqrtNoiseLevel = Sqrt32( *ptr_level, &sqrtNoiseLevel_exp ); /*Q31 - sqrtNoiseLevel_exp*/
3080 5404774 : ( *ptr_r ) = Mpy_32_32( ( *ptr_r ), sqrtNoiseLevel ); /*Q15 - sqrtNoiseLevel_exp*/
3081 5404774 : move32();
3082 5404774 : fftBuffer_temp_exp[idx] = add( fftBuffer_temp_exp[idx], sqrtNoiseLevel_exp );
3083 5404774 : move16();
3084 5404774 : idx = add( idx, 1 );
3085 5404774 : ptr_r += 2;
3086 :
3087 : /* Imaginary part in FFT bins */
3088 5404774 : test();
3089 5404774 : test();
3090 5404774 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
3091 : {
3092 3683032 : rand_gauss_fx( &tmp1, seed, Q15 ); /*Q15*/
3093 3683032 : rand_gauss_fx( &tmp2, seed2, Q15 ); /*Q15*/
3094 3683032 : *ptr_i = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q15*/
3095 3683032 : move32();
3096 3683032 : fftBuffer_temp_exp[idx] = Q16;
3097 3683032 : move16();
3098 : }
3099 : ELSE
3100 : {
3101 1721742 : rand_gauss_fx( ptr_i, seed, Q15 ); /*Q15*/
3102 1721742 : fftBuffer_temp_exp[idx] = Q16;
3103 1721742 : move16();
3104 : }
3105 5404774 : sqrtNoiseLevel_exp = sub( cngNoiseLevel_exp, 1 );
3106 5404774 : sqrtNoiseLevel = Sqrt32( *ptr_level, &sqrtNoiseLevel_exp ); /*Q31 - sqrtNoiseLevel_exp*/
3107 5404774 : ( *ptr_i ) = Mpy_32_32( ( *ptr_i ), sqrtNoiseLevel ); /*Q15 - sqrtNoiseLevel_exp*/
3108 5404774 : move32();
3109 5404774 : fftBuffer_temp_exp[idx] = add( fftBuffer_temp_exp[idx], sqrtNoiseLevel_exp );
3110 5404774 : move16();
3111 5404774 : idx = add( idx, 1 );
3112 5404774 : ptr_i += 2;
3113 : }
3114 :
3115 : /* Remaining FFT bins are set to zero */
3116 18381 : set32_fx( fftBuffer + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) );
3117 18381 : set16_fx( fftBuffer_temp_exp + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) );
3118 :
3119 : /* Nyquist frequency is discarded */
3120 18381 : fftBuffer[1] = 0;
3121 18381 : move32();
3122 :
3123 18381 : fftBuffer_exp = MAX_16;
3124 18381 : move16();
3125 10904525 : FOR( i = 0; i < hFdCngCom->fftlen; i++ )
3126 : {
3127 10886144 : IF( fftBuffer[i] != 0 )
3128 : {
3129 8545166 : fftBuffer_exp = s_min( fftBuffer_exp, add( sub( 31, fftBuffer_temp_exp[i] ), norm_l( fftBuffer[i] ) ) );
3130 : }
3131 : }
3132 18381 : if ( EQ_16( fftBuffer_exp, MAX_16 ) )
3133 : {
3134 2232 : fftBuffer_exp = 0;
3135 2232 : move16();
3136 : }
3137 18381 : fftBuffer_exp = sub( 31, fftBuffer_exp );
3138 10904525 : FOR( i = 0; i < hFdCngCom->fftlen; i++ )
3139 : {
3140 10886144 : fftBuffer[i] = L_shr( fftBuffer[i], sub( fftBuffer_exp, fftBuffer_temp_exp[i] ) ); /*Q31 - fftBuffer_temp_exp[i]*/
3141 10886144 : move32();
3142 : }
3143 :
3144 : /* If previous frame is active, reset the overlap-add buffer */
3145 18381 : tcx_transition = 0;
3146 18381 : move16();
3147 18381 : IF( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) )
3148 : {
3149 1772 : set16_fx( hFdCngCom->olapBufferSynth, 0, hFdCngCom->fftlen );
3150 1772 : test();
3151 1772 : test();
3152 1772 : if ( ( st->last_core_bfi > ACELP_CORE && EQ_16( st->codec_mode, MODE2 ) ) || EQ_16( st->codec_mode, MODE1 ) )
3153 : {
3154 1772 : tcx_transition = 1;
3155 1772 : move16();
3156 : }
3157 : }
3158 :
3159 : /* Perform STFT synthesis */
3160 18381 : SynthesisSTFT_ivas_fx( fftBuffer, fftBuffer_exp, timeDomainOutput, hFdCngCom->olapBufferSynth, hFdCngCom->olapWinSyn,
3161 18381 : tcx_transition, hFdCngCom, gen_exc, Q_new, st->element_mode, nchan_out );
3162 18381 : scale_sig32( fftBuffer + hFdCngCom->fftlen, sub( FFTLEN, hFdCngCom->fftlen ), sub( fftBuffer_exp, hFdCngCom->fftBuffer_exp ) ); /*Q31 - fftBuffer_exp*/
3163 :
3164 : {
3165 : Word32 Lener, att;
3166 : Word16 exp;
3167 : /* update CNG excitation energy for LP_CNG */
3168 :
3169 : /* calculate the residual signal energy */
3170 : /*enr = dotp( hFdCngCom->exc_cng, hFdCngCom->exc_cng, hFdCngCom->frameSize ) / hFdCngCom->frameSize;*/
3171 18381 : Lener = Dot_productSq16HQ( 1, hFdCngCom->exc_cng, st->L_frame, &exp ); /*Q31 - exp*/
3172 18381 : exp = add( sub( shl( sub( 15, *Q_new ), 1 ), 8 ), exp ); /*8 = log2(256)*/
3173 :
3174 : /* convert log2 of residual signal energy */
3175 : /*(float)log10( enr + 0.1f ) / (float)log10( 2.0f );*/
3176 18381 : Lener = BASOP_Util_Log2( Lener ); /*Q25*/
3177 18381 : Lener = L_add( Lener, L_shl( L_deposit_l( exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/
3178 18381 : if ( EQ_16( st->L_frame, L_FRAME16k ) )
3179 : {
3180 11524 : Lener = L_sub( Lener, 10802114l /*0.3219280949f Q25*/ ); /*log2(320) = 8.3219280949f*/
3181 : }
3182 : /* decrease the energy in case of WB input */
3183 18381 : IF( st->bwidth != NB )
3184 : {
3185 18381 : IF( EQ_16( st->bwidth, WB ) )
3186 : {
3187 4105 : IF( st->CNG_mode >= 0 )
3188 : {
3189 : /* Bitrate adapted attenuation */
3190 1 : att = L_shl( L_deposit_l( ENR_ATT_fx[st->CNG_mode] ), 17 ); /*Q25*/
3191 : }
3192 : ELSE
3193 : {
3194 : /* Use least attenuation for higher bitrates */
3195 4104 : att = L_shl( L_deposit_l( ENR_ATT_fx[4] ), 17 ); /*Q25*/
3196 : }
3197 : }
3198 : ELSE
3199 : {
3200 14276 : att = 384 << 17; /*1.5 Q8<<17=Q25*/
3201 14276 : move16();
3202 : }
3203 18381 : Lener = L_sub( Lener, att );
3204 : }
3205 : /*st->lp_ener = 0.8f * stcod->lp_ener + 0.2f * pow( 2.0f, enr );*/
3206 18381 : Lener = BASOP_util_Pow2( Lener, 6, &exp ); /*Q31 - exp*/
3207 18381 : Lener = Mult_32_16( Lener, 6554 /*0.2f Q15*/ ); /*Q31 - exp*/
3208 18381 : exp = sub( 25, exp );
3209 18381 : Lener = L_shr( Lener, exp ); /*Q6*/
3210 18381 : st->lp_ener_fx = L_add( Mult_32_16( st->lp_ener_fx, 26214 /*0.8f Q15*/ ), Lener ); /*Q6*/
3211 18381 : move32();
3212 : }
3213 :
3214 : /* Generate Gaussian random noise in real and imaginary parts of the CLDFB bands
3215 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each band */
3216 :
3217 18381 : test();
3218 18381 : IF( bufferReal != NULL && ( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) ) )
3219 : {
3220 : Word16 bufferReal_exp[CLDFB_NO_COL_MAX];
3221 : Word16 bufferImag_exp[CLDFB_NO_COL_MAX];
3222 0 : *bufferScale = 0;
3223 0 : move16();
3224 0 : FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
3225 : {
3226 0 : sqrtNoiseLevel_exp = add( CLDFBinvScalingFactor_EXP, sub( cngNoiseLevel_exp, 1 ) );
3227 0 : sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *ptr_level, scaleCldfb ), &sqrtNoiseLevel_exp ); /*Q31 - sqrtNoiseLevel_exp*/
3228 :
3229 0 : FOR( i = 0; i < hFdCngCom->numSlots; i++ )
3230 : {
3231 : /* Real part in CLDFB band */
3232 0 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
3233 : {
3234 0 : rand_gauss_fx( &tmp1, seed, Q15 ); /*Q15*/
3235 0 : rand_gauss_fx( &tmp2, seed2, Q15 ); /*Q15*/
3236 0 : bufferReal[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q15*/
3237 0 : move32();
3238 0 : bufferReal_exp[j] = Q16;
3239 0 : move16();
3240 : }
3241 : ELSE
3242 : {
3243 0 : rand_gauss_fx( &bufferReal[i][j], seed, Q15 ); /*Q15*/
3244 0 : move32();
3245 0 : bufferReal_exp[j] = Q16;
3246 0 : move16();
3247 : }
3248 :
3249 0 : bufferReal[i][j] = Mpy_32_32( bufferReal[i][j], sqrtNoiseLevel ); /*Q31 - ( bufferReal_exp[j] + sqrtNoiseLevel_exp )*/
3250 0 : move32();
3251 0 : bufferReal_exp[j] = add( bufferReal_exp[j], sqrtNoiseLevel_exp );
3252 0 : move16();
3253 :
3254 : /* Imaginary part in CLDFB band */
3255 0 : IF( EQ_16( st->element_mode, IVAS_CPE_MDCT ) || ( EQ_16( st->element_mode, IVAS_SCE ) && st->cng_ism_flag ) )
3256 : {
3257 0 : rand_gauss_fx( &tmp1, seed, Q15 ); /*Q15*/
3258 0 : rand_gauss_fx( &tmp2, seed2, Q15 ); /*Q15*/
3259 0 : bufferImag[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*Q15*/
3260 0 : move32();
3261 0 : bufferImag_exp[j] = Q16;
3262 0 : move16();
3263 : }
3264 : ELSE
3265 : {
3266 0 : rand_gauss_fx( &bufferImag[i][j], seed, Q15 ); /*Q15*/
3267 0 : bufferImag_exp[j] = Q16;
3268 0 : move16();
3269 : }
3270 0 : bufferImag[i][j] = Mpy_32_32( bufferImag[i][j], sqrtNoiseLevel ); /*Q31 - ( bufferReal_exp[j] + sqrtNoiseLevel_exp )*/
3271 0 : bufferImag_exp[j] = add( bufferImag_exp[j], sqrtNoiseLevel_exp );
3272 0 : move16();
3273 :
3274 0 : move32();
3275 : }
3276 0 : ptr_level++;
3277 : }
3278 :
3279 0 : FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
3280 : {
3281 0 : *bufferScale = s_max( *bufferScale, bufferReal_exp[j] );
3282 0 : move16();
3283 0 : *bufferScale = s_max( *bufferScale, bufferImag_exp[j] );
3284 0 : move16();
3285 : }
3286 :
3287 0 : FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
3288 : {
3289 0 : FOR( i = 0; i < hFdCngCom->numSlots; i++ )
3290 : {
3291 0 : bufferImag[i][j] = L_shr( bufferImag[i][j], sub( *bufferScale, bufferImag_exp[j] ) ); /*bufferImag_exp*/
3292 0 : move32();
3293 0 : bufferReal[i][j] = L_shr( bufferReal[i][j], sub( *bufferScale, bufferReal_exp[j] ) ); /*bufferReal_exp*/
3294 0 : move32();
3295 : }
3296 : }
3297 : }
3298 :
3299 18381 : test();
3300 18381 : IF( EQ_16( hFdCngCom->frame_type_previous, ACTIVE_FRAME ) && EQ_16( st->codec_mode, MODE2 ) )
3301 : {
3302 : Word32 old_exc_ener, gain, noise32;
3303 : Word16 seed_loc, lpcorder, old_syn, tmp, gain16, N, N2, N4, N8;
3304 : Word16 old_exc_ener_exp, gain_exp;
3305 : Word16 normFacE, normShiftE, normShiftEM1;
3306 : Word16 normFacG, normShiftG, normShiftGM1;
3307 : Word16 noiseExp, *old_exc, *old_Aq, *old_syn_pe;
3308 : Word16 noise[640], normShiftP2;
3309 : Word16 Q_exc, Q_syn;
3310 :
3311 :
3312 0 : assert( hFdCngCom->frameSize <= 640 );
3313 :
3314 0 : seed_loc = hFdCngCom->seed; /*Q0*/
3315 0 : move16();
3316 0 : N = hFdCngCom->frameSize; /*Q0*/
3317 0 : move16();
3318 0 : N2 = shr( hFdCngCom->frameSize, 1 );
3319 :
3320 0 : IF( st->last_core_bfi > ACELP_CORE )
3321 : {
3322 : Word16 left_overlap_mode;
3323 0 : left_overlap_mode = st->hTcxCfg->tcx_last_overlap_mode;
3324 0 : move16();
3325 0 : if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
3326 : {
3327 0 : left_overlap_mode = FULL_OVERLAP;
3328 0 : move16();
3329 : }
3330 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,
3331 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 );
3332 :
3333 0 : IF( st->hTcxCfg->last_aldo != 0 )
3334 : {
3335 0 : FOR( i = 0; i < hFdCngCom->frameSize - NS2SA( st->sr_core, N_ZERO_MDCT_NS ); i++ )
3336 : {
3337 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*/
3338 0 : move16();
3339 : }
3340 : }
3341 : ELSE
3342 : {
3343 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,
3344 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 );
3345 :
3346 0 : FOR( i = 0; i < st->hTcxCfg->tcx_mdct_window_length; i++ )
3347 : {
3348 0 : timeDomainOutput[i] = add( timeDomainOutput[i], shl( hTcxDec->syn_Overl[i], TCX_IMDCT_HEADROOM ) ); /*st->q_old_outLB_fx*/
3349 0 : move16();
3350 : }
3351 : }
3352 : }
3353 : ELSE
3354 : {
3355 :
3356 : /*
3357 : - the scaling of the LPCs (e.g. old_Aq) is always Q12 (encoder or decoder)
3358 :
3359 : - the scaling of the deemphasized signals (e.g. old_syn) is always Q0 (encoder or decoder)
3360 :
3361 : - the scaling of the excitation signals in the encoder (e.g. old_exc) is Q_new
3362 : - the scaling of the preemphasized signals in the encoder (e.g. old_syn_pe) is Q_new-1
3363 :
3364 : - the scaling of the excitation signals in the decoder (e.g. old_exc) is Q_exc (or stdec->Q_exc)
3365 : - the scaling of the preemphasized signals in the decoder (e.g. old_syn_pe) is Q_syn (or stdec->Q_syn)
3366 : */
3367 :
3368 0 : lpcorder = M;
3369 0 : move16();
3370 0 : old_Aq = st->old_Aq_12_8_fx; /*Q12*/
3371 0 : old_exc = st->old_exc_fx + sub( L_EXC_MEM_DEC, N2 ); /*Q_exc*/
3372 0 : old_syn_pe = st->mem_syn2_fx; /*Q_syn*/
3373 0 : old_syn = st->syn[lpcorder]; /*Q_syn*/
3374 0 : move16();
3375 0 : preemph_fac = st->preemph_fac; /*Q15*/
3376 0 : move16();
3377 0 : Q_exc = st->Q_exc;
3378 0 : move16();
3379 0 : Q_syn = st->Q_syn;
3380 0 : move16();
3381 :
3382 : /* shift to be in the range of values supported by getNormReciprocalWord16() */
3383 0 : N8 = shr( N2, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
3384 :
3385 0 : assert( N2 == ( N8 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
3386 :
3387 0 : normFacE = getNormReciprocalWord16( N8 );
3388 0 : normShiftE = BASOP_util_norm_s_bands2shift( N8 );
3389 0 : normShiftEM1 = sub( normShiftE, 1 );
3390 0 : normShiftP2 = add( normShiftE, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
3391 :
3392 0 : old_exc_ener = L_shr( L_mult( old_exc[0], old_exc[0] ), normShiftP2 ); /*2*(Q_exc)+1+normShiftP2*/
3393 0 : FOR( i = 1; i < N2; i++ )
3394 : {
3395 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*/
3396 : }
3397 0 : old_exc_ener = L_shl( Mpy_32_16_1( old_exc_ener, shl( normFacE, normShiftEM1 ) ), 1 ); /*Q31*/
3398 :
3399 0 : old_exc_ener_exp = 0;
3400 0 : move16();
3401 0 : old_exc_ener = Sqrt32( old_exc_ener, &old_exc_ener_exp ); /*Q31 - old_exc_ener_exp*/
3402 0 : old_exc_ener_exp = add( old_exc_ener_exp, ( sub( 15, Q_exc ) ) );
3403 :
3404 : /* shift to be in the range of values supported by getNormReciprocalWord16() */
3405 0 : N4 = shr( N, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
3406 :
3407 0 : assert( N == ( N4 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
3408 :
3409 0 : normFacG = getNormReciprocalWord16( N4 );
3410 0 : normShiftG = BASOP_util_norm_s_bands2shift( N4 );
3411 0 : normShiftGM1 = sub( normShiftG, 1 );
3412 0 : normShiftP2 = add( normShiftG, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
3413 :
3414 0 : gain = L_deposit_l( 0 );
3415 0 : FOR( i = 0; i < N; i++ )
3416 : {
3417 0 : noise32 = rand_gauss( &seed_loc );
3418 0 : noise[i] = extract_h( noise32 );
3419 0 : move16();
3420 0 : gain = L_add( gain, L_shr( L_mult( noise[i], noise[i] ), normShiftP2 ) );
3421 : }
3422 0 : gain = L_shl( Mpy_32_16_1( gain, shl( normFacG, normShiftGM1 ) ), 1 ); /*Q31 - gain_exp*/
3423 :
3424 0 : gain_exp = 2 * CNG_RAND_GAUSS_SHIFT;
3425 0 : move16();
3426 0 : gain = ISqrt32( gain, &gain_exp ); /*Q31 - gain_exp*/
3427 :
3428 0 : gain = Mpy_32_32( old_exc_ener, gain ); /*Q31 - old_exc_ener_exp - gain_exp*/
3429 0 : gain16 = extract_h( gain ); /*Q15 - old_exc_ener_exp - gain_exp*/
3430 :
3431 0 : gain_exp = add( old_exc_ener_exp, gain_exp );
3432 0 : noiseExp = add( CNG_RAND_GAUSS_SHIFT, gain_exp );
3433 :
3434 0 : s = sub( 15 - NOISE_HEADROOM, noiseExp );
3435 0 : FOR( i = 0; i < N; i++ )
3436 : {
3437 0 : noise[i] = shr_sat( mult( noise[i], gain16 ), s ); /*Q15 - noiseExp*/
3438 0 : move16();
3439 : }
3440 :
3441 0 : assert( lpcorder <= 16 );
3442 :
3443 0 : s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) );
3444 0 : FOR( i = 0; i < lpcorder; i++ )
3445 : {
3446 0 : old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s ); /*Q0*/
3447 0 : move16();
3448 : }
3449 :
3450 0 : E_UTIL_synthesis(
3451 : 0, /* i : scaling to apply for a[0] Q0 */
3452 : old_Aq, /* i : LP filter coefficients Q12 */
3453 : noise, /* i : input signal Qx */
3454 : noise, /* o : output signal Qx-s */
3455 : N, /* i : size of filtering Q0 */
3456 : old_syn_pe_tmp, /* i/o: memory associated with this filtering. Q0 */
3457 : 0, /* i : 0=no update, 1=update of memory. Q0 */
3458 : lpcorder /* i : order of LP filter Q0 */
3459 : );
3460 :
3461 0 : tmp = old_syn;
3462 0 : move16();
3463 :
3464 0 : E_UTIL_deemph2(
3465 : NOISE_HEADROOM,
3466 : noise, /* I/O: signal Qx */
3467 : preemph_fac, /* I: deemphasis factor Qx */
3468 : N, /* I: vector size */
3469 : &tmp /* I/O: memory (signal[-1]) Qx */
3470 : );
3471 :
3472 0 : FOR( i = 0; i < N4; i++ )
3473 : {
3474 0 : tmp = mult( noise[i], hFdCngCom->olapWinSyn[i].v.re ); /*Q15 - noiseExp*/
3475 0 : timeDomainOutput[i] = add( timeDomainOutput[i], tmp );
3476 0 : move16();
3477 0 : tmp = mult( noise[( i + N4 )], hFdCngCom->olapWinSyn[( ( N4 - 1 ) - i )].v.im ); /*Q15 - noiseExp*/
3478 0 : timeDomainOutput[( i + N4 )] = add( timeDomainOutput[( i + N4 )], tmp );
3479 0 : move16();
3480 0 : move16();
3481 : }
3482 : }
3483 : }
3484 18381 : return;
3485 : }
3486 :
3487 0 : void generate_comfort_noise_dec_hf_fx(
3488 : Word32 **bufferReal, /* o : matrix to real part of input bands bufferScale*/
3489 : Word32 **bufferImag, /* o : matrix to imaginary part of input bands bufferScale*/
3490 : Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */
3491 : Decoder_State *st )
3492 : {
3493 : Word16 i, j, s, sc, sn;
3494 : Word16 scaleCLDFB;
3495 : Word32 sqrtNoiseLevel;
3496 : Word16 randGaussExp;
3497 : Word16 cngNoiseLevelExp;
3498 : Word16 *seed;
3499 : Word32 *cngNoiseLevel;
3500 : Word32 *ptr_level;
3501 0 : HANDLE_FD_CNG_COM hFdCngCom = st->hFdCngDec->hFdCngCom;
3502 :
3503 0 : cngNoiseLevel = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3504 0 : cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
3505 0 : move16();
3506 0 : ptr_level = cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3507 0 : seed = &( hFdCngCom->seed );
3508 :
3509 : /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
3510 0 : scaleCLDFB = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); /*CLDFBinvScalingFactor_EXP + 1*/
3511 :
3512 0 : sn = 0;
3513 0 : move16();
3514 0 : IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
3515 : {
3516 0 : sn = add( sn, 1 );
3517 0 : cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
3518 : }
3519 :
3520 0 : randGaussExp = CNG_RAND_GAUSS_SHIFT;
3521 0 : move16();
3522 :
3523 0 : IF( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) )
3524 : {
3525 :
3526 0 : sc = add( shr( add( cngNoiseLevelExp, CLDFBinvScalingFactor_EXP + 1 - 1 ), 1 ), randGaussExp );
3527 0 : move16();
3528 0 : assert( ( ( cngNoiseLevelExp + CLDFBinvScalingFactor_EXP + 1 - 1 ) & 1 ) == 0 );
3529 :
3530 0 : FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
3531 : {
3532 : /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
3533 0 : s = 0;
3534 0 : move16();
3535 0 : sqrtNoiseLevel = Sqrt32( L_shr( Mpy_32_16_1( *ptr_level, scaleCLDFB ), sn ), &s ); /*Q31 - s*/
3536 :
3537 0 : FOR( i = 0; i < hFdCngCom->numSlots; i++ )
3538 : {
3539 : /* Real part in CLDFB band */
3540 0 : bufferReal[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*bufferScale*/
3541 0 : move32();
3542 : /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferReal[i][j],sc));*/
3543 :
3544 : /* Imaginary part in CLDFB band */
3545 0 : bufferImag[i][j] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s ); /*bufferScale*/
3546 0 : move32();
3547 : /*fprintf(pFile,"%13.10f\n",WORD322FL_SCALE(bufferImag[i][j],sc));*/
3548 : }
3549 0 : ptr_level = ptr_level + 1; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3550 : }
3551 0 : *bufferScale = sub( sc, 15 );
3552 0 : move16();
3553 : }
3554 0 : }
3555 :
3556 15059 : void generate_comfort_noise_dec_hf_ivas_fx(
3557 : Word32 **bufferReal, /* o : matrix to real part of input bands bufferScale*/
3558 : Word32 **bufferImag, /* o : matrix to imaginary part of input bands bufferScale*/
3559 : Word16 *bufferScale, /* o : pointer to scalefactor for real and imaginary part of input bands */
3560 : HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
3561 : const Word16 cng_coh_flag /* i : CNG Flag for coherence handling Q0*/
3562 : )
3563 : {
3564 : Word16 i, j, s, sc, sn;
3565 : Word16 scaleCLDFB;
3566 : Word32 sqrtNoiseLevel;
3567 : Word16 randGaussExp;
3568 : Word16 cngNoiseLevelExp;
3569 : Word16 *seed;
3570 : Word16 *seed2;
3571 : Word16 c1, c2;
3572 : Word32 *ptr_level;
3573 : Word32 *cngNoiseLevel;
3574 : Word32 tmp1, tmp2;
3575 :
3576 15059 : cngNoiseLevel = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3577 15059 : cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
3578 15059 : move16();
3579 15059 : ptr_level = cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3580 :
3581 15059 : seed = &( hFdCngCom->seed );
3582 :
3583 : /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
3584 15059 : scaleCLDFB = mult( hFdCngCom->invScalingFactor, CLDFB_SCALING ); /*CLDFBinvScalingFactor_EXP + 1*/
3585 :
3586 15059 : seed2 = &( hFdCngCom->seed );
3587 :
3588 15059 : c1 = 0;
3589 15059 : move16();
3590 15059 : c2 = 0;
3591 15059 : move16();
3592 15059 : sc = 0;
3593 15059 : move16();
3594 :
3595 15059 : IF( cng_coh_flag )
3596 : {
3597 5310 : seed2 = &( hFdCngCom->seed2 );
3598 :
3599 5310 : s = 0;
3600 5310 : move16();
3601 :
3602 5310 : c1 = Sqrt16( hFdCngCom->coherence_fx, &s ); /*Q15 - s*/
3603 5310 : c1 = shl( c1, s ); // Q15
3604 :
3605 5310 : s = 0;
3606 5310 : move16();
3607 5310 : c2 = Sqrt16( sub( MAX16B, hFdCngCom->coherence_fx ), &s ); /*Q15 - s*/
3608 5310 : c2 = shl( c2, s ); // Q15
3609 : }
3610 :
3611 15059 : sn = 0;
3612 15059 : move16();
3613 15059 : IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
3614 : {
3615 6821 : sn = add( sn, 1 );
3616 6821 : cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
3617 6821 : move16();
3618 : }
3619 :
3620 15059 : randGaussExp = CNG_RAND_GAUSS_SHIFT + 1;
3621 15059 : move16();
3622 :
3623 : /*
3624 : Generate Gaussian random noise in real and imaginary parts of the CLDFB bands
3625 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each band
3626 : */
3627 15059 : IF( LT_16( hFdCngCom->numCoreBands, hFdCngCom->regularStopBand ) )
3628 : {
3629 13431 : sc = add( shr( add( cngNoiseLevelExp, CLDFBinvScalingFactor_EXP + 1 - 1 ), 1 ), randGaussExp );
3630 13431 : move16();
3631 13431 : assert( ( ( cngNoiseLevelExp + CLDFBinvScalingFactor_EXP + 1 - 1 ) & 1 ) == 0 );
3632 :
3633 269588 : FOR( j = hFdCngCom->numCoreBands; j < hFdCngCom->regularStopBand; j++ )
3634 : {
3635 4354669 : FOR( i = 0; i < hFdCngCom->numSlots; i++ )
3636 : {
3637 : /* scaleCLDFB: CLDFBinvScalingFactor_EXP + 1 */
3638 4098512 : s = 0;
3639 4098512 : move16();
3640 4098512 : sqrtNoiseLevel = Sqrt32( L_shr( Mpy_32_16_1( *ptr_level, scaleCLDFB ), sn ), &s ); /*Q31 - s*/
3641 :
3642 4098512 : IF( cng_coh_flag )
3643 : {
3644 1545152 : rand_gauss_fx( &tmp1, seed, Q28 ); /*Q28*/
3645 1545152 : rand_gauss_fx( &tmp2, seed2, Q28 ); /*Q28*/
3646 :
3647 1545152 : bufferReal[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*bufferScale*/
3648 1545152 : move32();
3649 1545152 : bufferReal[i][j] = L_shl( Mpy_32_32( bufferReal[i][j], sqrtNoiseLevel ), s ); /*bufferScale*/
3650 1545152 : move32();
3651 :
3652 1545152 : rand_gauss_fx( &tmp1, seed, Q28 ); /*Q28*/
3653 1545152 : rand_gauss_fx( &tmp2, seed2, Q28 ); /*Q28*/
3654 :
3655 1545152 : bufferImag[i][j] = L_add( Mpy_32_16_1( tmp1, c1 ), Mpy_32_16_1( tmp2, c2 ) ); /*bufferScale*/
3656 1545152 : move32();
3657 1545152 : bufferImag[i][j] = L_shl( Mpy_32_32( bufferImag[i][j], sqrtNoiseLevel ), s ); /*bufferScale*/
3658 1545152 : move32();
3659 : }
3660 : ELSE
3661 : {
3662 : /* Real part in CLDFB band */
3663 2553360 : bufferReal[i][j] = L_shl( Mpy_32_32( L_shr( rand_gauss( seed ), 1 ), sqrtNoiseLevel ), s ); /*bufferScale*/
3664 2553360 : move32();
3665 :
3666 : /* Imaginary part in CLDFB band */
3667 2553360 : bufferImag[i][j] = L_shl( Mpy_32_32( L_shr( rand_gauss( seed ), 1 ), sqrtNoiseLevel ), s ); /*bufferScale*/
3668 2553360 : move32();
3669 : }
3670 : }
3671 256157 : ptr_level = ptr_level + 1; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3672 : }
3673 13431 : *bufferScale = sub( sc, 15 );
3674 13431 : move16();
3675 : }
3676 :
3677 15059 : return;
3678 : }
3679 :
3680 :
3681 : /*
3682 : generate_masking_noise_fx
3683 :
3684 : Parameters:
3685 :
3686 : timeDomainBuffer i/o : pointer to time domain output buffer 15Q0
3687 : st i/o : pointer to FD_CNG_COM structure
3688 : bitrate i : bitrate
3689 :
3690 : Function:
3691 : Generate additional comfort noise (kind of noise filling)
3692 :
3693 : Returns: none
3694 :
3695 : void
3696 : */
3697 1023 : void generate_masking_noise_fx(
3698 : Word16 *timeDomainBuffer, /* i/o : pointer to time domain output buffer 15Q0 */
3699 : Word16 Q,
3700 : HANDLE_FD_CNG_COM hFdCngCom /* i/o : pointer to FD_CNG_COM structure */
3701 : ,
3702 : Word16 length, /*Q0*/
3703 : Word16 core /*Q0*/ )
3704 : {
3705 : Word16 i, s, s1, s2, sq, cnt, startBand2, stopFFTbin2;
3706 : Word16 scaleExp, fftBufferExp, cngNoiseLevelExp;
3707 : Word16 scale, scaleTableSize;
3708 : Word16 maskingNoise[L_FRAME16k];
3709 : Word32 sqrtNoiseLevel;
3710 : Word32 *cngNoiseLevel;
3711 : Word32 *fftBuffer;
3712 : Word16 *seed;
3713 :
3714 : // PMTE(); /*IVAS CODE need to be added */
3715 :
3716 : /* pointer initializations */
3717 1023 : cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3718 1023 : fftBuffer = hFdCngCom->fftBuffer; /*Q31 - hFdCngCom->fftBuffer_exp*/
3719 1023 : seed = &( hFdCngCom->seed );
3720 :
3721 : /* Compute additional CN level */
3722 1023 : cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
3723 1023 : move16();
3724 :
3725 1023 : IF( NE_16( core, AMR_WB_CORE ) )
3726 : {
3727 1023 : scaleTableSize = 18;
3728 1023 : move16();
3729 1023 : assert( scaleTableSize == ( sizeof( scaleTable_cn_only ) / sizeof( scaleTable_cn_only[0] ) ) );
3730 :
3731 1023 : scale = -1;
3732 1023 : move16();
3733 15345 : FOR( i = 0; i < scaleTableSize; i++ )
3734 : {
3735 15345 : test();
3736 15345 : test();
3737 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 ) ) )
3738 :
3739 : {
3740 1023 : scale = scaleTable_cn_only[i].scale; /*Q14*/
3741 1023 : move16();
3742 1023 : BREAK;
3743 : }
3744 : }
3745 1023 : assert( scale >= 0 );
3746 : }
3747 : ELSE
3748 : {
3749 0 : scaleTableSize = 3;
3750 0 : move16();
3751 0 : assert( scaleTableSize == ( sizeof( scaleTable_cn_only_amrwbio ) / sizeof( scaleTable_cn_only_amrwbio[0] ) ) );
3752 :
3753 0 : scale = 0;
3754 0 : move16();
3755 0 : FOR( i = 0; i < scaleTableSize; i++ )
3756 : {
3757 0 : IF( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only_amrwbio[i][0] ) )
3758 : {
3759 0 : scale = scaleTable_cn_only_amrwbio[i][1]; /*Q14*/
3760 0 : move16();
3761 0 : BREAK;
3762 : }
3763 : }
3764 : }
3765 :
3766 : /* Exclude clean speech */
3767 :
3768 1023 : s1 = norm_s( scale );
3769 1023 : s2 = norm_s( hFdCngCom->likelihood_noisy_speech );
3770 :
3771 : /* scaleTable_cn_only[i].scale is scaled by 1 bit */
3772 1023 : scaleExp = sub( 1, add( s1, s2 ) );
3773 1023 : scale = mult_r( shl( scale, s1 ), shl( hFdCngCom->likelihood_noisy_speech, s2 ) ); /*Q15 - scaleExp*/
3774 :
3775 : {
3776 : /* add exponent of scale and cngNoiseLevel */
3777 1023 : fftBufferExp = add( scaleExp, cngNoiseLevelExp );
3778 :
3779 : /* even scalefactor needed for sqrt calculation */
3780 1023 : s = s_and( fftBufferExp, 1 );
3781 1023 : fftBufferExp = add( fftBufferExp, s );
3782 :
3783 : /* sqrt calculation => shift exponent */
3784 1023 : fftBufferExp = shr( fftBufferExp, 1 );
3785 :
3786 : /* consider scaling of random noise */
3787 1023 : fftBufferExp = add( fftBufferExp, CNG_RAND_GAUSS_SHIFT );
3788 :
3789 1023 : cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q0*/
3790 : /*
3791 : Generate Gaussian random noise in real and imaginary parts of the FFT bins
3792 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
3793 : */
3794 1023 : IF( hFdCngCom->startBand == 0 )
3795 : {
3796 : /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
3797 :
3798 : /* DC component in FFT */
3799 :
3800 : /* -s => consider scalefactor adaptation for sqrt calculation */
3801 0 : sq = sub( 0, s );
3802 0 : sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *cngNoiseLevel, scale ), &sq ); /*Q31 - sq*/
3803 0 : hFdCngCom->fftBuffer[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*q31 - hFdCngCom->fftBuffer_exp*/
3804 0 : move32();
3805 0 : hFdCngCom->fftBuffer[1] = 0;
3806 0 : move32();
3807 :
3808 0 : fftBuffer = hFdCngCom->fftBuffer + 2;
3809 0 : cngNoiseLevel++;
3810 :
3811 0 : cnt = sub( cnt, 1 );
3812 : }
3813 : ELSE
3814 : {
3815 1023 : startBand2 = shl( hFdCngCom->startBand, 1 );
3816 1023 : set32_fx( hFdCngCom->fftBuffer, 0, startBand2 );
3817 1023 : fftBuffer = hFdCngCom->fftBuffer + startBand2; /*Q31 - hFdCngCom->fftBuffer_exp*/
3818 : }
3819 :
3820 260865 : FOR( i = 0; i < cnt; i++ )
3821 : {
3822 : /* -1 => weighting with 0.5, -s => consider scalefactor adaptation for sqrt calculation */
3823 259842 : sq = sub( -1, s );
3824 259842 : sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *cngNoiseLevel, scale ), &sq ); /*Q31 - sq*/
3825 :
3826 : /* real part in FFT bins */
3827 :
3828 : /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
3829 259842 : *fftBuffer = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*Q31 - hFdCngCom->fftBuffer_exp*/
3830 259842 : move32();
3831 259842 : fftBuffer++;
3832 :
3833 : /* imaginary part in FFT bins */
3834 :
3835 : /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
3836 259842 : *fftBuffer = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*Q31 - hFdCngCom->fftBuffer_exp*/
3837 259842 : move32();
3838 259842 : fftBuffer++;
3839 :
3840 259842 : cngNoiseLevel++;
3841 : }
3842 :
3843 : /* remaining FFT bins are set to zero */
3844 1023 : stopFFTbin2 = shl( hFdCngCom->stopFFTbin, 1 );
3845 1023 : set32_fx( hFdCngCom->fftBuffer + stopFFTbin2, 0, sub( hFdCngCom->fftlen, stopFFTbin2 ) );
3846 :
3847 :
3848 : /* perform STFT synthesis */
3849 1023 : assert( hFdCngCom->olapBufferSynth2 != NULL );
3850 1023 : SynthesisSTFT( hFdCngCom->fftBuffer, fftBufferExp, maskingNoise, hFdCngCom->olapBufferSynth2, hFdCngCom->olapWinSyn,
3851 : 0, hFdCngCom, 0, NULL, -1 /*st->element_mode*/, -1 /*nchan_out*/ );
3852 : // PMT("parameters need update")
3853 :
3854 :
3855 : /* add some comfort noise on top of decoded signal */
3856 1023 : IF( hFdCngCom->frameSize > length )
3857 : {
3858 645 : FOR( i = 0; i < length; i++ )
3859 : {
3860 640 : timeDomainBuffer[i] = add( timeDomainBuffer[i], shr_r( maskingNoise[i], -Q ) ); /*Q0*/
3861 640 : move16();
3862 : }
3863 : }
3864 : ELSE
3865 : {
3866 261626 : FOR( i = 0; i < hFdCngCom->frameSize; i++ )
3867 : {
3868 260608 : timeDomainBuffer[i] = add_sat( timeDomainBuffer[i], shr_r_sat( maskingNoise[i], -Q ) ); /*Q0*/
3869 260608 : move16();
3870 : }
3871 : }
3872 : }
3873 1023 : }
3874 :
3875 : /*-------------------------------------------------------------------
3876 : * generate_masking_noise_update_seed_fx()
3877 : *
3878 : * Update seed for scenarios where generate_masking_noise_fx() is
3879 : * not called based on signal statistics
3880 : *-------------------------------------------------------------------*/
3881 :
3882 58348 : void generate_masking_noise_update_seed_fx(
3883 : HANDLE_FD_CNG_COM hFdCngCom /* i/o : pointer to FD_CNG_COM structure */
3884 : )
3885 : {
3886 : Word16 *seed;
3887 : Word16 cnt, i;
3888 :
3889 : /* pointer initializations */
3890 58348 : seed = &( hFdCngCom->seed );
3891 :
3892 58348 : cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q0*/
3893 :
3894 58348 : IF( hFdCngCom->startBand == 0 )
3895 : {
3896 0 : rand_gauss( seed ); /*Q15*/
3897 0 : cnt = sub( cnt, 1 );
3898 : }
3899 :
3900 16669204 : FOR( i = 0; i < cnt; i++ )
3901 : {
3902 16610856 : rand_gauss( seed ); /*Q15*/
3903 16610856 : rand_gauss( seed ); /*Q15*/
3904 : }
3905 :
3906 :
3907 58348 : return;
3908 : }
3909 :
3910 : /************************************************************
3911 : * Generate additional comfort noise (kind of noise filling) *
3912 : ************************************************************/
3913 264 : void generate_masking_noise_mdct_fx(
3914 : Word32 *mdctBuffer, /* i/o: time-domain signal Q31 - mdctBuffer_e*/
3915 : Word16 *mdctBuffer_e, /* i/o: exponent time-domain signal */
3916 : HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
3917 : ,
3918 : Word16 L_frame )
3919 : {
3920 : Word16 i, s, s1, s2, sq, cnt;
3921 : Word16 scaleExp, maskingNoiseExp, cngNoiseLevelExp;
3922 : Word16 scale, scaleTableSize;
3923 : Word32 noise;
3924 : Word32 sqrtNoiseLevel;
3925 : Word32 maskingNoise[2 * L_FRAME16k];
3926 : Word32 *pMaskingNoise;
3927 : Word32 *cngNoiseLevel;
3928 : Word16 *seed;
3929 :
3930 : // PMTE(); /*IVAS CODE need to be added */
3931 : /* pointer initializations */
3932 264 : cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
3933 264 : seed = &( hFdCngCom->seed );
3934 :
3935 : /* Compute additional CN level */
3936 264 : cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
3937 264 : move16();
3938 :
3939 : /* Compute additional CN level */
3940 264 : scaleTableSize = 18;
3941 264 : move16();
3942 264 : assert( scaleTableSize == ( sizeof( scaleTable_cn_only ) / sizeof( scaleTable_cn_only[0] ) ) );
3943 :
3944 264 : scale = -1;
3945 264 : move16();
3946 3960 : FOR( i = 0; i < scaleTableSize; i++ )
3947 : {
3948 3960 : test();
3949 3960 : test();
3950 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 ) ) )
3951 : {
3952 264 : scale = scaleTable_cn_only[i].scale; /*Q14*/
3953 264 : move16();
3954 264 : BREAK;
3955 : }
3956 : }
3957 264 : assert( scale >= 0 );
3958 :
3959 : /* Exclude clean speech */
3960 264 : s1 = norm_s( scale );
3961 264 : s2 = norm_s( hFdCngCom->likelihood_noisy_speech );
3962 :
3963 : /* scaleTable_cn_only[i].scale is scaled by 1 bit */
3964 264 : scaleExp = sub( 1, add( s1, s2 ) );
3965 264 : scale = mult_r( shl( scale, s1 ), shl( hFdCngCom->likelihood_noisy_speech, s2 ) ); /*Q15 - scaleExp*/
3966 :
3967 : /* add exponent of scale and cngNoiseLevel */
3968 264 : maskingNoiseExp = add( scaleExp, cngNoiseLevelExp );
3969 :
3970 : /* even scalefactor needed for sqrt calculation */
3971 264 : s = s_and( maskingNoiseExp, 1 );
3972 264 : maskingNoiseExp = add( maskingNoiseExp, s );
3973 :
3974 : /* sqrt calculation => shift exponent */
3975 264 : maskingNoiseExp = shr( maskingNoiseExp, 1 );
3976 :
3977 : /* consider scaling of random noise */
3978 264 : maskingNoiseExp = add( maskingNoiseExp, CNG_RAND_GAUSS_SHIFT );
3979 :
3980 264 : cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q0*/
3981 :
3982 : /*
3983 : Generate Gaussian random noise in real and imaginary parts of the FFT bins
3984 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
3985 : */
3986 264 : IF( hFdCngCom->startBand == 0 )
3987 : {
3988 : /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
3989 :
3990 : /* DC component in FFT */
3991 :
3992 : /* -1 => weighting with 0.5, -s => consider scalefactor adaptation for sqrt calculation */
3993 0 : sq = sub( -1, s );
3994 0 : sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *cngNoiseLevel, scale ), &sq ); /*Q31 - sq*/
3995 0 : maskingNoise[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*Q15*/
3996 0 : move32();
3997 :
3998 0 : pMaskingNoise = &maskingNoise[1]; /*Q15*/
3999 0 : cngNoiseLevel++;
4000 :
4001 0 : cnt = sub( cnt, 1 );
4002 : }
4003 : ELSE
4004 : {
4005 264 : set32_fx( maskingNoise, 0, hFdCngCom->startBand );
4006 264 : pMaskingNoise = maskingNoise + hFdCngCom->startBand; /*Q15*/
4007 : }
4008 :
4009 67320 : FOR( i = 0; i < cnt; i++ )
4010 : {
4011 : /* -1 => weighting with 0.5, -s => consider scalefactor adaptation for sqrt calculation */
4012 67056 : sq = sub( -1, s );
4013 67056 : sqrtNoiseLevel = Sqrt32( Mpy_32_16_1( *cngNoiseLevel, scale ), &sq ); /*Q31 - sq*/
4014 :
4015 : /* real part in FFT bins */
4016 :
4017 : /* random noise is scaled by CNG_RAND_GAUSS_SHIFT bits */
4018 67056 : *pMaskingNoise = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), sq ); /*Q15*/
4019 67056 : move32();
4020 67056 : pMaskingNoise++;
4021 :
4022 67056 : cngNoiseLevel++;
4023 : }
4024 :
4025 : /* re-normalization of energy level
4026 : 16 * 0.79056941504 = sqrt(NORM_MDCT_FACTOR)
4027 : */
4028 : assert( NORM_MDCT_FACTOR == 160 );
4029 :
4030 : /* do weighting with factor 0.79056941504 later */
4031 264 : maskingNoiseExp = add( maskingNoiseExp, 4 );
4032 :
4033 264 : s = s_max( *mdctBuffer_e, maskingNoiseExp );
4034 264 : s1 = sub( s, *mdctBuffer_e );
4035 264 : s2 = sub( s, maskingNoiseExp );
4036 :
4037 : /* avoid rescaling of mdct samples if no comfort noise is added */
4038 264 : IF( scale != 0 )
4039 : {
4040 : /* Add some comfort noise on top of decoded signal */
4041 0 : IF( s1 == 0 )
4042 : {
4043 0 : FOR( i = 0; i < hFdCngCom->stopFFTbin; i++ )
4044 : {
4045 : /* If shifting negative noise values the lowest result is -1 but never 0.
4046 : Shift positive noise values to avoid unwanted amplification of these small values later */
4047 0 : noise = L_shr( Mpy_32_16_1( L_abs( maskingNoise[i] ), 25905 /*0.79056941504 Q15*/ ), s2 ); /*Q31 - maskingNoiseExp - s2*/
4048 :
4049 0 : if ( maskingNoise[i] < 0 )
4050 : {
4051 0 : noise = L_negate( noise );
4052 : }
4053 :
4054 0 : mdctBuffer[i] = L_add( mdctBuffer[i], noise ); /*Q31 - s*/
4055 0 : move32();
4056 : }
4057 : }
4058 : ELSE
4059 : {
4060 0 : FOR( i = 0; i < hFdCngCom->stopFFTbin; i++ )
4061 : {
4062 0 : mdctBuffer[i] = L_add( L_shr( mdctBuffer[i], s1 ),
4063 : Mpy_32_16_1( maskingNoise[i], 25905 /*0.79056941504 Q15*/ ) ); /*Q31 - s*/
4064 0 : move32();
4065 : }
4066 0 : FOR( i = hFdCngCom->stopFFTbin; i < L_frame; i++ )
4067 : {
4068 0 : mdctBuffer[i] = L_shr( mdctBuffer[i], s1 ); /*Q31 - s*/
4069 0 : move32();
4070 : }
4071 0 : *mdctBuffer_e = s;
4072 0 : move16();
4073 : }
4074 : }
4075 264 : }
4076 :
4077 22705 : void generate_masking_noise_mdct_ivas_fx(
4078 : Word32 *mdctBuffer, /* i/o: time-domain signal Q31 - mdctBuffer_e*/
4079 : Word16 *mdctBuffer_e, /* i/o: exponent time-domain signal */
4080 : HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */ )
4081 : {
4082 : Word16 i, sq, cnt;
4083 : Word16 cngNoiseLevelExp;
4084 : Word32 scale, temp;
4085 : Word32 sqrtNoiseLevel;
4086 : Word32 maskingNoise[2 * L_FRAME16k];
4087 : Word32 *pMaskingNoise;
4088 : Word32 *cngNoiseLevel;
4089 : Word16 *seed;
4090 :
4091 : // PMTE(); /*IVAS CODE need to be added */
4092 : /* pointer initializations */
4093 22705 : cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*Q31 - hFdCngCom->cngNoiseLevelExp*/
4094 22705 : seed = &( hFdCngCom->seed );
4095 :
4096 : /* Compute additional CN level */
4097 22705 : cngNoiseLevelExp = hFdCngCom->cngNoiseLevelExp;
4098 22705 : move16();
4099 :
4100 22705 : scale = ONE_IN_Q30;
4101 22705 : move32();
4102 :
4103 22705 : cnt = sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand );
4104 :
4105 : /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
4106 22705 : IF( hFdCngCom->likelihood_noisy_speech > 0 )
4107 : {
4108 11144 : FOR( i = 0; i < SIZE_SCALE_TABLE_CN; i++ )
4109 : {
4110 11144 : test();
4111 11144 : test();
4112 11144 : IF( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) &&
4113 : GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) &&
4114 : LE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) )
4115 : {
4116 810 : BREAK;
4117 : }
4118 : }
4119 :
4120 : /* Exclude clean speech */
4121 810 : scale = L_mult( scaleTable_cn_only[i].scale, hFdCngCom->likelihood_noisy_speech ); // Q30 (14 + 15 + 1)
4122 :
4123 : /*
4124 : Generate Gaussian random noise in real and imaginary parts of the FFT bins
4125 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
4126 : */
4127 810 : IF( hFdCngCom->startBand == 0 )
4128 : {
4129 : /* *cngNoiseLevel * scale * 0.5 */
4130 0 : temp = Mpy_32_32( *cngNoiseLevel, scale ); // exp = cngNoiseLevelExp (cngNoiseLevelExp + Q30(scale) + 1(0.5f) - 31)
4131 0 : sq = cngNoiseLevelExp;
4132 0 : move16();
4133 :
4134 0 : sqrtNoiseLevel = Sqrt32( temp, &sq ); /*Q31 - sq*/
4135 :
4136 0 : rand_gauss_fx( &temp, seed, Q15 ); // Q15
4137 :
4138 0 : maskingNoise[0] = L_shl( Mpy_32_32( temp, sqrtNoiseLevel ), sq ); // Q15
4139 0 : move32();
4140 :
4141 0 : pMaskingNoise = &maskingNoise[1]; /*Q15*/
4142 0 : cngNoiseLevel++;
4143 0 : cnt = sub( cnt, 1 );
4144 : }
4145 : ELSE
4146 : {
4147 810 : set32_fx( maskingNoise, 0, hFdCngCom->startBand );
4148 810 : pMaskingNoise = maskingNoise + hFdCngCom->startBand; /*Q15*/
4149 : }
4150 :
4151 226902 : FOR( i = 0; i < cnt; i++ )
4152 : {
4153 : /* MDCT bins */
4154 : /* *cngNoiseLevel * scale * 0.5 */
4155 226092 : temp = Mpy_32_32( *cngNoiseLevel, scale ); // exp = cngNoiseLevelExp (cngNoiseLevelExp + Q30(scale) + 1(0.5f) - 31)
4156 226092 : sq = cngNoiseLevelExp;
4157 226092 : move16();
4158 :
4159 226092 : sqrtNoiseLevel = Sqrt32( temp, &sq ); /*Q31 - sq*/
4160 :
4161 226092 : rand_gauss_fx( &temp, seed, Q15 ); // Q15
4162 :
4163 226092 : *pMaskingNoise = L_shl( Mpy_32_32( temp, sqrtNoiseLevel ), sq ); // Q15
4164 226092 : move32();
4165 :
4166 226092 : pMaskingNoise++;
4167 226092 : cngNoiseLevel++;
4168 : }
4169 :
4170 : /*re-normalization of energy level: M/sqrt(2)*/
4171 810 : v_multc_fixed( maskingNoise, SQRT_NORM_MDCT_FACTOR_Q27, maskingNoise, hFdCngCom->stopFFTbin ); // Q11
4172 :
4173 810 : scale_sig32( maskingNoise, hFdCngCom->stopFFTbin, sub( 20, *mdctBuffer_e ) ); // exp = *mdctBuffer_e
4174 :
4175 : /* Add some comfort noise on top of decoded signal */
4176 810 : v_add_fixed( maskingNoise, mdctBuffer, mdctBuffer, hFdCngCom->stopFFTbin, 1 );
4177 810 : *mdctBuffer_e = sub( *mdctBuffer_e, 1 );
4178 810 : move16();
4179 : }
4180 : ELSE
4181 : {
4182 : /* very low level case - just update random seeds */
4183 21895 : IF( hFdCngCom->startBand == 0 )
4184 : {
4185 0 : rand_gauss_fx( &maskingNoise[0], seed, Q15 ); // Q15
4186 0 : cngNoiseLevel++;
4187 0 : cnt = sub( cnt, 1 );
4188 : }
4189 :
4190 6261817 : FOR( i = 0; i < cnt; i++ )
4191 : {
4192 6239922 : rand_gauss_fx( &maskingNoise[0], seed, Q15 ); // Q15
4193 6239922 : move32();
4194 : }
4195 : }
4196 :
4197 22705 : return;
4198 : }
4199 :
4200 :
4201 : /*-------------------------------------------------------------------
4202 : * initFdCngDec()
4203 : *
4204 : * Initialize an instance of type FD_CNG
4205 : *-------------------------------------------------------------------*/
4206 524837 : void configureFdCngDec_ivas_fx(
4207 : HANDLE_FD_CNG_DEC hFdCngDec, /* i/o: Contains the variables related to the FD-based CNG process */
4208 : const Word16 bwidth, /*Q0*/
4209 : const Word32 total_brate, /*Q0*/
4210 : const Word16 L_frame, /*Q0*/
4211 : const Word16 last_L_frame, /*Q0*/
4212 : const Word16 element_mode /*Q0*/ )
4213 : {
4214 : Word16 j, stopBandFR;
4215 524837 : HANDLE_FD_CNG_COM hsCom = hFdCngDec->hFdCngCom;
4216 :
4217 524837 : hsCom->CngBandwidth = bwidth; /*Q0*/
4218 524837 : move16();
4219 524837 : if ( EQ_16( hsCom->CngBandwidth, FB ) )
4220 : {
4221 347807 : hsCom->CngBandwidth = SWB;
4222 347807 : move16();
4223 : }
4224 524837 : test();
4225 524837 : IF( NE_32( total_brate, FRAME_NO_DATA ) && NE_32( total_brate, SID_2k40 ) )
4226 : {
4227 524540 : hsCom->CngBitrate = total_brate; /*Q0*/
4228 524540 : move32();
4229 : }
4230 297 : ELSE IF( EQ_32( hsCom->CngBitrate, -1 ) )
4231 : {
4232 : /* set minimum active CBR bitrate IF CngBitrate is uninitialized */
4233 0 : IF( element_mode > EVS_MONO )
4234 : {
4235 0 : hsCom->CngBitrate = IVAS_13k2;
4236 0 : move32();
4237 : }
4238 : ELSE
4239 : {
4240 0 : hsCom->CngBitrate = ACELP_7k20;
4241 0 : move32();
4242 : }
4243 : }
4244 :
4245 : /* FD-CNG config for MDCT-Stereo is always the same (since for > 48 kbps only) */
4246 : /* This may need adjustment in the future IF 2TC DTX for some mode uses MDCT-Stereo DTX for lower bitrates too */
4247 524837 : if ( EQ_16( element_mode, IVAS_CPE_MDCT ) )
4248 : {
4249 417535 : hsCom->CngBitrate = IVAS_48k;
4250 417535 : move32();
4251 : }
4252 524837 : hsCom->numSlots = 16;
4253 524837 : move32();
4254 :
4255 : /* NB configuration */
4256 524837 : IF( EQ_16( bwidth, NB ) )
4257 : {
4258 0 : hsCom->FdCngSetup = FdCngSetup_nb;
4259 0 : hsCom->numCoreBands = 16;
4260 0 : move16();
4261 0 : hsCom->regularStopBand = 16;
4262 0 : move16();
4263 : }
4264 :
4265 : /* WB configuration */
4266 524837 : ELSE IF( EQ_16( bwidth, WB ) )
4267 : {
4268 : /* FFT 6.4kHz, no CLDFB */
4269 1064 : test();
4270 1064 : test();
4271 1064 : IF( LE_32( hsCom->CngBitrate, ACELP_8k00 ) && EQ_16( L_frame, L_FRAME ) )
4272 : {
4273 312 : hsCom->FdCngSetup = FdCngSetup_wb1;
4274 312 : hsCom->numCoreBands = 16;
4275 312 : move16();
4276 312 : hsCom->regularStopBand = 16;
4277 312 : move16();
4278 : }
4279 : /* FFT 6.4kHz, CLDFB 8.0kHz */
4280 752 : ELSE IF( LE_32( hsCom->CngBitrate, ACELP_13k20 ) || EQ_16( L_frame, L_FRAME ) )
4281 : {
4282 149 : hsCom->FdCngSetup = FdCngSetup_wb2;
4283 149 : hsCom->numCoreBands = 16;
4284 149 : move16();
4285 149 : hsCom->regularStopBand = 20;
4286 149 : move16();
4287 149 : IF( EQ_16( L_frame, L_FRAME16k ) )
4288 : {
4289 8 : hsCom->FdCngSetup = FdCngSetup_wb2;
4290 8 : hsCom->numCoreBands = 20;
4291 8 : move16();
4292 8 : hsCom->regularStopBand = 20;
4293 8 : move16();
4294 8 : hsCom->FdCngSetup.fftlen = 640;
4295 8 : move16();
4296 8 : hsCom->FdCngSetup.stopFFTbin = 256;
4297 8 : move16();
4298 : }
4299 : }
4300 : /* FFT 8.0kHz, no CLDFB */
4301 : ELSE
4302 : {
4303 603 : hsCom->FdCngSetup = FdCngSetup_wb3;
4304 603 : hsCom->numCoreBands = 20;
4305 603 : move16();
4306 603 : hsCom->regularStopBand = 20;
4307 603 : move16();
4308 : }
4309 : }
4310 :
4311 : /* SWB/FB configuration */
4312 : ELSE
4313 : {
4314 : /* FFT 6.4kHz, CLDFB 14kHz */
4315 523773 : IF( EQ_16( L_frame, L_FRAME ) )
4316 : {
4317 2663 : hsCom->FdCngSetup = FdCngSetup_swb1;
4318 2663 : hsCom->numCoreBands = 16;
4319 2663 : move16();
4320 2663 : hsCom->regularStopBand = 35;
4321 2663 : move16();
4322 : }
4323 : /* FFT 8.0kHz, CLDFB 16kHz */
4324 : ELSE
4325 : {
4326 521110 : hsCom->FdCngSetup = FdCngSetup_swb2;
4327 521110 : hsCom->numCoreBands = 20;
4328 521110 : move16();
4329 521110 : hsCom->regularStopBand = 40;
4330 521110 : move16();
4331 521110 : test();
4332 521110 : if ( EQ_16( last_L_frame, L_FRAME ) && EQ_16( element_mode, IVAS_CPE_DFT ) )
4333 : {
4334 139 : hsCom->regularStopBand = 35;
4335 139 : move16();
4336 : }
4337 : }
4338 : }
4339 :
4340 :
4341 524837 : hsCom->fftlen = hsCom->FdCngSetup.fftlen;
4342 524837 : move16();
4343 524837 : hsCom->stopFFTbin = hsCom->FdCngSetup.stopFFTbin;
4344 524837 : move16();
4345 :
4346 : /* Configure the SID quantizer and the Comfort Noise Generator */
4347 :
4348 524837 : hsCom->startBand = 2;
4349 524837 : move16();
4350 524837 : hsCom->stopBand = add( hsCom->FdCngSetup.sidPartitions[( hsCom->FdCngSetup.numPartitions - 1 )], 1 ); /*Q0*/
4351 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 );
4352 :
4353 524837 : IF( EQ_16( hsCom->stopFFTbin, 160 ) )
4354 : {
4355 0 : hsCom->nFFTpart = 17;
4356 0 : move16();
4357 : }
4358 524837 : ELSE IF( EQ_16( hsCom->stopFFTbin, 256 ) )
4359 : {
4360 3124 : hsCom->nFFTpart = 20;
4361 3124 : move16();
4362 : }
4363 : ELSE
4364 : {
4365 521713 : hsCom->nFFTpart = 21;
4366 521713 : move16();
4367 : }
4368 524837 : hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); /*Q0*/
4369 524837 : move16();
4370 2098968 : FOR( j = 0; j < hsCom->nCLDFBpart; j++ )
4371 : {
4372 1574131 : hsCom->CLDFBpart[j] = sub( hsCom->part[( j + hsCom->nFFTpart )], sub( hsCom->stopFFTbin, hsCom->startBand ) ); /*Q0*/
4373 1574131 : move16();
4374 1574131 : hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[( j + hsCom->nFFTpart )];
4375 1574131 : move16();
4376 : }
4377 :
4378 524837 : stopBandFR = 40; //(Word16)floor(1000.f /*Hz*/ / 25.f /*Hz/Bin*/);
4379 524837 : move16();
4380 524837 : if ( GT_16( stopBandFR, hsCom->stopFFTbin ) )
4381 : {
4382 0 : stopBandFR = hsCom->stopFFTbin; /*Q0*/
4383 0 : move16();
4384 : }
4385 :
4386 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 );
4387 :
4388 524837 : hFdCngDec->nFFTpart_shaping = hFdCngDec->npart_shaping; /*Q0*/
4389 524837 : move16();
4390 :
4391 524837 : BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) );
4392 524837 : BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) );
4393 :
4394 524837 : SWITCH( hsCom->fftlen )
4395 : {
4396 3116 : case 512:
4397 3116 : hsCom->olapWinAna_fx = olapWinAna512_fx; /*Q30*/
4398 3116 : hsCom->fftSineTab_fx = NULL;
4399 3116 : hsCom->olapWinSyn_fx = olapWinSyn256_fx; /*Q15*/
4400 3116 : hsCom->fftlenShift = 8;
4401 3116 : move16();
4402 3116 : hsCom->fftlenFac = 32767 /*1.0 Q15*/;
4403 3116 : move16();
4404 3116 : BREAK;
4405 521721 : case 640:
4406 521721 : hsCom->olapWinAna_fx = olapWinAna640_fx; /*Q30*/
4407 521721 : hsCom->fftSineTab_fx = fftSineTab640_fx; /*Q15*/
4408 521721 : hsCom->olapWinSyn_fx = olapWinSyn320_fx; /*Q15*/
4409 521721 : hsCom->fftlenShift = 9;
4410 521721 : move16();
4411 521721 : hsCom->fftlenFac = 20480 /*0.625 Q15*/;
4412 521721 : move16();
4413 521721 : BREAK;
4414 0 : default:
4415 0 : assert( !"Unsupported FFT length for FD-based CNG" );
4416 : BREAK;
4417 : }
4418 524837 : BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) );
4419 524837 : BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) );
4420 524837 : hsCom->frameSize = shr( hsCom->fftlen, 1 );
4421 :
4422 524837 : return;
4423 : }
4424 :
4425 : /*-------------------------------------------------------------------
4426 : * FdCng_decodeSID_ivas_fx()
4427 : *
4428 : * Decode the FD-CNG bitstream
4429 : *-------------------------------------------------------------------*/
4430 :
4431 1913 : void FdCng_decodeSID_ivas_fx(
4432 : Decoder_State *st /* i/o: decoder state structure */
4433 : )
4434 : {
4435 : Word16 N;
4436 : Word32 *sidNoiseEst;
4437 : Word32 gain;
4438 : Word16 i, index;
4439 : Word32 v[32];
4440 : Word16 indices[32];
4441 : HANDLE_FD_CNG_COM hFdCngCom;
4442 : Word32 *invTrfMatrix_fx;
4443 : Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
4444 : Word16 tmp16;
4445 :
4446 1913 : IF( st->element_mode == EVS_MONO )
4447 : {
4448 0 : tmp16 = GAIN_Q_OFFSET_EVS_FX_Q0;
4449 0 : move16();
4450 : }
4451 : ELSE
4452 : {
4453 1913 : tmp16 = GAIN_Q_OFFSET_IVAS_FX_Q0;
4454 1913 : move16();
4455 : }
4456 :
4457 1913 : const Word16 gain_q_offset = tmp16; /* Q0 */
4458 1913 : move16();
4459 :
4460 1913 : invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /*Q31*/
4461 :
4462 1913 : hFdCngCom = ( st->hFdCngDec )->hFdCngCom;
4463 :
4464 1913 : sidNoiseEst = hFdCngCom->sidNoiseEst; /*Q16*/
4465 :
4466 1913 : N = hFdCngCom->npart; /*Q0*/
4467 1913 : move16();
4468 1913 : gain = 0;
4469 1913 : move32();
4470 1913 : hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 );
4471 1913 : move16();
4472 :
4473 : /* Read bitstream */
4474 13391 : FOR( i = 0; i < FD_CNG_stages_37bits; i++ )
4475 : {
4476 11478 : indices[i] = get_next_indice_fx( st, bits_37bits[i] ); /*Q0*/
4477 11478 : move16();
4478 : }
4479 :
4480 1913 : index = get_next_indice_fx( st, 7 );
4481 :
4482 : /* MSVQ decoder */
4483 :
4484 1913 : IF( st->element_mode != EVS_MONO )
4485 : {
4486 1913 : create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, FDCNG_VQ_MAX_LEN * FDCNG_VQ_DCT_MAXTRUNC );
4487 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 );
4488 : }
4489 : ELSE
4490 : { /* Legacy EVS_MONO MSVQ tables */
4491 0 : msvq_dec_fx( cdk_37bits, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v, NULL, 7 );
4492 : }
4493 :
4494 :
4495 : /* Decode gain */
4496 : // gain = ((float)index - gain_q_offset) / 1.5f;
4497 1913 : gain = L_mult0( sub( index, gain_q_offset ), 21845 ); // Q15
4498 :
4499 : /* Apply gain and undo log */
4500 : Word16 res_exp[NPART];
4501 1913 : Word16 max_res_exp = 0;
4502 1913 : move16();
4503 46554 : FOR( i = 0; i < N; i++ )
4504 : {
4505 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]*/
4506 44641 : move32();
4507 44641 : if ( LT_16( max_res_exp, res_exp[i] ) )
4508 : {
4509 1299 : max_res_exp = res_exp[i];
4510 1299 : move16();
4511 : }
4512 : }
4513 :
4514 46554 : FOR( i = 0; i < N; i++ )
4515 : {
4516 44641 : sidNoiseEst[i] = L_shr( sidNoiseEst[i], sub( max_res_exp, res_exp[i] ) ); /*Q31 - max_res_exp*/
4517 44641 : move32();
4518 : }
4519 :
4520 1913 : hFdCngCom->sidNoiseEstExp = max_res_exp;
4521 1913 : move16();
4522 :
4523 : /* NB last band energy compensation */
4524 :
4525 1913 : IF( hFdCngCom->CngBandwidth == NB )
4526 : {
4527 0 : sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], NB_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/
4528 0 : move32();
4529 : }
4530 :
4531 1913 : test();
4532 1913 : IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) )
4533 : {
4534 475 : sidNoiseEst[( N - 1 )] = Mpy_32_16_1( sidNoiseEst[( N - 1 )], SWB_13k2_LAST_BAND_SCALE ); /*Q31 - max_res_exp*/
4535 475 : move32();
4536 : }
4537 :
4538 1913 : scalebands( sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 );
4539 1913 : Word16 shift1 = L_norm_arr( hFdCngCom->cngNoiseLevel, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) );
4540 1913 : Word16 shift2 = L_norm_arr( hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ) );
4541 1913 : Word16 shift = s_max( sub( hFdCngCom->sidNoiseEstExp, shift1 ), sub( hFdCngCom->cngNoiseLevelExp, shift2 ) );
4542 :
4543 1913 : scale_sig32( hFdCngCom->cngNoiseLevel, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( hFdCngCom->sidNoiseEstExp, shift ) );
4544 1913 : scale_sig32( hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopBand, hFdCngCom->startBand ), sub( FFTCLDFBLEN, sub( hFdCngCom->stopBand, hFdCngCom->startBand ) ), sub( hFdCngCom->cngNoiseLevelExp, shift ) );
4545 :
4546 1913 : hFdCngCom->cngNoiseLevelExp = shift;
4547 1913 : move16();
4548 :
4549 1913 : lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, st->preemph_fac );
4550 :
4551 1913 : return;
4552 : }
4553 :
4554 : /*-------------------------------------------------------------------
4555 : * generate_masking_noise_ivas_fx()
4556 : *
4557 : * Generate additional comfort noise (kind of noise filling)
4558 : *-------------------------------------------------------------------*/
4559 :
4560 59366 : void generate_masking_noise_ivas_fx(
4561 : Word32 *timeDomainBuffer, /* i/o: time-domain signal Q31 - *exp_out*/
4562 : Word16 *exp_out, /* o : time-domain signal exp */
4563 : HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
4564 : const Word16 length, /* i : frame size Q0*/
4565 : const Word16 core, /* i : core Q0*/
4566 : const Word16 return_noise, /* i : noise is returned instead of added Q0*/
4567 : const Word16 secondary, /* i : flag to indicate secondary noise generation Q0*/
4568 : const Word16 element_mode, /* i : element mode Q0*/
4569 : STEREO_CNG_DEC_HANDLE hStereoCng, /* i : stereo CNG handle */
4570 : const Word16 nchan_out /* i : number of output channels Q0*/
4571 : )
4572 : {
4573 59366 : Word32 *cngNoiseLevel_fx = hFdCngCom->cngNoiseLevel;
4574 59366 : Word32 *ptr_level_fx = cngNoiseLevel_fx;
4575 59366 : Word32 *fftBuffer_fx = hFdCngCom->fftBuffer;
4576 : Word16 i;
4577 : Word32 maskingNoise_fx[L_FRAME16k];
4578 : Word32 *ptr_r_fx;
4579 : Word32 *ptr_i_fx;
4580 : Word16 startBand;
4581 59366 : Word16 *seed = &( hFdCngCom->seed );
4582 : Word32 scale_fx;
4583 : Word16 shift;
4584 59366 : scale_fx = 0x40000000; // 1.0 in Q30
4585 59366 : move32();
4586 59366 : startBand = hFdCngCom->startBand; /*Q0*/
4587 59366 : move16();
4588 59366 : shift = getScaleFactor32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN );
4589 59366 : if ( LT_16( sub( hFdCngCom->cngNoiseLevelExp, shift ), 4 ) )
4590 : {
4591 5596 : shift = sub( hFdCngCom->cngNoiseLevelExp, 4 ); /*Q0*/
4592 : }
4593 59366 : scale_sig32( hFdCngCom->cngNoiseLevel, FFTCLDFBLEN, shift ); /*hFdCngCom->cngNoiseLevelExp*/
4594 59366 : hFdCngCom->cngNoiseLevelExp = sub( hFdCngCom->cngNoiseLevelExp, shift );
4595 59366 : move16();
4596 :
4597 : /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
4598 59366 : *exp_out = Q15;
4599 59366 : move16();
4600 59366 : IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) )
4601 : {
4602 3404 : IF( NE_16( core, AMR_WB_CORE ) )
4603 : {
4604 : /* Compute additional CN level */
4605 45357 : FOR( i = 0; i < SIZE_SCALE_TABLE_CN; i++ )
4606 : {
4607 45357 : test();
4608 45357 : test();
4609 57458 : if ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_only[i].bwmode ) &&
4610 24202 : GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateFrom ) &&
4611 12101 : LT_32( hFdCngCom->CngBitrate, scaleTable_cn_only[i].bitrateTo ) )
4612 : {
4613 3404 : BREAK;
4614 : }
4615 : }
4616 :
4617 3404 : scale_fx = L_deposit_h( scaleTable_cn_only[i].scale_ivas ); /* Q30 */
4618 : }
4619 : ELSE
4620 : {
4621 : /* Compute additional CN level */
4622 0 : FOR( i = 0; i < SIZE_SCALE_TABLE_CN_AMRWB; i++ )
4623 : {
4624 0 : if ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_only_amrwbio[i][0] ) )
4625 : {
4626 0 : BREAK;
4627 : }
4628 : }
4629 :
4630 0 : IF( LT_16( i, SIZE_SCALE_TABLE_CN_AMRWB ) )
4631 : {
4632 0 : scale_fx = L_deposit_h( scaleTable_cn_only_amrwbio[i][1] ); /* Q30 */
4633 : }
4634 : ELSE
4635 : {
4636 0 : scale_fx = 0;
4637 0 : move32();
4638 : }
4639 : }
4640 :
4641 : /* Exclude clean speech */
4642 3404 : scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech ); // Q30
4643 :
4644 : /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
4645 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */
4646 3404 : IF( startBand == 0 )
4647 : {
4648 0 : rand_gauss_fx( &fftBuffer_fx[0], seed, *exp_out ); // Q15
4649 0 : ptr_r_fx = fftBuffer_fx + 2; /*Q31 - hFdCngCom->fftBuffer_exp*/
4650 : Word16 exp1;
4651 0 : exp1 = add( hFdCngCom->cngNoiseLevelExp, 1 );
4652 : Word32 mpy1;
4653 0 : mpy1 = Sqrt32( Mpy_32_32( scale_fx, *ptr_level_fx ), &exp1 ); /*Q31 - exp1*/
4654 0 : mpy1 = L_shl( mpy1, exp1 ); // Q31
4655 0 : fftBuffer_fx[0] = Mpy_32_32( fftBuffer_fx[0], mpy1 ); /* DC component in FFT */ // Q = Q15
4656 0 : ptr_level_fx++;
4657 : }
4658 : ELSE
4659 : {
4660 3404 : fftBuffer_fx[0] = 0;
4661 3404 : move32();
4662 3404 : set32_fx( fftBuffer_fx + 2, 0, shl( sub( startBand, 1 ), 1 ) );
4663 3404 : ptr_r_fx = fftBuffer_fx + shl( startBand, 1 ); /*Q31 - hFdCngCom->fftBuffer_exp*/
4664 : }
4665 3404 : ptr_i_fx = ptr_r_fx + 1;
4666 926580 : FOR( ; ptr_level_fx < cngNoiseLevel_fx + hFdCngCom->stopFFTbin - startBand; ptr_level_fx++ )
4667 : {
4668 : /* Real part in FFT bins */
4669 923176 : rand_gauss_fx( ptr_r_fx, seed, *exp_out ); // Q15
4670 : Word16 exp2;
4671 923176 : exp2 = add( hFdCngCom->cngNoiseLevelExp, 1 );
4672 : Word32 mpy2;
4673 923176 : mpy2 = Sqrt32( L_shr( Mpy_32_32( scale_fx, *ptr_level_fx ), 1 ), &exp2 ); /*Q31 - exp2*/
4674 923176 : ( *ptr_r_fx ) = L_shl( Mpy_32_32( *ptr_r_fx, mpy2 ), exp2 ); // Q = Q15
4675 923176 : move32();
4676 923176 : ptr_r_fx += 2;
4677 :
4678 : /* Imaginary part in FFT bins */
4679 923176 : rand_gauss_fx( ptr_i_fx, seed, *exp_out ); // Q15
4680 923176 : ( *ptr_i_fx ) = L_shl( Mpy_32_32( *ptr_i_fx, mpy2 ), exp2 ); // Q = Q15
4681 923176 : ptr_i_fx += 2;
4682 : }
4683 :
4684 : /* Remaining FFT bins are set to zero */
4685 3404 : set32_fx( fftBuffer_fx + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) );
4686 : /* Nyquist frequency is discarded */
4687 3404 : fftBuffer_fx[1] = 0;
4688 3404 : move32();
4689 : }
4690 : ELSE
4691 : {
4692 : /* very low level case - update random seeds and reset FFT buffer; don't fully skip SynthesisSTFT_flt(), because of the buffer updates done there... */
4693 55962 : generate_masking_noise_update_seed_fx( hFdCngCom );
4694 :
4695 55962 : set32_fx( fftBuffer_fx, 0, hFdCngCom->fftlen );
4696 : }
4697 :
4698 : /* Perform STFT synthesis */
4699 59366 : IF( secondary )
4700 : {
4701 438 : SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out );
4702 : }
4703 : ELSE
4704 : {
4705 58928 : SynthesisSTFT_fx( fftBuffer_fx, maskingNoise_fx, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, 0, hFdCngCom, element_mode, nchan_out );
4706 : }
4707 59366 : *exp_out = sub( *exp_out, Q9 );
4708 59366 : move16();
4709 :
4710 : /* Add some comfort noise on top of decoded signal */
4711 59366 : IF( return_noise )
4712 : {
4713 876 : Copy32( maskingNoise_fx, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ) ); /*Q31 - *exp_out*/
4714 : }
4715 : ELSE
4716 : {
4717 : #ifdef VEC_ARITH_OPT_v1
4718 58490 : v_add_fixed_no_hdrm( maskingNoise_fx, timeDomainBuffer, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ) ); /*Q31 - *exp_out*/
4719 : #else /* VEC_ARITH_OPT_v1 */
4720 : v_add_fixed( maskingNoise_fx, timeDomainBuffer, timeDomainBuffer, s_min( hFdCngCom->frameSize, length ), 0 ); /*Q31 - *exp_out*/
4721 : #endif /* VEC_ARITH_OPT_v1 */
4722 : }
4723 :
4724 59366 : return;
4725 : }
4726 :
4727 : /*-------------------------------------------------------------------
4728 : * generate_stereo_masking_noise_fx()
4729 : *
4730 : * Generate additional comfort noise (kind of noise filling)
4731 : *-------------------------------------------------------------------*/
4732 :
4733 888 : void generate_stereo_masking_noise_fx(
4734 : Word16 *syn, /* i/o: time-domain signal Q_syn*/
4735 : Word16 Q_syn,
4736 : Decoder_State *st, /* i/o: decoder state structure */
4737 : STEREO_TD_DEC_DATA_HANDLE hStereoTD, /* i : TD stereo structure */
4738 : const Word16 flag_sec_CNA, /* i : CNA flag for secondary channel Q0*/
4739 : const Word16 fadeOut, /* i : only fade out of previous state Q0*/
4740 : STEREO_CNG_DEC_HANDLE hStereoCng, /* i : Stereo CNG handle */
4741 : const Word16 nchan_out /* i : number of output channels Q0*/
4742 : )
4743 : {
4744 : HANDLE_FD_CNG_COM hFdCngCom;
4745 : Word32 gamma_fx, scale_fx /*, SP_ratio_fx needs to be integrated*/;
4746 : Word32 Np_fx[L_FRAME16k];
4747 : Word32 Ns_fx[L_FRAME16k];
4748 : Word32 N1_fx[L_FRAME16k];
4749 : Word32 N2_fx[L_FRAME16k];
4750 : Word16 N1_fx_exp, N2_fx_exp;
4751 : Word16 i;
4752 :
4753 888 : IF( st->idchan == 0 )
4754 : {
4755 438 : hFdCngCom = st->hFdCngDec->hFdCngCom;
4756 438 : Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, Ns_fx, shr( hFdCngCom->frameSize, 1 ), sub( Q6, st->Q_syn ) ); /*Q6*/
4757 438 : Copy32( hFdCngCom->olapBufferSynth2_fx, Np_fx, shr( hFdCngCom->frameSize, 1 ) ); /*st->Q_syn*/
4758 :
4759 438 : set32_fx( &Np_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) );
4760 438 : set32_fx( &Ns_fx[( hFdCngCom->frameSize / 2 )], 0, shr( hFdCngCom->frameSize, 1 ) );
4761 :
4762 438 : IF( !fadeOut )
4763 : {
4764 438 : Copy_Scale_sig_16_32_no_sat( hStereoCng->olapBufferSynth22_fx, hStereoCng->olapBufferSynth22_32fx, hFdCngCom->fftlen, sub( Q15, st->Q_syn ) ); /*Q15*/
4765 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
4766 : /* Generate masking noise for secondary channel */
4767 438 : IF( flag_sec_CNA )
4768 : {
4769 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
4770 438 : gamma_fx = L_shr( Mpy_32_32( hStereoCng->c_PS_LT_fx, hStereoCng->c_PS_LT_fx ), 1 ); /*Q30*/
4771 438 : scale_fx = ONE_IN_Q30;
4772 438 : move32();
4773 438 : IF( LT_32( gamma_fx, 966367642 /* 0.9 in Q30 */ ) )
4774 : {
4775 : Word16 exp_gamma;
4776 438 : exp_gamma = 0;
4777 438 : move16();
4778 : Word16 divisor1;
4779 438 : divisor1 = Inv16( (Word16) L_shr( L_sub( ONE_IN_Q30, gamma_fx ), Q15 ), &exp_gamma ); // Q15-exp_gamma
4780 438 : gamma_fx = L_shl( Mpy_32_16_1( gamma_fx, divisor1 ), exp_gamma ); // Q30
4781 : Word16 exp_gamma1, exp_gamma2, exp_gamma3;
4782 438 : exp_gamma1 = Q1;
4783 438 : exp_gamma2 = Q1;
4784 438 : exp_gamma3 = Q1;
4785 438 : move16();
4786 438 : move16();
4787 438 : move16();
4788 438 : gamma_fx = Sqrt32( L_add( gamma_fx, ONE_IN_Q30 ), &exp_gamma1 ); /*Q31 - exp_gamma1*/
4789 : Word32 temp;
4790 438 : temp = Sqrt32( gamma_fx, &exp_gamma2 ); // Q31-exp_gamma1
4791 438 : gamma_fx = L_sub( gamma_fx, L_shl( temp, sub( exp_gamma2, exp_gamma1 ) ) ); // Q31-exp_gamma1
4792 438 : gamma_fx = L_shl( gamma_fx, sub( exp_gamma1, Q1 ) ); // Q30
4793 : Word32 divisor2;
4794 438 : divisor2 = Sqrt32( L_add( ONE_IN_Q30, L_shl( Mpy_32_32( gamma_fx, gamma_fx ), Q1 ) ), &exp_gamma3 ); // Q31 - exp_gamma3
4795 438 : scale_fx = L_shl( divide3232( ONE_IN_Q30, divisor2 ), add( Q15, exp_gamma3 ) ); // Q30
4796 : }
4797 : ELSE
4798 : {
4799 0 : gamma_fx = 0;
4800 0 : move16();
4801 : }
4802 :
4803 56502 : FOR( i = 0; i < 2 * hFdCngCom->frameSize / 4; i++ )
4804 : {
4805 56064 : Np_fx[i] = L_add( Np_fx[i],
4806 : 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
4807 56064 : move32();
4808 : Word32 add2;
4809 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
4810 56064 : if ( hStereoCng->c_PS_LT_fx < 0 )
4811 : {
4812 35200 : add2 = L_negate( add2 ); /*Q6*/
4813 : }
4814 56064 : Ns_fx[i] = L_add( Ns_fx[i], add2 ); /*Q6*/
4815 56064 : move32();
4816 : }
4817 56502 : FOR( ; i < hFdCngCom->frameSize; i++ )
4818 : {
4819 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
4820 56064 : move32();
4821 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
4822 56064 : move32();
4823 56064 : IF( hStereoCng->c_PS_LT_fx < 0 )
4824 : {
4825 35200 : Ns_fx[i] = L_negate( Ns_fx[i] );
4826 35200 : move32();
4827 : }
4828 : }
4829 : /* Below code to be converted */
4830 438 : Word32 scale_fx_tmp = Mpy_32_32( scale_fx, L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ) ); // Q21
4831 56502 : FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ )
4832 : {
4833 56064 : hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp,
4834 56064 : L_add( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ),
4835 56064 : Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ),
4836 : Q14 ); // Q_olap
4837 56064 : move16();
4838 56064 : hStereoCng->olapBufferSynth22_fx[i] = (Word16) L_shr( Mpy_32_32( scale_fx_tmp,
4839 56064 : L_sub( L_shr( hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )], Q15 ),
4840 56064 : Mpy_32_16_1( gamma_fx, hStereoCng->olapBufferSynth22_fx[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ) ) ),
4841 : Q14 ); // Q_olap
4842 56064 : move16();
4843 : }
4844 : }
4845 : ELSE
4846 : {
4847 0 : FOR( i = 0; i < shr( hFdCngCom->frameSize, 1 ); i++ )
4848 : {
4849 0 : Np_fx[i] = L_add( Np_fx[i], N1_fx[i] ); // Q6
4850 0 : move32();
4851 : }
4852 0 : Copy32( &N1_fx[( hFdCngCom->frameSize / 2 )], &Np_fx[( hFdCngCom->frameSize / 2 )], shr( hFdCngCom->frameSize, 1 ) ); /*Q6*/
4853 0 : scale_fx = L_shl( shr( hFdCngCom->fftlen, 1 ), Q22 ); // Q21
4854 0 : FOR( i = 0; i < hFdCngCom->frameSize; i++ )
4855 : {
4856 0 : hFdCngCom->olapBufferSynth2[i] = (Word16) L_shr( Mpy_32_16_1( scale_fx, hFdCngCom->olapBufferSynth2[( i + ( 5 * ( hFdCngCom->frameSize / 4 ) ) )] ), Q6 ); // Q_olap
4857 0 : move16();
4858 : }
4859 : }
4860 :
4861 438 : Copy_Scale_sig_32_16( hStereoCng->olapBufferSynth22_32fx, hStereoCng->olapBufferSynth22_fx, hFdCngCom->fftlen, sub( st->Q_syn, 15 ) ); /*st->Q_syn*/
4862 : }
4863 : ELSE
4864 : {
4865 0 : set16_fx( hFdCngCom->olapBufferSynth2, 0, shr( hFdCngCom->frameSize, 1 ) );
4866 0 : set16_fx( hStereoCng->olapBufferSynth22_fx, 0, shr( hFdCngCom->frameSize, 1 ) );
4867 : }
4868 438 : IF( flag_sec_CNA )
4869 : {
4870 438 : Copy_Scale_sig_32_16( Ns_fx, hStereoCng->maskingNoiseS_fx, hFdCngCom->frameSize, 0 ); // Q6
4871 438 : hStereoCng->enableSecCNA = 1;
4872 438 : move16();
4873 : }
4874 : ELSE
4875 : {
4876 0 : set16_fx( hStereoCng->olapBufferSynth22_fx, 0, hFdCngCom->frameSize );
4877 : }
4878 :
4879 : /* add masking noise */
4880 112566 : FOR( i = 0; i < hFdCngCom->frameSize; i++ )
4881 : {
4882 112128 : syn[i] = add( syn[i], (Word16) L_shr( Np_fx[i], sub( Q16 + Q6, Q_syn ) ) ); // Q_syn
4883 112128 : move16();
4884 : }
4885 : }
4886 450 : ELSE IF( hStereoCng->enableSecCNA )
4887 : {
4888 : Word16 SP_ratio_fx;
4889 438 : SP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /* Use long-term SP ratio based on L/R synthesis Q15*/
4890 : Word16 prevSP_ratio_fx;
4891 438 : prevSP_ratio_fx = hStereoTD->prevSP_ratio_fx; /* Use long-term SP ratio based on L/R synthesis Q15*/
4892 438 : move16();
4893 : /* scale and add masking noise */
4894 28470 : FOR( i = 0; i < shr( *hStereoCng->frameSize, 2 ); i++ )
4895 : {
4896 : Word16 s;
4897 : Word16 scale_fx_tmp;
4898 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
4899 28032 : scale_fx_tmp = shl( scale_fx_tmp, s );
4900 28032 : syn[i] = add( syn[i], mult( scale_fx_tmp, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/
4901 28032 : move16();
4902 : }
4903 28470 : FOR( ; i < *hStereoCng->frameSize / 2; i++ )
4904 : {
4905 28032 : syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/
4906 28032 : move16();
4907 : }
4908 56502 : FOR( ; i < *hStereoCng->frameSize; i++ )
4909 : {
4910 56064 : syn[i] = add( syn[i], mult( SP_ratio_fx, shr( hStereoCng->maskingNoiseS_fx[i], sub( Q6, Q_syn ) ) ) ); /*Q_syn*/
4911 56064 : move16();
4912 : }
4913 438 : hStereoTD->prevSP_ratio_fx = extract_h( hStereoTD->SP_ratio_LT_fx ); /*Q15*/
4914 438 : move16();
4915 : }
4916 :
4917 888 : return;
4918 : }
4919 15697 : void generate_masking_noise_lb_dirac_fx(
4920 : HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
4921 : Word32 *tdBuffer, /* i/o: time-domain signal, if NULL no LB-CNA Q11*/
4922 : const Word16 nCldfbTs, /* i : number of CLDFB slots that will be rendered Q0*/
4923 : const Word16 cna_flag /* i : CNA flag for LB and HB Q0*/
4924 : )
4925 : {
4926 : Word16 i;
4927 15697 : Word32 *cngNoiseLevel = hFdCngCom->cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/
4928 15697 : Word32 *fftBuffer = hFdCngCom->fftBuffer; /*hFdCngCom->fftBuffer_exp*/
4929 : Word32 *ptr_r;
4930 : Word32 *ptr_i;
4931 : Word32 *ptr_level;
4932 15697 : Word16 *seed = &( hFdCngCom->seed );
4933 : Word32 scale;
4934 : Word16 n_samples_out, n_samples_start, n_samples_out_loop;
4935 :
4936 15697 : push_wmops( "fd_cng_dirac" );
4937 :
4938 : /* Init */
4939 15697 : scale = 0;
4940 15697 : move32();
4941 15697 : n_samples_out = i_mult( shr( hFdCngCom->frameSize, 4 ), nCldfbTs );
4942 15697 : n_samples_start = 0;
4943 15697 : move16();
4944 15697 : Word16 exp_out = Q11;
4945 15697 : move16();
4946 : /*LB CLDFB - CNA from STFT*/
4947 15697 : IF( cna_flag )
4948 : {
4949 : /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
4950 4095 : IF( GT_16( hFdCngCom->likelihood_noisy_speech, DELTA_MASKING_NOISE_Q15 ) )
4951 : {
4952 : /* Compute additional CN level */
4953 21523 : FOR( i = 0; i < 15; i++ )
4954 : {
4955 21523 : test();
4956 21523 : test();
4957 25956 : if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) &&
4958 8866 : GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) &&
4959 4433 : LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) )
4960 : {
4961 1709 : BREAK;
4962 : }
4963 : }
4964 :
4965 1709 : scale = L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ); /* Q30 */
4966 1709 : scale = Mpy_32_16_1( scale, hFdCngCom->likelihood_noisy_speech ); /* Q30 */
4967 : }
4968 : }
4969 :
4970 : /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/
4971 15697 : test();
4972 15697 : IF( cna_flag && tdBuffer != NULL )
4973 : {
4974 8190 : WHILE( n_samples_out > 0 )
4975 : {
4976 4095 : n_samples_out_loop = s_min( hFdCngCom->frameSize, n_samples_out );
4977 4095 : IF( scale != 0 )
4978 : {
4979 : /*Generate LF comfort noise only at first slot, for the whole frame*/
4980 1709 : ptr_level = cngNoiseLevel; /*hFdCngCom->cngNoiseLevelExp*/
4981 :
4982 : /* Generate Gaussian random noise in real and imaginary parts of the FFT bins
4983 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel_flt in each bin */
4984 1709 : IF( EQ_16( hFdCngCom->startBand, 0 ) )
4985 : {
4986 0 : rand_gauss_fx( &fftBuffer[0], seed, exp_out );
4987 0 : ptr_r = fftBuffer + 2; /*hFdCngCom->fftBuffer_exp*/
4988 :
4989 0 : Word16 exp2 = sub( 31, hFdCngCom->cngNoiseLevelExp );
4990 0 : Word32 sqr = Sqrt32( L_shr( Mpy_32_32( scale, *ptr_level ), 1 ), &exp2 ); /* DC component in FFT Q31 - exp2*/
4991 0 : sqr = L_shl( sqr, exp2 ); /*Q31*/
4992 0 : fftBuffer[0] = Mpy_32_32( fftBuffer[0], sqr ); /* DC component in FFT Q31 - hFdCngCom->fftBuffer_exp*/
4993 0 : move32();
4994 0 : ptr_level++;
4995 : }
4996 : ELSE
4997 : {
4998 1709 : fftBuffer[0] = 0;
4999 1709 : move32();
5000 1709 : set32_fx( fftBuffer + 2, 0, shl( sub( hFdCngCom->startBand, 1 ), 1 ) );
5001 1709 : ptr_r = fftBuffer + shl( hFdCngCom->startBand, 1 ); /*hFdCngCom->fftBuffer_exp*/
5002 : }
5003 1709 : ptr_i = ptr_r + 1; /*hFdCngCom->fftBuffer_exp*/
5004 :
5005 508691 : FOR( ; ptr_level < cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); ptr_level++ )
5006 : {
5007 506982 : rand_gauss_fx( ptr_r, seed, exp_out );
5008 506982 : Word16 exp2 = hFdCngCom->cngNoiseLevelExp;
5009 506982 : Word32 mpy2 = Sqrt32( Mpy_32_32( scale, *ptr_level ), &exp2 ); /*Q31 - exp2*/
5010 506982 : ( *ptr_r ) = L_shl( Mpy_32_32( *ptr_r, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/
5011 506982 : move32();
5012 506982 : ptr_r += 2;
5013 :
5014 : /* Imaginary part in FFT bins */
5015 506982 : rand_gauss_fx( ptr_i, seed, exp_out );
5016 506982 : ( *ptr_i ) = L_shl( Mpy_32_32( *ptr_i, mpy2 ), exp2 ); /*Q31 - hFdCngCom->fftBuffer_exp*/
5017 506982 : move32();
5018 506982 : ptr_i += 2;
5019 : }
5020 : /* Remaining FFT bins are set to zero */
5021 1709 : set32_fx( fftBuffer + shl( hFdCngCom->stopFFTbin, 1 ), 0, sub( hFdCngCom->fftlen, shl( hFdCngCom->stopFFTbin, 1 ) ) );
5022 : /* Nyquist frequency is discarded */
5023 1709 : fftBuffer[1] = 0;
5024 1709 : move32();
5025 :
5026 : /* Perform STFT synthesis */
5027 1709 : SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom );
5028 1709 : scale_sig32( tdBuffer + n_samples_start, n_samples_out_loop, Q9 ); // Q2 -> Q11
5029 : }
5030 :
5031 : ELSE
5032 : {
5033 : /* very low level case - update random seeds */
5034 2386 : generate_masking_noise_update_seed_fx( hFdCngCom );
5035 :
5036 2386 : set32_fx( fftBuffer, 0, hFdCngCom->fftlen );
5037 : /* Perform STFT synthesis */
5038 2386 : SynthesisSTFT_dirac_fx( fftBuffer, tdBuffer + n_samples_start, hFdCngCom->olapBufferSynth2_fx, hFdCngCom->olapWinSyn_fx, n_samples_out_loop, hFdCngCom );
5039 : }
5040 4095 : hFdCngCom->fftBuffer_exp = 31 - 11;
5041 4095 : move16();
5042 4095 : n_samples_out = sub( n_samples_out, hFdCngCom->frameSize );
5043 4095 : n_samples_start = add( n_samples_start, hFdCngCom->frameSize );
5044 : }
5045 : }
5046 :
5047 15697 : pop_wmops();
5048 :
5049 15697 : return;
5050 : }
5051 467712 : void generate_masking_noise_dirac_ivas_fx(
5052 : HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
5053 : HANDLE_CLDFB_FILTER_BANK h_cldfb, /* i : filterbank state */
5054 : Word32 *tdBuffer_fx, /* i/o: time-domain signal, if NULL no LB-CNA q_input*/
5055 : Word32 *Cldfb_RealBuffer_fx, /* o : CLDFD real buffer q_cldfb*/
5056 : Word32 *Cldfb_ImagBuffer_fx, /* o : CLDFD imaginary buffer q_cldfb*/
5057 : const Word16 slot_index, /* i : CLDFB slot index Q0*/
5058 : const Word16 cna_flag, /* i : CNA flag for LB and HB Q0*/
5059 : const Word16 fd_cng_flag, /* i : FD-CNG flag for HB Q0*/
5060 : Word16 q_input,
5061 : Word16 *q_cldfb )
5062 : {
5063 : Word16 i;
5064 : Word32 *ptr_level_fx;
5065 467712 : Word16 *seed = &( hFdCngCom->seed );
5066 : Word32 scale_fx;
5067 : Word16 q_scale, q_shift, q_ptr_level;
5068 :
5069 467712 : push_wmops( "fd_cng_dirac" );
5070 :
5071 : /* Init */
5072 467712 : scale_fx = 0;
5073 467712 : move32();
5074 :
5075 : /* Resample CLDFB memories if necessary*/
5076 467712 : IF( NE_16( i_mult( h_cldfb->no_channels, h_cldfb->no_col ), hFdCngCom->frameSize ) )
5077 : {
5078 519 : resampleCldfb_ivas_fx( h_cldfb, hFdCngCom->frameSize * FRAMES_PER_SEC );
5079 : }
5080 :
5081 467712 : set32_fx( Cldfb_RealBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX );
5082 467712 : set32_fx( Cldfb_ImagBuffer_fx, 0, CLDFB_NO_CHANNELS_MAX );
5083 :
5084 : /*LB CLDFB - CNA from STFT*/
5085 467712 : IF( cna_flag != 0 )
5086 : {
5087 : /* skip noise generating if level is very low, to avoid problems with possibly running into denormals */
5088 113708 : IF( hFdCngCom->likelihood_noisy_speech > 0 )
5089 : {
5090 : /* Compute additional CN level */
5091 599604 : FOR( i = 0; i < 15; i++ )
5092 : {
5093 599604 : test();
5094 599604 : test();
5095 724368 : if ( ( EQ_16( hFdCngCom->CngBandwidth, scaleTable_cn_dirac[i].bwmode ) ) &&
5096 249528 : ( GE_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateFrom ) ) &&
5097 124764 : ( LT_32( hFdCngCom->CngBitrate, scaleTable_cn_dirac[i].bitrateTo ) ) )
5098 : {
5099 47484 : BREAK;
5100 : }
5101 : }
5102 :
5103 47484 : scale_fx = L_shr( L_deposit_h( scaleTable_cn_dirac[i].scale_ivas ), Q3 ); /* Q27 */
5104 47484 : scale_fx = Mpy_32_16_1( scale_fx, hFdCngCom->likelihood_noisy_speech );
5105 : }
5106 : }
5107 : /* LB CLDFB - CNA from STFT: CNA applied only in channel 0*/
5108 467712 : IF( cna_flag && tdBuffer_fx != NULL )
5109 : {
5110 65496 : *q_cldfb = q_input;
5111 65496 : move16();
5112 65496 : IF( scale_fx != 0 )
5113 : {
5114 : /* LF CLDFB*/
5115 27320 : cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb );
5116 : }
5117 : ELSE
5118 : {
5119 : /* LB ana CLDFB*/
5120 38176 : cldfbAnalysis_ts_fx_fixed_q( &( tdBuffer_fx[( hFdCngCom->numCoreBands * slot_index )] ), Cldfb_RealBuffer_fx, Cldfb_ImagBuffer_fx, hFdCngCom->numCoreBands, h_cldfb, q_cldfb );
5121 : }
5122 : }
5123 :
5124 : /*HF CLDFB - CNA and/or FD-CNG*/
5125 467712 : if ( fd_cng_flag )
5126 : {
5127 9696 : scale_fx = L_add( scale_fx, ONE_IN_Q27 ); // 1 in Q27
5128 : }
5129 467712 : IF( scale_fx != 0 )
5130 : {
5131 50524 : q_scale = 27;
5132 50524 : move16();
5133 50524 : q_shift = norm_l( scale_fx );
5134 50524 : scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/
5135 50524 : q_scale = add( q_scale, q_shift );
5136 50524 : scale_fx = Mpy_32_32( scale_fx, Mpy_32_16_1( L_mult( h_cldfb->scale, h_cldfb->scale ), CLDFB_SCALING ) ); // Q = q_scale + 2 * Q8 - 34
5137 50524 : q_scale = sub( add( q_scale, 2 * Q8 ), 31 + 3 );
5138 50524 : ptr_level_fx = hFdCngCom->cngNoiseLevel + sub( hFdCngCom->stopFFTbin, hFdCngCom->startBand ); /*Q31 - hFdCngCom->cngNoiseLevelExp*/
5139 50524 : q_ptr_level = sub( 31, hFdCngCom->cngNoiseLevelExp );
5140 :
5141 1046448 : FOR( i = hFdCngCom->numCoreBands; i < hFdCngCom->regularStopBand; i++ )
5142 : {
5143 : Word32 num;
5144 : Word16 exp, q_num;
5145 995924 : q_shift = norm_l( scale_fx );
5146 995924 : scale_fx = L_shl( scale_fx, q_shift ); /*q_scale+q_shift*/
5147 995924 : q_scale = add( q_scale, q_shift );
5148 995924 : num = Mpy_32_32( scale_fx, *ptr_level_fx ); /*q_num*/
5149 995924 : q_num = sub( add( q_scale, q_ptr_level ), 31 - 1 ); // num = ( scale * *ptr_level ) * 0.5f
5150 995924 : exp = sub( 31, q_num );
5151 995924 : num = Sqrt32( num, &exp ); /*Q31 - exp*/
5152 : /* Real part in CLDFB band */
5153 995924 : rand_gauss_fx( &Cldfb_RealBuffer_fx[i], seed, *q_cldfb );
5154 995924 : Cldfb_RealBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_RealBuffer_fx[i], num ), exp );
5155 995924 : move32();
5156 : /* Imaginary part in CLDFB band */
5157 995924 : rand_gauss_fx( &Cldfb_ImagBuffer_fx[i], seed, *q_cldfb );
5158 995924 : Cldfb_ImagBuffer_fx[i] = L_shl( Mpy_32_32( Cldfb_ImagBuffer_fx[i], num ), exp );
5159 995924 : move32();
5160 :
5161 995924 : ptr_level_fx++;
5162 : }
5163 : }
5164 :
5165 467712 : pop_wmops();
5166 :
5167 467712 : return;
5168 : }
5169 :
5170 :
5171 : /*-------------------------------------------------------------------
5172 : * FdCngDecodeMDCTStereoSID()
5173 : *
5174 : * Decode FD-Cng parameters for CNG in MDCT-Stereo mode from the bitstream
5175 : *
5176 : *-------------------------------------------------------------------*/
5177 :
5178 410 : void FdCngDecodeMDCTStereoSID_fx(
5179 : CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */
5180 : )
5181 : {
5182 : DEC_CORE_HANDLE sts[CPE_CHANNELS];
5183 : HANDLE_FD_CNG_COM hFdCngCom;
5184 : Word32 *ms_ptr_fx[CPE_CHANNELS];
5185 : Word32 *lr_ptr_fx[CPE_CHANNELS];
5186 : Word32 logNoiseEst_fx[CPE_CHANNELS][NPART];
5187 : Word32 gain_fx[CPE_CHANNELS];
5188 : Word16 indices[FD_CNG_stages_37bits];
5189 : Word16 N, i, ch, p, stages;
5190 : Word16 is_out_ms;
5191 : Word32 *invTrfMatrix_fx;
5192 : Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
5193 : Word16 shift, exp_diff, max_exp_idx;
5194 : Word16 exp_arr[NPART];
5195 : Word32 tmp32, tmp32_arr[NPART];
5196 :
5197 410 : invTrfMatrix_fx = (Word32 *) tmpRAM_fx;
5198 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
5199 :
5200 410 : is_out_ms = 0;
5201 410 : move16();
5202 410 : if ( hCPE->hCoreCoder[0]->cng_sba_flag )
5203 : {
5204 0 : is_out_ms = 1;
5205 0 : move16();
5206 : }
5207 :
5208 410 : N = 0; /* to avoid compilation warning */
5209 410 : move16();
5210 :
5211 1230 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
5212 : {
5213 820 : sts[ch] = hCPE->hCoreCoder[ch];
5214 820 : ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/
5215 820 : lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q18*/
5216 : }
5217 :
5218 : /* decode noise shapes and gains */
5219 1230 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
5220 : {
5221 820 : sts[ch] = hCPE->hCoreCoder[ch];
5222 820 : hFdCngCom = ( sts[ch]->hFdCngDec )->hFdCngCom;
5223 820 : N = hFdCngCom->npart;
5224 820 : move16();
5225 820 : hFdCngCom->sid_frame_counter = add( hFdCngCom->sid_frame_counter, 1 ); /*Q0*/
5226 820 : move16();
5227 :
5228 820 : IF( ch )
5229 : {
5230 410 : stages = FD_CNG_JOINT_stages_25bits;
5231 410 : move16();
5232 : }
5233 : ELSE
5234 : {
5235 410 : stages = FD_CNG_stages_37bits;
5236 410 : move16();
5237 : }
5238 :
5239 : /* read bitstream */
5240 4920 : FOR( i = 0; i < stages; i++ )
5241 : {
5242 4100 : indices[i] = get_next_indice_fx( sts[ch], bits_37bits[i] ); /*Q0*/
5243 4100 : move16();
5244 : }
5245 : {
5246 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
5247 820 : move32();
5248 : }
5249 :
5250 : /* MSVQ decoder */
5251 820 : shift = find_guarded_bits_fx( N );
5252 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
5253 :
5254 820 : Scale_sig32( ms_ptr_fx[ch], N, shift ); // Q20
5255 : }
5256 :
5257 410 : dtx_read_padding_bits_fx( sts[1], mult( sub( IVAS_SID_5k2, 4400 ), ONE_BY_FRAMES_PER_SEC_Q15 ) );
5258 :
5259 410 : IF( sts[0]->hFdCngDec->hFdCngCom->no_side_flag )
5260 : {
5261 12 : set32_fx( ms_ptr_fx[1], 0, NPART );
5262 : }
5263 :
5264 410 : IF( EQ_16( is_out_ms, 0 ) )
5265 : {
5266 410 : inverseMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 );
5267 : }
5268 :
5269 1230 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
5270 : {
5271 820 : max_exp_idx = 0;
5272 820 : move16();
5273 820 : hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom;
5274 19504 : FOR( p = 0; p < N; p++ )
5275 : {
5276 18684 : tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20
5277 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]*/
5278 18684 : move32();
5279 18684 : if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) )
5280 : {
5281 74 : max_exp_idx = p; /*Q0*/
5282 74 : move16();
5283 : }
5284 : }
5285 :
5286 : // Bringing in same exponent
5287 19504 : FOR( p = 0; p < N; p++ )
5288 : {
5289 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]*/
5290 18684 : move32();
5291 : }
5292 :
5293 820 : hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx];
5294 820 : move16();
5295 :
5296 820 : scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 );
5297 :
5298 820 : hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp;
5299 820 : move16();
5300 :
5301 820 : lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac );
5302 : }
5303 :
5304 410 : test();
5305 410 : IF( EQ_16( hCPE->nchan_out, 1 ) && LE_32( hCPE->last_element_brate, IVAS_SID_5k2 ) )
5306 : {
5307 : /* create proper M noise shape in channel zero after gains have been applied */
5308 120 : exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp );
5309 120 : move16();
5310 2883 : FOR( p = 0; p < N; p++ )
5311 : {
5312 2763 : IF( GT_16( exp_diff, 0 ) )
5313 : {
5314 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*/
5315 159 : move32();
5316 : }
5317 : ELSE
5318 : {
5319 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*/
5320 2604 : move32();
5321 : }
5322 : }
5323 120 : IF( LT_16( exp_diff, 0 ) )
5324 : {
5325 44 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) );
5326 44 : move16();
5327 : }
5328 : }
5329 :
5330 410 : return;
5331 : }
5332 :
5333 :
5334 : /*-------------------------------------------------------------------
5335 : * FdCngDecodeDiracMDCTStereoSID_fx()
5336 : *
5337 : * Decode FD-CNG parameters for CNG in 2TC DirAC mode from the bitstream
5338 : *-------------------------------------------------------------------*/
5339 :
5340 167 : void FdCngDecodeDiracMDCTStereoSID_fx(
5341 : CPE_DEC_HANDLE hCPE /* i/o: CPE decoder state structure */
5342 : )
5343 : {
5344 : DEC_CORE_HANDLE sts[CPE_CHANNELS];
5345 : HANDLE_FD_CNG_COM hFdCngCom;
5346 : Word32 *ms_ptr_fx[CPE_CHANNELS];
5347 : Word32 *lr_ptr_fx[CPE_CHANNELS];
5348 : Word32 logNoiseEst_fx[CPE_CHANNELS][NPART];
5349 : Word32 gain_fx[CPE_CHANNELS];
5350 : Word16 indices[FD_CNG_stages_37bits];
5351 : Word16 N, i, ch, p;
5352 : Word32 *invTrfMatrix_fx;
5353 : Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
5354 : Word16 shift, exp_diff, max_exp_idx;
5355 : Word16 exp_arr[NPART];
5356 : Word32 tmp32, tmp32_arr[NPART];
5357 :
5358 167 : invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */
5359 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
5360 :
5361 501 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
5362 : {
5363 334 : sts[ch] = hCPE->hCoreCoder[ch];
5364 334 : ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0]; /*Q20*/
5365 334 : lr_ptr_fx[ch] = &sts[ch]->hFdCngDec->hFdCngCom->sidNoiseEst[0]; /*Q20*/
5366 334 : ( sts[ch]->hFdCngDec )->hFdCngCom->sid_frame_counter++; /*Q18*/
5367 : }
5368 :
5369 : /* decode noise shapes and gains */
5370 167 : hFdCngCom = ( sts[0]->hFdCngDec )->hFdCngCom;
5371 167 : N = hFdCngCom->npart; /*Q0*/
5372 167 : move16();
5373 :
5374 : /* read bitstream */
5375 1169 : FOR( i = 0; i < FD_CNG_stages_37bits; i++ )
5376 : {
5377 1002 : indices[i] = get_next_indice_fx( sts[0], bits_37bits[i] ); /*Q0*/
5378 1002 : move16();
5379 : }
5380 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
5381 167 : move32();
5382 :
5383 167 : gain_fx[1] = gain_fx[0]; /*Q20*/
5384 167 : move32();
5385 :
5386 : /* MSVQ decoder */
5387 167 : shift = find_guarded_bits_fx( N );
5388 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
5389 :
5390 167 : Scale_sig32( ms_ptr_fx[0], N, shift ); // Q20
5391 :
5392 167 : Copy32( ms_ptr_fx[0], ms_ptr_fx[1], N ); /*Q20*/
5393 :
5394 501 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
5395 : {
5396 334 : max_exp_idx = 0;
5397 334 : move16();
5398 334 : hFdCngCom = sts[ch]->hFdCngDec->hFdCngCom;
5399 :
5400 8350 : FOR( p = 0; p < N; p++ )
5401 : {
5402 8016 : tmp32 = L_add( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q20
5403 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]*/
5404 8016 : move32();
5405 8016 : if ( LT_16( exp_arr[max_exp_idx], exp_arr[p] ) )
5406 : {
5407 26 : max_exp_idx = p; /*Q0*/
5408 26 : move16();
5409 : }
5410 : }
5411 :
5412 : // Bringing in same exponent
5413 8350 : FOR( p = 0; p < N; p++ )
5414 : {
5415 8016 : lr_ptr_fx[ch][p] = L_shl( tmp32_arr[p], sub( exp_arr[p], exp_arr[max_exp_idx] ) ); /*Q20*/
5416 8016 : move32();
5417 : }
5418 :
5419 334 : hFdCngCom->sidNoiseEstExp = exp_arr[max_exp_idx]; /*Q0*/
5420 334 : move16();
5421 :
5422 : /* NB last band energy compensation */
5423 334 : test();
5424 334 : IF( hFdCngCom->CngBandwidth == NB )
5425 : {
5426 0 : lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], NB_LAST_BAND_SCALE_Q31 ); /*Q20*/
5427 0 : move32();
5428 : }
5429 334 : ELSE IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) )
5430 : {
5431 0 : lr_ptr_fx[ch][( N - 1 )] = Mpy_32_32( lr_ptr_fx[ch][( N - 1 )], SWB_13k2_LAST_BAND_SCALE_Q31 ); /*Q20*/
5432 0 : move32();
5433 : }
5434 :
5435 334 : scalebands( hFdCngCom->sidNoiseEst, hFdCngCom->part, hFdCngCom->npart, hFdCngCom->midband, hFdCngCom->nFFTpart, sub( hFdCngCom->stopBand, hFdCngCom->startBand ), hFdCngCom->cngNoiseLevel, 1 );
5436 :
5437 334 : hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp;
5438 334 : move16();
5439 :
5440 334 : lpc_from_spectrum( hFdCngCom, hFdCngCom->startBand, hFdCngCom->stopFFTbin, sts[ch]->preemph_fac );
5441 : }
5442 167 : sts[0]->hFdCngDec->hFdCngCom->coherence_fx = 0;
5443 167 : move16();
5444 167 : sts[1]->hFdCngDec->hFdCngCom->coherence_fx = 0;
5445 167 : move16();
5446 :
5447 167 : IF( EQ_16( hCPE->nchan_out, 1 ) )
5448 : {
5449 : /* create proper M noise shape in channel zero after gains have been applied */
5450 0 : exp_diff = sub( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, sts[1]->hFdCngDec->hFdCngCom->sidNoiseEstExp );
5451 0 : FOR( p = 0; p < N; p++ )
5452 : {
5453 0 : IF( exp_diff > 0 )
5454 : {
5455 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*/
5456 0 : move32();
5457 : }
5458 : ELSE
5459 : {
5460 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*/
5461 0 : move32();
5462 : }
5463 : }
5464 0 : IF( exp_diff < 0 )
5465 : {
5466 0 : sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp = add( sts[0]->hFdCngDec->hFdCngCom->sidNoiseEstExp, negate( exp_diff ) );
5467 0 : move16();
5468 : }
5469 : }
5470 :
5471 167 : return;
5472 : }
|