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