Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 : #include "options.h" /* Compilation switches */
6 : #include "cnst.h" /* Common constants */
7 : #include "rom_com.h" /* Static table prototypes */
8 : #include "prot_fx.h" /* Function prototypes */
9 : #include "stl.h"
10 :
11 : /*-------------------------------------------------------------------*
12 : * Local constants
13 : *-------------------------------------------------------------------*/
14 :
15 : #define ALPHA0_FX 13107 /*Q15*/
16 : #define BETA0_FX ( 32768 - ALPHA0_FX ) /*Q15*/
17 :
18 : /*========================================================================*/
19 : /* FUNCTION : Inac_swtch_ematch_fx() */
20 : /*------------------------------------------------------------------------*/
21 : /* PURPOSE : Apply energy matching when swithcing to INACTIVE frame coded */
22 : /* by the GSC technology */
23 : /*------------------------------------------------------------------------*/
24 : /* INPUT ARGUMENTS : */
25 : /* _ (Word16) coder_type : Coding mode */
26 : /* _ (Word16) L_frame : Frame lenght */
27 : /* _ (Word32) core_brate : core bitrate */
28 : /*------------------------------------------------------------------------*/
29 : /* INPUT/OUTPUT ARGUMENTS : */
30 : /* _ (Word16[]) exc2 : CELP/GSC excitation buffer Q_exc */
31 : /* _ (Word16[]) lt_ener_per_band : Long term energy per band Q12 */
32 : /* _ (Word16*) Q_exc : input and output format of exc2 */
33 : /*------------------------------------------------------------------------*/
34 : /* OUTPUT ARGUMENTS : */
35 : /*------------------------------------------------------------------------*/
36 : /*------------------------------------------------------------------------*/
37 : /* RETURN ARGUMENTS : */
38 : /* _ None */
39 : /*========================================================================*/
40 :
41 192056 : void Inac_switch_ematch_fx(
42 : Word16 exc2[], /* i/o: CELP/GSC excitation buffer Q_exc*/
43 : Word16 dct_exc_tmp[], /* i : GSC excitation in DCT domain */
44 : Word16 lt_ener_per_band[], /* i/o: Long term energy per band Q12 */
45 : const Word16 coder_type, /* i : Coding mode */
46 : const Word16 inactive_coder_type_flag, /* i : AVQ (0) or GSC (1) IC flag */
47 : const Word16 L_frame, /* i : Frame lenght */
48 : const Word16 Q_exc, /* i : input and output format of exc2 */
49 : const Word16 bfi, /* i : frame lost indicator */
50 : const Word16 last_core, /* i : Last core used */
51 : const Word16 last_codec_mode, /* i : Last codec mode */
52 : const Word16 tdm_low_rate_mode, /* i : secondary channel low rate mode flag */
53 : const Word16 element_mode /* i : element mode */
54 : )
55 : {
56 : Word16 Ener_per_bd[MBANDS_GN16k];
57 : Word16 ftmp;
58 : Word16 *pt_exc;
59 : Word16 j, i;
60 :
61 : Word16 exp, frac;
62 : Word32 L_tmp;
63 :
64 : /*--------------------------------------------------------------------------
65 : * average energy per band
66 : *--------------------------------------------------------------------------*/
67 :
68 192056 : test();
69 192056 : test();
70 192056 : test();
71 192056 : test();
72 192056 : test();
73 192056 : test();
74 192056 : test();
75 192056 : test();
76 192056 : test();
77 192056 : test();
78 192056 : IF( ( EQ_16( coder_type, AUDIO ) || ( EQ_16( coder_type, UNVOICED ) && EQ_16( tdm_low_rate_mode, 1 ) ) ) && bfi == 0 )
79 : {
80 13328 : Ener_per_band_comp_ivas_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1, L_frame );
81 :
82 : /* reset long-term energy per band */
83 226576 : FOR( i = 0; i < MBANDS_GN; i++ )
84 : {
85 213248 : lt_ener_per_band[i] = Ener_per_bd[i]; /*Q12*/
86 213248 : move16();
87 : }
88 : }
89 178728 : ELSE IF( EQ_16( coder_type, VOICED ) || EQ_16( coder_type, GENERIC ) || EQ_16( coder_type, TRANSITION ) || ( last_core != ACELP_CORE ) || NE_16( last_codec_mode, MODE1 ) || ( ( element_mode > EVS_MONO ) && EQ_16( coder_type, UNVOICED ) ) )
90 : {
91 : /* Find spectrum and energy per band for GC and VC frames */
92 164136 : edct_16fx( exc2, dct_exc_tmp, L_frame, 5, element_mode );
93 :
94 164136 : Ener_per_band_comp_ivas_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1, L_frame );
95 :
96 : /* reset long-term energy per band */
97 2790312 : FOR( i = 0; i < MBANDS_GN; i++ )
98 : {
99 2626176 : lt_ener_per_band[i] = Ener_per_bd[i]; /*Q12*/
100 2626176 : move16();
101 : }
102 : }
103 14592 : ELSE IF( ( coder_type == INACTIVE ) && inactive_coder_type_flag )
104 : {
105 : /* Find spectrum and energy per band for inactive frames */
106 11853 : edct_16fx( exc2, dct_exc_tmp, L_frame, 5, element_mode );
107 11853 : Ener_per_band_comp_ivas_fx( dct_exc_tmp, Ener_per_bd, Q_exc, MBANDS_GN, 1, L_frame );
108 :
109 : /* More agressive smoothing in the first 50 frames */
110 11853 : pt_exc = dct_exc_tmp;
111 11853 : move16();
112 201501 : FOR( i = 0; i < MBANDS_GN; i++ )
113 : {
114 : /* Compute smoothing gain to apply with gain limitation */
115 189648 : L_tmp = L_mult( ALPHA0_FX, lt_ener_per_band[i] ); /*Q(15+12+1)=Q(28) */
116 189648 : L_tmp = L_mac( L_tmp, BETA0_FX, Ener_per_bd[i] ); /*Q28 */
117 189648 : lt_ener_per_band[i] = round_fx( L_tmp ); /*Q12 */
118 189648 : move16();
119 :
120 189648 : ftmp = sub( lt_ener_per_band[i], Ener_per_bd[i] ); /*Q12 */
121 :
122 : /* ftmp = (float)pow(10, ftmp);= pow(2,3.321928*ftmp);*/
123 :
124 189648 : L_tmp = L_mult( 27213, ftmp ); /*Q(13+12+1)=Q26 ; 27213=3.321928 in Q13 */
125 189648 : L_tmp = L_shr( L_tmp, 10 ); /* From Q26 to Q16 */
126 189648 : frac = L_Extract_lc( L_tmp, &exp ); /* Extract exponent of ftmp */
127 189648 : ftmp = extract_l( Pow2( 14, frac ) ); /* Put 14 as exponent so that */
128 : /* output of Pow2() will be: */
129 : /* 16384 < Pow2() <= 32767 */
130 :
131 189648 : exp = sub( exp, 14 );
132 189648 : IF( LT_16( i, 2 ) )
133 : {
134 23706 : IF( EQ_16( element_mode, EVS_MONO ) )
135 : {
136 144 : FOR( j = 0; j < 8; j++ )
137 : {
138 128 : L_tmp = L_mult( *pt_exc, ftmp );
139 128 : L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc) -> Q(15+Q_exc)*/
140 128 : *pt_exc = round_fx_sat( L_tmp ); /*Q_exc - 1*/
141 128 : move16();
142 128 : pt_exc++;
143 : }
144 : }
145 : ELSE
146 : {
147 213210 : FOR( j = 0; j < 8; j++ )
148 : {
149 189520 : L_tmp = L_mult0( *pt_exc, ftmp );
150 189520 : L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc) -> Q(15+Q_exc)*/
151 189520 : *pt_exc = round_fx_sat( L_tmp ); /*Q_exc - 1*/
152 189520 : move16();
153 189520 : pt_exc++;
154 : }
155 : }
156 : }
157 : ELSE
158 : {
159 165942 : IF( EQ_16( element_mode, EVS_MONO ) )
160 : {
161 1904 : FOR( j = 0; j < 16; j++ )
162 : {
163 1792 : L_tmp = L_mult( *pt_exc, ftmp );
164 1792 : L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc) -> Q(15+Q_exc)*/
165 1792 : *pt_exc = round_fx_sat( L_tmp ); /*Q_exc - 1*/
166 1792 : move16();
167 1792 : pt_exc++;
168 : }
169 : }
170 : ELSE
171 : {
172 2819110 : FOR( j = 0; j < 16; j++ )
173 : {
174 2653280 : L_tmp = L_mult0( *pt_exc, ftmp );
175 2653280 : L_tmp = L_shl_sat( L_tmp, add( exp, 15 ) ); /* Q(Q_exc) -> Q(15+Q_exc)*/
176 2653280 : *pt_exc = round_fx_sat( L_tmp ); /*Q_exc - 1*/
177 2653280 : move16();
178 2653280 : pt_exc++;
179 : }
180 : }
181 : }
182 : }
183 :
184 : /* Going back to time */
185 11853 : IF( GT_16( element_mode, EVS_MONO ) )
186 : {
187 11845 : Scale_sig( dct_exc_tmp, 240, 1 ); // Q_exc
188 11845 : Scale_sig( exc2, 240, 1 ); // Q_exc
189 : }
190 11853 : edct_16fx( dct_exc_tmp, exc2, L_frame, 5, element_mode );
191 : }
192 :
193 192056 : return;
194 : }
|