midi.h

Go to the documentation of this file.
00001 /*
00002  * midi.h
00003  *
00004  * Copyright 2002 Thomas A. Vaughan
00005  * All rights reserved.
00006  *
00007  * Header file for the MIDI library.
00008  */
00009 
00010 #ifndef __MEDIA_MIDI_H__
00011 #define __MEDIA_MIDI_H__
00012 
00013 
00014 // includes --------------------------------------------------------------------
00015 #include "common/common.h"
00016 
00017 
00018 // namespace
00019 namespace media {
00020 
00021 
00022 ////////////////////////////////////////////////////////////////////////////////
00023 //
00024 //      MIDI objects
00025 //
00026 ////////////////////////////////////////////////////////////////////////////////
00027 
00028 /*
00029  * class MidiEvent
00030  *
00031  * Generic structure for all (non-sysex) midi messages
00032  */
00033 class MidiEvent {
00034 public:
00035         // public typedefs -----------------------------------------------------
00036         enum eStatus {
00037                 eNoteOff        = 0x8,  // note off event
00038                 eNoteOn         = 0x9,  // note on event
00039                 eNoteAfter      = 0xa,  // note aftertouch event
00040                 eControl        = 0xb,  // control change event
00041                 eProgram        = 0xc,  // program change event
00042                 eChannelAfter   = 0xd,  // channel aftertouch event
00043                 ePitch          = 0xe,  // pitch bend event
00044                 eSystem         = 0xf,  // system exclusive event
00045                 eInvalid        = 0x0   // invalid event value
00046         };
00047 
00048         // MidiEvent constructor, destructor -----------------------------------
00049         MidiEvent(void) throw() : m_status(0) { }       // invalid status
00050         MidiEvent(IN const MidiEvent& event) throw() {
00051                         *this = event;
00052                 }
00053 
00054         // MidiEvent class methods ---------------------------------------------
00055         eStatus GetStatus(void) const throw();
00056         byte_t  GetChannel(void) const throw();
00057         byte_t  GetByte0(void) const throw();
00058         byte_t  GetByte1(void) const throw();
00059         byte_t  GetNote(void) const throw();
00060         byte_t  GetVelocity(void) const throw();
00061         byte_t  GetControlNumber(void) const throw();
00062         byte_t  GetControlValue(void) const throw();
00063         byte_t  GetPatch(void) const throw();
00064         byte_t  GetPressure(void) const throw();
00065         word_t  GetPitch(void) const throw();
00066 
00067         const MidiEvent& operator = (IN const MidiEvent& event) throw() {
00068                         m_status = event.m_status;
00069                         m_word = event.m_word;
00070                         return *this;
00071                 }
00072 
00073         static bool IsValidStatus(IN eStatus status) throw();
00074         static int GetDataByteCount(IN eStatus status) throw();
00075 
00076         void    SetStatus(IN eStatus status) throw();
00077         void    SetChannel(IN int channel) throw();
00078         void    SetByte0(IN byte_t b0) throw() { m_data[0] = b0; }
00079         void    SetByte1(IN byte_t b1) throw() { m_data[1] = b1; }
00080         void    SetWord(IN word_t w) throw() { m_word = w; }
00081 
00082 protected:
00083         // private data members ------------------------------------------------
00084         byte_t  m_status;       // status byte
00085         byte_t  m_unused;       // unused, kept to preserve DWORD/WORD alignment
00086 
00087         union {
00088                 byte_t  m_data[2];      // data bytes
00089                 word_t  m_word;         // bytes as word
00090         };
00091 };
00092 
00093 
00094 
00095 /*
00096  * class MidiReceiver
00097  *
00098  * Someone who wants to receive midi events
00099  */
00100 class MidiReceiver {
00101 public:
00102         // media::MidiReceiver class interface methods -------------------------
00103         virtual void NotifyEvent(IN const MidiEvent& event) = 0;
00104 
00105 protected:
00106         // protected d'tor: you can't delete() one of these directly -----------
00107         virtual ~MidiReceiver(void) throw() { }
00108 };
00109 
00110 
00111 
00112 ////////////////////////////////////////////////////////////////////////////////
00113 //
00114 //      MIDI functions
00115 //
00116 ////////////////////////////////////////////////////////////////////////////////
00117 
00118 // Parsing routines
00119 void ParseMidi(IN MidiReceiver * receiver, IN const byte_t * buffer,
00120                 IN long bytes, OUT long * offset); 
00121 
00122 // Printing routines
00123 void PrintEvent(IN FILE * output, IN const MidiEvent& event) throw();
00124 
00125 
00126 
00127 
00128 ////////////////////////////////////////////////////////////////////////////////
00129 //
00130 //      Inline functions (nothing interesting for clients beyond this point)
00131 //
00132 ////////////////////////////////////////////////////////////////////////////////
00133 
00134 inline MidiEvent::eStatus
00135 MidiEvent::GetStatus(void)
00136 const throw()
00137 {
00138         return (MidiEvent::eStatus) ((m_status >> 4) & 0xf);
00139 }
00140 
00141 
00142 inline byte_t
00143 MidiEvent::GetChannel(void)
00144 const throw()
00145 {
00146         return m_status & 0xf;
00147 }
00148 
00149 
00150 inline void
00151 MidiEvent::SetStatus(IN eStatus status)
00152 throw()
00153 {
00154         ASSERT(IsValidStatus(status), "Invalid status");
00155         m_status = (m_status & 0x0f) + (status << 4);
00156 }
00157 
00158 
00159 inline void
00160 MidiEvent::SetChannel(IN int channel)
00161 throw()
00162 {
00163         ASSERT(channel >=0 && channel < 16, "Invalid channel");
00164         m_status = (m_status & 0xf0) + (channel & 0x0f);
00165 }
00166 
00167 
00168 inline byte_t
00169 MidiEvent::GetByte0(void)
00170 const throw()
00171 {
00172         return m_data[0];
00173 }
00174 
00175 
00176 inline byte_t
00177 MidiEvent::GetByte1(void)
00178 const throw()
00179 {
00180         return m_data[1];
00181 }
00182 
00183 
00184 inline byte_t
00185 MidiEvent::GetNote(void)
00186 const throw()
00187 {
00188         return m_data[0];
00189 }
00190 
00191 
00192 inline byte_t
00193 MidiEvent::GetVelocity(void)
00194 const throw()
00195 {
00196         return m_data[1];
00197 }
00198 
00199 
00200 inline byte_t
00201 MidiEvent::GetControlNumber(void)
00202 const throw()
00203 {
00204         return m_data[0];
00205 }
00206 
00207 
00208 inline byte_t
00209 MidiEvent::GetControlValue(void)
00210 const throw()
00211 {
00212         return m_data[1];
00213 }
00214 
00215 
00216 inline byte_t
00217 MidiEvent::GetPatch(void)
00218 const throw()
00219 {
00220         return m_data[0];
00221 }
00222 
00223 
00224 inline byte_t
00225 MidiEvent::GetPressure(void)
00226 const throw()
00227 {
00228         return m_data[0];
00229 }
00230 
00231 
00232 inline word_t
00233 MidiEvent::GetPitch(void)
00234 const throw()
00235 {
00236         return m_word;
00237 }
00238 
00239 
00240 };      // end of media namespace
00241 
00242 
00243 #endif  // __MEDIA_MIDI_H__