From a34b6ef16e25cf1ff25888a8ff54a9ca23fd2136 Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Wed, 20 Nov 2019 07:56:43 -0500 Subject: [PATCH] Remove Bridge audio/MIDI driver. --- include/bridge.hpp | 15 -- include/bridgeprotocol.hpp | 56 ----- src/audio.cpp | 30 +-- src/bridge.cpp | 454 ------------------------------------- src/main.cpp | 3 - 5 files changed, 2 insertions(+), 556 deletions(-) delete mode 100644 include/bridge.hpp delete mode 100644 include/bridgeprotocol.hpp delete mode 100644 src/bridge.cpp diff --git a/include/bridge.hpp b/include/bridge.hpp deleted file mode 100644 index f9784452..00000000 --- a/include/bridge.hpp +++ /dev/null @@ -1,15 +0,0 @@ -#pragma once -#include -#include - - -namespace rack { - - -void bridgeInit(); -void bridgeDestroy(); -void bridgeAudioSubscribe(int channel, audio::Port* port); -void bridgeAudioUnsubscribe(int channel, audio::Port* port); - - -} // namespace rack diff --git a/include/bridgeprotocol.hpp b/include/bridgeprotocol.hpp deleted file mode 100644 index d971493b..00000000 --- a/include/bridgeprotocol.hpp +++ /dev/null @@ -1,56 +0,0 @@ -#pragma once -#include - - -namespace rack { - - -/** Driver ID for AudioDriver and MidiDriver */ -const int BRIDGE_DRIVER = -12512; -const char* const BRIDGE_HOST = "127.0.0.1"; -const int BRIDGE_PORT = 12512; -const int BRIDGE_NUM_PORTS = 16; -/** Number of VST/AU automation parameters */ -const int BRIDGE_NUM_PARAMS = 16; -/** An arbitrary number which prevents connection from other protocols (like WebSockets) and old Bridge versions */ -const uint32_t BRIDGE_HELLO = 0xff00fefd; -const int BRIDGE_INPUTS = 8; -const int BRIDGE_OUTPUTS = 8; - - -/** All commands are called from the client and served by the server -send -- uint8_t cmd -*/ -enum BridgeCommand { - NO_COMMAND = 0, - /** Requests the server to shut down the client */ - QUIT_COMMAND, - /** Sets the port - send - - uint8_t port - */ - PORT_SET_COMMAND, - /** Sends a 3-byte MIDI command - send - - uint8_t msg[3] - */ - MIDI_MESSAGE_COMMAND, - /** Sets the audio sample rate - send - - uint32_t sampleRate - */ - AUDIO_SAMPLE_RATE_SET_COMMAND, - /** Sends and receives an audio buffer - send - - uint32_t frames - - float input[BRIDGE_INPUTS * frames] - recv - - float output[BRIDGE_OUTPUTS * frames] - */ - AUDIO_PROCESS_COMMAND, - NUM_COMMANDS -}; - - -} // namespace rack diff --git a/src/audio.cpp b/src/audio.cpp index b636e492..60f6e958 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -1,7 +1,6 @@ #include #include #include -#include #include @@ -10,7 +9,7 @@ namespace audio { Port::Port() { - setDriverId(RtAudio::UNSPECIFIED); + setDriverId(0); } Port::~Port() { @@ -24,14 +23,12 @@ std::vector Port::getDriverIds() { for (RtAudio::Api api : apis) { drivers.push_back((int) api); } - // Add fake Bridge driver - drivers.push_back(BRIDGE_DRIVER); return drivers; } std::string Port::getDriverName(int driverId) { switch (driverId) { - case RtAudio::UNSPECIFIED: return "Unspecified"; + case 0: return "Default"; case RtAudio::LINUX_ALSA: return "ALSA"; case RtAudio::LINUX_PULSE: return "PulseAudio"; case RtAudio::LINUX_OSS: return "OSS"; @@ -41,7 +38,6 @@ std::string Port::getDriverName(int driverId) { case RtAudio::WINDOWS_ASIO: return "ASIO"; case RtAudio::WINDOWS_DS: return "DirectSound"; case RtAudio::RTAUDIO_DUMMY: return "Dummy Audio"; - case BRIDGE_DRIVER: return "Bridge"; default: return "Unknown"; } } @@ -62,18 +58,12 @@ void Port::setDriverId(int driverId) { rtAudio = new RtAudio((RtAudio::Api) driverId); this->driverId = (int) rtAudio->getCurrentApi(); } - else if (driverId == BRIDGE_DRIVER) { - this->driverId = BRIDGE_DRIVER; - } } int Port::getDeviceCount() { if (rtAudio) { return rtAudio->getDeviceCount(); } - else if (driverId == BRIDGE_DRIVER) { - return BRIDGE_NUM_PORTS; - } return 0; } @@ -109,9 +99,6 @@ int Port::getDeviceChannels(int deviceId) { if (getDeviceInfo(deviceId, &deviceInfo)) return std::max((int) deviceInfo.inputChannels, (int) deviceInfo.outputChannels); } - else if (driverId == BRIDGE_DRIVER) { - return std::max(BRIDGE_OUTPUTS, BRIDGE_INPUTS); - } return 0; } @@ -124,9 +111,6 @@ std::string Port::getDeviceName(int deviceId) { if (getDeviceInfo(deviceId, &deviceInfo)) return deviceInfo.name; } - else if (driverId == BRIDGE_DRIVER) { - return string::f("%d", deviceId + 1); - } return ""; } @@ -148,9 +132,6 @@ std::string Port::getDeviceDetail(int deviceId, int offset) { return deviceDetail; } } - else if (driverId == BRIDGE_DRIVER) { - return string::f("Port %d", deviceId + 1); - } return ""; } @@ -288,10 +269,6 @@ void Port::openStream() { this->sampleRate = rtAudio->getStreamSampleRate(); onOpenStream(); } - else if (driverId == BRIDGE_DRIVER) { - setChannels(BRIDGE_OUTPUTS, BRIDGE_INPUTS); - bridgeAudioSubscribe(deviceId, this); - } } void Port::closeStream() { @@ -318,9 +295,6 @@ void Port::closeStream() { } deviceInfo = RtAudio::DeviceInfo(); } - else if (driverId == BRIDGE_DRIVER) { - bridgeAudioUnsubscribe(deviceId, this); - } onCloseStream(); } diff --git a/src/bridge.cpp b/src/bridge.cpp deleted file mode 100644 index e637e0a9..00000000 --- a/src/bridge.cpp +++ /dev/null @@ -1,454 +0,0 @@ -#include -#include -#include -#include - -#include -#if defined ARCH_WIN - #include -#else - #include - #include - #include - #include - #include -#endif - -#include - - -namespace rack { - - -struct BridgeMidiDriver; - - -struct BridgeClientConnection; -static BridgeClientConnection* connections[BRIDGE_NUM_PORTS] = {}; -static audio::Port* audioListeners[BRIDGE_NUM_PORTS] = {}; -static std::thread serverThread; -static bool serverRunning = false; -static BridgeMidiDriver* driver = NULL; - - -struct BridgeMidiInputDevice : midi::InputDevice { -}; - - -struct BridgeMidiDriver : midi::Driver { - BridgeMidiInputDevice devices[16]; - - std::string getName() override { - return "Bridge"; - } - - std::vector getInputDeviceIds() override { - std::vector deviceIds; - for (int i = 0; i < 16; i++) { - deviceIds.push_back(i); - } - return deviceIds; - } - - std::string getInputDeviceName(int deviceId) override { - if (deviceId < 0) - return ""; - return string::f("Port %d", deviceId + 1); - } - - midi::InputDevice* subscribeInput(int deviceId, midi::Input* input) override { - if (!(0 <= deviceId && deviceId < 16)) - return NULL; - - devices[deviceId].subscribe(input); - return &devices[deviceId]; - } - - void unsubscribeInput(int deviceId, midi::Input* input) override { - if (!(0 <= deviceId && deviceId < 16)) - return; - - devices[deviceId].unsubscribe(input); - } -}; - - -struct BridgeClientConnection { - int client; - bool ready = false; - - int port = -1; - int sampleRate = 0; - - ~BridgeClientConnection() { - setPort(-1); - } - - /** Returns true if successful */ - bool send(const void* buffer, int length) { - if (length <= 0) - return false; - -#if defined ARCH_LIN - int flags = MSG_NOSIGNAL; -#else - int flags = 0; -#endif - ssize_t remaining = 0; - while (remaining < length) { - ssize_t actual = ::send(client, (const char*) buffer, length, flags); - if (actual <= 0) { - ready = false; - return false; - } - remaining += actual; - } - return true; - } - - template - bool send(T x) { - return send(&x, sizeof(x)); - } - - /** Returns true if successful */ - bool recv(void* buffer, int length) { - if (length <= 0) - return false; - -#if defined ARCH_LIN - int flags = MSG_NOSIGNAL; -#else - int flags = 0; -#endif - ssize_t remaining = 0; - while (remaining < length) { - ssize_t actual = ::recv(client, (char*) buffer + remaining, length - remaining, flags); - if (actual <= 0) { - ready = false; - return false; - } - remaining += actual; - } - return true; - } - - template - bool recv(T* x) { - return recv(x, sizeof(*x)); - } - - void flush() { - // Turn off Nagle - int flag = 1; - setsockopt(client, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof(int)); - // Turn on Nagle - flag = 0; - setsockopt(client, IPPROTO_TCP, TCP_NODELAY, (char*) &flag, sizeof(int)); - } - - void run() { - INFO("Bridge client connected"); - - // Check hello key - uint32_t hello = -1; - recv(&hello); - if (hello != BRIDGE_HELLO) { - INFO("Bridge client protocol mismatch %x %x", hello, BRIDGE_HELLO); - return; - } - - // Process commands until no longer ready - ready = true; - while (ready) { - step(); - } - - INFO("Bridge client closed"); - } - - /** Accepts a command from the client */ - void step() { - uint8_t command; - if (!recv(&command)) { - return; - } - - switch (command) { - default: - case NO_COMMAND: { - WARN("Bridge client: bad command %d detected, closing", command); - ready = false; - } break; - - case QUIT_COMMAND: { - ready = false; - } break; - - case PORT_SET_COMMAND: { - uint8_t port = -1; - recv(&port); - setPort(port); - } break; - - case MIDI_MESSAGE_COMMAND: { - midi::Message message; - if (!recv(&message.bytes, 3)) { - return; - } - processMidi(message); - } break; - - case AUDIO_SAMPLE_RATE_SET_COMMAND: { - uint32_t sampleRate = 0; - recv(&sampleRate); - setSampleRate(sampleRate); - } break; - - case AUDIO_PROCESS_COMMAND: { - uint32_t frames = 0; - recv(&frames); - if (frames == 0 || frames > (1 << 16)) { - ready = false; - return; - } - - float input[BRIDGE_INPUTS * frames]; - if (!recv(&input, BRIDGE_INPUTS * frames * sizeof(float))) { - DEBUG("Failed to receive"); - return; - } - - float output[BRIDGE_OUTPUTS * frames]; - std::memset(&output, 0, sizeof(output)); - processStream(input, output, frames); - if (!send(&output, BRIDGE_OUTPUTS * frames * sizeof(float))) { - DEBUG("Failed to send"); - return; - } - // flush(); - } break; - } - } - - void setPort(int port) { - // Unbind from existing port - if (0 <= this->port && connections[this->port] == this) { - connections[this->port] = NULL; - } - - // Bind to new port - if ((0 <= port && port < BRIDGE_NUM_PORTS) && !connections[port]) { - this->port = port; - connections[this->port] = this; - refreshAudio(); - } - else { - this->port = -1; - } - } - - void processMidi(midi::Message message) { - if (!(0 <= port && port < BRIDGE_NUM_PORTS)) - return; - if (!driver) - return; - driver->devices[port].onMessage(message); - } - - void setSampleRate(int sampleRate) { - this->sampleRate = sampleRate; - refreshAudio(); - } - - void processStream(const float* input, float* output, int frames) { - if (!(0 <= port && port < BRIDGE_NUM_PORTS)) - return; - if (!audioListeners[port]) - return; - audioListeners[port]->setBlockSize(frames); - audioListeners[port]->processStream(input, output, frames); - } - - void refreshAudio() { - if (!(0 <= port && port < BRIDGE_NUM_PORTS)) - return; - if (connections[port] != this) - return; - if (!audioListeners[port]) - return; - audioListeners[port]->setSampleRate(sampleRate); - } -}; - - -static void clientRun(int client) { - DEFER({ -#if defined ARCH_WIN - if (shutdown(client, SD_SEND)) { - WARN("Bridge client shutdown() failed"); - } - if (closesocket(client)) { - WARN("Bridge client closesocket() failed"); - } -#else - if (close(client)) { - WARN("Bridge client close() failed"); - } -#endif - }); - -#if defined ARCH_MAC - // Avoid SIGPIPE - int flag = 1; - if (setsockopt(client, SOL_SOCKET, SO_NOSIGPIPE, &flag, sizeof(int))) { - WARN("Bridge client setsockopt() failed"); - return; - } -#endif - - // Disable non-blocking -#if defined ARCH_WIN - unsigned long blockingMode = 0; - if (ioctlsocket(client, FIONBIO, &blockingMode)) { - WARN("Bridge client ioctlsocket() failed"); - return; - } -#else - if (fcntl(client, F_SETFL, fcntl(client, F_GETFL, 0) & ~O_NONBLOCK)) { - WARN("Bridge client fcntl() failed"); - return; - } -#endif - - BridgeClientConnection connection; - connection.client = client; - connection.run(); -} - - -static void serverConnect() { - // Initialize sockets -#if defined ARCH_WIN - WSADATA wsaData; - if (WSAStartup(MAKEWORD(2, 2), &wsaData)) { - WARN("Bridge server WSAStartup() failed"); - return; - } - DEFER({ - WSACleanup(); - }); -#endif - - // Get address - struct sockaddr_in addr; - std::memset(&addr, 0, sizeof(addr)); - addr.sin_family = AF_INET; - addr.sin_port = htons(BRIDGE_PORT); -#if defined ARCH_WIN - addr.sin_addr.s_addr = inet_addr(BRIDGE_HOST); -#else - inet_pton(AF_INET, BRIDGE_HOST, &addr.sin_addr); -#endif - - // Open socket - int server = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); - if (server < 0) { - WARN("Bridge server socket() failed"); - return; - } - DEFER({ - if (close(server)) { - WARN("Bridge server close() failed"); - return; - } - INFO("Bridge server closed"); - }); - -#if defined ARCH_MAC || defined ARCH_LIN - int reuseAddrFlag = 1; - setsockopt(server, SOL_SOCKET, SO_REUSEADDR, &reuseAddrFlag, sizeof(reuseAddrFlag)); -#endif - - // Bind socket to address - if (bind(server, (struct sockaddr*) &addr, sizeof(addr))) { - WARN("Bridge server bind() failed"); - return; - } - - // Listen for clients - if (listen(server, 20)) { - WARN("Bridge server listen() failed"); - return; - } - INFO("Bridge server started"); - - // Enable non-blocking -#if defined ARCH_WIN - unsigned long blockingMode = 1; - if (ioctlsocket(server, FIONBIO, &blockingMode)) { - WARN("Bridge server ioctlsocket() failed"); - return; - } -#else - int flags = fcntl(server, F_GETFL, 0); - fcntl(server, F_SETFL, flags | O_NONBLOCK); -#endif - - // Accept clients - while (serverRunning) { - int client = accept(server, NULL, NULL); - if (client < 0) { - // Wait a bit before attempting to accept another client - std::this_thread::sleep_for(std::chrono::duration(0.1)); - continue; - } - - // Launch client thread - std::thread clientThread(clientRun, client); - clientThread.detach(); - } -} - -static void serverRun() { - while (serverRunning) { - std::this_thread::sleep_for(std::chrono::duration(0.1)); - serverConnect(); - } -} - - -void bridgeInit() { - serverRunning = true; - serverThread = std::thread(serverRun); - - driver = new BridgeMidiDriver; - midi::addDriver(BRIDGE_DRIVER, driver); -} - -void bridgeDestroy() { - serverRunning = false; - serverThread.join(); -} - -void bridgeAudioSubscribe(int port, audio::Port* audio) { - if (!(0 <= port && port < BRIDGE_NUM_PORTS)) - return; - // Check if an Audio is already subscribed on the port - if (audioListeners[port]) - return; - audioListeners[port] = audio; - if (connections[port]) - connections[port]->refreshAudio(); -} - -void bridgeAudioUnsubscribe(int port, audio::Port* audio) { - if (!(0 <= port && port < BRIDGE_NUM_PORTS)) - return; - if (audioListeners[port] != audio) - return; - audioListeners[port] = NULL; -} - - -} // namespace rack diff --git a/src/main.cpp b/src/main.cpp index 39575764..6984bebe 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -5,7 +5,6 @@ #include #include #include -#include #include #include #include @@ -158,7 +157,6 @@ int main(int argc, char* argv[]) { network::init(); midi::init(); rtmidiInit(); - bridgeInit(); keyboard::init(); gamepad::init(); plugin::init(); @@ -216,7 +214,6 @@ int main(int argc, char* argv[]) { ui::destroy(); } plugin::destroy(); - bridgeDestroy(); midi::destroy(); INFO("Destroying logger"); logger::destroy();