annotate data/midi/MIDIEvent.h @ 1247:8f076d02569a piper

Make SVDEBUG always write to a log file -- formerly this was disabled in NDEBUG builds. I think there's little use to that, it just means that we keep adding more cerr debug output because we aren't getting the log we need. And SVDEBUG logging is not usually used in tight loops, I don't think the performance overhead is too serious. Also update the About box.
author Chris Cannam
date Thu, 03 Nov 2016 14:57:00 +0000
parents cc27f35aa75c
children 48e9f538e6e9
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@1038 28 #include <stdexcept>
Chris@1038 29
Chris@687 30 #include "base/Debug.h"
Chris@301 31
Chris@301 32 typedef unsigned char MIDIByte;
Chris@301 33
Chris@301 34 namespace MIDIConstants
Chris@301 35 {
Chris@301 36 static const char *const MIDI_FILE_HEADER = "MThd";
Chris@301 37 static const char *const MIDI_TRACK_HEADER = "MTrk";
Chris@301 38
Chris@301 39 static const MIDIByte MIDI_STATUS_BYTE_MASK = 0x80;
Chris@301 40 static const MIDIByte MIDI_MESSAGE_TYPE_MASK = 0xF0;
Chris@301 41 static const MIDIByte MIDI_CHANNEL_NUM_MASK = 0x0F;
Chris@301 42
Chris@301 43 static const MIDIByte MIDI_NOTE_OFF = 0x80;
Chris@301 44 static const MIDIByte MIDI_NOTE_ON = 0x90;
Chris@301 45 static const MIDIByte MIDI_POLY_AFTERTOUCH = 0xA0;
Chris@301 46 static const MIDIByte MIDI_CTRL_CHANGE = 0xB0;
Chris@301 47 static const MIDIByte MIDI_PROG_CHANGE = 0xC0;
Chris@301 48 static const MIDIByte MIDI_CHNL_AFTERTOUCH = 0xD0;
Chris@301 49 static const MIDIByte MIDI_PITCH_BEND = 0xE0;
Chris@301 50 static const MIDIByte MIDI_SELECT_CHNL_MODE = 0xB0;
Chris@301 51 static const MIDIByte MIDI_SYSTEM_EXCLUSIVE = 0xF0;
Chris@301 52 static const MIDIByte MIDI_TC_QUARTER_FRAME = 0xF1;
Chris@301 53 static const MIDIByte MIDI_SONG_POSITION_PTR = 0xF2;
Chris@301 54 static const MIDIByte MIDI_SONG_SELECT = 0xF3;
Chris@301 55 static const MIDIByte MIDI_TUNE_REQUEST = 0xF6;
Chris@301 56 static const MIDIByte MIDI_END_OF_EXCLUSIVE = 0xF7;
Chris@301 57 static const MIDIByte MIDI_TIMING_CLOCK = 0xF8;
Chris@301 58 static const MIDIByte MIDI_START = 0xFA;
Chris@301 59 static const MIDIByte MIDI_CONTINUE = 0xFB;
Chris@301 60 static const MIDIByte MIDI_STOP = 0xFC;
Chris@301 61 static const MIDIByte MIDI_ACTIVE_SENSING = 0xFE;
Chris@301 62 static const MIDIByte MIDI_SYSTEM_RESET = 0xFF;
Chris@301 63 static const MIDIByte MIDI_SYSEX_NONCOMMERCIAL = 0x7D;
Chris@301 64 static const MIDIByte MIDI_SYSEX_NON_RT = 0x7E;
Chris@301 65 static const MIDIByte MIDI_SYSEX_RT = 0x7F;
Chris@301 66 static const MIDIByte MIDI_SYSEX_RT_COMMAND = 0x06;
Chris@301 67 static const MIDIByte MIDI_SYSEX_RT_RESPONSE = 0x07;
Chris@301 68 static const MIDIByte MIDI_MMC_STOP = 0x01;
Chris@301 69 static const MIDIByte MIDI_MMC_PLAY = 0x02;
Chris@301 70 static const MIDIByte MIDI_MMC_DEFERRED_PLAY = 0x03;
Chris@301 71 static const MIDIByte MIDI_MMC_FAST_FORWARD = 0x04;
Chris@301 72 static const MIDIByte MIDI_MMC_REWIND = 0x05;
Chris@301 73 static const MIDIByte MIDI_MMC_RECORD_STROBE = 0x06;
Chris@301 74 static const MIDIByte MIDI_MMC_RECORD_EXIT = 0x07;
Chris@301 75 static const MIDIByte MIDI_MMC_RECORD_PAUSE = 0x08;
Chris@301 76 static const MIDIByte MIDI_MMC_PAUSE = 0x08;
Chris@301 77 static const MIDIByte MIDI_MMC_EJECT = 0x0A;
Chris@301 78 static const MIDIByte MIDI_MMC_LOCATE = 0x44;
Chris@301 79 static const MIDIByte MIDI_FILE_META_EVENT = 0xFF;
Chris@301 80 static const MIDIByte MIDI_SEQUENCE_NUMBER = 0x00;
Chris@301 81 static const MIDIByte MIDI_TEXT_EVENT = 0x01;
Chris@301 82 static const MIDIByte MIDI_COPYRIGHT_NOTICE = 0x02;
Chris@301 83 static const MIDIByte MIDI_TRACK_NAME = 0x03;
Chris@301 84 static const MIDIByte MIDI_INSTRUMENT_NAME = 0x04;
Chris@301 85 static const MIDIByte MIDI_LYRIC = 0x05;
Chris@301 86 static const MIDIByte MIDI_TEXT_MARKER = 0x06;
Chris@301 87 static const MIDIByte MIDI_CUE_POINT = 0x07;
Chris@301 88 static const MIDIByte MIDI_CHANNEL_PREFIX = 0x20;
Chris@301 89 static const MIDIByte MIDI_CHANNEL_PREFIX_OR_PORT = 0x21;
Chris@301 90 static const MIDIByte MIDI_END_OF_TRACK = 0x2F;
Chris@301 91 static const MIDIByte MIDI_SET_TEMPO = 0x51;
Chris@301 92 static const MIDIByte MIDI_SMPTE_OFFSET = 0x54;
Chris@301 93 static const MIDIByte MIDI_TIME_SIGNATURE = 0x58;
Chris@301 94 static const MIDIByte MIDI_KEY_SIGNATURE = 0x59;
Chris@301 95 static const MIDIByte MIDI_SEQUENCER_SPECIFIC = 0x7F;
Chris@301 96 static const MIDIByte MIDI_CONTROLLER_BANK_MSB = 0x00;
Chris@301 97 static const MIDIByte MIDI_CONTROLLER_VOLUME = 0x07;
Chris@301 98 static const MIDIByte MIDI_CONTROLLER_BANK_LSB = 0x20;
Chris@301 99 static const MIDIByte MIDI_CONTROLLER_MODULATION = 0x01;
Chris@301 100 static const MIDIByte MIDI_CONTROLLER_PAN = 0x0A;
Chris@301 101 static const MIDIByte MIDI_CONTROLLER_SUSTAIN = 0x40;
Chris@301 102 static const MIDIByte MIDI_CONTROLLER_RESONANCE = 0x47;
Chris@301 103 static const MIDIByte MIDI_CONTROLLER_RELEASE = 0x48;
Chris@301 104 static const MIDIByte MIDI_CONTROLLER_ATTACK = 0x49;
Chris@301 105 static const MIDIByte MIDI_CONTROLLER_FILTER = 0x4A;
Chris@301 106 static const MIDIByte MIDI_CONTROLLER_REVERB = 0x5B;
Chris@301 107 static const MIDIByte MIDI_CONTROLLER_CHORUS = 0x5D;
Chris@301 108 static const MIDIByte MIDI_CONTROLLER_NRPN_1 = 0x62;
Chris@301 109 static const MIDIByte MIDI_CONTROLLER_NRPN_2 = 0x63;
Chris@301 110 static const MIDIByte MIDI_CONTROLLER_RPN_1 = 0x64;
Chris@301 111 static const MIDIByte MIDI_CONTROLLER_RPN_2 = 0x65;
Chris@301 112 static const MIDIByte MIDI_CONTROLLER_SOUNDS_OFF = 0x78;
Chris@301 113 static const MIDIByte MIDI_CONTROLLER_RESET = 0x79;
Chris@301 114 static const MIDIByte MIDI_CONTROLLER_LOCAL = 0x7A;
Chris@301 115 static const MIDIByte MIDI_CONTROLLER_ALL_NOTES_OFF = 0x7B;
Chris@301 116 static const MIDIByte MIDI_PERCUSSION_CHANNEL = 9;
Chris@301 117 }
Chris@301 118
Chris@301 119 class MIDIEvent
Chris@301 120 {
Chris@301 121 public:
Chris@301 122 MIDIEvent(unsigned long deltaTime,
Chris@1038 123 int eventCode,
Chris@1038 124 int data1 = 0,
Chris@1038 125 int data2 = 0) :
Chris@301 126 m_deltaTime(deltaTime),
Chris@301 127 m_duration(0),
Chris@301 128 m_metaEventCode(0)
Chris@1038 129 {
Chris@1038 130 if (eventCode < 0 || eventCode > 0xff ||
Chris@1038 131 data1 < 0 || data1 > 0xff ||
Chris@1038 132 data2 < 0 || data2 > 0xff) {
Chris@1038 133 throw std::domain_error("not all args within byte range");
Chris@1038 134 }
Chris@1038 135 m_eventCode = MIDIByte(eventCode);
Chris@1038 136 m_data1 = MIDIByte(data1);
Chris@1038 137 m_data2 = MIDIByte(data2);
Chris@1038 138 }
Chris@301 139
Chris@301 140 MIDIEvent(unsigned long deltaTime,
Chris@301 141 MIDIByte eventCode,
Chris@301 142 MIDIByte metaEventCode,
Chris@301 143 const std::string &metaMessage) :
Chris@301 144 m_deltaTime(deltaTime),
Chris@301 145 m_duration(0),
Chris@301 146 m_eventCode(eventCode),
Chris@301 147 m_data1(0),
Chris@301 148 m_data2(0),
Chris@301 149 m_metaEventCode(metaEventCode),
Chris@301 150 m_metaMessage(metaMessage)
Chris@301 151 { }
Chris@301 152
Chris@301 153 MIDIEvent(unsigned long deltaTime,
Chris@301 154 MIDIByte eventCode,
Chris@301 155 const std::string &sysEx) :
Chris@301 156 m_deltaTime(deltaTime),
Chris@301 157 m_duration(0),
Chris@301 158 m_eventCode(eventCode),
Chris@301 159 m_data1(0),
Chris@301 160 m_data2(0),
Chris@301 161 m_metaEventCode(0),
Chris@301 162 m_metaMessage(sysEx)
Chris@301 163 { }
Chris@301 164
Chris@301 165 ~MIDIEvent() { }
Chris@301 166
Chris@301 167 void setTime(const unsigned long &time) { m_deltaTime = time; }
Chris@301 168 void setDuration(const unsigned long& duration) { m_duration = duration;}
Chris@301 169 unsigned long addTime(const unsigned long &time) {
Chris@301 170 m_deltaTime += time;
Chris@301 171 return m_deltaTime;
Chris@301 172 }
Chris@301 173
Chris@301 174 MIDIByte getMessageType() const
Chris@301 175 { return (m_eventCode & MIDIConstants::MIDI_MESSAGE_TYPE_MASK); }
Chris@301 176
Chris@301 177 MIDIByte getChannelNumber() const
Chris@301 178 { return (m_eventCode & MIDIConstants::MIDI_CHANNEL_NUM_MASK); }
Chris@301 179
Chris@301 180 unsigned long getTime() const { return m_deltaTime; }
Chris@301 181 unsigned long getDuration() const { return m_duration; }
Chris@301 182
Chris@301 183 MIDIByte getPitch() const { return m_data1; }
Chris@301 184 MIDIByte getVelocity() const { return m_data2; }
Chris@301 185 MIDIByte getData1() const { return m_data1; }
Chris@301 186 MIDIByte getData2() const { return m_data2; }
Chris@301 187 MIDIByte getEventCode() const { return m_eventCode; }
Chris@301 188
Chris@301 189 bool isMeta() const { return (m_eventCode == MIDIConstants::MIDI_FILE_META_EVENT); }
Chris@301 190
Chris@301 191 MIDIByte getMetaEventCode() const { return m_metaEventCode; }
Chris@301 192 std::string getMetaMessage() const { return m_metaMessage; }
Chris@301 193 void setMetaMessage(const std::string &meta) { m_metaMessage = meta; }
Chris@301 194
Chris@301 195 friend bool operator<(const MIDIEvent &a, const MIDIEvent &b);
Chris@301 196
Chris@301 197 private:
Chris@301 198 MIDIEvent& operator=(const MIDIEvent);
Chris@301 199
Chris@301 200 unsigned long m_deltaTime;
Chris@301 201 unsigned long m_duration;
Chris@301 202 MIDIByte m_eventCode;
Chris@301 203 MIDIByte m_data1; // or Note
Chris@301 204 MIDIByte m_data2; // or Velocity
Chris@301 205 MIDIByte m_metaEventCode;
Chris@301 206 std::string m_metaMessage;
Chris@301 207 };
Chris@301 208
Chris@301 209 // Comparator for sorting
Chris@301 210 //
Chris@301 211 struct MIDIEventCmp
Chris@301 212 {
Chris@301 213 bool operator()(const MIDIEvent &mE1, const MIDIEvent &mE2) const
Chris@301 214 { return mE1.getTime() < mE2.getTime(); }
Chris@301 215
Chris@301 216 bool operator()(const MIDIEvent *mE1, const MIDIEvent *mE2) const
Chris@301 217 { return mE1->getTime() < mE2->getTime(); }
Chris@301 218 };
Chris@301 219
Chris@301 220 class MIDIException : virtual public std::exception
Chris@301 221 {
Chris@301 222 public:
Chris@301 223 MIDIException(QString message) throw() : m_message(message) {
Chris@301 224 std::cerr << "WARNING: MIDI exception: "
Chris@301 225 << message.toLocal8Bit().data() << std::endl;
Chris@301 226 }
Chris@301 227 virtual ~MIDIException() throw() { }
Chris@301 228
Chris@301 229 virtual const char *what() const throw() {
Chris@301 230 return m_message.toLocal8Bit().data();
Chris@301 231 }
Chris@301 232
Chris@301 233 protected:
Chris@301 234 QString m_message;
Chris@301 235 };
Chris@301 236
Chris@301 237 #endif