Browse Source

Bridge server progress

tags/v0.6.0
Andrew Belt 6 years ago
parent
commit
04ba73454c
4 changed files with 71 additions and 50 deletions
  1. +2
    -2
      include/audio.hpp
  2. +9
    -2
      src/app/AudioWidget.cpp
  3. +31
    -27
      src/audio.cpp
  4. +29
    -19
      src/bridge.cpp

+ 2
- 2
include/audio.hpp View File

@@ -40,7 +40,9 @@ struct AudioIO {
std::string getDeviceDetail(int device, int offset);
void setDevice(int device, int offset);

std::vector<int> getSampleRates();
void setSampleRate(int sampleRate);
std::vector<int> getBlockSizes();
void setBlockSize(int blockSize);

void setChannels(int numOutputs, int numInputs);
@@ -49,8 +51,6 @@ struct AudioIO {
void openStream();
void closeStream();

std::vector<int> getSampleRates();

virtual void processStream(const float *input, float *output, int frames) {}
virtual void onCloseStream() {}
virtual void onOpenStream() {}


+ 9
- 2
src/app/AudioWidget.cpp View File

@@ -98,7 +98,11 @@ struct AudioSampleRateChoice : LedDisplayChoice {
void onAction(EventAction &e) override {
Menu *menu = gScene->createMenu();
menu->addChild(construct<MenuLabel>(&MenuLabel::text, "Sample rate"));
for (int sampleRate : audioWidget->audioIO->getSampleRates()) {
std::vector<int> sampleRates = audioWidget->audioIO->getSampleRates();
if (sampleRates.empty()) {
menu->addChild(construct<MenuLabel>(&MenuLabel::text, "(None available)"));
}
for (int sampleRate : sampleRates) {
AudioSampleRateItem *item = new AudioSampleRateItem();
item->audioIO = audioWidget->audioIO;
item->sampleRate = sampleRate;
@@ -126,7 +130,10 @@ struct AudioBlockSizeChoice : LedDisplayChoice {
void onAction(EventAction &e) override {
Menu *menu = gScene->createMenu();
menu->addChild(construct<MenuLabel>(&MenuLabel::text, "Block size"));
std::vector<int> blockSizes = {64, 128, 256, 512, 1024, 2048, 4096};
std::vector<int> blockSizes = audioWidget->audioIO->getBlockSizes();
if (blockSizes.empty()) {
menu->addChild(construct<MenuLabel>(&MenuLabel::text, "(None available)"));
}
for (int blockSize : blockSizes) {
AudioBlockSizeItem *item = new AudioBlockSizeItem();
item->audioIO = audioWidget->audioIO;


+ 31
- 27
src/audio.cpp View File

@@ -70,7 +70,7 @@ int AudioIO::getDeviceCount() {
if (rtAudio) {
return rtAudio->getDeviceCount();
}
if (driver == BRIDGE_DRIVER) {
else if (driver == BRIDGE_DRIVER) {
return BRIDGE_NUM_PORTS;
}
return 0;
@@ -108,7 +108,7 @@ int AudioIO::getDeviceChannels(int device) {
if (getDeviceInfo(device, &deviceInfo))
return max((int) deviceInfo.inputChannels, (int) deviceInfo.outputChannels);
}
if (driver == BRIDGE_DRIVER) {
else if (driver == BRIDGE_DRIVER) {
return 2;
}
return 0;
@@ -123,7 +123,7 @@ std::string AudioIO::getDeviceName(int device) {
if (getDeviceInfo(device, &deviceInfo))
return deviceInfo.name;
}
if (driver == BRIDGE_DRIVER) {
else if (driver == BRIDGE_DRIVER) {
return stringf("%d", device + 1);
}
return "";
@@ -147,7 +147,7 @@ std::string AudioIO::getDeviceDetail(int device, int offset) {
return deviceDetail;
}
}
if (driver == BRIDGE_DRIVER) {
else if (driver == BRIDGE_DRIVER) {
return stringf("Port %d", device + 1);
}
return "";
@@ -160,13 +160,38 @@ void AudioIO::setDevice(int device, int offset) {
openStream();
}

std::vector<int> AudioIO::getSampleRates() {
if (rtAudio) {
try {
RtAudio::DeviceInfo deviceInfo = rtAudio->getDeviceInfo(device);
std::vector<int> sampleRates(deviceInfo.sampleRates.begin(), deviceInfo.sampleRates.end());
return sampleRates;
}
catch (RtAudioError &e) {
warn("Failed to query RtAudio device: %s", e.what());
}
}
return {};
}

void AudioIO::setSampleRate(int sampleRate) {
if (sampleRate == this->sampleRate)
return;
closeStream();
this->sampleRate = sampleRate;
openStream();
}

std::vector<int> AudioIO::getBlockSizes() {
if (rtAudio) {
return {64, 128, 256, 512, 1024, 2048, 4096};
}
return {};
}

void AudioIO::setBlockSize(int blockSize) {
if (blockSize == this->blockSize)
return;
closeStream();
this->blockSize = blockSize;
openStream();
@@ -256,11 +281,8 @@ void AudioIO::openStream() {
this->sampleRate = rtAudio->getStreamSampleRate();
onOpenStream();
}
if (driver == BRIDGE_DRIVER) {
else if (driver == BRIDGE_DRIVER) {
setChannels(0, 0);
// TEMP
sampleRate = 44100;
blockSize = 256;
bridgeAudioSubscribe(device, this);
}
}
@@ -289,31 +311,13 @@ void AudioIO::closeStream() {
}
deviceInfo = RtAudio::DeviceInfo();
}
if (driver == BRIDGE_DRIVER) {
else if (driver == BRIDGE_DRIVER) {
bridgeAudioUnsubscribe(device, this);
}

onCloseStream();
}

std::vector<int> AudioIO::getSampleRates() {
if (rtAudio) {
try {
RtAudio::DeviceInfo deviceInfo = rtAudio->getDeviceInfo(device);
std::vector<int> sampleRates(deviceInfo.sampleRates.begin(), deviceInfo.sampleRates.end());
return sampleRates;
}
catch (RtAudioError &e) {
warn("Failed to query RtAudio device: %s", e.what());
}
}
if (driver == BRIDGE_DRIVER) {
return {44100, 48000, 88200, 96000, 176400, 192000};
}

return {};
}

json_t *AudioIO::toJson() {
json_t *rootJ = json_object();
json_object_set_new(rootJ, "driver", json_integer(driver));


+ 29
- 19
src/bridge.cpp View File

@@ -21,14 +21,11 @@
namespace rack {


static const int RECV_BUFFER_SIZE = (1<<13);
static const int RECV_QUEUE_SIZE = (1<<17);

struct BridgeClientConnection;
static BridgeClientConnection *connections[BRIDGE_NUM_PORTS] = {};
static AudioIO *audioListeners[BRIDGE_NUM_PORTS] = {};
static std::thread serverThread;
static bool running;
static bool serverRunning = false;


struct BridgeClientConnection {
@@ -138,7 +135,7 @@ struct BridgeClientConnection {

case QUIT_COMMAND: {
debug("Bridge client quitting");
ready = true;
ready = false;
} break;

case PORT_SET_COMMAND: {
@@ -150,7 +147,7 @@ struct BridgeClientConnection {
case MIDI_MESSAGE_SEND_COMMAND: {
uint8_t midiBuffer[3];
recv(&midiBuffer, 3);
// debug("MIDI: %02x %02x %02x", midiBuffer[0], midiBuffer[1], midiBuffer[2]);
debug("MIDI: %02x %02x %02x", midiBuffer[0], midiBuffer[1], midiBuffer[2]);
} break;

case AUDIO_SAMPLE_RATE_SET_COMMAND: {
@@ -174,9 +171,13 @@ struct BridgeClientConnection {
}

float input[length];
recv(&input, length * sizeof(float));
if (!recv(&input, length * sizeof(float))) {
ready = false;
return;
}
float output[length];
int frames = length / 2;
memset(&output, 0, sizeof(output));
processStream(input, output, frames);
send(&output, length * sizeof(float));
flush();
@@ -184,12 +185,12 @@ struct BridgeClientConnection {

case AUDIO_ACTIVATE: {
audioActive = true;
refreshAudioActive();
refreshAudio();
} break;

case AUDIO_DEACTIVATE: {
audioActive = false;
refreshAudioActive();
refreshAudio();
} break;
}
}
@@ -206,7 +207,7 @@ struct BridgeClientConnection {
if ((0 <= port && port < BRIDGE_NUM_PORTS) && !connections[port]) {
this->port = port;
connections[this->port] = this;
refreshAudioActive();
refreshAudio();
}
else {
this->port = -1;
@@ -214,8 +215,8 @@ struct BridgeClientConnection {
}

void setSampleRate(int sampleRate) {
// TODO
this->sampleRate = sampleRate;
refreshAudio();
}

void processStream(const float *input, float *output, int frames) {
@@ -223,19 +224,22 @@ struct BridgeClientConnection {
return;
if (!audioListeners[port])
return;
audioListeners[port]->setBlockSize(frames);
audioListeners[port]->processStream(input, output, frames);
debug("%d frames", frames);
}

void refreshAudioActive() {
void refreshAudio() {
if (!(0 <= port && port < BRIDGE_NUM_PORTS))
return;
if (connections[port] != this)
return;
if (!audioListeners[port])
return;
if (audioActive)
audioListeners[port]->setChannels(2, 2);
else
audioListeners[port]->setChannels(0, 0);
audioListeners[port]->setSampleRate(sampleRate);
}
};

@@ -267,13 +271,13 @@ static void clientRun(int client) {
}


static void serverRun() {
static void serverConnect() {
int err;

// Initialize sockets
#ifdef ARCH_WIN
WSADATA wsaData;
err = WSAStartup(MAKEWORD(2,2), &wsaData);
err = WSAStartup(MAKEWORD(2, 2), &wsaData);
defer({
WSACleanup();
});
@@ -352,8 +356,7 @@ static void serverRun() {
#endif

// Accept clients
running = true;
while (running) {
while (serverRunning) {
int client = accept(server, NULL, NULL);
if (client < 0) {
// Wait a bit before attempting to accept another client
@@ -369,13 +372,20 @@ static void serverRun() {
info("Bridge server closed");
}

static void serverRun() {
while (serverRunning) {
std::this_thread::sleep_for(std::chrono::duration<double>(0.1));
serverConnect();
}
}

void bridgeInit() {
serverRunning = true;
serverThread = std::thread(serverRun);
}

void bridgeDestroy() {
running = false;
serverRunning = false;
serverThread.join();
}

@@ -387,7 +397,7 @@ void bridgeAudioSubscribe(int port, AudioIO *audio) {
return;
audioListeners[port] = audio;
if (connections[port])
connections[port]->refreshAudioActive();
connections[port]->refreshAudio();
}

void bridgeAudioUnsubscribe(int port, AudioIO *audio) {


Loading…
Cancel
Save