Added snd_config_hook_load_for_all_cards.

Added private_data parameter for snd_config_hooks function.
Fixed the return value mess in the config parser routines.
The include file could begin with 'confdir:' which is replaced with /usr/share/alsa.
The snd_config_search_definitions looks for raw name at first (without suggested root).
Added snd_func_private_card_strtype function.
All configuration files moved to the src/conf directory.
Configuration files modified to use load-on-demand feature using hooks.
This commit is contained in:
Jaroslav Kysela 2001-06-21 13:41:50 +00:00
parent be5529bc3a
commit bc581b87ae
24 changed files with 909 additions and 199 deletions

View file

@ -53,6 +53,7 @@ AC_OUTPUT(Makefile doc/Makefile include/Makefile src/Makefile \
src/control/Makefile src/mixer/Makefile src/pcm/Makefile \ src/control/Makefile src/mixer/Makefile src/pcm/Makefile \
src/rawmidi/Makefile src/timer/Makefile \ src/rawmidi/Makefile src/timer/Makefile \
src/hwdep/Makefile src/seq/Makefile src/instr/Makefile \ src/hwdep/Makefile src/seq/Makefile src/instr/Makefile \
src/compat/Makefile src/cards/Makefile aserver/Makefile \ src/compat/Makefile src/conf/Makefile \
test/Makefile utils/Makefile \ src/conf/cards/Makefile src/conf/pcm/Makefile \
aserver/Makefile test/Makefile utils/Makefile \
utils/alsa-lib.spec) utils/alsa-lib.spec)

View file

@ -1,4 +1,4 @@
SUBDIRS=control mixer pcm rawmidi timer hwdep seq instr compat cards SUBDIRS=control mixer pcm rawmidi timer hwdep seq instr compat conf
COMPATNUM=@LIBTOOL_VERSION_INFO@ COMPATNUM=@LIBTOOL_VERSION_INFO@
lib_LTLIBRARIES = libasound.la lib_LTLIBRARIES = libasound.la
@ -10,11 +10,6 @@ libasound_la_LIBADD = control/libcontrol.la mixer/libmixer.la pcm/libpcm.la \
libasound_la_LDFLAGS = -version-info $(COMPATNUM) libasound_la_LDFLAGS = -version-info $(COMPATNUM)
EXTRA_DIST = alsa.conf
alsadir = $(datadir)/alsa
alsa_DATA = alsa.conf
control/libcontrol.la: control/libcontrol.la:
$(MAKE) -C control libcontrol.la $(MAKE) -C control libcontrol.la

View file

