commit 75e74d4a795cc470cc766bebc2a0a53f285e780a
parent 59e86ffbff3a421127aae4df5645dd0912c076b6
Author: Christos Margiolis <christos@margiolis.net>
Date: Wed, 28 Jul 2021 18:37:18 +0300
mixer(3): moved control handling here
Diffstat:
4 files changed, 312 insertions(+), 145 deletions(-)
diff --git a/diff/mixer_kern.diff b/diff/mixer_kern.diff
@@ -308,51 +308,53 @@ index 8e11d553a3e..7857609b289 100644
void mix_setrealdev(struct snd_mixer *m, u_int32_t dev, u_int32_t realdev);
u_int32_t mix_getparent(struct snd_mixer *m, u_int32_t dev);
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
-index b4be28aeff8..2638885d431 100644
+index b4be28aeff8..e2014a70f9b 100644
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
-@@ -1012,12 +1012,28 @@ SYSCTL_PROC(_hw_snd, OID_AUTO, clone_gc, CTLTYPE_INT | CTLFLAG_RWTUN,
+@@ -1012,12 +1012,30 @@ SYSCTL_PROC(_hw_snd, OID_AUTO, clone_gc, CTLTYPE_INT | CTLFLAG_RWTUN,
"global clone garbage collector");
#endif
+static u_int8_t
-+pcm_status_init(struct snddev_info *d)
++pcm_mode_init(struct snddev_info *d)
+{
-+ u_int8_t status = PCM_STATUS_NONE;
++ u_int8_t mode = 0;
+
+ if (d->playcount > 0)
-+ status |= PCM_STATUS_PLAY;
++ mode |= PCM_MODE_PLAY;
+ if (d->reccount > 0)
-+ status |= PCM_STATUS_REC;
++ mode |= PCM_MODE_REC;
++ if (d->playcount == 0 && d->reccount == 0)
++ mode = PCM_MODE_NONE;
+
-+ return (status);
++ return (mode);
+}
+
static void
pcm_sysinit(device_t dev)
{
struct snddev_info *d = device_get_softc(dev);
-+ u_int8_t status;
++ u_int8_t mode;
+
-+ status = pcm_status_init(d);
++ mode = pcm_mode_init(d);
- /* XXX: an user should be able to set this with a control tool, the
+ /* XXX: a user should be able to set this with a control tool, the
sysadmin then needs min+max sysctls for this */
SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-@@ -1027,6 +1043,10 @@ pcm_sysinit(device_t dev)
+@@ -1027,6 +1045,10 @@ pcm_sysinit(device_t dev)
"bitperfect", CTLTYPE_INT | CTLFLAG_RWTUN, d, sizeof(d),
sysctl_dev_pcm_bitperfect, "I",
"bit-perfect playback/recording (0=disable, 1=enable)");
+ SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
+ SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-+ OID_AUTO, "status", CTLFLAG_RD, NULL, status,
-+ "playback/recording status (0=none, 1=play, 2=rec, 3=play+rec)");
++ OID_AUTO, "mode", CTLFLAG_RD, NULL, mode,
++ "mode (0=none, 1=play, 2=rec, 3=play+rec)");
#ifdef SND_DEBUG
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
-@@ -1130,7 +1150,7 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
+@@ -1130,7 +1152,7 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
sysctl_ctx_init(&d->rec_sysctl_ctx);
d->rec_sysctl_tree = SYSCTL_ADD_NODE(&d->rec_sysctl_ctx,
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "rec",
@@ -362,16 +364,16 @@ index b4be28aeff8..2638885d431 100644
if (numplay > 0 || numrec > 0)
d->flags |= SD_F_AUTOVCHAN;
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
-index d4b3a23e8eb..c16555f830a 100644
+index d4b3a23e8eb..eda4012a517 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -411,6 +411,10 @@ struct snddev_info {
void sound_oss_sysinfo(oss_sysinfo *);
int sound_oss_card_info(oss_card_info *);
-+#define PCM_STATUS_NONE 0x00
-+#define PCM_STATUS_PLAY 0x01
-+#define PCM_STATUS_REC 0x02
++#define PCM_MODE_NONE 0x01
++#define PCM_MODE_PLAY 0x02
++#define PCM_MODE_REC 0x04
+
#define PCM_LOCKOWNED(d) mtx_owned((d)->lock)
#define PCM_LOCK(d) mtx_lock((d)->lock)
diff --git a/mixer_lib/mixer.c b/mixer_lib/mixer.c
@@ -86,7 +86,7 @@ mixer_open(const char *name)
(void)strlcpy(m->name, name, sizeof(m->name));
} else {
dunit:
- if ((m->unit = mixer_getdunit()) < 0)
+ if ((m->unit = mixer_get_dunit()) < 0)
goto fail;
(void)snprintf(m->name, sizeof(m->name) - 1, "/dev/mixer%d", m->unit);
}
@@ -95,8 +95,8 @@ dunit:
goto fail;
m->devmask = m->recmask = m->recsrc = 0;
- m->f_default = m->unit == mixer_getdunit();
- m->status = mixer_getstatus(m->unit);
+ m->f_default = m->unit == mixer_get_dunit();
+ m->mode = mixer_get_mode(m->unit);
/* The unit number _must_ be set before the ioctl. */
m->mi.dev = m->unit;
m->ci.card = m->unit;
@@ -115,9 +115,11 @@ dunit:
if ((dp = calloc(1, sizeof(struct mix_dev))) == NULL)
goto fail;
dp->devno = i;
+ dp->nctl = 0;
if (_mixer_readvol(m, dp) < 0)
goto fail;
(void)strlcpy(dp->name, names[i], sizeof(dp->name));
+ TAILQ_INIT(&dp->ctls);
TAILQ_INSERT_TAIL(&m->devs, dp, devs);
m->ndev++;
}
@@ -140,12 +142,18 @@ int
mixer_close(struct mixer *m)
{
struct mix_dev *dp;
+ mix_ctl_t *cp;
int r;
r = close(m->fd);
while (!TAILQ_EMPTY(&m->devs)) {
dp = TAILQ_FIRST(&m->devs);
TAILQ_REMOVE(&m->devs, dp, devs);
+ while (!TAILQ_EMPTY(&dp->ctls)) {
+ cp = TAILQ_FIRST(&dp->ctls);
+ TAILQ_REMOVE(&dp->ctls, cp, ctls);
+ free(cp);
+ }
free(dp);
}
free(m);
@@ -162,7 +170,7 @@ mixer_close(struct mixer *m)
* The caller must manually assign the return value to `m->dev`.
*/
struct mix_dev *
-mixer_getdev(struct mixer *m, int dev)
+mixer_get_dev(struct mixer *m, int dev)
{
struct mix_dev *dp;
@@ -185,7 +193,7 @@ mixer_getdev(struct mixer *m, int dev)
* @param name device name (e.g vol, pcm, ...)
*/
struct mix_dev *
-mixer_getdevbyname(struct mixer *m, const char *name)
+mixer_get_dev_byname(struct mixer *m, const char *name)
{
struct mix_dev *dp;
@@ -199,6 +207,107 @@ mixer_getdevbyname(struct mixer *m, const char *name)
}
/*
+ * Make a mixer control.
+ */
+mix_ctl_t *
+mixer_make_ctl(int id, const char *name,
+ int (*mod)(struct mixer *m, void *p), int (*print)(struct mixer *m, void *p))
+{
+ mix_ctl_t *ctl;
+
+ if ((ctl = calloc(1, sizeof(mix_ctl_t))) == NULL)
+ return (NULL);
+ ctl->id = id;
+ if (name != NULL)
+ (void)strlcpy(ctl->name, name, sizeof(ctl->name));
+ ctl->mod = mod;
+ ctl->print = print;
+
+ return (ctl);
+}
+
+/*
+ * Add a mixer control to a device by passing all fields as arguments.
+ */
+int
+mixer_add_ctl(struct mix_dev *d, int id, const char *name,
+ int (*mod)(struct mixer *m, void *p), int (*print)(struct mixer *m, void *p))
+{
+ mix_ctl_t *ctl;
+
+ if ((ctl = mixer_make_ctl(id, name, mod, print)) == NULL)
+ return (-1);
+
+ return (mixer_add_ctl_s(d, ctl));
+}
+
+/*
+ * Add a mixer control to a device.
+ */
+int
+mixer_add_ctl_s(struct mix_dev *d, mix_ctl_t *ctl)
+{
+ if (ctl == NULL || ctl->mod == NULL || ctl->print == NULL)
+ return (-1);
+ TAILQ_INSERT_TAIL(&d->ctls, ctl, ctls);
+ d->nctl++;
+
+ return (0);
+}
+
+/*
+ * Remove a mixer control from a device.
+ */
+int
+mixer_remove_ctl(struct mix_dev *d, mix_ctl_t *ctl)
+{
+ if (ctl == NULL) {
+ errno = EINVAL;
+ return (-1);
+ }
+ if (!TAILQ_EMPTY(&d->ctls)) {
+ TAILQ_REMOVE(&d->ctls, ctl, ctls);
+ free(ctl);
+ }
+
+ return (0);
+}
+
+/*
+ * Get a mixer control by id.
+ */
+mix_ctl_t *
+mixer_get_ctl(struct mix_dev *d, int id)
+{
+ mix_ctl_t *cp;
+
+ TAILQ_FOREACH(cp, &d->ctls, ctls) {
+ if (cp->id == id)
+ return (cp);
+ }
+ errno = EINVAL;
+
+ return (NULL);
+}
+
+/*
+ * Get a mixer control by name.
+ */
+mix_ctl_t *
+mixer_get_ctl_byname(struct mix_dev *d, const char *name)
+{
+ mix_ctl_t *cp;
+
+ TAILQ_FOREACH(cp, &d->ctls, ctls) {
+ if (!strncmp(cp->name, name, sizeof(cp->name)))
+ return (cp);
+ }
+ errno = EINVAL;
+
+ return (NULL);
+}
+
+/*
* Change the mixer's left and right volume. The allowed volume values are
* between MIX_VOLMIN and MIX_VOLMAX. The `ioctl` for volume change requires
* an integer value between 0 and 100 stored as `lvol | rvol << 8` -- for
@@ -208,7 +317,7 @@ mixer_getdevbyname(struct mixer *m, const char *name)
* Volume clumping should be done by the caller.
*/
int
-mixer_setvol(struct mixer *m, mix_volume_t vol)
+mixer_set_vol(struct mixer *m, mix_volume_t vol)
{
int v;
@@ -234,7 +343,7 @@ mixer_setvol(struct mixer *m, mix_volume_t vol)
* MIX_TOGGLEMUTE toggle device's mute
*/
int
-mixer_setmute(struct mixer *m, int opt)
+mixer_set_mute(struct mixer *m, int opt)
{
switch (opt) {
case MIX_MUTE:
@@ -268,7 +377,7 @@ mixer_setmute(struct mixer *m, int opt)
* MIX_TOGGLERECSRC toggle device from recording sources
*/
int
-mixer_modrecsrc(struct mixer *m, int opt)
+mixer_mod_recsrc(struct mixer *m, int opt)
{
if (!m->recmask || !MIX_ISREC(m, m->dev->devno)) {
errno = ENODEV;
@@ -304,7 +413,7 @@ mixer_modrecsrc(struct mixer *m, int opt)
* and set the mixer structure's `f_default` flag.
*/
int
-mixer_getdunit(void)
+mixer_get_dunit(void)
{
size_t size;
int unit;
@@ -324,7 +433,7 @@ mixer_getdunit(void)
* @param unit the audio card number (e.g pcm0, pcm1, ...).
*/
int
-mixer_setdunit(struct mixer *m, int unit)
+mixer_set_dunit(struct mixer *m, int unit)
{
size_t size;
@@ -337,29 +446,29 @@ mixer_setdunit(struct mixer *m, int unit)
}
/*
- * Get sound device status (none, play, rec, play+rec). Userland programs can
- * use the MIX_STATUS_* flags to determine the status of the device.
+ * Get sound device mode (none, play, rec, play+rec). Userland programs can
+ * use the MIX_STATUS_* flags to determine the mode of the device.
*/
int
-mixer_getstatus(int unit)
+mixer_get_mode(int unit)
{
- char buf[BUFSIZ];
+ char buf[64];
size_t size;
- unsigned int status;
+ unsigned int mode;
- (void)snprintf(buf, sizeof(buf) - 1, "dev.pcm.%d.status", unit);
+ (void)snprintf(buf, sizeof(buf) - 1, "dev.pcm.%d.mode", unit);
size = sizeof(unsigned int);
- if (sysctlbyname(buf, &status, &size, NULL, 0) < 0)
+ if (sysctlbyname(buf, &mode, &size, NULL, 0) < 0)
return (-1);
- return (status);
+ return (mode);
}
/*
* Get the total number of mixers in the system.
*/
int
-mixer_getnmixers(void)
+mixer_get_nmixers(void)
{
struct mixer *m;
oss_sysinfo si;
diff --git a/mixer_lib/mixer.h b/mixer_lib/mixer.h
@@ -40,6 +40,16 @@ __FBSDID("$FreeBSD$");
#define MIX_ISREC(m,n) MIX_ISSET(n, (m)->recmask)
#define MIX_ISRECSRC(m,n) MIX_ISSET(n, (m)->recsrc)
+struct mixer;
+
+typedef struct mix_ctl {
+ int id;
+ char name[NAME_MAX];
+ int (*mod)(struct mixer *, void *);
+ int (*print)(struct mixer *, void *);
+ TAILQ_ENTRY(mix_ctl) ctls;
+} mix_ctl_t;
+
struct mix_dev {
char name[NAME_MAX];
int devno;
@@ -51,6 +61,8 @@ struct mix_dev {
float left;
float right;
} vol;
+ int nctl;
+ TAILQ_HEAD(, mix_ctl) ctls;
TAILQ_ENTRY(mix_dev) devs;
};
@@ -74,26 +86,34 @@ struct mixer {
#define MIX_SETRECSRC 0x04
#define MIX_TOGGLERECSRC 0x08
int recsrc;
- int f_default; /* TODO: combine with status? */
-#define MIX_STATUS_NONE 0x00
-#define MIX_STATUS_PLAY 0x01
-#define MIX_STATUS_REC 0x02
- int status;
+ int f_default;
+#define MIX_MODE_NONE 0x01
+#define MIX_MODE_PLAY 0x02
+#define MIX_MODE_REC 0x04
+ int mode;
};
typedef struct mix_volume mix_volume_t;
struct mixer *mixer_open(const char *);
int mixer_close(struct mixer *);
-struct mix_dev *mixer_getdev(struct mixer *, int);
-struct mix_dev *mixer_getdevbyname(struct mixer *, const char *);
-int mixer_setvol(struct mixer *, mix_volume_t);
-int mixer_setmute(struct mixer *, int);
-int mixer_modrecsrc(struct mixer *, int);
-int mixer_getdunit(void);
-int mixer_setdunit(struct mixer *, int);
-int mixer_getstatus(int);
-int mixer_getnmixers(void);
+struct mix_dev *mixer_get_dev(struct mixer *, int);
+struct mix_dev *mixer_get_dev_byname(struct mixer *, const char *);
+mix_ctl_t *mixer_make_ctl(int, const char *,
+ int (*)(struct mixer *, void *), int (*)(struct mixer *, void *));
+int mixer_add_ctl(struct mix_dev *, int, const char *,
+ int (*)(struct mixer *, void *), int (*)(struct mixer *, void *));
+int mixer_add_ctl_s(struct mix_dev *, mix_ctl_t *);
+int mixer_remove_ctl(struct mix_dev *, mix_ctl_t *);
+mix_ctl_t *mixer_get_ctl(struct mix_dev *, int);
+mix_ctl_t *mixer_get_ctl_byname(struct mix_dev *, const char *);
+int mixer_set_vol(struct mixer *, mix_volume_t);
+int mixer_set_mute(struct mixer *, int);
+int mixer_mod_recsrc(struct mixer *, int);
+int mixer_get_dunit(void);
+int mixer_set_dunit(struct mixer *, int);
+int mixer_get_mode(int);
+int mixer_get_nmixers(void);
__END_DECLS
diff --git a/mixer_prog/mixer_prog.c b/mixer_prog/mixer_prog.c
@@ -31,42 +31,28 @@
#define LEN(x) (sizeof(x) / sizeof(x[0]))
-#define MCTL_VOL 0
-#define MCTL_PAN 1
-#define MCTL_MUT 2
-#define MCTL_SRC 3
-
-struct mix_ctl {
- char name[NAME_MAX];
- void (*mod)(struct mixer *, const char *);
- void (*print)(struct mixer *);
- /* TODO: printed flag */
-};
-
static void usage(void) __dead2;
+static void initctls(struct mixer *);
static void printall(struct mixer *, int);
static void printminfo(struct mixer *, int);
-static void printdev(struct mixer *, struct mix_dev *, int);
+static void printdev(struct mixer *, int);
static void printrecsrc(struct mixer *, int);
-static int findctl(const char *);
/* Control handlers */
-static void mod_volume(struct mixer *, const char *);
-static void mod_mute(struct mixer *, const char *);
-static void mod_recsrc(struct mixer *, const char *);
-static void print_volume(struct mixer *);
-static void print_mute(struct mixer *);
-static void print_recsrc(struct mixer *);
-
-static const struct mix_ctl ctls[] = {
- [MCTL_VOL] = { "volume", mod_volume, print_volume },
- [MCTL_MUT] = { "mute", mod_mute, print_mute },
- [MCTL_SRC] = { "recsrc", mod_recsrc, print_recsrc },
-};
+static int mod_dunit(struct mixer *, void *);
+static int mod_volume(struct mixer *, void *);
+static int mod_mute(struct mixer *, void *);
+static int mod_recsrc(struct mixer *, void *);
+static int print_volume(struct mixer *, void *);
+static int print_mute(struct mixer *, void *);
+static int print_recsrc(struct mixer *, void *);
+
+static mix_ctl_t *ctl_dunit;
int
main(int argc, char *argv[])
{
struct mixer *m;
+ mix_ctl_t *cp;
char *name = NULL, buf[NAME_MAX];
char *p, *bufp, *devstr, *ctlstr, *valstr = NULL;
int dunit, i, n, pall = 1;
@@ -103,12 +89,13 @@ main(int argc, char *argv[])
/* Print all mixers and exit. */
if (aflag) {
- if ((n = mixer_getnmixers()) < 0)
+ if ((n = mixer_get_nmixers()) < 0)
err(1, "mixer_get_nmixers");
for (i = 0; i < n; i++) {
(void)snprintf(buf, sizeof(buf), "/dev/mixer%d", i);
if ((m = mixer_open(buf)) == NULL)
err(1, "mixer_open: %s", buf);
+ initctls(m);
if (sflag)
printrecsrc(m, oflag);
else {
@@ -124,18 +111,10 @@ main(int argc, char *argv[])
if ((m = mixer_open(name)) == NULL)
err(1, "mixer_open: %s", name);
- /* XXX: make it a control? */
- if (dflag) {
- if ((n = mixer_getdunit()) < 0) {
- warn("cannot get default unit");
- goto parse;
- }
- if (mixer_setdunit(m, dunit) < 0) {
- warn("cannot set default unit to: %d", dunit);
- goto parse;
- }
- printf("default_unit: %d -> %d\n", n, dunit);
- }
+ initctls(m);
+
+ if (dflag && ctl_dunit->mod(m, &dunit) < 0)
+ goto parse;
if (sflag) {
printrecsrc(m, oflag);
(void)mixer_close(m);
@@ -148,30 +127,31 @@ parse:
err(1, "strdup(%s)", *argv);
/* Split the string into device, control and value. */
devstr = strsep(&p, ".");
- if ((m->dev = mixer_getdevbyname(m, devstr)) == NULL) {
+ if ((m->dev = mixer_get_dev_byname(m, devstr)) == NULL) {
warnx("%s: no such device", devstr);
goto next;
}
/* Input: `dev`. */
if (p == NULL) {
- printdev(m, m->dev, 1);
+ printdev(m, 1);
pall = 0;
goto next;
}
ctlstr = strsep(&p, "=");
- if ((n = findctl(ctlstr)) < 0) {
+ if ((cp = mixer_get_ctl_byname(m->dev, ctlstr)) == NULL) {
warnx("%s.%s: no such control", devstr, ctlstr);
goto next;
}
+
/* Input: `dev.control`. */
if (p == NULL) {
- ctls[n].print(m);
+ (void)cp->print(m, cp->name);
pall = 0;
goto next;
}
valstr = p;
/* Input: `dev.control=val`. */
- ctls[n].mod(m, valstr);
+ cp->mod(m, valstr);
next:
free(p);
argc--;
@@ -195,13 +175,31 @@ usage(void)
}
static void
+initctls(struct mixer *m)
+{
+ struct mix_dev *dp;
+
+#define C_VOL 0
+#define C_MUT 1
+#define C_SRC 2
+ TAILQ_FOREACH(dp, &m->devs, devs) {
+ (void)mixer_add_ctl(dp, C_VOL, "volume", mod_volume, print_volume);
+ (void)mixer_add_ctl(dp, C_MUT, "mute", mod_mute, print_mute);
+ (void)mixer_add_ctl(dp, C_SRC, "recsrc", mod_recsrc, print_recsrc);
+ }
+ ctl_dunit = mixer_make_ctl(-1, "default_unit", mod_dunit, NULL);
+
+}
+
+static void
printall(struct mixer *m, int oflag)
{
struct mix_dev *dp;
printminfo(m, oflag);
TAILQ_FOREACH(dp, &m->devs, devs) {
- printdev(m, dp, oflag);
+ m->dev = dp;
+ printdev(m, oflag);
}
}
@@ -211,21 +209,27 @@ printminfo(struct mixer *m, int oflag)
if (oflag)
return;
printf("%s: <%s> %s", m->mi.name, m->ci.longname, m->ci.hw_info);
- /* TODO: clean up the mess */
- if (m->status & MIX_STATUS_PLAY)
- printf(" (play%s", m->status & MIX_STATUS_REC ? "" : ")");
- if (m->status == (MIX_STATUS_PLAY | MIX_STATUS_REC))
+ if (!(m->mode & MIX_MODE_NONE))
+ printf(" (");
+ if (m->mode & MIX_MODE_PLAY)
+ printf("play");
+ if (m->mode == (MIX_MODE_PLAY | MIX_MODE_REC))
printf("/");
- if (m->status & MIX_STATUS_REC)
- printf("%srec)", m->status & MIX_STATUS_PLAY ? "" : " (");
+ if (m->mode & MIX_MODE_REC)
+ printf("rec");
+ if (!(m->mode & MIX_MODE_NONE))
+ printf(")");
if (m->f_default)
printf(" (default)");
printf("\n");
}
static void
-printdev(struct mixer *m, struct mix_dev *d, int oflag)
+printdev(struct mixer *m, int oflag)
{
+ struct mix_dev *d = m->dev;
+ mix_ctl_t *cp;
+
if (!oflag) {
printf(" %-11s= %.2f:%.2f\t",
d->name, d->vol.left, d->vol.right);
@@ -239,12 +243,9 @@ printdev(struct mixer *m, struct mix_dev *d, int oflag)
printf(" mute");
printf("\n");
} else {
- printf("%s.%s=%.2f:%.2f\n",
- d->name, ctls[MCTL_VOL].name, d->vol.left, d->vol.right);
- printf("%s.%s=%d\n",
- d->name, ctls[MCTL_MUT].name, MIX_ISMUTE(m, d->devno));
- if (MIX_ISRECSRC(m, d->devno))
- printf("%s.%s=+\n", d->name, ctls[MCTL_SRC].name);
+ TAILQ_FOREACH(cp, &d->ctls, ctls) {
+ (void)cp->print(m, cp->name);
+ }
}
}
@@ -270,29 +271,40 @@ printrecsrc(struct mixer *m, int oflag)
}
static int
-findctl(const char *ctl)
+mod_dunit(struct mixer *m, void *p)
{
- int i;
+ int dunit = *((int *)p);
+ int n;
- for (i = 0; i < LEN(ctls); i++)
- if (strcmp(ctl, ctls[i].name) == 0)
- return (i);
+ if ((n = mixer_get_dunit()) < 0) {
+ warn("cannot get default unit");
+ return (-1);
+ }
+ if (mixer_set_dunit(m, dunit) < 0) {
+ warn("cannot set default unit to: %d", dunit);
+ return (-1);
+ }
+ printf("%s: %d -> %d\n", ctl_dunit->name, n, dunit);
- return (-1);
+ return (0);
}
-static void
-mod_volume(struct mixer *m, const char *val)
+static int
+mod_volume(struct mixer *m, void *p)
{
+ mix_ctl_t *cp;
mix_volume_t v;
+ const char *val;
char lstr[8], rstr[8];
float lprev, rprev, lrel, rrel;
int n;
+ cp = mixer_get_ctl(m->dev, C_VOL);
+ val = p;
n = sscanf(val, "%7[^:]:%7s", lstr, rstr);
if (n == EOF) {
warnx("invalid volume value: %s", val);
- return;
+ return (-1);
}
lrel = rrel = 0;
if (n > 0) {
@@ -325,21 +337,26 @@ mod_volume(struct mixer *m, const char *val)
lprev = m->dev->vol.left;
rprev = m->dev->vol.right;
- if (mixer_setvol(m, v) < 0)
+ if (mixer_set_vol(m, v) < 0)
warn("%s.%s=%.2f:%.2f",
- m->dev->name, ctls[MCTL_VOL].name, v.left, v.right);
+ m->dev->name, cp->name, v.left, v.right);
else
printf("%s.%s: %.2f:%.2f -> %.2f:%.2f\n",
- m->dev->name, ctls[MCTL_VOL].name,
- lprev, rprev, v.left, v.right);
+ m->dev->name, cp->name, lprev, rprev, v.left, v.right);
}
+
+ return (0);
}
-static void
-mod_mute(struct mixer *m, const char *val)
+static int
+mod_mute(struct mixer *m, void *p)
{
+ mix_ctl_t *cp;
+ const char *val;
int n, opt = -1;
+ cp = mixer_get_ctl(m->dev, C_MUT);
+ val = p;
switch (*val) {
case '0':
opt = MIX_UNMUTE;
@@ -352,21 +369,27 @@ mod_mute(struct mixer *m, const char *val)
break;
default:
warnx("%c: no such modifier", *val);
- return;
+ return (-1);
}
n = MIX_ISMUTE(m, m->dev->devno);
- if (mixer_setmute(m, opt) < 0)
- warn("%s.%s=%c", m->dev->name, ctls[MCTL_MUT].name, *val);
+ if (mixer_set_mute(m, opt) < 0)
+ warn("%s.%s=%c", m->dev->name, cp->name, *val);
else
printf("%s.%s: %d -> %d\n",
- m->dev->name, ctls[MCTL_MUT].name, n, MIX_ISMUTE(m, m->dev->devno));
+ m->dev->name, cp->name, n, MIX_ISMUTE(m, m->dev->devno));
+
+ return (0);
}
-static void
-mod_recsrc(struct mixer *m, const char *val)
+static int
+mod_recsrc(struct mixer *m, void *p)
{
+ mix_ctl_t *cp;
+ const char *val;
int n, opt = -1;
+ cp = mixer_get_ctl(m->dev, C_SRC);
+ val = p;
switch (*val) {
case '+':
opt = MIX_ADDRECSRC;
@@ -382,34 +405,47 @@ mod_recsrc(struct mixer *m, const char *val)
break;
default:
warnx("%c: no such modifier", *val);
- return;
+ return (-1);
}
n = MIX_ISRECSRC(m, m->dev->devno);
- if (mixer_modrecsrc(m, opt) < 0)
- warn("%s.%s=%c", m->dev->name, ctls[MCTL_SRC].name, *val);
+ if (mixer_mod_recsrc(m, opt) < 0)
+ warn("%s.%s=%c", m->dev->name, cp->name, *val);
else
printf("%s.%s: %d -> %d\n",
- m->dev->name, ctls[MCTL_SRC].name,
- n, MIX_ISRECSRC(m, m->dev->devno));
+ m->dev->name, cp->name, n, MIX_ISRECSRC(m, m->dev->devno));
+
+ return (0);
}
-static void
-print_volume(struct mixer *m)
+static int
+print_volume(struct mixer *m, void *p)
{
+ const char *ctl_name = p;
+
printf("%s.%s=%.2f:%.2f\n",
- m->dev->name, ctls[MCTL_VOL].name, m->dev->vol.left, m->dev->vol.right);
+ m->dev->name, ctl_name, m->dev->vol.left, m->dev->vol.right);
+
+ return (0);
}
-static void
-print_mute(struct mixer *m)
+static int
+print_mute(struct mixer *m, void *p)
{
- printf("%s.%s=%d\n", m->dev->name, ctls[MCTL_MUT].name,
- MIX_ISMUTE(m, m->dev->devno));
+ const char *ctl_name = p;
+
+ printf("%s.%s=%d\n", m->dev->name, ctl_name, MIX_ISMUTE(m, m->dev->devno));
+
+ return (0);
}
-static void
-print_recsrc(struct mixer *m)
+static int
+print_recsrc(struct mixer *m, void *p)
{
- printf("%s.%s=%d\n",
- m->dev->name, ctls[MCTL_SRC].name, MIX_ISRECSRC(m, m->dev->devno));
+ const char *ctl_name = p;
+
+ if (!MIX_ISRECSRC(m, m->dev->devno))
+ return (-1);
+ printf("%s.%s=+\n", m->dev->name, ctl_name);
+
+ return (0);
}