mirror of https://github.com/ericonr/sndio.git
use strings rather than channel numbers
This commit is contained in:
parent
dfa1d3dd8c
commit
905c319315
|
@ -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;
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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 */
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
|
23
sndiod/dev.c
23
sndiod/dev.c
|
@ -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;
|
||||
|
|
|
@ -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) */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Reference in New Issue