mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05:00
filter-chain: improve lv2 support
Add support for Worker. Add Options feature. Pass support in plugin load.
This commit is contained in:
parent
c04580a256
commit
8416d66ab3
5 changed files with 183 additions and 46 deletions
|
|
@ -39,7 +39,6 @@
|
||||||
#include <spa/utils/string.h>
|
#include <spa/utils/string.h>
|
||||||
#include <spa/utils/json.h>
|
#include <spa/utils/json.h>
|
||||||
#include <spa/param/profiler.h>
|
#include <spa/param/profiler.h>
|
||||||
#include <spa/support/cpu.h>
|
|
||||||
#include <spa/debug/pod.h>
|
#include <spa/debug/pod.h>
|
||||||
|
|
||||||
#include <pipewire/utils.h>
|
#include <pipewire/utils.h>
|
||||||
|
|
@ -739,6 +738,8 @@ static struct plugin *plugin_load(struct impl *impl, const char *type, const cha
|
||||||
struct fc_plugin *pl = NULL;
|
struct fc_plugin *pl = NULL;
|
||||||
struct plugin *hndl;
|
struct plugin *hndl;
|
||||||
int res = 0;
|
int res = 0;
|
||||||
|
const struct spa_support *support;
|
||||||
|
uint32_t n_support;
|
||||||
|
|
||||||
spa_list_for_each(hndl, &impl->plugin_list, link) {
|
spa_list_for_each(hndl, &impl->plugin_list, link) {
|
||||||
if (spa_streq(hndl->type, type) &&
|
if (spa_streq(hndl->type, type) &&
|
||||||
|
|
@ -747,16 +748,17 @@ static struct plugin *plugin_load(struct impl *impl, const char *type, const cha
|
||||||
return hndl;
|
return hndl;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
support = pw_context_get_support(impl->context, &n_support);
|
||||||
|
|
||||||
if (spa_streq(type, "builtin")) {
|
if (spa_streq(type, "builtin")) {
|
||||||
pl = load_builtin_plugin(path, NULL);
|
pl = load_builtin_plugin(support, n_support, path, NULL);
|
||||||
}
|
}
|
||||||
else if (spa_streq(type, "ladspa")) {
|
else if (spa_streq(type, "ladspa")) {
|
||||||
pl = load_ladspa_plugin(path, NULL);
|
pl = load_ladspa_plugin(support, n_support, path, NULL);
|
||||||
}
|
}
|
||||||
#ifdef HAVE_LILV
|
#ifdef HAVE_LILV
|
||||||
else if (spa_streq(type, "lv2")) {
|
else if (spa_streq(type, "lv2")) {
|
||||||
pl = load_lv2_plugin(path, NULL);
|
pl = load_lv2_plugin(support, n_support, path, NULL);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (pl == NULL)
|
if (pl == NULL)
|
||||||
|
|
@ -1280,6 +1282,7 @@ static int setup_graph(struct graph *graph, struct spa_json *inputs, struct spa_
|
||||||
sd = dd = NULL;
|
sd = dd = NULL;
|
||||||
|
|
||||||
for (i = 0; i < n_hndl; i++) {
|
for (i = 0; i < n_hndl; i++) {
|
||||||
|
pw_log_info("instantiate %s %d", d->name, i);
|
||||||
if ((node->hndl[i] = d->instantiate(d, &impl->rate, i, node->config)) == NULL) {
|
if ((node->hndl[i] = d->instantiate(d, &impl->rate, i, node->config)) == NULL) {
|
||||||
pw_log_error("cannot create plugin instance");
|
pw_log_error("cannot create plugin instance");
|
||||||
res = -ENOMEM;
|
res = -ENOMEM;
|
||||||
|
|
@ -1650,9 +1653,6 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
||||||
struct impl *impl;
|
struct impl *impl;
|
||||||
uint32_t id = pw_global_get_id(pw_impl_module_get_global(module));
|
uint32_t id = pw_global_get_id(pw_impl_module_get_global(module));
|
||||||
const char *str;
|
const char *str;
|
||||||
const struct spa_support *support;
|
|
||||||
uint32_t n_support;
|
|
||||||
struct spa_cpu *cpu_iface;
|
|
||||||
int res;
|
int res;
|
||||||
|
|
||||||
PW_LOG_TOPIC_INIT(mod_topic);
|
PW_LOG_TOPIC_INIT(mod_topic);
|
||||||
|
|
@ -1663,10 +1663,6 @@ int pipewire__module_init(struct pw_impl_module *module, const char *args)
|
||||||
|
|
||||||
pw_log_debug("module %p: new %s", impl, args);
|
pw_log_debug("module %p: new %s", impl, args);
|
||||||
|
|
||||||
support = pw_context_get_support(context, &n_support);
|
|
||||||
cpu_iface = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU);
|
|
||||||
init_builtin_plugin(cpu_iface ? spa_cpu_get_flags(cpu_iface) : 0);
|
|
||||||
|
|
||||||
if (args)
|
if (args)
|
||||||
props = pw_properties_new_string(args);
|
props = pw_properties_new_string(args);
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -30,6 +30,8 @@
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include <spa/utils/json.h>
|
#include <spa/utils/json.h>
|
||||||
|
#include <spa/support/cpu.h>
|
||||||
|
|
||||||
#include <pipewire/log.h>
|
#include <pipewire/log.h>
|
||||||
|
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
@ -771,12 +773,11 @@ static struct fc_plugin builtin_plugin = {
|
||||||
.make_desc = builtin_make_desc
|
.make_desc = builtin_make_desc
|
||||||
};
|
};
|
||||||
|
|
||||||
struct fc_plugin *load_builtin_plugin(const char *plugin, const char *config)
|
struct fc_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support,
|
||||||
|
const char *plugin, const char *config)
|
||||||
{
|
{
|
||||||
|
struct spa_cpu *cpu_iface;
|
||||||
|
cpu_iface = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_CPU);
|
||||||
|
pffft_select_cpu(cpu_iface ? spa_cpu_get_flags(cpu_iface) : 0);
|
||||||
return &builtin_plugin;
|
return &builtin_plugin;
|
||||||
}
|
}
|
||||||
|
|
||||||
void init_builtin_plugin(uint32_t cpu_flags)
|
|
||||||
{
|
|
||||||
pffft_select_cpu(cpu_flags);
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -226,7 +226,8 @@ exit:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fc_plugin *load_ladspa_plugin(const char *plugin, const char *config)
|
struct fc_plugin *load_ladspa_plugin(const struct spa_support *support, uint32_t n_support,
|
||||||
|
const char *plugin, const char *config)
|
||||||
{
|
{
|
||||||
struct fc_plugin *pl = NULL;
|
struct fc_plugin *pl = NULL;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include <spa/utils/defs.h>
|
#include <spa/utils/defs.h>
|
||||||
#include <spa/utils/list.h>
|
#include <spa/utils/list.h>
|
||||||
#include <spa/utils/string.h>
|
#include <spa/utils/string.h>
|
||||||
|
#include <spa/support/loop.h>
|
||||||
|
|
||||||
#include <pipewire/log.h>
|
#include <pipewire/log.h>
|
||||||
#include <pipewire/utils.h>
|
#include <pipewire/utils.h>
|
||||||
|
|
@ -36,6 +37,9 @@
|
||||||
#include <lilv/lilv.h>
|
#include <lilv/lilv.h>
|
||||||
#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
|
#include <lv2/lv2plug.in/ns/ext/atom/atom.h>
|
||||||
#include <lv2/lv2plug.in/ns/ext/buf-size/buf-size.h>
|
#include <lv2/lv2plug.in/ns/ext/buf-size/buf-size.h>
|
||||||
|
#include "lv2/lv2plug.in/ns/ext/worker/worker.h"
|
||||||
|
#include "lv2/lv2plug.in/ns/ext/options/options.h"
|
||||||
|
#include "lv2/lv2plug.in/ns/ext/parameters/parameters.h"
|
||||||
|
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
|
|
||||||
|
|
@ -61,17 +65,18 @@ static void uri_table_destroy(URITable *table)
|
||||||
static LV2_URID uri_table_map(LV2_URID_Map_Handle handle, const char *uri)
|
static LV2_URID uri_table_map(LV2_URID_Map_Handle handle, const char *uri)
|
||||||
{
|
{
|
||||||
URITable *table = (URITable*)handle;
|
URITable *table = (URITable*)handle;
|
||||||
char *p;
|
char **p;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
|
|
||||||
pw_array_for_each(p, &table->array) {
|
pw_array_for_each(p, &table->array) {
|
||||||
if (spa_streq(p, uri))
|
|
||||||
return i + 1;
|
|
||||||
i++;
|
i++;
|
||||||
|
if (spa_streq(*p, uri))
|
||||||
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
pw_array_add_ptr(&table->array, strdup(uri));
|
pw_array_add_ptr(&table->array, strdup(uri));
|
||||||
return pw_array_get_len(&table->array, char*);
|
i = pw_array_get_len(&table->array, char*);
|
||||||
|
done:
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *uri_table_unmap(LV2_URID_Map_Handle handle, LV2_URID urid)
|
static const char *uri_table_unmap(LV2_URID_Map_Handle handle, LV2_URID urid)
|
||||||
|
|
@ -87,6 +92,9 @@ struct context {
|
||||||
int ref;
|
int ref;
|
||||||
LilvWorld *world;
|
LilvWorld *world;
|
||||||
|
|
||||||
|
struct spa_loop *data_loop;
|
||||||
|
struct spa_loop *main_loop;
|
||||||
|
|
||||||
LilvNode *lv2_InputPort;
|
LilvNode *lv2_InputPort;
|
||||||
LilvNode *lv2_OutputPort;
|
LilvNode *lv2_OutputPort;
|
||||||
LilvNode *lv2_AudioPort;
|
LilvNode *lv2_AudioPort;
|
||||||
|
|
@ -98,18 +106,25 @@ struct context {
|
||||||
LilvNode *powerOf2BlockLength;
|
LilvNode *powerOf2BlockLength;
|
||||||
LilvNode *fixedBlockLength;
|
LilvNode *fixedBlockLength;
|
||||||
LilvNode *boundedBlockLength;
|
LilvNode *boundedBlockLength;
|
||||||
|
LilvNode* worker_schedule;
|
||||||
|
LilvNode* worker_iface;
|
||||||
|
|
||||||
URITable uri_table;
|
URITable uri_table;
|
||||||
LV2_URID_Map map;
|
LV2_URID_Map map;
|
||||||
LV2_URID_Unmap unmap;
|
|
||||||
LV2_Feature map_feature;
|
LV2_Feature map_feature;
|
||||||
|
LV2_URID_Unmap unmap;
|
||||||
LV2_Feature unmap_feature;
|
LV2_Feature unmap_feature;
|
||||||
const LV2_Feature *features[5];
|
|
||||||
|
LV2_URID atom_Int;
|
||||||
|
LV2_URID atom_Float;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#define context_map(c,uri) ((c)->map.map((c)->map.handle,(uri)))
|
||||||
|
|
||||||
static void context_free(struct context *c)
|
static void context_free(struct context *c)
|
||||||
{
|
{
|
||||||
if (c->world) {
|
if (c->world) {
|
||||||
|
lilv_node_free(c->worker_schedule);
|
||||||
lilv_node_free(c->powerOf2BlockLength);
|
lilv_node_free(c->powerOf2BlockLength);
|
||||||
lilv_node_free(c->fixedBlockLength);
|
lilv_node_free(c->fixedBlockLength);
|
||||||
lilv_node_free(c->boundedBlockLength);
|
lilv_node_free(c->boundedBlockLength);
|
||||||
|
|
@ -133,7 +148,7 @@ static const LV2_Feature buf_size_features[3] = {
|
||||||
{ LV2_BUF_SIZE__boundedBlockLength, NULL },
|
{ LV2_BUF_SIZE__boundedBlockLength, NULL },
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct context *context_new(void)
|
static struct context *context_new(const struct spa_support *support, uint32_t n_support)
|
||||||
{
|
{
|
||||||
struct context *c;
|
struct context *c;
|
||||||
|
|
||||||
|
|
@ -159,6 +174,8 @@ static struct context *context_new(void)
|
||||||
c->powerOf2BlockLength = lilv_new_uri(c->world, LV2_BUF_SIZE__powerOf2BlockLength);
|
c->powerOf2BlockLength = lilv_new_uri(c->world, LV2_BUF_SIZE__powerOf2BlockLength);
|
||||||
c->fixedBlockLength = lilv_new_uri(c->world, LV2_BUF_SIZE__fixedBlockLength);
|
c->fixedBlockLength = lilv_new_uri(c->world, LV2_BUF_SIZE__fixedBlockLength);
|
||||||
c->boundedBlockLength = lilv_new_uri(c->world, LV2_BUF_SIZE__boundedBlockLength);
|
c->boundedBlockLength = lilv_new_uri(c->world, LV2_BUF_SIZE__boundedBlockLength);
|
||||||
|
c->worker_schedule = lilv_new_uri(c->world, LV2_WORKER__schedule);
|
||||||
|
c->worker_iface = lilv_new_uri(c->world, LV2_WORKER__interface);
|
||||||
|
|
||||||
c->map.handle = &c->uri_table;
|
c->map.handle = &c->uri_table;
|
||||||
c->map.map = uri_table_map;
|
c->map.map = uri_table_map;
|
||||||
|
|
@ -168,11 +185,12 @@ static struct context *context_new(void)
|
||||||
c->unmap.unmap = uri_table_unmap;
|
c->unmap.unmap = uri_table_unmap;
|
||||||
c->unmap_feature.URI = LV2_URID_UNMAP_URI;
|
c->unmap_feature.URI = LV2_URID_UNMAP_URI;
|
||||||
c->unmap_feature.data = &c->unmap;
|
c->unmap_feature.data = &c->unmap;
|
||||||
c->features[0] = &c->map_feature;
|
|
||||||
c->features[1] = &c->unmap_feature;
|
c->atom_Int = context_map(c, LV2_ATOM__Int);
|
||||||
c->features[2] = &buf_size_features[0];
|
c->atom_Float = context_map(c, LV2_ATOM__Float);
|
||||||
c->features[3] = &buf_size_features[1];
|
|
||||||
c->features[4] = &buf_size_features[2];
|
c->data_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_DataLoop);
|
||||||
|
c->main_loop = spa_support_find(support, n_support, SPA_TYPE_INTERFACE_Loop);
|
||||||
|
|
||||||
return c;
|
return c;
|
||||||
error:
|
error:
|
||||||
|
|
@ -180,10 +198,10 @@ error:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct context *context_ref(void)
|
static struct context *context_ref(const struct spa_support *support, uint32_t n_support)
|
||||||
{
|
{
|
||||||
if (_context == NULL) {
|
if (_context == NULL) {
|
||||||
_context = context_new();
|
_context = context_new(support, n_support);
|
||||||
if (_context == NULL)
|
if (_context == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -210,38 +228,156 @@ struct descriptor {
|
||||||
struct plugin *p;
|
struct plugin *p;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct instance {
|
||||||
|
struct descriptor *desc;
|
||||||
|
LilvInstance *instance;
|
||||||
|
LV2_Worker_Schedule work_schedule;
|
||||||
|
LV2_Feature work_schedule_feature;
|
||||||
|
LV2_Options_Option options[6];
|
||||||
|
LV2_Feature options_feature;
|
||||||
|
|
||||||
|
const LV2_Feature *features[7];
|
||||||
|
|
||||||
|
const LV2_Worker_Interface *work_iface;
|
||||||
|
|
||||||
|
int32_t block_length;
|
||||||
|
};
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_respond(struct spa_loop *loop, bool async, uint32_t seq, const void *data,
|
||||||
|
size_t size, void *user_data)
|
||||||
|
{
|
||||||
|
struct instance *i = (struct instance*)user_data;
|
||||||
|
i->work_iface->work_response(i->instance->lv2_handle, size, data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called by the plugin to respond to non-RT work. */
|
||||||
|
static LV2_Worker_Status
|
||||||
|
work_respond(LV2_Worker_Respond_Handle handle, uint32_t size, const void *data)
|
||||||
|
{
|
||||||
|
struct instance *i = (struct instance*)handle;
|
||||||
|
struct context *c = i->desc->p->c;
|
||||||
|
spa_loop_invoke(c->data_loop, do_respond, 1, data, size, false, i);
|
||||||
|
return LV2_WORKER_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
do_schedule(struct spa_loop *loop, bool async, uint32_t seq, const void *data,
|
||||||
|
size_t size, void *user_data)
|
||||||
|
{
|
||||||
|
struct instance *i = (struct instance*)user_data;
|
||||||
|
i->work_iface->work(i->instance->lv2_handle, work_respond, i, size, data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/** Called by the plugin to schedule non-RT work. */
|
||||||
|
static LV2_Worker_Status
|
||||||
|
work_schedule(LV2_Worker_Schedule_Handle handle, uint32_t size, const void *data)
|
||||||
|
{
|
||||||
|
struct instance *i = (struct instance*)handle;
|
||||||
|
struct context *c = i->desc->p->c;
|
||||||
|
spa_loop_invoke(c->main_loop, do_schedule, 1, data, size, false, i);
|
||||||
|
return LV2_WORKER_SUCCESS;
|
||||||
|
}
|
||||||
|
|
||||||
static void *lv2_instantiate(const struct fc_descriptor *desc,
|
static void *lv2_instantiate(const struct fc_descriptor *desc,
|
||||||
unsigned long *SampleRate, int index, const char *config)
|
unsigned long *SampleRate, int index, const char *config)
|
||||||
{
|
{
|
||||||
struct descriptor *d = (struct descriptor*)desc;
|
struct descriptor *d = (struct descriptor*)desc;
|
||||||
struct plugin *p = d->p;
|
struct plugin *p = d->p;
|
||||||
struct context *c = p->c;
|
struct context *c = p->c;
|
||||||
return lilv_plugin_instantiate(p->p, *SampleRate, c->features);
|
struct instance *i;
|
||||||
|
uint32_t n_features = 0;
|
||||||
|
static const int32_t min_block_length = 1;
|
||||||
|
static const int32_t max_block_length = 8192;
|
||||||
|
static const int32_t seq_size = 32768;
|
||||||
|
float fsample_rate = *SampleRate;
|
||||||
|
|
||||||
|
i = calloc(1, sizeof(*i));
|
||||||
|
if (i == NULL)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
i->block_length = 1024;
|
||||||
|
i->desc = d;
|
||||||
|
i->features[n_features++] = &c->map_feature;
|
||||||
|
i->features[n_features++] = &c->unmap_feature;
|
||||||
|
i->features[n_features++] = &buf_size_features[0];
|
||||||
|
i->features[n_features++] = &buf_size_features[1];
|
||||||
|
i->features[n_features++] = &buf_size_features[2];
|
||||||
|
if (lilv_plugin_has_feature(p->p, c->worker_schedule)) {
|
||||||
|
i->work_schedule.handle = i;
|
||||||
|
i->work_schedule.schedule_work = work_schedule;
|
||||||
|
i->work_schedule_feature.URI = LV2_WORKER__schedule;
|
||||||
|
i->work_schedule_feature.data = &i->work_schedule;
|
||||||
|
i->features[n_features++] = &i->work_schedule_feature;
|
||||||
|
}
|
||||||
|
|
||||||
|
i->options[0] = (LV2_Options_Option) { LV2_OPTIONS_INSTANCE, 0,
|
||||||
|
context_map(c, LV2_BUF_SIZE__minBlockLength), sizeof(int32_t),
|
||||||
|
c->atom_Int, &min_block_length };
|
||||||
|
i->options[1] = (LV2_Options_Option) { LV2_OPTIONS_INSTANCE, 0,
|
||||||
|
context_map(c, LV2_BUF_SIZE__maxBlockLength), sizeof(int32_t),
|
||||||
|
c->atom_Int, &max_block_length };
|
||||||
|
i->options[2] = (LV2_Options_Option) { LV2_OPTIONS_INSTANCE, 0,
|
||||||
|
context_map(c, LV2_BUF_SIZE__sequenceSize), sizeof(int32_t),
|
||||||
|
c->atom_Int, &seq_size };
|
||||||
|
i->options[3] = (LV2_Options_Option) { LV2_OPTIONS_INSTANCE, 0,
|
||||||
|
context_map(c, "http://lv2plug.in/ns/ext/buf-size#nominalBlockLength"), sizeof(int32_t),
|
||||||
|
c->atom_Int, &i->block_length },
|
||||||
|
i->options[4] = (LV2_Options_Option) { LV2_OPTIONS_INSTANCE, 0,
|
||||||
|
context_map(c, LV2_PARAMETERS__sampleRate), sizeof(float),
|
||||||
|
c->atom_Float, &fsample_rate };
|
||||||
|
i->options[5] = (LV2_Options_Option) { LV2_OPTIONS_INSTANCE, 0, 0, 0, 0, NULL };
|
||||||
|
|
||||||
|
i->options_feature.URI = LV2_OPTIONS__options;
|
||||||
|
i->options_feature.data = i->options;
|
||||||
|
i->features[n_features++] = &i->options_feature;
|
||||||
|
|
||||||
|
i->instance = lilv_plugin_instantiate(p->p, *SampleRate, i->features);
|
||||||
|
if (i->instance == NULL) {
|
||||||
|
free(i);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
if (lilv_plugin_has_extension_data(p->p, c->worker_iface)) {
|
||||||
|
i->work_iface = (const LV2_Worker_Interface*)
|
||||||
|
lilv_instance_get_extension_data(i->instance, LV2_WORKER__interface);
|
||||||
|
}
|
||||||
|
|
||||||
|
return i;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lv2_cleanup(void *instance)
|
static void lv2_cleanup(void *instance)
|
||||||
{
|
{
|
||||||
lilv_instance_free(instance);
|
struct instance *i = instance;
|
||||||
|
lilv_instance_free(i->instance);
|
||||||
|
free(i);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lv2_connect_port(void *instance, unsigned long port, float *data)
|
static void lv2_connect_port(void *instance, unsigned long port, float *data)
|
||||||
{
|
{
|
||||||
lilv_instance_connect_port(instance, port, data);
|
struct instance *i = instance;
|
||||||
|
lilv_instance_connect_port(i->instance, port, data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lv2_activate(void *instance)
|
static void lv2_activate(void *instance)
|
||||||
{
|
{
|
||||||
lilv_instance_activate(instance);
|
struct instance *i = instance;
|
||||||
|
lilv_instance_activate(i->instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lv2_deactivate(void *instance)
|
static void lv2_deactivate(void *instance)
|
||||||
{
|
{
|
||||||
lilv_instance_deactivate(instance);
|
struct instance *i = instance;
|
||||||
|
lilv_instance_deactivate(i->instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lv2_run(void *instance, unsigned long SampleCount)
|
static void lv2_run(void *instance, unsigned long SampleCount)
|
||||||
{
|
{
|
||||||
lilv_instance_run(instance, SampleCount);
|
struct instance *i = instance;
|
||||||
|
lilv_instance_run(i->instance, SampleCount);
|
||||||
|
if (i->work_iface != NULL && i->work_iface->end_run != NULL)
|
||||||
|
i->work_iface->end_run(i->instance);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void lv2_free(struct fc_descriptor *desc)
|
static void lv2_free(struct fc_descriptor *desc)
|
||||||
|
|
@ -319,7 +455,8 @@ static void lv2_unload(struct fc_plugin *plugin)
|
||||||
free(p);
|
free(p);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fc_plugin *load_lv2_plugin(const char *plugin_uri, const char *config)
|
struct fc_plugin *load_lv2_plugin(const struct spa_support *support, uint32_t n_support,
|
||||||
|
const char *plugin_uri, const char *config)
|
||||||
{
|
{
|
||||||
struct context *c;
|
struct context *c;
|
||||||
const LilvPlugins *plugins;
|
const LilvPlugins *plugins;
|
||||||
|
|
@ -328,7 +465,7 @@ struct fc_plugin *load_lv2_plugin(const char *plugin_uri, const char *config)
|
||||||
int res;
|
int res;
|
||||||
struct plugin *p;
|
struct plugin *p;
|
||||||
|
|
||||||
c = context_ref();
|
c = context_ref(support, n_support);
|
||||||
if (c == NULL)
|
if (c == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -28,6 +28,7 @@
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <limits.h>
|
#include <limits.h>
|
||||||
|
|
||||||
|
#include <spa/support/plugin.h>
|
||||||
#include <spa/utils/defs.h>
|
#include <spa/utils/defs.h>
|
||||||
#include <spa/utils/list.h>
|
#include <spa/utils/list.h>
|
||||||
#include <spa/utils/string.h>
|
#include <spa/utils/string.h>
|
||||||
|
|
@ -93,8 +94,9 @@ static inline void fc_descriptor_free(struct fc_descriptor *desc)
|
||||||
desc->free(desc);
|
desc->free(desc);
|
||||||
}
|
}
|
||||||
|
|
||||||
struct fc_plugin *load_ladspa_plugin(const char *path, const char *config);
|
struct fc_plugin *load_ladspa_plugin(const struct spa_support *support, uint32_t n_support,
|
||||||
struct fc_plugin *load_lv2_plugin(const char *path, const char *config);
|
const char *path, const char *config);
|
||||||
struct fc_plugin *load_builtin_plugin(const char *path, const char *config);
|
struct fc_plugin *load_lv2_plugin(const struct spa_support *support, uint32_t n_support,
|
||||||
|
const char *path, const char *config);
|
||||||
void init_builtin_plugin(uint32_t cpu_flags);
|
struct fc_plugin *load_builtin_plugin(const struct spa_support *support, uint32_t n_support,
|
||||||
|
const char *path, const char *config);
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue