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 { struct Device {
std::set<Port*> subscribed; std::set<Port*> subscribed;
virtual ~Device() {} virtual ~Device() {}
// Called by Driver::subscribe().
void subscribe(Port* port);
void unsubscribe(Port* port);


virtual std::string getName() { virtual std::string getName() {
return ""; return "";
@@ -113,6 +110,10 @@ struct Device {
/** Sets the block size of the device, re-opening it if needed. */ /** Sets the block size of the device, re-opening it if needed. */
virtual void setBlockSize(int blockSize) {} 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. // Called by this Device class, forwards to subscribed Ports.
void processBuffer(const float* input, int inputStride, float* output, int outputStride, int frames); void processBuffer(const float* input, int inputStride, float* output, int outputStride, int frames);
void onStartStream(); void onStartStream();


+ 20
- 5
src/rtaudio.cpp View File

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


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


RtAudioDevice(RtAudio::Api api, int deviceId) { RtAudioDevice(RtAudio::Api api, int deviceId) {
this->api = api; this->api = api;
@@ -209,18 +212,30 @@ struct RtAudioDevice : audio::Device {
openStream(); 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) { static int rtAudioCallback(void* outputBuffer, void* inputBuffer, unsigned int nFrames, double streamTime, RtAudioStreamStatus status, void* userData) {
// fprintf(stderr, "."); // fprintf(stderr, ".");
// fflush(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"); 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; return 0;
} }
}; };


Loading…
Cancel
Save