|
|
|
@ -42,6 +42,7 @@ |
|
|
|
|
#define KRATE_CHECK_WRITE_STATE 10000 |
|
|
|
|
#define LAST_USAGE_TIMER 5000 |
|
|
|
|
#define FORMAT_SPIFFS_IF_FAILED true |
|
|
|
|
#define MIDI_SOLO_VOLUME 100 |
|
|
|
|
|
|
|
|
|
void OSCToMidiCC(OSCMessage &msg, int offset); |
|
|
|
|
void OSCMixerMuteToMidiCC(OSCMessage &msg, int offset); |
|
|
|
@ -65,7 +66,9 @@ HardwareSerial midi1(2); // RX: 16, TX: 17 |
|
|
|
|
#endif |
|
|
|
|
SoftwareSerial midi2; |
|
|
|
|
bool ap_mode_state; |
|
|
|
|
int8_t midistate[16 * 128]; |
|
|
|
|
int8_t midistate_cc[16 * 128]; |
|
|
|
|
int8_t midistate_mute[16]; |
|
|
|
|
int8_t midistate_solo[16]; |
|
|
|
|
bool last_reset_ap_check = false; |
|
|
|
|
looper sched; |
|
|
|
|
bool write_state = false; |
|
|
|
@ -82,7 +85,9 @@ void setup() |
|
|
|
|
|
|
|
|
|
//Serial.print("FORMAT SPIFFS..."); SPIFFS.format(); Serial.println("done."); while (1);
|
|
|
|
|
|
|
|
|
|
memset(midistate, -1, 16 * 128); |
|
|
|
|
memset(midistate_cc, -1, 16 * 128); |
|
|
|
|
memset(midistate_mute, -1, 16); |
|
|
|
|
memset(midistate_solo, -1, 16); |
|
|
|
|
|
|
|
|
|
pinMode(AP_DATA_RESET_PIN, INPUT_PULLDOWN); |
|
|
|
|
pinMode(AP_MODE_PIN, INPUT_PULLDOWN); |
|
|
|
@ -203,7 +208,7 @@ void setup() |
|
|
|
|
|
|
|
|
|
listDir(SPIFFS, "/", 1); |
|
|
|
|
read_midistate(1); |
|
|
|
|
show_midi_state(); |
|
|
|
|
show_midistate(); |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("<LOOP>\n"); |
|
|
|
|
} |
|
|
|
@ -288,8 +293,16 @@ void OSCToMidiCC(OSCMessage & msg, int offset) |
|
|
|
|
value = round(msg.getFloat(0)); |
|
|
|
|
value = value > 127 ? 127 : value; |
|
|
|
|
DEBUG_MSG("MSG: %s\tChannel: %u\t\tCC: %u\tValue: %u\n", address, midichannel, cc, value); |
|
|
|
|
MIDI1.sendControlChange(cc, value, midichannel); |
|
|
|
|
change_midi_state(midichannel, cc, value); |
|
|
|
|
if (cc == 7) |
|
|
|
|
{ |
|
|
|
|
if (midistate_mute[cc - 1] < 1 && midistate_solo[cc - 1] < 1) |
|
|
|
|
MIDI1.sendControlChange(cc, value, midichannel); |
|
|
|
|
else |
|
|
|
|
DEBUG_MSG("No volume change - only state change to %d\n", value); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
MIDI1.sendControlChange(cc, value, midichannel); |
|
|
|
|
change_midistate_cc(midichannel, cc, value); |
|
|
|
|
} |
|
|
|
|
else if (msg.size() == 2 && msg.isFloat(0) && msg.isFloat(1)) |
|
|
|
|
{ |
|
|
|
@ -299,21 +312,21 @@ void OSCToMidiCC(OSCMessage & msg, int offset) |
|
|
|
|
value = constrain(value, 0, 127); |
|
|
|
|
DEBUG_MSG("MSG: %s\tChannel: %u\t\tCC: %u\tValue: %u\n", address, midichannel, cc, value); |
|
|
|
|
MIDI1.sendControlChange(cc, value, midichannel); |
|
|
|
|
change_midi_state(midichannel, cc, value); |
|
|
|
|
change_midistate_cc(midichannel, cc, value); |
|
|
|
|
cc = getVar(address, 2); |
|
|
|
|
value = round(msg.getFloat(1)); |
|
|
|
|
value = constrain(value, 0, 127); |
|
|
|
|
DEBUG_MSG("MSG: %s\tChannel: %u\t\tCC: %u\tValue: %u\n", address, midichannel, cc, value); |
|
|
|
|
MIDI1.sendControlChange(cc, value, midichannel); |
|
|
|
|
change_midi_state(midichannel, cc, value); |
|
|
|
|
change_midistate_cc(midichannel, cc, value); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Cannot handle: % s\n", address); |
|
|
|
|
DEBUG_MSG("Cannot handle: %s\n", address); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void OSCMixerMuteToMidiCC(OSCMessage &msg, int offset) |
|
|
|
|
void OSCMixerMuteToMidiCC(OSCMessage & msg, int offset) |
|
|
|
|
{ |
|
|
|
|
char address[100] = { 0 }; |
|
|
|
|
uint8_t value; |
|
|
|
@ -330,14 +343,36 @@ void OSCMixerMuteToMidiCC(OSCMessage &msg, int offset) |
|
|
|
|
if (value == 1) |
|
|
|
|
MIDI1.sendControlChange(7, 0, midichannel); |
|
|
|
|
else |
|
|
|
|
MIDI1.sendControlChange(7, midistate[(midichannel - 1) * 128 + 6], midichannel); |
|
|
|
|
//change_midi_state(midichannel, cc, value);
|
|
|
|
|
MIDI1.sendControlChange(7, midistate_cc[(midichannel - 1) * 128 + 6], midichannel); |
|
|
|
|
|
|
|
|
|
change_midistate_mute(midichannel, value); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void OSCMixerSoloToMidiCC(OSCMessage &msg, int offset) |
|
|
|
|
void OSCMixerSoloToMidiCC(OSCMessage & msg, int offset) |
|
|
|
|
{ |
|
|
|
|
; |
|
|
|
|
char address[100] = { 0 }; |
|
|
|
|
uint8_t value; |
|
|
|
|
uint8_t midichannel; |
|
|
|
|
|
|
|
|
|
msg.getAddress(address, offset, sizeof(address)); |
|
|
|
|
|
|
|
|
|
if (msg.size() == 1 && msg.isFloat(0)) |
|
|
|
|
{ |
|
|
|
|
// Single or multi control with sending one value
|
|
|
|
|
midichannel = getVar(address, 0); |
|
|
|
|
value = constrain(msg.getFloat(0), 0, 1); |
|
|
|
|
DEBUG_MSG("MixerSolo MSG: %s\t Channel: %u\tMute \tValue: %u\n", address, midichannel, value); |
|
|
|
|
/*
|
|
|
|
|
if (value == 1) |
|
|
|
|
MIDI1.sendControlChange(7, 0, midichannel); |
|
|
|
|
else |
|
|
|
|
MIDI1.sendControlChange(7, midistate_cc[(midichannel - 1) * 128 + 6], midichannel); |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
change_midistate_solo(midichannel, value); |
|
|
|
|
set_midi_solo_mode(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MidiCCToOSC(uint8_t channel, uint8_t number, uint8_t val) |
|
|
|
@ -354,7 +389,66 @@ void MidiCCToOSC(uint8_t channel, uint8_t number, uint8_t val) |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("MidiCCToOsc: %s %f\n", buffer, val); |
|
|
|
|
|
|
|
|
|
change_midi_state(channel, number, val); |
|
|
|
|
change_midistate_cc(channel, number, val); |
|
|
|
|
|
|
|
|
|
if (clientIP) |
|
|
|
|
{ |
|
|
|
|
OSCMessage msg = OSCMessage(buffer); |
|
|
|
|
msg.add(val); |
|
|
|
|
|
|
|
|
|
udp.beginPacket(clientIP, UDP_SEND_PORT); |
|
|
|
|
msg.send(udp); |
|
|
|
|
udp.endPacket(); |
|
|
|
|
|
|
|
|
|
msg.empty(); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("No client IP.\n"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MidiMuteToOSC(uint8_t channel, uint8_t val) |
|
|
|
|
{ |
|
|
|
|
char buffer[1024]; |
|
|
|
|
|
|
|
|
|
if (channel < 1 && channel > 16) |
|
|
|
|
return; |
|
|
|
|
val = constrain(val, 0, 1); |
|
|
|
|
|
|
|
|
|
snprintf(buffer, sizeof(buffer), "/midi/mixer/mute/%d", channel); |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("MidiMuteToOsc: %s %f\n", buffer, val); |
|
|
|
|
|
|
|
|
|
if (clientIP) |
|
|
|
|
{ |
|
|
|
|
OSCMessage msg = OSCMessage(buffer); |
|
|
|
|
msg.add(val); |
|
|
|
|
|
|
|
|
|
udp.beginPacket(clientIP, UDP_SEND_PORT); |
|
|
|
|
msg.send(udp); |
|
|
|
|
udp.endPacket(); |
|
|
|
|
|
|
|
|
|
msg.empty(); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("No client IP.\n"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void MidiSoloToOSC(uint8_t channel, uint8_t val) |
|
|
|
|
{ |
|
|
|
|
char buffer[1024]; |
|
|
|
|
|
|
|
|
|
if (channel < 1 && channel > 16) |
|
|
|
|
return; |
|
|
|
|
if (val > 1) |
|
|
|
|
val = 1; |
|
|
|
|
|
|
|
|
|
snprintf(buffer, sizeof(buffer), "/midi/mixer/solo/%d", channel); |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("MidiSoloToOsc: %s %f\n", buffer, float(val)); |
|
|
|
|
|
|
|
|
|
if (clientIP) |
|
|
|
|
{ |
|
|
|
@ -373,39 +467,119 @@ void MidiCCToOSC(uint8_t channel, uint8_t number, uint8_t val) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void change_midi_state(uint8_t midichannel, uint8_t cc, uint8_t value) |
|
|
|
|
void change_midistate_cc(uint8_t midichannel, uint8_t cc, uint8_t value) |
|
|
|
|
{ |
|
|
|
|
last_usage = millis(); |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Setting internal state of MIDI Channel %2d CC#%02d to %d\n", midichannel, cc, int8_t(value)); |
|
|
|
|
|
|
|
|
|
if (midistate[(midichannel - 1) * 128 + cc - 1] != int8_t(value)) |
|
|
|
|
if (midistate_cc[(midichannel - 1) * 128 + cc - 1] != int8_t(value)) |
|
|
|
|
{ |
|
|
|
|
midistate[(midichannel - 1) * 128 + cc - 1] = int8_t(value); |
|
|
|
|
midistate_cc[(midichannel - 1) * 128 + cc - 1] = int8_t(value); |
|
|
|
|
write_state = true; |
|
|
|
|
lcd.setCursor(LCD_COL - 1, LCD_ROW - 1); |
|
|
|
|
lcd.print("*"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void show_midi_state(void) |
|
|
|
|
void change_midistate_mute(uint8_t midichannel, bool value) |
|
|
|
|
{ |
|
|
|
|
last_usage = millis(); |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Setting internal mute state of MIDI Channel %2d to %d\n", midichannel, int8_t(value)); |
|
|
|
|
|
|
|
|
|
if (midistate_mute[(midichannel - 1)] != value) |
|
|
|
|
{ |
|
|
|
|
midistate_mute[(midichannel - 1)] = value; |
|
|
|
|
write_state = true; |
|
|
|
|
lcd.setCursor(LCD_COL - 1, LCD_ROW - 1); |
|
|
|
|
lcd.print("*"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void change_midistate_solo(uint8_t midichannel, bool value) |
|
|
|
|
{ |
|
|
|
|
last_usage = millis(); |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Setting internal solo state of MIDI Channel %2d to %d\n", midichannel, int8_t(value)); |
|
|
|
|
|
|
|
|
|
if (midistate_solo[(midichannel - 1)] != value) |
|
|
|
|
{ |
|
|
|
|
midistate_solo[(midichannel - 1)] = value; |
|
|
|
|
write_state = true; |
|
|
|
|
lcd.setCursor(LCD_COL - 1, LCD_ROW - 1); |
|
|
|
|
lcd.print("*"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void show_midistate(void) |
|
|
|
|
{ |
|
|
|
|
uint8_t m, c; |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Current MIDI state:\n"); |
|
|
|
|
DEBUG_MSG("Current MIDI state: \n"); |
|
|
|
|
|
|
|
|
|
listDir(SPIFFS, "/", 1); |
|
|
|
|
|
|
|
|
|
for (m = 0; m < 16; m++) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("MIDI-Channel %2d\n", m + 1); |
|
|
|
|
DEBUG_MSG("MIDI - Channel %2d\n", m + 1); |
|
|
|
|
for (c = 0; c < 128; c++) |
|
|
|
|
{ |
|
|
|
|
if (midistate[m * 128 + c] >= 0) |
|
|
|
|
if (midistate_cc[m * 128 + c] >= 0) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("\tCC: %3d = %3d\n", c + 1, midistate[m * 128 + c]); |
|
|
|
|
DEBUG_MSG("\tCC: %3d = %3d\n", c + 1, midistate_cc[m * 128 + c]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
if (midistate_mute[m] > 0) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("\tMUTE\n"); |
|
|
|
|
} |
|
|
|
|
if (midistate_solo[m] > 0) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("\tSOLO\n"); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void set_midi_solo_mode(void) |
|
|
|
|
{ |
|
|
|
|
bool all_solo_off = true; |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Set MIDI solo mode\n"); |
|
|
|
|
|
|
|
|
|
for (uint8_t m = 0; m < 16; m++) |
|
|
|
|
{ |
|
|
|
|
if (midistate_solo[m] == 1) |
|
|
|
|
{ |
|
|
|
|
all_solo_off = false; |
|
|
|
|
|
|
|
|
|
MIDI1.sendControlChange(7, MIDI_SOLO_VOLUME, m + 1); |
|
|
|
|
DEBUG_MSG("\tChannel: %d: SOLO Volume: %d\n", m + 1, MIDI_SOLO_VOLUME); |
|
|
|
|
} |
|
|
|
|
else if (midistate_solo[m] == 0) |
|
|
|
|
{ |
|
|
|
|
MIDI1.sendControlChange(7, 0, m + 1); |
|
|
|
|
DEBUG_MSG("\tChannel: %d: Volume: %d\n", m + 1, 0); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (all_solo_off == true) |
|
|
|
|
{ |
|
|
|
|
set_midi_mute_mode(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void set_midi_mute_mode(void) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t m = 0; m < 16; m++) |
|
|
|
|
{ |
|
|
|
|
if (midistate_mute[m] == 1) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("\t Channel: %d: MUTE\n", m); |
|
|
|
|
MIDI1.sendControlChange(7, 0, m + 1); |
|
|
|
|
} |
|
|
|
|
else if (midistate_mute[m] == 0) |
|
|
|
|
MIDI1.sendControlChange(7, constrain(midistate_cc[m * 128 + 6], 0, 127), m + 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
@ -429,28 +603,26 @@ void check_write_state(void) |
|
|
|
|
{ |
|
|
|
|
write_midistate(1); |
|
|
|
|
write_state = false; |
|
|
|
|
show_midi_state(); |
|
|
|
|
show_midistate(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void write_midistate(uint8_t setup_number) |
|
|
|
|
void write_midistate_cc(uint8_t setup_number) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Write MIDI state\n"); |
|
|
|
|
|
|
|
|
|
uint32_t t0 = millis(); |
|
|
|
|
DEBUG_MSG("Write MIDI CC state\n"); |
|
|
|
|
|
|
|
|
|
for (uint8_t m = 0; m < 16; m++) |
|
|
|
|
{ |
|
|
|
|
for (uint8_t c = 0; c < 128; c++) |
|
|
|
|
{ |
|
|
|
|
if (midistate[m * 128 + c] >= 0) |
|
|
|
|
if (midistate_cc[m * 128 + c] >= 0) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Found MIDI Channel %2d, CC#%2d = %3d\n", m, c, midistate[m * 128 + c]); |
|
|
|
|
DEBUG_MSG("Found MIDI Channel %2d, CC#%2d = %3d\n", m, c, midistate_cc[m * 128 + c]); |
|
|
|
|
|
|
|
|
|
char midi_cc_name[33]; |
|
|
|
|
char midi_cc_name[24]; |
|
|
|
|
int16_t tmp_val; |
|
|
|
|
|
|
|
|
|
sprintf(midi_cc_name, "/%d/midistate/%d/%d", setup_number, m, c); |
|
|
|
|
sprintf(midi_cc_name, "/%d/midistate_cc/%d/%d", setup_number, m, c); |
|
|
|
|
|
|
|
|
|
if (SPIFFS.exists(midi_cc_name)) |
|
|
|
|
{ |
|
|
|
@ -458,7 +630,7 @@ void write_midistate(uint8_t setup_number) |
|
|
|
|
if (midi_cc) |
|
|
|
|
{ |
|
|
|
|
tmp_val = midi_cc.read(); |
|
|
|
|
DEBUG_MSG("Data for MIDI Channel %d, CC %d exists: %d\n", m, c, tmp_val); |
|
|
|
|
DEBUG_MSG("Data for MIDI Channel %d, CC %d exists : %d\n", m, c, tmp_val); |
|
|
|
|
} |
|
|
|
|
close(midi_cc); |
|
|
|
|
} |
|
|
|
@ -467,16 +639,16 @@ void write_midistate(uint8_t setup_number) |
|
|
|
|
tmp_val = -1; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (midistate[m * 128 + c] != tmp_val) |
|
|
|
|
if (midistate_cc[m * 128 + c] != tmp_val) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG(" Change from %d to %d detected\n", tmp_val, midistate[m * 128 + c]); |
|
|
|
|
DEBUG_MSG(" Change from %d to %d detected\n", tmp_val, midistate_cc[m * 128 + c]); |
|
|
|
|
|
|
|
|
|
File midi_cc = SPIFFS.open(midi_cc_name, "w"); |
|
|
|
|
if (midi_cc) |
|
|
|
|
{ |
|
|
|
|
midi_cc.write(midistate[m * 128 + c]); |
|
|
|
|
midi_cc.write(midistate_cc[m * 128 + c]); |
|
|
|
|
midi_cc.flush(); |
|
|
|
|
DEBUG_MSG("Wrote %d to %s.\n", midistate[m * 128 + c], midi_cc_name); |
|
|
|
|
DEBUG_MSG("Wrote %d to %s.\n", midistate_cc[m * 128 + c], midi_cc_name); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
DEBUG_MSG("Cannot write to %s.\n", midi_cc_name); |
|
|
|
@ -488,39 +660,35 @@ void write_midistate(uint8_t setup_number) |
|
|
|
|
|
|
|
|
|
lcd.setCursor(LCD_COL - 1, LCD_ROW - 1); |
|
|
|
|
lcd.print(" "); |
|
|
|
|
|
|
|
|
|
uint32_t t1 = millis(); |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("T1-T0=%d\n", t1 - t0); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void read_midistate(uint8_t setup_number) |
|
|
|
|
void read_midistate_cc(uint8_t setup_number) |
|
|
|
|
{ |
|
|
|
|
char setup_dir_name[33]; |
|
|
|
|
char setup_dir_name[24]; |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Read MIDI state\n"); |
|
|
|
|
DEBUG_MSG("Read MIDI CC state\n"); |
|
|
|
|
|
|
|
|
|
sprintf(setup_dir_name, "/%d/midistate", setup_number); |
|
|
|
|
sprintf(setup_dir_name, "/%d/midistate_cc", setup_number); |
|
|
|
|
|
|
|
|
|
File midistate_dir = SPIFFS.open(setup_dir_name); |
|
|
|
|
File midistate_cc_dir = SPIFFS.open(setup_dir_name); |
|
|
|
|
|
|
|
|
|
if (!midistate_dir) |
|
|
|
|
if (!midistate_cc_dir) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Failed to open directory %s.\n", setup_dir_name); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (!midistate_dir.isDirectory()) |
|
|
|
|
if (!midistate_cc_dir.isDirectory()) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("%s is not a directory.\n", setup_dir_name); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
File channel_cc = midistate_dir.openNextFile(); |
|
|
|
|
File channel_cc = midistate_cc_dir.openNextFile(); |
|
|
|
|
|
|
|
|
|
while (channel_cc) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Trying %s (Size: %d)\n", channel_cc.name(), channel_cc.size()); |
|
|
|
|
DEBUG_MSG("Trying %s (Size : %d)\n", channel_cc.name(), channel_cc.size()); |
|
|
|
|
|
|
|
|
|
if (uint8_t(channel_cc.size()) == 1) |
|
|
|
|
{ |
|
|
|
@ -547,40 +715,281 @@ void read_midistate(uint8_t setup_number) |
|
|
|
|
if (cc) |
|
|
|
|
{ |
|
|
|
|
int8_t val = cc.read(); |
|
|
|
|
DEBUG_MSG(" MIDI-Channel %d CC#%d = %d\n", midi_channel + 1, midi_cc + 1, val); |
|
|
|
|
midistate[midi_channel * 128 + midi_cc] = val; |
|
|
|
|
DEBUG_MSG(" MIDI - Channel %d CC#%d = %d\n", midi_channel + 1, midi_cc + 1, val); |
|
|
|
|
midistate_cc[midi_channel * 128 + midi_cc] = val; |
|
|
|
|
cc.close(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Removing %s: not the right size.\n", channel_cc.name()); |
|
|
|
|
DEBUG_MSG("Removing %s : not the right size.\n", channel_cc.name()); |
|
|
|
|
SPIFFS.remove(channel_cc.name()); |
|
|
|
|
} |
|
|
|
|
channel_cc = midistate_dir.openNextFile(); |
|
|
|
|
channel_cc = midistate_cc_dir.openNextFile(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void write_midistate_mute(uint8_t setup_number) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Write MIDI MUTE state\n"); |
|
|
|
|
|
|
|
|
|
for (uint8_t m = 0; m < 16; m++) |
|
|
|
|
{ |
|
|
|
|
if (midistate_mute[m] >= 0) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Found MIDI Channel %2d = %3d\n", m, midistate_mute[m]); |
|
|
|
|
|
|
|
|
|
char midi_mute_name[21]; |
|
|
|
|
int8_t tmp_val = -1; |
|
|
|
|
|
|
|
|
|
sprintf(midi_mute_name, "/%d/midistate_mute/%d", setup_number, m); |
|
|
|
|
|
|
|
|
|
if (SPIFFS.exists(midi_mute_name)) |
|
|
|
|
{ |
|
|
|
|
File midi_mute = SPIFFS.open(midi_mute_name, "r"); |
|
|
|
|
if (midi_mute) |
|
|
|
|
{ |
|
|
|
|
tmp_val = midi_mute.read(); |
|
|
|
|
DEBUG_MSG("Mute data for MIDI Channel %d exists : %d\n", m, tmp_val); |
|
|
|
|
} |
|
|
|
|
close(midi_mute); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (midistate_mute[m] != tmp_val) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG(" Change from %d to %d detected\n", tmp_val, midistate_mute[m]); |
|
|
|
|
|
|
|
|
|
File midi_mute = SPIFFS.open(midi_mute_name, "w"); |
|
|
|
|
if (midi_mute) |
|
|
|
|
{ |
|
|
|
|
midi_mute.write(midistate_mute[m]); |
|
|
|
|
midi_mute.flush(); |
|
|
|
|
DEBUG_MSG("Wrote %d to %s.\n", midistate_mute[m], midi_mute_name); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
DEBUG_MSG("Cannot write to %s.\n", midi_mute_name); |
|
|
|
|
close(midi_mute); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void read_midistate_mute(uint8_t setup_number) |
|
|
|
|
{ |
|
|
|
|
char setup_dir_name[21]; |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Read MIDI MUTE state\n"); |
|
|
|
|
|
|
|
|
|
sprintf(setup_dir_name, "/%d/midistate_mute", setup_number); |
|
|
|
|
|
|
|
|
|
File midistate_mute_dir = SPIFFS.open(setup_dir_name); |
|
|
|
|
|
|
|
|
|
if (!midistate_mute_dir) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Failed to open directory %s.\n", setup_dir_name); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
File channel_mute = midistate_mute_dir.openNextFile(); |
|
|
|
|
|
|
|
|
|
while (channel_mute) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Trying %s (Size : %d)\n", channel_mute.name(), channel_mute.size()); |
|
|
|
|
|
|
|
|
|
if (uint8_t(channel_mute.size()) == 1) |
|
|
|
|
{ |
|
|
|
|
if (!channel_mute.isDirectory()) |
|
|
|
|
{ |
|
|
|
|
char tmp_name[21]; |
|
|
|
|
uint8_t midi_channel; |
|
|
|
|
uint8_t count = 0; |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Using %s\n", channel_mute.name()); |
|
|
|
|
|
|
|
|
|
strcpy(tmp_name, channel_mute.name()); |
|
|
|
|
for (String part = strtok(tmp_name, "/"); part; part = strtok(NULL, "/")) |
|
|
|
|
{ |
|
|
|
|
count++; |
|
|
|
|
if (count == 3) |
|
|
|
|
midi_channel = atoi(part.c_str()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
File mute = SPIFFS.open(channel_mute.name(), "r"); |
|
|
|
|
if (mute) |
|
|
|
|
{ |
|
|
|
|
int8_t val = mute.read(); |
|
|
|
|
DEBUG_MSG(" MIDI - Channel MUTE %d = %d\n", midi_channel + 1, val); |
|
|
|
|
midistate_mute[midi_channel] = val; |
|
|
|
|
mute.close(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Removing %s : not the right size.\n", channel_mute.name()); |
|
|
|
|
SPIFFS.remove(channel_mute.name()); |
|
|
|
|
} |
|
|
|
|
channel_mute = midistate_mute_dir.openNextFile(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void write_midistate_solo(uint8_t setup_number) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Write MIDI SOLO state\n"); |
|
|
|
|
|
|
|
|
|
for (uint8_t m = 0; m < 16; m++) |
|
|
|
|
{ |
|
|
|
|
if (midistate_solo[m] >= 0) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Found MIDI Channel %2d = %3d\n", m, midistate_solo[m]); |
|
|
|
|
|
|
|
|
|
char midi_solo_name[21]; |
|
|
|
|
int8_t tmp_val = -1; |
|
|
|
|
|
|
|
|
|
sprintf(midi_solo_name, "/%d/midistate_solo/%d", setup_number, m); |
|
|
|
|
|
|
|
|
|
if (SPIFFS.exists(midi_solo_name)) |
|
|
|
|
{ |
|
|
|
|
File midi_solo = SPIFFS.open(midi_solo_name, "r"); |
|
|
|
|
if (midi_solo) |
|
|
|
|
{ |
|
|
|
|
tmp_val = midi_solo.read(); |
|
|
|
|
DEBUG_MSG("Solo data for MIDI Channel %d exists : %d\n", m, tmp_val); |
|
|
|
|
} |
|
|
|
|
close(midi_solo); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (midistate_solo[m] != tmp_val) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG(" Change from %d to %d detected\n", tmp_val, midistate_solo[m]); |
|
|
|
|
|
|
|
|
|
File midi_solo = SPIFFS.open(midi_solo_name, "w"); |
|
|
|
|
if (midi_solo) |
|
|
|
|
{ |
|
|
|
|
midi_solo.write(midistate_solo[m]); |
|
|
|
|
midi_solo.flush(); |
|
|
|
|
DEBUG_MSG("Wrote %d to %s.\n", midistate_solo[m], midi_solo_name); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
DEBUG_MSG("Cannot write to %s.\n", midi_solo_name); |
|
|
|
|
close(midi_solo); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void read_midistate_solo(uint8_t setup_number) |
|
|
|
|
{ |
|
|
|
|
char setup_dir_name[21]; |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Read MIDI SOLO state\n"); |
|
|
|
|
|
|
|
|
|
sprintf(setup_dir_name, "/%d/midistate_solo", setup_number); |
|
|
|
|
|
|
|
|
|
File midistate_solo_dir = SPIFFS.open(setup_dir_name); |
|
|
|
|
|
|
|
|
|
if (!midistate_solo_dir) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Failed to open directory %s.\n", setup_dir_name); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
File channel_solo = midistate_solo_dir.openNextFile(); |
|
|
|
|
|
|
|
|
|
while (channel_solo) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Trying %s (Size : %d)\n", channel_solo.name(), channel_solo.size()); |
|
|
|
|
|
|
|
|
|
if (uint8_t(channel_solo.size()) == 1) |
|
|
|
|
{ |
|
|
|
|
if (!channel_solo.isDirectory()) |
|
|
|
|
{ |
|
|
|
|
char tmp_name[20]; |
|
|
|
|
uint8_t midi_channel; |
|
|
|
|
uint8_t count = 0; |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Using %s\n", channel_solo.name()); |
|
|
|
|
|
|
|
|
|
strcpy(tmp_name, channel_solo.name()); |
|
|
|
|
for (String part = strtok(tmp_name, "/"); part; part = strtok(NULL, "/")) |
|
|
|
|
{ |
|
|
|
|
count++; |
|
|
|
|
if (count == 3) |
|
|
|
|
midi_channel = atoi(part.c_str()); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
File solo = SPIFFS.open(channel_solo.name(), "r"); |
|
|
|
|
if (solo) |
|
|
|
|
{ |
|
|
|
|
int8_t val = solo.read(); |
|
|
|
|
DEBUG_MSG(" MIDI - Channel SOLO %d = %d\n", midi_channel + 1, val); |
|
|
|
|
midistate_solo[midi_channel] = val; |
|
|
|
|
solo.close(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("Removing %s : not the right size.\n", channel_solo.name()); |
|
|
|
|
SPIFFS.remove(channel_solo.name()); |
|
|
|
|
} |
|
|
|
|
channel_solo = midistate_solo_dir.openNextFile(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
set_midi_solo_mode(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void read_midistate(uint8_t setup_number) |
|
|
|
|
{ |
|
|
|
|
read_midistate_cc(setup_number); |
|
|
|
|
read_midistate_mute(setup_number); |
|
|
|
|
read_midistate_solo(setup_number); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void write_midistate(uint8_t setup_number) |
|
|
|
|
{ |
|
|
|
|
write_midistate_cc(setup_number); |
|
|
|
|
write_midistate_mute(setup_number); |
|
|
|
|
write_midistate_solo(setup_number); |
|
|
|
|
|
|
|
|
|
lcd.setCursor(LCD_COL - 1, LCD_ROW - 1); |
|
|
|
|
lcd.print(" "); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void broadcast_midistate(void) |
|
|
|
|
{ |
|
|
|
|
uint8_t m, c; |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("Broadcast MIDI state:\n"); |
|
|
|
|
DEBUG_MSG("Broadcast MIDI CC state : \n"); |
|
|
|
|
|
|
|
|
|
for (m = 0; m < 16; m++) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("MIDI-Channel %2d\n", m + 1); |
|
|
|
|
DEBUG_MSG("MIDI - Channel %2d\n", m + 1); |
|
|
|
|
for (c = 0; c < 128; c++) |
|
|
|
|
{ |
|
|
|
|
if (midistate[m * 128 + c] >= 0) |
|
|
|
|
if (midistate_cc[m * 128 + c] >= 0) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("\tCC: %3d = %3d\n", c + 1, midistate[m * 128 + c]); |
|
|
|
|
MidiCCToOSC(m + 1, c + 1, midistate[m * 128 + c]); |
|
|
|
|
MIDI1.sendControlChange(c + 1, midistate[m * 128 + c], m + 1); |
|
|
|
|
DEBUG_MSG("\tCC : %3d = %3d\n", c + 1, midistate_cc[m * 128 + c]); |
|
|
|
|
MidiCCToOSC(m + 1, c + 1, midistate_cc[m * 128 + c]); |
|
|
|
|
MIDI1.sendControlChange(c + 1, midistate_cc[m * 128 + c], m + 1); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (midistate_mute[m] >= 0) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("\tMUTE : %3d\n", midistate_solo[m]); |
|
|
|
|
MidiMuteToOSC(m + 1, midistate_mute[m]); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
if (midistate_solo[m] >= 0) |
|
|
|
|
{ |
|
|
|
|
DEBUG_MSG("\SOLO : %3d\n", midistate_solo[m]); |
|
|
|
|
MidiSoloToOSC(m + 1, midistate_solo[m]); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
set_midi_solo_mode(); |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void check_reset_ap_data(void) |
|
|
|
@ -620,12 +1029,13 @@ void ping(OSCMessage & msg, int offset) |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void listDir(fs::FS & fs, const char * dirname, uint8_t levels) { |
|
|
|
|
Serial.printf("Listing directory: %s\r\n", dirname); |
|
|
|
|
void listDir(fs::FS & fs, const char * dirname, uint8_t levels) |
|
|
|
|
{ |
|
|
|
|
Serial.printf("Listing directory : %s\r\n", dirname); |
|
|
|
|
|
|
|
|
|
File root = fs.open(dirname); |
|
|
|
|
if (!root) { |
|
|
|
|
Serial.println("- failed to open directory"); |
|
|
|
|
Serial.println(" - failed to open directory"); |
|
|
|
|
return; |
|
|
|
|
} |
|
|
|
|
if (!root.isDirectory()) { |
|
|
|
@ -642,9 +1052,9 @@ void listDir(fs::FS & fs, const char * dirname, uint8_t levels) { |
|
|
|
|
listDir(fs, file.name(), levels - 1); |
|
|
|
|
} |
|
|
|
|
} else { |
|
|
|
|
Serial.print(" FILE: "); |
|
|
|
|
Serial.print(" FILE : "); |
|
|
|
|
Serial.print(file.name()); |
|
|
|
|
Serial.print("\tSIZE: "); |
|
|
|
|
Serial.print("\tSIZE : "); |
|
|
|
|
Serial.println(file.size()); |
|
|
|
|
} |
|
|
|
|
file = root.openNextFile(); |
|
|
|
|