feature request: latency compensation meta data

Issue #9 resolved
magnetophon created an issue

It would be nice if plugins could tell the host what latency they have, so the host can compensate.

Comments (23)

  1. Albert Graef repo owner

    Can you flesh this out a bit? Or, better yet, suggest a possible implementation as a pull request?

  2. magnetophon reporter

    I'm sorry, I can't. I hardly understand any C++

    You do know what I mean by this request, right?

  3. Albert Graef repo owner

    You do know what I mean by this request, right?

    Nope, that's why I asked for more details. :) Maybe you can at least tell me how the Faust meta data is supposed to look like, and what needs to be added to the LV2 manifest? Or better yet, attach a minimal test program with the new feature, and a mockup LV2 manifest for it.

  4. magnetophon reporter

    Sorry for not responding quicker. I'll try to better explain what I mean.

    LV2, like most plugin standards, has a way of telling the host: "I have X samples of unwanted latency, please compensate". The host uses this information to send the audio to the plugin X samples before it is needed at the plugins output, thereby compensating for the unwanted latency. An example would be a lookahead limiter. Such a plugin needs time to look ahead, but as a user, you want the output synchronized with your other tracks. It would be great if faust2lv2 could incorporate an easy way to provide this info to the host. I used the words metadata in the title of this bugreport, but those might not be the correct terms.

    Am I clear now?

    I don't know to implement this, but an example of an implementation is here: https://github.com/x42/nodelay.lv2 I'm not sure, but I'm guessing the relevant code is here: https://github.com/x42/nodelay.lv2/blob/master/nodelay.ttl.in#L53-L61

    Hope that helps! Thanks!

  5. Albert Graef repo owner

    Well, this doesn't say much. :( It's a property, but a property of what? The plugin? A port? Also, which hosts support this property? Ardour? Qtractor?

    I really need a working example of a ttl file that shows how this property is used. The example you provided above doesn't use lv2:latency at all, it uses the port property lv2:reportsLatency which is something completely different.

  6. David Robillard

    Long story short, do what lv2:reportsLatency says, and specify the portProperty as in that example.

    I'll skip the more general "why" about why there's also a property, but you should also specify lv2:designation lv2:latency, and conventionally lv2:symbol "latency".

  7. Albert Graef repo owner

    @drobilla Thanks for chiming in! I think that I get it now. The problem is, there's no easy way I could determine that value in an automatic fashion within the confines of a Faust architecture (at least I don't see any).

    I'm not sure whether that helps, but what I can do is to equip a passive (output) Faust control (which is already in the program) with the right properties so that it becomes a proper latency control output port. But then it's the duty of the Faust programmer to provide the value of that control in some suitable way (e.g., make it a constant value or something that's computed from an input control).

    So Robin's program would look somewhat like this in Faust (this just passes the input signal right through, but you get the idea):

    delay_in = hslider("delay", 0, 0, 192000, 1);
    delay_out = hbargraph("latency [lv2:reportsLatency] [lv2:integer] [unit:frames]", 0, 192000);
    process(x) = attach(x, delay_in : delay_out);
    

    In fact, it would be trivial to implement this, I just need to add lv2:reportsLatency to the LV2-specific Faust meta data recognized by faust-lv2, and make sure that the "latency" symbol doesn't get mangled if that's what hosts expect.

    @magnetophon is that what you want?

  8. magnetophon reporter

    Are you asking if I agree that the Faust programmer should set/calculate the value? If so: yes. There is no way for a computer to know if a delay is intentional or not. If not, I don't understand the question.

  9. Albert Graef repo owner

    FWIW, here's how Robin's program would look like in Faust, complete with the actual delay and the report/delay mode switch:

    delay_in = hslider("delay", 0, 0, 192000, 1);
    delay_out = hbargraph("latency [lv2:reportsLatency] [lv2:integer] [unit:frames]", 0, 192000);
    
    report = checkbox("report [lv2:scalepoint delay-only 0 delay+report 1 report-only 2]");
    do_delay = report != 2;
    do_report = report != 0;
    
    process(x) = attach((1-do_delay)*x+do_delay*x@delay_in,
      do_report*delay_in : delay_out);
    

    Well, at least I think that's what it does (minus the cross-fade). ;-) Luckily enough, it seems that Ardour recognizes the "latency" output port in there even without the lv2:reportsLatency portProperty (which isn't recognized by faust-lv2 yet, so it's not in the plugin ttl).

    Now what? How do I test this thing? Record a click track, then record my voice at a certain latency to see how everything lines up in the recording?

  10. Albert Graef repo owner

    @magnetophon:

    Are you asking if I agree that the Faust programmer should set/calculate the value? If so: yes.

    Ok, thanks. Yes, that was what I asked.

    @drobilla: One more question, if I may: That lv2:designation lv2:latency property, is it mandatory? I don't see that anywhere in Robin's ttl file, so I guess not.

  11. David Robillard

    Basically lv2:designation is a more modern generic mechanism for giving meaning to a port which meshes well with event-based control among other things (properties being the fundamental building block of RDF). So, "mandatory" is hard to say since this is all a bit laissez-faire (e.g. some hosts would probably be content with just assuming a control out named "latency" is the one), but it is best practice to include (it is best practice in general to include an lv2:designation for any port that has a meaning for which some property is defined).

    Can you get away without and have it work in most hosts people care about currently? Probably.

  12. Albert Graef repo owner

    @drobilla Thanks for the explanation, I added both the port property and the designation, so we should have all bases covered now.

    @magnetophon The latest HEAD implements the meta tag lv2:reportsLatency as discussed above, can you please check if it works for you?

    I'm still not quite sure how to test that this really does what it's supposed to, but what I can say is that the attached Faust plugin seems to work the same in Ardour as Robin's original version.

  13. Albert Graef repo owner

    Actually, it seems that Robin's plugin has a bug; it also reports zero latency in the "No delay, only report latency" mode. Incidentally, my Faust version does that mode correctly. :)

    Anyway, everything seems to work as it should (in Ardour at least; Qtractor just seems to ignore the latency port). @magnetophon, can you please give it a whirl so that I know that it works on your end, too? I'm attaching my latest version of mynodelay which takes the desired delay in msecs and has the default delay set to 1000 msec for easier testing.

  14. Log in to comment