commit 2a4476d554b6cf244c3c5019968640bea28e94ee
parent 08cd797e4e6cc44c08c1b83ab41063814ac9f537
Author: Christos Margiolis <christos@margiolis.net>
Date: Sat, 10 Jul 2021 13:37:02 +0300
kernel: allow volume to be changed while muted
Diffstat:
1 file changed, 35 insertions(+), 10 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..d85dff6eee7 100644
+index 92c5f3d613e..55f69c4b242 100644
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -58,9 +58,11 @@ struct snd_mixer {
@@ -32,7 +32,21 @@ index 92c5f3d613e..d85dff6eee7 100644
/* 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)
+@@ -272,6 +274,13 @@ mixer_set(struct snd_mixer *m, u_int dev, u_int lev)
+
+ MIXER_SET_UNLOCK(m, dropmtx);
+
++ /* Allow the volume to be "changed" while muted. */
++ if (m->mutedevs & (1 << dev)) {
++ m->level_muted[dev] = l | (r << 8);
++ MIXER_SET_LOCK(m, dropmtx);
++ return (0);
++ }
++
+ /* TODO: recursive handling */
+ parent = m->parent[dev];
+ if (parent >= SOUND_MIXER_NRDEVICES)
+@@ -287,7 +296,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);
@@ -41,7 +55,7 @@ index 92c5f3d613e..d85dff6eee7 100644
}
} 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)
+@@ -305,8 +314,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) {
@@ -52,7 +66,7 @@ index 92c5f3d613e..d85dff6eee7 100644
}
} 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)
+@@ -317,7 +326,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);
@@ -61,7 +75,7 @@ index 92c5f3d613e..d85dff6eee7 100644
}
}
-@@ -326,16 +328,55 @@ mixer_set(struct snd_mixer *m, u_int dev, u_int lev)
+@@ -326,16 +335,66 @@ mixer_set(struct snd_mixer *m, u_int dev, u_int lev)
m->level[dev] = l | (r << 8);
m->modify_counter++;
@@ -110,6 +124,17 @@ index 92c5f3d613e..d85dff6eee7 100644
+ mixer->level_muted[i] = mixer->level[i];
+ v = 0;
+ } else if (!(mutedevs & (1 << i)) && mixer->level[i] == 0) {
++ /*
++ * `mixer_set` checks if the device is muted and, if
++ * yes, assigns the volume to `level_muted` and returns.
++ * In case of an unmute, we'll first UNSET the mute bit
++ * so that we bypass this check.
++ *
++ * This is probably a dirty hack, but assigning the
++ * flags before the loop would cause the same effect,
++ * this time when muting.
++ */
++ mixer->mutedevs &= ~(1 << i);
+ v = mixer->level_muted[i];
+ } else
+ continue;
@@ -121,7 +146,7 @@ index 92c5f3d613e..d85dff6eee7 100644
}
static int
-@@ -598,6 +639,12 @@ mix_getdevs(struct snd_mixer *m)
+@@ -598,6 +657,12 @@ mix_getdevs(struct snd_mixer *m)
return m->devs;
}
@@ -134,7 +159,7 @@ index 92c5f3d613e..d85dff6eee7 100644
u_int32_t
mix_getrecdevs(struct snd_mixer *m)
{
-@@ -711,6 +758,7 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
+@@ -711,6 +776,7 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
if (m == NULL)
return (-1);
@@ -142,7 +167,7 @@ index 92c5f3d613e..d85dff6eee7 100644
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
v = snd_mixerdefaults[i];
-@@ -722,6 +770,11 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
+@@ -722,6 +788,11 @@ mixer_init(device_t dev, kobj_class_t cls, void *devinfo)
}
mixer_set(m, i, v | (v << 8));
@@ -154,7 +179,7 @@ index 92c5f3d613e..d85dff6eee7 100644
}
mixer_setrecsrc(m, 0); /* Set default input. */
-@@ -1305,10 +1358,16 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
+@@ -1305,10 +1376,16 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
goto done;
}
if ((cmd & ~0xff) == MIXER_WRITE(0)) {
@@ -173,7 +198,7 @@ index 92c5f3d613e..d85dff6eee7 100644
snd_mtxunlock(m->lock);
return ((ret == 0) ? 0 : ENXIO);
}
-@@ -1319,6 +1378,9 @@ mixer_ioctl_cmd(struct cdev *i_dev, u_long cmd, caddr_t arg, int mode,
+@@ -1319,6 +1396,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;