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"
7 : #include "prot_fx.h"
8 : #include "rom_com.h"
9 : #include "log2.h"
10 :
11 : /*===================================================================*/
12 : /* FUNCTION : void ppp_voiced_decoder_fx () */
13 : /*-------------------------------------------------------------------*/
14 : /* PURPOSE : */
15 : /*-------------------------------------------------------------------*/
16 : /* INPUT ARGUMENTS : */
17 : /* _ Word16 bfi_fx - Q0 bad frame indicator */
18 : /* _ const Word16 *lpc2_fx - Q12 current frame LPC */
19 : /* _ Word16 *exc_fx - Q0 previous frame excitation */
20 : /*-------------------------------------------------------------------*/
21 : /* OUTPUT ARGUMENTS : */
22 : /* _ Decoder_State *st_fx: */
23 : /* _ lastLgainD_fx - Q11 */
24 : /* _ lastHgainD_fx - Q11 */
25 : /* _ lasterbD_fx - Q13 */
26 : /* _ Word16 *pitch - Q6 fixed pitch values for each subframe */
27 : /* _ Word16 *out_fx - Q0 residual signal */
28 : /*-------------------------------------------------------------------*/
29 : /* INPUT/OUTPUT ARGUMENTS : */
30 : /* _ Decoder_State *st_fx: */
31 : /* _ lsp_old_fx - Q15 */
32 : /* _ st_fx->dtfs_dec_xxxx */
33 : /* _ a nd b in st_fx->dtfs_dec_Q */
34 : /* rest all in Q0 */
35 : /* _ gainp_ppp Q14 */
36 : /* _ Word16 *pitch_buf_fx - Q6 fixed pitch values for each subframe */
37 : /*-------------------------------------------------------------------*/
38 : /* RETURN ARGUMENTS : */
39 : /* _ None */
40 : /*-------------------------------------------------------------------*/
41 : /* CALLED FROM : RX */
42 : /*===================================================================*/
43 0 : ivas_error ppp_voiced_decoder_fx(
44 : Decoder_State *st_fx, /* i/o: state structure */
45 : Word16 *out_fx, /* o : residual signal Q0*/
46 : const Word16 *lpc2_fx, /* i : current frame LPC Q12*/
47 : Word16 *exc_fx, /* i : previous frame excitation Q0*/
48 : Word16 *pitch, /* o : fixed point pitch values for each subframe Q6*/
49 : Word16 bfi /* i : Frame error rate Q0*/
50 : )
51 : {
52 0 : Word16 k, delta_lag_D = 0, temp, Ql, Qh, diff;
53 0 : Word16 upper_cut_off_freq_of_interest = 0, upper_cut_off_freq = 0;
54 0 : move16();
55 0 : move16();
56 0 : move16();
57 : Word16 pl, l, n, rem_fx;
58 : Word16 temp_l_fx, temp_pl_fx, interp_delay_fx[3];
59 : Word32 logLag, Ltemp_q, Ltemp, rem32, temp32_fx, tempnH_fx;
60 : Word16 exp, tmp;
61 : Word32 L_tmp;
62 : DTFS_STRUCTURE *TMPDTFS_FX;
63 : DTFS_STRUCTURE *CURRP_Q_D_FX;
64 : DTFS_STRUCTURE *dtfs_temp_fx;
65 : Word16 pf_temp1[MAXLAG_WI]; /*maynot need more than MAXLAG_WI/2+1 */
66 : Word16 pf_temp2[MAXLAG_WI];
67 : Word16 pf_temp[MAXLAG_WI];
68 : Word16 pf_n2[MAXLAG_WI];
69 : Word16 S_fx[4 * PIT_MAX + 1], C_fx[4 * PIT_MAX + 1];
70 : Word16 temp_Fs;
71 : SC_VBR_DEC_HANDLE hSC_VBR;
72 :
73 0 : hSC_VBR = st_fx->hSC_VBR;
74 :
75 : ivas_error error;
76 :
77 0 : error = IVAS_ERR_OK;
78 0 : move32();
79 :
80 0 : IF( NE_32( ( error = DTFS_new_fx( &TMPDTFS_FX ) ), IVAS_ERR_OK ) )
81 : {
82 0 : IVAS_ERROR( error, "Error creating DTFS structure" );
83 : }
84 0 : IF( NE_32( ( error = DTFS_new_fx( &CURRP_Q_D_FX ) ), IVAS_ERR_OK ) )
85 : {
86 0 : IVAS_ERROR( error, "Error creating DTFS structure" );
87 : }
88 0 : IF( NE_32( ( error = DTFS_new_fx( &dtfs_temp_fx ) ), IVAS_ERR_OK ) )
89 : {
90 0 : IVAS_ERROR( error, "Error creating DTFS structure" );
91 : }
92 :
93 0 : test();
94 0 : IF( EQ_16( st_fx->bwidth, WB ) || EQ_16( st_fx->bwidth, SWB ) )
95 : {
96 0 : upper_cut_off_freq_of_interest = 0x2800;
97 0 : move16(); /*4000 normalized to 12800 in Q15 */
98 0 : upper_cut_off_freq = 0x4000;
99 0 : move16(); /*6400 normalized to 12800 in Q15 */
100 : }
101 0 : ELSE IF( EQ_16( st_fx->bwidth, NB ) )
102 : {
103 0 : upper_cut_off_freq_of_interest = 0x2100;
104 0 : move16(); /*3300 normalized to 12800 in Q15 */
105 0 : upper_cut_off_freq = 0x2800;
106 0 : move16();
107 : }
108 :
109 0 : temp_Fs = 8000;
110 0 : move16();
111 :
112 0 : if ( EQ_16( st_fx->bwidth, WB ) )
113 : {
114 0 : temp_Fs = 16000;
115 0 : move16();
116 : }
117 :
118 :
119 : /* Initialization */
120 0 : IF( hSC_VBR->firstTime_voiceddec )
121 : {
122 0 : hSC_VBR->firstTime_voiceddec = 0;
123 0 : move16();
124 :
125 : /* (st_fx->PREV_CW_D) = DTFS_new();*/
126 0 : hSC_VBR->dtfs_dec_lag = 0;
127 0 : move16();
128 0 : hSC_VBR->dtfs_dec_nH = 0;
129 0 : move16();
130 0 : hSC_VBR->dtfs_dec_nH_4kHz = 0;
131 0 : move16();
132 0 : hSC_VBR->dtfs_dec_upper_cut_off_freq_of_interest_fx = 3300;
133 0 : move16();
134 0 : hSC_VBR->dtfs_dec_upper_cut_off_freq_fx = 4000;
135 0 : move16();
136 :
137 0 : FOR( k = 0; k < MAXLAG_WI; k++ )
138 : {
139 0 : hSC_VBR->dtfs_dec_a_fx[k] = 0;
140 0 : move16();
141 0 : hSC_VBR->dtfs_dec_b_fx[k] = 0;
142 0 : move16();
143 : }
144 0 : hSC_VBR->dtfs_dec_Q = 0;
145 0 : move16();
146 : }
147 :
148 0 : pl = s_min( rint_new_fx( st_fx->old_pitch_buf_fx[( 2 * NB_SUBFR ) - 1] ), MAX_LAG_PIT );
149 0 : delta_lag_D = (Word16) get_next_indice_fx( st_fx, 5 );
150 :
151 :
152 0 : l = s_min( MAX_LAG_PIT, add( pl, sub( delta_lag_D, 11 ) ) );
153 :
154 :
155 0 : temp_pl_fx = pl;
156 0 : move16();
157 0 : temp_l_fx = l;
158 0 : move16();
159 :
160 0 : IF( NE_16( temp_pl_fx, temp_l_fx ) )
161 : {
162 0 : FOR( k = 0; k < NB_SUBFR; k++ )
163 : {
164 : /* do the linear pitch interp to drive the nb_post_filt_fx */
165 0 : Interpol_delay_fx( interp_delay_fx, temp_pl_fx, temp_l_fx, (Word16) k, frac_4sf_fx );
166 0 : pitch[k] = s_min( MAX_LAG_PIT << 6, s_max( 19 << 6, shl( interp_delay_fx[0], 2 ) ) );
167 0 : move16(); /*Q6 */
168 : }
169 : }
170 : ELSE
171 : {
172 0 : set16_fx( pitch, s_min( MAX_LAG_PIT << 6, s_max( 19 << 6, shl( temp_l_fx, 6 ) ) ), NB_SUBFR ); /*Q6 */
173 : }
174 :
175 0 : if ( EQ_16( st_fx->last_coder_type, UNVOICED ) )
176 : {
177 0 : pl = l;
178 0 : move16(); /* if prev frame was sil/uv*/
179 : }
180 :
181 0 : temp = mult( shl( l, 3 ), 30310 ); /*Q3+14+1-16 = Q2 30310 is 1.85 in Q14 */
182 :
183 0 : IF( temp >= 0 )
184 : {
185 0 : temp = add( temp, 2 );
186 : }
187 : ELSE
188 : {
189 0 : temp = sub( temp, 2 );
190 : }
191 0 : temp = shr( temp, 2 ); /*Q0 */
192 :
193 0 : if ( GT_16( pl, temp ) )
194 : {
195 0 : pl = shr( pl, 1 );
196 : }
197 :
198 0 : temp = mult( shl( l, 3 ), 8857 ); /*Q3+14+1-16 = Q2 8847 is 0.54 in Q14 */
199 0 : IF( temp >= 0 )
200 : {
201 0 : temp = add( temp, 2 );
202 : }
203 : ELSE
204 : {
205 0 : temp = sub( temp, 2 );
206 : }
207 0 : temp = shr( temp, 2 ); /*Q0 */
208 :
209 0 : test();
210 0 : if ( LE_16( shl( pl, 1 ), PIT_MAX ) && LE_16( pl, temp ) )
211 : {
212 0 : pl = shl( pl, 1 );
213 : }
214 :
215 : /* Restoring PPP memories when the last frame is non-PPP or full-rate PPP */
216 0 : IF( NE_16( st_fx->last_ppp_mode_dec, 1 ) )
217 : {
218 :
219 0 : GetSinCosTab_fx( pl, S_fx, C_fx );
220 0 : DTFS_to_fs_fx( exc_fx - pl, pl, dtfs_temp_fx, temp_Fs, 0, S_fx, C_fx );
221 :
222 0 : hSC_VBR->ph_offset_D_fx = 0;
223 0 : move16();
224 :
225 : /* Copy over PREV_CW_D into TMPDTFS */
226 0 : DTFS_copy_fx( TMPDTFS_FX, *dtfs_temp_fx );
227 :
228 0 : DTFS_car2pol_fx( TMPDTFS_FX );
229 :
230 : /*st_fx->lastLgainD = (float) log10(TMPDTFS->lag*DTFS_setEngyHarm(92.0,1104.5,0.0,1104.5,1.0,TMPDTFS)); */
231 :
232 0 : L_tmp = L_deposit_h( TMPDTFS_FX->lag_fx ); /*Q16 */
233 0 : exp = norm_l( L_tmp );
234 0 : tmp = Log2_norm_lc( L_shl( L_tmp, exp ) );
235 0 : exp = sub( sub( 30, exp ), 16 );
236 0 : L_tmp = Mpy_32_16( exp, tmp, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
237 0 : logLag = L_shl( L_tmp, 10 ); /*Q23 */
238 :
239 0 : Ltemp_q = L_shl( L_mult( shl( TMPDTFS_FX->Q, 1 ), 24660 ), 9 ); /* Ltemp_q=2Q*10log10(2), Q23 */
240 : /* Process low band */
241 0 : Ltemp = DTFS_setEngyHarm_fx( 236, 2828, 0, 2828, 1, 0, &Ql, TMPDTFS_FX ); /* Ltemp in 2*TMP.Q */
242 : /* Compensate for Q factor of energy to get log10(lag*eng) */
243 :
244 :
245 0 : Ltemp = log10_fx( Ltemp ); /* Ltemp=10log10(eng), Q23 */
246 0 : Ltemp = L_add_sat( L_sub_sat( Ltemp, Ltemp_q ), logLag ); /* Ltemp=10*log10(lag*eng), Q23 */
247 0 : hSC_VBR->lastLgainD_fx = round_fx_sat( L_shl_sat( (Word32) Mpy_32_16( extract_h( Ltemp ), extract_l( Ltemp ), 0x6666 ), 1 ) ); /* Q11 */
248 0 : move16();
249 :
250 :
251 : /* Process high band */
252 0 : Ltemp = DTFS_setEngyHarm_fx( 2828, upper_cut_off_freq_of_interest, 2828, upper_cut_off_freq, 1, 0, &Qh, TMPDTFS_FX );
253 :
254 :
255 0 : Ltemp = log10_fx( Ltemp ); // Q23
256 0 : Ltemp = L_add_sat( L_sub_sat( Ltemp, Ltemp_q ), logLag ); /* Ltemp=10*log10(lag*eng), Q23 */
257 0 : hSC_VBR->lastHgainD_fx = round_fx_sat( L_shl_sat( (Word32) Mpy_32_16( extract_h( Ltemp ), extract_l( Ltemp ), 0x6666 ), 1 ) ); /* Q11 */
258 0 : move16();
259 :
260 :
261 : /* Need to unify the Q factors of both bands */
262 0 : TMPDTFS_FX->Q = s_min( Ql, Qh ); /* set Q factor to be the smaller one */
263 0 : n = sub( Ql, Qh ); /* compare band Q factors */
264 :
265 : /*This logic adjusts difference between Q formats of both bands */
266 0 : IF( n < 0 )
267 : {
268 0 : rshiftHarmBand_fx( TMPDTFS_FX, 2828, upper_cut_off_freq, n );
269 : }
270 0 : ELSE IF( n > 0 )
271 : {
272 0 : rshiftHarmBand_fx( TMPDTFS_FX, 0, 2828, sub( Qh, Ql ) );
273 : }
274 :
275 0 : DTFS_to_erb_fx( *TMPDTFS_FX, hSC_VBR->lasterbD_fx );
276 : }
277 : ELSE
278 : {
279 : /* Copy DTFS related parameters from 'st' to 'dtfs_temp' structure */
280 0 : dtfs_temp_fx->lag_fx = hSC_VBR->dtfs_dec_lag;
281 0 : move16();
282 0 : dtfs_temp_fx->nH_fx = hSC_VBR->dtfs_dec_nH;
283 0 : move16();
284 0 : dtfs_temp_fx->nH_4kHz_fx = hSC_VBR->dtfs_dec_nH_4kHz;
285 0 : move16();
286 0 : dtfs_temp_fx->upper_cut_off_freq_of_interest_fx = hSC_VBR->dtfs_dec_upper_cut_off_freq_of_interest_fx;
287 0 : move16();
288 0 : dtfs_temp_fx->upper_cut_off_freq_fx = hSC_VBR->dtfs_dec_upper_cut_off_freq_fx;
289 0 : move16();
290 :
291 0 : Copy( hSC_VBR->dtfs_dec_a_fx, dtfs_temp_fx->a_fx, MAXLAG_WI );
292 0 : Copy( hSC_VBR->dtfs_dec_b_fx, dtfs_temp_fx->b_fx, MAXLAG_WI );
293 0 : dtfs_temp_fx->Q = hSC_VBR->dtfs_dec_Q;
294 0 : move16();
295 : }
296 :
297 0 : CURRP_Q_D_FX->lag_fx = l;
298 0 : move16();
299 :
300 : /* safety check in case of bit errors */
301 0 : IF( CURRP_Q_D_FX->lag_fx <= 0 )
302 : {
303 0 : CURRP_Q_D_FX->lag_fx = 1;
304 0 : move16();
305 0 : st_fx->BER_detect = 1;
306 0 : move16();
307 : }
308 :
309 : /* compute nH for lag */
310 0 : Ltemp = L_shl( (Word32) upper_cut_off_freq, 13 ); /*Q28 */
311 0 : upper_cut_off_freq = (Word16) find_remd( Ltemp, 20971, &rem32 ); /*denormalize upper_cut_off_freq */
312 :
313 :
314 : /* temp32_fx = (Word32)divide_dp((Word40)819200,(Word40)L_shl((Word32)CURRP_Q_D_FX->lag_fx,6),-23,1);//Q6 */
315 0 : exp = norm_s( CURRP_Q_D_FX->lag_fx );
316 0 : tmp = div_s( shl( 1, sub( 14, exp ) ), CURRP_Q_D_FX->lag_fx ); /*29-exp */
317 0 : L_tmp = L_shl_sat( L_mult0( tmp, 12800 ), sub( exp, 7 ) );
318 0 : temp32_fx = round_fx_sat( L_tmp );
319 0 : diff = round_fx( L_shl( temp32_fx, 16 - 6 ) ); /*Q0 */
320 :
321 0 : CURRP_Q_D_FX->nH_fx = find_rem( upper_cut_off_freq, diff, &rem_fx ); /*Q0 */
322 0 : move16();
323 :
324 0 : exp = norm_s( diff );
325 0 : tmp = div_s( shl( 1, sub( 14, exp ) ), diff ); /*29-exp */
326 0 : L_tmp = L_shl( L_mult0( 4000, tmp ), sub( exp, 7 ) );
327 0 : tempnH_fx = extract_h( L_tmp );
328 0 : CURRP_Q_D_FX->nH_4kHz_fx = round_fx( L_shl( tempnH_fx, 16 - 6 ) ); /*Q0 */
329 0 : move16();
330 :
331 :
332 0 : IF( GE_16( sub( upper_cut_off_freq, shr( (Word16) L_mult( diff, CURRP_Q_D_FX->nH_fx ), 1 ) ), diff ) )
333 : {
334 0 : CURRP_Q_D_FX->nH_fx = add( CURRP_Q_D_FX->nH_fx, 1 );
335 0 : move16();
336 : }
337 0 : tempnH_fx = L_mult0( extract_l( temp32_fx ), CURRP_Q_D_FX->nH_4kHz_fx ); /* */
338 0 : tempnH_fx = L_sub( (Word32) 256000, tempnH_fx ); /*Q6 */
339 :
340 0 : if ( GE_32( tempnH_fx, temp32_fx ) )
341 : {
342 0 : CURRP_Q_D_FX->nH_4kHz_fx = add( CURRP_Q_D_FX->nH_4kHz_fx, 1 );
343 0 : move16();
344 : }
345 :
346 0 : CURRP_Q_D_FX->upper_cut_off_freq_fx = dtfs_temp_fx->upper_cut_off_freq_fx;
347 0 : move16();
348 0 : CURRP_Q_D_FX->upper_cut_off_freq_of_interest_fx = dtfs_temp_fx->upper_cut_off_freq_of_interest_fx;
349 0 : move16();
350 0 : GetSinCosTab_fx( CURRP_Q_D_FX->lag_fx, S_fx, C_fx );
351 :
352 0 : IF( bfi == 0 )
353 : {
354 0 : IF( NE_32( ( error = ppp_quarter_decoder_fx( CURRP_Q_D_FX, dtfs_temp_fx->lag_fx, &( hSC_VBR->lastLgainD_fx ),
355 : &( hSC_VBR->lastHgainD_fx ), hSC_VBR->lasterbD_fx, bfi, S_fx, C_fx, *dtfs_temp_fx, st_fx ) ),
356 : IVAS_ERR_OK ) )
357 : {
358 0 : return error;
359 : }
360 : }
361 :
362 0 : IF( NE_32( ( error = WIsyn_fx( *dtfs_temp_fx, CURRP_Q_D_FX, lpc2_fx, &( hSC_VBR->ph_offset_D_fx ), out_fx, (Word16) L_FRAME, 0,
363 : S_fx, C_fx, pf_temp1, pf_temp2, pf_temp, pf_n2 ) ),
364 : IVAS_ERR_OK ) )
365 : {
366 0 : return error;
367 : }
368 :
369 0 : DTFS_copy_fx( dtfs_temp_fx, *CURRP_Q_D_FX );
370 :
371 : /* Copy DTFS related parameters from 'dtfs_temp' to 'st' structure */
372 0 : hSC_VBR->dtfs_dec_lag = dtfs_temp_fx->lag_fx;
373 0 : move16();
374 0 : hSC_VBR->dtfs_dec_nH = dtfs_temp_fx->nH_fx;
375 0 : move16();
376 0 : hSC_VBR->dtfs_dec_nH_4kHz = dtfs_temp_fx->nH_4kHz_fx;
377 0 : move16();
378 0 : hSC_VBR->dtfs_dec_upper_cut_off_freq_of_interest_fx = dtfs_temp_fx->upper_cut_off_freq_of_interest_fx;
379 0 : move16();
380 0 : hSC_VBR->dtfs_dec_upper_cut_off_freq_fx = dtfs_temp_fx->upper_cut_off_freq_fx;
381 0 : move16();
382 :
383 0 : Copy( dtfs_temp_fx->a_fx, hSC_VBR->dtfs_dec_a_fx, MAXLAG_WI );
384 0 : Copy( dtfs_temp_fx->b_fx, hSC_VBR->dtfs_dec_b_fx, MAXLAG_WI );
385 :
386 0 : hSC_VBR->dtfs_dec_Q = dtfs_temp_fx->Q;
387 0 : move16();
388 :
389 0 : free( TMPDTFS_FX );
390 0 : free( CURRP_Q_D_FX );
391 0 : free( dtfs_temp_fx );
392 :
393 0 : return IVAS_ERR_OK;
394 : }
395 : /*---------------------------------------------------------------------*
396 : * sc_vbr_dec_init()
397 : *
398 : * Initialize SC-VBR decoder
399 : *---------------------------------------------------------------------*/
400 3 : void sc_vbr_dec_init(
401 : SC_VBR_DEC_HANDLE hSC_VBR /* i/o: SC-VBR decoder handle */
402 : )
403 : {
404 3 : hSC_VBR->nelp_dec_seed = 0;
405 3 : move16();
406 3 : hSC_VBR->firstTime_voiceddec = 1;
407 3 : move16();
408 :
409 : /* DTFS variables */
410 3 : set16_fx( hSC_VBR->dtfs_dec_a_fx, 0, MAXLAG_WI );
411 3 : set16_fx( hSC_VBR->dtfs_dec_b_fx, 0, MAXLAG_WI );
412 3 : hSC_VBR->dtfs_dec_lag = 0;
413 3 : move16();
414 3 : hSC_VBR->dtfs_dec_nH = 0;
415 3 : move16();
416 3 : hSC_VBR->dtfs_dec_nH_4kHz = 0;
417 3 : move16();
418 3 : hSC_VBR->dtfs_dec_upper_cut_off_freq_of_interest_fx = 0;
419 3 : move16();
420 3 : hSC_VBR->dtfs_dec_upper_cut_off_freq_fx = 0;
421 3 : move16();
422 3 : hSC_VBR->ph_offset_D_fx = 0;
423 3 : move16();
424 3 : hSC_VBR->lastLgainD_fx = 0;
425 3 : move16();
426 3 : hSC_VBR->lastHgainD_fx = 0;
427 3 : move16();
428 3 : set16_fx( hSC_VBR->lasterbD_fx, 0, NUM_ERB_WB );
429 :
430 : /* NELP decoder variables */
431 3 : set32_fx( hSC_VBR->bp1_filt_mem_nb_dec_fx, 0, 14 );
432 3 : set16_fx( hSC_VBR->bp1_filt_mem_wb_dec_fx, 0, 8 );
433 3 : set16_fx( hSC_VBR->shape1_filt_mem_dec_fx, 0, 10 );
434 3 : set16_fx( hSC_VBR->shape2_filt_mem_dec_fx, 0, 10 );
435 3 : set16_fx( hSC_VBR->shape3_filt_mem_dec_fx, 0, 10 );
436 :
437 3 : return;
438 : }
|