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