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 11429 : 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 11429 : gain_pit_fx = 0;
67 11429 : move16();
68 11429 : hGSCDec = st_fx->hGSCDec;
69 :
70 : MUSIC_POSTFILT_HANDLE hMusicPF;
71 11429 : 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 :
77 11429 : use_fcb = 0;
78 11429 : move16();
79 11429 : test();
80 11429 : test();
81 11429 : 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 ) ) )
82 : {
83 86 : Local_BR_fx = ACELP_8k00;
84 86 : Pitch_CT_fx = GENERIC;
85 86 : Pitch_BR_fx = ACELP_8k00;
86 86 : move32();
87 86 : move32();
88 86 : move16();
89 86 : IF( EQ_16( st_fx->L_frame, L_FRAME16k ) )
90 : {
91 0 : Local_BR_fx = ACELP_14k80;
92 0 : move32();
93 0 : if ( st_fx->GSC_IVAS_mode > 0 )
94 : {
95 0 : Local_BR_fx = ACELP_9k60;
96 0 : move32();
97 : }
98 0 : Pitch_BR_fx = st_fx->core_brate;
99 0 : move32();
100 : }
101 : }
102 11343 : ELSE IF( EQ_16( st_fx->GSC_noisy_speech, 1 ) )
103 : {
104 682 : Local_BR_fx = ACELP_7k20;
105 682 : move32();
106 682 : Pitch_CT_fx = GENERIC;
107 682 : move16();
108 682 : Pitch_BR_fx = ACELP_7k20;
109 682 : move32();
110 682 : if ( EQ_16( st_fx->L_frame, L_FRAME16k ) )
111 : {
112 0 : Pitch_BR_fx = st_fx->core_brate;
113 0 : move32();
114 : }
115 : }
116 : ELSE
117 : {
118 10661 : Local_BR_fx = ACELP_7k20;
119 10661 : move32();
120 10661 : Pitch_CT_fx = AUDIO;
121 10661 : move16();
122 10661 : Pitch_BR_fx = st_fx->core_brate;
123 10661 : move32();
124 10661 : IF( EQ_16( st_fx->L_frame, L_FRAME16k ) )
125 : {
126 1043 : Pitch_BR_fx = ACELP_13k20;
127 1043 : move32();
128 1043 : Pitch_CT_fx = GENERIC;
129 1043 : move16();
130 : }
131 : }
132 11429 : L_subfr_fx = mult_r( st_fx->L_frame, div_s( 1, nb_subfr_fx ) ); /* TV2Opt : this could be less complex with 2 ifs*/
133 :
134 :
135 11429 : gain_code_fx = 0;
136 11429 : move16();
137 11429 : pitch_limit_flag = 1;
138 11429 : move16(); /* always extended pitch Q range */
139 11429 : test();
140 11429 : test();
141 11429 : test();
142 11429 : test();
143 11429 : test();
144 11429 : test();
145 11429 : 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 ) ) )
146 : {
147 682 : use_fcb = 1;
148 682 : move16();
149 : }
150 10747 : ELSE IF( ( st_fx->GSC_IVAS_mode > 0 ) && EQ_16( L_subfr_fx, 2 * L_SUBFR ) && LT_16( st_fx->GSC_IVAS_mode, 3 ) )
151 : {
152 1683 : use_fcb = 2;
153 1683 : st_fx->acelp_cfg.fcb_mode = 1;
154 1683 : move16();
155 1683 : move16();
156 1683 : set16_fx( st_fx->acelp_cfg.gains_mode, 6, 4 );
157 1683 : set16_fx( st_fx->acelp_cfg.pitch_bits, 9, 4 );
158 1683 : set16_fx( st_fx->acelp_cfg.fixed_cdk_index, 14, 5 );
159 : }
160 :
161 : /*------------------------------------------------------------------*
162 : * ACELP subframe loop
163 : *------------------------------------------------------------------*/
164 :
165 11429 : p_Aq_fx = Aq_fx; /* pointer to interpolated LPC parameters */
166 11429 : pt_pitch_fx = pitch_buf_fx; /* pointer to the pitch buffer */
167 11429 : pt_gain = gain_buf; /* pointer to the gain buffer */
168 :
169 33909 : FOR( i_subfr_fx = 0; i_subfr_fx < st_fx->L_frame; i_subfr_fx += L_subfr_fx )
170 : {
171 : /*----------------------------------------------------------------------*
172 : * Decode pitch lag
173 : *----------------------------------------------------------------------*/
174 :
175 22480 : *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 );
176 22480 : move16();
177 :
178 : /*--------------------------------------------------------------*
179 : * Find the adaptive codebook vector.
180 : *--------------------------------------------------------------*/
181 22480 : IF( st_fx->element_mode != EVS_MONO )
182 : {
183 22464 : 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 );
184 : }
185 : ELSE
186 : {
187 16 : 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 );
188 : }
189 :
190 : /*--------------------------------------------------------------*
191 : * Innovation decoding
192 : *--------------------------------------------------------------*/
193 :
194 22480 : IF( EQ_16( use_fcb, 1 ) )
195 : {
196 2728 : 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 );
197 :
198 : /*--------------------------------------------------------------*
199 : * Gain decoding
200 : * Estimate spectrum tilt and voicing
201 : *--------------------------------------------------------------*/
202 :
203 2728 : 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 );
204 :
205 2728 : 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 );
206 2728 : move16();
207 : }
208 19752 : ELSE IF( EQ_16( use_fcb, 2 ) ) /* IVAS only */
209 : {
210 : /*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);*/
211 3366 : 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 );
212 :
213 : /*--------------------------------------------------------------*
214 : * Gain decoding
215 : * Estimate spectrum tilt and voicing
216 : *--------------------------------------------------------------*/
217 :
218 3366 : 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 );
219 :
220 3366 : 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 );
221 3366 : move16();
222 : }
223 : ELSE
224 : {
225 16386 : nbits = 5;
226 16386 : move16();
227 16386 : if ( LT_32( st_fx->core_brate, MIN_RATE_FCB ) )
228 : {
229 16060 : nbits = 4;
230 16060 : move16();
231 : }
232 :
233 16386 : set16_fx( code_fx, 0, L_SUBFR );
234 16386 : gain_code_fx = L_deposit_l( 0 );
235 16386 : st_fx->tilt_code_fx = 0;
236 16386 : move16();
237 16386 : pit_idx_fx = (Word16) get_next_indice_fx( st_fx, nbits );
238 16386 : move16();
239 :
240 16386 : gain_pit_fx = add( 9590, dic_gp_fx[pit_idx_fx] ); /*Q14 0.5853 in Q14 9590*/
241 :
242 16386 : if ( st_fx->BER_detect ) /* Bitstream is corrupted, use the past pitch gain */
243 : {
244 0 : gain_pit_fx = st_fx->lp_gainp_fx;
245 0 : move16();
246 : }
247 16386 : gain_code_fx = L_mult0( s_max( sub( 32767, shl_sat( gain_pit_fx, 1 ) ), 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*/
248 : }
249 :
250 : /*----------------------------------------------------------------------*
251 : * Find the total excitation
252 : *----------------------------------------------------------------------*/
253 22480 : 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,
254 22480 : 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 );
255 :
256 22480 : gain_code16 = round_fx( L_shl( gain_code_fx, st_fx->Q_exc ) ); /*Q_exc*/
257 :
258 22480 : IF( NE_16( use_fcb, 0 ) )
259 : {
260 611534 : FOR( i = 0; i < L_subfr_fx; i++ )
261 : {
262 605440 : L_tmp = L_shl_sat( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); /*Q16+Q_exc*/
263 605440 : L_tmp = L_add_sat( L_tmp, L_shl_sat( L_mult( gain_code16, code_fx[i] ), 6 ) ); /*Q16+Q_exc*/
264 605440 : exc_fx[i + i_subfr_fx] = round_fx_sat( L_tmp ); /*Q_exc*/
265 605440 : move16();
266 605440 : move16();
267 : }
268 : }
269 : ELSE
270 : {
271 16386 : IF( norm_s( s_or( gain_pit_fx, 1 ) ) == 0 )
272 : {
273 234047 : FOR( i = 0; i < L_subfr_fx; i++ )
274 : {
275 231488 : L_tmp = L_shl( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); /*Q16+Q_exc*/
276 231488 : exc_fx[i + i_subfr_fx] = round_fx( L_tmp ); /*Q_exc*/
277 231488 : move16();
278 : }
279 : }
280 : ELSE
281 : {
282 13827 : gain_pitx2 = shl( gain_pit_fx, 1 ); /*Q15*/
283 :
284 2169475 : FOR( i = 0; i < L_subfr_fx; i++ )
285 : {
286 2155648 : L_tmp = L_mult( gain_pitx2, exc_fx[i + i_subfr_fx] ); /*Q16+Q_exc*/
287 2155648 : exc_fx[i + i_subfr_fx] = round_fx( L_tmp ); /*Q_exc*/
288 2155648 : move16();
289 : }
290 : }
291 : }
292 :
293 22480 : IF( EQ_16( L_subfr_fx, L_FRAME16k ) )
294 : {
295 : /* update gains for FEC - equivalent to lp_gain_updt() */
296 1043 : st_fx->lp_gainp_fx = gain_pit_fx;
297 1043 : move16();
298 1043 : st_fx->lp_gainc_fx = 0;
299 1043 : move32();
300 :
301 1043 : pt_pitch_fx++;
302 1043 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
303 1043 : pt_pitch_fx++;
304 1043 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
305 1043 : pt_pitch_fx++;
306 1043 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
307 1043 : pt_pitch_fx++;
308 1043 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
309 1043 : pt_pitch_fx++;
310 1043 : move16();
311 1043 : move16();
312 1043 : move16();
313 1043 : move16();
314 1043 : p_Aq_fx += 5 * ( M + 1 );
315 : }
316 21437 : ELSE IF( EQ_16( L_subfr_fx, L_FRAME16k / 2 ) )
317 : {
318 0 : IF( i_subfr_fx == 0 )
319 : {
320 0 : pt_pitch_fx++;
321 0 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
322 0 : pt_pitch_fx++;
323 0 : p_Aq_fx += 2 * ( M + 1 );
324 0 : move16();
325 :
326 : /* update gains for FEC - equivalent to lp_gain_updt() */
327 0 : st_fx->lp_gainp_fx = extract_h( L_mult( 6554, gain_pit_fx ) ); /*Q14 (3/15 in Q15 9830)*/
328 0 : st_fx->lp_gainc_fx = 0;
329 0 : move16();
330 0 : move16();
331 : }
332 : ELSE
333 : {
334 0 : pt_pitch_fx++;
335 0 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
336 0 : pt_pitch_fx++;
337 0 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
338 0 : pt_pitch_fx++;
339 0 : p_Aq_fx += 3 * ( M + 1 );
340 0 : move16();
341 0 : move16();
342 :
343 : /* update gains for FEC - equivalent to lp_gain_updt() */
344 0 : st_fx->lp_gainp_fx = extract_h( L_mult( 26214, gain_pit_fx ) ); /*Q14 (12/15 in Q15 9830)*/
345 0 : st_fx->lp_gainc_fx = 0;
346 0 : move16();
347 0 : move16();
348 : }
349 : }
350 21437 : ELSE IF( EQ_16( L_subfr_fx, 128 ) ) /*2*L_SUBFR*/
351 : {
352 4786 : p_Aq_fx += 2 * ( M + 1 );
353 4786 : move16();
354 4786 : pt_pitch_fx++;
355 4786 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
356 4786 : move16();
357 4786 : pt_pitch_fx++;
358 4786 : *pt_gain = gain_pit_fx;
359 4786 : move16();
360 4786 : pt_gain++;
361 4786 : *pt_gain = *( pt_gain - 1 );
362 4786 : move16();
363 4786 : pt_gain++;
364 4786 : IF( i_subfr_fx == 0 )
365 : {
366 : /* update gains for FEC - equivalent to lp_gain_updt() */
367 2393 : st_fx->lp_gainp_fx = extract_h( L_mult( 9830, gain_pit_fx ) ); /*Q14 (3/10 in Q15 9830)*/
368 2393 : st_fx->lp_gainc_fx = 0;
369 2393 : move16();
370 2393 : move16();
371 : }
372 : ELSE
373 : {
374 : /* update gains for FEC - equivalent to lp_gain_updt() */
375 2393 : st_fx->lp_gainp_fx = extract_h( L_mult( 22938, gain_pit_fx ) ); /*Q14 (7/10 in Q15 22938)*/
376 2393 : st_fx->lp_gainc_fx = 0;
377 2393 : move16();
378 2393 : move16();
379 : }
380 : }
381 16651 : ELSE IF( EQ_16( L_subfr_fx, 256 ) ) /*4*L_SUBFR*/
382 : {
383 5107 : pt_pitch_fx++;
384 5107 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
385 5107 : move16();
386 5107 : pt_pitch_fx++;
387 5107 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
388 5107 : move16();
389 5107 : pt_pitch_fx++;
390 5107 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
391 5107 : move16();
392 5107 : pt_pitch_fx++;
393 5107 : *pt_gain = gain_pit_fx;
394 5107 : move16();
395 5107 : pt_gain++;
396 5107 : *pt_gain = *( pt_gain - 1 );
397 5107 : move16();
398 5107 : pt_gain++;
399 5107 : *pt_gain = *( pt_gain - 1 );
400 5107 : move16();
401 5107 : pt_gain++;
402 5107 : *pt_gain = *( pt_gain - 1 );
403 5107 : move16();
404 5107 : pt_gain++;
405 5107 : p_Aq_fx += 4 * ( M + 1 );
406 :
407 : /* update gains for FEC - equivalent to lp_gain_updt() */
408 5107 : st_fx->lp_gainp_fx = gain_pit_fx; // Q14
409 5107 : move16();
410 5107 : st_fx->lp_gainc_fx = 0;
411 5107 : move16();
412 : }
413 : ELSE
414 : {
415 11544 : p_Aq_fx += ( M + 1 );
416 11544 : pt_pitch_fx++;
417 11544 : *pt_gain = gain_pit_fx;
418 11544 : move16();
419 11544 : pt_gain++;
420 :
421 11544 : 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 );
422 : }
423 : }
424 :
425 11429 : return;
426 : }
|