|
| 1 | +/* Copyright 2021 The TensorFlow Authors. All Rights Reserved. |
| 2 | +
|
| 3 | +Licensed under the Apache License, Version 2.0 (the "License"); |
| 4 | +you may not use this file except in compliance with the License. |
| 5 | +You may obtain a copy of the License at |
| 6 | +
|
| 7 | + http://www.apache.org/licenses/LICENSE-2.0 |
| 8 | +
|
| 9 | +Unless required by applicable law or agreed to in writing, software |
| 10 | +distributed under the License is distributed on an "AS IS" BASIS, |
| 11 | +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| 12 | +See the License for the specific language governing permissions and |
| 13 | +limitations under the License. |
| 14 | +==============================================================================*/ |
| 15 | +#include <stddef.h> |
| 16 | +#include <stdint.h> |
| 17 | +#include <string.h> |
| 18 | + |
| 19 | +#include "signal/src/msb.h" |
| 20 | +#include "signal/src/rfft.h" |
| 21 | + |
| 22 | +// Do not reorder these headers. "typedef.h" must appear before rfft.h |
| 23 | +#include "typedef.h" |
| 24 | +extern "C" { |
| 25 | +#include "rfft.h" |
| 26 | +} |
| 27 | + |
| 28 | +namespace tflm_signal { |
| 29 | + |
| 30 | +// TODO(b/467010877) The twiddle tables should come from the tflite file |
| 31 | +// This array includes the first 3*512/4=384 elements in the twiddle table in: |
| 32 | +// HEXAGON_Tools/<TOOL_VERSION>/Examples/libcore/SigProc/cxFFT_IFFT/include |
| 33 | +const uint16_t twiddles[] __attribute__((aligned(8))) = { |
| 34 | + 0x7fff, 0x0000, 0x0000, 0x8000, 0x0000, 0x8000, 0x0000, 0x8000, 0xa57e, |
| 35 | + 0xa57e, 0xa57e, 0x5a82, 0x5a82, 0xa57e, 0xcf05, 0x89bf, 0x89bf, 0xcf05, |
| 36 | + 0xa57e, 0xa57e, 0x89bf, 0xcf05, 0x30fc, 0x7642, 0x7642, 0xcf05, 0xe708, |
| 37 | + 0x8276, 0xb8e4, 0x9593, 0xcf05, 0x89bf, 0x9593, 0xb8e4, 0xe708, 0x7d8a, |
| 38 | + 0x30fc, 0x89bf, 0xb8e4, 0x9593, 0x8276, 0x18f9, 0x89bf, 0xcf05, 0x8276, |
| 39 | + 0xe708, 0x6a6e, 0x471d, 0x7d8a, 0xe708, 0xf375, 0x809e, 0xdad8, 0x8583, |
| 40 | + 0xe708, 0x8276, 0x9d0e, 0xaecd, 0xc3aa, 0x70e3, 0x471d, 0x9593, 0xc3aa, |
| 41 | + 0x8f1e, 0x809e, 0xf375, 0x9593, 0xb8e4, 0x8583, 0xdad8, 0x5134, 0x62f2, |
| 42 | + 0x6a6e, 0xb8e4, 0xdad8, 0x8583, 0x9d0e, 0xaecd, 0xb8e4, 0x9593, 0x8f1e, |
| 43 | + 0xc3aa, 0x0c8c, 0x7f62, 0x18f9, 0x8276, 0xaecd, 0x9d0e, 0x8f1e, 0x3c57, |
| 44 | + 0x8276, 0xe708, 0x809e, 0xf375, 0x7a7d, 0x2528, 0x7f62, 0xf375, 0xf9b9, |
| 45 | + 0x8028, 0xed38, 0x8163, 0xf375, 0x809e, 0xa129, 0xaa0b, 0xb3c1, 0x66d0, |
| 46 | + 0x5134, 0x9d0e, 0xc946, 0x8c4b, 0x83d7, 0xe0e7, 0x9d0e, 0xaecd, 0x877c, |
| 47 | + 0xd4e1, 0x41ce, 0x6dca, 0x70e3, 0xc3aa, 0xe0e7, 0x83d7, 0xaa0b, 0xa129, |
| 48 | + 0xc3aa, 0x8f1e, 0x9236, 0xbe32, 0xf9b9, 0x7fd9, 0x2528, 0x8583, 0xb3c1, |
| 49 | + 0x9931, 0x877c, 0x2b1f, 0x8583, 0xdad8, 0x8163, 0xed38, 0x73b6, 0x36ba, |
| 50 | + 0x7a7d, 0xdad8, 0xed38, 0x8163, 0xc946, 0x8c4b, 0xdad8, 0x8583, 0x9931, |
| 51 | + 0xb3c1, 0xd4e1, 0x7885, 0x3c57, 0x8f1e, 0xbe32, 0x9236, 0x8028, 0x0648, |
| 52 | + 0x8f1e, 0xc3aa, 0x83d7, 0xe0e7, 0x5ed7, 0x55f6, 0x62f2, 0xaecd, 0xd4e1, |
| 53 | + 0x877c, 0x9236, 0xbe32, 0xaecd, 0x9d0e, 0x8c4b, 0xc946, 0x1f1a, 0x7c2a, |
| 54 | + 0x0c8c, 0x809e, 0xaa0b, 0xa129, 0x9931, 0x4c40, 0x809e, 0xf375, 0x8028, |
| 55 | + 0xf9b9, 0x7e9d, 0x12c8, 0x7fd9, 0xf9b9, 0xfcdc, 0x800a, 0xf696, 0x8059, |
| 56 | + 0xf9b9, 0x8028, 0xa34c, 0xa7be, 0xac65, 0x60ec, 0x55f6, 0xa129, 0xcc22, |
| 57 | + 0x8afc, 0x8676, 0xd7da, 0xa129, 0xaa0b, 0x8894, 0xd1ef, 0x398d, 0x7255, |
| 58 | + 0x73b6, 0xc946, 0xe3f5, 0x831d, 0xb141, 0x9b18, 0xc946, 0x8c4b, 0x93dc, |
| 59 | + 0xbb86, 0xf055, 0x7f0a, 0x2b1f, 0x877c, 0xb64c, 0x975a, 0x84a3, 0x2224, |
| 60 | + 0x877c, 0xd4e1, 0x81e3, 0xea1e, 0x6f5f, 0x3f17, 0x7c2a, 0xe0e7, 0xf055, |
| 61 | + 0x80f7, 0xd1ef, 0x8894, 0xe0e7, 0x83d7, 0x9b18, 0xb141, 0xcc22, 0x7505, |
| 62 | + 0x41ce, 0x9236, 0xc0e9, 0x90a1, 0x800a, 0xfcdc, 0x9236, 0xbe32, 0x84a3, |
| 63 | + 0xdddd, 0x5843, 0x5cb4, 0x66d0, 0xb3c1, 0xd7da, 0x8676, 0x975a, 0xb64c, |
| 64 | + 0xb3c1, 0x9931, 0x8dab, 0xc674, 0x15e2, 0x7e1e, 0x12c8, 0x8163, 0xac65, |
| 65 | + 0x9f14, 0x93dc, 0x447b, 0x8163, 0xed38, 0x8059, 0xf696, 0x7ce4, 0x1c0c, |
| 66 | + 0x7e9d, 0xed38, 0xf696, 0x8059, 0xe3f5, 0x831d, 0xed38, 0x8163, 0x9f14, |
| 67 | + 0xac65, 0xbb86, 0x6c24, 0x4c40, 0x9931, 0xc674, 0x8dab, 0x81e3, 0xea1e, |
| 68 | + 0x9931, 0xb3c1, 0x8676, 0xd7da, 0x49b4, 0x68a7, 0x6dca, 0xbe32, 0xdddd, |
| 69 | + 0x84a3, 0xa34c, 0xa7be, 0xbe32, 0x9236, 0x90a1, 0xc0e9, 0x0324, 0x7ff6, |
| 70 | + 0x1f1a, 0x83d7, 0xb141, 0x9b18, 0x8afc, 0x33df, 0x83d7, 0xe0e7, 0x80f7, |
| 71 | + 0xf055, 0x776c, 0x2e11, 0x7885, 0xd4e1, 0xea1e, 0x81e3, 0xc0e9, 0x90a1, |
| 72 | + 0xd4e1, 0x877c, 0x975a, 0xb64c, 0xdddd, 0x7b5d, 0x36ba, 0x8c4b, 0xbb86, |
| 73 | + 0x93dc, 0x80f7, 0x0fab, 0x8c4b, 0xc946, 0x831d, 0xe3f5, 0x64e9, 0x4ec0, |
| 74 | + 0x5ed7, 0xaa0b, 0xd1ef, 0x8894, 0x8dab, 0xc674, 0xaa0b, 0xa129, 0x8afc, |
| 75 | + 0xcc22, 0x2827, 0x798a, 0x0648, 0x8028, 0xa7be, 0xa34c, 0x9f14, 0x539b, |
| 76 | + 0x8028, 0xf9b9, 0x800a, 0xfcdc, 0x7fa7, 0x096b, 0x7ff6, 0xfcdc, 0xfe6e, |
| 77 | + 0x8003, 0xfb4a, 0x8017, 0xfcdc, 0x800a, 0xa463, 0xa69c, 0xa8e3, 0x5dc8, |
| 78 | + 0x5843, 0xa34c, 0xcd92, 0x8a5b, 0x8806, 0xd368, 0xa34c, 0xa7be, 0x8927, |
| 79 | + 0xd079, 0x354e, 0x7460, 0x7505, 0xcc22, 0xe57e, 0x82c7, 0xb505, 0x9843, |
| 80 | + 0xcc22, 0x8afc, 0x94b6, 0xba33, 0xebab, 0x7e60, 0x2e11, 0x8894, 0xb797, |
| 81 | + 0x9674, 0x8377, 0x1d93, 0x8894, 0xd1ef, 0x822a, 0xe893, 0x6cf9, 0x4326, |
| 82 | + 0x7ce4, 0xe3f5, 0xf1e5, 0x80c8, 0xd65d, 0x86f7, 0xe3f5, 0x831d, 0x9c11, |
| 83 | + 0xb005, 0xc7dc, 0x7308, 0x447b, 0x93dc, 0xc248, 0x8fdd, 0x803e, 0xf827, |
| 84 | + 0x93dc, 0xbb86, 0x8511, 0xdc5a, 0x54ca, 0x5fe4, 0x68a7, 0xb64c, 0xd958, |
| 85 | + 0x85fb, 0x9a23, 0xb27f, 0xb64c, 0x975a, 0x8e62, 0xc50e, 0x113a, 0x7ed6, |
| 86 | + 0x15e2, 0x81e3, 0xad97, 0x9e0f, 0x916a, 0x4074, 0x81e3, 0xea1e, 0x8079, |
| 87 | + 0xf505, 0x7bc6, 0x209f, 0x7f0a, 0xf055, 0xf827, 0x803e, 0xe893, 0x822a, |
| 88 | + 0xf055, 0x80f7, 0xa01d, 0xab36, 0xb797, 0x698c, 0x4ec0, 0x9b18, 0xc7dc, |
| 89 | + 0x8cf9, 0x82c7, 0xe57e, 0x9b18, 0xb141, 0x86f7, 0xd65d, 0x45cd, 0x6b4b, |
| 90 | + 0x6f5f, 0xc0e9, 0xdf61, 0x843b, 0xa69c, 0xa463, 0xc0e9, 0x90a1, 0x916a, |
| 91 | + 0xbf8d, 0xfe6e, 0x7ffe, 0x2224, 0x84a3, 0xb27f, 0x9a23, 0x8927, 0x2f87, |
| 92 | + 0x84a3, 0xdddd, 0x812b, 0xeec7, 0x75a6, 0x326e, 0x798a, 0xd7da, 0xebab, |
| 93 | + 0x81a1, 0xc50e, 0x8e62, 0xd7da, 0x8676, 0x9843, 0xb505, 0xd958, 0x7a06, |
| 94 | + 0x398d, 0x8dab, 0xbcdb, 0x9307, 0x8079, 0x0afb, 0x8dab, 0xc674, 0x8377, |
| 95 | + 0xe26d, 0x61f1, 0x5269, 0x60ec, 0xac65, 0xd368, 0x8806, 0x8fdd, 0xc248, |
| 96 | + 0xac65, 0x9f14, 0x8ba1, 0xcab3, 0x23a7, 0x7aef, 0x096b, 0x8059, 0xa8e3, |
| 97 | + 0xa239, 0x9c11, 0x4ffb, 0x8059, 0xf696, 0x8017, 0xfb4a, 0x7f38, 0x0e1c, |
| 98 | + 0x7fa7, 0xf696, 0xfb4a, 0x8017, 0xf1e5, 0x80c8, 0xf696, 0x8059, 0xa239, |
| 99 | + 0xa8e3, 0xb005, 0x63ef, 0x539b, 0x9f14, 0xcab3, 0x8ba1, 0x8511, 0xdc5a, |
| 100 | + 0x9f14, 0xac65, 0x8806, 0xd368, 0x3db8, 0x7023, 0x7255, 0xc674, 0xe26d, |
| 101 | + 0x8377, 0xad97, 0x9e0f, 0xc674, 0x8dab, 0x9307, 0xbcdb, 0xf505, 0x7f87, |
| 102 | + 0x2827, 0x8676, 0xb505, 0x9843, 0x85fb, 0x26a8, 0x8676, 0xd7da, 0x81a1, |
| 103 | + 0xebab, 0x719e, 0x3af3, 0x7b5d, 0xdddd, 0xeec7, 0x812b, 0xcd92, 0x8a5b, |
| 104 | + 0xdddd, 0x84a3, 0x9a23, 0xb27f, 0xd079, 0x76d9, 0x3f17, 0x90a1, 0xbf8d, |
| 105 | + 0x916a, 0x8003, 0x0192, 0x90a1, 0xc0e9, 0x843b, 0xdf61, 0x5b9d, 0x5964, |
| 106 | + 0x64e9, 0xb141, 0xd65d, 0x86f7, 0x94b6, 0xba33, 0xb141, 0x9b18, 0x8cf9, |
| 107 | + 0xc7dc, 0x1a83, 0x7d3a, 0x0fab, 0x80f7, 0xab36, 0xa01d, 0x9674, 0x486a, |
| 108 | + 0x80f7, 0xf055, 0x803e, 0xf827, 0x7dd6, 0x176e, 0x7e1e, 0xea1e, 0xf505, |
| 109 | + 0x8079, 0xdf61, 0x843b, 0xea1e, 0x81e3, 0x9e0f, 0xad97, 0xbf8d, 0x6e97, |
| 110 | + 0x49b4, 0x975a, 0xc50e, 0x8e62, 0x812b, 0xeec7, 0x975a, 0xb64c, 0x85fb, |
| 111 | + 0xd958, 0x4d81, 0x65de, 0x6c24, 0xbb86, 0xdc5a, 0x8511, 0xa01d, 0xab36, |
| 112 | + 0xbb86, 0x93dc, 0x8fdd, 0xc248, 0x07d9, 0x7fc2, 0x1c0c, 0x831d, 0xb005, |
| 113 | + 0x9c11, 0x8cf9, 0x3825, 0x831d, 0xe3f5, 0x80c8, 0xf1e5, 0x790a, 0x29a4, |
| 114 | + 0x776c, 0xd1ef, 0xe893, 0x822a, 0xbcdb, 0x9307, 0xd1ef, 0x8894, 0x9674, |
| 115 | + 0xb797, 0xe26d, 0x7c89, 0x33df, 0x8afc, 0xba33, 0x94b6, 0x81a1, 0x1455, |
| 116 | + 0x8afc, 0xcc22, 0x82c7, 0xe57e, 0x67bd, 0x4afb, 0x5cb4, 0xa7be, 0xd079, |
| 117 | + 0x8927, 0x8ba1, 0xcab3, 0xa7be, 0xa34c, 0x8a5b, 0xcd92, 0x2c99, 0x77fb, |
| 118 | + 0x0324, 0x800a, 0xa69c, 0xa463, 0xa239, 0x571e, 0x800a, 0xfcdc, 0x8003, |
| 119 | + 0xfe6e, 0x7fea, 0x04b6}; |
| 120 | + |
| 121 | +// Twiddle factors used for the last stage of N-point real FFT |
| 122 | +// generated as j*W^k, k=1, 2, ... N/4 |
| 123 | +// That's 128 complex int16_t elements |
| 124 | +// Or 256 real int16_t elements |
| 125 | +const uint16_t rtwiddles[] __attribute__((aligned(8))) = { |
| 126 | + 0x0192, 0x7ffe, 0x0324, 0x7ff6, 0x04b6, 0x7fea, 0x0648, 0x7fd9, 0x07d9, |
| 127 | + 0x7fc2, 0x096b, 0x7fa7, 0x0afb, 0x7f87, 0x0c8c, 0x7f62, 0x0e1c, 0x7f38, |
| 128 | + 0x0fab, 0x7f0a, 0x113a, 0x7ed6, 0x12c8, 0x7e9d, 0x1455, 0x7e60, 0x15e2, |
| 129 | + 0x7e1e, 0x176e, 0x7dd6, 0x18f9, 0x7d8a, 0x1a83, 0x7d3a, 0x1c0c, 0x7ce4, |
| 130 | + 0x1d93, 0x7c89, 0x1f1a, 0x7c2a, 0x209f, 0x7bc6, 0x2224, 0x7b5d, 0x23a7, |
| 131 | + 0x7aef, 0x2528, 0x7a7d, 0x26a8, 0x7a06, 0x2827, 0x798a, 0x29a4, 0x790a, |
| 132 | + 0x2b1f, 0x7885, 0x2c99, 0x77fb, 0x2e11, 0x776c, 0x2f87, 0x76d9, 0x30fc, |
| 133 | + 0x7642, 0x326e, 0x75a6, 0x33df, 0x7505, 0x354e, 0x7460, 0x36ba, 0x73b6, |
| 134 | + 0x3825, 0x7308, 0x398d, 0x7255, 0x3af3, 0x719e, 0x3c57, 0x70e3, 0x3db8, |
| 135 | + 0x7023, 0x3f17, 0x6f5f, 0x4074, 0x6e97, 0x41ce, 0x6dca, 0x4326, 0x6cf9, |
| 136 | + 0x447b, 0x6c24, 0x45cd, 0x6b4b, 0x471d, 0x6a6e, 0x486a, 0x698c, 0x49b4, |
| 137 | + 0x68a7, 0x4afb, 0x67bd, 0x4c40, 0x66d0, 0x4d81, 0x65de, 0x4ec0, 0x64e9, |
| 138 | + 0x4ffb, 0x63ef, 0x5134, 0x62f2, 0x5269, 0x61f1, 0x539b, 0x60ec, 0x54ca, |
| 139 | + 0x5fe4, 0x55f6, 0x5ed7, 0x571e, 0x5dc8, 0x5843, 0x5cb4, 0x5964, 0x5b9d, |
| 140 | + 0x5a82, 0x5a82, 0x5b9d, 0x5964, 0x5cb4, 0x5843, 0x5dc8, 0x571e, 0x5ed7, |
| 141 | + 0x55f6, 0x5fe4, 0x54ca, 0x60ec, 0x539b, 0x61f1, 0x5269, 0x62f2, 0x5134, |
| 142 | + 0x63ef, 0x4ffb, 0x64e9, 0x4ec0, 0x65de, 0x4d81, 0x66d0, 0x4c40, 0x67bd, |
| 143 | + 0x4afb, 0x68a7, 0x49b4, 0x698c, 0x486a, 0x6a6e, 0x471d, 0x6b4b, 0x45cd, |
| 144 | + 0x6c24, 0x447b, 0x6cf9, 0x4326, 0x6dca, 0x41ce, 0x6e97, 0x4074, 0x6f5f, |
| 145 | + 0x3f17, 0x7023, 0x3db8, 0x70e3, 0x3c57, 0x719e, 0x3af3, 0x7255, 0x398d, |
| 146 | + 0x7308, 0x3825, 0x73b6, 0x36ba, 0x7460, 0x354e, 0x7505, 0x33df, 0x75a6, |
| 147 | + 0x326e, 0x7642, 0x30fc, 0x76d9, 0x2f87, 0x776c, 0x2e11, 0x77fb, 0x2c99, |
| 148 | + 0x7885, 0x2b1f, 0x790a, 0x29a4, 0x798a, 0x2827, 0x7a06, 0x26a8, 0x7a7d, |
| 149 | + 0x2528, 0x7aef, 0x23a7, 0x7b5d, 0x2224, 0x7bc6, 0x209f, 0x7c2a, 0x1f1a, |
| 150 | + 0x7c89, 0x1d93, 0x7ce4, 0x1c0c, 0x7d3a, 0x1a83, 0x7d8a, 0x18f9, 0x7dd6, |
| 151 | + 0x176e, 0x7e1e, 0x15e2, 0x7e60, 0x1455, 0x7e9d, 0x12c8, 0x7ed6, 0x113a, |
| 152 | + 0x7f0a, 0x0fab, 0x7f38, 0x0e1c, 0x7f62, 0x0c8c, 0x7f87, 0x0afb, 0x7fa7, |
| 153 | + 0x096b, 0x7fc2, 0x07d9, 0x7fd9, 0x0648, 0x7fea, 0x04b6, 0x7ff6, 0x0324, |
| 154 | + 0x7ffe, 0x0192, 0x7fff, 0x0000}; |
| 155 | + |
| 156 | +struct RfftState { |
| 157 | + int16_t* aligned_input; |
| 158 | + int32_t fft_length; |
| 159 | +}; |
| 160 | + |
| 161 | +size_t RfftInt16GetNeededMemory(int32_t fft_length) { |
| 162 | + return sizeof(RfftState) + 2 * sizeof(int16_t) * fft_length; |
| 163 | +} |
| 164 | + |
| 165 | +void* RfftInt16Init(int32_t fft_length, void* state, size_t state_size) { |
| 166 | + RfftState* rfft_state = (RfftState*)state; |
| 167 | + int16_t* unaligned_buffer = (int16_t*)(rfft_state + 1); |
| 168 | + rfft_state->aligned_input = |
| 169 | + (int16_t*)((uint32_t)(unaligned_buffer + fft_length) & |
| 170 | + ~((1 << tflite::tflm_signal::MostSignificantBit32( |
| 171 | + fft_length)) - |
| 172 | + 1)); |
| 173 | + rfft_state->fft_length = fft_length; |
| 174 | + return state; |
| 175 | +} |
| 176 | + |
| 177 | +void RfftInt16Apply(void* state, const int16_t* input, |
| 178 | + Complex<int16_t>* output) { |
| 179 | + RfftState* rfft_state = (RfftState*)state; |
| 180 | + memcpy(rfft_state->aligned_input, input, |
| 181 | + rfft_state->fft_length * sizeof(int16_t)); |
| 182 | + rfft(rfft_state->aligned_input, rfft_state->fft_length, (CWord2x16*)twiddles, |
| 183 | + (CWord2x16*)rtwiddles, (CWord2x16*)output); |
| 184 | + return; |
| 185 | +} |
| 186 | + |
| 187 | +} // namespace tflm_signal |
0 commit comments