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/track.h"
00038
00039
00040 #ifndef DEBUG_MDTRACK
00041 # define DEBUG_MDTRACK 0
00042 #endif
00043
00044 #if DEBUG_MDTRACK
00045 # undef DBG
00046 # define DBG(a) a
00047 #endif
00048
00049 namespace jdkmidi
00050 {
00051
00052 const MIDITimedBigMessage * MIDITrackChunk::GetEventAddress( int event_num ) const
00053 {
00054 return &buf[event_num];
00055 }
00056
00057 MIDITimedBigMessage * MIDITrackChunk::GetEventAddress( int event_num )
00058 {
00059 return &buf[event_num];
00060 }
00061
00062
00063
00064
00065
00066 MIDITrack::MIDITrack( int size)
00067 {
00068 buf_size=0;
00069 num_events=0;
00070
00071 for( int i=0; i<MIDIChunksPerTrack; ++i )
00072 chunk[i]=0;
00073
00074 if( size )
00075 {
00076 Expand( size );
00077 }
00078
00079 }
00080
00081 MIDITrack::MIDITrack( const MIDITrack &t )
00082 {
00083 buf_size=0;
00084 num_events=0;
00085
00086
00087 for( int i=0; i<t.GetNumEvents(); ++i )
00088 {
00089 const MIDITimedBigMessage *src;
00090 src = t.GetEventAddress( i );
00091 PutEvent(*src);
00092 }
00093 }
00094
00095 MIDITrack::~MIDITrack()
00096 {
00097 for( int i=0; i<buf_size/MIDITrackChunkSize; ++i )
00098 delete chunk[i];
00099 }
00100
00101 void MIDITrack::Clear()
00102 {
00103 num_events = 0;
00104 }
00105
00106
00107 void MIDITrack::ClearAndMerge(
00108 const MIDITrack *src1,
00109 const MIDITrack *src2
00110 )
00111 {
00112 Clear();
00113
00114 const MIDITimedBigMessage *ev1;
00115 int cur_trk1ev=0;
00116 int num_trk1ev = src1->GetNumEvents();
00117
00118 const MIDITimedBigMessage *ev2;
00119 int cur_trk2ev=0;
00120 int num_trk2ev = src2->GetNumEvents();
00121
00122 MIDIClockTime last_data_end_time=0;
00123
00124 while(
00125 cur_trk1ev<num_trk1ev
00126 || cur_trk2ev<num_trk2ev
00127 )
00128 {
00129
00130
00131 ev1=src1->GetEventAddress( cur_trk1ev );
00132 ev2=src2->GetEventAddress( cur_trk2ev );
00133
00134 bool has_ev1 = (cur_trk1ev<num_trk1ev) && ev1;
00135 bool has_ev2 = (cur_trk2ev<num_trk2ev) && ev2;
00136
00137 if( has_ev1 && ev1->IsNoOp() )
00138 {
00139 cur_trk1ev++;
00140 continue;
00141 }
00142
00143
00144
00145 if( has_ev2 && ev2->IsNoOp() )
00146 {
00147 cur_trk2ev++;
00148 continue;
00149 }
00150
00151
00152
00153 if( has_ev1 && ev1->IsDataEnd() )
00154 {
00155 if( ev1->GetTime() > last_data_end_time )
00156 {
00157 last_data_end_time = ev1->GetTime();
00158 }
00159 cur_trk1ev++;
00160 continue;
00161 }
00162
00163 if( has_ev2 && ev2->IsDataEnd() )
00164 {
00165 if( ev2->GetTime() > last_data_end_time )
00166 {
00167 last_data_end_time = ev2->GetTime();
00168 }
00169 cur_trk2ev++;
00170 continue;
00171 }
00172
00173 if( (has_ev1 && !has_ev2) )
00174 {
00175
00176
00177 if( !ev1->IsNoOp())
00178 {
00179 if( ev1->GetTime() > last_data_end_time )
00180 {
00181 last_data_end_time = ev1->GetTime();
00182 }
00183
00184 PutEvent( *ev1 );
00185 ++cur_trk1ev;
00186 }
00187 } else if( (!has_ev1 && has_ev2) )
00188 {
00189
00190 if( !ev2->IsNoOp() )
00191 {
00192 PutEvent( *ev2 );
00193 ++cur_trk2ev;
00194 }
00195 } else if( has_ev1 && has_ev2 )
00196 {
00197 int trk=1;
00198
00199 if( (ev1->GetTime() <= ev2->GetTime()) )
00200 {
00201 trk=1;
00202 }
00203 else
00204 {
00205 trk=2;
00206 }
00207
00208 if( trk==1 )
00209 {
00210 if( ev1->GetTime() > last_data_end_time )
00211 {
00212 last_data_end_time = ev1->GetTime();
00213 }
00214
00215 PutEvent( *ev1 );
00216
00217 ++cur_trk1ev;
00218 }
00219 else
00220 {
00221 if( ev2->GetTime() > last_data_end_time )
00222 {
00223 last_data_end_time = ev2->GetTime();
00224 }
00225
00226 PutEvent( *ev2 );
00227 ++cur_trk2ev;
00228 }
00229 }
00230 }
00231
00232
00233
00234 MIDITimedBigMessage dataend;
00235
00236 dataend.SetTime( last_data_end_time );
00237 dataend.SetDataEnd();
00238
00239 PutEvent( dataend );
00240 }
00241
00242 #if 0
00243 bool MIDITrack::Insert( int start_event, int num )
00244 {
00245
00246 return true;
00247 }
00248
00249 bool MIDITrack::Delete( int start_event, int num )
00250 {
00251
00252 return true;
00253 }
00254
00255 void MIDITrack::QSort( int left, int right )
00256 {
00257 int i,j;
00258 MIDITimedBigMessage *x, y;
00259
00260 i=left; j=right;
00261
00262
00263
00264 int pos=(left+right)/2;
00265
00266 for( ;pos<=right;++pos )
00267 {
00268 x=GetEventAddress(pos);
00269 if( x && !x->IsNoOp() )
00270 break;
00271 }
00272 if( GetEventAddress( pos )->IsNoOp() )
00273 {
00274 for( pos=(left+right)/2; pos>=left; --pos )
00275 {
00276 x = GetEventAddress(pos);
00277 if( x && !x->IsNoOp() )
00278 break;
00279 }
00280 }
00281
00282 if( x && x->IsNoOp() )
00283 return;
00284
00285 do
00286 {
00287 while( MIDITimedMessage::CompareEvents( *GetEventAddress(i), *x ) == 2 &&
00288 i<right ) ++i;
00289
00290 while( MIDITimedMessage::CompareEvents( *x, *GetEventAddress(j) ) == 2 &&
00291 j>left ) --j;
00292
00293 if( i<=j )
00294 {
00295 y=*GetEventAddress( i );
00296 *GetEventAddress( i ) = *GetEventAddress( j );
00297 *GetEventAddress( j ) = y;
00298 ++i;
00299 --j;
00300 }
00301
00302 } while( i<=j );
00303
00304 if( left<j )
00305 {
00306 QSort(left,j);
00307 }
00308 if( i<right )
00309 {
00310 QSort(i,right);
00311 }
00312
00313 }
00314
00315
00316 void MIDITrack::Sort()
00317 {
00318
00319
00320
00321
00322
00323
00324
00325
00326 unsigned int i;
00327 unsigned int first_out_of_order_item=0;
00328
00329 for( i=0; i<num_events-1; ++i )
00330 {
00331 first_out_of_order_item=i+1;
00332 if( MIDITimedMessage::CompareEvents(
00333 *GetEventAddress(i),
00334 *GetEventAddress(first_out_of_order_item)
00335 )==1 )
00336 break;
00337 }
00338
00339 if( first_out_of_order_item>=num_events-1 )
00340 {
00341
00342 }
00343
00344 QSort(0,num_events-1);
00345 }
00346
00347 #endif
00348
00349 void MIDITrack::Shrink()
00350 {
00351 int num_chunks_used = (int)((num_events / MIDITrackChunkSize) +1);
00352 int num_chunks_alloced = (int)(buf_size/MIDITrackChunkSize);
00353
00354 if( num_chunks_used < num_chunks_alloced )
00355 {
00356 for( int i=num_chunks_used; i<num_chunks_alloced; ++i )
00357 {
00358 delete(chunk[i]);
00359 chunk[i]=0;
00360 }
00361 buf_size=num_chunks_used * MIDITrackChunkSize;
00362 }
00363 }
00364
00365 bool MIDITrack::Expand( int increase_amount )
00366 {
00367 int num_chunks_to_expand = (int)((increase_amount/MIDITrackChunkSize)+1);
00368 int num_chunks_alloced = (int)(buf_size/MIDITrackChunkSize);
00369 int new_last_chunk_num= (int)(num_chunks_to_expand + num_chunks_alloced);
00370
00371 if( new_last_chunk_num >= MIDIChunksPerTrack )
00372 {
00373 return false;
00374 }
00375
00376 for( int i=num_chunks_alloced; i<new_last_chunk_num; ++i )
00377 {
00378 chunk[i]=new MIDITrackChunk;
00379
00380 if( !chunk[i] )
00381 {
00382 buf_size=(i-1)*MIDITrackChunkSize;
00383 return false;
00384 }
00385 }
00386
00387 buf_size=new_last_chunk_num * MIDITrackChunkSize;
00388
00389 return true;
00390 }
00391
00392 MIDITimedBigMessage * MIDITrack::GetEventAddress( int event_num )
00393 {
00394 return chunk[ event_num/(MIDITrackChunkSize) ]->GetEventAddress(
00395 (event_num%MIDITrackChunkSize) );
00396 }
00397
00398 const MIDITimedBigMessage * MIDITrack::GetEventAddress( int event_num ) const
00399 {
00400 return chunk[ event_num/(MIDITrackChunkSize) ]->GetEventAddress(
00401 (event_num%MIDITrackChunkSize) );
00402 }
00403
00404 bool MIDITrack::PutEvent( const MIDITimedBigMessage &msg )
00405 {
00406 if( num_events >= buf_size )
00407 {
00408 if( !Expand() )
00409 return false;
00410 }
00411
00412 GetEventAddress( num_events++ )->Copy( msg );
00413
00414 return true;
00415 }
00416
00417 bool MIDITrack::PutEvent( const MIDITimedMessage &msg, MIDISystemExclusive *sysex )
00418 {
00419 if( num_events >= buf_size )
00420 {
00421 if( !Expand() )
00422 return false;
00423 }
00424
00425 MIDITimedBigMessage *e = GetEventAddress( num_events );
00426
00427 e->Copy( msg );
00428 e->CopySysEx( sysex );
00429
00430 ++num_events;
00431
00432 return true;
00433 }
00434
00435 bool MIDITrack::GetEvent( int event_num, MIDITimedBigMessage *msg ) const
00436 {
00437 if( event_num >= num_events )
00438 {
00439 return false;
00440 }
00441 else
00442 {
00443 msg->Copy( *GetEventAddress( event_num ) );
00444 return true;
00445 }
00446 }
00447
00448 bool MIDITrack::SetEvent( int event_num, const MIDITimedBigMessage &msg )
00449 {
00450 if( event_num>=num_events )
00451 {
00452 return false;
00453 }
00454 else
00455 {
00456 GetEventAddress( event_num )->Copy( msg );
00457 return true;
00458 }
00459 }
00460
00461 bool MIDITrack::MakeEventNoOp( int event_num )
00462 {
00463 if( event_num>=num_events )
00464 {
00465 return false;
00466 }
00467 else
00468 {
00469 MIDITimedBigMessage *ev = GetEventAddress( event_num );
00470
00471 if( ev )
00472 {
00473 ev->ClearSysEx();
00474 ev->SetNoOp();
00475 }
00476 return true;
00477 }
00478 }
00479
00480 bool MIDITrack::FindEventNumber( MIDIClockTime time, int *event_num ) const
00481 {
00482 ENTER("MIDITrack::FindEventNumber( int , int * )");
00483
00484
00485
00486 for( int i=0; i<num_events; ++i )
00487 {
00488 const MIDITimedBigMessage *msg = GetEventAddress( i );
00489
00490 if( msg->GetTime()>=time )
00491 {
00492 *event_num=i;
00493 return true;
00494 }
00495 }
00496
00497 *event_num=num_events;
00498 return false;
00499 }
00500
00501 const MIDITimedBigMessage *MIDITrack::GetEvent( int event_num ) const
00502 {
00503 if( event_num >= num_events )
00504 {
00505 return 0;
00506 }
00507 else
00508 {
00509 return GetEventAddress( event_num );
00510 }
00511
00512 }
00513
00514 MIDITimedBigMessage *MIDITrack::GetEvent( int event_num )
00515 {
00516 if( event_num >= num_events )
00517 {
00518 return 0;
00519 }
00520 else
00521 {
00522 return GetEventAddress( event_num );
00523 }
00524
00525 }
00526
00527 int MIDITrack::GetBufferSize() const
00528 {
00529 return buf_size;
00530 }
00531
00532 int MIDITrack::GetNumEvents() const
00533 {
00534 return num_events;
00535 }
00536
00537 }