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
This commit is contained in:
David Robillard 2012-02-28 04:34:30 +00:00
parent 75ee0d49e2
commit c9907c647d
3 changed files with 63 additions and 5 deletions

View file

@ -559,6 +559,9 @@ if env['LV2']:
libraries['lilv'] = LibraryInfo()
libraries['lilv'].ParseConfig('pkg-config --cflags --libs lilv-0')
env.Append (CCFLAGS="-DHAVE_LV2")
if conf.CheckPKGVersion('lilv-0', '0.10.0'):
env.Append (CCFLAGS="-DHAVE_NEW_LILV")
else:
print 'LV2 support is not enabled (Lilv not found or older than 0.4.0)'
env['LV2'] = 0

View file

@ -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;

View file

@ -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)) {