<?xml version="1.0" encoding="utf-8"?>
<feed xmlns="http://www.w3.org/2005/Atom"><title>drobilla.net - LAD</title><link href="https://drobilla.net/" rel="alternate"/><link href="https://drobilla.net/category/lad/feed/atom" rel="self"/><id>https://drobilla.net/</id><updated>2026-02-10T19:50:00-05:00</updated><entry><title>Suil 0.10.26</title><link href="https://drobilla.net/2026/02/10/suil-0-10-26.html" rel="alternate"/><published>2026-02-10T19:50:00-05:00</published><updated>2026-02-10T19:50:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2026-02-10:/2026/02/10/suil-0-10-26.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/suil-0.10.26.tar.xz"&gt;Suil 0.10.26&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs.  It provides wrappers that allow Gtk and Qt hosts to load, and potentially embed, plugin GUIs that use the "native" windowing API (Coca, WIN32, or X11).&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add clang nullability annotations&lt;/li&gt;
&lt;li&gt;Address new warnings in clang and clang-tidy 21&lt;/li&gt;
&lt;li&gt;Fix documentation build without sphinx_lv2_theme&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Lilv 0.26.4</title><link href="https://drobilla.net/2026/02/10/lilv-0-26-4.html" rel="alternate"/><published>2026-02-10T18:47:00-05:00</published><updated>2026-02-10T18:47:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2026-02-10:/2026/02/10/lilv-0-26-4.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/lilv-0.26.4.tar.xz"&gt;Lilv 0.26.4&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add clang nullability annotations&lt;/li&gt;
&lt;li&gt;Address new warnings in clang and clang-tidy 21&lt;/li&gt;
&lt;li&gt;Fix default LV2 path on cross-compiled Windows builds&lt;/li&gt;
&lt;li&gt;Fix loading of duplicate bundles with equivalent versions&lt;/li&gt;
&lt;li&gt;Fix potential crash when UIs have multiple types or binaries&lt;/li&gt;
&lt;li&gt;Use consistent quoting and punctuation in log messages&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Sratom 0.6.22</title><link href="https://drobilla.net/2026/02/10/sratom-0-6-22.html" rel="alternate"/><published>2026-02-10T18:45:00-05:00</published><updated>2026-02-10T18:45:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2026-02-10:/2026/02/10/sratom-0-6-22.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/sratom-0.6.22.tar.xz"&gt;Sratom 0.6.22&lt;/a&gt; has been released.  Sratom is a small library for serializing LV2 atoms.  Sratom reads/writes atoms from/to RDF, allowing them to be converted between binary and text or stored in a model.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add clang nullability annotations&lt;/li&gt;
&lt;li&gt;Address new warnings in clang and clang-tidy 21&lt;/li&gt;
&lt;li&gt;Fix documentation build without sphinx_lv2_theme&lt;/li&gt;
&lt;li&gt;Gracefully handle reading vectors with missing childType properties&lt;/li&gt;
&lt;li&gt;Gracefully handle writing vectors with zero childSize properties&lt;/li&gt;
&lt;li&gt;Improve error handling&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>A More Modern Gtk3 Jalv Frontend</title><link href="https://drobilla.net/2025/11/26/a-more-modern-gtk3-jalv-frontend.html" rel="alternate"/><published>2025-11-26T21:36:00-05:00</published><updated>2025-11-26T21:36:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-11-26:/2025/11/26/a-more-modern-gtk3-jalv-frontend.html</id><content type="html">&lt;p&gt;My simple single-plugin LV2 host, &lt;a href="http://drobilla.net/software/jalv"&gt;Jalv&lt;/a&gt;, isn't quite sure whether it's a developer utility or polished user program, but in any case, it had become stale in the past few years and needed an update.&lt;/p&gt;
&lt;p&gt;Most of those changes are internal and only interesting for those who use it as a basis for larger systems.  The internals have been largely rewritten to support various things, but this post isn't about that.  This post is about a more obviously stale thing: the Gtk2 interface.&lt;/p&gt;
&lt;p&gt;In keeping with the free desktop tradition of constant breakage with reduced functionality, that toolkit is now EOLed, and soon the ability to embed GUIs whatsoever will probably go away.  Luckily though, we're not quite there yet, and it's still possible/feasible to embed GUIs in Gtk3 (at least on X11), so things can continue roughly as they were for a while.  Gtk2 &lt;em&gt;is&lt;/em&gt; EOLed though, which is a problem for distributions, and I have no interest in maintaining code for a dead toolkit, so that frontend is gone entirely in the latest release.  This does mean that some plugin GUIs written in Gtk2 will no longer work, but that's inherent to the situation (and why general plugin GUIs shouldn't use Gtk).&lt;/p&gt;
&lt;p&gt;This seemed like a good time to update the UI to be a bit more “modern”, particularly since a menu bar has never really made much sense here anyway.
I replaced this with a header bar, which I think does suit plugins better.  For example, here's the custom GUI for the &lt;a href="https://lsp-plug.in/"&gt;LSP&lt;/a&gt; Compressor:&lt;/p&gt;
&lt;p&gt;&lt;a href="/images/lsp_compressor_in_jalv.png"&gt;&lt;img alt="Custom UI for LSP Compressor" src="/images/lsp_compressor_in_jalv-357x222.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;As always, there's also generic controls, with a few refinements but still using the same boring stock widgets:&lt;/p&gt;
&lt;p&gt;&lt;a href="/images/amsynth_in_jalv.png"&gt;&lt;img alt="Generic UI for amsynth" src="/images/amsynth_in_jalv-208x239.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;All of the menu items have been moved into a single menu button, which is a pattern I'm sceptical of in general, but it works fine for a very simple application like this.  The preset menu can be unwieldy, but that's a whole topic unto itself that I hope to tackle more comprehensively later.&lt;/p&gt;
&lt;p&gt;Code-wise, it's long been a problem that the rudimentary (lack of) architecture couldn't easily support the more advanced features people wanted from it.  So, I've reworked everything into a more serious application, with a more explicit architecture and communication patterns that make adding new features much easier.  As far as the Gtk frontend goes, I've also switched to using more modern APIs like &lt;code&gt;GtkApplication&lt;/code&gt;, &lt;code&gt;GAction&lt;/code&gt;, and so on.  To be fair, these parts are quite nice.  Actions are a pretty good model for building accessible GUI applications, and these new APIs encourage doing the right thing.
There's still some areas that need work, but &lt;code&gt;jalv.gtk3&lt;/code&gt; (the version which has a &lt;code&gt;.desktop&lt;/code&gt; file and all that) is much closer to being a proper application that integrates with the desktop environment now, and smells less like a hackey program that developers just use to check if their plugin works.&lt;/p&gt;
&lt;p&gt;That aside, Jalv is still frequently used from the command-line, and there's a
major QoL improvement there as well: the positional argument now accepts files
and directories, not just plugin URIs.  The code will try to figure out what to
do automatically, for example, if a bundle or data file only describes a
single plugin, then that plugin is loaded.  Presets can also be passed (by path
or by URI), which will load the appropriate plugin with that preset initially applied.  In short, it's more like the “do what I mean” interface many people expect.&lt;/p&gt;
&lt;p&gt;It's been entirely too long since the last release, but now that the host libraries and Jalv are up to date with most issues resolved, I'm going to try to do some broader cross-project efforts to address a few things that are a mess across the LV2 ecosystem as a whole, with Jalv serving as a sort of reference implementation.
For now, though, it's just a much better implementation of the same old features.&lt;/p&gt;</content><category term="misc"/><category term="Hacking"/><category term="LAD"/><category term="LV2"/></entry><entry><title>Jalv 1.8.0</title><link href="https://drobilla.net/2025/11/26/jalv-1-8-0.html" rel="alternate"/><published>2025-11-26T20:13:00-05:00</published><updated>2025-11-26T20:13:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-11-26:/2025/11/26/jalv-1-8-0.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/jalv-1.8.0.tar.xz"&gt;Jalv 1.8.0&lt;/a&gt; has been released.  Jalv (JAck LV2) is a simple host for LV2 plugins.  It runs a plugin, and exposes the plugin ports to the system, essentially making the plugin an application.  For more information, see &lt;a href="http://drobilla.net/software/jalv"&gt;http://drobilla.net/software/jalv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add "quit" console command&lt;/li&gt;
&lt;li&gt;Add AppStream metainfo file&lt;/li&gt;
&lt;li&gt;Add Qt6 version&lt;/li&gt;
&lt;li&gt;Add missing short versions of command line options&lt;/li&gt;
&lt;li&gt;Add option to install tool man pages&lt;/li&gt;
&lt;li&gt;Add support for advanced parameters in console frontend&lt;/li&gt;
&lt;li&gt;Add support for control inputs with time:beatsPerMinute designation&lt;/li&gt;
&lt;li&gt;Add support for control outputs with lv2:latency designation&lt;/li&gt;
&lt;li&gt;Avoid over-use of yielding meson options&lt;/li&gt;
&lt;li&gt;Build Qt UI with -fPIC&lt;/li&gt;
&lt;li&gt;Clean up and strengthen code&lt;/li&gt;
&lt;li&gt;Clean up command line help output&lt;/li&gt;
&lt;li&gt;Cleanly separate audio thread from the rest of the application&lt;/li&gt;
&lt;li&gt;Fix Jack latency recomputation when plugin latency changes&lt;/li&gt;
&lt;li&gt;Fix clashing command line options&lt;/li&gt;
&lt;li&gt;Fix minor memory leaks&lt;/li&gt;
&lt;li&gt;Make help and version commands exit successfully&lt;/li&gt;
&lt;li&gt;Only send control messages to designated lv2:control ports&lt;/li&gt;
&lt;li&gt;Only send position to ports that explicitly support it&lt;/li&gt;
&lt;li&gt;Reduce Jack process callback overhead&lt;/li&gt;
&lt;li&gt;Remove Gtk2 interface&lt;/li&gt;
&lt;li&gt;Remove limits on the size of messages sent from plugin to UI&lt;/li&gt;
&lt;li&gt;Remove transport position dumping from Jack process callback&lt;/li&gt;
&lt;li&gt;Replace use of deprecated Gtk interfaces&lt;/li&gt;
&lt;li&gt;Rework Gtk3 interface into a relatively modern Gtk application&lt;/li&gt;
&lt;li&gt;Rewrite man pages in mdoc&lt;/li&gt;
&lt;li&gt;Simplify and unify plugin and preset command-line arguments&lt;/li&gt;
&lt;li&gt;Switch to external zix dependency&lt;/li&gt;
&lt;li&gt;Use Gtk switches instead of checkboxes for toggle controls&lt;/li&gt;
&lt;li&gt;Use fewer platform-specific APIs&lt;/li&gt;
&lt;li&gt;Use portable zix filesystem API&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Jalv"/></entry><entry><title>Lilv 0.26.2</title><link href="https://drobilla.net/2025/11/25/lilv-0-26-2.html" rel="alternate"/><published>2025-11-25T19:49:00-05:00</published><updated>2025-11-25T19:49:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-11-25:/2025/11/25/lilv-0-26-2.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/lilv-0.26.2.tar.xz"&gt;Lilv 0.26.2&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Actually reload files if bundles are unloaded then reloaded&lt;/li&gt;
&lt;li&gt;Add support for loading xsd:float literals, "INF", and "NaN"&lt;/li&gt;
&lt;li&gt;Avoid warning about non-existent entries in LV2_PATH&lt;/li&gt;
&lt;li&gt;Fix crash when duplicate plugins are discovered&lt;/li&gt;
&lt;li&gt;Fix lilv_node_is_literal() with booleans&lt;/li&gt;
&lt;li&gt;Refine command line tool interfaces and documentation&lt;/li&gt;
&lt;li&gt;lv2bench: Add support for common features and options&lt;/li&gt;
&lt;li&gt;lv2bench: Use more realistic real-time scheduling&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Sratom 0.6.20</title><link href="https://drobilla.net/2025/11/12/sratom-0-6-20.html" rel="alternate"/><published>2025-11-12T19:26:00-05:00</published><updated>2025-11-12T19:26:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-11-12:/2025/11/12/sratom-0-6-20.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/sratom-0.6.20.tar.xz"&gt;Sratom 0.6.20&lt;/a&gt; has been released.  Sratom is a small library for serializing LV2 atoms.  Sratom reads/writes atoms from/to RDF, allowing them to be converted between binary and text or stored in a model.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Avoid over-use of yielding meson options&lt;/li&gt;
&lt;li&gt;Avoid use of scanf when reading MIDI events&lt;/li&gt;
&lt;li&gt;Fix lint checks&lt;/li&gt;
&lt;li&gt;Fix potential memory error when writing ambiguous relative paths&lt;/li&gt;
&lt;li&gt;Improve code quality&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>Suil 0.10.24</title><link href="https://drobilla.net/2025/11/12/suil-0-10-24.html" rel="alternate"/><published>2025-11-12T19:20:00-05:00</published><updated>2025-11-12T19:20:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-11-12:/2025/11/12/suil-0-10-24.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/suil-0.10.24.tar.xz"&gt;Suil 0.10.24&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs.  It provides wrappers that allow Gtk and Qt hosts to load, and potentially embed, plugin GUIs that use the "native" windowing API (Coca, WIN32, or X11).&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add header warnings test&lt;/li&gt;
&lt;li&gt;Avoid over-use of yielding meson options&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Lilv 0.26.0</title><link href="https://drobilla.net/2025/11/12/lilv-0-26-0.html" rel="alternate"/><published>2025-11-12T19:15:00-05:00</published><updated>2025-11-12T19:15:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-11-12:/2025/11/12/lilv-0-26-0.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/lilv-0.26.0.tar.xz"&gt;Lilv 0.26.0&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add header warnings test&lt;/li&gt;
&lt;li&gt;Add option to control indexing overhead for subject queries&lt;/li&gt;
&lt;li&gt;Avoid over-use of yielding meson options&lt;/li&gt;
&lt;li&gt;Cache LANG value and add option to override it&lt;/li&gt;
&lt;li&gt;Fix Python tests&lt;/li&gt;
&lt;li&gt;Fix build with dynmanifest support&lt;/li&gt;
&lt;li&gt;Fix loading plugins that haven't been loaded yet as state&lt;/li&gt;
&lt;li&gt;Fix loading plugins with invalid lv2:appliesTo properties as state&lt;/li&gt;
&lt;li&gt;Fix potential memory leak in lilv_world_load_plugin_classes()&lt;/li&gt;
&lt;li&gt;Fix potential memory leak in lilv_world_set_option()&lt;/li&gt;
&lt;li&gt;Gracefully ignore and warn about non-directories in LV2_PATH&lt;/li&gt;
&lt;li&gt;Improve loading performance when many plugin versions are found&lt;/li&gt;
&lt;li&gt;Improve performance when loading and deleting state&lt;/li&gt;
&lt;li&gt;Only consider manifest data when discovering related presets/etc&lt;/li&gt;
&lt;li&gt;Print a warning when a property unexpectedly has several values&lt;/li&gt;
&lt;li&gt;Reduce temporary node allocations during query operations&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Zix 0.8.0</title><link href="https://drobilla.net/2025/11/12/zix-0-8-0.html" rel="alternate"/><published>2025-11-12T18:40:00-05:00</published><updated>2025-11-12T18:40:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-11-12:/2025/11/12/zix-0-8-0.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/zix-0.8.0.tar.xz"&gt;Zix 0.8.0&lt;/a&gt; has been released.  Zix is a lightweight C library of portability wrappers and data structures.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add ZIX_REALTIME and ZIX_NONBLOCKING attributes&lt;/li&gt;
&lt;li&gt;Add warning suppression macros&lt;/li&gt;
&lt;li&gt;Annotate count and size parameters of allocator API&lt;/li&gt;
&lt;li&gt;Avoid "deprecated" POSIX functions on Windows&lt;/li&gt;
&lt;li&gt;Avoid over-use of yielding meson options&lt;/li&gt;
&lt;li&gt;Clean up attribute documentation&lt;/li&gt;
&lt;li&gt;Gracefully handle failed allocation in path and filesystem functions&lt;/li&gt;
&lt;li&gt;Reduce empty BTree memory requirements&lt;/li&gt;
&lt;li&gt;Strengthen zix_file_equals()&lt;/li&gt;
&lt;li&gt;Use getenv() instead of environ to avoid issues on FreeBSD&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="C"/><category term="LAD"/><category term="Zix"/></entry><entry><title>Lilv “Object Index” Option Revised</title><link href="https://drobilla.net/2025/11/12/lilv-object-index-option-revised.html" rel="alternate"/><published>2025-11-12T13:58:00-05:00</published><updated>2025-11-12T13:58:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-11-12:/2025/11/12/lilv-object-index-option-revised.html</id><content type="html">&lt;p&gt;My previous post, &lt;a href="https://drobilla.net/2025/09/29/improving-lv2-discovery-performance.html"&gt;“Improving LV2 Discovery Performance”&lt;/a&gt;, described adding an option to &lt;a href="https://drobilla.net/software/lilv/"&gt;lilv&lt;/a&gt; that controls whether an additional index is maintained for loaded LV2 data.
While testing those changes for release, I discovered a few things (like &lt;a href="https://git.open-music-kontrollers.ch/~hp/lv2lint"&gt;lv2lint&lt;/a&gt;) that break without the index, which convinced me that disabling it by default wasn't the right decision.&lt;/p&gt;
&lt;p&gt;So, I'm instead enabling it by default, which avoids this “break by default” situation.
The downside is that hosts will need to add code in order to enjoy the performance improvements.
To make this change as simple as possible, I also made &lt;code&gt;lilv_world_set_option&lt;/code&gt; accept a null value to disable boolean options, so most hosts can simply add this line:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;lilv_world_set_option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;LILV_OPTION_OBJECT_INDEX&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;NULL&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This requires the new version, but the same change can be made without bumping the required version by avoiding the niceties:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="n"&gt;LilvNode&lt;/span&gt;&lt;span class="o"&gt;*&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;false_node&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;lilv_new_bool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nb"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;lilv_world_set_option&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;world&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="s"&gt;&amp;quot;http://drobilla.net/ns/lilv#object-index&amp;quot;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;span class="w"&gt;  &lt;/span&gt;&lt;span class="n"&gt;false_node&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;

