slave.pcm {
type hw
card {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_PCM_CARD
ALSA_CARD
default 0
}
device {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_PCM_DEVICE
]
@args.CARD {
type integer
default {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_FRONT_CARD
ALSA_PCM_CARD
@args.DEV {
type integer
default {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_FRONT_DEVICE
]
default 0
}
}
- @refer {
- filename {
- @func concat
- strings [
- {
- @func datadir
- }
- "/cards/"
- {
- @func card_strtype
- card $(CARD)
- }
- ".conf"
- ]
- }
- name {
- @func concat
- strings [
- "pcm.front_" $(DEV) ":CARD=" $(CARD)
- ]
- }
+ @func refer
+ file {
+ @func concat
+ strings [
+ {
+ @func datadir
+ }
+ "/cards/"
+ {
+ @func card_strtype
+ card $(CARD)
+ }
+ ".conf"
+ ]
+ }
+ name {
+ @func concat
+ strings [
+ "pcm.front_" $(DEV) ":CARD=" $(CARD)
+ ]
}
}
@args.CARD {
type integer
default {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_REAR_CARD
ALSA_PCM_CARD
@args.DEV {
type integer
default {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_REAR_DEVICE
]
default 0
}
}
- @refer {
- filename {
- @func concat
- strings [
- {
- @func datadir
- }
- "/cards/"
- {
- @func card_strtype
- card $(CARD)
- }
- ".conf"
- ]
- }
- name {
- @func concat
- strings [
- "pcm.rear_" $(DEV) ":CARD=" $(CARD)
- ]
- }
+ @func refer
+ file {
+ @func concat
+ strings [
+ {
+ @func datadir
+ }
+ "/cards/"
+ {
+ @func card_strtype
+ card $(CARD)
+ }
+ ".conf"
+ ]
+ }
+ name {
+ @func concat
+ strings [
+ "pcm.rear_" $(DEV) ":CARD=" $(CARD)
+ ]
}
}
@args.CARD {
type integer
default {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_CENTER_LFE_CARD
ALSA_PCM_CARD
@args.DEV {
type integer
default {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_CENTER_LFE_DEVICE
]
default 0
}
}
- @refer {
- filename {
- @func concat
- strings [
- {
- @func datadir
- }
- "/cards/"
- {
- @func card_strtype
- card $(CARD)
- }
- ".conf"
- ]
- }
- name {
- @func concat
- strings [
- "pcm.center_lfe_" $(DEV) ":CARD=" $(CARD)
- ]
- }
+ @func refer
+ file {
+ @func concat
+ strings [
+ {
+ @func datadir
+ }
+ "/cards/"
+ {
+ @func card_strtype
+ card $(CARD)
+ }
+ ".conf"
+ ]
+ }
+ name {
+ @func concat
+ strings [
+ "pcm.center_lfe_" $(DEV) ":CARD=" $(CARD)
+ ]
}
}
@args.CARD {
type integer
default {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_SURROUND40_CARD
ALSA_PCM_CARD
@args.DEV {
type integer
default {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_SURROUND40_DEVICE
]
default 0
}
}
- @refer {
- filename {
- @func concat
- strings [
- {
- @func datadir
- }
- "/cards/"
- {
- @func card_strtype
- card $(CARD)
- }
- ".conf"
- ]
- }
- name {
- @func concat
- strings [
- "pcm.surround40_" $(DEV) ":CARD=" $(CARD)
- ]
- }
+ @func refer
+ file {
+ @func concat
+ strings [
+ {
+ @func datadir
+ }
+ "/cards/"
+ {
+ @func card_strtype
+ card $(CARD)
+ }
+ ".conf"
+ ]
+ }
+ name {
+ @func concat
+ strings [
+ "pcm.surround40_" $(DEV) ":CARD=" $(CARD)
+ ]
}
}
@args.CARD {
type integer
default {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_SURROUND51_CARD
ALSA_PCM_CARD
@args.DEV {
type integer
default {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_SURROUND51_DEVICE
]
default 0
}
}
- @refer {
- filename {
- @func concat
- strings [
- {
- @func datadir
- }
- "/cards/"
- {
- @func card_strtype
- card $(CARD)
- }
- ".conf"
- ]
- }
- name {
- @func concat
- strings [
- "pcm.surround51_" $(DEV) ":CARD=" $(CARD)
- ]
- }
+ @func refer
+ file {
+ @func concat
+ strings [
+ {
+ @func datadir
+ }
+ "/cards/"
+ {
+ @func card_strtype
+ card $(CARD)
+ }
+ ".conf"
+ ]
+ }
+ name {
+ @func concat
+ strings [
+ "pcm.surround51_" $(DEV) ":CARD=" $(CARD)
+ ]
}
}
@args.CARD {
type integer
default {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_IEC958_CARD
ALSA_PCM_CARD
@args.DEV {
type integer
default {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_IEC958_DEVICE
]
# fs=48000Hz, clock accuracy=1000ppm
default 0x02
}
- @refer {
- filename {
- @func concat
- strings [
- {
- @func datadir
- }
- "/cards/"
- {
- @func card_strtype
- card $(CARD)
- }
- ".conf"
- ]
- }
- name {
- @func concat
- strings [
- "pcm.iec958_" $(DEV) ":"
- "CARD=" $(CARD) ","
- "AES0=" $(AES0) ","
- "AES1=" $(AES1) ","
- "AES2=" $(AES2) ","
- "AES3=" $(AES3)
- ]
- }
+ @func refer
+ file {
+ @func concat
+ strings [
+ {
+ @func datadir
+ }
+ "/cards/"
+ {
+ @func card_strtype
+ card $(CARD)
+ }
+ ".conf"
+ ]
+ }
+ name {
+ @func concat
+ strings [
+ "pcm.iec958_" $(DEV) ":"
+ "CARD=" $(CARD) ","
+ "AES0=" $(AES0) ","
+ "AES1=" $(AES1) ","
+ "AES2=" $(AES2) ","
+ "AES3=" $(AES3)
+ ]
}
}
rawmidi.default {
type hw
card {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_RAWMIDI_CARD
ALSA_CARD
default 0
}
device {
- @func getenv
- @type integer
+ @func igetenv
envname [
ALSA_RAWMIDI_DEVICE
]
@args.CARD {
type integer
}
- @refer {
+ @func refer
+ name {
@func concat
strings [ "pcm.emu10k1_front:" $(CARD) ",0,-1" ]
}
@args.CARD {
type integer
}
- @refer {
+ @func refer
+ name {
@func concat
strings [ "pcm.emu10k1_rear:" $(CARD) ",0,-1" ]
}
@args.CARD {
type integer
}
- @refer {
+ @func refer
+ name {
@func concat
strings [ "pcm.emu10k1_center_lfe:" $(CARD) ",0,-1" ]
}
}
static int evaluate_node(snd_config_t *father, snd_config_t *src,
- void *private_data, snd_config_t **_dst)
+ void *private_data, snd_config_t **dst)
{
snd_config_iterator_t i, next;
- const char *lib = NULL, *func = NULL, *type = NULL;
+ const char *lib = NULL, *func = NULL;
int err;
+ char buf[64];
+ char *evaluate_name = NULL;
+ int (*evaluate_func)(snd_config_t **dst, snd_config_t *src, void *private_data);
+ void *h;
- assert(father && src && _dst);
+ assert(father && src && dst);
snd_config_for_each(i, next, src) {
snd_config_t *n = snd_config_iterator_entry(i);
if (func == NULL)
goto __error;
snd_config_delete(n);
- } else if (!strcmp(id, "type")) {
- if ((err = snd_config_get_string(n, &type)) < 0)
- goto _invalid_field;
- type = strdup(type);
- if (type == NULL)
- goto __error;
- snd_config_delete(n);
}
}
if (func == NULL) {
- *_dst = NULL;
+ *dst = NULL;
return 0;
}
- {
- char buf[64];
- snd_config_type_t t;
- snd_config_t *dst = NULL;
- char *evaluate_name = NULL;
- int (*evaluate_func)(snd_config_t **dst, snd_config_t *src, void *private_data);
- void *h;
-
- if (evaluate_name == NULL) {
- snprintf(buf, sizeof(buf), "snd_func_%s", func);
- buf[sizeof(buf)-1] = '\0';
- evaluate_name = buf;
- }
+ if (evaluate_name == NULL) {
+ snprintf(buf, sizeof(buf), "snd_func_%s", func);
+ buf[sizeof(buf) - 1] = '\0';
+ evaluate_name = buf;
+ }
- h = dlopen(lib, RTLD_NOW);
- if (!h) {
- SNDERR("Cannot open shared library %s", lib);
- err = -ENOENT;
- goto __error;
- }
- evaluate_func = dlsym(h, evaluate_name);
- if (!evaluate_func) {
- dlclose(h);
- SNDERR("symbol %s is not defined inside %s", evaluate_name, lib ? lib : ALSA_LIB);
- err = -ENXIO;
- goto __error;
- }
- err = evaluate_func(&dst, src, private_data);
+ h = dlopen(lib, RTLD_NOW);
+ if (!h) {
+ SNDERR("Cannot open shared library %s", lib);
+ err = -ENOENT;
+ goto __error;
+ }
+ evaluate_func = dlsym(h, evaluate_name);
+ if (!evaluate_func) {
dlclose(h);
- if (err < 0) {
- SNDERR("function %s returned error: %s", evaluate_name, snd_strerror(err));
- goto __error;
- }
- if (type == NULL) {
- t = SND_CONFIG_TYPE_STRING;
- } else {
- err = snd_config_get_type_ascii(type, &t);
- if (err < 0) {
- err = -EINVAL;
- __err:
- snd_config_delete(dst);
- goto __error;
- }
- }
- if (t != snd_config_get_type(dst)) {
- char *ptr;
- snd_config_t *n;
- if (t == SND_CONFIG_TYPE_COMPOUND) {
- SNDERR("conversion to compound is not supported for field %s", snd_config_get_id(src));
- err = -EINVAL;
- goto __err;
- }
- err = snd_config_make(&n, snd_config_get_id(dst), t);
- if (err < 0)
- goto __err;
- err = snd_config_get_ascii(dst, &ptr);
- if (err < 0) {
- __err1:
- snd_config_delete(n);
- goto __err;
- }
- switch (t) {
- case SND_CONFIG_TYPE_STRING:
- n->u.string = ptr;
- ptr = NULL;
- err = 0;
- break;
- case SND_CONFIG_TYPE_INTEGER:
- {
- long v;
- err = safe_strtol(ptr, &v);
- if (err >= 0)
- snd_config_set_integer(dst, v);
- }
- break;
- case SND_CONFIG_TYPE_REAL:
- {
- double r;
- err = safe_strtod(ptr, &r);
- if (err >= 0)
- snd_config_set_real(dst, r);
- }
- break;
- default:
- err = -EINVAL;
- }
- if (ptr)
- free(ptr);
- if (err < 0)
- goto __err1;
- snd_config_delete(dst);
- dst = n;
- }
- *_dst = dst;
+ SNDERR("symbol %s is not defined inside %s", evaluate_name, lib ? lib : ALSA_LIB);
+ err = -ENXIO;
+ goto __error;
+ }
+ err = evaluate_func(dst, src, private_data);
+ dlclose(h);
+ if (err < 0) {
+ SNDERR("function %s returned error: %s", evaluate_name, snd_strerror(err));
+ goto __error;
}
-
err = 0;
+
__error:
if (func)
free((void *)func);
if (lib)
free((void *)lib);
- if (type)
- free((void *)type);
return err;
}
err = snd_config_search_alias(config, base, key, &conf);
if (err < 0)
return err;
- err = snd_config_expand(conf, args, NULL, result);
- if (err < 0)
- return err;
-
+ return snd_config_expand(conf, args, NULL, result);
}
return 0;
}
-/**
- * \brief Redirect the configuration block to an another
- * \param root the root of all configurations
- * \param config redirect configuration
- * \param name the identifier of new configuration block
- * \param dst_config new configuration block
- * \param dst_dynamic new configuration block is dynamically allocated
- */
-int snd_config_refer_load(snd_config_t *root,
- snd_config_t *config,
- char **name,
- snd_config_t **dst_config,
- int *dst_dynamic)
-{
- int err, dynamic;
- snd_config_t *result, *c;
- char *rname;
-
- assert(config);
- assert(name);
- assert(dst_config);
- assert(dst_dynamic);
- if (snd_config_get_type(config) == SND_CONFIG_TYPE_STRING) {
- const char *str;
- snd_config_get_string(config, &str);
- *name = strdup(str);
- if (*name == NULL)
- return -ENOMEM;
- *dst_config = root;
- *dst_dynamic = 0;
- return 0;
- }
- if (snd_config_get_type(config) != SND_CONFIG_TYPE_COMPOUND)
- return -EINVAL;
- result = root;
- dynamic = 0;
- rname = NULL;
- if (snd_config_search(config, "filename", &c) >= 0) {
- snd_config_t *rconfig;
- const char *filename;
- snd_input_t *input;
- err = snd_config_copy(&rconfig, root);
- if (err < 0)
- return err;
- if (snd_config_get_type(c) == SND_CONFIG_TYPE_STRING) {
- snd_config_get_string(c, &filename);
- } else {
- err = -EINVAL;
- __filename_error:
- snd_config_delete(rconfig);
- return err;
- }
- err = snd_input_stdio_open(&input, filename, "r");
- if (err < 0) {
- SNDERR("Unable to open filename %s: %s", filename, snd_strerror(err));
- goto __filename_error;
- }
- err = snd_config_load(rconfig, input);
- if (err < 0) {
- snd_input_close(input);
- goto __filename_error;
- }
- snd_input_close(input);
- result = rconfig;
- dynamic = 1;
- }
- if (snd_config_search(config, "name", &c) >= 0) {
- const char *ptr;
- if ((err = snd_config_get_string(c, &ptr)) < 0)
- goto __error;
- rname = strdup(ptr);
- if (rname == NULL) {
- err = -ENOMEM;
- goto __error;
- }
- }
- if (rname == NULL) {
- err = -EINVAL;
- goto __error;
- }
- *dst_config = result;
- *dst_dynamic = dynamic;
- *name = rname;
- return 0;
- __error:
- if (rname)
- free(rname);
- if (dynamic)
- snd_config_delete(result);
- return err;
-}
-
/*
* Helper functions for the configuration file
*/
return err;
}
+int snd_func_igetenv(snd_config_t **dst, snd_config_t *src, void *private_data)
+{
+ snd_config_t *d;
+ const char *str;
+ int err;
+ long v;
+ err = snd_func_getenv(&d, src, private_data);
+ if (err < 0)
+ return err;
+ err = snd_config_get_string(d, &str);
+ if (err < 0)
+ goto _end;
+ err = safe_strtol(str, &v);
+ if (err < 0)
+ goto _end;
+ err = snd_config_make_integer(dst, snd_config_get_id(src));
+ if (err < 0)
+ goto _end;
+ snd_config_set_integer(*dst, v);
+ err = 0;
+
+ _end:
+ snd_config_delete(d);
+ return err;
+}
+
+
+
int snd_func_concat(snd_config_t **dst, snd_config_t *src, void *private_data)
{
snd_config_t *n, *e;
snd_config_delete(e);
return err;
}
+
+int snd_func_refer(snd_config_t **dst, snd_config_t *src, void *private_data)
+{
+ snd_config_t *n, *e;
+ snd_config_t *root = NULL;
+ const char *file = NULL, *name = NULL;
+ int err;
+
+ err = snd_config_expand(src, NULL, private_data, &e);
+ if (err < 0)
+ return err;
+ err = snd_config_search(e, "file", &n);
+ if (err >= 0) {
+ err = snd_config_get_string(n, &file);
+ if (err < 0) {
+ SNDERR("file is not a string");
+ goto _end;
+ }
+ }
+ err = snd_config_search(e, "name", &n);
+ if (err >= 0) {
+ err = snd_config_get_string(n, &name);
+ if (err < 0) {
+ SNDERR("name is not a string");
+ goto _end;
+ }
+ }
+ if (!file && !name) {
+ err = -EINVAL;
+ SNDERR("neither file or name are specified");
+ goto _end;
+ }
+ if (!file)
+ root = snd_config;
+ else {
+ snd_input_t *input;
+ err = snd_config_top(&root);
+ if (err < 0)
+ goto _end;
+ err = snd_input_stdio_open(&input, file, "r");
+ if (err < 0) {
+ SNDERR("Unable to open file %s: %s", file, snd_strerror(err));
+ goto _end;
+ }
+ err = snd_config_load(root, input);
+ if (err < 0) {
+ snd_input_close(input);
+ goto _end;
+ }
+ }
+ if (!name) {
+ if (root == snd_config)
+ snd_config_copy(dst, root);
+ else
+ *dst = root;
+ err = 0;
+ } else
+ err = snd_config_search_definition(root, 0, name, dst);
+ if (err >= 0)
+ err = snd_config_set_id(*dst, snd_config_get_id(src));
+ _end:
+ if (root && root != snd_config)
+ snd_config_delete(root);
+ return err;
+}
const char *name, snd_pcm_stream_t stream, int mode)
{
int err;
- snd_config_t *pcm_conf, *conf;
+ snd_config_t *pcm_conf;
err = snd_config_search_definition(root, "pcm", name, &pcm_conf);
if (err < 0) {
SNDERR("Unknown PCM %s", name);
return err;
}
- if (snd_config_search(pcm_conf, "refer", &conf) >= 0) {
- snd_config_t *tmp_conf;
- int conf_free_tmp;
- char *refer_name = NULL;
- err = snd_config_refer_load(root, conf, &refer_name, &tmp_conf, &conf_free_tmp);
- snd_config_delete(pcm_conf);
- if (err < 0) {
- SNDERR("Refer load error for %s: %s", name, snd_strerror(err));
- return err;
- }
- err = snd_pcm_open_noupdate(pcmp, tmp_conf, refer_name, stream, mode);
- if (refer_name)
- free(refer_name);
- if (conf_free_tmp)
- snd_config_delete(tmp_conf);
- return err;
- }
err = snd_pcm_open_conf(pcmp, name, root, pcm_conf, stream, mode);
snd_config_delete(pcm_conf);
return err;