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.

220 lines
4.0KB

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