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