-
Notifications
You must be signed in to change notification settings - Fork 23
Description
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. :-/