summaryrefslogtreecommitdiff
path: root/libs
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2012-02-28 04:34:30 +0000
committerDavid Robillard <d@drobilla.net>2012-02-28 04:34:30 +0000
commitc9907c647dbe4b5bbd34539b06fbbbcd116c0b9c (patch)
tree2a54e9bf30fc941101eef7ae6cc8213a7405a3ba /libs
parent75ee0d49e285c12e2c0f746163c58c580c54aa61 (diff)
Implement special BPM and free-wheeling control ports.
Input control ports with lv2:hasProperty http://lv2plug.in/ns/ext/time#beatsPerMinute or http://lv2plug.in/ns/lv2core#freeWheeling will be automatically set by Ardour accordingly. git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@11538 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs')
-rw-r--r--libs/ardour/ardour/lv2_plugin.h4
-rw-r--r--libs/ardour/lv2_plugin.cc61
2 files changed, 60 insertions, 5 deletions
diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h
index 2377d14a86..fe16db6694 100644
--- a/libs/ardour/ardour/lv2_plugin.h
+++ b/libs/ardour/ardour/lv2_plugin.h
@@ -136,7 +136,9 @@ class LV2Plugin : public ARDOUR::Plugin
float* _control_data;
float* _shadow_data;
float* _defaults;
- float* _latency_control_port;
+ float* _bpm_control_port; ///< Special input set by ardour
+ float* _freewheel_control_port; ///< Special input set by ardour
+ float* _latency_control_port; ///< Special output set by plugin
bool _was_activated;
vector<bool> _port_is_input;
diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc
index db77f3b8bf..786a034575 100644
--- a/libs/ardour/lv2_plugin.cc
+++ b/libs/ardour/lv2_plugin.cc
@@ -37,6 +37,7 @@
#include <ardour/session.h>
#include <ardour/audioengine.h>
#include <ardour/lv2_plugin.h>
+#include <ardour/tempo.h>
#include <pbd/stl_delete.h>
@@ -97,14 +98,30 @@ LV2Plugin::init (LV2World& world, LilvPlugin* plugin, nframes_t rate)
_ui = NULL;
_control_data = 0;
_shadow_data = 0;
- _latency_control_port = 0;
+ _bpm_control_port = NULL;
+ _freewheel_control_port = NULL;
+ _latency_control_port = NULL;
_was_activated = false;
+ _instance_access_feature.URI = "http://lv2plug.in/ns/ext/instance-access";
+ _data_access_feature.URI = "http://lv2plug.in/ns/ext/data-access";
+
+ _features = (LV2_Feature**)malloc(sizeof(LV2_Feature*) * 5);
+ _features[0] = &_instance_access_feature;
+ _features[1] = &_data_access_feature;
+ _features[2] = &_urid_map_feature;
+ _features[3] = &_urid_unmap_feature;
+ _features[4] = NULL;
+
_instance = lilv_plugin_instantiate(plugin, rate, _features);
_name = lilv_plugin_get_name(plugin);
- assert(_name);
_author = lilv_plugin_get_author_name(plugin);
+ _instance_access_feature.data = (void*)_instance->lv2_handle;
+
+ _data_access_extension_data.extension_data = _instance->lv2_descriptor->extension_data;
+ _data_access_feature.data = &_data_access_extension_data;
+
if (_instance == 0) {
error << _("LV2: Failed to instantiate plugin ") << lilv_plugin_get_uri(plugin) << endl;
throw failed_constructor();
@@ -141,7 +158,21 @@ LV2Plugin::init (LV2World& world, LilvPlugin* plugin, nframes_t rate)
_defaults = new float[num_ports];
const bool latent = lilv_plugin_has_latency(plugin);
- uint32_t latency_port = (latent ? lilv_plugin_get_latency_port_index(plugin) : 0);
+ uint32_t latency_index = (latent ? lilv_plugin_get_latency_port_index(plugin) : 0);
+
+#ifdef HAVE_NEW_LILV
+ #define NS_TIME "http://lv2plug.in/ns/ext/time#"
+ LilvNode* time_bpm = lilv_new_uri(_world.world, NS_TIME "beatsPerMinute");
+ LilvNode* lv2_freeWheeling = lilv_new_uri(_world.world, LILV_NS_LV2 "freeWheeling");
+
+ LilvPort* bpm_port = lilv_plugin_get_port_by_parameter(
+ plugin, _world.input_class, time_bpm);
+ LilvPort* freewheel_port = lilv_plugin_get_port_by_parameter(
+ plugin, _world.output_class, lv2_freeWheeling);
+
+ lilv_node_free(lv2_freeWheeling);
+ lilv_node_free(time_bpm);
+#endif
for (uint32_t i = 0; i < num_ports; ++i) {
if (parameter_is_control(i)) {
@@ -153,11 +184,23 @@ LV2Plugin::init (LV2World& world, LilvPlugin* plugin, nframes_t rate)
lilv_instance_connect_port (_instance, i, &_control_data[i]);
- if (latent && i == latency_port) {
+ if (latent && i == latency_index) {
_latency_control_port = &_control_data[i];
*_latency_control_port = 0;
}
+#ifdef HAVE_NEW_LILV
+ if (parameter_is_input(i) && bpm_port
+ && i == lilv_port_get_index(plugin, bpm_port)) {
+ _bpm_control_port = &_shadow_data[i];
+ }
+
+ if (parameter_is_input(i) && freewheel_port
+ && i == lilv_port_get_index(plugin, freewheel_port)) {
+ _freewheel_control_port = &_shadow_data[i];
+ }
+#endif // HAVE_NEW_LILV
+
if (parameter_is_input(i)) {
_shadow_data[i] = default_value (i);
}
@@ -484,6 +527,16 @@ LV2Plugin::connect_and_run (vector<Sample*>& bufs, uint32_t nbufs, int32_t& in_i
then = get_cycles ();
+ if (_freewheel_control_port) {
+ *_freewheel_control_port = _session.engine().freewheeling ();
+ }
+
+ if (_bpm_control_port) {
+ TempoMap& tmap (_session.tempo_map ());
+ TempoMap::Metric metric = tmap.metric_at (_session.transport_frame () + offset);
+ *_bpm_control_port = metric.tempo().beats_per_minute ();
+ }
+
while (port_index < parameter_count()) {
if (parameter_is_audio(port_index)) {
if (parameter_is_input(port_index)) {