refactor: split fft lib

This commit is contained in:
liuyihui 2023-04-23 21:36:04 +08:00
parent 21f80b00f1
commit 384369ca62
4 changed files with 431 additions and 417 deletions

View File

@ -1,138 +1,11 @@
#pragma once
#include "inttypes.h"
#include "math.h"
#include "stdlib.h"
#include "table.h"
#define Re(x) 2 * x
#define Im(x) 2 * x + 1
#define q15_t int16_t
#define q31_t int32_t
#define FFT_BIN(num, fs, size) (uint16_t)((float)(num) * (float)fs / (float)size)
#define FFT_INDEX(freq, fs, size) ((int)((float)freq / ((float)fs / (float)size)))
#define FFT_INDEX(freq, fs, size) (uint16_t)((float)freq / ((float)fs / (float)size))
void bitreversal(q31_t *data, uint16_t len, uint16_t *bitrev, uint16_t step) {
q31_t tmp;
uint16_t n1 = len >> 1;
uint16_t n2 = n1 + 1;
for (uint16_t i = 0, j = 0; i <= (n1 - 2); i += 2) {
if (i < j) {
tmp = data[i];
data[i] = data[j];
data[j] = tmp;
tmp = data[i + n2];
data[i + n2] = data[j + n2];
data[j + n2] = tmp;
}
tmp = data[i + 1];
data[i + 1] = data[j + n1];
data[j + n1] = tmp;
j = *bitrev;
bitrev += step;
}
}
void butterfly(q15_t *data, uint16_t len, uint16_t step) {
q15_t xt, yt, cosv, sinv;
for (uint16_t m = len; m > 1; m = m >> 1) {
uint16_t n1 = m;
uint16_t n2 = m >> 1;
for (uint16_t i = 0, ia = 0; i < n2; i++) {
cosv = rotCoef[ia * 2];
sinv = rotCoef[ia * 2 + 1];
ia = ia + step;
for (uint16_t j = i, k; j < len; j += n1) {
k = j + n2;
if (m == len) {
xt = (data[Re(j)] >> 2u) - (data[Re(k)] >> 2u);
yt = (data[Im(j)] >> 2u) - (data[Im(k)] >> 2u);
data[Re(j)] = (q15_t)(((data[Re(j)] >> 2u) + (data[Re(k)] >> 2u)) >> 1);
data[Im(j)] = (q15_t)(((data[Im(k)] >> 2u) + (data[Im(j)] >> 2u)) >> 1);
data[Re(k)] = ((((q31_t)xt * cosv) >> 16)) + ((((q31_t)yt * sinv) >> 16));
data[Im(k)] = ((((q31_t)yt * cosv) >> 16)) - ((((q31_t)xt * sinv) >> 16));
} else if (m == 2) {
xt = data[Re(j)] - data[Re(k)];
yt = data[Im(j)] - data[Im(k)];
data[Re(j)] = data[Re(j)] + data[Re(k)];
data[Im(j)] = data[Im(k)] + data[Im(j)];
data[Re(k)] = xt;
data[Im(k)] = yt;
} else {
xt = data[Re(j)] - data[Re(k)];
yt = data[Im(j)] - data[Im(k)];
data[Re(j)] = (q15_t)((data[Re(j)] + data[Re(k)]) >> 1);
data[Im(j)] = (q15_t)((data[Im(k)] + data[Im(j)]) >> 1);
data[Re(k)] = ((((q31_t)xt * cosv) >> 16)) + ((((q31_t)yt * sinv) >> 16));
data[Im(k)] = ((((q31_t)yt * cosv) >> 16)) - ((((q31_t)xt * sinv) >> 16));
}
}
}
step = step << 1;
}
}
static inline void applyWindow(q15_t *src, const q15_t *window, uint16_t len) {
while (len--) {
*src = (q15_t)(((q31_t)(*src) * (*window)) >> 15);
src++;
window++;
}
}
int ZeroFFT(q15_t *data, uint16_t len) {
uint16_t step;
uint16_t *bitrev;
q15_t out[len * 2];
switch (len) {
case 1024u:
step = 1u;
bitrev = (uint16_t *)&armBitRevTable[0];
applyWindow(data, window_hanning_1024, 1024);
break;
case 512u:
step = 2u;
bitrev = (uint16_t *)&armBitRevTable[1];
applyWindow(data, window_hanning_512, 512);
break;
case 256u:
step = 4u;
bitrev = (uint16_t *)&armBitRevTable[3];
applyWindow(data, window_hanning_256, 256);
break;
case 128u:
step = 8u;
bitrev = (uint16_t *)&armBitRevTable[7];
applyWindow(data, window_hanning_128, 128);
break;
default:
return -1;
break;
}
for (uint16_t i = 0; i < len; i++) {
out[Re(i)] = data[i]; // real
out[Im(i)] = 0; // imaginary
}
butterfly(out, len, step);
bitreversal((q31_t *)out, len, bitrev, step);
for (uint16_t i = 0; i < len; i++) data[i] = (q15_t)abs(out[2 * i]);
return 0;
}
int FFT(q15_t *data, uint16_t len);

View File

