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.

217 lines
4.1KB

  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. if (driverIds.size() >= 1) {
  98. setDriverId(driverIds[0]);
  99. }
  100. }
  101. MidiInput::~MidiInput() {
  102. setDriverId(-1);
  103. }
  104. std::vector<int> MidiInput::getDeviceIds() {
  105. if (driver) {
  106. return driver->getInputDeviceIds();
  107. }
  108. return {};
  109. }
  110. std::string MidiInput::getDeviceName(int deviceId) {
  111. if (driver) {
  112. return driver->getInputDeviceName(deviceId);
  113. }
  114. return "";
  115. }
  116. void MidiInput::setDeviceId(int deviceId) {
  117. // Destroy device
  118. if (driver && this->deviceId >= 0) {
  119. driver->unsubscribeInputDevice(this->deviceId, this);
  120. }
  121. this->deviceId = -1;
  122. // Create device
  123. if (driver && deviceId >= 0) {
  124. driver->subscribeInputDevice(deviceId, this);
  125. this->deviceId = deviceId;
  126. }
  127. }
  128. void MidiInputQueue::onMessage(MidiMessage message) {
  129. // Filter channel
  130. if (channel >= 0) {
  131. if (message.status() != 0xf && message.channel() != channel)
  132. return;
  133. }
  134. // Push to queue
  135. if ((int) queue.size() < queueMaxSize)
  136. queue.push(message);
  137. }
  138. bool MidiInputQueue::shift(MidiMessage *message) {
  139. if (!message)
  140. return false;
  141. if (!queue.empty()) {
  142. *message = queue.front();
  143. queue.pop();
  144. return true;
  145. }
  146. return false;
  147. }
  148. ////////////////////
  149. // MidiOutput
  150. ////////////////////
  151. MidiOutput::MidiOutput() {
  152. }
  153. MidiOutput::~MidiOutput() {
  154. setDriverId(-1);
  155. }
  156. void MidiOutput::setDeviceId(int deviceId) {
  157. // TODO
  158. }
  159. ////////////////////
  160. // midi
  161. ////////////////////
  162. void midiDestroy() {
  163. driverIds.clear();
  164. for (auto &pair : drivers) {
  165. delete pair.second;
  166. }
  167. drivers.clear();
  168. }
  169. void midiDriverAdd(int driverId, MidiDriver *driver) {
  170. assert(driver);
  171. driverIds.push_back(driverId);
  172. drivers[driverId] = driver;
  173. }
  174. } // namespace rack