Line data Source code
1 : /******************************************************************************************************
2 :
3 : (C) 2022-2025 IVAS codec Public Collaboration with portions copyright Dolby International AB, Ericsson AB,
4 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
5 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
6 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
7 : contributors to this repository. All Rights Reserved.
8 :
9 : This software is protected by copyright law and by international treaties.
10 : The IVAS codec Public Collaboration consisting of Dolby International AB, Ericsson AB,
11 : Fraunhofer-Gesellschaft zur Foerderung der angewandten Forschung e.V., Huawei Technologies Co. LTD.,
12 : Koninklijke Philips N.V., Nippon Telegraph and Telephone Corporation, Nokia Technologies Oy, Orange,
13 : Panasonic Holdings Corporation, Qualcomm Technologies, Inc., VoiceAge Corporation, and other
14 : contributors to this repository retain full ownership rights in their respective contributions in
15 : the software. This notice grants no license of any kind, including but not limited to patent
16 : license, nor is any license granted by implication, estoppel or otherwise.
17 :
18 : Contributors are required to enter into the IVAS codec Public Collaboration agreement before making
19 : contributions.
20 :
21 : This software is provided "AS IS", without any express or implied warranties. The software is in the
22 : development stage. It is intended exclusively for experts who have experience with such software and
23 : solely for the purpose of inspection. All implied warranties of non-infringement, merchantability
24 : and fitness for a particular purpose are hereby disclaimed and excluded.
25 :
26 : Any dispute, controversy or claim arising under or in relation to providing this software shall be
27 : submitted to and settled by the final, binding jurisdiction of the courts of Munich, Germany in
28 : accordance with the laws of the Federal Republic of Germany excluding its conflict of law rules and
29 : the United Nations Convention on Contracts on the International Sales of Goods.
30 :
31 : *******************************************************************************************************/
32 :
33 : /*====================================================================================
34 : EVS Codec 3GPP TS26.443 Nov 04, 2021. Version 12.14.0 / 13.10.0 / 14.6.0 / 15.4.0 / 16.3.0
35 : ====================================================================================*/
36 :
37 : #include <assert.h>
38 : #include <stdint.h>
39 : #include "options.h"
40 : #ifdef DEBUGGING
41 : #include "debug.h"
42 : #endif
43 : #include <math.h>
44 : #include "prot.h"
45 : #include "wmc_auto.h"
46 :
47 : /*-------------------------------------------------------------------*
48 : * con_acelp()
49 : *
50 : * Concealment function for ACELP and TD-TCX
51 : *--------------------------------------------------------------------*/
52 :
53 0 : void con_acelp(
54 : float A[], /* i : coefficients NxAz[M+1] */
55 : const int16_t coder_type, /* i : ACELP coder type */
56 : float synth[], /* i/o: synthesis */
57 : int16_t *pT, /* o : pitch for all subframe */
58 : float *pgainT, /* o : pitch gain for all subfr */
59 : float stab_fac, /* i : stability of isf */
60 : Decoder_State *st, /* i/o: coder memory state */
61 : float pitch_buffer[], /* i/o: floating pitch values for each subframe */
62 : float *voice_factors, /* o : voicing factors */
63 : float *bwe_exc /* o : excitation for SWB TBE */
64 : )
65 : {
66 : int16_t i, i_subfr, L_frame, T0;
67 : float tmp_deemph;
68 : float mem_syn[M], mem_syn2[M], mem[M], *syn;
69 : float *noise_buf;
70 : float *exc, *harmonic_exc_buf, buf[L_EXC_MEM_DEC + M + L_FRAME16k + L_FRAME16k / 2], *p_A;
71 : float pitch_buf[NB_SUBFR16k];
72 0 : float alpha = 0.0f;
73 : float step, gain, gainCNG, gain_inov, ftmp;
74 : float *pt_exc, tmp_tc, predPitchLag;
75 0 : float pc = 0.f;
76 : int16_t extrapolationFailed, tmpSeed, Tc;
77 : float *pt1_exc;
78 0 : float *w = st->hTcxCfg->tcx_mdct_window;
79 : int16_t W1, W2, j;
80 0 : int16_t l_fir_fer = L_FIR_FER;
81 : float lpFiltAdapt[3];
82 : float hp_filt[3];
83 : int16_t nSubframes;
84 : float exc_unv[L_FRAME16k + L_FRAME16k / 2];
85 : float syn_unv[L_FRAME16k + L_FRAME16k / 2];
86 : float mem_syn_unv[M];
87 : float gain_lpc[NB_SUBFR16k];
88 : float h1[L_SUBFR + 1];
89 : float gainSynthDeemph;
90 0 : float tmp = 0.f;
91 : int16_t fUseExtrapolatedPitch;
92 :
93 : /* Framing parameters */
94 :
95 0 : L_frame = st->L_frame;
96 :
97 0 : fUseExtrapolatedPitch = 0;
98 0 : extrapolationFailed = 1;
99 :
100 : /*------------------------------------------------------------------------*
101 : * Initialize buffers *
102 : *------------------------------------------------------------------------*/
103 :
104 : /* set ACELP synthesis memory */
105 0 : mvr2r( st->mem_syn2, mem_syn, M );
106 :
107 : /* set excitation memory*/
108 0 : harmonic_exc_buf = buf + M;
109 0 : exc = harmonic_exc_buf + L_EXC_MEM_DEC;
110 0 : mvr2r( st->old_exc, harmonic_exc_buf, L_EXC_MEM_DEC );
111 0 : exc[L_frame] = 0.0f;
112 :
113 : /*------------------------------------------------------------------------*
114 : * PLC: [ACELP:Extrapolate Pitch Lag]
115 : *------------------------------------------------------------------------*/
116 :
117 0 : if ( st->flagGuidedAcelp == 1 )
118 : {
119 0 : T0 = st->guidedT0;
120 : }
121 :
122 0 : pitch_pred_linear_fit( st->nbLostCmpt, st->last_good, st->old_pitch_buf, &st->old_fpitch, &predPitchLag, st->pit_min, st->pit_max, st->mem_pitch_gain, 0, st->plc_use_future_lag, &extrapolationFailed, st->nb_subfr );
123 0 : T0 = (int16_t) ( predPitchLag + 0.5f );
124 :
125 0 : if ( extrapolationFailed )
126 : {
127 : /*------------------------------------------------------------------------*
128 : * - Construct adaptive codebook from side information *
129 : *------------------------------------------------------------------------*/
130 :
131 0 : if ( st->flagGuidedAcelp == 0 )
132 : {
133 0 : nSubframes = 0;
134 : }
135 : else
136 : {
137 0 : nSubframes = 2;
138 : /* Construct adaptive codebook with T0, T0_frac, T0_res, gain_pit for 2 sub-frames */
139 0 : for ( i = 0; i < 2 * L_SUBFR; i++ )
140 : {
141 0 : exc[i] = exc[i - st->guidedT0];
142 : }
143 : }
144 : }
145 : else
146 : {
147 0 : nSubframes = 0;
148 : }
149 :
150 :
151 0 : if ( nSubframes > 0 )
152 : {
153 0 : tmp_tc = (float) st->guidedT0; /* take the transmit pitch*/
154 : }
155 : else
156 : {
157 0 : tmp_tc = st->old_fpitch; /* take the previous frame last pitch*/
158 : }
159 :
160 : /* PLC: [ACELP: Fade-out]
161 : * PLC: calculate damping factor */
162 0 : alpha = Damping_fact( coder_type, st->nbLostCmpt, st->last_good, stab_fac, &( st->lp_gainp ), 0 );
163 :
164 0 : if ( st->nbLostCmpt == 1 )
165 : {
166 0 : st->cummulative_damping = 1.0f;
167 : }
168 : else
169 : {
170 0 : st->cummulative_damping *= alpha;
171 : }
172 :
173 : /*-----------------------------------------------------------------*
174 : * PLC: [ACELP: adaptive codebook]
175 : * PLC: Construct the harmonic part of excitation
176 : *-----------------------------------------------------------------*/
177 :
178 0 : if ( st->last_good >= UNVOICED_TRANSITION )
179 : {
180 :
181 : /*---------------------------------------------------------------*
182 : * Last pitch cycle of the previous frame is repeatedly copied. *
183 : *---------------------------------------------------------------*/
184 :
185 0 : Tc = (int16_t) ( tmp_tc + 0.5f );
186 :
187 0 : if ( ( T0 > 0 ) && ( T0 != Tc ) && ( abs( T0 - Tc ) < 0.15f * Tc ) && extrapolationFailed == 0 )
188 : {
189 0 : fUseExtrapolatedPitch = 1;
190 : }
191 :
192 0 : if ( st->enableGplc )
193 : {
194 0 : pt_exc = &exc[nSubframes * L_SUBFR];
195 : }
196 : else
197 : {
198 0 : pt_exc = exc;
199 : }
200 0 : pt1_exc = pt_exc - Tc;
201 :
202 0 : if ( fUseExtrapolatedPitch != 0 )
203 : {
204 : /* Required because later pt1_exc[1] used in filtering points to exc[0]. To make it safe also for GPL pt_exc is used instead of exc */
205 0 : pt_exc[0] = 0;
206 0 : pt_exc = harmonic_exc_buf;
207 0 : assert( pt_exc < pt1_exc - 1 );
208 : }
209 :
210 0 : if ( st->nbLostCmpt == 1 )
211 : {
212 : /* pitch cycle is first low-pass filtered */
213 : /*get filter coefficients*/
214 0 : genPlcFiltBWAdap( st->sr_core, &lpFiltAdapt[0], 0, st->cummulative_damping );
215 0 : for ( i = 0; i < Tc; i++ )
216 : {
217 0 : *pt_exc++ = ( lpFiltAdapt[0] * pt1_exc[-1] + lpFiltAdapt[1] * pt1_exc[0] + lpFiltAdapt[2] * pt1_exc[1] );
218 0 : pt1_exc++;
219 : }
220 : }
221 : else
222 : {
223 : /* copy the first pitch cycle without low-pass filtering */
224 0 : for ( i = 0; i < Tc; i++ )
225 : {
226 0 : *pt_exc++ = *pt1_exc++;
227 : }
228 : }
229 :
230 0 : if ( fUseExtrapolatedPitch != 0 )
231 : {
232 0 : pt1_exc = harmonic_exc_buf;
233 : }
234 :
235 0 : for ( i = 0; i < L_frame + ( 1 - nSubframes ) * L_SUBFR - Tc; i++ )
236 : {
237 0 : *pt_exc++ = *pt1_exc++;
238 : }
239 :
240 : /*-------------------------------------------------------*
241 : * PLC: [ACELP: adaptive codebook]
242 : * PLC: Resync pulse positions.
243 : *-------------------------------------------------------*/
244 :
245 0 : if ( nSubframes > 0 )
246 : {
247 0 : pitch_buf[0] = (float) st->guidedT0;
248 0 : pitch_buf[1] = (float) st->guidedT0;
249 : }
250 :
251 0 : if ( nSubframes > 0 )
252 : {
253 0 : pitch_buf[3] = pitch_buf[2] = pitch_buf[1]; /* do not resync on second half of frame */
254 0 : if ( st->nb_subfr == 5 )
255 : {
256 : /* for guidedacelp cases and nSubframes=2, set pitch_buf[4] to avoid memory_access issues in post_decoder() */
257 0 : pitch_buf[4] = pitch_buf[3];
258 : }
259 : }
260 : else
261 : {
262 0 : if ( fUseExtrapolatedPitch != 0 )
263 : {
264 0 : get_subframe_pitch( st->nb_subfr, st->old_fpitch, predPitchLag, pitch_buf );
265 :
266 0 : PulseResynchronization( harmonic_exc_buf, exc, L_frame, st->nb_subfr, st->old_fpitch, predPitchLag );
267 : }
268 : else
269 : {
270 0 : set_f( pitch_buf, st->old_fpitch, st->nb_subfr );
271 : }
272 : }
273 :
274 : /*------------------------------------------------------------*
275 : * PLC: [ACELP: adaptive codebook]
276 : * PLC: Create the harmonic part needed for the overlap-add.
277 : *------------------------------------------------------------*/
278 :
279 0 : pt_exc = exc + L_frame;
280 0 : pt1_exc = pt_exc - ( ( T0 == 0 ) ? Tc : T0 );
281 :
282 0 : for ( i = 0; i < L_frame / 2; i++ )
283 : {
284 0 : *pt_exc++ = *pt1_exc++;
285 : }
286 :
287 : /*-------------------------------------------------------*
288 : * PLC: [ACELP: adaptive codebook]
289 : * PLC: update the floating point pitch for consecutive loss
290 : *-------------------------------------------------------*/
291 :
292 0 : if ( fUseExtrapolatedPitch != 0 )
293 : {
294 :
295 0 : if ( st->flagGuidedAcelp == 1 )
296 : {
297 0 : st->old_fpitch = (float) T0;
298 : }
299 : else
300 : {
301 0 : st->old_fpitch = predPitchLag;
302 : }
303 : }
304 :
305 : /*-------------------------------------------------------*
306 : * PLC: [ACELP: adaptive BPF]
307 : * PLC: Accommodate the BPF
308 : *-------------------------------------------------------*/
309 :
310 0 : st->bpf_gain_param = 3; /*full BPF*/
311 :
312 : /*-------------------------------------------------------*
313 : * PLC: [ACELP: adaptive codebook]
314 : * PLC: Calculate the initial gain and fade out step.
315 : *-------------------------------------------------------*/
316 :
317 0 : pc = (float) fabs( pitch_buf[3] + pitch_buf[2] - pitch_buf[1] - pitch_buf[0] ) * 256.0f / (float) L_frame;
318 :
319 0 : if ( ( st->last_good <= UNVOICED_TRANSITION ) && ( coder_type == GENERIC ) && ( pc > 6 ) )
320 : {
321 0 : gain = 0.0f;
322 0 : st->lp_gainp = 0.0f;
323 : }
324 : else
325 : {
326 0 : gain = 1.0f; /* start-of-the-frame gain */
327 0 : st->lp_gainp = alpha;
328 : }
329 :
330 0 : step = ( 1.0f / L_frame ) * ( gain - st->lp_gainp );
331 :
332 : /*-------------------------------------------------------*
333 : * PLC: [ACELP: Fade-out]
334 : * Apply fade out
335 : *-------------------------------------------------------*/
336 :
337 0 : for ( i_subfr = 0; i_subfr < st->nb_subfr; i_subfr++ )
338 : {
339 0 : pgainT[i_subfr] = gain;
340 :
341 0 : for ( i = i_subfr * L_SUBFR; i < ( i_subfr + 1 ) * L_SUBFR; i++ )
342 : {
343 0 : exc[i] *= gain;
344 0 : gain -= step;
345 : }
346 : }
347 :
348 0 : for ( ; i < L_frame + ( L_frame / 2 ); i++ )
349 : {
350 0 : exc[i] *= gain;
351 0 : gain -= step;
352 : }
353 :
354 0 : for ( i = 0; i < st->nb_subfr; i++ )
355 : {
356 0 : pT[i] = (int16_t) ( pitch_buf[i] + 0.5f );
357 0 : pitch_buffer[i] = pitch_buf[i];
358 : }
359 :
360 : /* update old exc without random part*/
361 0 : mvr2r( harmonic_exc_buf + L_frame, st->old_exc, L_EXC_MEM_DEC );
362 : }
363 : else
364 : {
365 : /* No harmonic part */
366 0 : set_zero( &exc[0], L_frame + L_frame / 2 );
367 :
368 0 : for ( i = 0; i < st->nb_subfr; i++ )
369 : {
370 0 : pitch_buf[i] = st->pit_max;
371 0 : pgainT[i] = 0.f;
372 0 : pT[i] = L_SUBFR;
373 0 : pitch_buffer[i] = L_SUBFR;
374 : }
375 :
376 0 : st->bpf_gain_param = 0; /*no BPF*/
377 : }
378 :
379 : /*-----------------------------------------------------------------*
380 : * Construct the random part of excitation
381 : *-----------------------------------------------------------------*/
382 0 : noise_buf = buf;
383 0 : tmpSeed = st->seed_acelp;
384 :
385 0 : for ( i = 0; i < L_frame + l_fir_fer - 1; i++ )
386 : {
387 0 : noise_buf[i] = (float) own_random( &tmpSeed );
388 : }
389 0 : st->seed_acelp = tmpSeed;
390 :
391 0 : for ( ; i < L_frame + ( L_frame / 2 ) + l_fir_fer - 1; i++ )
392 : {
393 0 : noise_buf[i] = (float) own_random( &tmpSeed );
394 : }
395 :
396 : /*get filter coefficients*/
397 0 : genPlcFiltBWAdap( st->sr_core, &hp_filt[0], 1, st->cummulative_damping );
398 :
399 : /* PLC: [ACELP: Fade-out]
400 : * PLC: retrieve background level */
401 0 : tmp = 1.0f;
402 0 : gainSynthDeemph = getLevelSynDeemph( &( tmp ), A, L_SUBFR, st->preemph_fac, L_frame / L_SUBFR );
403 0 : gainCNG = st->cngTDLevel / gainSynthDeemph;
404 :
405 0 : gain = st->lp_gainc; /* start-of-the-frame gain */
406 :
407 0 : ftmp = 2.0f * gain;
408 :
409 0 : if ( gainCNG > ftmp )
410 : {
411 0 : gainCNG = ftmp;
412 : }
413 :
414 0 : st->lp_gainc = alpha * st->lp_gainc + ( 1.0f - alpha ) * gainCNG; /* end-of-the-frame gain */
415 :
416 0 : if ( ( st->last_good == UNVOICED_TRANSITION ) && ( coder_type == GENERIC ) )
417 : {
418 0 : st->lp_gainc = gainCNG;
419 : }
420 :
421 0 : highPassFiltering( st->last_good, L_frame + l_fir_fer / 2, noise_buf, hp_filt, l_fir_fer );
422 :
423 : /* Find energy normalization factor */
424 0 : pt_exc = noise_buf + l_fir_fer / 2;
425 0 : gain_inov = 1.0f / (float) sqrt( dotp( pt_exc, pt_exc, L_frame ) / L_frame + 0.01f );
426 :
427 : /* PLC: [ACELP: Fade-out]
428 : * PLC: Linearly attenuate the gain through the frame */
429 0 : step = ( 1.0f / L_frame ) * ( gain - st->lp_gainc );
430 :
431 0 : if ( ( st->last_good == UNVOICED_CLAS ) && ( coder_type != UNVOICED ) ) /* Attenuate somewhat on unstable unvoiced */
432 : {
433 0 : gain_inov *= 0.8f;
434 : }
435 :
436 0 : if ( st->last_good >= UNVOICED_TRANSITION )
437 : {
438 : float tilt_code;
439 :
440 0 : tilt_code = (float) ( 0.10f * ( 1.0f + st->voice_fac ) );
441 0 : gain_inov *= ( 1.f - tilt_code );
442 : }
443 :
444 0 : pt_exc = noise_buf;
445 :
446 : /* non-causal ringing of the FIR filter */
447 :
448 0 : for ( i = 0; i < l_fir_fer / 2; i++ )
449 : {
450 0 : *pt_exc++ *= ( gain_inov * gain );
451 : }
452 :
453 : /* Actual filtered random part of excitation */
454 :
455 0 : for ( i = 0; i < L_frame; i++ )
456 : {
457 0 : *pt_exc++ *= ( gain_inov * gain );
458 0 : gain -= step;
459 : }
460 :
461 0 : for ( i = 0; i < ( L_frame / 2 ) + l_fir_fer / 2; i++ )
462 : {
463 0 : *pt_exc++ *= ( gain_inov * gain );
464 : }
465 :
466 0 : st->past_gcode = gain;
467 :
468 0 : if ( st->last_good < UNVOICED_TRANSITION )
469 : {
470 0 : mvr2r( noise_buf + l_fir_fer / 2, exc, L_frame + L_frame / 2 );
471 0 : mvr2r( harmonic_exc_buf + L_frame, st->old_exc, L_EXC_MEM_DEC );
472 0 : mvr2r( exc, exc_unv, L_frame + ( L_frame / 2 ) ); /* Update exc_unv */
473 : }
474 : else
475 : {
476 0 : mvr2r( noise_buf + l_fir_fer / 2, exc_unv, L_frame + ( L_frame / 2 ) ); /* Update exc_unv */
477 : }
478 :
479 : /* Compute total excitation in noisebuffer to save memories */
480 0 : if ( st->last_good >= UNVOICED_TRANSITION )
481 : {
482 0 : for ( i = 0; i < L_frame + 1; i++ )
483 : {
484 0 : noise_buf[i] = exc[i] + exc_unv[i];
485 : }
486 : }
487 : else
488 : {
489 0 : noise_buf = exc_unv;
490 : }
491 :
492 0 : if ( st->hBWE_TD != NULL )
493 : {
494 0 : if ( L_frame == L_FRAME )
495 : {
496 0 : interp_code_5over2( noise_buf, bwe_exc, L_frame );
497 0 : set_f( voice_factors, st->last_voice_factor, NB_SUBFR );
498 : }
499 : else
500 : {
501 0 : interp_code_4over2( noise_buf, bwe_exc, L_frame );
502 0 : set_f( voice_factors, st->last_voice_factor, NB_SUBFR16k );
503 : }
504 : }
505 :
506 : /*----------------------------------------------------------*
507 : * - compute the synthesis speech *
508 : *----------------------------------------------------------*/
509 :
510 : /* Init syn buffer */
511 0 : syn = buf + M;
512 0 : mvr2r( st->mem_syn2, buf, M );
513 :
514 0 : if ( st->nbLostCmpt == 1 )
515 : {
516 :
517 0 : if ( st->last_good < UNVOICED_TRANSITION )
518 : {
519 0 : mvr2r( st->mem_syn2, mem_syn_unv, M );
520 : }
521 : else
522 : {
523 0 : set_zero( mem_syn_unv, M );
524 : }
525 : }
526 : else
527 : {
528 0 : mvr2r( st->mem_syn_unv_back, mem_syn_unv, M );
529 : }
530 :
531 : /* voiced synth */
532 :
533 0 : if ( st->last_good >= UNVOICED_TRANSITION )
534 : {
535 0 : p_A = A;
536 :
537 0 : for ( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
538 : {
539 0 : tmp = 0;
540 0 : set_zero( h1, L_SUBFR + 1 );
541 0 : set_zero( mem, M );
542 0 : h1[0] = 1.0f;
543 0 : syn_filt( p_A, M, h1, h1, L_SUBFR, mem, 0 ); /* impulse response of LPC */
544 0 : deemph( h1, st->preemph_fac, L_SUBFR, &tmp ); /* impulse response of deemph */
545 : /* impulse response level = gain introduced by synthesis+deemphasis */
546 0 : gain_lpc[i_subfr / L_SUBFR] = 1.f / (float) sqrt( dotp( h1, h1, L_SUBFR ) );
547 0 : p_A += ( M + 1 );
548 : }
549 :
550 0 : j = 0;
551 0 : for ( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
552 : {
553 :
554 0 : for ( i = 0; i < L_SUBFR; i++ )
555 : {
556 0 : exc[i_subfr + i] *= st->last_gain_syn_deemph * gain_lpc[j];
557 : }
558 0 : j++;
559 : }
560 :
561 0 : for ( i = L_frame; i < L_frame + L_frame / 2; i++ )
562 : {
563 0 : exc[i] *= st->last_gain_syn_deemph * gain_lpc[3];
564 : }
565 0 : p_A = A;
566 :
567 0 : for ( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
568 : {
569 0 : syn_filt( p_A, M, &exc[i_subfr], &syn[i_subfr], L_SUBFR, mem_syn, 1 );
570 0 : p_A += ( M + 1 );
571 : }
572 :
573 0 : mvr2r( mem_syn, mem_syn2, M );
574 :
575 : /* synthesize ola*/
576 0 : syn_filt( p_A - ( M + 1 ), M, &exc[L_frame], &syn[L_frame], ( L_frame / 2 ), mem_syn2, 0 );
577 : }
578 :
579 : /* unvoiced synth */
580 0 : tmp = 0;
581 0 : p_A = st->Aq_cng;
582 :
583 0 : for ( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
584 : {
585 0 : set_zero( h1, L_SUBFR + 1 );
586 0 : set_zero( mem, M );
587 0 : h1[0] = 1.0f;
588 0 : syn_filt( p_A, M, h1, h1, L_SUBFR, mem, 0 ); /* impulse response of LPC */
589 0 : deemph( h1, st->preemph_fac, L_SUBFR, &tmp ); /* impulse response of deemph */
590 : /* impulse response level = gain introduced by synthesis+deemphasis */
591 0 : gain_lpc[i_subfr / L_SUBFR] = 1.f / (float) sqrt( dotp( h1, h1, L_SUBFR ) );
592 0 : p_A += ( M + 1 );
593 : }
594 :
595 0 : j = 0;
596 0 : for ( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
597 : {
598 :
599 0 : for ( i = 0; i < L_SUBFR; i++ )
600 : {
601 0 : exc_unv[i_subfr + i] *= st->last_gain_syn_deemph * gain_lpc[j];
602 : }
603 0 : j++;
604 : }
605 :
606 0 : for ( i = L_frame; i < L_frame + L_frame / 2; i++ )
607 : {
608 0 : exc_unv[i] *= st->last_gain_syn_deemph * gain_lpc[j - 1];
609 : }
610 0 : p_A = st->Aq_cng;
611 :
612 0 : for ( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
613 : {
614 0 : syn_filt( p_A, M, &exc_unv[i_subfr], &syn_unv[i_subfr], L_SUBFR, mem_syn_unv, 1 );
615 0 : p_A += ( M + 1 );
616 : }
617 :
618 0 : mvr2r( mem_syn_unv, st->mem_syn_unv_back, M );
619 :
620 0 : if ( st->last_good < UNVOICED_TRANSITION )
621 : {
622 0 : mvr2r( mem_syn_unv, mem_syn, M );
623 : }
624 :
625 : /* unvoiced for ola */
626 0 : syn_filt( p_A - ( M + 1 ), M, &exc_unv[i_subfr], &syn_unv[i_subfr], ( L_frame / 2 ), mem_syn_unv, 0 );
627 :
628 : /* add separate synthesis buffers */
629 0 : if ( st->last_good >= UNVOICED_TRANSITION )
630 : {
631 0 : for ( i = 0; i < L_frame; i++ )
632 : {
633 0 : syn[i] += syn_unv[i];
634 : }
635 : }
636 : else
637 : {
638 0 : mvr2r( syn_unv, syn, L_frame + L_frame / 2 );
639 : }
640 :
641 :
642 : /* update buffer for the classification */
643 0 : FEC_clas_estim( syn, pitch_buf, st->L_frame, coder_type, st->codec_mode, st->mem_syn_clas_estim, &( st->clas_dec ), &st->lp_ener_bfi, 0, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL, -1.0f, st->narrowBand, 0, 1, st->preemph_fac, st->tcxonly, st->last_core_brate, -1 );
644 :
645 : /* Update Pitch Lag memory */
646 0 : mvr2r( &st->old_pitch_buf[L_frame / L_SUBFR], st->old_pitch_buf, L_frame / L_SUBFR );
647 0 : mvr2r( pitch_buf, &st->old_pitch_buf[L_frame / L_SUBFR], L_frame / L_SUBFR );
648 :
649 : /*updating enr_old parameters*/
650 0 : fer_energy( L_frame, st->last_good, syn, tmp_tc, &( st->enr_old ), 1 );
651 :
652 : /* update ACELP synthesis memory */
653 0 : mvr2r( mem_syn, st->mem_syn2, M );
654 0 : mvr2r( syn + L_frame - L_SYN_MEM, st->mem_syn_r, L_SYN_MEM );
655 :
656 : /* Deemphasis and output synth */
657 0 : tmp_deemph = st->syn[M];
658 0 : deemph( syn, st->preemph_fac, L_frame + L_frame / 2, &tmp_deemph );
659 :
660 0 : mvr2r( syn, synth, L_frame );
661 0 : mvr2r( syn + L_frame - L_frame / 2, st->hTcxDec->old_syn_Overl, L_frame / 2 );
662 :
663 :
664 : /* save last half frame if next frame is TCX */
665 0 : mvr2r( syn + L_frame, st->hTcxDec->syn_Overl_TDAC, L_frame / 2 );
666 0 : mvr2r( syn + L_frame - M - 1, st->syn, 1 + M );
667 :
668 : /* update old_Aq */
669 0 : mvr2r( p_A - ( M + 1 ), st->old_Aq_12_8, M + 1 );
670 :
671 0 : mvr2r( syn + L_frame, st->hTcxDec->syn_Overl, L_frame / 2 );
672 :
673 0 : W1 = st->hTcxCfg->tcx_mdct_window_length;
674 0 : W2 = st->hTcxCfg->tcx_mdct_window_length / 2;
675 :
676 0 : st->hTcxCfg->tcx_curr_overlap_mode = FULL_OVERLAP;
677 : {
678 0 : int16_t n = (int16_t) ( (float) L_frame * N_ZERO_MDCT_NS / FRAME_SIZE_NS );
679 :
680 0 : mvr2r( syn + L_frame - n, st->hHQ_core->old_outLB, L_frame - n );
681 :
682 0 : for ( i = 0; i < W1; i++ )
683 : {
684 0 : st->hHQ_core->old_outLB[i + n] *= w[W1 - 1 - i] * w[W1 - 1 - i];
685 : }
686 0 : set_zero( &st->hHQ_core->old_outLB[W1 + n], n );
687 : }
688 :
689 : /* create aliasing and windowing */
690 :
691 0 : for ( i = 0; i < W1; i++ )
692 : {
693 0 : buf[i] = st->hTcxDec->syn_Overl_TDAC[i] * w[W1 - 1 - i];
694 : }
695 :
696 0 : for ( i = 0; i < W2; i++ )
697 : {
698 0 : st->hTcxDec->syn_Overl_TDAC[i] = buf[i] + buf[W1 - 1 - i]; /* A-D */
699 : }
700 :
701 0 : for ( i = 0; i < W2; i++ )
702 : {
703 0 : st->hTcxDec->syn_Overl_TDAC[W2 + i] = buf[W2 + i] + buf[W1 - 1 - W2 - i]; /* B-C */
704 : }
705 :
706 0 : for ( i = 0; i < W1; i++ )
707 : {
708 0 : st->hTcxDec->syn_Overl_TDAC[i] *= w[W1 - 1 - i];
709 : }
710 :
711 : /* update memory for full band */
712 0 : lerp( st->hTcxDec->syn_Overl_TDAC, st->hTcxDec->syn_Overl_TDACFB, st->hTcxDec->L_frameTCX / 2, L_frame / 2 );
713 0 : lerp( st->hTcxDec->syn_Overl, st->hTcxDec->syn_OverlFB, st->hTcxDec->L_frameTCX / 2, L_frame / 2 );
714 0 : lerp( st->hHQ_core->old_outLB, st->hHQ_core->old_out, st->hTcxDec->L_frameTCX, L_frame );
715 :
716 : /* copy total excitation exc2 as 16kHz for acelp mode1 decoding */
717 0 : if ( st->hWIDec != NULL )
718 : {
719 0 : lerp( exc, st->hWIDec->old_exc2, L_EXC_MEM, L_frame );
720 0 : lerp( syn, st->hWIDec->old_syn2, L_EXC_MEM, L_frame );
721 : }
722 0 : st->bfi_pitch = pitch_buf[st->nb_subfr - 1];
723 0 : st->bfi_pitch_frame = L_frame;
724 :
725 0 : return;
726 : }
|