Giter Site home page Giter Site logo

lilv's Introduction

LV2

LV2 is a plugin standard for audio systems. It defines an extensible C API for plugins, and a format for self-contained "bundle" directories that contain plugins, metadata, and other resources. See http://lv2plug.in/ for more information.

This package contains specifications (C headers and Turtle data files), documentation generation tools, tests, and example plugins.

Installation

See the installation instructions for details on how to configure, build, and install LV2 with meson.

By default, on UNIX-like systems, everything is installed within the prefix, and LV2 bundles are installed in the "lv2" subdirectory of the libdir. On other systems, bundles are installed by default to the standard location for plugins on the system. The bundle installation directory can be overridden with the lv2dir option.

The specification bundles are run-time dependencies of LV2 applications. Programs expect their data to be available somewhere in LV2_PATH. See http://lv2plug.in/pages/filesystem-hierarchy-standard.html for details on the standard installation paths.

Headers

The lv2/ include namespace is reserved for this LV2 distribution. Other projects may extend LV2, but must place their headers elsewhere.

Headers are installed to includedir with paths like:

#include "lv2/urid/urid.h"

For backwards compatibility, if the old_headers option is set, then headers are also installed to the older URI-based paths:

#include "lv2/lv2plug.in/ns/ext/urid/urid.h"

Projects still using this style are encourated to migrate to the shorter style above.

lilv's People

Contributors

alex-tee avatar drobilla avatar giuliomoro avatar grejppi avatar rncbc avatar spotlightkid avatar ventosus avatar x42 avatar zadagu avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar

lilv's Issues

Connect audio files and/or JACK ports to a plug-in using the Python binding

Hi David,

I've built the latest lilv bindings for Python3 to experiment a little with it.
Things start to take place in my mind, but I'm stuck since I can't understand how to connect a plugin audio input/output ports to the outside world.

In the example below, I would like to connect the ports 0 and 1 to the audio file /tmp/test.wav and the ports 2 and 3 to the system's playback_1 and playback_2 JACK ports. Is it possible? And if it is, how?

>>> import lilv
>>> [calfrev] = [p for p in world.get_all_plugins() if p.get_name() == 'Calf Reverb']
>>> for idx in range(0, 16): print(idx, calfrev.get_port(idx).get_name())
... 
0 In L
1 In R
2 Out L
3 Out R
4 0dB
5 Wet amount
6 Output
7 Decay time
8 High Frq Damp
9 Room size
10 Diffusion
11 Wet Amount
12 Dry Amount
13 Pre Delay
14 Bass Cut
15 Treble Cut
>>> instance = lilv.Instance(calfrev, 48000)
>>> instance.connect_port(0, ... <<- I'm stuck here

State store function allows null and duplicate keys

The LV2_State_Store_Function does not analyze the type of the value.
Trying to submit an Atom:Object to it results into corrupted *.ttl file.

Code snippet:

LV2_Atom_Forge forge;
LV2_State_Store_Function hStore;
LV2_URID_Map *map;
const char *path = "/home/sadko/eclipse/lsp-plugins/res/test/3d/devel-room.obj";
                
    LV2_State_Status lv2_save_state(
        LV2_Handle                 instance,
        LV2_State_Store_Function   hStore,
        LV2_State_Handle           handle,
        uint32_t                   flags,
        const LV2_Feature *const * features)
    {

                LV2_Atom *msg       = lv2_atom_forge_object(&forge, &frame, 0, map->map(map->handle, "http://lsp-plug.in/types/lv2/types#KVT"));
                lv2_atom_forge_key(&forge, map->map(map->handle, "http://lsp-plug.in/kvt/scene/selected"));
                lv2_atom_forge_int(&forge, int32_t(0));
                lv2_atom_forge_key(&forge, map->map(map->handle, "http://lsp-plug.in/kvt/scene/objects"));
                lv2_atom_forge_int(&forge, int32_t(0));
                lv2_atom_forge_key(&forge, map->map(map->handle, "http://lsp-plug.in/kvt/scene/object/0/enabled"));
                lv2_atom_forge_float(&forge, 1.0f);
                lv2_atom_forge_pop(&forge, &frame);
                hStore(handle, 0, &msg[1], msg->size, forge.Object, LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);

                hStore(handle, map->map(map->handle, "http://lsp-plug.in/plugins/lv2/room_builder_mono/ports#ifn"), path, strlen(path) + 1, forge.Path, LV2_STATE_IS_POD | LV2_STATE_IS_PORTABLE);
    }

The expected result:

	state:state [
		a <http://lsp-plug.in/types/lv2/types#KVT> [
			<http://lsp-plug.in/kvt/scene/selected> "0"^^xsd:int ;
			<http://lsp-plug.in/kvt/scene/objects> "0"^^xsd:int ;
			<http://lsp-plug.in/kvt/scene/object/0/enabled> "1.0"^^xsd:float
		] ;
		<http://lsp-plug.in/plugins/lv2/room_builder_mono/ports#ifn> <file:///home/sadko/eclipse/lsp-plugins/res/test/3d/devel-room.obj>
	] .

The actual result:

	state:state [
		a <http://lsp-plug.in/types/lv2/types#KVT> ;
		<http://lsp-plug.in/kvt/scene/selected> "0"^^xsd:int ;
		<http://lsp-plug.in/kvt/scene/objects> "0"^^xsd:int ;
		<http://lsp-plug.in/kvt/scene/object/0/enabled> "1.0"^^xsd:float
	] .

<http://lsp-plug.in/plugins/lv2/room_builder_mono/ports#ifn> <file:///home/sadko/eclipse/lsp-plugins/res/test/3d/devel-room.obj> .

According to specification:

Atoms should be used anywhere values of various types must be stored or transmitted.

Actually, we can not submit something more complicated than plain data types.

symlinks and paths on windows

tl;dr: two bugs which work around each other. no change required.

liblilv hardcodes foward-slash '/' as separator in two places.

https://github.com/drobilla/lilv/blob/4b298e4c7fa74836d023726185dfb2325d675c51/src/util.c#L377
https://github.com/drobilla/lilv/blob/4b298e4c7fa74836d023726185dfb2325d675c51/src/state.c#L264

This has the effect that when using abstract_path() on windows pm->abs == pm->rel == full absolute path.

So creating sylinks fails

  Failed to link  G:\foo\bar/C:\path\to\actual_file.sf2  -> C:\path\to\actual_file.sf2

On the upside, pm->rel is used in the state.ttl . Currently that is the absolute path and state save/load works (!).

