#pragma once #include class MidiMessage { public: static MidiMessage* parseMessage(std::vector &messageBytes); virtual void print(std::ostream& stream) const = 0; }; std::ostream& operator<<(std::ostream& stream, const MidiMessage& message); class ChannelMessage : public MidiMessage { public: unsigned char channel; ChannelMessage(unsigned char channel) : channel(channel) { } }; class NoteMessage : public ChannelMessage { public: unsigned char pitch; unsigned char velocity; NoteMessage(unsigned char channel, unsigned char pitch, unsigned char velocity) : ChannelMessage(channel), pitch(pitch), velocity(velocity) { } }; class NoteOnMessage : public NoteMessage { public: NoteOnMessage(unsigned char channel, unsigned char pitch, unsigned char velocity) : NoteMessage(channel, pitch, velocity) { } virtual void print(std::ostream& stream) const; }; class NoteOffMessage : public NoteMessage { public: NoteOffMessage(unsigned char channel, unsigned char pitch, unsigned char velocity) : NoteMessage(channel, pitch, velocity) { } virtual void print(std::ostream& stream) const; }; class ControlChangeMessage : public ChannelMessage { public: unsigned char control; unsigned char value; ControlChangeMessage(unsigned char channel, unsigned char control, unsigned char value) : ChannelMessage(channel), control(control), value(value) { } virtual void print(std::ostream& stream) const; }; class ProgramChangeMessage : public ChannelMessage { public: unsigned char program; ProgramChangeMessage(unsigned char channel, unsigned char program) : ChannelMessage(channel), program(program) { } virtual void print(std::ostream& stream) const; }; class PitchBendChangeMessage : public ChannelMessage { public: uint16_t value; PitchBendChangeMessage(unsigned char channel, uint16_t value) : ChannelMessage(channel), value(value) { } virtual void print(std::ostream& stream) const; };