diff options
author | David Robillard <d@drobilla.net> | 2012-04-10 20:46:32 +0000 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2012-04-10 20:46:32 +0000 |
commit | 96a8a645363c878e41038f1fdee83bb4bb4e9869 (patch) | |
tree | eebeb2a36aa27af2c488db63429faffc36930678 /libs/ardour | |
parent | 99ba7de59182a0f474c92a862d42c53ccd56ada2 (diff) |
Forward port LV2 BPM and freewheeling port stuff from 2.0-ongoing.
Fix worker implementation to preserve error codes.
git-svn-id: svn://localhost/ardour2/branches/3.0@11877 d708f5d6-7413-0410-9779-e7cbd77b26cf
Diffstat (limited to 'libs/ardour')
-rw-r--r-- | libs/ardour/ardour/lv2_plugin.h | 10 | ||||
-rw-r--r-- | libs/ardour/ardour/worker.h | 4 | ||||
-rw-r--r-- | libs/ardour/lv2_plugin.cc | 75 | ||||
-rw-r--r-- | libs/ardour/wscript | 2 |
4 files changed, 71 insertions, 20 deletions
diff --git a/libs/ardour/ardour/lv2_plugin.h b/libs/ardour/ardour/lv2_plugin.h index d96a15a173..90c456c1f8 100644 --- a/libs/ardour/ardour/lv2_plugin.h +++ b/libs/ardour/ardour/lv2_plugin.h @@ -1,5 +1,5 @@ /* - Copyright (C) 2008-2011 Paul Davis + Copyright (C) 2008-2012 Paul Davis Author: David Robillard This program is free software; you can redistribute it and/or modify @@ -132,8 +132,8 @@ class LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee Worker* worker() { return _worker; } - void work(uint32_t size, const void* data); - void work_response(uint32_t size, const void* data); + int work(uint32_t size, const void* data); + int work_response(uint32_t size, const void* data); static URIMap _uri_map; @@ -155,7 +155,9 @@ class LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee float* _shadow_data; float* _defaults; LV2_Evbuf** _ev_buffers; - 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 ardour PBD::ID _insert_id; typedef enum { diff --git a/libs/ardour/ardour/worker.h b/libs/ardour/ardour/worker.h index eca5aa21ca..984e375c80 100644 --- a/libs/ardour/ardour/worker.h +++ b/libs/ardour/ardour/worker.h @@ -39,12 +39,12 @@ public: /** Do some work in the worker thread. */ - virtual void work(uint32_t size, const void* data) = 0; + virtual int work(uint32_t size, const void* data) = 0; /** Handle a response from the worker thread in the audio thread. */ - virtual void work_response(uint32_t size, const void* data) = 0; + virtual int work_response(uint32_t size, const void* data) = 0; }; /** diff --git a/libs/ardour/lv2_plugin.cc b/libs/ardour/lv2_plugin.cc index 2880fa43aa..7a2dc0b750 100644 --- a/libs/ardour/lv2_plugin.cc +++ b/libs/ardour/lv2_plugin.cc @@ -1,5 +1,5 @@ /* - Copyright (C) 2008-2011 Paul Davis + Copyright (C) 2008-2012 Paul Davis Author: David Robillard This program is free software; you can redistribute it and/or modify @@ -43,6 +43,7 @@ #include "ardour/debug.h" #include "ardour/lv2_plugin.h" #include "ardour/session.h" +#include "ardour/tempo.h" #include "ardour/worker.h" #include "i18n.h" @@ -124,7 +125,7 @@ work_schedule(LV2_Worker_Schedule_Handle handle, LV2Plugin* plugin = (LV2Plugin*)handle; if (plugin->session().engine().freewheeling()) { // Freewheeling, do the work immediately in this (audio) thread - plugin->work(size, data); + return (LV2_Worker_Status)plugin->work(size, data); } else { // Enqueue message for the worker thread return plugin->worker()->schedule(size, data) ? @@ -141,7 +142,7 @@ work_respond(LV2_Worker_Respond_Handle handle, LV2Plugin* plugin = (LV2Plugin*)handle; if (plugin->session().engine().freewheeling()) { // Freewheeling, respond immediately in this (audio) thread - plugin->work_response(size, data); + return (LV2_Worker_Status)plugin->work_response(size, data); } else { // Enqueue response for the worker return plugin->worker()->respond(size, data) ? @@ -156,6 +157,12 @@ struct LV2Plugin::Impl { , state(0) #endif {} + + /** 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); + LilvPlugin* plugin; const LilvUI* ui; const LilvNode* ui_type; @@ -326,17 +333,27 @@ LV2Plugin::init(void* c_plugin, framecnt_t rate) _port_flags.push_back(flags); } - const bool latent = lilv_plugin_has_latency(plugin); - const uint32_t latency_port = (latent) - ? lilv_plugin_get_latency_port_index(plugin) - : 0; - _control_data = new float[num_ports]; _shadow_data = new float[num_ports]; _defaults = new float[num_ports]; _ev_buffers = new LV2_Evbuf*[num_ports]; memset(_ev_buffers, 0, sizeof(LV2_Evbuf*) * num_ports); + const bool latent = lilv_plugin_has_latency(plugin); + const uint32_t latency_index = (latent) + ? lilv_plugin_get_latency_port_index(plugin) + : 0; + +#define NS_TIME "http://lv2plug.in/ns/ext/time#" + + // Build an array of pointers to special parameter buffers + void*** params = new void**[num_ports]; + for (uint32_t i = 0; i < num_ports; ++i) { + params[i] = NULL; + } + _impl->designated_input (NS_TIME "beatsPerMinute", params, (void**)&_bpm_control_port); + _impl->designated_input (LILV_NS_LV2 "freeWheeling", params, (void**)&_freewheel_control_port); + for (uint32_t i = 0; i < num_ports; ++i) { const LilvPort* port = lilv_plugin_get_port_by_index(plugin, i); const LilvNode* sym = lilv_port_get_symbol(plugin, port); @@ -356,19 +373,24 @@ LV2Plugin::init(void* c_plugin, framecnt_t rate) lilv_instance_connect_port(_impl->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; } if (parameter_is_input(i)) { _shadow_data[i] = default_value(i); + if (params[i]) { + *params[i] = (void*)&_shadow_data[i]; + } } } else { _defaults[i] = 0.0f; } } + delete[] params; + LilvUIs* uis = lilv_plugin_get_uis(plugin); if (lilv_uis_size(uis) > 0) { #ifdef HAVE_SUIL @@ -948,17 +970,18 @@ LV2Plugin::emit_to_ui(void* controller, UIMessageSink sink) } } -void +int LV2Plugin::work(uint32_t size, const void* data) { - _impl->work_iface->work( + return _impl->work_iface->work( _impl->instance->lv2_handle, work_respond, this, size, data); } -void +int LV2Plugin::work_response(uint32_t size, const void* data) { - _impl->work_iface->work_response(_impl->instance->lv2_handle, size, data); + return _impl->work_iface->work_response( + _impl->instance->lv2_handle, size, data); } void @@ -1170,6 +1193,16 @@ LV2Plugin::connect_and_run(BufferSet& bufs, cycles_t then = get_cycles(); + if (_freewheel_control_port) { + *_freewheel_control_port = _session.engine().freewheeling (); + } + + if (_bpm_control_port) { + TempoMap& tmap (_session.tempo_map ()); + Tempo tempo = tmap.tempo_at (_session.transport_frame () + offset); + *_bpm_control_port = tempo.beats_per_minute (); + } + ChanCount bufs_count; bufs_count.set(DataType::AUDIO, 1); bufs_count.set(DataType::MIDI, 1); @@ -1421,6 +1454,22 @@ LV2Plugin::latency_compute_run() deactivate(); } +LilvPort* +LV2Plugin::Impl::designated_input (const char* uri, void** bufptrs[], void** bufptr) +{ + LilvPort* port = NULL; +#ifdef HAVE_NEW_LILV + LilvNode* designation = lilv_new_uri(_world.world, uri); + port = lilv_plugin_get_port_by_designation( + plugin, _world.lv2_InputPort, designation); + lilv_node_free(designation); + if (port) { + bufptrs[lilv_port_get_index(plugin, port)] = bufptr; + } +#endif + return port; +} + LV2World::LV2World() : world(lilv_world_new()) { diff --git a/libs/ardour/wscript b/libs/ardour/wscript index b12ebf593d..e744b3818a 100644 --- a/libs/ardour/wscript +++ b/libs/ardour/wscript @@ -261,7 +261,7 @@ def configure(conf): autowaf.check_pkg(conf, 'lilv-0', uselib_store='LILV', atleast_version='0.0.0', mandatory=False) autowaf.check_pkg(conf, 'lilv-0', uselib_store='NEW_LILV', - atleast_version='0.11.0', mandatory=False) + atleast_version='0.14.0', mandatory=False) if conf.is_defined('HAVE_LILV'): autowaf.check_pkg(conf, 'suil-0', uselib_store='SUIL', atleast_version='0.2.0', mandatory=False) |