|
|
|
@ -1,4 +1,18 @@ |
|
|
|
|
// .../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 <Arduino.h> |
|
|
|
@ -10,19 +24,13 @@ |
|
|
|
|
#include <OSCData.h> |
|
|
|
|
#include <MIDI.h> |
|
|
|
|
#include "OSC2Midi.h" |
|
|
|
|
#include <HardwareSerial.h> |
|
|
|
|
|
|
|
|
|
void OSCToMidiCC(OSCMessage &msg, int offset); |
|
|
|
|
void MidiCCToOSC(uint8_t channel, uint8_t number, uint8_t value); |
|
|
|
|
|
|
|
|
|
WiFiUDP udp; |
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
|
source address of last OSC message for midi2osc messages. |
|
|
|
|
*/ |
|
|
|
|
IPAddress clientIP; |
|
|
|
|
|
|
|
|
|
/*IPAddress local_IP(192,168,4,2);
|
|
|
|
|
IPAddress gateway(192,168,4,1); |
|
|
|
|
IPAddress subnet(255,255,255,0);*/ |
|
|
|
|
IPAddress clientIP; // store client IP for feedback
|
|
|
|
|
|
|
|
|
|
/*
|
|
|
|
|
UART RX IO TX IO CTS RTS |
|
|
|
@ -31,27 +39,129 @@ IPAddress clientIP; |
|
|
|
|
UART2 GPIO16 GPIO17 GPIO8 GPIO7 |
|
|
|
|
*/ |
|
|
|
|
|
|
|
|
|
MIDI_CREATE_INSTANCE(HardwareSerial, Serial2, MIDI); // Pins on ESP32: RX: 6, TX: 7
|
|
|
|
|
//MIDI_CREATE_INSTANCE(HardwareSerial, Serial1, MIDI2); // Pins on ESP32: RX: ?, TX: ?
|
|
|
|
|
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() |
|
|
|
|
{ |
|
|
|
|
Serial2.begin(31250); |
|
|
|
|
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("\nHello OSC2Midi!\n"); |
|
|
|
|
DEBUG_MSG("<start>\nOSC2Midi\n"); |
|
|
|
|
|
|
|
|
|
WiFi.softAP("OSC2Midi", "1357924680"); |
|
|
|
|
pinMode(AP_TRIGGER_PIN, INPUT_PULLUP); |
|
|
|
|
|
|
|
|
|
DEBUG_MSG("\nAP IP address: %s\n", WiFi.softAPIP().toString().c_str()); |
|
|
|
|
//WiFi.softAP("OSC2Midi", "1357924680");
|
|
|
|
|
|
|
|
|
|
udp.begin(8000); |
|
|
|
|
|
|
|
|
|
MIDI.begin(MIDI_CHANNEL_OMNI); |
|
|
|
|
MIDI.setHandleControlChange(MidiCCToOSC); |
|
|
|
|
MIDI.turnThruOff(); |
|
|
|
|
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) |
|
|
|
@ -71,7 +181,7 @@ 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); |
|
|
|
|
MIDI.sendControlChange(cc, value, midichannel); |
|
|
|
|
MIDI1.sendControlChange(cc, value, midichannel); |
|
|
|
|
} |
|
|
|
|
else if (msg.size() == 2 && msg.isFloat(0) && msg.isFloat(1)) |
|
|
|
|
{ |
|
|
|
@ -80,12 +190,12 @@ 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); |
|
|
|
|
MIDI.sendControlChange(cc, value, midichannel); |
|
|
|
|
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); |
|
|
|
|
MIDI.sendControlChange(cc, value, midichannel); |
|
|
|
|
MIDI1.sendControlChange(cc, value, midichannel); |
|
|
|
|
} |
|
|
|
|
else |
|
|
|
|
{ |
|
|
|
@ -111,39 +221,3 @@ void MidiCCToOSC(uint8_t channel, uint8_t number, uint8_t val) |
|
|
|
|
udp.endPacket(); |
|
|
|
|
} |
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
void loop() |
|
|
|
|
{ |
|
|
|
|
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
|
|
|
|
|
MIDI.read(); |
|
|
|
|
} |
|
|
|
|