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 : #include "rom_com_fx.h" /* Static table prototypes */
9 : #include "rom_com.h" /* Static table prototypes */
10 : #include "prot_fx_enc.h"
11 :
12 : /*---------------------------------------------------------------------*
13 : * Local function prototype
14 : *---------------------------------------------------------------------*/
15 : static void find_cn_fx( const Word16 xn[], const Word16 Ap[], const Word16 *p_Aq, Word16 cn[] );
16 :
17 : /*-----------------------------------------------------------------*
18 : * Transform domain contribution encoding
19 : *-----------------------------------------------------------------*/
20 : #define Q_MINUS 4
21 3370 : void transf_cdbk_enc_fx(
22 : Encoder_State *st_fx, /* i/o: encoder state structure */
23 : const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP Q0*/
24 : const Word16 i_subfr, /* i : subframe index Q0*/
25 : Word16 cn[], /* i/o: target vector in residual domain Q_new*/
26 : Word16 exc[], /* i/o: pointer to excitation signal frame Q_new*/
27 : const Word16 *p_Aq, /* i : 12k8 Lp coefficient Q12*/
28 : const Word16 Ap[], /* i : weighted LP filter coefficients Q12*/
29 : const Word16 h1[], /* i : weighted filter input response Q15*/
30 : Word16 xn[], /* i/o: target vector Q_new + shift -1*/
31 : Word16 xn2[], /* i/o: target vector for innovation search Q_new + shift -1*/
32 : Word16 y1[], /* i/o: zero-memory filtered adaptive excitation Q_new + shift -1*/
33 : const Word16 y2[], /* i : zero-memory filtered innovative excitation Q9*/
34 : const Word16 Es_pred, /* i : predicited scaled innovation energy Q8*/
35 : Word16 *gain_pit, /* i/o: adaptive excitation gain Q14*/
36 : const Word32 gain_code, /* i : innovative excitation gain Q16*/
37 : Word16 g_corr[], /* o : ACELP correlation values Q15*/
38 : const Word16 clip_gain, /* i : adaptive gain clipping flag Q0*/
39 : Word16 *gain_preQ, /* o : prequantizer excitation gain Q2*/
40 : Word16 code_preQ[], /* o : prequantizer excitation Q_AVQ_OUT_DEC*/
41 : Word16 *unbits, /* o : number of AVQ unused bits Q0*/
42 : const Word16 Q_new, /* i : Current frame scaling */
43 : const Word16 shift /* i : shifting applied to y1, xn,... */
44 : )
45 : {
46 : Word16 i, index, nBits, Nsv, Es_pred_loc;
47 : Word16 x_in[L_SUBFR], x_tran[L_SUBFR], gcode16, stmp;
48 : Word16 e_corr, m_corr, e_ener, m_ener, m_den, e_den;
49 : Word16 x_norm[L_SUBFR + L_SUBFR / WIDTH_BAND];
50 : Word32 L_corr, L_ener, Ltmp, Ltmp1;
51 : Word16 nq[L_SUBFR / WIDTH_BAND];
52 : Word32 out32[L_SUBFR];
53 : Word16 Qdct;
54 : Word16 avq_bit_sFlag;
55 : Word16 trgtSvPos;
56 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
57 3370 : Flag Overflow = 0;
58 3370 : move32();
59 : #endif
60 :
61 3370 : avq_bit_sFlag = 0;
62 3370 : move16();
63 3370 : if ( st_fx->element_mode > EVS_MONO )
64 : {
65 0 : avq_bit_sFlag = 1;
66 0 : move16();
67 : }
68 :
69 : /*--------------------------------------------------------------*
70 : * Set bit-allocation
71 : *--------------------------------------------------------------*/
72 :
73 3370 : Nsv = 8;
74 3370 : move16();
75 3370 : nBits = st_fx->acelp_cfg.AVQ_cdk_bits[shr( i_subfr, 6 )]; /* Q0 */
76 3370 : move16();
77 :
78 : /* increase # of AVQ allocated bits by unused bits from the previous subframe */
79 3370 : nBits = add( nBits, *unbits );
80 :
81 : /*--------------------------------------------------------------*
82 : * Compute/Update target
83 : * For inactive frame, find target in residual domain
84 : * Deemphasis
85 : *--------------------------------------------------------------*/
86 3370 : IF( EQ_16( st_fx->coder_type, INACTIVE ) )
87 : {
88 0 : gcode16 = round_fx_o( L_shl_o( gain_code, Q_new, &Overflow ), &Overflow );
89 0 : FOR( i = 0; i < L_SUBFR; i++ )
90 : {
91 : /*x_tran[i] = xn[i] - *gain_pit * y1[i] - gain_code * y2[i];*/
92 0 : Ltmp = L_mult( gcode16, y2[i] );
93 0 : Ltmp = L_shl( Ltmp, add( 5, shift ) );
94 0 : Ltmp = L_negate( Ltmp );
95 0 : Ltmp = L_mac( Ltmp, xn[i], 16384 );
96 0 : Ltmp = L_msu( Ltmp, y1[i], *gain_pit ); /* Q_new + 14 + shift */
97 0 : Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* Q_new + 15 */
98 0 : x_tran[i] = round_fx_sat( Ltmp ); /*Q_new-1 */
99 0 : move16();
100 : }
101 0 : find_cn_fx( x_tran, Ap, p_Aq, x_in );
102 : }
103 : ELSE
104 : {
105 3370 : updt_tar_fx( cn, x_in, &exc[i_subfr], *gain_pit, L_SUBFR );
106 : }
107 3370 : Deemph2( x_in, FAC_PRE_AVQ_FX, L_SUBFR, &( st_fx->mem_deemp_preQ_fx ) );
108 :
109 : /*--------------------------------------------------------------*
110 : * DCT-II
111 : *--------------------------------------------------------------*/
112 :
113 3370 : test();
114 3370 : test();
115 3370 : test();
116 3370 : IF( NE_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && !harm_flag_acelp )
117 : {
118 0 : Copy_Scale_sig( x_in, x_tran, L_SUBFR, -Q_MINUS + 1 ); /*Q_new-1 -> Q_new-4*/
119 : /*Copy( x_in, x_tran, L_SUBFR );*/
120 0 : Qdct = sub( Q_new, Q_MINUS );
121 : }
122 : ELSE
123 : {
124 3370 : Qdct = 0;
125 3370 : move16();
126 3370 : edct2_fx( L_SUBFR, -1, x_in, out32, &Qdct, ip_edct2_64, w_edct2_64_fx );
127 3370 : Qdct = negate( Qdct );
128 3370 : Copy_Scale_sig_32_16( out32, x_tran, L_SUBFR, sub( Qdct, Q_MINUS - 1 ) ); /* Output in Q_new-4 */
129 3370 : Qdct = sub( Q_new, Q_MINUS );
130 : }
131 :
132 : /*--------------------------------------------------------------*
133 : * Split algebraic vector quantizer based on RE8 lattice
134 : *--------------------------------------------------------------*/
135 3370 : AVQ_cod_fx( x_tran, x_norm, nBits, Nsv, 0 );
136 :
137 : /*--------------------------------------------------------------*
138 : * Find prequantizer excitation gain
139 : * Quantize the gain
140 : *--------------------------------------------------------------*/
141 3370 : L_corr = L_deposit_l( 0 );
142 3370 : L_ener = L_deposit_l( 0 );
143 219050 : FOR( i = 0; i < Nsv * 8; i++ )
144 : {
145 : /*fcorr += fx_tran[i]*(float)ix_norm[i];*/
146 : /*fener += (float)ix_norm[i]*(float)ix_norm[i];*/
147 215680 : stmp = shl_sat( x_norm[i], Q_AVQ_OUT );
148 215680 : L_corr = L_mac_sat( L_corr, x_tran[i], stmp );
149 215680 : L_ener = L_mac_sat( L_ener, stmp, stmp );
150 : }
151 3370 : L_ener = L_max( L_ener, 1 );
152 :
153 : /* No negative gains allowed in the quantizer*/
154 3370 : L_corr = L_max( L_corr, 0 );
155 :
156 3370 : e_corr = norm_l( L_corr );
157 3370 : m_corr = extract_h( L_shl( L_corr, e_corr ) );
158 3370 : e_corr = sub( 30, add( e_corr, sub( Qdct, Q_AVQ_OUT ) ) );
159 3370 : e_ener = norm_l( L_ener );
160 3370 : m_ener = extract_h( L_shl( L_ener, e_ener ) );
161 3370 : e_ener = sub( 30, e_ener );
162 :
163 3370 : IF( GT_16( m_corr, m_ener ) )
164 : {
165 2319 : m_corr = shr( m_corr, 1 );
166 2319 : e_corr = add( e_corr, 1 );
167 : }
168 3370 : m_corr = div_s( m_corr, m_ener ); /* e_corr - e_ener */
169 3370 : e_corr = sub( e_corr, e_ener );
170 3370 : Ltmp = L_shl_sat( m_corr, s_min( add( e_corr, 1 ), 31 ) ); /* Lgain in Q16 */
171 3370 : IF( EQ_16( st_fx->coder_type, INACTIVE ) )
172 : {
173 0 : Ltmp1 = L_max( gain_code, 1 );
174 0 : e_den = norm_l( Ltmp1 );
175 0 : m_den = extract_h( L_shl_sat( Ltmp1, e_den ) );
176 : /* ensure m_corr < m_den */
177 0 : test();
178 0 : IF( m_corr > 0 && m_den > 0 )
179 : {
180 0 : m_corr = div_s( 16384, m_den );
181 0 : e_corr = sub( 14 + 4, e_den );
182 0 : Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); /*Q12*/
183 0 : stmp = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); /* Q12 */
184 : }
185 : ELSE
186 : {
187 0 : stmp = 0;
188 0 : move16();
189 : }
190 0 : IF( GT_32( st_fx->core_brate, 56000 ) )
191 : {
192 0 : index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_64k_Q12, G_AVQ_DELTA_INACT_64k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */
193 : }
194 0 : ELSE IF( GT_32( st_fx->core_brate, 42000 ) )
195 : {
196 0 : index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_48k_Q12, G_AVQ_DELTA_INACT_48k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */
197 : }
198 : ELSE
199 : {
200 0 : index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_Q12, G_AVQ_DELTA_INACT_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */
201 : }
202 0 : Ltmp = Mult_32_16( gain_code, stmp ); /* Q16 * Q12 - 15 -> Q13*/
203 0 : Ltmp = L_shl_sat( Ltmp, 5 ); /* Q13 -> Q18*/
204 0 : *gain_preQ = round_fx_sat( Ltmp ); /* Q2*/
205 : }
206 : ELSE
207 : {
208 3370 : IF( Es_pred < 0 )
209 : {
210 35 : Es_pred_loc = shr( negate( Es_pred ), 2 ); /* Q8 */
211 : }
212 : ELSE
213 : {
214 3335 : Es_pred_loc = Es_pred; /* Q8 */
215 3335 : move16();
216 : }
217 :
218 3370 : e_den = norm_s( Es_pred_loc );
219 3370 : m_den = shl( Es_pred_loc, e_den );
220 : /* ensure m_corr < m_den */
221 3370 : test();
222 3370 : IF( m_corr > 0 && m_den > 0 )
223 : {
224 3369 : m_corr = div_s( 16384, m_den ); /* 14 - 8 - e_den */
225 3369 : e_corr = sub( 14 - 8, e_den );
226 3369 : Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); /* Q18 */
227 : }
228 : ELSE
229 : {
230 1 : Ltmp = L_deposit_l( 0 );
231 : }
232 3370 : test();
233 3370 : IF( LE_32( st_fx->core_brate, 42000 ) && GT_32( st_fx->core_brate, ACELP_24k40 ) )
234 : {
235 0 : index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_32kbps_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); /* Q0 */
236 : }
237 : ELSE
238 : {
239 3370 : index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); /* Q0 */
240 : }
241 3370 : Ltmp = L_mult( stmp, Es_pred_loc ); /* Q0*Q8 -> Q9*/
242 3370 : Ltmp = L_shl( Ltmp, add( e_den, 9 ) ); /* Q18*/
243 3370 : *gain_preQ = round_fx( Ltmp ); /* Q2*/
244 : }
245 3370 : push_indice( st_fx->hBstr, IND_AVQ_GAIN, index, G_AVQ_BITS );
246 :
247 : /*--------------------------------------------------------------*
248 : * Encode and multiplex subvectors into bit-stream
249 : *--------------------------------------------------------------*/
250 3370 : trgtSvPos = Nsv - 1;
251 3370 : move16();
252 3370 : test();
253 3370 : test();
254 3370 : test();
255 3370 : test();
256 3370 : test();
257 3370 : IF( avq_bit_sFlag && GT_16( nBits, 85 ) && !harm_flag_acelp && ( EQ_16( st_fx->coder_type, GENERIC ) || EQ_16( st_fx->coder_type, TRANSITION ) || EQ_16( st_fx->coder_type, INACTIVE ) ) )
258 : {
259 0 : trgtSvPos = 2;
260 0 : avq_bit_sFlag = 2;
261 0 : move16();
262 0 : move16();
263 : }
264 :
265 3370 : AVQ_encmux_fx( st_fx->hBstr, -1, x_norm, &nBits, Nsv, nq, avq_bit_sFlag, trgtSvPos );
266 :
267 : /* save # of AVQ unused bits for next subframe */
268 3370 : *unbits = nBits; /* Q0 */
269 3370 : move16();
270 :
271 : /* at the last subframe, write AVQ unused bits */
272 3370 : test();
273 3370 : test();
274 3370 : IF( EQ_16( i_subfr, 4 * L_SUBFR ) && NE_16( st_fx->extl, SWB_BWE_HIGHRATE ) && NE_16( st_fx->extl, FB_BWE_HIGHRATE ) )
275 : {
276 0 : WHILE( *unbits > 0 )
277 : {
278 0 : i = s_min( *unbits, 16 );
279 0 : push_indice( st_fx->hBstr, IND_UNUSED, 0, i );
280 0 : *unbits -= i;
281 : }
282 : }
283 :
284 : /*--------------------------------------------------------------*
285 : * DCT transform
286 : *--------------------------------------------------------------*/
287 :
288 219050 : FOR( i = 0; i < Nsv * WIDTH_BAND; i++ )
289 : {
290 215680 : x_tran[i] = shl_o( x_norm[i], Q_AVQ_OUT_DEC, &Overflow );
291 215680 : move16();
292 : }
293 3370 : set16_fx( x_tran + Nsv * WIDTH_BAND, 0, sub( L_SUBFR, i_mult2( WIDTH_BAND, Nsv ) ) );
294 :
295 3370 : test();
296 3370 : test();
297 3370 : test();
298 3370 : IF( NE_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && !harm_flag_acelp )
299 : {
300 0 : Copy( x_tran, code_preQ, L_SUBFR ); /* Q_AVQ_OUT_DEC */
301 : }
302 : ELSE
303 : {
304 3370 : Qdct = 0;
305 3370 : move16();
306 3370 : edct2_fx( L_SUBFR, 1, x_tran, out32, &Qdct, ip_edct2_64, w_edct2_64_fx );
307 : /*qdct = sub(Q_AVQ_OUT_DEC,qdct+Q_AVQ_OUT_DEC);*/
308 3370 : Qdct = negate( Qdct );
309 3370 : Copy_Scale_sig_32_16( out32, code_preQ, L_SUBFR, Qdct ); /* Output in Q_AVQ_OUT_DEC */
310 : /*qdct = Q_AVQ_OUT_DEC;*/
311 : }
312 :
313 : /*--------------------------------------------------------------*
314 : * Preemphasise
315 : *--------------------------------------------------------------*/
316 : /* in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */
317 3370 : test();
318 3370 : if ( ( nq[7] != 0 ) && ( GT_16( sub( st_fx->last_nq_preQ, nq[0] ), 7 ) ) )
319 : {
320 : /* *mem_preemp /= 16; */
321 0 : st_fx->mem_preemp_preQ_fx = shr( st_fx->mem_preemp_preQ_fx, 4 );
322 0 : move16();
323 : }
324 3370 : st_fx->last_nq_preQ = nq[7];
325 3370 : move16();
326 :
327 3370 : PREEMPH_FX( code_preQ, FAC_PRE_AVQ_FX, L_SUBFR, &( st_fx->mem_preemp_preQ_fx ) );
328 :
329 : /*--------------------------------------------------------------*
330 : * For inactive segments
331 : * - Zero-memory filtered pre-filter excitation
332 : * - Update of targets and gain_pit
333 : * For inactive segments
334 : * - Update xn[L_subfr-1] for updating the memory of the weighting filter
335 : *--------------------------------------------------------------*/
336 :
337 3370 : IF( EQ_16( st_fx->coder_type, INACTIVE ) )
338 : {
339 : /*ftemp = fcode_preQ[0] *fh1[L_SUBFR-1];*/
340 0 : Ltmp = L_mult( code_preQ[0], h1[L_SUBFR - 1] ); /*1+14+shift + Q_AVQ_OUT */
341 0 : FOR( i = 1; i < L_SUBFR; i++ )
342 : {
343 : /*ftemp += fcode_preQ[i] * fh1[L_SUBFR-1-i];*/
344 0 : Ltmp = L_mac( Ltmp, code_preQ[i], h1[L_SUBFR - 1 - i] );
345 : }
346 : /*fxn[L_SUBFR-1] -= *fgain_preQ * ftemp;*/
347 0 : Ltmp = L_shr( Mult_32_16( Ltmp, *gain_preQ ), sub( add( Q_AVQ_OUT_DEC, 2 ), Q_new ) ); /* (2 + 1 + 14 +shift+Q_AVQ_OUT)-(Q_AVQ_OUT+2-Q_new) = 15 + Q_new + shift */
348 0 : xn[L_SUBFR - 1] = round_fx( L_sub( L_mult( xn[L_SUBFR - 1], 32767 ), Ltmp ) ); /* -> Q_new + shift -1 */
349 : }
350 : ELSE
351 : {
352 3370 : conv_fx( code_preQ, h1, x_tran, L_SUBFR );
353 3370 : updt_tar_HR_fx( cn, cn, code_preQ, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR );
354 :
355 3370 : updt_tar_HR_fx( xn, xn, x_tran, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR );
356 3370 : *gain_pit = corr_xy1_fx( xn, y1, g_corr, L_SUBFR, 0, &Overflow ); /* Q14 */
357 : /* clip gain if necessary to avoid problems at decoder */
358 3370 : test();
359 3370 : if ( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 ) )
360 : {
361 37 : *gain_pit = 15565; /* 0.95 in Q15 */
362 37 : move16();
363 : }
364 3370 : updt_tar_fx( xn, xn2, y1, *gain_pit, L_SUBFR );
365 : }
366 :
367 3370 : st_fx->use_acelp_preq = 1;
368 3370 : move16();
369 :
370 3370 : return;
371 : }
372 70770 : void transf_cdbk_enc_ivas_fx(
373 : Encoder_State *st_fx, /* i/o: encoder state structure */
374 : const Word16 harm_flag_acelp, /* i : harmonic flag for higher rates ACELP Q0*/
375 : const Word16 i_subfr, /* i : subframe index Q0*/
376 : Word16 cn[], /* i/o: target vector in residual domain Q_new*/
377 : Word16 exc[], /* i/o: pointer to excitation signal frame Q_new*/
378 : const Word16 *p_Aq, /* i : 12k8 Lp coefficient Q12*/
379 : const Word16 Ap[], /* i : weighted LP filter coefficients Q12*/
380 : const Word16 h1[], /* i : weighted filter input response Q15*/
381 : Word16 xn[], /* i/o: target vector Q_new + shift -1*/
382 : Word16 xn2[], /* i/o: target vector for innovation search Q_new + shift -1*/
383 : Word16 y1[], /* i/o: zero-memory filtered adaptive excitation Q_new + shift -1*/
384 : const Word16 y2[], /* i : zero-memory filtered innovative excitation Q9*/
385 : const Word16 Es_pred, /* i : predicited scaled innovation energy Q8*/
386 : Word16 *gain_pit, /* i/o: adaptive excitation gain Q14*/
387 : const Word32 gain_code, /* i : innovative excitation gain Q16*/
388 : Word16 g_corr[], /* o : ACELP correlation values Q15*/
389 : const Word16 clip_gain, /* i : adaptive gain clipping flag Q0*/
390 : Word16 *gain_preQ, /* o : prequantizer excitation gain Q2*/
391 : Word16 code_preQ[], /* o : prequantizer excitation Q_AVQ_OUT_DEC*/
392 : Word16 *unbits, /* o : number of AVQ unused bits Q0*/
393 : const Word16 Q_new, /* i : Current frame scaling */
394 : const Word16 shift /* i : shifting applied to y1, xn,... */
395 : )
396 : {
397 : Word16 i, index, nBits, Nsv, Es_pred_loc;
398 : Word16 x_in[L_SUBFR], x_tran[L_SUBFR], gcode16, stmp;
399 : Word16 e_corr, m_corr, e_ener, m_ener, m_den, e_den;
400 : Word16 x_norm[L_SUBFR + L_SUBFR / WIDTH_BAND];
401 : Word32 L_corr, L_ener, Ltmp, Ltmp1;
402 : Word16 nq[L_SUBFR / WIDTH_BAND];
403 : Word32 out32[L_SUBFR];
404 : Word16 Qdct;
405 : Word16 avq_bit_sFlag;
406 : Word16 trgtSvPos;
407 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
408 70770 : Flag Overflow = 0;
409 70770 : move32();
410 : #endif
411 :
412 70770 : avq_bit_sFlag = 0;
413 70770 : move16();
414 70770 : if ( st_fx->element_mode > EVS_MONO )
415 : {
416 70770 : avq_bit_sFlag = 1;
417 70770 : move16();
418 : }
419 :
420 : /*--------------------------------------------------------------*
421 : * Set bit-allocation
422 : *--------------------------------------------------------------*/
423 :
424 70770 : Nsv = 8;
425 70770 : move16();
426 70770 : nBits = st_fx->acelp_cfg.AVQ_cdk_bits[i_subfr >> 6]; /* Q0 */
427 70770 : move16();
428 :
429 : /* increase # of AVQ allocated bits by unused bits from the previous subframe */
430 70770 : nBits = add( nBits, *unbits );
431 :
432 : /*--------------------------------------------------------------*
433 : * Compute/Update target
434 : * For inactive frame, find target in residual domain
435 : * Deemphasis
436 : *--------------------------------------------------------------*/
437 70770 : IF( EQ_16( st_fx->coder_type, INACTIVE ) )
438 : {
439 13015 : gcode16 = round_fx_o( L_shl_o( gain_code, Q_new, &Overflow ), &Overflow );
440 845975 : FOR( i = 0; i < L_SUBFR; i++ )
441 : {
442 : /*x_tran[i] = xn[i] - *gain_pit * y1[i] - gain_code * y2[i];*/
443 832960 : Ltmp = L_mult( gcode16, y2[i] );
444 832960 : Ltmp = L_shl( Ltmp, add( 5, shift ) );
445 832960 : Ltmp = L_negate( Ltmp );
446 832960 : Ltmp = L_mac( Ltmp, xn[i], 16384 );
447 832960 : Ltmp = L_msu( Ltmp, y1[i], *gain_pit ); /* Q_new + 14 + shift */
448 832960 : Ltmp = L_shl_sat( Ltmp, sub( 1, shift ) ); /* Q_new + 15 */
449 832960 : x_tran[i] = round_fx_sat( Ltmp ); /*Q_new-1 */
450 : }
451 13015 : find_cn_fx( x_tran, Ap, p_Aq, x_in );
452 : }
453 : ELSE
454 : {
455 57755 : updt_tar_fx( cn, x_in, &exc[i_subfr], *gain_pit, L_SUBFR );
456 : }
457 70770 : Deemph2( x_in, FAC_PRE_AVQ_FX, L_SUBFR, &( st_fx->mem_deemp_preQ_fx ) );
458 :
459 : /*--------------------------------------------------------------*
460 : * DCT-II
461 : *--------------------------------------------------------------*/
462 :
463 70770 : test();
464 70770 : test();
465 70770 : test();
466 70770 : IF( NE_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && !harm_flag_acelp )
467 : {
468 41265 : Copy_Scale_sig( x_in, x_tran, L_SUBFR, -Q_MINUS + 1 ); /*Q_new-1 -> Q_new-4*/
469 : /*Copy( x_in, x_tran, L_SUBFR );*/
470 41265 : Qdct = sub( Q_new, Q_MINUS );
471 : }
472 : ELSE
473 : {
474 29505 : Qdct = 0;
475 29505 : move16();
476 29505 : edct2_fx( L_SUBFR, -1, x_in, out32, &Qdct, ip_edct2_64, w_edct2_64_fx );
477 29505 : Qdct = negate( Qdct );
478 29505 : Copy_Scale_sig_32_16( out32, x_tran, L_SUBFR, sub( Qdct, Q_MINUS - 1 ) ); /* Output in Q_new-4 */
479 29505 : Qdct = sub( Q_new, Q_MINUS );
480 : }
481 :
482 : /*--------------------------------------------------------------*
483 : * Split algebraic vector quantizer based on RE8 lattice
484 : *--------------------------------------------------------------*/
485 70770 : AVQ_cod_fx( x_tran, x_norm, nBits, Nsv, 0 );
486 :
487 : /*--------------------------------------------------------------*
488 : * Find prequantizer excitation gain
489 : * Quantize the gain
490 : *--------------------------------------------------------------*/
491 70770 : L_corr = L_deposit_l( 0 );
492 70770 : L_ener = L_deposit_l( 0 );
493 4600050 : FOR( i = 0; i < Nsv * 8; i++ )
494 : {
495 : /*fcorr += fx_tran[i]*(float)ix_norm[i];*/
496 : /*fener += (float)ix_norm[i]*(float)ix_norm[i];*/
497 4529280 : stmp = shl_sat( x_norm[i], Q_AVQ_OUT );
498 4529280 : L_corr = L_mac_sat( L_corr, x_tran[i], stmp );
499 4529280 : L_ener = L_mac_sat( L_ener, stmp, stmp );
500 : }
501 70770 : L_ener = L_max( L_ener, 1 );
502 :
503 : /* No negative gains allowed in the quantizer*/
504 70770 : L_corr = L_max( L_corr, 0 );
505 :
506 70770 : e_corr = norm_l( L_corr );
507 70770 : m_corr = extract_h( L_shl( L_corr, e_corr ) );
508 70770 : e_corr = sub( 30, add( e_corr, sub( Qdct, Q_AVQ_OUT ) ) );
509 70770 : e_ener = norm_l( L_ener );
510 70770 : m_ener = extract_h( L_shl( L_ener, e_ener ) ); /* 30 - e-ener */
511 70770 : e_ener = sub( 30, e_ener );
512 :
513 70770 : IF( GT_16( m_corr, m_ener ) )
514 : {
515 40866 : m_corr = shr( m_corr, 1 ); /* e_corr + 1 */
516 40866 : e_corr = add( e_corr, 1 );
517 : }
518 70770 : m_corr = div_s( m_corr, m_ener ); /* e_corr - e_ener */
519 70770 : e_corr = sub( e_corr, e_ener );
520 70770 : Ltmp = L_shl_sat( m_corr, s_min( add( e_corr, 1 ), 31 ) ); /* Lgain in Q16 */
521 70770 : IF( EQ_16( st_fx->coder_type, INACTIVE ) )
522 : {
523 13015 : Ltmp1 = L_max( gain_code, 1 );
524 13015 : e_den = norm_l( Ltmp1 );
525 13015 : m_den = extract_h( L_shl_sat( Ltmp1, e_den ) );
526 : /* ensure m_corr < m_den */
527 13015 : test();
528 13015 : IF( m_corr > 0 && m_den > 0 )
529 : {
530 13015 : m_corr = div_s( 16384, m_den );
531 13015 : e_corr = sub( 14 + 4, e_den );
532 13015 : Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); /*Q12*/
533 13015 : stmp = round_fx_o( L_shl_o( Ltmp, 16, &Overflow ), &Overflow ); /* Q12 */
534 : }
535 : ELSE
536 : {
537 0 : stmp = 0;
538 0 : move16();
539 : }
540 13015 : IF( GT_32( st_fx->core_brate, 56000 ) )
541 : {
542 0 : index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_64k_Q12, G_AVQ_DELTA_INACT_64k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */
543 : }
544 13015 : ELSE IF( GT_32( st_fx->core_brate, 42000 ) )
545 : {
546 1570 : index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_48k_Q12, G_AVQ_DELTA_INACT_48k_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */
547 : }
548 : ELSE
549 : {
550 11445 : index = usquant_fx( stmp, &stmp, G_AVQ_MIN_INACT_Q12, G_AVQ_DELTA_INACT_Q12 >> 1, ( 1 << G_AVQ_BITS ) ); /* Q0 */
551 : }
552 13015 : Ltmp = Mult_32_16( gain_code, stmp ); /* Q16 * Q12 - 15 -> Q13*/
553 13015 : Ltmp = L_shl_sat( Ltmp, 5 ); /* Q13 -> Q18*/
554 13015 : *gain_preQ = round_fx_sat( Ltmp ); /* Q2*/
555 13015 : move16();
556 : }
557 : ELSE
558 : {
559 57755 : IF( Es_pred < 0 )
560 : {
561 160 : Es_pred_loc = shr( negate( Es_pred ), 2 );
562 : }
563 : ELSE
564 : {
565 57595 : Es_pred_loc = Es_pred;
566 57595 : move16();
567 : }
568 :
569 57755 : e_den = norm_s( Es_pred_loc );
570 57755 : m_den = shl( Es_pred_loc, e_den );
571 : /* ensure m_corr < m_den */
572 57755 : test();
573 57755 : IF( m_corr > 0 && m_den > 0 )
574 : {
575 56948 : m_corr = div_s( 16384, m_den );
576 56948 : e_corr = sub( 14 - 8, e_den );
577 56948 : Ltmp = L_shr( Mult_32_16( Ltmp, m_corr ), e_corr ); /* Q16 */
578 : }
579 : ELSE
580 : {
581 807 : Ltmp = L_deposit_l( 0 );
582 : }
583 57755 : test();
584 57755 : IF( LE_32( st_fx->core_brate, 42000 ) && GT_32( st_fx->core_brate, ACELP_24k40 ) )
585 : {
586 52040 : index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_32kbps_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); /* Q0 */
587 : }
588 : ELSE
589 : {
590 5715 : index = gain_quant_fx( &Ltmp, &stmp, LG10_G_AVQ_MIN_Q14, LG10_G_AVQ_MAX_Q13, G_AVQ_BITS, &e_den ); /* Q0 */
591 : }
592 57755 : Ltmp = L_mult( stmp, Es_pred_loc ); /* Q0*Q8 -> Q9*/
593 57755 : Ltmp = L_shl( Ltmp, add( e_den, 9 ) ); /* Q18*/
594 57755 : *gain_preQ = round_fx( Ltmp ); /* Q2*/
595 57755 : move16();
596 : }
597 70770 : push_indice( st_fx->hBstr, IND_AVQ_GAIN, index, G_AVQ_BITS );
598 :
599 : /*--------------------------------------------------------------*
600 : * Encode and multiplex subvectors into bit-stream
601 : *--------------------------------------------------------------*/
602 70770 : trgtSvPos = sub( Nsv, 1 );
603 70770 : move16();
604 70770 : test();
605 70770 : test();
606 70770 : test();
607 70770 : test();
608 70770 : test();
609 70770 : IF( avq_bit_sFlag && GT_16( nBits, 85 ) && !harm_flag_acelp && ( EQ_16( st_fx->coder_type, GENERIC ) || EQ_16( st_fx->coder_type, TRANSITION ) || EQ_16( st_fx->coder_type, INACTIVE ) ) )
610 : {
611 20080 : trgtSvPos = 2;
612 20080 : avq_bit_sFlag = 2;
613 20080 : move16();
614 20080 : move16();
615 : }
616 :
617 70770 : AVQ_encmux_ivas_fx( st_fx->hBstr, -1, x_norm, &nBits, Nsv, nq, avq_bit_sFlag, trgtSvPos );
618 :
619 : /* save # of AVQ unused bits for next subframe */
620 70770 : *unbits = nBits;
621 70770 : move16();
622 :
623 : /* at the last subframe, write AVQ unused bits */
624 70770 : test();
625 70770 : test();
626 70770 : IF( EQ_16( i_subfr, 4 * L_SUBFR ) && NE_16( st_fx->extl, SWB_BWE_HIGHRATE ) && NE_16( st_fx->extl, FB_BWE_HIGHRATE ) )
627 : {
628 26622 : WHILE( *unbits > 0 )
629 : {
630 12468 : i = s_min( *unbits, 16 );
631 12468 : push_indice( st_fx->hBstr, IND_UNUSED, 0, i );
632 12468 : *unbits = sub( *unbits, i );
633 12468 : move16();
634 : }
635 : }
636 :
637 : /*--------------------------------------------------------------*
638 : * DCT transform
639 : *--------------------------------------------------------------*/
640 :
641 4600050 : FOR( i = 0; i < Nsv * WIDTH_BAND; i++ )
642 : {
643 4529280 : x_tran[i] = shl_o( x_norm[i], Q_AVQ_OUT_DEC, &Overflow );
644 4529280 : move16();
645 : }
646 70770 : set16_fx( x_tran + Nsv * WIDTH_BAND, 0, sub( L_SUBFR, i_mult2( WIDTH_BAND, Nsv ) ) );
647 :
648 70770 : test();
649 70770 : test();
650 70770 : test();
651 70770 : IF( NE_16( st_fx->coder_type, INACTIVE ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && !harm_flag_acelp )
652 : {
653 41265 : Copy( x_tran, code_preQ, L_SUBFR ); /* Q_AVQ_OUT_DEC */
654 : }
655 : ELSE
656 : {
657 29505 : Qdct = 0;
658 29505 : move16();
659 29505 : edct2_fx( L_SUBFR, 1, x_tran, out32, &Qdct, ip_edct2_64, w_edct2_64_fx );
660 : /*qdct = sub(Q_AVQ_OUT_DEC,qdct+Q_AVQ_OUT_DEC);*/
661 29505 : Qdct = negate( Qdct );
662 29505 : Copy_Scale_sig_32_16( out32, code_preQ, L_SUBFR, Qdct ); /* Output in Q_AVQ_OUT_DEC */
663 : /*qdct = Q_AVQ_OUT_DEC;*/
664 : }
665 :
666 : /*--------------------------------------------------------------*
667 : * Preemphasise
668 : *--------------------------------------------------------------*/
669 : /* in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */
670 70770 : test();
671 70770 : if ( ( nq[7] != 0 ) && ( GT_16( sub( st_fx->last_nq_preQ, nq[0] ), 7 ) ) )
672 : {
673 : /* *mem_preemp /= 16; */
674 1 : st_fx->mem_preemp_preQ_fx = shr( st_fx->mem_preemp_preQ_fx, 4 );
675 1 : move16();
676 : }
677 70770 : st_fx->last_nq_preQ = nq[7];
678 70770 : move16();
679 :
680 : /* TD pre-quantizer: in extreme cases at subframe boundaries, lower the preemphasis memory to avoid a saturation */
681 70770 : test();
682 70770 : test();
683 70770 : test();
684 70770 : test();
685 70770 : test();
686 70770 : IF( GT_16( st_fx->element_mode, EVS_MONO ) && NE_16( st_fx->coder_type, INACTIVE ) && GE_32( st_fx->core_brate, MIN_BRATE_AVQ_EXC ) && LE_32( st_fx->core_brate, MAX_BRATE_AVQ_EXC_TD ) && !harm_flag_acelp && code_preQ[0] != 0 )
687 : {
688 18410 : IF( GT_16( abs_s( st_fx->last_code_preq ), shl_sat( abs_s( code_preQ[0] ), 4 ) ) )
689 : {
690 0 : st_fx->mem_preemp_preQ_fx = shr( st_fx->mem_preemp_preQ_fx, 4 );
691 0 : move16();
692 : }
693 18410 : ELSE IF( GT_16( abs_s( st_fx->last_code_preq ), shl_sat( abs_s( code_preQ[0] ), 3 ) ) )
694 : {
695 0 : st_fx->mem_preemp_preQ_fx = shr( st_fx->mem_preemp_preQ_fx, 3 );
696 0 : move16();
697 : }
698 : }
699 :
700 70770 : st_fx->last_code_preq = shr( code_preQ[L_SUBFR - 1], 9 ); // Q0
701 70770 : move16();
702 :
703 70770 : PREEMPH_FX( code_preQ, FAC_PRE_AVQ_FX, L_SUBFR, &( st_fx->mem_preemp_preQ_fx ) );
704 :
705 : /*--------------------------------------------------------------*
706 : * For inactive segments
707 : * - Zero-memory filtered pre-filter excitation
708 : * - Update of targets and gain_pit
709 : * For inactive segments
710 : * - Update xn[L_subfr-1] for updating the memory of the weighting filter
711 : *--------------------------------------------------------------*/
712 :
713 70770 : IF( EQ_16( st_fx->coder_type, INACTIVE ) )
714 : {
715 : /*ftemp = fcode_preQ[0] *fh1[L_SUBFR-1];*/
716 13015 : Ltmp = L_mult( code_preQ[0], h1[L_SUBFR - 1] ); /*1+14+shift + Q_AVQ_OUT */
717 832960 : FOR( i = 1; i < L_SUBFR; i++ )
718 : {
719 : /*ftemp += fcode_preQ[i] * fh1[L_SUBFR-1-i];*/
720 819945 : Ltmp = L_mac( Ltmp, code_preQ[i], h1[L_SUBFR - 1 - i] );
721 : }
722 : /*fxn[L_SUBFR-1] -= *fgain_preQ * ftemp;*/
723 13015 : Ltmp = L_shr( Mult_32_16( Ltmp, *gain_preQ ), sub( add( Q_AVQ_OUT_DEC, 2 ), Q_new ) ); /* (2 + 1 + 14 +shift+Q_AVQ_OUT)-(Q_AVQ_OUT+2-Q_new) = 15 + Q_new + shift */
724 13015 : xn[L_SUBFR - 1] = round_fx( L_sub( L_mult( xn[L_SUBFR - 1], 32767 ), Ltmp ) ); /* -> Q_new + shift -1 */
725 : }
726 : ELSE
727 : {
728 57755 : conv_fx( code_preQ, h1, x_tran, L_SUBFR );
729 57755 : updt_tar_HR_fx( cn, cn, code_preQ, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR );
730 :
731 57755 : updt_tar_HR_fx( xn, xn, x_tran, *gain_preQ, sub( Q_new, add( -15 + 2, Q_AVQ_OUT_DEC ) ), L_SUBFR );
732 57755 : *gain_pit = corr_xy1_fx( xn, y1, g_corr, L_SUBFR, 0, &Overflow ); /* Q14 */
733 57755 : move16();
734 : /* clip gain if necessary to avoid problems at decoder */
735 57755 : test();
736 57755 : if ( EQ_16( clip_gain, 1 ) && GT_16( *gain_pit, 15565 ) )
737 : {
738 50 : *gain_pit = 15565; /* 0.95 in Q14 */
739 50 : move16();
740 : }
741 57755 : updt_tar_fx( xn, xn2, y1, *gain_pit, L_SUBFR );
742 : }
743 :
744 70770 : st_fx->use_acelp_preq = 1;
745 70770 : move16();
746 :
747 70770 : return;
748 : }
749 : /*-------------------------------------------------------------------*
750 : * Find target in residual domain - cn[]
751 : *-------------------------------------------------------------------*/
752 :
753 13015 : static void find_cn_fx(
754 : const Word16 xn[], /* i : target signal Qx*/
755 : const Word16 Ap[], /* i : weighted LP filter coefficients Q12*/
756 : const Word16 *p_Aq, /* i : 12k8 LP coefficients Q12*/
757 : Word16 cn[] /* o : target signal in residual domain Qx*/
758 : )
759 : {
760 : Word16 tmp, tmp_fl[L_SUBFR + M];
761 :
762 13015 : set16_fx( tmp_fl, 0, M );
763 13015 : Copy( xn, tmp_fl + M, L_SUBFR ); /* Qx */
764 13015 : tmp = 0;
765 13015 : move16();
766 13015 : PREEMPH_FX( tmp_fl + M, PREEMPH_FAC_16k, L_SUBFR, &tmp );
767 13015 : syn_filt_s_lc_fx( 0, Ap, tmp_fl + M, tmp_fl + M, L_SUBFR );
768 13015 : Residu3_lc_fx( p_Aq, M, tmp_fl + M, cn, L_SUBFR, 1 );
769 :
770 13015 : return;
771 : }
772 :
773 :
774 : /*-----------------------------------------------------------------*
775 : * Transform domain contribution encoding
776 : *-----------------------------------------------------------------*/
777 114293 : Word16 gain_quant_fx( /* o: quantization index Q0*/
778 : Word32 *gain, /* i: quantized gain Q16*/
779 : Word16 *gain16, /* o: quantized gain expg*/
780 : const Word16 c_min, /* i: log10 of lower limit in Q14*/
781 : const Word16 c_max, /* i: log10 of upper limit in Q13*/
782 : const Word16 bits, /* i: number of bits to quantize Q0*/
783 : Word16 *expg /* o: output exponent of gain16 */
784 : )
785 : {
786 : Word16 index, levels;
787 : Word16 c_gain;
788 : Word16 e_tmp, f_tmp, exp;
789 : Word16 tmp, tmp1, tmp2, frac;
790 : Word32 L_tmp;
791 :
792 114293 : levels = shl( 1, bits );
793 : /* Prevent gain to be smaller than 0.0003. */
794 : /* This is to avoid an overflow when the gain is very small */
795 : /* the log10 give a high negative value in Q13 that overflow */
796 : /* on this code (the resulting value of 'index' is not affected. */
797 : /* tmp2 = msu_r(L_deposit_h(c_gain),c_min,16384) */
798 114293 : L_tmp = L_max( *gain, 20 );
799 :
800 : /*c_min = (float)log10(min);*/
801 : /*c_mult = (float) ((levels-1)/(log10(max)-c_min));*/
802 :
803 : /*tmp = c_mult * ((float)log10(*gain) - c_min);
804 : = ((levels-1)/(log10(max)-log10(min)))*((float)log10(*gain) - log10(min));*/
805 :
806 114293 : e_tmp = norm_l( L_tmp );
807 114293 : f_tmp = Log2_norm_lc( L_shl( L_tmp, e_tmp ) );
808 114293 : e_tmp = sub( 30 - 16, e_tmp ); /*Q(min)=16*/
809 114293 : L_tmp = Mpy_32_16( e_tmp, f_tmp, 9864 ); /* Q16 */ /*log10(2) in Q15*/
810 114293 : c_gain = round_fx( L_shl( L_tmp, 13 ) ); /* Q13 */
811 :
812 : /*tmp1 = sub(c_max,c_min); Q14*/
813 : /*tmp2 = sub(c_gain,c_min); Q14*/
814 :
815 114293 : tmp1 = msu_r_sat( L_deposit_h( c_max /*in Q13 already*/ ), c_min, 16384 ); /*Q13*/
816 114293 : tmp2 = msu_r_sat( L_deposit_h( c_gain /*in Q13 already*/ ), c_min, 16384 ); /*Q13*/
817 114293 : IF( tmp1 != 0 )
818 : {
819 114293 : exp = norm_s( tmp1 );
820 114293 : frac = div_s( shl( 1, sub( 14, exp ) ), tmp1 ); /*Q(15-exp)*/
821 114293 : L_tmp = L_mult( tmp2, frac ); /*Q(30-exp)*/
822 114293 : L_tmp = Mult_32_16( L_tmp, sub( levels, 1 ) ); /*Q(15-exp)*/
823 114293 : index = extract_l( L_shr( L_add( L_tmp, shr( 1 << 14, exp ) ), sub( 15, exp ) ) ); /* Q0 */
824 : }
825 : ELSE
826 : {
827 0 : L_tmp = L_mult( tmp2, sub( levels, 1 ) ); /*Q15*/
828 0 : index = extract_l( L_shr( L_add( L_tmp, 1 << 14 ), 15 ) ); /* Q0 */
829 : }
830 :
831 114293 : index = s_max( index, 0 );
832 114293 : index = s_min( index, sub( levels, 1 ) );
833 :
834 : /**gain = (float)pow( 10.0, (((float)index)/c_mult) + c_min );
835 : y = index/c_mult + c_min;
836 : = (index/(levels-1))*(log10(max) - log10(min)) + log10(min);
837 : = z*log10(max) + (1-z)*log10(min)
838 : z = (index/(levels-1))*/
839 114293 : tmp = div_s( index, sub( levels, 1 ) ); /*Q15*/
840 114293 : L_tmp = L_mult( tmp, c_max ); /*Q29*/
841 114293 : L_tmp = L_mac0( L_tmp, sub( 32767, tmp ), c_min ); /*Q29*/
842 :
843 114293 : L_tmp = Mult_32_16( L_tmp, 27213 ); /*Q27, 3.321928 in Q13*/
844 114293 : L_tmp = L_shr( L_tmp, 11 ); /*Q27->Q16*/
845 :
846 114293 : frac = L_Extract_lc( L_tmp, expg ); /* Extract exponent of gcode0 */
847 :
848 114293 : *gain16 = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
849 : /* output of Pow2() will be: */
850 : /* 16384 < Pow2() <= 32767 */
851 114293 : *expg = sub( *expg, 14 );
852 114293 : move16();
853 :
854 114293 : return ( index );
855 : }
|