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.

137 lines
2.9KB

  1. #pragma once
  2. #include "util/common.hpp"
  3. #include <vector>
  4. #include <queue>
  5. #include <set>
  6. #include <jansson.h>
  7. namespace rack {
  8. struct MidiMessage {
  9. uint8_t cmd = 0x00;
  10. uint8_t data1 = 0x00;
  11. uint8_t data2 = 0x00;
  12. uint8_t channel() {
  13. return cmd & 0xf;
  14. }
  15. uint8_t status() {
  16. return (cmd >> 4) & 0xf;
  17. }
  18. uint8_t note() {
  19. return data1 & 0x7f;
  20. }
  21. uint8_t value() {
  22. return data2 & 0x7f;
  23. }
  24. };
  25. ////////////////////
  26. // MidiDevice
  27. ////////////////////
  28. struct MidiDevice {
  29. virtual ~MidiDevice() {}
  30. };
  31. struct MidiInput;
  32. struct MidiInputDevice : MidiDevice {
  33. std::set<MidiInput*> subscribed;
  34. void subscribe(MidiInput *midiInput);
  35. void unsubscribe(MidiInput *midiInput);
  36. void onMessage(MidiMessage message);
  37. };
  38. struct MidiOutputDevice : MidiDevice {
  39. // TODO
  40. };
  41. ////////////////////
  42. // MidiDriver
  43. ////////////////////
  44. struct MidiDriver {
  45. virtual ~MidiDriver() {}
  46. virtual std::string getName() {return "";}
  47. virtual std::vector<int> getInputDeviceIds() {return {};}
  48. virtual std::string getInputDeviceName(int deviceId) {return "";}
  49. virtual MidiInputDevice *subscribeInputDevice(int deviceId, MidiInput *midiInput) {return NULL;}
  50. virtual void unsubscribeInputDevice(int deviceId, MidiInput *midiInput) {}
  51. // virtual std::vector<int> getOutputDeviceIds() = 0;
  52. // virtual std::string getOutputDeviceName(int deviceId) = 0;
  53. // virtual MidiOutputDevice *subscribeOutputDevice(int deviceId, MidiOutput *midiOutput) = 0;
  54. // virtual void unsubscribeOutputDevice(int deviceId, MidiOutput *midiOutput) = 0;
  55. };
  56. ////////////////////
  57. // MidiIO
  58. ////////////////////
  59. struct MidiIO {
  60. int driverId = -1;
  61. int deviceId = -1;
  62. /* For MIDI output, the channel to output messages.
  63. For MIDI input, the channel to filter.
  64. Set to -1 to allow all MIDI channels (for input).
  65. Zero indexed.
  66. */
  67. int channel = -1;
  68. /** Not owned */
  69. MidiDriver *driver = NULL;
  70. virtual ~MidiIO();
  71. std::vector<int> getDriverIds();
  72. std::string getDriverName(int driverId);
  73. void setDriverId(int driverId);
  74. virtual std::vector<int> getDeviceIds() = 0;
  75. virtual std::string getDeviceName(int deviceId) = 0;
  76. virtual void setDeviceId(int deviceId) = 0;
  77. std::string getChannelName(int channel);
  78. json_t *toJson();
  79. void fromJson(json_t *rootJ);
  80. };
  81. struct MidiInput : MidiIO {
  82. MidiInput();
  83. ~MidiInput();
  84. std::vector<int> getDeviceIds() override;
  85. std::string getDeviceName(int deviceId) override;
  86. void setDeviceId(int deviceId) override;
  87. virtual void onMessage(MidiMessage message) {}
  88. };
  89. struct MidiInputQueue : MidiInput {
  90. int queueMaxSize = 8192;
  91. std::queue<MidiMessage> queue;
  92. void onMessage(MidiMessage message) override;
  93. /** If a MidiMessage is available, writes `message` and return true */
  94. bool shift(MidiMessage *message);
  95. };
  96. struct MidiOutput : MidiIO {
  97. MidiOutput();
  98. ~MidiOutput();
  99. void setDeviceId(int deviceId) override;
  100. };
  101. void midiDestroy();
  102. /** Registers a new MIDI driver. Takes pointer ownership. */
  103. void midiDriverAdd(int driverId, MidiDriver *driver);
  104. } // namespace rack