From 9d5ce1791e1010fd3c04fa267b99596a2f18d75d Mon Sep 17 00:00:00 2001 From: Andrew Belt Date: Thu, 8 Mar 2018 17:44:50 -0500 Subject: [PATCH] Bridge audio subscribing --- include/bridge.hpp | 8 ++++-- src/Core/AudioInterface.cpp | 8 +++--- src/audio.cpp | 25 +++++++++++++----- src/bridge.cpp | 52 ++++++++++++++++++++++--------------- 4 files changed, 59 insertions(+), 34 deletions(-) diff --git a/include/bridge.hpp b/include/bridge.hpp index aeea8dc3..d1c9e45c 100644 --- a/include/bridge.hpp +++ b/include/bridge.hpp @@ -1,14 +1,18 @@ #pragma once +#include "audio.hpp" -#define BRIDGE_CHANNELS 16 +namespace rack { -namespace rack { +static const int BRIDGE_CHANNELS = 16; void bridgeInit(); void bridgeDestroy(); +void bridgeAudioSubscribe(int channel, AudioIO *audio); +void bridgeAudioUnsubscribe(int channel, AudioIO *audio); +bool bridgeAudioIsSubscribed(int channel, AudioIO *audio); } // namespace rack diff --git a/src/Core/AudioInterface.cpp b/src/Core/AudioInterface.cpp index 2359a428..7312fb84 100644 --- a/src/Core/AudioInterface.cpp +++ b/src/Core/AudioInterface.cpp @@ -18,8 +18,6 @@ #define OUTPUTS 8 #define INPUTS 8 -static const auto audioTimeout = std::chrono::milliseconds(100); - using namespace rack; @@ -60,7 +58,8 @@ struct AudioInterfaceIO : AudioIO { auto cond = [&] { return (outputBuffer.size() >= (size_t) length); }; - if (audioCv.wait_for(lock, audioTimeout, cond)) { + auto timeout = std::chrono::duration(0.1); + if (audioCv.wait_for(lock, timeout, cond)) { // Consume audio block for (int i = 0; i < length; i++) { Frame f = outputBuffer.shift(); @@ -189,7 +188,8 @@ void AudioInterface::step() { auto cond = [&] { return (audioIO.outputBuffer.size() < (size_t) audioIO.blockSize); }; - if (audioIO.engineCv.wait_for(lock, audioTimeout, cond)) { + auto timeout = std::chrono::duration(0.1); + if (audioIO.engineCv.wait_for(lock, timeout, cond)) { // Push converted output int inLen = outputBuffer.size(); int outLen = audioIO.outputBuffer.capacity(); diff --git a/src/audio.cpp b/src/audio.cpp index a2eb7b67..4d8aeebb 100644 --- a/src/audio.cpp +++ b/src/audio.cpp @@ -3,7 +3,7 @@ #include "bridge.hpp" -#define BRIDGE_DRIVER -1 +#define BRIDGE_DRIVER -5000 namespace rack { @@ -60,7 +60,6 @@ void AudioIO::setDriver(int driver) { this->driver = (int) rtAudio->getCurrentApi(); } else if (driver == BRIDGE_DRIVER) { - // TODO Connect to Bridge this->driver = BRIDGE_DRIVER; } } @@ -253,13 +252,19 @@ void AudioIO::openStream() { onOpenStream(); } if (driver == BRIDGE_DRIVER) { - if (device < BRIDGE_CHANNELS) { - // TODO - } + numOutputs = 2; + numInputs = 2; + // TEMP + sampleRate = 44100; + blockSize = 256; + bridgeAudioSubscribe(device, this); } } void AudioIO::closeStream() { + numOutputs = 0; + numInputs = 0; + if (rtAudio) { if (rtAudio->isStreamRunning()) { info("Stopping RtAudio stream %d", device); @@ -281,14 +286,20 @@ void AudioIO::closeStream() { } deviceInfo = RtAudio::DeviceInfo(); } + if (driver == BRIDGE_DRIVER) { + bridgeAudioUnsubscribe(device, this); + } onCloseStream(); } bool AudioIO::isActive() { - if (rtAudio) + if (rtAudio) { return rtAudio->isStreamRunning(); - // TODO Bridge + } + if (driver == BRIDGE_DRIVER) { + bridgeAudioIsSubscribed(device, this); + } return false; } diff --git a/src/bridge.cpp b/src/bridge.cpp index 3e4ab263..78f6c712 100644 --- a/src/bridge.cpp +++ b/src/bridge.cpp @@ -2,8 +2,6 @@ #include "util/common.hpp" #include "dsp/ringbuffer.hpp" -#include - #include #include #include @@ -11,12 +9,12 @@ #include #include +#include namespace rack { - enum BridgeCommand { NO_COMMAND = 0, START_COMMAND, @@ -30,14 +28,14 @@ enum BridgeCommand { }; +static const int RECV_BUFFER_SIZE = (1<<13); +static const int RECV_QUEUE_SIZE = (1<<17); + +static AudioIO *audioListeners[BRIDGE_CHANNELS]; static std::thread serverThread; static bool serverQuit; -#define RECV_BUFFER_SIZE (1<<13) -#define RECV_QUEUE_SIZE (1<<17) - - struct BridgeClientConnection { RingBuffer recvQueue; BridgeCommand currentCommand = START_COMMAND; @@ -46,19 +44,10 @@ struct BridgeClientConnection { int sampleRate = -1; int audioChannels = 0; int audioBufferLength = -1; - // TEMP - // FILE *audioOutputFile; - - BridgeClientConnection() { - // audioOutputFile = fopen("out.f32", "w"); - // assert(audioOutputFile); - } - - ~BridgeClientConnection() { - // fclose(audioOutputFile); - } - /** Does not check if the queue has enough data. You must do that yourself. */ + /** Does not check if the queue has enough data. + You must do that yourself before calling this method. + */ template T shift() { T x; @@ -173,7 +162,7 @@ struct BridgeClientConnection { } void recv(uint8_t *buffer, int length) { - // Make sure we can fill the buffer before filling it + // Make sure we can fill the buffer if (recvQueue.capacity() < (size_t) length) { // If we can't accept it, future messages will be incomplete closeRequested = true; @@ -272,7 +261,7 @@ static void serverRun() { 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)); + std::this_thread::sleep_for(std::chrono::duration(0.1)); continue; } @@ -298,6 +287,27 @@ void bridgeDestroy() { serverThread.join(); } +void bridgeAudioSubscribe(int channel, AudioIO *audio) { + if (!(0 <= channel && channel < BRIDGE_CHANNELS)) + return; + if (audioListeners[channel]) + return; + audioListeners[channel] = audio; +} + +void bridgeAudioUnsubscribe(int channel, AudioIO *audio) { + if (!(0 <= channel && channel < BRIDGE_CHANNELS)) + return; + if (audioListeners[channel] != audio) + return; + audioListeners[channel] = NULL; +} + +bool bridgeAudioIsSubscribed(int channel, AudioIO *audio) { + if (!(0 <= channel && channel < BRIDGE_CHANNELS)) + return false; + return (audioListeners[channel] == audio); +} } // namespace rack