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 695138 : static Word16 TCX_MDCT_GetScaleFactor(
12 : const Word16 L, /* Q0 */
13 : Word16 *factor_e /* Q0 */
14 : )
15 : {
16 :
17 : Word16 factor;
18 :
19 695138 : IF( EQ_16( L, NORM_MDCT_FACTOR ) )
20 : {
21 33994 : factor = 32767;
22 33994 : move16();
23 33994 : *factor_e = 0;
24 33994 : move16();
25 : }
26 661144 : ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
27 : {
28 123118 : factor = 23170;
29 123118 : move16();
30 123118 : *factor_e = 0;
31 123118 : move16();
32 : }
33 538026 : ELSE IF( EQ_16( L, shl( NORM_MDCT_FACTOR, 2 ) ) )
34 : {
35 18586 : factor = 16384;
36 18586 : move16();
37 18586 : *factor_e = 0;
38 18586 : move16();
39 : }
40 : ELSE
41 : {
42 :
43 519440 : factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
44 519440 : *factor_e = 4;
45 519440 : move16();
46 :
47 519440 : factor = ISqrt16( factor, factor_e );
48 : }
49 :
50 695138 : return factor;
51 : }
52 :
53 137016 : static Word16 TCX_MDCT_Inverse_GetScaleFactor(
54 : const Word16 L, /* Q0 */
55 : Word16 *factor_e /* Q0 */
56 : )
57 : {
58 :
59 : Word16 factor;
60 :
61 137016 : IF( EQ_16( L, NORM_MDCT_FACTOR ) )
62 : {
63 46508 : factor = 32767;
64 46508 : move16();
65 46508 : *factor_e = 0;
66 46508 : move16();
67 : }
68 90508 : ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
69 : {
70 19134 : factor = 23170;
71 19134 : move16();
72 19134 : *factor_e = 1;
73 19134 : move16();
74 : }
75 71374 : ELSE IF( EQ_16( L, 4 * NORM_MDCT_FACTOR ) )
76 : {
77 1107 : factor = 32767;
78 1107 : move16();
79 1107 : *factor_e = 1;
80 1107 : move16();
81 : }
82 : ELSE
83 : {
84 70267 : factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
85 70267 : *factor_e = 4;
86 70267 : move16();
87 :
88 70267 : factor = Sqrt16( factor, factor_e );
89 : }
90 :
91 137016 : return factor;
92 : }
93 :
94 :
95 417441 : 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 417441 : Flag Overflow = 0;
112 417441 : move32();
113 : #endif
114 417441 : factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e );
115 417441 : *y_e = add( *y_e, factor_e );
116 417441 : move16();
117 :
118 417441 : neg_factor = negate( factor );
119 :
120 :
121 : /* Init */
122 39107235 : FOR( i = 0; i < m / 2; i++ )
123 : {
124 38689794 : y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
125 38689794 : move32();
126 : }
127 22730189 : FOR( i = 0; i < l / 2; i++ )
128 : {
129 22312748 : 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 22312748 : move32();
131 : }
132 39107235 : FOR( i = 0; i < m / 2; i++ )
133 : {
134 38689794 : y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
135 38689794 : move32();
136 : }
137 25221569 : FOR( i = 0; i < r / 2; i++ )
138 : {
139 24804128 : 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 24804128 : move32();
141 : }
142 :
143 417441 : *y_e = sub( 15, *y_e );
144 417441 : move16();
145 417441 : edct_fx( y, y, l / 2 + m + r / 2, y_e );
146 417441 : *y_e = sub( 15 - 1, *y_e );
147 417441 : move16();
148 417441 : return;
149 : }
150 :
151 277697 : 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 277697 : Flag Overflow = 0;
168 277697 : move32();
169 : #endif
170 277697 : factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e ); /* exp(factor_e) */
171 277697 : *y_e = add( *y_e, factor_e );
172 277697 : move16();
173 :
174 277697 : neg_factor = negate( factor );
175 :
176 :
177 : /* Init */
178 67169537 : FOR( i = 0; i < m / 2; i++ )
179 : {
180 66891840 : y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
181 66891840 : move32();
182 : }
183 47289117 : FOR( i = 0; i < l / 2; i++ )
184 : {
185 47011420 : 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 47011420 : move32();
187 : }
188 67169537 : FOR( i = 0; i < m / 2; i++ )
189 : {
190 66891840 : y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
191 66891840 : move32();
192 : }
193 49750597 : FOR( i = 0; i < r / 2; i++ )
194 : {
195 49472900 : 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 49472900 : move32();
197 : }
198 :
199 277697 : *y_e = sub( 15, *y_e );
200 277697 : move16();
201 :
202 277697 : edst_fx( y, y, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), y_e );
203 :
204 277697 : *y_e = sub( 15 - 1, *y_e );
205 277697 : move16();
206 :
207 277697 : return;
208 : }
209 :
210 136934 : 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 136934 : 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 136934 : L2 = shr( l, 1 );
227 136934 : R2 = shr( r, 1 );
228 :
229 136934 : x_e = sub( 15, x_e );
230 136934 : edct_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
231 136934 : x_e = sub( 15, x_e );
232 :
233 136934 : fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e ); /* exp(fac_e) */
234 136934 : x_e = add( x_e, fac_e );
235 :
236 136934 : negfac = negate( fac );
237 :
238 136934 : s = x_e;
239 136934 : move16();
240 :
241 10244244 : FOR( i = 0; i < R2; i++ )
242 : {
243 10107310 : 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 10107310 : move16();
246 : }
247 :
248 9941492 : FOR( i = 0; i < L2; i++ )
249 : {
250 9804558 : 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 9804558 : move16();
252 : }
253 :
254 20042926 : FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
255 : {
256 : Word16 f;
257 :
258 19905992 : f = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
259 19905992 : 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 19905992 : move16();
261 19905992 : y[l + m + R2 - 1 - i] = f;
262 19905992 : move16();
263 : }
264 136934 : }
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 : }
|