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);
 | 
						*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