AmEvent* ErodeFilter::HandleEvent(AmEvent* event, const am_filter_params* /*params*/) { if (!event) return event; ArpVALIDATE(mAddOn != NULL && mHolder != NULL, return event); event->SetNextFilter(mHolder->FirstConnection() ); if (event->Type() == event->NOTEON_TYPE || event->Type() == event->NOTEOFF_TYPE) { AmNoteOn* note; note = dynamic_cast<AmNoteOn*>( event ); if( !note ) return event; AmTime stoppingCondition = note->Duration() / 64; if (stoppingCondition <= 0) return event; AmNoteOn* nextNote = dynamic_cast<AmNoteOn*>( note->Copy() ); AmNoteOn* prevNote = note; while ( nextNote != NULL && nextNote->Duration() >= stoppingCondition ) { if (nextNote->Duration() <= 0) { nextNote->Delete(); return event; } if ( prevNote->Duration() < 4 ) return event; nextNote->SetDuration(prevNote->Duration () * 0.75 ); nextNote->SetStartTime(prevNote->EndTime() + 1); prevNote->AppendEvent(nextNote); prevNote = nextNote; nextNote = dynamic_cast<AmNoteOn*> ( nextNote->Copy() ); } } return event; }
void _AmControlTarget::Perform(const AmSong* song, const AmSelectionsI* selections) { if (!song || !selections) return; const AmTrack* track = song->Track(TrackWinProperties().OrderedTrackAt(0).TrackId()); if (!track) return; AmFilterHolderI* output = track->Filter(OUTPUT_PIPELINE); if (!output) return; AmEvent* event = selections->AsPlaybackList(song); if (!event) return; AmNoteOn* on = new AmNoteOn(64, 100, 0); if (!on) { event->DeleteChain(); return; } on->SetNextFilter(output); event = on->MergeEvent(event); if (!event) return; AmEvent* e = event; while ( e->NextEvent() ) e = e->NextEvent(); if (e) on->SetEndTime( e->EndTime() ); if (on->Duration() < PPQN / 8) on->SetEndTime( on->StartTime() + (PPQN / 8) ); mPerformer.SetBPM(song->BPM() ); mPerformer.Play(event); }
AmEvent* ParticleDecayFilter::HandleEvent(AmEvent* event, const am_filter_params* /*params*/) { if (!event) return event; ArpVALIDATE(mAddOn != NULL && mHolder != NULL, return event); event->SetNextFilter(mHolder->FirstConnection() ); double nextVal, cons=0.65; // it would be nice to one day make 'cons' user defined. int counter; if (event->Type() == event->NOTEON_TYPE || event->Type() == event->NOTEOFF_TYPE) { AmNoteOn* note = dynamic_cast<AmNoteOn*>( event ); if( !note ) return event; AmNoteOn* nextNote = dynamic_cast<AmNoteOn*>( note->Copy() ); if (nextNote->Duration() <= 0) { nextNote->Delete(); return event; } AmNoteOn* prevNote = note; // AmNoteOn* firstNote = note; VossRand pn; for ( counter = 1; counter <= 10; counter++ ) { //also this user definable nextVal = pn.GetValue(prevNote->Note(), cons); nextNote->SetStartTime(prevNote->EndTime() + 1); nextNote->SetNote(int(nextVal)); prevNote->AppendEvent(nextNote); prevNote = nextNote; nextNote = dynamic_cast<AmNoteOn*> ( nextNote->Copy() ); } } return event; }