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