Added handling and storing of mute and solo state.

master
Holger Wirtz 4 years ago
parent 98b3a0b491
commit 989ed20434
  1. 538
      OSC2MIDI.ino

@ -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();

Loading…
Cancel
Save