jdkmidi class library documentation

Copyright © 2004 J.D. Koftinoff Software, Ltd.

Released under the GNU General Public License (GPL)




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

jdkmidi::MIDIFileRead Class Reference

#include <fileread.h>

Inheritance diagram for jdkmidi::MIDIFileRead:

jdkmidi::MIDIFile List of all members.

Public Member Functions

 MIDIFileRead (MIDIFileReadStream *input_stream_, MIDIFileEvents *event_handler_, unsigned long max_msg_len=8192)
virtual ~MIDIFileRead ()
virtual bool Parse ()
int GetFormat ()
int GetNumberTracks ()
int GetDivision ()

Protected Member Functions

virtual int ReadHeader ()
virtual void mf_error (char *)

Protected Attributes

int no_merge
MIDIClockTime cur_time
int skip_init
unsigned long to_be_read
int cur_track
int abort_parse
unsigned char * the_msg
int max_msg_len
int msg_index

Private Member Functions

unsigned long ReadVariableNum ()
unsigned long Read32Bit ()
int Read16Bit ()
void ReadTrack ()
void MsgAdd (int)
void MsgInit ()
int EGetC ()
int ReadMT (unsigned long, int)
void BadByte (int)
void FormChanMessage (unsigned char st, unsigned char b1, unsigned char b2)

Private Attributes

int header_format
int header_ntrks
int header_division
MIDIFileReadStreaminput_stream
MIDIFileEventsevent_handler

Constructor & Destructor Documentation

jdkmidi::MIDIFileRead::MIDIFileRead MIDIFileReadStream input_stream_,
MIDIFileEvents event_handler_,
unsigned long  max_msg_len = 8192
 

Definition at line 319 of file jdkmidi_fileread.cpp.

References abort_parse, cur_time, cur_track, max_msg_len, msg_index, no_merge, skip_init, the_msg, and to_be_read.

00324     : 
00325     input_stream( input_stream_ ),
00326     event_handler( event_handler_ )
00327   {
00328     no_merge=0;
00329     cur_time=0;
00330     skip_init=1;
00331     to_be_read=0;
00332     msg_index=0;
00333     cur_track=0;
00334     abort_parse=0;
00335     max_msg_len=max_msg_len_;
00336     the_msg = new unsigned char[max_msg_len];
00337   } 

jdkmidi::MIDIFileRead::~MIDIFileRead  )  [virtual]
 

Definition at line 339 of file jdkmidi_fileread.cpp.

References the_msg.

00340   {
00341     delete [] the_msg;
00342   } 


Member Function Documentation

void jdkmidi::MIDIFileRead::BadByte int   )  [private]
 

Definition at line 690 of file jdkmidi_fileread.cpp.

References abort_parse, and mf_error().

00691   {
00692     mf_error( "Unexpected Byte" );
00693     abort_parse=true;
00694   } 

int jdkmidi::MIDIFileRead::EGetC  )  [private]
 

Definition at line 660 of file jdkmidi_fileread.cpp.

References abort_parse, input_stream, mf_error(), jdkmidi::MIDIFileReadStream::ReadChar(), and to_be_read.

00661   {
00662     int c;
00663     
00664     c = input_stream->ReadChar();
00665     
00666     
00667     if( c<0 )
00668     {
00669       mf_error( "Unexpected Stream Error" );
00670       abort_parse=true;
00671       return -1;
00672     }
00673     
00674     --to_be_read;
00675     
00676     return (int)c;
00677   } 

void jdkmidi::MIDIFileRead::FormChanMessage unsigned char  st,
unsigned char  b1,
unsigned char  b2
[private]
 

Definition at line 696 of file jdkmidi_fileread.cpp.

References jdkmidi::MIDIFileEvents::ChanMessage(), cur_time, event_handler, jdkmidi::MIDIMessage::SetByte1(), jdkmidi::MIDIMessage::SetByte2(), jdkmidi::MIDIMessage::SetStatus(), and jdkmidi::MIDITimedMessage::SetTime().

00697   {
00698     MIDITimedMessage m;
00699     
00700     m.SetStatus( st );
00701     m.SetByte1( b1 );
00702     m.SetByte2( b2 );
00703     m.SetTime( cur_time );
00704     
00705     if( st>=0x80 && st<0xf0 )
00706     {
00707       event_handler->ChanMessage(m);
00708     }
00709     
00710   } 

int jdkmidi::MIDIFileRead::GetDivision  )  [inline]
 

