commit 59b41ffceb9c625d13f70729ce4960d69cc511d2
parent eb835fa7f7d3f2c91b5a37a2e0e5c156b0ccef03
Author: Christos Margiolis <christos@margiolis.net>
Date: Tue, 29 Jun 2021 01:42:21 +0300
started writing the manpages, improved function naming
Diffstat:
5 files changed, 187 insertions(+), 56 deletions(-)
diff --git a/mixer_lib/mixer.3 b/mixer_lib/mixer.3
@@ -20,17 +20,36 @@
.\" THE SOFTWARE.
.\"
-.Dd March 11, 2021
+.Dd June 28, 2021
.Dt mixer 3
.Os
.Sh NAME
.Nm mixer
-.Nd a mixer library
+.Nd an OSS mixer library
.Sh LIBRARY
-Mixer (libmixer, -lmixer)
+Mixer library (libmixer, -lmixer)
.Sh SYNOPSIS
.In mixer.h
-.\" TODO
+.Ft struct mixer *
+.Fn mixer_open "const char *path"
+.Ft int
+.Fn mixer_close "struct mixer *m"
+.Ft struct mix_dev *
+.Fn mixer_getdev "struct mixer *m" "int devno"
+.Ft struct mix_dev *
+.Fn mixer_getdevbyname "struct mixer *m" "name"
+.Ft int
+.Fn mixer_setvol "struct mixer *m" "float lvol" "float rvol"
+.Ft int
+.Fn mixer_setpan "struct mixer *m" "float pan"
+.Ft int
+.Fn mixer_modrecsrc "struct mixer *m" "int opt"
+.Ft int
+.Fn mixer_getdunit "void"
+.Ft int
+.Fn mixer_setdunit "struct mixer *m" "int unit"
+.Ft int
+.Fn mixer_getnmixers "void"
.Sh DESCRIPTION
.\" TODO
.Sh SEE ALSO
diff --git a/mixer_lib/mixer.c b/mixer_lib/mixer.c
@@ -38,6 +38,7 @@
static int _mixer_close(struct mixer *m);
static const char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
+static int ndev = 0;
/*
* Open a mixer device in `/dev/mixerN`, where N is the number of the mixer
@@ -65,12 +66,12 @@ mixer_open(const char *name)
}
/* `name` is "/dev/mixer" so, we'll use the default unit. */
if (strncmp(name, BASEPATH, strlen(name)) == 0)
- goto default_unit;
+ goto dunit;
m->unit = strtol(name + strlen(BASEPATH), NULL, 10);
(void)strlcpy(m->name, name, sizeof(m->name));
} else {
-default_unit:
- if ((m->unit = mixer_get_default_unit()) < 0)
+dunit:
+ if ((m->unit = mixer_getdunit()) < 0)
goto fail;
(void)snprintf(m->name, sizeof(m->name) - 1, "/dev/mixer%d", m->unit);
}
@@ -79,7 +80,7 @@ default_unit:
goto fail;
m->devmask = m->recmask = m->recsrc = 0;
- m->f_default = m->unit == mixer_get_default_unit();
+ m->f_default = m->unit == mixer_getdunit();
/* The unit number _must_ be set before the ioctl. */
m->mi.dev = m->unit;
m->ci.card = m->unit;
@@ -114,6 +115,7 @@ default_unit:
dp->f_src = M_ISRECSRC(m, i);
(void)strlcpy(dp->name, names[i], sizeof(dp->name));
TAILQ_INSERT_TAIL(&m->devs, dp, devs);
+ ndev++;
}
/* The default device is always "vol". */
m->dev = TAILQ_FIRST(&m->devs);
@@ -132,6 +134,24 @@ mixer_close(struct mixer *m)
return (_mixer_close(m));
}
+struct mix_dev *
+mixer_getdev(struct mixer *m, int dev)
+{
+ struct mix_dev *dp;
+
+ if (dev < 0 || dev >= ndev) {
+ errno = ERANGE;
+ return (NULL);
+ }
+ TAILQ_FOREACH(dp, &m->devs, devs) {
+ if (dp->devno == dev)
+ return (dp);
+ }
+ errno = EINVAL;
+
+ return (NULL);
+}
+
/*
* Select a mixer device (e.g vol, pcm, mic) by name. The mixer structure
* keeps a list of all the devices the mixer has, but only one can be
@@ -143,7 +163,7 @@ mixer_close(struct mixer *m)
* @param: `name`: device name (e.g vol, pcm, ...)
*/
struct mix_dev *
-mixer_seldevbyname(struct mixer *m, const char *name)
+mixer_getdevbyname(struct mixer *m, const char *name)
{
struct mix_dev *dp;
@@ -168,7 +188,7 @@ mixer_seldevbyname(struct mixer *m, const char *name)
* be handlded by the caller.
*/
int
-mixer_chvol(struct mixer *m, float l, float r)
+mixer_setvol(struct mixer *m, float l, float r)
{
int v;
@@ -192,7 +212,7 @@ mixer_chvol(struct mixer *m, float l, float r)
* `M_PANMIN <= pan <= M_PANMAX`.
*/
int
-mixer_chpan(struct mixer *m, float pan)
+mixer_setpan(struct mixer *m, float pan)
{
int l, r;
@@ -203,7 +223,7 @@ mixer_chpan(struct mixer *m, float pan)
l = m->dev->lvol;
r = m->dev->rvol;
- return (mixer_chvol(m, l, r));
+ return (mixer_setvol(m, l, r));
}
/*
@@ -248,7 +268,7 @@ mixer_modrecsrc(struct mixer *m, int opt)
* and set the mixer structure's `f_default` flag.
*/
int
-mixer_get_default_unit(void)
+mixer_getdunit(void)
{
int unit;
size_t size;
@@ -268,7 +288,7 @@ mixer_get_default_unit(void)
* @param: `unit`: the audio card number (e.g pcm0, pcm1, ...).
*/
int
-mixer_set_default_unit(struct mixer *m, int unit)
+mixer_setdunit(struct mixer *m, int unit)
{
size_t size;
@@ -284,7 +304,7 @@ mixer_set_default_unit(struct mixer *m, int unit)
* Get the total number of mixers in the system.
*/
int
-mixer_get_nmixers(void)
+mixer_getnmixers(void)
{
struct mixer *m;
oss_sysinfo si;
diff --git a/mixer_lib/mixer.h b/mixer_lib/mixer.h
@@ -69,7 +69,7 @@ struct mix_dev {
};
struct mixer {
- TAILQ_HEAD(head, mix_dev) devs;
+ TAILQ_HEAD(head, mix_dev) devs; /* XXX: use LIST? */
struct mix_dev *dev;
oss_mixerinfo mi;
oss_card_info ci;
@@ -84,15 +84,14 @@ struct mixer {
struct mixer *mixer_open(const char *);
int mixer_close(struct mixer *);
-struct mix_dev *mixer_seldevbyname(struct mixer *, const char *);
-/* XXX: change names for ch* functions? */
-int mixer_chvol(struct mixer *, float, float);
-int mixer_chpan(struct mixer *, float);
+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_modrecsrc(struct mixer *, int);
-int mixer_get_default_unit(void);
-int mixer_set_default_unit(struct mixer *, int);
-int mixer_get_nmixers(void);
-/* TODO: get mixer/card total number */
+int mixer_getdunit(void);
+int mixer_setdunit(struct mixer *, int);
+int mixer_getnmixers(void);
__END_DECLS
diff --git a/mixer_prog/mixer_prog.8 b/mixer_prog/mixer_prog.8
@@ -20,17 +20,99 @@
.\" THE SOFTWARE.
.\"
-.Dd June 07, 2021
+.Dd June 28, 2021
.Dt mixer 8
.Os
.Sh NAME
.Nm mixer
.Nd manipulate soundcard mixer values
.Sh SYNOPSIS
-.\" TODO:
+.Nm
+.Op Fl f device
+.Op Fl d unit
+.Op Fl o
+.Oo
+.Ar dev
+.Sm off
+.Oo
+.Op Cm + | -
+.Ar lvol
+.Op : Oo Cm + | - Oc Ar rvol
+.Oc
+.Oc
+.Sm on
+.Ar ...
+.Nm
+.Op Fl f device
+.Op Fl d unit
+.Op Fl o
+.Fl s
+.Ar ...
+.Nm
+.Op Fl f device
+.Op Fl d unit
+.Op Fl o
+.Sm off
+.Bro
+.Cm ^ | + | - | =
+.Brc
+.Cm rec
+.Sm on
+.Ar rdev ...
+.Nm
+.Op Fl o
+.Fl a
.Sh DESCRIPTION
-.\" TODO:
+The
+.Nm
+utility is used to set and display soundcard mixer device levels. The list of mixer
+devices that may be modified are:
+.Bd -ragged -offset indent
+vol, bass, treble, synth, pcm, speaker, line, mic, cd, mix,
+pcm2, rec, igain, ogain, line1, line2, line3, dig1, dig2, dig3,
+phin, phout, video, radio, and monitor.
+.Ed
+.Pp
+Without any arguments,
+.Nm
+displays information and the current settings for all supported devices.
+If the
+.Ar dev
+argument is specified,
+.Nm
+displays only the values for
+.Ar dev .
+.Pp
+To modify a device's volume, the optional
+.Ar lvol
+and/or
+.Ar rvol
+values have to be specified. The values have to be normalized 32-bit floats
+(0.0 to 1.0). Omitting
+.Ar dev
+will change the value of the main channel (usually "vol").
+If the the left or right volume values are prefixed with
+.Cm +
+or
+.Cm - ,
+the value following will be used as a relative adjustment, modifying the
+current settings by the amount specified.
+.Sh FILES
+.Bl -tag -width /dev/mixerN -compact
+.It Pa /dev/mixerN
+the mixer device, where
+.Ar N
+is the number of that device, for example
+.Ar /dev/mixer0 .
+PCM cards and mixers have a 1:1 relationship, which means that
+.Ar mixer0
+is the mixer for
+.Ar pcm0
+and so on.
+.El
+\" TODO: write about the rest of the program.
.Sh SEE ALSO
-.Xr mixer 3
+.Xr mixer 3 ,
+.Xr sound 4
.Sh AUTHORS
.An Christos Margiolis Aq Mt christos@margiolis.net
diff --git a/mixer_prog/mixer_prog.c b/mixer_prog/mixer_prog.c
@@ -33,6 +33,7 @@ static void usage(void) __dead2;
static void printall(struct mixer *, int);
static void printmixer(struct mixer *);
static void printdev(struct mix_dev *, int);
+static void printrecsrc(struct mixer *, int);
static void __dead2
usage(void)
@@ -87,11 +88,33 @@ printdev(struct mix_dev *d, int oflag)
}
}
+static void
+printrecsrc(struct mixer *m, int oflag)
+{
+ struct mix_dev *dp;
+ int n = 0;
+
+ if (!m->recmask)
+ return;
+ if (!oflag) {
+ printmixer(m);
+ printf(" recording source: ");
+ }
+ TAILQ_FOREACH(dp, &m->devs, devs) {
+ if (M_ISRECSRC(m, dp->devno)) {
+ if (n)
+ printf("%s ", oflag ? " " : ", ");
+ printf("%s", dp->name);
+ n++;
+ }
+ }
+ printf("\n");
+}
+
int
main(int argc, char *argv[])
{
struct mixer *m;
- struct mix_dev *dp;
char lstr[8], rstr[8], *name = NULL, buf[NAME_MAX];
float l, r, lrel, rrel;
int dusage = 0, opt = 0, dunit;
@@ -118,6 +141,7 @@ main(int argc, char *argv[])
break;
case 'r':
/* Reserved for {+|-|^|=}rec rdev. */
+ /* FIXME: problems with -rec */
break;
case 's':
sflag = 1;
@@ -131,15 +155,19 @@ main(int argc, char *argv[])
argv += optind;
if (aflag) {
- if ((n = mixer_get_nmixers()) < 0)
+ if ((n = mixer_getnmixers()) < 0)
err(1, "mixer_get_nmixers");
for (i = 0; i < n; i++) {
(void)snprintf(buf, sizeof(buf), "/dev/mixer%d", i);
if ((m = mixer_open(buf)) == NULL)
err(1, "mixer_open: %s", buf);
- printall(m, oflag);
- if (oflag)
- printf("\n");
+ if (sflag)
+ printrecsrc(m, oflag);
+ else {
+ printall(m, oflag);
+ if (oflag)
+ printf("\n");
+ }
(void)mixer_close(m);
}
return (0);
@@ -153,30 +181,17 @@ main(int argc, char *argv[])
/* We don't want to get in here again. */
dflag = 0;
/* XXX: should we die if any of these two fails? */
- if ((n = mixer_get_default_unit()) < 0) {
+ if ((n = mixer_getdunit()) < 0) {
warn("cannot get default unit");
continue;
}
- if (mixer_set_default_unit(m, dunit) < 0) {
+ if (mixer_setdunit(m, dunit) < 0) {
warn("cannot set default unit to %d", dunit);
continue;
}
printf("default_unit: %d -> %d\n", n, dunit);
} else if (sflag) {
- if (!m->recmask)
- goto done;
- n = 0;
- printmixer(m);
- printf(" recording source: ");
- TAILQ_FOREACH(dp, &m->devs, devs) {
- if (M_ISRECSRC(m, dp->devno)) {
- if (n)
- printf(", ");
- printf("%s", dp->name);
- n++;
- }
- }
- printf("\n");
+ printrecsrc(m, oflag);
goto done;
} else if (argc > 0 && strcmp("rec", *argv + 1) == 0) {
if (**argv != '+' && **argv != '-' &&
@@ -199,7 +214,7 @@ main(int argc, char *argv[])
opt = M_TOGGLERECDEV;
break;
}
- if ((m->dev = mixer_seldevbyname(m, argv[1])) == NULL) {
+ if ((m->dev = mixer_getdevbyname(m, argv[1])) == NULL) {
warn("unknown recording device: %s", argv[1]);
/* XXX */
rc = 1;
@@ -215,13 +230,9 @@ main(int argc, char *argv[])
argc -= 2;
argv += 2;
} else if (argc > 0) {
- /*
- * FIXME: this is causing problems if we have
- * -options at the end
- */
if ((k = sscanf(*argv, "%f:%f", &l, &r)) > 0)
; /* nothing */
- else if ((m->dev = mixer_seldevbyname(m, *argv)) == NULL) {
+ else if ((m->dev = mixer_getdevbyname(m, *argv)) == NULL) {
warn("unknown device: %s", *argv);
rc = 1;
goto done;
@@ -272,7 +283,7 @@ main(int argc, char *argv[])
printf("%s.volume: %.2f:%.2f -> %.2f:%.2f\n",
m->dev->name, m->dev->lvol, m->dev->rvol, l, r);
- if (mixer_chvol(m, l, r) < 0) {
+ if (mixer_setvol(m, l, r) < 0) {
warnx("cannot change volume");
rc = 1;
}