#include "libardour-config.h"
-#include "ardour/types.h"
#include "ardour/audio_buffer.h"
#include "ardour/audioengine.h"
#include "ardour/debug.h"
#include "ardour/lv2_plugin.h"
#include "ardour/session.h"
#include "ardour/tempo.h"
+#include "ardour/types.h"
+#include "ardour/utils.h"
#include "ardour/worker.h"
#include "i18n.h"
/* log extension */
static int
-log_vprintf(LV2_Log_Handle handle,
+log_vprintf(LV2_Log_Handle /*handle*/,
LV2_URID type,
const char* fmt,
va_list args)
/** Find the LV2 input port with the given designation.
* If found, bufptrs[port_index] will be set to bufptr.
*/
- LilvPort* designated_input (const char* uri, void** bufptrs[], void** bufptr);
+ const LilvPort* designated_input (const char* uri, void** bufptrs[], void** bufptr);
const LilvPlugin* plugin;
const LilvUI* ui;
_log_feature.URI = LV2_LOG__log;
_work_schedule_feature.URI = LV2_WORKER__schedule;
_work_schedule_feature.data = NULL;
+ _def_state_feature.URI = LV2_STATE_PREFIX "loadDefaultState"; // Post LV2-1.2.0
+ _def_state_feature.data = NULL;
const LilvPlugin* plugin = _impl->plugin;
lilv_node_free(state_uri);
lilv_node_free(state_iface_uri);
- _features = (LV2_Feature**)calloc(10, sizeof(LV2_Feature*));
+ _features = (LV2_Feature**)calloc(11, sizeof(LV2_Feature*));
_features[0] = &_instance_access_feature;
_features[1] = &_data_access_feature;
_features[2] = &_make_path_feature;
_features[5] = _uri_map.urid_unmap_feature();
_features[6] = &_log_feature;
+ unsigned n_features = 7;
+#ifdef HAVE_NEW_LV2
+ _features[n_features++] = &_def_state_feature;
+#endif
+
lv2_atom_forge_init(&_impl->forge, _uri_map.urid_map());
- unsigned n_features = 7;
#ifdef HAVE_NEW_LV2
LV2_URID atom_Int = _uri_map.uri_to_id(LV2_ATOM__Int);
LV2_Options_Option options[] = {
throw failed_constructor();
}
+#ifdef HAVE_NEW_LILV
+ // Load default state
+ LilvState* state = lilv_state_new_from_world(
+ _world.world, _uri_map.urid_map(), lilv_plugin_get_uri(_impl->plugin));
+ if (state && _has_state_interface) {
+ lilv_state_restore(state, _impl->instance, NULL, NULL, 0, NULL);
+ }
+#endif
+
_sample_rate = rate;
const uint32_t num_ports = this->num_ports();
lilv_node_free(lv2_appliesTo);
}
-bool
-LV2Plugin::load_preset(PresetRecord r)
+static void
+set_port_value(const char* port_symbol,
+ void* user_data,
+ const void* value,
+ uint32_t /*size*/,
+ uint32_t type)
{
- std::map<std::string,uint32_t>::iterator it;
-
- LilvNode* lv2_port = lilv_new_uri(_world.world, LILV_NS_LV2 "port");
- LilvNode* lv2_symbol = lilv_new_uri(_world.world, LILV_NS_LV2 "symbol");
- LilvNode* preset = lilv_new_uri(_world.world, r.uri.c_str());
- LilvNode* pset_value = lilv_new_uri(_world.world, LV2_PRESETS__value);
-
- LilvNodes* ports = lilv_world_find_nodes(_world.world, preset, lv2_port, NULL);
- LILV_FOREACH(nodes, i, ports) {
- const LilvNode* port = lilv_nodes_get(ports, i);
- const LilvNode* symbol = get_value(_world.world, port, lv2_symbol);
- const LilvNode* value = get_value(_world.world, port, pset_value);
- if (value && lilv_node_is_float(value)) {
- it = _port_indices.find(lilv_node_as_string(symbol));
- if (it != _port_indices.end()) {
- set_parameter(it->second,lilv_node_as_float(value));
- }
- }
+ LV2Plugin* self = (LV2Plugin*)user_data;
+ if (type != 0 && type != self->_uri_map.uri_to_id(LV2_ATOM__Float)) {
+ return; // TODO: Support non-float ports
}
- lilv_nodes_free(ports);
- lilv_node_free(pset_value);
- lilv_node_free(preset);
- lilv_node_free(lv2_symbol);
- lilv_node_free(lv2_port);
+ const uint32_t port_index = self->port_index(port_symbol);
+ if (port_index != (uint32_t)-1) {
+ self->set_parameter(port_index, *(const float*)value);
+ }
+}
- Plugin::load_preset(r);
+bool
+LV2Plugin::load_preset(PresetRecord r)
+{
+ LilvWorld* world = _world.world;
+ LilvNode* pset = lilv_new_uri(world, r.uri.c_str());
+ LilvState* state = lilv_state_new_from_world(world, _uri_map.urid_map(), pset);
- return true;
+ if (state) {
+ lilv_state_restore(state, _impl->instance, set_port_value, this, 0, NULL);
+ lilv_state_free(state);
+ }
+
+ lilv_node_free(pset);
+ return state;
}
const void*
std::string
LV2Plugin::do_save_preset(string name)
{
- string pset_uri = uri();
- pset_uri += "#";
- pset_uri += name;
-
- string save_dir = Glib::build_filename(
+ const string base_name = legalize_for_uri(name);
+ const string file_name = base_name + ".ttl";
+ const string bundle = Glib::build_filename(
Glib::get_home_dir(),
- Glib::build_filename(".lv2", "presets")
- );
+ Glib::build_filename(".lv2", base_name + ".lv2"));
LilvState* state = lilv_state_new_from_instance(
_impl->plugin,
_impl->instance,
_uri_map.urid_map(),
- scratch_dir().c_str(), // file_dir
- NULL, // copy_dir
- NULL, // link_dir
- save_dir.c_str(), // save_dir
- lv2plugin_get_port_value, // get_value
- (void*) this, // user_data
- LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE, // flags
- _features // features
+ scratch_dir().c_str(), // file_dir
+ bundle.c_str(), // copy_dir
+ bundle.c_str(), // link_dir
+ bundle.c_str(), // save_dir
+ lv2plugin_get_port_value, // get_value
+ (void*)this, // user_data
+ LV2_STATE_IS_POD|LV2_STATE_IS_PORTABLE, // flags
+ _features // features
);
lilv_state_set_label(state, name.c_str());
lilv_state_save(
_world.world, // world
- _uri_map.urid_map(), // map
- _uri_map.urid_unmap(), // unmap
+ _uri_map.urid_map(), // map
+ _uri_map.urid_unmap(), // unmap
state, // state
- pset_uri.c_str(), // uri
- save_dir.c_str(), // dir
- (name + ".ttl").c_str() // filename
+ NULL, // uri (NULL = use file URI)
+ bundle.c_str(), // dir
+ file_name.c_str() // filename
);
lilv_state_free(state);
- return pset_uri;
+
+ return Glib::filename_to_uri(Glib::build_filename(bundle, file_name));
}
void
deactivate();
}
-LilvPort*
+const LilvPort*
LV2Plugin::Impl::designated_input (const char* uri, void** bufptrs[], void** bufptr)
{
- LilvPort* port = NULL;
+ const LilvPort* port = NULL;
LilvNode* designation = lilv_new_uri(_world.world, uri);
port = lilv_plugin_get_port_by_designation(
plugin, _world.lv2_InputPort, designation);