mixer

FreeBSD OSS mixer library implementation and a complete rewrite of mixer(8)
git clone git://git.margiolis.net/mixer.git
Log | Files | Refs | README

commit 4a0eb57baa1b67bf889bf03df2570a42ce66ab97
parent 90e81ce8fce5b824d9330df884e93fbbe736eca0
Author: Christos Margiolis <christos@margiolis.net>
Date:   Thu, 15 Jul 2021 00:07:28 +0300

minor refactoring

Diffstat:
MMakefile | 0
Mmixer_lib/mixer.3 | 4+---
Mmixer_lib/mixer.c | 37+++++++++++++++++++++----------------
Mmixer_lib/mixer.h | 36+++++++++++++++++-------------------
Mmixer_prog/Makefile | 2+-
Mmixer_prog/mixer_prog.c | 31++++++-------------------------
6 files changed, 46 insertions(+), 64 deletions(-)

diff --git a/Makefile b/Makefile diff --git a/mixer_lib/mixer.3 b/mixer_lib/mixer.3 @@ -39,9 +39,7 @@ Mixer library (libmixer, -lmixer) .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" +.Fn mixer_setvol "struct mixer *m" "mixer_volume_t vol" .Ft int .Fn mixer_setmute "struct mixer *m" "int opt" .Ft int diff --git a/mixer_lib/mixer.c b/mixer_lib/mixer.c @@ -26,6 +26,7 @@ #include <errno.h> #include <fcntl.h> +#include <math.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -37,9 +38,9 @@ static int _mixer_readvol(struct mixer *, struct mix_dev *); -static const char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES; -static int ndev = 0; - +/* + * Fetch volume from the device. + */ static int _mixer_readvol(struct mixer *m, struct mix_dev *dev) { @@ -54,18 +55,22 @@ _mixer_readvol(struct mixer *m, struct mix_dev *dev) } /* - * Open a mixer device in `/dev/mixerN`, where N is the number of the mixer - * file. Each device maps to an actual pcmN audio card, so `/dev/mixer0` - * is the mixer device for pcm0, and so on. + * Open a mixer device in `/dev/mixerN`, where N is the number of the mixer. + * Each device maps to an actual pcmN audio card, so `/dev/mixer0` is the + * mixer device for pcm0, and so on. + * + * @param name path to mixer device. NULL or "/dev/mixer" for the + * the default mixer (i.e `hw.snd.default_unit`). * - * @param: `name`: path to a mixer device. If it's NULL or "/dev/mixer", - * we open the default mixer (i.e `hw.snd.default_unit`). + * @retval mixer success + * @retval NULL fail */ struct mixer * mixer_open(const char *name) { struct mixer *m = NULL; struct mix_dev *dp; + const char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES; int i; if ((m = calloc(1, sizeof(struct mixer))) == NULL) @@ -116,7 +121,7 @@ dunit: goto fail; (void)strlcpy(dp->name, names[i], sizeof(dp->name)); TAILQ_INSERT_TAIL(&m->devs, dp, devs); - ndev++; + m->ndev++; } /* The default device is always "vol". */ @@ -155,7 +160,7 @@ mixer_getdev(struct mixer *m, int dev) { struct mix_dev *dp; - if (dev < 0 || dev >= ndev) { + if (dev < 0 || dev >= m->ndev) { errno = ERANGE; return (NULL); } @@ -176,7 +181,7 @@ mixer_getdev(struct mixer *m, int dev) * * The caller has to assign the return value to `m->dev`. * - * @param: `name`: device name (e.g vol, pcm, ...) + * @param name device name (e.g vol, pcm, ...) */ struct mix_dev * mixer_getdevbyname(struct mixer *m, const char *name) @@ -259,16 +264,16 @@ mixer_modrecsrc(struct mixer *m, int opt) return (-1); } switch (opt) { - case M_ADDRECDEV: + case M_ADDRECSRC: m->recsrc |= (1 << m->dev->devno); break; - case M_REMOVERECDEV: + case M_REMOVERECSRC: m->recsrc &= ~(1 << m->dev->devno); break; - case M_SETRECDEV: + case M_SETRECSRC: m->recsrc = (1 << m->dev->devno); break; - case M_TOGGLERECDEV: + case M_TOGGLERECSRC: m->recsrc ^= (1 << m->dev->devno); break; default: @@ -305,7 +310,7 @@ mixer_getdunit(void) * it's useful to have, so the caller can avoid having to manually use * the sysctl API. * - * @param: `unit`: the audio card number (e.g pcm0, pcm1, ...). + * @param unit the audio card number (e.g pcm0, pcm1, ...). */ int mixer_setdunit(struct mixer *m, int unit) diff --git a/mixer_lib/mixer.h b/mixer_lib/mixer.h @@ -34,30 +34,20 @@ __FBSDID("$FreeBSD$"); #include <limits.h> #include <math.h> -#define M_ADDRECDEV 0x01 -#define M_REMOVERECDEV 0x02 -#define M_SETRECDEV 0x04 -#define M_TOGGLERECDEV 0x08 - -#define M_MUTE 0x01 -#define M_UNMUTE 0x02 -#define M_TOGGLEMUTE 0x04 - -#define M_VOLMIN 0.0f -#define M_VOLMAX 1.0f -#define M_VOLNORM(v) ((v) / 100.0f) -#define M_VOLDENORM(v) ((int)roundf((v) * 100.0f)) - -#define M_ISSET(n, f) (((1 << (n)) & (f)) ? 1 : 0) -#define M_ISDEV(m, n) M_ISSET(n, (m)->devmask) -#define M_ISMUTE(m, n) M_ISSET(n, (m)->mutemask) -#define M_ISREC(m, n) M_ISSET(n, (m)->recmask) -#define M_ISRECSRC(m, n) M_ISSET(n, (m)->recsrc) +#define M_ISSET(n,f) (((1 << (n)) & (f)) ? 1 : 0) +#define M_ISDEV(m,n) M_ISSET(n, (m)->devmask) +#define M_ISMUTE(m,n) M_ISSET(n, (m)->mutemask) +#define M_ISREC(m,n) M_ISSET(n, (m)->recmask) +#define M_ISRECSRC(m,n) M_ISSET(n, (m)->recsrc) struct mix_dev { char name[NAME_MAX]; int devno; struct mix_volume { +#define M_VOLMIN 0.0f +#define M_VOLMAX 1.0f +#define M_VOLNORM(v) ((v) / 100.0f) +#define M_VOLDENORM(v) ((int)roundf((v) * 100.0f)) float left; float right; } vol; @@ -72,9 +62,17 @@ struct mixer { char name[NAME_MAX]; int fd; int unit; + int ndev; int devmask; +#define M_MUTE 0x01 +#define M_UNMUTE 0x02 +#define M_TOGGLEMUTE 0x04 int mutemask; int recmask; +#define M_ADDRECSRC 0x01 +#define M_REMOVERECSRC 0x02 +#define M_SETRECSRC 0x04 +#define M_TOGGLERECSRC 0x08 int recsrc; int f_default; }; diff --git a/mixer_prog/Makefile b/mixer_prog/Makefile @@ -5,6 +5,6 @@ BINDIR= /usr/sbin SRCS= ${PROG}.c MAN= ${PROG}.8 CFLAGS+= -pedantic -Wall -Wunused -LDFLAGS+= -lmixer -lm # FIXME: why -lm? +LDFLAGS+= -lmixer -lm .include <bsd.prog.mk> diff --git a/mixer_prog/mixer_prog.c b/mixer_prog/mixer_prog.c @@ -51,17 +51,14 @@ static void printrecsrc(struct mixer *, int); static int findctl(const char *); /* Control handlers */ static void mod_volume(struct mixer *, const char *); -static void mod_panning(struct mixer *, const char *); static void mod_mute(struct mixer *, const char *); static void mod_recsrc(struct mixer *, const char *); static void print_volume(struct mixer *); -static void print_panning(struct mixer *); static void print_mute(struct mixer *); static void print_recsrc(struct mixer *); static const struct mix_ctl ctls[] = { [MCTL_VOL] = { "volume", mod_volume, print_volume }, - [MCTL_PAN] = { "panning", mod_panning, print_panning }, [MCTL_MUT] = { "mute", mod_mute, print_mute }, [MCTL_SRC] = { "recsrc", mod_recsrc, print_recsrc }, }; @@ -222,12 +219,9 @@ printminfo(struct mixer *m, int oflag) static void printdev(struct mixer *m, struct mix_dev *d, int oflag) { - float pan; - - pan = d->vol.right - d->vol.left; if (!oflag) { - printf(" %-11s= %.2f:%.2f\t%+.2f\t", - d->name, d->vol.left, d->vol.right, pan); + printf(" %-11s= %.2f:%.2f\t", + d->name, d->vol.left, d->vol.right); if (!M_ISREC(m, d->devno)) printf(" pbk"); if (M_ISREC(m, d->devno)) @@ -242,7 +236,6 @@ printdev(struct mixer *m, struct mix_dev *d, int oflag) d->name, ctls[MCTL_VOL].name, d->vol.left, d->vol.right); printf("%s.%s=%d\n", d->name, ctls[MCTL_MUT].name, M_ISMUTE(m, d->devno)); - printf("%s.%s=%.2f\n", d->name, ctls[MCTL_PAN].name, pan); if (M_ISRECSRC(m, d->devno)) printf("%s.%s=+\n", d->name, ctls[MCTL_SRC].name); } @@ -336,12 +329,6 @@ mod_volume(struct mixer *m, const char *val) } static void -mod_panning(struct mixer *m, const char *val) -{ - /* XXX: */ -} - -static void mod_mute(struct mixer *m, const char *val) { int n, opt = -1; @@ -375,16 +362,16 @@ mod_recsrc(struct mixer *m, const char *val) switch (*val) { case '+': - opt = M_ADDRECDEV; + opt = M_ADDRECSRC; break; case '-': - opt = M_REMOVERECDEV; + opt = M_REMOVERECSRC; break; case '=': - opt = M_SETRECDEV; + opt = M_SETRECSRC; break; case '^': - opt = M_TOGGLERECDEV; + opt = M_TOGGLERECSRC; break; default: warnx("%c: no such modifier", *val); @@ -407,12 +394,6 @@ print_volume(struct mixer *m) } static void -print_panning(struct mixer *m) -{ - /* XXX: */ -} - -static void print_mute(struct mixer *m) { printf("%s.%s=%d\n", m->dev->name, ctls[MCTL_MUT].name,