[linux-audio-dev] Re: Plug-in API progress?

New Message Reply About this list Date view Thread view Subject view Author view Other groups

Subject: [linux-audio-dev] Re: Plug-in API progress?
From: Paul Barton-Davis (pbd_AT_Op.Net)
Date: ti syys   21 1999 - 18:04:06 EDT


>Here is my rough try on this. This looks so simple that you should look
>if I just have goofed. This is *not* the final version we have to think
>about good structure and field names and their final types.

I think you should look more closely at Csound (and by extension,
Quasimodo's) call interface for opcodes, which is very similar to the
one used by SuperCollider. The generic name for it is "closures". A
closure is a piece of memory that contains all the information
necessary to run a function.

You allocate a piece of heap (size specified by the functions call
interface), then stick pointers to the arguments arguments into
the heap so that it vaguely resembles a stack. Then you pass this
closure to the function. You keep the closure around for further
calls.

Its phenomenally efficient. Note that all this has been done already
in Csound and Quasimodo. There are more than 400 "plugins" in both
systems that use this kind of interface. It can be done neater than
Csound did it, because there is no need for source-level
compatibility. But the basic idea of a closure is well worth checking
out, and needs a strong argument (IMHO) if it is not to be used.

--p

ps. Going slightly off the wall, I think that you handle the GUI element
of a plugin API by dynamically compiling the plugin. That is, a plugin
consists of at least one .c and zero or more .h files. Any machine
fast enough to run this kind of stuff can compile this kind of code is
a second or less. Then, the plugin can use native GUI code (eg. Gnome,
or GTK or whatever), and not be limited by whatever facilities the
engine provides in this regard. This is a feature I would like to add
to Quasimodo in the distant future.

pps. here's some more details. This doesn't take care of some of the
global stuff that Juhana's API suggestion contains - thats intended to
be handled by the basic_closure struct, which can contain anything you
want.

As an example, consider a delay plugin with a two parameters: the
delay in msecs (as a float) and the wet/dry ratio as a float from 0 to
1.

Using a mix of C, C++ and psuedo-code:

struct delay_args : struct basic_closure {
       float dtime;
       float msecs;
       .
       .
       .
};

{ "delay", delay, sizeof (delay_args), "ff" }
  
  ^^^^^^
  name of plugin

           ^^^^^^
           function to call

                 ^^^^^^^^^^^^^^^^^^^^
                 closure size
                                      ^^^^^^
                                      argument format

So, to use this plugin you:

1) allocate storage for its parameters ("ff") (the GUI aspect has
   to define human-usable names for them; we'll use "dtime" and "mix")
2) allocate sizeof(delay_args) bytes
3) setup the basic_closure portion of the closure:

       closure->func = delay;
       closure->size = sizeof (delay_args) + sizeof (basic_closure);
       closure->output_buffer = output_buf;
       closure->input_buffer = input_buf;
       .
       .
       .

        /* whatever else all closures need */
 
4) marshall the args:

       argnum = 0;

       switch (interface->arg_format[i]) {

              case 'f':
               ((float *) &(((unsigned char) closure)+
                             sizeof(basic_closure)+(sizeof (float)*argnum)))
                             = ??;
       
5) then, whenever its necessary to invoke it:

       *(closure->func)(closure);

Inside the function "delay", the code looks like this:

void
delay (delay_args *ptr)

{
        float dtime;
        float msecs;
        sample_t *output_buf;
        sample_t *input_buf;
        .
        .
        .

        dtime = *ptr->dtime;
        msecs = *ptr->msecs;

        /* do something useful, put results in ptr->output_buf */

}


New Message Reply About this list Date view Thread view Subject view Author view Other groups

This archive was generated by hypermail 2b28 : pe maalis 10 2000 - 07:27:12 EST