commit 08cd797e4e6cc44c08c1b83ab41063814ac9f537
parent e8100ba095b92ad290f80f059e9a494a429fe372
Author: Christos Margiolis <christos@margiolis.net>
Date: Thu, 8 Jul 2021 22:39:52 +0300
kernel: return appropriate volume when muted. lib/prog: removed all device flags
Diffstat:
4 files changed, 148 insertions(+), 125 deletions(-)
diff --git a/diff/mixer_kern.diff b/diff/mixer_kern.diff
@@ -1,5 +1,5 @@
diff --git a/sys/dev/sound/pcm/mixer.c b/sys/dev/sound/pcm/mixer.c
-index 92c5f3d613e..a15b59eb47f 100644
+index 92c5f3d613e..d85dff6eee7 100644
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -58,9 +58,11 @@ struct snd_mixer {
@@ -14,10 +14,77 @@ index 92c5f3d613e..a15b59eb47f 100644
u_int8_t parent[32];
u_int32_t child[32];
u_int8_t realdev[32];
-@@ -338,6 +340,40 @@ mixer_get(struct snd_mixer *mixer, int dev)
- return -1;
+@@ -254,7 +256,7 @@ mixer_set(struct snd_mixer *m, u_int dev, u_int lev)
+
+ if (m == NULL || dev >= SOUND_MIXER_NRDEVICES ||
+ (0 == (m->devs & (1 << dev))))
+- return -1;
++ return (-1);
+
+ l = min((lev & 0x00ff), 100);
+ r = min(((lev & 0xff00) >> 8), 100);
+@@ -262,7 +264,7 @@ mixer_set(struct snd_mixer *m, u_int dev, u_int lev)
+
+ d = device_get_softc(m->dev);
+ if (d == NULL)
+- return -1;
++ return (-1);
+
+ /* It is safe to drop this mutex due to Giant. */
+ if (!(d->flags & SD_F_MPSAFE) && mtx_owned(m->lock) != 0)
+@@ -287,7 +289,7 @@ mixer_set(struct snd_mixer *m, u_int dev, u_int lev)
+ else if (realdev != SOUND_MIXER_NONE &&
+ MIXER_SET(m, realdev, tl, tr) < 0) {
+ MIXER_SET_LOCK(m, dropmtx);
+- return -1;
++ return (-1);
+ }
+ } else if (child != 0) {
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
+@@ -305,8 +307,8 @@ mixer_set(struct snd_mixer *m, u_int dev, u_int lev)
+ realdev = m->realdev[dev];
+ if (realdev != SOUND_MIXER_NONE &&
+ MIXER_SET(m, realdev, l, r) < 0) {
+- MIXER_SET_LOCK(m, dropmtx);
+- return -1;
++ MIXER_SET_LOCK(m, dropmtx);
++ return (-1);
+ }
+ } else {
+ if (dev == SOUND_MIXER_PCM && (d->flags & SD_F_SOFTPCMVOL))
+@@ -317,7 +319,7 @@ mixer_set(struct snd_mixer *m, u_int dev, u_int lev)
+ else if (realdev != SOUND_MIXER_NONE &&
+ MIXER_SET(m, realdev, l, r) < 0) {
+ MIXER_SET_LOCK(m, dropmtx);
+- return -1;
++ return (-1);
+ }
+ }
+
+@@ -326,16 +328,55 @@ mixer_set(struct snd_mixer *m, u_int dev, u_int lev)
+ m->level[dev] = l | (r << 8);
+ m->modify_counter++;
+
+- return 0;
++ return (0);
}
+ static int
+ mixer_get(struct snd_mixer *mixer, int dev)
+ {
+- if ((dev < SOUND_MIXER_NRDEVICES) && (mixer->devs & (1 << dev)))
+- return mixer->level[dev];
++ if ((dev < SOUND_MIXER_NRDEVICES) && (mixer->devs & (1 << dev))) {
++ if (mixer->mutedevs & (1 << dev))
++ return (mixer->level_muted[dev]);
++ else
++ return (mixer->level[dev]);
++ }
+ else
+- return -1;
++ return (-1);
++}
++
+static int
+mixer_setmute(struct snd_mixer *mixer, u_int32_t mutedevs)
+{
@@ -34,28 +101,27 @@ index 92c5f3d613e..a15b59eb47f 100644
+
+ /* FIXME: lock/unlock */
+
-+ mutedevs &= mixer->devs; /* Filter out invalid values. */
++ /* Filter out invalid values. */
++ mutedevs &= mixer->devs;
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
+ if (!(mixer->devs & (1 << i)))
+ continue;
+ if ((mutedevs & (1 << i)) && mixer->level[i] != 0) {
+ mixer->level_muted[i] = mixer->level[i];
+ v = 0;
-+ } else if (!(mutedevs & (1 << i)) && mixer->level[i] == 0)
++ } else if (!(mutedevs & (1 << i)) && mixer->level[i] == 0) {
+ v = mixer->level_muted[i];
-+ else
++ } else
+ continue;
+ ret += mixer_set(mixer, i, v);
+ }
+ mixer->mutedevs = mutedevs;
+
+ return (ret);
-+}
-+
+ }
+
static int
- mixer_setrecsrc(struct snd_mixer *mixer, u_int32_t src)
- {
-@@ -598,6 +634,12 @@ mix_getdevs(struct snd_mixer *m)
+@@ -598,6 +639,12 @@ mix_getdevs(struct snd_mixer *m)
return m->devs;
}
@@ -68,7 +134,7 @@ index 92c5f3d613e..a15b59eb47f 100644
u_int32_t
mix_getrecdevs(struct snd_mixer *m)
{
-@@ -711,6 +753,7 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
+@@ -711,6 +758,7 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
if (m == NULL)
return (-1);
@@ -76,7 +142,7 @@ index 92c5f3d613e..a15b59eb47f 100644
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
v = snd_mixerdefaults[i];
-@@ -722,6 +765,11 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
+@@ -722,6 +770,11 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
}
mixer_set(m, i, v | (v << 8));
@@ -88,7 +154,7 @@ index 92c5f3d613e..a15b59eb47f 100644
}
mixer_setrecsrc(m, 0); /* Set default input. */
-@@ -1305,10 +1353,16 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
+@@ -1305,10 +1358,16 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
goto done;
}
if ((cmd & ~0xff) == MIXER_WRITE(0)) {
@@ -107,7 +173,7 @@ index 92c5f3d613e..a15b59eb47f 100644
snd_mtxunlock(m->lock);
return ((ret == 0) ? 0 : ENXIO);
}
-@@ -1319,6 +1373,9 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
+@@ -1319,6 +1378,9 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
case SOUND_MIXER_STEREODEVS:
v = mix_getdevs(m);
break;
@@ -118,14 +184,14 @@ index 92c5f3d613e..a15b59eb47f 100644
v = mix_getrecdevs(m);
break;
diff --git a/sys/dev/sound/pcm/mixer.h b/sys/dev/sound/pcm/mixer.h
-index 8e11d553a3e..6d7d861e8a6 100644
+index 8e11d553a3e..626282c803e 100644
--- a/sys/dev/sound/pcm/mixer.h
+++ b/sys/dev/sound/pcm/mixer.h
@@ -60,8 +60,10 @@ device_t mix_get_dev(struct snd_mixer *m);
void mix_setdevs(struct snd_mixer *m, u_int32_t v);
void mix_setrecdevs(struct snd_mixer *m, u_int32_t v);
-+// XXX: int mix_setmutedevs(struct snd_mixer *m, u_int32_t mutedevs);
++//void mix_setmutedevs(struct snd_mixer *m, u_int32_t mutedevs);
u_int32_t mix_getdevs(struct snd_mixer *m);
u_int32_t mix_getrecdevs(struct snd_mixer *m);
+u_int32_t mix_getmutedevs(struct snd_mixer *m);
diff --git a/mixer_lib/mixer.c b/mixer_lib/mixer.c
@@ -34,7 +34,6 @@
#include "mixer.h"
#define BASEPATH "/dev/mixer"
-#define MIN(x, y) ((x) < (y) ? (x) : (y))
static int _mixer_readvol(struct mixer *, struct mix_dev *);
@@ -48,10 +47,8 @@ _mixer_readvol(struct mixer *m, struct mix_dev *dev)
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);
+ dev->vol.left = M_VOLNORM(v & 0x00ff);
+ dev->vol.right = M_VOLNORM((v >> 8) & 0x00ff);
return (0);
}
@@ -117,9 +114,6 @@ dunit:
dp->devno = i;
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;
(void)strlcpy(dp->name, names[i], sizeof(dp->name));
TAILQ_INSERT_TAIL(&m->devs, dp, devs);
ndev++;
@@ -210,15 +204,16 @@ mixer_getdevbyname(struct mixer *m, const char *name)
* be handlded by the caller.
*/
int
-mixer_setvol(struct mixer *m, float l, float r)
+mixer_setvol(struct mixer *m, mix_volume_t vol)
{
int v;
- if (l < M_VOLMIN || l > M_VOLMAX || r < M_VOLMIN || r > M_VOLMAX) {
+ if (vol.left < M_VOLMIN || vol.left > M_VOLMAX ||
+ vol.right < M_VOLMIN || vol.right > M_VOLMAX) {
errno = ERANGE;
return (-1);
}
- v = M_VOLDENORM(l) | M_VOLDENORM(r) << 8;
+ v = M_VOLDENORM(vol.left) | M_VOLDENORM(vol.right) << 8;
if (ioctl(m->fd, MIXER_WRITE(m->dev->devno), &v) < 0)
return (-1);
if (_mixer_readvol(m, m->dev) < 0)
@@ -227,27 +222,6 @@ mixer_setvol(struct mixer *m, float l, float r)
return (0);
}
-/*
- * TODO: Change panning.
- *
- * @param: `pan`: Panning value. It has to be in the range
- * `M_PANMIN <= pan <= M_PANMAX`.
- */
-int
-mixer_setpan(struct mixer *m, float pan)
-{
- int l, r;
-
- if (pan < M_PANMIN || pan > M_PANMAX) {
- errno = ERANGE;
- return (-1);
- }
- l = m->dev->lvol;
- r = m->dev->rvol;
-
- return (mixer_setvol(m, l, r));
-}
-
int
mixer_setmute(struct mixer *m, int opt)
{
@@ -269,8 +243,6 @@ mixer_setmute(struct mixer *m, int opt)
return (-1);
if (ioctl(m->fd, SOUND_MIXER_READ_MUTE, &m->mutemask) < 0)
return (-1);
- if (_mixer_readvol(m, m->dev) < 0)
- return (-1);
return 0;
}
@@ -307,7 +279,6 @@ mixer_modrecsrc(struct mixer *m, int opt)
return (-1);
if (ioctl(m->fd, SOUND_MIXER_READ_RECSRC, &m->recsrc) < 0)
return (-1);
- m->dev->f_src = M_ISRECSRC(m, m->dev->devno);
return (0);
}
diff --git a/mixer_lib/mixer.h b/mixer_lib/mixer.h
@@ -48,31 +48,19 @@ __FBSDID("$FreeBSD$");
#define M_VOLNORM(v) ((v) / 100.0f)
#define M_VOLDENORM(v) ((int)roundf((v) * 100.0f))
-#define M_PANMIN (-1.0f)
-#define M_PANMAX 1.0f
-
-#define M_ISSET(n, f) ((1 << (n)) & (f))
+#define M_ISSET(n, f) (((1 << (n)) & (f)) ? 1 : 0)
#define M_ISDEV(m, n) M_ISSET(n, (m)->devmask)
#define M_ISMUTE(m, n) M_ISSET(n, (m)->mutemask)
#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;
- int f_mut;
- int f_pbk;
- int f_rec;
- int f_src;
- float lvol;
- float rvol;
- float pan;
+ struct mix_volume {
+ float left;
+ float right;
+ } vol;
TAILQ_ENTRY(mix_dev) devs;
};
@@ -91,14 +79,13 @@ struct mixer {
int f_default;
};
-/* XXX: move control handling here? */
+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 *, float, float);
-int mixer_setpan(struct mixer *, float);
+int mixer_setvol(struct mixer *, mix_volume_t);
int mixer_setmute(struct mixer *, int);
int mixer_modrecsrc(struct mixer *, int);
int mixer_getdunit(void);
diff --git a/mixer_prog/mixer_prog.c b/mixer_prog/mixer_prog.c
@@ -46,7 +46,7 @@ struct mix_ctl {
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 printdev(struct mixer *, struct mix_dev *, int);
static void printrecsrc(struct mixer *, int);
static int findctl(const char *);
/* Control handlers */
@@ -157,7 +157,7 @@ parse:
}
/* Input: `dev`. */
if (p == NULL) {
- printdev(m->dev, 1);
+ printdev(m, m->dev, 1);
pall = 0;
goto next;
}
@@ -204,7 +204,7 @@ printall(struct mixer *m, int oflag)
printminfo(m, oflag);
TAILQ_FOREACH(dp, &m->devs, devs) {
- printdev(dp, oflag);
+ printdev(m, dp, oflag);
}
}
@@ -220,26 +220,31 @@ printminfo(struct mixer *m, int oflag)
}
static void
-printdev(struct mix_dev *d, int oflag)
+printdev(struct mixer *m, struct mix_dev *d, int oflag)
{
+ float pan;
+
+ pan = d->vol.right - d->vol.left;
if (!oflag) {
printf(" %-11s= %.2f:%.2f\t%+.2f\t",
- d->name, d->lvol, d->rvol, d->pan);
- if (d->f_pbk)
- printf(" pbk");
- if (d->f_rec)
- printf(" rec");
- if (d->f_src)
+ d->name, d->vol.left, d->vol.right, pan);
+ if (!M_ISREC(m, d->devno))
+ printf(" pbk");
+ if (M_ISREC(m, d->devno))
+ printf(" rec");
+ if (M_ISRECSRC(m, d->devno))
printf(" src");
- if (d->f_mut)
+ if (M_ISMUTE(m, d->devno))
printf(" mute");
printf("\n");
} else {
printf("%s.%s=%.2f:%.2f\n",
- d->name, ctls[MCTL_VOL].name, d->lvol, d->rvol);
- if (d->f_src)
+ d->name, ctls[MCTL_VOL].name, d->vol.left, d->vol.right);
+ printf("%s.%s=%d\n",
+ d->name, ctls[MCTL_MUT].name, M_ISMUTE(m, d->devno));
+ printf("%s.%s=%.2f\n", d->name, ctls[MCTL_PAN].name, pan);
+ if (M_ISRECSRC(m, d->devno))
printf("%s.%s=+\n", d->name, ctls[MCTL_SRC].name);
- /* TODO: add f_mut */
}
}
@@ -279,8 +284,9 @@ findctl(const char *ctl)
static void
mod_volume(struct mixer *m, const char *val)
{
+ mix_volume_t v;
char lstr[8], rstr[8];
- float l, r, lprev, rprev, lrel, rrel;
+ float lprev, rprev, lrel, rrel;
int n;
n = sscanf(val, "%7[^:]:%7s", lstr, rstr);
@@ -292,55 +298,47 @@ mod_volume(struct mixer *m, const char *val)
if (n > 0) {
if (*lstr == '+' || *lstr == '-')
lrel = rrel = 1;
- l = strtof(lstr, NULL);
+ v.left = strtof(lstr, NULL);
}
if (n > 1) {
if (*rstr == '+' || *rstr == '-')
rrel = 1;
- r = strtof(rstr, NULL);
+ v.right = strtof(rstr, NULL);
}
switch (n) {
case 1:
- r = l; /* FALLTHROUGH */
+ v.right = v.left; /* FALLTHROUGH */
case 2:
if (lrel)
- l += m->dev->lvol;
+ v.left += m->dev->vol.left;
if (rrel)
- r += m->dev->rvol;
-
- if (l < M_VOLMIN)
- l = M_VOLMIN;
- else if (l > M_VOLMAX)
- l = M_VOLMAX;
- if (r < M_VOLMIN)
- r = M_VOLMIN;
- else if (r > M_VOLMAX)
- r = M_VOLMAX;
-
- lprev = m->dev->lvol;
- rprev = m->dev->rvol;
- if (mixer_setvol(m, l, r) < 0)
+ v.right += m->dev->vol.right;
+
+ if (v.left < M_VOLMIN)
+ v.left = M_VOLMIN;
+ else if (v.left > M_VOLMAX)
+ v.left = M_VOLMAX;
+ if (v.right < M_VOLMIN)
+ v.right = M_VOLMIN;
+ else if (v.right > M_VOLMAX)
+ v.right = M_VOLMAX;
+
+ lprev = m->dev->vol.left;
+ rprev = m->dev->vol.right;
+ if (mixer_setvol(m, v) < 0)
warn("%s.%s=%.2f:%.2f",
- m->dev->name, ctls[MCTL_VOL].name, l, r);
+ m->dev->name, ctls[MCTL_VOL].name, v.left, v.right);
else
printf("%s.%s: %.2f:%.2f -> %.2f:%.2f\n",
m->dev->name, ctls[MCTL_VOL].name,
- lprev, rprev, l, r);
+ lprev, rprev, v.left, v.right);
}
}
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);
+ /* XXX: */
}
static void
@@ -362,12 +360,12 @@ mod_mute(struct mixer *m, const char *val)
warnx("%c: no such modifier", *val);
return;
}
- n = m->dev->f_mut;
+ n = M_ISMUTE(m, m->dev->devno);
if (mixer_setmute(m, opt) < 0)
warn("%s.%s=%c", m->dev->name, ctls[MCTL_MUT].name, *val);
else
printf("%s.%s: %d -> %d\n",
- m->dev->name, ctls[MCTL_MUT].name, n, m->dev->f_mut);
+ m->dev->name, ctls[MCTL_MUT].name, n, M_ISMUTE(m, m->dev->devno));
}
static void
@@ -392,37 +390,38 @@ mod_recsrc(struct mixer *m, const char *val)
warnx("%c: no such modifier", *val);
return;
}
- n = m->dev->f_src;
+ n = M_ISRECSRC(m, m->dev->devno);
if (mixer_modrecsrc(m, opt) < 0)
warn("%s.%s=%c", m->dev->name, ctls[MCTL_SRC].name, *val);
else
printf("%s.%s: %d -> %d\n",
- m->dev->name, ctls[MCTL_SRC].name, n, m->dev->f_src);
+ m->dev->name, ctls[MCTL_SRC].name,
+ n, M_ISRECSRC(m, m->dev->devno));
}
static void
print_volume(struct mixer *m)
{
printf("%s.%s=%.2f:%.2f\n",
- m->dev->name, ctls[MCTL_VOL].name, m->dev->lvol, m->dev->rvol);
+ m->dev->name, ctls[MCTL_VOL].name, m->dev->vol.left, m->dev->vol.right);
}
static void
print_panning(struct mixer *m)
{
- printf("%s.%s=%.2f\n",
- m->dev->name, ctls[MCTL_PAN].name, m->dev->pan);
+ /* XXX: */
}
static void
print_mute(struct mixer *m)
{
- printf("%s.%s=%d\n", m->dev->name, ctls[MCTL_MUT].name, m->dev->f_mut);
+ printf("%s.%s=%d\n", m->dev->name, ctls[MCTL_MUT].name,
+ M_ISMUTE(m, m->dev->devno));
}
static void
print_recsrc(struct mixer *m)
{
printf("%s.%s=%d\n",
- m->dev->name, ctls[MCTL_SRC].name, m->dev->f_rec);
+ m->dev->name, ctls[MCTL_SRC].name, M_ISRECSRC(m, m->dev->devno));
}