xref: /openbsd/usr.bin/sndiod/dev.h (revision 73471bf0)
1 /*	$OpenBSD: dev.h,v 1.41 2021/11/01 14:43:25 ratchov Exp $	*/
2 /*
3  * Copyright (c) 2008-2012 Alexandre Ratchov <alex@caoua.org>
4  *
5  * Permission to use, copy, modify, and distribute this software for any
6  * purpose with or without fee is hereby granted, provided that the above
7  * copyright notice and this permission notice appear in all copies.
8  *
9  * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10  * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11  * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12  * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13  * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14  * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15  * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16  */
17 #ifndef DEV_H
18 #define DEV_H
19 
20 #include "abuf.h"
21 #include "dsp.h"
22 #include "siofile.h"
23 #include "dev_sioctl.h"
24 #include "opt.h"
25 
26 /*
27  * preallocated audio clients
28  */
29 #define DEV_NSLOT	8
30 
31 /*
32  * preallocated control clients
33  */
34 #define DEV_NCTLSLOT 8
35 
36 /*
37  * audio stream state structure
38  */
39 
40 struct slotops
41 {
42 	void (*onmove)(void *);			/* clock tick */
43 	void (*onvol)(void *);			/* tell client vol changed */
44 	void (*fill)(void *);			/* request to fill a play block */
45 	void (*flush)(void *);			/* request to flush a rec block */
46 	void (*eof)(void *);			/* notify that play drained */
47 	void (*exit)(void *);			/* delete client */
48 };
49 
50 struct ctlops
51 {
52 	void (*exit)(void *);			/* delete client */
53 	void (*sync)(void *);			/* description ready */
54 };
55 
56 struct slot {
57 	struct slotops *ops;			/* client callbacks */
58 	struct slot *next;			/* next on the play list */
59 	struct opt *opt;			/* config used */
60 	void *arg;				/* user data for callbacks */
61 	struct aparams par;			/* socket side params */
62 	struct {
63 		int weight;			/* dynamic range */
64 		unsigned int vol;		/* volume within the vol */
65 		struct abuf buf;		/* socket side buffer */
66 		int bpf;			/* byte per frame */
67 		int nch;			/* number of play chans */
68 		struct cmap cmap;		/* channel mapper state */
69 		struct resamp resamp;		/* resampler state */
70 		struct conv dec;		/* format decoder params */
71 		int join;			/* channel join factor */
72 		int expand;			/* channel expand factor */
73 		void *resampbuf, *decbuf;	/* tmp buffers */
74 	} mix;
75 	struct {
76 		struct abuf buf;		/* socket side buffer */
77 		int prime;			/* initial cycles to skip */
78 		int bpf;			/* byte per frame */
79 		int nch;			/* number of rec chans */
80 		struct cmap cmap;		/* channel mapper state */
81 		struct resamp resamp;		/* buffer for resampling */
82 		struct conv enc;		/* buffer for encoding */
83 		int join;			/* channel join factor */
84 		int expand;			/* channel expand factor */
85 		void *resampbuf, *encbuf;	/* tmp buffers */
86 	} sub;
87 	int xrun;				/* underrun policy */
88 	int skip;				/* cycles to skip (for xrun) */
89 #define SLOT_BUFSZ(s) \
90 	((s)->appbufsz + (s)->opt->dev->bufsz / (s)->opt->dev->round * (s)->round)
91 	int appbufsz;				/* slot-side buffer size */
92 	int round;				/* slot-side block size */
93 	int rate;				/* slot-side sample rate */
94 	int delta;				/* pending clock ticks */
95 	int delta_rem;				/* remainder for delta */
96 	int mode;				/* MODE_{PLAY,REC} */
97 #define SLOT_INIT	0			/* not trying to do anything */
98 #define SLOT_START	1			/* buffer allocated */
99 #define SLOT_READY	2			/* buffer filled enough */
100 #define SLOT_RUN	3			/* buffer attached to device */
101 #define SLOT_STOP	4			/* draining */
102 	int pstate;
103 
104 #define SLOT_NAMEMAX	8
105 	char name[SLOT_NAMEMAX];		/* name matching [a-z]+ */
106 	unsigned int unit;			/* instance of name */
107 	unsigned int serial;			/* global unique number */
108 	unsigned int vol;			/* current (midi) volume */
109 	unsigned int id;			/* process id */
110 };
111 
112 /*
113  * subset of channels of a stream
114  */
115 
116 struct ctl {
117 	struct ctl *next;
118 
119 #define CTL_NONE	0		/* deleted */
120 #define CTL_NUM		2		/* number (aka integer value) */
121 #define CTL_SW		3		/* on/off switch, only bit 7 counts */
122 #define CTL_VEC		4		/* number, element of vector */
123 #define CTL_LIST	5		/* switch, element of a list */
124 #define CTL_SEL		6		/* element of a selector */
125 	unsigned int type;		/* one of above */
126 
127 #define CTL_HW		0
128 #define CTL_DEV_MASTER	1
129 #define CTL_OPT_DEV	2
130 #define CTL_SLOT_LEVEL	3
131 	unsigned int scope;
132 	union {
133 		struct {
134 			void *arg0;
135 			void *arg1;
136 		} any;
137 		struct {
138 			struct dev *dev;
139 			unsigned int addr;
140 		} hw;
141 		struct {
142 			struct dev *dev;
143 		} dev_master;
144 		struct {
145 			struct slot *slot;
146 		} slot_level;
147 		struct {
148 			struct slot *slot;
149 			struct opt *opt;
150 		} slot_opt;
151 		struct {
152 			struct opt *opt;
153 			struct dev *dev;
154 		} opt_dev;
155 	} u;
156 
157 	unsigned int addr;		/* slot side control address */
158 #define CTL_NAMEMAX	16		/* max name lenght */
159 	char func[CTL_NAMEMAX];		/* parameter function name */
160 	char group[CTL_NAMEMAX];	/* group aka namespace */
161 	struct ctl_node {
162 		char name[CTL_NAMEMAX];	/* stream name */
163 		int unit;
164 	} node0, node1;			/* affected channels */
165 #define CTL_DEVMASK		(1 << 31)
166 #define CTL_SLOTMASK(i)		(1 << (i))
167 	unsigned int val_mask;
168 	unsigned int desc_mask;
169 	unsigned int refs_mask;
170 	unsigned int maxval;
171 	unsigned int curval;
172 	int dirty;
173 };
174 
175 struct ctlslot {
176 	struct ctlops *ops;
177 	void *arg;
178 	struct opt *opt;
179 	unsigned int self;		/* equal to (1 << index) */
180 	unsigned int mode;
181 };
182 
183 /*
184  * MIDI time code (MTC)
185  */
186 struct mtc {
187 	/*
188 	 * MIDI time code (MTC) states
189 	 */
190 #define MTC_STOP	1		/* stopped, can't start */
191 #define MTC_START	2		/* attempting to start */
192 #define MTC_RUN		3		/* started */
193 	unsigned int tstate;		/* one of MTC_* constants */
194 	struct dev *dev;
195 
196 	unsigned int origin;		/* MTC start time */
197 	unsigned int fps;		/* MTC frames per second */
198 #define MTC_FPS_24	0
199 #define MTC_FPS_25	1
200 #define MTC_FPS_30	3
201 	unsigned int fps_id;		/* one of above */
202 	unsigned int hr;		/* MTC hours */
203 	unsigned int min;		/* MTC minutes */
204 	unsigned int sec;		/* MTC seconds */
205 	unsigned int fr;		/* MTC frames */
206 	unsigned int qfr;		/* MTC quarter frames */
207 	int delta;			/* rel. to the last MTC tick */
208 	int refs;
209 };
210 
211 /*
212  * audio device with plenty of slots
213  */
214 struct dev {
215 	struct dev *next;
216 	struct slot *slot_list;			/* audio streams attached */
217 
218 	/*
219 	 * name used for various controls
220 	 */
221 	char name[CTL_NAMEMAX];
222 
223 	/*
224 	 * next to try if this fails
225 	 */
226 	struct dev *alt_next;
227 
228 	/*
229 	 * audio device (while opened)
230 	 */
231 	struct dev_sio sio;
232 	struct dev_sioctl sioctl;
233 	struct aparams par;			/* encoding */
234 	int pchan, rchan;			/* play & rec channels */
235 	adata_t *rbuf;				/* rec buffer */
236 	adata_t *pbuf;				/* array of play buffers */
237 #define DEV_PBUF(d) ((d)->pbuf + (d)->poffs * (d)->pchan)
238 	int poffs;				/* index of current play buf */
239 	int psize;				/* size of play buffer */
240 	struct conv enc;			/* native->device format */
241 	struct conv dec;			/* device->native format */
242 	unsigned char *encbuf;			/* buffer for encoding */
243 	unsigned char *decbuf;			/* buffer for decoding */
244 
245 	/*
246 	 * current position, relative to the current cycle
247 	 */
248 	int delta;
249 
250 	/*
251 	 * desired parameters
252 	 */
253 	unsigned int reqmode;			/* mode */
254 	struct aparams reqpar;			/* parameters */
255 	int reqpchan, reqrchan;			/* play & rec chans */
256 	unsigned int reqbufsz;			/* buffer size */
257 	unsigned int reqround;			/* block size */
258 	unsigned int reqrate;			/* sample rate */
259 	unsigned int hold;			/* hold the device open ? */
260 	unsigned int autovol;			/* auto adjust playvol ? */
261 	unsigned int refcnt;			/* number of openers */
262 #define DEV_NMAX	16			/* max number of devices */
263 	unsigned int num;			/* device serial number */
264 #define DEV_CFG		0			/* closed */
265 #define DEV_INIT	1			/* stopped */
266 #define DEV_RUN		2			/* playin & recording */
267 	unsigned int pstate;			/* one of above */
268 	char *path;
269 
270 	/*
271 	 * actual parameters and runtime state (i.e. once opened)
272 	 */
273 	unsigned int mode;			/* bitmap of MODE_xxx */
274 	unsigned int bufsz, round, rate;
275 	unsigned int prime;
276 
277 	unsigned int master;			/* software vol. knob */
278 	unsigned int master_enabled;		/* 1 if h/w has no vo. knob */
279 };
280 
281 extern struct dev *dev_list;
282 extern struct ctl *ctl_list;
283 extern struct slot slot_array[DEV_NSLOT];
284 extern struct ctlslot ctlslot_array[DEV_NCTLSLOT];
285 extern struct mtc mtc_array[1];
286 
287 void slot_array_init(void);
288 
289 void dev_log(struct dev *);
290 int dev_open(struct dev *);
291 void dev_close(struct dev *);
292 void dev_abort(struct dev *);
293 struct dev *dev_migrate(struct dev *);
294 struct dev *dev_new(char *, struct aparams *, unsigned int, unsigned int,
295     unsigned int, unsigned int, unsigned int, unsigned int);
296 struct dev *dev_bynum(int);
297 void dev_del(struct dev *);
298 void dev_adjpar(struct dev *, int, int, int);
299 int  dev_init(struct dev *);
300 void dev_done(struct dev *);
301 int dev_ref(struct dev *);
302 void dev_unref(struct dev *);
303 int  dev_getpos(struct dev *);
304 unsigned int dev_roundof(struct dev *, unsigned int);
305 int dev_iscompat(struct dev *, struct dev *);
306 
307 /*
308  * interface to hardware device
309  */
310 void dev_onmove(struct dev *, int);
311 void dev_cycle(struct dev *);
312 
313 /*
314  * midi & midi call-backs
315  */
316 void dev_master(struct dev *, unsigned int);
317 void dev_midi_send(struct dev *, void *, int);
318 void dev_midi_vol(struct dev *, struct slot *);
319 void dev_midi_master(struct dev *);
320 void dev_midi_slotdesc(struct dev *, struct slot *);
321 void dev_midi_dump(struct dev *);
322 
323 void mtc_midi_qfr(struct mtc *, int);
324 void mtc_midi_full(struct mtc *);
325 void mtc_trigger(struct mtc *);
326 void mtc_start(struct mtc *);
327 void mtc_stop(struct mtc *);
328 void mtc_loc(struct mtc *, unsigned int);
329 void mtc_setdev(struct mtc *, struct dev *);
330 
331 /*
332  * sio_open(3) like interface for clients
333  */
334 void slot_log(struct slot *);
335 struct slot *slot_new(struct opt *, unsigned int, char *,
336     struct slotops *, void *, int);
337 void slot_del(struct slot *);
338 void slot_setvol(struct slot *, unsigned int);
339 void slot_setopt(struct slot *, struct opt *);
340 void slot_start(struct slot *);
341 void slot_stop(struct slot *, int);
342 void slot_read(struct slot *);
343 void slot_write(struct slot *);
344 void slot_initconv(struct slot *);
345 void slot_attach(struct slot *);
346 void slot_detach(struct slot *);
347 
348 /*
349  * control related functions
350  */
351 
352 struct ctl *ctl_new(int, void *, void *,
353     int, char *, char *, int, char *, char *, int, int, int);
354 void ctl_del(int, void *, void *);
355 void ctl_log(struct ctl *);
356 int ctl_setval(struct ctl *c, int val);
357 int ctl_match(struct ctl *, int, void *, void *);
358 struct ctl *ctl_find(int, void *, void *);
359 void ctl_update(struct ctl *);
360 int ctl_onval(int, void *, void *, int);
361 
362 struct ctlslot *ctlslot_new(struct opt *, struct ctlops *, void *);
363 void ctlslot_del(struct ctlslot *);
364 int ctlslot_visible(struct ctlslot *, struct ctl *);
365 struct ctl *ctlslot_lookup(struct ctlslot *, int);
366 void ctlslot_update(struct ctlslot *);
367 
368 void dev_label(struct dev *, int);
369 void dev_ctlsync(struct dev *);
370 
371 #endif /* !defined(DEV_H) */
372