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