1
1

midi.h 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107
  1. #pragma once
  2. #pragma comment(lib, "Winmm.lib")
  3. //========================================================================================================================
  4. //========================================================================================================================
  5. // Midi
  6. //========================================================================================================================
  7. //========================================================================================================================
  8. class Midi
  9. {
  10. public:
  11. Midi(void);
  12. ~Midi(void);
  13. };
  14. //========================================================================================================================
  15. //========================================================================================================================
  16. // MidiIn
  17. //========================================================================================================================
  18. //========================================================================================================================
  19. class MidiIn : public Midi
  20. {
  21. };
  22. //========================================================================================================================
  23. //========================================================================================================================
  24. // MidiOut
  25. //========================================================================================================================
  26. //========================================================================================================================
  27. class MidiOut : public Midi
  28. {
  29. public:
  30. static std::vector<std::wstring> list()
  31. {
  32. std::vector<std::wstring> midiOutPortNames;
  33. auto midiOutPortCnt = ::midiOutGetNumDevs();
  34. for(unsigned int port = 0; port < midiOutPortCnt; ++port) {
  35. MIDIOUTCAPS deviceCaps;
  36. ::midiOutGetDevCaps(port, &deviceCaps, sizeof(MIDIOUTCAPS));
  37. midiOutPortNames.push_back(deviceCaps.szPname);
  38. }
  39. return midiOutPortNames;
  40. }
  41. private:
  42. HMIDIOUT _handle;
  43. public:
  44. MidiOut(unsigned int portNumber)
  45. {
  46. if(::midiOutOpen(&_handle, portNumber, (DWORD)NULL, (DWORD)NULL, CALLBACK_NULL) != MMSYSERR_NOERROR) {
  47. throw std::exception("error opening midi out port");
  48. }
  49. }
  50. ~MidiOut()
  51. {
  52. ::midiOutReset(_handle);
  53. ::midiOutClose(_handle);
  54. }
  55. void send(const std::vector<byte>& message)
  56. {
  57. if(message.empty()) {
  58. return;
  59. }
  60. if(message[0] == 0xF0) {
  61. MIDIHDR sysex;
  62. sysex.lpData = (LPSTR)message.data();
  63. sysex.dwBufferLength = message.size();
  64. sysex.dwFlags = 0;
  65. if(midiOutPrepareHeader(_handle, &sysex, sizeof(MIDIHDR)) != MMSYSERR_NOERROR) {
  66. throw std::exception("error midiOutPrepareHeader");
  67. }
  68. if(midiOutLongMsg(_handle, &sysex, sizeof(MIDIHDR)) != MMSYSERR_NOERROR) {
  69. throw std::exception("error midiOutLongMsg");
  70. }
  71. while(MIDIERR_STILLPLAYING == midiOutUnprepareHeader(_handle, &sysex, sizeof(MIDIHDR))) {
  72. Sleep(1);
  73. }
  74. }
  75. else {
  76. if(message.size() > 3) {
  77. throw std::exception("invalid message. not a sysex and too big for normal");
  78. }
  79. //DWORD packet = MAKELONG(MAKEWORD(message[0], message[1]), MAKEWORD(message[2], 0));
  80. if(midiOutShortMsg(_handle, *reinterpret_cast<const DWORD*>(message.data())) != MMSYSERR_NOERROR) {
  81. throw std::exception("error midiOutShortMsg");
  82. }
  83. }
  84. }
  85. };