This leads to a second issue. When fixing this by using LILV_DIR_SEP[0] in the places shown above, the state-file only contains the filename pm->rel. This is just like on unix-systems.

However creating symlinks usually fails on windows. The referenced file does not exist in the state-dir and the state is not be loaded correctly. The solution here, liblilv should use the absolute path when symlink creation fails.

How to force usage of python3?

I was recently trying to update lilv to 0.24.8 from 0.24.4 and now it installs this file:

/usr/lib/python2.7/site-packages/lilv.py

Is there any way to force it to use python3 or is this file even needed?

Crash when trying to load nonexistent state

While this is an API user error (meanwhile fixed in Ardour), passing a non-existent path to lilv_state_new_from_file, crashes lilv since lilv v0.24.20-10 dd5e851.

zix_canonical_path returns NULL if the path passed to it does not exist.
This leads to a crash in serd_node_new_file_uri calling strlen((const char*)path)

Older versions of liblilv are not affected lilv_path_absolute never returned NULL.

==2333==ERROR: AddressSanitizer: SEGV on unknown address 0x000000000000 (pc 0x7f9f85b7bc19 bp 0x7ffe29b76d30 sp 0x7ffe29b764d8 T0)
==2333==The signal is caused by a READ memory access.
==2333==Hint: address points to the zero page.
    #0 0x7f9f85b7bc19  (/lib/x86_64-linux-gnu/libc.so.6+0x15dc19) (BuildId: 8a1bf172e710f8ca0c1576912c057b45f90d90d8)
    #1 0x7f9f8d0658dc in __interceptor_strlen ../../../../src/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc:459
    #2 0x7f9f8562e31d in serd_node_new_file_uri (/lib/x86_64-linux-gnu/libserd-0.so.0+0xd31d) (BuildId: 62a360419ccf9ac8817f7c4c60b9cfec3cf15e84)
    #3 0x7f9f88299e20 in lilv_state_new_from_file (/lib/x86_64-linux-gnu/liblilv-0.so.0+0xde20) (BuildId: cc7d3e69a11506058f4c11a6c81a8c7c67b1e196)
    #4 0x7f9f8c0be866 in ARDOUR::LV2Plugin::set_state(XMLNode const&, int) ../libs/ardour/lv2_plugin.cc:2320

How to access state:state values in presets?

I'm writing an LV2 host that leverages lilv for parsing lv2 ttl files... but not currently using the lilv methods for preset management and state. That may have been a mistake, but I'm too far along to easily correct that problem.

The specific problem: I'm trying to copy factory presets (presets included in plugin manifest.ttl files) into my own json-based preset management system. Copying of factory presets is done once when a plugin is first detected. But I'm having a trouble extracting the state:state part of the presets in the manifest.ttl/preset.ttl files.

I've tried both lilv_state_ functions; and lilv_world / lilv_node approaches, without success so far.

A sample preset looks like this:

tpset:toob-convolution-reverb-preset-2
    a pset:Preset ; 
    lv2:appliesTo <http://two-play.com/plugins/toob-convolution-reverb> ;
    rdfs:label "Hall" ;

    lv2:port [
 
        ...
    ] ;

    # Note the atom__Path for the selected impulse file, stored in state here
    state:state [
        <http://two-play.com/plugins/toob-impulse#impulseFile> <ReverbImpulseFiles/St.%20Margaret\u0027s%20Church.wav> ;
    ] .
}

It's straightforward to read port values using lilv_state_emit_port_values; but I can't find a way to access values in the state::state array (which I assume contain the state values). I found lilv_state_num_properties. But I can't find a _get_property method.

So I tried to read the state values using lilv_world_find_nodes queries. But I get stuck when receiving blank nodes after calling lilv_world_find_nodes with

