comparison midiFileReader/MIDIEvent.h @ 0:b299a65a3ad0

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