示例#1
0
AmEvent* ArpVelocityMapFilter::HandleEvent(AmEvent* event, const am_filter_params* /*params*/)
{
	if (!event) return event;
	ArpVALIDATE(mAddOn != NULL && mHolder != NULL, return event);
	event->SetNextFilter(mHolder->ConnectionAt(0) );
	if (event->Type() != event->NOTEON_TYPE) return event;
	AmNoteOn*		e = dynamic_cast<AmNoteOn*>(event);
	if (!e || !in_range(e, mFromRange) ) return event;

	int32		fromStart = mFromRange.start, fromEnd = mFromRange.end;
	int32		toStart = mToRange.start, toEnd = mToRange.end;
	/* If both the from and start are reversed, but them back to normal.
	 * Otherwise leave them skewed, to allow users to invert the range.
	 */
	if (fromEnd < fromStart && toEnd < toStart) {
		fromStart = mFromRange.end;
		fromEnd = mFromRange.start;
		toStart = mToRange.end;
		toEnd = mToRange.start;
	}
	float		scale = fabs(float(fromEnd - fromStart) / float(toEnd - toStart));
	if (mToRange.end < mToRange.start) scale = -scale;
	int32		newVel = int32(toStart + ((e->Velocity() - fromStart) * scale));
	
	if (toStart < toEnd) {
		if (newVel < toStart) newVel = toStart;
		else if (newVel > toEnd) newVel = toEnd;
	} else {
		if (newVel < toEnd) newVel = toEnd;
		else if (newVel > toStart) newVel = toStart;
	}
	e->SetVelocity(newVel);
	
	return event;
}
AmEvent* ArpAccentRandomizerFilter::HandleEvent(AmEvent* event, const am_filter_params* /*params*/)
{
	if(!event)
		return event;
	ArpVALIDATE(mAddOn != 0 && mHolder != 0, return event);
	
	event->SetNextFilter(mHolder->FirstConnection() );
	
	if( (event->Type() == event->NOTEON_TYPE) && (0 < mRandomizeAmount) ) {
		AmNoteOn* note = dynamic_cast<AmNoteOn*>(event);
		if(!note)
			return event;
		int32 delta = rand() % mRandomizeAmount;
		if(rand() % 2) // flip sign with 50% chance
			delta *= -1;
		int32 vel = note->Velocity();
		vel += delta;
		if(vel > 127)
			vel = 127;
		if(vel < 0)
			vel = 0;
		note->SetVelocity(vel);
	}
	return event;
}
示例#3
0
AmEvent* ArpUncertainChorusFilter::HandleToolEvent(	AmEvent* event, const am_filter_params* params,
        const am_tool_filter_params* toolParams)
{
    if (event && mHolder) event->SetNextFilter(mHolder->FirstConnection() );
    if (!event || !toolParams) return event;
    if (event->Type() == event->NOTEON_TYPE) {
        AmNoteOn*	e = dynamic_cast<AmNoteOn*>(event);
        if (!e) return event;
        BuildTable(e->Note(), toolParams);
        for (uint32 k = 0; k < NOTE_SIZE; k++) {
            if (mNotes[k] ) {
                AmNoteOn*	e2 = dynamic_cast<AmNoteOn*>(e->Copy() );
                if (e2) {
                    e2->SetNote(k);
                    e->AppendEvent(e2);
                }
            }
        }
    } else if (event->Type() == event->NOTEOFF_TYPE) {
        AmNoteOff*	e = dynamic_cast<AmNoteOff*>(event);
        if (!e) return event;
        BuildTable(e->Note(), toolParams);
        for (uint32 k = 0; k < NOTE_SIZE; k++) {
            if (mNotes[k] ) {
                AmNoteOff*	e2 = dynamic_cast<AmNoteOff*>(e->Copy() );
                if (e2) {
                    e2->SetNote(k);
                    e->AppendEvent(e2);
                }
            }
        }
    }

    return event;
}
示例#4
0
AmEvent* ArpUncertainChorusFilter::HandleEvent(AmEvent* event, const am_filter_params* params)
{
    if (event && mHolder) event->SetNextFilter(mHolder->FirstConnection() );
    if (!event || !should_chorus(mFrequency) ) return event;

    int32		newNote = rand() % 128;
    if (newNote < 0) newNote = 0;
    else if (newNote > 127) newNote = 127;

    if (event->Type() == event->NOTEON_TYPE) {
        AmNoteOn*	e = dynamic_cast<AmNoteOn*>(event);
        if (!e) return event;
        if (e->Note() != newNote) {
            AmNoteOn*	e2 = dynamic_cast<AmNoteOn*>(e->Copy() );
            if (e2) {
                e2->SetNote(uint8(newNote) );
                e->AppendEvent(e2);
            }
        }
    } else if (event->Type() == event->NOTEOFF_TYPE) {
        AmNoteOff*	e = dynamic_cast<AmNoteOff*>(event);
        if (!e) return event;
        if (e->Note() != newNote) {
            AmNoteOff*	e2 = dynamic_cast<AmNoteOff*>(e->Copy() );
            if (e2) {
                e2->SetNote(uint8(newNote) );
                e->AppendEvent(e2);
            }
        }
    }

    return event;
}
示例#5
0
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);
}
示例#6
0
AmEvent* ArpVaccineFilter::HandleEvent(AmEvent* event, const am_filter_params* params)
{
	if (!event) return event;
	if (mFrequency == 0 || mAmount == 0) return event;
	if (event->Type() != event->NOTEON_TYPE && event->Type() != event->NOTEOFF_TYPE) return event;
	if ( !ShouldVaccinate(mFrequency) ) return event;
	ArpVALIDATE(params && params->cur_signature, return event);
	const AmSignature*	curSig = params->cur_signature;
	AmSignature			sig;
	if ( !get_signature(event->StartTime(), curSig, sig) ) return event;

	int32				prox = (int32)(proximity_to_beat(event->StartTime(), sig) * 100);
	
	float	prox2 = (float)abs(mProximity - prox) / 100;
//	printf("proximity is %ld, that puts prox2 at %f\n", prox, prox2);
	if (prox2 < 0) prox2 = 0;
	else if (prox2 > 1) prox2 = 1;
	prox2 = 1 - prox2;

	/* If there are tool params, set my amount based on the param data.
	 */
	int32				amount = mAmount;
	if (params->flags&AMFF_TOOL_PARAMS) {
		if (mAmount >= 0) amount = (int32)(params->view_orig_y_pixel - params->view_cur_y_pixel);
		else amount = (int32)(params->view_cur_y_pixel - params->view_orig_y_pixel);
		if (amount < MIN_AMOUNT) amount = MIN_AMOUNT;
		else if (amount > MAX_AMOUNT) amount = MAX_AMOUNT;
	}
	
	if (event->Type() == event->NOTEON_TYPE) {
		AmNoteOn*	noe = dynamic_cast<AmNoteOn*>(event);
		if (noe) {
			int32	vel = noe->Velocity();
			float	scale = ((float)amount / 100) * prox2;
			vel = vel + (int32)(vel * scale);
			if (vel < 0) vel = 0;
			else if (vel > 127) vel = 127;
			noe->SetVelocity(vel);
		}
	} else if (event->Type() == event->NOTEOFF_TYPE) {
	}

	return event;
}
示例#7
0
void AmFilterTest1::TestBasic01()
{
	int i;
	
	printf("Making a vector.\n");
	vector<int, allocator<int> > myVect(2);
	myVect[0] = 1;
	
	printf("Making a map.\n");
	map< int, int, less<int>, allocator<int> > myMap;
	myMap[0] = 1;
	
	printf("Creating example filter object...\n");
	fflush(stdout);
	ArpExampleFilterAddon* exAddon = new ArpExampleFilterAddon;
	AmFilterHolder* exHolder = new AmFilterHolder;
	exHolder->SetFilter(exAddon->NewInstance(exHolder));
	
	printf("Creating BSynth filter object...\n");
	fflush(stdout);
#if 1
	AmConsumerFilterAddon* syAddon = new AmConsumerFilterAddon();
#else
	AmConsumerFilterAddon* syAddon = new AmConsumerFilterAddon("<midi port name>");
#endif
	/* NOTE:  The second consumer filter is not valid.  You need to
	 * supply the name of the midi port you want to use.
	 */
	AmFilterHolder* syHolder = new AmFilterHolder;
	syHolder->SetFilter(syAddon->NewInstance(syHolder));
	
	printf("Creating debug filter object...\n");
	fflush(stdout);
	ArpDebugFilterAddon* dbAddon = new ArpDebugFilterAddon(true);
	AmFilterHolder* dbHolder = new AmFilterHolder;
	dbHolder->SetFilter(dbAddon->NewInstance(dbHolder));
	
	printf("Attaching BSynth filter to example filter...\n");
	fflush(stdout);
	exHolder->AddSuccessor(syHolder);
	
	printf("Attaching debug filter to BSynth filter...\n");
	fflush(stdout);
	syHolder->AddSuccessor(dbHolder);
	
	printf("Creating a chain of NoteOn events...\n");
	fflush(stdout);
	AmEventI* evHead=NULL;
	AmEventI* evTail=NULL;
	for( i=1; i<=4; i++ ) {
		{
			AmProgramChange* ev = new AmProgramChange((i-1)*10,
																PPQN*4*i-((PPQN*3)/2));
			if( !evHead ) {
				evHead = ev;
			} else {
				evTail->AppendEvent(ev);
			}
			ev->SetNextFilter(exHolder);
			evTail = ev;
		}
		
		{
			AmNoteOn* ev = new AmNoteOn(60+5*i,100,PPQN*4*i);
			ev->SetRelVelocity(80);
			if( !evHead ) {
				evHead = ev;
			} else {
				evTail->AppendEvent(ev);
			}
			ev->SetNextFilter(exHolder);
			evTail = ev;
		}
		
		{
			AmTempoChange* ev = new AmTempoChange(120 + 40*i,PPQN*4*i);
			if( !evHead ) {
				evHead = ev;
			} else {
				evTail->AppendEvent(ev);
			}
			ev->SetNextFilter(exHolder);
			evTail = ev;
		}
	}
	
	printf("Initial Event Chain:\n");
	fflush(stdout);
	PrintEventChain(evHead);
	fflush(stdout);
	
	printf("Processing filters on event chain...\n");
	fflush(stdout);
	evHead = ArpExecFilters(evHead);
	
	printf("Final event chain:\n");
	fflush(stdout);
	PrintEventChain(evHead);
	fflush(stdout);
	
	printf("Performing the song!\n");
	fflush(stdout);
	{
		AmPerformer p;
		p.Start(evHead);
		// this is a bit of a hack to wait for it to finish;
		// it will be better when we flesh out the performer
		// interface to be able to send messages.
		do {
			snooze(1 * 1000000);	// wait for a sec
		} while( p.IsPlaying() );
	}
	fflush(stdout);
	
	printf("Placing the BSynth filter in its own list...\n");
	fflush(stdout);
	exHolder->RemoveSuccessor(syHolder);
	syHolder->RemoveSuccessor(dbHolder);
	
	printf("Creating a chain of sixteenth notes...\n");
	fflush(stdout);
	evHead = evTail = new AmProgramChange(B_KALIMBA, 0);
	evTail->SetNextFilter(syHolder);
	evTail->AppendEvent(new AmTempoChange(480, 0));
	evTail = evTail->TailEvent();
	evTail->SetNextFilter(syHolder);
	for( i=1; i<=4*4*4; i++ ) {
		{
			AmNoteOn* ev = new AmNoteOn(70+2*(i/(4*4)),100,PPQN*i/4);
			ev->SetDuration(PPQN/8);
			ev->SetRelVelocity(80);
			if( !evHead ) {
				evHead = ev;
			} else {
				evTail->AppendEvent(ev);
			}
			ev->SetNextFilter(syHolder);
			evTail = ev;
		}
	}
	
	printf("Performing the next song!\n");
	fflush(stdout);
	{
		AmPerformer p;
		p.Start(evHead);
		// this is a bit of a hack to wait for it to finish;
		// it will be better when we flesh out the performer
		// interface to be able to send messages.
		do {
			snooze(1 * 1000000);	// wait for a sec
		} while( p.IsPlaying() );
	}
	fflush(stdout);
	
	printf("Deleting filters -- WHICH FOR SOME REASON IS CRASHING, SO IT'S BEEN REMOVED.\n");
#if 0
	exHolder->Delete();
	exAddon->RemReference();
	syHolder->Delete();
	syAddon->RemReference();
	dbHolder->Delete();
	dbAddon->RemReference();
#endif	
	DoBigTest();
	
	printf("Repeating test...\n");
	fflush(stdout);
	
	DoBigTest();
}
示例#8
0
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;
}