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