FastLED 3.9.15
Loading...
Searching...
No Matches

◆ getFFT()

shared_ptr< const fft::Bins > fl::audio::Context::getFFT ( int bands = 16,
float fmin = fft::Args::DefaultMinFrequency(),
float fmax = fft::Args::DefaultMaxFrequency(),
fft::Mode mode = fft::Mode::AUTO,
fft::Window window = fft::Window::BLACKMAN_HARRIS )

Definition at line 35 of file audio_context.cpp.hpp.

35 {
36 fft::Args args(mSample.size(), bands, fmin, fmax, mSampleRate, mode, window);
37
38 // O(1) cache lookup using hash map
39 fl::size argsHash = hashFFTArgs(args);
40 auto it = mFFTCacheMap.find(argsHash);
41 if (it != mFFTCacheMap.end()) {
42 int idx = it->second;
43 if (idx >= 0 && idx < static_cast<int>(mFFTCache.size())) {
44 // Double-check args match in case of hash collision
45 if (mFFTCache[idx].args == args) {
46 return mFFTCache[idx].bins;
47 }
48 }
49 }
50
51 // Not cached — try to recycle a previously-used fft::Bins with matching band count
52 shared_ptr<fft::Bins> bins;
53 for (size i = 0; i < mRecyclePool.size(); i++) {
54 if (static_cast<int>(mRecyclePool[i]->bands()) == bands) {
55 bins = fl::move(mRecyclePool[i]);
56 mRecyclePool.erase(mRecyclePool.begin() + i);
57 bins->clear(); // Vectors keep capacity — zero allocs
58 break;
59 }
60 }
61 if (!bins) {
62 bins = fl::make_shared<fft::Bins>(bands);
63 }
64
65 fl::span<const fl::i16> sample = mSample.pcm();
66 mFFT.run(sample, bins.get(), args);
67
68 // Evict oldest if at capacity
69 if (static_cast<int>(mFFTCache.size()) >= MAX_FFT_CACHE_ENTRIES) {
70 // Remove the oldest entry's hash from hash map
71 fl::size oldHash = hashFFTArgs(mFFTCache[0].args);
72 mFFTCacheMap.erase(oldHash);
73
74 // Shift all remaining entries and update map indices
75 for (size i = 1; i < mFFTCache.size(); i++) {
76 fl::size key = hashFFTArgs(mFFTCache[i].args);
77 mFFTCacheMap[key] = static_cast<int>(i - 1);
78 }
79 mFFTCache.erase(mFFTCache.begin());
80 }
81
82 FFTCacheEntry entry;
83 entry.args = args;
84 entry.bins = bins;
85 int newIndex = static_cast<int>(mFFTCache.size());
86 mFFTCache.push_back(fl::move(entry));
87
88 // Add to hash map for O(1) future lookups
89 mFFTCacheMap[argsHash] = newIndex;
90
91 return bins;
92}
flat_map< fl::size, int > mFFTCacheMap
vector< FFTCacheEntry > mFFTCache
static constexpr int MAX_FFT_CACHE_ENTRIES
vector< shared_ptr< fft::Bins > > mRecyclePool
static fl::size hashFFTArgs(const fft::Args &args) FL_NOEXCEPT
constexpr remove_reference< T >::type && move(T &&t) FL_NOEXCEPT
Definition s16x16x4.h:28
CRGB sample(const CRGB *grid, const XYMap &xyMap, float x, float y, SampleMode mode)
Sample a pixel from a 2D CRGB grid at floating-point coordinates.
Definition sample.cpp.hpp:9
shared_ptr< T > make_shared(Args &&... args) FL_NOEXCEPT
Definition shared_ptr.h:414
corkscrew_args args
Definition old.h:149

References Context(), args, fl::audio::Context::FFTCacheEntry::args, fl::audio::Context::FFTCacheEntry::bins, fl::shared_ptr< T >::get(), getFFT(), hashFFTArgs(), fl::make_shared(), MAX_FFT_CACHE_ENTRIES, mFFT, mFFTCache, mFFTCacheMap, fl::fl::move(), mRecyclePool, mSample, mSampleRate, and fl::sample().

Referenced by getBandEnergy(), getFFT(), and getFFT16().

+ Here is the call graph for this function:
+ Here is the caller graph for this function: