Line data Source code
1 : /*====================================================================================
2 : EVS Codec 3GPP TS26.452 Aug 12, 2021. Version 16.3.0
3 : ====================================================================================*/
4 :
5 :
6 : #include <stdint.h>
7 : #include "options.h"
8 : #include "basop_util.h"
9 : #include "vad_basop.h"
10 : //#include "prot_fx.h"
11 : #include "rom_enc.h"
12 : #include "prot_fx.h" /* Function prototypes */
13 : #include "prot_fx_enc.h" /* Function prototypes */
14 :
15 : /*---------------------------------------------------------------------*
16 : * Local
17 : *---------------------------------------------------------------------*/
18 : #define RE( A ) A.r
19 : #define IM( A ) A.i
20 :
21 : typedef struct
22 : {
23 : complex_16 work[32];
24 : complex_16 const *tab;
25 : } cfft_info_16;
26 : /*-------------------------------------------------------------------*
27 : * ComplexMult_16()
28 : *
29 : *-------------------------------------------------------------------*/
30 496000 : static void ComplexMult_16(
31 : Word16 *y1,
32 : Word16 *y2,
33 : const Word16 x1,
34 : const Word16 x2,
35 : const Word16 c1,
36 : const Word16 c2 )
37 : {
38 496000 : *y1 = add( mult( x1, c1 ), mult( x2, c2 ) );
39 496000 : move16();
40 496000 : *y2 = sub( mult( x2, c1 ), mult( x1, c2 ) );
41 496000 : move16();
42 496000 : }
43 : /*-------------------------------------------------------------------*
44 : * ffr_getSfWord32()
45 : *
46 : *-------------------------------------------------------------------*/
47 24800 : Word16 ffr_getSfWord32(
48 : const Word32 *vector, /*!< Pointer to input vector */
49 : const Word16 len /*!< Length of input vector */
50 : )
51 : {
52 : Word32 maxVal;
53 : Word16 i;
54 : Word16 resu;
55 :
56 :
57 24800 : maxVal = 0;
58 24800 : move32();
59 254200 : FOR( i = 0; i < len; i++ )
60 : {
61 229400 : maxVal = L_max( maxVal, L_abs( vector[i] ) );
62 : }
63 :
64 24800 : resu = 31;
65 24800 : move16();
66 24800 : if ( maxVal )
67 : {
68 24707 : resu = norm_l( maxVal );
69 : }
70 :
71 24800 : return resu;
72 : }
73 : /*-------------------------------------------------------------------*
74 : * cgetpreSfWord16()
75 : *
76 : *-------------------------------------------------------------------*/
77 :
78 93000 : static void cgetpreSfWord16(
79 : Word16 *vector, /*!< Pointer to input vector */
80 : const Word16 len,
81 : const Word16 preshr,
82 : Word16 *num )
83 : {
84 : Word16 i;
85 :
86 :
87 93000 : *num = sub( *num, preshr );
88 93000 : move16();
89 3069000 : FOR( i = 0; i < len; i++ )
90 : {
91 2976000 : vector[i] = shr( vector[i], preshr );
92 2976000 : move16();
93 : }
94 93000 : }
95 : /*-------------------------------------------------------------------*
96 : * passf4_1_16()
97 : *
98 : *-------------------------------------------------------------------*/
99 :
100 31000 : static void passf4_1_16(
101 : const cmplx_s *cc,
102 : cmplx_s *ch,
103 : const cmplx_s *wa1,
104 : const cmplx_s *wa2,
105 : const cmplx_s *wa3 )
106 : {
107 : UWord16 i;
108 :
109 :
110 155000 : FOR( i = 0; i < 4; i++ )
111 : {
112 : cmplx_s c2, c3, c4, t1, t2, t3, t4;
113 :
114 124000 : t2 = C_add( cc[i], cc[i + 8] );
115 124000 : t1 = C_sub( cc[i], cc[i + 8] );
116 124000 : t3 = C_add( cc[i + 4], cc[i + 12] );
117 124000 : t4 = C_sub( cc[i + 4], cc[i + 12] );
118 124000 : t4 = C_mul_j( t4 );
119 :
120 124000 : c2 = C_add( t1, t4 );
121 124000 : c4 = C_sub( t1, t4 );
122 124000 : ch[i] = C_add( t2, t3 );
123 124000 : c3 = C_sub( t2, t3 );
124 :
125 124000 : ch[i + 4] = C_multr( c2, wa1[i] );
126 124000 : ch[i + 8] = C_multr( c3, wa2[i] );
127 124000 : ch[i + 12] = C_multr( c4, wa3[i] );
128 : #ifdef WMOPS
129 : multiCounter[currCounter].CL_move += 4;
130 : #endif
131 : }
132 31000 : }
133 : /*-------------------------------------------------------------------*
134 : * passf4_2_16()
135 : *
136 : *-------------------------------------------------------------------*/
137 31000 : static void passf4_2_16(
138 : const cmplx_s *cc,
139 : cmplx_s *ch )
140 : {
141 :
142 : Word16 k;
143 :
144 :
145 155000 : FOR( k = 0; k < 4; k++ )
146 : {
147 : cmplx_s t1, t2, t3, t4;
148 :
149 124000 : t2 = C_add( cc[4 * k], cc[4 * k + 2] );
150 124000 : t1 = C_sub( cc[4 * k], cc[4 * k + 2] );
151 124000 : t3 = C_add( cc[4 * k + 3], cc[4 * k + 1] );
152 124000 : t4 = C_sub( cc[4 * k + 1], cc[4 * k + 3] );
153 124000 : t4 = C_mul_j( t4 );
154 :
155 :
156 124000 : ch[k] = C_add( t2, t3 );
157 124000 : ch[k + 8] = C_sub( t2, t3 );
158 124000 : ch[k + 4] = C_add( t1, t4 );
159 124000 : ch[k + 12] = C_sub( t1, t4 );
160 : #ifdef WMOPS
161 : multiCounter[currCounter].CL_move += 4;
162 : #endif
163 : }
164 31000 : }
165 :
166 : /*-------------------------------------------------------------------*
167 : * cfftf_16()
168 : *
169 : *-------------------------------------------------------------------*/
170 31000 : static void cfftf_16(
171 : Word16 *scale,
172 : complex_16 *c,
173 : complex_16 *ch,
174 : const complex_16 *wa )
175 : {
176 :
177 31000 : cgetpreSfWord16( (Word16 *) c, 32, 3, scale );
178 31000 : passf4_1_16( (const cmplx_s *) c, (cmplx_s *) ch, (const cmplx_s *) &wa[0], (const cmplx_s *) &wa[4], (const cmplx_s *) &wa[8] );
179 31000 : cgetpreSfWord16( (Word16 *) ch, 32, 2, scale );
180 31000 : passf4_2_16( (const cmplx_s *) ch, (cmplx_s *) c );
181 31000 : }
182 : /*-------------------------------------------------------------------*
183 : * fft16_fix_4_16()
184 : *
185 : *-------------------------------------------------------------------*/
186 15500 : static void fft16_fix_4_16(
187 : Word32 **Sr,
188 : Word32 **Si,
189 : const Word32 Offset,
190 : const Word16 i,
191 : cfft_info_16 cfft,
192 : Word16 in_specamp_Q,
193 : const Word16 tmpQ,
194 : Word32 *spec_amp )
195 : {
196 : Word32 n;
197 :
198 : Word32 tmpr, tmpi, ptmpn, ptmp15_n, tmpspec;
199 : Word16 specamp_Q, tmpr_16, tmpi_16;
200 : Word16 resu, scalefactor1;
201 : complex_16 f_int2[16];
202 15500 : Word16 *count2 = &resu;
203 : Word16 Sr16, Si16;
204 : Word32 maxVal;
205 :
206 :
207 15500 : maxVal = L_deposit_l( 0 );
208 263500 : FOR( n = 0; n < 16; n++ )
209 : {
210 248000 : maxVal = L_max( maxVal, L_abs( Sr[Offset + n][i] ) );
211 248000 : maxVal = L_max( maxVal, L_abs( Si[Offset + n][i] ) );
212 : }
213 :
214 15500 : resu = 30;
215 15500 : move16();
216 15500 : IF( maxVal )
217 : {
218 15500 : resu = sub( norm_l( maxVal ), 1 );
219 : }
220 :
221 263500 : FOR( n = 0; n < 16; n++ )
222 : {
223 248000 : Sr16 = round_fx( L_shl( Sr[Offset + n][i], resu ) );
224 248000 : Si16 = round_fx( L_shl( Si[Offset + n][i], resu ) );
225 248000 : ComplexMult_16( &IM( f_int2[n] ), &RE( f_int2[n] ), Si16, Sr16, RE( M_in_fix16[n] ), IM( M_in_fix16[n] ) ); /*q+16*/
226 : }
227 :
228 15500 : cfftf_16( count2, f_int2, cfft.work, (const complex_16 *) cfft.tab );
229 15500 : cgetpreSfWord16( (Word16 *) f_int2, 32, 1, count2 );
230 15500 : scalefactor1 = add( *count2, DATAFFT_Q );
231 :
232 15500 : in_specamp_Q = add( in_specamp_Q, shl( scalefactor1, 1 ) );
233 :
234 139500 : FOR( n = 0; n < 8; n++ )
235 : {
236 124000 : tmpi = L_mac( L_mult( IM( f_int2[n] ), M_Wr_fix16[n] ), RE( f_int2[n] ), M_Wi_fix16[n] );
237 124000 : tmpr = L_msu( L_mult( RE( f_int2[n] ), M_Wr_fix16[n] ), IM( f_int2[n] ), M_Wi_fix16[n] );
238 124000 : tmpi_16 = extract_h( tmpi );
239 124000 : tmpr_16 = extract_h( tmpr );
240 :
241 124000 : ptmpn = L_mac0( L_mult0( tmpi_16, tmpi_16 ), tmpr_16, tmpr_16 );
242 :
243 124000 : tmpi = L_mac( L_mult( IM( f_int2[15 - n] ), M_Wr_fix16[15 - n] ), RE( f_int2[15 - n] ), M_Wi_fix16[15 - n] );
244 124000 : tmpr = L_msu( L_mult( RE( f_int2[15 - n] ), M_Wr_fix16[15 - n] ), IM( f_int2[15 - n] ), M_Wi_fix16[15 - n] );
245 124000 : tmpi_16 = extract_h( tmpi );
246 124000 : tmpr_16 = extract_h( tmpr );
247 :
248 124000 : ptmp15_n = L_add( ( L_mult0( tmpi_16, tmpi_16 ) ), ( L_mult0( tmpr_16, tmpr_16 ) ) );
249 124000 : tmpspec = L_add( ptmpn, ptmp15_n );
250 :
251 124000 : tmpspec = fft_vad_Sqrt_l( tmpspec, in_specamp_Q, &specamp_Q );
252 124000 : spec_amp[i * 8 + n] = L_shr( tmpspec, limitScale32( sub( specamp_Q, tmpQ ) ) );
253 124000 : move32();
254 : }
255 15500 : }
256 : /*-------------------------------------------------------------------*
257 : * fft16_fix_5_16()
258 : *
259 : *-------------------------------------------------------------------*/
260 15500 : static void fft16_fix_5_16(
261 : Word32 **Sr,
262 : Word32 **Si,
263 : const Word32 Offset,
264 : const Word16 i,
265 : cfft_info_16 cfft,
266 : Word16 in_specamp_Q,
267 : const Word16 tmpQ,
268 : Word32 *spec_amp )
269 : {
270 : Word32 n;
271 :
272 : Word32 tmpr, tmpi, ptmpn, ptmp15_n, tmpspec;
273 : Word16 specamp_Q, tmpr_16, tmpi_16;
274 :
275 : Word16 resu, scalefactor1;
276 : complex_16 f_int2[16];
277 15500 : Word16 *count2 = &resu;
278 : Word16 Sr16, Si16;
279 : Word32 maxVal;
280 :
281 :
282 15500 : maxVal = L_deposit_l( 0 );
283 263500 : FOR( n = 0; n < 16; n++ )
284 : {
285 248000 : maxVal = L_max( maxVal, L_abs( Sr[Offset + n][i] ) );
286 248000 : maxVal = L_max( maxVal, L_abs( Si[Offset + n][i] ) );
287 : }
288 :
289 15500 : resu = 30;
290 15500 : move16();
291 15500 : IF( maxVal )
292 : {
293 15500 : resu = sub( norm_l( maxVal ), 1 );
294 : }
295 :
296 263500 : FOR( n = 0; n < 16; n++ )
297 : {
298 248000 : Sr16 = round_fx( L_shl( Sr[Offset + n][i], resu ) );
299 248000 : Si16 = round_fx( L_shl( Si[Offset + n][i], resu ) );
300 248000 : ComplexMult_16( &IM( f_int2[n] ), &RE( f_int2[n] ), Si16, Sr16, RE( M_in_fix16[n] ), IM( M_in_fix16[n] ) ); /*q+16*/
301 : }
302 :
303 15500 : cfftf_16( count2, f_int2, cfft.work, (const complex_16 *) cfft.tab );
304 15500 : cgetpreSfWord16( (Word16 *) f_int2, 32, 1, count2 );
305 :
306 15500 : scalefactor1 = add( *count2, DATAFFT_Q );
307 :
308 15500 : in_specamp_Q = add( in_specamp_Q, shl( scalefactor1, 1 ) );
309 :
310 139500 : FOR( n = 0; n < 8; n++ )
311 : {
312 124000 : tmpi = L_mac( L_mult( IM( f_int2[n] ), M_Wr_fix16[n] ), RE( f_int2[n] ), M_Wi_fix16[n] );
313 124000 : tmpr = L_msu( L_mult( RE( f_int2[n] ), M_Wr_fix16[n] ), IM( f_int2[n] ), M_Wi_fix16[n] );
314 124000 : tmpi_16 = extract_h( tmpi );
315 124000 : tmpr_16 = extract_h( tmpr );
316 :
317 124000 : ptmpn = L_add( ( L_mult0( tmpi_16, tmpi_16 ) ), ( L_mult0( tmpr_16, tmpr_16 ) ) );
318 :
319 124000 : tmpi = L_mac( L_mult( IM( f_int2[15 - n] ), M_Wr_fix16[15 - n] ), RE( f_int2[15 - n] ), M_Wi_fix16[15 - n] );
320 124000 : tmpr = L_msu( L_mult( RE( f_int2[15 - n] ), M_Wr_fix16[15 - n] ), IM( f_int2[15 - n] ), M_Wi_fix16[15 - n] );
321 124000 : tmpi_16 = extract_h( tmpi );
322 124000 : tmpr_16 = extract_h( tmpr );
323 :
324 124000 : ptmp15_n = L_mac0( L_mult0( tmpi_16, tmpi_16 ), tmpr_16, tmpr_16 );
325 124000 : tmpspec = L_add( ptmpn, ptmp15_n );
326 :
327 124000 : tmpspec = fft_vad_Sqrt_l( tmpspec, in_specamp_Q, &specamp_Q );
328 124000 : spec_amp[i * 8 + 7 - n] = L_shr( tmpspec, limitScale32( sub( specamp_Q, tmpQ ) ) );
329 124000 : move32();
330 : }
331 15500 : }
332 :
333 3100 : void subband_FFT_fx(
334 : Word32 **Sr, /*(i) real part of the CLDFB*/
335 : Word32 **Si, /*(i) imag part of the CLDFB*/
336 : Word32 *spec_amp, /*(o) spectral amplitude*/
337 : Word32 Offset, /*(i) offset of the CLDFB*/
338 : Word16 *fftoQ /*(o) the Scaling */
339 : )
340 : {
341 : Word16 i;
342 : Word16 tmpQ, in_specamp_Q;
343 : cfft_info_16 cfft;
344 :
345 :
346 3100 : cfft.tab = wnk_table_16;
347 3100 : in_specamp_Q = shl( sub( *fftoQ, DATAFFT_Q ), 1 );
348 3100 : tmpQ = add( *fftoQ, 8 );
349 :
350 18600 : FOR( i = 0; i < 10; i = i + 2 )
351 : {
352 15500 : fft16_fix_4_16( Sr, Si, Offset, i, cfft, in_specamp_Q, tmpQ, spec_amp );
353 : }
354 :
355 18600 : FOR( i = 1; i < 10; i = i + 2 )
356 : {
357 15500 : fft16_fix_5_16( Sr, Si, Offset, i, cfft, in_specamp_Q, tmpQ, spec_amp );
358 : }
359 3100 : }
|