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