commit e8100ba095b92ad290f80f059e9a494a429fe372
parent a843a32e978a31becd6bd582a13a64d8c65405aa
Author: Christos Margiolis <christos@margiolis.net>
Date: Wed, 7 Jul 2021 15:16:02 +0300
minor changes
Diffstat:
4 files changed, 230 insertions(+), 203 deletions(-)
diff --git a/mixer_lib/mixer.c b/mixer_lib/mixer.c
@@ -34,12 +34,28 @@
#include "mixer.h"
#define BASEPATH "/dev/mixer"
+#define MIN(x, y) ((x) < (y) ? (x) : (y))
-static int _mixer_close(struct mixer *m);
+static int _mixer_readvol(struct mixer *, struct mix_dev *);
static const char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
static int ndev = 0;
+static int
+_mixer_readvol(struct mixer *m, struct mix_dev *dev)
+{
+ int v;
+
+ if (ioctl(m->fd, MIXER_READ(dev->devno), &v) < 0)
+ return (-1);
+ dev->lvol = M_VOLNORM(v & 0x00ff);
+ dev->rvol = M_VOLNORM((v >> 8) & 0x00ff);
+ dev->pan = dev->rvol - dev->lvol;
+ dev->f_mut = M_ISMUTE(m, dev->devno);
+
+ return (0);
+}
+
/*
* Open a mixer device in `/dev/mixerN`, where N is the number of the mixer
* file. Each device maps to an actual pcmN audio card, so `/dev/mixer0`
@@ -53,7 +69,7 @@ mixer_open(const char *name)
{
struct mixer *m = NULL;
struct mix_dev *dp;
- int i, v;
+ int i;
if ((m = calloc(1, sizeof(struct mixer))) == NULL)
goto fail;
@@ -96,18 +112,11 @@ dunit:
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
if (!M_ISDEV(m, i))
continue;
- if (ioctl(m->fd, MIXER_READ(i), &v) < 0)
- goto fail;
if ((dp = calloc(1, sizeof(struct mix_dev))) == NULL)
goto fail;
dp->devno = i;
-
- /* XXX: Make this a seperate function? */
- dp->lvol = M_VOLNORM(v & 0x7f);
- dp->rvol = M_VOLNORM((v >> 8) & 0x7f);
- dp->pan = dp->rvol - dp->lvol;
-
- dp->f_mut = M_ISMUTE(m, i) ? 1 : 0;
+ if (_mixer_readvol(m, dp) < 0)
+ goto fail;
dp->f_pbk = !M_ISREC(m, i) ? 1 : 0;
dp->f_rec = M_ISREC(m, i) ? 1 : 0;
dp->f_src = M_ISRECSRC(m, i) ? 1 : 0;
@@ -127,10 +136,24 @@ fail:
return (NULL);
}
+/*
+ * Free resources and close the mixer.
+ */
int
mixer_close(struct mixer *m)
{
- return (_mixer_close(m));
+ struct mix_dev *dp;
+ int r;
+
+ r = close(m->fd);
+ while (!TAILQ_EMPTY(&m->devs)) {
+ dp = TAILQ_FIRST(&m->devs);
+ TAILQ_REMOVE(&m->devs, dp, devs);
+ free(dp);
+ }
+ free(m);
+
+ return (r);
}
struct mix_dev *
@@ -195,11 +218,11 @@ mixer_setvol(struct mixer *m, float l, float r)
errno = ERANGE;
return (-1);
}
- m->dev->lvol = l;
- m->dev->rvol = r;
v = M_VOLDENORM(l) | M_VOLDENORM(r) << 8;
if (ioctl(m->fd, MIXER_WRITE(m->dev->devno), &v) < 0)
return (-1);
+ if (_mixer_readvol(m, m->dev) < 0)
+ return (-1);
return (0);
}
@@ -228,8 +251,6 @@ mixer_setpan(struct mixer *m, float pan)
int
mixer_setmute(struct mixer *m, int opt)
{
- int v;
-
switch (opt) {
case M_MUTE:
m->mutemask |= (1 << m->dev->devno);
@@ -248,13 +269,8 @@ mixer_setmute(struct mixer *m, int opt)
return (-1);
if (ioctl(m->fd, SOUND_MIXER_READ_MUTE, &m->mutemask) < 0)
return (-1);
- /* Update the volume. */
- if (ioctl(m->fd, MIXER_READ(m->dev->devno), &v) < 0)
+ if (_mixer_readvol(m, m->dev) < 0)
return (-1);
- m->dev->lvol = M_VOLNORM(v & 0x7f);
- m->dev->rvol = M_VOLNORM((v >> 8) & 0x7f);
- m->dev->pan = m->dev->rvol - m->dev->lvol;
- m->dev->f_mut = M_ISMUTE(m, m->dev->devno);
return 0;
}
@@ -356,23 +372,3 @@ mixer_getnmixers(void)
return (si.nummixers);
}
-
-/*
- * Free resources and close the mixer.
- */
-static int
-_mixer_close(struct mixer *m)
-{
- struct mix_dev *dp;
- int r;
-
- r = close(m->fd);
- while (!TAILQ_EMPTY(&m->devs)) {
- dp = TAILQ_FIRST(&m->devs);
- TAILQ_REMOVE(&m->devs, dp, devs);
- free(dp);
- }
- free(m);
-
- return (r);
-}
diff --git a/mixer_lib/mixer.h b/mixer_lib/mixer.h
@@ -57,18 +57,22 @@ __FBSDID("$FreeBSD$");
#define M_ISREC(m, n) M_ISSET(n, (m)->recmask)
#define M_ISRECSRC(m, n) M_ISSET(n, (m)->recsrc)
+//struct mix_vol {
+ //float l;
+ //float r;
+ //float pan;
+//};
+
struct mix_dev {
char name[NAME_MAX];
int devno;
- float lvol;
- float rvol;
- float pan;
- //int rate;
- //int samples;
int f_mut;
int f_pbk;
int f_rec;
int f_src;
+ float lvol;
+ float rvol;
+ float pan;
TAILQ_ENTRY(mix_dev) devs;
};
diff --git a/mixer_prog/mixer_prog.8 b/mixer_prog/mixer_prog.8
@@ -31,7 +31,8 @@
.Op Fl f Ar device
.Op Fl d Ar unit
.Op Fl os
-.Op Ar command Ar ...
+.Op Ar dev Ns Op . Ns Ar control Ns Op = Ns Ar value
+.Ar ...
.Nm
.Op Fl d Ar unit
.Op Fl os
diff --git a/mixer_prog/mixer_prog.c b/mixer_prog/mixer_prog.c
@@ -31,36 +31,172 @@
#define LEN(x) (sizeof(x) / sizeof(x[0]))
-#define CTRL_VOL 0
-#define CTRL_MUT 1
-#define CTRL_SRC 2
+#define MCTL_VOL 0
+#define MCTL_PAN 1
+#define MCTL_MUT 2
+#define MCTL_SRC 3
-struct ctrl {
+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 printall(struct mixer *, int);
static void printminfo(struct mixer *, int);
static void printdev(struct mix_dev *, int);
static void printrecsrc(struct mixer *, int);
-static int findctrl(const char *);
+static int findctl(const char *);
+/* Control handlers */
static void mod_volume(struct mixer *, const char *);
+static void mod_panning(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_panning(struct mixer *);
static void print_mute(struct mixer *);
static void print_recsrc(struct mixer *);
-static void usage(void) __dead2;
-static const struct ctrl ctrls[] = {
- [CTRL_VOL] = { "volume", mod_volume, print_volume },
- [CTRL_MUT] = { "mute", mod_mute, print_mute },
- [CTRL_SRC] = { "recsrc", mod_recsrc, print_recsrc },
+static const struct mix_ctl ctls[] = {
+ [MCTL_VOL] = { "volume", mod_volume, print_volume },
+ [MCTL_PAN] = { "panning", mod_panning, print_panning },
+ [MCTL_MUT] = { "mute", mod_mute, print_mute },
+ [MCTL_SRC] = { "recsrc", mod_recsrc, print_recsrc },
};
+int
+main(int argc, char *argv[])
+{
+ struct mixer *m;
+ char *name = NULL, buf[NAME_MAX];
+ char *p, *bufp, *devstr, *ctlstr, *valstr = NULL;
+ int dunit, i, n, pall = 1;
+ int aflag = 0, dflag = 0, oflag = 0, sflag = 0;
+ char ch;
+
+ while ((ch = getopt(argc, argv, "ad:f:os")) != -1) {
+ switch (ch) {
+ case 'a':
+ aflag = 1;
+ break;
+ case 'd':
+ dunit = strtol(optarg, NULL, 10);
+ if (errno == EINVAL || errno == ERANGE)
+ err(1, "strtol");
+ dflag = 1;
+ break;
+ case 'f':
+ name = optarg;
+ break;
+ case 'o':
+ oflag = 1;
+ break;
+ case 's':
+ sflag = 1;
+ break;
+ case '?':
+ default:
+ usage();
+ }
+ }
+ argc -= optind;
+ argv += optind;
+
+ /* Print all mixers and exit. */
+ if (aflag) {
+ if ((n = mixer_getnmixers()) < 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);
+ if (sflag)
+ printrecsrc(m, oflag);
+ else {
+ printall(m, oflag);
+ if (oflag)
+ printf("\n");
+ }
+ (void)mixer_close(m);
+ }
+ return (0);
+ }
+
+ 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);
+ }
+ if (sflag) {
+ printrecsrc(m, oflag);
+ (void)mixer_close(m);
+ return (0);
+ }
+
+parse:
+ while (argc > 0) {
+ if ((p = bufp = strdup(*argv)) == NULL)
+ err(1, "strdup(%s)", *argv);
+ /* Split the string into device, control and value. */
+ devstr = strsep(&p, ".");
+ if ((m->dev = mixer_getdevbyname(m, devstr)) == NULL) {
+ warnx("%s: no such device", devstr);
+ goto next;
+ }
+ /* Input: `dev`. */
+ if (p == NULL) {
+ printdev(m->dev, 1);
+ pall = 0;
+ goto next;
+ }
+ ctlstr = strsep(&p, "=");
+ if ((n = findctl(ctlstr)) < 0) {
+ warnx("%s.%s: no such control", devstr, ctlstr);
+ goto next;
+ }
+ /* Input: `dev.control`. */
+ if (p == NULL) {
+ ctls[n].print(m);
+ pall = 0;
+ goto next;
+ }
+ valstr = p;
+ /* Input: `dev.control=val`. */
+ ctls[n].mod(m, valstr);
+next:
+ free(p);
+ argc--;
+ argv++;
+ }
+
+ if (pall)
+ printall(m, oflag);
+ (void)mixer_close(m);
+
+ return (0);
+}
+
+static void __dead2
+usage(void)
+{
+ printf("usage: %1$s [-f device] [-d unit] [-os] [dev[.control[=value]]] ...\n"
+ " %1$s [-d unit] [-os] -a\n",
+ getprogname());
+ exit(1);
+}
+
static void
printall(struct mixer *m, int oflag)
{
@@ -100,9 +236,9 @@ printdev(struct mix_dev *d, int oflag)
printf("\n");
} else {
printf("%s.%s=%.2f:%.2f\n",
- d->name, ctrls[CTRL_VOL].name, d->lvol, d->rvol);
+ d->name, ctls[MCTL_VOL].name, d->lvol, d->rvol);
if (d->f_src)
- printf("%s.%s=+\n", d->name, ctrls[CTRL_SRC].name);
+ printf("%s.%s=+\n", d->name, ctls[MCTL_SRC].name);
/* TODO: add f_mut */
}
}
@@ -129,12 +265,12 @@ printrecsrc(struct mixer *m, int oflag)
}
static int
-findctrl(const char *ctrl)
+findctl(const char *ctl)
{
int i;
- for (i = 0; i < LEN(ctrls); i++)
- if (strcmp(ctrl, ctrls[i].name) == 0)
+ for (i = 0; i < LEN(ctls); i++)
+ if (strcmp(ctl, ctls[i].name) == 0)
return (i);
return (-1);
@@ -185,15 +321,29 @@ mod_volume(struct mixer *m, const char *val)
rprev = m->dev->rvol;
if (mixer_setvol(m, l, r) < 0)
warn("%s.%s=%.2f:%.2f",
- m->dev->name, ctrls[CTRL_VOL].name, l, r);
+ m->dev->name, ctls[MCTL_VOL].name, l, r);
else
printf("%s.%s: %.2f:%.2f -> %.2f:%.2f\n",
- m->dev->name, ctrls[CTRL_VOL].name,
+ m->dev->name, ctls[MCTL_VOL].name,
lprev, rprev, l, r);
}
}
static void
+mod_panning(struct mixer *m, const char *val)
+{
+ float n, v;
+
+ n = m->dev->pan;
+ v = strtof(val, NULL);
+ if (mixer_setpan(m, v) < 0)
+ warn("%s.%s=%.2f", m->dev->name, ctls[MCTL_PAN].name, v);
+ else
+ printf("%s.%s: %.2f -> %.2f\n",
+ m->dev->name, ctls[MCTL_PAN].name, n, v);
+}
+
+static void
mod_mute(struct mixer *m, const char *val)
{
int n, opt = -1;
@@ -214,10 +364,10 @@ mod_mute(struct mixer *m, const char *val)
}
n = m->dev->f_mut;
if (mixer_setmute(m, opt) < 0)
- warn("%s.%s=%c", m->dev->name, ctrls[CTRL_MUT].name, *val);
+ warn("%s.%s=%c", m->dev->name, ctls[MCTL_MUT].name, *val);
else
printf("%s.%s: %d -> %d\n",
- m->dev->name, ctrls[CTRL_MUT].name, n, m->dev->f_mut);
+ m->dev->name, ctls[MCTL_MUT].name, n, m->dev->f_mut);
}
static void
@@ -244,159 +394,35 @@ mod_recsrc(struct mixer *m, const char *val)
}
n = m->dev->f_src;
if (mixer_modrecsrc(m, opt) < 0)
- warn("%s.%s=%c", m->dev->name, ctrls[CTRL_SRC].name, *val);
+ warn("%s.%s=%c", m->dev->name, ctls[MCTL_SRC].name, *val);
else
printf("%s.%s: %d -> %d\n",
- m->dev->name, ctrls[CTRL_SRC].name, n, m->dev->f_src);
+ m->dev->name, ctls[MCTL_SRC].name, n, m->dev->f_src);
}
static void
print_volume(struct mixer *m)
{
printf("%s.%s=%.2f:%.2f\n",
- m->dev->name, ctrls[CTRL_VOL].name, m->dev->lvol, m->dev->rvol);
+ m->dev->name, ctls[MCTL_VOL].name, m->dev->lvol, m->dev->rvol);
}
static void
-print_mute(struct mixer *m)
+print_panning(struct mixer *m)
{
- printf("%s.%s=%d\n", m->dev->name, ctrls[CTRL_MUT].name, m->dev->f_mut);
+ printf("%s.%s=%.2f\n",
+ m->dev->name, ctls[MCTL_PAN].name, m->dev->pan);
}
static void
-print_recsrc(struct mixer *m)
-{
- printf("%s.%s=%d\n",
- m->dev->name, ctrls[CTRL_SRC].name, m->dev->f_rec);
-}
-
-static void __dead2
-usage(void)
+print_mute(struct mixer *m)
{
- printf("usage: %1$s [-f device] [-d unit] [-os] [command ...]\n"
- " %1$s [-d unit] [-os] -a\n",
- getprogname());
- exit(1);
+ printf("%s.%s=%d\n", m->dev->name, ctls[MCTL_MUT].name, m->dev->f_mut);
}
-int
-main(int argc, char *argv[])
+static void
+print_recsrc(struct mixer *m)
{
- struct mixer *m;
- char *name = NULL, buf[NAME_MAX];
- char *p, *bufp, *devstr, *ctrlstr, *valstr = NULL;
- int dunit, i, n, pall = 1;
- int aflag = 0, dflag = 0, oflag = 0, sflag = 0;
- char ch;
-
- while ((ch = getopt(argc, argv, "ad:f:os")) != -1) {
- switch (ch) {
- case 'a':
- aflag = 1;
- break;
- case 'd':
- dunit = strtol(optarg, NULL, 10);
- if (errno == EINVAL || errno == ERANGE)
- err(1, "strtol");
- dflag = 1;
- break;
- case 'f':
- name = optarg;
- break;
- case 'o':
- oflag = 1;
- break;
- case 's':
- sflag = 1;
- break;
- case '?':
- default:
- usage();
- }
- }
- argc -= optind;
- argv += optind;
-
- /* Print all mixers and exit. */
- if (aflag) {
- if ((n = mixer_getnmixers()) < 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);
- if (sflag)
- printrecsrc(m, oflag);
- else {
- printall(m, oflag);
- if (oflag)
- printf("\n");
- }
- (void)mixer_close(m);
- }
- return (0);
- }
-
- 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);
- }
- if (sflag) {
- printrecsrc(m, oflag);
- (void)mixer_close(m);
- return (0);
- }
-
-parse:
- while (argc > 0) {
- if ((p = bufp = strdup(*argv)) == NULL)
- err(1, "strdup(%s)", *argv);
- /* Split the string into device, control and value. */
- devstr = strsep(&p, ".");
- if ((m->dev = mixer_getdevbyname(m, devstr)) == NULL) {
- warnx("%s: no such device", devstr);
- goto next;
- }
- /* Input: `dev`. */
- if (p == NULL) {
- printdev(m->dev, 1);
- pall = 0;
- goto next;
- }
- ctrlstr = strsep(&p, "=");
- if ((n = findctrl(ctrlstr)) < 0) {
- warnx("%s.%s: no such control", devstr, ctrlstr);
- goto next;
- }
- /* Input: `dev.ctrl`. */
- if (p == NULL) {
- ctrls[n].print(m);
- pall = 0;
- goto next;
- }
- valstr = p;
- /* Input: `dev.ctrl=val`. */
- ctrls[n].mod(m, valstr);
-next:
- free(p);
- argc--;
- argv++;
- }
-
- if (pall)
- printall(m, oflag);
- (void)mixer_close(m);
-
- return (0);
+ printf("%s.%s=%d\n",
+ m->dev->name, ctls[MCTL_SRC].name, m->dev->f_rec);
}