outline a "NoSampleAccurateControl" LV2 feature:
Since control-ports have a fixed value for the current process-block, Ardour splits a plugin's run() process cycle on every automation event to facilitate sample-accurate automation. Since automation is interpolated between events, this ensures that each explicit automation point is reached (not interpolated). Plugins where this is not required and which favor a fixed block-size, can now specify an optional Feature: NoSampleAccurateControl. One example: a convolution plugin with smoothed gain control.
This commit is contained in:
parent
bc15146560
commit
065d7c852a
|
@ -97,6 +97,7 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
|
|||
void cleanup ();
|
||||
|
||||
int set_block_size (pframes_t);
|
||||
bool requires_fixed_sized_buffers () const;
|
||||
|
||||
int connect_and_run (BufferSet& bufs,
|
||||
ChanMapping in, ChanMapping out,
|
||||
|
@ -178,6 +179,7 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
|
|||
uint32_t _patch_port_in_index;
|
||||
uint32_t _patch_port_out_index;
|
||||
URIMap& _uri_map;
|
||||
bool _no_sample_accurate_ctrl;
|
||||
|
||||
friend const void* lv2plugin_get_port_value(const char* port_symbol,
|
||||
void* user_data,
|
||||
|
|
|
@ -155,6 +155,7 @@ public:
|
|||
LilvNode* units_midiNote;
|
||||
LilvNode* patch_writable;
|
||||
LilvNode* patch_Message;
|
||||
LilvNode* lv2_noSampleAccurateCtrl;
|
||||
#ifdef HAVE_LV2_1_2_0
|
||||
LilvNode* bufz_powerOf2BlockLength;
|
||||
LilvNode* bufz_fixedBlockLength;
|
||||
|
@ -286,6 +287,7 @@ LV2Plugin::LV2Plugin (AudioEngine& engine,
|
|||
, _patch_port_in_index((uint32_t)-1)
|
||||
, _patch_port_out_index((uint32_t)-1)
|
||||
, _uri_map(URIMap::instance())
|
||||
, _no_sample_accurate_ctrl (false)
|
||||
{
|
||||
init(c_plugin, rate);
|
||||
}
|
||||
|
@ -300,6 +302,7 @@ LV2Plugin::LV2Plugin (const LV2Plugin& other)
|
|||
, _patch_port_in_index((uint32_t)-1)
|
||||
, _patch_port_out_index((uint32_t)-1)
|
||||
, _uri_map(URIMap::instance())
|
||||
, _no_sample_accurate_ctrl (false)
|
||||
{
|
||||
init(other._impl->plugin, other._sample_rate);
|
||||
|
||||
|
@ -481,6 +484,12 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
|
|||
throw failed_constructor();
|
||||
}
|
||||
lilv_nodes_free(required_features);
|
||||
|
||||
LilvNodes* optional_features = lilv_plugin_get_optional_features (plugin);
|
||||
if (lilv_nodes_contains (optional_features, _world.lv2_noSampleAccurateCtrl)) {
|
||||
_no_sample_accurate_ctrl = true;
|
||||
}
|
||||
lilv_nodes_free(optional_features);
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_LILV_0_16_0
|
||||
|
@ -685,6 +694,25 @@ LV2Plugin::set_block_size (pframes_t nframes)
|
|||
return 0;
|
||||
}
|
||||
|
||||
bool
|
||||
LV2Plugin::requires_fixed_sized_buffers () const
|
||||
{
|
||||
/* This controls if Ardour will split the plugin's run()
|
||||
* on automation events in order to pass sample-accurate automation
|
||||
* via standard control-ports.
|
||||
*
|
||||
* When returning true Ardour will *not* sub-divide the process-cycle.
|
||||
* Automation events that happen between cycle-start and cycle-end will be
|
||||
* ignored (ctrl values are interpolated to cycle-start).
|
||||
* NB. Atom Sequences are still sample accurate.
|
||||
*
|
||||
* Note: This does not guarantee a fixed block-size.
|
||||
* e.g The process cycle may be split when looping, also
|
||||
* the period-size may change any time: see set_block_size()
|
||||
*/
|
||||
return _no_sample_accurate_ctrl;
|
||||
}
|
||||
|
||||
LV2Plugin::~LV2Plugin ()
|
||||
{
|
||||
DEBUG_TRACE(DEBUG::LV2, string_compose("%1 destroy\n", name()));
|
||||
|
@ -2448,6 +2476,7 @@ LV2World::LV2World()
|
|||
units_db = lilv_new_uri(world, LV2_UNITS__db);
|
||||
patch_writable = lilv_new_uri(world, LV2_PATCH__writable);
|
||||
patch_Message = lilv_new_uri(world, LV2_PATCH__Message);
|
||||
lv2_noSampleAccurateCtrl = lilv_new_uri(world, LV2_CORE_PREFIX "NoSampleAccurateCtrl"); // XXX
|
||||
#ifdef HAVE_LV2_1_2_0
|
||||
bufz_powerOf2BlockLength = lilv_new_uri(world, LV2_BUF_SIZE__powerOf2BlockLength);
|
||||
bufz_fixedBlockLength = lilv_new_uri(world, LV2_BUF_SIZE__fixedBlockLength);
|
||||
|
@ -2463,6 +2492,7 @@ LV2World::~LV2World()
|
|||
lilv_node_free(bufz_fixedBlockLength);
|
||||
lilv_node_free(bufz_powerOf2BlockLength);
|
||||
#endif
|
||||
lilv_node_free(lv2_noSampleAccurateCtrl);
|
||||
lilv_node_free(patch_Message);
|
||||
lilv_node_free(patch_writable);
|
||||
lilv_node_free(units_hz);
|
||||
|
|
Loading…
Reference in New Issue
Block a user