On Wed, 2012-08-08 at 05:38 -0400, Jeremy Salwen wrote:
[...]
  You emphasized the current state of lilv, saying
"Lilv doesn't really
 do anything like this related to run time", and didn't speak further
 on the possibilities.  To me, this statement coupled with the further
 silence on the topic meant that you intended to keep it this way.
 Anyway, I'm more pleasantly surprised that this is not the case than I
 am bothered by the fact that I misunderstood you.
 I completely understand that from an implementational point of view,
 midi binding functionality is quite different than what lilv does.
 But from a utilizational point of view, midi binding fits right in
 with the rest of the API. 
Yes, but it is really more of an afterthought to some more fundamental
control things that need to happen.  The silence is because I do not see
any interesting questions there.  Things just need doing.
  I suppose if the contained libraries are parallel
installable,
 packagers could still package them independently, but if we want
 that... why distribute them in one package upstream in the first
 place?  To save a tiny (if loud) niche of people from a few commands? 
  I had a different concept of SDK then you  I thought
we were talking
 about the scenario above as the default case, where the SDK simply
 packaged the various libraries and tools together for convenience.
 That the main difference would be the unification of the
 documentation, and the implicit pressure on developers to use more of
 the libraries.  I agree that what you were talking about: monolithic
 incompatible versions, would be a mistake.but that seems like an issue
 orthogonal to what level of wrapping "magic" goes into the plugin host
 library. 
This is precisely what I am talking about.  Putting libraries in the SDK
makes these issues happen.  Libraries have compatibility issues that the
specifications do not.
   Even on the
host side of things, I was unsatisfied with the lilv
 c++ wrapper, so I wrote lolvmm. 
 And (unless I'm mistaken) never told me about it until now, so Lilv
 remains unimproved.  A wonderful example of "collaboration" failing in
 practice ;)
  Well my wrapper came out of this conversation on the drobilla
 tracker: 
http://dev.drobilla.net/ticket/756
 I then posted a link to my library a few months ago when I finished. 
 
So you did.  Apologies, my mistake (I really wish Trac would email about
ticket comments!)
  In the SDK model, we *don't want* to see
alternatives develop.  We
 want
 to see *improvements contributed*.
  I see contributions and alternatives as two sides of the same coin.
 To me it is irrelevant if the alternative code exists on some dude's
 website or if it get's standardized and included in the official SDK. 
Well, it is not irrelevant at all.  "The" way to do things being a
rotten header buried on some impossible to find website somewhere - or
sometimes one that's just gone away entirely - was a massive problem for
LV2 in the past.  The extensions that defined properties and such were
even worse.
Tried that, didn't work.  In practice, the specs need to be curated and
maintained in the official package.
   The point is that Joe the developer still has a
choice in how he
 hosts his plugins.
           * Control events
          * Events for announcing new parameters dynamically (I am
         assuming this
         is a requirement)
          * Appropriate properties for describing the MIDI binding of
         parameters
           * Events for setting/announcing that as well
          * Probably some kind of helper header API to make the above
         easier
         (i.e. reading/writing those events in a single function call)
          * An example plugin that actually uses this stuff (a
         multi-band EQ
         seems the best candidate)
         After all that is done, working, and established... sure, some
         library
         for automagic MIDI binding.  Whatever.  Right now, worrying
         about that
         is putting many carts before the horse.
 No!  We do not need control events for midi binding.  The only thing
 we need at this point is  
Except everything even remotely related to LV2 is *constantly* held up
by control ports.  I am tired of investing effort in a mistake, and I am
definitely not breaking the Lilv API to implement magic support for a
mistake that I constantly deal with griped about.
The sooner those damned ports die the better off we all are.
  * Appropriate properties for describing the MIDI
binding of parameters
 And that's what I was trying to get working on.  I think you're
 looking to far into the future.  I have, right here, right now, a
 synthesizer plugin that desperately wants default midi binding.  I am
 telling you that if I sat down today, with a set of properties that
 describe midi binding, I could build a modified lilv shared library
 that implemented default midi binding and without any compatibility
 changes, suddenly every single host would support that feature.  I
 could even add some extra functions so that hosts who are aware of it
 could turn it off, or modify the bindings in real time.  Again, this
 is all with standard control ports.  And when event ports come around,
 we could implement the exact same binding functionality, and the host
 wouldn't even need to know what type of control port it is. 
Well, what you say now is considerably different from what you said in
your original email to the lv2 mailing list, and, I will say again, Lilv
does not, will not, and *can not* do this "magic" in this way.  You said
you understood this...
In your original email, you were describing some odd hybrid of MIDI
parameters and control ports where the host could switch between them,
and perhaps have GUI controls which send MIDI to the plugin.
Specifically, you said:
          I was thinking about the ideal behavior from
