1/*-
2 * Copyright (c) 2021 Christos Margiolis <christos@FreeBSD.org>
3 *
4 * Permission is hereby granted, free of charge, to any person obtaining a copy
5 * of this software and associated documentation files (the "Software"), to deal
6 * in the Software without restriction, including without limitation the rights
7 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
8 * copies of the Software, and to permit persons to whom the Software is
9 * furnished to do so, subject to the following conditions:
10 *
11 * The above copyright notice and this permission notice shall be included in
12 * all copies or substantial portions of the Software.
13 *
14 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
19 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
20 * THE SOFTWARE.
21 */
22
23#ifndef _MIXER_H_
24#define _MIXER_H_
25
26#include <sys/cdefs.h>
27#include <sys/queue.h>
28#include <sys/soundcard.h>
29
30#include <limits.h>
31
32#define MIX_ISSET(n,f)		(((1U << (n)) & (f)) ? 1 : 0)
33#define MIX_ISDEV(m,n)		MIX_ISSET(n, (m)->devmask)
34#define MIX_ISMUTE(m,n)		MIX_ISSET(n, (m)->mutemask)
35#define MIX_ISREC(m,n)		MIX_ISSET(n, (m)->recmask)
36#define MIX_ISRECSRC(m,n)	MIX_ISSET(n, (m)->recsrc)
37
38/* Forward declarations */
39struct mixer;
40struct mix_dev;
41
42typedef struct mix_ctl mix_ctl_t;
43typedef struct mix_volume mix_volume_t;
44
45/* User-defined controls */
46struct mix_ctl {
47	struct mix_dev *parent_dev;		/* parent device */
48	int id;					/* control id */
49	char name[NAME_MAX];			/* control name */
50	int (*mod)(struct mix_dev *, void *);	/* modify control values */
51	int (*print)(struct mix_dev *, void *);	/* print control */
52	TAILQ_ENTRY(mix_ctl) ctls;
53};
54
55struct mix_dev {
56	struct mixer *parent_mixer;		/* parent mixer */
57	char name[NAME_MAX];			/* device name (e.g "vol") */
58	int devno;				/* device number */
59	struct mix_volume {
60#define MIX_VOLMIN		0.0f
61#define MIX_VOLMAX		1.0f
62#define MIX_VOLNORM(v)		((v) / 100.0f)
63#define MIX_VOLDENORM(v)	((int)((v) * 100.0f + 0.5f))
64		float left;			/* left volume */
65		float right;			/* right volume */
66	} vol;
67	int nctl;				/* number of controls */
68	TAILQ_HEAD(mix_ctlhead, mix_ctl) ctls;	/* control list */
69	TAILQ_ENTRY(mix_dev) devs;
70};
71
72struct mixer {
73	TAILQ_HEAD(mix_devhead, mix_dev) devs;	/* device list */
74	struct mix_dev *dev;			/* selected device */
75	oss_mixerinfo mi;			/* mixer info */
76	oss_card_info ci;			/* audio card info */
77	char name[NAME_MAX];			/* mixer name (e.g /dev/mixer0) */
78	int fd;					/* file descriptor */
79	int unit;				/* audio card unit */
80	int ndev;				/* number of devices */
81	int devmask;				/* supported devices */
82#define MIX_MUTE		0x01
83#define MIX_UNMUTE		0x02
84#define MIX_TOGGLEMUTE		0x04
85	int mutemask;				/* muted devices */
86	int recmask;				/* recording devices */
87#define MIX_ADDRECSRC		0x01
88#define MIX_REMOVERECSRC	0x02
89#define MIX_SETRECSRC		0x04
90#define MIX_TOGGLERECSRC	0x08
91	int recsrc;				/* recording sources */
92#define MIX_MODE_MIXER		0x01
93#define MIX_MODE_PLAY		0x02
94#define MIX_MODE_REC		0x04
95	int mode;				/* dev.pcm.X.mode sysctl */
96	int f_default;				/* default mixer flag */
97};
98
99__BEGIN_DECLS
100
101struct mixer *mixer_open(const char *);
102int mixer_close(struct mixer *);
103struct mix_dev *mixer_get_dev(struct mixer *, int);
104struct mix_dev *mixer_get_dev_byname(struct mixer *, const char *);
105int mixer_add_ctl(struct mix_dev *, int, const char *,
106    int (*)(struct mix_dev *, void *), int (*)(struct mix_dev *, void *));
107int mixer_add_ctl_s(mix_ctl_t *);
108int mixer_remove_ctl(mix_ctl_t *);
109mix_ctl_t *mixer_get_ctl(struct mix_dev *, int);
110mix_ctl_t *mixer_get_ctl_byname(struct mix_dev *, const char *);
111int mixer_set_vol(struct mixer *, mix_volume_t);
112int mixer_set_mute(struct mixer *, int);
113int mixer_mod_recsrc(struct mixer *, int);
114int mixer_get_dunit(void);
115int mixer_set_dunit(struct mixer *, int);
116int mixer_get_mode(int);
117int mixer_get_nmixers(void);
118int mixer_get_path(char *, size_t, int);
119
120__END_DECLS
121
122#endif /* _MIXER_H_ */
123