From b4be7f4b330df256719fe8e9cc0a984b30b946e9 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Sun, 18 Mar 2018 03:31:27 -0400 Subject: [PATCH] Bridge server progress --- include/bridgeprotocol.hpp | 5 +-- src/bridge.cpp | 67 +++++++++++++++++++++++--------------- 2 files changed, 44 insertions(+), 28 deletions(-) diff --git a/include/bridgeprotocol.hpp b/include/bridgeprotocol.hpp index 5329f164..a728ed89 100644 --- a/include/bridgeprotocol.hpp +++ b/include/bridgeprotocol.hpp @@ -6,6 +6,7 @@ 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; @@ -42,9 +43,9 @@ enum BridgeCommand { /** Sends and receives an audio buffer send - uint32_t length - - float input[n] + - float input[length] recv - - float output[n] + - float output[length] */ AUDIO_PROCESS_COMMAND, /** Resumes the audio buffer, forcing Rack to wait on an audio buffer */ diff --git a/src/bridge.cpp b/src/bridge.cpp index 903194cf..fb621f0c 100644 --- a/src/bridge.cpp +++ b/src/bridge.cpp @@ -28,12 +28,12 @@ struct BridgeClientConnection; static BridgeClientConnection *connections[BRIDGE_NUM_PORTS] = {}; static AudioIO *audioListeners[BRIDGE_NUM_PORTS] = {}; static std::thread serverThread; -static bool serverRunning; +static bool running; struct BridgeClientConnection { int client; - bool running = false; + bool ready = false; int port = -1; int sampleRate = 0; @@ -56,7 +56,7 @@ struct BridgeClientConnection { #endif ssize_t actual = ::send(client, buffer, length, flags); if (actual != length) { - running = false; + ready = false; return false; } return true; @@ -79,7 +79,7 @@ struct BridgeClientConnection { #endif ssize_t actual = ::recv(client, buffer, length, flags); if (actual != length) { - running = false; + ready = false; return false; } return true; @@ -90,20 +90,31 @@ struct BridgeClientConnection { return recv(x, sizeof(*x)); } + void flush() { + int err; + // Turn off Nagle + int flag = 1; + err = setsockopt(client, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof(int)); + // Turn on Nagle + flag = 0; + err = setsockopt(client, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof(int)); + (void) err; + } + void run() { info("Bridge client connected"); // Check hello key - uint32_t hello; - recv(&hello); + uint32_t hello = -1; + recv(&hello); if (hello != BRIDGE_HELLO) { - info("Bridge client protocol mismatch"); + info("Bridge client protocol mismatch %x %x", hello, BRIDGE_HELLO); return; } - // Process commands until no longer running - running = true; - while (running) { + // Process commands until no longer ready + ready = true; + while (ready) { step(); } @@ -113,49 +124,52 @@ struct BridgeClientConnection { /** Accepts a command from the client */ void step() { uint8_t command = NO_COMMAND; - recv(&command); + if (!recv(&command)) { + ready = false; + return; + } switch (command) { default: case NO_COMMAND: { - warn("Bridge client: bad command detected, closing"); - running = false; + warn("Bridge client: bad command %d detected, closing", command); + ready = false; } break; case QUIT_COMMAND: { debug("Bridge client quitting"); - running = true; + ready = true; } break; case PORT_SET_COMMAND: { - uint32_t port = -1; - recv(&port); + uint8_t port = -1; + recv(&port); setPort(port); } break; case MIDI_MESSAGE_SEND_COMMAND: { uint8_t midiBuffer[3]; - recv(&midiBuffer); - debug("MIDI: %02x %02x %02x", midiBuffer[0], midiBuffer[1], midiBuffer[2]); + recv(&midiBuffer, 3); + // debug("MIDI: %02x %02x %02x", midiBuffer[0], midiBuffer[1], midiBuffer[2]); } break; case AUDIO_SAMPLE_RATE_SET_COMMAND: { uint32_t sampleRate = 0; - recv(&sampleRate); + recv(&sampleRate); setSampleRate(sampleRate); } break; case AUDIO_CHANNELS_SET_COMMAND: { uint8_t channels = 0; - recv(&channels); + recv(&channels); // TODO } break; case AUDIO_PROCESS_COMMAND: { uint32_t length = 0; - recv(&length); + recv(&length); if (length == 0) { - running = false; + ready = false; return; } @@ -165,6 +179,7 @@ struct BridgeClientConnection { int frames = length / 2; processStream(input, output, frames); send(&output, length * sizeof(float)); + flush(); } break; case AUDIO_ACTIVATE: { @@ -188,7 +203,7 @@ struct BridgeClientConnection { } // Bind to new port - if (port >= 0 && !connections[port]) { + if ((0 <= port && port < BRIDGE_NUM_PORTS) && !connections[port]) { this->port = port; connections[this->port] = this; refreshAudioActive(); @@ -337,8 +352,8 @@ static void serverRun() { #endif // Accept clients - serverRunning = true; - while (serverRunning) { + running = true; + while (running) { int client = accept(server, NULL, NULL); if (client < 0) { // Wait a bit before attempting to accept another client @@ -360,7 +375,7 @@ void bridgeInit() { } void bridgeDestroy() { - serverRunning = false; + running = false; serverThread.join(); }