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.

120 lines
2.3KB

  1. #include "midi.hpp"
  2. namespace rack {
  3. ////////////////////
  4. // MidiIO
  5. ////////////////////
  6. int MidiIO::getDeviceCount() {
  7. if (rtMidi)
  8. return rtMidi->getPortCount();
  9. return 0;
  10. }
  11. std::string MidiIO::getDeviceName(int device) {
  12. if (rtMidi) {
  13. if (device < 0)
  14. return "";
  15. return rtMidi->getPortName(device);
  16. }
  17. return "";
  18. }
  19. void MidiIO::openDevice(int device) {
  20. if (rtMidi) {
  21. rtMidi->closePort();
  22. if (device >= 0) {
  23. rtMidi->openPort(device);
  24. }
  25. this->device = device;
  26. }
  27. }
  28. bool MidiIO::isActive() {
  29. if (rtMidi)
  30. return rtMidi->isPortOpen();
  31. return false;
  32. }
  33. json_t *MidiIO::toJson() {
  34. json_t *rootJ = json_object();
  35. std::string deviceName = getDeviceName(device);
  36. json_object_set_new(rootJ, "deviceName", json_string(deviceName.c_str()));
  37. json_object_set_new(rootJ, "channel", json_integer(channel));
  38. return rootJ;
  39. }
  40. void MidiIO::fromJson(json_t *rootJ) {
  41. json_t *deviceNameJ = json_object_get(rootJ, "deviceName");
  42. if (deviceNameJ) {
  43. std::string deviceName = json_string_value(deviceNameJ);
  44. // Search for device with equal name
  45. for (int device = 0; device < getDeviceCount(); device++) {
  46. if (getDeviceName(device) == deviceName) {
  47. openDevice(device);
  48. break;
  49. }
  50. }
  51. }
  52. json_t *channelJ = json_object_get(rootJ, "channel");
  53. if (channelJ)
  54. channel = json_integer_value(channelJ);
  55. }
  56. ////////////////////
  57. // MidiInput
  58. ////////////////////
  59. static void midiInputCallback(double timeStamp, std::vector<unsigned char> *message, void *userData) {
  60. if (!message) return;
  61. if (!userData) return;
  62. MidiInput *midiInput = (MidiInput*) userData;
  63. if (!midiInput) return;
  64. MidiMessage midiMessage;
  65. midiMessage.time = timeStamp;
  66. midiMessage.data = *message;
  67. midiInput->onMessage(midiMessage);
  68. }
  69. MidiInput::MidiInput() {
  70. rtMidiIn = new RtMidiIn();
  71. rtMidi = rtMidiIn;
  72. rtMidiIn->setCallback(midiInputCallback, this);
  73. }
  74. MidiInput::~MidiInput() {
  75. delete rtMidiIn;
  76. }
  77. void MidiInputQueue::onMessage(const MidiMessage &message) {
  78. for (uint8_t d : message.data) {
  79. debug("MIDI message: %02x", d);
  80. }
  81. const int messageQueueSize = 8192;
  82. if (messageQueue.size() < messageQueueSize)
  83. messageQueue.push(message);
  84. }
  85. ////////////////////
  86. // MidiOutput
  87. ////////////////////
  88. MidiOutput::MidiOutput() {
  89. rtMidiOut = new RtMidiOut();
  90. rtMidi = rtMidiOut;
  91. }
  92. MidiOutput::~MidiOutput() {
  93. delete rtMidiOut;
  94. }
  95. } // namespace rack