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_linear.c \
../src/pcm/pcm_lfloat.c \ ../src/pcm/pcm_lfloat.c \
../src/pcm/pcm_mulaw.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_hooks.c \
../src/pcm/pcm_meter.c \ ../src/pcm/pcm_meter.c \
../src/pcm/pcm_ladspa.c \
../src/pcm/pcm_misc.c \ ../src/pcm/pcm_misc.c \
../src/rawmidi \ ../src/rawmidi \
../src/timer \ ../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) 2000 by Abramo Bagnara <abramo@alsa-project.org>
* Copyright (c) 1999 by Uros Bizjak <uros@kss-loka.si> * Copyright (c) 1999 by Uros Bizjak <uros@kss-loka.si>
* Jaroslav Kysela <perex@suse.cz> * 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 = ""; const char *_snd_module_pcm_adpcm = "";
#endif #endif
#ifndef DOC_HIDDEN
typedef void (*adpcm_f)(const snd_pcm_channel_area_t *dst_areas, typedef void (*adpcm_f)(const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
const snd_pcm_channel_area_t *src_areas, const snd_pcm_channel_area_t *src_areas,
@ -73,6 +84,8 @@ typedef struct {
snd_pcm_adpcm_state_t *states; snd_pcm_adpcm_state_t *states;
} snd_pcm_adpcm_t; } snd_pcm_adpcm_t;
#endif
/* First table lookup for Ima-ADPCM quantizer */ /* First table lookup for Ima-ADPCM quantizer */
static char IndexAdjust[8] = { -1, -1, -1, -1, 2, 4, 6, 8 }; 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); return (state->pred_val);
} }
#ifndef DOC_HIDDEN
void snd_pcm_adpcm_decode(const snd_pcm_channel_area_t *dst_areas, void snd_pcm_adpcm_decode(const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
const snd_pcm_channel_area_t *src_areas, 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) 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; 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_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, close: snd_pcm_plugin_close,
info: snd_pcm_plugin_info, info: snd_pcm_plugin_info,
hw_refine: snd_pcm_adpcm_hw_refine, hw_refine: snd_pcm_adpcm_hw_refine,
@ -510,6 +527,18 @@ snd_pcm_ops_t snd_pcm_adpcm_ops = {
munmap: snd_pcm_plugin_munmap, 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) 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; 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; 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, int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf, snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode) 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); snd_pcm_close(spcm);
return err; return err;
} }
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_adpcm_open, SND_PCM_DLSYM_VERSION); 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 * PCM - A-Law conversion
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org> * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
@ -28,6 +35,8 @@
const char *_snd_module_pcm_alaw = ""; const char *_snd_module_pcm_alaw = "";
#endif #endif
#ifndef DOC_HIDDEN
typedef void (*alaw_f)(const snd_pcm_channel_area_t *dst_areas, typedef void (*alaw_f)(const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
const snd_pcm_channel_area_t *src_areas, const snd_pcm_channel_area_t *src_areas,
@ -43,6 +52,8 @@ typedef struct {
snd_pcm_format_t sformat; snd_pcm_format_t sformat;
} snd_pcm_alaw_t; } snd_pcm_alaw_t;
#endif
static inline int val_seg(int val) static inline int val_seg(int val)
{ {
int r = 1; int r = 1;
@ -126,6 +137,8 @@ static int alaw_to_s16(unsigned char a_val)
return ((a_val & 0x80) ? t : -t); return ((a_val & 0x80) ? t : -t);
} }
#ifndef DOC_HIDDEN
void snd_pcm_alaw_decode(const snd_pcm_channel_area_t *dst_areas, void snd_pcm_alaw_decode(const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
const snd_pcm_channel_area_t *src_areas, 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) 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; 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_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, close: snd_pcm_plugin_close,
info: snd_pcm_plugin_info, info: snd_pcm_plugin_info,
hw_refine: snd_pcm_alaw_hw_refine, hw_refine: snd_pcm_alaw_hw_refine,
@ -384,6 +399,18 @@ snd_pcm_ops_t snd_pcm_alaw_ops = {
munmap: snd_pcm_plugin_munmap, 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) 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; 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; 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, int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf, snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode) 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); snd_pcm_close(spcm);
return err; return err;
} }
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_alaw_open, SND_PCM_DLSYM_VERSION); 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 * PCM - File plugin
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org> * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
@ -28,6 +35,8 @@
const char *_snd_module_pcm_file = ""; const char *_snd_module_pcm_file = "";
#endif #endif
#ifndef DOC_HIDDEN
typedef enum _snd_pcm_file_format { typedef enum _snd_pcm_file_format {
SND_PCM_FILE_FORMAT_RAW SND_PCM_FILE_FORMAT_RAW
} snd_pcm_file_format_t; } snd_pcm_file_format_t;
@ -48,6 +57,8 @@ typedef struct {
size_t buffer_bytes; size_t buffer_bytes;
} snd_pcm_file_t; } snd_pcm_file_t;
#endif /* DOC_HIDDEN */
static void snd_pcm_file_write_bytes(snd_pcm_t *pcm, size_t bytes) static void snd_pcm_file_write_bytes(snd_pcm_t *pcm, size_t bytes)
{ {
snd_pcm_file_t *file = pcm->private_data; 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_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, close: snd_pcm_file_close,
info: snd_pcm_file_info, info: snd_pcm_file_info,
hw_refine: snd_pcm_file_hw_refine, hw_refine: snd_pcm_file_hw_refine,
@ -388,7 +399,7 @@ snd_pcm_ops_t snd_pcm_file_ops = {
munmap: snd_pcm_file_munmap, 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, status: snd_pcm_file_status,
state: snd_pcm_file_state, state: snd_pcm_file_state,
delay: snd_pcm_file_delay, 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, 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_t *pcm;
snd_pcm_file_t *file; 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; 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, int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf, snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode) 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); snd_pcm_close(spcm);
return err; return err;
} }
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_file_open, SND_PCM_DLSYM_VERSION); 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 * PCM - LADSPA integration plugin
* Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz> * Copyright (c) 2001 by Jaroslav Kysela <perex@suse.cz>
@ -32,6 +39,8 @@
const char *_snd_module_pcm_ladspa = ""; const char *_snd_module_pcm_ladspa = "";
#endif #endif
#ifndef DOC_HIDDEN
#define NO_ASSIGN 0xffffffff #define NO_ASSIGN 0xffffffff
typedef enum _snd_pcm_ladspa_policy { typedef enum _snd_pcm_ladspa_policy {
@ -89,6 +98,8 @@ typedef struct {
struct list_head instances; struct list_head instances;
} snd_pcm_ladspa_plugin_t; } snd_pcm_ladspa_plugin_t;
#endif /* DOC_HIDDEN */
static int snd_pcm_ladspa_find_port(unsigned int *res, static int snd_pcm_ladspa_find_port(unsigned int *res,
snd_pcm_ladspa_plugin_t *lplug, snd_pcm_ladspa_plugin_t *lplug,
LADSPA_PortDescriptor pdesc, 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_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, close: snd_pcm_ladspa_close,
info: snd_pcm_plugin_info, info: snd_pcm_plugin_info,
hw_refine: snd_pcm_ladspa_hw_refine, hw_refine: snd_pcm_ladspa_hw_refine,
@ -1095,6 +1106,18 @@ static int snd_pcm_ladspa_build_plugins(struct list_head *list,
return 0; 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, int snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
const char *ladspa_path, const char *ladspa_path,
snd_config_t *ladspa_pplugins, snd_config_t *ladspa_pplugins,
@ -1154,6 +1177,70 @@ int snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
return 0; 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, int _snd_pcm_ladspa_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf, snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode) 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); snd_pcm_close(spcm);
return err; return err;
} }
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_ladspa_open, SND_PCM_DLSYM_VERSION); 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_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, close: snd_pcm_meter_close,
info: snd_pcm_meter_info, info: snd_pcm_meter_info,
hw_refine: snd_pcm_meter_hw_refine, hw_refine: snd_pcm_meter_hw_refine,
@ -590,7 +590,7 @@ snd_pcm_ops_t snd_pcm_meter_ops = {
munmap: snd_pcm_meter_munmap, 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, status: snd_pcm_meter_status,
state: snd_pcm_meter_state, state: snd_pcm_meter_state,
delay: snd_pcm_meter_delay, 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, 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, int snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name, unsigned int frequency,
snd_pcm_t *slave, int close_slave) 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; 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, int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf, snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode) 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 * PCM - Multi
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org> * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
@ -31,6 +38,8 @@
const char *_snd_module_pcm_multi = ""; const char *_snd_module_pcm_multi = "";
#endif #endif
#ifndef DOC_HIDDEN
typedef struct { typedef struct {
snd_pcm_t *pcm; snd_pcm_t *pcm;
unsigned int channels_count; unsigned int channels_count;
@ -51,6 +60,8 @@ typedef struct {
snd_pcm_multi_channel_t *channels; snd_pcm_multi_channel_t *channels;
} snd_pcm_multi_t; } snd_pcm_multi_t;
#endif
static int snd_pcm_multi_close(snd_pcm_t *pcm) static int snd_pcm_multi_close(snd_pcm_t *pcm)
{ {
snd_pcm_multi_t *multi = pcm->private_data; 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, close: snd_pcm_multi_close,
info: snd_pcm_multi_info, info: snd_pcm_multi_info,
hw_refine: snd_pcm_multi_hw_refine, hw_refine: snd_pcm_multi_hw_refine,
@ -572,7 +583,7 @@ snd_pcm_ops_t snd_pcm_multi_ops = {
munmap: snd_pcm_multi_munmap, 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, status: snd_pcm_multi_status,
state: snd_pcm_multi_state, state: snd_pcm_multi_state,
delay: snd_pcm_multi_delay, 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, 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, int snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
unsigned int slaves_count, unsigned int master_slave, unsigned int slaves_count, unsigned int master_slave,
snd_pcm_t **slaves_pcm, unsigned int *schannels_count, 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; 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, int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf, snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode) snd_pcm_stream_t stream, int mode)
@ -874,4 +953,6 @@ _free:
free(channels_schannel); free(channels_schannel);
return err; return err;
} }
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_multi_open, SND_PCM_DLSYM_VERSION); 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 * PCM - Plug
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org> * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
@ -27,6 +34,8 @@
const char *_snd_module_pcm_plug = ""; const char *_snd_module_pcm_plug = "";
#endif #endif
#ifndef DOC_HIDDEN
enum snd_pcm_plug_route_policy { enum snd_pcm_plug_route_policy {
PLUG_ROUTE_POLICY_NONE, PLUG_ROUTE_POLICY_NONE,
PLUG_ROUTE_POLICY_DEFAULT, PLUG_ROUTE_POLICY_DEFAULT,
@ -48,6 +57,8 @@ typedef struct {
unsigned int tt_ssize, tt_cused, tt_sused; unsigned int tt_ssize, tt_cused, tt_sused;
} snd_pcm_plug_t; } snd_pcm_plug_t;
#endif
static int snd_pcm_plug_close(snd_pcm_t *pcm) static int snd_pcm_plug_close(snd_pcm_t *pcm)
{ {
snd_pcm_plug_t *plug = pcm->private_data; 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_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, close: snd_pcm_plug_close,
info: snd_pcm_plug_info, info: snd_pcm_plug_info,
hw_refine: snd_pcm_plug_hw_refine, hw_refine: snd_pcm_plug_hw_refine,
@ -879,6 +890,18 @@ snd_pcm_ops_t snd_pcm_plug_ops = {
munmap: snd_pcm_plug_munmap, 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, int snd_pcm_plug_open(snd_pcm_t **pcmp,
const char *name, const char *name,
snd_pcm_format_t sformat, int schannels, int srate, snd_pcm_format_t sformat, int schannels, int srate,
@ -923,8 +946,61 @@ int snd_pcm_plug_open(snd_pcm_t **pcmp,
return 0; 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, int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf, snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode) 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) if (err < 0)
return err; return err;
if (tt) { if (tt) {
ttable = malloc(MAX_CHANNELS * MAX_CHANNELS * sizeof(*ttable)); err = snd_pcm_route_determine_ttable(tt, &csize, &ssize);
err = snd_pcm_route_load_ttable(tt, ttable, MAX_CHANNELS, MAX_CHANNELS, if (err < 0) {
&cused, &sused, -1); 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) { if (err < 0) {
snd_config_delete(sconf); snd_config_delete(sconf);
return err; return err;
@ -1010,4 +1094,6 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_close(spcm); snd_pcm_close(spcm);
return err; return err;
} }
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_plug_open, SND_PCM_DLSYM_VERSION); 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 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
* *
*/ */
/*! /*!
* \page pcm_plugins PCM (digital audio) plugins
* \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 PCM plugins extends functionality and features of PCM devices.
* copying among channels and so on. 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 <sys/shm.h>
#include <limits.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> * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
* *
* *
@ -29,6 +36,8 @@
const char *_snd_module_pcm_route = ""; const char *_snd_module_pcm_route = "";
#endif #endif
#ifndef DOC_HIDDEN
/* The best possible hack to support missing optimization in gcc 2.7.2.3 */ /* 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 #if SND_PCM_PLUGIN_ROUTE_RESOLUTION & (SND_PCM_PLUGIN_ROUTE_RESOLUTION - 1) != 0
#define div(a) a /= SND_PCM_PLUGIN_ROUTE_RESOLUTION #define div(a) a /= SND_PCM_PLUGIN_ROUTE_RESOLUTION
@ -91,6 +100,7 @@ typedef struct {
snd_pcm_route_params_t params; snd_pcm_route_params_t params;
} snd_pcm_route_t; } snd_pcm_route_t;
#endif /* DOC_HIDDEN */
static void snd_pcm_route_convert1_zero(const snd_pcm_channel_area_t *dst_area, static void snd_pcm_route_convert1_zero(const snd_pcm_channel_area_t *dst_area,
snd_pcm_uframes_t dst_offset, 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); 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, static void snd_pcm_route_convert1_one(const snd_pcm_channel_area_t *dst_area,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
const snd_pcm_channel_area_t *src_areas, 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, static void snd_pcm_route_convert(const snd_pcm_channel_area_t *dst_areas,
snd_pcm_uframes_t dst_offset, snd_pcm_uframes_t dst_offset,
const snd_pcm_channel_area_t *src_areas, 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_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, close: snd_pcm_route_close,
info: snd_pcm_plugin_info, info: snd_pcm_plugin_info,
hw_refine: snd_pcm_route_hw_refine, 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; 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, int snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_format_t sformat, int schannels, snd_pcm_format_t sformat, int schannels,
snd_pcm_route_ttable_entry_t *ttable, 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; 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, int snd_pcm_route_determine_ttable(snd_config_t *tt,
unsigned int *tt_csize, unsigned int *tt_csize,
unsigned int *tt_ssize) unsigned int *tt_ssize)
@ -828,7 +865,17 @@ int snd_pcm_route_determine_ttable(snd_config_t *tt,
return 0; 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, 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_csize, unsigned int tt_ssize,
unsigned int *tt_cused, unsigned int *tt_sused, 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; 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, int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf, snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode) 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); snd_pcm_close(spcm);
return err; return err;
} }
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_route_open, SND_PCM_DLSYM_VERSION); 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 * PCM - Share
* Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org> * Copyright (c) 2000 by Abramo Bagnara <abramo@alsa-project.org>
@ -37,6 +44,8 @@
const char *_snd_module_pcm_share = ""; const char *_snd_module_pcm_share = "";
#endif #endif
#ifndef DOC_HIDDEN
static LIST_HEAD(snd_pcm_share_slaves); static LIST_HEAD(snd_pcm_share_slaves);
static pthread_mutex_t snd_pcm_share_slaves_mutex = PTHREAD_MUTEX_INITIALIZER; static pthread_mutex_t snd_pcm_share_slaves_mutex = PTHREAD_MUTEX_INITIALIZER;
@ -106,6 +115,8 @@ typedef struct {
int slave_socket; int slave_socket;
} snd_pcm_share_t; } snd_pcm_share_t;
#endif /* DOC_HIDDEN */
static void _snd_pcm_share_stop(snd_pcm_t *pcm, snd_pcm_state_t state); 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) 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_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, close: snd_pcm_share_close,
info: snd_pcm_share_info, info: snd_pcm_share_info,
hw_refine: snd_pcm_share_hw_refine, hw_refine: snd_pcm_share_hw_refine,
@ -1192,7 +1203,7 @@ snd_pcm_ops_t snd_pcm_share_ops = {
munmap: snd_pcm_share_munmap, 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, status: snd_pcm_share_status,
state: snd_pcm_share_state, state: snd_pcm_share_state,
delay: snd_pcm_share_delay, 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, 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, int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
snd_pcm_format_t sformat, int srate, snd_pcm_format_t sformat, int srate,
unsigned int schannels, unsigned int schannels,
@ -1383,6 +1413,50 @@ int snd_pcm_share_open(snd_pcm_t **pcmp, const char *name, const char *sname,
return 0; 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, int _snd_pcm_share_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *root, snd_config_t *conf, snd_config_t *root, snd_config_t *conf,
snd_pcm_stream_t stream, int mode) snd_pcm_stream_t stream, int mode)
@ -1502,4 +1576,6 @@ _free:
free((char *)sname); free((char *)sname);
return err; return err;
} }
#ifndef DOC_HIDDEN
SND_DLSYM_BUILD_VERSION(_snd_pcm_share_open, SND_PCM_DLSYM_VERSION); SND_DLSYM_BUILD_VERSION(_snd_pcm_share_open, SND_PCM_DLSYM_VERSION);
#endif