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