Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <stdint.h>
5 : #include "options.h" /* Compilation switches */
6 : #include "cnst.h" /* Common constants */
7 : #include "rom_com.h" /* Static table prototypes */
8 : #include "prot_fx.h" /* Function prototypes */
9 :
10 : /*==========================================================================*/
11 : /* FUNCTION : void dec_pit_exc_fx() */
12 : /*--------------------------------------------------------------------------*/
13 : /* PURPOSE : Decode pitch only contribution */
14 : /*--------------------------------------------------------------------------*/
15 : /* INPUT ARGUMENTS : */
16 : /* _ (Word16*) Aq_fx : LP filter coefficient Q12 */
17 : /* _ (Word16) coder_type : coding type Q0 */
18 : /* _ (Word16) nb_subfr_fx :Number of subframe considered */
19 : /* _ (Word16) Es_pred_fx :predicted scaled innov. energy */
20 : /*--------------------------------------------------------------------------*/
21 : /* OUTPUT ARGUMENTS : */
22 : /* _ (Word16*) pitch_buf_fx : floating pitch values for each subframe Q6 */
23 : /* _ (Word16*) code_fx : innovation Q12 */
24 : /*--------------------------------------------------------------------------*/
25 : /* INPUT/OUTPUT ARGUMENTS : */
26 : /* Decoder_State_fx *st_fx : decoder state structure */
27 : /* _ (Word16*) exc_fx : adapt. excitation exc */
28 : /*--------------------------------------------------------------------------*/
29 : /* RETURN ARGUMENTS : */
30 : /* _ None */
31 : /*==========================================================================*/
32 :
33 11717 : void dec_pit_exc_fx(
34 : Decoder_State *st_fx, /* i/o: decoder static memory */
35 : const Word16 *Aq_fx, /* i : LP filter coefficient */
36 : const Word16 coder_type, /* i : coding type */
37 : const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */
38 : Word16 *pitch_buf_fx, /* o : Word16 pitch values for each subframe */
39 : Word16 *code_fx, /* o : innovation */
40 : Word16 *exc_fx, /* i/o: adapt. excitation exc */
41 : Word16 *bwe_exc_fx, /* o : excitation for SWB TBE */
42 : const Word16 nb_subfr_fx, /* i : Number of subframe considered */
43 : Word16 *gain_buf, /* o : Word16 pitch gain for each subframe Q14*/
44 : const Word16 tdm_Pitch_reuse_flag, /* i : primary channel pitch reuse flag */
45 : const Word16 tdm_Pri_pitch_buf[] /* i : primary channel pitch buffer */
46 : )
47 : {
48 : Word16 T0_fx, T0_frac_fx, T0_min_fx, T0_max_fx; /* integer pitch variables */
49 : Word16 gain_pit_fx; /* pitch gain Q14 */
50 : Word32 gain_code_fx; /* gain/normalized gain of the algebraic excitation Q16 */
51 : Word32 norm_gain_code_fx; /* normalized gain of the algebraic excitation Q16 */
52 : Word16 gain_inov_fx; /* Innovation gain Q12 */
53 : Word16 voice_fac_fx; /* voicing factor Q15 */
54 : Word16 L_subfr_fx, pit_idx_fx;
55 : const Word16 *p_Aq_fx; /* Pointer to frame LP coefficient Q12 */
56 : Word16 *pt_pitch_fx; /* pointer to Word16 pitch Q6 */
57 : Word16 i_subfr_fx, i; /* tmp variables */
58 : Word32 Local_BR_fx, Pitch_BR_fx;
59 : Word16 pitch_limit_flag, Pitch_CT_fx;
60 : Word16 *pt_gain; /* Pointer to Word16 gain values for each subframe */
61 :
62 : Word16 gain_code16, gain_pitx2;
63 : Word32 L_tmp;
64 : Word16 nbits;
65 : GSC_DEC_HANDLE hGSCDec;
66 11717 : gain_pit_fx = 0;
67 11717 : move16();
68 11717 : hGSCDec = st_fx->hGSCDec;
69 :
70 : MUSIC_POSTFILT_HANDLE hMusicPF;
71 11717 : hMusicPF = st_fx->hMusicPF;
72 :
73 : Word16 use_fcb;
74 : Word32 gc_mem[NB_SUBFR - 1]; /* gain_code from previous subframes */
75 : Word16 gp_mem[NB_SUBFR - 1]; /* gain_pitch from previous subframes */
76 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
77 11717 : Flag Overflow = 0;
78 11717 : move32();
79 : #endif
80 :
81 11717 : use_fcb = 0;
82 11717 : move16();
83 11717 : test();
84 11717 : test();
85 11717 : IF( ( st_fx->GSC_IVAS_mode > 0 ) && ( EQ_16( st_fx->GSC_noisy_speech, 1 ) || GT_32( st_fx->core_brate, GSC_H_RATE_STG ) ) )
86 : {
87 99 : Local_BR_fx = ACELP_8k00;
88 99 : Pitch_CT_fx = GENERIC;
89 99 : Pitch_BR_fx = ACELP_8k00;
90 99 : move32();
91 99 : move32();
92 99 : move16();
93 99 : IF( EQ_16( st_fx->L_frame, L_FRAME16k ) )
94 : {
95 0 : Local_BR_fx = ACELP_14k80;
96 0 : move32();
97 0 : if ( st_fx->GSC_IVAS_mode > 0 )
98 : {
99 0 : Local_BR_fx = ACELP_9k60;
100 0 : move32();
101 : }
102 0 : Pitch_BR_fx = st_fx->core_brate;
103 0 : move32();
104 : }
105 : }
106 11618 : ELSE IF( EQ_16( st_fx->GSC_noisy_speech, 1 ) )
107 : {
108 695 : Local_BR_fx = ACELP_7k20;
109 695 : move32();
110 695 : Pitch_CT_fx = GENERIC;
111 695 : move16();
112 695 : Pitch_BR_fx = ACELP_7k20;
113 695 : move32();
114 695 : if ( EQ_16( st_fx->L_frame, L_FRAME16k ) )
115 : {
116 0 : Pitch_BR_fx = st_fx->core_brate;
117 0 : move32();
118 : }
119 : }
120 : ELSE
121 : {
122 10923 : Local_BR_fx = ACELP_7k20;
123 10923 : move32();
124 10923 : Pitch_CT_fx = AUDIO;
125 10923 : move16();
126 10923 : Pitch_BR_fx = st_fx->core_brate;
127 10923 : move32();
128 10923 : IF( EQ_16( st_fx->L_frame, L_FRAME16k ) )
129 : {
130 1024 : Pitch_BR_fx = ACELP_13k20;
131 1024 : move32();
132 1024 : Pitch_CT_fx = GENERIC;
133 1024 : move16();
134 : }
135 : }
136 11717 : L_subfr_fx = mult_r( st_fx->L_frame, div_s( 1, nb_subfr_fx ) ); /* TV2Opt : this could be less complex with 2 ifs*/
137 :
138 :
139 11717 : gain_code_fx = 0;
140 11717 : move16();
141 11717 : pitch_limit_flag = 1;
142 11717 : move16(); /* always extended pitch Q range */
143 11717 : test();
144 11717 : test();
145 11717 : test();
146 11717 : test();
147 11717 : test();
148 11717 : test();
149 11717 : IF( ( ( GE_32( st_fx->core_brate, MIN_RATE_FCB ) || ( EQ_16( st_fx->GSC_noisy_speech, 1 ) && ( ( EQ_16( st_fx->L_frame, L_FRAME ) && GE_32( st_fx->core_brate, ACELP_13k20 ) ) || ( EQ_16( st_fx->L_frame, L_FRAME16k ) && GE_32( st_fx->core_brate, GSC_H_RATE_STG ) ) || st_fx->GSC_IVAS_mode == 0 ) ) ) && EQ_16( L_subfr_fx, L_SUBFR ) ) )
150 : {
151 695 : use_fcb = 1;
152 695 : move16();
153 : }
154 11022 : ELSE IF( ( st_fx->GSC_IVAS_mode > 0 ) && EQ_16( L_subfr_fx, 2 * L_SUBFR ) && LT_16( st_fx->GSC_IVAS_mode, 3 ) )
155 : {
156 1822 : use_fcb = 2;
157 1822 : st_fx->acelp_cfg.fcb_mode = 1;
158 1822 : move16();
159 1822 : move16();
160 1822 : set16_fx( st_fx->acelp_cfg.gains_mode, 6, 4 );
161 1822 : set16_fx( st_fx->acelp_cfg.pitch_bits, 9, 4 );
162 1822 : set16_fx( st_fx->acelp_cfg.fixed_cdk_index, 14, 5 );
163 : }
164 :
165 : /*------------------------------------------------------------------*
166 : * ACELP subframe loop
167 : *------------------------------------------------------------------*/
168 :
169 11717 : p_Aq_fx = Aq_fx; /* pointer to interpolated LPC parameters */
170 11717 : pt_pitch_fx = pitch_buf_fx; /* pointer to the pitch buffer */
171 11717 : pt_gain = gain_buf; /* pointer to the gain buffer */
172 :
173 35026 : FOR( i_subfr_fx = 0; i_subfr_fx < st_fx->L_frame; i_subfr_fx += L_subfr_fx )
174 : {
175 : /*----------------------------------------------------------------------*
176 : * Decode pitch lag
177 : *----------------------------------------------------------------------*/
178 :
179 23309 : *pt_pitch_fx = pit_decode_fx( st_fx, Pitch_BR_fx, 0, st_fx->L_frame, i_subfr_fx, Pitch_CT_fx, &pitch_limit_flag, &T0_fx, &T0_frac_fx, &T0_min_fx, &T0_max_fx, L_subfr_fx, tdm_Pitch_reuse_flag, tdm_Pri_pitch_buf );
180 23309 : move16();
181 :
182 : /*--------------------------------------------------------------*
183 : * Find the adaptive codebook vector.
184 : *--------------------------------------------------------------*/
185 23309 : IF( st_fx->element_mode != EVS_MONO )
186 : {
187 23297 : pred_lt4_ivas_fx( &exc_fx[i_subfr_fx], &exc_fx[i_subfr_fx], T0_fx, T0_frac_fx, L_subfr_fx + 1, L_pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP );
188 : }
189 : ELSE
190 : {
191 12 : pred_lt4( &exc_fx[i_subfr_fx], &exc_fx[i_subfr_fx], T0_fx, T0_frac_fx, L_subfr_fx + 1, pitch_inter4_2, L_INTERPOL2, PIT_UP_SAMP );
192 : }
193 :
194 : /*--------------------------------------------------------------*
195 : * Innovation decoding
196 : *--------------------------------------------------------------*/
197 :
198 23309 : IF( EQ_16( use_fcb, 1 ) )
199 : {
200 2780 : inov_decode_fx( st_fx, Local_BR_fx, 0, st_fx->L_frame, 1, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_subfr_fx );
201 :
202 : /*--------------------------------------------------------------*
203 : * Gain decoding
204 : * Estimate spectrum tilt and voicing
205 : *--------------------------------------------------------------*/
206 :
207 2780 : gain_dec_mless_fx( st_fx, st_fx->L_frame, LOCAL_CT, i_subfr_fx, -1, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx );
208 :
209 2780 : st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0, L_subfr_fx, 0 );
210 2780 : move16();
211 : }
212 20529 : ELSE IF( EQ_16( use_fcb, 2 ) ) /* IVAS only */
213 : {
214 : /*inov_decode_fx(st_fx, Local_BR_fx, 0, st_fx->L_frame, 1, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_subfr_fx);*/
215 3644 : inov_decode_fx( st_fx, st_fx->core_brate, 0, st_fx->L_frame, 0, i_subfr_fx, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_subfr_fx );
216 :
217 : /*--------------------------------------------------------------*
218 : * Gain decoding
219 : * Estimate spectrum tilt and voicing
220 : *--------------------------------------------------------------*/
221 :
222 3644 : gain_dec_lbr_fx( st_fx, GENERIC, i_subfr_fx, code_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx, gc_mem, gp_mem, L_subfr_fx );
223 :
224 3644 : st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr_fx, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, 0, L_subfr_fx, 0 );
225 3644 : move16();
226 : }
227 : ELSE
228 : {
229 16885 : nbits = 5;
230 16885 : move16();
231 16885 : if ( LT_32( st_fx->core_brate, MIN_RATE_FCB ) )
232 : {
233 16570 : nbits = 4;
234 16570 : move16();
235 : }
236 :
237 16885 : set16_fx( code_fx, 0, L_SUBFR );
238 16885 : gain_code_fx = L_deposit_l( 0 );
239 16885 : st_fx->tilt_code_fx = 0;
240 16885 : move16();
241 16885 : pit_idx_fx = (Word16) get_next_indice_fx( st_fx, nbits );
242 16885 : move16();
243 :
244 16885 : gain_pit_fx = add( 9590, dic_gp_fx[pit_idx_fx] ); /*Q14 0.5853 in Q14 9590*/
245 :
246 16885 : if ( st_fx->BER_detect ) /* Bitstream is corrupted, use the past pitch gain */
247 : {
248 0 : gain_pit_fx = st_fx->lp_gainp_fx;
249 0 : move16();
250 : }
251 16885 : gain_code_fx = L_mult0( s_max( sub( 32767, shl_o( gain_pit_fx, 1, &Overflow ) ), 16384 /*0.5.Q15*/ ), st_fx->lp_gainc_fx ); /* Use gain pitch and past gain code as an indicator to help finding the best scaling value. gain_code_fx used a temp var*/
252 : }
253 :
254 : /*----------------------------------------------------------------------*
255 : * Find the total excitation
256 : *----------------------------------------------------------------------*/
257 23309 : Rescale_exc( hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr_fx], &bwe_exc_fx[( i_subfr_fx * ( 2 * HIBND_ACB_L_FAC ) ) / 2], hGSCDec->last_exc_dct_in_fx,
258 23309 : L_subfr_fx, shr( imult1616( L_subfr_fx, 2 * HIBND_ACB_L_FAC ), 1 ), gain_code_fx, &( st_fx->Q_exc ), st_fx->Q_subfr, NULL, i_subfr_fx, coder_type );
259 :
260 23309 : gain_code16 = round_fx( L_shl( gain_code_fx, st_fx->Q_exc ) ); /*Q_exc*/
261 :
262 23309 : IF( NE_16( use_fcb, 0 ) )
263 : {
264 650776 : FOR( i = 0; i < L_subfr_fx; i++ )
265 : {
266 644352 : L_tmp = L_shl_sat( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); /*Q16+Q_exc*/
267 644352 : L_tmp = L_add_sat( L_tmp, L_shl_sat( L_mult( gain_code16, code_fx[i] ), 6 ) ); /*Q16+Q_exc*/
268 644352 : exc_fx[i + i_subfr_fx] = round_fx_sat( L_tmp ); /*Q_exc*/
269 644352 : move16();
270 644352 : move16();
271 : }
272 : }
273 : ELSE
274 : {
275 16885 : IF( norm_s( s_or( gain_pit_fx, 1 ) ) == 0 )
276 : {
277 257225 : FOR( i = 0; i < L_subfr_fx; i++ )
278 : {
279 254336 : L_tmp = L_shl( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); /*Q16+Q_exc*/
280 254336 : exc_fx[i + i_subfr_fx] = round_fx( L_tmp ); /*Q_exc*/
281 254336 : move16();
282 : }
283 : }
284 : ELSE
285 : {
286 13996 : gain_pitx2 = shl( gain_pit_fx, 1 ); /*Q15*/
287 :
288 2180396 : FOR( i = 0; i < L_subfr_fx; i++ )
289 : {
290 2166400 : L_tmp = L_mult( gain_pitx2, exc_fx[i + i_subfr_fx] ); /*Q16+Q_exc*/
291 2166400 : exc_fx[i + i_subfr_fx] = round_fx( L_tmp ); /*Q_exc*/
292 2166400 : move16();
293 : }
294 : }
295 : }
296 :
297 23309 : IF( EQ_16( L_subfr_fx, L_FRAME16k ) )
298 : {
299 : /* update gains for FEC - equivalent to lp_gain_updt() */
300 1024 : st_fx->lp_gainp_fx = gain_pit_fx;
301 1024 : move16();
302 1024 : st_fx->lp_gainc_fx = 0;
303 1024 : move32();
304 :
305 1024 : pt_pitch_fx++;
306 1024 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
307 1024 : pt_pitch_fx++;
308 1024 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
309 1024 : pt_pitch_fx++;
310 1024 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
311 1024 : pt_pitch_fx++;
312 1024 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
313 1024 : pt_pitch_fx++;
314 1024 : move16();
315 1024 : move16();
316 1024 : move16();
317 1024 : move16();
318 1024 : p_Aq_fx += 5 * ( M + 1 );
319 : }
320 22285 : ELSE IF( EQ_16( L_subfr_fx, L_FRAME16k / 2 ) )
321 : {
322 0 : IF( i_subfr_fx == 0 )
323 : {
324 0 : pt_pitch_fx++;
325 0 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
326 0 : pt_pitch_fx++;
327 0 : p_Aq_fx += 2 * ( M + 1 );
328 0 : move16();
329 :
330 : /* update gains for FEC - equivalent to lp_gain_updt() */
331 0 : st_fx->lp_gainp_fx = extract_h( L_mult( 6554, gain_pit_fx ) ); /*Q14 (3/15 in Q15 9830)*/
332 0 : st_fx->lp_gainc_fx = 0;
333 0 : move16();
334 0 : move16();
335 : }
336 : ELSE
337 : {
338 0 : pt_pitch_fx++;
339 0 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
340 0 : pt_pitch_fx++;
341 0 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
342 0 : pt_pitch_fx++;
343 0 : p_Aq_fx += 3 * ( M + 1 );
344 0 : move16();
345 0 : move16();
346 :
347 : /* update gains for FEC - equivalent to lp_gain_updt() */
348 0 : st_fx->lp_gainp_fx = extract_h( L_mult( 26214, gain_pit_fx ) ); /*Q14 (12/15 in Q15 9830)*/
349 0 : st_fx->lp_gainc_fx = 0;
350 0 : move16();
351 0 : move16();
352 : }
353 : }
354 22285 : ELSE IF( EQ_16( L_subfr_fx, 128 ) ) /*2*L_SUBFR*/
355 : {
356 5178 : p_Aq_fx += 2 * ( M + 1 );
357 5178 : move16();
358 5178 : pt_pitch_fx++;
359 5178 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
360 5178 : move16();
361 5178 : pt_pitch_fx++;
362 5178 : *pt_gain = gain_pit_fx;
363 5178 : move16();
364 5178 : pt_gain++;
365 5178 : *pt_gain = *( pt_gain - 1 );
366 5178 : move16();
367 5178 : pt_gain++;
368 5178 : IF( i_subfr_fx == 0 )
369 : {
370 : /* update gains for FEC - equivalent to lp_gain_updt() */
371 2589 : st_fx->lp_gainp_fx = extract_h( L_mult( 9830, gain_pit_fx ) ); /*Q14 (3/10 in Q15 9830)*/
372 2589 : st_fx->lp_gainc_fx = 0;
373 2589 : move16();
374 2589 : move16();
375 : }
376 : ELSE
377 : {
378 : /* update gains for FEC - equivalent to lp_gain_updt() */
379 2589 : st_fx->lp_gainp_fx = extract_h( L_mult( 22938, gain_pit_fx ) ); /*Q14 (7/10 in Q15 22938)*/
380 2589 : st_fx->lp_gainc_fx = 0;
381 2589 : move16();
382 2589 : move16();
383 : }
384 : }
385 17107 : ELSE IF( EQ_16( L_subfr_fx, 256 ) ) /*4*L_SUBFR*/
386 : {
387 5103 : pt_pitch_fx++;
388 5103 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
389 5103 : move16();
390 5103 : pt_pitch_fx++;
391 5103 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
392 5103 : move16();
393 5103 : pt_pitch_fx++;
394 5103 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
395 5103 : move16();
396 5103 : pt_pitch_fx++;
397 5103 : *pt_gain = gain_pit_fx;
398 5103 : move16();
399 5103 : pt_gain++;
400 5103 : *pt_gain = *( pt_gain - 1 );
401 5103 : move16();
402 5103 : pt_gain++;
403 5103 : *pt_gain = *( pt_gain - 1 );
404 5103 : move16();
405 5103 : pt_gain++;
406 5103 : *pt_gain = *( pt_gain - 1 );
407 5103 : move16();
408 5103 : pt_gain++;
409 5103 : p_Aq_fx += 4 * ( M + 1 );
410 :
411 : /* update gains for FEC - equivalent to lp_gain_updt() */
412 5103 : st_fx->lp_gainp_fx = gain_pit_fx; // Q14
413 5103 : move16();
414 5103 : st_fx->lp_gainc_fx = 0;
415 5103 : move16();
416 : }
417 : ELSE
418 : {
419 12004 : p_Aq_fx += ( M + 1 );
420 12004 : pt_pitch_fx++;
421 12004 : *pt_gain = gain_pit_fx;
422 12004 : move16();
423 12004 : pt_gain++;
424 :
425 12004 : lp_gain_updt_ivas_fx( i_subfr_fx, gain_pit_fx, 0, &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, st_fx->L_frame );
426 : }
427 : }
428 :
429 11717 : return;
430 : }
|