Browse Source

Massive refactor to MIDI API, re-enable Bridge

tags/v0.6.1
Andrew Belt 6 years ago
parent
commit
ba275e31e5
11 changed files with 271 additions and 224 deletions
  1. +16
    -2
      include/bridge.hpp
  2. +8
    -6
      include/gamepad.hpp
  3. +7
    -5
      include/keyboard.hpp
  4. +25
    -33
      include/midi.hpp
  5. +18
    -14
      include/rtmidi.hpp
  6. +35
    -21
      src/bridge.cpp
  7. +16
    -15
      src/gamepad.cpp
  8. +19
    -16
      src/keyboard.cpp
  9. +2
    -0
      src/main.cpp
  10. +56
    -73
      src/midi.cpp
  11. +69
    -39
      src/rtmidi.cpp

+ 16
- 2
include/bridge.hpp View File

@@ -7,12 +7,26 @@
namespace rack {


struct BridgeMidiInputDevice : MidiInputDevice {
};


struct BridgeMidiDriver : MidiDriver {
BridgeMidiInputDevice devices[16];
std::string getName() override {return "Bridge";}

std::vector<int> getInputDeviceIds() override;
std::string getInputDeviceName(int deviceId) override;
MidiInputDevice *subscribeInputDevice(int deviceId, MidiInput *midiInput) override;
void unsubscribeInputDevice(int deviceId, MidiInput *midiInput) override;
};


void bridgeInit();
void bridgeDestroy();
void bridgeMidiSubscribe(int channel, MidiInput *midi);
void bridgeMidiUnsubscribe(int channel, MidiInput *midi);
void bridgeAudioSubscribe(int channel, AudioIO *audio);
void bridgeAudioUnsubscribe(int channel, AudioIO *audio);
BridgeMidiDriver *bridgeGetMidiDriver();


} // namespace rack

+ 8
- 6
include/gamepad.hpp View File

@@ -18,18 +18,20 @@ struct GamepadInputDevice : MidiInputDevice {
};


struct GamepadInputDriver : MidiInputDriver {
struct GamepadDriver : MidiDriver {
GamepadInputDevice devices[16];

GamepadInputDriver();
std::vector<int> getDeviceIds() override;
std::string getDeviceName(int deviceId) override;
MidiInputDevice *getDevice(int deviceId) override;
GamepadDriver();
std::string getName() override {return "Gamepad";}
std::vector<int> getInputDeviceIds() override;
std::string getInputDeviceName(int deviceId) override;
MidiInputDevice *subscribeInputDevice(int deviceId, MidiInput *midiInput) override;
void unsubscribeInputDevice(int deviceId, MidiInput *midiInput) override;
};


void gamepadStep();
MidiInputDriver *gamepadGetInputDriver();
GamepadDriver *gamepadGetDriver();


} // namespace rack

+ 7
- 5
include/keyboard.hpp View File

@@ -16,18 +16,20 @@ struct KeyboardInputDevice : MidiInputDevice {
};


struct KeyboardInputDriver : MidiInputDriver {
struct KeyboardDriver : MidiDriver {
KeyboardInputDevice device;
std::string getName() override {return "Computer keyboard";}

std::vector<int> getDeviceIds() override;
std::string getDeviceName(int deviceId) override;
MidiInputDevice *getDevice(int deviceId) override;
std::vector<int> getInputDeviceIds() override;
std::string getInputDeviceName(int deviceId) override;
MidiInputDevice *subscribeInputDevice(int deviceId, MidiInput *midiInput) override;
void unsubscribeInputDevice(int deviceId, MidiInput *midiInput) override;
};


void keyboardPress(int key);
void keyboardRelease(int key);
KeyboardInputDriver *keyboardGetInputDriver();
KeyboardDriver *keyboardGetDriver();


} // namespace rack

+ 25
- 33
include/midi.hpp View File

@@ -30,42 +30,43 @@ struct MidiMessage {
};

