FastLED 3.9.15
Loading...
Searching...
No Matches
wave_simulation.h
Go to the documentation of this file.
1/*
2This is the WaveSimulation API. These classes allow flexible super sampling
3to achieve much better visual quality. They will also run the simulator
4update multiple times in order to achieve consistent speed between super
5sampling factors.
6
7A super sampling value of 2x will give the best results for the CPU consumption
8as most artifacts will be averaged out at this resolution.
9
10Based on works and code by Shawn Silverman.
11*/
12
13#pragma once
14
15#include <stdint.h>
16
17#include "fl/math_macros.h" // if needed for MAX/MIN macros
18#include "fl/namespace.h"
19#include "fl/scoped_ptr.h"
20#include "fl/warn.h"
22
23#include "fl/grid.h"
24#include "fl/ptr.h"
25#include "fl/supersample.h"
26#include "fl/xymap.h"
27#include "fx/fx.h"
28#include "fx/fx2d.h"
29
30namespace fl {
31
33
34// -----------------------------------------------------------------------------
35// New supersampled 1D simulation class.
36//
37// This class mimics the supersampling logic of WaveSimulation2D.
38// The constructor accepts the desired downsampled length and a supersampling
39// multiplier (via a SuperSample enum). Internally, it creates a high-resolution
40// simulation of size (multiplier * length), and its accessor methods average
41// over or replicate across the corresponding block of high-res cells.
43 public:
44 // Constructor:
45 // - length: desired downsampled grid length.
46 // - factor: supersampling multiplier (e.g., 1x, 2x, 4x, or 8x).
47 // Higher values yield better quality but are more cpu intensive.
48 // - speed and dampening are passed on to the internal simulation.
49 WaveSimulation1D(uint32_t length,
51 float speed = 0.16f, int dampening = 6);
52
53 void init(uint32_t length, SuperSample factor, float speed, int dampening);
54
56 if (uint32_t(factor) == mMultiplier) {
57 return;
58 }
59 init(mOuterLength, factor, mSim->getSpeed(), mSim->getDampenening());
60 }
61
62 // Only applies to getu8().
63 void setEasingMode(U8EasingFunction mode) { mU8Mode = mode; }
64
65 ~WaveSimulation1D() = default;
66
67 // Delegate methods to the internal simulation.
68 void setSpeed(float speed);
69 void setDampening(int damp);
70 int getDampenening() const;
71 float getSpeed() const;
72
73 // Runs the simulator faster by updating it multiple times.
74 void setExtraFrames(uint8_t extra);
75
76 // Downsampled getter for the floating point value at index x.
77 // It averages over the corresponding 'multiplier'-sized block in the
78 // high-res simulation.
79 float getf(size_t x) const;
80
81 // Downsampled getter for the Q15 (fixed point) value at index x.
82 // It averages the multiplier cells of Q15 values.
83 int16_t geti16(size_t x) const;
84 int16_t geti16Previous(size_t x) const;
85
86 bool geti16All(size_t x, int16_t *curr, int16_t *prev, int16_t *diff) const;
87
88 // Downsampled getters for the 8-bit representations.
89 int8_t geti8(size_t x) const;
90
91 uint8_t getu8(size_t x) const;
92
93 // Check if x is within the bounds of the outer (downsampled) simulation.
94 bool has(size_t x) const;
95
96 // Upsampling setter: set the value at an outer grid cell x by replicating
97 // it to the corresponding multiplier cells in the high-res simulation.
98 void setf(size_t x, float value);
99
100 void setHalfDuplex(bool on) { mSim->setHalfDuplex(on); }
101
102 // Advance the simulation one time step.
103 void update();
104
105 // Get the outer (downsampled) grid length.
106 uint32_t getLength() const;
107
109
110 private:
111 uint32_t mOuterLength; // Length of the downsampled simulation.
112 uint8_t mExtraFrames = 0;
113 uint32_t mMultiplier; // Supersampling multiplier (e.g., 2, 4, or 8).
115 // Internal high-resolution simulation.
117};
118
120 public:
121 // Constructor:
122 // - W and H specify the desired inner grid size of the downsampled
123 // simulation.
124 // - 'factor' selects the supersampling mMultiplier (e.g., 2x, 4x, or 8x).
125 // Higher values yield better quality but are more cpu intensive.
126 // - Internally, the simulation is created with dimensions (factor*W x
127 // factor*H).
128 // - 'speed' and 'dampening' parameters are passed on to the internal
129 // simulation.
130 WaveSimulation2D(uint32_t W, uint32_t H,
132 float speed = 0.16f, float dampening = 6.0f);
133
134 void init(uint32_t width, uint32_t height, SuperSample factor, float speed,
135 int dampening);
136
137 ~WaveSimulation2D() = default;
138
139 // Delegated simulation methods.
140 void setSpeed(float speed);
141
142 void setExtraFrames(uint8_t extra);
143
144 void setDampening(int damp);
145
147
148 int getDampenening() const;
149
150 float getSpeed() const;
151
153 if (uint32_t(factor) == mMultiplier) {
154 return;
155 }
156 init(mOuterWidth, mOuterHeight, factor, mSim->getSpeed(),
157 mSim->getDampenening());
158 }
159
160 // Downsampled getter for the floating point value at (x,y) in the outer
161 // grid. It averages over the corresponding multiplier×multiplier block in
162 // the high-res simulation.
163 float getf(size_t x, size_t y) const;
164
165 // Downsampled getter for the Q15 (fixed point) value at (x,y).
166 // It averages the multiplier×multiplier block of Q15 values.
167 int16_t geti16(size_t x, size_t y) const;
168 int16_t geti16Previous(size_t x, size_t y) const;
169
170 bool geti16All(size_t x, size_t y, int16_t *curr, int16_t *prev,
171 int16_t *diff) const;
172
173 // Downsampled getters for the 8-bit representations.
174 int8_t geti8(size_t x, size_t y) const;
175
176 // Special function to get the value as a uint8_t for drawing / gradients.
177 // Ease out functions are applied to this when in half duplex mode.
178 uint8_t getu8(size_t x, size_t y) const;
179
180 // Check if (x,y) is within the bounds of the outer (downsampled) grid.
181 bool has(size_t x, size_t y) const;
182
183 // Upsampling setter: set the value at an outer grid cell (x,y) by
184 // replicating it to all cells of the corresponding multiplier×multiplier
185 // block in the high-res simulation.
186 void setf(size_t x, size_t y, float value);
187
188 void seti16(size_t x, size_t y, int16_t value);
189
190 void setHalfDuplex(bool on) { mSim->setHalfDuplex(on); }
191
192 // Advance the simulation one time step.
193 void update();
194
195 // Get the outer grid dimensions.
196 uint32_t getWidth() const;
197 uint32_t getHeight() const;
198
200
201 private:
202 uint32_t mOuterWidth; // Width of the downsampled (outer) grid.
203 uint32_t mOuterHeight; // Height of the downsampled (outer) grid.
204 uint8_t mExtraFrames = 0;
205 uint32_t mMultiplier; // Supersampling multiplier (e.g., 2, 4, or 8).
207 // Internal high-resolution simulation.
209 fl::Grid<int16_t> mChangeGrid; // Needed for multiple updates.
210};
211
212} // namespace fl
int y
Definition Audio.ino:72
int x
Definition Audio.ino:71
UISlider speed("Speed", 1.0f, -20.0f, 20.0f, 0.01f)
UISlider dampening("Dampening", 6.0f, 0.0f, 10.0f, 0.1f)
Definition grid.h:9
void setf(size_t x, float value)
WaveSimulation1D_Real & real()
fl::scoped_ptr< WaveSimulation1D_Real > mSim
void init(uint32_t length, SuperSample factor, float speed, int dampening)
void setEasingMode(U8EasingFunction mode)
WaveSimulation1D(uint32_t length, SuperSample factor=SuperSample::SUPER_SAMPLE_NONE, float speed=0.16f, int dampening=6)
int8_t geti8(size_t x) const
int16_t geti16(size_t x) const
bool has(size_t x) const
float getf(size_t x) const
~WaveSimulation1D()=default
void setSpeed(float speed)
U8EasingFunction mU8Mode
void setDampening(int damp)
void setSuperSample(SuperSample factor)
void setExtraFrames(uint8_t extra)
uint8_t getu8(size_t x) const
int16_t geti16Previous(size_t x) const
bool geti16All(size_t x, int16_t *curr, int16_t *prev, int16_t *diff) const
uint32_t getLength() const
void setHalfDuplex(bool on)
void setSuperSample(SuperSample factor)
int16_t geti16(size_t x, size_t y) const
uint32_t getWidth() const
void init(uint32_t width, uint32_t height, SuperSample factor, float speed, int dampening)
void setExtraFrames(uint8_t extra)
uint32_t getHeight() const
int8_t geti8(size_t x, size_t y) const
fl::Grid< int16_t > mChangeGrid
fl::scoped_ptr< WaveSimulation2D_Real > mSim
void setSpeed(float speed)
WaveSimulation2D_Real & real()
void setEasingMode(U8EasingFunction mode)
bool geti16All(size_t x, size_t y, int16_t *curr, int16_t *prev, int16_t *diff) const
float getf(size_t x, size_t y) const
uint8_t getu8(size_t x, size_t y) const
void seti16(size_t x, size_t y, int16_t value)
void setf(size_t x, size_t y, float value)
U8EasingFunction mU8Mode
bool has(size_t x, size_t y) const
void setDampening(int damp)
~WaveSimulation2D()=default
WaveSimulation2D(uint32_t W, uint32_t H, SuperSample factor=SuperSample::SUPER_SAMPLE_NONE, float speed=0.16f, float dampening=6.0f)
int16_t geti16Previous(size_t x, size_t y) const
void setHalfDuplex(bool on)
UISlider length("Length", 1.0f, 0.0f, 1.0f, 0.01f)
Implements the FastLED namespace macros.
U8EasingFunction
@ WAVE_U8_MODE_LINEAR
@ WAVE_U8_MODE_SQRT
SuperSample
Definition supersample.h:4
@ SUPER_SAMPLE_NONE
Definition supersample.h:5
Implements a simple red square effect for 2D LED grids.
Definition crgb.h:16