Added initial comments for PCM plugins

This commit is contained in:
Jaroslav Kysela 2002-01-16 16:42:40 +00:00
parent 6ead410b11
commit a24b602f28
11 changed files with 796 additions and 28 deletions

View file

@ -42,8 +42,16 @@ INPUT = index.doxygen \
../src/pcm/pcm_linear.c \
../src/pcm/pcm_lfloat.c \
../src/pcm/pcm_mulaw.c \
../src/pcm/pcm_alaw.c \
../src/pcm/pcm_adpcm.c \
../src/pcm/pcm_route.c \
../src/pcm/pcm_plug.c \
../src/pcm/pcm_file.c \
../src/pcm/pcm_multi.c \
../src/pcm/pcm_share.c \
../src/pcm/pcm_hooks.c \
../src/pcm/pcm_meter.c \
../src/pcm/pcm_ladspa.c \
../src/pcm/pcm_misc.c \
../src/rawmidi \
../src/timer \

View file

@ -1,5 +1,14 @@
/**
* \file pcm/pcm_adpcm.c
* \ingroup PCM_Plugins
* \brief PCM Ima-ADPCM Conversion Plugin Interface
* \author Abramo Bagnara <abramo@alsa-project.org>
* \author Uros Bizjak <uros@kss-loka.si>
* \author Jaroslav Kysela <perex@suse.cz>
* \date 2000-2001
*/
/*
* PCM - Ima-ADPC conversion
* PCM - Ima-ADPCM conversion
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
* Copyright (c) 1999 by Uros Bizjak <uros@kss-loka.si>
* Jaroslav Kysela <perex@suse.cz>
@ -56,6 +65,8 @@ IMA compatability project proceedings, Vol 2, Issue 2, May 1992.
const char *_snd_module_pcm_adpcm = "";
#endif
#ifndef DOC_HIDDEN
typedef void (*adpcm_f)(const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset,
const snd_pcm_channel_area_t *src_areas,
@ -73,6 +84,8 @@ typedef struct {
snd_pcm_adpcm_state_t *states;
} snd_pcm_adpcm_t;
#endif
/* First table lookup for Ima-ADPCM quantizer */
static char IndexAdjust[8] = { -1, -1, -1, -1, 2, 4, 6, 8 };
@ -196,6 +209,8 @@ static int adpcm_decoder(unsigned char code, snd_pcm_adpcm_state_t * state)
return (state->pred_val);
}
#ifndef DOC_HIDDEN
void snd_pcm_adpcm_decode(const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset,
const snd_pcm_channel_area_t *src_areas,
@ -302,6 +317,8 @@ void snd_pcm_adpcm_encode(const snd_pcm_channel_area_t *dst_areas,
}
}
#endif
static int snd_pcm_adpcm_hw_refine_cprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
snd_pcm_adpcm_t *adpcm = pcm->private_data;
@ -495,7 +512,7 @@ static void snd_pcm_adpcm_dump(snd_pcm_t *pcm, snd_output_t *out)
snd_pcm_dump(adpcm->plug.slave, out);
}
snd_pcm_ops_t snd_pcm_adpcm_ops = {
static snd_pcm_ops_t snd_pcm_adpcm_ops = {
close: snd_pcm_plugin_close,
info: snd_pcm_plugin_info,
hw_refine: snd_pcm_adpcm_hw_refine,
@ -510,6 +527,18 @@ snd_pcm_ops_t snd_pcm_adpcm_ops = {
munmap: snd_pcm_plugin_munmap,
};
/**
* \brief Creates a new Ima-ADPCM conversion PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param sformat Slave (destination) format
* \param slave Slave PCM handle
* \param close_slave When set, the slave PCM handle is closed with copy PCM
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave)
{
snd_pcm_t *pcm;
@ -546,6 +575,49 @@ int snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sfor
return 0;
}
/*! \page pcm_plugins
\section pcm_plugins_adpcm Plugin: Ima-ADPCM
This plugin converts Ima-ADPCM samples to linear or linear to Mu-Law samples
from master Ima-ADPCM conversion PCM to given slave PCM. The channel count,
format and rate must match for both of them.
\code
pcm.name {
type adpcm # Ima-ADPCM conversion PCM
slave STR # Slave name
# or
slave { # Slave definition
pcm STR # Slave PCM name
# or
pcm { } # Slave PCM definition
}
}
\endcode
\subsection pcm_plugins_adpcm_funcref Function reference
<UL>
<LI>snd_pcm_adpcm_open()
<LI>_snd_pcm_adpcm_open()
</UL>
*/
/**
* \brief Creates a new Ima-ADPCM conversion PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param root Root configuration node
* \param conf Configuration node with copy PCM description
* \param stream Stream type
* \param mode Stream mode
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
@ -592,4 +664,6 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_close(spcm);
return err;
}
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_adpcm_open, SND_PCM_DLSYM_VERSION);
#endif

View file

@ -1,3 +1,10 @@
/**
* \file pcm/pcm_alaw.c
* \ingroup PCM_Plugins
* \brief PCM A-Law Conversion Plugin Interface
* \author Abramo Bagnara <abramo@alsa-project.org>
* \date 2000-2001
*/
/*
* PCM - A-Law conversion
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
@ -28,6 +35,8 @@
const char *_snd_module_pcm_alaw = "";
#endif
#ifndef DOC_HIDDEN
typedef void (*alaw_f)(const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset,
const snd_pcm_channel_area_t *src_areas,
@ -43,6 +52,8 @@ typedef struct {
snd_pcm_format_t sformat;
} snd_pcm_alaw_t;
#endif
static inline int val_seg(int val)
{
int r = 1;
@ -126,6 +137,8 @@ static int alaw_to_s16(unsigned char a_val)
return ((a_val & 0x80) ? t : -t);
}
#ifndef DOC_HIDDEN
void snd_pcm_alaw_decode(const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset,
const snd_pcm_channel_area_t *src_areas,
@ -201,6 +214,8 @@ void snd_pcm_alaw_encode(const snd_pcm_channel_area_t *dst_areas,
}
}
#endif /* DOC_HIDDEN */
static int snd_pcm_alaw_hw_refine_cprepare(snd_pcm_t *pcm, snd_pcm_hw_params_t *params)
{
snd_pcm_alaw_t *alaw = pcm->private_data;
@ -369,7 +384,7 @@ static void snd_pcm_alaw_dump(snd_pcm_t *pcm, snd_output_t *out)
snd_pcm_dump(alaw->plug.slave, out);
}
snd_pcm_ops_t snd_pcm_alaw_ops = {
static snd_pcm_ops_t snd_pcm_alaw_ops = {
close: snd_pcm_plugin_close,
info: snd_pcm_plugin_info,
hw_refine: snd_pcm_alaw_hw_refine,
@ -384,6 +399,18 @@ snd_pcm_ops_t snd_pcm_alaw_ops = {
munmap: snd_pcm_plugin_munmap,
};
/**
* \brief Creates a new A-Law conversion PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param sformat Slave (destination) format
* \param slave Slave PCM handle
* \param close_slave When set, the slave PCM handle is closed with copy PCM
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sformat, snd_pcm_t *slave, int close_slave)
{
snd_pcm_t *pcm;
@ -419,6 +446,49 @@ int snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name, snd_pcm_format_t sform
return 0;
}
/*! \page pcm_plugins
\section pcm_plugins_alaw Plugin: A-Law
This plugin converts A-Law samples to linear or linear to A-Law samples
from master A-Law conversion PCM to given slave PCM. The channel count,
format and rate must match for both of them.
\code
pcm.name {
type alaw # A-Law conversion PCM
slave STR # Slave name
# or
slave { # Slave definition
pcm STR # Slave PCM name
# or
pcm { } # Slave PCM definition
}
}
\endcode
\subsection pcm_plugins_alaw_funcref Function reference
<UL>
<LI>snd_pcm_alaw_open()
<LI>_snd_pcm_alaw_open()
</UL>
*/
/**
* \brief Creates a new A-Law conversion PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param root Root configuration node
* \param conf Configuration node with copy PCM description
* \param stream Stream type
* \param mode Stream mode
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
@ -465,4 +535,6 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_close(spcm);
return err;
}
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_alaw_open, SND_PCM_DLSYM_VERSION);
#endif

View file

@ -1,3 +1,10 @@
/**
* \file pcm/pcm_file.c
* \ingroup PCM_Plugins
* \brief PCM File Plugin Interface
* \author Abramo Bagnara <abramo@alsa-project.org>
* \date 2000-2001
*/
/*
* PCM - File plugin
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
@ -28,6 +35,8 @@
const char *_snd_module_pcm_file = "";
#endif
#ifndef DOC_HIDDEN
typedef enum _snd_pcm_file_format {
SND_PCM_FILE_FORMAT_RAW
} snd_pcm_file_format_t;
@ -48,6 +57,8 @@ typedef struct {
size_t buffer_bytes;
} snd_pcm_file_t;
#endif /* DOC_HIDDEN */
static void snd_pcm_file_write_bytes(snd_pcm_t *pcm, size_t bytes)
{
snd_pcm_file_t *file = pcm->private_data;
@ -373,7 +384,7 @@ static void snd_pcm_file_dump(snd_pcm_t *pcm, snd_output_t *out)
snd_pcm_dump(file->slave, out);
}
snd_pcm_ops_t snd_pcm_file_ops = {
static snd_pcm_ops_t snd_pcm_file_ops = {
close: snd_pcm_file_close,
info: snd_pcm_file_info,
hw_refine: snd_pcm_file_hw_refine,
@ -388,7 +399,7 @@ snd_pcm_ops_t snd_pcm_file_ops = {
munmap: snd_pcm_file_munmap,
};
snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
static snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
status: snd_pcm_file_status,
state: snd_pcm_file_state,
delay: snd_pcm_file_delay,
@ -408,7 +419,23 @@ snd_pcm_fast_ops_t snd_pcm_file_fast_ops = {
mmap_commit: snd_pcm_file_mmap_commit,
};
int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name, const char *fname, int fd, const char *fmt, snd_pcm_t *slave, int close_slave)
/**
* \brief Creates a new File PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param fname Filename (or NULL if file descriptor is available)
* \param fd File descriptor
* \param fmt File format ("raw" is supported only)
* \param slave Slave PCM handle
* \param close_slave When set, the slave PCM handle is closed with copy PCM
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
const char *fname, int fd, const char *fmt,
snd_pcm_t *slave, int close_slave)
{
snd_pcm_t *pcm;
snd_pcm_file_t *file;
@ -461,6 +488,51 @@ int snd_pcm_file_open(snd_pcm_t **pcmp, const char *name, const char *fname, int
return 0;
}
/*! \page pcm_plugins
\section pcm_plugins_file Plugin: File
This plugin stores contents of a PCM stream to file.
\code
pcm.name {
type file # File PCM
slave STR # Slave name
# or
slave { # Slave definition
pcm STR # Slave PCM name
# or
pcm { } # Slave PCM definition
}
file STR # Filename
or
file INT # File descriptor number
[format STR] # File format (only "raw" at the moment)
}
\endcode
\subsection pcm_plugins_file_funcref Function reference
<UL>
<LI>snd_pcm_file_open()
<LI>_snd_pcm_file_open()
</UL>
*/
/**
* \brief Creates a new File PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param root Root configuration node
* \param conf Configuration node with File PCM description
* \param stream Stream type
* \param mode Stream mode
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
@ -526,4 +598,6 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_close(spcm);
return err;
}
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_file_open, SND_PCM_DLSYM_VERSION);
#endif

View file

@ -1,3 +1,10 @@
/**
* \file pcm/pcm_ladspa.c
* \ingroup PCM_Plugins
* \brief ALSA Plugin <-> LADSPA Plugin Interface
* \author Jaroslav Kysela <perex@suse.cz>
* \date 2001
*/
/*
* PCM - LADSPA integration plugin
* Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
@ -32,6 +39,8 @@
const char *_snd_module_pcm_ladspa = "";
#endif
#ifndef DOC_HIDDEN
#define NO_ASSIGN 0xffffffff
typedef enum _snd_pcm_ladspa_policy {
@ -89,6 +98,8 @@ typedef struct {
struct list_head instances;
} snd_pcm_ladspa_plugin_t;
#endif /* DOC_HIDDEN */
static int snd_pcm_ladspa_find_port(unsigned int *res,
snd_pcm_ladspa_plugin_t *lplug,
LADSPA_PortDescriptor pdesc,
@ -684,7 +695,7 @@ static void snd_pcm_ladspa_dump(snd_pcm_t *pcm, snd_output_t *out)
snd_pcm_dump(ladspa->plug.slave, out);
}
snd_pcm_ops_t snd_pcm_ladspa_ops = {
static snd_pcm_ops_t snd_pcm_ladspa_ops = {
close: snd_pcm_ladspa_close,
info: snd_pcm_plugin_info,
hw_refine: snd_pcm_ladspa_hw_refine,
@ -1095,6 +1106,18 @@ static int snd_pcm_ladspa_build_plugins(struct list_head *list,
return 0;
}
/**
* \brief Creates a new LADSPA<->ALSA Plugin
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param sformat Slave (destination) format
* \param slave Slave PCM handle
* \param close_slave When set, the slave PCM handle is closed with copy PCM
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
const char *ladspa_path,
snd_config_t *ladspa_pplugins,
@ -1154,6 +1177,70 @@ int snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
return 0;
}
/*! \page pcm_plugins
\section pcm_plugins_ladpsa Plugin: LADSPA <-> ALSA
This plugin allows to apply a set of LADPSA plugins.
The input and output format is always #SND_PCM_FORMAT_FLOAT (note: this type
can be either little or big-endian depending on architecture).
\code
pcm.name {
type ladspa # ALSA<->LADSPA PCM
slave STR # Slave name
# or
slave { # Slave definition
pcm STR # Slave PCM name
# or
pcm { } # Slave PCM definition
}
path STR # Path (directory) with LADSPA plugins
plugins | # Definition for both directions
playback_plugins | # Definition for playback direction
capture_plugins { # Definition for capture direction
N { # Configuration for LADPSA plugin N
id INT # LADSPA plugin ID (for example 1043)
label STR # LADSPA plugin label (for example 'delay_5s')
filename STR # Full filename of .so library with LADSPA plugin code
policy STR # Policy can be 'none' or 'duplicate'
input | output {
bindings {
C INT or STR # C - channel, INT - audio port index, STR - audio port name
}
controls {
I INT or REAL # I - control port index, INT or REAL - control value
# or
STR INT or REAL # STR - control port name, INT or REAL - control value
}
}
}
}
}
\endcode
\subsection pcm_plugins_ladspa_funcref Function reference
<UL>
<LI>snd_pcm_ladspa_open()
<LI>_snd_pcm_ladspa_open()
</UL>
*/
/**
* \brief Creates a new LADSPA<->ALSA PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param root Root configuration node
* \param conf Configuration node with LADSPA<->ALSA PCM description
* \param stream Stream type
* \param mode Stream mode
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int _snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
@ -1218,4 +1305,6 @@ int _snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_close(spcm);
return err;
}
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_ladspa_open, SND_PCM_DLSYM_VERSION);
#endif

View file

@ -575,7 +575,7 @@ static void snd_pcm_meter_dump(snd_pcm_t *pcm, snd_output_t *out)
snd_pcm_dump(meter->slave, out);
}
snd_pcm_ops_t snd_pcm_meter_ops = {
static snd_pcm_ops_t snd_pcm_meter_ops = {
close: snd_pcm_meter_close,
info: snd_pcm_meter_info,
hw_refine: snd_pcm_meter_hw_refine,
@ -590,7 +590,7 @@ snd_pcm_ops_t snd_pcm_meter_ops = {
munmap: snd_pcm_meter_munmap,
};
snd_pcm_fast_ops_t snd_pcm_meter_fast_ops = {
static snd_pcm_fast_ops_t snd_pcm_meter_fast_ops = {
status: snd_pcm_meter_status,
state: snd_pcm_meter_state,
delay: snd_pcm_meter_delay,
@ -610,6 +610,18 @@ snd_pcm_fast_ops_t snd_pcm_meter_fast_ops = {
mmap_commit: snd_pcm_meter_mmap_commit,
};
/**
* \brief Creates a new Meter PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param frequency Update frequency
* \param slave Slave PCM handle
* \param close_slave When set, the slave PCM handle is closed with copy PCM
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name, unsigned int frequency,
snd_pcm_t *slave, int close_slave)
{
@ -730,6 +742,63 @@ static int snd_pcm_meter_add_scope_conf(snd_pcm_t *pcm, const char *name,
return err >= 0 ? open_func(pcm, name, root, conf) : err;
}
/*! \page pcm_plugins
\section pcm_plugins_meter Plugin: Meter
Show meter (visual waveform representation).
\code
pcm_scope_type.NAME {
[lib STR] # Library file (default libasound.so)
[open STR] # Open function (default _snd_pcm_scope_NAME_open)
}
pcm_scope.name {
type STR # Scope type
...
}
pcm.name {
type meter # Meter PCM
slave STR # Slave name
# or
slave { # Slave definition
pcm STR # Slave PCM name
# or
pcm { } # Slave PCM definition
}
[frequency INT] # Updates per second
scopes {
ID STR # Scope name (see pcm_scope)
# or
ID { } # Scope definition (see pcm_scope)
}
}
\endcode
\subsection pcm_plugins_meter_funcref Function reference
<UL>
<LI>snd_pcm_meter_open()
<LI>_snd_pcm_meter_open()
</UL>
*/
/**
* \brief Creates a new Meter PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param root Root configuration node
* \param conf Configuration node with Meter PCM description
* \param stream Stream type
* \param mode Stream mode
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)

View file

@ -1,3 +1,10 @@
/**
* \file pcm/pcm_multi.c
* \ingroup PCM_Plugins
* \brief PCM Multi Streams to One Conversion Plugin Interface
* \author Abramo Bagnara <abramo@alsa-project.org>
* \date 2000-2001
*/
/*
* PCM - Multi
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
@ -31,6 +38,8 @@
const char *_snd_module_pcm_multi = "";
#endif
#ifndef DOC_HIDDEN
typedef struct {
snd_pcm_t *pcm;
unsigned int channels_count;
@ -51,6 +60,8 @@ typedef struct {
snd_pcm_multi_channel_t *channels;
} snd_pcm_multi_t;
#endif
static int snd_pcm_multi_close(snd_pcm_t *pcm)
{
snd_pcm_multi_t *multi = pcm->private_data;
@ -557,7 +568,7 @@ static void snd_pcm_multi_dump(snd_pcm_t *pcm, snd_output_t *out)
}
}
snd_pcm_ops_t snd_pcm_multi_ops = {
static snd_pcm_ops_t snd_pcm_multi_ops = {
close: snd_pcm_multi_close,
info: snd_pcm_multi_info,
hw_refine: snd_pcm_multi_hw_refine,
@ -572,7 +583,7 @@ snd_pcm_ops_t snd_pcm_multi_ops = {
munmap: snd_pcm_multi_munmap,
};
snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = {
static snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = {
status: snd_pcm_multi_status,
state: snd_pcm_multi_state,
delay: snd_pcm_multi_delay,
@ -592,6 +603,23 @@ snd_pcm_fast_ops_t snd_pcm_multi_fast_ops = {
mmap_commit: snd_pcm_multi_mmap_commit,
};
/**
* \brief Creates a new Multi PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param slaves_count Count of slaves
* \param master_slave Master slave number
* \param slaves_pcm Array with slave PCMs
* \param schannels_count Array with slave channel counts
* \param channels_count Count of channels
* \param sidxs Array with channels indexes to slaves
* \param schannels Array with slave channels
* \param close_slaves When set, the slave PCM handle is closed
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
unsigned int slaves_count, unsigned int master_slave,
snd_pcm_t **slaves_pcm, unsigned int *schannels_count,
@ -660,6 +688,57 @@ int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
return 0;
}
/*! \page pcm_plugins
\section pcm_plugins_multi Plugin: Multiple streams to One
This plugin converts multiple streams to one.
\code
pcm.name {
type multi # Multiple streams conversion PCM
slaves { # Slaves definition
ID STR # Slave PCM name
# or
ID {
pcm STR # Slave PCM name
# or
pcm { } # Slave PCM definition
channels INT # Slave channels
}
}
bindings { # Bindings table
N {
slave STR # Slave key
channel INT # Slave channel
}
}
[master INT] # Define the master slave
}
\endcode
\subsection pcm_plugins_multi_funcref Function reference
<UL>
<LI>snd_pcm_multi_open()
<LI>_snd_pcm_multi_open()
</UL>
*/
/**
* \brief Creates a new Multi PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param root Root configuration node
* \param conf Configuration node with Multi PCM description
* \param stream Stream type
* \param mode Stream mode
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
@ -874,4 +953,6 @@ _free:
free(channels_schannel);
return err;
}
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_multi_open, SND_PCM_DLSYM_VERSION);
#endif

View file

@ -1,3 +1,10 @@
/*
* \file pcm/pcm_plug.c
* \ingroup PCM_Plugins
* \brief PCM Route & Volume Plugin Interface
* \author Abramo Bagnara <abramo@alsa-project.org>
* \date 2000-2001
*/
/*
* PCM - Plug
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
@ -27,6 +34,8 @@
const char *_snd_module_pcm_plug = "";
#endif
#ifndef DOC_HIDDEN
enum snd_pcm_plug_route_policy {
PLUG_ROUTE_POLICY_NONE,
PLUG_ROUTE_POLICY_DEFAULT,
@ -48,6 +57,8 @@ typedef struct {
unsigned int tt_ssize, tt_cused, tt_sused;
} snd_pcm_plug_t;
#endif
static int snd_pcm_plug_close(snd_pcm_t *pcm)
{
snd_pcm_plug_t *plug = pcm->private_data;
@ -864,7 +875,7 @@ static void snd_pcm_plug_dump(snd_pcm_t *pcm, snd_output_t *out)
snd_pcm_dump(plug->slave, out);
}
snd_pcm_ops_t snd_pcm_plug_ops = {
static snd_pcm_ops_t snd_pcm_plug_ops = {
close: snd_pcm_plug_close,
info: snd_pcm_plug_info,
hw_refine: snd_pcm_plug_hw_refine,
@ -879,6 +890,18 @@ snd_pcm_ops_t snd_pcm_plug_ops = {
munmap: snd_pcm_plug_munmap,
};
/**
* \brief Creates a new Plug PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param sformat Slave (destination) format
* \param slave Slave PCM handle
* \param close_slave When set, the slave PCM handle is closed with copy PCM
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int snd_pcm_plug_open(snd_pcm_t **pcmp,
const char *name,
snd_pcm_format_t sformat, int schannels, int srate,
@ -923,8 +946,61 @@ int snd_pcm_plug_open(snd_pcm_t **pcmp,
return 0;
}
#define MAX_CHANNELS 64
/*! \page pcm_plugins
\section pcm_plugins_plug Automatic conversion plugin
This plugin converts channels, rate and format on request.
\code
pcm.name {
type plug # Automatic conversion PCM
slave STR # Slave name
# or
slave { # Slave definition
pcm STR # Slave PCM name
# or
pcm { } # Slave PCM definition
[format STR] # Slave format (default nearest) or "unchanged"
[channels INT] # Slave channels (default nearest) or "unchanged"
[rate INT] # Slave rate (default nearest) or "unchanged"
}
route_policy STR # route policy for automatic ttable generation
# STR can be 'default', 'average', 'copy', 'duplicate'
# average: result is average of input channels
# copy: only first channels are copied to destination
# duplicate: duplicate first set of channels
# default: copy policy, except for mono capture - sum
ttable { # Transfer table (bidimensional compound of cchannels * schannels numbers)
CCHANNEL {
SCHANNEL REAL # route value (0.0 - 1.0)
}
}
}
\endcode
\subsection pcm_plugins_plug_funcref Function reference
<UL>
<LI>snd_pcm_plug_open()
<LI>_snd_pcm_plug_open()
</UL>
*/
/**
* \brief Creates a new Plug PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param root Root configuration node
* \param conf Configuration node with Plug PCM description
* \param stream Stream type
* \param mode Stream mode
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
@ -991,9 +1067,17 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
if (err < 0)
return err;
if (tt) {
ttable = malloc(MAX_CHANNELS * MAX_CHANNELS * sizeof(*ttable));
err = snd_pcm_route_load_ttable(tt, ttable, MAX_CHANNELS, MAX_CHANNELS,
&cused, &sused, -1);
err = snd_pcm_route_determine_ttable(tt, &csize, &ssize);
if (err < 0) {
snd_config_delete(sconf);
return err;
}
ttable = malloc(csize * ssize * sizeof(*ttable));
if (ttable == NULL) {
snd_config_delete(sconf);
return err;
}
err = snd_pcm_route_load_ttable(tt, ttable, csize, ssize, &cused, &sused, -1);
if (err < 0) {
snd_config_delete(sconf);
return err;
@ -1010,4 +1094,6 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_close(spcm);
return err;
}
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_plug_open, SND_PCM_DLSYM_VERSION);
#endif

View file

@ -26,13 +26,61 @@
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
*
*/
/*!
* \page pcm_plugins PCM (digital audio) plugins
*
* PCM plugins extends functionality and features of PCM devices.
* The plugins take care about various sample conversions, sample
* copying among channels and so on.
*/
\page pcm_plugins PCM (digital audio) plugins
PCM plugins extends functionality and features of PCM devices.
The plugins take care about various sample conversions, sample
copying among channels and so on.
\section pcm_plugins_slave Slave definition
The slave plugin can be specified directly with a string or the definition
can be entered inside a compound configuration node. Some restrictions can
be also specified (like static rate or count of channels).
\code
pcm_slave.NAME {
pcm STR # PCM name
# or
pcm { } # PCM definition
format STR # Format or "unchanged"
channels INT # Count of channels or "unchanged" string
rate INT # Rate in Hz or "unchanged" string
period_time INT # Period time in us or "unchanged" string
buffer_time INT # Buffer time in us or "unchanged" string
}
\endcode
Example:
\code
pcm_slave.slave_rate44100Hz {
pcm "hw:0,0"
rate 44100
}
pcm.rate44100Hz {
type plug
slave slave_rate44100Hz
}
\endcode
The equivalent configuration (in one compound):
\code
pcm.rate44100Hz {
type plug
slave {
pcm "hw:0,0"
rate 44100
}
}
\endcode
*/
#include <sys/shm.h>
#include <limits.h>

View file

@ -1,5 +1,12 @@
/**
* \file pcm/pcm_route.c
* \ingroup PCM_Plugins
* \brief PCM Route & Volume Plugin Interface
* \author Abramo Bagnara <abramo@alsa-project.org>
* \date 2000-2001
*/
/*
* PCM - Linear conversion
* PCM - Route & Volume Plugin
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
*
*
@ -29,6 +36,8 @@
const char *_snd_module_pcm_route = "";
#endif
#ifndef DOC_HIDDEN
/* The best possible hack to support missing optimization in gcc 2.7.2.3 */
#if SND_PCM_PLUGIN_ROUTE_RESOLUTION & (SND_PCM_PLUGIN_ROUTE_RESOLUTION - 1) != 0
#define div(a) a /= SND_PCM_PLUGIN_ROUTE_RESOLUTION
@ -91,6 +100,7 @@ typedef struct {
snd_pcm_route_params_t params;
} snd_pcm_route_t;
#endif /* DOC_HIDDEN */
static void snd_pcm_route_convert1_zero(const snd_pcm_channel_area_t *dst_area,
snd_pcm_uframes_t dst_offset,
@ -103,6 +113,8 @@ static void snd_pcm_route_convert1_zero(const snd_pcm_channel_area_t *dst_area,
snd_pcm_area_silence(dst_area, dst_offset, frames, params->dst_sfmt);
}
#ifndef DOC_HIDDEN
static void snd_pcm_route_convert1_one(const snd_pcm_channel_area_t *dst_area,
snd_pcm_uframes_t dst_offset,
const snd_pcm_channel_area_t *src_areas,
@ -381,6 +393,8 @@ static void snd_pcm_route_convert1_many(const snd_pcm_channel_area_t *dst_area,
}
}
#endif /* DOC_HIDDEN */
static void snd_pcm_route_convert(const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset,
const snd_pcm_channel_area_t *src_areas,
@ -646,7 +660,7 @@ static void snd_pcm_route_dump(snd_pcm_t *pcm, snd_output_t *out)
snd_pcm_dump(route->plug.slave, out);
}
snd_pcm_ops_t snd_pcm_route_ops = {
static snd_pcm_ops_t snd_pcm_route_ops = {
close: snd_pcm_route_close,
info: snd_pcm_plugin_info,
hw_refine: snd_pcm_route_hw_refine,
@ -732,7 +746,23 @@ static int route_load_ttable(snd_pcm_route_params_t *params, snd_pcm_stream_t st
return 0;
}
/**
* \brief Creates a new Route & Volume PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param sformat Slave format
* \param schannels Slave channels
* \param ttable Attenuation table
* \param tt_ssize Attenuation table - slave size
* \param tt_cused Attenuation table - client used count
* \param tt_sused Attenuation table - slave used count
* \param slave Slave PCM handle
* \param close_slave When set, the slave PCM handle is closed with copy PCM
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_format_t sformat, int schannels,
snd_pcm_route_ttable_entry_t *ttable,
@ -779,6 +809,13 @@ int snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
return 0;
}
/**
* \brief Determine route matrix sizes
* \param tt Configuration root describing route matrix
* \param tt_csize Returned client size in elements
* \param tt_ssize Returned slave size in elements
* \retval zero on success otherwise a negative error code
*/
int snd_pcm_route_determine_ttable(snd_config_t *tt,
unsigned int *tt_csize,
unsigned int *tt_ssize)
@ -828,7 +865,17 @@ int snd_pcm_route_determine_ttable(snd_config_t *tt,
return 0;
}
/* this functions is used from pcm_plug.c */
/**
* \brief Load route matrix
* \param tt Configuration root describing route matrix
* \param ttable Returned route matrix
* \param tt_csize Client size in elements
* \param tt_ssize Slave size in elements
* \param tt_cused Used client elements
* \param tt_sused Used slave elements
* \param schannels Slave channels
* \retval zero on success otherwise a negative error code
*/
int snd_pcm_route_load_ttable(snd_config_t *tt, snd_pcm_route_ttable_entry_t *ttable,
unsigned int tt_csize, unsigned int tt_ssize,
unsigned int *tt_cused, unsigned int *tt_sused,
@ -892,6 +939,48 @@ int snd_pcm_route_load_ttable(snd_config_t *tt, snd_pcm_route_ttable_entry_t *tt
return 0;
}
/*! \page pcm_plugins
\section pcm_plugins_route Plugin: Route & Volume
This plugin converts channels and applies volume during the conversion.
The format and rate must match for both of them.
\code
pcm.name {
type route # Route & Volume conversion PCM
slave STR # Slave name
# or
slave { # Slave definition
pcm STR # Slave PCM name
# or
pcm { } # Slave PCM definition
}
}
\endcode
\subsection pcm_plugins_route_funcref Function reference
<UL>
<LI>snd_pcm_route_open()
<LI>_snd_pcm_route_open()
</UL>
*/
/**
* \brief Creates a new Route & Volume PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param root Root configuration node
* \param conf Configuration node with Route & Volume PCM description
* \param stream Stream type
* \param mode Stream mode
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
@ -981,4 +1070,6 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_close(spcm);
return err;
}
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_route_open, SND_PCM_DLSYM_VERSION);
#endif

View file

@ -1,3 +1,10 @@
/**
* \file pcm/pcm_share.c
* \ingroup PCM_Plugins
* \brief PCM Share Plugin Interface
* \author Abramo Bagnara <abramo@alsa-project.org>
* \date 2000-2001
*/
/*
* PCM - Share
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
@ -37,6 +44,8 @@
const char *_snd_module_pcm_share = "";
#endif
#ifndef DOC_HIDDEN
static LIST_HEAD(snd_pcm_share_slaves);
static pthread_mutex_t snd_pcm_share_slaves_mutex = PTHREAD_MUTEX_INITIALIZER;
@ -106,6 +115,8 @@ typedef struct {
int slave_socket;
} snd_pcm_share_t;
#endif /* DOC_HIDDEN */
static void _snd_pcm_share_stop(snd_pcm_t *pcm, snd_pcm_state_t state);
static snd_pcm_uframes_t snd_pcm_share_slave_avail(snd_pcm_share_slave_t *slave)
@ -1177,7 +1188,7 @@ static void snd_pcm_share_dump(snd_pcm_t *pcm, snd_output_t *out)
snd_pcm_dump(slave->pcm, out);
}
snd_pcm_ops_t snd_pcm_share_ops = {
static snd_pcm_ops_t snd_pcm_share_ops = {
close: snd_pcm_share_close,
info: snd_pcm_share_info,
hw_refine: snd_pcm_share_hw_refine,
@ -1192,7 +1203,7 @@ snd_pcm_ops_t snd_pcm_share_ops = {
munmap: snd_pcm_share_munmap,
};
snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
static snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
status: snd_pcm_share_status,
state: snd_pcm_share_state,
delay: snd_pcm_share_delay,
@ -1212,6 +1223,25 @@ snd_pcm_fast_ops_t snd_pcm_share_fast_ops = {
mmap_commit: snd_pcm_share_mmap_commit,
};
/**
* \brief Creates a new Share PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param sname Slave name
* \param sformat Slave format
* \param srate Slave rate
* \param schannels Slave channels
* \param speriod_time Slave period time
* \param sbuffer_time Slave buffer time
* \param channels Count of channels
* \param channels_map Map of channels
* \param stream Direction
* \param mode PCM mode
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
snd_pcm_format_t sformat, int srate,
unsigned int schannels,
@ -1383,6 +1413,50 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
return 0;
}
/*! \page pcm_plugins
\section pcm_plugins_share Plugin: Share
This plugin allows sharing of multiple channels with more clients.
\code
pcm.name {
type share # Share PCM
slave STR # Slave name
# or
slave { # Slave definition
pcm STR # Slave PCM name
# or
pcm { } # Slave PCM definition
}
bindings {
N INT # Slave channel INT for client channel N
}
}
\endcode
\subsection pcm_plugins_share_funcref Function reference
<UL>
<LI>snd_pcm_share_open()
<LI>_snd_pcm_share_open()
</UL>
*/
/**
* \brief Creates a new Share PCM
* \param pcmp Returns created PCM handle
* \param name Name of PCM
* \param root Root configuration node
* \param conf Configuration node with Share PCM description
* \param stream Stream type
* \param mode Stream mode
* \retval zero on success otherwise a negative error code
* \warning Using of this function might be dangerous in the sense
* of compatibility reasons. The prototype might be freely
* changed in future.
*/
int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode)
@ -1502,4 +1576,6 @@ _free:
free((char *)sname);
return err;
}
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_share_open, SND_PCM_DLSYM_VERSION);
#endif