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 "cnst.h"
8 : #include "prot_fx.h"
9 : #include "basop_util.h"
10 :
11 826605 : static Word16 TCX_MDCT_GetScaleFactor(
12 : const Word16 L, /* Q0 */
13 : Word16 *factor_e /* Q0 */
14 : )
15 : {
16 :
17 : Word16 factor;
18 :
19 826605 : IF( EQ_16( L, NORM_MDCT_FACTOR ) )
20 : {
21 40209 : factor = 32767;
22 40209 : move16();
23 40209 : *factor_e = 0;
24 40209 : move16();
25 : }
26 786396 : ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
27 : {
28 139321 : factor = 23170;
29 139321 : move16();
30 139321 : *factor_e = 0;
31 139321 : move16();
32 : }
33 647075 : ELSE IF( EQ_16( L, shl( NORM_MDCT_FACTOR, 2 ) ) )
34 : {
35 18328 : factor = 16384;
36 18328 : move16();
37 18328 : *factor_e = 0;
38 18328 : move16();
39 : }
40 : ELSE
41 : {
42 :
43 628747 : factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
44 628747 : *factor_e = 4;
45 628747 : move16();
46 :
47 628747 : factor = ISqrt16( factor, factor_e );
48 : }
49 :
50 826605 : return factor;
51 : }
52 :
53 40112 : static Word16 TCX_MDCT_Inverse_GetScaleFactor(
54 : const Word16 L, /* Q0 */
55 : Word16 *factor_e /* Q0 */
56 : )
57 : {
58 :
59 : Word16 factor;
60 :
61 40112 : IF( EQ_16( L, NORM_MDCT_FACTOR ) )
62 : {
63 27457 : factor = 32767;
64 27457 : move16();
65 27457 : *factor_e = 0;
66 27457 : move16();
67 : }
68 12655 : ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
69 : {
70 6658 : factor = 23170;
71 6658 : move16();
72 6658 : *factor_e = 1;
73 6658 : move16();
74 : }
75 5997 : ELSE IF( EQ_16( L, 4 * NORM_MDCT_FACTOR ) )
76 : {
77 156 : factor = 32767;
78 156 : move16();
79 156 : *factor_e = 1;
80 156 : move16();
81 : }
82 : ELSE
83 : {
84 5841 : factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
85 5841 : *factor_e = 4;
86 5841 : move16();
87 :
88 5841 : factor = Sqrt16( factor, factor_e );
89 : }
90 :
91 40112 : return factor;
92 : }
93 :
94 :
95 495501 : void TCX_MDCT(
96 : const Word16 *x, /* Qx */
97 : Word32 *y, /* exp(y_e) */
98 : Word16 *y_e,
99 : const Word16 l, /* Q0 */
100 : const Word16 m, /* Q0 */
101 : const Word16 r, /* Q0 */
102 : const Word16 element_mode /* Q0 */
103 : )
104 : {
105 :
106 : Word16 i;
107 : Word16 factor, neg_factor;
108 : Word16 factor_e;
109 : (void) element_mode;
110 :
111 495501 : factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e );
112 495501 : *y_e = add( *y_e, factor_e );
113 495501 : move16();
114 :
115 495501 : neg_factor = negate( factor );
116 :
117 : /* Init */
118 46954420 : FOR( i = 0; i < m / 2; i++ )
119 : {
120 46458919 : y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
121 46458919 : move32();
122 : }
123 26951594 : FOR( i = 0; i < l / 2; i++ )
124 : {
125 26456093 : y[m / 2 + r / 2 + m / 2 + i] = L_msu_sat( L_mult( x[i], factor ), x[l - 1 - i], factor ); /* exp(y_e) */
126 26456093 : move32();
127 : }
128 46954420 : FOR( i = 0; i < m / 2; i++ )
129 : {
130 46458919 : y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
131 46458919 : move32();
132 : }
133 30222674 : FOR( i = 0; i < r / 2; i++ )
134 : {
135 29727173 : y[m / 2 + r / 2 - 1 - m / 2 - i] = L_mac_sat( L_mult( x[l + m + i], neg_factor ), x[l + m + r - 1 - i], neg_factor ); /* exp(y_e) */
136 29727173 : move32();
137 : }
138 :
139 495501 : *y_e = sub( 15, *y_e );
140 495501 : move16();
141 495501 : edct_fx( y, y, l / 2 + m + r / 2, y_e );
142 495501 : *y_e = sub( 15 - 1, *y_e );
143 495501 : move16();
144 495501 : return;
145 : }
146 :
147 331104 : void TCX_MDST(
148 : const Word16 *x, /* Qx */
149 : Word32 *y, /* exp(y_e) */
150 : Word16 *y_e,
151 : const Word16 l, /* Q0 */
152 : const Word16 m, /* Q0 */
153 : const Word16 r, /* Q0 */
154 : const Word16 element_mode /* Q0 */
155 : )
156 : {
157 :
158 : Word16 i;
159 : Word16 factor, neg_factor;
160 : Word16 factor_e;
161 : (void) element_mode;
162 :
163 331104 : factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e ); /* exp(factor_e) */
164 331104 : *y_e = add( *y_e, factor_e );
165 331104 : move16();
166 :
167 331104 : neg_factor = negate( factor );
168 :
169 :
170 : /* Init */
171 80953814 : FOR( i = 0; i < m / 2; i++ )
172 : {
173 80622710 : y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
174 80622710 : move32();
175 : }
176 56562774 : FOR( i = 0; i < l / 2; i++ )
177 : {
178 56231670 : y[m / 2 + r / 2 + m / 2 + i] = L_msu_sat( L_mult( x[i], neg_factor ), x[l - 1 - i], factor ); /* exp(y_e) */
179 56231670 : move32();
180 : }
181 80953814 : FOR( i = 0; i < m / 2; i++ )
182 : {
183 80622710 : y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
184 80622710 : move32();
185 : }
186 59758014 : FOR( i = 0; i < r / 2; i++ )
187 : {
188 59426910 : y[m / 2 + r / 2 - 1 - m / 2 - i] = L_mac_sat( L_mult( x[l + m + i], neg_factor ), x[l + m + r - 1 - i], factor ); /* exp(y_e) */
189 59426910 : move32();
190 : }
191 :
192 331104 : *y_e = sub( 15, *y_e );
193 331104 : move16();
194 :
195 331104 : edst_fx( y, y, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), y_e );
196 :
197 331104 : *y_e = sub( 15 - 1, *y_e );
198 331104 : move16();
199 :
200 331104 : return;
201 : }
202 :
203 40112 : void TCX_MDCT_Inverse(
204 : Word32 *x, // Q( 31 - x_e )
205 : Word16 x_e,
206 : Word16 *y, /* Qy */
207 : const Word16 l, /* Q0 */
208 : const Word16 m, /* Q0 */
209 : const Word16 r, /* Q0 */
210 : const Word16 element_mode /* Q0 */
211 : )
212 : {
213 :
214 : Word16 i, fac, negfac, s;
215 40112 : Word16 L2 = l, R2 = r;
216 : Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
217 : Word16 fac_e;
218 : (void) element_mode;
219 40112 : L2 = shr( l, 1 );
220 40112 : R2 = shr( r, 1 );
221 :
222 40112 : x_e = sub( 15, x_e );
223 40112 : edct_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
224 40112 : x_e = sub( 15, x_e );
225 :
226 40112 : fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e ); /* exp(fac_e) */
227 40112 : x_e = add( x_e, fac_e );
228 :
229 40112 : negfac = negate( fac );
230 :
231 40112 : s = x_e;
232 40112 : move16();
233 :
234 2047403 : FOR( i = 0; i < R2; i++ )
235 : {
236 2007291 : y[l + m + R2 + i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) ); /* fold out right end of DCT exp(fac_e)*/
237 :
238 2007291 : move16();
239 : }
240 :
241 2028183 : FOR( i = 0; i < L2; i++ )
242 : {
243 1988071 : y[i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], fac ), s ) ); /* negate, fold out left end of DCT exp(fac_e)*/
244 1988071 : move16();
245 : }
246 :
247 4648152 : FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
248 : {
249 : Word16 f;
250 :
251 4608040 : f = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
252 4608040 : y[L2 + i] = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT exp(fac_e)*/
253 4608040 : move16();
254 4608040 : y[l + m + R2 - 1 - i] = f;
255 4608040 : move16();
256 : }
257 40112 : }
258 :
259 0 : void TCX_MDST_Inverse_fx(
260 : Word32 *x, /* exp(x_e) */
261 : Word16 x_e,
262 : Word16 *y, /* Qx */
263 : const Word16 l, /* Q0 */
264 : const Word16 m, /* Q0 */
265 : const Word16 r /* Q0 */
266 : )
267 : {
268 :
269 : Word16 i, fac, negfac, s;
270 0 : Word16 L2 = l, R2 = r;
271 0 : move16();
272 0 : move16();
273 : Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
274 : Word16 fac_e;
275 :
276 0 : L2 = shr( l, 1 );
277 0 : R2 = shr( r, 1 );
278 :
279 0 : x_e = sub( 15, x_e );
280 0 : edst_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
281 0 : x_e = sub( 15, x_e );
282 :
283 0 : fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
284 0 : x_e = add( x_e, fac_e );
285 :
286 0 : negfac = negate( fac );
287 :
288 0 : s = x_e;
289 0 : move16();
290 :
291 0 : FOR( i = 0; i < R2; i++ )
292 : {
293 0 : y[l + m + R2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], fac ), s ) ); /* fold out right end of DCT exp(fac_e)*/
294 0 : move16();
295 : }
296 :
297 0 : FOR( i = 0; i < L2; i++ )
298 : {
299 0 : y[i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], negfac ), s ) ); /* negate, fold out left end of DCT exp(fac_e)*/
300 0 : move16();
301 : }
302 :
303 0 : FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
304 : {
305 : Word16 f;
306 0 : f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], fac ), s ) );
307 :
308 0 : y[L2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT exp(fac_e)*/
309 0 : move16();
310 :
311 0 : y[l + m + R2 - 1 - i] = negate( f );
312 0 : move16();
313 : }
314 0 : }
315 :
316 : /*-------------------------------------------------------------------*
317 : * TCX_MDXT_Inverse_fx()
318 : *
319 : *
320 : *-------------------------------------------------------------------*/
321 :
322 0 : void TCX_MDXT_Inverse_fx(
323 : const Word32 *x, /* exp(x_e) */
324 : Word16 x_e,
325 : Word16 *y, /* Qx */
326 : const Word16 l, /* Q0 */
327 : const Word16 m, /* Q0 */
328 : const Word16 r, /* Q0 */
329 : const UWord16 kernel_type /* Q0 */
330 : )
331 : {
332 : Word16 signLeft;
333 : Word16 signRight;
334 : Word16 i, fac, negfac, s, fac_e;
335 0 : const Word16 L2 = shr( l, 1 ), R2 = shr( r, 1 );
336 : Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
337 : Word16 f;
338 :
339 0 : set32_fx( tmp_buf, 0, N_MAX + L_MDCT_OVLP_MAX / 2 );
340 :
341 0 : edxt_fx( x, tmp_buf + L2, add( add( L2, m ), R2 ), kernel_type, TRUE );
342 :
343 0 : fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
344 0 : x_e = add( x_e, fac_e );
345 :
346 0 : negfac = negate( fac );
347 0 : IF( GE_16( kernel_type, MDCT_II ) )
348 : {
349 0 : signLeft = negfac;
350 : }
351 : ELSE
352 : {
353 0 : signLeft = fac;
354 : }
355 : // signRight = ( kernel_type & 1 ? fac : negfac );
356 0 : IF( L_and( kernel_type, 1 ) )
357 : {
358 0 : signRight = fac;
359 : }
360 : ELSE
361 : {
362 0 : signRight = negfac;
363 : }
364 :
365 0 : s = x_e;
366 0 : move16();
367 :
368 0 : FOR( i = 0; i < L2; i++ )
369 : {
370 0 : y[i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + m + R2 + i], signLeft ), s ) ); /* fold out the left end exp(fac_e)*/
371 : }
372 :
373 0 : FOR( i = 0; i < R2; i++ )
374 : {
375 0 : y[l + m + R2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], signRight ), s ) ); /* ...and right end exp(fac_e)*/
376 0 : move16();
377 : }
378 :
379 0 : FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
380 : {
381 :
382 0 : f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
383 :
384 0 : y[L2 + i] = round_fx( L_shl( Mpy_32_16_1( tmp_buf[l + m + R2 - 1 - i], negfac ), s ) ); /* time-reverse mid of DCT exp(fac_e)*/
385 0 : move16();
386 :
387 0 : y[l + m + R2 - 1 - i] = f;
388 0 : move16();
389 : }
390 :
391 0 : return;
392 : }
|