/
MIDIEvent.h
244 lines (212 loc) · 9.75 KB
/
MIDIEvent.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
/* Source taken from https://code.soundsoftware.ac.uk/projects/midifile/repository */
/*
This is a modified version of a source file from the
Rosegarden MIDI and audio sequencer and notation editor.
This file copyright 2000-2010 Richard Bown and Chris Cannam.
Permission is hereby granted, free of charge, to any person
obtaining a copy of this software and associated documentation
files (the "Software"), to deal in the Software without
restriction, including without limitation the rights to use, copy,
modify, merge, publish, distribute, sublicense, and/or sell copies
of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR
ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
Except as contained in this notice, the names of the authors
shall not be used in advertising or otherwise to promote the sale,
use or other dealings in this Software without prior written
authorization.
*/
#ifndef _MIDI_EVENT_H_
#define _MIDI_EVENT_H_
#include <string>
#include <iostream>
typedef unsigned char MIDIByte;
namespace MIDIConstants
{
static const char *const MIDI_FILE_HEADER = "MThd";
static const char *const MIDI_TRACK_HEADER = "MTrk";
static const MIDIByte MIDI_STATUS_BYTE_MASK = 0x80;
static const MIDIByte MIDI_MESSAGE_TYPE_MASK = 0xF0;
static const MIDIByte MIDI_CHANNEL_NUM_MASK = 0x0F;
static const MIDIByte MIDI_NOTE_OFF = 0x80;
static const MIDIByte MIDI_NOTE_ON = 0x90;
static const MIDIByte MIDI_POLY_AFTERTOUCH = 0xA0;
static const MIDIByte MIDI_CTRL_CHANGE = 0xB0;
static const MIDIByte MIDI_PROG_CHANGE = 0xC0;
static const MIDIByte MIDI_CHNL_AFTERTOUCH = 0xD0;
static const MIDIByte MIDI_PITCH_BEND = 0xE0;
static const MIDIByte MIDI_SELECT_CHNL_MODE = 0xB0;
static const MIDIByte MIDI_SYSTEM_EXCLUSIVE = 0xF0;
static const MIDIByte MIDI_TC_QUARTER_FRAME = 0xF1;
static const MIDIByte MIDI_SONG_POSITION_PTR = 0xF2;
static const MIDIByte MIDI_SONG_SELECT = 0xF3;
static const MIDIByte MIDI_TUNE_REQUEST = 0xF6;
static const MIDIByte MIDI_END_OF_EXCLUSIVE = 0xF7;
static const MIDIByte MIDI_TIMING_CLOCK = 0xF8;
static const MIDIByte MIDI_START = 0xFA;
static const MIDIByte MIDI_CONTINUE = 0xFB;
static const MIDIByte MIDI_STOP = 0xFC;
static const MIDIByte MIDI_ACTIVE_SENSING = 0xFE;
static const MIDIByte MIDI_SYSTEM_RESET = 0xFF;
static const MIDIByte MIDI_SYSEX_NONCOMMERCIAL = 0x7D;
static const MIDIByte MIDI_SYSEX_NON_RT = 0x7E;
static const MIDIByte MIDI_SYSEX_RT = 0x7F;
static const MIDIByte MIDI_SYSEX_RT_COMMAND = 0x06;
static const MIDIByte MIDI_SYSEX_RT_RESPONSE = 0x07;
static const MIDIByte MIDI_MMC_STOP = 0x01;
static const MIDIByte MIDI_MMC_PLAY = 0x02;
static const MIDIByte MIDI_MMC_DEFERRED_PLAY = 0x03;
static const MIDIByte MIDI_MMC_FAST_FORWARD = 0x04;
static const MIDIByte MIDI_MMC_REWIND = 0x05;
static const MIDIByte MIDI_MMC_RECORD_STROBE = 0x06;
static const MIDIByte MIDI_MMC_RECORD_EXIT = 0x07;
static const MIDIByte MIDI_MMC_RECORD_PAUSE = 0x08;
static const MIDIByte MIDI_MMC_PAUSE = 0x08;
static const MIDIByte MIDI_MMC_EJECT = 0x0A;
static const MIDIByte MIDI_MMC_LOCATE = 0x44;
static const MIDIByte MIDI_FILE_META_EVENT = 0xFF;
static const MIDIByte MIDI_SEQUENCE_NUMBER = 0x00;
static const MIDIByte MIDI_TEXT_EVENT = 0x01;
static const MIDIByte MIDI_COPYRIGHT_NOTICE = 0x02;
static const MIDIByte MIDI_TRACK_NAME = 0x03;
static const MIDIByte MIDI_INSTRUMENT_NAME = 0x04;
static const MIDIByte MIDI_LYRIC = 0x05;
static const MIDIByte MIDI_TEXT_MARKER = 0x06;
static const MIDIByte MIDI_CUE_POINT = 0x07;
static const MIDIByte MIDI_CHANNEL_PREFIX = 0x20;
static const MIDIByte MIDI_CHANNEL_PREFIX_OR_PORT = 0x21;
static const MIDIByte MIDI_END_OF_TRACK = 0x2F;
static const MIDIByte MIDI_SET_TEMPO = 0x51;
static const MIDIByte MIDI_SMPTE_OFFSET = 0x54;
static const MIDIByte MIDI_TIME_SIGNATURE = 0x58;
static const MIDIByte MIDI_KEY_SIGNATURE = 0x59;
static const MIDIByte MIDI_SEQUENCER_SPECIFIC = 0x7F;
static const MIDIByte MIDI_CONTROLLER_BANK_MSB = 0x00;
static const MIDIByte MIDI_CONTROLLER_VOLUME = 0x07;
static const MIDIByte MIDI_CONTROLLER_BANK_LSB = 0x20;
static const MIDIByte MIDI_CONTROLLER_MODULATION = 0x01;
static const MIDIByte MIDI_CONTROLLER_PAN = 0x0A;
static const MIDIByte MIDI_CONTROLLER_SUSTAIN = 0x40;
static const MIDIByte MIDI_CONTROLLER_RESONANCE = 0x47;
static const MIDIByte MIDI_CONTROLLER_RELEASE = 0x48;
static const MIDIByte MIDI_CONTROLLER_ATTACK = 0x49;
static const MIDIByte MIDI_CONTROLLER_FILTER = 0x4A;
static const MIDIByte MIDI_CONTROLLER_REVERB = 0x5B;
static const MIDIByte MIDI_CONTROLLER_CHORUS = 0x5D;
static const MIDIByte MIDI_CONTROLLER_NRPN_1 = 0x62;
static const MIDIByte MIDI_CONTROLLER_NRPN_2 = 0x63;
static const MIDIByte MIDI_CONTROLLER_RPN_1 = 0x64;
static const MIDIByte MIDI_CONTROLLER_RPN_2 = 0x65;
static const MIDIByte MIDI_CONTROLLER_SOUNDS_OFF = 0x78;
static const MIDIByte MIDI_CONTROLLER_RESET = 0x79;
static const MIDIByte MIDI_CONTROLLER_LOCAL = 0x7A;
static const MIDIByte MIDI_CONTROLLER_ALL_NOTES_OFF = 0x7B;
static const MIDIByte MIDI_PERCUSSION_CHANNEL = 9;
typedef enum {
MIDI_SINGLE_TRACK_FILE = 0x00,
MIDI_SIMULTANEOUS_TRACK_FILE = 0x01,
MIDI_SEQUENTIAL_TRACK_FILE = 0x02,
MIDI_FILE_BAD_FORMAT = 0xFF
} MIDIFileFormatType;
}
class MIDIEvent
{
public:
MIDIEvent(unsigned long deltaTime,
MIDIByte eventCode,
MIDIByte data1 = 0,
MIDIByte data2 = 0) :
m_deltaTime(deltaTime),
m_duration(0),
m_eventCode(eventCode),
m_data1(data1),
m_data2(data2),
m_metaEventCode(0)
{ }
MIDIEvent(unsigned long deltaTime,
MIDIByte eventCode,
MIDIByte metaEventCode,
const std::string &metaMessage) :
m_deltaTime(deltaTime),
m_duration(0),
m_eventCode(eventCode),
m_data1(0),
m_data2(0),
m_metaEventCode(metaEventCode),
m_metaMessage(metaMessage)
{ }
MIDIEvent(unsigned long deltaTime,
MIDIByte eventCode,
const std::string &sysEx) :
m_deltaTime(deltaTime),
m_duration(0),
m_eventCode(eventCode),
m_data1(0),
m_data2(0),
m_metaEventCode(0),
m_metaMessage(sysEx)
{ }
~MIDIEvent() { }
void setTime(const unsigned long &time) { m_deltaTime = time; }
void setDuration(const unsigned long& duration) { m_duration = duration;}
unsigned long addTime(const unsigned long &time) {
m_deltaTime += time;
return m_deltaTime;
}
int getMessageType() const
{ return (m_eventCode & MIDIConstants::MIDI_MESSAGE_TYPE_MASK); }
int getChannelNumber() const
{ return (m_eventCode & MIDIConstants::MIDI_CHANNEL_NUM_MASK); }
unsigned long getTime() const { return m_deltaTime; }
unsigned long getDuration() const { return m_duration; }
int getPitch() const { return m_data1; }
int getVelocity() const { return m_data2; }
int getData1() const { return m_data1; }
int getData2() const { return m_data2; }
int getEventCode() const { return m_eventCode; }
bool isMeta() const { return (m_eventCode == MIDIConstants::MIDI_FILE_META_EVENT); }
int getMetaEventCode() const { return m_metaEventCode; }
std::string getMetaMessage() const { return m_metaMessage; }
void setMetaMessage(const std::string &meta) { m_metaMessage = meta; }
friend bool operator<(const MIDIEvent &a, const MIDIEvent &b);
private:
unsigned long m_deltaTime;
unsigned long m_duration;
MIDIByte m_eventCode;
MIDIByte m_data1; // or Note
MIDIByte m_data2; // or Velocity
MIDIByte m_metaEventCode;
std::string m_metaMessage;
};
// Comparator for sorting
//
struct MIDIEventCmp
{
bool operator()(const MIDIEvent &mE1, const MIDIEvent &mE2) const
{ return mE1.getTime() < mE2.getTime(); }
bool operator()(const MIDIEvent *mE1, const MIDIEvent *mE2) const
{ return mE1->getTime() < mE2->getTime(); }
};
class MIDIException : virtual public std::exception
{
public:
MIDIException(std::string message) throw() : m_message(message) {
std::cerr << "WARNING: MIDI exception: " << message.c_str() << std::endl;
}
virtual ~MIDIException() throw() { }
virtual const char *what() const throw() {
return m_message.c_str();
}
protected:
std::string m_message;
};
#endif