annotate data/fileio/MIDIEvent.h @ 490:c3fb8258e34d

* Make it possible to import an entire session from an RDF document. However, at the moment the timings of events appear to be constrained by how far the audio decoder has got through its audio file at the time the event is queried -- need to investigate.
author Chris Cannam
date Fri, 21 Nov 2008 18:03:14 +0000
parents 73537d900d4b
children
rev   line source
Chris@301 1 /* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */
Chris@301 2
Chris@301 3 /*
Chris@301 4 Sonic Visualiser
Chris@301 5 An audio file viewer and annotation editor.
Chris@301 6 Centre for Digital Music, Queen Mary, University of London.
Chris@301 7
Chris@301 8 This program is free software; you can redistribute it and/or
Chris@301 9 modify it under the terms of the GNU General Public License as
Chris@301 10 published by the Free Software Foundation; either version 2 of the
Chris@301 11 License, or (at your option) any later version. See the file
Chris@301 12 COPYING included with this distribution for more information.
Chris@301 13 */
Chris@301 14
Chris@301 15
Chris@301 16 /*
Chris@301 17 This is a modified version of a source file from the
Chris@301 18 Rosegarden MIDI and audio sequencer and notation editor.
Chris@301 19 This file copyright 2000-2006 Richard Bown and Chris Cannam.
Chris@301 20 */
Chris@301 21
Chris@301 22 #ifndef _MIDI_EVENT_H_
Chris@301 23 #define _MIDI_EVENT_H_
Chris@301 24
Chris@301 25 #include <QString>
Chris@301 26 #include <string>
Chris@301 27 #include <iostream>
Chris@301 28
Chris@301 29 typedef unsigned char MIDIByte;
Chris@301 30
Chris@301 31 namespace MIDIConstants
Chris@301 32 {
Chris@301 33 static const char *const MIDI_FILE_HEADER = "MThd";
Chris@301 34 static const char *const MIDI_TRACK_HEADER = "MTrk";
Chris@301 35
Chris@301 36 static const MIDIByte MIDI_STATUS_BYTE_MASK = 0x80;
Chris@301 37 static const MIDIByte MIDI_MESSAGE_TYPE_MASK = 0xF0;
Chris@301 38 static const MIDIByte MIDI_CHANNEL_NUM_MASK = 0x0F;
Chris@301 39
Chris@301 40 static const MIDIByte MIDI_NOTE_OFF = 0x80;
Chris@301 41 static const MIDIByte MIDI_NOTE_ON = 0x90;
Chris@301 42 static const MIDIByte MIDI_POLY_AFTERTOUCH = 0xA0;
Chris@301 43 static const MIDIByte MIDI_CTRL_CHANGE = 0xB0;
Chris@301 44 static const MIDIByte MIDI_PROG_CHANGE = 0xC0;
Chris@301 45 static const MIDIByte MIDI_CHNL_AFTERTOUCH = 0xD0;
Chris@301 46 static const MIDIByte MIDI_PITCH_BEND = 0xE0;
Chris@301 47 static const MIDIByte MIDI_SELECT_CHNL_MODE = 0xB0;
Chris@301 48 static const MIDIByte MIDI_SYSTEM_EXCLUSIVE = 0xF0;
Chris@301 49 static const MIDIByte MIDI_TC_QUARTER_FRAME = 0xF1;
Chris@301 50 static const MIDIByte MIDI_SONG_POSITION_PTR = 0xF2;
Chris@301 51 static const MIDIByte MIDI_SONG_SELECT = 0xF3;
Chris@301 52 static const MIDIByte MIDI_TUNE_REQUEST = 0xF6;
Chris@301 53 static const MIDIByte MIDI_END_OF_EXCLUSIVE = 0xF7;
Chris@301 54 static const MIDIByte MIDI_TIMING_CLOCK = 0xF8;
Chris@301 55 static const MIDIByte MIDI_START = 0xFA;
Chris@301 56 static const MIDIByte MIDI_CONTINUE = 0xFB;
Chris@301 57 static const MIDIByte MIDI_STOP = 0xFC;
Chris@301 58 static const MIDIByte MIDI_ACTIVE_SENSING = 0xFE;
Chris@301 59 static const MIDIByte MIDI_SYSTEM_RESET = 0xFF;
Chris@301 60 static const MIDIByte MIDI_SYSEX_NONCOMMERCIAL = 0x7D;
Chris@301 61 static const MIDIByte MIDI_SYSEX_NON_RT = 0x7E;
Chris@301 62 static const MIDIByte MIDI_SYSEX_RT = 0x7F;
Chris@301 63 static const MIDIByte MIDI_SYSEX_RT_COMMAND = 0x06;
Chris@301 64 static const MIDIByte MIDI_SYSEX_RT_RESPONSE = 0x07;
Chris@301 65 static const MIDIByte MIDI_MMC_STOP = 0x01;
Chris@301 66 static const MIDIByte MIDI_MMC_PLAY = 0x02;
Chris@301 67 static const MIDIByte MIDI_MMC_DEFERRED_PLAY = 0x03;
Chris@301 68 static const MIDIByte MIDI_MMC_FAST_FORWARD = 0x04;
Chris@301 69 static const MIDIByte MIDI_MMC_REWIND = 0x05;
Chris@301 70 static const MIDIByte MIDI_MMC_RECORD_STROBE = 0x06;
Chris@301 71 static const MIDIByte MIDI_MMC_RECORD_EXIT = 0x07;
Chris@301 72 static const MIDIByte MIDI_MMC_RECORD_PAUSE = 0x08;
Chris@301 73 static const MIDIByte MIDI_MMC_PAUSE = 0x08;
Chris@301 74 static const MIDIByte MIDI_MMC_EJECT = 0x0A;
Chris@301 75 static const MIDIByte MIDI_MMC_LOCATE = 0x44;
Chris@301 76 static const MIDIByte MIDI_FILE_META_EVENT = 0xFF;
Chris@301 77 static const MIDIByte MIDI_SEQUENCE_NUMBER = 0x00;
Chris@301 78 static const MIDIByte MIDI_TEXT_EVENT = 0x01;
Chris@301 79 static const MIDIByte MIDI_COPYRIGHT_NOTICE = 0x02;
Chris@301 80 static const MIDIByte MIDI_TRACK_NAME = 0x03;
Chris@301 81 static const MIDIByte MIDI_INSTRUMENT_NAME = 0x04;
Chris@301 82 static const MIDIByte MIDI_LYRIC = 0x05;
Chris@301 83 static const MIDIByte MIDI_TEXT_MARKER = 0x06;
Chris@301 84 static const MIDIByte MIDI_CUE_POINT = 0x07;
Chris@301 85 static const MIDIByte MIDI_CHANNEL_PREFIX = 0x20;
Chris@301 86 static const MIDIByte MIDI_CHANNEL_PREFIX_OR_PORT = 0x21;
Chris@301 87 static const MIDIByte MIDI_END_OF_TRACK = 0x2F;
Chris@301 88 static const MIDIByte MIDI_SET_TEMPO = 0x51;
Chris@301 89 static const MIDIByte MIDI_SMPTE_OFFSET = 0x54;
Chris@301 90 static const MIDIByte MIDI_TIME_SIGNATURE = 0x58;
Chris@301 91 static const MIDIByte MIDI_KEY_SIGNATURE = 0x59;
Chris@301 92 static const MIDIByte MIDI_SEQUENCER_SPECIFIC = 0x7F;
Chris@301 93 static const MIDIByte MIDI_CONTROLLER_BANK_MSB = 0x00;
Chris@301 94 static const MIDIByte MIDI_CONTROLLER_VOLUME = 0x07;
Chris@301 95 static const MIDIByte MIDI_CONTROLLER_BANK_LSB = 0x20;
Chris@301 96 static const MIDIByte MIDI_CONTROLLER_MODULATION = 0x01;
Chris@301 97 static const MIDIByte MIDI_CONTROLLER_PAN = 0x0A;
Chris@301 98 static const MIDIByte MIDI_CONTROLLER_SUSTAIN = 0x40;
Chris@301 99 static const MIDIByte MIDI_CONTROLLER_RESONANCE = 0x47;
Chris@301 100 static const MIDIByte MIDI_CONTROLLER_RELEASE = 0x48;
Chris@301 101 static const MIDIByte MIDI_CONTROLLER_ATTACK = 0x49;
Chris@301 102 static const MIDIByte MIDI_CONTROLLER_FILTER = 0x4A;
Chris@301 103 static const MIDIByte MIDI_CONTROLLER_REVERB = 0x5B;
Chris@301 104 static const MIDIByte MIDI_CONTROLLER_CHORUS = 0x5D;
Chris@301 105 static const MIDIByte MIDI_CONTROLLER_NRPN_1 = 0x62;
Chris@301 106 static const MIDIByte MIDI_CONTROLLER_NRPN_2 = 0x63;
Chris@301 107 static const MIDIByte MIDI_CONTROLLER_RPN_1 = 0x64;
Chris@301 108 static const MIDIByte MIDI_CONTROLLER_RPN_2 = 0x65;
Chris@301 109 static const MIDIByte MIDI_CONTROLLER_SOUNDS_OFF = 0x78;
Chris@301 110 static const MIDIByte MIDI_CONTROLLER_RESET = 0x79;
Chris@301 111 static const MIDIByte MIDI_CONTROLLER_LOCAL = 0x7A;
Chris@301 112 static const MIDIByte MIDI_CONTROLLER_ALL_NOTES_OFF = 0x7B;
Chris@301 113 static const MIDIByte MIDI_PERCUSSION_CHANNEL = 9;
Chris@301 114 }
Chris@301 115
Chris@301 116 class MIDIEvent
Chris@301 117 {
Chris@301 118 public:
Chris@301 119 MIDIEvent(unsigned long deltaTime,
Chris@301 120 MIDIByte eventCode,
Chris@301 121 MIDIByte data1 = 0,
Chris@301 122 MIDIByte data2 = 0) :
Chris@301 123 m_deltaTime(deltaTime),
Chris@301 124 m_duration(0),
Chris@301 125 m_eventCode(eventCode),
Chris@301 126 m_data1(data1),
Chris@301 127 m_data2(data2),
Chris@301 128 m_metaEventCode(0)
Chris@301 129 { }
Chris@301 130
Chris@301 131 MIDIEvent(unsigned long deltaTime,
Chris@301 132 MIDIByte eventCode,
Chris@301 133 MIDIByte metaEventCode,
Chris@301 134 const std::string &metaMessage) :
Chris@301 135 m_deltaTime(deltaTime),
Chris@301 136 m_duration(0),
Chris@301 137 m_eventCode(eventCode),
Chris@301 138 m_data1(0),
Chris@301 139 m_data2(0),
Chris@301 140 m_metaEventCode(metaEventCode),
Chris@301 141 m_metaMessage(metaMessage)
Chris@301 142 { }
Chris@301 143
Chris@301 144 MIDIEvent(unsigned long deltaTime,
Chris@301 145 MIDIByte eventCode,
Chris@301 146 const std::string &sysEx) :
Chris@301 147 m_deltaTime(deltaTime),
Chris@301 148 m_duration(0),
Chris@301 149 m_eventCode(eventCode),
Chris@301 150 m_data1(0),
Chris@301 151 m_data2(0),
Chris@301 152 m_metaEventCode(0),
Chris@301 153 m_metaMessage(sysEx)
Chris@301 154 { }
Chris@301 155
Chris@301 156 ~MIDIEvent() { }
Chris@301 157
Chris@301 158 void setTime(const unsigned long &time) { m_deltaTime = time; }
Chris@301 159 void setDuration(const unsigned long& duration) { m_duration = duration;}
Chris@301 160 unsigned long addTime(const unsigned long &time) {
Chris@301 161 m_deltaTime += time;
Chris@301 162 return m_deltaTime;
Chris@301 163 }
Chris@301 164
Chris@301 165 MIDIByte getMessageType() const
Chris@301 166 { return (m_eventCode & MIDIConstants::MIDI_MESSAGE_TYPE_MASK); }
Chris@301 167
Chris@301 168 MIDIByte getChannelNumber() const
Chris@301 169 { return (m_eventCode & MIDIConstants::MIDI_CHANNEL_NUM_MASK); }
Chris@301 170
Chris@301 171 unsigned long getTime() const { return m_deltaTime; }
Chris@301 172 unsigned long getDuration() const { return m_duration; }
Chris@301 173
Chris@301 174 MIDIByte getPitch() const { return m_data1; }
Chris@301 175 MIDIByte getVelocity() const { return m_data2; }
Chris@301 176 MIDIByte getData1() const { return m_data1; }
Chris@301 177 MIDIByte getData2() const { return m_data2; }
Chris@301 178 MIDIByte getEventCode() const { return m_eventCode; }
Chris@301 179
Chris@301 180 bool isMeta() const { return (m_eventCode == MIDIConstants::MIDI_FILE_META_EVENT); }
Chris@301 181
Chris@301 182 MIDIByte getMetaEventCode() const { return m_metaEventCode; }
Chris@301 183 std::string getMetaMessage() const { return m_metaMessage; }
Chris@301 184 void setMetaMessage(const std::string &meta) { m_metaMessage = meta; }
Chris@301 185
Chris@301 186 friend bool operator<(const MIDIEvent &a, const MIDIEvent &b);
Chris@301 187
Chris@301 188 private:
Chris@301 189 MIDIEvent& operator=(const MIDIEvent);
Chris@301 190
Chris@301 191 unsigned long m_deltaTime;
Chris@301 192 unsigned long m_duration;
Chris@301 193 MIDIByte m_eventCode;
Chris@301 194 MIDIByte m_data1; // or Note
Chris@301 195 MIDIByte m_data2; // or Velocity
Chris@301 196 MIDIByte m_metaEventCode;
Chris@301 197 std::string m_metaMessage;
Chris@301 198 };
Chris@301 199
Chris@301 200 // Comparator for sorting
Chris@301 201 //
Chris@301 202 struct MIDIEventCmp
Chris@301 203 {
Chris@301 204 bool operator()(const MIDIEvent &mE1, const MIDIEvent &mE2) const
Chris@301 205 { return mE1.getTime() < mE2.getTime(); }
Chris@301 206
Chris@301 207 bool operator()(const MIDIEvent *mE1, const MIDIEvent *mE2) const
Chris@301 208 { return mE1->getTime() < mE2->getTime(); }
Chris@301 209 };
Chris@301 210
Chris@301 211 class MIDIException : virtual public std::exception
Chris@301 212 {
Chris@301 213 public:
Chris@301 214 MIDIException(QString message) throw() : m_message(message) {
Chris@301 215 std::cerr << "WARNING: MIDI exception: "
Chris@301 216 << message.toLocal8Bit().data() << std::endl;
Chris@301 217 }
Chris@301 218 virtual ~MIDIException() throw() { }
Chris@301 219
Chris@301 220 virtual const char *what() const throw() {
Chris@301 221 return m_message.toLocal8Bit().data();
Chris@301 222 }
Chris@301 223
Chris@301 224 protected:
Chris@301 225 QString m_message;
Chris@301 226 };
Chris@301 227
Chris@301 228 #endif