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,
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);

View file

@ -24,7 +24,7 @@ extern "C" {
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);
@ -38,7 +38,7 @@ int snd_defaults_rawmidi_device(void);
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);
@ -63,6 +63,16 @@ struct list_head {
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;

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
* @pos: the &struct list_head to use as a loop counter.

View file

@ -29,9 +29,15 @@
#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 {
@ -45,23 +51,33 @@ typedef struct {
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;
@ -74,11 +90,32 @@ static void unget_char(int c, input_t *input)
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) {
@ -89,9 +126,11 @@ static int get_char_skip_comments(input_t *input)
break;
}
}
return c;
}
static int get_nonwhite(input_t *input)
{
int c;
@ -346,6 +385,7 @@ static int parse_def(snd_config_t *father, input_t *input)
snd_config_t *n;
enum {MERGE, NOCREATE, REMOVE} mode;
while (1) {
#if 0
c = get_nonwhite(input);
switch (c) {
case '?':
@ -358,6 +398,9 @@ static int parse_def(snd_config_t *father, input_t *input)
mode = MERGE;
unget_char(c, input);
}
#else
mode = MERGE;
#endif
err = get_string(&id, input);
if (err < 0)
return err;
@ -521,10 +564,15 @@ int snd_config_load(snd_config_t *config, FILE *fp)
{
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) {
@ -538,17 +586,17 @@ int snd_config_load(snd_config_t *config, FILE *fp)
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;
}
@ -594,7 +642,33 @@ int snd_config_make(snd_config_t **config, char *id,
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)
@ -860,12 +934,12 @@ int snd_config_search(snd_config_t *config, char *key, snd_config_t **result)
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
@ -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,
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 (config->type != SND_CONFIG_TYPE_COMPOUND)
return -ENOENT;
err = _snd_config_search(config, k, -1, &n);
if (err < 0)
return err;
config = n;
}
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);
va_end(arg);
*result = n;
return 0;
}
snd_config_t *snd_config = 0;

View file

@ -36,18 +36,20 @@ int snd_card_load(int card)
{
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 {
close (open_dev);
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 open_dev;
}
int snd_cards(void)
{
@ -70,50 +72,39 @@ 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);
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;
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;
@ -131,7 +122,7 @@ int snd_card_name(const char *string)
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)
@ -152,7 +143,7 @@ int snd_card_get_name(int card, char **name)
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)

View file

@ -84,7 +84,7 @@ int snd_ctl_file_descriptor(snd_ctl_t *handle)
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)

View file

@ -31,7 +31,7 @@ static int defaults_card(const char *env)
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)

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);
if (err < 0)
return -EINVAL;
card = snd_card_name(str);
card = snd_card_get_index(str);
if (card < 0)
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);
if (err < 0)
return -EINVAL;
card = snd_card_name(str);
card = snd_card_get_index(str);
if (card < 0)
return card;
}

View file

@ -6,7 +6,7 @@ int main(void)
{
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;

View file

@ -32,7 +32,7 @@ int main(void)
{
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" : "");