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.

218 lines
4.3KB

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