Completed conf. Better name for snd_card_get_index. Cleaned card access

This commit is contained in:
Abramo Bagnara 2000-08-25 14:33:53 +00:00
parent 845d917797
commit b5576ef229
10 changed files with 144 additions and 89 deletions

View file

@ -38,6 +38,10 @@ int snd_config_delete(snd_config_t *config);
int snd_config_make(snd_config_t **config, char *key, int snd_config_make(snd_config_t **config, char *key,
snd_config_type_t type); 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_integer_set(snd_config_t *config, long value);
int snd_config_real_set(snd_config_t *config, double value); int snd_config_real_set(snd_config_t *config, double value);

View file

@ -24,7 +24,7 @@ extern "C" {
int snd_card_load(int card); int snd_card_load(int card);
int snd_cards(void); int snd_cards(void);
unsigned int snd_cards_mask(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_name(int card, char **name);
int snd_card_get_longname(int card, char **name); int snd_card_get_longname(int card, char **name);
@ -38,7 +38,7 @@ int snd_defaults_rawmidi_device(void);
int snd_ctl_open(snd_ctl_t **handle, int card); int snd_ctl_open(snd_ctl_t **handle, int card);
int snd_ctl_close(snd_ctl_t *handle); int snd_ctl_close(snd_ctl_t *handle);
int snd_ctl_file_descriptor(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_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_cinfo(snd_ctl_t *handle, snd_control_info_t * sw);
int snd_ctl_cread(snd_ctl_t *handle, snd_control_t * control); int snd_ctl_cread(snd_ctl_t *handle, snd_control_t * control);
@ -63,6 +63,16 @@ struct list_head {
struct list_head *next, *prev; 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_list_stru snd_hcontrol_list_t;
typedef struct snd_hcontrol_stru snd_hcontrol_t; typedef struct snd_hcontrol_stru snd_hcontrol_t;

View file

@ -136,15 +136,6 @@ static __inline__ void list_splice(struct list_head *list, struct list_head *hea
} }
} }
/**
* 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 * list_for_each - iterate over a list
* @pos: the &struct list_head to use as a loop counter. * @pos: the &struct list_head to use as a loop counter.

View file

@ -29,9 +29,15 @@
#define SYS_ASOUNDRC "/etc/asound.conf" #define SYS_ASOUNDRC "/etc/asound.conf"
#define USR_ASOUNDRC ".asoundrc" #define USR_ASOUNDRC ".asoundrc"
typedef struct { struct filedesc {
char *name;
FILE *fp; FILE *fp;
unsigned int line, column; unsigned int line, column;
struct filedesc *next;
};
typedef struct {
struct filedesc *current;
int unget; int unget;
int ch; int ch;
enum { enum {
@ -45,23 +51,33 @@ typedef struct {
static int get_char(input_t *input) static int get_char(input_t *input)
{ {
int c; int c;
struct filedesc *fd;
if (input->unget) { if (input->unget) {
input->unget = 0; input->unget = 0;
return input->ch; return input->ch;
} }
c = getc(input->fp); again:
fd = input->current;
c = getc(fd->fp);
switch (c) { switch (c) {
case '\n': case '\n':
input->column = 0; fd->column = 0;
input->line++; fd->line++;
break; break;
case '\t': case '\t':
input->column += 8 - input->column % 8; fd->column += 8 - fd->column % 8;
break; break;
case EOF: case EOF:
if (fd->next) {
fclose(fd->fp);
free(fd->name);
input->current = fd->next;
free(fd);
goto again;
}
break; break;
default: default:
input->column++; fd->column++;
break; break;
} }
return c; return c;
@ -74,11 +90,32 @@ static void unget_char(int c, input_t *input)
input->unget = 1; input->unget = 1;
} }
static int get_delimstring(char **string, int delim, input_t *input);
static int get_char_skip_comments(input_t *input) static int get_char_skip_comments(input_t *input)
{ {
int c; int c;
while (1) { while (1) {
c = get_char(input); 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 != '#') if (c != '#')
break; break;
while (1) { while (1) {
@ -89,9 +126,11 @@ static int get_char_skip_comments(input_t *input)
break; break;
} }
} }
return c; return c;
} }
static int get_nonwhite(input_t *input) static int get_nonwhite(input_t *input)
{ {
int c; int c;
@ -346,6 +385,7 @@ static int parse_def(snd_config_t *father, input_t *input)
snd_config_t *n; snd_config_t *n;
enum {MERGE, NOCREATE, REMOVE} mode; enum {MERGE, NOCREATE, REMOVE} mode;
while (1) { while (1) {
#if 0
c = get_nonwhite(input); c = get_nonwhite(input);
switch (c) { switch (c) {
case '?': case '?':
@ -358,6 +398,9 @@ static int parse_def(snd_config_t *father, input_t *input)
mode = MERGE; mode = MERGE;
unget_char(c, input); unget_char(c, input);
} }
#else
mode = MERGE;
#endif
err = get_string(&id, input); err = get_string(&id, input);
if (err < 0) if (err < 0)
return err; return err;
@ -521,10 +564,15 @@ int snd_config_load(snd_config_t *config, FILE *fp)
{ {
int err; int err;
input_t input; input_t input;
struct filedesc *fd;
assert(config && fp); assert(config && fp);
input.fp = fp; fd = malloc(sizeof(*fd));
input.line = 1; fd->name = NULL;
input.column = 0; fd->fp = fp;
fd->line = 1;
fd->column = 0;
fd->next = NULL;
input.current = fd;
input.unget = 0; input.unget = 0;
err = parse_defs(config, &input); err = parse_defs(config, &input);
if (err < 0) { if (err < 0) {
@ -538,17 +586,17 @@ int snd_config_load(snd_config_t *config, FILE *fp)
return 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; snd_config_iterator_t i;
assert(config && leaf); assert(father && leaf);
snd_config_foreach(i, config) { snd_config_foreach(i, father) {
snd_config_t *n = snd_config_entry(i); snd_config_t *n = snd_config_entry(i);
if (strcmp(leaf->id, n->id) == 0) if (strcmp(leaf->id, n->id) == 0)
return -EEXIST; return -EEXIST;
} }
leaf->father = config; leaf->father = father;
list_add_tail(&leaf->list, &config->u.compound.fields); list_add_tail(&leaf->list, &father->u.compound.fields);
return 0; return 0;
} }
@ -594,7 +642,33 @@ int snd_config_make(snd_config_t **config, char *id,
return -ENOMEM; return -ENOMEM;
} else } else
id1 = NULL; 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) int snd_config_integer_set(snd_config_t *config, long value)
@ -860,12 +934,12 @@ int snd_config_search(snd_config_t *config, char *key, snd_config_t **result)
snd_config_t *n; snd_config_t *n;
int err; int err;
char *p = strchr(key, '.'); char *p = strchr(key, '.');
if (config->type != SND_CONFIG_TYPE_COMPOUND)
return -ENOENT;
if (p) { if (p) {
err = _snd_config_search(config, key, p - key, &n); err = _snd_config_search(config, key, p - key, &n);
if (err < 0) if (err < 0)
return err; return err;
if (n->type != SND_CONFIG_TYPE_COMPOUND)
return -EINVAL;
config = n; config = n;
key = p + 1; key = p + 1;
} else } else
@ -876,40 +950,25 @@ int snd_config_search(snd_config_t *config, char *key, snd_config_t **result)
int snd_config_searchv(snd_config_t *config, int snd_config_searchv(snd_config_t *config,
snd_config_t **result, ...) snd_config_t **result, ...)
{ {
snd_config_t *n;
va_list arg; 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); assert(config && result);
va_start(arg, result); va_start(arg, result);
while (1) { while (1) {
char *k = va_arg(arg, char *); char *k = va_arg(arg, char *);
size_t len; int err;
if (!k) if (!k)
break; break;
len = strlen(k); if (config->type != SND_CONFIG_TYPE_COMPOUND)
if (idx + len + dot>= alloc) { return -ENOENT;
size_t old_alloc = alloc; err = _snd_config_search(config, k, -1, &n);
alloc = idx + len + dot; if (err < 0)
alloc += bufsize - alloc % bufsize; return err;
if (old_alloc == bufsize) { config = n;
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'; va_end(arg);
return snd_config_search(config, buf, result); *result = n;
return 0;
} }
snd_config_t *snd_config = 0; snd_config_t *snd_config = 0;

View file

@ -36,17 +36,19 @@ int snd_card_load(int card)
{ {
int open_dev; int open_dev;
char control[32]; char control[32];
char aload[32];
sprintf(control, SND_FILE_CONTROL, card); sprintf(control, SND_FILE_CONTROL, card);
sprintf(aload, SND_FILE_LOAD, card);
if ((open_dev=open(control, O_RDONLY)) < 0) { if ((open_dev=open(control, O_RDONLY)) < 0) {
close(open(aload, O_RDONLY)); char aload[32];
} else { sprintf(aload, SND_FILE_LOAD, card);
close (open_dev); open_dev = open(aload, O_RDONLY);
} }
return 0; if (open_dev >= 0) {
close (open_dev);
return 0;
}
return open_dev;
} }
int snd_cards(void) int snd_cards(void)
@ -70,50 +72,39 @@ int snd_cards(void)
unsigned int snd_cards_mask(void) unsigned int snd_cards_mask(void)
{ {
int fd, idx; int idx;
unsigned int mask; unsigned int mask;
char filename[32];
static unsigned int save_mask = 0; static unsigned int save_mask = 0;
if (save_mask) if (save_mask)
return save_mask; return save_mask;
for (idx = 0, mask = 0; idx < SND_CARDS; idx++) { for (idx = 0, mask = 0; idx < SND_CARDS; idx++) {
snd_card_load(idx); if (snd_card_load(idx) >= 0)
sprintf(filename, SND_FILE_CONTROL, idx); mask |= 1 << 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;
} }
save_mask = mask; save_mask = mask;
return 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; snd_ctl_t *handle;
struct snd_ctl_hw_info info; snd_ctl_hw_info_t info;
if (!string || *string == '\0') if (!string || *string == '\0')
return -EINVAL; return -EINVAL;
bitmask = snd_cards_mask();
if (!bitmask)
return -ENODEV;
if ((isdigit(*string) && *(string + 1) == 0) || if ((isdigit(*string) && *(string + 1) == 0) ||
(isdigit(*string) && isdigit(*(string + 1)) && *(string + 2) == 0)) { (isdigit(*string) && isdigit(*(string + 1)) && *(string + 2) == 0)) {
sscanf(string, "%i", &card); sscanf(string, "%i", &card);
if (card < 0 || card > 31) if (card < 0 || card > 31)
return -EINVAL; return -EINVAL;
if (card < 0 || !((1 << card) & bitmask)) if (snd_card_load(card) >= 0)
return -EINVAL; return card;
return card; return -EINVAL;
} }
for (card = 0; card < 32; card++) { for (card = 0; card < 32; card++) {
if (!((1 << card) & bitmask)) if (snd_card_load(card) < 0)
continue; continue;
if (snd_ctl_open(&handle, card) < 0) if (snd_ctl_open(&handle, card) < 0)
continue; continue;
@ -131,7 +122,7 @@ int snd_card_name(const char *string)
int snd_card_get_name(int card, char **name) int snd_card_get_name(int card, char **name)
{ {
snd_ctl_t *handle; snd_ctl_t *handle;
struct snd_ctl_hw_info info; snd_ctl_hw_info_t info;
int err; int err;
if (name == NULL) if (name == NULL)
@ -152,7 +143,7 @@ int snd_card_get_name(int card, char **name)
int snd_card_get_longname(int card, char **name) int snd_card_get_longname(int card, char **name)
{ {
snd_ctl_t *handle; snd_ctl_t *handle;
struct snd_ctl_hw_info info; snd_ctl_hw_info_t info;
int err; int err;
if (name == NULL) if (name == NULL)

View file

@ -84,7 +84,7 @@ int snd_ctl_file_descriptor(snd_ctl_t *handle)
return handle->fd; 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); assert(handle && info);
if (ioctl(handle->fd, SND_CTL_IOCTL_HW_INFO, info) < 0) if (ioctl(handle->fd, SND_CTL_IOCTL_HW_INFO, info) < 0)

View file

@ -31,7 +31,7 @@ static int defaults_card(const char *env)
e = getenv(env); e = getenv(env);
if (!e) if (!e)
return -ENOENT; return -ENOENT;
return snd_card_name(e); return snd_card_get_index(e);
} }
static int defaults_device(const char *env) static int defaults_device(const char *env)

View file

@ -523,7 +523,7 @@ static int _snd_pcm_open_hw(snd_pcm_t **handlep, snd_config_t *conf,
err = snd_config_string_get(n, &str); err = snd_config_string_get(n, &str);
if (err < 0) if (err < 0)
return -EINVAL; return -EINVAL;
card = snd_card_name(str); card = snd_card_get_index(str);
if (card < 0) if (card < 0)
return card; return card;
} }
@ -569,7 +569,7 @@ static int _snd_pcm_open_plug(snd_pcm_t **handlep, snd_config_t *conf,
err = snd_config_string_get(n, &str); err = snd_config_string_get(n, &str);
if (err < 0) if (err < 0)
return -EINVAL; return -EINVAL;
card = snd_card_name(str); card = snd_card_get_index(str);
if (card < 0) if (card < 0)
return card; return card;
} }

View file

@ -6,7 +6,7 @@ int main(void)
{ {
int idx, idx1, cards, err; int idx, idx1, cards, err;
snd_ctl_t *handle; snd_ctl_t *handle;
struct snd_ctl_hw_info info; snd_ctl_hw_info_t info;
snd_pcm_info_t pcminfo; snd_pcm_info_t pcminfo;
snd_mixer_info_t mixerinfo; snd_mixer_info_t mixerinfo;
snd_rawmidi_info_t rawmidiinfo; snd_rawmidi_info_t rawmidiinfo;

View file

@ -32,7 +32,7 @@ int main(void)
{ {
int idx, idx1, cards, err; int idx, idx1, cards, err;
snd_ctl_t *handle; snd_ctl_t *handle;
struct snd_ctl_hw_info info; snd_ctl_hw_info_t info;
cards = snd_cards(); cards = snd_cards();
printf("Detected %i soundcard%s...\n", cards, cards > 1 ? "s" : ""); printf("Detected %i soundcard%s...\n", cards, cards > 1 ? "s" : "");