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; }
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; }