From bf21ddcd78ad297a24cece220234f84595444360 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Sun, 18 Mar 2018 06:12:53 -0400 Subject: [PATCH] Bridge progress --- dep/oui-blendish | 2 +- include/bridge.hpp | 3 ++ include/bridgeprotocol.hpp | 14 +++++--- include/midi.hpp | 4 +-- src/audio.cpp | 3 -- src/bridge.cpp | 65 ++++++++++++++++++++++++-------------- src/midi.cpp | 19 +++++------ 7 files changed, 67 insertions(+), 43 deletions(-) diff --git a/dep/oui-blendish b/dep/oui-blendish index b7066201..383f24f6 160000 --- a/dep/oui-blendish +++ b/dep/oui-blendish @@ -1 +1 @@ -Subproject commit b7066201022a757cbcbd986d8c91d565e4daef90 +Subproject commit 383f24f6ed41facf25eda0d32b0f6bc9aee96e53 diff --git a/include/bridge.hpp b/include/bridge.hpp index 2605bbfc..28dfbc06 100644 --- a/include/bridge.hpp +++ b/include/bridge.hpp @@ -1,6 +1,7 @@ #pragma once #include "bridgeprotocol.hpp" #include "audio.hpp" +#include "midi.hpp" namespace rack { @@ -8,6 +9,8 @@ namespace rack { void bridgeInit(); void bridgeDestroy(); +void bridgeMidiSubscribe(int channel, MidiInput *midi); +void bridgeMidiUnsubscribe(int channel, MidiInput *midi); void bridgeAudioSubscribe(int channel, AudioIO *audio); void bridgeAudioUnsubscribe(int channel, AudioIO *audio); diff --git a/include/bridgeprotocol.hpp b/include/bridgeprotocol.hpp index a728ed89..d3194102 100644 --- a/include/bridgeprotocol.hpp +++ b/include/bridgeprotocol.hpp @@ -5,10 +5,16 @@ namespace rack { -static const int BRIDGE_NUM_PORTS = 16; -static const int BRIDGE_NUM_PARAMS = 16; -// A random number which prevents connection from other protocols and old Bridge versions -const uint32_t BRIDGE_HELLO = 0xff00fefd; +// TODO Change driver and port number to something less common +/** Driver ID in AudioIO and MidiIO */ +#define BRIDGE_DRIVER -5000 +#define BRIDGE_HOST "127.0.0.1" +#define BRIDGE_PORT 5000 +#define BRIDGE_NUM_PORTS 16 +/** Number of VST/AU automation parameters */ +#define BRIDGE_NUM_PARAMS 16 +/** An arbitrary number which prevents connection from other protocols (like WebSockets) and old Bridge versions */ +#define BRIDGE_HELLO 0xff00fefd /** All commands are called from the client and served by the server diff --git a/include/midi.hpp b/include/midi.hpp index 5cf1e7d0..ff1f9220 100644 --- a/include/midi.hpp +++ b/include/midi.hpp @@ -70,14 +70,14 @@ struct MidiInput : MidiIO { MidiInput(); ~MidiInput(); void setDriver(int driver) override; - virtual void onMessage(const MidiMessage &message) {} + virtual void onMessage(MidiMessage message) {} }; struct MidiInputQueue : MidiInput { int queueSize = 8192; std::queue queue; - void onMessage(const MidiMessage &message) override; + void onMessage(MidiMessage message) override; /** If a MidiMessage is available, writes `message` and return true */ bool shift(MidiMessage *message); }; diff --git a/src/audio.cpp b/src/audio.cpp index fbef04ed..140e1b53 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -3,9 +3,6 @@ #include "bridge.hpp" -#define BRIDGE_DRIVER -5000 - - namespace rack { diff --git a/src/bridge.cpp b/src/bridge.cpp index a7952ffb..9e06db7b 100644 --- a/src/bridge.cpp +++ b/src/bridge.cpp @@ -24,6 +24,7 @@ namespace rack { struct BridgeClientConnection; static BridgeClientConnection *connections[BRIDGE_NUM_PORTS] = {}; static AudioIO *audioListeners[BRIDGE_NUM_PORTS] = {}; +static MidiInput *midiListeners[BRIDGE_NUM_PORTS] = {}; static std::thread serverThread; static bool serverRunning = false; @@ -51,7 +52,7 @@ struct BridgeClientConnection { #else int flags = 0; #endif - ssize_t actual = ::send(client, buffer, length, flags); + ssize_t actual = ::send(client, (const char*) buffer, length, flags); if (actual != length) { ready = false; return false; @@ -74,7 +75,7 @@ struct BridgeClientConnection { #else int flags = 0; #endif - ssize_t actual = ::recv(client, buffer, length, flags); + ssize_t actual = ::recv(client, (char*) buffer, length, flags); if (actual != length) { ready = false; return false; @@ -145,9 +146,12 @@ struct BridgeClientConnection { } break; case MIDI_MESSAGE_SEND_COMMAND: { - uint8_t midiBuffer[3]; - recv(&midiBuffer, 3); - debug("MIDI: %02x %02x %02x", midiBuffer[0], midiBuffer[1], midiBuffer[2]); + MidiMessage message; + if (!recv(&message, 3)) { + ready = false; + return; + } + processMidi(message); } break; case AUDIO_SAMPLE_RATE_SET_COMMAND: { @@ -214,6 +218,14 @@ struct BridgeClientConnection { } } + void processMidi(MidiMessage message) { + if (!(0 <= port && port < BRIDGE_NUM_PORTS)) + return; + if (!midiListeners[port]) + return; + midiListeners[port]->onMessage(message); + } + void setSampleRate(int sampleRate) { this->sampleRate = sampleRate; refreshAudio(); @@ -288,29 +300,15 @@ static void serverConnect() { #endif // Get address -#ifdef ARCH_WIN - struct addrinfo hints; - struct addrinfo *result = NULL; - ZeroMemory(&hints, sizeof(hints)); - hints.ai_family = AF_INET; - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - hints.ai_flags = AI_PASSIVE; - err = getaddrinfo("127.0.0.1", "5000", &hints, &result); - if (err) { - warn("Could not get Bridge server address"); - return; - } - defer({ - freeaddrinfo(result); - }); -#else struct sockaddr_in addr; memset(&addr, 0, sizeof(addr)); addr.sin_family = AF_INET; - inet_pton(AF_INET, "127.0.0.1", &addr.sin_addr); - addr.sin_port = htons(5000); +#ifdef ARCH_WIN + InetPton(AF_INET, BRIDGE_HOST, &addr.sin_addr); +#else + inet_pton(AF_INET, BRIDGE_HOST, &addr.sin_addr); #endif + addr.sin_port = htons(BRIDGE_PORT); // Open socket #ifdef ARCH_WIN @@ -389,6 +387,25 @@ void bridgeDestroy() { serverThread.join(); } +void bridgeMidiSubscribe(int port, MidiInput *midi) { + if (!(0 <= port && port < BRIDGE_NUM_PORTS)) + return; + // Check if a Midi is already subscribed on the port + if (midiListeners[port]) + return; + midiListeners[port] = midi; + if (connections[port]) + connections[port]->refreshAudio(); +} + +void bridgeMidiUnsubscribe(int port, MidiInput *midi) { + if (!(0 <= port && port < BRIDGE_NUM_PORTS)) + return; + if (midiListeners[port] != midi) + return; + midiListeners[port] = NULL; +} + void bridgeAudioSubscribe(int port, AudioIO *audio) { if (!(0 <= port && port < BRIDGE_NUM_PORTS)) return; diff --git a/src/midi.cpp b/src/midi.cpp index 06911484..f5c09215 100644 --- a/src/midi.cpp +++ b/src/midi.cpp @@ -2,9 +2,6 @@ #include "bridge.hpp" -#define BRIDGE_DRIVER -5000 - - namespace rack { @@ -133,11 +130,6 @@ static void midiInputCallback(double timeStamp, std::vector *mess if (message->size() >= 3) msg.data2 = (*message)[2]; - // Filter channel - if (midiInput->channel >= 0) { - if (msg.status() != 0xf && msg.channel() != midiInput->channel) - return; - } midiInput->onMessage(msg); } @@ -163,9 +155,18 @@ void MidiInput::setDriver(int driver) { rtMidi = rtMidiIn; this->driver = rtMidiIn->getCurrentApi(); } + else if (driver == BRIDGE_DRIVER) { + + } } -void MidiInputQueue::onMessage(const MidiMessage &message) { +void MidiInputQueue::onMessage(MidiMessage message) { + // Filter channel + if (channel >= 0) { + if (message.status() != 0xf && message.channel() != channel) + return; + } + if ((int) queue.size() < queueSize) queue.push(message); }