From: Jaroslav Kysela Date: Thu, 21 Jun 2001 13:41:50 +0000 (+0000) Subject: Added snd_config_hook_load_for_all_cards. X-Git-Tag: v1.0.3~776 X-Git-Url: https://git.alsa-project.org/?a=commitdiff_plain;h=bc581b87ae47f1be0d62e47133bef33acbff1bb3;p=alsa-lib.git 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. --- diff --git a/configure.in b/configure.in index 7e9cc4cd..c88e558a 100644 --- a/configure.in +++ b/configure.in @@ -53,6 +53,7 @@ AC_OUTPUT(Makefile doc/Makefile include/Makefile src/Makefile \ 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) diff --git a/src/Makefile.am b/src/Makefile.am index a2f66141..6409d970 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -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@ 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) -EXTRA_DIST = alsa.conf - -alsadir = $(datadir)/alsa -alsa_DATA = alsa.conf - control/libcontrol.la: $(MAKE) -C control libcontrol.la diff --git a/src/conf.c b/src/conf.c index 459bd4a8..addb051a 100644 --- a/src/conf.c +++ b/src/conf.c @@ -51,17 +51,17 @@ struct filedesc { 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) @@ -123,12 +123,12 @@ static int get_char(input_t *input) 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) @@ -152,9 +152,21 @@ static int get_char_skip_comments(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; @@ -171,7 +183,7 @@ static int get_char_skip_comments(input_t *input) while (1) { c = get_char(input); if (c == EOF) - return c; + return LOCAL_UNEXPECTED_EOF; if (c == '\n') break; } @@ -246,6 +258,11 @@ static int get_freestring(char **string, int id, input_t *input) int c; while (1) { c = get_char(input); + if (c < 0) { + if (buf != _buf) + free(buf); + return c; + } switch (c) { case '.': if (!id) @@ -255,7 +272,6 @@ static int get_freestring(char **string, int id, input_t *input) case '\t': case '\n': case '\r': - case EOF: case '=': case ',': case ';': @@ -314,16 +330,13 @@ static int get_delimstring(char **string, int delim, input_t *input) 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) { @@ -362,12 +375,10 @@ static int get_delimstring(char **string, int delim, input_t *input) /* 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 ';': @@ -376,8 +387,7 @@ static int get_string(char **string, int id, input_t *input) case '}': case '[': case ']': - input->error = UNEXPECTED_CHAR; - return -EINVAL; + return LOCAL_UNEXPECTED_CHAR; case '\'': case '"': 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) return -ENOMEM; c = get_nonwhite(input); + if (c < 0) { + err = c; + goto __end; + } switch (c) { case '{': case '[': @@ -558,10 +572,13 @@ static int parse_array_def(snd_config_t *father, input_t *input, int idx) 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; @@ -584,10 +601,9 @@ static int parse_array_defs(snd_config_t *father, input_t *input) { 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; @@ -607,15 +623,15 @@ static int parse_def(snd_config_t *father, input_t *input) 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); @@ -650,8 +666,11 @@ static int parse_def(snd_config_t *father, input_t *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); @@ -691,8 +710,7 @@ static int parse_def(snd_config_t *father, input_t *input) 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; @@ -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) { + 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; @@ -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 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); @@ -919,8 +937,9 @@ 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.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); @@ -1022,40 +1041,32 @@ int snd_config_load(snd_config_t *config, snd_input_t *in) 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; } @@ -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) { - 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; \ ); @@ -1602,14 +1613,14 @@ static struct finfo { 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); @@ -1678,7 +1689,7 @@ static int snd_config_hooks_call(snd_config_t *root, snd_config_t *config) 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); @@ -1692,7 +1703,7 @@ static int snd_config_hooks_call(snd_config_t *root, snd_config_t *config) 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; @@ -1714,7 +1725,7 @@ static int snd_config_hooks(snd_config_t *config) 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++; @@ -1728,7 +1739,7 @@ static int snd_config_hooks(snd_config_t *config) 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; @@ -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"); 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; } @@ -1850,6 +1861,25 @@ int snd_config_hook_load(snd_config_t *root, snd_config_t *config, snd_config_t 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 @@ -1978,7 +2008,7 @@ int snd_config_update() 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; @@ -2796,7 +2826,9 @@ int snd_config_search_definition(snd_config_t *config, } 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); diff --git a/src/conf/Makefile.am b/src/conf/Makefile.am new file mode 100644 index 00000000..dfee749b --- /dev/null +++ b/src/conf/Makefile.am @@ -0,0 +1,8 @@ +SUBDIRS=cards pcm + +cfg_files = alsa.conf cards.conf + +EXTRA_DIST = $(cfg_files) + +alsadir = $(datadir)/alsa +alsa_DATA = $(cfg_files) diff --git a/src/conf/alsa.conf b/src/conf/alsa.conf new file mode 100644 index 00000000..8ff480eb --- /dev/null +++ b/src/conf/alsa.conf @@ -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 +} diff --git a/src/control/cards.conf b/src/conf/cards.conf similarity index 100% rename from src/control/cards.conf rename to src/conf/cards.conf diff --git a/src/cards/CMI8738.conf b/src/conf/cards/CMIPCI.conf similarity index 74% rename from src/cards/CMI8738.conf rename to src/conf/cards/CMIPCI.conf index 7d4dce17..60596c39 100644 --- a/src/cards/CMI8738.conf +++ b/src/conf/cards/CMIPCI.conf @@ -2,7 +2,7 @@ # Configuration for the CMIPCI chip # -cards.CMI8738.pcm.front.0 { +CMIPCI.pcm.front.0 { @args [ CARD ] @args.CARD { type string @@ -14,7 +14,7 @@ cards.CMI8738.pcm.front.0 { # 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 @@ -25,11 +25,11 @@ cards.CMI8738.pcm.rear.0 { } # 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 @@ -41,7 +41,7 @@ cards.CMI8738.pcm.surround40.0 { pcm { @func concat strings [ - "cards.CMI8738.pcm.front.0:CARD=" $CARD + "cards.CMIPCI.pcm.front.0:CARD=" $CARD ] } channels 2 @@ -50,7 +50,7 @@ cards.CMI8738.pcm.surround40.0 { pcm { @func concat strings [ - "cards.CMI8738.pcm.rear.0:CARD=" $CARD + "cards.CMIPCI.pcm.rear.0:CARD=" $CARD ] } 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 { type string @@ -86,18 +86,18 @@ cards.CMI8738.pcm.iec958.0 { 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 ] diff --git a/src/cards/EMU10K1.conf b/src/conf/cards/EMU10K1.conf similarity index 89% rename from src/cards/EMU10K1.conf rename to src/conf/cards/EMU10K1.conf index b1b916cd..e7da311b 100644 --- a/src/cards/EMU10K1.conf +++ b/src/conf/cards/EMU10K1.conf @@ -2,7 +2,9 @@ # Configuration for the EMU10K1 chip # -cards.EMU10K1.pcm.front.0 { + + +EMU10K1.pcm.front.0 { @args [ CARD ] @args.CARD { type string @@ -12,7 +14,9 @@ cards.EMU10K1.pcm.front.0 { device 0 } -cards.EMU10K1.pcm.rear.0 { + + +EMU10K1.pcm.rear.0 { @args [ CARD ] @args.CARD { type string @@ -42,7 +46,9 @@ cards.EMU10K1.pcm.rear.0 { } } -cards.EMU10K1.pcm.center_lfe.0 { + + +EMU10K1.pcm.center_lfe.0 { @args [ CARD ] @args.CARD { type string @@ -84,7 +90,9 @@ cards.EMU10K1.pcm.center_lfe.0 { } } -cards.EMU10K1.pcm.surround40.0 { + + +EMU10K1.pcm.surround40.0 { @args [ CARD ] @args.CARD { type string @@ -118,7 +126,9 @@ cards.EMU10K1.pcm.surround40.0 { ] } -cards.EMU10K1.pcm.surround51.0 { + + +EMU10K1.pcm.surround51.0 { @args [ CARD ] @args.CARD { type string @@ -163,7 +173,9 @@ cards.EMU10K1.pcm.surround51.0 { ] } -cards.EMU10K1.pcm.iec958.0 { + + +EMU10K1.pcm.iec958.0 { @args [ CARD DEV AES0 AES1 AES2 AES3 ] @args.CARD { type string diff --git a/src/cards/ENS1370.conf b/src/conf/cards/ENS1370.conf similarity index 85% rename from src/cards/ENS1370.conf rename to src/conf/cards/ENS1370.conf index 0f78be82..7a803f63 100644 --- a/src/cards/ENS1370.conf +++ b/src/conf/cards/ENS1370.conf @@ -2,7 +2,9 @@ # Configuration for the ENS1370 chip # -cards.ENS1370.pcm.front.0 { + + +ENS1370.pcm.front.0 { @args [ CARD ] @args.CARD { type string @@ -12,7 +14,9 @@ cards.ENS1370.pcm.front.0 { device 1 } -cards.ENS1370.pcm.rear.0 { + + +ENS1370.pcm.rear.0 { @args [ CARD ] @args.CARD { type string @@ -42,7 +46,9 @@ cards.ENS1370.pcm.rear.0 { } } -cards.ENS1370.pcm.surround40.0 { + + +ENS1370.pcm.surround40.0 { @args [ CARD ] @args.CARD { type string diff --git a/src/cards/FM801.conf b/src/conf/cards/FM801.conf similarity index 71% rename from src/cards/FM801.conf rename to src/conf/cards/FM801.conf index fe2862f7..3d5f5b2d 100644 --- a/src/cards/FM801.conf +++ b/src/conf/cards/FM801.conf @@ -2,7 +2,9 @@ # Configuration for the FM801 chip # -cards.FM801.pcm.front.0 { + + +FM801.pcm.front.0 { @args [ CARD ] @args.CARD { type string @@ -12,10 +14,17 @@ cards.FM801.pcm.front.0 { device 0 } -cards.FM801.pcm.surround40.0 "cards.FM801.pcm.front.0" -cards.FM801.pcm.surround51.0 "cards.FM801.pcm.front.0" + + +FM801.pcm.surround40.0 "cards.FM801.pcm.front.0" + + + +FM801.pcm.surround51.0 "cards.FM801.pcm.front.0" + + -cards.FM801.pcm.iec958.0 { +FM801.pcm.iec958.0 { @args [ CARD DEV AES0 AES1 AES2 AES3 ] @args.CARD { type string diff --git a/src/cards/ICE1712.conf b/src/conf/cards/ICE1712.conf similarity index 80% rename from src/cards/ICE1712.conf rename to src/conf/cards/ICE1712.conf index 51d814f4..efc30f2e 100644 --- a/src/cards/ICE1712.conf +++ b/src/conf/cards/ICE1712.conf @@ -2,7 +2,9 @@ # Configuration for the ICE1712 (Envy24) chip # -cards.ICE1712.pcm.front.0 { + + +ICE1712.pcm.front.0 { @args [ CARD ] @args.CARD { type string @@ -16,7 +18,9 @@ cards.ICE1712.pcm.front.0 { } } -cards.ICE1712.pcm.surround40.0 { + + +ICE1712.pcm.surround40.0 { @args [ CARD ] @args.CARD { type string @@ -32,7 +36,9 @@ cards.ICE1712.pcm.surround40.0 { } } -cards.ICE1712.pcm.surround51.0 { + + +ICE1712.pcm.surround51.0 { @args [ CARD ] @args.CARD { type string @@ -50,7 +56,9 @@ cards.ICE1712.pcm.surround51.0 { } } -cards.ICE1712.pcm.iec958.0 { + + +ICE1712.pcm.iec958.0 { @args [ CARD DEV AES0 AES1 AES2 AES3 ] @args.CARD { type string @@ -72,13 +80,10 @@ cards.ICE1712.pcm.iec958.0 { } 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 diff --git a/src/cards/INTEL8X0.conf b/src/conf/cards/INTEL8X0.conf similarity index 71% rename from src/cards/INTEL8X0.conf rename to src/conf/cards/INTEL8X0.conf index 9628d09c..3f2a1ce9 100644 --- a/src/cards/INTEL8X0.conf +++ b/src/conf/cards/INTEL8X0.conf @@ -2,7 +2,9 @@ # Configuration for the INTEL8X0 chip # -cards.INTEL8X0.pcm.front.0 { + + +INTEL8X0.pcm.front.0 { @args [ CARD ] @args.CARD { type string @@ -12,32 +14,13 @@ cards.INTEL8X0.pcm.front.0 { 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 } - ] -} + -cards.INTEL8X0.pcm.surround51.0 { +INTEL8X0.pcm.surround40.0 "cards.INTEL8X0.pcm.front.0" + + + +INTEL8X0.pcm.surround51.0 { @args [ CARD ] @args.CARD { type string @@ -51,7 +34,7 @@ cards.INTEL8X0.pcm.surround51.0 { "cards.INTEL8X0.pcm.front.0:CARD=" $CARD ] } - channels 2 + channels 6 } ] bindings [ @@ -64,7 +47,9 @@ cards.INTEL8X0.pcm.surround51.0 { ] } -cards.INTEL8X0.pcm.iec958.0 { + + +INTEL8X0.pcm.iec958.0 { @args [ CARD DEV AES0 AES1 AES2 AES3 ] @args.CARD { type string diff --git a/src/cards/Makefile.am b/src/conf/cards/Makefile.am similarity index 69% rename from src/cards/Makefile.am rename to src/conf/cards/Makefile.am index be76cb70..08391033 100644 --- a/src/cards/Makefile.am +++ b/src/conf/cards/Makefile.am @@ -1,6 +1,6 @@ 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) diff --git a/src/cards/SI_7018.conf b/src/conf/cards/SI_7018.conf similarity index 84% rename from src/cards/SI_7018.conf rename to src/conf/cards/SI_7018.conf index 73e1433c..ebf8461a 100644 --- a/src/cards/SI_7018.conf +++ b/src/conf/cards/SI_7018.conf @@ -2,7 +2,9 @@ # Configuration for the SI7018 chip # -cards.SI_7018.pcm.front.0 { + + +SI_7018.pcm.front.0 { @args [ CARD ] @args.CARD { type string @@ -12,7 +14,9 @@ cards.SI_7018.pcm.front.0 { device 0 } -cards.SI_7018.pcm.rear.0 { + + +SI_7018.pcm.rear.0 { @args [ CARD ] @args.CARD { type string @@ -36,7 +40,9 @@ cards.SI_7018.pcm.rear.0 { } } -cards.SI_7018.pcm.surround40.0 { + + +SI_7018.pcm.surround40.0 { @args [ CARD ] @args.CARD { type string diff --git a/src/cards/TRID4DWAVENX.conf b/src/conf/cards/TRID4DWAVENX.conf similarity index 87% rename from src/cards/TRID4DWAVENX.conf rename to src/conf/cards/TRID4DWAVENX.conf index 7b4f4e49..e17e07f1 100644 --- a/src/cards/TRID4DWAVENX.conf +++ b/src/conf/cards/TRID4DWAVENX.conf @@ -2,7 +2,9 @@ # Configuration for the Trident 4D-Wave NX chip # -cards.TRID4DWAVENX.pcm.front.0 { + + +TRID4DWAVENX.pcm.front.0 { @args [ CARD ] @args.CARD { type string @@ -12,7 +14,9 @@ cards.TRID4DWAVENX.pcm.front.0 { device 0 } -cards.TRID4DWAVENX.pcm.rear.0 { + + +TRID4DWAVENX.pcm.rear.0 { @args [ CARD ] @args.CARD { type string @@ -50,7 +54,9 @@ cards.TRID4DWAVENX.pcm.rear.0 { } } -cards.TRID4DWAVENX.pcm.surround40.0 { + + +TRID4DWAVENX.pcm.surround40.0 { @args [ CARD ] @args.CARD { type string @@ -84,7 +90,9 @@ cards.TRID4DWAVENX.pcm.surround40.0 { ] } -cards.TRID4DWAVENX.pcm.iec958.0 { + + +TRID4DWAVENX.pcm.iec958.0 { @args [ CARD AES0 AES1 AES2 AES3 ] @args.CARD { type string diff --git a/src/cards/YMFPCI.conf b/src/conf/cards/YMFPCI.conf similarity index 84% rename from src/cards/YMFPCI.conf rename to src/conf/cards/YMFPCI.conf index cd9dbf19..9cba3800 100644 --- a/src/cards/YMFPCI.conf +++ b/src/conf/cards/YMFPCI.conf @@ -2,7 +2,9 @@ # Configuration for the YMFPCI chip # -cards.YMFPCI.pcm.front.0 { + + +YMFPCI.pcm.front.0 { @args [ CARD ] @args.CARD { type string @@ -12,7 +14,9 @@ cards.YMFPCI.pcm.front.0 { device 0 } -cards.YMFPCI.pcm.rear.0 { + + +YMFPCI.pcm.rear.0 { @args [ CARD ] @args.CARD { type string @@ -22,7 +26,9 @@ cards.YMFPCI.pcm.rear.0 { device 2 } -cards.YMFPCI.pcm.surround40.0 { + + +YMFPCI.pcm.surround40.0 { @args [ CARD ] @args.CARD { type string @@ -56,7 +62,9 @@ cards.YMFPCI.pcm.surround40.0 { ] } -cards.YMFPCI.pcm.iec958.0 { + + +YMFPCI.pcm.iec958.0 { @args [ CARD DEV AES0 AES1 AES2 AES3 ] @args.CARD { type string diff --git a/src/conf/pcm/Makefile.am b/src/conf/pcm/Makefile.am new file mode 100644 index 00000000..f611cb6c --- /dev/null +++ b/src/conf/pcm/Makefile.am @@ -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) diff --git a/src/conf/pcm/center_lfe.conf b/src/conf/pcm/center_lfe.conf new file mode 100644 index 00000000..7ab08f71 --- /dev/null +++ b/src/conf/pcm/center_lfe.conf @@ -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 + ] + } +} diff --git a/src/conf/pcm/front.conf b/src/conf/pcm/front.conf new file mode 100644 index 00000000..73cad08a --- /dev/null +++ b/src/conf/pcm/front.conf @@ -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 + ] + } +} diff --git a/src/conf/pcm/rear.conf b/src/conf/pcm/rear.conf new file mode 100644 index 00000000..85ad8ec4 --- /dev/null +++ b/src/conf/pcm/rear.conf @@ -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 + ] + } +} diff --git a/src/conf/pcm/surround40.conf b/src/conf/pcm/surround40.conf new file mode 100644 index 00000000..3368af77 --- /dev/null +++ b/src/conf/pcm/surround40.conf @@ -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 + ] + } +} diff --git a/src/conf/pcm/surround51.conf b/src/conf/pcm/surround51.conf new file mode 100644 index 00000000..fc66f7a3 --- /dev/null +++ b/src/conf/pcm/surround51.conf @@ -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 + ] + } +} diff --git a/src/confmisc.c b/src/confmisc.c index 78ab85ba..b6b05a34 100644 --- a/src/confmisc.c +++ b/src/confmisc.c @@ -428,39 +428,16 @@ static int string_from_integer(char **dst, long v) } #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); @@ -487,6 +464,38 @@ int snd_func_card_strtype(snd_config_t **dst, snd_config_t *root, snd_config_t * 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; diff --git a/src/control/Makefile.am b/src/control/Makefile.am index 0b28efcd..48bd6464 100644 --- a/src/control/Makefile.am +++ b/src/control/Makefile.am @@ -10,8 +10,3 @@ all: libcontrol.la INCLUDES=-I$(top_srcdir)/include - -EXTRA_DIST = cards.conf - -alsadir = $(datadir)/alsa -alsa_DATA = cards.conf