Browse Source

Add mutex to RtAudioDevice process, subscribe, and unsubscribe methods.

tags/v2.0.0
Andrew Belt 3 years ago
parent
commit
e5ef358c08
2 changed files with 24 additions and 8 deletions
  1. +4
    -3
      include/audio.hpp
  2. +20
    -5
      src/rtaudio.cpp

+ 4
- 3
include/audio.hpp View File

@@ -73,9 +73,6 @@ Methods throw `rack::Exception` if the driver API has an exception.
struct Device {
std::set<Port*> subscribed;
virtual ~Device() {}
// Called by Driver::subscribe().
void subscribe(Port* port);
void unsubscribe(Port* port);

virtual std::string getName() {
return "";
@@ -113,6 +110,10 @@ struct Device {
/** Sets the block size of the device, re-opening it if needed. */
virtual void setBlockSize(int blockSize) {}

// Called by Driver::subscribe().
virtual void subscribe(Port* port);
virtual void unsubscribe(Port* port);

// Called by this Device class, forwards to subscribed Ports.
void processBuffer(const float* input, int inputStride, float* output, int outputStride, int frames);
void onStartStream();


+ 20
- 5
src/rtaudio.cpp View File

@@ -1,5 +1,6 @@
#include <map>
#include <algorithm>
#include <mutex>

#pragma GCC diagnostic push
#ifndef __clang__
@@ -42,6 +43,8 @@ struct RtAudioDevice : audio::Device {
RtAudio::StreamOptions options;
int blockSize = 0;
float sampleRate = 0;
/** Ensures that ports do not subscribe/unsubscribe while processBuffer() is called. */
std::mutex processMutex;

RtAudioDevice(RtAudio::Api api, int deviceId) {
this->api = api;
@@ -209,18 +212,30 @@ struct RtAudioDevice : audio::Device {
openStream();
}

void subscribe(audio::Port* port) override {
std::lock_guard<std::mutex> lock(processMutex);
Device::subscribe(port);
}

void unsubscribe(audio::Port* port) override {
std::lock_guard<std::mutex> lock(processMutex);
Device::unsubscribe(port);
}

static int rtAudioCallback(void* outputBuffer, void* inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void* userData) {
// fprintf(stderr, ".");
// fflush(stderr);

RtAudioDevice* device = (RtAudioDevice*) userData;
assert(device);
RtAudioDevice* that = (RtAudioDevice*) userData;
assert(that);

std::lock_guard<std::mutex> lock(that->processMutex);

system::setThreadName("RtAudio");

int inputStride = device->getNumInputs();
int outputStride = device->getNumOutputs();
device->processBuffer((const float*) inputBuffer, inputStride, (float*) outputBuffer, outputStride, nFrames);
int inputStride = that->getNumInputs();
int outputStride = that->getNumOutputs();
that->processBuffer((const float*) inputBuffer, inputStride, (float*) outputBuffer, outputStride, nFrames);
return 0;
}
};


Loading…
Cancel
Save