summaryrefslogtreecommitdiff
path: root/filter.h
blob: 27e8d0666e64b5c4eb6aa721cfc5c0ffa32bcb14 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
/* SPDX-License-Identifier: GPL-2.0 */

/** \file filter.h Filter API
 *
 * Filters are part of para_audiod(1), para_filter(1) and para_play(1).
 * Each filter is implemented in its own file whose name ends in _filter.c. For
 * example, the file which contains the implementation of the mp3 decoder is
 * \ref mp3dec_filter.c. Additionally, there is \ref filter_common.c which
 * contains the few public helpers declared in this header file.
 *
 * An instance of a filter is described by struct \ref filter_node. It is
 * created by calling \ref filter::open(). The simplest possible setup is
 * a filter chain with a single filter where the data source is stdin and
 * the data sink is stdout. This is the setup created by para_filter(1)
 * if only one filter option is specified.
 *
 * All users of the filter API create a buffer tree and link the buffer
 * tree node of the filter instance, \ref filter_node::btrn, into the tree
 * as an internal node. The instance is then registered to the scheduler by
 * calling \ref task_register().
 */

/** Describes one instance of a filter. */
struct filter_node {
	/** The number in the array of available filters. */
	unsigned filter_num;
	/**
	 * Each filter may store any filter-specific information about the particular
	 * instance of the filter here.
	 */
	void *private_data;
	/** The list of registered callbacks. */
	struct list_head callbacks;
	/** A pointer to the configuration of this instance. */
	void *conf;
	/** The parsed command line, merged with options given in the config file. */
	struct lls_parse_result *lpr;
	/** The buffer tree node. */
	struct btr_node *btrn;
	/** The task of to this filter instance. */
	struct task *task;
	/** The minimal input queue size, see \ref btr_node_status(). */
	size_t min_iqs;
};

/**
 * Definition of a paraslash filter.
 *
 * Filters describe how to transform input data into output data. This
 * structure contains the methods which have to be defined to implement a
 * particular filter.
 *
 * Since more than one instance of the same filter may be running at the
 * same time, all filter methods must be reentrant. In particular, no static
 * non-constant variables must be defined.
 *
 * \sa \ref filter_node, struct \ref receiver, struct \ref writer.
 */
struct filter {
	/**
	 * Open one instance of this filter.
	 *
	 * This should allocate the output buffer of the given filter node
	 * and do any other filter-specific preparations like initializing the
	 * \ref filter_node::private_data member suitably. The open function
	 * is optional, If it is provided, it is assumed to succeed.
	 */
	void (*open)(struct filter_node *fn);
	/**
	 * Close one instance of this filter.
	 *
	 * Free all resources associated with the given filter instance. It's
	 * OK to set this to NULL if the filter does not need to perform any
	 * cleanup operation.
	 */
	void (*close)(struct filter_node *fn);
	/**
	 * Prepare the filter according to command line options.
	 *
	 * In addition to the syntactic checks which are automatically performed
	 * by the lopsub functions, some filters like to also check the command
	 * line arguments semantically. Moreover, since applications may open
	 * the filter many times with the same options, filters need a method
	 * which allows them to precompute once those parts of the setup which
	 * depend only on the command line options.
	 *
	 * If this function pointer is not NULL, the function is called once at
	 * startup. The returned pointer value is made available to the ->open
	 * method via the ->conf pointer of struct filter_node.
	 *
	 * Filters are supposed to abort if the setup fails. If the function
	 * returns, it is assumed to have succeeded.
	 */
	void *(*setup)(const struct lls_parse_result *lpr);
	/**
	 * Deallocate precomputed resources.
	 *
	 * This should free whatever ->setup() has allocated.
	 */
	void (*teardown)(const struct lls_parse_result *lpr, void *conf);
	/** Force a zero timeout if data is available in the buffer tree. */
	void (*pre_monitor)(struct sched *s, void *context);
	/** Convert (filter) input data into output data. */
	int (*post_monitor)(struct sched *s, void *context);
	/**
	 * Answer a buffer tree query.
	 *
	 * This optional function pointer is used for inter node communications
	 * of the buffer tree nodes. See \ref btr_command_handler for details.
	 */
	btr_command_handler execute;
};

/** \cond doxygen_ignore */
#define FILTER_CMD(_num) (lls_cmd(_num, filter_cmd_suite))
#define FILTER_CMD_OPT(_cmd, _opt) (lls_opt( \
	LSG_FILTER_CMD_ ## _cmd ## _OPT_ ## _opt, \
	FILTER_CMD(LSG_FILTER_CMD_CMD_ ## _cmd)))
#define FILTER_CMD_OPT_RESULT(_cmd, _opt, _lpr) \
	(lls_opt_result(LSG_FILTER_CMD_ ## _cmd ## _OPT_ ## _opt, _lpr))
#define FILTER_CMD_OPT_GIVEN(_cmd, _opt, _lpr) \
	(lls_opt_given(FILTER_CMD_OPT_RESULT(_cmd, _opt, _lpr)))
#define FILTER_CMD_OPT_UINT32_VAL(_cmd, _opt, _lpr) \
	(lls_uint32_val(0, FILTER_CMD_OPT_RESULT(_cmd, _opt, _lpr)))
#define FILTER_CMD_OPT_STRING_VAL(_cmd, _opt, _lpr) \
	(lls_string_val(0, FILTER_CMD_OPT_RESULT(_cmd, _opt, _lpr)))
/** \endcond */

void print_filter_helps(bool detailed);
void print_filter_list(void);
int filter_setup(const char *fa, void **conf, struct lls_parse_result **lprp);
const struct filter *filter_get(int filter_num);
const char *filter_name(int filter_num);
void generic_filter_pre_monitor(struct sched *s, void *context);
int decoder_execute(const char *cmd, unsigned sample_rate, unsigned channels,
		char **result);

/**
 * Write the two bytes of a signed 16 bit number in host byte order.
 *
 * Little endian means to write the lower eight bits at the lower address. This
 * is what most architectures do, including x86 and arm.
 *
 * \param buf Exactly two bytes are written, so this must be at least two
 * bytes large.
 *
 * \param val Between -32768 and 32767, inclusively.
 */
_static_inline_ void write_int16_host_endian(char *buf, int val)
{

/*
 * Shifting a negative value x is the same as shifting -x - 1, then
 * negate. then subtract one. For example, -256>>8 is -1 but -257>>8 is -2.
 */
#ifdef WORDS_BIGENDIAN
	*buf = val >> 8;
	*(buf + 1) = val & 0xff;
#else
	*buf = val & 0xff;
	*(buf + 1) = val >> 8;
#endif
}