////////////////////
// MidiIODevice
// MidiDevice
////////////////////

struct MidiIODevice {
virtual ~MidiIODevice() {}
struct MidiDevice {
virtual ~MidiDevice() {}
};

struct MidiInput;

struct MidiInputDevice : MidiIODevice {
struct MidiInputDevice : MidiDevice {
std::set<MidiInput*> subscribed;
void subscribe(MidiInput *midiInput);
void unsubscribe(MidiInput *midiInput);
void onMessage(MidiMessage message);
};

struct MidiOutputDevice : MidiIODevice {
struct MidiOutputDevice : MidiDevice {
// TODO
};

////////////////////
// MidiIODriver
// MidiDriver
////////////////////

struct MidiIODriver {
virtual ~MidiIODriver() {}
virtual std::vector<int> getDeviceIds() = 0;
virtual std::string getDeviceName(int deviceId) = 0;
};
struct MidiDriver {
virtual ~MidiDriver() {}
virtual std::string getName() {return "";}

struct MidiInputDriver : MidiIODriver {
virtual MidiInputDevice *getDevice(int deviceId) = 0;
};
virtual std::vector<int> getInputDeviceIds() {return {};}
virtual std::string getInputDeviceName(int deviceId) {return "";}
virtual MidiInputDevice *subscribeInputDevice(int deviceId, MidiInput *midiInput) {return NULL;}
virtual void unsubscribeInputDevice(int deviceId, MidiInput *midiInput) {}

struct MidiOutputDriver : MidiIODriver {
virtual MidiOutputDevice *getDevice(int deviceId) = 0;
// virtual std::vector<int> getOutputDeviceIds() = 0;
// virtual std::string getOutputDeviceName(int deviceId) = 0;
// virtual MidiOutputDevice *subscribeOutputDevice(int deviceId, MidiOutput *midiOutput) = 0;
// virtual void unsubscribeOutputDevice(int deviceId, MidiOutput *midiOutput) = 0;
};

////////////////////
@@ -81,12 +82,14 @@ struct MidiIO {
Zero indexed.
*/
int channel = -1;
/** Not owned */
MidiDriver *driver = NULL;

virtual ~MidiIO() {}
virtual ~MidiIO();

std::vector<int> getDriverIds();
std::string getDriverName(int driverId);
virtual void setDriverId(int driverId) = 0;
void setDriverId(int driverId);

virtual std::vector<int> getDeviceIds() = 0;
virtual std::string getDeviceName(int deviceId) = 0;
@@ -99,26 +102,17 @@ struct MidiIO {


struct MidiInput : MidiIO {
/** Not owned */
MidiInputDriver *driver = NULL;
/** Not owned, must unsubscribe when destructed */
MidiInputDevice *device = NULL;

MidiInput();
~MidiInput();

void setDriverId(int driverId) override;
std::vector<int> getDeviceIds() override;
std::string getDeviceName(int deviceId) override;
void setDeviceId(int deviceId) override;

virtual void onMessage(MidiMessage message) {}
};


struct MidiInputQueue : MidiInput {
int queueSize = 8192;
// TODO Switch to RingBuffer
int queueMaxSize = 8192;
std::queue<MidiMessage> queue;
void onMessage(MidiMessage message) override;
/** If a MidiMessage is available, writes `message` and return true */
@@ -127,15 +121,13 @@ struct MidiInputQueue : MidiInput {


struct MidiOutput : MidiIO {
/** Not owned */
MidiOutputDriver *driver = NULL;
/** Not owned, must unsubscribe when destructed */
MidiOutputDevice *device = NULL;
MidiOutput();
~MidiOutput();
void setDriverId(int driverId) override;
void setDeviceId(int deviceId) override;
};


void midiInit();


} // namespace rack

+ 18
- 14
include/rtmidi.hpp View File

@@ -2,6 +2,7 @@

#include "util/common.hpp"
#include "midi.hpp"
#include <map>

#pragma GCC diagnostic push
#ifndef __clang__
@@ -14,30 +15,33 @@
namespace rack {


struct RtMidiInputDriver : MidiInputDriver {
/** Just for querying MIDI driver information */
struct RtMidiInputDevice : MidiInputDevice {
RtMidiIn *rtMidiIn;

RtMidiInputDriver(int driverId);
~RtMidiInputDriver();
std::vector<int> getDeviceIds() override;
std::string getDeviceName(int deviceId) override;
MidiInputDevice *getDevice(int deviceId) override;
RtMidiInputDevice(int driverId, int deviceId);
~RtMidiInputDevice();
};


struct RtMidiInputDevice : MidiInputDevice {
struct RtMidiDriver : MidiDriver {
int driverId;
/** Just for querying MIDI driver information */
RtMidiIn *rtMidiIn;
/** Cached */
std::string deviceName;

RtMidiInputDevice(int driverId, int deviceId);
~RtMidiInputDevice();
RtMidiOut *rtMidiOut;
std::map<int, RtMidiInputDevice*> devices;

RtMidiDriver(int driverId);
~RtMidiDriver();
std::string getName() override;
std::vector<int> getInputDeviceIds() override;
std::string getInputDeviceName(int deviceId) override;
MidiInputDevice *subscribeInputDevice(int deviceId, MidiInput *midiInput) override;
void unsubscribeInputDevice(int deviceId, MidiInput *midiInput) override;
};


std::vector<int> rtmidiGetDrivers();
MidiInputDriver *rtmidiGetInputDriver(int driverId);
RtMidiDriver *rtmidiCreateDriver(int driverId);


} // namespace rack

+ 35
- 21
src/bridge.cpp View File

@@ -23,9 +23,9 @@ namespace rack {
struct BridgeClientConnection;
static BridgeClientConnection *connections[BRIDGE_NUM_PORTS] = {};
static AudioIO *audioListeners[BRIDGE_NUM_PORTS] = {};
static MidiInput *midiListeners[BRIDGE_NUM_PORTS] = {};
static std::thread serverThread;
static bool serverRunning = false;
static BridgeMidiDriver driver;


struct BridgeClientConnection {
@@ -206,9 +206,7 @@ struct BridgeClientConnection {
void processMidi(MidiMessage message) {
if (!(0 <= port && port < BRIDGE_NUM_PORTS))
return;
if (!midiListeners[port])
return;
midiListeners[port]->onMessage(message);
driver.devices[port].onMessage(message);
}

void setSampleRate(int sampleRate) {
@@ -372,6 +370,35 @@ static void serverRun() {
}
}


std::vector<int> BridgeMidiDriver::getInputDeviceIds() {
std::vector<int> deviceIds;
for (int i = 0; i < 16; i++) {
deviceIds.push_back(i);
}
return deviceIds;
}

std::string BridgeMidiDriver::getInputDeviceName(int deviceId) {
return stringf("Port %d", deviceId + 1);
}

MidiInputDevice *BridgeMidiDriver::subscribeInputDevice(int deviceId, MidiInput *midiInput) {
if (!(0 <= deviceId && deviceId < 16))
return NULL;

devices[deviceId].subscribe(midiInput);
return &devices[deviceId];
}

void BridgeMidiDriver::unsubscribeInputDevice(int deviceId, MidiInput *midiInput) {
if (!(0 <= deviceId && deviceId < 16))
return;

devices[deviceId].unsubscribe(midiInput);
}


void bridgeInit() {
serverRunning = true;
serverThread = std::thread(serverRun);
@@ -382,23 +409,6 @@ void bridgeDestroy() {
serverThread.join();
}

void bridgeMidiSubscribe(int port, MidiInput *midi) {
if (!(0 <= port && port < BRIDGE_NUM_PORTS))
return;
// Check if a Midi is already subscribed on the port
if (midiListeners[port])
return;
midiListeners[port] = midi;
}

void bridgeMidiUnsubscribe(int port, MidiInput *midi) {
if (!(0 <= port && port < BRIDGE_NUM_PORTS))
return;
if (midiListeners[port] != midi)
return;
midiListeners[port] = NULL;
}

void bridgeAudioSubscribe(int port, AudioIO *audio) {
if (!(0 <= port && port < BRIDGE_NUM_PORTS))
return;
@@ -418,5 +428,9 @@ void bridgeAudioUnsubscribe(int port, AudioIO *audio) {
audioListeners[port] = NULL;
}

BridgeMidiDriver *bridgeGetMidiDriver() {
return &driver;
}


} // namespace rack

+ 16
- 15
src/gamepad.cpp View File

@@ -49,13 +49,13 @@ void GamepadInputDevice::step() {
}


GamepadInputDriver::GamepadInputDriver() {
GamepadDriver::GamepadDriver() {
for (int i = 0; i < 16; i++) {
devices[i].deviceId = i;
}
}

std::vector<int> GamepadInputDriver::getDeviceIds() {
std::vector<int> GamepadDriver::getInputDeviceIds() {
std::vector<int> deviceIds;
for (int i = 0; i < 16; i++) {
if (glfwJoystickPresent(i)) {
@@ -65,7 +65,7 @@ std::vector<int> GamepadInputDriver::getDeviceIds() {
return deviceIds;
}

std::string GamepadInputDriver::getDeviceName(int deviceId) {
std::string GamepadDriver::getInputDeviceName(int deviceId) {
if (!(0 <= deviceId && deviceId < 16))
return "";

@@ -76,34 +76,35 @@ std::string GamepadInputDriver::getDeviceName(int deviceId) {
return stringf("Gamepad %d (unavailable)", deviceId + 1);
}

MidiInputDevice *GamepadInputDriver::getDevice(int deviceId) {
MidiInputDevice *GamepadDriver::subscribeInputDevice(int deviceId, MidiInput *midiInput) {
if (!(0 <= deviceId && deviceId < 16))
return NULL;

devices[deviceId].subscribe(midiInput);
return &devices[deviceId];
}

void GamepadDriver::unsubscribeInputDevice(int deviceId, MidiInput *midiInput) {
if (!(0 <= deviceId && deviceId < 16))
return;

static GamepadInputDriver *driver = NULL;
devices[deviceId].unsubscribe(midiInput);
}


void gamepadStep() {
// Check if the driver has been instantiated
if (!driver)
return;
static GamepadDriver driver;


void gamepadStep() {
for (int i = 0; i < 16; i++) {
if (glfwJoystickPresent(i)) {
driver->devices[i].step();
driver.devices[i].step();
}
}
}

MidiInputDriver *gamepadGetInputDriver() {
if (!driver) {
driver = new GamepadInputDriver();
}
return driver;
GamepadDriver *gamepadGetDriver() {
return &driver;
}




+ 19
- 16
src/keyboard.cpp View File

@@ -74,41 +74,44 @@ void KeyboardInputDevice::processKey(int key, bool released) {
}


std::vector<int> KeyboardInputDriver::getDeviceIds() {
std::vector<int> KeyboardDriver::getInputDeviceIds() {
return {0};
}

std::string KeyboardInputDriver::getDeviceName(int deviceId) {
std::string KeyboardDriver::getInputDeviceName(int deviceId) {
if (deviceId == 0)
return "QWERTY keyboard (US)";
return "";
}

MidiInputDevice *KeyboardInputDriver::getDevice(int deviceId) {
MidiInputDevice *KeyboardDriver::subscribeInputDevice(int deviceId, MidiInput *midiInput) {
if (deviceId != 0)
return NULL;

device.subscribe(midiInput);
return &device;
}

void KeyboardDriver::unsubscribeInputDevice(int deviceId, MidiInput *midiInput) {
if (deviceId != 0)
return;

device.unsubscribe(midiInput);
}


static KeyboardInputDriver *driver = NULL;
static KeyboardDriver driver;

void keyboardPress(int key) {
if (!driver)
return;
driver->device.processKey(key, false);
driver.device.processKey(key, false);
}

void keyboardRelease(int key) {
if (!driver)
return;
driver->device.processKey(key, true);
driver.device.processKey(key, true);
}

KeyboardInputDriver *keyboardGetInputDriver() {
// Lazily create driver
if (!driver) {
driver = new KeyboardInputDriver();
}
return driver;
KeyboardDriver *keyboardGetDriver() {
return &driver;
}




+ 2
- 0
src/main.cpp View File

@@ -6,6 +6,7 @@
#include "settings.hpp"
#include "asset.hpp"
#include "bridge.hpp"
#include "midi.hpp"
#include "osdialog.h"

#include <unistd.h>
@@ -36,6 +37,7 @@ int main(int argc, char* argv[]) {

pluginInit();
engineInit();
midiInit();
bridgeInit();
windowInit();
appInit();


+ 56
- 73
src/midi.cpp View File

@@ -8,8 +8,11 @@
namespace rack {


static std::map<int, MidiDriver*> drivers;


////////////////////
// MidiIODevice
// MidiDevice
////////////////////

void MidiInputDevice::subscribe(MidiInput *midiInput) {
@@ -17,13 +20,10 @@ void MidiInputDevice::subscribe(MidiInput *midiInput) {
}

void MidiInputDevice::unsubscribe(MidiInput *midiInput) {
// Remove MidiInput from subscriptions
auto it = subscribed.find(midiInput);
if (it != subscribed.end())
subscribed.erase(it);

if (subscribed.size() == 0) {
warn("TODO: Fix memory leak");
}
}

void MidiInputDevice::onMessage(MidiMessage message) {
@@ -33,7 +33,7 @@ void MidiInputDevice::onMessage(MidiMessage message) {
}

////////////////////
// MidiIODriver
// MidiDriver
////////////////////


@@ -41,28 +41,40 @@ void MidiInputDevice::onMessage(MidiMessage message) {
// MidiIO
////////////////////

MidiIO::~MidiIO() {
// Because of polymorphic destruction, descendants must call this in their own destructor
// setDriverId(-1);
}

std::vector<int> MidiIO::getDriverIds() {
std::vector<int> driverIds = rtmidiGetDrivers();
// Add custom driverIds
driverIds.push_back(BRIDGE_DRIVER);
driverIds.push_back(GAMEPAD_DRIVER);
driverIds.push_back(KEYBOARD_DRIVER);
std::vector<int> driverIds;
for (auto pair : drivers) {
driverIds.push_back(pair.first);
}
return driverIds;
}

std::string MidiIO::getDriverName(int driverId) {
switch (driverId) {
case -1: return "None";
case RtMidi::UNSPECIFIED: return "Unspecified";
case RtMidi::MACOSX_CORE: return "Core MIDI";
case RtMidi::LINUX_ALSA: return "ALSA";
case RtMidi::UNIX_JACK: return "JACK";
case RtMidi::WINDOWS_MM: return "Windows MIDI";
case RtMidi::RTMIDI_DUMMY: return "Dummy MIDI";
case BRIDGE_DRIVER: return "Bridge";
case GAMEPAD_DRIVER: return "Gamepad";
case KEYBOARD_DRIVER: return "Computer keyboard";
default: return "Unknown";
MidiDriver *driver = drivers[driverId];
if (driver) {
return driver->getName();
}
return "";
}

void MidiIO::setDriverId(int driverId) {
// Destroy driver
setDeviceId(-1);
if (driver) {
driver = NULL;
}
this->driverId = -1;

// Set driver
auto it = drivers.find(driverId);
if (it != drivers.end()) {
driver = it->second;
this->driverId = driverId;
}
}

@@ -109,72 +121,34 @@ void MidiIO::fromJson(json_t *rootJ) {
// MidiInput
////////////////////


MidiInput::MidiInput() {
}

MidiInput::~MidiInput() {
setDriverId(-1);
}

void MidiInput::setDriverId(int driverId) {
// Destroy driver
setDeviceId(-1);
if (driver) {
driver = NULL;
}
this->driverId = -1;

// Create driver
if (driverId >= 0) {
driver = rtmidiGetInputDriver(driverId);
}
else if (driverId == BRIDGE_DRIVER) {
// TODO
}
else if (driverId == GAMEPAD_DRIVER) {
driver = gamepadGetInputDriver();
}
else if (driverId == KEYBOARD_DRIVER) {
driver = keyboardGetInputDriver();
}

// Set driverId
if (driver) {
this->driverId = driverId;
}
}

std::vector<int> MidiInput::getDeviceIds() {
if (driver) {
return driver->getDeviceIds();
return driver->getInputDeviceIds();
}
return {};
}

std::string MidiInput::getDeviceName(int deviceId) {
if (driver) {
return driver->getDeviceName(deviceId);
return driver->getInputDeviceName(deviceId);
}
return "";
}

void MidiInput::setDeviceId(int deviceId) {
// Destroy device
if (device) {
device->unsubscribe(this);
device = NULL;
if (driver && deviceId >= 0) {
driver->unsubscribeInputDevice(deviceId, this);
}
this->deviceId = -1;

// Create device
if (driver && deviceId >= 0) {
device = driver->getDevice(deviceId);
device->subscribe(this);
}

// Set deviceId
if (device) {
driver->subscribeInputDevice(deviceId, this);
this->deviceId = deviceId;
}
}
@@ -187,12 +161,13 @@ void MidiInputQueue::onMessage(MidiMessage message) {
}

// Push to queue
if ((int) queue.size() < queueSize)
if ((int) queue.size() < queueMaxSize)
queue.push(message);
}

bool MidiInputQueue::shift(MidiMessage *message) {
if (!message) return false;
if (!message)
return false;
if (!queue.empty()) {
*message = queue.front();
queue.pop();
@@ -201,7 +176,6 @@ bool MidiInputQueue::shift(MidiMessage *message) {
return false;
}


////////////////////
// MidiOutput
////////////////////
@@ -210,15 +184,24 @@ MidiOutput::MidiOutput() {
}

MidiOutput::~MidiOutput() {
// TODO
setDriverId(-1);
}

void MidiOutput::setDriverId(int driverId) {
void MidiOutput::setDeviceId(int deviceId) {
// TODO
}

void MidiOutput::setDeviceId(int deviceId) {
// TODO
////////////////////
// midi
////////////////////

void midiInit() {
for (int driverId : rtmidiGetDrivers()) {
drivers[driverId] = rtmidiCreateDriver(driverId);
}
// drivers[BRIDGE_DRIVER] = bridgeCreateDriver();
drivers[GAMEPAD_DRIVER] = gamepadGetDriver();
drivers[KEYBOARD_DRIVER] = keyboardGetDriver();
}




+ 69
- 39
src/rtmidi.cpp View File

@@ -5,36 +5,6 @@
namespace rack {


RtMidiInputDriver::RtMidiInputDriver(int driverId) {
rtMidiIn = new RtMidiIn((RtMidi::Api) driverId);
assert(rtMidiIn);
}

RtMidiInputDriver::~RtMidiInputDriver() {
delete rtMidiIn;
}

std::vector<int> RtMidiInputDriver::getDeviceIds() {
int count = rtMidiIn->getPortCount();;
std::vector<int> deviceIds;
for (int i = 0; i < count; i++)
deviceIds.push_back(i);
return deviceIds;
}

std::string RtMidiInputDriver::getDeviceName(int deviceId) {
if (deviceId >= 0) {
return rtMidiIn->getPortName(deviceId);
}
return "";
}

MidiInputDevice *RtMidiInputDriver::getDevice(int deviceId) {
// TODO Get from cache
return new RtMidiInputDevice(rtMidiIn->getCurrentApi(), deviceId);
}


static void midiInputCallback(double timeStamp, std::vector<unsigned char> *message, void *userData) {
if (!message) return;
if (!userData) return;
@@ -54,6 +24,7 @@ static void midiInputCallback(double timeStamp, std::vector<unsigned char> *mess

RtMidiInputDevice::RtMidiInputDevice(int driverId, int deviceId) {
rtMidiIn = new RtMidiIn((RtMidi::Api) driverId, "VCV Rack");
assert(rtMidiIn);
rtMidiIn->ignoreTypes(false, false, false);
rtMidiIn->setCallback(midiInputCallback, this);
}
@@ -64,6 +35,72 @@ RtMidiInputDevice::~RtMidiInputDevice() {
}


RtMidiDriver::RtMidiDriver(int driverId) {
this->driverId = driverId;
rtMidiIn = new RtMidiIn((RtMidi::Api) driverId);
assert(rtMidiIn);
rtMidiOut = new RtMidiOut((RtMidi::Api) driverId);
assert(rtMidiOut);
}

RtMidiDriver::~RtMidiDriver() {
delete rtMidiIn;
delete rtMidiOut;
}

std::string RtMidiDriver::getName() {
switch (driverId) {
case RtMidi::UNSPECIFIED: return "Unspecified";
case RtMidi::MACOSX_CORE: return "Core MIDI";
case RtMidi::LINUX_ALSA: return "ALSA";
case RtMidi::UNIX_JACK: return "JACK";
case RtMidi::WINDOWS_MM: return "Windows MIDI";
case RtMidi::RTMIDI_DUMMY: return "Dummy MIDI";
default: return "";
}
}

std::vector<int> RtMidiDriver::getInputDeviceIds() {
// TODO The IDs unfortunately jump around in RtMidi. Is there a way to keep them constant when a MIDI device is added/removed?
int count = rtMidiIn->getPortCount();
std::vector<int> deviceIds;
for (int i = 0; i < count; i++)
deviceIds.push_back(i);
return deviceIds;
}

std::string RtMidiDriver::getInputDeviceName(int deviceId) {
if (deviceId >= 0) {
return rtMidiIn->getPortName(deviceId);
}
return "";
}

MidiInputDevice *RtMidiDriver::subscribeInputDevice(int deviceId, MidiInput *midiInput) {
RtMidiInputDevice *device = devices[deviceId];
if (!device) {
devices[deviceId] = device = new RtMidiInputDevice(driverId, deviceId);
}

device->subscribe(midiInput);
return device;
}

void RtMidiDriver::unsubscribeInputDevice(int deviceId, MidiInput *midiInput) {
RtMidiInputDevice *device = devices[deviceId];
assert(device);
device->unsubscribe(midiInput);

// Destroy device if nothing else is subscribed
if (device->subscribed.empty()) {
auto it = devices.find(deviceId);
assert(it != devices.end());
devices.erase(it);
delete device;
}
}


std::vector<int> rtmidiGetDrivers() {
std::vector<RtMidi::Api> rtApis;
RtMidi::getCompiledApi(rtApis);
@@ -75,15 +112,8 @@ std::vector<int> rtmidiGetDrivers() {
return drivers;
}

static std::map<int, RtMidiInputDriver*> rtmidiInputDrivers;

MidiInputDriver *rtmidiGetInputDriver(int driverId) {
// Lazily create RtMidiInputDriver
RtMidiInputDriver *d = rtmidiInputDrivers[driverId];
if (!d) {
rtmidiInputDrivers[driverId] = d = new RtMidiInputDriver(driverId);
}
return d;
RtMidiDriver *rtmidiCreateDriver(int driverId) {
return new RtMidiDriver(driverId);
}




Loading…
Cancel
Save