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 27b0d8918fc7ac9d9acf6ab626f836096d40d8d0
parent 62ae192d6951bf184b9a51e55b7e607b32eb53f2
Author: Christos Margiolis <christos@margiolis.net>
Date:   Sat, 31 Jul 2021 18:32:53 +0300

removed mixer_make_ctl and minor fixed in mixer(8)

Diffstat:
Mmixer_lib/mixer.c | 30+++++++-----------------------
Mmixer_lib/mixer.h | 55+++++++++++++++++++++++++++----------------------------
Mmixer_prog/mixer_prog.c | 53++++++++++++++++++++++++++++-------------------------
3 files changed, 62 insertions(+), 76 deletions(-)

diff --git a/mixer_lib/mixer.c b/mixer_lib/mixer.c @@ -208,40 +208,23 @@ mixer_get_dev_byname(struct mixer *m, const char *name) } /* - * Make a mixer control. + * Add a mixer control to a device by passing all fields as arguments. */ -mix_ctl_t * -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)) +int +mixer_add_ctl(struct mix_dev *parent_dev, int id, const char *name, + int (*mod)(struct mix_dev *, void *), + int (*print)(struct mix_dev *, void *)) { mix_ctl_t *ctl; - /* XXX: do not alloc? */ if ((ctl = calloc(1, sizeof(mix_ctl_t))) == NULL) - return (NULL); + return (-1); ctl->parent_dev = parent_dev; ctl->id = id; if (name != NULL) (void)strlcpy(ctl->name, name, sizeof(ctl->name)); ctl->mod = mod; ctl->print = print; - - return (ctl); -} - -/* - * Add a mixer control to a device by passing all fields as arguments. - */ -int -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(parent_dev, id, name, mod, print)) == NULL) - return (-1); return (mixer_add_ctl_s(ctl)); } @@ -449,6 +432,7 @@ mixer_set_dunit(struct mixer *m, int unit) size = sizeof(int); if (sysctlbyname("hw.snd.default_unit", NULL, 0, &unit, size) < 0) return (-1); + /* XXX: how will other mixers get updated? */ m->f_default = m->unit == unit; return (0); diff --git a/mixer_lib/mixer.h b/mixer_lib/mixer.h @@ -47,65 +47,64 @@ struct mix_dev; typedef struct mix_ctl mix_ctl_t; typedef struct mix_volume mix_volume_t; +/* User-defined controls */ struct mix_ctl { - struct mix_dev *parent_dev; - int id; - char name[NAME_MAX]; - int (*mod)(struct mix_dev *, void *); - int (*print)(struct mix_dev *, void *); + struct mix_dev *parent_dev; /* parent device */ + int id; /* control id */ + char name[NAME_MAX]; /* control name */ + int (*mod)(struct mix_dev *, void *); /* modify control values */ + int (*print)(struct mix_dev *, void *); /* print control */ TAILQ_ENTRY(mix_ctl) ctls; }; struct mix_dev { - struct mixer *parent_mixer; - char name[NAME_MAX]; - int devno; + struct mixer *parent_mixer; /* parent mixer */ + char name[NAME_MAX]; /* device name (e.g "vol") */ + int devno; /* device number */ struct mix_volume { #define MIX_VOLMIN 0.0f #define MIX_VOLMAX 1.0f #define MIX_VOLNORM(v) ((v) / 100.0f) #define MIX_VOLDENORM(v) ((int)roundf((v) * 100.0f)) - float left; - float right; + float left; /* left volume */ + float right; /* right volume */ } vol; - int nctl; - TAILQ_HEAD(, mix_ctl) ctls; + int nctl; /* number of controls */ + TAILQ_HEAD(, mix_ctl) ctls; /* control list */ TAILQ_ENTRY(mix_dev) devs; }; struct mixer { - TAILQ_HEAD(, mix_dev) devs; - struct mix_dev *dev; - oss_mixerinfo mi; - oss_card_info ci; - char name[NAME_MAX]; - int fd; - int unit; - int ndev; - int devmask; + TAILQ_HEAD(, mix_dev) devs; /* device list */ + struct mix_dev *dev; /* selected device */ + oss_mixerinfo mi; /* mixer info */ + oss_card_info ci; /* audio card info */ + char name[NAME_MAX]; /* mixer name (e.g /dev/mixer0) */ + int fd; /* file descriptor */ + int unit; /* audio card unit */ + int ndev; /* number of devices */ + int devmask; /* valid devices */ #define MIX_MUTE 0x01 #define MIX_UNMUTE 0x02 #define MIX_TOGGLEMUTE 0x04 - int mutemask; - int recmask; + int mutemask; /* muted devices */ + int recmask; /* recording devices */ #define MIX_ADDRECSRC 0x01 #define MIX_REMOVERECSRC 0x02 #define MIX_SETRECSRC 0x04 #define MIX_TOGGLERECSRC 0x08 - int recsrc; - int f_default; + int recsrc; /* recording sources */ + int f_default; /* default mixer flag */ #define MIX_MODE_MIXER 0x01 #define MIX_MODE_PLAY 0x02 #define MIX_MODE_REC 0x04 - int mode; + int mode; /* dev.pcm.X.mode sysctl */ }; 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(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 mix_dev *, void *), int (*)(struct mix_dev *, void *)); int mixer_add_ctl_s(mix_ctl_t *); diff --git a/mixer_prog/mixer_prog.c b/mixer_prog/mixer_prog.c @@ -29,24 +29,28 @@ #include <mixer.h> -#define LEN(x) (sizeof(x) / sizeof(x[0])) - -static void usage(void) __dead2; -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); /* XXX: change name */ +static void usage(void) __dead2; +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); /* XXX: change name */ /* Control handlers */ -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; +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 const mix_ctl_t ctl_dunit = { + .parent_dev = NULL, + .id = -1, + .name = "default_unit", + .mod = mod_dunit, + .print = NULL +}; int main(int argc, char *argv[]) @@ -113,7 +117,7 @@ main(int argc, char *argv[]) initctls(m); - if (dflag && ctl_dunit->mod(ctl_dunit->parent_dev, &dunit) < 0) + if (dflag && ctl_dunit.mod(m->dev, &dunit) < 0) goto parse; if (sflag) { printrecsrc(m, oflag); @@ -187,7 +191,6 @@ 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(NULL, -1, "default_unit", mod_dunit, NULL); } static void @@ -248,7 +251,6 @@ printdev(struct mixer *m, int oflag) } } -/* TODO: -o option .recsrc */ static void printrecsrc(struct mixer *m, int oflag) { @@ -257,14 +259,15 @@ printrecsrc(struct mixer *m, int oflag) if (!m->recmask) return; - printminfo(m, oflag); if (!oflag) - printf(" recording source(s): "); + printf("%s: ", m->mi.name); TAILQ_FOREACH(dp, &m->devs, devs) { if (MIX_ISRECSRC(m, dp->devno)) { - if (n++) - printf("%s ", oflag ? " " : ", "); + if (n++ && !oflag) + printf(", "); printf("%s", dp->name); + if (oflag) + printf(".recsrc=+%s", n ? " " : ""); } } printf("\n"); @@ -284,7 +287,7 @@ mod_dunit(struct mix_dev *d, void *p) warn("cannot set default unit to: %d", dunit); return (-1); } - printf("%s: %d -> %d\n", ctl_dunit->name, n, dunit); + printf("%s: %d -> %d\n", ctl_dunit.name, n, dunit); return (0); }