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 "stl.h"
8 : #include "options.h"
9 : #include "cnst.h"
10 : #include "stl.h"
11 : #include "rom_com_fx.h"
12 : #include "rom_com.h"
13 : #include "rom_enc.h"
14 : #include "prot_fx.h"
15 : #include "prot_fx_enc.h"
16 : #include "ivas_prot_fx.h"
17 : #include "basop_util.h"
18 : #include "rom_basop_util.h"
19 :
20 :
21 : /********************************
22 : * External functions *
23 : ********************************/
24 : #ifndef swap
25 : #define swap( x, y, type ) \
26 : { \
27 : type u__p; \
28 : u__p = x; \
29 : x = y; \
30 : y = u__p; \
31 : }
32 : #endif
33 : extern void BASOP_getTables( const PWord16 **ptwiddle, const PWord16 **sin_twiddle, Word16 *psin_step, Word16 length );
34 :
35 : /*************************************
36 : * Create an instance of type FD_CNG *
37 : *************************************/
38 480 : void createFdCngEnc_fx( HANDLE_FD_CNG_ENC *hFdCngEnc )
39 : {
40 : HANDLE_FD_CNG_ENC hs;
41 :
42 : /* Allocate memory */
43 480 : hs = (HANDLE_FD_CNG_ENC) calloc( 1, sizeof( FD_CNG_ENC ) );
44 480 : move16();
45 :
46 :
47 480 : createFdCngCom_fx( &( hs->hFdCngCom ) );
48 480 : *hFdCngEnc = hs;
49 480 : move16();
50 :
51 480 : return;
52 : }
53 :
54 480 : void initFdCngEnc_fx(
55 : HANDLE_FD_CNG_ENC hsEnc,
56 : Word32 input_Fs, /* Q0 */
57 : Word16 scale )
58 : {
59 : Word16 j;
60 480 : HANDLE_FD_CNG_COM hsCom = hsEnc->hFdCngCom;
61 :
62 : /* Initialize common */
63 480 : initFdCngCom( hsCom, scale );
64 :
65 : /* Configure the Noise Estimator */
66 :
67 480 : hsCom->numSlots = 16;
68 480 : move16();
69 480 : hsCom->numCoreBands = 16;
70 480 : move16();
71 480 : hsCom->regularStopBand = idiv1616U( extract_l( L_shr( input_Fs, 5 ) ), 25 ); /* Q0 */
72 480 : move16();
73 480 : if ( GT_16( hsCom->regularStopBand, 40 ) )
74 : {
75 351 : hsCom->regularStopBand = 40;
76 351 : move16();
77 : }
78 :
79 480 : hsCom->startBand = 2;
80 480 : move16();
81 480 : IF( EQ_16( hsCom->regularStopBand, 10 ) )
82 : {
83 0 : hsCom->stopFFTbin = 160;
84 0 : move16();
85 0 : hsCom->stopBand = 160;
86 0 : move16();
87 0 : hsCom->nFFTpart = 17;
88 0 : move16();
89 : }
90 : ELSE
91 : {
92 480 : hsCom->stopFFTbin = 256;
93 480 : move16();
94 480 : hsCom->stopBand = add( sub( hsCom->regularStopBand, hsCom->numCoreBands ), hsCom->stopFFTbin ); /* Q0 */
95 480 : move16();
96 480 : hsCom->nFFTpart = 20;
97 480 : move16();
98 : }
99 :
100 480 : initPartitions( sidparts_encoder_noise_est, SIZE_SIDPARTS_ENC_NOISE_EST, hsCom->startBand, hsCom->stopBand, hsCom->part, &hsCom->npart, hsCom->midband, hsCom->psize, hsCom->psize_norm, &hsCom->psize_norm_exp, hsCom->psize_inv, 0 );
101 :
102 480 : hsCom->nCLDFBpart = sub( hsCom->npart, hsCom->nFFTpart ); /* Q0 */
103 480 : move16();
104 2316 : FOR( j = 0; j < hsCom->nCLDFBpart; j++ )
105 : {
106 1836 : hsCom->CLDFBpart[j] = sub( hsCom->part[j + hsCom->nFFTpart], sub( 256, hsCom->startBand ) ); /* Q0 */
107 1836 : hsCom->CLDFBpsize_inv[j] = hsCom->psize_inv[j + hsCom->nFFTpart]; /* Q15 */
108 1836 : move16();
109 1836 : move16();
110 : }
111 :
112 : /* Initialize noise estimation algorithm */
113 480 : set32_fx( hsEnc->msPeriodog_fx, 0, NPART );
114 480 : hsEnc->msPeriodog_fx_exp_fft = 0;
115 480 : move16();
116 480 : hsEnc->msPeriodog_fx_exp_cldfb = 0;
117 480 : move16();
118 480 : hsEnc->msPeriodog_fx_exp = 31;
119 480 : move16();
120 480 : set32_fx( hsEnc->msAlpha_fx, 0, NPART );
121 480 : set32_fx( hsEnc->msBminWin_fx, 0, NPART );
122 480 : set32_fx( hsEnc->msBminSubWin_fx, 0, NPART );
123 :
124 480 : set32_fx( hsEnc->msNoiseEst_fx, 0, NPART );
125 480 : hsEnc->msNoiseEst_fx_exp = 0;
126 480 : move16();
127 480 : set32_fx( hsEnc->energy_ho_fx, 0, NPART );
128 480 : set32_fx( hsEnc->msNoiseEst_old_fx, 0, NPART );
129 480 : hsEnc->msNoiseEst_old_fx_exp = 0;
130 480 : move16();
131 480 : set16_fx( hsEnc->msLogPeriodog_fx, 0, NPART );
132 480 : set16_fx( hsEnc->msLogNoiseEst_fx, 0, NPART );
133 480 : set16_fx( hsEnc->msPsd_fx, 0, NPART );
134 480 : set16_fx( hsEnc->msNoiseFloor_fx, 0, NPART );
135 480 : set32_fx( hsEnc->msMinBuf_fx, 2147483647l /*1.0 Q31*/, MSNUMSUBFR * NPART );
136 480 : set32_fx( hsEnc->msCurrentMin_fx, 2147483647l /*1.0 Q31*/, NPART );
137 480 : set32_fx( hsEnc->msCurrentMinOut_fx, 2147483647l /*1.0 Q31*/, NPART );
138 480 : set32_fx( hsEnc->msCurrentMinSubWindow_fx, 2147483647l /*1.0 Q31*/, NPART );
139 480 : set16_fx( hsEnc->msPsdFirstMoment_fx, 0, NPART );
140 480 : set16_fx( hsEnc->msPeriodogBuf_fx, 0, MSBUFLEN * NPART );
141 :
142 480 : set16_fx( hsEnc->msLocalMinFlag, 0, NPART );
143 480 : set16_fx( hsEnc->msNewMinFlag, 0, NPART );
144 480 : hsEnc->msPeriodogBufPtr = 0;
145 480 : move16();
146 480 : set32_fx( hsEnc->msPsdSecondMoment_fx, 0, NPART );
147 480 : set32_fx( hsEnc->mem_coherence_fx, EPSILON_FX, 4 );
148 480 : set16_fx( hsEnc->mem_coherence_exp, 0, 4 );
149 :
150 480 : return;
151 : }
152 :
153 : /************************************
154 : * Configure FD_CNG *
155 : ************************************/
156 3 : void configureFdCngEnc_fx( HANDLE_FD_CNG_ENC hsEnc, /* i/o: Contains the variables related to the FD-based CNG process */
157 : Word16 bandwidth, /* i: bandwidth Q0*/
158 : Word32 bitrate /* Q0 */
159 : )
160 : {
161 3 : HANDLE_FD_CNG_COM hsCom = hsEnc->hFdCngCom;
162 : Word16 psizeDec[NPART];
163 : Word16 psizeDec_norm[NPART];
164 : Word16 psizeDec_norm_exp;
165 : Word16 psize_invDec[NPART];
166 :
167 3 : set16_fx( psizeDec, 0, NPART );
168 :
169 3 : hsCom->CngBandwidth = bandwidth;
170 3 : move16();
171 3 : IF( EQ_16( hsCom->CngBandwidth, FB ) )
172 : {
173 0 : hsCom->CngBandwidth = SWB;
174 0 : move16();
175 : }
176 3 : hsCom->CngBitrate = bitrate; /* Q0 */
177 3 : move32();
178 :
179 : /* NB configuration */
180 3 : IF( EQ_16( bandwidth, NB ) )
181 : {
182 0 : hsCom->FdCngSetup = FdCngSetup_nb; /* PTR assignation -> no move needed*/
183 : }
184 :
185 : /* WB configuration */
186 3 : ELSE IF( EQ_16( bandwidth, WB ) )
187 : {
188 : /* FFT 6.4kHz, no CLDFB */
189 0 : IF( LE_32( bitrate, ACELP_8k00 ) )
190 : {
191 0 : hsCom->FdCngSetup = FdCngSetup_wb1;
192 : }
193 : /* FFT 6.4kHz, CLDFB 8.0kHz */
194 0 : ELSE IF( LE_32( bitrate, ACELP_13k20 ) )
195 : {
196 0 : hsCom->FdCngSetup = FdCngSetup_wb2;
197 : }
198 : /* FFT 8.0kHz, no CLDFB */
199 : ELSE
200 : {
201 0 : hsCom->FdCngSetup = FdCngSetup_wb3;
202 : }
203 : }
204 :
205 : /* SWB/FB configuration */
206 : ELSE
207 : {
208 : /* FFT 6.4kHz, CLDFB 14kHz */
209 3 : IF( LE_32( bitrate, ACELP_13k20 ) )
210 : {
211 1 : hsCom->FdCngSetup = FdCngSetup_swb1;
212 : }
213 : /* FFT 8.0kHz, CLDFB 16kHz */
214 : ELSE
215 : {
216 2 : hsCom->FdCngSetup = FdCngSetup_swb2;
217 : }
218 : }
219 3 : hsCom->fftlen = hsCom->FdCngSetup.fftlen; /* Q0 */
220 3 : move16();
221 3 : hsEnc->stopFFTbinDec = hsCom->FdCngSetup.stopFFTbin; /* Q0 */
222 3 : move16();
223 :
224 : /* Configure the SID quantizer and the Confort Noise Generator */
225 :
226 3 : hsEnc->startBandDec = hsCom->startBand; /* Q0 */
227 3 : move16();
228 3 : hsEnc->stopBandDec = add( hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1], 1 ); /* Q0 */
229 3 : move16();
230 3 : initPartitions( hsCom->FdCngSetup.sidPartitions,
231 3 : hsCom->FdCngSetup.numPartitions,
232 3 : hsEnc->startBandDec,
233 3 : hsEnc->stopBandDec,
234 3 : hsEnc->partDec,
235 : &hsEnc->npartDec,
236 3 : hsEnc->midbandDec,
237 : psizeDec,
238 : psizeDec_norm,
239 : &psizeDec_norm_exp,
240 : psize_invDec,
241 : 0 );
242 3 : IF( EQ_16( hsEnc->stopFFTbinDec, 160 ) )
243 : {
244 0 : hsEnc->nFFTpartDec = 17;
245 0 : move16();
246 : }
247 3 : ELSE IF( EQ_16( hsEnc->stopFFTbinDec, 256 ) )
248 : {
249 1 : hsEnc->nFFTpartDec = 20;
250 1 : move16();
251 : }
252 : ELSE
253 : {
254 2 : hsEnc->nFFTpartDec = 21;
255 2 : move16();
256 : }
257 :
258 3 : SWITCH( hsCom->fftlen )
259 : {
260 1 : case 512:
261 1 : hsCom->fftlenShift = 8;
262 1 : move16();
263 1 : hsCom->fftlenFac = 32767 /*1.0 Q15*/;
264 1 : move16();
265 1 : BREAK;
266 2 : case 640:
267 2 : hsCom->fftlenShift = 9;
268 2 : move16();
269 2 : hsCom->fftlenFac = 20480 /*0.625 Q15*/;
270 2 : move16();
271 2 : BREAK;
272 0 : default:
273 0 : assert( !"Unsupported FFT length for FD-based CNG" );
274 : BREAK;
275 : }
276 3 : BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) );
277 3 : BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) );
278 3 : hsCom->frameSize = shr( hsCom->fftlen, 1 );
279 3 : move16();
280 3 : }
281 :
282 35556 : void configureFdCngEnc_ivas_fx(
283 : HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: Contains the variables related to the FD-based CNG process */
284 : const Word16 bwidth, /* Q0 */
285 : const Word32 total_brate /* Q0 */
286 : )
287 : {
288 35556 : HANDLE_FD_CNG_COM hsCom = hFdCngEnc->hFdCngCom;
289 : Word16 psizeDec[NPART];
290 : Word16 psizeDec_norm[NPART];
291 : Word16 psizeDec_norm_exp;
292 : Word16 psize_invDec[NPART];
293 :
294 35556 : set16_fx( psizeDec, 0, NPART );
295 :
296 35556 : hsCom->CngBandwidth = bwidth; /* Q0 */
297 35556 : move16();
298 35556 : IF( EQ_16( hsCom->CngBandwidth, FB ) )
299 : {
300 25861 : hsCom->CngBandwidth = SWB;
301 25861 : move16();
302 : }
303 35556 : hsCom->CngBitrate = total_brate; /* Q0 */
304 35556 : move32();
305 :
306 : /* NB configuration */
307 35556 : IF( EQ_16( bwidth, NB ) )
308 : {
309 0 : hsCom->FdCngSetup = FdCngSetup_nb; /* PTR assignation -> no move needed*/
310 : }
311 :
312 : /* WB configuration */
313 35556 : ELSE IF( EQ_16( bwidth, WB ) )
314 : {
315 : /* FFT 6.4kHz, no CLDFB */
316 3960 : IF( LE_32( total_brate, ACELP_8k00 ) )
317 : {
318 0 : hsCom->FdCngSetup = FdCngSetup_wb1;
319 : }
320 : /* FFT 6.4kHz, CLDFB 8.0kHz */
321 3960 : ELSE IF( LE_32( total_brate, ACELP_13k20 ) )
322 : {
323 1467 : hsCom->FdCngSetup = FdCngSetup_wb2;
324 : }
325 : /* FFT 8.0kHz, no CLDFB */
326 : ELSE
327 : {
328 2493 : hsCom->FdCngSetup = FdCngSetup_wb3;
329 : }
330 : }
331 :
332 : /* SWB/FB configuration */
333 : ELSE
334 : {
335 : /* FFT 6.4kHz, CLDFB 14kHz */
336 31596 : IF( LE_32( total_brate, ACELP_13k20 ) )
337 : {
338 17041 : hsCom->FdCngSetup = FdCngSetup_swb1;
339 : }
340 : /* FFT 8.0kHz, CLDFB 16kHz */
341 : ELSE
342 : {
343 14555 : hsCom->FdCngSetup = FdCngSetup_swb2;
344 : }
345 : }
346 35556 : hsCom->fftlen = hsCom->FdCngSetup.fftlen; /* Q0 */
347 35556 : move16();
348 35556 : hFdCngEnc->stopFFTbinDec = hsCom->FdCngSetup.stopFFTbin; /* Q0 */
349 35556 : move16();
350 :
351 : /* Configure the SID quantizer and the Confort Noise Generator */
352 :
353 35556 : hFdCngEnc->startBandDec = hsCom->startBand; /* Q0 */
354 35556 : move16();
355 35556 : hFdCngEnc->stopBandDec = add( hsCom->FdCngSetup.sidPartitions[hsCom->FdCngSetup.numPartitions - 1], 1 ); /* Q0 */
356 35556 : move16();
357 35556 : initPartitions( hsCom->FdCngSetup.sidPartitions,
358 35556 : hsCom->FdCngSetup.numPartitions,
359 35556 : hFdCngEnc->startBandDec,
360 35556 : hFdCngEnc->stopBandDec,
361 35556 : hFdCngEnc->partDec,
362 : &hFdCngEnc->npartDec,
363 35556 : hFdCngEnc->midbandDec,
364 : psizeDec,
365 : psizeDec_norm,
366 : &psizeDec_norm_exp,
367 : psize_invDec,
368 : 0 );
369 35556 : IF( EQ_16( hFdCngEnc->stopFFTbinDec, 160 ) )
370 : {
371 0 : hFdCngEnc->nFFTpartDec = 17;
372 0 : move16();
373 : }
374 35556 : ELSE IF( EQ_16( hFdCngEnc->stopFFTbinDec, 256 ) )
375 : {
376 18508 : hFdCngEnc->nFFTpartDec = 20;
377 18508 : move16();
378 : }
379 : ELSE
380 : {
381 17048 : hFdCngEnc->nFFTpartDec = 21;
382 17048 : move16();
383 : }
384 :
385 35556 : SWITCH( hsCom->fftlen )
386 : {
387 18508 : case 512:
388 18508 : hsCom->fftSineTab_fx = NULL;
389 18508 : hsCom->olapWinAna_fx = olapWinAna512_fx; /* Q30 */
390 18508 : hsCom->olapWinSyn_fx = olapWinSyn256_fx; /* Q15 */
391 18508 : hsCom->fftlenShift = 8;
392 18508 : move16();
393 18508 : hsCom->fftlenFac = 32767 /*1.0 Q15*/;
394 18508 : move16();
395 18508 : BREAK;
396 17048 : case 640:
397 17048 : hsCom->fftSineTab_fx = fftSineTab640_fx; /* Q15 */
398 17048 : hsCom->olapWinAna_fx = olapWinAna640_fx; /* Q30 */
399 17048 : hsCom->olapWinSyn_fx = olapWinSyn320_fx; /* Q15 */
400 17048 : hsCom->fftlenShift = 9;
401 17048 : move16();
402 17048 : hsCom->fftlenFac = 20480 /*0.625 Q15*/;
403 17048 : move16();
404 17048 : BREAK;
405 0 : default:
406 0 : assert( !"Unsupported FFT length for FD-based CNG" );
407 : BREAK;
408 : }
409 35556 : BASOP_getTables( &hsCom->olapWinAna, NULL, NULL, shr( hsCom->fftlen, 1 ) );
410 35556 : BASOP_getTables( &hsCom->olapWinSyn, NULL, NULL, shr( hsCom->fftlen, 2 ) );
411 35556 : hsCom->frameSize = shr( hsCom->fftlen, 1 );
412 35556 : move16();
413 :
414 35556 : return;
415 : }
416 :
417 : /**************************************
418 : * Delete the instance of type FD_CNG *
419 : **************************************/
420 8313 : void deleteFdCngEnc_fx( HANDLE_FD_CNG_ENC *hFdCngEnc )
421 : {
422 :
423 : HANDLE_FD_CNG_ENC hsEnc;
424 8313 : hsEnc = *hFdCngEnc;
425 8313 : move16();
426 8313 : IF( hsEnc != NULL )
427 : {
428 480 : deleteFdCngCom_fx( &( hsEnc->hFdCngCom ) );
429 480 : free( hsEnc );
430 480 : *hFdCngEnc = NULL;
431 480 : move16();
432 : }
433 8313 : }
434 :
435 :
436 156230 : void resetFdCngEnc_fx(
437 : Encoder_State *st )
438 : {
439 : Word16 tmpTest;
440 : Word16 n;
441 : Word16 totalNoiseIncrease;
442 156230 : Word16 thresh = 5 * 256; /* 5.0 in Q8 */
443 156230 : NOISE_EST_HANDLE hNoiseEst = st->hNoiseEst;
444 :
445 : /* st->totalNoise_fx; Q8 Noise estimator - total noise energy */
446 :
447 : /* Detect fast increase of totalNoise */
448 156230 : totalNoiseIncrease = sub( hNoiseEst->totalNoise_fx, st->last_totalNoise_fx ); // Q8
449 156230 : st->last_totalNoise_fx = hNoiseEst->totalNoise_fx; // Q8
450 156230 : move16();
451 156230 : IF( totalNoiseIncrease > 0 )
452 : {
453 14312 : IF( EQ_16( st->totalNoise_increase_len, TOTALNOISE_HIST_SIZE ) )
454 : {
455 5936 : FOR( n = 0; n < TOTALNOISE_HIST_SIZE - 1; n++ )
456 : {
457 4452 : st->totalNoise_increase_hist_fx[n] = st->totalNoise_increase_hist_fx[n + 1]; // Q8
458 4452 : move16();
459 : }
460 1484 : st->totalNoise_increase_hist_fx[TOTALNOISE_HIST_SIZE - 1] = totalNoiseIncrease; // Q8
461 1484 : move16();
462 : }
463 : ELSE
464 : {
465 12828 : st->totalNoise_increase_hist_fx[st->totalNoise_increase_len] = totalNoiseIncrease; // Q8
466 12828 : move16();
467 12828 : st->totalNoise_increase_len = add( st->totalNoise_increase_len, 1 ); // Q0
468 : }
469 : }
470 : ELSE
471 : {
472 141918 : st->totalNoise_increase_len = 0;
473 141918 : move16();
474 : }
475 156230 : totalNoiseIncrease = 0;
476 156230 : move16();
477 180873 : FOR( n = 0; n < st->totalNoise_increase_len; n++ )
478 : {
479 24643 : totalNoiseIncrease = add( totalNoiseIncrease, st->totalNoise_increase_hist_fx[n] ); // Q8
480 : }
481 :
482 156230 : test();
483 156230 : test();
484 156230 : tmpTest = ( ( GT_16( totalNoiseIncrease, thresh ) ) && ( EQ_16( st->totalNoise_increase_len, TOTALNOISE_HIST_SIZE ) ) && ( GT_16( st->ini_frame, 150 ) ) );
485 :
486 156230 : test();
487 156230 : IF( tmpTest || ( GT_16( st->input_bwidth, st->last_input_bwidth ) ) || EQ_16( st->last_core, AMR_WB_CORE ) )
488 : {
489 351 : st->fd_cng_reset_flag = 1;
490 351 : move16();
491 351 : st->hFdCngEnc->hFdCngCom->msFrCnt_init_counter = 0;
492 351 : move16();
493 351 : st->hFdCngEnc->hFdCngCom->init_old = 32767;
494 351 : move16();
495 : }
496 155879 : ELSE IF( s_and( ( st->fd_cng_reset_flag > 0 ), (Word16) ( LT_16( st->fd_cng_reset_flag, 10 ) ) ) )
497 : {
498 3132 : st->fd_cng_reset_flag = add( st->fd_cng_reset_flag, 1 );
499 : }
500 : ELSE
501 : {
502 152747 : st->fd_cng_reset_flag = 0;
503 152747 : move16();
504 : }
505 156230 : }
506 :
507 : /*
508 : perform_noise_estimation_enc_fx
509 :
510 : Parameters:
511 :
512 : band_energies i: energy in critical bands without minimum noise floor MODE2_E_MIN
513 : band_energies_exp i: exponent for energy in critical bands without minimum noise floor MODE2_E_MIN
514 : cldfbBufferReal, i: real part of the CLDFB buffer
515 : cldfbBufferImag, i: imaginary part of the CLDFB buffer
516 : cldfbBufferExp, i: exponent for CLDFB buffer
517 : bitrate i: bitrate
518 : st i/o: FD_CNG structure containing all buffers and variables
519 :
520 : Function:
521 : Perform noise estimation
522 :
523 : Returns:
524 : void
525 : */
526 3100 : void perform_noise_estimation_enc_fx( Word32 *band_energies, /* i: energy in critical bands without minimum noise floor MODE2_E_MIN band_energies_exp*/
527 : Word16 band_energies_exp, /* i: exponent for energy in critical bands without minimum noise floor MODE2_E_MIN */
528 : Word32 *enerBuffer, /* enerBuffer_exp */
529 : Word16 enerBuffer_exp,
530 : HANDLE_FD_CNG_ENC st /* i/o: FD_CNG structure containing all buffers and variables */
531 : )
532 : {
533 : Word16 i, j, s, s1, s2;
534 : Word16 nFFTpart;
535 : Word16 nCLDFBpart;
536 : Word16 numBands;
537 : Word16 numCoreBands;
538 : Word16 regularStopBand;
539 : Word16 numSlots;
540 : Word32 tmp;
541 : Word32 *periodog;
542 : Word32 *ptr_per;
543 : Word32 *msPeriodog;
544 :
545 :
546 3100 : nFFTpart = st->hFdCngCom->nFFTpart;
547 3100 : move16();
548 3100 : nCLDFBpart = st->hFdCngCom->nCLDFBpart;
549 3100 : move16();
550 3100 : numCoreBands = st->hFdCngCom->numCoreBands;
551 3100 : move16();
552 3100 : regularStopBand = st->hFdCngCom->regularStopBand;
553 3100 : move16();
554 3100 : numSlots = st->hFdCngCom->numSlots;
555 3100 : move16();
556 3100 : periodog = st->hFdCngCom->periodog;
557 3100 : move16();
558 3100 : ptr_per = periodog;
559 3100 : move16();
560 3100 : msPeriodog = st->msPeriodog_fx;
561 3100 : move16();
562 :
563 3100 : assert( numSlots == 16 );
564 :
565 : /* preemphasis compensation and grouping of per bin energies into msPeriodog */
566 65100 : FOR( i = 0; i < nFFTpart; i++ )
567 : {
568 62000 : tmp = L_add( L_shr( band_energies[i], 1 ), L_shr( band_energies[i + NB_BANDS], 1 ) ); /* exp(band_energies_exp) */
569 62000 : msPeriodog[i] = Mpy_32_16_1( tmp, preemphCompensation_fx[i] ); /* exp(band_energies_exp + 4) */
570 62000 : move32();
571 : }
572 :
573 : /* exponent for fft part of msPeriodog */
574 3100 : st->msPeriodog_fx_exp_fft = add( band_energies_exp, PREEMPH_COMPENSATION_EXP );
575 3100 : move16();
576 :
577 3100 : numBands = sub( regularStopBand, numCoreBands ); /* Q0 */
578 :
579 3100 : IF( numBands > 0 )
580 : {
581 : /* Adjust to the desired time resolution by averaging the periodograms over the CLDFB time slots */
582 :
583 77500 : FOR( j = numCoreBands; j < regularStopBand; j++ )
584 : {
585 74400 : *ptr_per = Mpy_32_16_1( enerBuffer[j], st->hFdCngCom->scalingFactor ); /* exp(enerBuffer_exp) */
586 74400 : move32();
587 :
588 74400 : ptr_per++;
589 : }
590 :
591 : /* exponent for cldfb part of msPeriodog */
592 3100 : st->hFdCngCom->exp_cldfb_periodog = add( sub( enerBuffer_exp, 4 ), CLDFBscalingFactor_EXP );
593 :
594 : /* Adjust CLDFB filterbank to the desired frequency resolution by averaging over spectral partitions for SID transmission */
595 3100 : bandcombinepow(
596 : periodog,
597 3100 : st->hFdCngCom->exp_cldfb_periodog,
598 : numBands,
599 3100 : st->hFdCngCom->CLDFBpart,
600 3100 : st->hFdCngCom->nCLDFBpart,
601 3100 : st->hFdCngCom->CLDFBpsize_inv,
602 3100 : &msPeriodog[nFFTpart],
603 : &st->msPeriodog_fx_exp_cldfb );
604 :
605 : /* find common exponent for fft part and cldfb part of msperiodog */
606 3100 : s1 = getScaleFactor32( msPeriodog, nFFTpart );
607 3100 : s2 = getScaleFactor32( &msPeriodog[nFFTpart], nCLDFBpart );
608 :
609 3100 : s = s_max( sub( st->msPeriodog_fx_exp_fft, s1 ), sub( st->msPeriodog_fx_exp_cldfb, s2 ) );
610 3100 : s1 = sub( s, st->msPeriodog_fx_exp_fft );
611 3100 : s2 = sub( s, st->msPeriodog_fx_exp_cldfb );
612 :
613 3100 : st->msPeriodog_fx_exp_fft = s;
614 3100 : move16();
615 3100 : st->msPeriodog_fx_exp_cldfb = s;
616 3100 : move16();
617 :
618 65100 : FOR( i = 0; i < nFFTpart; i++ )
619 : {
620 62000 : msPeriodog[i] = L_shr( msPeriodog[i], s1 ); // st->msPeriodog_fx_exp_fft
621 62000 : move32();
622 : }
623 :
624 15500 : FOR( i = 0; i < nCLDFBpart; i++ )
625 : {
626 12400 : msPeriodog[nFFTpart + i] = L_shr( msPeriodog[nFFTpart + i], s_min( 31, s2 ) ); // st->msPeriodog_fx_exp_fft
627 12400 : move32();
628 : }
629 : }
630 :
631 : /* exponent for entire msPeriodog vector */
632 3100 : st->msPeriodog_fx_exp = st->msPeriodog_fx_exp_fft;
633 3100 : move16();
634 :
635 : /* Compress MS inputs */
636 3100 : compress_range( st->msPeriodog_fx, st->msPeriodog_fx_exp, st->msLogPeriodog_fx, st->hFdCngCom->npart );
637 :
638 : /* Call the minimum statistics routine for noise estimation */
639 3100 : minimum_statistics(
640 3100 : st->hFdCngCom->npart,
641 3100 : st->hFdCngCom->nFFTpart,
642 3100 : st->hFdCngCom->psize_norm,
643 3100 : st->msLogPeriodog_fx,
644 3100 : st->msNoiseFloor_fx,
645 3100 : st->msLogNoiseEst_fx,
646 3100 : st->msAlpha_fx,
647 3100 : st->msPsd_fx,
648 3100 : st->msPsdFirstMoment_fx,
649 3100 : st->msPsdSecondMoment_fx,
650 3100 : st->msMinBuf_fx,
651 3100 : st->msBminWin_fx,
652 3100 : st->msBminSubWin_fx,
653 3100 : st->msCurrentMin_fx,
654 3100 : st->msCurrentMinOut_fx,
655 3100 : st->msCurrentMinSubWindow_fx,
656 3100 : st->msLocalMinFlag,
657 3100 : st->msNewMinFlag,
658 3100 : st->msPeriodogBuf_fx,
659 : &( st->msPeriodogBufPtr ),
660 : st->hFdCngCom );
661 :
662 : /* Expand MS outputs */
663 3100 : expand_range( st->msLogNoiseEst_fx, st->msNoiseEst_fx, &st->msNoiseEst_fx_exp, st->hFdCngCom->npart );
664 3100 : }
665 :
666 : /*
667 : AdjustFirstSID_fx
668 :
669 : Parameters:
670 :
671 : npart i : number of parts
672 : msPeriodog i : pointer to periodog vector
673 : msPeriodog_exp i : exponent of periodog vector
674 : energy_ho i/o : pointer to energy
675 : energy_ho_exp i/o : pointer to exponent of energy
676 : msNoiseEst i/o : pointer to estimated noise
677 : msNoiseEst_exp i/o : pointer to exponent of estimated noise
678 : msNoiseEst_old i/o : pointer to old estimated noise
679 : msNoiseEst_old_exp i/o : pointer to exponent of old estimated noise
680 : active_frame_counter i/o : pointer to active frame counter
681 : stcod i : pointer to Coder_State structure
682 :
683 : Function:
684 : Adjust the noise estimator at the beginning of each CNG phase (encoder-side)
685 :
686 : Returns:
687 : void
688 : */
689 121162 : Word16 AdjustFirstSID_fx(
690 : Word16 npart, /* i : number of parts Q0*/
691 : Word32 *msPeriodog, /* i : pointer to periodog vector msPeriodog_exp */
692 : Word16 msPeriodog_exp, /* i : exponent of periodog vector */
693 : Word32 *energy_ho, /* i/o : pointer to energy energy_ho_exp*/
694 : Word16 *energy_ho_exp, /* i/o : pointer to exponent of energy */
695 : Word32 *msNoiseEst, /* i/o : pointer to estimated noise msNoiseEst_exp*/
696 : Word16 *msNoiseEst_exp, /* i/o : pointer to exponent of estimated noise */
697 : Word32 *msNoiseEst_old, /* i/o : pointer to old estimated noise msNoiseEst_old_exp*/
698 : Word16 *msNoiseEst_old_exp, /* i/o : pointer to exponent of old estimated noise */
699 : Word16 *active_frame_counter, /* i/o : pointer to active frame counter Q0*/
700 : Encoder_State *stcod /* i : pointer to Coder_State_Plus structure */
701 : )
702 : {
703 : Word16 i, sc, s1, s2, lambda, lambdaM1, invFac;
704 : Word32 tmp32, energy_ho_local, msNoiseEst_local;
705 121162 : DTX_ENC_HANDLE hDtxEnc = stcod->hDtxEnc;
706 :
707 121162 : test();
708 121162 : IF( EQ_16( hDtxEnc->cnt_SID, 1 ) && GT_32( stcod->last_core_brate, SID_2k40 ) )
709 : {
710 : /* Detect the hangover period and the first SID frame at the beginning of each CNG phase */
711 :
712 : /* First hangover frame */
713 2889 : Copy32( msPeriodog, energy_ho, npart ); /* exp(msPeriodog_exp) */
714 2889 : *energy_ho_exp = msPeriodog_exp;
715 2889 : move16();
716 :
717 : /* Set first SID to current input level but add some smoothing */
718 2889 : IF( GE_16( *active_frame_counter, 254 ) )
719 : {
720 5 : lambda = 0;
721 5 : move16();
722 5 : lambdaM1 = 0x7FFF;
723 5 : move16();
724 : }
725 : ELSE
726 : {
727 : /* -0.94229902485 = 1024.0*log10(0.96)/log10(2.0)/64.0 */
728 : /* active_frame_counter scaled by (1/1024.0) for compensation */
729 2884 : tmp32 = L_shl( L_deposit_l( add( *active_frame_counter, 1 ) ), WORD32_BITS - 1 - 10 );
730 2884 : tmp32 = BASOP_Util_InvLog2( Mpy_32_16_1( tmp32, -30877 /*-0.94229902485 Q15*/ ) );
731 2884 : lambda = extract_h( tmp32 ); /* Q15 */
732 2884 : lambdaM1 = extract_h( L_sub( 0x7FFFFFFF /* 1.0f in Q31*/, tmp32 ) );
733 : }
734 :
735 2889 : invFac = getNormReciprocalWord16( 1 );
736 :
737 : /* one bit headroom for addition */
738 2889 : sc = add( s_max( *msNoiseEst_old_exp, *energy_ho_exp ), 1 );
739 2889 : s1 = limitScale32( sub( sc, *msNoiseEst_old_exp ) );
740 2889 : s2 = limitScale32( sub( sc, *energy_ho_exp ) );
741 2889 : *energy_ho_exp = sc;
742 2889 : move16();
743 :
744 70566 : FOR( i = 0; i < npart; i++ )
745 : {
746 67677 : msNoiseEst_old[i] = Mpy_32_16_1( msNoiseEst_old[i], lambda ); /* exp(msNoiseEst_old) */
747 67677 : move32();
748 67677 : tmp32 = Mpy_32_16_1( Mpy_32_16_1( energy_ho[i], invFac ), lambdaM1 );
749 67677 : energy_ho[i] = L_add( L_shr( msNoiseEst_old[i], s1 ), L_shr( tmp32, s2 ) );
750 67677 : move32();
751 : }
752 :
753 2889 : sc = s_max( *msNoiseEst_exp, *energy_ho_exp );
754 2889 : s1 = limitScale32( sub( sc, *msNoiseEst_exp ) );
755 2889 : s2 = limitScale32( sub( sc, *energy_ho_exp ) );
756 2889 : *msNoiseEst_exp = sc;
757 2889 : move16();
758 :
759 2889 : tmp32 = 0;
760 2889 : move32();
761 70566 : FOR( i = 0; i < npart; i++ )
762 : {
763 67677 : msNoiseEst_local = L_shr( msNoiseEst[i], s1 ); /* exp(msNoiseEst + s1) */
764 67677 : energy_ho_local = L_shr( energy_ho[i], s2 ); /* exp(energy_ho_exp + s2) */
765 67677 : IF( GT_32( msNoiseEst_local, energy_ho_local ) )
766 : {
767 38025 : msNoiseEst[i] = energy_ho_local; /* exp(energy_ho_exp + s2) */
768 38025 : move32();
769 : }
770 : ELSE
771 : {
772 29652 : msNoiseEst[i] = msNoiseEst_local; /* exp(energy_ho_exp + s2) */
773 29652 : move32();
774 : }
775 67677 : if ( msNoiseEst[i] > 0 )
776 : {
777 63317 : tmp32 = 1;
778 63317 : move32();
779 : }
780 : }
781 : /* Set exponent to zero if msNoiseEst is zero */
782 2889 : if ( tmp32 == 0 )
783 : {
784 174 : *msNoiseEst_exp = 0;
785 174 : move16();
786 : }
787 :
788 2889 : *active_frame_counter = 0;
789 2889 : move16();
790 : }
791 121162 : test();
792 121162 : IF( NE_32( stcod->core_brate, SID_2k40 ) && NE_32( stcod->core_brate, FRAME_NO_DATA ) )
793 : {
794 : /* Count the number of active frames in a row */
795 90037 : *active_frame_counter = add( *active_frame_counter, 1 ); /* Q0 */
796 90037 : move16();
797 : }
798 : ELSE
799 : {
800 : /* Store the noise estimate obtained in the CNG phases */
801 31125 : Copy32( msNoiseEst, msNoiseEst_old, npart ); /* exp(msNoiseEst_exp) */
802 31125 : *msNoiseEst_old_exp = *msNoiseEst_exp;
803 31125 : move16();
804 : }
805 :
806 :
807 121162 : return 0;
808 : }
809 :
810 :
811 : /*
812 : msvq_encoder
813 :
814 : Parameters:
815 :
816 : cb i : Codebook (indexed cb[stages][levels][p]) format Q9.7
817 : u[] i : Vector to be encoded (prediction and mean removed) format Q9.7
818 : levels i : Number of levels in each stage
819 : maxC i : Tree search size
820 : stages i : Number of stages
821 : N i : Vector dimension
822 : maxN i : Codebook vector dimension
823 : Idx o : Indices
824 :
825 :
826 : Function:
827 : multi stage vector quantisation
828 :
829 : Returns:
830 : void
831 : */
832 0 : static void msvq_encoder( const Word16 *const cb[], /* i : Codebook (indexed cb[*stages][levels][p]) scaled with 8 bits Q9.7*/
833 : Word16 u[], /* i : Vector to be encoded (prediction and mean removed) Q9.7*/
834 : const Word16 levels[], /* i : Number of levels in each stage Q0*/
835 : Word16 maxC, /* i : Tree search size Q0*/
836 : Word16 stages, /* i : Number of stages Q0*/
837 : Word16 N, /* i : Vector dimension Q0*/
838 : Word16 maxN, /* i : Codebook vector dimension Q0*/
839 : Word16 Idx[] /* o : Indices Q0*/
840 : )
841 : {
842 : Word32 *dist[2];
843 : Word32 t1, en, ss2, tmp;
844 : const Word16 *cbp, *cb_stage, *p2;
845 : Word16 *p1, *pTmp;
846 : Word16 *indices[2], *resid[2], Tmp[M_MAX];
847 : Word16 i, j, m, s, c, c2, p_max;
848 : Word16 parents[MBEST_MAX];
849 : Word32 dist_buf[2 * MBEST_MAX];
850 : Word16 resid_buf[2 * MBEST_MAX * M_MAX];
851 : Word16 idx_buf[2 * MBEST_MAX * NSTAGES_MAX];
852 :
853 :
854 : /*----------------------------------------------------------------*
855 : * Allocate memory for previous (parent) and current nodes.
856 : * Parent node is indexed [0], current node is indexed [1].
857 : *----------------------------------------------------------------*/
858 :
859 0 : indices[0] = idx_buf;
860 0 : indices[1] = idx_buf + maxC * stages;
861 0 : set16_fx( idx_buf, 0, 2 * stages * maxC );
862 :
863 0 : resid[0] = resid_buf;
864 0 : resid[1] = resid_buf + maxC * N;
865 :
866 0 : dist[0] = dist_buf;
867 0 : dist[1] = dist_buf + maxC;
868 :
869 0 : set16_fx( parents, 0, maxC );
870 :
871 : /*----------------------------------------------------------------*
872 : * ISF weights are normalized, so it is always better to multiply it first
873 : * Set up inital distance vector
874 : *----------------------------------------------------------------*/
875 :
876 0 : ss2 = L_mult( u[0], u[0] );
877 0 : FOR( j = 1; j < N; j++ )
878 : {
879 0 : ss2 = L_mac( ss2, u[j], u[j] );
880 : }
881 :
882 0 : FOR( j = 0; j < maxC; j++ )
883 : {
884 0 : dist[1][j] = ss2;
885 0 : move32();
886 : }
887 :
888 : /* Set up inital error (residual) vectors */
889 0 : pTmp = resid[1];
890 0 : FOR( c = 0; c < maxC; c++ )
891 : {
892 0 : FOR( j = 0; j < N; j++ )
893 : {
894 0 : *pTmp++ = u[j];
895 0 : move16();
896 : }
897 : }
898 :
899 : /* Loop over all stages */
900 0 : m = 1;
901 0 : move16();
902 0 : FOR( s = 0; s < stages; s++ )
903 : {
904 0 : cbp = cb[s];
905 :
906 : /* Save pointer to beginning of current stage */
907 0 : cb_stage = cbp;
908 :
909 : /* Set up pointers to parent and current nodes */
910 0 : swap( indices[0], indices[1], Word16 * );
911 0 : swap( resid[0], resid[1], Word16 * );
912 0 : swap( dist[0], dist[1], Word32 * );
913 :
914 : /* p_max points to maximum distortion node (worst of best) */
915 0 : p_max = 0;
916 0 : move16();
917 :
918 : /* Set distortions to a large value */
919 0 : FOR( j = 0; j < maxC; j++ )
920 : {
921 0 : dist[1][j] = MAXVAL_WORD32;
922 0 : move32();
923 : }
924 :
925 0 : FOR( j = 0; j < levels[s]; j++ )
926 : {
927 : /* Compute weighted codebook element and its energy */
928 0 : Tmp[0] = cbp[0];
929 0 : move16();
930 0 : en = L_mult( cbp[0], cbp[0] );
931 0 : FOR( i = 1; i < N; i++ )
932 : {
933 0 : Tmp[i] = cbp[i];
934 0 : move16();
935 0 : en = L_mac( en, cbp[i], cbp[i] );
936 : }
937 :
938 0 : cbp += maxN;
939 :
940 : /* Iterate over all parent nodes */
941 0 : FOR( c = 0; c < m; c++ )
942 : {
943 0 : pTmp = &resid[0][c * N];
944 :
945 0 : t1 = L_mult( pTmp[0], Tmp[0] );
946 0 : FOR( i = 1; i < N; i++ )
947 : {
948 0 : t1 = L_mac( t1, pTmp[i], Tmp[i] );
949 : }
950 :
951 0 : tmp = L_add( dist[0][c], L_sub( en, L_shl( t1, 1 ) ) );
952 :
953 : BASOP_SATURATE_WARNING_OFF_EVS
954 0 : t1 = L_sub_sat( tmp, dist[1][p_max] );
955 : BASOP_SATURATE_WARNING_ON_EVS
956 0 : IF( t1 <= 0 )
957 : /* IF (L_sub(L_shr(tmp,1), L_shr(dist[1][p_max],1) ) <= 0 ) */
958 : {
959 : /* Replace worst */
960 0 : dist[1][p_max] = tmp;
961 0 : move32();
962 0 : indices[1][p_max * stages + s] = j;
963 0 : move16();
964 0 : parents[p_max] = c;
965 0 : move16();
966 :
967 0 : p_max = 0;
968 0 : move16();
969 :
970 0 : FOR( i = 1; i < maxC; i++ )
971 : {
972 0 : if ( GT_32( dist[1][i], dist[1][p_max] ) )
973 : {
974 0 : p_max = i;
975 0 : move16();
976 : }
977 : }
978 : }
979 : }
980 : } /* FOR (j=0; j<levels[s]; j++) */
981 :
982 : /*------------------------------------------------------------*
983 : * Compute error vectors for each node
984 : *------------------------------------------------------------*/
985 0 : pTmp = resid[1];
986 :
987 0 : FOR( c = 0; c < maxC; c++ )
988 : {
989 : /* Subtract codebook entry from residual vector of parent node and multiply with scale factor */
990 0 : p1 = resid[0] + parents[c] * N;
991 0 : p2 = cb_stage + ( indices[1][c * stages + s] ) * maxN;
992 :
993 0 : FOR( j = 0; j < N; j++ )
994 : {
995 0 : pTmp[j] = sub( p1[j], p2[j] );
996 0 : move16();
997 : }
998 0 : pTmp += N;
999 :
1000 : /* Get indices that were used for parent node */
1001 0 : Copy( indices[0] + parents[c] * stages, indices[1] + c * stages, s ); // Q0
1002 : }
1003 0 : m = maxC;
1004 0 : move16();
1005 : } /* FOR (s=0; s<stages; s++) */
1006 :
1007 : /* Find the optimum candidate (search for minimum) */
1008 0 : c2 = 0;
1009 0 : move16();
1010 0 : FOR( i = 1; i < maxC; i++ )
1011 : {
1012 0 : if ( LT_32( dist[1][i], dist[1][c2] ) )
1013 : {
1014 0 : c2 = i;
1015 0 : move16();
1016 : }
1017 : }
1018 :
1019 0 : Copy( indices[1] + c2 * stages, Idx, stages );
1020 0 : }
1021 :
1022 :
1023 : /*
1024 : FdCng_encodeSID_fx
1025 :
1026 : Parameters:
1027 :
1028 : stenc i/o: pointer to FD_CNG structure containing all buffers and variables
1029 : bitstream o : pointer to bitstream
1030 : total_nbbits o : pointer to total number of encoded bits
1031 : bitrate i : bitrate
1032 : amrwb_io i : amr wideband mode
1033 : preemph_fac i : preemphase factor
1034 :
1035 :
1036 : Function:
1037 : Generate a bitstream out of the partition levels
1038 :
1039 : Returns:
1040 : void
1041 : */
1042 0 : void FdCng_encodeSID_fx( HANDLE_FD_CNG_ENC stenc, /* i/o: pointer to FD_CNG structure containing all buffers and variables */
1043 : Encoder_State *corest,
1044 : Word16 preemph_fac /* i : preemphase factor */
1045 : )
1046 : {
1047 : Word16 i, index, N;
1048 : Word16 E_Exp, normFacN, normShiftN;
1049 : Word16 normFacGain, normShiftGain, sidNoiseEst_Exp;
1050 :
1051 : Word32 tmp, gain, e, maxVal;
1052 : Word32 *E, E_ExpLd64;
1053 : Word32 v[32];
1054 :
1055 : Word16 indices[32];
1056 : Word16 v16[32];
1057 0 : BSTR_ENC_HANDLE hBstr = corest->hBstr;
1058 : HANDLE_FD_CNG_COM st;
1059 0 : Word16 maxC_37bits = FD_CNG_maxC_37bits, stages_37bits = FD_CNG_stages_37bits, maxN_37bits = FD_CNG_maxN_37bits;
1060 :
1061 : /* Init */
1062 0 : st = stenc->hFdCngCom;
1063 :
1064 0 : E_Exp = stenc->msNoiseEst_fx_exp;
1065 0 : move16();
1066 0 : E_ExpLd64 = L_shl( E_Exp, WORD32_BITS - 1 - LD_DATA_SCALE );
1067 0 : E = stenc->msNoiseEst_fx;
1068 :
1069 0 : N = stenc->npartDec;
1070 0 : move16();
1071 :
1072 0 : normFacN = getNormReciprocalWord16( N );
1073 0 : normShiftN = BASOP_util_norm_s_bands2shift( N );
1074 :
1075 0 : normFacGain = getNormReciprocalWord16( N_GAIN_MAX - N_GAIN_MIN );
1076 0 : normShiftGain = BASOP_util_norm_s_bands2shift( N_GAIN_MAX - N_GAIN_MIN );
1077 :
1078 : /* Convert to LOG */
1079 :
1080 : /* e: Q14.23 format, v: Q9.23 format */
1081 0 : e = L_deposit_l( 0 );
1082 0 : tmp = Mpy_32_32_r( L_shl( 1, sub( 31, E_Exp ) ), 214748 ); /* 1e-4f, Q31-E_Exp */
1083 0 : FOR( i = 0; i < N; i++ )
1084 : {
1085 : /* assert( E[i] != 0 ); */
1086 : /* constant: 0.75257498916 = 10.0 * log10(2.0)/log10(10.0) * 0.25 */
1087 0 : v[i] = Mpy_32_16_1( L_add( BASOP_Util_Log2( L_add( E[i], L_max( 1, tmp ) ) ), E_ExpLd64 ), 24660 /*0.75257498916 Q15*/ );
1088 0 : move32();
1089 0 : e = L_add( e, L_shr( v[i], normShiftN ) );
1090 : }
1091 0 : e = L_shl( Mpy_32_16_1( e, shl( normFacN, sub( normShiftN, 1 ) ) ), 1 );
1092 :
1093 :
1094 : /* Normalize MSVQ input */
1095 :
1096 : /* gain: Q9.23 format */
1097 0 : gain = L_deposit_l( 0 );
1098 0 : FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ )
1099 : {
1100 0 : gain = L_add( gain, L_shr( v[i], normShiftGain ) );
1101 : }
1102 0 : gain = L_shl( Mpy_32_16_1( gain, shl( normFacGain, sub( normShiftGain, 1 ) ) ), 1 );
1103 :
1104 0 : FOR( i = 0; i < N; i++ )
1105 : {
1106 0 : v16[i] = extract_h( L_sub( v[i], gain ) );
1107 : }
1108 :
1109 : {
1110 : /* MSVQ encoder */
1111 0 : msvq_encoder( cdk_37bits, v16, levels_37bits, maxC_37bits, stages_37bits, N, maxN_37bits, indices );
1112 :
1113 : /* MSVQ decoder */
1114 0 : msvq_decoder( cdk_37bits, stages_37bits, N, maxN_37bits, indices, v16 );
1115 : }
1116 0 : FOR( i = 0; i < N; i++ )
1117 : {
1118 0 : v[i] = L_deposit_h( v16[i] );
1119 : }
1120 :
1121 :
1122 : /* Compute gain, Q9.23 format */
1123 0 : gain = 0;
1124 0 : FOR( i = 0; i < N; i++ )
1125 : {
1126 0 : gain = L_add( gain, L_shr( v[i], normShiftN ) );
1127 : }
1128 0 : gain = L_sub( e, L_shl( Mpy_32_16_1( gain, shl( normFacN, sub( normShiftN, 1 ) ) ), 1 ) );
1129 :
1130 :
1131 : /* Apply bitrate-dependant scale */
1132 : {
1133 0 : apply_scale( &gain, st->CngBandwidth, st->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO );
1134 : }
1135 :
1136 : /* Quantize gain, Q14.23 format */
1137 0 : gain = L_add( gain, L_shr( gain, 1 ) );
1138 0 : gain = L_add( gain, 507510784l /*60.5 Q23*/ );
1139 0 : index = extract_l( L_shr( gain, WORD32_BITS - 1 - 8 ) );
1140 :
1141 0 : if ( index < 0 )
1142 : {
1143 0 : index = 0;
1144 0 : move16();
1145 : }
1146 :
1147 0 : if ( GT_16( index, 127 ) )
1148 : {
1149 0 : index = 127;
1150 0 : move16();
1151 : }
1152 :
1153 : /* gain Q14.23 format */
1154 0 : gain = L_shl( L_deposit_l( index ), WORD32_BITS - 1 - 8 );
1155 0 : gain = L_sub( gain, 503316480l /*60.0 Q23*/ );
1156 0 : gain = Mpy_32_16_1( gain, 21845 /*2.0f/3.0f Q15*/ );
1157 :
1158 : /* Apply gain and undo log */
1159 :
1160 : /* sidNoiseEst: format Q6.26, 0.66438561897 = log10(10)/log10(2.0) / 10.0 * 2.0 */
1161 :
1162 : /* calculate worst case for scaling */
1163 0 : maxVal = 0x80000000 /*-1.0 Q31*/;
1164 0 : move32();
1165 0 : FOR( i = 0; i < N; i++ )
1166 : {
1167 0 : maxVal = L_max( maxVal, v[i] );
1168 : }
1169 :
1170 0 : maxVal = L_add( maxVal, gain );
1171 0 : maxVal = L_shl( Mpy_32_16_1( maxVal, 21771 /*0.66438561897 Q15*/ ), 1 );
1172 : // PMT("st must be replaced by hFdCngCom")
1173 0 : sidNoiseEst_Exp = 0;
1174 0 : move16();
1175 0 : WHILE( maxVal >= 0 )
1176 : {
1177 0 : maxVal = L_sub( maxVal, 33554432l /*0.015625 Q31*/ );
1178 0 : sidNoiseEst_Exp = add( sidNoiseEst_Exp, 1 );
1179 : }
1180 0 : st->sidNoiseEstExp = sidNoiseEst_Exp;
1181 0 : move16();
1182 0 : E_ExpLd64 = L_shl( sidNoiseEst_Exp, WORD32_BITS - 1 - LD_DATA_SCALE );
1183 :
1184 0 : FOR( i = 0; i < N; i++ )
1185 : {
1186 0 : tmp = L_add( v[i], gain );
1187 0 : tmp = L_shl( Mpy_32_16_1( tmp, 21771 /*0.66438561897 Q15*/ ), 1 );
1188 0 : tmp = L_sub( tmp, E_ExpLd64 );
1189 0 : assert( tmp < 0 );
1190 0 : st->sidNoiseEst[i] = BASOP_Util_InvLog2( tmp );
1191 0 : move32();
1192 : }
1193 :
1194 : /* NB last band energy compensation */
1195 0 : IF( EQ_16( st->CngBandwidth, NB ) )
1196 : {
1197 0 : st->sidNoiseEst[N - 1] = Mpy_32_16_1( st->sidNoiseEst[N - 1], NB_LAST_BAND_SCALE );
1198 0 : move32();
1199 : }
1200 :
1201 0 : test();
1202 0 : if ( EQ_16( st->CngBandwidth, SWB ) && LE_32( st->CngBitrate, ACELP_13k20 ) )
1203 : {
1204 0 : st->sidNoiseEst[N - 1] = Mpy_32_16_1( st->sidNoiseEst[N - 1], SWB_13k2_LAST_BAND_SCALE );
1205 0 : move32();
1206 : }
1207 :
1208 :
1209 : /* Write bitstream */
1210 0 : IF( EQ_16( corest->codec_mode, MODE2 ) )
1211 : {
1212 0 : FOR( i = 0; i < stages_37bits; i++ )
1213 : {
1214 0 : push_next_indice( hBstr, indices[i], bits_37bits[i] );
1215 : }
1216 0 : push_next_indice( hBstr, index, 7 );
1217 : }
1218 : ELSE
1219 : {
1220 0 : push_indice( hBstr, IND_SID_TYPE, 1, 1 );
1221 0 : push_indice( hBstr, IND_ACELP_16KHZ, corest->bwidth, 2 );
1222 0 : IF( EQ_16( corest->L_frame, L_FRAME16k ) )
1223 : {
1224 0 : push_indice( hBstr, IND_ACELP_16KHZ, 1, 1 );
1225 : }
1226 : ELSE
1227 : {
1228 0 : push_indice( hBstr, IND_ACELP_16KHZ, 0, 1 );
1229 : }
1230 0 : FOR( i = 0; i < stages_37bits; i++ )
1231 : {
1232 0 : push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] );
1233 : }
1234 0 : push_indice( hBstr, IND_ENERGY, index, 7 );
1235 : }
1236 :
1237 : /* Interpolate the bin/band-wise levels from the partition levels */
1238 : /* sidNoiseEst: Q6.26 format => cngNoiseLevel: Q6.26 format */
1239 0 : scalebands( st->sidNoiseEst, stenc->partDec, stenc->npartDec, stenc->midbandDec, stenc->nFFTpartDec, sub( stenc->stopBandDec, stenc->startBandDec ), st->cngNoiseLevel, 1 );
1240 0 : st->cngNoiseLevelExp = st->sidNoiseEstExp;
1241 0 : move16();
1242 :
1243 :
1244 0 : lpc_from_spectrum( st, stenc->startBandDec, stenc->stopFFTbinDec, preemph_fac );
1245 0 : }
1246 :
1247 :
1248 0 : void generate_comfort_noise_enc_fx( Encoder_State *stcod,
1249 : Word16 Q_new,
1250 : Word16 gen_exc )
1251 : {
1252 : Word16 i, s, sn, cnt;
1253 : Word16 startBand2;
1254 : Word16 stopFFTbin2;
1255 : Word16 preemph_fac;
1256 : Word32 sqrtNoiseLevel;
1257 : Word16 randGaussExp;
1258 : Word16 fftBufferExp;
1259 : Word16 cngNoiseLevelExp;
1260 : Word16 *seed;
1261 : Word16 *timeDomainOutput;
1262 : Word32 *ptr_r, *ptr_i;
1263 : Word32 *cngNoiseLevel;
1264 : Word32 *ptr_level;
1265 : Word32 *fftBuffer;
1266 : Word16 old_syn_pe_tmp[16];
1267 0 : Word16 tcx_transition = 0;
1268 0 : HANDLE_FD_CNG_ENC stenc = stcod->hFdCngEnc;
1269 0 : HANDLE_FD_CNG_COM st = stenc->hFdCngCom;
1270 0 : DTX_ENC_HANDLE hDtxEnc = stcod->hDtxEnc;
1271 0 : TD_CNG_ENC_HANDLE hTdCngEnc = stcod->hTdCngEnc;
1272 :
1273 0 : LPD_state_HANDLE hLPDmem = stcod->hLPDmem;
1274 0 : TCX_ENC_HANDLE hTcxEnc = stcod->hTcxEnc;
1275 :
1276 : /* Warning fix */
1277 0 : s = 0;
1278 :
1279 : /* pointer initialization */
1280 :
1281 0 : cngNoiseLevel = st->cngNoiseLevel;
1282 0 : cngNoiseLevelExp = st->cngNoiseLevelExp;
1283 0 : ptr_level = cngNoiseLevel;
1284 0 : seed = &( st->seed );
1285 0 : fftBuffer = st->fftBuffer;
1286 0 : timeDomainOutput = st->timeDomainBuffer;
1287 :
1288 : /*
1289 : Generate Gaussian random noise in real and imaginary parts of the FFT bins
1290 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
1291 : scaling Gaussian random noise: format Q3.29
1292 : */
1293 0 : sn = 0;
1294 0 : move16();
1295 0 : IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
1296 : {
1297 0 : sn = add( sn, 1 );
1298 0 : cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
1299 0 : move16();
1300 : }
1301 :
1302 0 : randGaussExp = CNG_RAND_GAUSS_SHIFT;
1303 0 : move16();
1304 0 : cnt = sub( stenc->stopFFTbinDec, stenc->startBandDec );
1305 0 : IF( stenc->startBandDec == 0 )
1306 : {
1307 : /* DC component in FFT */
1308 0 : s = 0;
1309 0 : move16();
1310 0 : sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s );
1311 :
1312 0 : fftBuffer[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
1313 0 : move32();
1314 :
1315 : /* Nyquist frequency is discarded */
1316 0 : fftBuffer[1] = L_deposit_l( 0 );
1317 :
1318 0 : ptr_level = ptr_level + 1;
1319 0 : ptr_r = fftBuffer + 2;
1320 0 : cnt = sub( cnt, 1 );
1321 : }
1322 : ELSE
1323 : {
1324 0 : startBand2 = shl( stenc->startBandDec, 1 );
1325 0 : set32_fx( fftBuffer, 0, startBand2 );
1326 0 : ptr_r = fftBuffer + startBand2;
1327 : }
1328 :
1329 0 : sn = add( sn, 1 );
1330 0 : ptr_i = ptr_r + 1;
1331 0 : FOR( i = 0; i < cnt; i++ )
1332 : {
1333 0 : s = 0;
1334 0 : move16();
1335 0 : sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s );
1336 :
1337 : /* Real part in FFT bins */
1338 0 : *ptr_r = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
1339 0 : move32();
1340 :
1341 : /* Imaginary part in FFT bins */
1342 0 : *ptr_i = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
1343 0 : move32();
1344 :
1345 0 : ptr_r = ptr_r + 2;
1346 0 : ptr_i = ptr_i + 2;
1347 0 : ptr_level = ptr_level + 1;
1348 : }
1349 :
1350 : /* Remaining FFT bins are set to zero */
1351 0 : stopFFTbin2 = shl( stenc->stopFFTbinDec, 1 );
1352 0 : set32_fx( fftBuffer + stopFFTbin2, 0, sub( st->fftlen, stopFFTbin2 ) );
1353 :
1354 0 : fftBufferExp = add( shr( cngNoiseLevelExp, 1 ), randGaussExp );
1355 :
1356 : /* If previous frame is active, reset the overlap-add buffer */
1357 0 : IF( GT_32( stcod->last_core_brate, SID_2k40 ) )
1358 : {
1359 0 : set16_fx( st->olapBufferSynth, 0, st->fftlen );
1360 0 : test();
1361 0 : test();
1362 0 : IF( ( GT_32( stcod->last_core, ACELP_CORE ) && EQ_16( stcod->codec_mode, MODE2 ) ) || EQ_16( stcod->codec_mode, MODE1 ) )
1363 : {
1364 0 : tcx_transition = 1;
1365 0 : move16();
1366 : }
1367 : }
1368 :
1369 : /* Perform STFT synthesis */
1370 0 : SynthesisSTFT( fftBuffer, fftBufferExp, timeDomainOutput, st->olapBufferSynth, st->olapWinSyn,
1371 : tcx_transition, st, gen_exc, &Q_new, -1, -1 );
1372 : {
1373 : Word32 Lener, att;
1374 : Word16 exp;
1375 : /* update CNG excitation energy for LP_CNG */
1376 :
1377 : /* calculate the residual signal energy */
1378 : /*enr = dotp( st->exc_cng, st->exc_cng, st->frameSize ) / st->frameSize;*/
1379 0 : Lener = Dot_productSq16HQ( 1, st->exc_cng, stcod->L_frame, &exp );
1380 0 : exp = add( sub( shl( sub( 15, Q_new ), 1 ), 8 ), exp ); /*8 = log2(256)*/
1381 :
1382 : /* convert log2 of residual signal energy */
1383 : /*(float)log10( enr + 0.1f ) / (float)log10( 2.0f );*/
1384 0 : Lener = BASOP_Util_Log2( Lener );
1385 0 : Lener = L_add( Lener, L_shl( L_deposit_l( exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/
1386 0 : if ( EQ_16( stcod->L_frame, L_FRAME16k ) )
1387 : {
1388 0 : Lener = L_sub( Lener, 10802114l /*0.3219280949f Q25*/ ); /*log2(320) = 8.3219280949f*/
1389 : }
1390 : /* decrease the energy in case of WB input */
1391 0 : IF( NE_16( stcod->bwidth, NB ) )
1392 : {
1393 0 : IF( EQ_16( stcod->bwidth, WB ) )
1394 : {
1395 0 : IF( hDtxEnc->CNG_mode >= 0 )
1396 : {
1397 : /* Bitrate adapted attenuation */
1398 0 : att = L_shl( L_deposit_l( ENR_ATT_fx[hDtxEnc->CNG_mode] ), 17 );
1399 : }
1400 : ELSE
1401 : {
1402 : /* Use least attenuation for higher bitrates */
1403 0 : att = L_shl( L_deposit_l( ENR_ATT_fx[4] ), 17 );
1404 : }
1405 : }
1406 : ELSE
1407 : {
1408 0 : att = 384 << 17;
1409 0 : move32(); /*1.5 Q8<<17=Q25*/
1410 : }
1411 0 : Lener = L_sub( Lener, att );
1412 : }
1413 : /*stdec->lp_ener = 0.8f * stcod->lp_ener + 0.2f * pow( 2.0f, enr );*/
1414 0 : Lener = BASOP_util_Pow2( Lener, 6, &exp );
1415 0 : Lener = Mult_32_16( Lener, 6554 /*0.2f Q15*/ );
1416 0 : exp = sub( 25, exp );
1417 0 : Lener = L_shr( Lener, exp ); /*Q6*/
1418 0 : hTdCngEnc->lp_ener_fx = L_add( Mult_32_16( hTdCngEnc->lp_ener_fx, 26214 /*0.8f Q15*/ ), Lener ); /*Q6*/
1419 : }
1420 :
1421 : /* Overlap-add when previous frame is active */
1422 0 : test();
1423 0 : IF( ( GT_32( stcod->last_core_brate, SID_2k40 ) ) && ( EQ_16( stcod->codec_mode, MODE2 ) ) )
1424 : {
1425 : Word32 old_exc_ener, gain, noise32;
1426 : Word16 seed_loc, lpcorder, old_syn, tmp, gain16, N, N2, N4, N8;
1427 : Word16 old_exc_ener_exp, gain_exp;
1428 : Word16 normFacE, normShiftE, normShiftEM1;
1429 : Word16 normFacG, normShiftG, normShiftGM1;
1430 : Word16 noiseExp, *old_exc, old_Aq[M + 1], *old_syn_pe;
1431 : Word16 noise[640], normShiftP2;
1432 : Word16 Q_exc, Q_syn;
1433 :
1434 :
1435 0 : assert( st->frameSize <= 640 );
1436 :
1437 0 : seed_loc = st->seed;
1438 0 : move16();
1439 0 : N = st->frameSize;
1440 0 : move16();
1441 0 : N2 = shr( st->frameSize, 1 );
1442 :
1443 0 : IF( GT_16( stcod->last_core, ACELP_CORE ) )
1444 : {
1445 : Word16 left_overlap_mode;
1446 0 : left_overlap_mode = stcod->hTcxCfg->tcx_last_overlap_mode;
1447 0 : move16();
1448 0 : if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
1449 : {
1450 0 : left_overlap_mode = FULL_OVERLAP;
1451 0 : move16();
1452 : }
1453 :
1454 0 : tcx_windowing_synthesis_current_frame( timeDomainOutput,
1455 0 : stcod->hTcxCfg->tcx_mdct_window, /*Keep sine windows for limiting Time modulation*/
1456 0 : stcod->hTcxCfg->tcx_mdct_window_half,
1457 0 : stcod->hTcxCfg->tcx_mdct_window_minimum,
1458 0 : stcod->hTcxCfg->tcx_mdct_window_length,
1459 0 : stcod->hTcxCfg->tcx_mdct_window_half_length,
1460 0 : stcod->hTcxCfg->tcx_mdct_window_min_length,
1461 : 0,
1462 : left_overlap_mode,
1463 : NULL,
1464 : NULL,
1465 : NULL,
1466 : NULL,
1467 : NULL,
1468 : N / 2,
1469 0 : shr( sub( abs_s( stcod->hTcxCfg->tcx_offset ), stcod->hTcxCfg->tcx_offset ), 1 ), /* equivalent to: stdec->hTcxCfg->tcx_offset<0?-stdec->hTcxCfg->tcx_offset:0 */
1470 : 1,
1471 : 0,
1472 : 0 );
1473 :
1474 0 : IF( stcod->hTcxCfg->last_aldo != 0 )
1475 : {
1476 0 : FOR( i = 0; i < st->frameSize; i++ )
1477 : {
1478 0 : timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( hTcxEnc->old_out_fx[i + NS2SA_FX2( stcod->sr_core, N_ZERO_MDCT_NS )], hTcxEnc->Q_old_out ) );
1479 0 : move16();
1480 : }
1481 : }
1482 : ELSE
1483 : {
1484 0 : tcx_windowing_synthesis_past_frame( hTcxEnc->Txnq,
1485 0 : stcod->hTcxCfg->tcx_aldo_window_1_trunc,
1486 0 : stcod->hTcxCfg->tcx_mdct_window_half,
1487 0 : stcod->hTcxCfg->tcx_mdct_window_minimum,
1488 0 : stcod->hTcxCfg->tcx_mdct_window_length,
1489 0 : stcod->hTcxCfg->tcx_mdct_window_half_length,
1490 0 : stcod->hTcxCfg->tcx_mdct_window_min_length,
1491 0 : stcod->hTcxCfg->tcx_last_overlap_mode );
1492 :
1493 0 : FOR( i = 0; i < N2; i++ )
1494 : {
1495 0 : timeDomainOutput[i] = add( timeDomainOutput[i], shl( hTcxEnc->Txnq[i], TCX_IMDCT_HEADROOM ) );
1496 0 : move16();
1497 : }
1498 : }
1499 : }
1500 : ELSE
1501 : {
1502 :
1503 : /*
1504 : - the scaling of the LPCs (e.g. old_Aq) is always Q12 (encoder or decoder)
1505 :
1506 : - the scaling of the deemphasized signals (e.g. old_syn) is always Q0 (encoder or decoder)
1507 :
1508 : - the scaling of the excitation signals in the encoder (e.g. old_exc) is Q_new
1509 : - the scaling of the preemphasized signals in the encoder (e.g. old_syn_pe) is Q_new-1
1510 :
1511 : - the scaling of the excitation signals in the decoder (e.g. old_exc) is Q_exc (or stdec->Q_exc)
1512 : - the scaling of the preemphasized signals in the decoder (e.g. old_syn_pe) is Q_syn (or stdec->Q_syn)
1513 : */
1514 :
1515 0 : lpcorder = M;
1516 0 : move16();
1517 0 : E_LPC_f_lsp_a_conversion( stcod->lsp_old_fx, old_Aq, M );
1518 0 : old_exc = hLPDmem->old_exc + sub( L_EXC_MEM, N2 );
1519 0 : old_syn_pe = hLPDmem->mem_syn2;
1520 0 : old_syn = hLPDmem->syn[lpcorder];
1521 0 : move16();
1522 0 : preemph_fac = stcod->preemph_fac;
1523 0 : move16();
1524 0 : Q_exc = Q_new;
1525 0 : Q_syn = sub( Q_new, 1 );
1526 :
1527 : /* shift to be in the range of values supported by getNormReciprocalWord16() */
1528 0 : N8 = shr( N2, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
1529 :
1530 0 : assert( N2 == ( N8 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
1531 :
1532 0 : normFacE = getNormReciprocalWord16( N8 );
1533 0 : normShiftE = BASOP_util_norm_s_bands2shift( N8 );
1534 0 : normShiftEM1 = sub( normShiftE, 1 );
1535 0 : normShiftP2 = add( normShiftE, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
1536 :
1537 0 : old_exc_ener = L_shr( L_mult( old_exc[0], old_exc[0] ), normShiftP2 );
1538 0 : FOR( i = 1; i < N2; i++ )
1539 : {
1540 0 : old_exc_ener = L_add( old_exc_ener, L_shr( L_mult( old_exc[i], old_exc[i] ), normShiftP2 ) );
1541 : }
1542 0 : old_exc_ener = L_shl( Mpy_32_16_1( old_exc_ener, shl( normFacE, normShiftEM1 ) ), 1 );
1543 :
1544 0 : old_exc_ener_exp = 0;
1545 0 : move16();
1546 0 : old_exc_ener = Sqrt32( old_exc_ener, &old_exc_ener_exp );
1547 0 : old_exc_ener_exp = add( old_exc_ener_exp, ( sub( 15, Q_exc ) ) );
1548 :
1549 : /* shift to be in the range of values supported by getNormReciprocalWord16() */
1550 0 : N4 = shr( N, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
1551 :
1552 0 : assert( N == ( N4 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
1553 :
1554 0 : normFacG = getNormReciprocalWord16( N4 );
1555 0 : normShiftG = BASOP_util_norm_s_bands2shift( N4 );
1556 0 : normShiftGM1 = sub( normShiftG, 1 );
1557 0 : normShiftP2 = add( normShiftG, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
1558 :
1559 0 : gain = L_deposit_l( 0 );
1560 0 : FOR( i = 0; i < N; i++ )
1561 : {
1562 0 : noise32 = rand_gauss( &seed_loc );
1563 0 : noise[i] = extract_h( noise32 );
1564 0 : gain = L_add( gain, L_shr( L_mult( noise[i], noise[i] ), normShiftP2 ) );
1565 : }
1566 0 : gain = L_shl( Mpy_32_16_1( gain, shl( normFacG, normShiftGM1 ) ), 1 );
1567 :
1568 0 : gain_exp = 2 * CNG_RAND_GAUSS_SHIFT;
1569 0 : move16();
1570 0 : gain = ISqrt32( gain, &gain_exp );
1571 :
1572 0 : gain = Mpy_32_32( old_exc_ener, gain );
1573 0 : gain16 = extract_h( gain );
1574 :
1575 0 : gain_exp = add( old_exc_ener_exp, gain_exp );
1576 0 : noiseExp = add( CNG_RAND_GAUSS_SHIFT, gain_exp );
1577 :
1578 0 : s = sub( 15 - NOISE_HEADROOM, noiseExp );
1579 0 : FOR( i = 0; i < N; i++ )
1580 : {
1581 0 : noise[i] = shr_sat( mult( noise[i], gain16 ), s );
1582 0 : move16();
1583 : }
1584 :
1585 0 : assert( lpcorder <= 16 );
1586 :
1587 0 : s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) );
1588 0 : FOR( i = 0; i < lpcorder; i++ )
1589 : {
1590 0 : old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s );
1591 0 : move16();
1592 : }
1593 :
1594 0 : E_UTIL_synthesis(
1595 : 0, /* i : scaling to apply for a[0] Q0 */
1596 : old_Aq, /* i : LP filter coefficients Q12 */
1597 : noise, /* i : input signal Qx */
1598 : noise, /* o : output signal Qx-s */
1599 : N, /* i : size of filtering Q0 */
1600 : old_syn_pe_tmp, /* i/o: memory associated with this filtering. Q0 */
1601 : 0, /* i : 0=no update, 1=update of memory. Q0 */
1602 : lpcorder /* i : order of LP filter Q0 */
1603 : );
1604 :
1605 0 : tmp = old_syn;
1606 0 : move16();
1607 :
1608 0 : E_UTIL_deemph2(
1609 : NOISE_HEADROOM,
1610 : noise, /* I/O: signal Qx */
1611 : preemph_fac, /* I: deemphasis factor Qx */
1612 : N, /* I: vector size */
1613 : &tmp /* I/O: memory (signal[-1]) Qx */
1614 : );
1615 :
1616 0 : FOR( i = 0; i < N4; i++ )
1617 : {
1618 0 : tmp = mult( noise[i], st->olapWinSyn[i].v.re );
1619 0 : timeDomainOutput[i] = add( timeDomainOutput[i], tmp );
1620 0 : move16();
1621 0 : tmp = mult( noise[i + N4], st->olapWinSyn[N4 - 1 - i].v.im );
1622 0 : timeDomainOutput[i + N4] = add( timeDomainOutput[i + N4], tmp );
1623 0 : move16();
1624 : }
1625 : }
1626 : }
1627 0 : }
1628 :
1629 12598 : void generate_comfort_noise_enc_ivas_fx( Encoder_State *stcod,
1630 : Word16 Q_new,
1631 : Word16 gen_exc )
1632 : {
1633 : Word16 i, s, sn, cnt;
1634 : Word16 startBand2;
1635 : Word16 stopFFTbin2;
1636 : Word16 preemph_fac;
1637 : Word32 sqrtNoiseLevel;
1638 : Word16 randGaussExp;
1639 : Word16 fftBufferExp;
1640 : Word16 cngNoiseLevelExp;
1641 : Word16 *seed;
1642 : Word16 *timeDomainOutput;
1643 : Word32 *ptr_r, *ptr_i;
1644 : Word32 *cngNoiseLevel;
1645 : Word32 *ptr_level;
1646 : Word32 *fftBuffer;
1647 : Word16 old_syn_pe_tmp[16];
1648 12598 : Word16 tcx_transition = 0;
1649 12598 : move16();
1650 12598 : HANDLE_FD_CNG_ENC stenc = stcod->hFdCngEnc;
1651 12598 : HANDLE_FD_CNG_COM st = stenc->hFdCngCom;
1652 12598 : DTX_ENC_HANDLE hDtxEnc = stcod->hDtxEnc;
1653 12598 : TD_CNG_ENC_HANDLE hTdCngEnc = stcod->hTdCngEnc;
1654 :
1655 12598 : LPD_state_HANDLE hLPDmem = stcod->hLPDmem;
1656 12598 : TCX_ENC_HANDLE hTcxEnc = stcod->hTcxEnc;
1657 :
1658 : /* Warning fix */
1659 12598 : s = 0;
1660 12598 : move16();
1661 :
1662 : /* pointer initialization */
1663 :
1664 12598 : cngNoiseLevel = st->cngNoiseLevel;
1665 12598 : cngNoiseLevelExp = st->cngNoiseLevelExp;
1666 12598 : move16();
1667 12598 : ptr_level = cngNoiseLevel; // cngNoiseLevelExp
1668 12598 : seed = &( st->seed );
1669 12598 : fftBuffer = st->fftBuffer; // st->fftBuffer_exp
1670 12598 : timeDomainOutput = st->timeDomainBuffer; // Q15
1671 :
1672 : /*
1673 : Generate Gaussian random noise in real and imaginary parts of the FFT bins
1674 : Amplitudes are adjusted to the estimated noise level cngNoiseLevel in each bin
1675 : scaling Gaussian random noise: format Q3.29
1676 : */
1677 12598 : sn = 0;
1678 12598 : move16();
1679 12598 : IF( s_and( cngNoiseLevelExp, 1 ) != 0 )
1680 : {
1681 7119 : sn = add( sn, 1 );
1682 7119 : cngNoiseLevelExp = add( cngNoiseLevelExp, sn );
1683 : }
1684 :
1685 12598 : randGaussExp = CNG_RAND_GAUSS_SHIFT;
1686 12598 : move16();
1687 12598 : cnt = sub( stenc->stopFFTbinDec, stenc->startBandDec ); // Q)=0
1688 12598 : IF( stenc->startBandDec == 0 )
1689 : {
1690 : /* DC component in FFT */
1691 0 : s = 0;
1692 0 : move16();
1693 0 : sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s );
1694 :
1695 0 : fftBuffer[0] = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
1696 0 : move32();
1697 :
1698 : /* Nyquist frequency is discarded */
1699 0 : fftBuffer[1] = L_deposit_l( 0 );
1700 0 : move32();
1701 :
1702 0 : ptr_level = ptr_level + 1;
1703 0 : ptr_r = fftBuffer + 2;
1704 0 : cnt = sub( cnt, 1 );
1705 : }
1706 : ELSE
1707 : {
1708 12598 : startBand2 = shl( stenc->startBandDec, 1 );
1709 12598 : set32_fx( fftBuffer, 0, startBand2 );
1710 12598 : ptr_r = fftBuffer + startBand2;
1711 : }
1712 :
1713 12598 : sn = add( sn, 1 );
1714 12598 : ptr_i = ptr_r + 1;
1715 3605514 : FOR( i = 0; i < cnt; i++ )
1716 : {
1717 3592916 : s = 0;
1718 3592916 : move16();
1719 3592916 : sqrtNoiseLevel = Sqrt32( L_shr( *ptr_level, sn ), &s );
1720 :
1721 : /* Real part in FFT bins */
1722 3592916 : *ptr_r = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
1723 3592916 : move32();
1724 :
1725 : /* Imaginary part in FFT bins */
1726 3592916 : *ptr_i = L_shl( Mpy_32_32( rand_gauss( seed ), sqrtNoiseLevel ), s );
1727 3592916 : move32();
1728 :
1729 3592916 : ptr_r = ptr_r + 2;
1730 3592916 : ptr_i = ptr_i + 2;
1731 3592916 : ptr_level = ptr_level + 1;
1732 : }
1733 :
1734 : /* Remaining FFT bins are set to zero */
1735 12598 : stopFFTbin2 = shl( stenc->stopFFTbinDec, 1 );
1736 12598 : set32_fx( fftBuffer + stopFFTbin2, 0, sub( st->fftlen, stopFFTbin2 ) );
1737 :
1738 12598 : fftBufferExp = add( shr( cngNoiseLevelExp, 1 ), randGaussExp );
1739 :
1740 : /* If previous frame is active, reset the overlap-add buffer */
1741 12598 : IF( GT_32( stcod->last_core_brate, SID_2k40 ) )
1742 : {
1743 659 : set16_fx( st->olapBufferSynth, 0, st->fftlen );
1744 659 : test();
1745 659 : test();
1746 659 : IF( ( GT_32( stcod->last_core, ACELP_CORE ) && EQ_16( stcod->codec_mode, MODE2 ) ) || EQ_16( stcod->codec_mode, MODE1 ) )
1747 : {
1748 659 : tcx_transition = 1;
1749 659 : move16();
1750 : }
1751 : }
1752 :
1753 : /* Perform STFT synthesis */
1754 12598 : SynthesisSTFT_enc_ivas_fx( fftBuffer, fftBufferExp, timeDomainOutput, st->olapBufferSynth, st->olapWinSyn,
1755 : tcx_transition, st, gen_exc, &Q_new, -1, -1 );
1756 12598 : IF( hTdCngEnc != NULL )
1757 : {
1758 : Word32 Lener, att;
1759 : Word16 exp;
1760 : /* update CNG excitation energy for LP_CNG */
1761 :
1762 : /* calculate the residual signal energy */
1763 : /*enr = dotp( st->exc_cng, st->exc_cng, st->frameSize ) / st->frameSize;*/
1764 10483 : Lener = Dot_productSq16HQ( 1, st->exc_cng, stcod->L_frame, &exp );
1765 10483 : exp = add( sub( shl( sub( 15, Q_new ), 1 ), 8 ), exp ); /*8 = log2(256)*/
1766 :
1767 : /* convert log2 of residual signal energy */
1768 : /*(float)log10( enr + 0.1f ) / (float)log10( 2.0f );*/
1769 10483 : Lener = BASOP_Util_Log2( Lener );
1770 10483 : Lener = L_add( Lener, L_shl( L_deposit_l( exp ), WORD32_BITS - 1 - LD_DATA_SCALE ) ); /*Q25*/
1771 10483 : if ( EQ_16( stcod->L_frame, L_FRAME16k ) )
1772 : {
1773 5977 : Lener = L_sub( Lener, 10802114l /*0.3219280949f Q25*/ ); /*log2(320) = 8.3219280949f*/
1774 : }
1775 : /* decrease the energy in case of WB input */
1776 10483 : IF( NE_16( stcod->bwidth, NB ) )
1777 : {
1778 10483 : IF( EQ_16( stcod->bwidth, WB ) )
1779 : {
1780 3706 : IF( hDtxEnc->CNG_mode >= 0 )
1781 : {
1782 : /* Bitrate adapted attenuation */
1783 0 : att = L_shl( L_deposit_l( ENR_ATT_fx[hDtxEnc->CNG_mode] ), 17 );
1784 : }
1785 : ELSE
1786 : {
1787 : /* Use least attenuation for higher bitrates */
1788 3706 : att = L_shl( L_deposit_l( ENR_ATT_fx[4] ), 17 );
1789 : }
1790 : }
1791 : ELSE
1792 : {
1793 6777 : att = 384 << 17;
1794 6777 : move32(); /*1.5 Q8<<17=Q25*/
1795 : }
1796 10483 : Lener = L_sub( Lener, att );
1797 : }
1798 : /*stdec->lp_ener = 0.8f * stcod->lp_ener + 0.2f * pow( 2.0f, enr );*/
1799 10483 : Lener = BASOP_util_Pow2( Lener, 6, &exp );
1800 10483 : Lener = Mult_32_16( Lener, 6554 /*0.2f Q15*/ );
1801 10483 : exp = sub( 25, exp );
1802 10483 : Lener = L_shr( Lener, exp ); /*Q6*/
1803 10483 : hTdCngEnc->lp_ener_fx = L_add( Mult_32_16( hTdCngEnc->lp_ener_fx, 26214 /*0.8f Q15*/ ), Lener ); /*Q6*/
1804 10483 : move32();
1805 : }
1806 :
1807 : /* Overlap-add when previous frame is active */
1808 12598 : test();
1809 12598 : IF( ( GT_32( stcod->last_core_brate, SID_2k40 ) ) && ( EQ_16( stcod->codec_mode, MODE2 ) ) )
1810 : {
1811 : Word32 old_exc_ener, gain, noise32;
1812 : Word16 seed_loc, lpcorder, old_syn, tmp, gain16, N, N2, N4, N8;
1813 : Word16 old_exc_ener_exp, gain_exp;
1814 : Word16 normFacE, normShiftE, normShiftEM1;
1815 : Word16 normFacG, normShiftG, normShiftGM1;
1816 : Word16 noiseExp, *old_exc, old_Aq[M + 1], *old_syn_pe;
1817 : Word16 noise[640], normShiftP2;
1818 : Word16 Q_exc, Q_syn;
1819 :
1820 :
1821 0 : assert( st->frameSize <= 640 );
1822 :
1823 0 : seed_loc = st->seed;
1824 0 : move16();
1825 0 : N = st->frameSize; // Q0
1826 0 : move16();
1827 0 : N2 = shr( st->frameSize, 1 );
1828 :
1829 0 : IF( GT_16( stcod->last_core, ACELP_CORE ) )
1830 : {
1831 : Word16 left_overlap_mode;
1832 0 : left_overlap_mode = stcod->hTcxCfg->tcx_last_overlap_mode;
1833 0 : move16();
1834 0 : if ( EQ_16( left_overlap_mode, ALDO_WINDOW ) )
1835 : {
1836 0 : left_overlap_mode = FULL_OVERLAP;
1837 0 : move16();
1838 : }
1839 :
1840 0 : tcx_windowing_synthesis_current_frame( timeDomainOutput,
1841 0 : stcod->hTcxCfg->tcx_mdct_window, /*Keep sine windows for limiting Time modulation*/
1842 0 : stcod->hTcxCfg->tcx_mdct_window_half,
1843 0 : stcod->hTcxCfg->tcx_mdct_window_minimum,
1844 0 : stcod->hTcxCfg->tcx_mdct_window_length,
1845 0 : stcod->hTcxCfg->tcx_mdct_window_half_length,
1846 0 : stcod->hTcxCfg->tcx_mdct_window_min_length,
1847 : 0,
1848 : left_overlap_mode,
1849 : NULL,
1850 : NULL,
1851 : NULL,
1852 : NULL,
1853 : NULL,
1854 : N / 2,
1855 0 : shr( sub( abs_s( stcod->hTcxCfg->tcx_offset ), stcod->hTcxCfg->tcx_offset ), 1 ), /* equivalent to: stdec->hTcxCfg->tcx_offset<0?-stdec->hTcxCfg->tcx_offset:0 */
1856 : 1,
1857 : 0,
1858 : 0 );
1859 :
1860 0 : IF( stcod->hTcxCfg->last_aldo != 0 )
1861 : {
1862 0 : FOR( i = 0; i < st->frameSize; i++ )
1863 : {
1864 0 : timeDomainOutput[i] = add( timeDomainOutput[i], shr_r( hTcxEnc->old_out_fx[i + NS2SA_FX2( stcod->sr_core, N_ZERO_MDCT_NS )], hTcxEnc->Q_old_out ) );
1865 0 : move16();
1866 : }
1867 : }
1868 : ELSE
1869 : {
1870 0 : tcx_windowing_synthesis_past_frame( hTcxEnc->Txnq,
1871 0 : stcod->hTcxCfg->tcx_aldo_window_1_trunc,
1872 0 : stcod->hTcxCfg->tcx_mdct_window_half,
1873 0 : stcod->hTcxCfg->tcx_mdct_window_minimum,
1874 0 : stcod->hTcxCfg->tcx_mdct_window_length,
1875 0 : stcod->hTcxCfg->tcx_mdct_window_half_length,
1876 0 : stcod->hTcxCfg->tcx_mdct_window_min_length,
1877 0 : stcod->hTcxCfg->tcx_last_overlap_mode );
1878 :
1879 0 : FOR( i = 0; i < N2; i++ )
1880 : {
1881 0 : timeDomainOutput[i] = add( timeDomainOutput[i], shl( hTcxEnc->Txnq[i], TCX_IMDCT_HEADROOM ) ); // Q15
1882 0 : move16();
1883 : }
1884 : }
1885 : }
1886 : ELSE
1887 : {
1888 :
1889 : /*
1890 : - the scaling of the LPCs (e.g. old_Aq) is always Q12 (encoder or decoder)
1891 :
1892 : - the scaling of the deemphasized signals (e.g. old_syn) is always Q0 (encoder or decoder)
1893 :
1894 : - the scaling of the excitation signals in the encoder (e.g. old_exc) is Q_new
1895 : - the scaling of the preemphasized signals in the encoder (e.g. old_syn_pe) is Q_new-1
1896 :
1897 : - the scaling of the excitation signals in the decoder (e.g. old_exc) is Q_exc (or stdec->Q_exc)
1898 : - the scaling of the preemphasized signals in the decoder (e.g. old_syn_pe) is Q_syn (or stdec->Q_syn)
1899 : */
1900 :
1901 0 : lpcorder = M;
1902 0 : move16();
1903 0 : E_LPC_f_lsp_a_conversion( stcod->lsp_old_fx, old_Aq, M );
1904 0 : old_exc = hLPDmem->old_exc + sub( L_EXC_MEM, N2 );
1905 0 : old_syn_pe = hLPDmem->mem_syn2;
1906 0 : old_syn = hLPDmem->syn[lpcorder];
1907 0 : move16();
1908 0 : preemph_fac = stcod->preemph_fac;
1909 0 : move16();
1910 0 : Q_exc = Q_new;
1911 0 : move16();
1912 0 : Q_syn = sub( Q_new, 1 );
1913 :
1914 : /* shift to be in the range of values supported by getNormReciprocalWord16() */
1915 0 : N8 = shr( N2, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
1916 :
1917 0 : assert( N2 == ( N8 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
1918 :
1919 0 : normFacE = getNormReciprocalWord16( N8 );
1920 0 : normShiftE = BASOP_util_norm_s_bands2shift( N8 );
1921 0 : normShiftEM1 = sub( normShiftE, 1 );
1922 0 : normShiftP2 = add( normShiftE, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
1923 :
1924 0 : old_exc_ener = L_shr( L_mult( old_exc[0], old_exc[0] ), normShiftP2 );
1925 0 : FOR( i = 1; i < N2; i++ )
1926 : {
1927 0 : old_exc_ener = L_add( old_exc_ener, L_shr( L_mult( old_exc[i], old_exc[i] ), normShiftP2 ) );
1928 : }
1929 0 : old_exc_ener = L_shl( Mpy_32_16_1( old_exc_ener, shl( normFacE, normShiftEM1 ) ), 1 );
1930 :
1931 0 : old_exc_ener_exp = 0;
1932 0 : move16();
1933 0 : old_exc_ener = Sqrt32( old_exc_ener, &old_exc_ener_exp );
1934 0 : old_exc_ener_exp = add( old_exc_ener_exp, ( sub( 15, Q_exc ) ) );
1935 :
1936 : /* shift to be in the range of values supported by getNormReciprocalWord16() */
1937 0 : N4 = shr( N, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
1938 :
1939 0 : assert( N == ( N4 << CNG_NORM_RECIPROCAL_RANGE_SHIFT ) );
1940 :
1941 0 : normFacG = getNormReciprocalWord16( N4 );
1942 0 : normShiftG = BASOP_util_norm_s_bands2shift( N4 );
1943 0 : normShiftGM1 = sub( normShiftG, 1 );
1944 0 : normShiftP2 = add( normShiftG, CNG_NORM_RECIPROCAL_RANGE_SHIFT );
1945 :
1946 0 : gain = L_deposit_l( 0 );
1947 0 : FOR( i = 0; i < N; i++ )
1948 : {
1949 0 : noise32 = rand_gauss( &seed_loc );
1950 0 : noise[i] = extract_h( noise32 );
1951 0 : move16();
1952 0 : gain = L_add( gain, L_shr( L_mult( noise[i], noise[i] ), normShiftP2 ) );
1953 : }
1954 0 : gain = L_shl( Mpy_32_16_1( gain, shl( normFacG, normShiftGM1 ) ), 1 );
1955 :
1956 0 : gain_exp = 2 * CNG_RAND_GAUSS_SHIFT;
1957 0 : move16();
1958 0 : gain = ISqrt32( gain, &gain_exp );
1959 :
1960 0 : gain = Mpy_32_32( old_exc_ener, gain );
1961 0 : gain16 = extract_h( gain );
1962 :
1963 0 : gain_exp = add( old_exc_ener_exp, gain_exp );
1964 0 : noiseExp = add( CNG_RAND_GAUSS_SHIFT, gain_exp );
1965 :
1966 0 : s = sub( 15 - NOISE_HEADROOM, noiseExp );
1967 0 : FOR( i = 0; i < N; i++ )
1968 : {
1969 0 : noise[i] = shr_sat( mult( noise[i], gain16 ), s );
1970 0 : move16();
1971 : }
1972 :
1973 0 : assert( lpcorder <= 16 );
1974 :
1975 0 : s = sub( 15 - NOISE_HEADROOM, ( sub( 15, Q_syn ) ) );
1976 0 : FOR( i = 0; i < lpcorder; i++ )
1977 : {
1978 0 : old_syn_pe_tmp[i] = shr_sat( old_syn_pe[i], s );
1979 0 : move16();
1980 : }
1981 :
1982 0 : E_UTIL_synthesis(
1983 : 0, /* i : scaling to apply for a[0] Q0 */
1984 : old_Aq, /* i : LP filter coefficients Q12 */
1985 : noise, /* i : input signal Qx */
1986 : noise, /* o : output signal Qx-s */
1987 : N, /* i : size of filtering Q0 */
1988 : old_syn_pe_tmp, /* i/o: memory associated with this filtering. Q0 */
1989 : 0, /* i : 0=no update, 1=update of memory. Q0 */
1990 : lpcorder /* i : order of LP filter Q0 */
1991 : );
1992 :
1993 0 : tmp = old_syn;
1994 0 : move16();
1995 :
1996 0 : E_UTIL_deemph2(
1997 : NOISE_HEADROOM,
1998 : noise, /* I/O: signal Qx */
1999 : preemph_fac, /* I: deemphasis factor Qx */
2000 : N, /* I: vector size */
2001 : &tmp /* I/O: memory (signal[-1]) Qx */
2002 : );
2003 :
2004 0 : FOR( i = 0; i < N4; i++ )
2005 : {
2006 0 : tmp = mult( noise[i], st->olapWinSyn[i].v.re );
2007 0 : timeDomainOutput[i] = add( timeDomainOutput[i], tmp );
2008 0 : move16();
2009 0 : tmp = mult( noise[i + N4], st->olapWinSyn[N4 - 1 - i].v.im );
2010 0 : timeDomainOutput[i + N4] = add( timeDomainOutput[i + N4], tmp );
2011 0 : move16();
2012 : }
2013 : }
2014 : }
2015 12598 : }
2016 :
2017 : /*-------------------------------------------------------------------*
2018 : * cng_energy_fx()
2019 : *
2020 : *
2021 : *-------------------------------------------------------------------*/
2022 :
2023 : /*! r: CNG energy */
2024 0 : Word16 cng_energy_fx(
2025 : const Word16 element_mode, /* i : element mode Q0*/
2026 : const Word16 bwidth, /* i : audio bandwidh Q0*/
2027 : const Word16 CNG_mode, /* i : mode for DTX configuration Q0*/
2028 : const Word16 CNG_att, /* i : attenuation factor for CNG Q7*/
2029 : const Word16 *exc, /* i : input signal Q_new*/
2030 : const Word16 len, /* i : vector length Q0*/
2031 : const Word16 Q_new /* i : Input scaling */
2032 : )
2033 : {
2034 : Word16 i, maxv, scale;
2035 : Word16 hi, lo, enr, tmp16, att;
2036 : const Word16 *pt_res;
2037 : Word32 L_ener, L_tmp;
2038 :
2039 0 : maxv = 0;
2040 0 : move16();
2041 0 : FOR( i = 0; i < len; i++ )
2042 : {
2043 0 : maxv = s_max( maxv, abs_s( exc[i] ) );
2044 : }
2045 0 : scale = norm_s( maxv );
2046 0 : pt_res = exc;
2047 0 : L_ener = L_deposit_l( 1 );
2048 0 : IF( EQ_16( len, L_FRAME ) )
2049 : {
2050 0 : FOR( i = 0; i < 128; i++ )
2051 : {
2052 0 : tmp16 = shl( *pt_res, scale );
2053 0 : L_tmp = L_mult0( tmp16, tmp16 );
2054 0 : pt_res++;
2055 0 : tmp16 = shl( *pt_res, scale );
2056 0 : L_tmp = L_mac0_sat( L_tmp, tmp16, tmp16 ); /* 2*(Q_new+scale) */
2057 0 : pt_res++;
2058 0 : L_ener = L_add( L_ener, L_shr( L_tmp, 7 ) ); /* 2*(Q_new+scale)+1, divide by L_frame done here */
2059 : }
2060 : }
2061 : ELSE /* L_FRAME16k */
2062 : {
2063 0 : FOR( i = 0; i < 160; i++ )
2064 : {
2065 0 : tmp16 = shl( *pt_res, scale );
2066 0 : L_tmp = L_mult0( tmp16, tmp16 );
2067 0 : pt_res++;
2068 0 : tmp16 = shl( *pt_res, scale );
2069 0 : L_tmp = L_mac0_sat( L_tmp, tmp16, tmp16 ); /* 2*(Q_new+scale) */
2070 0 : pt_res++;
2071 0 : L_ener = L_add( L_ener, L_shr( Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ), 7 ) ); /* 2*(Q_new+scale)+15+1-16+1, divide by L_frame done here */
2072 : }
2073 : }
2074 :
2075 0 : hi = norm_l( L_ener );
2076 0 : lo = Log2_norm_lc( L_shl( L_ener, hi ) );
2077 0 : hi = sub( 30, add( hi, shl( add( Q_new, scale ), 1 ) ) ); /* log2 exp in Q2*(Q_new+scale) */
2078 0 : L_tmp = L_Comp( hi, lo ); /* Q16 */
2079 0 : enr = round_fx( L_shl( L_tmp, 8 ) ); /* Q8 (16+8-16) */
2080 :
2081 : /* decrease the energy in case of WB input */
2082 0 : test();
2083 0 : IF( EQ_16( element_mode, IVAS_CPE_DFT ) || EQ_16( element_mode, IVAS_CPE_TD ) )
2084 : {
2085 : (void) CNG_att;
2086 : }
2087 0 : ELSE IF( NE_16( bwidth, NB ) )
2088 : {
2089 0 : IF( EQ_16( bwidth, WB ) )
2090 : {
2091 0 : IF( CNG_mode >= 0 )
2092 : {
2093 : /* Bitrate adapted attenuation */
2094 0 : att = ENR_ATT_fx[CNG_mode];
2095 : }
2096 : ELSE
2097 : {
2098 : /* Use least attenuation for higher bitrates */
2099 0 : att = ENR_ATT_fx[4];
2100 : }
2101 : }
2102 : ELSE
2103 : {
2104 0 : att = 384;
2105 0 : move16(); /*Q8*/
2106 : }
2107 0 : enr = sub( enr, att );
2108 : }
2109 0 : return enr;
2110 : }
2111 :
2112 : /*-------------------------------------------------------------------*
2113 : * cng_energy_ivas_fx()
2114 : *
2115 : *
2116 : *-------------------------------------------------------------------*/
2117 :
2118 : /*! r: CNG energy */
2119 1419 : Word16 cng_energy_ivas_fx(
2120 : const Word16 element_mode, /* i : element mode Q0*/
2121 : const Word16 bwidth, /* i : audio bandwidh Q0*/
2122 : const Word16 CNG_mode, /* i : mode for DTX configuration Q0*/
2123 : const Word16 CNG_att, /* i : attenuation factor for CNG Q7*/
2124 : const Word16 *exc, /* i : input signal Q_new*/
2125 : const Word16 len, /* i : vector length */
2126 : const Word16 Q_new /* i : Input scaling */
2127 : )
2128 : {
2129 : Word16 i, maxv, scale;
2130 : Word16 hi, lo, enr, tmp16, att;
2131 : const Word16 *pt_res;
2132 : Word32 L_ener, L_tmp;
2133 :
2134 1419 : maxv = 0;
2135 1419 : move16();
2136 416395 : FOR( i = 0; i < len; i++ )
2137 : {
2138 414976 : maxv = s_max( maxv, abs_s( exc[i] ) );
2139 : }
2140 1419 : scale = norm_s( maxv );
2141 1419 : pt_res = exc;
2142 1419 : L_ener = L_deposit_l( 1 );
2143 1419 : IF( EQ_16( len, L_FRAME ) )
2144 : {
2145 78819 : FOR( i = 0; i < 128; i++ )
2146 : {
2147 78208 : tmp16 = shl( *pt_res, sub( scale, 4 ) ); // Q_new + scale - 4
2148 78208 : L_tmp = L_mult0( tmp16, tmp16 );
2149 78208 : pt_res++;
2150 78208 : tmp16 = shl( *pt_res, sub( scale, 4 ) ); // Q_new + scale - 4
2151 78208 : L_tmp = L_mac0( L_tmp, tmp16, tmp16 ); /* 2*(Q_new+scale) + 7 */
2152 78208 : pt_res++;
2153 78208 : L_ener = L_add( L_ener, L_tmp ); /* 2*(Q_new+scale)+1, divide by L_frame done here */
2154 : }
2155 : }
2156 : ELSE /* L_FRAME16k */
2157 : {
2158 130088 : FOR( i = 0; i < 160; i++ )
2159 : {
2160 129280 : tmp16 = shl( *pt_res, sub( scale, 4 ) ); // Q_new + scale - 4
2161 129280 : L_tmp = L_mult( tmp16, tmp16 );
2162 129280 : pt_res++;
2163 129280 : tmp16 = shl( *pt_res, sub( scale, 4 ) ); // Q_new + scale - 4
2164 129280 : L_tmp = L_mac( L_tmp, tmp16, tmp16 ); /* 2*(Q_new+scale) - 7 */
2165 129280 : pt_res++;
2166 129280 : L_ener = L_add( L_ener, Mult_32_16( L_tmp, 26214 /* 256/320, Q15 */ ) ); /* 2*(Q_new+scale)+15+1-16+1, divide by L_frame done here */
2167 : }
2168 : }
2169 :
2170 1419 : hi = norm_l( L_ener );
2171 1419 : lo = Log2_norm_lc( L_shl( L_ener, hi ) );
2172 1419 : hi = sub( 30, add( hi, shl( add( Q_new, scale ), 1 ) ) ); /* log2 exp in Q2*(Q_new+scale) */
2173 1419 : L_tmp = L_Comp( hi, lo ); /* Q16 */
2174 1419 : enr = round_fx( L_shl( L_tmp, 8 ) ); /* Q8 (16+8-16) */
2175 :
2176 : /* decrease the energy in case of WB input */
2177 1419 : test();
2178 1419 : IF( EQ_16( element_mode, IVAS_CPE_DFT ) || EQ_16( element_mode, IVAS_CPE_TD ) )
2179 : {
2180 : // PMT(" IVAS CNG ener computing is missing")
2181 1075 : enr = add( enr, mult( CNG_att, FAC_LOG2_BY10_Q16 ) ); /* Q8 (7+16-15) */
2182 : }
2183 344 : ELSE IF( NE_16( bwidth, NB ) )
2184 : {
2185 344 : IF( EQ_16( bwidth, WB ) )
2186 : {
2187 223 : IF( CNG_mode >= 0 )
2188 : {
2189 : /* Bitrate adapted attenuation */
2190 0 : att = ENR_ATT_fx[CNG_mode];
2191 0 : move16();
2192 : }
2193 : ELSE
2194 : {
2195 : /* Use least attenuation for higher bitrates */
2196 223 : att = ENR_ATT_fx[4];
2197 223 : move16();
2198 : }
2199 : }
2200 : ELSE
2201 : {
2202 121 : att = 384;
2203 121 : move16(); /*Q8*/
2204 : }
2205 344 : enr = sub( enr, att );
2206 : }
2207 1419 : return enr;
2208 : }
2209 :
2210 121132 : void perform_noise_estimation_enc_ivas_fx(
2211 : Word32 *band_energies, /* i: energy in critical bands without minimum noise floor MODE2_E_MIN band_energies_exp*/
2212 : Word16 band_energies_exp,
2213 : Word32 *enerBuffer, /* enerBuffer_exp */
2214 : Word16 enerBuffer_exp,
2215 : HANDLE_FD_CNG_ENC hFdCngEnc, /* i/o: CNG structure containing all buffers and variables */
2216 : const Word32 input_Fs, /* i : input sampling rate Q0*/
2217 : CPE_ENC_HANDLE hCPE /* i : CPE encoder structure */
2218 : )
2219 : {
2220 : Word16 i, j, s, s1, s2;
2221 : Word16 numBands;
2222 121132 : Word16 numCoreBands = hFdCngEnc->hFdCngCom->numCoreBands; /* Q0 */
2223 121132 : move16();
2224 121132 : Word16 regularStopBand = hFdCngEnc->hFdCngCom->regularStopBand; /* Q0 */
2225 121132 : move16();
2226 121132 : Word16 numSlots = hFdCngEnc->hFdCngCom->numSlots; /* Q0 */
2227 121132 : move16();
2228 121132 : assert( numSlots == 16 );
2229 :
2230 121132 : Word32 numSlots_inv_fx = 1073741824; // Q34 of .0625
2231 121132 : move32();
2232 121132 : Word32 *periodog = hFdCngEnc->hFdCngCom->periodog; /* exp(peridog_exp) */
2233 121132 : Word32 *ptr_per_fx = periodog;
2234 : Word64 periodog_64;
2235 : Word16 periodog_exp[PERIODOGLEN];
2236 121132 : Word16 npart = hFdCngEnc->hFdCngCom->npart; /* Q0 */
2237 121132 : move16();
2238 121132 : Word16 nFFTpart = hFdCngEnc->hFdCngCom->nFFTpart; /* Q0 */
2239 121132 : move16();
2240 121132 : Word16 nCLDFBpart = hFdCngEnc->hFdCngCom->nCLDFBpart; /* Q0 */
2241 121132 : move16();
2242 :
2243 121132 : Word16 *psize = hFdCngEnc->hFdCngCom->psize; // 6Q9
2244 121132 : Word32 *msPeriodog_fx = hFdCngEnc->msPeriodog_fx;
2245 121132 : Word32 *msNoiseEst_fx = hFdCngEnc->msNoiseEst_fx; /* exp(msNoiseEst_fx_exp) */
2246 :
2247 121132 : Word16 *msLogPeriodog_fx = hFdCngEnc->msLogPeriodog_fx;
2248 121132 : Word16 *msLogNoiseEst_fx = hFdCngEnc->msLogNoiseEst_fx;
2249 :
2250 121132 : Word32 scaleEB_fx = 0;
2251 121132 : move32();
2252 : Word32 tmp;
2253 :
2254 121132 : test();
2255 121132 : IF( hCPE != NULL && hCPE->hStereoDft != NULL )
2256 : {
2257 : // band_res_dft = ( (float) input_Fs ) / hCPE->hStereoDft->NFFT;
2258 : // chan_width_f = 24000.f / CLDFB_NO_CHANNELS_MAX;
2259 : // chan_width_bins = chan_width_f / band_res_dft;
2260 :
2261 : ///* Scaling of Energy buffer to get energy per sample, same scaling as for band_energies, 3 is to compensate for the 1/3 scaling in calculate_energy_buffer */
2262 : // scaleEB = 3 * 4.0f / ( hCPE->hStereoDft->NFFT * hCPE->hStereoDft->NFFT );
2263 :
2264 : ///* Scale with number of bins in one band */
2265 : // scaleEB = scaleEB / chan_width_bins;
2266 :
2267 30299 : SWITCH( input_Fs )
2268 : {
2269 0 : case 8000:
2270 0 : scaleEB_fx = 251648; // Q35
2271 0 : move32();
2272 0 : BREAK;
2273 6282 : case 16000:
2274 6282 : scaleEB_fx = 62912; // Q35
2275 6282 : move32();
2276 6282 : BREAK;
2277 15751 : case 32000:
2278 15751 : scaleEB_fx = 15728; // Q35
2279 15751 : move32();
2280 15751 : BREAK;
2281 8266 : case 48000:
2282 8266 : scaleEB_fx = 6991; // Q35
2283 8266 : move32();
2284 8266 : BREAK;
2285 0 : default:
2286 0 : assert( 0 && "invalid sample rate" );
2287 : }
2288 : }
2289 : ELSE
2290 : {
2291 90833 : scaleEB_fx = Mpy_32_32( numSlots_inv_fx, L_deposit_l( hFdCngEnc->hFdCngCom->scalingFactor ) ); // Q34 + Q30 - Q31 = Q33
2292 90833 : scaleEB_fx = L_shl( scaleEB_fx, 2 ); // Q35
2293 : }
2294 :
2295 : /* preemphasis compensation and grouping of per bin energies into msPeriodog */
2296 2543772 : FOR( i = 0; i < nFFTpart; i++ )
2297 : {
2298 2422640 : tmp = L_add( L_shr( band_energies[i], 1 ), L_shr( band_energies[i + NB_BANDS], 1 ) );
2299 2422640 : msPeriodog_fx[i] = Mpy_32_16_1( tmp, preemphCompensation_fx[i] );
2300 2422640 : move32();
2301 : }
2302 :
2303 : /* exponent for fft part of msPeriodog */
2304 121132 : hFdCngEnc->msPeriodog_fx_exp_fft = add( band_energies_exp, PREEMPH_COMPENSATION_EXP );
2305 121132 : move16();
2306 :
2307 121132 : Word16 max_exp = -31;
2308 121132 : move16();
2309 121132 : i = 0;
2310 121132 : move16();
2311 : /* Adjust to the desired time resolution by averaging the periodograms over the time slots */
2312 2684300 : FOR( j = numCoreBands; j < regularStopBand; j++ )
2313 : {
2314 2563168 : periodog_64 = W_mult_32_32( enerBuffer[j], scaleEB_fx );
2315 2563168 : Word16 scale = W_norm( periodog_64 );
2316 2563168 : *ptr_per_fx = W_extract_h( W_shl( periodog_64, scale ) );
2317 2563168 : move32();
2318 2563168 : periodog_exp[i] = sub( Q31, add( add( sub( Q31, enerBuffer_exp ), 35 - 31 ), scale ) );
2319 2563168 : move16();
2320 2563168 : if ( *ptr_per_fx )
2321 : {
2322 2540850 : max_exp = s_max( max_exp, periodog_exp[i] );
2323 : }
2324 2563168 : ptr_per_fx++;
2325 2563168 : i++;
2326 : }
2327 : /* exponent for cldfb part of msPeriodog */
2328 : // hFdCngEnc->hFdCngCom->exp_cldfb_periodog = add( sub( enerBuffer_exp, 4 ), CLDFBscalingFactor_EXP );
2329 : // move16();
2330 :
2331 121132 : numBands = sub( regularStopBand, numCoreBands ); /* Q0 */
2332 2684300 : FOR( i = 0; i < numBands; i++ )
2333 : {
2334 :
2335 2563168 : periodog[i] = L_shr( periodog[i], sub( max_exp, periodog_exp[i] ) );
2336 :
2337 2563168 : move16();
2338 : }
2339 121132 : hFdCngEnc->hFdCngCom->exp_cldfb_periodog = max_exp;
2340 121132 : move16();
2341 121132 : IF( numBands > 0 )
2342 : {
2343 : ///* Adjust CLDFB filterbank to the desired frequency resolution by averaging over spectral partitions for SID transmission */
2344 121132 : bandcombinepow(
2345 : periodog,
2346 121132 : hFdCngEnc->hFdCngCom->exp_cldfb_periodog,
2347 : numBands,
2348 121132 : hFdCngEnc->hFdCngCom->CLDFBpart,
2349 : nCLDFBpart,
2350 121132 : hFdCngEnc->hFdCngCom->CLDFBpsize_inv,
2351 121132 : &msPeriodog_fx[nFFTpart],
2352 : &hFdCngEnc->msPeriodog_fx_exp_cldfb );
2353 :
2354 : ///* find common exponent for fft part and cldfb part of msperiodog */
2355 121132 : s1 = L_norm_arr( msPeriodog_fx, nFFTpart );
2356 121132 : s2 = L_norm_arr( &msPeriodog_fx[nFFTpart], nCLDFBpart );
2357 :
2358 121132 : s = s_max( sub( hFdCngEnc->msPeriodog_fx_exp_fft, s1 ), sub( hFdCngEnc->msPeriodog_fx_exp_cldfb, s2 ) );
2359 121132 : s1 = sub( s, hFdCngEnc->msPeriodog_fx_exp_fft );
2360 121132 : s2 = sub( s, hFdCngEnc->msPeriodog_fx_exp_cldfb );
2361 :
2362 121132 : hFdCngEnc->msPeriodog_fx_exp_fft = s;
2363 121132 : move16();
2364 121132 : hFdCngEnc->msPeriodog_fx_exp_cldfb = s;
2365 121132 : move16();
2366 :
2367 2543772 : FOR( i = 0; i < nFFTpart; i++ )
2368 : {
2369 2422640 : msPeriodog_fx[i] = L_shr( msPeriodog_fx[i], s1 ); /* hFdCngEnc->msPeriodog_fx_exp_fft */
2370 2422640 : move32();
2371 : }
2372 :
2373 554060 : FOR( i = 0; i < nCLDFBpart; i++ )
2374 : {
2375 432928 : msPeriodog_fx[nFFTpart + i] = L_shr( msPeriodog_fx[nFFTpart + i], s2 ); /* hFdCngEnc->msPeriodog_fx_exp_fft */
2376 432928 : move32();
2377 : }
2378 : }
2379 : /* exponent for entire msPeriodog vector */
2380 121132 : hFdCngEnc->msPeriodog_fx_exp = hFdCngEnc->msPeriodog_fx_exp_fft;
2381 121132 : move16();
2382 :
2383 : /* Compress MS inputs */
2384 : // compress_range_flt( msPeriodog, msLogPeriodog, npart );
2385 121132 : compress_range( msPeriodog_fx, hFdCngEnc->msPeriodog_fx_exp, msLogPeriodog_fx, npart );
2386 :
2387 :
2388 : /* Call the minimum statistics routine for noise estimation */
2389 :
2390 121132 : minimum_statistics_fx( npart, nFFTpart, psize, msLogPeriodog_fx, hFdCngEnc->msNoiseFloor_fx, msLogNoiseEst_fx, hFdCngEnc->msAlpha_fx, hFdCngEnc->msPsd_fx, hFdCngEnc->msPsdFirstMoment_fx,
2391 121132 : hFdCngEnc->msPsdSecondMoment_fx, hFdCngEnc->msMinBuf_fx, hFdCngEnc->msBminWin_fx, hFdCngEnc->msBminSubWin_fx, hFdCngEnc->msCurrentMin_fx, hFdCngEnc->msCurrentMinOut_fx, hFdCngEnc->msCurrentMinSubWindow_fx, hFdCngEnc->msLocalMinFlag, hFdCngEnc->msNewMinFlag, hFdCngEnc->msPeriodogBuf_fx, &( hFdCngEnc->msPeriodogBufPtr ), hFdCngEnc->hFdCngCom,
2392 68424 : ENC, ( hCPE == NULL ) ? 0 : hCPE->element_mode );
2393 :
2394 : /* Expand MS outputs */
2395 121132 : expand_range( msLogNoiseEst_fx, msNoiseEst_fx, &hFdCngEnc->msNoiseEst_fx_exp, hFdCngEnc->hFdCngCom->npart );
2396 :
2397 121132 : return;
2398 : }
2399 :
2400 :
2401 : /*-------------------------------------------------------------------*
2402 : * FdCng_encodeSID()
2403 : *
2404 : * Generate a bitstream out of the partition levels
2405 : *-------------------------------------------------------------------*/
2406 1954 : void FdCng_encodeSID_ivas_fx(
2407 : Encoder_State *st /* i/o: encoder state structure */
2408 : )
2409 : {
2410 : Word16 N;
2411 1954 : HANDLE_FD_CNG_ENC hFdCngEnc = st->hFdCngEnc;
2412 1954 : HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
2413 1954 : BSTR_ENC_HANDLE hBstr = st->hBstr;
2414 :
2415 : Word32 *invTrfMatrix_fx, *E_fx;
2416 : Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
2417 : Word32 v_fx[32], gain_fx, e_fx, temp;
2418 : Word16 w_fx[32], indices[32], exp[32];
2419 : Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC];
2420 : Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN];
2421 : Word16 v_e, gain_q_offset, preemph_fac;
2422 : Word16 i, index;
2423 :
2424 1954 : gain_q_offset = GAIN_Q_OFFSET_IVAS_FX_Q0;
2425 1954 : move16();
2426 :
2427 1954 : if ( st->element_mode == EVS_MONO )
2428 : {
2429 0 : gain_q_offset = GAIN_Q_OFFSET_EVS_FX_Q0;
2430 0 : move16();
2431 : }
2432 :
2433 1954 : preemph_fac = st->preemph_fac; // Q15
2434 1954 : move16();
2435 :
2436 : /* Init */
2437 1954 : N = hFdCngEnc->npartDec;
2438 1954 : move16();
2439 :
2440 1954 : E_fx = hFdCngEnc->msNoiseEst_fx;
2441 :
2442 1954 : invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */
2443 :
2444 1954 : set_zero_fx( v_fx, FDCNG_VQ_MAX_LEN );
2445 :
2446 : /* Convert to LOG */
2447 1954 : e_fx = 0;
2448 1954 : move32();
2449 47326 : FOR( i = 0; i < N; i++ )
2450 : {
2451 45372 : IF( E_fx[i] == 0 )
2452 : {
2453 : /* 10 * log(1e-4) = 10 * (-4) = -40 */
2454 4 : v_fx[i] = -41943040; // -40.0 in Q20
2455 4 : move32();
2456 : }
2457 : ELSE
2458 : {
2459 45368 : v_fx[i] = Mpy_32_32( 671088640 /*10 in Q26*/, BASOP_Util_Log10( E_fx[i], hFdCngEnc->msNoiseEst_fx_exp ) ); // Q20 = 26+25-31
2460 45368 : move32();
2461 : }
2462 45372 : e_fx = L_add( e_fx, v_fx[i] ); // Q20
2463 : }
2464 :
2465 : /* Normalize MSVQ input */
2466 1954 : gain_fx = 0;
2467 1954 : move32();
2468 27356 : FOR( i = N_GAIN_MIN; i < N_GAIN_MAX; i++ )
2469 : {
2470 25402 : gain_fx = L_add( gain_fx, v_fx[i] ); // Q20
2471 : }
2472 :
2473 : /*gain /= (float) ( N_GAIN_MAX - N_GAIN_MIN );*/
2474 1954 : gain_fx = Mpy_32_32( gain_fx, 165191050 /* 1/13 in Q31*/ ); // Q20
2475 :
2476 47326 : FOR( i = 0; i < N; i++ )
2477 : {
2478 45372 : v_fx[i] = L_sub( v_fx[i], gain_fx ); // Q20
2479 45372 : move32();
2480 : }
2481 :
2482 1954 : v_e = 11; // Q20
2483 1954 : move16();
2484 :
2485 : /* MSVQ encoder */
2486 1954 : set_val_Word16( w_fx, ONE_IN_Q8, N );
2487 :
2488 1954 : IF( st->element_mode != EVS_MONO )
2489 : {
2490 : /* DCT domain compressed/truncated indices used for first stage */
2491 : /* quantization with stage1 stored in DCT24 domain, stages 2 through 6 directly dearched
2492 : in FDCNG band domain
2493 : */
2494 1954 : IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) )
2495 : {
2496 : /* truncated DCT21 analysis */
2497 508 : create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31
2498 :
2499 508 : dctT2_N_apply_matrix_fx( v_fx /*Q20*/, dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX ); // Q20
2500 :
2501 : /* truncated IDCT21 extension to 24 bands */
2502 508 : extend_dctN_input_fx( v_fx, dct_target_fx, N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); // Q20
2503 :
2504 508 : Copy32( tot_sig_ext_fx, v_fx, FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 */ // Q20
2505 : }
2506 :
2507 1954 : create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) ); // Q31
2508 :
2509 1954 : msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices );
2510 :
2511 1954 : msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 1, invTrfMatrix_fx, v_fx, NULL, 7 );
2512 :
2513 1954 : v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) );
2514 : }
2515 : ELSE
2516 : { /* EVS_MONO tables */
2517 0 : msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, v_fx, v_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, w_fx, N, FD_CNG_maxN_37bits, 0, NULL, indices );
2518 :
2519 0 : msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N, FD_CNG_maxN_37bits, indices, 0, NULL, v_fx, NULL, 7 );
2520 :
2521 0 : v_e = sub( 31, sub( 20, find_guarded_bits_fx( N ) ) );
2522 : }
2523 :
2524 : /* Compute gain */
2525 1954 : gain_fx = 0;
2526 1954 : move32();
2527 47326 : FOR( i = 0; i < N; i++ )
2528 : {
2529 45372 : gain_fx = L_add( gain_fx, v_fx[i] ); // Q = 31 - v_e
2530 : }
2531 :
2532 1954 : e_fx = L_shl( e_fx, sub( 11, v_e ) ); // Q = 31 - v_e
2533 1954 : gain_fx = Mpy_32_16_1( L_sub( e_fx, gain_fx ), div_s( 1, N ) ); // Q = 31 - v_e
2534 1954 : gain_fx = L_shl( gain_fx, sub( v_e, 8 ) ); // Q23
2535 :
2536 : /* Apply bitrate-dependant scale */
2537 1954 : IF( st->element_mode > EVS_MONO )
2538 : {
2539 1954 : apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
2540 : }
2541 : ELSE
2542 : {
2543 0 : apply_scale( &gain_fx, hFdCngCom->CngBandwidth, hFdCngCom->CngBitrate, scaleTableMono, SIZE_SCALE_TABLE_MONO );
2544 : }
2545 :
2546 : /* Quantize gain */
2547 1954 : temp = Madd_32_32( L_shl( gain_q_offset, 22 ), gain_fx, 1610612736 /*1.5 in Q30*/ ); // Q22
2548 1954 : index = extract_l( L_shr( L_add( temp, ONE_IN_Q21 ), 22 ) ); // Q0
2549 :
2550 1954 : if ( index < 0 )
2551 : {
2552 364 : index = 0;
2553 364 : move16();
2554 : }
2555 :
2556 1954 : if ( GT_16( index, 127 ) )
2557 : {
2558 0 : index = 127;
2559 0 : move16();
2560 : }
2561 :
2562 1954 : gain_fx = L_shl( L_mult0( sub( index, gain_q_offset ), 21845 /*1.5 in Q15*/ ), sub( 16, v_e ) ); // Q = 31-v_e
2563 :
2564 : /* Apply gain and undo log */
2565 47326 : FOR( i = 0; i < N; i++ )
2566 : {
2567 45372 : temp = Mpy_32_32( L_add( v_fx[i], gain_fx ), 214748365 /* 0.1 in Q31*/ ); // Q = 31-v_e
2568 45372 : hFdCngCom->sidNoiseEst[i] = BASOP_Util_fPow( 10, 31, temp, v_e, &exp[i] );
2569 45372 : move32();
2570 : }
2571 :
2572 1954 : maximum_s( exp, N, &hFdCngCom->sidNoiseEstExp );
2573 :
2574 47326 : FOR( i = 0; i < N; i++ )
2575 : {
2576 45372 : hFdCngCom->sidNoiseEst[i] = L_shr( hFdCngCom->sidNoiseEst[i], sub( hFdCngCom->sidNoiseEstExp, exp[i] ) ); // exp = hFdCngCom->sidNoiseEstExp
2577 45372 : move32();
2578 : }
2579 :
2580 : /* NB last band energy compensation */
2581 1954 : IF( hFdCngCom->CngBandwidth == NB )
2582 : {
2583 0 : hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], NB_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp)
2584 0 : move32();
2585 : }
2586 :
2587 1954 : test();
2588 1954 : IF( EQ_16( hFdCngCom->CngBandwidth, SWB ) && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) )
2589 : {
2590 767 : hFdCngCom->sidNoiseEst[N - 1] = Mpy_32_16_1( hFdCngCom->sidNoiseEst[N - 1], SWB_13k2_LAST_BAND_SCALE ); // exp(hFdCngCom->sidNoiseEstExp)
2591 767 : move32();
2592 : }
2593 :
2594 : /* Write bitstream */
2595 1954 : IF( EQ_16( st->codec_mode, MODE2 ) )
2596 : {
2597 0 : FOR( i = 0; i < FD_CNG_stages_37bits; i++ )
2598 : {
2599 0 : push_next_indice( hBstr, indices[i], bits_37bits[i] );
2600 : }
2601 :
2602 0 : push_next_indice( hBstr, index, 7 );
2603 : }
2604 : ELSE
2605 : {
2606 1954 : Word16 is_frame_len_16k = 0;
2607 1954 : move16();
2608 1954 : if ( EQ_16( st->L_frame, L_FRAME16k ) )
2609 : {
2610 844 : is_frame_len_16k = 1;
2611 844 : move16();
2612 : }
2613 1954 : push_indice( hBstr, IND_SID_TYPE, 1, 1 );
2614 1954 : push_indice( hBstr, IND_BWIDTH, st->bwidth, 2 );
2615 1954 : push_indice( hBstr, IND_ACELP_16KHZ, is_frame_len_16k, 1 );
2616 :
2617 13678 : FOR( i = 0; i < FD_CNG_stages_37bits; i++ )
2618 : {
2619 11724 : push_indice( hBstr, IND_LSF, indices[i], bits_37bits[i] );
2620 : }
2621 :
2622 1954 : push_indice( hBstr, IND_ENERGY, index, 7 );
2623 : }
2624 :
2625 : /* Interpolate the bin/band-wise levels from the partition levels */
2626 1954 : scalebands( hFdCngCom->sidNoiseEst, hFdCngEnc->partDec, hFdCngEnc->npartDec, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 );
2627 1954 : hFdCngCom->cngNoiseLevelExp = hFdCngCom->sidNoiseEstExp;
2628 1954 : move16();
2629 :
2630 1954 : lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, preemph_fac );
2631 :
2632 1954 : return;
2633 : }
2634 :
2635 :
2636 : /*-------------------------------------------------------------------*
2637 : * stereoFdCngCoherence()
2638 : *
2639 : * compute coherence of channels for use in FD-CNG
2640 : *-------------------------------------------------------------------*/
2641 18228 : void stereoFdCngCoherence_fx(
2642 : Encoder_State **sts, /* i/o: core encoder structures */
2643 : const Word16 last_element_mode, /* i : last element mode Q0*/
2644 : Word16 fft_buf_fx[CPE_CHANNELS][2 * L_FFT], /* i : fft buffers for L and R channels fft_exp*/
2645 : Word16 fft_exp )
2646 : {
2647 : const Word16 *pt_fftL, *pt_fftR;
2648 : Word16 i_subfr, i;
2649 : Word32 cr, ci, eL, eR;
2650 : Word16 cr_exp, ci_exp, eL_exp, eR_exp;
2651 : Word32 *mem;
2652 : Word16 *mem_exp;
2653 :
2654 18228 : IF( NE_16( last_element_mode, IVAS_CPE_MDCT ) )
2655 : {
2656 63 : set32_fx( sts[0]->hFdCngEnc->mem_coherence_fx, EPSILON_FX, 4 );
2657 63 : set16_fx( sts[0]->hFdCngEnc->mem_coherence_exp, 0, 4 );
2658 : }
2659 18228 : test();
2660 18228 : test();
2661 18228 : IF( EQ_32( sts[0]->core_brate, -1 ) || EQ_32( sts[1]->core_brate, -1 ) )
2662 : {
2663 : /* case: at least one channel has triggered VAD -> ACTIVE FRAME */
2664 14492 : IF( EQ_32( sts[0]->core_brate, -1 ) )
2665 : {
2666 13972 : sts[1]->total_brate = sts[0]->total_brate; /* Q0 */
2667 13972 : move32();
2668 13972 : sts[1]->active_cnt = sts[0]->active_cnt; /* Q0 */
2669 13972 : move16();
2670 13972 : if ( GE_32( sts[1]->active_cnt, CNG_TYPE_HO ) )
2671 : {
2672 12840 : sts[1]->last_total_brate_cng = -1;
2673 12840 : move16();
2674 : }
2675 : }
2676 14492 : IF( EQ_32( sts[1]->core_brate, -1 ) )
2677 : {
2678 13679 : sts[0]->total_brate = sts[1]->total_brate; /* Q0 */
2679 13679 : move32();
2680 13679 : sts[0]->active_cnt = sts[1]->active_cnt; /* Q0 */
2681 13679 : move16();
2682 13679 : if ( GE_16( sts[0]->active_cnt, CNG_TYPE_HO ) )
2683 : {
2684 12589 : sts[0]->last_total_brate_cng = -1;
2685 12589 : move16();
2686 : }
2687 : }
2688 14492 : sts[0]->core_brate = -1;
2689 14492 : move32();
2690 14492 : sts[1]->core_brate = -1;
2691 14492 : move32();
2692 14492 : sts[0]->hDtxEnc->cnt_SID = 0;
2693 14492 : move16();
2694 14492 : sts[1]->hDtxEnc->cnt_SID = 0;
2695 14492 : move16();
2696 : }
2697 3736 : ELSE IF( LE_32( sts[0]->core_brate, SID_2k40 ) && LE_32( sts[1]->core_brate, SID_2k40 ) )
2698 : {
2699 : /* case: no VAD for both channels -> INACTIVE FRAME */
2700 3736 : reset_indices_enc_fx( sts[0]->hBstr, sts[0]->hBstr->nb_ind_tot );
2701 :
2702 3736 : reset_indices_enc_fx( sts[1]->hBstr, sts[1]->hBstr->nb_ind_tot );
2703 :
2704 : /* synchronize SID sending for variable SID rate */
2705 3736 : IF( NE_32( sts[0]->core_brate, sts[1]->core_brate ) )
2706 : {
2707 0 : sts[0]->core_brate = SID_2k40;
2708 0 : move32();
2709 0 : sts[1]->core_brate = SID_2k40;
2710 0 : move32();
2711 : }
2712 :
2713 : /* synchronize SID counters */
2714 3736 : sts[0]->hDtxEnc->cnt_SID = s_min( sts[0]->hDtxEnc->cnt_SID, sts[1]->hDtxEnc->cnt_SID ); /* Q0 */
2715 3736 : sts[1]->hDtxEnc->cnt_SID = sts[0]->hDtxEnc->cnt_SID; /* Q0 */
2716 3736 : move16();
2717 3736 : move16();
2718 : }
2719 :
2720 18228 : pt_fftL = fft_buf_fx[0];
2721 18228 : pt_fftR = fft_buf_fx[1];
2722 18228 : mem = sts[0]->hFdCngEnc->mem_coherence_fx; /* exp(sts[0]->hFdCngEnc->mem_coherence_exp) */
2723 18228 : mem_exp = sts[0]->hFdCngEnc->mem_coherence_exp;
2724 54684 : FOR( i_subfr = 0; i_subfr < 2; i_subfr++ )
2725 : {
2726 36456 : cr = ci = eL = eR = EPSILON_FX;
2727 36456 : move32();
2728 36456 : move32();
2729 36456 : move32();
2730 36456 : move32();
2731 36456 : cr_exp = ci_exp = eL_exp = eR_exp = 0;
2732 36456 : move16();
2733 36456 : move16();
2734 36456 : move16();
2735 36456 : move16();
2736 :
2737 36456 : cr = BASOP_Util_Add_Mant32Exp( cr, cr_exp, L_add( L_mult( pt_fftL[0], pt_fftR[0] ), L_mult( pt_fftL[L_FFT / 2], pt_fftR[L_FFT / 2] ) ), shl( fft_exp, 1 ), &cr_exp ); /* exp(cr_exp) */
2738 36456 : eL = BASOP_Util_Add_Mant32Exp( eL, eL_exp, L_add( L_mult( pt_fftL[0], pt_fftL[0] ), L_mult( pt_fftL[L_FFT / 2], pt_fftL[L_FFT / 2] ) ), shl( fft_exp, 1 ), &eL_exp ); /* exp(eL_exp) */
2739 36456 : eR = BASOP_Util_Add_Mant32Exp( eR, eR_exp, L_add( L_mult( pt_fftR[0], pt_fftR[0] ), L_mult( pt_fftR[L_FFT / 2], pt_fftR[L_FFT / 2] ) ), shl( fft_exp, 1 ), &eR_exp ); /* exp(eR_exp) */
2740 :
2741 4666368 : FOR( i = 1; i < L_FFT / 2; i++ )
2742 : {
2743 4629912 : cr = BASOP_Util_Add_Mant32Exp( cr, cr_exp, L_add( L_mult( pt_fftL[i], pt_fftR[i] ), L_mult( pt_fftL[L_FFT - i], pt_fftR[L_FFT - i] ) ), shl( fft_exp, 1 ), &cr_exp ); /* exp(cr_exp) */
2744 4629912 : ci = BASOP_Util_Add_Mant32Exp( ci, ci_exp, L_add( L_mult( -pt_fftL[i], pt_fftR[L_FFT - i] ), L_mult( pt_fftL[L_FFT - i], pt_fftR[i] ) ), shl( fft_exp, 1 ), &ci_exp ); /* exp(ci_exp) */
2745 4629912 : eL = BASOP_Util_Add_Mant32Exp( eL, eL_exp, L_add( L_mult( pt_fftL[i], pt_fftL[i] ), L_mult( pt_fftL[L_FFT - i], pt_fftL[L_FFT - i] ) ), shl( fft_exp, 1 ), &eL_exp ); /* exp(eL_exp) */
2746 4629912 : eR = BASOP_Util_Add_Mant32Exp( eR, eR_exp, L_add( L_mult( pt_fftR[i], pt_fftR[i] ), L_mult( pt_fftR[L_FFT - i], pt_fftR[L_FFT - i] ) ), shl( fft_exp, 1 ), &eR_exp ); /* exp(eR_exp) */
2747 : }
2748 36456 : test();
2749 36456 : test();
2750 36456 : IF( LE_32( sts[0]->ini_frame, 50 ) || ( sts[0]->vad_flag == 0 && sts[1]->vad_flag == 0 ) )
2751 : {
2752 12666 : mem[0] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[0], 31129 /*0.95f*/ ), mem_exp[0], Mpy_32_16_1( cr, 1638 /*0.05f*/ ), cr_exp, &mem_exp[0] ); /* exp(mem_exp[0]) */
2753 12666 : move32();
2754 12666 : mem[1] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[1], 31129 /*0.95f*/ ), mem_exp[1], Mpy_32_16_1( ci, 1638 /*0.05f*/ ), ci_exp, &mem_exp[1] ); /* exp(mem_exp[1]) */
2755 12666 : move32();
2756 12666 : mem[2] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[2], 31129 /*0.95f*/ ), mem_exp[2], Mpy_32_16_1( eL, 1638 /*0.05f*/ ), eL_exp, &mem_exp[2] ); /* exp(mem_exp[2]) */
2757 12666 : move32();
2758 12666 : mem[3] = BASOP_Util_Add_Mant32Exp( Mpy_32_16_1( mem[3], 31129 /*0.95f*/ ), mem_exp[3], Mpy_32_16_1( eR, 1638 /*0.05f*/ ), eR_exp, &mem_exp[3] ); /* exp(mem_exp[3]) */
2759 12666 : move32();
2760 : }
2761 :
2762 36456 : pt_fftL += L_FFT;
2763 36456 : pt_fftR += L_FFT;
2764 : }
2765 :
2766 : Word16 sqr_inp, temp, sqr_out, sqr_inp_exp;
2767 18228 : Word32 sqr_inp32 = BASOP_Util_Add_Mant32Exp( Mpy_32_32( mem[0], mem[0] ), shl( mem_exp[0], 1 ), Mpy_32_32( mem[1], mem[1] ), shl( mem_exp[1], 1 ), &sqr_inp_exp ); /* exp(sqr_inp_exp) */
2768 18228 : sqr_inp = BASOP_Util_Divide3232_Scale( sqr_inp32, Mpy_32_32( mem[2], mem[3] ), &temp );
2769 18228 : sqr_inp_exp = add( temp, sub( sqr_inp_exp, add( mem_exp[2], mem_exp[3] ) ) );
2770 18228 : sqr_out = Sqrt16( sqr_inp, &sqr_inp_exp );
2771 18228 : sts[0]->hFdCngEnc->hFdCngCom->coherence_fx = shl_sat( sqr_out, sqr_inp_exp ); // Q15 expected.
2772 18228 : move16();
2773 18228 : return;
2774 : }
2775 :
2776 : /*-------------------------------------------------------------------*
2777 : * FdCngEncodeMDCTStereoSID()
2778 : *
2779 : * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX
2780 : *-------------------------------------------------------------------*/
2781 :
2782 416 : void FdCngEncodeMDCTStereoSID_fx(
2783 : CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */
2784 : )
2785 : {
2786 : ENC_CORE_HANDLE sts[CPE_CHANNELS];
2787 : Word16 indices[CPE_CHANNELS][FD_CNG_stages_37bits];
2788 : Word16 gain_idx[CPE_CHANNELS];
2789 : Word16 N, stages, ch, p, coh_idx;
2790 : Word32 *lr_in_ptr_fx[CPE_CHANNELS];
2791 : Word16 lr_in_ptr_e[CPE_CHANNELS];
2792 : Word32 *ms_ptr_fx[CPE_CHANNELS];
2793 : Word16 ms_ptr_e;
2794 : Word32 *lr_out_ptr_fx[CPE_CHANNELS];
2795 : Word16 lr_out_ptr_e[CPE_CHANNELS];
2796 : Word32 logNoiseEst_fx[CPE_CHANNELS][NPART];
2797 : Word32 E_fx[CPE_CHANNELS];
2798 : Word32 gain_fx[CPE_CHANNELS];
2799 : Word16 weights_fx[NPART];
2800 : Word32 side_energy_fx;
2801 : Word16 Qside_energy;
2802 : Word32 *invTrfMatrix_fx;
2803 : Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC]; /*24*18*/
2804 416 : invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */
2805 : Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN], dct_target_fx[CPE_CHANNELS][FDCNG_VQ_DCT_MAXTRUNC]; /* 24 +2*18*/
2806 : Word16 tmp, tmp_e;
2807 : Word16 no_side_flag;
2808 : Word16 is_inp_ms;
2809 : Word16 size_value, temp_e, gb, shift;
2810 : Word32 tmp32, t1, t2;
2811 :
2812 416 : is_inp_ms = 0;
2813 416 : move16();
2814 416 : IF( EQ_16( hCPE->hCoreCoder[0]->cng_sba_flag, 1 ) )
2815 : {
2816 0 : is_inp_ms = 1;
2817 0 : move16();
2818 : }
2819 :
2820 : /* set pointers and initialize */
2821 1248 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
2822 : {
2823 832 : sts[ch] = hCPE->hCoreCoder[ch];
2824 832 : lr_in_ptr_fx[ch] = &sts[ch]->hFdCngEnc->msNoiseEst_fx[0]; /* exp(sts[ch]->hFdCngEnc->msNoiseEst_fx_exp) */
2825 832 : lr_in_ptr_e[ch] = sts[ch]->hFdCngEnc->msNoiseEst_fx_exp;
2826 832 : ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0];
2827 832 : lr_out_ptr_fx[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0]; /* exp(sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp) */
2828 832 : lr_out_ptr_e[ch] = sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp;
2829 : }
2830 416 : N = sts[0]->hFdCngEnc->npartDec; /* Q0 */
2831 416 : move16();
2832 416 : set16_fx( weights_fx, ONE_IN_Q8, NPART );
2833 :
2834 : /* apply log and save energy of original left and right channels */
2835 1248 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
2836 : {
2837 : // E[ch] = 0.0f;
2838 832 : E_fx[ch] = 0;
2839 832 : move32();
2840 19810 : FOR( p = 0; p < N; p++ )
2841 : {
2842 18978 : IF( lr_in_ptr_fx[ch][p] )
2843 : {
2844 18978 : t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] ); // Q25
2845 18978 : t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) ); // Q25
2846 18978 : ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23
2847 18978 : move32();
2848 : }
2849 : ELSE
2850 : {
2851 : // 10.f * log10f( EPSILON ) --> -150.0f
2852 : // Subsequent additions / subtractions happen on these numbers, so to avoid saturations
2853 : // this value is set to -128.0f in Q23
2854 0 : ms_ptr_fx[ch][p] = -ONE_IN_Q30; // Q23
2855 0 : move32();
2856 : }
2857 18978 : E_fx[ch] = L_add( E_fx[ch], L_shr( ms_ptr_fx[ch][p], 4 ) ); // Q19
2858 18978 : move32();
2859 : }
2860 : }
2861 416 : ms_ptr_e = Q31 - Q23;
2862 416 : move16();
2863 :
2864 : /* M/S transform on log envelopes */
2865 416 : IF( is_inp_ms == 0 )
2866 : {
2867 416 : convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 ); // ms_ptr_e = Q23;
2868 : }
2869 :
2870 416 : gb = find_guarded_bits_fx( N );
2871 416 : side_energy_fx = sum2_f_32_fx( ms_ptr_fx[1], N, gb );
2872 416 : Qside_energy = sub( sub( shl( sub( 31, ms_ptr_e ), 1 ), 31 ), gb );
2873 :
2874 : /* do not transmit side shape if initial noise shapes are very similar */
2875 416 : IF( LE_32( side_energy_fx, L_shl( 214748365, sub( Qside_energy, Q31 ) ) ) )
2876 : {
2877 11 : no_side_flag = 1;
2878 11 : move16();
2879 : }
2880 : ELSE
2881 : {
2882 405 : no_side_flag = 0;
2883 405 : move16();
2884 : }
2885 :
2886 : /* Quantize noise shapes */
2887 1248 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
2888 : {
2889 : /* Normalize MSVQ input */
2890 832 : gain_fx[ch] = 0;
2891 832 : move32();
2892 11648 : FOR( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ )
2893 : {
2894 10816 : tmp32 = Mpy_32_32( ms_ptr_fx[ch][p], 165191050 /* 0.07 in Q31*/ ); // Q23
2895 10816 : gain_fx[ch] = L_add( gain_fx[ch], tmp32 ); // Q23
2896 10816 : move32();
2897 : }
2898 :
2899 19810 : FOR( p = 0; p < N; p++ )
2900 : {
2901 18978 : ms_ptr_fx[ch][p] = L_sub( ms_ptr_fx[ch][p], gain_fx[ch] ); // Q23
2902 18978 : move32();
2903 : }
2904 : }
2905 :
2906 : /* always split channel targetloop */
2907 :
2908 : /* extend fdcng envelope from length 21 to a 24 length fdncg domain envelope signal */
2909 : /* High quality cosine smooth basis extension used to not introduce noise in stage#1 DCT24 analysis and subsequent VQ-steps */
2910 416 : IF( EQ_16( N, FDCNG_VQ_MAX_LEN_WB ) )
2911 : {
2912 165 : size_value = BASOP_Util_Divide1616_Scale( sizeof( tmpRAM_fx ), ( sizeof( Word32 ) ), &temp_e ); /*Q15*/
2913 165 : size_value = shr( size_value, sub( 15, temp_e ) );
2914 165 : create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N, FDCNG_VQ_DCT_MAXTRUNC, size_value ); // Q31 /*WB: create truncated IDCT21 matrix */
2915 495 : for ( ch = 0; ch < CPE_CHANNELS; ch++ )
2916 : {
2917 : /* run DCT_N N==21 , truncated at 18/21 ~= 86% , i.e use a bit better better quality in extrapolation , than subsequent DCT24 analysis which is truncated at 75%*/
2918 : /* truncated DCT 21 analysis */
2919 330 : dctT2_N_apply_matrix_fx( (const Word32 *) ms_ptr_fx[ch], dct_target_fx[ch], FDCNG_VQ_DCT_MAXTRUNC, N, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX );
2920 : /* extrapolate extend fdcng envelope signal in the fdncg ienvelope/"time" domain using DCT21 basis vectors,
2921 : estimated DCT21 coeffs scaling extended basis vectors are used to create extrapolated length 24 input target envelope signal */
2922 : /* this DCT21 extension does not introduce DCT24 coefficient noise for the subsequent dct24 target analysis, and later in IDCT24 synthesis */
2923 :
2924 : /* truncated IDCT 21 extension synthesis */
2925 330 : extend_dctN_input_fx( ms_ptr_fx[ch], dct_target_fx[ch], N, tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx /* DCT_N basis vectors */, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/
2926 :
2927 330 : Copy32( tot_sig_ext_fx, ms_ptr_fx[ch], FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ */
2928 : }
2929 : }
2930 :
2931 416 : size_value = BASOP_Util_Divide1616_Scale( sizeof( tmpRAM_fx ), ( sizeof( Word32 ) ), &temp_e ); /*Q15*/
2932 416 : size_value = shr( size_value, sub( 15, temp_e ) );
2933 416 : create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, size_value ); /*always create/set up IDCT24 matrix in RAM */
2934 :
2935 : /* end split */
2936 1248 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
2937 : {
2938 : /* MSVQ */
2939 832 : IF( ch )
2940 : {
2941 416 : stages = FD_CNG_JOINT_stages_25bits;
2942 416 : move16();
2943 : }
2944 : ELSE
2945 : {
2946 416 : stages = FD_CNG_stages_37bits;
2947 416 : move16();
2948 : }
2949 :
2950 : /* DCT24 domain compressed/truncated indices used for first stage */
2951 : /* mid channel quantization using stages 1 through 6 */
2952 : /* & side channel quantization using stages 1 through 4 */
2953 :
2954 : {
2955 832 : msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, ms_ptr_fx[ch], ms_ptr_e, levels_37bits, FD_CNG_maxC_37bits, stages, weights_fx, N, FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices[ch] );
2956 832 : msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, stages, N, FD_CNG_maxN_37bits, indices[ch], 1, invTrfMatrix_fx, ms_ptr_fx[ch], NULL, 7 );
2957 : }
2958 : }
2959 416 : shift = find_guarded_bits_fx( N );
2960 416 : ms_ptr_e = sub( 31, sub( 20, shift ) );
2961 :
2962 416 : IF( no_side_flag )
2963 : {
2964 11 : set32_fx( ms_ptr_fx[1], 0, N );
2965 : }
2966 :
2967 : /* undo M/S */
2968 416 : IF( is_inp_ms == 0 )
2969 : {
2970 416 : convertToMS_fx( N, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 );
2971 : }
2972 :
2973 : /* Compute gain against original left and right channels */
2974 1248 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
2975 : {
2976 832 : gain_fx[ch] = 0;
2977 832 : move32();
2978 :
2979 832 : tmp_e = 15;
2980 832 : move16();
2981 832 : tmp = Inv16( N, &tmp_e );
2982 19810 : FOR( p = 0; p < N; p++ )
2983 : {
2984 18978 : gain_fx[ch] = L_add( gain_fx[ch], Mpy_32_16_1( ms_ptr_fx[ch][p], shl( tmp, tmp_e ) ) ); // Q23
2985 18978 : move32();
2986 : }
2987 832 : gain_fx[ch] = L_sub( L_shl( Mpy_32_16_1( E_fx[ch], shl( tmp, tmp_e ) ), Q23 - Q19 ), L_shl( gain_fx[ch], sub( ms_ptr_e, 8 ) ) ); // Q23
2988 832 : move32();
2989 :
2990 832 : apply_scale( &gain_fx[ch], sts[ch]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[ch]->element_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
2991 :
2992 : /* quantize gain */
2993 832 : gain_idx[ch] = (Word16) Mpy_32_32_r( L_add( gain_fx[ch], 251658240 ), 384 ); // Q23
2994 832 : move16();
2995 832 : gain_idx[ch] = s_max( 0, s_min( 127, gain_idx[ch] ) );
2996 832 : move16();
2997 :
2998 832 : gain_fx[ch] = Mpy_32_16_1( L_shl( sub( gain_idx[ch], GAIN_Q_OFFSET_IVAS_FX_Q0 ), 23 ), 21845 ); // Q23
2999 832 : move32();
3000 : }
3001 :
3002 : /* restore channel noise envelopes */
3003 1248 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
3004 : {
3005 832 : HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc;
3006 832 : HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
3007 :
3008 832 : tmp_e = 0;
3009 832 : move16();
3010 : Word32 pow;
3011 :
3012 : Word16 e_lr_out[NPART];
3013 :
3014 19810 : FOR( p = 0; p < N; p++ )
3015 : {
3016 18978 : pow = L_shl( gain_fx[ch], 8 - ms_ptr_e );
3017 18978 : pow = L_add( ms_ptr_fx[ch][p], pow );
3018 18978 : pow = Mpy_32_32( pow, 214748365 ); /*pow = 0.1*/
3019 18978 : lr_out_ptr_fx[ch][p] = BASOP_Util_fPow( 10, 31, pow, ms_ptr_e, &e_lr_out[p] );
3020 18978 : move32();
3021 18978 : tmp_e = s_max( tmp_e, e_lr_out[p] );
3022 : }
3023 :
3024 19810 : FOR( p = 0; p < N; p++ )
3025 : {
3026 18978 : lr_out_ptr_fx[ch][p] = L_shl( lr_out_ptr_fx[ch][p], e_lr_out[p] - tmp_e );
3027 18978 : move32();
3028 : }
3029 832 : lr_out_ptr_e[ch] = tmp_e;
3030 832 : move32();
3031 :
3032 832 : sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp = tmp_e;
3033 832 : move16();
3034 :
3035 : /* scale bands and get scalefactors */
3036 832 : scalebands( lr_out_ptr_fx[ch], hFdCngEnc->partDec, N, hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 );
3037 832 : hFdCngCom->cngNoiseLevelExp = lr_out_ptr_e[ch];
3038 832 : move16();
3039 :
3040 832 : lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac );
3041 :
3042 832 : sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame;
3043 : }
3044 :
3045 : /* quantize channel coherence */
3046 416 : coh_idx = mult_r( sts[0]->hFdCngEnc->hFdCngCom->coherence_fx, 15 );
3047 416 : coh_idx = s_max( 0, s_min( coh_idx, 15 ) );
3048 :
3049 : /* ---- Write SID bitstream ---- */
3050 :
3051 :
3052 : /* noise shapes and channel gains */
3053 1248 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
3054 : {
3055 832 : IF( ch )
3056 : {
3057 416 : stages = FD_CNG_JOINT_stages_25bits;
3058 416 : sts[ch]->hBstr->ind_list = sts[0]->hBstr->ind_list + sts[0]->hBstr->nb_ind_tot;
3059 :
3060 : /* side info */
3061 416 : push_indice( sts[ch]->hBstr, IND_SID_TYPE, coh_idx, 4 );
3062 416 : push_indice( sts[ch]->hBstr, IND_SID_TYPE, no_side_flag, 1 );
3063 : }
3064 : ELSE
3065 : {
3066 416 : stages = FD_CNG_stages_37bits;
3067 : /* side info */
3068 416 : push_indice( sts[ch]->hBstr, IND_SID_TYPE, 1, 1 );
3069 416 : push_indice( sts[ch]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 );
3070 416 : push_indice( sts[ch]->hBstr, IND_ACELP_16KHZ, sts[0]->L_frame == L_FRAME16k ? 1 : 0, 1 );
3071 : }
3072 :
3073 4992 : FOR( Word16 i = 0; i < stages; i++ )
3074 : {
3075 4160 : push_indice( sts[ch]->hBstr, IND_LSF, indices[ch][i], bits_37bits[i] );
3076 : }
3077 832 : push_indice( sts[ch]->hBstr, IND_ENERGY, gain_idx[ch], 7 );
3078 : }
3079 :
3080 : /* pad with zeros to reach common SID frame size */
3081 416 : push_indice( sts[1]->hBstr, IND_ENERGY, 0, ( IVAS_SID_5k2 - 4400 ) / FRAMES_PER_SEC );
3082 :
3083 416 : return;
3084 : }
3085 :
3086 : /*-------------------------------------------------------------------*
3087 : * FdCngEncodeDiracMDCTStereoSID()
3088 : *
3089 : * Encode DTX parameters and noise shapes into SID for MDCT-Stereo DTX
3090 : * together with Dirac
3091 : *-------------------------------------------------------------------*/
3092 :
3093 123 : void FdCngEncodeDiracMDCTStereoSID_fx(
3094 : CPE_ENC_HANDLE hCPE /* i/o: CPE encoder state structure */
3095 : )
3096 : {
3097 : ENC_CORE_HANDLE sts[CPE_CHANNELS];
3098 : Word32 *lr_in_ptr_fx[CPE_CHANNELS];
3099 : Word16 lr_in_ptr_e[CPE_CHANNELS];
3100 : Word32 *ms_ptr_fx[CPE_CHANNELS];
3101 : Word16 ms_ptr_e;
3102 : Word32 *lr_out_ptr_fx[CPE_CHANNELS];
3103 : Word16 lr_out_ptr_e[CPE_CHANNELS];
3104 : Word32 logNoiseEst_fx[CPE_CHANNELS][NPART];
3105 : Word32 E_fx[CPE_CHANNELS];
3106 : Word32 gain_fx[CPE_CHANNELS];
3107 : Word16 weights_fx[NPART];
3108 : Word16 N[CPE_CHANNELS];
3109 : Word16 indices[CPE_CHANNELS][FD_CNG_stages_37bits];
3110 : Word16 gain_idx[CPE_CHANNELS];
3111 : Word16 ch, p;
3112 : Word16 tmp, tmp_e, shift;
3113 : Word32 *invTrfMatrix_fx;
3114 : Word32 tmpRAM_fx[FDCNG_VQ_MAX_LEN][FDCNG_VQ_DCT_MAXTRUNC];
3115 : Word32 dct_target_fx[FDCNG_VQ_DCT_MAXTRUNC];
3116 : Word32 tot_sig_ext_fx[FDCNG_VQ_MAX_LEN];
3117 123 : invTrfMatrix_fx = (Word32 *) tmpRAM_fx; /* dynamically filled */
3118 : Word32 t1, t2, tmp32;
3119 : /* set pointers and initialize */
3120 :
3121 369 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
3122 : {
3123 246 : sts[ch] = hCPE->hCoreCoder[ch];
3124 246 : N[ch] = sts[ch]->hFdCngEnc->npartDec;
3125 246 : lr_in_ptr_fx[ch] = &sts[ch]->hFdCngEnc->msNoiseEst_fx[0];
3126 246 : lr_in_ptr_e[ch] = sts[ch]->hFdCngEnc->msNoiseEst_fx_exp;
3127 246 : ms_ptr_fx[ch] = &logNoiseEst_fx[ch][0];
3128 246 : lr_out_ptr_fx[ch] = &sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEst[0];
3129 246 : lr_out_ptr_e[ch] = sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp;
3130 246 : move16();
3131 : }
3132 123 : set16_fx( weights_fx, ONE_IN_Q8, NPART );
3133 :
3134 : /* apply log and save energy of original left and right channels */
3135 369 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
3136 : {
3137 : // E[ch] = 0.0f;
3138 246 : E_fx[ch] = 0;
3139 246 : move32();
3140 6150 : FOR( p = 0; p < N[ch]; p++ )
3141 : {
3142 5904 : t1 = BASOP_Util_Log2( lr_in_ptr_fx[ch][p] + EPSILLON_FX ); // Q25
3143 5904 : t2 = L_add( t1, L_shl( lr_in_ptr_e[ch], Q25 ) ); // Q25
3144 5904 : ms_ptr_fx[ch][p] = Mpy_32_32( t2, TEN_MULT_LOG10_2_IN_Q29 ); // Q23
3145 5904 : move32();
3146 5904 : E_fx[ch] = L_add( E_fx[ch], L_shr( ms_ptr_fx[ch][p], 5 ) ); // Q18
3147 5904 : move32();
3148 : }
3149 : }
3150 123 : ms_ptr_e = Q31 - Q23;
3151 123 : move16();
3152 :
3153 : /* M/S transform on log envelopes */
3154 123 : convertToMS_fx( N[0], ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q30 );
3155 123 : E_fx[0] = 0;
3156 123 : move32();
3157 3075 : FOR( p = 0; p < N[0]; p++ )
3158 : {
3159 2952 : E_fx[0] = L_add( E_fx[0], L_shr( ms_ptr_fx[0][p], 5 ) ); // Q18
3160 2952 : move32();
3161 : }
3162 :
3163 : /* Quantize M noise shape */
3164 : /* Normalize MSVQ input */
3165 123 : gain_fx[0] = 0;
3166 123 : move16();
3167 1722 : FOR( p = N_GAIN_MIN; p < N_GAIN_MAX; p++ )
3168 : {
3169 1599 : tmp32 = Mpy_32_32( ms_ptr_fx[0][p], 165191050 /* 0.07 in Q31 */ ); // Q23
3170 1599 : gain_fx[0] = L_add( gain_fx[0], tmp32 ); // Q23
3171 1599 : move32();
3172 : }
3173 :
3174 3075 : FOR( p = 0; p < N[0]; p++ )
3175 : {
3176 2952 : ms_ptr_fx[0][p] = L_sub( ms_ptr_fx[0][p], gain_fx[0] ); // Q23
3177 2952 : move32();
3178 : }
3179 :
3180 :
3181 : /* MSVQ */
3182 : /* DCT domain compressed/truncated indices used for first stage */
3183 : /* mid quantization using stages #1 through 6 */
3184 123 : scale_sig32( ms_ptr_fx[0], N[0], -6 );
3185 123 : ms_ptr_e = add( ms_ptr_e, 6 );
3186 123 : move16();
3187 123 : IF( EQ_16( N[0], FDCNG_VQ_MAX_LEN_WB ) )
3188 : {
3189 0 : create_IDCT_N_Matrix_fx( invTrfMatrix_fx, N[0], FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) );
3190 : /* truncated DCT 21 analysis */
3191 0 : dctT2_N_apply_matrix_fx( (const Word32 *) ms_ptr_fx[0], dct_target_fx, FDCNG_VQ_DCT_MAXTRUNC, N[0], invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, DCT_T2_21_XX );
3192 : /* truncated IDCT21 extension to 24 synthesis */
3193 :
3194 0 : extend_dctN_input_fx( ms_ptr_fx[0], dct_target_fx, N[0], tot_sig_ext_fx, FDCNG_VQ_MAX_LEN, invTrfMatrix_fx, FDCNG_VQ_DCT_MAXTRUNC, IDCT_T2_XX_21 ); /* use 18 basis vectors*/
3195 :
3196 0 : Copy32( tot_sig_ext_fx, ms_ptr_fx[0], FDCNG_VQ_MAX_LEN ); /* write extended result as input to VQ stage #1 Q23*/
3197 : }
3198 123 : create_IDCT_N_Matrix_fx( invTrfMatrix_fx, FDCNG_VQ_MAX_LEN, FDCNG_VQ_DCT_MAXTRUNC, sizeof( tmpRAM_fx ) / ( sizeof( Word32 ) ) );
3199 :
3200 123 : msvq_enc_ivas_fx( ivas_cdk_37bits_fx, Q7, NULL, NULL, ms_ptr_fx[0], ms_ptr_e, levels_37bits, FD_CNG_maxC_37bits, FD_CNG_stages_37bits, weights_fx, N[0], FD_CNG_maxN_37bits, 1, invTrfMatrix_fx, indices[0] );
3201 123 : msvq_dec_fx( ivas_cdk_37bits_fx, NULL, NULL, FD_CNG_stages_37bits, N[0], FD_CNG_maxN_37bits, indices[0], 1, invTrfMatrix_fx, ms_ptr_fx[0], NULL, 7 );
3202 123 : shift = find_guarded_bits_fx( N[0] );
3203 123 : ms_ptr_e = sub( 31, sub( 20, shift ) );
3204 123 : scale_sig32( ms_ptr_fx[1], N[1], sub( 8, ms_ptr_e ) ); /* Q31 - ms_ptr_e */
3205 :
3206 : /* set S to zero */
3207 123 : set32_fx( ms_ptr_fx[1], 0, NPART );
3208 :
3209 : /* compute M gain */
3210 123 : gain_fx[0] = 0;
3211 123 : move32();
3212 123 : tmp_e = 15;
3213 123 : move16();
3214 123 : tmp = Inv16( N[0], &tmp_e );
3215 3075 : FOR( p = 0; p < N[0]; p++ )
3216 : {
3217 2952 : gain_fx[0] = L_add( gain_fx[0], Mpy_32_16_1( ms_ptr_fx[0][p], shl( tmp, tmp_e ) ) ); // Q23
3218 2952 : move32();
3219 : }
3220 123 : gain_fx[0] = L_sub( L_shl( Mpy_32_16_1( E_fx[0], shl( tmp, tmp_e ) ), Q23 - Q18 ), L_shl( gain_fx[0], ms_ptr_e - 8 ) ); // Q23
3221 123 : move32();
3222 :
3223 123 : apply_scale( &gain_fx[0], sts[0]->hFdCngEnc->hFdCngCom->CngBandwidth, sts[0]->hDtxEnc->last_active_brate, scaleTableStereo, SIZE_SCALE_TABLE_STEREO );
3224 :
3225 : /* quantize gain */
3226 123 : gain_idx[0] = extract_l( Mpy_32_32_r( L_add( gain_fx[0], 251658240 ), 384 ) );
3227 123 : move16();
3228 123 : gain_idx[0] = s_max( 0, s_min( 127, gain_idx[0] ) );
3229 123 : move16();
3230 :
3231 123 : gain_fx[0] = Mpy_32_16_1( L_shl( sub( gain_idx[0], GAIN_Q_OFFSET_IVAS_FX_Q0 ), 23 ), 21845 /* 0.66 in Q15 */ ); // Q23
3232 123 : move32();
3233 123 : gain_fx[1] = gain_fx[0]; // Q23
3234 123 : move32();
3235 :
3236 : /* undo M/S */
3237 123 : convertToMS_fx( NPART, ms_ptr_fx[0], ms_ptr_fx[1], ONE_IN_Q31 );
3238 :
3239 : /* restore channel noise envelopes */
3240 369 : FOR( ch = 0; ch < CPE_CHANNELS; ch++ )
3241 : {
3242 246 : HANDLE_FD_CNG_ENC hFdCngEnc = sts[ch]->hFdCngEnc;
3243 246 : HANDLE_FD_CNG_COM hFdCngCom = hFdCngEnc->hFdCngCom;
3244 :
3245 : Word32 pow;
3246 : Word16 e_lr_out[NPART];
3247 246 : tmp_e = -MAX_16;
3248 6150 : FOR( p = 0; p < N[ch]; p++ )
3249 : {
3250 5904 : pow = L_shl( gain_fx[ch], sub( 8, ms_ptr_e ) ); /* Q31 - ms_ptr_e */
3251 5904 : pow = L_add( ms_ptr_fx[ch][p], pow ); /* Q31 - ms_ptr_e */
3252 5904 : pow = Mpy_32_32( pow, 214748365 /* 0.1 in Q31 */ ); /*pow = 0.1 Q31 - ms_ptr_e*/
3253 5904 : lr_out_ptr_fx[ch][p] = BASOP_Util_fPow( 10, 31, pow, ms_ptr_e, &e_lr_out[p] );
3254 5904 : tmp_e = s_max( tmp_e, e_lr_out[p] );
3255 : }
3256 :
3257 6150 : FOR( p = 0; p < N[ch]; p++ )
3258 : {
3259 5904 : lr_out_ptr_fx[ch][p] = L_shl( lr_out_ptr_fx[ch][p], sub( e_lr_out[p], tmp_e ) ); // Q(31 - tmp_e)
3260 : }
3261 :
3262 246 : sts[ch]->hFdCngEnc->hFdCngCom->sidNoiseEstExp = tmp_e;
3263 246 : move16();
3264 246 : lr_out_ptr_e[ch] = tmp_e;
3265 246 : move16();
3266 :
3267 : /* NB last band energy compensation */
3268 246 : IF( hFdCngCom->CngBandwidth == NB )
3269 : {
3270 0 : lr_out_ptr_fx[ch][N[ch] - 1] = Mpy_32_16_1( lr_out_ptr_fx[ch][N[ch] - 1], NB_LAST_BAND_SCALE ); // Q(31 - tmp_e)
3271 0 : move32();
3272 : }
3273 246 : ELSE IF( hFdCngCom->CngBandwidth == SWB && LE_32( hFdCngCom->CngBitrate, ACELP_13k20 ) )
3274 : {
3275 0 : lr_out_ptr_fx[ch][N[ch] - 1] = Mpy_32_16_1( lr_out_ptr_fx[ch][N[ch] - 1], SWB_13k2_LAST_BAND_SCALE ); // Q(31 - tmp_e)
3276 0 : move32();
3277 : }
3278 : /* scale bands and get scalefactors */
3279 246 : scalebands( lr_out_ptr_fx[ch], hFdCngEnc->partDec, N[ch], hFdCngEnc->midbandDec, hFdCngEnc->nFFTpartDec, sub( hFdCngEnc->stopBandDec, hFdCngEnc->startBandDec ), hFdCngCom->cngNoiseLevel, 1 );
3280 246 : hFdCngCom->cngNoiseLevelExp = lr_out_ptr_e[ch];
3281 246 : move16();
3282 246 : lpc_from_spectrum( hFdCngCom, hFdCngEnc->startBandDec, hFdCngEnc->stopFFTbinDec, sts[ch]->preemph_fac );
3283 246 : sts[ch]->hDtxEnc->last_CNG_L_frame = sts[ch]->L_frame;
3284 : }
3285 123 : sts[0]->hFdCngEnc->hFdCngCom->coherence_fx = 0;
3286 123 : move16();
3287 123 : sts[1]->hFdCngEnc->hFdCngCom->coherence_fx = 0;
3288 123 : move16();
3289 :
3290 : /* ---- Write SID bitstream ---- */
3291 :
3292 : /* side info */
3293 123 : push_indice( sts[0]->hBstr, IND_SID_TYPE, 1, 1 );
3294 123 : push_indice( sts[0]->hBstr, IND_BWIDTH, sts[0]->bwidth, 2 );
3295 123 : IF( EQ_16( sts[0]->L_frame, L_FRAME16k ) )
3296 : {
3297 123 : push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, 1, 1 );
3298 : }
3299 : ELSE
3300 : {
3301 0 : push_indice( sts[0]->hBstr, IND_ACELP_16KHZ, 0, 1 );
3302 : }
3303 :
3304 : /* noise shapes and channel gains */
3305 861 : FOR( Word16 i = 0; i < FD_CNG_stages_37bits; i++ )
3306 : {
3307 738 : push_indice( sts[0]->hBstr, IND_LSF, indices[0][i], bits_37bits[i] );
3308 : }
3309 123 : push_indice( sts[0]->hBstr, IND_ENERGY, gain_idx[0], 7 );
3310 :
3311 123 : return;
3312 : }
|