mirror of
				https://gitlab.freedesktop.org/pipewire/pipewire.git
				synced 2025-11-03 09:01:54 -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);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
#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…
	
	Add table
		Add a link
		
	
		Reference in a new issue