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 75736 : 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 75736 : in = in + shr( sub( decimate, 1 ), 1 );
27 75736 : out = out + sub( L, 1 );
28 7198440 : FOR( i = 0; i < L; i++ )
29 : {
30 7122704 : *out = *in;
31 7122704 : move16();
32 7122704 : in += decimate;
33 7122704 : out--;
34 : }
35 75736 : }
36 : /*--------------------------------------------------------------------------*
37 : * mvr2r_dec()
38 : *
39 : *
40 : *--------------------------------------------------------------------------*/
41 75248 : 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 75248 : in = in + shr( sub( decimate, 1 ), 1 );
50 7136032 : FOR( i = 0; i < L; i++ )
51 : {
52 7060784 : *out = *in;
53 7060784 : move16();
54 7060784 : in += decimate;
55 7060784 : out++;
56 : }
57 75248 : }
58 : /*--------------------------------------------------------------------------*
59 : * copy_win()
60 : *
61 : *
62 : *--------------------------------------------------------------------------*/
63 :
64 150984 : 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 150984 : IF( decimate < 0 )
74 : {
75 75736 : set16_fx( out_win, 32767, nb_one ); // Q15
76 75736 : mvs2s_inv( in_win, out_win + nb_one, win_lenght, negate( decimate ) );
77 75736 : set16_fx( out_win + add( win_lenght, nb_one ), 0, nb_zero );
78 : }
79 : ELSE
80 : {
81 75248 : set16_fx( out_win, 0, nb_zero );
82 75248 : mvs2s_dec( in_win, out_win + nb_zero, win_lenght, decimate );
83 75248 : set16_fx( out_win + add( nb_zero, win_lenght ), 32767, nb_one ); // Q15
84 : }
85 150984 : }
86 : /*--------------------------------------------------------------------------*
87 : * tcx_get_windows_mode1()
88 : *
89 : *
90 : *--------------------------------------------------------------------------*/
91 :
92 3274815 : 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 3274815 : IF( EQ_16( left_mode, MIN_OVERLAP ) )
104 : {
105 12418 : test();
106 12418 : IF( EQ_16( L, 256 ) || EQ_16( L, 512 ) )
107 : {
108 1106 : 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 11312 : copy_win( left_win, R1_48 - 4 * R2_48 / 7, small_overlap_48, R2_48 / 7, 3 * R2_48 / 7, 1 ); // Q15
113 11312 : 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 3262397 : ELSE IF( EQ_16( left_mode, HALF_OVERLAP ) )
117 : {
118 27045 : test();
119 27045 : IF( EQ_16( L, 256 ) || EQ_16( L, 512 ) )
120 : {
121 2572 : 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 24473 : copy_win( left_win, R1_48 - 5 * R2_48 / 7, half_overlap_48, 3 * R2_48 / 7, 2 * R2_48 / 7, 1 ); // Q15
126 24473 : 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 3235352 : ELSE IF( EQ_16( left_mode, ALDO_WINDOW ) ) /* ALDO */
130 : {
131 3235352 : test();
132 3235352 : IF( EQ_16( L, 256 ) || EQ_16( L, 512 ) )
133 : {
134 321282 : Copy( window_256kHz, left_win, R1_25 ); // Q15
135 : }
136 : ELSE
137 : {
138 2914070 : Copy( window_48kHz_fx, left_win, R1_48 ); // Q15
139 2914070 : 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 3274815 : test();
149 3274815 : IF( EQ_16( right_mode, MIN_OVERLAP ) || EQ_16( right_mode, TRANSITION_OVERLAP ) )
150 : {
151 12586 : test();
152 12586 : IF( EQ_16( L, 256 ) || EQ_16( L, 512 ) )
153 : {
154 1558 : 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 11028 : copy_win( right_win, 3 * R2_48 / 7, small_overlap_48, R2_48 / 7, 3 * R2_48 / 7, -1 ); // Q15
160 11028 : copy_win( right_win_int, 3 * R2_16 / 7, small_overlap_int, R2_16 / 7, 3 * R2_16 / 7, -1 ); // Q15
161 : }
162 : }
163 3262229 : ELSE IF( EQ_16( right_mode, HALF_OVERLAP ) )
164 : {
165 27395 : test();
166 27395 : IF( EQ_16( L, 256 ) || EQ_16( L, 512 ) )
167 : {
168 2668 : 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 24727 : copy_win( right_win, 2 * R2_48 / 7, half_overlap_48, 3 * R2_48 / 7, 2 * R2_48 / 7, -1 ); // Q15
173 24727 : 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 3234834 : ELSE IF( EQ_16( right_mode, ALDO_WINDOW ) )
177 : {
178 3234834 : test();
179 3234834 : IF( EQ_16( L, 256 ) || EQ_16( L, 512 ) )
180 : {
181 320734 : Copy( window_256kHz + R1_25, right_win, R2_25 ); // Q15
182 : }
183 : ELSE
184 : {
185 2914100 : Copy( window_48kHz_fx + R1_48, right_win, R2_48 ); // Q15
186 2914100 : 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 3274815 : }
194 :
195 : /*--------------------------------------------------------------------------*
196 : * wtda()
197 : *
198 : * Windowing and time-domain aliasing
199 : *--------------------------------------------------------------------------*/
200 :
201 869788 : 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 869788 : tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L );
224 :
225 869788 : decimate = 1;
226 869788 : move16(); /* L_FRAME 48k */
227 869788 : decay = 0;
228 869788 : move16();
229 869788 : windecay48 = WINDECAY48;
230 869788 : move16();
231 869788 : n = R1_48 - R2_48;
232 869788 : move16();
233 :
234 869788 : test();
235 869788 : IF( EQ_16( L, L_FRAME32k ) || EQ_16( L, L_FRAME16k ) )
236 : {
237 229757 : decimate = 3;
238 229757 : move16();
239 229757 : decay = 1;
240 229757 : move16();
241 229757 : n = R1_16 - R2_16;
242 229757 : move16();
243 :
244 229757 : if ( EQ_16( L, L_FRAME32k ) )
245 : {
246 182096 : n = 2 * N16_CORE_SW;
247 182096 : move16();
248 : }
249 : }
250 640031 : 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 869788 : IF( old_wtda == NULL )
261 : {
262 :
263 844377 : allsig_r = new_audio + n;
264 844377 : allsig_l = new_audio + sub( n, L );
265 : }
266 : ELSE
267 : {
268 : /* Rescale signals if Q are not identical */
269 :
270 25411 : IF( GT_16( *Qold_wtda, *Q ) )
271 : {
272 :
273 11002 : Copy_Scale_sig( old_wtda, old_wtda, L, sub( *Q, *Qold_wtda ) );
274 11002 : *Qold_wtda = *Q;
275 11002 : move16();
276 : }
277 14409 : 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 25411 : allsig_r = new_audio + n;
285 25411 : allsig_l = old_wtda + n;
286 : }
287 :
288 :
289 869788 : IF( EQ_16( L, L_FRAME32k ) )
290 : {
291 :
292 : /* decimate = 3 */
293 : /* decay =1 */
294 :
295 182096 : pa = wtda_audio;
296 182096 : p1 = allsig_r + L_FRAME16k - 1;
297 182096 : p2 = win_int_right + ( 3 * L_FRAME16k / 2 - 1 - WINDECAY16 ); /* 3*L/2*decimate-decimate+decay-windecay48;*/
298 182096 : p3 = p1 + 1;
299 182096 : p4 = p2 + 1;
300 :
301 182096 : p5 = win_right + ( ( 3 * L_FRAME16k / 2 - 1 ) * 3 + 1 - WINDECAY48 );
302 182096 : p6 = win_right + ( ( 3 * L_FRAME16k / 2 + 1 ) * 3 - 1 - 1 - WINDECAY48 );
303 :
304 12928816 : FOR( i = 0; i < L_FRAME16k - 2 * N16_CORE_SW; i += 2 )
305 : {
306 12746720 : *pa++ = L_negate( L_mac0( L_mult0( *p1--, *p2-- ), *p3++, *p4++ ) );
307 12746720 : move32();
308 12746720 : *pa++ = L_negate( L_mac0( L_mult0( *p1--, *p5 ), *p3++, *p6 ) );
309 12746720 : move32();
310 12746720 : p5 -= decimate;
311 12746720 : p6 += decimate;
312 : /* Q + 15 */
313 : }
314 :
315 16570736 : FOR( i = 0; i < n; i += 2 )
316 : {
317 16388640 : *pa++ = L_mult( *p1--, -16384 );
318 16388640 : move32();
319 16388640 : *pa++ = L_mult( *p1--, -16384 );
320 16388640 : move32();
321 : }
322 :
323 182096 : pa = wtda_audio + L_FRAME16k;
324 182096 : p1 = allsig_l;
325 182096 : p2 = win_left + 1;
326 182096 : p3 = new_audio + 2 * N16_CORE_SW - 1;
327 182096 : p4 = win_int_left;
328 :
329 16570736 : FOR( i = 0; i < n; i += 2 )
330 : {
331 16388640 : *pa++ = L_mac0( L_mult0( *p1++, *p2 ), *p3--, -32768 );
332 16388640 : move32();
333 16388640 : *pa++ = L_mac0( L_mult0( *p1++, *p4++ ), *p3--, -32768 );
334 16388640 : move32();
335 16388640 : p2 += decimate;
336 : }
337 :
338 182096 : p5 = allsig_l + L_FRAME32k - 1 - N16_CORE_SW * 2;
339 182096 : p6 = win_left + ( L_FRAME16k - N16_CORE_SW ) * 3 - 1 - 1;
340 182096 : p3 = win_int_left + ( L_FRAME16k - N16_CORE_SW - 1 );
341 :
342 182096 : tmp = sub( shr( L, 1 ), n );
343 12928816 : FOR( i = 0; i < tmp; i += 2 )
344 : {
345 12746720 : *pa++ = L_msu0( L_mult0( *p1++, *p2 ), *p5--, *p6 );
346 12746720 : move32();
347 12746720 : *pa++ = L_msu0( L_mult0( *p1++, *p4++ ), *p5--, *p3-- );
348 12746720 : move32();
349 12746720 : p2 += decimate;
350 12746720 : p6 -= decimate;
351 : }
352 : }
353 : ELSE
354 : {
355 687692 : pa = wtda_audio;
356 687692 : p1 = allsig_r + sub( shr( L, 1 ), 1 );
357 687692 : 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 687692 : p3 = p1 + 1;
359 687692 : p4 = win_right + sub( sub( sub( add( i_mult2( i_mult2( 3, shr( L, 1 ) ), decimate ), decimate ), decay ), windecay48 ), 1 );
360 :
361 687692 : tmp = sub( shr( L, 1 ), n );
362 138430472 : 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 137742780 : *pa++ = L_msu0( L_msu0( 0, *p1--, *p2 ), *p3++, *p4 );
366 137742780 : move32();
367 137742780 : p2 -= decimate;
368 137742780 : p4 += decimate;
369 : /* Q + 15 */
370 : }
371 :
372 177785552 : FOR( i = 0; i < n; i++ )
373 : {
374 177097860 : *pa++ = L_negate( L_shr( L_deposit_h( *p1-- ), 1 ) );
375 177097860 : move32();
376 : /* wtda_audio[i]=-allsig_r[L/2-i-1]; */
377 : }
378 :
379 :
380 687692 : pa = wtda_audio + shr( L, 1 );
381 687692 : p1 = allsig_l;
382 687692 : p2 = win_left + decay;
383 687692 : p3 = new_audio + sub( n, 1 );
384 :
385 177785552 : FOR( i = 0; i < n; i++ )
386 : {
387 177097860 : *pa++ = L_mac0( L_mult0( *p1++, *p2 ), *p3--, -32768 );
388 177097860 : move32();
389 177097860 : p2 += decimate;
390 : /* wtda_audio[i+L/2]=allsig_l[i]*win_left[i*decimate+decay]-new_audio[n-i-1];*/
391 : }
392 :
393 687692 : p3 = allsig_l + sub( sub( L, 1 ), n );
394 687692 : p4 = win_left + sub( sub( i_mult2( sub( L, n ), decimate ), 1 ), decay );
395 :
396 687692 : tmp = sub( shr( L, 1 ), n );
397 138430472 : FOR( i = 0; i < tmp; i++ )
398 : {
399 137742780 : *pa++ = L_msu0( L_mult0( *p1++, *p2 ), *p3--, *p4 );
400 137742780 : move32();
401 137742780 : p2 += decimate;
402 137742780 : 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 869788 : *Q = add( *Q, 15 ); /* output Q */
408 869788 : move16();
409 :
410 869788 : IF( old_wtda != NULL )
411 : {
412 :
413 25411 : Copy( new_audio, old_wtda, L );
414 : }
415 869788 : return;
416 : }
417 :
418 12399 : 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 12399 : tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L );
437 :
438 12399 : decimate = 1; /* L_FRAME 48k */
439 12399 : move16();
440 12399 : decay = 0;
441 12399 : move16();
442 12399 : windecay48 = extract_l( WINDECAY48 ); // (int16_t)(2 * ((float)L_FRAME48k * N_ZERO_MDCT_NS / FRAME_SIZE_NS)) + R1_48
443 :
444 12399 : test();
445 12399 : IF( EQ_16( L, L_FRAME32k ) || EQ_16( L, L_FRAME16k ) )
446 : {
447 1997 : decimate = 3;
448 1997 : move16();
449 1997 : decay = 1;
450 1997 : move16();
451 : }
452 10402 : 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 12399 : SWITCH( L ) // (int16_t)((float)L * N_ZERO_MDCT_NS / FRAME_SIZE_NS)
461 : {
462 1245 : case L_FRAME16k:
463 1245 : n = 90;
464 1245 : move16();
465 1245 : BREAK;
466 752 : case L_FRAME32k:
467 752 : n = 180;
468 752 : move16();
469 752 : BREAK;
470 10402 : case L_FRAME48k:
471 10402 : n = 270;
472 10402 : move16();
473 10402 : 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 12399 : 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 12399 : i = 0;
484 12399 : move16();
485 :
486 12399 : 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 12399 : allsig_r = new_audio + n;
494 12399 : allsig_l = old_wtda + n;
495 : }
496 :
497 12399 : 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 2283217 : FOR( i = 0; i < L / 2 - n; i++ )
552 : {
553 2271570 : idx1 = sub( sub( shr( L, 1 ), i ), 1 );
554 2271570 : idx2 = sub( add( sub( i_mult( i_mult( 3, shr( L, 1 ) ), decimate ), i_mult( add( i, 1 ), decimate ) ), decay ), windecay48 );
555 2271570 : idx3 = add( shr( L, 1 ), i );
556 2271570 : idx4 = sub( sub( add( sub( i_mult( i_mult( 3, shr( L, 1 ) ), decimate ), 1 ), i_mult( add( i, 1 ), decimate ) ), decay ), windecay48 );
557 2271570 : 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 2271570 : move32();
559 : }
560 :
561 2932237 : FOR( i = L / 2 - n; i < L / 2; i++ )
562 : {
563 2920590 : wtda_audio[i] = L_negate( allsig_r[( ( ( L >> 1 ) - i ) - 1 )] );
564 2920590 : move32();
565 : }
566 :
567 2932237 : FOR( i = 0; i < n; i++ )
568 : {
569 2920590 : 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 2920590 : move32();
571 : }
572 :
573 2283217 : FOR( i = n; i < L / 2; i++ )
574 : {
575 2271570 : idx1 = i;
576 2271570 : move16();
577 2271570 : idx2 = add( i_mult( i, decimate ), decay );
578 2271570 : idx3 = sub( sub( L, i ), 1 );
579 2271570 : idx4 = sub( sub( sub( i_mult( L, decimate ), i_mult( i, decimate ) ), 1 ), decay );
580 2271570 : 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 2271570 : move32();
582 : }
583 : }
584 :
585 12399 : IF( old_wtda != NULL )
586 : {
587 12399 : Copy32( new_audio, old_wtda, L );
588 : }
589 :
590 12399 : return;
591 : }
592 :
593 609758 : 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 609758 : tcx_get_windows_mode1( left_mode, right_mode, win_left, win_right, win_int_left, win_int_right, L );
611 :
612 609758 : decimate = 1; /* L_FRAME48k */
613 609758 : move16();
614 609758 : decay = 0;
615 609758 : move16();
616 609758 : windecay48 = ( 2 * ( (Word64) L_FRAME48k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_48;
617 609758 : move16();
618 :
619 609758 : test();
620 609758 : IF( EQ_16( L, L_FRAME32k ) || EQ_16( L, L_FRAME16k ) )
621 : {
622 192944 : decimate = 3;
623 192944 : move16();
624 192944 : decay = 1;
625 192944 : move16();
626 : }
627 416814 : 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 609758 : n = extract_l( Mpy_32_32( L, 603979776 /* N_ZERO_MDCT_NS / FRAME_SIZE_NS in Q31 */ ) );
636 609758 : move16();
637 :
638 609758 : windecay16 = ( 2 * ( L_FRAME16k * N_ZERO_MDCT_NS / FRAME_SIZE_NS ) ) + R1_16;
639 609758 : move16();
640 :
641 609758 : allsig_r = new_audio + n;
642 609758 : allsig_l = new_audio + n - L;
643 :
644 609758 : IF( EQ_16( L, L_FRAME32k ) )
645 : {
646 155372 : IF( UL_and( kernel_type, 1 ) )
647 : {
648 11025164 : FOR( i = 0; i < L / 2 - n; i += 2 )
649 : {
650 10869880 : 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 10869880 : allsig_r[L / 2 + i], win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16] ) ); // q_in - 1
652 10869880 : move16();
653 10869880 : 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 10869880 : allsig_r[L / 2 + i + 1], win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48] ) ); // q_in - 1
655 10869880 : move16();
656 : }
657 : }
658 : ELSE
659 : {
660 6248 : FOR( i = 0; i < L / 2 - n; i += 2 )
661 : {
662 6160 : 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 6160 : allsig_r[L / 2 + i], win_int_right[3 * L_FRAME16k / 2 + i / 2 - windecay16] ) ); // q_in - 1
664 6160 : move16();
665 6160 : 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 6160 : allsig_r[L / 2 + i + 1], win_right[( 3 * L_FRAME16k / 2 + 1 + i / 2 ) * decimate - decay - 1 - windecay48] ) ); // q_in - 1
667 6160 : move16();
668 : }
669 : }
670 :
671 14138852 : FOR( i = L / 2 - n; i < L / 2; i += 2 )
672 : {
673 13983480 : wtda_audio[i] = shr( negate( allsig_r[L / 2 - i - 1] ), 1 ); // q_in - 1
674 13983480 : move16();
675 13983480 : wtda_audio[i + 1] = shr( negate( allsig_r[L / 2 - ( i + 1 ) - 1] ), 1 ); // q_in - 1
676 13983480 : move16();
677 : }
678 :
679 155372 : IF( GE_32( kernel_type, 2 ) )
680 : {
681 14130389 : FOR( i = 0; i < n; i += 2 )
682 : {
683 13975110 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( negate( allsig_l[i] ), win_left[( i / 2 ) * decimate + decay] ),
684 13975110 : new_audio[n - i - 1], MAX16B ) ); // q_in - 1
685 13975110 : move16();
686 13975110 : wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( negate( allsig_l[i + 1] ), win_int_left[i / 2] ),
687 13975110 : new_audio[n - ( i + 1 ) - 1], MAX16B ) ); // q_in - 1
688 13975110 : move16();
689 : }
690 :
691 11024809 : FOR( i = n; i < L / 2; i += 2 )
692 : {
693 10869530 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( negate( allsig_l[i] ), win_left[( i / 2 ) * decimate + decay] ),
694 10869530 : allsig_l[L - i - 1], win_left[( L / 2 - i / 2 ) * decimate - 1 - decay] ) ); // q_in - 1
695 10869530 : move16();
696 10869530 : wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( negate( allsig_l[i + 1] ), win_int_left[i / 2] ),
697 10869530 : allsig_l[L - ( i + 1 ) - 1], win_int_left[L / 2 - i / 2 - 1] ) ); // q_in - 1
698 10869530 : move16();
699 : }
700 : }
701 : ELSE
702 : {
703 8463 : FOR( i = 0; i < n; i += 2 )
704 : {
705 8370 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[( i / 2 ) * decimate + decay] ),
706 8370 : new_audio[n - i - 1], MAX16B ) ); // q_in - 1
707 8370 : move16();
708 8370 : wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( allsig_l[i + 1], win_int_left[i / 2] ),
709 8370 : new_audio[n - ( i + 1 ) - 1], MAX16B ) ); // q_in - 1
710 8370 : move16();
711 : }
712 :
713 6603 : FOR( i = n; i < L / 2; i += 2 )
714 : {
715 6510 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[( i / 2 ) * decimate + decay] ),
716 6510 : allsig_l[L - i - 1], win_left[( L / 2 - i / 2 ) * decimate - 1 - decay] ) ); // q_in - 1
717 6510 : move16();
718 6510 : wtda_audio[i + L / 2 + 1] = round_fx( L_msu0( L_mult0( allsig_l[i + 1], win_int_left[i / 2] ),
719 6510 : allsig_l[L - ( i + 1 ) - 1], win_int_left[L / 2 - i / 2 - 1] ) ); // q_in - 1
720 6510 : move16();
721 : }
722 : }
723 : }
724 : ELSE
725 : {
726 454386 : IF( UL_and( kernel_type, 1 ) )
727 : {
728 90596807 : FOR( i = 0; i < L / 2 - n; i++ )
729 : {
730 90142570 : 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 90142570 : allsig_r[L / 2 + i], win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48] ) ); // q_in - 1
732 90142570 : move16();
733 : }
734 : }
735 : ELSE
736 : {
737 18559 : FOR( i = 0; i < L / 2 - n; i++ )
738 : {
739 18410 : 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 18410 : allsig_r[L / 2 + i], win_right[3 * L / 2 * decimate - 1 + ( i + 1 ) * decimate - decay - windecay48] ) ); // q_in - 1
741 18410 : move16();
742 : }
743 : }
744 :
745 116375646 : FOR( i = L / 2 - n; i < L / 2; i++ )
746 : {
747 115921260 : wtda_audio[i] = shr( negate( allsig_r[L / 2 - i - 1] ), 1 ); // q_in - 1
748 115921260 : move16();
749 : }
750 :
751 454386 : IF( GE_32( kernel_type, 2 ) )
752 : {
753 116350735 : FOR( i = 0; i < n; i++ )
754 : {
755 115896510 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( negate( allsig_l[i] ), win_left[i * decimate + decay] ),
756 115896510 : new_audio[n - i - 1], MAX16B ) ); // q_in - 1
757 115896510 : move16();
758 : }
759 :
760 90595955 : FOR( i = n; i < L / 2; i++ )
761 : {
762 90141730 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( negate( allsig_l[i] ), win_left[i * decimate + decay] ),
763 90141730 : allsig_l[L - i - 1], win_left[L * decimate - i * decimate - 1 - decay] ) ); // q_in - 1
764 90141730 : move16();
765 : }
766 : }
767 : ELSE
768 : {
769 24911 : FOR( i = 0; i < n; i++ )
770 : {
771 24750 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[i * decimate + decay] ),
772 24750 : new_audio[n - i - 1], MAX16B ) ); // q_in - 1
773 24750 : move16();
774 : }
775 :
776 19411 : FOR( i = n; i < L / 2; i++ )
777 : {
778 19250 : wtda_audio[i + L / 2] = round_fx( L_msu0( L_mult0( allsig_l[i], win_left[i * decimate + decay] ),
779 19250 : allsig_l[L - i - 1], win_left[L * decimate - i * decimate - 1 - decay] ) ); // q_in - 1
780 19250 : move16();
781 : }
782 : }
783 : }
784 :
785 609758 : return;
786 : }
|