[LV2] Dplug wrapper for LV2

Hanspeter Portner dev at open-music-kontrollers.ch
Sat Mar 30 07:05:10 PDT 2019


On 30.03.19 12:18, Auburn Sounds wrote:
> 
>     Opaque blobs are, IMO, a bad idea, so the state extension encourages
>     transparent state so it can be portably saved in whatever way makes the
>     most sense for the host, easily investigated by the user, and so on,
>     but you *can* save blobs if you really want to.
> 
> 
> 
> I've argued several times on IRC about the use case where opaque blogs are
> useful. Maybe I'm not clear enough, so let me sum up again.

I guess I've partially been involved in this conversation trying to help you.

Your initial arguments were that with LV2 you cannot (from one plugin version to
another)

* rename ports
* reorder ports
* add ports
* change control port ranges
* remove ports

Well, it turns out you can do all of them but the last (as long as the port
symbol stays the same).

[x] rename ports
[x] reorder ports
[x] add ports
[x] change control port ranges
[ ] remove ports

Then you've brought up this example here:

2019-03-29 10:11:16	p0nce	let me take an example
2019-03-29 10:11:36	p0nce	say a customer use Bablinator 1.0 with a cutoff
parameter of 400hz
2019-03-29 10:12:10	p0nce	in Bablinator 2.0, me the GentleAudio developer have
remapped cutoff to extend up to 500hz
2019-03-29 10:12:27	p0nce	but cutoff is mapped logarithmicatlly
2019-03-29 10:12:56	p0nce	with my custom serialization to EnterprisePresetXML, I
can remap that parameter when loading a Bablinator 1.0 chunk
2019-03-29 10:13:16	p0nce	if I'm the LV2 host though, I cannot do anything apart
from saying "this is not the right Bablinator version"
2019-03-29 10:13:48	p0nce	because GentleAudio didn't said to me how exactly the
parameter was mapped, the format couldn't express this s-curve
2019-03-29 10:14:00	p0nce	BUT
2019-03-29 10:14:24	p0nce	say this upgrade doesn't work, either GentleAudio or
PoorLV2Host doesn't manage to do it
2019-03-29 10:14:39	p0nce	I, the AngryCustomer write to GentleAudio to have my
session back
2019-03-29 10:14:58	p0nce	if the host handle the save/restore, then they cannot
do anything, and the host either
2019-03-29 10:15:06	p0nce	if the plugin handle the chunking, they can
2019-03-29 10:16:02	p0nce	the manufacturer of the plugin, because the host
developer will be busy doing proper software
2019-03-29 10:16:10	p0nce	that's the heart of my argumentation
2019-03-29 10:20:11	p0nce	(ok my example require that cutoff is not mapped in a
known way)

The problem as I've understood it (may well be that I've misunderstood it) is
that you use fixed control port ranges [0,1] (because other plugin specs force
you to) and do some internal mapping to e.g. cutoff frequency.

In your plugin v1 you map control port range [0,1] to internal range [0,400] Hz.
User sets cutoff in the host to 200 Hz and saves a preset (control port value 0.5).

No dev released plugin v2 which maps control port range [0,1] to internal range
[0,500] Hz. Previous user's preset from plugin v1 is loaded in plugin v2 with
control port value 0.5, which now maps to 250 Hz (assuming linear mapping for
simplicity).

That's (one) reason you want to be in control of how your control port values
are saved, right ?

I've tried to explain to you on IRC (and obviously failed), that with LV2 you
don't have this problem, because you don't need to map from a (silly) [0,1]
control port range to the real (physical) internal parameter range [0, 400] Hz.

You just use the latter directly for your control ports.

Here exemplified with some metadata.

plugin v1
---------

lv2:port [
	a lv2:InputPort, lv2:ControlPort ;
	lv2:index 0 ;
	lv2:symbol "cutoff" ;
	lv2:name "Cutoff frequency" ;
	lv2:default 200 ;
	lv2:minimum 0 ;
	lv2:maximum 400 ;
	lv2:portProperty lv2:logarithmic ;
	units:unit units:frequency ;
] .

User sets cutoff frequency to 200 Hz and safed a preset in the host, the preset
contains the following chunk of metadata:

preset for v1
-------------

<>
	a pet:Preset ;
	lv2:prot [
		lv2:symbol "cutoff" ;
		pset:value 200
	] .

Now the dev decides to reorder the control port from index 0->2, renames it from
'cutoff frequency'->'Renamed cutoff frequency' and changes the range from
[0,400]->[0,500].

Any LV2 host will be fine to load the preset from v1 into an instance from v2
(and vice versa).

plugin v2
---------

lv2:port [
	a lv2:InputPort, lv2:ControlPort ;
	lv2:index 2 ;
	lv2:symbol "cutoff" ;
	lv2:name "Renamed cutoff frequency" ;
	lv2:default 220 ;
	lv2:minimum 0 ;
	lv2:maximum 500 ;
	lv2:portProperty lv2:logarithmic ;
	units:unit units:frequency ;
] .

> "If the host does state saving, there is no way to have upgrades over the
> lifetime of a plug-in.Because the host know much less about the plugin semantics
> than the plugin itself. **Some plug-in parse blobs to upgrade state to a
> seemingly incompatible plug-in version.**"

If you expose the real (physical) value directly to the control ports in your
LV2 wrapper, I think your issues (as you explained them in the above example)
are gone, imho.

> I think it's a good idea for the format acceptance, and for backwards
> compatibility for a product existence. Such "chunk parsing" I've seen as an
> intern in plugin company.


More information about the Devel mailing list