&lt;span class="n"&gt;lilv_node_free&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;false_node&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This will log a warning about the unsupported option on older versions, but otherwise have no effect.&lt;/p&gt;</content><category term="misc"/><category term="Hacking"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/><category term="RDF"/></entry><entry><title>Improving LV2 Discovery Performance</title><link href="https://drobilla.net/2025/09/29/improving-lv2-discovery-performance.html" rel="alternate"/><published>2025-09-29T10:25:00-04:00</published><updated>2025-09-29T10:25:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-09-29:/2025/09/29/improving-lv2-discovery-performance.html</id><content type="html">&lt;p&gt;LV2 plugins (and other data, like presets) are discovered by parsing &lt;a href="https://www.w3.org/TR/turtle/"&gt;Turtle&lt;/a&gt; files installed in various bundle directories.
If the host only needs to know &lt;em&gt;which&lt;/em&gt; things are installed, then only &lt;code&gt;manifest.ttl&lt;/code&gt; files need to be loaded.
That takes only a fraction of a second (60 ms on this machine, which has 897 plugins installed), but if the host needs more information (like the plugin's label or what ports it has), then the data files need to be loaded as well, which can take several seconds.
The parser (from &lt;a href="https://drobilla.net/software/serd/"&gt;serd&lt;/a&gt;) is very fast, so the overwhelming majority of this time is spent inserting data into a model.&lt;/p&gt;
&lt;p&gt;I was recently doing some work on &lt;a href="https://drobilla.net/software/lilv/"&gt;lilv&lt;/a&gt; related to discovery, and got sidetracked into investigating how much of this overhead could be eliminated.
Quite a bit, as it turns out, but before explaining how, I'll give a brief summary of the relevant fundamentals so people who don't spend their days in the triple mines can understand what I'm talking about.&lt;/p&gt;
&lt;p&gt;LV2 data is written in the &lt;a href="https://www.w3.org/TR/turtle/"&gt;Turtle&lt;/a&gt; syntax, which can have a lot of structure, but is ultimately just a shorthand for data that is simply a “flat” series of triples.
For example, the abbreviated Turtle&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;&amp;lt;http://example.org/amp&amp;gt;&lt;/span&gt;
    &lt;span class="kt"&gt;a&lt;/span&gt; &lt;span class="nn"&gt;lv2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nt"&gt;Plugin&lt;/span&gt; &lt;span class="p"&gt;;&lt;/span&gt;
    &lt;span class="nn"&gt;doap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Amplifier&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;represents the two triples&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;&amp;lt;http://example.org/amp&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;rdf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt;  &lt;span class="nn"&gt;lv2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nt"&gt;Plugin&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;
&lt;span class="nv"&gt;&amp;lt;http://example.org/amp&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;doap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt; &lt;span class="s"&gt;&amp;quot;Amplifier&amp;quot;&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;which describe a plugin with the name “Amplifier”.&lt;/p&gt;
&lt;p&gt;Two implications of this format are important to understand here:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;All data is a set of triples which can be stored in some lexicographical order to be quickly searchable (for example, a set ordered subject-first can be used to quickly find triples that start with a given subject).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;All data can be streamed via a simple “flat” interface (for example a function with three parameters), and is trivial to inspect and/or filter on the fly (much like line-based text in POSIX pipelines).&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The data may not be stored as a “literal” ordered set of triples (they're actually &lt;em&gt;quads&lt;/em&gt; in memory for one thing), but this simplified way of thinking about it is good enough for this explanation.&lt;/p&gt;
&lt;p&gt;Which order is best depends on the query.
For example (borrowing a bit of syntax from &lt;a href="https://www.w3.org/TR/sparql11-query/"&gt;SPARQL&lt;/a&gt; where &lt;code&gt;?name&lt;/code&gt; represents a query variable), if the host asks something like “what's the name of this plugin” or&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nl"&gt;&amp;lt;http://example.org/amp&amp;gt;&lt;/span&gt; &lt;span class="nn"&gt;doap&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nt"&gt;name&lt;/span&gt; &lt;span class="nv"&gt;?name&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;then it needs to find triples that start with the given subject and predicate (&lt;code&gt;&amp;lt;http://example.org/amp&amp;gt;&lt;/code&gt; and &lt;code&gt;doap:name&lt;/code&gt;) to see what object (&lt;code&gt;?name&lt;/code&gt;) they have.
So, a subject-predicate-object or “SPO” index will work well.
If, however, the host asks something like “which things are plugins” or&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="nv"&gt;?plugin&lt;/span&gt; &lt;span class="nn"&gt;rdf&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nt"&gt;type&lt;/span&gt; &lt;span class="nn"&gt;lv2&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="nt"&gt;Plugin&lt;/span&gt; &lt;span class="p"&gt;.&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;then an SPO index doesn't help because there's no known subject to search for.
Most queries are like this, with either a subject or object wildcard (querying relatively “fixed” predicates is rare), so lilv has always had both an SPO and OPS index to support them.&lt;/p&gt;
&lt;p&gt;This is convenient, but twice the indexing means roughly twice the overhead.
The SPO index is the natural order used in the syntax, and supports most code (which mainly looks up properties of known things), but the OPS index isn't used so much.
Can it be removed entirely to speed things up?
It &lt;em&gt;is&lt;/em&gt; used for many important things, but conveniently, there's only a few fixed cases of those (like finding plugins as above).
So, we can take advantage of the streaming nature of the data to record this information while it's being read, instead of inserting it into an index only to query it out later.&lt;/p&gt;
&lt;p&gt;To do this in the implementation, I introduced the concept of a “skimmer”.
A skimmer inserts triples into a model as usual, but first “skims” them and records items of interest for later use.
For example, a skimmer checks whether a triple has &lt;code&gt;rdf:type lv2:Plugin&lt;/code&gt;, and if so, records the subject in a result set that stores only plugin URIs.
Some cases are a bit trickier, and actually pulling this off cleanly took quite an overhaul, but details aside, it turns out that this approach can be used to eliminate the OPS index entirely without losing any functionality.&lt;/p&gt;
&lt;p&gt;How much of an improvement does this make?
On this machine, using &lt;code&gt;lv2ls -n&lt;/code&gt; as a crude benchmark, the time goes from 3.11 to 1.72 seconds, or about a 45% improvement.
The memory consumption goes down a bit as well, from (even more crudely) a max-RSS of about 138 to 112 MiB, or about a 19% improvement (everything here is an average of three runs).
The improvement will vary dramatically based on what's installed, for example in some earlier tests with a different configuration I saw drops from around 7 to 4 seconds, but in general, not bad!&lt;/p&gt;
&lt;p&gt;Are there any downsides to this?
Yes, primarily two:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;As with any significant change, there is the possibility of regression.
   Discovery is a little more restricted than before, so although I've done my best to test things, there is a possibility of things not being discovered anymore.
   Usually the fix for this is adding information to the manifest that should have been there anyway.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Though the implementation itself doesn't make queries that require the OPS index, hosts themselves can since lilv provides generic query functions.
   To support this, there's a new boolean option, &lt;code&gt;LILV_OPTION_OBJECT_INDEX&lt;/code&gt;, which can be used to enable or disable the OPS index.
   Since most hosts don't need it, I decided to disable this by default.
   That will be a regression for hosts that do, however, who need to explicitly opt in to the old behaviour by enabling this option.
   A warning is printed if a query will be slow because of the missing index, so it should at least be obvious if this happens.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;These changes are now in the &lt;code&gt;main&lt;/code&gt; branch in git, which will be released soon, probably as version 0.26.0.&lt;/p&gt;</content><category term="misc"/><category term="Hacking"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/><category term="RDF"/></entry><entry><title>Software Pages Removed</title><link href="https://drobilla.net/2025/02/16/software-pages-removed.html" rel="alternate"/><published>2025-02-16T11:32:00-05:00</published><updated>2025-02-16T11:32:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-02-16:/2025/02/16/software-pages-removed.html</id><content type="html">&lt;p&gt;I haven't been sure what to do about the software pages here for quite a while.
Most of them were essentially just stale versions of the README files from their projects,
and for better and worse, most of the projects I maintain are libraries that don't have as much of a need for a homepage as user-facing software.
It's easy to just ignore things that don't really matter in day-to-day work,
but the embarrassingly bad state of things became really clear when I sat down to actually poke through this site.&lt;/p&gt;
&lt;p&gt;Since it's much more important for me right now to streamline maintenance duties and eliminate as much overhead as possible,
I've simply removed all of the software pages, and redirected those addresses to the corresponding Gitlab projects where possible.
I might bring them back at some point, but for now, no pages are better than stale pages that really only serve to make things look bad.
I don't have traffic metrics here, but I seriously doubt anyone will either notice or care.&lt;/p&gt;
&lt;p&gt;I'm not sure about the utility of the software release posts or tarballs either.
Ideally, the effort required to make a release could be reduced to simply pushing a git tag,
and cross-domain posting hugely complicates that.
Besides, the tarballs are made manually on my personal machine, so they're absolutely &lt;em&gt;less&lt;/em&gt; trustworthy than the signed tags in git anyway, and, I assume, not reproducible.
At the same time, for many reasons I'm wary of fully investing in some git forge or another,
the automatic tarballs provided by all of them leave much to be desired (the silly “v” names for example),
and I don't want to disrupt things for packagers.
We'll see, but for now I'll leave the mechanics of actual releases as they are.&lt;/p&gt;
&lt;p&gt;Ultimately, pages and posts are largely a waste of time for libraries and similar things that only support other projects anyway.
So, a more radical simplification of the release process would be a good idea,
but for now I'll just take out the trash and reduce the amount of things I need to consider in that process.&lt;/p&gt;</content><category term="misc"/><category term="Hacking"/><category term="LAD"/></entry><entry><title>Intermission</title><link href="https://drobilla.net/2025/02/04/intermission.html" rel="alternate"/><published>2025-02-04T14:40:00-05:00</published><updated>2025-02-04T14:40:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-02-04:/2025/02/04/intermission.html</id><content type="html">&lt;p&gt;I don't suppose inactivity from me will be terribly surprising to anyone after the past several years.
Still, since I was working on emptying my bug-fix and maintenance queue, making releases, and finally getting to some significant forward progress again, an update:&lt;/p&gt;
&lt;p&gt;Unfortunately I got violently ill last week with some horrible flu-like thing, the worst I've ever had (and I'm a COVID casualty, so that's saying quite a lot).
Somehow, it's still going strong.
So, aside from maybe a few minutes a day of idle tinkering, everything I was doing is on pause for a while.
Hopefully a short while, but so far so not good, so we'll see.&lt;/p&gt;
&lt;p&gt;As an added bonus, Google just bricked my phone with a botched forced update, so I'm locked out of 2FA and many other things besides (I suppose I had to learn the hard way that I've gotten lazy and too dependent on that horrible device).
So, yeah, things aren't going great, to put it lightly.&lt;/p&gt;
&lt;p&gt;On the bright side, I do have some exciting things in the queue, but since I don't do vapourware or hype (to a fault, really), and have a huge amount of “infrastructure” work to do first anyway, you'll have to stay tuned for that.
Assuming I don't die first, anyway.&lt;/p&gt;
&lt;p&gt;... if I do, it &lt;em&gt;would&lt;/em&gt; be pretty funny that this was my last post though, so I've got that going for me, which is nice.&lt;/p&gt;
&lt;p&gt;[Edited on 2025-02-16 to remove broken link]&lt;/p&gt;</content><category term="misc"/><category term="Hacking"/><category term="LAD"/></entry><entry><title>Suil 0.10.22</title><link href="https://drobilla.net/2025/01/19/suil-0-10-22.html" rel="alternate"/><published>2025-01-19T13:58:00-05:00</published><updated>2025-01-19T13:58:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-01-19:/2025/01/19/suil-0-10-22.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/suil-0.10.22.tar.xz"&gt;Suil 0.10.22&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs.  It provides wrappers that allow Gtk and Qt hosts to load, and potentially embed, plugin GUIs that use the "native" windowing API (Coca, WIN32, or X11).&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add support for X11 in Qt6&lt;/li&gt;
&lt;li&gt;Fix library current_version on MacOS&lt;/li&gt;
&lt;li&gt;Monitor size hints and window resizes for X11 in Gtk3&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Lilv 0.24.26</title><link href="https://drobilla.net/2025/01/19/lilv-0-24-26.html" rel="alternate"/><published>2025-01-19T13:53:00-05:00</published><updated>2025-01-19T13:53:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-01-19:/2025/01/19/lilv-0-24-26.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/lilv-0.24.26.tar.xz"&gt;Lilv 0.24.26&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add lint option with project metadata and code quality tests&lt;/li&gt;
&lt;li&gt;Avoid use of VLAs in lv2apply&lt;/li&gt;
&lt;li&gt;Clean up and isolate platform-specific code&lt;/li&gt;
&lt;li&gt;Fix C++ test build on MacOS&lt;/li&gt;
&lt;li&gt;Fix library current_version on MacOS&lt;/li&gt;
&lt;li&gt;Fix test suite when TMPDIR has no trailing slash&lt;/li&gt;
&lt;li&gt;Fully separate library code from programs&lt;/li&gt;
&lt;li&gt;Improve const correctness&lt;/li&gt;
&lt;li&gt;Replace more platform-specific code with use of zix&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Sratom 0.6.18</title><link href="https://drobilla.net/2025/01/19/sratom-0-6-18.html" rel="alternate"/><published>2025-01-19T13:49:00-05:00</published><updated>2025-01-19T13:49:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-01-19:/2025/01/19/sratom-0-6-18.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/sratom-0.6.18.tar.xz"&gt;Sratom 0.6.18&lt;/a&gt; has been released.  Sratom is a small library for serializing LV2 atoms.  Sratom reads/writes atoms from/to RDF, allowing them to be converted between binary and text or stored in a model.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add lint option with project metadata and code formatting tests&lt;/li&gt;
&lt;li&gt;Avoid snprintf when writing MIDI events&lt;/li&gt;
&lt;li&gt;Enable clang nullability checks&lt;/li&gt;
&lt;li&gt;Fix library current_version on MacOS&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>Zix 0.6.2</title><link href="https://drobilla.net/2025/01/18/zix-0-6-2.html" rel="alternate"/><published>2025-01-18T23:53:00-05:00</published><updated>2025-01-18T23:53:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-01-18:/2025/01/18/zix-0-6-2.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/zix-0.6.2.tar.xz"&gt;Zix 0.6.2&lt;/a&gt; has been released.  Zix is a lightweight C library of portability wrappers and data structures.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix documentation build with sphinxygen fallback wrap&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="C"/><category term="LAD"/><category term="Zix"/></entry><entry><title>Zix 0.6.0</title><link href="https://drobilla.net/2025/01/18/zix-0-6-0.html" rel="alternate"/><published>2025-01-18T21:49:00-05:00</published><updated>2025-01-18T21:49:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2025-01-18:/2025/01/18/zix-0-6-0.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/zix-0.6.0.tar.xz"&gt;Zix 0.6.0&lt;/a&gt; has been released.  Zix is a lightweight C library of portability wrappers and data structures.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add ZIX_NODISCARD attribute&lt;/li&gt;
&lt;li&gt;Add option to build for older Windows versions&lt;/li&gt;
&lt;li&gt;Add zix_expand_environment_strings()&lt;/li&gt;
&lt;li&gt;Add zix_string_view_equals()&lt;/li&gt;
&lt;li&gt;Avoid fdatasync() on Darwin&lt;/li&gt;
&lt;li&gt;Fix build on POSIX systems without PATH_MAX defined&lt;/li&gt;
&lt;li&gt;Fix library current_version on MacOS&lt;/li&gt;
&lt;li&gt;Fix nullability annotations for zix_canonical_path() and friends&lt;/li&gt;
&lt;li&gt;Fix ring unit test when mlock() is unavailable&lt;/li&gt;
&lt;li&gt;Improve documentation&lt;/li&gt;
&lt;li&gt;Support building for UWP&lt;/li&gt;
&lt;li&gt;Support building for Windows with or without UNICODE&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="C"/><category term="LAD"/><category term="Zix"/></entry><entry><title>Main Branches Renamed</title><link href="https://drobilla.net/2024/10/31/main-branches-renamed.html" rel="alternate"/><published>2024-10-31T23:23:00-04:00</published><updated>2024-10-31T23:23:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2024-10-31:/2024/10/31/main-branches-renamed.html</id><content type="html">&lt;p&gt;As most git users are aware, the default branch name in git changed from
&lt;code&gt;master&lt;/code&gt; to &lt;code&gt;main&lt;/code&gt; a while ago.  Since I maintain projects created both before
and after this change, some maintenance tasks have become more difficult to
automate as a result (and I'm a sucker for consistency).&lt;/p&gt;
&lt;p&gt;I put off dealing with this because I was planning to make &lt;code&gt;master&lt;/code&gt; branches
disappear at the same time APIs are broken, but that wasn't a good idea for
several reasons beyond the scope of this post.  So, I've changed all of my
personal projects, and all projects maintained under the LV2 umbrella, to use
&lt;code&gt;main&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;If you're tracking any of those repositories, maintain packaging
infrastructure, or similar, please update your local trees and/or configuration
accordingly.  It's best to rename the local branch with git, since this
preserves your local reftree and avoids accidental use of the old name:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;git branch -m master main
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/></entry><entry><title>Lilv 0.24.24</title><link href="https://drobilla.net/2024/01/23/lilv-0-24-24.html" rel="alternate"/><published>2024-01-23T19:39:00-05:00</published><updated>2024-01-23T19:39:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2024-01-23:/2024/01/23/lilv-0-24-24.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/lilv-0.24.24.tar.xz"&gt;Lilv 0.24.24&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Avoid overriding state features passed by the host&lt;/li&gt;
&lt;li&gt;Fix null dereference when trying to load state from a missing file&lt;/li&gt;
&lt;li&gt;Fix potential null dereferences and conversion warnings&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Lilv 0.24.22</title><link href="https://drobilla.net/2023/10/22/lilv-0-24-22.html" rel="alternate"/><published>2023-10-22T20:14:00-04:00</published><updated>2023-10-22T20:14:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2023-10-22:/2023/10/22/lilv-0-24-22.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/lilv-0.24.22.tar.xz"&gt;Lilv 0.24.22&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allow LILV_API to be defined by the user&lt;/li&gt;
&lt;li&gt;Clean up code&lt;/li&gt;
&lt;li&gt;Clean up inconsistent tool command line interfaces&lt;/li&gt;
&lt;li&gt;Convert man pages to mdoc&lt;/li&gt;
&lt;li&gt;Fix crash when plugins pass NULL to the LV2_State_Retrieve_Function&lt;/li&gt;
&lt;li&gt;Fix dependencies in pkg-config file&lt;/li&gt;
&lt;li&gt;Fix potential crash when writing state files fails&lt;/li&gt;
&lt;li&gt;Order plugin classes by URI&lt;/li&gt;
&lt;li&gt;Override pkg-config dependency within meson&lt;/li&gt;
&lt;li&gt;Remove junk files from documentation install&lt;/li&gt;
&lt;li&gt;Replace duplicated dox_to_sphinx script with sphinxygen dependency&lt;/li&gt;
&lt;li&gt;Switch to external zix dependency&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Suil 0.10.20</title><link href="https://drobilla.net/2023/10/22/suil-0-10-20.html" rel="alternate"/><published>2023-10-22T20:11:00-04:00</published><updated>2023-10-22T20:11:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2023-10-22:/2023/10/22/suil-0-10-20.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/suil-0.10.20.tar.xz"&gt;Suil 0.10.20&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allow SUIL_API to be defined by the user&lt;/li&gt;
&lt;li&gt;Fix dependencies in pkg-config file&lt;/li&gt;
&lt;li&gt;Only check for Gtk Quartz support on MacOS&lt;/li&gt;
&lt;li&gt;Override pkg-config dependency within meson&lt;/li&gt;
&lt;li&gt;Remove Gtk in Qt and Qt in Gtk wrappers&lt;/li&gt;
&lt;li&gt;Remove junk files from documentation install&lt;/li&gt;
&lt;li&gt;Replace duplicated dox_to_sphinx script with sphinxygen dependency&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Sratom 0.6.16</title><link href="https://drobilla.net/2023/10/22/sratom-0-6-16.html" rel="alternate"/><published>2023-10-22T20:06:00-04:00</published><updated>2023-10-22T20:06:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2023-10-22:/2023/10/22/sratom-0-6-16.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/sratom-0.6.16.tar.xz"&gt;Sratom 0.6.16&lt;/a&gt; has been released.  Sratom is a small library for serializing LV2 atoms.  Sratom reads/writes atoms from/to RDF, allowing them to be converted between binary and text or stored in a model.  For more information, see &lt;a href="http://drobilla.net/software/sratom"&gt;http://drobilla.net/software/sratom&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clean up code&lt;/li&gt;
&lt;li&gt;Constrain relative URI references to the base URI&lt;/li&gt;
&lt;li&gt;Fix dependencies in pkg-config file&lt;/li&gt;
&lt;li&gt;Override pkg-config dependency within meson&lt;/li&gt;
&lt;li&gt;Remove junk files from documentation install&lt;/li&gt;
&lt;li&gt;Replace duplicated dox_to_sphinx script with sphinxygen dependency&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>Zix 0.4.2</title><link href="https://drobilla.net/2023/10/22/zix-0-4-2.html" rel="alternate"/><published>2023-10-22T18:56:00-04:00</published><updated>2023-10-22T18:56:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2023-10-22:/2023/10/22/zix-0-4-2.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/zix-0.4.2.tar.xz"&gt;Zix 0.4.2&lt;/a&gt; has been released.  Zix is a lightweight C library of portability wrappers and data structures.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clean up documentation build&lt;/li&gt;
&lt;li&gt;Fix documentation build in a virtualenv&lt;/li&gt;
&lt;li&gt;Improve test suite code coverage&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="C"/><category term="LAD"/><category term="Zix"/></entry><entry><title>Zix 0.4.0</title><link href="https://drobilla.net/2023/08/23/zix-0-4-0.html" rel="alternate"/><published>2023-08-23T23:25:00-04:00</published><updated>2023-08-23T23:25:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2023-08-23:/2023/08/23/zix-0-4-0.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/zix-0.4.0.tar.xz"&gt;Zix 0.4.0&lt;/a&gt; has been released.  Zix is a lightweight C library of portability wrappers and data structures.&lt;/p&gt;</content><category term="misc"/><category term="Software"/><category term="C"/><category term="LAD"/><category term="Zix"/></entry><entry><title>In Search of the Ultimate Compile-Time Configuration System</title><link href="https://drobilla.net/2023/02/13/in-search-of-the-ultimate-compile-time-configuration-system.html" rel="alternate"/><published>2023-02-13T23:38:00-05:00</published><updated>2023-02-13T23:38:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2023-02-13:/2023/02/13/in-search-of-the-ultimate-compile-time-configuration-system.html</id><content type="html">&lt;p&gt;One of the many programming side quests I embark on from time to time is finding the best way to do compile-time configuration in C and C++ code.
This is one of those characteristically C things that most projects need to do, but that has no well-established best practice.
What you can find is all over the place, and often pretty half-baked just to suit the particularities of the “official” build.
Let's try to come up with something better.&lt;/p&gt;
&lt;p&gt;Ideal requirements:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Ability to enable or disable any features from the command line by defining symbols, including the ability to override or completely disable any automatic checks implemented in the code.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Good integration with, but no hard dependency on, any build system.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The code should build with reasonable defaults when simply thrown at a compiler “as-is”.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Mistakes, such as forgetting to include the configuration header or using misspelled symbols, are caught by tooling (preferably compiler warnings).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;It's never necessary to modify the code to achieve a particular build.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Here's a skeleton of the best I've managed to come up with so far, for a made-up “mylib” project and a few POSIX functions.
It has a bit of boilerplate, but there's good reasons for everything that I'll get to.
This configuration header is written manually (not generated) and included (privately) in the source code:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#ifndef MYLIB_CONFIG_H&lt;/span&gt;
&lt;span class="cp"&gt;#define MYLIB_CONFIG_H&lt;/span&gt;

&lt;span class="cp"&gt;#if !defined(MYLIB_NO_DEFAULT_CONFIG)&lt;/span&gt;

&lt;span class="c1"&gt;// Derive default configuration from the build environment&lt;/span&gt;

&lt;span class="c1"&gt;// We need unistd.h to check _POSIX_VERSION&lt;/span&gt;
&lt;span class="cp"&gt;#  ifdef __has_include&lt;/span&gt;
&lt;span class="cp"&gt;#    if __has_include(&amp;lt;unistd.h&amp;gt;)&lt;/span&gt;
&lt;span class="cp"&gt;#&lt;/span&gt;&lt;span class="w"&gt;      &lt;/span&gt;&lt;span class="cp"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#    endif&lt;/span&gt;
&lt;span class="cp"&gt;#  elif defined(__unix__)&lt;/span&gt;
&lt;span class="cp"&gt;#&lt;/span&gt;&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="cp"&gt;include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;lt;unistd.h&amp;gt;&lt;/span&gt;
&lt;span class="cp"&gt;#  endif&lt;/span&gt;

&lt;span class="c1"&gt;// Define MYLIB_POSIX_VERSION unconditionally for convenience below&lt;/span&gt;
&lt;span class="cp"&gt;#  if defined(_POSIX_VERSION)&lt;/span&gt;
&lt;span class="cp"&gt;#    define MYLIB_POSIX_VERSION _POSIX_VERSION&lt;/span&gt;
&lt;span class="cp"&gt;#  else&lt;/span&gt;
&lt;span class="cp"&gt;#    define MYLIB_POSIX_VERSION 0&lt;/span&gt;
&lt;span class="cp"&gt;#  endif&lt;/span&gt;

&lt;span class="c1"&gt;// POSIX.1-2001: fileno()&lt;/span&gt;
&lt;span class="cp"&gt;#  if !defined(HAVE_FILENO)&lt;/span&gt;
&lt;span class="cp"&gt;#    if MYLIB_POSIX_VERSION &amp;gt;= 200112L || defined(_WIN32)&lt;/span&gt;
&lt;span class="cp"&gt;#      define HAVE_FILENO 1&lt;/span&gt;
&lt;span class="cp"&gt;#    endif&lt;/span&gt;
&lt;span class="cp"&gt;#  endif&lt;/span&gt;

&lt;span class="c1"&gt;// POSIX.1-2001: posix_fadvise()&lt;/span&gt;
&lt;span class="cp"&gt;#  if !defined(HAVE_POSIX_FADVISE)&lt;/span&gt;
&lt;span class="cp"&gt;#    if MYLIB__POSIX_VERSION &amp;gt;= 200112L &amp;amp;&amp;amp; !defined(__APPLE__)&lt;/span&gt;
&lt;span class="cp"&gt;#      define HAVE_POSIX_FADVISE 1&lt;/span&gt;
&lt;span class="cp"&gt;#    endif&lt;/span&gt;
&lt;span class="cp"&gt;#  endif&lt;/span&gt;

&lt;span class="cp"&gt;#endif &lt;/span&gt;&lt;span class="c1"&gt;// !defined(MYLIB_NO_DEFAULT_CONFIG)&lt;/span&gt;

&lt;span class="c1"&gt;// Define USE variables for use in the code&lt;/span&gt;

&lt;span class="cp"&gt;#if defined(HAVE_FILENO) &amp;amp;&amp;amp; HAVE_FILENO&lt;/span&gt;
&lt;span class="cp"&gt;#  define USE_FILENO 1&lt;/span&gt;
&lt;span class="cp"&gt;#else&lt;/span&gt;
&lt;span class="cp"&gt;#  define USE_FILENO 0&lt;/span&gt;
&lt;span class="cp"&gt;#endif&lt;/span&gt;

&lt;span class="cp"&gt;#if defined(HAVE_POSIX_FADVISE) &amp;amp;&amp;amp; HAVE_POSIX_FADVISE&lt;/span&gt;
&lt;span class="cp"&gt;#  define USE_POSIX_FADVISE 1&lt;/span&gt;
&lt;span class="cp"&gt;#else&lt;/span&gt;
&lt;span class="cp"&gt;#  define USE_POSIX_FADVISE 0&lt;/span&gt;
&lt;span class="cp"&gt;#endif&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;User interface:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;By default, features are enabled if they can be detected or assumed to be available from the build environment,
    unless &lt;code&gt;MYLIB_NO_DEFAULT_CONFIG&lt;/code&gt; is defined,
    which disables everything by default to allow complete control.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;If a symbol like &lt;code&gt;HAVE_SOMETHING&lt;/code&gt; is defined to non-zero,
    then the “something” feature is assumed to be available.
    If it is zero, then the feature is disabled.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Usage in code:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;To check for a feature,
    the configuration header must be included,
    and the symbol like &lt;code&gt;USE_SOMETHING&lt;/code&gt; (&lt;em&gt;not&lt;/em&gt; &lt;code&gt;HAVE_SOMETHING&lt;/code&gt;) used as a boolean in an &lt;code&gt;#if&lt;/code&gt; expression, like:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="cp"&gt;#include&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="cpf"&gt;&amp;quot;mylib_config.h&amp;quot;&lt;/span&gt;

&lt;span class="c1"&gt;// [snip]&lt;/span&gt;

&lt;span class="cp"&gt;#if USE_FILENO&lt;/span&gt;
&lt;span class="w"&gt;    &lt;/span&gt;&lt;span class="kt"&gt;int&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fd&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="n"&gt;fileno&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;file&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;span class="cp"&gt;#endif&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;None of the other configuration symbols described here may be used directly.
    In particular, the configuration header should be the only place in the code that touches &lt;code&gt;HAVE&lt;/code&gt; symbols.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The main “trick” here which allows for all of the different configuration “modes” is the use of two “kinds” of symbol:
&lt;code&gt;HAVE&lt;/code&gt; symbols and &lt;code&gt;USE&lt;/code&gt; symbols.
&lt;code&gt;HAVE&lt;/code&gt; symbols are exclusively the interface for the user or build system,
and &lt;code&gt;USE&lt;/code&gt; symbols are the opposite: exclusively for use in the code and never by the user or build system.
This way, use of the configuration header is mandatory for any code that needs configuration.&lt;/p&gt;
&lt;p&gt;The &lt;code&gt;USE&lt;/code&gt; symbols are defined to 0 or 1 unconditionally, and code must check them with &lt;code&gt;#if&lt;/code&gt;, not with &lt;code&gt;#ifdef&lt;/code&gt;.
This prevents mistakes, since both forgetting to include the configuration header, and misspelling a symbol, will be caught by compiler warnings.
Tools like &lt;code&gt;include-what-you-use&lt;/code&gt; can also enforce direct inclusion more strictly.&lt;/p&gt;
&lt;p&gt;From the command line, basic usage is typical: define symbols like &lt;code&gt;HAVE_SOMETHING&lt;/code&gt; to enable features.
For complete control over the configuration,
define &lt;code&gt;MYLIB_NO_DEFAULT_CONFIG&lt;/code&gt;,
in which case all features must be explicitly enabled.
This is mainly useful for build systems,
so that all features can be checked for and only those that are found used in the code.
It's also useful for avoiding issues with strange compilers or platforms that aren't supported by the checks.&lt;/p&gt;
&lt;p&gt;I think this design covers all of the above requirements,
and while the header itself can get a bit verbose,
it's relatively straightforward and,
more importantly, &lt;em&gt;usage&lt;/em&gt; of it is simple and resilient to mistakes.&lt;/p&gt;
&lt;p&gt;There is one thing here that isn't caught by tooling though:
misspelling a &lt;code&gt;HAVE&lt;/code&gt; variable will silently not work.
This is a concession to the simple case of just defining a few relevant &lt;code&gt;HAVE&lt;/code&gt; symbols on the command line,
and to keep command lines from the build system as terse as possible.
It is however possible to modify this pattern a bit to catch this potential mistake as well:
require all known &lt;code&gt;HAVE&lt;/code&gt; variables to be defined to 1 or 0,
and check &lt;em&gt;those&lt;/em&gt; with &lt;code&gt;#if&lt;/code&gt; as well in the configuration header itself.
This adds a couple of lines per check to the boilerplate, for example:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;&lt;span class="c1"&gt;// POSIX.1-2001, Windows: fileno()&lt;/span&gt;
&lt;span class="cp"&gt;#  ifndef HAVE_FILENO&lt;/span&gt;
&lt;span class="cp"&gt;#    if defined(_WIN32) || defined(_POSIX_VERSION) &amp;amp;&amp;amp; _POSIX_VERSION &amp;gt;= 200112L&lt;/span&gt;
&lt;span class="cp"&gt;#      define HAVE_FILENO 1&lt;/span&gt;
&lt;span class="cp"&gt;#    else&lt;/span&gt;
&lt;span class="cp"&gt;#      define HAVE_FILENO 0&lt;/span&gt;
&lt;span class="cp"&gt;#    endif&lt;/span&gt;
&lt;span class="cp"&gt;#  endif&lt;/span&gt;

&lt;span class="c1"&gt;// [snip]&lt;/span&gt;

&lt;span class="cp"&gt;#if HAVE_FILENO&lt;/span&gt;
&lt;span class="cp"&gt;#  define USE_FILENO 1&lt;/span&gt;
&lt;span class="cp"&gt;#else&lt;/span&gt;
&lt;span class="cp"&gt;#  define USE_FILENO 0&lt;/span&gt;
&lt;span class="cp"&gt;#endif&lt;/span&gt;
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;This way, compiler warnings will catch any mistakes in the build system (because, for example, &lt;code&gt;HAVE_FILENO&lt;/code&gt; isn't defined),
ensuring that everything is explicitly either enabled or disabled.
I'm not sure which style to use.
Potential silent errors in the build system are pretty bad,
but at the same time,
I don't want to sacrifice the ability of the code to be easily compiled “manually”.
It's probably possible to have both,
but I'm not sure how painful the boilerplate cost would be.
I did have the stricter version for a while,
but the extremely verbose compiler command lines were pretty annoying,
so I removed it.
Now, as I write this, I'm second guessing myself, but so it goes.&lt;/p&gt;
&lt;p&gt;Questions for another day, I suppose.
One of the things about programming side quests is that they usually never end.&lt;/p&gt;</content><category term="misc"/><category term="Software"/><category term="C"/><category term="LAD"/></entry><entry><title>C++ Bindings</title><link href="https://drobilla.net/2023/01/22/cpp-bindings.html" rel="alternate"/><published>2023-01-22T23:46:00-05:00</published><updated>2023-01-22T23:46:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2023-01-22:/2023/01/22/cpp-bindings.html</id><content type="html">&lt;p&gt;For some C libraries, I'd like to include “official” C++ bindings to make life
easier for people using them from C++ (which in the audio world, is most).
However, that's not something I know a good pattern for, in terms of project
organization, installation, versioning, and so on.  Figuring one out is a
trickier problem than it may seem at first.&lt;/p&gt;
&lt;p&gt;In the - in this case literally - “C and C++” world, there is a notorious lack
of consistent conventions and best practices in some areas, and this seems to
be one of them.  So, I suppose I will have to suss out the “best” (and least
weird) way myself.  The “best” way should:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Provide “official” C++ bindings which are developed, maintained, and
    shipped with the underlying C library.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Avoid having the C++ wrapper be locked to the same version as the C library
    (which is a strict semver reflection of the ABI).&lt;/p&gt;
&lt;p&gt;Rationale: It must be possible to develop the C++ bindings, including make
breaking changes, while the C library version (and therefore the ABI) stays
the same.  Otherwise, it would be nearly impossible to change them, because
that'd require changing the version... but the underlying C API version
needs to break as infrequently as possible.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Isolate the bindings (and “C++ stuff”) from the underlying C library as
    much as possible.  Ensure that builds on systems without a C++ toolchain
    work (this isn't uncommon on minimal or embedded systems which much of this
    software is appropriate for use on).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Avoid making a completely separate new project (repository, test and
    releasing infrastructure, and so on) if at all possible.  The maintenance
    burden would be far too high, and the bindings would be prone to rot.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Use a simple and predictable naming scheme that works with any “main”
    project name.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Poking around repositories and tinkering a little bit, the best practices I can
come up with (for the sort of libraries I'm thinking about anyway), is:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Develop and release bindings as a sub-project within the “main” project.&lt;/p&gt;
&lt;p&gt;This is only a “project” in the build system sense.  The bindings are
maintained in the same git repository, and released in the same archive,
as the C library.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Name the bindings sub-project by appending a &lt;code&gt;cpp&lt;/code&gt; suffix, for example,
    &lt;code&gt;mylib-cpp&lt;/code&gt;.  This scheme is... well, not &lt;em&gt;uncommon&lt;/em&gt; (for example, in the
    Debian repositories), and can easily be applied to any name, including
    libraries that already have multi-word names.&lt;/p&gt;
&lt;p&gt;Following &lt;code&gt;meson&lt;/code&gt; requirements, this means the sub-project lives at a path
like &lt;code&gt;subprojects/mylib-cpp&lt;/code&gt; in the repository.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Install a separate “package” (for example via &lt;code&gt;pkg-config&lt;/code&gt;) for the
    bindings, which depends on the one for the underlying C library.  The major
    version is appended to both, for example, &lt;code&gt;mylib-cpp-1&lt;/code&gt; might depend on
    &lt;code&gt;mylib-1&lt;/code&gt;.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Keep the C++ bindings themselves as light as possible, and header-only.
    This avoids link-time issues, making C++ API compatibility a compile-time
    issue only.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Give the bindings package a separate version number and let it increase as
    necessary.  This version is not aligned with that of the underlying C
    library in any meaningful way.  Technically, a given version of the
    bindings depends on &lt;em&gt;some&lt;/em&gt; version of the C library, but in practice, this
    is always simply the version it's shipped with.&lt;/p&gt;
&lt;p&gt;A strange consequence of this scheme is that the version of the C++
bindings can only drift ever further away, so in the future even major
versions may not correspond at all.  This is a bit weird, but is the only
way to make everything work and be properly versioned.  Effectively, the
version of the bindings is just an implementation detail, something
developers deal with in configuration scripts.  From the perspective of
packagers or users, there is just one version of the library, the version
of the underlying C library - the C++ bindings just may break sometimes,
even within a major version of the project as a whole.&lt;/p&gt;
&lt;p&gt;I can't think of any concrete reason why this could be a problem: the urge
to have shiny “4.0.0” type version bumps across everything at the same time
smells like... marketing, frankly, not engineering.  It does make parallel
installation of different major versions more difficult, though.  Packagers
can split up the installation and make separate packages if they really
want to.  “Upstream” (me) officially doesn't care about parallel
installation of different major versions of the C++ bindings.&lt;/p&gt;
&lt;p&gt;All that said, ideally they happen to stay relatively aligned anyway.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Make sure there is a simple and obvious option to disable C++ entirely,
    leaving a C library package with the broadest compatibility possible.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The short, vibes-based description of all that is something like: there is a
stable and strictly versioned C library with every effort put into long-term
source and binary compatibility, as always... and then there's a C++ bindings
sub-project that tags along with it but is otherwise independent.  The bindings
are more volatile, but it's C++, so they're going to be volatile no matter what
you do anyway.  The bindings project is universally named by tacking a &lt;code&gt;-cpp&lt;/code&gt;
or &lt;code&gt;_cpp&lt;/code&gt; on the end as appropriate in every context: include directories,
package names, and so on.&lt;/p&gt;
&lt;p&gt;So, an installation might look something like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;include/dostuff-1/dostuff.h
include/dostuff-cpp-4/dostuff.hpp
lib/libdostuff-1.so
lib/libdostuff-1.so.1
lib/libdostuff-1.so.1.2.4
lib/pkgconfig/dostuff-1.pc
lib/pkgconfig/dostuff-cpp-4.pc
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;In the source code, the bindings and any supporting C++ code is entirely
contained within the subproject, except for a minimal skeleton to handle
compile time options and so on.  This can be more work than a single
heterogeneous project in some ways, less work in others, but overall I think it
has more maintenance benefits.  Importantly, it keeps any new issues or
volatility as far away from the C library as possible, making it easy to see if
a change could possibly break the ABI or the C library at all, for example.&lt;/p&gt;
&lt;p&gt;This scheme may be extended to other languages if that's appropriate.  The
naming scheme for Python is like &lt;code&gt;python-dostuff&lt;/code&gt;.  It probably makes more
sense to maintain Cython wrappers as separate projects maintained in the Python
way (&lt;em&gt;sigh...&lt;/em&gt;), but the whole point of a naming scheme is to have space for
things in case you need them.  In reality, language bindings are usually done
independently by other people in separate projects (Rust folks will use Cargo
in a separate repository, and so on).&lt;/p&gt;
&lt;p&gt;All of this is, obviously, a massively over-thought bikeshed, but adding
multiple programming languages and multiple versioning and compatibility
schemes/philosophies to a project is a bit tricky.  I can't just copy from an
existing best-practice pattern I've been honing for years like I can with
straight C libraries.  This approach seems like it shouldn't cause too much
trouble, though.&lt;/p&gt;
&lt;p&gt;That said, I'm just making this up as I go along and have no experience
maintaining anything quite like this (only more or less homogeneous C or C++
libraries), so feedback is, as always, welcome.  I may revise this post if
anything turns out to be a mistake, so it can ultimately serve as a reference
for the next person trying to figure out how to do “C family” source code
releases right.&lt;/p&gt;</content><category term="misc"/><category term="Software"/><category term="C"/><category term="Cpp"/><category term="LAD"/></entry><entry><title>Down to the Last Man, Doc!</title><link href="https://drobilla.net/2022/11/30/down-to-the-last-man-doc.html" rel="alternate"/><published>2022-11-30T13:53:00-05:00</published><updated>2022-11-30T13:53:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-11-30:/2022/11/30/down-to-the-last-man-doc.html</id><content type="html">&lt;p&gt;While working through some remaining things in the build/documentation/packaging/infrastructure cleanup phase I've been going through lately,
I noticed that some of the man pages hosted at this domain have become stale
(there was a helpful ticket about one of them, but more or less all of them were out of date).&lt;/p&gt;
&lt;p&gt;I'm still not entirely sure what to do about the general duplication between README files and the neglected home pages I still (barely) maintain here,
but this part struck me as obviously needing to be automated.&lt;/p&gt;
&lt;p&gt;Of course, now that my attention was drawn to them,
I noticed that many of the man pages themselves were in a terrible state.
In recent years I've become more enthusiastic about man pages,
particularly after moving to &lt;a href="https://mandoc.bsd.lv/"&gt;mandoc&lt;/a&gt;.
As a language, &lt;code&gt;mdoc&lt;/code&gt; is dramatically better than the “traditional” man macros (the ones most often used on Linux),
and includes meaningful semantic markup for more or less everything you'll need.
It's still &lt;a href="https://gitlab.com/lv2/lilv/-/blob/main/doc/lv2info.1"&gt;line noise&lt;/a&gt; to write,
but you actually get something for it.
Since it's semantic markup,
it feels like a better investment to me:
superficially ugly, perhaps, but with high fidelity as a portable source material.
Converting &lt;em&gt;from&lt;/em&gt; mandoc to just about anything, I imagine,
could be done automatically easily enough,
if it wasn't already supported by the tool&lt;sup id="fnref:1"&gt;&lt;a class="footnote-ref" href="#fn:1"&gt;1&lt;/a&gt;&lt;/sup&gt;.&lt;/p&gt;
&lt;p&gt;In practice,
I find that the language encourages/enables writing more consistent pages with better formatting,
and &lt;code&gt;mandoc&lt;/code&gt;, unlike &lt;code&gt;groff&lt;/code&gt;,
emits clean and simple HTML pages that can be easily styled with CSS.
It's relatively pleasant to use in general,
and emits sensible error messages that point directly to the problem when you screw something up.
I've also come to appreciate the BSD style of man page more:
the summary is actually a summary,
it's less YELLEY,
and there is a standard for sections and their order.
I may spend most of my time in a GNU/Linux universe,
but BSD got man pages right.
That's not terribly surprising:
BSD culture in general actually likes and cares about man pages.
GNU treated them as an unfortunate legacy to prop up a failed successor (info).
Of course the BSD tooling around man pages is much better.
I tend towards BSD style for command line interfaces anyway,
but you can document GNU-style long options in &lt;code&gt;mdoc&lt;/code&gt; as well.&lt;/p&gt;
&lt;p&gt;So!  If I'm going to be putting energy into man pages,
I might as well convert them to &lt;code&gt;mdoc&lt;/code&gt;.
I think good tooling is very important,
and nice command-line tools with clear and articulate man pages are a part of that.
Unfortunately, neither the LV2 tools themselves nor their documentation have frankly ever been of very high quality.
Addressing this is one of the next themes of upcoming work,
but for now,
simply converting the existing content (with a few touch-ups along the way) is an easy step forward.
It meshes nicely with the “bring all projects in line with a consistent set of ‘modern’ quality standards and automate everything” arc I've been on lately anyway.&lt;/p&gt;
&lt;p&gt;The process of going through all of these has made me realize that I should prioritize the tool work,
because the state of some of these tools is frankly embarrassing,
but, uh,
pay no attention to the &lt;code&gt;man&lt;/code&gt; behind the curtain!
It's a formats and infrastructure kind of day!&lt;/p&gt;
&lt;p&gt;Having manually converted all the pages and checked them in the terminal,
I needed a place to have them automatically updated, converted to HTML, and uploaded.
The (not-really-existing) &lt;a href="https://gitlab.com/lv2/lv2kit"&gt;lv2kit&lt;/a&gt; project is the (not-really) parent of LV2 itself and all the “official” libraries,
so I put it in CI there for the time being.
I don't know what the best organization is for man pages under the LV2 umbrella in the grand scheme of things,
but for now,
this gets things automatically updated and online:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://lv2.gitlab.io/lv2kit/man/lv2apply.html"&gt;&lt;code&gt;lv2apply&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lv2.gitlab.io/lv2kit/man/lv2bench.html"&gt;&lt;code&gt;lv2bench&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lv2.gitlab.io/lv2kit/man/lv2info.html"&gt;&lt;code&gt;lv2info&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lv2.gitlab.io/lv2kit/man/lv2ls.html"&gt;&lt;code&gt;lv2ls&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lv2.gitlab.io/lv2kit/man/serdi.html"&gt;&lt;code&gt;serdi&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lv2.gitlab.io/lv2kit/man/sord_validate.html"&gt;&lt;code&gt;sord_validate&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://lv2.gitlab.io/lv2kit/man/sordi.html"&gt;&lt;code&gt;sordi&lt;/code&gt;&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;It's possible to build the documentation into a broader HTML page to integrate with toolbars and the like,
but for now these are just complete pages straight out of &lt;code&gt;mandoc&lt;/code&gt;.
I did however write a simple stylesheet to adopt the same colours, fonts, spacing, typography-inspired minimalism, and infamous green links that I use everywhere,
so things at least look reasonably coherent.
I think it looks Good Enough&amp;#8482;,
anyway,
but more relevantly,
if you poke around in the document structure you'll see that the output is, for the most part, sensible semantic markup as well:
lists are lists, sections are sections, different “sorts” of things are given classes, tables aren't abused, and so on.
Everything here, from input to output, is reasonably clear and feels like it has obviously had some care put into it.
The output looks like something a reasonable human might write themselves (if you run it through a formatter, anyway).
I certainly can't say any of that about the equivalent &lt;code&gt;groff&lt;/code&gt;-based monstrosity.
In short, &lt;em&gt;mandoc&lt;/em&gt; is good and you should use it.&lt;/p&gt;
&lt;p&gt;As for these pages,
the future of lv2kit as an “actual” released project is still unclear,
but it is regularly updated (since the libraries rely on it for CI),
so the man pages should never be stale again.
I certainly wouldn't call these &lt;em&gt;good&lt;/em&gt; yet,
but &lt;em&gt;not rotten&lt;/em&gt; is a start!&lt;/p&gt;
&lt;div class="footnote"&gt;
&lt;hr&gt;
&lt;ol&gt;
&lt;li id="fn:1"&gt;
&lt;p&gt;&lt;code&gt;mandoc&lt;/code&gt; currently supports emitting &lt;code&gt;ascii&lt;/code&gt;, &lt;code&gt;html&lt;/code&gt;, &lt;code&gt;man&lt;/code&gt;, &lt;code&gt;markdown&lt;/code&gt;, &lt;code&gt;pdf&lt;/code&gt;, &lt;code&gt;ps&lt;/code&gt;, &lt;code&gt;tree&lt;/code&gt;, and &lt;code&gt;utf8&lt;/code&gt;.&amp;#160;&lt;a class="footnote-backref" href="#fnref:1" title="Jump back to footnote 1 in the text"&gt;&amp;#8617;&lt;/a&gt;&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;/div&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/></entry><entry><title>On the LV2 Stack, Dependencies, and Incrementalism</title><link href="https://drobilla.net/2022/10/15/on-the-lv2-stack-dependencies-and-incrementalism.html" rel="alternate"/><published>2022-10-15T19:07:00-04:00</published><updated>2022-10-15T19:07:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-10-15:/2022/10/15/on-the-lv2-stack-dependencies-and-incrementalism.html</id><content type="html">&lt;p&gt;For quite a while now, 
I've been working on new major versions of the LV2 host stack (&lt;a href="http://gitlab.com/drobilla/serd"&gt;serd&lt;/a&gt;, &lt;a href="http://gitlab.com/drobilla/sord"&gt;sord&lt;/a&gt;, &lt;a href="http://gitlab.com/lv2/sratom"&gt;sratom&lt;/a&gt;, &lt;a href="http://gitlab.com/lv2/suil"&gt;suil&lt;/a&gt;, and &lt;a href="http://gitlab.com/lv2/lilv"&gt;lilv&lt;/a&gt;) while maintaining the current stable versions.
Mainly this is a task of trying to push as many changes back as I can,
without actually breaking any APIs.
Aside from the usual bug fixes and code improvements,
this includes a lot of build system, tooling, and general quality control improvements.
This keeps the divergence low,
so it will be easier to go back and do maintenance on the old versions where necessary.&lt;/p&gt;
&lt;p&gt;At this point, this process is almost done: everything uses meson now,
has a consistent QC regime (high-coverage testing, multi-platform CI, strict compiler warnings, machine formatting, clean clang-tidy configurations, and so on),
most long-standing issues are fixed,
and I'm finally starting to run out of changes that I can do without finally breaking the APIs and releasing new major versions.&lt;/p&gt;
&lt;p&gt;It recently occurred to me, though, that there's one more incremental thing I can do here before “ripping the band-aid off”, so to speak.
In typical low-level C hacker fashion,
I have some things that I just copy around piecemeal from project to project as necessary.
One of those is &lt;a href="http://gitlab.com/drobilla/zix"&gt;zix&lt;/a&gt;,
a simple library of basic data structures and portability wrappers.
This has existed for over a decade,
but I have never released it as a “proper” library.
More dependencies, more problems, but copy-paste code reuse certainly isn't without its own problems.
In this case, I have three projects that use it: sord, lilv, and &lt;a href="http://gitlab.com/drobilla/jalv"&gt;jalv&lt;/a&gt;
(and some other developers have discovered this and taken bits for their own purposes as well).
This has been troublesome from time to time when bugs need fixing,
and depending on how pedantic you are,
might technically be considered a violation of some distributions' policies (notably Debian's).&lt;/p&gt;
&lt;p&gt;Meanwhile, the lack of a common lowest-level dependency for this kind of very boring and generic stuff
(something like the role that glib plays in that ecosystem) has proven increasingly problematic.
There is some sketchy code around that exists solely to work around this “missing” dependency,
and still some questionable use of things to skirt around missing facilities
(for example, jalv has no mutexes).
With the new versions I have in the pipeline,
this problem becomes more acute for several reasons,
so I've decided to release zix and depend on it as a proper released and versioned library,
like all the others.&lt;/p&gt;
&lt;p&gt;This is something that can be done before the new versions though,
and,
like all of the above tooling/etc improvements,
I think it's best to do as much as possible on the current versions before replacing them,
because that process will be painful enough as it is.
My thinking originally was to not add any more libraries until I can take advantage of the solid “subproject” abilities of meson and wrap everything up into a single “lv2kit” to decrease the maintenance and packaging burden,
but now I'm realizing that this isn't very realistic.
For one, it's weird, and weird is bad.
For another, it wouldn't really reduce packaging overhead,
since distributions would surely want to package the individual libraries separately anyway.
The lv2kit idea is still a goal, but pragmatically,
I think it's best to just continue on in the good old “shotgun blast of little libraries” way and deal with that later.&lt;/p&gt;
&lt;p&gt;Concretely, that will look like this:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;serd &amp;lt;--\--- sratom
         --- sord --- lilv --- jalv
zix  &amp;lt;--/------------/--------/
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;That is, zix will become a thing, and sord, lilv, and jalv will gain it as a dependency.
This will let any issues with packaging or subprojects or whatever get ironed out,
without changing any of the APIs that LV2 hosts use directly whatsoever.&lt;/p&gt;
&lt;p&gt;... and that, I think, is the last non-trivial thing I can do without rocking the boat,
before the fun part where I finally get to change whatever I want in these APIs I hastily banged out over a decade ago now,
and never intended to live this long in the first place.
The dependency tree may get a bit more complicated,
but a whole bunch of other things are going to get wildly simplified in exchange,
which seems like a pretty good deal to me.&lt;/p&gt;
&lt;p&gt;[Edited on 2025-02-16 to update broken links]&lt;/p&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/></entry><entry><title>I Was Told The Crowd Would Have Funding</title><link href="https://drobilla.net/2022/10/15/i-was-told-the-crowd-would-have-funding.html" rel="alternate"/><published>2022-10-15T17:52:00-04:00</published><updated>2022-10-15T17:52:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-10-15:/2022/10/15/i-was-told-the-crowd-would-have-funding.html</id><content type="html">&lt;p&gt;I am, like many an obsessive nerd before me,
terrible at self-promotion and living a healthy and sustainable life in general.
However, as I sit here sick, burnt-out, and slowly going broke while I desperately dump what little energy I have into boring software that mostly benefits other people,
it occurs to me that it might be smart to set up the usual channels for people to support this work,
and mention them here (despite how embarrassing it is to do so).&lt;/p&gt;
&lt;p&gt;It's pretty well-known these days how brutal and thankless it can be to maintain Open Source infrastructure.
While I enjoy what I do around here in a way,
truth be told, I'm not sure I can do it much longer.
In an ideal sense,
my grand plan (as described in some earlier posts) is to get the foundation solid and increase the LV2 “bus factor” so I can return to building user-facing things and tackle some new problems which tends to be more rewarding.
Realistically, though, I may just be cleaning things up and minimizing the maintenance overhead so that I can hand them off or simply abandon them without feeling &lt;em&gt;too&lt;/em&gt; bad about it.
Time will tell, but if any of this helped at all with surviving the ever-skyrocketing cost of living... well, it certainly wouldn't hurt my motivation.&lt;/p&gt;
&lt;p&gt;So!  In addition to the old direct donation and subscription links on my &lt;a href="/pages/support.html"&gt;support&lt;/a&gt; page,
I've set up &lt;a href="https://github.com/sponsors/drobilla"&gt;Github Sponsor&lt;/a&gt; and &lt;a href="https://patreon.com/drobilla"&gt;Patreon&lt;/a&gt; accounts.
If you're reading this, presumably you know about the various projects I author, maintain, or contribute to.
If you use or benefit from any of that and can spare a few bucks,
I'd appreciate any support.
Every little bit really does help.&lt;/p&gt;
&lt;p&gt;[Edited on 2025-02-16 to update broken links]&lt;/p&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/></entry><entry><title>Patchage 1.0.10</title><link href="https://drobilla.net/2022/09/10/patchage-1-0-10.html" rel="alternate"/><published>2022-09-10T00:59:00-04:00</published><updated>2022-09-10T00:59:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-09-10:/2022/09/10/patchage-1-0-10.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/patchage-1.0.10.tar.xz"&gt;Patchage 1.0.10&lt;/a&gt; has been released.  Patchage is a modular patch bay for Jack and ALSA based audio/MIDI systems.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add German translation&lt;/li&gt;
&lt;li&gt;Add Korean translation from Junghee Lee&lt;/li&gt;
&lt;li&gt;Add i18n support&lt;/li&gt;
&lt;li&gt;Replace boost with standard C++17 facilities&lt;/li&gt;
&lt;li&gt;Upgrade to fmt 9.0.0&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="Patchage"/></entry><entry><title>Jalv 1.6.8</title><link href="https://drobilla.net/2022/09/10/jalv-1-6-8.html" rel="alternate"/><published>2022-09-10T00:43:00-04:00</published><updated>2022-09-10T00:43:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-09-10:/2022/09/10/jalv-1-6-8.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/jalv-1.6.8.tar.xz"&gt;Jalv 1.6.8&lt;/a&gt; has been released.  Jalv (JAck LV2) is a simple host for LV2 plugins.  It runs a plugin, and exposes the plugin ports to the system, essentially making the plugin an application.  For more information, see &lt;a href="http://drobilla.net/software/jalv"&gt;http://drobilla.net/software/jalv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add Gtk plugin selector UI and desktop file&lt;/li&gt;
&lt;li&gt;Add missing option in console help output&lt;/li&gt;
&lt;li&gt;Add version option to console executable&lt;/li&gt;
&lt;li&gt;Build Qt interface as C++14&lt;/li&gt;
&lt;li&gt;Change no-menu short option to m to avoid clash with jack-name&lt;/li&gt;
&lt;li&gt;Clean up and modernize code&lt;/li&gt;
&lt;li&gt;Fix "preset" console command when "presets" hasn't been called&lt;/li&gt;
&lt;li&gt;Fix MSVC build&lt;/li&gt;
&lt;li&gt;Fix atom buffer alignment&lt;/li&gt;
&lt;li&gt;Fix crash when running jalv without arguments&lt;/li&gt;
&lt;li&gt;Fix man page headers&lt;/li&gt;
&lt;li&gt;Fix memory leaks&lt;/li&gt;
&lt;li&gt;Fix outdated man pages&lt;/li&gt;
&lt;li&gt;Fix spurious transport messages&lt;/li&gt;
&lt;li&gt;Fix thread-safety of plugin/UI communication rings&lt;/li&gt;
&lt;li&gt;Flush stdout after printing control values in console interface&lt;/li&gt;
&lt;li&gt;Print status information consistently to stdout&lt;/li&gt;
&lt;li&gt;Propagate worker errors to the scheduler when possible&lt;/li&gt;
&lt;li&gt;Remove Gtkmm interface&lt;/li&gt;
&lt;li&gt;Remove Qt4 support&lt;/li&gt;
&lt;li&gt;Support both rdfs:label and lv2:name for port group labels&lt;/li&gt;
&lt;li&gt;Switch to meson build system&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Jalv"/></entry><entry><title>Sratom 0.6.14</title><link href="https://drobilla.net/2022/09/09/sratom-0-6-14.html" rel="alternate"/><published>2022-09-09T17:29:00-04:00</published><updated>2022-09-09T17:29:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-09-09:/2022/09/09/sratom-0-6-14.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/sratom-0.6.14.tar.xz"&gt;Sratom 0.6.14&lt;/a&gt; has been released.  Sratom is a small library for serializing LV2 atoms.  Sratom reads/writes atoms from/to RDF, allowing them to be converted between binary and text or stored in a model.  For more information, see &lt;a href="http://drobilla.net/software/sratom"&gt;http://drobilla.net/software/sratom&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add project metadata&lt;/li&gt;
&lt;li&gt;Adopt REUSE machine-readable licensing standard&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>Suil 0.10.18</title><link href="https://drobilla.net/2022/09/09/suil-0-10-18.html" rel="alternate"/><published>2022-09-09T17:29:00-04:00</published><updated>2022-09-09T17:29:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-09-09:/2022/09/09/suil-0-10-18.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/suil-0.10.18.tar.xz"&gt;Suil 0.10.18&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add project metadata&lt;/li&gt;
&lt;li&gt;Adopt REUSE machine-readable licensing standard&lt;/li&gt;
&lt;li&gt;Fix MacOS build when Gtk3 and Qt5 are present without X11&lt;/li&gt;
&lt;li&gt;Fix opening wrapped UIs multiple times in Gtk&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Lilv 0.24.20</title><link href="https://drobilla.net/2022/09/09/lilv-0-24-20.html" rel="alternate"/><published>2022-09-09T17:28:00-04:00</published><updated>2022-09-09T17:28:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-09-09:/2022/09/09/lilv-0-24-20.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/lilv-0.24.20.tar.xz"&gt;Lilv 0.24.20&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Adopt REUSE machine-readable licensing standard&lt;/li&gt;
&lt;li&gt;Update project metadata&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Meson Features and Packaging</title><link href="https://drobilla.net/2022/08/16/on-meson-features.html" rel="alternate"/><published>2022-08-16T15:42:00-04:00</published><updated>2022-08-16T15:42:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-08-16:/2022/08/16/on-meson-features.html</id><content type="html">&lt;p&gt;Recently, I have been porting all of the software I maintain to &lt;a href="//mesonbuild.com"&gt;meson&lt;/a&gt;.
For the most part, this has been a nice improvement.
Meson strives to be a generally sensible and coherent build system that addresses the needs of both upstream developers and packagers,
and it shows.  It isn't perfect (like all software), but it's a pretty big improvement over what came before in many ways.&lt;/p&gt;
&lt;p&gt;One disagreement has come up, however, and I think it - at best - betrays a misunderstanding of meson feature options, and - at worst - threatens to effectively destroy their utility entirely for no good reason.
This disagreement originates from &lt;code&gt;arch-meson&lt;/code&gt;, which adds &lt;code&gt;--auto-features=enabled&lt;/code&gt; by default.
This isn't technically &lt;em&gt;wrong&lt;/em&gt;, but it's problematic at scale.
To explain why, I first need to explain how meson feature options work.&lt;/p&gt;
&lt;p&gt;Meson feature options are a better solution to the &lt;code&gt;--enable-this&lt;/code&gt; and &lt;code&gt;--disable-that&lt;/code&gt; style options of autoconf and similar.  They make all the possible states of a feature clear and explicit.  Those states are:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;disabled&lt;/code&gt;, which unconditionally disables the feature.&lt;/li&gt;
&lt;li&gt;&lt;code&gt;auto&lt;/code&gt;, which enables the feature if possible (typically if dependencies are found).&lt;/li&gt;
&lt;li&gt;&lt;code&gt;enabled&lt;/code&gt;, which unconditionally enables the feature.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;The default value for an option can be any of the three, and is given by the developer in the option definition.
This is a better system because there are three states with clear meanings.
They allow the builder to:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Ensure that a feature is definitely not included.&lt;/li&gt;
&lt;li&gt;Ask that a feature be included if possible.&lt;/li&gt;
&lt;li&gt;Ensure that a feature is definitely included (failing to configure otherwise).&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Each of these states (and desires) are distinct and, importantly, their definitions are not conditional.
There is no “unless” in the definition of &lt;code&gt;disabled&lt;/code&gt; or &lt;code&gt;enabled&lt;/code&gt;,
and adding one would destroy their utility.
It's not “enabled unless someone &lt;em&gt;feels&lt;/em&gt; like it's fine to disable”, it's just “enabled”.&lt;/p&gt;
&lt;p&gt;Concretely, for &lt;code&gt;enabled&lt;/code&gt; in particular, this means that, as a builder of whatever meson project, you can:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;meson setup build -Dsomething=enabled
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Then, you know that if configuration succeeded, the &lt;code&gt;something&lt;/code&gt; feature is enabled.
This is important.
It is also &lt;em&gt;the only way&lt;/em&gt; to reliably/mechanically ensure that a build contains a feature.
“Destroying” it (as something meson users can generally expect) would therefore mean that there &lt;em&gt;there is no way&lt;/em&gt; to ensure that a build contains a feature in general.
Surely everyone - especially packagers - can agree that's bad.&lt;/p&gt;
&lt;p&gt;Hopefully that's a decent enough explanation of why meson feature options are a good, coherent, and reliable system.&lt;/p&gt;
&lt;p&gt;What's the problem then?
Well, there is that convenience option, &lt;code&gt;--auto-features=enabled&lt;/code&gt;,
which enables all features for convenience.
This allows the builder to override the developer-chosen defaults,
and force the build script to be explicit about all non-enabled features.
This is, again, not technically wrong, and is indeed convenient at times.&lt;/p&gt;
&lt;p&gt;The problem is more of a social one.
Because Arch chose to make this the default (unlike most other distributions, as far as I can tell),
people have apparently adopted the mentality that &lt;code&gt;--auto-features=enabled&lt;/code&gt; not building is an upstream bug.
It isn't.
The shorthand &lt;code&gt;--auto-features&lt;/code&gt; is just that - a shorthand for enabling all features.
It is equivalent to explicitly enabling every feature independently,
so doing so is quite literally &lt;em&gt;asking&lt;/em&gt; for the build to fail if &lt;code&gt;any&lt;/code&gt; feature is not present.&lt;/p&gt;
&lt;p&gt;Where this gets weird is when features seem unlikely,
or even impossible,
to build on a given system.
The bug filed against my project was about Cocoa on Linux.
I get it, Cocoa is &lt;em&gt;mostly&lt;/em&gt; a MacOS thing, and is &lt;em&gt;almost certainly&lt;/em&gt; unavailable elsewhere,
but my argument is that this doesn't matter at all.
Even if it were literally impossible for Cocoa to exist on top of, say, FreeBSD somewhere (which it isn't, and cross-compiling is a thing anyway),
it still wouldn't matter.
A similar case can be made for optional dependencies that are not publicly available at all (something I have done in the past).
Feature options working as expected in general is much more important than any of this subjective case-specific thinking.&lt;/p&gt;
&lt;p&gt;“This doesn't work for me, so the package should not build when this feature is enabled” is not a good argument,
regardless of &lt;em&gt;why&lt;/em&gt; it doesn't work.
It doesn't matter if you imagine a feature “can't” be built on some system
(anyone who has been in this game long enough should be able to see where that slippery slope leads...).
The power of feature options depend on the states meaning just what they say,
and making &lt;code&gt;enabled&lt;/code&gt; &lt;em&gt;sometimes&lt;/em&gt; effectively equivalent to &lt;code&gt;auto&lt;/code&gt; destroys that power.
There's not really any point in using features at that point,
you might as well just use a boolean flag.&lt;/p&gt;
&lt;p&gt;Put another way, the proposed “fix” here would make it so that:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre&gt;&lt;span&gt;&lt;/span&gt;&lt;code&gt;meson setup build -Dsomething=enabled
&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;

&lt;p&gt;Can successfully configure, but &lt;em&gt;without&lt;/em&gt; the &lt;code&gt;something&lt;/code&gt; feature being included.
Et voila, we've made the feature states effectively meaningless.
&lt;em&gt;That&lt;/em&gt; would be a bug, and letting this mentality take over would resign us back to manually wading through logs to see if what we asked for &lt;em&gt;actually&lt;/em&gt; happened.&lt;/p&gt;
&lt;p&gt;It's also worth noting that feature options are deeply integrated all over the place in meson,
for example, you can pass them to as “required” parameters and the right thing will happen.
Diluting the meaning of &lt;code&gt;enabled&lt;/code&gt; would cause deeper problems than the builder-visible ones explained here.
What does it even mean for a feature to be enabled, except not &lt;em&gt;actually&lt;/em&gt; enabled,
when that feature status is being used to dictate that another dependency is required?
Everything falls apart.
The feature option system, when used as intended, is designed well,
but messing around with the meaning of &lt;code&gt;enabled&lt;/code&gt; like this ruins it.
I don't think it's hyperbole to say it “destroys” the whole thing:
it turns a sensible and coherent system into some confused boolean,
which is both objectively less powerful, and, well... confusing.&lt;/p&gt;
&lt;p&gt;This may seem trivial when you're zoomed in to a single project or handful of options,
but globally it is a much bigger deal than it might seem at first.
Even in my relatively tidy third-party source directory,
there's nearly a &lt;em&gt;thousand&lt;/em&gt; meson options.
I can't imagine how many there are globally.
The basic way that features work can't depend on the builder understanding details about every single option,
that would be a complete disaster.
It is crucial that &lt;code&gt;disabled&lt;/code&gt; and &lt;code&gt;enabled&lt;/code&gt; mean exactly what they say, always.&lt;/p&gt;
&lt;p&gt;I have never seen this problem come up from a user configuring the project themselves.
Presumably, people realize that explicitly requesting a potentially failed build,
then complaining that it did what they ask,
is... rather silly.
This gets obscured when a tool (&lt;code&gt;arch-meson&lt;/code&gt;) does it automatically,
but remains just as silly.
It makes no difference from the perspective of a meson package or its maintainer:
by enabling all features, the builder has &lt;em&gt;explicitly requested&lt;/em&gt; ignoring the defaults and failing to build if &lt;em&gt;any feature&lt;/em&gt; was not present.&lt;/p&gt;
&lt;p&gt;Yet, here we are, with upstream developers getting “bug” reports &lt;em&gt;for feature options working exactly how they are supposed to work&lt;/em&gt;.
This, unfortunately, means that Arch is putting toxic pressure on the meson ecosystem,
pushing upstream developers to make things objectively worse.&lt;/p&gt;
&lt;p&gt;I don't know what the solution to that is, and I'm not an Arch developer (though I'm typing this on an Arch-derived distribution and have nothing in particular against it).
Breaking all the existing packages that use &lt;code&gt;arch-meson&lt;/code&gt; is probably not going to happen,
but perhaps improving the documentation would be good enough.&lt;/p&gt;
&lt;p&gt;All I know is that &lt;code&gt;--auto-features=enabled&lt;/code&gt; not building is &lt;em&gt;very definitely&lt;/em&gt; not a bug.
Quite the opposite, that is &lt;em&gt;literally the whole point&lt;/em&gt; of feature options.
If there's something out there that's leading people to thinking that enabled features not building is a bug,
then it is misleading people in a bad way,
and needs to be fixed.&lt;/p&gt;</content><category term="misc"/><category term="Hacking"/><category term="Software"/><category term="LAD"/></entry><entry><title>MDA.lv2 1.2.10</title><link href="https://drobilla.net/2022/08/13/mda-lv2-1-2-10.html" rel="alternate"/><published>2022-08-13T23:50:00-04:00</published><updated>2022-08-13T23:50:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-08-13:/2022/08/13/mda-lv2-1-2-10.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/mda-lv2-1.2.10.tar.xz"&gt;MDA.lv2 1.2.10&lt;/a&gt; has been released.  This is a port of the MDA VST plugins to LV2.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix preset installation&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="MDA.lv2"/></entry><entry><title>Raul 2.0.0</title><link href="https://drobilla.net/2022/08/13/raul-2-0-0.html" rel="alternate"/><published>2022-08-13T22:40:00-04:00</published><updated>2022-08-13T22:40:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-08-13:/2022/08/13/raul-2-0-0.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/raul-2.0.0.tar.xz"&gt;Raul 2.0.0&lt;/a&gt; has been released.  Raul (Realtime Audio Utility Library) is a header-only C++ utility library for real-time audio applications.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add INSTALL.md file&lt;/li&gt;
&lt;li&gt;Add managed_ptr for automatic real-time safe garbage collection&lt;/li&gt;
&lt;li&gt;Fix semaphore with initial count on Darwin&lt;/li&gt;
&lt;li&gt;Implement Semaphore for Windows&lt;/li&gt;
&lt;li&gt;Improve RingBuffer&lt;/li&gt;
&lt;li&gt;Improve test suite&lt;/li&gt;
&lt;li&gt;Make namespace name lowercase&lt;/li&gt;
&lt;li&gt;Remove OSC and RDF library dependent code&lt;/li&gt;
&lt;li&gt;Remove TimeSlice and TimeStamp&lt;/li&gt;
&lt;li&gt;Remove URI class&lt;/li&gt;
&lt;li&gt;Remove boost dependency&lt;/li&gt;
&lt;li&gt;Remove features now provided by C++11&lt;/li&gt;
&lt;li&gt;Remove glib dependency&lt;/li&gt;
&lt;li&gt;Remove remaining library code, now header only&lt;/li&gt;
&lt;li&gt;Remove several questionable classes&lt;/li&gt;
&lt;li&gt;Switch to meson build system&lt;/li&gt;
&lt;li&gt;Update license to GPL3+&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="Raul"/></entry><entry><title>Patchage 1.0.8</title><link href="https://drobilla.net/2022/08/13/patchage-1-0-8.html" rel="alternate"/><published>2022-08-13T22:15:00-04:00</published><updated>2022-08-13T22:15:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-08-13:/2022/08/13/patchage-1-0-8.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/patchage-1.0.8.tar.xz"&gt;Patchage 1.0.8&lt;/a&gt; has been released.  Patchage is a modular patch bay for Jack and ALSA based audio/MIDI systems.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Switch to C++17 and modernize code&lt;/li&gt;
&lt;li&gt;Switch to meson build system&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="Patchage"/></entry><entry><title>Ganv 1.8.2</title><link href="https://drobilla.net/2022/08/13/ganv-1-8-2.html" rel="alternate"/><published>2022-08-13T22:12:00-04:00</published><updated>2022-08-13T22:12:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-08-13:/2022/08/13/ganv-1-8-2.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/ganv-1.8.2.tar.xz"&gt;Ganv 1.8.2&lt;/a&gt; has been released.  Ganv is an interactive Gtk canvas widget for graph-based interfaces (patchers, modular synthesizers, finite state automata, interactive graphs, etc). For more information, see &lt;a href="http://drobilla.net/software/ganv"&gt;http://drobilla.net/software/ganv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Switch to meson build system&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="Ganv"/></entry><entry><title>BLOP.lv2 1.0.4</title><link href="https://drobilla.net/2022/08/13/blop-lv2-1-0-4.html" rel="alternate"/><published>2022-08-13T20:56:00-04:00</published><updated>2022-08-13T20:56:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-08-13:/2022/08/13/blop-lv2-1-0-4.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/blop-lv2-1.0.4.tar.xz"&gt;BLOP.lv2 1.0.4&lt;/a&gt; has been released.  BLOP.lv2 is a port of the BLOP LADSPA plugins by Mike Rawes to LV2.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add default values for controls&lt;/li&gt;
&lt;li&gt;Add missing port metadata&lt;/li&gt;
&lt;li&gt;Add option accessors&lt;/li&gt;
&lt;li&gt;Fix pulse and sync_pulse option interfaces&lt;/li&gt;
&lt;li&gt;Fix quantiser mode scale points&lt;/li&gt;
&lt;li&gt;Remove invalid port type&lt;/li&gt;
&lt;li&gt;Switch to meson build system&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Blop.lv2"/></entry><entry><title>MDA.lv2 1.2.8</title><link href="https://drobilla.net/2022/08/13/mda-lv2-1-2-8.html" rel="alternate"/><published>2022-08-13T20:51:00-04:00</published><updated>2022-08-13T20:51:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-08-13:/2022/08/13/mda-lv2-1-2-8.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/mda-lv2-1.2.8.tar.xz"&gt;MDA.lv2 1.2.8&lt;/a&gt; has been released.  This is a port of the MDA VST plugins to LV2.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add REUSE licensing metadata&lt;/li&gt;
&lt;li&gt;Add lv2lint test&lt;/li&gt;
&lt;li&gt;Switch to meson build system&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="MDA.lv2"/></entry><entry><title>Fomp.lv2 1.2.4</title><link href="https://drobilla.net/2022/08/13/fomp-1-2-4.html" rel="alternate"/><published>2022-08-13T20:43:00-04:00</published><updated>2022-08-13T20:43:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-08-13:/2022/08/13/fomp-1-2-4.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/fomp-1.2.4.tar.xz"&gt;Fomp.lv2 1.2.4&lt;/a&gt; has been released.  Fomp is an LV2 port of the MCP, VCO, FIL, and WAH plugins by Fons Adriaensen.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add lv2lint test&lt;/li&gt;
&lt;li&gt;Switch to meson build system&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Fomp.lv2"/></entry><entry><title>Suil 0.10.16</title><link href="https://drobilla.net/2022/08/12/suil-0-10-16.html" rel="alternate"/><published>2022-08-12T22:17:00-04:00</published><updated>2022-08-12T22:17:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-08-12:/2022/08/12/suil-0-10-16.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/suil-0.10.16.tar.xz"&gt;Suil 0.10.16&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix wrapper module installation path&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Lilv 0.24.18</title><link href="https://drobilla.net/2022/08/12/lilv-0-24-18.html" rel="alternate"/><published>2022-08-12T22:15:00-04:00</published><updated>2022-08-12T22:15:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-08-12:/2022/08/12/lilv-0-24-18.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/lilv-0.24.18.tar.xz"&gt;Lilv 0.24.18&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allow programs to be used from subproject&lt;/li&gt;
&lt;li&gt;Fix default LV2_PATH&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Lilv 0.24.16</title><link href="https://drobilla.net/2022/07/19/lilv-0-24-16.html" rel="alternate"/><published>2022-07-19T01:16:00-04:00</published><updated>2022-07-19T01:16:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-07-19:/2022/07/19/lilv-0-24-16.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/lilv-0.24.16.tar.xz"&gt;Lilv 0.24.16&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix fallback flock() detection on MacOS&lt;/li&gt;
&lt;li&gt;Switch to meson build system&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Suil 0.10.14</title><link href="https://drobilla.net/2022/07/19/suil-0-10-14.html" rel="alternate"/><published>2022-07-19T01:14:00-04:00</published><updated>2022-07-19T01:14:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-07-19:/2022/07/19/suil-0-10-14.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/suil-0.10.14.tar.xz"&gt;Suil 0.10.14&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix MacOS build&lt;/li&gt;
&lt;li&gt;Fix documentation install path&lt;/li&gt;
&lt;li&gt;Remove dead Qt4 support code&lt;/li&gt;
&lt;li&gt;Switch to meson build system&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Sratom 0.6.12</title><link href="https://drobilla.net/2022/07/19/sratom-0-6-12.html" rel="alternate"/><published>2022-07-19T01:13:00-04:00</published><updated>2022-07-19T01:13:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-07-19:/2022/07/19/sratom-0-6-12.html</id><content type="html">&lt;p&gt;&lt;a href="https://download.drobilla.net/sratom-0.6.12.tar.xz"&gt;Sratom 0.6.12&lt;/a&gt; has been released.  Sratom is a small library for serializing LV2 atoms.  Sratom reads/writes atoms from/to RDF, allowing them to be converted between binary and text or stored in a model.  For more information, see &lt;a href="http://drobilla.net/software/sratom"&gt;http://drobilla.net/software/sratom&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Switch to meson build system&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>Patchage 1.0.6</title><link href="https://drobilla.net/2022/05/27/patchage-1-0-6.html" rel="alternate"/><published>2022-05-27T03:08:00-04:00</published><updated>2022-05-27T03:08:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-05-27:/2022/05/27/patchage-1-0-6.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/patchage-1.0.6.tar.bz2"&gt;Patchage 1.0.6&lt;/a&gt; has been released.  Patchage is a modular patch bay for Jack and ALSA based audio/MIDI systems.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix ALSA sequencer port subscriptions&lt;/li&gt;
&lt;li&gt;Fix crash on client disconnection&lt;/li&gt;
&lt;li&gt;Fix initial display with no configuration file&lt;/li&gt;
&lt;li&gt;Fix various minor bugs&lt;/li&gt;
&lt;li&gt;Rework code architecture to be more decoupled and data-driven&lt;/li&gt;
&lt;li&gt;Save "human names" setting in configuration&lt;/li&gt;
&lt;li&gt;Show latency in toolbar with 2 decimal places&lt;/li&gt;
&lt;li&gt;Switch to C++14&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="Patchage"/></entry><entry><title>Suil 0.10.12</title><link href="https://drobilla.net/2022/05/27/suil-0-10-12.html" rel="alternate"/><published>2022-05-27T01:43:00-04:00</published><updated>2022-05-27T01:43:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-05-27:/2022/05/27/suil-0-10-12.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/suil-0.10.12.tar.bz2"&gt;Suil 0.10.12&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix build issues with newer toolchains&lt;/li&gt;
&lt;li&gt;Fix some compiler warnings&lt;/li&gt;
&lt;li&gt;Remove Qt4 support&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Lilv 0.24.14</title><link href="https://drobilla.net/2022/05/27/lilv-0-24-14.html" rel="alternate"/><published>2022-05-27T01:38:00-04:00</published><updated>2022-05-27T01:38:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-05-27:/2022/05/27/lilv-0-24-14.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/lilv-0.24.14.tar.bz2"&gt;Lilv 0.24.14&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix build issues with newer toolchains&lt;/li&gt;
&lt;li&gt;Fix unused parameter warnings&lt;/li&gt;
&lt;li&gt;Update zix tree&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Sratom 0.6.10</title><link href="https://drobilla.net/2022/05/26/sratom-0-6-10.html" rel="alternate"/><published>2022-05-26T23:27:00-04:00</published><updated>2022-05-26T23:27:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2022-05-26:/2022/05/26/sratom-0-6-10.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/sratom-0.6.10.tar.bz2"&gt;Sratom 0.6.10&lt;/a&gt; has been released.  Sratom is a small library for serialising LV2 atoms to and from RDF, for converting between binary and text or storing in a model.  For more information, see &lt;a href="http://drobilla.net/software/sratom"&gt;http://drobilla.net/software/sratom&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix documentation installation directory&lt;/li&gt;
&lt;li&gt;Fix potential blank node ID truncation&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>Ganv 1.8.0</title><link href="https://drobilla.net/2021/01/07/ganv-1-8-0.html" rel="alternate"/><published>2021-01-07T22:38:00-05:00</published><updated>2021-01-07T22:38:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2021-01-07:/2021/01/07/ganv-1-8-0.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/ganv-1.8.0.tar.bz2"&gt;Ganv 1.8.0&lt;/a&gt; has been released.  Ganv is an interactive Gtk canvas widget for graph-based interfaces (patchers, modular synthesizers, finite state automata, interactive graphs, etc). For more information, see &lt;a href="http://drobilla.net/software/ganv"&gt;http://drobilla.net/software/ganv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Expand canvas automatically to fit nodes&lt;/li&gt;
&lt;li&gt;Fix various compiler warnings&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="Ganv"/></entry><entry><title>Jalv 1.6.6</title><link href="https://drobilla.net/2021/01/07/jalv-1-6-6.html" rel="alternate"/><published>2021-01-07T22:05:00-05:00</published><updated>2021-01-07T22:05:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2021-01-07:/2021/01/07/jalv-1-6-6.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/jalv-1.6.6.tar.bz2"&gt;Jalv 1.6.6&lt;/a&gt; has been released.  Jalv is a simple but fully featured LV2 host for Jack which exposes plugin ports to Jack, essentially making any LV2 plugin function as a Jack application. For more information, see &lt;a href="http://drobilla.net/software/jalv"&gt;http://drobilla.net/software/jalv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add a command line argument to select a specific UI&lt;/li&gt;
&lt;li&gt;Explicitly support lv2:inPlaceBroken&lt;/li&gt;
&lt;li&gt;Ignore ports with nonsense lv2:control designations&lt;/li&gt;
&lt;li&gt;Remove Jack session support&lt;/li&gt;
&lt;li&gt;Support port events for ui:showInterface UIs&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Jalv"/></entry><entry><title>Patchage 1.0.4</title><link href="https://drobilla.net/2021/01/07/patchage-1-0-4.html" rel="alternate"/><published>2021-01-07T21:59:00-05:00</published><updated>2021-01-07T21:59:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2021-01-07:/2021/01/07/patchage-1-0-4.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/patchage-1.0.4.tar.bz2"&gt;Patchage 1.0.4&lt;/a&gt; has been released.  Patchage is a modular patch bay for Jack and ALSA based audio/MIDI systems.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add NSMicrophoneUsageDescription for MacOS 10.15 Catalina&lt;/li&gt;
&lt;li&gt;Add command line option to print version&lt;/li&gt;
&lt;li&gt;Fix making and breaking connections with Jack DBus&lt;/li&gt;
&lt;li&gt;Fix sample rate with Jack DBus&lt;/li&gt;
&lt;li&gt;Fix unstable module positions&lt;/li&gt;
&lt;li&gt;Improve man page&lt;/li&gt;
&lt;li&gt;Remove Jack session support&lt;/li&gt;
&lt;li&gt;Remove flaky DSP load meter&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="Patchage"/></entry><entry><title>Lilv 0.24.12</title><link href="https://drobilla.net/2021/01/07/lilv-0-24-12.html" rel="alternate"/><published>2021-01-07T21:46:00-05:00</published><updated>2021-01-07T21:46:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2021-01-07:/2021/01/07/lilv-0-24-12.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/lilv-0.24.12.tar.bz2"&gt;Lilv 0.24.12&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allow connecting ports to structures in Python&lt;/li&gt;
&lt;li&gt;Fix potential memory error when joining filesystem paths&lt;/li&gt;
&lt;li&gt;Fix saving state with files on Windows&lt;/li&gt;
&lt;li&gt;Fix unlikely undefined behavior when saving state&lt;/li&gt;
&lt;li&gt;Fix writing state manifests on Windows&lt;/li&gt;
&lt;li&gt;Remove the need for a generated configuration header&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Suil 0.10.10</title><link href="https://drobilla.net/2021/01/07/suil-0-10-10.html" rel="alternate"/><published>2021-01-07T21:40:00-05:00</published><updated>2021-01-07T21:40:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2021-01-07:/2021/01/07/suil-0-10-10.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/suil-0.10.10.tar.bz2"&gt;Suil 0.10.10&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Clean up minor code issues&lt;/li&gt;
&lt;li&gt;Remove the need for a generated configuration header&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Sratom 0.6.8</title><link href="https://drobilla.net/2021/01/07/sratom-0-6-8.html" rel="alternate"/><published>2021-01-07T21:36:00-05:00</published><updated>2021-01-07T21:36:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2021-01-07:/2021/01/07/sratom-0-6-8.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/sratom-0.6.8.tar.bz2"&gt;Sratom 0.6.8&lt;/a&gt; has been released.  Sratom is a small library for serialising LV2 atoms to and from RDF, for converting between binary and text or storing in a model.  For more information, see &lt;a href="http://drobilla.net/software/sratom"&gt;http://drobilla.net/software/sratom&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix potential null pointer dereference&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>Beautiful C and C++ Documentation with Sphinx</title><link href="https://drobilla.net/2020/11/26/beautiful-c-and-cxx-documentation-with-sphinx.html" rel="alternate"/><published>2020-11-26T17:12:00-05:00</published><updated>2020-11-26T17:12:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2020-11-26:/2020/11/26/beautiful-c-and-cxx-documentation-with-sphinx.html</id><content type="html">&lt;p&gt;Like many, I've long suffered under the antiquated and inflexible HTML
documentation generated by Doxygen.  Having recently worked on some Python
documentation using Sphinx, though, I found it powerful and pleasant enough to
use.  It also has a way of encouraging actually &lt;em&gt;writing&lt;/em&gt; documentation, rather
than just generating a dump of glorified comments, which is a good thing.
Though I'm not at all a fan of ReStructuredText syntax (which at times seems
like it's trying to be cryptic on purpose), Sphinx is undeniably powerful, and
I like the “assemble a bunch of plainish text files” approach in general.  The
support for multiple languages is also very appealing, though not without its
problems, as we'll get to.&lt;/p&gt;
&lt;p&gt;So, is it possible to use Sphinx to generate documentation for C and C++
libraries?  Yes!  As explained somewhat recently in a &lt;a href="https://devblogs.microsoft.com/cppblog/clear-functional-c-documentation-with-sphinx-breathe-doxygen-cmake/"&gt;post by Sy Brand&lt;/a&gt;,
there is a project called Breathe that integrates Doxygen (for extracting
documentation) with Sphinx (for generating output).  That sounded promising, so
I attempted to migrate a library to using Breathe instead of Doxygen's HTML
support.  Unfortunately, though, I encountered quite a few roadblocks where I
couldn't quite get output that I was happy with.  Worse, the project itself is
very complicated, and as I poked around in swaths of originally generated but
manually modified code, I decided that Breathe was not for me.  That would feel
like just exchanging one inflexible and unhackable system for another.&lt;/p&gt;
&lt;p&gt;What, then, to do?  Though I realize that deep integration via modules like
Breathe is usually the way things are done with Sphinx, I am a KISS sort of
person, so I like to think of it as something more like a Static Site
Generator: it reads a bunch of plainish text input files, and outputs HTML (or
whatever other presentation format).  How do we describe C and C++ things in
Sphinx?  It turns out that recent versions have built-in support for these
“domains” now, which define markup for describing everything in these
languages.  This means that everything to do with nicely formatting and
cross-referencing C and C++ is already dealt with out of the box.  Excellent.&lt;/p&gt;
&lt;p&gt;So, taking a step back and assessing the situation: we have some XML files that
describe the documentation, and we have a tool that reads text files and
produces nice documentation.  This strikes me as a relatively straightforward
task for a nice and simple “files in, files out” script, not somewhere a
Goldbergian contraption that mashes Doxygen into Sphinx is required.  So, after
investigating any other promising options (no such luck), I resigned myself to
trying to write such a thing, at the very least to see if it's feasible.  I
certainly have no time or interest in writing and maintaining a Documentation
System, but a self-contained script to convert one thing to another seems
reasonable enough.&lt;/p&gt;
&lt;p&gt;As it turns out, I wouldn't call it trivial, but it's certainly feasible.  I
ended up with a &lt;a href="https://gitlab.com/lv2/pugl/-/blob/6a530fcaf22effb8f54f290996c02e9e90d58a7a/scripts/dox_to_sphinx.py"&gt;~700 line Python script&lt;/a&gt; that does everything I need
(though this is of course not the same as everything possible).  It's a bit
“gluey” and makes some assumptions about the structure and so on, but it does
the job and is something I feel I can maintain as necessary.  I won't be
publishing or supporting this as an independent project any time soon, and make
no claims about it being general purpose, but feel free to steal it if any of
this sounds appealing.&lt;/p&gt;
&lt;p&gt;With this, I was able to get around some long-standing gripes I have with
Doxygen, and easily make whatever I wanted to happen a reality, so I'm pretty
happy with this approach.  Everything is nicely decoupled, so I don't feel
over-invested in any of the tools involved.  If, for example, someone finally
writes a good clang-based extractor that gains traction (JSON please, I did not
enjoy this revisitation of the horrors of XML at all), I should be able to
switch to using that easily enough.  I've actually found this somewhat crude
and UNIXey approach quite convenient: you can simply look at the ReST files to
understand what is happening, or tweak them a bit and run Sphinx to test what
you're aiming for, and so on.  Text files are good.&lt;/p&gt;
&lt;p&gt;So, after however many years, I think I've found an approach to documentation
I'm actually quite happy with, that can support all of the languages that I
use, and in general doesn't seem to get in my way.  Hooray.  For starters, I
did my window system portability layer, &lt;a href="https://gitlab.com/lv2/pugl"&gt;Pugl&lt;/a&gt;.  The generated documentation
for the C API can be seen at &lt;a href="https://lv2.gitlab.io/pugl/c/singlehtml/"&gt;https://lv2.gitlab.io/pugl/c/singlehtml/&lt;/a&gt;, and
the C++ at &lt;a href="https://lv2.gitlab.io/pugl/cpp/singlehtml/"&gt;https://lv2.gitlab.io/pugl/cpp/singlehtml/&lt;/a&gt;.  This is more or less
the standard Alabaster theme with a few tweaks, which I'm not sure feels
appropriate for API documentation (and is &lt;em&gt;much&lt;/em&gt; more bloated with a bunch of
Javascript than I'd like), but it's pretty enough, at least.  I'll tinker with
themes later when I feel like jumping down that rabbit hole.&lt;/p&gt;
&lt;p&gt;The slightly cumbersome links are an artifact of the one problem I encountered
using Sphinx domains: you can't really document C &lt;em&gt;and&lt;/em&gt; C++ APIs nicely in the
same documentation set.  If you use the &lt;code&gt;cpp&lt;/code&gt; domain everywhere, you get name
mangling in links even for C symbols, which is really unfortunate, and you
can't really mix them.  To take a contrived example, if you have a &lt;code&gt;struct
MylibThing&lt;/code&gt; in C, then a type alias in C++ like &lt;code&gt;using Thing = MylibThing&lt;/code&gt;,
Sphinx isn't clever enough to figure out that &lt;code&gt;MylibThing&lt;/code&gt; is from C, and will
generate warnings and not link correctly.  Perhaps someday it will, which would
be nice, but for now I opted to simply generate completely separate
documentation sets.  This means the C documentation is duplicated in the C++
documentation so that things can be hyperlinked, which isn't ideal, but I can
live with it.  A certain amount of redundancy is inherent in multi-language
documentation anyway.&lt;/p&gt;
&lt;p&gt;As I add Python bindings to most libraries, having a unified documentation
system for all of these languages will be very nice.  There is one additional
thing I'll need at some point for the LV2 documentation in particular: a domain
for RDF properties and classes.  The LV2 documentation really suffers from an
unnatural code (via Doxygen) and data (via lv2specgen) documentation split, and
my hope is that Sphinx can provide a nice environment for writing documentation
that refers to both worlds freely.  That, unfortunately, will be much more
work, but hopefully writing a custom Sphinx domain isn't too hard...&lt;/p&gt;</content><category term="misc"/><category term="Hacking"/><category term="C"/><category term="Cpp"/><category term="LAD"/><category term="LV2"/></entry><entry><title>Sratom 0.6.6</title><link href="https://drobilla.net/2020/09/27/sratom-0-6-6.html" rel="alternate"/><published>2020-09-27T15:18:00-04:00</published><updated>2020-09-27T15:18:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2020-09-27:/2020/09/27/sratom-0-6-6.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/sratom-0.6.6.tar.bz2"&gt;Sratom 0.6.6&lt;/a&gt; has been released.  Sratom is a small library for serialising LV2 atoms to and from RDF, for converting between binary and text or storing in a model.  For more information, see &lt;a href="http://drobilla.net/software/sratom"&gt;http://drobilla.net/software/sratom&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix various minor warnings and other code quality issues&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>Suil 0.10.8</title><link href="https://drobilla.net/2020/09/27/suil-0-10-8.html" rel="alternate"/><published>2020-09-27T12:22:00-04:00</published><updated>2020-09-27T12:22:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2020-09-27:/2020/09/27/suil-0-10-8.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/suil-0.10.8.tar.bz2"&gt;Suil 0.10.8&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix X11 in Gtk size regressions (thanks Robin Gareus)&lt;/li&gt;
&lt;li&gt;Fix compilation on MacOS older than 10.12&lt;/li&gt;
&lt;li&gt;Fix drag and drop for X11 in Gtk&lt;/li&gt;
&lt;li&gt;Fix various minor warnings and other code quality issues&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Lilv 0.24.10</title><link href="https://drobilla.net/2020/09/27/lilv-0-24-10.html" rel="alternate"/><published>2020-09-27T12:17:00-04:00</published><updated>2020-09-27T12:17:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2020-09-27:/2020/09/27/lilv-0-24-10.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/lilv-0.24.10.tar.bz2"&gt;Lilv 0.24.10&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix memory leaks in lv2bench&lt;/li&gt;
&lt;li&gt;Fix various minor warnings and other code quality issues&lt;/li&gt;
&lt;li&gt;Make lilv_world_get() use translations&lt;/li&gt;
&lt;li&gt;Split and clean up test suite&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Lilv 0.24.8</title><link href="https://drobilla.net/2020/04/26/lilv-0-24-8.html" rel="alternate"/><published>2020-04-26T15:55:00-04:00</published><updated>2020-04-26T15:55:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2020-04-26:/2020/04/26/lilv-0-24-8.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/lilv-0.24.8.tar.bz2"&gt;Lilv 0.24.8&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allow passing strings for URIs in Python API when unambiguous&lt;/li&gt;
&lt;li&gt;Fix cases where incorrect translation is used&lt;/li&gt;
&lt;li&gt;Fix deleting state bundles loaded from the model&lt;/li&gt;
&lt;li&gt;Fix memory leak when dyn-manifest has no plugins (thanks Michael Fisher)&lt;/li&gt;
&lt;li&gt;Implement state:freePath feature&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Patchage 1.0.2</title><link href="https://drobilla.net/2020/04/09/patchage-1-0-2.html" rel="alternate"/><published>2020-04-09T12:29:00-04:00</published><updated>2020-04-09T12:29:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2020-04-09:/2020/04/09/patchage-1-0-2.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/patchage-1.0.2.tar.bz2"&gt;Patchage 1.0.2&lt;/a&gt; has been released.  Patchage is a modular patch bay for Jack and ALSA based audio/MIDI systems.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add support for exporting canvas as PDF&lt;/li&gt;
&lt;li&gt;Bring back Jack buffer size selector&lt;/li&gt;
&lt;li&gt;Configure based on compiler target OS for cross-compilation&lt;/li&gt;
&lt;li&gt;Don't install 512x512 icons&lt;/li&gt;
&lt;li&gt;Fix compilation with Jack DBus&lt;/li&gt;
&lt;li&gt;Order ports deterministically&lt;/li&gt;
&lt;li&gt;Restore messages pane visibility and height&lt;/li&gt;
&lt;li&gt;Save window size and position when closed via window manager&lt;/li&gt;
&lt;li&gt;Style messages pane to match canvas&lt;/li&gt;
&lt;li&gt;Support Jack CV and OSC via metadata&lt;/li&gt;
&lt;li&gt;Upgrade to waf 2.0.19&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="Patchage"/></entry><entry><title>Ganv 1.6.0</title><link href="https://drobilla.net/2020/04/09/ganv-1-6-0.html" rel="alternate"/><published>2020-04-09T11:45:00-04:00</published><updated>2020-04-09T11:45:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2020-04-09:/2020/04/09/ganv-1-6-0.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/ganv-1.6.0.tar.bz2"&gt;Ganv 1.6.0&lt;/a&gt; has been released.  Ganv is an interactive Gtk canvas widget for graph-based interfaces (patchers, modular synthesizers, finite state automata, interactive graphs, etc). For more information, see &lt;a href="http://drobilla.net/software/ganv"&gt;http://drobilla.net/software/ganv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add API to specify module port order.&lt;/li&gt;
&lt;li&gt;Add support for PDF and PS export.&lt;/li&gt;
&lt;li&gt;Add support for beveled box corners.&lt;/li&gt;
&lt;li&gt;Add support for edges that do not constrain the layout.&lt;/li&gt;
&lt;li&gt;Dampen sprung layout energy over time to prevent oscillation.&lt;/li&gt;
&lt;li&gt;Distinguish edge color from port color slighly.&lt;/li&gt;
&lt;li&gt;Fix compilation with --no-fdgl (patch from Vlad Glagolev).&lt;/li&gt;
&lt;li&gt;Fix crash when destroying canvas.&lt;/li&gt;
&lt;li&gt;Fix port position on modules with embedded widgets.&lt;/li&gt;
&lt;li&gt;Fix positioning of embedded widgets when changing layout.&lt;/li&gt;
&lt;li&gt;Fix size of vertical flow modules.&lt;/li&gt;
&lt;li&gt;Fix unexpected node jumping when dragging new connections.&lt;/li&gt;
&lt;li&gt;Fix various minor visual alignment/sizing issues.&lt;/li&gt;
&lt;li&gt;Highlight connected edges on port hover.&lt;/li&gt;
&lt;li&gt;Improve appearance of graphs with circle nodes.&lt;/li&gt;
&lt;li&gt;Improve text rendering at high zoom.&lt;/li&gt;
&lt;li&gt;Improve update performance.&lt;/li&gt;
&lt;li&gt;Preserve selection for quickly making several connections.&lt;/li&gt;
&lt;li&gt;Upgrade to waf 2.0.19&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="Ganv"/></entry><entry><title>Cleaning Up the LV2 Extension Mess</title><link href="https://drobilla.net/2019/11/13/cleaning-up-the-lv2-extension-mess.html" rel="alternate"/><published>2019-11-13T23:05:00-05:00</published><updated>2019-11-13T23:05:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2019-11-13:/2019/11/13/cleaning-up-the-lv2-extension-mess.html</id><content type="html">&lt;p&gt;After reading my last post, and watching a few old talks around LV2 and so on,
I got to thinking about the extension mess problem I mentioned, and it occured
to me that there might be some commonality here with the “staging” or “contrib”
area question as well.&lt;/p&gt;
&lt;p&gt;This is all based on some ideas that have been bouncing around in my head for
ages, but that I haven't really developed and certainly not written down, so
I'm going to try and sketch out a proposal for how to handle these things
without breaking anything.&lt;/p&gt;
&lt;p&gt;Concretely, there are two problems here: one is that the spec is just a mess.
For example, the &lt;a href="http://lv2plug.in/ns/ext/data-access/data-access.html"&gt;Data
Access&lt;/a&gt; and &lt;a href="http://lv2plug.in/ns/ext/instance-access/instance-access.html"&gt;Instance
Access&lt;/a&gt;
extensions are really just parts of the same thing and should live together,
nobody cares about &lt;a href="http://lv2plug.in/ns/ext/morph/morph.html"&gt;Morph&lt;/a&gt; and it's
not in a state that really belongs in the “recommended standard” list (sorry,
flagrant abuse of power on my part there), and so on.&lt;/p&gt;
&lt;p&gt;The other problem is that there are sometimes contributions which solve a
problem, and are a reasonable enough pragmatic step, but also not really up to
par.  Maybe they aren't portable, aren't defined well enough, could do more
harm than good if they're presented as recommendations, and so on.  People, for
whatever reason, want them “in LV2”.  Yet, nobody has the time to spend to
develop them into a more proper specification yet, and nobody is happy when
things don't get merged.&lt;/p&gt;
&lt;p&gt;It seems there is a common factor to these problems, and it's moving things
without breaking anything.  To clean up the current mess, we can move
extensions &lt;em&gt;to&lt;/em&gt; the contrib area.  When a previously half-baked contribution is
developed further, we can move it &lt;em&gt;from&lt;/em&gt; the contrib area.  This is an obvious
coarse-grained use case; I think there is also a case for finer-grained URI
migration, but I'll focus on the easy and most useful case for now.&lt;/p&gt;
&lt;p&gt;How might we do this?  Though moving instance-access to contrib is not a goal,
it's about as simple as an extension gets, so I'll pretend we want to do that
for the sake of a simple example.  At the very least, it will be a nice little
fantasy for me to pretend that the curse of crappy plugin UIs that mess with
DSP guts has finally been vanquished for good :) This is just about the
mechanism, what we should actually do to clean things up is a question for
another time.&lt;/p&gt;
&lt;p&gt;So, what's instance-access?  It's a handful of URIs, and a feature.  The
feature is extremely simple, the payload is just some pointer.  Can those URIs
be moved without breaking anything?  For at least this simple case, I think so:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Lilv, on loading data, aggressively maps &lt;em&gt;everything&lt;/em&gt; to the new location.
   If it says &lt;a href="http://lv2plug.in/ns/ext/instance-access"&gt;http://lv2plug.in/ns/ext/instance-access&lt;/a&gt; in a data file, then
   it gets loaded into memory as
   &lt;a href="http://lv2plug.in/ns/contrib/instance-access"&gt;http://lv2plug.in/ns/contrib/instance-access&lt;/a&gt;.  In this case, that means
   that, as far as the host can tell, the UI has lv2:optionalFeature
   &lt;a href="http://lv2plug.in/ns/contrib/instance-access"&gt;http://lv2plug.in/ns/contrib/instance-access&lt;/a&gt;.  This can be done pretty
   easily just above the parser level so that it's universally true.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;When the UI is instantiated, the (old) host passes the
   &lt;a href="http://lv2plug.in/ns/ext/instance-access"&gt;http://lv2plug.in/ns/ext/instance-access&lt;/a&gt; feature to
   &lt;code&gt;lilv_plugin_instantiate()&lt;/code&gt;.  Internally, lilv duplicates this, and passes
   &lt;em&gt;both&lt;/em&gt; the old and new features to the UI with the same data.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The plugin is either old, and looks for the old feature URI, or new, and
   looks for the new feature URI, and either way, finds it.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;I can't think of a reason this wouldn't work, and it doesn't even require any
host changes.  It's a bit bloated, but not in a way that matters, and would
need a significant (but not too bad) amount of code specifically to deal with
this in lilv, but such is my lot in life.&lt;/p&gt;
&lt;p&gt;In the more general case, there is also the issue of URID mappings.  Let's
pretend that &lt;a href="http://lv2plug.in/ns/ext/instance-access"&gt;http://lv2plug.in/ns/ext/instance-access&lt;/a&gt; is mapped to a URID
both by the host and the plugin, and that URID is sent between them.  Though
this isn't really an intended use-case for this particular extension, it's a
perfectly valid thing to do:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;The host URID-map maps both the old and new URIs to the same URID.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;... that's it, actually.  Regardless of which “version” either host or plugin
know about, the URID is identical.  This requires hosts to actually implement
something though, or for a URI map to be added to lilv, so it's not as easy.
It can't just be done in LV2 and would take some time to get established.&lt;/p&gt;
&lt;p&gt;There is one remaining snag: &lt;code&gt;extension_data&lt;/code&gt;.  This one is a bit trickier,
because we need to assume the hosts uses &lt;code&gt;lilv_instance_get_extension_data&lt;/code&gt;
which is just a trivial wrapper, and probably not used by everyone.  That's an
easy enough fix to make, though.  Then, lilv just needs to call the plugin
method for the new URI, return that if it isn't NULL, and fallback to calling
it with the old URI.&lt;/p&gt;
&lt;p&gt;All of this requires a map between old and new to exist, of course, but this
would be written down in the specs themselves and it's easy enough to load such
a thing inside lilv.&lt;/p&gt;
&lt;p&gt;I'm sure there are other places where URIs as strings are used in the API that
would need thinking about, and I'll have to scan through the spec to see, but I
suspect the above is at least 90% of what matters.&lt;/p&gt;
&lt;p&gt;So... am I missing something?  Do send me (or lv2-dev) an email if so, but now
that I write it down this seems more viable than I assumed it would be.  There
will definitely be corner cases, since plugins and hosts can use these strings
for anything everywhere, but as far as the actual interface is concerned it
seems possible to make this happen without too much pain.  What could we do
with this?&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Merge data-access and instance-access&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Merge buf-size and resize-port&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Put all the “official” extensions in the same namespace (“directory”), and
   get rid of the annoying inconsistency of &lt;code&gt;ext&lt;/code&gt; and &lt;code&gt;extensions&lt;/code&gt; and so on
   (which doesn't really matter, except in the soft sense that ugliness
   matters).  The header includes already look like this and it's so much
   nicer.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;We could put the deprecated extensions in a special namespace so they really
   stand out, but this doesn't seem to really matter (though it should be done
   visually on the &lt;a href="http://lv2plug.in/ns/"&gt;spec page&lt;/a&gt; regardless).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Move presets into lv2core itself?  This isn't an extension-level move like
   the above, but why not?  One less prefix to bother with, and in retrospect,
   a plugin spec without any kind of presets at all is pretty silly.  Perhaps
   the same for port-groups.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Do... something with port-properties, and maybe parameters.  Let's say
   combine them into a “control” extension that generally has all the
   definition of control related stuff.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Move morph to contrib.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Maybe move dyn-manifest to contrib.  This is a bit more contentious, but
   it's a pretty ugly solution, and the caveats of using it currently aren't
   very clear.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That would leave a specification list like this (assuming parameters and
port-properties move to “control”):&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Atom: A generic value container and several data types&lt;/li&gt;
&lt;li&gt;Buf Size: Access to, and restrictions on, block and buffer sizes&lt;/li&gt;
&lt;li&gt;Instance Access: Provides access to a plugin instance&lt;/li&gt;
&lt;li&gt;Log: A feature for writing log messages&lt;/li&gt;
&lt;li&gt;LV2: An open and extensible audio plugin standard&lt;/li&gt;
&lt;li&gt;MIDI: A normalised definition of raw MIDI&lt;/li&gt;
&lt;li&gt;Options: Instantiation time options&lt;/li&gt;
&lt;li&gt;Control: Common properties and parameters for audio processing&lt;/li&gt;
&lt;li&gt;Patch: Messages for accessing and manipulating properties with events&lt;/li&gt;
&lt;li&gt;State: An interface for LV2 plugins to save and restore state&lt;/li&gt;
&lt;li&gt;Time: Properties for describing time&lt;/li&gt;
&lt;li&gt;UI: LV2 plugin UIs of any type&lt;/li&gt;
&lt;li&gt;Units: Meaningful units for values&lt;/li&gt;
&lt;li&gt;URID: Features for mapping URIs to and from integers&lt;/li&gt;
&lt;li&gt;Worker: Support for doing non-realtime work in plugins&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Not everything left is immaculate, and from a user-facing documentation point
of view other things like putting the data-only vocabularies in a separate
section might help even more, but I think this would be a big improvement.
More importantly, it would of course give us an attic to put slightly more
sketchy things.  Looking at LV2 as a Specification™, that feels wrong, but
looking at it as a project, it seems really necessary.&lt;/p&gt;</content><category term="misc"/><category term="LAD"/><category term="LV2"/></entry><entry><title>LV2: The Good, Bad, and Ugly</title><link href="https://drobilla.net/2019/11/11/lv2-the-good-bad-and-ugly.html" rel="alternate"/><published>2019-11-11T21:35:00-05:00</published><updated>2019-11-11T21:35:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2019-11-11:/2019/11/11/lv2-the-good-bad-and-ugly.html</id><content type="html">&lt;p&gt;It occurred to me that I haven't really been documenting what I've been up to,
a lot of which is behind the scenes in non-release branches, so I thought I
would write a post about the general action around LV2 lately.  I've also been
asked several times about what the long-term strategy for LV2 is, if there
should be an “LV3”, whether LV* can start to really gain traction as a
competitor to the big proprietary formats, and so on.&lt;/p&gt;
&lt;p&gt;So, here it is, a huge brain dump on what's good, what's bad, what's ugly, and
what I think should be done about it.&lt;/p&gt;
&lt;h3&gt;The Good&lt;/h3&gt;
&lt;p&gt;LV2 is different from other plugin standards in several ways.  This is not
always a good thing (which we'll get to shortly), but there are some things
that have proven to be very good ideas, even if the execution was not always
ideal:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Openness: Obvious, but worth mentioning anyway.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Extensibility: The general idea of building an extensible core, so that
   plugin and host authors can add functionality in a controlled way is a great
   one.  This allows developers to prototype new functionality to eventually be
   standardised, make use of additional functionality if it is available, and
   so on.  Some problems, like ensuring things are documented, that
   implementations agree, and so on, get more difficult when anybody can add
   anything, but this is worth the benefit of not having a standardisation
   process block getting things done.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;DSP and UI split: Also obvious in my opinion, but certainly not a universal
   thing.  There are a lot of bad things to be said about the actual state of
   GUI support, but keeping them separate, with the &lt;em&gt;option&lt;/em&gt; to have a pointer
   to the guts of a plugin instance is the right approach.  Having a
   well-defined way to communicate between GUI and DSP makes it easy to do the
   right thing.  Multi-threaded realtime programming is hard, and plugins
   dropping out because of GUI activity and so on should not be a thing.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Standard implementation between host and plugins (for some things): This is
   a huge win in reducing the burden on both host and plugin authors, and
   allows both to rely on certain things being done right.  This also makes a
   location where stronger validation and so on can happen, which we should
   exploit more.  The war between host and plugin authors, trying to make
   things compatible with the arbitrary behaviour of countless implementations
   is largely why everyone hates plugins.  This doesn't have to be a thing.  We
   haven't actually done well in that area with LV2 (quite the opposite), but
   having a place to put that code is the right move.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Transparent communication: Though you technically can do just about anything
   with LV2, a “proper” plugin has a transparent control interface that works
   in a standard way.  This gets you all kinds of things for free, like
   human-readable debug tracing, network transparency, and so on, and also
   encourages design that's better from a user point of view, like having good
   host controls for parameters, automation, accessibility, and so on.  This is
   somewhat related to having a DSP and UI split.  The benefits of having
   plugins be controlled in a standard way are endless, as are the awful things
   that happen when GUIs and audio code aren't forcefully kept at arm's reach.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The Bad&lt;/h3&gt;
&lt;p&gt;Now to the more interesting part.  There are some nice ideas in LV2, and I
think an idealised and cleaned up version of it that adheres to the main
underlying design principles would be beautiful.  In reality, however, LV2 is
an atrocious mess in all kinds of ways:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Control ports: LV2 uses LADSPA-style control ports, which contain a single
   float.  This is a tricky one to put in the “bad” category, since
   pragmatically grafting extensibility onto LADSPA is why LV2 has been
   moderately successful.  It had to be that way: we needed working plugins,
   not a tedious standardisation process that goes nowhere (there's already
   GMPI for that).  That said, control ports are incredibly limiting and that
   they still exist is an endless source of trouble: they are static, they
   require buffer splitting for sample accuracy, they can only convey a float,
   there is no hook to detect changes and do smoothing, and so on. A control
   protocol (something like MIDI except... good) is the right way to control
   plugins.  Notes and controls and all the rest should be in the same stream,
   synchronous with audio.  It's hard to migrate to such a reality, but there
   should be one consistent way to control a plugin, and it should be a stream
   of sample-accurate events.  No methods, no threading and ABI nightmares, no
   ambiguity, just a nice synchronous stream of inputs, and a single run
   function that reads those and produces outputs.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The &lt;code&gt;connect_port&lt;/code&gt; method: Another LADSPA-ism.  This means that using some
   signal means the host must call a method on the plugin to connect it first.
   This is an awful design: it forces both the host and the plugin to maintain
   more state than is necessary, and it's slow.  I have written several plugins
   that would be completely stateless (essentially pure functions) except the
   spec requires the plugin to maintain all these pointers and implement
   methods to mutate them.  Inputs and outputs just should be passed to the run
   method, so all of that goes away and everything is nicely scoped.  As far as
   the basics of the C API are concerned, this is, in my opinion, the most
   egregious mistake.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Turtle: Everyone loves to hate Turtle.  It's mostly a nice syntax (if the
   namespace prefix limitations are very annoying), but it's weird.  Worse,
   people might search for “RDF” and find the confusing W3C trash-fire there.
   The underlying ideas are good, but that three-letter-acronym should be
   absolutely eliminated from the spec and documentation.  The good thing in
   LV2 is really just “property-centric design”, which can be explained in a
   simple way anyone can understand.  It's more or less just “JSON with URIs”
   anyway, and nobody ever got fired for using JSON.  Speaking of which,
   syntax-wise, JSON-LD is probably the way to go today.  JSON is annoying in
   different ways, but this would allow LV2 data files to look completely
   typical to almost any developer, but still have the same meaning and have
   the same advantages under the hood of a real data model.  This could
   actually be done without breaking anything in practice, but JSON-LD is much
   harder to implement so I'm not quite there yet.  It would also be some work
   to write the vocabulary (vocabularies?), but it's doable.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Lack of quality control: Again a consequence of pragmatic evolution, but the
   lack of standard quality control has become a real problem.  There has been
   progress made there, with things like &lt;code&gt;lv2lint&lt;/code&gt; and &lt;code&gt;lv2_validate&lt;/code&gt;, but it's
   not good enough.  The biggest problem with plugins (and plugin hosts) in
   general is that most of them are just broken.  There should be a standard
   test suite for both, that is as strict as possible, and its use should be
   strongly “encouraged” at the very least.  The above-mentioned existence of
   standard code in-between hosts and plugins could be useful here, for
   example, hosts could just refuse to load non-conforming plugins outright.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Extension spam: The “standard” extensions are not all very good, or widely
   supported.  They also aren't broken down and organized especially well in
   some cases.  We are at least somewhat stuck with this for compatibility, but
   it makes things confusing.  There are many reasons for this, but in general
   I think a better thought-out standardisation process, and a “sort of
   standard” staging ground to put contributions that some implementations
   agree on but aren't ideal or quite at “recommended standard” yet would help.
   I'm still not sure exactly how to do this, there's no best practice for such
   things out there that's easy to steal, but with the benefit of hindsight I
   think we could do much better.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Library spam: The standard host implementation is quite a few libraries.
   This is a mostly good thing, in that they have distinct purposes, different
   dependencies, and so on, but in practice it's annoying for packagers, or
   anyone who wants to vendor it.  I think the best approach here is to combine
   them into a meta-package or “SDK”, so libraries can still be properly split
   but without the maintenance burden.  I am working towards this with
   “lv2kit”.  It's currently hard for outsiders to even figure out what they
   need, a one-stop “all the LV2 things” in a single package would help
   immensely, especially for people outside of the Linux world (where
   distributions package everything anyway, so nobody really cares).&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;C++ and other language bindings: Plugin interfaces more or less have to be
   in C.  However, outside of POSIXland, nobody wants to actually write C.
   Virtually the entire audio industry uses C++.  Good bindings are important.
   Python is also nice for some things.  Rust would be great, and so on.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The Ugly&lt;/h3&gt;
&lt;p&gt;These are things that are just... well, ugly.  Not really “bad” in concrete ways
that matter much, but make life unpleasant all the same.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Extensibility only through the URI-based mechanism: In general,
   extensibility is good.  The host can pass whatever features, and plugins can
   publish whatever interfaces, and everything is discoverable and degrades
   gracefully and so on.  It works.  The downside is that there's some
   syntactic overhead to that which can be annoying.  We should have put sizes
   or versions in structs so they were also extensible in the classical way.
   For example, the &lt;code&gt;connect_port&lt;/code&gt; problem mentioned above could be fixed by
   adding a new run method, but we can't literally add a new run method to
   &lt;code&gt;LV2_Descriptor&lt;/code&gt;.  We would have to make a separate interface, and have the
   host access it with &lt;code&gt;extension_data&lt;/code&gt;, and so on, which makes things ugly.
   Maybe this is for the best, but ugliness matters.  In general there are a
   few places where we could have used more typical C patterns.  Weirdness
   matters too.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Extension organization: The list of specifications is a complete mess.  It
   annoys me so much.  I am not really sure about this: in some cases, an
   extension is a clearly separate thing, and having it be essentially a
   separate spec is great.  In other cases, we've ended up with vaguely related
   grab-bags of things for lack of anywhere else to put them.  I sometimes
   wonder if the KISS approach of just having one big namespace would have been
   the right way to go.  It would mean less prefixes everywhere at the very
   least.  Maybe we could use some other way of grouping things where it makes
   sense?&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Static data: This is a tough one.  One of the design principles of LV2 is
   that hosts don't need to load and run any code to just discover plugins, and
   information about them.  This is &lt;em&gt;great&lt;/em&gt;.  However, whenever the need for
   something more dynamic comes along (dynamic ports, say), we don't have any
   great way to deal with it, because the way everything is described is
   inherently static.  Going fully dynamic doesn't feel great either.  I think
   the solution here is to take advantage of the fact that the data files are
   really just a syntax and the same data can be expressed in other ways. We
   already have all the fundamental bits here, Atoms are essentially
   “realtime-ready RDF” and can be round-tripped to Turtle without loss.  My
   grand, if vague, vision here is that everything could just be the same
   conceptually, and the source of it be made irrelevant and hidden behind a
   single API. For example, a data file can say things like (pseudocode alert)
   &lt;code&gt;&amp;lt;volume&amp;gt; hasType Float; &amp;lt;volume&amp;gt; minimumValue 0.0; &amp;lt;volume&amp;gt; maximumValue
   1.0&lt;/code&gt; but a message from a plugin can say exactly the same thing at run time.
   If the host library (lilv) handled all this nicely, hosts could just do
   &lt;code&gt;lv2_get_minimum(gain)&lt;/code&gt; and not really care where the information came from.
   I think this is a much better approach than grafting on ever-more API for
   every little thing, but it would have to be done nicely with good support.
   I think the key here is to retain the advantages we have, but put some work
   into making really obvious and straightforward APIs for everything.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Overly dynamic URIDs: URIDs are a mechanism in LV2 where things are
   conceptually URIs (which makes everything extensible), but integers in
   practice for speed.  Generally a URID is made at instantiation time by
   calling a host-provided mapping function.  This is, for the most part,
   wonderful, but being always dynamic causes some problems.  You need dynamic
   state to talk about URIs at all, which makes for a lot of boilerplate, and
   gets in the way of things like language bindings (you couldn't make a simple
   standalone template that gives you an &lt;code&gt;Int&lt;/code&gt; atom for an &lt;code&gt;int32_t&lt;/code&gt;, for
   example).  I think it would be a good idea to have a static set of URIDs for
   things in the standard, so that &lt;code&gt;lv2_minimum&lt;/code&gt; or whatever is just statically
   there, but preserve the ability to extend things with dynamic mapping.  This
   is easy enough by adding the concept of a “minimum dynamic URID value”,
   where everything less than that is reserved by the standard.  Alternatively,
   or perhaps in addition, maybe having a standard loader to ease the pain of
   loading every little thing (like with OpenGL) would help make code cleaner
   and boilerplate free.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The Documentation Sucks: Of course, the documentation of everything always
   sucks, so you have to take this feedback with a grain of salt, but it's true
   of LV2.  A lot of improvements here are blocked by the specification
   breakdown being set in stone, but it could be improved.  I think the
   reference documentation is not the problem though, we really need
   example-driven documentation written as prose.  This is a completely
   different thing to reference documentation and I think it's important to not
   confuse the two.  There has been a bit of work adapting the “book” to be
   better in this sense, but it's not very far along.  Once it's there, it
   needs to be brought to the forefront, and the reference documentation put in
   a place where it's clear it's about details.  Optics matter.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;h3&gt;The Work&lt;/h3&gt;
&lt;p&gt;I'm sure there are countless things floating around in my mind I've forgotten
about at the moment, but that's all that comes to mind at a high level.  There
are, of course, countless little specific problems that need work (like
inventing a control protocol for everything, and having it be powerful but
pleasant to use), but I'm only focusing on the greater things about LV2 itself,
as a specification family and a project.  The big question, of course, is
whether LV3 should be a thing.  I am not sure, it's a hard question.  My
thinking is: maybe, but we should work towards it first.  It's always tempting
to throw out everything and Do It Right, but that never works out.  The
extensible nature of LV2 means that we can graft better things on over time,
until all the various pieces feel right.  I see no point in breaking the entire
world with a grandiose LV3 project until, for example, we've figured out how we
want to control plugins.  I am a big believer in iterative design, and working
code in general.  We can build that in LV2.  Maybe we can even do it and end up
at more or less LV3 anyway, without causing any hard breakage.  To that end, I
have been improving things in general, to try and address some of the above,
and generally bring the software up to a level of quality I am happy with:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;
&lt;p&gt;Portability: The LV2 host stack has (almost) always been at least
   theoretically portable, and relatively portable in practice, but it's
   obvious that it comes from the Linux world and &lt;em&gt;might&lt;/em&gt; work elsewhere.  I
   have been doing a lot of work on the DevOps front to ensure that everything
   works everywhere, always, and no platform is second-class.  The libraries
   live on Gitlab, and have a CI setup that builds and tests on Linux (both x86
   and ARM), Windows, and MacOS, and cross-compiles with MinGW.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Frequent releases: Another consequence of the many-libraries problem is that
   releasing is &lt;em&gt;really&lt;/em&gt; tedious, and I'm generally pretty bad at making
   releases.  This makes things just feel stale.  I've recently almost entirely
   automated this process, so that &lt;em&gt;everything&lt;/em&gt; involved in making a release
   can be done by just calling a script.  Also on the DevOps and stale fronts,
   I've been moving to automatically generating documentation on CI, so it's
   always published and up to date.  Automating everything is important to keep
   a project vibrant, especially when maintenance resources are scarce.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Generally complex APIs: The library APIs aren't great, and the general
   situation is confusing.  Most authors only need Lilv, but there are these
   “Serd” and “Sord” things in there that show up sometimes, all work with
   roughly the same sort of “nodes”, but all have different types and APIs for
   them, and so on.  I have been working on a new major version of serd that
   takes advantage of the API break to make things much simpler, and improve
   all kinds of things in general.  This will be exposed directly in lilv where
   it makes sense, eliminating a lot of glue, and eliminating the sord library
   entirely.  The lilv API itself is also dramatically bigger and more
   complicated than it needs to be.  At the time, it felt like adding obvious
   helper methods for every little thing was a good idea, so people can just
   find &lt;code&gt;lv2_port_get_specific_thing_I_want()&lt;/code&gt; which is nice when it's
   there... except it's not always there.  The property-based design of LV2
   means that &lt;code&gt;lv2_get(port, specific_thing_I_want)&lt;/code&gt; could work for everything
   (and this ability is already there).  This results in situations like people
   thinking they are blocked by a missing function, and spending a lot of time
   writing and submitting patches to add them, when the functionality was there
   all along.  It would be easier on everyone if everything just always worked
   the same general way, and it would make the API surface &lt;em&gt;much&lt;/em&gt; smaller which
   is always nice.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;Validation: There has been a data validator for a while, but it wasn't
   great.  It didn't, for example, point at the exact position in the file
   where the error was, you just had to figure that part out.  The new version
   of serd fixes this, so validation errors and warnings use standard GCC
   format to report the exact position along with a helpful error message,
   which automatically integrates with almost every editor or IDE on the planet
   for free.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;SDK: As mentioned above, I'm working on putting all the “standard” host
   libraries into a unified “lv2kit” which is the one package you will need to
   build LV2 things.  There are still some details about this I haven't sorted
   out (e.g. should the spec be in there or not?  What about non-LV2-specific
   libraries like serd?  Optional vendoring?), but it's coming along and I
   think will make it far more realistic to expect people to implement LV2.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;The spec mess: I am idly thinking about whether or not it would be possible
   to add a compatibility mechanism to allow us to move URIs without breaking
   anything.  It's largely superficial, but cleaning up the specification list
   would really help the optics of the project if nothing else.  90% here is
   trivial (just aggressively map everything forwards), but all the corner
   cases still need to be thought out.&lt;/p&gt;
&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;That's all the work in the trenches going on at the moment to improve the state
of LV2.  Though I wish I, or anyone else, had the time and energy to invest
effort into addressing the more ambitious questions around the plugin API
itself, at the moment I am more than tapped out.  Regardless, I think it makes
sense to get the current state of things in a form that is moving forward and
easier to work with, and raise the quality bar as high as possible first.  With
a very high-quality implementation and extensive testing and validation, I'll
feel a lot more confident in addressing some of the more interesting questions
around plugin interfaces, and perhaps someday moving towards an LV3.&lt;/p&gt;
&lt;p&gt;On that note, feedback is always welcome.  Most of the obvious criticism are
well-known, but more perspectives are always useful, and silent wheels get no
grease.  Better yet, issues and/or merge requests are even more welcome.  The
bus factor of LV2 isn't &lt;em&gt;quite&lt;/em&gt; as bad as it seems from the web, but it would
help to get more activity on the project itself from anyone other than myself.
The standards for API additions and such are pretty high, but there's plenty of
low-hanging fruit to be picked.&lt;/p&gt;</content><category term="misc"/><category term="LAD"/><category term="LV2"/></entry><entry><title>Jalv 1.6.4</title><link href="https://drobilla.net/2019/11/10/jalv-1-6-4.html" rel="alternate"/><published>2019-11-10T21:56:00-05:00</published><updated>2019-11-10T21:56:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2019-11-10:/2019/11/10/jalv-1-6-4.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/jalv-1.6.4.tar.bz2"&gt;Jalv 1.6.4&lt;/a&gt; has been released.  Jalv is a simple but fully featured LV2 host for Jack which exposes plugin ports to Jack, essentially making any LV2 plugin function as a Jack application. For more information, see &lt;a href="http://drobilla.net/software/jalv"&gt;http://drobilla.net/software/jalv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Support rdfs:label for port groups&lt;/li&gt;
&lt;li&gt;Use screen refresh rate with Gtk3 and Qt5&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Jalv"/></entry><entry><title>Lilv 0.24.6</title><link href="https://drobilla.net/2019/11/10/lilv-0-24-6.html" rel="alternate"/><published>2019-11-10T21:39:00-05:00</published><updated>2019-11-10T21:39:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2019-11-10:/2019/11/10/lilv-0-24-6.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/lilv-0.24.6.tar.bz2"&gt;Lilv 0.24.6&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add more strict error detection when storing plugin state properties&lt;/li&gt;
&lt;li&gt;Add option to override LV2_PATH in applications&lt;/li&gt;
&lt;li&gt;Don't print errors when saving state if correct links already exist&lt;/li&gt;
&lt;li&gt;Fix GCC8 warnings&lt;/li&gt;
&lt;li&gt;Fix creating directories across drives on Windows&lt;/li&gt;
&lt;li&gt;Fix issues with loading state with saved files from the model&lt;/li&gt;
&lt;li&gt;Fix memory errors and Python 3.4+ compatibility in Python bindings&lt;/li&gt;
&lt;li&gt;Fix unit tests on Windows&lt;/li&gt;
&lt;li&gt;Make Python bindings more Pythonic&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Suil 0.10.6</title><link href="https://drobilla.net/2019/11/10/suil-0-10-6.html" rel="alternate"/><published>2019-11-10T21:35:00-05:00</published><updated>2019-11-10T21:35:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2019-11-10:/2019/11/10/suil-0-10-6.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/suil-0.10.6.tar.bz2"&gt;Suil 0.10.6&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add no-cocoa configure flag&lt;/li&gt;
&lt;li&gt;Update build system&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Sratom 0.6.4</title><link href="https://drobilla.net/2019/11/10/sratom-0-6-4.html" rel="alternate"/><published>2019-11-10T21:20:00-05:00</published><updated>2019-11-10T21:20:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2019-11-10:/2019/11/10/sratom-0-6-4.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/sratom-0.6.4.tar.bz2"&gt;Sratom 0.6.4&lt;/a&gt; has been released.  Sratom is a small library for serialising LV2 atoms to and from RDF, for converting between binary and text or storing in a model.  For more information, see &lt;a href="http://drobilla.net/software/sratom"&gt;http://drobilla.net/software/sratom&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Make sratom_free() safe to call on NULL&lt;/li&gt;
&lt;li&gt;Various minor code cleanups&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>Jalv 1.6.2</title><link href="https://drobilla.net/2019/06/06/jalv-1-6-2.html" rel="alternate"/><published>2019-06-06T20:38:00-04:00</published><updated>2019-06-06T20:38:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2019-06-06:/2019/06/06/jalv-1-6-2.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/jalv-1.6.2.tar.bz2"&gt;Jalv 1.6.2&lt;/a&gt; has been released.  Jalv is a simple but fully featured LV2 host for Jack which exposes plugin ports to Jack, essentially making any LV2 plugin function as a Jack application. For more information, see &lt;a href="http://drobilla.net/software/jalv"&gt;http://drobilla.net/software/jalv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add jalv -i option to ignore stdin for background use&lt;/li&gt;
&lt;li&gt;Add several commands to console interface&lt;/li&gt;
&lt;li&gt;Add support for running as an internal Jack client (thanks Timo Wischer)&lt;/li&gt;
&lt;li&gt;Add support for underscore in port names on command line (thanks Jośe Fernando Moyano)&lt;/li&gt;
&lt;li&gt;Fix Jack deactivation&lt;/li&gt;
&lt;li&gt;Fix compilation with recent Gtkmm versions that require C++11&lt;/li&gt;
&lt;li&gt;Fix potential crash when closed with worker (thanks JP Cimalando)&lt;/li&gt;
&lt;li&gt;Fix potential hang after Ctrl-c in console interface (thanks Laxmi Devi)&lt;/li&gt;
&lt;li&gt;Make Suil dependency optional&lt;/li&gt;
&lt;li&gt;Remove support for deprecated event and uri-map extensions&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Jalv"/></entry><entry><title>Suil 0.10.4</title><link href="https://drobilla.net/2019/06/06/suil-0-10-4.html" rel="alternate"/><published>2019-06-06T19:02:00-04:00</published><updated>2019-06-06T19:02:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2019-06-06:/2019/06/06/suil-0-10-4.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/suil-0.10.4.tar.bz2"&gt;Suil 0.10.4&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add support for Qt5 in Gtk3&lt;/li&gt;
&lt;li&gt;Add support for min/base size hints for X11 in Gtk (thanks Hermann Meyer)&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Suil 0.10.2</title><link href="https://drobilla.net/2018/12/20/suil-0-10-2.html" rel="alternate"/><published>2018-12-20T17:22:00-05:00</published><updated>2018-12-20T17:22:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2018-12-20:/2018/12/20/suil-0-10-2.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/suil-0.10.2.tar.bz2"&gt;Suil 0.10.2&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add support for Cocoa in Qt5&lt;/li&gt;
&lt;li&gt;Fix resizing and add idle and update rate support for Qt5 in Gtk2&lt;/li&gt;
&lt;li&gt;Fix various issues with Qt5 in Gtk2&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Sratom 0.6.2</title><link href="https://drobilla.net/2018/07/22/sratom-0-6-2.html" rel="alternate"/><published>2018-07-22T18:48:00-04:00</published><updated>2018-07-22T18:48:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2018-07-22:/2018/07/22/sratom-0-6-2.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/sratom-0.6.2.tar.bz2"&gt;Sratom 0.6.2&lt;/a&gt; has been released.  Sratom is a small library for serialising LV2 atoms to and from RDF, for converting between binary and text or storing in a model.  For more information, see &lt;a href="http://drobilla.net/software/sratom"&gt;http://drobilla.net/software/sratom&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Various minor code cleanups&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>Lilv 0.24.4</title><link href="https://drobilla.net/2018/07/22/lilv-0-24-4.html" rel="alternate"/><published>2018-07-22T18:42:00-04:00</published><updated>2018-07-22T18:42:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2018-07-22:/2018/07/22/lilv-0-24-4.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/lilv-0.24.4.tar.bz2"&gt;Lilv 0.24.4&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don't attempt to load remote or non-Turtle files&lt;/li&gt;
&lt;li&gt;Fix saving state when broken links are encountered&lt;/li&gt;
&lt;li&gt;Gracefully handle plugins with missing binary URIs&lt;/li&gt;
&lt;li&gt;Install Python bindings when configured without tests (thanks Clement Skau)&lt;/li&gt;
&lt;li&gt;Remove use of deprecated readdir_r&lt;/li&gt;
&lt;li&gt;lv2apply: Activate plugin before running&lt;/li&gt;
&lt;li&gt;lv2apply: Use default values when they are not nan&lt;/li&gt;
&lt;li&gt;lv2bench: Improve support for plugins with sequence ports&lt;/li&gt;
&lt;li&gt;lv2bench: Support running a single plugin given on the command line&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Suil 0.10.0</title><link href="https://drobilla.net/2017/10/03/suil-0-10-0.html" rel="alternate"/><published>2017-10-03T20:11:00-04:00</published><updated>2017-10-03T20:11:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2017-10-03:/2017/10/03/suil-0-10-0.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/suil-0.10.0.tar.bz2"&gt;Suil 0.10.0&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add suil_init() to support early initialization and passing any necessary information that may be needed in the future (thanks Stefan Westerfeld)&lt;/li&gt;
&lt;li&gt;Add support for Qt5 in Gtk2&lt;/li&gt;
&lt;li&gt;Add support for X11 in Gtk3&lt;/li&gt;
&lt;li&gt;Fix building with X11 against custom LV2 install path (thanks Robin Gareus)&lt;/li&gt;
&lt;li&gt;Fix minor memory errors&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Jalv 1.6.0</title><link href="https://drobilla.net/2017/01/04/jalv-1-6-0.html" rel="alternate"/><published>2017-01-04T17:24:00-05:00</published><updated>2017-01-04T17:24:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2017-01-04:/2017/01/04/jalv-1-6-0.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/jalv-1.6.0.tar.bz2"&gt;Jalv 1.6.0&lt;/a&gt; has been released.  Jalv is a simple but fully featured LV2 host for Jack which exposes plugin ports to Jack, essentially making any LV2 plugin function as a Jack application. For more information, see &lt;a href="http://drobilla.net/software/jalv"&gt;http://drobilla.net/software/jalv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add PortAudio backend (compile time option, audio only)&lt;/li&gt;
&lt;li&gt;Add Qt5 version&lt;/li&gt;
&lt;li&gt;Add command prompt to console version for changing controls&lt;/li&gt;
&lt;li&gt;Add generic Qt control UI from Amadeus Folego&lt;/li&gt;
&lt;li&gt;Add option to print plugin trace messages&lt;/li&gt;
&lt;li&gt;Allow Jack client name to be set from command line (thanks Adam Avramov)&lt;/li&gt;
&lt;li&gt;Exit GUI versions on interrupt&lt;/li&gt;
&lt;li&gt;Exit on Jack shutdown (patch from Robin Gareus)&lt;/li&gt;
&lt;li&gt;Fix memory error on preset save resulting in odd bundle names&lt;/li&gt;
&lt;li&gt;Fix semaphore correctness issues&lt;/li&gt;
&lt;li&gt;Fix unreliable UI state initialization (patch from Hanspeter Portner)&lt;/li&gt;
&lt;li&gt;Improve preset support&lt;/li&gt;
&lt;li&gt;Print colorful log if output is a terminal&lt;/li&gt;
&lt;li&gt;Report Jack latency (patch from Robin Gareus)&lt;/li&gt;
&lt;li&gt;Set Jack port order metadata&lt;/li&gt;
&lt;li&gt;Support CV ports if Jack metadata is enabled (patch from Hanspeter Portner)&lt;/li&gt;
&lt;li&gt;Support numeric and string plugin properties (event-based control)&lt;/li&gt;
&lt;li&gt;Support thread-safe state restoration&lt;/li&gt;
&lt;li&gt;Update UI when internal plugin state is changed during preset load&lt;/li&gt;
&lt;li&gt;Use moc-qt4 if present for systems with multiple Qt versions&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Jalv"/></entry><entry><title>Lilv 0.24.2</title><link href="https://drobilla.net/2017/01/04/lilv-0-24-2.html" rel="alternate"/><published>2017-01-04T16:48:00-05:00</published><updated>2017-01-04T16:48:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2017-01-04:/2017/01/04/lilv-0-24-2.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/lilv-0.24.2.tar.bz2"&gt;Lilv 0.24.2&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix comparison of restored states with paths&lt;/li&gt;
&lt;li&gt;Fix saving state to paths that contain URI delimiters (#, ?, etc)&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Suil 0.8.4</title><link href="https://drobilla.net/2016/09/20/suil-0-8-4.html" rel="alternate"/><published>2016-09-20T02:47:00-04:00</published><updated>2016-09-20T02:47:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2016-09-20:/2016/09/20/suil-0-8-4.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/suil-0.8.4.tar.bz2"&gt;Suil 0.8.4&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add Cocoa in Gtk wrapper (patch from Robin Gareus)&lt;/li&gt;
&lt;li&gt;Add Gtk2 and X11 in Qt5 wrappers (patch from Rui Nuno Capela)&lt;/li&gt;
&lt;li&gt;Bubble X11 key events up to Gtk parent (patch from Filipe Coelho)&lt;/li&gt;
&lt;li&gt;Center X11 UIs in Gtk (patch from Robin Gareus)&lt;/li&gt;
&lt;li&gt;Configure based on compiler target OS for cross-compilation&lt;/li&gt;
&lt;li&gt;Fix a few minor/unlikely memory errors&lt;/li&gt;
&lt;li&gt;Fix compilation with -Wl,--no-undefined&lt;/li&gt;
&lt;li&gt;Fix initial size of resizable X11 UIs in Gtk (patch from Robin Gareus)&lt;/li&gt;
&lt;li&gt;Gracefully handle failure to open wrapper&lt;/li&gt;
&lt;li&gt;Only report suil_ui_supported() if necessary wrapper is compiled in&lt;/li&gt;
&lt;li&gt;Upgrade to waf 1.8.14&lt;/li&gt;
&lt;li&gt;Various Windows fixes (patches from Robin Gareus)&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Sratom 0.6.0</title><link href="https://drobilla.net/2016/09/20/sratom-0-6-0.html" rel="alternate"/><published>2016-09-20T02:25:00-04:00</published><updated>2016-09-20T02:25:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2016-09-20:/2016/09/20/sratom-0-6-0.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/sratom-0.6.0.tar.bz2"&gt;Sratom 0.6.0&lt;/a&gt; has been released.  Sratom is a small library for serialising LV2 atoms to and from RDF, for converting between binary and text or storing in a model.  For more information, see &lt;a href="http://drobilla.net/software/sratom"&gt;http://drobilla.net/software/sratom&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add sratom_set_env() for setting prefixes&lt;/li&gt;
&lt;li&gt;Fix padding of constructed vectors (thanks Hanspeter Portner)&lt;/li&gt;
&lt;li&gt;Fix warnings when building with ISO C++ compilers&lt;/li&gt;
&lt;li&gt;Support round-trip serialisation of relative paths&lt;/li&gt;
&lt;li&gt;Support sequences with beat time stamps&lt;/li&gt;
&lt;li&gt;Upgrade to waf 1.8.14&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>Lilv 0.24.0</title><link href="https://drobilla.net/2016/09/20/lilv-0-24-0.html" rel="alternate"/><published>2016-09-20T02:24:00-04:00</published><updated>2016-09-20T02:24:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2016-09-20:/2016/09/20/lilv-0-24-0.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/lilv-0.24.0.tar.bz2"&gt;Lilv 0.24.0&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add LILV_URI_ATOM_PORT and LILV_URI_CV_PORT defines&lt;/li&gt;
&lt;li&gt;Add lilv_state_set_metadata() for adding state banks/comments/etc (based on patch from Hanspeter Portner)&lt;/li&gt;
&lt;li&gt;Add lilv_world_get_symbol()&lt;/li&gt;
&lt;li&gt;Add lv2apply utility for applying plugins to audio files&lt;/li&gt;
&lt;li&gt;Add new hand-crafted Pythonic bindings with full test coverage&lt;/li&gt;
&lt;li&gt;Check lv2:binary predicate for UIs&lt;/li&gt;
&lt;li&gt;Do not instantiate plugin when data fails to parse&lt;/li&gt;
&lt;li&gt;Fix crash when NULL predicate is passed to lilv_world_find_nodes()&lt;/li&gt;
&lt;li&gt;Fix crash when state contains non-POD properties&lt;/li&gt;
&lt;li&gt;Fix documentation installation&lt;/li&gt;
&lt;li&gt;Fix loading dyn-manifest from bundles with spaces in their path&lt;/li&gt;
&lt;li&gt;Fix outdated comment references to lilv_uri_to_path()&lt;/li&gt;
&lt;li&gt;Fix state file versioning&lt;/li&gt;
&lt;li&gt;Replace bundles if bundle with newer plugin version is loaded (based on patch from Robin Gareus)&lt;/li&gt;
&lt;li&gt;Support re-loading plugins&lt;/li&gt;
&lt;li&gt;Unload contained resources when bundle is unloaded&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Git migration</title><link href="https://drobilla.net/2015/11/14/git-migration.html" rel="alternate"/><published>2015-11-14T16:46:00-05:00</published><updated>2015-11-14T16:46:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2015-11-14:/2015/11/14/git-migration.html</id><content type="html">&lt;p&gt;I have finally migrated all of my software to git. This was not a very
fun process due to the nested nature of my “drobillad” repository, but
now all projects live in their own git repositories with history and
tags from SVN preserved.&lt;/p&gt;
&lt;p&gt;It is still possible to build all my audio software in one step, the
top-level repository &lt;a href="http://git.drobilla.net/drobillad.git"&gt;http://git.drobilla.net/drobillad.git&lt;/a&gt; is now a
skeleton with git submodules for each project. Anyone using SVN should
switch immediately, the SVN repositories will remain in their current
state for the foreseeable future but all development activity will move
to git.&lt;/p&gt;
&lt;p&gt;All the repositories are available in &lt;a href="http://git.drobilla.net/"&gt;cgit&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;[Edited on 2025-02-16 to remove broken links]&lt;/p&gt;</content><category term="misc"/><category term="Hacking"/><category term="LAD"/><category term="LV2"/></entry><entry><title>Lilv 0.22.0</title><link href="https://drobilla.net/2015/10/08/lilv-0-22-0.html" rel="alternate"/><published>2015-10-08T19:39:00-04:00</published><updated>2015-10-08T19:39:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2015-10-08:/2015/10/08/lilv-0-22-0.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/lilv-0.22.0.tar.bz2"&gt;Lilv 0.22.0&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add lilv_file_uri_parse() for correct URI to path conversion&lt;/li&gt;
&lt;li&gt;Add lilv_free() for systems picky about such things&lt;/li&gt;
&lt;li&gt;Add lilv_node_get_path() for convenient file URI path access&lt;/li&gt;
&lt;li&gt;Add lilv_state_delete() for deleting user saved presets&lt;/li&gt;
&lt;li&gt;Add lilv_state_emit_port_values() for special port value handling&lt;/li&gt;
&lt;li&gt;Add lilv_state_get_uri()&lt;/li&gt;
&lt;li&gt;Configure based on compiler target OS for cross-compilation&lt;/li&gt;
&lt;li&gt;Expose lilv_world_load_specifications() and lilv_world_load_plugin_classes()&lt;/li&gt;
&lt;li&gt;Fix a few minor/unlikely memory errors&lt;/li&gt;
&lt;li&gt;Fix bindings for Python 3&lt;/li&gt;
&lt;li&gt;Fix creation of duplicate manifest entries when saving state&lt;/li&gt;
&lt;li&gt;Fix directory walking on some systems (thanks Matt Fischer)&lt;/li&gt;
&lt;li&gt;Fix lilv_realpath() on pre-POSIX-2008 systems&lt;/li&gt;
&lt;li&gt;Fix lilv_world_ask() to work with wildcards&lt;/li&gt;
&lt;li&gt;Fix loading files with spaces in their path&lt;/li&gt;
&lt;li&gt;Load discovered owl ontologies as specifications&lt;/li&gt;
&lt;li&gt;Minor documentation improvements&lt;/li&gt;
&lt;li&gt;Preserve absolute paths in state if no link directory is given&lt;/li&gt;
&lt;li&gt;Tolerate passing NULL to lilv_state_restore()&lt;/li&gt;
&lt;li&gt;Upgrade to waf 1.8.14&lt;/li&gt;
&lt;li&gt;Windows fixes (thanks John Emmas)&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>LV2 Plugin Control Units in Ardour</title><link href="https://drobilla.net/2014/11/03/lv2-plugin-control-units-in-ardour.html" rel="alternate"/><published>2014-11-03T20:09:00-05:00</published><updated>2014-11-03T20:09:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-11-03:/2014/11/03/lv2-plugin-control-units-in-ardour.html</id><content type="html">&lt;p&gt;LV2 has had a “units” extension since the beginning, which allows
plugins to specify units like Hz or dB for their controls. To date this
information has not been used very widely by hosts, so I've done some
work in Ardour to use this information for better UI generation and
intelligent plugin control.&lt;/p&gt;
&lt;p&gt;Units can specify a format string which describes how to print a value
in that unit. This is now used to draw the text on control sliders:&lt;/p&gt;
&lt;p&gt;&lt;img alt="An Ardour control dialog for an LV2 plugin." src="/images/control_dialog-300x152.png"&gt;&lt;/p&gt;
&lt;p&gt;The same controls are used in automation lane headers. If the control is
a note number, then right-clicking will present a menu with an option to
pop up a note selector dialog where the value can be chosen on a piano
keyboard:&lt;/p&gt;
&lt;p&gt;&lt;img alt="The select note menu on a note number port." src="/images/select_note_menu-300x286.png"&gt;&lt;/p&gt;
&lt;p&gt;&lt;img alt="The Ardour note selector dialog." src="/images/note_choose_dialog-300x51.png"&gt;&lt;/p&gt;
&lt;p&gt;Similarly, numeric frequency controls have a context menu which can set
the value to a specific number of beats in the current tempo, if the
frequency range is low:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Setting a low frequency port in beats." src="/images/set_beats_menu-272x300.png"&gt;&lt;/p&gt;
&lt;p&gt;If the frequency range is high, then numeric frequency ports can be set
with the note selector dialog just like note numbers:&lt;/p&gt;
&lt;p&gt;&lt;img alt="Setting an audible frequency port by note." src="/images/set_freq_menu-300x83.png"&gt;&lt;/p&gt;
&lt;p&gt;In the future, it would be nice to have this idea applied more
extensively so automation lanes can “pretend” a port is in the desired
unit, for example allowing the user to automate an LFO frequency in
beats, or a cutoff frequency in notes. Until then, being able to at
least easily set controls to musically sensible values makes many
production tasks easier, particularly in electronic music where it's
often desirable to set plugin controls based on key or tempo.&lt;/p&gt;
&lt;p&gt;Up next is setting time ports based on tempo, for cases like setting
delay lines to a certain number of beats, but many plugins are missing
the unit information required to make this possible. Hopefully better
and more widespread host support will provide some incentive for plugin
authors to specify the units of their ports. It is very simple to do so,
see the &lt;a href="http://lv2plug.in/ns/extensions/units"&gt;LV2 units&lt;/a&gt; documentation
for examples.&lt;/p&gt;</content><category term="misc"/><category term="Ardour"/><category term="Hacking"/><category term="LAD"/><category term="LV2"/></entry><entry><title>Jalv 1.4.6</title><link href="https://drobilla.net/2014/08/08/jalv-1-4-6.html" rel="alternate"/><published>2014-08-08T22:30:00-04:00</published><updated>2014-08-08T22:30:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-08-08:/2014/08/08/jalv-1-4-6.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/jalv-1.4.6.tar.bz2"&gt;Jalv 1.4.6&lt;/a&gt; has been released.  Jalv is a simple but fully featured LV2 host for Jack which exposes plugin ports to Jack, essentially making any LV2 plugin function as a Jack application. For more information, see &lt;a href="http://drobilla.net/software/jalv"&gt;http://drobilla.net/software/jalv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add option to print control output changes to stdout&lt;/li&gt;
&lt;li&gt;Add support for data-access extension (based on patch by Filipe Coelho)&lt;/li&gt;
&lt;li&gt;Generate Qt moc nonsense at build time for broader compatibility&lt;/li&gt;
&lt;li&gt;Set port pretty names via new Jack metadata API&lt;/li&gt;
&lt;li&gt;Show newly saved presets in the preset menu&lt;/li&gt;
&lt;li&gt;Support new UI show/hide interface in console version&lt;/li&gt;
&lt;li&gt;Support saving the same preset several times&lt;/li&gt;
&lt;li&gt;Update for latest LV2 Atom Object simplifications&lt;/li&gt;
&lt;li&gt;Update man pages and console jalv help output for new options&lt;/li&gt;
&lt;li&gt;Upgrade to waf 1.7.16&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Jalv"/></entry><entry><title>Ganv 1.4.2</title><link href="https://drobilla.net/2014/08/08/ganv-1-4-2.html" rel="alternate"/><published>2014-08-08T22:24:00-04:00</published><updated>2014-08-08T22:24:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-08-08:/2014/08/08/ganv-1-4-2.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/ganv-1.4.2.tar.bz2"&gt;Ganv 1.4.2&lt;/a&gt; has been released.  Ganv is an interactive Gtk canvas widget for graph-based interfaces (patchers, modular synthesizers, finite state automata, interactive graphs, etc). For more information, see &lt;a href="http://drobilla.net/software/ganv"&gt;http://drobilla.net/software/ganv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Fix bug where edges would not update when nodes are moved after the canvas is cleared (fix stuck connections in Patchage after refresh).&lt;/li&gt;
&lt;li&gt;Upgrade to waf 1.7.16&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="Ganv"/></entry><entry><title>Lilv 0.20.0</title><link href="https://drobilla.net/2014/08/08/lilv-0-20-0.html" rel="alternate"/><published>2014-08-08T22:21:00-04:00</published><updated>2014-08-08T22:21:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-08-08:/2014/08/08/lilv-0-20-0.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/lilv-0.20.0.tar.bz2"&gt;Lilv 0.20.0&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add convenient lilv_new_file_uri for creating file URIs&lt;/li&gt;
&lt;li&gt;Add lilv_world_unload_bundle() and lilv_world_unload_resource()&lt;/li&gt;
&lt;li&gt;Call lv2_lib_descriptor separately for different bundle paths (fix loading several dynamic plugins like Ingen at once)&lt;/li&gt;
&lt;li&gt;Don't load files multiple times if they are listed as rdfs:seeAlso for several plugins&lt;/li&gt;
&lt;li&gt;Fix issues with lilv_plugin_get_author_name and friends (thanks Filipe Coelho)&lt;/li&gt;
&lt;li&gt;Fix several minor memory leaks&lt;/li&gt;
&lt;li&gt;Fix use of lv2info -m and -p options to write plugin data (useful for porting plugins bridges with NASPRO)&lt;/li&gt;
&lt;li&gt;Improve test coverage&lt;/li&gt;
&lt;li&gt;Improved/working lv2_apply.py to apply plugin to a .wav (thanks Joe Button)&lt;/li&gt;
&lt;li&gt;Tolerate calling lilv_node_as_uri or lilv_node_as_blank on NULL&lt;/li&gt;
&lt;li&gt;Upgrade to waf 1.7.16&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Suil 0.8.2</title><link href="https://drobilla.net/2014/08/08/suil-0-8-2.html" rel="alternate"/><published>2014-08-08T22:18:00-04:00</published><updated>2014-08-08T22:18:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-08-08:/2014/08/08/suil-0-8-2.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/suil-0.8.2.tar.bz2"&gt;Suil 0.8.2&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add configure options to disable all Gtk or Qt support&lt;/li&gt;
&lt;li&gt;Fix embedding several Qt UIs in Gtk&lt;/li&gt;
&lt;li&gt;Upgrade to waf 1.7.16&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Sratom 0.4.6</title><link href="https://drobilla.net/2014/08/08/sratom-0-4-6.html" rel="alternate"/><published>2014-08-08T22:14:00-04:00</published><updated>2014-08-08T22:14:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-08-08:/2014/08/08/sratom-0-4-6.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/sratom-0.4.6.tar.bz2"&gt;Sratom 0.4.6&lt;/a&gt; has been released.  Sratom is a small library for serialising LV2 atoms to and from RDF, for converting between binary and text or storing in a model.  For more information, see &lt;a href="http://drobilla.net/software/sratom"&gt;http://drobilla.net/software/sratom&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Don't set eg prefix in sratom_to_turtle&lt;/li&gt;
&lt;li&gt;Update for latest LV2 Atom Object simplification&lt;/li&gt;
&lt;li&gt;Upgrade to waf 1.7.16&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>Patchage 1.0.0</title><link href="https://drobilla.net/2014/04/28/patchage-1-0-0.html" rel="alternate"/><published>2014-04-28T03:46:00-04:00</published><updated>2014-04-28T03:46:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-04-28:/2014/04/28/patchage-1-0-0.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/patchage-1.0.0.tar.bz2"&gt;Patchage 1.0.0&lt;/a&gt; has been released.  Patchage is a modular patch bay for Jack and ALSA based audio/MIDI systems.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Allow removing connections by selecting their handle and pressing delete&lt;/li&gt;
&lt;li&gt;Fix font configuration on OSX&lt;/li&gt;
&lt;li&gt;Integrate with Mac menu bar on OSX&lt;/li&gt;
&lt;li&gt;Make port colours configurable&lt;/li&gt;
&lt;li&gt;Remove LASH support and simplify UI&lt;/li&gt;
&lt;li&gt;Remove Raul dependency&lt;/li&gt;
&lt;li&gt;Support for DOT export for rendering with GraphViz&lt;/li&gt;
&lt;li&gt;Support port pretty names via new Jack metadata API&lt;/li&gt;
&lt;li&gt;Switch from FlowCanvas to Ganv (much improved looks and performance)&lt;/li&gt;
&lt;li&gt;Use Mac style key bindings on OSX&lt;/li&gt;
&lt;li&gt;Use XDG_CONFIG_HOME instead of ~/.patchagerc&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="Patchage"/></entry><entry><title>Ganv 1.4.0</title><link href="https://drobilla.net/2014/04/28/ganv-1-4-0.html" rel="alternate"/><published>2014-04-28T03:44:00-04:00</published><updated>2014-04-28T03:44:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-04-28:/2014/04/28/ganv-1-4-0.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/ganv-1.4.0.tar.bz2"&gt;Ganv 1.4.0&lt;/a&gt; has been released.  Ganv is an interactive Gtk canvas widget for graph-based interfaces (patchers, modular synthesizers, finite state automata, interactive graphs, etc). For more information, see &lt;a href="http://drobilla.net/software/ganv"&gt;http://drobilla.net/software/ganv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add Connection::set_curved()&lt;/li&gt;
&lt;li&gt;Add ability to select connections by their handles, either individually or in groups with rect select.&lt;/li&gt;
&lt;li&gt;Add ability to select connections directly&lt;/li&gt;
&lt;li&gt;Add font size API&lt;/li&gt;
&lt;li&gt;Adjust padding and placement to precisely fit text&lt;/li&gt;
&lt;li&gt;Begin using library and pkg-config names suitable for parallel installation.  This version of flowcanvas is flowcanvas-1 and is NOT compatible with previous versions&lt;/li&gt;
&lt;li&gt;Clean up API and improve documentation.&lt;/li&gt;
&lt;li&gt;Clean up API/ABI by hiding private implementations.&lt;/li&gt;
&lt;li&gt;Dramatically increase performance by rendering text manually rather than using the truly awful Gnome::Canvas::Text.&lt;/li&gt;
&lt;li&gt;Fix lingering handle when deleting connections&lt;/li&gt;
&lt;li&gt;Further slight improvements in memory consumption and alignment.&lt;/li&gt;
&lt;li&gt;Improve scalability to graphs with many connections (eliminate linear connection searches and redundant connection collections).&lt;/li&gt;
&lt;li&gt;Remove use of boost smart pointers.  Adding and removing from containers (e.g. Canvas, Module) is now done automatically.&lt;/li&gt;
&lt;li&gt;Size empty ports in font based units so they look right when zoomed&lt;/li&gt;
&lt;li&gt;Switch to GPLv3+&lt;/li&gt;
&lt;li&gt;Use system theme font size by default&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="Ganv"/></entry><entry><title>Pretty names in Patchage via Jack Metadata</title><link href="https://drobilla.net/2014/04/09/pretty-names-in-patchage-via-jack-metadata.html" rel="alternate"/><published>2014-04-09T21:26:00-04:00</published><updated>2014-04-09T21:26:00-04:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-04-09:/2014/04/09/pretty-names-in-patchage-via-jack-metadata.html</id><content type="html">&lt;p&gt;The much-awaited (by me, at least) Jack metadata API has arrived. This
will allow us to easily achieve many new things with minimal/nonexistent
API friction. One of the simplest and most obvious is pretty names for
Jack clients and ports, so I've chosen this as the first thing to tackle
(as part of a drive to get Patchage polished up for a much overdue
release).&lt;/p&gt;
&lt;p&gt;Unfortunately, as far as I can tell, there is a chicken &amp;amp; egg scenario
here since nothing is setting this metadata yet. So, I've made Jalv and
Ingen both set pretty names for their ports. In the case of Jalv, the
“pretty name” is the label given in the plugin data (distinct from the
LV2 “symbol” which is restricted and unique).&lt;/p&gt;
&lt;p&gt;Firing up Jalv with the Tal Dub III plugin (LV2 port courtesy KXStudio),
we can see the port symbols, which are a bit awkward for end users with
their prefixes and underscores. Conflating strong identifiers with
human-readable labels is a serious design error I learned of the hard
way, but that's a discussion for another time...&lt;/p&gt;
&lt;p&gt;Enable “Human Names” in the view menu, or press C-h, and voilà, we see
the pretty names set in Jack metadata (if present) instead.&lt;/p&gt;
&lt;p&gt;&lt;a href="/images/patchage_symbols.png"&gt;&lt;img alt="Tal Dub III in Jalv as shown by Patchage with human names off." src="/images/patchage_symbols.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="/images/patchage_human_names.png"&gt;&lt;img alt="Tal Dub III in Jalv as shown by Patchage with human names enabled." src="/images/patchage_human_names.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;The metadata API is very simple to use for ports, though there seems to
be a hole in the API which makes it difficult to get the UUID for your
client to set metadata (I want a simple jack_client_uuid, like
jack_port_uuid, but it seems you have to get a string UUID and parse
it to a jack_uuid_t, clunky enough that I just didn't bother). In any
case, I am happy to see a low-friction mechanism in Jack which apps can
use to share metadata towards making a better user experience.&lt;/p&gt;
&lt;p&gt;It will be interesting to see what sort of information proves useful and
becomes established/standard. For those of us of a mad scientist bent
who live in a nest of patch cables, a CV tag seems like another obvious
simple step, but for everyone, a big step is finally having meaningful
port grouping and channel roles. I have always liked to joke that Jack
(like LADSPA) doesn't &lt;em&gt;really&lt;/em&gt; even do stereo, but with metadata, we can
mark up stereo, 5.1, Ambisonics, etc., and other clients will be able to
make sense of the channel assignments without resorting to dirty kludges
based on guessing from names. All without changing the ABI one bit. Good
stuff.&lt;/p&gt;</content><category term="misc"/><category term="Hacking"/><category term="LAD"/></entry><entry><title>Labeled MIDI controller values in Ardour</title><link href="https://drobilla.net/2014/01/06/labeled-midi-controller-values-in-ardour.html" rel="alternate"/><published>2014-01-06T17:09:00-05:00</published><updated>2014-01-06T17:09:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-01-06:/2014/01/06/labeled-midi-controller-values-in-ardour.html</id><content type="html">&lt;p&gt;A while ago, I implemented &lt;a href="/2013/01/20/ardour-midi-patch-controller-and-note-names.html"&gt;MIDI patch, controller, and note name
support for
Ardour&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;There was one thing missing from that work: labelled controller values.
This is particularly useful for controllers that don't represent a
continuous numeric parameter, but instead have a set of specific values.
For example, the Moog Minitaur supports CC #86 to control the LFO sync
clock division, but it's not obvious how a 0-127 number maps to a clock
division. From the manual, we can learn that 61-67 is “1/4”, 68-73 is
“1/8 Dot”, and so on.&lt;/p&gt;
&lt;p&gt;Translate that information into standard MIDINameDocument format, and a
few hours of hacking later... voila, Ardour displays something sensible
when hovering over an automation point instead of a meaningless number.&lt;/p&gt;
&lt;p&gt;&lt;a href="/images/ardour_midi_cc_cursor.png"&gt;&lt;img alt="Ardour displaying a labelled MIDI controller value when hovering over an automation point." src="/images/ardour_midi_cc_cursor-150x85.png"&gt;&lt;/a&gt;&lt;/p&gt;
&lt;p&gt;If you want to add support for your MIDI device or program, my .midnam
documents for the Moog Minitaur, MF-104M, and MF-108M, included in the
Ardour distribution all contain examples of labelled values. It should
be relatively obvious how to copy and modify these for other devices.&lt;/p&gt;</content><category term="misc"/><category term="Ardour"/><category term="Hacking"/><category term="LAD"/></entry><entry><title>Jalv 1.4.4</title><link href="https://drobilla.net/2014/01/04/jalv-1-4-4.html" rel="alternate"/><published>2014-01-04T21:11:00-05:00</published><updated>2014-01-04T21:11:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-01-04:/2014/01/04/jalv-1-4-4.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/jalv-1.4.4.tar.bz2"&gt;Jalv 1.4.4&lt;/a&gt; has been released.  Jalv is a simple but fully featured LV2 host for Jack which exposes plugin ports to Jack, essentially making any LV2 plugin function as a Jack application. For more information, see &lt;a href="http://drobilla.net/software/jalv"&gt;http://drobilla.net/software/jalv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add --no-menu option for jalv.gtk&lt;/li&gt;
&lt;li&gt;Add -c option for setting controls from the command line&lt;/li&gt;
&lt;li&gt;Don't expose non-MIDI event ports to Jack&lt;/li&gt;
&lt;li&gt;Hide controls for ports with notOnGUI property in generic UI (based on patch from Robin Gareus)&lt;/li&gt;
&lt;li&gt;Preset menu support for Qt (patch from Timo Westkämper)&lt;/li&gt;
&lt;li&gt;Support ui:portMap feature to allow UIs to avoid hard-coded port indices (useful for compatibility and separately distributed UIs)&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Jalv"/></entry><entry><title>Sratom 0.4.4</title><link href="https://drobilla.net/2014/01/04/sratom-0-4-4.html" rel="alternate"/><published>2014-01-04T21:09:00-05:00</published><updated>2014-01-04T21:09:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-01-04:/2014/01/04/sratom-0-4-4.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/sratom-0.4.4.tar.bz2"&gt;Sratom 0.4.4&lt;/a&gt; has been released.  Sratom is a small library for serialising LV2 atoms to and from RDF, for converting between binary and text or storing in a model.  For more information, see &lt;a href="http://drobilla.net/software/sratom"&gt;http://drobilla.net/software/sratom&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Escape invalid characters when writing paths as URIs&lt;/li&gt;
&lt;li&gt;Fancier printing without subject and predicate&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="RDF"/><category term="Sratom"/></entry><entry><title>Lilv 0.18.0</title><link href="https://drobilla.net/2014/01/04/lilv-0-18-0.html" rel="alternate"/><published>2014-01-04T21:06:00-05:00</published><updated>2014-01-04T21:06:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-01-04:/2014/01/04/lilv-0-18-0.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/lilv-0.18.0.tar.bz2"&gt;Lilv 0.18.0&lt;/a&gt; has been released.  Lilv is a C library to make the use of LV2 plugins as simple as possible for applications. For more information, see &lt;a href="http://drobilla.net/software/lilv"&gt;http://drobilla.net/software/lilv&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add lilv_port_get_node() for using world query functions with ports&lt;/li&gt;
&lt;li&gt;Add support for running plugins from Python by Kaspar Emanuel&lt;/li&gt;
&lt;li&gt;Allow lilv_state_restore() to be used without passing an instance, for restoring port values via a callback only&lt;/li&gt;
&lt;li&gt;Allow passing NULL port_class to lilv_plugin_get_port_by_designation&lt;/li&gt;
&lt;li&gt;Call GetProcAddress with correct calling convention on Windows&lt;/li&gt;
&lt;li&gt;Clean up after test suite so multiple runs are successful&lt;/li&gt;
&lt;li&gt;Fix unlikely memory leak in lilv_plugin_instantiate()&lt;/li&gt;
&lt;li&gt;Support denoting latency ports with lv2:designation lv2:latency&lt;/li&gt;
&lt;li&gt;lilvmm.hpp: Add wrappers for UI API&lt;/li&gt;
&lt;li&gt;lv2info: Don't display invalid control maxes and defaults (patch from Robin Gareus)&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Lilv"/></entry><entry><title>Suil 0.8.0</title><link href="https://drobilla.net/2014/01/04/suil-0-8-0.html" rel="alternate"/><published>2014-01-04T21:06:00-05:00</published><updated>2014-01-04T21:06:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2014-01-04:/2014/01/04/suil-0-8-0.html</id><content type="html">&lt;p&gt;&lt;a href="//download.drobilla.net/suil-0.8.0.tar.bz2"&gt;Suil 0.8.0&lt;/a&gt; has been released.  Suil is a library for loading and wrapping LV2 plugin UIs. For more information, see &lt;a href="http://drobilla.net/software/suil"&gt;http://drobilla.net/software/suil&lt;/a&gt;.&lt;/p&gt;
&lt;p&gt;Changes:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Add suil_instance_get_handle (patch from Rui Nuno Capela)&lt;/li&gt;
&lt;li&gt;Fix compilation errors on some systems&lt;/li&gt;
&lt;li&gt;Upgrade to waf 1.7.14&lt;/li&gt;
&lt;/ul&gt;</content><category term="misc"/><category term="Software"/><category term="LAD"/><category term="LV2"/><category term="Suil"/></entry><entry><title>Interactive Force-Directed Graph Layout in Ingen</title><link href="https://drobilla.net/2013/12/20/interactive-force-directed-graph-layout-in-ingen.html" rel="alternate"/><published>2013-12-20T00:51:00-05:00</published><updated>2013-12-20T00:51:00-05:00</updated><author><name>drobilla</name></author><id>tag:drobilla.net,2013-12-20:/2013/12/20/interactive-force-directed-graph-layout-in-ingen.html</id><content type="html">&lt;p&gt;GraphViz has, unfortunately, broken reverse compatibility of their
library API, which has been nagging as a maintenance headache for
FlowCanvas and its successor
&lt;a href="/software/ganv"&gt;Ganv&lt;/a&gt; for a while now. It would be
nice to just get rid of that dependency altogether...&lt;/p&gt;
&lt;p&gt;Meanwhile, I had to write some force-directed graph layout (FDGL) code
for another project...&lt;/p&gt;
&lt;p&gt;... You can probably see where this is going. In the spirit of it
theoretically being a holiday (there are no holidays in practice in grad
school), I spent some time implementing live FDGL in Ganv, and recorded
a &lt;a href="/videos/ganv_fdgl.ogv"&gt;video of interactive layout in Ingen&lt;/a&gt;
to show progress.&lt;/p&gt;
&lt;p&gt;One nice thing about using live FDGL in a program like
&lt;a href="/software/ingen"&gt;Ingen&lt;/a&gt; is that the user can
customize the layout in an intuitive tactile way, since objects behave
physical laws. This video demonstrates some manual rearranging of a
patch, and a total reconfiguration by switching the signal flow
direction. Manual tweaking of the layout like this was not possible with
the previous GraphViz-based layout code.&lt;/p&gt;
&lt;p&gt;It took quite a bit of tweaking to get the physics working well, so
layouts looked good but the patch didn't explode if there are
disconnected components. It's still not quite ideal, but usable.&lt;/p&gt;
&lt;p&gt;This is implemented at the Ganv level and thus works in Ingen (as
shown), Patchage, and Machina. I'm still not confident enough in this
implementation to enable it by default and/or drop Graphviz quite yet,
but the adventurous who follow svn, &lt;code&gt;./waf configure --debug --fdgl&lt;/code&gt;. If
you're hit by the graphviz breakage (and I still haven't fixed the
check...), add &lt;code&gt;--no-graphviz&lt;/code&gt; to work around the problem.&lt;/p&gt;
&lt;p&gt;[Edited on 2025-02-16 to remove broken link]&lt;/p&gt;</content><category term="misc"/><category term="Hacking"/><category term="LAD"/></entry></feed>