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 "prot_fx.h" /* Function prototypes */
7 : #include "rom_com.h" /* Function prototypes */
8 : #include "rom_dec.h"
9 :
10 :
11 : /*--------------------------------------------------------------------------*
12 : * Local constants
13 : *--------------------------------------------------------------------------*/
14 :
15 : #define NUMSF 8
16 : #define NUMSF_M1 ( NUMSF - 1 )
17 : #define NUMSF_M2 ( NUMSF - 2 )
18 : #define NUMSF_S2 ( NUMSF / 2 )
19 : #define LOG2_NUMSF 3
20 :
21 : /*--------------------------------------------------------------------------*
22 : * preecho_sb()
23 : *
24 : * Time-domain sub-band based pre-echo reduction
25 : *--------------------------------------------------------------------------*/
26 :
27 9020 : void preecho_sb_fx(
28 : const Word32 core_brate, /* i Q0 : core bit-rate */
29 : Word32 *wtda_audio_fx, /* i q_sig32 : imdct signal, used to compute imdct_mem_fx when not 24400 bps */
30 : Word16 q_sig32, /* i Q value for wtda_audio_fx */
31 : Word16 *rec_sig_fx, /* i q_sig16 : reconstructed signal, output of the imdct transform */
32 : Word16 q_sig16, /* i Q value for rec_sig_fx and imdct_mem_fx */
33 : const Word16 framelength, /* i Q0 : frame length */
34 : Word16 *memfilt_lb_fx, /* i/o Q0 : memory */
35 : Word32 *mean_prev_hb_fx, /* i/o Q0 : memory */
36 : Word16 *smoothmem_fx, /* i/o Q15 : memory */
37 : Word32 *mean_prev_fx, /* i/o Q0 : memory */
38 : Word32 *mean_prev_nc_fx, /* i/o Q0 : memory */
39 : Word16 *wmold_hb_fx, /* i/o Q15 : memory */
40 : Word16 *prevflag, /* i/o Q0 : flag */
41 : Word16 *pastpre, /* i/o Q0 : flag */
42 : const Word16 bwidth /* i Q0 : bandwidth */
43 : )
44 : {
45 : Word16 i, j, len3xLp20;
46 : Word16 zcr[9]; /* 0..3 (0..7): zero crossing of the 4 (8) subframes, 4..5: (8..10) zero crossing of the future subframes */
47 : Word16 maxnzcr[8], cntnzcr; /* max number of samples without zero crossing */
48 :
49 : Word16 maxind, stind, stind_hb, cnt2, cnt5, adv, advmem;
50 : Word16 ind2, ind3, ind4, ind5, ind6, pluslim, ind2_m1, ind2_sfl, numsf_ind2;
51 : Word16 subframelength, subsubframelength;
52 : Word16 *ptr_fx, *fxptr1, *fxptr2, *fxptr3, *fxptr4, *fxptr5, *fxptr6 /*, *fxptr7, *fxptr8*/;
53 : Word32 *fx32ptr1, *fx32ptr4, *fx32ptr5, *fx32ptr6;
54 : Word16 *sptr1, *sptr2, sptr1_loc, sptr2_loc;
55 : Word16 framelength_m1;
56 : Word16 limzcr, limmaxnzcr;
57 : Word16 num_subsubframes, log2_num_subsubframes;
58 : Word16 nb_flag, smooth_len;
59 : Word16 firstnzcr;
60 : Word16 invsmoothlenp1_fx;
61 : Word16 subframelength_s2, subframelength_s34;
62 : Word16 tmp_fx1, tmp_fx2, tmp_fx3;
63 : Word32 tmp_fxL1, tmp_fxL2, tmp_fxL3;
64 : Word32 es_mdct_fx[9]; /* 0..3 (0..7): energy of the 4 (8) subframes, 4..5: (8..10) energy of the future subframes */
65 : Word32 es_mdct_hb_fx[9]; /* 0..3 (0..7): energy of the 4 (8) subframes, 4..5: (8..10) energy of the future subframes */
66 : Word32 es_mdct_half_fx[9];
67 : Word32 es_mdct_quart_fx[9];
68 : Word32 savehalfe_fx, last2_fx, maxcrit_fx, sum_plus_es_fx, mean_plus_es_fx[65];
69 : Word32 savehalfe_hb_fx, last2_hb_fx;
70 : Word32 plus_es_mdct_fx[64], max_es_fx, max_es_hb_fx, max_plus_es_mdct_fx;
71 : Word16 imdct_mem_fx[L_FRAME48k]; /* memory of the imdct transform, used in the next frame */
72 : Word16 rec_sig_lb_fx[L_FRAME48k], rec_sig_hb_fx[L_FRAME48k]; /* 960 max frame length at 48 kHz */
73 :
74 : Word16 min_g_fx[13], g_fx, gt_fx[13];
75 : Word16 min_g_hb_fx[13], gt_hb_fx[13];
76 : Word16 preechogain_fx[L_FRAME48k + PREECHO_SMOOTH_LEN];
77 : Word16 preechogain_hb_fx[L_FRAME48k];
78 : Word16 pre_g_ch_tab[9];
79 : Word32 eshbmean2_fx, eshbmean3_fx, sxyhb2_fx, sxylb3_fx;
80 : Word16 wmold_fx;
81 : Word16 lim16_fx, lim32_fx;
82 : Word16 fattnext_fx;
83 : Word16 oldgain_fx, oldgain_hb_fx;
84 : UWord16 tmp_u16;
85 : Word32 mean_prev_hb_fx_loc, mean_prev_nc_fx_loc, mean_prev_fx_loc; /* */
86 : Word16 q16p1, qmemp1, qtmp;
87 9020 : Word16 shift_q = sub( 15, q_sig32 );
88 :
89 9020 : q16p1 = add( q_sig16, 1 );
90 9020 : qmemp1 = q16p1;
91 :
92 9020 : IF( LE_32( core_brate, HQ_32k ) )
93 : {
94 :
95 5831 : mean_prev_fx_loc = L_add( *mean_prev_fx, 0 );
96 5831 : mean_prev_hb_fx_loc = L_shl_sat( *mean_prev_hb_fx, shl( q_sig16, 1 ) ); /*Q0 to q_sig16*/
97 5831 : mean_prev_nc_fx_loc = L_add( *mean_prev_nc_fx, 0 );
98 5831 : framelength_m1 = sub( framelength, 1 );
99 5831 : nb_flag = 0;
100 5831 : move16();
101 5831 : if ( ( bwidth == NB ) )
102 : {
103 0 : nb_flag = 1;
104 0 : move16();
105 : }
106 5831 : limzcr = 16;
107 5831 : move16();
108 5831 : smooth_len = 4;
109 5831 : move16();
110 5831 : invsmoothlenp1_fx = 6554; /*0.2 in Q15*/
111 5831 : move16();
112 5831 : IF( EQ_16( nb_flag, 1 ) )
113 : {
114 0 : limzcr = 10;
115 0 : move16();
116 0 : smooth_len = PREECHO_SMOOTH_LEN;
117 0 : move16();
118 0 : invsmoothlenp1_fx = INV_PREECHO_SMOOTH_LENP1_FX;
119 0 : move16();
120 : }
121 :
122 5831 : limmaxnzcr = mult( framelength, 1365 ); /*1/24 in Q15*/ /*Q0*/
123 5831 : num_subsubframes = 8;
124 5831 : move16();
125 5831 : log2_num_subsubframes = 3;
126 5831 : move16();
127 :
128 5831 : IF( EQ_16( framelength, L_FRAME8k ) )
129 : {
130 0 : num_subsubframes = 4;
131 0 : move16();
132 0 : log2_num_subsubframes = 2;
133 0 : move16();
134 : }
135 :
136 5831 : len3xLp20 = mult_r( framelength, 7168 ); /*7*framelength/32;*/ /*Q0*/
137 : /* len3xLp20 = framelength/2-(short)((float)framelength*N_ZERO_MDCT/FRAME_SIZE_MS); in float*/
138 :
139 5831 : fxptr1 = imdct_mem_fx;
140 1102941 : FOR( i = 0; i < len3xLp20; i++ )
141 : {
142 1097110 : *fxptr1++ = negate( extract_h( L_shl_sat( wtda_audio_fx[len3xLp20 - 1 - i], shift_q ) ) ); /*Q-1*/
143 1097110 : move16(); /*convert to Word16 Q-1 with saturation (saturation not a problem here) */
144 : }
145 2513511 : FOR( i = 0; i < framelength >> 1; i++ )
146 : {
147 2507680 : *fxptr1++ = negate( extract_h( L_shl_sat( wtda_audio_fx[i], shift_q ) ) ); /*Q-1*/
148 2507680 : move16(); /*convert to Word16 Q-1 with saturation (saturation not a problem here) */
149 : }
150 :
151 5831 : qmemp1 = 0; /*already in q-1*/
152 5831 : move16();
153 :
154 5831 : subframelength = shr( framelength, LOG2_NUMSF ); /*Q0*/
155 5831 : subsubframelength = shr( subframelength, log2_num_subsubframes ); /*Q0*/
156 5831 : wmold_fx = *smoothmem_fx; /*Q15*/
157 5831 : move16();
158 5831 : subframelength_s2 = shr( subframelength, 1 ); /*Q0*/
159 5831 : subframelength_s34 = mult( subframelength, 24576 /*3/4 in Q15*/ ); /*Q0*/
160 :
161 5831 : cntnzcr = -1;
162 5831 : move16();
163 :
164 5831 : lim16_fx = 3277; /*Q15*/
165 5831 : move16();
166 5831 : lim32_fx = 328; /*Q15*/
167 5831 : move16();
168 5831 : savehalfe_fx = L_deposit_l( 0 );
169 5831 : savehalfe_hb_fx = L_deposit_l( 0 );
170 :
171 5831 : IF( *pastpre == 0 )
172 : {
173 : /* if past frame mean energies are not known (no preecho_sb in the past frame), limit max attenuation to 1*/
174 823 : lim16_fx = 32767; /*Q15*/
175 823 : move16();
176 823 : lim32_fx = 32767; /*Q15*/
177 823 : move16();
178 : }
179 :
180 5831 : *pastpre = 2;
181 5831 : move16();
182 5831 : fxptr1 = rec_sig_lb_fx; /*q_sig16*/
183 5831 : fxptr2 = rec_sig_fx; /*q_sig16*/
184 5831 : fxptr3 = rec_sig_fx + 1; /*q_sig16*/
185 5831 : fxptr4 = rec_sig_fx + 2; /*q_sig16*/
186 :
187 5831 : tmp_fxL1 = L_mult( shl_sat( *memfilt_lb_fx, q_sig16 ), 8192 ); /* *memfilt_lb_fx in q0 */
188 5831 : tmp_fxL1 = L_mac( tmp_fxL1, *fxptr3, 8192 /*Q15*/ ); /*Q16*/
189 5831 : *fxptr1 = mac_r( tmp_fxL1, *fxptr2, 16384 /*Q15*/ ); /*Q0*/
190 5831 : move16();
191 5831 : fxptr1++;
192 :
193 5009529 : FOR( j = 2; j < framelength; j++ )
194 : {
195 5003698 : tmp_fxL1 = L_mult( *fxptr2, 8192 /*Q15*/ ); /*Q16*/
196 5003698 : tmp_fxL1 = L_mac( tmp_fxL1, *fxptr4, 8192 /*Q15*/ ); /*Q16*/
197 5003698 : *fxptr1 = mac_r( tmp_fxL1, *fxptr3, 16384 /*Q15*/ ); /*Q0*/
198 5003698 : move16();
199 5003698 : fxptr1++;
200 5003698 : fxptr2++;
201 5003698 : fxptr3++;
202 5003698 : fxptr4++;
203 : }
204 :
205 5831 : tmp_fxL1 = L_mult( *fxptr2, 8192 ); /*Q16*/
206 5831 : *fxptr1 = mac_r( tmp_fxL1, *fxptr3, 16384 ); /*Q0*/
207 5831 : move16();
208 5831 : fxptr1 = rec_sig_lb_fx; /*q_sig16*/
209 5831 : fxptr2 = rec_sig_fx; /*q_sig16*/
210 5831 : fxptr3 = rec_sig_hb_fx; /*q_sig16*/
211 :
212 5021191 : FOR( j = 0; j < framelength; j++ )
213 : {
214 5015360 : *fxptr3 = sub( *fxptr2, *fxptr1 );
215 5015360 : move16();
216 5015360 : fxptr1++;
217 5015360 : fxptr2++;
218 5015360 : fxptr3++;
219 : }
220 :
221 5831 : fxptr2--;
222 5831 : *memfilt_lb_fx = shr_sat( *fxptr2, q_sig16 ); /*Q0*/
223 5831 : move16(); /* *memfilt_lb_fx in q0 */
224 :
225 : /* energy of low bands 8 present and 1 future sub-frames */
226 5831 : sptr1 = zcr; /*Q0*/
227 5831 : sptr1_loc = 0;
228 5831 : move16();
229 5831 : sptr2 = maxnzcr; /*Q0*/
230 :
231 5831 : fxptr2 = rec_sig_fx; /*q_sig16*/
232 5831 : fxptr3 = rec_sig_hb_fx; /*q_sig16*/
233 5831 : fx32ptr1 = es_mdct_fx;
234 5831 : fx32ptr5 = es_mdct_half_fx;
235 5831 : fx32ptr6 = es_mdct_quart_fx;
236 5831 : fx32ptr4 = es_mdct_hb_fx;
237 5831 : firstnzcr = 0;
238 5831 : move16();
239 52479 : FOR( j = 0; j < NUMSF; j++ ) /* 8 present subframes */
240 : {
241 46648 : tmp_fx2 = sub( j, 1 );
242 46648 : tmp_fx1 = shr_sat( *fxptr2, q16p1 ); /*q-1 to avoisd saturation in energy*/
243 46648 : tmp_fxL1 = L_mac0_sat( 25, tmp_fx1, tmp_fx1 ); /*2*(Q-1)*/
244 46648 : tmp_fxL2 = L_mac0_sat( 100, *fxptr3, *fxptr3 ); /*2*(q_sig16)*/
245 46648 : sptr2_loc = 0;
246 46648 : move16();
247 :
248 46648 : fxptr2++;
249 46648 : fxptr3++;
250 :
251 5015360 : FOR( i = 1; i < subframelength; i++ )
252 : {
253 4968712 : if ( EQ_16( i, subframelength_s2 ) )
254 : {
255 46648 : *fx32ptr5 = tmp_fxL1; /*2*(Q-1)*/
256 46648 : move32();
257 : }
258 :
259 4968712 : if ( EQ_16( i, subframelength_s34 ) )
260 : {
261 46648 : *fx32ptr6 = tmp_fxL1; /*2*(Q-1)*/
262 46648 : move32();
263 : }
264 4968712 : tmp_fx1 = shr_sat( *fxptr2, q16p1 ); /*q-1 to avoisd saturation in energy*/
265 4968712 : tmp_fxL1 = L_mac0_sat( tmp_fxL1, tmp_fx1, tmp_fx1 ); /*2*(Q-1)*/
266 4968712 : tmp_fxL2 = L_mac0_sat( tmp_fxL2, *fxptr3, *fxptr3 ); /*2*(q_sig16)*/
267 4968712 : cntnzcr = add( cntnzcr, 1 );
268 4968712 : IF( L_mult0( *fxptr2, *( fxptr2 - 1 ) ) <= 0 )
269 : {
270 738746 : sptr1_loc = add( sptr1_loc, 1 );
271 738746 : sptr2_loc = s_max( sptr2_loc, cntnzcr );
272 :
273 738746 : test();
274 738746 : if ( ( firstnzcr > 0 ) && ( GT_16( cntnzcr, maxnzcr[tmp_fx2] ) ) )
275 : {
276 9813 : maxnzcr[tmp_fx2] = cntnzcr; /*Q0*/
277 9813 : move16();
278 : }
279 :
280 738746 : firstnzcr = 0;
281 738746 : move16();
282 738746 : cntnzcr = -1;
283 738746 : move16();
284 : }
285 4968712 : fxptr2++;
286 4968712 : fxptr3++;
287 : }
288 46648 : if ( LT_16( j, NUMSF_M1 ) )
289 : {
290 40817 : cntnzcr = add( cntnzcr, 1 );
291 : }
292 46648 : sptr2_loc = s_max( sptr2_loc, cntnzcr );
293 46648 : *fx32ptr4 = tmp_fxL2; /*2*(q_sig16)*/
294 46648 : move32();
295 46648 : fx32ptr4++;
296 46648 : *sptr1 = sptr1_loc; /*Q0*/
297 46648 : move16();
298 46648 : *sptr2 = sptr2_loc; /*Q0*/
299 46648 : move16();
300 46648 : sptr1++;
301 46648 : sptr2++;
302 :
303 46648 : test();
304 46648 : if ( ( firstnzcr > 0 ) && ( GT_16( cntnzcr, maxnzcr[tmp_fx2] ) ) )
305 : {
306 876 : maxnzcr[tmp_fx2] = cntnzcr; /*Q0*/
307 876 : move16();
308 : }
309 :
310 46648 : sptr1_loc = 0;
311 46648 : move16();
312 46648 : test();
313 46648 : firstnzcr = 1;
314 46648 : move16();
315 46648 : IF( ( LT_16( j, NUMSF_M1 ) ) && ( L_mult0( *fxptr2, *( fxptr2 - 1 ) ) <= 0 ) ) /* zcr between 2 subframes */
316 : {
317 6797 : sptr1_loc = add( sptr1_loc, 1 ); /* counts for the nexte subframe */
318 6797 : cntnzcr = -1;
319 6797 : move16();
320 6797 : firstnzcr = 0;
321 6797 : move16();
322 : }
323 :
324 46648 : *fx32ptr1 = tmp_fxL1; /*2*(Q-1)*/
325 46648 : move32();
326 46648 : if ( LT_32( *fx32ptr5, L_shr( *fx32ptr1, 1 ) ) )
327 : {
328 23196 : tmp_fxL1 = L_shl_sat( L_sub_sat( *fx32ptr1, *fx32ptr5 ), 1 ); /*2*(Q-1)*/
329 : }
330 46648 : *fx32ptr5 = tmp_fxL1; /*2*(Q-1)*/
331 46648 : move32();
332 :
333 46648 : fx32ptr1++;
334 46648 : fx32ptr5++;
335 46648 : fx32ptr6++;
336 : }
337 :
338 5831 : fxptr2 = imdct_mem_fx; /* q_sig16 or q-1*/
339 5831 : j = NUMSF;
340 5831 : move16(); /* one future subframe but 96 samples (not 80) (enough with ALDO window) */
341 5831 : tmp_fx1 = shr( *fxptr2, qmemp1 ); /* q-1 shr to avoid overflow in es_mdct_fx*/
342 5831 : tmp_fxL1 = L_mac0( 25, tmp_fx1, tmp_fx1 ); /*2*(Q-1)*/
343 :
344 5831 : sptr1_loc = 0;
345 5831 : move16();
346 5831 : fxptr2++;
347 5831 : tmp_fx3 = sub( len3xLp20, 1 );
348 1097110 : FOR( i = 1; i < len3xLp20; i++ )
349 : {
350 1091279 : tmp_fx1 = shr( *fxptr2, qmemp1 ); /*q-1 to avoisd saturation in energy*/
351 1091279 : tmp_fxL1 = L_mac0_sat( tmp_fxL1, tmp_fx1, tmp_fx1 ); /*2*(Q-1)*/
352 1091279 : if ( *fxptr2 * *( fxptr2 - 1 ) <= 0 )
353 : {
354 180451 : sptr1_loc = add( sptr1_loc, 1 );
355 : }
356 :
357 1091279 : fxptr2++;
358 : }
359 5831 : *fx32ptr1 = tmp_fxL1; /*2*(Q-1)*/
360 5831 : move32();
361 5831 : *sptr1 = sptr1_loc; /*Q0*/
362 5831 : fxptr2 = imdct_mem_fx; /*q_sig16*/
363 5831 : fxptr3 = imdct_mem_fx + 1; /*q_sig16*/
364 5831 : fxptr4 = imdct_mem_fx + 2; /*q_sig16*/
365 5831 : tmp_fxL1 = L_mult( rec_sig_fx[framelength_m1], -8192 /*Q15*/ ); /*q_sig16+Q16*/
366 5831 : tmp_fxL1 = L_mac( tmp_fxL1, *fxptr3, -8192 ); /*q_sig16+Q16*/
367 5831 : tmp_fx1 = mac_r( tmp_fxL1, *fxptr2, 16384 /*Q15*/ ); /*q_sig16*/
368 :
369 5831 : tmp_fxL2 = L_deposit_l( 100 );
370 5831 : tmp_fxL2 = L_mac0( tmp_fxL2, tmp_fx1, tmp_fx1 ); /*2*(q_sig16)*/
371 :
372 1091279 : FOR( j = 1; j < tmp_fx3; j++ ) /* tmp_fx3 still contains subframelength*1.2-1 */
373 : {
374 1085448 : tmp_fxL1 = L_mult( *fxptr2, -8192 /*Q15*/ ); /*q_sig16+Q16*/
375 1085448 : tmp_fxL1 = L_mac_sat( tmp_fxL1, *fxptr4, -8192 ); /*q_sig16+Q16*/
376 1085448 : tmp_fx1 = mac_r_sat( tmp_fxL1, *fxptr3, 16384 /*Q15*/ ); /*q_sig16*/
377 :
378 1085448 : tmp_fxL2 = L_mac0_sat( tmp_fxL2, tmp_fx1, tmp_fx1 ); /*2*(q_sig16)*/
379 1085448 : fxptr2++;
380 1085448 : fxptr3++;
381 1085448 : fxptr4++;
382 : }
383 :
384 5831 : tmp_fxL1 = L_mult( *fxptr2, -8192 /*Q15*/ ); /*q_sig16+Q16*/
385 5831 : tmp_fx1 = mac_r_sat( tmp_fxL1, *fxptr3, 16384 /*Q15*/ ); /*q_sig16*/
386 5831 : es_mdct_hb_fx[NUMSF] = L_mac0_sat( tmp_fxL2, tmp_fx1, tmp_fx1 ); /*2*(q_sig16)*/
387 5831 : move32();
388 :
389 5831 : max_es_hb_fx = L_add( es_mdct_hb_fx[0], 0 ); /* for memorising the max energy */
390 5831 : max_es_fx = L_add( es_mdct_fx[0], 0 ); /* for memorising the max energy */
391 5831 : maxind = 0;
392 5831 : move16();
393 52479 : FOR( i = 1; i <= NUMSF; i++ )
394 : {
395 46648 : max_es_hb_fx = L_max( max_es_hb_fx, es_mdct_hb_fx[i] ); /* max energy low band, 8 present and 1 future subframes */
396 :
397 46648 : max_es_fx = L_max( max_es_fx, es_mdct_fx[i] ); /* max energy low band, 8 present and 1 future subframes */
398 :
399 46648 : if ( GE_32( es_mdct_fx[i], max_es_fx ) ) /* '=' to handle the first window*/
400 : {
401 11030 : maxind = i;
402 11030 : move16();
403 : }
404 : }
405 :
406 5831 : cnt2 = cnt5 = 0;
407 5831 : move16();
408 5831 : move16();
409 5831 : test();
410 5831 : if ( *prevflag != 0 || LT_32( max_es_fx, L_mult0( subframelength, 2500 ) ) )
411 : {
412 486 : maxind = 0;
413 486 : move16();
414 : }
415 :
416 5831 : if ( LT_32( max_es_fx, L_shl_sat( mean_prev_fx_loc, 2 ) ) ) /*OK if saturated*/
417 : {
418 4634 : maxind = 0;
419 4634 : move16();
420 : }
421 5831 : *prevflag = 0;
422 5831 : move16();
423 :
424 7187 : FOR( i = 0; i < maxind; i++ ) /* only subbands before max energy subband are handled */
425 : {
426 1356 : g_fx = 32767; /*Q15*/
427 1356 : move16(); /* default gain */
428 1356 : min_g_fx[i] = 32767; /*Q15*/
429 1356 : move16();
430 1356 : min_g_hb_fx[i] = 32767; /*Q15*/
431 1356 : move16();
432 :
433 1356 : Mpy_32_16_ss( es_mdct_half_fx[i], 328, &tmp_fxL1, &tmp_u16 ); /* 328 for 1/100*/
434 1356 : Mpy_32_16_ss( es_mdct_half_fx[i], 3277, &tmp_fxL2, &tmp_u16 ); /* 3277 for 1/10*/
435 1356 : Mpy_32_16_ss( es_mdct_fx[i], 5461, &tmp_fxL3, &tmp_u16 ); /* 5461 for 1/6*/
436 1356 : test();
437 1356 : test();
438 1356 : test();
439 1356 : IF( ( GT_32( tmp_fxL1, L_add( mean_prev_nc_fx_loc, 125000 ) ) ) || /* less then 20% energy in 3/4 of the subframe -> starting onset in the last quarter */
440 : ( ( GT_32( tmp_fxL2, L_add( mean_prev_nc_fx_loc, 125000 ) ) ) &&
441 : ( ( LT_16( zcr[i], limzcr ) ) || ( LT_32( es_mdct_quart_fx[i], tmp_fxL3 ) ) ) ) ) /* already an offset, plosif, do not touch */
442 : {
443 301 : maxind = i;
444 301 : move16(); /* no preecho reduction after the first subframe with gain 1 */
445 301 : *prevflag = 1;
446 301 : move16();
447 350 : FOR( j = sub( i, 1 ); j >= 0; j-- )
448 : {
449 49 : if ( GT_32( es_mdct_fx[j], L_shr( es_mdct_fx[i], 1 ) ) )
450 : {
451 8 : maxind = j;
452 8 : move16();
453 : }
454 : }
455 : }
456 : ELSE
457 : {
458 1055 : IF( LT_32( es_mdct_fx[i], L_shr( max_es_fx, 4 ) ) )
459 : {
460 362 : g_fx = lim16_fx; /*Q15*/
461 362 : move16();
462 362 : cnt5 = add( cnt5, 1 );
463 :
464 362 : IF( LT_32( es_mdct_fx[i], L_shr( max_es_fx, 5 ) ) )
465 : {
466 142 : g_fx = lim32_fx; /*Q15*/
467 142 : move16();
468 142 : cnt2 = add( cnt2, 1 );
469 : }
470 :
471 362 : IF( LT_32( mean_prev_fx_loc, es_mdct_fx[i] ) )
472 : {
473 189 : tmp_fx1 = norm_l( es_mdct_fx[i] );
474 189 : tmp_fxL1 = L_shl( es_mdct_fx[i], tmp_fx1 );
475 189 : tmp_fxL2 = L_shl( mean_prev_fx_loc, tmp_fx1 );
476 189 : tmp_fx1 = round_fx_sat( tmp_fxL1 );
477 189 : tmp_fx2 = round_fx( tmp_fxL2 );
478 189 : tmp_fx3 = div_s( tmp_fx2, tmp_fx1 );
479 189 : min_g_fx[i] = Frac_sqrt( tmp_fx3 );
480 189 : move16();
481 : }
482 :
483 362 : IF( LT_32( mean_prev_hb_fx_loc, es_mdct_hb_fx[i] ) )
484 : {
485 237 : tmp_fx1 = norm_l( es_mdct_hb_fx[i] );
486 237 : tmp_fxL1 = L_shl( es_mdct_hb_fx[i], tmp_fx1 );
487 237 : tmp_fxL2 = L_shl( mean_prev_hb_fx_loc, tmp_fx1 );
488 237 : tmp_fx1 = round_fx_sat( tmp_fxL1 );
489 237 : tmp_fx2 = round_fx( tmp_fxL2 );
490 237 : tmp_fx3 = div_s( tmp_fx2, tmp_fx1 );
491 237 : min_g_hb_fx[i] = Frac_sqrt( tmp_fx3 );
492 237 : move16();
493 : }
494 362 : test();
495 362 : IF( ( LT_16( zcr[i], shr( limzcr, 1 ) ) ) || ( GT_16( maxnzcr[i], limmaxnzcr ) ) )
496 : {
497 76 : if ( LT_16( min_g_fx[i], 32767 ) ) /* *mean_prev < es_mdct[i]) */
498 : {
499 31 : mean_prev_fx_loc = L_add( es_mdct_fx[i], 0 );
500 : }
501 76 : min_g_fx[i] = 32767; /*Q15*/
502 76 : move16(); /* not noise-like, do not touch the amplitude, but may do in HB*/
503 : }
504 : }
505 : ELSE
506 : {
507 693 : test();
508 693 : if ( i > 0 && LT_16( maxind, NUMSF ) )
509 : {
510 80 : *prevflag = 1;
511 80 : move16();
512 : }
513 693 : maxind = i;
514 693 : move16(); /* no preecho reduction after the first subframe with gain 1*/
515 : }
516 : }
517 1356 : gt_fx[i] = g_fx; /*Q15*/
518 1356 : move16();
519 1356 : gt_hb_fx[i] = g_fx; /*Q15*/
520 1356 : move16();
521 : }
522 :
523 57956 : FOR( i = maxind; i <= NUMSF; i++ ) /* also for the first memory subframe */
524 : {
525 52125 : gt_fx[i] = 32767; /*Q15*/
526 52125 : move16();
527 52125 : min_g_fx[i] = 32767; /*Q15*/
528 52125 : move16();
529 52125 : gt_hb_fx[i] = 32767; /*Q15*/
530 52125 : move16();
531 52125 : min_g_hb_fx[i] = 32767; /*Q15*/
532 52125 : move16();
533 : }
534 :
535 5831 : ind2 = 0;
536 5831 : move16();
537 52479 : FOR( i = 0; i < NUMSF; i++ )
538 : {
539 46648 : if ( LT_16( gt_fx[i], 32767 ) ) /*gt not yet limited by min_g*/
540 : {
541 246 : ind2 = add( i, 1 ); /* first subframe with gain = 1 after last gain < 1 --> frame with the attack*/
542 : }
543 : }
544 :
545 5831 : test();
546 5831 : if ( ( GT_16( wmold_fx, 16384 ) ) && ( LT_16( add( cnt2, cnt5 ), 2 ) ) ) /* mini either 1 cnt2 (and so also cnt5) or 2 cnt5 */
547 : {
548 : /* maxind = 0; false alarm, no echo reduction */
549 5708 : ind2 = 0;
550 5708 : move16();
551 : }
552 5831 : ind2_m1 = sub( ind2, 1 );
553 5831 : ind2_sfl = i_mult( subframelength, ind2 );
554 5831 : numsf_ind2 = sub( NUMSF, ind2 );
555 5831 : fxptr3 = gt_fx; /*Q15*/
556 5831 : fxptr4 = gt_hb_fx; /*Q15*/
557 5831 : fxptr5 = min_g_fx; /*Q15*/
558 5831 : fxptr6 = min_g_hb_fx; /*Q15*/
559 :
560 5831 : fxptr1 = preechogain_fx + smooth_len;
561 5831 : pre_g_ch_tab[0] = smooth_len;
562 5831 : move16(); /*1st after smoothmem*/
563 5831 : fxptr2 = preechogain_hb_fx;
564 6043 : FOR( i = 0; i < ind2; i++ ) /* only subbands before max energy subband are handled*/
565 : {
566 212 : *fxptr3 = s_max( *fxptr3, *fxptr5 );
567 212 : move16();
568 :
569 212 : *fxptr4 = s_max( *fxptr4, *fxptr6 );
570 212 : move16();
571 :
572 24172 : FOR( j = 0; j < subframelength; j++ )
573 : {
574 23960 : *fxptr1 = *fxptr3;
575 23960 : move16();
576 23960 : *fxptr2 = *fxptr4;
577 23960 : move16();
578 23960 : fxptr1++;
579 23960 : fxptr2++;
580 : }
581 212 : pre_g_ch_tab[( i + 1 )] = add( pre_g_ch_tab[i], subframelength );
582 212 : fxptr3++;
583 212 : fxptr4++;
584 212 : fxptr5++;
585 212 : fxptr6++;
586 : }
587 :
588 5831 : max_plus_es_mdct_fx = L_deposit_l( 0 );
589 5831 : adv = smooth_len;
590 5831 : move16(); /* samples needed to have near 1 gain after smoothing at the beggining of the attack subframe*/
591 5831 : advmem = adv; /*Q0*/
592 5831 : move16();
593 :
594 5831 : test();
595 5831 : test();
596 5831 : IF( ind2 > 0 || LT_16( wmold_fx, 32767 ) || LT_16( *wmold_hb_fx, 32767 ) )
597 : {
598 72 : ptr_fx = imdct_mem_fx; /*q_sig16*/
599 72 : qtmp = qmemp1;
600 72 : pluslim = num_subsubframes;
601 72 : move16(); /* if ind2 == NUMSF */
602 72 : IF( numsf_ind2 > 0 )
603 : {
604 70 : ptr_fx = rec_sig_fx + ind2_sfl; /*q_sig16*/
605 70 : qtmp = q16p1;
606 70 : move16();
607 70 : pluslim = i_mult( numsf_ind2, num_subsubframes );
608 : }
609 :
610 72 : maxcrit_fx = L_add( mean_prev_nc_fx_loc, 0 );
611 72 : IF( ind2 == 0 )
612 : {
613 0 : sum_plus_es_fx = L_add( mean_prev_nc_fx_loc, 0 ); /* 8 times mean sususb enenrgy (=maxcrit)*/
614 0 : pluslim = num_subsubframes;
615 0 : move16();
616 0 : oldgain_fx = wmold_fx; /*Q15*/
617 0 : move16();
618 0 : oldgain_hb_fx = *wmold_hb_fx; /*Q15*/
619 0 : move16();
620 : }
621 : ELSE /* ind2 > 0*/
622 : {
623 72 : sum_plus_es_fx = es_mdct_fx[ind2_m1];
624 72 : move32(); /* 8 times mean sususb enenrgy (=maxcrit)*/
625 72 : oldgain_fx = gt_fx[ind2_m1]; /*Q15*/
626 72 : move16();
627 72 : oldgain_hb_fx = gt_hb_fx[ind2_m1]; /*Q15*/
628 72 : move16();
629 :
630 72 : tmp_fx1 = mult_r( gt_fx[ind2_m1], gt_fx[ind2_m1] ); /*Q15*/
631 72 : Mpy_32_16_ss( es_mdct_fx[ind2_m1], tmp_fx1, &maxcrit_fx, &tmp_u16 );
632 72 : Mpy_32_16_ss( max_es_fx, 410, &tmp_fxL1, &tmp_u16 ); /* 410 for 1/80*/
633 :
634 72 : test();
635 72 : if ( ( GT_32( tmp_fxL1, maxcrit_fx ) ) && ( GT_16( zcr[ind2], limzcr ) ) )
636 : {
637 15 : maxcrit_fx = L_add( tmp_fxL1, 0 ); /* still 10 times smaller then mean max_es*/
638 : }
639 : }
640 72 : fx32ptr1 = plus_es_mdct_fx;
641 72 : fx32ptr4 = mean_plus_es_fx + 1;
642 3000 : FOR( j = 0; j < pluslim; j++ ) /* 8 sub-subframes */
643 : {
644 2928 : tmp_fxL1 = 100;
645 2928 : move16();
646 44488 : FOR( i = 0; i < subsubframelength; i++ )
647 : {
648 :
649 41560 : tmp_fx1 = shr( *ptr_fx, qtmp ); /* q-1, to have same shift as es_mdct_.. */
650 41560 : tmp_fxL1 = L_mac0_sat( tmp_fxL1, tmp_fx1, tmp_fx1 ); /*2*(Q-1)*/
651 41560 : ptr_fx++;
652 : }
653 2928 : if ( GT_32( tmp_fxL1, max_plus_es_mdct_fx ) )
654 : {
655 487 : max_plus_es_mdct_fx = L_add( tmp_fxL1, 0 );
656 : }
657 :
658 2928 : sum_plus_es_fx = L_add_sat( sum_plus_es_fx, L_shl_sat( tmp_fxL1, 2 ) ); /*2*(Q-1)*/
659 2928 : *fx32ptr1 = tmp_fxL1; /*2*(Q-1)*/
660 2928 : fx32ptr1++;
661 2928 : Mpy_32_16_ss( sum_plus_es_fx, inv_jp2[j], fx32ptr4, &tmp_u16 ); /* 410 for 1/80*/
662 2928 : if ( LT_32( *fx32ptr4, maxcrit_fx ) )
663 : {
664 305 : *fx32ptr4 = maxcrit_fx;
665 305 : move32();
666 : }
667 2928 : fx32ptr4++;
668 : }
669 72 : *fx32ptr4 = -1;
670 72 : move32(); /*mean_plus_es_fx[pluslim] = -1; */
671 72 : *mean_plus_es_fx = *plus_es_mdct_fx; /*2*(Q-1)*/
672 72 : move32(); /* index [0] */
673 72 : if ( LT_32( *mean_plus_es_fx, maxcrit_fx ) )
674 : {
675 55 : *mean_plus_es_fx = maxcrit_fx; /*2*(Q-1)*/
676 55 : move32();
677 : }
678 :
679 72 : j = 0;
680 72 : move16();
681 316 : WHILE( ( LT_32( plus_es_mdct_fx[j], mean_plus_es_fx[j] ) ) && ( LT_32( plus_es_mdct_fx[j], L_shr( max_plus_es_mdct_fx, 3 ) ) ) )
682 : {
683 244 : test();
684 244 : j = add( j, 1 );
685 : }
686 72 : tmp_fx3 = i_mult( j, subsubframelength );
687 72 : adv = sub( adv, tmp_fx3 );
688 72 : IF( numsf_ind2 > 0 ) /* onset not in future frame */
689 : {
690 70 : fxptr1 = preechogain_fx + ind2_sfl + smooth_len;
691 70 : fxptr2 = preechogain_hb_fx + ind2_sfl;
692 :
693 3350 : FOR( i = 0; i < tmp_fx3; i++ )
694 : {
695 3280 : *fxptr1 = oldgain_fx; /*Q15*/
696 3280 : move16(); /*keep the gain of the previous subframe*/
697 3280 : *fxptr2 = oldgain_hb_fx; /*Q15*/
698 3280 : move16(); /*keep the gain of the previous subframe*/
699 3280 : fxptr1++;
700 3280 : fxptr2++;
701 : }
702 : }
703 : }
704 :
705 5831 : IF( ind2 > 0 )
706 : {
707 : /* check increasing energy of preecho by regression last 3 subframes (if possible) */
708 72 : ind3 = add( ind2, shr( j, log2_num_subsubframes ) ); /* return (with rounding) to subframe basis */
709 72 : ind4 = sub( ind3, 1 );
710 72 : ind5 = sub( ind3, 2 );
711 72 : ind6 = sub( ind3, 3 );
712 72 : IF( ind4 > 0 )
713 : {
714 : /* case of 3 points is simply */
715 64 : eshbmean2_fx = L_add( es_mdct_hb_fx[ind4], es_mdct_hb_fx[ind5] ); /*2*(q_sig16)*/
716 :
717 64 : sxyhb2_fx = L_sub( es_mdct_hb_fx[ind4], es_mdct_hb_fx[ind5] ); /* / eshbmean2 * 2; 04042013: division not needed, only sign of sxyhb2 is used*/
718 :
719 64 : IF( GT_16( ind3, 2 ) )
720 : {
721 36 : tmp_fxL1 = L_add( eshbmean2_fx, es_mdct_hb_fx[ind6] ); /*2*(q_sig16)*/
722 36 : Mpy_32_16_ss( tmp_fxL1, 4369, &eshbmean3_fx, &tmp_u16 ); /*10922 : 1/3*/
723 36 : sxylb3_fx = L_sub( es_mdct_fx[ind4], es_mdct_fx[ind6] ); /* /eslbmean3 / 2; /2 for 3 points regression calc; 04042013: division not needed, only sign of sxylb3 is used*/
724 36 : tmp_fxL1 = L_sub( es_mdct_hb_fx[ind4], es_mdct_hb_fx[ind6] ); /*2*(q_sig16)*/
725 36 : test();
726 36 : IF( ( LT_32( tmp_fxL1, eshbmean3_fx ) ) || ( sxylb3_fx < 0 ) )
727 : {
728 17 : ind2 = 0;
729 17 : move16();
730 17 : ind2_sfl = 0;
731 17 : move16();
732 17 : adv = advmem;
733 17 : move16();
734 : }
735 : }
736 : ELSE
737 : {
738 28 : IF( sxyhb2_fx < 0 )
739 : {
740 2 : ind2 = 0;
741 2 : move16();
742 2 : ind2_sfl = 0;
743 2 : move16();
744 2 : adv = advmem;
745 2 : move16(); /* 04042013: small bug corection*/
746 : }
747 : }
748 :
749 64 : tmp_fxL1 = L_add( eshbmean2_fx, es_mdct_hb_fx[ind3] ); /*2*(q_sig16)*/
750 64 : Mpy_32_16_ss( tmp_fxL1, 4369, &eshbmean3_fx, &tmp_u16 ); /*10922 : 1/3*/
751 :
752 64 : tmp_fxL1 = L_sub( es_mdct_hb_fx[ind3], es_mdct_hb_fx[ind5] ); /*2*(q_sig16)*/
753 64 : IF( LT_32( tmp_fxL1, eshbmean3_fx ) )
754 : {
755 6 : ind2 = 0;
756 6 : move16();
757 6 : ind2_sfl = 0;
758 6 : move16();
759 6 : adv = advmem;
760 6 : move16();
761 : }
762 : }
763 : }
764 :
765 5831 : ind2_m1 = sub( ind2, 1 ); /*ind2_m1 needs to be recomputed as ind2 could have changed since*/
766 :
767 5831 : stind = sub( ind2_sfl, adv );
768 5831 : stind_hb = add( stind, advmem );
769 5831 : if ( stind < 0 )
770 : {
771 5778 : stind = 0;
772 5778 : move16();
773 : }
774 :
775 5831 : if ( stind_hb < 0 )
776 : {
777 0 : stind_hb = 0;
778 0 : move16();
779 : }
780 :
781 5831 : tmp_fx1 = add( stind, smooth_len );
782 5831 : fxptr1 = preechogain_fx + tmp_fx1; /*Q15*/
783 5831 : fxptr2 = preechogain_hb_fx + stind_hb; /*Q15*/
784 :
785 4981264 : FOR( i = tmp_fx1; i < framelength; i++ ) /* rest of the gains, without 4 (PREECHO_SMOOTH_LEN) 1 for fadeout */
786 : {
787 4975433 : *( fxptr1++ ) = 32767; /*Q15*/
788 4975433 : move16();
789 : }
790 5831 : pre_g_ch_tab[ind2] = s_min( tmp_fx1, framelength ); /*Q0*/
791 5831 : move16();
792 :
793 5004376 : FOR( i = stind_hb; i < framelength; i++ ) /* rest of the gains*/
794 : {
795 4998545 : *( fxptr2++ ) = 32767; /*Q15*/
796 4998545 : move16();
797 : }
798 :
799 5831 : fxptr1 = preechogain_fx; /*Q15*/
800 29155 : FOR( i = 0; i < smooth_len; i++ )
801 : {
802 23324 : *( fxptr1++ ) = *smoothmem_fx; /*Q15*/
803 23324 : move16();
804 : }
805 :
806 5831 : fattnext_fx = 32767; /*Q15*/
807 5831 : move16();
808 5831 : if ( GT_16( stind, framelength ) )
809 : {
810 0 : fattnext_fx = gt_fx[ind2_m1]; /*Q15*/
811 0 : move16();
812 : }
813 :
814 5831 : fxptr1 = preechogain_fx + framelength; /*Q15*/
815 29155 : FOR( i = 0; i < smooth_len; i++ )
816 : {
817 23324 : *( fxptr1++ ) = fattnext_fx; /*Q15*/
818 23324 : move16();
819 : }
820 :
821 11792 : FOR( i = 0; i <= ind2; i++ )
822 : {
823 5961 : tmp_fx1 = pre_g_ch_tab[i]; /*Q0*/
824 5961 : move16();
825 5961 : tmp_fx2 = sub( tmp_fx1, smooth_len ); /* any index in the previous subframe*/
826 5961 : tmp_fx3 = mult_r( sub( preechogain_fx[tmp_fx1], preechogain_fx[tmp_fx2] ), invsmoothlenp1_fx ); /*step Q15*/
827 5961 : tmp_fx1 = tmp_fx3; /*Q15*/
828 5961 : move16(); /*cumulated step*/
829 5961 : fxptr1 = preechogain_fx + tmp_fx2; /*Q15*/
830 29805 : FOR( j = 0; j < smooth_len; j++ )
831 : {
832 23844 : *fxptr1 = add_sat( *fxptr1, tmp_fx1 ); /*Q15*/
833 23844 : move16();
834 23844 : tmp_fx1 = add( tmp_fx1, tmp_fx3 ); /*Q15*/
835 23844 : fxptr1++;
836 : }
837 : }
838 :
839 5831 : *smoothmem_fx = fattnext_fx; /*Q15*/
840 5831 : move16();
841 5831 : *wmold_hb_fx = preechogain_hb_fx[framelength_m1]; /*Q15*/
842 5831 : move16();
843 :
844 : /* apply gain */
845 5831 : fxptr1 = preechogain_fx; /*Q15*/
846 5831 : fxptr2 = preechogain_hb_fx; /*Q15*/
847 5831 : fxptr3 = rec_sig_fx; /*q_sig16*/
848 5831 : fxptr4 = rec_sig_lb_fx; /*q_sig16*/
849 5831 : fxptr5 = rec_sig_hb_fx; /*q_sig16*/
850 5021191 : FOR( i = 0; i < framelength; i++ )
851 : {
852 5015360 : tmp_fxL1 = L_mult( *fxptr4, *fxptr1 ); /*q_sig16 + Q16*/
853 5015360 : *fxptr3 = mac_r( tmp_fxL1, *fxptr5, *fxptr2 ); /*q_sig16*/
854 5015360 : move16();
855 5015360 : fxptr1++;
856 5015360 : fxptr2++;
857 5015360 : fxptr3++;
858 5015360 : fxptr4++;
859 5015360 : fxptr5++;
860 : }
861 :
862 5831 : mean_prev_nc_fx_loc = L_add( es_mdct_fx[0], 0 ); /* compute mean not corrected by the actual gains 2*(Q-1)*/
863 :
864 46648 : FOR( i = 1; i < NUMSF; i++ ) /* all present subbands */
865 : {
866 40817 : if ( EQ_16( i, NUMSF_S2 ) )
867 : {
868 5831 : savehalfe_fx = L_add( mean_prev_nc_fx_loc, 0 ); /*2*(Q-1)*/
869 : }
870 40817 : mean_prev_nc_fx_loc = L_add_sat( mean_prev_nc_fx_loc, es_mdct_fx[i] ); /*2*(Q-1)*/
871 : }
872 :
873 5831 : if ( LT_32( savehalfe_fx, L_shr( mean_prev_nc_fx_loc, 1 ) ) )
874 : {
875 2380 : mean_prev_nc_fx_loc = L_shl_sat( L_sub_sat( mean_prev_nc_fx_loc, savehalfe_fx ), 1 ); /*2*(Q-1)*/
876 : }
877 5831 : mean_prev_nc_fx_loc = L_shr( mean_prev_nc_fx_loc, 3 ); /* >> LOG2_NUMSF in fixpoint 2*(Q-1)*/
878 :
879 5961 : FOR( i = 0; i < ind2; i++ ) /* only subbands before max energy subband are handled*/
880 : {
881 130 : tmp_fx1 = mult_r( gt_fx[i], gt_fx[i] ); /*Q15*/
882 130 : Mpy_32_16_ss( es_mdct_fx[i], tmp_fx1, &es_mdct_fx[i], &tmp_u16 );
883 :
884 130 : tmp_fx1 = mult_r( gt_hb_fx[i], gt_hb_fx[i] ); /*Q15*/
885 130 : Mpy_32_16_ss( es_mdct_hb_fx[i], tmp_fx1, &es_mdct_hb_fx[i], &tmp_u16 );
886 : }
887 :
888 5831 : mean_prev_fx_loc = L_shr( es_mdct_fx[0], 3 ); /* compute mean used in next frame to limit gain 2*(Q-1)*/
889 5831 : mean_prev_hb_fx_loc = L_shr( es_mdct_hb_fx[0], 3 ); /* compute mean used in next frame to limit gain 2*(q_sig16)*/
890 :
891 46648 : FOR( i = 1; i < NUMSF; i++ ) /* all present subbands */
892 : {
893 40817 : IF( EQ_16( i, NUMSF_S2 ) )
894 : {
895 5831 : savehalfe_fx = L_add( mean_prev_fx_loc, 0 ); /*2*(Q-1)*/
896 5831 : savehalfe_hb_fx = L_add( mean_prev_hb_fx_loc, 0 ); /*2*(q_sig16)*/
897 : }
898 :
899 40817 : mean_prev_fx_loc = L_add( mean_prev_fx_loc, L_shr( es_mdct_fx[i], 3 ) ); /*2*(Q-1)*/
900 40817 : mean_prev_hb_fx_loc = L_add( mean_prev_hb_fx_loc, L_shr( es_mdct_hb_fx[i], 3 ) ); /*2*(q_sig16)*/
901 : }
902 :
903 5831 : tmp_fxL1 = L_sub( mean_prev_fx_loc, savehalfe_fx ); /*2*(Q-1)*/
904 5831 : if ( LT_32( savehalfe_fx, L_shr( mean_prev_fx_loc, 1 ) ) )
905 : {
906 2586 : mean_prev_fx_loc = L_shl( tmp_fxL1, 1 ); /*2*(Q-1)*/
907 : }
908 :
909 5831 : tmp_fxL1 = L_sub( mean_prev_hb_fx_loc, savehalfe_hb_fx ); /*2*(q_sig16)*/
910 5831 : if ( LT_32( savehalfe_hb_fx, L_shr( mean_prev_hb_fx_loc, 1 ) ) )
911 : {
912 3121 : mean_prev_hb_fx_loc = L_shl( tmp_fxL1, 1 ); /*2*(q_sig16)*/
913 : }
914 :
915 5831 : last2_fx = L_shr( L_add_sat( es_mdct_fx[NUMSF_M1], es_mdct_fx[NUMSF_M2] ), 1 ); /*q_sig16*/
916 5831 : last2_hb_fx = L_shr( L_add_sat( es_mdct_hb_fx[NUMSF_M1], es_mdct_hb_fx[NUMSF_M2] ), 1 ); /*q_sig16*/
917 5831 : if ( GT_32( last2_fx, mean_prev_fx_loc ) )
918 : {
919 2072 : mean_prev_fx_loc = L_add( last2_fx, 0 );
920 : }
921 :
922 5831 : if ( GT_32( last2_hb_fx, mean_prev_hb_fx_loc ) )
923 : {
924 2846 : mean_prev_hb_fx_loc = L_add( last2_hb_fx, 0 ); /*2*(q_sig16)*/
925 : }
926 5831 : *mean_prev_fx = mean_prev_fx_loc; /*2*(Q-1)*/
927 5831 : move32();
928 5831 : *mean_prev_hb_fx = L_shr_sat( mean_prev_hb_fx_loc, shl_sat( q_sig16, 1 ) ); /*Q0*/
929 5831 : move32(); /*save in Q0*/
930 5831 : *mean_prev_nc_fx = mean_prev_nc_fx_loc; /*2*(Q-1)*/
931 5831 : move32();
932 : }
933 :
934 9020 : return;
935 : }
936 :
937 : /*--------------------------------------------------------------------------*
938 : * Inverse_Transform()
939 : *
940 : * Inverse transform from the DCT domain to time domain
941 : *--------------------------------------------------------------------------*/
942 :
943 55005 : void Inverse_Transform(
944 : const Word32 *in_mdct, /* i : input MDCT vector Q */
945 : Word16 *Q, /* i/o: Q value of input */
946 : Word32 *out, /* o : output vector Q */
947 : const Word16 is_transient, /* i : transient flag Q0 */
948 : const Word16 L, /* i : output frame length Q0 */
949 : const Word16 L_inner, /* i : length of the transform Q0 */
950 : const Word16 element_mode /* i : IVAS element mode Q0 */
951 : )
952 : {
953 : Word16 ta, seg, tmp16;
954 : Word16 segment_length;
955 : const Word16 *win, *win2;
956 : Word32 out_alias[L_FRAME48k];
957 : Word32 alias[MAX_SEGMENT_LENGTH];
958 : Word32 in_mdct_modif[L_FRAME48k];
959 : Word32 *in_segment_modif;
960 : const Word32 *in_segment;
961 : Word32 *out_segment;
962 : Word16 segment_length_div2, segment_length_div4;
963 : Word16 tmp, q_out;
964 : Word32 L_temp;
965 : (void) ( element_mode );
966 : /* This value is used to right shift all vectors returned by 'iedct_short_fx()' */
967 : /* to bring them to a scaling that is equal to the 1st 'Q' returned by the 1st */
968 : /* call to 'iedct_short_fx()' minus these guard bits. */
969 : #define N_GUARD_BITS ( 9 + 1 ) /* 9 is enough but we put one extra bit */
970 :
971 55005 : IF( is_transient )
972 : {
973 1621 : segment_length = shr( L, 1 );
974 1621 : segment_length_div2 = shr( L, 2 );
975 1621 : segment_length_div4 = shr( L, 3 );
976 :
977 1621 : IF( EQ_16( L, L_FRAME48k ) )
978 : {
979 476 : win = short_window_48kHz_fx; /*Q15*/
980 : }
981 1145 : ELSE IF( EQ_16( L, L_FRAME32k ) )
982 : {
983 130 : win = short_window_32kHz_fx; /*Q15*/
984 : }
985 1015 : ELSE IF( EQ_16( L, L_FRAME16k ) )
986 : {
987 1015 : win = short_window_16kHz_fx; /*Q15*/
988 : }
989 : ELSE /* L == L_FRAME8k */
990 : {
991 0 : win = short_window_8kHz_fx; /*Q15*/
992 : }
993 :
994 1621 : set32_fx( out_alias, 0, L );
995 :
996 1621 : in_segment = in_mdct; /*Q*/
997 1621 : in_segment_modif = in_mdct_modif;
998 :
999 1621 : tmp16 = sub( L, L_inner );
1000 1621 : IF( tmp16 == 0 )
1001 : {
1002 420 : Copy32( in_mdct, in_mdct_modif, L ); /*Q*/
1003 : }
1004 1201 : ELSE IF( tmp16 > 0 )
1005 : {
1006 595 : FOR( seg = 0; seg < NUM_TIME_SWITCHING_BLOCKS; seg++ )
1007 : {
1008 71516 : FOR( ta = 0; ta < L_inner; ta += NUM_TIME_SWITCHING_BLOCKS )
1009 : {
1010 71040 : *in_segment_modif++ = *in_segment++; /*Q*/
1011 71040 : move32();
1012 : }
1013 :
1014 43676 : FOR( ta = 0; ta < tmp16; ta += NUM_TIME_SWITCHING_BLOCKS )
1015 : {
1016 43200 : *in_segment_modif++ = 0L;
1017 43200 : move32();
1018 : }
1019 : }
1020 : }
1021 : ELSE /* L < L_inner */
1022 : {
1023 5410 : FOR( seg = 0; seg < NUM_TIME_SWITCHING_BLOCKS; seg++ )
1024 : {
1025 382248 : FOR( ta = 0; ta < segment_length_div2; ta++ )
1026 : {
1027 377920 : *in_segment_modif++ = *in_segment++; /*Q*/
1028 377920 : move32();
1029 : }
1030 4328 : in_segment += shr( sub( L_inner, L ), 2 ); /*Q*/
1031 4328 : move32();
1032 : }
1033 : }
1034 :
1035 1621 : out_segment = out_alias - segment_length_div4;
1036 1621 : in_segment = in_mdct_modif; /*Q*/
1037 :
1038 1621 : tmp = *Q;
1039 : /* output of 'iedct_short_fx' has up to 'output frame length'/2 # of Elements */
1040 1621 : iedct_short_fx( in_segment, &tmp, alias, segment_length );
1041 1621 : IF( GT_16( tmp, N_GUARD_BITS ) )
1042 : {
1043 21 : q_out = sub( tmp, N_GUARD_BITS );
1044 21 : tmp = sub( tmp, q_out );
1045 : }
1046 : ELSE
1047 : {
1048 1600 : q_out = 0;
1049 1600 : move16();
1050 : }
1051 :
1052 109741 : FOR( ta = segment_length_div4; ta < segment_length_div2; ta++ )
1053 : {
1054 108120 : out_segment[ta] = L_shr( alias[ta], tmp ); /*q_out*/
1055 108120 : move32();
1056 : }
1057 : /* This previous loop fills the output buffer from [0..seg_len_div4-1] */
1058 :
1059 1621 : win2 = &win[segment_length_div2]; /*Q15*/
1060 217861 : FOR( ta = segment_length_div2; ta < segment_length; ta++ )
1061 : {
1062 216240 : out_segment[ta] = L_shr( Mult_32_16( alias[ta], *--win2 ), tmp ); /*q_out*/
1063 216240 : move32();
1064 : }
1065 : /* This previous loop fills the output buffer from [seg_len_div4..seg_len-seg_len_div4-1] */
1066 :
1067 1621 : out_segment += segment_length_div2; /*q_out*/
1068 1621 : in_segment += segment_length_div2; /*Q*/
1069 :
1070 4863 : FOR( seg = 1; seg < NUM_TIME_SWITCHING_BLOCKS - 1; seg++ )
1071 : {
1072 3242 : tmp = *Q;
1073 3242 : move16();
1074 : /* output of 'iedct_short_fx' has up to 'output frame length'/2 # of Elements */
1075 3242 : iedct_short_fx( in_segment, &tmp, alias, segment_length );
1076 3242 : tmp = sub( tmp, q_out );
1077 :
1078 435722 : FOR( ta = 0; ta < segment_length_div2; ta++ )
1079 : {
1080 432480 : out_segment[ta] = L_add( out_segment[ta], L_shr( Mult_32_16( alias[ta], *win2++ ), tmp ) ); /*q_out*/
1081 432480 : move32();
1082 : }
1083 435722 : FOR( ; ta < segment_length; ta++ )
1084 : {
1085 432480 : out_segment[ta] = L_add( out_segment[ta], L_shr( Mult_32_16( alias[ta], *--win2 ), tmp ) ); /*q_out*/
1086 432480 : move32();
1087 : }
1088 :
1089 3242 : in_segment += segment_length_div2; /*Q*/
1090 3242 : out_segment += segment_length_div2; /*q_out*/
1091 : }
1092 :
1093 1621 : tmp = *Q;
1094 1621 : move16();
1095 1621 : iedct_short_fx( in_segment, &tmp, alias, segment_length );
1096 1621 : tmp = sub( tmp, q_out );
1097 :
1098 217861 : FOR( ta = 0; ta < segment_length_div2; ta++ )
1099 : {
1100 216240 : out_segment[ta] = L_add( out_segment[ta], L_shr( Mult_32_16( alias[ta], *win2++ ), tmp ) ); /*q_out*/
1101 216240 : move32();
1102 : }
1103 :
1104 1621 : seg = add( segment_length_div2, shr( segment_length_div2, 1 ) ); /* seg = 3*segment_length/4 Q0*/
1105 109741 : FOR( ta = segment_length_div2; ta < seg; ta++ )
1106 : {
1107 108120 : out_segment[ta] = L_shr( alias[ta], tmp ); /*q_out*/
1108 108120 : move32();
1109 : }
1110 :
1111 434101 : FOR( ta = 0; ta < segment_length; ta++ )
1112 : {
1113 432480 : L_temp = L_add( out_alias[ta], 0 );
1114 432480 : out[ta] = out_alias[L - 1 - ta]; /*q_out*/
1115 432480 : move32();
1116 432480 : out[L - 1 - ta] = L_temp; /*q_out*/
1117 432480 : move32();
1118 : }
1119 :
1120 1621 : *Q = q_out;
1121 1621 : move16();
1122 : }
1123 : ELSE
1124 : {
1125 53384 : edct_fx( in_mdct, out, L, Q );
1126 : }
1127 55005 : }
|