annotate data/midi/MIDIEvent.h @ 1008:d9e0e59a1581

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