ESP-IDF Firmware
Firmware architecture and call graph
Loading...
Searching...
No Matches
dsps_fft2r_fc32_ansi.c
Go to the documentation of this file.
1// Copyright 2018-2019 Espressif Systems (Shanghai) PTE LTD
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 "dsps_fft2r.h"
16#include "dsp_common.h"
17#include "dsp_types.h"
18#include <math.h>
19#include "esp_attr.h"
20#include "esp_log.h"
21#include <string.h>
22#include <malloc.h>
23
24
25static const char *TAG = "fftr2_ansi";
26
31
32uint16_t *dsps_fft2r_ram_rev_table = NULL;
33
34#ifdef CONFIG_IDF_TARGET_ESP32S3
35extern float *dsps_fft2r_w_table_fc32_1024;
36#endif // CONFIG_IDF_TARGET_ESP32S3
37
38unsigned short reverse(unsigned short x, unsigned short N, int order);
39
40esp_err_t dsps_fft2r_init_fc32(float *fft_table_buff, int table_size)
41{
42 esp_err_t result = ESP_OK;
43 if (dsps_fft2r_initialized != 0) {
44 return result;
45 }
46 if (table_size > CONFIG_DSP_MAX_FFT_SIZE) {
48 }
49 if (table_size == 0) {
50 return result;
51 }
52 if (fft_table_buff != NULL) {
55 }
56 dsps_fft_w_table_fc32 = fft_table_buff;
57 dsps_fft_w_table_size = table_size;
58 } else {
60#if CONFIG_IDF_TARGET_ESP32S3
61 if (table_size <= 1024) {
62 dsps_fft_w_table_fc32 = dsps_fft2r_w_table_fc32_1024;
63 } else {
64 dsps_fft_w_table_fc32 = (float *)memalign(16, sizeof(float) * table_size);
65 }
66#else
67 dsps_fft_w_table_fc32 = (float *)malloc(table_size * sizeof(float));
68#endif
69 if (dsps_fft_w_table_fc32 == NULL) {
71 }
72 }
73 dsps_fft_w_table_size = table_size;
75
76 }
77
78 // FFT ram_rev table allocated
79 int pow = dsp_power_of_two(table_size);
80 if ((pow > 3) && (pow < 13)) {
81 dsps_fft2r_ram_rev_table = (uint16_t *)malloc(2 * dsps_fft2r_rev_tables_fc32_size[pow - 4] * sizeof(uint16_t));
82 if (dsps_fft2r_ram_rev_table == NULL) {
84 }
85 memcpy(dsps_fft2r_ram_rev_table, dsps_fft2r_rev_tables_fc32[pow - 4], 2 * dsps_fft2r_rev_tables_fc32_size[pow - 4] * sizeof(uint16_t));
87 }
88
90 if (result != ESP_OK) {
91 return result;
92 }
94 if (result != ESP_OK) {
95 return result;
96 }
98
99 return ESP_OK;
100}
101
103{
105#if CONFIG_IDF_TARGET_ESP32S3
106 if (dsps_fft_w_table_fc32 != dsps_fft2r_w_table_fc32_1024) {
108 }
109#else
111#endif
112 }
113 if (dsps_fft2r_ram_rev_table != NULL) {
116 }
117 // Re init bitrev table for next use
121}
122
123esp_err_t dsps_fft2r_fc32_ansi_(float *data, int N, float *w)
124{
125 if (!dsp_is_power_of_two(N)) {
127 }
130 }
131
132 esp_err_t result = ESP_OK;
133
134 int ie, ia, m;
135 float re_temp, im_temp;
136 float c, s;
137 ie = 1;
138 for (int N2 = N / 2; N2 > 0; N2 >>= 1) {
139 ia = 0;
140 for (int j = 0; j < ie; j++) {
141 c = w[2 * j];
142 s = w[2 * j + 1];
143 for (int i = 0; i < N2; i++) {
144 m = ia + N2;
145 re_temp = c * data[2 * m] + s * data[2 * m + 1];
146 im_temp = c * data[2 * m + 1] - s * data[2 * m];
147 data[2 * m] = data[2 * ia] - re_temp;
148 data[2 * m + 1] = data[2 * ia + 1] - im_temp;
149 data[2 * ia] = data[2 * ia] + re_temp;
150 data[2 * ia + 1] = data[2 * ia + 1] + im_temp;
151 ia++;
152 }
153 ia += N2;
154 }
155 ie <<= 1;
156 }
157 return result;
158}
159
160
161unsigned short reverse(unsigned short x, unsigned short N, int order)
162{
163 unsigned short b = x;
164
165 b = (b & 0xff00) >> 8 | (b & 0x00fF) << 8;
166 b = (b & 0xf0F0) >> 4 | (b & 0x0f0F) << 4;
167 b = (b & 0xCCCC) >> 2 | (b & 0x3333) << 2;
168 b = (b & 0xAAAA) >> 1 | (b & 0x5555) << 1;
169 return b >> (16 - order);
170}
171
173{
174 if (!dsp_is_power_of_two(N)) {
176 }
177
178 esp_err_t result = ESP_OK;
179
180 int j, k;
181 float r_temp, i_temp;
182 j = 0;
183 for (int i = 1; i < (N - 1); i++) {
184 k = N >> 1;
185 while (k <= j) {
186 j -= k;
187 k >>= 1;
188 }
189 j += k;
190 if (i < j) {
191 r_temp = data[j * 2];
192 data[j * 2] = data[i * 2];
193 data[i * 2] = r_temp;
194 i_temp = data[j * 2 + 1];
195 data[j * 2 + 1] = data[i * 2 + 1];
196 data[i * 2 + 1] = i_temp;
197 }
198 }
199 return result;
200}
201
203{
204 if (!dsp_is_power_of_two(N)) {
206 }
207
208 esp_err_t result = ESP_OK;
209
210 int i;
211 float e = M_PI * 2.0 / N;
212
213 for (i = 0; i < (N >> 1); i++) {
214 w[2 * i] = cosf(i * e);
215 w[2 * i + 1] = sinf(i * e);
216 }
217
218 return result;
219}
220
222{
223 if (!dsp_is_power_of_two(N)) {
225 }
226 esp_err_t result = ESP_OK;
227
228 int i;
229 int n2 = N << 1;
230
231 float rkl = 0;
232 float rkh = 0;
233 float rnl = 0;
234 float rnh = 0;
235 float ikl = 0;
236 float ikh = 0;
237 float inl = 0;
238 float inh = 0;
239
240 for (i = 0; i < (N / 4); i++) {
241 rkl = data[i * 2 + 0 + 2];
242 ikl = data[i * 2 + 1 + 2];
243 rnl = data[n2 - i * 2 - 2];
244 inl = data[n2 - i * 2 - 1];
245
246 rkh = data[i * 2 + 0 + 2 + N];
247 ikh = data[i * 2 + 1 + 2 + N];
248 rnh = data[n2 - i * 2 - 2 - N];
249 inh = data[n2 - i * 2 - 1 - N];
250
251 data[i * 2 + 0 + 2] = rkl + rnl;
252 data[i * 2 + 1 + 2] = ikl - inl;
253
254 data[n2 - i * 2 - 1 - N] = inh - ikh;
255 data[n2 - i * 2 - 2 - N] = rkh + rnh;
256
257 data[i * 2 + 0 + 2 + N] = ikl + inl;
258 data[i * 2 + 1 + 2 + N] = rnl - rkl;
259
260 data[n2 - i * 2 - 1] = rkh - rnh;
261 data[n2 - i * 2 - 2] = ikh + inh;
262 }
263 data[N] = data[1];
264 data[1] = 0;
265 data[N + 1] = 0;
266
267 return result;
268}
269
270esp_err_t dsps_gen_bitrev2r_table(int N, int step, char *name_ext)
271{
272 if (!dsp_is_power_of_two(N)) {
274 }
275
276 int j, k;
277 j = 0;
278 int items_count = 0;
279 ESP_LOGD(TAG, "const uint16_t bitrev2r_table_%i_%s[] = { ", N, name_ext);
280 for (int i = 1; i < (N - 1); i++) {
281 k = N >> 1;
282 while (k <= j) {
283 j -= k;
284 k >>= 1;
285 }
286 j += k;
287 if (i < j) {
288 ESP_LOGD(TAG, "%i, %i, ", i * step, j * step);
289 items_count++;
290 if ((items_count % 8) == 0) {
291 ESP_LOGD(TAG, " ");
292 }
293 }
294 }
295 ESP_LOGD(TAG, "};");
296 ESP_LOGD(TAG, "const uint16_t bitrev2r_table_%i_%s_size = %i;\n", N, name_ext, items_count);
297
298 ESP_LOGD(TAG, "extern const uint16_t bitrev2r_table_%i_%s[];", N, name_ext);
299 ESP_LOGD(TAG, "extern const uint16_t bitrev2r_table_%i_%s_size;\n", N, name_ext);
300 return ESP_OK;
301}
302
304{
305 uint16_t *table;
306 uint16_t table_size;
307 switch (N) {
308 case 16:
309 table = (uint16_t *)dsps_fft2r_rev_tables_fc32[0];
310 table_size = dsps_fft2r_rev_tables_fc32_size[0];
311 break;
312 case 32:
313 table = (uint16_t *)dsps_fft2r_rev_tables_fc32[1];
314 table_size = dsps_fft2r_rev_tables_fc32_size[1];
315 break;
316 case 64:
317 table = (uint16_t *)dsps_fft2r_rev_tables_fc32[2];
318 table_size = dsps_fft2r_rev_tables_fc32_size[2];
319 break;
320 case 128:
321 table = (uint16_t *)dsps_fft2r_rev_tables_fc32[3];
322 table_size = dsps_fft2r_rev_tables_fc32_size[3];
323 break;
324 case 256:
325 table = (uint16_t *)dsps_fft2r_rev_tables_fc32[4];
326 table_size = dsps_fft2r_rev_tables_fc32_size[4];
327 break;
328 case 512:
329 table = (uint16_t *)dsps_fft2r_rev_tables_fc32[5];
330 table_size = dsps_fft2r_rev_tables_fc32_size[5];
331 break;
332 case 1024:
333 table = (uint16_t *)dsps_fft2r_rev_tables_fc32[6];
334 table_size = dsps_fft2r_rev_tables_fc32_size[6];
335 break;
336 case 2048:
337 table = (uint16_t *)dsps_fft2r_rev_tables_fc32[7];
338 table_size = dsps_fft2r_rev_tables_fc32_size[7];
339 break;
340 case 4096:
341 table = (uint16_t *)dsps_fft2r_rev_tables_fc32[8];
342 table_size = dsps_fft2r_rev_tables_fc32_size[8];
343 break;
344
345 default:
346 return dsps_bit_rev_fc32(data, N);
347 break;
348 }
349 return dsps_bit_rev_lookup_fc32(data, table_size, table);
350}
351
352esp_err_t dsps_bit_rev_lookup_fc32_ansi(float *data, int reverse_size, uint16_t *reverse_tab)
353{
354 float r_temp, i_temp;
355 for (int n = 0 ; n < reverse_size ; n++) {
356 uint16_t i = reverse_tab[n * 2 + 0] >> 2;
357 uint16_t j = reverse_tab[n * 2 + 1] >> 2;
358 r_temp = data[j];
359 data[j] = data[i];
360 data[i] = r_temp;
361 i_temp = data[j + 1];
362 data[j + 1] = data[i + 1];
363 data[i + 1] = i_temp;
364 }
365 return ESP_OK;
366}
bool dsp_is_power_of_two(int x)
check power of two The function check if the argument is power of 2. The implementation use ANSI C an...
int dsp_power_of_two(int x)
Power of two The function return power of 2 for values 2^N. The implementation use ANSI C and could b...
#define ESP_ERR_DSP_PARAM_OUTOFRANGE
#define ESP_ERR_DSP_UNINITIALIZED
#define ESP_ERR_DSP_INVALID_LENGTH
#define ESP_ERR_DSP_REINITIALIZED
#define memalign(align_, size_)
Definition dsp_tests.h:35
#define dsps_bit_rev_fc32
Definition dsps_fft2r.h:249
#define dsps_bit_rev_lookup_fc32
Definition dsps_fft2r.h:252
#define CONFIG_DSP_MAX_FFT_SIZE
Definition dsps_fft2r.h:24
const uint16_t dsps_fft2r_rev_tables_fc32_size[]
uint16_t * dsps_fft2r_rev_tables_fc32[]
void dsps_fft2r_rev_tables_init_fc32(void)
float * dsps_fft_w_table_fc32
esp_err_t dsps_gen_bitrev2r_table(int N, int step, char *name_ext)
uint8_t dsps_fft2r_mem_allocated
esp_err_t dsps_fft2r_fc32_ansi_(float *data, int N, float *w)
complex FFT of radix 2
void dsps_fft2r_deinit_fc32()
deinit fft tables
esp_err_t dsps_gen_w_r2_fc32(float *w, int N)
Generate coefficients table for the FFT radix 2.
esp_err_t dsps_cplx2reC_fc32_ansi(float *data, int N)
Convert complex array to two real arrays.
uint16_t * dsps_fft2r_ram_rev_table
unsigned short reverse(unsigned short x, unsigned short N, int order)
esp_err_t dsps_fft2r_init_fc32(float *fft_table_buff, int table_size)
init fft tables
uint8_t dsps_fft2r_initialized
esp_err_t dsps_bit_rev_lookup_fc32_ansi(float *data, int reverse_size, uint16_t *reverse_tab)
esp_err_t dsps_bit_rev2r_fc32(float *data, int N)
esp_err_t dsps_bit_rev_fc32_ansi(float *data, int N)
bit reverse operation for the complex input array
int dsps_fft_w_table_size
int esp_err_t
Definition esp_err.h:21
#define ESP_OK
Definition esp_err.h:23
#define M_PI
Definition esp_err.h:26
#define ESP_LOGD
Definition esp_log.h:22
static const char * TAG
Definition main/main.c:31
static float data[128 *2]
Definition test_fft2r.c:34
float x[1024]
Definition test_fir.c:10
#define N
Definition test_mmult.c:13
const int m
Definition test_mmult.c:16
const int n
Definition test_mmult.c:17
const int k
Definition test_mmult.c:18