@ -51,17 +51,17 @@ struct filedesc {
struct filedesc *next; struct filedesc *next;
}; };
#define LOCAL_ERROR (-0x68000000)
#define LOCAL_UNTERMINATED_STRING (LOCAL_ERROR - 0)
#define LOCAL_UNTERMINATED_QUOTE (LOCAL_ERROR - 1)
#define LOCAL_UNEXPECTED_CHAR (LOCAL_ERROR - 2)
#define LOCAL_UNEXPECTED_EOF (LOCAL_ERROR - 3)
typedef struct { typedef struct {
struct filedesc *current; struct filedesc *current;
int unget; int unget;
int ch; int ch;
enum {
UNTERMINATED_STRING = -1,
UNTERMINATED_QUOTE = -2,
UNEXPECTED_CHAR = -3,
UNEXPECTED_EOF = -4,
BAD_ENV_DEFAULT = -5,
} error;
} input_t; } input_t;
int safe_strtol(const char *str, long *val) int safe_strtol(const char *str, long *val)
@ -123,12 +123,12 @@ static int get_char(input_t *input)
free(fd); free(fd);
goto again; goto again;
} }
break; return LOCAL_UNEXPECTED_EOF;
default: default:
fd->column++; fd->column++;
break; break;
} }
return c; return (unsigned char)c;
} }
static void unget_char(int c, input_t *input) static void unget_char(int c, input_t *input)
@ -152,9 +152,21 @@ static int get_char_skip_comments(input_t *input)
int err = get_delimstring(&str, '>', input); int err = get_delimstring(&str, '>', input);
if (err < 0) if (err < 0)
return err; return err;
if (!strncmp(str, "confdir:", 8)) {
char *tmp = malloc(strlen(DATADIR "/alsa") + 1 + strlen(str + 8) + 1);
if (tmp == NULL) {
free(str);
return -ENOMEM;
}
sprintf(tmp, DATADIR "/alsa/%s", str + 8);
free(str);
str = tmp;
}
err = snd_input_stdio_open(&in, str, "r"); err = snd_input_stdio_open(&in, str, "r");
if (err < 0) if (err < 0) {
free(str);
return err; return err;
}
fd = malloc(sizeof(*fd)); fd = malloc(sizeof(*fd));
if (!fd) if (!fd)
return -ENOMEM; return -ENOMEM;
@ -171,7 +183,7 @@ static int get_char_skip_comments(input_t *input)
while (1) { while (1) {
c = get_char(input); c = get_char(input);
if (c == EOF) if (c == EOF)
return c; return LOCAL_UNEXPECTED_EOF;
if (c == '\n') if (c == '\n')
break; break;
} }
@ -246,6 +258,11 @@ static int get_freestring(char **string, int id, input_t *input)
int c; int c;
while (1) { while (1) {
c = get_char(input); c = get_char(input);
if (c < 0) {
if (buf != _buf)
free(buf);
return c;
}
switch (c) { switch (c) {
case '.': case '.':
if (!id) if (!id)
@ -255,7 +272,6 @@ static int get_freestring(char **string, int id, input_t *input)
case '\t': case '\t':
case '\n': case '\n':
case '\r': case '\r':
case EOF:
case '=': case '=':
case ',': case ',':
case ';': case ';':
@ -314,16 +330,13 @@ static int get_delimstring(char **string, int delim, input_t *input)
int c; int c;
while (1) { while (1) {
c = get_char(input); c = get_char(input);
if (c < 0)
return c;
switch (c) { switch (c) {
case EOF:
input->error = UNTERMINATED_STRING;
return -EINVAL;
case '\\': case '\\':
c = get_quotedchar(input); c = get_quotedchar(input);
if (c < 0) { if (c < 0)
input->error = UNTERMINATED_QUOTE; return c;
return -EINVAL;
}
break; break;
default: default:
if (c == delim) { if (c == delim) {
@ -362,12 +375,10 @@ static int get_delimstring(char **string, int delim, input_t *input)
/* Return 0 for free string, 1 for delimited string */ /* Return 0 for free string, 1 for delimited string */
static int get_string(char **string, int id, input_t *input) static int get_string(char **string, int id, input_t *input)
{ {
int c = get_nonwhite(input); int c = get_nonwhite(input), err;
int err; if (c < 0)
return c;
switch (c) { switch (c) {
case EOF:
input->error = UNEXPECTED_EOF;
return -EINVAL;
case '=': case '=':
case ',': case ',':
case ';': case ';':
@ -376,8 +387,7 @@ static int get_string(char **string, int id, input_t *input)
case '}': case '}':
case '[': case '[':
case ']': case ']':
input->error = UNEXPECTED_CHAR; return LOCAL_UNEXPECTED_CHAR;
return -EINVAL;
case '\'': case '\'':
case '"': case '"':
err = get_delimstring(string, c, input); err = get_delimstring(string, c, input);
@ -534,6 +544,10 @@ static int parse_array_def(snd_config_t *father, input_t *input, int idx)
if (id == NULL) if (id == NULL)
return -ENOMEM; return -ENOMEM;
c = get_nonwhite(input); c = get_nonwhite(input);
if (c < 0) {
err = c;
goto __end;
}
switch (c) { switch (c) {
case '{': case '{':
case '[': case '[':
@ -558,10 +572,13 @@ static int parse_array_def(snd_config_t *father, input_t *input, int idx)
endchr = ']'; endchr = ']';
} }
c = get_nonwhite(input); c = get_nonwhite(input);
if (c < 0) {
err = c;
goto __end;
}
if (c != endchr) { if (c != endchr) {
snd_config_delete(n); snd_config_delete(n);
input->error = (c == EOF ? UNEXPECTED_EOF : UNEXPECTED_CHAR); err = LOCAL_UNEXPECTED_CHAR;
err = -EINVAL;
goto __end; goto __end;
} }
break; break;
@ -584,10 +601,9 @@ static int parse_array_defs(snd_config_t *father, input_t *input)
{ {
int idx = 0; int idx = 0;
while (1) { while (1) {
int c = get_nonwhite(input); int c = get_nonwhite(input), err;
int err; if (c < 0)
if (c == EOF) return c;
return 0;
unget_char(c, input); unget_char(c, input);
if (c == ']') if (c == ']')
return 0; return 0;
@ -607,15 +623,15 @@ static int parse_def(snd_config_t *father, input_t *input)
enum {MERGE, NOCREATE, REMOVE} mode; enum {MERGE, NOCREATE, REMOVE} mode;
while (1) { while (1) {
c = get_nonwhite(input); c = get_nonwhite(input);
if (c < 0)
return c;
switch (c) { switch (c) {
#if 0
case '?': case '?':
mode = NOCREATE; mode = NOCREATE;
break; break;
case '!': case '!':
mode = REMOVE; mode = REMOVE;
break; break;
#endif
default: default:
mode = MERGE; mode = MERGE;
unget_char(c, input); unget_char(c, input);
@ -650,8 +666,11 @@ static int parse_def(snd_config_t *father, input_t *input)
n->u.compound.join = 1; n->u.compound.join = 1;
father = n; father = n;
} }
if (c == '=') if (c == '=') {
c = get_nonwhite(input); c = get_nonwhite(input);
if (c < 0)
return c;
}
if (_snd_config_search(father, id, -1, &n) == 0) { if (_snd_config_search(father, id, -1, &n) == 0) {
if (mode == REMOVE) { if (mode == REMOVE) {
snd_config_delete(n); snd_config_delete(n);
@ -691,8 +710,7 @@ static int parse_def(snd_config_t *father, input_t *input)
c = get_nonwhite(input); c = get_nonwhite(input);
if (c != endchr) { if (c != endchr) {
snd_config_delete(n); snd_config_delete(n);
input->error = (c == EOF ? UNEXPECTED_EOF : UNEXPECTED_CHAR); err = LOCAL_UNEXPECTED_CHAR;
err = -EINVAL;
goto __end; goto __end;
} }
break; break;
@ -720,11 +738,11 @@ static int parse_def(snd_config_t *father, input_t *input)
static int parse_defs(snd_config_t *father, input_t *input) static int parse_defs(snd_config_t *father, input_t *input)
{ {
int c, err;
while (1) { while (1) {
int c = get_nonwhite(input); c = get_nonwhite(input);
int err; if (c < 0)
if (c == EOF) return c == LOCAL_UNEXPECTED_EOF ? 0 : c;
return 0;
unget_char(c, input); unget_char(c, input);
if (c == '}') if (c == '}')
return 0; return 0;
@ -905,12 +923,12 @@ static int _snd_config_save_leaves(snd_config_t *config, snd_output_t *out, unsi
/** /**
* \brief Substitute one node to another * \brief Substitute one node to another
* \brief dst Destination node * \brief dst Destination node
* \brief src Source node (invalid after cal) * \brief src Source node (invalid after call)
*/ */
int snd_config_substitute(snd_config_t *dst, snd_config_t *src) int snd_config_substitute(snd_config_t *dst, snd_config_t *src)
{ {
assert(dst && src); assert(dst && src);
if (src->type == SND_CONFIG_TYPE_COMPOUND) { if (src->type == SND_CONFIG_TYPE_COMPOUND) { /* append */
snd_config_iterator_t i, next; snd_config_iterator_t i, next;
snd_config_for_each(i, next, src) { snd_config_for_each(i, next, src) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
@ -919,6 +937,7 @@ int snd_config_substitute(snd_config_t *dst, snd_config_t *src)
src->u.compound.fields.next->prev = &dst->u.compound.fields; src->u.compound.fields.next->prev = &dst->u.compound.fields;
src->u.compound.fields.prev->next = &dst->u.compound.fields; src->u.compound.fields.prev->next = &dst->u.compound.fields;
} }
if (dst->id)
free(dst->id); free(dst->id);
dst->id = src->id; dst->id = src->id;
dst->type = src->type; dst->type = src->type;
@ -1022,40 +1041,32 @@ int snd_config_load(snd_config_t *config, snd_input_t *in)
fd->next = NULL; fd->next = NULL;
input.current = fd; input.current = fd;
input.unget = 0; input.unget = 0;
input.error = 0;
err = parse_defs(config, &input); err = parse_defs(config, &input);
fd = input.current; fd = input.current;
if (err < 0) { if (err < 0) {
if (input.error < 0) {
const char *str; const char *str;
switch (input.error) { switch (err) {
case UNTERMINATED_STRING: case LOCAL_UNTERMINATED_STRING:
str = "Unterminated string"; str = "Unterminated string";
break; break;
case UNTERMINATED_QUOTE: case LOCAL_UNTERMINATED_QUOTE:
str = "Unterminated quote"; str = "Unterminated quote";
break; break;
case UNEXPECTED_CHAR: case LOCAL_UNEXPECTED_CHAR:
str = "Unexpected char"; str = "Unexpected char";
break; break;
case UNEXPECTED_EOF: case LOCAL_UNEXPECTED_EOF:
str = "Unexpected end of file"; str = "Unexpected end of file";
break; break;
case BAD_ENV_DEFAULT:
str = "Bad environment default value";
break;
default: default:
assert(0); str = strerror(-err);
break; break;
} }
SNDERR("%s:%d:%d:%s", fd->name ? fd->name : "_toplevel_", SNDERR("%s:%d:%d:%s", fd->name ? fd->name : "_toplevel_", fd->line, fd->column, str);
fd->line, fd->column, str);
}
goto _end; goto _end;
} }
if (get_char(&input) != EOF) { if (get_char(&input) != LOCAL_UNEXPECTED_EOF) {
SNDERR("%s:%d:%d:Unexpected }", fd->name ? fd->name : "", SNDERR("%s:%d:%d:Unexpected }", fd->name ? fd->name : "", fd->line, fd->column);
fd->line, fd->column);
err = -EINVAL; err = -EINVAL;
goto _end; goto _end;
} }
@ -1541,9 +1552,9 @@ int snd_config_search_alias(snd_config_t *config,
*/ */
int snd_config_search_hooks(snd_config_t *config, const char *key, snd_config_t **result) int snd_config_search_hooks(snd_config_t *config, const char *key, snd_config_t **result)
{ {
static int snd_config_hooks(snd_config_t *config); static int snd_config_hooks(snd_config_t *config, void *private_data);
SND_CONFIG_SEARCH(config, key, result, \ SND_CONFIG_SEARCH(config, key, result, \
err = snd_config_hooks(config); \ err = snd_config_hooks(config, NULL); \
if (err < 0) \ if (err < 0) \
return err; \ return err; \
); );
@ -1602,14 +1613,14 @@ static struct finfo {
static unsigned int files_info_count = 0; static unsigned int files_info_count = 0;
static int snd_config_hooks_call(snd_config_t *root, snd_config_t *config) static int snd_config_hooks_call(snd_config_t *root, snd_config_t *config, void *private_data)
{ {
void *h = NULL; void *h = NULL;
snd_config_t *c, *func_conf = NULL; snd_config_t *c, *func_conf = NULL;
char *buf = NULL; char *buf = NULL;
const char *lib = NULL, *func_name = NULL; const char *lib = NULL, *func_name = NULL;
const char *str; const char *str;
int (*func)(snd_config_t *root, snd_config_t *config, snd_config_t **dst) = NULL; int (*func)(snd_config_t *root, snd_config_t *config, snd_config_t **dst, void *private_data) = NULL;
int err; int err;
err = snd_config_search(config, "func", &c); err = snd_config_search(config, "func", &c);
@ -1678,7 +1689,7 @@ static int snd_config_hooks_call(snd_config_t *root, snd_config_t *config)
snd_config_delete(func_conf); snd_config_delete(func_conf);
if (err >= 0) { if (err >= 0) {
snd_config_t *nroot; snd_config_t *nroot;
err = func(root, config, &nroot); err = func(root, config, &nroot, private_data);
if (err < 0) if (err < 0)
SNDERR("function %s returned error: %s", func_name, snd_strerror(err)); SNDERR("function %s returned error: %s", func_name, snd_strerror(err));
dlclose(h); dlclose(h);
@ -1692,7 +1703,7 @@ static int snd_config_hooks_call(snd_config_t *root, snd_config_t *config)
return 0; return 0;
} }
static int snd_config_hooks(snd_config_t *config) static int snd_config_hooks(snd_config_t *config, void *private_data)
{ {
snd_config_t *n; snd_config_t *n;
snd_config_iterator_t i, next; snd_config_iterator_t i, next;
@ -1714,7 +1725,7 @@ static int snd_config_hooks(snd_config_t *config)
goto _err; goto _err;
} }
if (i == idx) { if (i == idx) {
err = snd_config_hooks_call(config, n); err = snd_config_hooks_call(config, n, private_data);
if (err < 0) if (err < 0)
return err; return err;
idx++; idx++;
@ -1728,7 +1739,7 @@ static int snd_config_hooks(snd_config_t *config)
return err; return err;
} }
int snd_config_hook_load(snd_config_t *root, snd_config_t *config, snd_config_t **dst) int snd_config_hook_load(snd_config_t *root, snd_config_t *config, snd_config_t **dst, void *private_data)
{ {
snd_config_t *n, *res = NULL; snd_config_t *n, *res = NULL;
snd_config_iterator_t i, next; snd_config_iterator_t i, next;
@ -1752,7 +1763,7 @@ int snd_config_hook_load(snd_config_t *root, snd_config_t *config, snd_config_t
SNDERR("Unable to find field files in the preload section"); SNDERR("Unable to find field files in the preload section");
return -EINVAL; return -EINVAL;
} }
if ((err = snd_config_expand(n, root, NULL, NULL, &n)) < 0) { if ((err = snd_config_expand(n, root, NULL, private_data, &n)) < 0) {
SNDERR("Unable to expand filenames in the preload section"); SNDERR("Unable to expand filenames in the preload section");
return err; return err;
} }
@ -1850,6 +1861,25 @@ int snd_config_hook_load(snd_config_t *root, snd_config_t *config, snd_config_t
return err; return err;
} }
int snd_config_hook_load_for_all_cards(snd_config_t *root, snd_config_t *config, snd_config_t **dst, void *private_data ATTRIBUTE_UNUSED)
{
int card = -1, err;
do {
err = snd_card_next(&card);
if (err < 0)
return err;
if (card >= 0) {
snd_config_t *nroot;
err = snd_config_hook_load(root, config, &nroot, (void *)(unsigned long)card);
if (err < 0)
return err;
}
} while (card >= 0);
*dst = NULL;
return 0;
}
/** /**
* \brief Update #snd_config rereading (if needed) files specified in * \brief Update #snd_config rereading (if needed) files specified in
* environment variable ALSA_CONFIG_PATH. If it's not set the default value is * environment variable ALSA_CONFIG_PATH. If it's not set the default value is
@ -1978,7 +2008,7 @@ int snd_config_update()
SNDERR("cannot access file %s", fi[k].name); SNDERR("cannot access file %s", fi[k].name);
} }
} }
err = snd_config_hooks(snd_config); err = snd_config_hooks(snd_config, NULL);
if (err < 0) { if (err < 0) {
SNDERR("hooks failed, removing configuration"); SNDERR("hooks failed, removing configuration");
goto _end; goto _end;
@ -2796,6 +2826,8 @@ int snd_config_search_definition(snd_config_t *config,
} else { } else {
key = (char *) name; key = (char *) name;
} }
err = snd_config_search_alias_hooks(config, NULL, key, &conf);
if (err < 0)
err = snd_config_search_alias_hooks(config, base, key, &conf); err = snd_config_search_alias_hooks(config, base, key, &conf);
if (err < 0) if (err < 0)
return err; return err;

8
src/conf/Makefile.am Normal file
View file

@ -0,0 +1,8 @@
SUBDIRS=cards pcm
cfg_files = alsa.conf cards.conf
EXTRA_DIST = $(cfg_files)
alsadir = $(datadir)/alsa
alsa_DATA = $(cfg_files)

377
src/conf/alsa.conf Normal file
View file

@ -0,0 +1,377 @@
#
# ALSA library configuration file
#
# preload configuration files
@hooks [
{
func load
files [
"/etc/asound.conf"
"~/.asoundrc"
]
errors false
}
]
# load card-specific configuration files (on request)
cards.@hooks [
{
func load_for_all_cards
files [
{
@func concat
strings [
{ @func datadir }
"/cards/"
{ @func private_card_strtype }
".conf"
]
}
]
errors false
}
]
# defaults
defaults.ctl.card 0
defaults.pcm.card 0
defaults.pcm.device 0
defaults.pcm.subdevice -1
defaults.pcm.front.card defaults.pcm.card
defaults.pcm.front.device defaults.pcm.device
defaults.pcm.rear.card defaults.pcm.card
defaults.pcm.rear.device defaults.pcm.device
defaults.pcm.surround40.card defaults.pcm.card
defaults.pcm.surround40.device defaults.pcm.device
defaults.pcm.surround51.card defaults.pcm.card
defaults.pcm.surround51.device defaults.pcm.device
defaults.rawmidi.card 0
defaults.rawmidi.device 0
defaults.rawmidi.subdevice -1
#
# PCM interface
#
pcm.hw {
@args [ CARD DEV SUBDEV ]
@args.CARD {
type string
default {
@func getenv
vars [
ALSA_PCM_CARD
ALSA_CARD
]
default {
@func refer
name defaults.pcm.card
}
}
}
@args.DEV {
type integer
default {
@func igetenv
vars [
ALSA_PCM_DEVICE
]
default {
@func refer
name defaults.pcm.device
}
}
}
@args.SUBDEV {
type integer
default {
@func refer
name defaults.pcm.subdevice
}
}
type hw
card $CARD
device $DEV
subdevice $SUBDEV
}
pcm.plughw {
@args [ CARD DEV SUBDEV ]
@args.CARD {
type string
default {
@func getenv
vars [
ALSA_PCM_CARD
ALSA_CARD
]
default {
@func refer
name defaults.pcm.card
}
}
}
@args.DEV {
type integer
default {
@func igetenv
vars [
ALSA_PCM_DEVICE
]
default {
@func refer
name defaults.pcm.device
}
}
}
@args.SUBDEV {
type integer
default {
@func refer
name defaults.pcm.subdevice
}
}
type plug
slave.pcm {
type hw
card $CARD
device $DEV
subdevice $SUBDEV
}
}
pcm.plug {
@args [ SLAVE ]
@args.SLAVE {
type string
}
type plug
slave.pcm $SLAVE
}
pcm.shm {
@args [ SOCKET PCM ]
@args.SOCKET {
type string
}
@args.PCM {
type string
}
type shm
server $SOCKET
pcm $PCM
}
pcm.tee {
@args [ SLAVE FILE FORMAT ]
@args.SLAVE {
type string
}
@args.FILE {
type string
}
@args.FORMAT {
type string
default raw
}
type file
slave.pcm $SLAVE
file $FILE
format $FORMAT
}
pcm.file {
@args [ FILE FORMAT ]
@args.FILE {
type string
}
@args.FORMAT {
type string
default raw
}
type file
slave.pcm null
file $FILE
format $FORMAT
}
pcm.null {
type null
}
pcm.default {
type plug
slave.pcm {
type hw
card {
@func getenv
vars [
ALSA_PCM_CARD
ALSA_CARD
]
default {
@func refer
name defaults.pcm.card
}
}
device {
@func igetenv
vars [
ALSA_PCM_DEVICE
]
default {
@func refer
name defaults.pcm.device
}
}
subdevice {
@func refer
name defaults.pcm.subdevice
}
}
}
# redirect to load-on-demand extended pcm definitions
pcm.cards cards.pcm
# some links for easy use
pcm.front cards.pcm.front
pcm.rear cards.pcm.rear
pcm.center_lfe cards.pcm.center_lfe
pcm.surround40 cards.pcm.surround40
pcm.surround51 cards.pcm.surround51
#
# Control interface
#
ctl.hw {
@args[ CARD ]
@args.CARD {
type string
default {
@func getenv
vars [
ALSA_CTL_CARD
ALSA_CARD
]
default {
@func refer
name defaults.ctl.card
}
}
}
type hw
card $CARD
}
ctl.shm {
@args [ SOCKET CTL ]
@args.SOCKET {
type string
}
@args.CTL {
type string
}
type shm
server $SOCKET
ctl $CTL
}
ctl.default {
type hw
card {
@func getenv
vars [
ALSA_CTL_CARD
ALSA_CARD
]
default {
@func refer
name defaults.ctl.card
}
}
}
#
# RawMidi interface
#
rawmidi.hw {
@args [ CARD DEV SUBDEV ]
@args.CARD {
type string
default {
@func getenv
vars [
ALSA_RAWMIDI_CARD
ALSA_CARD
]
default {
@func refer
name defaults.rawmidi.card
}
}
}
@args.DEV {
type integer
default {
@func igetenv
vars [
ALSA_RAWMIDI_DEVICE
]
default {
@func refer
name defaults.rawmidi.device
}
}
}
@args.SUBDEV {
type integer
default -1
}
type hw
card $CARD
device $DEV
subdevice $SUBDEV
}
rawmidi.default {
type hw
card {
@func getenv
vars [
ALSA_RAWMIDI_CARD
ALSA_CARD
]
default {
@func refer
name defaults.rawmidi.card
}
}
device {
@func igetenv
vars [
ALSA_RAWMIDI_DEVICE
]
default {
@func refer
name defaults.rawmidi.device
}
}
}
#
# Sequencer interface
#
seq.default {
type hw
}
seq.hw {
type hw
}

View file

@ -2,7 +2,7 @@
# Configuration for the CMIPCI chip # Configuration for the CMIPCI chip
# #
cards.CMI8738.pcm.front.0 { CMIPCI.pcm.front.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -14,7 +14,7 @@ cards.CMI8738.pcm.front.0 {
# 2nd DAC # 2nd DAC
# FIXME: we need a volume attenuator for rear channel. # FIXME: we need a volume attenuator for rear channel.
cards.CMI8738.pcm.rear.0 { CMIPCI.pcm.rear.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -25,11 +25,11 @@ cards.CMI8738.pcm.rear.0 {
} }
# for the recent CM8738 chips # for the recent CM8738 chips
# cards.CMI8738.pcm.surround40.0 "cards.CMI8738.pcm.front.0" # cards.CMIPCI.pcm.surround40.0 "cards.CMIPCI.pcm.front.0"
cards.CMI8738.pcm.surround51.0 "cards.CMI8738.pcm.front.0" CMIPCI.pcm.surround51.0 "cards.CMIPCI.pcm.front.0"
# for the old CM8738 with 2nd DAC for rear # for the old CM8738 with 2nd DAC for rear
cards.CMI8738.pcm.surround40.0 { CMIPCI.pcm.surround40.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -41,7 +41,7 @@ cards.CMI8738.pcm.surround40.0 {
pcm { pcm {
@func concat @func concat
strings [ strings [
"cards.CMI8738.pcm.front.0:CARD=" $CARD "cards.CMIPCI.pcm.front.0:CARD=" $CARD
] ]
} }
channels 2 channels 2
@ -50,7 +50,7 @@ cards.CMI8738.pcm.surround40.0 {
pcm { pcm {
@func concat @func concat
strings [ strings [
"cards.CMI8738.pcm.rear.0:CARD=" $CARD "cards.CMIPCI.pcm.rear.0:CARD=" $CARD
] ]
} }
channels 2 channels 2
@ -65,7 +65,7 @@ cards.CMI8738.pcm.surround40.0 {
} }
cards.CMI8738.pcm.iec958.0 { CMIPCI.pcm.iec958.0 {
@args [ CARD DEV AES0 AES1 AES2 AES3 ] @args [ CARD DEV AES0 AES1 AES2 AES3 ]
@args.CARD { @args.CARD {
type string type string
@ -86,18 +86,18 @@ cards.CMI8738.pcm.iec958.0 {
type integer type integer
} }
type hooks type hooks
slave.pcm {
type hw
card $CARD
device 2
}
hooks.0 { hooks.0 {
type ctl_elems type ctl_elems
hook_args [ hook_args [
{
name "IEC958 Enable"
value 1
lock true
preserve true
}
{ {
interface PCM interface PCM
name "IEC958 Playback PCM Stream" name "IEC958 Playback PCM Stream"
device 2
lock true lock true
preserve true preserve true
value [ $AES0 $AES1 $AES2 $AES3 ] value [ $AES0 $AES1 $AES2 $AES3 ]

View file

@ -2,7 +2,9 @@
# Configuration for the EMU10K1 chip # Configuration for the EMU10K1 chip
# #
cards.EMU10K1.pcm.front.0 { <confdir:pcm/front.conf>
EMU10K1.pcm.front.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -12,7 +14,9 @@ cards.EMU10K1.pcm.front.0 {
device 0 device 0
} }
cards.EMU10K1.pcm.rear.0 { <confdir:pcm/rear.conf>
EMU10K1.pcm.rear.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -42,7 +46,9 @@ cards.EMU10K1.pcm.rear.0 {
} }
} }
cards.EMU10K1.pcm.center_lfe.0 { <confdir:pcm/center_lfe.conf>
EMU10K1.pcm.center_lfe.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -84,7 +90,9 @@ cards.EMU10K1.pcm.center_lfe.0 {
} }
} }
cards.EMU10K1.pcm.surround40.0 { <confdir:pcm/surround40.conf>
EMU10K1.pcm.surround40.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -118,7 +126,9 @@ cards.EMU10K1.pcm.surround40.0 {
] ]
} }
cards.EMU10K1.pcm.surround51.0 { <confdir:pcm/surround51.conf>
EMU10K1.pcm.surround51.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -163,7 +173,9 @@ cards.EMU10K1.pcm.surround51.0 {
] ]
} }
cards.EMU10K1.pcm.iec958.0 { <confdir:pcm/iec958.conf>
EMU10K1.pcm.iec958.0 {
@args [ CARD DEV AES0 AES1 AES2 AES3 ] @args [ CARD DEV AES0 AES1 AES2 AES3 ]
@args.CARD { @args.CARD {
type string type string

View file

@ -2,7 +2,9 @@
# Configuration for the ENS1370 chip # Configuration for the ENS1370 chip
# #
cards.ENS1370.pcm.front.0 { <confdir:pcm/front.conf>
ENS1370.pcm.front.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -12,7 +14,9 @@ cards.ENS1370.pcm.front.0 {
device 1 device 1
} }
cards.ENS1370.pcm.rear.0 { <confdir:pcm/rear.conf>
ENS1370.pcm.rear.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -42,7 +46,9 @@ cards.ENS1370.pcm.rear.0 {
} }
} }
cards.ENS1370.pcm.surround40.0 { <confdir:pcm/surround40.conf>
ENS1370.pcm.surround40.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string

View file

@ -2,7 +2,9 @@
# Configuration for the FM801 chip # Configuration for the FM801 chip
# #
cards.FM801.pcm.front.0 { <confdir:pcm/front.conf>
FM801.pcm.front.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -12,10 +14,17 @@ cards.FM801.pcm.front.0 {
device 0 device 0
} }
cards.FM801.pcm.surround40.0 "cards.FM801.pcm.front.0" <confdir:pcm/surround40.conf>
cards.FM801.pcm.surround51.0 "cards.FM801.pcm.front.0"
cards.FM801.pcm.iec958.0 { FM801.pcm.surround40.0 "cards.FM801.pcm.front.0"
<confdir:pcm/surround51.conf>
FM801.pcm.surround51.0 "cards.FM801.pcm.front.0"
<confdir:pcm/iec958.conf>
FM801.pcm.iec958.0 {
@args [ CARD DEV AES0 AES1 AES2 AES3 ] @args [ CARD DEV AES0 AES1 AES2 AES3 ]
@args.CARD { @args.CARD {
type string type string

View file

@ -2,7 +2,9 @@
# Configuration for the ICE1712 (Envy24) chip # Configuration for the ICE1712 (Envy24) chip
# #
cards.ICE1712.pcm.front.0 { <confdir:pcm/front.conf>
ICE1712.pcm.front.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -16,7 +18,9 @@ cards.ICE1712.pcm.front.0 {
} }
} }
cards.ICE1712.pcm.surround40.0 { <confdir:pcm/surround40.conf>
ICE1712.pcm.surround40.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -32,7 +36,9 @@ cards.ICE1712.pcm.surround40.0 {
} }
} }
cards.ICE1712.pcm.surround51.0 { <confdir:pcm/surround51.conf>
ICE1712.pcm.surround51.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -50,7 +56,9 @@ cards.ICE1712.pcm.surround51.0 {
} }
} }
cards.ICE1712.pcm.iec958.0 { <confdir:pcm/iec958.conf>
ICE1712.pcm.iec958.0 {
@args [ CARD DEV AES0 AES1 AES2 AES3 ] @args [ CARD DEV AES0 AES1 AES2 AES3 ]
@args.CARD { @args.CARD {
type string type string
@ -72,14 +80,11 @@ cards.ICE1712.pcm.iec958.0 {
} }
type hooks type hooks
slave.pcm { slave.pcm {
type route type plug
ttable.0.8 1 ttable.0.8 1
ttable.1.9 1 ttable.1.9 1
slave.pcm {
type hw
card $CARD card $CARD
} }
}
hooks.0 { hooks.0 {
type ctl_elems type ctl_elems
hook_args [ hook_args [

View file

@ -2,7 +2,9 @@
# Configuration for the INTEL8X0 chip # Configuration for the INTEL8X0 chip
# #
cards.INTEL8X0.pcm.front.0 { <confdir:pcm/front.conf>
INTEL8X0.pcm.front.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -12,32 +14,13 @@ cards.INTEL8X0.pcm.front.0 {
device 0 device 0
} }
cards.INTEL8X0.pcm.surround40.0 { <confdir:pcm/surround40.conf>
@args [ CARD ]
@args.CARD {
type string
}
type multi
slaves [
{
pcm {
@func concat
strings [
"cards.INTEL8X0.pcm.front.0:CARD=" $CARD
]
}
channels 4
}
]
bindings [
{ slave 0 channel 0 }
{ slave 0 channel 1 }
{ slave 1 channel 0 }
{ slave 1 channel 1 }
]
}
cards.INTEL8X0.pcm.surround51.0 { INTEL8X0.pcm.surround40.0 "cards.INTEL8X0.pcm.front.0"
<confdir:pcm/surround51.conf>
INTEL8X0.pcm.surround51.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -51,7 +34,7 @@ cards.INTEL8X0.pcm.surround51.0 {
"cards.INTEL8X0.pcm.front.0:CARD=" $CARD "cards.INTEL8X0.pcm.front.0:CARD=" $CARD
] ]
} }
channels 2 channels 6
} }
] ]
bindings [ bindings [
@ -64,7 +47,9 @@ cards.INTEL8X0.pcm.surround51.0 {
] ]
} }
cards.INTEL8X0.pcm.iec958.0 { <confdir:pcm/iec958.conf>
INTEL8X0.pcm.iec958.0 {
@args [ CARD DEV AES0 AES1 AES2 AES3 ] @args [ CARD DEV AES0 AES1 AES2 AES3 ]
@args.CARD { @args.CARD {
type string type string

View file

@ -1,6 +1,6 @@
alsadir = $(datadir)/alsa/cards alsadir = $(datadir)/alsa/cards
cfg_files = SI_7018.conf EMU10K1.conf TRID4DWAVENX.conf ENS1370.conf \ cfg_files = SI_7018.conf EMU10K1.conf TRID4DWAVENX.conf ENS1370.conf \
INTEL8X0.conf YMFPCI.conf FM801.conf ICE1712.conf CMI8738.conf INTEL8X0.conf YMFPCI.conf FM801.conf ICE1712.conf CMIPCI.conf
EXTRA_DIST = $(cfg_files) EXTRA_DIST = $(cfg_files)
alsa_DATA = $(cfg_files) alsa_DATA = $(cfg_files)

View file

@ -2,7 +2,9 @@
# Configuration for the SI7018 chip # Configuration for the SI7018 chip
# #
cards.SI_7018.pcm.front.0 { <confdir:pcm/front.conf>
SI_7018.pcm.front.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -12,7 +14,9 @@ cards.SI_7018.pcm.front.0 {
device 0 device 0
} }
cards.SI_7018.pcm.rear.0 { <confdir:pcm/rear.conf>
SI_7018.pcm.rear.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -36,7 +40,9 @@ cards.SI_7018.pcm.rear.0 {
} }
} }
cards.SI_7018.pcm.surround40.0 { <confdir:pcm/surround40.conf>
SI_7018.pcm.surround40.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string

View file

@ -2,7 +2,9 @@
# Configuration for the Trident 4D-Wave NX chip # Configuration for the Trident 4D-Wave NX chip
# #
cards.TRID4DWAVENX.pcm.front.0 { <confdir:pcm/front.conf>
TRID4DWAVENX.pcm.front.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -12,7 +14,9 @@ cards.TRID4DWAVENX.pcm.front.0 {
device 0 device 0
} }
cards.TRID4DWAVENX.pcm.rear.0 { <confdir:pcm/rear.conf>
TRID4DWAVENX.pcm.rear.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -50,7 +54,9 @@ cards.TRID4DWAVENX.pcm.rear.0 {
} }
} }
cards.TRID4DWAVENX.pcm.surround40.0 { <confdir:pcm/surround40.conf>
TRID4DWAVENX.pcm.surround40.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -84,7 +90,9 @@ cards.TRID4DWAVENX.pcm.surround40.0 {
] ]
} }
cards.TRID4DWAVENX.pcm.iec958.0 { <confdir:pcm/iec958.conf>
TRID4DWAVENX.pcm.iec958.0 {
@args [ CARD AES0 AES1 AES2 AES3 ] @args [ CARD AES0 AES1 AES2 AES3 ]
@args.CARD { @args.CARD {
type string type string

View file

@ -2,7 +2,9 @@
# Configuration for the YMFPCI chip # Configuration for the YMFPCI chip
# #
cards.YMFPCI.pcm.front.0 { <confdir:pcm/front.conf>
YMFPCI.pcm.front.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -12,7 +14,9 @@ cards.YMFPCI.pcm.front.0 {
device 0 device 0
} }
cards.YMFPCI.pcm.rear.0 { <confdir:pcm/rear.conf>
YMFPCI.pcm.rear.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -22,7 +26,9 @@ cards.YMFPCI.pcm.rear.0 {
device 2 device 2
} }
cards.YMFPCI.pcm.surround40.0 { <confdir:pcm/surround40.conf>
YMFPCI.pcm.surround40.0 {
@args [ CARD ] @args [ CARD ]
@args.CARD { @args.CARD {
type string type string
@ -56,7 +62,9 @@ cards.YMFPCI.pcm.surround40.0 {
] ]
} }
cards.YMFPCI.pcm.iec958.0 { <confdir:pcm/iec958.conf>
YMFPCI.pcm.iec958.0 {
@args [ CARD DEV AES0 AES1 AES2 AES3 ] @args [ CARD DEV AES0 AES1 AES2 AES3 ]
@args.CARD { @args.CARD {
type string type string

7
src/conf/pcm/Makefile.am Normal file
View file

@ -0,0 +1,7 @@
cfg_files = front.conf rear.conf center_lfe.conf surround40.conf \
surround51.conf
EXTRA_DIST = $(cfg_files)
alsadir = $(datadir)/alsa/pcm
alsa_DATA = $(cfg_files)

View file

@ -0,0 +1,47 @@
#
# Hardware output from center & lfe speakers
#
pcm.!center_lfe {
@args [ CARD DEV ]
@args.CARD {
type string
default {
@func getenv
vars [
ALSA_CENTER_LFE_CARD
ALSA_PCM_CARD
ALSA_CARD
]
default {
@func refer
name defaults.pcm.center_lfe.card
}
}
}
@args.DEV {
type integer
default {
@func igetenv
vars [
ALSA_CENTER_LFE_DEVICE
]
default {
@func refer
name defaults.pcm.center_lfe.device
}
}
}
@func refer
name {
@func concat
strings [
"cards."
{
@func card_strtype
card $CARD
}
".pcm.center_lfe." $DEV ":CARD=" $CARD
]
}
}

47
src/conf/pcm/front.conf Normal file
View file

@ -0,0 +1,47 @@
#
# Hardware output from front speakers
#
pcm.!front {
@args [ CARD DEV ]
@args.CARD {
type string
default {
@func getenv
vars [
ALSA_FRONT_CARD
ALSA_PCM_CARD
ALSA_CARD
]
default {
@func refer
name defaults.pcm.front.card
}
}
}
@args.DEV {
type integer
default {
@func igetenv
vars [
ALSA_FRONT_DEVICE
]
default {
@func refer
name defaults.pcm.front.device
}
}
}
@func refer
name {
@func concat
strings [
"cards."
{
@func card_strtype
card $CARD
}
".pcm.front." $DEV ":CARD=" $CARD
]
}
}

47
src/conf/pcm/rear.conf Normal file
View file

@ -0,0 +1,47 @@
#
# Hardware output from rear speakers
#
pcm.!rear {
@args [ CARD DEV ]
@args.CARD {
type string
default {
@func getenv
vars [
ALSA_REAR_CARD
ALSA_PCM_CARD
ALSA_CARD
]
default {
@func refer
name defaults.pcm.rear.card
}
}
}
@args.DEV {
type integer
default {
@func igetenv
vars [
ALSA_REAR_DEVICE
]
default {
@func refer
name defaults.pcm.rear.device
}
}
}
@func refer
name {
@func concat
strings [
"cards."
{
@func card_strtype
card $CARD
}
".pcm.rear." $DEV ":CARD=" $CARD
]
}
}

View file

@ -0,0 +1,52 @@
#
# Hardware output from 4.0 speakers.
# Samples must be positioned:
# chn0 - front left
# chn1 - front right
# chn2 - rear left
# chn3 - rear right
#
pcm.!surround40 {
@args [ CARD DEV ]
@args.CARD {
type string
default {
@func getenv
vars [
ALSA_SURROUND40_CARD
ALSA_PCM_CARD
ALSA_CARD
]
default {
@func refer
name defaults.pcm.surround40.card
}
}
}
@args.DEV {
type integer
default {
@func igetenv
vars [
ALSA_SURROUND40_DEVICE
]
default {
@func refer
name defaults.pcm.surround40.device
}
}
}
@func refer
name {
@func concat
strings [
"cards."
{
@func card_strtype
card $CARD
}
".pcm.surround40." $DEV ":CARD=" $CARD
]
}
}

View file

@ -0,0 +1,54 @@
#
# Hardware output from 5.1 speakers
# Samples must be positioned:
# chn0 - front left
# chn1 - front right
# chn2 - rear left
# chn3 - rear right
# chn4 - center
# chn5 - lfe
#
pcm.!surround51 {
@args [ CARD DEV ]
@args.CARD {
type string
default {
@func getenv
vars [
ALSA_SURROUND51_CARD
ALSA_PCM_CARD
ALSA_CARD
]
default {
@func refer
name defaults.pcm.surround51.card
}
}
}
@args.DEV {
type integer
default {
@func igetenv
vars [
ALSA_SURROUND51_DEVICE
]
default {
@func refer
name defaults.pcm.surround51.device
}
}
}
@func refer
name {
@func concat
strings [
"cards."
{
@func card_strtype
card $CARD
}
".pcm.surround51." $DEV ":CARD=" $CARD
]
}
}

View file

@ -428,39 +428,16 @@ static int string_from_integer(char **dst, long v)
} }
#endif #endif
int snd_func_card_strtype(snd_config_t **dst, snd_config_t *root, snd_config_t *src, void *private_data) int snd_func_private_card_strtype(snd_config_t **dst, snd_config_t *root ATTRIBUTE_UNUSED, snd_config_t *src, void *private_data)
{ {
snd_config_t *n;
char *res = NULL; char *res = NULL;
char *str;
snd_ctl_t *ctl = NULL; snd_ctl_t *ctl = NULL;
snd_ctl_card_info_t *info; snd_ctl_card_info_t *info;
long v; long v;
int err; int err;
err = snd_config_search(src, "card", &n); v = (long)private_data;
if (err < 0) { assert(v >= 0 && v <= 32);
SNDERR("field card not found");
goto __error;
}
err = snd_config_evaluate(n, root, private_data, NULL);
if (err < 0) {
SNDERR("error evaluating card");
goto __error;
}
err = snd_config_get_ascii(n, &str);
if (err < 0) {
SNDERR("field card is not an integer or a string");
goto __error;
}
v = snd_card_get_index(str);
if (v < 0) {
SNDERR("cannot find card '%s'", str);
free(str);
err = v;
goto __error;
}
free(str);
err = open_ctl(v, &ctl); err = open_ctl(v, &ctl);
if (err < 0) { if (err < 0) {
SNDERR("could not open control for card %li", v); SNDERR("could not open control for card %li", v);
@ -487,6 +464,38 @@ int snd_func_card_strtype(snd_config_t **dst, snd_config_t *root, snd_config_t *
return err; return err;
} }
int snd_func_card_strtype(snd_config_t **dst, snd_config_t *root, snd_config_t *src, void *private_data)
{
snd_config_t *n;
char *str;
long v;
int err;
err = snd_config_search(src, "card", &n);
if (err < 0) {
SNDERR("field card not found");
return err;
}
err = snd_config_evaluate(n, root, private_data, NULL);
if (err < 0) {
SNDERR("error evaluating card");
return err;
}
err = snd_config_get_ascii(n, &str);
if (err < 0) {
SNDERR("field card is not an integer or a string");
return err;
}
v = snd_card_get_index(str);
if (v < 0) {
SNDERR("cannot find card '%s'", str);
free(str);
return v;
}
free(str);
return snd_func_private_card_strtype(dst, root, src, (void *)v);
}
int snd_func_card_id(snd_config_t **dst, snd_config_t *root, snd_config_t *src, void *private_data) int snd_func_card_id(snd_config_t **dst, snd_config_t *root, snd_config_t *src, void *private_data)
{ {
snd_config_t *n; snd_config_t *n;

View file

@ -10,8 +10,3 @@ all: libcontrol.la
INCLUDES=-I$(top_srcdir)/include INCLUDES=-I$(top_srcdir)/include
EXTRA_DIST = cards.conf
alsadir = $(datadir)/alsa
alsa_DATA = cards.conf