the user's point
         of view, and a realize that a knob which sends midi CC events
         to the plugin would be ideal. 
As has been said often in this discussion, this is awful, and no, spec
work will not be done towards it.  Controlling plugin parameters via
MIDI is a gigantic step backwards, and spending time bloating
hosts/libraries doing this is ridiculous.  Why would you go out of your
way to have a 7-bit controller?  I am completely in agreement with Jeff
on this one.  It is not only awful on paper, it has been shown to be
awful in practice with other APIs.  This is not the way forward.
Now, if you have control ports, and want to describe their default MIDI
bindings in the .ttl file, that is an entirely different thing.
Essentially all that is needed is a single predicate to list the MIDI
binding, since the MIDI extension already defines everything else about
MIDI:
http://lv2plug.in/ns/ext/midi
I do not know which extension is most appropriate to put this predicate,
since it could be used for non-MIDI things as well.  In any case,
something like:
<someport> foo:binding [ a midi:Controller ; midi:controllerNumber 27 ]
There are a few main reasons I have not done this yet:
* Nobody actually cared who was intending on actually writing code,
until you right now
* To do this in a utility API for control ports means the API depends on
the plugin instance directly, which means all the advantages of the
event based scheme in my previous mail go away, and much of the whole
thing will have to be rewritten for control events
* Static MIDI bindings don't seem very useful anyway, to me
This is not a new pattern.  The theme of "oh, well, it could be done
correctly, but we have these LADSPA things that everybody despises and
suck for all sorts of other reasons, so we can kind of do it half-assed
for now and then re-do it again later" is a recurring one.
If you want to work on the host side portions of this, feel free,
however it can not be "magically" implemented in lilv as you wish (which
you will see if you try despite my suggestion).  To be clear, I am not
saying I personally dislike this idea, I am saying it is not possible.
It can however be made simple, at least.  Step one, and the most useful
90% of the work, would be to write code that reads that data, generates
some interim structure, which can then match against a MIDI event (i.e.
return true if and only if the MIDI event matches the binding
description).  This is a necessary component of any solution.  The
interim structure is required because this must be real-time safe so you
can't read from the data every time.
The 'get a value from a MIDI event' part is probably best done in a
static inline header included in the MIDI extension.
Given those two things, all the host has to do in its 'foreach event'
loop (which is usually present anyway, always in the case of hosts
writing from Jack or similar) is check if the event matches the binding
of any port, and if so sets the port value.  For acceptable performance
with lots of ports and bindings, the above mentioned structure that does
this matching will have to store a port index and do the search in
log(n_bindings) time.
         It is also important to take a look at existing host reality,
         which
         frankly the GMPI perspective tends to lack: for example, the
         two main
         large hosts I work on, Ardour and Ingen, would probably not
         use this
         convenience layer whatsoever, since they already have their
         own binding
         mechanisms that are specific to the internals of those
         particular
         programs.
 But these are precisely the hosts which don't need default midi
 bindings:  you can do them manually! It's hosts like lv2_jack_host
 that would benefit the most, because they would go from midi bindings
 (and in fact any control ports) being unusable, to usable, albeit only
 with default settings.  That's the power of default midi bindings,
 that you can host a plugin with the simplest midi host, and you can
 tweak the knobs through your midi keyboard that the host might not
 even understand how to vary.  I don't see a stronger argument for how
 things should be done based on the "existing host reality" than the
 practical benefits that this path would offer.
 I'm all for event-based control ports, but that's an issue separate
 from midi binding libraries, which I think can be handled right now. 
Personally I think this use case is a heck of a lot more nichey than you
let on, especially since it means you need to configure your MIDI
controller to match the plugin... unless the plugin is associated with
specific hardware, how many people are about to - or even can - do that?
There is a reason MIDI learn is how it is almost always done, static
bindings on the plugin just aren't very useful in most cases.
That said, sure, support for this would be nice (largely because it can
be re-used when the bindings are more usefully stored elsewhere, but
nice nonetheless).  It is unfortunately not possible to have lilv hosts
magically support this without any changes at all, but it can be made
very easy as described above.
As far as what I am about to do goes, there is quite a bit of LV2 work
that needs doing that I consider to be of much higher priority than
this.  I will not be concerned with binding until we have something
worth binding, and that big red column of fail in the document that
started this thread turns green.  However, patches are welcome.
-dr
P.S. Your mail client is mangling quotes in a way that makes replying
cleanly very difficult and time consuming...