On Wed, 2013-11-06 at 04:33 +0100, Robin Gareus wrote:
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
- ...
Indeed. Don't Do That(TM). Using non-standard types is not so good,
but can be valid. This, however, is not valid. The property value has
no atom header, so the host might look for the type and/or size the
standard guarantees is there, find some float bytes instead, and boom.
Do not send corrupt atoms around!
raw() is very much a "do not use this unless you really very definitely
know exactly what you are doing" function. Perhaps the docs should say
as much.
Anyway, jalv.gtk -d is a good indicator of sanity, it should print
something human readable. Practical reasons aside (e.g. working in
separated hosts like Ingen), debugging is a heck of a lot nicer when you
can just look at the data flying around. If it crashes, it's probably
because the atoms are corrupt.
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).
Why? I have constantly said since day 1 that instance-access is
suitable for visualization use. For plugins that do a bunch of stuff
*and* have visualization, they can simply degrade to not having the
fancy visualization part if it's not available. It's people abusing the
facility to do control that I have a problem with, for very good
reasons.
Using instance-access for visualization is 100% OK (assuming graceful
degradation if the plugin does other things). Using it for control is
grounds for being taken out back and shot.
Synchronizing even one [audio] thread with the
gfx-hardware is not
trivial. Default LV2 communication involves two or mo
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.
While this is practically true in most cases, it's not really the right
thinking for what's going on here. Essentially what you have between
the plugin instance and UI is a network. The best you get is
"recentish". So, yeah, hardish sync is inherently not happening.
While messages will work just fine for many kinds of basic
visualization, for hyper accurate scopes that want to go so far as to
sync with graphics hardware, obviously it's not the best approach.
That's why instance-access exists. By all means, use it. I'd actually
like to see somebody use the god damned thing for the intended purpose
for a change :P
(If such performance is not required, though, messages are better,
because working across processes and/or networks is handy. Scopes are a
bit much, but e.g. simple meters should certainly do so)
Cheers,
--
dr