Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 : #include <stdint.h>
5 : #include <assert.h>
6 : #include "options.h" /* Compilation switches */
7 : #include "cnst.h" /* Common constants */
8 : #include "rom_com.h" /* Static table prototypes */
9 : #include "prot_fx.h" /* required by wmc_tool */
10 : #include "stat_com.h"
11 : #include "wmc_auto.h"
12 :
13 : /*--------------------------------------------------------------------------*
14 : * mvr2r_inv()
15 : *
16 : *
17 : *--------------------------------------------------------------------------*/
18 39986 : static void mvs2s_inv(
19 : const Word16 *in, /* i : input vector */
20 : Word16 *out, /* o : output vector */
21 : const Word16 L, /* i : length */
22 : const Word16 decimate /* i : decimation flag [-1,1] */
23 : )
24 : {
25 : Word16 i;
26 39986 : in = in + shr( sub( decimate, 1 ), 1 );
27 39986 : out = out + sub( L, 1 );
28 3611218 : FOR( i = 0; i < L; i++ )
29 : {
30 3571232 : *out = *in;
31 3571232 : move16();
32 3571232 : in += decimate;
33 3571232 : out--;
34 : }
35 39986 : }
36 : /*--------------------------------------------------------------------------*
37 : * mvr2r_dec()
38 : *
39 : *
40 : *--------------------------------------------------------------------------*/
41 33734 : static void mvs2s_dec(
42 : const Word16 *in, /* i : input vector */
43 : Word16 *out, /* o : output vector */
44 : const Word16 L, /* i : length */
45 : const Word16 decimate /* i : decimation flag [-1,1] */
46 : )
47 : {
48 : Word16 i;
49 33734 : in = in + shr( sub( decimate, 1 ), 1 );
50 3308454 : FOR( i = 0; i < L; i++ )
51 : {
52 3274720 : *out = *in;
53 3274720 : move16();
54 3274720 : in += decimate;
55 3274720 : out++;
56 : }
57 33734 : }
58 : /*--------------------------------------------------------------------------*
59 : * copy_win()
60 : *
61 : *
62 : *--------------------------------------------------------------------------*/
63 :
64 73720 : static void copy_win(
65 : Word16 *out_win, /* o : output window buffer Q15*/
66 : const Word16 nb_zero, /* i : length of zero padding */
67 : const Word16 *in_win, /* i : input window */
68 : const Word16 win_lenght, /* i : length */
69 : const Word16 nb_one, /* i : length of flat section (ones) */
70 : const Word16 decimate /* i : input window */
71 : )
72 : {
73 73720 : IF( decimate < 0 )
74 : {
75 39986 : set16_fx( out_win, 32767, nb_one ); // Q15
76 39986 : mvs2s_inv( in_win, out_win + nb_one, win_lenght, negate( decimate ) );
77 39986 : set16_fx( out_win + add( win_lenght, nb_one ), 0, nb_zero );
78 : }
79 : ELSE
80 : {
81 33734 : set16_fx( out_win, 0, nb_zero );
82 33734 : mvs2s_dec( in_win, out_win + nb_zero, win_lenght, decimate );
83 33734 : set16_fx( out_win + add( nb_zero, win_lenght ), 32767, nb_one ); // Q15
84 : }
85 73720 : }
86 : /*--------------------------------------------------------------------------*
87 : * tcx_get_windows_mode1()
88 : *
89 : *
90 : *--------------------------------------------------------------------------*/
91 :
92 1671921 : void tcx_get_windows_mode1(
93 : const Word16 left_mode, /* i: overlap mode of left window half */
94 : const Word16 right_mode, /* i: overlap mode of right window half */
95 : Word16 *left_win, /* o: left overlap window */
96 : Word16 *right_win, /* o: right overlap window */
97 : Word16 *left_win_int, /* o: left overlap window */
98 : Word16 *right_win_int, /* o: right overlap window */
99 : const Word16 L /* i : length */
100 : )
101 : {
102 : /* Left part */
103 1671921 : IF( EQ_16( left_mode, MIN_OVERLAP ) )
104 : {
105 4892 : test();
106 4892 : IF( EQ_16( L, 256 ) || EQ_16( L, 512 ) )
107 : {
108 948 : copy_win( left_win, R1_25 - 4 * R2_25 / 7, small_overlap_25, R2_25 / 7, 3 * R2_25 / 7, 1 ); // Q15
109 : }
110 : ELSE
111 : {
112 3944 : copy_win( left_win, R1_48 - 4 * R2_48 / 7, small_overlap_48, R2_48 / 7, 3 * R2_48 / 7, 1 ); // Q15
113 3944 : copy_win( left_win_int, R1_16 - 4 * R2_16 / 7, small_overlap_int, R2_16 / 7, 3 * R2_16 / 7, 1 ); // Q15
114 : }
115 : }
116 1667029 : ELSE IF( EQ_16( left_mode, HALF_OVERLAP ) )
117 : {
118 13676 : test();
119 13676 : IF( EQ_16( L, 256 ) || EQ_16( L, 512 ) )
120 : {
121 2454 : copy_win( left_win, R1_25 - 5 * R2_25 / 7, half_overlap_25, 3 * R2_25 / 7, 2 * R2_25 / 7, 1 ); // Q15
122 : }
123 : ELSE
124 : {
125 11222 : copy_win( left_win, R1_48 - 5 * R2_48 / 7, half_overlap_48, 3 * R2_48 / 7, 2 * R2_48 / 7, 1 ); // Q15
126 11222 : copy_win( left_win_int, R1_16 - 5 * R2_16 / 7, half_overlap_int, 3 * R2_16 / 7, 2 * R2_16 / 7, 1 ); // Q15
127 : }
128 : }
129 1653353 : ELSE IF( EQ_16( left_mode, ALDO_WINDOW ) ) /* ALDO */
130 : {
131 1653353 : test();
132 1653353 : IF( EQ_16( L, 256 ) || EQ_16( L, 512 ) )
133 : {
134 283677 : Copy( window_256kHz, left_win, R1_25 ); // Q15
135 : }
136 : ELSE
137 : {
138 1369676 : Copy( window_48kHz_fx, left_win, R1_48 ); // Q15
139 1369676 : Copy( window_8_16_32kHz_fx, left_win_int, R1_16 ); // Q15
140 : }
141 : }
142 : ELSE
143 : {
144 : /*assert(!"Window not supported");*/
145 : }
146 :
147 : /* Right part */
148 1671921 : test();
149 1671921 : IF( EQ_16( right_mode, MIN_OVERLAP ) || EQ_16( right_mode, TRANSITION_OVERLAP ) )
150 : {
151 7951 : test();
152 7951 : IF( EQ_16( L, 256 ) || EQ_16( L, 512 ) )
153 : {
154 1477 : copy_win( right_win, 3 * R2_25 / 7, small_overlap_25, R2_25 / 7, 3 * R2_25 / 7, -1 ); // Q15
155 : }
156 : ELSE
157 : {
158 :
159 6474 : copy_win( right_win, 3 * R2_48 / 7, small_overlap_48, R2_48 / 7, 3 * R2_48 / 7, -1 ); // Q15
160 6474 : copy_win( right_win_int, 3 * R2_16 / 7, small_overlap_int, R2_16 / 7, 3 * R2_16 / 7, -1 ); // Q15
161 : }
162 : }
163 1663970 : ELSE IF( EQ_16( right_mode, HALF_OVERLAP ) )
164 : {
165 14057 : test();
166 14057 : IF( EQ_16( L, 256 ) || EQ_16( L, 512 ) )
167 : {
168 2553 : copy_win( right_win, 2 * R2_25 / 7, half_overlap_25, 3 * R2_25 / 7, 2 * R2_25 / 7, -1 ); // Q15
169 : }
170 : ELSE
171 : {
172 11504 : copy_win( right_win, 2 * R2_48 / 7, half_overlap_48, 3 * R2_48 / 7, 2 * R2_48 / 7, -1 ); // Q15
173 11504 : copy_win( right_win_int, 2 * R2_16 / 7, half_overlap_int, 3 * R2_16 / 7, 2 * R2_16 / 7, -1 ); // Q15
174 : }
175 : }
176 1649913 : ELSE IF( EQ_16( right_mode, ALDO_WINDOW ) )
177 : {
178 1649913 : test();
179 1649913 : IF( EQ_16( L, 256 ) || EQ_16( L, 512 ) )
180 : {
181 283049 : Copy( window_256kHz + R1_25, right_win, R2_25 ); // Q15
182 : }
183 : ELSE
184 : {
185 1366864 : Copy( window_48kHz_fx + R1_48, right_win, R2_48 ); // Q15
186 1366864 : Copy( window_8_16_32kHz_fx + R1_16, right_win_int, R2_16 ); // Q15
187 : }
188 : }
189 : ELSE
190 : {
191 : /* assert(!"Window not supported");*/
192 : }
193 1671921 : }
194 :
195 : /*--------------------------------------------------------------------------*
196 : * wtda()
197 : *
198 : * Windowing and time-domain aliasing
199 : *--------------------------------------------------------------------------*/
200 :
201 9014 : void wtda_fx(
202 : Word16 *new_audio, /* i : input audio Q0 */
203 : Word16 *Q, /* i/o : Q of input/Output Audio */
204 : Word32 *wtda_audio, /* o : windowed audio Qout */
205 : Word16 *old_wtda, /* i/o: windowed audio from previous frame Qout */
206 : Word16 *Qold_wtda,
207 : const Word16 left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */
208 : const Word16 right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */
209 : const Word16 L /* i : length */
210 : )
211 : {
212 : Word16 i, decimate, decay, tmp;
213 : Word16 n, windecay48;
214 : Word16 *allsig_l;
215 : Word16 *allsig_r;
216 : Word16 win_right[R2_48];
217 : Word16 win_int_left[R1_16];
218 : Word16 win_left[R1_48];
219 : Word16 win_int_right[R2_16];
220 : Word16 *p1, *p2, *p3, *p4, *p5, *p6;
221 : Word32 *pa;
222 :
223 9014 : tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L );
224 :
225 9014 : decimate = 1;
226 9014 : move16(); /* L_FRAME 48k */
227 9014 : decay = 0;
228 9014 : move16();
229 9014 : windecay48 = WINDECAY48;
230 9014 : move16();
231 9014 : n = R1_48 - R2_48;
232 9014 : move16();
233 :
234 9014 : test();
235 9014 : IF( EQ_16( L, L_FRAME32k ) || EQ_16( L, L_FRAME16k ) )
236 : {
237 1321 : decimate = 3;
238 1321 : move16();
239 1321 : decay = 1;
240 1321 : move16();
241 1321 : n = R1_16 - R2_16;
242 1321 : move16();
243 :
244 1321 : if ( EQ_16( L, L_FRAME32k ) )
245 : {
246 508 : n = 2 * N16_CORE_SW;
247 508 : move16();
248 : }
249 : }
250 7693 : ELSE IF( EQ_16( L, L_FRAME8k ) )
251 : {
252 0 : decimate = 6;
253 0 : move16();
254 0 : decay = 2;
255 0 : move16();
256 0 : n = ( R1_16 - R2_16 ) / 2;
257 0 : move16();
258 : }
259 :
260 9014 : IF( old_wtda == NULL )
261 : {
262 :
263 144 : allsig_r = new_audio + n;
264 144 : allsig_l = new_audio + sub( n, L );
265 : }
266 : ELSE
267 : {
268 : /* Rescale signals if Q are not identical */
269 :
270 8870 : IF( GT_16( *Qold_wtda, *Q ) )
271 : {
272 :
273 0 : Copy_Scale_sig( old_wtda, old_wtda, L, sub( *Q, *Qold_wtda ) );
274 0 : *Qold_wtda = *Q;
275 0 : move16();
276 : }
277 8870 : ELSE IF( LT_16( *Qold_wtda, *Q ) )
278 : {
279 6 : Copy_Scale_sig( new_audio, new_audio, L, sub( *Qold_wtda, *Q ) );
280 6 : *Q = *Qold_wtda;
281 6 : move16();
282 : }
283 :
284 8870 : allsig_r = new_audio + n;
285 8870 : allsig_l = old_wtda + n;
286 : }
287 :
288 :
289 9014 : IF( EQ_16( L, L_FRAME32k ) )
290 : {
291 :
292 : /* decimate = 3 */
293 : /* decay =1 */
294 :
295 508 : pa = wtda_audio;
296 508 : p1 = allsig_r + L_FRAME16k - 1;
297 508 : p2 = win_int_right + ( 3 * L_FRAME16k / 2 - 1 - WINDECAY16 ); /* 3*L/2*decimate-decimate+decay-windecay48;*/
298 508 : p3 = p1 + 1;
299 508 : p4 = p2 + 1;
300 :
301 508 : p5 = win_right + ( ( 3 * L_FRAME16k / 2 - 1 ) * 3 + 1 - WINDECAY48 );
302 508 : p6 = win_right + ( ( 3 * L_FRAME16k / 2 + 1 ) * 3 - 1 - 1 - WINDECAY48 );
303 :
304 36068 : FOR( i = 0; i < L_FRAME16k - 2 * N16_CORE_SW; i += 2 )
305 : {
306 35560 : *pa++ = L_negate( L_mac0( L_mult0( *p1--, *p2-- ), *p3++, *p4++ ) );
307 35560 : move32();
308 35560 : *pa++ = L_negate( L_mac0( L_mult0( *p1--, *p5 ), *p3++, *p6 ) );
309 35560 : move32();
310 35560 : p5 -= decimate;
311 35560 : p6 += decimate;
312 : /* Q + 15 */
313 : }
314 :
315 46228 : FOR( i = 0; i < n; i += 2 )
316 : {
317 45720 : *pa++ = L_mult( *p1--, -16384 );
318 45720 : move32();
319 45720 : *pa++ = L_mult( *p1--, -16384 );
320 45720 : move32();
321 : }
322 :
323 508 : pa = wtda_audio + L_FRAME16k;
324 508 : p1 = allsig_l;
325 508 : p2 = win_left + 1;
326 508 : p3 = new_audio + 2 * N16_CORE_SW - 1;
327 508 : p4 = win_int_left;
328 :
329 46228 : FOR( i = 0; i < n; i += 2 )
330 : {
331 45720 : *pa++ = L_mac0( L_mult0( *p1++, *p2 ), *p3--, -32768 );
332 45720 : move32();
333 45720 : *pa++ = L_mac0( L_mult0( *p1++, *p4++ ), *p3--, -32768 );
334 45720 : move32();
335 45720 : p2 += decimate;
336 : }
337 :
338 508 : p5 = allsig_l + L_FRAME32k - 1 - N16_CORE_SW * 2;
339 508 : p6 = win_left + ( L_FRAME16k - N16_CORE_SW ) * 3 - 1 - 1;
340 508 : p3 = win_int_left + ( L_FRAME16k - N16_CORE_SW - 1 );
341 :
342 508 : tmp = sub( shr( L, 1 ), n );
343 36068 : FOR( i = 0; i < tmp; i += 2 )
344 : {
345 35560 : *pa++ = L_msu0( L_mult0( *p1++, *p2 ), *p5--, *p6 );
346 35560 : move32();
347 35560 : *pa++ = L_msu0( L_mult0( *p1++, *p4++ ), *p5--, *p3-- );
348 35560 : move32();
349 35560 : p2 += decimate;
350 35560 : p6 -= decimate;
351 : }
352 : }
353 : ELSE
354 : {
355 8506 : pa = wtda_audio;
356 8506 : p1 = allsig_r + sub( shr( L, 1 ), 1 );
357 8506 : p2 = win_right + sub( add( sub( i_mult2( i_mult2( 3, shr( L, 1 ) ), decimate ), decimate ), decay ), windecay48 ); /* 3*L/2*decimate-decimate+decay-windecay48;*/
358 8506 : p3 = p1 + 1;
359 8506 : p4 = win_right + sub( sub( sub( add( i_mult2( i_mult2( 3, shr( L, 1 ) ), decimate ), decimate ), decay ), windecay48 ), 1 );
360 :
361 8506 : tmp = sub( shr( L, 1 ), n );
362 1680946 : FOR( i = 0; i < tmp; i++ )
363 : {
364 : /* wtda_audio[i]=-allsig_r[L/2-i-1]*win_right[3*L/2*decimate-(i+1)*decimate+decay-windecay48]-allsig_r[L/2+i]*win_right[3*L/2*decimate-1+(i+1)*decimate-decay-windecay48];*/
365 1672440 : *pa++ = L_msu0( L_msu0( 0, *p1--, *p2 ), *p3++, *p4 );
366 1672440 : move32();
367 1672440 : p2 -= decimate;
368 1672440 : p4 += decimate;
369 : /* Q + 15 */
370 : }
371 :
372 2158786 : FOR( i = 0; i < n; i++ )
373 : {
374 2150280 : *pa++ = L_negate( L_shr( L_deposit_h( *p1-- ), 1 ) );
375 2150280 : move32();
376 : /* wtda_audio[i]=-allsig_r[L/2-i-1]; */
377 : }
378 :
379 :
380 8506 : pa = wtda_audio + shr( L, 1 );
381 8506 : p1 = allsig_l;
382 8506 : p2 = win_left + decay;
383 8506 : p3 = new_audio + sub( n, 1 );
384 :
385 2158786 : FOR( i = 0; i < n; i++ )
386 : {
387 2150280 : *pa++ = L_mac0( L_mult0( *p1++, *p2 ), *p3--, -32768 );
388 2150280 : move32();
389 2150280 : p2 += decimate;
390 : /* wtda_audio[i+L/2]=allsig_l[i]*win_left[i*decimate+decay]-new_audio[n-i-1];*/
391 : }
392 :
393 8506 : p3 = allsig_l + sub( sub( L, 1 ), n );
394 8506 : p4 = win_left + sub( sub( i_mult2( sub( L, n ), decimate ), 1 ), decay );
395 :
396 8506 : tmp = sub( shr( L, 1 ), n );
397 1680946 : FOR( i = 0; i < tmp; i++ )
398 : {
399 1672440 : *pa++ = L_msu0( L_mult0( *p1++, *p2 ), *p3--, *p4 );
400 1672440 : move32();
401 1672440 : p2 += decimate;
402 1672440 : p4 -= decimate;
403 : /* wtda_audio[i+L/2]=allsig_l[i]*win_left[i*decimate+decay]-allsig_l[L-i-1]*win_left[L*decimate-i*decimate-1-decay];*/
404 : }
405 : }
406 :
407 9014 : *Q = add( *Q, 15 ); /* output Q */
408 9014 : move16();
409 :
410 9014 : IF( old_wtda != NULL )
411 : {
412 :
413 8870 : Copy( new_audio, old_wtda, L );
414 : }
415 9014 : return;
416 : }
417 :
418 12649 : void wtda_fx32(
419 : const Word32 *new_audio, /* i : input audio Q11 */
420 : Word32 *wtda_audio, /* o : windowed audio Q11 */
421 : Word32 *old_wtda, /* i/o: windowed audio from previous frame */
422 : const Word16 left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */
423 : const Word16 right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */
424 : const Word16 L /* i : length */
425 : )
426 : {
427 : Word16 i, decimate, decay;
428 : Word16 idx1, idx2, idx3, idx4;
429 : Word16 n, windecay48, windecay16;
430 : const Word32 *allsig_l, *allsig_r;
431 : Word16 win_right[R2_48];
432 : Word16 win_int_left[R1_16];
433 : Word16 win_left[R1_48];
434 : Word16 win_int_right[R2_16];
435 :
436 12649 : tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L );
437 :
438 12649 : decimate = 1; /* L_FRAME 48k */
439 12649 : move16();
440 12649 : decay = 0;
441 12649 : move16();
442 12649 : windecay48 = extract_l( WINDECAY48 ); // (int16_t)(2 * ((float)L_FRAME48k * N_ZERO_MDCT_NS / FRAME_SIZE_NS)) + R1_48
443 :
444 12649 : test();
445 12649 : IF( EQ_16( L, L_FRAME32k ) || EQ_16( L, L_FRAME16k ) )
446 : {
447 2016 : decimate = 3;
448 2016 : move16();
449 2016 : decay = 1;
450 2016 : move16();
451 : }
452 10633 : ELSE IF( EQ_16( L, L_FRAME8k ) )
453 : {
454 0 : decimate = 6;
455 0 : move16();
456 0 : decay = 2;
457 0 : move16();
458 : }
459 :
460 12649 : SWITCH( L ) // (int16_t)((float)L * N_ZERO_MDCT_NS / FRAME_SIZE_NS)
461 : {
462 1264 : case L_FRAME16k:
463 1264 : n = 90;
464 1264 : move16();
465 1264 : BREAK;
466 752 : case L_FRAME32k:
467 752 : n = 180;
468 752 : move16();
469 752 : BREAK;
470 10633 : case L_FRAME48k:
471 10633 : n = 270;
472 10633 : move16();
473 10633 : BREAK;
474 0 : default:
475 0 : n = (Word16) ( ( L * N_ZERO_MDCT_NS ) / FRAME_SIZE_NS );
476 0 : move16();
477 0 : BREAK;
478 : }
479 :
480 12649 : windecay16 = extract_l( WINDECAY16 ); // (int16_t)(2 * ((float)L_FRAME16k * N_ZERO_MDCT_NS / FRAME_SIZE_NS)) + R1_16;
481 :
482 : /* algorithmic delay reduction */
483 12649 : i = 0;
484 12649 : move16();
485 :
486 12649 : IF( old_wtda == NULL )
487 : {
488 0 : allsig_r = new_audio + n;
489 0 : allsig_l = new_audio + n - L;
490 : }
491 : ELSE
492 : {
493 12649 : allsig_r = new_audio + n;
494 12649 : allsig_l = old_wtda + n;
495 : }
496 :
497 12649 : IF( EQ_16( L, L_FRAME32k ) )
498 : {
499 53392 : FOR( i = 0; i < ( L / 2 - n ); i += 2 )
500 : {
501 52640 : idx1 = sub( sub( shr( L, 1 ), i ), 1 );
502 52640 : idx2 = sub( sub( 3 * L_FRAME16k / 2 - 1, shr( i, 1 ) ), windecay16 );
503 52640 : idx3 = add( shr( L, 1 ), i );
504 52640 : idx4 = sub( add( 3 * L_FRAME16k / 2, shr( i, 1 ) ), windecay16 );
505 52640 : wtda_audio[i] = L_sub_sat( Mpy_32_16_1( -allsig_r[idx1], win_int_right[idx2] ), Mpy_32_16_1( allsig_r[idx3], win_int_right[idx4] ) );
506 52640 : move32();
507 :
508 52640 : idx1 = sub( sub( shr( L, 1 ), add( i, 1 ) ), 1 );
509 52640 : idx2 = sub( add( i_mult( ( sub( sub( 3 * L_FRAME16k / 2, shr( i, 1 ) ), 1 ) ), decimate ), decay ), windecay48 );
510 52640 : idx3 = add( add( shr( L, 1 ), i ), 1 );
511 52640 : idx4 = sub( sub( sub( i_mult( ( add( 3 * L_FRAME16k / 2 + 1, shr( i, 1 ) ) ), decimate ), decay ), 1 ), windecay48 );
512 52640 : wtda_audio[i + 1] = L_sub_sat( Mpy_32_16_1( -allsig_r[idx1], win_right[idx2] ), Mpy_32_16_1( allsig_r[idx3], win_right[idx4] ) );
513 52640 : move32();
514 : }
515 :
516 68432 : FOR( i = L / 2 - n; i < L / 2; i += 2 )
517 : {
518 67680 : wtda_audio[i] = L_negate( allsig_r[( ( ( L >> 1 ) - i ) - 1 )] );
519 67680 : move32();
520 67680 : wtda_audio[i + 1] = L_negate( allsig_r[( ( ( L >> 1 ) - ( i + 1 ) ) - 1 )] );
521 67680 : move32();
522 : }
523 68432 : FOR( i = 0; i < n; i += 2 )
524 : {
525 67680 : wtda_audio[( i + ( L >> 1 ) )] = L_sub_sat( Mpy_32_16_1( allsig_l[i], win_left[( ( ( i >> 1 ) * decimate ) + decay )] ), new_audio[( ( n - i ) - 1 )] );
526 67680 : move32();
527 67680 : wtda_audio[( ( i + ( L >> 1 ) ) + 1 )] = L_sub_sat( Mpy_32_16_1( allsig_l[i + 1], win_int_left[i / 2] ), new_audio[( ( n - ( i + 1 ) ) - 1 )] );
528 67680 : move32();
529 : }
530 :
531 53392 : FOR( i = n; i < L / 2; i += 2 )
532 : {
533 52640 : idx1 = i;
534 52640 : move16();
535 52640 : idx2 = add( i_mult( shr( i, 1 ), decimate ), decay );
536 52640 : idx3 = sub( sub( L, i ), 1 );
537 52640 : idx4 = sub( sub( i_mult( sub( shr( L, 1 ), shr( i, 1 ) ), decimate ), 1 ), decay );
538 52640 : wtda_audio[( i + ( L >> 1 ) )] = L_sub_sat( Mpy_32_16_1( allsig_l[idx1], win_left[idx2] ), Mpy_32_16_1( allsig_l[idx3], win_left[idx4] ) );
539 52640 : move32();
540 :
541 52640 : idx1 = add( i, 1 );
542 52640 : idx2 = shr( i, 1 );
543 52640 : idx3 = sub( sub( L, add( i, 1 ) ), 1 );
544 52640 : idx4 = sub( sub( shr( L, 1 ), shr( i, 1 ) ), 1 );
545 52640 : wtda_audio[( ( i + ( L >> 1 ) ) + 1 )] = L_sub_sat( Mpy_32_16_1( allsig_l[idx1], win_int_left[idx2] ), Mpy_32_16_1( allsig_l[idx3], win_int_left[idx4] ) );
546 52640 : move32();
547 : }
548 : }
549 : ELSE
550 : {
551 2333307 : FOR( i = 0; i < L / 2 - n; i++ )
552 : {
553 2321410 : idx1 = sub( sub( shr( L, 1 ), i ), 1 );
554 2321410 : idx2 = sub( add( sub( i_mult( i_mult( 3, shr( L, 1 ) ), decimate ), i_mult( add( i, 1 ), decimate ) ), decay ), windecay48 );
555 2321410 : idx3 = add( shr( L, 1 ), i );
556 2321410 : idx4 = sub( sub( add( sub( i_mult( i_mult( 3, shr( L, 1 ) ), decimate ), 1 ), i_mult( add( i, 1 ), decimate ) ), decay ), windecay48 );
557 2321410 : wtda_audio[i] = L_sub_sat( Mpy_32_16_1( -allsig_r[idx1], win_right[idx2] ), Mpy_32_16_1( allsig_r[idx3], win_right[idx4] ) );
558 2321410 : move32();
559 : }
560 :
561 2996567 : FOR( i = L / 2 - n; i < L / 2; i++ )
562 : {
563 2984670 : wtda_audio[i] = L_negate( allsig_r[( ( ( L >> 1 ) - i ) - 1 )] );
564 2984670 : move32();
565 : }
566 :
567 2996567 : FOR( i = 0; i < n; i++ )
568 : {
569 2984670 : wtda_audio[( i + ( L >> 1 ) )] = L_sub_sat( Mpy_32_16_1( allsig_l[i], win_left[( ( i * decimate ) + decay )] ), new_audio[( ( n - i ) - 1 )] );
570 2984670 : move32();
571 : }
572 :
573 2333307 : FOR( i = n; i < L / 2; i++ )
574 : {
575 2321410 : idx1 = i;
576 2321410 : move16();
577 2321410 : idx2 = add( i_mult( i, decimate ), decay );
578 2321410 : idx3 = sub( sub( L, i ), 1 );
579 2321410 : idx4 = sub( sub( sub( i_mult( L, decimate ), i_mult( i, decimate ) ), 1 ), decay );
580 2321410 : wtda_audio[( i + ( L >> 1 ) )] = L_sub_sat( Mpy_32_16_1( allsig_l[idx1], win_left[idx2] ), Mpy_32_16_1( allsig_l[idx3], win_left[idx4] ) );
581 2321410 : move32();
582 : }
583 : }
584 :
585 12649 : IF( old_wtda != NULL )
586 : {
587 12649 : Copy32( new_audio, old_wtda, L );
588 : }
589 :
590 12649 : return;
591 : }
592 :
593 0 : void wtda_ext_fx(
594 : const Word16 *new_audio, /* i : input audio (Q_in) */
595 : Word16 *wtda_audio, /* o : windowed audio (Q_in - 1) */
596 : const Word16 left_mode, /* i : window overlap of previous frame (0: full, 2: none, or 3: half) */
597 : const Word16 right_mode, /* i : window overlap of current frame (0: full, 2: none, or 3: half) */
598 : const Word16 L, /* i : length */
599 : const UWord16 kernel_type /* i : transform kernel type (0 - 3) */
600 : )
601 : {
602 : Word16 i, decimate, decay;
603 : Word16 n, windecay48, windecay16;
604 : const Word16 *allsig_l, *allsig_r;
605 : Word16 win_right[R2_48];
606 : Word16 win_int_left[R1_16];
607 : Word16 win_left[R1_48];
608 : Word16 win_int_right[R2_16];
609 :
610 0 : tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L );
611 :
612 0 : decimate = 1; /* L_FRAME48k */
613 0 : move16();
614 0 : decay = 0;
615 0 : move16();
616 0 : windecay48 = ( 2 * ( (Word64) L_FRAME48k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_48;
617 0 : move16();
618 :
619 0 : test();
620 0 : IF( EQ_16( L, L_FRAME32k ) || EQ_16( L, L_FRAME16k ) )
621 : {
622 0 : decimate = 3;
623 0 : move16();
624 0 : decay = 1;
625 0 : move16();
626 : }
627 0 : ELSE IF( EQ_16( L, L_FRAME8k ) )
628 : {
629 0 : decimate = 6;
630 0 : move16();
631 0 : decay = 2;
632 0 : move16();
633 : }
634 :
635 0 : n = extract_l( Mpy_32_32( L, 603979776 /* N_ZERO_MDCT_NS / FRAME_SIZE_NS in Q31 */ ) );
636 0 : move16();
637 :
638 0 : windecay16 = ( 2 * ( L_FRAME16k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_16;
639 0 : move16();
640 :
641 0 : allsig_r = new_audio + n;
642 0 : allsig_l = new_audio + n - L;
643 :
644 0 : IF( EQ_16( L, L_FRAME32k ) )
645 : {
646 0 : IF( UL_and( kernel_type, 1 ) )
647 : {
648 0 : FOR( i = 0; i < L / 2 - n; i += 2 )
649 : {
650 0 : wtda_audio[i] = round_fx( L_mac0( L_mult0( negate( allsig_r[L / 2 - i - 1] ), win_int_right[3 * L_FRAME16k / 2 - i / 2 - 1 - windecay16] ),
651 0 : allsig_r[L / 2 + i], win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16] ) ); // q_in - 1
652 0 : move16();
653 0 : wtda_audio[i + 1] = round_fx( L_mac0( L_mult0( negate( allsig_r[L / 2 - ( i + 1 ) - 1] ), win_right[( 3 * L_FRAME16k / 2 - i / 2 - 1 ) * decimate + decay - windecay48] ),
654 0 : allsig_r[L / 2 + i + 1], win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48] ) ); // q_in - 1
655 0 : move16();
656 : }
657 : }
658 : ELSE
659 : {
660 0 : FOR( i = 0; i < L / 2 - n; i += 2 )
661 : {
662 0 : wtda_audio[i] = round_fx( L_msu0( L_mult0( negate( allsig_r[L / 2 - i - 1] ), win_int_right[3 * L_FRAME16k / 2 - i / 2 - 1 - windecay16] ),
663 0 : allsig_r[L / 2 + i], win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16] ) ); // q_in - 1
664 0 : move16();
665 0 : wtda_audio[i + 1] = round_fx( L_msu0( L_mult0( negate( allsig_r[L / 2 - ( i + 1 ) - 1] ), win_right[( 3 * L_FRAME16k / 2 - i / 2 - 1 ) * decimate + decay - windecay48] ),
666 0 : allsig_r[L / 2 + i + 1], win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48] ) ); // q_in - 1
667 0 : move16();
668 : }
669 : }
670 :
671 0 : FOR( i = L / 2 - n; i < L / 2; i += 2 )
672 : {
673 0 : wtda_audio[i] = shr( negate( allsig_r[L / 2 - i - 1] ), 1 ); // q_in - 1
674 0 : move16();
675 0 : wtda_audio[i + 1] = shr( negate( allsig_r[L / 2 - ( i + 1 ) - 1] ), 1 ); // q_in - 1
676 0 : move16();
677 : }
678 :
679 0 : IF( GE_32( kernel_type, 2 ) )
680 : {
681 0 : FOR( i = 0; i < n; i += 2 )
682 : {
683 0 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( negate( allsig_l[i] ), win_left[( i / 2 ) * decimate + decay] ),
684 0 : new_audio[n - i - 1], MAX16B ) ); // q_in - 1
685 0 : move16();
686 0 : wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( negate( allsig_l[i + 1] ), win_int_left[i / 2] ),
687 0 : new_audio[n - ( i + 1 ) - 1], MAX16B ) ); // q_in - 1
688 0 : move16();
689 : }
690 :
691 0 : FOR( i = n; i < L / 2; i += 2 )
692 : {
693 0 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( negate( allsig_l[i] ), win_left[( i / 2 ) * decimate + decay] ),
694 0 : allsig_l[L - i - 1], win_left[( L / 2 - i / 2 ) * decimate - 1 - decay] ) ); // q_in - 1
695 0 : move16();
696 0 : wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( negate( allsig_l[i + 1] ), win_int_left[i / 2] ),
697 0 : allsig_l[L - ( i + 1 ) - 1], win_int_left[L / 2 - i / 2 - 1] ) ); // q_in - 1
698 0 : move16();
699 : }
700 : }
701 : ELSE
702 : {
703 0 : FOR( i = 0; i < n; i += 2 )
704 : {
705 0 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[( i / 2 ) * decimate + decay] ),
706 0 : new_audio[n - i - 1], MAX16B ) ); // q_in - 1
707 0 : move16();
708 0 : wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( allsig_l[i + 1], win_int_left[i / 2] ),
709 0 : new_audio[n - ( i + 1 ) - 1], MAX16B ) ); // q_in - 1
710 0 : move16();
711 : }
712 :
713 0 : FOR( i = n; i < L / 2; i += 2 )
714 : {
715 0 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[( i / 2 ) * decimate + decay] ),
716 0 : allsig_l[L - i - 1], win_left[( L / 2 - i / 2 ) * decimate - 1 - decay] ) ); // q_in - 1
717 0 : move16();
718 0 : wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( allsig_l[i + 1], win_int_left[i / 2] ),
719 0 : allsig_l[L - ( i + 1 ) - 1], win_int_left[L / 2 - i / 2 - 1] ) ); // q_in - 1
720 0 : move16();
721 : }
722 : }
723 : }
724 : ELSE
725 : {
726 0 : IF( UL_and( kernel_type, 1 ) )
727 : {
728 0 : FOR( i = 0; i < L / 2 - n; i++ )
729 : {
730 0 : wtda_audio[i] = round_fx( L_mac0( L_mult0( negate( allsig_r[L / 2 - i - 1] ), win_right[3 * L / 2 * decimate - ( i + 1 ) * decimate + decay - windecay48] ),
731 0 : allsig_r[L / 2 + i], win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48] ) ); // q_in - 1
732 0 : move16();
733 : }
734 : }
735 : ELSE
736 : {
737 0 : FOR( i = 0; i < L / 2 - n; i++ )
738 : {
739 0 : wtda_audio[i] = round_fx( L_msu0( L_mult0( negate( allsig_r[L / 2 - i - 1] ), win_right[3 * L / 2 * decimate - ( i + 1 ) * decimate + decay - windecay48] ),
740 0 : allsig_r[L / 2 + i], win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48] ) ); // q_in - 1
741 0 : move16();
742 : }
743 : }
744 :
745 0 : FOR( i = L / 2 - n; i < L / 2; i++ )
746 : {
747 0 : wtda_audio[i] = shr( negate( allsig_r[L / 2 - i - 1] ), 1 ); // q_in - 1
748 0 : move16();
749 : }
750 :
751 0 : IF( GE_32( kernel_type, 2 ) )
752 : {
753 0 : FOR( i = 0; i < n; i++ )
754 : {
755 0 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( negate( allsig_l[i] ), win_left[i * decimate + decay] ),
756 0 : new_audio[n - i - 1], MAX16B ) ); // q_in - 1
757 0 : move16();
758 : }
759 :
760 0 : FOR( i = n; i < L / 2; i++ )
761 : {
762 0 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( negate( allsig_l[i] ), win_left[i * decimate + decay] ),
763 0 : allsig_l[L - i - 1], win_left[L * decimate - i * decimate - 1 - decay] ) ); // q_in - 1
764 0 : move16();
765 : }
766 : }
767 : ELSE
768 : {
769 0 : FOR( i = 0; i < n; i++ )
770 : {
771 0 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[i * decimate + decay] ),
772 0 : new_audio[n - i - 1], MAX16B ) ); // q_in - 1
773 0 : move16();
774 : }
775 :
776 0 : FOR( i = n; i < L / 2; i++ )
777 : {
778 0 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[i * decimate + decay] ),
779 0 : allsig_l[L - i - 1], win_left[L * decimate - i * decimate - 1 - decay] ) ); // q_in - 1
780 0 : move16();
781 : }
782 : }
783 : }
784 :
785 0 : return;
786 : }
|