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"
6 : #include "cnst.h" /* Common constants */
7 : #include "rom_com_fx.h" /* Static table prototypes */
8 : #include "rom_com.h" /* Static table prototypes */
9 : //#include "prot_fx.h" /* Function prototypes */
10 : #include "prot_fx.h" /* Function prototypes */
11 : #include "prot_fx_enc.h" /* Function prototypes */
12 :
13 : /*-----------------------------------------------------------------*
14 : * Local constant
15 : *-----------------------------------------------------------------*/
16 : #define INPOL 4 /* +- range in samples for impulse position searching */
17 :
18 : /*-----------------------------------------------------------------*
19 : * Local function prototypes
20 : *-----------------------------------------------------------------*/
21 : static void convolve_tc_fx( const Word16 g[], const Word16 h[], Word16 y[], const Word16 L_1, const Word16 L_2 );
22 : static void correlate_tc_fx( const Word16 *x, Word16 *y, const Word16 *h, const Word16 start, const Word16 L_1, const Word16 L_2 );
23 : static void convolve_tc2_fx( const Word16 g[], const Word16 h[], Word16 y[], const Word16 pos_max );
24 :
25 : /*---------------------------------------------------------------------------------------*
26 : * Function set_impulse() for TC *
27 : * ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ *
28 : * Builds glottal codebook contribution based on glotal impulses positions finding. *
29 : * *
30 : * Returns a position of the glotal impulse center and *
31 : * a number of the glotal impulse shape. *
32 : * *
33 : * |----| |----| xn *
34 : * imp_pos-> || | imp_shape-> | g1 | | *
35 : * | | | | g2 | exc |---| y1 ---- | *
36 : * | | |--------------| |---------| h |-------|gain|-------(-)---> xn2 *
37 : * | || | gn | |---| ---- *
38 : * |----| |----| *
39 : * codebook excitation h_orig gain *
40 : * *
41 : * *
42 : * nominator dd <xn,y1>*<xn,y1> *
43 : * Searching criterion: maximize ------------- = ---- = ----------------- *
44 : * denominator rr <y1,y1> *
45 : * *
46 : * Notice: gain = gain_trans * gain_pit (computed in trans_enc() function) *
47 : * *
48 : *---------------------------------------------------------------------------------------*/
49 14413 : void set_impulse_fx(
50 : const Word16 xn_fx[], /* i : target signal Q_new-1+shift*/
51 : const Word16 h_orig_fx[], /* i : impulse response of weighted synthesis filter Q(14+shift)*/
52 : Word16 exc_fx[], /* o : adaptive codebook excitation Q_new*/
53 : Word16 yy1_fx[], /* o : filtered adaptive codebook excitation Q_new*/
54 : Word16 *imp_shape, /* o : adaptive codebook index Q0*/
55 : Word16 *imp_pos, /* o : position of the glottal impulse center index Q0*/
56 : Word32 *gain_trans_fx, /* o : transition gain Q7*/
57 : Word16 Q_new /* i : Current scaling */
58 : )
59 : {
60 : Word16 i, j, m;
61 : Word16 start1, start2, end1;
62 : Word32 rr_fx[L_SUBFR]; /* criterion: nominator coefficients */
63 : Word16 dd_fx[L_SUBFR], tmp16; /* criterion: denominator coefficients */
64 : Word16 gh_fx[L_SUBFR], num, den, exp_num, exp_den; /* convolution of 'g' and 'h' filters */
65 : Word16 krit_fx, krit_max_fx, gain16;
66 : Word32 Lrr, Ldd, Ltmp, Ltmp1;
67 : const Word16 *pt_Glt;
68 : #ifndef ISSUE_1867_replace_overflow_libenc
69 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
70 : Flag Overflow = 0;
71 : move32();
72 : #endif
73 : #endif
74 14413 : krit_max_fx = -32768;
75 14413 : move16();
76 :
77 : /* main loop */
78 : /* impulse */
79 129717 : FOR( m = 0; m < NUM_IMPULSE; m++ )
80 : {
81 : /* set searching ranges */
82 115304 : IF( LT_16( *imp_pos, L_SUBFR - INPOL ) )
83 : {
84 111951 : end1 = add( *imp_pos, INPOL ); // Q0
85 : }
86 : ELSE
87 : {
88 3353 : end1 = L_SUBFR;
89 3353 : move16();
90 : }
91 115304 : IF( GT_16( *imp_pos, INPOL ) )
92 : {
93 101740 : start1 = sub( *imp_pos, INPOL ); // Q0
94 : }
95 : ELSE
96 : {
97 13564 : start1 = 0;
98 13564 : move16();
99 : }
100 115304 : IF( GT_16( start1, L_IMPULSE2 ) )
101 : {
102 83023 : start2 = start1;
103 83023 : move16();
104 : }
105 : ELSE
106 : {
107 32281 : start2 = L_IMPULSE2;
108 32281 : move16();
109 : }
110 :
111 : /*-----------------------------------------------------------*
112 : * nominator & DEnominator, gh=convolve(g,h)
113 : *-----------------------------------------------------------*/
114 115304 : IF( LT_16( start1, L_IMPULSE2 ) )
115 : {
116 29073 : Lrr = L_deposit_l( 0 );
117 29073 : Ldd = L_deposit_l( 0 );
118 29073 : convolve_tc_fx( &Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - start1],
119 29073 : &h_orig_fx[0], gh_fx, add( L_IMPULSE - L_IMPULSE2, start1 ), L_SUBFR );
120 :
121 : /* nominator & DEnominator row <0> */
122 1889745 : FOR( i = 0; i < L_SUBFR; i++ )
123 : {
124 : #ifdef ISSUE_1867_replace_overflow_libenc
125 1860672 : Lrr = L_mac_sat( Lrr, gh_fx[i], gh_fx[i] ); // Q27
126 1860672 : Ldd = L_mac_sat( Ldd, gh_fx[i], xn_fx[i] ); // Q27
127 : #else
128 : Lrr = L_mac_o( Lrr, gh_fx[i], gh_fx[i], &Overflow ); // Q27
129 : Ldd = L_mac_o( Ldd, gh_fx[i], xn_fx[i], &Overflow ); // Q27
130 : #endif
131 : }
132 29073 : rr_fx[start1] = Lrr;
133 29073 : move32();
134 : #ifdef ISSUE_1867_replace_overflow_libenc
135 29073 : dd_fx[start1] = round_fx_sat( Ldd ); // Q11
136 : #else
137 : dd_fx[start1] = round_fx_o( Ldd, &Overflow ); // Q11
138 : #endif
139 29073 : rr_fx[start1] = L_max( rr_fx[start1], 1 );
140 :
141 169405 : FOR( i = add( start1, 1 ); i < L_IMPULSE2; i++ )
142 : {
143 140332 : Lrr = L_deposit_l( 0 );
144 140332 : Ldd = L_deposit_l( 0 );
145 : /* DEnominator rows <1,L_IMPULSE2-1> */
146 8981248 : FOR( j = L_SUBFR - 1; j > 0; j-- )
147 : {
148 : /* gh_fx[j] = gh_fx[j-1] + glottal_cdbk[m*L_IMPULSE+L_IMPULSE2-i]*h_orig_fx[j] */
149 8840916 : gh_fx[j] = mac_r( L_deposit_h( gh_fx[j - 1] ),
150 8840916 : Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - i], h_orig_fx[j] ); // Q13
151 8840916 : move16();
152 : #ifdef ISSUE_1867_replace_overflow_libenc
153 8840916 : Lrr = L_mac_sat( Lrr, gh_fx[j], gh_fx[j] ); // Q27
154 8840916 : Ldd = L_mac_sat( Ldd, gh_fx[j], xn_fx[j] ); // Q27
155 : #else
156 : Lrr = L_mac_o( Lrr, gh_fx[j], gh_fx[j], &Overflow ); // Q27
157 : Ldd = L_mac_o( Ldd, gh_fx[j], xn_fx[j], &Overflow ); // Q27
158 : #endif
159 : }
160 :
161 140332 : gh_fx[0] = mult_r( Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - i], h_orig_fx[0] ); // Q13
162 140332 : move16();
163 : #ifdef ISSUE_1867_replace_overflow_libenc
164 140332 : Lrr = L_mac_sat( Lrr, gh_fx[0], gh_fx[0] ); // Q27
165 140332 : Ldd = L_mac_sat( Ldd, gh_fx[0], xn_fx[0] ); // Q27
166 : #else
167 : Lrr = L_mac_o( Lrr, gh_fx[0], gh_fx[0], &Overflow ); // Q27
168 : Ldd = L_mac_o( Ldd, gh_fx[0], xn_fx[0], &Overflow ); // Q27
169 : #endif
170 140332 : dd_fx[i] = round_fx_sat( Ldd ); // Q11
171 140332 : rr_fx[i] = L_max( Lrr, 1 );
172 140332 : move32();
173 : /* move rr and dd into rr[i] and dd[i] */
174 : }
175 :
176 : /* complete convolution(excitation,h_orig) */
177 1860672 : FOR( j = L_SUBFR - 1; j > 0; j-- )
178 : {
179 1831599 : gh_fx[j] = mac_r( L_deposit_h( gh_fx[j - 1] ),
180 1831599 : Glottal_cdbk_fx[m * L_IMPULSE], h_orig_fx[j] ); // Q13
181 : }
182 : }
183 : ELSE
184 : {
185 86231 : convolve_tc_fx( &Glottal_cdbk_fx[m * L_IMPULSE], h_orig_fx, gh_fx, L_IMPULSE, L_SUBFR );
186 : }
187 :
188 115304 : IF( GE_16( end1, start2 ) )
189 : {
190 : /* DEnominator row <L_SUBFR-1> */
191 104567 : Lrr = L_mult( gh_fx[0], gh_fx[0] ); // Q27
192 941103 : FOR( j = 1; j <= L_IMPULSE2; j++ )
193 : {
194 : /*rr[L_SUBFR-1] += gh[j]*gh[j];*/
195 836536 : Lrr = L_mac_sat( Lrr, gh_fx[j], gh_fx[j] ); // Q27
196 : }
197 104567 : rr_fx[L_SUBFR - 1] = Lrr;
198 104567 : move32();
199 : /* DEnominator rows <L_IMPULSE2,L_SUBFR-2> */
200 4050710 : FOR( i = L_SUBFR - 2; i >= start2; i-- )
201 : {
202 : /*rr[i] = rr[i+1] + gh[L_SUBFR+L_IMPULSE2-1-i]*gh[L_SUBFR+L_IMPULSE2-1-i];*/
203 : #ifdef ISSUE_1867_replace_overflow_libenc
204 3946143 : rr_fx[i] = L_mac_sat( rr_fx[i + 1], gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i], gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i] ); // Q27
205 : #else
206 : rr_fx[i] = L_mac_o( rr_fx[i + 1], gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i], gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i], &Overflow ); // Q27
207 : #endif
208 3946143 : move32();
209 : }
210 : /* nominator rows <L_IMPULSE2,L_SUBFR-1> */
211 104567 : correlate_tc_fx( xn_fx, &dd_fx[L_IMPULSE2], gh_fx, sub( start2, L_IMPULSE2 ),
212 104567 : L_SUBFR, sub( end1, L_IMPULSE2 ) );
213 : }
214 : /*------------------------------------------------------------*
215 : * maxim. criterion
216 : *------------------------------------------------------------*/
217 1004209 : FOR( i = start1; i < end1; i++ )
218 : {
219 : /* krit = (float)(dd[i]*dd[i])/rr[i] */
220 888905 : exp_num = sub( norm_s( dd_fx[i] ), 1 );
221 888905 : num = shl( dd_fx[i], exp_num );
222 888905 : num = mult_r( num, num );
223 :
224 888905 : exp_den = norm_l( rr_fx[i] );
225 888905 : den = extract_h( L_shl( rr_fx[i], exp_den ) );
226 :
227 888905 : num = div_s( num, den );
228 :
229 888905 : krit_fx = shr_sat( num, sub( sub( shl_sat( exp_num, 1 ), exp_den ), 2 ) ); /* Q18 */
230 :
231 888905 : IF( GT_16( krit_fx, krit_max_fx ) )
232 : {
233 95032 : krit_max_fx = krit_fx; // Q18
234 95032 : move16();
235 95032 : *imp_pos = i;
236 95032 : move16();
237 95032 : *imp_shape = m;
238 95032 : move16();
239 : }
240 : }
241 : }
242 :
243 : /*---------------------------------------------------------------*
244 : * Build the excitation using found codeword
245 : *---------------------------------------------------------------*/
246 :
247 14413 : set16_fx( exc_fx, 0, L_SUBFR );
248 14413 : set16_fx( yy1_fx, 0, L_SUBFR );
249 14413 : tmp16 = sub( extract_l( L_mac0( L_IMPULSE2, *imp_shape, L_IMPULSE ) ), *imp_pos );
250 14413 : pt_Glt = &Glottal_cdbk_fx[tmp16]; // Q13
251 14413 : move16();
252 14413 : j = add( *imp_pos, L_IMPULSE2 );
253 259434 : FOR( i = sub( *imp_pos, L_IMPULSE2 ); i <= j; i++ )
254 : {
255 245021 : test();
256 245021 : if ( i >= 0 && LT_16( i, L_SUBFR ) )
257 : {
258 230230 : exc_fx[i] = pt_Glt[i];
259 230230 : move16(); /*Q13*/
260 : }
261 : }
262 :
263 : /*---------------------------------------------------------------*
264 : * Form filtered excitation, find gain_trans
265 : *---------------------------------------------------------------*/
266 14413 : convolve_tc2_fx( exc_fx, h_orig_fx, yy1_fx, *imp_pos );
267 :
268 : /* Find the ACELP correlations and the pitch gain (for current subframe) */
269 : /**gain_trans = dot_product( xn, yy1, L_SUBFR )/(dot_product( yy1, yy1, L_SUBFR ) + 0.01f);*/
270 : /* Compute scalar product <y1[],y1[]> */
271 14413 : Ltmp = Dot_product( yy1_fx, yy1_fx, L_SUBFR );
272 14413 : exp_den = norm_l( Ltmp );
273 14413 : den = extract_h( L_shl( Ltmp, exp_den ) );
274 :
275 : /* Compute scalar product <xn[],y1[]> */
276 14413 : Ltmp1 = Dot_product( xn_fx, yy1_fx, L_SUBFR );
277 14413 : exp_num = sub( norm_l( Ltmp1 ), 1 );
278 14413 : num = extract_h( L_shl( Ltmp1, exp_num ) );
279 14413 : tmp16 = s_or( shr( num, 16 ), 1 ); /* extract sign if num < 0 tmp16 = -1 else tmp16 = 1 */
280 14413 : num = abs_s( num );
281 :
282 : /* compute gain = xy/yy */
283 14413 : gain16 = div_s( num, den );
284 :
285 14413 : i = add( exp_num, sub( Q_new, 1 + 1 + 3 ) );
286 14413 : i = sub( i, exp_den ); /* Gain_trans in Q7 */
287 14413 : gain16 = i_mult2( gain16, tmp16 ); /* apply sign */
288 14413 : *gain_trans_fx = L_shr( L_deposit_l( gain16 ), i ); // Q7
289 14413 : move32();
290 14413 : }
291 : /*-------------------------------------------------------------------*
292 : * convolve_tc_fx:
293 : *
294 : * convolution for different vectors' lengths
295 : *-------------------------------------------------------------------*/
296 115304 : static void convolve_tc_fx(
297 : const Word16 g[], /* i : input vector Qx */
298 : const Word16 h[], /* i : impulse response (or second input vector) Q15 */
299 : Word16 y[], /* o : output vector (result of convolution) 12 bits */
300 : const Word16 L_1, /* i : vector h size Q0 */
301 : const Word16 L_2 /* i : vector g size Q0 */
302 : )
303 : {
304 : Word16 i, n, len;
305 : Word32 L_sum;
306 :
307 7494760 : FOR( n = 0; n < L_2; n++ )
308 : {
309 7379456 : len = s_min( add( n, 1 ), L_1 );
310 7379456 : L_sum = L_mult( g[0], h[n] ); /* Qx */
311 101134953 : FOR( i = 1; i < len; i++ )
312 : {
313 93755497 : L_sum = L_mac_sat( L_sum, g[i], h[n - i] ); /* Qx + 16 */
314 : }
315 :
316 7379456 : y[n] = round_fx_sat( L_sum ); /* Qx */
317 : }
318 115304 : }
319 : /*-------------------------------------------------------------------*
320 : * convolve_tc2_fx:
321 : *
322 : * convolution for one vector with only L_IMPULSE nonzero coefficients
323 : *-------------------------------------------------------------------*/
324 14413 : static void convolve_tc2_fx(
325 : const Word16 g[], /* i : input vector Qx */
326 : const Word16 h[], /* i : impulse response (or second input vector) Q15 */
327 : Word16 y[], /* o : output vector (result of convolution) 12 bits */
328 : const Word16 pos_max /* o : artificial impulse position Q0 */
329 : )
330 : {
331 : Word32 temp;
332 : Word16 i, n;
333 : Word16 i_start, i_end, i_end2;
334 :
335 14413 : i_start = sub( pos_max, L_IMPULSE2 ); // Q0
336 14413 : i_start = s_max( i_start, 0 );
337 :
338 14413 : i_end = add( pos_max, L_IMPULSE ); // Q0
339 14413 : i_end = s_min( i_end, L_SUBFR );
340 :
341 671676 : FOR( n = i_start; n < L_SUBFR; n++ )
342 : {
343 657263 : temp = L_mult( g[0], h[n] ); /* Qx + 16 */
344 657263 : i_end2 = s_min( add( n, 1 ), i_end );
345 :
346 19959649 : FOR( i = 1; i < i_end2; i++ )
347 : {
348 19302386 : temp = L_mac( temp, g[i], h[n - i] ); // Qx + 16
349 : }
350 657263 : y[n] = round_fx( temp ); // Qx
351 : }
352 14413 : }
353 : /*-------------------------------------------------------------------*
354 : * correlate_tc:
355 : *
356 : * correlation for different vectors' lengths
357 : *-------------------------------------------------------------------*/
358 104567 : static void correlate_tc_fx(
359 : const Word16 *x, /* i: target signal Qx*/
360 : Word16 *y, /* o: correlation between x[] and h[] -Q3*/
361 : const Word16 *h, /* i: impulse response (of weighted synthesis filter) Q15*/
362 : const Word16 start, /* i: index of iterest Q0*/
363 : const Word16 L_1, /* i: vector size Q0*/
364 : const Word16 L_2 /* i: index of interest Q0*/
365 : )
366 : {
367 : Word16 i, j;
368 : Word32 s;
369 :
370 853175 : FOR( i = start; i < L_2; i++ )
371 : {
372 748608 : s = L_deposit_l( 0 );
373 31923383 : FOR( j = i; j < L_1; j++ )
374 : {
375 31174775 : s = L_mac_sat( s, x[j], h[j - i] ); /* Qx + 16 */
376 : }
377 748608 : y[i] = round_fx_sat( s ); /* Qx */
378 : }
379 104567 : }
|