diff --git a/include/fft/fft.h b/include/fft/fft.h index 5347005..95143f5 100644 --- a/include/fft/fft.h +++ b/include/fft/fft.h @@ -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); \ No newline at end of file diff --git a/include/fft/table.h b/include/fft/table.h index eb94efa..9590fb9 100644 --- a/include/fft/table.h +++ b/include/fft/table.h @@ -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}; \ No newline at end of file +extern const uint16_t bitrevTable[]; +extern const q15_t rotCoef[]; diff --git a/src/fft/fft.c b/src/fft/fft.c new file mode 100644 index 0000000..e3290d2 --- /dev/null +++ b/src/fft/fft.c @@ -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; +} diff --git a/src/fft/table.c b/src/fft/table.c new file mode 100644 index 0000000..67c23f6 --- /dev/null +++ b/src/fft/table.c @@ -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}; \ No newline at end of file