allow LV2 plugins to query current block-size.

This is akin to VST2's audioMasterGetBlockSize.
It returns the current nominal block size (think jack-buffersize).

It's not the only block size that may be used when calling run(), it's
just the normal one. The actual block sizes used may be larger or smaller
and may vary between successive calls of run().

This change became neccesary after 53e969e9. Some plugins expected 
maxBlockLength to be the /current/ buffer-size and not all-time maxiumum.
Those plugins can now use nominalBlockLength.
This commit is contained in:
Robin Gareus
2015-09-10 00:55:28 +02:00
parent 390ea007c5
commit 09caf8336f
2 changed files with 46 additions and 11 deletions

View File

@@ -96,7 +96,7 @@ class LIBARDOUR_API LV2Plugin : public ARDOUR::Plugin, public ARDOUR::Workee
void deactivate ();
void cleanup ();
int set_block_size (pframes_t /*nframes*/) { return 0; }
int set_block_size (pframes_t);
int connect_and_run (BufferSet& bufs,
ChanMapping in, ChanMapping out,

View File

@@ -158,6 +158,7 @@ public:
#ifdef HAVE_LV2_1_2_0
LilvNode* bufz_powerOf2BlockLength;
LilvNode* bufz_fixedBlockLength;
LilvNode* bufz_nominalBlockLength;
#endif
private:
@@ -238,7 +239,9 @@ log_printf(LV2_Log_Handle handle,
struct LV2Plugin::Impl {
Impl() : plugin(0), ui(0), ui_type(0), name(0), author(0), instance(0)
, work_iface(0)
, opts_iface(0)
, state(0)
, block_length(0)
{}
/** Find the LV2 input port with the given designation.
@@ -246,16 +249,18 @@ struct LV2Plugin::Impl {
*/
const LilvPort* designated_input (const char* uri, void** bufptrs[], void** bufptr);
const LilvPlugin* plugin;
const LilvUI* ui;
const LilvNode* ui_type;
LilvNode* name;
LilvNode* author;
LilvInstance* instance;
const LV2_Worker_Interface* work_iface;
LilvState* state;
LV2_Atom_Forge forge;
LV2_Atom_Forge ui_forge;
const LilvPlugin* plugin;
const LilvUI* ui;
const LilvNode* ui_type;
LilvNode* name;
LilvNode* author;
LilvInstance* instance;
const LV2_Worker_Interface* work_iface;
const LV2_Options_Interface* opts_iface;
LilvState* state;
LV2_Atom_Forge forge;
LV2_Atom_Forge ui_forge;
int32_t block_length;
};
LV2Plugin::LV2Plugin (AudioEngine& engine,
@@ -317,6 +322,7 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
_state_version = 0;
_was_activated = false;
_has_state_interface = false;
_impl->block_length = _session.get_block_size();
_instance_access_feature.URI = "http://lv2plug.in/ns/ext/instance-access";
_data_access_feature.URI = "http://lv2plug.in/ns/ext/data-access";
@@ -374,6 +380,8 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
sizeof(int32_t), atom_Int, &_max_block_length },
{ LV2_OPTIONS_INSTANCE, 0, _uri_map.uri_to_id(LV2_BUF_SIZE__sequenceSize),
sizeof(int32_t), atom_Int, &_seq_size },
{ LV2_OPTIONS_INSTANCE, 0, _uri_map.uri_to_id("http://lv2plug.in/ns/ext/buf-size#nominalBlockLength"),
sizeof(int32_t), atom_Int, &_impl->block_length },
{ LV2_OPTIONS_INSTANCE, 0, 0, 0, 0, NULL }
};
@@ -427,6 +435,14 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
}
lilv_node_free(worker_iface_uri);
LilvNode* options_iface_uri = lilv_new_uri(_world.world, LV2_OPTIONS__interface);
if (lilv_plugin_has_extension_data(plugin, options_iface_uri)) {
_impl->opts_iface = (const LV2_Options_Interface*)extension_data(
LV2_OPTIONS__interface);
}
lilv_node_free(options_iface_uri);
if (lilv_plugin_has_feature(plugin, _world.lv2_inPlaceBroken)) {
error << string_compose(
_("LV2: \"%1\" cannot be used, since it cannot do inplace processing."),
@@ -636,6 +652,23 @@ LV2Plugin::init(const void* c_plugin, framecnt_t rate)
latency_compute_run();
}
int
LV2Plugin::set_block_size (pframes_t nframes)
{
#ifdef HAVE_LV2_1_2_0
if (_impl->opts_iface) {
LV2_URID atom_Int = _uri_map.uri_to_id(LV2_ATOM__Int);
_impl->block_length = nframes;
LV2_Options_Option block_size_option = {
LV2_OPTIONS_INSTANCE, 0, _uri_map.uri_to_id ("http://lv2plug.in/ns/ext/buf-size#nominalBlockLength"),
sizeof(int32_t), atom_Int, (void*)&_impl->block_length
};
_impl->opts_iface->set (_impl->instance->lv2_handle, &block_size_option);
}
#endif
return 0;
}
LV2Plugin::~LV2Plugin ()
{
DEBUG_TRACE(DEBUG::LV2, string_compose("%1 destroy\n", name()));
@@ -2395,6 +2428,7 @@ LV2World::LV2World()
#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);
bufz_nominalBlockLength = lilv_new_uri(world, "http://lv2plug.in/ns/ext/buf-size#nominalBlockLength");
#endif
}
@@ -2402,6 +2436,7 @@ LV2World::LV2World()
LV2World::~LV2World()
{
#ifdef HAVE_LV2_1_2_0
lilv_node_free(bufz_nominalBlockLength);
lilv_node_free(bufz_fixedBlockLength);
lilv_node_free(bufz_powerOf2BlockLength);
#endif