Fix documentation of external PCM plugin SDK

Fix documentation of external PCM plugin SDK.
This commit is contained in:
Takashi Iwai 2005-05-24 09:42:01 +00:00
parent 8b76989e19
commit 7651690858
6 changed files with 312 additions and 31 deletions

View 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 \

View 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, \

View 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)
*
@ -22,6 +31,13 @@
#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 */

View 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>
*
@ -22,6 +31,13 @@
#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_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_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 */

View 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;

View 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.
*/
/**