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 <stdint.h>
38 : #include "options.h"
39 : #ifdef DEBUGGING
40 : #include "debug.h"
41 : #endif
42 : #include <math.h>
43 : #include "rom_dec.h"
44 : #include "rom_com.h"
45 : #include "cnst.h"
46 : #include "prot.h"
47 : #include "wmc_auto.h"
48 :
49 : /*---------------------------------------------------------------------*
50 : * Local constants
51 : *---------------------------------------------------------------------*/
52 :
53 : #define FEC_MAX 512
54 : #define FEC_NB_PULSE_MAX 20
55 : #define FEC_FFT_MAX_SIZE 512
56 : #define FEC_DCIM_FILT_SIZE_MAX 60
57 :
58 : #define PHASE_DITH ( PI2 )
59 :
60 : #define DELTA_CORR 6 /* Range for phase correction around peak */
61 : #define THRESH_TR_dB 10.0f
62 : #define THRESH_TR_LIN (float) pow( 10.0f, THRESH_TR_dB / 10.0f )
63 : #define THRESH_TR_LIN_INV (float) pow( 10.0f, -THRESH_TR_dB / 10.0f )
64 : #define MAX_INCREASE_GRPOW 0.0f /* maximum amplification in case of transients */
65 : #define MAX_INCREASE_GRPOW_LIN (float) pow( 10.0f, MAX_INCREASE_GRPOW / 10.0f )
66 :
67 : #define PHASE_DITH_SCALE (float) pow( 2.0, -16.0 ) /* for scaling random short values to +/- pi */
68 :
69 : #define BURST_PHDITH_THRESH ( 4 - 1 ) /* speech start phase dither with <burst_phdith_thresh> losses in a row */
70 : #define BURST_PHDITH_RAMPUP_LEN 2 /* speech ramp up degree of phase dither over a length of <burst_phdith_rampup_len> frames */
71 : #define BURST_ATT_THRESH ( 3 - 1 ) /* speech start attenuate with <burst_att_thresh> losses in a row */
72 : #define ATT_PER_FRAME 4 /* speech attenuation in dB */
73 : #define BETA_MUTE_THR 10 /* time threshold to start beta-noise attenuation */
74 : #define BETA_MUTE_FAC 0.5f /* attenuation factor per additional bad frame */
75 :
76 : #define LGW32k 7
77 : #define LGW16k 6
78 : #define LGW48k LGW32k + 1 /* Use the same frequency groups as for SWB + 1 */
79 :
80 : #define L_TRANA_LOG32k 8
81 : #define L_TRANA_LOG16k 7
82 :
83 : #define DELTA_CORR_F0_INT 2 /* Constant controls the bin range where Jacobsen is used */
84 : #define ST_PFIND_SENS 0.93f /* peakfinder sensitivity */
85 : #define L_PROT_NS 32000000L /* Prototype frame length in nanoseconds (32 ms) */
86 : #define PH_ECU_CORR_LIMIT 0.85f /* Correlation limit for IVAS Phase ECU activation */
87 : #define PH_ECU_N_LIMIT 56 /* fec_alg analysis frame limit for IVAS Phase ECU activation */
88 : #define PFIND_SENS 0.97f /* peakfinder sensitivity */
89 :
90 : /*---------------------------------------------------------------------*
91 : * Local functions
92 : *---------------------------------------------------------------------*/
93 :
94 : static int16_t rand_phase( const int16_t seed, float *sin_F, float *cos_F );
95 : static float imax2_jacobsen_mag( const float *y_re, const float *y_im );
96 :
97 : /*-------------------------------------------------------------------*
98 : * mult_rev2()
99 : *
100 : * Multiplication of two vectors second vector is multiplied in reverse order
101 : *-------------------------------------------------------------------*/
102 :
103 9952 : static void mult_rev2(
104 : const float x1[], /* i : Input vector 1 */
105 : const float x2[], /* i : Input vector 2 */
106 : float y[], /* o : Output vector that contains vector 1 .* vector 2 */
107 : const int16_t N /* i : Vector length */
108 : )
109 : {
110 : int16_t i, j;
111 :
112 1343808 : for ( i = 0, j = N - 1; i < N; i++, j-- )
113 : {
114 1333856 : y[i] = x1[i] * x2[j];
115 : }
116 :
117 9952 : return;
118 : }
119 :
120 :
121 : /*-------------------------------------------------------------------*
122 : * fft_spec2()
123 : *
124 : * Square magnitude of fft spectrum
125 : *-------------------------------------------------------------------*/
126 :
127 14838 : static void fft_spec2(
128 : float x[], /* i/o: Input vector: complex spectrum -> square magnitude spectrum */
129 : const int16_t N /* i : Vector length */
130 : )
131 : {
132 : int16_t i, j;
133 :
134 3967872 : for ( i = 1, j = N - 1; i < N / 2; i++, j-- )
135 : {
136 3953034 : x[i] = x[i] * x[i] + x[j] * x[j];
137 : }
138 :
139 14838 : x[0] *= x[0];
140 14838 : x[N / 2] *= x[N / 2];
141 :
142 14838 : return;
143 : }
144 :
145 : /*------------------------------------------------------------------*
146 : * rand_phase()
147 : *
148 : * randomized phase in form of sin and cos components
149 : *------------------------------------------------------------------*/
150 :
151 : /*! r: Updated seed from RNG */
152 2546012 : static int16_t rand_phase(
153 : const int16_t seed, /* i : RNG seed */
154 : float *sin_F, /* o : random phase sin value */
155 : float *cos_F /* o : random phase cos value */
156 : )
157 : {
158 2546012 : const float *sincos = sincos_t_ext + 128;
159 2546012 : int16_t seed2 = seed;
160 2546012 : own_random( &seed2 );
161 :
162 2546012 : if ( seed2 & 0x40 )
163 : {
164 1271893 : *sin_F = sincos[seed2 >> 8];
165 : }
166 : else
167 : {
168 1274119 : *sin_F = -sincos[seed2 >> 8];
169 : }
170 :
171 2546012 : if ( seed2 & 0x80 )
172 : {
173 1273426 : *cos_F = sincos[-( seed2 >> 8 )];
174 : }
175 : else
176 : {
177 1272586 : *cos_F = -sincos[-( seed2 >> 8 )];
178 : }
179 :
180 2546012 : return seed2;
181 : }
182 :
183 : /*-----------------------------------------------------------------------------
184 : * imax2_jacobsen_mag()
185 : *
186 : * refine peak interpolation using jacobsen and periodic speca ana windows
187 : *----------------------------------------------------------------------------*/
188 :
189 : /*! r: The location, relative to the middle of the 3 given data point, of the maximum. (Q15)*/
190 93477 : float imax2_jacobsen_mag(
191 : const float *y_re, /* i : The 3 given data points. real part order -1 0 1 */
192 : const float *y_im /* i : The 3 given data points. imag part order 1 0 -1 (from FFT) */
193 : )
194 : {
195 : float posi;
196 : const float *pY;
197 : float y_m1_re, y_0_re, y_p1_re;
198 : float y_m1_im, y_0_im, y_p1_im;
199 : float N_re, N_im;
200 : float D_re, D_im;
201 : float numer, denom;
202 :
203 : /* Jacobsen estimates peak offset relative y_0 using
204 : * X_m1 - X_p1
205 : * d = REAL ( ------------------- ) * c_jacob
206 : * 2*X_0 - X_m1 -Xp1
207 : *
208 : * Where c_jacob is a window dependent constant
209 : */
210 : #define C_JACOB 1.1453f /* % assume 0.1875 hammrect window 'symmetric' */
211 :
212 : /* Get the bin parameters into variables */
213 93477 : pY = y_re;
214 93477 : y_m1_re = *pY++;
215 93477 : y_0_re = *pY++;
216 93477 : y_p1_re = *pY++;
217 :
218 : /* Same for imaginary parts - note reverse order from FFT */
219 93477 : pY = y_im;
220 93477 : y_p1_im = *pY++;
221 93477 : y_0_im = *pY++;
222 93477 : y_m1_im = *pY++;
223 :
224 : /* prepare numerator real and imaginary parts*/
225 93477 : N_re = y_m1_re - y_p1_re;
226 93477 : N_im = y_m1_im - y_p1_im;
227 :
228 : /* prepare denominator real and imaginary parts */
229 :
230 93477 : D_re = 2 * y_0_re - y_m1_re - y_p1_re;
231 93477 : D_im = 2 * y_0_im - y_m1_im - y_p1_im;
232 :
233 : /* REAL part of complex division */
234 93477 : numer = N_re * D_re + N_im * D_im;
235 93477 : denom = D_re * D_re + D_im * D_im;
236 :
237 93477 : test();
238 93477 : if ( numer != 0 && denom != 0 )
239 : {
240 93477 : posi = numer / denom * C_JACOB;
241 : }
242 : else
243 : {
244 0 : posi = 0; /* flat top, division is not possible choose center freq */
245 : }
246 :
247 93477 : return posi;
248 : }
249 :
250 :
251 : /*------------------------------------------------------------------*
252 : * trans_ana()
253 : *
254 : * Transient analysis
255 : *------------------------------------------------------------------*/
256 :
257 11829 : static void trans_ana(
258 : const float *xfp, /* i : Input signal */
259 : float *mag_chg, /* i/o: Magnitude modification */
260 : float *ph_dith, /* i/o: Phase dither */
261 : float *mag_chg_1st, /* i/o: per band magnitude modifier for transients */
262 : const int16_t output_frame, /* i : Frame length */
263 : const int16_t time_offs, /* i : Time offset */
264 : const float est_mus_content, /* i : 0.0=speech_like ... 1.0=Music (==st->env_stab ) */
265 : const int16_t last_fec, /* i : signal that previous frame was concealed with fec_alg*/
266 : const int16_t element_mode, /* i : element_mode req to handle EVS_MONO specific BE path*/
267 : float *alpha, /* o : Magnitude modification factors for fade to average */
268 : float *beta, /* o : Magnitude modification factors for fade to average */
269 : float *beta_mute, /* o : Factor for long-term mute */
270 : float Xavg[LGW_MAX] /* o : Frequency group average gain to fade to */
271 : )
272 : {
273 : const float *w_hamm;
274 : float grp_pow_chg, att_val, att_degree;
275 : float xfp_left[L_TRANA48k], xfp_right[L_TRANA48k];
276 : float gr_pow_left[LGW_MAX], gr_pow_right[LGW_MAX];
277 : const float *xfp_;
278 11829 : int16_t Ltrana, Ltrana_2, Lprot, LtranaLog = 0, Lgw, k, burst_len;
279 : int16_t att_always[LGW_MAX]; /* fixed attenuation per frequency group if set to 1*/
280 : int16_t burst_phdith_thresh;
281 : int16_t burst_att_thresh;
282 : float att_per_frame;
283 : int16_t tr_dec[LGW_MAX];
284 :
285 : /* check burst error */
286 11829 : burst_len = time_offs / output_frame + 1;
287 :
288 11829 : set_s( att_always, 0, LGW_MAX );
289 11829 : *ph_dith = 0.0f;
290 :
291 : /* softly shift attenuation just a bit later for estimated "stable" music_content */
292 11829 : burst_phdith_thresh = BURST_PHDITH_THRESH + (int16_t) ( est_mus_content * 1.0f + 0.5f );
293 11829 : burst_att_thresh = BURST_ATT_THRESH + (int16_t) ( est_mus_content * 1.0f + 0.5f );
294 11829 : att_per_frame = (float) ( ATT_PER_FRAME - (int16_t) ( est_mus_content * 1.0f + 0.5f ) ); /* only slighty less att for music */
295 11829 : att_per_frame *= 0.1f;
296 :
297 11829 : if ( burst_len > burst_phdith_thresh )
298 : {
299 : /* increase degree of dither */
300 4616 : *ph_dith = PHASE_DITH * min( 1.0f, ( (float) burst_len - (float) burst_phdith_thresh ) / (float) BURST_PHDITH_RAMPUP_LEN );
301 : }
302 :
303 11829 : att_degree = 0;
304 11829 : if ( burst_len > burst_att_thresh )
305 : {
306 4837 : set_s( att_always, 1, LGW_MAX );
307 :
308 : /* increase degree of attenuation */
309 4837 : if ( burst_len - burst_att_thresh <= PH_ECU_MUTE_START )
310 : {
311 1915 : att_degree = (float) ( burst_len - burst_att_thresh ) * att_per_frame;
312 : }
313 : else
314 : {
315 2922 : att_degree = (float) PH_ECU_MUTE_START * att_per_frame + ( burst_len - burst_att_thresh - PH_ECU_MUTE_START ) * 6.0206f;
316 : }
317 : }
318 :
319 11829 : Lprot = ( 2 * output_frame * 4 ) / 5; /* 4/5==1024/1280, keep mult within short */
320 11829 : Ltrana = Lprot / QUOT_LPR_LTR;
321 11829 : Ltrana_2 = Ltrana / 2;
322 :
323 11829 : if ( output_frame == L_FRAME48k )
324 : {
325 4189 : w_hamm = w_hamm48k_2;
326 4189 : Lgw = LGW48k;
327 : }
328 7640 : else if ( output_frame == L_FRAME32k )
329 : {
330 3840 : w_hamm = w_hamm32k_2;
331 3840 : LtranaLog = L_TRANA_LOG32k;
332 3840 : Lgw = LGW32k;
333 : }
334 : else
335 : {
336 3800 : w_hamm = w_hamm16k_2;
337 3800 : LtranaLog = L_TRANA_LOG16k;
338 3800 : Lgw = LGW16k;
339 : }
340 :
341 11829 : if ( burst_len <= 1 || ( burst_len == 2 && last_fec ) )
342 : {
343 4946 : set_f( alpha, 1.0f, LGW_MAX );
344 4946 : set_f( beta, 0.0f, LGW_MAX );
345 4946 : *beta_mute = BETA_MUTE_FAC_INI;
346 :
347 : /* apply hamming window */
348 4946 : v_mult( xfp, w_hamm, xfp_left, Ltrana_2 );
349 4946 : mult_rev2( xfp + Ltrana_2, w_hamm, xfp_left + Ltrana_2, Ltrana_2 );
350 :
351 4946 : xfp_ = xfp + Lprot - Ltrana;
352 4946 : v_mult( xfp_, w_hamm, xfp_right, Ltrana_2 );
353 4946 : mult_rev2( xfp_ + Ltrana_2, w_hamm, xfp_right + Ltrana_2, Ltrana_2 );
354 :
355 : /* spectrum */
356 4946 : if ( output_frame == L_FRAME48k )
357 : {
358 1838 : fft3( xfp_left, xfp_left, Ltrana );
359 1838 : fft3( xfp_right, xfp_right, Ltrana );
360 : }
361 : else
362 : {
363 3108 : fft_rel( xfp_left, Ltrana, LtranaLog );
364 3108 : fft_rel( xfp_right, Ltrana, LtranaLog );
365 : }
366 :
367 : /* square representation */
368 4946 : fft_spec2( xfp_left, Ltrana );
369 4946 : fft_spec2( xfp_right, Ltrana );
370 :
371 : /* band powers in frequency groups
372 : exclude bin at 0 and at EVS_PI from calculation */
373 4946 : xfp_left[Ltrana_2] = 0.0f;
374 4946 : xfp_right[Ltrana_2] = 0.0f;
375 : }
376 :
377 95021 : for ( k = 0; k < Lgw; k++ )
378 : {
379 83192 : if ( burst_len <= 1 || ( burst_len == 2 && last_fec ) )
380 : {
381 35063 : gr_pow_left[k] = sum_f( xfp_left + gw[k], gw[k + 1] - gw[k] );
382 35063 : gr_pow_right[k] = sum_f( xfp_right + gw[k], gw[k + 1] - gw[k] );
383 :
384 : /* check if transient in any of the bands */
385 35063 : gr_pow_left[k] += FLT_MIN; /* otherwise div by zero may occur */
386 35063 : gr_pow_right[k] += FLT_MIN;
387 :
388 35063 : Xavg[k] = (float) ( sqrt( 0.5f * ( gr_pow_left[k] + gr_pow_right[k] ) / (float) ( gw[k + 1] - gw[k] ) ) );
389 :
390 35063 : grp_pow_chg = gr_pow_right[k] / gr_pow_left[k];
391 :
392 : /* dither phase in case of transient */
393 : /* separate transition detection and application of forced burst dithering */
394 35063 : tr_dec[k] = ( grp_pow_chg > THRESH_TR_LIN ) || ( grp_pow_chg < THRESH_TR_LIN_INV );
395 :
396 : /* magnitude modification */
397 35063 : if ( tr_dec[k] || att_always[k] )
398 : {
399 3576 : att_val = min( MAX_INCREASE_GRPOW_LIN, grp_pow_chg );
400 3576 : att_val = (float) sqrt( att_val );
401 3576 : mag_chg_1st[k] = att_val;
402 3576 : mag_chg[k] = att_val;
403 : }
404 : else
405 : {
406 31487 : mag_chg_1st[k] = 1.0f;
407 31487 : mag_chg[k] = 1.0f;
408 : }
409 : }
410 : else
411 : {
412 48129 : if ( burst_len < OFF_FRAMES_LIMIT )
413 : {
414 35241 : mag_chg[k] = mag_chg_1st[k] * (float) pow( 10.0, -att_degree / 20.0 );
415 : }
416 : else
417 : {
418 12888 : mag_chg[k] = 0;
419 : }
420 :
421 48129 : if ( element_mode != EVS_MONO )
422 : {
423 48122 : if ( k == 0 && burst_len > BETA_MUTE_THR ) /* beta_mute final long term attenuation adjusted only once per frame in the first sub-band, Ref Eq(184) in 26.447 */
424 : {
425 3630 : *beta_mute *= BETA_MUTE_FAC;
426 : }
427 : }
428 : else
429 : {
430 7 : if ( burst_len > BETA_MUTE_THR ) /* legacy incorrect(too fast) EVS_MONO operation, still kept for BE. To be updated after EVS CR, ref Eq (184) in 26.447 */
431 : {
432 0 : *beta_mute *= BETA_MUTE_FAC;
433 : }
434 : }
435 :
436 48129 : alpha[k] = mag_chg[k];
437 48129 : beta[k] = (float) ( sqrt( 1.0f - SQR( alpha[k] ) ) * *beta_mute );
438 48129 : if ( k >= LGW32k - 1 )
439 : {
440 6831 : beta[k] *= 0.1f;
441 : }
442 41298 : else if ( k >= LGW16k - 1 )
443 : {
444 6883 : beta[k] *= 0.5f;
445 : }
446 : }
447 : }
448 :
449 11829 : return;
450 : }
451 :
452 :
453 : /*------------------------------------------------------------------*
454 : * peakfinder()
455 : *
456 : * Peak-picking algorithm
457 : *------------------------------------------------------------------*/
458 :
459 18308 : void peakfinder(
460 : const float *x0, /* i : vector from which the maxima will be found */
461 : const int16_t len0, /* i : length of input vector */
462 : int16_t *plocs, /* o : the indicies of the identified peaks in x0 */
463 : int16_t *cInd, /* o : number of identified peaks */
464 : const float sel, /* i : The amount above surrounding data for a peak to be identified */
465 : const int16_t endpoints /* i : Flag to include endpoints in peak search */
466 : )
467 : {
468 : float minMag, tempMag, leftMin;
469 : float dx0[L_PROT48k_2], x[L_PROT48k_2 + 1], peakMag[MAX_PLOCS];
470 18308 : int16_t k, i, len, tempLoc = 0, foundPeak, ii, xInd;
471 : int16_t *ind, indarr[L_PROT48k_2 + 1], peakLoc[MAX_PLOCS];
472 :
473 18308 : ind = indarr;
474 :
475 : /* Find derivative */
476 18308 : v_sub( x0 + 1, x0, dx0, len0 - 1 );
477 :
478 : /* This is so we find the first of repeated values */
479 2930796 : for ( i = 0; i < len0 - 1; i++ )
480 : {
481 2912488 : if ( dx0[i] == 0.0f )
482 : {
483 102188 : dx0[i] = -1.0e-12f;
484 : }
485 : }
486 :
487 : /* Find where the derivative changes sign
488 : Include endpoints in potential peaks and valleys */
489 18308 : k = 0;
490 :
491 18308 : if ( endpoints )
492 : {
493 4946 : x[k] = x0[0];
494 4946 : ind[k++] = 0;
495 : }
496 :
497 2912488 : for ( i = 1; i < len0 - 1; i++ )
498 : {
499 2894180 : if ( dx0[i - 1] * dx0[i] < 0 )
500 : {
501 1540161 : ind[k] = i;
502 1540161 : x[k++] = x0[i];
503 : }
504 : }
505 :
506 18308 : if ( endpoints )
507 : {
508 4946 : ind[k] = len0 - 1;
509 4946 : x[k++] = x0[len0 - 1];
510 : }
511 : /* x only has the peaks, valleys, and endpoints */
512 18308 : len = k;
513 18308 : minimum( x, len, &minMag );
514 :
515 18308 : if ( ( len > 2 ) || ( !endpoints && ( len > 0 ) ) )
516 : {
517 : /* Set initial parameters for loop */
518 16957 : tempMag = minMag;
519 16957 : foundPeak = 0;
520 16957 : leftMin = minMag;
521 :
522 16957 : if ( endpoints )
523 : {
524 : /* Deal with first point a little differently since tacked it on
525 : Calculate the sign of the derivative since we taked the first point
526 : on it does not necessarily alternate like the rest. */
527 :
528 : /* The first point is larger or equal to the second */
529 4946 : if ( x[0] >= x[1] )
530 : {
531 1158 : ii = -1;
532 1158 : if ( x[1] >= x[2] ) /* x[1] is not extremum -> overwrite with x[0] */
533 : {
534 0 : x[1] = x[0];
535 0 : ind[1] = ind[0];
536 0 : ind++;
537 0 : len--;
538 : }
539 : }
540 : else /* First point is smaller than the second */
541 : {
542 3788 : ii = 0;
543 3788 : if ( x[1] < x[2] ) /* x[1] is not extremum -> overwrite with x[0] */
544 : {
545 0 : x[1] = x[0];
546 0 : ind[1] = ind[0];
547 0 : ind++;
548 0 : len--;
549 : }
550 : }
551 : }
552 : else
553 : {
554 12011 : ii = -1; /* First point is a peak */
555 12011 : if ( len >= 2 )
556 : {
557 12007 : if ( x[1] >= x[0] )
558 : {
559 1833 : ii = 0; /* First point is a valley, skip it */
560 : }
561 : }
562 : }
563 16957 : *cInd = 0;
564 :
565 : /* Loop through extrema which should be peaks and then valleys */
566 784903 : while ( ii < len - 1 )
567 : {
568 776486 : ii++; /* This is a peak */
569 :
570 : /*Reset peak finding if we had a peak and the next peak is bigger
571 : than the last or the left min was small enough to reset.*/
572 776486 : if ( foundPeak )
573 : {
574 129471 : tempMag = minMag;
575 129471 : foundPeak = 0;
576 : }
577 :
578 : /* Make sure we don't iterate past the length of our vector */
579 776486 : if ( ii == len - 1 )
580 : {
581 8540 : break; /* We assign the last point differently out of the loop */
582 : }
583 :
584 : /* Found new peak that was larger than temp mag and selectivity larger
585 : than the minimum to its left. */
586 767946 : if ( ( x[ii] > tempMag ) && ( x[ii] > leftMin + sel ) )
587 : {
588 148214 : tempLoc = ii;
589 148214 : tempMag = x[ii];
590 : }
591 :
592 767946 : ii++; /* Move onto the valley */
593 :
594 : /* Come down at least sel from peak */
595 767946 : if ( !foundPeak && ( tempMag > sel + x[ii] ) )
596 : {
597 131098 : foundPeak = 1; /* We have found a peak */
598 131098 : leftMin = x[ii];
599 131098 : peakLoc[*cInd] = tempLoc; /* Add peak to index */
600 131098 : peakMag[*cInd] = tempMag;
601 131098 : ( *cInd )++;
602 : }
603 636848 : else if ( x[ii] < leftMin ) /* New left minimum */
604 : {
605 117352 : leftMin = x[ii];
606 : }
607 : }
608 :
609 : /* Check end point */
610 16957 : if ( x[len - 1] > tempMag && x[len - 1] > leftMin + sel )
611 : {
612 3358 : peakLoc[*cInd] = len - 1;
613 3358 : peakMag[*cInd] = x[len - 1];
614 3358 : ( *cInd )++;
615 : }
616 13599 : else if ( !foundPeak && tempMag > minMag ) /* Check if we still need to add the last point */
617 : {
618 213 : peakLoc[*cInd] = tempLoc;
619 213 : peakMag[*cInd] = tempMag;
620 213 : ( *cInd )++;
621 : }
622 :
623 : /* Create output */
624 151626 : for ( i = 0; i < *cInd; i++ )
625 : {
626 134669 : plocs[i] = ind[peakLoc[i]];
627 : }
628 : }
629 : else
630 : {
631 1351 : if ( endpoints )
632 : {
633 : /* This is a monotone function where an endpoint is the only peak */
634 0 : xInd = ( x[0] > x[1] ) ? 0 : 1;
635 0 : peakMag[0] = x[xInd];
636 0 : if ( peakMag[0] > minMag + sel )
637 : {
638 0 : plocs[0] = ind[xInd];
639 0 : *cInd = 1;
640 : }
641 : else
642 : {
643 0 : *cInd = 0;
644 : }
645 : }
646 : else
647 : {
648 : /* Input constant or all zeros -- no peaks found */
649 1351 : *cInd = 0;
650 : }
651 : }
652 :
653 18308 : return;
654 : }
655 :
656 :
657 : /*-------------------------------------------------------------------*
658 : * imax_pos()
659 : *
660 : * Get interpolated maximum position
661 : *-------------------------------------------------------------------*/
662 :
663 : /*! r: interpolated maximum position */
664 39357 : float imax_pos(
665 : const float *y /* i : Input vector for peak interpolation */
666 : )
667 : {
668 : float posi, y1, y2, y3, y3_y1, y2i;
669 : float ftmp_den1, ftmp_den2;
670 : /* Seek the extrema of the parabola P(x) defined by 3 consecutive points so that P([-1 0 1]) = [y1 y2 y3] */
671 39357 : y1 = y[0];
672 39357 : y2 = y[1];
673 39357 : y3 = y[2];
674 39357 : y3_y1 = y3 - y1;
675 39357 : ftmp_den1 = ( y1 + y3 - 2 * y2 );
676 39357 : ftmp_den2 = ( 4 * y2 - 2 * y1 - 2 * y3 );
677 :
678 39357 : if ( ftmp_den2 == 0.0f || ftmp_den1 == 0.0f )
679 : {
680 0 : return ( 0.0f ); /* early exit with left-most value */
681 : }
682 :
683 39357 : y2i = -0.125f * SQR( y3_y1 ) / ( ftmp_den1 ) + y2;
684 : /* their corresponding normalized locations */
685 39357 : posi = y3_y1 / ( ftmp_den2 );
686 : /* Interpolated maxima if locations are not within [-1,1], calculated extrema are ignored */
687 39357 : if ( posi >= 1.0f || posi <= -1.0f )
688 : {
689 78 : posi = y3 > y1 ? 1.0f : -1.0f;
690 : }
691 : else
692 : {
693 39279 : if ( y1 >= y2i )
694 : {
695 234 : posi = ( y1 > y3 ) ? -1.0f : 1.0f;
696 : }
697 39045 : else if ( y3 >= y2i )
698 : {
699 0 : posi = 1.0f;
700 : }
701 : }
702 :
703 39357 : return posi + 1.0f;
704 : }
705 :
706 :
707 : /*-------------------------------------------------------------------*
708 : * spec_ana()
709 : *
710 : * Spectral analysis
711 : *-------------------------------------------------------------------*/
712 :
713 4946 : static void spec_ana(
714 : const float *prevsynth, /* i : Input signal */
715 : int16_t *plocs, /* o : The indicies of the identified peaks */
716 : float *plocsi, /* o : Interpolated positions of the identified peaks */
717 : int16_t *num_plocs, /* o : Number of identified peaks */
718 : float *X_sav, /* o : Stored fft spectrum */
719 : const int16_t output_frame, /* i : Frame length */
720 : const int16_t bwidth, /* i : Encoded bandwidth */
721 : const int16_t element_mode, /* i : IVAS element mode */
722 : float *noise_fac, /* o : for few peaks zeroing valleys decision making */
723 : const float pcorr )
724 : {
725 4946 : int16_t i, Lprot, LprotLog2 = 0, hamm_len2 = 0, Lprot2_1, m;
726 : float *pPlocsi;
727 : int16_t *pPlocs;
728 : int16_t currPlocs, endPlocs, Lprot2p1, nJacob;
729 : int16_t n, k;
730 : int16_t st_point;
731 : int16_t end_point;
732 :
733 : float sig, noise, nsr;
734 : float window_corr_step, window_corr;
735 4946 : const float *w_hamm = NULL;
736 : float xfp[L_PROT48k];
737 : float Xmax, Xmin, sel;
738 : int16_t stop_band_start;
739 : int16_t stop_band_length;
740 :
741 4946 : Lprot = 2 * output_frame * L_PROT32k / 1280;
742 4946 : Lprot2_1 = Lprot / 2 + 1;
743 :
744 4946 : if ( output_frame == L_FRAME48k )
745 : {
746 1838 : w_hamm = w_hamm_sana48k_2;
747 1838 : hamm_len2 = L_PROT_HAMM_LEN2_48k;
748 : }
749 3108 : else if ( output_frame == L_FRAME32k )
750 : {
751 1711 : w_hamm = w_hamm_sana32k_2;
752 1711 : hamm_len2 = L_PROT_HAMM_LEN2_32k;
753 1711 : LprotLog2 = 10;
754 : }
755 : else
756 : {
757 1397 : w_hamm = w_hamm_sana16k_2;
758 1397 : hamm_len2 = L_PROT_HAMM_LEN2_16k;
759 1397 : LprotLog2 = 9;
760 : }
761 :
762 : /* Apply hamming-rect window */
763 4946 : mvr2r( prevsynth + hamm_len2, xfp + hamm_len2, Lprot - 2 * hamm_len2 );
764 4946 : if ( element_mode == EVS_MONO )
765 : {
766 60 : v_mult( prevsynth, w_hamm, xfp, hamm_len2 );
767 60 : mult_rev2( prevsynth + Lprot - hamm_len2, w_hamm, xfp + Lprot - hamm_len2, hamm_len2 );
768 : }
769 : else
770 : {
771 4886 : window_corr = w_hamm[0];
772 4886 : window_corr_step = w_hamm[0] / hamm_len2;
773 985622 : for ( i = 0; i < hamm_len2; i++ )
774 : {
775 980736 : xfp[i] = prevsynth[i] * ( w_hamm[i] - window_corr );
776 980736 : xfp[Lprot - i - 1] = prevsynth[Lprot - i - 1] * ( w_hamm[i] - window_corr );
777 980736 : window_corr -= window_corr_step;
778 : }
779 : }
780 :
781 : /* Spectrum */
782 4946 : if ( output_frame == L_FRAME48k )
783 : {
784 1838 : fft3( xfp, xfp, Lprot );
785 : }
786 : else
787 : {
788 3108 : fft_rel( xfp, Lprot, LprotLog2 );
789 : }
790 :
791 : /* Apply zeroing of non-coded FFT spectrum */
792 4946 : if ( output_frame > inner_frame_tbl[bwidth] )
793 : {
794 232 : stop_band_start = 128 << bwidth;
795 232 : stop_band_length = Lprot - ( stop_band_start << 1 );
796 232 : stop_band_start = stop_band_start + 1;
797 232 : set_f( xfp + stop_band_start, 0, stop_band_length );
798 : }
799 :
800 4946 : mvr2r( xfp, X_sav, Lprot );
801 :
802 : /* Magnitude representation */
803 4946 : fft_spec2( xfp, Lprot );
804 :
805 2655140 : for ( i = 0; i < Lprot2_1; i++ )
806 : {
807 2650194 : xfp[i] = (float) sqrt( (double) xfp[i] );
808 : }
809 :
810 : /* Find maxima */
811 4946 : maximum( xfp, Lprot2_1, &Xmax );
812 4946 : minimum( xfp, Lprot2_1, &Xmin );
813 4946 : if ( element_mode == EVS_MONO )
814 : {
815 60 : sel = ( Xmax - Xmin ) * ( 1.0f - PFIND_SENS );
816 : }
817 : else
818 : {
819 4886 : sel = ( Xmax - Xmin ) * ( 1.0f - ST_PFIND_SENS );
820 : }
821 :
822 4946 : peakfinder( xfp, Lprot2_1, plocs, num_plocs, sel, TRUE ); /* NB peak at xfp[0] and xfp Lprot2_1-1 may occur */
823 :
824 : /* Currently not the pitch correlation but some LF correlation */
825 4946 : if ( element_mode != EVS_MONO && *num_plocs > 50 && pcorr < 0.6f )
826 : {
827 28 : *num_plocs = 0;
828 : }
829 :
830 4946 : if ( element_mode == EVS_MONO )
831 : {
832 : /* Refine peaks */
833 734 : for ( m = 0; m < *num_plocs; m++ )
834 : {
835 674 : if ( plocs[m] == 0 )
836 : {
837 0 : plocsi[m] = plocs[m] + imax_pos( &xfp[plocs[m]] );
838 : }
839 674 : else if ( plocs[m] == Lprot / 2 )
840 : {
841 0 : plocsi[m] = plocs[m] - 2 + imax_pos( &xfp[plocs[m] - 2] );
842 : }
843 : else
844 : {
845 674 : plocsi[m] = plocs[m] - 1 + imax_pos( &xfp[plocs[m] - 1] );
846 : }
847 : }
848 : }
849 : else
850 : {
851 :
852 4886 : Lprot2p1 = Lprot / 2 + 1;
853 :
854 : /* Refine peaks */
855 4886 : pPlocsi = plocsi;
856 4886 : pPlocs = plocs;
857 4886 : n = *num_plocs; /* number of peaks to process */
858 :
859 : /* Special case-- The very 1st peak if it is at 0 index position (DC) */
860 : /* With DELTA_CORR_F0_INT == 2 one needs to handle both *pPlocs==0 and *pPlocs==1 */
861 4886 : if ( n > 0 && *pPlocs == 0 ) /* Very 1st peak position possible to have a peak at 0/DC index position. */
862 : {
863 360 : *pPlocsi++ = *pPlocs + imax_pos( &xfp[*pPlocs] );
864 360 : pPlocs++;
865 360 : n = n - 1;
866 : }
867 :
868 4886 : if ( n > 0 && *pPlocs == 1 ) /* Also 2nd peak position uses DC which makes jacobsen unsuitable. */
869 : {
870 391 : *pPlocsi++ = *pPlocs - 1 + imax_pos( &xfp[*pPlocs - 1] );
871 391 : currPlocs = *pPlocs++;
872 391 : n = n - 1;
873 : }
874 :
875 : /* All remaining peaks except the very last two possible integer positions */
876 4886 : currPlocs = *pPlocs++;
877 4886 : endPlocs = Lprot2p1 - DELTA_CORR_F0_INT; /* last *pPlocs position for Jacobsen */
878 :
879 : /* precompute number of turns based on endpoint integer location and make into a proper for loop */
880 4886 : if ( n > 0 )
881 : {
882 4810 : nJacob = n;
883 4810 : if ( sub( endPlocs, plocs[sub( *num_plocs, 1 )] ) <= 0 )
884 : {
885 66 : nJacob = sub( nJacob, 1 );
886 : }
887 :
888 98287 : for ( k = 0; k < nJacob; k++ )
889 : {
890 93477 : *pPlocsi++ = currPlocs + imax2_jacobsen_mag( &( X_sav[currPlocs - 1] ), &( X_sav[Lprot - 1 - currPlocs] ) );
891 93477 : currPlocs = *pPlocs++;
892 : }
893 4810 : n = n - nJacob;
894 : }
895 :
896 : /* At this point there should at most two plocs left to process */
897 : /* the position before fs/2 and fs/2 both use the same magnitude points */
898 4886 : if ( n > 0 )
899 : {
900 : /* [ . . . . . . . ] Lprot/2+1 positions */
901 : /* | | | */
902 : /* 0 (Lprot/2-2) (Lprot/2) */
903 :
904 66 : if ( currPlocs == ( Lprot2p1 - DELTA_CORR_F0_INT ) ) /* Also 2nd last peak position uses fs/2 which makes jacobsen less suitable. */
905 : {
906 51 : *pPlocsi++ = currPlocs - 1 + imax_pos( &xfp[currPlocs - 1] );
907 51 : currPlocs = *pPlocs++;
908 51 : n = n - 1;
909 : }
910 :
911 : /* Here the only remaining point would be a fs/2 plocs */
912 : /* pXfp = xfp + sub(Lprot2,1); already set just a reminder where it
913 : * whould point */
914 66 : if ( n > 0 ) /* fs/2 which makes special case . */
915 : {
916 15 : *pPlocsi++ = currPlocs - 2 + imax_pos( &xfp[currPlocs - 2] );
917 15 : currPlocs = *pPlocs++;
918 15 : n = n - 1;
919 : }
920 : }
921 :
922 : /* For few peaks decide noise floor attenuation */
923 4886 : if ( *num_plocs < 3 && *num_plocs > 0 )
924 : {
925 221 : sig = sum_f( xfp, Lprot2_1 ) + EPSILON;
926 :
927 : /*excluding peaks and neighboring bins*/
928 537 : for ( i = 0; i < *num_plocs; i++ )
929 : {
930 316 : st_point = max( 0, plocs[i] - DELTA_CORR );
931 316 : end_point = min( Lprot2_1 - 1, plocs[i] + DELTA_CORR );
932 316 : set_f( &xfp[st_point], 0.0f, end_point - st_point + 1 );
933 : }
934 221 : noise = sum_f( xfp, Lprot2_1 ) + EPSILON;
935 221 : nsr = noise / sig;
936 :
937 221 : if ( nsr < 0.03f )
938 : {
939 54 : *noise_fac = 0.5f;
940 : }
941 : else
942 : {
943 167 : *noise_fac = 1.0f;
944 : }
945 : }
946 : }
947 :
948 4946 : return;
949 : }
950 :
951 : /*-------------------------------------------------------------------*
952 : * subst_spec()
953 : *
954 : * Substitution spectrum calculation
955 : *-------------------------------------------------------------------*/
956 :
957 11829 : static void subst_spec(
958 : const int16_t *plocs, /* i : The indicies of the identified peaks */
959 : const float *plocsi, /* i : Interpolated positions of the identified peaks */
960 : int16_t *num_plocs, /* i/o: Number of identified peaks */
961 : const int16_t time_offs, /* i : Time offset */
962 : float *X, /* i/o: FFT spectrum */
963 : const float *mag_chg, /* i : Magnitude modification */
964 : const float ph_dith, /* i : Phase dither */
965 : const int16_t *is_trans, /* i : Transient flags */
966 : const int16_t output_frame, /* i : Frame length */
967 : int16_t *seed, /* i/o: Random seed */
968 : const float *alpha, /* i : Magnitude modification factors for fade to average */
969 : const float *beta, /* i : Magnitude modification factors for fade to average */
970 : float beta_mute, /* i : Factor for long-term mute */
971 : const float Xavg[LGW_MAX], /* i : Frequency group averages to fade to */
972 : const int16_t element_mode, /* i : IVAS element mode */
973 : const int16_t ph_ecu_lookahead, /* i : Phase ECU lookahead */
974 : const float noise_fac /* i : noise factor */
975 :
976 : )
977 : {
978 : const float *sincos;
979 : int16_t Xph_short;
980 : float corr_phase[MAX_PLOCS], Xph;
981 : float Lprot_1, cos_F, sin_F, tmp;
982 : int16_t Lprot, Lecu, m, i, e, im_ind, delta_corr_up, delta_corr_dn, delta_tmp;
983 : float mag_chg_local; /* for peak attenuation in burst */
984 : int16_t k;
985 : float one_peak_flag_mask;
986 : float alpha_local;
987 : float beta_local;
988 :
989 11829 : sincos = sincos_t_ext + 128;
990 11829 : Lprot = (int16_t) ( L_PROT32k * output_frame / 640 );
991 11829 : Lprot_1 = 1.0f / Lprot;
992 11829 : Lecu = output_frame * 2;
993 :
994 : /* Correction phase of the identified peaks */
995 11829 : if ( is_trans[0] || is_trans[1] )
996 : {
997 440 : *num_plocs = 0;
998 : }
999 : else
1000 : {
1001 11389 : tmp = PI2 * ( Lecu - ( Lecu - Lprot ) / 2 + NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_ALDO_OLP2_NS ) - ph_ecu_lookahead - output_frame / 2 + time_offs ) * Lprot_1;
1002 269948 : for ( m = 0; m < *num_plocs; m++ )
1003 : {
1004 258559 : corr_phase[m] = plocsi[m] * tmp;
1005 : }
1006 : }
1007 11829 : one_peak_flag_mask = 1; /* all ones mask -> keep */
1008 11829 : if ( element_mode != EVS_MONO )
1009 : {
1010 11768 : if ( ( *num_plocs > 0 ) && sub( *num_plocs, 3 ) < 0 )
1011 : {
1012 288 : one_peak_flag_mask = noise_fac; /* all zeroes mask -> zero */
1013 : }
1014 11768 : if ( *num_plocs == 0 )
1015 : {
1016 1088 : X[0] = 0; /* reset DC if there are no peaks */
1017 1088 : X[shr( Lprot, 1 )] = 0; /* also reset fs/2 if there are no peaks */
1018 : }
1019 : }
1020 :
1021 11829 : i = 1;
1022 11829 : k = 0;
1023 11829 : im_ind = Lprot - 1;
1024 270388 : for ( m = 0; m < *num_plocs; m++ )
1025 : {
1026 258559 : delta_corr_dn = DELTA_CORR;
1027 258559 : delta_corr_up = DELTA_CORR;
1028 :
1029 258559 : if ( m > 0 )
1030 : {
1031 247827 : delta_tmp = ( plocs[m] - plocs[m - 1] - 1 ) / 2;
1032 247827 : if ( delta_tmp < DELTA_CORR )
1033 : {
1034 181773 : delta_corr_dn = delta_tmp;
1035 : }
1036 : }
1037 :
1038 258559 : if ( m < *num_plocs - 1 )
1039 : {
1040 247827 : delta_tmp = ( plocs[m + 1] - plocs[m] - 1 ) / 2;
1041 247827 : if ( delta_tmp < DELTA_CORR )
1042 : {
1043 181773 : delta_corr_up = delta_tmp;
1044 : }
1045 : }
1046 :
1047 : /* Input Xph */
1048 1439382 : while ( i < plocs[m] - delta_corr_dn )
1049 : {
1050 1180823 : *seed = own_random( seed );
1051 :
1052 1180823 : if ( *seed & 0x40 )
1053 : {
1054 588298 : sin_F = sincos[*seed >> 8];
1055 : }
1056 : else
1057 : {
1058 592525 : sin_F = -sincos[*seed >> 8];
1059 : }
1060 :
1061 1180823 : if ( *seed & 0x80 )
1062 : {
1063 591828 : cos_F = sincos[-( *seed >> 8 )];
1064 : }
1065 : else
1066 : {
1067 588995 : cos_F = -sincos[-( *seed >> 8 )];
1068 : }
1069 :
1070 1180823 : if ( element_mode == EVS_MONO )
1071 : {
1072 1138 : tmp = ( X[i] * cos_F - X[im_ind] * sin_F );
1073 1138 : X[im_ind] = ( X[i] * sin_F + X[im_ind] * cos_F );
1074 : }
1075 : else
1076 : {
1077 1179685 : tmp = one_peak_flag_mask * ( X[i] * cos_F - X[im_ind] * sin_F );
1078 1179685 : X[im_ind] = one_peak_flag_mask * ( X[i] * sin_F + X[im_ind] * cos_F );
1079 : }
1080 :
1081 1180823 : if ( alpha[k] < 1.0f )
1082 : {
1083 489630 : *seed = rand_phase( *seed, &sin_F, &cos_F );
1084 489630 : X[i] = alpha[k] * tmp + beta[k] * Xavg[k] * cos_F;
1085 489630 : X[im_ind] = alpha[k] * X[im_ind] + beta[k] * Xavg[k] * sin_F;
1086 : }
1087 : else
1088 : {
1089 691193 : X[i] = mag_chg[k] * tmp;
1090 691193 : X[im_ind] *= mag_chg[k];
1091 : }
1092 1180823 : i++;
1093 1180823 : im_ind--;
1094 1180823 : if ( i >= ivas_gwlpr[k + 1] )
1095 : {
1096 20525 : k++;
1097 : }
1098 : }
1099 :
1100 258559 : e = plocs[m] + delta_corr_up;
1101 258559 : if ( e > Lprot / 2 - 1 )
1102 : {
1103 883 : e = Lprot / 2 - 1;
1104 : }
1105 :
1106 258559 : Xph = corr_phase[m];
1107 : /* extract fractional phase integer index in the range [0...1023] */
1108 258559 : Xph_short = (int16_t) ( 0x000003ff & (int32_t) ( ( Xph * 512 ) / EVS_PI ) );
1109 :
1110 :
1111 258559 : if ( Xph_short >= 512 )
1112 : {
1113 129093 : sin_F = -sincos_t_ext[Xph_short - 512];
1114 129093 : if ( Xph_short < 768 )
1115 : {
1116 64725 : cos_F = -sincos_t_ext[Xph_short - 512 + 256];
1117 : }
1118 : else
1119 : {
1120 64368 : cos_F = sincos_t_ext[-Xph_short + 1024 + 256];
1121 : }
1122 : }
1123 : else
1124 : {
1125 129466 : sin_F = sincos_t_ext[Xph_short];
1126 129466 : if ( Xph_short < 256 )
1127 : {
1128 67172 : cos_F = sincos_t_ext[Xph_short + 256];
1129 : }
1130 : else
1131 : {
1132 62294 : cos_F = -sincos_t_ext[-Xph_short + 256 + 512];
1133 : }
1134 : }
1135 :
1136 2213113 : while ( i <= e )
1137 : {
1138 1954554 : mag_chg_local = mag_chg[k];
1139 :
1140 1954554 : if ( ph_dith != 0.0f )
1141 : {
1142 : /* Call phase randomization only when needed */
1143 973151 : Xph = corr_phase[m];
1144 973151 : *seed = own_random( seed );
1145 973151 : Xph += *seed * ph_dith * PHASE_DITH_SCALE; /* where ph_dith is 0..2PI, or -2PI (in transient), bin phase scaling factor from trans_ana */
1146 :
1147 973151 : if ( ph_dith > 0.0f )
1148 : {
1149 : /* up to 6 dB additional att of peaks in non_transient longer bursts, (when peak phase is randomized) */
1150 : /* 0.5~= sqrt((float)pow(10.0,-6/10.0)); ph_dith= 0..2pi,--> scale=1.0 ...5 */
1151 973151 : mag_chg_local *= 0.5f + ( 1.0f - ( 1.0f / PHASE_DITH ) * ph_dith ) * 0.5f;
1152 : }
1153 :
1154 973151 : Xph_short = (int16_t) ( ( (int32_t) ( ( Xph * 512 ) / EVS_PI ) ) & 0x000003ff );
1155 :
1156 973151 : if ( Xph_short >= 512 )
1157 : {
1158 486880 : sin_F = -sincos_t_ext[Xph_short - 512];
1159 486880 : if ( Xph_short < 768 )
1160 : {
1161 246084 : cos_F = -sincos_t_ext[Xph_short - 512 + 256];
1162 : }
1163 : else
1164 : {
1165 240796 : cos_F = sincos_t_ext[-Xph_short + 1024 + 256];
1166 : }
1167 : }
1168 : else
1169 : {
1170 486271 : sin_F = sincos_t_ext[Xph_short];
1171 486271 : if ( Xph_short < 256 )
1172 : {
1173 241763 : cos_F = sincos_t_ext[Xph_short + 256];
1174 : }
1175 : else
1176 : {
1177 244508 : cos_F = -sincos_t_ext[-Xph_short + 256 + 512];
1178 : }
1179 : }
1180 : }
1181 :
1182 1954554 : tmp = ( X[i] * cos_F - X[im_ind] * sin_F );
1183 1954554 : X[im_ind] = ( X[i] * sin_F + X[im_ind] * cos_F );
1184 1954554 : if ( alpha[k] < 1.0f )
1185 : {
1186 1047270 : alpha_local = mag_chg_local;
1187 1047270 : beta_local = (float) ( beta_mute * sqrt( 1.0f - SQR( alpha_local ) ) );
1188 1047270 : if ( k >= LGW32k - 1 )
1189 : {
1190 474257 : beta_local *= 0.1f;
1191 : }
1192 573013 : else if ( k >= LGW16k - 1 )
1193 : {
1194 283935 : beta_local *= 0.5f;
1195 : }
1196 :
1197 1047270 : *seed = rand_phase( *seed, &sin_F, &cos_F );
1198 1047270 : X[i] = alpha_local * tmp + beta_local * Xavg[k] * cos_F;
1199 1047270 : X[im_ind] = alpha_local * X[im_ind] + beta_local * Xavg[k] * sin_F;
1200 : }
1201 : else
1202 : {
1203 907284 : X[i] = mag_chg_local * tmp;
1204 907284 : X[im_ind] *= mag_chg_local;
1205 : }
1206 :
1207 1954554 : i++;
1208 1954554 : im_ind--;
1209 1954554 : if ( i >= ivas_gwlpr[k + 1] )
1210 : {
1211 35261 : k++;
1212 : }
1213 : }
1214 : }
1215 :
1216 3020655 : while ( i < Lprot / 2 )
1217 : {
1218 3008826 : *seed = own_random( seed );
1219 :
1220 3008826 : if ( *seed & 0x40 )
1221 : {
1222 1506282 : sin_F = sincos[*seed >> 8];
1223 : }
1224 : else
1225 : {
1226 1502544 : sin_F = -sincos[*seed >> 8];
1227 : }
1228 :
1229 3008826 : if ( *seed & 0x80 )
1230 : {
1231 1505685 : cos_F = sincos[-( *seed >> 8 )];
1232 : }
1233 : else
1234 : {
1235 1503141 : cos_F = -sincos[-( *seed >> 8 )];
1236 : }
1237 :
1238 :
1239 3008826 : if ( element_mode == EVS_MONO )
1240 : {
1241 25642 : tmp = ( X[i] * cos_F - X[im_ind] * sin_F );
1242 25642 : X[im_ind] = ( X[i] * sin_F + X[im_ind] * cos_F );
1243 : }
1244 : else
1245 : {
1246 2983184 : tmp = one_peak_flag_mask * ( X[i] * cos_F - X[im_ind] * sin_F );
1247 2983184 : X[im_ind] = one_peak_flag_mask * ( X[i] * sin_F + X[im_ind] * cos_F );
1248 : }
1249 :
1250 3008826 : if ( alpha[k] < 1.0f )
1251 : {
1252 1009112 : *seed = rand_phase( *seed, &sin_F, &cos_F );
1253 1009112 : X[i] = alpha[k] * tmp + beta[k] * Xavg[k] * cos_F;
1254 1009112 : X[im_ind] = alpha[k] * X[im_ind] + beta[k] * Xavg[k] * sin_F;
1255 1009112 : im_ind--;
1256 : }
1257 : else
1258 : {
1259 1999714 : X[i] = mag_chg[k] * tmp;
1260 1999714 : X[im_ind--] *= mag_chg[k];
1261 : }
1262 3008826 : i++;
1263 :
1264 3008826 : if ( i >= ivas_gwlpr[k + 1] )
1265 : {
1266 27406 : k++;
1267 : }
1268 : }
1269 :
1270 11829 : return;
1271 : }
1272 :
1273 : /*--------------------------------------------------------------------------
1274 : * rec_wtda()
1275 : *
1276 : * Windowing and TDA of reconstructed frame
1277 : *--------------------------------------------------------------------------*/
1278 :
1279 11829 : static void rec_wtda(
1280 : float *X, /* i/o: ECU frame / unwindowed ECU frame */
1281 : float *ecu_rec, /* o : Reconstructed frame in tda domain */
1282 : const int16_t output_frame, /* i : Frame length */
1283 : const int16_t Lprot, /* i : Prototype frame length */
1284 : const float old_dec[270], /* i : end of last decoded for OLA before tda and itda */
1285 : const int16_t element_mode, /* i : IVAS element mode */
1286 : const int16_t *num_p, /* i : Number of peaks */
1287 : const int16_t *plocs /* i : Peak locations */
1288 : )
1289 : {
1290 : int16_t timesh;
1291 : int16_t xf_len;
1292 : int16_t i;
1293 : float *p_ecu;
1294 : float g;
1295 : float tbl_delta;
1296 : float xsubst_[2 * L_FRAME48k];
1297 : const float *w_hamm;
1298 : float *pX_start, *pX_end;
1299 : float tmp;
1300 : int16_t hamm_len2;
1301 : float *pNew;
1302 : const float *pOldW, *pNewW;
1303 : float xfwin[NS2SA( L_FRAME48k * FRAMES_PER_SEC, N_ZERO_MDCT_NS - ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 )];
1304 : const float *pOld;
1305 : int16_t copy_len;
1306 : int16_t ola_len;
1307 :
1308 11829 : copy_len = NS2SA( output_frame * FRAMES_PER_SEC, ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 ); /* prototype fill on each side of xsubst to fill MDCT Frame */
1309 11829 : ola_len = NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS - ( 2 * FRAME_SIZE_NS - L_PROT_NS ) / 2 ); /* remaining lengt of LA_ZEROS to overlap add decoded with xsubst */
1310 :
1311 11829 : if ( output_frame == L_FRAME48k )
1312 : {
1313 4189 : w_hamm = w_hamm_sana48k_2;
1314 4189 : hamm_len2 = L_PROT_HAMM_LEN2_48k;
1315 : }
1316 7640 : else if ( output_frame == L_FRAME32k )
1317 : {
1318 3840 : w_hamm = w_hamm_sana32k_2;
1319 3840 : hamm_len2 = L_PROT_HAMM_LEN2_32k;
1320 : }
1321 : else
1322 : {
1323 3800 : w_hamm = w_hamm_sana16k_2;
1324 3800 : hamm_len2 = L_PROT_HAMM_LEN2_16k;
1325 : }
1326 :
1327 11829 : if ( element_mode != EVS_MONO && *num_p > 0 && plocs[0] > 3 )
1328 : {
1329 : /* Perform inverse windowing of hammrect */
1330 5741 : pX_start = X;
1331 5741 : pX_end = X + Lprot - 1;
1332 1278509 : for ( i = 0; i < hamm_len2; i++ )
1333 : {
1334 1272768 : tmp = 1.0f / *w_hamm;
1335 1272768 : *pX_start *= tmp;
1336 1272768 : *pX_end *= tmp;
1337 1272768 : pX_start++;
1338 1272768 : pX_end--;
1339 1272768 : w_hamm++;
1340 : }
1341 : }
1342 :
1343 : /* extract reconstructed frame with aldo window */
1344 11829 : timesh = NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ) - ( 2 * output_frame - Lprot ) / 2;
1345 :
1346 11829 : set_f( xsubst_, 0.0f, 2 * output_frame - Lprot + timesh );
1347 11829 : mvr2r( X, xsubst_ + 2 * output_frame - Lprot + timesh, Lprot - timesh );
1348 :
1349 : /* Copy and OLA look ahead zero part of MDCT window from decoded signal */
1350 11829 : if ( element_mode != EVS_MONO )
1351 : {
1352 11768 : mvr2r( old_dec, xsubst_ + NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS ), copy_len ); /* also need to scale to Q0 ?? */
1353 11768 : pOld = old_dec + copy_len;
1354 11768 : pNew = xsubst_ + copy_len + NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS );
1355 11768 : sinq( EVS_PI / ( ola_len * 2 ), 0.0f, ola_len, xfwin );
1356 11768 : v_mult( xfwin, xfwin, xfwin, ola_len ); /* xfwin = sin^2 of 0..pi/4 */
1357 11768 : pOldW = xfwin + ola_len - 1;
1358 11768 : pNewW = xfwin;
1359 633896 : for ( i = 0; i < ola_len; i++ )
1360 : {
1361 622128 : *pNew = *pOld * *pOldW + *pNew * *pNewW;
1362 622128 : pOld += 1;
1363 622128 : pNew += 1;
1364 622128 : pOldW -= 1;
1365 622128 : pNewW += 1;
1366 : }
1367 : }
1368 : else
1369 : {
1370 : /* Smoothen onset of ECU frame */
1371 61 : xf_len = (int16_t) ( (float) output_frame * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) - ( output_frame - Lprot / 2 );
1372 61 : p_ecu = xsubst_ + 2 * output_frame - Lprot + timesh;
1373 61 : tbl_delta = 64.f / xf_len; /* 64 samples = 1/4 cycle in sincos_t */
1374 3155 : for ( i = 0; i < xf_len; i++, p_ecu++ )
1375 : {
1376 3094 : g = sincos_t[( (int16_t) ( i * tbl_delta ) )];
1377 3094 : g *= g;
1378 3094 : *p_ecu = g * ( *p_ecu );
1379 : }
1380 : }
1381 :
1382 : /* Apply TDA and windowing to ECU frame */
1383 11829 : wtda( xsubst_ + output_frame, ecu_rec, NULL, ALDO_WINDOW, ALDO_WINDOW, output_frame );
1384 :
1385 11829 : return;
1386 : }
1387 :
1388 :
1389 : /*--------------------------------------------------------------------------
1390 : * rec_frame()
1391 : *
1392 : * Frame reconstruction
1393 : *--------------------------------------------------------------------------*/
1394 :
1395 11829 : static void rec_frame(
1396 : float *X, /* i/o: FFT spectrum / IFFT of spectrum */
1397 : float *ecu_rec, /* o : Reconstructed frame in tda domain */
1398 : const int16_t output_frame, /* i : Frame length */
1399 : const float *old_dec, /* i : end of last decoded for OLA before tda and itda */
1400 : const int16_t element_mode, /* i : IVAS element mode */
1401 : const int16_t *num_p, /* i : Number of peaks */
1402 : const int16_t *plocs /* i : Peak locations */
1403 : )
1404 : {
1405 11829 : int16_t Lprot, LprotLog2 = 0;
1406 :
1407 11829 : Lprot = 2 * output_frame * L_PROT32k / 1280;
1408 :
1409 11829 : if ( output_frame == L_FRAME48k )
1410 : {
1411 4189 : LprotLog2 = 9;
1412 : }
1413 7640 : else if ( output_frame == L_FRAME32k )
1414 : {
1415 3840 : LprotLog2 = 10;
1416 : }
1417 : else
1418 : {
1419 3800 : LprotLog2 = 9;
1420 : }
1421 :
1422 : /* extend spectrum and IDFT */
1423 11829 : if ( output_frame == L_FRAME48k )
1424 : {
1425 4189 : ifft3( X, X, Lprot );
1426 : }
1427 : else
1428 : {
1429 7640 : ifft_rel( X, Lprot, LprotLog2 );
1430 : }
1431 :
1432 11829 : rec_wtda( X, ecu_rec, output_frame, Lprot, old_dec, element_mode, num_p, plocs );
1433 :
1434 11829 : return;
1435 : }
1436 :
1437 :
1438 : /*--------------------------------------------------------------------------
1439 : * fir_dwn()
1440 : *
1441 : * FIR downsampling filter
1442 : *--------------------------------------------------------------------------*/
1443 :
1444 11929 : static void fir_dwn(
1445 : const float x[], /* i : input vector */
1446 : const float h[], /* i : impulse response of the FIR filter */
1447 : float y[], /* o : output vector (result of filtering) */
1448 : const int16_t L, /* i : input vector size */
1449 : const int16_t K, /* i : order of the FIR filter (K+1 coefs.) */
1450 : const int16_t decimation /* i : decimation */
1451 : )
1452 : {
1453 : float s;
1454 : int16_t i, j, k, mmax;
1455 :
1456 11929 : k = 0;
1457 :
1458 : /* do the filtering */
1459 3769564 : for ( i = K / 2; i < L; i += decimation )
1460 : {
1461 3757635 : s = x[i] * h[0];
1462 :
1463 3757635 : if ( i < K )
1464 : {
1465 59645 : mmax = i;
1466 : }
1467 : else
1468 : {
1469 3697990 : mmax = K;
1470 : }
1471 :
1472 155811405 : for ( j = 1; j <= mmax; j++ )
1473 : {
1474 152053770 : s += h[j] * x[i - j];
1475 : }
1476 :
1477 3757635 : y[k] = s;
1478 3757635 : k++;
1479 : }
1480 :
1481 71574 : for ( ; i < L + K / 2; i += decimation )
1482 : {
1483 59645 : s = 0;
1484 :
1485 1999725 : for ( j = i - L + 1; j <= K; j++ )
1486 : {
1487 1940080 : s += h[j] * x[i - j];
1488 : }
1489 :
1490 59645 : y[k] = s;
1491 59645 : k++;
1492 : }
1493 :
1494 11929 : return;
1495 : }
1496 :
1497 :
1498 : /*--------------------------------------------------------------------------
1499 : * fec_ecu_pitch()
1500 : *
1501 : * Pitch/correlation analysis and adaptive analysis frame length calculation
1502 : *--------------------------------------------------------------------------*/
1503 :
1504 11929 : static void fec_ecu_pitch(
1505 : const float *prevsynth, /* i : previous synthesis */
1506 : float *prevsynth_LP, /* o : down-sampled synthesis */
1507 : const int16_t L, /* i : Output frame length */
1508 : int16_t *N, /* o : Analysis frame length in 8kHz */
1509 : float *min_corr, /* o : correlation */
1510 : int16_t *decimatefator, /* o : Decimation factor */
1511 : const int16_t HqVoicing /* i : Hq voicing flag */
1512 : )
1513 : {
1514 : int16_t i, filt_size;
1515 : float accA, accB, accC, Ryy;
1516 : int16_t delay_ind, k, cb_start, cb_end, tmp_short, Lon20;
1517 : float Asr_LP[FEC_DCIM_FILT_SIZE_MAX + 1];
1518 :
1519 11929 : switch ( L )
1520 : {
1521 4222 : case L_FRAME48k:
1522 4222 : *decimatefator = 6;
1523 4222 : filt_size = 60;
1524 4222 : mvr2r( Asr_LP48, Asr_LP, filt_size + 1 );
1525 4222 : break;
1526 3878 : case L_FRAME32k:
1527 3878 : *decimatefator = 4;
1528 3878 : filt_size = 40;
1529 3878 : mvr2r( Asr_LP32, Asr_LP, filt_size + 1 );
1530 3878 : break;
1531 3829 : case L_FRAME16k:
1532 3829 : *decimatefator = 2;
1533 3829 : filt_size = 20;
1534 3829 : mvr2r( Asr_LP16, Asr_LP, filt_size + 1 );
1535 3829 : break;
1536 0 : default:
1537 0 : *decimatefator = 2;
1538 0 : filt_size = 40;
1539 0 : mvr2r( Asr_LP16, Asr_LP, filt_size + 1 );
1540 0 : break;
1541 : }
1542 :
1543 : /* We need to inverse the ALDO window */
1544 :
1545 : /* Resampling to work at 8Khz */
1546 11929 : fir_dwn( prevsynth, Asr_LP, prevsynth_LP, 2 * L, filt_size, *decimatefator ); /* resampling without delay */
1547 :
1548 11929 : Lon20 = (int16_t) ( ( L / 20 ) / *decimatefator );
1549 :
1550 : /* Correlation analysis */
1551 11929 : *min_corr = 0;
1552 11929 : accC = 0;
1553 584521 : for ( k = 0; k < 6 * Lon20; k++ )
1554 : {
1555 572592 : accC += prevsynth_LP[34 * Lon20 + k] * prevsynth_LP[34 * Lon20 + k];
1556 : }
1557 :
1558 11929 : if ( HqVoicing == 1 )
1559 : {
1560 4 : cb_start = 0;
1561 4 : cb_end = 33 * Lon20;
1562 : }
1563 : else
1564 : {
1565 11925 : cb_start = 0;
1566 11925 : cb_end = 28 * Lon20;
1567 : }
1568 :
1569 11929 : tmp_short = 34 * Lon20;
1570 11929 : accB = 0;
1571 11929 : delay_ind = cb_start;
1572 2113735 : for ( i = cb_start; i < cb_end; i++ ) /* cb_end = 35 let 6 ms min of loop size */
1573 : {
1574 2104664 : accA = 0;
1575 2104664 : if ( i == cb_start )
1576 : {
1577 11929 : accB = 0;
1578 584521 : for ( k = 0; k < 6 * Lon20; k++ )
1579 : {
1580 572592 : accA += prevsynth_LP[i + k] * prevsynth_LP[tmp_short + k];
1581 572592 : accB += prevsynth_LP[i + k] * prevsynth_LP[i + k];
1582 : }
1583 : }
1584 : else
1585 : {
1586 2092735 : accB = accB - prevsynth_LP[i - 1] * prevsynth_LP[i - 1] + prevsynth_LP[i + 6 * Lon20 - 1] * prevsynth_LP[i + 6 * Lon20 - 1];
1587 102544015 : for ( k = 0; k < 6 * Lon20; k++ )
1588 : {
1589 100451280 : accA += prevsynth_LP[i + k] * prevsynth_LP[tmp_short + k];
1590 : }
1591 : }
1592 :
1593 : /* tests to avoid division by zero */
1594 2104664 : if ( accB <= 0 )
1595 : {
1596 0 : accB = 1.0f;
1597 : }
1598 :
1599 2104664 : if ( accC <= 0 )
1600 : {
1601 0 : accC = 1.0f;
1602 : }
1603 :
1604 2104664 : if ( accB * accC <= 0 )
1605 : {
1606 0 : Ryy = accA;
1607 : }
1608 : else
1609 : {
1610 2104664 : Ryy = accA / (float) sqrt( ( accB * accC ) );
1611 : }
1612 :
1613 2104664 : if ( Ryy > *min_corr )
1614 : {
1615 89532 : *min_corr = Ryy;
1616 89532 : delay_ind = i;
1617 : }
1618 :
1619 2104664 : if ( HqVoicing == 0 && *min_corr > 0.95f )
1620 : {
1621 2858 : break;
1622 : }
1623 : }
1624 :
1625 11929 : *N = 40 * Lon20 - delay_ind - 6 * Lon20;
1626 :
1627 11929 : return;
1628 : }
1629 :
1630 :
1631 : /*--------------------------------------------------------------------------
1632 : * fec_ecu_dft()
1633 : *
1634 : * DFT analysis on adaptive frame length. Analysis frame stretched to
1635 : * next power of 2 using linear interpolation.
1636 : *--------------------------------------------------------------------------*/
1637 :
1638 100 : static void fec_ecu_dft(
1639 : const float *prevsynth_LP, /* i : Downsampled past synthesis (2*160 samples) */
1640 : const int16_t N, /* i : Analysis frame length in 8 kHz (corr. max) */
1641 : float *Tfr, /* o : DFT coefficients, real part */
1642 : float *Tfi, /* o : DFT coefficients, imag part */
1643 : float *sum_Tf_abs, /* o : Sum of magnitude spectrum */
1644 : float *Tf_abs, /* o : Magnitude spectrum */
1645 : int16_t *Nfft, /* o : DFT analysis length 2^(nextpow2(N)) */
1646 : const int16_t element_mode /* i : IVAS element mode */
1647 : )
1648 : {
1649 : float target[2 * L_FRAME8k], tmp;
1650 : int16_t i, Lon20, tmp_short, N_LP, k;
1651 : int16_t alignment_point;
1652 :
1653 100 : Lon20 = (int16_t) 160 / 20;
1654 100 : if ( element_mode == EVS_MONO )
1655 : {
1656 16 : alignment_point = 2 * 160 - 3 * Lon20;
1657 : }
1658 : else
1659 : {
1660 84 : alignment_point = 2 * 160;
1661 : }
1662 :
1663 :
1664 6770 : for ( i = 0; i < N; i++ )
1665 : {
1666 6670 : target[i] = prevsynth_LP[alignment_point - N + i];
1667 : }
1668 :
1669 : /* DFT */
1670 100 : *sum_Tf_abs = 0;
1671 100 : *Nfft = (int16_t) pow( 2, (int16_t) ceil( log( N ) / log( 2 ) ) );
1672 100 : tmp = ( (float) N - 1.0f ) / ( (float) *Nfft - 1.0f );
1673 :
1674 100 : set_f( Tfr, 0.0f, *Nfft );
1675 100 : set_f( Tfi, 0.0f, *Nfft );
1676 100 : Tfr[0] = target[0];
1677 100 : Tfr[*Nfft - 1] = target[N - 1];
1678 9308 : for ( i = 1; i < *Nfft - 1; i++ ) /* interpolation for FFT */
1679 : {
1680 9208 : tmp_short = (int16_t) floor( i * tmp );
1681 9208 : Tfr[i] = target[tmp_short] + ( (float) i * tmp - ( (float) tmp_short ) ) * ( target[tmp_short + 1] - target[tmp_short] );
1682 : }
1683 :
1684 100 : DoRTFTn( Tfr, Tfi, *Nfft );
1685 100 : N_LP = (int16_t) ceil( *Nfft / 2 );
1686 :
1687 4804 : for ( k = 0; k < N_LP; k++ )
1688 : {
1689 4704 : Tf_abs[k] = (float) sqrt( Tfr[k] * Tfr[k] + Tfi[k] * Tfi[k] );
1690 4704 : *sum_Tf_abs += Tf_abs[k];
1691 : }
1692 :
1693 100 : return;
1694 : }
1695 :
1696 : /*--------------------------------------------------------------------------*
1697 : * singenerator()
1698 : *
1699 : * fast cosinus generator Amp*cos(2*pi*freq+phi)
1700 : *--------------------------------------------------------------------------*/
1701 :
1702 :
1703 707 : static void singenerator(
1704 : const int16_t L, /* i : size of output */
1705 : const float cosfreq, /* i : cosine of 1-sample dephasing at the given frequency */
1706 : const float sinfreq, /* i : sine of 1-sample dephasing at the given frequency */
1707 : const float a_re, /* i : real part of complex spectral coefficient at the given frequency */
1708 : const float a_im, /* i : imag part of complex spectral coefficient at the given frequency */
1709 : float xx[] /* o : output vector */
1710 : )
1711 : {
1712 :
1713 : float *ptr, L_C0, L_S0, L_C1, L_S1;
1714 : float C0, S0, C1, S1;
1715 : int16_t i;
1716 :
1717 707 : L_C0 = a_re;
1718 707 : S0 = a_im;
1719 :
1720 707 : ptr = xx;
1721 :
1722 707 : *ptr = *ptr + L_C0;
1723 707 : ptr++;
1724 :
1725 465600 : for ( i = 0; i < L / 2 - 1; i++ )
1726 : {
1727 464893 : C0 = L_C0;
1728 464893 : L_C1 = C0 * cosfreq;
1729 464893 : L_C1 = L_C1 - S0 * sinfreq;
1730 464893 : L_S1 = C0 * sinfreq;
1731 464893 : S1 = L_S1 + S0 * cosfreq;
1732 464893 : *ptr = *ptr + L_C1;
1733 464893 : ptr++;
1734 :
1735 464893 : C1 = L_C1;
1736 464893 : L_C0 = C1 * cosfreq;
1737 464893 : L_C0 = L_C0 - S1 * sinfreq;
1738 464893 : L_S0 = C1 * sinfreq;
1739 464893 : S0 = L_S0 + S1 * cosfreq;
1740 464893 : *ptr = *ptr + L_C0;
1741 464893 : ptr++;
1742 : }
1743 :
1744 707 : C0 = L_C0;
1745 707 : L_C1 = C0 * cosfreq;
1746 707 : L_C1 = L_C1 - S0 * sinfreq;
1747 707 : *ptr = *ptr + L_C1;
1748 707 : ptr++;
1749 :
1750 707 : return;
1751 : }
1752 :
1753 :
1754 : /*--------------------------------------------------------------------------
1755 : * sinusoidal_synthesis()
1756 : *
1757 : * ECU frame sinusoid generation
1758 : *--------------------------------------------------------------------------*/
1759 :
1760 100 : static void sinusoidal_synthesis(
1761 : const float *Tfr, /* i : DFT coefficients, real part */
1762 : const float *Tfi, /* i : DFT coefficients, imag part */
1763 : float *Tf_abs, /* i : Magnitude spectrum */
1764 : const int16_t N, /* i : Analysis frame length in 8 kHz (corr. max) */
1765 : const int16_t L, /* i : Output frame length */
1766 : const int16_t decimate_factor, /* i : Downsampling factor */
1767 : const int16_t Nfft, /* i : DFT analysis length 2^(nextpow2(N)) */
1768 : const float sum_Tf_abs, /* i : Sum of magnitude spectrum */
1769 : float *synthesis, /* o : ECU sinusoidal synthesis */
1770 : const int16_t HqVoicing /* i : HQ voicing flag */
1771 : )
1772 : {
1773 100 : int16_t i, k, nb_pulses, indmax = 0, nb_pulses_final;
1774 : int16_t pulses[FEC_MAX / 2];
1775 : float a_re[FEC_NB_PULSE_MAX], a_im[FEC_NB_PULSE_MAX], cosfreq, sinfreq;
1776 : float freq[FEC_NB_PULSE_MAX], tmp;
1777 : float mmax, cumsum;
1778 100 : int16_t Lon20 = 8;
1779 :
1780 : /* peak selection */
1781 : int16_t PL, cpt;
1782 : float old, new_s;
1783 : int16_t *p_pulses;
1784 : int16_t glued;
1785 :
1786 100 : p_pulses = pulses;
1787 100 : nb_pulses = 0;
1788 100 : new_s = Tf_abs[1];
1789 100 : glued = 1;
1790 100 : cpt = 0;
1791 100 : old = 0;
1792 :
1793 100 : PL = 0;
1794 100 : if ( N > Lon20 * 10 || HqVoicing )
1795 : {
1796 14 : PL = 1;
1797 : }
1798 2867 : while ( cpt <= N / 2 - 1 - 2 )
1799 : {
1800 2767 : if ( Tf_abs[cpt] > old && Tf_abs[cpt] > new_s )
1801 : {
1802 884 : glued = cpt;
1803 :
1804 2095 : for ( i = glued; i < cpt + PL + 1; i++ )
1805 : {
1806 1211 : *p_pulses++ = i;
1807 1211 : nb_pulses++;
1808 : }
1809 884 : old = Tf_abs[cpt + PL];
1810 884 : new_s = Tf_abs[cpt + 2 + PL];
1811 884 : cpt = cpt + PL + 1;
1812 884 : glued = 1;
1813 : }
1814 : else
1815 : {
1816 1883 : old = Tf_abs[cpt];
1817 1883 : new_s = Tf_abs[cpt + 2];
1818 1883 : cpt++;
1819 1883 : glued = 0;
1820 : }
1821 : }
1822 :
1823 :
1824 100 : nb_pulses_final = 0;
1825 :
1826 : /* peak selection : keep the more energetics (max 20) */
1827 100 : tmp = 1.0f / (float) ( Nfft / 2 );
1828 100 : cumsum = 0;
1829 770 : for ( i = 0; i < min( FEC_NB_PULSE_MAX, nb_pulses ); i++ )
1830 : {
1831 707 : mmax = 0;
1832 15897 : for ( k = 0; k < nb_pulses; k++ )
1833 : {
1834 15190 : if ( Tf_abs[pulses[k]] > mmax )
1835 : {
1836 1263 : mmax = Tf_abs[pulses[k]];
1837 1263 : indmax = pulses[k];
1838 : }
1839 : }
1840 707 : cumsum += Tf_abs[indmax];
1841 :
1842 707 : if ( HqVoicing || cumsum < sum_Tf_abs * 0.7f )
1843 : {
1844 670 : a_re[i] = Tfr[indmax] * tmp;
1845 670 : a_im[i] = Tfi[indmax] * tmp;
1846 670 : freq[i] = (float) indmax * 2 / ( (float) N );
1847 670 : nb_pulses_final++;
1848 670 : Tf_abs[indmax] = -1;
1849 : }
1850 : else
1851 : {
1852 37 : a_re[i] = Tfr[indmax] * tmp;
1853 37 : a_im[i] = Tfi[indmax] * tmp;
1854 37 : freq[i] = (float) indmax * 2 / ( (float) N );
1855 37 : nb_pulses_final++;
1856 37 : break;
1857 : }
1858 : }
1859 :
1860 100 : nb_pulses = nb_pulses_final;
1861 :
1862 : /* sinusoidal synthesis */
1863 100 : set_f( synthesis, 0.0f, 40 * L / 20 );
1864 :
1865 100 : if ( HqVoicing )
1866 : {
1867 2 : k = 40 * L / 20;
1868 : }
1869 : else
1870 : {
1871 98 : k = 40 * L / 20;
1872 : }
1873 :
1874 807 : for ( i = 0; i < nb_pulses; i++ )
1875 : {
1876 707 : cosfreq = (float) cos( EVS_PI * freq[i] / (float) decimate_factor );
1877 707 : sinfreq = (float) sin( EVS_PI * freq[i] / (float) decimate_factor );
1878 707 : singenerator( k, cosfreq, sinfreq, a_re[i], a_im[i], synthesis );
1879 : }
1880 :
1881 100 : return;
1882 : }
1883 :
1884 : /*--------------------------------------------------------------------------
1885 : * fec_noise_filling()
1886 : *
1887 : * Adds noise component to ECU frame by
1888 : * - subtracting the sinusoidal synthesis from the analysis frame
1889 : * - copying noise segments at random indices and adding them together
1890 : * with an overlap-add operation
1891 : * Copying the beginning of the frame from the past synthesis and aligning
1892 : * it to be inserted into wtda
1893 : *--------------------------------------------------------------------------*/
1894 :
1895 100 : static void fec_noise_filling(
1896 : const float *prevsynth, /* i : Past synthesis buffer (length 2*L) */
1897 : float *synthesis, /* i/o: Sinusoidal ECU / Sinusoidal ECU + noise */
1898 : const int16_t L, /* i : Output frame length */
1899 : const int16_t N, /* i : Analysis frame length in 8 kHz (corr. max) */
1900 : const int16_t HqVoicing, /* i : HQ voicing flag */
1901 : float *gapsynth, /* o : Buffer for crossfade to good frame */
1902 : int16_t *ni_seed_forfec, /* i/o: Random seed for picking noise segments */
1903 : const int16_t element_mode, /* i : IVAS element mode */
1904 : const float *old_out )
1905 : {
1906 : float SS[L_FRAME48k / 2], tmp;
1907 : int16_t Rnd_N_noise;
1908 : int16_t k, kk, i;
1909 : int16_t N_noise;
1910 : float noisevect[34 * L_FRAME48k / 20];
1911 : const float *p_mdct_ola;
1912 : int16_t alignment_point;
1913 :
1914 100 : if ( element_mode == EVS_MONO )
1915 : {
1916 16 : alignment_point = 2 * L - 3 * L / 20;
1917 : }
1918 : else
1919 : {
1920 84 : alignment_point = 2 * L;
1921 : }
1922 100 : mvr2r( prevsynth + alignment_point - N, noisevect, N );
1923 :
1924 :
1925 : /* Noise addition on full band */
1926 : /* residual */
1927 100 : if ( N < L )
1928 : {
1929 95 : N_noise = ( N / 2 );
1930 22851 : for ( k = 0; k < N; k++ )
1931 : {
1932 22756 : noisevect[k] = ( noisevect[k] - synthesis[k] );
1933 : }
1934 : }
1935 : else
1936 : {
1937 5 : N_noise = L / 2;
1938 3525 : for ( k = 0; k < L; k++ )
1939 : {
1940 3520 : noisevect[k] = ( noisevect[N - L + k] - synthesis[N - L + k] );
1941 : }
1942 : }
1943 :
1944 100 : if ( HqVoicing )
1945 : {
1946 548 : for ( i = 0; i < N; i++ )
1947 : {
1948 546 : noisevect[i] *= 0.25f;
1949 : }
1950 : }
1951 :
1952 100 : kk = 0;
1953 100 : k = 0;
1954 100 : Rnd_N_noise = N_noise;
1955 :
1956 2037 : while ( k < 2 * L )
1957 : {
1958 1937 : if ( kk == 0 )
1959 : {
1960 990 : tmp = ( ( own_random( ni_seed_forfec ) / (PCM16_TO_FLT_FAC) *0.2f ) + 0.5f );
1961 990 : kk = 1;
1962 : }
1963 : else
1964 : {
1965 947 : tmp = ( ( own_random( ni_seed_forfec ) / (PCM16_TO_FLT_FAC) *0.3f ) + 0.7f );
1966 947 : kk = 0;
1967 : }
1968 :
1969 1937 : Rnd_N_noise = (int16_t) ( (float) N_noise * tmp );
1970 :
1971 1937 : sinq( (const float) EVS_PI / ( 2.0f * (float) Rnd_N_noise ), (const float) EVS_PI / ( 4.0f * (float) Rnd_N_noise ), (const int16_t) Rnd_N_noise, SS );
1972 :
1973 136470 : for ( i = 0; i < Rnd_N_noise; i++ )
1974 : {
1975 134533 : if ( k < 2 * L )
1976 : {
1977 130560 : synthesis[k] += ( noisevect[N_noise - Rnd_N_noise + i] * SS[i] + noisevect[N_noise + i] * SS[Rnd_N_noise - i - 1] ); /* *noisefact; */
1978 : }
1979 134533 : k++;
1980 : }
1981 : }
1982 :
1983 100 : if ( element_mode == EVS_MONO )
1984 : {
1985 16 : kk = 7 * L / 20;
1986 16 : p_mdct_ola = prevsynth + 37 * L / 20;
1987 : }
1988 : else
1989 : {
1990 84 : kk = NS2SA( L * FRAMES_PER_SEC, N_ZERO_MDCT_NS );
1991 84 : p_mdct_ola = old_out + kk;
1992 : }
1993 :
1994 : /* overlappadd with the ms of valid mdct of the last frame */
1995 100 : sinq( EVS_PI / ( 6.0f * L / 20.0f ), EVS_PI / ( 12.0f * L / 20.0f ), 3 * L / 20, SS );
1996 :
1997 9892 : for ( k = 0; k < 3 * L / 20; k++ )
1998 : {
1999 9792 : tmp = SS[k] * SS[k];
2000 9792 : synthesis[k] = p_mdct_ola[k] * ( 1 - tmp ) + synthesis[k] * tmp;
2001 : }
2002 :
2003 100 : mvr2r( synthesis, synthesis + kk, 2 * L - kk );
2004 100 : mvr2r( synthesis + L, gapsynth, L );
2005 :
2006 100 : mvr2r( prevsynth + alignment_point - kk, synthesis, kk );
2007 :
2008 100 : return;
2009 : }
2010 :
2011 :
2012 : /*--------------------------------------------------------------------------
2013 : * fec_alg()
2014 : *
2015 : * Pitch based error-concealment algorithm with adaptive analysis frame
2016 : * length
2017 : *--------------------------------------------------------------------------*/
2018 :
2019 100 : static void fec_alg(
2020 : const float *prevsynth, /* i : previous synthesis */
2021 : const float *prevsynth_LP, /* i : down-sampled synthesis */
2022 : float *ecu_rec, /* o : ECU frame with Windowing/TDA */
2023 : const int16_t output_frame, /* i : Output frame length */
2024 : const int16_t N, /* i : Analysis frame length in 8 kHz (corr. max) */
2025 : const int16_t decimatefactor, /* i : Downsampling factor */
2026 : const int16_t HqVoicing, /* i : HQ voicing flag */
2027 : float *gapsynth, /* o : Buffer for crossfade to good frame */
2028 : int16_t *ni_seed_forfec, /* i/o: Random seed for picking noise segments */
2029 : const int16_t element_mode, /* i : IVAS element mode */
2030 : const float *old_out
2031 :
2032 : )
2033 : {
2034 : int16_t n, Nfft;
2035 : float sum_Tf_abs;
2036 : float Tfr[FEC_FFT_MAX_SIZE];
2037 : float Tfi[FEC_FFT_MAX_SIZE];
2038 : float Tf_abs[FEC_FFT_MAX_SIZE / 2];
2039 : float synthesis[2 * L_FRAME48k];
2040 :
2041 100 : fec_ecu_dft( prevsynth_LP, N, Tfr, Tfi, &sum_Tf_abs, Tf_abs, &Nfft, element_mode );
2042 :
2043 100 : sinusoidal_synthesis( Tfr, Tfi, Tf_abs, N, output_frame, decimatefactor, Nfft, sum_Tf_abs, synthesis, HqVoicing );
2044 :
2045 100 : fec_noise_filling( prevsynth, synthesis, output_frame, N * decimatefactor, HqVoicing, gapsynth, ni_seed_forfec, element_mode, old_out );
2046 :
2047 100 : n = (int16_t) ( (float) output_frame * N_ZERO_MDCT_NS / FRAME_SIZE_NS );
2048 100 : wtda( synthesis + ( output_frame - n ), ecu_rec, NULL, ALDO_WINDOW, ALDO_WINDOW, output_frame );
2049 :
2050 100 : return;
2051 : }
2052 :
2053 :
2054 : /*--------------------------------------------------------------------------
2055 : * hq_phase_ecu()
2056 : *
2057 : * Main routine for HQ phase ECU
2058 : *--------------------------------------------------------------------------*/
2059 :
2060 11829 : static void hq_phase_ecu(
2061 : const float *prevsynth, /* i : buffer of previously synthesized signal */
2062 : float *ecu_rec, /* o : reconstructed frame in tda domain */
2063 : int16_t *time_offs, /* i/o: Sample offset for consecutive frame losses*/
2064 : float *X_sav, /* i/o: Stored spectrum of prototype frame */
2065 : int16_t *num_p, /* i/o: Number of identified peaks */
2066 : int16_t *plocs, /* i/o: Peak locations */
2067 : float *plocsi, /* i/o: Interpolated peak locations */
2068 : const float env_stab, /* i : Envelope stability parameter */
2069 : int16_t *last_fec, /* i/o: Flag for usage of pitch dependent ECU */
2070 : const int16_t prev_bfi, /* i : indicating burst frame error */
2071 : const int16_t old_is_transient[2], /* i : flags indicating previous transient frames*/
2072 : float *mag_chg_1st, /* i/o: per band magnitude modifier for transients*/
2073 : float Xavg[LGW_MAX], /* i/o: Frequency group average gain to fade to */
2074 : float *beta_mute, /* o : Factor for long-term mute */
2075 : const int16_t bwidth, /* i : Encoded bandwidth */
2076 : const int16_t output_frame, /* i : frame length */
2077 : const float pcorr, /* i : pitch correlation */
2078 : const int16_t element_mode /* i : IVAS element mode */
2079 : )
2080 : {
2081 : int16_t Lprot;
2082 : float mag_chg[LGW_MAX], ph_dith, X[L_PROT48k];
2083 : int16_t seed;
2084 : float alpha[LGW_MAX], beta[LGW_MAX];
2085 : const float *old_dec;
2086 : float noise_fac;
2087 : int16_t ph_ecu_lookahead;
2088 :
2089 11829 : noise_fac = 1.0f;
2090 :
2091 11829 : if ( element_mode == EVS_MONO )
2092 : {
2093 61 : ph_ecu_lookahead = NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS );
2094 : }
2095 : else
2096 : {
2097 11768 : ph_ecu_lookahead = 0;
2098 : }
2099 :
2100 :
2101 11829 : Lprot = ( 2 * output_frame * 4 ) / 5;
2102 :
2103 11829 : if ( !prev_bfi || ( prev_bfi && *last_fec && ( *time_offs == output_frame ) ) )
2104 : {
2105 4946 : if ( !( prev_bfi && *last_fec && ( element_mode == EVS_MONO ) ) )
2106 : {
2107 4942 : *time_offs = 0; /* IVAS reset of offset time counter, timeoffset variable later also used to calculate burst length */
2108 : }
2109 :
2110 4946 : trans_ana( prevsynth + 2 * output_frame - Lprot - *time_offs + ph_ecu_lookahead, mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, *last_fec, element_mode, alpha, beta, beta_mute, Xavg );
2111 4946 : spec_ana( prevsynth + 2 * output_frame - Lprot - *time_offs + ph_ecu_lookahead, plocs, plocsi, num_p, X_sav, output_frame, bwidth, element_mode, &noise_fac, pcorr );
2112 :
2113 4946 : if ( prev_bfi && *last_fec )
2114 : {
2115 12 : if ( element_mode != EVS_MONO )
2116 : {
2117 8 : *time_offs = (int16_t) ( *time_offs + output_frame ); /* USAN avoid risk of internal int32_t in "+=" */
2118 8 : if ( *time_offs <= 0 )
2119 : { /* detected wrap around of st->time_offs */
2120 0 : *time_offs = (int16_t) INT16_MAX; /* keep a very high value so that the long term muting stays on */
2121 : }
2122 : }
2123 : else
2124 : {
2125 4 : *time_offs = (int16_t) ( *time_offs + output_frame ); /* EVS_MONO BE compatible, but EVS CR needed as wrap will cause burst length muting envelope instability issues */
2126 : }
2127 : }
2128 : }
2129 : else
2130 : {
2131 6883 : *time_offs = (int16_t) ( *time_offs + output_frame ); /* cast added for USAN, "+=" avoided as it may creat a truncation from int to int16_t */
2132 6883 : if ( *time_offs <= 0 )
2133 : {
2134 : /* detect wrap around of st->time_offs */
2135 405 : *time_offs = (int16_t) INT16_MAX; /* high value --> continued muting will ensure that the now saturated seed is not creating tones */
2136 : }
2137 :
2138 6883 : trans_ana( prevsynth + 2 * output_frame - Lprot, mag_chg, &ph_dith, mag_chg_1st, output_frame, *time_offs, env_stab, 0, element_mode, alpha, beta, beta_mute, Xavg ); /* 1.0 stable-music, 0.0 speech-like */
2139 : }
2140 :
2141 11829 : mvr2r( X_sav, X, Lprot );
2142 :
2143 : /* seed for own_rand2 */
2144 11829 : seed = *time_offs;
2145 11829 : if ( *num_p > 0 )
2146 : {
2147 11082 : seed = (int16_t) ( seed + plocs[*num_p - 1] ); /* explicit cast and "+=" not used, as it "+=" may create a cast from 32 bit to 16 bit, triggering USAN */
2148 : }
2149 :
2150 11829 : subst_spec( plocs, plocsi, num_p, *time_offs, X, mag_chg, ph_dith, old_is_transient, output_frame, &seed, alpha, beta, *beta_mute, Xavg, element_mode, ph_ecu_lookahead, noise_fac );
2151 :
2152 : /* reconstructed frame in tda domain */
2153 11829 : old_dec = prevsynth + 2 * output_frame - NS2SA( output_frame * FRAMES_PER_SEC, N_ZERO_MDCT_NS );
2154 11829 : rec_frame( X, ecu_rec, output_frame, old_dec, element_mode, num_p, plocs );
2155 :
2156 11829 : return;
2157 : }
2158 :
2159 :
2160 : /*--------------------------------------------------------------------------
2161 : * hq_ecu()
2162 : *
2163 : * Main routine for HQ ECU
2164 : *--------------------------------------------------------------------------*/
2165 :
2166 11929 : void hq_ecu(
2167 : const float *prevsynth, /* i : buffer of previously synthesized signal */
2168 : float *ecu_rec, /* o : reconstructed frame in tda domain */
2169 : int16_t *time_offs, /* i/o: Sample offset for consecutive frame losses*/
2170 : float *X_sav, /* i/o: Stored spectrum of prototype frame */
2171 : int16_t *num_p, /* i/o: Number of identified peaks */
2172 : int16_t *plocs, /* i/o: Peak locations */
2173 : float *plocsi, /* i/o: Interpolated peak locations */
2174 : const float env_stab, /* i : Envelope stability parameter */
2175 : int16_t *last_fec, /* i/o: Flag for usage of pitch dependent ECU */
2176 : const int16_t ph_ecu_HqVoicing, /* i : HQ Voicing flag */
2177 : int16_t *ph_ecu_active, /* i : Phase ECU active flag */
2178 : float *gapsynth, /* o : Gap synthesis for crossfade to good frame */
2179 : const int16_t prev_bfi, /* i : indicating burst frame error */
2180 : const int16_t old_is_transient[2], /* i : flags indicating previous transient frames*/
2181 : float *mag_chg_1st, /* i/o: per band magnitude modifier for transients*/
2182 : float Xavg[LGW_MAX], /* i/o: Frequency group average gain to fade to */
2183 : float *beta_mute, /* o : Factor for long-term mute */
2184 : const int16_t output_frame, /* i : frame length */
2185 : Decoder_State *st /* i/o: decoder state structure */
2186 : )
2187 : {
2188 : int16_t N;
2189 11929 : float corr = 0.0f;
2190 : int16_t decimatefactor;
2191 : float prevsynth_LP[2 * L_FRAME8k];
2192 : HQ_DEC_HANDLE hHQ_core;
2193 : const float *fec_alg_input;
2194 : int16_t evs_mode_selection;
2195 : int16_t ivas_mode_selection;
2196 :
2197 11929 : hHQ_core = st->hHQ_core;
2198 11929 : if ( st->element_mode == EVS_MONO )
2199 : {
2200 77 : fec_alg_input = prevsynth + NS2SA( output_frame * FRAMES_PER_SEC, ACELP_LOOK_NS / 2 - PH_ECU_LOOKAHEAD_NS );
2201 : }
2202 : else
2203 : {
2204 11852 : fec_alg_input = prevsynth - NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS );
2205 : }
2206 :
2207 : /* find pitch and R value */
2208 11929 : if ( !( output_frame < L_FRAME16k ) )
2209 : {
2210 11929 : fec_ecu_pitch( fec_alg_input, prevsynth_LP, output_frame, &N, &corr, &decimatefactor, ph_ecu_HqVoicing );
2211 : }
2212 : else
2213 : {
2214 0 : corr = 0.0f;
2215 0 : decimatefactor = 4;
2216 0 : N = output_frame / 4;
2217 : }
2218 :
2219 96 : evs_mode_selection = ( st->total_brate >= 48000 && ( output_frame >= L_FRAME16k && !prev_bfi && ( !old_is_transient[0] || old_is_transient[1] ) &&
2220 23938 : ( ph_ecu_HqVoicing || ( ( ( hHQ_core->env_stab_plc > 0.5 ) && ( corr < 0.6 ) ) || ( hHQ_core->env_stab_plc < 0.5 && ( corr > 0.85 ) ) ) ) ) ) ||
2221 11919 : ( st->total_brate < 48000 && ( ( ph_ecu_HqVoicing || corr > 0.85 ) && !prev_bfi && ( !old_is_transient[0] || old_is_transient[1] ) ) );
2222 :
2223 11929 : ivas_mode_selection = ( N < PH_ECU_N_LIMIT ) || ( corr < PH_ECU_CORR_LIMIT );
2224 :
2225 11929 : if ( ( ( st->element_mode == EVS_MONO ) && evs_mode_selection ) ||
2226 11913 : ( ( st->element_mode != EVS_MONO ) && evs_mode_selection && ivas_mode_selection ) )
2227 :
2228 : {
2229 100 : fec_alg( fec_alg_input, prevsynth_LP, ecu_rec, output_frame, N, decimatefactor, ph_ecu_HqVoicing, gapsynth, &hHQ_core->ni_seed_forfec, st->element_mode, st->hHQ_core->old_out );
2230 100 : *last_fec = 1;
2231 100 : *ph_ecu_active = 0;
2232 100 : *time_offs = output_frame;
2233 : }
2234 : else
2235 : {
2236 11829 : hq_phase_ecu( prevsynth - NS2SA( output_frame * FRAMES_PER_SEC, PH_ECU_LOOKAHEAD_NS ), ecu_rec, time_offs, X_sav, num_p, plocs, plocsi, env_stab, last_fec, prev_bfi, old_is_transient, mag_chg_1st, Xavg, beta_mute, st->bwidth, output_frame, corr, st->element_mode );
2237 :
2238 11829 : *last_fec = 0;
2239 11829 : *ph_ecu_active = 1;
2240 : }
2241 :
2242 11929 : return;
2243 : }
|