` <preset_iri> state:state nullptr

which succeeds, returning a single blank node.

But I can't find a way to enumerate the predicates in the resulting blank-node triples. lilv_world_find_nodes does not allow a null predicate node; and, generally, I can't predict what other plugins are going to use as predicates. I can't figure what to do next. If there's a way to get a list of triples, given only a blank nodes returned by LILV_FOREACH, I can't find it.

I can think of desperate ways to get this to work (creating a temporary instance of the plugin so that I can load via lilv, and then extract the state through lv2 host APIs. But I'm hoping I've missing something simple and obvious..

So far, I have:


  AutoLilvNode t = lilv_world_get(pWorld,presetUri, ,this->lilvUris.state__state,nullptr);
  
  AutoLilvNodes stateProperties = lilv_world_find_nodes(pWorld,preset,lilvUris.state__state,nullptr);
  LILV_FOREACH(nodes,j,stateProperties)
  {
      AutoLilvNode propertyNode = lilv_nodes_get(stateProperties,j);

     /*  WHAT NOW? propertyNode contains a blank URI, and I need to get the predicate for each blank node. **
  }

I rummaged through liv's state.c file to see how lilv does it. lilv uses

 SordIter* props = sord_search(model, state_node, 0, 0, 0);

But lilv_world_find_nodes doesn't allow a null predicate, and if lilv has a method for enumerating matching triples, I can't find it.

I feel like I'm missing something embarassingly obvious. :-/

lilv_world_get_plugin_classes() misses various RDF classes

I noticed that these classes are not returned by lilv_world_get_plugin_classes():

I assume this is not intended.

Here is a repro code (very simple enumeration):

#include <stdio.h>
#include "lilv/lilv.h"

int main ()
{
  int i, j;

  const LilvWorld *world = lilv_world_new ();

  lilv_world_load_bundle (world, lilv_new_uri (world, "http://www.w3.org/2000/01/rdf-schema"));

  lilv_world_load_all (world);

  const LilvPluginClasses *classes = lilv_world_get_plugin_classes (world);
  LILV_FOREACH(plugin_classes, i, classes) {
    const LilvPluginClass *c = lilv_plugin_classes_get (classes, i);
    puts (lilv_node_as_uri (lilv_plugin_class_get_uri (c)));
    const LilvPluginClasses *children = lilv_plugin_class_get_children (c);
    LILV_FOREACH(plugin_classes, j, children) {
      const LilvPluginClass *h = lilv_plugin_classes_get (children, j);
      printf ("  ");
      puts (lilv_node_as_uri (lilv_plugin_class_get_uri (h)));
    }
  }

  lilv_world_free (world);
}

It is because those classes does not have "parent" and lilv_world_get_plugin_classes() filters out such classes that do not have parent.

I will create a straightforward fix for this in a PR.

Default LV2 Path for Windows

# define LILV_DEFAULT_LV2_PATH "%APPDATA%/LV2;%COMMONPROGRAMFILES%/LV2"

This should use backslashes for dir separators:

#    define LILV_DEFAULT_LV2_PATH "%APPDATA%\\LV2;%COMMONPROGRAMFILES%\\LV2"

Likewise the following line adds an extra '%' which breaks discovery

lilv/wscript

Line 269 in b8a07a1

conf.define('LILV_DEFAULT_LV2_PATH', lv2_path.replace('%', '%%'))

this leads to "-DLILV_DEFAULT_LV2_PATH=\"%%APPDATA%%\\\\LV2;%%COMMONPROGRAMFILES%%\\\\LV2\""

The correct default path at runtime (after expanding escaped backslashes) that is used in lilv_world_load_all() should be
%APPDATA%\LV2;%COMMONPROGRAMFILES%\LV2

Documentation doesn't mention threading rules consistently

The LV2 documentation mentions threading rules. It appears that lilv doesn't attempt to apply thread synchronisation (it doesn't "abstract away" the threading rules as far as I can see). The documentation mentions some threading classes, but not everywhere. In particular, it's not clear from the documentation whether lilv_instance_run and lilv_instance_deactivate can be called concurrently.

Lilv is insanely slow for some reason

I don't have that many plug-ins, but Lilv is making all my LV2-using apps having a very slow startup, like 8 seconds when I try to profile. Lilv 0.24.20 as shipped by Arch Linux

Here's a profiler trace:
lv2

I have 78 megabytes of .ttl files in my /usr/lib which isn't that much for my computer (i7-8750H with 32GB of ram), my hunch is that there's some quadratic behaviour occuring somewhere.

lilv_world_get_plugin_classes() misses plugin classes whose parent is non-uri

(Excuse me for these spammy reports!) Similar to issue #19 and issue #21, these plugin classes have SORD_BLANK as its parent node type and thus filtered by [*1] :

Again, I assume this is not an intended behavior.

Simply removing the filter condition at [*1] brings them back.

[*1] https://github.com/drobilla/lilv/blob/c1637b46f9ff960f58dcf2bb3b69bff231f8acfd/src/world.c#L1013

How to save preset to a bank?

I have been struggling with this for a few days so thought I would ask here. I can save a preset but how do I assign that preset to a bank?

Send midi from host

Would there be any good example to send midi message from the host to a plugin?

Factory Presets

There is no way to find out if a LV2 preset is part of a plugin bundle (factory preset), or in a read-only location.

If a user tries to delete a preset that is referenced from the plugin's main manifest.ttl, that whole file is removed (like it was a user preset). Some time later the host crashes in serd_reader_read_file.
Try jalv.gtk http://gareus.org/oss/lv2/midifilter#midichord and delete the "sus4" preset that comes with the plugin

It would be nice if presets found in

  • read only locations
  • the plugins own bundle
    would have a LilvNode identifying them as such.

--
Current workaround: factory presets can have a RDFS:comment (fi. zero-config-convolver has elaborate explanation of each of the IR file presets), while lilv generated user presets cannot. -- This can be used to identify some presets as "factory" presets.

i18n Translation Issue

System Info

jalv 1.6.4
lilv 0.24.6
lv2 1.16.0

OS: Arch Linux x86_64
Host: TM1701
Kernel: 5.4.6-arch3-1
Uptime: 1 hour, 5 mins
Packages: 2501 (pacman), 3 (dpkg), 21 (flatpak)
Shell: bash 5.0.11
Resolution: 1920x1080
DE: GNOME 3.34.2
WM: Mutter
WM Theme: Adwaita
Theme: Adwaita [GTK2/3]
Icons: Adwaita [GTK2/3]
Terminal: gnome-terminal
CPU: Intel i7-8550U (8) @ 4.000GHz
GPU: NVIDIA GeForce MX150
GPU: Intel UHD Graphics 620
Memory: 3387MiB / 15899MiB

Summary:

Jalv.gtk & Ardour (LV2 host plugin GUI) both exhibit issues with i18n translations.

Tested using sfztools/sfizz@90bb90c

Issues are:

  • Scalepoint text can get stuck at a different language than system setting
  • Plugin Description (in Ardour) text does not translate
  • Group Labels are not translated into locale language (other than default) unless the size of translated string, is small (a few characters)
  • Random scalepoint behaviour- text with capitalization will translate:
    x1 Sovracampionamento will translate
    x1 sovracampionamento will not translate
  • Scalepoint will also get translate if string is small (a few characters)

LANG=it_IT.UTF-8 jalv.gtk http://sfztools.github.io/sfizz
Italian_but_Configuration_is_English
jalv.gtk http://sfztools.github.io/sfizz (run after LANG=Italian)
EN_but_still_Italian_scalepoints

build error

Sorry Dave, it's not my day.

Another build error, this time with lilv.

[21/27] Linking build/liblilv-0.so
[22/27] Linking build/utils/lilv-bench
[23/27] Linking build/utils/lv2ls
[24/27] Linking build/utils/lv2info
[25/27] Linking build/utils/lv2apply
[26/27] Linking build/utils/lv2bench
./liblilv-0.so: undefined reference to `serd_free'
collect2: error: ld returned 1 exit status

./liblilv-0.so: undefined reference to `serd_free'
collect2: error: ld returned 1 exit status

./liblilv-0.so: undefined reference to `serd_free'
collect2: error: ld returned 1 exit status

./liblilv-0.so: undefined reference to `serd_free'
collect2: error: ld returned 1 exit status

./liblilv-0.so: undefined reference to `serd_free'
collect2: error: ld returned 1 exit status

