mirror of https://github.com/ericonr/sndio.git
Add "maxval" attribute to sioctl_desc structure.
As control may have different max values, make sndioctl expose floats in the [0:1] range.
This commit is contained in:
parent
2207b5e6db
commit
e55971c61e
|
@ -145,8 +145,9 @@ struct amsg_ctl_desc {
|
|||
uint8_t type; /* see sioctl_desc structure */
|
||||
uint8_t __pad1[1];
|
||||
uint16_t addr; /* control address */
|
||||
uint16_t __pad2[1];
|
||||
uint16_t maxval;
|
||||
uint16_t curval;
|
||||
uint32_t __pad2[3];
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -90,6 +90,7 @@ sioctl_aucat_rdata(struct sioctl_aucat_hdl *hdl)
|
|||
strlcpy(desc.func, c->func, SIOCTL_NAMEMAX);
|
||||
desc.type = c->type;
|
||||
desc.addr = ntohs(c->addr);
|
||||
desc.maxval = ntohs(c->maxval);
|
||||
_sioctl_ondesc_cb(&hdl->sioctl,
|
||||
&desc, ntohs(c->curval));
|
||||
rpos += sizeof(struct amsg_ctl_desc);
|
||||
|
|
|
@ -42,9 +42,6 @@
|
|||
sizeof(DEVPATH_PREFIX) - 1 + \
|
||||
sizeof(int) * 3)
|
||||
|
||||
#define SUN_TO_SIOCTL(v) (((v) * 127 + 127) / 255)
|
||||
#define SIOCTL_TO_SUN(v) (((v) * 255 + 63) / 127)
|
||||
|
||||
struct volume
|
||||
{
|
||||
int nch; /* channels in the level control */
|
||||
|
@ -178,10 +175,8 @@ setvol(struct sioctl_sun_hdl *hdl, struct volume *vol, int addr, int val)
|
|||
ctrl.dev = vol->level_idx;
|
||||
ctrl.type = AUDIO_MIXER_VALUE;
|
||||
ctrl.un.value.num_channels = vol->nch;
|
||||
for (i = 0; i < vol->nch; i++) {
|
||||
ctrl.un.value.level[i] =
|
||||
SIOCTL_TO_SUN(vol->level_val[i]);
|
||||
}
|
||||
for (i = 0; i < vol->nch; i++)
|
||||
ctrl.un.value.level[i] = vol->level_val[i];
|
||||
DPRINTF("vol %d setting to %d\n", addr, vol->level_val[addr]);
|
||||
if (ioctl(hdl->fd, AUDIO_MIXER_WRITE, &ctrl) < 0) {
|
||||
DPRINTF("level write failed\n");
|
||||
|
@ -233,6 +228,7 @@ scanvol(struct sioctl_sun_hdl *hdl, struct volume *vol)
|
|||
return 0;
|
||||
}
|
||||
desc.type = SIOCTL_NUM;
|
||||
desc.maxval = AUDIO_MAX_GAIN;
|
||||
desc.node1.name[0] = 0;
|
||||
desc.node1.unit = -1;
|
||||
strlcpy(desc.func, "level", SIOCTL_NAMEMAX);
|
||||
|
@ -240,7 +236,7 @@ scanvol(struct sioctl_sun_hdl *hdl, struct volume *vol)
|
|||
for (i = 0; i < vol->nch; i++) {
|
||||
desc.node0.unit = i;
|
||||
desc.addr = vol->base_addr + i;
|
||||
val = SUN_TO_SIOCTL(ctrl.un.value.level[i]);
|
||||
val = ctrl.un.value.level[i];
|
||||
vol->level_val[i] = val;
|
||||
_sioctl_ondesc_cb(&hdl->sioctl, &desc, val);
|
||||
}
|
||||
|
@ -253,11 +249,12 @@ scanvol(struct sioctl_sun_hdl *hdl, struct volume *vol)
|
|||
return 0;
|
||||
}
|
||||
desc.type = SIOCTL_SW;
|
||||
desc.maxval = 1;
|
||||
desc.node1.name[0] = 0;
|
||||
desc.node1.unit = -1;
|
||||
strlcpy(desc.func, "mute", SIOCTL_NAMEMAX);
|
||||
strlcpy(desc.node0.name, vol->name, SIOCTL_NAMEMAX);
|
||||
val = ctrl.un.ord ? SIOCTL_VALMAX : 0;
|
||||
val = ctrl.un.ord ? 1 : 0;
|
||||
vol->mute_val = val;
|
||||
for (i = 0; i < vol->nch; i++) {
|
||||
desc.node0.unit = i;
|
||||
|
@ -287,7 +284,7 @@ updatevol(struct sioctl_sun_hdl *hdl, struct volume *vol, int idx)
|
|||
return 0;
|
||||
}
|
||||
if (idx == vol->mute_idx) {
|
||||
val = ctrl.un.ord ? SIOCTL_VALMAX : 0;
|
||||
val = ctrl.un.ord ? 1 : 0;
|
||||
if (vol->mute_val == val)
|
||||
return 1;
|
||||
vol->mute_val = val;
|
||||
|
@ -297,7 +294,7 @@ updatevol(struct sioctl_sun_hdl *hdl, struct volume *vol, int idx)
|
|||
}
|
||||
} else {
|
||||
for (i = 0; i < vol->nch; i++) {
|
||||
val = SUN_TO_SIOCTL(ctrl.un.value.level[i]);
|
||||
val = ctrl.un.value.level[i];
|
||||
if (vol->level_val[i] == val)
|
||||
continue;
|
||||
vol->level_val[i] = val;
|
||||
|
|
|
@ -30,7 +30,6 @@
|
|||
* limits
|
||||
*/
|
||||
#define SIOCTL_NAMEMAX 12 /* max name length */
|
||||
#define SIOCTL_VALMAX 127 /* max control value */
|
||||
|
||||
/*
|
||||
* private ``handle'' structure
|
||||
|
@ -115,6 +114,8 @@ struct sioctl_desc {
|
|||
char group[SIOCTL_NAMEMAX]; /* group this control belongs to */
|
||||
struct sioctl_node node0; /* affected node */
|
||||
struct sioctl_node node1; /* dito for SIOCTL_{VEC,LIST} */
|
||||
unsigned int maxval; /* max value for SIOCTL_{NUM,VEC} */
|
||||
int __pad[3];
|
||||
};
|
||||
|
||||
/*
|
||||
|
|
|
@ -16,11 +16,11 @@
|
|||
*/
|
||||
#include <errno.h>
|
||||
#include <poll.h>
|
||||
#include <sndio.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <unistd.h>
|
||||
#include <sndio.h>
|
||||
|
||||
struct info {
|
||||
struct info *next;
|
||||
|
@ -52,9 +52,9 @@ void print_val(struct info *, int);
|
|||
void print_par(struct info *, int, char *);
|
||||
int parse_name(char **, char *);
|
||||
int parse_unit(char **, unsigned int *);
|
||||
int parse_val(char **, unsigned int *);
|
||||
int parse_val(char **, float *);
|
||||
int parse_node(char **, char *, int *);
|
||||
int parse_modeval(char **, int *, int *);
|
||||
int parse_modeval(char **, int *, float *);
|
||||
void dump(void);
|
||||
int cmd(char *);
|
||||
void commit(void);
|
||||
|
@ -78,6 +78,12 @@ isname_next(int c)
|
|||
return isname_first(c) || (c >= '0' && c <= '9') || (c == '_');
|
||||
}
|
||||
|
||||
static int
|
||||
ftoi(float f)
|
||||
{
|
||||
return f + 0.5;
|
||||
}
|
||||
|
||||
/*
|
||||
* compare two sioctl_desc structures, used to sort infolist
|
||||
*/
|
||||
|
@ -368,7 +374,7 @@ print_val(struct info *p, int mono)
|
|||
switch (p->desc.type) {
|
||||
case SIOCTL_NUM:
|
||||
case SIOCTL_SW:
|
||||
printf("%.2g", p->curval / (float)SIOCTL_VALMAX);
|
||||
printf("%.2g", p->curval / (float)p->desc.maxval);
|
||||
break;
|
||||
case SIOCTL_VEC:
|
||||
case SIOCTL_LIST:
|
||||
|
@ -383,7 +389,7 @@ print_val(struct info *p, int mono)
|
|||
if (more)
|
||||
printf(",");
|
||||
print_node(&e->desc.node1, mono);
|
||||
printf(":%.2g", e->curval / (float)SIOCTL_VALMAX);
|
||||
printf(":%.2g", e->curval / (float)e->desc.maxval);
|
||||
more = 1;
|
||||
}
|
||||
}
|
||||
|
@ -461,25 +467,21 @@ parse_unit(char **line, unsigned int *num)
|
|||
}
|
||||
|
||||
int
|
||||
parse_val(char **line, unsigned int *num)
|
||||
parse_val(char **line, float *num)
|
||||
{
|
||||
char *p = *line;
|
||||
unsigned int ival;
|
||||
float fval;
|
||||
float val;
|
||||
int n;
|
||||
|
||||
if (sscanf(p, "%g%n", &fval, &n) != 1) {
|
||||
if (sscanf(p, "%g%n", &val, &n) != 1) {
|
||||
fprintf(stderr, "number expected near '%s'\n", p);
|
||||
return 0;
|
||||
}
|
||||
if (fval < 0 || fval > 1) {
|
||||
fprintf(stderr, "%g: expected number between 0 and 1\n", fval);
|
||||
if (val < 0 || val > 1) {
|
||||
fprintf(stderr, "%g: expected number between 0 and 1\n", val);
|
||||
return 0;
|
||||
}
|
||||
ival = fval * (SIOCTL_VALMAX + 1);
|
||||
if (ival > SIOCTL_VALMAX)
|
||||
ival = SIOCTL_VALMAX;
|
||||
*num = ival;
|
||||
*num = val;
|
||||
*line = p + n;
|
||||
return 1;
|
||||
}
|
||||
|
@ -515,7 +517,7 @@ parse_node(char **line, char *str, int *unit)
|
|||
* parse a decimal prefixed by the optional mode
|
||||
*/
|
||||
int
|
||||
parse_modeval(char **line, int *rmode, int *rval)
|
||||
parse_modeval(char **line, int *rmode, float *rval)
|
||||
{
|
||||
char *p = *line;
|
||||
unsigned mode;
|
||||
|
@ -561,12 +563,12 @@ dump(void)
|
|||
switch (i->desc.type) {
|
||||
case SIOCTL_NUM:
|
||||
case SIOCTL_SW:
|
||||
printf("* (%u)", i->curval);
|
||||
printf("0..%d (%u)", i->desc.maxval, i->curval);
|
||||
break;
|
||||
case SIOCTL_VEC:
|
||||
case SIOCTL_LIST:
|
||||
print_node(&i->desc.node1, 0);
|
||||
printf(":* (%u)", i->curval);
|
||||
printf(":0..%d (%u)", i->desc.maxval, i->curval);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
@ -584,7 +586,8 @@ cmd(char *line)
|
|||
char astr[SIOCTL_NAMEMAX], vstr[SIOCTL_NAMEMAX];
|
||||
int aunit, vunit;
|
||||
unsigned npar = 0, nent = 0;
|
||||
int val, comma, mode;
|
||||
int comma, mode;
|
||||
float val;
|
||||
|
||||
pos = strrchr(line, '/');
|
||||
if (pos != NULL) {
|
||||
|
@ -637,7 +640,7 @@ cmd(char *line)
|
|||
if (!matchpar(i, astr, aunit))
|
||||
continue;
|
||||
i->mode = mode;
|
||||
i->newval = val;
|
||||
i->newval = ftoi(val * i->desc.maxval);
|
||||
npar++;
|
||||
}
|
||||
break;
|
||||
|
@ -668,7 +671,7 @@ cmd(char *line)
|
|||
if (!parse_modeval(&pos, &mode, &val))
|
||||
return 0;
|
||||
} else {
|
||||
val = SIOCTL_VALMAX;
|
||||
val = 1.;
|
||||
mode = MODE_SET;
|
||||
}
|
||||
nent = 0;
|
||||
|
@ -677,7 +680,7 @@ cmd(char *line)
|
|||
continue;
|
||||
for (e = i; e != NULL; e = nextent(e, 0)) {
|
||||
if (matchent(e, vstr, vunit)) {
|
||||
e->newval = val;
|
||||
e->newval = ftoi(val * e->desc.maxval);
|
||||
e->mode = mode;
|
||||
nent++;
|
||||
}
|
||||
|
@ -723,8 +726,8 @@ commit(void)
|
|||
break;
|
||||
case MODE_ADD:
|
||||
val = i->curval + i->newval;
|
||||
if (val > SIOCTL_VALMAX)
|
||||
val = SIOCTL_VALMAX;
|
||||
if (val > i->desc.maxval)
|
||||
val = i->desc.maxval;
|
||||
break;
|
||||
case MODE_SUB:
|
||||
val = i->curval - i->newval;
|
||||
|
@ -732,11 +735,8 @@ commit(void)
|
|||
val = 0;
|
||||
break;
|
||||
case MODE_TOGGLE:
|
||||
val = (i->curval >= SIOCTL_VALMAX / 2) ?
|
||||
0 : SIOCTL_VALMAX;
|
||||
val = i->curval ? 0 : i->desc.maxval;
|
||||
}
|
||||
if (i->desc.type == SIOCTL_SW || i->desc.type == SIOCTL_LIST)
|
||||
val = val ? SIOCTL_VALMAX : 0;
|
||||
sioctl_setval(hdl, i->ctladdr, val);
|
||||
i->curval = val;
|
||||
}
|
||||
|
|
|
@ -1147,10 +1147,10 @@ dev_open(struct dev *d)
|
|||
dev_addctl(d, "app", CTL_NUM,
|
||||
CTLADDR_SLOT_LEVEL(i),
|
||||
name, -1, "level",
|
||||
NULL, -1, d->slot[i].vol);
|
||||
NULL, -1, 127, d->slot[i].vol);
|
||||
}
|
||||
dev_addctl(d, "", CTL_NUM,
|
||||
CTLADDR_MASTER, "output", -1, "level", NULL, -1, d->master);
|
||||
CTLADDR_MASTER, "output", -1, "level", NULL, -1, 127, d->master);
|
||||
|
||||
d->pstate = DEV_INIT;
|
||||
return 1;
|
||||
|
@ -2259,7 +2259,7 @@ ctl_log(struct ctl *c)
|
|||
*/
|
||||
struct ctl *
|
||||
dev_addctl(struct dev *d, char *gstr, int type, int addr,
|
||||
char *str0, int unit0, char *func, char *str1, int unit1, int val)
|
||||
char *str0, int unit0, char *func, char *str1, int unit1, int maxval, int val)
|
||||
{
|
||||
struct ctl *c, **pc;
|
||||
int i;
|
||||
|
@ -2276,6 +2276,7 @@ dev_addctl(struct dev *d, char *gstr, int type, int addr,
|
|||
} else
|
||||
memset(&c->node1, 0, sizeof(struct ctl_node));
|
||||
c->addr = addr;
|
||||
c->maxval = maxval;
|
||||
c->val_mask = ~0;
|
||||
c->desc_mask = ~0;
|
||||
c->curval = val;
|
||||
|
|
|
@ -139,6 +139,7 @@ struct ctl {
|
|||
unsigned int val_mask;
|
||||
unsigned int desc_mask;
|
||||
unsigned int refs_mask;
|
||||
unsigned int maxval;
|
||||
unsigned int curval;
|
||||
int dirty;
|
||||
};
|
||||
|
@ -309,7 +310,7 @@ int dev_onval(struct dev *, int, int);
|
|||
int dev_nctl(struct dev *);
|
||||
void dev_label(struct dev *, int);
|
||||
struct ctl *dev_addctl(struct dev *, char *, int, int,
|
||||
char *, int, char *, char *, int, int);
|
||||
char *, int, char *, char *, int, int, int);
|
||||
void dev_rmctl(struct dev *, int);
|
||||
int dev_makeunit(struct dev *, char *);
|
||||
|
||||
|
|
|
@ -77,7 +77,7 @@ dev_sioctl_ondesc(void *arg, struct sioctl_desc *desc, int val)
|
|||
|
||||
dev_addctl(d, group, desc->type, addr,
|
||||
desc->node0.name, desc->node0.unit, desc->func,
|
||||
desc->node1.name, desc->node1.unit, val);
|
||||
desc->node1.name, desc->node1.unit, desc->maxval, val);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -1543,6 +1543,7 @@ sock_buildmsg(struct sock *f)
|
|||
desc->type = c->type;
|
||||
strlcpy(desc->func, c->func, AMSG_CTL_NAMEMAX);
|
||||
desc->addr = htons(c->addr);
|
||||
desc->maxval = htons(c->maxval);
|
||||
desc->curval = htons(c->curval);
|
||||
size += sizeof(struct amsg_ctl_desc);
|
||||
desc++;
|
||||
|
|
|
@ -44,7 +44,8 @@
|
|||
char *dev_name;
|
||||
struct pollfd pfds[16];
|
||||
struct sioctl_hdl *hdl;
|
||||
unsigned int output_addr, output_val = SIOCTL_VALMAX;
|
||||
unsigned int output_addr;
|
||||
int output_val, output_maxval;
|
||||
int output_found = 0;
|
||||
int verbose;
|
||||
|
||||
|
@ -70,6 +71,7 @@ dev_ondesc(void *unused, struct sioctl_desc *desc, int val)
|
|||
strcmp(desc->func, "level") == 0) {
|
||||
output_found = 1;
|
||||
output_addr = desc->addr;
|
||||
output_maxval = desc->maxval;
|
||||
output_val = val;
|
||||
if (verbose)
|
||||
fprintf(stderr, "%s: output at addr %u, value = %u\n",
|
||||
|
@ -139,8 +141,8 @@ dev_incrvol(int incr)
|
|||
if (!dev_connect())
|
||||
return;
|
||||
vol = output_val + incr;
|
||||
if (vol > SIOCTL_VALMAX)
|
||||
vol = SIOCTL_VALMAX;
|
||||
if (vol > output_maxval)
|
||||
vol = output_maxval;
|
||||
if (vol < 0)
|
||||
vol = 0;
|
||||
if (output_val != (unsigned int)vol) {
|
||||
|
|
Loading…
Reference in New Issue