MidiMessage.cpp 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192
  1. #include <vector>
  2. #include "RtMidi.h" // RtMidiError
  3. #include "MidiMessage.h"
  4. MidiMessage* MidiMessage::parseMessage(std::vector<unsigned char> &messageBytes)
  5. {
  6. // msg[0] has 8 bits
  7. // - 4 higher significant bits: message type
  8. // - 4 lower significant bits: channel (0 - 15)
  9. unsigned char messageType = messageBytes[0] >> 4;
  10. if(messageType == 0xF)
  11. {
  12. // system message
  13. throw RtMidiError("MidiMessage::parseMessage() does not support system messages yet.", RtMidiError::DEBUG_WARNING);
  14. }
  15. else
  16. {
  17. // channel message
  18. unsigned char channel = messageBytes[0] & 0xF;
  19. switch(messageType)
  20. {
  21. case 0x8:
  22. case 0x9:
  23. {
  24. unsigned char pitch = messageBytes[1];
  25. unsigned char velocity = messageBytes[2];
  26. if(messageType == 0x8 || velocity == 0)
  27. {
  28. return new NoteOffMessage(channel, pitch, velocity);
  29. }
  30. else
  31. {
  32. return new NoteOnMessage(channel, pitch, velocity);
  33. }
  34. }
  35. case 0xB:
  36. return new ControlChangeMessage(channel, messageBytes[1], messageBytes[2]);
  37. case 0xC:
  38. return new ProgramChangeMessage(channel, messageBytes[1]);
  39. case 0xE:
  40. // messageBytes[1] are the least significant 7 bits.
  41. // messageBytes[2] are the most significant 7 bits.
  42. return new PitchBendChangeMessage(
  43. channel,
  44. (messageBytes[2] << 7) + messageBytes[1]
  45. );
  46. default:
  47. throw RtMidiError(
  48. "MidiMessage::parseMessage() does not support the given type of channel message yet.",
  49. RtMidiError::DEBUG_WARNING
  50. );
  51. }
  52. }
  53. }
  54. std::ostream& operator<<(std::ostream& stream, const MidiMessage& message)
  55. {
  56. message.print(stream);
  57. return stream;
  58. }
  59. void NoteOnMessage::print(std::ostream& stream) const
  60. {
  61. stream << "channel #" << (unsigned short)(channel + 1) << ": "
  62. << "note " << (unsigned short)pitch << " with velocity " << (unsigned short)velocity << " on\n";
  63. }
  64. void NoteOffMessage::print(std::ostream& stream) const
  65. {
  66. stream << "channel #" << (unsigned short)(channel + 1) << ": "
  67. << "note " << (unsigned short)pitch << " off\n";
  68. }
  69. void ControlChangeMessage::print(std::ostream& stream) const
  70. {
  71. stream << "channel #" << (unsigned short)(channel + 1) << ": "
  72. << "change value of control #" << (unsigned short)(control + 1)
  73. << " to " << (unsigned short)value << "\n";
  74. }
  75. void ProgramChangeMessage::print(std::ostream& stream) const
  76. {
  77. stream << "channel #" << (unsigned short)(channel + 1) << ": "
  78. << "switch to program # " << (unsigned short)(program + 1) << "\n";
  79. }
  80. void PitchBendChangeMessage::print(std::ostream& stream) const
  81. {
  82. stream << "channel #" << (unsigned short)(channel + 1) << ": "
  83. << "pitch bended to " << value << "\n";
  84. }