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"
8 : #include "stl.h"
9 : #include "prot_fx.h" /* Function prototypes */
10 : #include "prot_fx_enc.h" /* Function prototypes */
11 :
12 :
13 : /*-------------------------------------------------------------------*
14 : * long_enr_fx()
15 : *
16 : * Compute relative energy, long-term average total noise energy and total active speech energy
17 : *-------------------------------------------------------------------*/
18 1160968 : void ivas_long_enr_fx(
19 : Encoder_State *st_fx, /* i/o: state structure */
20 : const Word16 Etot, /* i : total channel E (see lib_enc\analy_sp.c) Q8 */
21 : const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover Q0*/
22 : Word16 high_lpn_flag, /* i : sp/mus LPN flag Q0*/
23 : FRONT_VAD_ENC_HANDLE hFrontVad[], /* i/o: front-VAD handles */
24 : const Word16 n_chan, /* i : number of channels Q0*/
25 : const Word16 localVAD_HE_SAD_LR[], /* i : HE-SAD flag without hangover LR channels Q0*/
26 : const Word16 Etot_LR[] /* i : total channel energy LR channels Q8 */
27 :
28 : )
29 : {
30 : Word16 tmp;
31 : Word16 alpha;
32 1160968 : NOISE_EST_HANDLE hNoiseEst = st_fx->hNoiseEst;
33 :
34 : /*-----------------------------------------------------------------*
35 : * Compute long term estimate of total noise energy
36 : * and total active speech energy
37 : *-----------------------------------------------------------------*/
38 : Word16 n;
39 1160968 : IF( hFrontVad != NULL )
40 : {
41 49758 : IF( LT_16( hFrontVad[0]->ini_frame, 4 ) )
42 : {
43 1644 : FOR( n = 0; n < n_chan; n++ )
44 : {
45 1004 : hFrontVad[n]->lp_noise_fx = hFrontVad[n]->hNoiseEst->totalNoise_fx; /* Q8 */
46 1004 : move16();
47 1004 : tmp = add( hFrontVad[n]->lp_noise_fx, 2560 ); /* Q8 */
48 :
49 1004 : if ( LT_16( hFrontVad[n]->lp_speech_fx, tmp ) )
50 : {
51 0 : hFrontVad[n]->lp_speech_fx = tmp; /* Q8 */
52 0 : move16();
53 : }
54 : }
55 : }
56 : ELSE
57 : {
58 : Word16 smooth_prev, smooth_curr;
59 :
60 49118 : IF( LT_16( hFrontVad[0]->ini_frame, 150 ) )
61 : {
62 15270 : smooth_prev = 31130; /* 0.95f in Q15 */
63 15270 : smooth_curr = 1638; /* 0.05f in Q15 */
64 15270 : move16();
65 15270 : move16();
66 : }
67 : ELSE
68 : {
69 33848 : smooth_prev = 32113; /* 0.98f in Q15 */
70 33848 : smooth_curr = 655; /* 0.02f in Q15 */
71 33848 : move16();
72 33848 : move16();
73 : }
74 :
75 129840 : FOR( n = 0; n < n_chan; n++ )
76 : {
77 80722 : hFrontVad[n]->lp_noise_fx = add( mult_r( smooth_prev, hFrontVad[n]->lp_noise_fx ), mult_r( smooth_curr, hFrontVad[n]->hNoiseEst->totalNoise_fx ) ); /* Q8 */
78 80722 : move16();
79 80722 : test();
80 80722 : IF( localVAD_HE_SAD_LR[n] && !high_lpn_flag )
81 : {
82 36000 : IF( LT_16( sub( hFrontVad[n]->lp_speech_fx, Etot_LR[n] ), 2560 /*10.0f in Q8*/ ) )
83 : {
84 24420 : hFrontVad[n]->lp_speech_fx = add( mult_r( 32113 /*0.98f in Q15*/, hFrontVad[n]->lp_speech_fx ), mult_r( 655 /*0.02f in Q15*/, Etot_LR[n] ) ); /* Q8 */
85 24420 : move16();
86 : }
87 : ELSE
88 : {
89 11580 : hFrontVad[n]->lp_speech_fx = sub( hFrontVad[n]->lp_speech_fx, 13 /*0.05f in Q8*/ ); /* Q8 */
90 11580 : move16();
91 : }
92 : }
93 : }
94 : }
95 131484 : FOR( n = 0; n < n_chan; n++ )
96 : {
97 81726 : hFrontVad[n]->hNoiseEst->Etot_last_32fx = L_deposit_h( Etot_LR[n] ); /* Q24 */
98 81726 : move16();
99 : }
100 : }
101 : ELSE
102 : {
103 1111210 : IF( LT_16( st_fx->ini_frame, 4 ) )
104 : {
105 31843 : st_fx->lp_noise_fx = hNoiseEst->totalNoise_fx; /* Q8 */
106 31843 : move16();
107 31843 : tmp = add( st_fx->lp_noise_fx, 2560 ); /*10.0 in Q8*/
108 31843 : st_fx->lp_speech_fx = s_max( st_fx->lp_speech_fx, tmp );
109 31843 : move16();
110 : }
111 : ELSE
112 : {
113 : /* if ( st->ini_frame < 150 ) {
114 : st->lp_noise = 0.95f * st->lp_noise + 0.05f * st->totalNoise;
115 : } else {
116 : st->lp_noise = 0.98f * st->lp_noise + 0.02f * st->totalNoise;
117 : } */
118 1079367 : alpha = 655; /* 0.02 Q15 */
119 1079367 : move16();
120 1079367 : if ( LT_16( st_fx->ini_frame, 150 ) ) /* should match HE_LT_CNT_INIT_FX */
121 : {
122 301691 : alpha = 1638;
123 301691 : move16(); /* 0.05 Q15 */
124 : }
125 1079367 : st_fx->lp_noise_fx = noise_est_AR1_Qx( hNoiseEst->totalNoise_fx, st_fx->lp_noise_fx, alpha ); /* Q8 state, alpha in Q15 */
126 1079367 : move16();
127 1079367 : test();
128 1079367 : IF( ( localVAD_HE_SAD != 0 ) && ( high_lpn_flag == 0 ) )
129 : {
130 815048 : IF( LT_16( sub( st_fx->lp_speech_fx, Etot ), 2560 ) ) /* 10.0 in Q8 */
131 : {
132 : /* st->lp_speech = 0.98f * st->lp_speech + 0.02f * Etot; */
133 638028 : st_fx->lp_speech_fx = noise_est_AR1_Qx( Etot, st_fx->lp_speech_fx, 655 ); /* Q8 state, 0.02 in Q15 */
134 638028 : move16();
135 : }
136 : ELSE
137 : {
138 177020 : st_fx->lp_speech_fx = sub( st_fx->lp_speech_fx, 13 ); /* st->lp_speech = st->lp_speech - 0.05f; linear decay*/
139 177020 : move16();
140 : }
141 : }
142 : }
143 : /* Update */
144 1111210 : st_fx->hNoiseEst->Etot_last_32fx = L_deposit_h( Etot ); /* Q24 */
145 1111210 : move16();
146 : }
147 :
148 : /*-----------------------------------------------------------------*
149 : * Initialize parameters for energy tracking and signal dynamics
150 : *-----------------------------------------------------------------*/
151 1160968 : return;
152 : }
153 :
154 :
155 3100 : void long_enr_fx(
156 : Encoder_State *st_fx, /* i/o: state structure */
157 : const Word16 Etot, /* i : total channel E (see lib_enc\analy_sp.c) Q8*/
158 : const Word16 localVAD_HE_SAD, /* i : HE-SAD flag without hangover Q0*/
159 : Word16 high_lpn_flag /* i : sp/mus LPN flag Q0*/
160 : )
161 : {
162 : Word16 tmp;
163 : Word16 alpha;
164 3100 : NOISE_EST_HANDLE hNoiseEst = st_fx->hNoiseEst;
165 :
166 : /*-----------------------------------------------------------------*
167 : * Compute long term estimate of total noise energy
168 : * and total active speech energy
169 : *-----------------------------------------------------------------*/
170 :
171 : {
172 3100 : IF( LT_16( st_fx->ini_frame, 4 ) )
173 : {
174 12 : st_fx->lp_noise_fx = hNoiseEst->totalNoise_fx; /* Q8 */
175 12 : move16();
176 12 : tmp = add( st_fx->lp_noise_fx, 2560 ); /*10.0 in Q8*/
177 12 : st_fx->lp_speech_fx = s_max( st_fx->lp_speech_fx, tmp ); /* Q8 */
178 12 : move16();
179 : }
180 : ELSE
181 : {
182 : /* if ( st->ini_frame < 150 ) {
183 : st->lp_noise = 0.95f * st->lp_noise + 0.05f * st->totalNoise;
184 : } else {
185 : st->lp_noise = 0.98f * st->lp_noise + 0.02f * st->totalNoise;
186 : } */
187 3088 : alpha = 655; /* 0.02 Q15 */
188 3088 : move16();
189 3088 : if ( LT_16( st_fx->ini_frame, 150 ) ) /* should match HE_LT_CNT_INIT_FX */
190 : {
191 438 : alpha = 1638; /* 0.05 Q15 */
192 438 : move16();
193 : }
194 3088 : st_fx->lp_noise_fx = noise_est_AR1_Qx( hNoiseEst->totalNoise_fx, st_fx->lp_noise_fx, alpha ); /* Q8 state, alpha in Q15 */
195 3088 : move16();
196 :
197 3088 : test();
198 3088 : IF( ( localVAD_HE_SAD != 0 ) && ( high_lpn_flag == 0 ) )
199 : {
200 2938 : IF( LT_16( sub( st_fx->lp_speech_fx, Etot ), 10 * 256 ) ) /* 10.0 in Q8 */
201 : {
202 : /* st->lp_speech = 0.98f * st->lp_speech + 0.02f * Etot; */
203 2083 : st_fx->lp_speech_fx = noise_est_AR1_Qx( Etot, st_fx->lp_speech_fx, 655 ); /* Q8 state, 0.02 in Q15 */
204 2083 : move16();
205 : }
206 : ELSE
207 : {
208 855 : st_fx->lp_speech_fx = sub( st_fx->lp_speech_fx, 13 ); /* st->lp_speech = st->lp_speech - 0.05f; linear decay*/
209 855 : move16();
210 : }
211 : }
212 : }
213 : }
214 :
215 : /*-----------------------------------------------------------------*
216 : * Initialize parameters for energy tracking and signal dynamics
217 : *-----------------------------------------------------------------*/
218 3100 : return;
219 : }
|