GenePool::MIDIEventList *GenePool::getEvents(void) { list<MIDITimedBigMessage*> *events = new list<MIDITimedBigMessage*>; for (EventPool::iterator i = pool_.begin(); i != pool_.end(); ++i) { for (BreadNoteCluster::iterator j = (*i)->begin(); j != (*i)->end(); ++j) { BreadNote *e = (*j); u_int8_t pitch = e->pitch(); u_int32_t ontime = e->ontime(); u_int32_t duration = e->duration(); u_int8_t channel = e->channel(); u_int8_t dynamic = e->dynamic(); MIDITimedBigMessage *m = new MIDITimedBigMessage; m->SetTime(ontime); m->SetNoteOn(channel, pitch, dynamic); events->push_back(m); m = new MIDITimedBigMessage; m->SetTime(ontime+duration); m->SetNoteOff(channel, pitch, dynamic); events->push_back(m); // printf("(%d %d %d %d %d) ", ontime, pitch, duration, channel, // dynamic); } } return events; }
void CompressStartPause( const MIDIMultiTrack &src, MIDIMultiTrack &dst, int ignore_channel ) { dst.ClearAndResize( src.GetNumTracks() ); dst.SetClksPerBeat( src.GetClksPerBeat() ); MIDIClockTime ev_time = 0; MIDISequencer seq( &src ); seq.GoToTime( 0 ); if ( !seq.GetNextEventTime ( &ev_time ) ) return; // empty src multitrack MIDITimedBigMessage ev; int ev_track; bool compress = true; MIDIClockTime old_ev_time = 0, delta_ev_time = 0, ev_time0 = 0; while ( seq.GetNextEvent( &ev_track, &ev ) ) { if ( ev.IsServiceMsg() || ev.IsNoOp() ) continue; if ( ev.IsChannelEvent() && ev.GetChannel() == ignore_channel ) continue; ev_time = ev.GetTime(); if ( compress ) { // compress time intervals between adjacent messages to 1 tick if (ev_time > old_ev_time) ++delta_ev_time; old_ev_time = ev_time; ev.SetTime( delta_ev_time ); if ( ev.ImplicitIsNoteOn() ) { compress = false; ev_time0 = ev_time - delta_ev_time; } } else { ev.SetTime( ev_time - ev_time0 ); } dst.GetTrack(ev_track)->PutEvent(ev); } }
bool AddEndingPause( MIDIMultiTrack &tracks, int track_num, MIDIClockTime pause_ticks ) { MIDIClockTime t = tracks.GetTrack( track_num )->GetLastEventTime(); MIDITimedBigMessage msg; msg.SetTime( t + pause_ticks ); // add lowest "note on" in channel 0 with velocity 0 (i.e. "note off") msg.SetNoteOn( 0, 0, 0 ); return tracks.GetTrack( track_num )->PutEvent( msg ); }
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 ); } }
void MIDITrack::ClearAndMerge( const MIDITrack *src1, const MIDITrack *src2 ) { Clear(); const MIDITimedBigMessage *ev1; int cur_trk1ev=0; int num_trk1ev = src1->GetNumEvents(); const MIDITimedBigMessage *ev2; int cur_trk2ev=0; int num_trk2ev = src2->GetNumEvents(); MIDIClockTime last_data_end_time=0; while( cur_trk1ev<num_trk1ev || cur_trk2ev<num_trk2ev ) { // skip any NOPs on track 1 ev1=src1->GetEventAddress( cur_trk1ev ); ev2=src2->GetEventAddress( cur_trk2ev ); bool has_ev1 = (cur_trk1ev<num_trk1ev) && ev1; bool has_ev2 = (cur_trk2ev<num_trk2ev) && ev2; if( has_ev1 && ev1->IsNoOp() ) { cur_trk1ev++; continue; } // skip any NOPs on track 2 if( has_ev2 && ev2->IsNoOp() ) { cur_trk2ev++; continue; } // skip all data end if( has_ev1 && ev1->IsDataEnd() ) { if( ev1->GetTime() > last_data_end_time ) { last_data_end_time = ev1->GetTime(); } cur_trk1ev++; continue; } if( has_ev2 && ev2->IsDataEnd() ) { if( ev2->GetTime() > last_data_end_time ) { last_data_end_time = ev2->GetTime(); } cur_trk2ev++; continue; } if( (has_ev1 && !has_ev2) ) { // nothing left on trk 2 if( !ev1->IsNoOp()) { if( ev1->GetTime() > last_data_end_time ) { last_data_end_time = ev1->GetTime(); } PutEvent( *ev1 ); ++cur_trk1ev; } } else if( (!has_ev1 && has_ev2) ) { // nothing left on trk 1 if( !ev2->IsNoOp() ) { PutEvent( *ev2 ); ++cur_trk2ev; } } else if( has_ev1 && has_ev2 ) { int trk=1; if( (ev1->GetTime() <= ev2->GetTime()) ) { trk=1; } else { trk=2; } if( trk==1 ) { if( ev1->GetTime() > last_data_end_time ) { last_data_end_time = ev1->GetTime(); } PutEvent( *ev1 ); ++cur_trk1ev; } else { if( ev2->GetTime() > last_data_end_time ) { last_data_end_time = ev2->GetTime(); } PutEvent( *ev2 ); ++cur_trk2ev; } } } // put single final data end event MIDITimedBigMessage dataend; dataend.SetTime( last_data_end_time ); dataend.SetDataEnd(); PutEvent( dataend ); }