* Cleaned the alsa.conf syntax:

- added pcm.front, pcm.rear, pcm.center_lfe blocks
* Added configuration for EMU10K1 (it's fully working one!!!)
* snd_config_redirect_load->snd_config_refer_load rename
* snd_config_search_alias code change (works also with pairs base.key)
* cleanups in the evaluate function (the function prototype has been changed)
This commit is contained in:
Jaroslav Kysela 2001-06-15 08:47:59 +00:00
parent 1b8d405606
commit 977a9a33f0
25 changed files with 468 additions and 266 deletions

View file

@ -96,11 +96,11 @@ int snd_config_string_replace(const char *src, char idchr,
snd_config_string_replace_callback_t *callback, snd_config_string_replace_callback_t *callback,
void *private_data, void *private_data,
char **dst); char **dst);
int snd_config_redirect_load(snd_config_t *root, int snd_config_refer_load(snd_config_t *root,
snd_config_t *config, snd_config_t *config,
char **name, char **name,
snd_config_t **dst_config, snd_config_t **dst_config,
int *dst_dynamic); int *dst_dynamic);
#ifdef __cplusplus #ifdef __cplusplus
} }

View file

@ -129,6 +129,156 @@ pcm.default {
} }
} }
pcm.front {
args [ CARD DEV ]
args.CARD {
type integer
default {
@func getenv
@type integer
envname [
ALSA_FRONT_CARD
ALSA_PCM_CARD
ALSA_CARD
]
default 0
}
}
args.DEV {
type integer
default {
@func getenv
@type integer
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)
]
}
}
}
pcm.rear {
args [ CARD DEV ]
args.CARD {
type integer
default {
@func getenv
@type integer
envname [
ALSA_REAR_CARD
ALSA_PCM_CARD
ALSA_CARD
]
default 0
}
}
args.DEV {
type integer
default {
@func getenv
@type integer
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)
]
}
}
}
pcm.center_lfe {
args [ CARD DEV ]
args.CARD {
type integer
default {
@func getenv
@type integer
envname [
ALSA_CENTER_LFE_CARD
ALSA_PCM_CARD
ALSA_CARD
]
default 0
}
}
args.DEV {
type integer
default {
@func getenv
@type integer
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)
]
}
}
}
pcm.surround40 { pcm.surround40 {
args [ CARD DEV ] args [ CARD DEV ]
args.CARD { args.CARD {
@ -304,7 +454,7 @@ pcm.iec958 {
} }
} }
pcm.spdif iec958 pcm.spdif pcm.iec958
# #
# Control interface # Control interface

View file

@ -1,5 +1,5 @@
alsadir = $(datadir)/alsa/cards alsadir = $(datadir)/alsa/cards
cfg_files = SI_7018.conf cfg_files = SI_7018.conf EMU10K1.conf
EXTRA_DIST = $(cfg_files) EXTRA_DIST = $(cfg_files)
alsa_DATA = $(cfg_files) alsa_DATA = $(cfg_files)

View file

@ -2,7 +2,7 @@
# Configuration for the SI7018 chip # Configuration for the SI7018 chip
# #
pcm.front { pcm.si7018_front {
args [ CARD DEV SUBDEV ] args [ CARD DEV SUBDEV ]
args.CARD { args.CARD {
type integer type integer
@ -20,12 +20,18 @@ pcm.front {
subdevice $(SUBDEV) subdevice $(SUBDEV)
} }
pcm_slave.front { pcm.front_0 {
pcm pcm.front args [ CARD ]
channels 2 args.CARD {
type integer
}
redir {
@func concat
strings [ "pcm.si7018_front:" $(CARD) ",0,-1" ]
}
} }
pcm.rear { pcm.si7010_rear {
args [ CARD DEV SUBDEV ] args [ CARD DEV SUBDEV ]
args.CARD { args.CARD {
type integer type integer
@ -43,12 +49,18 @@ pcm.rear {
subdevice $(SUBDEV) subdevice $(SUBDEV)
} }
pcm_slave.rear { pcm.rear_0 {
pcm pcm.rear args [ CARD ]
channels 2 args.CARD {
type integer
}
redir {
@func concat
strings [ "pcm.si7018_rear:" $(CARD) ",0,-1" ]
}
} }
pcm.surround40_0_trident_dx_nx { pcm.surround40_0 {
args [ CARD ] args [ CARD ]
args.CARD { args.CARD {
type integer type integer
@ -56,16 +68,22 @@ pcm.surround40_0_trident_dx_nx {
type multi type multi
slaves [ slaves [
{ {
@func concat pcm {
strings [ @func concat
"pcm_slave.front:" $(CARD) ",0,-1" strings [
] "pcm.si7018_front:" $(CARD) ",0,-1"
]
}
channels 2
} }
{ {
@func concat pcm {
strings [ @func concat
"pcm_slave.rear:" $(CARD) ",0,-1" strings [
] "pcm.si7018_rear:" $(CARD) ",0,-1"
]
}
channels 2
} }
] ]
bindings [ bindings [

View file

@ -1443,8 +1443,9 @@ int snd_config_searchv(snd_config_t *config,
* \param result Pointer to found node * \param result Pointer to found node
* \return 0 on success otherwise a negative error code * \return 0 on success otherwise a negative error code
* *
* If base.key is found and it's a string the value found is recursively * First key is tried and if nothing is found is tried base.key.
* tried instead of suffix. * If the value found is a string this is recursively tried in the
* same way.
*/ */
int snd_config_search_alias(snd_config_t *config, int snd_config_search_alias(snd_config_t *config,
const char *base, const char *key, const char *base, const char *key,
@ -1454,19 +1455,20 @@ int snd_config_search_alias(snd_config_t *config,
int err; int err;
assert(config && key); assert(config && key);
if (base) { if (base) {
err = snd_config_searchv(config, &res, base, key, 0); err = snd_config_searchv(config, &res, base, key, NULL);
if (err < 0)
return err;
while (snd_config_get_string(res, &key) >= 0 &&
snd_config_searchv(config, &res, base, key, 0) >= 0)
;
} else { } else {
err = snd_config_search(config, key, &res); err = snd_config_search(config, key, &res);
}
if (err < 0)
return err;
while (snd_config_get_string(res, &base) >= 0) {
err = snd_config_search(config, base, &res);
if (err >= 0) {
if (snd_config_get_string(res, &key) >= 0)
err = snd_config_search(res, key, &res);
}
if (err < 0) if (err < 0)
return err; break;
while (snd_config_get_string(res, &key) >= 0 &&
snd_config_search(config, key, &res) >= 0)
;
} }
if (result) if (result)
*result = res; *result = res;
@ -1926,11 +1928,11 @@ static int evaluate_node(snd_config_t *father, snd_config_t *src,
} }
{ {
char buf[64], *ptr; char buf[64];
snd_config_type_t t; snd_config_type_t t;
snd_config_t *dst = NULL; snd_config_t *dst = NULL;
char *evaluate_name = NULL; char *evaluate_name = NULL;
int (*evaluate_func)(char **dst, snd_config_t *src, void *private_data); int (*evaluate_func)(snd_config_t **dst, snd_config_t *src, void *private_data);
void *h; void *h;
if (evaluate_name == NULL) { if (evaluate_name == NULL) {
@ -1942,64 +1944,82 @@ static int evaluate_node(snd_config_t *father, snd_config_t *src,
h = dlopen(lib, RTLD_NOW); h = dlopen(lib, RTLD_NOW);
if (!h) { if (!h) {
SNDERR("Cannot open shared library %s", lib); SNDERR("Cannot open shared library %s", lib);
return -ENOENT; err = -ENOENT;
goto __error;
} }
evaluate_func = dlsym(h, evaluate_name); evaluate_func = dlsym(h, evaluate_name);
if (!evaluate_func) { if (!evaluate_func) {
dlclose(h); dlclose(h);
SNDERR("symbol %s is not defined inside %s", evaluate_name, lib ? lib : ALSA_LIB); SNDERR("symbol %s is not defined inside %s", evaluate_name, lib ? lib : ALSA_LIB);
return -ENXIO; err = -ENXIO;
goto __error;
} }
err = evaluate_func(&ptr, src, private_data); err = evaluate_func(&dst, src, private_data);
dlclose(h); dlclose(h);
if (err < 0) { if (err < 0) {
SNDERR("function %s returned error: %s", evaluate_name, snd_strerror(err)); SNDERR("function %s returned error: %s", evaluate_name, snd_strerror(err));
return err; goto __error;
} }
if (type == NULL) { if (type == NULL) {
t = SND_CONFIG_TYPE_STRING; t = SND_CONFIG_TYPE_STRING;
} else { } else {
err = snd_config_get_type_ascii(type, &t); err = snd_config_get_type_ascii(type, &t);
if (err < 0 || t == SND_CONFIG_TYPE_COMPOUND) { 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); free(ptr);
return -EINVAL; if (err < 0)
} goto __err1;
snd_config_delete(dst);
dst = n;
} }
err = snd_config_make(&dst, snd_config_get_id(src), t);
if (err < 0) {
free(ptr);
return err;
}
switch (t) {
case SND_CONFIG_TYPE_INTEGER:
{
long v;
err = safe_strtol(ptr, &v);
if (err < 0) {
free(ptr);
snd_config_delete(dst);
return err;
}
snd_config_set_integer(dst, v);
}
break;
case SND_CONFIG_TYPE_REAL:
{
double r;
err = safe_strtod(ptr, &r);
if (err < 0) {
free(ptr);
snd_config_delete(dst);
return err;
}
snd_config_set_real(dst, r);
}
break;
default:
snd_config_set_string(dst, ptr);
break;
}
free(ptr);
*_dst = dst; *_dst = dst;
} }
@ -2019,6 +2039,8 @@ int snd_config_evaluate(snd_config_t *conf, void *private_data)
snd_config_iterator_t i, next; snd_config_iterator_t i, next;
assert(conf); assert(conf);
if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND)
return 0;
snd_config_for_each(i, next, conf) { snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
if (snd_config_get_type(n) == SND_CONFIG_TYPE_COMPOUND) { if (snd_config_get_type(n) == SND_CONFIG_TYPE_COMPOUND) {

View file

@ -215,11 +215,11 @@ int snd_config_string_replace(const char *src, char idchr,
* \param dst_config new configuration block * \param dst_config new configuration block
* \param dst_dynamic new configuration block is dynamically allocated * \param dst_dynamic new configuration block is dynamically allocated
*/ */
int snd_config_redirect_load(snd_config_t *root, int snd_config_refer_load(snd_config_t *root,
snd_config_t *config, snd_config_t *config,
char **name, char **name,
snd_config_t **dst_config, snd_config_t **dst_config,
int *dst_dynamic) int *dst_dynamic)
{ {
int err, dynamic; int err, dynamic;
snd_config_t *result, *c; snd_config_t *result, *c;
@ -303,12 +303,11 @@ int snd_config_redirect_load(snd_config_t *root,
* Helper functions for the configuration file * Helper functions for the configuration file
*/ */
int snd_func_getenv(char **dst, snd_config_t *src, void *private_data ATTRIBUTE_UNUSED) int snd_func_getenv(snd_config_t **dst, snd_config_t *src, void *private_data ATTRIBUTE_UNUSED)
{ {
snd_config_t *n, *d, *e; snd_config_t *n, *d, *e;
snd_config_iterator_t i, next; snd_config_iterator_t i, next;
const char *res; char *res, *def = NULL;
char *def = NULL;
int idx = 0, err; int idx = 0, err;
err = snd_config_expand(src, NULL, NULL, &e); err = snd_config_expand(src, NULL, NULL, &e);
@ -361,7 +360,12 @@ int snd_func_getenv(char **dst, snd_config_t *src, void *private_data ATTRIBUTE_
def = NULL; def = NULL;
__ok: __ok:
err = res == NULL ? -ENOMEM : 0; err = res == NULL ? -ENOMEM : 0;
*dst = (char *)res; if (err >= 0) {
err = snd_config_make_string(dst, snd_config_get_id(src));
if (err >= 0)
snd_config_set_string(*dst, res);
free(res);
}
__error: __error:
if (def) if (def)
free(def); free(def);
@ -369,7 +373,7 @@ int snd_func_getenv(char **dst, snd_config_t *src, void *private_data ATTRIBUTE_
return err; return err;
} }
int snd_func_concat(char **dst, snd_config_t *src, void *private_data ATTRIBUTE_UNUSED) int snd_func_concat(snd_config_t **dst, snd_config_t *src, void *private_data ATTRIBUTE_UNUSED)
{ {
snd_config_t *n, *e; snd_config_t *n, *e;
snd_config_iterator_t i, next; snd_config_iterator_t i, next;
@ -421,19 +425,20 @@ int snd_func_concat(char **dst, snd_config_t *src, void *private_data ATTRIBUTE_
err = -EINVAL; err = -EINVAL;
goto __error; goto __error;
} }
err = 0; err = snd_config_make_string(dst, snd_config_get_id(src));
*dst = res; if (err >= 0)
snd_config_set_string(*dst, res);
free(res);
__error: __error:
snd_config_delete(e); snd_config_delete(e);
return err; return err;
} }
int snd_func_datadir(char **dst, snd_config_t *src ATTRIBUTE_UNUSED, void *private_data ATTRIBUTE_UNUSED) int snd_func_datadir(snd_config_t **dst, snd_config_t *src, void *private_data ATTRIBUTE_UNUSED)
{ {
char *res = strdup(DATADIR "/alsa"); int err = snd_config_make_string(dst, snd_config_get_id(src));
if (res == NULL) if (err >= 0)
return -ENOMEM; err = snd_config_set_string(*dst, DATADIR "/alsa");
*dst = res;
return 0; return 0;
} }
@ -459,7 +464,7 @@ static int string_from_integer(char **dst, long v)
} }
#endif #endif
int snd_func_card_strtype(char **dst, snd_config_t *src, void *private_data ATTRIBUTE_UNUSED) int snd_func_card_strtype(snd_config_t **dst, snd_config_t *src, void *private_data ATTRIBUTE_UNUSED)
{ {
snd_config_t *n, *e; snd_config_t *n, *e;
char *res = NULL; char *res = NULL;
@ -497,7 +502,10 @@ int snd_func_card_strtype(char **dst, snd_config_t *src, void *private_data ATTR
SNDERR("snd_card_type_enum_to_string failed for %i", (int)snd_ctl_card_info_get_type(info)); SNDERR("snd_card_type_enum_to_string failed for %i", (int)snd_ctl_card_info_get_type(info));
goto __error; goto __error;
} }
*dst = res; err = snd_config_make_string(dst, snd_config_get_id(src));
if (err >= 0)
err = snd_config_set_string(*dst, res);
free(res);
__error: __error:
if (ctl) if (ctl)
snd_ctl_close(ctl); snd_ctl_close(ctl);
@ -505,7 +513,7 @@ int snd_func_card_strtype(char **dst, snd_config_t *src, void *private_data ATTR
return err; return err;
} }
int snd_func_card_id(char **dst, snd_config_t *src, void *private_data ATTRIBUTE_UNUSED) int snd_func_card_id(snd_config_t **dst, snd_config_t *src, void *private_data ATTRIBUTE_UNUSED)
{ {
snd_config_t *n, *e; snd_config_t *n, *e;
char *res = NULL; char *res = NULL;
@ -543,7 +551,10 @@ int snd_func_card_id(char **dst, snd_config_t *src, void *private_data ATTRIBUTE
err = -ENOMEM; err = -ENOMEM;
goto __error; goto __error;
} }
*dst = res; err = snd_config_make_string(dst, snd_config_get_id(src));
if (err >= 0)
err = snd_config_set_string(*dst, res);
free(res);
__error: __error:
if (ctl) if (ctl)
snd_ctl_close(ctl); snd_ctl_close(ctl);
@ -551,7 +562,7 @@ int snd_func_card_id(char **dst, snd_config_t *src, void *private_data ATTRIBUTE
return err; return err;
} }
int snd_func_pcm_id(char **dst, snd_config_t *src, void *private_data ATTRIBUTE_UNUSED) int snd_func_pcm_id(snd_config_t **dst, snd_config_t *src, void *private_data ATTRIBUTE_UNUSED)
{ {
snd_config_t *n, *e; snd_config_t *n, *e;
char *res = NULL; char *res = NULL;
@ -608,7 +619,10 @@ int snd_func_pcm_id(char **dst, snd_config_t *src, void *private_data ATTRIBUTE_
err = -ENOMEM; err = -ENOMEM;
goto __error; goto __error;
} }
*dst = res; err = snd_config_make_string(dst, snd_config_get_id(src));
if (err >= 0)
err = snd_config_set_string(*dst, res);
free(res);
__error: __error:
if (ctl) if (ctl)
snd_ctl_close(ctl); snd_ctl_close(ctl);

View file

@ -459,32 +459,50 @@ int snd_ctl_open_conf(snd_ctl_t **ctlp, const char *name,
return open_func(ctlp, name, ctl_conf, mode); return open_func(ctlp, name, ctl_conf, mode);
} }
int snd_ctl_open_noupdate(snd_ctl_t **ctlp, const char *name, int mode) int snd_ctl_open_noupdate(snd_ctl_t **ctlp, snd_config_t *root, const char *name, int mode)
{ {
int err; int err;
snd_config_t *ctl_conf; snd_config_t *ctl_conf;
char *base, *key;
const char *args = strchr(name, ':'); const char *args = strchr(name, ':');
char *base;
if (args) { if (args) {
args++; args++;
base = alloca(args - name); base = alloca(args - name);
memcpy(base, name, args - name - 1); memcpy(base, name, args - name - 1);
base[args - name - 1] = 0; base[args - name - 1] = '\0';
} else key = strchr(base, '.');
base = (char *) name; if (key)
err = snd_config_search_alias(snd_config, "ctl", base, &ctl_conf); *key++ = '\0';
} else {
key = strchr(name, '.');
if (key) {
key++;
base = alloca(key - name);
memcpy(base, name, key - name - 1);
base[key - name - 1] = '\0';
} else
base = (char *) name;
}
if (key == NULL) {
key = base;
base = NULL;
}
err = snd_config_search_alias(root, base, key, &ctl_conf);
if (err < 0) { if (err < 0) {
SNDERR("Unknown CTL %s", name); (void)(base == NULL && (err = snd_config_search_alias(root, "ctl", key, &ctl_conf)));
if (err < 0) {
SNDERR("Unknown PCM %s", name);
return err;
}
}
err = snd_config_expand(ctl_conf, args, NULL, &ctl_conf);
if (err < 0) {
SNDERR("Could not expand configuration for %s: %s", name, snd_strerror(err));
return err; return err;
} }
if (args) {
err = snd_config_expand(ctl_conf, args, NULL, &ctl_conf);
if (err < 0)
return err;
}
err = snd_ctl_open_conf(ctlp, name, ctl_conf, mode); err = snd_ctl_open_conf(ctlp, name, ctl_conf, mode);
if (args) snd_config_delete(ctl_conf);
snd_config_delete(ctl_conf);
return err; return err;
} }
@ -502,7 +520,7 @@ int snd_ctl_open(snd_ctl_t **ctlp, const char *name, int mode)
err = snd_config_update(); err = snd_config_update();
if (err < 0) if (err < 0)
return err; return err;
return snd_ctl_open_noupdate(ctlp, name, mode); return snd_ctl_open_noupdate(ctlp, snd_config, name, mode);
} }
/** /**

View file

@ -437,7 +437,7 @@ static int add_elem(snd_sctl_t *h, snd_config_t *conf,
{ {
snd_config_iterator_t i, next; snd_config_iterator_t i, next;
char *tmp; char *tmp;
int iface = SND_CTL_ELEM_IFACE_PCM; int iface = SND_CTL_ELEM_IFACE_MIXER;
char *name = NULL; char *name = NULL;
long index = 0; long index = 0;
long device = -1; long device = -1;
@ -452,7 +452,7 @@ static int add_elem(snd_sctl_t *h, snd_config_t *conf,
const char *id = snd_config_get_id(n); const char *id = snd_config_get_id(n);
if (strcmp(id, "comment") == 0) if (strcmp(id, "comment") == 0)
continue; continue;
if (strcmp(id, "iface") == 0) { if (strcmp(id, "iface") == 0 || strcmp(id, "interface") == 0) {
if ((err = config_replace(n, callback, private_data, &tmp)) < 0) if ((err = config_replace(n, callback, private_data, &tmp)) < 0)
goto _err; goto _err;
if ((err = snd_config_get_ctl_iface_ascii(tmp)) < 0) { if ((err = snd_config_get_ctl_iface_ascii(tmp)) < 0) {
@ -471,6 +471,7 @@ static int add_elem(snd_sctl_t *h, snd_config_t *conf,
if (strcmp(id, "index") == 0) { if (strcmp(id, "index") == 0) {
if ((err = config_replace_integer(n, callback, private_data, &index)) < 0) if ((err = config_replace_integer(n, callback, private_data, &index)) < 0)
goto _err; goto _err;
continue;
} }
if (strcmp(id, "device") == 0) { if (strcmp(id, "device") == 0) {
if ((err = config_replace_integer(n, callback, private_data, &device)) < 0) if ((err = config_replace_integer(n, callback, private_data, &device)) < 0)
@ -544,7 +545,7 @@ static int add_elem(snd_sctl_t *h, snd_config_t *conf,
snd_ctl_elem_info_set_id(elem->info, elem->id); snd_ctl_elem_info_set_id(elem->info, elem->id);
err = snd_ctl_elem_info(h->ctl, elem->info); err = snd_ctl_elem_info(h->ctl, elem->info);
if (err < 0) { if (err < 0) {
SNDERR("Cannot obtain info for CTL elem"); SNDERR("Cannot obtain info for CTL elem (%s,'%s',%li,%li,%li): %s", snd_ctl_elem_iface_name(iface), name, index, device, subdevice, snd_strerror(err));
goto _err; goto _err;
} }
snd_ctl_elem_value_set_id(elem->val, elem->id); snd_ctl_elem_value_set_id(elem->val, elem->id);
@ -597,6 +598,7 @@ int snd_sctl_build(snd_sctl_t **sctl, snd_ctl_t *handle, snd_config_t *conf,
int err; int err;
assert(sctl); assert(sctl);
assert(handle);
assert(conf); assert(conf);
if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND)
return -EINVAL; return -EINVAL;

View file

@ -1001,9 +1001,8 @@ static int snd_pcm_open_noupdate(snd_pcm_t **pcmp, snd_config_t *root,
{ {
int err; int err;
snd_config_t *pcm_conf; snd_config_t *pcm_conf;
char *key; char *base, *key;
const char *args = strchr(name, ':'); const char *args = strchr(name, ':');
char *base;
snd_config_t *conf; snd_config_t *conf;
if (args) { if (args) {
args++; args++;
@ -1037,23 +1036,23 @@ static int snd_pcm_open_noupdate(snd_pcm_t **pcmp, snd_config_t *root,
} }
err = snd_config_expand(pcm_conf, args, NULL, &pcm_conf); err = snd_config_expand(pcm_conf, args, NULL, &pcm_conf);
if (err < 0) { if (err < 0) {
SNDERR("Could not expand configuration: %s", snd_strerror(err)); SNDERR("Could not expand configuration for %s: %s", name, snd_strerror(err));
return err; return err;
} }
if (snd_config_search(pcm_conf, "refer", &conf) >= 0) { if (snd_config_search(pcm_conf, "refer", &conf) >= 0) {
snd_config_t *tmp_conf; snd_config_t *tmp_conf;
int conf_free_tmp; int conf_free_tmp;
char *redir_name = NULL; char *refer_name = NULL;
err = snd_config_redirect_load(root, conf, &redir_name, &tmp_conf, &conf_free_tmp); err = snd_config_refer_load(root, conf, &refer_name, &tmp_conf, &conf_free_tmp);
if (args) if (args)
snd_config_delete(pcm_conf); snd_config_delete(pcm_conf);
if (err < 0) { if (err < 0) {
SNDERR("Redirect error: %s", snd_strerror(err)); SNDERR("Refer load error for %s: %s", name, snd_strerror(err));
return err; return err;
} }
err = snd_pcm_open_noupdate(pcmp, tmp_conf, redir_name, stream, mode); err = snd_pcm_open_noupdate(pcmp, tmp_conf, refer_name, stream, mode);
if (redir_name) if (refer_name)
free(redir_name); free(refer_name);
if (conf_free_tmp) if (conf_free_tmp)
snd_config_delete(tmp_conf); snd_config_delete(tmp_conf);
return err; return err;
@ -1083,25 +1082,13 @@ int snd_pcm_open(snd_pcm_t **pcmp, const char *name,
} }
#ifndef DOC_HIDDEN #ifndef DOC_HIDDEN
int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *root, snd_config_t *conf, int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *root,
const char *args, snd_pcm_stream_t stream, int mode) snd_config_t *conf, snd_pcm_stream_t stream,
int mode)
{ {
const char *str; const char *str;
if (snd_config_get_string(conf, &str) >= 0) { if (snd_config_get_string(conf, &str) >= 0)
char *tmp; return snd_pcm_open_noupdate(pcmp, root, str, stream, mode);
int err;
if (args == NULL)
return snd_pcm_open_noupdate(pcmp, root, str, stream, mode);
tmp = malloc(strlen(str) + 1 + strlen(args) + 1);
if (tmp == NULL)
return -ENOMEM;
strcpy(tmp, str);
strcat(tmp, ":");
strcat(tmp, args);
err = snd_pcm_open_noupdate(pcmp, root, tmp, stream, mode);
free(tmp);
return err;
}
return snd_pcm_open_conf(pcmp, NULL, root, conf, stream, mode); return snd_pcm_open_conf(pcmp, NULL, root, conf, stream, mode);
} }
#endif #endif
@ -4318,8 +4305,7 @@ static const char *names[SND_PCM_HW_PARAM_LAST + 1] = {
}; };
int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf, int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
snd_config_t **pcm_conf, const char **pcm_args, snd_config_t **_pcm_conf, unsigned int count, ...)
unsigned int count, ...)
{ {
snd_config_iterator_t i, next; snd_config_iterator_t i, next;
const char *str; const char *str;
@ -4330,48 +4316,18 @@ int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
int valid; int valid;
} fields[count]; } fields[count];
unsigned int k; unsigned int k;
int pcm_valid = 0; snd_config_t *pcm_conf = NULL;
int err; int err;
va_list args; va_list args;
assert(root); assert(root);
assert(conf); assert(conf);
assert(pcm_conf); assert(_pcm_conf);
if (snd_config_get_string(conf, &str) >= 0) { if (snd_config_get_string(conf, &str) >= 0) {
char *key; err = snd_config_search_alias(conf, "pcm_slave", str, &conf);
const char *args = strchr(str, ':');
char *base;
if (args) {
args++;
base = alloca(args - str);
memcpy(base, str, args - str - 1);
base[args - str - 1] = '\0';
key = strchr(base, '.');
if (key)
*key++ = '\0';
} else {
key = strchr(str, '.');
if (key) {
key++;
base = alloca(key - str);
memcpy(base, str, key - str - 1);
base[key - str - 1] = '\0';
} else
base = (char *) str;
}
if (key == NULL) {
key = base;
base = NULL;
}
err = snd_config_search_alias(root, base, key, &conf);
if (err < 0) { if (err < 0) {
(void)(base == NULL && (err = snd_config_search_alias(root, "pcm_slave", key, &conf))); SNDERR("Configuration pcm_slave.%s was not found\n", str);
if (err < 0) { return -EINVAL;
SNDERR("unknown pcm_slave %s", str);
return err;
}
} }
if (pcm_args)
*pcm_args = args;
} }
if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) { if (snd_config_get_type(conf) != SND_CONFIG_TYPE_COMPOUND) {
SNDERR("Invalid slave definition"); SNDERR("Invalid slave definition");
@ -4391,8 +4347,7 @@ int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
if (strcmp(id, "comment") == 0) if (strcmp(id, "comment") == 0)
continue; continue;
if (strcmp(id, "pcm") == 0) { if (strcmp(id, "pcm") == 0) {
*pcm_conf = n; pcm_conf = n;
pcm_valid = 1;
continue; continue;
} }
for (k = 0; k < count; ++k) { for (k = 0; k < count; ++k) {
@ -4435,7 +4390,7 @@ int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
SNDERR("Unknown field %s", id); SNDERR("Unknown field %s", id);
// return -EINVAL; // return -EINVAL;
} }
if (!pcm_valid) { if (!pcm_conf) {
SNDERR("missing field pcm"); SNDERR("missing field pcm");
return -EINVAL; return -EINVAL;
} }
@ -4445,6 +4400,7 @@ int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
return -EINVAL; return -EINVAL;
} }
} }
*_pcm_conf = pcm_conf;
return 0; return 0;
} }

View file

@ -556,7 +556,6 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_t *spcm; snd_pcm_t *spcm;
snd_config_t *slave = NULL, *sconf; snd_config_t *slave = NULL, *sconf;
snd_pcm_format_t sformat; snd_pcm_format_t sformat;
const char *args;
snd_config_for_each(i, next, conf) { snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n); const char *id = snd_config_get_id(n);
@ -573,7 +572,7 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
SNDERR("slave is not defined"); SNDERR("slave is not defined");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_slave_conf(root, slave, &sconf, &args, 1, err = snd_pcm_slave_conf(root, slave, &sconf, 1,
SND_PCM_HW_PARAM_FORMAT, 1, &sformat); SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
if (err < 0) if (err < 0)
return err; return err;
@ -582,7 +581,7 @@ int _snd_pcm_adpcm_open(snd_pcm_t **pcmp, const char *name,
SNDERR("invalid slave format"); SNDERR("invalid slave format");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_open_slave(&spcm, root, sconf, args, stream, mode); err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_adpcm_open(pcmp, name, sformat, spcm, 1); err = snd_pcm_adpcm_open(pcmp, name, sformat, spcm, 1);

View file

@ -429,7 +429,6 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_t *spcm; snd_pcm_t *spcm;
snd_config_t *slave = NULL, *sconf; snd_config_t *slave = NULL, *sconf;
snd_pcm_format_t sformat; snd_pcm_format_t sformat;
const char *args;
snd_config_for_each(i, next, conf) { snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n); const char *id = snd_config_get_id(n);
@ -446,7 +445,7 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
SNDERR("slave is not defined"); SNDERR("slave is not defined");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_slave_conf(root, slave, &sconf, &args, 1, err = snd_pcm_slave_conf(root, slave, &sconf, 1,
SND_PCM_HW_PARAM_FORMAT, 1, &sformat); SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
if (err < 0) if (err < 0)
return err; return err;
@ -455,7 +454,7 @@ int _snd_pcm_alaw_open(snd_pcm_t **pcmp, const char *name,
SNDERR("invalid slave format"); SNDERR("invalid slave format");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_open_slave(&spcm, root, sconf, args, stream, mode); err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_alaw_open(pcmp, name, sformat, spcm, 1); err = snd_pcm_alaw_open(pcmp, name, sformat, spcm, 1);

View file

@ -198,7 +198,6 @@ int _snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name,
int err; int err;
snd_pcm_t *spcm; snd_pcm_t *spcm;
snd_config_t *slave = NULL, *sconf; snd_config_t *slave = NULL, *sconf;
const char *args;
snd_config_for_each(i, next, conf) { snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n); const char *id = snd_config_get_id(n);
@ -215,10 +214,10 @@ int _snd_pcm_copy_open(snd_pcm_t **pcmp, const char *name,
SNDERR("slave is not defined"); SNDERR("slave is not defined");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_slave_conf(root, slave, &sconf, &args, 0); err = snd_pcm_slave_conf(root, slave, &sconf, 0);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_open_slave(&spcm, root, sconf, args, stream, mode); err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_copy_open(pcmp, name, spcm, 1); err = snd_pcm_copy_open(pcmp, name, spcm, 1);

View file

@ -466,7 +466,6 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
const char *fname = NULL; const char *fname = NULL;
const char *format = NULL; const char *format = NULL;
long fd = -1; long fd = -1;
const char *args;
snd_config_for_each(i, next, conf) { snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n); const char *id = snd_config_get_id(n);
@ -502,14 +501,14 @@ int _snd_pcm_file_open(snd_pcm_t **pcmp, const char *name,
SNDERR("slave is not defined"); SNDERR("slave is not defined");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_slave_conf(root, slave, &sconf, &args, 0); err = snd_pcm_slave_conf(root, slave, &sconf, 0);
if (err < 0) if (err < 0)
return err; return err;
if (!fname && fd < 0) { if (!fname && fd < 0) {
SNDERR("file is not defined"); SNDERR("file is not defined");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_open_slave(&spcm, root, sconf, args, stream, mode); err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_file_open(pcmp, name, fname, fd, format, spcm, 1); err = snd_pcm_file_open(pcmp, name, fname, fd, format, spcm, 1);

View file

@ -355,7 +355,7 @@ int snd_pcm_hook_add_conf(snd_pcm_t *pcm, snd_config_t *conf)
type = n; type = n;
continue; continue;
} }
if (strcmp(id, "args") == 0) { if (strcmp(id, "hook_args") == 0) {
args = n; args = n;
continue; continue;
} }
@ -441,7 +441,6 @@ int _snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_t *spcm; snd_pcm_t *spcm;
snd_config_t *slave = NULL, *sconf; snd_config_t *slave = NULL, *sconf;
snd_config_t *hooks = NULL; snd_config_t *hooks = NULL;
const char *args;
snd_config_for_each(i, next, conf) { snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n); const char *id = snd_config_get_id(n);
@ -466,10 +465,10 @@ int _snd_pcm_hooks_open(snd_pcm_t **pcmp, const char *name,
SNDERR("slave is not defined"); SNDERR("slave is not defined");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_slave_conf(root, slave, &sconf, &args, 0); err = snd_pcm_slave_conf(root, slave, &sconf, 0);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_open_slave(&spcm, root, sconf, args, stream, mode); err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_hooks_open(pcmp, name, spcm, 1); err = snd_pcm_hooks_open(pcmp, name, spcm, 1);

View file

@ -334,7 +334,6 @@ int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_t *spcm; snd_pcm_t *spcm;
snd_config_t *slave = NULL, *sconf; snd_config_t *slave = NULL, *sconf;
snd_pcm_format_t sformat; snd_pcm_format_t sformat;
const char *args;
snd_config_for_each(i, next, conf) { snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n); const char *id = snd_config_get_id(n);
@ -351,7 +350,7 @@ int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
SNDERR("slave is not defined"); SNDERR("slave is not defined");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_slave_conf(root, slave, &sconf, &args, 1, err = snd_pcm_slave_conf(root, slave, &sconf, 1,
SND_PCM_HW_PARAM_FORMAT, 1, &sformat); SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
if (err < 0) if (err < 0)
return err; return err;
@ -359,7 +358,7 @@ int _snd_pcm_linear_open(snd_pcm_t **pcmp, const char *name,
SNDERR("slave format is not linear"); SNDERR("slave format is not linear");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_open_slave(&spcm, root, sconf, args, stream, mode); err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_linear_open(pcmp, name, sformat, spcm, 1); err = snd_pcm_linear_open(pcmp, name, sformat, spcm, 1);

View file

@ -527,11 +527,12 @@ int snd_pcm_hw_strategy_simple_choices(snd_pcm_hw_strategy_t *strategy, int orde
snd_pcm_hw_strategy_simple_choices_list_t *choices); snd_pcm_hw_strategy_simple_choices_list_t *choices);
#endif #endif
int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf, snd_config_t **pcm_conf, int snd_pcm_slave_conf(snd_config_t *root, snd_config_t *conf,
const char **args, unsigned int count, ...); snd_config_t **pcm_conf, unsigned int count, ...);
int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *root, snd_config_t *conf, int snd_pcm_open_slave(snd_pcm_t **pcmp, snd_config_t *root,
const char *args, snd_pcm_stream_t stream, int mode); snd_config_t *conf, snd_pcm_stream_t stream,
int mode);
int snd_pcm_conf_generic_id(const char *id); int snd_pcm_conf_generic_id(const char *id);
#define SND_PCM_HW_PARBIT_ACCESS (1U << SND_PCM_HW_PARAM_ACCESS) #define SND_PCM_HW_PARBIT_ACCESS (1U << SND_PCM_HW_PARAM_ACCESS)

View file

@ -743,7 +743,6 @@ int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *slave = NULL, *sconf; snd_config_t *slave = NULL, *sconf;
long frequency = -1; long frequency = -1;
snd_config_t *scopes = NULL; snd_config_t *scopes = NULL;
const char *args;
snd_config_for_each(i, next, conf) { snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n); const char *id = snd_config_get_id(n);
@ -776,10 +775,10 @@ int _snd_pcm_meter_open(snd_pcm_t **pcmp, const char *name,
SNDERR("slave is not defined"); SNDERR("slave is not defined");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_slave_conf(root, slave, &sconf, &args, 0); err = snd_pcm_slave_conf(root, slave, &sconf, 0);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_open_slave(&spcm, root, sconf, args, stream, mode); err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_meter_open(pcmp, name, frequency > 0 ? (unsigned int) frequency : FREQUENCY, spcm, 1); err = snd_pcm_meter_open(pcmp, name, frequency > 0 ? (unsigned int) frequency : FREQUENCY, spcm, 1);

View file

@ -444,7 +444,6 @@ int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
snd_pcm_t *spcm; snd_pcm_t *spcm;
snd_config_t *slave = NULL, *sconf; snd_config_t *slave = NULL, *sconf;
snd_pcm_format_t sformat; snd_pcm_format_t sformat;
const char *args;
snd_config_for_each(i, next, conf) { snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n); const char *id = snd_config_get_id(n);
@ -461,7 +460,7 @@ int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
SNDERR("slave is not defined"); SNDERR("slave is not defined");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_slave_conf(root, slave, &sconf, &args, 1, err = snd_pcm_slave_conf(root, slave, &sconf, 1,
SND_PCM_HW_PARAM_FORMAT, 1, &sformat); SND_PCM_HW_PARAM_FORMAT, 1, &sformat);
if (err < 0) if (err < 0)
return err; return err;
@ -470,7 +469,7 @@ int _snd_pcm_mulaw_open(snd_pcm_t **pcmp, const char *name,
SNDERR("invalid slave format"); SNDERR("invalid slave format");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_open_slave(&spcm, root, sconf, args, stream, mode); err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_mulaw_open(pcmp, name, sformat, spcm, 1); err = snd_pcm_mulaw_open(pcmp, name, sformat, spcm, 1);

View file

@ -659,7 +659,6 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
unsigned int idx; unsigned int idx;
const char **slaves_id = NULL; const char **slaves_id = NULL;
snd_config_t **slaves_conf = NULL; snd_config_t **slaves_conf = NULL;
const char **slaves_args = NULL;
snd_pcm_t **slaves_pcm = NULL; snd_pcm_t **slaves_pcm = NULL;
unsigned int *slaves_channels = NULL; unsigned int *slaves_channels = NULL;
int *channels_sidx = NULL; int *channels_sidx = NULL;
@ -731,7 +730,6 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
} }
slaves_id = calloc(slaves_count, sizeof(*slaves_id)); slaves_id = calloc(slaves_count, sizeof(*slaves_id));
slaves_conf = calloc(slaves_count, sizeof(*slaves_conf)); slaves_conf = calloc(slaves_count, sizeof(*slaves_conf));
slaves_args = calloc(slaves_count, sizeof(*slaves_args));
slaves_pcm = calloc(slaves_count, sizeof(*slaves_pcm)); slaves_pcm = calloc(slaves_count, sizeof(*slaves_pcm));
slaves_channels = calloc(slaves_count, sizeof(*slaves_channels)); slaves_channels = calloc(slaves_count, sizeof(*slaves_channels));
channels_sidx = calloc(channels_count, sizeof(*channels_sidx)); channels_sidx = calloc(channels_count, sizeof(*channels_sidx));
@ -744,7 +742,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *m = snd_config_iterator_entry(i); snd_config_t *m = snd_config_iterator_entry(i);
int channels; int channels;
slaves_id[idx] = snd_config_get_id(m); slaves_id[idx] = snd_config_get_id(m);
err = snd_pcm_slave_conf(root, m, &slaves_conf[idx], &slaves_args[idx], 1, err = snd_pcm_slave_conf(root, m, &slaves_conf[idx], 1,
SND_PCM_HW_PARAM_CHANNELS, 1, &channels); SND_PCM_HW_PARAM_CHANNELS, 1, &channels);
if (err < 0) if (err < 0)
goto _free; goto _free;
@ -818,7 +816,7 @@ int _snd_pcm_multi_open(snd_pcm_t **pcmp, const char *name,
} }
for (idx = 0; idx < slaves_count; ++idx) { for (idx = 0; idx < slaves_count; ++idx) {
err = snd_pcm_open_slave(&slaves_pcm[idx], root, slaves_conf[idx], slaves_args[idx], stream, mode); err = snd_pcm_open_slave(&slaves_pcm[idx], root, slaves_conf[idx], stream, mode);
if (err < 0) if (err < 0)
goto _free; goto _free;
} }
@ -836,8 +834,6 @@ _free:
} }
if (slaves_conf) if (slaves_conf)
free(slaves_conf); free(slaves_conf);
if (slaves_args)
free(slaves_args);
if (slaves_pcm) if (slaves_pcm)
free(slaves_pcm); free(slaves_pcm);
if (slaves_channels) if (slaves_channels)

View file

@ -721,7 +721,6 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *tt = NULL; snd_config_t *tt = NULL;
snd_pcm_route_ttable_entry_t *ttable = NULL; snd_pcm_route_ttable_entry_t *ttable = NULL;
unsigned int cused, sused; unsigned int cused, sused;
const char *args;
snd_config_for_each(i, next, conf) { snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n); const char *id = snd_config_get_id(n);
@ -746,7 +745,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
SNDERR("slave is not defined"); SNDERR("slave is not defined");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_slave_conf(root, slave, &sconf, &args, 0); err = snd_pcm_slave_conf(root, slave, &sconf, 0);
if (err < 0) if (err < 0)
return err; return err;
if (tt) { if (tt) {
@ -757,7 +756,7 @@ int _snd_pcm_plug_open(snd_pcm_t **pcmp, const char *name,
return err; return err;
} }
err = snd_pcm_open_slave(&spcm, root, sconf, args, stream, mode); err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_plug_open(pcmp, name, ttable, MAX_CHANNELS, cused, sused, spcm, 1); err = snd_pcm_plug_open(pcmp, name, ttable, MAX_CHANNELS, cused, sused, spcm, 1);

View file

@ -544,7 +544,6 @@ int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *slave = NULL, *sconf; snd_config_t *slave = NULL, *sconf;
snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN; snd_pcm_format_t sformat = SND_PCM_FORMAT_UNKNOWN;
int srate = -1; int srate = -1;
const char *args;
snd_config_for_each(i, next, conf) { snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n); const char *id = snd_config_get_id(n);
@ -561,7 +560,7 @@ int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
SNDERR("slave is not defined"); SNDERR("slave is not defined");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_slave_conf(root, slave, &sconf, &args, 2, err = snd_pcm_slave_conf(root, slave, &sconf, 2,
SND_PCM_HW_PARAM_FORMAT, 0, &sformat, SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
SND_PCM_HW_PARAM_RATE, 1, &srate); SND_PCM_HW_PARAM_RATE, 1, &srate);
if (err < 0) if (err < 0)
@ -571,7 +570,7 @@ int _snd_pcm_rate_open(snd_pcm_t **pcmp, const char *name,
SNDERR("slave format is not linear"); SNDERR("slave format is not linear");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_open_slave(&spcm, root, sconf, args, stream, mode); err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_rate_open(pcmp, name, err = snd_pcm_rate_open(pcmp, name,

View file

@ -848,7 +848,6 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
snd_config_t *tt = NULL; snd_config_t *tt = NULL;
snd_pcm_route_ttable_entry_t ttable[MAX_CHANNELS*MAX_CHANNELS]; snd_pcm_route_ttable_entry_t ttable[MAX_CHANNELS*MAX_CHANNELS];
unsigned int cused, sused; unsigned int cused, sused;
const char *args;
snd_config_for_each(i, next, conf) { snd_config_for_each(i, next, conf) {
snd_config_t *n = snd_config_iterator_entry(i); snd_config_t *n = snd_config_iterator_entry(i);
const char *id = snd_config_get_id(n); const char *id = snd_config_get_id(n);
@ -877,7 +876,7 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
SNDERR("ttable is not defined"); SNDERR("ttable is not defined");
return -EINVAL; return -EINVAL;
} }
err = snd_pcm_slave_conf(root, slave, &sconf, &args, 2, err = snd_pcm_slave_conf(root, slave, &sconf, 2,
SND_PCM_HW_PARAM_FORMAT, 0, &sformat, SND_PCM_HW_PARAM_FORMAT, 0, &sformat,
SND_PCM_HW_PARAM_CHANNELS, 0, &schannels); SND_PCM_HW_PARAM_CHANNELS, 0, &schannels);
if (err < 0) if (err < 0)
@ -893,7 +892,7 @@ int _snd_pcm_route_open(snd_pcm_t **pcmp, const char *name,
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_open_slave(&spcm, root, sconf, args, stream, mode); err = snd_pcm_open_slave(&spcm, root, sconf, stream, mode);
if (err < 0) if (err < 0)
return err; return err;
err = snd_pcm_route_open(pcmp, name, sformat, schannels, err = snd_pcm_route_open(pcmp, name, sformat, schannels,

View file

@ -156,32 +156,50 @@ int snd_rawmidi_open_conf(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
} }
int snd_rawmidi_open_noupdate(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp, int snd_rawmidi_open_noupdate(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
const char *name, int mode) snd_config_t *root, const char *name, int mode)
{ {
int err; int err;
snd_config_t *rawmidi_conf; snd_config_t *rawmidi_conf;
char *base, *key;
const char *args = strchr(name, ':'); const char *args = strchr(name, ':');
char *base;
if (args) { if (args) {
args++; args++;
base = alloca(args - name); base = alloca(args - name);
memcpy(base, name, args - name - 1); memcpy(base, name, args - name - 1);
base[args - name - 1] = 0; base[args - name - 1] = '\0';
} else key = strchr(base, '.');
base = (char *) name; if (key)
err = snd_config_search_alias(snd_config, "rawmidi", base, &rawmidi_conf); *key++ = '\0';
} else {
key = strchr(name, '.');
if (key) {
key++;
base = alloca(key - name);
memcpy(base, name, key - name - 1);
base[key - name - 1] = '\0';
} else
base = (char *) name;
}
if (key == NULL) {
key = base;
base = NULL;
}
err = snd_config_search_alias(root, base, key, &rawmidi_conf);
if (err < 0) { if (err < 0) {
SNDERR("Unknown RAWMIDI %s", name); (void)(base == NULL && (err = snd_config_search_alias(root, "rawmidi", key, &rawmidi_conf)));
return err; if (err < 0) {
} SNDERR("Unknown RawMidi %s", name);
if (args) {
err = snd_config_expand(rawmidi_conf, args, NULL, &rawmidi_conf);
if (err < 0)
return err; return err;
}
} }
err = snd_config_expand(rawmidi_conf, args, NULL, &rawmidi_conf);
if (err < 0) {
SNDERR("Could not expand configuration for %s: %s", name, snd_strerror(err));
return err;
}
err = snd_rawmidi_open_conf(inputp, outputp, name, rawmidi_conf, mode); err = snd_rawmidi_open_conf(inputp, outputp, name, rawmidi_conf, mode);
if (args) snd_config_delete(rawmidi_conf);
snd_config_delete(rawmidi_conf);
return err; return err;
} }
@ -204,7 +222,7 @@ int snd_rawmidi_open(snd_rawmidi_t **inputp, snd_rawmidi_t **outputp,
err = snd_config_update(); err = snd_config_update();
if (err < 0) if (err < 0)
return err; return err;
return snd_rawmidi_open_noupdate(inputp, outputp, name, mode); return snd_rawmidi_open_noupdate(inputp, outputp, snd_config, name, mode);
} }
/** /**

View file

@ -141,33 +141,51 @@ static int snd_seq_open_conf(snd_seq_t **seqp, const char *name,
return open_func(seqp, name, seq_conf, streams, mode); return open_func(seqp, name, seq_conf, streams, mode);
} }
static int snd_seq_open_noupdate(snd_seq_t **seqp, const char *name, static int snd_seq_open_noupdate(snd_seq_t **seqp, snd_config_t *root,
int streams, int mode) const char *name, int streams, int mode)
{ {
int err; int err;
snd_config_t *seq_conf; snd_config_t *seq_conf;
char *base, *key;
const char *args = strchr(name, ':'); const char *args = strchr(name, ':');
char *base;
if (args) { if (args) {
args++; args++;
base = alloca(args - name); base = alloca(args - name);
memcpy(base, name, args - name - 1); memcpy(base, name, args - name - 1);
base[args - name - 1] = 0; base[args - name - 1] = '\0';
} else key = strchr(base, '.');
base = (char *) name; if (key)
err = snd_config_search_alias(snd_config, "seq", base, &seq_conf); *key++ = '\0';
} else {
key = strchr(name, '.');
if (key) {
key++;
base = alloca(key - name);
memcpy(base, name, key - name - 1);
base[key - name - 1] = '\0';
} else
base = (char *) name;
}
if (key == NULL) {
key = base;
base = NULL;
}
err = snd_config_search_alias(root, base, key, &seq_conf);
if (err < 0) { if (err < 0) {
SNDERR("Unknown SEQ %s", name); (void)(base == NULL && (err = snd_config_search_alias(root, "seq", key, &seq_conf)));
if (err < 0) {
SNDERR("Unknown PCM %s", name);
return err;
}
}
err = snd_config_expand(seq_conf, args, NULL, &seq_conf);
if (err < 0) {
SNDERR("Could not expand configuration for %s: %s", name, snd_strerror(err));
return err; return err;
} }
if (args) {
err = snd_config_expand(seq_conf, args, NULL, &seq_conf);
if (err < 0)
return err;
}
err = snd_seq_open_conf(seqp, name, seq_conf, streams, mode); err = snd_seq_open_conf(seqp, name, seq_conf, streams, mode);
if (args) snd_config_delete(seq_conf);
snd_config_delete(seq_conf);
return err; return err;
} }
@ -209,7 +227,7 @@ int snd_seq_open(snd_seq_t **seqp, const char *name,
err = snd_config_update(); err = snd_config_update();
if (err < 0) if (err < 0)
return err; return err;
return snd_seq_open_noupdate(seqp, name, streams, mode); return snd_seq_open_noupdate(seqp, snd_config, name, streams, mode);
} }
/** /**

View file

@ -165,10 +165,10 @@ int main(int argc, char** argv)
err = snd_rawmidi_status(handle_out, ostat); err = snd_rawmidi_status(handle_out, ostat);
if (err < 0) if (err < 0)
fprintf(stderr, "output stream status error: %d\n", err); fprintf(stderr, "output stream status error: %d\n", err);
printf("input.status.avail = %li\n", snd_rawmidi_status_get_avail(istat)); printf("input.status.avail = %i\n", snd_rawmidi_status_get_avail(istat));
printf("input.status.xruns = %li\n", snd_rawmidi_status_get_xruns(istat)); printf("input.status.xruns = %i\n", snd_rawmidi_status_get_xruns(istat));
printf("output.status.avail = %li\n", snd_rawmidi_status_get_avail(ostat)); printf("output.status.avail = %i\n", snd_rawmidi_status_get_avail(ostat));
printf("output.status.xruns = %li\n", snd_rawmidi_status_get_xruns(ostat)); printf("output.status.xruns = %i\n", snd_rawmidi_status_get_xruns(ostat));
diff = timediff(end, start); diff = timediff(end, start);
printf("Time diff: %Liusec (%Li bytes/sec)\n", diff, ((long long)opos * 1000000) / diff); printf("Time diff: %Liusec (%Li bytes/sec)\n", diff, ((long long)opos * 1000000) / diff);