00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00029
00030
00031
00032
00033
00034
00035 #include "jdkmidi/world.h"
00036
00037 #include "jdkmidi/filewrite.h"
00038
00039 #ifndef DEBUG_MDFWR
00040 # define DEBUG_MDFWR 0
00041 #endif
00042
00043 #if DEBUG_MDFWR
00044 # undef DBG
00045 # define DBG(a) a
00046 #endif
00047
00048 namespace jdkmidi
00049 {
00050
00051
00052 MIDIFileWriteStream::MIDIFileWriteStream()
00053 {
00054 }
00055
00056 MIDIFileWriteStream::~MIDIFileWriteStream()
00057 {
00058 }
00059
00060 MIDIFileWriteStreamFile::MIDIFileWriteStreamFile( FILE *f_ )
00061 : f(f_)
00062 {
00063 }
00064
00065 MIDIFileWriteStreamFile::~MIDIFileWriteStreamFile()
00066 {
00067 }
00068
00069 long MIDIFileWriteStreamFile::Seek( long pos, int whence )
00070 {
00071 return fseek( f, pos, whence );
00072 }
00073
00074 int MIDIFileWriteStreamFile::WriteChar( int c )
00075 {
00076 if( fputc( c, f )==EOF )
00077 {
00078 return -1;
00079 }
00080 else
00081 {
00082 return 0;
00083 }
00084 }
00085
00086
00087 MIDIFileWrite::MIDIFileWrite( MIDIFileWriteStream *out_stream_ )
00088 : out_stream( out_stream_ )
00089 {
00090 ENTER( "MIDIFileWrite::MIDIFileWrite()" );
00091
00092 file_length=0;
00093 error=0;
00094 track_length=0;
00095 track_time=0;
00096 running_status=0;
00097 track_position=0;
00098 }
00099
00100 MIDIFileWrite::~MIDIFileWrite()
00101 {
00102 ENTER( "MIDIFileWrite::~MIDIFileWrite()" );
00103
00104 }
00105
00106 void MIDIFileWrite::Error(char *s)
00107 {
00108 ENTER( "void MIDIFileWrite::Error()" );
00109
00110
00111
00112 error=true;
00113 }
00114
00115 void MIDIFileWrite::WriteShort( unsigned short c )
00116 {
00117 ENTER( "void MIDIFileWrite::WriteShort()" );
00118
00119 WriteCharacter( (unsigned char)((c>>8)&0xff) );
00120 WriteCharacter( (unsigned char)((c&0xff)) );
00121 }
00122
00123 void MIDIFileWrite::Write3Char( long c )
00124 {
00125 ENTER( "void MIDIFileWrite::Write3Char()" );
00126
00127 WriteCharacter( (unsigned char)((c>>16)&0xff) );
00128 WriteCharacter( (unsigned char)((c>>8)&0xff) );
00129 WriteCharacter( (unsigned char)((c&0xff)) );
00130 }
00131
00132 void MIDIFileWrite::WriteLong( unsigned long c )
00133 {
00134 ENTER( "void MIDIFileWrite::WriteLong()" );
00135
00136 WriteCharacter( (unsigned char) ((c>>24)&0xff) );
00137 WriteCharacter( (unsigned char) ((c>>16)&0xff) );
00138 WriteCharacter( (unsigned char) ((c>>8)&0xff) );
00139 WriteCharacter( (unsigned char) ((c&0xff)) );
00140 }
00141
00142 void MIDIFileWrite::WriteFileHeader(
00143 int format,
00144 int ntrks,
00145 int division
00146 )
00147 {
00148 ENTER( "void MIDIFileWrite::WriteFileHeader()" );
00149
00150 WriteCharacter( (unsigned char) 'M' );
00151 WriteCharacter( (unsigned char) 'T' );
00152 WriteCharacter( (unsigned char) 'h' );
00153 WriteCharacter( (unsigned char) 'd' );
00154 WriteLong( 6 );
00155 WriteShort( (short)format );
00156 WriteShort( (short)ntrks );
00157 WriteShort( (short)division );
00158 file_length=4+4+6;
00159 }
00160
00161 void MIDIFileWrite::WriteTrackHeader( unsigned long length )
00162 {
00163 ENTER( "void MIDIFileWrite::WriteTrackHeader()" );
00164
00165 track_position=file_length;
00166 track_length=0;
00167 track_time=0;
00168 running_status=0;
00169
00170 WriteCharacter( (unsigned char) 'M' );
00171 WriteCharacter( (unsigned char) 'T' );
00172 WriteCharacter( (unsigned char) 'r' );
00173 WriteCharacter( (unsigned char) 'k' );
00174
00175 WriteLong( length );
00176 file_length+=8;
00177 within_track=true;
00178 }
00179
00180 int MIDIFileWrite::WriteVariableNum( unsigned long n )
00181 {
00182 ENTER( "short MIDIFileWrite::WriteVariableNum()" );
00183
00184 register unsigned long buffer;
00185 short cnt=0;
00186
00187 buffer=n&0x7f;
00188 while( (n>>=7) > 0)
00189 {
00190 buffer <<=8;
00191 buffer|=0x80;
00192 buffer+=(n&0x7f);
00193 }
00194
00195 while( true )
00196 {
00197 WriteCharacter( (unsigned char) (buffer&0xff) );
00198 cnt++;
00199 if( buffer&0x80 )
00200 buffer>>=8;
00201 else
00202 break;
00203 }
00204 return cnt;
00205 }
00206
00207 void MIDIFileWrite::WriteDeltaTime( unsigned long abs_time )
00208 {
00209 ENTER( "void MIDIFileWrite::WriteDeltaTime()" );
00210
00211 long dtime=abs_time-track_time;
00212 if( dtime<0 )
00213 {
00214
00215 dtime=0;
00216 }
00217
00218 IncrementCounters( WriteVariableNum( dtime ) );
00219 track_time=abs_time;
00220 }
00221
00222 void MIDIFileWrite::WriteEvent( const MIDITimedMessage &m )
00223 {
00224 ENTER( "void MIDIFileWrite::WriteEvent()" );
00225
00226 if( m.IsNoOp() )
00227 {
00228 return;
00229 }
00230
00231 if( m.IsMetaEvent() )
00232 {
00233
00234
00235
00236 if( m.IsTempo() )
00237 {
00238 unsigned long tempo = (60000000/m.GetTempo32())*32;
00239 WriteTempo( m.GetTime(), tempo );
00240 return;
00241 }
00242 if( m.IsDataEnd() )
00243 {
00244 WriteEndOfTrack( m.GetTime() );
00245 return;
00246 }
00247 if( m.IsKeySig() )
00248 {
00249 WriteKeySignature( m.GetTime(), m.GetKeySigSharpFlats(), m.GetKeySigMajorMinor() );
00250 return;
00251 }
00252 return;
00253 }
00254 else
00255 {
00256 short len=m.GetLength();
00257
00258 WriteDeltaTime( m.GetTime() );
00259 if( m.GetStatus()!=running_status )
00260 {
00261 running_status=m.GetStatus();
00262 WriteCharacter( (unsigned char) running_status );
00263 IncrementCounters(1);
00264 }
00265 if( len>1 )
00266 {
00267 WriteCharacter( (unsigned char) m.GetByte1() );
00268 IncrementCounters(1);
00269 }
00270 if( len>2 )
00271 {
00272 WriteCharacter( (unsigned char) m.GetByte2() );
00273 IncrementCounters(1);
00274 }
00275 }
00276
00277 }
00278
00279 void MIDIFileWrite::WriteEvent( const MIDITimedBigMessage &m )
00280 {
00281 if( m.IsNoOp() )
00282 {
00283 return;
00284 }
00285
00286 if( m.IsMetaEvent() )
00287 {
00288
00289
00290
00291 if( m.GetSysEx() )
00292 {
00293 WriteMetaEvent(
00294 m.GetTime(),
00295 m.GetMetaType(),
00296 m.GetSysEx()->GetBuf(),
00297 m.GetSysEx()->GetLength()
00298 );
00299 }
00300 else
00301 {
00302
00303
00304 if( m.IsTempo() )
00305 {
00306 unsigned long tempo = (60000000/m.GetTempo32())*32;
00307 WriteTempo( m.GetTime(), tempo );
00308 }
00309 else if( m.IsDataEnd() )
00310 {
00311 WriteEndOfTrack( m.GetTime() );
00312 }
00313 else if( m.IsKeySig() )
00314 {
00315 WriteKeySignature( m.GetTime(), m.GetKeySigSharpFlats(), m.GetKeySigMajorMinor() );
00316 }
00317
00318 }
00319
00320 }
00321 else
00322 {
00323 short len=m.GetLength();
00324
00325 if( m.IsSysEx() && m.GetSysEx() )
00326 {
00327 WriteEvent( m.GetTime(), m.GetSysEx() );
00328 }
00329 else if( len>0 )
00330 {
00331 WriteDeltaTime( m.GetTime() );
00332 if( m.GetStatus()!=running_status )
00333 {
00334 running_status=m.GetStatus();
00335 WriteCharacter( (unsigned char) running_status );
00336 IncrementCounters(1);
00337 }
00338 if( len>1 )
00339 {
00340 WriteCharacter( (unsigned char) m.GetByte1() );
00341 IncrementCounters(1);
00342 }
00343 if( len>2 )
00344 {
00345 WriteCharacter( (unsigned char) m.GetByte2() );
00346 IncrementCounters(1);
00347 }
00348 }
00349 }
00350
00351 }
00352
00353 void MIDIFileWrite::WriteEvent(
00354 unsigned long time,
00355 const MIDISystemExclusive *e
00356 )
00357 {
00358 ENTER( "void MIDIFileWrite::WriteEvent()" );
00359
00360 int len=e->GetLength();
00361
00362 WriteDeltaTime( time );
00363
00364 WriteCharacter( (unsigned char)SYSEX_START );
00365 IncrementCounters( WriteVariableNum( len-1 ) );
00366
00367 for( int i=1; i<len; i++ )
00368 {
00369 WriteCharacter( (unsigned char)(e->GetData(i)) );
00370 }
00371 IncrementCounters( len );
00372 running_status=0;
00373 }
00374
00375 void MIDIFileWrite::WriteEvent( unsigned long time, unsigned short text_type, const char *text )
00376 {
00377 ENTER( "void MIDIFileWrite::WriteEvent()" );
00378
00379 WriteDeltaTime( time );
00380
00381 WriteCharacter( (unsigned char) 0xff );
00382 WriteCharacter( (unsigned char) text_type );
00383
00384 IncrementCounters(2);
00385
00386 long len=strlen(text);
00387
00388 IncrementCounters( WriteVariableNum( len ) );
00389
00390 while( *text )
00391 {
00392 WriteCharacter( (unsigned char) *text++ );
00393 }
00394 IncrementCounters( len );
00395 running_status=0;
00396 }
00397
00398 void MIDIFileWrite::WriteMetaEvent( unsigned long time, unsigned char type, const unsigned char *data, long length )
00399 {
00400 ENTER( "void MIDIFileWrite::WriteMetaEvent()" );
00401
00402 WriteDeltaTime( time );
00403 WriteCharacter( (unsigned char) 0xff );
00404 WriteCharacter( (unsigned char) type );
00405
00406 IncrementCounters(2);
00407
00408 IncrementCounters( WriteVariableNum( length ) );
00409
00410 for( int i=0; i<length; i++ )
00411 {
00412 WriteCharacter( (unsigned char) data[i] );
00413 }
00414 IncrementCounters( length );
00415 running_status=0;
00416 }
00417
00418 void MIDIFileWrite::WriteTempo( unsigned long time, long tempo )
00419 {
00420 ENTER( "void MIDIFileWrite::WriteTempo()" );
00421
00422 WriteDeltaTime( time );
00423 WriteCharacter( (unsigned char) 0xff );
00424 WriteCharacter( (unsigned char) 0x51 );
00425 WriteCharacter( (unsigned char) 0x03 );
00426
00427 Write3Char( tempo );
00428 IncrementCounters(6);
00429 running_status=0;
00430 }
00431
00432 void MIDIFileWrite::WriteKeySignature( unsigned long time, char sharp_flat, char minor )
00433 {
00434 ENTER( "void MIDIFileWrite::WriteKeySignature()" );
00435
00436 WriteDeltaTime( time );
00437 WriteCharacter( (unsigned char) 0xff );
00438 WriteCharacter( (unsigned char) 0x59 );
00439 WriteCharacter( (unsigned char) 0x02 );
00440 WriteCharacter( (unsigned char) sharp_flat );
00441 WriteCharacter( (unsigned char) minor );
00442 IncrementCounters(5);
00443 running_status=0;
00444 }
00445
00446 void MIDIFileWrite::WriteTimeSignature(
00447 unsigned long time,
00448 char numerator,
00449 char denominator_power,
00450 char midi_clocks_per_metronome,
00451 char num_32nd_per_midi_quarter_note)
00452 {
00453 ENTER( "void MIDIFileWrite::WriteTimeSignature()" );
00454
00455 WriteDeltaTime( time );
00456 WriteCharacter( (unsigned char) 0xff );
00457 WriteCharacter( (unsigned char) 0x58 );
00458 WriteCharacter( (unsigned char) 0x04 );
00459 WriteCharacter( (unsigned char) numerator );
00460 WriteCharacter( (unsigned char) denominator_power );
00461 WriteCharacter( (unsigned char) midi_clocks_per_metronome );
00462 WriteCharacter( (unsigned char) num_32nd_per_midi_quarter_note );
00463 IncrementCounters(7);
00464 running_status=0;
00465 }
00466
00467 void MIDIFileWrite::WriteEndOfTrack( unsigned long time )
00468 {
00469 ENTER( "void MIDIFileWrite::WriteEndOfTrack()" );
00470
00471 if( within_track==true )
00472 {
00473 if( time==0 )
00474 time=track_time;
00475 WriteDeltaTime( time );
00476 WriteCharacter( (unsigned char) 0xff );
00477 WriteCharacter( (unsigned char) 0x2f );
00478 WriteCharacter( (unsigned char) 0x00 );
00479 IncrementCounters( 3 );
00480 within_track=false;
00481 running_status=0;
00482 }
00483 }
00484
00485 void MIDIFileWrite::RewriteTrackLength()
00486 {
00487 ENTER( "void MIDIFileWrite::RewriteTrackLength()" );
00488
00489
00490
00491
00492
00493 Seek( track_position+4 );
00494 WriteLong( track_length );
00495 Seek( track_position+8+track_length );
00496 }
00497
00498 }