Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include <stdint.h>
6 : #include <assert.h>
7 : #include "options.h"
8 : #include "cnst.h"
9 : //#include "prot_fx.h"
10 : #include "basop_util.h"
11 : #include "options.h"
12 : #include "rom_basop_util.h"
13 : #include "rom_com.h" /* Common constants */
14 : #include "prot_fx.h" /* Function prototypes */
15 : #include "prot_fx_enc.h" /* Function prototypes */
16 : #include "basop_util.h" /* Function prototypes */
17 :
18 : /*-------------------------------------------------------------------*
19 : * coder_acelp_fx()
20 : *
21 : * Encode ACELP frame
22 : *-------------------------------------------------------------------*/
23 :
24 612 : Word16 coder_acelp_fx( /* o : SEGSNR for CL decision */
25 : const Word16 A[], /* i : coefficients 4xAz[M+1] Qx*/
26 : const Word16 Aq[], /* i : coefficients 4xAz_q[M+1] Q12*/
27 : const Word16 speech[], /* i : speech[-M..lg] Qx*/
28 : Word16 *prm, /* o : acelp parameters */
29 : Word16 stab_fac, /*Q15 */
30 : Encoder_State *st,
31 : PLC_ENC_EVS_HANDLE hPlc_Ext,
32 : const Word16 target_bits, /* i/o: coder memory state */
33 : const Word16 Q_new,
34 : const Word16 shift,
35 : Word16 *pitch_buf, /* o : pitch values for each subfr.*/
36 : Word16 *voice_factors, /* o : voicing factors Q15 */
37 : Word16 *bwe_exc /* o : excitation for SWB TBE Qx */
38 : )
39 : {
40 : Word16 i, i_subfr, j_subfr;
41 : Word16 tmp, Es_pred;
42 : Word16 T0, T0_min, T0_min_frac, T0_max, T0_max_frac, T0_res;
43 : Word16 T0_frac;
44 : Word16 gain_pit, voice_fac;
45 : Word32 gain_code, Ltmp, Ltmp2;
46 : ACELP_CbkCorr g_corr;
47 : const Word16 *p_A, *p_Aq;
48 : Word16 h1[L_SUBFR]; /* weighted impulse response of LP */
49 : Word16 code[L_SUBFR];
50 : Word16 xn_exp;
51 : Word16 Q_xn;
52 : Word16 Q_new_p5;
53 : Word16 cn[L_SUBFR];
54 : Word16 xn[L_SUBFR];
55 : Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */
56 : Word16 y2[L_SUBFR]; /* Filtered adaptive excitation */
57 : Word16 res_save;
58 : Word16 exc_buf[L_EXC_MEM + L_DIV_MAX + 1], *exc;
59 : Word16 exc2[L_SUBFR];
60 : Word16 *syn, syn_buf[M + L_DIV_MAX + L_DIV_MAX / 2]; /*128 for the memory, L_DIV for the current synth and 128 for the ZIR for next TCX*/
61 : Word16 syn2[L_DIV_MAX];
62 : Word16 gain_inov;
63 : Word32 past_gcode;
64 : Word16 L_frame;
65 : Word16 clip_gain;
66 : Word32 gain_code2;
67 : Word16 code2[L_SUBFR];
68 : Word16 y22[L_SUBFR]; /* Filtered adaptive excitation */
69 612 : Word16 error = 0;
70 612 : move16();
71 612 : Word16 gain_preQ = 0; /* Gain of prequantizer excitation */
72 612 : move16();
73 : Word16 code_preQ[L_SUBFR]; /* Prequantizer excitation */
74 :
75 612 : Word16 dummy = 0;
76 612 : move16();
77 : ACELP_config *acelp_cfg;
78 : #ifndef ISSUE_1867_replace_overflow_libenc
79 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
80 : Flag Overflow = 0;
81 : move32();
82 : #endif
83 : #endif
84 :
85 612 : acelp_cfg = &( st->acelp_cfg );
86 612 : LPD_state_HANDLE hLPDmem = st->hLPDmem;
87 612 : RF_ENC_HANDLE hRF = st->hRF;
88 612 : TD_BWE_ENC_HANDLE hBWE_TD = st->hBWE_TD;
89 612 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
90 :
91 612 : set16_fx( code_preQ, 0, L_SUBFR );
92 :
93 :
94 612 : T0 = 0; /* to avoid compilation warnings */
95 612 : T0_frac = 0; /* to avoid compilation warnings */
96 612 : T0_res = 0; /* to avoid compilation warnings */
97 612 : gain_pit = 0; /* to avoid compilation warnings */
98 :
99 :
100 : /* Configure ACELP */
101 :
102 612 : BITS_ALLOC_config_acelp( target_bits, st->coder_type, acelp_cfg, st->narrowBand, st->nb_subfr );
103 :
104 : /* Init Framing parameters */
105 612 : move16();
106 612 : move16();
107 612 : move16();
108 612 : move16();
109 612 : L_frame = st->L_frame;
110 612 : move16();
111 :
112 : /*------------------------------------------------------------------------*
113 : * Previous frame is TCX (for non-EVS modes)(deactivated permanently) *
114 : *------------------------------------------------------------------------*/
115 :
116 : /*------------------------------------------------------------------------*
117 : * Initialize buffers *
118 : *------------------------------------------------------------------------*/
119 :
120 : /* Rescale ACELP memories, which were not scaled yet*/
121 612 : xn_exp = sub( sub( 15 + 1, Q_new ), shift );
122 612 : Q_xn = add( sub( Q_new, 1 ), shift );
123 612 : Q_new_p5 = add( Q_new, 5 );
124 :
125 : /* Reset phase dispersion */
126 612 : IF( st->last_core > ACELP_CORE )
127 : {
128 29 : move16();
129 29 : move16();
130 :
131 29 : hLPDmem->dm_fx.prev_gain_code = 0;
132 29 : set16_fx( hLPDmem->dm_fx.prev_gain_pit, 0, 6 );
133 29 : hLPDmem->dm_fx.prev_state = 0;
134 : }
135 :
136 : /* set excitation memory*/
137 612 : exc = exc_buf + L_EXC_MEM;
138 612 : Copy( hLPDmem->old_exc, exc_buf, L_EXC_MEM );
139 612 : *( exc + st->L_frame ) = 0;
140 :
141 : /* Init syn buffer */
142 612 : move16();
143 612 : syn = syn_buf + M;
144 612 : Copy( hLPDmem->mem_syn, syn_buf, M );
145 :
146 :
147 : /* calculate residual */
148 612 : calc_residu_fx( st, speech, exc, Aq );
149 : /*------------------------------------------------------------------------*
150 : * Find and quantize mean_ener_code for gain quantizer *
151 : *------------------------------------------------------------------------*/
152 :
153 612 : Es_pred = 0;
154 612 : move16();
155 612 : IF( acelp_cfg->nrg_mode > 0 )
156 : {
157 612 : Es_pred_enc_fx( &Es_pred, prm, L_frame, exc, st->voicing_fx, acelp_cfg->nrg_bits, acelp_cfg->nrg_mode > 1, Q_new );
158 612 : prm++;
159 : }
160 :
161 612 : IF( EQ_16( st->L_frame, L_FRAME ) )
162 : {
163 0 : Copy( Aq + 2 * ( M + 1 ), hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) );
164 : }
165 : ELSE
166 : {
167 612 : Copy( Aq + 3 * ( M + 1 ), hBWE_TD->cur_sub_Aq_fx, ( M + 1 ) );
168 : }
169 :
170 :
171 : /*------------------------------------------------------------------------*
172 : * Loop for every subframe in the analysis frame *
173 : *------------------------------------------------------------------------*
174 : * To find the pitch and innovation parameters. The subframe size is *
175 : * L_SUBFR and the loop is repeated L_FRAME_PLUS/L_SUBFR *
176 : * times. *
177 : * - compute impulse response of weighted synthesis filter (h1[]) *
178 : * - compute the target signal for pitch search *
179 : * - find the closed-loop pitch parameters *
180 : * - encode the pitch delay *
181 : * - update the impulse response h1[] by including fixed-gain pitch *
182 : * - find target vector for codebook search *
183 : * - correlation between target vector and impulse response *
184 : * - codebook search *
185 : * - encode codebook address *
186 : * - VQ of pitch and codebook gains *
187 : * - find synthesis speech *
188 : * - update states of weighting filter *
189 : *------------------------------------------------------------------------*/
190 :
191 612 : p_A = A;
192 612 : p_Aq = Aq;
193 :
194 612 : move16();
195 612 : res_save = exc[0];
196 :
197 612 : j_subfr = 0;
198 612 : move16();
199 3672 : FOR( i_subfr = 0; i_subfr < L_frame; i_subfr += L_SUBFR )
200 : {
201 :
202 : /* Restore exc[i_subfr] and save next exc[L_SUBFR+i_subfr] */
203 3060 : move16();
204 3060 : move16();
205 3060 : exc[i_subfr] = res_save;
206 3060 : res_save = exc[L_SUBFR + i_subfr];
207 :
208 : /*--------------------------------------------------------------------------*
209 : * Find target for pitch search (xn[]), target for innovation search (cn[]) *
210 : * and impulse response of the weighted synthesis filter (h1[]). *
211 : *--------------------------------------------------------------------------*/
212 3060 : find_targets_fx( speech, &syn[i_subfr - M], i_subfr, &hLPDmem->mem_w0, p_Aq, exc, L_SUBFR, p_A, st->preemph_fac, xn, cn, h1 );
213 :
214 : /*---------------------------------------------------------------*
215 : * Compute impulse response, h1[], of weighted synthesis filter *
216 : *---------------------------------------------------------------*/
217 3060 : Scale_sig( h1, L_SUBFR, add( 1, shift ) ); /* Q13+1-shift */
218 :
219 : /* scaling of xn[] to limit dynamic at 12 bits */
220 3060 : Scale_sig( xn, L_SUBFR, shift );
221 :
222 : /*-----------------------------------------------------------------*
223 : * Gain clipping test to avoid unstable synthesis on frame erasure
224 : * or in case of floating point encoder & fixed p. decoder
225 : *-----------------------------------------------------------------*/
226 :
227 3060 : clip_gain = Mode2_gp_clip_fx( st->voicing_fx, i_subfr, st->coder_type, xn, st->clip_var_fx, L_SUBFR, Q_xn );
228 :
229 : /*-----------------------------------------------------------------*
230 : * - find unity gain pitch excitation (adaptive codebook entry) *
231 : * with fractional interpolation. *
232 : * - find filtered pitch exc. y1[]=exc[] convolved with h1[]) *
233 : * - compute pitch gain1 *
234 : *-----------------------------------------------------------------*/
235 :
236 3060 : IF( acelp_cfg->ltp_bits != 0 )
237 : {
238 : /* Adaptive Codebook (GC and VC) */
239 :
240 3060 : Mode2_pit_encode_fx( acelp_cfg->ltp_mode, i_subfr, &prm, &exc[i_subfr], st->pitch, &T0_min, &T0_min_frac, &T0_max, &T0_max_frac,
241 3060 : &T0, &T0_frac, &T0_res, h1, xn, st->pit_min, st->pit_fr1, st->pit_fr1b, st->pit_fr2, st->pit_max, st->pit_res_max );
242 :
243 3060 : E_ACELP_adaptive_codebook( exc, T0, T0_frac, T0_res, st->pit_res_max, acelp_cfg->ltf_mode, i_subfr, L_SUBFR, L_frame, h1, clip_gain, xn,
244 : y1, &g_corr, &prm, &gain_pit, xn_exp, 0, 0, &dummy );
245 : }
246 0 : ELSE IF( acelp_cfg->ltp_bits == 0 )
247 : {
248 : /* No adaptive codebook (UC) */
249 0 : gain_pit = 0;
250 0 : g_corr.xy1 = 0;
251 0 : g_corr.xy1_e = 0;
252 0 : g_corr.y1y1 = 0;
253 0 : g_corr.y1y1_e = 0;
254 0 : set16_fx( y1, 0, L_SUBFR );
255 0 : set16_fx( exc + i_subfr, 0, L_SUBFR );
256 0 : T0 = L_SUBFR;
257 0 : T0_frac = 0;
258 0 : T0_res = 1;
259 0 : move16();
260 0 : move16();
261 0 : move16();
262 0 : move16();
263 0 : move16();
264 0 : move16();
265 0 : move16();
266 0 : move16();
267 : }
268 :
269 3060 : IF( st->igf != 0 )
270 : {
271 3060 : tbe_celp_exc( L_frame, i_subfr, T0, T0_frac, &error, bwe_exc );
272 : }
273 :
274 3060 : pitch_buf[i_subfr / L_SUBFR] = shl( add( shl( T0, 2 ), T0_frac ), 4 );
275 :
276 : /*----------------------------------------------------------------------*
277 : * Encode the algebraic innovation *
278 : *----------------------------------------------------------------------*/
279 :
280 3060 : E_ACELP_innovative_codebook_fx( exc, T0, T0_frac, T0_res, gain_pit, hLPDmem->tilt_code, acelp_cfg, i_subfr, p_Aq, h1, xn, cn, y1, y2, (Word8) st->acelp_autocorr, &prm, code, shift, st->L_frame, st->last_L_frame, st->total_brate );
281 :
282 3060 : E_ACELP_xy2_corr( xn, y1, y2, &g_corr, L_SUBFR, Q_xn );
283 :
284 3060 : g_corr.y2y2_e = sub( g_corr.y2y2_e, 18 ); /* -18 (y2*y2: Q9*Q9) */
285 3060 : g_corr.xy2_e = sub( g_corr.xy2_e, add( Q_xn, 9 ) ); /* -(Q_xn+9) (xn: Q_xn y2: Q9) */
286 3060 : g_corr.y1y2_e = sub( g_corr.y1y2_e, add( Q_xn, 9 ) ); /* -(Q_xn+9) (y1: Q_xn y2: Q9) */
287 3060 : g_corr.xx_e = sub( g_corr.xx_e, add( Q_xn, Q_xn ) ); /* -(Q_xn+Q_xn) (xn: Q_xn) */
288 3060 : move16();
289 3060 : move16();
290 3060 : move16();
291 3060 : move16();
292 :
293 : /*----------------------------------------------------------------------*
294 : * Add Gaussian excitation *
295 : *----------------------------------------------------------------------*/
296 :
297 3060 : IF( EQ_16( acelp_cfg->gains_mode[j_subfr], 7 ) )
298 : {
299 0 : assert( gain_pit == 0 );
300 0 : gauss_L2_fx( h1, code2, y2, y22, &gain_code2, &g_corr, gain_pit, hLPDmem->tilt_code, p_Aq, acelp_cfg->formant_enh_num, &( st->seed_acelp ), shift );
301 : }
302 : ELSE
303 : {
304 3060 : gain_code2 = L_deposit_l( 0 );
305 3060 : set16_fx( code2, 0, L_SUBFR );
306 3060 : set16_fx( y22, 0, L_SUBFR );
307 : }
308 :
309 : /*----------------------------------------------------------*
310 : * - Compute the fixed codebook gain *
311 : * - quantize fixed codebook gain *
312 : *----------------------------------------------------------*/
313 :
314 3060 : encode_acelp_gains_fx( code, acelp_cfg->gains_mode[j_subfr], Es_pred, clip_gain, &g_corr, &gain_pit, &gain_code, &prm,
315 3060 : &past_gcode, &gain_inov, L_SUBFR, code2, &gain_code2, st->flag_noisy_speech_snr );
316 :
317 3060 : gp_clip_test_gain_pit_fx( st->element_mode, st->core_brate, gain_pit, st->clip_var_fx );
318 :
319 : /*----------------------------------------------------------*
320 : * - voice factor (for pitch enhancement) *
321 : *----------------------------------------------------------*/
322 3060 : E_UTIL_voice_factor( exc, i_subfr, code, gain_pit, gain_code, &voice_fac, &( hLPDmem->tilt_code ), L_SUBFR, acelp_cfg->voice_tilt, Q_new, shift );
323 :
324 3060 : IF( st->Opt_RF_ON )
325 : {
326 0 : hRF->rf_tilt_buf[i_subfr / L_SUBFR] = hLPDmem->tilt_code;
327 0 : move16();
328 : }
329 : /*-----------------------------------------------------------------*
330 : * Update memory of the weighting filter
331 : *-----------------------------------------------------------------*/
332 : /* st_fx->mem_w0 = xn[L_SUBFR-1] - (gain_pit*y1[L_SUBFR-1]) - (gain_code*y2[L_SUBFR-1]); */
333 3060 : Ltmp = Mpy_32_16_1( gain_code, y2[L_SUBFR - 1] );
334 3060 : Ltmp = L_shl( Ltmp, add( 5, Q_xn ) );
335 3060 : Ltmp = L_mac( Ltmp, y1[L_SUBFR - 1], gain_pit );
336 : /* Add Gaussian contribution*/
337 3060 : Ltmp2 = Mpy_32_16_1( gain_code2, y22[L_SUBFR - 1] );
338 3060 : Ltmp2 = L_shl( Ltmp2, add( 5, Q_xn ) );
339 3060 : Ltmp = L_add( Ltmp, Ltmp2 );
340 3060 : hLPDmem->mem_w0 = sub( xn[L_SUBFR - 1], round_fx( L_shl( Ltmp, 1 ) ) );
341 3060 : move16();
342 : BASOP_SATURATE_WARNING_OFF_EVS;
343 3060 : hLPDmem->mem_w0 = shr_sat( hLPDmem->mem_w0, shift ); /*Qnew-1*/
344 3060 : move16();
345 : BASOP_SATURATE_WARNING_ON_EVS;
346 :
347 : /*-------------------------------------------------------*
348 : * - Find the total excitation. *
349 : *-------------------------------------------------------*/
350 198900 : FOR( i = 0; i < L_SUBFR; i++ )
351 : {
352 : /* code in Q9, gain_pit in Q14; exc Q_new */
353 195840 : Ltmp = Mpy_32_16_1( gain_code2, code2[i] );
354 195840 : Ltmp = L_shl( Ltmp, Q_new_p5 );
355 195840 : Ltmp = L_mac( Ltmp, gain_pit, exc[i + i_subfr] );
356 : #ifdef ISSUE_1867_replace_overflow_libenc
357 195840 : exc2[i] = round_fx_sat( L_shl_sat( Ltmp, 1 ) );
358 : #else
359 : exc2[i] = round_fx_sat( L_shl_o( Ltmp, 1, &Overflow ) );
360 : #endif
361 195840 : move16();
362 195840 : Ltmp2 = Mpy_32_16_1( gain_code, code[i] );
363 195840 : Ltmp2 = L_shl_sat( Ltmp2, Q_new_p5 );
364 195840 : Ltmp = L_add_sat( Ltmp, Ltmp2 );
365 : #ifdef ISSUE_1867_replace_overflow_libenc
366 195840 : Ltmp = L_shl_sat( Ltmp, 1 ); /* saturation can occur here */
367 195840 : exc[i + i_subfr] = round_fx_sat( Ltmp );
368 : #else
369 : Ltmp = L_shl_o( Ltmp, 1, &Overflow ); /* saturation can occur here */
370 : exc[i + i_subfr] = round_fx_o( Ltmp, &Overflow );
371 : #endif
372 195840 : move16();
373 : }
374 : /*-----------------------------------------------------------------*
375 : * Prepare TBE excitation
376 : *-----------------------------------------------------------------*/
377 :
378 3060 : IF( st->igf != 0 )
379 : {
380 3060 : prep_tbe_exc_fx( L_frame, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR],
381 3060 : bwe_exc, gain_preQ, code_preQ, Q_new, T0, T0_frac, st->coder_type, st->core_brate,
382 3060 : st->element_mode, st->idchan, st->hBWE_TD != NULL, st->tdm_LRTD_flag );
383 : }
384 :
385 : /*---------------------------------------------------------*
386 : * Enhance the excitation *
387 : *---------------------------------------------------------*/
388 :
389 3060 : E_UTIL_enhancer( voice_fac, stab_fac, past_gcode, gain_inov, &hLPDmem->gc_threshold, code, exc2, gain_pit, &hLPDmem->dm_fx.prev_gain_code,
390 3060 : hLPDmem->dm_fx.prev_gain_pit, &hLPDmem->dm_fx.prev_state, st->coder_type, acelp_cfg->fixed_cdk_index[j_subfr], L_SUBFR, L_frame, Q_new );
391 :
392 : /*----------------------------------------------------------*
393 : * - compute the synthesis speech *
394 : *----------------------------------------------------------*/
395 :
396 3060 : E_UTIL_synthesis( 1, p_Aq, exc2, &syn2[i_subfr], L_SUBFR, hLPDmem->mem_syn2, 1, M );
397 :
398 : /*Save data for BPF*/
399 :
400 3060 : move16();
401 3060 : move16();
402 : /* st->bpf_T[j_subfr] = (int)((float)T0+(float)T0_frac/(float)T0_res+0.5f); */
403 3060 : st->bpf_T[j_subfr] = add( T0, shr( div_s( T0_frac, T0_res ), 14 ) );
404 3060 : st->bpf_gainT[j_subfr] = gain_pit;
405 :
406 3060 : E_UTIL_synthesis( 1, p_Aq, &exc[i_subfr], &syn[i_subfr], L_SUBFR, &syn[i_subfr - M], 0, M );
407 :
408 : /*----------------------------------------------------------*
409 : * Update *
410 : *----------------------------------------------------------*/
411 :
412 3060 : p_A += ( M + 1 );
413 3060 : p_Aq += ( M + 1 );
414 :
415 3060 : IF( hPlc_Ext != NULL )
416 : {
417 3060 : hPlc_Ext->T0_4th = T0;
418 3060 : move16();
419 : }
420 :
421 3060 : move32();
422 3060 : st->gain_code[j_subfr] = gain_code;
423 :
424 3060 : j_subfr = add( j_subfr, 1 );
425 : } /* end of subframe loop */
426 :
427 612 : p_A -= ( M + 1 );
428 612 : p_Aq -= ( M + 1 );
429 :
430 :
431 : /*----------------------------------------------------------*
432 : * Update LPD memory *
433 : *----------------------------------------------------------*/
434 612 : Copy( exc + L_frame - L_EXC_MEM, hLPDmem->old_exc, L_EXC_MEM );
435 612 : Copy( syn + L_frame - M, hLPDmem->mem_syn, M );
436 612 : Copy( syn + L_frame - L_SYN_MEM, hLPDmem->mem_syn_r, L_SYN_MEM );
437 :
438 612 : IF( hPlc_Ext != NULL )
439 : {
440 612 : hPlc_Ext->Q_exp = sub( Q_new, hPlc_Ext->Q_new );
441 612 : move16();
442 612 : hPlc_Ext->Q_new = Q_new;
443 612 : move16();
444 612 : Copy( exc + L_frame - L_EXC_MEM - 8, hPlc_Ext->old_exc_Qold, 8 );
445 : }
446 :
447 : /*----------------------------------------------------------*
448 : * ZIR at the end of the ACELP frame (for TCX) *
449 : *----------------------------------------------------------*/
450 612 : Copy( syn2, syn, L_frame );
451 612 : move16();
452 612 : tmp = hLPDmem->syn[M];
453 612 : E_UTIL_deemph2( sub( Q_new, 1 ), syn, st->preemph_fac, L_frame, &tmp );
454 :
455 612 : IF( st->hTcxEnc != NULL )
456 : {
457 612 : bufferCopyFx( syn + L_frame - ( L_frame / 2 ), hTcxEnc->Txnq, shr( L_frame, 1 ), 0 /*Qf_syn*/, -1 /*Qf_Txnq*/, 0 /*Q_syn*/, 0 /*Q_Txnq*/ );
458 : }
459 612 : Copy( syn + L_frame - M - 1, hLPDmem->syn, 1 + M ); /*Q0*/
460 612 : Copy( syn, st->synth, L_frame );
461 :
462 612 : assert( T0_res <= 6 );
463 :
464 : /*Update MODE1*/
465 612 : Copy( p_Aq, st->old_Aq_12_8_fx, M + 1 );
466 612 : st->old_Es_pred_fx = Es_pred;
467 612 : move16();
468 612 : return 0;
469 : }
|