From d at drobilla.net Tue Feb 4 11:08:26 2025 From: d at drobilla.net (David Robillard) Date: Tue, 4 Feb 2025 14:08:26 -0500 Subject: [LV2] Control ports vs lv2:Parameter In-Reply-To: <39e21c9b-4ece-49b9-9b77-86cc8e0f43b1@gmail.com> References: <39e21c9b-4ece-49b9-9b77-86cc8e0f43b1@gmail.com> Message-ID: On 2025-01-17 11:03, Stefano D'Angelo wrote: > Il 30/06/24 08:40, Stefano D'Angelo ha scritto: > >> Il giorno mar 25 giu 2024 alle ore 23:27 David Robillard >> ha scritto: >>> On Thu, 2024-06-06 at 12:05 +0200, Stefano D'Angelo wrote: >>>> Hi all, >>>> >>>> Is there a way to provide "graceful degradation" for hosts that do >>>> not >>>> support lv2:Parameter but still use lv2:ControlPort? Should/could >>>> both >>>> mechanisms be used to refer to the same parameter? >>> Both mechanisms can be used to refer to the same "conceptual" parameter >>> in a sense, by giving ports an lv2:designation.? This doesn't amount to >>> a graceful degradation mechanism for old hosts, though (it could be >>> useful for version and/or state migration among other things, but it's >>> not a mechanism). >>> >>> I guess you could invent one - a message to disable actually using the >>> value of the control ports or something - but it seems like it would be >>> quite a mess. >>> >>> I'd suggest just being the chicken or the egg instead, so to speak. >> Ok, clear. I guess I'll have to support one mechanism per plugin, >> perhaps having different versions of the same plugin if I want to >> support both. >> >> Maybe in the future we could have something like >> "is-an-advanced/better-version-of" predicate in the RDF - like dc: >> replaces -, so that hosts might actually hide the "not advanced/worse" >> plugin if the better one is supported? > > Sorry to resurrect this discussion after such a long time. > > I just noticed that the documentation of lv2:Parameter says that "a > parameter could be controlled via a ControlPort, messages, or both", so > I was wondering if it would be ok to have both a mandatory ControlPort > and a lv2:connectionOptional Atom port "writing to"/"reading from" the > same lv2:Parameter (the Atom port would be also normally operate on all > other input our output controls). If that's the case, the plugin could > also lv2:requiredFeature urid:map, and thus effectively provide graceful > degradation in a sense. > > Before I give it a try, do you think? this is blasphemy or does it sound > reasonable and feasible? > > (BTW, in case you wonder, I am interested in supporting Ardour, Reaper > and Pipewire, and AFAIK Pipewire doesn't support reading/writing > lv2:Parameters via Atom ports, see https://gitlab.freedesktop.org/ > pipewire/pipewire/-/issues/4042.) Hi Stefano, No worries, sorry for not being very on top of this on my end. My last year (several years really) hasn't been conducive to driving solutions across the whole ecosystem, just keeping things maintained is about all I've had time for. I'm getting around to better implementing (and figuring out how to better specify) the parameter stuff now though. The thing the quoted sentence is getting at is really just the "transport independence" of parameters. A "parameter" is a slightly abstract thing in other words: you can change it with messages, you can designate a control port with it, it's sometimes stored in state, and so on. The terminology here arguably isn't great, but c'est la vie. I didn't consider the idea of using both at once and I don't remember anyone else doing so either. The intent here was a bit more meta: tying parameters in general to the mechanism of control ports has been a disaster, so untying them avoids that problem. If people add yet another mechanism or want to add OSC support or whatever, it won't require the user-visible breakage that this transition does, because the host trivially knows what all the parameter values are. Mechanism is a separate thing (as it should be, and always should have been, but live and learn). Practically speaking it also integrates directly with state, of course, but that's beside the point here. Anyway, I don't see any concrete technical problem with having both, except for the conflict: a mandatory control port always has a value. So what does the plugin do when it gets a message that sets that parameter to some other value? There's solutions to that that will maybe work in practice (switch to ignoring controls if you ever receive a message or something) but it's pretty hackey. Worth a shot I suppose, if you're dedicated to trying some graceful degradation situation. It's not clear what a host should do in this situation though, this would probably need to be decided and written down somewhere if it makes sense. In the grand scheme of things, control ports have been an absolute nightmare in so many ways, I wish people were more bold and just used the new stuff, or even invented a better way to do parameters if that's necessary and pushed that instead, but I haven't had the time to take on such a wide-sweeping project and nobody else has either, so here we are. If pipewire is the blocker here, maybe that's something to look into... at the moment I'm completely ignorant to that, but thanks for the link, I'll check it out at some point. -- dr From zanga.mail at gmail.com Wed Feb 5 23:11:17 2025 From: zanga.mail at gmail.com (Stefano D'Angelo) Date: Thu, 6 Feb 2025 08:11:17 +0100 Subject: [LV2] Control ports vs lv2:Parameter In-Reply-To: References: <39e21c9b-4ece-49b9-9b77-86cc8e0f43b1@gmail.com> Message-ID: Il 04/02/25 20:08, David Robillard ha scritto: > On 2025-01-17 11:03, Stefano D'Angelo wrote: >> Il 30/06/24 08:40, Stefano D'Angelo ha scritto: >> >>> Il giorno mar 25 giu 2024 alle ore 23:27 David Robillard >>> ha scritto: >>>> On Thu, 2024-06-06 at 12:05 +0200, Stefano D'Angelo wrote: >>>>> Hi all, >>>>> >>>>> Is there a way to provide "graceful degradation" for hosts that do >>>>> not >>>>> support lv2:Parameter but still use lv2:ControlPort? Should/could >>>>> both >>>>> mechanisms be used to refer to the same parameter? >>>> Both mechanisms can be used to refer to the same "conceptual" >>>> parameter >>>> in a sense, by giving ports an lv2:designation.? This doesn't >>>> amount to >>>> a graceful degradation mechanism for old hosts, though (it could be >>>> useful for version and/or state migration among other things, but it's >>>> not a mechanism). >>>> >>>> I guess you could invent one - a message to disable actually using the >>>> value of the control ports or something - but it seems like it >>>> would be >>>> quite a mess. >>>> >>>> I'd suggest just being the chicken or the egg instead, so to speak. >>> Ok, clear. I guess I'll have to support one mechanism per plugin, >>> perhaps having different versions of the same plugin if I want to >>> support both. >>> >>> Maybe in the future we could have something like >>> "is-an-advanced/better-version-of" predicate in the RDF - like dc: >>> replaces -, so that hosts might actually hide the "not advanced/worse" >>> plugin if the better one is supported? >> >> Sorry to resurrect this discussion after such a long time. >> >> I just noticed that the documentation of lv2:Parameter says that "a >> parameter could be controlled via a ControlPort, messages, or both", >> so I was wondering if it would be ok to have both a mandatory >> ControlPort and a lv2:connectionOptional Atom port "writing >> to"/"reading from" the same lv2:Parameter (the Atom port would be >> also normally operate on all other input our output controls). If >> that's the case, the plugin could also lv2:requiredFeature urid:map, >> and thus effectively provide graceful degradation in a sense. >> >> Before I give it a try, do you think? this is blasphemy or does it >> sound reasonable and feasible? >> >> (BTW, in case you wonder, I am interested in supporting Ardour, >> Reaper and Pipewire, and AFAIK Pipewire doesn't support >> reading/writing lv2:Parameters via Atom ports, see >> https://gitlab.freedesktop.org/ pipewire/pipewire/-/issues/4042.) > > Hi Stefano, > > No worries, sorry for not being very on top of this on my end.? My > last year (several years really) hasn't been conducive to driving > solutions across the whole ecosystem, just keeping things maintained > is about all I've had time for.? I'm getting around to better > implementing (and figuring out how to better specify) the parameter > stuff now though. > > The thing the quoted sentence is getting at is really just the > "transport independence" of parameters.? A "parameter" is a slightly > abstract thing in other words: you can change it with messages, you > can designate a control port with it, it's sometimes stored in state, > and so on.? The terminology here arguably isn't great, but c'est la > vie.? I didn't consider the idea of using both at once and I don't > remember anyone else doing so either.? The intent here was a bit more > meta: tying parameters in general to the mechanism of control ports > has been a disaster, so untying them avoids that problem.? If people > add yet another mechanism or want to add OSC support or whatever, it > won't require the user-visible breakage that this transition does, > because the host trivially knows what all the parameter values are.? > Mechanism is a separate thing (as it should be, and always should have > been, but live and learn).? Practically speaking it also integrates > directly with state, of course, but that's beside the point here. Ok, I see. > Anyway, I don't see any concrete technical problem with having both, > except for the conflict: a mandatory control port always has a value. > So what does the plugin do when it gets a message that sets that > parameter to some other value?? There's solutions to that that will > maybe work in practice (switch to ignoring controls if you ever > receive a message or something) but it's pretty hackey. Worth a shot I > suppose, if you're dedicated to trying some graceful degradation > situation.? It's not clear what a host should do in this situation > though, this would probably need to be decided and written down > somewhere if it makes sense. For some reason I thought that control port values could represent parameter values at the beginning of buffers (frame/sample index 0) and events would set values at arbitrary times/indices within the buffer length, but of course that's not specified anywhere. > In the grand scheme of things, control ports have been an absolute > nightmare in so many ways, I wish people were more bold and just used > the new stuff, or even invented a better way to do parameters if > that's necessary and pushed that instead, but I haven't had the time > to take on such a wide-sweeping project and nobody else has either, so > here we are. ?If pipewire is the blocker here, maybe that's something > to look into... at the moment I'm completely ignorant to that, but > thanks for the link, I'll check it out at some point. As this time it's not a hobby thing, I'll stick with whatever is commonly accepted/done/available. This means that right now I'll have either two versions of the same plugins - and try hard to make it clear to users that they should use one or the other depending on the host (that's a mess though) - or otherwise release only one based on where I expect them to be most used/useful. Best, Stefano