FastLED 3.9.15
Loading...
Searching...
No Matches
Keyboard.cpp
Go to the documentation of this file.
1#include <Arduino.h>
2
3#include "./util.h"
4#include "./color_mapper.h"
5#include "./Keyboard.h"
6#include "./dprint.h"
7#include "fl/unused.h"
8
9Key::Key() : on_(false), sustained_(false), sustain_pedal_on_(false),
10 velocity_(0), idx_(0), event_time_(0) {}
11
12void Key::SetOn(uint8_t vel, const ColorHSV& color, uint32_t now_ms) {
13 if (curr_color_.v_ < color.v_) { // if the new color is "brighter" than the current color.
14 velocity_ = vel;
15 curr_color_ = color;
16 event_time_ = now_ms;
17 }
19 event_time_ = now_ms;
20 on_ = true;
21}
22
23void Key::SetOff(uint32_t now_ms) {
25 on_ = false;
26 event_time_ = now_ms;
27 sustained_ = false;
28}
29
31 sustained_ = true;
32}
33
34void Key::Update(uint32_t now_ms, uint32_t delta_ms, bool sustain_pedal_on) {
35 if (sustained_ && !sustain_pedal_on) {
36 sustained_ = false;
37 SetOff(now_ms);
38 }
39 sustain_pedal_on_ = sustain_pedal_on;
40 UpdateIntensity(now_ms, delta_ms);
41}
42
43float Key::VelocityFactor() const { return velocity_ / 127.f; }
44
45float Key::CalcAttackDecayFactor(uint32_t delta_ms) const {
46 bool dampened_key = (idx_ < kFirstNoteNoDamp);
47 float active_lights_factor = ::CalcDecayFactor(
49 on_,
50 idx_,
52 dampened_key,
53 delta_ms);
54 return active_lights_factor;
55}
56
57float Key::AttackRemapFactor(uint32_t now_ms) {
58 if (on_) {
59 return ::AttackRemapFactor(now_ms - event_time_);
60 } else {
61 return 1.0;
62 }
63}
64
65float Key::IntensityFactor() const {
66 return intensity_;
67}
68
69void Key::UpdateIntensity(uint32_t now_ms, uint32_t delta_ms) {
70 if (on_) {
71 // Intensity can be calculated by a
72 float intensity =
75 AttackRemapFactor(now_ms);
76
77 // This is FRAME RATE DEPENDENT FUNCTION!!!!
78 // CHANGE TO TIME INDEPENDENT BEFORE SUBMIT.
79 intensity_ = (.9f * intensity) + (.1f * intensity_);
80 } else if(intensity_ > 0.0f) { // major cpu hotspot.
81
83 float delta_s = delta_ms / 1000.f;
84 if (intensity_ > .5f) {
85 const float kRate = .12f;
86 // Time flexible decay function. Stays accurate
87 // even as the frame rate changes.
88 // Formula: A = Pe^(r*t)
89 intensity_ = intensity_ * exp(-delta_s * kRate);
90 } else {
91 // Quickly fade at the bottom end of the transition.
92 const float kRate = .05f;
93 intensity_ -= delta_s * kRate;
94 }
95 } else {
96 float delta_s = delta_ms / 1000.f;
97 if (intensity_ > .5f) {
98 const float kRate = 12.0f;
99 // Time flexible decay function. Stays accurate
100 // even as the frame rate changes.
101 // Formula: A = Pe^(r*t)
102 intensity_ = intensity_ * exp(-delta_s * kRate);
103 } else {
104 // Quickly fade at the bottom end of the transition.
105 const float kRate = 2.0f;
106 intensity_ -= delta_s * kRate;
107 }
108
109 }
110 intensity_ = constrain(intensity_, 0.0f, 1.0f);
111 }
112}
113
114void KeyboardState::HandleNoteOn(uint8_t midi_note, uint8_t velocity, int color_selector_value, uint32_t now_ms) {
115 if (0 == velocity) {
116 // Some keyboards signify "NoteOff" with a velocity of zero.
117 HandleNoteOff(midi_note, velocity, now_ms);
118 return;
119 }
120
121#ifdef DEBUG_KEYBOARD
122 dprint("HandleNoteOn:");
123
124 dprint("midi_note = ");
125 dprint(midi_note);
126
127 dprint(", velocity = ");
128 dprintln(velocity);
129 #endif
130
131 float brightness = ToBrightness(velocity);
132
133 dprint("brightness: "); dprintln(brightness);
134
135 ColorHSV pixel_color_hsv = SelectColor(midi_note, brightness,
136 color_selector_value);
137
138 // TODO: Give a key access to the Keyboard owner, therefore it could inspect the
139 // sustained variable instead of passing it here.
140 Key* key = GetKey(midi_note);
141
142 dprint("key indx: "); dprintln(key->idx_);
143
144 key->SetOn(velocity, pixel_color_hsv, now_ms);
145}
146
147void KeyboardState::HandleNoteOff(uint8_t midi_note, uint8_t /*velocity*/, uint32_t now_ms) {
148#ifdef DEBUG_KEYBOARD
149 dprint("HandleNoteOff:");
150
151 dprint("midi_note = ");
152 dprint(midi_note);
153
154 dprint(", velocity = ");
155 dprintln(velocity);
156#endif
157
158 Key* key = GetKey(midi_note);
159
160 if (sustain_pedal_) {
161 key->SetSustained();
162 } else {
163 key->SetOff(now_ms);
164 }
165}
166
167void KeyboardState::HandleControlChange(uint8_t d1, uint8_t d2) {
168 // Note that d1 and d2 just mean "data-1" and "data-2".
169 // TODO: Find out what d1 and d2 should be called.
170 const bool foot_pedal = (d1 == kMidiFootPedal);
171
172 if (foot_pedal) {
173 // Spec says that if that values 0-63 are OFF, otherwise ON.
174 sustain_pedal_ = (d2 >= 64);
175 }
176}
177
178void KeyboardState::HandleAfterTouchPoly(uint8_t note, uint8_t pressure) {
179 FL_UNUSED(note);
180 FL_UNUSED(pressure);
181
182 dprintln("HandleAfterTouchPoly");
183
184 dprint("\tnote = ");
185 dprint(note);
186
187 dprint(", pressure = ");
188 dprintln(pressure);
189}
190
192 for (int i = 0; i < kNumKeys; ++i) {
193 keys_[i].idx_ = i;
194 }
195}
196
197void KeyboardState::Update(uint32_t now_ms, uint32_t delta_ms) {
198 for (int i = 0; i < kNumKeys; ++i) {
199 keys_[i].Update(now_ms, delta_ms, sustain_pedal_);
200 }
201}
202
203uint8_t KeyboardState::KeyIndex(int midi_pitch) {
204 //return constrain(midi_pitch, 21, 108) - 21;
205 return ::KeyIndex(midi_pitch);
206}
207
208Key* KeyboardState::GetKey(int midi_pitch) {
209 uint8_t idx = KeyIndex(midi_pitch);
210 return &keys_[idx];
211}
@ kFirstNoteNoDamp
Definition Keyboard.h:15
UISlider brightness("Brightness", 128, 0, 255, 1)
void Update(uint32_t now_ms, uint32_t delta_ms)
Definition Keyboard.cpp:197
static const int kNumKeys
Definition Keyboard.h:101
void HandleControlChange(uint8_t d1, uint8_t d2)
Definition Keyboard.cpp:167
void HandleAfterTouchPoly(uint8_t note, uint8_t pressure)
Definition Keyboard.cpp:178
void HandleNoteOn(uint8_t midi_note, uint8_t velocity, int color_selector_value, uint32_t now_ms)
Definition Keyboard.cpp:114
static uint8_t KeyIndex(int midi_pitch)
Definition Keyboard.cpp:203
bool sustain_pedal_
Definition Keyboard.h:102
Key * GetKey(int midi_pitch)
Definition Keyboard.cpp:208
Key keys_[kNumKeys]
Definition Keyboard.h:103
void HandleNoteOff(uint8_t midi_note, uint8_t velocity, uint32_t now_ms)
Definition Keyboard.cpp:147
const ColorHSV SelectColor(int midi_note, float brightness, int color_selector_val)
#define dprint(x)
Definition dprint.h:13
#define dprintln(x)
Definition dprint.h:14
@ kMidiFootPedal
Definition settings.h:22
float v_
Definition color.h:108
void SetOff(uint32_t now_ms)
Definition Keyboard.cpp:23
void SetSustained()
Definition Keyboard.cpp:30
Key()
Definition Keyboard.cpp:9
ColorHSV orig_color_
Definition Keyboard.h:47
int idx_
Definition Keyboard.h:40
float AttackRemapFactor(uint32_t now_ms)
Definition Keyboard.cpp:57
float IntensityFactor() const
Definition Keyboard.cpp:65
bool sustained_
Definition Keyboard.h:37
ColorHSV curr_color_
Definition Keyboard.h:48
void SetOn(uint8_t vel, const ColorHSV &color, uint32_t now_ms)
Definition Keyboard.cpp:12
unsigned long event_time_
Definition Keyboard.h:41
bool on_
Definition Keyboard.h:36
bool sustain_pedal_on_
Definition Keyboard.h:38
float CalcAttackDecayFactor(uint32_t delta_ms) const
Definition Keyboard.cpp:45
void Update(uint32_t now_ms, uint32_t delta_ms, bool sustain_pedal_on)
Definition Keyboard.cpp:34
uint8_t velocity_
Definition Keyboard.h:39
float VelocityFactor() const
Definition Keyboard.cpp:43
float intensity_
Definition Keyboard.h:46
void UpdateIntensity(uint32_t now_ms, uint32_t delta_ms)
Definition Keyboard.cpp:69
Definition Keyboard.h:22
#define FL_UNUSED(x)
Definition unused.h:8
float CalcDecayFactor(bool sustain_pedal_on, bool key_on, int key_idx, float velocity, bool dampened_key, float time_elapsed_ms)
Definition util.cpp:70
float ToBrightness(int velocity)
Definition util.cpp:98