Subject: Re: [linux-audio-dev] FW: LADPSA Freeverb - update?
From: Paul Barton-Davis (pbd_AT_Op.Net)
Date: Wed May 24 2000 - 15:51:14 EEST
>I'm very happy for us to start the debate on this again - I've just been
>having a bit of a discussion about this with Robert Jonsson. How's this for
>an approach:
>
>STRATEGY
>
> (A) Ideally I think that *all* hosts should be able to generate GUIs
>automagically for *all* plugins.
Fine. Its OK with me if the hosts *can* do this. I just want to do the
same as VST here, and allow the plugin to generate its own GUI
instead, if it wants to.
> (4) The GUI toolkit issue is a nightmare. Consider the
>following 'context' list: Qt, Gtk, Java, Motif, Standalone, LTK. The
>last two mean: Standalone - skin constructs its own separate Window
>and does its own thing graphically. LTK - all GUI interaction goes
>through some VST-style abstracted toolkit API that we'd have to spec
>up.
I don't want to get that specific. My proposal is as follows (its sort
of a cross between your "Skin" and "LTK" ideas):
The LADSPA_Descriptor should include:
typedef struct {
some_type_that_can_be_losslessly_cast_to_Display server_id;
some_type_that_can_be_losslessly_cast_to_Window window_id;
} LADSPA_GUI_Info;
int ladspa_gui_construct (LADSPA_Handle *, LADSPA_GUI_Info *);
"Display" is an X11 display ID. It describes the X11 server connection
to be used for the GUI. "Window" is an X11 window ID. It describes a
window created by the host for the plugin. We don't want to use these
directly, since it would force any ladspa.h user to include the X
headers as well. Bad.
This function returns:
0: successfull creation of the GUI
-1: error during creation of the GUI
1: plugin wants the host to build a default GUI
This interface requires that the toolkit used by the plugin provides a
way to use a "foreign window" as well as a "foreign" server connection.
"Foreign" here means "not created by the toolkit itself".
I know that GTK+ can do this.
Note: there is an argument that we could skip the host-provided
window. I think I prefer it because it means that the host's own GUI
code can keep track of all the windows that the X server thinks the
host owns. If we let plugins create their own windows (and to be fair,
we can't stop them), the host could potentially get confused. I'm not
sure about that. It would be simpler to drop this, and just pass the
Display.
Now, as to plugin/gui/host interactions:
1) the plugin run() and run_adding() calls must NEVER use any
functions that may call a GUI toolkit's library. the plugin MUST
assume at all times that its GUI is running in a different thread
than the run/run_adding calls (this may or may not be true
depending on the host).
2) We assume the typical event-driven/callback model for the GUI
toolkit. the GUI callback functions attached to various components
of the interface *may* directly modify the data accessed via the plugin's
ports. This, however, can cause non-sample accurate modifications,
since the GUI may be running in a different thread than the
run()/run_adding() call.
If the plugin wants to use any host-provided automation
facilities, it must call something like:
int ladspa_audio_port_set (LADSPA_Handle *,
int port_id,
int nsamples,
LADSPA_Data *data);
int ladspa_control_port_set (LADSPA_Handle *,
int port_id,
LADSPA_Data data);
3) it would be better to provide a library that allowed the GUI to
queue port changes so that they could be modified on the next call
to run() or run_adding(). This is where the MuCoS discussion comes
into play. Note that the host-provided automation would obviously
do this too, in the sense that it would not modify the port values
until shortly before the call to run() or run_adding(). A generalized
way of delivering "events" to the plugin would be very desirable. Note
however that months of discussion on LAD about this did not get us
anywhere with this.
4) providing our own GUI library that was tuned to the needs to "nice
looking audio apps" would be nice. but a plugin does not need to
use this if it doesn't want to.
5) Non-GUI hosts would never call ladspa_gui_construct(). Thus,
plugins cannot assume that it will be called.
Here's my idea of what a GUI constructor that uses GTK might look
like, in skeleton form:
#include <gtk.h>
struct {
GdkWindow *gdk_window;
GtkWindow *window;
.
.
} my_gui;
int myplug_gui_constructor (LADSPA_Handle *h, LADSPA_GUI_Info *ginfo)
{
/* ... tell toolkit to start using a foreign server ... */
... i'm still checking on this ...
/* ... tell toolkit to create its own window type from
the foreign window ...
*/
my_gui.gdk_window = gdk_window_foreign_new (ginfo->window_id);
.... i'm still checking on how to do this step, but
it will be something like this: ....
my_gui.window = gtk_window_new_with_window (GTK_WINDOW_TOPLEVEL,
my_gui.gdk_window);
/* ... create a bunch of pixmaps & widgets, arrange them, set up
event callbacks, etc, etc. ...
*/
return 0;
}
This archive was generated by hypermail 2b28 : Wed May 24 2000 - 17:12:30 EEST