00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "jdkmidi/world.h"
00025 #include "jdkmidi/sequencer.h"
00026
00027 namespace jdkmidi
00028 {
00029
00030 static void FixQuotes( char *s_ )
00031 {
00032 unsigned char *s = (unsigned char *)s_;
00033 while( *s )
00034 {
00035 if( *s==0xd2 || *s==0xd3 )
00036 {
00037 *s='"';
00038 }
00039 else if( *s==0xd5 )
00040 {
00041 *s='\'';
00042 }
00043 else if( *s>=0x80 )
00044 {
00045 *s = ' ';
00046 }
00047 s++;
00048 }
00049 }
00050
00052
00053 MIDISequencerGUIEventNotifier::MIDISequencerGUIEventNotifier()
00054 {
00055 }
00056
00057 MIDISequencerGUIEventNotifier::~MIDISequencerGUIEventNotifier()
00058 {
00059 }
00060
00061
00062
00064
00065
00066 MIDISequencerGUIEventNotifierText::MIDISequencerGUIEventNotifierText(
00067 FILE *f_
00068 )
00069 :
00070 f(f_),
00071 en(true)
00072 {
00073
00074 }
00075
00076 MIDISequencerGUIEventNotifierText::~MIDISequencerGUIEventNotifierText()
00077 {
00078 }
00079
00080
00081 void MIDISequencerGUIEventNotifierText::Notify(
00082 const MIDISequencer *seq,
00083 MIDISequencerGUIEvent e
00084 )
00085 {
00086 if( en )
00087 {
00088 fprintf( f, "GUI EVENT: G=%d, SG=%d, ITEM=%d\n",
00089 e.GetEventGroup(),
00090 e.GetEventSubGroup(),
00091 e.GetEventItem()
00092 );
00093
00094 if( e.GetEventGroup() == MIDISequencerGUIEvent::GROUP_TRANSPORT )
00095 {
00096 if(
00097 e.GetEventItem() == MIDISequencerGUIEvent::GROUP_TRANSPORT_BEAT
00098 )
00099 {
00100 fprintf( f, "MEAS %3d BEAT %3d\n",
00101 seq->GetCurrentMeasure()+1,
00102 seq->GetCurrentBeat()+1
00103 );
00104 }
00105 }
00106 else
00107 if( e.GetEventGroup() == MIDISequencerGUIEvent::GROUP_CONDUCTOR )
00108 {
00109
00110 if(
00111 e.GetEventItem() == MIDISequencerGUIEvent::GROUP_CONDUCTOR_TIMESIG
00112 )
00113 {
00114 fprintf( f, "TIMESIG: %d/%d\n",
00115 seq->GetTrackState(0)->timesig_numerator,
00116 seq->GetTrackState(0)->timesig_denominator
00117 );
00118 }
00119 if(
00120 e.GetEventItem() == MIDISequencerGUIEvent::GROUP_CONDUCTOR_TEMPO
00121 )
00122 {
00123 fprintf( f, "TEMPO: %3.2f\n",
00124 seq->GetTrackState(0)->tempobpm
00125 );
00126 }
00127 }
00128 }
00129 }
00130
00131 bool MIDISequencerGUIEventNotifierText::GetEnable() const
00132 {
00133 return en;
00134 }
00135
00136 void MIDISequencerGUIEventNotifierText::SetEnable( bool f )
00137 {
00138 en = f;
00139 }
00140
00142
00143 MIDISequencerTrackNotifier::MIDISequencerTrackNotifier(
00144 MIDISequencer *seq_,
00145 int trk,
00146 MIDISequencerGUIEventNotifier *n
00147 )
00148 :
00149 seq( seq ),
00150 track_num( trk ),
00151 notifier( n )
00152 {
00153
00154 }
00155
00156 MIDISequencerTrackNotifier::~MIDISequencerTrackNotifier()
00157 {
00158
00159 }
00160
00161 void MIDISequencerTrackNotifier::Notify( int item )
00162 {
00163 if( notifier )
00164 {
00165 notifier->Notify(
00166 seq,
00167 MIDISequencerGUIEvent(
00168 MIDISequencerGUIEvent::GROUP_TRACK,
00169 track_num,
00170 item
00171 )
00172 );
00173 }
00174 }
00175
00176 void MIDISequencerTrackNotifier::NotifyConductor( int item )
00177 {
00178
00179 if( notifier && track_num==0 )
00180 {
00181 notifier->Notify(
00182 seq,
00183 MIDISequencerGUIEvent(
00184 MIDISequencerGUIEvent::GROUP_CONDUCTOR,
00185 0,
00186 item
00187 )
00188 );
00189 }
00190 }
00191
00193
00194 MIDISequencerTrackProcessor::MIDISequencerTrackProcessor()
00195 :
00196 mute(false),
00197 solo(false),
00198 velocity_scale(100),
00199 rechannel(-1),
00200 transpose(0),
00201 extra_proc(0)
00202 {
00203 }
00204
00205
00206 MIDISequencerTrackProcessor::~MIDISequencerTrackProcessor()
00207 {
00208 }
00209
00210
00211 void MIDISequencerTrackProcessor::Reset()
00212 {
00213 mute=false;
00214 solo=false;
00215 velocity_scale=100;
00216 rechannel=-1;
00217 transpose=0;
00218 }
00219
00220
00221 bool MIDISequencerTrackProcessor::Process( MIDITimedBigMessage *msg )
00222 {
00223
00224
00225
00226 if( mute )
00227 {
00228
00229 return false;
00230 }
00231
00232
00233
00234 if( msg->IsNoOp() )
00235 {
00236
00237
00238 return false;
00239 }
00240
00241
00242
00243 if( extra_proc && extra_proc->Process(msg)==false )
00244 {
00245
00246 return false;
00247 }
00248
00249
00250 if( msg->IsChannelMsg() )
00251 {
00252
00253 if( rechannel!=-1 )
00254 {
00255 msg->SetChannel( (unsigned char)rechannel );
00256 }
00257
00258
00259 if( msg->IsNoteOn() && msg->GetVelocity()>0 )
00260 {
00261
00262
00263 int vel = (int)msg->GetVelocity();
00264
00265 vel = vel*velocity_scale / 100;
00266
00267
00268
00269 if( vel<0 )
00270 {
00271 vel=0;
00272 }
00273
00274
00275
00276 msg->SetVelocity( (unsigned char)vel );
00277
00278 }
00279
00280
00281
00282 if( msg->IsNoteOn() || msg->IsNoteOff() || msg->IsPolyPressure() )
00283 {
00284 int new_note = ((int)msg->GetNote())+transpose;
00285
00286 if( new_note>=0 && new_note<=127 )
00287 {
00288
00289 msg->SetNote( (unsigned char)new_note );
00290 }
00291 else
00292 {
00293
00294 return false;
00295 }
00296
00297 }
00298
00299 }
00300
00301 return true;
00302 }
00303
00304
00306
00307 MIDISequencerTrackState::MIDISequencerTrackState(
00308 MIDISequencer *seq_,
00309 int trk,
00310 MIDISequencerGUIEventNotifier *n
00311 )
00312 :
00313 MIDISequencerTrackNotifier( seq_, trk, n ),
00314 tempobpm( 120.0 ),
00315 volume(100),
00316 timesig_numerator(4),
00317 timesig_denominator(4),
00318 bender_value(0),
00319 got_good_track_name(false),
00320 notes_are_on(false),
00321 note_matrix()
00322 {
00323 *track_name = 0;
00324 }
00325
00326
00327 MIDISequencerTrackState::~MIDISequencerTrackState()
00328 {
00329 }
00330
00331 void MIDISequencerTrackState::GoToZero()
00332 {
00333 tempobpm = 120.0;
00334 timesig_numerator=4;
00335 timesig_denominator=4;
00336 bender_value=0;
00337 note_matrix.Clear();
00338 }
00339
00340 void MIDISequencerTrackState::Reset()
00341 {
00342 tempobpm = 120.0;
00343 volume=100;
00344 notes_are_on=false;
00345 timesig_numerator=4;
00346 timesig_denominator=4;
00347 bender_value=0;
00348 *track_name=0;
00349 note_matrix.Clear();
00350 got_good_track_name=false;
00351 }
00352
00353
00354 bool MIDISequencerTrackState::Process( MIDITimedBigMessage *msg )
00355 {
00356
00357
00358 if( msg->IsNoOp() )
00359 {
00360
00361
00362 return false;
00363 }
00364
00365
00366 if( msg->IsChannelMsg() )
00367 {
00368
00369 if( msg->GetType()==PITCH_BEND )
00370 {
00371
00372
00373
00374 bender_value = msg->GetBenderValue();
00375 }
00376 else if( msg->IsControlChange() )
00377 {
00378
00379
00380
00381
00382 if( msg->GetController()==C_MAIN_VOLUME )
00383 {
00384
00385 volume = msg->GetControllerValue();
00386
00387 Notify(
00388 MIDISequencerGUIEvent::GROUP_TRACK_VOLUME
00389 );
00390 }
00391 }
00392 else if( msg->IsProgramChange() )
00393 {
00394
00395
00396
00397 pg = msg->GetPGValue();
00398
00399 Notify(
00400 MIDISequencerGUIEvent::GROUP_TRACK_PG
00401 );
00402 }
00403
00404 }
00405 else
00406 {
00407
00408 if( msg->IsMetaEvent() )
00409 {
00410
00411 if( msg->IsTempo() )
00412 {
00413
00414
00415 tempobpm = ((float)msg->GetTempo32())*(1.0f/32.0f);
00416 if(tempobpm<1 )
00417 {
00418 tempobpm=120.0;
00419 }
00420
00421 NotifyConductor(
00422 MIDISequencerGUIEvent::GROUP_CONDUCTOR_TEMPO
00423 );
00424 }
00425 else
00426 if( msg->GetMetaType()==META_TIMESIG )
00427 {
00428
00429
00430 timesig_numerator = msg->GetTimeSigNumerator();
00431 timesig_denominator = msg->GetTimeSigDenominator();
00432
00433 NotifyConductor(
00434 MIDISequencerGUIEvent::GROUP_CONDUCTOR_TIMESIG
00435 );
00436
00437 }
00438 else
00439 if( ( msg->GetMetaType()==META_TRACK_NAME
00440 || msg->GetMetaType()==META_INSTRUMENT_NAME
00441 || (!got_good_track_name && msg->GetMetaType()==META_GENERIC_TEXT && msg->GetTime()==0)
00442 )
00443 &&
00444 msg->GetSysEx() )
00445 {
00446 got_good_track_name = true;
00447
00448
00449 int len = msg->GetSysEx()->GetLength();
00450
00451 if( len>(int)sizeof(track_name)-1 )
00452 len=(int)sizeof(track_name)-1;
00453
00454 memcpy(track_name, msg->GetSysEx()->GetBuf(), len );
00455
00456 track_name[len]='\0';
00457
00458 FixQuotes( track_name );
00459
00460 Notify(
00461 MIDISequencerGUIEvent::GROUP_TRACK_NAME
00462 );
00463
00464 }
00465
00466 }
00467
00468 }
00469
00470
00471
00472
00473 if( note_matrix.Process( *msg ) )
00474 {
00475
00476
00477 if( ( notes_are_on && note_matrix.GetTotalCount()==0)
00478 || (!notes_are_on && note_matrix.GetTotalCount()>0 ) )
00479 {
00480
00481 notes_are_on = !notes_are_on;
00482
00483
00484 Notify(
00485 MIDISequencerGUIEvent::GROUP_TRACK_NOTE
00486 );
00487 }
00488 }
00489
00490
00491 return true;
00492 }
00493
00495
00496 MIDISequencerState::MIDISequencerState(
00497 MIDISequencer *s,
00498 MIDIMultiTrack * m,
00499 MIDISequencerGUIEventNotifier *n
00500 )
00501 :
00502 notifier(n),
00503 multitrack(m),
00504 num_tracks( m->GetNumTracks() ),
00505 iterator( m ),
00506 cur_clock(0),
00507 cur_time_ms(0),
00508 cur_beat(0),
00509 cur_measure(0),
00510 next_beat_time(0)
00511 {
00512
00513 for( int i=0; i<num_tracks; ++i )
00514 {
00515 track_state[i] = new MIDISequencerTrackState( s, i, notifier );
00516 }
00517 }
00518
00519 MIDISequencerState::MIDISequencerState( const MIDISequencerState &s )
00520 :
00521 notifier(s.notifier),
00522 multitrack(s.multitrack),
00523 num_tracks( s.num_tracks ),
00524 iterator( s.iterator ),
00525 cur_clock( s.cur_clock),
00526 cur_time_ms( s.cur_time_ms),
00527 cur_beat( s.cur_beat),
00528 cur_measure( s.cur_measure),
00529 next_beat_time(s.next_beat_time)
00530 {
00531
00532 for( int i=0; i<num_tracks; ++i )
00533 {
00534 track_state[i] = new MIDISequencerTrackState( *s.track_state[i] );
00535 }
00536
00537 }
00538
00539
00540 MIDISequencerState::~MIDISequencerState()
00541 {
00542 for( int i=0; i<num_tracks; ++i )
00543 {
00544 delete track_state[i];
00545 }
00546 }
00547
00548 const MIDISequencerState & MIDISequencerState::operator = ( const MIDISequencerState & s )
00549 {
00550 if( num_tracks!=s.num_tracks )
00551 {
00552 {
00553 for( int i=0; i<num_tracks; ++i )
00554 {
00555 delete track_state[i];
00556 }
00557 }
00558
00559
00560 num_tracks = s.num_tracks;
00561
00562 {
00563 for( int i=0; i<num_tracks; ++i )
00564 {
00565 track_state[i] = new MIDISequencerTrackState( *s.track_state[i] );
00566 }
00567 }
00568
00569 }
00570
00571
00572 iterator = s.iterator;
00573 cur_clock = s.cur_clock;
00574 cur_time_ms = s.cur_time_ms;
00575 cur_beat = s.cur_beat;
00576 cur_measure = s.cur_measure;
00577 next_beat_time = s.next_beat_time;
00578
00579 return *this;
00580 }
00581
00582
00584
00585
00586 MIDISequencer::MIDISequencer(
00587 MIDIMultiTrack *m,
00588 MIDISequencerGUIEventNotifier *n
00589 )
00590 :
00591 solo_mode(false),
00592 tempo_scale(100),
00593 num_tracks( m->GetNumTracks() ),
00594 state( this, m,n )
00595 {
00596
00597 for( int i=0; i<num_tracks; ++i )
00598 {
00599 track_processors[i] = new MIDISequencerTrackProcessor;
00600 }
00601 }
00602
00603
00604 MIDISequencer::~MIDISequencer()
00605 {
00606 for(int i=0; i<num_tracks; ++i )
00607 {
00608 delete track_processors[i];
00609 }
00610 }
00611
00612 void MIDISequencer::ResetTrack( int trk )
00613 {
00614 state.track_state[trk]->Reset();
00615 track_processors[trk]->Reset();
00616 }
00617
00618 void MIDISequencer::ResetAllTracks()
00619 {
00620 for( int i=0; i<num_tracks; ++i )
00621 {
00622 state.track_state[i]->Reset();
00623 track_processors[i]->Reset();
00624 }
00625 }
00626
00627 MIDISequencerState *MIDISequencer::GetState()
00628 {
00629 return &state;
00630 }
00631
00632 const MIDISequencerState *MIDISequencer::GetState() const
00633 {
00634 return &state;
00635 }
00636
00637 void MIDISequencer::SetState( MIDISequencerState *s )
00638 {
00639 state = *s;
00640 }
00641
00642 MIDIClockTime MIDISequencer::GetCurrentMIDIClockTime() const
00643 {
00644 return state.cur_clock;
00645 }
00646
00647 double MIDISequencer::GetCurrentTimeInMs() const
00648 {
00649 return state.cur_time_ms;
00650 }
00651
00652 int MIDISequencer::GetCurrentBeat() const
00653 {
00654 return state.cur_beat;
00655 }
00656
00657
00658 int MIDISequencer::GetCurrentMeasure() const
00659 {
00660 return state.cur_measure;
00661 }
00662
00663 double MIDISequencer::GetCurrentTempoScale() const
00664 {
00665 return ((double)tempo_scale)*0.01;
00666 }
00667
00668 double MIDISequencer::GetCurrentTempo() const
00669 {
00670 return state.track_state[0]->tempobpm;
00671 }
00672
00673 MIDISequencerTrackState * MIDISequencer::GetTrackState( int trk )
00674 {
00675 return state.track_state[trk];
00676 }
00677
00678 const MIDISequencerTrackState * MIDISequencer::GetTrackState( int trk ) const
00679 {
00680 return state.track_state[ trk ];
00681 }
00682
00683 MIDISequencerTrackProcessor * MIDISequencer::GetTrackProcessor( int trk )
00684 {
00685 return track_processors[trk];
00686 }
00687
00688 const MIDISequencerTrackProcessor * MIDISequencer::GetTrackProcessor( int trk ) const
00689 {
00690 return track_processors[ trk ];
00691 }
00692
00693 bool MIDISequencer::GetSoloMode() const
00694 {
00695 return solo_mode;
00696 }
00697
00698 void MIDISequencer::SetCurrentTempoScale( float scale )
00699 {
00700 tempo_scale = (int)(scale*100);
00701 }
00702
00703 void MIDISequencer::SetSoloMode( bool m, int trk )
00704 {
00705 int i;
00706 solo_mode = m;
00707
00708 for( i=0; i<num_tracks; ++i )
00709 {
00710 if( i==trk )
00711 {
00712 track_processors[i]->solo = true;
00713 }
00714 else
00715 {
00716 track_processors[i]->solo = false;
00717 }
00718 }
00719
00720 }
00721
00722 void MIDISequencer::GoToZero()
00723 {
00724
00725
00726 for( int i=0; i<num_tracks; ++i )
00727 {
00728 state.track_state[i]->GoToZero();
00729 }
00730
00731 state.iterator.GoToTime( 0 );
00732
00733 state.cur_time_ms = 0.0;
00734 state.cur_clock = 0;
00735
00736
00737 state.next_beat_time =
00738 state.multitrack->GetClksPerBeat()
00739 * 4 / (state.track_state[0]->timesig_denominator);
00740
00741
00742
00743
00744 ScanEventsAtThisTime();
00745 }
00746
00747 bool MIDISequencer::GoToTime( MIDIClockTime time_clk )
00748 {
00749
00750
00751 bool notifier_mode=false;
00752 if( state.notifier )
00753 {
00754 notifier_mode = state.notifier->GetEnable();
00755 state.notifier->SetEnable(false);
00756 }
00757
00758 if( time_clk < state.cur_clock || time_clk==0 )
00759 {
00760
00761 for( int i=0; i<state.num_tracks; ++i )
00762 {
00763 state.track_state[i]->GoToZero();
00764 }
00765
00766 state.iterator.GoToTime( 0 );
00767
00768 state.cur_time_ms = 0.0;
00769 state.cur_clock = 0;
00770
00771 state.next_beat_time =
00772 state.multitrack->GetClksPerBeat()
00773 * 4 / (state.track_state[0]->timesig_denominator);
00774
00775 state.cur_beat = 0;
00776 state.cur_measure = 0;
00777
00778 }
00779
00780 MIDIClockTime t=0;
00781 int trk;
00782 MIDITimedBigMessage ev;
00783
00784 while(
00785 GetNextEventTime( &t )
00786 && t<time_clk
00787 && GetNextEvent(&trk,&ev)
00788 )
00789 {
00790 ;
00791 }
00792
00793
00794
00795
00796
00797 ScanEventsAtThisTime();
00798
00799
00800 if( state.notifier )
00801 {
00802 state.notifier->SetEnable( notifier_mode );
00803
00804
00805
00806 state.notifier->Notify( this, MIDISequencerGUIEvent::GROUP_ALL );
00807 }
00808
00809
00810
00811 return true;
00812
00813 }
00814
00815 bool MIDISequencer::GoToTimeMs( float time_ms )
00816 {
00817
00818
00819 bool notifier_mode=false;
00820 if( state.notifier )
00821 {
00822 notifier_mode = state.notifier->GetEnable();
00823 state.notifier->SetEnable(false);
00824 }
00825
00826 if( time_ms < state.cur_time_ms || time_ms==0.0 )
00827 {
00828
00829 for( int i=0; i<state.num_tracks; ++i )
00830 {
00831 state.track_state[i]->GoToZero();
00832 }
00833
00834 state.iterator.GoToTime( 0 );
00835
00836 state.cur_time_ms = 0.0;
00837 state.cur_clock = 0;
00838
00839 state.next_beat_time =
00840 state.multitrack->GetClksPerBeat()
00841 * 4 / (state.track_state[0]->timesig_denominator);
00842
00843 state.cur_beat = 0;
00844 state.cur_measure = 0;
00845 }
00846
00847 float t=0;
00848 int trk;
00849 MIDITimedBigMessage ev;
00850
00851 while(
00852 GetNextEventTimeMs( &t )
00853 && t<time_ms
00854 && GetNextEvent(&trk,&ev)
00855 )
00856 {
00857 ;
00858 }
00859
00860
00861
00862
00863
00864
00865
00866 if( state.notifier )
00867 {
00868 state.notifier->SetEnable( notifier_mode );
00869
00870
00871
00872 state.notifier->Notify( this, MIDISequencerGUIEvent::GROUP_ALL );
00873 }
00874
00875
00876 return true;
00877
00878 }
00879
00880 bool MIDISequencer::GoToMeasure( int measure, int beat )
00881 {
00882
00883
00884 bool notifier_mode=false;
00885 if( state.notifier )
00886 {
00887 notifier_mode = state.notifier->GetEnable();
00888 state.notifier->SetEnable(false);
00889 }
00890
00891 if( measure < state.cur_measure || measure==0 )
00892 {
00893 for( int i=0; i<state.num_tracks; ++i )
00894 {
00895 state.track_state[i]->GoToZero();
00896 }
00897
00898 state.iterator.GoToTime( 0 );
00899
00900 state.cur_time_ms = 0.0;
00901 state.cur_clock = 0;
00902 state.cur_beat = 0;
00903 state.cur_measure = 0;
00904
00905 state.next_beat_time =
00906 state.multitrack->GetClksPerBeat()
00907 * 4 / (state.track_state[0]->timesig_denominator);
00908
00909 }
00910
00911 MIDIClockTime t=0;
00912 int trk;
00913 MIDITimedBigMessage ev;
00914
00915
00916
00917
00918 while(
00919 GetNextEventTime( &t )
00920 && GetNextEvent(&trk,&ev)
00921 && state.cur_measure<=measure
00922 )
00923 {
00924 if( state.cur_measure==measure && state.cur_beat>=beat )
00925 {
00926 break;
00927 }
00928 }
00929
00930
00931
00932
00933
00934
00935 ScanEventsAtThisTime();
00936
00937
00938
00939
00940 if( state.notifier )
00941 {
00942 state.notifier->SetEnable( notifier_mode );
00943
00944
00945
00946 state.notifier->Notify( this, MIDISequencerGUIEvent::GROUP_ALL );
00947 }
00948
00949
00950
00951 return state.cur_measure == measure && state.cur_beat == beat;
00952
00953 }
00954
00955
00956
00957 bool MIDISequencer::GetNextEventTimeMs( float *t )
00958 {
00959 MIDIClockTime ct;
00960 bool f = GetNextEventTime( &ct );
00961
00962 if( f )
00963 {
00964
00965
00966 double delta_clocks = (double)(ct - state.cur_clock);
00967
00968
00969
00970 double clocks_per_sec = ((state.track_state[0]->tempobpm *
00971 (((double)tempo_scale)*0.01)
00972 * (1.0f/60.0f)) * state.multitrack->GetClksPerBeat());
00973
00974 if( clocks_per_sec>0 )
00975 {
00976 float ms_per_clock = 1000.0f /clocks_per_sec;
00977
00978
00979
00980 float delta_ms = float(delta_clocks * ms_per_clock);
00981
00982
00983
00984 *t = delta_ms + state.cur_time_ms;
00985 }
00986 else
00987 {
00988 f=false;
00989 }
00990 }
00991
00992 return f;
00993 }
00994
00995 bool MIDISequencer::GetNextEventTime( MIDIClockTime *t )
00996 {
00997
00998 bool f = state.iterator.GetCurEventTime(t);
00999
01000 if( f )
01001 {
01002
01003
01004
01005 if( (*t) >= state.next_beat_time )
01006 {
01007
01008
01009 *t = state.next_beat_time;
01010 }
01011 }
01012
01013 return f;
01014 }
01015
01016 bool MIDISequencer::GetNextEvent( int *tracknum, MIDITimedBigMessage *msg )
01017 {
01018 MIDIClockTime t;
01019
01020
01021
01022 if( state.iterator.GetCurEventTime(&t) )
01023 {
01024
01025
01026 MIDIClockTime new_clock;
01027 float new_time_ms;
01028
01029 GetNextEventTime( &new_clock );
01030 GetNextEventTimeMs( &new_time_ms );
01031
01032
01033
01034
01035 state.cur_clock = new_clock;
01036 state.cur_time_ms = new_time_ms;
01037
01038
01039
01040
01041 if( state.next_beat_time<=t )
01042 {
01043
01044
01045
01046 *tracknum = 0;
01047
01048
01049 beat_marker_msg.SetBeatMarker();
01050 beat_marker_msg.SetTime( state.next_beat_time );
01051 *msg = beat_marker_msg;
01052
01053
01054
01055 int new_beat = state.cur_beat+1;
01056 int new_measure = state.cur_measure;
01057
01058
01059
01060 if( new_beat>=state.track_state[0]->timesig_numerator )
01061 {
01062
01063
01064 new_beat=0;
01065 ++new_measure;
01066 }
01067
01068
01069
01070
01071
01072
01073
01074
01075
01076
01077 state.next_beat_time +=
01078 state.multitrack->GetClksPerBeat()
01079 * 4 / (state.track_state[0]->timesig_denominator);
01080
01081 state.cur_beat = new_beat;
01082 state.cur_measure = new_measure;
01083
01084
01085 state.notifier->Notify(
01086 this,
01087 MIDISequencerGUIEvent(
01088 MIDISequencerGUIEvent::GROUP_TRANSPORT,
01089 0,
01090 MIDISequencerGUIEvent::GROUP_TRANSPORT_BEAT
01091 )
01092 );
01093
01094
01095 if( state.cur_beat==0 )
01096 {
01097 state.notifier->Notify(
01098 this,
01099 MIDISequencerGUIEvent(
01100 MIDISequencerGUIEvent::GROUP_TRANSPORT,
01101 0,
01102 MIDISequencerGUIEvent::GROUP_TRANSPORT_MEASURE
01103 )
01104 );
01105 }
01106
01107
01108 state.track_state[*tracknum]->Process(msg);
01109
01110
01111 return true;
01112 }
01113 else
01114 {
01115 MIDITimedBigMessage *msg_ptr;
01116
01117 if( state.iterator.GetCurEvent( tracknum, &msg_ptr ) )
01118 {
01119 int trk=*tracknum;
01120
01121
01122
01123 *msg = *msg_ptr;
01124
01125 bool allow_msg=true;
01126
01127
01128
01129 if( solo_mode )
01130 {
01131
01132
01133
01134
01135 if( trk==0 || track_processors[trk]->solo )
01136 {
01137 allow_msg=true;
01138 }
01139 else
01140 {
01141 allow_msg=false;
01142 }
01143
01144 }
01145
01146
01147 if( !(allow_msg
01148 && track_processors[trk]->Process(msg)
01149 && state.track_state[trk]->Process(msg))
01150 )
01151 {
01152
01153
01154 msg->SetNoOp();
01155 }
01156
01157
01158 state.iterator.GoToNextEvent();
01159
01160 return true;
01161
01162 }
01163 }
01164 }
01165
01166 return false;
01167 }
01168
01169 void MIDISequencer::ScanEventsAtThisTime()
01170 {
01171
01172
01173 MIDIMultiTrackIteratorState istate( state.iterator.GetState() );
01174 int prev_measure = state.cur_measure;
01175 int prev_beat = state.cur_beat;
01176
01177
01178
01179
01180 MIDIClockTime orig_clock = state.cur_clock;
01181 double orig_time_ms = state.cur_time_ms;
01182
01183
01184 MIDIClockTime t=0;
01185 int trk;
01186 MIDITimedBigMessage ev;
01187
01188 while(
01189 GetNextEventTime( &t )
01190 && t==orig_clock
01191 && GetNextEvent(&trk,&ev)
01192 )
01193 {
01194 ;
01195 }
01196
01197
01198 state.iterator.SetState( istate );
01199
01200
01201 state.cur_clock = orig_clock;
01202 state.cur_time_ms = float(orig_time_ms);
01203
01204 state.cur_measure=prev_measure;
01205 state.cur_beat = prev_beat;
01206
01207 }
01208
01209
01210
01211
01212 }