Waf: Leaving directory `/home/alex/github/lilv/build'
Build failed
-> task in 'utils/lilv-bench' failed with exit status 1 (run with -v to display more information)
-> task in 'utils/lv2apply' failed with exit status 1 (run with -v to display more information)
-> task in 'utils/lv2ls' failed with exit status 1 (run with -v to display more information)
-> task in 'utils/lv2info' failed with exit status 1 (run with -v to display more information)
-> task in 'utils/lv2bench' failed with exit status 1 (run with -v to display more information)

What have i done wrong here?

Alex.

simple lv2 code

Alot of people find it difficult because it is using macro. It is simple as pie.

#include "lilv/lilvmm.hpp"
#include

using namespace std;

int main()
{
Lilv::World world;
LilvIter * iter;
world.load_all();
Lilv::Plugins plugins = world.get_all_plugins();
cout << "Num Plugins = " << plugins.size() << endl;
iter = plugins.begin();
Lilv::Plugin plugin = plugins.get(iter);
Lilv::Node name = plugin.get_name();
cout << "Plugin: " << name.as_string() << endl;
}

Here is a tiny swig you can use it in Python, Lua, C#, etc

%module lilv
%{
#include "lilv.h"
#include "lilvmm.hpp"
%}
%ignore lilv_plugin_get_num_ports_of_class_va;
%include "lilv.h"
%include "lilvpp.hpp"

Note you have to preprocess lilvmm.hpp with gcc first like this: gcc -E lilvmm.hpp > lilpp.hpp so swig knows what the macros are

Fix Compile for mingw-w64

I don't really know how to go through the process of submitting code changes so I just wanted to let you, the developer know that testbench compilation fails under mingw-w64 cross-compile when the wafscript tries to link to librt. To circumvent this I made a change to the code to make it link to libpthread for the clock_gettime function instead.

You had an exception to skip the librt link if the compile environment is MSVC, but if you add an if loop to link to libpthread when the compile environment is mingw-w64, it should work.

Crash when deleting / updating preset

Recent lv2kit, lilv v0.24.6-2-gd1c9d1b and Ardour (6.0-pre0-3173-g563a8b15e0)

Steps to reproduce: Create a LV2 preset, change a parameter, save the preset.

Expected behavior: Old preset is deleted, a new one (with same name) is created. Known to work with 0.24.2.

Thread 1 "ardour-6.0.pre0" received signal SIGSEGV, Segmentation fault.
0x00007ffff2db32aa in zix_tree_begin (t=0x0) at ../libs/lv2kit/libs/lilv/src/zix/tree.c:622
622		if (!t->root) {
(gdb) bt
#0  0x00007ffff2db32aa in zix_tree_begin (t=0x0) at ../libs/lv2kit/libs/lilv/src/zix/tree.c:622
#1  0x00007ffff2dacc14 in lilv_state_delete (world=0x555556e26840, state=0x55555720ac10) at ../libs/lv2kit/libs/lilv/src/state.c:1257
#2  0x00007ffff7c6503f in ARDOUR::LV2Plugin::do_remove_preset(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (this=0x55555c045650, name="2048")
    at ../libs/ardour/lv2_plugin.cc:1712
#3  0x00007ffff79cd2f9 in ARDOUR::Plugin::remove_preset(std::__cxx11::basic_string<char, std::char_traits<char>, std::allocator<char> >) (this=0x55555c045650, name="2048")
    at ../libs/ardour/plugin.cc:140
#4  0x0000555556867bfc in PlugUIBase::save_plugin_setting() (this=0x55555caf87c0) at ../gtk2_ardour/plugin_ui.cc:671

lilv_world_get() does not select translation values

lilv_world_get() just selects an arbitrary value (by using sord_get() directly) because it is designed for properties that only have one value. However language tags screw this concept up, so it should probably select the best translation from the set of values if there are several.

See #31 (comment)

saving state on windows-drives fails in lilv_mkdir_p

mkdir ("G:", 0755); fails with EACCESS, likewise trying to create "G:" also fails with EACCESS,
while creating "G:\test" works.

lilv_mkdir_p() splits the path by separator. e.g. "G:\test\folder" starts with "G:".

"modern includes" should be conditional

I think the changes introduced here 84762e0 should be conditional to the system at hand.

Is this not something that could be detected by waf, which would then generate an appropriate #define? Also, strange enough, currently ./waf configure works fine, but then it fails at compile time, which is also not the way it should be, IMHO.

autowaf.build_pc generates lilv-0.pc which is missing serd-0, sord-0, and sratom-0 dependency

The current build produces a lilv-0.pc pkg-config file , which looks like this:

prefix=/usr
exec_prefix=${prefix}
libdir=${exec_prefix}/lib
includedir=${prefix}/include

Name: Lilv
Version: 0.24.5
Description: Simple C library for hosting LV2 plugins
Requires: lv2   
Libs: -L${libdir} -llilv-0  -ldl
Cflags: -I${includedir}/lilv-0

This is missing serd-0, serd-0 and sratom-0 in the Requires: line.

I think something must have changed in the autowaf.build_pc function when waflib was included as a git submodule instead of as a binary blob in the waf script, so the substitution of @PKG_serd_0@ @PKG_sord_0@ @PKG_sratom_0@ in the lilv.pc.in no longer works correctly.

Dereference symlinks on state restore

lilv_state_restore's retrieve callback should dereference symlinks by calling readlink.

  • load a file into a plugin. e.g. /file.test
  • save state. lilv generates two symlinks:
    • state-dir/file.test -> externals/file.test
    • externals/file.test -> /file.test
  • re-load plugin, restore state. the plugin uses state-dir/file.test

Now copy the plugin or save a preset. the file state-dir/file.test is used as new original. This causes various issues.

Also simply inspecting which file the plugin uses only points to state-dir/file.test. From a user's POV it would be nice if the plugin would show the canonical path.

Compile failure: GCC diagnostic not allowed inside functions

Setting top to                                : /Users/ardour/src/stack/lilv-0.24.11 
Setting out to                                : /Users/ardour/src/stack/lilv-0.24.11/build 
Checking for 'clang' (C compiler)             : not found 
Checking for 'gcc' (C compiler)               : gcc 
Checking for 'clang++' (C++ compiler)         : not found 
Checking for 'g++' (C++ compiler)             : g++ 
Checking for program 'python'                 : /usr/bin/python 
Checking for python version >= 2.6.0          : 2.6.1 
Checking for flag '-std=c99'                  : yes 
Checking for program 'pkg-config'             : /Users/ardour/gtk/inst/bin/pkg-config 
Checking for 'lv2 >= 1.18.0'                  : yes 
Checking for 'serd-0 >= 0.30.0'               : yes 
Checking for 'sord-0 >= 0.14.0'               : yes 
Checking for 'sratom-0 >= 0.4.0'              : yes 
Checking for 'sndfile >= 1.0.0'               : yes 
Checking for lstat                            : yes 
Checking for flock                            : yes 
Checking for fileno                           : yes 
Checking for clock_gettime                    : no 
Checking for library dl                       : yes 
Install prefix                                : /Users/ardour/gtk/inst 
C Flags                                       : -DMAC_OS_X_VERSION_MAX_ALLOWED=1050 -mmacosx-version-min=10.5 -O3 -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fshow-column -std=c99 
C++ Flags                                     : -DMAC_OS_X_VERSION_MAX_ALLOWED=1050 -mmacosx-version-min=10.5 -O3 -D_LARGEFILE64_SOURCE -D_FILE_OFFSET_BITS=64 -fshow-column 
Debuggable                                    : no 
Build documentation                           : no 
Unit tests                                    : no 
Dynamic manifest support                      : no 
Utilities                                     : yes 
Python bindings                               : yes 
Default LV2_PATH                              : ~/Library/Audio/Plug-Ins/LV2:~/.lv2:/usr/local/lib/lv2:/usr/lib/lv2:/Library/Audio/Plug-Ins/LV2 
'configure' finished successfully (2.130s)
Build commands will be stored in build/compile_commands.json
Waf: Entering directory `/Users/ardour/src/stack/lilv-0.24.11/build'
[ 1/27] Compiling src/world.c
[ 2/27] Compiling src/plugin.c
[ 3/27] Compiling src/filesystem.c
[ 4/27] Compiling src/util.c
../src/util.c: In function 'lilv_uri_to_path':
../src/util.c:94: error: #pragma GCC diagnostic not allowed inside functions
../src/util.c:95: error: #pragma GCC diagnostic not allowed inside functions
../src/util.c:101: error: #pragma GCC diagnostic not allowed inside functions

