|
@@ -21,16 +21,23 @@ |
|
|
namespace rack { |
|
|
namespace rack { |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
static void rtMidiErrorCallback(RtMidiError::Type type, const std::string& errorText, void* userData) { |
|
|
|
|
|
// Do nothing |
|
|
|
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
struct RtMidiInputDevice : midi::InputDevice { |
|
|
struct RtMidiInputDevice : midi::InputDevice { |
|
|
RtMidiIn* rtMidiIn; |
|
|
RtMidiIn* rtMidiIn; |
|
|
std::string name; |
|
|
std::string name; |
|
|
|
|
|
|
|
|
RtMidiInputDevice(int driverId, int deviceId) { |
|
|
RtMidiInputDevice(int driverId, int deviceId) { |
|
|
rtMidiIn = new RtMidiIn((RtMidi::Api) driverId, "VCV Rack"); |
|
|
|
|
|
if (!rtMidiIn) { |
|
|
|
|
|
throw Exception(string::f("Failed to create RtMidi input driver %d", driverId)); |
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
rtMidiIn = new RtMidiIn((RtMidi::Api) driverId, "VCV Rack"); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
catch (RtMidiError& e) { |
|
|
|
|
|
throw Exception(string::f("Failed to create RtMidi input driver %d: %s", driverId, e.what())); |
|
|
|
|
|
} |
|
|
|
|
|
rtMidiIn->setErrorCallback(rtMidiErrorCallback); |
|
|
rtMidiIn->ignoreTypes(false, false, false); |
|
|
rtMidiIn->ignoreTypes(false, false, false); |
|
|
rtMidiIn->setCallback(midiInputCallback, this); |
|
|
rtMidiIn->setCallback(midiInputCallback, this); |
|
|
|
|
|
|
|
@@ -50,6 +57,7 @@ struct RtMidiInputDevice : midi::InputDevice { |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
~RtMidiInputDevice() { |
|
|
~RtMidiInputDevice() { |
|
|
|
|
|
// This does not throw for any driver API |
|
|
rtMidiIn->closePort(); |
|
|
rtMidiIn->closePort(); |
|
|
delete rtMidiIn; |
|
|
delete rtMidiIn; |
|
|
} |
|
|
} |
|
@@ -93,10 +101,13 @@ struct RtMidiOutputDevice : midi::OutputDevice { |
|
|
bool stopped = false; |
|
|
bool stopped = false; |
|
|
|
|
|
|
|
|
RtMidiOutputDevice(int driverId, int deviceId) : messageQueue(messageEarlier) { |
|
|
RtMidiOutputDevice(int driverId, int deviceId) : messageQueue(messageEarlier) { |
|
|
rtMidiOut = new RtMidiOut((RtMidi::Api) driverId, "VCV Rack"); |
|
|
|
|
|
if (!rtMidiOut) { |
|
|
|
|
|
throw Exception(string::f("Failed to create RtMidi output driver %d", driverId)); |
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
rtMidiOut = new RtMidiOut((RtMidi::Api) driverId, "VCV Rack"); |
|
|
} |
|
|
} |
|
|
|
|
|
catch (RtMidiError& e) { |
|
|
|
|
|
throw Exception(string::f("Failed to create RtMidi output driver %d: %s", driverId, e.what())); |
|
|
|
|
|
} |
|
|
|
|
|
rtMidiOut->setErrorCallback(rtMidiErrorCallback); |
|
|
|
|
|
|
|
|
try { |
|
|
try { |
|
|
name = rtMidiOut->getPortName(deviceId); |
|
|
name = rtMidiOut->getPortName(deviceId); |
|
@@ -117,6 +128,7 @@ struct RtMidiOutputDevice : midi::OutputDevice { |
|
|
|
|
|
|
|
|
~RtMidiOutputDevice() { |
|
|
~RtMidiOutputDevice() { |
|
|
stopThread(); |
|
|
stopThread(); |
|
|
|
|
|
// This does not throw for any driver API |
|
|
rtMidiOut->closePort(); |
|
|
rtMidiOut->closePort(); |
|
|
delete rtMidiOut; |
|
|
delete rtMidiOut; |
|
|
} |
|
|
} |
|
@@ -194,20 +206,28 @@ struct RtMidiDriver : midi::Driver { |
|
|
|
|
|
|
|
|
RtMidiDriver(int driverId) { |
|
|
RtMidiDriver(int driverId) { |
|
|
this->driverId = driverId; |
|
|
this->driverId = driverId; |
|
|
rtMidiIn = new RtMidiIn((RtMidi::Api) driverId); |
|
|
|
|
|
if (!rtMidiIn) { |
|
|
|
|
|
throw Exception(string::f("Failed to create RtMidi input driver %d", driverId)); |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
rtMidiIn = new RtMidiIn((RtMidi::Api) driverId); |
|
|
|
|
|
} |
|
|
|
|
|
catch (RtMidiError& e) { |
|
|
|
|
|
throw Exception(string::f("Failed to create RtMidi input driver %d: %s", driverId, e.what())); |
|
|
} |
|
|
} |
|
|
|
|
|
rtMidiIn->setErrorCallback(rtMidiErrorCallback); |
|
|
|
|
|
|
|
|
rtMidiOut = new RtMidiOut((RtMidi::Api) driverId); |
|
|
|
|
|
if (!rtMidiOut) { |
|
|
|
|
|
throw Exception(string::f("Failed to create RtMidi output driver %d", driverId)); |
|
|
|
|
|
|
|
|
try { |
|
|
|
|
|
rtMidiOut = new RtMidiOut((RtMidi::Api) driverId); |
|
|
|
|
|
} |
|
|
|
|
|
catch (RtMidiError& e) { |
|
|
|
|
|
throw Exception(string::f("Failed to create RtMidi output driver %d: %s", driverId, e.what())); |
|
|
} |
|
|
} |
|
|
|
|
|
rtMidiOut->setErrorCallback(rtMidiErrorCallback); |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
~RtMidiDriver() { |
|
|
~RtMidiDriver() { |
|
|
assert(inputDevices.empty()); |
|
|
assert(inputDevices.empty()); |
|
|
assert(outputDevices.empty()); |
|
|
assert(outputDevices.empty()); |
|
|
|
|
|
// This does not throw for any driver API |
|
|
delete rtMidiIn; |
|
|
delete rtMidiIn; |
|
|
delete rtMidiOut; |
|
|
delete rtMidiOut; |
|
|
} |
|
|
} |
|
|