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