Waf: Leaving directory `/Users/ardour/src/stack/lilv-0.24.11/build'
Build failed
 -> task in 'liblilv' failed with exit status 1 (run with -v to display more information)

lilv_world_get_plugin_classes() misses label-less classes e.g. AmbisonicGroup

It's similar to issue #19 - lilv_world_get_plugin_classes() skips plugin classes that do not have "label". Obviously it is intended (as per [*1]), but that results in some unexpected lack of results.

Here are the missing classes because of this:

[*1] https://github.com/drobilla/lilv/blob/c1637b46f9ff960f58dcf2bb3b69bff231f8acfd/src/world.c#L1019

Build fails under macOS 12 when tests are enabled

Trying to build using github actions and its macos-12 is failing.
Using build options

--buildtype release -Ddefault_library=static -Dbindings_py=disabled -Ddocs=disabled

configuration output:

The Meson build system
Version: 1.3.2
Source dir: /Users/runner/PawPawBuilds/builds/macos-10.15/lilv-0.24.24
Build dir: /Users/runner/PawPawBuilds/builds/macos-10.15/lilv-0.24.24/build
Build type: native build
Project name: lilv
Project version: 0.24.24
C compiler for the host machine: gcc (clang 14.0.0 "Apple clang version 14.0.0 (clang-1400.0.29.202)")
C linker for the host machine: gcc ld64 820.1
Host machine cpu family: x86_64
Host machine cpu: x86_64
C++ compiler for the host machine: g++ (clang 14.0.0 "Apple clang version 14.0.0 (clang-1400.0.29.202)")
C++ linker for the host machine: g++ ld64 820.1
Library m found: YES
Library dl found: YES
Found pkg-config: YES (/Users/runner/PawPawBuilds/targets/macos-10.15/bin/pkg-config) 0.28
Run-time dependency zix-0 found: YES 0.4.2
Run-time dependency serd-0 found: YES 0.32.2
Run-time dependency sord-0 found: YES 0.16.16
Run-time dependency lv2 found: YES 1.18.10
Run-time dependency sratom-0 found: YES 0.6.16
Run-time dependency sndfile found: YES 1.2.2
Library rt found: NO
Checking if "clock_gettime" with dependency -lrt compiles: YES 
Configuring manifest.ttl using configuration
Configuring bad_syntax.ttl using configuration
Configuring manifest.ttl using configuration
Configuring failed_instantiation.ttl using configuration
Configuring manifest.ttl using configuration
Configuring failed_lib_descriptor.ttl using configuration
Configuring manifest.ttl using configuration
Configuring lib_descriptor.ttl using configuration
Configuring manifest.ttl using configuration
Configuring missing_descriptor.ttl using configuration
Configuring manifest.ttl using configuration
Configuring missing_name.ttl using configuration
Configuring manifest.ttl using configuration
Configuring missing_plugin.ttl using configuration
Configuring manifest.ttl using configuration
Configuring missing_port.ttl using configuration
Configuring manifest.ttl using configuration
Configuring missing_port_name.ttl using configuration
Configuring manifest.ttl using configuration
Configuring new_version.ttl using configuration
Configuring manifest.ttl using configuration
Configuring old_version.ttl using configuration
Configuring manifest.ttl using configuration
Configuring test_plugin.ttl using configuration
Build targets in project: 49
NOTICE: Future-deprecated features used:
 * 0.64.0: {'copy arg in configure_file'}

lilv 0.24.24

  Components
    Tests           : YES
    Tools           : YES

  Configuration
    Default LV2_PATH: ~/.lv2:~/Library/Audio/Plug-Ins/LV2:/usr/local/lib/lv2:/usr/lib/lv2:/Library/Audio/Plug-Ins/LV2

  Directories
    Install prefix  : /Users/runner/PawPawBuilds/targets/macos-10.15
    Headers         : /Users/runner/PawPawBuilds/targets/macos-10.15/include
    Libraries       : /Users/runner/PawPawBuilds/targets/macos-10.15/lib
    Executables     : /Users/runner/PawPawBuilds/targets/macos-10.15/bin
    Man pages       : /Users/runner/PawPawBuilds/targets/macos-10.15/share/man

  User defined options
    buildtype       : release
    default_library : static
    libdir          : lib
    prefix          : /Users/runner/PawPawBuilds/targets/macos-10.15
    bindings_py     : disabled
    docs            : disabled

Found ninja-1.11.1 at /usr/local/bin/ninja

error output:

FAILED: test/cpp/test_lilv_hpp.p/test_lilv_hpp.cpp.o 
g++ -Itest/cpp/test_lilv_hpp.p -Itest/cpp -I../test/cpp -I../src -I../include -I/Users/runner/PawPawBuilds/targets/macos-10.15/include -I/Users/runner/PawPawBuilds/targets/macos-10.15/include/serd-0 -I/Users/runner/PawPawBuilds/targets/macos-10.15/include/sord-0 -I/Users/runner/PawPawBuilds/targets/macos-10.15/include/zix-0 -I/Users/runner/PawPawBuilds/targets/macos-10.15/include/sratom-0 -fdiagnostics-color=always -DNDEBUG -Wall -Winvalid-pch -O3 -pipe -fPIC -DPIC -fdata-sections -ffunction-sections -fno-common -fvisibility=hidden -fno-stack-protector -U_FORTIFY_SOURCE -Wp,-U_FORTIFY_SOURCE -ffast-math -fno-finite-math-only -Os -DNDEBUG=1 -fomit-frame-pointer -mtune=generic -msse -msse2 -mfpmath=sse -DMAC_OS_X_VERSION_MAX_ALLOWED=MAC_OS_X_VERSION_10_15 -DMAC_OS_X_VERSION_MIN_REQUIRED=MAC_OS_X_VERSION_10_15 -mmacosx-version-min=10.15 -arch x86_64 -Werror=objc-method-access -DHAVE_MIXED_SIZE_ADDRESSING -fvisibility-inlines-hidden -DSRATOM_STATIC -DSORD_STATIC -DZIX_STATIC -DSERD_STATIC -DLILV_STATIC -Wno-c++98-compat -Wno-cast-align -Wno-cast-qual -Wno-documentation-unknown-command -Wno-padded -Wno-poison-system-directories -Wno-reserved-id-macro -MD -MQ test/cpp/test_lilv_hpp.p/test_lilv_hpp.cpp.o -MF test/cpp/test_lilv_hpp.p/test_lilv_hpp.cpp.o.d -o test/cpp/test_lilv_hpp.p/test_lilv_hpp.cpp.o -c ../test/cpp/test_lilv_hpp.cpp
In file included from ../test/cpp/test_lilv_hpp.cpp:4:
../include/lilv/lilvmm.hpp:120:19: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
  inline Node(Node&& other) noexcept
                  ^
../include/lilv/lilvmm.hpp:120:28: error: expected ';' at end of declaration list
  inline Node(Node&& other) noexcept
                           ^
                           ;
../include/lilv/lilvmm.hpp:104:7: error: member initializer 'me' does not name a non-static data member or base class
    : me(lilv_node_duplicate(node))
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../include/lilv/lilvmm.hpp:108:35: error: no member named 'me' in 'Lilv::Node'
    : me(lilv_node_duplicate(copy.me))
                             ~~~~ ^
../include/lilv/lilvmm.hpp:108:7: error: member initializer 'me' does not name a non-static data member or base class
    : me(lilv_node_duplicate(copy.me))
      ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../include/lilv/lilvmm.hpp:114:22: error: use of undeclared identifier 'me'
      lilv_node_free(me);
                     ^
../include/lilv/lilvmm.hpp:115:7: error: use of undeclared identifier 'me'
      me = lilv_node_duplicate(rhs.me);
      ^
../include/lilv/lilvmm.hpp:115:36: error: no member named 'me' in 'Lilv::Node'
      me = lilv_node_duplicate(rhs.me);
                               ~~~ ^
../include/lilv/lilvmm.hpp:215:3: error: no matching function for call to 'lilv_nodes_contains'
  LILV_WRAP1(bool, nodes, contains, const Node&, node)
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../include/lilv/lilvmm.hpp:65:12: note: expanded from macro 'LILV_WRAP1'
    return lilv_##prefix##_##name(me, a1);   \
           ^~~~~~~~~~~~~~~~~~~~~~
<scratch space>:491:1: note: expanded from here
lilv_nodes_contains
^~~~~~~~~~~~~~~~~~~
../include/lilv/lilv.h:521:1: note: candidate function not viable: no known conversion from 'const Lilv::Node' to 'const LilvNode *' (aka 'const LilvNodeImpl *') for 2nd argument
lilv_nodes_contains(const LilvNodes* nodes, const LilvNode* value);
^
In file included from ../test/cpp/test_lilv_hpp.cpp:4:
../include/lilv/lilvmm.hpp:293:3: error: no matching function for call to 'lilv_plugin_get_value'
  LILV_WRAP1(Nodes, plugin, get_value, const Node&, pred)
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../include/lilv/lilvmm.hpp:65:12: note: expanded from macro 'LILV_WRAP1'
    return lilv_##prefix##_##name(me, a1);   \
           ^~~~~~~~~~~~~~~~~~~~~~
<scratch space>:52:1: note: expanded from here
lilv_plugin_get_value
^~~~~~~~~~~~~~~~~~~~~
../include/lilv/lilv.h:944:1: note: candidate function not viable: no known conversion from 'const Lilv::Node' to 'const LilvNode *' (aka 'const LilvNodeImpl *') for 2nd argument
lilv_plugin_get_value(const LilvPlugin* plugin, const LilvNode* predicate);
^
In file included from ../test/cpp/test_lilv_hpp.cpp:4:
../include/lilv/lilvmm.hpp:294:3: error: no matching function for call to 'lilv_plugin_has_feature'
  LILV_WRAP1(bool, plugin, has_feature, const Node&, feature_uri)
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../include/lilv/lilvmm.hpp:65:12: note: expanded from macro 'LILV_WRAP1'
    return lilv_##prefix##_##name(me, a1);   \
           ^~~~~~~~~~~~~~~~~~~~~~
<scratch space>:55:1: note: expanded from here
lilv_plugin_has_feature
^~~~~~~~~~~~~~~~~~~~~~~
../include/lilv/lilv.h:954:1: note: candidate function not viable: no known conversion from 'const Lilv::Node' to 'const LilvNode *' (aka 'const LilvNodeImpl *') for 2nd argument
lilv_plugin_has_feature(const LilvPlugin* plugin, const LilvNode* feature);
^
In file included from ../test/cpp/test_lilv_hpp.cpp:4:
../include/lilv/lilvmm.hpp:307:3: error: no matching function for call to 'lilv_plugin_get_related'
  LILV_WRAP1(Nodes, plugin, get_related, const Node&, type)
  ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
../include/lilv/lilvmm.hpp:65:12: note: expanded from macro 'LILV_WRAP1'
    return lilv_##prefix##_##name(me, a1);   \
           ^~~~~~~~~~~~~~~~~~~~~~
<scratch space>:94:1: note: expanded from here
lilv_plugin_get_related
^~~~~~~~~~~~~~~~~~~~~~~
../include/lilv/lilv.h:1221:1: note: candidate function not viable: no known conversion from 'const Lilv::Node' to 'const LilvNode *' (aka 'const LilvNodeImpl *') for 2nd argument
lilv_plugin_get_related(const LilvPlugin* plugin, const LilvNode* type);
^
In file included from ../test/cpp/test_lilv_hpp.cpp:4:
../include/lilv/lilvmm.hpp:354:55: error: use of undeclared identifier 'nullptr'
    : me(lilv_plugin_instantiate(plugin, sample_rate, nullptr))
                                                      ^
../include/lilv/lilvmm.hpp:370:36: error: use of undeclared identifier 'nullptr'
    return me ? new Instance(me) : nullptr;
                                   ^
../include/lilv/lilvmm.hpp:408:36: warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]
  World(const World&)            = delete;
                                   ^
../include/lilv/lilvmm.hpp:409:36: warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]
  World& operator=(const World&) = delete;
                                   ^
../include/lilv/lilvmm.hpp:411:14: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
  World(World&&)            = delete;
             ^
../include/lilv/lilvmm.hpp:411:31: warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]
  World(World&&)            = delete;
                              ^
../include/lilv/lilvmm.hpp:412:25: warning: rvalue references are a C++11 extension [-Wc++11-extensions]
  World& operator=(World&&) = delete;
                        ^
../include/lilv/lilvmm.hpp:412:31: warning: deleted function definitions are a C++11 extension [-Wc++11-extensions]
  World& operator=(World&&) = delete;
                              ^
../test/cpp/test_lilv_hpp.cpp:9:26: error: expected ';' at end of declaration
  const Lilv::World world{};
                         ^
                         ;
7 warnings and 14 errors generated.

with the full logs available at https://github.com/DISTRHO/PawPaw/actions/runs/8203426480/job/22436150152

seems to me there is a -std=c++11 or similar missing

Improper behaviour when saving/restoring Strings with LV2:State interface

When trying to store multiple strings:

/scene/object/4/material/sound_speed
/scene/object/4/material/transparency/inner
/scene/object/4/material/dissipation/inner
/scene/object/4/material/dispersion/inner
/scene/object/4/material/absorption/inner

with same key: "http://lsp-plug.in/kvt#keys" we get the following result:

        state:state [
                <http://lsp-plug.in/kvt#keys> "/scene/object/4/material/sound_speed" ,
                        "/scene/object/4/material/transparency/inner" ,
                        "/scene/object/4/material/dissipation/inner" ,
                        "/scene/object/4/material/dispersion/inner" ,
                        "/scene/object/4/material/absorption/inner";
        ]

When reading LV2 state, we get only one random parameter, all other string parts are omitted:

[TRC][/home/vsadovnikov/eclipse/lsp-plugins/include/container/lv2/extensions.h: 569] retrieve_value: retrieve(57 (http://lsp-plug.in/kvt#keys))
[TRC][/home/vsadovnikov/eclipse/lsp-plugins/include/container/lv2/extensions.h: 571] retrieve_value: retrieved ptr = 0x9a959c0, size=44, type=41, flags=0x3
Received KVT key set:
00000000: 2f 73 63 65 6e 65 2f 6f 62 6a 65 63 74 2f 32 2f    /scene/object/2/
00000010: 6d 61 74 65 72 69 61 6c 2f 74 72 61 6e 73 70 61    material/transpa
00000020: 72 65 6e 63 79 2f 6f 75 74 65 72 00                rency/outer.

There is currently no way to fetch all the strings with same key while the LV2:State interface allows to store multiple values associated with the same key.

Recreating LV2 presets deletes sym-linked files

In Ardour, saving a preset first deletes the current presets, and then re-creates it.

lilv_world_unload_resource();
lilv_state_delete();
// [..]
lilv_state_new_from_instance();
lilv_state_save();

This worked fine before c9a54e0, however recent liblilv unlinks all the external resource in lilv_state_delete(), and for some reason they are not re-created.

Since creating presets works correctly, it looks as if the files are still assumed to be mapped and hence the symlinks not re-created.

Related to lsp-plugins/lsp-plugins#119 (comment)

[FR/QUESTION] Can lilv (Python binding) be used to send MIDI atoms to a plugin port?

If so, can you give a short example, how to achieve this? Is there any code in lilv (or another library, which can be used from Python) to help construct MIDI atoms (I suppose one could always use the struct module or ctypes)?

If not, would you consider adding such a feature?

The main use case would be to be able to write automated tests for MIDI processing/filter LV2 plugins.

SEGV with python-lilv

Hi David,

I am trying to use the python interface of lilv and wrote a simple program which gives me the URI and name of each preset for a given URI of a plugin:

#!/usr/bin/python3

#PLUGIN="https://github.com/dcoredump/dexed.lv2"
PLUGIN="http://tytel.org/helm"

import lilv
import pprint

world = lilv.World()
world.load_all()
plugin = world.get_all_plugins().get_by_uri(world.new_uri(PLUGIN))
preset_uri = lilv.Node(world.new_uri("http://lv2plug.in/ns/ext/presets#Preset"))
psets = plugin.get_related(preset_uri)
label_uri = world.new_uri(lilv.LILV_NS_RDFS + "label")
print(lilv.LILV_NS_RDFS + "label")
for pset_node in psets:
    print(pset_node.get_turtle_token())
    pset_nodes=world.find_nodes(pset_node,label_uri,None)
    for pset_name in pset_nodes:
        print(pset_name.get_turtle_token())

When running this I get a SEGV at the end:

....................
<http://tytel.org/helm#preset101>
SF Brass CC2
<http://tytel.org/helm#preset102>
SF Brass Soft Stutter
Segmentation fault

I don't know if I am doing something wrong or if there is a problem with python-lilv... can you take a look at this?

Thanks && Regards, Holger

[EDIT]
I found out that commenting out node_free(self.node) (lilv.py: 728) avoids the SEGV... but I think this is not a really nice solution...

plugins ignored

Hi,

is there a plan to port the python binding to python3 ?

I try to load all plugins I get this :

>>> world.load_all()
lilv_world_add_plugin(): warning: Duplicate plugin <http://lv2plug.in/plugins/eg-midigate>
lilv_world_add_plugin(): warning: ... found in file:///usr/lib/lv2/eg-midigate.lv2/
lilv_world_add_plugin(): warning: ... and      file:///usr/local/lib/lv2/eg-midigate.lv2/ (ignored)
lilv_world_add_plugin(): warning: Duplicate plugin <http://lv2plug.in/plugins/eg-params>
lilv_world_add_plugin(): warning: ... found in file:///usr/lib/lv2/eg-params.lv2/
lilv_world_add_plugin(): warning: ... and      file:///usr/local/lib/lv2/eg-params.lv2/ (ignored)
lilv_world_add_plugin(): warning: Duplicate plugin <http://drobilla.net/plugins/mda/Ambience>
lilv_world_add_plugin(): warning: ... found in file:///usr/lib/lv2/mda.lv2/
lilv_world_add_plugin(): warning: ... and      file:///usr/local/lib/lv2/mda.lv2/ (ignored)
lilv_world_add_plugin(): warning: Duplicate plugin <http://drobilla.net/plugins/mda/Bandisto>
lilv_world_add_plugin(): warning: ... found in file:///usr/lib/lv2/mda.lv2/
lilv_world_add_plugin(): warning: ... and      file:///usr/local/lib/lv2/mda.lv2/ (ignored)
lilv_world_add_plugin(): warning: Duplicate plugin <http://drobilla.net/plugins/mda/BeatBox>
lilv_world_add_plugin(): warning: ... found in file:///usr/lib/lv2/mda.lv2/
lilv_world_add_plugin(): warning: ... and      file:///usr/local/lib/lv2/mda.lv2/ (ignored)
lilv_world_add_plugin(): warning: Duplicate plugin <http://drobilla.net/plugins/mda/Combo>
lilv_world_add_plugin(): warning: ... found in file:///usr/lib/lv2/mda.lv2/
lilv_world_add_plugin(): warning: ... and      file:///usr/local/lib/lv2/mda.lv2/ (ignored)
lilv_world_add_plugin(): warning: Duplicate plugin <http://drobilla.net/plugins/mda/DX10>
lilv_world_add_plugin(): warning: ... found in file:///usr/lib/lv2/mda.lv2/
lilv_world_add_plugin(): warning: ... and      file:///usr/local/lib/lv2/mda.lv2/ (ignored)
lilv_world_add_plugin(): warning: Duplicate plugin <http://drobilla.net/plugins/mda/DeEss>
lilv_world_add_plugin(): warning: ... found in file:///usr/lib/lv2/mda.lv2/

No documentation.

I would like to implement this in an old sequencer I wrote.

However, there is zero documentation on lilv or ladspav2 as a host and my time to work on this is limited. A reference by itself is useless and the examples are incredibly complex. Implementing LV1 15 years ago was a tiny fraction of the code, and not even wrapper libs were needed.

A tutorial on setting up, using it, discovering, bringing up an UI, etc. or at least what each thing is supposed to be would be appreciated, otherwise I'm afraid even supporting Linux is just a bad idea.

I'm surprised you spent so much writing example code but not even dedicated to explain even an overview on how the library is supposed to work.

If you don't have time for this, I suggest you make Github the official development platform (it's 2018, hosting the project on hour own website is very 1999), put documentation in here in Markup and ask the community for contributions on this aspect.

Best

Bad decoding of \\ characters

reporting a ticket that is likely on serd or sord side, but I am having trouble finding exactly what is wrong.

take a plugin that writes json in a string parameter, saving state like so:

{
  "id": 1079059256177472,
  "plugin": "Cardinal",
  "model": "TextEditor",
  "version": "2.0",
  "params": [],
  "data": {
    "filepath": "",
    "lang": "None",
    "etext": "\n\n1 - LP Filter\n2 - Resonance\n3 - OSC 1 <> 2\n4 - Attack\n5 - Decay\n6 - Sustain\n\n\n\n\n\n",
    "width": 11
  },
  "pos": [
    48,
    0
  ]
}

this is valid json, verified by json linters, all fine so far.

when saving this as plugin state with lilv, the state/preset ttl contents end up alike this:

{
  "id": 7797650034473482,
  "plugin": "Cardinal",
  "model": "TextEditor",
  "version": "2.0",
  "params": [],
  "leftModuleId": 7219430607288126,
  "data": {
    "filepath": "",
    "lang": "None",
    "etext": "\\n\\nThis section spreads\\n\\nthe unison sound\\n\\nacross 4 stereo outs\\n\\n\\n\\n\\n\\n\\n",
    "width": 14
  },
  "pos": [
    31,
    1
  ]
}

There is some extra encoding of the \ characters, but seems consistent in what it does.

When loading this state, this is the string given to the plugin as state which sadly becomes invalid:

{
  "id": 7797650034473482,
  "plugin": "Cardinal",
  "model": "TextEditor",
  "version": "2.0",
  "params": [],
  "leftModuleId": 7219430607288126,
  "data": {
    "filepath": "",
    "lang": "None",
    "etext": "\
\nThis section spreads\n\nthe unison sound\n\nacross 4 stereo outs\n\n\n\n\n\n\n",
    "width": 14
  },
  "pos": [
    31,
    1
  ]
}

compare the 1st to 3rd code-blocks on this ticket, the "etext" has a real newline in there which is invalid in JSON. only happens on the 1st occurrence weirdly enough.

initially I thought this was a bug on my side, but I dumped the state from lilv directly into a file, and that file content is what you see on this 3rd pasted code block.
seems like something on lilv or libs used by it is not decoding back the values properly.

issue has been there for a while, and also present on very recent lilv/lv2 libs too.
only reporting it now since I assumed I did something wrong, but now I am not so certain anymore...

[ Security issue ] Viruses detected after compile

Greeting,

Today I wanted to build LMMS on Windows using the latest MSVC and QT 6 to help with porting to the latest QT version released.
Before that, using VCPKG I tried to install all the needed dependencies, which include "lilv" library.
To my surprise it wouldn't build, at least not the release ( the debug builds ) and after hours of investigation, I have noticed that my antivirus spotted a danger with the generated DLL "lilv.dll" and another executable generated in "meson-private\tmpu5lnsej4\output.exe" in the build directory which is also spotted as a virus.
In the doubt of a false positive I decided to send the DLL to virustotal website to be tested by more antiviruses, and 10 of them spotted the DLL as infected.

VirusTotal result

I don't know since when the malicious code was pushed because last time I compiled LMMS on Windows was years ago. But it means that all linux distro shipping the lib lilv are at risk as of now.

Search issue with translated plugins

See brummer10/jalv_select#39


Notes from drobilla on IRC #lv2:

Since the only particularly feasible solution is to load all translations into memory at once, which aside from massively increasing memory usage would probably require a bunch more work to not making a bunch of other things tedious, it's kind of an academic question
I'd rather see a precedent of using a non-translated identifier for such things
If URIs are too tedious for that (which they probably are), symbols like "calf.reverb" or some such are what I'd like to see
That said, sure, particularly these days, free-form text search is kind of expected for everything, but the cost:benefit of this specifically with respect to the language thing doesn't seem great to me
But lilv, probably.  It would be possible to add an option to load everything if hosts really want to
Doesn't really seem to have anything to do with jalv
It might not be so bad if it's only for the untranslated (which is not "english" in anything but convention) and translated name
I have no idea how the search in jalv_select works

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    ๐Ÿ–– Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. ๐Ÿ“Š๐Ÿ“ˆ๐ŸŽ‰

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google โค๏ธ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.