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 "prot_fx.h" /* Function prototypes */
8 :
9 : #define Q3_4 ( 4 << Q3 )
10 : #define Q3_17 ( 17 << Q3 )
11 : #define Q16_8 ( 8 << Q16 )
12 : #define Q16_30 ( 30 << Q16 )
13 :
14 : /*======================================================================*/
15 : /* FUNCTION : decod_tran_fx() */
16 : /*----------------------------------------------------------------------*/
17 : /* PURPOSE : Decode transition (TC) frames */
18 : /* */
19 : /*----------------------------------------------------------------------*/
20 : /* GLOBAL INPUT ARGUMENTS : */
21 : /* _ (Struct) st_fx : decoder static memory */
22 : /* _ (Word16) L_frame_fx : length of the frame Q0 */
23 : /* _ (Word16[]) Aq_fx : LP filter coefficient Q12 */
24 : /* _ (Word16) coder_type : coding type Q12 */
25 : /* _ (Word16) Es_pred_fx : predicted scaled innov. energy Q8 */
26 : /* _ (Word16[]) pitch_buf_fx : floating pitch values for each subframe Q6*/
27 : /* _ (Word16[]) voice_factors_fx: frame error rate Q15 */
28 : /*-----------------------------------------------------------------------*/
29 : /* OUTPUT ARGUMENTS : */
30 : /* _ (Word16[]) exc_fx : adapt. excitation exc (Q_exc) */
31 : /* _ (Word16[]) exc2_fx : adapt. excitation/total exc (Q_exc) */
32 : /*-----------------------------------------------------------------------*/
33 :
34 :
35 : /*-----------------------------------------------------------------------*/
36 : /* RETURN ARGUMENTS : */
37 : /* _ None */
38 : /*=======================================================================*/
39 :
40 13057 : void decod_tran_fx(
41 : Decoder_State *st_fx, /* i/o: decoder static memory */
42 : const Word16 L_frame_fx, /* i : length of the frame */
43 : const Word16 tc_subfr_fx, /* i : TC subframe index */
44 : const Word16 *Aq_fx, /* i : LP filter coefficient */
45 : const Word16 Es_pred_fx, /* i : predicted scaled innov. energy */
46 : Word16 *pitch_buf_fx, /* o : floating pitch values for each subframe*/
47 : Word16 *voice_factors_fx, /* o : voicing factors */
48 : Word16 *exc_fx, /* i/o: adapt. excitation exc */
49 : Word16 *exc2_fx, /* i/o: adapt. excitation/total exc */
50 : Word16 *bwe_exc_fx, /* i/o: excitation for SWB TBE */
51 : Word16 *unbits, /* i/o: number of unused bits */
52 : const Word16 sharpFlag, /* i : formant sharpening flag */
53 : Word16 *gain_buf /* o : floating pitch gain for each subframe */
54 : )
55 : {
56 : Word16 T0, T0_frac, T0_min, T0_max; /* integer pitch variables */
57 : Word32 gain_code_fx; /* Quantized algebraic codeebook gain */
58 : Word32 norm_gain_code_fx; /* normalized algebraic codeebook gain */
59 : Word16 gain_pit_fx; /* Quantized pitch gain */
60 : Word16 voice_fac_fx; /* Voicing factor */
61 : Word16 gain_inov_fx; /* inovation gain */
62 : Word16 code_fx[L_SUBFR]; /* algebraic codevector */
63 : const Word16 *p_Aq_fx; /* pointer to lp filter coefficient */
64 : Word16 *pt_pitch_fx; /* pointer to floating pitch */
65 : Word16 i_subfr, i; /* tmp variables */
66 : Word16 position; /* TC related flag */
67 : Word16 gain_preQ_fx; /* Gain of prequantizer excitation */
68 : Word16 code_preQ_fx[L_SUBFR]; /* Prequantizer excitation */
69 : Word16 Jopt_flag; /* flag indicating zero adaptive contribtuion */
70 : Word32 norm_gain_preQ_fx;
71 : Word16 gain_code16;
72 : Word32 L_tmp;
73 : Word16 tmp16, tmp1_fx, tmp_fx;
74 : #ifdef FIX_2010_PREP_TBE_EXC
75 : Word16 Q_code_preQ;
76 : #endif
77 : GSC_DEC_HANDLE hGSCDec;
78 13057 : hGSCDec = st_fx->hGSCDec;
79 : MUSIC_POSTFILT_HANDLE hMusicPF;
80 13057 : hMusicPF = st_fx->hMusicPF;
81 :
82 :
83 13057 : gain_code_fx = 0; /* Quantized algebraic codeebook gain */
84 13057 : move32();
85 13057 : norm_gain_code_fx = 0; /* normalized algebraic codeebook gain Q16 */
86 13057 : move32();
87 13057 : gain_pit_fx = 0; /* Quantized pitch gain Q14 */
88 13057 : move16();
89 13057 : gain_inov_fx = 0; /* inovation gain */
90 13057 : move16();
91 13057 : gain_preQ_fx = 0; /* Gain of prequantizer excitation Q2 */
92 13057 : move16();
93 :
94 13057 : set16_fx( code_preQ_fx, 0, L_SUBFR ); // Q10
95 : /*----------------------------------------------------------------*
96 : * ACELP subframe loop
97 : *----------------------------------------------------------------*/
98 :
99 13057 : p_Aq_fx = Aq_fx; // Q12
100 13057 : pt_pitch_fx = pitch_buf_fx; // Q6
101 13057 : Jopt_flag = 0;
102 13057 : move16();
103 13057 : norm_gain_preQ_fx = 0;
104 13057 : move16();
105 :
106 71690 : FOR( i_subfr = 0; i_subfr < L_frame_fx; i_subfr += L_SUBFR )
107 : {
108 : /*------------------------------------------------------------*
109 : * TC : subframe determination &
110 : * adaptive/glottal part of excitation construction
111 : *------------------------------------------------------------*/
112 :
113 58633 : test();
114 58633 : IF( i_subfr == 0 && GT_16( st_fx->Q_exc, 2 ) )
115 : {
116 7989 : tmp16 = sub( 2, st_fx->Q_exc );
117 7989 : Scale_sig( exc_fx - L_EXC_MEM, L_EXC_MEM, tmp16 ); // Q2
118 7989 : Scale_sig( bwe_exc_fx - PIT16k_MAX * 2, PIT16k_MAX * 2, tmp16 ); // Q2
119 7989 : Scale_sig( hGSCDec->last_exc_dct_in_fx, L_FRAME, tmp16 ); // Q2
120 7989 : st_fx->Q_exc = add( st_fx->Q_exc, tmp16 );
121 7989 : move16();
122 : }
123 :
124 58633 : transition_dec_fx( st_fx, 0, L_frame_fx, i_subfr, tc_subfr_fx, &Jopt_flag, exc_fx,
125 : &T0, &T0_frac, &T0_min, &T0_max, &pt_pitch_fx, &position, bwe_exc_fx, &st_fx->Q_exc );
126 : /*-----------------------------------------------------------------*
127 : * Transform domain contribution decoding - active frames
128 : *-----------------------------------------------------------------*/
129 58633 : IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) )
130 : {
131 5835 : gain_code_fx = 0;
132 5835 : move16();
133 5835 : transf_cdbk_dec_fx( st_fx, 0, i_subfr, Es_pred_fx, gain_code_fx, &gain_preQ_fx, &norm_gain_preQ_fx, code_preQ_fx, unbits );
134 : }
135 :
136 : /*-----------------------------------------------------------------*
137 : * ACELP codebook search + pitch sharpening
138 : *-----------------------------------------------------------------*/
139 :
140 58633 : inov_decode_fx( st_fx, st_fx->core_brate, 0, L_frame_fx, sharpFlag, i_subfr, p_Aq_fx, st_fx->tilt_code_fx, *pt_pitch_fx, code_fx, L_SUBFR );
141 :
142 : /*-----------------------------------------------------------------*
143 : * De-quantize the gains
144 : * Update tilt of code: 0.0 (unvoiced) to 0.5 (voiced)
145 : *-----------------------------------------------------------------*/
146 :
147 58633 : IF( Jopt_flag == 0 )
148 : {
149 : /* 2/3-bit decoding */
150 18191 : IF( st_fx->element_mode == EVS_MONO )
151 : {
152 90 : gain_dec_tc_fx( st_fx, code_fx, i_subfr, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx );
153 : }
154 : ELSE
155 : {
156 18101 : gain_dec_tc_ivas_fx( st_fx, code_fx, i_subfr, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx );
157 : }
158 : }
159 : ELSE
160 : {
161 : /* 5-bit decoding */
162 40442 : IF( GT_32( st_fx->core_brate, ACELP_32k ) )
163 : {
164 2747 : gain_dec_SQ_fx( st_fx, i_subfr, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx );
165 : }
166 : ELSE
167 : {
168 37695 : gain_dec_mless_fx( st_fx, L_frame_fx, st_fx->coder_type, i_subfr, tc_subfr_fx, code_fx, Es_pred_fx, &gain_pit_fx, &gain_code_fx, &gain_inov_fx, &norm_gain_code_fx );
169 : }
170 : }
171 :
172 : /* update LP filtered gains for the case of frame erasures */
173 58633 : IF( st_fx->element_mode == EVS_MONO )
174 : {
175 546 : lp_gain_updt_fx( i_subfr, gain_pit_fx, L_add( norm_gain_code_fx, norm_gain_preQ_fx ), &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_frame_fx );
176 :
177 546 : st_fx->tilt_code_fx = est_tilt_fx( exc_fx + i_subfr, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, st_fx->Q_exc );
178 546 : move16();
179 : }
180 : ELSE
181 : {
182 58087 : lp_gain_updt_ivas_fx( i_subfr, gain_pit_fx, L_add( norm_gain_code_fx, norm_gain_preQ_fx ), &st_fx->lp_gainp_fx, &st_fx->lp_gainc_fx, L_frame_fx );
183 :
184 58087 : st_fx->tilt_code_fx = est_tilt_ivas_fx( exc_fx + i_subfr, gain_pit_fx, code_fx, gain_code_fx, &voice_fac_fx, st_fx->Q_exc, L_SUBFR, 0 );
185 58087 : move16();
186 : }
187 :
188 : /*----------------------------------------------------------------------*
189 : * Find the total excitation
190 : *----------------------------------------------------------------------*/
191 58633 : test();
192 58633 : test();
193 58633 : test();
194 58633 : IF( st_fx->element_mode > EVS_MONO && ( GE_16( add( i_subfr, L_SUBFR ), tc_subfr_fx ) && LT_16( i_subfr, tc_subfr_fx ) && GT_16( st_fx->Q_subfr[0], 4 ) ) )
195 : {
196 4830 : test();
197 4830 : test();
198 4830 : test();
199 4830 : IF( GE_16( st_fx->Q_subfr[0], 7 ) && LE_32( st_fx->lp_gainc_fx, Q3_4 ) && LE_32( norm_gain_code_fx, Q16_8 ) )
200 : {
201 1418 : st_fx->Q_subfr[0] = s_min( st_fx->Q_subfr[0], 4 );
202 1418 : move16();
203 : }
204 3412 : ELSE IF( LE_32( st_fx->lp_gainc_fx, Q3_17 ) && LE_32( L_sub( gain_code_fx, norm_gain_code_fx ), Q16_30 ) )
205 : {
206 2077 : st_fx->Q_subfr[0] = s_min( 4, sub( st_fx->Q_subfr[0], 2 ) );
207 2077 : move16();
208 : }
209 : }
210 58633 : IF( EQ_16( L_frame_fx, L_FRAME ) ) /* Rescaling for 12.8k core */
211 : {
212 26608 : Rescale_exc( hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr], &bwe_exc_fx[( ( i_subfr * 2 * HIBND_ACB_L_FAC ) >> 1 )], hGSCDec->last_exc_dct_in_fx,
213 26608 : L_SUBFR, L_SUBFR * HIBND_ACB_L_FAC, gain_code_fx, &( st_fx->Q_exc ), st_fx->Q_subfr, exc2_fx, i_subfr, st_fx->coder_type );
214 : }
215 : ELSE /* Rescaling for 16k core */
216 : {
217 32025 : Rescale_exc( hMusicPF->dct_post_old_exc_fx, &exc_fx[i_subfr], &bwe_exc_fx[i_subfr * 2], hGSCDec->last_exc_dct_in_fx,
218 32025 : L_SUBFR, L_SUBFR * 2, gain_code_fx, &( st_fx->Q_exc ), st_fx->Q_subfr, exc2_fx, i_subfr, st_fx->coder_type );
219 : }
220 :
221 58633 : gain_code16 = round_fx( L_shl( gain_code_fx, st_fx->Q_exc ) ); /*Q_exc*/
222 58633 : Acelp_dec_total_exc( exc_fx, exc2_fx, gain_code16, gain_pit_fx, i_subfr, code_fx, L_SUBFR );
223 :
224 : /*-----------------------------------------------------------------*
225 : * Add the ACELP pre-quantizer contribution
226 : *-----------------------------------------------------------------*/
227 58633 : IF( GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) )
228 : {
229 5835 : IF( ( st_fx->element_mode == EVS_MONO ) )
230 : {
231 250 : tmp1_fx = add( 15 - Q_AVQ_OUT_DEC - 2, st_fx->Q_exc );
232 : }
233 : ELSE
234 : {
235 5585 : tmp1_fx = add( 15 - Q_AVQ_OUT - 2, st_fx->Q_exc );
236 : }
237 379275 : FOR( i = 0; i < L_SUBFR; i++ )
238 : {
239 373440 : L_tmp = L_mult( gain_preQ_fx, code_preQ_fx[i] ); /* Q2 + Q10 -> Q13*/
240 373440 : L_tmp = L_shl_sat( L_tmp, tmp1_fx ); /* Q16 + Q_exc */
241 373440 : tmp_fx = round_fx_sat( L_tmp );
242 373440 : exc2_fx[i + i_subfr] = add_sat( exc2_fx[i + i_subfr], tmp_fx );
243 373440 : move16();
244 373440 : exc_fx[i + i_subfr] = add_sat( exc_fx[i + i_subfr], tmp_fx );
245 373440 : move16();
246 : }
247 : }
248 :
249 : /*-----------------------------------------------------------------*
250 : * Prepare TBE excitation
251 : *-----------------------------------------------------------------*/
252 : Word16 tmp_idx_2;
253 58633 : tmp_idx_2 = 0;
254 58633 : move16();
255 58633 : if ( i_subfr != 0 )
256 : {
257 45576 : tmp_idx_2 = idiv1616( i_subfr, L_SUBFR );
258 : }
259 :
260 : #ifdef FIX_2010_PREP_TBE_EXC
261 : /*
262 : 2025-09-15 multrus:
263 : TODO:
264 : check with vaillancourt
265 : - where this difference between EVS and IVAS comes from
266 : - where Q_code_preQ could be derived
267 : - whether any of the above calculations need to be adjusted
268 : */
269 58633 : Q_code_preQ = Q6;
270 58633 : move16();
271 58633 : if ( EQ_16( st_fx->element_mode, EVS_MONO ) )
272 : {
273 546 : Q_code_preQ = Q10;
274 546 : move16();
275 : }
276 :
277 58633 : prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx,
278 58633 : &voice_factors_fx[tmp_idx_2], bwe_exc_fx, gain_preQ_fx, code_preQ_fx, Q_code_preQ,
279 58633 : st_fx->Q_exc, T0, T0_frac, st_fx->coder_type, st_fx->core_brate,
280 58633 : st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag );
281 : #else
282 : prep_tbe_exc_fx( L_frame_fx, L_SUBFR, i_subfr, gain_pit_fx, gain_code_fx, code_fx, voice_fac_fx,
283 : &voice_factors_fx[tmp_idx_2], bwe_exc_fx, gain_preQ_fx, code_preQ_fx,
284 : st_fx->Q_exc, T0, T0_frac, st_fx->coder_type, st_fx->core_brate,
285 : st_fx->element_mode, st_fx->idchan, st_fx->hBWE_TD != NULL, st_fx->tdm_LRTD_flag );
286 : #endif
287 :
288 : /*----------------------------------------------------------------*
289 : * Excitation enhancements (update of total excitation signal)
290 : *----------------------------------------------------------------*/
291 :
292 58633 : IF( GT_32( st_fx->core_brate, ACELP_32k ) )
293 : {
294 4010 : Copy( exc_fx + i_subfr, exc2_fx + i_subfr, L_SUBFR );
295 : }
296 : ELSE
297 : {
298 54623 : enhancer_fx( st_fx->core_brate, 0, st_fx->coder_type, i_subfr, L_frame_fx, voice_fac_fx, st_fx->stab_fac_fx,
299 54623 : norm_gain_code_fx, gain_inov_fx, &st_fx->gc_threshold_fx, code_fx, exc2_fx, gain_pit_fx, &( st_fx->dm_fx ), st_fx->Q_exc );
300 : }
301 :
302 : Word16 tmp_idx;
303 58633 : tmp_idx = 0;
304 58633 : move16();
305 58633 : if ( i_subfr != 0 )
306 : {
307 45576 : tmp_idx = idiv1616( i_subfr, L_SUBFR );
308 : }
309 58633 : p_Aq_fx += ( M + 1 );
310 58633 : pt_pitch_fx++;
311 58633 : st_fx->tilt_code_dec_fx[tmp_idx] = st_fx->tilt_code_fx; // Q15
312 58633 : move16();
313 58633 : gain_buf[tmp_idx] = gain_pit_fx; // Q14
314 58633 : move16();
315 : }
316 :
317 : /* SC-VBR */
318 13057 : st_fx->prev_gain_pit_dec_fx = gain_pit_fx;
319 13057 : move16(); /*Q14*/
320 :
321 13057 : return;
322 : }
|