|
|
|
// .../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>
|
|
|
|
//#include <ESP8266WiFi.h>
|
|
|
|
#include <WiFiManager.h>
|
|
|
|
#include <WiFiUdp.h>
|
|
|
|
#include <OSCMessage.h>
|
|
|
|
#include <OSCBundle.h>
|
|
|
|
#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;
|
|
|
|
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("<start>\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();
|
|
|
|
}
|
|
|
|
}
|