mirror of
https://gitlab.freedesktop.org/pipewire/pipewire.git
synced 2025-11-04 13:30:12 -05: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
7 changed files with 147 additions and 60 deletions
|
|
@ -67,6 +67,8 @@ static inline void spa_json_enter(struct spa_json * iter, struct spa_json * sub)
|
||||||
*sub = SPA_JSON_ENTER(iter);
|
*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
|
/** Get the next token. \a value points to the token and the return value
|
||||||
* is the length. */
|
* is the length. */
|
||||||
static inline int spa_json_next(struct spa_json * iter, const char **value)
|
static inline int spa_json_next(struct spa_json * iter, const char **value)
|
||||||
|
|
|
||||||
|
|
@ -36,6 +36,10 @@ context.modules = [
|
||||||
type = builtin
|
type = builtin
|
||||||
name = convolver
|
name = convolver
|
||||||
label = 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> "
|
" name = <name> "
|
||||||
" plugin = <plugin> "
|
" plugin = <plugin> "
|
||||||
" label = <label> "
|
" label = <label> "
|
||||||
|
" config = { "
|
||||||
|
" <configkey> = <value> ... "
|
||||||
|
" } "
|
||||||
" control = { "
|
" control = { "
|
||||||
" <controlname> = <value> ... "
|
" <controlname> = <value> ... "
|
||||||
" } "
|
" } "
|
||||||
|
|
@ -100,8 +103,6 @@ static const struct spa_dict_item module_props[] = {
|
||||||
|
|
||||||
#include <pipewire/pipewire.h>
|
#include <pipewire/pipewire.h>
|
||||||
|
|
||||||
#include "ladspa.h"
|
|
||||||
|
|
||||||
#define MAX_HNDL 64
|
#define MAX_HNDL 64
|
||||||
#define MAX_PORTS 64
|
#define MAX_PORTS 64
|
||||||
#define MAX_CONTROLS 256
|
#define MAX_CONTROLS 256
|
||||||
|
|
@ -158,6 +159,7 @@ struct node {
|
||||||
struct descriptor *desc;
|
struct descriptor *desc;
|
||||||
|
|
||||||
char name[256];
|
char name[256];
|
||||||
|
char *config;
|
||||||
|
|
||||||
struct port input_port[MAX_PORTS];
|
struct port input_port[MAX_PORTS];
|
||||||
struct port output_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)
|
if (node == NULL)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
if (LADSPA_IS_PORT_INPUT(descriptor)) {
|
if (FC_IS_PORT_INPUT(descriptor)) {
|
||||||
if (LADSPA_IS_PORT_CONTROL(descriptor)) {
|
if (FC_IS_PORT_CONTROL(descriptor)) {
|
||||||
ports = node->control_port;
|
ports = node->control_port;
|
||||||
n_ports = node->desc->n_control;
|
n_ports = node->desc->n_control;
|
||||||
} else {
|
} else {
|
||||||
ports = node->input_port;
|
ports = node->input_port;
|
||||||
n_ports = node->desc->n_input;
|
n_ports = node->desc->n_input;
|
||||||
}
|
}
|
||||||
} else if (LADSPA_IS_PORT_OUTPUT(descriptor)) {
|
} else if (FC_IS_PORT_OUTPUT(descriptor)) {
|
||||||
if (LADSPA_IS_PORT_CONTROL(descriptor)) {
|
if (FC_IS_PORT_CONTROL(descriptor)) {
|
||||||
ports = node->notify_port;
|
ports = node->notify_port;
|
||||||
n_ports = node->desc->n_notify;
|
n_ports = node->desc->n_notify;
|
||||||
} else {
|
} 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)
|
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 spa_pod_frame f[2];
|
||||||
struct port *port = graph->control_port[idx];
|
struct port *port = graph->control_port[idx];
|
||||||
struct node *node = port->node;
|
struct node *node = port->node;
|
||||||
struct descriptor *desc = node->desc;
|
struct descriptor *desc = node->desc;
|
||||||
const struct fc_descriptor *d = desc->desc;
|
const struct fc_descriptor *d = desc->desc;
|
||||||
struct fc_port *p = &d->ports[port->p];
|
struct fc_port *p = &d->ports[port->p];
|
||||||
|
float def, min, max;
|
||||||
char name[512];
|
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')
|
if (node->name[0] != '\0')
|
||||||
snprintf(name, sizeof(name), "%s:%s", node->name, p->name);
|
snprintf(name, sizeof(name), "%s:%s", node->name, p->name);
|
||||||
else
|
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),
|
SPA_PROP_INFO_name, SPA_POD_String(name),
|
||||||
0);
|
0);
|
||||||
spa_pod_builder_prop(b, SPA_PROP_INFO_type, 0);
|
spa_pod_builder_prop(b, SPA_PROP_INFO_type, 0);
|
||||||
if (p->min == p->max) {
|
if (min == max) {
|
||||||
spa_pod_builder_float(b, p->def);
|
spa_pod_builder_float(b, def);
|
||||||
} else {
|
} else {
|
||||||
spa_pod_builder_push_choice(b, &f[1], SPA_CHOICE_Range, 0);
|
spa_pod_builder_push_choice(b, &f[1], SPA_CHOICE_Range, 0);
|
||||||
spa_pod_builder_float(b, p->def);
|
spa_pod_builder_float(b, def);
|
||||||
spa_pod_builder_float(b, p->min);
|
spa_pod_builder_float(b, min);
|
||||||
spa_pod_builder_float(b, p->max);
|
spa_pod_builder_float(b, max);
|
||||||
spa_pod_builder_pop(b, &f[1]);
|
spa_pod_builder_pop(b, &f[1]);
|
||||||
}
|
}
|
||||||
spa_pod_builder_prop(b, SPA_PROP_INFO_params, 0);
|
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;
|
struct port *port;
|
||||||
float old;
|
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)
|
if (port == NULL)
|
||||||
return 0;
|
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++) {
|
for (p = 0; p < d->n_ports; p++) {
|
||||||
struct fc_port *fp = &d->ports[p];
|
struct fc_port *fp = &d->ports[p];
|
||||||
|
|
||||||
if (LADSPA_IS_PORT_AUDIO(fp->flags)) {
|
if (FC_IS_PORT_AUDIO(fp->flags)) {
|
||||||
if (LADSPA_IS_PORT_INPUT(fp->flags)) {
|
if (FC_IS_PORT_INPUT(fp->flags)) {
|
||||||
pw_log_info("using port %lu ('%s') as input %d", p,
|
pw_log_info("using port %lu ('%s') as input %d", p,
|
||||||
fp->name, desc->n_input);
|
fp->name, desc->n_input);
|
||||||
desc->input[desc->n_input++] = p;
|
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,
|
pw_log_info("using port %lu ('%s') as output %d", p,
|
||||||
fp->name, desc->n_output);
|
fp->name, desc->n_output);
|
||||||
desc->output[desc->n_output++] = p;
|
desc->output[desc->n_output++] = p;
|
||||||
}
|
}
|
||||||
} else if (LADSPA_IS_PORT_CONTROL(fp->flags)) {
|
} else if (FC_IS_PORT_CONTROL(fp->flags)) {
|
||||||
if (LADSPA_IS_PORT_INPUT(fp->flags)) {
|
if (FC_IS_PORT_INPUT(fp->flags)) {
|
||||||
pw_log_info("using port %lu ('%s') as control %d", p,
|
pw_log_info("using port %lu ('%s') as control %d", p,
|
||||||
fp->name, desc->n_control);
|
fp->name, desc->n_control);
|
||||||
desc->control[desc->n_control++] = p;
|
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,
|
pw_log_info("using port %lu ('%s') as notify %d", p,
|
||||||
fp->name, desc->n_notify);
|
fp->name, desc->n_notify);
|
||||||
desc->notify[desc->n_notify++] = p;
|
desc->notify[desc->n_notify++] = p;
|
||||||
|
|
@ -863,6 +877,31 @@ exit:
|
||||||
return NULL;
|
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
|
* "Reverb tail" = 2.0
|
||||||
|
|
@ -914,12 +953,12 @@ static int parse_link(struct graph *graph, struct spa_json *json)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
def_node = spa_list_first(&graph->node_list, struct node, link);
|
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);
|
pw_log_error("unknown output port %s", output);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
def_node = spa_list_last(&graph->node_list, struct node, link);
|
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);
|
pw_log_error("unknown input port %s", input);
|
||||||
return -ENOENT;
|
return -ENOENT;
|
||||||
}
|
}
|
||||||
|
|
@ -968,13 +1007,16 @@ static void link_free(struct link *link)
|
||||||
* name = rev
|
* name = rev
|
||||||
* plugin = g2reverb
|
* plugin = g2reverb
|
||||||
* label = G2reverb
|
* label = G2reverb
|
||||||
* control = [
|
* config = {
|
||||||
* ...
|
* ...
|
||||||
* ]
|
* }
|
||||||
|
* control = {
|
||||||
|
* ...
|
||||||
|
* }
|
||||||
*/
|
*/
|
||||||
static int load_node(struct graph *graph, struct spa_json *json)
|
static int load_node(struct graph *graph, struct spa_json *json)
|
||||||
{
|
{
|
||||||
struct spa_json control;
|
struct spa_json control, config;
|
||||||
struct descriptor *desc;
|
struct descriptor *desc;
|
||||||
struct node *node;
|
struct node *node;
|
||||||
const char *val;
|
const char *val;
|
||||||
|
|
@ -984,6 +1026,7 @@ static int load_node(struct graph *graph, struct spa_json *json)
|
||||||
char plugin[256] = "";
|
char plugin[256] = "";
|
||||||
char label[256] = "";
|
char label[256] = "";
|
||||||
bool have_control = false;
|
bool have_control = false;
|
||||||
|
bool have_config = false;
|
||||||
uint32_t i;
|
uint32_t i;
|
||||||
|
|
||||||
while (spa_json_get_string(json, key, sizeof(key)) > 0) {
|
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;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
have_control = true;
|
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)
|
} else if (spa_json_next(json, &val) < 0)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1068,6 +1114,8 @@ static int load_node(struct graph *graph, struct spa_json *json)
|
||||||
port->p = desc->notify[i];
|
port->p = desc->notify[i];
|
||||||
spa_list_init(&port->link_list);
|
spa_list_init(&port->link_list);
|
||||||
}
|
}
|
||||||
|
if (have_config)
|
||||||
|
parse_config(node, &config);
|
||||||
if (have_control)
|
if (have_control)
|
||||||
parse_control(node, &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;
|
desc = node->desc;
|
||||||
d = desc->desc;
|
d = desc->desc;
|
||||||
for (i = 0; i < n_hndl; i++) {
|
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");
|
pw_log_error("cannot create plugin instance");
|
||||||
res = -ENOMEM;
|
res = -ENOMEM;
|
||||||
goto error;
|
goto error;
|
||||||
|
|
@ -1244,7 +1292,6 @@ static int setup_graph(struct graph *graph, struct spa_json *inputs, struct spa_
|
||||||
}
|
}
|
||||||
if (d->activate)
|
if (d->activate)
|
||||||
d->activate(node->hndl[i]);
|
d->activate(node->hndl[i]);
|
||||||
|
|
||||||
}
|
}
|
||||||
/* collect all control ports on the graph */
|
/* collect all control ports on the graph */
|
||||||
for (j = 0; j < desc->n_control; j++) {
|
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")) {
|
if (spa_streq(v, "null")) {
|
||||||
gp->desc = NULL;
|
gp->desc = NULL;
|
||||||
pw_log_info("ignore input port %d", graph->n_input);
|
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;
|
res = -ENOENT;
|
||||||
pw_log_error("input port %s not found", v);
|
pw_log_error("input port %s not found", v);
|
||||||
goto error;
|
goto error;
|
||||||
|
|
@ -1320,7 +1367,7 @@ static int setup_graph(struct graph *graph, struct spa_json *inputs, struct spa_
|
||||||
if (spa_streq(v, "null")) {
|
if (spa_streq(v, "null")) {
|
||||||
gp->desc = NULL;
|
gp->desc = NULL;
|
||||||
pw_log_info("silence output port %d", graph->n_output);
|
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;
|
res = -ENOENT;
|
||||||
pw_log_error("output port %s not found", v);
|
pw_log_error("output port %s not found", v);
|
||||||
goto error;
|
goto error;
|
||||||
|
|
|
||||||
|
|
@ -24,8 +24,9 @@
|
||||||
|
|
||||||
#include <sndfile.h>
|
#include <sndfile.h>
|
||||||
|
|
||||||
|
#include <spa/utils/json.h>
|
||||||
|
|
||||||
#include "plugin.h"
|
#include "plugin.h"
|
||||||
#include "ladspa.h"
|
|
||||||
|
|
||||||
#include "biquad.h"
|
#include "biquad.h"
|
||||||
#include "convolver.h"
|
#include "convolver.h"
|
||||||
|
|
@ -41,7 +42,7 @@ struct builtin {
|
||||||
};
|
};
|
||||||
|
|
||||||
static void *builtin_instantiate(const struct fc_descriptor * Descriptor,
|
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;
|
struct builtin *impl;
|
||||||
|
|
||||||
|
|
@ -78,11 +79,11 @@ static void copy_run(void * Instance, unsigned long SampleCount)
|
||||||
static struct fc_port copy_ports[] = {
|
static struct fc_port copy_ports[] = {
|
||||||
{ .index = 0,
|
{ .index = 0,
|
||||||
.name = "Out",
|
.name = "Out",
|
||||||
.flags = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
.flags = FC_PORT_OUTPUT | FC_PORT_AUDIO,
|
||||||
},
|
},
|
||||||
{ .index = 1,
|
{ .index = 1,
|
||||||
.name = "In",
|
.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[] = {
|
static struct fc_port mixer_ports[] = {
|
||||||
{ .index = 0,
|
{ .index = 0,
|
||||||
.name = "Out",
|
.name = "Out",
|
||||||
.flags = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
.flags = FC_PORT_OUTPUT | FC_PORT_AUDIO,
|
||||||
},
|
},
|
||||||
{ .index = 1,
|
{ .index = 1,
|
||||||
.name = "In 1",
|
.name = "In 1",
|
||||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
.flags = FC_PORT_INPUT | FC_PORT_AUDIO,
|
||||||
},
|
},
|
||||||
{ .index = 2,
|
{ .index = 2,
|
||||||
.name = "In 2",
|
.name = "In 2",
|
||||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
.flags = FC_PORT_INPUT | FC_PORT_AUDIO,
|
||||||
},
|
},
|
||||||
{ .index = 3,
|
{ .index = 3,
|
||||||
.name = "Gain 1",
|
.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
|
.def = 1.0f, .min = 0.0f, .max = 10.0f
|
||||||
},
|
},
|
||||||
{ .index = 4,
|
{ .index = 4,
|
||||||
.name = "Gain 2",
|
.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
|
.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[] = {
|
static struct fc_port bq_ports[] = {
|
||||||
{ .index = 0,
|
{ .index = 0,
|
||||||
.name = "Out",
|
.name = "Out",
|
||||||
.flags = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
.flags = FC_PORT_OUTPUT | FC_PORT_AUDIO,
|
||||||
},
|
},
|
||||||
{ .index = 1,
|
{ .index = 1,
|
||||||
.name = "In",
|
.name = "In",
|
||||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_AUDIO,
|
.flags = FC_PORT_INPUT | FC_PORT_AUDIO,
|
||||||
},
|
},
|
||||||
{ .index = 2,
|
{ .index = 2,
|
||||||
.name = "Freq",
|
.name = "Freq",
|
||||||
.flags = LADSPA_PORT_INPUT | LADSPA_PORT_CONTROL,
|
.flags = FC_PORT_INPUT | FC_PORT_CONTROL,
|
||||||
.hint = LADSPA_HINT_SAMPLE_RATE,
|
.hint = FC_HINT_SAMPLE_RATE,
|
||||||
.def = 0.0f, .min = 0.0f, .max = 1.0f,
|
.def = 0.0f, .min = 0.0f, .max = 1.0f,
|
||||||
},
|
},
|
||||||
{ .index = 3,
|
{ .index = 3,
|
||||||
.name = "Q",
|
.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,
|
.def = 0.0f, .min = 0.0f, .max = 10.0f,
|
||||||
},
|
},
|
||||||
{ .index = 4,
|
{ .index = 4,
|
||||||
.name = "Gain",
|
.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,
|
.def = 0.0f, .min = -120.0f, .max = 5.0f,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
@ -380,22 +381,47 @@ static const struct fc_descriptor bq_allpass_desc = {
|
||||||
/** convolve */
|
/** convolve */
|
||||||
struct convolver_impl {
|
struct convolver_impl {
|
||||||
unsigned long rate;
|
unsigned long rate;
|
||||||
LADSPA_Data *port[64];
|
float *port[64];
|
||||||
|
|
||||||
struct convolver *conv;
|
struct convolver *conv;
|
||||||
};
|
};
|
||||||
|
|
||||||
static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
|
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;
|
struct convolver_impl *impl;
|
||||||
SF_INFO info;
|
SF_INFO info;
|
||||||
SNDFILE *f;
|
SNDFILE *f;
|
||||||
float *samples;
|
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);
|
spa_zero(info);
|
||||||
f = sf_open(filename, SFM_READ, &info) ;
|
f = sf_open(filename, SFM_READ, &info) ;
|
||||||
if (f == NULL) {
|
if (f == NULL) {
|
||||||
|
|
@ -415,7 +441,12 @@ static void * convolver_instantiate(const struct fc_descriptor * Descriptor,
|
||||||
|
|
||||||
sf_read_float(f, samples, info.frames);
|
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);
|
free(samples);
|
||||||
sf_close(f);
|
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,
|
static void convolver_connect_port(void * Instance, unsigned long Port,
|
||||||
LADSPA_Data * DataLocation)
|
float * DataLocation)
|
||||||
{
|
{
|
||||||
struct convolver_impl *impl = Instance;
|
struct convolver_impl *impl = Instance;
|
||||||
impl->port[Port] = DataLocation;
|
impl->port[Port] = DataLocation;
|
||||||
|
|
@ -439,11 +470,11 @@ static void convolver_cleanup(void * Instance)
|
||||||
static struct fc_port convolve_ports[] = {
|
static struct fc_port convolve_ports[] = {
|
||||||
{ .index = 0,
|
{ .index = 0,
|
||||||
.name = "Out",
|
.name = "Out",
|
||||||
.flags = LADSPA_PORT_OUTPUT | LADSPA_PORT_AUDIO,
|
.flags = FC_PORT_OUTPUT | FC_PORT_AUDIO,
|
||||||
},
|
},
|
||||||
{ .index = 1,
|
{ .index = 1,
|
||||||
.name = "In",
|
.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->segCount = (irlen + conv->blockSize-1) / conv->blockSize;
|
||||||
conv->fftComplexSize = (conv->segSize / 2) + 1;
|
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);
|
conv->fft = kiss_fftr_f32_alloc(conv->segSize, 0, NULL, NULL);
|
||||||
if (conv->fft == NULL)
|
if (conv->fft == NULL)
|
||||||
return 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 processing = SPA_MIN(len - processed, conv->blockSize - conv->inputBufferFill);
|
||||||
const int inputBufferPos = 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->inputBuffer + inputBufferPos, input + processed, processing * sizeof(float));
|
||||||
|
|
||||||
memcpy(conv->fft_buffer, conv->inputBuffer, conv->blockSize * 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,
|
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;
|
struct descriptor *d = (struct descriptor *)desc;
|
||||||
return d->d->instantiate(d->d, SampleRate);
|
return d->d->instantiate(d->d, SampleRate);
|
||||||
|
|
|
||||||
|
|
@ -40,14 +40,24 @@ struct fc_plugin {
|
||||||
struct fc_port {
|
struct fc_port {
|
||||||
uint32_t index;
|
uint32_t index;
|
||||||
const char *name;
|
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;
|
uint64_t flags;
|
||||||
|
|
||||||
|
#define FC_HINT_SAMPLE_RATE (1ULL << 3)
|
||||||
uint64_t hint;
|
uint64_t hint;
|
||||||
float def;
|
float def;
|
||||||
float min;
|
float min;
|
||||||
float max;
|
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 {
|
struct fc_descriptor {
|
||||||
const char *name;
|
const char *name;
|
||||||
uint64_t flags;
|
uint64_t flags;
|
||||||
|
|
@ -58,7 +68,7 @@ struct fc_descriptor {
|
||||||
struct fc_port *ports;
|
struct fc_port *ports;
|
||||||
|
|
||||||
void *(*instantiate) (const struct fc_descriptor *desc,
|
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);
|
void (*cleanup) (void *instance);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue