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 "options.h" /* Compilation switches */
7 : #include "cnst.h" /* Compilation switches */
8 : #include "rom_com.h" /* Static table prototypes */
9 : #include "prot_fx.h" /* Function prototypes */
10 : #include "prot_fx_enc.h" /* Function prototypes */
11 :
12 :
13 : /*=================================================================================*/
14 : /* FUNCTION : void encod_tran_fx () */
15 : /*---------------------------------------------------------------------------------*/
16 : /* PURPOSE : */
17 : /*---------------------------------------------------------------------------------*/
18 : /* INPUT ARGUMENTS : */
19 : /* (Word16) L_frame_fx : length of the frame Q0 */
20 : /* (Word16[]) speech_fx : input speech Q0 */
21 : /* (Word16[]) Aq_fx : 12k8 Lp coefficient Q12 */
22 : /* (Word16[]) A_fx : unquantized A(z) filter with bandwidth expansion Q12 */
23 : /* (Word16) coder_type : coding type Q0 */
24 : /* (Word16) Es_pred_fx : predicted scaled innov. energy Q8 */
25 : /* (Word16[]) T_op_fx : open loop pitch Q0 */
26 : /* (Word16[]) voicing_fx : voicing Q15 */
27 : /* (Word16*) res_fx : residual signal Q_new*/
28 : /* (Word16) gsc_attack_flag : Flag to indicate when an audio attack is deal with TM*/
29 : /* (Word16) shift : shift factor */
30 : /* (Word16[]) Q_new : input scaling */
31 : /*---------------------------------------------------------------------------------*/
32 : /* OUTPUT ARGUMENTS : */
33 : /* (Word16*) voice_factors : voicing factors Q15 */
34 : /*---------------------------------------------------------------------------------*/
35 : /* INPUT/OUTPUT ARGUMENTS : */
36 : /* Encoder_State *st_fx :Encoder state structure */
37 : /* (Word16*) syn_fx :core synthesis Qnew */
38 : /* (Word16*) exc_fx :current non-enhanced excitation Q0 */
39 : /* (Word16*) exc2_fx :current enhanced excitation Q0 */
40 : /* (Word16*) pitch_buf_fx :floating pitch values for each subframe Q6 */
41 : /* (Word16*) bwe_exc_fx :excitation for SWB TBE Q0 */
42 : /*---------------------------------------------------------------------------------*/
43 : /* RETURN ARGUMENTS : */
44 : /* _ None */
45 : /*---------------------------------------------------------------------------------*/
46 :
47 191 : Word16 encod_tran_fx(
48 : Encoder_State *st_fx, /* i/o: state structure */
49 : const Word16 speech_fx[], /* i : input speech Q0*/
50 : const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/
51 : const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/
52 : const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8*/
53 : const Word16 *res_fx, /* i : residual signal Q_new*/
54 : Word16 *syn_fx, /* i/o: core synthesis Q_new*/
55 : Word16 *exc_fx, /* i/o: current non-enhanced excitation Q0*/
56 : Word16 *exc2_fx, /* i/o: current enhanced excitation Q0*/
57 : Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe Q6*/
58 : Word16 *voice_factors, /* o : voicing factors Q15*/
59 : Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE Q0*/
60 : Word16 tc_subfr, /* i/o: TC subframe classification Q0*/
61 : Word16 position, /* i : maximum of residual signal index Q0*/
62 : Word16 *unbits, /* i/o: number of unused bits Q0*/
63 : const Word16 shift, /* i : Scaling to get 12 bits */
64 : const Word16 Q_new /* i : Input scaling */
65 : )
66 : {
67 : Word16 xn[L_SUBFR]; /* Target vector for pitch search */
68 : Word16 xn2[L_SUBFR]; /* Target vector for codebook search */
69 : Word16 cn[L_SUBFR]; /* Target vector in residual domain */
70 : Word16 h1[L_SUBFR + ( M + 1 )]; /* Impulse response vector */
71 : Word16 h2_fx[L_SUBFR + ( M + 1 )]; /* Impulse response vector */
72 : Word16 code[L_SUBFR]; /* Fixed codebook excitation */
73 : Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */
74 : Word16 y2[L_SUBFR]; /* Filtered algebraic excitation */
75 191 : Word16 gain_pit = 0, Gain_pitX2, gcode16; /* Pitch gain */
76 : Word16 voice_fac; /* Voicing factor */
77 191 : Word32 gain_code = 0; /* Gain of code */
78 : Word32 Lgcode;
79 191 : Word16 gain_inov = 0; /* inovation gain */
80 : Word16 i, i_subfr, tmp1_fx, tmp_fx; /* tmp variables */
81 : Word16 unbits_ACELP;
82 : Word16 T0_min, T0_max; /* pitch and TC variables */
83 : Word16 T0, T0_frac; /* close loop integer pitch and fractional part */
84 : Word16 *pt_pitch; /* pointer to floating pitch buffer */
85 : Word16 g_corr[10]; /* ACELP correlation values and gain pitch */
86 : Word16 clip_gain; /* LSF clip gain */
87 : const Word16 *p_Aw, *p_Aq; /* pointer to LP filter coefficient vector */
88 191 : Word16 gain_preQ = 0; /* Gain of prequantizer excitation */
89 : Word16 code_preQ[L_SUBFR]; /* Prequantizer excitation */
90 : Word16 Jopt_flag; /* joint optimization flag */
91 191 : Word16 unbits_PI = 0; /* saved bits for PI */
92 191 : Word32 norm_gain_code = 0;
93 : Word16 L_frame_fx;
94 : Word16 shift_wsp;
95 : Word32 L_tmp;
96 191 : BSTR_ENC_HANDLE hBstr = st_fx->hBstr;
97 191 : SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR;
98 191 : LPD_state_HANDLE hLPDmem = st_fx->hLPDmem;
99 :
100 191 : L_frame_fx = st_fx->L_frame;
101 191 : move16();
102 :
103 : /*------------------------------------------------------------------*
104 : * Initializations
105 : *------------------------------------------------------------------*/
106 :
107 191 : gain_pit = 0;
108 191 : move16();
109 191 : gain_code = L_deposit_l( 0 );
110 191 : gain_preQ = 0;
111 191 : move16();
112 191 : unbits_PI = 0;
113 191 : move16();
114 191 : IF( EQ_16( L_frame_fx, L_FRAME ) )
115 : {
116 141 : T0_max = PIT_MAX;
117 141 : move16();
118 141 : T0_min = PIT_MIN;
119 141 : move16();
120 : }
121 : ELSE /* L_frame == L_FRAME16k */
122 : {
123 50 : T0_max = PIT16k_MAX;
124 50 : move16();
125 50 : T0_min = PIT16k_MIN;
126 50 : move16();
127 : }
128 :
129 : /**unbits = 0;move16();*/
130 191 : Jopt_flag = 0;
131 191 : move16();
132 191 : unbits_ACELP = *unbits; /* Q0 */
133 191 : move16();
134 191 : *unbits = 0;
135 191 : move16();
136 :
137 191 : p_Aw = Aw_fx; /* Q12 */
138 191 : p_Aq = Aq_fx; /* Q12 */
139 191 : pt_pitch = pitch_buf_fx; /* Q6 */
140 191 : gain_preQ = 0;
141 191 : move16();
142 191 : set16_fx( code_preQ, 0, L_SUBFR );
143 191 : shift_wsp = add( Q_new, shift );
144 :
145 : /*----------------------------------------------------------------*
146 : * ACELP subframe loop
147 : *----------------------------------------------------------------*/
148 :
149 1005 : FOR( i_subfr = 0; i_subfr < L_frame_fx; i_subfr += L_SUBFR )
150 : {
151 : /*----------------------------------------------------------------*
152 : * Find the the excitation search target "xn" and innovation
153 : * target in residual domain "cn"
154 : * Compute impulse response, h1[], of weighted synthesis filter
155 : *----------------------------------------------------------------*/
156 :
157 814 : Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */
158 :
159 814 : find_targets_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq,
160 814 : res_fx, L_SUBFR, p_Aw, st_fx->preemph_fac, xn, cn, h1 );
161 :
162 814 : Copy_Scale_sig( h1, h2_fx, L_SUBFR, -2 );
163 814 : Scale_sig( h1, L_SUBFR, add( 1, shift ) ); /* set h1[] in Q14 with scaling for convolution */
164 :
165 : /* scaling of xn[] to limit dynamic at 12 bits */
166 814 : Scale_sig( xn, L_SUBFR, shift );
167 :
168 : /*-----------------------------------------------------------------*
169 : * TC: subframe determination &
170 : * adaptive/glottal part of excitation construction
171 : *-----------------------------------------------------------------*/
172 :
173 814 : transition_enc_fx( st_fx, i_subfr, &tc_subfr, &Jopt_flag, &position, &T0, &T0_frac, &T0_min, &T0_max, exc_fx, y1,
174 814 : h1, xn, xn2, st_fx->clip_var_fx, &gain_pit, g_corr, &clip_gain, &pt_pitch, bwe_exc_fx, &unbits_ACELP, Q_new, shift );
175 :
176 : /*-----------------------------------------------------------------*
177 : * Transform domain contribution encoding - active frames
178 : *-----------------------------------------------------------------*/
179 :
180 814 : IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) )
181 : {
182 250 : transf_cdbk_enc_fx( st_fx, 0, i_subfr, cn, exc_fx, p_Aq, Aw_fx, h1, xn, xn2, y1, y2, Es_pred_fx,
183 : &gain_pit, gain_code, g_corr, clip_gain, &gain_preQ, code_preQ, unbits, Q_new, shift );
184 : }
185 :
186 : /*-----------------------------------------------------------------*
187 : * ACELP codebook search + pitch sharpening
188 : *-----------------------------------------------------------------*/
189 :
190 814 : inov_encode_fx( st_fx, st_fx->core_brate, 0, L_frame_fx, st_fx->last_L_frame, st_fx->coder_type, st_fx->bwidth, st_fx->sharpFlag,
191 814 : i_subfr, tc_subfr, p_Aq, gain_pit, cn, exc_fx, h2_fx, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &unbits_PI, L_SUBFR, shift );
192 :
193 814 : test();
194 814 : test();
195 814 : test();
196 814 : if ( ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) && ( tc_subfr == 0 ) && ( EQ_16( i_subfr, L_SUBFR ) ) && ( EQ_16( T0, 2 * L_SUBFR ) ) )
197 : {
198 7 : Jopt_flag = 1;
199 7 : move16();
200 : }
201 :
202 : /*-----------------------------------------------------------------*
203 : * Quantize the gains
204 : * Test quantized gain of pitch for pitch clipping algorithm
205 : * Update tilt of code: 0.0 (unvoiced) to 0.5 (voiced)
206 : *-----------------------------------------------------------------*/
207 :
208 814 : IF( Jopt_flag == 0 )
209 : {
210 : /* SQ gain_code */
211 170 : gain_enc_tc_fx( hBstr, st_fx->acelp_cfg.gains_mode, i_subfr, xn, y2, code, Es_pred_fx,
212 : &gain_pit, &gain_code, &gain_inov, &norm_gain_code, shift_wsp );
213 : }
214 : ELSE
215 : {
216 644 : IF( GT_32( st_fx->core_brate, ACELP_32k ) )
217 : {
218 : /* SQ gain_pit and gain_code */
219 238 : gain_enc_SQ_fx( hBstr, st_fx->acelp_cfg.gains_mode, i_subfr, xn, y1, y2, code, Es_pred_fx,
220 : &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, clip_gain, shift_wsp );
221 : }
222 : ELSE
223 : {
224 : /* VQ gain_pit and gain_code */
225 406 : gain_enc_mless_fx( hBstr, st_fx->acelp_cfg.gains_mode, st_fx->element_mode, L_frame_fx, i_subfr, tc_subfr, xn, y1, shift_wsp, y2, code, Es_pred_fx,
226 : &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, clip_gain );
227 : }
228 : }
229 814 : gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit, st_fx->clip_var_fx );
230 :
231 814 : Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/
232 814 : gcode16 = round_fx_sat( Lgcode );
233 814 : hLPDmem->tilt_code = Est_tilt2( &exc_fx[i_subfr], gain_pit, code, Lgcode, &voice_fac, shift ); /* Q15 */
234 :
235 : /*-----------------------------------------------------------------*
236 : * Update memory of the weighting filter
237 : *-----------------------------------------------------------------*/
238 :
239 : /*st->mem_w0 = xn[L_SUBFR-1] - (gain_pit*y1[L_SUBFR-1]) - (gain_code*y2[L_SUBFR-1]);*/
240 814 : L_tmp = L_mult( gcode16, y2[L_SUBFR - 1] ); /* Q10 + Q_new */
241 814 : L_tmp = L_shl( L_tmp, add( 5, shift ) ); /* Q15 + Q_new + shift */
242 814 : L_tmp = L_negate( L_tmp );
243 814 : L_tmp = L_mac( L_tmp, xn[L_SUBFR - 1], 16384 );
244 814 : L_tmp = L_msu( L_tmp, y1[L_SUBFR - 1], gain_pit );
245 814 : L_tmp = L_shl_sat( L_tmp, sub( 1, shift ) ); /* Q_new + 15 */
246 814 : hLPDmem->mem_w0 = round_fx_sat( L_tmp ); /*Q_new-1*/
247 :
248 : /*-----------------------------------------------------------------*
249 : * Construct adaptive part of the excitation
250 : * Save the non-enhanced excitation for FEC_exc
251 : *-----------------------------------------------------------------*/
252 :
253 : /* Here, all these conditions have one purpose: to use */
254 : /* the most efficient loop (the one with the least ops) */
255 : /* This is done by upscaling gain_pit_fx and/or gain_code16 */
256 : /* when they don't use all 16 bits of precision */
257 :
258 : /* exc Q_exc, gpit Q14, code Q12, gcode Q0 */
259 814 : IF( norm_s( gain_pit ) == 0 )
260 : {
261 20345 : FOR( i = 0; i < L_SUBFR; i++ )
262 : {
263 20032 : exc2_fx[i + i_subfr] = round_fx_sat( L_shl_sat( L_mult_sat( gain_pit, exc_fx[i + i_subfr] ), 1 ) ); /* Q_new */
264 : }
265 : }
266 : ELSE
267 : {
268 501 : Gain_pitX2 = shl( gain_pit, 1 ); /* Q15 */
269 32565 : FOR( i = 0; i < L_SUBFR; i++ )
270 : {
271 32064 : exc2_fx[i + i_subfr] = mult_r( Gain_pitX2, exc_fx[i + i_subfr] ); /* Q_new */
272 : }
273 : }
274 :
275 : /*-----------------------------------------------------------------*
276 : * Construct adaptive part of the excitation
277 : * Save the non-enhanced excitation for FEC_exc
278 : *-----------------------------------------------------------------*/
279 52910 : FOR( i = 0; i < L_SUBFR; i++ )
280 : {
281 : /* code in Q9, gain_pit in Q14 */
282 52096 : L_tmp = L_mult( gcode16, code[i] ); /* Q10 + Q_new */
283 52096 : L_tmp = L_shl_sat( L_tmp, 5 ); /* Q15 + Q_new */
284 52096 : L_tmp = L_mac_sat( L_tmp, exc_fx[i + i_subfr], gain_pit ); /* Q15 + Q_new */
285 52096 : L_tmp = L_shl_sat( L_tmp, 1 ); /* saturation can occur here Q16 + Q_new */
286 52096 : exc_fx[i + i_subfr] = round_fx_sat( L_tmp ); /* Q_new */
287 : }
288 :
289 : /*-----------------------------------------------------------------*
290 : * Add the ACELP pre-quantizer contribution
291 : *-----------------------------------------------------------------*/
292 :
293 814 : IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) )
294 : {
295 250 : tmp1_fx = add( 16 - ( 2 + Q_AVQ_OUT_DEC + 1 ), Q_new );
296 16250 : FOR( i = 0; i < L_SUBFR; i++ )
297 : {
298 16000 : L_tmp = L_mult( gain_preQ, code_preQ[i] ); /* Q2 + Q10 -> Q13*/
299 16000 : L_tmp = L_shl_sat( L_tmp, tmp1_fx ); /* Q16 + Q_exc */
300 16000 : tmp_fx = round_fx_sat( L_tmp );
301 16000 : exc2_fx[i + i_subfr] = add_sat( exc2_fx[i + i_subfr], tmp_fx ); /* Q_exc */
302 16000 : move16();
303 16000 : exc_fx[i + i_subfr] = add_sat( exc_fx[i + i_subfr], tmp_fx ); /* Q_exc */
304 16000 : move16();
305 : }
306 : }
307 :
308 : /*-----------------------------------------------------------------*
309 : * Prepare TBE excitation
310 : *-----------------------------------------------------------------*/
311 :
312 814 : prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR],
313 814 : bwe_exc_fx, gain_preQ, code_preQ, Q10, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate, st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag );
314 :
315 : /*-----------------------------------------------------------------*
316 : * Synthesize speech to update mem_syn[].
317 : * Update A(z) filters
318 : *-----------------------------------------------------------------*/
319 :
320 814 : Syn_filt_s( 1, p_Aq, M, &exc_fx[i_subfr], &syn_fx[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1 );
321 :
322 814 : p_Aw += ( M + 1 );
323 814 : p_Aq += ( M + 1 );
324 814 : pt_pitch++;
325 : }
326 :
327 : /* write reserved bits */
328 191 : WHILE( unbits_PI > 0 )
329 : {
330 0 : i = s_min( unbits_PI, 16 );
331 0 : push_indice( hBstr, IND_UNUSED, 0, i );
332 0 : unbits_PI -= i;
333 : }
334 :
335 : /* write TC configuration */
336 191 : IF( EQ_16( L_frame_fx, L_FRAME ) )
337 : {
338 141 : IF( EQ_16( tc_subfr, TC_0_0 ) )
339 : {
340 55 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
341 : }
342 86 : ELSE IF( EQ_16( tc_subfr, TC_0_64 ) )
343 : {
344 13 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
345 13 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
346 13 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
347 13 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
348 : }
349 73 : ELSE IF( EQ_16( tc_subfr, TC_0_128 ) )
350 : {
351 18 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
352 18 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
353 18 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
354 18 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
355 : }
356 55 : ELSE IF( EQ_16( tc_subfr, TC_0_192 ) )
357 : {
358 3 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
359 3 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
360 3 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
361 : }
362 52 : ELSE IF( EQ_16( tc_subfr, L_SUBFR ) )
363 : {
364 10 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
365 10 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
366 10 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
367 : }
368 42 : ELSE IF( EQ_16( tc_subfr, 2 * L_SUBFR ) )
369 : {
370 2 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
371 2 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
372 2 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
373 2 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
374 : }
375 40 : ELSE IF( EQ_16( tc_subfr, 3 * L_SUBFR ) )
376 : {
377 40 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
378 40 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
379 40 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
380 40 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
381 : }
382 : }
383 : ELSE /* L_frame == L_FRAME16k */
384 : {
385 50 : IF( tc_subfr == 0 )
386 : {
387 39 : push_indice( hBstr, IND_TC_SUBFR, 0, 2 );
388 : }
389 11 : ELSE IF( EQ_16( tc_subfr, L_SUBFR ) )
390 : {
391 10 : push_indice( hBstr, IND_TC_SUBFR, 1, 2 );
392 : }
393 1 : ELSE IF( EQ_16( tc_subfr, 2 * L_SUBFR ) )
394 : {
395 1 : push_indice( hBstr, IND_TC_SUBFR, 2, 2 );
396 : }
397 0 : ELSE IF( EQ_16( tc_subfr, 3 * L_SUBFR ) )
398 : {
399 0 : push_indice( hBstr, IND_TC_SUBFR, 3, 2 );
400 0 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
401 : }
402 0 : ELSE IF( EQ_16( tc_subfr, 4 * L_SUBFR ) )
403 : {
404 0 : push_indice( hBstr, IND_TC_SUBFR, 3, 2 );
405 0 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
406 : }
407 : }
408 :
409 191 : IF( st_fx->Opt_SC_VBR )
410 : {
411 : /* SC-VBR */
412 0 : hSC_VBR->prev_ppp_gain_pit_fx = gain_pit; /* Q14 */
413 0 : move16();
414 0 : hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; /* Q15 */
415 0 : move16();
416 : }
417 :
418 191 : return tc_subfr;
419 : }
420 :
421 :
422 22354 : Word16 encod_tran_ivas_fx(
423 : Encoder_State *st_fx, /* i/o: state structure */
424 : const Word16 speech_fx[], /* i : input speech Q0*/
425 : const Word16 Aw_fx[], /* i : weighted A(z) unquantized for subframes Q12*/
426 : const Word16 Aq_fx[], /* i : 12k8 Lp coefficient Q12*/
427 : const Word16 Es_pred_fx, /* i : predicted scaled innov. energy Q8*/
428 : const Word16 *res_fx, /* i : residual signal Q_new*/
429 : Word16 *syn_fx, /* i/o: core synthesis Q_new*/
430 : Word16 *exc_fx, /* i/o: current non-enhanced excitation Q0*/
431 : Word16 *exc2_fx, /* i/o: current enhanced excitation Q0*/
432 : Word16 *pitch_buf_fx, /* i/o: floating pitch values for each subframe Q6*/
433 : Word16 *voice_factors, /* o : voicing factors Q15*/
434 : Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE Q0*/
435 : Word16 tc_subfr, /* i/o: TC subframe classification Q0*/
436 : Word16 position, /* i : maximum of residual signal index Q0*/
437 : Word16 *unbits, /* i/o: number of unused bits Q0*/
438 : const Word16 shift_r, /* i : Scaling to get 12 bits */
439 : const Word16 Q_new /* i : Input scaling */
440 : )
441 : {
442 : Word16 xn[L_SUBFR]; /* Target vector for pitch search */
443 : Word16 xn2[L_SUBFR]; /* Target vector for codebook search */
444 : Word16 cn[L_SUBFR]; /* Target vector in residual domain */
445 : Word16 h1[L_SUBFR + ( M + 1 )]; /* Impulse response vector */
446 : Word16 h2_fx[L_SUBFR + ( M + 1 )]; /* Impulse response vector */
447 : Word16 code[L_SUBFR]; /* Fixed codebook excitation */
448 : Word16 y1[L_SUBFR]; /* Filtered adaptive excitation */
449 : Word16 y2[L_SUBFR]; /* Filtered algebraic excitation */
450 22354 : Word16 gain_pit = 0, Gain_pitX2, gcode16; /* Pitch gain */
451 : Word16 voice_fac; /* Voicing factor */
452 22354 : Word32 gain_code = 0; /* Gain of code */
453 : Word32 Lgcode;
454 22354 : Word16 gain_inov = 0; /* inovation gain */
455 : Word16 i, i_subfr, tmp1_fx, tmp_fx; /* tmp variables */
456 : Word16 unbits_ACELP;
457 : Word16 T0_min, T0_max; /* pitch and TC variables */
458 : Word16 T0, T0_frac; /* close loop integer pitch and fractional part */
459 : Word16 *pt_pitch; /* pointer to floating pitch buffer */
460 : Word16 g_corr[10]; /* ACELP correlation values and gain pitch */
461 : Word16 clip_gain; /* LSF clip gain */
462 : const Word16 *p_Aw, *p_Aq; /* pointer to LP filter coefficient vector */
463 22354 : Word16 gain_preQ = 0; /* Gain of prequantizer excitation */
464 : Word16 code_preQ[L_SUBFR]; /* Prequantizer excitation */
465 : Word16 Jopt_flag; /* joint optimization flag */
466 22354 : Word16 unbits_PI = 0; /* saved bits for PI */
467 22354 : Word32 norm_gain_code = 0;
468 : Word16 L_frame_fx;
469 : Word16 shift_wsp;
470 : Word32 L_tmp;
471 : Word16 q_h1;
472 : Word16 shift, tmp;
473 22354 : BSTR_ENC_HANDLE hBstr = st_fx->hBstr;
474 22354 : SC_VBR_ENC_HANDLE hSC_VBR = st_fx->hSC_VBR;
475 22354 : LPD_state_HANDLE hLPDmem = st_fx->hLPDmem;
476 :
477 22354 : shift = shift_r; /* for IVAS, shift_r is always 0 */
478 : /* will be reusing the EVS shift strategy later on to allow of H1 overshoot */
479 22354 : move16();
480 22354 : L_frame_fx = st_fx->L_frame;
481 22354 : move16();
482 :
483 22354 : set16_fx( h1, 0, L_SUBFR + ( M + 1 ) );
484 :
485 : /*------------------------------------------------------------------*
486 : * Initializations
487 : *------------------------------------------------------------------*/
488 :
489 22354 : gain_pit = 0;
490 22354 : move16();
491 22354 : gain_code = L_deposit_l( 0 );
492 22354 : gain_preQ = 0;
493 22354 : move16();
494 22354 : unbits_PI = 0;
495 22354 : move16();
496 22354 : IF( EQ_16( L_frame_fx, L_FRAME ) )
497 : {
498 11500 : T0_max = PIT_MAX;
499 11500 : move16();
500 11500 : T0_min = PIT_MIN;
501 11500 : move16();
502 : }
503 : ELSE /* L_frame == L_FRAME16k */
504 : {
505 10854 : T0_max = PIT16k_MAX;
506 10854 : move16();
507 10854 : T0_min = PIT16k_MIN;
508 10854 : move16();
509 : }
510 :
511 : /**unbits = 0;move16();*/
512 22354 : Jopt_flag = 0;
513 22354 : move16();
514 22354 : unbits_ACELP = *unbits; /* Q0 */
515 22354 : move16();
516 22354 : *unbits = 0;
517 22354 : move16();
518 :
519 22354 : p_Aw = Aw_fx; /* Q12 */
520 22354 : p_Aq = Aq_fx; /* Q12 */
521 22354 : pt_pitch = pitch_buf_fx;
522 22354 : gain_preQ = 0;
523 22354 : move16();
524 22354 : set16_fx( code_preQ, 0, L_SUBFR );
525 22354 : shift_wsp = add( Q_new, shift );
526 22354 : if ( LT_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) )
527 : {
528 19741 : shift_wsp = sub( shift_wsp, 1 );
529 : }
530 :
531 : /*----------------------------------------------------------------*
532 : * ACELP subframe loop
533 : *----------------------------------------------------------------*/
534 :
535 122624 : FOR( i_subfr = 0; i_subfr < L_frame_fx; i_subfr += L_SUBFR )
536 : {
537 : /*----------------------------------------------------------------*
538 : * Find the the excitation search target "xn" and innovation
539 : * target in residual domain "cn"
540 : * Compute impulse response, h1[], of weighted synthesis filter
541 : *----------------------------------------------------------------*/
542 :
543 100270 : Copy( &res_fx[i_subfr], &exc_fx[i_subfr], L_SUBFR ); /* Q_new */
544 :
545 :
546 100270 : find_targets_ivas_fx( speech_fx, hLPDmem->mem_syn, i_subfr, &hLPDmem->mem_w0, p_Aq,
547 100270 : res_fx, L_SUBFR, p_Aw, st_fx->preemph_fac, xn, cn, h1 );
548 :
549 100270 : q_h1 = sub( 14, norm_s( h1[0] ) );
550 100270 : tmp = sub( 14, norm_arr( h1, L_SUBFR ) );
551 100270 : shift = sub( q_h1, tmp ); /* shift is initialized to shift_r ( to 0) at the beginning of the scope, re-compute shift_wsp in case it has changed */
552 100270 : shift_wsp = add( Q_new, shift );
553 100270 : if ( LT_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) )
554 : {
555 87205 : shift_wsp = sub( shift_wsp, 1 );
556 : }
557 100270 : Copy_Scale_sig( h1, h2_fx, L_SUBFR, sub( 11, q_h1 ) ); /*Q11*/
558 100270 : Scale_sig( h1, L_SUBFR, add( sub( 14, q_h1 ), shift ) );
559 : /* scaling of xn[] to limit dynamic at 12 bits */
560 100270 : Scale_sig( xn, L_SUBFR, shift );
561 :
562 : /*-----------------------------------------------------------------*
563 : * TC: subframe determination &
564 : * adaptive/glottal part of excitation construction
565 : *-----------------------------------------------------------------*/
566 :
567 100270 : transition_enc_ivas_fx( st_fx, i_subfr, &tc_subfr, &Jopt_flag, &position, &T0, &T0_frac, &T0_min, &T0_max, exc_fx, y1,
568 100270 : h1, xn, xn2, st_fx->clip_var_fx, &gain_pit, g_corr, &clip_gain, &pt_pitch, bwe_exc_fx, &unbits_ACELP, Q_new, shift );
569 :
570 : /*-----------------------------------------------------------------*
571 : * Transform domain contribution encoding - active frames
572 : *-----------------------------------------------------------------*/
573 :
574 100270 : IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) )
575 : {
576 13065 : transf_cdbk_enc_ivas_fx( st_fx, 0, i_subfr, cn, exc_fx, p_Aq, Aw_fx, h1, xn, xn2, y1, y2, Es_pred_fx,
577 : &gain_pit, gain_code, g_corr, clip_gain, &gain_preQ, code_preQ, unbits, Q_new, shift );
578 : }
579 :
580 : /*-----------------------------------------------------------------*
581 : * ACELP codebook search + pitch sharpening
582 : *-----------------------------------------------------------------*/
583 :
584 100270 : inov_encode_ivas_fx( st_fx, st_fx->core_brate, 0, L_frame_fx, st_fx->last_L_frame, st_fx->coder_type, st_fx->bwidth, st_fx->sharpFlag,
585 100270 : i_subfr, tc_subfr, p_Aq, gain_pit, cn, exc_fx, h2_fx, hLPDmem->tilt_code, *pt_pitch, xn2, code, y2, &unbits_PI, L_SUBFR, shift, Q_new );
586 :
587 100270 : test();
588 100270 : test();
589 100270 : test();
590 100270 : if ( ( EQ_16( st_fx->L_frame, L_FRAME16k ) ) && ( tc_subfr == 0 ) && ( EQ_16( i_subfr, L_SUBFR ) ) && ( EQ_16( T0, 2 * L_SUBFR ) ) )
591 : {
592 748 : Jopt_flag = 1;
593 748 : move16();
594 : }
595 :
596 : /*-----------------------------------------------------------------*
597 : * Quantize the gains
598 : * Test quantized gain of pitch for pitch clipping algorithm
599 : * Update tilt of code: 0.0 (unvoiced) to 0.5 (voiced)
600 : *-----------------------------------------------------------------*/
601 :
602 100270 : IF( Jopt_flag == 0 )
603 : {
604 : /* SQ gain_code */
605 30576 : gain_enc_tc_fx( hBstr, st_fx->acelp_cfg.gains_mode, i_subfr, xn, y2, code, Es_pred_fx,
606 : &gain_pit, &gain_code, &gain_inov, &norm_gain_code, shift_wsp );
607 : }
608 : ELSE
609 : {
610 69694 : IF( GT_32( st_fx->core_brate, ACELP_32k ) )
611 : {
612 : /* SQ gain_pit and gain_code */
613 5985 : gain_enc_SQ_fx( hBstr, st_fx->acelp_cfg.gains_mode, i_subfr, xn, y1, y2, code, Es_pred_fx,
614 : &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, clip_gain, shift_wsp );
615 : }
616 : ELSE
617 : {
618 : /* VQ gain_pit and gain_code */
619 63709 : gain_enc_mless_fx( hBstr, st_fx->acelp_cfg.gains_mode, st_fx->element_mode, L_frame_fx, i_subfr, tc_subfr, xn, y1, shift_wsp, y2, code, Es_pred_fx,
620 : &gain_pit, &gain_code, &gain_inov, &norm_gain_code, g_corr, clip_gain );
621 : }
622 : }
623 100270 : gp_clip_test_gain_pit_fx( st_fx->element_mode, st_fx->core_brate, gain_pit, st_fx->clip_var_fx );
624 :
625 100270 : Lgcode = L_shl_sat( gain_code, Q_new ); /* scaled gain_code with Qnew -> Q16*/
626 100270 : gcode16 = round_fx_sat( Lgcode );
627 100270 : hLPDmem->tilt_code = est_tilt_ivas_fx( &exc_fx[i_subfr], gain_pit, code, gain_code, &voice_fac, Q_new, L_SUBFR, 0 ); // Q15
628 :
629 : /*-----------------------------------------------------------------*
630 : * Update memory of the weighting filter
631 : *-----------------------------------------------------------------*/
632 :
633 : /*st->mem_w0 = xn[L_SUBFR-1] - (gain_pit*y1[L_SUBFR-1]) - (gain_code*y2[L_SUBFR-1]);*/
634 100270 : L_tmp = L_mult0( gcode16, y2[L_SUBFR - 1] );
635 100270 : L_tmp = L_shl( L_tmp, add( 5, shift ) ); // Q_new+14+shift
636 100270 : L_tmp = L_negate( L_tmp );
637 100270 : L_tmp = L_mac( L_tmp, xn[L_SUBFR - 1], 16384 ); // Q_new-1+15+shift
638 100270 : L_tmp = L_msu( L_tmp, y1[L_SUBFR - 1], gain_pit ); // Q_new-1+15+shift
639 100270 : L_tmp = L_shl_sat( L_tmp, sub( 1, shift ) ); // Q_new+15
640 100270 : hLPDmem->mem_w0 = round_fx_sat( L_tmp ); /*Q_new-1*/
641 :
642 : /*-----------------------------------------------------------------*
643 : * Construct adaptive part of the excitation
644 : * Save the non-enhanced excitation for FEC_exc
645 : *-----------------------------------------------------------------*/
646 :
647 : /* Here, all these conditions have one purpose: to use */
648 : /* the most efficient loop (the one with the least ops) */
649 : /* This is done by upscaling gain_pit_fx and/or gain_code16 */
650 : /* when they don't use all 16 bits of precision */
651 :
652 : /* exc Q_exc, gpit Q14, code Q12, gcode Q0 */
653 100270 : IF( norm_s( gain_pit ) == 0 )
654 : {
655 2726555 : FOR( i = 0; i < L_SUBFR; i++ )
656 : {
657 2684608 : exc2_fx[i + i_subfr] = round_fx_sat( L_shl_sat( L_mult_sat( gain_pit, exc_fx[i + i_subfr] ), 1 ) ); /* Q_exc */
658 : }
659 : }
660 : ELSE
661 : {
662 58323 : Gain_pitX2 = shl( gain_pit, 1 );
663 3790995 : FOR( i = 0; i < L_SUBFR; i++ )
664 : {
665 3732672 : exc2_fx[i + i_subfr] = mult_r( Gain_pitX2, exc_fx[i + i_subfr] ); /* Q_exc */
666 : }
667 : }
668 :
669 : /*-----------------------------------------------------------------*
670 : * Construct adaptive part of the excitation
671 : * Save the non-enhanced excitation for FEC_exc
672 : *-----------------------------------------------------------------*/
673 :
674 6517550 : FOR( i = 0; i < L_SUBFR; i++ )
675 : {
676 : /* code in Q9, gain_pit in Q14 */
677 6417280 : L_tmp = L_mult( gcode16, code[i] ); /* Q10 + Q_new */
678 6417280 : L_tmp = L_shl_sat( L_tmp, 5 ); /* Q15 + Q_new */
679 6417280 : L_tmp = L_mac_sat( L_tmp, exc_fx[i + i_subfr], gain_pit ); /* Q15 + Q_new */
680 6417280 : L_tmp = L_shl_sat( L_tmp, 1 ); /* saturation can occur here Q16 + Q_new */
681 6417280 : exc_fx[i + i_subfr] = round_fx_sat( L_tmp ); /* Q_new */
682 : }
683 :
684 : /*-----------------------------------------------------------------*
685 : * Add the ACELP pre-quantizer contribution
686 : *-----------------------------------------------------------------*/
687 :
688 100270 : IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) )
689 : {
690 13065 : tmp1_fx = add( 16 - ( 2 + Q_AVQ_OUT_DEC + 1 ), Q_new );
691 849225 : FOR( i = 0; i < L_SUBFR; i++ )
692 : {
693 836160 : L_tmp = L_mult( gain_preQ, code_preQ[i] ); /* Q2 + Q10 -> Q13*/
694 836160 : L_tmp = L_shl_sat( L_tmp, tmp1_fx ); /* Q16 + Q_exc */
695 836160 : tmp_fx = round_fx_sat( L_tmp );
696 :
697 836160 : exc2_fx[i + i_subfr] = add_sat( exc2_fx[i + i_subfr], tmp_fx ); /* Q_exc */
698 836160 : move16();
699 836160 : exc_fx[i + i_subfr] = add_sat( exc_fx[i + i_subfr], tmp_fx ); /* Q_exc */
700 836160 : move16();
701 : }
702 : }
703 :
704 : /*-----------------------------------------------------------------*
705 : * Prepare TBE excitation
706 : *-----------------------------------------------------------------*/
707 :
708 100270 : prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit, gain_code, code, voice_fac, &voice_factors[i_subfr / L_SUBFR],
709 100270 : bwe_exc_fx, gain_preQ, code_preQ, Q10, Q_new, T0, T0_frac, st_fx->coder_type, st_fx->core_brate,
710 100270 : st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag );
711 :
712 : /*-----------------------------------------------------------------*
713 : * Synthesize speech to update mem_syn[].
714 : * Update A(z) filters
715 : *-----------------------------------------------------------------*/
716 :
717 100270 : Syn_filt_s( 1, p_Aq, M, &exc_fx[i_subfr], &syn_fx[i_subfr], L_SUBFR, hLPDmem->mem_syn, 1 );
718 :
719 100270 : p_Aw += ( M + 1 );
720 100270 : p_Aq += ( M + 1 );
721 100270 : pt_pitch++;
722 : }
723 :
724 : /* write reserved bits */
725 22354 : WHILE( unbits_PI > 0 )
726 : {
727 0 : i = s_min( unbits_PI, 16 );
728 0 : push_indice( hBstr, IND_UNUSED, 0, i );
729 0 : unbits_PI -= i;
730 : }
731 :
732 : /* write TC configuration */
733 22354 : IF( EQ_16( L_frame_fx, L_FRAME ) )
734 : {
735 11500 : IF( EQ_16( tc_subfr, TC_0_0 ) )
736 : {
737 3184 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
738 : }
739 8316 : ELSE IF( EQ_16( tc_subfr, TC_0_64 ) )
740 : {
741 1713 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
742 1713 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
743 1713 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
744 1713 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
745 : }
746 6603 : ELSE IF( EQ_16( tc_subfr, TC_0_128 ) )
747 : {
748 924 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
749 924 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
750 924 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
751 924 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
752 : }
753 5679 : ELSE IF( EQ_16( tc_subfr, TC_0_192 ) )
754 : {
755 381 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
756 381 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
757 381 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
758 : }
759 5298 : ELSE IF( EQ_16( tc_subfr, L_SUBFR ) )
760 : {
761 1688 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
762 1688 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
763 1688 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
764 : }
765 3610 : ELSE IF( EQ_16( tc_subfr, 2 * L_SUBFR ) )
766 : {
767 864 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
768 864 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
769 864 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
770 864 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
771 : }
772 2746 : ELSE IF( EQ_16( tc_subfr, 3 * L_SUBFR ) )
773 : {
774 2746 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
775 2746 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
776 2746 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
777 2746 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
778 : }
779 : }
780 : ELSE /* L_frame == L_FRAME16k */
781 : {
782 10854 : IF( tc_subfr == 0 )
783 : {
784 4678 : push_indice( hBstr, IND_TC_SUBFR, 0, 2 );
785 : }
786 6176 : ELSE IF( EQ_16( tc_subfr, L_SUBFR ) )
787 : {
788 1332 : push_indice( hBstr, IND_TC_SUBFR, 1, 2 );
789 : }
790 4844 : ELSE IF( EQ_16( tc_subfr, 2 * L_SUBFR ) )
791 : {
792 1531 : push_indice( hBstr, IND_TC_SUBFR, 2, 2 );
793 : }
794 3313 : ELSE IF( EQ_16( tc_subfr, 3 * L_SUBFR ) )
795 : {
796 410 : push_indice( hBstr, IND_TC_SUBFR, 3, 2 );
797 410 : push_indice( hBstr, IND_TC_SUBFR, 0, 1 );
798 : }
799 2903 : ELSE IF( EQ_16( tc_subfr, 4 * L_SUBFR ) )
800 : {
801 2903 : push_indice( hBstr, IND_TC_SUBFR, 3, 2 );
802 2903 : push_indice( hBstr, IND_TC_SUBFR, 1, 1 );
803 : }
804 : }
805 :
806 22354 : IF( st_fx->Opt_SC_VBR )
807 : {
808 : /* SC-VBR */
809 0 : hSC_VBR->prev_ppp_gain_pit_fx = gain_pit; /* Q14 */
810 0 : move16();
811 0 : hSC_VBR->prev_tilt_code_fx = hLPDmem->tilt_code; /* Q15 */
812 0 : move16();
813 : }
814 :
815 22354 : return tc_subfr;
816 : }
|