[LV2] [LAD] LV2: Communicate from the DSP to the UI

Robin Gareus robin at gareus.org
Tue Nov 5 19:34:40 PST 2013

Hi guys,

On 11/05/2013 06:48 AM, Michael Fisher wrote:
> ForgeFrame frame;
> AtomObject obj (forge.write_blank (frame, 0, object_type));
> forge.property_head (prop_type, 0);
> forge.write_raw (buffer, sizeof (float) * bufsize);

That works all right, but it's not proper LV2 Atom/RDF.
 - the receiver has no idea about the length
 - if the host-buffer overflows there's no way to re-sync
 - it cannot be interleaved with other DSP -> UI messages
 - `jalv.gtk -d ...` cannot parse it as RDF
 - ...

LV2_Atom_Vector is made for exactly that purpose.

from sratom/tests/sratom_test.c:

  lv2_atom_forge_property_head(&forge, eg_vector, 0);
  int32_t elems[] = { 1, 2, 3, 4 };
  lv2_atom_forge_vector(&forge, 4, forge.Int, sizeof(int32_t), elems);

<OT> @Drobilla:
I think the last line is slightly wrong, it should be
  lv2_atom_forge_vector(&forge, sizeof(int32_t), forge.Int, 4, elems);
as per ns/ext/atom/forge.h

lv2_atom_forge_vector(LV2_Atom_Forge* forge,
                      uint32_t        child_size,
                      uint32_t        child_type,
                      uint32_t        n_elems,
                      const void*     elems)

not that it really matters because only (child_size * n_elems) is used.

Either way, you'll likely need
http://lv2plug.in/ns/ext/resize-port/#minimumSize as well if you're
going to pass large chunks of data around.

<rant mode on>

Anyway even if you make it work, I doubt that you'll have much fun:

Atom messages are written into a ringbuffer in the LV2host in the
DSP-thread. This ringbuffer is sent to the UI by another thread
(jalv.gtk and ardour use a g_timeout() usually at 40ms ~ 25fps), and
finally things are drawn in the X11 thread ie. gtk-main or qt's main.

Other LV2 hosts may do do things differently and you have no control
over it.

As much as like LV2 from a user's perspective and host integration. It
kinds sucks for visualizations. The only realistic way do to RT
*visualizations* (e.g. a scope) right is to bypass the host (use
instance access & a semaphore) and use openGL with vblank-sync using a
custom thread in the UI (drobilla is going to blacklist me now).

Synchronizing even one [audio] thread with the gfx-hardware is not
trivial. Default LV2 communication involves two or more, including some
threads that the LV2-host controls. -- It may be fun for someone to sort
this all out, but not me.

That being said I do like LV2 Atoms, event-queues, mapped URIs, and more
generally the CY-y way of LV2, though. It's very nice, robust and
elegant for control. Sometimes a tad overkill, but heck, therefore it's
portable, too.

However, if you want to write a proper scope, make it a jack application
- or wait for Fons to release zita-scope.

<rant mode off>

I did some tests a while ago, passing raw audio data inside an
LV2_Atom_Vector to the UI. I've just added an over-simplified scope UI
so that you see for yourself. unzip,
 sudo make install PREFIX=/usr
 jalv.gtk http://gareus.org/oss/lv2/audiopipe
 # curse loudly
 sudo make uninstall PREFIX=/usr

-------------- next part --------------
A non-text attachment was scrubbed...
Name: audiopipe.lv2.tar.gz
Type: application/x-gzip
Size: 5462 bytes
Desc: not available
URL: <http://lists.lv2plug.in/pipermail/devel-lv2plug.in/attachments/20131106/c4578cd1/attachment-0002.bin>

More information about the Devel mailing list