00001 #include "jdkmidi/world.h"
00002 #include "jdkmidi/advancedsequencer.h"
00003
00004
00005 namespace jdkmidi
00006 {
00007 static void FixQuotes( char *s_ )
00008 {
00009 unsigned char *s = (unsigned char *)s_;
00010 while( *s )
00011 {
00012 if( *s==0xd2 || *s==0xd3 )
00013 {
00014 *s='"';
00015 }
00016 else if( *s==0xd5 )
00017 {
00018 *s='\'';
00019 }
00020 else if( *s>=0x80 )
00021 {
00022 *s = ' ';
00023 }
00024 s++;
00025 }
00026 }
00027
00028 AdvancedSequencer::AdvancedSequencer()
00029 :
00030 thru_processor(2),
00031 thru_transposer(),
00032 thru_rechannelizer(),
00033 driver(256,stdout),
00034 tracks(17),
00035 notifier( stdout ),
00036 seq( &tracks, ¬ifier ),
00037 mgr( &driver, ¬ifier, &seq ),
00038 repeat_start_measure(0),
00039 repeat_end_measure(0),
00040 repeat_play_mode(false),
00041 num_warp_positions(0),
00042 file_loaded(false),
00043 chain_mode(false)
00044 {
00045 }
00046
00047 AdvancedSequencer::~AdvancedSequencer()
00048 {
00049 Stop();
00050 CloseMIDI();
00051
00052 for( int i=0; i<num_warp_positions; ++i )
00053 {
00054 delete warp_positions[i];
00055 }
00056 }
00057
00058
00059
00060 bool AdvancedSequencer::OpenMIDI( int in_port, int out_port, int timer_resolution )
00061 {
00062 #if 0
00063 CloseMIDI();
00064
00065 if( !driver.StartTimer( timer_resolution ) )
00066 {
00067 return false;
00068 }
00069
00070 if( in_port!=-1 )
00071 {
00072 driver.OpenMIDIInPort( in_port );
00073 }
00074
00075 if( driver.OpenMIDIOutPort( out_port ) )
00076 {
00077 return true;
00078 }
00079 else
00080 {
00081 return false;
00082 }
00083 #else
00084 return true;
00085 #endif
00086 }
00087
00088
00089 void AdvancedSequencer::CloseMIDI()
00090 {
00091 Stop();
00092 #if 0
00093 driver.StopTimer();
00094 driver.AllNotesOff();
00095 Sleep(100);
00096 driver.CloseMIDIInPort();
00097 driver.CloseMIDIOutPort();
00098 #endif
00099 }
00100
00101
00102 void AdvancedSequencer::SetMIDIThruEnable( bool f )
00103 {
00104 driver.SetThruEnable( f );
00105 }
00106
00107 bool AdvancedSequencer::GetMIDIThruEnable() const
00108 {
00109 return driver.GetThruEnable();
00110 }
00111
00112 void AdvancedSequencer::SetMIDIThruChannel( int chan )
00113 {
00114 thru_rechannelizer.SetAllRechan( chan );
00115 driver.AllNotesOff();
00116
00117 }
00118
00119
00120 int AdvancedSequencer::GetMIDIThruChannel() const
00121 {
00122 return thru_rechannelizer.GetRechanMap( 0 );
00123 }
00124
00125
00126
00127 void AdvancedSequencer::SetMIDIThruTranspose( int val )
00128 {
00129 thru_transposer.SetAllTranspose( val );
00130 driver.AllNotesOff();
00131 }
00132
00133
00134 int AdvancedSequencer::GetMIDIThruTranspose() const
00135 {
00136 return thru_transposer.GetTransposeChannel( 0 );
00137 }
00138
00139
00140
00141 bool AdvancedSequencer::Load( const char *fname )
00142 {
00143 char realname[1024];
00144
00145 strcpy( realname, fname );
00146 int orignamelen = strlen(fname);
00147
00148 chain_mode =false;
00149 if( orignamelen>0 )
00150 {
00151 if( realname[orignamelen-1]=='+' )
00152 {
00153 realname[orignamelen-1]=0;
00154 chain_mode = true;
00155 }
00156 }
00157
00158 MIDIFileReadStreamFile mfreader_stream( realname );
00159 MIDIFileReadMultiTrack track_loader( &tracks );
00160 MIDIFileRead reader( &mfreader_stream, &track_loader );
00161
00162 Stop();
00163 driver.AllNotesOff();
00164
00165 tracks.Clear();
00166 seq.ResetAllTracks();
00167
00168 if( reader.Parse() )
00169 {
00170 file_loaded=true;
00171
00172 Reset();
00173
00174 GoToMeasure( 0 );
00175 ExtractWarpPositions();
00176
00177 }
00178 else
00179 {
00180 file_loaded=false;
00181 }
00182 return file_loaded;
00183 }
00184
00185
00186 void AdvancedSequencer::Reset()
00187 {
00188 Stop();
00189 driver.AllNotesOff();
00190 UnmuteAllTracks();
00191 UnSoloTrack();
00192 SetTempoScale( 1.00 );
00193
00194 seq.ResetAllTracks();
00195 GoToMeasure( 0 );
00196
00197 }
00198
00199 void AdvancedSequencer::GoToTime( MIDIClockTime t )
00200 {
00201 if( mgr.IsSeqPlay() )
00202 {
00203 Stop();
00204 seq.GoToTime( t+1 );
00205 Play();
00206 }
00207 else
00208 {
00209 seq.GoToTime( t+1 );
00210 }
00211
00212 }
00213
00214
00215 void AdvancedSequencer::GoToMeasure( int measure, int beat )
00216 {
00217 if( !file_loaded )
00218 {
00219 return;
00220 }
00221
00222
00223
00224
00225 int warp_to_item = (measure-1) / MEASURES_PER_WARP;
00226
00227
00228 if( warp_to_item >= num_warp_positions )
00229 warp_to_item = num_warp_positions-1;
00230
00231 if( warp_to_item<0 )
00232 warp_to_item=0;
00233
00234
00235 if( mgr.IsSeqPlay() )
00236 {
00237 Stop();
00238
00239 if( warp_positions[warp_to_item] )
00240 {
00241 seq.SetState( warp_positions[warp_to_item] );
00242 }
00243 seq.GoToMeasure( measure, beat );
00244 Play();
00245 }
00246 else
00247 {
00248 if( warp_positions[warp_to_item] )
00249 {
00250 seq.SetState( warp_positions[warp_to_item] );
00251 }
00252
00253 seq.GoToMeasure( measure, beat );
00254 for( int i=0; i<seq.GetNumTracks(); ++i )
00255 {
00256 seq.GetTrackState(i)->note_matrix.Clear();
00257 }
00258 }
00259 }
00260
00261
00262 void AdvancedSequencer::Play( int clock_offset )
00263 {
00264 if( !file_loaded )
00265 {
00266 return;
00267 }
00268
00269 Stop();
00270
00271 for( int i=0; i<seq.GetNumTracks(); ++i )
00272 {
00273 seq.GetTrackState(i)->note_matrix.Clear();
00274 }
00275
00276
00277 if( repeat_play_mode )
00278 {
00279 seq.GoToMeasure( repeat_start_measure );
00280 }
00281
00282 MIDIClockTime cur_time = seq.GetCurrentMIDIClockTime();
00283
00284 if( (long)cur_time>-clock_offset )
00285 cur_time+=clock_offset;
00286
00287 seq.GoToTime( cur_time );
00288
00289 mgr.SetSeqOffset( (unsigned long)seq.GetCurrentTimeInMs() );
00290 mgr.SetTimeOffset( 0 );
00291
00292 mgr.SeqPlay();
00293 }
00294
00295
00296
00297 void AdvancedSequencer::RepeatPlay( bool enable, int start_measure, int end_measure )
00298 {
00299 if( !file_loaded )
00300 {
00301 return;
00302 }
00303
00304 if( start_measure < end_measure && start_measure>=0 )
00305 {
00306 repeat_play_mode = enable;
00307 repeat_start_measure = start_measure;
00308 repeat_end_measure = end_measure;
00309 }
00310 else
00311 {
00312 repeat_play_mode = false;
00313 }
00314
00315 mgr.SetRepeatPlay(
00316 repeat_play_mode,
00317 repeat_start_measure,
00318 repeat_end_measure
00319 );
00320 }
00321
00322
00323 void AdvancedSequencer::Pause()
00324 {
00325 if( !file_loaded )
00326 {
00327 return;
00328 }
00329 Stop();
00330 }
00331
00332
00333 void AdvancedSequencer::Stop()
00334 {
00335 if( !file_loaded )
00336 {
00337 return;
00338 }
00339 if( !mgr.IsSeqStop() )
00340 {
00341 mgr.SeqStop();
00342
00343 driver.AllNotesOff();
00344 for( int i=0; i<seq.GetNumTracks(); ++i )
00345 {
00346 seq.GetTrackState(i)->note_matrix.Clear();
00347 }
00348
00349 }
00350 }
00351
00352
00353
00354 void AdvancedSequencer::UnmuteAllTracks()
00355 {
00356 if( !file_loaded )
00357 {
00358 return;
00359 }
00360 for( int i=0; i<seq.GetNumTracks(); ++i )
00361 {
00362 if( seq.GetTrackProcessor(i)->mute )
00363 {
00364 seq.GetTrackState(i)->note_matrix.Clear();
00365 seq.GetTrackProcessor(i)->mute = false;
00366 }
00367 }
00368
00369 driver.AllNotesOff();
00370 }
00371
00372 void AdvancedSequencer::SoloTrack( int trk )
00373 {
00374 if( !file_loaded )
00375 {
00376 return;
00377 }
00378 if( trk==-1 )
00379 {
00380 seq.SetSoloMode(false);
00381 driver.AllNotesOff();
00382
00383 for( int i=0; i<seq.GetNumTracks(); ++i )
00384 {
00385 seq.GetTrackState(i)->note_matrix.Clear();
00386 }
00387 }
00388 else
00389 {
00390 seq.SetSoloMode(true,trk);
00391 driver.AllNotesOff();
00392
00393 for( int i=0; i<seq.GetNumTracks(); ++i )
00394 {
00395 seq.GetTrackState(i)->note_matrix.Clear();
00396 }
00397
00398 }
00399 }
00400
00401
00402 void AdvancedSequencer::UnSoloTrack()
00403 {
00404 if( !file_loaded )
00405 {
00406 return;
00407 }
00408 seq.SetSoloMode( false );
00409 driver.AllNotesOff();
00410 for( int i=0; i<seq.GetNumTracks(); ++i )
00411 {
00412 seq.GetTrackState(i)->note_matrix.Clear();
00413 }
00414 }
00415
00416
00417 void AdvancedSequencer::SetTrackMute( int trk, bool f )
00418 {
00419 if( !file_loaded )
00420 {
00421 return;
00422 }
00423 seq.GetTrackProcessor(trk)->mute = f;
00424 driver.AllNotesOff();
00425 }
00426
00427
00428
00429 void AdvancedSequencer::SetTempoScale( double scale )
00430 {
00431 if( !file_loaded )
00432 {
00433 return;
00434 }
00435 seq.SetCurrentTempoScale( scale );
00436 }
00437
00438
00439 double AdvancedSequencer::GetTempoWithoutScale() const
00440 {
00441 return seq.GetCurrentTempo();
00442 }
00443
00444
00445 double AdvancedSequencer::GetTempoWithScale() const
00446 {
00447 return seq.GetCurrentTempo() * seq.GetCurrentTempoScale();
00448 }
00449
00450
00451
00452 int AdvancedSequencer::GetMeasure() const
00453 {
00454 if( !file_loaded )
00455 {
00456 return 0;
00457 }
00458
00459 return seq.GetCurrentMeasure();
00460 }
00461
00462
00463 int AdvancedSequencer::GetBeat() const
00464 {
00465 if( !file_loaded )
00466 {
00467 return 0;
00468 }
00469
00470 return seq.GetCurrentBeat();
00471 }
00472
00473
00474
00475 int AdvancedSequencer::GetTimeSigNumerator() const
00476 {
00477 if( !file_loaded )
00478 {
00479 return 4;
00480 }
00481 return seq.GetTrackState(0)->timesig_numerator;
00482 }
00483
00484
00485 int AdvancedSequencer::GetTimeSigDenominator() const
00486 {
00487 if( !file_loaded )
00488 {
00489 return 4;
00490 }
00491
00492 return seq.GetTrackState(0)->timesig_denominator;
00493 }
00494
00495
00496
00497 int AdvancedSequencer::GetTrackNoteCount( int trk ) const
00498 {
00499 if( !file_loaded )
00500 {
00501 return 0;
00502 }
00503
00504 if( mgr.IsSeqStop() )
00505 {
00506 return 0;
00507 }
00508 else
00509 {
00510 return seq.GetTrackState(trk)->note_matrix.GetTotalCount();
00511 }
00512 }
00513
00514
00515 const char *AdvancedSequencer::GetTrackName( int trk ) const
00516 {
00517 if( !file_loaded )
00518 {
00519 return "";
00520 }
00521
00522 return seq.GetTrackState(trk)->track_name;
00523 }
00524
00525
00526 int AdvancedSequencer::GetTrackVolume( int trk ) const
00527 {
00528 if( !file_loaded )
00529 {
00530 return 100;
00531 }
00532
00533 return seq.GetTrackState(trk)->volume;
00534 }
00535
00536
00537
00538 void AdvancedSequencer::SetTrackVelocityScale( int trk, int scale )
00539 {
00540 if( !file_loaded )
00541 {
00542 return;
00543 }
00544
00545 seq.GetTrackProcessor(trk)->velocity_scale = scale;
00546 }
00547
00548
00549 int AdvancedSequencer::GetTrackVelocityScale( int trk ) const
00550 {
00551 if( !file_loaded )
00552 {
00553 return 100;
00554 }
00555
00556 return seq.GetTrackProcessor(trk)->velocity_scale;
00557 }
00558
00559
00560
00561 void AdvancedSequencer::SetTrackRechannelize( int trk, int chan )
00562 {
00563 if( !file_loaded )
00564 {
00565 return;
00566 }
00567
00568 seq.GetTrackProcessor(trk)->rechannel = chan;
00569 driver.AllNotesOff();
00570 seq.GetTrackState(trk)->note_matrix.Clear();
00571
00572 }
00573
00574
00575 int AdvancedSequencer::GetTrackRechannelize( int trk ) const
00576 {
00577 if( !file_loaded )
00578 {
00579 return -1;
00580 }
00581
00582
00583 return seq.GetTrackProcessor(trk)->rechannel;
00584 }
00585
00586
00587
00588 void AdvancedSequencer::SetTrackTranspose( int trk, int trans )
00589 {
00590 if( !file_loaded )
00591 {
00592 return;
00593 }
00594
00595 bool was_playing=mgr.IsSeqPlay();
00596
00597 if( mgr.IsSeqPlay() )
00598 {
00599 was_playing=true;
00600 mgr.SeqStop();
00601 }
00602
00603 if( trk==-1 )
00604 {
00605 for( trk=0; trk<tracks.GetNumTracks(); ++trk )
00606 {
00607 seq.GetTrackProcessor(trk)->transpose = trans;
00608 }
00609 }
00610 else
00611 {
00612 seq.GetTrackProcessor(trk)->transpose = trans;
00613 }
00614
00615 if( was_playing )
00616 {
00617 #if 0
00618 driver.ResetMIDIOut();
00619 driver.AllNotesOff();
00620 #endif
00621 seq.GetTrackState(trk)->note_matrix.Clear();
00622
00623 mgr.SeqPlay();
00624 }
00625
00626 }
00627
00628
00629 int AdvancedSequencer::GetTrackTranspose( int trk ) const
00630 {
00631 if( !file_loaded )
00632 {
00633 return 0;
00634 }
00635
00636 return seq.GetTrackProcessor(trk)->transpose;
00637 }
00638
00639
00640
00641
00642 void AdvancedSequencer::ExtractMarkers( std::vector< std::string > *list )
00643 {
00644 if( !file_loaded )
00645 {
00646 list->clear();
00647 num_markers=0;
00648 return;
00649 }
00650
00651 MIDITrack *t = tracks.GetTrack(0);
00652
00653 list->clear();
00654 int cnt=0;
00655
00656 int measure=0;
00657 int beat=0;
00658
00659 int timesig_numerator=4;
00660 int timesig_denominator=4;
00661
00662 MIDIClockTime last_beat_time=0;
00663 MIDIClockTime last_event_time=0;
00664 int clks_per_beat=tracks.GetClksPerBeat();
00665
00666 for( int i=0; i<t->GetNumEvents(); ++i )
00667 {
00668 MIDITimedBigMessage *m = t->GetEventAddress(i);
00669
00670 if( m )
00671 {
00672
00673
00674 long beats_gone_by = (m->GetTime()-last_beat_time)/clks_per_beat;
00675
00676 if( beats_gone_by>0 )
00677 {
00678
00679 beat += beats_gone_by;
00680
00681 measure += beat/timesig_numerator;
00682 beat = beat%timesig_numerator;
00683 last_beat_time += (clks_per_beat * beats_gone_by);
00684 }
00685
00686
00687 if( m->IsMetaEvent() && m->IsTimeSig() )
00688 {
00689 timesig_numerator = m->GetTimeSigNumerator();
00690 timesig_denominator = m->GetTimeSigDenominator();
00691 clks_per_beat=tracks.GetClksPerBeat() * 4 / timesig_denominator;
00692 }
00693
00694 if( m->IsTextEvent() && m->GetSysEx() )
00695 {
00696 if( (m->GetMetaType() == META_GENERIC_TEXT )
00697 || m->GetMetaType() == META_MARKER_TEXT
00698 || m->GetMetaType() == META_CUE_TEXT )
00699 {
00700 char buf[256];
00701 char line[256];
00702
00703 memcpy( buf, m->GetSysEx()->GetBuf(), m->GetSysEx()->GetLength() );
00704 buf[ m->GetSysEx()->GetLength() ] = '\0';
00705 FixQuotes( buf );
00706
00707 sprintf( line, "%03d:%d %s", measure+1, beat+1, buf );
00708 list->push_back( std::string(line) );
00709 marker_times[ cnt++ ] = m->GetTime();
00710 }
00711 }
00712
00713 last_event_time = m->GetTime();
00714 }
00715 }
00716 num_markers = cnt;
00717 }
00718
00719
00720 int AdvancedSequencer::GetCurrentMarker() const
00721 {
00722 if( !file_loaded )
00723 {
00724 return -1;
00725 }
00726
00727
00728
00729
00730 MIDIClockTime cur_time = seq.GetCurrentMIDIClockTime();
00731
00732 cur_time+=20;
00733
00734 int last=-1;
00735
00736 for( int i=0; i<num_markers; ++i )
00737 {
00738 if( marker_times[i] > cur_time )
00739 {
00740 break;
00741 }
00742 else
00743 {
00744 last=i;
00745 }
00746 }
00747 return last;
00748 }
00749
00750
00751
00752 int AdvancedSequencer::FindFirstChannelOnTrack(int trk)
00753 {
00754 if( !file_loaded )
00755 {
00756 return -1;
00757 }
00758
00759 int first_channel = -1;
00760
00761 MIDITrack *t = tracks.GetTrack(trk);
00762
00763 if( t )
00764 {
00765
00766
00767
00768
00769 for( int i=0; i<t->GetNumEvents(); ++i )
00770 {
00771 MIDITimedBigMessage *m = t->GetEventAddress(i);
00772
00773 if( m )
00774 {
00775 if( m->IsChannelMsg() )
00776 {
00777 first_channel = m->GetChannel() + 1;
00778 break;
00779 }
00780 }
00781 }
00782
00783 }
00784
00785 return first_channel;
00786 }
00787
00788
00789 void AdvancedSequencer::ExtractWarpPositions()
00790 {
00791 if( !file_loaded )
00792 {
00793 for( int i=0; i<num_warp_positions; ++i )
00794 {
00795 delete warp_positions[i];
00796 }
00797 num_warp_positions=0;
00798 return;
00799 }
00800
00801 Stop();
00802
00803
00804
00805 for( int i=0; i<num_warp_positions; ++i )
00806 {
00807 delete warp_positions[i];
00808 }
00809 num_warp_positions=0;
00810
00811
00812
00813 while(num_warp_positions<MAX_WARP_POSITIONS)
00814 {
00815 if( !seq.GoToMeasure( num_warp_positions*MEASURES_PER_WARP, 0 ) )
00816 {
00817 break;
00818 }
00819
00820
00821 warp_positions[num_warp_positions++] =
00822 new MIDISequencerState(
00823 *seq.GetState()
00824 );
00825 }
00826
00827 seq.GoToMeasure( 0,0 );
00828 }
00829
00830 }