@ -1,289 +1,11 @@
#pragma once
#include "inttypes.h"
#include "fft.h"
#define q15_t int16_t
#define q31_t int32_t
extern const q15_t hanning_128[];
extern const q15_t hanning_256[];
extern const q15_t hanning_512[];
extern const q15_t hanning_1024[];
const q15_t window_hanning_128[] = {
0, 20, 80, 180, 319, 498, 716, 972, 1266, 1597, 1964, 2366, 2803, 3273, 3775, 4308,
4870, 5461, 6078, 6720, 7386, 8075, 8783, 9510, 10254, 11013, 11785, 12568, 13361, 14161, 14966, 15775,
16586, 17396, 18203, 19006, 19803, 20591, 21369, 22134, 22886, 23622, 24340, 25038, 25716, 26370, 27000, 27604,
28181, 28729, 29246, 29732, 30186, 30605, 30990, 31339, 31652, 31927, 32164, 32362, 32521, 32641, 32721, 32761,
32761, 32721, 32641, 32521, 32362, 32164, 31927, 31652, 31339, 30990, 30605, 30186, 29732, 29246, 28729, 28181,
27604, 27000, 26370, 25716, 25038, 24340, 23622, 22886, 22134, 21369, 20591, 19803, 19006, 18203, 17396, 16586,
15775, 14966, 14161, 13361, 12568, 11785, 11013, 10254, 9510, 8783, 8075, 7386, 6720, 6078, 5461, 4870,
4308, 3775, 3273, 2803, 2366, 1964, 1597, 1266, 972, 716, 498, 319, 180, 80, 20, 0,
};
const q15_t window_hanning_256[] = {
0, 4, 19, 44, 79, 124, 178, 243, 317, 401, 494, 598, 710, 833, 965, 1106,
1256, 1416, 1585, 1762, 1949, 2144, 2348, 2561, 2782, 3011, 3248, 3493, 3746, 4007, 4275, 4551,
4834, 5124, 5420, 5724, 6033, 6349, 6672, 7000, 7333, 7673, 8017, 8367, 8721, 9080, 9444, 9812,
10183, 10559, 10938, 11320, 11706, 12094, 12485, 12878, 13273, 13671, 14070, 14470, 14871, 15274, 15677, 16080,
16484, 16888, 17291, 17694, 18096, 18496, 18896, 19294, 19691, 20085, 20477, 20867, 21253, 21637, 22018, 22395,
22769, 23139, 23505, 23866, 24223, 24575, 24922, 25264, 25600, 25931, 26256, 26575, 26888, 27195, 27495, 27788,
28074, 28354, 28626, 28890, 29147, 29396, 29638, 29871, 30096, 30313, 30521, 30720, 30911, 31094, 31267, 31431,
31586, 31732, 31868, 31996, 32113, 32221, 32320, 32408, 32488, 32557, 32616, 32666, 32706, 32735, 32755, 32765,
32765, 32755, 32735, 32706, 32666, 32616, 32557, 32488, 32408, 32320, 32221, 32113, 31996, 31868, 31732, 31586,
31431, 31267, 31094, 30911, 30720, 30521, 30313, 30096, 29871, 29638, 29396, 29147, 28890, 28626, 28354, 28074,
27788, 27495, 27195, 26888, 26575, 26256, 25931, 25600, 25264, 24922, 24575, 24223, 23866, 23505, 23139, 22769,
22395, 22018, 21637, 21253, 20867, 20477, 20085, 19691, 19294, 18896, 18496, 18096, 17694, 17291, 16888, 16484,
16080, 15677, 15274, 14871, 14470, 14070, 13671, 13273, 12878, 12485, 12094, 11706, 11320, 10938, 10559, 10183,
9812, 9444, 9080, 8721, 8367, 8017, 7673, 7333, 7000, 6672, 6349, 6033, 5724, 5420, 5124, 4834,
4551, 4275, 4007, 3746, 3493, 3248, 3011, 2782, 2561, 2348, 2144, 1949, 1762, 1585, 1416, 1256,
1106, 965, 833, 710, 598, 494, 401, 317, 243, 178, 124, 79, 44, 19, 4, 0,
};
const q15_t window_hanning_512[] = {
0, 1, 4, 11, 19, 30, 44, 60, 79, 100, 123, 149, 178, 208, 242, 277,
316, 356, 399, 445, 492, 543, 595, 650, 708, 767, 830, 894, 961, 1030, 1102, 1175,
1251, 1330, 1410, 1493, 1579, 1666, 1756, 1847, 1941, 2038, 2136, 2237, 2339, 2444, 2551, 2660,
2771, 2884, 2999, 3117, 3236, 3357, 3480, 3605, 3732, 3861, 3992, 4125, 4259, 4396, 4534, 4674,
4816, 4959, 5105, 5252, 5400, 5551, 5703, 5856, 6011, 6168, 6326, 6486, 6647, 6810, 6974, 7140,
7307, 7475, 7645, 7816, 7989, 8162, 8337, 8513, 8690, 8869, 9048, 9229, 9411, 9594, 9778, 9962,
10148, 10335, 10523, 10711, 10901, 11091, 11282, 11474, 11666, 11860, 12054, 12248, 12443, 12639, 12836, 13033,
13230, 13428, 13626, 13825, 14024, 14224, 14424, 14624, 14824, 15025, 15226, 15427, 15628, 15829, 16030, 16232,
16433, 16635, 16836, 17038, 17239, 17440, 17641, 17842, 18042, 18242, 18442, 18642, 18841, 19040, 19239, 19437,
19635, 19832, 20029, 20225, 20420, 20615, 20810, 21003, 21196, 21388, 21580, 21770, 21960, 22149, 22337, 22525,
22711, 22896, 23080, 23264, 23446, 23627, 23807, 23986, 24164, 24341, 24517, 24691, 24864, 25035, 25206, 25375,
25543, 25709, 25874, 26037, 26199, 26360, 26519, 26677, 26832, 26987, 27140, 27291, 27440, 27588, 27734, 27879,
28021, 28162, 28301, 28439, 28574, 28708, 28839, 28969, 29097, 29223, 29348, 29470, 29590, 29708, 29824, 29939,
30051, 30161, 30269, 30375, 30478, 30580, 30679, 30777, 30872, 30965, 31056, 31144, 31230, 31314, 31396, 31476,
31553, 31628, 31700, 31771, 31839, 31904, 31968, 32029, 32087, 32144, 32197, 32249, 32298, 32344, 32389, 32430,
32470, 32507, 32541, 32573, 32603, 32630, 32655, 32677, 32697, 32714, 32729, 32741, 32751, 32759, 32764, 32766,
32766, 32764, 32759, 32751, 32741, 32729, 32714, 32697, 32677, 32655, 32630, 32603, 32573, 32541, 32507, 32470,
32430, 32389, 32344, 32298, 32249, 32197, 32144, 32087, 32029, 31968, 31904, 31839, 31771, 31700, 31628, 31553,
31476, 31396, 31314, 31230, 31144, 31056, 30965, 30872, 30777, 30679, 30580, 30478, 30375, 30269, 30161, 30051,
29939, 29824, 29708, 29590, 29470, 29348, 29223, 29097, 28969, 28839, 28708, 28574, 28439, 28301, 28162, 28021,
27879, 27734, 27588, 27440, 27291, 27140, 26987, 26832, 26677, 26519, 26360, 26199, 26037, 25874, 25709, 25543,
25375, 25206, 25035, 24864, 24691, 24517, 24341, 24164, 23986, 23807, 23627, 23446, 23264, 23080, 22896, 22711,
22525, 22337, 22149, 21960, 21770, 21580, 21388, 21196, 21003, 20810, 20615, 20420, 20225, 20029, 19832, 19635,
19437, 19239, 19040, 18841, 18642, 18442, 18242, 18042, 17842, 17641, 17440, 17239, 17038, 16836, 16635, 16433,
16232, 16030, 15829, 15628, 15427, 15226, 15025, 14824, 14624, 14424, 14224, 14024, 13825, 13626, 13428, 13230,
13033, 12836, 12639, 12443, 12248, 12054, 11860, 11666, 11474, 11282, 11091, 10901, 10711, 10523, 10335, 10148,
9962, 9778, 9594, 9411, 9229, 9048, 8869, 8690, 8513, 8337, 8162, 7989, 7816, 7645, 7475, 7307,
7140, 6974, 6810, 6647, 6486, 6326, 6168, 6011, 5856, 5703, 5551, 5400, 5252, 5105, 4959, 4816,
4674, 4534, 4396, 4259, 4125, 3992, 3861, 3732, 3605, 3480, 3357, 3236, 3117, 2999, 2884, 2771,
2660, 2551, 2444, 2339, 2237, 2136, 2038, 1941, 1847, 1756, 1666, 1579, 1493, 1410, 1330, 1251,
1175, 1102, 1030, 961, 894, 830, 767, 708, 650, 595, 543, 492, 445, 399, 356, 316,
277, 242, 208, 178, 149, 123, 100, 79, 60, 44, 30, 19, 11, 4, 1, 0,
};
const q15_t window_hanning_1024[] = {
0, 0, 1, 2, 4, 7, 11, 15, 19, 25, 30, 37, 44, 52, 60, 69,
79, 89, 100, 111, 123, 136, 149, 163, 177, 192, 208, 224, 241, 259, 277, 296,
315, 335, 355, 377, 398, 421, 444, 467, 491, 516, 542, 568, 594, 621, 649, 677,
706, 736, 766, 797, 828, 860, 892, 925, 959, 993, 1028, 1063, 1099, 1136, 1173, 1211,
1249, 1288, 1327, 1367, 1408, 1449, 1491, 1533, 1576, 1619, 1663, 1707, 1752, 1798, 1844, 1891,
1938, 1986, 2034, 2083, 2132, 2182, 2232, 2283, 2335, 2387, 2439, 2493, 2546, 2600, 2655, 2710,
2766, 2822, 2879, 2936, 2994, 3052, 3111, 3170, 3230, 3290, 3351, 3412, 3474, 3536, 3599, 3662,
3725, 3789, 3854, 3919, 3985, 4051, 4117, 4184, 4252, 4319, 4388, 4456, 4526, 4595, 4665, 4736,
4807, 4878, 4950, 5023, 5095, 5168, 5242, 5316, 5390, 5465, 5540, 5616, 5692, 5769, 5845, 5923,
6000, 6078, 6157, 6236, 6315, 6394, 6474, 6555, 6635, 6716, 6798, 6880, 6962, 7044, 7127, 7210,
7294, 7378, 7462, 7547, 7631, 7717, 7802, 7888, 7974, 8061, 8148, 8235, 8322, 8410, 8498, 8586,
8675, 8764, 8853, 8943, 9033, 9123, 9213, 9304, 9395, 9486, 9577, 9669, 9761, 9853, 9945, 10038,
10131, 10224, 10317, 10411, 10505, 10599, 10693, 10787, 10882, 10977, 11072, 11167, 11263, 11359, 11454, 11550,
11647, 11743, 11840, 11936, 12033, 12130, 12228, 12325, 12423, 12520, 12618, 12716, 12814, 12913, 13011, 13110,
13208, 13307, 13406, 13505, 13604, 13703, 13803, 13902, 14002, 14101, 14201, 14301, 14401, 14500, 14600, 14700,
14801, 14901, 15001, 15101, 15202, 15302, 15402, 15503, 15603, 15704, 15805, 15905, 16006, 16106, 16207, 16308,
16408, 16509, 16609, 16710, 16811, 16911, 17012, 17112, 17213, 17313, 17414, 17514, 17615, 17715, 17815, 17915,
18015, 18116, 18216, 18316, 18415, 18515, 18615, 18715, 18814, 18914, 19013, 19112, 19211, 19311, 19409, 19508,
19607, 19706, 19804, 19902, 20001, 20099, 20197, 20294, 20392, 20490, 20587, 20684, 20781, 20878, 20975, 21071,
21167, 21264, 21360, 21455, 21551, 21646, 21742, 21837, 21931, 22026, 22120, 22214, 22308, 22402, 22495, 22589,
22682, 22775, 22867, 22959, 23051, 23143, 23235, 23326, 23417, 23508, 23598, 23688, 23778, 23868, 23957, 24046,
24135, 24224, 24312, 24400, 24487, 24575, 24662, 24748, 24835, 24921, 25007, 25092, 25177, 25262, 25346, 25430,
25514, 25597, 25680, 25763, 25845, 25927, 26009, 26090, 26171, 26252, 26332, 26411, 26491, 26570, 26648, 26727,
26805, 26882, 26959, 27036, 27112, 27188, 27263, 27338, 27413, 27487, 27561, 27634, 27707, 27780, 27852, 27923,
27995, 28065, 28136, 28206, 28275, 28344, 28412, 28481, 28548, 28615, 28682, 28748, 28814, 28879, 28944, 29009,
29073, 29136, 29199, 29261, 29323, 29385, 29446, 29506, 29566, 29626, 29685, 29743, 29801, 29859, 29916, 29972,
30028, 30083, 30138, 30193, 30247, 30300, 30353, 30405, 30457, 30508, 30559, 30609, 30659, 30708, 30756, 30804,
30852, 30899, 30945, 30991, 31036, 31081, 31125, 31169, 31212, 31254, 31296, 31338, 31379, 31419, 31459, 31498,
31536, 31574, 31612, 31648, 31685, 31720, 31755, 31790, 31824, 31857, 31890, 31922, 31954, 31985, 32015, 32045,
32074, 32103, 32131, 32158, 32185, 32211, 32237, 32262, 32287, 32311, 32334, 32357, 32379, 32400, 32421, 32441,
32461, 32480, 32498, 32516, 32533, 32550, 32566, 32581, 32596, 32610, 32624, 32637, 32649, 32661, 32672, 32682,
32692, 32702, 32710, 32718, 32726, 32732, 32739, 32744, 32749, 32753, 32757, 32760, 32763, 32765, 32766, 32766,
32766, 32766, 32765, 32763, 32760, 32757, 32753, 32749, 32744, 32739, 32732, 32726, 32718, 32710, 32702, 32692,
32682, 32672, 32661, 32649, 32637, 32624, 32610, 32596, 32581, 32566, 32550, 32533, 32516, 32498, 32480, 32461,
32441, 32421, 32400, 32379, 32357, 32334, 32311, 32287, 32262, 32237, 32211, 32185, 32158, 32131, 32103, 32074,
32045, 32015, 31985, 31954, 31922, 31890, 31857, 31824, 31790, 31755, 31720, 31685, 31648, 31612, 31574, 31536,
31498, 31459, 31419, 31379, 31338, 31296, 31254, 31212, 31169, 31125, 31081, 31036, 30991, 30945, 30899, 30852,
30804, 30756, 30708, 30659, 30609, 30559, 30508, 30457, 30405, 30353, 30300, 30247, 30193, 30138, 30083, 30028,
29972, 29916, 29859, 29801, 29743, 29685, 29626, 29566, 29506, 29446, 29385, 29323, 29261, 29199, 29136, 29073,
29009, 28944, 28879, 28814, 28748, 28682, 28615, 28548, 28481, 28412, 28344, 28275, 28206, 28136, 28065, 27995,
27923, 27852, 27780, 27707, 27634, 27561, 27487, 27413, 27338, 27263, 27188, 27112, 27036, 26959, 26882, 26805,
26727, 26648, 26570, 26491, 26411, 26332, 26252, 26171, 26090, 26009, 25927, 25845, 25763, 25680, 25597, 25514,
25430, 25346, 25262, 25177, 25092, 25007, 24921, 24835, 24748, 24662, 24575, 24487, 24400, 24312, 24224, 24135,
24046, 23957, 23868, 23778, 23688, 23598, 23508, 23417, 23326, 23235, 23143, 23051, 22959, 22867, 22775, 22682,
22589, 22495, 22402, 22308, 22214, 22120, 22026, 21931, 21837, 21742, 21646, 21551, 21455, 21360, 21264, 21167,
21071, 20975, 20878, 20781, 20684, 20587, 20490, 20392, 20294, 20197, 20099, 20001, 19902, 19804, 19706, 19607,
19508, 19409, 19311, 19211, 19112, 19013, 18914, 18814, 18715, 18615, 18515, 18415, 18316, 18216, 18116, 18015,
17915, 17815, 17715, 17615, 17514, 17414, 17313, 17213, 17112, 17012, 16911, 16811, 16710, 16609, 16509, 16408,
16308, 16207, 16106, 16006, 15905, 15805, 15704, 15603, 15503, 15402, 15302, 15202, 15101, 15001, 14901, 14801,
14700, 14600, 14500, 14401, 14301, 14201, 14101, 14002, 13902, 13803, 13703, 13604, 13505, 13406, 13307, 13208,
13110, 13011, 12913, 12814, 12716, 12618, 12520, 12423, 12325, 12228, 12130, 12033, 11936, 11840, 11743, 11647,
11550, 11454, 11359, 11263, 11167, 11072, 10977, 10882, 10787, 10693, 10599, 10505, 10411, 10317, 10224, 10131,
10038, 9945, 9853, 9761, 9669, 9577, 9486, 9395, 9304, 9213, 9123, 9033, 8943, 8853, 8764, 8675,
8586, 8498, 8410, 8322, 8235, 8148, 8061, 7974, 7888, 7802, 7717, 7631, 7547, 7462, 7378, 7294,
7210, 7127, 7044, 6962, 6880, 6798, 6716, 6635, 6555, 6474, 6394, 6315, 6236, 6157, 6078, 6000,
5923, 5845, 5769, 5692, 5616, 5540, 5465, 5390, 5316, 5242, 5168, 5095, 5023, 4950, 4878, 4807,
4736, 4665, 4595, 4526, 4456, 4388, 4319, 4252, 4184, 4117, 4051, 3985, 3919, 3854, 3789, 3725,
3662, 3599, 3536, 3474, 3412, 3351, 3290, 3230, 3170, 3111, 3052, 2994, 2936, 2879, 2822, 2766,
2710, 2655, 2600, 2546, 2493, 2439, 2387, 2335, 2283, 2232, 2182, 2132, 2083, 2034, 1986, 1938,
1891, 1844, 1798, 1752, 1707, 1663, 1619, 1576, 1533, 1491, 1449, 1408, 1367, 1327, 1288, 1249,
1211, 1173, 1136, 1099, 1063, 1028, 993, 959, 925, 892, 860, 828, 797, 766, 736, 706,
677, 649, 621, 594, 568, 542, 516, 491, 467, 444, 421, 398, 377, 355, 335, 315,
296, 277, 259, 241, 224, 208, 192, 177, 163, 149, 136, 123, 111, 100, 89, 79,
69, 60, 52, 44, 37, 30, 25, 19, 15, 11, 7, 4, 2, 1, 0, 0,
};
/*
Table for bit reversal process, where N = 4096 logN2 = 12, N is the maximum FFT Size supported
for (l = 1; l <= N / 4; l++) {
for (i = 0; i < logN2; i++) {
a[i] = l & (1 << i);
}
for (j = 0; j < logN2; j++) {
if (a[j] != 0) y[l] += (1 << ((logN2 - 1) - j));
}
y[l] = y[l] >> 1;
}
*/
const uint16_t armBitRevTable[256] = {
0x100, 0x80, 0x180, 0x40, 0x140, 0xc0, 0x1c0, 0x20, 0x120, 0xa0, 0x1a0, 0x60, 0x160, 0xe0, 0x1e0, 0x10, 0x110, 0x90,
0x190, 0x50, 0x150, 0xd0, 0x1d0, 0x30, 0x130, 0xb0, 0x1b0, 0x70, 0x170, 0xf0, 0x1f0, 0x8, 0x108, 0x88, 0x188, 0x48,
0x148, 0xc8, 0x1c8, 0x28, 0x128, 0xa8, 0x1a8, 0x68, 0x168, 0xe8, 0x1e8, 0x18, 0x118, 0x98, 0x198, 0x58, 0x158, 0xd8,
0x1d8, 0x38, 0x138, 0xb8, 0x1b8, 0x78, 0x178, 0xf8, 0x1f8, 0x4, 0x104, 0x84, 0x184, 0x44, 0x144, 0xc4, 0x1c4, 0x24,
0x124, 0xa4, 0x1a4, 0x64, 0x164, 0xe4, 0x1e4, 0x14, 0x114, 0x94, 0x194, 0x54, 0x154, 0xd4, 0x1d4, 0x34, 0x134, 0xb4,
0x1b4, 0x74, 0x174, 0xf4, 0x1f4, 0xc, 0x10c, 0x8c, 0x18c, 0x4c, 0x14c, 0xcc, 0x1cc, 0x2c, 0x12c, 0xac, 0x1ac, 0x6c,
0x16c, 0xec, 0x1ec, 0x1c, 0x11c, 0x9c, 0x19c, 0x5c, 0x15c, 0xdc, 0x1dc, 0x3c, 0x13c, 0xbc, 0x1bc, 0x7c, 0x17c, 0xfc,
0x1fc, 0x2, 0x102, 0x82, 0x182, 0x42, 0x142, 0xc2, 0x1c2, 0x22, 0x122, 0xa2, 0x1a2, 0x62, 0x162, 0xe2, 0x1e2, 0x12,
0x112, 0x92, 0x192, 0x52, 0x152, 0xd2, 0x1d2, 0x32, 0x132, 0xb2, 0x1b2, 0x72, 0x172, 0xf2, 0x1f2, 0xa, 0x10a, 0x8a,
0x18a, 0x4a, 0x14a, 0xca, 0x1ca, 0x2a, 0x12a, 0xaa, 0x1aa, 0x6a, 0x16a, 0xea, 0x1ea, 0x1a, 0x11a, 0x9a, 0x19a, 0x5a,
0x15a, 0xda, 0x1da, 0x3a, 0x13a, 0xba, 0x1ba, 0x7a, 0x17a, 0xfa, 0x1fa, 0x6, 0x106, 0x86, 0x186, 0x46, 0x146, 0xc6,
0x1c6, 0x26, 0x126, 0xa6, 0x1a6, 0x66, 0x166, 0xe6, 0x1e6, 0x16, 0x116, 0x96, 0x196, 0x56, 0x156, 0xd6, 0x1d6, 0x36,
0x136, 0xb6, 0x1b6, 0x76, 0x176, 0xf6, 0x1f6, 0xe, 0x10e, 0x8e, 0x18e, 0x4e, 0x14e, 0xce, 0x1ce, 0x2e, 0x12e, 0xae,
0x1ae, 0x6e, 0x16e, 0xee, 0x1ee, 0x1e, 0x11e, 0x9e, 0x19e, 0x5e, 0x15e, 0xde, 0x1de, 0x3e, 0x13e, 0xbe, 0x1be, 0x7e,
0x17e, 0xfe, 0x1fe, 0x1,
};
/*
Example code for q15 Twiddle factors Generation::
for (i = 0; i < 3N / 4; i++) {
rotCoef[2 * i] = cos(i * 2 * PI / (float)N);
rotCoef[2 * i + 1] = sin(i * 2 * PI / (float)N);
}
where N = 1024 and PI = 3.14159265358979, Cos and Sin values are interleaved fashion
Convert Floating point to int16 round(rotCoef(i) * pow(2, 15))
*/
const q15_t rotCoef[1536] = {
32767, 0, 32766, 201, 32765, 402, 32761, 603, 32757, 804, 32752, 1005, 32745, 1206,
32737, 1407, 32728, 1608, 32717, 1809, 32705, 2009, 32692, 2210, 32678, 2410, 32663, 2611,
32646, 2811, 32628, 3012, 32609, 3212, 32589, 3412, 32567, 3612, 32545, 3811, 32521, 4011,
32495, 4210, 32469, 4410, 32441, 4609, 32412, 4808, 32382, 5007, 32351, 5205, 32318, 5404,
32285, 5602, 32250, 5800, 32213, 5998, 32176, 6195, 32137, 6393, 32098, 6590, 32057, 6786,
32014, 6983, 31971, 7179, 31926, 7375, 31880, 7571, 31833, 7767, 31785, 7962, 31736, 8157,
31685, 8351, 31633, 8545, 31580, 8739, 31526, 8933, 31470, 9126, 31414, 9319, 31356, 9512,
31297, 9704, 31237, 9896, 31176, 10087, 31113, 10278, 31050, 10469, 30985, 10659, 30919, 10849,
30852, 11039, 30783, 11228, 30714, 11417, 30643, 11605, 30571, 11793, 30498, 11980, 30424, 12167,
30349, 12353, 30273, 12539, 30195, 12725, 30117, 12910, 30037, 13094, 29956, 13279, 29874, 13462,
29791, 13645, 29706, 13828, 29621, 14010, 29534, 14191, 29447, 14372, 29358, 14553, 29268, 14732,
29177, 14912, 29085, 15090, 28992, 15269, 28898, 15446, 28803, 15623, 28706, 15800, 28609, 15976,
28510, 16151, 28411, 16325, 28310, 16499, 28208, 16673, 28105, 16846, 28001, 17018, 27896, 17189,
27790, 17360, 27683, 17530, 27575, 17700, 27466, 17869, 27356, 18037, 27245, 18204, 27133, 18371,
27019, 18537, 26905, 18703, 26790, 18868, 26674, 19032, 26556, 19195, 26438, 19357, 26319, 19519,
26198, 19680, 26077, 19841, 25955, 20000, 25832, 20159, 25708, 20317, 25582, 20475, 25456, 20631,
25329, 20787, 25201, 20942, 25072, 21096, 24942, 21250, 24811, 21403, 24680, 21554, 24547, 21705,
24413, 21856, 24279, 22005, 24143, 22154, 24007, 22301, 23870, 22448, 23731, 22594, 23592, 22739,
23452, 22884, 23311, 23027, 23170, 23170, 23027, 23311, 22884, 23452, 22739, 23592, 22594, 23731,
22448, 23870, 22301, 24007, 22154, 24143, 22005, 24279, 21856, 24413, 21705, 24547, 21554, 24680,
21403, 24811, 21250, 24942, 21096, 25072, 20942, 25201, 20787, 25329, 20631, 25456, 20475, 25582,
20317, 25708, 20159, 25832, 20000, 25955, 19841, 26077, 19680, 26198, 19519, 26319, 19357, 26438,
19195, 26556, 19032, 26674, 18868, 26790, 18703, 26905, 18537, 27019, 18371, 27133, 18204, 27245,
18037, 27356, 17869, 27466, 17700, 27575, 17530, 27683, 17360, 27790, 17189, 27896, 17018, 28001,
16846, 28105, 16673, 28208, 16499, 28310, 16325, 28411, 16151, 28510, 15976, 28609, 15800, 28706,
15623, 28803, 15446, 28898, 15269, 28992, 15090, 29085, 14912, 29177, 14732, 29268, 14553, 29358,
14372, 29447, 14191, 29534, 14010, 29621, 13828, 29706, 13645, 29791, 13462, 29874, 13279, 29956,
13094, 30037, 12910, 30117, 12725, 30195, 12539, 30273, 12353, 30349, 12167, 30424, 11980, 30498,
11793, 30571, 11605, 30643, 11417, 30714, 11228, 30783, 11039, 30852, 10849, 30919, 10659, 30985,
10469, 31050, 10278, 31113, 10087, 31176, 9896, 31237, 9704, 31297, 9512, 31356, 9319, 31414,
9126, 31470, 8933, 31526, 8739, 31580, 8545, 31633, 8351, 31685, 8157, 31736, 7962, 31785,
7767, 31833, 7571, 31880, 7375, 31926, 7179, 31971, 6983, 32014, 6786, 32057, 6590, 32098,
6393, 32137, 6195, 32176, 5998, 32213, 5800, 32250, 5602, 32285, 5404, 32318, 5205, 32351,
5007, 32382, 4808, 32412, 4609, 32441, 4410, 32469, 4210, 32495, 4011, 32521, 3811, 32545,
3612, 32567, 3412, 32589, 3212, 32609, 3012, 32628, 2811, 32646, 2611, 32663, 2410, 32678,
2210, 32692, 2009, 32705, 1809, 32717, 1608, 32728, 1407, 32737, 1206, 32745, 1005, 32752,
804, 32757, 603, 32761, 402, 32765, 201, 32766, 0, 32767, -201, 32766, -402, 32765,
-603, 32761, -804, 32757, -1005, 32752, -1206, 32745, -1407, 32737, -1608, 32728, -1809, 32717,
-2009, 32705, -2210, 32692, -2410, 32678, -2611, 32663, -2811, 32646, -3012, 32628, -3212, 32609,
-3412, 32589, -3612, 32567, -3811, 32545, -4011, 32521, -4210, 32495, -4410, 32469, -4609, 32441,
-4808, 32412, -5007, 32382, -5205, 32351, -5404, 32318, -5602, 32285, -5800, 32250, -5998, 32213,
-6195, 32176, -6393, 32137, -6590, 32098, -6786, 32057, -6983, 32014, -7179, 31971, -7375, 31926,
-7571, 31880, -7767, 31833, -7962, 31785, -8157, 31736, -8351, 31685, -8545, 31633, -8739, 31580,
-8933, 31526, -9126, 31470, -9319, 31414, -9512, 31356, -9704, 31297, -9896, 31237, -10087, 31176,
-10278, 31113, -10469, 31050, -10659, 30985, -10849, 30919, -11039, 30852, -11228, 30783, -11417, 30714,
-11605, 30643, -11793, 30571, -11980, 30498, -12167, 30424, -12353, 30349, -12539, 30273, -12725, 30195,
-12910, 30117, -13094, 30037, -13279, 29956, -13462, 29874, -13645, 29791, -13828, 29706, -14010, 29621,
-14191, 29534, -14372, 29447, -14553, 29358, -14732, 29268, -14912, 29177, -15090, 29085, -15269, 28992,
-15446, 28898, -15623, 28803, -15800, 28706, -15976, 28609, -16151, 28510, -16325, 28411, -16499, 28310,
-16673, 28208, -16846, 28105, -17018, 28001, -17189, 27896, -17360, 27790, -17530, 27683, -17700, 27575,
-17869, 27466, -18037, 27356, -18204, 27245, -18371, 27133, -18537, 27019, -18703, 26905, -18868, 26790,
-19032, 26674, -19195, 26556, -19357, 26438, -19519, 26319, -19680, 26198, -19841, 26077, -20000, 25955,
-20159, 25832, -20317, 25708, -20475, 25582, -20631, 25456, -20787, 25329, -20942, 25201, -21096, 25072,
-21250, 24942, -21403, 24811, -21554, 24680, -21705, 24547, -21856, 24413, -22005, 24279, -22154, 24143,
-22301, 24007, -22448, 23870, -22594, 23731, -22739, 23592, -22884, 23452, -23027, 23311, -23170, 23170,
-23311, 23027, -23452, 22884, -23592, 22739, -23731, 22594, -23870, 22448, -24007, 22301, -24143, 22154,
-24279, 22005, -24413, 21856, -24547, 21705, -24680, 21554, -24811, 21403, -24942, 21250, -25072, 21096,
-25201, 20942, -25329, 20787, -25456, 20631, -25582, 20475, -25708, 20317, -25832, 20159, -25955, 20000,
-26077, 19841, -26198, 19680, -26319, 19519, -26438, 19357, -26556, 19195, -26674, 19032, -26790, 18868,
-26905, 18703, -27019, 18537, -27133, 18371, -27245, 18204, -27356, 18037, -27466, 17869, -27575, 17700,
-27683, 17530, -27790, 17360, -27896, 17189, -28001, 17018, -28105, 16846, -28208, 16673, -28310, 16499,
-28411, 16325, -28510, 16151, -28609, 15976, -28706, 15800, -28803, 15623, -28898, 15446, -28992, 15269,
-29085, 15090, -29177, 14912, -29268, 14732, -29358, 14553, -29447, 14372, -29534, 14191, -29621, 14010,
-29706, 13828, -29791, 13645, -29874, 13462, -29956, 13279, -30037, 13094, -30117, 12910, -30195, 12725,
-30273, 12539, -30349, 12353, -30424, 12167, -30498, 11980, -30571, 11793, -30643, 11605, -30714, 11417,
-30783, 11228, -30852, 11039, -30919, 10849, -30985, 10659, -31050, 10469, -31113, 10278, -31176, 10087,
-31237, 9896, -31297, 9704, -31356, 9512, -31414, 9319, -31470, 9126, -31526, 8933, -31580, 8739,
-31633, 8545, -31685, 8351, -31736, 8157, -31785, 7962, -31833, 7767, -31880, 7571, -31926, 7375,
-31971, 7179, -32014, 6983, -32057, 6786, -32098, 6590, -32137, 6393, -32176, 6195, -32213, 5998,
-32250, 5800, -32285, 5602, -32318, 5404, -32351, 5205, -32382, 5007, -32412, 4808, -32441, 4609,
-32469, 4410, -32495, 4210, -32521, 4011, -32545, 3811, -32567, 3612, -32589, 3412, -32609, 3212,
-32628, 3012, -32646, 2811, -32663, 2611, -32678, 2410, -32692, 2210, -32705, 2009, -32717, 1809,
-32728, 1608, -32737, 1407, -32745, 1206, -32752, 1005, -32757, 804, -32761, 603, -32765, 402,
-32766, 201, -32767, 0, -32766, -201, -32765, -402, -32761, -603, -32757, -804, -32752, -1005,
-32745, -1206, -32737, -1407, -32728, -1608, -32717, -1809, -32705, -2009, -32692, -2210, -32678, -2410,
-32663, -2611, -32646, -2811, -32628, -3012, -32609, -3212, -32589, -3412, -32567, -3612, -32545, -3811,
-32521, -4011, -32495, -4210, -32469, -4410, -32441, -4609, -32412, -4808, -32382, -5007, -32351, -5205,
-32318, -5404, -32285, -5602, -32250, -5800, -32213, -5998, -32176, -6195, -32137, -6393, -32098, -6590,
-32057, -6786, -32014, -6983, -31971, -7179, -31926, -7375, -31880, -7571, -31833, -7767, -31785, -7962,
-31736, -8157, -31685, -8351, -31633, -8545, -31580, -8739, -31526, -8933, -31470, -9126, -31414, -9319,
-31356, -9512, -31297, -9704, -31237, -9896, -31176, -10087, -31113, -10278, -31050, -10469, -30985, -10659,
-30919, -10849, -30852, -11039, -30783, -11228, -30714, -11417, -30643, -11605, -30571, -11793, -30498, -11980,
-30424, -12167, -30349, -12353, -30273, -12539, -30195, -12725, -30117, -12910, -30037, -13094, -29956, -13279,
-29874, -13462, -29791, -13645, -29706, -13828, -29621, -14010, -29534, -14191, -29447, -14372, -29358, -14553,
-29268, -14732, -29177, -14912, -29085, -15090, -28992, -15269, -28898, -15446, -28803, -15623, -28706, -15800,
-28609, -15976, -28510, -16151, -28411, -16325, -28310, -16499, -28208, -16673, -28105, -16846, -28001, -17018,
-27896, -17189, -27790, -17360, -27683, -17530, -27575, -17700, -27466, -17869, -27356, -18037, -27245, -18204,
-27133, -18371, -27019, -18537, -26905, -18703, -26790, -18868, -26674, -19032, -26556, -19195, -26438, -19357,
-26319, -19519, -26198, -19680, -26077, -19841, -25955, -20000, -25832, -20159, -25708, -20317, -25582, -20475,
-25456, -20631, -25329, -20787, -25201, -20942, -25072, -21096, -24942, -21250, -24811, -21403, -24680, -21554,
-24547, -21705, -24413, -21856, -24279, -22005, -24143, -22154, -24007, -22301, -23870, -22448, -23731, -22594,
-23592, -22739, -23452, -22884, -23311, -23027, -23170, -23170, -23027, -23311, -22884, -23452, -22739, -23592,
-22594, -23731, -22448, -23870, -22301, -24007, -22154, -24143, -22005, -24279, -21856, -24413, -21705, -24547,
-21554, -24680, -21403, -24811, -21250, -24942, -21096, -25072, -20942, -25201, -20787, -25329, -20631, -25456,
-20475, -25582, -20317, -25708, -20159, -25832, -20000, -25955, -19841, -26077, -19680, -26198, -19519, -26319,
-19357, -26438, -19195, -26556, -19032, -26674, -18868, -26790, -18703, -26905, -18537, -27019, -18371, -27133,
-18204, -27245, -18037, -27356, -17869, -27466, -17700, -27575, -17530, -27683, -17360, -27790, -17189, -27896,
-17018, -28001, -16846, -28105, -16673, -28208, -16499, -28310, -16325, -28411, -16151, -28510, -15976, -28609,
-15800, -28706, -15623, -28803, -15446, -28898, -15269, -28992, -15090, -29085, -14912, -29177, -14732, -29268,
-14553, -29358, -14372, -29447, -14191, -29534, -14010, -29621, -13828, -29706, -13645, -29791, -13462, -29874,
-13279, -29956, -13094, -30037, -12910, -30117, -12725, -30195, -12539, -30273, -12353, -30349, -12167, -30424,
-11980, -30498, -11793, -30571, -11605, -30643, -11417, -30714, -11228, -30783, -11039, -30852, -10849, -30919,
-10659, -30985, -10469, -31050, -10278, -31113, -10087, -31176, -9896, -31237, -9704, -31297, -9512, -31356,
-9319, -31414, -9126, -31470, -8933, -31526, -8739, -31580, -8545, -31633, -8351, -31685, -8157, -31736,
-7962, -31785, -7767, -31833, -7571, -31880, -7375, -31926, -7179, -31971, -6983, -32014, -6786, -32057,
-6590, -32098, -6393, -32137, -6195, -32176, -5998, -32213, -5800, -32250, -5602, -32285, -5404, -32318,
-5205, -32351, -5007, -32382, -4808, -32412, -4609, -32441, -4410, -32469, -4210, -32495, -4011, -32521,
-3811, -32545, -3612, -32567, -3412, -32589, -3212, -32609, -3012, -32628, -2811, -32646, -2611, -32663,
-2410, -32678, -2210, -32692, -2009, -32705, -1809, -32717, -1608, -32728, -1407, -32737, -1206, -32745,
-1005, -32752, -804, -32757, -603, -32761, -402, -32765, -201, -32766};
extern const uint16_t bitrevTable[];
extern const q15_t rotCoef[];

