Re: [linux-audio-dev] back to the API

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

Subject: Re: [linux-audio-dev] back to the API
From: Paul Barton-Davis (pbd_AT_Op.Net)
Date: ti loka   19 1999 - 02:16:54 EDT


>> i see it oppositely: the API has to define what gets passed to various
>> plugin function calls. By making it the plugin itself, the API becomes
>> completely amenable to source-code compatible alteration. If you
>> specify anything else, any time you want to change the argument type
>> or number, everything needs to be recoded, not just recompiled.
>
>How does it make a difference WRT binary level compatibility whether
>the API specifies what the events should look like, or what a struct
>should look like?

no difference to *binary* compatibility - if you change the size of
anything, or the arguments to anything, you have to recompile
anyway. but if plugin functions only get a pointer to a plugin struct,
you can always extend that struct at any time, and not have to change
any plugin code when the recompile is done.

an API *has* to include some struct definitions. event and plugin seem
like the two most likely. a plugin has to be able to inspect events
(OK, so you can wrap a void * in macros, but this seems silly), and it
might want to modify itself. Or do you really want macros for all this ?

>> either way, i figure there should be two OOB mechanisms for events
>> requiring more space than fits into the union: one would use a void *
>> member of the union, and would point to space managed entirely by the
>> plugin (via some allocation/deallocation API that we provide).
>
>Major problem; this still has to be implemented. And it has to work
>without shared memory...

in what sense ? do you mean without thread-shared memory, without
shmem-like memory, or without shared memory period ? if its without
shared memory period, then i cannot see how the client or plugin API
can possibly function. if you're worried about an in-kernel
implementation, you just mmap some space from/to the kernel. its
easier to map it into the kernel, i think.

>> note that events take essentially 3 arguments:
>>
>> - what changed (ev_target_id) - this may refer (from a plugin's
>> point of view) to some C parameter in memory, or it
>> may not - the engine doesn't care
>> - how it changed (delta from old value, absolute new value,
>> increment or decrement from old value)
>
>Uhm, this seems to be asking for trouble with automation and editing
>of automation data... Why deltas and inc/dec? What are plugins
>allowed to send?

they send events that say:

     "XXX has changed by +4"
     "YYY has changed, new value is 13.4554"
     "ZZZ has been incremented"

in each case, XXX, YYY or ZZZ is the target_id of the change, which is
assigned by the engine when the plugin declares its "parameters", and
is looked up by the plugin during event processing to decide if it
really cares.

its really just an editlist, suprise, suprise!

>> - value (interpreted based on the kind of change)

>Whether this is enough depends on what the event system will be used
>for - and IMO, the design we're working on has too much potential to
>be restricted to audio for the simple reason that you can't send more
>than 32 bytes (or whatever) as a single event without extra trouble
>and overhead. I believe things like a 3D sound FX system for games or
>movie sound track editing would benefit from larger events... Should
>we extend the "standard" when such needs become important?

can you give an example of an event from those worlds which needs more
space ?

>> can't happen. events appear at an event source. only one "object" has
>> access to the event source. the event can go to many event
>> destinations but thats different: these are just LISP-like lists of
>> pointers to events. the object that owns the event source posts events
>> to it in the order received, so that when the engine inspects all
>> active event sources, it finds them already sorted in time order on
>> any given event source. its job is to build the event cell lists for
>> each destination, which requires mux-ing each relevant source and
>> sorting by timeorder while so doing. thats all.
>
>So, you have to force every event source to use a unique kind of
>event? Ok, it's rather silly to connect two sources of the same kind
>of events to the same input - it should probably just not be allowed.

nope. two objects can generate the same kind of event. they would end
up in two distinct event sources, and be merged by the engine into a
single event list for presentation at a destination.

>Good point, but that's not exactly what I meant. How could you
>possibly give the engine anything but a void * to you closure, if
>it's not 100% defined in the API, or 100% private to the plugin?
>Further, how do you optimize engines without breaking plugin binary
>compatibility, if you have "private" implementation stuff in the API?

you define a plugin struct :

    struct plugin {
           ... stuff the engine cares about ...
    };

then in the plugin code, in the
"run-me-when-instantiating-an-instance" function, you do this:

    struct my_kind_of_plugin {
           struct plugin std;
           ... stuff this plugin cares about ...
    };

then just allocate a "my_kind_of_plugin", set up the fields that the
engine needs to see, and send it up to the engine as a "struct
plugin".

yes, yes, this is entirely going back on my comments about header
structs, but this is one case where it seems right.

oops, my daughter is awake. see you tomorrow.

--p


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:59 EST