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 :
303 442033 : void enhancer_ivas_fx(
304 : const Word16 codec_mode, /* i : flag indicating Codec Mode */
305 : const Word32 core_brate, /* i : decoder bitrate */
306 : const Word16 cbk_index,
307 : const Word16 Opt_AMR_WB, /* i : flag indicating AMR-WB IO mode */
308 : const Word16 coder_type, /* i : coder type */
309 : const Word16 i_subfr, /* i : subframe number */
310 : const Word16 L_frame, /* i : frame size */
311 : const Word16 voice_fac, /* i : subframe voicing estimation Q15 */
312 : const Word16 stab_fac, /* i : LP filter stablility measure Q15 */
313 : Word32 norm_gain_code, /* i : normalised innovative cb. gain Q16 */
314 : const Word16 gain_inov, /* i : gain of the unscaled innovation Q12 */
315 : Word32 *gc_threshold, /* i/o: gain code threshold Q16 */
316 : Word16 *code, /* i/o: innovation Q12 */
317 : Word16 *exc2, /* i/o: adapt. excitation/total exc. Q_exc*/
318 : const Word16 gain_pit, /* i : quantized pitch gain Q14 */
319 : struct dispMem_fx *dm_fx, /* i/o: phase dispersion algorithm memory */
320 : const Word16 Q_exc /* i : Q of the excitation */
321 : )
322 : {
323 : Word16 tmp, fac, *pt_exc2;
324 : Word16 i;
325 : Word32 L_tmp;
326 : Word32 L_tmp1, L_tmp2;
327 : Word16 gain_code_hi;
328 : Word16 pit_sharp, tmp16;
329 : Word16 excp[L_SUBFR], sc;
330 : Word64 w_temp;
331 :
332 :
333 442033 : pit_sharp = gain_pit;
334 442033 : move16(); /* to remove gcc warning */
335 442033 : pt_exc2 = exc2 + i_subfr;
336 :
337 : /*------------------------------------------------------------*
338 : * Phase dispersion to enhance noise at low bit rate
339 : *------------------------------------------------------------*/
340 :
341 442033 : i = 2;
342 442033 : move16(); /* no dispersion */
343 442033 : test();
344 442033 : test();
345 442033 : test();
346 442033 : IF( Opt_AMR_WB )
347 : {
348 0 : IF( LE_32( core_brate, ACELP_6k60 ) )
349 : {
350 0 : i = 0;
351 0 : move16(); /* high dispersion */
352 : }
353 0 : ELSE IF( LE_32( core_brate, ACELP_8k85 ) )
354 : {
355 0 : i = 1;
356 0 : move16(); /* low dispersion */
357 : }
358 : }
359 442033 : ELSE IF( EQ_16( codec_mode, MODE1 ) && NE_16( coder_type, UNVOICED ) )
360 :
361 : {
362 436537 : test();
363 436537 : test();
364 436537 : test();
365 436537 : test();
366 436537 : IF( LE_32( core_brate, ACELP_7k20 ) )
367 : {
368 4700 : i = 0;
369 4700 : move16(); /* high dispersion */
370 : }
371 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 ) )
372 : {
373 31928 : i = 1;
374 31928 : move16(); /* low dispersion */
375 : }
376 : }
377 5496 : ELSE IF( EQ_16( codec_mode, MODE2 ) )
378 : {
379 0 : test();
380 0 : test();
381 0 : test();
382 0 : test();
383 0 : test();
384 0 : test();
385 0 : test();
386 0 : test();
387 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 ) ) )
388 : {
389 0 : i = 0; /* high dispersion */
390 0 : move16();
391 : }
392 0 : ELSE IF( NE_16( coder_type, VOICED ) && LE_16( cbk_index, 7 ) )
393 : {
394 0 : i = 1; /* low dispersion */
395 0 : move16();
396 : }
397 : }
398 5496 : ELSE IF( EQ_16( codec_mode, MODE1 ) && EQ_16( coder_type, UNVOICED ) && cbk_index /*uc_two_stage_flag*/ )
399 : {
400 5496 : i = 0; /* high dispersion */
401 5496 : move16();
402 : }
403 :
404 442033 : phase_dispersion_fx( norm_gain_code, gain_pit, code, i, dm_fx );
405 :
406 : /*------------------------------------------------------------
407 : * noise enhancer
408 : *
409 : * - Enhance excitation on noise. (modify gain of code)
410 : * If signal is noisy and LPC filter is stable, move gain
411 : * of code 1.5 dB toward gain of code threshold.
412 : * This decreases by 3 dB noise energy variation.
413 : *-----------------------------------------------------------*/
414 :
415 : /* tmp = 0.5f * (1.0f - voice_fac) */
416 442033 : tmp = msu_r_sat( 0x40000000 /*0.5.Q31*/, voice_fac, 16384 /*0.5.Q15*/ ); /*Q15 */ /* 1=unvoiced, 0=voiced */
417 : /* fac = stab_fac * tmp */
418 442033 : fac = mult( stab_fac, tmp ); /*Q15*/
419 :
420 442033 : IF( LT_32( norm_gain_code, *gc_threshold ) )
421 : {
422 230429 : L_tmp = Madd_32_16( norm_gain_code, norm_gain_code, 6226 /*0.19.Q15*/ ); /*Q16 */
423 230429 : L_tmp = L_min( L_tmp, *gc_threshold ); /*Q16 */
424 : }
425 : ELSE
426 : {
427 211604 : L_tmp = Mult_32_16( norm_gain_code, 27536 /*0.84.Q15*/ ); /*Q16 */
428 211604 : L_tmp = L_max( L_tmp, *gc_threshold ); /*Q16 */
429 : }
430 442033 : *gc_threshold = L_tmp;
431 442033 : move32(); /*Q16 */
432 :
433 : /* gain_code = (fac * tmp) + (1.0 - fac) * gain_code ==> fac * (tmp - gain_code) + gain_code */
434 442033 : L_tmp = L_sub( L_tmp, norm_gain_code ); /*Q16 */
435 442033 : norm_gain_code = Madd_32_16( norm_gain_code, L_tmp, fac ); /*Q16 */
436 :
437 : /* gain_code *= gain_inov - Inverse the normalization */
438 442033 : L_tmp = Mult_32_16( norm_gain_code, gain_inov ); /*Q13*/ /* gain_inov in Q12 */
439 :
440 442033 : sc = 6;
441 442033 : move16();
442 :
443 442033 : gain_code_hi = round_fx( L_shl( L_tmp, add( Q_exc, 3 ) ) ); /* in Q_exc */
444 :
445 : /*------------------------------------------------------------*
446 : * pitch enhancer
447 : *
448 : * - Enhance excitation on voiced. (HP filtering of code)
449 : * On voiced signal, filtering of code by a smooth fir HP
450 : * filter to decrease energy of code at low frequency.
451 : *------------------------------------------------------------*/
452 442033 : test();
453 442033 : test();
454 442033 : IF( !Opt_AMR_WB && EQ_16( codec_mode, MODE1 ) && EQ_16( coder_type, UNVOICED ) )
455 : {
456 : /* Copy(code, exc2, L_SUBFR) */
457 357240 : FOR( i = 0; i < L_SUBFR; i++ )
458 : {
459 351744 : pt_exc2[i] = round_fx( L_shl( L_mult( gain_code_hi, code[i] ), sc ) ); /*Q0 */ /* code in Q12 (Q9 for encoder) */
460 351744 : move16();
461 : }
462 : }
463 : ELSE
464 : {
465 436537 : test();
466 436537 : test();
467 436537 : IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
468 : {
469 0 : pit_sharp = shl_sat( gain_pit, 1 ); /* saturation can occur here Q14 -> Q15 */
470 : /* saturation takes care of "if (pit_sharp > 1.0) { pit_sharp=1.0; }" */
471 0 : IF( GT_16( pit_sharp, 16384 /*0.5.Q15*/ ) )
472 : {
473 0 : tmp16 = mult( pit_sharp, 8192 /*0.25.Q15*/ );
474 0 : FOR( i = 0; i < L_SUBFR; i++ )
475 : {
476 : /* excp[i] = pt_exc2[i] * pit_sharp * 0.25 */
477 0 : excp[i] = mult_r( pt_exc2[i], tmp16 );
478 0 : move16();
479 : }
480 : }
481 : }
482 :
483 436537 : IF( EQ_16( L_frame, L_FRAME16k ) )
484 : {
485 : /* tmp = 0.150 * (1.0 + voice_fac) */
486 : /* 0.30=voiced, 0=unvoiced */
487 249485 : tmp = mac_r( 0x13333333L /*0.150.Q31*/, voice_fac, 4915 /*0.150.Q15*/ ); /*Q15 */
488 : }
489 : ELSE
490 : {
491 : /* tmp = 0.125 * (1.0 + voice_fac) */
492 : /* 0.25=voiced, 0=unvoiced */
493 187052 : tmp = mac_r( 0x10000000L /*0.125.Q31*/, voice_fac, 4096 /*0.125.Q15*/ ); /*Q15 */
494 : }
495 :
496 : /*-----------------------------------------------------------------
497 : * Do a simple noncasual "sharpening": effectively an FIR
498 : * filter with coefs [-tmp 1.0 -tmp] where tmp=0...0.25.
499 : * This is applied to code and add_fxed to exc2
500 : *-----------------------------------------------------------------*/
501 :
502 436537 : L_tmp1 = L_deposit_h( gain_code_hi ); // Q = 16 + Q_exc, gain_code
503 436537 : L_tmp2 = L_mult( tmp, gain_code_hi ); // Q = 16 + Q_exc, gain_code * temp
504 :
505 : /* pt_exc2[0] += code[0] - tmp * code[1] */
506 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)
507 436537 : w_temp = W_shl( w_temp, sc ); // Q = 32 + Q_exc
508 436537 : pt_exc2[0] = W_round32_s( W_msu_32_16( w_temp, MIN_32, pt_exc2[0] ) ); // Q = Q_exc
509 436537 : move16();
510 :
511 27501831 : FOR( i = 1; i < L_SUBFR - 1; i++ )
512 : {
513 : /* pt_exc2[i] += (code[i] - tmp * code[i-1] - tmp * code[i+1]) * gain_code */
514 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)
515 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)
516 27065294 : w_temp = W_shl( w_temp, sc ); // Q = 32 + Q_exc
517 27065294 : pt_exc2[i] = W_round32_s( W_msu_32_16( w_temp, MIN_32, pt_exc2[i] ) ); // Q = Q_exc
518 27065294 : move16();
519 : }
520 :
521 : /* pt_exc2[L_SUBFR-1] += code[L_SUBFR-1] - tmp * code[L_SUBFR-2] */
522 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)
523 436537 : w_temp = W_shl( w_temp, sc ); // Q = 32 + Q_exc
524 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
525 436537 : move16();
526 :
527 436537 : test();
528 436537 : test();
529 436537 : IF( Opt_AMR_WB && ( EQ_32( core_brate, ACELP_8k85 ) || EQ_32( core_brate, ACELP_6k60 ) ) )
530 : {
531 0 : IF( GT_16( pit_sharp, 16384 /*0.5.Q15*/ ) )
532 : {
533 0 : FOR( i = 0; i < L_SUBFR; i++ )
534 : {
535 : /* excp[i] += pt_exc2[i] */
536 0 : excp[i] = add_sat( excp[i], pt_exc2[i] );
537 0 : move16();
538 : }
539 0 : agc2_fx( pt_exc2, excp, L_SUBFR );
540 0 : Copy( excp, pt_exc2, L_SUBFR );
541 : }
542 : }
543 : }
544 442033 : }
545 :
546 : /*---------------------------------------------------------*
547 : * Enhancement of the excitation signal before synthesis
548 : *---------------------------------------------------------*/
549 :
550 6110 : Word16 E_UTIL_enhancer(
551 : Word16 voice_fac, /* i : subframe voicing estimation Q15 */
552 : Word16 stab_fac, /* i : LP filter stability measure Q15 */
553 : Word32 gain_code, /* i : innovative cb. gain 15Q16 */
554 : Word16 gain_inov, /* i : gain of the unscaled innovation Q11 */
555 : Word32 *gc_threshold, /* i/o: gain code threshold 15Q16 */
556 : Word16 *code, /* i/o: innovation(in: Q9) code_exp */
557 : Word16 *exc2, /* i/o: adapt. excitation/total exc. */
558 : Word16 gain_pit, /* i : Quantized pitch gain 1Q14 */
559 : Word32 *prev_gain_code, /* i/o: previous codebook gain 15Q16 */
560 : Word16 prev_gain_pit[], /* i/o: previous pitch gain, size=6 1Q14 */
561 : Word16 *prev_state, /* i/o: Phase dispersion algorithm memory Q0 */
562 : Word16 coder_type, /* i : coder type */
563 : Word16 cdk_index, /* i : */
564 : Word16 L_subfr, /* i : length of subframe */
565 : Word16 L_frame, /* i : frame size */
566 : Word16 Q_new )
567 : {
568 : Word16 disp_mode, i;
569 : Word16 tmp, fac, gain;
570 : Word32 L_tmp;
571 : Word16 code_exp, exc2_exp;
572 : Word16 max_cdk_index_uv;
573 :
574 6110 : move16();
575 6110 : code_exp = 15 - 9;
576 6110 : exc2_exp = sub( 15, Q_new );
577 6110 : gain_inov = shr( gain_inov, 1 );
578 : /*-----------------------------------------------------------------*
579 : * Phase dispersion to enhance noise at low bit rates
580 : *-----------------------------------------------------------------*/
581 :
582 6110 : max_cdk_index_uv = 10;
583 6110 : move16();
584 6110 : if ( EQ_16( L_frame, L_FRAME16k ) )
585 : {
586 6110 : max_cdk_index_uv = 14;
587 6110 : move16();
588 : }
589 6110 : disp_mode = 2; /* any=off */
590 6110 : move16();
591 6110 : test();
592 6110 : test();
593 6110 : test();
594 6110 : test();
595 6110 : IF( ( ( NE_16( coder_type, VOICED ) ) && ( LE_16( cdk_index, 2 ) ) ) || ( ( EQ_16( coder_type, UNVOICED ) ) && ( LE_16( cdk_index, max_cdk_index_uv ) ) ) )
596 : {
597 0 : disp_mode = 0; /* high */
598 0 : move16();
599 : }
600 6110 : ELSE IF( ( NE_16( coder_type, VOICED ) ) && ( LE_16( cdk_index, 7 ) ) )
601 : {
602 0 : disp_mode = 1; /* low */
603 0 : move16();
604 : }
605 :
606 6110 : phase_dispersion( gain_code, gain_pit, code, &code_exp, disp_mode, prev_gain_code, prev_gain_pit, prev_state, L_subfr );
607 :
608 : /*------------------------------------------------------------*
609 : * noise enhancer *
610 : * ~~~~~~~~~~~~~~ *
611 : * - Enhance excitation on noise. (modify gain of code) *
612 : * If signal is noisy and LPC filter is stable, move gain *
613 : * of code 1.5 dB toward gain of code threshold. *
614 : * This decrease by 3 dB noise energy variation. *
615 : *------------------------------------------------------------*/
616 6110 : fac = 0;
617 6110 : move16();
618 :
619 : /* if gain_code is computed function of energy, noise enhancer is by-passed.*/
620 : BASOP_SATURATE_WARNING_OFF_EVS
621 6110 : tmp = msu_r_sat( 1073741824l /*0.5f Q31*/, 16384 /*0.5f Q15*/, voice_fac ); /* 1=unvoiced, 0=voiced */
622 : BASOP_SATURATE_WARNING_ON_EVS
623 6110 : fac = mult_r( stab_fac, tmp ); /* fac in Q15 */
624 :
625 6110 : L_tmp = gain_code; /* L_tmp in 15Q16 */
626 6110 : move32();
627 :
628 6110 : IF( LT_32( L_tmp, *gc_threshold ) )
629 : {
630 3353 : L_tmp = L_shl( Mpy_32_32( L_tmp, 1277752832l /*1.19f/2.0f Q31*/ ), 1 );
631 3353 : L_tmp = L_min( L_tmp, *gc_threshold );
632 : }
633 : ELSE
634 : {
635 2757 : L_tmp = Mpy_32_32( L_tmp, 1804608000l /*1.0f/1.19f Q31*/ );
636 2757 : L_tmp = L_max( L_tmp, *gc_threshold );
637 : }
638 :
639 6110 : *gc_threshold = L_tmp; /* in 15Q16 */
640 6110 : move32();
641 :
642 : /* gain = ( (fac * L_tmp) + (gain_code - fac*gain_code) ) * gain_inov */
643 : /* exponent of L_tmp: 31-16 + 15-11 */
644 6110 : 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 );
645 :
646 : /* exponent gain: 31-16 + 15-11 - tmp */
647 6110 : tmp = norm_l( L_tmp );
648 :
649 : /* exponent of code: 31-16 + 15-11 - tmp + code_exp */
650 6110 : code_exp = sub( add( 31 - 16 + 15 - 11, code_exp ), tmp );
651 :
652 6110 : L_tmp = L_shl_sat( L_tmp, tmp );
653 6110 : gain = round_fx_sat( L_tmp );
654 :
655 397150 : FOR( i = 0; i < L_subfr; i++ )
656 : {
657 391040 : code[i] = mult_r( code[i], gain );
658 391040 : move16();
659 : }
660 :
661 : /*------------------------------------------------------------*
662 : * pitch enhancer *
663 : * ~~~~~~~~~~~~~~ *
664 : * - Enhance excitation on voice. (HP filtering of code) *
665 : * On voiced signal, filtering of code by a smooth fir HP *
666 : * filter to decrease energy of code in low frequency. *
667 : *------------------------------------------------------------*/
668 :
669 : /* exponent difference of code and exc2. +1 accounts for headroom required below. */
670 6110 : gain = add( sub( code_exp, exc2_exp ), 1 );
671 :
672 6110 : tmp = mac_r( 268435456l /*0.125f Q31*/, 4096 /*0.125f Q15*/, voice_fac ); /* 0.25=voiced, 0=unvoiced */
673 6110 : IF( EQ_16( L_frame, L_FRAME16k ) )
674 : {
675 6110 : tmp = mac_r( 322122560l /*0.150f Q31*/, 4915 /*0.150f Q15*/, voice_fac ); /* 0.30=voiced, 0=unvoiced */
676 : }
677 :
678 : /* exc2[0] = exc2[0] + code[0] - tmp*code[1]; */
679 6110 : L_tmp = L_mult( code[0], 16384 );
680 6110 : L_tmp = L_msu0( L_tmp, tmp, code[1] );
681 6110 : IF( gain )
682 : {
683 5961 : L_tmp = L_shl_sat( L_tmp, gain );
684 : }
685 6110 : exc2[0] = msu_r_sat( L_tmp, -32768, exc2[0] );
686 6110 : move16();
687 :
688 384930 : FOR( i = 1; i < L_subfr - 1; i++ )
689 : {
690 : /* exc2[i] = exc2[i] + code[i] - tmp*(code[i+1]+code[i-1]); */
691 378820 : L_tmp = L_mult( code[i], 16384 );
692 378820 : L_tmp = L_msu0_sat( L_tmp, tmp, code[i - 1] );
693 378820 : L_tmp = L_msu0_sat( L_tmp, tmp, code[i + 1] );
694 378820 : IF( gain )
695 : {
696 369582 : L_tmp = L_shl_sat( L_tmp, gain );
697 : }
698 378820 : exc2[i] = msu_r_sat( L_tmp, -32768, exc2[i] );
699 378820 : move16();
700 : }
701 : /* exc2[L_subfr-1] = exc2[L_subfr-1] + code[L_subfr-1] - tmp*code[L_subfr-2]; */
702 6110 : L_tmp = L_mult( code[i], 16384 );
703 6110 : L_tmp = L_msu0_sat( L_tmp, tmp, code[i - 1] );
704 6110 : IF( gain )
705 : {
706 5961 : L_tmp = L_shl_sat( L_tmp, gain );
707 : }
708 6110 : exc2[i] = msu_r_sat( L_tmp, -32768, exc2[i] );
709 6110 : move16();
710 :
711 6110 : return code_exp;
712 : }
713 :
714 :
715 : /*-----------------------------------------------------------------------*
716 : * Phase_dispersion:
717 : *
718 : * post-processing to enhance noise in low bit rate.
719 : *-----------------------------------------------------------------------*/
720 : /*======================================================================================*/
721 : /* FUNCTION : phase_dispersion_fx() */
722 : /*--------------------------------------------------------------------------------------*/
723 : /* PURPOSE : post-processing to enhance noise in low bit rate. */
724 : /*--------------------------------------------------------------------------------------*/
725 : /* INPUT ARGUMENTS : */
726 : /* _ (Word32) gain_code : gain of code Q16 */
727 : /* _ (Word16) gain_pit : gain of pitch Q14 */
728 : /* _ (Word16) mode : level, 0=hi, 1=lo, 2=off */
729 : /*--------------------------------------------------------------------------------------*/
730 : /* OUTPUT ARGUMENTS : */
731 : /* _ None */
732 : /*--------------------------------------------------------------------------------------*/
733 : /* INPUT/OUTPUT ARGUMENTS : */
734 : /* _ (Word16[]) code : code vector (Q12) */
735 : /* _ (struct dispMem_fx*) dm_fx : static memory (size = 8) */
736 : /* (a[0]->Q0,a[1]->Q16,a[2-7]->Q14) */
737 : /*--------------------------------------------------------------------------------------*/
738 :
739 : /* _ None */
740 : /*--------------------------------------------------------------------------------------*/
741 : /* RETURN ARGUMENTS : */
742 : /* _ None */
743 : /*======================================================================================*/
744 497596 : static void phase_dispersion_fx(
745 : Word32 gain_code, /* i : gain of code Q16 */
746 : Word16 gain_pit, /* i : gain of pitch Q14 */
747 : Word16 code[], /* i/o: code vector */
748 : Word16 mode, /* i : level, 0=hi, 1=lo, 2=off */
749 : struct dispMem_fx *dm_fx /* i/o: static memory (size = 8) */
750 : )
751 : {
752 : Word16 i, j, state;
753 : Word16 *prev_gain_pit, *prev_state;
754 : Word32 *prev_gain_code;
755 : Word16 *code2_real, *code2_imag;
756 : Word16 *code_real, *code_imag;
757 : const Word16 *h_real, *h_imag;
758 :
759 : Word16 code2[2 * L_SUBFR];
760 :
761 497596 : prev_state = &( dm_fx->prev_state );
762 497596 : prev_gain_code = &( dm_fx->prev_gain_code );
763 497596 : prev_gain_pit = dm_fx->prev_gain_pit;
764 :
765 497596 : state = 2;
766 497596 : move16();
767 497596 : if ( LT_16( gain_pit, pitch_0_9 ) )
768 : {
769 358600 : state = 1;
770 358600 : move16();
771 : }
772 :
773 497596 : if ( LT_16( gain_pit, pitch_0_6 ) )
774 : {
775 196962 : state = 0;
776 196962 : move16();
777 : }
778 :
779 2985576 : FOR( i = 5; i > 0; i-- )
780 : {
781 2487980 : prev_gain_pit[i] = prev_gain_pit[i - 1];
782 2487980 : move16();
783 : }
784 497596 : prev_gain_pit[0] = gain_pit;
785 497596 : move16();
786 :
787 497596 : IF( GT_32( L_sub_sat( gain_code, *prev_gain_code ), L_shl_sat( *prev_gain_code, 1 ) ) )
788 : {
789 15275 : state = s_min( add( state, 1 ), 2 );
790 : }
791 : ELSE
792 : {
793 482321 : j = 0;
794 482321 : move16();
795 :
796 3376247 : FOR( i = 0; i < 6; i++ )
797 : {
798 2893926 : j = sub( j, shr( sub( prev_gain_pit[i], pitch_0_6 ), 15 ) );
799 : }
800 :
801 482321 : if ( GT_16( j, 2 ) )
802 : {
803 230091 : state = 0;
804 230091 : move16();
805 : }
806 :
807 482321 : if ( GT_16( sub( state, *prev_state ), 1 ) )
808 : {
809 18181 : state = sub( state, 1 );
810 : }
811 : }
812 :
813 497596 : *prev_gain_code = gain_code;
814 497596 : move32();
815 497596 : *prev_state = state;
816 497596 : move16();
817 :
818 : /*-----------------------------------------------------------------*
819 : * circular convolution
820 : *-----------------------------------------------------------------*/
821 :
822 497596 : state = add( state, mode ); /* level of dispersion */
823 :
824 497596 : IF( LT_16( state, 2 ) )
825 : {
826 31129 : r_fft_fx_lc( phs_tbl_dec, SIZE, SIZE2, NUM_STAGES, code, code2, 1 );
827 :
828 31129 : h_real = Mid_H_phasedisp;
829 31129 : if ( state == 0 )
830 : {
831 7416 : h_real = Low_H_phasedisp;
832 : }
833 :
834 : /* FFT Coefs are in code2 */
835 31129 : code2_real = code2;
836 31129 : code2_imag = code2 + L_SUBFR - 1;
837 :
838 31129 : code_real = code;
839 31129 : code_imag = code + L_SUBFR - 1;
840 :
841 31129 : h_imag = h_real + L_SUBFR - 1;
842 :
843 31129 : *code_real++ = mult( *code2_real++, *h_real++ );
844 31129 : move16(); /* DC */
845 :
846 996128 : FOR( i = 1; i < L_SUBFR / 2; i++ )
847 : {
848 964999 : *code_real++ = msu_r( L_mult( *code2_real, *h_real ), *code2_imag, *h_imag );
849 964999 : move16();
850 964999 : *code_imag-- = mac_r( L_mult( *code2_real, *h_imag ), *code2_imag, *h_real );
851 964999 : move16();
852 :
853 964999 : code2_real++;
854 964999 : h_imag--;
855 964999 : h_real++;
856 964999 : code2_imag--;
857 : }
858 31129 : *code_real++ = mult( *code2_real++, *h_real++ );
859 31129 : move16(); /* DC */
860 :
861 31129 : r_fft_fx_lc( phs_tbl_dec, SIZE, SIZE2, NUM_STAGES, code, code2, 0 );
862 :
863 2023385 : FOR( i = 0; i < L_SUBFR; i++ )
864 : {
865 : /* saturation can occur here */
866 1992256 : code[i] = shl( code2[i], 1 ); /*Q12 */
867 1992256 : move16();
868 : }
869 : }
870 497596 : }
871 :
872 : /*======================================================================================*/
873 : /* FUNCTION : agc2_fx() */
874 : /*--------------------------------------------------------------------------------------*/
875 : /* PURPOSE : AGC post-processing for lower G722.2 modes */
876 : /*--------------------------------------------------------------------------------------*/
877 : /* INPUT ARGUMENTS : */
878 : /* _ (Word16*[]) sig_in : postfilter input signal (Q0) */
879 : /* _ (Word16) l_trm : subframe size */
880 : /*--------------------------------------------------------------------------------------*/
881 : /* OUTPUT ARGUMENTS : */
882 : /* _ None */
883 : /*--------------------------------------------------------------------------------------*/
884 : /* INPUT/OUTPUT ARGUMENTS : */
885 : /* _ (Word16*[]) sig_out : postfilter output signal (Q0) */
886 : /*--------------------------------------------------------------------------------------*/
887 :
888 : /* _ None */
889 : /*--------------------------------------------------------------------------------------*/
890 : /* RETURN ARGUMENTS : */
891 : /* _ None */
892 : /*======================================================================================*/
893 0 : static void agc2_fx(
894 : const Word16 *sig_in, /* i : postfilter input signal */
895 : Word16 *sig_out, /* i/o: postfilter output signal */
896 : const Word16 l_trm /* i : subframe size */
897 : )
898 : {
899 :
900 : Word16 i, exp;
901 : Word16 gain_in, gain_out, g0;
902 : Word32 s;
903 :
904 : Word16 temp;
905 :
906 : /* calculate gain_out with exponent */
907 0 : temp = shr( sig_out[0], 2 );
908 0 : s = L_mult0( temp, temp );
909 0 : FOR( i = 1; i < l_trm; i++ )
910 : {
911 0 : temp = shr( sig_out[i], 2 );
912 0 : s = L_mac0_sat( s, temp, temp );
913 : }
914 0 : IF( s != 0 )
915 : {
916 0 : exp = sub( norm_l( s ), 1 );
917 0 : gain_out = round_fx( L_shl( s, exp ) );
918 :
919 : /* calculate gain_in with exponent */
920 0 : temp = shr( sig_in[0], 2 );
921 0 : s = L_mult0( temp, temp );
922 0 : FOR( i = 1; i < l_trm; i++ )
923 : {
924 0 : temp = shr( sig_in[i], 2 );
925 0 : s = L_mac0_sat( s, temp, temp );
926 : }
927 :
928 0 : g0 = 0;
929 0 : move16();
930 0 : IF( s != 0 )
931 : {
932 0 : i = norm_l( s );
933 0 : gain_in = round_fx_sat( L_shl_sat( s, i ) );
934 0 : exp = sub( exp, i );
935 :
936 : /*---------------------------------------------------*
937 : * g0 = sqrt(gain_in / gain_out)
938 : *---------------------------------------------------*/
939 0 : s = L_mult0( 128, div_s( gain_out, gain_in ) ); /* s = gain_out / gain_in */
940 0 : s = L_shr( s, exp ); /* add exponent */
941 :
942 0 : s = Isqrt( s );
943 0 : g0 = round_fx_sat( L_shl_sat( s, 9 ) );
944 : }
945 :
946 : /* sig_out(n) = gain(n) sig_out(n) */
947 0 : FOR( i = 0; i < l_trm; i++ )
948 : {
949 0 : sig_out[i] = round_fx_sat( L_shl_sat( L_mac( -8192, sig_out[i], g0 ), 2 ) );
950 0 : move16();
951 : }
952 : }
953 0 : }
|