xref: /openbsd-src/usr.bin/sndiod/dev.c (revision f2da64fbbbf1b03f09f390ab01267c93dfd77c4c)
1 /*	$OpenBSD: dev.c,v 1.26 2016/05/25 05:34:23 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 #include <stdio.h>
18 #include <string.h>
19 
20 #include "abuf.h"
21 #include "defs.h"
22 #include "dev.h"
23 #include "dsp.h"
24 #include "siofile.h"
25 #include "midi.h"
26 #include "sysex.h"
27 #include "utils.h"
28 
29 void zomb_onmove(void *);
30 void zomb_onvol(void *);
31 void zomb_fill(void *);
32 void zomb_flush(void *);
33 void zomb_eof(void *);
34 void zomb_exit(void *);
35 
36 void dev_log(struct dev *);
37 void dev_midi_qfr(struct dev *, int);
38 void dev_midi_full(struct dev *);
39 void dev_midi_vol(struct dev *, struct slot *);
40 void dev_midi_master(struct dev *);
41 void dev_midi_slotdesc(struct dev *, struct slot *);
42 void dev_midi_dump(struct dev *);
43 void dev_midi_imsg(void *, unsigned char *, int);
44 void dev_midi_omsg(void *, unsigned char *, int);
45 void dev_midi_fill(void *, int);
46 void dev_midi_exit(void *);
47 
48 int play_filt_resamp(struct slot *, void *, void *, int);
49 int play_filt_dec(struct slot *, void *, void *, int);
50 void dev_mix_badd(struct dev *, struct slot *);
51 void dev_mix_adjvol(struct dev *);
52 int rec_filt_resamp(struct slot *, void *, void *, int);
53 int rec_filt_enc(struct slot *, void *, void *, int);
54 void dev_sub_bcopy(struct dev *, struct slot *);
55 
56 void dev_onmove(struct dev *, int);
57 void dev_master(struct dev *, unsigned int);
58 void dev_cycle(struct dev *);
59 int dev_getpos(struct dev *);
60 struct dev *dev_new(char *, struct aparams *, unsigned int, unsigned int,
61     unsigned int, unsigned int, unsigned int, unsigned int);
62 void dev_adjpar(struct dev *, int, int, int);
63 int dev_open(struct dev *);
64 void dev_close(struct dev *);
65 int dev_ref(struct dev *);
66 void dev_unref(struct dev *);
67 int dev_init(struct dev *);
68 void dev_done(struct dev *);
69 struct dev *dev_bynum(int);
70 void dev_del(struct dev *);
71 unsigned int dev_roundof(struct dev *, unsigned int);
72 void dev_wakeup(struct dev *);
73 void dev_sync_attach(struct dev *);
74 void dev_mmcstart(struct dev *);
75 void dev_mmcstop(struct dev *);
76 void dev_mmcloc(struct dev *, unsigned int);
77 
78 void slot_log(struct slot *);
79 struct slot *slot_new(struct dev *, char *, struct slotops *, void *, int);
80 void slot_del(struct slot *);
81 void slot_setvol(struct slot *, unsigned int);
82 void slot_attach(struct slot *);
83 void slot_ready(struct slot *);
84 void slot_start(struct slot *);
85 void slot_detach(struct slot *);
86 void slot_stop(struct slot *);
87 void slot_skip_update(struct slot *);
88 void slot_write(struct slot *);
89 void slot_read(struct slot *);
90 int slot_skip(struct slot *);
91 
92 struct midiops dev_midiops = {
93 	dev_midi_imsg,
94 	dev_midi_omsg,
95 	dev_midi_fill,
96 	dev_midi_exit
97 };
98 
99 struct slotops zomb_slotops = {
100 	zomb_onmove,
101 	zomb_onvol,
102 	zomb_fill,
103 	zomb_flush,
104 	zomb_eof,
105 	zomb_exit
106 };
107 
108 struct dev *dev_list = NULL;
109 unsigned int dev_sndnum = 0;
110 
111 void
112 dev_log(struct dev *d)
113 {
114 #ifdef DEBUG
115 	static char *pstates[] = {
116 		"cfg", "ini", "run"
117 	};
118 #endif
119 	log_puts("snd");
120 	log_putu(d->num);
121 #ifdef DEBUG
122 	if (log_level >= 3) {
123 		log_puts(" pst=");
124 		log_puts(pstates[d->pstate]);
125 	}
126 #endif
127 }
128 
129 void
130 slot_log(struct slot *s)
131 {
132 #ifdef DEBUG
133 	static char *pstates[] = {
134 		"ini", "sta", "rdy", "run", "stp", "mid"
135 	};
136 	static char *tstates[] = {
137 		"off", "sta", "run", "stp"
138 	};
139 #endif
140 	log_puts(s->name);
141 	log_putu(s->unit);
142 #ifdef DEBUG
143 	if (log_level >= 3) {
144 		log_puts(" vol=");
145 		log_putu(s->vol);
146 		if (s->ops) {
147 			log_puts(",pst=");
148 			log_puts(pstates[s->pstate]);
149 			log_puts(",mmc=");
150 			log_puts(tstates[s->tstate]);
151 		}
152 	}
153 #endif
154 }
155 
156 void
157 zomb_onmove(void *arg)
158 {
159 }
160 
161 void
162 zomb_onvol(void *arg)
163 {
164 }
165 
166 void
167 zomb_fill(void *arg)
168 {
169 }
170 
171 void
172 zomb_flush(void *arg)
173 {
174 }
175 
176 void
177 zomb_eof(void *arg)
178 {
179 	struct slot *s = arg;
180 
181 #ifdef DEBUG
182 	if (log_level >= 3) {
183 		slot_log(s);
184 		log_puts(": zomb_eof\n");
185 	}
186 #endif
187 	s->ops = NULL;
188 }
189 
190 void
191 zomb_exit(void *arg)
192 {
193 #ifdef DEBUG
194 	struct slot *s = arg;
195 
196 	if (log_level >= 3) {
197 		slot_log(s);
198 		log_puts(": zomb_exit\n");
199 	}
200 #endif
201 }
202 
203 /*
204  * send a quarter frame MTC message
205  */
206 void
207 dev_midi_qfr(struct dev *d, int delta)
208 {
209 	unsigned char buf[2];
210 	unsigned int data;
211 	int qfrlen;
212 
213 	d->mtc.delta += delta * MTC_SEC;
214 	qfrlen = d->rate * (MTC_SEC / (4 * d->mtc.fps));
215 	while (d->mtc.delta >= qfrlen) {
216 		switch (d->mtc.qfr) {
217 		case 0:
218 			data = d->mtc.fr & 0xf;
219 			break;
220 		case 1:
221 			data = d->mtc.fr >> 4;
222 			break;
223 		case 2:
224 			data = d->mtc.sec & 0xf;
225 			break;
226 		case 3:
227 			data = d->mtc.sec >> 4;
228 			break;
229 		case 4:
230 			data = d->mtc.min & 0xf;
231 			break;
232 		case 5:
233 			data = d->mtc.min >> 4;
234 			break;
235 		case 6:
236 			data = d->mtc.hr & 0xf;
237 			break;
238 		case 7:
239 			data = (d->mtc.hr >> 4) | (d->mtc.fps_id << 1);
240 			/*
241 			 * tick messages are sent 2 frames ahead
242 			 */
243 			d->mtc.fr += 2;
244 			if (d->mtc.fr < d->mtc.fps)
245 				break;
246 			d->mtc.fr -= d->mtc.fps;
247 			d->mtc.sec++;
248 			if (d->mtc.sec < 60)
249 				break;
250 			d->mtc.sec = 0;
251 			d->mtc.min++;
252 			if (d->mtc.min < 60)
253 				break;
254 			d->mtc.min = 0;
255 			d->mtc.hr++;
256 			if (d->mtc.hr < 24)
257 				break;
258 			d->mtc.hr = 0;
259 			break;
260 		default:
261 			/* NOTREACHED */
262 			data = 0;
263 		}
264 		buf[0] = 0xf1;
265 		buf[1] = (d->mtc.qfr << 4) | data;
266 		d->mtc.qfr++;
267 		d->mtc.qfr &= 7;
268 		midi_send(d->midi, buf, 2);
269 		d->mtc.delta -= qfrlen;
270 	}
271 }
272 
273 /*
274  * send a full frame MTC message
275  */
276 void
277 dev_midi_full(struct dev *d)
278 {
279 	struct sysex x;
280 	unsigned int fps;
281 
282 	d->mtc.delta = MTC_SEC * dev_getpos(d);
283 	if (d->rate % (30 * 4 * d->round) == 0) {
284 		d->mtc.fps_id = MTC_FPS_30;
285 		d->mtc.fps = 30;
286 	} else if (d->rate % (25 * 4 * d->round) == 0) {
287 		d->mtc.fps_id = MTC_FPS_25;
288 		d->mtc.fps = 25;
289 	} else {
290 		d->mtc.fps_id = MTC_FPS_24;
291 		d->mtc.fps = 24;
292 	}
293 #ifdef DEBUG
294 	if (log_level >= 3) {
295 		dev_log(d);
296 		log_puts(": mtc full frame at ");
297 		log_puti(d->mtc.delta);
298 		log_puts(", ");
299 		log_puti(d->mtc.fps);
300 		log_puts(" fps\n");
301 	}
302 #endif
303 	fps = d->mtc.fps;
304 	d->mtc.hr =  (d->mtc.origin / (MTC_SEC * 3600)) % 24;
305 	d->mtc.min = (d->mtc.origin / (MTC_SEC * 60))   % 60;
306 	d->mtc.sec = (d->mtc.origin / (MTC_SEC))        % 60;
307 	d->mtc.fr =  (d->mtc.origin / (MTC_SEC / fps))  % fps;
308 
309 	x.start = SYSEX_START;
310 	x.type = SYSEX_TYPE_RT;
311 	x.dev = SYSEX_DEV_ANY;
312 	x.id0 = SYSEX_MTC;
313 	x.id1 = SYSEX_MTC_FULL;
314 	x.u.full.hr = d->mtc.hr | (d->mtc.fps_id << 5);
315 	x.u.full.min = d->mtc.min;
316 	x.u.full.sec = d->mtc.sec;
317 	x.u.full.fr = d->mtc.fr;
318 	x.u.full.end = SYSEX_END;
319 	d->mtc.qfr = 0;
320 	midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(full));
321 }
322 
323 /*
324  * send a volume change MIDI message
325  */
326 void
327 dev_midi_vol(struct dev *d, struct slot *s)
328 {
329 	unsigned char msg[3];
330 
331 	msg[0] = MIDI_CTL | (s - d->slot);
332 	msg[1] = MIDI_CTL_VOL;
333 	msg[2] = s->vol;
334 	midi_send(d->midi, msg, 3);
335 }
336 
337 /*
338  * send a master volume MIDI message
339  */
340 void
341 dev_midi_master(struct dev *d)
342 {
343 	struct sysex x;
344 
345 	memset(&x, 0, sizeof(struct sysex));
346 	x.start = SYSEX_START;
347 	x.type = SYSEX_TYPE_RT;
348 	x.dev = SYSEX_DEV_ANY;
349 	x.id0 = SYSEX_CONTROL;
350 	x.id1 = SYSEX_MASTER;
351 	x.u.master.fine = 0;
352 	x.u.master.coarse = d->master;
353 	x.u.master.end = SYSEX_END;
354 	midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(master));
355 }
356 
357 /*
358  * send a sndiod-specific slot description MIDI message
359  */
360 void
361 dev_midi_slotdesc(struct dev *d, struct slot *s)
362 {
363 	struct sysex x;
364 
365 	memset(&x, 0, sizeof(struct sysex));
366 	x.start = SYSEX_START;
367 	x.type = SYSEX_TYPE_EDU;
368 	x.dev = SYSEX_DEV_ANY;
369 	x.id0 = SYSEX_AUCAT;
370 	x.id1 = SYSEX_AUCAT_SLOTDESC;
371 	if (*s->name != '\0') {
372 		snprintf((char *)x.u.slotdesc.name, SYSEX_NAMELEN,
373 		    "%s%u", s->name, s->unit);
374 	}
375 	x.u.slotdesc.chan = s - d->slot;
376 	x.u.slotdesc.end = SYSEX_END;
377 	midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(slotdesc));
378 }
379 
380 void
381 dev_midi_dump(struct dev *d)
382 {
383 	struct sysex x;
384 	struct slot *s;
385 	int i;
386 
387 	dev_midi_master(d);
388 	for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) {
389 		dev_midi_slotdesc(d, s);
390 		dev_midi_vol(d, s);
391 	}
392 	x.start = SYSEX_START;
393 	x.type = SYSEX_TYPE_EDU;
394 	x.dev = SYSEX_DEV_ANY;
395 	x.id0 = SYSEX_AUCAT;
396 	x.id1 = SYSEX_AUCAT_DUMPEND;
397 	x.u.dumpend.end = SYSEX_END;
398 	midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(dumpend));
399 }
400 
401 void
402 dev_midi_imsg(void *arg, unsigned char *msg, int len)
403 {
404 #ifdef DEBUG
405 	struct dev *d = arg;
406 
407 	dev_log(d);
408 	log_puts(": can't receive midi messages\n");
409 	panic();
410 #endif
411 }
412 
413 void
414 dev_midi_omsg(void *arg, unsigned char *msg, int len)
415 {
416 	struct dev *d = arg;
417 	struct sysex *x;
418 	unsigned int fps, chan;
419 
420 	if ((msg[0] & MIDI_CMDMASK) == MIDI_CTL && msg[1] == MIDI_CTL_VOL) {
421 		chan = msg[0] & MIDI_CHANMASK;
422 		if (chan >= DEV_NSLOT)
423 			return;
424 		slot_setvol(d->slot + chan, msg[2]);
425 		return;
426 	}
427 	x = (struct sysex *)msg;
428 	if (x->start != SYSEX_START)
429 		return;
430 	if (len < SYSEX_SIZE(empty))
431 		return;
432 	switch (x->type) {
433 	case SYSEX_TYPE_RT:
434 		if (x->id0 == SYSEX_CONTROL && x->id1 == SYSEX_MASTER) {
435 			if (len == SYSEX_SIZE(master))
436 				dev_master(d, x->u.master.coarse);
437 			return;
438 		}
439 		if (x->id0 != SYSEX_MMC)
440 			return;
441 		switch (x->id1) {
442 		case SYSEX_MMC_STOP:
443 			if (len != SYSEX_SIZE(stop))
444 				return;
445 			if (log_level >= 2) {
446 				dev_log(d);
447 				log_puts(": mmc stop\n");
448 			}
449 			dev_mmcstop(d);
450 			break;
451 		case SYSEX_MMC_START:
452 			if (len != SYSEX_SIZE(start))
453 				return;
454 			if (log_level >= 2) {
455 				dev_log(d);
456 				log_puts(": mmc start\n");
457 			}
458 			dev_mmcstart(d);
459 			break;
460 		case SYSEX_MMC_LOC:
461 			if (len != SYSEX_SIZE(loc) ||
462 			    x->u.loc.len != SYSEX_MMC_LOC_LEN ||
463 			    x->u.loc.cmd != SYSEX_MMC_LOC_CMD)
464 				return;
465 			switch (x->u.loc.hr >> 5) {
466 			case MTC_FPS_24:
467 				fps = 24;
468 				break;
469 			case MTC_FPS_25:
470 				fps = 25;
471 				break;
472 			case MTC_FPS_30:
473 				fps = 30;
474 				break;
475 			default:
476 				dev_mmcstop(d);
477 				return;
478 			}
479 			dev_mmcloc(d,
480 			    (x->u.loc.hr & 0x1f) * 3600 * MTC_SEC +
481 			     x->u.loc.min * 60 * MTC_SEC +
482 			     x->u.loc.sec * MTC_SEC +
483 			     x->u.loc.fr * (MTC_SEC / fps) +
484 			     x->u.loc.cent * (MTC_SEC / 100 / fps));
485 			break;
486 		}
487 		break;
488 	case SYSEX_TYPE_EDU:
489 		if (x->id0 != SYSEX_AUCAT || x->id1 != SYSEX_AUCAT_DUMPREQ)
490 			return;
491 		if (len != SYSEX_SIZE(dumpreq))
492 			return;
493 		dev_midi_dump(d);
494 		break;
495 	}
496 }
497 
498 void
499 dev_midi_fill(void *arg, int count)
500 {
501 	/* nothing to do */
502 }
503 
504 void
505 dev_midi_exit(void *arg)
506 {
507 	struct dev *d = arg;
508 
509 	if (log_level >= 1) {
510 		dev_log(d);
511 		log_puts(": midi end point died\n");
512 	}
513 	if (d->pstate != DEV_CFG)
514 		dev_close(d);
515 }
516 
517 int
518 slot_skip(struct slot *s)
519 {
520 	unsigned char *data = (unsigned char *)0xdeadbeef; /* please gcc */
521 	int max, count;
522 
523 	max = s->skip;
524 	while (s->skip > 0) {
525 		if (s->pstate != SLOT_STOP && (s->mode & MODE_RECMASK)) {
526 			data = abuf_wgetblk(&s->sub.buf, &count);
527 			if (count < s->round * s->sub.bpf)
528 				break;
529 		}
530 		if (s->mode & MODE_PLAY) {
531 			if (s->mix.buf.used < s->round * s->mix.bpf)
532 				break;
533 		}
534 #ifdef DEBUG
535 		if (log_level >= 4) {
536 			slot_log(s);
537 			log_puts(": skipped a cycle\n");
538 		}
539 #endif
540 		if (s->pstate != SLOT_STOP && (s->mode & MODE_RECMASK)) {
541 			if (s->sub.encbuf)
542 				enc_sil_do(&s->sub.enc, data, s->round);
543 			else
544 				memset(data, 0, s->round * s->sub.bpf);
545 			abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf);
546 		}
547 		if (s->mode & MODE_PLAY) {
548 			abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
549 		}
550 		s->skip--;
551 	}
552 	return max - s->skip;
553 }
554 
555 int
556 play_filt_resamp(struct slot *s, void *res_in, void *out, int todo)
557 {
558 	int i, offs, vol, nch;
559 	void *in;
560 
561 	if (s->mix.resampbuf) {
562 		todo = resamp_do(&s->mix.resamp,
563 		    res_in, s->mix.resampbuf, todo);
564 		in = s->mix.resampbuf;
565 	} else
566 		in = res_in;
567 
568 	nch = s->mix.cmap.nch;
569 	vol = ADATA_MUL(s->mix.weight, s->mix.vol) / s->mix.join;
570 	cmap_add(&s->mix.cmap, in, out, vol, todo);
571 
572 	offs = 0;
573 	for (i = s->mix.join - 1; i > 0; i--) {
574 		offs += nch;
575 		cmap_add(&s->mix.cmap, (adata_t *)in + offs, out, vol, todo);
576 	}
577 	offs = 0;
578 	for (i = s->mix.expand - 1; i > 0; i--) {
579 		offs += nch;
580 		cmap_add(&s->mix.cmap, in, (adata_t *)out + offs, vol, todo);
581 	}
582 	return todo;
583 }
584 
585 int
586 play_filt_dec(struct slot *s, void *in, void *out, int todo)
587 {
588 	void *tmp;
589 
590 	tmp = s->mix.decbuf;
591 	if (tmp)
592 		dec_do(&s->mix.dec, in, tmp, todo);
593 	return play_filt_resamp(s, tmp ? tmp : in, out, todo);
594 }
595 
596 /*
597  * mix "todo" frames from the input block over the output block; if
598  * there are frames to drop, less frames are consumed from the input
599  */
600 void
601 dev_mix_badd(struct dev *d, struct slot *s)
602 {
603 	adata_t *idata, *odata;
604 	int icount;
605 
606 	odata = DEV_PBUF(d);
607 	idata = (adata_t *)abuf_rgetblk(&s->mix.buf, &icount);
608 #ifdef DEBUG
609 	if (icount < s->round * s->mix.bpf) {
610 		slot_log(s);
611 		log_puts(": not enough data to mix (");
612 		log_putu(icount);
613 		log_puts("bytes)\n");
614 		panic();
615 	}
616 #endif
617 	play_filt_dec(s, idata, odata, s->round);
618 	abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
619 }
620 
621 /*
622  * Normalize input levels.
623  */
624 void
625 dev_mix_adjvol(struct dev *d)
626 {
627 	unsigned int n;
628 	struct slot *i, *j;
629 	int weight;
630 
631 	for (i = d->slot_list; i != NULL; i = i->next) {
632 		if (!(i->mode & MODE_PLAY))
633 			continue;
634 		weight = ADATA_UNIT;
635 		if (d->autovol) {
636 			/*
637 			 * count the number of inputs that have
638 			 * overlapping channel sets
639 			 */
640 			n = 0;
641 			for (j = d->slot_list; j != NULL; j = j->next) {
642 				if (!(j->mode & MODE_PLAY))
643 					continue;
644 				if (i->mix.slot_cmin <= j->mix.slot_cmax &&
645 				    i->mix.slot_cmax >= j->mix.slot_cmin)
646 					n++;
647 			}
648 			weight /= n;
649 		}
650 		if (weight > i->mix.maxweight)
651 			weight = i->mix.maxweight;
652 		i->mix.weight = ADATA_MUL(weight, MIDI_TO_ADATA(d->master));
653 #ifdef DEBUG
654 		if (log_level >= 3) {
655 			slot_log(i);
656 			log_puts(": set weight: ");
657 			log_puti(i->mix.weight);
658 			log_puts("/");
659 			log_puti(i->mix.maxweight);
660 			log_puts("\n");
661 		}
662 #endif
663 	}
664 }
665 
666 int
667 rec_filt_resamp(struct slot *s, void *in, void *res_out, int todo)
668 {
669 	int i, vol, offs, nch;
670 	void *out = res_out;
671 
672 	out = (s->sub.resampbuf) ? s->sub.resampbuf : res_out;
673 
674 	nch = s->sub.cmap.nch;
675 	vol = ADATA_UNIT / s->sub.join;
676 	cmap_copy(&s->sub.cmap, in, out, vol, todo);
677 
678 	offs = 0;
679 	for (i = s->sub.join - 1; i > 0; i--) {
680 		offs += nch;
681 		cmap_add(&s->sub.cmap, (adata_t *)in + offs, out, vol, todo);
682 	}
683 	offs = 0;
684 	for (i = s->sub.expand - 1; i > 0; i--) {
685 		offs += nch;
686 		cmap_copy(&s->sub.cmap, in, (adata_t *)out + offs, vol, todo);
687 	}
688 	if (s->sub.resampbuf) {
689 		todo = resamp_do(&s->sub.resamp,
690 		    s->sub.resampbuf, res_out, todo);
691 	}
692 	return todo;
693 }
694 
695 int
696 rec_filt_enc(struct slot *s, void *in, void *out, int todo)
697 {
698 	void *tmp;
699 
700 	tmp = s->sub.encbuf;
701 	todo = rec_filt_resamp(s, in, tmp ? tmp : out, todo);
702 	if (tmp)
703 		enc_do(&s->sub.enc, tmp, out, todo);
704 	return todo;
705 }
706 
707 /*
708  * Copy data from slot to device
709  */
710 void
711 dev_sub_bcopy(struct dev *d, struct slot *s)
712 {
713 	adata_t *idata, *odata;
714 	int ocount, moffs;
715 
716 	if (s->mode & MODE_MON) {
717 		moffs = d->poffs + d->round;
718 		if (moffs == d->psize)
719 			moffs = 0;
720 		idata = d->pbuf + moffs * d->pchan;
721 	} else
722 		idata = d->rbuf;
723 	odata = (adata_t *)abuf_wgetblk(&s->sub.buf, &ocount);
724 #ifdef DEBUG
725 	if (ocount < s->round * s->sub.bpf) {
726 		log_puts("dev_sub_bcopy: not enough space\n");
727 		panic();
728 	}
729 #endif
730 	ocount = rec_filt_enc(s, idata, odata, d->round);
731 	abuf_wcommit(&s->sub.buf, ocount * s->sub.bpf);
732 }
733 
734 /*
735  * run a one block cycle: consume one recorded block from
736  * rbuf and produce one play block in pbuf
737  */
738 void
739 dev_cycle(struct dev *d)
740 {
741 	struct slot *s, **ps;
742 	unsigned char *base;
743 	int nsamp;
744 
745 	/*
746 	 * check if the device is actually used. If it isn't,
747 	 * then close it
748 	 */
749 	if (d->slot_list == NULL && d->tstate != MMC_RUN) {
750 		if (log_level >= 2) {
751 			dev_log(d);
752 			log_puts(": device stopped\n");
753 		}
754 		dev_sio_stop(d);
755 		d->pstate = DEV_INIT;
756 		if (d->refcnt == 0)
757 			dev_close(d);
758 		return;
759 	}
760 
761 	if (d->prime > 0) {
762 #ifdef DEBUG
763 		if (log_level >= 4) {
764 			dev_log(d);
765 			log_puts(": empty cycle, prime = ");
766 			log_putu(d->prime);
767 			log_puts("\n");
768 		}
769 #endif
770 		base = (unsigned char *)DEV_PBUF(d);
771 		nsamp = d->round * d->pchan;
772 		memset(base, 0, nsamp * sizeof(adata_t));
773 		if (d->encbuf) {
774 			enc_do(&d->enc, (unsigned char *)DEV_PBUF(d),
775 			    d->encbuf, d->round);
776 		}
777 		d->prime -= d->round;
778 		return;
779 	}
780 
781 	d->delta -= d->round;
782 #ifdef DEBUG
783 	if (log_level >= 4) {
784 		dev_log(d);
785 		log_puts(": full cycle: delta = ");
786 		log_puti(d->delta);
787 		if (d->mode & MODE_PLAY) {
788 			log_puts(", poffs = ");
789 			log_puti(d->poffs);
790 		}
791 		log_puts("\n");
792 	}
793 #endif
794 	if (d->mode & MODE_PLAY) {
795 		base = (unsigned char *)DEV_PBUF(d);
796 		nsamp = d->round * d->pchan;
797 		memset(base, 0, nsamp * sizeof(adata_t));
798 	}
799 	if ((d->mode & MODE_REC) && d->decbuf)
800 		dec_do(&d->dec, d->decbuf, (unsigned char *)d->rbuf, d->round);
801 	ps = &d->slot_list;
802 	while ((s = *ps) != NULL) {
803 #ifdef DEBUG
804 		if (log_level >= 4) {
805 			slot_log(s);
806 			log_puts(": running");
807 			log_puts(", skip = ");
808 			log_puti(s->skip);
809 			log_puts("\n");
810 		}
811 #endif
812 		/*
813 		 * skip cycles for XRUN_SYNC correction
814 		 */
815 		slot_skip(s);
816 		if (s->skip < 0) {
817 			s->skip++;
818 			ps = &s->next;
819 			continue;
820 		}
821 
822 #ifdef DEBUG
823 		if (s->pstate == SLOT_STOP && !(s->mode & MODE_PLAY)) {
824 			slot_log(s);
825 			log_puts(": rec-only slots can't be drained\n");
826 			panic();
827 		}
828 #endif
829 		/*
830 		 * check if stopped stream finished draining
831 		 */
832 		if (s->pstate == SLOT_STOP &&
833 		    s->mix.buf.used < s->round * s->mix.bpf) {
834 			/*
835 			 * partial blocks are zero-filled by socket
836 			 * layer, so s->mix.buf.used == 0 and we can
837 			 * destroy the buffer
838 			 */
839 			s->pstate = SLOT_INIT;
840 			abuf_done(&s->mix.buf);
841 			if (s->mix.decbuf)
842 				xfree(s->mix.decbuf);
843 			if (s->mix.resampbuf)
844 				xfree(s->mix.resampbuf);
845 			s->ops->eof(s->arg);
846 			*ps = s->next;
847 			dev_mix_adjvol(d);
848 			continue;
849 		}
850 
851 		/*
852 		 * check for xruns
853 		 */
854 		if (((s->mode & MODE_PLAY) &&
855 			s->mix.buf.used < s->round * s->mix.bpf) ||
856 		    ((s->mode & MODE_RECMASK) &&
857 			s->sub.buf.len - s->sub.buf.used <
858 			s->round * s->sub.bpf)) {
859 
860 #ifdef DEBUG
861 			if (log_level >= 3) {
862 				slot_log(s);
863 				log_puts(": xrun, pause cycle\n");
864 			}
865 #endif
866 			if (s->xrun == XRUN_IGNORE) {
867 				s->delta -= s->round;
868 				ps = &s->next;
869 			} else if (s->xrun == XRUN_SYNC) {
870 				s->skip++;
871 				ps = &s->next;
872 			} else if (s->xrun == XRUN_ERROR) {
873 				s->ops->exit(s->arg);
874 				*ps = s->next;
875 			} else {
876 #ifdef DEBUG
877 				slot_log(s);
878 				log_puts(": bad xrun mode\n");
879 				panic();
880 #endif
881 			}
882 			continue;
883 		}
884 		if ((s->mode & MODE_RECMASK) && !(s->pstate == SLOT_STOP)) {
885 			if (s->sub.prime == 0) {
886 				dev_sub_bcopy(d, s);
887 				s->ops->flush(s->arg);
888 			} else {
889 #ifdef DEBUG
890 				if (log_level >= 3) {
891 					slot_log(s);
892 					log_puts(": prime = ");
893 					log_puti(s->sub.prime);
894 					log_puts("\n");
895 				}
896 #endif
897 				s->sub.prime--;
898 			}
899 		}
900 		if (s->mode & MODE_PLAY) {
901 			dev_mix_badd(d, s);
902 			if (s->pstate != SLOT_STOP)
903 				s->ops->fill(s->arg);
904 		}
905 		ps = &s->next;
906 	}
907 	if ((d->mode & MODE_PLAY) && d->encbuf) {
908 		enc_do(&d->enc, (unsigned char *)DEV_PBUF(d),
909 		    d->encbuf, d->round);
910 	}
911 }
912 
913 /*
914  * called at every clock tick by the device
915  */
916 void
917 dev_onmove(struct dev *d, int delta)
918 {
919 	long long pos;
920 	struct slot *s, *snext;
921 
922 	d->delta += delta;
923 
924 	for (s = d->slot_list; s != NULL; s = snext) {
925 		/*
926 		 * s->ops->onmove() may remove the slot
927 		 */
928 		snext = s->next;
929 		pos = (long long)delta * s->round + s->delta_rem;
930 		s->delta_rem = pos % d->round;
931 		s->delta += pos / (int)d->round;
932 		if (s->delta >= 0)
933 			s->ops->onmove(s->arg);
934 	}
935 	if (d->tstate == MMC_RUN)
936 		dev_midi_qfr(d, delta);
937 }
938 
939 void
940 dev_master(struct dev *d, unsigned int master)
941 {
942 	if (log_level >= 2) {
943 		dev_log(d);
944 		log_puts(": master volume set to ");
945 		log_putu(master);
946 		log_puts("\n");
947 	}
948 	d->master = master;
949 	if (d->mode & MODE_PLAY)
950 		dev_mix_adjvol(d);
951 }
952 
953 /*
954  * return the latency that a stream would have if it's attached
955  */
956 int
957 dev_getpos(struct dev *d)
958 {
959 	return (d->mode & MODE_PLAY) ? -d->bufsz : 0;
960 }
961 
962 /*
963  * Create a sndio device
964  */
965 struct dev *
966 dev_new(char *path, struct aparams *par,
967     unsigned int mode, unsigned int bufsz, unsigned int round,
968     unsigned int rate, unsigned int hold, unsigned int autovol)
969 {
970 	struct dev *d;
971 	unsigned int i;
972 
973 	if (dev_sndnum == DEV_NMAX) {
974 		if (log_level >= 1)
975 			log_puts("too many devices\n");
976 		return NULL;
977 	}
978 	d = xmalloc(sizeof(struct dev));
979 	d->path = xstrdup(path);
980 	d->num = dev_sndnum++;
981 
982 	/*
983 	 * XXX: below, we allocate a midi input buffer, since we don't
984 	 *	receive raw midi data, so no need to allocate a input
985 	 *	ibuf.  Possibly set imsg & fill callbacks to NULL and
986 	 *	use this to in midi_new() to check if buffers need to be
987 	 *	allocated
988 	 */
989 	d->midi = midi_new(&dev_midiops, d, MODE_MIDIIN | MODE_MIDIOUT);
990 	midi_tag(d->midi, d->num);
991 	d->reqpar = *par;
992 	d->reqmode = mode;
993 	d->reqpchan = d->reqrchan = 0;
994 	d->reqbufsz = bufsz;
995 	d->reqround = round;
996 	d->reqrate = rate;
997 	d->hold = hold;
998 	d->autovol = autovol;
999 	d->refcnt = 0;
1000 	d->pstate = DEV_CFG;
1001 	d->serial = 0;
1002 	for (i = 0; i < DEV_NSLOT; i++) {
1003 		d->slot[i].unit = i;
1004 		d->slot[i].ops = NULL;
1005 		d->slot[i].vol = MIDI_MAXCTL;
1006 		d->slot[i].tstate = MMC_OFF;
1007 		d->slot[i].serial = d->serial++;
1008 		strlcpy(d->slot[i].name, "prog", SLOT_NAMEMAX);
1009 	}
1010 	d->slot_list = NULL;
1011 	d->master = MIDI_MAXCTL;
1012 	d->mtc.origin = 0;
1013 	d->tstate = MMC_STOP;
1014 	d->next = dev_list;
1015 	dev_list = d;
1016 	return d;
1017 }
1018 
1019 /*
1020  * adjust device parameters and mode
1021  */
1022 void
1023 dev_adjpar(struct dev *d, int mode,
1024     int pmax, int rmax)
1025 {
1026 	d->reqmode |= mode & MODE_AUDIOMASK;
1027 	if (mode & MODE_PLAY) {
1028 		if (d->reqpchan < pmax + 1)
1029 			d->reqpchan = pmax + 1;
1030 	}
1031 	if (mode & MODE_REC) {
1032 		if (d->reqrchan < rmax + 1)
1033 			d->reqrchan = rmax + 1;
1034 	}
1035 }
1036 
1037 /*
1038  * Open the device with the dev_reqxxx capabilities. Setup a mixer, demuxer,
1039  * monitor, midi control, and any necessary conversions.
1040  */
1041 int
1042 dev_open(struct dev *d)
1043 {
1044 	d->mode = d->reqmode;
1045 	d->round = d->reqround;
1046 	d->bufsz = d->reqbufsz;
1047 	d->rate = d->reqrate;
1048 	d->pchan = d->reqpchan;
1049 	d->rchan = d->reqrchan;
1050 	d->par = d->reqpar;
1051 	if (d->pchan == 0)
1052 		d->pchan = 2;
1053 	if (d->rchan == 0)
1054 		d->rchan = 2;
1055 	if (!dev_sio_open(d)) {
1056 		if (log_level >= 1) {
1057 			dev_log(d);
1058 			log_puts(": ");
1059 			log_puts(d->path);
1060 			log_puts(": failed to open audio device\n");
1061 		}
1062 		return 0;
1063 	}
1064 	if (d->mode & MODE_REC) {
1065 		/*
1066 		 * Create device <-> demuxer buffer
1067 		 */
1068 		d->rbuf = xmalloc(d->round * d->rchan * sizeof(adata_t));
1069 
1070 		/*
1071 		 * Insert a converter, if needed.
1072 		 */
1073 		if (!aparams_native(&d->par)) {
1074 			dec_init(&d->dec, &d->par, d->rchan);
1075 			d->decbuf = xmalloc(d->round * d->rchan * d->par.bps);
1076 		} else
1077 			d->decbuf = NULL;
1078 	}
1079 	if (d->mode & MODE_PLAY) {
1080 		/*
1081 		 * Create device <-> mixer buffer
1082 		 */
1083 		d->poffs = 0;
1084 		d->psize = d->bufsz + d->round;
1085 		d->pbuf = xmalloc(d->psize * d->pchan * sizeof(adata_t));
1086 		d->mode |= MODE_MON;
1087 
1088 		/*
1089 		 * Append a converter, if needed.
1090 		 */
1091 		if (!aparams_native(&d->par)) {
1092 			enc_init(&d->enc, &d->par, d->pchan);
1093 			d->encbuf = xmalloc(d->round * d->pchan * d->par.bps);
1094 		} else
1095 			d->encbuf = NULL;
1096 	}
1097 	d->pstate = DEV_INIT;
1098 	if (log_level >= 2) {
1099 		dev_log(d);
1100 		log_puts(": ");
1101 		log_putu(d->rate);
1102 		log_puts("Hz, ");
1103 		aparams_log(&d->par);
1104 		if (d->mode & MODE_PLAY) {
1105 			log_puts(", play 0:");
1106 			log_puti(d->pchan - 1);
1107 		}
1108 		if (d->mode & MODE_REC) {
1109 			log_puts(", rec 0:");
1110 			log_puti(d->rchan - 1);
1111 		}
1112 		log_puts(", ");
1113 		log_putu(d->bufsz / d->round);
1114 		log_puts(" blocks of ");
1115 		log_putu(d->round);
1116 		log_puts(" frames\n");
1117 	}
1118 	return 1;
1119 }
1120 
1121 /*
1122  * force the device to go in DEV_CFG state, the caller is supposed to
1123  * ensure buffers are drained
1124  */
1125 void
1126 dev_close(struct dev *d)
1127 {
1128 	int i;
1129 	struct slot *s;
1130 
1131 #ifdef DEBUG
1132 	if (log_level >= 3) {
1133 		dev_log(d);
1134 		log_puts(": closing\n");
1135 	}
1136 #endif
1137 	d->pstate = DEV_CFG;
1138 	for (s = d->slot, i = DEV_NSLOT; i > 0; i--, s++) {
1139 		if (s->ops)
1140 			s->ops->exit(s->arg);
1141 		s->ops = NULL;
1142 	}
1143 	d->slot_list = NULL;
1144 	dev_sio_close(d);
1145 	if (d->mode & MODE_PLAY) {
1146 		if (d->encbuf != NULL)
1147 			xfree(d->encbuf);
1148 		xfree(d->pbuf);
1149 	}
1150 	if (d->mode & MODE_REC) {
1151 		if (d->decbuf != NULL)
1152 			xfree(d->decbuf);
1153 		xfree(d->rbuf);
1154 	}
1155 }
1156 
1157 int
1158 dev_ref(struct dev *d)
1159 {
1160 #ifdef DEBUG
1161 	if (log_level >= 3) {
1162 		dev_log(d);
1163 		log_puts(": device requested\n");
1164 	}
1165 #endif
1166 	if (d->pstate == DEV_CFG && !dev_open(d))
1167 		return 0;
1168 	d->refcnt++;
1169 	return 1;
1170 }
1171 
1172 void
1173 dev_unref(struct dev *d)
1174 {
1175 #ifdef DEBUG
1176 	if (log_level >= 3) {
1177 		dev_log(d);
1178 		log_puts(": device released\n");
1179 	}
1180 #endif
1181 	d->refcnt--;
1182 	if (d->refcnt == 0 && d->pstate == DEV_INIT)
1183 		dev_close(d);
1184 }
1185 
1186 /*
1187  * initialize the device with the current parameters
1188  */
1189 int
1190 dev_init(struct dev *d)
1191 {
1192 	if ((d->reqmode & MODE_AUDIOMASK) == 0) {
1193 #ifdef DEBUG
1194 		    dev_log(d);
1195 		    log_puts(": has no streams\n");
1196 #endif
1197 		    return 0;
1198 	}
1199 	if (d->hold && !dev_ref(d))
1200 		return 0;
1201 	return 1;
1202 }
1203 
1204 /*
1205  * Unless the device is already in process of closing, request it to close
1206  */
1207 void
1208 dev_done(struct dev *d)
1209 {
1210 #ifdef DEBUG
1211 	if (log_level >= 3) {
1212 		dev_log(d);
1213 		log_puts(": draining\n");
1214 	}
1215 #endif
1216 	if (d->tstate != MMC_STOP)
1217 		dev_mmcstop(d);
1218 	if (d->hold)
1219 		dev_unref(d);
1220 }
1221 
1222 struct dev *
1223 dev_bynum(int num)
1224 {
1225 	struct dev *d;
1226 
1227 	for (d = dev_list; d != NULL; d = d->next) {
1228 		if (d->num == num)
1229 			return d;
1230 	}
1231 	return NULL;
1232 }
1233 
1234 /*
1235  * Free the device
1236  */
1237 void
1238 dev_del(struct dev *d)
1239 {
1240 	struct dev **p;
1241 
1242 #ifdef DEBUG
1243 	if (log_level >= 3) {
1244 		dev_log(d);
1245 		log_puts(": deleting\n");
1246 	}
1247 #endif
1248 	if (d->pstate != DEV_CFG)
1249 		dev_close(d);
1250 	for (p = &dev_list; *p != d; p = &(*p)->next) {
1251 #ifdef DEBUG
1252 		if (*p == NULL) {
1253 			dev_log(d);
1254 			log_puts(": device to delete not on the list\n");
1255 			panic();
1256 		}
1257 #endif
1258 	}
1259 	midi_del(d->midi);
1260 	*p = d->next;
1261 	xfree(d->path);
1262 	xfree(d);
1263 }
1264 
1265 unsigned int
1266 dev_roundof(struct dev *d, unsigned int newrate)
1267 {
1268 	return (d->round * newrate + d->rate / 2) / d->rate;
1269 }
1270 
1271 /*
1272  * If the device is paused, then resume it.
1273  */
1274 void
1275 dev_wakeup(struct dev *d)
1276 {
1277 	if (d->pstate == DEV_INIT) {
1278 		if (log_level >= 2) {
1279 			dev_log(d);
1280 			log_puts(": device started\n");
1281 		}
1282 		if (d->mode & MODE_PLAY) {
1283 			d->prime = d->bufsz;
1284 		} else {
1285 			d->prime = 0;
1286 		}
1287 		d->poffs = 0;
1288 
1289 		/*
1290 		 * empty cycles don't increment delta, so it's ok to
1291 		 * start at 0
1292 		 **/
1293 		d->delta = 0;
1294 
1295 		d->pstate = DEV_RUN;
1296 		dev_sio_start(d);
1297 	}
1298 }
1299 
1300 /*
1301  * check that all clients controlled by MMC are ready to start, if so,
1302  * attach them all at the same position
1303  */
1304 void
1305 dev_sync_attach(struct dev *d)
1306 {
1307 	int i;
1308 	struct slot *s;
1309 
1310 	if (d->tstate != MMC_START) {
1311 		if (log_level >= 2) {
1312 			dev_log(d);
1313 			log_puts(": not started by mmc yet, waiting...\n");
1314 		}
1315 		return;
1316 	}
1317 	for (i = 0; i < DEV_NSLOT; i++) {
1318 		s = d->slot + i;
1319 		if (!s->ops || s->tstate == MMC_OFF)
1320 			continue;
1321 		if (s->tstate != MMC_START || s->pstate != SLOT_READY) {
1322 #ifdef DEBUG
1323 			if (log_level >= 3) {
1324 				slot_log(s);
1325 				log_puts(": not ready, start delayed\n");
1326 			}
1327 #endif
1328 			return;
1329 		}
1330 	}
1331 	if (!dev_ref(d))
1332 		return;
1333 	for (i = 0; i < DEV_NSLOT; i++) {
1334 		s = d->slot + i;
1335 		if (!s->ops)
1336 			continue;
1337 		if (s->tstate == MMC_START) {
1338 #ifdef DEBUG
1339 			if (log_level >= 3) {
1340 				slot_log(s);
1341 				log_puts(": started\n");
1342 			}
1343 #endif
1344 			s->tstate = MMC_RUN;
1345 			slot_attach(s);
1346 		}
1347 	}
1348 	d->tstate = MMC_RUN;
1349 	dev_midi_full(d);
1350 	dev_wakeup(d);
1351 }
1352 
1353 /*
1354  * start all slots simultaneously
1355  */
1356 void
1357 dev_mmcstart(struct dev *d)
1358 {
1359 	if (d->tstate == MMC_STOP) {
1360 		d->tstate = MMC_START;
1361 		dev_sync_attach(d);
1362 #ifdef DEBUG
1363 	} else {
1364 		if (log_level >= 3) {
1365 			dev_log(d);
1366 			log_puts(": ignoring mmc start\n");
1367 		}
1368 #endif
1369 	}
1370 }
1371 
1372 /*
1373  * stop all slots simultaneously
1374  */
1375 void
1376 dev_mmcstop(struct dev *d)
1377 {
1378 	switch (d->tstate) {
1379 	case MMC_START:
1380 		d->tstate = MMC_STOP;
1381 		return;
1382 	case MMC_RUN:
1383 		d->tstate = MMC_STOP;
1384 		dev_unref(d);
1385 		break;
1386 	default:
1387 #ifdef DEBUG
1388 		if (log_level >= 3) {
1389 			dev_log(d);
1390 			log_puts(": ignored mmc stop\n");
1391 		}
1392 #endif
1393 		return;
1394 	}
1395 }
1396 
1397 /*
1398  * relocate all slots simultaneously
1399  */
1400 void
1401 dev_mmcloc(struct dev *d, unsigned int origin)
1402 {
1403 	if (log_level >= 2) {
1404 		dev_log(d);
1405 		log_puts(": relocated to ");
1406 		log_putu(origin);
1407 		log_puts("\n");
1408 	}
1409 	if (d->tstate == MMC_RUN)
1410 		dev_mmcstop(d);
1411 	d->mtc.origin = origin;
1412 	if (d->tstate == MMC_RUN)
1413 		dev_mmcstart(d);
1414 }
1415 
1416 /*
1417  * allocate a new slot and register the given call-backs
1418  */
1419 struct slot *
1420 slot_new(struct dev *d, char *who, struct slotops *ops, void *arg, int mode)
1421 {
1422 	char *p;
1423 	char name[SLOT_NAMEMAX];
1424 	unsigned int i, unit, umap = 0;
1425 	unsigned int ser, bestser, bestidx;
1426 	struct slot *s;
1427 
1428 	/*
1429 	 * create a ``valid'' control name (lowcase, remove [^a-z], trucate)
1430 	 */
1431 	for (i = 0, p = who; ; p++) {
1432 		if (i == SLOT_NAMEMAX - 1 || *p == '\0') {
1433 			name[i] = '\0';
1434 			break;
1435 		} else if (*p >= 'A' && *p <= 'Z') {
1436 			name[i++] = *p + 'a' - 'A';
1437 		} else if (*p >= 'a' && *p <= 'z')
1438 			name[i++] = *p;
1439 	}
1440 	if (i == 0)
1441 		strlcpy(name, "noname", SLOT_NAMEMAX);
1442 
1443 	/*
1444 	 * find the first unused "unit" number for this name
1445 	 */
1446 	for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) {
1447 		if (s->ops == NULL)
1448 			continue;
1449 		if (strcmp(s->name, name) == 0)
1450 			umap |= (1 << s->unit);
1451 	}
1452 	for (unit = 0; ; unit++) {
1453 		if ((umap & (1 << unit)) == 0)
1454 			break;
1455 	}
1456 
1457 	/*
1458 	 * find a free controller slot with the same name/unit
1459 	 */
1460 	for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) {
1461 		if (s->ops == NULL &&
1462 		    strcmp(s->name, name) == 0 &&
1463 		    s->unit == unit) {
1464 #ifdef DEBUG
1465 			if (log_level >= 3) {
1466 				log_puts(name);
1467 				log_putu(unit);
1468 				log_puts(": reused\n");
1469 			}
1470 #endif
1471 			goto found;
1472 		}
1473 	}
1474 
1475 	/*
1476 	 * couldn't find a matching slot, pick oldest free slot
1477 	 * and set its name/unit
1478 	 */
1479 	bestser = 0;
1480 	bestidx = DEV_NSLOT;
1481 	for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) {
1482 		if (s->ops != NULL)
1483 			continue;
1484 		ser = d->serial - s->serial;
1485 		if (ser > bestser) {
1486 			bestser = ser;
1487 			bestidx = i;
1488 		}
1489 	}
1490 	if (bestidx == DEV_NSLOT) {
1491 		if (log_level >= 1) {
1492 			log_puts(name);
1493 			log_putu(unit);
1494 			log_puts(": out of sub-device slots\n");
1495 		}
1496 		return NULL;
1497 	}
1498 	s = d->slot + bestidx;
1499 	if (s->name[0] != '\0')
1500 		s->vol = MIDI_MAXCTL;
1501 	strlcpy(s->name, name, SLOT_NAMEMAX);
1502 	s->serial = d->serial++;
1503 	s->unit = unit;
1504 #ifdef DEBUG
1505 	if (log_level >= 3) {
1506 		log_puts(name);
1507 		log_putu(unit);
1508 		log_puts(": overwritten slot ");
1509 		log_putu(bestidx);
1510 		log_puts("\n");
1511 	}
1512 #endif
1513 
1514 found:
1515 	if (!dev_ref(d))
1516 		return NULL;
1517 	s->dev = d;
1518 	s->ops = ops;
1519 	s->arg = arg;
1520 	s->pstate = SLOT_INIT;
1521 	s->tstate = MMC_OFF;
1522 
1523 	if ((mode & s->dev->mode) != mode) {
1524 		if (log_level >= 1) {
1525 			slot_log(s);
1526 			log_puts(": requested mode not supported\n");
1527 		}
1528 		return 0;
1529 	}
1530 	s->mode = mode;
1531 	aparams_init(&s->par);
1532 	if (s->mode & MODE_PLAY) {
1533 		s->mix.slot_cmin = s->mix.dev_cmin = 0;
1534 		s->mix.slot_cmax = s->mix.dev_cmax = d->pchan - 1;
1535 	}
1536 	if (s->mode & MODE_RECMASK) {
1537 		s->sub.slot_cmin = s->sub.dev_cmin = 0;
1538 		s->sub.slot_cmax = s->sub.dev_cmax =
1539 		    ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1;
1540 	}
1541 	s->xrun = XRUN_IGNORE;
1542 	s->dup = 0;
1543 	s->appbufsz = d->bufsz;
1544 	s->round = d->round;
1545 	s->rate = d->rate;
1546 	s->mix.maxweight = ADATA_UNIT;
1547 	dev_midi_slotdesc(d, s);
1548 	dev_midi_vol(d, s);
1549 	return s;
1550 }
1551 
1552 /*
1553  * release the given slot
1554  */
1555 void
1556 slot_del(struct slot *s)
1557 {
1558 	s->arg = s;
1559 	s->ops = &zomb_slotops;
1560 	switch (s->pstate) {
1561 	case SLOT_INIT:
1562 		s->ops = NULL;
1563 		break;
1564 	case SLOT_START:
1565 	case SLOT_READY:
1566 	case SLOT_RUN:
1567 		slot_stop(s);
1568 		/* PASSTHROUGH */
1569 	case SLOT_STOP:
1570 		break;
1571 	}
1572 	dev_unref(s->dev);
1573 	s->dev = NULL;
1574 }
1575 
1576 /*
1577  * change the slot play volume; called either by the slot or by MIDI
1578  */
1579 void
1580 slot_setvol(struct slot *s, unsigned int vol)
1581 {
1582 #ifdef DEBUG
1583 	if (log_level >= 3) {
1584 		slot_log(s);
1585 		log_puts(": setting volume ");
1586 		log_putu(vol);
1587 		log_puts("\n");
1588 	}
1589 #endif
1590 	s->vol = vol;
1591 	if (s->ops == NULL)
1592 		return;
1593 	s->mix.vol = MIDI_TO_ADATA(s->vol);
1594 }
1595 
1596 /*
1597  * attach the slot to the device (ie start playing & recording
1598  */
1599 void
1600 slot_attach(struct slot *s)
1601 {
1602 	struct dev *d = s->dev;
1603 	unsigned int slot_nch, dev_nch;
1604 	long long pos;
1605 	int startpos;
1606 
1607 	/*
1608 	 * start the device if not started
1609 	 */
1610 	dev_wakeup(d);
1611 
1612 	/*
1613 	 * get the current position, the origin is when the first sample
1614 	 * played and/or recorded
1615 	 */
1616 	startpos = dev_getpos(d) * (int)s->round / (int)d->round;
1617 
1618 	/*
1619 	 * adjust initial clock
1620 	 */
1621 	pos = (long long)d->delta * s->round;
1622 	s->delta = startpos + pos / (int)d->round;
1623 	s->delta_rem = pos % d->round;
1624 
1625 	s->pstate = SLOT_RUN;
1626 #ifdef DEBUG
1627 	if (log_level >= 2) {
1628 		slot_log(s);
1629 		log_puts(": attached at ");
1630 		log_puti(startpos);
1631 		log_puts(", delta = ");
1632 		log_puti(d->delta);
1633 		log_puts("\n");
1634 	}
1635 #endif
1636 
1637 	/*
1638 	 * We dont check whether the device is dying,
1639 	 * because dev_xxx() functions are supposed to
1640 	 * work (i.e., not to crash)
1641 	 */
1642 #ifdef DEBUG
1643 	if ((s->mode & d->mode) != s->mode) {
1644 		slot_log(s);
1645 		log_puts(": mode beyond device mode, not attaching\n");
1646 		panic();
1647 	}
1648 #endif
1649 	s->next = d->slot_list;
1650 	d->slot_list = s;
1651 	s->skip = 0;
1652 	if (s->mode & MODE_PLAY) {
1653 		slot_nch = s->mix.slot_cmax - s->mix.slot_cmin + 1;
1654 		dev_nch = s->mix.dev_cmax - s->mix.dev_cmin + 1;
1655 		s->mix.decbuf = NULL;
1656 		s->mix.resampbuf = NULL;
1657 		s->mix.join = 1;
1658 		s->mix.expand = 1;
1659 		if (s->dup) {
1660 			if (dev_nch > slot_nch)
1661 				s->mix.expand = dev_nch / slot_nch;
1662 			else if (dev_nch < slot_nch)
1663 				s->mix.join = slot_nch / dev_nch;
1664 		}
1665 		cmap_init(&s->mix.cmap,
1666 		    s->mix.slot_cmin, s->mix.slot_cmax,
1667 		    s->mix.slot_cmin, s->mix.slot_cmax,
1668 		    0, d->pchan - 1,
1669 		    s->mix.dev_cmin, s->mix.dev_cmax);
1670 		if (!aparams_native(&s->par)) {
1671 			dec_init(&s->mix.dec, &s->par, slot_nch);
1672 			s->mix.decbuf =
1673 			    xmalloc(s->round * slot_nch * sizeof(adata_t));
1674 		}
1675 		if (s->rate != d->rate) {
1676 			resamp_init(&s->mix.resamp, s->round, d->round,
1677 			    slot_nch);
1678 			s->mix.resampbuf =
1679 			    xmalloc(d->round * slot_nch * sizeof(adata_t));
1680 		}
1681 		s->mix.vol = MIDI_TO_ADATA(s->vol);
1682 		dev_mix_adjvol(d);
1683 	}
1684 	if (s->mode & MODE_RECMASK) {
1685 		slot_nch = s->sub.slot_cmax - s->sub.slot_cmin + 1;
1686 		dev_nch = s->sub.dev_cmax - s->sub.dev_cmin + 1;
1687 		s->sub.encbuf = NULL;
1688 		s->sub.resampbuf = NULL;
1689 		s->sub.join = 1;
1690 		s->sub.expand = 1;
1691 		if (s->dup) {
1692 			if (dev_nch > slot_nch)
1693 				s->sub.join = dev_nch / slot_nch;
1694 			else if (dev_nch < slot_nch)
1695 				s->sub.expand = slot_nch / dev_nch;
1696 		}
1697 		cmap_init(&s->sub.cmap,
1698 		    0, ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1,
1699 		    s->sub.dev_cmin, s->sub.dev_cmax,
1700 		    s->sub.slot_cmin, s->sub.slot_cmax,
1701 		    s->sub.slot_cmin, s->sub.slot_cmax);
1702 		if (s->rate != d->rate) {
1703 			resamp_init(&s->sub.resamp, d->round, s->round,
1704 			    slot_nch);
1705 			s->sub.resampbuf =
1706 			    xmalloc(d->round * slot_nch * sizeof(adata_t));
1707 		}
1708 		if (!aparams_native(&s->par)) {
1709 			enc_init(&s->sub.enc, &s->par, slot_nch);
1710 			s->sub.encbuf =
1711 			    xmalloc(s->round * slot_nch * sizeof(adata_t));
1712 		}
1713 
1714 		/*
1715 		 * N-th recorded block is the N-th played block
1716 		 */
1717 		s->sub.prime = -startpos / (int)s->round;
1718 	}
1719 }
1720 
1721 /*
1722  * if MMC is enabled, and try to attach all slots synchronously, else
1723  * simply attach the slot
1724  */
1725 void
1726 slot_ready(struct slot *s)
1727 {
1728 	/*
1729 	 * device may be disconnected, and if so we're called from
1730 	 * slot->ops->exit() on a closed device
1731 	 */
1732 	if (s->dev->pstate == DEV_CFG)
1733 		return;
1734 	if (s->tstate == MMC_OFF)
1735 		slot_attach(s);
1736 	else {
1737 		s->tstate = MMC_START;
1738 		dev_sync_attach(s->dev);
1739 	}
1740 }
1741 
1742 /*
1743  * setup buffers & conversion layers, prepare the slot to receive data
1744  * (for playback) or start (recording).
1745  */
1746 void
1747 slot_start(struct slot *s)
1748 {
1749 	unsigned int bufsz;
1750 #ifdef DEBUG
1751 	struct dev *d = s->dev;
1752 
1753 
1754 	if (s->pstate != SLOT_INIT) {
1755 		slot_log(s);
1756 		log_puts(": slot_start: wrong state\n");
1757 		panic();
1758 	}
1759 #endif
1760 	bufsz = s->appbufsz;
1761 	if (s->mode & MODE_PLAY) {
1762 #ifdef DEBUG
1763 		if (log_level >= 3) {
1764 			slot_log(s);
1765 			log_puts(": playing ");
1766 			aparams_log(&s->par);
1767 			log_puts(" -> ");
1768 			aparams_log(&d->par);
1769 			log_puts("\n");
1770 		}
1771 #endif
1772 		s->mix.bpf = s->par.bps *
1773 		    (s->mix.slot_cmax - s->mix.slot_cmin + 1);
1774 		abuf_init(&s->mix.buf, bufsz * s->mix.bpf);
1775 	}
1776 	if (s->mode & MODE_RECMASK) {
1777 #ifdef DEBUG
1778 		if (log_level >= 3) {
1779 			slot_log(s);
1780 			log_puts(": recording ");
1781 			aparams_log(&s->par);
1782 			log_puts(" <- ");
1783 			aparams_log(&d->par);
1784 			log_puts("\n");
1785 	}
1786 #endif
1787 		s->sub.bpf = s->par.bps *
1788 		    (s->sub.slot_cmax - s->sub.slot_cmin + 1);
1789 		abuf_init(&s->sub.buf, bufsz * s->sub.bpf);
1790 	}
1791 	s->mix.weight = MIDI_TO_ADATA(MIDI_MAXCTL);
1792 #ifdef DEBUG
1793 	if (log_level >= 3) {
1794 		slot_log(s);
1795 		log_puts(": allocated ");
1796 		log_putu(s->appbufsz);
1797 		log_puts("/");
1798 		log_putu(SLOT_BUFSZ(s));
1799 		log_puts(" fr buffers\n");
1800 	}
1801 #endif
1802 	if (s->mode & MODE_PLAY) {
1803 		s->pstate = SLOT_START;
1804 	} else {
1805 		s->pstate = SLOT_READY;
1806 		slot_ready(s);
1807 	}
1808 }
1809 
1810 /*
1811  * stop playback and recording, and free conversion layers
1812  */
1813 void
1814 slot_detach(struct slot *s)
1815 {
1816 	struct slot **ps;
1817 
1818 #ifdef DEBUG
1819 	if (log_level >= 3) {
1820 		slot_log(s);
1821 		log_puts(": detaching\n");
1822 	}
1823 #endif
1824 	for (ps = &s->dev->slot_list; *ps != s; ps = &(*ps)->next) {
1825 #ifdef DEBUG
1826 		if (s == NULL) {
1827 			slot_log(s);
1828 			log_puts(": can't detach, not on list\n");
1829 			panic();
1830 		}
1831 #endif
1832 	}
1833 	*ps = s->next;
1834 	if (s->mode & MODE_RECMASK) {
1835 		if (s->sub.encbuf)
1836 			xfree(s->sub.encbuf);
1837 		if (s->sub.resampbuf)
1838 			xfree(s->sub.resampbuf);
1839 	}
1840 	if (s->mode & MODE_PLAY) {
1841 		if (s->mix.decbuf)
1842 			xfree(s->mix.decbuf);
1843 		if (s->mix.resampbuf)
1844 			xfree(s->mix.resampbuf);
1845 		dev_mix_adjvol(s->dev);
1846 	}
1847 }
1848 
1849 /*
1850  * put the slot in stopping state (draining play buffers) or
1851  * stop & detach if no data to drain.
1852  */
1853 void
1854 slot_stop(struct slot *s)
1855 {
1856 #ifdef DEBUG
1857 	if (log_level >= 3) {
1858 		slot_log(s);
1859 		log_puts(": stopping\n");
1860 	}
1861 #endif
1862 	if (s->pstate == SLOT_START) {
1863 		if (s->mode & MODE_PLAY) {
1864 			s->pstate = SLOT_READY;
1865 			slot_ready(s);
1866 		} else
1867 			s->pstate = SLOT_INIT;
1868 	}
1869 	if (s->mode & MODE_RECMASK)
1870 		abuf_done(&s->sub.buf);
1871 	if (s->pstate == SLOT_READY) {
1872 #ifdef DEBUG
1873 		if (log_level >= 3) {
1874 			slot_log(s);
1875 			log_puts(": not drained (blocked by mmc)\n");
1876 		}
1877 #endif
1878 		if (s->mode & MODE_PLAY)
1879 			abuf_done(&s->mix.buf);
1880 		s->ops->eof(s->arg);
1881 		s->pstate = SLOT_INIT;
1882 	} else {
1883 		/* s->pstate == SLOT_RUN */
1884 		if (s->mode & MODE_PLAY)
1885 			s->pstate = SLOT_STOP;
1886 		else {
1887 			slot_detach(s);
1888 			s->pstate = SLOT_INIT;
1889 			s->ops->eof(s->arg);
1890 		}
1891 	}
1892 	if (s->tstate != MMC_OFF)
1893 		s->tstate = MMC_STOP;
1894 }
1895 
1896 void
1897 slot_skip_update(struct slot *s)
1898 {
1899 	int skip;
1900 
1901 	skip = slot_skip(s);
1902 	while (skip > 0) {
1903 #ifdef DEBUG
1904 		if (log_level >= 4) {
1905 			slot_log(s);
1906 			log_puts(": catching skipped block\n");
1907 		}
1908 #endif
1909 		if (s->mode & MODE_RECMASK)
1910 			s->ops->flush(s->arg);
1911 		if (s->mode & MODE_PLAY)
1912 			s->ops->fill(s->arg);
1913 		skip--;
1914 	}
1915 }
1916 
1917 /*
1918  * notify the slot that we just wrote in the play buffer, must be called
1919  * after each write
1920  */
1921 void
1922 slot_write(struct slot *s)
1923 {
1924 	if (s->pstate == SLOT_START && s->mix.buf.used == s->mix.buf.len) {
1925 #ifdef DEBUG
1926 		if (log_level >= 4) {
1927 			slot_log(s);
1928 			log_puts(": switching to READY state\n");
1929 		}
1930 #endif
1931 		s->pstate = SLOT_READY;
1932 		slot_ready(s);
1933 	}
1934 	slot_skip_update(s);
1935 }
1936 
1937 /*
1938  * notify the slot that we freed some space in the rec buffer
1939  */
1940 void
1941 slot_read(struct slot *s)
1942 {
1943 	slot_skip_update(s);
1944 }
1945