MIDIEvent.h
Go to the documentation of this file.
1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
2 
3 /*
4  Sonic Visualiser
5  An audio file viewer and annotation editor.
6  Centre for Digital Music, Queen Mary, University of London.
7 
8  This program is free software; you can redistribute it and/or
9  modify it under the terms of the GNU General Public License as
10  published by the Free Software Foundation; either version 2 of the
11  License, or (at your option) any later version. See the file
12  COPYING included with this distribution for more information.
13 */
14 
15 
16 /*
17  This is a modified version of a source file from the
18  Rosegarden MIDI and audio sequencer and notation editor.
19  This file copyright 2000-2006 Richard Bown and Chris Cannam.
20 */
21 
22 #ifndef SV_MIDI_EVENT_H
23 #define SV_MIDI_EVENT_H
24 
25 #include <QString>
26 #include <string>
27 #include <iostream>
28 #include <stdexcept>
29 
30 #include "base/Debug.h"
31 
32 typedef unsigned char MIDIByte;
33 
34 namespace MIDIConstants
35 {
36  static const char *const MIDI_FILE_HEADER = "MThd";
37  static const char *const MIDI_TRACK_HEADER = "MTrk";
38 
39  static const MIDIByte MIDI_STATUS_BYTE_MASK = 0x80;
40  static const MIDIByte MIDI_MESSAGE_TYPE_MASK = 0xF0;
41  static const MIDIByte MIDI_CHANNEL_NUM_MASK = 0x0F;
42 
43  static const MIDIByte MIDI_NOTE_OFF = 0x80;
44  static const MIDIByte MIDI_NOTE_ON = 0x90;
45  static const MIDIByte MIDI_POLY_AFTERTOUCH = 0xA0;
46  static const MIDIByte MIDI_CTRL_CHANGE = 0xB0;
47  static const MIDIByte MIDI_PROG_CHANGE = 0xC0;
48  static const MIDIByte MIDI_CHNL_AFTERTOUCH = 0xD0;
49  static const MIDIByte MIDI_PITCH_BEND = 0xE0;
50  static const MIDIByte MIDI_SELECT_CHNL_MODE = 0xB0;
51  static const MIDIByte MIDI_SYSTEM_EXCLUSIVE = 0xF0;
52  static const MIDIByte MIDI_TC_QUARTER_FRAME = 0xF1;
53  static const MIDIByte MIDI_SONG_POSITION_PTR = 0xF2;
54  static const MIDIByte MIDI_SONG_SELECT = 0xF3;
55  static const MIDIByte MIDI_TUNE_REQUEST = 0xF6;
56  static const MIDIByte MIDI_END_OF_EXCLUSIVE = 0xF7;
57  static const MIDIByte MIDI_TIMING_CLOCK = 0xF8;
58  static const MIDIByte MIDI_START = 0xFA;
59  static const MIDIByte MIDI_CONTINUE = 0xFB;
60  static const MIDIByte MIDI_STOP = 0xFC;
61  static const MIDIByte MIDI_ACTIVE_SENSING = 0xFE;
62  static const MIDIByte MIDI_SYSTEM_RESET = 0xFF;
63  static const MIDIByte MIDI_SYSEX_NONCOMMERCIAL = 0x7D;
64  static const MIDIByte MIDI_SYSEX_NON_RT = 0x7E;
65  static const MIDIByte MIDI_SYSEX_RT = 0x7F;
66  static const MIDIByte MIDI_SYSEX_RT_COMMAND = 0x06;
67  static const MIDIByte MIDI_SYSEX_RT_RESPONSE = 0x07;
68  static const MIDIByte MIDI_MMC_STOP = 0x01;
69  static const MIDIByte MIDI_MMC_PLAY = 0x02;
70  static const MIDIByte MIDI_MMC_DEFERRED_PLAY = 0x03;
71  static const MIDIByte MIDI_MMC_FAST_FORWARD = 0x04;
72  static const MIDIByte MIDI_MMC_REWIND = 0x05;
73  static const MIDIByte MIDI_MMC_RECORD_STROBE = 0x06;
74  static const MIDIByte MIDI_MMC_RECORD_EXIT = 0x07;
75  static const MIDIByte MIDI_MMC_RECORD_PAUSE = 0x08;
76  static const MIDIByte MIDI_MMC_PAUSE = 0x08;
77  static const MIDIByte MIDI_MMC_EJECT = 0x0A;
78  static const MIDIByte MIDI_MMC_LOCATE = 0x44;
79  static const MIDIByte MIDI_FILE_META_EVENT = 0xFF;
80  static const MIDIByte MIDI_SEQUENCE_NUMBER = 0x00;
81  static const MIDIByte MIDI_TEXT_EVENT = 0x01;
82  static const MIDIByte MIDI_COPYRIGHT_NOTICE = 0x02;
83  static const MIDIByte MIDI_TRACK_NAME = 0x03;
84  static const MIDIByte MIDI_INSTRUMENT_NAME = 0x04;
85  static const MIDIByte MIDI_LYRIC = 0x05;
86  static const MIDIByte MIDI_TEXT_MARKER = 0x06;
87  static const MIDIByte MIDI_CUE_POINT = 0x07;
88  static const MIDIByte MIDI_CHANNEL_PREFIX = 0x20;
90  static const MIDIByte MIDI_END_OF_TRACK = 0x2F;
91  static const MIDIByte MIDI_SET_TEMPO = 0x51;
92  static const MIDIByte MIDI_SMPTE_OFFSET = 0x54;
93  static const MIDIByte MIDI_TIME_SIGNATURE = 0x58;
94  static const MIDIByte MIDI_KEY_SIGNATURE = 0x59;
95  static const MIDIByte MIDI_SEQUENCER_SPECIFIC = 0x7F;
96  static const MIDIByte MIDI_CONTROLLER_BANK_MSB = 0x00;
97  static const MIDIByte MIDI_CONTROLLER_VOLUME = 0x07;
98  static const MIDIByte MIDI_CONTROLLER_BANK_LSB = 0x20;
99  static const MIDIByte MIDI_CONTROLLER_MODULATION = 0x01;
100  static const MIDIByte MIDI_CONTROLLER_PAN = 0x0A;
101  static const MIDIByte MIDI_CONTROLLER_SUSTAIN = 0x40;
102  static const MIDIByte MIDI_CONTROLLER_RESONANCE = 0x47;
103  static const MIDIByte MIDI_CONTROLLER_RELEASE = 0x48;
104  static const MIDIByte MIDI_CONTROLLER_ATTACK = 0x49;
105  static const MIDIByte MIDI_CONTROLLER_FILTER = 0x4A;
106  static const MIDIByte MIDI_CONTROLLER_REVERB = 0x5B;
107  static const MIDIByte MIDI_CONTROLLER_CHORUS = 0x5D;
108  static const MIDIByte MIDI_CONTROLLER_NRPN_1 = 0x62;
109  static const MIDIByte MIDI_CONTROLLER_NRPN_2 = 0x63;
110  static const MIDIByte MIDI_CONTROLLER_RPN_1 = 0x64;
111  static const MIDIByte MIDI_CONTROLLER_RPN_2 = 0x65;
113  static const MIDIByte MIDI_CONTROLLER_RESET = 0x79;
114  static const MIDIByte MIDI_CONTROLLER_LOCAL = 0x7A;
117 }
118 
120 {
121 public:
122  MIDIEvent(unsigned long deltaTime,
123  int eventCode,
124  int data1 = 0,
125  int data2 = 0) :
126  m_deltaTime(deltaTime),
127  m_duration(0),
128  m_metaEventCode(0)
129  {
130  if (eventCode < 0 || eventCode > 0xff ||
131  data1 < 0 || data1 > 0xff ||
132  data2 < 0 || data2 > 0xff) {
133  throw std::domain_error("not all args within byte range");
134  }
135  m_eventCode = MIDIByte(eventCode);
136  m_data1 = MIDIByte(data1);
137  m_data2 = MIDIByte(data2);
138  }
139 
140  MIDIEvent(unsigned long deltaTime,
141  MIDIByte eventCode,
142  MIDIByte metaEventCode,
143  const std::string &metaMessage) :
144  m_deltaTime(deltaTime),
145  m_duration(0),
146  m_eventCode(eventCode),
147  m_data1(0),
148  m_data2(0),
149  m_metaEventCode(metaEventCode),
150  m_metaMessage(metaMessage)
151  { }
152 
153  MIDIEvent(unsigned long deltaTime,
154  MIDIByte eventCode,
155  const std::string &sysEx) :
156  m_deltaTime(deltaTime),
157  m_duration(0),
158  m_eventCode(eventCode),
159  m_data1(0),
160  m_data2(0),
161  m_metaEventCode(0),
162  m_metaMessage(sysEx)
163  { }
164 
165  MIDIEvent(const MIDIEvent &) =default;
166  MIDIEvent& operator=(const MIDIEvent &) =default;
167 
169 
170  void setTime(const unsigned long &time) { m_deltaTime = time; }
171  void setDuration(const unsigned long& duration) { m_duration = duration;}
172  unsigned long addTime(const unsigned long &time) {
173  m_deltaTime += time;
174  return m_deltaTime;
175  }
176 
178  { return (m_eventCode & MIDIConstants::MIDI_MESSAGE_TYPE_MASK); }
179 
181  { return (m_eventCode & MIDIConstants::MIDI_CHANNEL_NUM_MASK); }
182 
183  unsigned long getTime() const { return m_deltaTime; }
184  unsigned long getDuration() const { return m_duration; }
185 
186  MIDIByte getPitch() const { return m_data1; }
187  MIDIByte getVelocity() const { return m_data2; }
188  MIDIByte getData1() const { return m_data1; }
189  MIDIByte getData2() const { return m_data2; }
190  MIDIByte getEventCode() const { return m_eventCode; }
191 
192  bool isMeta() const { return (m_eventCode == MIDIConstants::MIDI_FILE_META_EVENT); }
193 
194  MIDIByte getMetaEventCode() const { return m_metaEventCode; }
195  std::string getMetaMessage() const { return m_metaMessage; }
196  void setMetaMessage(const std::string &meta) { m_metaMessage = meta; }
197 
198  friend bool operator<(const MIDIEvent &a, const MIDIEvent &b);
199 
200 private:
201  unsigned long m_deltaTime;
202  unsigned long m_duration;
204  MIDIByte m_data1; // or Note
205  MIDIByte m_data2; // or Velocity
207  std::string m_metaMessage;
208 };
209 
210 // Comparator for sorting
211 //
213 {
214  bool operator()(const MIDIEvent &mE1, const MIDIEvent &mE2) const
215  { return mE1.getTime() < mE2.getTime(); }
216 
217  bool operator()(const MIDIEvent *mE1, const MIDIEvent *mE2) const
218  { return mE1->getTime() < mE2->getTime(); }
219 };
220 
221 class MIDIException : virtual public std::exception
222 {
223 public:
224  MIDIException(QString message) throw() : m_message(message) {
225  std::cerr << "WARNING: MIDI exception: "
226  << message.toLocal8Bit().data() << std::endl;
227  }
228  virtual ~MIDIException() throw() { }
229 
230  const char *what() const throw() override {
231  static QByteArray msg;
232  msg = m_message.toLocal8Bit();
233  return msg.data();
234  }
235 
236 protected:
237  QString m_message;
238 };
239 
240 #endif
static const MIDIByte MIDI_KEY_SIGNATURE
Definition: MIDIEvent.h:94
static const MIDIByte MIDI_MMC_PLAY
Definition: MIDIEvent.h:69
static const MIDIByte MIDI_CHANNEL_PREFIX_OR_PORT
Definition: MIDIEvent.h:89
static const MIDIByte MIDI_END_OF_TRACK
Definition: MIDIEvent.h:90
static const MIDIByte MIDI_CONTROLLER_FILTER
Definition: MIDIEvent.h:105
static const MIDIByte MIDI_CONTROLLER_RPN_2
Definition: MIDIEvent.h:111
static const MIDIByte MIDI_COPYRIGHT_NOTICE
Definition: MIDIEvent.h:82
void setDuration(const unsigned long &duration)
Definition: MIDIEvent.h:171
MIDIByte m_data1
Definition: MIDIEvent.h:204
static const MIDIByte MIDI_CONTROLLER_RESET
Definition: MIDIEvent.h:113
unsigned long m_deltaTime
Definition: MIDIEvent.h:201
static const MIDIByte MIDI_CHANNEL_PREFIX
Definition: MIDIEvent.h:88
static const MIDIByte MIDI_MMC_RECORD_STROBE
Definition: MIDIEvent.h:73
static const MIDIByte MIDI_SYSEX_RT
Definition: MIDIEvent.h:65
static const MIDIByte MIDI_CHANNEL_NUM_MASK
Definition: MIDIEvent.h:41
static const MIDIByte MIDI_TUNE_REQUEST
Definition: MIDIEvent.h:55
~MIDIEvent()
Definition: MIDIEvent.h:168
static const MIDIByte MIDI_CONTROLLER_MODULATION
Definition: MIDIEvent.h:99
static const MIDIByte MIDI_TC_QUARTER_FRAME
Definition: MIDIEvent.h:52
MIDIByte getMessageType() const
Definition: MIDIEvent.h:177
static const char *const MIDI_TRACK_HEADER
Definition: MIDIEvent.h:37
static const MIDIByte MIDI_SONG_SELECT
Definition: MIDIEvent.h:54
static const MIDIByte MIDI_CONTROLLER_NRPN_2
Definition: MIDIEvent.h:109
MIDIByte getVelocity() const
Definition: MIDIEvent.h:187
static const MIDIByte MIDI_TRACK_NAME
Definition: MIDIEvent.h:83
static const MIDIByte MIDI_MMC_DEFERRED_PLAY
Definition: MIDIEvent.h:70
MIDIByte getEventCode() const
Definition: MIDIEvent.h:190
static const MIDIByte MIDI_TEXT_MARKER
Definition: MIDIEvent.h:86
void setTime(const unsigned long &time)
Definition: MIDIEvent.h:170
static const MIDIByte MIDI_CONTROLLER_ATTACK
Definition: MIDIEvent.h:104
static const MIDIByte MIDI_SELECT_CHNL_MODE
Definition: MIDIEvent.h:50
static const MIDIByte MIDI_SEQUENCE_NUMBER
Definition: MIDIEvent.h:80
static const MIDIByte MIDI_MMC_EJECT
Definition: MIDIEvent.h:77
static const MIDIByte MIDI_MMC_STOP
Definition: MIDIEvent.h:68
MIDIByte getChannelNumber() const
Definition: MIDIEvent.h:180
unsigned long getDuration() const
Definition: MIDIEvent.h:184
static const MIDIByte MIDI_TEXT_EVENT
Definition: MIDIEvent.h:81
static const MIDIByte MIDI_CONTROLLER_BANK_LSB
Definition: MIDIEvent.h:98
static const MIDIByte MIDI_MMC_RECORD_PAUSE
Definition: MIDIEvent.h:75
MIDIByte m_eventCode
Definition: MIDIEvent.h:203
MIDIEvent(unsigned long deltaTime, MIDIByte eventCode, MIDIByte metaEventCode, const std::string &metaMessage)
Definition: MIDIEvent.h:140
static const MIDIByte MIDI_SMPTE_OFFSET
Definition: MIDIEvent.h:92
static const MIDIByte MIDI_PERCUSSION_CHANNEL
Definition: MIDIEvent.h:116
MIDIByte getData2() const
Definition: MIDIEvent.h:189
unsigned char MIDIByte
Definition: MIDIEvent.h:32
static const MIDIByte MIDI_MMC_REWIND
Definition: MIDIEvent.h:72
static const MIDIByte MIDI_CONTROLLER_NRPN_1
Definition: MIDIEvent.h:108
static const MIDIByte MIDI_LYRIC
Definition: MIDIEvent.h:85
static const MIDIByte MIDI_SYSEX_RT_COMMAND
Definition: MIDIEvent.h:66
static const MIDIByte MIDI_CUE_POINT
Definition: MIDIEvent.h:87
static const MIDIByte MIDI_FILE_META_EVENT
Definition: MIDIEvent.h:79
MIDIEvent(unsigned long deltaTime, MIDIByte eventCode, const std::string &sysEx)
Definition: MIDIEvent.h:153
static const MIDIByte MIDI_SET_TEMPO
Definition: MIDIEvent.h:91
static const MIDIByte MIDI_SYSEX_NON_RT
Definition: MIDIEvent.h:64
static const MIDIByte MIDI_CONTROLLER_ALL_NOTES_OFF
Definition: MIDIEvent.h:115
static const MIDIByte MIDI_CONTROLLER_RPN_1
Definition: MIDIEvent.h:110
unsigned long m_duration
Definition: MIDIEvent.h:202
static const MIDIByte MIDI_INSTRUMENT_NAME
Definition: MIDIEvent.h:84
static const MIDIByte MIDI_CONTROLLER_RESONANCE
Definition: MIDIEvent.h:102
static const MIDIByte MIDI_SEQUENCER_SPECIFIC
Definition: MIDIEvent.h:95
static const MIDIByte MIDI_STATUS_BYTE_MASK
Definition: MIDIEvent.h:39
bool isMeta() const
Definition: MIDIEvent.h:192
static const MIDIByte MIDI_STOP
Definition: MIDIEvent.h:60
static const MIDIByte MIDI_TIMING_CLOCK
Definition: MIDIEvent.h:57
std::string getMetaMessage() const
Definition: MIDIEvent.h:195
static const MIDIByte MIDI_CONTROLLER_SOUNDS_OFF
Definition: MIDIEvent.h:112
static const MIDIByte MIDI_ACTIVE_SENSING
Definition: MIDIEvent.h:61
static const MIDIByte MIDI_PITCH_BEND
Definition: MIDIEvent.h:49
static const MIDIByte MIDI_MMC_RECORD_EXIT
Definition: MIDIEvent.h:74
static const MIDIByte MIDI_MMC_PAUSE
Definition: MIDIEvent.h:76
std::string m_metaMessage
Definition: MIDIEvent.h:207
MIDIException(QString message)
Definition: MIDIEvent.h:224
virtual ~MIDIException()
Definition: MIDIEvent.h:228
MIDIByte m_metaEventCode
Definition: MIDIEvent.h:206
static const MIDIByte MIDI_CONTROLLER_RELEASE
Definition: MIDIEvent.h:103
MIDIByte getMetaEventCode() const
Definition: MIDIEvent.h:194
MIDIByte getData1() const
Definition: MIDIEvent.h:188
static const MIDIByte MIDI_START
Definition: MIDIEvent.h:58
static const MIDIByte MIDI_MMC_LOCATE
Definition: MIDIEvent.h:78
static const MIDIByte MIDI_MMC_FAST_FORWARD
Definition: MIDIEvent.h:71
static const MIDIByte MIDI_CTRL_CHANGE
Definition: MIDIEvent.h:46
static const MIDIByte MIDI_CONTROLLER_REVERB
Definition: MIDIEvent.h:106
static const MIDIByte MIDI_POLY_AFTERTOUCH
Definition: MIDIEvent.h:45
static const MIDIByte MIDI_SYSTEM_EXCLUSIVE
Definition: MIDIEvent.h:51
static const MIDIByte MIDI_CONTROLLER_LOCAL
Definition: MIDIEvent.h:114
static const MIDIByte MIDI_NOTE_OFF
Definition: MIDIEvent.h:43
static const char *const MIDI_FILE_HEADER
Definition: MIDIEvent.h:36
static const MIDIByte MIDI_PROG_CHANGE
Definition: MIDIEvent.h:47
static const MIDIByte MIDI_SYSTEM_RESET
Definition: MIDIEvent.h:62
static const MIDIByte MIDI_SYSEX_RT_RESPONSE
Definition: MIDIEvent.h:67
bool operator()(const MIDIEvent *mE1, const MIDIEvent *mE2) const
Definition: MIDIEvent.h:217
static const MIDIByte MIDI_TIME_SIGNATURE
Definition: MIDIEvent.h:93
static const MIDIByte MIDI_SONG_POSITION_PTR
Definition: MIDIEvent.h:53
static const MIDIByte MIDI_CONTINUE
Definition: MIDIEvent.h:59
unsigned long getTime() const
Definition: MIDIEvent.h:183
static const MIDIByte MIDI_SYSEX_NONCOMMERCIAL
Definition: MIDIEvent.h:63
MIDIByte m_data2
Definition: MIDIEvent.h:205
static const MIDIByte MIDI_MESSAGE_TYPE_MASK
Definition: MIDIEvent.h:40
void setMetaMessage(const std::string &meta)
Definition: MIDIEvent.h:196
MIDIByte getPitch() const
Definition: MIDIEvent.h:186
static const MIDIByte MIDI_NOTE_ON
Definition: MIDIEvent.h:44
static const MIDIByte MIDI_CONTROLLER_VOLUME
Definition: MIDIEvent.h:97
MIDIEvent(unsigned long deltaTime, int eventCode, int data1=0, int data2=0)
Definition: MIDIEvent.h:122
unsigned char MIDIByte
static const MIDIByte MIDI_CONTROLLER_SUSTAIN
Definition: MIDIEvent.h:101
bool operator()(const MIDIEvent &mE1, const MIDIEvent &mE2) const
Definition: MIDIEvent.h:214
static const MIDIByte MIDI_END_OF_EXCLUSIVE
Definition: MIDIEvent.h:56
static const MIDIByte MIDI_CHNL_AFTERTOUCH
Definition: MIDIEvent.h:48
const char * what() const override
Definition: MIDIEvent.h:230
static const MIDIByte MIDI_CONTROLLER_PAN
Definition: MIDIEvent.h:100
unsigned long addTime(const unsigned long &time)
Definition: MIDIEvent.h:172
static const MIDIByte MIDI_CONTROLLER_BANK_MSB
Definition: MIDIEvent.h:96
static const MIDIByte MIDI_CONTROLLER_CHORUS
Definition: MIDIEvent.h:107
QString m_message
Definition: MIDIEvent.h:237