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.

282 lines
5.8KB

  1. #pragma once
  2. #include <vector>
  3. #include <queue>
  4. #include <set>
  5. #include <jansson.h>
  6. #include <common.hpp>
  7. #include <context.hpp>
  8. namespace rack {
  9. /** MIDI driver
  10. */
  11. namespace midi {
  12. struct Message {
  13. /** Initialized to 3 empty bytes. */
  14. std::vector<uint8_t> bytes;
  15. /** Timestamp of MIDI message in nanoseconds. Negative if not set. */
  16. int64_t timestamp = -1;
  17. Message() : bytes(3) {}
  18. int getSize() const {
  19. return bytes.size();
  20. }
  21. void setSize(int size) {
  22. bytes.resize(size);
  23. }
  24. uint8_t getChannel() const {
  25. if (bytes.size() < 1)
  26. return 0;
  27. return bytes[0] & 0xf;
  28. }
  29. void setChannel(uint8_t channel) {
  30. if (bytes.size() < 1)
  31. return;
  32. bytes[0] = (bytes[0] & 0xf0) | (channel & 0xf);
  33. }
  34. uint8_t getStatus() const {
  35. if (bytes.size() < 1)
  36. return 0;
  37. return bytes[0] >> 4;
  38. }
  39. void setStatus(uint8_t status) {
  40. if (bytes.size() < 1)
  41. return;
  42. bytes[0] = (bytes[0] & 0xf) | (status << 4);
  43. }
  44. uint8_t getNote() const {
  45. if (bytes.size() < 2)
  46. return 0;
  47. return bytes[1];
  48. }
  49. void setNote(uint8_t note) {
  50. if (bytes.size() < 2)
  51. return;
  52. bytes[1] = note & 0x7f;
  53. }
  54. uint8_t getValue() const {
  55. if (bytes.size() < 3)
  56. return 0;
  57. return bytes[2];
  58. }
  59. void setValue(uint8_t value) {
  60. if (bytes.size() < 3)
  61. return;
  62. bytes[2] = value & 0x7f;
  63. }
  64. };
  65. ////////////////////
  66. // Driver
  67. ////////////////////
  68. struct InputDevice;
  69. struct Input;
  70. struct OutputDevice;
  71. struct Output;
  72. struct Driver {
  73. virtual ~Driver() {}
  74. /** Returns the name of the driver. E.g. "ALSA". */
  75. virtual std::string getName() {
  76. return "";
  77. }
  78. /** Returns a list of all input device IDs that can be subscribed to. */
  79. virtual std::vector<int> getInputDeviceIds() {
  80. return {};
  81. }
  82. /** Returns the name of an input device without obtaining it. */
  83. virtual std::string getInputDeviceName(int deviceId) {
  84. return "";
  85. }
  86. /** Adds the given port as a reference holder of a device and returns the it.
  87. Creates the Device if no ports are subscribed before calling.
  88. */
  89. virtual InputDevice* subscribeInput(int deviceId, Input* input) {
  90. return NULL;
  91. }
  92. /** Removes the give port as a reference holder of a device.
  93. Deletes the Device if no ports are subscribed after calling.
  94. */
  95. virtual void unsubscribeInput(int deviceId, Input* input) {}
  96. // The following behave identically as the above methods except for outputs.
  97. virtual std::vector<int> getOutputDeviceIds() {
  98. return {};
  99. }
  100. virtual std::string getOutputDeviceName(int deviceId) {
  101. return "";
  102. }
  103. virtual OutputDevice* subscribeOutput(int deviceId, Output* output) {
  104. return NULL;
  105. }
  106. virtual void unsubscribeOutput(int deviceId, Output* output) {}
  107. };
  108. ////////////////////
  109. // Device
  110. ////////////////////
  111. struct Device {
  112. virtual ~Device() {}
  113. virtual std::string getName() {
  114. return "";
  115. }
  116. };
  117. struct InputDevice : Device {
  118. std::set<Input*> subscribed;
  119. /** Not public. Use Driver::subscribeInput(). */
  120. void subscribe(Input* input);
  121. /** Not public. Use Driver::unsubscribeInput(). */
  122. void unsubscribe(Input* input);
  123. /** Called when a MIDI message is received from the device. */
  124. void onMessage(const Message &message);
  125. };
  126. struct OutputDevice : Device {
  127. std::set<Output*> subscribed;
  128. /** Not public. Use Driver::subscribeOutput(). */
  129. void subscribe(Output* output);
  130. /** Not public. Use Driver::unsubscribeOutput(). */
  131. void unsubscribe(Output* output);
  132. /** Sends a MIDI message to the device. */
  133. virtual void sendMessage(const Message &message) {}
  134. };
  135. ////////////////////
  136. // Port
  137. ////////////////////
  138. struct Port {
  139. /** For MIDI output, the channel to automatically set outbound messages.
  140. If -1, the channel is not overwritten and must be set by MIDI generator.
  141. For MIDI input, messages will be filtered by the channel.
  142. If -1, all MIDI channels pass through.
  143. */
  144. int channel = -1;
  145. // private
  146. int driverId = -1;
  147. int deviceId = -1;
  148. /** Not owned */
  149. Driver* driver = NULL;
  150. Device* device = NULL;
  151. Context* context;
  152. Port();
  153. virtual ~Port();
  154. Driver* getDriver() {
  155. return driver;
  156. }
  157. int getDriverId() {
  158. return driverId;
  159. }
  160. void setDriverId(int driverId);
  161. Device* getDevice() {
  162. return device;
  163. }
  164. virtual std::vector<int> getDeviceIds() = 0;
  165. int getDeviceId() {
  166. return deviceId;
  167. }
  168. virtual void setDeviceId(int deviceId) = 0;
  169. virtual std::string getDeviceName(int deviceId) = 0;
  170. virtual std::vector<int> getChannels() = 0;
  171. int getChannel() {
  172. return channel;
  173. }
  174. void setChannel(int channel);
  175. std::string getChannelName(int channel);
  176. json_t* toJson();
  177. void fromJson(json_t* rootJ);
  178. };
  179. struct Input : Port {
  180. /** Not owned */
  181. InputDevice* inputDevice = NULL;
  182. Input();
  183. ~Input();
  184. void reset();
  185. std::vector<int> getDeviceIds() override {
  186. if (driver)
  187. return driver->getInputDeviceIds();
  188. return {};
  189. }
  190. void setDeviceId(int deviceId) override;
  191. std::string getDeviceName(int deviceId) override {
  192. if (driver)
  193. return driver->getInputDeviceName(deviceId);
  194. return "";
  195. }
  196. std::vector<int> getChannels() override;
  197. virtual void onMessage(const Message &message) {}
  198. };
  199. struct InputQueue : Input {
  200. int queueMaxSize = 8192;
  201. std::queue<Message> queue;
  202. void onMessage(const Message &message) override;
  203. };
  204. struct Output : Port {
  205. /** Not owned */
  206. OutputDevice* outputDevice = NULL;
  207. Output();
  208. ~Output();
  209. void reset();
  210. std::vector<int> getDeviceIds() override {
  211. if (driver)
  212. return driver->getOutputDeviceIds();
  213. return {};
  214. }
  215. void setDeviceId(int deviceId) override;
  216. std::string getDeviceName(int deviceId) override {
  217. if (driver)
  218. return driver->getInputDeviceName(deviceId);
  219. return "";
  220. }
  221. std::vector<int> getChannels() override;
  222. void sendMessage(const Message &message);
  223. };
  224. void init();
  225. void destroy();
  226. /** Registers a new MIDI driver. Takes pointer ownership. */
  227. void addDriver(int driverId, Driver* driver);
  228. std::vector<int> getDriverIds();
  229. Driver* getDriver(int driverId);
  230. } // namespace midi
  231. } // namespace rack