FastLED 3.10.8
Loading...
Searching...
No Matches
fx_engine.cpp.hpp
Go to the documentation of this file.
1#include "fl/fx/fx_engine.h"
3#include "fl/fx/video.h"
5#include "fl/task/scheduler.h"
6#include "fl/stl/noexcept.h"
7
8namespace fl {
9
10FxEngine::FxEngine(u16 numLeds, bool interpolate)
12 mInterpolate(interpolate) {
14}
15
17
19 mAudioBack.push_back(frame);
20}
21
25
26int FxEngine::addFx(FxPtr effect) FL_NO_EXCEPT {
27 float fps = 0;
28 if (mInterpolate && effect->hasFixedFrameRate(&fps)) {
29 // Wrap the effect in a VideoFxWrapper so that we can get
30 // interpolation.
31 VideoFxWrapperPtr vid_fx = fl::make_shared<VideoFxWrapper>(effect);
32 vid_fx->setFade(0, 0); // No fade for interpolated effects
33 effect = vid_fx;
34 }
35 bool auto_set = mEffects.empty();
36 bool ok = mEffects.insert(mCounter, effect);
37 if (!ok) {
38 return -1;
39 }
40 if (auto_set) {
42 mCompositor.startTransition(0, 0, effect);
43 }
44 return mCounter++;
45}
46
47bool FxEngine::nextFx(u16 duration) FL_NO_EXCEPT {
48 bool ok = mEffects.next(mCurrId, &mCurrId, true);
49 if (!ok) {
50 return false;
51 }
52 setNextFx(mCurrId, duration);
53 return true;
54}
55
56bool FxEngine::setNextFx(int index, u16 duration) FL_NO_EXCEPT {
57 if (!mEffects.has(index)) {
58 return false;
59 }
60 mCurrId = index;
61 mDuration = duration;
62 mDurationSet = true;
63 return true;
64}
65
67 if (!mEffects.has(index)) {
68 return FxPtr();
69 }
70
71 FxPtr removedFx;
72 bool ok = mEffects.get(index, &removedFx);
73 if (!ok) {
74 return FxPtr();
75 }
76
77 if (mCurrId == index) {
78 // If we're removing the current effect, switch to the next one
79 mEffects.next(mCurrId, &mCurrId, true);
80 mDurationSet = true;
81 mDuration = 0; // Instant transition
82 }
83
84 return removedFx;
85}
86
88 if (mEffects.has(id)) {
89 FxPtr fx;
90 mEffects.get(id, &fx);
91 return fx;
92 }
93 return FxPtr();
94}
95
96bool FxEngine::draw(fl::u32 now, fl::span<CRGB> finalBuffer) FL_NO_EXCEPT {
97 mTimeFunction.update(now);
98 fl::u32 warpedTime = mTimeFunction.time();
99
100 // Swap audio double-buffers: back → front, then clear back for next frame.
102 mAudioBack.clear();
103
104 // Bump the task scheduler so the audio auto-pump task runs NOW,
105 // feeding any pending I2S samples into the Processor before we read levels.
106 // Without this, draw() would read stale levels from the previous frame.
107 if (mAudioProcessor) {
109 }
110
111 // If an audio processor is wired, poll it for one frame per draw cycle.
112 if (mAudioProcessor) {
113 AudioFrame af;
114 af.bass = mAudioProcessor->getBassLevel();
115 af.mid = mAudioProcessor->getMidLevel();
116 af.treble = mAudioProcessor->getTrebleLevel();
117 af.volume = mAudioProcessor->getEnergy();
118 af.beat = mAudioProcessor->isVibeBassSpike();
119 af.timestamp = now;
120 mAudioFront.push_back(af);
121 }
122
123 // Build AudioBatch on the stack — shared across both compositor layers.
124 // Passes Processor pointer for lazy access to vibe/equalizer/percussion.
126 AudioBatch audioBatch(audioSpan, mAudioProcessor.get());
127 const AudioBatch *audioPtr =
128 (mAudioFront.empty() && !mAudioProcessor) ? nullptr : &audioBatch;
129
130 if (mEffects.empty()) {
131 return false;
132 }
133 if (mDurationSet) {
134 FxPtr fx;
135 bool ok = mEffects.get(mCurrId, &fx);
136 if (!ok) {
137 // something went wrong.
138 return false;
139 }
140 mCompositor.startTransition(now, mDuration, fx);
141 mDurationSet = false;
142 }
143 if (!mEffects.empty()) {
144 float speed = mTimeFunction.scale();
145 mCompositor.draw(now, warpedTime, finalBuffer, speed, audioPtr);
146 }
147 return true;
148}
149
150} // namespace fl
uint16_t speed
Definition Noise.ino:72
FxPtr getFx(int index) FL_NO_EXCEPT
Retrieves an effect from the engine without removing it.
FxPtr removeFx(int index) FL_NO_EXCEPT
Requests removal of an effect from the engine, which might not happen immediately (for example the Fx...
fl::vector< AudioFrame > mAudioBack
Definition fx_engine.h:148
void setAudio(fl::shared_ptr< fl::audio::Processor > proc) FL_NO_EXCEPT
Connects an audio processor for automatic audio delivery.
int addFx(FxPtr effect) FL_NO_EXCEPT
Adds a new effect to the engine.
bool nextFx(u16 transition_ms=500) FL_NO_EXCEPT
Transitions to the next effect in the sequence.
bool mDurationSet
Flag indicating if a new transition has been set.
Definition fx_engine.h:140
bool setNextFx(int index, u16 duration) FL_NO_EXCEPT
Sets the next effect to transition to.
void pushAudioFrame(const AudioFrame &frame) FL_NO_EXCEPT
Pushes an audio frame into the back buffer.
FxCompositor mCompositor
Handles effect transitions and rendering.
Definition fx_engine.h:137
~FxEngine() FL_NO_EXCEPT
Destructor for FxEngine.
int mCurrId
Id of the current effect.
Definition fx_engine.h:138
fl::vector< AudioFrame > mAudioFront
Definition fx_engine.h:147
fl::shared_ptr< fl::audio::Processor > mAudioProcessor
Definition fx_engine.h:151
u16 mDuration
Duration of the current transition.
Definition fx_engine.h:139
IntFxMap mEffects
Collection of effects.
Definition fx_engine.h:136
bool draw(fl::u32 now, fl::span< CRGB > outputBuffer) FL_NO_EXCEPT
Renders the current effect or transition to the output buffer.
bool mInterpolate
Definition fx_engine.h:142
TimeWarp mTimeFunction
Definition fx_engine.h:134
FxEngine(u16 numLeds, bool interpolate=true) FL_NO_EXCEPT
Constructs an FxEngine with the specified number of LEDs.
static Scheduler & instance() FL_NO_EXCEPT
void update() FL_NO_EXCEPT
#define FASTLED_FX_ENGINE_MAX_FX
constexpr remove_reference< T >::type && move(T &&t) FL_NO_EXCEPT
Definition move.h:30
shared_ptr< T > make_shared(Args &&... args) FL_NO_EXCEPT
Definition shared_ptr.h:423
u8 u8 fract8 blur_amount FL_NO_EXCEPT
Definition blur.h:186
Base definition for an LED controller.
Definition crgb.hpp:179
fl::u32 timestamp
When this audio sample was captured (ms)
Definition audio_frame.h:16
float volume
Overall volume (0.0-1.0, normalized RMS)
Definition audio_frame.h:14
float mid
Mid energy (0.0-1.0, normalized)
Definition audio_frame.h:12
float bass
Bass energy (0.0-1.0, normalized)
Definition audio_frame.h:11
bool beat
True if a beat was detected this sample.
Definition audio_frame.h:15
float treble
Treble energy (0.0-1.0, normalized)
Definition audio_frame.h:13
Lightweight snapshot of pre-computed audio analysis for one audio sample.
Definition audio_frame.h:10
Task scheduler — manages timer and frame-based tasks.