int AdvancedSequencer::FindFirstChannelOnTrack ( int trk ) { if ( !file_loaded ) { return -1; } int first_channel = -1; MIDITrack *t = tracks.GetTrack ( trk ); if ( t ) { // go through all events // until we find a channel message // and then return the channel number plus 1 for ( int i = 0; i < t->GetNumEvents(); ++i ) { MIDITimedBigMessage *m = t->GetEventAddress ( i ); if ( m ) { if ( m->IsChannelMsg() ) { first_channel = m->GetChannel() + 1; break; } } } } return first_channel; }
MIDITrack::MIDITrack( const MIDITrack &t ) { buf_size=0; num_events=0; for( int i=0; i<t.GetNumEvents(); ++i ) { const MIDITimedBigMessage *src; src = t.GetEventAddress( i ); PutEvent(*src); } }
bool MIDIFileReadMultiTrack::AddEventToMultiTrack ( const MIDITimedMessage &msg, MIDISystemExclusive *sysex, int dest_track ) { bool result = false; if ( dest_track != -1 && dest_track < multitrack->GetNumTracks() ) { MIDITrack *t = multitrack->GetTrack ( dest_track ); if ( t ) { result = t->PutEvent ( msg, sysex ); } } return result; }
void MIDIFileReadMultiTrack::AddEventToMultiTrack ( const MIDITimedMessage &msg, MIDISystemExclusive *sysex, int dest_track ) { if ( dest_track!=-1 && dest_track<multitrack->GetNumTracks() ) { MIDITrack *t = multitrack->GetTrack ( dest_track ); if ( t ) { t->PutEvent ( msg, sysex ); } } }
void LastEventsProlongation( MIDIMultiTrack &tracks, int track_num, MIDIClockTime add_ticks ) { MIDITrack *track = tracks.GetTrack( track_num ); int index = track->GetNumEvents() - 1; if ( add_ticks == 0 || index < 0 ) return; MIDITimedBigMessage *msg = track->GetEvent( index ); MIDIClockTime tmax = msg->GetTime(); while ( msg->GetTime() == tmax ) { msg->SetTime( tmax + add_ticks ); if ( --index < 0 ) break; msg = track->GetEvent( index ); } }
bool MIDIMultiTrackIterator::GoToNextEventOnTrack ( int track_num ) { // Get the track that we are dealing with MIDITrack *track = multitrack->GetTrack ( track_num ); // Get ptr to the current event number for this track int *event_num = &state.next_event_number[ track_num ]; // skip this track if this event number is <0 - This track has hit end already. if ( *event_num <0 ) { return false; // at end of track } // increment *event_num to next event on track ( *event_num ) += 1; // are we at end of track? if ( *event_num >= track->GetNumEvents() ) { // yes, set *event_num to -1 *event_num=-1; return false; // at end of track } else { // not at end of track yet - get the time of the event MIDITimedBigMessage *msg; msg = track->GetEventAddress ( *event_num ); state.next_event_time[ track_num ] = msg->GetTime(); } return true; }
void AdvancedSequencer::ExtractMarkers ( std::vector< std::string > *list ) { if ( !file_loaded ) { list->clear(); num_markers = 0; return; } MIDITrack *t = tracks.GetTrack ( 0 ); list->clear(); int cnt = 0; int measure = 0; int beat = 0; int timesig_numerator = 4; int timesig_denominator = 4; MIDIClockTime last_beat_time = 0; MIDIClockTime last_event_time = 0; int clks_per_beat = tracks.GetClksPerBeat(); for ( int i = 0; i < t->GetNumEvents(); ++i ) { MIDITimedBigMessage *m = t->GetEventAddress ( i ); if ( m ) { // how many beats have gone by since the last event? long beats_gone_by = ( m->GetTime() - last_beat_time ) / clks_per_beat; if ( beats_gone_by > 0 ) { // calculate what our new measure/beat is beat += beats_gone_by; // carry over beat overflow to measure measure += beat / timesig_numerator; beat = beat % timesig_numerator; last_beat_time += ( clks_per_beat * beats_gone_by ); } if ( m->IsMetaEvent() && m->IsTimeSig() ) { timesig_numerator = m->GetTimeSigNumerator(); timesig_denominator = m->GetTimeSigDenominator(); clks_per_beat = tracks.GetClksPerBeat() * 4 / timesig_denominator; } if ( m->IsTextEvent() && m->GetSysEx() ) { if ( ( m->GetMetaType() == META_GENERIC_TEXT ) || m->GetMetaType() == META_MARKER_TEXT || m->GetMetaType() == META_CUE_TEXT ) { char buf[256]; char line[256]; memcpy ( buf, m->GetSysEx()->GetBuf(), m->GetSysEx()->GetLength() ); buf[ m->GetSysEx()->GetLength() ] = '\0'; FixQuotes ( buf ); sprintf ( line, "%03d:%d %s", measure + 1, beat + 1, buf ); list->push_back ( std::string ( line ) ); marker_times[ cnt++ ] = m->GetTime(); } } last_event_time = m->GetTime(); } } num_markers = cnt; }
void MIDIMultiTrackIterator::GoToTime ( MIDIClockTime time ) { // start at time 0 state.Reset(); // transfer info from the first events in each track in the // multitrack object to our current state. for ( int i=0; i<multitrack->GetNumTracks(); ++i ) { MIDITrack *track = multitrack->GetTrack ( i ); // default: set the next_event_number for this track to -1 // to signify end of track state.next_event_number[ i ] = -1; // are there any events in this track? if ( track && track->GetNumEvents() >0 ) { // yes, extract the time of the first event MIDITimedBigMessage *msg = track->GetEventAddress ( 0 ); if ( msg ) { // found the first message of the track. Keep track // of the event number and the event time. state.next_event_number[i]=0; state.next_event_time[i]=msg->GetTime(); } } } // are there any events at all? find the track with the // earliest event if ( state.FindTrackOfFirstEvent() !=-1 ) { // yes // iterate through all the events until we find a time >= the requested time while ( state.GetCurrentTime() <time ) { // did not get to the requested time yet. // go to the next chronological event on all tracks if ( !GoToNextEvent() ) { // there is no more events to go to break; } } } }