80#include "platforms/is_platform.h"
98#if defined(FL_IS_ESP32) && FL_HAS_INCLUDE("esp_dsp.h")
99#define FL_FFT_ESP_DSP_AVAILABLE 1
105#define FL_FFT_ESP_DSP_AVAILABLE 0
108#define FL_FFT_ESP_DSP_ACTIVE FL_FFT_ESP_DSP_AVAILABLE
114#if FL_FFT_ESP_DSP_AVAILABLE
124struct EspDspRealCtx {
132 static EspDspRealCtx ctx;
137 static bool initialized =
false;
138 if (initialized)
return true;
140 dsps_fft2r_init_fc32(
nullptr, CONFIG_DSP_MAX_FFT_SIZE);
142 FL_WARN(
"dsps_fft2r_init_fc32 failed: " <<
static_cast<int>(err));
149inline bool espDspEnsureTwiddles(
int N)
FL_NOEXCEPT {
150 EspDspRealCtx &ctx = espDspRealCtx();
151 if (ctx.n == N)
return true;
152 if (!espDspGlobalInit())
return false;
154 ctx.cos_table.resize(N / 2 - 1);
155 ctx.sin_table.resize(N / 2 - 1);
156 const float twoPi = 6.28318530717958647692f;
157 const float invN = 1.0f /
static_cast<float>(N);
158 for (
int k = 1; k < N / 2; ++k) {
159 float th = twoPi *
static_cast<float>(k) * invN;
160 ctx.cos_table[k - 1] = ::cosf(th);
161 ctx.sin_table[k - 1] = ::sinf(th);
182inline void espDspRealForward(
int N,
const float *in,
184 if (!espDspEnsureTwiddles(N))
return;
185 EspDspRealCtx &ctx = espDspRealCtx();
190 for (
int k = 0; k < N / 2; ++k) {
191 ctx.work[2 * k] = in[2 * k];
192 ctx.work[2 * k + 1] = in[2 * k + 1];
196 dsps_fft2r_fc32(ctx.work.data(), N / 2);
197 dsps_bit_rev_fc32_ansi(ctx.work.data(), N / 2);
200 const float Y0r = ctx.work[0];
201 const float Y0i = ctx.work[1];
202 out[0].
r = Y0r + Y0i;
204 out[N / 2].
r = Y0r - Y0i;
207 for (
int k = 1; k < N / 2; ++k) {
208 const int kp = N / 2 - k;
209 const float Ykr = ctx.work[2 * k];
210 const float Yki = ctx.work[2 * k + 1];
211 const float Ykpr = ctx.work[2 * kp];
212 const float Ykpi = ctx.work[2 * kp + 1];
213 const float a = Ykr - Ykpr;
214 const float b = Yki + Ykpi;
215 const float c = ctx.cos_table[k - 1];
216 const float s = ctx.sin_table[k - 1];
217 out[k].
r = 0.5f * ((Ykr + Ykpr) + c * b - s * a);
218 out[k].
i = 0.5f * ((Yki - Ykpi) - c * a - s * b);
fl::UIAudio audio("Audio Input")
void kiss_fftr(kiss_fftr_cfg st, const kiss_fft_scalar *timedata, kiss_fft_cpx *freqdata) FL_NOEXCEPT
struct kiss_fftr_state * kiss_fftr_cfg
Centralized logging categories for FastLED hardware interfaces and subsystems.
void fl_fft_real_forward(kiss_fftr_cfg cfg, int N, const kiss_fft_scalar *in, kiss_fft_cpx *out) FL_NOEXCEPT
Forward real-to-complex FFT.
Base definition for an LED controller.