参照元†
- snd_pcm_t **pcmp
- const char *name
- snd_config_t *pcm_root
- snd_config_t *pcm_conf
- snd_pcm_stream_t stream
- int mode
返り値†
static int snd_pcm_open_conf(snd_pcm_t **pcmp, const char *name,
snd_config_t *pcm_root, snd_config_t *pcm_conf,
snd_pcm_stream_t stream, int mode)
{
const char *str;
char *buf = NULL, *buf1 = NULL;
int err;
snd_config_t *conf, *type_conf = NULL, *tmp;
snd_config_iterator_t i, next;
const char *id;
const char *lib = NULL, *open_name = NULL;
int (*open_func)(snd_pcm_t **, const char *,
snd_config_t *, snd_config_t *,
snd_pcm_stream_t, int) = NULL;
#ifndef PIC
extern void *snd_pcm_open_symbols(void);
#endif
if (snd_config_get_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND) {
char *val;
id = NULL;
snd_config_get_id(pcm_conf, &id);
val = NULL;
snd_config_get_ascii(pcm_conf, &val);
SNDERR("Invalid type for PCM %s%sdefinition (id: %s, value: %s)", name ? name : "", name ? " " : "", id, val);
free(val);
return -EINVAL;
}
err = snd_config_search(pcm_conf, "type", &conf);
if (err < 0) {
SNDERR("type is not defined");
return err;
}
err = snd_config_get_id(conf, &id);
if (err < 0) {
SNDERR("unable to get id");
return err;
}
err = snd_config_get_string(conf, &str);
if (err < 0) {
SNDERR("Invalid type for %s", id);
return err;
}
err = snd_config_search_definition(pcm_root, "pcm_type", str, &type_conf);
if (err >= 0) {
if (snd_config_get_type(type_conf) != SND_CONFIG_TYPE_COMPOUND) {
SNDERR("Invalid type for PCM type %s definition", str);
goto _err;
}
snd_config_for_each(i, next, type_conf) {
snd_config_t *n = snd_config_iterator_entry(i);
const char *id;
if (snd_config_get_id(n, &id) < 0)
continue;
if (strcmp(id, "comment") == 0)
continue;
if (strcmp(id, "lib") == 0) {
err = snd_config_get_string(n, &lib);
if (err < 0) {
SNDERR("Invalid type for %s", id);
goto _err;
}
continue;
}
if (strcmp(id, "open") == 0) {
err = snd_config_get_string(n, &open_name);
if (err < 0) {
SNDERR("Invalid type for %s", id);
goto _err;
}
continue;
}
SNDERR("Unknown field %s", id);
err = -EINVAL;
goto _err;
}
}
if (!open_name) {
buf = malloc(strlen(str) + 32);
if (buf == NULL) {
err = -ENOMEM;
goto _err;
}
open_name = buf;
sprintf(buf, "_snd_pcm_%s_open", str);
}
if (!lib) {
const char *const *build_in = build_in_pcms;
while (*build_in) {
if (!strcmp(*build_in, str))
break;
build_in++;
}
if (*build_in == NULL) {
buf1 = malloc(strlen(str) + sizeof(ALSA_PLUGIN_DIR) + 32);
if (buf1 == NULL) {
err = -ENOMEM;
goto _err;
}
lib = buf1;
sprintf(buf1, "%s/libasound_module_pcm_%s.so", ALSA_PLUGIN_DIR, str);
}
}
#ifndef PIC
snd_pcm_open_symbols(); /* this call is for static linking only */
#endif
open_func = snd_dlobj_cache_get(lib, open_name,
SND_DLSYM_VERSION(SND_PCM_DLSYM_VERSION), 1);
if (open_func) {
err = open_func(pcmp, name, pcm_root, pcm_conf, stream, mode);
if (err >= 0) {
if ((*pcmp)->open_func) {
/* only init plugin (like empty, asym) */
snd_dlobj_cache_put(open_func);
} else {
(*pcmp)->open_func = open_func;
}
err = 0;
} else {
snd_dlobj_cache_put(open_func);
}
} else {
err = -ENXIO;
}
if (err >= 0) {
err = snd_config_search(pcm_root, "defaults.pcm.compat", &tmp);
if (err >= 0) {
long i;
if (snd_config_get_integer(tmp, &i) >= 0) {
if (i > 0)
(*pcmp)->compat = 1;
}
} else {
char *str = getenv("LIBASOUND_COMPAT");
if (str && *str)
(*pcmp)->compat = 1;
}
err = snd_config_search(pcm_root, "defaults.pcm.minperiodtime", &tmp);
if (err >= 0)
snd_config_get_integer(tmp, &(*pcmp)->minperiodtime);
err = 0;
}
_err:
if (type_conf)
snd_config_delete(type_conf);
free(buf);
free(buf1);
return err;
}
コメント†