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.

106 lines
2.1KB

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