Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 :
6 : #include <stdint.h>
7 : #include "options.h"
8 : #include "cnst.h"
9 : #include "prot_fx.h" /* Function prototypes */
10 : #include "prot_fx_enc.h" /* Function prototypes */
11 : #include "stat_enc.h"
12 : #include "basop_util.h"
13 :
14 :
15 : /*-------------------------------------------------------------------*
16 : * coderLookAheadInnovation()
17 : *
18 : *
19 : *-------------------------------------------------------------------*/
20 315 : static void coderLookAheadInnovation(
21 : Word16 A_3Q12[], /* input: coefficients NxAz[M+1] Q12*/
22 : Word16 *pT, /* out: pitch Q0*/
23 : PLC_ENC_EVS_HANDLE st, /* i/o: coder memory state */
24 : Word16 *speechLookAhead_Qx, /* i: input speech in Q(st->Qold) */
25 : Word16 *old_exc, /* i: input excitation in Q(st->Qold) */
26 : Word16 L_frame )
27 : {
28 : Word16 i;
29 : Word16 prev_pitch, T0_fx;
30 : Word16 *exc_Qx, exc_buf_Qx[L_EXC_MEM + 2 * L_SUBFR + 8];
31 315 : Word32 mantissa_max = -0x7fffffffL;
32 315 : Word16 subfr_len = 0;
33 315 : Word16 search_range = 9;
34 : Word16 exc_max;
35 : Word16 exc_sh;
36 : Word32 ps, alp, alp_ini;
37 : Word32 alp_s1, alp_s2;
38 : Word16 k;
39 : Word16 ps_e, alp_e;
40 : Word32 max_ps, max_ps_tmp;
41 : Word16 max_ps_e;
42 : Word16 tmp_loop;
43 315 : move32();
44 315 : move16();
45 315 : move16();
46 :
47 : /* Debug init (not instrumented) */
48 315 : T0_fx = -3000;
49 315 : move16();
50 315 : subfr_len = shl( L_SUBFR, 1 ); /* 2*L_SUBFR */
51 315 : if ( GT_16( L_FRAME16k, L_frame ) )
52 : {
53 0 : subfr_len = add( L_SUBFR, 48 ); /* 1.75*L_SUBFR */
54 : }
55 315 : set16_fx( exc_buf_Qx, 0, L_EXC_MEM + 2 * L_SUBFR + 8 );
56 :
57 : /*------------------------------------------------------------------------*
58 : * - BASOP specific initialization. *
59 : *------------------------------------------------------------------------*/
60 : /* initialization */
61 315 : exc_Qx = exc_buf_Qx + L_EXC_MEM + 8; /* Q(st->Qold) */
62 103635 : FOR( i = 0; i < L_EXC_MEM + 8; i++ )
63 : {
64 103320 : exc_buf_Qx[i] = old_exc[i]; /* Q(st->Qold) */
65 103320 : move16();
66 : }
67 :
68 :
69 : /*------------------------------------------------------------------------*
70 : * - Get residual signal and target at lookahead part. *
71 : *------------------------------------------------------------------------*/
72 : /* find LP residual signal for look-ahead part */
73 315 : getLookAheadResSig( speechLookAhead_Qx, A_3Q12, exc_Qx, L_frame, 2 );
74 315 : Scale_sig( exc_Qx, subfr_len, 1 ); /* Q(st->Qold) + 1 */
75 :
76 : /* find target signals */
77 315 : prev_pitch = st->T0_4th; /* Q0 */
78 315 : move16();
79 : /* find best candidate of pitch lag */
80 315 : T0_fx = st->T0_4th; /* Q0 */
81 315 : move16();
82 315 : mantissa_max = -0x7fffffffL; /* Q15 */
83 315 : move32();
84 315 : max_ps = -0x7fffffffL; /* Q15 */
85 315 : move32();
86 315 : max_ps_e = 16;
87 315 : move16();
88 :
89 : /*find maximum*/
90 315 : exc_max = 0;
91 315 : move16();
92 315 : tmp_loop = s_min( -prev_pitch + search_range + subfr_len, 0 ); /* Q0 */
93 29486 : FOR( i = -prev_pitch - search_range; i < tmp_loop; i++ )
94 : {
95 29171 : exc_max = s_max( exc_Qx[i], exc_max ); /* Q(st->Qold) + 1 */
96 : }
97 40635 : FOR( i = 0; i < subfr_len; i++ )
98 : {
99 40320 : exc_max = s_max( exc_max, exc_Qx[i] ); /* Q(st->Qold) + 1 */
100 : }
101 : /*calculate scaling factor for optimal precision and assure no overflow in dotproduct*/
102 315 : exc_sh = sub( 15, norm_s( sub( subfr_len, 1 ) ) ); /*ceil(ld(subfr_len))*/
103 315 : exc_sh = s_max( sub( exc_sh, norm_s( s_max( abs_s( exc_max ), 1 ) ) ), 0 );
104 315 : exc_sh = shr( add( exc_sh, 1 ), 1 );
105 :
106 : /*scale buffer only where its needed*/
107 315 : tmp_loop = s_min( -prev_pitch + search_range + subfr_len, 0 ); /* Q0 */
108 29486 : FOR( i = -prev_pitch - search_range; i < tmp_loop; i++ )
109 : {
110 29171 : exc_Qx[i] = shr( exc_Qx[i], exc_sh ); /* Q(st->Qold) + 1 */
111 29171 : move16();
112 : }
113 40635 : FOR( i = 0; i < subfr_len; i++ )
114 : {
115 40320 : exc_Qx[i] = shr( exc_Qx[i], exc_sh ); /* Q(st->Qold) + 1 */
116 40320 : move16();
117 : }
118 :
119 : /*Calculate "big" dotproduct from buffer, including search range*/
120 315 : alp_ini = L_deposit_l( 0 );
121 315 : move16();
122 46305 : FOR( i = -prev_pitch - search_range; i < -prev_pitch + search_range + subfr_len; i++ )
123 : {
124 45990 : alp_ini = L_mac( alp_ini, exc_Qx[i], exc_Qx[i] ); /* 2*(Q(st->Qold) + 1) + 1 */
125 : }
126 :
127 5985 : FOR( i = -search_range; i < search_range; i++ )
128 : {
129 5670 : test();
130 5670 : IF( GT_16( add( prev_pitch, i ), st->pit_max ) || LT_16( add( prev_pitch, i ), st->pit_min ) )
131 : {
132 36 : CONTINUE;
133 : }
134 5634 : ps = L_deposit_l( 0 );
135 5634 : alp_s1 = L_deposit_l( 0 );
136 5634 : alp_s2 = L_deposit_l( 0 );
137 :
138 726786 : FOR( k = 0; k < subfr_len; k++ )
139 : {
140 721152 : ps = L_mac( ps, exc_Qx[k], exc_Qx[k - prev_pitch - i] ); /* 2*(Q(st->Qold) + 1) + 1 */
141 : }
142 :
143 : /*calculate "small" dotproducts in order to subtract them from the "bigger" one*/
144 58908 : FOR( k = -( ( prev_pitch + search_range ) ); k < -prev_pitch - i; k++ )
145 : {
146 53274 : alp_s1 = L_mac( alp_s1, exc_Qx[k], exc_Qx[k] ); /* 2*(Q(st->Qold) + 1) + 1 */
147 : }
148 5634 : tmp_loop = sub( add( search_range, subfr_len ), prev_pitch );
149 53772 : FOR( k = +subfr_len - i - prev_pitch; k < tmp_loop; k++ )
150 : {
151 48138 : alp_s2 = L_mac( alp_s2, exc_Qx[k], exc_Qx[k] ); /* 2*(Q(st->Qold) + 1) + 1 */
152 : }
153 5634 : alp = L_sub( alp_ini, L_add( alp_s1, alp_s2 ) );
154 5634 : alp = L_max( alp, 1 ); /* alp must not be 0 */
155 5634 : alp_e = shl( exc_sh, 1 );
156 5634 : ps_e = shl( exc_sh, 1 );
157 5634 : alp = ISqrt32( alp, &alp_e ); /* Q31-alp_e */
158 5634 : ps = Mpy_32_16_1( ps, round_fx( alp ) ); /*alp_e+ps_e*/
159 :
160 5634 : ps_e = add( alp_e, ps_e );
161 :
162 : BASOP_SATURATE_WARNING_OFF_EVS
163 5634 : max_ps_tmp = L_shl_sat( max_ps, sub( max_ps_e, ps_e ) );
164 : BASOP_SATURATE_WARNING_ON_EVS
165 :
166 5634 : IF( LT_32( max_ps_tmp, ps ) )
167 : {
168 1418 : max_ps = L_add( ps, 0 );
169 1418 : max_ps_e = ps_e;
170 1418 : move16();
171 1418 : T0_fx = add( prev_pitch, i );
172 : }
173 : }
174 315 : mantissa_max = max_ps; /* Q31-ps_e */
175 315 : move32();
176 315 : if ( mantissa_max < 0 )
177 : {
178 0 : T0_fx = st->T0_4th;
179 0 : move16();
180 : }
181 :
182 : /* Update excitation */
183 315 : pT[0] = T0_fx;
184 315 : move16();
185 :
186 315 : return;
187 : }
188 :
189 : /************************************************************/
190 : /* Static functions */
191 : /************************************************************/
192 : /*-------------------------------------------------------------------*
193 : * enc_prm_side_Info_fx()
194 : *
195 : *
196 : *-------------------------------------------------------------------*/
197 984 : void enc_prm_side_Info_fx(
198 : PLC_ENC_EVS_HANDLE hPlc_Ext,
199 : Encoder_State *st )
200 : {
201 : Word16 diff_pitch;
202 : Word16 bits_per_subfr, search_range;
203 :
204 984 : bits_per_subfr = 4;
205 984 : move16();
206 984 : search_range = 8;
207 984 : move16();
208 :
209 984 : IF( GT_16( hPlc_Ext->nBits, 1 ) )
210 : {
211 :
212 437 : push_next_indice( st->hBstr, 1, 1 );
213 :
214 437 : diff_pitch = sub( hPlc_Ext->T0, hPlc_Ext->T0_4th );
215 437 : test();
216 437 : if ( ( GT_16( diff_pitch, sub( search_range, 1 ) ) ) || ( LT_16( diff_pitch, add( -search_range, 1 ) ) ) )
217 : {
218 15 : diff_pitch = -8;
219 15 : move16();
220 : }
221 :
222 437 : push_next_indice( st->hBstr, add( diff_pitch, search_range ), bits_per_subfr );
223 : }
224 : ELSE
225 : {
226 547 : push_next_indice( st->hBstr, 0, 1 );
227 : }
228 :
229 984 : return;
230 : }
231 :
232 : /*-------------------------------------------------------------------*
233 : * encoderSideLossSimulation_fx()
234 : *
235 : * Encoder side loss simulation
236 : *-------------------------------------------------------------------*/
237 1246 : void encoderSideLossSimulation_fx(
238 : Encoder_State *st,
239 : PLC_ENC_EVS_HANDLE hPlc_Ext,
240 : Word16 *lsf_q, /* Qx2.56 */
241 : const Word16 stab_fac, /* Q15 */
242 : const Word16 calcOnlyISF, /* Q0 */
243 : const Word16 L_frame )
244 : {
245 : Word16 lspLocal_Q15[M];
246 : Word16 const *xsfBase; /* base for differential XSF coding */
247 :
248 :
249 : /* Decoder State Update */
250 1246 : IF( EQ_16( L_frame, L_FRAME_16k ) )
251 : {
252 984 : lsf2lsp_fx( lsf_q, lspLocal_Q15, M, INT_FS_16k_FX ); /* Q15 */
253 : }
254 : ELSE
255 : {
256 262 : lsf2lsp_fx( lsf_q, lspLocal_Q15, M, INT_FS_FX ); /* Q15 */
257 : }
258 :
259 :
260 1246 : xsfBase = PlcGetLsfBase( st->lpcQuantization,
261 1246 : st->narrowBand,
262 : st->sr_core );
263 :
264 1246 : Copy( st->mem_MA_fx, hPlc_Ext->mem_MA_14Q1, M ); /* Qx2.56 */
265 1246 : Copy( st->mem_AR_fx, hPlc_Ext->mem_AR, M ); /* Qx2.56 */
266 :
267 :
268 : /* ISF parameter processing for concealment */
269 1246 : updateLSFForConcealment( hPlc_Ext, lsf_q );
270 1246 : hPlc_Ext->stab_fac_Q15 = stab_fac;
271 1246 : move16();
272 :
273 1246 : Copy( lsf_q, hPlc_Ext->lsfold_14Q1, M ); /* Qx2.56 */
274 1246 : Copy( lspLocal_Q15, hPlc_Ext->lspold_Q15, M ); /* Q15 */
275 :
276 :
277 1246 : IF( calcOnlyISF != 0 )
278 : {
279 : /* ISF concealment simulation */
280 931 : getConcealedLSF( hPlc_Ext, xsfBase, st->clas, L_frame );
281 931 : hPlc_Ext->T0 = hPlc_Ext->T0_4th; /* Q0 */
282 931 : move16();
283 : }
284 : ELSE
285 : {
286 : Word16 old_exc_Qx[L_EXC_MEM + 8];
287 : Word16 A_3Q12[( NB_SUBFR16k + 1 ) * ( M + 1 )];
288 : Word16 *speechLookAhead_Qx;
289 :
290 : /* calculate Q-value for input speech */
291 315 : speechLookAhead_Qx = &( st->speech_enc_pe[L_frame] );
292 :
293 315 : Copy( hPlc_Ext->old_exc_Qold, old_exc_Qx, 8 );
294 315 : Copy( hPlc_Ext->LPDmem->old_exc, &old_exc_Qx[8], L_EXC_MEM );
295 315 : Scale_sig( old_exc_Qx, 8, hPlc_Ext->Q_exp );
296 :
297 : /* ISF concealment simulation */
298 315 : getConcealedLP( hPlc_Ext, A_3Q12, xsfBase, st->clas, L_frame );
299 :
300 : /* apply encoder side PLC simulation */
301 315 : hPlc_Ext->pit_min = st->pit_min; /* Q0 */
302 315 : move16();
303 315 : hPlc_Ext->pit_max = st->pit_max; /* Q0 */
304 315 : move16();
305 315 : coderLookAheadInnovation( A_3Q12, &( hPlc_Ext->T0 ), hPlc_Ext, speechLookAhead_Qx, old_exc_Qx, L_frame );
306 : }
307 1246 : return;
308 : }
309 :
310 : /*-------------------------------------------------------------------*
311 : * GplcTcxEncSetup_fx()
312 : *
313 : *
314 : *-------------------------------------------------------------------*/
315 :
316 634 : void GplcTcxEncSetup_fx(
317 : Encoder_State *st,
318 : PLC_ENC_EVS_HANDLE hPlc_Ext,
319 : Word16 Q_new )
320 : {
321 634 : TCX_ENC_HANDLE hTcxEnc = st->hTcxEnc;
322 :
323 634 : hPlc_Ext->T0_4th = hTcxEnc->tcxltp_pitch_int;
324 634 : move16();
325 634 : hPlc_Ext->Q_exp = sub( Q_new, hPlc_Ext->Q_new );
326 634 : move16();
327 634 : hPlc_Ext->Q_new = Q_new;
328 634 : move16();
329 634 : set16_fx( hPlc_Ext->old_exc_Qold, 0, 8 );
330 634 : }
331 : /*-------------------------------------------------------------------*
332 : * encSideSpecPowDiffuseDetector_fx()
333 : *
334 : *
335 : *-------------------------------------------------------------------*/
336 612 : Word16 encSideSpecPowDiffuseDetector_fx(
337 : Word16 *lsf_ref, /* Qx2.56 */
338 : Word16 *lsf_con, /* Qx2.56 */
339 : const Word32 sr_core, /* Q0 */
340 : Word16 *prev_lsf4_mean, /* Qx2.56 */
341 : const Word8 sw, /* Q0 */
342 : const Word16 coder_type )
343 : {
344 : Word16 tmp;
345 : Word16 lsf_mod[M];
346 : Word32 dist1, dist2, cum_dist1, cum_dist2;
347 : Word16 lsf4_mean;
348 : Word16 th;
349 : Word16 idx;
350 : Word16 cnt_imprv, i;
351 : Word32 L_tmp;
352 : Word16 th_dif;
353 :
354 : /* calculate the mean of the lowest 4 LSFs */
355 :
356 612 : L_tmp = L_mult( lsf_ref[0], 8192 /*1.0/4.0 Q15*/ ); /* Qx2.56 */
357 612 : L_tmp = L_mac( L_tmp, lsf_ref[1], 8192 /*1.0/4.0 Q15*/ ); /* Qx2.56 */
358 612 : L_tmp = L_mac( L_tmp, lsf_ref[2], 8192 /*1.0/4.0 Q15*/ ); /* Qx2.56 */
359 612 : lsf4_mean = mac_r( L_tmp, lsf_ref[3], 8192 /*1.0/4.0 Q15*/ ); /* Qx2.56 */
360 :
361 612 : IF( sw )
362 : {
363 612 : Copy( lsf_con, lsf_mod, M ); /* Qx2.56 */
364 :
365 612 : modify_lsf( lsf_mod, M, sr_core, 1 );
366 :
367 612 : move16();
368 612 : move16();
369 612 : cum_dist1 = 0;
370 612 : cum_dist2 = 0;
371 :
372 612 : cnt_imprv = 0;
373 612 : move16();
374 :
375 612 : IF( EQ_32( sr_core, INT_FS_16k ) )
376 : {
377 612 : th = 2560; /* Qx2.56 */
378 612 : move16(); /* LSF */
379 612 : th_dif = 288; /* Qx2.56 */
380 612 : move16(); /* LSF */
381 : }
382 : ELSE
383 : {
384 0 : th = 2048; /* Qx2.56 */
385 0 : move16(); /* LSF */
386 0 : th_dif = 230; /* Qx2.56 */
387 0 : move16(); /* LSF */
388 : }
389 :
390 10404 : FOR( i = 0; i < M; i++ )
391 : {
392 9792 : tmp = sub( lsf_con[i], lsf_ref[i] );
393 9792 : dist1 = L_mult( tmp, tmp ); /* 2*(Qx2.56)+1 */
394 9792 : tmp = sub( lsf_mod[i], lsf_ref[i] );
395 9792 : dist2 = L_mult( tmp, tmp ); /* 2*(Qx2.56)+1 */
396 :
397 9792 : if ( GT_32( dist1, dist2 ) )
398 : {
399 654 : cnt_imprv = add( cnt_imprv, 1 );
400 : }
401 9792 : cum_dist1 = L_add( cum_dist1, dist1 );
402 9792 : cum_dist2 = L_add( cum_dist2, dist2 );
403 : }
404 :
405 612 : idx = 0;
406 612 : move16();
407 :
408 612 : test();
409 612 : test();
410 612 : test();
411 612 : test();
412 612 : if ( GT_32( cum_dist1, L_add( cum_dist2, Mpy_32_16_1( cum_dist2, 4915 ) ) ) && GT_16( sub( lsf4_mean, *prev_lsf4_mean ), th_dif ) && LT_16( *prev_lsf4_mean, th ) && GT_16( cnt_imprv, 2 ) && EQ_16( coder_type, GENERIC ) )
413 : {
414 6 : idx = 1;
415 6 : move16();
416 : }
417 : }
418 : ELSE
419 : {
420 0 : move16();
421 0 : idx = 0;
422 : }
423 : /* update parameters */
424 612 : move16();
425 612 : *prev_lsf4_mean = lsf4_mean;
426 :
427 612 : return idx;
428 : }
429 :
430 :
431 : /*-------------------------------------------------------------------*
432 : * updateSpecPowDiffuseIdx_fx()
433 : *
434 : *
435 : *-------------------------------------------------------------------*/
436 612 : void updateSpecPowDiffuseIdx_fx(
437 : Encoder_State *st )
438 : {
439 : Word16 min_gp;
440 : Word16 k;
441 :
442 612 : move32();
443 612 : move16();
444 612 : st->mean_gc[1] = st->gain_code[0]; /* Q15 */
445 612 : min_gp = st->bpf_gainT[0]; /* Q15 */
446 :
447 2448 : FOR( k = 1; k < 4; k++ )
448 : {
449 1836 : st->mean_gc[1] = L_add_sat( st->mean_gc[1], st->gain_code[k] );
450 1836 : move32();
451 1836 : min_gp = s_min( min_gp, st->bpf_gainT[k] );
452 : }
453 :
454 : /* Suppress saturation warning in threshold comparison. */
455 612 : test();
456 612 : if ( LT_32( st->mean_gc[1], L_add_sat( st->mean_gc[0], Mpy_32_16_r( st->mean_gc[0], 3211 /*0.098 Q15*/ ) ) ) || GT_16( min_gp, 13435 /*0.82 Q14*/ ) )
457 : {
458 425 : move16();
459 425 : st->glr_idx[0] = 0;
460 : }
461 612 : move16();
462 612 : st->mean_gc[0] = st->mean_gc[1]; /* Q15 */
463 :
464 612 : return;
465 : }
|