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 "prot_fx.h" /* Function prototypes */
8 : #include "rom_com.h" /* Static table prototypes */
9 : #include "basop_util.h"
10 :
11 : /*---------------------------------------------------------------------*
12 : * Local constants
13 : *---------------------------------------------------------------------*/
14 : #define pitch_0_9 14746 /* 0.9 in Q14 */
15 : #define pitch_0_6 9830 /* 0.6 in Q14 */
16 : #define SIZE 64
17 : #define SIZE2 32
18 : #define NUM_STAGES 5
19 :
20 : /*---------------------------------------------------------------------*
21 : * Local functions
22 : *---------------------------------------------------------------------*/
23 : static void phase_dispersion_fx( Word32 gain_code, Word16 gain_pit, Word16 code[], Word16 mode, struct dispMem_fx *dm_fx );
24 : static void agc2_fx( const Word16 *sig_in, Word16 *sig_out, const Word16 l_trm );
25 :
26 : /*======================================================================================*/
27 : /* FUNCTION : enhancer_fx() */
28 : /*--------------------------------------------------------------------------------------*/
29 : /* PURPOSE : Enhancement of the excitation signal before synthesis */
30 : /*--------------------------------------------------------------------------------------*/
31 : /* INPUT ARGUMENTS : */
32 : /* _ (Word32) core_brate : decoder bitrate */
33 : /* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode */
34 : /* _ (Word16) coder_type : coder type */
35 : /* _ (Word16) i_subfr : subframe number */
36 : /* _ (Word16) voice_fac : subframe voicing estimation (Q15) */
37 : /* _ (Word16) stab_fac : LP filter stablility measure (Q15) */
38 : /* _ (Word32) norm_gain_code : normalised innovative cb. gain (Q16) */
39 : /* _ (Word16) gain_inov : gain of the unscaled innovation (Q12) */
40 : /* _ (Word16) gain_pit_fx : Pitch gain (Q14) */
41 : /* _ (Word16) Q_exc : Q of the excitation */
42 : /* _ (Word16) Enc : Encoder = 1; decoder = 0 */
43 : /*--------------------------------------------------------------------------------------*/
44 : /* OUTPUT ARGUMENTS : */
45 : /* _ (Word16*) voice_factors_fx : TBE voicing factor (Q15) */
46 : /*--------------------------------------------------------------------------------------*/
47 : /* INPUT/OUTPUT ARGUMENTS : */
48 : /* _ (Word32*) gc_threshold : gain code threshold (Q16) */
49 : /* _ (Word16*[]) code : innovation (Q12) */
50 : /* _ (Word16*[]) exc2 : adapt. excitation/total exc (Q0) */
51 : /* _ (struct dispMem_fx*) dm_fx : phase dispersion algorithm memory */
52 : /* (a[0]->Q0,a[1]->Q16,a[2-7]->Q14) */
53 : /*--------------------------------------------------------------------------------------*/
54 :
55 : /* _ None */
56 : /*--------------------------------------------------------------------------------------*/
57 : /* RETURN ARGUMENTS : */
58 : /* _ None */
59 : /*======================================================================================*/
60 55563 : void enhancer_fx(
61 : const Word32 core_brate, /* i : decoder bitrate */
62 : const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */
63 : const Word16 coder_type, /* i : coder type */
64 : const Word16 i_subfr, /* i : subframe number */
65 : const Word16 L_frame, /* i : frame size */
66 : const Word16 voice_fac, /* i : subframe voicing estimation Q15 */
67 : const Word16 stab_fac, /* i : LP filter stablility measure Q15 */
68 : Word32 norm_gain_code, /* i : normalised innovative cb. gain Q16 */
69 : const Word16 gain_inov, /* i : gain of the unscaled innovation Q12 */
70 : Word32 *gc_threshold, /* i/o: gain code threshold Q16 */
71 : Word16 *code, /* i/o: innovation Q12 */
72 : Word16 *exc2, /* i/o: adapt. excitation/total exc. Q_exc*/
73 : const Word16 gain_pit, /* i : quantized pitch gain Q14 */
74 : struct dispMem_fx *dm_fx, /* i/o: phase dispersion algorithm memory */
75 : const Word16 Q_exc /* i : Q of the excitation */
76 : )
77 : {
78 : Word16 tmp, fac, *pt_exc2;
79 : Word16 i;
80 : Word32 L_tmp;
81 : Word16 gain_code_hi;
82 : Word16 pit_sharp, tmp16;
83 : Word16 excp[L_SUBFR], sc;
84 :
85 :
86 55563 : pit_sharp = gain_pit;
87 55563 : move16(); /* to remove gcc warning */
88 55563 : pt_exc2 = exc2 + i_subfr;
89 :
90 : /*------------------------------------------------------------*
91 : * Phase dispersion to enhance noise at low bit rate
92 : *------------------------------------------------------------*/
93 :
94 55563 : i = 2;
95 55563 : move16(); /* no dispersion */
96 55563 : IF( Opt_AMR_WB )
97 : {
98 0 : IF( LE_32( core_brate, ACELP_6k60 ) )
99 : {
100 0 : i = 0;
101 0 : move16(); /* high dispersion */
102 : }
103 0 : ELSE IF( LE_32( core_brate, ACELP_8k85 ) )
104 : {
105 0 : i = 1;
106 0 : move16(); /* low dispersion */
107 : }
108 : }
109 55563 : ELSE IF( NE_16( coder_type, UNVOICED ) )
110 :
111 : {
112 55563 : test();
113 55563 : test();
114 55563 : test();
115 55563 : test();
116 55563 : IF( LE_32( core_brate, ACELP_7k20 ) )
117 : {
118 280 : i = 0;
119 280 : move16(); /* high dispersion */
120 : }
121 55283 : ELSE IF( ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, TRANSITION ) || EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && LE_32( core_brate, ACELP_9k60 ) )
122 : {
123 5088 : i = 1;
124 5088 : move16(); /* low dispersion */
125 : }
126 : }
127 :
128 55563 : phase_dispersion_fx( norm_gain_code, gain_pit, code, i, dm_fx );
129 :
130 : /*------------------------------------------------------------
131 : * noise enhancer
132 : *
133 : * - Enhance excitation on noise. (modify gain of code)
134 : * If signal is noisy and LPC filter is stable, move gain
135 : * of code 1.5 dB toward gain of code threshold.
136 : * This decreases by 3 dB noise energy variation.
137 : *-----------------------------------------------------------*/
138 :
139 : /* tmp = 0.5f * (1.0f - voice_fac) */
140 55563 : tmp = msu_r_sat( 0x40000000 /*0.5.Q31*/, voice_fac, 16384 /*0.5.Q15*/ ); /*Q15 */ /* 1=unvoiced, 0=voiced */
141 : /* fac = stab_fac * tmp */
142 55563 : fac = mult( stab_fac, tmp ); /*Q15*/
143 :
144 55563 : IF( LT_32( norm_gain_code, *gc_threshold ) )
145 : {
146 22766 : L_tmp = Madd_32_16( norm_gain_code, norm_gain_code, 6226 /*0.19.Q15*/ ); /*Q16 */
147 22766 : L_tmp = L_min( L_tmp, *gc_threshold ); /*Q16 */
148 : }
149 : ELSE
150 : {
151 32797 : L_tmp = Mult_32_16( norm_gain_code, 27536 /*0.84.Q15*/ ); /*Q16 */
152 32797 : L_tmp = L_max( L_tmp, *gc_threshold ); /*Q16 */
153 : }
154 55563 : *gc_threshold = L_tmp;
155 55563 : move32(); /*Q16 */
156 :
157 : /* gain_code = (fac * tmp) + (1.0 - fac) * gain_code ==> fac * (tmp - gain_code) + gain_code */
158 55563 : L_tmp = L_sub( L_tmp, norm_gain_code ); /*Q16 */
159 55563 : norm_gain_code = Madd_32_16( norm_gain_code, L_tmp, fac ); /*Q16 */
160 :
161 : /* gain_code *= gain_inov - Inverse the normalization */
162 55563 : L_tmp = Mult_32_16( norm_gain_code, gain_inov ); /*Q13*/ /* gain_inov in Q12 */
163 :
164 55563 : sc = 6;
165 55563 : move16();
166 :
167 55563 : gain_code_hi = round_fx( L_shl( L_tmp, add( Q_exc, 3 ) ) ); /* in Q_exc */
168 :
169 : /*------------------------------------------------------------*
170 : * pitch enhancer
171 : *
172 : * - Enhance excitation on voiced. (HP filtering of code)
173 : * On voiced signal, filtering of code by a smooth fir HP
174 : * filter to decrease energy of code at low frequency.
175 : *------------------------------------------------------------*/
176 55563 : test();
177 55563 : IF( !Opt_AMR_WB && EQ_16( coder_type, UNVOICED ) )
178 : {
179 : /* Copy(code, exc2, L_SUBFR) */
180 0 : FOR( i = 0; i < L_SUBFR; i++ )
181 : {
182 0 : pt_exc2[i] = round_fx( L_shl( L_mult( gain_code_hi, code[i] ), sc ) ); /*Q0 */ /* code in Q12 (Q9 for encoder) */
183 0 : move16();
184 : }
185 : }
186 : ELSE
187 : {
188 55563 : test();
189 55563 : test();
190 55563 : IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
191 : {
192 0 : pit_sharp = shl_sat( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */
193 : /* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */
194 0 : IF( GT_16( pit_sharp, 16384 /*0.5.Q15*/ ) )
195 : {
196 0 : tmp16 = mult( pit_sharp, 8192 /*0.25.Q15*/ );
197 0 : FOR( i = 0; i < L_SUBFR; i++ )
198 : {
199 : /* excp[i] = pt_exc2[i] * pit_sharp * 0.25 */
200 0 : excp[i] = mult_r( pt_exc2[i], tmp16 );
201 0 : move16();
202 : }
203 : }
204 : }
205 :
206 55563 : IF( EQ_16( L_frame, L_FRAME16k ) )
207 : {
208 : /* tmp = 0.150 * (1.0 + voice_fac) */
209 : /* 0.30=voiced, 0=unvoiced */
210 26955 : tmp = mac_r( 0x10000000L, voice_fac, 4915 /*0.15.Q15*/ ); /*Q15 */
211 : }
212 : ELSE
213 : {
214 : /* tmp = 0.125 * (1.0 + voice_fac) */
215 : /* 0.25=voiced, 0=unvoiced */
216 28608 : tmp = mac_r( 0x10000000L /*0.125.Q31*/, voice_fac, 4096 ); /*Q15 */
217 : }
218 :
219 : /*-----------------------------------------------------------------
220 : * Do a simple noncasual "sharpening": effectively an FIR
221 : * filter with coefs [-tmp 1.0 -tmp] where tmp=0...0.25.
222 : * This is applied to code and add_fxed to exc2
223 : *-----------------------------------------------------------------*/
224 : /* pt_exc2[0] += code[0] - tmp * code[1] */
225 55563 : L_tmp = L_deposit_h( code[0] ); /* if Enc :Q9 * Q15 -> Q25 */
226 55563 : L_tmp = L_msu( L_tmp, code[1], tmp ); /* Q12 * Q15 -> Q28 */
227 55563 : L_tmp = L_shl_sat( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc );
228 55563 : pt_exc2[0] = msu_r_sat( L_tmp, -32768, pt_exc2[0] );
229 55563 : move16();
230 :
231 3500469 : FOR( i = 1; i < L_SUBFR - 1; i++ )
232 : {
233 : /* pt_exc2[i] += code[i] - tmp * code[i-1] - tmp * code[i+1] */
234 3444906 : L_tmp = L_msu( -32768, code[i], -32768 );
235 3444906 : L_tmp = L_msu( L_tmp, code[i + 1], tmp );
236 3444906 : tmp16 = msu_r_sat( L_tmp, code[i - 1], tmp );
237 3444906 : L_tmp = L_shl_sat( L_mult( gain_code_hi, tmp16 ), sc );
238 3444906 : pt_exc2[i] = msu_r_sat( L_tmp, -32768, pt_exc2[i] );
239 3444906 : move16();
240 : }
241 :
242 : /* pt_exc2[L_SUBFR-1] += code[L_SUBFR-1] - tmp * code[L_SUBFR-2] */
243 55563 : L_tmp = L_deposit_h( code[L_SUBFR - 1] ); /*Q28 */
244 55563 : L_tmp = L_msu( L_tmp, code[L_SUBFR - 2], tmp ); /*Q28 */
245 55563 : L_tmp = L_shl( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc );
246 55563 : pt_exc2[L_SUBFR - 1] = msu_r_sat( L_tmp, -32768, pt_exc2[L_SUBFR - 1] );
247 55563 : move16();
248 55563 : test();
249 55563 : test();
250 55563 : IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
251 : {
252 0 : IF( GT_16( pit_sharp, 16384 /*0.5.Q115*/ ) )
253 : {
254 0 : FOR( i = 0; i < L_SUBFR; i++ )
255 : {
256 : /* excp[i] += pt_exc2[i] */
257 0 : excp[i] = add_sat( excp[i], pt_exc2[i] );
258 0 : move16();
259 : }
260 0 : agc2_fx( pt_exc2, excp, L_SUBFR );
261 0 : Copy( excp, pt_exc2, L_SUBFR );
262 : }
263 : }
264 : }
265 55563 : }
266 :
267 :
268 : /*======================================================================================*/
269 : /* FUNCTION : enhancer_fx() */
270 : /*--------------------------------------------------------------------------------------*/
271 : /* PURPOSE : Enhancement of the excitation signal before synthesis */
272 : /*--------------------------------------------------------------------------------------*/
273 : /* INPUT ARGUMENTS : */
274 : /* _ (Word32) core_brate : decoder bitrate */
275 : /* _ (Word16) Opt_AMR_WB : flag indicating AMR-WB IO mode */
276 : /* _ (Word16) coder_type : coder type */
277 : /* _ (Word16) i_subfr : subframe number */
278 : /* _ (Word16) voice_fac : subframe voicing estimation (Q15) */
279 : /* _ (Word16) stab_fac : LP filter stablility measure (Q15) */
280 : /* _ (Word32) norm_gain_code : normalised innovative cb. gain (Q16) */
281 : /* _ (Word16) gain_inov : gain of the unscaled innovation (Q12) */
282 : /* _ (Word16) gain_pit_fx : Pitch gain (Q14) */
283 : /* _ (Word16) Q_exc : Q of the excitation */
284 : /* _ (Word16) Enc : Encoder = 1; decoder = 0 */
285 : /*--------------------------------------------------------------------------------------*/
286 : /* OUTPUT ARGUMENTS : */
287 : /* _ (Word16*) voice_factors_fx : TBE voicing factor (Q15) */
288 : /*--------------------------------------------------------------------------------------*/
289 : /* INPUT/OUTPUT ARGUMENTS : */
290 : /* _ (Word32*) gc_threshold : gain code threshold (Q16) */
291 : /* _ (Word16*[]) code : innovation (Q12) */
292 : /* _ (Word16*[]) exc2 : adapt. excitation/total exc (Q0) */
293 : /* _ (struct dispMem_fx*) dm_fx : phase dispersion algorithm memory */
294 : /* (a[0]->Q0,a[1]->Q16,a[2-7]->Q14) */
295 : /*--------------------------------------------------------------------------------------*/
296 :
297 : /* _ None */
298 : /*--------------------------------------------------------------------------------------*/
299 : /* RETURN ARGUMENTS : */
300 : /* _ None */
301 : /*======================================================================================*/
302 5496 : void enhancer_ivas_fx(
303 : const Word16 codec_mode, /* i : flag indicating Codec Mode */
304 : const Word32 core_brate, /* i : decoder bitrate */
305 : const Word16 cbk_index, /* i : */
306 : const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */
307 : const Word16 coder_type, /* i : coder type */
308 : const Word16 i_subfr, /* i : subframe number */
309 : const Word16 L_frame, /* i : frame size */
310 : const Word16 voice_fac, /* i : subframe voicing estimation Q15 */
311 : const Word16 stab_fac, /* i : LP filter stablility measure Q15 */
312 : Word32 norm_gain_code, /* i : normalised innovative cb. gain Q16 */
313 : const Word16 gain_inov, /* i : gain of the unscaled innovation Q12 */
314 : Word32 *gc_threshold, /* i/o: gain code threshold Q16 */
315 : Word16 *code, /* i/o: innovation Q12 */
316 : Word16 *exc2, /* i/o: adapt. excitation/total exc. Q_exc*/
317 : const Word16 gain_pit, /* i : quantized pitch gain Q14 */
318 : struct dispMem_fx *dm_fx, /* i/o: phase dispersion algorithm memory */
319 : const Word16 Q_exc /* i : Q of the excitation */
320 : )
321 : {
322 : Word16 tmp, fac, *pt_exc2;
323 : Word16 i;
324 : Word32 L_tmp;
325 : Word16 gain_code_hi;
326 : Word16 pit_sharp, tmp16;
327 : Word16 excp[L_SUBFR], sc;
328 :
329 :
330 5496 : pit_sharp = gain_pit;
331 5496 : move16(); /* to remove gcc warning */
332 5496 : pt_exc2 = exc2 + i_subfr;
333 :
334 : /*------------------------------------------------------------*
335 : * Phase dispersion to enhance noise at low bit rate
336 : *------------------------------------------------------------*/
337 :
338 5496 : i = 2;
339 5496 : move16(); /* no dispersion */
340 5496 : test();
341 5496 : test();
342 5496 : test();
343 5496 : IF( Opt_AMR_WB )
344 : {
345 0 : IF( LE_32( core_brate, ACELP_6k60 ) )
346 : {
347 0 : i = 0;
348 0 : move16(); /* high dispersion */
349 : }
350 0 : ELSE IF( LE_32( core_brate, ACELP_8k85 ) )
351 : {
352 0 : i = 1;
353 0 : move16(); /* low dispersion */
354 : }
355 : }
356 5496 : ELSE IF( EQ_16( codec_mode, MODE1 ) && NE_16( coder_type, UNVOICED ) )
357 :
358 : {
359 0 : test();
360 0 : test();
361 0 : test();
362 0 : test();
363 0 : IF( LE_32( core_brate, ACELP_7k20 ) )
364 : {
365 0 : i = 0;
366 0 : move16(); /* high dispersion */
367 : }
368 0 : ELSE IF( ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, TRANSITION ) || EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && LE_32( core_brate, ACELP_9k60 ) )
369 : {
370 0 : i = 1;
371 0 : move16(); /* low dispersion */
372 : }
373 : }
374 5496 : ELSE IF( EQ_16( codec_mode, MODE2 ) )
375 : {
376 0 : test();
377 0 : test();
378 0 : test();
379 0 : test();
380 0 : test();
381 0 : test();
382 0 : test();
383 0 : test();
384 0 : IF( ( NE_16( coder_type, VOICED ) && LE_16( cbk_index, 2 ) ) || ( EQ_16( coder_type, UNVOICED ) && EQ_16( L_frame, L_FRAME ) && LE_16( cbk_index, 10 ) ) || ( EQ_16( coder_type, UNVOICED ) && EQ_16( L_frame, L_FRAME16k ) && LE_16( cbk_index, 14 ) ) )
385 : {
386 0 : i = 0; /* high dispersion */
387 0 : move16();
388 : }
389 0 : ELSE IF( NE_16( coder_type, VOICED ) && LE_16( cbk_index, 7 ) )
390 : {
391 0 : i = 1; /* low dispersion */
392 0 : move16();
393 : }
394 : }
395 5496 : ELSE IF( EQ_16( codec_mode, MODE1 ) && EQ_16( coder_type, UNVOICED ) && cbk_index /*uc_two_stage_flag*/ )
396 : {
397 5496 : i = 0; /* high dispersion */
398 5496 : move16();
399 : }
400 :
401 5496 : phase_dispersion_fx( norm_gain_code, gain_pit, code, i, dm_fx );
402 :
403 : /*------------------------------------------------------------
404 : * noise enhancer
405 : *
406 : * - Enhance excitation on noise. (modify gain of code)
407 : * If signal is noisy and LPC filter is stable, move gain
408 : * of code 1.5 dB toward gain of code threshold.
409 : * This decreases by 3 dB noise energy variation.
410 : *-----------------------------------------------------------*/
411 :
412 : /* tmp = 0.5f * (1.0f - voice_fac) */
413 5496 : tmp = msu_r_sat( 0x40000000 /*0.5.Q31*/, voice_fac, 16384 /*0.5.Q14*/ ); /*Q15 */ /* 1=unvoiced, 0=voiced */
414 : /* fac = stab_fac * tmp */
415 5496 : fac = mult( stab_fac, tmp ); /*Q15*/
416 :
417 5496 : IF( LT_32( norm_gain_code, *gc_threshold ) )
418 : {
419 2713 : L_tmp = Madd_32_16( norm_gain_code, norm_gain_code, 6226 /*0.19.Q15*/ ); /*Q16 */
420 2713 : L_tmp = L_min( L_tmp, *gc_threshold ); /*Q16 */
421 : }
422 : ELSE
423 : {
424 2783 : L_tmp = Mult_32_16( norm_gain_code, 27536 /*0.84.Q15*/ ); /*Q16 */
425 2783 : L_tmp = L_max( L_tmp, *gc_threshold ); /*Q16 */
426 : }
427 5496 : *gc_threshold = L_tmp;
428 5496 : move32(); /*Q16 */
429 :
430 : /* gain_code = (fac * tmp) + (1.0 - fac) * gain_code ==> fac * (tmp - gain_code) + gain_code */
431 5496 : L_tmp = L_sub( L_tmp, norm_gain_code ); /*Q16 */
432 5496 : norm_gain_code = Madd_32_16( norm_gain_code, L_tmp, fac ); /*Q16 */
433 :
434 : /* gain_code *= gain_inov - Inverse the normalization */
435 5496 : L_tmp = Mult_32_16( norm_gain_code, gain_inov ); /*Q13*/ /* gain_inov in Q12 */
436 :
437 5496 : sc = 6;
438 5496 : move16();
439 :
440 5496 : gain_code_hi = round_fx( L_shl( L_tmp, add( Q_exc, 3 ) ) ); /* in Q_exc */
441 :
442 : /*------------------------------------------------------------*
443 : * pitch enhancer
444 : *
445 : * - Enhance excitation on voiced. (HP filtering of code)
446 : * On voiced signal, filtering of code by a smooth fir HP
447 : * filter to decrease energy of code at low frequency.
448 : *------------------------------------------------------------*/
449 5496 : test();
450 5496 : IF( !Opt_AMR_WB && EQ_16( coder_type, UNVOICED ) )
451 : {
452 : /* Copy(code, exc2, L_SUBFR) */
453 357240 : FOR( i = 0; i < L_SUBFR; i++ )
454 : {
455 351744 : pt_exc2[i] = round_fx( L_shl( L_mult( gain_code_hi, code[i] ), sc ) ); /*Q0 */ /* code in Q12 (Q9 for encoder) */
456 351744 : move16();
457 : }
458 : }
459 : ELSE
460 : {
461 0 : test();
462 0 : test();
463 0 : IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
464 : {
465 0 : pit_sharp = shl_sat( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */
466 : /* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */
467 0 : IF( GT_16( pit_sharp, 16384 /*0.5.Q15*/ ) )
468 : {
469 0 : tmp16 = mult( pit_sharp, 8192 /*0.25.Q15*/ );
470 0 : FOR( i = 0; i < L_SUBFR; i++ )
471 : {
472 : /* excp[i] = pt_exc2[i] * pit_sharp * 0.25 */
473 0 : excp[i] = mult_r( pt_exc2[i], tmp16 );
474 0 : move16();
475 : }
476 : }
477 : }
478 :
479 0 : IF( EQ_16( L_frame, L_FRAME16k ) )
480 : {
481 : /* tmp = 0.150 * (1.0 + voice_fac) */
482 : /* 0.30=voiced, 0=unvoiced */
483 0 : tmp = mac_r( 0x13333333L /*0.150.Q31*/, voice_fac, 4915 /*0.150.Q15*/ ); /*Q15 */
484 : }
485 : ELSE
486 : {
487 : /* tmp = 0.125 * (1.0 + voice_fac) */
488 : /* 0.25=voiced, 0=unvoiced */
489 0 : tmp = mac_r( 0x10000000L /*0.125.Q31*/, voice_fac, 4096 ); /*Q15 */
490 : }
491 :
492 : /*-----------------------------------------------------------------
493 : * Do a simple noncasual "sharpening": effectively an FIR
494 : * filter with coefs [-tmp 1.0 -tmp] where tmp=0...0.25.
495 : * This is applied to code and add_fxed to exc2
496 : *-----------------------------------------------------------------*/
497 : /* pt_exc2[0] += code[0] - tmp * code[1] */
498 0 : L_tmp = L_deposit_h( code[0] ); /* if Enc :Q9 * Q15 -> Q25 */
499 0 : L_tmp = L_msu( L_tmp, code[1], tmp ); /* Q12 * Q15 -> Q28 */
500 0 : L_tmp = L_shl( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc );
501 0 : pt_exc2[0] = msu_r( L_tmp, -32768, pt_exc2[0] );
502 0 : move16(); /* in Q_exc */
503 :
504 0 : FOR( i = 1; i < L_SUBFR - 1; i++ )
505 : {
506 : /* pt_exc2[i] += code[i] - tmp * code[i-1] - tmp * code[i+1] */
507 0 : L_tmp = L_msu( -32768, code[i], -32768 );
508 0 : L_tmp = L_msu( L_tmp, code[i + 1], tmp );
509 0 : tmp16 = msu_r( L_tmp, code[i - 1], tmp );
510 0 : L_tmp = L_shl( L_mult( gain_code_hi, tmp16 ), sc );
511 0 : pt_exc2[i] = msu_r_sat( L_tmp, -32768, pt_exc2[i] );
512 0 : move16(); /* in Q_exc */
513 : }
514 :
515 : /* pt_exc2[L_SUBFR-1] += code[L_SUBFR-1] - tmp * code[L_SUBFR-2] */
516 0 : L_tmp = L_deposit_h( code[L_SUBFR - 1] ); /*Q28 */
517 0 : L_tmp = L_msu( L_tmp, code[L_SUBFR - 2], tmp ); /*Q28 */
518 0 : L_tmp = L_shl( L_mult( gain_code_hi, extract_h( L_tmp ) ), sc );
519 0 : pt_exc2[L_SUBFR - 1] = msu_r( L_tmp, -32768, pt_exc2[L_SUBFR - 1] );
520 0 : move16(); /* in Q_exc */
521 0 : test();
522 0 : test();
523 0 : IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
524 : {
525 0 : IF( GT_16( pit_sharp, 16384 /*0.5.Q14*/ ) )
526 : {
527 0 : FOR( i = 0; i < L_SUBFR; i++ )
528 : {
529 : /* excp[i] += pt_exc2[i] */
530 0 : excp[i] = add( excp[i], pt_exc2[i] );
531 0 : move16();
532 : }
533 0 : agc2_fx( pt_exc2, excp, L_SUBFR );
534 0 : Copy( excp, pt_exc2, L_SUBFR );
535 : }
536 : }
537 : }
538 5496 : }
539 :
540 436537 : void enhancer_ivas_fx2(
541 : const Word32 core_brate, /* i : decoder bitrate */
542 : const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */
543 : const Word16 coder_type, /* i : coder type */
544 : const Word16 i_subfr, /* i : subframe number */
545 : const Word16 L_frame, /* i : frame size */
546 : const Word16 voice_fac, /* i : subframe voicing estimation Q15 */
547 : const Word16 stab_fac, /* i : LP filter stablility measure Q15 */
548 : Word32 norm_gain_code, /* i : normalised innovative cb. gain Q16 */
549 : const Word16 gain_inov, /* i : gain of the unscaled innovation Q12 */
550 : Word32 *gc_threshold, /* i/o: gain code threshold Q16 */
551 : Word16 *code, /* i/o: innovation Q12 */
552 : Word16 *exc2, /* i/o: adapt. excitation/total exc. Q_exc*/
553 : const Word16 gain_pit, /* i : quantized pitch gain Q14 */
554 : struct dispMem_fx *dm_fx, /* i/o: phase dispersion algorithm memory */
555 : const Word16 Q_exc /* i : Q of the excitation */
556 : )
557 : {
558 : Word16 tmp, fac, *pt_exc2;
559 : Word16 i;
560 : Word32 L_tmp;
561 : Word32 L_tmp1, L_tmp2;
562 : Word16 gain_code_hi;
563 : Word16 pit_sharp, tmp16;
564 : Word16 excp[L_SUBFR], sc;
565 : Word64 w_temp;
566 :
567 :
568 436537 : pit_sharp = gain_pit;
569 436537 : move16(); /* to remove gcc warning */
570 436537 : pt_exc2 = exc2 + i_subfr;
571 :
572 : /*------------------------------------------------------------*
573 : * Phase dispersion to enhance noise at low bit rate
574 : *------------------------------------------------------------*/
575 :
576 436537 : i = 2;
577 436537 : move16(); /* no dispersion */
578 436537 : IF( Opt_AMR_WB )
579 : {
580 0 : IF( LE_32( core_brate, ACELP_6k60 ) )
581 : {
582 0 : i = 0;
583 0 : move16(); /* high dispersion */
584 : }
585 0 : ELSE IF( LE_32( core_brate, ACELP_8k85 ) )
586 : {
587 0 : i = 1;
588 0 : move16(); /* low dispersion */
589 : }
590 : }
591 436537 : ELSE IF( NE_16( coder_type, UNVOICED ) )
592 :
593 : {
594 436537 : test();
595 436537 : test();
596 436537 : test();
597 436537 : test();
598 436537 : IF( LE_32( core_brate, ACELP_7k20 ) )
599 : {
600 4700 : i = 0;
601 4700 : move16(); /* high dispersion */
602 : }
603 431837 : ELSE IF( ( EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, TRANSITION ) || EQ_16( coder_type, AUDIO ) || coder_type == INACTIVE ) && LE_32( core_brate, ACELP_9k60 ) )
604 : {
605 31928 : i = 1;
606 31928 : move16(); /* low dispersion */
607 : }
608 : }
609 :
610 436537 : phase_dispersion_fx( norm_gain_code, gain_pit, code, i, dm_fx );
611 :
612 : /*------------------------------------------------------------
613 : * noise enhancer
614 : *
615 : * - Enhance excitation on noise. (modify gain of code)
616 : * If signal is noisy and LPC filter is stable, move gain
617 : * of code 1.5 dB toward gain of code threshold.
618 : * This decreases by 3 dB noise energy variation.
619 : *-----------------------------------------------------------*/
620 :
621 : /* tmp = 0.5f * (1.0f - voice_fac) */
622 436537 : tmp = msu_r_sat( 0x40000000 /*0.5.Q31*/, voice_fac, 16384 /*0.5.Q15*/ ); /*Q15 */ /* 1=unvoiced, 0=voiced */
623 : /* fac = stab_fac * tmp */
624 436537 : fac = mult( stab_fac, tmp ); /*Q15*/
625 :
626 436537 : IF( LT_32( norm_gain_code, *gc_threshold ) )
627 : {
628 227722 : L_tmp = Madd_32_16( norm_gain_code, norm_gain_code, 6226 /*0.19.Q15*/ ); /*Q16 */
629 227722 : L_tmp = L_min( L_tmp, *gc_threshold ); /*Q16 */
630 : }
631 : ELSE
632 : {
633 208815 : L_tmp = Mult_32_16( norm_gain_code, 27536 /*0.84.Q15*/ ); /*Q16 */
634 208815 : L_tmp = L_max( L_tmp, *gc_threshold ); /*Q16 */
635 : }
636 436537 : *gc_threshold = L_tmp;
637 436537 : move32(); /*Q16 */
638 :
639 : /* gain_code = (fac * tmp) + (1.0 - fac) * gain_code ==> fac * (tmp - gain_code) + gain_code */
640 436537 : L_tmp = L_sub( L_tmp, norm_gain_code ); /*Q16 */
641 436537 : norm_gain_code = Madd_32_16( norm_gain_code, L_tmp, fac ); /*Q16 */
642 :
643 : /* gain_code *= gain_inov - Inverse the normalization */
644 436537 : L_tmp = Mult_32_16( norm_gain_code, gain_inov ); /*Q13*/ /* gain_inov in Q12 */
645 :
646 436537 : sc = 6;
647 436537 : move16();
648 :
649 436537 : gain_code_hi = round_fx( L_shl( L_tmp, add( Q_exc, 3 ) ) ); /* in Q_exc */
650 :
651 : /*------------------------------------------------------------*
652 : * pitch enhancer
653 : *
654 : * - Enhance excitation on voiced. (HP filtering of code)
655 : * On voiced signal, filtering of code by a smooth fir HP
656 : * filter to decrease energy of code at low frequency.
657 : *------------------------------------------------------------*/
658 436537 : test();
659 436537 : IF( !Opt_AMR_WB && EQ_16( coder_type, UNVOICED ) )
660 : {
661 : /* Copy(code, exc2, L_SUBFR) */
662 0 : FOR( i = 0; i < L_SUBFR; i++ )
663 : {
664 0 : pt_exc2[i] = round_fx( L_shl( L_mult( gain_code_hi, code[i] ), sc ) ); /*Q0 */ /* code in Q12 (Q9 for encoder) */
665 0 : move16();
666 : }
667 : }
668 : ELSE
669 : {
670 436537 : test();
671 436537 : test();
672 436537 : IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
673 : {
674 0 : pit_sharp = shl_sat( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */
675 : /* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */
676 0 : IF( GT_16( pit_sharp, 16384 /*0.5.Q15*/ ) )
677 : {
678 0 : tmp16 = mult( pit_sharp, 8192 /*0.25.Q15*/ );
679 0 : FOR( i = 0; i < L_SUBFR; i++ )
680 : {
681 : /* excp[i] = pt_exc2[i] * pit_sharp * 0.25 */
682 0 : excp[i] = mult_r( pt_exc2[i], tmp16 );
683 0 : move16();
684 : }
685 : }
686 : }
687 :
688 436537 : IF( EQ_16( L_frame, L_FRAME16k ) )
689 : {
690 : /* tmp = 0.150 * (1.0 + voice_fac) */
691 : /* 0.30=voiced, 0=unvoiced */
692 249485 : tmp = mac_r( 0x13333333L /*0.150.Q31*/, voice_fac, 4915 /*0.150.Q15*/ ); /*Q15 */
693 : }
694 : ELSE
695 : {
696 : /* tmp = 0.125 * (1.0 + voice_fac) */
697 : /* 0.25=voiced, 0=unvoiced */
698 187052 : tmp = mac_r( 0x10000000L /*0.125.Q31*/, voice_fac, 4096 /*0.125.Q15*/ ); /*Q15 */
699 : }
700 :
701 : /*-----------------------------------------------------------------
702 : * Do a simple noncasual "sharpening": effectively an FIR
703 : * filter with coefs [-tmp 1.0 -tmp] where tmp=0...0.25.
704 : * This is applied to code and add_fxed to exc2
705 : *-----------------------------------------------------------------*/
706 :
707 436537 : L_tmp1 = L_deposit_h( gain_code_hi ); // Q = 16 + Q_exc, gain_code
708 436537 : L_tmp2 = L_mult( tmp, gain_code_hi ); // Q = 16 + Q_exc, gain_code * temp
709 :
710 : /* pt_exc2[0] += code[0] - tmp * code[1] */
711 436537 : w_temp = W_msu_32_16( W_mult_32_16( L_tmp1, code[0] ), L_tmp2, code[1] ); // Q = 32 + Q_exc - sc (16+Q_exc+15-sc+1)
712 436537 : w_temp = W_shl( w_temp, sc ); // Q = 32 + Q_exc
713 436537 : pt_exc2[0] = W_round32_s( W_msu_32_16( w_temp, MIN_32, pt_exc2[0] ) ); // Q = Q_exc
714 436537 : move16();
715 :
716 27501831 : FOR( i = 1; i < L_SUBFR - 1; i++ )
717 : {
718 : /* pt_exc2[i] += (code[i] - tmp * code[i-1] - tmp * code[i+1]) * gain_code */
719 27065294 : w_temp = W_msu_32_16( W_mult_32_16( L_tmp1, code[i] ), L_tmp2, code[i - 1] ); // Q = 32 + Q_exc - sc (16+Q_exc+15-sc+1)
720 27065294 : w_temp = W_msu_32_16( w_temp, L_tmp2, code[i + 1] ); // Q = 32 + Q_exc - sc (16+Q_exc+15-sc+1)
721 27065294 : w_temp = W_shl( w_temp, sc ); // Q = 32 + Q_exc
722 27065294 : pt_exc2[i] = W_round32_s( W_msu_32_16( w_temp, MIN_32, pt_exc2[i] ) ); // Q = Q_exc
723 27065294 : move16();
724 : }
725 :
726 : /* pt_exc2[L_SUBFR-1] += code[L_SUBFR-1] - tmp * code[L_SUBFR-2] */
727 436537 : w_temp = W_msu_32_16( W_mult_32_16( L_tmp1, code[L_SUBFR - 1] ), L_tmp2, code[L_SUBFR - 2] ); // Q = 32 + Q_exc - sc (16+Q_exc+15-sc+1)
728 436537 : w_temp = W_shl( w_temp, sc ); // Q = 32 + Q_exc
729 436537 : pt_exc2[L_SUBFR - 1] = W_round32_s( W_msu_32_16( w_temp, MIN_32, pt_exc2[L_SUBFR - 1] ) ); // Q = Q_exc
730 436537 : move16();
731 :
732 436537 : test();
733 436537 : test();
734 436537 : IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
735 : {
736 0 : IF( GT_16( pit_sharp, 16384 /*0.5.Q15*/ ) )
737 : {
738 0 : FOR( i = 0; i < L_SUBFR; i++ )
739 : {
740 : /* excp[i] += pt_exc2[i] */
741 0 : excp[i] = add_sat( excp[i], pt_exc2[i] );
742 0 : move16();
743 : }
744 0 : agc2_fx( pt_exc2, excp, L_SUBFR );
745 0 : Copy( excp, pt_exc2, L_SUBFR );
746 : }
747 : }
748 : }
749 436537 : }
750 :
751 : /*---------------------------------------------------------*
752 : * Enhancement of the excitation signal before synthesis
753 : *---------------------------------------------------------*/
754 :
755 6070 : Word16 E_UTIL_enhancer(
756 : Word16 voice_fac, /* i : subframe voicing estimation Q15 */
757 : Word16 stab_fac, /* i : LP filter stability measure Q15 */
758 : Word32 gain_code, /* i : innovative cb. gain 15Q16 */
759 : Word16 gain_inov, /* i : gain of the unscaled innovation Q11 */
760 : Word32 *gc_threshold, /* i/o: gain code threshold 15Q16 */
761 : Word16 *code, /* i/o: innovation(in: Q9) code_exp */
762 : Word16 *exc2, /* i/o: adapt. excitation/total exc. */
763 : Word16 gain_pit, /* i : Quantized pitch gain 1Q14 */
764 : Word32 *prev_gain_code, /* i/o: previous codebook gain 15Q16 */
765 : Word16 prev_gain_pit[], /* i/o: previous pitch gain, size=6 1Q14 */
766 : Word16 *prev_state, /* i/o: Phase dispersion algorithm memory Q0 */
767 : Word16 coder_type, /* i : coder type */
768 : Word16 cdk_index, /* i : */
769 : Word16 L_subfr, /* i : length of subframe */
770 : Word16 L_frame, /* i : frame size */
771 : Word16 Q_new )
772 : {
773 : Word16 disp_mode, i;
774 : Word16 tmp, fac, gain;
775 : Word32 L_tmp;
776 : Word16 code_exp, exc2_exp;
777 : Word16 max_cdk_index_uv;
778 :
779 6070 : move16();
780 6070 : code_exp = 15 - 9;
781 6070 : exc2_exp = sub( 15, Q_new );
782 6070 : gain_inov = shr( gain_inov, 1 );
783 : /*-----------------------------------------------------------------*
784 : * Phase dispersion to enhance noise at low bit rates
785 : *-----------------------------------------------------------------*/
786 :
787 6070 : max_cdk_index_uv = 10;
788 6070 : move16();
789 6070 : if ( EQ_16( L_frame, L_FRAME16k ) )
790 : {
791 6070 : max_cdk_index_uv = 14;
792 6070 : move16();
793 : }
794 6070 : disp_mode = 2; /* any=off */
795 6070 : move16();
796 6070 : test();
797 6070 : test();
798 6070 : test();
799 6070 : test();
800 6070 : IF( ( ( NE_16( coder_type, VOICED ) ) && ( LE_16( cdk_index, 2 ) ) ) || ( ( EQ_16( coder_type, UNVOICED ) ) && ( LE_16( cdk_index, max_cdk_index_uv ) ) ) )
801 : {
802 0 : disp_mode = 0; /* high */
803 0 : move16();
804 : }
805 6070 : ELSE IF( ( NE_16( coder_type, VOICED ) ) && ( LE_16( cdk_index, 7 ) ) )
806 : {
807 0 : disp_mode = 1; /* low */
808 0 : move16();
809 : }
810 :
811 6070 : phase_dispersion( gain_code, gain_pit, code, &code_exp, disp_mode, prev_gain_code, prev_gain_pit, prev_state, L_subfr );
812 :
813 : /*------------------------------------------------------------*
814 : * noise enhancer *
815 : * ~~~~~~~~~~~~~~ *
816 : * - Enhance excitation on noise. (modify gain of code) *
817 : * If signal is noisy and LPC filter is stable, move gain *
818 : * of code 1.5 dB toward gain of code threshold. *
819 : * This decrease by 3 dB noise energy variation. *
820 : *------------------------------------------------------------*/
821 6070 : fac = 0;
822 6070 : move16();
823 :
824 : /* if gain_code is computed function of energy, noise enhancer is by-passed.*/
825 : BASOP_SATURATE_WARNING_OFF_EVS
826 6070 : tmp = msu_r_sat( 1073741824l /*0.5f Q31*/, 16384 /*0.5f Q15*/, voice_fac ); /* 1=unvoiced, 0=voiced */
827 : BASOP_SATURATE_WARNING_ON_EVS
828 6070 : fac = mult_r( stab_fac, tmp ); /* fac in Q15 */
829 :
830 6070 : L_tmp = gain_code; /* L_tmp in 15Q16 */
831 6070 : move32();
832 :
833 6070 : IF( LT_32( L_tmp, *gc_threshold ) )
834 : {
835 3376 : L_tmp = L_shl( Mpy_32_32( L_tmp, 1277752832l /*1.19f/2.0f Q31*/ ), 1 );
836 3376 : L_tmp = L_min( L_tmp, *gc_threshold );
837 : }
838 : ELSE
839 : {
840 2694 : L_tmp = Mpy_32_32( L_tmp, 1804608000l /*1.0f/1.19f Q31*/ );
841 2694 : L_tmp = L_max( L_tmp, *gc_threshold );
842 : }
843 :
844 6070 : *gc_threshold = L_tmp; /* in 15Q16 */
845 6070 : move32();
846 :
847 : /* gain = ( (fac * L_tmp) + (gain_code - fac*gain_code) ) * gain_inov */
848 : /* exponent of L_tmp: 31-16 + 15-11 */
849 6070 : L_tmp = Mpy_32_16_1( L_add( Mpy_32_16_1( L_tmp, fac ), L_sub( gain_code, Mpy_32_16_1( gain_code, fac ) ) ), gain_inov );
850 :
851 : /* exponent gain: 31-16 + 15-11 - tmp */
852 6070 : tmp = norm_l( L_tmp );
853 :
854 : /* exponent of code: 31-16 + 15-11 - tmp + code_exp */
855 6070 : code_exp = sub( add( 31 - 16 + 15 - 11, code_exp ), tmp );
856 :
857 6070 : L_tmp = L_shl_sat( L_tmp, tmp );
858 6070 : gain = round_fx_sat( L_tmp );
859 :
860 394550 : FOR( i = 0; i < L_subfr; i++ )
861 : {
862 388480 : code[i] = mult_r( code[i], gain );
863 388480 : move16();
864 : }
865 :
866 : /*------------------------------------------------------------*
867 : * pitch enhancer *
868 : * ~~~~~~~~~~~~~~ *
869 : * - Enhance excitation on voice. (HP filtering of code) *
870 : * On voiced signal, filtering of code by a smooth fir HP *
871 : * filter to decrease energy of code in low frequency. *
872 : *------------------------------------------------------------*/
873 :
874 : /* exponent difference of code and exc2. +1 accounts for headroom required below. */
875 6070 : gain = add( sub( code_exp, exc2_exp ), 1 );
876 :
877 6070 : tmp = mac_r( 268435456l /*0.125f Q31*/, 4096 /*0.125f Q15*/, voice_fac ); /* 0.25=voiced, 0=unvoiced */
878 6070 : IF( EQ_16( L_frame, L_FRAME16k ) )
879 : {
880 6070 : tmp = mac_r( 322122560l /*0.150f Q31*/, 4915 /*0.150f Q15*/, voice_fac ); /* 0.30=voiced, 0=unvoiced */
881 : }
882 :
883 : /* exc2[0] = exc2[0] + code[0] - tmp*code[1]; */
884 6070 : L_tmp = L_mult( code[0], 16384 );
885 6070 : L_tmp = L_msu0( L_tmp, tmp, code[1] );
886 6070 : IF( gain )
887 : {
888 5909 : L_tmp = L_shl_sat( L_tmp, gain );
889 : }
890 6070 : exc2[0] = msu_r_sat( L_tmp, -32768, exc2[0] );
891 6070 : move16();
892 :
893 382410 : FOR( i = 1; i < L_subfr - 1; i++ )
894 : {
895 : /* exc2[i] = exc2[i] + code[i] - tmp*(code[i+1]+code[i-1]); */
896 376340 : L_tmp = L_mult( code[i], 16384 );
897 376340 : L_tmp = L_msu0_sat( L_tmp, tmp, code[i - 1] );
898 376340 : L_tmp = L_msu0_sat( L_tmp, tmp, code[i + 1] );
899 376340 : IF( gain )
900 : {
901 366358 : L_tmp = L_shl_sat( L_tmp, gain );
902 : }
903 376340 : exc2[i] = msu_r_sat( L_tmp, -32768, exc2[i] );
904 376340 : move16();
905 : }
906 : /* exc2[L_subfr-1] = exc2[L_subfr-1] + code[L_subfr-1] - tmp*code[L_subfr-2]; */
907 6070 : L_tmp = L_mult( code[i], 16384 );
908 6070 : L_tmp = L_msu0_sat( L_tmp, tmp, code[i - 1] );
909 6070 : IF( gain )
910 : {
911 5909 : L_tmp = L_shl_sat( L_tmp, gain );
912 : }
913 6070 : exc2[i] = msu_r_sat( L_tmp, -32768, exc2[i] );
914 6070 : move16();
915 :
916 6070 : return code_exp;
917 : }
918 :
919 :
920 : /*-----------------------------------------------------------------------*
921 : * Phase_dispersion:
922 : *
923 : * post-processing to enhance noise in low bit rate.
924 : *-----------------------------------------------------------------------*/
925 : /*======================================================================================*/
926 : /* FUNCTION : phase_dispersion_fx() */
927 : /*--------------------------------------------------------------------------------------*/
928 : /* PURPOSE : post-processing to enhance noise in low bit rate. */
929 : /*--------------------------------------------------------------------------------------*/
930 : /* INPUT ARGUMENTS : */
931 : /* _ (Word32) gain_code : gain of code Q16 */
932 : /* _ (Word16) gain_pit : gain of pitch Q14 */
933 : /* _ (Word16) mode : level, 0=hi, 1=lo, 2=off */
934 : /*--------------------------------------------------------------------------------------*/
935 : /* OUTPUT ARGUMENTS : */
936 : /* _ None */
937 : /*--------------------------------------------------------------------------------------*/
938 : /* INPUT/OUTPUT ARGUMENTS : */
939 : /* _ (Word16[]) code : code vector (Q12) */
940 : /* _ (struct dispMem_fx*) dm_fx : static memory (size = 8) */
941 : /* (a[0]->Q0,a[1]->Q16,a[2-7]->Q14) */
942 : /*--------------------------------------------------------------------------------------*/
943 :
944 : /* _ None */
945 : /*--------------------------------------------------------------------------------------*/
946 : /* RETURN ARGUMENTS : */
947 : /* _ None */
948 : /*======================================================================================*/
949 497596 : static void phase_dispersion_fx(
950 : Word32 gain_code, /* i : gain of code Q16 */
951 : Word16 gain_pit, /* i : gain of pitch Q14 */
952 : Word16 code[], /* i/o: code vector */
953 : Word16 mode, /* i : level, 0=hi, 1=lo, 2=off */
954 : struct dispMem_fx *dm_fx /* i/o: static memory (size = 8) */
955 : )
956 : {
957 : Word16 i, j, state;
958 : Word16 *prev_gain_pit, *prev_state;
959 : Word32 *prev_gain_code;
960 : Word16 *code2_real, *code2_imag;
961 : Word16 *code_real, *code_imag;
962 : const Word16 *h_real, *h_imag;
963 :
964 : Word16 code2[2 * L_SUBFR];
965 :
966 497596 : prev_state = &( dm_fx->prev_state );
967 497596 : prev_gain_code = &( dm_fx->prev_gain_code );
968 497596 : prev_gain_pit = dm_fx->prev_gain_pit;
969 :
970 497596 : state = 2;
971 497596 : move16();
972 497596 : if ( LT_16( gain_pit, pitch_0_9 ) )
973 : {
974 358600 : state = 1;
975 358600 : move16();
976 : }
977 :
978 497596 : if ( LT_16( gain_pit, pitch_0_6 ) )
979 : {
980 196962 : state = 0;
981 196962 : move16();
982 : }
983 :
984 2985576 : FOR( i = 5; i > 0; i-- )
985 : {
986 2487980 : prev_gain_pit[i] = prev_gain_pit[i - 1];
987 2487980 : move16();
988 : }
989 497596 : prev_gain_pit[0] = gain_pit;
990 497596 : move16();
991 :
992 497596 : IF( GT_32( L_sub_sat( gain_code, *prev_gain_code ), L_shl_sat( *prev_gain_code, 1 ) ) )
993 : {
994 15275 : state = s_min( add( state, 1 ), 2 );
995 : }
996 : ELSE
997 : {
998 482321 : j = 0;
999 482321 : move16();
1000 :
1001 3376247 : FOR( i = 0; i < 6; i++ )
1002 : {
1003 2893926 : j = sub( j, shr( sub( prev_gain_pit[i], pitch_0_6 ), 15 ) );
1004 : }
1005 :
1006 482321 : if ( GT_16( j, 2 ) )
1007 : {
1008 230091 : state = 0;
1009 230091 : move16();
1010 : }
1011 :
1012 482321 : if ( GT_16( sub( state, *prev_state ), 1 ) )
1013 : {
1014 18181 : state = sub( state, 1 );
1015 : }
1016 : }
1017 :
1018 497596 : *prev_gain_code = gain_code;
1019 497596 : move32();
1020 497596 : *prev_state = state;
1021 497596 : move16();
1022 :
1023 : /*-----------------------------------------------------------------*
1024 : * circular convolution
1025 : *-----------------------------------------------------------------*/
1026 :
1027 497596 : state = add( state, mode ); /* level of dispersion */
1028 :
1029 497596 : IF( LT_16( state, 2 ) )
1030 : {
1031 31129 : r_fft_fx_lc( phs_tbl_dec, SIZE, SIZE2, NUM_STAGES, code, code2, 1 );
1032 :
1033 31129 : h_real = Mid_H_phasedisp;
1034 31129 : if ( state == 0 )
1035 : {
1036 7416 : h_real = Low_H_phasedisp;
1037 : }
1038 :
1039 : /* FFT Coefs are in code2 */
1040 31129 : code2_real = code2;
1041 31129 : code2_imag = code2 + L_SUBFR - 1;
1042 :
1043 31129 : code_real = code;
1044 31129 : code_imag = code + L_SUBFR - 1;
1045 :
1046 31129 : h_imag = h_real + L_SUBFR - 1;
1047 :
1048 31129 : *code_real++ = mult( *code2_real++, *h_real++ );
1049 31129 : move16(); /* DC */
1050 :
1051 996128 : FOR( i = 1; i < L_SUBFR / 2; i++ )
1052 : {
1053 964999 : *code_real++ = msu_r( L_mult( *code2_real, *h_real ), *code2_imag, *h_imag );
1054 964999 : move16();
1055 964999 : *code_imag-- = mac_r( L_mult( *code2_real, *h_imag ), *code2_imag, *h_real );
1056 964999 : move16();
1057 :
1058 964999 : code2_real++;
1059 964999 : h_imag--;
1060 964999 : h_real++;
1061 964999 : code2_imag--;
1062 : }
1063 31129 : *code_real++ = mult( *code2_real++, *h_real++ );
1064 31129 : move16(); /* DC */
1065 :
1066 31129 : r_fft_fx_lc( phs_tbl_dec, SIZE, SIZE2, NUM_STAGES, code, code2, 0 );
1067 :
1068 2023385 : FOR( i = 0; i < L_SUBFR; i++ )
1069 : {
1070 : /* saturation can occur here */
1071 1992256 : code[i] = shl( code2[i], 1 ); /*Q12 */
1072 1992256 : move16();
1073 : }
1074 : }
1075 497596 : }
1076 :
1077 : /*======================================================================================*/
1078 : /* FUNCTION : agc2_fx() */
1079 : /*--------------------------------------------------------------------------------------*/
1080 : /* PURPOSE : AGC post-processing for lower G722.2 modes */
1081 : /*--------------------------------------------------------------------------------------*/
1082 : /* INPUT ARGUMENTS : */
1083 : /* _ (Word16*[]) sig_in : postfilter input signal (Q0) */
1084 : /* _ (Word16) l_trm : subframe size */
1085 : /*--------------------------------------------------------------------------------------*/
1086 : /* OUTPUT ARGUMENTS : */
1087 : /* _ None */
1088 : /*--------------------------------------------------------------------------------------*/
1089 : /* INPUT/OUTPUT ARGUMENTS : */
1090 : /* _ (Word16*[]) sig_out : postfilter output signal (Q0) */
1091 : /*--------------------------------------------------------------------------------------*/
1092 :
1093 : /* _ None */
1094 : /*--------------------------------------------------------------------------------------*/
1095 : /* RETURN ARGUMENTS : */
1096 : /* _ None */
1097 : /*======================================================================================*/
1098 0 : static void agc2_fx(
1099 : const Word16 *sig_in, /* i : postfilter input signal */
1100 : Word16 *sig_out, /* i/o: postfilter output signal */
1101 : const Word16 l_trm /* i : subframe size */
1102 : )
1103 : {
1104 :
1105 : Word16 i, exp;
1106 : Word16 gain_in, gain_out, g0;
1107 : Word32 s;
1108 :
1109 : Word16 temp;
1110 :
1111 : /* calculate gain_out with exponent */
1112 0 : temp = shr( sig_out[0], 2 );
1113 0 : s = L_mult0( temp, temp );
1114 0 : FOR( i = 1; i < l_trm; i++ )
1115 : {
1116 0 : temp = shr( sig_out[i], 2 );
1117 0 : s = L_mac0_sat( s, temp, temp );
1118 : }
1119 0 : IF( s != 0 )
1120 : {
1121 0 : exp = sub( norm_l( s ), 1 );
1122 0 : gain_out = round_fx( L_shl( s, exp ) );
1123 :
1124 : /* calculate gain_in with exponent */
1125 0 : temp = shr( sig_in[0], 2 );
1126 0 : s = L_mult0( temp, temp );
1127 0 : FOR( i = 1; i < l_trm; i++ )
1128 : {
1129 0 : temp = shr( sig_in[i], 2 );
1130 0 : s = L_mac0_sat( s, temp, temp );
1131 : }
1132 :
1133 0 : g0 = 0;
1134 0 : move16();
1135 0 : IF( s != 0 )
1136 : {
1137 0 : i = norm_l( s );
1138 0 : gain_in = round_fx_sat( L_shl_sat( s, i ) );
1139 0 : exp = sub( exp, i );
1140 :
1141 : /*---------------------------------------------------*
1142 : * g0 = sqrt(gain_in / gain_out)
1143 : *---------------------------------------------------*/
1144 0 : s = L_mult0( 128, div_s( gain_out, gain_in ) ); /* s = gain_out / gain_in */
1145 0 : s = L_shr( s, exp ); /* add exponent */
1146 :
1147 0 : s = Isqrt( s );
1148 0 : g0 = round_fx_sat( L_shl_sat( s, 9 ) );
1149 : }
1150 :
1151 : /* sig_out(n) = gain(n) sig_out(n) */
1152 0 : FOR( i = 0; i < l_trm; i++ )
1153 : {
1154 0 : sig_out[i] = round_fx_sat( L_shl_sat( L_mac( -8192, sig_out[i], g0 ), 2 ) );
1155 0 : move16();
1156 : }
1157 : }
1158 0 : }
|