Bernard Escaillas
/
MidiTee
midi.h
- Committer:
- Midimetric
- Date:
- 2011-06-07
- Revision:
- 0:71d791204057
File content as of revision 0:71d791204057:
#ifndef MIDI_H #define MIDI_H #include <vector> #ifndef BYTE #define BYTE typedef unsigned char byte; #endif #ifndef WORD #define WORD typedef unsigned short word; #endif // unused midi code serves as defining 'Not A Known Value': #define NAKN 253 // out of 14bit range value serves as defining 'Not A Known Word': #define NAKW 0x5000 // generic: #define NONE 0 // values for member 'next': #define VALA 1 #define VALB 2 #define MSB 3 #define LSB 4 #define PAIR 5 #define ITEM 6 #define MSB2 7 #define LSB2 8 // values for member 'type': // channel message: #define NOTE 1 #define POLA 2 #define CTRL 3 #define PROG 4 #define BANK 5 #define DATA 6 #define INCR 7 #define DECR 8 #define RPN_ 9 #define NRPN 10 #define MONA 11 #define BEND 12 // no channel message: #define SYSX 13 #define TCOD 14 #define SPOS 15 #define SSEL 16 #define TUNE 17 #define CLOK 18 #define STAR 19 #define CONT 20 #define STOP 21 #define SENS 22 #define RSET 23 /////////////////////////////////////////////////////////////////////////////// // base class for all Messages //_____________________________________________________________________________ class MidiM {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: byte Command; byte Type; byte Channel; byte Next; // expected type of next inconming byte byte ValA; // data byte ValB; // data vector<byte> Raw; MidiM( byte type ) : Command(0), Type( type ), Channel( NAKN ), Next(NONE), ValA(NAKN), ValB(NAKN) {} MidiM( byte type, byte ch ) : Command(0), Type( type ), Channel( ch ), Next(NONE), ValA(NAKN), ValB(NAKN) {} virtual ~MidiM(){} virtual bool Append( byte b) { Raw.push_back(b); return true; } virtual byte ValCount() { return 0; } short Get14() { return ( ValA == NAKN ? 0 : ValA << 7 ) + ( ValB == NAKN ? 0 : ValB ); } void Set14( short v ) { ValA = ( v >> 7 ) & 127; ValB = v & 127; Next = NONE; } }; //_____________________________________________________________________________ class MidiTune : public MidiM {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiTune() : MidiM( TUNE ) { Raw.push_back( Command = 0xF6 ); } virtual ~MidiTune(){} // virtual void Send( Serial &s ) { s.putc( 0xF6 ); } }; //_____________________________________________________________________________ class MidiClock : public MidiM {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiClock() : MidiM( CLOK ) { Raw.push_back( Command = 0xF8 ); } virtual ~MidiClock(){} // virtual void Send( Serial &s ) { s.putc( 0xF8 ); } }; //_____________________________________________________________________________ class MidiStart : public MidiM {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiStart() : MidiM( STAR ) { Raw.push_back( Command = 0xFA ); } virtual ~MidiStart(){} // virtual void Send( Serial &s ) { s.putc( 0xFA ); } }; //_____________________________________________________________________________ class MidiContinue : public MidiM {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiContinue() : MidiM( CONT ) { Raw.push_back( Command = 0xFB ); } virtual ~MidiContinue(){} // virtual void Send( Serial &s ) { s.putc( 0xFB ); } }; //_____________________________________________________________________________ class MidiStop : public MidiM {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiStop() : MidiM( STOP ) { Raw.push_back( Command = 0xFC ); } virtual ~MidiStop(){} // virtual void Send( Serial &s ) { s.putc( 0xFC ); } }; //_____________________________________________________________________________ class MidiSensing : public MidiM {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiSensing() : MidiM( SENS ) { Raw.push_back( Command = 0xFE ); } virtual ~MidiSensing(){} // virtual void Send( Serial &s ) { s.putc( 0xFE ); } }; //_____________________________________________________________________________ class MidiReset : public MidiM {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiReset() : MidiM( RSET ) { Raw.push_back( Command = 0xFF ); } virtual ~MidiReset(){} // virtual void Send( Serial &s ) { s.putc( 0xFF ); } }; /////////////////////////////////////////////////////////////////////////////// // base class & derived classes for all Messages having 1 byte of data //_____________________________________________________________________________ class MidiM1 : public MidiM {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiM1( byte type, byte ch ) : MidiM( type, ch ) { Next = VALA; } MidiM1( byte type, byte ch, byte v ) : MidiM( type, ch ) { Next = NONE; ValA = v; } virtual ~MidiM1(){} virtual bool Append( byte b ) { Raw.push_back(b); if( b > 127 || Next == NONE ) return false; Next = NONE; ValA = b; return true; } virtual byte ValCount() { return 1; } }; //_____________________________________________________________________________ class MidiSelect : public MidiM1 {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiSelect() : MidiM1( SSEL, NAKN ) { Raw.push_back( Command = 0xF3 ); } MidiSelect( byte v ) : MidiM1( SSEL, NAKN, v ) { Raw.push_back( Command = 0xF3 ); } virtual ~MidiSelect(){} // virtual void Send( Serial &s ) { s.putc( 0xF3 ); s.putc( ValA ); } }; //_____________________________________________________________________________ class MidiTimeCode : public MidiM1 {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiTimeCode() : MidiM1( TCOD, NAKN ) { Raw.push_back( Command = 0xF1 ); } MidiTimeCode( byte v ) : MidiM1( TCOD, NAKN, v ) { Raw.push_back( Command = 0xF1 ); } virtual ~MidiTimeCode(){} // virtual void Send( Serial &s ) { s.putc( 0xF1 ); s.putc( ValA ); } }; //_____________________________________________________________________________ class MidiProgram : public MidiM1 {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiProgram( byte ch ) : MidiM1( PROG, ch ) { Raw.push_back( ( Command = 0xC0 ) + ch ); } MidiProgram( byte ch, byte v ) : MidiM1( PROG, ch, v ){ Raw.push_back( ( Command = 0xC0 ) + ch ); } virtual ~MidiProgram(){} // virtual void Send( Serial &s ){ s.putc( 0xC0 + Channel ); s.putc( ValA ); } }; //_____________________________________________________________________________ class MidiMonoAft : public MidiM1 {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiMonoAft( byte ch ) : MidiM1( MONA, ch ) { Raw.push_back( ( Command = 0xD0 ) + ch ); } MidiMonoAft( byte ch, byte v ) : MidiM1( MONA, ch, v ){ Raw.push_back( ( Command = 0xD0 ) + ch ); } virtual ~MidiMonoAft(){} // virtual void Send( Serial &s ){ s.putc( 0xD0 + Channel ); s.putc( ValA ); } }; /////////////////////////////////////////////////////////////////////////////// // base class & derived classes for all Messages having 2 byte of data //_____________________________________________________________________________ class MidiM2 : public MidiM {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiM2(byte type,byte ch) : MidiM(type,ch){ Next = VALA; } MidiM2(byte type,byte ch,byte v) : MidiM(type,ch){Next=VALB;ValA=v;} MidiM2(byte type,byte ch,byte v,byte w): MidiM(type,ch){Next=NONE;ValA=v;ValB=w;} virtual ~MidiM2(){} virtual byte ValCount() { return 2; } virtual bool Append( byte b ) { Raw.push_back(b); if( b > 127 || Next == NONE ) return false; if( Next == VALA ) { ValA = b; Next = VALB; } else { ValB = b; Next = NONE; } return true; } }; //_____________________________________________________________________________ class MidiPosition : public MidiM2 {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiPosition() : MidiM2( SPOS, NAKN ) { Raw.push_back( Command = 0xF3 ); } MidiPosition( byte v ) : MidiM2( SPOS, NAKN, v ) { Raw.push_back( Command = 0xF3 ); } MidiPosition( byte v, byte w ) : MidiM2( SPOS, NAKN, v, w ) { Command = 0xF3; } virtual ~MidiPosition(){} // virtual void Send( Serial &s ){ s.putc(0xF3); s.putc(ValA); s.putc(ValB); } }; //_____________________________________________________________________________ class MidiNoteOn : public MidiM2 {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiNoteOn( byte ch ) : MidiM2( NOTE, ch ) { Raw.push_back( ( Command = 0x90 ) + ch ); } MidiNoteOn( byte ch, byte v ): MidiM2( NOTE, ch, v ) { Raw.push_back( ( Command = 0x90 ) + ch ); } MidiNoteOn( byte ch, byte v, byte w ) : MidiM2( NOTE, ch, v, w ) { Command = 0x90; } virtual ~MidiNoteOn(){} /* virtual void Send( Serial &s ) { s.putc( 0x90 + Channel ); s.putc( ValA ); s.putc( ValB ); }*/ }; //_____________________________________________________________________________ class MidiNoteOff : public MidiM2 {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiNoteOff( byte ch ) : MidiM2( NOTE, ch ) { Raw.push_back( ( Command = 0x80 ) + ch ); } MidiNoteOff( byte ch, byte v ): MidiM2( NOTE, ch, v ) { Raw.push_back( ( Command = 0x80 ) + ch ); } MidiNoteOff( byte ch, byte v, byte w ): MidiM2( NOTE, ch, v, w ) { Command = 0x80; } virtual ~MidiNoteOff(){} /* virtual void Send( Serial &s ) { s.putc( 0x80 + Channel ); s.putc( ValA ); s.putc( ValB ); }*/ }; //_____________________________________________________________________________ class MidiPolyAft : public MidiM2 {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiPolyAft( byte ch ) : MidiM2( POLA, ch ) { Raw.push_back( ( Command = 0xA0 ) + ch ); } MidiPolyAft( byte ch, byte v ): MidiM2( POLA, ch, v ) { Raw.push_back( ( Command = 0xA0 ) + ch ); } MidiPolyAft( byte ch, byte v, byte w ): MidiM2( POLA, ch, v, w ) { Command = 0xA0; } virtual ~MidiPolyAft(){} /* virtual void Send( Serial &s ) { s.putc( 0xA0 + Channel ); s.putc( ValA ); s.putc( ValB ); }*/ }; //_____________________________________________________________________________ class MidiBend : public MidiM2 {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiBend( byte ch ) : MidiM2( BEND, ch ) { Raw.push_back( ( Command = 0xE0 ) + ch ); } MidiBend( byte ch, byte v ) : MidiM2( BEND, ch, v ) { Raw.push_back( ( Command = 0xE0 ) + ch ); } MidiBend( byte ch, byte v, byte w ): MidiM2( BEND, ch, v, w ) { Command = 0xE0; } virtual ~MidiBend(){} /* virtual void Send( Serial &s ) { s.putc( 0xE0 + Channel ); s.putc( ValA ); s.putc( ValB ); }*/ }; //_____________________________________________________________________________ class MidiControl : public MidiM2 {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiControl( byte ch ) : MidiM2( CTRL, ch ) { Raw.push_back( ( Command = 0xB0 ) + ch ); } MidiControl( byte ch, byte v ): MidiM2( CTRL, ch, v ) { Raw.push_back( ( Command = 0xB0 ) + ch ); } MidiControl( byte ch, byte v, byte w ): MidiM2( CTRL, ch, v, w ) { Command = 0xB0; } virtual ~MidiControl(){} /* virtual void Send( Serial &s ) { byte c = 0xB0 + Channel; switch( Type ) { case CTRL : s.putc( c ); s.putc(ValA ); s.putc( ValB ); break; case BANK : if( ValA != NAKN ) s.putc( c ); s.putc( 0 ); s.putc( ValA ); if( ValB != NAKN ) s.putc( c ); s.putc( 32 ); s.putc( ValB ); break; case DATA : if( ValA != NAKN ) s.putc( c ); s.putc( 6 ); s.putc( ValA ); if( ValB != NAKN ) s.putc( c ); s.putc( 38 ); s.putc( ValB ); break; case INCR : s.putc( c ); s.putc( 96 ); break; case DECR : s.putc( c ); s.putc( 97 ); break; case NRPN : if( ValA != NAKN ) s.putc( c ); s.putc( 99 ); s.putc( ValA ); if( ValB != NAKN ) s.putc( c ); s.putc( 98 ); s.putc( ValB ); break; case RPN_ : if( ValA != NAKN ) s.putc( c ); s.putc( 101 ); s.putc( ValA ); if( ValB != NAKN ) s.putc( c ); s.putc( 100 ); s.putc( ValB ); break; } }*/ virtual bool Append( byte b ) { Raw.push_back(b); switch( Next ) { case VALA: if( HasBank || HasData ) switch( b ) { case 0: if( HasBank ) { Next=MSB; Type=BANK; } else { Next=VALB; ValA=b; } return true; case 32: if( HasBank ) { Next=LSB; Type=BANK; } else { Next=VALB; ValA=b; } return true; case 6: if( HasData ) { Next=MSB; Type=DATA; } else { Next=VALB; ValA=b; } return true; case 38: if( HasData ) { Next=LSB; Type=DATA; } else { Next=VALB; ValA=b; } return true; case 96: if( HasData ) { Next=NONE; Type=INCR; } else { Next=VALB; ValA=b; } return true; case 97: if( HasData ) { Next=NONE; Type=DECR; } else { Next=VALB; ValA=b; } return true; case 98: if( HasData ) { Next=LSB; Type=NRPN; } else { Next=VALB; ValA=b; } return true; case 99: if( HasData ) { Next=MSB; Type=NRPN; } else { Next=VALB; ValA=b; } return true; case 100: if( HasData ) { Next=LSB; Type=NRPN; } else { Next=VALB; ValA=b; } return true; case 101: if( HasData ) { Next=MSB; Type=NRPN; } else { Next=VALB; ValA=b; } return true; default: Next = VALB; ValA = b; return true; } else{ Next = VALB; ValA = b; return true; } case VALB: Next = NONE; ValB = b; return true; case MSB: Next = PAIR; ValA = b; return true; // wait for 0xB* case LSB: Next = PAIR; ValB = b; return true; // wait for 0xB* case MSB2: Next = NONE; ValA = b; return true; case LSB2: Next = NONE; ValB = b; return true; case PAIR: Next = ITEM; return true; // 0xB* case ITEM: switch( Type ) { case BANK: if( b!= 0 && b!= 32 ){ Next = NONE; return false; } Next = b == 0 ? MSB2 : LSB2; return true; case DATA: if( b!= 6 && b!= 38 ){ Next = NONE; return false; } Next = b == 6 ? MSB2 : LSB2; return true; case NRPN: if( b!= 98 && b!= 99 ){ Next = NONE; return false; } Next = b == 99 ? MSB2 : LSB2; return true; case RPN_: if( b!=100 && b!=101 ){ Next = NONE; return false; } Next = b ==101 ? MSB2 : LSB2; return true; } } return false; } }; //_____________________________________________________________________________ class MidiX : public MidiM2 // class for SysEx message {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" public: MidiX() : MidiM2( SYSX, NAKN ){ Raw.push_back( Command = 0xF0 ); } virtual ~MidiX(){} virtual bool Append( byte b ) { Raw.push_back(b); if( b==0xF7 ) Next = NONE; return true; } }; //_____________________________________________________________________________ MidiM* MidiCreateMessage( byte command ) {//"""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""""" if( command >= 0xF0 ) switch( command ) { case 0xF0: return new MidiX(); case 0xF1: return new MidiTimeCode(); case 0xF2: return new MidiPosition(); case 0xF3: return new MidiSelect(); case 0xF6: return new MidiTune(); case 0xF8: return new MidiClock(); case 0xFA: return new MidiStart(); case 0xFB: return new MidiContinue(); case 0xFC: return new MidiStop(); case 0xFE: return new MidiSensing(); case 0xFF: return new MidiReset(); } else switch( command >> 4 ) { case 0x8: return new MidiNoteOff( command & 15 ); case 0x9: return new MidiNoteOn ( command & 15 ); case 0xA: return new MidiPolyAft( command & 15 ); case 0xB: return new MidiControl( command & 15 ); case 0xC: return new MidiProgram( command & 15 ); case 0xD: return new MidiMonoAft( command & 15 ); case 0xE: return new MidiBend ( command & 15 ); } return new MidiM( NONE ); } #undef VALA #undef VALB #undef MSB #undef LSB #undef PAIR #undef ITEM #undef MSB2 #undef LSB2 #endif