Home | History | Annotate | Download | only in server
      1 /* Copyright (c) 2012 The Chromium OS Authors. All rights reserved.
      2  * Use of this source code is governed by a BSD-style license that can be
      3  * found in the LICENSE file.
      4  */
      5 
      6 #include <inttypes.h>
      7 #include <sys/param.h>
      8 #include <syslog.h>
      9 
     10 #include "cras_util.h"
     11 #include "cras_dsp_module.h"
     12 #include "cras_dsp_pipeline.h"
     13 #include "dsp_util.h"
     14 
     15 /* We have a static representation of the dsp graph in a "struct ini",
     16  * and here we will construct a dynamic representation of it in a
     17  * "struct pipeline". The difference between the static one and the
     18  * dynamic one is that we will only include the subset of the dsp
     19  * graph actually needed in the dynamic one (so those plugins that are
     20  * disabled will not be included). Here are the mapping between the
     21  * static representation and the dynamic representation:
     22  *
     23  *      static                      dynamic
     24  *  -------------    --------------------------------------
     25  *  struct ini       struct pipeline
     26  *  struct plugin    struct instance
     27  *  strict port      struct audio_port, struct control_port
     28  *
     29  * For example, if the ini file specifies these plugins and their
     30  * connections:
     31  *
     32  * [A]
     33  * output_0={audio}
     34  * [B]
     35  * input_0={audio}
     36  * output_1={result}
     37  * [C]
     38  * input_0={result}
     39  *
     40  * That is, A connects to B, and B connects to C. If the plugin B is
     41  * now disabled, in the pipeline we construct there will only be two
     42  * instances (A and C) and the audio ports on these instances will
     43  * connect to each other directly, bypassing B.
     44  */
     45 
     46 /* This represents an audio port on an instance. */
     47 struct audio_port {
     48 	struct audio_port *peer;  /* the audio port this port connects to */
     49 	struct plugin *plugin;  /* the plugin corresponds to the instance */
     50 	int original_index;  /* the port index in the plugin */
     51 	int buf_index; /* the buffer index in the pipeline */
     52 };
     53 
     54 /* This represents a control port on an instance. */
     55 struct control_port {
     56 	struct control_port *peer;  /* the control port this port connects to */
     57 	struct plugin *plugin;  /* the plugin corresponds to the instance */
     58 	int original_index;  /* the port index in the plugin */
     59 	float value;  /* the value of the control port */
     60 };
     61 
     62 DECLARE_ARRAY_TYPE(struct audio_port, audio_port_array);
     63 DECLARE_ARRAY_TYPE(struct control_port, control_port_array);
     64 
     65 /* An instance is a dynamic representation of a plugin. We only create
     66  * an instance when a plugin is needed (data actually flows through it
     67  * and it is not disabled). An instance also contains a pointer to a
     68  * struct dsp_module, which is the implementation of the plugin */
     69 struct instance {
     70 	/* The plugin this instance corresponds to */
     71 	struct plugin *plugin;
     72 
     73 	/* These are the ports on this instance. The difference
     74 	 * between this and the port array in a struct plugin is that
     75 	 * the ports skip disabled plugins and connect to the upstream
     76 	 * ports directly.
     77 	 */
     78 	audio_port_array input_audio_ports;
     79 	audio_port_array output_audio_ports;
     80 	control_port_array input_control_ports;
     81 	control_port_array output_control_ports;
     82 
     83 	/* The implementation of the plugin */
     84 	struct dsp_module *module;
     85 
     86 	/* Whether this module's instantiate() function has been called */
     87 	int instantiated;
     88 
     89 	/* This caches the value returned from get_properties() of a module */
     90 	int properties;
     91 
     92 	/* This is the total buffering delay from source to this instance. It is
     93 	 * in number of frames. */
     94 	int total_delay;
     95 };
     96 
     97 DECLARE_ARRAY_TYPE(struct instance, instance_array)
     98 
     99 /* An pipeline is a dynamic representation of a dsp ini file. */
    100 struct pipeline {
    101 	/* The purpose of the pipeline. "playback" or "capture" */
    102 	const char *purpose;
    103 
    104 	/* The ini file this pipeline comes from */
    105 	struct ini *ini;
    106 
    107 	/* All needed instances for this pipeline. It is sorted in an
    108 	 * order that if instance B depends on instance A, then A will
    109 	 * appear in front of B. */
    110 	instance_array instances;
    111 
    112 	/* The maximum number of audio buffers that will be used at
    113 	 * the same time for this pipeline */
    114 	int peak_buf;
    115 
    116 	/* The audio data buffers */
    117 	float **buffers;
    118 
    119 	/* The instance where the audio data flow in */
    120 	struct instance *source_instance;
    121 
    122 	/* The instance where the audio data flow out */
    123 	struct instance *sink_instance;
    124 
    125 	/* The number of audio channels for this pipeline */
    126 	int input_channels;
    127 	int output_channels;
    128 
    129 	/* The audio sampling rate for this pipleine. It is zero if
    130 	 * cras_dsp_pipeline_instantiate() has not been called. */
    131 	int sample_rate;
    132 
    133 	/* The total time it takes to run the pipeline, in nanoseconds. */
    134 	int64_t total_time;
    135 
    136 	/* The max/min time it takes to run the pipeline, in nanoseconds. */
    137 	int64_t max_time;
    138 	int64_t min_time;
    139 
    140 	/* The number of blocks the pipeline. */
    141 	int64_t total_blocks;
    142 
    143 	/* The total number of sample frames the pipeline processed */
    144 	int64_t total_samples;
    145 };
    146 
    147 static struct instance *find_instance_by_plugin(instance_array *instances,
    148 						struct plugin *plugin)
    149 {
    150 	int i;
    151 	struct instance *instance;
    152 
    153 	FOR_ARRAY_ELEMENT(instances, i, instance) {
    154 		if (instance->plugin == plugin)
    155 			return instance;
    156 	}
    157 
    158 	return NULL;
    159 }
    160 
    161 /* Finds out where the data sent to plugin:index come from. The issue
    162  * we need to handle here is the previous plugin may be disabled, so
    163  * we need to go upstream until we find the real origin */
    164 static int find_origin_port(struct ini *ini, instance_array *instances,
    165 			    struct plugin *plugin, int index,
    166 			    struct plugin **origin, int *origin_index)
    167 {
    168 	enum port_type type;
    169 	struct port *port;
    170 	int flow_id;
    171 	struct flow *flow;
    172 	int i, k;
    173 	int found;
    174 
    175 	port = ARRAY_ELEMENT(&plugin->ports, index);
    176 	type = port->type;
    177 	flow_id = port->flow_id;
    178 	if (flow_id == INVALID_FLOW_ID)
    179 		return -1;
    180 	flow = ARRAY_ELEMENT(&ini->flows, flow_id);
    181 
    182 	/* move to the previous plugin */
    183 	plugin = flow->from;
    184 	index = flow->from_port;
    185 
    186 	/* if the plugin is not disabled, it will be pointed by some instance */
    187 	if (find_instance_by_plugin(instances, plugin)) {
    188 		*origin = plugin;
    189 		*origin_index = index;
    190 		return 0;
    191 	}
    192 
    193 	/* Now we know the previous plugin is disabled, we need to go
    194 	 * upstream. We assume the k-th output port of the plugin
    195 	 * corresponds to the k-th input port of the plugin (with the
    196 	 * same type) */
    197 
    198 	k = 0;
    199 	found = 0;
    200 	FOR_ARRAY_ELEMENT(&plugin->ports, i, port) {
    201 		if (index == i) {
    202 			found = 1;
    203 			break;
    204 		}
    205 		if (port->direction == PORT_OUTPUT && port->type == type)
    206 			k++;
    207 	}
    208 	if (!found)
    209 		return -1;
    210 
    211 	found = 0;
    212 	FOR_ARRAY_ELEMENT(&plugin->ports, i, port) {
    213 		if (port->direction == PORT_INPUT && port->type == type) {
    214 			if (k-- == 0) {
    215 				index = i;
    216 				found = 1;
    217 				break;
    218 			}
    219 		}
    220 	}
    221 	if (!found)
    222 		return -1;
    223 
    224 	return find_origin_port(ini, instances, plugin, index, origin,
    225 				origin_index);
    226 }
    227 
    228 static struct audio_port *find_output_audio_port(instance_array *instances,
    229 						 struct plugin *plugin,
    230 						 int index)
    231 {
    232 	int i;
    233 	struct instance *instance;
    234 	struct audio_port *audio_port;
    235 
    236 	instance = find_instance_by_plugin(instances, plugin);
    237 	if (!instance)
    238 		return NULL;
    239 
    240 	FOR_ARRAY_ELEMENT(&instance->output_audio_ports, i, audio_port) {
    241 		if (audio_port->original_index == index)
    242 			return audio_port;
    243 	}
    244 
    245 	return NULL;
    246 }
    247 
    248 static struct control_port *find_output_control_port(instance_array *instances,
    249 						     struct plugin *plugin,
    250 						     int index)
    251 {
    252 	int i;
    253 	struct instance *instance;
    254 	struct control_port *control_port;
    255 
    256 	instance = find_instance_by_plugin(instances, plugin);
    257 	if (!instance)
    258 		return NULL;
    259 
    260 	FOR_ARRAY_ELEMENT(&instance->output_control_ports, i, control_port) {
    261 		if (control_port->original_index == index)
    262 			return control_port;
    263 	}
    264 
    265 	return NULL;
    266 }
    267 
    268 static char is_disabled(struct plugin *plugin, struct cras_expr_env *env)
    269 {
    270 	char disabled;
    271 	return (plugin->disable_expr &&
    272 		cras_expr_expression_eval_boolean(
    273 			plugin->disable_expr, env, &disabled) == 0 &&
    274 		disabled == 1);
    275 }
    276 
    277 static int topological_sort(struct pipeline *pipeline,
    278 			    struct cras_expr_env *env,
    279 			    struct plugin *plugin, char* visited)
    280 {
    281 	struct port *port;
    282 	struct flow *flow;
    283 	int index;
    284 	int i;
    285 	int flow_id;
    286 	struct instance *instance;
    287 	struct ini *ini = pipeline->ini;
    288 
    289 	index = ARRAY_INDEX(&ini->plugins, plugin);
    290 	if (visited[index])
    291 		return 0;
    292 	visited[index] = 1;
    293 
    294 	FOR_ARRAY_ELEMENT(&plugin->ports, i, port) {
    295 		if (port->flow_id == INVALID_FLOW_ID)
    296 			continue;
    297 		flow_id = port->flow_id;
    298 		flow = ARRAY_ELEMENT(&ini->flows, flow_id);
    299 		if (!flow->from) {
    300 			syslog(LOG_ERR, "no plugin flows to %s:%d",
    301 			       plugin->title, i);
    302 			return -1;
    303 		}
    304 		if (topological_sort(pipeline, env, flow->from, visited) < 0)
    305 			return -1;
    306 	}
    307 
    308 	/* if the plugin is disabled, we don't construct an instance for it */
    309 	if (is_disabled(plugin, env))
    310 		return 0;
    311 
    312 	instance = ARRAY_APPEND_ZERO(&pipeline->instances);
    313 	instance->plugin = plugin;
    314 
    315 	/* constructs audio and control ports for the instance */
    316 	FOR_ARRAY_ELEMENT(&plugin->ports, i, port) {
    317 		int need_connect = (port->flow_id != INVALID_FLOW_ID &&
    318 				    port->direction == PORT_INPUT);
    319                 struct plugin *origin = NULL;
    320 		int origin_index = 0;
    321 
    322 		if (need_connect) {
    323 			if (find_origin_port(ini, &pipeline->instances, plugin,
    324 					     i, &origin, &origin_index) < 0)
    325 				return -1;
    326 		}
    327 
    328 		if (port->type == PORT_AUDIO) {
    329 			audio_port_array *audio_port_array =
    330 				(port->direction == PORT_INPUT) ?
    331 				&instance->input_audio_ports :
    332 				&instance->output_audio_ports;
    333 			struct audio_port *audio_port =
    334 				ARRAY_APPEND_ZERO(audio_port_array);
    335 			audio_port->plugin = plugin;
    336 			audio_port->original_index = i;
    337 			if (need_connect) {
    338 				struct audio_port *from;
    339 				from = find_output_audio_port(
    340 					&pipeline->instances, origin,
    341 					origin_index);
    342 				if (!from)
    343 					return -1;
    344 				from->peer = audio_port;
    345 				audio_port->peer = from;
    346 			}
    347 		} else if (port->type == PORT_CONTROL) {
    348 			control_port_array *control_port_array =
    349 				(port->direction == PORT_INPUT) ?
    350 				&instance->input_control_ports :
    351 				&instance->output_control_ports;
    352 			struct control_port *control_port =
    353 				ARRAY_APPEND_ZERO(control_port_array);
    354 			control_port->plugin = plugin;
    355 			control_port->original_index = i;
    356 			control_port->value = port->init_value;
    357 			if (need_connect) {
    358 				struct control_port *from;
    359 				from = find_output_control_port(
    360 					&pipeline->instances, origin,
    361 					origin_index);
    362 				if (!from)
    363 					return -1;
    364 				from->peer = control_port;
    365 				control_port->peer = from;
    366 			}
    367 		}
    368 	}
    369 
    370 	return 0;
    371 }
    372 
    373 static struct plugin *find_enabled_builtin_plugin(struct ini *ini,
    374 						  const char *label,
    375 						  const char *purpose,
    376 						  struct cras_expr_env *env)
    377 {
    378 	int i;
    379 	struct plugin *plugin, *found = NULL;
    380 
    381 	FOR_ARRAY_ELEMENT(&ini->plugins, i, plugin) {
    382 		if (strcmp(plugin->library, "builtin") != 0)
    383 			continue;
    384 		if (strcmp(plugin->label, label) != 0)
    385 			continue;
    386 		if (!plugin->purpose || strcmp(plugin->purpose, purpose) != 0)
    387 			continue;
    388 		if (is_disabled(plugin, env))
    389 			continue;
    390 		if (found) {
    391 			syslog(LOG_ERR, "two %s plugins enabled: %s and %s",
    392 			       label, found->title, plugin->title);
    393 			return NULL;
    394 		}
    395 		found = plugin;
    396 	}
    397 
    398 	return found;
    399 }
    400 
    401 struct pipeline *cras_dsp_pipeline_create(struct ini *ini,
    402 					  struct cras_expr_env *env,
    403 					  const char *purpose)
    404 {
    405 	struct pipeline *pipeline;
    406 	int n;
    407 	char *visited;
    408 	int rc;
    409 	struct plugin *source = find_enabled_builtin_plugin(
    410 		ini, "source", purpose, env);
    411 	struct plugin *sink = find_enabled_builtin_plugin(
    412 		ini, "sink", purpose, env);
    413 
    414 	if (!source || !sink) {
    415 		syslog(LOG_DEBUG,
    416 		       "no enabled source or sink found %p/%p for %s",
    417 		       source, sink, purpose);
    418 		return NULL;
    419 	}
    420 
    421 	pipeline = calloc(1, sizeof(struct pipeline));
    422 	if (!pipeline) {
    423 		syslog(LOG_ERR, "no memory for pipeline");
    424 		return NULL;
    425 	}
    426 
    427 	pipeline->ini = ini;
    428 	pipeline->purpose = purpose;
    429 	/* create instances for needed plugins, in the order of dependency */
    430 	n = ARRAY_COUNT(&ini->plugins);
    431 	visited = calloc(1, n);
    432 	rc = topological_sort(pipeline, env, sink, visited);
    433 	free(visited);
    434 
    435 	if (rc < 0) {
    436 		syslog(LOG_ERR, "failed to construct pipeline");
    437 		return NULL;
    438 	}
    439 
    440 	pipeline->source_instance = find_instance_by_plugin(
    441 		&pipeline->instances, source);
    442 	pipeline->sink_instance = find_instance_by_plugin(
    443 		&pipeline->instances, sink);
    444 
    445 	if (!pipeline->source_instance || !pipeline->sink_instance) {
    446 		syslog(LOG_ERR, "source(%p) or sink(%p) missing/disabled?",
    447 		       source, sink);
    448 		cras_dsp_pipeline_free(pipeline);
    449 		return NULL;
    450 	}
    451 
    452 	pipeline->input_channels = ARRAY_COUNT(
    453 		&pipeline->source_instance->output_audio_ports);
    454 	pipeline->output_channels = ARRAY_COUNT(
    455 		&pipeline->sink_instance->input_audio_ports);
    456 	if (pipeline->output_channels > pipeline->input_channels) {
    457 		/* Can't increase channel count, no where to put them. */
    458 		syslog(LOG_ERR, "DSP output more channels than input\n");
    459 		cras_dsp_pipeline_free(pipeline);
    460 		return NULL;
    461 	}
    462 
    463 	return pipeline;
    464 }
    465 
    466 static int load_module(struct plugin *plugin, struct instance *instance)
    467 {
    468 	struct dsp_module *module;
    469 	module = cras_dsp_module_load_builtin(plugin);
    470 	if (!module)
    471 		module = cras_dsp_module_load_ladspa(plugin);
    472 	if (!module)
    473 		return -1;
    474 	instance->module = module;
    475 	instance->properties = module->get_properties(module);
    476 	return 0;
    477 }
    478 
    479 static void use_buffers(char *busy, audio_port_array *audio_ports)
    480 {
    481 	int i, k = 0;
    482 	struct audio_port *audio_port;
    483 
    484 	FOR_ARRAY_ELEMENT(audio_ports, i, audio_port) {
    485 		while (busy[k])
    486 			k++;
    487 		audio_port->buf_index = k;
    488 		busy[k] = 1;
    489 	}
    490 }
    491 
    492 static void unuse_buffers(char *busy, audio_port_array *audio_ports)
    493 {
    494 	int i;
    495 	struct audio_port *audio_port;
    496 
    497 	FOR_ARRAY_ELEMENT(audio_ports, i, audio_port) {
    498 		busy[audio_port->buf_index] = 0;
    499 	}
    500 }
    501 
    502 /* assign which buffer each audio port on each instance should use */
    503 static int allocate_buffers(struct pipeline *pipeline)
    504 {
    505 	int i;
    506 	struct instance *instance;
    507 	int need_buf = 0, peak_buf = 0;
    508 	char *busy;
    509 
    510 	/* first figure out how many buffers do we need */
    511 	FOR_ARRAY_ELEMENT(&pipeline->instances, i, instance) {
    512 		int in = ARRAY_COUNT(&instance->input_audio_ports);
    513 		int out = ARRAY_COUNT(&instance->output_audio_ports);
    514 
    515 		if (instance->properties & MODULE_INPLACE_BROKEN) {
    516 			/* We cannot reuse input buffer as output
    517 			 * buffer, so we need to use extra buffers */
    518 			need_buf += out;
    519 			peak_buf = MAX(peak_buf, need_buf);
    520 			need_buf -= in;
    521 		} else {
    522 			need_buf += out - in;
    523 			peak_buf = MAX(peak_buf, need_buf);
    524 		}
    525 	}
    526 
    527 	/* then allocate the buffers */
    528 	pipeline->peak_buf = peak_buf;
    529 	pipeline->buffers = (float **)calloc(peak_buf, sizeof(float *));
    530 
    531 	if (!pipeline->buffers) {
    532 		syslog(LOG_ERR, "failed to allocate buffers");
    533 		return -1;
    534 	}
    535 
    536 	for (i = 0; i < peak_buf; i++) {
    537 		size_t size = DSP_BUFFER_SIZE * sizeof(float);
    538 		float *buf = calloc(1, size);
    539 		if (!buf) {
    540 			syslog(LOG_ERR, "failed to allocate buf");
    541 			return -1;
    542 		}
    543 		pipeline->buffers[i] = buf;
    544 	}
    545 
    546 	/* Now assign buffer index for each instance's input/output ports */
    547 	busy = calloc(peak_buf, sizeof(*busy));
    548 	FOR_ARRAY_ELEMENT(&pipeline->instances, i, instance) {
    549 		int j;
    550 		struct audio_port *audio_port;
    551 
    552 		/* Collect input buffers from upstream */
    553 		FOR_ARRAY_ELEMENT(&instance->input_audio_ports, j, audio_port) {
    554 			audio_port->buf_index = audio_port->peer->buf_index;
    555 		}
    556 
    557 		/* If the module has the MODULE_INPLACE_BROKEN flag,
    558 		 * we cannot reuse input buffers as output buffers, so
    559 		 * we need to use extra buffers. For example, in this graph
    560 		 *
    561 		 * [A]
    562 		 * output_0={x}
    563 		 * output_1={y}
    564 		 * output_2={z}
    565 		 * output_3={w}
    566 		 * [B]
    567 		 * input_0={x}
    568 		 * input_1={y}
    569 		 * input_2={z}
    570 		 * input_3={w}
    571 		 * output_4={u}
    572 		 *
    573 		 * Then peak_buf for this pipeline is 4. However if
    574 		 * plugin B has the MODULE_INPLACE_BROKEN flag, then
    575 		 * peak_buf is 5 because plugin B cannot output to the
    576 		 * same buffer used for input.
    577 		 *
    578 		 * This means if we don't have the flag, we can free
    579 		 * the input buffers then allocate the output buffers,
    580 		 * but if we have the flag, we have to allocate the
    581 		 * output buffers before freeing the input buffers.
    582 		 */
    583 		if (instance->properties & MODULE_INPLACE_BROKEN) {
    584 			use_buffers(busy, &instance->output_audio_ports);
    585 			unuse_buffers(busy, &instance->input_audio_ports);
    586 		} else {
    587 			unuse_buffers(busy, &instance->input_audio_ports);
    588 			use_buffers(busy, &instance->output_audio_ports);
    589 		}
    590 	}
    591 	free(busy);
    592 
    593 	return 0;
    594 }
    595 
    596 int cras_dsp_pipeline_load(struct pipeline *pipeline)
    597 {
    598 	int i;
    599 	struct instance *instance;
    600 
    601 	FOR_ARRAY_ELEMENT(&pipeline->instances, i, instance) {
    602 		struct plugin *plugin = instance->plugin;
    603 		if (load_module(plugin, instance) != 0)
    604 			return -1;
    605 	}
    606 
    607 	if (allocate_buffers(pipeline) != 0)
    608 		return -1;
    609 
    610 	return 0;
    611 }
    612 
    613 /* Calculates the total buffering delay of each instance from the source */
    614 static void calculate_audio_delay(struct pipeline *pipeline)
    615 {
    616 	int i;
    617 	struct instance *instance;
    618 
    619 	FOR_ARRAY_ELEMENT(&pipeline->instances, i, instance) {
    620 		struct dsp_module *module = instance->module;
    621 		audio_port_array *audio_in = &instance->input_audio_ports;
    622 		struct audio_port *audio_port;
    623 		int delay = 0;
    624 		int j;
    625 
    626 		/* Finds the max delay of all modules that provide input to this
    627 		 * instance. */
    628 		FOR_ARRAY_ELEMENT(audio_in, j, audio_port) {
    629 			struct instance *upstream = find_instance_by_plugin(
    630 				&pipeline->instances, audio_port->peer->plugin);
    631 			delay = MAX(upstream->total_delay, delay);
    632 		}
    633 
    634 		instance->total_delay = delay + module->get_delay(module);
    635 	}
    636 }
    637 
    638 int cras_dsp_pipeline_instantiate(struct pipeline *pipeline, int sample_rate)
    639 {
    640 	int i;
    641 	struct instance *instance;
    642 
    643 	FOR_ARRAY_ELEMENT(&pipeline->instances, i, instance) {
    644 		struct dsp_module *module = instance->module;
    645 		if (module->instantiate(module, sample_rate) != 0)
    646 			return -1;
    647 		instance->instantiated = 1;
    648 		syslog(LOG_DEBUG, "instantiate %s", instance->plugin->label);
    649 	}
    650 	pipeline->sample_rate = sample_rate;
    651 
    652 	FOR_ARRAY_ELEMENT(&pipeline->instances, i, instance) {
    653 		audio_port_array *audio_in = &instance->input_audio_ports;
    654 		audio_port_array *audio_out = &instance->output_audio_ports;
    655 		control_port_array *control_in = &instance->input_control_ports;
    656 		control_port_array *control_out =
    657 			&instance->output_control_ports;
    658 		int j;
    659 		struct audio_port *audio_port;
    660 		struct control_port *control_port;
    661 		struct dsp_module *module = instance->module;
    662 
    663 		/* connect audio ports */
    664 		FOR_ARRAY_ELEMENT(audio_in, j, audio_port) {
    665 			float *buf = pipeline->buffers[audio_port->buf_index];
    666 			module->connect_port(module,
    667 					     audio_port->original_index,
    668 					     buf);
    669 			syslog(LOG_DEBUG, "connect audio buf %d to %s:%d (in)",
    670 			       audio_port->buf_index, instance->plugin->title,
    671 			       audio_port->original_index);
    672 		}
    673 		FOR_ARRAY_ELEMENT(audio_out, j, audio_port) {
    674 			float *buf = pipeline->buffers[audio_port->buf_index];
    675 			module->connect_port(module,
    676 					     audio_port->original_index,
    677 					     buf);
    678 			syslog(LOG_DEBUG, "connect audio buf %d to %s:%d (out)",
    679 			       audio_port->buf_index, instance->plugin->title,
    680 			       audio_port->original_index);
    681 		}
    682 
    683 		/* connect control ports */
    684 		FOR_ARRAY_ELEMENT(control_in, j, control_port) {
    685 			/* Note for input control ports which has a
    686 			 * peer, we use &control_port->peer->value, so
    687 			 * we can get the peer port's output value
    688 			 * directly */
    689 			float *value = control_port->peer ?
    690 				&control_port->peer->value :
    691 				&control_port->value;
    692 			module->connect_port(module,
    693 					     control_port->original_index,
    694 					     value);
    695 			syslog(LOG_DEBUG,
    696 			       "connect control (val=%g) to %s:%d (in)",
    697 			       control_port->value, instance->plugin->title,
    698 			       control_port->original_index);
    699 		}
    700 		FOR_ARRAY_ELEMENT(control_out, j, control_port) {
    701 			module->connect_port(module,
    702 					     control_port->original_index,
    703 					     &control_port->value);
    704 			syslog(LOG_DEBUG,
    705 			       "connect control (val=%g) to %s:%d (out)",
    706 			       control_port->value, instance->plugin->title,
    707 			       control_port->original_index);
    708 		}
    709 	}
    710 
    711 	calculate_audio_delay(pipeline);
    712 	return 0;
    713 }
    714 
    715 void cras_dsp_pipeline_deinstantiate(struct pipeline *pipeline)
    716 {
    717 	int i;
    718 	struct instance *instance;
    719 
    720 	FOR_ARRAY_ELEMENT(&pipeline->instances, i, instance) {
    721 		struct dsp_module *module = instance->module;
    722 		if (instance->instantiated) {
    723 			module->deinstantiate(module);
    724 			instance->instantiated = 0;
    725 		}
    726 	}
    727 	pipeline->sample_rate = 0;
    728 }
    729 
    730 int cras_dsp_pipeline_get_delay(struct pipeline *pipeline)
    731 {
    732 	return pipeline->sink_instance->total_delay;
    733 }
    734 
    735 int cras_dsp_pipeline_get_sample_rate(struct pipeline *pipeline)
    736 {
    737 	return pipeline->sample_rate;
    738 }
    739 
    740 int cras_dsp_pipeline_get_num_input_channels(struct pipeline *pipeline)
    741 {
    742 	return pipeline->input_channels;
    743 }
    744 
    745 int cras_dsp_pipeline_get_num_output_channels(struct pipeline *pipeline)
    746 {
    747 	return pipeline->output_channels;
    748 }
    749 
    750 int cras_dsp_pipeline_get_peak_audio_buffers(struct pipeline *pipeline)
    751 {
    752 	return pipeline->peak_buf;
    753 }
    754 
    755 static float *find_buffer(struct pipeline *pipeline,
    756 			  audio_port_array *audio_ports,
    757 			  int index)
    758 {
    759 	int i;
    760 	struct audio_port *audio_port;
    761 
    762 	FOR_ARRAY_ELEMENT(audio_ports, i, audio_port) {
    763 		if (audio_port->original_index == index)
    764 			return pipeline->buffers[audio_port->buf_index];
    765 	}
    766 	return NULL;
    767 }
    768 
    769 float *cras_dsp_pipeline_get_source_buffer(struct pipeline *pipeline, int index)
    770 {
    771 	return find_buffer(pipeline,
    772 			   &pipeline->source_instance->output_audio_ports,
    773 			   index);
    774 }
    775 
    776 float *cras_dsp_pipeline_get_sink_buffer(struct pipeline *pipeline, int index)
    777 {
    778 	return find_buffer(pipeline,
    779 			   &pipeline->sink_instance->input_audio_ports,
    780 			   index);
    781 }
    782 
    783 void cras_dsp_pipeline_run(struct pipeline *pipeline, int sample_count)
    784 {
    785 	int i;
    786 	struct instance *instance;
    787 
    788 	FOR_ARRAY_ELEMENT(&pipeline->instances, i, instance) {
    789 		struct dsp_module *module = instance->module;
    790 		module->run(module, sample_count);
    791 	}
    792 }
    793 
    794 void cras_dsp_pipeline_add_statistic(struct pipeline *pipeline,
    795 				     const struct timespec *time_delta,
    796 				     int samples)
    797 {
    798 	int64_t t;
    799 	if (samples <= 0)
    800 		return;
    801 
    802 	t = time_delta->tv_sec * 1000000000LL + time_delta->tv_nsec;
    803 
    804 	if (pipeline->total_blocks == 0) {
    805 		pipeline->max_time = t;
    806 		pipeline->min_time = t;
    807 	} else {
    808 		pipeline->max_time = MAX(pipeline->max_time, t);
    809 		pipeline->min_time = MIN(pipeline->min_time, t);
    810 	}
    811 
    812 	pipeline->total_blocks++;
    813 	pipeline->total_samples += samples;
    814 	pipeline->total_time += t;
    815 }
    816 
    817 void cras_dsp_pipeline_apply(struct pipeline *pipeline,
    818 			     uint8_t *buf, unsigned int frames)
    819 {
    820 	size_t remaining;
    821 	size_t chunk;
    822 	size_t i;
    823 	int16_t *target;
    824 	unsigned int input_channels = pipeline->input_channels;
    825 	unsigned int output_channels = pipeline->output_channels;
    826 	float *source[input_channels];
    827 	float *sink[output_channels];
    828 	struct timespec begin, end, delta;
    829 
    830 	if (!pipeline || frames == 0)
    831 		return;
    832 
    833 	clock_gettime(CLOCK_THREAD_CPUTIME_ID, &begin);
    834 
    835 	target = (int16_t *)buf;
    836 
    837 	/* get pointers to source and sink buffers */
    838 	for (i = 0; i < input_channels; i++)
    839 		source[i] = cras_dsp_pipeline_get_source_buffer(pipeline, i);
    840 	for (i = 0; i < output_channels; i++)
    841 		sink[i] = cras_dsp_pipeline_get_sink_buffer(pipeline, i);
    842 
    843 	remaining = frames;
    844 
    845 	/* process at most DSP_BUFFER_SIZE frames each loop */
    846 	while (remaining > 0) {
    847 		chunk = MIN(remaining, (size_t)DSP_BUFFER_SIZE);
    848 
    849 		/* deinterleave and convert to float */
    850 		dsp_util_deinterleave(target, source, input_channels, chunk);
    851 
    852 		/* Run the pipeline */
    853 		cras_dsp_pipeline_run(pipeline, chunk);
    854 
    855 		/* interleave and convert back to int16_t */
    856 		dsp_util_interleave(sink, target, output_channels, chunk);
    857 
    858 		target += chunk * output_channels;
    859 		remaining -= chunk;
    860 	}
    861 
    862 	clock_gettime(CLOCK_THREAD_CPUTIME_ID, &end);
    863 	subtract_timespecs(&end, &begin, &delta);
    864 	cras_dsp_pipeline_add_statistic(pipeline, &delta, frames);
    865 }
    866 
    867 void cras_dsp_pipeline_free(struct pipeline *pipeline)
    868 {
    869 	int i;
    870 	struct instance *instance;
    871 
    872 	FOR_ARRAY_ELEMENT(&pipeline->instances, i, instance) {
    873 		struct dsp_module *module = instance->module;
    874 		instance->plugin = NULL;
    875 		ARRAY_FREE(&instance->input_audio_ports);
    876 		ARRAY_FREE(&instance->input_control_ports);
    877 		ARRAY_FREE(&instance->output_audio_ports);
    878 		ARRAY_FREE(&instance->output_control_ports);
    879 
    880 		if (module) {
    881 			if (instance->instantiated) {
    882 				module->deinstantiate(module);
    883 				instance->instantiated = 0;
    884 			}
    885 			module->free_module(module);
    886 			instance->module = NULL;
    887 		}
    888 	}
    889 
    890 	pipeline->ini = NULL;
    891 	ARRAY_FREE(&pipeline->instances);
    892 
    893 	for (i = 0; i < pipeline->peak_buf; i++)
    894 		free(pipeline->buffers[i]);
    895 	free(pipeline->buffers);
    896 	free(pipeline);
    897 }
    898 
    899 static void dump_audio_ports(struct dumper *d, const char *name,
    900 			     audio_port_array *audio_ports)
    901 {
    902 	int i;
    903 	struct audio_port *audio_port;
    904 	int n = ARRAY_COUNT(audio_ports);
    905 
    906 	if (n == 0)
    907 		return;
    908 	dumpf(d, "   %s (%d) =\n", name, n);
    909 
    910 	FOR_ARRAY_ELEMENT(audio_ports, i, audio_port) {
    911 		dumpf(d, "   %p, peer %p, orig=%d, buf=%d\n",
    912 		      audio_port, audio_port->peer,
    913 		      audio_port->original_index, audio_port->buf_index);
    914 	}
    915 }
    916 
    917 static void dump_control_ports(struct dumper *d, const char *name,
    918 			       control_port_array *control_ports)
    919 {
    920 	int i;
    921 	struct control_port *control_port;
    922 	int n = ARRAY_COUNT(control_ports);
    923 
    924 	if (n == 0)
    925 		return;
    926 	dumpf(d, "   %s (%d) =\n", name, ARRAY_COUNT(control_ports));
    927 
    928 	FOR_ARRAY_ELEMENT(control_ports, i, control_port) {
    929 		dumpf(d, "   %p, peer %p, orig=%d, value=%g\n",
    930 		      control_port, control_port->peer,
    931 		      control_port->original_index, control_port->value);
    932 	}
    933 }
    934 
    935 void cras_dsp_pipeline_dump(struct dumper *d, struct pipeline *pipeline)
    936 {
    937 	int i;
    938 	struct instance *instance;
    939 
    940 	dumpf(d, "---- pipeline dump begin ----\n");
    941 	dumpf(d, "pipeline (%s):\n", pipeline->purpose);
    942 	dumpf(d, " input channels: %d\n", pipeline->input_channels);
    943 	dumpf(d, " output channels: %d\n", pipeline->output_channels);
    944 	dumpf(d, " sample_rate: %d\n", pipeline->sample_rate);
    945 	dumpf(d, " processed samples: %" PRId64 "\n", pipeline->total_samples);
    946 	dumpf(d, " processed blocks: %" PRId64 "\n", pipeline->total_blocks);
    947 	dumpf(d, " total processing time: %" PRId64 "ns\n",
    948 	      pipeline->total_time);
    949 	if (pipeline->total_blocks) {
    950 		dumpf(d, " average block size: %" PRId64 "\n",
    951 		      pipeline->total_samples / pipeline->total_blocks);
    952 		dumpf(d, " avg processing time per block: %" PRId64 "ns\n",
    953 		      pipeline->total_time / pipeline->total_blocks);
    954 	}
    955 	dumpf(d, " min processing time per block: %" PRId64 "ns\n",
    956 	      pipeline->min_time);
    957 	dumpf(d, " max processing time per block: %" PRId64 "ns\n",
    958 	      pipeline->max_time);
    959 	dumpf(d, " cpu load: %g%%\n", pipeline->total_time * 1e-9
    960 	      / pipeline->total_samples * pipeline->sample_rate * 100);
    961 	dumpf(d, " instances (%d):\n",
    962 	      ARRAY_COUNT(&pipeline->instances));
    963 	FOR_ARRAY_ELEMENT(&pipeline->instances, i, instance) {
    964 		struct dsp_module *module = instance->module;
    965 		dumpf(d, "  [%d]%s mod=%p, total delay=%d\n",
    966 		      i, instance->plugin->title, module,
    967 		      instance->total_delay);
    968 		if (module)
    969 			module->dump(module, d);
    970 		dump_audio_ports(d, "input_audio_ports",
    971 				 &instance->input_audio_ports);
    972 		dump_audio_ports(d, "output_audio_ports",
    973 				 &instance->output_audio_ports);
    974 		dump_control_ports(d, "input_control_ports",
    975 				   &instance->input_control_ports);
    976 		dump_control_ports(d, "output_control_ports",
    977 				   &instance->output_control_ports);
    978 	}
    979 	dumpf(d, " peak_buf = %d\n", pipeline->peak_buf);
    980 	dumpf(d, "---- pipeline dump end ----\n");
    981 }
    982