135
src/fft/fft.c Normal file
View File

@ -0,0 +1,135 @@
#include "fft/fft.h"
#include "fft/table.h"
#include "inttypes.h"
#include "math.h"
#include "stdlib.h"
#define Re(x) 2 * x
#define Im(x) 2 * x + 1
static inline void bitreversal(q31_t *data, uint16_t len, uint16_t *bitrev, uint16_t step) {
q31_t tmp;
uint16_t n1 = len >> 1;
uint16_t n2 = n1 + 1;
for (uint16_t i = 0, j = 0; i <= (n1 - 2); i += 2) {
if (i < j) {
tmp = data[i];
data[i] = data[j];
data[j] = tmp;
tmp = data[i + n2];
data[i + n2] = data[j + n2];
data[j + n2] = tmp;
}
tmp = data[i + 1];
data[i + 1] = data[j + n1];
data[j + n1] = tmp;
j = *bitrev;
bitrev += step;
}
}
static inline void butterfly(q15_t *data, uint16_t len, uint16_t step) {
q15_t xt, yt, cosv, sinv;
for (uint16_t m = len; m > 1; m = m >> 1) {
uint16_t n1 = m;
uint16_t n2 = m >> 1;
for (uint16_t i = 0, ia = 0; i < n2; i++) {
cosv = rotCoef[ia * 2];
sinv = rotCoef[ia * 2 + 1];
ia = ia + step;
for (uint16_t j = i, k; j < len; j += n1) {
k = j + n2;
if (m == len) {
xt = (data[Re(j)] >> 2u) - (data[Re(k)] >> 2u);
yt = (data[Im(j)] >> 2u) - (data[Im(k)] >> 2u);
data[Re(j)] = (q15_t)(((data[Re(j)] >> 2u) + (data[Re(k)] >> 2u)) >> 1);
data[Im(j)] = (q15_t)(((data[Im(k)] >> 2u) + (data[Im(j)] >> 2u)) >> 1);
data[Re(k)] = ((((q31_t)xt * cosv) >> 16)) + ((((q31_t)yt * sinv) >> 16));
data[Im(k)] = ((((q31_t)yt * cosv) >> 16)) - ((((q31_t)xt * sinv) >> 16));
} else if (m == 2) {
xt = data[Re(j)] - data[Re(k)];
yt = data[Im(j)] - data[Im(k)];
data[Re(j)] = data[Re(j)] + data[Re(k)];
data[Im(j)] = data[Im(k)] + data[Im(j)];
data[Re(k)] = xt;
data[Im(k)] = yt;
} else {
xt = data[Re(j)] - data[Re(k)];
yt = data[Im(j)] - data[Im(k)];
data[Re(j)] = (q15_t)((data[Re(j)] + data[Re(k)]) >> 1);
data[Im(j)] = (q15_t)((data[Im(k)] + data[Im(j)]) >> 1);
data[Re(k)] = ((((q31_t)xt * cosv) >> 16)) + ((((q31_t)yt * sinv) >> 16));
data[Im(k)] = ((((q31_t)yt * cosv) >> 16)) - ((((q31_t)xt * sinv) >> 16));
}
}
}
step = step << 1;
}
}
static inline void applyWindow(q15_t *src, const q15_t *window, uint16_t len) {
while (len--) {
*src = (q15_t)(((q31_t)(*src) * (*window)) >> 15);
src++;
window++;
}
}
int FFT(q15_t *data, uint16_t len) {
uint16_t step;
uint16_t *bitrev;
q15_t out[len * 2];
switch (len) {
case 1024u:
step = 1u;
bitrev = (uint16_t *)&bitrevTable[0];
applyWindow(data, hanning_1024, 1024);
break;
case 512u:
step = 2u;
bitrev = (uint16_t *)&bitrevTable[1];
applyWindow(data, hanning_512, 512);
break;
case 256u:
step = 4u;
bitrev = (uint16_t *)&bitrevTable[3];
applyWindow(data, hanning_256, 256);
break;
case 128u:
step = 8u;
bitrev = (uint16_t *)&bitrevTable[7];
applyWindow(data, hanning_128, 128);
break;
default:
return -1;
break;
}
for (uint16_t i = 0; i < len; i++) {
out[Re(i)] = data[i]; // real
out[Im(i)] = 0; // imaginary
}
butterfly(out, len, step);
bitreversal((q31_t *)out, len, bitrev, step);
for (uint16_t i = 0; i < len; i++) data[i] = (q15_t)abs(out[2 * i]);
return 0;
}

