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.
src/control/Makefile src/mixer/Makefile src/pcm/Makefile \
src/rawmidi/Makefile src/timer/Makefile \
src/hwdep/Makefile src/seq/Makefile src/instr/Makefile \
- src/compat/Makefile src/cards/Makefile aserver/Makefile \
- test/Makefile utils/Makefile \
+ src/compat/Makefile src/conf/Makefile \
+ src/conf/cards/Makefile src/conf/pcm/Makefile \
+ aserver/Makefile test/Makefile utils/Makefile \
utils/alsa-lib.spec)
-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@
lib_LTLIBRARIES = libasound.la
libasound_la_LDFLAGS = -version-info $(COMPATNUM)
-EXTRA_DIST = alsa.conf
-
-alsadir = $(datadir)/alsa
-alsa_DATA = alsa.conf
-
control/libcontrol.la:
$(MAKE) -C control libcontrol.la
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 {
struct filedesc *current;
int unget;
int ch;
- enum {
- UNTERMINATED_STRING = -1,
- UNTERMINATED_QUOTE = -2,
- UNEXPECTED_CHAR = -3,
- UNEXPECTED_EOF = -4,
- BAD_ENV_DEFAULT = -5,
- } error;
} input_t;
int safe_strtol(const char *str, long *val)
free(fd);
goto again;
}
- break;
+ return LOCAL_UNEXPECTED_EOF;
default:
fd->column++;
break;
}
- return c;
+ return (unsigned char)c;
}
static void unget_char(int c, input_t *input)
int err = get_delimstring(&str, '>', input);
if (err < 0)
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");
- if (err < 0)
+ if (err < 0) {
+ free(str);
return err;
+ }
fd = malloc(sizeof(*fd));
if (!fd)
return -ENOMEM;
while (1) {
c = get_char(input);
if (c == EOF)
- return c;
+ return LOCAL_UNEXPECTED_EOF;
if (c == '\n')
break;
}
int c;
while (1) {
c = get_char(input);
+ if (c < 0) {
+ if (buf != _buf)
+ free(buf);
+ return c;
+ }
switch (c) {
case '.':
if (!id)
case '\t':
case '\n':
case '\r':
- case EOF:
case '=':
case ',':
case ';':
int c;
while (1) {
c = get_char(input);
+ if (c < 0)
+ return c;
switch (c) {
- case EOF:
- input->error = UNTERMINATED_STRING;
- return -EINVAL;
case '\\':
c = get_quotedchar(input);
- if (c < 0) {
- input->error = UNTERMINATED_QUOTE;
- return -EINVAL;
- }
+ if (c < 0)
+ return c;
break;
default:
if (c == delim) {
/* Return 0 for free string, 1 for delimited string */
static int get_string(char **string, int id, input_t *input)
{
- int c = get_nonwhite(input);
- int err;
+ int c = get_nonwhite(input), err;
+ if (c < 0)
+ return c;
switch (c) {
- case EOF:
- input->error = UNEXPECTED_EOF;
- return -EINVAL;
case '=':
case ',':
case ';':
case '}':
case '[':
case ']':
- input->error = UNEXPECTED_CHAR;
- return -EINVAL;
+ return LOCAL_UNEXPECTED_CHAR;
case '\'':
case '"':
err = get_delimstring(string, c, input);
if (id == NULL)
return -ENOMEM;
c = get_nonwhite(input);
+ if (c < 0) {
+ err = c;
+ goto __end;
+ }
switch (c) {
case '{':
case '[':
endchr = ']';
}
c = get_nonwhite(input);
+ if (c < 0) {
+ err = c;
+ goto __end;
+ }
if (c != endchr) {
snd_config_delete(n);
- input->error = (c == EOF ? UNEXPECTED_EOF : UNEXPECTED_CHAR);
- err = -EINVAL;
+ err = LOCAL_UNEXPECTED_CHAR;
goto __end;
}
break;
{
int idx = 0;
while (1) {
- int c = get_nonwhite(input);
- int err;
- if (c == EOF)
- return 0;
+ int c = get_nonwhite(input), err;
+ if (c < 0)
+ return c;
unget_char(c, input);
if (c == ']')
return 0;
enum {MERGE, NOCREATE, REMOVE} mode;
while (1) {
c = get_nonwhite(input);
+ if (c < 0)
+ return c;
switch (c) {
-#if 0
case '?':
mode = NOCREATE;
break;
case '!':
mode = REMOVE;
break;
-#endif
default:
mode = MERGE;
unget_char(c, input);
n->u.compound.join = 1;
father = n;
}
- if (c == '=')
+ if (c == '=') {
c = get_nonwhite(input);
+ if (c < 0)
+ return c;
+ }
if (_snd_config_search(father, id, -1, &n) == 0) {
if (mode == REMOVE) {
snd_config_delete(n);
c = get_nonwhite(input);
if (c != endchr) {
snd_config_delete(n);
- input->error = (c == EOF ? UNEXPECTED_EOF : UNEXPECTED_CHAR);
- err = -EINVAL;
+ err = LOCAL_UNEXPECTED_CHAR;
goto __end;
}
break;
static int parse_defs(snd_config_t *father, input_t *input)
{
+ int c, err;
while (1) {
- int c = get_nonwhite(input);
- int err;
- if (c == EOF)
- return 0;
+ c = get_nonwhite(input);
+ if (c < 0)
+ return c == LOCAL_UNEXPECTED_EOF ? 0 : c;
unget_char(c, input);
if (c == '}')
return 0;
/**
* \brief Substitute one node to another
* \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)
{
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_for_each(i, next, src) {
snd_config_t *n = snd_config_iterator_entry(i);
src->u.compound.fields.next->prev = &dst->u.compound.fields;
src->u.compound.fields.prev->next = &dst->u.compound.fields;
}
- free(dst->id);
- dst->id = src->id;
+ if (dst->id)
+ free(dst->id);
+ dst->id = src->id;
dst->type = src->type;
dst->u = src->u;
free(src);
fd->next = NULL;
input.current = fd;
input.unget = 0;
- input.error = 0;
err = parse_defs(config, &input);
fd = input.current;
if (err < 0) {
- if (input.error < 0) {
- const char *str;
- switch (input.error) {
- case UNTERMINATED_STRING:
- str = "Unterminated string";
- break;
- case UNTERMINATED_QUOTE:
- str = "Unterminated quote";
- break;
- case UNEXPECTED_CHAR:
- str = "Unexpected char";
- break;
- case UNEXPECTED_EOF:
- str = "Unexpected end of file";
- break;
- case BAD_ENV_DEFAULT:
- str = "Bad environment default value";
- break;
- default:
- assert(0);
- break;
- }
- SNDERR("%s:%d:%d:%s", fd->name ? fd->name : "_toplevel_",
- fd->line, fd->column, str);
+ const char *str;
+ switch (err) {
+ case LOCAL_UNTERMINATED_STRING:
+ str = "Unterminated string";
+ break;
+ case LOCAL_UNTERMINATED_QUOTE:
+ str = "Unterminated quote";
+ break;
+ case LOCAL_UNEXPECTED_CHAR:
+ str = "Unexpected char";
+ break;
+ case LOCAL_UNEXPECTED_EOF:
+ str = "Unexpected end of file";
+ break;
+ default:
+ str = strerror(-err);
+ break;
}
+ SNDERR("%s:%d:%d:%s", fd->name ? fd->name : "_toplevel_", fd->line, fd->column, str);
goto _end;
}
- if (get_char(&input) != EOF) {
- SNDERR("%s:%d:%d:Unexpected }", fd->name ? fd->name : "",
- fd->line, fd->column);
+ if (get_char(&input) != LOCAL_UNEXPECTED_EOF) {
+ SNDERR("%s:%d:%d:Unexpected }", fd->name ? fd->name : "", fd->line, fd->column);
err = -EINVAL;
goto _end;
}
*/
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, \
- err = snd_config_hooks(config); \
+ err = snd_config_hooks(config, NULL); \
if (err < 0) \
return err; \
);
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;
snd_config_t *c, *func_conf = NULL;
char *buf = NULL;
const char *lib = NULL, *func_name = NULL;
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;
err = snd_config_search(config, "func", &c);
snd_config_delete(func_conf);
if (err >= 0) {
snd_config_t *nroot;
- err = func(root, config, &nroot);
+ err = func(root, config, &nroot, private_data);
if (err < 0)
SNDERR("function %s returned error: %s", func_name, snd_strerror(err));
dlclose(h);
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_iterator_t i, next;
goto _err;
}
if (i == idx) {
- err = snd_config_hooks_call(config, n);
+ err = snd_config_hooks_call(config, n, private_data);
if (err < 0)
return err;
idx++;
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_iterator_t i, next;
SNDERR("Unable to find field files in the preload section");
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");
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
* environment variable ALSA_CONFIG_PATH. If it's not set the default value is
SNDERR("cannot access file %s", fi[k].name);
}
}
- err = snd_config_hooks(snd_config);
+ err = snd_config_hooks(snd_config, NULL);
if (err < 0) {
SNDERR("hooks failed, removing configuration");
goto _end;
} else {
key = (char *) name;
}
- err = snd_config_search_alias_hooks(config, base, key, &conf);
+ err = snd_config_search_alias_hooks(config, NULL, key, &conf);
+ if (err < 0)
+ err = snd_config_search_alias_hooks(config, base, key, &conf);
if (err < 0)
return err;
return snd_config_expand(conf, config, args, NULL, result);
--- /dev/null
+SUBDIRS=cards pcm
+
+cfg_files = alsa.conf cards.conf
+
+EXTRA_DIST = $(cfg_files)
+
+alsadir = $(datadir)/alsa
+alsa_DATA = $(cfg_files)
--- /dev/null
+#
+# 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
+}
# Configuration for the CMIPCI chip
#
-cards.CMI8738.pcm.front.0 {
+CMIPCI.pcm.front.0 {
@args [ CARD ]
@args.CARD {
type string
# 2nd DAC
# FIXME: we need a volume attenuator for rear channel.
-cards.CMI8738.pcm.rear.0 {
+CMIPCI.pcm.rear.0 {
@args [ CARD ]
@args.CARD {
type string
}
# for the recent CM8738 chips
-# cards.CMI8738.pcm.surround40.0 "cards.CMI8738.pcm.front.0"
-cards.CMI8738.pcm.surround51.0 "cards.CMI8738.pcm.front.0"
+# cards.CMIPCI.pcm.surround40.0 "cards.CMIPCI.pcm.front.0"
+CMIPCI.pcm.surround51.0 "cards.CMIPCI.pcm.front.0"
# for the old CM8738 with 2nd DAC for rear
-cards.CMI8738.pcm.surround40.0 {
+CMIPCI.pcm.surround40.0 {
@args [ CARD ]
@args.CARD {
type string
pcm {
@func concat
strings [
- "cards.CMI8738.pcm.front.0:CARD=" $CARD
+ "cards.CMIPCI.pcm.front.0:CARD=" $CARD
]
}
channels 2
pcm {
@func concat
strings [
- "cards.CMI8738.pcm.rear.0:CARD=" $CARD
+ "cards.CMIPCI.pcm.rear.0:CARD=" $CARD
]
}
channels 2
}
-cards.CMI8738.pcm.iec958.0 {
+CMIPCI.pcm.iec958.0 {
@args [ CARD DEV AES0 AES1 AES2 AES3 ]
@args.CARD {
type string
type integer
}
type hooks
- slave.pcm {
- type hw
- card $CARD
- device 2
- }
hooks.0 {
type ctl_elems
hook_args [
+ {
+ name "IEC958 Enable"
+ value 1
+ lock true
+ preserve true
+ }
{
interface PCM
name "IEC958 Playback PCM Stream"
- device 2
lock true
preserve true
value [ $AES0 $AES1 $AES2 $AES3 ]
# Configuration for the EMU10K1 chip
#
-cards.EMU10K1.pcm.front.0 {
+<confdir:pcm/front.conf>
+
+EMU10K1.pcm.front.0 {
@args [ CARD ]
@args.CARD {
type string
device 0
}
-cards.EMU10K1.pcm.rear.0 {
+<confdir:pcm/rear.conf>
+
+EMU10K1.pcm.rear.0 {
@args [ CARD ]
@args.CARD {
type string
}
}
-cards.EMU10K1.pcm.center_lfe.0 {
+<confdir:pcm/center_lfe.conf>
+
+EMU10K1.pcm.center_lfe.0 {
@args [ CARD ]
@args.CARD {
type string
}
}
-cards.EMU10K1.pcm.surround40.0 {
+<confdir:pcm/surround40.conf>
+
+EMU10K1.pcm.surround40.0 {
@args [ CARD ]
@args.CARD {
type string
]
}
-cards.EMU10K1.pcm.surround51.0 {
+<confdir:pcm/surround51.conf>
+
+EMU10K1.pcm.surround51.0 {
@args [ CARD ]
@args.CARD {
type string
]
}
-cards.EMU10K1.pcm.iec958.0 {
+<confdir:pcm/iec958.conf>
+
+EMU10K1.pcm.iec958.0 {
@args [ CARD DEV AES0 AES1 AES2 AES3 ]
@args.CARD {
type string
# Configuration for the ENS1370 chip
#
-cards.ENS1370.pcm.front.0 {
+<confdir:pcm/front.conf>
+
+ENS1370.pcm.front.0 {
@args [ CARD ]
@args.CARD {
type string
device 1
}
-cards.ENS1370.pcm.rear.0 {
+<confdir:pcm/rear.conf>
+
+ENS1370.pcm.rear.0 {
@args [ CARD ]
@args.CARD {
type string
}
}
-cards.ENS1370.pcm.surround40.0 {
+<confdir:pcm/surround40.conf>
+
+ENS1370.pcm.surround40.0 {
@args [ CARD ]
@args.CARD {
type string
# Configuration for the FM801 chip
#
-cards.FM801.pcm.front.0 {
+<confdir:pcm/front.conf>
+
+FM801.pcm.front.0 {
@args [ CARD ]
@args.CARD {
type string
device 0
}
-cards.FM801.pcm.surround40.0 "cards.FM801.pcm.front.0"
-cards.FM801.pcm.surround51.0 "cards.FM801.pcm.front.0"
+<confdir:pcm/surround40.conf>
+
+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>
-cards.FM801.pcm.iec958.0 {
+FM801.pcm.iec958.0 {
@args [ CARD DEV AES0 AES1 AES2 AES3 ]
@args.CARD {
type string
# Configuration for the ICE1712 (Envy24) chip
#
-cards.ICE1712.pcm.front.0 {
+<confdir:pcm/front.conf>
+
+ICE1712.pcm.front.0 {
@args [ CARD ]
@args.CARD {
type string
}
}
-cards.ICE1712.pcm.surround40.0 {
+<confdir:pcm/surround40.conf>
+
+ICE1712.pcm.surround40.0 {
@args [ CARD ]
@args.CARD {
type string
}
}
-cards.ICE1712.pcm.surround51.0 {
+<confdir:pcm/surround51.conf>
+
+ICE1712.pcm.surround51.0 {
@args [ CARD ]
@args.CARD {
type string
}
}
-cards.ICE1712.pcm.iec958.0 {
+<confdir:pcm/iec958.conf>
+
+ICE1712.pcm.iec958.0 {
@args [ CARD DEV AES0 AES1 AES2 AES3 ]
@args.CARD {
type string
}
type hooks
slave.pcm {
- type route
+ type plug
ttable.0.8 1
ttable.1.9 1
- slave.pcm {
- type hw
- card $CARD
- }
+ card $CARD
}
hooks.0 {
type ctl_elems
# Configuration for the INTEL8X0 chip
#
-cards.INTEL8X0.pcm.front.0 {
+<confdir:pcm/front.conf>
+
+INTEL8X0.pcm.front.0 {
@args [ CARD ]
@args.CARD {
type string
device 0
}
-cards.INTEL8X0.pcm.surround40.0 {
- @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 }
- ]
-}
+<confdir:pcm/surround40.conf>
-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 {
type string
"cards.INTEL8X0.pcm.front.0:CARD=" $CARD
]
}
- channels 2
+ channels 6
}
]
bindings [
]
}
-cards.INTEL8X0.pcm.iec958.0 {
+<confdir:pcm/iec958.conf>
+
+INTEL8X0.pcm.iec958.0 {
@args [ CARD DEV AES0 AES1 AES2 AES3 ]
@args.CARD {
type string
alsadir = $(datadir)/alsa/cards
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)
alsa_DATA = $(cfg_files)
# Configuration for the SI7018 chip
#
-cards.SI_7018.pcm.front.0 {
+<confdir:pcm/front.conf>
+
+SI_7018.pcm.front.0 {
@args [ CARD ]
@args.CARD {
type string
device 0
}
-cards.SI_7018.pcm.rear.0 {
+<confdir:pcm/rear.conf>
+
+SI_7018.pcm.rear.0 {
@args [ CARD ]
@args.CARD {
type string
}
}
-cards.SI_7018.pcm.surround40.0 {
+<confdir:pcm/surround40.conf>
+
+SI_7018.pcm.surround40.0 {
@args [ CARD ]
@args.CARD {
type string
# 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 {
type string
device 0
}
-cards.TRID4DWAVENX.pcm.rear.0 {
+<confdir:pcm/rear.conf>
+
+TRID4DWAVENX.pcm.rear.0 {
@args [ CARD ]
@args.CARD {
type string
}
}
-cards.TRID4DWAVENX.pcm.surround40.0 {
+<confdir:pcm/surround40.conf>
+
+TRID4DWAVENX.pcm.surround40.0 {
@args [ CARD ]
@args.CARD {
type string
]
}
-cards.TRID4DWAVENX.pcm.iec958.0 {
+<confdir:pcm/iec958.conf>
+
+TRID4DWAVENX.pcm.iec958.0 {
@args [ CARD AES0 AES1 AES2 AES3 ]
@args.CARD {
type string
# Configuration for the YMFPCI chip
#
-cards.YMFPCI.pcm.front.0 {
+<confdir:pcm/front.conf>
+
+YMFPCI.pcm.front.0 {
@args [ CARD ]
@args.CARD {
type string
device 0
}
-cards.YMFPCI.pcm.rear.0 {
+<confdir:pcm/rear.conf>
+
+YMFPCI.pcm.rear.0 {
@args [ CARD ]
@args.CARD {
type string
device 2
}
-cards.YMFPCI.pcm.surround40.0 {
+<confdir:pcm/surround40.conf>
+
+YMFPCI.pcm.surround40.0 {
@args [ CARD ]
@args.CARD {
type string
]
}
-cards.YMFPCI.pcm.iec958.0 {
+<confdir:pcm/iec958.conf>
+
+YMFPCI.pcm.iec958.0 {
@args [ CARD DEV AES0 AES1 AES2 AES3 ]
@args.CARD {
type string
--- /dev/null
+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)
--- /dev/null
+#
+# 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
+ ]
+ }
+}
--- /dev/null
+#
+# 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
+ ]
+ }
+}
--- /dev/null
+#
+# 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
+ ]
+ }
+}
--- /dev/null
+#
+# 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
+ ]
+ }
+}
--- /dev/null
+#
+# 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
+ ]
+ }
+}
}
#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 *str;
snd_ctl_t *ctl = NULL;
snd_ctl_card_info_t *info;
long v;
int err;
- err = snd_config_search(src, "card", &n);
- if (err < 0) {
- 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);
+ v = (long)private_data;
+ assert(v >= 0 && v <= 32);
err = open_ctl(v, &ctl);
if (err < 0) {
SNDERR("could not open control for card %li", v);
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)
{
snd_config_t *n;
INCLUDES=-I$(top_srcdir)/include
-
-EXTRA_DIST = cards.conf
-
-alsadir = $(datadir)/alsa
-alsa_DATA = cards.conf