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 2850 : static Word16 TCX_MDCT_GetScaleFactor(
12 : const Word16 L, /* Q0 */
13 : Word16 *factor_e /* Q0 */
14 : )
15 : {
16 :
17 : Word16 factor;
18 :
19 2850 : IF( EQ_16( L, NORM_MDCT_FACTOR ) )
20 : {
21 0 : factor = 32767;
22 0 : move16();
23 0 : *factor_e = 0;
24 0 : move16();
25 : }
26 2850 : ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
27 : {
28 452 : factor = 23170;
29 452 : move16();
30 452 : *factor_e = 0;
31 452 : move16();
32 : }
33 2398 : ELSE IF( EQ_16( L, shl( NORM_MDCT_FACTOR, 2 ) ) )
34 : {
35 616 : factor = 16384;
36 616 : move16();
37 616 : *factor_e = 0;
38 616 : move16();
39 : }
40 : ELSE
41 : {
42 :
43 1782 : factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
44 1782 : *factor_e = 4;
45 1782 : move16();
46 :
47 1782 : factor = ISqrt16( factor, factor_e );
48 : }
49 :
50 2850 : return factor;
51 : }
52 :
53 122602 : static Word16 TCX_MDCT_Inverse_GetScaleFactor(
54 : const Word16 L, /* Q0 */
55 : Word16 *factor_e /* Q0 */
56 : )
57 : {
58 :
59 : Word16 factor;
60 :
61 122602 : IF( EQ_16( L, NORM_MDCT_FACTOR ) )
62 : {
63 42128 : factor = 32767;
64 42128 : move16();
65 42128 : *factor_e = 0;
66 42128 : move16();
67 : }
68 80474 : ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
69 : {
70 13550 : factor = 23170;
71 13550 : move16();
72 13550 : *factor_e = 1;
73 13550 : move16();
74 : }
75 66924 : ELSE IF( EQ_16( L, 4 * NORM_MDCT_FACTOR ) )
76 : {
77 1015 : factor = 32767;
78 1015 : move16();
79 1015 : *factor_e = 1;
80 1015 : move16();
81 : }
82 : ELSE
83 : {
84 65909 : factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
85 65909 : *factor_e = 4;
86 65909 : move16();
87 :
88 65909 : factor = Sqrt16( factor, factor_e );
89 : }
90 :
91 122602 : return factor;
92 : }
93 :
94 :
95 1425 : 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 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
111 1425 : Flag Overflow = 0;
112 1425 : move32();
113 : #endif
114 1425 : factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e );
115 1425 : *y_e = add( *y_e, factor_e );
116 1425 : move16();
117 :
118 1425 : neg_factor = negate( factor );
119 :
120 :
121 : /* Init */
122 317775 : FOR( i = 0; i < m / 2; i++ )
123 : {
124 316350 : y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
125 316350 : move32();
126 : }
127 247475 : FOR( i = 0; i < l / 2; i++ )
128 : {
129 246050 : y[m / 2 + r / 2 + m / 2 + i] = L_msu_o( L_mult( x[i], factor ), x[l - 1 - i], factor, &Overflow ); /* exp(y_e) */
130 246050 : move32();
131 : }
132 317775 : FOR( i = 0; i < m / 2; i++ )
133 : {
134 316350 : y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
135 316350 : move32();
136 : }
137 247475 : FOR( i = 0; i < r / 2; i++ )
138 : {
139 246050 : y[m / 2 + r / 2 - 1 - m / 2 - i] = L_mac_o( L_mult( x[l + m + i], neg_factor ), x[l + m + r - 1 - i], neg_factor, &Overflow ); /* exp(y_e) */
140 246050 : move32();
141 : }
142 :
143 1425 : *y_e = sub( 15, *y_e );
144 1425 : move16();
145 1425 : edct_fx( y, y, l / 2 + m + r / 2, y_e );
146 1425 : *y_e = sub( 15 - 1, *y_e );
147 1425 : move16();
148 1425 : return;
149 : }
150 :
151 1425 : void TCX_MDST(
152 : const Word16 *x, /* Qx */
153 : Word32 *y, /* exp(y_e) */
154 : Word16 *y_e,
155 : const Word16 l, /* Q0 */
156 : const Word16 m, /* Q0 */
157 : const Word16 r, /* Q0 */
158 : const Word16 element_mode /* Q0 */
159 : )
160 : {
161 :
162 : Word16 i;
163 : Word16 factor, neg_factor;
164 : Word16 factor_e;
165 : (void) element_mode;
166 : #ifdef BASOP_NOGLOB_DECLARE_LOCAL
167 1425 : Flag Overflow = 0;
168 1425 : move32();
169 : #endif
170 1425 : factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e ); /* exp(factor_e) */
171 1425 : *y_e = add( *y_e, factor_e );
172 1425 : move16();
173 :
174 1425 : neg_factor = negate( factor );
175 :
176 :
177 : /* Init */
178 317775 : FOR( i = 0; i < m / 2; i++ )
179 : {
180 316350 : y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
181 316350 : move32();
182 : }
183 247475 : FOR( i = 0; i < l / 2; i++ )
184 : {
185 246050 : y[m / 2 + r / 2 + m / 2 + i] = L_msu_o( L_mult( x[i], neg_factor ), x[l - 1 - i], factor, &Overflow ); /* exp(y_e) */
186 246050 : move32();
187 : }
188 317775 : FOR( i = 0; i < m / 2; i++ )
189 : {
190 316350 : y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
191 316350 : move32();
192 : }
193 247475 : FOR( i = 0; i < r / 2; i++ )
194 : {
195 246050 : 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) */
196 246050 : move32();
197 : }
198 :
199 1425 : *y_e = sub( 15, *y_e );
200 1425 : move16();
201 :
202 1425 : edst_fx( y, y, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), y_e );
203 :
204 1425 : *y_e = sub( 15 - 1, *y_e );
205 1425 : move16();
206 :
207 1425 : return;
208 : }
209 :
210 122520 : void TCX_MDCT_Inverse(
211 : Word32 *x, // Q( 31 - x_e )
212 : Word16 x_e,
213 : Word16 *y, /* Qy */
214 : const Word16 l, /* Q0 */
215 : const Word16 m, /* Q0 */
216 : const Word16 r, /* Q0 */
217 : const Word16 element_mode /* Q0 */
218 : )
219 : {
220 :
221 : Word16 i, fac, negfac, s;
222 122520 : Word16 L2 = l, R2 = r;
223 : Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
224 : Word16 fac_e;
225 : (void) element_mode;
226 122520 : L2 = shr( l, 1 );
227 122520 : R2 = shr( r, 1 );
228 :
229 122520 : x_e = sub( 15, x_e );
230 122520 : edct_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
231 122520 : x_e = sub( 15, x_e );
232 :
233 122520 : fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e ); /* exp(fac_e) */
234 122520 : x_e = add( x_e, fac_e );
235 :
236 122520 : negfac = negate( fac );
237 :
238 122520 : s = x_e;
239 122520 : move16();
240 :
241 9272994 : FOR( i = 0; i < R2; i++ )
242 : {
243 9150474 : 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)*/
244 :
245 9150474 : move16();
246 : }
247 :
248 8982102 : FOR( i = 0; i < L2; i++ )
249 : {
250 8859582 : 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)*/
251 8859582 : move16();
252 : }
253 :
254 17843312 : FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
255 : {
256 : Word16 f;
257 :
258 17720792 : f = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
259 17720792 : 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)*/
260 17720792 : move16();
261 17720792 : y[l + m + R2 - 1 - i] = f;
262 17720792 : move16();
263 : }
264 122520 : }
265 :
266 20 : void TCX_MDST_Inverse_fx(
267 : Word32 *x, /* exp(x_e) */
268 : Word16 x_e,
269 : Word16 *y, /* Qx */
270 : const Word16 l, /* Q0 */
271 : const Word16 m, /* Q0 */
272 : const Word16 r /* Q0 */
273 : )
274 : {
275 :
276 : Word16 i, fac, negfac, s;
277 20 : Word16 L2 = l, R2 = r;
278 20 : move16();
279 20 : move16();
280 : Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
281 : Word16 fac_e;
282 :
283 20 : L2 = shr( l, 1 );
284 20 : R2 = shr( r, 1 );
285 :
286 20 : x_e = sub( 15, x_e );
287 20 : edst_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
288 20 : x_e = sub( 15, x_e );
289 :
290 20 : fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
291 20 : x_e = add( x_e, fac_e );
292 :
293 20 : negfac = negate( fac );
294 :
295 20 : s = x_e;
296 20 : move16();
297 :
298 934 : FOR( i = 0; i < R2; i++ )
299 : {
300 914 : 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)*/
301 914 : move16();
302 : }
303 :
304 934 : FOR( i = 0; i < L2; i++ )
305 : {
306 914 : 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)*/
307 914 : move16();
308 : }
309 :
310 1556 : FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
311 : {
312 : Word16 f;
313 1536 : f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], fac ), s ) );
314 :
315 1536 : 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)*/
316 1536 : move16();
317 :
318 1536 : y[l + m + R2 - 1 - i] = negate( f );
319 1536 : move16();
320 : }
321 20 : }
322 :
323 : /*-------------------------------------------------------------------*
324 : * TCX_MDXT_Inverse_fx()
325 : *
326 : *
327 : *-------------------------------------------------------------------*/
328 :
329 62 : void TCX_MDXT_Inverse_fx(
330 : const Word32 *x, /* exp(x_e) */
331 : Word16 x_e,
332 : Word16 *y, /* Qx */
333 : const Word16 l, /* Q0 */
334 : const Word16 m, /* Q0 */
335 : const Word16 r, /* Q0 */
336 : const UWord16 kernel_type /* Q0 */
337 : )
338 : {
339 : Word16 signLeft;
340 : Word16 signRight;
341 : Word16 i, fac, negfac, s, fac_e;
342 62 : const Word16 L2 = shr( l, 1 ), R2 = shr( r, 1 );
343 : Word32 tmp_buf[N_MAX + L_MDCT_OVLP_MAX / 2];
344 : Word16 f;
345 :
346 62 : set32_fx( tmp_buf, 0, N_MAX + L_MDCT_OVLP_MAX / 2 );
347 :
348 62 : edxt_fx( x, tmp_buf + L2, add( add( L2, m ), R2 ), kernel_type, TRUE );
349 :
350 62 : fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e );
351 62 : x_e = add( x_e, fac_e );
352 :
353 62 : negfac = negate( fac );
354 62 : IF( GE_16( kernel_type, MDCT_II ) )
355 : {
356 46 : signLeft = negfac;
357 : }
358 : ELSE
359 : {
360 16 : signLeft = fac;
361 : }
362 : // signRight = ( kernel_type & 1 ? fac : negfac );
363 62 : IF( L_and( kernel_type, 1 ) )
364 : {
365 16 : signRight = fac;
366 : }
367 : ELSE
368 : {
369 46 : signRight = negfac;
370 : }
371 :
372 62 : s = x_e;
373 62 : move16();
374 :
375 3424 : FOR( i = 0; i < L2; i++ )
376 : {
377 3362 : 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)*/
378 : }
379 :
380 3464 : FOR( i = 0; i < R2; i++ )
381 : {
382 3402 : 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)*/
383 3402 : move16();
384 : }
385 :
386 4750 : FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
387 : {
388 :
389 4688 : f = round_fx( L_shl( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
390 :
391 4688 : 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)*/
392 4688 : move16();
393 :
394 4688 : y[l + m + R2 - 1 - i] = f;
395 4688 : move16();
396 : }
397 :
398 62 : return;
399 : }
|