Definition at line 174 of file fileread.h.

References header_division.

00174 { return header_division; }

int jdkmidi::MIDIFileRead::GetFormat  )  [inline]
 

Definition at line 172 of file fileread.h.

References header_format.

00172 { return header_format;   }

int jdkmidi::MIDIFileRead::GetNumberTracks  )  [inline]
 

Definition at line 173 of file fileread.h.

References header_ntrks.

00173 { return header_ntrks;    }

void jdkmidi::MIDIFileRead::mf_error char *   )  [protected, virtual]
 

Definition at line 344 of file jdkmidi_fileread.cpp.

References abort_parse, event_handler, and jdkmidi::MIDIFileEvents::mf_error().

00345   {
00346     event_handler->mf_error(e);
00347     abort_parse=true;   
00348   } 

void jdkmidi::MIDIFileRead::MsgAdd int   )  [private]
 

Definition at line 679 of file jdkmidi_fileread.cpp.

References max_msg_len, msg_index, and the_msg.

00680   {
00681     if( msg_index<max_msg_len )
00682       the_msg[ msg_index++ ] = (unsigned char)a;
00683   } 

void jdkmidi::MIDIFileRead::MsgInit  )  [private]
 

Definition at line 685 of file jdkmidi_fileread.cpp.

References msg_index.

00686   {
00687     msg_index=0;
00688   } 

bool jdkmidi::MIDIFileRead::Parse  )  [virtual]
 

Definition at line 350 of file jdkmidi_fileread.cpp.

References abort_parse, cur_track, mf_error(), ReadHeader(), and ReadTrack().

00351   {
00352     int n;
00353     
00354     n = ReadHeader();
00355     if( n <=0 )
00356     {
00357       mf_error( "No Tracks" );
00358       return false;
00359     }
00360     for( cur_track=0; cur_track<n; cur_track++ )
00361     {
00362       ReadTrack();
00363       if( abort_parse )
00364       {
00365         return false;
00366       }
00367     }
00368     return true;
00369   } 

int jdkmidi::MIDIFileRead::Read16Bit  )  [private]
 

Definition at line 650 of file jdkmidi_fileread.cpp.

References EGetC(), and jdkmidi::MIDIFile::To16Bit().

00651   {
00652     int c1, c2;
00653     
00654     c1=EGetC();
00655     c2=EGetC();
00656     
00657     return To16Bit( (unsigned char)c1, (unsigned char)c2 );
00658   } 

unsigned long jdkmidi::MIDIFileRead::Read32Bit  )  [private]
 

Definition at line 638 of file jdkmidi_fileread.cpp.

References EGetC(), and jdkmidi::MIDIFile::To32Bit().

00639   {
00640     int c1, c2, c3, c4;
00641     
00642     c1=EGetC();
00643     c2=EGetC();
00644     c3=EGetC();
00645     c4=EGetC();
00646     
00647     return To32Bit( (unsigned char)c1, (unsigned char)c2, (unsigned char)c3, (unsigned char)c4 );
00648   } 

int jdkmidi::MIDIFileRead::ReadHeader  )  [protected, virtual]
 

Definition at line 403 of file jdkmidi_fileread.cpp.

References jdkmidi::_MThd, abort_parse, EGetC(), event_handler, header_division, header_format, header_ntrks, jdkmidi::MIDIFileEvents::mf_header(), Read16Bit(), Read32Bit(), ReadMT(), skip_init, and to_be_read.

00404   {
00405     int   the_format;
00406     int  ntrks;
00407     int   division;
00408     
00409     if( ReadMT( _MThd, skip_init )==0xffff )
00410       return 0;
00411     
00412     if( abort_parse )
00413       return 0;
00414     
00415     to_be_read = Read32Bit();
00416     the_format=Read16Bit();
00417     ntrks=Read16Bit();
00418     division=Read16Bit();
00419     
00420     if( abort_parse )
00421       return 0;
00422     
00423     
00424     header_format=the_format;
00425     header_ntrks=ntrks;
00426     header_division=division;
00427     
00428     event_handler->mf_header( the_format, ntrks, division );
00429     
00430     
00431     // printf( "\nto be read = %d\n", to_be_read );
00432     
00433     while( to_be_read > 0 )
00434       EGetC();
00435     
00436     return ntrks;
00437   } 

int jdkmidi::MIDIFileRead::ReadMT unsigned  long,
int 
[private]
 

Definition at line 371 of file jdkmidi_fileread.cpp.

