Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include "ivas_cnst.h"
38 : #include <assert.h>
39 : #include <stdint.h>
40 : #include "options.h"
41 : #ifdef DEBUGGING
42 : #include "debug.h"
43 : #endif
44 : #include <math.h>
45 : #include "prot.h"
46 : #include "rom_com.h"
47 : #include "wmc_auto.h"
48 :
49 :
50 : /*-------------------------------------------------------------------
51 : * Local function prototypes
52 : *-------------------------------------------------------------------*/
53 :
54 : static void mhvals( const int16_t d, float *m );
55 :
56 : static void getmidbands( int16_t *part, const int16_t npart, int16_t *midband, float *psize, float *psize_inv );
57 :
58 :
59 : /*-------------------------------------------------------------------
60 : * createFdCngCom()
61 : *
62 : * Create an instance of type FD_CNG_COM
63 : *-------------------------------------------------------------------*/
64 :
65 623306 : ivas_error createFdCngCom(
66 : HANDLE_FD_CNG_COM *hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
67 : )
68 : {
69 : HANDLE_FD_CNG_COM hs;
70 :
71 : /* Allocate memory */
72 623306 : if ( ( hs = (HANDLE_FD_CNG_COM) malloc( sizeof( FD_CNG_COM ) ) ) == NULL )
73 : {
74 0 : return IVAS_ERROR( IVAS_ERR_FAILED_ALLOC, "Can not allocate memory for FD CNG COM" );
75 : }
76 :
77 623306 : *hFdCngCom = hs;
78 :
79 623306 : return IVAS_ERR_OK;
80 : }
81 :
82 :
83 : /*-------------------------------------------------------------------
84 : * initFdCngCom()
85 : *
86 : *
87 : *-------------------------------------------------------------------*/
88 :
89 623306 : void initFdCngCom(
90 : HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
91 : const float scale )
92 : {
93 : /* Calculate FFT scaling factor */
94 623306 : hFdCngCom->scalingFactor = 1 / ( scale * scale * 8.f );
95 :
96 : /* Initialize the overlap-add */
97 623306 : set_f( hFdCngCom->timeDomainBuffer, 0.0f, L_FRAME16k );
98 623306 : set_f( hFdCngCom->olapBufferAna, 0.0f, FFTLEN );
99 623306 : set_f( hFdCngCom->olapBufferSynth, 0.0f, FFTLEN );
100 623306 : set_f( hFdCngCom->olapBufferSynth2, 0.0f, FFTLEN );
101 :
102 : /* Initialize the comfort noise generation */
103 623306 : set_f( hFdCngCom->fftBuffer, 0.0f, FFTLEN );
104 623306 : set_f( hFdCngCom->cngNoiseLevel, 0.0f, FFTCLDFBLEN );
105 :
106 : /* Initialize quantizer */
107 623306 : set_f( hFdCngCom->sidNoiseEst, 0.0f, NPART );
108 623306 : set_f( hFdCngCom->A_cng, 0.0f, M + 1 );
109 623306 : hFdCngCom->A_cng[0] = 1.f;
110 :
111 : /* Set some counters and flags */
112 623306 : hFdCngCom->inactive_frame_counter = 0; /* Either SID or zero frames */
113 623306 : hFdCngCom->active_frame_counter = 0;
114 623306 : hFdCngCom->frame_type_previous = ACTIVE_FRAME;
115 623306 : hFdCngCom->flag_noisy_speech = 0;
116 623306 : hFdCngCom->likelihood_noisy_speech = 0.f;
117 623306 : hFdCngCom->numCoreBands = 0;
118 623306 : hFdCngCom->stopBand = 0;
119 623306 : hFdCngCom->startBand = 0;
120 623306 : hFdCngCom->stopFFTbin = 0;
121 623306 : hFdCngCom->frameSize = 0;
122 623306 : hFdCngCom->fftlen = 0;
123 623306 : hFdCngCom->seed = 0;
124 623306 : hFdCngCom->seed2 = 1;
125 623306 : hFdCngCom->seed3 = 2;
126 623306 : hFdCngCom->CngBitrate = -1;
127 :
128 : /* Initialize noise estimation algorithm */
129 623306 : set_f( hFdCngCom->periodog, 0.0f, PERIODOGLEN );
130 623306 : mhvals( MSNUMSUBFR * MSSUBFRLEN, &( hFdCngCom->msM_win ) );
131 623306 : mhvals( MSSUBFRLEN, &( hFdCngCom->msM_subwin ) );
132 623306 : set_f( hFdCngCom->msPeriodogSum, 0.0f, 2 );
133 623306 : set_f( hFdCngCom->msPsdSum, 0.0f, 2 );
134 623306 : set_f( hFdCngCom->msSlope, 0.0f, 2 );
135 623306 : set_f( hFdCngCom->msQeqInvAv, 0.0f, 2 );
136 623306 : hFdCngCom->msFrCnt_init_counter = 0;
137 623306 : hFdCngCom->msFrCnt_init_thresh = 1;
138 623306 : hFdCngCom->init_old = 0;
139 623306 : hFdCngCom->offsetflag = 0;
140 623306 : hFdCngCom->msFrCnt = MSSUBFRLEN;
141 623306 : hFdCngCom->msMinBufferPtr = 0;
142 623306 : set_f( hFdCngCom->msAlphaCor, 0.3f, 2 );
143 :
144 623306 : set_f( hFdCngCom->coherence, 0.5f, MDCT_ST_DTX_NUM_COHERENCE_BANDS );
145 :
146 623306 : return;
147 : }
148 :
149 :
150 : /*-------------------------------------------------------------------
151 : * deleteFdCngCom()
152 : *
153 : * Delete an instance of type FD_CNG_COM
154 : *-------------------------------------------------------------------*/
155 :
156 623306 : void deleteFdCngCom(
157 : HANDLE_FD_CNG_COM *hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
158 : )
159 : {
160 623306 : HANDLE_FD_CNG_COM hsCom = *hFdCngCom;
161 :
162 623306 : if ( hsCom != NULL )
163 : {
164 623306 : free( hsCom );
165 623306 : *hFdCngCom = NULL;
166 : }
167 :
168 623306 : return;
169 : }
170 :
171 :
172 : /*-------------------------------------------------------------------
173 : * initPartitions()
174 : *
175 : * Initialize the spectral partitioning
176 : *-------------------------------------------------------------------*/
177 :
178 59110905 : void initPartitions(
179 : const int16_t *part_in,
180 : const int16_t npart_in,
181 : const int16_t startBand,
182 : const int16_t stopBand,
183 : int16_t *part_out,
184 : int16_t *npart_out,
185 : int16_t *midband,
186 : float *psize,
187 : float *psize_inv,
188 : const int16_t stopBandFR )
189 : {
190 : int16_t i, j, len_out;
191 :
192 59110905 : if ( part_in != NULL )
193 : {
194 59110905 : if ( stopBandFR > startBand )
195 : {
196 29290197 : len_out = stopBandFR - startBand; /*part_out*/
197 1142317683 : for ( i = 0; i < len_out; i++ )
198 : {
199 1113027486 : part_out[i] = i;
200 : }
201 : }
202 : else
203 : {
204 29820708 : len_out = 0;
205 : } /*npart_in,part_out*/
206 1916838123 : for ( j = 0; j < npart_in && part_in[j] < stopBand; j++ )
207 : {
208 1857727218 : if ( part_in[j] >= stopBandFR && part_in[j] >= startBand )
209 : {
210 1389084066 : part_out[len_out++] = part_in[j] - startBand;
211 : }
212 : }
213 : }
214 : else
215 : {
216 0 : len_out = stopBand - startBand; /*part_out*/
217 0 : for ( i = 0; i < len_out; i++ )
218 : {
219 0 : part_out[i] = i;
220 : }
221 : }
222 :
223 59110905 : *npart_out = len_out;
224 59110905 : getmidbands( part_out, len_out, midband, psize, psize_inv );
225 :
226 59110905 : return;
227 : }
228 :
229 :
230 : /*-------------------------------------------------------------------
231 : * compress_range()
232 : *
233 : * Apply some dynamic range compression based on the log
234 : *-------------------------------------------------------------------*/
235 :
236 6880562 : void compress_range(
237 : float *in,
238 : float *out,
239 : const int16_t len )
240 : {
241 6880562 : float *ptrIn = in;
242 6880562 : float *ptrOut = out;
243 : int16_t i;
244 :
245 : /* out = log2( 1 + in ) */
246 352101143 : for ( i = 0; i < len; i++ )
247 : {
248 345220581 : *ptrOut = (float) log10( *ptrIn + 1.f );
249 345220581 : ptrIn++;
250 345220581 : ptrOut++;
251 : }
252 6880562 : v_multc( out, 1.f / (float) log10( 2.f ), out, len );
253 :
254 : /* Quantize to simulate a fixed-point representation 6Q9 */
255 6880562 : v_multc( out, CNG_LOG_SCALING, out, len );
256 352101143 : for ( ptrOut = out; ptrOut < out + len; ptrOut++ )
257 : {
258 345220581 : *ptrOut = (float) ( (int16_t) ( *ptrOut + 0.5f ) );
259 345220581 : if ( *ptrOut == 0.f )
260 : {
261 115574427 : *ptrOut = 1.f;
262 : }
263 : }
264 6880562 : v_multc( out, 1. / CNG_LOG_SCALING, out, len );
265 :
266 6880562 : return;
267 : }
268 :
269 :
270 : /*-------------------------------------------------------------------
271 : * expand_range()
272 : *
273 : * Apply some dynamic range expansion to undo the compression
274 : *-------------------------------------------------------------------*/
275 :
276 6880571 : void expand_range(
277 : float *in,
278 : float *out,
279 : const int16_t len )
280 : {
281 6880571 : float *ptrIn = in;
282 6880571 : float *ptrOut = out;
283 : int16_t i;
284 :
285 : /* out = (2^(in) - 1) */
286 352101710 : for ( i = 0; i < len; i++ )
287 : {
288 345221139 : *ptrOut = (float) pow( 2.f, *ptrIn ) - 1.f;
289 345221139 : if ( *ptrOut < 0.0003385080526823181f )
290 : {
291 3185193 : *ptrOut = 0.0003385080526823181f;
292 : }
293 345221139 : ptrIn++;
294 345221139 : ptrOut++;
295 : }
296 :
297 6880571 : return;
298 : }
299 :
300 :
301 : /*-------------------------------------------------------------------
302 : * minimum_statistics()
303 : *
304 : * Noise estimation using Minimum Statistics (MS)
305 : *-------------------------------------------------------------------*/
306 :
307 6880562 : void minimum_statistics(
308 : const int16_t len, /* i : Vector length */
309 : const int16_t lenFFT, /* i : Length of the FFT part of the vectors */
310 : float *psize,
311 : float *msPeriodog, /* i : Periodograms */
312 : float *msNoiseFloor,
313 : float *msNoiseEst, /* o : Noise estimates */
314 : float *msAlpha,
315 : float *msPsd,
316 : float *msPsdFirstMoment,
317 : float *msPsdSecondMoment,
318 : float *msMinBuf,
319 : float *msBminWin,
320 : float *msBminSubWin,
321 : float *msCurrentMin,
322 : float *msCurrentMinOut,
323 : float *msCurrentMinSubWindow,
324 : int16_t *msLocalMinFlag,
325 : int16_t *msNewMinFlag,
326 : float *msPeriodogBuf,
327 : int16_t *msPeriodogBufPtr,
328 : HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
329 : const int16_t enc_dec, /* i : encoder/decoder indicator */
330 : const int16_t element_mode /* i : IVAS element mode type */
331 : )
332 : {
333 6880562 : float msM_win = hFdCngCom->msM_win;
334 6880562 : float msM_subwin = hFdCngCom->msM_subwin;
335 6880562 : float *msPsdSum = hFdCngCom->msPsdSum;
336 6880562 : float *msPeriodogSum = hFdCngCom->msPeriodogSum;
337 : float slope;
338 : float *ptr;
339 6880562 : float msAlphaCorAlpha = MSALPHACORALPHA;
340 6880562 : float msAlphaCorAlpha2 = 1.f - MSALPHACORALPHA;
341 :
342 : int16_t i, j, k;
343 : float scalar, scalar2, scalar3;
344 : float snr, BminCorr, QeqInv, QeqInvAv;
345 : float beta;
346 : float msAlphaHatMin2;
347 6880562 : int16_t len2 = MSNUMSUBFR * len;
348 : int16_t current_len;
349 : int16_t start, stop, cnt;
350 : int16_t totsize;
351 6880562 : const float inv_buflen = 1.f / MSBUFLEN;
352 :
353 : /* No minimum statistics at initialization */
354 6880562 : if ( hFdCngCom->msFrCnt_init_counter < hFdCngCom->msFrCnt_init_thresh )
355 : {
356 567865 : mvr2r( msPeriodog, msPsd, len );
357 567865 : mvr2r( msPeriodog, msNoiseFloor, len );
358 567865 : mvr2r( msPeriodog, msNoiseEst, len );
359 567865 : mvr2r( msPeriodog, msPsdFirstMoment, len );
360 567865 : set_f( msPsdSecondMoment, 0.0f, len );
361 567865 : msPeriodogSum[0] = dotp( msPeriodog, psize, lenFFT );
362 567865 : msPsdSum[0] = msPeriodogSum[0];
363 567865 : if ( lenFFT < len )
364 : {
365 60082 : msPeriodogSum[1] = dotp( msPeriodog + lenFFT, psize + lenFFT, len - lenFFT );
366 60082 : msPsdSum[1] = msPeriodogSum[1];
367 : }
368 :
369 : /* Increment frame counter at initialization */
370 : /* Some frames are sometimes zero at initialization => ignore them */
371 567865 : if ( msPeriodog[0] < hFdCngCom->init_old )
372 : {
373 79338 : set_f( msCurrentMinOut, FLT_MAX, len );
374 79338 : set_f( msCurrentMin, FLT_MAX, len );
375 79338 : set_f( msMinBuf, FLT_MAX, len2 );
376 79338 : set_f( msCurrentMinSubWindow, FLT_MAX, len );
377 79338 : hFdCngCom->msFrCnt_init_counter++;
378 : }
379 567865 : hFdCngCom->init_old = msPeriodog[0];
380 : }
381 : else
382 : {
383 :
384 : /* Consider the FFT and CLDFB bands separately
385 : - first iteration for FFT bins,
386 : - second one for CLDFB bands in SWB mode */
387 6312697 : start = 0;
388 6312697 : stop = lenFFT;
389 6312697 : totsize = hFdCngCom->stopFFTbin - hFdCngCom->startBand;
390 6312697 : cnt = 0; /*msAlphaCor*/
391 14592799 : while ( stop > start )
392 : {
393 8280102 : current_len = stop - start;
394 :
395 : /* Compute smoothed correction factor for PSD smoothing */
396 8280102 : msPeriodogSum[cnt] = dotp( msPeriodog + start, psize + start, current_len );
397 8280102 : scalar = msPeriodogSum[cnt] * msPeriodogSum[cnt] + DELTA;
398 8280102 : scalar2 = msPsdSum[cnt] - msPeriodogSum[cnt];
399 8280102 : scalar = max( scalar / ( scalar + scalar2 * scalar2 ), MSALPHACORMAX );
400 8280102 : hFdCngCom->msAlphaCor[cnt] = msAlphaCorAlpha * hFdCngCom->msAlphaCor[cnt] + msAlphaCorAlpha2 * scalar;
401 :
402 : /* Compute SNR */
403 8280102 : snr = dotp( msNoiseFloor + start, psize + start, current_len );
404 8280102 : snr = ( msPsdSum[cnt] + DELTA ) / ( snr + DELTA );
405 8280102 : snr = (float) pow( snr, MSSNREXP );
406 8280102 : msAlphaHatMin2 = min( MSALPHAHATMIN, snr );
407 8280102 : scalar = MSALPHAMAX * hFdCngCom->msAlphaCor[cnt]; /*msAlpha,msPsd,msPeriodog,msNoiseFloor*/
408 320907696 : for ( j = start; j < stop; j++ )
409 : {
410 : /* Compute optimal smoothing parameter for PSD estimation */
411 312627594 : scalar2 = msNoiseFloor[j] + DELTA;
412 312627594 : scalar2 *= scalar2;
413 312627594 : scalar3 = msPsd[j] - msNoiseFloor[j];
414 312627594 : msAlpha[j] = max( ( scalar * scalar2 ) / ( scalar2 + scalar3 * scalar3 ), msAlphaHatMin2 );
415 :
416 : /* Compute the PSD (smoothed periodogram) in each band */
417 312627594 : msPsd[j] = msAlpha[j] * msPsd[j] + ( 1.f - msAlpha[j] ) * msPeriodog[j];
418 : }
419 8280102 : msPsdSum[cnt] = dotp( msPsd + start, psize + start, current_len );
420 8280102 : QeqInvAv = 0;
421 8280102 : scalar = ( (float) ( MSNUMSUBFR * MSSUBFRLEN ) - 1.f ) * ( 1.f - msM_win );
422 8280102 : scalar2 = ( (float) MSSUBFRLEN - 1.f ) * ( 1.f - msM_subwin ); /*msAlpha,msPsd,msPsdFirstMoment,msPsdSecondMoment,msNoiseFloor,msBminSubWin,msBminWin,psize*/
423 320907696 : for ( j = start; j < stop; j++ )
424 : {
425 : /* Compute variance of PSD */
426 312627594 : beta = min( msAlpha[j] * msAlpha[j], MSBETAMAX );
427 312627594 : scalar3 = msPsd[j] - msPsdFirstMoment[j];
428 312627594 : msPsdFirstMoment[j] = beta * msPsdFirstMoment[j] + ( 1.f - beta ) * msPsd[j];
429 312627594 : msPsdSecondMoment[j] = beta * msPsdSecondMoment[j] + ( 1.f - beta ) * scalar3 * scalar3;
430 : /* Compute inverse of amount of degrees of freedom */
431 312627594 : QeqInv = min( ( msPsdSecondMoment[j] + DELTA ) / ( 2.f * msNoiseFloor[j] * msNoiseFloor[j] + DELTA ), MSQEQINVMAX );
432 312627594 : QeqInvAv += QeqInv * psize[j];
433 :
434 : /* Compute bias correction Bmin */
435 312627594 : msBminWin[j] = 1.f + scalar * QeqInv / ( 0.5f - msM_win * QeqInv );
436 312627594 : msBminSubWin[j] = 1.f + scalar2 * QeqInv / ( 0.5f - msM_subwin * QeqInv );
437 : }
438 8280102 : QeqInvAv /= totsize;
439 8280102 : hFdCngCom->msQeqInvAv[cnt] = QeqInvAv;
440 :
441 : /* New minimum? */
442 8280102 : BminCorr = 1.f + MSAV * (float) sqrt( QeqInvAv ); /*msPsd,msBminWin,msNewMinFlag,msCurrentMin,msCurrentMinSubWindow*/
443 320907696 : for ( j = start; j < stop; j++ )
444 : {
445 312627594 : scalar = BminCorr * msPsd[j];
446 312627594 : scalar2 = scalar * msBminWin[j];
447 312627594 : if ( scalar2 < msCurrentMin[j] )
448 : {
449 159732232 : msNewMinFlag[j] = 1;
450 159732232 : msCurrentMin[j] = scalar2;
451 159732232 : msCurrentMinSubWindow[j] = scalar * msBminSubWin[j];
452 : }
453 : else
454 : {
455 152895362 : msNewMinFlag[j] = 0;
456 : }
457 : }
458 :
459 : /* This is used later to identify local minima */
460 8280102 : if ( hFdCngCom->msFrCnt >= MSSUBFRLEN )
461 : {
462 720582 : i = 0;
463 1625502 : while ( i < 3 )
464 : {
465 1394985 : if ( hFdCngCom->msQeqInvAv[cnt] < msQeqInvAv_thresh[i] )
466 : {
467 490065 : break;
468 : }
469 : else
470 : {
471 904920 : i++;
472 : }
473 : }
474 720582 : hFdCngCom->msSlope[cnt] = msNoiseSlopeMax[i];
475 : }
476 :
477 : /* Consider the FFT and CLDFB bands separately */
478 8280102 : start = stop;
479 8280102 : stop = len;
480 8280102 : totsize = hFdCngCom->stopBand - hFdCngCom->stopFFTbin;
481 8280102 : cnt++;
482 : } /*while (stop > start)*/
483 :
484 : /* Update minimum between sub windows */
485 6312697 : if ( hFdCngCom->msFrCnt > 1 && hFdCngCom->msFrCnt < MSSUBFRLEN )
486 : {
487 : /*msNewMinFlag,msCurrentMinSubWindow,msCurrentMinOut*/
488 262686603 : for ( j = 0; j < len; j++ )
489 : {
490 257477916 : if ( msNewMinFlag[j] > 0 )
491 : {
492 119626670 : msLocalMinFlag[j] = 1;
493 : }
494 257477916 : if ( msCurrentMinSubWindow[j] < msCurrentMinOut[j] )
495 : {
496 57339976 : msCurrentMinOut[j] = msCurrentMinSubWindow[j];
497 : }
498 : }
499 : /* Get the current noise floor */
500 5208687 : mvr2r( msCurrentMinOut, msNoiseFloor, len );
501 : }
502 :
503 : /* sub window complete */
504 : else
505 : {
506 1104010 : if ( hFdCngCom->msFrCnt >= MSSUBFRLEN )
507 : {
508 : /* Collect buffers */
509 554599 : mvr2r( msCurrentMinSubWindow, msMinBuf + len * hFdCngCom->msMinBufferPtr, len );
510 :
511 : /* Compute minimum among all buffers */
512 554599 : mvr2r( msMinBuf, msCurrentMinOut, len );
513 554599 : ptr = msMinBuf + len;
514 3327594 : for ( i = 1; i < MSNUMSUBFR; i++ )
515 : {
516 : /*msCurrentMinOut*/
517 141424745 : for ( j = 0; j < len; j++ )
518 : {
519 138651750 : if ( *ptr < msCurrentMinOut[j] )
520 : {
521 34479247 : msCurrentMinOut[j] = *ptr;
522 : }
523 138651750 : ptr++;
524 : }
525 : }
526 :
527 : /* Take over local minima */
528 554599 : slope = hFdCngCom->msSlope[0]; /*msLocalMinFlag,msNewMinFlag,msCurrentMinSubWindow,msCurrentMinOut*/
529 28284949 : for ( j = 0; j < len; j++ )
530 : {
531 27730350 : if ( j == lenFFT )
532 : {
533 165983 : slope = hFdCngCom->msSlope[1];
534 : }
535 27730350 : if ( msLocalMinFlag[j] && !msNewMinFlag[j] &&
536 11277789 : msCurrentMinSubWindow[j] < slope * msCurrentMinOut[j] &&
537 7715352 : msCurrentMinSubWindow[j] > msCurrentMinOut[j] )
538 : {
539 2641781 : msCurrentMinOut[j] = msCurrentMinSubWindow[j];
540 2641781 : i = j;
541 18492467 : for ( k = 0; k < MSNUMSUBFR; k++ )
542 : {
543 15850686 : msMinBuf[i] = msCurrentMinOut[j];
544 15850686 : i += len;
545 : }
546 : }
547 : }
548 :
549 : /* Reset */
550 554599 : set_s( msLocalMinFlag, 0, len );
551 554599 : set_f( msCurrentMin, FLT_MAX, len );
552 :
553 : /* Get the current noise floor */
554 554599 : mvr2r( msCurrentMinOut, msNoiseFloor, len );
555 : }
556 : }
557 :
558 : /* Detect sudden offsets based on the FFT bins (core bandwidth) */
559 6312697 : if ( msPsdSum[0] > 50.f * msPeriodogSum[0] )
560 : {
561 10462 : if ( hFdCngCom->offsetflag > 0 )
562 : {
563 3131 : mvr2r( msPeriodog, msPsd, len );
564 3131 : mvr2r( msPeriodog, msCurrentMinOut, len );
565 3131 : set_f( hFdCngCom->msAlphaCor, 1.0f, cnt );
566 3131 : set_f( msAlpha, 0.0f, len );
567 3131 : mvr2r( msPeriodog, msPsdFirstMoment, len );
568 3131 : set_f( msPsdSecondMoment, 0.0f, len );
569 3131 : msPsdSum[0] = dotp( msPeriodog, psize, lenFFT );
570 3131 : if ( lenFFT < len )
571 : {
572 1046 : msPsdSum[1] = dotp( msPeriodog + lenFFT, psize + lenFFT, len - lenFFT );
573 : }
574 : }
575 10462 : hFdCngCom->offsetflag = 1;
576 : }
577 : else
578 : {
579 6302235 : hFdCngCom->offsetflag = 0;
580 : }
581 :
582 : /* Increment frame counter */
583 6312697 : if ( hFdCngCom->msFrCnt == MSSUBFRLEN )
584 : {
585 554599 : hFdCngCom->msFrCnt = 1;
586 554599 : hFdCngCom->msMinBufferPtr++;
587 554599 : if ( hFdCngCom->msMinBufferPtr == MSNUMSUBFR )
588 : {
589 65065 : hFdCngCom->msMinBufferPtr = 0;
590 : }
591 : }
592 : else
593 : {
594 5758098 : ( hFdCngCom->msFrCnt )++;
595 : }
596 :
597 : /* Smooth noise estimate during CNG phases */ /*msNoiseEst,msNoiseFloor*/
598 318940291 : for ( j = 0; j < len; j++ )
599 : {
600 312627594 : msNoiseEst[j] = 0.95f * msNoiseEst[j] + 0.05f * msNoiseFloor[j];
601 : }
602 : }
603 :
604 6880562 : if ( enc_dec == DEC && element_mode == IVAS_CPE_TD )
605 : {
606 0 : v_multc( msNoiseEst, 1.4125f, msNoiseEst, NPART_SHAPING );
607 : }
608 :
609 : /* Collect buffers */
610 6880562 : mvr2r( msPeriodog, msPeriodogBuf + len * ( *msPeriodogBufPtr ), len );
611 :
612 6880562 : ( *msPeriodogBufPtr )++;
613 6880562 : if ( ( *msPeriodogBufPtr ) == MSBUFLEN )
614 : {
615 1328049 : ( *msPeriodogBufPtr ) = 0;
616 : }
617 :
618 : /* Upper limit the noise floors with the averaged input energy */ /*msNoiseEst*/
619 352101143 : for ( j = 0; j < len; j++ )
620 : {
621 345220581 : scalar = msPeriodogBuf[j];
622 1726102905 : for ( i = j + len; i < MSBUFLEN * len; i += len )
623 : {
624 1380882324 : scalar += msPeriodogBuf[i];
625 : } /*division by a constant = multiplication by its (constant) inverse */
626 345220581 : scalar *= inv_buflen;
627 345220581 : if ( msNoiseEst[j] > scalar )
628 : {
629 137389409 : msNoiseEst[j] = scalar;
630 : }
631 345220581 : assert( msNoiseEst[j] >= 0 );
632 : }
633 :
634 6880562 : return;
635 : }
636 :
637 :
638 : /*-------------------------------------------------------------------
639 : * apply_scale()
640 : *
641 : * Apply bitrate-dependent scale
642 : *-------------------------------------------------------------------*/
643 :
644 10080782 : void apply_scale(
645 : float *scale, /* o : scalefactor */
646 : const int16_t bwidth, /* i : audio bandwidth */
647 : const int32_t brate, /* i : Bit rate */
648 : const SCALE_SETUP *scaleTable, /* i : Scale table */
649 : const int16_t scaleTableSize /* i : Size of scale table */
650 : )
651 : {
652 : int16_t i;
653 :
654 101589916 : for ( i = 0; i < scaleTableSize; i++ )
655 : {
656 101589916 : if ( ( bwidth == scaleTable[i].bwmode ) &&
657 46144521 : ( brate >= scaleTable[i].bitrateFrom ) &&
658 46144521 : ( brate < scaleTable[i].bitrateTo ) )
659 : {
660 10080782 : break;
661 : }
662 : }
663 :
664 10080782 : assert( i < scaleTableSize );
665 :
666 10080782 : *scale += scaleTable[i].scale;
667 :
668 10080782 : return;
669 : }
670 :
671 :
672 : /*-------------------------------------------------------------------
673 : * bandcombinepow()
674 : *
675 : * Compute the power for each partition
676 : *-------------------------------------------------------------------*/
677 :
678 7449703 : void bandcombinepow(
679 : const float *bandpow, /* i : Power for each band */
680 : const int16_t nband, /* i : Number of bands */
681 : int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */
682 : const int16_t npart, /* i : Number of partitions */
683 : const float *psize_inv, /* i : Inverse partition sizes */
684 : float *partpow /* o : Power for each partition */
685 : )
686 : {
687 : int16_t i, p;
688 : float temp;
689 :
690 7449703 : if ( nband == npart )
691 : {
692 0 : mvr2r( bandpow, partpow, nband );
693 : }
694 : else
695 : {
696 : /* Compute the power in each partition */
697 7449703 : i = 0; /*part,partpow,psize_inv*/
698 326724048 : for ( p = 0; p < npart; p++ )
699 : {
700 : /* Arithmetic averaging of power for all bins in partition */
701 319274345 : temp = 0;
702 1964578185 : for ( ; i <= part[p]; i++ )
703 : {
704 1645303840 : temp += bandpow[i];
705 : }
706 319274345 : partpow[p] = temp * psize_inv[p];
707 : }
708 : }
709 :
710 7449703 : return;
711 : }
712 :
713 :
714 : /*-------------------------------------------------------------------
715 : * scalebands()
716 : *
717 : * Scale partitions (with smoothing)
718 : *-------------------------------------------------------------------*/
719 :
720 7674671 : void scalebands(
721 : const float *partpow, /* i : Power for each partition */
722 : int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */
723 : const int16_t npart, /* i : Number of partitions */
724 : int16_t *midband, /* i : Central band of each partition */
725 : const int16_t nFFTpart, /* i : Number of FFT partitions */
726 : const int16_t nband, /* i : Number of bands */
727 : float *bandpow, /* o : Power for each band */
728 : const int16_t flag_fft_en )
729 : {
730 7674671 : int16_t i, j = 0, nint, startBand, startPart, stopPart;
731 7674671 : float val, delta = 0.f;
732 :
733 : /* Interpolate the bin/band-wise levels from the partition levels */
734 7674671 : if ( nband == npart )
735 : {
736 0 : mvr2r( partpow, bandpow, npart );
737 : }
738 : else
739 : {
740 7674671 : startBand = 0;
741 7674671 : startPart = 0;
742 7674671 : stopPart = nFFTpart;
743 15410218 : while ( startBand < nband )
744 : {
745 7735547 : if ( flag_fft_en || startPart >= nFFTpart )
746 : {
747 :
748 : /* first half partition */
749 7716893 : j = startPart;
750 7716893 : val = partpow[j];
751 15633432 : for ( i = startBand; i <= midband[j]; i++ )
752 : {
753 7916539 : bandpow[i] = val;
754 : }
755 7716893 : j++;
756 :
757 7716893 : delta = 1;
758 : /* inner partitions */
759 468236771 : for ( ; j < stopPart; j++ )
760 : {
761 460519878 : nint = midband[j] - midband[j - 1];
762 : /* log-linear interpolation */ /* Only one new LOG needs to be computed per loop iteration */
763 460519878 : delta = (float) exp( ( log( partpow[j] + DELTA ) - log( partpow[j - 1] + DELTA ) ) * normReciprocal[nint] );
764 460519878 : val = partpow[j - 1];
765 2167773787 : for ( ; i < midband[j]; i++ )
766 : {
767 1707253909 : val *= delta;
768 1707253909 : bandpow[i] = val;
769 : }
770 460519878 : bandpow[i++] = partpow[j];
771 : }
772 7716893 : if ( delta > 1.f )
773 : {
774 1259084 : delta = 1.f;
775 : }
776 :
777 : /* last half partition */
778 7716893 : val = partpow[stopPart - 1];
779 66199151 : for ( ; i <= part[stopPart - 1]; i++ )
780 : {
781 58482258 : val *= delta;
782 58482258 : bandpow[i] = val;
783 : }
784 : }
785 7735547 : startBand = part[stopPart - 1] + 1;
786 7735547 : startPart = stopPart;
787 7735547 : stopPart = npart;
788 : }
789 : }
790 :
791 7674671 : return;
792 : }
793 :
794 :
795 : /*-------------------------------------------------------------------
796 : * getmidbands()
797 : *
798 : * Get central band for each partition
799 : *-------------------------------------------------------------------*/
800 :
801 59110905 : static void getmidbands(
802 : int16_t *part, /* i : Partition upper boundaries (band indices starting from 0) */
803 : const int16_t npart, /* i : Number of partitions */
804 : int16_t *midband, /* o : Central band of each partition */
805 : float *psize, /* o : Partition sizes */
806 : float *psize_inv /* o : Inverse of partition sizes */
807 : )
808 : {
809 : int16_t j;
810 :
811 : /* first half partition */
812 59110905 : midband[0] = part[0];
813 59110905 : psize[0] = (float) part[0] + 1.f;
814 59110905 : psize_inv[0] = normReciprocal[part[0] + 1];
815 :
816 : /* inner partitions */ /*part,midband,psize_inv*/
817 2502111552 : for ( j = 1; j < npart; j++ )
818 : {
819 2443000647 : midband[j] = ( part[j - 1] + 1 + part[j] ) >> 1;
820 2443000647 : psize[j] = (float) ( part[j] - part[j - 1] );
821 2443000647 : psize_inv[j] = normReciprocal[part[j] - part[j - 1]];
822 : }
823 :
824 59110905 : return;
825 : }
826 :
827 :
828 : /*-------------------------------------------------------------------
829 : * AnalysisSTFT()
830 : *
831 : * STFT analysis filterbank
832 : *-------------------------------------------------------------------*/
833 :
834 6682212 : void AnalysisSTFT(
835 : const float *timeDomainInput,
836 : float *fftBuffer, /* o : FFT bins */
837 : HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
838 : )
839 : {
840 6682212 : float *olapBuffer = hFdCngCom->olapBufferAna;
841 6682212 : const float *olapWin = hFdCngCom->olapWinAna;
842 :
843 : /* Shift and cascade for overlap-add */
844 6682212 : mvr2r( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->fftlen - hFdCngCom->frameSize );
845 6682212 : mvr2r( timeDomainInput, olapBuffer + hFdCngCom->fftlen - hFdCngCom->frameSize, hFdCngCom->frameSize );
846 :
847 : /* Window the signal */
848 6682212 : v_mult( olapBuffer, olapWin, fftBuffer, hFdCngCom->fftlen );
849 :
850 : /* Perform FFT */
851 6682212 : RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, -1 );
852 :
853 6682212 : return;
854 : }
855 :
856 :
857 : /*-------------------------------------------------------------------
858 : * SynthesisSTFT()
859 : *
860 : * STFT synthesis filterbank
861 : *-------------------------------------------------------------------*/
862 :
863 3937916 : void SynthesisSTFT(
864 : float *fftBuffer, /* i : FFT bins */
865 : float *timeDomainOutput,
866 : float *olapBuffer,
867 : const float *olapWin,
868 : const int16_t tcx_transition,
869 : HANDLE_FD_CNG_COM hFdCngCom, /* i/o: FD_CNG structure containing all buffers and variables */
870 : const int16_t element_mode, /* i : element mode */
871 : const int16_t nchan_out /* i : number of output channels */
872 : )
873 : {
874 : int16_t i;
875 : float buf[M + 1 + 320], tmp;
876 :
877 : /* Perform IFFT */
878 3937916 : RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, 1 );
879 :
880 : /* Handle overlap in P/S domain for stereo */
881 3937916 : if ( ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) && nchan_out == 2 )
882 : {
883 7057 : mvr2r( olapBuffer + 3 * hFdCngCom->frameSize / 4 - ( M + 1 ), buf, hFdCngCom->frameSize + M + 1 );
884 7057 : set_f( olapBuffer, 0.0f, hFdCngCom->fftlen );
885 : }
886 : else
887 : {
888 3930859 : mvr2r( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->frameSize );
889 3930859 : set_f( olapBuffer + hFdCngCom->frameSize, 0.0f, hFdCngCom->frameSize ); /*olapBuffer, fftBuffer, olapWin*/
890 : }
891 :
892 3937916 : if ( tcx_transition )
893 : {
894 8705969 : for ( i = 0; i < 5 * hFdCngCom->frameSize / 4; i++ )
895 : {
896 8681280 : olapBuffer[i] = fftBuffer[i];
897 : }
898 : }
899 : else
900 : {
901 572755595 : for ( i = hFdCngCom->frameSize / 4; i < 3 * hFdCngCom->frameSize / 4; i++ )
902 : {
903 568842368 : olapBuffer[i] += fftBuffer[i] * olapWin[i - hFdCngCom->frameSize / 4];
904 : }
905 572755595 : for ( ; i < 5 * hFdCngCom->frameSize / 4; i++ )
906 : {
907 568842368 : olapBuffer[i] = fftBuffer[i];
908 : }
909 : }
910 576252796 : for ( ; i < 7 * hFdCngCom->frameSize / 4; i++ )
911 : {
912 572314880 : olapBuffer[i] = fftBuffer[i] * olapWin[i - 3 * hFdCngCom->frameSize / 4];
913 : }
914 :
915 290095356 : for ( ; i < hFdCngCom->fftlen; i++ )
916 : {
917 286157440 : olapBuffer[i] = 0;
918 : }
919 :
920 : /* Get time-domain signal */
921 3937916 : v_multc( olapBuffer + hFdCngCom->frameSize / 4, (float) ( hFdCngCom->fftlen / 2 ), timeDomainOutput, hFdCngCom->frameSize );
922 :
923 : /* Get excitation */
924 3937916 : if ( ( element_mode == IVAS_CPE_TD || element_mode == IVAS_CPE_DFT ) && nchan_out == 2 )
925 : {
926 910353 : for ( i = 0; i < hFdCngCom->frameSize / 2; i++ )
927 : {
928 903296 : buf[i + ( M + 1 )] += olapBuffer[i + hFdCngCom->frameSize / 4];
929 : }
930 7057 : v_multc( buf, (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize );
931 : }
932 : else
933 : {
934 3930859 : v_multc( olapBuffer + hFdCngCom->frameSize / 4 - ( M + 1 ), (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize );
935 : }
936 :
937 3937916 : tmp = buf[0];
938 3937916 : preemph( buf + 1, PREEMPH_FAC, M + hFdCngCom->frameSize, &tmp );
939 3937916 : residu( hFdCngCom->A_cng, M, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize );
940 :
941 3937916 : return;
942 : }
943 :
944 :
945 : /*-------------------------------------------------------------------
946 : * SynthesisSTFT_dirac()
947 : *
948 : * STFT synthesis filterbank
949 : *-------------------------------------------------------------------*/
950 :
951 263651 : void SynthesisSTFT_dirac(
952 : float *fftBuffer, /* i : FFT bins */
953 : float *timeDomainOutput,
954 : float *olapBuffer,
955 : const float *olapWin,
956 : const int16_t samples_out,
957 : HANDLE_FD_CNG_COM hFdCngCom /* i/o: FD_CNG structure containing all buffers and variables */
958 : )
959 : {
960 : int16_t i;
961 : float buf[M + 1 + 320], tmp;
962 :
963 : /* Perform IFFT */
964 263651 : RFFTN( fftBuffer, hFdCngCom->fftSineTab, hFdCngCom->fftlen, 1 );
965 :
966 : /* Handle overlap in P/S domain for stereo */
967 263651 : mvr2r( olapBuffer + hFdCngCom->frameSize, olapBuffer, hFdCngCom->frameSize );
968 263651 : set_f( olapBuffer + hFdCngCom->frameSize, 0.0f, hFdCngCom->frameSize ); /*olapBuffer, fftBuffer, olapWin*/
969 :
970 38307939 : for ( i = hFdCngCom->frameSize / 4; i < 3 * hFdCngCom->frameSize / 4; i++ )
971 : {
972 38044288 : olapBuffer[i] += fftBuffer[i] * olapWin[i - hFdCngCom->frameSize / 4];
973 : }
974 38307939 : for ( ; i < 5 * hFdCngCom->frameSize / 4; i++ )
975 : {
976 38044288 : olapBuffer[i] = fftBuffer[i];
977 : }
978 :
979 38307939 : for ( ; i < 7 * hFdCngCom->frameSize / 4; i++ )
980 : {
981 38044288 : olapBuffer[i] = fftBuffer[i];
982 : }
983 :
984 19285795 : for ( ; i < hFdCngCom->fftlen; i++ )
985 : {
986 19022144 : olapBuffer[i] = 0;
987 : }
988 :
989 : /* Get time-domain signal */
990 263651 : v_multc( olapBuffer + hFdCngCom->frameSize / 4, (float) ( hFdCngCom->fftlen / 2 ), timeDomainOutput, samples_out );
991 :
992 : /* Get excitation */
993 263651 : v_multc( olapBuffer + hFdCngCom->frameSize / 4 - ( M + 1 ), (float) ( hFdCngCom->fftlen / 2 ), buf, M + 1 + hFdCngCom->frameSize );
994 263651 : tmp = buf[0];
995 263651 : preemph( buf + 1, PREEMPH_FAC, M + hFdCngCom->frameSize, &tmp );
996 263651 : residu( hFdCngCom->A_cng, M, buf + 1 + M, hFdCngCom->exc_cng, hFdCngCom->frameSize );
997 :
998 : /* update and window olapBuf if we have a output frame that is shorter than the default frame size...*/
999 263651 : if ( samples_out < hFdCngCom->frameSize )
1000 : {
1001 45 : mvr2r( olapBuffer + samples_out, olapBuffer + hFdCngCom->frameSize, 3 * hFdCngCom->frameSize / 4 );
1002 : }
1003 38307939 : for ( i = 5 * hFdCngCom->frameSize / 4; i < 7 * hFdCngCom->frameSize / 4; i++ )
1004 : {
1005 38044288 : olapBuffer[i] *= olapWin[i - 3 * hFdCngCom->frameSize / 4];
1006 : }
1007 :
1008 263651 : return;
1009 : }
1010 :
1011 :
1012 : /*-------------------------------------------------------------------
1013 : * mhvals()
1014 : *
1015 : * Compute some values used in the bias correction of the minimum statistics algorithm
1016 : *-------------------------------------------------------------------*/
1017 :
1018 1246612 : static void mhvals(
1019 : const int16_t d,
1020 : float *m )
1021 : {
1022 : int16_t i, j;
1023 : float qi, qj, q;
1024 1246612 : int16_t len = SIZE_SCALE_TABLE_CN;
1025 :
1026 1246612 : i = 0;
1027 10596202 : for ( i = 0; i < len; i++ )
1028 : {
1029 10596202 : if ( d <= d_array[i] )
1030 : {
1031 1246612 : break;
1032 : }
1033 : }
1034 1246612 : if ( i == len )
1035 : {
1036 0 : i = len - 1;
1037 0 : j = i;
1038 : }
1039 : else
1040 : {
1041 1246612 : j = i - 1;
1042 : }
1043 1246612 : if ( d == d_array[i] )
1044 : {
1045 0 : *m = m_array[i];
1046 : }
1047 : else
1048 : {
1049 1246612 : qj = (float) sqrt( (float) d_array[i - 1] ); /*interpolate using sqrt(d)*/
1050 1246612 : qi = (float) sqrt( (float) d_array[i] );
1051 1246612 : q = (float) sqrt( (float) d );
1052 1246612 : *m = m_array[i] + ( qi * qj / q - qj ) * ( m_array[j] - m_array[i] ) / ( qi - qj );
1053 : }
1054 :
1055 1246612 : return;
1056 : }
1057 :
1058 : /*-------------------------------------------------------------------
1059 : * rand_gauss()
1060 : *
1061 : * Random generator with Gaussian distribution with mean 0 and std 1
1062 : *-------------------------------------------------------------------*/
1063 :
1064 5678103066 : float rand_gauss(
1065 : float *x,
1066 : int16_t *seed )
1067 : {
1068 : float temp;
1069 :
1070 5678103066 : temp = (float) own_random( seed );
1071 5678103066 : temp += (float) own_random( seed );
1072 5678103066 : temp += (float) own_random( seed );
1073 5678103066 : temp *= OUTMAX_INV;
1074 :
1075 5678103066 : *x = temp;
1076 :
1077 5678103066 : return temp;
1078 : }
1079 :
1080 :
1081 : /*-------------------------------------------------------------------
1082 : * lpc_from_spectrum()
1083 : *
1084 : *
1085 : *-------------------------------------------------------------------*/
1086 :
1087 247313 : void lpc_from_spectrum(
1088 : HANDLE_FD_CNG_COM hFdCngCom,
1089 : const int16_t start,
1090 : const int16_t stop,
1091 : const float preemph_fac )
1092 : {
1093 : int16_t i;
1094 : float r[32], nf;
1095 : float fftBuffer[FFTLEN], *ptr, *pti;
1096 :
1097 247313 : float *powspec = hFdCngCom->cngNoiseLevel;
1098 247313 : int16_t fftlen = hFdCngCom->fftlen;
1099 247313 : const float *fftSineTab = hFdCngCom->fftSineTab;
1100 247313 : float *A = hFdCngCom->A_cng;
1101 :
1102 : /* Power Spectrum */
1103 247313 : ptr = fftBuffer;
1104 247313 : pti = fftBuffer + 1;
1105 247313 : nf = 1e-3f;
1106 741939 : for ( i = 0; i < start; i++ )
1107 : {
1108 494626 : *ptr = nf;
1109 494626 : *pti = 0.f;
1110 494626 : ptr += 2;
1111 494626 : pti += 2;
1112 : }
1113 75607663 : for ( ; i < stop; i++ )
1114 : {
1115 75360350 : *ptr = max( nf, powspec[i - start] );
1116 75360350 : *pti = 0.f;
1117 75360350 : ptr += 2;
1118 75360350 : pti += 2;
1119 : }
1120 278225 : for ( ; i < fftlen / 2; i++ )
1121 : {
1122 30912 : *ptr = nf;
1123 30912 : *pti = 0.f;
1124 30912 : ptr += 2;
1125 30912 : pti += 2;
1126 : }
1127 247313 : fftBuffer[1] = nf;
1128 :
1129 : /* Pre-emphasis */
1130 247313 : ptr = fftBuffer;
1131 76133201 : for ( i = 0; i < fftlen / 2; i++ )
1132 : {
1133 75885888 : *ptr *= ( 1.f + preemph_fac * preemph_fac - 2.0f * preemph_fac * (float) cos( -2.0f * EVS_PI * (float) i / (float) fftlen ) );
1134 :
1135 75885888 : ptr += 2;
1136 : }
1137 247313 : fftBuffer[1] *= ( 1.f + preemph_fac * preemph_fac + 2.0f * preemph_fac );
1138 :
1139 : /* Autocorrelation */
1140 247313 : RFFTN( fftBuffer, fftSineTab, fftlen, 1 );
1141 4451634 : for ( i = 0; i <= M; i++ )
1142 : {
1143 4204321 : r[i] = fftBuffer[i] * ( fftlen / 2 ) * ( fftlen / 2 );
1144 : }
1145 247313 : if ( r[0] < 100.f )
1146 : {
1147 17081 : r[0] = 100.f;
1148 : }
1149 :
1150 247313 : r[0] *= 1.0005f;
1151 :
1152 : /* LPC */
1153 247313 : lev_dur( A, r, M, NULL );
1154 :
1155 247313 : return;
1156 : }
1157 :
1158 :
1159 : /*-------------------------------------------------------------------
1160 : * FdCng_exc()
1161 : *
1162 : * Generate FD-CNG as LP excitation
1163 : *-------------------------------------------------------------------*/
1164 :
1165 283520 : void FdCng_exc(
1166 : HANDLE_FD_CNG_COM hFdCngCom,
1167 : int16_t *CNG_mode,
1168 : const int16_t L_frame,
1169 : const float *lsp_old,
1170 : const int16_t first_CNG,
1171 : float *lspCNG,
1172 : float *Aq, /* o : LPC coeffs */
1173 : float *lsp_new, /* o : lsp */
1174 : float *lsf_new, /* o : lsf */
1175 : float *exc, /* o : LP excitation */
1176 : float *exc2, /* o : LP excitation */
1177 : float *bwe_exc /* o : LP excitation for BWE */
1178 : )
1179 : {
1180 : int16_t i;
1181 283520 : *CNG_mode = -1;
1182 :
1183 : /*Get excitation */
1184 1590393 : for ( i = 0; i < L_frame / L_SUBFR; i++ )
1185 : {
1186 1306873 : mvr2r( hFdCngCom->A_cng, Aq + i * ( M + 1 ), M + 1 );
1187 : }
1188 :
1189 283520 : a2lsp_stab( Aq, lsp_new, lsp_old );
1190 :
1191 283520 : if ( first_CNG == 0 )
1192 : {
1193 125099 : mvr2r( lsp_old, lspCNG, M );
1194 : }
1195 :
1196 4819840 : for ( i = 0; i < M; i++ )
1197 : {
1198 : /* AR low-pass filter */
1199 4536320 : lspCNG[i] = CNG_ISF_FACT * lspCNG[i] + ( 1 - CNG_ISF_FACT ) * lsp_new[i];
1200 : }
1201 :
1202 283520 : if ( L_frame == L_FRAME16k )
1203 : {
1204 172793 : lsp2lsf( lsp_new, lsf_new, M, INT_FS_16k );
1205 : }
1206 : else
1207 : {
1208 110727 : lsp2lsf( lsp_new, lsf_new, M, INT_FS_12k8 );
1209 : }
1210 :
1211 283520 : mvr2r( hFdCngCom->exc_cng, exc, L_frame );
1212 283520 : mvr2r( hFdCngCom->exc_cng, exc2, L_frame );
1213 :
1214 283520 : if ( bwe_exc )
1215 : {
1216 211802 : if ( L_frame == L_FRAME )
1217 : {
1218 110727 : interp_code_5over2( exc2, bwe_exc, L_frame );
1219 : }
1220 : else
1221 : {
1222 101075 : interp_code_4over2( exc2, bwe_exc, L_frame );
1223 : }
1224 : }
1225 :
1226 283520 : return;
1227 : }
|