commit 0a2cf822789f7543fa5d2329a9f947c1cdca418d
parent 44dea3fb5c67e1742696455b5bfaed3cc3209980
Author: Christos Margiolis <christos@margiolis.net>
Date: Thu, 17 Jun 2021 14:45:21 +0300
added panning function to implement soon, minor fixes
Diffstat:
2 files changed, 42 insertions(+), 15 deletions(-)
diff --git a/mixer_lib/mixer.c b/mixer_lib/mixer.c
@@ -44,7 +44,7 @@ static const char *names[SOUND_MIXER_NRDEVICES] = SOUND_DEVICE_NAMES;
* file. Each device maps to an actual pcmN audio card, so `/dev/mixer0`
* is the mixer device for pcm0, and so on.
*
- * @arg: `name`: path to a mixer device. If it's NULL or "/dev/mixer",
+ * @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`).
*/
struct mixer *
@@ -82,15 +82,11 @@ default_unit:
/* The unit number _must_ be set before the ioctl. */
m->mi.dev = m->unit;
m->ci.card = m->unit;
- if (ioctl(m->fd, SNDCTL_MIXERINFO, &m->mi) < 0)
- goto fail;
- if (ioctl(m->fd, SNDCTL_CARDINFO, &m->ci) < 0)
- goto fail;
- if (ioctl(m->fd, SOUND_MIXER_READ_DEVMASK, &m->devmask) < 0)
- goto fail;
- if (ioctl(m->fd, SOUND_MIXER_READ_RECMASK, &m->recmask) < 0)
- goto fail;
- if (ioctl(m->fd, SOUND_MIXER_READ_RECSRC, &m->recsrc) < 0)
+ if (ioctl(m->fd, SNDCTL_MIXERINFO, &m->mi) < 0 ||
+ ioctl(m->fd, SNDCTL_CARDINFO, &m->ci) < 0 ||
+ ioctl(m->fd, SOUND_MIXER_READ_DEVMASK, &m->devmask) < 0 ||
+ ioctl(m->fd, SOUND_MIXER_READ_RECMASK, &m->recmask) < 0 ||
+ ioctl(m->fd, SOUND_MIXER_READ_RECSRC, &m->recsrc) < 0)
goto fail;
TAILQ_INIT(&m->devs);
@@ -140,8 +136,8 @@ mixer_close(struct mixer *m)
*
* The caller has to assign the return value to `m->dev`.
*
- * @arg: `name`: device name (e.g vol, pcm, ...)
- * @arg: `flags`: m->devmask / m->recmask / m->recsrc
+ * @param: `name`: device name (e.g vol, pcm, ...)
+ * @param: `flags`: m->devmask / m->recmask / m->recsrc
*/
struct mix_dev *
mixer_seldevbyname(struct mixer *m, const char *name, int flags)
@@ -160,9 +156,14 @@ mixer_seldevbyname(struct mixer *m, const char *name, int flags)
/*
* Change the mixer's left and right volume. The allowed volume values are
- * between M_VOLMIN and M_VOLMAX and are stored as `lvol | rvol << 8`.
+ * between M_VOLMIN and M_VOLMAX. The `ioctl` for volume change requires
+ * an integer value between 0 and 100 stored as `lvol | rvol << 8` -- for
+ * that reason, we de-normalize the 32-bit float volume value, before
+ * we pass it to the `ioctl`.
*
- * TODO update comment
+ * If the volumes passed are not in the range `M_VOLMIN <= vol <= M_VOLMAX`,
+ * we return an error and `errno` is set to ERANGE. Volume clumping should
+ * be handlded by the caller.
*/
int
mixer_chvol(struct mixer *m, float l, float r)
@@ -183,6 +184,27 @@ mixer_chvol(struct mixer *m, float l, float r)
}
/*
+ * TODO: Change panning.
+ *
+ * @param: `pan`: Panning value. It has to be in the range
+ * `M_PANMIN <= pan <= M_PANMAX`.
+ */
+int
+mixer_chpan(struct mixer *m, float pan)
+{
+ int l, r;
+
+ if (pan < M_PANMIN || pan > M_PANMAX) {
+ errno = ERANGE;
+ return (-1);
+ }
+ l = m->dev->lvol;
+ r = m->dev->rvol;
+
+ return (mixer_chvol(m, l, r));
+}
+
+/*
* Modify the mixer's selected device flags. The `recsrc` flag tells
* us if a device is a recording source.
*/
@@ -236,7 +258,7 @@ mixer_get_default_unit(void)
* it's useful to have, so the caller can avoid having to manually use
* the sysctl API.
*
- * @arg: `unit`: the audio card number (e.g pcm0, pcm1, ...).
+ * @param: `unit`: the audio card number (e.g pcm0, pcm1, ...).
*/
int
mixer_set_default_unit(struct mixer *m, int unit)
diff --git a/mixer_lib/mixer.h b/mixer_lib/mixer.h
@@ -42,6 +42,9 @@ __FBSDID("$FreeBSD$");
#define M_VOLNORM(v) ((v) / 100.0f)
#define M_VOLDENORM(v) ((int)roundf((v) * 100.0f))
+#define M_PANMIN (-1.0f)
+#define M_PANMAX 1.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)
@@ -78,7 +81,9 @@ struct mixer {
struct mixer *mixer_open(const char *);
int mixer_close(struct mixer *);
struct mix_dev *mixer_seldevbyname(struct mixer *, const char *, int);
+/* XXX: change names for ch* functions? */
int mixer_chvol(struct mixer *, float, float);
+int mixer_chpan(struct mixer *, float);
int mixer_modrecsrc(struct mixer *, int);
int mixer_get_default_unit(void);
int mixer_set_default_unit(struct mixer *, int);