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 703730 : static Word16 TCX_MDCT_GetScaleFactor(
12 : const Word16 L, /* Q0 */
13 : Word16 *factor_e /* Q0 */
14 : )
15 : {
16 :
17 : Word16 factor;
18 :
19 703730 : IF( EQ_16( L, NORM_MDCT_FACTOR ) )
20 : {
21 34640 : factor = 32767;
22 34640 : move16();
23 34640 : *factor_e = 0;
24 34640 : move16();
25 : }
26 669090 : ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
27 : {
28 124611 : factor = 23170;
29 124611 : move16();
30 124611 : *factor_e = 0;
31 124611 : move16();
32 : }
33 544479 : ELSE IF( EQ_16( L, shl( NORM_MDCT_FACTOR, 2 ) ) )
34 : {
35 19324 : factor = 16384;
36 19324 : move16();
37 19324 : *factor_e = 0;
38 19324 : move16();
39 : }
40 : ELSE
41 : {
42 :
43 525155 : factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
44 525155 : *factor_e = 4;
45 525155 : move16();
46 :
47 525155 : factor = ISqrt16( factor, factor_e );
48 : }
49 :
50 703730 : return factor;
51 : }
52 :
53 31678 : static Word16 TCX_MDCT_Inverse_GetScaleFactor(
54 : const Word16 L, /* Q0 */
55 : Word16 *factor_e /* Q0 */
56 : )
57 : {
58 :
59 : Word16 factor;
60 :
61 31678 : IF( EQ_16( L, NORM_MDCT_FACTOR ) )
62 : {
63 21109 : factor = 32767;
64 21109 : move16();
65 21109 : *factor_e = 0;
66 21109 : move16();
67 : }
68 10569 : ELSE IF( EQ_16( L, 2 * NORM_MDCT_FACTOR ) )
69 : {
70 5624 : factor = 23170;
71 5624 : move16();
72 5624 : *factor_e = 1;
73 5624 : move16();
74 : }
75 4945 : ELSE IF( EQ_16( L, 4 * NORM_MDCT_FACTOR ) )
76 : {
77 97 : factor = 32767;
78 97 : move16();
79 97 : *factor_e = 1;
80 97 : move16();
81 : }
82 : ELSE
83 : {
84 4848 : factor = mult_r( shl( L, 4 ), 26214 /*128.f / NORM_MDCT_FACTOR*/ ); /* 4Q11 */
85 4848 : *factor_e = 4;
86 4848 : move16();
87 :
88 4848 : factor = Sqrt16( factor, factor_e );
89 : }
90 :
91 31678 : return factor;
92 : }
93 :
94 :
95 421683 : 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 421683 : factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e );
112 421683 : *y_e = add( *y_e, factor_e );
113 421683 : move16();
114 :
115 421683 : neg_factor = negate( factor );
116 :
117 : /* Init */
118 39570335 : FOR( i = 0; i < m / 2; i++ )
119 : {
120 39148652 : y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
121 39148652 : move32();
122 : }
123 22934521 : FOR( i = 0; i < l / 2; i++ )
124 : {
125 22512838 : 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 22512838 : move32();
127 : }
128 39570335 : FOR( i = 0; i < m / 2; i++ )
129 : {
130 39148652 : y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
131 39148652 : move32();
132 : }
133 25533701 : FOR( i = 0; i < r / 2; i++ )
134 : {
135 25112018 : 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 25112018 : move32();
137 : }
138 :
139 421683 : *y_e = sub( 15, *y_e );
140 421683 : move16();
141 421683 : edct_fx( y, y, l / 2 + m + r / 2, y_e );
142 421683 : *y_e = sub( 15 - 1, *y_e );
143 421683 : move16();
144 421683 : return;
145 : }
146 :
147 282047 : 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 282047 : factor = TCX_MDCT_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &factor_e ); /* exp(factor_e) */
164 282047 : *y_e = add( *y_e, factor_e );
165 282047 : move16();
166 :
167 282047 : neg_factor = negate( factor );
168 :
169 :
170 : /* Init */
171 67705827 : FOR( i = 0; i < m / 2; i++ )
172 : {
173 67423780 : y[m / 2 + r / 2 + i] = L_mult( x[l + m / 2 - 1 - i], neg_factor ); /* exp(y_e) */
174 67423780 : move32();
175 : }
176 47539917 : FOR( i = 0; i < l / 2; i++ )
177 : {
178 47257870 : 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 47257870 : move32();
180 : }
181 67705827 : FOR( i = 0; i < m / 2; i++ )
182 : {
183 67423780 : y[m / 2 + r / 2 - 1 - i] = L_mult( x[l + m / 2 + i], neg_factor ); /* exp(y_e) */
184 67423780 : move32();
185 : }
186 50108937 : FOR( i = 0; i < r / 2; i++ )
187 : {
188 49826890 : 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 49826890 : move32();
190 : }
191 :
192 282047 : *y_e = sub( 15, *y_e );
193 282047 : move16();
194 :
195 282047 : edst_fx( y, y, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), y_e );
196 :
197 282047 : *y_e = sub( 15 - 1, *y_e );
198 282047 : move16();
199 :
200 282047 : return;
201 : }
202 :
203 31678 : 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 31678 : 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 31678 : L2 = shr( l, 1 );
220 31678 : R2 = shr( r, 1 );
221 :
222 31678 : x_e = sub( 15, x_e );
223 31678 : edct_fx( x, tmp_buf + L2, add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &x_e );
224 31678 : x_e = sub( 15, x_e );
225 :
226 31678 : fac = TCX_MDCT_Inverse_GetScaleFactor( add( add( shr( l, 1 ), m ), shr( r, 1 ) ), &fac_e ); /* exp(fac_e) */
227 31678 : x_e = add( x_e, fac_e );
228 :
229 31678 : negfac = negate( fac );
230 :
231 31678 : s = x_e;
232 31678 : move16();
233 :
234 1636987 : FOR( i = 0; i < R2; i++ )
235 : {
236 1605309 : 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 1605309 : move16();
239 : }
240 :
241 1625127 : FOR( i = 0; i < L2; i++ )
242 : {
243 1593449 : 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 1593449 : move16();
245 : }
246 :
247 3734678 : FOR( i = 0; i < ( ( L2 + m + R2 ) >> 1 ); i++ )
248 : {
249 : Word16 f;
250 :
251 3703000 : f = round_fx_sat( L_shl_sat( Mpy_32_16_1( tmp_buf[L2 + i], negfac ), s ) );
252 3703000 : 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 3703000 : move16();
254 3703000 : y[l + m + R2 - 1 - i] = f;
255 3703000 : move16();
256 : }
257 31678 : }
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 : }
|