LV2 Development - instance handling specific to Ardour

Hi all!
tldr: yes, LV2mailing list exists, but this is host specific.

(I know its only a Tremolo, in this example, but has implications for other plugins in the works)

I’m in the process of putting together my own LV2 that addresses a short coming in Tremolo I would have liked to use. I have found that if a new instance is created that a new LFO is essentially created with no relationship to the first instance. short; more processing for a bad result, as the LFO’s are not aligned. (and really only need to have one LFO per Nchannel track)

The best solution I could think of, was to have another 2 atomPorts, one as a int flagging system and the other an array to hold modulation data, created by the first instance, every
activate() increments the flag by 1, and holds a copy in instance struct.
run() has a statement, if flag == 1 runs the LFO and processes its output. but the flags greater than 1 process audio with modulation array. (maybe i could achive this just in the .so without ports?)

Now the question I have is are instances just a child of a pluggin loaded once? or if the same pluggin is loaded twice across different tracks are they instances all children of the one parent? (sh!t explanation but.
Probably a clearer way to ask would be, does the one pluggin loaded on two separate busses, run as it own process each?

also could be an issue resolved by LV2 Instance Access but have no idea if supported by Ardour

That is not LV2 specific but also applies to VST2/3 and other plugin standards.

The common solution is to sync to the host transport. The LFO can be reset when the transport starts rolling (using a custom tempo), or ideally follow the host’s time (e.g pulse every quarter note).

This way the resulting sound is reproducible. After a rewind, playing the same song passage again, the same result is produced.

If the LFO is freely running the result is different every time. So an exported song will be different than what you heard before.

PS. Another solution would be to use Automation. A simple toggle that resets the LFO on the falling edge.

A somewhat unreliable way would be to reset the LFO in LV2’s activate method. Ardour also flushes (activate/deactivate) plugins at transport stop.

blatant plug:

Harrison’s “XT-TP Tremolo Panner” uses the host-sync method that Robin describes. I understand that you might want to make your own plugin for the task, but if you want to ‘try’ something first, you could start with the XT-TP.

Harrison’s plugins come pre-installed in Mixbus and Ardour binaries. You don’t need a license to try them in demo mode.


Thanks Robin and Ben!

I will test both approaches, and will definitely have a play with XT-TP.
The transport is something I quite often overlook, as half the time I’m just using busses to process audio for jamming, and not actually recording.

I think I’m after more of a learning experience, and eventually create a plugin that is not available on any platform(read: pipedream). Still an amateur with A LOT to learn, maybe I will see the light after learning how to sync instances.

I understand why instances are important, but to not have a method to do common processing (my imagination fancys a seperate run_plug() and run_instance() ) but this is not an LV2 standard) .
There are a lot of plugins with mono versions and stereo versions, that could really benefit from such an ability. Probably been discussed at length across plugin standards the merits of separation.I also imagine this approach could be used for instrument plugins with configurable outs which is where I want to go eventually.

Had a “play” XT-TP, Like the bais control for sure! and the rythmic options are also neat!
Had to have a look at the pluggin.ttl lol, one thing i have noticed with other plugins aswell; mono version just skips ports in the mono version? still uses the same shared object. Is the same processing occuring? or does the host know to skip those ports via the connect_port()? empty port buffers? or null? so many questions lol.

Also did a bit of testing
static void activate (LV2_Handle instance) { MyTremolo* t = (MyTremolo*) instance; if (!t) return; lv2_log_note(&t->logger, "log activate.\n"); }
couldn’t get a flush with the transport(made sense to me though), however i did find i would get this log on ManualConfig + audio port but now cant recreate issue(still on 8.0.0 spinner, so could be a resolved bug).

yet to sync with host

Ah, I forgot. This depends on Preferences > Transport > Plugins > Silence Plugins when transport stops.

Thank you!
would have taken me a month of sundays to figure it out, highly appreciated!

This topic was automatically closed 28 days after the last reply. New replies are no longer allowed.