use strings rather than channel numbers

This commit is contained in:
Alexandre Ratchov 2015-03-05 10:12:34 +01:00
parent dfa1d3dd8c
commit 905c319315
11 changed files with 169 additions and 170 deletions

View File

@ -29,7 +29,7 @@
/*
* limits
*/
#define AMSG_MIX_NAMEMAX 12 /* max name length */
#define AMSG_MIX_NAMEMAX 16 /* max name length */
#define AMSG_MIX_INTMAX 127 /* max channel number */
#define AMSG_MIX_HALF 64 /* also bool threshold */
@ -115,8 +115,7 @@ struct amsg {
*/
struct amsg_mix_chan {
char str[AMSG_MIX_NAMEMAX]; /* stream name */
uint8_t min; /* first channel */
uint8_t num; /* number of channels */
char opt[AMSG_MIX_NAMEMAX]; /* stream name */
};
/*
@ -125,9 +124,9 @@ struct amsg_mix_chan {
struct amsg_mix_desc {
struct amsg_mix_chan chan0; /* affected channels */
struct amsg_mix_chan chan1; /* dito for AMSG_MIX_{SEL,VEC,LIST} */
char grp[AMSG_MIX_NAMEMAX]; /* parameter group name */
uint8_t type; /* see siomix_desc structure */
uint8_t __pad[1];
char grp[AMSG_MIX_NAMEMAX]; /* parameter group name */
uint16_t addr; /* control address */
uint16_t __pad2[1];
uint16_t curval;

View File

@ -172,11 +172,11 @@ _siomix_ondesc_cb(struct siomix_hdl *hdl,
struct siomix_desc *desc, unsigned int val)
{
if (desc) {
DPRINTF("%u -> %s[%u/%u].%s=%s[%u/%u]\n",
DPRINTF("%u -> %s[%s].%s=%s[%s]\n",
desc->addr,
desc->chan0.str, desc->chan0.min, desc->chan0.num,
desc->chan0.str, desc->chan0.opt,
desc->grp,
desc->chan1.str, desc->chan1.min, desc->chan1.num);
desc->chan1.str, desc->chan1.opt);
}
if (hdl->desc_cb)
hdl->desc_cb(hdl->desc_arg, desc, val);

View File

@ -75,13 +75,11 @@ siomix_aucat_rdata(struct siomix_aucat_hdl *hdl)
c = hdl->tmp;
while (size >= sizeof(struct amsg_mix_desc)) {
strlcpy(desc.chan0.str, c->chan0.str, SIOMIX_NAMEMAX);
desc.chan0.min = c->chan0.min;
desc.chan0.num = c->chan0.num;
strlcpy(desc.chan0.opt, c->chan0.opt, SIOMIX_NAMEMAX);
strlcpy(desc.chan1.str, c->chan1.str, SIOMIX_NAMEMAX);
desc.chan1.min = c->chan1.min;
desc.chan1.num = c->chan1.num;
desc.type = c->type;
strlcpy(desc.chan1.opt, c->chan1.opt, SIOMIX_NAMEMAX);
strlcpy(desc.grp, c->grp, SIOMIX_NAMEMAX);
desc.type = c->type;
desc.addr = ntohs(c->addr);
_siomix_ondesc_cb(&hdl->siomix, &desc, ntohs(c->curval));
size -= sizeof(struct amsg_mix_desc);

View File

@ -118,8 +118,7 @@ stucture as follows:
.Bd -literal
struct siomix_chan {
char str[SIOMIX_NAMEMAX]; /* stream name */
unsigned int min; /* first channel */
unsigned int num; /* number of channels */
char opt[SIOMIX_NAMEMAX]; /* optionnal channel */
};
struct siomix_desc {
@ -184,9 +183,8 @@ The
.Va chan0
and
.Va chan1
attributes indicate the names of the affected streams, the first
channels and the number of channels affected; zero
indicates that no channel information is exposed.
attributes indicate the names of the affected streams, and
an optional channel sub-set.
.Va chan1
is meaningful for
.Va SIOMIX_VEC

View File

@ -149,15 +149,17 @@ siomix_sun_close(struct siomix_hdl *addr)
free(hdl);
}
/*
* parse foo-4:5 and convert it to "foo", 4, 2
*/
static int
copy_ch(struct siomix_sun_hdl *hdl, struct siomix_chan *c, char *istr, int cls)
copy_ch(struct siomix_sun_hdl *hdl,
int icls, char *istr, char *ostr, int *rmin, int *rnum)
{
size_t len;
char *sep, *ostr, *endp;
long min, max;
char *sep, *endp;
long cmin, cmax;
c->min = c->num = 0;
ostr = c->str;
ostr[0] = 0;
sep = strchr(istr, '-');
@ -169,59 +171,86 @@ copy_ch(struct siomix_sun_hdl *hdl, struct siomix_chan *c, char *istr, int cls)
ostr[len] = 0;
istr = sep + 1;
min = strtol(istr, &endp, 10);
cmin = strtol(istr, &endp, 10);
if (endp != istr) {
/*
* this a "foo-0:3" style range
*/
istr = endp;
c->min = min;
c->num = 1;
if (*endp == ':') {
istr++;
max = strtol(istr, &endp, 10);
cmax = strtol(istr, &endp, 10);
if (endp == istr) {
DPRINTF("bad range\n");
return 0;
}
istr = endp;
c->num = max - min + 1;
} else if (*endp == 0) {
cmax = cmin;
} else {
DPRINTF("unknown range\n");
return 0;
}
*rmin = cmin;
*rnum = cmax - cmin + 1;
} else {
if (strcmp(ostr, "line") == 0)
if (strcmp(ostr, "line") == 0) {
/* rename make "line-foo" to "foo" */
ostr[0] = 0;
else
} else {
/* append unknown suffix with '_' */
strlcat(ostr, "_", SIOMIX_NAMEMAX);
}
strlcat(ostr, istr, SIOMIX_NAMEMAX);
*rmin = 0;
*rnum = 0;
}
} else {
*rmin = 0;
*rnum = 0;
strlcpy(ostr, istr, SIOMIX_NAMEMAX);
}
if (cls == -1)
if (icls == -1)
return 1;
if (strcmp(ostr, "line") == 0) {
if (cls == hdl->iclass)
if (icls == hdl->iclass)
strlcpy(ostr, "in", SIOMIX_NAMEMAX);
if (cls == hdl->oclass)
if (icls == hdl->oclass)
strlcpy(ostr, "out", SIOMIX_NAMEMAX);
}
if (strcmp(ostr, "volume") == 0) {
if (cls == hdl->rclass)
if (icls == hdl->rclass)
strlcpy(ostr, "rec", SIOMIX_NAMEMAX);
}
return 1;
}
static void
make_opt(char *opt, int min, int num)
{
switch (num) {
case 0:
opt[0] = 0;
break;
case 1:
snprintf(opt, SIOMIX_NAMEMAX, "%u", min);
break;
default:
snprintf(opt, SIOMIX_NAMEMAX, "%u-%u", min, min + num - 1);
break;
}
}
static int
copyname_num(struct siomix_sun_hdl *hdl,
struct siomix_desc *desc, struct mixer_devinfo *info)
struct mixer_devinfo *info, struct siomix_desc *desc, int *rmin, int *rnum)
{
size_t len;
char *sep, *istr;
sep = strchr(info->label.name, '_');
if (sep) {
strlcpy(desc->grp, "levels", SIOMIX_NAMEMAX);
strlcpy(desc->grp, "mix", SIOMIX_NAMEMAX);
desc->type = SIOMIX_VEC;
len = sep - info->label.name;
if (len >= SIOMIX_NAMEMAX - 1)
@ -229,29 +258,27 @@ copyname_num(struct siomix_sun_hdl *hdl,
memcpy(desc->chan0.str, info->label.name, len);
desc->chan0.str[len] = 0;
istr = sep + 1;
if (!copy_ch(hdl, &desc->chan1, istr, info->mixer_class))
if (!copy_ch(hdl, info->mixer_class, istr,
desc->chan1.str, rmin, rnum))
return 0;
desc->chan0.min = desc->chan1.min;
desc->chan0.num = desc->chan1.num;
} else {
strlcpy(desc->grp, "level", SIOMIX_NAMEMAX);
desc->type = SIOMIX_NUM;
istr = info->label.name;
if (!copy_ch(hdl, &desc->chan0, istr, info->mixer_class))
if (!copy_ch(hdl, info->mixer_class, istr,
desc->chan0.str, rmin, rnum))
return 0;
desc->chan1.str[0] = '\0';
desc->chan1.min = 0;
desc->chan1.num = 0;
}
return 1;
}
static int
copyname_enum(struct siomix_sun_hdl *hdl,
struct siomix_desc *desc, struct mixer_devinfo *info)
struct mixer_devinfo *info, struct siomix_desc *desc, int *rmin, int *rnum)
{
char istr[SIOMIX_NAMEMAX], *sep;
size_t len;
size_t len;
sep = strrchr(info->label.name, '.');
if (sep == NULL)
@ -264,9 +291,10 @@ copyname_enum(struct siomix_sun_hdl *hdl,
strlcpy(desc->grp, info->label.name, SIOMIX_NAMEMAX);
while (info->prev >= 0)
info = hdl->info + info->prev;
if (!copy_ch(hdl, &desc->chan0,
info->label.name, info->mixer_class))
if (!copy_ch(hdl, info->mixer_class, info->label.name,
desc->chan0.str, rmin, rnum))
return 0;
desc->chan1.str[0] = 0;
} else {
strlcpy(desc->grp, sep + 1, SIOMIX_NAMEMAX);
len = sep - info->label.name;
@ -274,9 +302,10 @@ copyname_enum(struct siomix_sun_hdl *hdl,
return 0;
memcpy(istr, info->label.name, len);
istr[len] = '\0';
if (!copy_ch(hdl, &desc->chan0, istr,
info->mixer_class))
if (!copy_ch(hdl, info->mixer_class, istr,
desc->chan0.str, rmin, rnum))
return 0;
desc->chan1.str[0] = 0;
}
/*
* certain cards expose adc[0-1].source and adc[2-3].source
@ -324,19 +353,20 @@ enum_to_sw(struct mixer_devinfo *info, struct siomix_desc *desc)
return 0;
v0 = info->un.e.member[ord_to_num(info, 0)].label.name;
v1 = info->un.e.member[ord_to_num(info, 1)].label.name;
desc->chan1.str[0] = 0;
desc->chan1.min = 0;
desc->chan1.num = 0;
desc->type = SIOMIX_SW;
if (strcmp(v0, "off") == 0 && strcmp(v1, "on") == 0)
return 1;
goto make_sw;
if (strcmp(v0, "unplugged") == 0 && strcmp(v1, "plugged") == 0) {
strlcpy(desc->grp,
info->un.e.member[1].label.name,
SIOMIX_NAMEMAX);
return 1;
goto make_sw;
}
return 0;
make_sw:
desc->chan1.str[0] = 0;
desc->chan1.opt[0] = 0;
desc->type = SIOMIX_SW;
return 1;
}
static int
@ -346,7 +376,8 @@ siomix_sun_ondesc(struct siomix_hdl *addr)
struct mixer_devinfo *info;
struct mixer_ctrl *ctrl;
struct siomix_desc desc;
int i, j, v;
char *ostr;
int i, j, v, cmin, cnum;
for (i = 0; i < hdl->ninfo; i++) {
info = hdl->info + i;
@ -373,19 +404,25 @@ siomix_sun_ondesc(struct siomix_hdl *addr)
info = hdl->info;
for (i = 0; i < hdl->ninfo; i++) {
DPRINTF("parsing \"%s\"\n", info->label.name);
DPRINTF("psarsing \"%s\"\n", info->label.name);
switch (info->type) {
case AUDIO_MIXER_VALUE:
desc.addr = i * 32;
if (!copyname_num(hdl, &desc, info))
if (!copyname_num(hdl, info, &desc, &cmin, &cnum))
return 0;
if (info->un.v.num_channels > 1)
desc.chan0.num = 1;
make_opt(desc.chan0.opt, cmin, cnum);
desc.chan1.opt[0] = 0;
for (j = 0; j < info->un.v.num_channels; j++) {
v = hdl->curval[i].un.value.level[j] *
127 / 255;
ostr = desc.type == SIOMIX_NUM ?
desc.chan0.opt : desc.chan1.opt;
if (info->un.v.num_channels > 1) {
make_opt(ostr, cmin + j, 1);
} else {
make_opt(ostr, cmin, cnum);
}
_siomix_ondesc_cb(&hdl->siomix, &desc, v);
desc.chan0.min++;
desc.addr++;
}
break;
@ -393,20 +430,24 @@ siomix_sun_ondesc(struct siomix_hdl *addr)
desc.addr = i * 32;
if (info->un.e.num_mem <= 1)
break;
if (!copyname_enum(hdl, &desc, info))
if (!copyname_enum(hdl, info, &desc, &cmin, &cnum))
return 0;
if (enum_to_sw(info, &desc)) {
make_opt(desc.chan0.opt, cmin, cnum);
_siomix_ondesc_cb(&hdl->siomix, &desc,
ord_to_num(info, hdl->curval[i].un.ord));
break;
}
for (j = 0; j < info->un.e.num_mem; j++) {
if (!copyname_enum(hdl, &desc, info))
if (!copyname_enum(hdl, info,
&desc, &cmin, &cnum))
return 0;
copy_ch(hdl, &desc.chan1,
info->un.e.member[j].label.name,
info->mixer_class);
make_opt(desc.chan0.opt, cmin, cnum);
if (!copy_ch(hdl, info->mixer_class,
info->un.e.member[j].label.name,
desc.chan1.str, &cmin, &cnum))
return 0;
make_opt(desc.chan1.opt, cmin, cnum);
desc.type = SIOMIX_LIST;
v = (j == ord_to_num(info,
hdl->curval[i].un.ord)) ? 1 : 0;
@ -418,14 +459,16 @@ siomix_sun_ondesc(struct siomix_hdl *addr)
desc.addr = i * 32;
if (info->un.s.num_mem == 0)
break;
if (!copyname_enum(hdl, &desc, info))
if (!copyname_enum(hdl, info, &desc, &cmin, &cnum))
return 0;
make_opt(desc.chan0.opt, cmin, cnum);
desc.type = SIOMIX_LIST;
for (j = 0; j < info->un.s.num_mem; j++) {
if (!copy_ch(hdl, &desc.chan1,
if (!copy_ch(hdl, info->mixer_class,
info->un.s.member[j].label.name,
info->mixer_class))
desc.chan1.str, &cmin, &cnum))
return 0;
make_opt(desc.chan1.opt, cmin, cnum);
_siomix_ondesc_cb(&hdl->siomix, &desc,
mask_to_bit(info, j,
hdl->curval[i].un.mask));

View File

@ -98,8 +98,7 @@ struct sio_cap {
*/
struct siomix_chan {
char str[SIOMIX_NAMEMAX]; /* stream name */
unsigned int min; /* first channel */
unsigned int num; /* number of channels */
char opt[SIOMIX_NAMEMAX]; /* optional (sub-)stream name */
};
/*

View File

@ -44,13 +44,13 @@ struct info {
int cmpdesc(struct siomix_desc *, struct siomix_desc *);
int isdiag(struct info *);
struct info *selpos(struct info *);
struct info *vecent(struct info *, char *, unsigned, unsigned);
struct info *vecent(struct info *, char *, char *);
struct info *nextgrp(struct info *);
struct info *nextpar(struct info *);
struct info *firstent(struct info *, char *);
struct info *nextent(struct info *, int);
int matchpar(struct info *, char *, unsigned, unsigned);
int matchent(struct info *, char *, unsigned, unsigned);
int matchpar(struct info *, char *, char *);
int matchent(struct info *, char *, char *);
int ismono(struct info *);
void print_chan(struct siomix_chan *, int);
void print_desc(struct info *, int);
@ -58,7 +58,7 @@ void print_val(struct info *, int);
void print_par(struct info *, int);
int parse_name(char **, char *);
int parse_dec(char **, unsigned *);
int parse_chan(char **, char *, unsigned *, unsigned *);
int parse_chan(char **, char *, char *);
int parse_modeval(char **, int *, unsigned *);
void dump(void);
int cmd(char *);
@ -90,7 +90,7 @@ cmpdesc(struct siomix_desc *d1, struct siomix_desc *d2)
res = strcmp(d1->grp, d2->grp);
if (res != 0)
return res;
res = d1->chan0.min - d2->chan0.min;
res = strcmp(d1->chan0.opt, d2->chan0.opt);
if (d1->type == SIOMIX_VEC ||
d1->type == SIOMIX_LIST) {
if (res != 0)
@ -98,7 +98,7 @@ cmpdesc(struct siomix_desc *d1, struct siomix_desc *d2)
res = strcmp(d1->chan1.str, d2->chan1.str);
if (res != 0)
return res;
res = d1->chan1.min - d2->chan1.min;
res = strcmp(d1->chan1.opt, d2->chan0.opt);
}
return res;
}
@ -109,12 +109,10 @@ cmpdesc(struct siomix_desc *d1, struct siomix_desc *d2)
int
isdiag(struct info *e)
{
if (e->desc.chan0.num == 0 ||
e->desc.chan1.num == 0)
if (strlen(e->desc.chan0.opt) == 0 ||
strlen(e->desc.chan1.opt) == 0)
return 1;
return
e->desc.chan1.min == e->desc.chan0.min &&
e->desc.chan1.num == e->desc.chan0.num;
return strcmp(e->desc.chan1.opt, e->desc.chan0.opt) == 0;
}
/*
@ -136,12 +134,11 @@ selpos(struct info *i)
* find the selector or vector entry with the given name and channels
*/
struct info *
vecent(struct info *i, char *vstr, unsigned vmin, unsigned vnum)
vecent(struct info *i, char *vstr, char *vopt)
{
while (i != NULL) {
if (strcmp(i->desc.chan1.str, vstr) == 0 &&
i->desc.chan1.num == vnum &&
i->desc.chan1.min == vmin)
if ((strcmp(i->desc.chan1.str, vstr) == 0) &&
(strlen(vopt) == 0 || strcmp(i->desc.chan1.opt, vopt) == 0))
break;
i = i->next;
}
@ -172,19 +169,16 @@ nextgrp(struct info *i)
struct info *
nextpar(struct info *i)
{
char *str, *grp;
unsigned min, num;
char *str, *opt, *grp;
grp = i->desc.grp;
str = i->desc.chan0.str;
min = i->desc.chan0.min;
num = i->desc.chan0.num;
opt = i->desc.chan0.opt;
for (i = i->next; i != NULL; i = i->next) {
if (strcmp(i->desc.chan0.str, str) != 0 ||
strcmp(i->desc.grp, grp) != 0)
break;
if (i->desc.chan0.min != min ||
i->desc.chan0.num != num)
if (strcmp(i->desc.chan0.opt, opt) != 0)
return i;
}
return NULL;
@ -221,21 +215,18 @@ firstent(struct info *g, char *vstr)
struct info *
nextent(struct info *i, int mono)
{
char *str, *grp;
unsigned min, num;
char *str, *opt, *grp;
grp = i->desc.grp;
str = i->desc.chan0.str;
min = i->desc.chan0.min;
num = i->desc.chan0.num;
opt = i->desc.chan0.opt;
for (i = i->next; i != NULL; i = i->next) {
if (strcmp(i->desc.chan0.str, str) != 0 ||
strcmp(i->desc.grp, grp) != 0)
return NULL;
if (mono)
return i;
if (i->desc.chan0.min == min &&
i->desc.chan0.num == num)
if (strcmp(i->desc.chan0.opt, opt) != 0)
return i;
}
return NULL;
@ -245,19 +236,17 @@ nextent(struct info *i, int mono)
* return true if parameter matches the given name and channel range
*/
int
matchpar(struct info *i, char *astr, unsigned amin, unsigned anum)
matchpar(struct info *i, char *astr, char *aopt)
{
if (strcmp(i->desc.chan0.str, astr) != 0)
return 0;
if (anum == 0)
if (strlen(aopt) == 0)
return 1;
else if (i->desc.chan0.num == 0) {
fprintf(stderr, "range used for parameter with no range\n");
else if (strlen(i->desc.chan0.opt) == 0) {
fprintf(stderr, "opt used for parameter with no opt\n");
exit(1);
}
return
i->desc.chan0.min >= amin &&
i->desc.chan0.min + i->desc.chan0.num <= amin + anum;
return strcmp(i->desc.chan0.opt, aopt) == 0;
}
/*
@ -265,19 +254,17 @@ matchpar(struct info *i, char *astr, unsigned amin, unsigned anum)
* channel range
*/
int
matchent(struct info *i, char *vstr, unsigned vmin, unsigned vnum)
matchent(struct info *i, char *vstr, char *vopt)
{
if (strcmp(i->desc.chan1.str, vstr) != 0)
return 0;
if (vnum == 0) {
if (strlen(vopt) == 0)
return 1;
} else {
if (i->desc.chan1.num == 0) {
fprintf(stderr, "range not allowed\n");
exit(1);
}
else if (strlen(i->desc.chan1.opt) == 0) {
fprintf(stderr, "opt used for parameter with no opt\n");
exit(1);
}
return i->desc.chan1.min == vmin && i->desc.chan1.num == vnum;
return strcmp(i->desc.chan1.opt, vopt) == 0;
}
/*
@ -311,8 +298,7 @@ ismono(struct info *g)
} else {
e1 = vecent(p1,
e2->desc.chan1.str,
p1->desc.chan0.min,
p1->desc.chan0.num);
p1->desc.chan0.opt);
if (e1 == NULL)
continue;
if (e1->curval != e2->curval)
@ -332,11 +318,8 @@ void
print_chan(struct siomix_chan *c, int mono)
{
printf("%s", c->str);
if (!mono && c->num > 0) {
printf("[%u", c->min);
if (c->num > 1)
printf("-%u", c->min + c->num - 1);
printf("]");
if (!mono && strlen(c->opt) > 0) {
printf("[%s]", c->opt);
}
}
@ -441,7 +424,7 @@ print_par(struct info *p, int mono)
if (i->desc.type != SIOMIX_LABEL)
continue;
if (strcmp(i->desc.chan0.str, p->desc.chan0.str) == 0 &&
i->desc.chan0.min == p->desc.chan0.min &&
strcmp(i->desc.chan0.opt, p->desc.chan0.opt) == 0 &&
strlen(i->desc.grp) > 0) {
printf("\t# %s", i->desc.grp);
}
@ -507,39 +490,25 @@ parse_dec(char **line, unsigned *num)
* parse a sub-stream, eg. "spkr[4-7]"
*/
int
parse_chan(char **line, char *str, unsigned *rmin, unsigned *rnum)
parse_chan(char **line, char *str, char *opt)
{
char *p = *line;
unsigned min, max;
if (!parse_name(&p, str))
return 0;
if (*p != '[') {
*rmin = 0;
*rnum = 0;
*opt = 0;
*line = p;
return 1;
}
p++;
if (!parse_dec(&p, &min))
if (!parse_name(&p, opt))
return 0;
if (*p == '-') {
p++;
if (!parse_dec(&p, &max))
return 0;
if (max < min) {
fprintf(stderr, "%u-%u: bad range\n", min, max);
return 0;
}
} else
max = min;
if (*p != ']') {
fprintf(stderr, "']' expected near '%s'\n", p);
return 0;
}
p++;
*rmin = min;
*rnum = max - min + 1;
*line = p;
return 1;
}
@ -621,11 +590,12 @@ cmd(char *line)
char *pos = line;
struct info *i, *e, *g;
char grp[SIOMIX_NAMEMAX], astr[SIOMIX_NAMEMAX], vstr[SIOMIX_NAMEMAX];
char aopt[SIOMIX_NAMEMAX], vopt[SIOMIX_NAMEMAX];
unsigned amin, anum, vmin, vnum, val;
unsigned npar = 0, nent = 0;
int comma, mode;
if (!parse_chan(&pos, astr, &amin, &anum))
if (!parse_chan(&pos, astr, aopt))
return 0;
if (*pos != '.') {
fprintf(stderr, "'.' expected near '%s'\n", pos);
@ -663,7 +633,7 @@ cmd(char *line)
if (!parse_modeval(&pos, &mode, &val))
return 0;
for (i = g; i != NULL; i = nextpar(i)) {
if (!matchpar(i, astr, amin, anum))
if (!matchpar(i, astr, aopt))
continue;
i->mode = mode;
i->newval = val;
@ -673,7 +643,7 @@ cmd(char *line)
case SIOMIX_VEC:
case SIOMIX_LIST:
for (i = g; i != NULL; i = nextpar(i)) {
if (!matchpar(i, astr, amin, anum))
if (!matchpar(i, astr, aopt))
continue;
for (e = i; e != NULL; e = nextent(e, 0)) {
e->newval = 0;
@ -690,7 +660,7 @@ cmd(char *line)
break;
pos++;
}
if (!parse_chan(&pos, vstr, &vmin, &vnum))
if (!parse_chan(&pos, vstr, vopt))
return 0;
if (*pos == ':') {
pos++;
@ -702,10 +672,10 @@ cmd(char *line)
}
nent = 0;
for (i = g; i != NULL; i = nextpar(i)) {
if (!matchpar(i, astr, amin, anum))
if (!matchpar(i, astr, aopt))
continue;
for (e = i; e != NULL; e = nextent(e, 0)) {
if (matchent(e, vstr, vmin, vnum)) {
if (matchent(e, vstr, vopt)) {
e->newval = val;
e->mode = mode;
nent++;
@ -713,7 +683,7 @@ cmd(char *line)
}
}
if (nent == 0) {
fprintf(stderr, "%s[%d/%d]: invalid value\n", vstr, vmin, vnum);
fprintf(stderr, "%s[%s]: invalid value\n", vstr, vopt);
print_par(g, 0);
exit(1);
}

View File

@ -1148,16 +1148,16 @@ dev_open(struct dev *d)
dev_uniqname(d, "slot", ctlname);
c = dev_addctl(d, CTL_NUM,
d->ctl_addr + CTLADDR_SLOT_LEVEL(i),
ctlname, 0, 0, "softvol", NULL, 0, 0);
ctlname, "", "softvol", NULL, NULL);
c->curval = d->slot[i].vol;
dev_addctl(d, CTL_LABEL,
d->ctl_addr + CTLADDR_SLOT_LABEL(i),
ctlname, 0, 0, d->slot[i].name, NULL, 0, 0);
ctlname, "", d->slot[i].name, NULL, NULL);
}
dev_uniqname(d, "master", ctlname);
c = dev_addctl(d, CTL_NUM,
d->ctl_addr + CTLADDR_MASTER,
ctlname, 0, 0, "softvol", NULL, 0, 0);
ctlname, "", "softvol", NULL, NULL);
c->curval = d->master;
return 1;
}
@ -2030,13 +2030,9 @@ void
ctl_chan_log(struct ctl_chan *c)
{
log_puts(c->str);
if (c->num > 0) {
if (strlen(c->opt) > 0) {
log_puts("[");
log_putu(c->min);
if (c->num > 1) {
log_puts("-");
log_putu(c->min + c->num - 1);
}
log_puts(c->opt);
log_puts("]");
}
}
@ -2093,8 +2089,7 @@ dev_uniqname(struct dev *d, char *templ, char *name)
*/
struct ctl *
dev_addctl(struct dev *d, int type, int addr,
char *str0, int cmin0, int cnum0, char *grp,
char *str1, int cmin1, int cnum1)
char *str0, char *opt0, char *grp, char *str1, char *opt1)
{
struct ctl *c;
@ -2102,13 +2097,11 @@ dev_addctl(struct dev *d, int type, int addr,
c->type = type;
strlcpy(c->grp, grp, CTL_NAMEMAX);
strlcpy(c->chan0.str, str0, CTL_NAMEMAX);
c->chan0.min = cmin0;
c->chan0.num = cnum0;
strlcpy(c->chan0.opt, opt0, CTL_NAMEMAX);
if (c->type == CTL_VEC ||
c->type == CTL_LIST) {
strlcpy(c->chan1.str, str1, CTL_NAMEMAX);
c->chan1.min = cmin1;
c->chan1.num = cnum1;
strlcpy(c->chan1.opt, opt1, CTL_NAMEMAX);
} else
memset(&c->chan1, 0, sizeof(struct ctl_chan));
c->addr = addr;

View File

@ -113,12 +113,11 @@ struct ctl {
#define CTL_LABEL 6 /* attach string to stream */
unsigned int type; /* one of above */
unsigned int addr; /* control address */
#define CTL_NAMEMAX 12 /* max name lenght */
#define CTL_NAMEMAX 16 /* max name lenght */
char grp[CTL_NAMEMAX]; /* parameter group name */
struct ctl_chan {
char str[CTL_NAMEMAX]; /* stream name */
unsigned int min; /* first channel */
unsigned int num; /* number of channels */
char opt[CTL_NAMEMAX];
} chan0, chan1; /* affected channels */
unsigned int val_mask;
unsigned int desc_mask;
@ -290,6 +289,6 @@ int dev_onctl(struct dev *, int, int);
int dev_nctl(struct dev *);
void dev_label(struct dev *, int);
struct ctl *dev_addctl(struct dev *, int, int,
char *, int, int, char *, char *, int, int);
char *, char *, char *, char *, char *);
#endif /* !defined(DEV_H) */

View File

@ -71,8 +71,8 @@ dev_siomix_ondesc(void *arg, struct siomix_desc *desc, int val)
return;
}
c = dev_addctl(d, desc->type, desc->addr,
desc->chan0.str, desc->chan0.min, desc->chan0.num, desc->grp,
desc->chan1.str, desc->chan1.min, desc->chan1.num);
desc->chan0.str, desc->chan0.opt, desc->grp,
desc->chan1.str, desc->chan1.opt);
c->curval = val;
#ifdef DEBUG
if (log_level >= 3) {

View File

@ -1553,12 +1553,12 @@ sock_buildmsg(struct sock *f)
c->val_mask &= ~mask;
strlcpy(desc->chan0.str, c->chan0.str,
AMSG_MIX_NAMEMAX);
desc->chan0.min = c->chan0.min;
desc->chan0.num = c->chan0.num;
strlcpy(desc->chan0.opt, c->chan0.opt,
AMSG_MIX_NAMEMAX);
strlcpy(desc->chan1.str, c->chan1.str,
AMSG_MIX_NAMEMAX);
desc->chan1.min = c->chan1.min;
desc->chan1.num = c->chan1.num;
strlcpy(desc->chan1.opt, c->chan1.opt,
AMSG_MIX_NAMEMAX);
desc->type = c->type;
strlcpy(desc->grp, c->grp, AMSG_MIX_NAMEMAX);
desc->addr = htons(c->addr);