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.
</OT>
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,
make
sudo make install PREFIX=/usr
jalv.gtk
http://gareus.org/oss/lv2/audiopipe
# curse loudly
sudo make uninstall PREFIX=/usr
Cheers!
robin