Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 :
6 : #include <assert.h>
7 : #include <stdint.h>
8 : #include "options.h"
9 : #include "basop_util.h"
10 : #include "vad_basop.h"
11 : //#include "prot_fx.h"
12 : #include "prot_fx.h" /* Function prototypes */
13 : #include "prot_fx_enc.h" /* Function prototypes */
14 :
15 : /*-------------------------------------------------------------------*
16 : * spec_flatness_fx()
17 : *
18 : *
19 : *-------------------------------------------------------------------*/
20 3100 : void spec_flatness_fx(
21 : Word32 *spec_amp, /* i : spectral amplitude*/
22 : Word32 smooth_spec_amp[], /* i : smoothed spectral amplitude*/
23 : Word16 sSFM[SFM_NUM] /* o : spectral flatness rate*/
24 : )
25 : {
26 : Word32 i;
27 : Word32 *smooth_spec_amp32;
28 : Word32 prods, prods_Exp;
29 : Word32 sums, prods_ExpM;
30 : Word32 zerop1;
31 :
32 : Word16 smooth_spec_amp16;
33 : Word16 Qnorm_prods, Qnorm_sums;
34 : Word16 SFM;
35 : Word16 prods_s, prods_Exps;
36 : Word16 prods_leadingzero, prods_Expleadingzero;
37 :
38 : Word16 leadingzero_prod, leadingzero_spec_amp;
39 : Word16 prods_Q_last, prods_ExpQ;
40 : Word16 SFM_Qtmp;
41 : Word16 prods_Q;
42 :
43 :
44 3100 : smooth_spec_amp32 = smooth_spec_amp;
45 3100 : zerop1 = 0;
46 3100 : move32();
47 3100 : prods_Q = 0;
48 3100 : move16();
49 189100 : FOR( i = MIN_AMP_ID; i <= MAX_AMP_ID; i++ )
50 : {
51 186000 : smooth_spec_amp32[i - MIN_AMP_ID] = L_add( MUL_F( smooth_spec_amp32[i - MIN_AMP_ID], 0x5999 ), MUL_F( spec_amp[i], 0x2666 ) );
52 186000 : move32();
53 : }
54 : /*sSFM1*/
55 3100 : sums = 0;
56 3100 : move32();
57 3100 : prods = 1;
58 3100 : move32();
59 3100 : prods_Q = 0;
60 3100 : move16();
61 :
62 :
63 49600 : FOR( i = ( 5 - MIN_AMP_ID ); i < ( 20 - MIN_AMP_ID ); i++ )
64 : {
65 46500 : sums = L_add( sums, smooth_spec_amp32[i] );
66 46500 : leadingzero_spec_amp = norm_l( smooth_spec_amp32[i] );
67 46500 : smooth_spec_amp16 = extract_h( L_shl( smooth_spec_amp32[i], leadingzero_spec_amp ) );
68 46500 : leadingzero_prod = norm_l( prods );
69 46500 : prods = L_shl( prods, leadingzero_prod );
70 46500 : prods_s = extract_h( prods );
71 46500 : prods = L_mult( prods_s, smooth_spec_amp16 );
72 46500 : prods_Q = add( add( prods_Q, leadingzero_spec_amp ), leadingzero_prod );
73 : }
74 3100 : prods_Q = sub( prods_Q, 255 );
75 :
76 3100 : prods_Q_last = prods_Q;
77 3100 : move16();
78 3100 : prods_ExpM = L_mult( prods_Q_last, -2184 );
79 :
80 3100 : prods = VAD_Pow( prods, 0x08888888, 0, 31, &prods_Q );
81 3100 : prods_Exp = VAD_Pow2( prods_ExpM, 16, &prods_ExpQ );
82 :
83 3100 : prods_leadingzero = norm_l( prods );
84 3100 : prods_Expleadingzero = norm_l( prods_Exp );
85 3100 : prods_s = extract_h( L_shl( prods, prods_leadingzero ) );
86 3100 : prods_Exps = extract_h( L_shl( prods_Exp, prods_Expleadingzero ) );
87 :
88 3100 : prods = L_mult( prods_s, prods_Exps );
89 3100 : prods_Q = add( prods_Q, prods_leadingzero );
90 3100 : prods_Q = add( prods_Q, prods_ExpQ );
91 3100 : prods_Q = add( prods_Q, prods_Expleadingzero );
92 3100 : prods_Q = sub( prods_Q, 31 );
93 :
94 3100 : prods = L_max( prods, 0 );
95 :
96 3100 : if ( prods <= 0 )
97 : {
98 0 : prods_Q = 34;
99 0 : move16();
100 : }
101 3100 : sums = MUL_F( sums, 0x0888 );
102 :
103 : /*+0.1 */
104 3100 : IF( GE_16( prods_Q, 34 ) )
105 : {
106 190 : prods = L_shr( prods, sub( prods_Q, 33 ) );
107 190 : zerop1 = CNT0P1 >> 1;
108 190 : move32();
109 190 : prods_Q = 33;
110 190 : move16();
111 : }
112 : ELSE
113 : {
114 2910 : prods_Q = sub( prods_Q, 1 );
115 2910 : prods = L_shr( prods, 1 );
116 2910 : zerop1 = L_shr( CNT0P1, sub( 34, prods_Q ) );
117 : }
118 3100 : prods = L_add( prods, zerop1 );
119 :
120 3100 : zerop1 = CNT0P1 >> 20;
121 3100 : move32();
122 3100 : sums = L_add( sums, zerop1 );
123 :
124 : /*div*/
125 3100 : Qnorm_prods = sub( norm_l( prods ), 1 );
126 3100 : Qnorm_sums = norm_l( sums );
127 3100 : prods = L_shl( prods, Qnorm_prods );
128 3100 : sums = L_shl( sums, Qnorm_sums );
129 :
130 3100 : SFM = div_l( prods, extract_h( sums ) );
131 :
132 3100 : SFM_Qtmp = add( prods_Q, Qnorm_prods );
133 3100 : SFM_Qtmp = sub( SFM_Qtmp, Qnorm_sums );
134 3100 : SFM_Qtmp = add( SFM_Qtmp, 15 );
135 3100 : SFM_Qtmp = sub( SFM_Qtmp, SPEC_AMP_Q );
136 3100 : SFM_Qtmp = sub( SFM_Qtmp, SFM_Q );
137 :
138 3100 : sSFM[0] = add_sat( mult( sSFM[0], 0x6ccc ), shr( mult( SFM, 0x1333 ), SFM_Qtmp ) );
139 3100 : move16();
140 :
141 : /*sSFM2*/
142 3100 : sums = 0;
143 3100 : move32();
144 3100 : prods = 1;
145 3100 : move32();
146 3100 : prods_Q = 0;
147 3100 : move16();
148 :
149 65100 : FOR( i = ( 20 - MIN_AMP_ID ); i < ( 40 - MIN_AMP_ID ); i++ )
150 : {
151 62000 : sums = L_add( sums, smooth_spec_amp32[i] );
152 62000 : leadingzero_spec_amp = norm_l( smooth_spec_amp32[i] );
153 62000 : smooth_spec_amp16 = extract_h( L_shl( smooth_spec_amp32[i], leadingzero_spec_amp ) );
154 62000 : leadingzero_prod = norm_l( prods );
155 62000 : prods = L_shl( prods, leadingzero_prod );
156 62000 : prods_s = extract_h( prods );
157 62000 : prods = L_mult( prods_s, smooth_spec_amp16 );
158 62000 : prods_Q = add( add( prods_Q, leadingzero_spec_amp ), leadingzero_prod );
159 : }
160 3100 : prods_Q = sub( prods_Q, 340 );
161 :
162 3100 : prods_Q_last = prods_Q;
163 3100 : move16();
164 3100 : prods_ExpM = L_mult( prods_Q_last, -1638 );
165 :
166 3100 : prods = VAD_Pow( prods, 0x06666666, 0, 31, &prods_Q );
167 3100 : prods_Exp = VAD_Pow2( prods_ExpM, 16, &prods_ExpQ );
168 :
169 3100 : prods_leadingzero = norm_l( prods );
170 3100 : prods_Expleadingzero = norm_l( prods_Exp );
171 3100 : prods_s = extract_h( L_shl( prods, prods_leadingzero ) );
172 3100 : prods_Exps = extract_h( L_shl( prods_Exp, prods_Expleadingzero ) );
173 :
174 3100 : prods = L_mult( prods_s, prods_Exps );
175 3100 : prods_Q = add( prods_Q, prods_leadingzero );
176 3100 : prods_Q = add( prods_Q, prods_ExpQ );
177 3100 : prods_Q = add( prods_Q, prods_Expleadingzero );
178 3100 : prods_Q = sub( prods_Q, 31 );
179 :
180 3100 : prods = L_max( prods, 0 );
181 :
182 3100 : if ( prods <= 0 )
183 : {
184 0 : prods_Q = 34;
185 0 : move16();
186 : }
187 3100 : sums = MUL_F( sums, 0x0666 );
188 :
189 : /*+0.1 */
190 3100 : IF( GE_16( prods_Q, 34 ) )
191 : {
192 461 : prods = L_shr( prods, sub( prods_Q, 33 ) );
193 461 : zerop1 = CNT0P1 >> 1;
194 461 : move32();
195 461 : prods_Q = 33;
196 461 : move16();
197 : }
198 : ELSE
199 : {
200 2639 : prods_Q = sub( prods_Q, 1 );
201 2639 : prods = L_shr( prods, 1 );
202 2639 : zerop1 = L_shr( CNT0P1, sub( 34, prods_Q ) );
203 : }
204 3100 : prods = L_add( prods, zerop1 );
205 :
206 3100 : zerop1 = CNT0P1 >> 20;
207 3100 : move32();
208 3100 : sums = L_add( sums, zerop1 );
209 :
210 : /*div*/
211 3100 : Qnorm_prods = sub( norm_l( prods ), 1 );
212 3100 : Qnorm_sums = norm_l( sums );
213 3100 : prods = L_shl( prods, Qnorm_prods );
214 3100 : sums = L_shl( sums, Qnorm_sums );
215 :
216 3100 : SFM = div_l( prods, extract_h( sums ) );
217 :
218 3100 : SFM_Qtmp = add( prods_Q, Qnorm_prods );
219 3100 : SFM_Qtmp = sub( SFM_Qtmp, Qnorm_sums );
220 3100 : SFM_Qtmp = add( SFM_Qtmp, 15 );
221 3100 : SFM_Qtmp = sub( SFM_Qtmp, SPEC_AMP_Q );
222 3100 : SFM_Qtmp = sub( SFM_Qtmp, SFM_Q );
223 :
224 3100 : sSFM[1] = add_sat( mult( sSFM[1], 0x6ccc ), shr( mult( SFM, 0x1333 ), SFM_Qtmp ) );
225 :
226 3100 : move16();
227 : /*sSFM3*/
228 3100 : sums = 0;
229 3100 : move32();
230 3100 : prods = 1;
231 3100 : move32();
232 3100 : prods_Q = 0;
233 3100 : move16();
234 :
235 80600 : FOR( i = ( 40 - MIN_AMP_ID ); i <= ( MAX_AMP_ID - MIN_AMP_ID ); i++ )
236 : {
237 77500 : sums = L_add( sums, smooth_spec_amp32[i] );
238 77500 : leadingzero_spec_amp = norm_l( smooth_spec_amp32[i] );
239 77500 : smooth_spec_amp16 = extract_h( L_shl( smooth_spec_amp32[i], leadingzero_spec_amp ) );
240 77500 : leadingzero_prod = norm_l( prods );
241 77500 : prods = L_shl( prods, leadingzero_prod );
242 77500 : prods_s = extract_h( prods );
243 77500 : prods = L_mult( prods_s, smooth_spec_amp16 );
244 77500 : prods_Q = add( add( prods_Q, leadingzero_spec_amp ), leadingzero_prod );
245 : }
246 3100 : prods_Q = sub( prods_Q, 425 );
247 :
248 3100 : prods_Q_last = prods_Q;
249 3100 : move16();
250 3100 : prods_ExpM = L_mult( prods_Q_last, -1310 );
251 :
252 3100 : prods = VAD_Pow( prods, 0x051eb851, 0, 31, &prods_Q );
253 3100 : prods_Exp = VAD_Pow2( prods_ExpM, 16, &prods_ExpQ );
254 :
255 3100 : prods_leadingzero = norm_l( prods );
256 3100 : prods_Expleadingzero = norm_l( prods_Exp );
257 3100 : prods_s = extract_h( L_shl( prods, prods_leadingzero ) );
258 3100 : prods_Exps = extract_h( L_shl( prods_Exp, prods_Expleadingzero ) );
259 :
260 3100 : prods = L_mult( prods_s, prods_Exps );
261 3100 : prods_Q = add( prods_Q, prods_leadingzero );
262 3100 : prods_Q = add( prods_Q, prods_ExpQ );
263 3100 : prods_Q = add( prods_Q, prods_Expleadingzero );
264 3100 : prods_Q = sub( prods_Q, 31 );
265 :
266 3100 : prods = L_max( prods, 0 );
267 3100 : if ( prods <= 0 )
268 : {
269 0 : prods_Q = 34;
270 0 : move16();
271 : }
272 :
273 3100 : sums = MUL_F( sums, 0x051e );
274 :
275 : /*+0.1 */
276 3100 : IF( GE_16( prods_Q, 34 ) )
277 : {
278 641 : prods = L_shr( prods, sub( prods_Q, 33 ) );
279 641 : zerop1 = CNT0P1 >> 1;
280 641 : move32();
281 641 : prods_Q = 33;
282 641 : move16();
283 : }
284 : ELSE
285 : {
286 2459 : prods_Q = sub( prods_Q, 1 );
287 2459 : prods = L_shr( prods, 1 );
288 2459 : zerop1 = L_shr( CNT0P1, sub( 34, prods_Q ) );
289 : }
290 3100 : prods = L_add( prods, zerop1 );
291 :
292 3100 : zerop1 = CNT0P1 >> 20;
293 3100 : move32();
294 3100 : sums = L_add( sums, zerop1 );
295 :
296 : /*div*/
297 3100 : Qnorm_prods = sub( norm_l( prods ), 1 );
298 3100 : Qnorm_sums = norm_l( sums );
299 3100 : prods = L_shl( prods, Qnorm_prods );
300 3100 : sums = L_shl( sums, Qnorm_sums );
301 :
302 3100 : SFM = div_l( prods, extract_h( sums ) );
303 :
304 3100 : SFM_Qtmp = add( prods_Q, Qnorm_prods );
305 3100 : SFM_Qtmp = sub( SFM_Qtmp, Qnorm_sums );
306 3100 : SFM_Qtmp = add( SFM_Qtmp, 15 );
307 3100 : SFM_Qtmp = sub( SFM_Qtmp, SPEC_AMP_Q );
308 3100 : SFM_Qtmp = sub( SFM_Qtmp, SFM_Q );
309 :
310 3100 : sSFM[2] = add_sat( mult( sSFM[2], 0x6ccc ), shr_sat( mult( SFM, 0x1333 ), SFM_Qtmp ) );
311 3100 : move16();
312 3100 : }
|