Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F107117557
D32499.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
18 KB
Referenced Files
None
Subscribers
None
D32499.diff
View Options
diff --git a/sys/dev/sound/pcm/channel.h b/sys/dev/sound/pcm/channel.h
--- a/sys/dev/sound/pcm/channel.h
+++ b/sys/dev/sound/pcm/channel.h
@@ -166,7 +166,8 @@
struct pcmchan_matrix matrix;
struct pcmchan_matrix matrix_scratch;
- int volume[SND_VOL_C_MAX][SND_CHN_T_VOL_MAX];
+ int16_t volume[SND_VOL_C_MAX][SND_CHN_T_VOL_MAX];
+ int8_t muted[SND_VOL_C_MAX][SND_CHN_T_VOL_MAX];
void *data1, *data2;
};
@@ -271,6 +272,9 @@
int center);
int chn_setvolume_matrix(struct pcm_channel *c, int vc, int vt, int val);
int chn_getvolume_matrix(struct pcm_channel *c, int vc, int vt);
+int chn_setmute_multi(struct pcm_channel *c, int vc, int mute);
+int chn_setmute_matrix(struct pcm_channel *c, int vc, int vt, int mute);
+int chn_getmute_matrix(struct pcm_channel *c, int vc, int vt);
void chn_vpc_reset(struct pcm_channel *c, int vc, int force);
int chn_setparam(struct pcm_channel *c, uint32_t format, uint32_t speed);
int chn_setspeed(struct pcm_channel *c, uint32_t speed);
@@ -307,6 +311,8 @@
#define CHN_GETVOLUME(x, y, z) ((x)->volume[y][z])
#endif
+#define CHN_GETMUTE(x, y, z) ((x)->muted[y][z])
+
#ifdef OSSV4_EXPERIMENT
int chn_getpeaks(struct pcm_channel *c, int *lpeak, int *rpeak);
#endif
diff --git a/sys/dev/sound/pcm/channel.c b/sys/dev/sound/pcm/channel.c
--- a/sys/dev/sound/pcm/channel.c
+++ b/sys/dev/sound/pcm/channel.c
@@ -1223,6 +1223,8 @@
c->volume[SND_VOL_C_MASTER][SND_CHN_T_VOL_0DB] = SND_VOL_0DB_MASTER;
c->volume[SND_VOL_C_PCM][SND_CHN_T_VOL_0DB] = chn_vol_0db_pcm;
+ memset(c->muted, 0, sizeof(c->muted));
+
chn_vpc_reset(c, SND_VOL_C_PCM, 1);
ret = ENODEV;
@@ -1394,6 +1396,75 @@
return (c->volume[vc][vt]);
}
+int
+chn_setmute_multi(struct pcm_channel *c, int vc, int mute)
+{
+ int i, ret;
+
+ ret = 0;
+
+ for (i = 0; i < SND_CHN_T_MAX; i++) {
+ if ((1 << i) & SND_CHN_LEFT_MASK)
+ ret |= chn_setmute_matrix(c, vc, i, mute);
+ else if ((1 << i) & SND_CHN_RIGHT_MASK)
+ ret |= chn_setmute_matrix(c, vc, i, mute) << 8;
+ else
+ ret |= chn_setmute_matrix(c, vc, i, mute) << 16;
+ }
+ return (ret);
+}
+
+int
+chn_setmute_matrix(struct pcm_channel *c, int vc, int vt, int mute)
+{
+ int i;
+
+ KASSERT(c != NULL && vc >= SND_VOL_C_MASTER && vc < SND_VOL_C_MAX &&
+ (vc == SND_VOL_C_MASTER || (vc & 1)) &&
+ (vt == SND_CHN_T_VOL_0DB || (vt >= SND_CHN_T_BEGIN && vt <= SND_CHN_T_END)),
+ ("%s(): invalid mute matrix c=%p vc=%d vt=%d mute=%d",
+ __func__, c, vc, vt, mute));
+
+ CHN_LOCKASSERT(c);
+
+ mute = (mute != 0);
+
+ c->muted[vc][vt] = mute;
+
+ /*
+ * Do relative calculation here and store it into class + 1
+ * to ease the job of feeder_volume.
+ */
+ if (vc == SND_VOL_C_MASTER) {
+ for (vc = SND_VOL_C_BEGIN; vc <= SND_VOL_C_END;
+ vc += SND_VOL_C_STEP)
+ c->muted[SND_VOL_C_VAL(vc)][vt] = mute;
+ } else if (vc & 1) {
+ if (vt == SND_CHN_T_VOL_0DB) {
+ for (i = SND_CHN_T_BEGIN; i <= SND_CHN_T_END;
+ i += SND_CHN_T_STEP) {
+ c->muted[SND_VOL_C_VAL(vc)][i] = mute;
+ }
+ } else {
+ c->muted[SND_VOL_C_VAL(vc)][vt] = mute;
+ }
+ }
+ return (mute);
+}
+
+int
+chn_getmute_matrix(struct pcm_channel *c, int vc, int vt)
+{
+ KASSERT(c != NULL && vc >= SND_VOL_C_MASTER && vc < SND_VOL_C_MAX &&
+ (vt == SND_CHN_T_VOL_0DB ||
+ (vt >= SND_CHN_T_BEGIN && vt <= SND_CHN_T_END)),
+ ("%s(): invalid mute matrix c=%p vc=%d vt=%d",
+ __func__, c, vc, vt));
+ CHN_LOCKASSERT(c);
+
+ return (c->muted[vc][vt]);
+}
+
struct pcmchan_matrix *
chn_getmatrix(struct pcm_channel *c)
{
diff --git a/sys/dev/sound/pcm/dsp.c b/sys/dev/sound/pcm/dsp.c
--- a/sys/dev/sound/pcm/dsp.c
+++ b/sys/dev/sound/pcm/dsp.c
@@ -965,6 +965,7 @@
struct snddev_info *d;
struct pcm_channel *rdch, *wrch;
int j, devtype, ret;
+ int left, right, center, mute;
d = dsp_get_info(dev);
if (!PCM_REGISTERED(d) || !(dsp_get_flags(dev) & SD_F_VPC))
@@ -1003,67 +1004,95 @@
}
/* Final validation */
- if (volch != NULL) {
- CHN_LOCK(volch);
- if (!(volch->feederflags & (1 << FEEDER_VOLUME))) {
- CHN_UNLOCK(volch);
- return (-1);
- }
- if (volch->direction == PCMDIR_PLAY)
- wrch = volch;
- else
- rdch = volch;
- }
-
- ret = EINVAL;
+ if (volch == NULL)
+ return (EINVAL);
- if (volch != NULL &&
- ((j == SOUND_MIXER_PCM && volch->direction == PCMDIR_PLAY) ||
- (j == SOUND_MIXER_RECLEV && volch->direction == PCMDIR_REC))) {
- if ((cmd & ~0xff) == MIXER_WRITE(0)) {
- int left, right, center;
+ CHN_LOCK(volch);
+ if (!(volch->feederflags & (1 << FEEDER_VOLUME))) {
+ CHN_UNLOCK(volch);
+ return (EINVAL);
+ }
+ switch (cmd & ~0xff) {
+ case MIXER_WRITE(0):
+ switch (j) {
+ case SOUND_MIXER_MUTE:
+ if (volch->direction == PCMDIR_REC) {
+ chn_setmute_multi(volch, SND_VOL_C_PCM, (*(int *)arg & SOUND_MASK_RECLEV) != 0);
+ } else {
+ chn_setmute_multi(volch, SND_VOL_C_PCM, (*(int *)arg & SOUND_MASK_PCM) != 0);
+ }
+ break;
+ case SOUND_MIXER_PCM:
+ if (volch->direction != PCMDIR_PLAY)
+ break;
left = *(int *)arg & 0x7f;
right = ((*(int *)arg) >> 8) & 0x7f;
center = (left + right) >> 1;
- chn_setvolume_multi(volch, SND_VOL_C_PCM, left, right,
- center);
- } else if ((cmd & ~0xff) == MIXER_READ(0)) {
- *(int *)arg = CHN_GETVOLUME(volch,
- SND_VOL_C_PCM, SND_CHN_T_FL);
- *(int *)arg |= CHN_GETVOLUME(volch,
- SND_VOL_C_PCM, SND_CHN_T_FR) << 8;
+ chn_setvolume_multi(volch, SND_VOL_C_PCM,
+ left, right, center);
+ break;
+ case SOUND_MIXER_RECLEV:
+ if (volch->direction != PCMDIR_REC)
+ break;
+ left = *(int *)arg & 0x7f;
+ right = ((*(int *)arg) >> 8) & 0x7f;
+ center = (left + right) >> 1;
+ chn_setvolume_multi(volch, SND_VOL_C_PCM,
+ left, right, center);
+ break;
+ default:
+ /* ignore all other mixer writes */
+ break;
}
- ret = 0;
- } else if (rdch != NULL || wrch != NULL) {
+ break;
+
+ case MIXER_READ(0):
switch (j) {
+ case SOUND_MIXER_MUTE:
+ mute = CHN_GETMUTE(volch, SND_VOL_C_PCM, SND_CHN_T_FL) ||
+ CHN_GETMUTE(volch, SND_VOL_C_PCM, SND_CHN_T_FR);
+ if (volch->direction == PCMDIR_REC) {
+ *(int *)arg = mute << SOUND_MIXER_RECLEV;
+ } else {
+ *(int *)arg = mute << SOUND_MIXER_PCM;
+ }
+ break;
+ case SOUND_MIXER_PCM:
+ if (volch->direction != PCMDIR_PLAY)
+ break;
+ *(int *)arg = CHN_GETVOLUME(volch,
+ SND_VOL_C_PCM, SND_CHN_T_FL);
+ *(int *)arg |= CHN_GETVOLUME(volch,
+ SND_VOL_C_PCM, SND_CHN_T_FR) << 8;
+ break;
+ case SOUND_MIXER_RECLEV:
+ if (volch->direction != PCMDIR_REC)
+ break;
+ *(int *)arg = CHN_GETVOLUME(volch,
+ SND_VOL_C_PCM, SND_CHN_T_FL);
+ *(int *)arg |= CHN_GETVOLUME(volch,
+ SND_VOL_C_PCM, SND_CHN_T_FR) << 8;
+ break;
case SOUND_MIXER_DEVMASK:
case SOUND_MIXER_CAPS:
case SOUND_MIXER_STEREODEVS:
- if ((cmd & ~0xff) == MIXER_READ(0)) {
- *(int *)arg = 0;
- if (rdch != NULL)
- *(int *)arg |= SOUND_MASK_RECLEV;
- if (wrch != NULL)
- *(int *)arg |= SOUND_MASK_PCM;
- }
- ret = 0;
- break;
- case SOUND_MIXER_RECMASK:
- case SOUND_MIXER_RECSRC:
- if ((cmd & ~0xff) == MIXER_READ(0))
- *(int *)arg = 0;
- ret = 0;
+ if (volch->direction == PCMDIR_REC)
+ *(int *)arg = SOUND_MASK_RECLEV;
+ else
+ *(int *)arg = SOUND_MASK_PCM;
break;
default:
+ *(int *)arg = 0;
break;
}
- }
-
- if (volch != NULL)
- CHN_UNLOCK(volch);
+ break;
- return (ret);
+ default:
+ break;
+ }
+ CHN_UNLOCK(volch);
+ return (0);
}
static int
@@ -2294,8 +2323,7 @@
size_t len;
len = strlen(namep);
-
- if (bcmp(name, namep, len) != 0)
+ if (strncmp(name, namep, len) != 0)
return (ENODEV);
name += len;
diff --git a/sys/dev/sound/pcm/feeder_volume.c b/sys/dev/sound/pcm/feeder_volume.c
--- a/sys/dev/sound/pcm/feeder_volume.c
+++ b/sys/dev/sound/pcm/feeder_volume.c
@@ -237,10 +237,13 @@
feed_volume_feed(struct pcm_feeder *f, struct pcm_channel *c, uint8_t *b,
uint32_t count, void *source)
{
+ int temp_vol[SND_CHN_T_VOL_MAX];
struct feed_volume_info *info;
uint32_t j, align;
- int i, *vol, *matrix;
+ int i, *matrix;
uint8_t *dst;
+ const int16_t *vol;
+ const int8_t *muted;
/*
* Fetch filter data operation.
@@ -251,6 +254,7 @@
return (FEEDER_FEED(f->source, c, b, count, source));
vol = c->volume[SND_VOL_C_VAL(info->volume_class)];
+ muted = c->muted[SND_VOL_C_VAL(info->volume_class)];
matrix = info->matrix;
/*
@@ -258,17 +262,22 @@
*/
j = 0;
i = info->channels;
- do {
- if (vol[matrix[--i]] != SND_VOL_FLAT) {
+ while (i--) {
+ if (vol[matrix[i]] != SND_VOL_FLAT ||
+ muted[matrix[i]] != 0) {
j = 1;
break;
}
- } while (i != 0);
+ }
/* Nope, just bypass entirely. */
if (j == 0)
return (FEEDER_FEED(f->source, c, b, count, source));
+ /* Check if any controls are muted. */
+ for (j = 0; j != SND_CHN_T_VOL_MAX; j++)
+ temp_vol[j] = muted[j] ? 0 : vol[j];
+
dst = b;
align = info->bps * info->channels;
@@ -281,7 +290,7 @@
if (j == 0)
break;
- info->apply(vol, matrix, info->channels, dst, j);
+ info->apply(temp_vol, matrix, info->channels, dst, j);
j *= align;
dst += j;
diff --git a/sys/dev/sound/pcm/mixer.h b/sys/dev/sound/pcm/mixer.h
--- a/sys/dev/sound/pcm/mixer.h
+++ b/sys/dev/sound/pcm/mixer.h
@@ -60,8 +60,10 @@
void mix_setdevs(struct snd_mixer *m, u_int32_t v);
void mix_setrecdevs(struct snd_mixer *m, u_int32_t v);
+void mix_setmutedevs(struct snd_mixer *m, u_int32_t v);
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);
void mix_setparentchild(struct snd_mixer *m, u_int32_t parent, u_int32_t childs);
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/mixer.c b/sys/dev/sound/pcm/mixer.c
--- a/sys/dev/sound/pcm/mixer.c
+++ b/sys/dev/sound/pcm/mixer.c
@@ -51,16 +51,16 @@
KOBJ_FIELDS;
void *devinfo;
int busy;
- int hwvol_muted;
int hwvol_mixer;
int hwvol_step;
int type;
device_t dev;
- u_int32_t hwvol_mute_level;
u_int32_t devs;
+ u_int32_t mutedevs;
u_int32_t recdevs;
u_int32_t recsrc;
u_int16_t level[32];
+ u_int16_t level_muted[32];
u_int8_t parent[32];
u_int32_t child[32];
u_int8_t realdev[32];
@@ -244,7 +244,7 @@
}
static int
-mixer_set(struct snd_mixer *m, u_int dev, u_int lev)
+mixer_set(struct snd_mixer *m, u_int dev, u_int32_t muted, u_int lev)
{
struct snddev_info *d;
u_int l, r, tl, tr;
@@ -254,7 +254,7 @@
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 +262,7 @@
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)
@@ -270,6 +270,11 @@
else
dropmtx = 0;
+ /* Allow the volume to be "changed" while muted. */
+ if (muted & (1 << dev)) {
+ m->level_muted[dev] = l | (r << 8);
+ return (0);
+ }
MIXER_SET_UNLOCK(m, dropmtx);
/* TODO: recursive handling */
@@ -287,7 +292,7 @@
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 +310,8 @@
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 +322,7 @@
else if (realdev != SOUND_MIXER_NONE &&
MIXER_SET(m, realdev, l, r) < 0) {
MIXER_SET_LOCK(m, dropmtx);
- return -1;
+ return (-1);
}
}
@@ -326,16 +331,42 @@
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];
- else
- return -1;
+ 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);
+ }
+}
+
+void
+mix_setmutedevs(struct snd_mixer *mixer, u_int32_t mutedevs)
+{
+ u_int32_t delta;
+
+ /* Filter out invalid values. */
+ mutedevs &= mixer->devs;
+ delta = (mixer->mutedevs ^ mutedevs) & mixer->devs;
+ mixer->mutedevs = mutedevs;
+
+ for (int i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
+ if (!(delta & (1 << i)))
+ continue;
+ if (mutedevs & (1 << i)) {
+ mixer->level_muted[i] = mixer->level[i];
+ mixer_set(mixer, i, 0, 0);
+ } else {
+ mixer_set(mixer, i, 0, mixer->level_muted[i]);
+ }
+ }
}
static int
@@ -598,6 +629,12 @@
return m->devs;
}
+u_int32_t
+mix_getmutedevs(struct snd_mixer *m)
+{
+ return m->mutedevs;
+}
+
u_int32_t
mix_getrecdevs(struct snd_mixer *m)
{
@@ -721,7 +758,7 @@
}
}
- mixer_set(m, i, v | (v << 8));
+ mixer_set(m, i, 0, v | (v << 8));
}
mixer_setrecsrc(m, 0); /* Set default input. */
@@ -799,7 +836,7 @@
snd_mtxlock(m->lock);
for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- mixer_set(m, i, 0);
+ mixer_set(m, i, 0, 0);
mixer_setrecsrc(m, SOUND_MASK_MIC);
@@ -836,8 +873,12 @@
return i;
}
- for (i = 0; i < SOUND_MIXER_NRDEVICES; i++)
- mixer_set(m, i, m->level[i]);
+ for (i = 0; i < SOUND_MIXER_NRDEVICES; i++) {
+ if (m->mutedevs & (1 << i))
+ mixer_set(m, i, 0, 0);
+ else
+ mixer_set(m, i, 0, m->level[i]);
+ }
mixer_setrecsrc(m, m->recsrc);
snd_mtxunlock(m->lock);
@@ -863,10 +904,8 @@
if (dev == -1) {
snd_mtxunlock(m->lock);
return EINVAL;
- }
- else if (dev != m->hwvol_mixer) {
+ } else {
m->hwvol_mixer = dev;
- m->hwvol_muted = 0;
}
}
snd_mtxunlock(m->lock);
@@ -897,14 +936,7 @@
void
mixer_hwvol_mute_locked(struct snd_mixer *m)
{
- if (m->hwvol_muted) {
- m->hwvol_muted = 0;
- mixer_set(m, m->hwvol_mixer, m->hwvol_mute_level);
- } else {
- m->hwvol_muted++;
- m->hwvol_mute_level = mixer_get(m, m->hwvol_mixer);
- mixer_set(m, m->hwvol_mixer, 0);
- }
+ mix_setmutedevs(m, m->mutedevs ^ (1 << m->hwvol_mixer));
}
void
@@ -925,11 +957,8 @@
{
int level, left, right;
- if (m->hwvol_muted) {
- m->hwvol_muted = 0;
- level = m->hwvol_mute_level;
- } else
- level = mixer_get(m, m->hwvol_mixer);
+ level = mixer_get(m, m->hwvol_mixer);
+
if (level != -1) {
left = level & 0xff;
right = (level >> 8) & 0xff;
@@ -943,7 +972,8 @@
right = 0;
else if (right > 100)
right = 100;
- mixer_set(m, m->hwvol_mixer, left | right << 8);
+
+ mixer_set(m, m->hwvol_mixer, m->mutedevs, left | right << 8);
}
}
@@ -976,7 +1006,7 @@
KASSERT(m != NULL, ("NULL snd_mixer"));
snd_mtxlock(m->lock);
- ret = mixer_set(m, dev, left | (right << 8));
+ ret = mixer_set(m, dev, m->mutedevs, left | (right << 8));
snd_mtxunlock(m->lock);
return ((ret != 0) ? ENXIO : 0);
@@ -1304,10 +1334,18 @@
goto done;
}
if ((cmd & ~0xff) == MIXER_WRITE(0)) {
- if (j == SOUND_MIXER_RECSRC)
+ switch (j) {
+ case SOUND_MIXER_RECSRC:
ret = mixer_setrecsrc(m, *arg_i);
- else
- ret = mixer_set(m, j, *arg_i);
+ break;
+ case SOUND_MIXER_MUTE:
+ mix_setmutedevs(m, *arg_i);
+ ret = 0;
+ break;
+ default:
+ ret = mixer_set(m, j, m->mutedevs, *arg_i);
+ break;
+ }
snd_mtxunlock(m->lock);
return ((ret == 0) ? 0 : ENXIO);
}
@@ -1318,6 +1356,9 @@
case SOUND_MIXER_STEREODEVS:
v = mix_getdevs(m);
break;
+ case SOUND_MIXER_MUTE:
+ v = mix_getmutedevs(m);
+ break;
case SOUND_MIXER_RECMASK:
v = mix_getrecdevs(m);
break;
@@ -1326,6 +1367,7 @@
break;
default:
v = mixer_get(m, j);
+ break;
}
*arg_i = v;
snd_mtxunlock(m->lock);
@@ -1554,5 +1596,5 @@
level = (left & 0xFF) | ((right & 0xFF) << 8);
- return (mixer_set(m, dev, level));
+ return (mixer_set(m, dev, m->mutedevs, level));
}
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -411,6 +411,10 @@
void sound_oss_sysinfo(oss_sysinfo *);
int sound_oss_card_info(oss_card_info *);
+#define PCM_MODE_MIXER 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)
#define PCM_UNLOCK(d) mtx_unlock((d)->lock)
diff --git a/sys/dev/sound/pcm/sound.c b/sys/dev/sound/pcm/sound.c
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -1015,12 +1015,30 @@
"global clone garbage collector");
#endif
+static u_int8_t
+pcm_mode_init(struct snddev_info *d)
+{
+ u_int8_t mode = 0;
+
+ if (d->playcount > 0)
+ mode |= PCM_MODE_PLAY;
+ if (d->reccount > 0)
+ mode |= PCM_MODE_REC;
+ if (d->mixer_dev != NULL)
+ mode |= PCM_MODE_MIXER;
+
+ return (mode);
+}
+
static void
pcm_sysinit(device_t dev)
{
struct snddev_info *d = device_get_softc(dev);
+ u_int8_t mode;
+
+ 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)),
@@ -1030,6 +1048,11 @@
"bitperfect", CTLTYPE_INT | CTLFLAG_RWTUN | CTLFLAG_NEEDGIANT, 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, "mode", CTLFLAG_RD, NULL, mode,
+ "mode (1=mixer, 2=play, 4=rec. The values are OR'ed if more than one"
+ "mode is supported)");
#ifdef SND_DEBUG
SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
@@ -1133,7 +1156,7 @@
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",
- CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "record channels node");
+ CTLFLAG_RD | CTLFLAG_MPSAFE, 0, "recording channels node");
if (numplay > 0 || numrec > 0)
d->flags |= SD_F_AUTOVCHAN;
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Sat, Jan 11, 9:32 AM (20 h, 15 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
15751867
Default Alt Text
D32499.diff (18 KB)
Attached To
Mode
D32499: sound(4): Apply mixer patches in 13.0-RELEASE
Attached
Detach File
Event Timeline
Log In to Comment