FastLED 3.9.13
Loading...
Searching...
No Matches
LuminescentGrand.ino
1
8
9#include "shared/defs.h"
10
11#if !ENABLE_SKETCH
12// avr can't compile this, neither can the esp8266.
13void setup() {}
14void loop() {}
15#else
16
17
18//#define DEBUG_PAINTER
19//#define DEBUG_KEYBOARD 1
20
21// Repeated keyboard presses in the main loop
22#define DEBUG_FORCED_KEYBOARD
23// #define DEBUG_MIDI_KEY 72
24
25#define MIDI_SERIAL_PORT Serial1
26
27#define FASTLED_UI // Brings in the UI components.
28#include "FastLED.h"
29
30// H
31#include <Arduino.h>
32#include "shared/Keyboard.h"
33#include "shared/color.h"
34#include "shared/led_layout_array.h"
35#include "shared/Keyboard.h"
36#include "shared/Painter.h"
37#include "shared/settings.h"
38#include "arduino/LedRopeTCL.h"
39#include "arduino/ui_state.h"
40#include "shared/dprint.h"
41#include "fl/dbg.h"
42#include "fl/ui.h"
43#include "fl/unused.h"
44
45// Spoof the midi library so it thinks it's running on an arduino.
46//#ifndef ARDUINO
47//#define ARDUINO 1
48//#endif
49
50#ifdef MIDI_AUTO_INSTANCIATE
51#undef MIDI_AUTO_INSTANCIATE
52#define MIDI_AUTO_INSTANCIATE 0
53#endif
54
55#include "arduino/MIDI.h"
56
57
58MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MY_MIDI);
59
60
61FASTLED_TITLE("Luminescent Grand");
62FASTLED_DESCRIPTION("A midi keyboard visualizer.");
63
64
66// Light rope and keyboard.
67LedRopeTCL led_rope(kNumKeys);
68KeyboardState keyboard;
69
70
72// Called when the note is pressed.
73// Input:
74// channel - Ignored.
75// midi_note - Value between 21-108 which maps to the keyboard keys.
76// velocity - Value between 0-127
77void HandleNoteOn(byte channel, byte midi_note, byte velocity) {
78 FASTLED_DBG("HandleNoteOn: midi_note = " << int(midi_note) << ", velocity = " << int(velocity));
79 keyboard.HandleNoteOn(midi_note, velocity, color_selector.curr_val(), millis());
80}
81
83// Called when the note is released.
84// Input:
85// channel - Ignored.
86// midi_note - Value between 21-108 which maps to the keyboard keys.
87// velocity - Value between 0-127
88void HandleNoteOff(byte channel, byte midi_note, byte velocity) {
89 FASTLED_DBG("HandleNoteOn: midi_note = " << int(midi_note) << ", velocity = " << int(velocity));
90 keyboard.HandleNoteOff(midi_note, velocity, millis());
91}
92
94// This is uninmplemented because the test keyboard didn't
95// have this functionality. Right now the only thing it does is
96// print out that the key was pressed.
97void HandleAfterTouchPoly(byte channel, byte note, byte pressure) {
98 keyboard.HandleAfterTouchPoly(note, pressure);
99}
100
101
103// Detects whether the foot pedal has been touched.
104void HandleControlChange(byte channel, byte d1, byte d2) {
105 keyboard.HandleControlChange(d1, d2);
106}
107
108void HandleAfterTouchChannel(byte channel, byte pressure) {
109 #if 0 // Disabled for now.
110 if (0 == pressure) {
111 for (int i = 0; i < kNumKeys; ++i) {
112 Key& key = keyboard.keys_[i];
113 key.SetOff();
114 }
115 }
116 #endif
117}
118
119
120
122// Called once when the app starts.
123void setup() {
124 FASTLED_DBG("setup");
125 // Serial port for logging.
126 Serial.begin(57600);
127 //start serial with midi baudrate 31250
128 // Initiate MIDI communications, listen to all channels
129 MY_MIDI.begin(MIDI_CHANNEL_OMNI);
130
131 // Connect the HandleNoteOn function to the library, so it is called upon reception of a NoteOn.
132 MY_MIDI.setHandleNoteOn(HandleNoteOn);
133 MY_MIDI.setHandleNoteOff(HandleNoteOff);
134 MY_MIDI.setHandleAfterTouchPoly(HandleAfterTouchPoly);
135 MY_MIDI.setHandleAfterTouchChannel(HandleAfterTouchChannel);
136 MY_MIDI.setHandleControlChange(HandleControlChange);
137
138 ui_init();
139}
140
141void DbgDoSimulatedKeyboardPress() {
142#ifdef DEBUG_FORCED_KEYBOARD
143 static uint32_t start_time = 0;
144 static bool toggle = 0;
145
146 const uint32_t time_on = 25;
147 const uint32_t time_off = 500;
148
149 // Just force it on whenever this function is called.
150 is_debugging = true;
151
152 uint32_t now = millis();
153 uint32_t delta_time = now - start_time;
154
155
156 uint32_t threshold_time = toggle ? time_off : time_on;
157 if (delta_time < threshold_time) {
158 return;
159 }
160
161 int random_key = random(0, 88);
162
163 start_time = now;
164 if (toggle) {
165 HandleNoteOn(0, random_key, 64);
166 } else {
167 HandleNoteOff(0, random_key, 82);
168 }
169 toggle = !toggle;
170#endif
171}
172
174// Repeatedly called by the app.
175void loop() {
176 //FASTLED_DBG("loop");
177
178 // Calculate dt.
179 static uint32_t s_prev_time = 0;
180 uint32_t prev_time = 0;
181 FASTLED_UNUSED(prev_time); // actually used in perf tests.
182 uint32_t now_ms = millis();
183 uint32_t delta_ms = now_ms - s_prev_time;
184 s_prev_time = now_ms;
185
186 if (!is_debugging) {
187 if (Serial.available() > 0) {
188 int v = Serial.read();
189 if (v == 'd') {
190 is_debugging = true;
191 }
192 }
193 }
194
195 DbgDoSimulatedKeyboardPress();
196
197 const unsigned long start_time = millis();
198 // Each frame we call the midi processor 100 times to make sure that all notes
199 // are processed.
200 for (int i = 0; i < 100; ++i) {
201 MY_MIDI.read();
202 }
203
204 const unsigned long midi_time = millis() - start_time;
205
206 // Updates keyboard: releases sustained keys that.
207
208 const uint32_t keyboard_time_start = millis();
209
210 // This is kind of a hack... but give the keyboard a future time
211 // so that all keys just pressed get a value > 0 for their time
212 // durations.
213 keyboard.Update(now_ms + delta_ms, delta_ms);
214 const uint32_t keyboard_delta_time = millis() - keyboard_time_start;
215
216 ui_state ui_st = ui_update(now_ms, delta_ms);
217
218 //dprint("vis selector = ");
219 //dprintln(vis_state);
220
221
222 // These int values are for desting the performance of the
223 // app. If the app ever runs slow then set kShowFps to 1
224 // in the settings.h file.
225 const unsigned long start_painting = millis();
226 FASTLED_UNUSED(start_painting);
227
228
229 // Paints the keyboard using the led_rope.
230 Painter::VisState which_vis = Painter::VisState(ui_st.which_visualizer);
231 Painter::Paint(now_ms, delta_ms, which_vis, &keyboard, &led_rope);
232
233 const unsigned long paint_time = millis() - start_time;
234 const unsigned long total_time = midi_time + paint_time + keyboard_delta_time;
235
236 if (kShowFps) {
237 float fps = 1.0f/(float(total_time) / 1000.f);
238 Serial.print("fps - "); Serial.println(fps);
239 Serial.print("midi time - "); Serial.println(midi_time);
240 Serial.print("keyboard update time - "); Serial.println(keyboard_delta_time);
241 Serial.print("draw & paint time - "); Serial.println(paint_time);
242 }
243
244 EVERY_N_SECONDS(1) {
245 FASTLED_DBG("is_debugging = " << is_debugging);
246 }
247
248}
249
250
251#endif // __AVR__
central include file for FastLED, defines the CFastLED class/object
MIDI Library for the Arduino.
#define EVERY_N_SECONDS(N)
Checks whether to execute a block of code every N seconds.
Definition lib8tion.h:1283
#define MIDI_CREATE_INSTANCE(Type, SerialPort, Name)
Create an instance of the library attached to a serial port. You can use HardwareSerial or SoftwareSe...
Definition serialMIDI.h:99
Definition Keyboard.h:22