References abort_parse, EGetC(), mf_error(), and OSTYPE.

00372   {
00373     unsigned long read=0;
00374     int c;       
00375     
00376     read=OSTYPE( EGetC(), EGetC(), EGetC(), EGetC() );
00377     if( type!=read )
00378     {
00379       if( skip )
00380       {
00381         do
00382         {
00383           read<<=8;
00384           c=EGetC();
00385           read|=c;
00386           if( read==type )
00387             return true;
00388           if( abort_parse )
00389             return false;
00390           
00391         } while( c!=-1 );
00392       }
00393       mf_error( "Error looking for chunk type" );
00394       return false;
00395     }
00396     else
00397     {
00398       return true;
00399     }
00400     
00401   } 

void jdkmidi::MIDIFileRead::ReadTrack  )  [private]
 

Definition at line 443 of file jdkmidi_fileread.cpp.

References jdkmidi::_MTrk, abort_parse, BadByte(), cur_time, cur_track, EGetC(), event_handler, FormChanMessage(), jdkmidi::MIDIFileEvents::MetaEvent(), jdkmidi::MIDIFileEvents::mf_arbitrary(), jdkmidi::MIDIFileEvents::mf_endtrack(), mf_error(), jdkmidi::MIDIFileEvents::mf_starttrack(), jdkmidi::MIDIFileEvents::mf_sysex(), msg_index, MsgAdd(), MsgInit(), no_merge, Read32Bit(), ReadMT(), ReadVariableNum(), the_msg, to_be_read, and jdkmidi::MIDIFileEvents::UpdateTime().

00444   {
00445     //
00446     // This array is indexed by the high half of a status byte.  Its
00447     // value is either the number of bytes needed (1 or 2) for a channel
00448     // message, or 0 (meaning it's not  a channel message).
00449     //
00450     
00451     static char chantype[] = 
00452       {
00453         0, 0, 0, 0, 0, 0, 0, 0,         // 0x00 through 0x70
00454         2, 2, 2, 2, 1, 1, 2, 0          // 0x80 through 0xf0
00455       };
00456     
00457     unsigned long lookfor, lng;
00458     int c, c1, type;
00459     int sysexcontinue=0; // 1 if last message was unfinished sysex
00460     int running=0;       // 1 when running status used
00461     int status=0;                // (possible running) status byte
00462     int needed;
00463     
00464     
00465     if( ReadMT( _MTrk, 0) == 0xffff )
00466       return;
00467     
00468     to_be_read=Read32Bit();
00469     cur_time=0;
00470     
00471     event_handler->mf_starttrack( cur_track );
00472     
00473     while( to_be_read > 0 && !abort_parse )
00474     {
00475       unsigned long deltat=ReadVariableNum();
00476       
00477       event_handler->UpdateTime( deltat );
00478       
00479       cur_time += deltat;
00480       
00481       c=EGetC();
00482       
00483       if( c==-1 )
00484         break;
00485       
00486       if( sysexcontinue && c!=0xf7 )
00487         mf_error( "Error after expected continuation of SysEx" );
00488       
00489       if( (c&0x80)==0 )
00490       {
00491         if( status==0 )
00492           mf_error( "Unexpected Running Status" );
00493         running=1;
00494         needed = chantype[ (status>>4) & 0xf ];
00495       }
00496       else
00497       {
00498         // TO DO: is running status to be cleared or not when meta event happens?
00499         
00500 #if MIDIFRD_ALLOW_STATUS_ACROSS_META_EVENT
00501         if(  c!=0xff )
00502         {
00503           status=c;
00504           running=0;
00505           needed=0;
00506         }
00507         
00508 #else
00509         status=c;
00510         running=0;
00511         needed = chantype[ (status>>4) & 0xf ]; 
00512 #endif
00513         
00514       }
00515       
00516       
00517       
00518       if( needed )            // ie. is it a channel message?
00519       {
00520         if( running )
00521           c1=c;
00522         else
00523           c1=EGetC();
00524         FormChanMessage( (unsigned char)status, (unsigned char)c1, (unsigned char)((needed>1) ? EGetC() : 0 ));
00525         continue;
00526       }
00527       
00528       
00529       switch( c )
00530       {
00531       case 0xff:              // meta-event
00532         type=EGetC();
00533         lng = ReadVariableNum();
00534         
00535         lookfor = to_be_read - lng;
00536         
00537         MsgInit();
00538         while( to_be_read > lookfor)
00539         {
00540           MsgAdd( EGetC() );
00541         }
00542         
00543         event_handler->MetaEvent( cur_time, type, msg_index, the_msg );
00544         break;
00545         
00546       case 0xf0:              // start of sys-ex
00547         lng = ReadVariableNum();
00548         lookfor = to_be_read - lng;
00549         
00550         MsgInit();
00551         MsgAdd(0xf0);
00552         
00553         while( to_be_read>lookfor )
00554           MsgAdd( c=EGetC() );
00555         
00556         if( c==0xf7 || no_merge==0 )
00557         {
00558           // make a sysex object out of the raw sysex data
00559           // the buffer is not to be deleted upon destruction of ex
00560           
00561           MIDISystemExclusive ex(
00562             the_msg,
00563             msg_index,
00564             msg_index,
00565             false
00566             );
00567           
00568           // give the sysex object to our event handler
00569           
00570           event_handler->mf_sysex( cur_time, ex );
00571         }
00572         else
00573           sysexcontinue=1; // merge into next msg
00574         break;
00575       case 0xf7:              // sysex continuation or 
00576         // arbitary stuff
00577         lng=ReadVariableNum();
00578         lookfor = to_be_read - lng;
00579         
00580         if( ! sysexcontinue )
00581           MsgInit();
00582         
00583         while( to_be_read > lookfor )
00584           MsgAdd(c=EGetC());
00585         
00586         if( !sysexcontinue )
00587         {
00588           event_handler->mf_arbitrary( cur_time, msg_index, the_msg );
00589         }
00590         else if( c== 0xf7 )
00591         {
00592           // make a sysex object out of the raw sysex data
00593           // the buffer is not to be deleted upon destruction of ex
00594           
00595           MIDISystemExclusive ex(
00596             the_msg,
00597             msg_index,
00598             msg_index,
00599             false
00600             );
00601           event_handler->mf_sysex( cur_time, ex );
00602           sysexcontinue=0;
00603         }
00604         break;
00605       default:
00606         BadByte(c);
00607         break;
00608       }
00609     }
00610     event_handler->mf_endtrack( cur_track );
00611     return;
00612   } 

