parent
2dc6d3cddc
commit
15449c78ab
@ -0,0 +1,42 @@ |
|||||||
|
#include "OSC2Midi.h" |
||||||
|
#include <string.h> |
||||||
|
#include <stdlib.h> |
||||||
|
|
||||||
|
/*
|
||||||
|
* TODO: this will return rather unpredictable numbers when
|
||||||
|
* given strings with numbers > 255. |
||||||
|
*/ |
||||||
|
uint8_t getCC(const char *str, int index) |
||||||
|
{ |
||||||
|
const char *offset = str; |
||||||
|
|
||||||
|
// skip the first /
|
||||||
|
if (strncmp(str, "/", strlen("/")) == 0) |
||||||
|
{ |
||||||
|
offset++; |
||||||
|
} |
||||||
|
|
||||||
|
if (index == -1) |
||||||
|
{ |
||||||
|
return atoi(offset); |
||||||
|
} |
||||||
|
|
||||||
|
while (index > 0) |
||||||
|
{ |
||||||
|
const char *new_offset = strstr(offset, "/"); |
||||||
|
if (new_offset) { |
||||||
|
offset = new_offset + 1; |
||||||
|
} else { |
||||||
|
return 0; |
||||||
|
} |
||||||
|
|
||||||
|
index--; |
||||||
|
} |
||||||
|
|
||||||
|
return atoi(offset); |
||||||
|
} |
||||||
|
|
||||||
|
uint8_t getCC(const char *str) |
||||||
|
{ |
||||||
|
return getCC(str, -1); |
||||||
|
} |
@ -0,0 +1,9 @@ |
|||||||
|
#ifndef OSC2MIDI_H |
||||||
|
#define OSC2MIDI_H |
||||||
|
|
||||||
|
#include <cstdint> |
||||||
|
|
||||||
|
uint8_t getCC(const char *str, int index); |
||||||
|
uint8_t getCC(const char *str); |
||||||
|
|
||||||
|
#endif |
@ -0,0 +1,116 @@ |
|||||||
|
#include "debug.h" |
||||||
|
#include <Arduino.h> |
||||||
|
#include <ESP8266WiFi.h> |
||||||
|
#include <WiFiUdp.h> |
||||||
|
#include <OSCMessage.h> |
||||||
|
#include <OSCBundle.h> |
||||||
|
#include <OSCData.h> |
||||||
|
#include <MIDI.h> |
||||||
|
#include "OSC2Midi.h" |
||||||
|
|
||||||
|
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);*/ |
||||||
|
|
||||||
|
MIDI_CREATE_INSTANCE(HardwareSerial, Serial, MIDI); |
||||||
|
|
||||||
|
void setup() { |
||||||
|
// Midi via UART0
|
||||||
|
Serial.begin(31250); |
||||||
|
Serial.swap(); |
||||||
|
|
||||||
|
#ifdef DEBUG |
||||||
|
// Debug via UART1 TX only
|
||||||
|
Serial1.begin(115200, SERIAL_8N1, SERIAL_TX_ONLY, 2); |
||||||
|
Serial1.setDebugOutput(true); |
||||||
|
#endif |
||||||
|
|
||||||
|
DEBUG_MSG("\nHello OSC2Midi!\n"); |
||||||
|
|
||||||
|
WiFi.softAP("OSC2Midi", "Midi2OSCGateway"); |
||||||
|
|
||||||
|
DEBUG_MSG("\nAP IP address: %s\n", WiFi.softAPIP().toString().c_str()); |
||||||
|
|
||||||
|
udp.begin(8000); |
||||||
|
|
||||||
|
MIDI.setHandleControlChange(MidiCCToOSC); |
||||||
|
} |
||||||
|
|
||||||
|
void OSCToMidiCC(OSCMessage &msg, int offset) { |
||||||
|
char address[100] = { 0 }; |
||||||
|
uint8_t cc, value; |
||||||
|
|
||||||
|
msg.getAddress(address, offset, sizeof(address)); |
||||||
|
|
||||||
|
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\tCC: %u\tValue: %u\n", address, cc, value); |
||||||
|
MIDI.sendControlChange(cc, value, 1); |
||||||
|
} else if (msg.size() == 2 && msg.isFloat(0) && msg.isFloat(1)) { |
||||||
|
// XY pad, two values
|
||||||
|
cc = getCC(address, 0); |
||||||
|
value = round(msg.getFloat(0)); |
||||||
|
value = value > 127 ? 127 : value; |
||||||
|
DEBUG_MSG("MSG: %s\tCC: %u\tValue: %u\n", address, cc, value); |
||||||
|
MIDI.sendControlChange(cc, value, 1); |
||||||
|
|
||||||
|
cc = getCC(address, 1); |
||||||
|
value = round(msg.getFloat(1)); |
||||||
|
value = value > 127 ? 127 : value; |
||||||
|
DEBUG_MSG("MSG: %s\tCC: %u\tValue: %u\n", address, cc, value); |
||||||
|
MIDI.sendControlChange(cc, value, 1); |
||||||
|
} else { |
||||||
|
DEBUG_MSG("Cannot handle: %s\n", address); |
||||||
|
} |
||||||
|
} |
||||||
|
|
||||||
|
void MidiCCToOSC(uint8_t channel, uint8_t number, uint8_t value) { |
||||||
|
char buffer[1024]; |
||||||
|
snprintf(buffer, sizeof(buffer), "/midi/cc/%u", number); |
||||||
|
|
||||||
|
OSCMessage msg = OSCMessage(buffer); |
||||||
|
msg.add(value * 1.0); |
||||||
|
|
||||||
|
DEBUG_MSG("MidiCCToOsc: %s %f", buffer, value * 1.0); |
||||||
|
|
||||||
|
udp.beginPacket(clientIP, 8001); |
||||||
|
msg.send(udp); |
||||||
|
udp.endPacket(); |
||||||
|
} |
||||||
|
|
||||||
|
void loop() { |
||||||
|
OSCMessage msg; |
||||||
|
uint8_t buffer[1024]; |
||||||
|
|
||||||
|
// 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); |
||||||
|
} else { |
||||||
|
DEBUG_MSG("Error parsing OSC message: %d\n", msg.getError()); |
||||||
|
} |
||||||
|
|
||||||
|
// Keep track of the client IP address for "talking back"
|
||||||
|
clientIP = udp.remoteIP(); |
||||||
|
} |
||||||
|
|
||||||
|
// Check if there are any CC messages from synth itself
|
||||||
|
MIDI.read(); |
||||||
|
} |
@ -0,0 +1,26 @@ |
|||||||
|
#ifndef DEBUG_H |
||||||
|
#define DEBUG_H |
||||||
|
|
||||||
|
#ifdef DEBUG |
||||||
|
|
||||||
|
#define DEBUG_ESP_PORT Serial1 |
||||||
|
#define DEBUG_MSG(...) Serial1.printf( __VA_ARGS__ ) |
||||||
|
|
||||||
|
#define DEBUG_OSC_MESSAGE(msg) \ |
||||||
|
do { \
|
||||||
|
char address[100]; \
|
||||||
|
msg.getAddress(address, 0, sizeof(address)); \
|
||||||
|
Serial1.printf("osc message: [%d] %s ", msg.size(), address); \
|
||||||
|
for (int i = 0; i < msg.size(); i++) { \
|
||||||
|
if (msg.isFloat(i)) { Serial1.printf("f:%f\t", msg.getFloat(i)); } \
|
||||||
|
if (msg.isInt(i)) { Serial1.printf("i:%d\t", msg.getInt(i)); } \
|
||||||
|
} \
|
||||||
|
Serial1.printf("\n"); \
|
||||||
|
} while(0); |
||||||
|
|
||||||
|
#else |
||||||
|
#define DEBUG_MSG(...) |
||||||
|
#define DEBUG_OSC_MESSAGE(...) |
||||||
|
#endif |
||||||
|
|
||||||
|
#endif |
Loading…
Reference in new issue