filter api
authorAndre Noll <maan@tuebingen.mpg.de>
Thu, 12 Jun 2025 19:18:46 +0000 (21:18 +0200)
committerAndre Noll <maan@tuebingen.mpg.de>
Thu, 12 Jun 2025 19:18:46 +0000 (21:18 +0200)
filter.h
recv.h
web/para.css

index 77057e6a7d2b9a997219d907b3ddd459716283ad..ccf68965522b032cf4fc6a3656a040baecf41447 100644 (file)
--- a/filter.h
+++ b/filter.h
@@ -1,10 +1,26 @@
 /* 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;
@@ -28,15 +44,15 @@ struct filter_node {
 };
 
 /**
- * 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.
@@ -45,18 +61,18 @@ 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
-        * 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);
        /**
@@ -96,9 +112,7 @@ struct filter {
        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, \
@@ -111,13 +125,35 @@ int filter_setup(const char *fa, void **conf, struct lls_parse_result **lprp);
        (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;
@@ -126,6 +162,3 @@ static inline void write_int16_host_endian(char *buf, int val)
        *(buf + 1) = val >> 8;
 #endif
 }
-
-const struct filter *filter_get(int filter_num);
-const char *filter_name(int filter_num);
diff --git a/recv.h b/recv.h
index 62b6ef802eb5e158492b268195dd6c64d6e15b55..51dc382ab6604cbf48a49f2e606db36ced63d3fa 100644 (file)
--- a/recv.h
+++ b/recv.h
@@ -2,13 +2,13 @@
 
 /** \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.
  */
index fd457902c279610a8aff3047e639e5a77b02402c..ca8e491ae593228684c39034e9fab664d2b50797 100644 (file)
@@ -84,8 +84,8 @@ div.groupHeader {
        font-weight: bold;
 }
 
-td.tiny {
-       font-size: 75%;
+td.paramname {
+       color: #0ff;
 }
 
 .memitem { /* outer border around function */