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.

midi.hpp 6.9KB

6 years ago
6 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300
  1. #pragma once
  2. #include <vector>
  3. #include <set>
  4. #include <jansson.h>
  5. #include <common.hpp>
  6. #include <context.hpp>
  7. namespace rack {
  8. /** Abstraction for all MIDI drivers in Rack */
  9. namespace midi {
  10. struct Message {
  11. /** Initialized to 3 empty bytes. */
  12. std::vector<uint8_t> bytes;
  13. /** The Engine frame timestamp of the Message.
  14. For output messages, the frame when the message was generated.
  15. For input messages, the frame when it is intended to be processed.
  16. -1 for undefined, to be sent or processed immediately.
  17. */
  18. int64_t frame = -1;
  19. Message() : bytes(3) {}
  20. int getSize() const {
  21. return bytes.size();
  22. }
  23. void setSize(int size) {
  24. bytes.resize(size);
  25. }
  26. uint8_t getChannel() const {
  27. if (bytes.size() < 1)
  28. return 0;
  29. return bytes[0] & 0xf;
  30. }
  31. void setChannel(uint8_t channel) {
  32. if (bytes.size() < 1)
  33. return;
  34. bytes[0] = (bytes[0] & 0xf0) | (channel & 0xf);
  35. }
  36. uint8_t getStatus() const {
  37. if (bytes.size() < 1)
  38. return 0;
  39. return bytes[0] >> 4;
  40. }
  41. void setStatus(uint8_t status) {
  42. if (bytes.size() < 1)
  43. return;
  44. bytes[0] = (bytes[0] & 0xf) | (status << 4);
  45. }
  46. uint8_t getNote() const {
  47. if (bytes.size() < 2)
  48. return 0;
  49. return bytes[1];
  50. }
  51. void setNote(uint8_t note) {
  52. if (bytes.size() < 2)
  53. return;
  54. bytes[1] = note & 0x7f;
  55. }
  56. uint8_t getValue() const {
  57. if (bytes.size() < 3)
  58. return 0;
  59. return bytes[2];
  60. }
  61. void setValue(uint8_t value) {
  62. if (bytes.size() < 3)
  63. return;
  64. bytes[2] = value & 0x7f;
  65. }
  66. std::string toString() const;
  67. int64_t getFrame() const {
  68. return frame;
  69. }
  70. void setFrame(int64_t frame) {
  71. this->frame = frame;
  72. }
  73. };
  74. ////////////////////
  75. // Driver
  76. ////////////////////
  77. struct InputDevice;
  78. struct Input;
  79. struct OutputDevice;
  80. struct Output;
  81. /** Wraps a MIDI driver API containing any number of MIDI devices.
  82. */
  83. struct Driver {
  84. virtual ~Driver() {}
  85. /** Returns the name of the driver. E.g. "ALSA". */
  86. virtual std::string getName() {
  87. return "";
  88. }
  89. /** Returns a list of all input device IDs that can be subscribed to. */
  90. virtual std::vector<int> getInputDeviceIds() {
  91. return {};
  92. }
  93. /** Returns the default device to use when the driver is selected, or -1 for none. */
  94. virtual int getDefaultInputDeviceId() {
  95. return -1;
  96. }
  97. /** Returns the name of an input device without obtaining it. */
  98. virtual std::string getInputDeviceName(int deviceId) {
  99. return "";
  100. }
  101. /** Adds the given port as a reference holder of a device and returns the it.
  102. Creates the Device if no ports are subscribed before calling.
  103. */
  104. virtual InputDevice* subscribeInput(int deviceId, Input* input) {
  105. return NULL;
  106. }
  107. /** Removes the give port as a reference holder of a device.
  108. Deletes the Device if no ports are subscribed after calling.
  109. */
  110. virtual void unsubscribeInput(int deviceId, Input* input) {}
  111. // The following behave identically as the above methods except for outputs.
  112. virtual std::vector<int> getOutputDeviceIds() {
  113. return {};
  114. }
  115. virtual int getDefaultOutputDeviceId() {
  116. return -1;
  117. }
  118. virtual std::string getOutputDeviceName(int deviceId) {
  119. return "";
  120. }
  121. virtual OutputDevice* subscribeOutput(int deviceId, Output* output) {
  122. return NULL;
  123. }
  124. virtual void unsubscribeOutput(int deviceId, Output* output) {}
  125. };
  126. ////////////////////
  127. // Device
  128. ////////////////////
  129. /** A single MIDI device of a driver API.
  130. Modules and the UI should not interact with this API directly. Use Port instead.
  131. Methods throw `rack::Exception` if the driver API has an exception.
  132. */
  133. struct Device {
  134. virtual ~Device() {}
  135. virtual std::string getName() {
  136. return "";
  137. }
  138. };
  139. struct InputDevice : Device {
  140. std::set<Input*> subscribed;
  141. /** Not public. Use Driver::subscribeInput(). */
  142. void subscribe(Input* input);
  143. /** Not public. Use Driver::unsubscribeInput(). */
  144. void unsubscribe(Input* input);
  145. /** Called when a MIDI message is received from the device. */
  146. void onMessage(const Message& message);
  147. };
  148. struct OutputDevice : Device {
  149. std::set<Output*> subscribed;
  150. /** Not public. Use Driver::subscribeOutput(). */
  151. void subscribe(Output* output);
  152. /** Not public. Use Driver::unsubscribeOutput(). */
  153. void unsubscribe(Output* output);
  154. /** Sends a MIDI message to the device. */
  155. virtual void sendMessage(const Message& message) {}
  156. };
  157. ////////////////////
  158. // Port
  159. ////////////////////
  160. /** A handle to a Device, typically owned by modules to have shared access to a single Device.
  161. All Port methods safely wrap Drivers methods.
  162. That is, if the active Device throws a `rack::Exception`, it is caught and logged inside all Port methods, so they do not throw exceptions.
  163. Use Input or Output subclasses in your module, not Port directly.
  164. */
  165. struct Port {
  166. /** For MIDI output, the channel to automatically set outbound messages.
  167. If -1, the channel is not overwritten and must be set by MIDI generator.
  168. For MIDI input, messages will be filtered by the channel.
  169. If -1, all MIDI channels pass through.
  170. */
  171. int channel = -1;
  172. // private
  173. int driverId = -1;
  174. int deviceId = -1;
  175. /** Not owned */
  176. Driver* driver = NULL;
  177. Device* device = NULL;
  178. Context* context;
  179. Port();
  180. virtual ~Port();
  181. Driver* getDriver();
  182. int getDriverId();
  183. void setDriverId(int driverId);
  184. Device* getDevice();
  185. virtual std::vector<int> getDeviceIds() = 0;
  186. virtual int getDefaultDeviceId() = 0;
  187. int getDeviceId();
  188. virtual void setDeviceId(int deviceId) = 0;
  189. virtual std::string getDeviceName(int deviceId) = 0;
  190. virtual std::vector<int> getChannels() = 0;
  191. int getChannel();
  192. void setChannel(int channel);
  193. std::string getChannelName(int channel);
  194. json_t* toJson();
  195. void fromJson(json_t* rootJ);
  196. };
  197. struct Input : Port {
  198. /** Not owned */
  199. InputDevice* inputDevice = NULL;
  200. Input();
  201. ~Input();
  202. void reset();
  203. std::vector<int> getDeviceIds() override;
  204. int getDefaultDeviceId() override;
  205. void setDeviceId(int deviceId) override;
  206. std::string getDeviceName(int deviceId) override;
  207. std::vector<int> getChannels() override;
  208. virtual void onMessage(const Message& message) {}
  209. };
  210. /** An Input port that stores incoming MIDI messages and releases them when ready according to their frame timestamp.
  211. */
  212. struct InputQueue : Input {
  213. struct Internal;
  214. Internal* internal;
  215. InputQueue();
  216. ~InputQueue();
  217. void onMessage(const Message& message) override;
  218. /** Pops and returns the next message (by setting `messageOut`) if its frame timestamp is `maxFrame` or earlier.
  219. Returns whether a message was returned.
  220. */
  221. bool tryPop(Message* messageOut, int64_t maxFrame);
  222. size_t size();
  223. };
  224. struct Output : Port {
  225. /** Not owned */
  226. OutputDevice* outputDevice = NULL;
  227. Output();
  228. ~Output();
  229. void reset();
  230. std::vector<int> getDeviceIds() override;
  231. int getDefaultDeviceId() override;
  232. void setDeviceId(int deviceId) override;
  233. std::string getDeviceName(int deviceId) override;
  234. std::vector<int> getChannels() override;
  235. void sendMessage(const Message& message);
  236. };
  237. PRIVATE void init();
  238. PRIVATE void destroy();
  239. /** Registers a new MIDI driver. Takes pointer ownership. */
  240. void addDriver(int driverId, Driver* driver);
  241. std::vector<int> getDriverIds();
  242. Driver* getDriver(int driverId);
  243. } // namespace midi
  244. } // namespace rack