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