diff --git a/include/gamepad.hpp b/include/gamepad.hpp index 410225bc..84cb5299 100644 --- a/include/gamepad.hpp +++ b/include/gamepad.hpp @@ -11,7 +11,7 @@ const int GAMEPAD_DRIVER = -10; struct GamepadInputDevice : MidiInputDevice { - int device; + int deviceId; }; @@ -19,9 +19,9 @@ struct GamepadInputDriver : MidiInputDriver { GamepadInputDevice gamepadInputDevices[16]; GamepadInputDriver(); - int getDeviceCount() override; - std::string getDeviceName(int device) override; - MidiInputDevice *getDevice(int device) override; + std::vector getDeviceIds() override; + std::string getDeviceName(int deviceId) override; + MidiInputDevice *getDevice(int deviceId) override; }; diff --git a/include/midi.hpp b/include/midi.hpp index bb573ad7..8663dc67 100644 --- a/include/midi.hpp +++ b/include/midi.hpp @@ -56,16 +56,16 @@ struct MidiOutputDevice : MidiIODevice { struct MidiIODriver { virtual ~MidiIODriver() {} - virtual int getDeviceCount() = 0; - virtual std::string getDeviceName(int device) = 0; + virtual std::vector getDeviceIds() = 0; + virtual std::string getDeviceName(int deviceId) = 0; }; struct MidiInputDriver : MidiIODriver { - virtual MidiInputDevice *getDevice(int device) = 0; + virtual MidiInputDevice *getDevice(int deviceId) = 0; }; struct MidiOutputDriver : MidiIODriver { - virtual MidiOutputDevice *getDevice(int device) = 0; + virtual MidiOutputDevice *getDevice(int deviceId) = 0; }; //////////////////// @@ -73,8 +73,8 @@ struct MidiOutputDriver : MidiIODriver { //////////////////// struct MidiIO { - int driver = -1; - int device = -1; + int driverId = -1; + int deviceId = -1; /* For MIDI output, the channel to output messages. For MIDI input, the channel to filter. Set to -1 to allow all MIDI channels (for input). @@ -84,13 +84,13 @@ struct MidiIO { virtual ~MidiIO() {} - std::vector getDrivers(); - std::string getDriverName(int driver); - virtual void setDriver(int driver) = 0; + std::vector getDriverIds(); + std::string getDriverName(int driverId); + virtual void setDriverId(int driverId) = 0; - virtual int getDeviceCount() = 0; - virtual std::string getDeviceName(int device) = 0; - virtual void setDevice(int device) = 0; + virtual std::vector getDeviceIds() = 0; + virtual std::string getDeviceName(int deviceId) = 0; + virtual void setDeviceId(int deviceId) = 0; std::string getChannelName(int channel); json_t *toJson(); @@ -100,17 +100,17 @@ struct MidiIO { struct MidiInput : MidiIO { /** Not owned */ - MidiInputDriver *midiInputDriver = NULL; + MidiInputDriver *driver = NULL; /** Not owned, must unsubscribe when destructed */ - MidiInputDevice *midiInputDevice = NULL; + MidiInputDevice *device = NULL; MidiInput(); ~MidiInput(); - void setDriver(int driver) override; - int getDeviceCount() override; - std::string getDeviceName(int device) override; - void setDevice(int device) override; + void setDriverId(int driverId) override; + std::vector getDeviceIds() override; + std::string getDeviceName(int deviceId) override; + void setDeviceId(int deviceId) override; virtual void onMessage(MidiMessage message) {} }; @@ -128,13 +128,13 @@ struct MidiInputQueue : MidiInput { struct MidiOutput : MidiIO { /** Not owned */ - MidiOutputDriver *midiOutputDriver = NULL; + MidiOutputDriver *driver = NULL; /** Not owned, must unsubscribe when destructed */ - MidiOutputDevice *midiOutputDevice = NULL; + MidiOutputDevice *device = NULL; MidiOutput(); ~MidiOutput(); - void setDriver(int driver) override; - void setDevice(int device) override; + void setDriverId(int driverId) override; + void setDeviceId(int deviceId) override; }; diff --git a/include/rtmidi.hpp b/include/rtmidi.hpp index 987832d1..b765597b 100644 --- a/include/rtmidi.hpp +++ b/include/rtmidi.hpp @@ -18,11 +18,11 @@ struct RtMidiInputDriver : MidiInputDriver { /** Just for querying MIDI driver information */ RtMidiIn *rtMidiIn; - RtMidiInputDriver(int driver); + RtMidiInputDriver(int driverId); ~RtMidiInputDriver(); - int getDeviceCount() override; - std::string getDeviceName(int device) override; - MidiInputDevice *getDevice(int device) override; + std::vector getDeviceIds() override; + std::string getDeviceName(int deviceId) override; + MidiInputDevice *getDevice(int deviceId) override; }; @@ -31,13 +31,13 @@ struct RtMidiInputDevice : MidiInputDevice { /** Cached */ std::string deviceName; - RtMidiInputDevice(int driver, int device); + RtMidiInputDevice(int driverId, int deviceId); ~RtMidiInputDevice(); }; std::vector rtmidiGetDrivers(); -MidiInputDriver *rtmidiGetInputDriver(int driver); +MidiInputDriver *rtmidiGetInputDriver(int driverId); } // namespace rack diff --git a/src/app/MidiWidget.cpp b/src/app/MidiWidget.cpp index 33e41daa..39736c40 100644 --- a/src/app/MidiWidget.cpp +++ b/src/app/MidiWidget.cpp @@ -7,9 +7,9 @@ namespace rack { struct MidiDriverItem : MenuItem { MidiIO *midiIO; - int driver; + int driverId; void onAction(EventAction &e) override { - midiIO->setDriver(driver); + midiIO->setDriverId(driverId); } }; @@ -18,25 +18,25 @@ struct MidiDriverChoice : LedDisplayChoice { void onAction(EventAction &e) override { Menu *menu = gScene->createMenu(); menu->addChild(construct(&MenuLabel::text, "MIDI driver")); - for (int driver : midiWidget->midiIO->getDrivers()) { + for (int driverId : midiWidget->midiIO->getDriverIds()) { MidiDriverItem *item = new MidiDriverItem(); item->midiIO = midiWidget->midiIO; - item->driver = driver; - item->text = midiWidget->midiIO->getDriverName(driver); - item->rightText = CHECKMARK(item->driver == midiWidget->midiIO->driver); + item->driverId = driverId; + item->text = midiWidget->midiIO->getDriverName(driverId); + item->rightText = CHECKMARK(item->driverId == midiWidget->midiIO->driverId); menu->addChild(item); } } void step() override { - text = midiWidget->midiIO->getDriverName(midiWidget->midiIO->driver); + text = midiWidget->midiIO->getDriverName(midiWidget->midiIO->driverId); } }; struct MidiDeviceItem : MenuItem { MidiIO *midiIO; - int device; + int deviceId; void onAction(EventAction &e) override { - midiIO->setDevice(device); + midiIO->setDeviceId(deviceId); } }; @@ -48,23 +48,22 @@ struct MidiDeviceChoice : LedDisplayChoice { { MidiDeviceItem *item = new MidiDeviceItem(); item->midiIO = midiWidget->midiIO; - item->device = -1; + item->deviceId = -1; item->text = "(No device)"; - item->rightText = CHECKMARK(item->device == midiWidget->midiIO->device); + item->rightText = CHECKMARK(item->deviceId == midiWidget->midiIO->deviceId); menu->addChild(item); } - int driverCount = midiWidget->midiIO->getDeviceCount(); - for (int device = 0; device < driverCount; device++) { + for (int deviceId : midiWidget->midiIO->getDeviceIds()) { MidiDeviceItem *item = new MidiDeviceItem(); item->midiIO = midiWidget->midiIO; - item->device = device; - item->text = midiWidget->midiIO->getDeviceName(device); - item->rightText = CHECKMARK(item->device == midiWidget->midiIO->device); + item->deviceId = deviceId; + item->text = midiWidget->midiIO->getDeviceName(deviceId); + item->rightText = CHECKMARK(item->deviceId == midiWidget->midiIO->deviceId); menu->addChild(item); } } void step() override { - text = midiWidget->midiIO->getDeviceName(midiWidget->midiIO->device); + text = midiWidget->midiIO->getDeviceName(midiWidget->midiIO->deviceId); if (text.empty()) { text = "(No device)"; color.a = 0.5f; diff --git a/src/gamepad.cpp b/src/gamepad.cpp index e30ade2b..a52c75a4 100644 --- a/src/gamepad.cpp +++ b/src/gamepad.cpp @@ -8,26 +8,36 @@ namespace rack { GamepadInputDriver::GamepadInputDriver() { for (int i = 0; i < 16; i++) { - gamepadInputDevices[i].device = i; + gamepadInputDevices[i].deviceId = i; } } -int GamepadInputDriver::getDeviceCount() { - return 16; +std::vector GamepadInputDriver::getDeviceIds() { + std::vector deviceIds; + for (int i = 0; i < 16; i++) { + if (glfwJoystickPresent(i)) { + deviceIds.push_back(i); + } + } + return deviceIds; } -std::string GamepadInputDriver::getDeviceName(int device) { - assert(0 <= device && device < 16); - const char *name = glfwGetJoystickName(device); +std::string GamepadInputDriver::getDeviceName(int deviceId) { + if (!(0 <= deviceId && deviceId < 16)) + return ""; + + const char *name = glfwGetJoystickName(deviceId); if (name) { return name; } - return stringf("Gamepad %d (unavailable)", device + 1); + return stringf("Gamepad %d (unavailable)", deviceId + 1); } -MidiInputDevice *GamepadInputDriver::getDevice(int device) { - assert(0 <= device && device < 16); - return &gamepadInputDevices[device]; +MidiInputDevice *GamepadInputDriver::getDevice(int deviceId) { + if (!(0 <= deviceId && deviceId < 16)) + return NULL; + + return &gamepadInputDevices[deviceId]; } diff --git a/src/midi.cpp b/src/midi.cpp index 5c6ec348..0c479956 100644 --- a/src/midi.cpp +++ b/src/midi.cpp @@ -40,16 +40,16 @@ void MidiInputDevice::onMessage(MidiMessage message) { // MidiIO //////////////////// -std::vector MidiIO::getDrivers() { - std::vector drivers = rtmidiGetDrivers(); - // Add custom drivers - drivers.push_back(BRIDGE_DRIVER); - drivers.push_back(GAMEPAD_DRIVER); - return drivers; +std::vector MidiIO::getDriverIds() { + std::vector driverIds = rtmidiGetDrivers(); + // Add custom driverIds + driverIds.push_back(BRIDGE_DRIVER); + driverIds.push_back(GAMEPAD_DRIVER); + return driverIds; } -std::string MidiIO::getDriverName(int driver) { - switch (driver) { +std::string MidiIO::getDriverName(int driverId) { + switch (driverId) { case RtMidi::UNSPECIFIED: return "Unspecified"; case RtMidi::MACOSX_CORE: return "Core MIDI"; case RtMidi::LINUX_ALSA: return "ALSA"; @@ -71,8 +71,8 @@ std::string MidiIO::getChannelName(int channel) { json_t *MidiIO::toJson() { json_t *rootJ = json_object(); - json_object_set_new(rootJ, "driver", json_integer(driver)); - std::string deviceName = getDeviceName(device); + json_object_set_new(rootJ, "driver", json_integer(driverId)); + std::string deviceName = getDeviceName(deviceId); if (!deviceName.empty()) json_object_set_new(rootJ, "deviceName", json_string(deviceName.c_str())); json_object_set_new(rootJ, "channel", json_integer(channel)); @@ -82,16 +82,15 @@ json_t *MidiIO::toJson() { void MidiIO::fromJson(json_t *rootJ) { json_t *driverJ = json_object_get(rootJ, "driver"); if (driverJ) - setDriver(json_integer_value(driverJ)); + setDriverId(json_integer_value(driverJ)); json_t *deviceNameJ = json_object_get(rootJ, "deviceName"); if (deviceNameJ) { std::string deviceName = json_string_value(deviceNameJ); // Search for device with equal name - int deviceCount = getDeviceCount(); - for (int device = 0; device < deviceCount; device++) { - if (getDeviceName(device) == deviceName) { - setDevice(device); + for (int deviceId : getDeviceIds()) { + if (getDeviceName(deviceId) == deviceName) { + setDeviceId(deviceId); break; } } @@ -111,52 +110,66 @@ MidiInput::MidiInput() { } MidiInput::~MidiInput() { - setDriver(-1); + setDriverId(-1); } -void MidiInput::setDriver(int driver) { - setDevice(-1); - if (midiInputDriver) { - midiInputDriver = NULL; +void MidiInput::setDriverId(int driverId) { + // Destroy driver + setDeviceId(-1); + if (driver) { + driver = NULL; } + this->driverId = -1; - if (driver >= 0) { - midiInputDriver = rtmidiGetInputDriver(driver); + // Create driver + if (driverId >= 0) { + driver = rtmidiGetInputDriver(driverId); } - else if (driver == BRIDGE_DRIVER) { + else if (driverId == BRIDGE_DRIVER) { // TODO } - else if (driver == GAMEPAD_DRIVER) { - midiInputDriver = gamepadGetInputDriver(); + else if (driverId == GAMEPAD_DRIVER) { + driver = gamepadGetInputDriver(); + } + + // Set driverId + if (driver) { + this->driverId = driverId; } - this->driver = driver; } -int MidiInput::getDeviceCount() { - if (midiInputDriver) { - return midiInputDriver->getDeviceCount(); +std::vector MidiInput::getDeviceIds() { + if (driver) { + return driver->getDeviceIds(); } - return 0; + return {}; } -std::string MidiInput::getDeviceName(int device) { - if (midiInputDriver) { - return midiInputDriver->getDeviceName(device); +std::string MidiInput::getDeviceName(int deviceId) { + if (driver) { + return driver->getDeviceName(deviceId); } return ""; } -void MidiInput::setDevice(int device) { - if (midiInputDevice) { - midiInputDevice->unsubscribe(this); - midiInputDevice = NULL; +void MidiInput::setDeviceId(int deviceId) { + // Destroy device + if (device) { + device->unsubscribe(this); + device = NULL; + } + this->deviceId = -1; + + // Create device + if (driver && deviceId >= 0) { + device = driver->getDevice(deviceId); + device->subscribe(this); } - if (midiInputDriver && device >= 0) { - midiInputDevice = midiInputDriver->getDevice(device); - midiInputDevice->subscribe(this); + // Set deviceId + if (device) { + this->deviceId = deviceId; } - this->device = device; } void MidiInputQueue::onMessage(MidiMessage message) { @@ -192,11 +205,11 @@ MidiOutput::~MidiOutput() { // TODO } -void MidiOutput::setDriver(int driver) { +void MidiOutput::setDriverId(int driverId) { // TODO } -void MidiOutput::setDevice(int device) { +void MidiOutput::setDeviceId(int deviceId) { // TODO } diff --git a/src/rtmidi.cpp b/src/rtmidi.cpp index f870d23d..74f0be40 100644 --- a/src/rtmidi.cpp +++ b/src/rtmidi.cpp @@ -5,8 +5,8 @@ namespace rack { -RtMidiInputDriver::RtMidiInputDriver(int driver) { - rtMidiIn = new RtMidiIn((RtMidi::Api) driver); +RtMidiInputDriver::RtMidiInputDriver(int driverId) { + rtMidiIn = new RtMidiIn((RtMidi::Api) driverId); assert(rtMidiIn); } @@ -14,20 +14,24 @@ RtMidiInputDriver::~RtMidiInputDriver() { delete rtMidiIn; } -int RtMidiInputDriver::getDeviceCount() { - return rtMidiIn->getPortCount(); +std::vector RtMidiInputDriver::getDeviceIds() { + int count = rtMidiIn->getPortCount();; + std::vector deviceIds; + for (int i = 0; i < count; i++) + deviceIds.push_back(i); + return deviceIds; } -std::string RtMidiInputDriver::getDeviceName(int device) { - if (device >= 0) { - return rtMidiIn->getPortName(device); +std::string RtMidiInputDriver::getDeviceName(int deviceId) { + if (deviceId >= 0) { + return rtMidiIn->getPortName(deviceId); } return ""; } -MidiInputDevice *RtMidiInputDriver::getDevice(int device) { +MidiInputDevice *RtMidiInputDriver::getDevice(int deviceId) { // TODO Get from cache - return new RtMidiInputDevice(rtMidiIn->getCurrentApi(), device); + return new RtMidiInputDevice(rtMidiIn->getCurrentApi(), deviceId); } @@ -48,8 +52,8 @@ static void midiInputCallback(double timeStamp, std::vector *mess midiInputDevice->onMessage(msg); } -RtMidiInputDevice::RtMidiInputDevice(int driver, int device) { - rtMidiIn = new RtMidiIn((RtMidi::Api) driver, "VCV Rack"); +RtMidiInputDevice::RtMidiInputDevice(int driverId, int deviceId) { + rtMidiIn = new RtMidiIn((RtMidi::Api) driverId, "VCV Rack"); rtMidiIn->ignoreTypes(false, false, false); rtMidiIn->setCallback(midiInputCallback, this); } @@ -73,11 +77,11 @@ std::vector rtmidiGetDrivers() { static std::map rtmidiInputDrivers; -MidiInputDriver *rtmidiGetInputDriver(int driver) { +MidiInputDriver *rtmidiGetInputDriver(int driverId) { // Lazily create RtMidiInputDriver - RtMidiInputDriver *d = rtmidiInputDrivers[driver]; + RtMidiInputDriver *d = rtmidiInputDrivers[driverId]; if (!d) { - rtmidiInputDrivers[driver] = d = new RtMidiInputDriver(driver); + rtmidiInputDrivers[driverId] = d = new RtMidiInputDriver(driverId); } return d; }