Subject: Re: [linux-audio-dev] LADSPA with dynamic datatype and multichannel support released !!
From: Karl W. MacMillan (karlmac_AT_peabody.jhu.edu)
Date: Mon Mar 27 2000 - 21:32:56 EEST
Well, I give up because I am out of ways to explain my objections - if
anyone agrees with me please speak up. I would still like to see an
example (with lots of details instead of "but this knob goes to eleven")
of a problem this solves that can't be handled by a plugin internally (as
Richard was saying). All I can say is this does not address my concerns
in any fundamental way (which you seem to think it should, Benno). Off to
migrate the bug reporting system for Windows 2000 to 64bit floats to
prepare for the future . . .
Karl (Bill)
On Mon, 27 Mar 2000, Benno Senoner wrote:
> folks , after working very hard on LADSPA during the whole weekend ,
> I _GOT_ it. :-)
>
> dynamic datatype and multichannel support for LADSPA is here (works great)
>
> but before you download the code, please read the whole mail,
> because we need your comments and ideas in order to make
> LADSPA the best and most flexible API, while still retaining simplicity.
>
> the ladspa package:
> http://www.linuxdj.com/ladspa/ladspa03272000.tar.gz
>
> the header file:
> http://www.linuxdj.com/ladspa/ladspa.h.txt
>
> I adapted the example host and the two plugins ( delay.c and filter.c) to the
> new LADSPA API.
>
> The only structure which used LADSPA_Data directly was PortRangeHint
> ( LowerBound and UpperBound).
> The PortRangeHint structure now contains two void * pointer to LowerBound
> and UpperBound. Therefore the plugin has to malloc() the memory for the values.
>
> I eliminated the LADSPA_Data type completely , since neither the union
> nor the char[16] solution sounded acceptable to me after reading David's mail.
> The approach is now to allow _ANY_ datatype, with no size restrictions, since
> it's all managed dynamically.
>
> Now to general capabilities:
>
> - hosts and plugin can support an arbitrary number of datatypes.
> the host can lookup the supported datatypes and choose amongst one of them
>
> - plugins can support DIFFERENT datatypes for input and outputs.
> The restriction is that you can have only one input datatype and one output
> datype.
> For example if you set input datatype = float and output datatype = double
> the both input CONTROL ports and input AUDIO ports have to use the float
> type, while output CONTROL ports and output AUDIO ports have to use double.
>
> Allowing per-port datatype would make things much more complicated for host
> and plugins, since our goal here is audio streaming not events.
>
> For example if you have a lowpassfilter running in 32bit float mode, then the
> cutoff frequency will be a float too, when you use the 64bit version, the
> parameter becomes 64bit too. I think that is not that much restrictive.
> Notice that input and output is decoupled.
> if you run a plugin with input dataype=float and output datatype=double
> (assuming that it supports different datatypes for input and output)
> the input control ports become float and the output control ports become
> double.
> Too much restrictive ? (IMHO it's not worth the trouble change this)
>
> I opted for separate input and output datatypes since it will allow
> to implement easily the famous CONVERTER-PLUGINS.
> (e.g. the ones which Juhana was talking about: double->16bit int converters
> etc) there is no limit about combinations.
> Each datatype is described by a DataTypeDescriptor:
>
> typedef struct {
> int BitSize;
> int BitAlign;
> int Type;
> char *Name;
> char *Description;
> } LADSPA_DataTypeDescriptor;
>
> let's take the famous 'float' datatype (32bit)
>
> BitSize=32
> BitAlign=32 (aligned to its size)
> Type=LADSPA_DATATYPE_NUMERIC | LADSPA_DATATYPE_FLOAT (just informational flags)
> Name="FLOAT32"
> Description: if the plugin wants, it can supply a brief description about the
> datatype.
>
> FLOAT32 is the UNIQUE identifier of the datatype.
> That means new datatype names have to be callocated in a centralized fashion,
> in order to avoid name clashes.
>
> Notice that this design allows even streams of single bits to be streamed
> between plugins.
> The key issue is that the data "supplier" plugin and data "consumer" plugin ,
> speak the same language.
> For example setting BitSize=4 and BitAlign=8, one could send a stream of 4bit
> data incapsulated into byte arrays (8 bit aligned etc)
>
> But most plugins will mostly only use the "float" or the "double" datatype, or
> maybe some integers for performance reasons.
>
> I'd say the genral recommendation for plugin-developers if to support the
> "float" datatype if they want that the plugin can run on as many as possible
> hosts.
> high-end plugins should provide the 32bit-float algorithm AND the 64bit-double
> algorithm, so that it runs well on "toy" hosts, and on complicated/professional
> hosts.
>
>
> Performance: SAME as old LADSPA since there is no runtime overhead
>
> Multichannel capabilities:
>
> although old LADSPA allows multiple input/output channels , it's not flexible
> enough, because the host sometimes want to use a subset of the available
> channels to perform operations.
>
> The only restriction of my multichannel model is that the ports are created
> when the descriptor() function is called that means.
> If we have a 32channel -> 1channel mixer
> the mixer shows up 32input ports after the descriptor() function is called.
> Then when calling instantiate() we can choose the number of desired channels.
> But we can tolerate this little waste of mem (in the case we use <32channels),
> since redesigning the port concept in order to be fully dynamic would complicate
> things.
>
> A plugin can inform the host how many channels it supports on the input side and
> output side. ( fields inside the plugin Descriptor)
> int InputChannelsMin; /* minimum number of supported input channels */
> int InputChannelsMax; /* maximum number of supported input channels */
> int OutputChannelsMin; /* minimum number of supported output channels */
> int OutputChannelsMax; /* maximum number of supported output channels */
>
> plus there is a flag if number of input channels has to match the number of
> output channels
>
> eg. A Hall plugin which supports mono and stereo:
> InputChannelsMin=1
> InputChannelsMax=2
> OutputChannelsMin=1
> OutputChannelsMax=2
> MultiChannelFlags=LADSPA_MULTICHANNEL_MATCH_INOUT (number of input channels
> has to be equal to the number of output channels)
>
>
> as another example a 4channel -> 1 channel mixer has:
> InputChannelsMin=1
> InputChannelsMax=4
> OutputChannelsMin=1
> OutputChannelsMax=1
> and the MATCH_IN_OUT flag is NOT set since you can choose the number of inputs
> between 1 and 4 while on the output side there is always only one channel.
>
> The API supports interleaved multichannel mode too:
> basically instead of using N (N=number of channels) ports with data-rate of R,
> you use one singe port with datarate N*R.
> But this will ONLY be used in very special cases, for example
> there could arise the need to process a 100 track interleaved stream
> with specialized multichannel plugins. In this case the interleaved mode
> can increase the performance quite a bit, but again , "normal" plugins and
> hosts will use the separate channel mode. (one port for every channel)
>
> (Notice: mentally sick people could even combine the interleaved multichannel
> mode with bit fields, for example streaming multiple interleaved single-bit
> streams over arrays of bytes. David, u like this ? :-) )
>
>
> In the case of a plugin supporting multiple datatypes ,
> since the datatype is passed to the instantiate function, some of the
> functionpointer assignments have to be moved from the descriptor()
> function to the instantiate() function since these are datatype dependent.
> eg. a plugin supporting float and double would have two run() functions
> run32() and run64() the Descriptor->run pointer would be assigned based
> on the datatype passed to the instantiate function.
> It's really easy to add a new datatype to a plugin.
>
>
> What is still missing is runAdd() support, it will be added as soon we
> agree on the setGian() issue (per-channel setGain etc).
> Any proposal ?
>
>
> Please study the C examples carefully:
> ladspa.h , the plugins: delay.c filter.c
> and the host: applyplugin.c
>
> And make your positive/negative comments / proposals etc.
>
> Anyway I think most of the people on the list will agree that the API is still
> small and clean, and that simple plugin writers and host writers do not have to
> face with added complexity (except for the few initialization issues).
>
> I think that ardour can take advantage of many of the new capabilities, since
> there are basically no restrictions in terms of dataype or number of channels.
> ( Paul you got your outbits == inbits , satisfied now ? :-)) )
>
>
> If some people are still fixated on the float-only method, then we should vote
> which version to use.
>
> I see ZERO advantages of old LADSPA over my
> multidatatype/multichannel version, but the NEARTERM DANGERS of old LADSPA
> are around the corner, and when they will show up there will be already
> zillions of plugins around, and here we have the Y2K-bug-like problem again.
>
> cheers,
> Benno.
>
>
>
>
_____________________________________________________
| Karl W. MacMillan |
| Peabody Institute of the Johns Hopkins University |
| Network and Telecommunications Services |
| karlmac_AT_peabody.jhu.edu |
| 410/659-8297 |
-----------------------------------------------------
This archive was generated by hypermail 2b28 : Mon Mar 27 2000 - 22:29:22 EEST