47template <
typename Arr>
49 const fl::u32 n =
sizeof(bank) /
sizeof(bank[0]);
118 const float tempoConf =
mProcessor->getTempoConfidence();
119 const float beatConf =
mProcessor->getBeatConfidence();
127 const bool silenceReleased =
140 tempoConf >=
mCfg.tempoConfidenceEnter &&
141 beatConf >=
mCfg.beatConfidenceEnter) {
144 (tempoConf >=
mCfg.tempoConfidenceExit &&
145 beatConf >=
mCfg.beatConfidenceExit)) {
163 if (candidateHeld >=
mCfg.classifierHysteresisMs &&
164 stateHeld >=
mCfg.minDwellMs) {
178 return mCfg.silenceSpeed * manualSpeedScalar;
187 const float bassBoost = (bass - 1.0f) *
mCfg.disorganizedSpeedSpan;
188 float speed = 1.0f + bassBoost;
191 return speed * manualSpeedScalar;
200 float bpmScale = 1.0f;
202 bpmScale =
bpm / 120.0f;
203 if (bpmScale < 0.6f) bpmScale = 0.6f;
204 if (bpmScale > 1.6f) bpmScale = 1.6f;
209 auto pulseFromEvent = [&](fl::u32
t,
float weight) ->
float {
210 if (
t == 0)
return 0.0f;
211 const fl::u32 dt = nowMs -
t;
212 if (dt >=
mCfg.pulseDecayMs)
return 0.0f;
213 const float k = 1.0f - (
static_cast<float>(dt) /
mCfg.pulseDecayMs);
214 return weight * k * k;
216 const float kickPulse = pulseFromEvent(
mLastKickMs, 0.50f);
217 const float snarePulse = pulseFromEvent(
mLastSnareMs, 0.25f);
219 float pulse = kickPulse + snarePulse + downbeatPulse;
220 if (pulse > 1.5f) pulse = 1.5f;
224 const float phase =
mProcessor->getMeasurePhase();
226 const float phaseBow = 0.15f *
fl::sin(phase * 6.2831853f);
228 float speed =
mCfg.bpmLockedBaseSpeed * bpmScale + pulse + phaseBow;
230 return speed * manualSpeedScalar;
248 default:
speed = manualSpeedScalar;
break;
fl::Animartrix animartrix(xyMap, FIRST_ANIMATION)
FastLED chrono implementation - duration types for time measurements.
SoundState classify(fl::u32 nowMs)
float tick(fl::u32 nowMs, float manualSpeedScalar)
Per-frame tick.
void begin()
Wire up audio callbacks (downbeat/kick/snare).
float driveBpmLocked(fl::u32 nowMs, float manualSpeedScalar)
static fl::AnimartrixAnim pickAnimationFor(SoundState s, fl::u32 nowMs)
SoundOrchestrator(fl::shared_ptr< fl::audio::Processor > processor, fl::shared_ptr< fl::Animartrix > animartrix, fl::FxEngine *engine)
void switchAnimationIfNeeded(SoundState newState, fl::u32 nowMs)
fl::AnimartrixAnim mCurrentAnim
fl::u32 mCandidateSinceMs
float driveSilence(fl::u32 nowMs, float manualSpeedScalar)
float driveDisorganized(fl::u32 nowMs, float manualSpeedScalar)
fl::u32 mNonSilentSinceMs
fl::shared_ptr< fl::audio::Processor > mProcessor
fl::shared_ptr< fl::Animartrix > mAnimartrix
fl::u32 mStateEnteredAtMs
Manages and renders multiple visual effects (Fx) for LED strips.
constexpr fl::AnimartrixAnim kSilenceBank[]
constexpr fl::AnimartrixAnim kBpmLockedBank[]
constexpr fl::u32 kAnimCyclePeriodMs
constexpr fl::AnimartrixAnim kDisorganizedBank[]
fl::AnimartrixAnim pickFromBank(const Arr &bank, fl::u32 nowMs)
const char * toString(SoundState s)
fl::u32 millis()
Universal millisecond timer - returns milliseconds since system startup.
enable_if< is_fixed_point< T >::value, T >::type sin(T angle) FL_NOEXCEPT