xref: /openbsd-src/usr.bin/sndiod/dev.h (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: dev.h,v 1.11 2016/03/23 06:16:35 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 
24 /*
25  * audio stream state structure
26  */
27 
28 struct slotops
29 {
30 	void (*onmove)(void *);			/* clock tick */
31 	void (*onvol)(void *);	        /* tell client vol changed */
32 	void (*fill)(void *);			/* request to fill a play block */
33 	void (*flush)(void *);			/* request to flush a rec block */
34 	void (*eof)(void *);			/* notify that play drained */
35 	void (*exit)(void *);			/* delete client */
36 };
37 
38 struct slot {
39 	struct slotops *ops;			/* client callbacks */
40 	struct slot *next;			/* next on the play list */
41 	struct dev *dev;			/* device this belongs to */
42 	void *arg;				/* user data for callbacks */
43 	struct aparams par;			/* socket side params */
44 	struct {
45 		int weight;			/* dynamic range */
46 		int maxweight;			/* max dynamic range allowed */
47 		unsigned int vol;		/* volume within the vol */
48 		struct abuf buf;		/* socket side buffer */
49 		int bpf;			/* byte per frame */
50 		int slot_cmin, slot_cmax;	/* slot source chans */
51 		int dev_cmin, dev_cmax;		/* device destination chans */
52 		struct cmap cmap;		/* channel mapper state */
53 		struct resamp resamp;		/* resampler state */
54 		struct conv dec;		/* format decoder params */
55 		int join;			/* channel join factor */
56 		int expand;			/* channel expand factor */
57 		void *resampbuf, *decbuf;	/* tmp buffers */
58 	} mix;
59 	struct {
60 		struct abuf buf;		/* socket side buffer */
61 		int prime;			/* initial cycles to skip */
62 		int bpf;			/* byte per frame */
63 		int slot_cmin, slot_cmax;	/* slot destination chans */
64 		int dev_cmin, dev_cmax;		/* device source chans */
65 		struct cmap cmap;		/* channel mapper state */
66 		struct resamp resamp;		/* buffer for resampling */
67 		struct conv enc;		/* buffer for encoding */
68 		int join;			/* channel join factor */
69 		int expand;			/* channel expand factor */
70 		void *resampbuf, *encbuf;	/* tmp buffers */
71 	} sub;
72 	int xrun;				/* underrun policy */
73 	int skip;				/* cycles to skip (for xrun) */
74 	int dup;				/* mono-to-stereo and alike */
75 #define SLOT_BUFSZ(s) \
76 	((s)->appbufsz + (s)->dev->bufsz / (s)->dev->round * (s)->round)
77 	int appbufsz;				/* slot-side buffer size */
78 	int round;				/* slot-side block size */
79 	int rate;				/* slot-side sample rate */
80 	int delta;				/* pending clock ticks */
81 	int delta_rem;				/* remainder for delta */
82 	int mode;				/* MODE_{PLAY,REC} */
83 #define SLOT_INIT	0			/* not trying to do anything */
84 #define SLOT_START	1			/* buffer allocated */
85 #define SLOT_READY	2			/* buffer filled enough */
86 #define SLOT_RUN	3			/* buffer attached to device */
87 #define SLOT_STOP	4			/* draining */
88 	int pstate;
89 
90 #define SLOT_NAMEMAX	8
91 	char name[SLOT_NAMEMAX];		/* name matching [a-z]+ */
92 	unsigned int unit;			/* instance of name */
93 	unsigned int serial;			/* global unique number */
94 	unsigned int vol;			/* current (midi) volume */
95 	unsigned int tstate;			/* mmc state */
96 };
97 
98 /*
99  * audio device with plenty of slots
100  */
101 struct dev {
102 	struct dev *next;
103 	struct slot *slot_list;			/* audio streams attached */
104 	struct midi *midi;
105 
106 	/*
107 	 * audio device (while opened)
108 	 */
109 	struct dev_sio sio;
110 	struct aparams par;			/* encoding */
111 	int pchan, rchan;			/* play & rec channels */
112 	adata_t *rbuf;				/* rec buffer */
113 	adata_t *pbuf;				/* array of play buffers */
114 #define DEV_PBUF(d) ((d)->pbuf + (d)->poffs * (d)->pchan)
115 	int poffs;				/* index of current play buf */
116 	int psize;				/* size of play buffer */
117 	struct conv enc;			/* native->device format */
118 	struct conv dec;			/* device->native format */
119 	unsigned char *encbuf;			/* buffer for encoding */
120 	unsigned char *decbuf;			/* buffer for decoding */
121 
122 	/*
123 	 * preallocated audio sub-devices
124 	 */
125 #define DEV_NSLOT	8
126 	struct slot slot[DEV_NSLOT];
127 	unsigned int serial;			/* for slot allocation */
128 
129 	/*
130 	 * current position, relative to the current cycle
131 	 */
132 	int delta;
133 
134 	/*
135 	 * desired parameters
136 	 */
137 	unsigned int reqmode;			/* mode */
138 	struct aparams reqpar;			/* parameters */
139 	int reqpchan, reqrchan;			/* play & rec chans */
140 	unsigned int reqbufsz;			/* buffer size */
141 	unsigned int reqround;			/* block size */
142 	unsigned int reqrate;			/* sample rate */
143 	unsigned int hold;			/* hold the device open ? */
144 	unsigned int autovol;			/* auto adjust playvol ? */
145 	unsigned int refcnt;			/* number of openers */
146 #define DEV_NMAX	16			/* max number of devices */
147 	unsigned int num;			/* device serial number */
148 #define DEV_CFG		0			/* closed */
149 #define DEV_INIT	1			/* stopped */
150 #define DEV_RUN		2			/* playin & recording */
151 	unsigned int pstate;			/* one of above */
152 	char *path;				/* sio path */
153 
154 	/*
155 	 * actual parameters and runtime state (i.e. once opened)
156 	 */
157 	unsigned int mode;			/* bitmap of MODE_xxx */
158 	unsigned int bufsz, round, rate;
159 	unsigned int prime;
160 
161 	/*
162 	 * MIDI time code (MTC)
163 	 */
164 	struct {
165 		unsigned int origin;		/* MTC start time */
166 		unsigned int fps;		/* MTC frames per second */
167 #define MTC_FPS_24	0
168 #define MTC_FPS_25	1
169 #define MTC_FPS_30	3
170 		unsigned int fps_id;		/* one of above */
171 		unsigned int hr;		/* MTC hours */
172 		unsigned int min;		/* MTC minutes */
173 		unsigned int sec;		/* MTC seconds */
174 		unsigned int fr;		/* MTC frames */
175 		unsigned int qfr;		/* MTC quarter frames */
176 		int delta;			/* rel. to the last MTC tick */
177 		int refs;
178 	} mtc;
179 
180 	/*
181 	 * MIDI machine control (MMC)
182 	 */
183 #define MMC_OFF		0			/* ignore MMC messages */
184 #define MMC_STOP	1			/* stopped, can't start */
185 #define MMC_START	2			/* attempting to start */
186 #define MMC_RUN		3			/* started */
187 	unsigned int tstate;			/* one of above */
188 	unsigned int master;			/* master volume controller */
189 };
190 
191 extern struct dev *dev_list;
192 
193 void dev_log(struct dev *);
194 void dev_close(struct dev *);
195 struct dev *dev_new(char *, struct aparams *, unsigned int, unsigned int,
196     unsigned int, unsigned int, unsigned int, unsigned int);
197 struct dev *dev_bynum(int);
198 void dev_del(struct dev *);
199 void dev_adjpar(struct dev *, int, int, int);
200 int  dev_init(struct dev *);
201 void dev_done(struct dev *);
202 int dev_ref(struct dev *);
203 void dev_unref(struct dev *);
204 int  dev_getpos(struct dev *);
205 unsigned int dev_roundof(struct dev *, unsigned int);
206 
207 /*
208  * interface to hardware device
209  */
210 void dev_onmove(struct dev *, int);
211 void dev_cycle(struct dev *);
212 
213 /*
214  * midi & midi call-backs
215  */
216 void dev_mmcstart(struct dev *);
217 void dev_mmcstop(struct dev *);
218 void dev_mmcloc(struct dev *, unsigned int);
219 void dev_master(struct dev *, unsigned int);
220 void dev_midi_vol(struct dev *, struct slot *);
221 
222 /*
223  * sio_open(3) like interface for clients
224  */
225 void slot_log(struct slot *);
226 struct slot *slot_new(struct dev *, char *, struct slotops *, void *, int);
227 void slot_del(struct slot *);
228 void slot_setvol(struct slot *, unsigned int);
229 void slot_start(struct slot *);
230 void slot_stop(struct slot *);
231 void slot_read(struct slot *);
232 void slot_write(struct slot *);
233 
234 #endif /* !defined(DEV_H) */
235