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 :
186 23309 : 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 );
187 :
188 : /*--------------------------------------------------------------*
189 : * Innovation decoding
190 : *--------------------------------------------------------------*/
191 :
192 23309 : IF( EQ_16( use_fcb, 1 ) )
193 : {
194 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 );
195 :
196 : /*--------------------------------------------------------------*
197 : * Gain decoding
198 : * Estimate spectrum tilt and voicing
199 : *--------------------------------------------------------------*/
200 :
201 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 );
202 :
203 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 );
204 2780 : move16();
205 : }
206 20529 : ELSE IF( EQ_16( use_fcb, 2 ) ) /* IVAS only */
207 : {
208 : /*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);*/
209 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 );
210 :
211 : /*--------------------------------------------------------------*
212 : * Gain decoding
213 : * Estimate spectrum tilt and voicing
214 : *--------------------------------------------------------------*/
215 :
216 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 );
217 :
218 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 );
219 3644 : move16();
220 : }
221 : ELSE
222 : {
223 16885 : nbits = 5;
224 16885 : move16();
225 16885 : if ( LT_32( st_fx->core_brate, MIN_RATE_FCB ) )
226 : {
227 16570 : nbits = 4;
228 16570 : move16();
229 : }
230 :
231 16885 : set16_fx( code_fx, 0, L_SUBFR );
232 16885 : gain_code_fx = L_deposit_l( 0 );
233 16885 : st_fx->tilt_code_fx = 0;
234 16885 : move16();
235 16885 : pit_idx_fx = (Word16) get_next_indice_fx( st_fx, nbits );
236 16885 : move16();
237 :
238 16885 : gain_pit_fx = add( 9590, dic_gp_fx[pit_idx_fx] ); /*Q14 0.5853 in Q14 9590*/
239 :
240 16885 : if ( st_fx->BER_detect ) /* Bitstream is corrupted, use the past pitch gain */
241 : {
242 0 : gain_pit_fx = st_fx->lp_gainp_fx;
243 0 : move16();
244 : }
245 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*/
246 : }
247 :
248 : /*----------------------------------------------------------------------*
249 : * Find the total excitation
250 : *----------------------------------------------------------------------*/
251 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,
252 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 );
253 :
254 23309 : gain_code16 = round_fx( L_shl( gain_code_fx, st_fx->Q_exc ) ); /*Q_exc*/
255 :
256 23309 : IF( NE_16( use_fcb, 0 ) )
257 : {
258 650776 : FOR( i = 0; i < L_subfr_fx; i++ )
259 : {
260 644352 : L_tmp = L_shl_sat( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); /*Q16+Q_exc*/
261 644352 : L_tmp = L_add_sat( L_tmp, L_shl_sat( L_mult( gain_code16, code_fx[i] ), 6 ) ); /*Q16+Q_exc*/
262 644352 : exc_fx[i + i_subfr_fx] = round_fx_sat( L_tmp ); /*Q_exc*/
263 644352 : move16();
264 644352 : move16();
265 : }
266 : }
267 : ELSE
268 : {
269 16885 : IF( norm_s( s_or( gain_pit_fx, 1 ) ) == 0 )
270 : {
271 257225 : FOR( i = 0; i < L_subfr_fx; i++ )
272 : {
273 254336 : L_tmp = L_shl( L_mult( gain_pit_fx, exc_fx[i + i_subfr_fx] ), 1 ); /*Q16+Q_exc*/
274 254336 : exc_fx[i + i_subfr_fx] = round_fx( L_tmp ); /*Q_exc*/
275 254336 : move16();
276 : }
277 : }
278 : ELSE
279 : {
280 13996 : gain_pitx2 = shl( gain_pit_fx, 1 ); /*Q15*/
281 :
282 2180396 : FOR( i = 0; i < L_subfr_fx; i++ )
283 : {
284 2166400 : L_tmp = L_mult( gain_pitx2, exc_fx[i + i_subfr_fx] ); /*Q16+Q_exc*/
285 2166400 : exc_fx[i + i_subfr_fx] = round_fx( L_tmp ); /*Q_exc*/
286 2166400 : move16();
287 : }
288 : }
289 : }
290 :
291 23309 : IF( EQ_16( L_subfr_fx, L_FRAME16k ) )
292 : {
293 : /* update gains for FEC - equivalent to lp_gain_updt() */
294 1024 : st_fx->lp_gainp_fx = gain_pit_fx;
295 1024 : move16();
296 1024 : st_fx->lp_gainc_fx = 0;
297 1024 : move32();
298 :
299 1024 : pt_pitch_fx++;
300 1024 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
301 1024 : pt_pitch_fx++;
302 1024 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
303 1024 : pt_pitch_fx++;
304 1024 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
305 1024 : pt_pitch_fx++;
306 1024 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
307 1024 : pt_pitch_fx++;
308 1024 : move16();
309 1024 : move16();
310 1024 : move16();
311 1024 : move16();
312 1024 : p_Aq_fx += 5 * ( M + 1 );
313 : }
314 22285 : ELSE IF( EQ_16( L_subfr_fx, L_FRAME16k / 2 ) )
315 : {
316 0 : IF( i_subfr_fx == 0 )
317 : {
318 0 : pt_pitch_fx++;
319 0 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
320 0 : pt_pitch_fx++;
321 0 : p_Aq_fx += 2 * ( M + 1 );
322 0 : move16();
323 :
324 : /* update gains for FEC - equivalent to lp_gain_updt() */
325 0 : st_fx->lp_gainp_fx = extract_h( L_mult( 6554, gain_pit_fx ) ); /*Q14 (3/15 in Q15 9830)*/
326 0 : st_fx->lp_gainc_fx = 0;
327 0 : move16();
328 0 : move16();
329 : }
330 : ELSE
331 : {
332 0 : pt_pitch_fx++;
333 0 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
334 0 : pt_pitch_fx++;
335 0 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
336 0 : pt_pitch_fx++;
337 0 : p_Aq_fx += 3 * ( M + 1 );
338 0 : move16();
339 0 : move16();
340 :
341 : /* update gains for FEC - equivalent to lp_gain_updt() */
342 0 : st_fx->lp_gainp_fx = extract_h( L_mult( 26214, gain_pit_fx ) ); /*Q14 (12/15 in Q15 9830)*/
343 0 : st_fx->lp_gainc_fx = 0;
344 0 : move16();
345 0 : move16();
346 : }
347 : }
348 22285 : ELSE IF( EQ_16( L_subfr_fx, 128 ) ) /*2*L_SUBFR*/
349 : {
350 5178 : p_Aq_fx += 2 * ( M + 1 );
351 5178 : move16();
352 5178 : pt_pitch_fx++;
353 5178 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
354 5178 : move16();
355 5178 : pt_pitch_fx++;
356 5178 : *pt_gain = gain_pit_fx;
357 5178 : move16();
358 5178 : pt_gain++;
359 5178 : *pt_gain = *( pt_gain - 1 );
360 5178 : move16();
361 5178 : pt_gain++;
362 5178 : IF( i_subfr_fx == 0 )
363 : {
364 : /* update gains for FEC - equivalent to lp_gain_updt() */
365 2589 : st_fx->lp_gainp_fx = extract_h( L_mult( 9830, gain_pit_fx ) ); /*Q14 (3/10 in Q15 9830)*/
366 2589 : st_fx->lp_gainc_fx = 0;
367 2589 : move16();
368 2589 : move16();
369 : }
370 : ELSE
371 : {
372 : /* update gains for FEC - equivalent to lp_gain_updt() */
373 2589 : st_fx->lp_gainp_fx = extract_h( L_mult( 22938, gain_pit_fx ) ); /*Q14 (7/10 in Q15 22938)*/
374 2589 : st_fx->lp_gainc_fx = 0;
375 2589 : move16();
376 2589 : move16();
377 : }
378 : }
379 17107 : ELSE IF( EQ_16( L_subfr_fx, 256 ) ) /*4*L_SUBFR*/
380 : {
381 5103 : pt_pitch_fx++;
382 5103 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
383 5103 : move16();
384 5103 : pt_pitch_fx++;
385 5103 : *pt_pitch_fx = *( pt_pitch_fx - 1 );
386 5103 : move16();
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_gain = gain_pit_fx;
392 5103 : move16();
393 5103 : pt_gain++;
394 5103 : *pt_gain = *( pt_gain - 1 );
395 5103 : move16();
396 5103 : pt_gain++;
397 5103 : *pt_gain = *( pt_gain - 1 );
398 5103 : move16();
399 5103 : pt_gain++;
400 5103 : *pt_gain = *( pt_gain - 1 );
401 5103 : move16();
402 5103 : pt_gain++;
403 5103 : p_Aq_fx += 4 * ( M + 1 );
404 :
405 : /* update gains for FEC - equivalent to lp_gain_updt() */
406 5103 : st_fx->lp_gainp_fx = gain_pit_fx; // Q14
407 5103 : move16();
408 5103 : st_fx->lp_gainc_fx = 0;
409 5103 : move16();
410 : }
411 : ELSE
412 : {
413 12004 : p_Aq_fx += ( M + 1 );
414 12004 : pt_pitch_fx++;
415 12004 : *pt_gain = gain_pit_fx;
416 12004 : move16();
417 12004 : pt_gain++;
418 :
419 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 );
420 : }
421 : }
422 :
423 11717 : return;
424 : }
|