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 14181 : 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 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
69 14181 : Flag Overflow = 0;
70 14181 : move32();
71 : #endif
72 14181 : krit_max_fx = -32768;
73 14181 : move16();
74 :
75 : /* main loop */
76 : /* impulse */
77 127629 : FOR( m = 0; m < NUM_IMPULSE; m++ )
78 : {
79 : /* set searching ranges */
80 113448 : IF( LT_16( *imp_pos, L_SUBFR - INPOL ) )
81 : {
82 110104 : end1 = add( *imp_pos, INPOL ); // Q0
83 : }
84 : ELSE
85 : {
86 3344 : end1 = L_SUBFR;
87 3344 : move16();
88 : }
89 113448 : IF( GT_16( *imp_pos, INPOL ) )
90 : {
91 99878 : start1 = sub( *imp_pos, INPOL ); // Q0
92 : }
93 : ELSE
94 : {
95 13570 : start1 = 0;
96 13570 : move16();
97 : }
98 113448 : IF( GT_16( start1, L_IMPULSE2 ) )
99 : {
100 81869 : start2 = start1;
101 81869 : move16();
102 : }
103 : ELSE
104 : {
105 31579 : start2 = L_IMPULSE2;
106 31579 : move16();
107 : }
108 :
109 : /*-----------------------------------------------------------*
110 : * nominator & DEnominator, gh=convolve(g,h)
111 : *-----------------------------------------------------------*/
112 113448 : IF( LT_16( start1, L_IMPULSE2 ) )
113 : {
114 28526 : Lrr = L_deposit_l( 0 );
115 28526 : Ldd = L_deposit_l( 0 );
116 28526 : convolve_tc_fx( &Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - start1],
117 28526 : &h_orig_fx[0], gh_fx, add( L_IMPULSE - L_IMPULSE2, start1 ), L_SUBFR );
118 :
119 : /* nominator & DEnominator row <0> */
120 1854190 : FOR( i = 0; i < L_SUBFR; i++ )
121 : {
122 1825664 : Lrr = L_mac_o( Lrr, gh_fx[i], gh_fx[i], &Overflow ); // Q27
123 1825664 : Ldd = L_mac_o( Ldd, gh_fx[i], xn_fx[i], &Overflow ); // Q27
124 : }
125 28526 : rr_fx[start1] = Lrr;
126 28526 : move32();
127 28526 : dd_fx[start1] = round_fx_o( Ldd, &Overflow ); // Q11
128 28526 : rr_fx[start1] = L_max( rr_fx[start1], 1 );
129 :
130 167034 : FOR( i = add( start1, 1 ); i < L_IMPULSE2; i++ )
131 : {
132 138508 : Lrr = L_deposit_l( 0 );
133 138508 : Ldd = L_deposit_l( 0 );
134 : /* DEnominator rows <1,L_IMPULSE2-1> */
135 8864512 : FOR( j = L_SUBFR - 1; j > 0; j-- )
136 : {
137 : /* gh_fx[j] = gh_fx[j-1] + glottal_cdbk[m*L_IMPULSE+L_IMPULSE2-i]*h_orig_fx[j] */
138 8726004 : gh_fx[j] = mac_r( L_deposit_h( gh_fx[j - 1] ),
139 8726004 : Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - i], h_orig_fx[j] ); // Q13
140 8726004 : move16();
141 8726004 : Lrr = L_mac_o( Lrr, gh_fx[j], gh_fx[j], &Overflow ); // Q27
142 8726004 : Ldd = L_mac_o( Ldd, gh_fx[j], xn_fx[j], &Overflow ); // Q27
143 : }
144 :
145 138508 : gh_fx[0] = mult_r( Glottal_cdbk_fx[m * L_IMPULSE + L_IMPULSE2 - i], h_orig_fx[0] ); // Q13
146 138508 : move16();
147 138508 : Lrr = L_mac_o( Lrr, gh_fx[0], gh_fx[0], &Overflow ); // Q27
148 138508 : Ldd = L_mac_o( Ldd, gh_fx[0], xn_fx[0], &Overflow ); // Q27
149 138508 : dd_fx[i] = round_fx_sat( Ldd ); // Q11
150 138508 : rr_fx[i] = L_max( Lrr, 1 );
151 138508 : move32();
152 : /* move rr and dd into rr[i] and dd[i] */
153 : }
154 :
155 : /* complete convolution(excitation,h_orig) */
156 1825664 : FOR( j = L_SUBFR - 1; j > 0; j-- )
157 : {
158 1797138 : gh_fx[j] = mac_r( L_deposit_h( gh_fx[j - 1] ),
159 1797138 : Glottal_cdbk_fx[m * L_IMPULSE], h_orig_fx[j] ); // Q13
160 : }
161 : }
162 : ELSE
163 : {
164 84922 : convolve_tc_fx( &Glottal_cdbk_fx[m * L_IMPULSE], h_orig_fx, gh_fx, L_IMPULSE, L_SUBFR );
165 : }
166 :
167 113448 : IF( GE_16( end1, start2 ) )
168 : {
169 : /* DEnominator row <L_SUBFR-1> */
170 102745 : Lrr = L_mult( gh_fx[0], gh_fx[0] ); // Q27
171 924705 : FOR( j = 1; j <= L_IMPULSE2; j++ )
172 : {
173 : /*rr[L_SUBFR-1] += gh[j]*gh[j];*/
174 821960 : Lrr = L_mac_sat( Lrr, gh_fx[j], gh_fx[j] ); // Q27
175 : }
176 102745 : rr_fx[L_SUBFR - 1] = Lrr;
177 102745 : move32();
178 : /* DEnominator rows <L_IMPULSE2,L_SUBFR-2> */
179 3981396 : FOR( i = L_SUBFR - 2; i >= start2; i-- )
180 : {
181 : /*rr[i] = rr[i+1] + gh[L_SUBFR+L_IMPULSE2-1-i]*gh[L_SUBFR+L_IMPULSE2-1-i];*/
182 7757302 : rr_fx[i] = L_mac_o( rr_fx[i + 1], gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i],
183 3878651 : gh_fx[L_SUBFR + L_IMPULSE2 - 1 - i], &Overflow ); // Q27
184 3878651 : move32();
185 : }
186 : /* nominator rows <L_IMPULSE2,L_SUBFR-1> */
187 102745 : correlate_tc_fx( xn_fx, &dd_fx[L_IMPULSE2], gh_fx, sub( start2, L_IMPULSE2 ),
188 102745 : L_SUBFR, sub( end1, L_IMPULSE2 ) );
189 : }
190 : /*------------------------------------------------------------*
191 : * maxim. criterion
192 : *------------------------------------------------------------*/
193 987808 : FOR( i = start1; i < end1; i++ )
194 : {
195 : /* krit = (float)(dd[i]*dd[i])/rr[i] */
196 874360 : exp_num = sub( norm_s( dd_fx[i] ), 1 );
197 874360 : num = shl( dd_fx[i], exp_num );
198 874360 : num = mult_r( num, num );
199 :
200 874360 : exp_den = norm_l( rr_fx[i] );
201 874360 : den = extract_h( L_shl( rr_fx[i], exp_den ) );
202 :
203 874360 : num = div_s( num, den );
204 874360 : krit_fx = shr_o( num, sub( sub( shl_o( exp_num, 1, &Overflow ), exp_den ), 2 ), &Overflow ); /* Q18 */
205 :
206 874360 : IF( GT_16( krit_fx, krit_max_fx ) )
207 : {
208 93218 : krit_max_fx = krit_fx; // Q18
209 93218 : move16();
210 93218 : *imp_pos = i;
211 93218 : move16();
212 93218 : *imp_shape = m;
213 93218 : move16();
214 : }
215 : }
216 : }
217 :
218 : /*---------------------------------------------------------------*
219 : * Build the excitation using found codeword
220 : *---------------------------------------------------------------*/
221 :
222 14181 : set16_fx( exc_fx, 0, L_SUBFR );
223 14181 : set16_fx( yy1_fx, 0, L_SUBFR );
224 14181 : tmp16 = sub( extract_l( L_mac0( L_IMPULSE2, *imp_shape, L_IMPULSE ) ), *imp_pos );
225 14181 : pt_Glt = &Glottal_cdbk_fx[tmp16]; // Q13
226 14181 : move16();
227 14181 : j = add( *imp_pos, L_IMPULSE2 );
228 255258 : FOR( i = sub( *imp_pos, L_IMPULSE2 ); i <= j; i++ )
229 : {
230 241077 : test();
231 241077 : if ( i >= 0 && LT_16( i, L_SUBFR ) )
232 : {
233 226405 : exc_fx[i] = pt_Glt[i];
234 226405 : move16(); /*Q13*/
235 : }
236 : }
237 :
238 : /*---------------------------------------------------------------*
239 : * Form filtered excitation, find gain_trans
240 : *---------------------------------------------------------------*/
241 14181 : convolve_tc2_fx( exc_fx, h_orig_fx, yy1_fx, *imp_pos );
242 :
243 : /* Find the ACELP correlations and the pitch gain (for current subframe) */
244 : /**gain_trans = dot_product( xn, yy1, L_SUBFR )/(dot_product( yy1, yy1, L_SUBFR ) + 0.01f);*/
245 : /* Compute scalar product <y1[],y1[]> */
246 14181 : Ltmp = Dot_product( yy1_fx, yy1_fx, L_SUBFR );
247 14181 : exp_den = norm_l( Ltmp );
248 14181 : den = extract_h( L_shl( Ltmp, exp_den ) );
249 :
250 : /* Compute scalar product <xn[],y1[]> */
251 14181 : Ltmp1 = Dot_product( xn_fx, yy1_fx, L_SUBFR );
252 14181 : exp_num = sub( norm_l( Ltmp1 ), 1 );
253 14181 : num = extract_h( L_shl( Ltmp1, exp_num ) );
254 14181 : tmp16 = s_or( shr( num, 16 ), 1 ); /* extract sign if num < 0 tmp16 = -1 else tmp16 = 1 */
255 14181 : num = abs_s( num );
256 :
257 : /* compute gain = xy/yy */
258 14181 : gain16 = div_s( num, den );
259 :
260 14181 : i = add( exp_num, sub( Q_new, 1 + 1 + 3 ) );
261 14181 : i = sub( i, exp_den ); /* Gain_trans in Q7 */
262 14181 : gain16 = i_mult2( gain16, tmp16 ); /* apply sign */
263 14181 : *gain_trans_fx = L_shr( L_deposit_l( gain16 ), i ); // Q7
264 14181 : move32();
265 14181 : }
266 : /*-------------------------------------------------------------------*
267 : * convolve_tc_fx:
268 : *
269 : * convolution for different vectors' lengths
270 : *-------------------------------------------------------------------*/
271 113448 : static void convolve_tc_fx(
272 : const Word16 g[], /* i : input vector Qx */
273 : const Word16 h[], /* i : impulse response (or second input vector) Q15 */
274 : Word16 y[], /* o : output vector (result of convolution) 12 bits */
275 : const Word16 L_1, /* i : vector h size Q0 */
276 : const Word16 L_2 /* i : vector g size Q0 */
277 : )
278 : {
279 : Word16 i, n, len;
280 : Word32 L_sum;
281 :
282 7374120 : FOR( n = 0; n < L_2; n++ )
283 : {
284 7260672 : len = s_min( add( n, 1 ), L_1 );
285 7260672 : L_sum = L_mult( g[0], h[n] ); /* Qx */
286 99487383 : FOR( i = 1; i < len; i++ )
287 : {
288 92226711 : L_sum = L_mac( L_sum, g[i], h[n - i] ); /* Qx + 16 */
289 : }
290 :
291 7260672 : y[n] = round_fx( L_sum ); /* Qx */
292 : }
293 113448 : }
294 : /*-------------------------------------------------------------------*
295 : * convolve_tc2_fx:
296 : *
297 : * convolution for one vector with only L_IMPULSE nonzero coefficients
298 : *-------------------------------------------------------------------*/
299 14181 : static void convolve_tc2_fx(
300 : const Word16 g[], /* i : input vector Qx */
301 : const Word16 h[], /* i : impulse response (or second input vector) Q15 */
302 : Word16 y[], /* o : output vector (result of convolution) 12 bits */
303 : const Word16 pos_max /* o : artificial impulse position Q0 */
304 : )
305 : {
306 : Word32 temp;
307 : Word16 i, n;
308 : Word16 i_start, i_end, i_end2;
309 :
310 14181 : i_start = sub( pos_max, L_IMPULSE2 ); // Q0
311 14181 : i_start = s_max( i_start, 0 );
312 :
313 14181 : i_end = add( pos_max, L_IMPULSE ); // Q0
314 14181 : i_end = s_min( i_end, L_SUBFR );
315 :
316 661436 : FOR( n = i_start; n < L_SUBFR; n++ )
317 : {
318 647255 : temp = L_mult( g[0], h[n] ); /* Qx + 16 */
319 647255 : i_end2 = s_min( add( n, 1 ), i_end );
320 :
321 19640165 : FOR( i = 1; i < i_end2; i++ )
322 : {
323 18992910 : temp = L_mac( temp, g[i], h[n - i] ); // Qx + 16
324 : }
325 647255 : y[n] = round_fx( temp ); // Qx
326 : }
327 14181 : }
328 : /*-------------------------------------------------------------------*
329 : * correlate_tc:
330 : *
331 : * correlation for different vectors' lengths
332 : *-------------------------------------------------------------------*/
333 102745 : static void correlate_tc_fx(
334 : const Word16 *x, /* i: target signal Qx*/
335 : Word16 *y, /* o: correlation between x[] and h[] -Q3*/
336 : const Word16 *h, /* i: impulse response (of weighted synthesis filter) Q15*/
337 : const Word16 start, /* i: index of iterest Q0*/
338 : const Word16 L_1, /* i: vector size Q0*/
339 : const Word16 L_2 /* i: index of interest Q0*/
340 : )
341 : {
342 : Word16 i, j;
343 : Word32 s;
344 :
345 838875 : FOR( i = start; i < L_2; i++ )
346 : {
347 736130 : s = L_deposit_l( 0 );
348 31415050 : FOR( j = i; j < L_1; j++ )
349 : {
350 30678920 : s = L_mac_sat( s, x[j], h[j - i] ); /* Qx + 16 */
351 : }
352 736130 : y[i] = round_fx_sat( s ); /* Qx */
353 : }
354 102745 : }
|