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 :
10 : /*===================================================================*/
11 : /* FUNCTION : struct DTFS_fx::dequant_cw_fx () */
12 : /*-------------------------------------------------------------------*/
13 : /* PURPOSE : Dequantize QPPP prototype */
14 : /*-------------------------------------------------------------------*/
15 : /* INPUT ARGUMENTS : */
16 : /* _ (Word16) pl: previous lag */
17 : /* _ (Word16) p_idx: Power index */
18 : /* _ (Word16[]) a_idx: Amplitude indices, 2 words */
19 : /* _ (struct DTFS_fx) X : prototype in polar domain */
20 : /* (Word16) lag: length of prototype */
21 : /*-------------------------------------------------------------------*/
22 : /* OUTPUT ARGUMENTS : */
23 : /* _ (struct DTFS_fx) X : prototype in polar domain */
24 : /* (Word16) lag: length of prototype in time domain */
25 : /* (Word16 []) a: amplitude of harmonics, normalized */
26 : /* (Word16) Q: norm factor of a */
27 : /* _ (Word16[]) curr_erb: Quantized current ERB, Q13 */
28 : /*-------------------------------------------------------------------*/
29 : /* INPUT/OUTPUT ARGUMENTS : */
30 : /* _ (Word16[]) lasterb: ERB history for differential */
31 : /* quantization, Q13 */
32 : /* _ (Word16) Lgain: low band power history, log domain, Q11 */
33 : /* _ (Word16) Hgain: high band power history, log domain, Q11 */
34 : /*-------------------------------------------------------------------*/
35 : /* RETURN ARGUMENTS : _ None. */
36 : /*-------------------------------------------------------------------*/
37 : /* CALLED FROM : TX/RX */
38 : /*===================================================================*/
39 :
40 0 : static void DTFS_dequant_cw_fx(
41 : Word16 pl_fx, /* i : Previous lag */
42 : Word16 POWER_IDX_fx, /* i : POWER index */
43 : const Word16 *AMP_IDX_fx, /* i : Amp Shape index */
44 : Word16 *lastLgainD_fx, /* i/o: low band last gain */
45 : Word16 *lastHgainD_fx, /* i/o: high band last gain */
46 : Word16 *lasterbD_fx, /* i/o: last frame ERB vector */
47 : DTFS_STRUCTURE *X_fx, /* o : DTFS structure dequantized */
48 : Word16 num_erb_fx )
49 :
50 : {
51 : Word16 tmp_fx, mfreq_fx[NUM_ERB_WB], curr_erb_fx[NUM_ERB_WB];
52 0 : const Word16 *PowerCB_fx = NULL;
53 : Word16 slot_fx[NUM_ERB_WB];
54 : Word16 Ql, Qh, n;
55 : Word32 Ltemp_fx, logLag_fx;
56 : Word16 exp, frac, exp1;
57 : Word32 L_tmp, L_temp;
58 : Word32 L_tmp2;
59 :
60 0 : IF( EQ_16( num_erb_fx, NUM_ERB_NB ) )
61 : {
62 0 : PowerCB_fx = PowerCB_NB_fx; // Q11
63 0 : move16();
64 : }
65 0 : ELSE IF( EQ_16( num_erb_fx, NUM_ERB_WB ) )
66 : {
67 0 : PowerCB_fx = PowerCB_WB_fx; // Q11
68 0 : move16();
69 : }
70 :
71 : /* Amplitude Dequantization */
72 :
73 0 : erb_add_fx( curr_erb_fx, X_fx->lag_fx, lasterbD_fx, pl_fx, AMP_IDX_fx, num_erb_fx );
74 :
75 0 : curr_erb_fx[0] = mult_r( curr_erb_fx[1], 9830 ); /* 0.3 inQ15 leaves curr_erb in Q13 */
76 0 : move16();
77 0 : curr_erb_fx[num_erb_fx - 2] = mult_r( curr_erb_fx[num_erb_fx - 3], 9830 ); /* Q13 */
78 0 : move16();
79 :
80 :
81 0 : curr_erb_fx[num_erb_fx - 1] = 0;
82 0 : move16();
83 :
84 0 : erb_slot_fx( X_fx->lag_fx, slot_fx, mfreq_fx, num_erb_fx );
85 :
86 : /* mfreq normalized (2.56) in Q15 */
87 0 : DTFS_erb_inv_fx( curr_erb_fx, slot_fx, mfreq_fx, X_fx, num_erb_fx );
88 :
89 :
90 : /* Back up the lasterbD memory after power normalization */
91 :
92 0 : DTFS_setEngyHarm_fx( 236, 2828, 0, 2828, 1, 0, &Ql, X_fx );
93 0 : DTFS_setEngyHarm_fx( 2828, X_fx->upper_cut_off_freq_of_interest_fx, 2828, X_fx->upper_cut_off_freq_fx, 1, 0, &Qh, X_fx );
94 :
95 : /* Need to unify the Q factors of both bands */
96 0 : X_fx->Q = s_min( Ql, Qh ); /* set Q factor to be the smaller one */
97 0 : move16();
98 0 : n = sub( Ql, Qh ); /* compare band Q factors */
99 :
100 :
101 : /* This logic adjusts difference between Q formats of both bands */
102 0 : IF( n < 0 )
103 : {
104 0 : rshiftHarmBand_fx( X_fx, 2828, X_fx->upper_cut_off_freq_fx, n );
105 : }
106 0 : ELSE IF( n > 0 )
107 : {
108 0 : rshiftHarmBand_fx( X_fx, 0, 2828, sub( Qh, Ql ) );
109 : }
110 :
111 0 : DTFS_to_erb_fx( *X_fx, lasterbD_fx );
112 :
113 :
114 : /* Power Dequantization */
115 :
116 0 : tmp_fx = shl( POWER_IDX_fx, 1 ); /* tmp=2*POWER_IDX */
117 0 : *lastLgainD_fx = add_sat( *lastLgainD_fx, PowerCB_fx[tmp_fx] ); /* Q11 */
118 0 : *lastHgainD_fx = add_sat( *lastHgainD_fx, PowerCB_fx[tmp_fx + 1] ); /* Q11 */
119 0 : move16();
120 0 : move16();
121 0 : L_tmp = L_deposit_h( X_fx->lag_fx ); /* Q16 */
122 0 : exp = norm_l( L_tmp );
123 0 : L_tmp = L_shl( L_tmp, exp );
124 0 : frac = Log2_norm_lc( L_tmp );
125 0 : exp = sub( 30, add( exp, 16 ) );
126 0 : L_tmp = Mpy_32_16( exp, frac, 12330 ); /* Q13 */ /* 10*log10(2) in Q12*/
127 0 : Ltemp_fx = L_shl( L_tmp, 10 ); /* Q23 */
128 :
129 :
130 0 : logLag_fx = Mult_32_16( Ltemp_fx, 0x6666 ); /* logLag=log10(lag), Q26 */
131 :
132 0 : Ltemp_fx = L_sub( L_shr( L_deposit_h( *lastLgainD_fx ), 1 ), logLag_fx ); /* Ltemp=Lgain-log10(lag), Q26 */
133 :
134 : /* Lacc_fx=dsp_pow10(Ltemp_fx); : Lacc=10^Lgain/lag, Q15 */
135 :
136 0 : L_tmp = Mult_32_16( Ltemp_fx, 27213 ); /* 3.321928 in Q13 */
137 0 : L_tmp = L_shr( L_tmp, 8 ); /* Q16 */
138 0 : frac = L_Extract_lc( L_tmp, &exp1 ); /* Extract exponent */
139 0 : L_tmp = Pow2( 14, frac );
140 0 : exp1 = sub( exp1, 14 );
141 0 : L_temp = L_shl_sat( L_tmp, add( exp1, 15 ) ); /* Q15 */
142 0 : L_tmp2 = L_temp;
143 0 : if ( GE_32( L_temp, 2147483647 ) )
144 : {
145 0 : L_temp = L_shl( L_tmp, 15 ); /*Q(15-exp1) */
146 : }
147 :
148 0 : n = norm_l( L_temp );
149 0 : Ltemp_fx = L_shl( L_temp, n ); /* Ltemp in Q(15+n) or Q(15 - exp1 +n) */
150 :
151 0 : IF( GE_32( L_tmp2, 2147483647 ) )
152 : {
153 0 : DTFS_setEngyHarm_fx( 236, 2828, 0, 2828, Ltemp_fx, add( 15, sub( n, exp1 ) ), &Ql, X_fx );
154 : }
155 : ELSE
156 : {
157 0 : DTFS_setEngyHarm_fx( 236, 2828, 0, 2828, Ltemp_fx, add( 15, n ), &Ql, X_fx );
158 : }
159 :
160 0 : Ltemp_fx = L_sub( L_shr( L_deposit_h( *lastHgainD_fx ), 1 ), logLag_fx ); /* Ltemp=Hgain-log10(lag), Q26 */
161 : /* Lacc_fx=dsp_pow10(Ltemp_fx); : Lacc=10^Hgain/lag, Q15 */
162 0 : L_tmp = Mult_32_16( Ltemp_fx, 27213 ); /* 3.321928 in Q13 */ /* Q24 */
163 0 : L_tmp = L_shr( L_tmp, 8 ); /* Q16 */
164 0 : frac = L_Extract_lc( L_tmp, &exp1 ); /* Extract exponent */
165 0 : L_tmp = Pow2( 14, frac );
166 0 : exp1 = sub( exp1, 14 );
167 0 : L_temp = L_shl_sat( L_tmp, exp1 + 15 ); /* Q15 */
168 0 : L_tmp2 = L_temp;
169 0 : move32();
170 0 : if ( GE_32( L_temp, 2147483647 ) )
171 : {
172 0 : L_temp = L_shl( L_tmp, 15 ); /*Q(15-exp1) */
173 : }
174 :
175 :
176 0 : n = norm_l( L_temp );
177 0 : Ltemp_fx = L_shl( L_temp, n ); /* Ltemp in Q(15+n) or Q(15 - exp1 +n) */
178 :
179 0 : IF( GE_32( L_tmp2, 2147483647 ) )
180 : {
181 0 : DTFS_setEngyHarm_fx( 2828, X_fx->upper_cut_off_freq_of_interest_fx, 2828, X_fx->upper_cut_off_freq_fx, Ltemp_fx, add( 15, sub( n, exp1 ) ), &Qh, X_fx );
182 : }
183 : ELSE
184 : {
185 0 : DTFS_setEngyHarm_fx( 2828, X_fx->upper_cut_off_freq_of_interest_fx, 2828, X_fx->upper_cut_off_freq_fx, Ltemp_fx, add( 15, n ), &Qh, X_fx );
186 : }
187 :
188 :
189 : /* Need to unify the Q factors of both bands */
190 0 : X_fx->Q = s_min( Ql, Qh ); /* set Q factor to be the smaller one */
191 0 : move16();
192 0 : n = sub( Ql, Qh ); /* compare band Q factors */
193 :
194 :
195 0 : IF( n < 0 )
196 : {
197 0 : rshiftHarmBand_fx( X_fx, 2828, X_fx->upper_cut_off_freq_fx, n );
198 : }
199 0 : ELSE IF( n > 0 )
200 : {
201 0 : rshiftHarmBand_fx( X_fx, 0, 2828, sub( Qh, Ql ) );
202 : }
203 0 : }
204 : /*===================================================================*/
205 : /* FUNCTION : void ppp_quarter_decoder_fx () */
206 : /*-------------------------------------------------------------------*/
207 : /* PURPOSE : */
208 : /*-------------------------------------------------------------------*/
209 : /* INPUT ARGUMENTS : */
210 : /* _ Word16 bfi_fx - Q0 bad frame indicator */
211 : /* _ const Word16 *curr_lpc_fx - Q12 current frame LPC */
212 : /* _ Word16 *exc_fx - Q0 previous frame excitation */
213 : /* _ Word16 prevCW_lag_fx - Q0 Previous lag */
214 : /* _ (struct DTFS_fx) PREV_CW_D_FX : prototype in polar domain */
215 : /* (Word16) lag: length of prototype in time domain */
216 : /* (Word16 []) a: amplitude of harmonics, normalized */
217 : /* (Word16) Q: norm factor of a */
218 : /*-------------------------------------------------------------------*/
219 : /* OUTPUT ARGUMENTS : */
220 : /* _ Decoder_State_fx *st_fx: */
221 : /* _ Word16 *pitch - Q6 floating pitch values for each subframe */
222 : /* _ Word16 *out_fx - Q0 residual signal */
223 : /*-------------------------------------------------------------------*/
224 : /* INPUT/OUTPUT ARGUMENTS : */
225 : /* _ Decoder_State_fx *st_fx: */
226 : /* _ lsp_old_fx - Q15 */
227 : /* _ st_fx->dtfs_dec_xxxx */
228 : /* _ gainp_ppp Q14 */
229 : /* _ lastLgainD_fx - Q11 */
230 : /* _ lastHgainD_fx - Q11 */
231 : /* _ lasterbD_fx - Q13 */
232 : /* _ (struct DTFS_fx) CURRCW_Q_DTFS_FX : prototype in polar domain*/
233 : /* (Word16) lag: length of prototype in time domain */
234 : /* (Word16 []) a: amplitude of harmonics, normalized */
235 : /* (Word16) Q: norm factor of a */
236 : /* _ Word16 *pitch_buf_fx - Q6 fixed pitch values for each subframe */
237 : /* _ Word16 *exc_fx - Q0 previous frame excitation */
238 : /*-------------------------------------------------------------------*/
239 : /* RETURN ARGUMENTS : */
240 : /* _ None */
241 : /*-------------------------------------------------------------------*/
242 : /* CALLED FROM : RX */
243 : /*===================================================================*/
244 0 : ivas_error ppp_quarter_decoder_fx(
245 : DTFS_STRUCTURE *CURRCW_Q_DTFS_FX, /* i/o: Current CW DTFS */
246 : Word16 prevCW_lag_fx, /* i : Previous lag */
247 : Word16 *lastLgainD_fx, /* i/o: Last gain lowband Q11 */
248 : Word16 *lastHgainD_fx, /* i/o: Last gain highwband Q11 */
249 : Word16 *lasterbD_fx, /* i/o: Last ERB vector Q13 */
250 : Word16 bfi, /* i : FER flag */
251 : Word16 *S_fx, /* i : sine table, Q15 */
252 : Word16 *C_fx, /* i : cosine table, Q15 */
253 : DTFS_STRUCTURE PREV_CW_D_FX, /* i : Previous DTFS */
254 : Decoder_State *st_fx )
255 : {
256 : DTFS_STRUCTURE *PREVDTFS_FX;
257 : Word16 AMP_IDX_fx[2];
258 0 : Word16 temp_pl_fx = prevCW_lag_fx, temp_l_fx = CURRCW_Q_DTFS_FX->lag_fx;
259 0 : move16();
260 0 : move16();
261 : Word16 temp_fx;
262 0 : Word16 l_fx = CURRCW_Q_DTFS_FX->lag_fx;
263 0 : move16();
264 : Word16 POWER_IDX_fx;
265 0 : Word16 Erot_fx = 0;
266 0 : move16();
267 0 : Word16 num_erb_fx = 24;
268 0 : move16();
269 : Word32 temp32d_fx, temp32n_fx;
270 : Word32 L_tmp, L_tmp1;
271 : Word16 tmp, exp;
272 : ivas_error error;
273 :
274 0 : error = IVAS_ERR_OK;
275 0 : move16();
276 0 : IF( NE_32( ( error = DTFS_new_fx( &PREVDTFS_FX ) ), IVAS_ERR_OK ) )
277 : {
278 0 : return error;
279 : }
280 :
281 0 : IF( EQ_16( CURRCW_Q_DTFS_FX->upper_cut_off_freq_fx, 4000 ) )
282 : {
283 0 : num_erb_fx = 22;
284 0 : move16();
285 : }
286 0 : ELSE IF( EQ_16( CURRCW_Q_DTFS_FX->upper_cut_off_freq_fx, 6400 ) )
287 : {
288 0 : num_erb_fx = 24;
289 0 : move16();
290 : }
291 :
292 0 : DTFS_copy_fx( PREVDTFS_FX, PREV_CW_D_FX );
293 0 : IF( bfi == 0 )
294 : {
295 0 : POWER_IDX_fx = (Word16) get_next_indice_fx( st_fx, 6 );
296 0 : AMP_IDX_fx[0] = (Word16) get_next_indice_fx( st_fx, 6 );
297 0 : move16();
298 0 : AMP_IDX_fx[1] = (Word16) get_next_indice_fx( st_fx, 6 );
299 0 : move16();
300 :
301 : /* Amplitude Dequantization */
302 : /*This normalization and de-normalization is done to avoid division by 12800. And this logic is used only in
303 : dequant_cw. So upper cut-off frequencies need to be multiplied by a factor2.56.
304 : This logic of normalisation is not employed in adjustlag, hence denormalisation is necessury.*/
305 : /*As the upper cut of freqencies are normalized to 12800, we have to multiply upper cut off freq by
306 : 2.56(1/12800 in Q15) */
307 0 : temp32n_fx = L_mult( CURRCW_Q_DTFS_FX->upper_cut_off_freq_fx, 10486 ); /* Q0+Q27 = Q28 */
308 0 : CURRCW_Q_DTFS_FX->upper_cut_off_freq_fx = extract_l( L_shr( temp32n_fx, 13 ) ); /*Q15 */
309 0 : move16();
310 0 : temp32n_fx = L_mult( CURRCW_Q_DTFS_FX->upper_cut_off_freq_of_interest_fx, 10486 ); /* Q0+Q27 = Q28 */
311 0 : CURRCW_Q_DTFS_FX->upper_cut_off_freq_of_interest_fx = extract_l( L_shr( temp32n_fx, 13 ) ); /*Q15 */
312 0 : move16();
313 :
314 0 : DTFS_dequant_cw_fx( prevCW_lag_fx, POWER_IDX_fx, AMP_IDX_fx, lastLgainD_fx, lastHgainD_fx, lasterbD_fx, CURRCW_Q_DTFS_FX, num_erb_fx );
315 : /*De-normalize cut off frequencies */
316 :
317 0 : temp32n_fx = L_shl( L_deposit_l( CURRCW_Q_DTFS_FX->upper_cut_off_freq_fx ), 13 ); /*Q28 */
318 0 : CURRCW_Q_DTFS_FX->upper_cut_off_freq_fx = extract_l( find_remd( temp32n_fx, 20971, &temp32d_fx ) );
319 0 : move16();
320 0 : temp32n_fx = L_shl( L_deposit_l( CURRCW_Q_DTFS_FX->upper_cut_off_freq_of_interest_fx ), 13 ); /*Q28 */
321 0 : CURRCW_Q_DTFS_FX->upper_cut_off_freq_of_interest_fx = extract_l( find_remd( temp32n_fx, 20971, &temp32d_fx ) );
322 0 : move16();
323 : }
324 :
325 : /* Copying phase spectrum over */
326 0 : DTFS_adjustLag_fx( PREVDTFS_FX, l_fx );
327 :
328 0 : temp_fx = sub( L_FRAME, temp_l_fx ); /*Q0 */
329 :
330 0 : exp = norm_s( temp_pl_fx );
331 0 : tmp = div_s( shl( 1, sub( 14, exp ) ), temp_pl_fx ); /*Q(29-exp) */
332 0 : L_tmp = L_mult( temp_fx, tmp ); /*Q(31-exp); +1 due to /2 */
333 0 : L_tmp = L_shl( L_tmp, sub( exp, 15 ) ); /*Q16 */
334 :
335 0 : exp = norm_s( temp_l_fx );
336 0 : tmp = div_s( shl( 1, sub( 14, exp ) ), temp_l_fx ); /*Q(29-exp) */
337 0 : L_tmp1 = L_mult( temp_fx, tmp ); /*Q(31-exp); +1 due to /2 */
338 0 : L_tmp1 = L_shl( L_tmp1, sub( exp, 15 ) ); /*Q16 */
339 :
340 0 : L_tmp = L_add( L_tmp, L_tmp1 ); /*Q16 */
341 :
342 0 : tmp = lshr( extract_l( L_tmp ), 1 ); /*Q15 */
343 0 : L_tmp = L_mult( temp_l_fx, tmp ); /*Q16 */
344 0 : temp_fx = rint_new_fx( L_tmp );
345 0 : Erot_fx = sub( temp_l_fx, temp_fx ); /*Q0 */
346 :
347 0 : Q2phaseShift_fx( PREVDTFS_FX, shl( Erot_fx, 2 ), CURRCW_Q_DTFS_FX->lag_fx, S_fx, C_fx );
348 0 : IF( EQ_16( bfi, 1 ) )
349 : {
350 0 : DTFS_car2pol_fx( CURRCW_Q_DTFS_FX );
351 : }
352 : /*Phase copying is done through copy_phase instead of car2pol and pol2car */
353 0 : copy_phase_fx( PREVDTFS_FX, *CURRCW_Q_DTFS_FX, CURRCW_Q_DTFS_FX );
354 :
355 : {
356 0 : temp_fx = (Word16) get_next_indice_fx( st_fx, 3 );
357 :
358 0 : temp_fx = sub( temp_fx, 3 );
359 0 : temp_fx = shl( temp_fx, 2 ); /*Q2 */
360 0 : Q2phaseShift_fx( CURRCW_Q_DTFS_FX, temp_fx, CURRCW_Q_DTFS_FX->lag_fx, S_fx, C_fx );
361 : }
362 :
363 0 : free( PREVDTFS_FX );
364 0 : return error;
365 : }
|