You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

212 lines
4.2KB

  1. #include "midi.hpp"
  2. #include "rtmidi.hpp"
  3. #include "bridge.hpp"
  4. #include "gamepad.hpp"
  5. #include "keyboard.hpp"
  6. namespace rack {
  7. static std::vector<int> driverIds;
  8. static std::map<int, MidiDriver*> drivers;
  9. ////////////////////
  10. // MidiDevice
  11. ////////////////////
  12. void MidiInputDevice::subscribe(MidiInput *midiInput) {
  13. subscribed.insert(midiInput);
  14. }
  15. void MidiInputDevice::unsubscribe(MidiInput *midiInput) {
  16. // Remove MidiInput from subscriptions
  17. auto it = subscribed.find(midiInput);
  18. if (it != subscribed.end())
  19. subscribed.erase(it);
  20. }
  21. void MidiInputDevice::onMessage(MidiMessage message) {
  22. for (MidiInput *midiInput : subscribed) {
  23. midiInput->onMessage(message);
  24. }
  25. }
  26. ////////////////////
  27. // MidiDriver
  28. ////////////////////
  29. ////////////////////
  30. // MidiIO
  31. ////////////////////
  32. MidiIO::~MidiIO() {
  33. // Because of polymorphic destruction, descendants must call this in their own destructor
  34. // setDriverId(-1);
  35. }
  36. std::vector<int> MidiIO::getDriverIds() {
  37. return driverIds;
  38. }
  39. std::string MidiIO::getDriverName(int driverId) {
  40. auto it = drivers.find(driverId);
  41. if (it == drivers.end())
  42. return "";
  43. return it->second->getName();
  44. }
  45. void MidiIO::setDriverId(int driverId) {
  46. // Destroy driver
  47. setDeviceId(-1);
  48. if (driver) {
  49. driver = NULL;
  50. }
  51. this->driverId = -1;
  52. // Set driver
  53. auto it = drivers.find(driverId);
  54. if (it != drivers.end()) {
  55. driver = it->second;
  56. this->driverId = driverId;
  57. }
  58. }
  59. std::string MidiIO::getChannelName(int channel) {
  60. if (channel == -1)
  61. return "All channels";
  62. else
  63. return stringf("Channel %d", channel + 1);
  64. }
  65. json_t *MidiIO::toJson() {
  66. json_t *rootJ = json_object();
  67. json_object_set_new(rootJ, "driver", json_integer(driverId));
  68. std::string deviceName = getDeviceName(deviceId);
  69. if (!deviceName.empty())
  70. json_object_set_new(rootJ, "deviceName", json_string(deviceName.c_str()));
  71. json_object_set_new(rootJ, "channel", json_integer(channel));
  72. return rootJ;
  73. }
  74. void MidiIO::fromJson(json_t *rootJ) {
  75. json_t *driverJ = json_object_get(rootJ, "driver");
  76. if (driverJ)
  77. setDriverId(json_integer_value(driverJ));
  78. json_t *deviceNameJ = json_object_get(rootJ, "deviceName");
  79. if (deviceNameJ) {
  80. std::string deviceName = json_string_value(deviceNameJ);
  81. // Search for device with equal name
  82. for (int deviceId : getDeviceIds()) {
  83. if (getDeviceName(deviceId) == deviceName) {
  84. setDeviceId(deviceId);
  85. break;
  86. }
  87. }
  88. }
  89. json_t *channelJ = json_object_get(rootJ, "channel");
  90. if (channelJ)
  91. channel = json_integer_value(channelJ);
  92. }
  93. ////////////////////
  94. // MidiInput
  95. ////////////////////
  96. MidiInput::~MidiInput() {
  97. setDriverId(-1);
  98. }
  99. std::vector<int> MidiInput::getDeviceIds() {
  100. if (driver) {
  101. return driver->getInputDeviceIds();
  102. }
  103. return {};
  104. }
  105. std::string MidiInput::getDeviceName(int deviceId) {
  106. if (driver) {
  107. return driver->getInputDeviceName(deviceId);
  108. }
  109. return "";
  110. }
  111. void MidiInput::setDeviceId(int deviceId) {
  112. // Destroy device
  113. if (driver && deviceId >= 0) {
  114. driver->unsubscribeInputDevice(deviceId, this);
  115. }
  116. this->deviceId = -1;
  117. // Create device
  118. if (driver && deviceId >= 0) {
  119. driver->subscribeInputDevice(deviceId, this);
  120. this->deviceId = deviceId;
  121. }
  122. }
  123. void MidiInputQueue::onMessage(MidiMessage message) {
  124. // Filter channel
  125. if (channel >= 0) {
  126. if (message.status() != 0xf && message.channel() != channel)
  127. return;
  128. }
  129. // Push to queue
  130. if ((int) queue.size() < queueMaxSize)
  131. queue.push(message);
  132. }
  133. bool MidiInputQueue::shift(MidiMessage *message) {
  134. if (!message)
  135. return false;
  136. if (!queue.empty()) {
  137. *message = queue.front();
  138. queue.pop();
  139. return true;
  140. }
  141. return false;
  142. }
  143. ////////////////////
  144. // MidiOutput
  145. ////////////////////
  146. MidiOutput::MidiOutput() {
  147. }
  148. MidiOutput::~MidiOutput() {
  149. setDriverId(-1);
  150. }
  151. void MidiOutput::setDeviceId(int deviceId) {
  152. // TODO
  153. }
  154. ////////////////////
  155. // midi
  156. ////////////////////
  157. static void midiAddDriver(int driverId, MidiDriver *driver) {
  158. assert(driver);
  159. driverIds.push_back(driverId);
  160. drivers[driverId] = driver;
  161. }
  162. void midiInit() {
  163. for (int driverId : rtmidiGetDrivers()) {
  164. midiAddDriver(driverId, rtmidiCreateDriver(driverId));
  165. }
  166. midiAddDriver(BRIDGE_DRIVER, bridgeGetMidiDriver());
  167. midiAddDriver(KEYBOARD_DRIVER, keyboardGetDriver());
  168. midiAddDriver(GAMEPAD_DRIVER, gamepadGetDriver());
  169. }
  170. } // namespace rack