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 44dea3fb5c67e1742696455b5bfaed3cc3209980
parent 160aa057c2465d58a6ec706d5d832f4ab1670ba3
Author: Christos Margiolis <christos@margiolis.net>
Date:   Wed, 16 Jun 2021 21:28:55 +0300

volumes now are 32-bit floats -- some things might not work properly yet

Diffstat:
MREADME | 2+-
Mmixer_lib/Makefile | 1+
Mmixer_lib/mixer.3 | 2+-
Mmixer_lib/mixer.c | 34+++++++++++++++++++---------------
Mmixer_lib/mixer.h | 14++++++++++----
Mmixer_prog/Makefile | 2+-
Mmixer_prog/mixer_prog.8 | 2+-
Mmixer_prog/mixer_prog.c | 38++++++++++++++++++++------------------
8 files changed, 54 insertions(+), 41 deletions(-)

diff --git a/README b/README @@ -9,4 +9,4 @@ Usage $ make # make install clean -Please report any bugs to <christos@freebsd.org>. +Please report any bugs to <christos@FreeBSD.org>. diff --git a/mixer_lib/Makefile b/mixer_lib/Makefile @@ -5,5 +5,6 @@ SRCS= ${LIB}.c INCS= ${LIB}.h MAN= ${LIB}.3 CFLAGS+= -pedantic -Wall -Wunused +LDFLAGS+= -lm .include <bsd.lib.mk> diff --git a/mixer_lib/mixer.3 b/mixer_lib/mixer.3 @@ -1,5 +1,5 @@ .\"- -.\" Copyright (c) 2021 Christos Margiolis <christos@freebsd.org> +.\" Copyright (c) 2021 Christos Margiolis <christos@FreeBSD.org> .\" .\" Permission is hereby granted, free of charge, to any person obtaining a copy .\" of this software and associated documentation files (the "Software"), to deal diff --git a/mixer_lib/mixer.c b/mixer_lib/mixer.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2021 Christos Margiolis <christos@freebsd.org> + * Copyright (c) 2021 Christos Margiolis <christos@FreeBSD.org> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -102,8 +102,12 @@ default_unit: if (ioctl(m->fd, MIXER_READ(i), &v) < 0) goto fail; dp->devno = i; - dp->lvol = v & 0x7f; - dp->rvol = (v >> 8) & 0x7f; + dp->lvol = M_VOLNORM(v & 0x7f); + dp->rvol = M_VOLNORM((v >> 8) & 0x7f); + /* + * TODO: find a way to know if it's already muted + * or not, this doesn't make sense + */ dp->lmute = 0; dp->rmute = 0; dp->f_pbk = !M_ISREC(m, i); @@ -156,23 +160,23 @@ mixer_seldevbyname(struct mixer *m, const char *name, int flags) /* * Change the mixer's left and right volume. The allowed volume values are - * between 0 and 100 and are stored as `lvol | rvol << 8`. + * between M_VOLMIN and M_VOLMAX and are stored as `lvol | rvol << 8`. + * + * TODO update comment */ int -mixer_chvol(struct mixer *m, int l, int r) +mixer_chvol(struct mixer *m, float l, float r) { - if (l < 0) - l = 0; - else if (l > 100) - l = 100; - if (r < 0) - r = 0; - else if (r > 100) - r = 100; + int v; + + if (l < M_VOLMIN || l > M_VOLMAX || r < M_VOLMIN || r > M_VOLMAX) { + errno = ERANGE; + return (-1); + } m->dev->lvol = l; m->dev->rvol = r; - l |= r << 8; - if (ioctl(m->fd, MIXER_WRITE(m->dev->devno), &l) < 0) + v = M_VOLDENORM(l) | M_VOLDENORM(r) << 8; + if (ioctl(m->fd, MIXER_WRITE(m->dev->devno), &v) < 0) return (-1); return (0); diff --git a/mixer_lib/mixer.h b/mixer_lib/mixer.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2021 Christos Margiolis <christos@freebsd.org> + * Copyright (c) 2021 Christos Margiolis <christos@FreeBSD.org> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,12 +30,18 @@ __FBSDID("$FreeBSD$"); #include <sys/soundcard.h> #include <limits.h> +#include <math.h> #define M_ADDRECDEV 0x01 #define M_REMOVERECDEV 0x02 #define M_SETRECDEV 0x04 #define M_TOGGLERECDEV 0x08 +#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)) #define M_ISDEV(m, n) M_ISSET(n, (m)->devmask) #define M_ISREC(m, n) M_ISSET(n, (m)->recmask) @@ -44,8 +50,8 @@ __FBSDID("$FreeBSD$"); struct mix_dev { char name[NAME_MAX]; int devno; - short lvol; - short rvol; + float lvol; + float rvol; int lmute; int rmute; //int rate; @@ -72,7 +78,7 @@ struct mixer { struct mixer *mixer_open(const char *); int mixer_close(struct mixer *); struct mix_dev *mixer_seldevbyname(struct mixer *, const char *, int); -int mixer_chvol(struct mixer *, int, int); +int mixer_chvol(struct mixer *, float, float); int mixer_modrecsrc(struct mixer *, int); int mixer_get_default_unit(void); int mixer_set_default_unit(struct mixer *, int); 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 +LDFLAGS+= -lmixer -lm # FIXME: why -lm? .include <bsd.prog.mk> diff --git a/mixer_prog/mixer_prog.8 b/mixer_prog/mixer_prog.8 @@ -1,5 +1,5 @@ .\"- -.\" Copyright (c) 2021 Christos Margiolis <christos@freebsd.org> +.\" Copyright (c) 2021 Christos Margiolis <christos@FreeBSD.org> .\" .\" Permission is hereby granted, free of charge, to any person obtaining a copy .\" of this software and associated documentation files (the "Software"), to deal diff --git a/mixer_prog/mixer_prog.c b/mixer_prog/mixer_prog.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2021 Christos Margiolis <christos@freebsd.org> + * Copyright (c) 2021 Christos Margiolis <christos@FreeBSD.org> * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -101,8 +101,8 @@ main(int argc, char *argv[]) struct mixer *m; struct mix_dev *dp; char lstr[8], rstr[8], *name = NULL; + float l, r, lrel, rrel; int dusage = 0, drecsrc = 0, sflag = 0, Sflag = 0; - int l, r, lprev, rprev, lrel, rrel; char ch, n, t, k, opt = 0; /* FIXME: problems with -rec */ @@ -136,12 +136,12 @@ main(int argc, char *argv[]) n = 0; TAILQ_FOREACH(dp, &m->devs, devs) { if (sflag || Sflag) { - printf("%s%s%c%d:%d", n ? " " : "", + printf("%s%s%c%.2f:%.2f", n ? " " : "", dp->name, Sflag ? ':' : ' ', dp->lvol, dp->rvol); n++; } else - printf("Mixer %-8s is currently set to %3d:%d\n", + printf("Mixer %-8s is currently set to %.2f:%.2f\n", dp->name, dp->lvol, dp->rvol); } if (n && m->recmask) @@ -201,7 +201,7 @@ main(int argc, char *argv[]) continue; } - if ((t = sscanf(*argv, "%d:%d", &l, &r)) > 0) + if ((t = sscanf(*argv, "%f:%f", &l, &r)) > 0) ; /* nothing */ else if ((m->dev = mixer_seldevbyname(m, *argv, m->devmask)) == NULL) { @@ -221,18 +221,18 @@ main(int argc, char *argv[]) if (k > 0) { if (*lstr == '+' || *lstr == '-') lrel = rrel = 1; - l = strtol(lstr, NULL, 10); + l = strtof(lstr, NULL); } if (k > 1) { if (*rstr == '+' || *rstr == '-') rrel = 1; - r = strtol(rstr, NULL, 10); + r = strtof(rstr, NULL); } } switch (argc > 1 ? k : t) { case 0: - printf("Mixer %-8s is currently set to %3d:%d\n", + printf("Mixer %-8s is currently set to %.2f:%.2f\n", m->dev->name, m->dev->lvol, m->dev->rvol); argc--; argv++; @@ -240,25 +240,27 @@ main(int argc, char *argv[]) case 1: r = l; /* FALLTHROUGH */ case 2: - /* - * Keep the previous volume so we don't have to clump - * it manually before we print it in case the user gives a - * value < 0 or > 100. - */ - lprev = m->dev->lvol; - rprev = m->dev->rvol; if (lrel) l += m->dev->lvol; if (rrel) r += m->dev->rvol; + + if (l < M_VOLMIN) + l = M_VOLMIN; + else if (l > M_VOLMAX) + l = M_VOLMAX; + if (r < M_VOLMIN) + r = M_VOLMIN; + else if (r > M_VOLMAX) + r = M_VOLMAX; if (mixer_chvol(m, l, r) < 0) { warnx("cannot change volume"); break; } if (!Sflag) - printf("Setting the mixer %s from %d:%d to %d:%d\n", - m->dev->name, lprev, rprev, - m->dev->lvol, m->dev->rvol); + printf("Setting the mixer %s from %.2f:%.2f " + "to %.2f:%.2f\n", + m->dev->name, m->dev->lvol, m->dev->rvol, l, r); argc -= 2; argv += 2; }