Mercurial > hg > midi-score-follower
diff midiFileReader/MIDIEvent.h @ 0:b299a65a3ad0
start project
author | Andrew N Robertson <andrew.robertson@eecs.qmul.ac.uk> |
---|---|
date | Tue, 16 Aug 2011 11:29:59 +0100 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/midiFileReader/MIDIEvent.h Tue Aug 16 11:29:59 2011 +0100 @@ -0,0 +1,242 @@ +/* -*- c-basic-offset: 4 indent-tabs-mode: nil -*- vi:set ts=8 sts=4 sw=4: */ + +/* + This is a modified version of a source file from the + Rosegarden MIDI and audio sequencer and notation editor. + This file copyright 2000-2010 Richard Bown and Chris Cannam. + + Permission is hereby granted, free of charge, to any person + obtaining a copy of this software and associated documentation + files (the "Software"), to deal in the Software without + restriction, including without limitation the rights to use, copy, + modify, merge, publish, distribute, sublicense, and/or sell copies + of the Software, and to permit persons to whom the Software is + furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be + included in all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF + MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR + ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF + CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION + WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + + Except as contained in this notice, the names of the authors + shall not be used in advertising or otherwise to promote the sale, + use or other dealings in this Software without prior written + authorization. +*/ + +#ifndef _MIDI_EVENT_H_ +#define _MIDI_EVENT_H_ + +#include <string> +#include <iostream> + +typedef unsigned char MIDIByte; + +namespace MIDIConstants +{ + static const char *const MIDI_FILE_HEADER = "MThd"; + static const char *const MIDI_TRACK_HEADER = "MTrk"; + + static const MIDIByte MIDI_STATUS_BYTE_MASK = 0x80; + static const MIDIByte MIDI_MESSAGE_TYPE_MASK = 0xF0; + static const MIDIByte MIDI_CHANNEL_NUM_MASK = 0x0F; + + static const MIDIByte MIDI_NOTE_OFF = 0x80; + static const MIDIByte MIDI_NOTE_ON = 0x90; + static const MIDIByte MIDI_POLY_AFTERTOUCH = 0xA0; + static const MIDIByte MIDI_CTRL_CHANGE = 0xB0; + static const MIDIByte MIDI_PROG_CHANGE = 0xC0; + static const MIDIByte MIDI_CHNL_AFTERTOUCH = 0xD0; + static const MIDIByte MIDI_PITCH_BEND = 0xE0; + static const MIDIByte MIDI_SELECT_CHNL_MODE = 0xB0; + static const MIDIByte MIDI_SYSTEM_EXCLUSIVE = 0xF0; + static const MIDIByte MIDI_TC_QUARTER_FRAME = 0xF1; + static const MIDIByte MIDI_SONG_POSITION_PTR = 0xF2; + static const MIDIByte MIDI_SONG_SELECT = 0xF3; + static const MIDIByte MIDI_TUNE_REQUEST = 0xF6; + static const MIDIByte MIDI_END_OF_EXCLUSIVE = 0xF7; + static const MIDIByte MIDI_TIMING_CLOCK = 0xF8; + static const MIDIByte MIDI_START = 0xFA; + static const MIDIByte MIDI_CONTINUE = 0xFB; + static const MIDIByte MIDI_STOP = 0xFC; + static const MIDIByte MIDI_ACTIVE_SENSING = 0xFE; + static const MIDIByte MIDI_SYSTEM_RESET = 0xFF; + static const MIDIByte MIDI_SYSEX_NONCOMMERCIAL = 0x7D; + static const MIDIByte MIDI_SYSEX_NON_RT = 0x7E; + static const MIDIByte MIDI_SYSEX_RT = 0x7F; + static const MIDIByte MIDI_SYSEX_RT_COMMAND = 0x06; + static const MIDIByte MIDI_SYSEX_RT_RESPONSE = 0x07; + static const MIDIByte MIDI_MMC_STOP = 0x01; + static const MIDIByte MIDI_MMC_PLAY = 0x02; + static const MIDIByte MIDI_MMC_DEFERRED_PLAY = 0x03; + static const MIDIByte MIDI_MMC_FAST_FORWARD = 0x04; + static const MIDIByte MIDI_MMC_REWIND = 0x05; + static const MIDIByte MIDI_MMC_RECORD_STROBE = 0x06; + static const MIDIByte MIDI_MMC_RECORD_EXIT = 0x07; + static const MIDIByte MIDI_MMC_RECORD_PAUSE = 0x08; + static const MIDIByte MIDI_MMC_PAUSE = 0x08; + static const MIDIByte MIDI_MMC_EJECT = 0x0A; + static const MIDIByte MIDI_MMC_LOCATE = 0x44; + static const MIDIByte MIDI_FILE_META_EVENT = 0xFF; + static const MIDIByte MIDI_SEQUENCE_NUMBER = 0x00; + static const MIDIByte MIDI_TEXT_EVENT = 0x01; + static const MIDIByte MIDI_COPYRIGHT_NOTICE = 0x02; + static const MIDIByte MIDI_TRACK_NAME = 0x03; + static const MIDIByte MIDI_INSTRUMENT_NAME = 0x04; + static const MIDIByte MIDI_LYRIC = 0x05; + static const MIDIByte MIDI_TEXT_MARKER = 0x06; + static const MIDIByte MIDI_CUE_POINT = 0x07; + static const MIDIByte MIDI_CHANNEL_PREFIX = 0x20; + static const MIDIByte MIDI_CHANNEL_PREFIX_OR_PORT = 0x21; + static const MIDIByte MIDI_END_OF_TRACK = 0x2F; + static const MIDIByte MIDI_SET_TEMPO = 0x51; + static const MIDIByte MIDI_SMPTE_OFFSET = 0x54; + static const MIDIByte MIDI_TIME_SIGNATURE = 0x58; + static const MIDIByte MIDI_KEY_SIGNATURE = 0x59; + static const MIDIByte MIDI_SEQUENCER_SPECIFIC = 0x7F; + static const MIDIByte MIDI_CONTROLLER_BANK_MSB = 0x00; + static const MIDIByte MIDI_CONTROLLER_VOLUME = 0x07; + static const MIDIByte MIDI_CONTROLLER_BANK_LSB = 0x20; + static const MIDIByte MIDI_CONTROLLER_MODULATION = 0x01; + static const MIDIByte MIDI_CONTROLLER_PAN = 0x0A; + static const MIDIByte MIDI_CONTROLLER_SUSTAIN = 0x40; + static const MIDIByte MIDI_CONTROLLER_RESONANCE = 0x47; + static const MIDIByte MIDI_CONTROLLER_RELEASE = 0x48; + static const MIDIByte MIDI_CONTROLLER_ATTACK = 0x49; + static const MIDIByte MIDI_CONTROLLER_FILTER = 0x4A; + static const MIDIByte MIDI_CONTROLLER_REVERB = 0x5B; + static const MIDIByte MIDI_CONTROLLER_CHORUS = 0x5D; + static const MIDIByte MIDI_CONTROLLER_NRPN_1 = 0x62; + static const MIDIByte MIDI_CONTROLLER_NRPN_2 = 0x63; + static const MIDIByte MIDI_CONTROLLER_RPN_1 = 0x64; + static const MIDIByte MIDI_CONTROLLER_RPN_2 = 0x65; + static const MIDIByte MIDI_CONTROLLER_SOUNDS_OFF = 0x78; + static const MIDIByte MIDI_CONTROLLER_RESET = 0x79; + static const MIDIByte MIDI_CONTROLLER_LOCAL = 0x7A; + static const MIDIByte MIDI_CONTROLLER_ALL_NOTES_OFF = 0x7B; + static const MIDIByte MIDI_PERCUSSION_CHANNEL = 9; + + typedef enum { + MIDI_SINGLE_TRACK_FILE = 0x00, + MIDI_SIMULTANEOUS_TRACK_FILE = 0x01, + MIDI_SEQUENTIAL_TRACK_FILE = 0x02, + MIDI_FILE_BAD_FORMAT = 0xFF + } MIDIFileFormatType; +} + +class MIDIEvent +{ +public: + MIDIEvent(unsigned long deltaTime, + MIDIByte eventCode, + MIDIByte data1 = 0, + MIDIByte data2 = 0) : + m_deltaTime(deltaTime), + m_duration(0), + m_eventCode(eventCode), + m_data1(data1), + m_data2(data2), + m_metaEventCode(0) + { } + + MIDIEvent(unsigned long deltaTime, + MIDIByte eventCode, + MIDIByte metaEventCode, + const std::string &metaMessage) : + m_deltaTime(deltaTime), + m_duration(0), + m_eventCode(eventCode), + m_data1(0), + m_data2(0), + m_metaEventCode(metaEventCode), + m_metaMessage(metaMessage) + { } + + MIDIEvent(unsigned long deltaTime, + MIDIByte eventCode, + const std::string &sysEx) : + m_deltaTime(deltaTime), + m_duration(0), + m_eventCode(eventCode), + m_data1(0), + m_data2(0), + m_metaEventCode(0), + m_metaMessage(sysEx) + { } + + ~MIDIEvent() { } + + void setTime(const unsigned long &time) { m_deltaTime = time; } + void setDuration(const unsigned long& duration) { m_duration = duration;} + unsigned long addTime(const unsigned long &time) { + m_deltaTime += time; + return m_deltaTime; + } + + int getMessageType() const + { return (m_eventCode & MIDIConstants::MIDI_MESSAGE_TYPE_MASK); } + + int getChannelNumber() const + { return (m_eventCode & MIDIConstants::MIDI_CHANNEL_NUM_MASK); } + + unsigned long getTime() const { return m_deltaTime; } + unsigned long getDuration() const { return m_duration; } + + int getPitch() const { return m_data1; } + int getVelocity() const { return m_data2; } + int getData1() const { return m_data1; } + int getData2() const { return m_data2; } + int getEventCode() const { return m_eventCode; } + + bool isMeta() const { return (m_eventCode == MIDIConstants::MIDI_FILE_META_EVENT); } + + int getMetaEventCode() const { return m_metaEventCode; } + std::string getMetaMessage() const { return m_metaMessage; } + void setMetaMessage(const std::string &meta) { m_metaMessage = meta; } + + friend bool operator<(const MIDIEvent &a, const MIDIEvent &b); + +private: + unsigned long m_deltaTime; + unsigned long m_duration; + MIDIByte m_eventCode; + MIDIByte m_data1; // or Note + MIDIByte m_data2; // or Velocity + MIDIByte m_metaEventCode; + std::string m_metaMessage; +}; + +// Comparator for sorting +// +struct MIDIEventCmp +{ + bool operator()(const MIDIEvent &mE1, const MIDIEvent &mE2) const + { return mE1.getTime() < mE2.getTime(); } + + bool operator()(const MIDIEvent *mE1, const MIDIEvent *mE2) const + { return mE1->getTime() < mE2->getTime(); } +}; + +class MIDIException : virtual public std::exception +{ +public: + MIDIException(std::string message) throw() : m_message(message) { + std::cerr << "WARNING: MIDI exception: " << message.c_str() << std::endl; + } + virtual ~MIDIException() throw() { } + + virtual const char *what() const throw() { + return m_message.c_str(); + } + +protected: + std::string m_message; +}; + +#endif