Subject: Re: [linux-audio-dev] Re: Quasimodo (Was: Re: LADSPA GUI)
From: Paul Barton-Davis (pbd_AT_Op.Net)
Date: Wed Mar 15 2000 - 23:20:00 EST
>How about making that switch a logical element that the engine is
>supposed to understand? That is, the switch not only selects an
>input, but also tells the engine which sources aren't needed, so that
>the engine can skip them if their output isn't needed elsewhere. (In
>an actual implementation, the switch probably wouldn't be all that
>similar to a "real" plugin, as it doesn't do much more than shuffling
>pointers and booleans around.)
Yeah, exactly like Quasimodo's "INLINE" feature for control flow
opcodes. In Csound, such things really are implemented as regular
opcodes, but its pretty easy (it took me about 3 hours) to convert
all the obvious cases of this stuff into inlined code in the "host".
All that INLINE indicates about an opcode in quasimodo is that instead
of taking a certain data value in the opcode description as a function
ptr, it should be cast to an enum, and used as the branch in a switch
statement. Snippet:
A modules internal "execute() function does this:
--------------------------------------------------------------------
/* XXX dirty trick - real function pointers do
not have low integer values.
*/
if ((unsigned int) p->executor > inline_LAST) {
p->executor (p);
} else {
nsmps = CycleFrames;
b = 0;
switch ((unsigned int) p->executor) {
#include <quasimodo/inline_arithmetic.h>
}
}
----------------------------------------------------------------------
and inline_arithmetic.h contains stuff like this:
---------------------------------------------------------------------
case inline_LogicalAnd:
*((LOGCL *)p)->rbool = (*((LOGCL *) p)->ibool &&
*((LOGCL *) p)->jbool) ? 1 : 0;
break;
case inline_LogicalOr:
*((LOGCL *)p)->rbool = (*((LOGCL *) p)->ibool ||
*((LOGCL *) p)->jbool) ? 1 : 0;
break;
case inline_ConditionScalar:
if (*((CONVAL *) p)->cond)
*((CONVAL *) p)->r = *((CONVAL *) p)->a;
else
*((CONVAL *) p)->r = *((CONVAL *) p)->b;
break;
case inline_ConditionVector:
r = ((CONVAL *) p)->r;
if (*((CONVAL *) p)->cond)
a = ((CONVAL *) p)->a;
else
a = ((CONVAL *) p)->b;
do
*r++ = *a++;
while (--nsmps);
break;
-------------------------------------------------------------------
But what you're suggesting is still along the lines of a script
language that is used to describe the processing flow. If you're going
to go part-way there, go all the way. The Guile home page at
www.gnu.org has some nice examples of why this always a good idea.
--p
This archive was generated by hypermail 2b28 : Thu Mar 16 2000 - 06:50:21 EST