// .../Arduino/hardware/espressif/esp32/cores/esp32/HardwareSerial.cpp: /* #ifndef RX1 #define RX1 35 #endif #ifndef TX1 #define TX1 34 #endif */ #define DEBUG 1 #define AP_TRIGGER_PIN 15 #define AP_TIMEOUT 120 #define AP_NAME "OSC2MidiBridge" #include "debug.h" #include //#include #include #include #include #include #include #include #include "OSC2Midi.h" #include void OSCToMidiCC(OSCMessage &msg, int offset); void MidiCCToOSC(uint8_t channel, uint8_t number, uint8_t value); WiFiUDP udp; IPAddress clientIP; // store client IP for feedback /* UART RX IO TX IO CTS RTS UART0 GPIO3 GPIO1 N/A N/A UART1 GPIO9 GPIO10 GPIO6 GPIO11 UART2 GPIO16 GPIO17 GPIO8 GPIO7 */ HardwareSerial midi1(2); // RX: 16, TX: 17 HardwareSerial midi2(1); // RX: 35, TX: 34 (changed in .../Arduino/hardware/espressif/esp32/cores/esp32/HardwareSerial.cpp!) MIDI_CREATE_INSTANCE(HardwareSerial, midi1, MIDI1); MIDI_CREATE_INSTANCE(HardwareSerial, midi2, MIDI2); void setup() { WiFi.mode(WIFI_STA); // explicitly set mode, esp defaults to STA+AP /* midi1.begin(31250, SERIAL_8N1, 16, 17); midi2.begin(31250, SERIAL_8N1, 35, 34); */ midi1.begin(31250); midi2.begin(31250); Serial.begin(115200); Serial.setDebugOutput(true); DEBUG_MSG("\nOSC2Midi\n"); pinMode(AP_TRIGGER_PIN, INPUT_PULLUP); //WiFi.softAP("OSC2Midi", "1357924680"); udp.begin(8000); MIDI1.begin(MIDI_CHANNEL_OMNI); MIDI1.setHandleControlChange(MidiCCToOSC); MIDI1.turnThruOff(); MIDI2.begin(MIDI_CHANNEL_OMNI); MIDI2.setHandleControlChange(MidiCCToOSC); MIDI2.turnThruOff(); } void loop() { // check if we need to configure a AP if (digitalRead(AP_TRIGGER_PIN) == LOW) { WiFiManager wm; //reset settings - for testing //wifiManager.resetSettings(); wm.setConfigPortalTimeout(AP_TIMEOUT); if (!wm.startConfigPortal(AP_NAME)) { DEBUG_MSG("Failed to connect and hit timeout - restarting!\n"); delay(3000); ESP.restart(); delay(5000); } DEBUG_MSG("\nAP IP address: %s\n", WiFi.softAPIP().toString().c_str()); } else { OSCMessage msg; uint8_t buffer[1024]; uint16_t outPort; // Check if there are any OSC packets to handle size_t size = udp.parsePacket(); if (size > 0 && size <= 1024) { udp.read(buffer, size); msg.fill(buffer, size); if (!msg.hasError()) { DEBUG_OSC_MESSAGE(msg); msg.route("/midi/cc", OSCToMidiCC); //msg.route("/midi/sysex", OSCToMidiSYSEX); //msg.route("/midi/note", OSCToMidiNote); } else { DEBUG_MSG("Error parsing OSC message: %d\n", msg.getError()); } // Keep track of the client IP address for "talking back" clientIP = udp.remoteIP(); udp.flush(); } // Check if there are any CC messages from synth itself //MIDI1.read(); if (MIDI1.read()) { Serial.print("MIDI-IN[1] Type: "); Serial.print(MIDI1.getType(), DEC); Serial.print(" Data1: "); Serial.print(MIDI1.getData1(), DEC); Serial.print(" Data2: "); Serial.print(MIDI1.getData2(), DEC); Serial.print(" Channel: "); Serial.print(MIDI1.getChannel(), DEC); Serial.println(" Channel: "); } // MIDI-Merger from MIDI2 to MIDI1 if (MIDI2.read()) { MIDI1.send(MIDI2.getType(), MIDI2.getData1(), MIDI2.getData2(), MIDI2.getChannel()); Serial.print("MIDI-IN[2] Type: "); Serial.print(MIDI2.getType(), DEC); Serial.print(" Data1: "); Serial.print(MIDI2.getData1(), DEC); Serial.print(" Data2: "); Serial.print(MIDI2.getData2(), DEC); Serial.print(" Channel: "); Serial.print(MIDI2.getChannel(), DEC); Serial.println(" Channel: "); } } } void OSCToMidiCC(OSCMessage & msg, int offset) { char address[100] = { 0 }; uint8_t cc, value; uint8_t midichannel; msg.getAddress(address, offset, sizeof(address)); midichannel = getMIDIChannel(address); //midichannel--; if (msg.size() == 1 && msg.isFloat(0)) { // Single or multi control with sending one value cc = getCC(address); 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); } else if (msg.size() == 2 && msg.isFloat(0) && msg.isFloat(1)) { // XY pad, two values cc = getVar(address, 1); 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); cc = getVar(address, 2); value = round(msg.getFloat(1)); 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); } else { DEBUG_MSG("Cannot handle: %s\n", address); } } void MidiCCToOSC(uint8_t channel, uint8_t number, uint8_t val) { char buffer[1024]; snprintf(buffer, sizeof(buffer), "/midi/cc/%u/%u", channel, number); DEBUG_MSG("MidiCCToOsc: %s %f\n", buffer, val * 1.0); if (clientIP) { OSCMessage msg = OSCMessage(buffer); msg.add(val); udp.beginPacket(clientIP, 9000); msg.send(udp); udp.endPacket(); } }