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 695591 : static Word16 TCX_MDCT_GetScaleFactor(
12 : const Word16 L, /* Q0 */
13 : Word16 *factor_e /* Q0 */
14 : )
15 : {
16 :
17 : Word16 factor;
18 :
19 695591 : 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 661597 : ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
27 : {
28 123803 : factor = 23170;
29 123803 : move16();
30 123803 : *factor_e = 0;
31 123803 : move16();
32 : }
33 537794 : ELSE IF( EQ_16( L, shl( NORM_MDCT_FACTOR, 2 ) ) )
34 : {
35 19142 : factor = 16384;
36 19142 : move16();
37 19142 : *factor_e = 0;
38 19142 : move16();
39 : }
40 : ELSE
41 : {
42 :
43 518652 : factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
44 518652 : *factor_e = 4;
45 518652 : move16();
46 :
47 518652 : factor = ISqrt16( factor, factor_e );
48 : }
49 :
50 695591 : return factor;
51 : }
52 :
53 137012 : static Word16 TCX_MDCT_Inverse_GetScaleFactor(
54 : const Word16 L, /* Q0 */
55 : Word16 *factor_e /* Q0 */
56 : )
57 : {
58 :
59 : Word16 factor;
60 :
61 137012 : 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 90504 : ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
69 : {
70 19132 : factor = 23170;
71 19132 : move16();
72 19132 : *factor_e = 1;
73 19132 : move16();
74 : }
75 71372 : ELSE IF( EQ_16( L, 4 * NORM_MDCT_FACTOR ) )
76 : {
77 1106 : factor = 32767;
78 1106 : move16();
79 1106 : *factor_e = 1;
80 1106 : move16();
81 : }
82 : ELSE
83 : {
84 70266 : factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
85 70266 : *factor_e = 4;
86 70266 : move16();
87 :
88 70266 : factor = Sqrt16( factor, factor_e );
89 : }
90 :
91 137012 : return factor;
92 : }
93 :
94 :
95 417426 : 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 417426 : Flag Overflow = 0;
112 417426 : move32();
113 : #endif
114 417426 : factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e );
115 417426 : *y_e = add( *y_e, factor_e );
116 417426 : move16();
117 :
118 417426 : neg_factor = negate( factor );
119 :
120 :
121 : /* Init */
122 39078136 : FOR( i = 0; i < m / 2; i++ )
123 : {
124 38660710 : y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
125 38660710 : move32();
126 : }
127 22729944 : FOR( i = 0; i < l / 2; i++ )
128 : {
129 22312518 : 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 22312518 : move32();
131 : }
132 39078136 : FOR( i = 0; i < m / 2; i++ )
133 : {
134 38660710 : y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
135 38660710 : move32();
136 : }
137 25218144 : FOR( i = 0; i < r / 2; i++ )
138 : {
139 24800718 : 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 24800718 : move32();
141 : }
142 :
143 417426 : *y_e = sub( 15, *y_e );
144 417426 : move16();
145 417426 : edct_fx( y, y, l / 2 + m + r / 2, y_e );
146 417426 : *y_e = sub( 15 - 1, *y_e );
147 417426 : move16();
148 417426 : return;
149 : }
150 :
151 278165 : 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 278165 : Flag Overflow = 0;
168 278165 : move32();
169 : #endif
170 278165 : factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e ); /* exp(factor_e) */
171 278165 : *y_e = add( *y_e, factor_e );
172 278165 : move16();
173 :
174 278165 : neg_factor = negate( factor );
175 :
176 :
177 : /* Init */
178 67227225 : FOR( i = 0; i < m / 2; i++ )
179 : {
180 66949060 : y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
181 66949060 : move32();
182 : }
183 47340765 : FOR( i = 0; i < l / 2; i++ )
184 : {
185 47062600 : 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 47062600 : move32();
187 : }
188 67227225 : FOR( i = 0; i < m / 2; i++ )
189 : {
190 66949060 : y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
191 66949060 : move32();
192 : }
193 49798885 : FOR( i = 0; i < r / 2; i++ )
194 : {
195 49520720 : 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 49520720 : move32();
197 : }
198 :
199 278165 : *y_e = sub( 15, *y_e );
200 278165 : move16();
201 :
202 278165 : edst_fx( y, y, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), y_e );
203 :
204 278165 : *y_e = sub( 15 - 1, *y_e );
205 278165 : move16();
206 :
207 278165 : return;
208 : }
209 :
210 136930 : 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 136930 : 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 136930 : L2 = shr( l, 1 );
227 136930 : R2 = shr( r, 1 );
228 :
229 136930 : x_e = sub( 15, x_e );
230 136930 : edct_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
231 136930 : x_e = sub( 15, x_e );
232 :
233 136930 : fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e ); /* exp(fac_e) */
234 136930 : x_e = add( x_e, fac_e );
235 :
236 136930 : negfac = negate( fac );
237 :
238 136930 : s = x_e;
239 136930 : move16();
240 :
241 10244016 : FOR( i = 0; i < R2; i++ )
242 : {
243 10107086 : 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 10107086 : move16();
246 : }
247 :
248 9941264 : FOR( i = 0; i < L2; i++ )
249 : {
250 9804334 : 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 9804334 : move16();
252 : }
253 :
254 20042282 : FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
255 : {
256 : Word16 f;
257 :
258 19905352 : f = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
259 19905352 : 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 19905352 : move16();
261 19905352 : y[l + m + R2 - 1 - i] = f;
262 19905352 : move16();
263 : }
264 136930 : }
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 : }
|