Rust Audio

First prototype of lv2 UI

Hello,

I started working on a UI solution for lv2. So far I have a very early prototype of an amplifier plugin. The UI has a knob to set the gain, a button for enable/bypass and two meters to show input and output levels.

Short demo clip:

Status

The following new crates are involved (none of them on crates.io yet):

  • lv2-ui – the lv2 interface
  • pugl-sys – a rust wrapper for pugl, the interface to the windowing system
  • pugl-ui – a stub for a pugl based GUI toolkit. Handles event propagation and widget layout. Not widgets themselves though.
  • ampmeter-rs.lv2 – the Simple Amplifiler demo plugin with some extra ports.
  • ampmeter-rs-ui.lv2 – the gui for ampmeter-rs-lv2. It has to be in a separate crate as in a rust crate there can only be one library.

Todo

Lots of stuff. A lot in the pugl- crates. lv2 specific stuff:

  • Atom ports
  • Bidirectional communication between UI and DSP part.

So far everything works without modifying existing crates of rust-lv2. One thing that needs to be modified in lv2-core AFAICS is, that the port communication between DSP and UI is bidirectional. Between host and plugin communication via one port is unidirectional an, e.g. InputPort is for signaling from the host to the plugin.

Between DSP and UI however, port communication via one port is bidirectional. For example if the plugin has an InputPort<Control> the DSP sets the current value of the control for example when the UI shows up by calling port_event() provided by the UI. When a port value is to be changed due to UI action the UI tells it to DSP by calling the write_function() callback, that the DSP provides. For now I do this with a newly introduced struct UIPort<T>.

I plan to further develop this in the upcoming weeks and months. Ideally lv2-ui will eventually part of rust-lv2. The two pugl- crates should remain separate as not everyone will be using pugl to create a UI.

Any thoughts, hints, findings? I would be glad to contribute to rust-lv2 and to Rust Audio in general.

2 Likes

I’m Interested, i will probably try it.

Just a remark about crates and projects. Having several crates doesn’t require to have one git repo per crate. For projects having several crates, I think it’s better to use one git repo with a workspace. This make intention clear and among other things, this allow to build all crates of the workspace in one command and gather all built binaries in one place.

You are right. It’s probably a good idea to move ampmeter-rs.lv2 and ampmeter-rs-ui.lv2 into one repo and I’ll probably do it. The others however, are sufficiently independent and should remain separate.

I forgot to mention, there is some initiative from vst side to deal with UI, did you look at it ? I found this project documenting some experiences around vst UI in rust.

Looks good so far!

However, if you want lv2-ui to be a part of Rust-LV2, you should fork it, integrate lv2-ui and then make a pull request. Otherwise, the project setup will get even more complicated than it already is.

I’m not able to discuss any implementation details with you yet since you’re quite early in your developments and I don’t have a deep understanding in LV2’s UI spec yet, but I would ask you to keep things as similar to Rust-LV2 and to reuse as much code as possible. LV2’s UI spec looks very similar to its core spec and I would love it if this would also be the case for lv2-ui and lv2-core!

I like that you already made the parallel between PluginInstance and PluginUIInstance. Maybe you should also adapt the lv2_descriptor macro! I also like that the UI receives the window as a raw pointer, which makes it open for different frameworks. Please keep it that way!

A little progress:

  • Atom port communication kinda works. Probably not in all cases
  • The two ampmeter repos have been consolidated.
  • Test installations are a bit easier

You can now checkout ampmeter-rs.lv2 repo (link see in original post) and run cargo build.

Next I am planning to write an actual plugin and thereby test and further develop the whole ui stack.