Main Page | Namespace List | Class Hierarchy | Alphabetical List | Compound List | File List | Namespace Members | Compound Members | File Members

/home/pete/Work/TSE3.svn/tse3/src/tse3/Midi.h

Go to the documentation of this file.
00001 /*
00002  * @(#)Midi.h 3.00 14 May 1999
00003  *
00004  * Copyright (c) 2000 Pete Goodliffe (pete@cthree.org)
00005  *
00006  * This file is part of TSE3 - the Trax Sequencer Engine version 3.00.
00007  *
00008  * This library is modifiable/redistributable under the terms of the GNU
00009  * General Public License.
00010  *
00011  * You should have received a copy of the GNU General Public License along
00012  * with this program; see the file COPYING. If not, write to the Free Software
00013  * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
00014  *
00015  */
00016 
00017 #ifndef TSE3_MIDI_H
00018 #define TSE3_MIDI_H
00019 
00020 namespace TSE3
00021 {
00039     struct Clock
00040     {
00044         static const int PPQN = 96;
00045 
00051         Clock(int pulses = 0) : pulses(pulses)   {}
00052         Clock(const Clock &m) : pulses(m.pulses) {}
00053 
00060         int beat() const { return pulses / PPQN; }
00061 
00069         int pulse() const { return pulses % PPQN; }
00070 
00074         int pulses;
00075 
00083         static Clock convert(Clock time, int otherPPQN)
00084         {
00085             return (time * Clock::PPQN) / otherPPQN;
00086         }
00087 
00088         /*
00089          * Dull stuff to make Clock behave like the ints do.
00090          */
00091 
00092         operator int() const { return pulses; }
00093 
00094         const Clock operator+(const Clock &c)
00095         {
00096             Clock ret;
00097             ret.pulses = pulses + c.pulses;
00098             return ret;
00099         }
00100         const Clock operator+(int i)
00101         {
00102             Clock ret;
00103             ret.pulses = pulses + i;
00104             return ret;
00105         }
00106         Clock operator+=(const Clock &c)
00107         {
00108             pulses += c.pulses;
00109             return *this;
00110         }
00111         const Clock operator-(const Clock &c)
00112         {
00113             Clock ret;
00114             ret.pulses = pulses - c.pulses;
00115             return ret;
00116         }
00117         const Clock operator-(int i)
00118         {
00119             Clock ret;
00120             ret.pulses = pulses - i;
00121             return ret;
00122         }
00123         Clock operator-=(const Clock &c)
00124         {
00125             pulses -= c.pulses;
00126             return *this;
00127         }
00128         const Clock operator*(const Clock &c)
00129         {
00130             Clock ret;
00131             ret.pulses = pulses * c.pulses;
00132             return ret;
00133         }
00134         const Clock operator*(int i)
00135         {
00136             Clock ret;
00137             ret.pulses = pulses * i;
00138             return ret;
00139         }
00140         Clock operator*=(const Clock &c)
00141         {
00142             pulses *= c.pulses;
00143             return *this;
00144         }
00145         Clock operator*=(int i)
00146         {
00147             pulses *= i;
00148             return *this;
00149         }
00150         const Clock operator/(const Clock &c)
00151         {
00152             Clock ret;
00153             ret.pulses = pulses / c.pulses;
00154             return ret;
00155         }
00156         const Clock operator/(int i)
00157         {
00158             Clock ret;
00159             ret.pulses = pulses / i;
00160             return ret;
00161         }
00162         Clock operator/=(const Clock &c)
00163         {
00164             pulses /= c.pulses;
00165             return *this;
00166         }
00167         Clock operator/=(int i)
00168         {
00169             pulses /= i;
00170             return *this;
00171         }
00172         const Clock operator%(const Clock &c)
00173         {
00174             Clock ret;
00175             ret.pulses = pulses % c.pulses;
00176             return ret;
00177         }
00178         const Clock operator%(int i)
00179         {
00180             Clock ret;
00181             ret.pulses = pulses % i;
00182             return ret;
00183         }
00184         Clock operator%=(const Clock &c)
00185         {
00186             pulses %= c.pulses;
00187             return *this;
00188         }
00189         Clock operator%=(int i)
00190         {
00191             pulses %= i;
00192             return *this;
00193         }
00194     };
00195 
00214     template <class etype>
00215     struct Event
00216     {
00217         typedef etype event_type;
00218 
00225         Event(etype data, Clock time) : data(data), time(time) {}
00226 
00230         etype data;
00231 
00235         Clock time;
00236 
00241         int operator<(const Event<etype> &e) const
00242         {
00243             return time.pulses < e.time.pulses;
00244         }
00245 
00250         int operator<=(const Event<etype> &e) const
00251         {
00252             return time.pulses <= e.time.pulses;
00253         }
00254 
00259         int operator>(const Event<etype> &e) const
00260         {
00261             return time.pulses > e.time.pulses;
00262         }
00263 
00268         int operator>=(const Event<etype> &e) const
00269         {
00270             return time.pulses >= e.time.pulses;
00271         }
00272 
00277         int operator==(const Event<etype> &e) const
00278         {
00279             return time.pulses == e.time.pulses;
00280         }
00281 
00286         bool equals(const Event<etype> &e) const
00287         {
00288             return (*this == e) && data == e.data;
00289         }
00290 
00297         class equal_to
00298         {
00299             public:
00300                 equal_to(const Event<etype> &e) : e1(e) {}
00301                 bool operator()(const Event<etype> &e2) const
00302                 {
00303                     return e1.equals(e2);
00304                 }
00305             private:
00306                 const Event<etype> &e1;
00307         };
00308     };
00309 
00310 
00311     /**************************************************************************
00312      * A selection of useful MIDI command definitions.
00313      *************************************************************************/
00314 
00350     enum MidiCommands
00351     {
00352         // Channel messages
00353         MidiCommand_NoteOff             = 0x8,
00354         MidiCommand_NoteOn              = 0x9,
00355         MidiCommand_KeyPressure         = 0xa,
00356         MidiCommand_ControlChange       = 0xb,
00357         MidiCommand_ProgramChange       = 0xc,
00358         MidiCommand_ChannelPressure     = 0xd,
00359         MidiCommand_PitchBend           = 0xe,
00360         MidiCommand_System              = 0xf,
00361 
00362         // Meta MIDI messages
00363         MidiCommand_Invalid             = 0x0,
00364         MidiCommand_TSE_Meta            = 0x1,
00365         MidiCommand_NoteEdit_Meta       = 0x2
00366     };
00367 
00390     enum TSEMetaMidiCommands
00391     {
00392         MidiCommand_TSE_Meta_Tempo      = 0x00,
00393         MidiCommand_TSE_Meta_TimeSig    = 0x01,
00394         MidiCommand_TSE_Meta_KeySig     = 0x02,
00395         MidiCommand_TSE_Meta_MoveTo     = 0x03
00396     };
00397 
00404     extern unsigned int MidiCommand_NoDataBytes[];
00405 
00412     enum MidiSystemCommands
00413     {
00414         MidiSystem_SysExStart           = 0x0,
00415         MidiSystem_MidiTimeCode         = 0x1,
00416         MidiSystem_SongPosition         = 0x2,
00417         MidiSystem_SongSelect           = 0x3,
00418         MidiSystem_TuneRequest          = 0x6,
00419         MidiSystem_SysExEnd             = 0x7,
00420         MidiSystem_TimingClock          = 0x8,
00421         MidiSystem_Start                = 0xa,
00422         MidiSystem_Continue             = 0xb,
00423         MidiSystem_Stop                 = 0xc,
00424         MidiSystem_ActiveSensing        = 0xe,
00425         MidiSystem_SystemReset          = 0xf
00426     };
00427 
00437     enum MidiControlChanges
00438     {
00439         MidiControl_BankSelectMSB       = 0x00,
00440         MidiControl_ModulationMSB       = 0x01,
00441         MidiControl_BreathControllerMSB = 0x02,
00442         MidiControl_FootController      = 0x04,
00443         MidiControl_PortamentoTimeMSB   = 0x05,
00444         MidiControl_DataEntryMSB        = 0x06,
00445         MidiControl_ChannelVolumeMSB    = 0x07,
00446         MidiControl_BalanceMSB          = 0x08,
00447         MidiControl_PanMSB              = 0x0a,
00448         MidiControl_ExpressionCtrlMSB   = 0x0b,
00449         MidiControl_EffectCtrl1MSB      = 0x0c,
00450         MidiControl_EffectCtrl2MSB      = 0x0d,
00451         MidiControl_GeneralCtrl1MSB     = 0x10,
00452         MidiControl_GeneralCtrl2MSB     = 0x11,
00453         MidiControl_GeneralCtrl3MSB     = 0x12,
00454         MidiControl_GeneralCtrl4MSB     = 0x13,
00455 
00456         MidiControl_BankSelectLSB       = 0x20,
00457         MidiControl_ModulationLSB       = 0x21,
00458         MidiControl_BreathControllerLSB = 0x22,
00459         MidiControl_FootControlLer      = 0x24,
00460         MidiControl_PortamentoTimeLSB   = 0x25,
00461         MidiControl_DataEntryLSB        = 0x26,
00462         MidiControl_ChannelVolumeLSB    = 0x27,
00463         MidiControl_BalanceLSB          = 0x28,
00464         MidiControl_PanLSB              = 0x2a,
00465         MidiControl_ExpressionCtrlLSB   = 0x2b,
00466         MidiControl_EffectCtrl1LSB      = 0x2c,
00467         MidiControl_EffectCtrl2LSB      = 0x2d,
00468         MidiControl_GeneralCtrl1LSB     = 0x30,
00469         MidiControl_GeneralCtrl2LSB     = 0x31,
00470         MidiControl_GeneralCtrl3LSB     = 0x32,
00471         MidiControl_GeneralCtrl4LSB     = 0x33,
00472 
00473         MidiControl_SustainPedal        = 0x40,
00474         MidiControl_Portamento          = 0x41,
00475         MidiControl_Sostenuto           = 0x42,
00476         MidiControl_SoftPedal           = 0x43,
00477         MidiControl_Legato              = 0x44,
00478         MidiControl_Hold2               = 0x45,
00479 
00480         MidiControl_SoundVariationLSB   = 0x46,
00481         MidiControl_Timbre              = 0x47,
00482         MidiControl_ReleaseTime         = 0x48,
00483         MidiControl_AttackTime          = 0x49,
00484         MidiControl_Brightness          = 0x4a,
00485 
00486         MidiControl_GeneralCtrl5        = 0x50,
00487         MidiControl_GeneralCtrl6        = 0x51,
00488         MidiControl_GeneralCtrl7        = 0x52,
00489         MidiControl_GeneralCtrl8        = 0x53,
00490         MidiControl_PortamentoSource    = 0x54,
00491         MidiControl_ReverbDepth         = 0x5b,
00492         MidiControl_TremoloDepth        = 0x5c,
00493         MidiControl_ChorusDepth         = 0x5d,
00494         MidiControl_CelesteDepth        = 0x5e,
00495         MidiControl_PhaserDepth         = 0x5f,
00496         MidiControl_DataIncrement       = 0x60,
00497         MidiControl_DataDecrement       = 0x61,
00498         MidiControl_NRPM_LSB            = 0x62,
00499         MidiControl_NRPM_MSB            = 0x63,
00500         MidiControl_RPM_LSB             = 0x64,
00501         MidiControl_RPM_MSB             = 0x65,
00502 
00503         MidiControl_AllSoundOff         = 0x78,
00504         MidiControl_ResetAllControllers = 0x79,
00505         MidiControl_LocalControl        = 0x7a,
00506         MidiControl_AllNotesOff         = 0x7b,
00507         MidiControl_OmniModeOff         = 0x7c,
00508         MidiControl_OmniModeOn          = 0x7d,
00509         MidiControl_MonoModeOn          = 0x7e,
00510         MidiControl_PolyModeOn          = 0x7f
00511     };
00512 
00524     struct MidiCommand
00525     {
00535         MidiCommand(int status, int channel, int port,
00536                     int data1, int data2)
00537             : port(port), status(status), channel(channel),
00538               data1(data1), data2(data2), selected(0) {}
00539 
00548         MidiCommand(int status, int channel, int port,
00549                     int data1)
00550             : port(port), status(status), channel(channel),
00551               data1(data1), data2(0), selected(0) {}
00552 
00556         MidiCommand()
00557             : port(0), status(MidiCommand_Invalid), channel(0),
00558               data1(0), data2(0), selected(0) {}
00559 
00565         int noDataBytes() const
00566         {
00567             return MidiCommand_NoDataBytes[status << 4];
00568         }
00569 
00575         bool isChannel() const
00576         {
00577             return (status >= MidiCommand_NoteOn
00578                     && status <= MidiCommand_PitchBend);
00579         }
00580 
00586         bool isNote() const
00587         {
00588             return (status >= MidiCommand_NoteOff
00589                     && status <= MidiCommand_KeyPressure);
00590         }
00591 
00597         int port;
00598 
00602         unsigned status   : 4;
00603 
00607         signed channel  : 5;
00608 
00612         unsigned data1    : 8;
00613 
00617         unsigned data2    : 8;
00618 
00624         unsigned selected : 1;
00625 
00630         enum MagicPortNumbers
00631         {
00632             NoPort   = -1,
00633             AllPorts = -2,
00634             SamePort = -3
00635         };
00636 
00641         enum MagicChannelNumbers
00642         {
00643             NoChannel   = -1,
00644             AllChannels = -2,
00645             SameChannel = -3
00646         };
00647 
00652         int operator==(const MidiCommand &c) const
00653         {
00654             return channel == c.channel
00655                    && status == c.status
00656                    && data1  == c.data1
00657                    && data2  == c.data2
00658                    && port   == c.port;
00659         }
00660     };
00661 
00662 
00688     struct MidiEvent
00689     {
00690         MidiEvent()
00691         : data(MidiCommand()), time(0), offData(MidiCommand()), offTime(0) {}
00692 
00701         MidiEvent(MidiCommand mc, Clock t)
00702         : data(mc), time(t), offData(MidiCommand()), offTime(0) {}
00703 
00715         MidiEvent(MidiCommand mc, Clock t, MidiCommand oc, Clock ot)
00716         : data(mc), time(t), offData(oc), offTime(ot) {}
00717 
00730         MidiEvent(MidiCommand mc, Clock t, int offVel, Clock ot)
00731         : data(mc), time(t), offData(mc), offTime(ot)
00732         {
00733             offData.status = MidiCommand_NoteOff;
00734             offData.data2 = offVel;
00735         }
00736 
00740         MidiCommand data;
00741 
00745         Clock time;
00746 
00751         MidiCommand offData;
00752 
00757         Clock offTime;
00758 
00759         /*
00760          * This comparison operator only compares event times, NOT the data
00761          * contents.
00762          */
00763         int operator<(const MidiEvent &e) const { return time < e.time; }
00764 
00769         int operator<=(const MidiEvent &e) const { return time <= e.time; }
00770 
00771         /*
00772          * This comparison operator only compares event times, NOT the data
00773          * contents.
00774          */
00775         int operator>(const MidiEvent &e) const { return time > e.time; }
00776 
00781         int operator>=(const MidiEvent &e) const { return time >= e.time; }
00782 
00787         int operator==(const MidiEvent &e) const { return time == e.time; }
00788 
00793         int operator!=(const MidiEvent &e) const { return time != e.time; }
00794 
00799         bool equals(const MidiEvent &e) const
00800         {
00801             return (time == e.time) && (data == e.data);
00802             // XXX: what about MidiCommand_NoteOffs ???
00803         }
00804 
00810         class equal_to
00811         {
00812             public:
00813                 equal_to(const MidiEvent &e) : e1(e) {}
00814                 bool operator()(const MidiEvent &e2) const
00815                 {
00816                     return e1.equals(e2);
00817                 }
00818             private:
00819                 const MidiEvent &e1;
00820         };
00821     };
00822 };
00823 
00824 #endif

Generated on Wed May 25 14:45:08 2005 for TSE3 by doxygen 1.3.2