Browse Source

Bridge audio subscribing

tags/v0.6.0
Andrew Belt 7 years ago
parent
commit
9d5ce1791e
4 changed files with 59 additions and 34 deletions
  1. +6
    -2
      include/bridge.hpp
  2. +4
    -4
      src/Core/AudioInterface.cpp
  3. +18
    -7
      src/audio.cpp
  4. +31
    -21
      src/bridge.cpp

+ 6
- 2
include/bridge.hpp View File

@@ -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

+ 4
- 4
src/Core/AudioInterface.cpp View File

@@ -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<float>(0.1);
if (audioCv.wait_for(lock, timeout, cond)) {
// Consume audio block
for (int i = 0; i < length; i++) {
Frame<OUTPUTS> 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<float>(0.1);
if (audioIO.engineCv.wait_for(lock, timeout, cond)) {
// Push converted output
int inLen = outputBuffer.size();
int outLen = audioIO.outputBuffer.capacity();


+ 18
- 7
src/audio.cpp View File

@@ -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;
}



+ 31
- 21
src/bridge.cpp View File

@@ -2,8 +2,6 @@
#include "util/common.hpp"
#include "dsp/ringbuffer.hpp"

#include <thread>

#include <unistd.h>
#include <sys/socket.h>
#include <netinet/in.h>
@@ -11,12 +9,12 @@
#include <netinet/tcp.h>
#include <fcntl.h>

#include <thread>


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<uint8_t, RECV_QUEUE_SIZE> 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 <typename T>
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<double>(0.1));
std::this_thread::sleep_for(std::chrono::duration<float>(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

Loading…
Cancel
Save