commit 62ae192d6951bf184b9a51e55b7e607b32eb53f2
parent 75e74d4a795cc470cc766bebc2a0a53f285e780a
Author: Christos Margiolis <christos@margiolis.net>
Date: Sat, 31 Jul 2021 17:44:31 +0300
working on control handling, might need a clean up
Diffstat:
4 files changed, 84 insertions(+), 60 deletions(-)
diff --git a/diff/mixer_kern.diff b/diff/mixer_kern.diff
@@ -308,7 +308,7 @@ index 8e11d553a3e..7857609b289 100644
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/sound.c b/sys/dev/sound/pcm/sound.c
-index b4be28aeff8..e2014a70f9b 100644
+index b4be28aeff8..6b1b8bcbc93 100644
--- a/sys/dev/sound/pcm/sound.c
+++ b/sys/dev/sound/pcm/sound.c
@@ -1012,12 +1012,30 @@ SYSCTL_PROC(_hw_snd, OID_AUTO, clone_gc, CTLTYPE_INT | CTLFLAG_RWTUN,
@@ -324,8 +324,8 @@ index b4be28aeff8..e2014a70f9b 100644
+ mode |= PCM_MODE_PLAY;
+ if (d->reccount > 0)
+ mode |= PCM_MODE_REC;
-+ if (d->playcount == 0 && d->reccount == 0)
-+ mode = PCM_MODE_NONE;
++ if (d->mixer_dev != NULL)
++ mode |= PCM_MODE_MIXER;
+
+ return (mode);
+}
@@ -343,18 +343,19 @@ index b4be28aeff8..e2014a70f9b 100644
sysadmin then needs min+max sysctls for this */
SYSCTL_ADD_UINT(device_get_sysctl_ctx(dev),
SYSCTL_CHILDREN(device_get_sysctl_tree(dev)),
-@@ -1027,6 +1045,10 @@ pcm_sysinit(device_t dev)
+@@ -1027,6 +1045,11 @@ pcm_sysinit(device_t dev)
"bitperfect", CTLTYPE_INT | CTLFLAG_RWTUN, 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 (0=none, 1=play, 2=rec, 3=play+rec)");
++ "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,
-@@ -1130,7 +1152,7 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
+@@ -1130,7 +1153,7 @@ pcm_register(device_t dev, void *devinfo, int numplay, int numrec)
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",
@@ -364,14 +365,14 @@ index b4be28aeff8..e2014a70f9b 100644
if (numplay > 0 || numrec > 0)
d->flags |= SD_F_AUTOVCHAN;
diff --git a/sys/dev/sound/pcm/sound.h b/sys/dev/sound/pcm/sound.h
-index d4b3a23e8eb..eda4012a517 100644
+index d4b3a23e8eb..e9979cf426c 100644
--- a/sys/dev/sound/pcm/sound.h
+++ b/sys/dev/sound/pcm/sound.h
@@ -411,6 +411,10 @@ struct snddev_info {
void sound_oss_sysinfo(oss_sysinfo *);
int sound_oss_card_info(oss_card_info *);
-+#define PCM_MODE_NONE 0x01
++#define PCM_MODE_MIXER 0x01
+#define PCM_MODE_PLAY 0x02
+#define PCM_MODE_REC 0x04
+
diff --git a/mixer_lib/mixer.c b/mixer_lib/mixer.c
@@ -114,6 +114,7 @@ dunit:
continue;
if ((dp = calloc(1, sizeof(struct mix_dev))) == NULL)
goto fail;
+ dp->parent_mixer = m;
dp->devno = i;
dp->nctl = 0;
if (_mixer_readvol(m, dp) < 0)
@@ -210,13 +211,16 @@ mixer_get_dev_byname(struct mixer *m, const char *name)
* Make a mixer control.
*/
mix_ctl_t *
-mixer_make_ctl(int id, const char *name,
- int (*mod)(struct mixer *m, void *p), int (*print)(struct mixer *m, void *p))
+mixer_make_ctl(struct mix_dev *parent_dev, int id, const char *name,
+ int (*mod)(struct mix_dev *d, void *p),
+ int (*print)(struct mix_dev *d, void *p))
{
mix_ctl_t *ctl;
+ /* XXX: do not alloc? */
if ((ctl = calloc(1, sizeof(mix_ctl_t))) == NULL)
return (NULL);
+ ctl->parent_dev = parent_dev;
ctl->id = id;
if (name != NULL)
(void)strlcpy(ctl->name, name, sizeof(ctl->name));
@@ -230,27 +234,30 @@ mixer_make_ctl(int id, const char *name,
* Add a mixer control to a device by passing all fields as arguments.
*/
int
-mixer_add_ctl(struct mix_dev *d, int id, const char *name,
- int (*mod)(struct mixer *m, void *p), int (*print)(struct mixer *m, void *p))
+mixer_add_ctl(struct mix_dev *parent_dev, int id, const char *name,
+ int (*mod)(struct mix_dev *d, void *p),
+ int (*print)(struct mix_dev *d, void *p))
{
mix_ctl_t *ctl;
- if ((ctl = mixer_make_ctl(id, name, mod, print)) == NULL)
+ if ((ctl = mixer_make_ctl(parent_dev, id, name, mod, print)) == NULL)
return (-1);
- return (mixer_add_ctl_s(d, ctl));
+ return (mixer_add_ctl_s(ctl));
}
/*
* Add a mixer control to a device.
*/
int
-mixer_add_ctl_s(struct mix_dev *d, mix_ctl_t *ctl)
+mixer_add_ctl_s(mix_ctl_t *ctl)
{
- if (ctl == NULL || ctl->mod == NULL || ctl->print == NULL)
+ struct mix_dev *p = ctl->parent_dev;
+
+ if (ctl == NULL || p == NULL || ctl->mod == NULL || ctl->print == NULL)
return (-1);
- TAILQ_INSERT_TAIL(&d->ctls, ctl, ctls);
- d->nctl++;
+ TAILQ_INSERT_TAIL(&p->ctls, ctl, ctls);
+ p->nctl++;
return (0);
}
@@ -259,14 +266,16 @@ mixer_add_ctl_s(struct mix_dev *d, mix_ctl_t *ctl)
* Remove a mixer control from a device.
*/
int
-mixer_remove_ctl(struct mix_dev *d, mix_ctl_t *ctl)
+mixer_remove_ctl(mix_ctl_t *ctl)
{
+ struct mix_dev *p = ctl->parent_dev;
+
if (ctl == NULL) {
errno = EINVAL;
return (-1);
}
- if (!TAILQ_EMPTY(&d->ctls)) {
- TAILQ_REMOVE(&d->ctls, ctl, ctls);
+ if (!TAILQ_EMPTY(&p->ctls)) {
+ TAILQ_REMOVE(&p->ctls, ctl, ctls);
free(ctl);
}
diff --git a/mixer_lib/mixer.h b/mixer_lib/mixer.h
@@ -40,17 +40,24 @@ __FBSDID("$FreeBSD$");
#define MIX_ISREC(m,n) MIX_ISSET(n, (m)->recmask)
#define MIX_ISRECSRC(m,n) MIX_ISSET(n, (m)->recsrc)
+/* Forward declarations */
struct mixer;
+struct mix_dev;
-typedef struct mix_ctl {
+typedef struct mix_ctl mix_ctl_t;
+typedef struct mix_volume mix_volume_t;
+
+struct mix_ctl {
+ struct mix_dev *parent_dev;
int id;
char name[NAME_MAX];
- int (*mod)(struct mixer *, void *);
- int (*print)(struct mixer *, void *);
+ int (*mod)(struct mix_dev *, void *);
+ int (*print)(struct mix_dev *, void *);
TAILQ_ENTRY(mix_ctl) ctls;
-} mix_ctl_t;
+};
struct mix_dev {
+ struct mixer *parent_mixer;
char name[NAME_MAX];
int devno;
struct mix_volume {
@@ -87,24 +94,22 @@ struct mixer {
#define MIX_TOGGLERECSRC 0x08
int recsrc;
int f_default;
-#define MIX_MODE_NONE 0x01
+#define MIX_MODE_MIXER 0x01
#define MIX_MODE_PLAY 0x02
#define MIX_MODE_REC 0x04
int mode;
};
-typedef struct mix_volume mix_volume_t;
-
struct mixer *mixer_open(const char *);
int mixer_close(struct mixer *);
struct mix_dev *mixer_get_dev(struct mixer *, int);
struct mix_dev *mixer_get_dev_byname(struct mixer *, const char *);
-mix_ctl_t *mixer_make_ctl(int, const char *,
- int (*)(struct mixer *, void *), int (*)(struct mixer *, void *));
+mix_ctl_t *mixer_make_ctl(struct mix_dev *, int, const char *,
+ int (*)(struct mix_dev *, void *), int (*)(struct mix_dev *, void *));
int mixer_add_ctl(struct mix_dev *, int, const char *,
- int (*)(struct mixer *, void *), int (*)(struct mixer *, void *));
-int mixer_add_ctl_s(struct mix_dev *, mix_ctl_t *);
-int mixer_remove_ctl(struct mix_dev *, mix_ctl_t *);
+ int (*)(struct mix_dev *, void *), int (*)(struct mix_dev *, void *));
+int mixer_add_ctl_s(mix_ctl_t *);
+int mixer_remove_ctl(mix_ctl_t *);
mix_ctl_t *mixer_get_ctl(struct mix_dev *, int);
mix_ctl_t *mixer_get_ctl_byname(struct mix_dev *, const char *);
int mixer_set_vol(struct mixer *, mix_volume_t);
diff --git a/mixer_prog/mixer_prog.c b/mixer_prog/mixer_prog.c
@@ -36,15 +36,15 @@ static void initctls(struct mixer *);
static void printall(struct mixer *, int);
static void printminfo(struct mixer *, int);
static void printdev(struct mixer *, int);
-static void printrecsrc(struct mixer *, int);
+static void printrecsrc(struct mixer *, int); /* XXX: change name */
/* Control handlers */
-static int mod_dunit(struct mixer *, void *);
-static int mod_volume(struct mixer *, void *);
-static int mod_mute(struct mixer *, void *);
-static int mod_recsrc(struct mixer *, void *);
-static int print_volume(struct mixer *, void *);
-static int print_mute(struct mixer *, void *);
-static int print_recsrc(struct mixer *, void *);
+static int mod_dunit(struct mix_dev *, void *);
+static int mod_volume(struct mix_dev *, void *);
+static int mod_mute(struct mix_dev *, void *);
+static int mod_recsrc(struct mix_dev *, void *);
+static int print_volume(struct mix_dev *, void *);
+static int print_mute(struct mix_dev *, void *);
+static int print_recsrc(struct mix_dev *, void *);
static mix_ctl_t *ctl_dunit;
@@ -113,7 +113,7 @@ main(int argc, char *argv[])
initctls(m);
- if (dflag && ctl_dunit->mod(m, &dunit) < 0)
+ if (dflag && ctl_dunit->mod(ctl_dunit->parent_dev, &dunit) < 0)
goto parse;
if (sflag) {
printrecsrc(m, oflag);
@@ -145,13 +145,13 @@ parse:
/* Input: `dev.control`. */
if (p == NULL) {
- (void)cp->print(m, cp->name);
+ (void)cp->print(cp->parent_dev, cp->name);
pall = 0;
goto next;
}
valstr = p;
/* Input: `dev.control=val`. */
- cp->mod(m, valstr);
+ cp->mod(cp->parent_dev, valstr);
next:
free(p);
argc--;
@@ -187,8 +187,7 @@ initctls(struct mixer *m)
(void)mixer_add_ctl(dp, C_MUT, "mute", mod_mute, print_mute);
(void)mixer_add_ctl(dp, C_SRC, "recsrc", mod_recsrc, print_recsrc);
}
- ctl_dunit = mixer_make_ctl(-1, "default_unit", mod_dunit, NULL);
-
+ ctl_dunit = mixer_make_ctl(NULL, -1, "default_unit", mod_dunit, NULL);
}
static void
@@ -206,19 +205,19 @@ printall(struct mixer *m, int oflag)
static void
printminfo(struct mixer *m, int oflag)
{
+ int playrec = MIX_MODE_PLAY | MIX_MODE_REC;
+
if (oflag)
return;
printf("%s: <%s> %s", m->mi.name, m->ci.longname, m->ci.hw_info);
- if (!(m->mode & MIX_MODE_NONE))
- printf(" (");
+ printf(" (");
if (m->mode & MIX_MODE_PLAY)
printf("play");
- if (m->mode == (MIX_MODE_PLAY | MIX_MODE_REC))
+ if ((m->mode & playrec) == playrec)
printf("/");
if (m->mode & MIX_MODE_REC)
printf("rec");
- if (!(m->mode & MIX_MODE_NONE))
- printf(")");
+ printf(")");
if (m->f_default)
printf(" (default)");
printf("\n");
@@ -244,11 +243,12 @@ printdev(struct mixer *m, int oflag)
printf("\n");
} else {
TAILQ_FOREACH(cp, &d->ctls, ctls) {
- (void)cp->print(m, cp->name);
+ (void)cp->print(cp->parent_dev, cp->name);
}
}
}
+/* TODO: -o option .recsrc */
static void
printrecsrc(struct mixer *m, int oflag)
{
@@ -271,7 +271,7 @@ printrecsrc(struct mixer *m, int oflag)
}
static int
-mod_dunit(struct mixer *m, void *p)
+mod_dunit(struct mix_dev *d, void *p)
{
int dunit = *((int *)p);
int n;
@@ -280,7 +280,7 @@ mod_dunit(struct mixer *m, void *p)
warn("cannot get default unit");
return (-1);
}
- if (mixer_set_dunit(m, dunit) < 0) {
+ if (mixer_set_dunit(d->parent_mixer, dunit) < 0) {
warn("cannot set default unit to: %d", dunit);
return (-1);
}
@@ -290,8 +290,9 @@ mod_dunit(struct mixer *m, void *p)
}
static int
-mod_volume(struct mixer *m, void *p)
+mod_volume(struct mix_dev *d, void *p)
{
+ struct mixer *m;
mix_ctl_t *cp;
mix_volume_t v;
const char *val;
@@ -299,6 +300,7 @@ mod_volume(struct mixer *m, void *p)
float lprev, rprev, lrel, rrel;
int n;
+ m = d->parent_mixer;
cp = mixer_get_ctl(m->dev, C_VOL);
val = p;
n = sscanf(val, "%7[^:]:%7s", lstr, rstr);
@@ -349,12 +351,14 @@ mod_volume(struct mixer *m, void *p)
}
static int
-mod_mute(struct mixer *m, void *p)
+mod_mute(struct mix_dev *d, void *p)
{
+ struct mixer *m;
mix_ctl_t *cp;
const char *val;
int n, opt = -1;
+ m = d->parent_mixer;
cp = mixer_get_ctl(m->dev, C_MUT);
val = p;
switch (*val) {
@@ -382,12 +386,14 @@ mod_mute(struct mixer *m, void *p)
}
static int
-mod_recsrc(struct mixer *m, void *p)
+mod_recsrc(struct mix_dev *d, void *p)
{
+ struct mixer *m;
mix_ctl_t *cp;
const char *val;
int n, opt = -1;
+ m = d->parent_mixer;
cp = mixer_get_ctl(m->dev, C_SRC);
val = p;
switch (*val) {
@@ -418,8 +424,9 @@ mod_recsrc(struct mixer *m, void *p)
}
static int
-print_volume(struct mixer *m, void *p)
+print_volume(struct mix_dev *d, void *p)
{
+ struct mixer *m = d->parent_mixer;
const char *ctl_name = p;
printf("%s.%s=%.2f:%.2f\n",
@@ -429,8 +436,9 @@ print_volume(struct mixer *m, void *p)
}
static int
-print_mute(struct mixer *m, void *p)
+print_mute(struct mix_dev *d, void *p)
{
+ struct mixer *m = d->parent_mixer;
const char *ctl_name = p;
printf("%s.%s=%d\n", m->dev->name, ctl_name, MIX_ISMUTE(m, m->dev->devno));
@@ -439,8 +447,9 @@ print_mute(struct mixer *m, void *p)
}
static int
-print_recsrc(struct mixer *m, void *p)
+print_recsrc(struct mix_dev *d, void *p)
{
+ struct mixer *m = d->parent_mixer;
const char *ctl_name = p;
if (!MIX_ISRECSRC(m, m->dev->devno))