unsigned long jdkmidi::MIDIFileRead::ReadVariableNum  )  [private]
 

Definition at line 614 of file jdkmidi_fileread.cpp.

References EGetC().

00615   {
00616     unsigned long value;
00617     int c;
00618     
00619     c=EGetC();
00620     if( c==-1 )
00621     {
00622       return 0;
00623     }
00624     value = c;
00625     
00626     if( c & 0x80 )
00627     {
00628       value &= 0x7f;
00629       do
00630       {
00631         c=EGetC();
00632         value =  (value<<7) + (c&0x7f);
00633       } while( c&0x80 );
00634     }
00635     return value;
00636   } 


Member Data Documentation

int jdkmidi::MIDIFileRead::abort_parse [protected]
 

Definition at line 188 of file fileread.h.

MIDIClockTime jdkmidi::MIDIFileRead::cur_time [protected]
 

Definition at line 184 of file fileread.h.

int jdkmidi::MIDIFileRead::cur_track [protected]
 

Definition at line 187 of file fileread.h.

MIDIFileEvents* jdkmidi::MIDIFileRead::event_handler [private]
 

Definition at line 217 of file fileread.h.

int jdkmidi::MIDIFileRead::header_division [private]
 

Definition at line 214 of file fileread.h.

int jdkmidi::MIDIFileRead::header_format [private]
 

Definition at line 212 of file fileread.h.

int jdkmidi::MIDIFileRead::header_ntrks [private]
 

Definition at line 213 of file fileread.h.

MIDIFileReadStream* jdkmidi::MIDIFileRead::input_stream [private]
 

Definition at line 216 of file fileread.h.

int jdkmidi::MIDIFileRead::max_msg_len [protected]
 

Definition at line 191 of file fileread.h.

int jdkmidi::MIDIFileRead::msg_index [protected]
 

Definition at line 192 of file fileread.h.

int jdkmidi::MIDIFileRead::no_merge [protected]
 

Definition at line 183 of file fileread.h.

int jdkmidi::MIDIFileRead::skip_init [protected]
 

Definition at line 185 of file fileread.h.

unsigned char* jdkmidi::MIDIFileRead::the_msg [protected]
 

Definition at line 190 of file fileread.h.

unsigned long jdkmidi::MIDIFileRead::to_be_read [protected]
 

Definition at line 186 of file fileread.h.


The documentation for this class was generated from the following files: