int snd_config_make(snd_config_t **config, char *key,
snd_config_type_t type);
+int snd_config_integer_make(snd_config_t **config, char *key);
+int snd_config_real_make(snd_config_t **config, char *key);
+int snd_config_string_make(snd_config_t **config, char *key);
+int snd_config_compound_make(snd_config_t **config, char *key, int join);
int snd_config_integer_set(snd_config_t *config, long value);
int snd_config_real_set(snd_config_t *config, double value);
int snd_card_load(int card);
int snd_cards(void);
unsigned int snd_cards_mask(void);
-int snd_card_name(const char *name);
+int snd_card_get_index(const char *name);
int snd_card_get_name(int card, char **name);
int snd_card_get_longname(int card, char **name);
int snd_ctl_open(snd_ctl_t **handle, int card);
int snd_ctl_close(snd_ctl_t *handle);
int snd_ctl_file_descriptor(snd_ctl_t *handle);
-int snd_ctl_hw_info(snd_ctl_t *handle, struct snd_ctl_hw_info *info);
+int snd_ctl_hw_info(snd_ctl_t *handle, snd_ctl_hw_info_t *info);
int snd_ctl_clist(snd_ctl_t *handle, snd_control_list_t * list);
int snd_ctl_cinfo(snd_ctl_t *handle, snd_control_info_t * sw);
int snd_ctl_cread(snd_ctl_t *handle, snd_control_t * control);
struct list_head *next, *prev;
};
+/**
+ * list_entry - get the struct for this entry
+ * @ptr: the &struct list_head pointer.
+ * @type: the type of the struct this is embedded in.
+ * @member: the name of the list_struct within the struct.
+ */
+#define list_entry(ptr, type, member) \
+ ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
+
+
typedef struct snd_hcontrol_list_stru snd_hcontrol_list_t;
typedef struct snd_hcontrol_stru snd_hcontrol_t;
}
}
-/**
- * list_entry - get the struct for this entry
- * @ptr: the &struct list_head pointer.
- * @type: the type of the struct this is embedded in.
- * @member: the name of the list_struct within the struct.
- */
-#define list_entry(ptr, type, member) \
- ((type *)((char *)(ptr)-(unsigned long)(&((type *)0)->member)))
-
/**
* list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter.
#define SYS_ASOUNDRC "/etc/asound.conf"
#define USR_ASOUNDRC ".asoundrc"
-typedef struct {
+struct filedesc {
+ char *name;
FILE *fp;
unsigned int line, column;
+ struct filedesc *next;
+};
+
+typedef struct {
+ struct filedesc *current;
int unget;
int ch;
enum {
static int get_char(input_t *input)
{
int c;
+ struct filedesc *fd;
if (input->unget) {
input->unget = 0;
return input->ch;
}
- c = getc(input->fp);
+ again:
+ fd = input->current;
+ c = getc(fd->fp);
switch (c) {
case '\n':
- input->column = 0;
- input->line++;
+ fd->column = 0;
+ fd->line++;
break;
case '\t':
- input->column += 8 - input->column % 8;
+ fd->column += 8 - fd->column % 8;
break;
case EOF:
+ if (fd->next) {
+ fclose(fd->fp);
+ free(fd->name);
+ input->current = fd->next;
+ free(fd);
+ goto again;
+ }
break;
default:
- input->column++;
+ fd->column++;
break;
}
return c;
input->unget = 1;
}
+static int get_delimstring(char **string, int delim, input_t *input);
+
static int get_char_skip_comments(input_t *input)
{
int c;
while (1) {
c = get_char(input);
+ if (c == '<') {
+ char *file;
+ FILE *fp;
+ struct filedesc *fd;
+ int err = get_delimstring(&file, '>', input);
+ if (err < 0)
+ return err;
+ fp = fopen(file, "r");
+ if (!fp)
+ return -errno;
+ fd = malloc(sizeof(*fd));
+ fd->name = file;
+ fd->fp = fp;
+ fd->next = input->current;
+ fd->line = 1;
+ fd->column = 0;
+ input->current = fd;
+ continue;
+ }
if (c != '#')
break;
while (1) {
break;
}
}
+
return c;
}
+
static int get_nonwhite(input_t *input)
{
int c;
snd_config_t *n;
enum {MERGE, NOCREATE, REMOVE} mode;
while (1) {
+#if 0
c = get_nonwhite(input);
switch (c) {
case '?':
mode = MERGE;
unget_char(c, input);
}
+#else
+ mode = MERGE;
+#endif
err = get_string(&id, input);
if (err < 0)
return err;
{
int err;
input_t input;
+ struct filedesc *fd;
assert(config && fp);
- input.fp = fp;
- input.line = 1;
- input.column = 0;
+ fd = malloc(sizeof(*fd));
+ fd->name = NULL;
+ fd->fp = fp;
+ fd->line = 1;
+ fd->column = 0;
+ fd->next = NULL;
+ input.current = fd;
input.unget = 0;
err = parse_defs(config, &input);
if (err < 0) {
return 0;
}
-int snd_config_add(snd_config_t *config, snd_config_t *leaf)
+int snd_config_add(snd_config_t *father, snd_config_t *leaf)
{
snd_config_iterator_t i;
- assert(config && leaf);
- snd_config_foreach(i, config) {
+ assert(father && leaf);
+ snd_config_foreach(i, father) {
snd_config_t *n = snd_config_entry(i);
if (strcmp(leaf->id, n->id) == 0)
return -EEXIST;
}
- leaf->father = config;
- list_add_tail(&leaf->list, &config->u.compound.fields);
+ leaf->father = father;
+ list_add_tail(&leaf->list, &father->u.compound.fields);
return 0;
}
return -ENOMEM;
} else
id1 = NULL;
- return _snd_config_make(config, id, type);
+ return _snd_config_make(config, id1, type);
+}
+
+int snd_config_integer_make(snd_config_t **config, char *id)
+{
+ return snd_config_make(config, id, SND_CONFIG_TYPE_INTEGER);
+}
+
+int snd_config_real_make(snd_config_t **config, char *id)
+{
+ return snd_config_make(config, id, SND_CONFIG_TYPE_REAL);
+}
+
+int snd_config_string_make(snd_config_t **config, char *id)
+{
+ return snd_config_make(config, id, SND_CONFIG_TYPE_STRING);
+}
+
+int snd_config_compound_make(snd_config_t **config, char *id,
+ int join)
+{
+ int err;
+ err = snd_config_make(config, id, SND_CONFIG_TYPE_COMPOUND);
+ if (err < 0)
+ return err;
+ (*config)->u.compound.join = join;
+ return 0;
}
int snd_config_integer_set(snd_config_t *config, long value)
snd_config_t *n;
int err;
char *p = strchr(key, '.');
+ if (config->type != SND_CONFIG_TYPE_COMPOUND)
+ return -ENOENT;
if (p) {
err = _snd_config_search(config, key, p - key, &n);
if (err < 0)
return err;
- if (n->type != SND_CONFIG_TYPE_COMPOUND)
- return -EINVAL;
config = n;
key = p + 1;
} else
int snd_config_searchv(snd_config_t *config,
snd_config_t **result, ...)
{
+ snd_config_t *n;
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;
+ int err;
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);
+ if (config->type != SND_CONFIG_TYPE_COMPOUND)
+ return -ENOENT;
+ err = _snd_config_search(config, k, -1, &n);
+ if (err < 0)
+ return err;
+ config = n;
+ }
+ va_end(arg);
+ *result = n;
+ return 0;
}
snd_config_t *snd_config = 0;
{
int open_dev;
char control[32];
- char aload[32];
sprintf(control, SND_FILE_CONTROL, card);
- sprintf(aload, SND_FILE_LOAD, card);
if ((open_dev=open(control, O_RDONLY)) < 0) {
- close(open(aload, O_RDONLY));
- } else {
+ char aload[32];
+ sprintf(aload, SND_FILE_LOAD, card);
+ open_dev = open(aload, O_RDONLY);
+ }
+ if (open_dev >= 0) {
close (open_dev);
+ return 0;
}
- return 0;
+ return open_dev;
}
int snd_cards(void)
unsigned int snd_cards_mask(void)
{
- int fd, idx;
+ int idx;
unsigned int mask;
- char filename[32];
static unsigned int save_mask = 0;
if (save_mask)
return save_mask;
for (idx = 0, mask = 0; idx < SND_CARDS; idx++) {
- snd_card_load(idx);
- sprintf(filename, SND_FILE_CONTROL, idx);
- if ((fd = open(filename, O_RDWR)) < 0) {
- snd_card_load(idx);
- if ((fd = open(filename, O_RDWR)) < 0)
- continue;
- }
- close(fd);
- mask |= 1 << idx;
+ if (snd_card_load(idx) >= 0)
+ mask |= 1 << idx;
}
save_mask = mask;
return mask;
}
-int snd_card_name(const char *string)
+int snd_card_get_index(const char *string)
{
- int card, bitmask;
+ int card;
snd_ctl_t *handle;
- struct snd_ctl_hw_info info;
+ snd_ctl_hw_info_t info;
if (!string || *string == '\0')
return -EINVAL;
- bitmask = snd_cards_mask();
- if (!bitmask)
- return -ENODEV;
if ((isdigit(*string) && *(string + 1) == 0) ||
(isdigit(*string) && isdigit(*(string + 1)) && *(string + 2) == 0)) {
sscanf(string, "%i", &card);
if (card < 0 || card > 31)
return -EINVAL;
- if (card < 0 || !((1 << card) & bitmask))
- return -EINVAL;
- return card;
+ if (snd_card_load(card) >= 0)
+ return card;
+ return -EINVAL;
}
for (card = 0; card < 32; card++) {
- if (!((1 << card) & bitmask))
+ if (snd_card_load(card) < 0)
continue;
if (snd_ctl_open(&handle, card) < 0)
continue;
int snd_card_get_name(int card, char **name)
{
snd_ctl_t *handle;
- struct snd_ctl_hw_info info;
+ snd_ctl_hw_info_t info;
int err;
if (name == NULL)
int snd_card_get_longname(int card, char **name)
{
snd_ctl_t *handle;
- struct snd_ctl_hw_info info;
+ snd_ctl_hw_info_t info;
int err;
if (name == NULL)
return handle->fd;
}
-int snd_ctl_hw_info(snd_ctl_t *handle, struct snd_ctl_hw_info *info)
+int snd_ctl_hw_info(snd_ctl_t *handle, snd_ctl_hw_info_t *info)
{
assert(handle && info);
if (ioctl(handle->fd, SND_CTL_IOCTL_HW_INFO, info) < 0)
e = getenv(env);
if (!e)
return -ENOENT;
- return snd_card_name(e);
+ return snd_card_get_index(e);
}
static int defaults_device(const char *env)
err = snd_config_string_get(n, &str);
if (err < 0)
return -EINVAL;
- card = snd_card_name(str);
+ card = snd_card_get_index(str);
if (card < 0)
return card;
}
err = snd_config_string_get(n, &str);
if (err < 0)
return -EINVAL;
- card = snd_card_name(str);
+ card = snd_card_get_index(str);
if (card < 0)
return card;
}
{
int idx, idx1, cards, err;
snd_ctl_t *handle;
- struct snd_ctl_hw_info info;
+ snd_ctl_hw_info_t info;
snd_pcm_info_t pcminfo;
snd_mixer_info_t mixerinfo;
snd_rawmidi_info_t rawmidiinfo;
{
int idx, idx1, cards, err;
snd_ctl_t *handle;
- struct snd_ctl_hw_info info;
+ snd_ctl_hw_info_t info;
cards = snd_cards();
printf("Detected %i soundcard%s...\n", cards, cards > 1 ? "s" : "");