/* Copyright (C) 2005 Andre Noll <maan@tuebingen.mpg.de>, see file COPYING. */
-/** \file filter.h Filter-related structures and exported symbols from filter_common.c. */
+/** \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 implements the filter that decodes mp3 files is
+ * \ref mp3dec_filter.c. Additionally, there is \ref filter_common.c which
+ * contains the few public helpers declared in this 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 is specified.
+ *
+ * All users of the filter API create a buffer tree and link the node of
+ * the filter instance, \ref filter_node::btrn, into the buffer tree as
+ * an internal node. The instance is then registered to the scheduler by
+ * passing \ref filter_node::task to \ref task_register().
+ */
-/**
- * Describes one running instance of a filter.
-*/
+/** Describes one instance of a filter. */
struct filter_node {
/** The number in the array of available filters. */
unsigned filter_num;
};
/**
- * Describes a method to convert audio data.
+ * Definition of a paraslash filter.
*
- * Paraslash filters are "modules" which transform the data of an audio stream.
- * This structure contains the methods which have to be implemented by each
- * 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.
*
- * As several instances of the same filter may be running at the same time, all
- * filter methods must be reentrant and no static non-constant variables must
- * be used.
+ * 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 \ref
* sched.
/**
* 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
- * private_data member of \a fn suitably. The open function is
- * optional, If it is provided, it is assumed to succeed.
+ * 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 \a fn that were previously
- * allocated by the open() function. It's OK to set this to NULL if the
- * filter does not need to perform any cleanup operation.
+ * 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);
/**
btr_command_handler execute;
};
-void print_filter_helps(bool detailed);
-void print_filter_list(void);
-int filter_setup(const char *fa, void **conf, struct lls_parse_result **lprp);
+/** \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, \
(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);
-static inline void write_int16_host_endian(char *buf, int val)
+/**
+ * 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;
*(buf + 1) = val >> 8;
#endif
}
-
-const struct filter *filter_get(int filter_num);
-const char *filter_name(int filter_num);
/** \file recv.h Receiver API
*
- * Receivers are part of para_audiod(1) and para_recv(1). Each receiver is
- * implemented in a separate file which defines a non-static a \ref receiver
- * structure. An instance of the receiver, a \ref receiver_node, is created
- * by calling \ref receiver::open. The receiver node is set up by making
- * it the root of a buffer tree and registering it to the scheduler. Once
- * scheduling is started the receiver node performs I/O as long as there is
- * input available and room and room in its output buffer.
+ * Receivers are part of para_audiod(1), para_recv(1) and para_play(1). Each
+ * receiver is implemented in a separate file which defines a non-static a \ref
+ * receiver structure. An instance of the receiver, a \ref receiver_node,
+ * is created by calling \ref receiver::open. The receiver node is set
+ * up by making it the root of a buffer tree and registering it to the
+ * scheduler. Once scheduling is started the receiver node performs I/O as
+ * long as there is input available and room and room in its output buffer.
*
* The few functions declared here are defined in \ref recv_common.c.
*/