mirror of
https://gitlab.freedesktop.org/pipewire/pipewire
synced 2024-09-19 16:01:45 +00:00
filter-chain: parse config options
Remove LADSPA dependencies, only use it in ladspa_plugin.c Parse convolver config, like filename
This commit is contained in:
parent
a2aaa71392
commit
44c6ec146e
|
@ -67,6 +67,8 @@ static inline void spa_json_enter(struct spa_json * iter, struct spa_json * sub)
|
|||
*sub = SPA_JSON_ENTER(iter);
|
||||
}
|
||||
|
||||
#define SPA_JSON_SAVE(iter) (struct spa_json) { (iter)->cur, (iter)->end, }
|
||||
|
||||
/** Get the next token. \a value points to the token and the return value
|
||||
* is the length. */
|
||||
static inline int spa_json_next(struct spa_json * iter, const char **value)
|
||||
|
|
|
@ -36,6 +36,10 @@ context.modules = [
|
|||
type = builtin
|
||||
name = convolver
|
||||
label = convolver
|
||||
config = {
|
||||
filename = "src/modules/module-filter-chain/street2-L.wav"
|
||||
blocksize = 512
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
|
@ -69,6 +69,9 @@ static const struct spa_dict_item module_props[] = {
|
|||
" name = <name> "
|
||||
" plugin = <plugin> "
|
||||
" label = <label> "
|
||||
" config = { "
|
||||
" <configkey> = <value> ... "
|
||||
" } "
|
||||
" control = { "
|
||||
" <controlname> = <value> ... "
|
||||
" } "
|
||||
|
@ -100,8 +103,6 @@ static const struct spa_dict_item module_props[] = {
|
|||
|
||||
#include <pipewire/pipewire.h>
|
||||
|
||||
#include "ladspa.h"
|
||||
|
||||
#define MAX_HNDL 64
|
||||
#define MAX_PORTS 64
|
||||
#define MAX_CONTROLS 256
|
||||
|
@ -158,6 +159,7 @@ struct node {
|
|||
struct descriptor *desc;
|
||||
|
||||
char name[256];
|
||||
char *config;
|
||||
|
||||
struct port input_port[MAX_PORTS];
|
||||
struct port output_port[MAX_PORTS];
|
||||
|
@ -352,16 +354,16 @@ static struct port *find_port(struct node *node, const char *name, int descripto
|
|||
if (node == NULL)
|
||||
return NULL;
|
||||
|
||||
if (LADSPA_IS_PORT_INPUT(descriptor)) {
|
||||
if (LADSPA_IS_PORT_CONTROL(descriptor)) {
|
||||
if (FC_IS_PORT_INPUT(descriptor)) {
|
||||
if (FC_IS_PORT_CONTROL(descriptor)) {
|
||||
ports = node->control_port;
|
||||
n_ports = node->desc->n_control;
|
||||
} else {
|
||||
ports = node->input_port;
|
||||
n_ports = node->desc->n_input;
|
||||
}
|
||||
} else if (LADSPA_IS_PORT_OUTPUT(descriptor)) {
|
||||
if (LADSPA_IS_PORT_CONTROL(descriptor)) {
|
||||
} else if (FC_IS_PORT_OUTPUT(descriptor)) {
|
||||
if (FC_IS_PORT_CONTROL(descriptor)) {
|
||||
ports = node->notify_port;
|
||||
n_ports = node->desc->n_notify;
|
||||
} else {
|
||||
|
@ -382,14 +384,26 @@ static struct port *find_port(struct node *node, const char *name, int descripto
|
|||
|
||||
static struct spa_pod *get_prop_info(struct graph *graph, struct spa_pod_builder *b, uint32_t idx)
|
||||
{
|
||||
struct impl *impl = graph->impl;
|
||||
struct spa_pod_frame f[2];
|
||||
struct port *port = graph->control_port[idx];
|
||||
struct node *node = port->node;
|
||||
struct descriptor *desc = node->desc;
|
||||
const struct fc_descriptor *d = desc->desc;
|
||||
struct fc_port *p = &d->ports[port->p];
|
||||
float def, min, max;
|
||||
char name[512];
|
||||
|
||||
if (p->hint & FC_HINT_SAMPLE_RATE) {
|
||||
def = p->def * impl->rate;
|
||||
min = p->min * impl->rate;
|
||||
max = p->max * impl->rate;
|
||||
} else {
|
||||
def = p->def;
|
||||
min = p->min;
|
||||
max = p->max;
|
||||
}
|
||||
|
||||
if (node->name[0] != '\0')
|
||||
snprintf(name, sizeof(name), "%s:%s", node->name, p->name);
|
||||
else
|
||||
|
@ -402,13 +416,13 @@ static struct spa_pod *get_prop_info(struct graph *graph, struct spa_pod_builder
|
|||
SPA_PROP_INFO_name, SPA_POD_String(name),
|
||||
0);
|
||||
spa_pod_builder_prop(b, SPA_PROP_INFO_type, 0);
|
||||
if (p->min == p->max) {
|
||||
spa_pod_builder_float(b, p->def);
|
||||
if (min == max) {
|
||||
spa_pod_builder_float(b, def);
|
||||
} else {
|
||||
spa_pod_builder_push_choice(b, &f[1], SPA_CHOICE_Range, 0);
|
||||
spa_pod_builder_float(b, p->def);
|
||||
spa_pod_builder_float(b, p->min);
|
||||
spa_pod_builder_float(b, p->max);
|
||||
spa_pod_builder_float(b, def);
|
||||
spa_pod_builder_float(b, min);
|
||||
spa_pod_builder_float(b, max);
|
||||
spa_pod_builder_pop(b, &f[1]);
|
||||
}
|
||||
spa_pod_builder_prop(b, SPA_PROP_INFO_params, 0);
|
||||
|
@ -452,7 +466,7 @@ static int set_control_value(struct node *node, const char *name, float *value)
|
|||
struct port *port;
|
||||
float old;
|
||||
|
||||
port = find_port(node, name, LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL);
|
||||
port = find_port(node, name, FC_PORT_INPUT | FC_PORT_CONTROL);
|
||||
if (port == NULL)
|
||||
return 0;
|
||||
|
||||
|
@ -816,24 +830,24 @@ static struct descriptor *descriptor_load(struct impl *impl, const char *type,
|
|||
for (p = 0; p < d->n_ports; p++) {
|
||||
struct fc_port *fp = &d->ports[p];
|
||||
|
||||
if (LADSPA_IS_PORT_AUDIO(fp->flags)) {
|
||||
if (LADSPA_IS_PORT_INPUT(fp->flags)) {
|
||||
if (FC_IS_PORT_AUDIO(fp->flags)) {
|
||||
if (FC_IS_PORT_INPUT(fp->flags)) {
|
||||
pw_log_info("using port %lu ('%s') as input %d", p,
|
||||
fp->name, desc->n_input);
|
||||
desc->input[desc->n_input++] = p;
|
||||
}
|
||||
else if (LADSPA_IS_PORT_OUTPUT(fp->flags)) {
|
||||
else if (FC_IS_PORT_OUTPUT(fp->flags)) {
|
||||
pw_log_info("using port %lu ('%s') as output %d", p,
|
||||
fp->name, desc->n_output);
|
||||
desc->output[desc->n_output++] = p;
|
||||
}
|
||||
} else if (LADSPA_IS_PORT_CONTROL(fp->flags)) {
|
||||
if (LADSPA_IS_PORT_INPUT(fp->flags)) {
|
||||
} else if (FC_IS_PORT_CONTROL(fp->flags)) {
|
||||
if (FC_IS_PORT_INPUT(fp->flags)) {
|
||||
pw_log_info("using port %lu ('%s') as control %d", p,
|
||||
fp->name, desc->n_control);
|
||||
desc->control[desc->n_control++] = p;
|
||||
}
|
||||
else if (LADSPA_IS_PORT_OUTPUT(fp->flags)) {
|
||||
else if (FC_IS_PORT_OUTPUT(fp->flags)) {
|
||||
pw_log_info("using port %lu ('%s') as notify %d", p,
|
||||
fp->name, desc->n_notify);
|
||||
desc->notify[desc->n_notify++] = p;
|
||||
|
@ -863,6 +877,31 @@ exit:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/**
|
||||
* {
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
static int parse_config(struct node *node, struct spa_json *config)
|
||||
{
|
||||
const char *val;
|
||||
int len;
|
||||
|
||||
if ((len = spa_json_next(config, &val)) <= 0)
|
||||
return len;
|
||||
|
||||
if (spa_json_is_null(val, len))
|
||||
return 0;
|
||||
|
||||
if (spa_json_is_container(val, len))
|
||||
len = spa_json_container_len(config, val, len);
|
||||
|
||||
if ((node->config = malloc(len+1)) != NULL)
|
||||
spa_json_parse_string(val, len, node->config);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* {
|
||||
* "Reverb tail" = 2.0
|
||||
|
@ -914,12 +953,12 @@ static int parse_link(struct graph *graph, struct spa_json *json)
|
|||
break;
|
||||
}
|
||||
def_node = spa_list_first(&graph->node_list, struct node, link);
|
||||
if ((out_port = find_port(def_node, output, LADSPA_PORT_OUTPUT)) == NULL) {
|
||||
if ((out_port = find_port(def_node, output, FC_PORT_OUTPUT)) == NULL) {
|
||||
pw_log_error("unknown output port %s", output);
|
||||
return -ENOENT;
|
||||
}
|
||||
def_node = spa_list_last(&graph->node_list, struct node, link);
|
||||
if ((in_port = find_port(def_node, input, LADSPA_PORT_INPUT)) == NULL) {
|
||||
if ((in_port = find_port(def_node, input, FC_PORT_INPUT)) == NULL) {
|
||||
pw_log_error("unknown input port %s", input);
|
||||
return -ENOENT;
|
||||
}
|
||||
|
@ -968,13 +1007,16 @@ static void link_free(struct link *link)
|
|||
* name = rev
|
||||
* plugin = g2reverb
|
||||
* label = G2reverb
|
||||
* control = [
|
||||
* config = {
|
||||
* ...
|
||||
* ]
|
||||
* }
|
||||
* control = {
|
||||
* ...
|
||||
* }
|
||||
*/
|
||||
static int load_node(struct graph *graph, struct spa_json *json)
|
||||
{
|
||||
struct spa_json control;
|
||||
struct spa_json control, config;
|
||||
struct descriptor *desc;
|
||||
struct node *node;
|
||||
const char *val;
|
||||
|
@ -984,6 +1026,7 @@ static int load_node(struct graph *graph, struct spa_json *json)
|
|||
char plugin[256] = "";
|
||||
char label[256] = "";
|
||||
bool have_control = false;
|
||||
bool have_config = false;
|
||||
uint32_t i;
|
||||
|
||||
while (spa_json_get_string(json, key, sizeof(key)) > 0) {
|
||||
|
@ -1013,6 +1056,9 @@ static int load_node(struct graph *graph, struct spa_json *json)
|
|||
return -EINVAL;
|
||||
}
|
||||
have_control = true;
|
||||
} else if (spa_streq("config", key)) {
|
||||
config = SPA_JSON_SAVE(json);
|
||||
have_config = true;
|
||||
} else if (spa_json_next(json, &val) < 0)
|
||||
break;
|
||||
}
|
||||
|
@ -1068,6 +1114,8 @@ static int load_node(struct graph *graph, struct spa_json *json)
|
|||
port->p = desc->notify[i];
|
||||
spa_list_init(&port->link_list);
|
||||
}
|
||||
if (have_config)
|
||||
parse_config(node, &config);
|
||||
if (have_control)
|
||||
parse_control(node, &control);
|
||||
|
||||
|
@ -1219,7 +1267,7 @@ static int setup_graph(struct graph *graph, struct spa_json *inputs, struct spa_
|
|||
desc = node->desc;
|
||||
d = desc->desc;
|
||||
for (i = 0; i < n_hndl; i++) {
|
||||
if ((node->hndl[i] = d->instantiate(d, impl->rate, NULL)) == NULL) {
|
||||
if ((node->hndl[i] = d->instantiate(d, impl->rate, i, node->config)) == NULL) {
|
||||
pw_log_error("cannot create plugin instance");
|
||||
res = -ENOMEM;
|
||||
goto error;
|
||||
|
@ -1244,7 +1292,6 @@ static int setup_graph(struct graph *graph, struct spa_json *inputs, struct spa_
|
|||
}
|
||||
if (d->activate)
|
||||
d->activate(node->hndl[i]);
|
||||
|
||||
}
|
||||
/* collect all control ports on the graph */
|
||||
for (j = 0; j < desc->n_control; j++) {
|
||||
|
@ -1272,7 +1319,7 @@ static int setup_graph(struct graph *graph, struct spa_json *inputs, struct spa_
|
|||
if (spa_streq(v, "null")) {
|
||||
gp->desc = NULL;
|
||||
pw_log_info("ignore input port %d", graph->n_input);
|
||||
} else if ((port = find_port(first, v, LADSPA_PORT_INPUT)) == NULL) {
|
||||
} else if ((port = find_port(first, v, FC_PORT_INPUT)) == NULL) {
|
||||
res = -ENOENT;
|
||||
pw_log_error("input port %s not found", v);
|
||||
goto error;
|
||||
|
@ -1320,7 +1367,7 @@ static int setup_graph(struct graph *graph, struct spa_json *inputs, struct spa_
|
|||
if (spa_streq(v, "null")) {
|
||||
gp->desc = NULL;
|
||||
pw_log_info("silence output port %d", graph->n_output);
|
||||
} else if ((port = find_port(last, v, LADSPA_PORT_OUTPUT)) == NULL) {
|
||||
} else if ((port = find_port(last, v, FC_PORT_OUTPUT)) == NULL) {
|
||||
res = -ENOENT;
|
||||
pw_log_error("output port %s not found", v);
|
||||
goto error;
|
||||
|
|
|
@ -24,8 +24,9 @@
|
|||
|
||||
#include <sndfile.h>
|
||||
|
||||
#include <spa/utils/json.h>
|
||||
|
||||
#include "plugin.h"
|
||||
#include "ladspa.h"
|
||||
|
||||
#include "biquad.h"
|
||||
#include "convolver.h"
|
||||
|
@ -41,7 +42,7 @@ struct builtin {
|
|||
};
|
||||
|
||||
static void *builtin_instantiate(const struct fc_descriptor * Descriptor,
|
||||
unsigned long SampleRate, const char *config)
|
||||
unsigned long SampleRate, int index, const char *config)
|
||||
{
|
||||
struct builtin *impl;
|
||||
|
||||
|
@ -78,11 +79,11 @@ static void copy_run(void * Instance, unsigned long SampleCount)
|
|||
static struct fc_port copy_ports[] = {
|
||||
{ .index = 0,
|
||||
.name = "Out",
|
||||
.flags = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
||||
.flags = FC_PORT_OUTPUT | FC_PORT_AUDIO,
|
||||
},
|
||||
{ .index = 1,
|
||||
.name = "In",
|
||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
||||
.flags = FC_PORT_INPUT | FC_PORT_AUDIO,
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -121,24 +122,24 @@ static void mixer_run(void * Instance, unsigned long SampleCount)
|
|||
static struct fc_port mixer_ports[] = {
|
||||
{ .index = 0,
|
||||
.name = "Out",
|
||||
.flags = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
||||
.flags = FC_PORT_OUTPUT | FC_PORT_AUDIO,
|
||||
},
|
||||
{ .index = 1,
|
||||
.name = "In 1",
|
||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
||||
.flags = FC_PORT_INPUT | FC_PORT_AUDIO,
|
||||
},
|
||||
{ .index = 2,
|
||||
.name = "In 2",
|
||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
||||
.flags = FC_PORT_INPUT | FC_PORT_AUDIO,
|
||||
},
|
||||
{ .index = 3,
|
||||
.name = "Gain 1",
|
||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
||||
.flags = FC_PORT_INPUT | FC_PORT_CONTROL,
|
||||
.def = 1.0f, .min = 0.0f, .max = 10.0f
|
||||
},
|
||||
{ .index = 4,
|
||||
.name = "Gain 2",
|
||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
||||
.flags = FC_PORT_INPUT | FC_PORT_CONTROL,
|
||||
.def = 1.0f, .min = 0.0f, .max = 10.0f
|
||||
},
|
||||
};
|
||||
|
@ -158,26 +159,26 @@ static const struct fc_descriptor mixer_desc = {
|
|||
static struct fc_port bq_ports[] = {
|
||||
{ .index = 0,
|
||||
.name = "Out",
|
||||
.flags = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
||||
.flags = FC_PORT_OUTPUT | FC_PORT_AUDIO,
|
||||
},
|
||||
{ .index = 1,
|
||||
.name = "In",
|
||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
||||
.flags = FC_PORT_INPUT | FC_PORT_AUDIO,
|
||||
},
|
||||
{ .index = 2,
|
||||
.name = "Freq",
|
||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
||||
.hint = LADSPA_HINT_SAMPLE_RATE,
|
||||
.flags = FC_PORT_INPUT | FC_PORT_CONTROL,
|
||||
.hint = FC_HINT_SAMPLE_RATE,
|
||||
.def = 0.0f, .min = 0.0f, .max = 1.0f,
|
||||
},
|
||||
{ .index = 3,
|
||||
.name = "Q",
|
||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
||||
.flags = FC_PORT_INPUT | FC_PORT_CONTROL,
|
||||
.def = 0.0f, .min = 0.0f, .max = 10.0f,
|
||||
},
|
||||
{ .index = 4,
|
||||
.name = "Gain",
|
||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
||||
.flags = FC_PORT_INPUT | FC_PORT_CONTROL,
|
||||
.def = 0.0f, .min = -120.0f, .max = 5.0f,
|
||||
},
|
||||
};
|
||||
|
@ -380,22 +381,47 @@ static const struct fc_descriptor bq_allpass_desc = {
|
|||
/** convolve */
|
||||
struct convolver_impl {
|
||||
unsigned long rate;
|
||||
LADSPA_Data *port[64];
|
||||
float *port[64];
|
||||
|
||||
struct convolver *conv;
|
||||
};
|
||||
|
||||
static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
|
||||
unsigned long SampleRate, const char *config)
|
||||
unsigned long SampleRate, int index, const char *config)
|
||||
{
|
||||
struct convolver_impl *impl;
|
||||
SF_INFO info;
|
||||
SNDFILE *f;
|
||||
float *samples;
|
||||
const char *filename;
|
||||
int i, offset;
|
||||
struct spa_json it[2];
|
||||
const char *val;
|
||||
char key[256];
|
||||
char filename[PATH_MAX] = "";
|
||||
int blocksize = 256;
|
||||
|
||||
if (config == NULL)
|
||||
return NULL;
|
||||
|
||||
spa_json_init(&it[0], config, strlen(config));
|
||||
if (spa_json_enter_object(&it[0], &it[1]) <= 0)
|
||||
return NULL;
|
||||
|
||||
while (spa_json_get_string(&it[1], key, sizeof(key)) > 0) {
|
||||
if (spa_streq(key, "filename")) {
|
||||
if (spa_json_get_string(&it[1], filename, sizeof(filename)) <= 0)
|
||||
return NULL;
|
||||
}
|
||||
else if (spa_streq(key, "blocksize")) {
|
||||
if (spa_json_get_int(&it[1], &blocksize) <= 0)
|
||||
return NULL;
|
||||
}
|
||||
else if (spa_json_next(&it[1], &val) < 0)
|
||||
break;
|
||||
}
|
||||
if (!filename[0])
|
||||
return NULL;
|
||||
|
||||
filename = "src/modules/module-filter-chain/convolve.wav";
|
||||
filename = "src/modules/module-filter-chain/street2-L.wav";
|
||||
spa_zero(info);
|
||||
f = sf_open(filename, SFM_READ, &info) ;
|
||||
if (f == NULL) {
|
||||
|
@ -415,7 +441,12 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
|
|||
|
||||
sf_read_float(f, samples, info.frames);
|
||||
|
||||
impl->conv = convolver_new(256, samples, info.frames);
|
||||
offset = index % info.channels;
|
||||
|
||||
for (i = 0; i < info.frames; i++)
|
||||
samples[i] = samples[info.channels * i + offset];
|
||||
|
||||
impl->conv = convolver_new(blocksize, samples, info.frames);
|
||||
|
||||
free(samples);
|
||||
sf_close(f);
|
||||
|
@ -424,7 +455,7 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
|
|||
}
|
||||
|
||||
static void convolver_connect_port(void * Instance, unsigned long Port,
|
||||
LADSPA_Data * DataLocation)
|
||||
float * DataLocation)
|
||||
{
|
||||
struct convolver_impl *impl = Instance;
|
||||
impl->port[Port] = DataLocation;
|
||||
|
@ -439,11 +470,11 @@ static void convolver_cleanup(void * Instance)
|
|||
static struct fc_port convolve_ports[] = {
|
||||
{ .index = 0,
|
||||
.name = "Out",
|
||||
.flags = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
||||
.flags = FC_PORT_OUTPUT | FC_PORT_AUDIO,
|
||||
},
|
||||
{ .index = 1,
|
||||
.name = "In",
|
||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
||||
.flags = FC_PORT_INPUT | FC_PORT_AUDIO,
|
||||
},
|
||||
};
|
||||
|
||||
|
|
|
@ -81,10 +81,6 @@ struct convolver *convolver_new(int block, const float *ir, int irlen)
|
|||
conv->segCount = (irlen + conv->blockSize-1) / conv->blockSize;
|
||||
conv->fftComplexSize = (conv->segSize / 2) + 1;
|
||||
|
||||
fprintf(stderr, "blockSize:%d segSize:%d segCount:%d fftComplexSize:%d\n",
|
||||
conv->blockSize, conv->segSize, conv->segCount,
|
||||
conv->fftComplexSize);
|
||||
|
||||
conv->fft = kiss_fftr_f32_alloc(conv->segSize, 0, NULL, NULL);
|
||||
if (conv->fft == NULL)
|
||||
return NULL;
|
||||
|
@ -156,9 +152,6 @@ int convolver_run(struct convolver *conv, const float *input, float *output, int
|
|||
const int processing = SPA_MIN(len - processed, conv->blockSize - conv->inputBufferFill);
|
||||
const int inputBufferPos = conv->inputBufferFill;
|
||||
|
||||
fprintf(stderr, "len:%d processing:%d fill:%d processed:%d\n",
|
||||
len, processing, inputBufferPos, processed);
|
||||
|
||||
memcpy(conv->inputBuffer + inputBufferPos, input + processed, processing * sizeof(float));
|
||||
|
||||
memcpy(conv->fft_buffer, conv->inputBuffer, conv->blockSize * sizeof(float));
|
||||
|
|
|
@ -48,7 +48,7 @@ struct descriptor {
|
|||
};
|
||||
|
||||
static void *ladspa_instantiate(const struct fc_descriptor *desc,
|
||||
unsigned long SampleRate, const char *config)
|
||||
unsigned long SampleRate, int index, const char *config)
|
||||
{
|
||||
struct descriptor *d = (struct descriptor *)desc;
|
||||
return d->d->instantiate(d->d, SampleRate);
|
||||
|
|
|
@ -40,14 +40,24 @@ struct fc_plugin {
|
|||
struct fc_port {
|
||||
uint32_t index;
|
||||
const char *name;
|
||||
#define FC_PORT_INPUT (1ULL << 0)
|
||||
#define FC_PORT_OUTPUT (1ULL << 1)
|
||||
#define FC_PORT_CONTROL (1ULL << 2)
|
||||
#define FC_PORT_AUDIO (1ULL << 3)
|
||||
uint64_t flags;
|
||||
|
||||
#define FC_HINT_SAMPLE_RATE (1ULL << 3)
|
||||
uint64_t hint;
|
||||
float def;
|
||||
float min;
|
||||
float max;
|
||||
};
|
||||
|
||||
#define FC_IS_PORT_INPUT(x) ((x) & FC_PORT_INPUT)
|
||||
#define FC_IS_PORT_OUTPUT(x) ((x) & FC_PORT_OUTPUT)
|
||||
#define FC_IS_PORT_CONTROL(x) ((x) & FC_PORT_CONTROL)
|
||||
#define FC_IS_PORT_AUDIO(x) ((x) & FC_PORT_AUDIO)
|
||||
|
||||
struct fc_descriptor {
|
||||
const char *name;
|
||||
uint64_t flags;
|
||||
|
@ -58,7 +68,7 @@ struct fc_descriptor {
|
|||
struct fc_port *ports;
|
||||
|
||||
void *(*instantiate) (const struct fc_descriptor *desc,
|
||||
unsigned long SampleRate, const char *config);
|
||||
unsigned long SampleRate, int index, const char *config);
|
||||
|
||||
void (*cleanup) (void *instance);
|
||||
|
||||
|
|
Loading…
Reference in a new issue