1 /* 2 Drumstick MIDI File Player Multiplatform Program 3 Copyright (C) 2006-2021, Pedro Lopez-Cabanillas <plcl@users.sf.net> 4 5 This program is free software; you can redistribute it and/or modify 6 it under the terms of the GNU General Public License as published by 7 the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 13 GNU General Public License for more details. 14 15 You should have received a copy of the GNU General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. 17 */ 18 19 #ifndef EVENTS_H 20 #define EVENTS_H 21 22 #include <QEvent> 23 24 25 /** 26 * @file events.h 27 * Classes managing MIDI events. 28 * 29 * @defgroup Sequencer MIDI Events 30 * @{ 31 */ 32 33 /** 34 * Constant SequencerEventType is the QEvent::type() of any MIDIEvent 35 * object to be used to check the argument in QObject::customEvent(). 36 */ 37 const QEvent::Type MIDIEventType = QEvent::Type(QEvent::User + 3161); 38 39 /** 40 * Base class for the event's hierarchy 41 * 42 * All event classes share this base class. It provides common properties 43 */ 44 class MIDIEvent : public QEvent 45 { 46 public: 47 MIDIEvent(); clone()48 virtual MIDIEvent *clone() { return new MIDIEvent(*this); } 49 delta()50 long delta() const { return m_delta; } tick()51 long tick() const { return m_tick; } 52 void setDelta(const long delta); 53 void setTick(const long tick); tag()54 int tag() const { return m_tag; } 55 void setTag(const int aTag); status()56 int status() const { return m_status; } isChannel()57 virtual bool isChannel() { return false; } isMetaEvent()58 virtual bool isMetaEvent() { return false; } 59 60 protected: 61 long m_delta; 62 long m_tick; 63 int m_tag; 64 int m_status; 65 }; 66 67 /** 68 * Base class for the events having a Channel property 69 */ 70 class ChannelEvent : public MIDIEvent 71 { 72 public: ChannelEvent()73 ChannelEvent() : MIDIEvent(), m_channel(0) {} ChannelEvent(int ch)74 explicit ChannelEvent(int ch): MIDIEvent(), m_channel(ch) {} isChannel()75 virtual bool isChannel() override { return true; } 76 /** 77 * Sets the channel of the event 78 * @param c A channel, between 0 and 15. 79 * @see channel() 80 */ setChannel(const int c)81 void setChannel(const int c) { m_channel = (c & 0xf); } 82 /** 83 * Gets the event's channel 84 * @return The event's channel 85 * @see setChannel() 86 */ channel()87 int channel() const { return m_channel; } 88 protected: 89 int m_channel; 90 }; 91 92 /** 93 * Base class for the events having Key and Velocity properties. 94 */ 95 class KeyEvent : public ChannelEvent 96 { 97 public: KeyEvent()98 KeyEvent() : ChannelEvent(), m_note(0), m_velocity(0) {} KeyEvent(int ch,int key,int vel)99 KeyEvent(int ch, int key, int vel): ChannelEvent(ch), m_note(key), m_velocity(vel) {} 100 /** 101 * Gets the MIDI note of this event. 102 * @return The event's MIDI note. 103 * @see setKey() 104 */ key()105 int key() const { return m_note; } 106 /** 107 * Sets the MIDI note of this event. 108 * @param b A MIDI note, between 0 and 127. 109 * @see getKey() 110 */ setKey(const int b)111 void setKey(const int b) { m_note = b; } 112 /** 113 * Gets the note velocity of this event. 114 * @return The event's note velocity. 115 * @see setVelocity() 116 */ velocity()117 int velocity() const { return m_velocity; } 118 /** 119 * Sets the note velocity of this event. 120 * @param b A velocity value, between 0 and 127. 121 * @see velocity() 122 */ setVelocity(const int b)123 void setVelocity(const int b) { m_velocity = b; } 124 protected: 125 int m_note; 126 int m_velocity; 127 }; 128 129 130 /** 131 * Event representing a note-on MIDI event 132 */ 133 class NoteOnEvent : public KeyEvent 134 { 135 public: NoteOnEvent()136 NoteOnEvent() : KeyEvent() { } 137 NoteOnEvent(const int ch, const int key, const int vel); clone()138 virtual NoteOnEvent *clone() override { return new NoteOnEvent(*this); } 139 }; 140 141 /** 142 * Event representing a note-off MIDI event 143 */ 144 class NoteOffEvent : public KeyEvent 145 { 146 public: NoteOffEvent()147 NoteOffEvent() : KeyEvent() {} 148 NoteOffEvent(const int ch, const int key, const int vel); clone()149 virtual NoteOffEvent *clone() override { return new NoteOffEvent(*this); } 150 }; 151 152 /** 153 * Event representing a MIDI key pressure, or polyphonic after-touch event 154 */ 155 class KeyPressEvent : public KeyEvent 156 { 157 public: KeyPressEvent()158 KeyPressEvent() : KeyEvent() { } 159 KeyPressEvent(const int ch, const int key, const int vel); clone()160 virtual KeyPressEvent *clone() override { return new KeyPressEvent(*this); } 161 }; 162 163 /** 164 * Event representing a MIDI control change event 165 */ 166 class ControllerEvent : public ChannelEvent 167 { 168 public: ControllerEvent()169 ControllerEvent() : ChannelEvent(), m_param(0), m_value(0) {} 170 ControllerEvent(const int ch, const int cc, const int val); clone()171 virtual ControllerEvent *clone() override { return new ControllerEvent(*this); } 172 173 static const int MIDI_CTL_MSB_BANK = 0x00; /**< Bank selection */ 174 static const int MIDI_CTL_MSB_MODWHEEL = 0x01; /**< Modulation */ 175 static const int MIDI_CTL_MSB_BREATH = 0x02; /**< Breath */ 176 static const int MIDI_CTL_MSB_FOOT = 0x04; /**< Foot */ 177 static const int MIDI_CTL_MSB_PORTAMENTO_TIME = 0x05; /**< Portamento time */ 178 static const int MIDI_CTL_MSB_DATA_ENTRY = 0x06; /**< Data entry */ 179 static const int MIDI_CTL_MSB_MAIN_VOLUME = 0x07; /**< Main volume */ 180 static const int MIDI_CTL_MSB_BALANCE = 0x08; /**< Balance */ 181 static const int MIDI_CTL_MSB_PAN = 0x0a; /**< Panpot */ 182 static const int MIDI_CTL_MSB_EXPRESSION = 0x0b; /**< Expression */ 183 static const int MIDI_CTL_MSB_EFFECT1 = 0x0c; /**< Effect1 */ 184 static const int MIDI_CTL_MSB_EFFECT2 = 0x0d; /**< Effect2 */ 185 static const int MIDI_CTL_MSB_GENERAL_PURPOSE1 = 0x10; /**< General purpose 1 */ 186 static const int MIDI_CTL_MSB_GENERAL_PURPOSE2 = 0x11; /**< General purpose 2 */ 187 static const int MIDI_CTL_MSB_GENERAL_PURPOSE3 = 0x12; /**< General purpose 3 */ 188 static const int MIDI_CTL_MSB_GENERAL_PURPOSE4 = 0x13; /**< General purpose 4 */ 189 static const int MIDI_CTL_LSB_BANK = 0x20; /**< Bank selection */ 190 static const int MIDI_CTL_LSB_MODWHEEL = 0x21; /**< Modulation */ 191 static const int MIDI_CTL_LSB_BREATH = 0x22; /**< Breath */ 192 static const int MIDI_CTL_LSB_FOOT = 0x24; /**< Foot */ 193 static const int MIDI_CTL_LSB_PORTAMENTO_TIME = 0x25; /**< Portamento time */ 194 static const int MIDI_CTL_LSB_DATA_ENTRY = 0x26; /**< Data entry */ 195 static const int MIDI_CTL_LSB_MAIN_VOLUME = 0x27; /**< Main volume */ 196 static const int MIDI_CTL_LSB_BALANCE = 0x28; /**< Balance */ 197 static const int MIDI_CTL_LSB_PAN = 0x2a; /**< Panpot */ 198 static const int MIDI_CTL_LSB_EXPRESSION = 0x2b; /**< Expression */ 199 static const int MIDI_CTL_LSB_EFFECT1 = 0x2c; /**< Effect1 */ 200 static const int MIDI_CTL_LSB_EFFECT2 = 0x2d; /**< Effect2 */ 201 static const int MIDI_CTL_LSB_GENERAL_PURPOSE1 = 0x30; /**< General purpose 1 */ 202 static const int MIDI_CTL_LSB_GENERAL_PURPOSE2 = 0x31; /**< General purpose 2 */ 203 static const int MIDI_CTL_LSB_GENERAL_PURPOSE3 = 0x32; /**< General purpose 3 */ 204 static const int MIDI_CTL_LSB_GENERAL_PURPOSE4 = 0x33; /**< General purpose 4 */ 205 static const int MIDI_CTL_SUSTAIN = 0x40; /**< Sustain pedal */ 206 static const int MIDI_CTL_PORTAMENTO = 0x41; /**< Portamento */ 207 static const int MIDI_CTL_SOSTENUTO = 0x42; /**< Sostenuto */ 208 static const int MIDI_CTL_SUSTENUTO = 0x42; /**< Sostenuto (a typo in the older version) */ 209 static const int MIDI_CTL_SOFT_PEDAL = 0x43; /**< Soft pedal */ 210 static const int MIDI_CTL_LEGATO_FOOTSWITCH = 0x44; /**< Legato foot switch */ 211 static const int MIDI_CTL_HOLD2 = 0x45; /**< Hold2 */ 212 static const int MIDI_CTL_SC1_SOUND_VARIATION = 0x46; /**< SC1 Sound Variation */ 213 static const int MIDI_CTL_SC2_TIMBRE = 0x47; /**< SC2 Timbre */ 214 static const int MIDI_CTL_SC3_RELEASE_TIME = 0x48; /**< SC3 Release Time */ 215 static const int MIDI_CTL_SC4_ATTACK_TIME = 0x49; /**< SC4 Attack Time */ 216 static const int MIDI_CTL_SC5_BRIGHTNESS = 0x4a; /**< SC5 Brightness */ 217 static const int MIDI_CTL_SC6 = 0x4b; /**< SC6 */ 218 static const int MIDI_CTL_SC7 = 0x4c; /**< SC7 */ 219 static const int MIDI_CTL_SC8 = 0x4d; /**< SC8 */ 220 static const int MIDI_CTL_SC9 = 0x4e; /**< SC9 */ 221 static const int MIDI_CTL_SC10 = 0x4f; /**< SC10 */ 222 static const int MIDI_CTL_GENERAL_PURPOSE5 = 0x50; /**< General purpose 5 */ 223 static const int MIDI_CTL_GENERAL_PURPOSE6 = 0x51; /**< General purpose 6 */ 224 static const int MIDI_CTL_GENERAL_PURPOSE7 = 0x52; /**< General purpose 7 */ 225 static const int MIDI_CTL_GENERAL_PURPOSE8 = 0x53; /**< General purpose 8 */ 226 static const int MIDI_CTL_PORTAMENTO_CONTROL = 0x54; /**< Portamento control */ 227 static const int MIDI_CTL_E1_REVERB_DEPTH = 0x5b; /**< E1 Reverb Depth */ 228 static const int MIDI_CTL_E2_TREMOLO_DEPTH = 0x5c; /**< E2 Tremolo Depth */ 229 static const int MIDI_CTL_E3_CHORUS_DEPTH = 0x5d; /**< E3 Chorus Depth */ 230 static const int MIDI_CTL_E4_DETUNE_DEPTH = 0x5e; /**< E4 Detune Depth */ 231 static const int MIDI_CTL_E5_PHASER_DEPTH = 0x5f; /**< E5 Phaser Depth */ 232 static const int MIDI_CTL_DATA_INCREMENT = 0x60; /**< Data Increment */ 233 static const int MIDI_CTL_DATA_DECREMENT = 0x61; /**< Data Decrement */ 234 static const int MIDI_CTL_NONREG_PARM_NUM_LSB = 0x62; /**< Non-registered parameter number */ 235 static const int MIDI_CTL_NONREG_PARM_NUM_MSB = 0x63; /**< Non-registered parameter number */ 236 static const int MIDI_CTL_REGIST_PARM_NUM_LSB = 0x64; /**< Registered parameter number */ 237 static const int MIDI_CTL_REGIST_PARM_NUM_MSB = 0x65; /**< Registered parameter number */ 238 static const int MIDI_CTL_ALL_SOUNDS_OFF = 0x78; /**< All sounds off */ 239 static const int MIDI_CTL_RESET_CONTROLLERS = 0x79; /**< Reset Controllers */ 240 static const int MIDI_CTL_LOCAL_CONTROL_SWITCH = 0x7a; /**< Local control switch */ 241 static const int MIDI_CTL_ALL_NOTES_OFF = 0x7b; /**< All notes off */ 242 static const int MIDI_CTL_OMNI_OFF = 0x7c; /**< Omni off */ 243 static const int MIDI_CTL_OMNI_ON = 0x7d; /**< Omni on */ 244 static const int MIDI_CTL_MONO1 = 0x7e; /**< Mono1 */ 245 static const int MIDI_CTL_MONO2 = 0x7f; /**< Mono2 */ 246 247 /** 248 * Gets the controller event's parameter. 249 * @return The controller event's parameter. 250 * @see setParam() 251 */ param()252 int param() const { return m_param; } 253 /** 254 * Sets the controller event's parameter. 255 * @param p The controller event's parameter. 256 * @see getParam() 257 */ setParam(const int p)258 void setParam( const int p ) { m_param = p; } 259 /** 260 * Gets the controller event's value. 261 * @return The controller event's value. 262 * @see setValue() 263 */ value()264 int value() const { return m_value; } 265 /** 266 * Sets the controller event's value. 267 * @param v The controller event's value. 268 * @see value() 269 */ setValue(const int v)270 void setValue( const int v ) { m_value = v; } 271 protected: 272 int m_param; 273 int m_value; 274 }; 275 276 /** 277 * Event representing a MIDI program change event 278 */ 279 class ProgramChangeEvent : public ChannelEvent 280 { 281 public: ProgramChangeEvent()282 ProgramChangeEvent() : ChannelEvent(), m_program(0) { } 283 ProgramChangeEvent(const int ch, const int val); clone()284 virtual ProgramChangeEvent *clone() override { return new ProgramChangeEvent(*this); } 285 /** Gets the MIDI program number */ program()286 int program() const { return m_program; } 287 /** Sets the MIDI program number */ setProgram(const int v)288 void setProgram( const int v ) { m_program = v; } 289 protected: 290 int m_program; 291 }; 292 293 /** 294 * Event representing a MIDI bender, or pitch wheel event 295 */ 296 class PitchBendEvent : public ChannelEvent 297 { 298 public: PitchBendEvent()299 PitchBendEvent() : ChannelEvent(), m_value(0) { } 300 PitchBendEvent(const int ch, const int val); clone()301 virtual PitchBendEvent *clone() override { return new PitchBendEvent(*this); } 302 /** Gets the MIDI pitch bend value, zero centered from -8192 to 8191 */ value()303 int value() const { return m_value; } 304 /** Sets the MIDI pitch bend value, zero centered from -8192 to 8191 */ setValue(const int v)305 void setValue( const int v ) { m_value = v; } 306 protected: 307 int m_value; 308 }; 309 310 /** 311 * Event representing a MIDI channel pressure or after-touch event 312 */ 313 class ChanPressEvent : public ChannelEvent 314 { 315 public: ChanPressEvent()316 ChanPressEvent() : ChannelEvent(), m_value(0) { } 317 ChanPressEvent( const int ch, const int val); clone()318 virtual ChanPressEvent *clone() override { return new ChanPressEvent(*this); } 319 /** Gets the channel aftertouch value */ value()320 int value() const { return m_value; } 321 /** Sets the channel aftertouch value */ setValue(const int v)322 void setValue( const int v ) { m_value = v; } 323 protected: 324 int m_value; 325 }; 326 327 /** 328 * Base class for variable length events 329 */ 330 class VariableEvent : public MIDIEvent 331 { 332 public: 333 VariableEvent(); 334 explicit VariableEvent(const QByteArray& data); 335 VariableEvent(const unsigned int datalen, char* dataptr); clone()336 virtual VariableEvent *clone() override { return new VariableEvent(*this); } isMetaEvent()337 virtual bool isMetaEvent() override { return true; } length()338 unsigned int length() const { return m_data.length(); } data()339 QByteArray data() const { return m_data; } setData(const QByteArray & d)340 void setData(const QByteArray& d) { m_data = d; } 341 protected: 342 QByteArray m_data; 343 }; 344 345 /** 346 * Event representing a MIDI system exclusive event 347 */ 348 class SysExEvent : public VariableEvent 349 { 350 public: 351 SysExEvent(); 352 explicit SysExEvent(const QByteArray& data); 353 SysExEvent(const unsigned int datalen, char* dataptr); clone()354 virtual SysExEvent *clone() override { return new SysExEvent(*this); } 355 }; 356 357 /** 358 * Event representing a SMF text event 359 * 360 * This event type is not intended to be transmitted over the wire to an 361 * external device, but it is useful for sequencer programs or MIDI applications 362 */ 363 class TextEvent : public VariableEvent 364 { 365 public: 366 TextEvent(); 367 TextEvent(const unsigned int datalen, char* dataptr); 368 explicit TextEvent(const QByteArray& text, const int textType = 1); clone()369 virtual TextEvent *clone() override { return new TextEvent(*this); } 370 int textType() const; 371 protected: 372 int m_textType; 373 }; 374 375 /** 376 * Generic event 377 */ 378 class SystemEvent : public MIDIEvent 379 { 380 public: SystemEvent()381 SystemEvent() : MIDIEvent() {} 382 explicit SystemEvent(const int message); clone()383 virtual SystemEvent *clone() override { return new SystemEvent(*this); } message()384 int message() const { return m_status; } 385 }; 386 387 388 /** 389 * Event representing a tempo change 390 */ 391 class TempoEvent : public MIDIEvent 392 { 393 public: 394 TempoEvent(); 395 explicit TempoEvent(const qreal tempo); clone()396 virtual TempoEvent *clone() override { return new TempoEvent(*this); } isMetaEvent()397 virtual bool isMetaEvent() override { return true; } bpm()398 qreal bpm() const { return 6e7 / m_tempo; } tempo()399 qreal tempo() const { return m_tempo; } setTempo(const qreal t)400 void setTempo(const qreal t) { m_tempo = t; } 401 protected: 402 qreal m_tempo; 403 }; 404 405 /** 406 * Event representing a time signature change 407 */ 408 class TimeSignatureEvent : public MIDIEvent 409 { 410 public: 411 TimeSignatureEvent(); 412 TimeSignatureEvent(const int numerator, const int denominator); clone()413 virtual TimeSignatureEvent *clone() override { return new TimeSignatureEvent(*this); } isMetaEvent()414 virtual bool isMetaEvent() override { return true; } numerator()415 int numerator() const { return m_numerator; } denominator()416 int denominator() const { return m_denominator; } 417 protected: 418 int m_numerator; 419 int m_denominator; 420 }; 421 422 /** 423 * Event representing a key signature change 424 */ 425 class KeySignatureEvent : public MIDIEvent 426 { 427 public: 428 KeySignatureEvent(); 429 KeySignatureEvent(const int alterations, const bool minorMode); clone()430 virtual KeySignatureEvent *clone() override { return new KeySignatureEvent(*this); } isMetaEvent()431 virtual bool isMetaEvent() override { return true; } alterations()432 int alterations() const { return m_alterations; } minorMode()433 bool minorMode() const { return m_minorMode; } 434 protected: 435 int m_alterations; 436 bool m_minorMode; 437 }; 438 439 /** 440 * Event representing a rhythm beat 441 */ 442 class BeatEvent : public MIDIEvent 443 { 444 public: 445 BeatEvent(); 446 BeatEvent(const int bar, const int beat, const int max); clone()447 virtual BeatEvent *clone() override { return new BeatEvent(*this); } isMetaEvent()448 virtual bool isMetaEvent() override { return true; } bar()449 int bar() const { return m_bar; } beat()450 int beat() const { return m_beat; } barLength()451 int barLength() const { return m_max; } 452 protected: 453 int m_bar; 454 int m_beat; 455 int m_max; 456 }; 457 458 /** @} */ 459 460 #endif //EVENTS_H 461