284
src/fft/table.c Normal file
View File

@ -0,0 +1,284 @@
#include "fft/table.h"
const q15_t hanning_128[] = {
0, 20, 80, 180, 319, 498, 716, 972, 1266, 1597, 1964, 2366, 2803, 3273, 3775, 4308,
4870, 5461, 6078, 6720, 7386, 8075, 8783, 9510, 10254, 11013, 11785, 12568, 13361, 14161, 14966, 15775,
16586, 17396, 18203, 19006, 19803, 20591, 21369, 22134, 22886, 23622, 24340, 25038, 25716, 26370, 27000, 27604,
28181, 28729, 29246, 29732, 30186, 30605, 30990, 31339, 31652, 31927, 32164, 32362, 32521, 32641, 32721, 32761,
32761, 32721, 32641, 32521, 32362, 32164, 31927, 31652, 31339, 30990, 30605, 30186, 29732, 29246, 28729, 28181,
27604, 27000, 26370, 25716, 25038, 24340, 23622, 22886, 22134, 21369, 20591, 19803, 19006, 18203, 17396, 16586,
15775, 14966, 14161, 13361, 12568, 11785, 11013, 10254, 9510, 8783, 8075, 7386, 6720, 6078, 5461, 4870,
4308, 3775, 3273, 2803, 2366, 1964, 1597, 1266, 972, 716, 498, 319, 180, 80, 20, 0,
};
const q15_t hanning_256[] = {
0, 4, 19, 44, 79, 124, 178, 243, 317, 401, 494, 598, 710, 833, 965, 1106,
1256, 1416, 1585, 1762, 1949, 2144, 2348, 2561, 2782, 3011, 3248, 3493, 3746, 4007, 4275, 4551,
4834, 5124, 5420, 5724, 6033, 6349, 6672, 7000, 7333, 7673, 8017, 8367, 8721, 9080, 9444, 9812,
10183, 10559, 10938, 11320, 11706, 12094, 12485, 12878, 13273, 13671, 14070, 14470, 14871, 15274, 15677, 16080,
16484, 16888, 17291, 17694, 18096, 18496, 18896, 19294, 19691, 20085, 20477, 20867, 21253, 21637, 22018, 22395,
22769, 23139, 23505, 23866, 24223, 24575, 24922, 25264, 25600, 25931, 26256, 26575, 26888, 27195, 27495, 27788,
28074, 28354, 28626, 28890, 29147, 29396, 29638, 29871, 30096, 30313, 30521, 30720, 30911, 31094, 31267, 31431,
31586, 31732, 31868, 31996, 32113, 32221, 32320, 32408, 32488, 32557, 32616, 32666, 32706, 32735, 32755, 32765,
32765, 32755, 32735, 32706, 32666, 32616, 32557, 32488, 32408, 32320, 32221, 32113, 31996, 31868, 31732, 31586,
31431, 31267, 31094, 30911, 30720, 30521, 30313, 30096, 29871, 29638, 29396, 29147, 28890, 28626, 28354, 28074,
27788, 27495, 27195, 26888, 26575, 26256, 25931, 25600, 25264, 24922, 24575, 24223, 23866, 23505, 23139, 22769,
22395, 22018, 21637, 21253, 20867, 20477, 20085, 19691, 19294, 18896, 18496, 18096, 17694, 17291, 16888, 16484,
16080, 15677, 15274, 14871, 14470, 14070, 13671, 13273, 12878, 12485, 12094, 11706, 11320, 10938, 10559, 10183,
9812, 9444, 9080, 8721, 8367, 8017, 7673, 7333, 7000, 6672, 6349, 6033, 5724, 5420, 5124, 4834,
4551, 4275, 4007, 3746, 3493, 3248, 3011, 2782, 2561, 2348, 2144, 1949, 1762, 1585, 1416, 1256,
1106, 965, 833, 710, 598, 494, 401, 317, 243, 178, 124, 79, 44, 19, 4, 0,
};
const q15_t hanning_512[] = {
0, 1, 4, 11, 19, 30, 44, 60, 79, 100, 123, 149, 178, 208, 242, 277,
316, 356, 399, 445, 492, 543, 595, 650, 708, 767, 830, 894, 961, 1030, 1102, 1175,
1251, 1330, 1410, 1493, 1579, 1666, 1756, 1847, 1941, 2038, 2136, 2237, 2339, 2444, 2551, 2660,
2771, 2884, 2999, 3117, 3236, 3357, 3480, 3605, 3732, 3861, 3992, 4125, 4259, 4396, 4534, 4674,
4816, 4959, 5105, 5252, 5400, 5551, 5703, 5856, 6011, 6168, 6326, 6486, 6647, 6810, 6974, 7140,
7307, 7475, 7645, 7816, 7989, 8162, 8337, 8513, 8690, 8869, 9048, 9229, 9411, 9594, 9778, 9962,
10148, 10335, 10523, 10711, 10901, 11091, 11282, 11474, 11666, 11860, 12054, 12248, 12443, 12639, 12836, 13033,
13230, 13428, 13626, 13825, 14024, 14224, 14424, 14624, 14824, 15025, 15226, 15427, 15628, 15829, 16030, 16232,
16433, 16635, 16836, 17038, 17239, 17440, 17641, 17842, 18042, 18242, 18442, 18642, 18841, 19040, 19239, 19437,
19635, 19832, 20029, 20225, 20420, 20615, 20810, 21003, 21196, 21388, 21580, 21770, 21960, 22149, 22337, 22525,
22711, 22896, 23080, 23264, 23446, 23627, 23807, 23986, 24164, 24341, 24517, 24691, 24864, 25035, 25206, 25375,
25543, 25709, 25874, 26037, 26199, 26360, 26519, 26677, 26832, 26987, 27140, 27291, 27440, 27588, 27734, 27879,
28021, 28162, 28301, 28439, 28574, 28708, 28839, 28969, 29097, 29223, 29348, 29470, 29590, 29708, 29824, 29939,
30051, 30161, 30269, 30375, 30478, 30580, 30679, 30777, 30872, 30965, 31056, 31144, 31230, 31314, 31396, 31476,
31553, 31628, 31700, 31771, 31839, 31904, 31968, 32029, 32087, 32144, 32197, 32249, 32298, 32344, 32389, 32430,
32470, 32507, 32541, 32573, 32603, 32630, 32655, 32677, 32697, 32714, 32729, 32741, 32751, 32759, 32764, 32766,
32766, 32764, 32759, 32751, 32741, 32729, 32714, 32697, 32677, 32655, 32630, 32603, 32573, 32541, 32507, 32470,
32430, 32389, 32344, 32298, 32249, 32197, 32144, 32087, 32029, 31968, 31904, 31839, 31771, 31700, 31628, 31553,
31476, 31396, 31314, 31230, 31144, 31056, 30965, 30872, 30777, 30679, 30580, 30478, 30375, 30269, 30161, 30051,
29939, 29824, 29708, 29590, 29470, 29348, 29223, 29097, 28969, 28839, 28708, 28574, 28439, 28301, 28162, 28021,
27879, 27734, 27588, 27440, 27291, 27140, 26987, 26832, 26677, 26519, 26360, 26199, 26037, 25874, 25709, 25543,
25375, 25206, 25035, 24864, 24691, 24517, 24341, 24164, 23986, 23807, 23627, 23446, 23264, 23080, 22896, 22711,
22525, 22337, 22149, 21960, 21770, 21580, 21388, 21196, 21003, 20810, 20615, 20420, 20225, 20029, 19832, 19635,
19437, 19239, 19040, 18841, 18642, 18442, 18242, 18042, 17842, 17641, 17440, 17239, 17038, 16836, 16635, 16433,
16232, 16030, 15829, 15628, 15427, 15226, 15025, 14824, 14624, 14424, 14224, 14024, 13825, 13626, 13428, 13230,
13033, 12836, 12639, 12443, 12248, 12054, 11860, 11666, 11474, 11282, 11091, 10901, 10711, 10523, 10335, 10148,
9962, 9778, 9594, 9411, 9229, 9048, 8869, 8690, 8513, 8337, 8162, 7989, 7816, 7645, 7475, 7307,
7140, 6974, 6810, 6647, 6486, 6326, 6168, 6011, 5856, 5703, 5551, 5400, 5252, 5105, 4959, 4816,
4674, 4534, 4396, 4259, 4125, 3992, 3861, 3732, 3605, 3480, 3357, 3236, 3117, 2999, 2884, 2771,
2660, 2551, 2444, 2339, 2237, 2136, 2038, 1941, 1847, 1756, 1666, 1579, 1493, 1410, 1330, 1251,
1175, 1102, 1030, 961, 894, 830, 767, 708, 650, 595, 543, 492, 445, 399, 356, 316,
277, 242, 208, 178, 149, 123, 100, 79, 60, 44, 30, 19, 11, 4, 1, 0,
};
const q15_t hanning_1024[] = {
0, 0, 1, 2, 4, 7, 11, 15, 19, 25, 30, 37, 44, 52, 60, 69,
79, 89, 100, 111, 123, 136, 149, 163, 177, 192, 208, 224, 241, 259, 277, 296,
315, 335, 355, 377, 398, 421, 444, 467, 491, 516, 542, 568, 594, 621, 649, 677,
706, 736, 766, 797, 828, 860, 892, 925, 959, 993, 1028, 1063, 1099, 1136, 1173, 1211,
1249, 1288, 1327, 1367, 1408, 1449, 1491, 1533, 1576, 1619, 1663, 1707, 1752, 1798, 1844, 1891,
1938, 1986, 2034, 2083, 2132, 2182, 2232, 2283, 2335, 2387, 2439, 2493, 2546, 2600, 2655, 2710,
2766, 2822, 2879, 2936, 2994, 3052, 3111, 3170, 3230, 3290, 3351, 3412, 3474, 3536, 3599, 3662,
3725, 3789, 3854, 3919, 3985, 4051, 4117, 4184, 4252, 4319, 4388, 4456, 4526, 4595, 4665, 4736,
4807, 4878, 4950, 5023, 5095, 5168, 5242, 5316, 5390, 5465, 5540, 5616, 5692, 5769, 5845, 5923,
6000, 6078, 6157, 6236, 6315, 6394, 6474, 6555, 6635, 6716, 6798, 6880, 6962, 7044, 7127, 7210,
7294, 7378, 7462, 7547, 7631, 7717, 7802, 7888, 7974, 8061, 8148, 8235, 8322, 8410, 8498, 8586,
8675, 8764, 8853, 8943, 9033, 9123, 9213, 9304, 9395, 9486, 9577, 9669, 9761, 9853, 9945, 10038,
10131, 10224, 10317, 10411, 10505, 10599, 10693, 10787, 10882, 10977, 11072, 11167, 11263, 11359, 11454, 11550,
11647, 11743, 11840, 11936, 12033, 12130, 12228, 12325, 12423, 12520, 12618, 12716, 12814, 12913, 13011, 13110,
13208, 13307, 13406, 13505, 13604, 13703, 13803, 13902, 14002, 14101, 14201, 14301, 14401, 14500, 14600, 14700,
14801, 14901, 15001, 15101, 15202, 15302, 15402, 15503, 15603, 15704, 15805, 15905, 16006, 16106, 16207, 16308,
16408, 16509, 16609, 16710, 16811, 16911, 17012, 17112, 17213, 17313, 17414, 17514, 17615, 17715, 17815, 17915,
18015, 18116, 18216, 18316, 18415, 18515, 18615, 18715, 18814, 18914, 19013, 19112, 19211, 19311, 19409, 19508,
19607, 19706, 19804, 19902, 20001, 20099, 20197, 20294, 20392, 20490, 20587, 20684, 20781, 20878, 20975, 21071,
21167, 21264, 21360, 21455, 21551, 21646, 21742, 21837, 21931, 22026, 22120, 22214, 22308, 22402, 22495, 22589,
22682, 22775, 22867, 22959, 23051, 23143, 23235, 23326, 23417, 23508, 23598, 23688, 23778, 23868, 23957, 24046,
24135, 24224, 24312, 24400, 24487, 24575, 24662, 24748, 24835, 24921, 25007, 25092, 25177, 25262, 25346, 25430,
25514, 25597, 25680, 25763, 25845, 25927, 26009, 26090, 26171, 26252, 26332, 26411, 26491, 26570, 26648, 26727,
26805, 26882, 26959, 27036, 27112, 27188, 27263, 27338, 27413, 27487, 27561, 27634, 27707, 27780, 27852, 27923,
27995, 28065, 28136, 28206, 28275, 28344, 28412, 28481, 28548, 28615, 28682, 28748, 28814, 28879, 28944, 29009,
29073, 29136, 29199, 29261, 29323, 29385, 29446, 29506, 29566, 29626, 29685, 29743, 29801, 29859, 29916, 29972,
30028, 30083, 30138, 30193, 30247, 30300, 30353, 30405, 30457, 30508, 30559, 30609, 30659, 30708, 30756, 30804,
30852, 30899, 30945, 30991, 31036, 31081, 31125, 31169, 31212, 31254, 31296, 31338, 31379, 31419, 31459, 31498,
31536, 31574, 31612, 31648, 31685, 31720, 31755, 31790, 31824, 31857, 31890, 31922, 31954, 31985, 32015, 32045,
32074, 32103, 32131, 32158, 32185, 32211, 32237, 32262, 32287, 32311, 32334, 32357, 32379, 32400, 32421, 32441,
32461, 32480, 32498, 32516, 32533, 32550, 32566, 32581, 32596, 32610, 32624, 32637, 32649, 32661, 32672, 32682,
32692, 32702, 32710, 32718, 32726, 32732, 32739, 32744, 32749, 32753, 32757, 32760, 32763, 32765, 32766, 32766,
32766, 32766, 32765, 32763, 32760, 32757, 32753, 32749, 32744, 32739, 32732, 32726, 32718, 32710, 32702, 32692,
32682, 32672, 32661, 32649, 32637, 32624, 32610, 32596, 32581, 32566, 32550, 32533, 32516, 32498, 32480, 32461,
32441, 32421, 32400, 32379, 32357, 32334, 32311, 32287, 32262, 32237, 32211, 32185, 32158, 32131, 32103, 32074,
32045, 32015, 31985, 31954, 31922, 31890, 31857, 31824, 31790, 31755, 31720, 31685, 31648, 31612, 31574, 31536,
31498, 31459, 31419, 31379, 31338, 31296, 31254, 31212, 31169, 31125, 31081, 31036, 30991, 30945, 30899, 30852,
30804, 30756, 30708, 30659, 30609, 30559, 30508, 30457, 30405, 30353, 30300, 30247, 30193, 30138, 30083, 30028,
29972, 29916, 29859, 29801, 29743, 29685, 29626, 29566, 29506, 29446, 29385, 29323, 29261, 29199, 29136, 29073,
29009, 28944, 28879, 28814, 28748, 28682, 28615, 28548, 28481, 28412, 28344, 28275, 28206, 28136, 28065, 27995,
27923, 27852, 27780, 27707, 27634, 27561, 27487, 27413, 27338, 27263, 27188, 27112, 27036, 26959, 26882, 26805,
26727, 26648, 26570, 26491, 26411, 26332, 26252, 26171, 26090, 26009, 25927, 25845, 25763, 25680, 25597, 25514,
25430, 25346, 25262, 25177, 25092, 25007, 24921, 24835, 24748, 24662, 24575, 24487, 24400, 24312, 24224, 24135,
24046, 23957, 23868, 23778, 23688, 23598, 23508, 23417, 23326, 23235, 23143, 23051, 22959, 22867, 22775, 22682,
22589, 22495, 22402, 22308, 22214, 22120, 22026, 21931, 21837, 21742, 21646, 21551, 21455, 21360, 21264, 21167,
21071, 20975, 20878, 20781, 20684, 20587, 20490, 20392, 20294, 20197, 20099, 20001, 19902, 19804, 19706, 19607,
19508, 19409, 19311, 19211, 19112, 19013, 18914, 18814, 18715, 18615, 18515, 18415, 18316, 18216, 18116, 18015,
17915, 17815, 17715, 17615, 17514, 17414, 17313, 17213, 17112, 17012, 16911, 16811, 16710, 16609, 16509, 16408,
16308, 16207, 16106, 16006, 15905, 15805, 15704, 15603, 15503, 15402, 15302, 15202, 15101, 15001, 14901, 14801,
14700, 14600, 14500, 14401, 14301, 14201, 14101, 14002, 13902, 13803, 13703, 13604, 13505, 13406, 13307, 13208,
13110, 13011, 12913, 12814, 12716, 12618, 12520, 12423, 12325, 12228, 12130, 12033, 11936, 11840, 11743, 11647,
11550, 11454, 11359, 11263, 11167, 11072, 10977, 10882, 10787, 10693, 10599, 10505, 10411, 10317, 10224, 10131,
10038, 9945, 9853, 9761, 9669, 9577, 9486, 9395, 9304, 9213, 9123, 9033, 8943, 8853, 8764, 8675,
8586, 8498, 8410, 8322, 8235, 8148, 8061, 7974, 7888, 7802, 7717, 7631, 7547, 7462, 7378, 7294,
7210, 7127, 7044, 6962, 6880, 6798, 6716, 6635, 6555, 6474, 6394, 6315, 6236, 6157, 6078, 6000,
5923, 5845, 5769, 5692, 5616, 5540, 5465, 5390, 5316, 5242, 5168, 5095, 5023, 4950, 4878, 4807,
4736, 4665, 4595, 4526, 4456, 4388, 4319, 4252, 4184, 4117, 4051, 3985, 3919, 3854, 3789, 3725,
3662, 3599, 3536, 3474, 3412, 3351, 3290, 3230, 3170, 3111, 3052, 2994, 2936, 2879, 2822, 2766,
2710, 2655, 2600, 2546, 2493, 2439, 2387, 2335, 2283, 2232, 2182, 2132, 2083, 2034, 1986, 1938,
1891, 1844, 1798, 1752, 1707, 1663, 1619, 1576, 1533, 1491, 1449, 1408, 1367, 1327, 1288, 1249,
1211, 1173, 1136, 1099, 1063, 1028, 993, 959, 925, 892, 860, 828, 797, 766, 736, 706,
677, 649, 621, 594, 568, 542, 516, 491, 467, 444, 421, 398, 377, 355, 335, 315,
296, 277, 259, 241, 224, 208, 192, 177, 163, 149, 136, 123, 111, 100, 89, 79,
69, 60, 52, 44, 37, 30, 25, 19, 15, 11, 7, 4, 2, 1, 0, 0,
};
/*
Table for bit reversal process, where N = 4096 logN2 = 12, N is the maximum FFT Size supported
for (l = 1; l <= N / 4; l++) {
for (i = 0; i < logN2; i++) {
a[i] = l & (1 << i);
}
for (j = 0; j < logN2; j++) {
if (a[j] != 0) y[l] += (1 << ((logN2 - 1) - j));
}
y[l] = y[l] >> 1;
}
*/
const uint16_t bitrevTable[256] = {
0x100, 0x80, 0x180, 0x40, 0x140, 0xc0, 0x1c0, 0x20, 0x120, 0xa0, 0x1a0, 0x60, 0x160, 0xe0, 0x1e0, 0x10, 0x110, 0x90,
0x190, 0x50, 0x150, 0xd0, 0x1d0, 0x30, 0x130, 0xb0, 0x1b0, 0x70, 0x170, 0xf0, 0x1f0, 0x8, 0x108, 0x88, 0x188, 0x48,
0x148, 0xc8, 0x1c8, 0x28, 0x128, 0xa8, 0x1a8, 0x68, 0x168, 0xe8, 0x1e8, 0x18, 0x118, 0x98, 0x198, 0x58, 0x158, 0xd8,
0x1d8, 0x38, 0x138, 0xb8, 0x1b8, 0x78, 0x178, 0xf8, 0x1f8, 0x4, 0x104, 0x84, 0x184, 0x44, 0x144, 0xc4, 0x1c4, 0x24,
0x124, 0xa4, 0x1a4, 0x64, 0x164, 0xe4, 0x1e4, 0x14, 0x114, 0x94, 0x194, 0x54, 0x154, 0xd4, 0x1d4, 0x34, 0x134, 0xb4,
0x1b4, 0x74, 0x174, 0xf4, 0x1f4, 0xc, 0x10c, 0x8c, 0x18c, 0x4c, 0x14c, 0xcc, 0x1cc, 0x2c, 0x12c, 0xac, 0x1ac, 0x6c,
0x16c, 0xec, 0x1ec, 0x1c, 0x11c, 0x9c, 0x19c, 0x5c, 0x15c, 0xdc, 0x1dc, 0x3c, 0x13c, 0xbc, 0x1bc, 0x7c, 0x17c, 0xfc,
0x1fc, 0x2, 0x102, 0x82, 0x182, 0x42, 0x142, 0xc2, 0x1c2, 0x22, 0x122, 0xa2, 0x1a2, 0x62, 0x162, 0xe2, 0x1e2, 0x12,
0x112, 0x92, 0x192, 0x52, 0x152, 0xd2, 0x1d2, 0x32, 0x132, 0xb2, 0x1b2, 0x72, 0x172, 0xf2, 0x1f2, 0xa, 0x10a, 0x8a,
0x18a, 0x4a, 0x14a, 0xca, 0x1ca, 0x2a, 0x12a, 0xaa, 0x1aa, 0x6a, 0x16a, 0xea, 0x1ea, 0x1a, 0x11a, 0x9a, 0x19a, 0x5a,
0x15a, 0xda, 0x1da, 0x3a, 0x13a, 0xba, 0x1ba, 0x7a, 0x17a, 0xfa, 0x1fa, 0x6, 0x106, 0x86, 0x186, 0x46, 0x146, 0xc6,
0x1c6, 0x26, 0x126, 0xa6, 0x1a6, 0x66, 0x166, 0xe6, 0x1e6, 0x16, 0x116, 0x96, 0x196, 0x56, 0x156, 0xd6, 0x1d6, 0x36,
0x136, 0xb6, 0x1b6, 0x76, 0x176, 0xf6, 0x1f6, 0xe, 0x10e, 0x8e, 0x18e, 0x4e, 0x14e, 0xce, 0x1ce, 0x2e, 0x12e, 0xae,
0x1ae, 0x6e, 0x16e, 0xee, 0x1ee, 0x1e, 0x11e, 0x9e, 0x19e, 0x5e, 0x15e, 0xde, 0x1de, 0x3e, 0x13e, 0xbe, 0x1be, 0x7e,
0x17e, 0xfe, 0x1fe, 0x1,
};
/*
Example code for q15 Twiddle factors Generation::
for (i = 0; i < 3N / 4; i++) {
rotCoef[2 * i] = cos(i * 2 * PI / (float)N);
rotCoef[2 * i + 1] = sin(i * 2 * PI / (float)N);
}
where N = 1024 and PI = 3.14159265358979, Cos and Sin values are interleaved fashion
Convert Floating point to int16 round(rotCoef(i) * pow(2, 15))
*/
const q15_t rotCoef[1536] = {
32767, 0, 32766, 201, 32765, 402, 32761, 603, 32757, 804, 32752, 1005, 32745, 1206,
32737, 1407, 32728, 1608, 32717, 1809, 32705, 2009, 32692, 2210, 32678, 2410, 32663, 2611,
32646, 2811, 32628, 3012, 32609, 3212, 32589, 3412, 32567, 3612, 32545, 3811, 32521, 4011,
32495, 4210, 32469, 4410, 32441, 4609, 32412, 4808, 32382, 5007, 32351, 5205, 32318, 5404,
32285, 5602, 32250, 5800, 32213, 5998, 32176, 6195, 32137, 6393, 32098, 6590, 32057, 6786,
32014, 6983, 31971, 7179, 31926, 7375, 31880, 7571, 31833, 7767, 31785, 7962, 31736, 8157,
31685, 8351, 31633, 8545, 31580, 8739, 31526, 8933, 31470, 9126, 31414, 9319, 31356, 9512,
31297, 9704, 31237, 9896, 31176, 10087, 31113, 10278, 31050, 10469, 30985, 10659, 30919, 10849,
30852, 11039, 30783, 11228, 30714, 11417, 30643, 11605, 30571, 11793, 30498, 11980, 30424, 12167,
30349, 12353, 30273, 12539, 30195, 12725, 30117, 12910, 30037, 13094, 29956, 13279, 29874, 13462,
29791, 13645, 29706, 13828, 29621, 14010, 29534, 14191, 29447, 14372, 29358, 14553, 29268, 14732,
29177, 14912, 29085, 15090, 28992, 15269, 28898, 15446, 28803, 15623, 28706, 15800, 28609, 15976,
28510, 16151, 28411, 16325, 28310, 16499, 28208, 16673, 28105, 16846, 28001, 17018, 27896, 17189,
27790, 17360, 27683, 17530, 27575, 17700, 27466, 17869, 27356, 18037, 27245, 18204, 27133, 18371,
27019, 18537, 26905, 18703, 26790, 18868, 26674, 19032, 26556, 19195, 26438, 19357, 26319, 19519,
26198, 19680, 26077, 19841, 25955, 20000, 25832, 20159, 25708, 20317, 25582, 20475, 25456, 20631,
25329, 20787, 25201, 20942, 25072, 21096, 24942, 21250, 24811, 21403, 24680, 21554, 24547, 21705,
24413, 21856, 24279, 22005, 24143, 22154, 24007, 22301, 23870, 22448, 23731, 22594, 23592, 22739,
23452, 22884, 23311, 23027, 23170, 23170, 23027, 23311, 22884, 23452, 22739, 23592, 22594, 23731,
22448, 23870, 22301, 24007, 22154, 24143, 22005, 24279, 21856, 24413, 21705, 24547, 21554, 24680,
21403, 24811, 21250, 24942, 21096, 25072, 20942, 25201, 20787, 25329, 20631, 25456, 20475, 25582,
20317, 25708, 20159, 25832, 20000, 25955, 19841, 26077, 19680, 26198, 19519, 26319, 19357, 26438,
19195, 26556, 19032, 26674, 18868, 26790, 18703, 26905, 18537, 27019, 18371, 27133, 18204, 27245,
18037, 27356, 17869, 27466, 17700, 27575, 17530, 27683, 17360, 27790, 17189, 27896, 17018, 28001,
16846, 28105, 16673, 28208, 16499, 28310, 16325, 28411, 16151, 28510, 15976, 28609, 15800, 28706,
15623, 28803, 15446, 28898, 15269, 28992, 15090, 29085, 14912, 29177, 14732, 29268, 14553, 29358,
14372, 29447, 14191, 29534, 14010, 29621, 13828, 29706, 13645, 29791, 13462, 29874, 13279, 29956,
13094, 30037, 12910, 30117, 12725, 30195, 12539, 30273, 12353, 30349, 12167, 30424, 11980, 30498,
11793, 30571, 11605, 30643, 11417, 30714, 11228, 30783, 11039, 30852, 10849, 30919, 10659, 30985,
10469, 31050, 10278, 31113, 10087, 31176, 9896, 31237, 9704, 31297, 9512, 31356, 9319, 31414,
9126, 31470, 8933, 31526, 8739, 31580, 8545, 31633, 8351, 31685, 8157, 31736, 7962, 31785,
7767, 31833, 7571, 31880, 7375, 31926, 7179, 31971, 6983, 32014, 6786, 32057, 6590, 32098,
6393, 32137, 6195, 32176, 5998, 32213, 5800, 32250, 5602, 32285, 5404, 32318, 5205, 32351,
5007, 32382, 4808, 32412, 4609, 32441, 4410, 32469, 4210, 32495, 4011, 32521, 3811, 32545,
3612, 32567, 3412, 32589, 3212, 32609, 3012, 32628, 2811, 32646, 2611, 32663, 2410, 32678,
2210, 32692, 2009, 32705, 1809, 32717, 1608, 32728, 1407, 32737, 1206, 32745, 1005, 32752,
804, 32757, 603, 32761, 402, 32765, 201, 32766, 0, 32767, -201, 32766, -402, 32765,
-603, 32761, -804, 32757, -1005, 32752, -1206, 32745, -1407, 32737, -1608, 32728, -1809, 32717,
-2009, 32705, -2210, 32692, -2410, 32678, -2611, 32663, -2811, 32646, -3012, 32628, -3212, 32609,
-3412, 32589, -3612, 32567, -3811, 32545, -4011, 32521, -4210, 32495, -4410, 32469, -4609, 32441,
-4808, 32412, -5007, 32382, -5205, 32351, -5404, 32318, -5602, 32285, -5800, 32250, -5998, 32213,
-6195, 32176, -6393, 32137, -6590, 32098, -6786, 32057, -6983, 32014, -7179, 31971, -7375, 31926,
-7571, 31880, -7767, 31833, -7962, 31785, -8157, 31736, -8351, 31685, -8545, 31633, -8739, 31580,
-8933, 31526, -9126, 31470, -9319, 31414, -9512, 31356, -9704, 31297, -9896, 31237, -10087, 31176,
-10278, 31113, -10469, 31050, -10659, 30985, -10849, 30919, -11039, 30852, -11228, 30783, -11417, 30714,
-11605, 30643, -11793, 30571, -11980, 30498, -12167, 30424, -12353, 30349, -12539, 30273, -12725, 30195,
-12910, 30117, -13094, 30037, -13279, 29956, -13462, 29874, -13645, 29791, -13828, 29706, -14010, 29621,
-14191, 29534, -14372, 29447, -14553, 29358, -14732, 29268, -14912, 29177, -15090, 29085, -15269, 28992,
-15446, 28898, -15623, 28803, -15800, 28706, -15976, 28609, -16151, 28510, -16325, 28411, -16499, 28310,
-16673, 28208, -16846, 28105, -17018, 28001, -17189, 27896, -17360, 27790, -17530, 27683, -17700, 27575,
-17869, 27466, -18037, 27356, -18204, 27245, -18371, 27133, -18537, 27019, -18703, 26905, -18868, 26790,
-19032, 26674, -19195, 26556, -19357, 26438, -19519, 26319, -19680, 26198, -19841, 26077, -20000, 25955,
-20159, 25832, -20317, 25708, -20475, 25582, -20631, 25456, -20787, 25329, -20942, 25201, -21096, 25072,
-21250, 24942, -21403, 24811, -21554, 24680, -21705, 24547, -21856, 24413, -22005, 24279, -22154, 24143,
-22301, 24007, -22448, 23870, -22594, 23731, -22739, 23592, -22884, 23452, -23027, 23311, -23170, 23170,
-23311, 23027, -23452, 22884, -23592, 22739, -23731, 22594, -23870, 22448, -24007, 22301, -24143, 22154,
-24279, 22005, -24413, 21856, -24547, 21705, -24680, 21554, -24811, 21403, -24942, 21250, -25072, 21096,
-25201, 20942, -25329, 20787, -25456, 20631, -25582, 20475, -25708, 20317, -25832, 20159, -25955, 20000,
-26077, 19841, -26198, 19680, -26319, 19519, -26438, 19357, -26556, 19195, -26674, 19032, -26790, 18868,
-26905, 18703, -27019, 18537, -27133, 18371, -27245, 18204, -27356, 18037, -27466, 17869, -27575, 17700,
-27683, 17530, -27790, 17360, -27896, 17189, -28001, 17018, -28105, 16846, -28208, 16673, -28310, 16499,
-28411, 16325, -28510, 16151, -28609, 15976, -28706, 15800, -28803, 15623, -28898, 15446, -28992, 15269,
-29085, 15090, -29177, 14912, -29268, 14732, -29358, 14553, -29447, 14372, -29534, 14191, -29621, 14010,
-29706, 13828, -29791, 13645, -29874, 13462, -29956, 13279, -30037, 13094, -30117, 12910, -30195, 12725,
-30273, 12539, -30349, 12353, -30424, 12167, -30498, 11980, -30571, 11793, -30643, 11605, -30714, 11417,
-30783, 11228, -30852, 11039, -30919, 10849, -30985, 10659, -31050, 10469, -31113, 10278, -31176, 10087,
-31237, 9896, -31297, 9704, -31356, 9512, -31414, 9319, -31470, 9126, -31526, 8933, -31580, 8739,
-31633, 8545, -31685, 8351, -31736, 8157, -31785, 7962, -31833, 7767, -31880, 7571, -31926, 7375,
-31971, 7179, -32014, 6983, -32057, 6786, -32098, 6590, -32137, 6393, -32176, 6195, -32213, 5998,
-32250, 5800, -32285, 5602, -32318, 5404, -32351, 5205, -32382, 5007, -32412, 4808, -32441, 4609,
-32469, 4410, -32495, 4210, -32521, 4011, -32545, 3811, -32567, 3612, -32589, 3412, -32609, 3212,
-32628, 3012, -32646, 2811, -32663, 2611, -32678, 2410, -32692, 2210, -32705, 2009, -32717, 1809,
-32728, 1608, -32737, 1407, -32745, 1206, -32752, 1005, -32757, 804, -32761, 603, -32765, 402,
-32766, 201, -32767, 0, -32766, -201, -32765, -402, -32761, -603, -32757, -804, -32752, -1005,
-32745, -1206, -32737, -1407, -32728, -1608, -32717, -1809, -32705, -2009, -32692, -2210, -32678, -2410,
-32663, -2611, -32646, -2811, -32628, -3012, -32609, -3212, -32589, -3412, -32567, -3612, -32545, -3811,
-32521, -4011, -32495, -4210, -32469, -4410, -32441, -4609, -32412, -4808, -32382, -5007, -32351, -5205,
-32318, -5404, -32285, -5602, -32250, -5800, -32213, -5998, -32176, -6195, -32137, -6393, -32098, -6590,
-32057, -6786, -32014, -6983, -31971, -7179, -31926, -7375, -31880, -7571, -31833, -7767, -31785, -7962,
-31736, -8157, -31685, -8351, -31633, -8545, -31580, -8739, -31526, -8933, -31470, -9126, -31414, -9319,
-31356, -9512, -31297, -9704, -31237, -9896, -31176, -10087, -31113, -10278, -31050, -10469, -30985, -10659,
-30919, -10849, -30852, -11039, -30783, -11228, -30714, -11417, -30643, -11605, -30571, -11793, -30498, -11980,
-30424, -12167, -30349, -12353, -30273, -12539, -30195, -12725, -30117, -12910, -30037, -13094, -29956, -13279,
-29874, -13462, -29791, -13645, -29706, -13828, -29621, -14010, -29534, -14191, -29447, -14372, -29358, -14553,
-29268, -14732, -29177, -14912, -29085, -15090, -28992, -15269, -28898, -15446, -28803, -15623, -28706, -15800,
-28609, -15976, -28510, -16151, -28411, -16325, -28310, -16499, -28208, -16673, -28105, -16846, -28001, -17018,
-27896, -17189, -27790, -17360, -27683, -17530, -27575, -17700, -27466, -17869, -27356, -18037, -27245, -18204,
-27133, -18371, -27019, -18537, -26905, -18703, -26790, -18868, -26674, -19032, -26556, -19195, -26438, -19357,
-26319, -19519, -26198, -19680, -26077, -19841, -25955, -20000, -25832, -20159, -25708, -20317, -25582, -20475,
-25456, -20631, -25329, -20787, -25201, -20942, -25072, -21096, -24942, -21250, -24811, -21403, -24680, -21554,
-24547, -21705, -24413, -21856, -24279, -22005, -24143, -22154, -24007, -22301, -23870, -22448, -23731, -22594,
-23592, -22739, -23452, -22884, -23311, -23027, -23170, -23170, -23027, -23311, -22884, -23452, -22739, -23592,
-22594, -23731, -22448, -23870, -22301, -24007, -22154, -24143, -22005, -24279, -21856, -24413, -21705, -24547,
-21554, -24680, -21403, -24811, -21250, -24942, -21096, -25072, -20942, -25201, -20787, -25329, -20631, -25456,
-20475, -25582, -20317, -25708, -20159, -25832, -20000, -25955, -19841, -26077, -19680, -26198, -19519, -26319,
-19357, -26438, -19195, -26556, -19032, -26674, -18868, -26790, -18703, -26905, -18537, -27019, -18371, -27133,
-18204, -27245, -18037, -27356, -17869, -27466, -17700, -27575, -17530, -27683, -17360, -27790, -17189, -27896,
-17018, -28001, -16846, -28105, -16673, -28208, -16499, -28310, -16325, -28411, -16151, -28510, -15976, -28609,
-15800, -28706, -15623, -28803, -15446, -28898, -15269, -28992, -15090, -29085, -14912, -29177, -14732, -29268,
-14553, -29358, -14372, -29447, -14191, -29534, -14010, -29621, -13828, -29706, -13645, -29791, -13462, -29874,
-13279, -29956, -13094, -30037, -12910, -30117, -12725, -30195, -12539, -30273, -12353, -30349, -12167, -30424,
-11980, -30498, -11793, -30571, -11605, -30643, -11417, -30714, -11228, -30783, -11039, -30852, -10849, -30919,
-10659, -30985, -10469, -31050, -10278, -31113, -10087, -31176, -9896, -31237, -9704, -31297, -9512, -31356,
-9319, -31414, -9126, -31470, -8933, -31526, -8739, -31580, -8545, -31633, -8351, -31685, -8157, -31736,
-7962, -31785, -7767, -31833, -7571, -31880, -7375, -31926, -7179, -31971, -6983, -32014, -6786, -32057,
-6590, -32098, -6393, -32137, -6195, -32176, -5998, -32213, -5800, -32250, -5602, -32285, -5404, -32318,
-5205, -32351, -5007, -32382, -4808, -32412, -4609, -32441, -4410, -32469, -4210, -32495, -4011, -32521,
-3811, -32545, -3612, -32567, -3412, -32589, -3212, -32609, -3012, -32628, -2811, -32646, -2611, -32663,
-2410, -32678, -2210, -32692, -2009, -32705, -1809, -32717, -1608, -32728, -1407, -32737, -1206, -32745,
-1005, -32752, -804, -32757, -603, -32761, -402, -32765, -201, -32766};