[linux-audio-dev] LADSPA needs & wishes

Fraser fraser at arkhostings.com
Sat Jan 27 05:05:58 UTC 2007


Hi All,

I've been converting my old VST plugins over to LADSPA and have come
across something in the api which I really miss - the inability separate
the algorithmic to the displayed value of a parameter.
I'm finding this inability is leading to non-ideal programming habits.


Let me show what I mean with a few examples.

I have a control that represents a gain knob (say -12dB -> 12dB):

What's best for the run function is a value that represents the ratio
which I can simply multiply the audio by as it it keeps the maths simple
(0.25 -> 4). What's best for display is decibels (as that is way gain is
understood).

I can't do this with LADSPA - so as I programmer I'm left with a lose-lose
choice.

* I either choose a parameter range of -12 -> 12 (dB) and convert that to
a ratio every time the run function is called:
fGain      = pow(10, *(psMyPlugin->m_pfControlGain)      /20);
Which is an unnecessary use of cpu. (and as someone who has mixed many
albums on computers you need every scap of cpu you can get)

* Or I choose to use 0.25 -> 4 as my range. Now users are faced with a
parameter they don't intuitively understand (it is contrary to every other
bit of audio gear they have ever used) - most people cannot do
20*Log10(Gain) in their heads to work out the equivalent value in dB.

Of the two choices I choose the first, better to eat up too much cpu than
to have an interface that is unintuitive, but this is not ideal.

This gets worse when you have a control for something like 'warmth'. The
user does not need to know the range of values required to apply warmth in
an efficient manner (it won't mean anything to them), they just need to
know how much (0%-100%).


Another example - presets

I have a control that allows an operator to chose one of fifty presets
(say a reverb with small room, medium room, large room, hall etc). I don't
have a choice this time. Internally using an integer to represent the
different presets is fine, it's exactly all I need.
However even though I know what the preset is, I cannot display it's name
back to the user, so our user is left with a set of meaningless numbers
which they must resolve into names by some other means (print the doco out
and stick it on the wall?)



What I'd find useful in the api is an optional 'get_display' function
which allows the host app to get a human interpretation of a parameter for
display. It would only need to be called when a plugin windows is opened
or when a parameter is changed. Since the host has to convert the
parameter to a string in order to display it anyway, this is not a extra
step overall. We are just bringing it into the realm of the plugin.

/* pseudo code */
void GetMyDisplay(char *stDisplay, int Size, unsigned long Port)
{
  stTemp[LADSPA_MAX_EVER_DISPLAY_SIZE);
  switch(Port) {
    case MY_GAINCONTROL:
      sprintf(stTemp,"%4.1f dB",20*log10(PortValue));
      stTemp[Size-1]='\0';  /* truncate it to what the host wants*/
      strncopy(stDisplay,stTemp,Size);
      break;
    case MY_WARMTHCONTROL:
      sprintf(stTemp,"%4.1f %%",some_complex_function(PortValue));
      stTemp[Size-1]='\0';  /* truncate it to what the host wants*/
      strncopy(stDisplay,stTemp,Size);
      break;
  }
}



Now for a wish.

GUI - under OSX or windows this isn't such a big drama, there's only one
GUI environment to deal with. under Linux it's a different matter.

I sometimes think the best thing to do is to provide enough hints to the
host so it can render a more comprehensive gui, if it desires, rather than
the plugin drawing the gui as is traditionally done. This would entail a
few things.

1) Utilize ports of type: LADSPA_PORT_OUTPUT | LADSPA_PORT_CONTROL
what is that?
-> it's a meter, a light, etc

We'd just need some hints defined and the rest is up to the host
(most host apps already have their own audio specific widgets. we just
need to tell them which ones we want to use). These all need to be bounded
as any other control would be.

/* a peak meter, expects a ratio not a dB value */
LADSPA_HINT_METER_PEAK

/* a vu meter, expects a ratio not a dB value */
LADSPA_HINT_METER_VU

/* Some meters like gain reduction meters in a compressor meter backwards,
ie illuminated from max value downwards rather than minimum value upwards
*/
LADSPA_HINT_METER_REVERSED

/* a simple on/off light */
LADSPA_HINT_LIGHT_ONOFF

/* a light which has intesity */
LADSPA_HINT_LIGHT_INTENSITY

2) Add control layout to the port definitions
Could be done as by defining arbitrary bounding boxes.
/*
 * +----------+------+
 * | gain     |      |
 * +----------+ meter|
 * | warmth   |      |
 * +----------+------+
*/
PortLayoutHints[MY_GAIN].top=0;
PortLayoutHints[MY_GAIN].bot=1;
PortLayoutHints[MY_GAIN].left=0;
PortLayoutHints[MY_GAIN].right=3;
PortLayoutHints[MY_WARMTH].top=1;
PortLayoutHints[MY_WARMTH].bot=2;
PortLayoutHints[MY_WARMTH].left=0;
PortLayoutHints[MY_WARMTH].right=3;
PortLayoutHints[MY_METER].top=0;
PortLayoutHints[MY_METER].bot=2;
PortLayoutHints[MY_METER].left=3;
PortLayoutHints[MY_METER].right=5;

3) Customization
- control colours in the layout hints
- background & logo images in the descriptor
etc

This would all be optional for the host


Thanks for taking the time to read though all this, turned out to be
longer than I anticipated!

regards,
Fraser




More information about the Linux-audio-dev mailing list