Line data Source code
1 : /******************************************************************************
2 : * ETSI TS 103 634 V1.5.1 *
3 : * Low Complexity Communication Codec Plus (LC3plus) *
4 : * *
5 : * Copyright licence is solely granted through ETSI Intellectual Property *
6 : * Rights Policy, 3rd April 2019. No patent licence is granted by implication, *
7 : * estoppel or otherwise. *
8 : ******************************************************************************/
9 :
10 : /* guard against unindended includes */
11 : #ifndef INCLUDED_FROM_IISFFT_C
12 : #error "this file must not be included"
13 : #endif
14 :
15 0 : static void fft15(LC3_FLOAT* vec)
16 : {
17 : LC3_FLOAT r0, r1, r2, r3, r4, r5, r6, r7, r8, r9, r10, r11, r12, r13, r14, r15, r16, r17, i0, i1, i2, i3, i4, i5,
18 : i6, i7, i8, i9, i10, i11, i12, i13, i14, i15, i16, i17, tmp0, tmp1, tmp2, tmp3, tmp4, tmp5, tmp6, tmp7, tmp8,
19 : tmp9, tmp10, tmp11, tmp12, tmp13, tmp14, tmp15, tmp16, tmp17, tmp18, tmp19, tmp20, tmp21, tmp22, tmp23, tmp24,
20 : tmp25, tmp26, tmp27, tmp28, tmp29;
21 :
22 : /* Pre-additions real part */
23 0 : r1 = vec[2] + vec[8];
24 0 : r2 = vec[2] - vec[8];
25 0 : r3 = vec[4] + vec[16];
26 0 : r4 = vec[4] - vec[16];
27 0 : r5 = vec[6] + vec[24];
28 0 : r6 = vec[6] - vec[24];
29 0 : r7 = vec[10] + vec[20];
30 0 : r8 = vec[10] - vec[20];
31 0 : r9 = vec[12] + vec[18];
32 0 : r10 = vec[12] - vec[18];
33 0 : r11 = vec[14] + vec[26];
34 0 : r12 = vec[14] - vec[26];
35 0 : r13 = vec[22] + vec[28];
36 0 : r14 = vec[22] - vec[28];
37 :
38 0 : tmp2 = r1 + r3;
39 0 : tmp4 = r1 - r3;
40 0 : tmp6 = r2 + r14;
41 0 : tmp8 = r2 - r14;
42 0 : tmp10 = r4 + r12;
43 0 : tmp12 = r4 - r12;
44 0 : tmp14 = r5 + r9;
45 0 : tmp16 = r5 - r9;
46 0 : tmp18 = r11 + r13;
47 0 : tmp20 = r11 - r13;
48 :
49 : /* Pre-additions imaginary part */
50 0 : i1 = vec[3] + vec[9];
51 0 : i2 = vec[3] - vec[9];
52 0 : i3 = vec[5] + vec[17];
53 0 : i4 = vec[5] - vec[17];
54 0 : i5 = vec[7] + vec[25];
55 0 : i6 = vec[7] - vec[25];
56 0 : i7 = vec[11] + vec[21];
57 0 : i8 = vec[11] - vec[21];
58 0 : i9 = vec[13] + vec[19];
59 0 : i10 = vec[13] - vec[19];
60 0 : i11 = vec[15] + vec[27];
61 0 : i12 = vec[15] - vec[27];
62 0 : i13 = vec[23] + vec[29];
63 0 : i14 = vec[23] - vec[29];
64 :
65 0 : tmp3 = i1 + i3;
66 0 : tmp5 = i1 - i3;
67 0 : tmp7 = i2 + i14;
68 0 : tmp9 = i2 - i14;
69 0 : tmp11 = i4 + i12;
70 0 : tmp13 = i4 - i12;
71 0 : tmp15 = i5 + i9;
72 0 : tmp17 = i5 - i9;
73 0 : tmp19 = i11 + i13;
74 0 : tmp21 = i11 - i13;
75 :
76 : /* Pre-additions and core multiplications */
77 0 : tmp28 = tmp4 + tmp20;
78 0 : tmp29 = tmp5 + tmp21;
79 0 : r4 = tmp2 + tmp18;
80 0 : i4 = tmp3 + tmp19;
81 0 : r3 = (r4 + tmp14) * (LC3_FLOAT)-1.25;
82 0 : i3 = (i4 + tmp15) * (LC3_FLOAT)-1.25;
83 0 : r2 = (tmp29 - i8) * (LC3_FLOAT)-8.660254037844387e-1;
84 0 : i2 = (tmp28 - r8) * (LC3_FLOAT)8.660254037844387e-1;
85 0 : r1 = r4 + r7;
86 0 : i1 = i4 + i7;
87 0 : r0 = r1 + vec[0] + tmp14;
88 0 : i0 = i1 + vec[1] + tmp15;
89 0 : r7 = tmp4 - tmp20;
90 0 : i7 = tmp5 - tmp21;
91 0 : r8 = (tmp3 - tmp19) * (LC3_FLOAT)-4.841229182759272e-1;
92 0 : i8 = (tmp2 - tmp18) * (LC3_FLOAT)4.841229182759272e-1;
93 0 : tmp0 = tmp6 + r10;
94 0 : tmp1 = tmp7 + i10;
95 0 : tmp2 = r6 - tmp10;
96 0 : tmp3 = i6 - tmp11;
97 0 : r10 = tmp7 * (LC3_FLOAT)-2.308262652881440;
98 0 : i10 = tmp6 * (LC3_FLOAT)2.308262652881440;
99 0 : r11 = tmp8 * (LC3_FLOAT)1.332676064001459;
100 0 : i11 = tmp9 * (LC3_FLOAT)1.332676064001459;
101 0 : r6 = (r7 - tmp16) * (LC3_FLOAT)5.590169943749475e-1;
102 0 : i6 = (i7 - tmp17) * (LC3_FLOAT)5.590169943749475e-1;
103 0 : r12 = (tmp1 + tmp3) * (LC3_FLOAT)5.877852522924733e-1;
104 0 : i12 = (tmp0 + tmp2) * (LC3_FLOAT)-5.877852522924733e-1;
105 0 : r13 = (tmp7 - tmp11) * (LC3_FLOAT)-8.816778784387098e-1;
106 0 : i13 = (tmp6 - tmp10) * (LC3_FLOAT)8.816778784387098e-1;
107 0 : r14 = (tmp8 + tmp12) * (LC3_FLOAT)5.090369604551274e-1;
108 0 : i14 = (tmp9 + tmp13) * (LC3_FLOAT)5.090369604551274e-1;
109 0 : r16 = tmp11 * (LC3_FLOAT)5.449068960040204e-1;
110 0 : i16 = tmp10 * (LC3_FLOAT)-5.449068960040204e-1;
111 0 : r17 = tmp12 * (LC3_FLOAT)3.146021430912046e-1;
112 0 : i17 = tmp13 * (LC3_FLOAT)3.146021430912046e-1;
113 :
114 0 : r4 *= (LC3_FLOAT)1.875;
115 0 : i4 *= (LC3_FLOAT)1.875;
116 0 : r1 *= (LC3_FLOAT)-1.5;
117 0 : i1 *= (LC3_FLOAT)-1.5;
118 0 : r7 *= (LC3_FLOAT)-8.385254915624212e-1;
119 0 : i7 *= (LC3_FLOAT)-8.385254915624212e-1;
120 0 : r5 = tmp29 * (LC3_FLOAT)1.082531754730548;
121 0 : i5 = tmp28 * (LC3_FLOAT)-1.082531754730548;
122 0 : r9 = tmp1 * (LC3_FLOAT)1.538841768587627;
123 0 : i9 = tmp0 * (LC3_FLOAT)-1.538841768587627;
124 0 : r15 = tmp3 * (LC3_FLOAT)3.632712640026803e-1;
125 0 : i15 = tmp2 * (LC3_FLOAT)-3.632712640026803e-1;
126 :
127 : /* Post-additions real part */
128 0 : tmp2 = r0 + r1;
129 0 : tmp4 = r3 + r6;
130 0 : tmp6 = r3 - r6;
131 0 : tmp8 = r4 + r5;
132 0 : tmp10 = r4 - r5;
133 0 : tmp12 = r7 + r8;
134 0 : tmp14 = r7 - r8;
135 0 : tmp16 = r13 + r16;
136 0 : tmp18 = r14 + r17;
137 0 : tmp20 = r10 - r13;
138 0 : tmp22 = r11 - r14;
139 0 : tmp24 = r12 + r15;
140 0 : tmp26 = r12 - r9;
141 :
142 0 : r1 = tmp2 + r2;
143 0 : r2 = tmp2 - r2;
144 0 : r3 = tmp4 + tmp26;
145 0 : r4 = tmp4 - tmp26;
146 0 : r5 = tmp6 + tmp24;
147 0 : r6 = tmp6 - tmp24;
148 0 : r7 = tmp16 + tmp18;
149 0 : r8 = tmp16 - tmp18;
150 0 : r9 = tmp20 - tmp22;
151 0 : r10 = tmp20 + tmp22;
152 0 : r11 = r1 + tmp8;
153 0 : r12 = r2 + tmp10;
154 0 : r13 = r11 - tmp12;
155 0 : r14 = r12 - tmp14;
156 0 : r15 = r12 + tmp14;
157 0 : r16 = r11 + tmp12;
158 :
159 : /* Post-additions imaginary part */
160 0 : tmp3 = i0 + i1;
161 0 : tmp5 = i3 + i6;
162 0 : tmp7 = i3 - i6;
163 0 : tmp9 = i4 + i5;
164 0 : tmp11 = i4 - i5;
165 0 : tmp13 = i7 + i8;
166 0 : tmp15 = i7 - i8;
167 0 : tmp17 = i13 + i16;
168 0 : tmp19 = i14 + i17;
169 0 : tmp21 = i10 - i13;
170 0 : tmp23 = i11 - i14;
171 0 : tmp25 = i12 + i15;
172 0 : tmp27 = i12 - i9;
173 :
174 0 : i1 = tmp3 + i2;
175 0 : i2 = tmp3 - i2;
176 0 : i3 = tmp5 + tmp27;
177 0 : i4 = tmp5 - tmp27;
178 0 : i5 = tmp7 + tmp25;
179 0 : i6 = tmp7 - tmp25;
180 0 : i7 = tmp17 + tmp19;
181 0 : i8 = tmp17 - tmp19;
182 0 : i9 = tmp21 - tmp23;
183 0 : i10 = tmp21 + tmp23;
184 0 : i11 = i1 + tmp9;
185 0 : i12 = i2 + tmp11;
186 0 : i13 = i11 - tmp13;
187 0 : i14 = i12 - tmp15;
188 0 : i15 = i12 + tmp15;
189 0 : i16 = i11 + tmp13;
190 :
191 0 : *vec++ = r0;
192 0 : *vec++ = i0;
193 0 : *vec++ = r13 + r5 + r7;
194 0 : *vec++ = i13 + i5 + i7;
195 0 : *vec++ = r15 + r3 - r9;
196 0 : *vec++ = i15 + i3 - i9;
197 0 : *vec++ = r0 + r4;
198 0 : *vec++ = i0 + i4;
199 0 : *vec++ = r13 + r6 - r7;
200 0 : *vec++ = i13 + i6 - i7;
201 0 : *vec++ = r2;
202 0 : *vec++ = i2;
203 0 : *vec++ = r0 + r5;
204 0 : *vec++ = i0 + i5;
205 0 : *vec++ = r16 + r3 - r10;
206 0 : *vec++ = i16 + i3 - i10;
207 0 : *vec++ = r15 + r4 + r9;
208 0 : *vec++ = i15 + i4 + i9;
209 0 : *vec++ = r0 + r6;
210 0 : *vec++ = i0 + i6;
211 0 : *vec++ = r1;
212 0 : *vec++ = i1;
213 0 : *vec++ = r14 + r5 + r8;
214 0 : *vec++ = i14 + i5 + i8;
215 0 : *vec++ = r0 + r3;
216 0 : *vec++ = i0 + i3;
217 0 : *vec++ = r16 + r4 + r10;
218 0 : *vec++ = i16 + i4 + i10;
219 0 : *vec++ = r14 + r6 - r8;
220 0 : *vec++ = i14 + i6 - i8;
221 0 : }
222 :
223 0 : static void fft16(LC3_FLOAT* vec)
224 : {
225 0 : const LC3_FLOAT INV_SQRT2 = 7.071067811865475e-1;
226 0 : const LC3_FLOAT COS_PI_DIV8 = 9.238795325112867e-1;
227 0 : const LC3_FLOAT COS_3PI_DIV8 = 3.826834323650898e-1;
228 0 : const LC3_FLOAT SQRT2PLUS1 = 2.414213562373095;
229 0 : const LC3_FLOAT SQRT2MINUS1 = 4.142135623730952e-1;
230 :
231 : LC3_FLOAT temp10, temp11, temp12, temp13, temp14, temp15, temp16, temp17, temp18, temp19, temp110, temp111, temp112,
232 : temp113, temp114, temp115, temp20, temp21, temp22, temp23, temp24, temp25, temp26, temp27, temp28, temp29,
233 : temp210, temp211, temp212, temp213, temp214, temp215, vec0, vec1, vec2, vec3, vec4, vec5, vec6, vec7, vec8,
234 : vec9, vec10, vec11, vec12, vec13, vec14, vec15;
235 :
236 : /* even */
237 0 : vec0 = vec[0] + vec[16];
238 0 : vec1 = vec[1] + vec[17];
239 0 : vec2 = vec[2] + vec[18];
240 0 : vec3 = vec[3] + vec[19];
241 0 : vec4 = vec[4] + vec[20];
242 0 : vec5 = vec[5] + vec[21];
243 0 : vec6 = vec[6] + vec[22];
244 0 : vec7 = vec[7] + vec[23];
245 0 : vec8 = vec[8] + vec[24];
246 0 : vec9 = vec[9] + vec[25];
247 0 : vec10 = vec[10] + vec[26];
248 0 : vec11 = vec[11] + vec[27];
249 0 : vec12 = vec[12] + vec[28];
250 0 : vec13 = vec[13] + vec[29];
251 0 : vec14 = vec[14] + vec[30];
252 0 : vec15 = vec[15] + vec[31];
253 :
254 : /* Pre-additions */
255 0 : temp10 = vec0 + vec8;
256 0 : temp12 = vec0 - vec8;
257 0 : temp11 = vec1 + vec9;
258 0 : temp13 = vec1 - vec9;
259 0 : temp14 = vec2 + vec10;
260 0 : temp16 = vec2 - vec10;
261 0 : temp15 = vec3 + vec11;
262 0 : temp17 = vec3 - vec11;
263 0 : temp18 = vec4 + vec12;
264 0 : temp110 = vec4 - vec12;
265 0 : temp19 = vec5 + vec13;
266 0 : temp111 = vec5 - vec13;
267 0 : temp112 = vec6 + vec14;
268 0 : temp114 = vec6 - vec14;
269 0 : temp113 = vec7 + vec15;
270 0 : temp115 = vec7 - vec15;
271 :
272 : /* Pre-additions and core multiplications */
273 0 : temp20 = temp10 + temp18;
274 0 : temp24 = temp10 - temp18;
275 0 : temp21 = temp11 + temp19;
276 0 : temp25 = temp11 - temp19;
277 0 : temp28 = temp12 - temp111;
278 0 : temp210 = temp12 + temp111;
279 0 : temp29 = temp13 + temp110;
280 0 : temp211 = temp13 - temp110;
281 0 : temp22 = temp14 + temp112;
282 0 : temp27 = temp14 - temp112;
283 0 : temp23 = temp15 + temp113;
284 0 : temp26 = temp113 - temp15;
285 :
286 0 : temp11 = temp16 + temp114;
287 0 : temp12 = temp16 - temp114;
288 0 : temp10 = temp17 + temp115;
289 0 : temp13 = temp17 - temp115;
290 0 : temp212 = (temp10 + temp12) * INV_SQRT2;
291 0 : temp214 = (temp10 - temp12) * INV_SQRT2;
292 0 : temp213 = (temp13 - temp11) * INV_SQRT2;
293 0 : temp215 = (temp11 + temp13) * -INV_SQRT2;
294 :
295 : /* odd */
296 0 : vec0 = vec[0] - vec[16];
297 0 : vec1 = vec[1] - vec[17];
298 0 : vec2 = vec[2] - vec[18];
299 0 : vec3 = vec[3] - vec[19];
300 0 : vec4 = vec[4] - vec[20];
301 0 : vec5 = vec[5] - vec[21];
302 0 : vec6 = vec[6] - vec[22];
303 0 : vec7 = vec[7] - vec[23];
304 0 : vec8 = vec[8] - vec[24];
305 0 : vec9 = vec[9] - vec[25];
306 0 : vec10 = vec[10] - vec[26];
307 0 : vec11 = vec[11] - vec[27];
308 0 : vec12 = vec[12] - vec[28];
309 0 : vec13 = vec[13] - vec[29];
310 0 : vec14 = vec[14] - vec[30];
311 0 : vec15 = vec[15] - vec[31];
312 :
313 : /* Pre-additions and core multiplications */
314 0 : temp19 = (vec2 + vec14) * -COS_3PI_DIV8;
315 0 : temp110 = (vec2 - vec14) * COS_PI_DIV8;
316 0 : temp18 = (vec3 + vec15) * COS_3PI_DIV8;
317 0 : temp111 = (vec3 - vec15) * COS_PI_DIV8;
318 0 : temp15 = (vec4 + vec12) * -INV_SQRT2;
319 0 : temp16 = (vec4 - vec12) * INV_SQRT2;
320 0 : temp14 = (vec5 + vec13) * INV_SQRT2;
321 0 : temp17 = (vec5 - vec13) * INV_SQRT2;
322 0 : temp113 = (vec6 + vec10) * -COS_PI_DIV8;
323 0 : temp114 = (vec6 - vec10) * COS_3PI_DIV8;
324 0 : temp112 = (vec7 + vec11) * COS_PI_DIV8;
325 0 : temp115 = (vec7 - vec11) * COS_3PI_DIV8;
326 :
327 : /* Core multiplications */
328 0 : vec2 = temp18 * SQRT2PLUS1 - temp112 * SQRT2MINUS1;
329 0 : vec3 = temp19 * SQRT2PLUS1 - temp113 * SQRT2MINUS1;
330 0 : vec4 = temp110 * SQRT2MINUS1 - temp114 * SQRT2PLUS1;
331 0 : vec5 = temp111 * SQRT2MINUS1 - temp115 * SQRT2PLUS1;
332 :
333 : /* Post-additions */
334 0 : temp18 += temp112;
335 0 : temp19 += temp113;
336 0 : temp110 += temp114;
337 0 : temp111 += temp115;
338 0 : vec6 = vec0 + temp14;
339 0 : vec10 = vec0 - temp14;
340 0 : vec7 = vec1 + temp15;
341 0 : vec11 = vec1 - temp15;
342 :
343 0 : vec12 = temp16 - vec9;
344 0 : vec14 = temp16 + vec9;
345 0 : vec13 = vec8 + temp17;
346 0 : vec15 = vec8 - temp17;
347 :
348 0 : temp10 = vec6 - vec14;
349 0 : temp12 = vec6 + vec14;
350 0 : temp11 = vec7 + vec15;
351 0 : temp13 = vec7 - vec15;
352 0 : temp14 = vec10 + vec12;
353 0 : temp16 = vec10 - vec12;
354 0 : temp15 = vec11 + vec13;
355 0 : temp17 = vec11 - vec13;
356 :
357 0 : vec10 = temp18 + temp110;
358 0 : temp110 = temp18 - temp110;
359 0 : vec11 = temp19 + temp111;
360 0 : temp111 = temp19 - temp111;
361 :
362 0 : temp112 = vec2 + vec4;
363 0 : temp114 = vec2 - vec4;
364 0 : temp113 = vec3 + vec5;
365 0 : temp115 = vec3 - vec5;
366 :
367 : /* Post-additions */
368 0 : *vec++ = temp20 + temp22;
369 0 : *vec++ = temp21 + temp23;
370 0 : *vec++ = temp12 + vec10;
371 0 : *vec++ = temp13 + vec11;
372 0 : *vec++ = temp210 + temp212;
373 0 : *vec++ = temp211 + temp213;
374 0 : *vec++ = temp10 + temp112;
375 0 : *vec++ = temp11 + temp113;
376 0 : *vec++ = temp24 - temp26;
377 0 : *vec++ = temp25 - temp27;
378 0 : *vec++ = temp16 + temp114;
379 0 : *vec++ = temp17 + temp115;
380 0 : *vec++ = temp28 + temp214;
381 0 : *vec++ = temp29 + temp215;
382 0 : *vec++ = temp14 + temp110;
383 0 : *vec++ = temp15 + temp111;
384 0 : *vec++ = temp20 - temp22;
385 0 : *vec++ = temp21 - temp23;
386 0 : *vec++ = temp12 - vec10;
387 0 : *vec++ = temp13 - vec11;
388 0 : *vec++ = temp210 - temp212;
389 0 : *vec++ = temp211 - temp213;
390 0 : *vec++ = temp10 - temp112;
391 0 : *vec++ = temp11 - temp113;
392 0 : *vec++ = temp24 + temp26;
393 0 : *vec++ = temp25 + temp27;
394 0 : *vec++ = temp16 - temp114;
395 0 : *vec++ = temp17 - temp115;
396 0 : *vec++ = temp28 - temp214;
397 0 : *vec++ = temp29 - temp215;
398 0 : *vec++ = temp14 - temp110;
399 0 : *vec++ = temp15 - temp111;
400 0 : }
|