[linux-audio-dev] XAP: Cookies and Event Actions

David Olofson david at olofson.net
Fri Jan 17 22:08:01 UTC 2003


While hacking a more uniform control event type into Audiality, I 
realized something: The event action *might* be better off as a part 
of the cookie.

The voice mixers in Audiality have two types of controls; ramped 
controls and controls without ramping. As it is, they're implemented 
in different ways, use different arrays, different events and 
different event handling code. You use SET for the non-ramped 
controls, and ISET, IRAMP and ISTOP for the ramped controls. Same 
index means one control for SET, and another for ISET.

Fine; no problem with that so far, since the Patch Plugins (that 
drive the voices, implementing mono/poly, envelopes and whatnot) have 
intimate knowledge of the voice controls. Everything's hardcoded, 
basically.

However, when applied to "real" plugins, this scheme has a problem: 
There are two kinds of controls, and they're not compatible in any 
way. If you have ramped output, you need a ramped input, and vice 
versa.


Now, the idea I had was to drop the event action/type field, and have 
receivers encode that part as well, into the cookie. That way, if you 
don't have ramping for some controls, you can just encode a different 
action field into your cookies, so that when you get those events, 
you end up in a different case in the decoding switch(), where you 
"fake" the response in a suitable way. Taking some Audiality code as 
an example:

	switch(ev->type)
	{
	  case VE_START:
		voice_start(v, ev->arg1);
		...
		break;
	  case VE_STOP:
		voice_kill(v);
		aev_free(ev);
		return;	/* Back in the voice pool! --> */
	  case VE_SET:
		v->c[ev->index] = ev->arg1;
		if(VC_PITCH == ev->index)
			v->step = calc_step(v);
		break;
	  case VE_ISET:
		v->ic[ev->index].v = ev->arg1 << RAMP_BITS;
		v->ic[ev->index].dv = 0;
		break;
	  case VE_IRAMP:
		v->ic[ev->index].dv = ev->arg1 << RAMP_BITS;
		v->ic[ev->index].dv -= v->ic[ev->index].v;
		v->ic[ev->index].dv /= ev->arg2;
		break;
	  case VE_ISTOP:
		v->ic[ev->index].dv = 0;
		break;
	}

(which requires senders to special-case normal and ramped controls) 
becomes:

	switch(ev->cookie & 0xf)
	{
	  case VE_START:
		voice_start(v, ev->arg1);
		...
		break;
	  case VE_STOP:
		voice_kill(v);
		aev_free(ev);
		return;	/* Back in the voice pool! --> */
	  case VE_SET:
		v->c[ev->index] = ev->arg1;
		break;
	  case VE_SET_PITCH:
		v->step = calc_step(v);
		v->c[ev->index] = ev->arg1;
		break;
	  case VE_RAMP:
		v->c[ev->index] = ev->arg1 << RAMP_BITS;
	  case VE_STOP:
		break;
	  case VE_ISET:
		v->ic[ev->index].v = ev->arg1 << RAMP_BITS;
		v->ic[ev->index].dv = 0;
		break;
	  case VE_IRAMP:
		v->ic[ev->index].dv = ev->arg1 << RAMP_BITS;
		v->ic[ev->index].dv -= v->ic[ev->index].v;
		v->ic[ev->index].dv /= ev->arg2;
		break;
	  case VE_ISTOP:
		v->ic[ev->index].dv = 0;
		break;
	}

Notice the new VE_RAMP and VE_STOP actions? Those are where ramping 
events go if you send them to a non-ramped control. Also note that 
VE_SET_PITCH no longer needs an extra conditional to run (the rather 
expensive) calc_step() for the pitch control.

Just encode whatever action you want into the cookie for each control 
connected. A full control target now looks like this:

struct AEV_target
{
	AEV_queue	*queue;
	Uint32		set_cookie;
	Uint32		ramp_cookie;
	Uint32		stop_cookie;
} AEV_target;

One cookie for each type of action there is for a control. This way, 
you can encode *all* aspects of control handling into the cookie, 
without adding any significant complexity or overhead to senders. You 
could have only one set of control event handlers, or you could have 
one set of cases for *each control*! You decide.


I'm definitely switching to this system internally in Audiality.

(And if it's a bad idea, you'll find out...! :-)


(Note that STOP is just to deal with the limited accuracy of the 
integer math in Audiality - and that might actually have been a 
"false fix" for another bug I found later. Will try without STOP 
again, and/or tweak the ramping code. Or just ditch the bl**dy 
integer code! :-)


//David Olofson - Programmer, Composer, Open Source Advocate

.- The Return of Audiality! --------------------------------.
| Free/Open Source Audio Engine for use in Games or Studio. |
| RT and off-line synth. Scripting. Sample accurate timing. |
`---------------------------> http://olofson.net/audiality -'
   --- http://olofson.net --- http://www.reologica.se ---



More information about the Linux-audio-dev mailing list