FastLED 3.10.6
Loading...
Searching...
No Matches
room_sense.h
Go to the documentation of this file.
1// room_sense.h - what the room sounds like, as a handful of smooth signals.
2//
3// RoomListener polls the audio Processor once per frame and fills RoomSense.
4// Everything downstream reads RoomSense and nothing else, so the audio
5// pipeline can change without touching a single visual.
6//
7// There is no state enum. The three regimes (calm room, busy room, music
8// with a beat) are three weights that always sum to one. They move with
9// asymmetric attack and release, which gives the same "slow to enter
10// silence, fast to leave it" feel the old classifier needed timers for.
11#pragma once
12
13#include "FastLED.h"
15#include "fl/stl/shared_ptr.h"
16#include "fl/stl/stdint.h"
17
18namespace mood_ring {
19
21struct RoomEvents {
22 bool beat = false;
23 bool downbeat = false;
24 bool kick = false;
25 bool snare = false;
26 bool hihat = false;
27};
28
31struct RoomSense {
32 // Regime blend. calm + flow + groove == 1.
33 float presence = 0.0f;
34 float calm = 1.0f;
35 float flow = 0.0f;
36 float groove = 0.0f;
37
38 // Energy.
39 float energy = 0.0f;
40 float trend = 0.0f;
41 float punch = 0.0f;
42 float shimmer = 0.0f;
43 float low = 0.0f;
44 float mid = 0.0f;
45 float high = 0.0f;
46
47 // Rhythm.
48 float bpm = 0.0f;
49 float beatPhase = 0.0f;
50 float measurePhase = 0.0f;
51 float grooveConfidence = 0.0f;
52
53 // Mood.
54 float warmth = 0.5f;
55 float arousal = 0.0f;
56
58};
59
62 float presenceAttackMs = 150.0f;
63 float presenceReleaseMs = 900.0f;
64 float grooveAttackMs = 800.0f;
65 float grooveReleaseMs = 1500.0f;
66 float grooveEnter = 0.60f;
67 float grooveExit = 0.35f;
68 float punchGain = 1.5f;
69};
70
72class Follower {
73 public:
74 float update(float target, float dtMs, float attackMs, float releaseMs);
75 float value() const { return mValue; }
76 void reset(float v) { mValue = v; }
77
78 private:
79 float mValue = 0.0f;
80};
81
83 public:
85
87 void begin();
88
90 void update(fl::u32 nowMs);
91
95 void rest(fl::u32 nowMs);
96
97 const RoomSense &sense() const { return mSense; }
98
100 const char *regimeName() const;
101
103
104 private:
106 float stepClock(fl::u32 nowMs);
107 void deriveBlend(float dtMs);
108 void blendFrom(float presenceTarget, float grooveConf, float dtMs);
109 void deriveEnergy(float dtMs);
110 void deriveRhythm(fl::u32 nowMs);
111 void deriveMood(float dtMs);
112 void deriveEvents();
113
116 fl::u32 mLastMs = 0;
117
129
130 // Event timestamps written by Processor callbacks, consumed by update().
131 fl::u32 mLastBeatMs = 0;
132 fl::u32 mLastDownbeatMs = 0;
133 fl::u32 mLastKickMs = 0;
134 fl::u32 mLastSnareMs = 0;
135 fl::u32 mLastHiHatMs = 0;
136 fl::u32 mSeenBeatMs = 0;
137 fl::u32 mSeenDownbeatMs = 0;
138 fl::u32 mSeenKickMs = 0;
139 fl::u32 mSeenSnareMs = 0;
140 fl::u32 mSeenHiHatMs = 0;
141};
142
143} // namespace mood_ring
void reset(float v)
Definition room_sense.h:76
float value() const
Definition room_sense.h:75
float update(float target, float dtMs, float attackMs, float releaseMs)
Smoothed one-pole follower with independent attack and release.
Definition room_sense.h:72
void update(fl::u32 nowMs)
Poll the Processor and refresh sense(). Call once per frame.
void deriveMood(float dtMs)
void deriveRhythm(fl::u32 nowMs)
fl::shared_ptr< fl::audio::Processor > mProcessor
Definition room_sense.h:114
RoomListener(fl::shared_ptr< fl::audio::Processor > processor)
void rest(fl::u32 nowMs)
Not listening this frame.
const char * regimeName() const
Which regime currently dominates, for logs only.
void deriveBlend(float dtMs)
ListenerTuning tuning
Definition room_sense.h:102
void blendFrom(float presenceTarget, float grooveConf, float dtMs)
void begin()
Install the event callbacks. Call once after the Processor exists.
const RoomSense & sense() const
Definition room_sense.h:97
float stepClock(fl::u32 nowMs)
Advance the frame clock; returns a bounded dt in ms.
void deriveEnergy(float dtMs)
float shimmer
treble transient
Definition room_sense.h:42
float punchGain
scales the bass transient
Definition room_sense.h:68
float arousal
0 calm .. 1 energetic
Definition room_sense.h:55
float punch
bass transient (a hit, not loudness)
Definition room_sense.h:41
float grooveAttackMs
how slowly we start trusting a beat
Definition room_sense.h:64
float presenceReleaseMs
how slowly silence settles in
Definition room_sense.h:63
float energy
smoothed loudness
Definition room_sense.h:39
float measurePhase
0 on the downbeat
Definition room_sense.h:50
float trend
[-1, 1] falling .. rising
Definition room_sense.h:40
float grooveExit
confidence where groove is fully off
Definition room_sense.h:67
float grooveReleaseMs
how slowly we stop trusting it
Definition room_sense.h:65
float presence
sound is present (silence -> 0)
Definition room_sense.h:33
float beatPhase
0 on the beat, ramps to 1 before the next
Definition room_sense.h:49
float warmth
0 cool .. 1 warm, from valence
Definition room_sense.h:54
float grooveEnter
confidence where groove is fully on
Definition room_sense.h:66
float presenceAttackMs
how fast sound wakes the ring
Definition room_sense.h:62
Everything a visual is allowed to react to.
Definition room_sense.h:31
One-frame rising edges. Set on the frame the event lands, cleared next.
Definition room_sense.h:21
Everything the UI is allowed to tune on the listening side.
Definition room_sense.h:61