Skip to content

Commit 8419a93

Browse files
committed
v1.4.0 Added New Timed Events and some minor fixes
1 parent fef6795 commit 8419a93

24 files changed

+670
-146
lines changed

boards.local.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,9 +7,9 @@
77
# To locate boards.txt
88

99
# On mac, open your Applications folder, right click on Arduino or Teensyduino (which ever you are using)
10-
# then select "Show Package Contents" and navigate to "Contents/Java/hardware/teensy/avr/boards.txt"
10+
# then select "Show Package Contents" and navigate to "Contents/Java/hardware/teensy/avr/"
1111

12-
# On Windows: go to "Program Files (x86)/Arduino/hardware/teensy/avr/boards.txt"
12+
# On Windows: go to "Program Files (x86)/Arduino/hardware/teensy/avr/"
1313
# After doing this you can restart Teensyduino and you will then see the "Require BMC Config" option under tools
1414

1515

library.properties

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name=BMC
2-
version=1.3.0
2+
version=1.4.0
33
author=Nero Rox
44
maintainer=Nero Rox <info@roxxxtar.com>
55
sentence=Fully featured MIDI Controller Library with a Companion Editor App for 32-bit Teensy boards, Requires Teensyduino.

src/BMC-Api.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -181,6 +181,11 @@ class BMCApi : public BMC {
181181
void onTriggerCustom(void (*fptr)(uint8_t id)){
182182
#if BMC_MAX_TRIGGERS > 0
183183
callback.triggerCustom = fptr;
184+
#endif
185+
}
186+
void onTimedEventCustom(void (*fptr)(uint8_t id, uint8_t a, uint8_t b, uint8_t c)){
187+
#if BMC_MAX_TIMED_EVENTS > 0
188+
callback.timedEventCustom = fptr;
184189
#endif
185190
}
186191
// triggered when EEPROM has been updated either by the editor or the API

src/BMC-Version.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@
2222

2323
// BMC Version stored in EEPROM (for editor usage)
2424
#define BMC_VERSION_MAJ 1
25-
#define BMC_VERSION_MIN 3
25+
#define BMC_VERSION_MIN 4
2626
#define BMC_VERSION_PATCH 0
2727

2828
//16 bits unsigned, LSB byte is minor, MSB byte is major

src/BMC.cpp

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,9 @@ BMC::BMC():
5252
#if BMC_MAX_PIXEL_PROGRAMS > 0
5353
,pixelPrograms(store.global)
5454
#endif
55+
#if BMC_MAX_TIMED_EVENTS > 0
56+
,timedEvents(store.global)
57+
#endif
5558
#if BMC_MAX_BUTTONS > 1
5659
// second argument is true for global buttons
5760
// to check which callback to use
@@ -170,6 +173,10 @@ void BMC::update(){
170173
tempoToTap.update();
171174
#endif
172175

176+
#if BMC_MAX_TIMED_EVENTS > 0
177+
readTimedEvent();
178+
#endif
179+
173180
editor.update();
174181

175182
// read the midi input ports

src/BMC.debug.cpp

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -235,6 +235,7 @@ void BMC::readDebug(){
235235
BMC_PRINTLN("BMC_MAX_PRESET_ITEMS", BMC_MAX_PRESET_ITEMS);
236236
BMC_PRINTLN("BMC_MAX_CUSTOM_SYSEX", BMC_MAX_CUSTOM_SYSEX);
237237
BMC_PRINTLN("BMC_MAX_TRIGGERS", BMC_MAX_TRIGGERS);
238+
BMC_PRINTLN("BMC_MAX_TIMED_EVENTS", BMC_MAX_TIMED_EVENTS);
238239
BMC_PRINTLN("BMC_MAX_TEMPO_TO_TAP", BMC_MAX_TEMPO_TO_TAP);
239240
BMC_PRINTLN("BMC_MAX_SKETCH_BYTES", BMC_MAX_SKETCH_BYTES);
240241
BMC_PRINTLN("BMC_MAX_GLOBAL_BUTTONS", BMC_MAX_GLOBAL_BUTTONS);
@@ -405,6 +406,10 @@ void BMC::readDebug(){
405406
BMC_PRINTLN("store.global.triggers",sizeof(store.global.triggers),"bytes");
406407
BMC_PRINTLN("store.global.triggers[0]",sizeof(store.global.triggers[0]),"bytes");
407408
#endif
409+
#if BMC_MAX_TIMED_EVENTS > 0
410+
BMC_PRINTLN("store.global.timedEvents",sizeof(store.global.timedEvents),"bytes");
411+
BMC_PRINTLN("store.global.timedEvents[0]",sizeof(store.global.timedEvents[0]),"bytes");
412+
#endif
408413
#if BMC_MAX_TEMPO_TO_TAP > 0
409414
BMC_PRINTLN("store.global.tempoToTap",sizeof(store.global.tempoToTap),"bytes");
410415
BMC_PRINTLN("store.global.tempoToTap[0]",sizeof(store.global.tempoToTap[0]),"bytes");

src/BMC.editor.cpp

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -147,6 +147,12 @@ void BMC::assignSettings(){
147147
}
148148
#endif
149149

150+
#if BMC_MAX_TIMED_EVENTS > 0
151+
if(editor.timedEventsUpdated()){
152+
timedEvents.buildListeners();
153+
}
154+
#endif
155+
150156
#if BMC_MAX_BUTTONS > 32
151157
buttonStates = ~buttonStates;
152158
buttonStates2 = ~buttonStates2;

src/BMC.h

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -141,6 +141,10 @@
141141
#if BMC_MAX_TRIGGERS > 0
142142
#include "utility/BMC-Triggers.h"
143143
#endif
144+
#if BMC_MAX_TIMED_EVENTS > 0
145+
#include "utility/BMC-TimedEvents.h"
146+
#endif
147+
144148
// see BMC-Api.h for API calls
145149
class BMC {
146150
private:
@@ -257,6 +261,12 @@ class BMC {
257261
BMCTriggers triggers;
258262
#endif
259263

264+
#if BMC_MAX_TIMED_EVENTS > 0
265+
BMCTimedEvents timedEvents;
266+
#endif
267+
268+
269+
260270
uint8_t page = 0;
261271
uint8_t programBank = 0;
262272

@@ -324,6 +334,11 @@ class BMC {
324334
void processTrigger(uint8_t index);
325335
#endif
326336

337+
#if BMC_MAX_TIMED_EVENTS > 0
338+
void readTimedEvent();
339+
void processTimedEvent(uint8_t n);
340+
#endif
341+
327342
// ** HARDWARE **
328343
// code @ BMC.hardware.cpp
329344
void setupHardware();

src/BMC.hardware.buttons.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -138,7 +138,7 @@ void BMC::handleButton(uint8_t index, uint8_t t_trigger){
138138
for(uint8_t e = 0; e < BMC_MAX_BUTTON_EVENTS; e++){
139139
bmcStoreButtonEvent &data = store.pages[page].buttons[index].events[e];
140140
uint8_t type = BMC_GET_BYTE(0,data.event);
141-
uint8_t trigger = (data.mode & 0x0F)==t_trigger ? t_trigger : BMC_NONE;
141+
uint8_t trigger = ((data.mode&0x0F)==t_trigger) ? t_trigger : BMC_NONE;
142142

143143
if(trigger == BMC_NONE || type == BMC_NONE){
144144
continue;
@@ -781,6 +781,15 @@ void BMC::handleGlobalButton(uint8_t index, uint8_t t_trigger){
781781
break;
782782
#endif
783783

784+
#if BMC_MAX_TIMED_EVENTS > 0
785+
case BMC_BUTTON_EVENT_TYPE_TIMED_EVENT:
786+
// byteA = timed event Index
787+
timedEvents.trigger(byteA);
788+
break;
789+
#endif
790+
791+
792+
784793
#if BMC_MAX_LIBRARY > 0
785794
case BMC_BUTTON_EVENT_TYPE_LIBRARY:
786795
// byteA = index of the library item

src/BMC.timedEvents.cpp

Lines changed: 122 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,122 @@
1+
/*
2+
See https://www.RoxXxtar.com/bmc for more details
3+
Copyright (c) 2020 RoxXxtar.com
4+
Licensed under the MIT license.
5+
See LICENSE file in the project root for full license information.
6+
*/
7+
#include <BMC.h>
8+
9+
#if BMC_MAX_TIMED_EVENTS > 0
10+
void BMC::readTimedEvent(){
11+
if(timedEvents.available()==0){
12+
return;
13+
}
14+
for(uint8_t index = 0, n=timedEvents.available(); index < n; index++){
15+
if(timedEvents.isReady(index)){
16+
processTimedEvent(index);
17+
}
18+
}
19+
}
20+
void BMC::processTimedEvent(uint8_t n){
21+
// ready to trigger
22+
if(n>=BMC_MAX_TIMED_EVENTS){
23+
return;
24+
}
25+
uint32_t event = store.global.timedEvents[n].event;
26+
switch(BMC_GET_BYTE(0, event)){
27+
case BMC_NONE:
28+
return;
29+
case BMC_TIMED_EVENT_TYPE_LIBRARY:
30+
#if BMC_MAX_LIBRARY>0
31+
// byteA = index of the library item
32+
library.send(BMC_EVENT_TO_LIBRARY_NUM(event>>8));
33+
#endif
34+
break;
35+
case BMC_TIMED_EVENT_TYPE_LIBRARY2:
36+
#if BMC_MAX_LIBRARY>1
37+
// byteA = index of the 1st library item to send
38+
// byteB = index of the 2nd library item to send
39+
library.send(BMC_EVENT_TO_LIBRARY_NUM(event>>8), BMC_EVENT_TO_LIBRARY_NUM(event>>18));
40+
#endif
41+
break;
42+
case BMC_TIMED_EVENT_TYPE_RELAY_NL_CONTROL:
43+
#if BMC_MAX_NL_RELAYS>0
44+
if(BMC_GET_BYTE(1, event) < BMC_MAX_NL_RELAYS){
45+
relaysNL[BMC_GET_BYTE(1, event)].command(BMC_GET_BYTE(2, event));
46+
}
47+
#endif
48+
break;
49+
case BMC_TIMED_EVENT_TYPE_RELAY_L_CONTROL:
50+
#if BMC_MAX_L_RELAYS>0
51+
if(BMC_GET_BYTE(1, event) < BMC_MAX_L_RELAYS){
52+
relaysL[BMC_GET_BYTE(1, event)].command(BMC_GET_BYTE(2, event));
53+
}
54+
#endif
55+
break;
56+
case BMC_TIMED_EVENT_TYPE_BUTTON_EVENT:
57+
#if BMC_MAX_BUTTONS > 0
58+
{
59+
uint8_t btnN = BMC_GET_BYTE(1, event);
60+
uint8_t btnEventN = BMC_GET_BYTE(2, event);
61+
bmcStoreButtonEvent &data = store.pages[page].buttons[btnN].events[btnEventN];
62+
uint8_t type = BMC_GET_BYTE(0,data.event);
63+
if(type!=BMC_NONE){
64+
handleButtonEvent(type, data);
65+
}
66+
}
67+
#endif
68+
break;
69+
case BMC_TIMED_EVENT_TYPE_GLOBAL_BUTTON_EVENT:
70+
#if BMC_MAX_GLOBAL_BUTTONS > 0
71+
{
72+
uint8_t btnN = BMC_GET_BYTE(1, event);
73+
uint8_t btnEventN = BMC_GET_BYTE(2, event);
74+
bmcStoreButtonEvent &data = globalData.buttons[btnN].events[btnEventN];
75+
uint8_t type = BMC_GET_BYTE(0,data.event);
76+
if(type!=BMC_NONE){
77+
handleButtonEvent(type, data);
78+
}
79+
}
80+
#endif
81+
break;
82+
case BMC_TIMED_EVENT_TYPE_ENCODER:
83+
#if BMC_MAX_ENCODERS > 0
84+
{
85+
uint8_t enc = BMC_GET_BYTE(1, event);
86+
uint8_t inc = BMC_GET_BYTE(2, event);
87+
uint8_t type = BMC_GET_BYTE(0, store.pages[page].encoders[enc].event);
88+
if(type!=BMC_NONE){
89+
handleEncoder(store.pages[page].encoders[enc], inc);
90+
}
91+
}
92+
#endif
93+
break;
94+
case BMC_TIMED_EVENT_TYPE_GLOBAL_ENCODER:
95+
#if BMC_MAX_GLOBAL_ENCODERS > 0
96+
{
97+
uint8_t enc = BMC_GET_BYTE(1, event);
98+
uint8_t inc = BMC_GET_BYTE(2, event);
99+
uint8_t type = BMC_GET_BYTE(0, globalData.encoders[enc].event);
100+
if(type!=BMC_NONE){
101+
handleEncoder(globalData.encoders[enc], inc);
102+
}
103+
}
104+
#endif
105+
break;
106+
case BMC_TIMED_EVENT_TYPE_PAGE:
107+
#if BMC_MAX_GLOBAL_ENCODERS > 1
108+
setPage(BMC_GET_BYTE(1, event));
109+
#endif
110+
break;
111+
case BMC_TIMED_EVENT_TYPE_MASTER_CLOCK:
112+
midiClock.setBpm((event >> 8) & 0x1FF);
113+
break;
114+
case BMC_TIMED_EVENT_TYPE_CUSTOM:
115+
callback.timedEventCustom(n,
116+
BMC_GET_BYTE(1,event),
117+
BMC_GET_BYTE(2,event),
118+
BMC_GET_BYTE(3,event));
119+
break;
120+
}
121+
}
122+
#endif

src/BMC.triggers.cpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
*/
77
#include <BMC.h>
88

9-
#if BMC_MAX_TRIGGERS
9+
#if BMC_MAX_TRIGGERS > 0
1010
void BMC::readTrigger(){
1111
if(!triggers.isAllowed()){
1212
return;
@@ -58,11 +58,11 @@
5858
midiClock.tap();
5959
BMC_PRINTLN("BMCTriggers BMC_TRIGGER_EVENT_TYPE_CLOCK_TAP");
6060
break;
61-
case BMC_TRIGGER_EVENT_TYPE_PAGE_ACTIVE_SENSE:
61+
case BMC_TRIGGER_EVENT_TYPE_ACTIVE_SENSE:
6262
// event (bits 08 to 15) = Command
6363
// event (bits 16 to 23) = Ports
6464
midiActiveSense.command(byteA, byteB);
65-
BMC_PRINTLN("BMCTriggers BMC_TRIGGER_EVENT_TYPE_PAGE_ACTIVE_SENSE");
65+
BMC_PRINTLN("BMCTriggers BMC_TRIGGER_EVENT_TYPE_ACTIVE_SENSE");
6666
break;
6767
case BMC_TRIGGER_EVENT_TYPE_PAGE:
6868
// event (bits 08 to 15) = Page Number

src/editor/BMC-Editor.backup.cpp

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -317,9 +317,6 @@ void BMCEditor::backupPixelProgram(uint16_t t_minLength){
317317
#endif
318318
sendNotification(BMC_NOTIFY_BACKUP_DATA_ACCEPTED, t_minLength);
319319
}
320-
321-
322-
323320
void BMCEditor::backupGlobalTriggers(uint16_t t_minLength){
324321
#if BMC_MAX_TRIGGERS > 0
325322
uint8_t index = getMessagePageNumber();
@@ -336,6 +333,22 @@ void BMCEditor::backupGlobalTriggers(uint16_t t_minLength){
336333
#endif
337334
sendNotification(BMC_NOTIFY_BACKUP_DATA_ACCEPTED, t_minLength);
338335
}
336+
void BMCEditor::backupGlobalTimedEvents(uint16_t t_minLength){
337+
#if BMC_MAX_TIMED_EVENTS > 0
338+
uint8_t index = getMessagePageNumber();
339+
if(index >= BMC_MAX_TIMED_EVENTS){
340+
sendNotification(BMC_NOTIFY_BACKUP_DATA_ACCEPTED, 0);
341+
return;
342+
}
343+
// does NOT require additional bytes from write message
344+
if(incoming.size() == t_minLength){
345+
bmcStoreGlobalTimedEvents& item = store.global.timedEvents[index];
346+
item.event = incoming.get32Bits(9);
347+
item.timeout = incoming.get32Bits(14);
348+
}
349+
#endif
350+
sendNotification(BMC_NOTIFY_BACKUP_DATA_ACCEPTED, t_minLength);
351+
}
339352
void BMCEditor::backupGlobalLed(uint16_t t_minLength){
340353
#if BMC_MAX_GLOBAL_LEDS > 0
341354
uint8_t index = getMessagePageNumber();

0 commit comments

Comments
 (0)