]> git.alsa-project.org Git - alsa-lib.git/commitdiff
Fix documentation of external PCM plugin SDK
authorTakashi Iwai <tiwai@suse.de>
Tue, 24 May 2005 09:42:01 +0000 (09:42 +0000)
committerTakashi Iwai <tiwai@suse.de>
Tue, 24 May 2005 09:42:01 +0000 (09:42 +0000)
Fix documentation of external PCM plugin SDK.

doc/doxygen.cfg
include/pcm_external.h
include/pcm_extplug.h
include/pcm_ioplug.h
src/pcm/pcm_extplug.c
src/pcm/pcm_ioplug.c

index 5f830b1a05274d563a52fdc62abb94903bac871a..6ac2688bbbc492bb7f244bb864d5905a1396cbd8 100644 (file)
@@ -23,6 +23,9 @@ INPUT            = index.doxygen \
                   ../include/seq_event.h \
                   ../include/seqmid.h \
                   ../include/seq_midi_event.h \
+                  ../include/pcm_external.h \
+                  ../include/pcm_extplug.h \
+                  ../include/pcm_ioplug.h \
                   ../include/conv.h \
                   ../include/instr.h \
                   ../src/error.c \
index 548105351ee281c08204499eb70b14c5d2fa9551..57504188828132a1570805509418730d1fa9a185 100644 (file)
@@ -37,9 +37,19 @@ extern "C" {
  *  \{
  */
 
+/**
+ * Define the object entry for external PCM plugins
+ */
 #define SND_PCM_PLUGIN_ENTRY(name) _snd_pcm_##name##_open
+
+/**
+ * Define the symbols of the given plugin with versions
+ */
 #define SND_PCM_PLUGIN_SYMBOL(name) SND_DLSYM_BUILD_VERSION(SND_PCM_PLUGIN_ENTRY(name), SND_PCM_DLSYM_VERSION);
 
+/**
+ * Define the plugin
+ */
 #define SND_PCM_PLUGIN_DEFINE_FUNC(plugin) \
 int SND_PCM_PLUGIN_ENTRY(plugin) (snd_pcm_t **pcmp, const char *name,\
                                  snd_config_t *root, snd_config_t *conf, \
index 566c18ef7a0683b979ad8b2ef54f100d5f3b76b2..7a822d8ff9c1b355864b1a4444d6ef3b37b11468 100644 (file)
@@ -1,3 +1,12 @@
+/**
+ * \file include/pcm_extplug.h
+ * \brief External Filter-Plugin SDK
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 2005
+ *
+ * External Filter-Plugin SDK
+ */
+
 /*
  * ALSA external PCM plugin SDK (draft version)
  *
 #ifndef __ALSA_PCM_EXTPLUG_H
 #define __ALSA_PCM_EXTPLUG_H
 
+/**
+ * \defgroup PCM_ExtPlug External Filter plugin SDK
+ * \ingroup Plugin_SDK
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
 /** hw constraints for extplug */
 enum {
        SND_PCM_EXTPLUG_HW_FORMAT,      /**< format */
@@ -29,23 +45,28 @@ enum {
        SND_PCM_EXTPLUG_HW_PARAMS       /**< max number of hw constraints */
 };
        
+/** Handle of external filter plugin */
 typedef struct snd_pcm_extplug snd_pcm_extplug_t;
+/** Callback table of extplug */
 typedef struct snd_pcm_extplug_callback snd_pcm_extplug_callback_t;
 
-/**
+/*
  * Protocol version
  */
-#define SND_PCM_EXTPLUG_VERSION_MAJOR  1
-#define SND_PCM_EXTPLUG_VERSION_MINOR  0
-#define SND_PCM_EXTPLUG_VERSION_TINY   0
+#define SND_PCM_EXTPLUG_VERSION_MAJOR  1       /**< Protocol major version */
+#define SND_PCM_EXTPLUG_VERSION_MINOR  0       /**< Protocol minor version */
+#define SND_PCM_EXTPLUG_VERSION_TINY   0       /**< Protocol tiny version */
+/**
+ * Filter-plugin protocol version
+ */
 #define SND_PCM_EXTPLUG_VERSION                ((SND_PCM_EXTPLUG_VERSION_MAJOR<<16) |\
                                         (SND_PCM_EXTPLUG_VERSION_MINOR<<8) |\
                                         (SND_PCM_EXTPLUG_VERSION_TINY))
 
-/** handle of extplug */
+/** Handle of extplug */
 struct snd_pcm_extplug {
        /**
-        * protocol version; SND_PCM_EXTPLUG_VERSION must be filled here
+        * protocol version; #SND_PCM_EXTPLUG_VERSION must be filled here
         * before calling #snd_pcm_extplug_create()
         */
        unsigned int version;
@@ -99,7 +120,7 @@ struct snd_pcm_extplug {
        unsigned int slave_channels;
 };
 
-/** callback table of extplug */
+/** Callback table of extplug */
 struct snd_pcm_extplug_callback {
        /**
         * transfer between source and destination; this is a required callback
@@ -143,15 +164,22 @@ int snd_pcm_extplug_set_param_minmax(snd_pcm_extplug_t *extplug, int type, unsig
 int snd_pcm_extplug_set_slave_param_list(snd_pcm_extplug_t *extplug, int type, unsigned int num_list, const unsigned int *list);
 int snd_pcm_extplug_set_slave_param_minmax(snd_pcm_extplug_t *extplug, int type, unsigned int min, unsigned int max);
 
+/**
+ * set the parameter constraint with a single value
+ */
 static inline int snd_pcm_extplug_set_param(snd_pcm_extplug_t *extplug, int type, unsigned int val)
 {
        return snd_pcm_extplug_set_param_list(extplug, type, 1, &val);
 }
 
+/**
+ * set the parameter constraint for slave PCM with a single value
+ */
 static inline int snd_pcm_extplug_set_slave_param(snd_pcm_extplug_t *extplug, int type, unsigned int val)
 {
        return snd_pcm_extplug_set_slave_param_list(extplug, type, 1, &val);
 }
 
+/** \} */
 
 #endif /* __ALSA_PCM_EXTPLUG_H */
index 5dee834dfdcd46db7e99dddf85bafca06277e382..58f97be6e411c76acafb31b18916b333892f0324 100644 (file)
@@ -1,5 +1,14 @@
+/**
+ * \file include/pcm_ioplug.h
+ * \brief External I/O-Plugin SDK
+ * \author Takashi Iwai <tiwai@suse.de>
+ * \date 2005
+ *
+ * External I/O-Plugin SDK
+ */
+
 /*
- * ALSA external PCM plugin SDK (draft version)
+ * ALSA external PCM plugin SDK
  *
  * Copyright (c) 2005 Takashi Iwai <tiwai@suse.de>
  *
 #ifndef __ALSA_PCM_IOPLUG_H
 #define __ALSA_PCM_IOPLUG_H
 
+/**
+ * \defgroup PCM_IOPlug External I/O plugin SDK
+ * \ingroup Plugin_SDK
+ * See the \ref pcm page for more details.
+ * \{
+ */
+
 /** hw constraints for ioplug */
 enum {
        SND_PCM_IOPLUG_HW_ACCESS = 0,   /**< access type */
@@ -34,7 +50,9 @@ enum {
        SND_PCM_IOPLUG_HW_PARAMS        /**< max number of hw constraints */
 };
        
+/** I/O plugin handle */
 typedef struct snd_pcm_ioplug snd_pcm_ioplug_t;
+/** Callback table of ioplug */
 typedef struct snd_pcm_ioplug_callback snd_pcm_ioplug_callback_t;
 
 /**
@@ -42,20 +60,23 @@ typedef struct snd_pcm_ioplug_callback snd_pcm_ioplug_callback_t;
  */
 #define SND_PCM_IOPLUG_FLAG_LISTED     (1<<0)          /* list up this PCM */
 
-/**
+/*
  * Protocol version
  */
-#define SND_PCM_IOPLUG_VERSION_MAJOR   1
-#define SND_PCM_IOPLUG_VERSION_MINOR   0
-#define SND_PCM_IOPLUG_VERSION_TINY    0
+#define SND_PCM_IOPLUG_VERSION_MAJOR   1       /**< Protocol major version */
+#define SND_PCM_IOPLUG_VERSION_MINOR   0       /**< Protocol minor version */
+#define SND_PCM_IOPLUG_VERSION_TINY    0       /**< Protocol tiny version */
+/**
+ * IO-plugin protocol version
+ */
 #define SND_PCM_IOPLUG_VERSION         ((SND_PCM_IOPLUG_VERSION_MAJOR<<16) |\
                                         (SND_PCM_IOPLUG_VERSION_MINOR<<8) |\
                                         (SND_PCM_IOPLUG_VERSION_TINY))
 
-/** handle of ioplug */
+/** Handle of ioplug */
 struct snd_pcm_ioplug {
        /**
-        * protocol version; SND_PCM_IOPLUG_VERSION must be filled here
+        * protocol version; #SND_PCM_IOPLUG_VERSION must be filled here
         * before calling #snd_pcm_ioplug_create()
         */
        unsigned int version;
@@ -80,21 +101,21 @@ struct snd_pcm_ioplug {
         */
        snd_pcm_t *pcm;
 
-       snd_pcm_stream_t stream;        /* stream direcion; read-only */        
-       snd_pcm_state_t state;          /* current PCM state; read-only */
-       volatile snd_pcm_uframes_t appl_ptr;    /* application pointer; read-only */
-       volatile snd_pcm_uframes_t hw_ptr;      /* hw pointer; read-only */
-       int nonblock;                   /* non-block mode; read-only */
-
-       snd_pcm_access_t access;        /* access type; filled after hw_params is called */
-       snd_pcm_format_t format;        /* format; filled after hw_params is called */
-       unsigned int channels;          /* channels; filled after hw_params is called */
-       unsigned int rate;              /* rate; filled after hw_params is called */
-       snd_pcm_uframes_t period_size;  /* period size; filled after hw_params is called */
-       snd_pcm_uframes_t buffer_size;  /* buffer size; filled after hw_params is called */
+       snd_pcm_stream_t stream;        /**< stream direcion; read-only */      
+       snd_pcm_state_t state;          /**< current PCM state; read-only */
+       volatile snd_pcm_uframes_t appl_ptr;    /**< application pointer; read-only */
+       volatile snd_pcm_uframes_t hw_ptr;      /**< hw pointer; read-only */
+       int nonblock;                   /**< non-block mode; read-only */
+
+       snd_pcm_access_t access;        /**< access type; filled after hw_params is called */
+       snd_pcm_format_t format;        /**< PCM format; filled after hw_params is called */
+       unsigned int channels;          /**< number of channels; filled after hw_params is called */
+       unsigned int rate;              /**< rate; filled after hw_params is called */
+       snd_pcm_uframes_t period_size;  /**< period size; filled after hw_params is called */
+       snd_pcm_uframes_t buffer_size;  /**< buffer size; filled after hw_params is called */
 };
 
-/** callback table of ioplug */
+/** Callback table of ioplug */
 struct snd_pcm_ioplug_callback {
        /**
         * start the PCM; required
@@ -183,4 +204,6 @@ void snd_pcm_ioplug_params_reset(snd_pcm_ioplug_t *io);
 int snd_pcm_ioplug_set_param_minmax(snd_pcm_ioplug_t *io, int type, unsigned int min, unsigned int max);
 int snd_pcm_ioplug_set_param_list(snd_pcm_ioplug_t *io, int type, unsigned int num_list, const unsigned int *list);
 
+/** \} */
+
 #endif /* __ALSA_PCM_IOPLUG_H */
index e51800b04e311870145540890c15841939116482..36d4d2481b3b9336fafb21876769da53c094f454 100644 (file)
@@ -433,7 +433,96 @@ static snd_pcm_ops_t snd_pcm_extplug_ops = {
  * Exported functions
  */
 
-/*! \page pcm_external_plugins
+/*! \page pcm_external_plugins PCM External Plugin SDK
+
+\section pcm_externals External Plugins
+
+The external plugins are implemented in a shared object file located
+at /usr/lib/alsa-lib (the exact location depends on the build option
+and asoundrc configuration).  It has to be the file like
+libasound_module_pcm_MYPLUGIN.so, where MYPLUGIN corresponds to your
+own plugin name.
+
+The entry point of the plugin is defined via
+#SND_PCM_PLUGIN_DEFINE_FUNC() macro.  This macro defines the function
+with a proper name to be referred from alsa-lib.  The function takes
+the following 6 arguments:
+\code
+int (snd_pcm_t **pcmp, const char *name, snd_config_t *root,
+       snd_config_t *conf, snd_pcm_stream_t stream, int mode)
+\endcode
+The first argument, pcmp, is the pointer to store the resultant PCM
+handle.  The arguments name, root, stream and mode are the parameters
+to be passed to the plugin constructor.  The conf is the configuration
+tree for the plugin.  The arguments above are defined in the macro
+itself, so don't use variables with the same names to shadow
+parameters.
+
+After parsing the configuration parameters in the given conf tree,
+usually you will call the external plugin API function,
+#snd_pcm_extplug_create() or #snd_pcm_ioplug_create(), depending
+on the plugin type.  The PCM handle must be filled *pcmp in return.
+Then this function must return either a value 0 when succeeded, or a
+negative value as the error code. 
+
+Finally, add #SND_PCM_PLUGIN_SYMBOL() with the name of your
+plugin as the argument at the end.  This defines the proper versioned
+symbol as the reference.
+
+The typical code would look like below:
+\code
+struct myplug_info {
+       snd_pcm_extplug_t ext;
+       int my_own_data;
+       ...
+};
+
+SND_PCM_PLUGIN_DEFINE_FUNC(myplug)
+{
+       snd_config_iterator_t i, next;
+       struct myplug_info *myplug;
+       int err;
+
+       snd_config_for_each(i, next, conf) {
+               snd_config_t *n = snd_config_iterator_entry(i);
+               const char *id;
+               if (snd_config_get_id(n, &id) < 0)
+                       continue;
+               if (strcmp(id, "comment") == 0 || strcmp(id, "type") == 0)
+                       continue;
+               if (strcmp(id, "my_own_parameter") == 0) {
+                       ....
+                       continue;
+               }
+               SNDERR("Unknown field %s", id);
+               return -EINVAL;
+       }
+
+       myplug = calloc(1, sizeof(*myplug));
+       if (myplug == NULL)
+               return -ENOMEM;
+
+       myplug->ext.version = SND_PCM_EXTPLUG_VERSION;
+       myplug->ext.name = "My Own Plugin";
+       myplug->ext.callback = &my_own_callback;
+       myplug->ext.private_data = myplug;
+       ....
+
+       err = snd_pcm_extplug_create(&myplug->ext, name, stream, mode);
+       if (err < 0) {
+               myplug_free(myplug);
+               return err;
+       }
+
+       *pcmp = myplug->ext.pcm;
+       return 0;
+}
+
+SND_PCM_PLUGIN_SYMBOL(myplug);
+\endcode
+
+Read the codes in alsa-plugins package for the real examples.
+
 
 \section pcm_extplug External Plugin: Filter-Type Plugin
 
@@ -443,6 +532,54 @@ and feeds to the output.  Thus, this plugin always needs a slave PCM as its outp
 The plugin can modify the format and the channels of the input/output PCM.
 It can <i>not</i> modify the sample rate (because of simplicity reason).
 
+The following fields have to be filled in extplug record before calling
+#snd_pcm_extplug_create() : version, name, callback.
+Otherfields are optional and should be initialized with zero.
+
+The constant #SND_PCM_EXTPLUG_VERSION must be passed to the version
+field for the version check in alsa-lib.  A non-NULL ASCII string
+has to be passed to the name field.  The callback field contains the 
+table of callback functions for this plugin (defined as
+#snd_pcm_extplug_callback_t).
+
+The driver can set an arbitrary value (pointer) to private_data
+field to refer its own data in the callbacks.
+
+The rest fields are filled by #snd_pcm_extplug_create().  The pcm field
+is the resultant PCM handle.  The others are the current status of the
+PCM.
+
+The callback functions in #snd_pcm_extplug_callback_t define the real
+behavior of the driver.
+At least, transfer callback must be given.  This callback is called
+at each time certain size of data block is transfered to the slave
+PCM.  Other callbacks are optional.  
+
+The close callback is called when the PCM is closed.  If the plugin
+allocates private resources, this is the place to release them
+again.  The hw_params and hw_free callbacks are called at
+#snd_pcm_hw_params() and #snd_pcm_hw_free() API calls,
+respectively.  The last, dump callback, is called for printing the
+information of the given plugin.
+
+The hw_params constraints can be defined via either
+#snd_pcm_extplug_set_param_minmax() and #snd_pcm_extplug_set_param_list()
+functions after calling #snd_pcm_extplug_create().
+The former defines the minimal and maximal acceptable values for the
+given hw_params parameter (SND_PCM_EXTPLUG_HW_XXX).
+This function can't be used for the format parameter.  The latter
+function specifies the available parameter values as the list.
+As mentioned above, the rate can't be changed.  Only changeable
+parameters are sample format and channels.
+
+To define the constraints of the slave PCM configuration, use
+either #snd_pcm_extplug_set_slave_param_minmax() and
+#snd_pcm_extplug_set_slave_param_list().  The arguments are as same
+as former functions.
+
+To clear the parameter constraints, call #snd_pcm_extplug_params_reset()
+function. 
+
 */
 
 /**
@@ -460,8 +597,8 @@ It can <i>not</i> modify the sample rate (because of simplicity reason).
  * PCM plugin as "slave" config value.
  * name, root, stream and mode arguments are the values used for opening the PCM.
  *
- * The callback is the mandatory field of extplug handle.  At least, transfer callback
- * must be set before calling this function.
+ * The callback is the mandatory field of extplug handle.  At least, start, stop and
+ * pointer callbacks must be set before calling this function.
  */
 int snd_pcm_extplug_create(snd_pcm_extplug_t *extplug, const char *name,
                           snd_config_t *root, snd_config_t *slave_conf,
@@ -505,7 +642,7 @@ int snd_pcm_extplug_create(snd_pcm_extplug_t *extplug, const char *name,
        ext->plug.gen.slave = spcm;
        ext->plug.gen.close_slave = 1;
 
-       err = snd_pcm_new(&pcm, SND_PCM_TYPE_IOPLUG, name, stream, mode);
+       err = snd_pcm_new(&pcm, SND_PCM_TYPE_EXTPLUG, name, stream, mode);
        if (err < 0) {
                free(ext);
                return err;
index 2dc97d24a479e6bed2d246f632b2031249e1a1c2..6b9da1112c3acf86d88ba5479b41ad861ad6eedd 100644 (file)
@@ -757,13 +757,93 @@ static snd_pcm_fast_ops_t snd_pcm_ioplug_fast_ops = {
  * Exported functions
  */
 
-/*! \page pcm_external_plugins
+/*! \page pcm_external_plugins PCM External Plugin SDK
 
 \section pcm_ioplug External Plugin: I/O Plugin
 
 The I/O-type plugin is a PCM plugin to work as the input or output terminal point,
 i.e. as a user-space PCM driver.
 
+The new plugin is created via #snd_pcm_ioplug_create() function.
+The first argument is a pointer of the pluging information.  Some of
+this struct must be initialized in prior to call
+#snd_pcm_ioplug_create().  Then the function fills other fields in
+return.  The rest arguments, name, stream and mode, are usually
+identical with the values passed from the ALSA plugin constructor.
+
+The following fields are mandatory: version, name, callback.
+Otherfields are optional and should be initialized with zero.
+
+The constant #SND_PCM_IOPLUG_VERSION must be passed to the version
+field for the version check in alsa-lib.  A non-NULL ASCII string
+has to be passed to the name field.  The callback field contains the 
+table of callback functions for this plugin (defined as
+#snd_pcm_ioplug_callback_t).
+
+flags field specifies the optional bit-flags.  poll_fd and poll_events
+specify the poll file descriptor and the corresponding poll events
+(POLLIN, POLLOUT) for the plugin.  If the plugin requires multiple
+poll descriptors or poll descriptor(s) dynamically varying, set
+poll_descriptors and poll_descriptors_count callbacks to the callback
+table.  Then the poll_fd and poll_events field are ignored.
+
+mmap_rw specifies whether the plugin behaves in the pseudo mmap mode.
+When this value is set to 1, the plugin creates always a local buffer
+and performs read/write calls using this buffer as if it's mmapped.
+The address of local buffer can be obtained via
+#snd_pcm_ioplug_mmap_areas() function.
+When poll_fd, poll_events and mmap_rw fields are changed after
+#snd_pcm_ioplug_create(), call #snd_pcm_ioplug_reinit_status() to
+reflect the changes.
+
+The driver can set an arbitrary value (pointer) to private_data
+field to refer its own data in the callbacks.
+
+The rest fields are filled by #snd_pcm_ioplug_create().  The pcm field
+is the resultant PCM handle.  The others are the current status of the
+PCM.
+
+The callback functions in #snd_pcm_ioplug_callback_t define the real
+behavior of the driver.
+At least, start, stop and pointer callbacks must be given.  Other
+callbacks are optional.  The start and stop callbacks are called when
+the PCM stream is started and stopped, repsectively.  The pointer
+callback returns the current DMA position, which may be called at any
+time.
+
+The transfer callback is called when any data transfer happens.  It
+receives the area array, offset and the size to transfer.  The area
+array contains the array of snd_pcm_channel_area_t with the elements
+of number of channels.
+
+When the PCM is closed, close callback is called.  If the driver
+allocates any internal buffers, they should be released in this
+callback.  The hw_params and hw_free callbacks are called when
+hw_params are set and reset, respectively.  Note that they may be
+called multiple times according to the application.  Similarly,
+sw_params callback is called when sw_params is set or changed.
+
+The prepare, drain, pause and resume callbacks are called when
+#snd_pcm_prepare(), #snd_pcm_drain(), #snd_pcm_pause(), and
+#snd_pcm_resume() are called.  The poll_descriptors_count and
+poll_descriptors callbacks are used to return the multiple or dynamic
+poll descriptors as mentioned above.  The poll_revents callback is
+used to modify poll events.  If the driver needs to mangle the native
+poll events to proper poll events for PCM, you can do it in this
+callback.
+
+Finally, the dump callback is used to print the status of the plugin.
+
+The hw_params constraints can be defined via either
+#snd_pcm_iplug_set_param_minmax() and #snd_pcm_ioplug_set_param_list()
+functions after calling #snd_pcm_ioplug_create().
+The former defines the minimal and maximal acceptable values for the
+given hw_params parameter (SND_PCM_IOPLUG_HW_XXX).
+This function can't be used for the format parameter.  The latter
+function specifies the available parameter values as the list.
+
+To clear the parameter constraints, call #snd_pcm_ioplug_params_reset() function.
+
 */
 
 /**