bool MIDISequencer::GetNextEventTimeMs ( float *t )
{
    double t2;
    bool res = GetNextEventTimeMs ( &t2 );
    *t = ( float ) t2;
    return res;
}
bool MIDISequencer::GoToTimeMs ( float time_ms )
{
    // temporarily disable the gui notifier
    bool notifier_mode = false;

    if ( state.notifier )
    {
        notifier_mode = state.notifier->GetEnable();
        state.notifier->SetEnable ( false );
    }

    if ( time_ms < state.cur_time_ms || time_ms == 0.0 )
    {
        // start from zero if desired time is before where we are
        for ( int i = 0; i < state.num_tracks; ++i )
        {
            state.track_state[i]->GoToZero();
        }

        state.iterator.GoToTime ( 0 );
        state.cur_time_ms = 0.0;
        state.cur_clock = 0;
//  state.next_beat_time = state.multitrack->GetClksPerBeat();
        state.next_beat_time =
            state.multitrack->GetClksPerBeat()
            * 4 / ( state.track_state[0]->timesig_denominator );
        state.cur_beat = 0;
        state.cur_measure = 0;
    }

    float t = 0;
    int trk;
    MIDITimedBigMessage ev;

    while (
        GetNextEventTimeMs ( &t )
        && t < time_ms
        && GetNextEvent ( &trk, &ev )
    )
    {
        ;
    }

    // examine all the events at this specific time
    // and update the track states to reflect this time
// ScanEventsAtThisTime();

    // re-enable the gui notifier if it was enabled previously
    if ( state.notifier )
    {
        state.notifier->SetEnable ( notifier_mode );
        // cause a full gui refresh now
        state.notifier->Notify ( this, MIDISequencerGUIEvent::GROUP_ALL );
    }

    return true;
}
Exemplo n.º 3
0
 bool MIDISequencer::GetNextEvent( int *tracknum, MIDITimedBigMessage *msg ) 
 {
   MIDIClockTime t;
   
   
   // ask the iterator for the current event time
   if( state.iterator.GetCurEventTime(&t) )
   {
     // move current time forward one event
     
     MIDIClockTime new_clock;
     float new_time_ms=0.0f;
     
     GetNextEventTime( &new_clock );
     GetNextEventTimeMs( &new_time_ms );
     
     // must set cur_clock AFTER GetnextEventTimeMs() is called
     // since GetNextEventTimeMs() uses cur_clock to calculate
     
     state.cur_clock = new_clock;
     state.cur_time_ms = new_time_ms;
     
     
     // is the next beat marker before this event?
     
     if( state.next_beat_time<=t )
     {
       // yes, this is a beat event now.
       
       // say this event came on track 0, the conductor track
       *tracknum = 0;
       
       // put current info into beat marker message
       beat_marker_msg.SetBeatMarker();
       beat_marker_msg.SetTime( state.next_beat_time );
       *msg = beat_marker_msg;
       
       // update our beat count
       
       int new_beat = state.cur_beat+1;
       int new_measure = state.cur_measure;
       
       // do we need to update the measure number?
       
       if( new_beat>=state.track_state[0]->timesig_numerator )
       {
         // yup
         
         new_beat=0;
         ++new_measure;
       }
       
       // update our next beat time
       
       
       // denom=4  (16) ---> 4/16 midi file beats per symbolic beat
       // denom=3  (8)  ---> 4/8 midi file beats per symbolic beat
       // denom=2  (4)  ---> 4/4 midi file beat per symbolic beat
       // denom=1  (2)  ---> 4/2 midi file beats per symbolic beat
       // denom=0  (1)  ---> 4/1 midi file beats per symbolic beat
       
       state.next_beat_time +=
         state.multitrack->GetClksPerBeat()
         * 4 / (state.track_state[0]->timesig_denominator);
       
       state.cur_beat = new_beat;
       state.cur_measure = new_measure;
       
       // now notify the GUI that the beat number changed
       state.notifier->Notify(
         this,
         MIDISequencerGUIEvent(
           MIDISequencerGUIEvent::GROUP_TRANSPORT,
           0,
           MIDISequencerGUIEvent::GROUP_TRANSPORT_BEAT
           )
         );
       
       // if the new beat number is 0 then the measure changed too
       if( state.cur_beat==0 )
       {
         state.notifier->Notify(
           this,
           MIDISequencerGUIEvent(
             MIDISequencerGUIEvent::GROUP_TRANSPORT,
             0,
             MIDISequencerGUIEvent::GROUP_TRANSPORT_MEASURE
             )
           );
       }
       
       // give the beat marker event to the conductor track to process
       state.track_state[*tracknum]->Process(msg);
       
       
       return true;
     }
     else	// this event comes before the next beat
     {
       MIDITimedBigMessage *msg_ptr;
       
       if( state.iterator.GetCurEvent( tracknum, &msg_ptr ) )
       {
         int trk=*tracknum;
         
         // copy the event so Process can modify it
         
         *msg = *msg_ptr;
         
         bool allow_msg=true;
         
         // are we in solo mode?
         
         if( solo_mode )
         {
           // yes, only allow this message thru if
           // the track is either track 0
           // or it is explicitly solod.
           
           if( trk==0 || track_processors[trk]->solo )
           {
             allow_msg=true;
           }
           else
           {
             allow_msg=false;
           }
           
         }
         
         
         if( !(allow_msg
               && track_processors[trk]->Process(msg)
               && state.track_state[trk]->Process(msg))
           )
         {
           // the message is not allowed to come out!
           // erase it
           msg->SetNoOp();
         }
         
         // go to the next event on the multitrack
         state.iterator.GoToNextEvent();
         
         return true;
         
       }
     }
   }
   
   return false;
 }