mirror of
https://github.com/alsa-project/alsa-lib.git
synced 2025-10-31 22:25:35 -04:00
Continued config implementation. Added incomplete support for pcm
This commit is contained in:
parent
c709eb8140
commit
244653df61
8 changed files with 329 additions and 19 deletions
|
|
@ -24,11 +24,14 @@ struct snd_config {
|
||||||
snd_config_t *father;
|
snd_config_t *father;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int snd_config_top(snd_config_t **config);
|
||||||
|
|
||||||
int snd_config_load(snd_config_t **config, FILE *fp);
|
int snd_config_load(snd_config_t *config, FILE *fp);
|
||||||
int snd_config_save(snd_config_t *config, FILE *fp);
|
int snd_config_save(snd_config_t *config, FILE *fp);
|
||||||
|
|
||||||
int snd_config_search(snd_config_t *config, char *key, snd_config_t **result);
|
int snd_config_search(snd_config_t *config, char *key, snd_config_t **result);
|
||||||
|
int snd_config_searchv(snd_config_t *config,
|
||||||
|
snd_config_t **result, ...);
|
||||||
|
|
||||||
int snd_config_add(snd_config_t *config, snd_config_t *leaf);
|
int snd_config_add(snd_config_t *config, snd_config_t *leaf);
|
||||||
int snd_config_delete(snd_config_t *config);
|
int snd_config_delete(snd_config_t *config);
|
||||||
|
|
@ -55,3 +58,15 @@ typedef struct list_head *snd_config_iterator_t;
|
||||||
|
|
||||||
#define snd_config_entry(iterator) list_entry(iterator, snd_config_t, list)
|
#define snd_config_entry(iterator) list_entry(iterator, snd_config_t, list)
|
||||||
|
|
||||||
|
static inline snd_config_type_t snd_config_type(snd_config_t *config)
|
||||||
|
{
|
||||||
|
return config->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
static inline char *snd_config_id(snd_config_t *config)
|
||||||
|
{
|
||||||
|
return config->id;
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_config_t *snd_config;
|
||||||
|
int snd_config_update();
|
||||||
|
|
|
||||||
|
|
@ -122,6 +122,9 @@ int snd_pcm_synchro(snd_pcm_synchro_cmd_t cmd,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
int snd_pcm_open(snd_pcm_t **handle, char *name,
|
||||||
|
int stream, int mode);
|
||||||
|
|
||||||
int snd_pcm_hw_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevice, int stream, int mode);
|
int snd_pcm_hw_open_subdevice(snd_pcm_t **handle, int card, int device, int subdevice, int stream, int mode);
|
||||||
int snd_pcm_hw_open(snd_pcm_t **handle, int card, int device, int stream, int mode);
|
int snd_pcm_hw_open(snd_pcm_t **handle, int card, int device, int stream, int mode);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ libasound_la_SOURCES = error.c
|
||||||
libasound_la_LIBADD = control/libcontrol.la mixer/libmixer.la pcm/libpcm.la \
|
libasound_la_LIBADD = control/libcontrol.la mixer/libmixer.la pcm/libpcm.la \
|
||||||
rawmidi/librawmidi.la timer/libtimer.la \
|
rawmidi/librawmidi.la timer/libtimer.la \
|
||||||
hwdep/libhwdep.la seq/libseq.la instr/libinstr.la \
|
hwdep/libhwdep.la seq/libseq.la instr/libinstr.la \
|
||||||
compat/libcompat.la
|
compat/libcompat.la conf/libconf.la
|
||||||
|
|
||||||
libasound_la_LDFLAGS = -version-info $(COMPATNUM)
|
libasound_la_LDFLAGS = -version-info $(COMPATNUM)
|
||||||
|
|
||||||
|
|
@ -37,4 +37,7 @@ instr/libinstr.la:
|
||||||
compat/libcompat.la:
|
compat/libcompat.la:
|
||||||
$(MAKE) -C compat libcompat.la
|
$(MAKE) -C compat libcompat.la
|
||||||
|
|
||||||
|
conf/libconf.la:
|
||||||
|
$(MAKE) -C conf libconf.la
|
||||||
|
|
||||||
INCLUDES=-I$(top_srcdir)/include
|
INCLUDES=-I$(top_srcdir)/include
|
||||||
|
|
|
||||||
152
src/conf/conf.c
152
src/conf/conf.c
|
|
@ -22,9 +22,13 @@
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.h>
|
#include <errno.h>
|
||||||
#include <stdarg.h>
|
#include <stdarg.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
#include "asoundlib.h"
|
#include "asoundlib.h"
|
||||||
#include "list.h"
|
#include "list.h"
|
||||||
|
|
||||||
|
#define SYS_ASOUNDRC "/etc/asound.conf"
|
||||||
|
#define USR_ASOUNDRC ".asoundrc"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
FILE *fp;
|
FILE *fp;
|
||||||
unsigned int line, column;
|
unsigned int line, column;
|
||||||
|
|
@ -183,7 +187,7 @@ static int get_freestring(char **string, input_t *input)
|
||||||
}
|
}
|
||||||
if (idx >= alloc) {
|
if (idx >= alloc) {
|
||||||
size_t old_alloc = alloc;
|
size_t old_alloc = alloc;
|
||||||
alloc *= 2;
|
alloc += bufsize;
|
||||||
if (old_alloc == bufsize) {
|
if (old_alloc == bufsize) {
|
||||||
buf = malloc(alloc);
|
buf = malloc(alloc);
|
||||||
memcpy(buf, _buf, old_alloc);
|
memcpy(buf, _buf, old_alloc);
|
||||||
|
|
@ -227,7 +231,7 @@ static int get_delimstring(char **string, int delim, input_t *input)
|
||||||
}
|
}
|
||||||
if (idx >= alloc) {
|
if (idx >= alloc) {
|
||||||
size_t old_alloc = alloc;
|
size_t old_alloc = alloc;
|
||||||
alloc *= 2;
|
alloc += bufsize;
|
||||||
if (old_alloc == bufsize) {
|
if (old_alloc == bufsize) {
|
||||||
buf = malloc(alloc);
|
buf = malloc(alloc);
|
||||||
memcpy(buf, _buf, old_alloc);
|
memcpy(buf, _buf, old_alloc);
|
||||||
|
|
@ -507,30 +511,30 @@ static int parse_defs(snd_config_t *father, input_t *input)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int snd_config_top(snd_config_t **config)
|
||||||
|
{
|
||||||
|
assert(config);
|
||||||
|
return _snd_config_make(config, 0, SND_CONFIG_TYPE_COMPOUND);
|
||||||
|
}
|
||||||
|
|
||||||
int snd_config_load(snd_config_t **config, FILE *fp)
|
int snd_config_load(snd_config_t *config, FILE *fp)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
input_t input;
|
input_t input;
|
||||||
snd_config_t *c;
|
|
||||||
assert(config && fp);
|
assert(config && fp);
|
||||||
err = _snd_config_make(&c, 0, SND_CONFIG_TYPE_COMPOUND);
|
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
input.fp = fp;
|
input.fp = fp;
|
||||||
input.line = 1;
|
input.line = 1;
|
||||||
input.column = 0;
|
input.column = 0;
|
||||||
input.unget = 0;
|
input.unget = 0;
|
||||||
err = parse_defs(c, &input);
|
err = parse_defs(config, &input);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
snd_config_delete(c);
|
snd_config_delete(config);
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
if (get_char(&input) != EOF) {
|
if (get_char(&input) != EOF) {
|
||||||
snd_config_delete(c);
|
snd_config_delete(config);
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
*config = c;
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -595,14 +599,18 @@ int snd_config_make(snd_config_t **config, char *id,
|
||||||
|
|
||||||
int snd_config_integer_set(snd_config_t *config, long value)
|
int snd_config_integer_set(snd_config_t *config, long value)
|
||||||
{
|
{
|
||||||
assert(config->type == SND_CONFIG_TYPE_INTEGER);
|
assert(config);
|
||||||
|
if (config->type != SND_CONFIG_TYPE_INTEGER)
|
||||||
|
return -EINVAL;
|
||||||
config->u.integer = value;
|
config->u.integer = value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int snd_config_real_set(snd_config_t *config, double value)
|
int snd_config_real_set(snd_config_t *config, double value)
|
||||||
{
|
{
|
||||||
assert(config->type == SND_CONFIG_TYPE_REAL);
|
assert(config);
|
||||||
|
if (config->type != SND_CONFIG_TYPE_REAL)
|
||||||
|
return -EINVAL;
|
||||||
config->u.real = value;
|
config->u.real = value;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -610,7 +618,8 @@ int snd_config_real_set(snd_config_t *config, double value)
|
||||||
int snd_config_string_set(snd_config_t *config, char *value)
|
int snd_config_string_set(snd_config_t *config, char *value)
|
||||||
{
|
{
|
||||||
assert(config);
|
assert(config);
|
||||||
assert(config->type == SND_CONFIG_TYPE_INTEGER);
|
if (config->type != SND_CONFIG_TYPE_STRING)
|
||||||
|
return -EINVAL;
|
||||||
if (config->u.string)
|
if (config->u.string)
|
||||||
free(config->u.string);
|
free(config->u.string);
|
||||||
config->u.string = strdup(value);
|
config->u.string = strdup(value);
|
||||||
|
|
@ -645,7 +654,8 @@ int snd_config_set(snd_config_t *config, ...)
|
||||||
int snd_config_integer_get(snd_config_t *config, long *ptr)
|
int snd_config_integer_get(snd_config_t *config, long *ptr)
|
||||||
{
|
{
|
||||||
assert(config && ptr);
|
assert(config && ptr);
|
||||||
assert(config->type == SND_CONFIG_TYPE_INTEGER);
|
if (config->type != SND_CONFIG_TYPE_INTEGER)
|
||||||
|
return -EINVAL;
|
||||||
*ptr = config->u.integer;
|
*ptr = config->u.integer;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -653,7 +663,8 @@ int snd_config_integer_get(snd_config_t *config, long *ptr)
|
||||||
int snd_config_real_get(snd_config_t *config, double *ptr)
|
int snd_config_real_get(snd_config_t *config, double *ptr)
|
||||||
{
|
{
|
||||||
assert(config && ptr);
|
assert(config && ptr);
|
||||||
assert(config->type == SND_CONFIG_TYPE_REAL);
|
if (config->type != SND_CONFIG_TYPE_REAL)
|
||||||
|
return -EINVAL;
|
||||||
*ptr = config->u.real;
|
*ptr = config->u.real;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -661,7 +672,8 @@ int snd_config_real_get(snd_config_t *config, double *ptr)
|
||||||
int snd_config_string_get(snd_config_t *config, char **ptr)
|
int snd_config_string_get(snd_config_t *config, char **ptr)
|
||||||
{
|
{
|
||||||
assert(config && ptr);
|
assert(config && ptr);
|
||||||
assert(config->type == SND_CONFIG_TYPE_INTEGER);
|
if (config->type != SND_CONFIG_TYPE_STRING)
|
||||||
|
return -EINVAL;
|
||||||
*ptr = config->u.string;
|
*ptr = config->u.string;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
@ -861,3 +873,109 @@ int snd_config_search(snd_config_t *config, char *key, snd_config_t **result)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int snd_config_searchv(snd_config_t *config,
|
||||||
|
snd_config_t **result, ...)
|
||||||
|
{
|
||||||
|
va_list arg;
|
||||||
|
const size_t bufsize = 256;
|
||||||
|
char _buf[bufsize];
|
||||||
|
char *buf = _buf;
|
||||||
|
size_t alloc = bufsize;
|
||||||
|
size_t idx = 0;
|
||||||
|
size_t dot = 0;
|
||||||
|
assert(config && result);
|
||||||
|
va_start(arg, result);
|
||||||
|
while (1) {
|
||||||
|
char *k = va_arg(arg, char *);
|
||||||
|
size_t len;
|
||||||
|
if (!k)
|
||||||
|
break;
|
||||||
|
len = strlen(k);
|
||||||
|
if (idx + len + dot>= alloc) {
|
||||||
|
size_t old_alloc = alloc;
|
||||||
|
alloc = idx + len + dot;
|
||||||
|
alloc += bufsize - alloc % bufsize;
|
||||||
|
if (old_alloc == bufsize) {
|
||||||
|
buf = malloc(alloc);
|
||||||
|
memcpy(buf, _buf, old_alloc);
|
||||||
|
} else
|
||||||
|
buf = realloc(buf, alloc);
|
||||||
|
}
|
||||||
|
if (dot)
|
||||||
|
buf[idx] = '.';
|
||||||
|
memcpy(buf + idx + dot, k, len);
|
||||||
|
idx += len + dot;
|
||||||
|
if (dot == 0)
|
||||||
|
dot = 1;
|
||||||
|
}
|
||||||
|
buf[idx] = '\0';
|
||||||
|
return snd_config_search(config, buf, result);
|
||||||
|
}
|
||||||
|
|
||||||
|
snd_config_t *snd_config = 0;
|
||||||
|
static dev_t sys_asoundrc_device;
|
||||||
|
static ino_t sys_asoundrc_inode;
|
||||||
|
static time_t sys_asoundrc_mtime;
|
||||||
|
static dev_t usr_asoundrc_device;
|
||||||
|
static ino_t usr_asoundrc_inode;
|
||||||
|
static time_t usr_asoundrc_mtime;
|
||||||
|
|
||||||
|
int snd_config_update()
|
||||||
|
{
|
||||||
|
int err;
|
||||||
|
char *usr_asoundrc = NULL;
|
||||||
|
char *home = getenv("HOME");
|
||||||
|
struct stat st;
|
||||||
|
int reload;
|
||||||
|
FILE *fp;
|
||||||
|
if (home) {
|
||||||
|
size_t len = strlen(home);
|
||||||
|
size_t len1 = strlen(USR_ASOUNDRC);
|
||||||
|
usr_asoundrc = alloca(len + len1 + 2);
|
||||||
|
memcpy(usr_asoundrc, home, len);
|
||||||
|
usr_asoundrc[len] = '/';
|
||||||
|
memcpy(usr_asoundrc + len + 1, USR_ASOUNDRC, len1);
|
||||||
|
usr_asoundrc[len + 1 + len1] = '\0';
|
||||||
|
}
|
||||||
|
reload = (snd_config == NULL);
|
||||||
|
if (!reload &&
|
||||||
|
stat(usr_asoundrc, &st) == 0 &&
|
||||||
|
(st.st_dev != usr_asoundrc_device ||
|
||||||
|
st.st_ino != usr_asoundrc_inode ||
|
||||||
|
st.st_mtime != usr_asoundrc_mtime))
|
||||||
|
reload = 1;
|
||||||
|
if (!reload &&
|
||||||
|
stat(SYS_ASOUNDRC, &st) == 0 &&
|
||||||
|
(st.st_dev != sys_asoundrc_device ||
|
||||||
|
st.st_ino != sys_asoundrc_inode ||
|
||||||
|
st.st_mtime != sys_asoundrc_mtime))
|
||||||
|
reload = 1;
|
||||||
|
if (!reload)
|
||||||
|
return 0;
|
||||||
|
if (snd_config == NULL) {
|
||||||
|
err = snd_config_top(&snd_config);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
fp = fopen(SYS_ASOUNDRC, "r");
|
||||||
|
if (fp) {
|
||||||
|
err = snd_config_load(snd_config, fp);
|
||||||
|
if (err < 0) {
|
||||||
|
snd_config = NULL;
|
||||||
|
fclose(fp);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
fp = fopen(usr_asoundrc, "r");
|
||||||
|
if (fp) {
|
||||||
|
err = snd_config_load(snd_config, fp);
|
||||||
|
if (err < 0) {
|
||||||
|
snd_config = NULL;
|
||||||
|
fclose(fp);
|
||||||
|
return err;
|
||||||
|
}
|
||||||
|
fclose(fp);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
||||||
168
src/pcm/pcm.c
168
src/pcm/pcm.c
|
|
@ -27,6 +27,7 @@
|
||||||
#include <sys/poll.h>
|
#include <sys/poll.h>
|
||||||
#include <sys/uio.h>
|
#include <sys/uio.h>
|
||||||
#include "pcm_local.h"
|
#include "pcm_local.h"
|
||||||
|
#include "list.h"
|
||||||
|
|
||||||
snd_pcm_type_t snd_pcm_type(snd_pcm_t *handle)
|
snd_pcm_type_t snd_pcm_type(snd_pcm_t *handle)
|
||||||
{
|
{
|
||||||
|
|
@ -501,3 +502,170 @@ ssize_t snd_pcm_samples_to_bytes(snd_pcm_t *handle, ssize_t samples)
|
||||||
return samples * handle->bits_per_sample / 8;
|
return samples * handle->bits_per_sample / 8;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int _snd_pcm_open_hw(snd_pcm_t **handlep, snd_config_t *conf,
|
||||||
|
int stream, int mode)
|
||||||
|
{
|
||||||
|
snd_config_iterator_t i;
|
||||||
|
long card = -1, device = -1, subdevice = -1;
|
||||||
|
char *str;
|
||||||
|
int err;
|
||||||
|
snd_config_foreach(i, conf) {
|
||||||
|
snd_config_t *n = snd_config_entry(i);
|
||||||
|
if (strcmp(n->id, "comment") == 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(n->id, "type") == 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(n->id, "stream") == 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(n->id, "card") == 0) {
|
||||||
|
err = snd_config_integer_get(n, &card);
|
||||||
|
if (err < 0) {
|
||||||
|
err = snd_config_string_get(n, &str);
|
||||||
|
if (err < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
card = snd_card_name(str);
|
||||||
|
if (card < 0)
|
||||||
|
return card;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(n->id, "device") == 0) {
|
||||||
|
err = snd_config_integer_get(n, &device);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(n->id, "subdevice") == 0) {
|
||||||
|
err = snd_config_integer_get(n, &subdevice);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (card < 0 || device < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
return snd_pcm_hw_open_subdevice(handlep, card, device, subdevice, stream, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _snd_pcm_open_plug(snd_pcm_t **handlep, snd_config_t *conf,
|
||||||
|
int stream, int mode)
|
||||||
|
{
|
||||||
|
snd_config_iterator_t i;
|
||||||
|
long card = -1, device = -1, subdevice = -1;
|
||||||
|
char *str;
|
||||||
|
int err;
|
||||||
|
snd_config_foreach(i, conf) {
|
||||||
|
snd_config_t *n = snd_config_entry(i);
|
||||||
|
if (strcmp(n->id, "comment") == 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(n->id, "type") == 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(n->id, "stream") == 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(n->id, "card") == 0) {
|
||||||
|
err = snd_config_integer_get(n, &card);
|
||||||
|
if (err < 0) {
|
||||||
|
err = snd_config_string_get(n, &str);
|
||||||
|
if (err < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
card = snd_card_name(str);
|
||||||
|
if (card < 0)
|
||||||
|
return card;
|
||||||
|
}
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(n->id, "device") == 0) {
|
||||||
|
err = snd_config_integer_get(n, &device);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(n->id, "subdevice") == 0) {
|
||||||
|
err = snd_config_integer_get(n, &subdevice);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
if (card < 0 || device < 0)
|
||||||
|
return -EINVAL;
|
||||||
|
return snd_pcm_plug_open_subdevice(handlep, card, device, subdevice, stream, mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int _snd_pcm_open_multi(snd_pcm_t **handle, snd_config_t *conf,
|
||||||
|
int stream, int mode)
|
||||||
|
{
|
||||||
|
snd_config_iterator_t i;
|
||||||
|
char *str;
|
||||||
|
int err;
|
||||||
|
snd_config_foreach(i, conf) {
|
||||||
|
snd_config_t *n = snd_config_entry(i);
|
||||||
|
if (strcmp(n->id, "comment") == 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(n->id, "type") == 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(n->id, "stream") == 0)
|
||||||
|
continue;
|
||||||
|
if (strcmp(n->id, "slave") == 0) {
|
||||||
|
if (snd_config_type(n) != SND_CONFIG_TYPE_COMPOUND)
|
||||||
|
return -EINVAL;
|
||||||
|
/* Not yet implemented */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
if (strcmp(n->id, "binding") == 0) {
|
||||||
|
if (snd_config_type(n) != SND_CONFIG_TYPE_COMPOUND)
|
||||||
|
return -EINVAL;
|
||||||
|
/* Not yet implemented */
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
return -ENOSYS;
|
||||||
|
}
|
||||||
|
|
||||||
|
int snd_pcm_open(snd_pcm_t **handlep, char *name,
|
||||||
|
int stream, int mode)
|
||||||
|
{
|
||||||
|
char *str;
|
||||||
|
int err;
|
||||||
|
snd_config_t *pcm_conf, *conf;
|
||||||
|
assert(handlep && name);
|
||||||
|
err = snd_config_update();
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
err = snd_config_searchv(snd_config, &pcm_conf, "pcm", name, 0);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
if (snd_config_type(pcm_conf) != SND_CONFIG_TYPE_COMPOUND)
|
||||||
|
return -EINVAL;
|
||||||
|
err = snd_config_search(pcm_conf, "stream", &conf);
|
||||||
|
if (err >= 0) {
|
||||||
|
err = snd_config_string_get(conf, &str);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
if (strcmp(str, "playback") == 0) {
|
||||||
|
if (stream != SND_PCM_STREAM_PLAYBACK)
|
||||||
|
return -EINVAL;
|
||||||
|
} else if (strcmp(str, "capture") == 0) {
|
||||||
|
if (stream != SND_PCM_STREAM_CAPTURE)
|
||||||
|
return -EINVAL;
|
||||||
|
} else
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
err = snd_config_search(pcm_conf, "type", &conf);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
err = snd_config_string_get(conf, &str);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
if (strcmp(str, "hw") == 0)
|
||||||
|
return _snd_pcm_open_hw(handlep, pcm_conf, stream, mode);
|
||||||
|
else if (strcmp(str, "plug") == 0)
|
||||||
|
return _snd_pcm_open_plug(handlep, pcm_conf, stream, mode);
|
||||||
|
else if (strcmp(str, "multi") == 0)
|
||||||
|
return _snd_pcm_open_multi(handlep, pcm_conf, stream, mode);
|
||||||
|
else
|
||||||
|
return -EINVAL;
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -406,6 +406,7 @@ int snd_pcm_hw_open_subdevice(snd_pcm_t **handlep, int card, int device, int sub
|
||||||
snd_pcm_t *handle;
|
snd_pcm_t *handle;
|
||||||
snd_pcm_hw_t *hw;
|
snd_pcm_hw_t *hw;
|
||||||
|
|
||||||
|
assert(handlep);
|
||||||
*handlep = 0;
|
*handlep = 0;
|
||||||
|
|
||||||
if ((ret = snd_ctl_open(&ctl, card)) < 0)
|
if ((ret = snd_ctl_open(&ctl, card)) < 0)
|
||||||
|
|
|
||||||
|
|
@ -737,6 +737,7 @@ int snd_pcm_multi_create(snd_pcm_t **handlep, size_t slaves_count,
|
||||||
char client_map[32] = { 0 };
|
char client_map[32] = { 0 };
|
||||||
char slave_map[32][32] = { { 0 } };
|
char slave_map[32][32] = { { 0 } };
|
||||||
|
|
||||||
|
assert(handlep);
|
||||||
assert(slaves_count > 0 && slaves_handle && slaves_channels_count);
|
assert(slaves_count > 0 && slaves_handle && slaves_channels_count);
|
||||||
assert(binds_count > 0 && binds_slave && binds_client_channel && binds_slave_channel);
|
assert(binds_count > 0 && binds_slave && binds_client_channel && binds_slave_channel);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -789,6 +789,7 @@ int snd_pcm_plug_create(snd_pcm_t **handlep, snd_pcm_t *slave, int close_slave)
|
||||||
{
|
{
|
||||||
snd_pcm_t *handle;
|
snd_pcm_t *handle;
|
||||||
snd_pcm_plug_t *plug;
|
snd_pcm_plug_t *plug;
|
||||||
|
assert(handlep && slave);
|
||||||
handle = calloc(1, sizeof(snd_pcm_t));
|
handle = calloc(1, sizeof(snd_pcm_t));
|
||||||
if (!handle)
|
if (!handle)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue