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