first commit
This commit is contained in:
commit
5893b00dd2
1669 changed files with 1982740 additions and 0 deletions
213
libraries/FastLED/examples/LuminescentGrand/shared/Keyboard.cpp
Normal file
213
libraries/FastLED/examples/LuminescentGrand/shared/Keyboard.cpp
Normal file
|
|
@ -0,0 +1,213 @@
|
|||
|
||||
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include "./util.h"
|
||||
#include "./color_mapper.h"
|
||||
#include "./Keyboard.h"
|
||||
#include "./dprint.h"
|
||||
|
||||
Key::Key() : on_(false), sustained_(false), sustain_pedal_on_(false),
|
||||
velocity_(0), idx_(0), event_time_(0) {}
|
||||
|
||||
void Key::SetOn(uint8_t vel, const ColorHSV& color, uint32_t now_ms) {
|
||||
if (curr_color_.v_ < color.v_) { // if the new color is "brighter" than the current color.
|
||||
velocity_ = vel;
|
||||
curr_color_ = color;
|
||||
event_time_ = now_ms;
|
||||
}
|
||||
orig_color_ = curr_color_;
|
||||
event_time_ = now_ms;
|
||||
on_ = true;
|
||||
}
|
||||
|
||||
void Key::SetOff(uint32_t now_ms) {
|
||||
orig_color_ = curr_color_;
|
||||
on_ = false;
|
||||
event_time_ = now_ms;
|
||||
sustained_ = false;
|
||||
}
|
||||
|
||||
void Key::SetSustained() {
|
||||
sustained_ = true;
|
||||
}
|
||||
|
||||
void Key::Update(uint32_t now_ms, uint32_t delta_ms, bool sustain_pedal_on) {
|
||||
if (sustained_ && !sustain_pedal_on) {
|
||||
sustained_ = false;
|
||||
SetOff(now_ms);
|
||||
}
|
||||
sustain_pedal_on_ = sustain_pedal_on;
|
||||
UpdateIntensity(now_ms, delta_ms);
|
||||
}
|
||||
|
||||
float Key::VelocityFactor() const { return velocity_ / 127.f; }
|
||||
|
||||
float Key::CalcAttackDecayFactor(uint32_t delta_ms) const {
|
||||
bool dampened_key = (idx_ < kFirstNoteNoDamp);
|
||||
float active_lights_factor = ::CalcDecayFactor(
|
||||
sustain_pedal_on_,
|
||||
on_,
|
||||
idx_,
|
||||
VelocityFactor(),
|
||||
dampened_key,
|
||||
delta_ms);
|
||||
return active_lights_factor;
|
||||
}
|
||||
|
||||
float Key::AttackRemapFactor(uint32_t now_ms) {
|
||||
if (on_) {
|
||||
return ::AttackRemapFactor(now_ms - event_time_);
|
||||
} else {
|
||||
return 1.0;
|
||||
}
|
||||
}
|
||||
|
||||
float Key::IntensityFactor() const {
|
||||
return intensity_;
|
||||
}
|
||||
|
||||
void Key::UpdateIntensity(uint32_t now_ms, uint32_t delta_ms) {
|
||||
if (on_) {
|
||||
// Intensity can be calculated by a
|
||||
float intensity =
|
||||
CalcAttackDecayFactor(now_ms - event_time_) *
|
||||
VelocityFactor() *
|
||||
AttackRemapFactor(now_ms);
|
||||
|
||||
// This is FRAME RATE DEPENDENT FUNCTION!!!!
|
||||
// CHANGE TO TIME INDEPENDENT BEFORE SUBMIT.
|
||||
intensity_ = (.9f * intensity) + (.1f * intensity_);
|
||||
} else if(intensity_ > 0.0f) { // major cpu hotspot.
|
||||
|
||||
if (sustain_pedal_on_) {
|
||||
float delta_s = delta_ms / 1000.f;
|
||||
if (intensity_ > .5f) {
|
||||
const float kRate = .12f;
|
||||
// Time flexible decay function. Stays accurate
|
||||
// even as the frame rate changes.
|
||||
// Formula: A = Pe^(r*t)
|
||||
intensity_ = intensity_ * exp(-delta_s * kRate);
|
||||
} else {
|
||||
// Quickly fade at the bottom end of the transition.
|
||||
const float kRate = .05f;
|
||||
intensity_ -= delta_s * kRate;
|
||||
}
|
||||
} else {
|
||||
float delta_s = delta_ms / 1000.f;
|
||||
if (intensity_ > .5f) {
|
||||
const float kRate = 12.0f;
|
||||
// Time flexible decay function. Stays accurate
|
||||
// even as the frame rate changes.
|
||||
// Formula: A = Pe^(r*t)
|
||||
intensity_ = intensity_ * exp(-delta_s * kRate);
|
||||
} else {
|
||||
// Quickly fade at the bottom end of the transition.
|
||||
const float kRate = 2.0f;
|
||||
intensity_ -= delta_s * kRate;
|
||||
}
|
||||
|
||||
}
|
||||
intensity_ = constrain(intensity_, 0.0f, 1.0f);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardState::HandleNoteOn(uint8_t midi_note, uint8_t velocity, int color_selector_value, uint32_t now_ms) {
|
||||
if (0 == velocity) {
|
||||
// Some keyboards signify "NoteOff" with a velocity of zero.
|
||||
HandleNoteOff(midi_note, velocity, now_ms);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_KEYBOARD
|
||||
dprint("HandleNoteOn:");
|
||||
|
||||
dprint("midi_note = ");
|
||||
dprint(midi_note);
|
||||
|
||||
dprint(", velocity = ");
|
||||
dprintln(velocity);
|
||||
#endif
|
||||
|
||||
float brightness = ToBrightness(velocity);
|
||||
|
||||
dprint("brightness: "); dprintln(brightness);
|
||||
|
||||
ColorHSV pixel_color_hsv = SelectColor(midi_note, brightness,
|
||||
color_selector_value);
|
||||
|
||||
// TODO: Give a key access to the Keyboard owner, therefore it could inspect the
|
||||
// sustained variable instead of passing it here.
|
||||
Key* key = GetKey(midi_note);
|
||||
|
||||
dprint("key indx: "); dprintln(key->idx_);
|
||||
|
||||
key->SetOn(velocity, pixel_color_hsv, now_ms);
|
||||
}
|
||||
|
||||
void KeyboardState::HandleNoteOff(uint8_t midi_note, uint8_t /*velocity*/, uint32_t now_ms) {
|
||||
#ifdef DEBUG_KEYBOARD
|
||||
dprint("HandleNoteOff:");
|
||||
|
||||
dprint("midi_note = ");
|
||||
dprint(midi_note);
|
||||
|
||||
dprint(", velocity = ");
|
||||
dprintln(velocity);
|
||||
#endif
|
||||
|
||||
Key* key = GetKey(midi_note);
|
||||
|
||||
if (sustain_pedal_) {
|
||||
key->SetSustained();
|
||||
} else {
|
||||
key->SetOff(now_ms);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardState::HandleControlChange(uint8_t d1, uint8_t d2) {
|
||||
// Note that d1 and d2 just mean "data-1" and "data-2".
|
||||
// TODO: Find out what d1 and d2 should be called.
|
||||
const bool foot_pedal = (d1 == kMidiFootPedal);
|
||||
|
||||
if (foot_pedal) {
|
||||
// Spec says that if that values 0-63 are OFF, otherwise ON.
|
||||
sustain_pedal_ = (d2 >= 64);
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardState::HandleAfterTouchPoly(uint8_t note, uint8_t pressure) {
|
||||
dprintln("HandleAfterTouchPoly");
|
||||
|
||||
dprint("\tnote = ");
|
||||
dprint(note);
|
||||
|
||||
dprint(", pressure = ");
|
||||
dprintln(pressure);
|
||||
}
|
||||
|
||||
KeyboardState::KeyboardState() : sustain_pedal_(false), keys_() {
|
||||
for (int i = 0; i < kNumKeys; ++i) {
|
||||
keys_[i].idx_ = i;
|
||||
}
|
||||
}
|
||||
|
||||
void KeyboardState::Update(uint32_t now_ms, uint32_t delta_ms) {
|
||||
for (int i = 0; i < kNumKeys; ++i) {
|
||||
keys_[i].Update(now_ms, delta_ms, sustain_pedal_);
|
||||
}
|
||||
}
|
||||
|
||||
uint8_t KeyboardState::KeyIndex(int midi_pitch) {
|
||||
//return constrain(midi_pitch, 21, 108) - 21;
|
||||
return ::KeyIndex(midi_pitch);
|
||||
}
|
||||
|
||||
Key* KeyboardState::GetKey(int midi_pitch) {
|
||||
uint8_t idx = KeyIndex(midi_pitch);
|
||||
return &keys_[idx];
|
||||
}
|
||||
|
||||
|
||||
|
||||
Loading…
Add table
Add a link
Reference in a new issue