aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSean Farley <scf@FreeBSD.org>2026-03-12 18:22:02 +0000
committerChristos Margiolis <christos@FreeBSD.org>2026-03-19 12:17:35 +0000
commitbd5ce67416b56d895c2e1a7f0497163c3814e982 (patch)
treec6052dd189e0a54df0400a5b18d3c7dcc63253a1
parent660a79ef4f1112c90690b56c6e5ac7532428ec8c (diff)
sound: enforce MASTER volume mute during playback
MASTER mute (vol.mute) works while audio is playing. However, if a stream is stopped and restarted (PCMTRIG_STOP -> PCMTRIG_START), the audio will resume even though the mixer shows the MASTER volume as muted. Other streams that are already playing remain silent. New streams may also start playing audio regardless of the MASTER mute state. The volume feeder now considers the MASTER mute when determining whether a channel should be muted. This ensures MASTER mute is consistently enforced for all streams and removes the dependency on trigger-driven state propagation. Tested with Creative Labs CA0132 card. MFC after: 1 week Reviewed by: christos Differential Revision: https://reviews.freebsd.org/D55605 (cherry picked from commit ac5ff2813027c385f9037b47b2b164d4c1bebd09)
-rw-r--r--sys/dev/sound/pcm/feeder_volume.c11
1 files changed, 10 insertions, 1 deletions
diff --git a/sys/dev/sound/pcm/feeder_volume.c b/sys/dev/sound/pcm/feeder_volume.c
index fc4ed1bbb0a5..e43b2594c7e0 100644
--- a/sys/dev/sound/pcm/feeder_volume.c
+++ b/sys/dev/sound/pcm/feeder_volume.c
@@ -242,11 +242,14 @@ feed_volume_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
{
int temp_vol[SND_CHN_T_VOL_MAX];
struct feed_volume_info *info;
+ struct snd_mixer *m;
+ struct snddev_info *d;
uint32_t j, align;
int i, *matrix;
uint8_t *dst;
const int16_t *vol;
const int8_t *muted;
+ bool master_muted = false;
/*
* Fetch filter data operation.
@@ -278,8 +281,14 @@ feed_volume_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
return (FEEDER_FEED(f->source, c, b, count, source));
/* Check if any controls are muted. */
+ d = (c != NULL) ? c->parentsnddev : NULL;
+ m = (d != NULL && d->mixer_dev != NULL) ? d->mixer_dev->si_drv1 : NULL;
+
+ if (m != NULL)
+ master_muted = (mix_getmutedevs(m) & (1 << SND_VOL_C_MASTER));
+
for (j = 0; j != SND_CHN_T_VOL_MAX; j++)
- temp_vol[j] = muted[j] ? 0 : vol[j];
+ temp_vol[j] = (muted[j] || master_muted) ? 0 : vol[j];
dst = b;
align = info->bps * info->channels;