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.0KB

6 years ago
6 years ago
123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270
  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. NAN if not set. */
  16. double timestamp = NAN;
  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. /** Wraps a MIDI driver API containing any number of MIDI devices.
  73. */
  74. struct Driver {
  75. virtual ~Driver() {}
  76. /** Returns the name of the driver. E.g. "ALSA". */
  77. virtual std::string getName() {
  78. return "";
  79. }
  80. /** Returns a list of all input device IDs that can be subscribed to. */
  81. virtual std::vector<int> getInputDeviceIds() {
  82. return {};
  83. }
  84. /** Returns the name of an input device without obtaining it. */
  85. virtual std::string getInputDeviceName(int deviceId) {
  86. return "";
  87. }
  88. /** Adds the given port as a reference holder of a device and returns the it.
  89. Creates the Device if no ports are subscribed before calling.
  90. */
  91. virtual InputDevice* subscribeInput(int deviceId, Input* input) {
  92. return NULL;
  93. }
  94. /** Removes the give port as a reference holder of a device.
  95. Deletes the Device if no ports are subscribed after calling.
  96. */
  97. virtual void unsubscribeInput(int deviceId, Input* input) {}
  98. // The following behave identically as the above methods except for outputs.
  99. virtual std::vector<int> getOutputDeviceIds() {
  100. return {};
  101. }
  102. virtual std::string getOutputDeviceName(int deviceId) {
  103. return "";
  104. }
  105. virtual OutputDevice* subscribeOutput(int deviceId, Output* output) {
  106. return NULL;
  107. }
  108. virtual void unsubscribeOutput(int deviceId, Output* output) {}
  109. };
  110. ////////////////////
  111. // Device
  112. ////////////////////
  113. /** A single MIDI device of a driver API.
  114. Modules and the UI should not interact with this API directly. Use Port instead.
  115. Methods throw `rack::Exception` if the driver API has an exception.
  116. */
  117. struct Device {
  118. virtual ~Device() {}
  119. virtual std::string getName() {
  120. return "";
  121. }
  122. };
  123. struct InputDevice : Device {
  124. std::set<Input*> subscribed;
  125. /** Not public. Use Driver::subscribeInput(). */
  126. void subscribe(Input* input);
  127. /** Not public. Use Driver::unsubscribeInput(). */
  128. void unsubscribe(Input* input);
  129. /** Called when a MIDI message is received from the device. */
  130. void onMessage(const Message &message);
  131. };
  132. struct OutputDevice : Device {
  133. std::set<Output*> subscribed;
  134. /** Not public. Use Driver::subscribeOutput(). */
  135. void subscribe(Output* output);
  136. /** Not public. Use Driver::unsubscribeOutput(). */
  137. void unsubscribe(Output* output);
  138. /** Sends a MIDI message to the device. */
  139. virtual void sendMessage(const Message &message) {}
  140. };
  141. ////////////////////
  142. // Port
  143. ////////////////////
  144. /** A handle to a Device, typically owned by modules to have shared access to a single Device.
  145. All Port methods safely wrap Drivers methods.
  146. 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.
  147. Use Input or Output subclasses in your module, not Port directly.
  148. */
  149. struct Port {
  150. /** For MIDI output, the channel to automatically set outbound messages.
  151. If -1, the channel is not overwritten and must be set by MIDI generator.
  152. For MIDI input, messages will be filtered by the channel.
  153. If -1, all MIDI channels pass through.
  154. */
  155. int channel = -1;
  156. // private
  157. int driverId = -1;
  158. int deviceId = -1;
  159. /** Not owned */
  160. Driver* driver = NULL;
  161. Device* device = NULL;
  162. Context* context;
  163. Port();
  164. virtual ~Port();
  165. Driver* getDriver();
  166. int getDriverId();
  167. void setDriverId(int driverId);
  168. Device* getDevice();
  169. virtual std::vector<int> getDeviceIds() = 0;
  170. int getDeviceId();
  171. virtual void setDeviceId(int deviceId) = 0;
  172. virtual std::string getDeviceName(int deviceId) = 0;
  173. virtual std::vector<int> getChannels() = 0;
  174. int getChannel();
  175. void setChannel(int channel);
  176. std::string getChannelName(int channel);
  177. json_t* toJson();
  178. void fromJson(json_t* rootJ);
  179. };
  180. struct Input : Port {
  181. /** Not owned */
  182. InputDevice* inputDevice = NULL;
  183. Input();
  184. ~Input();
  185. void reset();
  186. std::vector<int> getDeviceIds() override;
  187. void setDeviceId(int deviceId) override;
  188. std::string getDeviceName(int deviceId) override;
  189. std::vector<int> getChannels() override;
  190. virtual void onMessage(const Message &message) {}
  191. };
  192. struct InputQueue : Input {
  193. int queueMaxSize = 8192;
  194. std::queue<Message> queue;
  195. void onMessage(const Message &message) override;
  196. };
  197. struct Output : Port {
  198. /** Not owned */
  199. OutputDevice* outputDevice = NULL;
  200. Output();
  201. ~Output();
  202. void reset();
  203. std::vector<int> getDeviceIds() override;
  204. void setDeviceId(int deviceId) override;
  205. std::string getDeviceName(int deviceId) override;
  206. std::vector<int> getChannels() override;
  207. void sendMessage(const Message &message);
  208. };
  209. void init();
  210. void destroy();
  211. /** Registers a new MIDI driver. Takes pointer ownership. */
  212. void addDriver(int driverId, Driver* driver);
  213. std::vector<int> getDriverIds();
  214. Driver* getDriver(int driverId);
  215. } // namespace midi
  216. } // namespace rack