#include <FastLED.h>
#define I2S_WS 7
#define I2S_SD 8
#define I2S_CLK 4
#define PIN_PREVIEW 3
{12.0f, 50.0f}, {22.0f, 42.0f}, {22.0f, 58.0f},
{32.0f, 34.0f}, {32.0f, 50.0f}, {32.0f, 66.0f},
{50.0f, 30.0f}, {50.0f, 38.0f}, {50.0f, 46.0f},
{50.0f, 54.0f}, {50.0f, 62.0f}, {50.0f, 70.0f},
{88.0f, 50.0f}, {78.0f, 42.0f}, {78.0f, 58.0f},
{68.0f, 34.0f}, {68.0f, 50.0f}, {68.0f, 66.0f},
};
"HydroPack screenmap must contain every preview LED");
}
"The INMP441 sound-pressure gate warms up for two seconds of confident "
"beats before arming music mode. Conversation and one-off noise stay "
"dark; musical bass "
"fires the center, with stronger hits launching to both triangles.");
1.0f);
0.05f);
#if defined(FL_IS_WASM)
#endif
return;
}
return;
}
}
return false;
}
return true;
}
}
return false;
}
return true;
}
}
const float bassAverage =
gAudio->getVibeBassAtt();
if (!levels.
bassSpike || bassAverage <= 0.0f) {
return 0.0f;
}
return fl::clamp((levels.
bass - bassAverage) / bassAverage, 0.0f, 1.0f);
}
void fireAnalyzer(
float bass,
float threshold,
float minIntensity,
if (bass <= threshold) {
return;
}
const float intensity =
fl::clamp((bass - threshold) / threshold,
minIntensity, 1.0f);
}
float decaySeconds, float deltaSeconds) {
const float seconds = target > value ? attackSeconds : decaySeconds;
if (seconds <= 0.0f) {
return target;
}
const float amount =
fl::clamp(deltaSeconds / seconds, 0.0f, 1.0f);
return value + (target - value) * amount;
}
float attackSeconds, float decaySeconds,
float deltaSeconds) {
deltaSeconds);
deltaSeconds);
}
float deltaSeconds) {
if (durationSeconds <= 0.0f) {
return target;
}
const float step = deltaSeconds / durationSeconds;
if (target > value) {
return fl::min(target, value + step);
}
return fl::max(target, value - step);
}
}
const CRGB centerColor(0, centerBrightness / 3, centerBrightness);
const CRGB triangleColor(0, triangleBrightness / 3, triangleBrightness);
}
}
}
#if defined(FL_IS_WASM)
streamDetectorFrames.setGroup("Debug");
#endif
FL_WARN(
"HydroPack: no audio processor available");
return;
}
gAudio->setNoiseFloorTrackingEnabled(
true);
#if defined(FL_IS_WASM)
if (streamDetectorFrames.value()) {
"HYDRO frame=%lu spl=%.1f zcf=%.3f silent=%u "
"beat=%.3f bpm=%.1f tempo=%.3f tempo_bpm=%.1f "
"vibe_bass=%.3f vibe_att=%.3f vibe_conf=%.3f spike=%u "
"bass_raw=%.3f gate=%u\\n",
}
#endif
}
return;
}
}
});
}
static bool firstFrame = true;
const uint32_t deltaMs = firstFrame ? 0 : (now - lastMs);
firstFrame = false;
lastMs = now;
}
if (deltaMs > 0) {
const float deltaSeconds = float(deltaMs) * 0.001f;
deltaSeconds);
}
}
}
fl::UIDescription description("Demo of the Animatrix effects. @author of fx is StefanPetrick")
fl::UITitle title("Animartrix")
FL_DISABLE_WARNING_PUSH FL_DISABLE_WARNING_GLOBAL_CONSTRUCTORS CFastLED FastLED
Global LED strip management instance.
static Config CreateInmp441(int pin_ws, int pin_sd, int pin_clk, AudioChannel channel, u16 sample_rate=44100ul, int i2s_num=0) FL_NO_EXCEPT
fl::UIButton trigger("Trigger")
#define EVERY_N_MILLIS(N)
Checks whether to execute a block of code every N milliseconds.
constexpr float kDefaultMinimumBeatConfidence
constexpr uint32_t kMaximumMusicBeatGapMs
fl::UISlider stageThresholdDbSpl("Minimum Music Level (dB SPL)", kDefaultStageThresholdDbSpl, 60.0f, 105.0f, 1.0f)
CRGB previewLeds[kPreviewLedCount]
float gCenterEnvelopeStage
float gTriangleEnvelopeStage
uint8_t toByte(float value)
constexpr uint8_t kHydroPackLedCount
constexpr float kTriangleEnvelopeFadeSeconds
uint32_t gTriangleFireAtMs
constexpr uint8_t kPreviewLedCount
fl::audio::SoundLevelMeter gSoundLevelMeter
constexpr uint8_t kTriangleLedCount
float gSoundPressureDbSpl
constexpr float kTriangleBassThreshold
constexpr uint8_t kRightTriangleStart
void fireAnalyzer(float bass, float threshold, float minIntensity, float &trigger)
fl::audio::Config audioConfig
uint32_t gLastQualifyingBeatMs
fl::UISlider minimumBeatConfidence("Minimum Vibe Beat Confidence", kDefaultMinimumBeatConfidence, 0.0f, 1.0f, 0.05f)
fl::ScreenMap makePreviewMap()
float applyAttackDecay(float value, float target, float attackSeconds, float decaySeconds, float deltaSeconds)
uint32_t gMusicWarmupStartedMs
float getVibeBeatConfidence(const fl::audio::detector::VibeLevels &levels)
constexpr uint8_t kCenterStart
constexpr float kDefaultStageThresholdDbSpl
constexpr float kMaximumMusicZcf
constexpr uint32_t kMusicWarmupMs
constexpr float kCenterEnvelopeFadeSeconds
constexpr uint32_t kTriangleLaunchDelayMs
const fl::vec2f kHydroPackLedLayout[]
uint32_t gMusicActiveUntilMs
fl::shared_ptr< fl::audio::Processor > gAudio
constexpr uint32_t kMusicHoldMs
fl::UIAudio audioUi("Audio Input", audioConfig)
constexpr float kMusicModeFadeSeconds
float gPendingTriangleLevel
void advanceDoubleEnvelope(float &trigger, float &stage, float &level, float attackSeconds, float decaySeconds, float deltaSeconds)
constexpr float kCenterEnvelopeAttackSeconds
constexpr float kCenterBassThreshold
constexpr float kTriangleEnvelopeAttackSeconds
float advanceLinearFade(float value, float target, float durationSeconds, float deltaSeconds)
duration< fl::i64 > seconds
Seconds - duration with period of 1 second.
constexpr common_type_t< T, U > max(T a, U b) FL_NO_EXCEPT
void delay(u32 ms, bool run_async=true) FL_NO_EXCEPT
Public delay wrapper that keeps bare Arduino delay() preferred after using fl::delay; while still all...
FL_DISABLE_WARNING_PUSH U constexpr common_type_t< T, U > min(T a, U b) FL_NO_EXCEPT
constexpr enable_if< is_fixed_point< T >::value, T >::type clamp(T x, T lo, T hi) FL_NO_EXCEPT
fl::u32 millis()
Universal millisecond timer - returns milliseconds since system startup.
void printf(const char *format) FL_NO_EXCEPT
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.
constexpr enable_if< is_fixed_point< T >::value, T >::type step(T edge, T x) FL_NO_EXCEPT
#define FL_STATIC_ASSERT(...)
Portable compile-time assertion wrapper.
Aggregator header for the fl/ui/ family of per-element UI types.