xref: /openbsd-src/usr.bin/sndiod/dev.c (revision 1a8dbaac879b9f3335ad7fb25429ce63ac1d6bac)
1 /*	$OpenBSD: dev.c,v 1.77 2020/07/19 11:13: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 #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 "opt.h"
27 #include "sysex.h"
28 #include "utils.h"
29 
30 void zomb_onmove(void *);
31 void zomb_onvol(void *);
32 void zomb_fill(void *);
33 void zomb_flush(void *);
34 void zomb_eof(void *);
35 void zomb_exit(void *);
36 
37 void dev_log(struct dev *);
38 void dev_midi_qfr(struct dev *, int);
39 void dev_midi_full(struct dev *);
40 void dev_midi_vol(struct dev *, struct slot *);
41 void dev_midi_master(struct dev *);
42 void dev_midi_slotdesc(struct dev *, struct slot *);
43 void dev_midi_dump(struct dev *);
44 void dev_midi_imsg(void *, unsigned char *, int);
45 void dev_midi_omsg(void *, unsigned char *, int);
46 void dev_midi_fill(void *, int);
47 void dev_midi_exit(void *);
48 
49 void dev_mix_badd(struct dev *, struct slot *);
50 void dev_mix_adjvol(struct dev *);
51 void dev_sub_bcopy(struct dev *, struct slot *);
52 
53 void dev_onmove(struct dev *, int);
54 void dev_master(struct dev *, unsigned int);
55 void dev_cycle(struct dev *);
56 int dev_getpos(struct dev *);
57 struct dev *dev_new(char *, struct aparams *, unsigned int, unsigned int,
58     unsigned int, unsigned int, unsigned int, unsigned int);
59 void dev_adjpar(struct dev *, int, int, int);
60 int dev_allocbufs(struct dev *);
61 int dev_open(struct dev *);
62 void dev_freebufs(struct dev *);
63 void dev_close(struct dev *);
64 int dev_ref(struct dev *);
65 void dev_unref(struct dev *);
66 int dev_init(struct dev *);
67 void dev_done(struct dev *);
68 struct dev *dev_bynum(int);
69 void dev_del(struct dev *);
70 void dev_setalt(struct dev *, unsigned int);
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_ctlname(struct slot *, char *, size_t);
79 void slot_log(struct slot *);
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_allocbufs(struct slot *);
85 void slot_freebufs(struct slot *);
86 void slot_initconv(struct slot *);
87 void slot_start(struct slot *);
88 void slot_detach(struct slot *);
89 void slot_stop(struct slot *);
90 void slot_skip_update(struct slot *);
91 void slot_write(struct slot *);
92 void slot_read(struct slot *);
93 int slot_skip(struct slot *);
94 
95 void ctl_node_log(struct ctl_node *);
96 void ctl_log(struct ctl *);
97 
98 struct midiops dev_midiops = {
99 	dev_midi_imsg,
100 	dev_midi_omsg,
101 	dev_midi_fill,
102 	dev_midi_exit
103 };
104 
105 struct slotops zomb_slotops = {
106 	zomb_onmove,
107 	zomb_onvol,
108 	zomb_fill,
109 	zomb_flush,
110 	zomb_eof,
111 	zomb_exit
112 };
113 
114 struct dev *dev_list = NULL;
115 unsigned int dev_sndnum = 0;
116 
117 void
118 dev_log(struct dev *d)
119 {
120 #ifdef DEBUG
121 	static char *pstates[] = {
122 		"cfg", "ini", "run"
123 	};
124 #endif
125 	log_puts("snd");
126 	log_putu(d->num);
127 #ifdef DEBUG
128 	if (log_level >= 3) {
129 		log_puts(" pst=");
130 		log_puts(pstates[d->pstate]);
131 	}
132 #endif
133 }
134 
135 void
136 slot_ctlname(struct slot *s, char *name, size_t size)
137 {
138 	snprintf(name, size, "%s%u", s->name, s->unit);
139 }
140 
141 void
142 slot_log(struct slot *s)
143 {
144 	char name[CTL_NAMEMAX];
145 #ifdef DEBUG
146 	static char *pstates[] = {
147 		"ini", "sta", "rdy", "run", "stp", "mid"
148 	};
149 #endif
150 	slot_ctlname(s, name, CTL_NAMEMAX);
151 	log_puts(name);
152 #ifdef DEBUG
153 	if (log_level >= 3) {
154 		log_puts(" vol=");
155 		log_putu(s->vol);
156 		if (s->ops) {
157 			log_puts(",pst=");
158 			log_puts(pstates[s->pstate]);
159 		}
160 	}
161 #endif
162 }
163 
164 void
165 zomb_onmove(void *arg)
166 {
167 }
168 
169 void
170 zomb_onvol(void *arg)
171 {
172 }
173 
174 void
175 zomb_fill(void *arg)
176 {
177 }
178 
179 void
180 zomb_flush(void *arg)
181 {
182 }
183 
184 void
185 zomb_eof(void *arg)
186 {
187 	struct slot *s = arg;
188 
189 #ifdef DEBUG
190 	if (log_level >= 3) {
191 		slot_log(s);
192 		log_puts(": zomb_eof\n");
193 	}
194 #endif
195 	s->ops = NULL;
196 }
197 
198 void
199 zomb_exit(void *arg)
200 {
201 #ifdef DEBUG
202 	struct slot *s = arg;
203 
204 	if (log_level >= 3) {
205 		slot_log(s);
206 		log_puts(": zomb_exit\n");
207 	}
208 #endif
209 }
210 
211 /*
212  * send a quarter frame MTC message
213  */
214 void
215 dev_midi_qfr(struct dev *d, int delta)
216 {
217 	unsigned char buf[2];
218 	unsigned int data;
219 	int qfrlen;
220 
221 	d->mtc.delta += delta * MTC_SEC;
222 	qfrlen = d->rate * (MTC_SEC / (4 * d->mtc.fps));
223 	while (d->mtc.delta >= qfrlen) {
224 		switch (d->mtc.qfr) {
225 		case 0:
226 			data = d->mtc.fr & 0xf;
227 			break;
228 		case 1:
229 			data = d->mtc.fr >> 4;
230 			break;
231 		case 2:
232 			data = d->mtc.sec & 0xf;
233 			break;
234 		case 3:
235 			data = d->mtc.sec >> 4;
236 			break;
237 		case 4:
238 			data = d->mtc.min & 0xf;
239 			break;
240 		case 5:
241 			data = d->mtc.min >> 4;
242 			break;
243 		case 6:
244 			data = d->mtc.hr & 0xf;
245 			break;
246 		case 7:
247 			data = (d->mtc.hr >> 4) | (d->mtc.fps_id << 1);
248 			/*
249 			 * tick messages are sent 2 frames ahead
250 			 */
251 			d->mtc.fr += 2;
252 			if (d->mtc.fr < d->mtc.fps)
253 				break;
254 			d->mtc.fr -= d->mtc.fps;
255 			d->mtc.sec++;
256 			if (d->mtc.sec < 60)
257 				break;
258 			d->mtc.sec = 0;
259 			d->mtc.min++;
260 			if (d->mtc.min < 60)
261 				break;
262 			d->mtc.min = 0;
263 			d->mtc.hr++;
264 			if (d->mtc.hr < 24)
265 				break;
266 			d->mtc.hr = 0;
267 			break;
268 		default:
269 			/* NOTREACHED */
270 			data = 0;
271 		}
272 		buf[0] = 0xf1;
273 		buf[1] = (d->mtc.qfr << 4) | data;
274 		d->mtc.qfr++;
275 		d->mtc.qfr &= 7;
276 		midi_send(d->midi, buf, 2);
277 		d->mtc.delta -= qfrlen;
278 	}
279 }
280 
281 /*
282  * send a full frame MTC message
283  */
284 void
285 dev_midi_full(struct dev *d)
286 {
287 	struct sysex x;
288 	unsigned int fps;
289 
290 	d->mtc.delta = MTC_SEC * dev_getpos(d);
291 	if (d->rate % (30 * 4 * d->round) == 0) {
292 		d->mtc.fps_id = MTC_FPS_30;
293 		d->mtc.fps = 30;
294 	} else if (d->rate % (25 * 4 * d->round) == 0) {
295 		d->mtc.fps_id = MTC_FPS_25;
296 		d->mtc.fps = 25;
297 	} else {
298 		d->mtc.fps_id = MTC_FPS_24;
299 		d->mtc.fps = 24;
300 	}
301 #ifdef DEBUG
302 	if (log_level >= 3) {
303 		dev_log(d);
304 		log_puts(": mtc full frame at ");
305 		log_puti(d->mtc.delta);
306 		log_puts(", ");
307 		log_puti(d->mtc.fps);
308 		log_puts(" fps\n");
309 	}
310 #endif
311 	fps = d->mtc.fps;
312 	d->mtc.hr =  (d->mtc.origin / (MTC_SEC * 3600)) % 24;
313 	d->mtc.min = (d->mtc.origin / (MTC_SEC * 60))   % 60;
314 	d->mtc.sec = (d->mtc.origin / (MTC_SEC))        % 60;
315 	d->mtc.fr =  (d->mtc.origin / (MTC_SEC / fps))  % fps;
316 
317 	x.start = SYSEX_START;
318 	x.type = SYSEX_TYPE_RT;
319 	x.dev = SYSEX_DEV_ANY;
320 	x.id0 = SYSEX_MTC;
321 	x.id1 = SYSEX_MTC_FULL;
322 	x.u.full.hr = d->mtc.hr | (d->mtc.fps_id << 5);
323 	x.u.full.min = d->mtc.min;
324 	x.u.full.sec = d->mtc.sec;
325 	x.u.full.fr = d->mtc.fr;
326 	x.u.full.end = SYSEX_END;
327 	d->mtc.qfr = 0;
328 	midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(full));
329 }
330 
331 /*
332  * send a volume change MIDI message
333  */
334 void
335 dev_midi_vol(struct dev *d, struct slot *s)
336 {
337 	unsigned char msg[3];
338 
339 	msg[0] = MIDI_CTL | (s - d->slot);
340 	msg[1] = MIDI_CTL_VOL;
341 	msg[2] = s->vol;
342 	midi_send(d->midi, msg, 3);
343 }
344 
345 /*
346  * send a master volume MIDI message
347  */
348 void
349 dev_midi_master(struct dev *d)
350 {
351 	struct ctl *c;
352 	unsigned int master, v;
353 	struct sysex x;
354 
355 	if (d->master_enabled)
356 		master = d->master;
357 	else {
358 		master = 0;
359 		for (c = d->ctl_list; c != NULL; c = c->next) {
360 			if (c->type != CTL_NUM ||
361 			    strcmp(c->group, "") != 0 ||
362 			    strcmp(c->node0.name, "output") != 0 ||
363 			    strcmp(c->func, "level") != 0)
364 				continue;
365 			v = (c->curval * 127 + c->maxval / 2) / c->maxval;
366 			if (master < v)
367 				master = v;
368 		}
369 	}
370 
371 	memset(&x, 0, sizeof(struct sysex));
372 	x.start = SYSEX_START;
373 	x.type = SYSEX_TYPE_RT;
374 	x.dev = SYSEX_DEV_ANY;
375 	x.id0 = SYSEX_CONTROL;
376 	x.id1 = SYSEX_MASTER;
377 	x.u.master.fine = 0;
378 	x.u.master.coarse = master;
379 	x.u.master.end = SYSEX_END;
380 	midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(master));
381 }
382 
383 /*
384  * send a sndiod-specific slot description MIDI message
385  */
386 void
387 dev_midi_slotdesc(struct dev *d, struct slot *s)
388 {
389 	struct sysex x;
390 
391 	memset(&x, 0, sizeof(struct sysex));
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_SLOTDESC;
397 	if (*s->name != '\0')
398 		slot_ctlname(s, (char *)x.u.slotdesc.name, SYSEX_NAMELEN);
399 	x.u.slotdesc.chan = s - d->slot;
400 	x.u.slotdesc.end = SYSEX_END;
401 	midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(slotdesc));
402 }
403 
404 void
405 dev_midi_dump(struct dev *d)
406 {
407 	struct sysex x;
408 	struct slot *s;
409 	int i;
410 
411 	dev_midi_master(d);
412 	for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) {
413 		dev_midi_slotdesc(d, s);
414 		dev_midi_vol(d, s);
415 	}
416 	x.start = SYSEX_START;
417 	x.type = SYSEX_TYPE_EDU;
418 	x.dev = SYSEX_DEV_ANY;
419 	x.id0 = SYSEX_AUCAT;
420 	x.id1 = SYSEX_AUCAT_DUMPEND;
421 	x.u.dumpend.end = SYSEX_END;
422 	midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(dumpend));
423 }
424 
425 void
426 dev_midi_imsg(void *arg, unsigned char *msg, int len)
427 {
428 #ifdef DEBUG
429 	struct dev *d = arg;
430 
431 	dev_log(d);
432 	log_puts(": can't receive midi messages\n");
433 	panic();
434 #endif
435 }
436 
437 void
438 dev_midi_omsg(void *arg, unsigned char *msg, int len)
439 {
440 	struct dev *d = arg;
441 	struct sysex *x;
442 	unsigned int fps, chan;
443 
444 	if ((msg[0] & MIDI_CMDMASK) == MIDI_CTL && msg[1] == MIDI_CTL_VOL) {
445 		chan = msg[0] & MIDI_CHANMASK;
446 		if (chan >= DEV_NSLOT)
447 			return;
448 		slot_setvol(d->slot + chan, msg[2]);
449 		dev_onval(d, CTLADDR_SLOT_LEVEL(chan), msg[2]);
450 		return;
451 	}
452 	x = (struct sysex *)msg;
453 	if (x->start != SYSEX_START)
454 		return;
455 	if (len < SYSEX_SIZE(empty))
456 		return;
457 	switch (x->type) {
458 	case SYSEX_TYPE_RT:
459 		if (x->id0 == SYSEX_CONTROL && x->id1 == SYSEX_MASTER) {
460 			if (len == SYSEX_SIZE(master)) {
461 				dev_master(d, x->u.master.coarse);
462 				if (d->master_enabled) {
463 					dev_onval(d, CTLADDR_MASTER,
464 					   x->u.master.coarse);
465 				}
466 			}
467 			return;
468 		}
469 		if (x->id0 != SYSEX_MMC)
470 			return;
471 		switch (x->id1) {
472 		case SYSEX_MMC_STOP:
473 			if (len != SYSEX_SIZE(stop))
474 				return;
475 			if (log_level >= 2) {
476 				dev_log(d);
477 				log_puts(": mmc stop\n");
478 			}
479 			dev_mmcstop(d);
480 			break;
481 		case SYSEX_MMC_START:
482 			if (len != SYSEX_SIZE(start))
483 				return;
484 			if (log_level >= 2) {
485 				dev_log(d);
486 				log_puts(": mmc start\n");
487 			}
488 			dev_mmcstart(d);
489 			break;
490 		case SYSEX_MMC_LOC:
491 			if (len != SYSEX_SIZE(loc) ||
492 			    x->u.loc.len != SYSEX_MMC_LOC_LEN ||
493 			    x->u.loc.cmd != SYSEX_MMC_LOC_CMD)
494 				return;
495 			switch (x->u.loc.hr >> 5) {
496 			case MTC_FPS_24:
497 				fps = 24;
498 				break;
499 			case MTC_FPS_25:
500 				fps = 25;
501 				break;
502 			case MTC_FPS_30:
503 				fps = 30;
504 				break;
505 			default:
506 				dev_mmcstop(d);
507 				return;
508 			}
509 			dev_mmcloc(d,
510 			    (x->u.loc.hr & 0x1f) * 3600 * MTC_SEC +
511 			     x->u.loc.min * 60 * MTC_SEC +
512 			     x->u.loc.sec * MTC_SEC +
513 			     x->u.loc.fr * (MTC_SEC / fps));
514 			break;
515 		}
516 		break;
517 	case SYSEX_TYPE_EDU:
518 		if (x->id0 != SYSEX_AUCAT || x->id1 != SYSEX_AUCAT_DUMPREQ)
519 			return;
520 		if (len != SYSEX_SIZE(dumpreq))
521 			return;
522 		dev_midi_dump(d);
523 		break;
524 	}
525 }
526 
527 void
528 dev_midi_fill(void *arg, int count)
529 {
530 	/* nothing to do */
531 }
532 
533 void
534 dev_midi_exit(void *arg)
535 {
536 	struct dev *d = arg;
537 
538 	if (log_level >= 1) {
539 		dev_log(d);
540 		log_puts(": midi end point died\n");
541 	}
542 	if (d->pstate != DEV_CFG)
543 		dev_close(d);
544 }
545 
546 int
547 slot_skip(struct slot *s)
548 {
549 	unsigned char *data = (unsigned char *)0xdeadbeef; /* please gcc */
550 	int max, count;
551 
552 	max = s->skip;
553 	while (s->skip > 0) {
554 		if (s->pstate != SLOT_STOP && (s->mode & MODE_RECMASK)) {
555 			data = abuf_wgetblk(&s->sub.buf, &count);
556 			if (count < s->round * s->sub.bpf)
557 				break;
558 		}
559 		if (s->mode & MODE_PLAY) {
560 			if (s->mix.buf.used < s->round * s->mix.bpf)
561 				break;
562 		}
563 #ifdef DEBUG
564 		if (log_level >= 4) {
565 			slot_log(s);
566 			log_puts(": skipped a cycle\n");
567 		}
568 #endif
569 		if (s->pstate != SLOT_STOP && (s->mode & MODE_RECMASK)) {
570 			if (s->sub.encbuf)
571 				enc_sil_do(&s->sub.enc, data, s->round);
572 			else
573 				memset(data, 0, s->round * s->sub.bpf);
574 			abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf);
575 		}
576 		if (s->mode & MODE_PLAY) {
577 			abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
578 		}
579 		s->skip--;
580 	}
581 	return max - s->skip;
582 }
583 
584 /*
585  * Mix the slot input block over the output block
586  */
587 void
588 dev_mix_badd(struct dev *d, struct slot *s)
589 {
590 	adata_t *idata, *odata, *in;
591 	int icount, i, offs, vol, nch;
592 
593 	odata = DEV_PBUF(d);
594 	idata = (adata_t *)abuf_rgetblk(&s->mix.buf, &icount);
595 #ifdef DEBUG
596 	if (icount < s->round * s->mix.bpf) {
597 		slot_log(s);
598 		log_puts(": not enough data to mix (");
599 		log_putu(icount);
600 		log_puts("bytes)\n");
601 		panic();
602 	}
603 #endif
604 
605 	/*
606 	 * Apply the following processing chain:
607 	 *
608 	 *	dec -> resamp-> cmap
609 	 *
610 	 * where the first two are optional.
611 	 */
612 
613 	in = idata;
614 
615 	if (s->mix.decbuf) {
616 		dec_do(&s->mix.dec, (void *)in, s->mix.decbuf, s->round);
617 		in = s->mix.decbuf;
618 	}
619 
620 	if (s->mix.resampbuf) {
621 		resamp_do(&s->mix.resamp, in, s->mix.resampbuf, s->round);
622 		in = s->mix.resampbuf;
623 	}
624 
625 	nch = s->mix.cmap.nch;
626 	vol = ADATA_MUL(s->mix.weight, s->mix.vol) / s->mix.join;
627 	cmap_add(&s->mix.cmap, in, odata, vol, d->round);
628 
629 	offs = 0;
630 	for (i = s->mix.join - 1; i > 0; i--) {
631 		offs += nch;
632 		cmap_add(&s->mix.cmap, in + offs, odata, vol, d->round);
633 	}
634 
635 	offs = 0;
636 	for (i = s->mix.expand - 1; i > 0; i--) {
637 		offs += nch;
638 		cmap_add(&s->mix.cmap, in, odata + offs, vol, d->round);
639 	}
640 
641 	abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
642 }
643 
644 /*
645  * Normalize input levels.
646  */
647 void
648 dev_mix_adjvol(struct dev *d)
649 {
650 	unsigned int n;
651 	struct slot *i, *j;
652 	int jcmax, icmax, weight;
653 
654 	for (i = d->slot_list; i != NULL; i = i->next) {
655 		if (!(i->mode & MODE_PLAY))
656 			continue;
657 		icmax = i->opt->pmin + i->mix.nch - 1;
658 		weight = ADATA_UNIT;
659 		if (d->autovol) {
660 			/*
661 			 * count the number of inputs that have
662 			 * overlapping channel sets
663 			 */
664 			n = 0;
665 			for (j = d->slot_list; j != NULL; j = j->next) {
666 				if (!(j->mode & MODE_PLAY))
667 					continue;
668 				jcmax = j->opt->pmin + j->mix.nch - 1;
669 				if (i->opt->pmin <= jcmax &&
670 				    icmax >= j->opt->pmin)
671 					n++;
672 			}
673 			weight /= n;
674 		}
675 		if (weight > i->opt->maxweight)
676 			weight = i->opt->maxweight;
677 		i->mix.weight = d->master_enabled ?
678 		    ADATA_MUL(weight, MIDI_TO_ADATA(d->master)) : weight;
679 #ifdef DEBUG
680 		if (log_level >= 3) {
681 			slot_log(i);
682 			log_puts(": set weight: ");
683 			log_puti(i->mix.weight);
684 			log_puts("/");
685 			log_puti(i->opt->maxweight);
686 			log_puts("\n");
687 		}
688 #endif
689 	}
690 }
691 
692 /*
693  * Copy data from slot to device
694  */
695 void
696 dev_sub_bcopy(struct dev *d, struct slot *s)
697 {
698 	adata_t *idata, *enc_out, *resamp_out, *cmap_out;
699 	void *odata;
700 	int ocount, moffs;
701 
702 	int i, vol, offs, nch;
703 
704 
705 	if (s->mode & MODE_MON) {
706 		moffs = d->poffs + d->round;
707 		if (moffs == d->psize)
708 			moffs = 0;
709 		idata = d->pbuf + moffs * d->pchan;
710 	} else
711 		idata = d->rbuf;
712 	odata = (adata_t *)abuf_wgetblk(&s->sub.buf, &ocount);
713 #ifdef DEBUG
714 	if (ocount < s->round * s->sub.bpf) {
715 		log_puts("dev_sub_bcopy: not enough space\n");
716 		panic();
717 	}
718 #endif
719 
720 	/*
721 	 * Apply the following processing chain:
722 	 *
723 	 *	cmap -> resamp -> enc
724 	 *
725 	 * where the last two are optional.
726 	 */
727 
728 	enc_out = odata;
729 	resamp_out = s->sub.encbuf ? s->sub.encbuf : enc_out;
730 	cmap_out = s->sub.resampbuf ? s->sub.resampbuf : resamp_out;
731 
732 	nch = s->sub.cmap.nch;
733 	vol = ADATA_UNIT / s->sub.join;
734 	cmap_copy(&s->sub.cmap, idata, cmap_out, vol, d->round);
735 
736 	offs = 0;
737 	for (i = s->sub.join - 1; i > 0; i--) {
738 		offs += nch;
739 		cmap_add(&s->sub.cmap, idata + offs, cmap_out, vol, d->round);
740 	}
741 
742 	offs = 0;
743 	for (i = s->sub.expand - 1; i > 0; i--) {
744 		offs += nch;
745 		cmap_copy(&s->sub.cmap, idata, cmap_out + offs, vol, d->round);
746 	}
747 
748 	if (s->sub.resampbuf) {
749 		resamp_do(&s->sub.resamp,
750 		    s->sub.resampbuf, resamp_out, d->round);
751 	}
752 
753 	if (s->sub.encbuf)
754 		enc_do(&s->sub.enc, s->sub.encbuf, (void *)enc_out, s->round);
755 
756 	abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf);
757 }
758 
759 /*
760  * run a one block cycle: consume one recorded block from
761  * rbuf and produce one play block in pbuf
762  */
763 void
764 dev_cycle(struct dev *d)
765 {
766 	struct slot *s, **ps;
767 	unsigned char *base;
768 	int nsamp;
769 
770 	/*
771 	 * check if the device is actually used. If it isn't,
772 	 * then close it
773 	 */
774 	if (d->slot_list == NULL && d->tstate != MMC_RUN) {
775 		if (log_level >= 2) {
776 			dev_log(d);
777 			log_puts(": device stopped\n");
778 		}
779 		dev_sio_stop(d);
780 		d->pstate = DEV_INIT;
781 		if (d->refcnt == 0)
782 			dev_close(d);
783 		return;
784 	}
785 
786 	if (d->prime > 0) {
787 #ifdef DEBUG
788 		if (log_level >= 4) {
789 			dev_log(d);
790 			log_puts(": empty cycle, prime = ");
791 			log_putu(d->prime);
792 			log_puts("\n");
793 		}
794 #endif
795 		base = (unsigned char *)DEV_PBUF(d);
796 		nsamp = d->round * d->pchan;
797 		memset(base, 0, nsamp * sizeof(adata_t));
798 		if (d->encbuf) {
799 			enc_do(&d->enc, (unsigned char *)DEV_PBUF(d),
800 			    d->encbuf, d->round);
801 		}
802 		d->prime -= d->round;
803 		return;
804 	}
805 
806 	d->delta -= d->round;
807 #ifdef DEBUG
808 	if (log_level >= 4) {
809 		dev_log(d);
810 		log_puts(": full cycle: delta = ");
811 		log_puti(d->delta);
812 		if (d->mode & MODE_PLAY) {
813 			log_puts(", poffs = ");
814 			log_puti(d->poffs);
815 		}
816 		log_puts("\n");
817 	}
818 #endif
819 	if (d->mode & MODE_PLAY) {
820 		base = (unsigned char *)DEV_PBUF(d);
821 		nsamp = d->round * d->pchan;
822 		memset(base, 0, nsamp * sizeof(adata_t));
823 	}
824 	if ((d->mode & MODE_REC) && d->decbuf)
825 		dec_do(&d->dec, d->decbuf, (unsigned char *)d->rbuf, d->round);
826 	ps = &d->slot_list;
827 	while ((s = *ps) != NULL) {
828 #ifdef DEBUG
829 		if (log_level >= 4) {
830 			slot_log(s);
831 			log_puts(": running");
832 			log_puts(", skip = ");
833 			log_puti(s->skip);
834 			log_puts("\n");
835 		}
836 #endif
837 		/*
838 		 * skip cycles for XRUN_SYNC correction
839 		 */
840 		slot_skip(s);
841 		if (s->skip < 0) {
842 			s->skip++;
843 			ps = &s->next;
844 			continue;
845 		}
846 
847 #ifdef DEBUG
848 		if (s->pstate == SLOT_STOP && !(s->mode & MODE_PLAY)) {
849 			slot_log(s);
850 			log_puts(": rec-only slots can't be drained\n");
851 			panic();
852 		}
853 #endif
854 		/*
855 		 * check if stopped stream finished draining
856 		 */
857 		if (s->pstate == SLOT_STOP &&
858 		    s->mix.buf.used < s->round * s->mix.bpf) {
859 			/*
860 			 * partial blocks are zero-filled by socket
861 			 * layer, so s->mix.buf.used == 0 and we can
862 			 * destroy the buffer
863 			 */
864 			*ps = s->next;
865 			s->pstate = SLOT_INIT;
866 			s->ops->eof(s->arg);
867 			slot_freebufs(s);
868 			dev_mix_adjvol(d);
869 #ifdef DEBUG
870 			if (log_level >= 3) {
871 				slot_log(s);
872 				log_puts(": drained\n");
873 			}
874 #endif
875 			continue;
876 		}
877 
878 		/*
879 		 * check for xruns
880 		 */
881 		if (((s->mode & MODE_PLAY) &&
882 			s->mix.buf.used < s->round * s->mix.bpf) ||
883 		    ((s->mode & MODE_RECMASK) &&
884 			s->sub.buf.len - s->sub.buf.used <
885 			s->round * s->sub.bpf)) {
886 
887 #ifdef DEBUG
888 			if (log_level >= 3) {
889 				slot_log(s);
890 				log_puts(": xrun, pause cycle\n");
891 			}
892 #endif
893 			if (s->xrun == XRUN_IGNORE) {
894 				s->delta -= s->round;
895 				ps = &s->next;
896 			} else if (s->xrun == XRUN_SYNC) {
897 				s->skip++;
898 				ps = &s->next;
899 			} else if (s->xrun == XRUN_ERROR) {
900 				s->ops->exit(s->arg);
901 				*ps = s->next;
902 			} else {
903 #ifdef DEBUG
904 				slot_log(s);
905 				log_puts(": bad xrun mode\n");
906 				panic();
907 #endif
908 			}
909 			continue;
910 		}
911 		if ((s->mode & MODE_RECMASK) && !(s->pstate == SLOT_STOP)) {
912 			if (s->sub.prime == 0) {
913 				dev_sub_bcopy(d, s);
914 				s->ops->flush(s->arg);
915 			} else {
916 #ifdef DEBUG
917 				if (log_level >= 3) {
918 					slot_log(s);
919 					log_puts(": prime = ");
920 					log_puti(s->sub.prime);
921 					log_puts("\n");
922 				}
923 #endif
924 				s->sub.prime--;
925 			}
926 		}
927 		if (s->mode & MODE_PLAY) {
928 			dev_mix_badd(d, s);
929 			if (s->pstate != SLOT_STOP)
930 				s->ops->fill(s->arg);
931 		}
932 		ps = &s->next;
933 	}
934 	if ((d->mode & MODE_PLAY) && d->encbuf) {
935 		enc_do(&d->enc, (unsigned char *)DEV_PBUF(d),
936 		    d->encbuf, d->round);
937 	}
938 }
939 
940 /*
941  * called at every clock tick by the device
942  */
943 void
944 dev_onmove(struct dev *d, int delta)
945 {
946 	long long pos;
947 	struct slot *s, *snext;
948 
949 	d->delta += delta;
950 
951 	for (s = d->slot_list; s != NULL; s = snext) {
952 		/*
953 		 * s->ops->onmove() may remove the slot
954 		 */
955 		snext = s->next;
956 		pos = (long long)delta * s->round + s->delta_rem;
957 		s->delta_rem = pos % d->round;
958 		s->delta += pos / (int)d->round;
959 		if (s->delta >= 0)
960 			s->ops->onmove(s->arg);
961 	}
962 	if (d->tstate == MMC_RUN)
963 		dev_midi_qfr(d, delta);
964 }
965 
966 void
967 dev_master(struct dev *d, unsigned int master)
968 {
969 	struct ctl *c;
970 	unsigned int v;
971 
972 	if (log_level >= 2) {
973 		dev_log(d);
974 		log_puts(": master volume set to ");
975 		log_putu(master);
976 		log_puts("\n");
977 	}
978 	if (d->master_enabled) {
979 		d->master = master;
980 		if (d->mode & MODE_PLAY)
981 			dev_mix_adjvol(d);
982 	} else {
983 		for (c = d->ctl_list; c != NULL; c = c->next) {
984 			if (c->type != CTL_NUM ||
985 			    strcmp(c->group, "") != 0 ||
986 			    strcmp(c->node0.name, "output") != 0 ||
987 			    strcmp(c->func, "level") != 0)
988 				continue;
989 			v = (master * c->maxval + 64) / 127;
990 			dev_setctl(d, c->addr, v);
991 		}
992 	}
993 }
994 
995 /*
996  * return the latency that a stream would have if it's attached
997  */
998 int
999 dev_getpos(struct dev *d)
1000 {
1001 	return (d->mode & MODE_PLAY) ? -d->bufsz : 0;
1002 }
1003 
1004 /*
1005  * Create a sndio device
1006  */
1007 struct dev *
1008 dev_new(char *path, struct aparams *par,
1009     unsigned int mode, unsigned int bufsz, unsigned int round,
1010     unsigned int rate, unsigned int hold, unsigned int autovol)
1011 {
1012 	struct dev *d;
1013 	unsigned int i;
1014 
1015 	if (dev_sndnum == DEV_NMAX) {
1016 		if (log_level >= 1)
1017 			log_puts("too many devices\n");
1018 		return NULL;
1019 	}
1020 	d = xmalloc(sizeof(struct dev));
1021 	d->alt_list = NULL;
1022 	dev_addname(d,path);
1023 	d->num = dev_sndnum++;
1024 	d->opt_list = NULL;
1025 	d->alt_num = -1;
1026 
1027 	/*
1028 	 * XXX: below, we allocate a midi input buffer, since we don't
1029 	 *	receive raw midi data, so no need to allocate a input
1030 	 *	ibuf.  Possibly set imsg & fill callbacks to NULL and
1031 	 *	use this to in midi_new() to check if buffers need to be
1032 	 *	allocated
1033 	 */
1034 	d->midi = midi_new(&dev_midiops, d, MODE_MIDIIN | MODE_MIDIOUT);
1035 	midi_tag(d->midi, d->num);
1036 	d->reqpar = *par;
1037 	d->reqmode = mode;
1038 	d->reqpchan = d->reqrchan = 0;
1039 	d->reqbufsz = bufsz;
1040 	d->reqround = round;
1041 	d->reqrate = rate;
1042 	d->hold = hold;
1043 	d->autovol = autovol;
1044 	d->refcnt = 0;
1045 	d->pstate = DEV_CFG;
1046 	d->serial = 0;
1047 	for (i = 0; i < DEV_NSLOT; i++) {
1048 		d->slot[i].unit = i;
1049 		d->slot[i].ops = NULL;
1050 		d->slot[i].vol = MIDI_MAXCTL;
1051 		d->slot[i].serial = d->serial++;
1052 		memset(d->slot[i].name, 0, SLOT_NAMEMAX);
1053 	}
1054 	for (i = 0; i < DEV_NCTLSLOT; i++) {
1055 		d->ctlslot[i].ops = NULL;
1056 		d->ctlslot[i].dev = d;
1057 		d->ctlslot[i].mask = 0;
1058 		d->ctlslot[i].mode = 0;
1059 	}
1060 	d->slot_list = NULL;
1061 	d->master = MIDI_MAXCTL;
1062 	d->mtc.origin = 0;
1063 	d->tstate = MMC_STOP;
1064 	d->ctl_list = NULL;
1065 	d->next = dev_list;
1066 	dev_list = d;
1067 	return d;
1068 }
1069 
1070 /*
1071  * add a alternate name
1072  */
1073 int
1074 dev_addname(struct dev *d, char *name)
1075 {
1076 	struct dev_alt *a;
1077 
1078 	if (d->alt_list != NULL && d->alt_list->idx == DEV_NMAX - 1) {
1079 		log_puts(name);
1080 		log_puts(": too many alternate names\n");
1081 		return 0;
1082 	}
1083 	a = xmalloc(sizeof(struct dev_alt));
1084 	a->name = name;
1085 	a->idx = (d->alt_list == NULL) ? 0 : d->alt_list->idx + 1;
1086 	a->next = d->alt_list;
1087 	d->alt_list = a;
1088 	return 1;
1089 }
1090 
1091 /*
1092  * set prefered alt device name
1093  */
1094 void
1095 dev_setalt(struct dev *d, unsigned int idx)
1096 {
1097 	struct dev_alt **pa, *a;
1098 
1099 	/* find alt with given index */
1100 	for (pa = &d->alt_list; (a = *pa)->idx != idx; pa = &a->next)
1101 		;
1102 
1103 	/* detach from list */
1104 	*pa = a->next;
1105 
1106 	/* attach at head */
1107 	a->next = d->alt_list;
1108 	d->alt_list = a;
1109 
1110 	/* reopen device with the new alt */
1111 	if (idx != d->alt_num)
1112 		dev_reopen(d);
1113 }
1114 
1115 /*
1116  * adjust device parameters and mode
1117  */
1118 void
1119 dev_adjpar(struct dev *d, int mode,
1120     int pmax, int rmax)
1121 {
1122 	d->reqmode |= mode & MODE_AUDIOMASK;
1123 	if (mode & MODE_PLAY) {
1124 		if (d->reqpchan < pmax + 1)
1125 			d->reqpchan = pmax + 1;
1126 	}
1127 	if (mode & MODE_REC) {
1128 		if (d->reqrchan < rmax + 1)
1129 			d->reqrchan = rmax + 1;
1130 	}
1131 }
1132 
1133 /*
1134  * Open the device with the dev_reqxxx capabilities. Setup a mixer, demuxer,
1135  * monitor, midi control, and any necessary conversions.
1136  */
1137 int
1138 dev_allocbufs(struct dev *d)
1139 {
1140 	if (d->mode & MODE_REC) {
1141 		/*
1142 		 * Create device <-> demuxer buffer
1143 		 */
1144 		d->rbuf = xmalloc(d->round * d->rchan * sizeof(adata_t));
1145 
1146 		/*
1147 		 * Insert a converter, if needed.
1148 		 */
1149 		if (!aparams_native(&d->par)) {
1150 			dec_init(&d->dec, &d->par, d->rchan);
1151 			d->decbuf = xmalloc(d->round * d->rchan * d->par.bps);
1152 		} else
1153 			d->decbuf = NULL;
1154 	}
1155 	if (d->mode & MODE_PLAY) {
1156 		/*
1157 		 * Create device <-> mixer buffer
1158 		 */
1159 		d->poffs = 0;
1160 		d->psize = d->bufsz + d->round;
1161 		d->pbuf = xmalloc(d->psize * d->pchan * sizeof(adata_t));
1162 		d->mode |= MODE_MON;
1163 
1164 		/*
1165 		 * Append a converter, if needed.
1166 		 */
1167 		if (!aparams_native(&d->par)) {
1168 			enc_init(&d->enc, &d->par, d->pchan);
1169 			d->encbuf = xmalloc(d->round * d->pchan * d->par.bps);
1170 		} else
1171 			d->encbuf = NULL;
1172 	}
1173 	if (log_level >= 2) {
1174 		dev_log(d);
1175 		log_puts(": ");
1176 		log_putu(d->rate);
1177 		log_puts("Hz, ");
1178 		aparams_log(&d->par);
1179 		if (d->mode & MODE_PLAY) {
1180 			log_puts(", play 0:");
1181 			log_puti(d->pchan - 1);
1182 		}
1183 		if (d->mode & MODE_REC) {
1184 			log_puts(", rec 0:");
1185 			log_puti(d->rchan - 1);
1186 		}
1187 		log_puts(", ");
1188 		log_putu(d->bufsz / d->round);
1189 		log_puts(" blocks of ");
1190 		log_putu(d->round);
1191 		log_puts(" frames\n");
1192 	}
1193 	return 1;
1194 }
1195 
1196 /*
1197  * Reset parameters and open the device.
1198  */
1199 int
1200 dev_open(struct dev *d)
1201 {
1202 	int i;
1203 	char name[CTL_NAMEMAX];
1204 	struct dev_alt *a;
1205 
1206 	d->master_enabled = 0;
1207 	d->mode = d->reqmode;
1208 	d->round = d->reqround;
1209 	d->bufsz = d->reqbufsz;
1210 	d->rate = d->reqrate;
1211 	d->pchan = d->reqpchan;
1212 	d->rchan = d->reqrchan;
1213 	d->par = d->reqpar;
1214 	if (d->pchan == 0)
1215 		d->pchan = 2;
1216 	if (d->rchan == 0)
1217 		d->rchan = 2;
1218 	if (!dev_sio_open(d)) {
1219 		if (log_level >= 1) {
1220 			dev_log(d);
1221 			log_puts(": failed to open audio device\n");
1222 		}
1223 		return 0;
1224 	}
1225 	if (!dev_allocbufs(d))
1226 		return 0;
1227 
1228 	for (i = 0; i < DEV_NSLOT; i++) {
1229 		if (d->slot[i].name[0] == 0)
1230 			continue;
1231 		slot_ctlname(&d->slot[i], name, CTL_NAMEMAX);
1232 		dev_addctl(d, "app", CTL_NUM,
1233 		    CTLADDR_SLOT_LEVEL(i),
1234 		    name, -1, "level",
1235 		    NULL, -1, 127, d->slot[i].vol);
1236 	}
1237 
1238 	/* if there are multiple alt devs, add server.device knob */
1239 	if (d->alt_list->next != NULL) {
1240 		for (a = d->alt_list; a != NULL; a = a->next) {
1241 			snprintf(name, sizeof(name), "%d", a->idx);
1242 			dev_addctl(d, "", CTL_SEL,
1243 			    CTLADDR_ALT_SEL + a->idx,
1244 			    "server", -1, "device",
1245 			    name, -1, 1, a->idx == d->alt_num);
1246 		}
1247 	}
1248 
1249 	d->pstate = DEV_INIT;
1250 	return 1;
1251 }
1252 
1253 /*
1254  * Force all slots to exit and close device, called after an error
1255  */
1256 void
1257 dev_abort(struct dev *d)
1258 {
1259 	int i;
1260 	struct slot *s;
1261 	struct ctlslot *c;
1262 
1263 	for (s = d->slot, i = DEV_NSLOT; i > 0; i--, s++) {
1264 		if (s->ops)
1265 			s->ops->exit(s->arg);
1266 		s->ops = NULL;
1267 	}
1268 	d->slot_list = NULL;
1269 
1270 	for (c = d->ctlslot, i = DEV_NCTLSLOT; i > 0; i--, c++) {
1271 		if (c->ops)
1272 			c->ops->exit(c->arg);
1273 		c->ops = NULL;
1274 	}
1275 
1276 	if (d->pstate != DEV_CFG)
1277 		dev_close(d);
1278 }
1279 
1280 /*
1281  * force the device to go in DEV_CFG state, the caller is supposed to
1282  * ensure buffers are drained
1283  */
1284 void
1285 dev_freebufs(struct dev *d)
1286 {
1287 #ifdef DEBUG
1288 	if (log_level >= 3) {
1289 		dev_log(d);
1290 		log_puts(": closing\n");
1291 	}
1292 #endif
1293 	if (d->mode & MODE_PLAY) {
1294 		if (d->encbuf != NULL)
1295 			xfree(d->encbuf);
1296 		xfree(d->pbuf);
1297 	}
1298 	if (d->mode & MODE_REC) {
1299 		if (d->decbuf != NULL)
1300 			xfree(d->decbuf);
1301 		xfree(d->rbuf);
1302 	}
1303 }
1304 
1305 /*
1306  * Close the device and exit all slots
1307  */
1308 void
1309 dev_close(struct dev *d)
1310 {
1311 	struct ctl *c;
1312 
1313 	d->pstate = DEV_CFG;
1314 	dev_sio_close(d);
1315 	dev_freebufs(d);
1316 
1317 	/* there are no clients, just free remaining local controls */
1318 	while ((c = d->ctl_list) != NULL) {
1319 		d->ctl_list = c->next;
1320 		xfree(c);
1321 	}
1322 }
1323 
1324 /*
1325  * Close the device, but attempt to migrate everything to a new sndio
1326  * device.
1327  */
1328 int
1329 dev_reopen(struct dev *d)
1330 {
1331 	struct slot *s;
1332 	long long pos;
1333 	unsigned int pstate;
1334 	int delta;
1335 
1336 	/* not opened */
1337 	if (d->pstate == DEV_CFG)
1338 		return 1;
1339 
1340 	/* save state */
1341 	delta = d->delta;
1342 	pstate = d->pstate;
1343 
1344 	if (!dev_sio_reopen(d))
1345 		return 0;
1346 
1347 	/* reopen returns a stopped device */
1348 	d->pstate = DEV_INIT;
1349 
1350 	/* reallocate new buffers, with new parameters */
1351 	dev_freebufs(d);
1352 	dev_allocbufs(d);
1353 
1354 	/*
1355 	 * adjust time positions, make anything go back delta ticks, so
1356 	 * that the new device can start at zero
1357 	 */
1358 	for (s = d->slot_list; s != NULL; s = s->next) {
1359 		pos = (long long)s->delta * d->round + s->delta_rem;
1360 		pos -= (long long)delta * s->round;
1361 		s->delta_rem = pos % (int)d->round;
1362 		s->delta = pos / (int)d->round;
1363 		if (log_level >= 3) {
1364 			slot_log(s);
1365 			log_puts(": adjusted: delta -> ");
1366 			log_puti(s->delta);
1367 			log_puts(", delta_rem -> ");
1368 			log_puti(s->delta_rem);
1369 			log_puts("\n");
1370 		}
1371 
1372 		/* reinitilize the format conversion chain */
1373 		slot_initconv(s);
1374 	}
1375 	if (d->tstate == MMC_RUN) {
1376 		d->mtc.delta -= delta * MTC_SEC;
1377 		if (log_level >= 2) {
1378 			dev_log(d);
1379 			log_puts(": adjusted mtc: delta ->");
1380 			log_puti(d->mtc.delta);
1381 			log_puts("\n");
1382 		}
1383 	}
1384 
1385 	/* remove old controls and add new ones */
1386 	dev_sioctl_close(d);
1387 	dev_sioctl_open(d);
1388 
1389 	/* start the device if needed */
1390 	if (pstate == DEV_RUN)
1391 		dev_wakeup(d);
1392 
1393 	return 1;
1394 }
1395 
1396 int
1397 dev_ref(struct dev *d)
1398 {
1399 #ifdef DEBUG
1400 	if (log_level >= 3) {
1401 		dev_log(d);
1402 		log_puts(": device requested\n");
1403 	}
1404 #endif
1405 	if (d->pstate == DEV_CFG && !dev_open(d))
1406 		return 0;
1407 	d->refcnt++;
1408 	return 1;
1409 }
1410 
1411 void
1412 dev_unref(struct dev *d)
1413 {
1414 #ifdef DEBUG
1415 	if (log_level >= 3) {
1416 		dev_log(d);
1417 		log_puts(": device released\n");
1418 	}
1419 #endif
1420 	d->refcnt--;
1421 	if (d->refcnt == 0 && d->pstate == DEV_INIT)
1422 		dev_close(d);
1423 }
1424 
1425 /*
1426  * initialize the device with the current parameters
1427  */
1428 int
1429 dev_init(struct dev *d)
1430 {
1431 	if ((d->reqmode & MODE_AUDIOMASK) == 0) {
1432 #ifdef DEBUG
1433 		    dev_log(d);
1434 		    log_puts(": has no streams\n");
1435 #endif
1436 		    return 0;
1437 	}
1438 	if (d->hold && !dev_ref(d))
1439 		return 0;
1440 	return 1;
1441 }
1442 
1443 /*
1444  * Unless the device is already in process of closing, request it to close
1445  */
1446 void
1447 dev_done(struct dev *d)
1448 {
1449 #ifdef DEBUG
1450 	if (log_level >= 3) {
1451 		dev_log(d);
1452 		log_puts(": draining\n");
1453 	}
1454 #endif
1455 	if (d->tstate != MMC_STOP)
1456 		dev_mmcstop(d);
1457 	if (d->hold)
1458 		dev_unref(d);
1459 }
1460 
1461 struct dev *
1462 dev_bynum(int num)
1463 {
1464 	struct dev *d;
1465 
1466 	for (d = dev_list; d != NULL; d = d->next) {
1467 		if (d->num == num)
1468 			return d;
1469 	}
1470 	return NULL;
1471 }
1472 
1473 /*
1474  * Free the device
1475  */
1476 void
1477 dev_del(struct dev *d)
1478 {
1479 	struct dev **p;
1480 	struct dev_alt *a;
1481 
1482 #ifdef DEBUG
1483 	if (log_level >= 3) {
1484 		dev_log(d);
1485 		log_puts(": deleting\n");
1486 	}
1487 #endif
1488 	while (d->opt_list != NULL)
1489 		opt_del(d, d->opt_list);
1490 	if (d->pstate != DEV_CFG)
1491 		dev_close(d);
1492 	for (p = &dev_list; *p != d; p = &(*p)->next) {
1493 #ifdef DEBUG
1494 		if (*p == NULL) {
1495 			dev_log(d);
1496 			log_puts(": device to delete not on the list\n");
1497 			panic();
1498 		}
1499 #endif
1500 	}
1501 	midi_del(d->midi);
1502 	*p = d->next;
1503 	while ((a = d->alt_list) != NULL) {
1504 		d->alt_list = a->next;
1505 		xfree(a);
1506 	}
1507 	xfree(d);
1508 }
1509 
1510 unsigned int
1511 dev_roundof(struct dev *d, unsigned int newrate)
1512 {
1513 	return (d->round * newrate + d->rate / 2) / d->rate;
1514 }
1515 
1516 /*
1517  * If the device is paused, then resume it.
1518  */
1519 void
1520 dev_wakeup(struct dev *d)
1521 {
1522 	if (d->pstate == DEV_INIT) {
1523 		if (log_level >= 2) {
1524 			dev_log(d);
1525 			log_puts(": device started\n");
1526 		}
1527 		if (d->mode & MODE_PLAY) {
1528 			d->prime = d->bufsz;
1529 		} else {
1530 			d->prime = 0;
1531 		}
1532 		d->poffs = 0;
1533 
1534 		/*
1535 		 * empty cycles don't increment delta, so it's ok to
1536 		 * start at 0
1537 		 **/
1538 		d->delta = 0;
1539 
1540 		d->pstate = DEV_RUN;
1541 		dev_sio_start(d);
1542 	}
1543 }
1544 
1545 /*
1546  * check that all clients controlled by MMC are ready to start, if so,
1547  * attach them all at the same position
1548  */
1549 void
1550 dev_sync_attach(struct dev *d)
1551 {
1552 	int i;
1553 	struct slot *s;
1554 
1555 	if (d->tstate != MMC_START) {
1556 		if (log_level >= 2) {
1557 			dev_log(d);
1558 			log_puts(": not started by mmc yet, waiting...\n");
1559 		}
1560 		return;
1561 	}
1562 	for (i = 0; i < DEV_NSLOT; i++) {
1563 		s = d->slot + i;
1564 		if (!s->ops || !s->opt->mmc)
1565 			continue;
1566 		if (s->pstate != SLOT_READY) {
1567 #ifdef DEBUG
1568 			if (log_level >= 3) {
1569 				slot_log(s);
1570 				log_puts(": not ready, start delayed\n");
1571 			}
1572 #endif
1573 			return;
1574 		}
1575 	}
1576 	if (!dev_ref(d))
1577 		return;
1578 	for (i = 0; i < DEV_NSLOT; i++) {
1579 		s = d->slot + i;
1580 		if (!s->ops || !s->opt->mmc)
1581 			continue;
1582 		slot_attach(s);
1583 	}
1584 	d->tstate = MMC_RUN;
1585 	dev_midi_full(d);
1586 	dev_wakeup(d);
1587 }
1588 
1589 /*
1590  * start all slots simultaneously
1591  */
1592 void
1593 dev_mmcstart(struct dev *d)
1594 {
1595 	if (d->tstate == MMC_STOP) {
1596 		d->tstate = MMC_START;
1597 		dev_sync_attach(d);
1598 #ifdef DEBUG
1599 	} else {
1600 		if (log_level >= 3) {
1601 			dev_log(d);
1602 			log_puts(": ignoring mmc start\n");
1603 		}
1604 #endif
1605 	}
1606 }
1607 
1608 /*
1609  * stop all slots simultaneously
1610  */
1611 void
1612 dev_mmcstop(struct dev *d)
1613 {
1614 	switch (d->tstate) {
1615 	case MMC_START:
1616 		d->tstate = MMC_STOP;
1617 		return;
1618 	case MMC_RUN:
1619 		d->tstate = MMC_STOP;
1620 		dev_unref(d);
1621 		break;
1622 	default:
1623 #ifdef DEBUG
1624 		if (log_level >= 3) {
1625 			dev_log(d);
1626 			log_puts(": ignored mmc stop\n");
1627 		}
1628 #endif
1629 		return;
1630 	}
1631 }
1632 
1633 /*
1634  * relocate all slots simultaneously
1635  */
1636 void
1637 dev_mmcloc(struct dev *d, unsigned int origin)
1638 {
1639 	if (log_level >= 2) {
1640 		dev_log(d);
1641 		log_puts(": relocated to ");
1642 		log_putu(origin);
1643 		log_puts("\n");
1644 	}
1645 	if (d->tstate == MMC_RUN)
1646 		dev_mmcstop(d);
1647 	d->mtc.origin = origin;
1648 	if (d->tstate == MMC_RUN)
1649 		dev_mmcstart(d);
1650 }
1651 
1652 /*
1653  * allocate buffers & conversion chain
1654  */
1655 void
1656 slot_initconv(struct slot *s)
1657 {
1658 	unsigned int dev_nch;
1659 	struct dev *d = s->dev;
1660 
1661 	if (s->mode & MODE_PLAY) {
1662 		cmap_init(&s->mix.cmap,
1663 		    s->opt->pmin, s->opt->pmin + s->mix.nch - 1,
1664 		    s->opt->pmin, s->opt->pmin + s->mix.nch - 1,
1665 		    0, d->pchan - 1,
1666 		    s->opt->pmin, s->opt->pmax);
1667 		if (!aparams_native(&s->par)) {
1668 			dec_init(&s->mix.dec, &s->par, s->mix.nch);
1669 		}
1670 		if (s->rate != d->rate) {
1671 			resamp_init(&s->mix.resamp, s->round, d->round,
1672 			    s->mix.nch);
1673 		}
1674 		s->mix.join = 1;
1675 		s->mix.expand = 1;
1676 		if (s->opt->dup && s->mix.cmap.nch > 0) {
1677 			dev_nch = d->pchan < (s->opt->pmax + 1) ?
1678 			    d->pchan - s->opt->pmin :
1679 			    s->opt->pmax - s->opt->pmin + 1;
1680 			if (dev_nch > s->mix.nch)
1681 				s->mix.expand = dev_nch / s->mix.nch;
1682 			else if (s->mix.nch > dev_nch)
1683 				s->mix.join = s->mix.nch / dev_nch;
1684 		}
1685 	}
1686 
1687 	if (s->mode & MODE_RECMASK) {
1688 		unsigned int outchan = (s->mode & MODE_MON) ?
1689 		    d->pchan : d->rchan;
1690 
1691 		cmap_init(&s->sub.cmap,
1692 		    0, outchan - 1,
1693 		    s->opt->rmin, s->opt->rmax,
1694 		    s->opt->rmin, s->opt->rmin + s->sub.nch - 1,
1695 		    s->opt->rmin, s->opt->rmin + s->sub.nch - 1);
1696 		if (s->rate != d->rate) {
1697 			resamp_init(&s->sub.resamp, d->round, s->round,
1698 			    s->sub.nch);
1699 		}
1700 		if (!aparams_native(&s->par)) {
1701 			enc_init(&s->sub.enc, &s->par, s->sub.nch);
1702 		}
1703 		s->sub.join = 1;
1704 		s->sub.expand = 1;
1705 		if (s->opt->dup && s->sub.cmap.nch > 0) {
1706 			dev_nch = outchan < (s->opt->rmax + 1) ?
1707 			    outchan - s->opt->rmin :
1708 			    s->opt->rmax - s->opt->rmin + 1;
1709 			if (dev_nch > s->sub.nch)
1710 				s->sub.join = dev_nch / s->sub.nch;
1711 			else if (s->sub.nch > dev_nch)
1712 				s->sub.expand = s->sub.nch / dev_nch;
1713 		}
1714 
1715 		/*
1716 		 * cmap_copy() doesn't write samples in all channels,
1717 	         * for instance when mono->stereo conversion is
1718 	         * disabled. So we have to prefill cmap_copy() output
1719 	         * with silence.
1720 	         */
1721 		if (s->sub.resampbuf) {
1722 			memset(s->sub.resampbuf, 0,
1723 			    d->round * s->sub.nch * sizeof(adata_t));
1724 		} else if (s->sub.encbuf) {
1725 			memset(s->sub.encbuf, 0,
1726 			    s->round * s->sub.nch * sizeof(adata_t));
1727 		} else {
1728 			memset(s->sub.buf.data, 0,
1729 			    s->appbufsz * s->sub.nch * sizeof(adata_t));
1730 		}
1731 	}
1732 }
1733 
1734 /*
1735  * allocate buffers & conversion chain
1736  */
1737 void
1738 slot_allocbufs(struct slot *s)
1739 {
1740 	struct dev *d = s->dev;
1741 
1742 	if (s->mode & MODE_PLAY) {
1743 		s->mix.bpf = s->par.bps * s->mix.nch;
1744 		abuf_init(&s->mix.buf, s->appbufsz * s->mix.bpf);
1745 
1746 		s->mix.decbuf = NULL;
1747 		s->mix.resampbuf = NULL;
1748 		if (!aparams_native(&s->par)) {
1749 			s->mix.decbuf =
1750 			    xmalloc(s->round * s->mix.nch * sizeof(adata_t));
1751 		}
1752 		if (s->rate != d->rate) {
1753 			s->mix.resampbuf =
1754 			    xmalloc(d->round * s->mix.nch * sizeof(adata_t));
1755 		}
1756 	}
1757 
1758 	if (s->mode & MODE_RECMASK) {
1759 		s->sub.bpf = s->par.bps * s->sub.nch;
1760 		abuf_init(&s->sub.buf, s->appbufsz * s->sub.bpf);
1761 
1762 		s->sub.encbuf = NULL;
1763 		s->sub.resampbuf = NULL;
1764 		if (s->rate != d->rate) {
1765 			s->sub.resampbuf =
1766 			    xmalloc(d->round * s->sub.nch * sizeof(adata_t));
1767 		}
1768 		if (!aparams_native(&s->par)) {
1769 			s->sub.encbuf =
1770 			    xmalloc(s->round * s->sub.nch * sizeof(adata_t));
1771 		}
1772 	}
1773 
1774 	slot_initconv(s);
1775 
1776 #ifdef DEBUG
1777 	if (log_level >= 3) {
1778 		slot_log(s);
1779 		log_puts(": allocated ");
1780 		log_putu(s->appbufsz);
1781 		log_puts("/");
1782 		log_putu(SLOT_BUFSZ(s));
1783 		log_puts(" fr buffers\n");
1784 	}
1785 #endif
1786 }
1787 
1788 /*
1789  * free buffers & conversion chain
1790  */
1791 void
1792 slot_freebufs(struct slot *s)
1793 {
1794 	if (s->mode & MODE_RECMASK) {
1795 		abuf_done(&s->sub.buf);
1796 		if (s->sub.encbuf)
1797 			xfree(s->sub.encbuf);
1798 		if (s->sub.resampbuf)
1799 			xfree(s->sub.resampbuf);
1800 	}
1801 
1802 	if (s->mode & MODE_PLAY) {
1803 		abuf_done(&s->mix.buf);
1804 		if (s->mix.decbuf)
1805 			xfree(s->mix.decbuf);
1806 		if (s->mix.resampbuf)
1807 			xfree(s->mix.resampbuf);
1808 	}
1809 }
1810 
1811 /*
1812  * allocate a new slot and register the given call-backs
1813  */
1814 struct slot *
1815 slot_new(struct dev *d, struct opt *opt, unsigned int id, char *who,
1816     struct slotops *ops, void *arg, int mode)
1817 {
1818 	char *p;
1819 	char name[SLOT_NAMEMAX];
1820 	unsigned int i, ser, bestser, bestidx;
1821 	struct slot *unit[DEV_NSLOT];
1822 	struct slot *s;
1823 
1824 	/*
1825 	 * create a ``valid'' control name (lowcase, remove [^a-z], truncate)
1826 	 */
1827 	for (i = 0, p = who; ; p++) {
1828 		if (i == SLOT_NAMEMAX - 1 || *p == '\0') {
1829 			name[i] = '\0';
1830 			break;
1831 		} else if (*p >= 'A' && *p <= 'Z') {
1832 			name[i++] = *p + 'a' - 'A';
1833 		} else if (*p >= 'a' && *p <= 'z')
1834 			name[i++] = *p;
1835 	}
1836 	if (i == 0)
1837 		strlcpy(name, "noname", SLOT_NAMEMAX);
1838 
1839 	/*
1840 	 * build a unit-to-slot map for this name
1841 	 */
1842 	for (i = 0; i < DEV_NSLOT; i++)
1843 		unit[i] = NULL;
1844 	for (i = 0; i < DEV_NSLOT; i++) {
1845 		s = d->slot + i;
1846 		if (strcmp(s->name, name) == 0)
1847 			unit[s->unit] = s;
1848 	}
1849 
1850 	/*
1851 	 * find the free slot with the least unit number and same id
1852 	 */
1853 	for (i = 0; i < DEV_NSLOT; i++) {
1854 		s = unit[i];
1855 		if (s != NULL && s->ops == NULL && s->id == id)
1856 			goto found;
1857 	}
1858 
1859 	/*
1860 	 * find the free slot with the least unit number
1861 	 */
1862 	for (i = 0; i < DEV_NSLOT; i++) {
1863 		s = unit[i];
1864 		if (s != NULL && s->ops == NULL) {
1865 			s->id = id;
1866 			goto found;
1867 		}
1868 	}
1869 
1870 	/*
1871 	 * couldn't find a matching slot, pick oldest free slot
1872 	 * and set its name/unit
1873 	 */
1874 	bestser = 0;
1875 	bestidx = DEV_NSLOT;
1876 	for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) {
1877 		if (s->ops != NULL)
1878 			continue;
1879 		ser = d->serial - s->serial;
1880 		if (ser > bestser) {
1881 			bestser = ser;
1882 			bestidx = i;
1883 		}
1884 	}
1885 	if (bestidx != DEV_NSLOT) {
1886 		s = d->slot + bestidx;
1887 		s->vol = MIDI_MAXCTL;
1888 		strlcpy(s->name, name, SLOT_NAMEMAX);
1889 		s->serial = d->serial++;
1890 		for (i = 0; unit[i] != NULL; i++)
1891 			; /* nothing */
1892 		s->unit = i;
1893 		s->id = id;
1894 		goto found;
1895 	}
1896 
1897 	if (log_level >= 1) {
1898 		log_puts(name);
1899 		log_puts(": out of sub-device slots\n");
1900 	}
1901 	return NULL;
1902 
1903 found:
1904 	if ((mode & MODE_REC) && (opt->mode & MODE_MON)) {
1905 		mode |= MODE_MON;
1906 		mode &= ~MODE_REC;
1907 	}
1908 	if ((mode & opt->mode) != mode) {
1909 		if (log_level >= 1) {
1910 			slot_log(s);
1911 			log_puts(": requested mode not allowed\n");
1912 		}
1913 		return 0;
1914 	}
1915 	if (!dev_ref(d))
1916 		return NULL;
1917 	dev_label(d, s - d->slot);
1918 	if ((mode & d->mode) != mode) {
1919 		if (log_level >= 1) {
1920 			slot_log(s);
1921 			log_puts(": requested mode not supported\n");
1922 		}
1923 		dev_unref(d);
1924 		return NULL;
1925 	}
1926 	s->dev = d;
1927 	s->opt = opt;
1928 	s->ops = ops;
1929 	s->arg = arg;
1930 	s->pstate = SLOT_INIT;
1931 	s->mode = mode;
1932 	aparams_init(&s->par);
1933 	if (s->mode & MODE_PLAY)
1934 		s->mix.nch = s->opt->pmax - s->opt->pmin + 1;
1935 	if (s->mode & MODE_RECMASK)
1936 		s->sub.nch = s->opt->rmax - s->opt->rmin + 1;
1937 	s->xrun = s->opt->mmc ? XRUN_SYNC : XRUN_IGNORE;
1938 	s->appbufsz = d->bufsz;
1939 	s->round = d->round;
1940 	s->rate = d->rate;
1941 	dev_midi_slotdesc(d, s);
1942 	dev_midi_vol(d, s);
1943 #ifdef DEBUG
1944 	if (log_level >= 3) {
1945 		slot_log(s);
1946 		log_puts(": using ");
1947 		dev_log(d);
1948 		log_puts(".");
1949 		log_puts(opt->name);
1950 		log_puts(", mode = ");
1951 		log_putx(mode);
1952 		log_puts("\n");
1953 	}
1954 #endif
1955 	return s;
1956 }
1957 
1958 /*
1959  * release the given slot
1960  */
1961 void
1962 slot_del(struct slot *s)
1963 {
1964 	s->arg = s;
1965 	s->ops = &zomb_slotops;
1966 	switch (s->pstate) {
1967 	case SLOT_INIT:
1968 		s->ops = NULL;
1969 		break;
1970 	case SLOT_START:
1971 	case SLOT_READY:
1972 	case SLOT_RUN:
1973 		slot_stop(s);
1974 		/* PASSTHROUGH */
1975 	case SLOT_STOP:
1976 		break;
1977 	}
1978 	dev_unref(s->dev);
1979 	s->dev = NULL;
1980 }
1981 
1982 /*
1983  * change the slot play volume; called either by the slot or by MIDI
1984  */
1985 void
1986 slot_setvol(struct slot *s, unsigned int vol)
1987 {
1988 #ifdef DEBUG
1989 	if (log_level >= 3) {
1990 		slot_log(s);
1991 		log_puts(": setting volume ");
1992 		log_putu(vol);
1993 		log_puts("\n");
1994 	}
1995 #endif
1996 	s->vol = vol;
1997 	s->mix.vol = MIDI_TO_ADATA(s->vol);
1998 }
1999 
2000 /*
2001  * attach the slot to the device (ie start playing & recording
2002  */
2003 void
2004 slot_attach(struct slot *s)
2005 {
2006 	struct dev *d = s->dev;
2007 	long long pos;
2008 	int startpos;
2009 
2010 	/*
2011 	 * start the device if not started
2012 	 */
2013 	dev_wakeup(d);
2014 
2015 	/*
2016 	 * get the current position, the origin is when the first sample
2017 	 * played and/or recorded
2018 	 */
2019 	startpos = dev_getpos(d) * (int)s->round / (int)d->round;
2020 
2021 	/*
2022 	 * adjust initial clock
2023 	 */
2024 	pos = (long long)d->delta * s->round;
2025 	s->delta = startpos + pos / (int)d->round;
2026 	s->delta_rem = pos % d->round;
2027 
2028 	s->pstate = SLOT_RUN;
2029 #ifdef DEBUG
2030 	if (log_level >= 2) {
2031 		slot_log(s);
2032 		log_puts(": attached at ");
2033 		log_puti(startpos);
2034 		log_puts(", delta = ");
2035 		log_puti(d->delta);
2036 		log_puts("\n");
2037 	}
2038 #endif
2039 
2040 	/*
2041 	 * We dont check whether the device is dying,
2042 	 * because dev_xxx() functions are supposed to
2043 	 * work (i.e., not to crash)
2044 	 */
2045 #ifdef DEBUG
2046 	if ((s->mode & d->mode) != s->mode) {
2047 		slot_log(s);
2048 		log_puts(": mode beyond device mode, not attaching\n");
2049 		panic();
2050 	}
2051 #endif
2052 	s->next = d->slot_list;
2053 	d->slot_list = s;
2054 	if (s->mode & MODE_PLAY) {
2055 		s->mix.vol = MIDI_TO_ADATA(s->vol);
2056 		dev_mix_adjvol(d);
2057 	}
2058 }
2059 
2060 /*
2061  * if MMC is enabled, and try to attach all slots synchronously, else
2062  * simply attach the slot
2063  */
2064 void
2065 slot_ready(struct slot *s)
2066 {
2067 	/*
2068 	 * device may be disconnected, and if so we're called from
2069 	 * slot->ops->exit() on a closed device
2070 	 */
2071 	if (s->dev->pstate == DEV_CFG)
2072 		return;
2073 	if (!s->opt->mmc)
2074 		slot_attach(s);
2075 	else
2076 		dev_sync_attach(s->dev);
2077 }
2078 
2079 /*
2080  * setup buffers & conversion layers, prepare the slot to receive data
2081  * (for playback) or start (recording).
2082  */
2083 void
2084 slot_start(struct slot *s)
2085 {
2086 #ifdef DEBUG
2087 	if (s->pstate != SLOT_INIT) {
2088 		slot_log(s);
2089 		log_puts(": slot_start: wrong state\n");
2090 		panic();
2091 	}
2092 	if (s->mode & MODE_PLAY) {
2093 		if (log_level >= 3) {
2094 			slot_log(s);
2095 			log_puts(": playing ");
2096 			aparams_log(&s->par);
2097 			log_puts(" -> ");
2098 			aparams_log(&s->dev->par);
2099 			log_puts("\n");
2100 		}
2101 	}
2102 	if (s->mode & MODE_RECMASK) {
2103 		if (log_level >= 3) {
2104 			slot_log(s);
2105 			log_puts(": recording ");
2106 			aparams_log(&s->par);
2107 			log_puts(" <- ");
2108 			aparams_log(&s->dev->par);
2109 			log_puts("\n");
2110 		}
2111 	}
2112 #endif
2113 	slot_allocbufs(s);
2114 
2115 	if (s->mode & MODE_RECMASK) {
2116 		/*
2117 		 * N-th recorded block is the N-th played block
2118 		 */
2119 		s->sub.prime = -dev_getpos(s->dev) / s->dev->round;
2120 	}
2121 	s->skip = 0;
2122 
2123 	if (s->mode & MODE_PLAY) {
2124 		s->pstate = SLOT_START;
2125 	} else {
2126 		s->pstate = SLOT_READY;
2127 		slot_ready(s);
2128 	}
2129 }
2130 
2131 /*
2132  * stop playback and recording, and free conversion layers
2133  */
2134 void
2135 slot_detach(struct slot *s)
2136 {
2137 	struct slot **ps;
2138 
2139 #ifdef DEBUG
2140 	if (log_level >= 3) {
2141 		slot_log(s);
2142 		log_puts(": detaching\n");
2143 	}
2144 #endif
2145 	for (ps = &s->dev->slot_list; *ps != s; ps = &(*ps)->next) {
2146 #ifdef DEBUG
2147 		if (*ps == NULL) {
2148 			slot_log(s);
2149 			log_puts(": can't detach, not on list\n");
2150 			panic();
2151 		}
2152 #endif
2153 	}
2154 	*ps = s->next;
2155 	if (s->mode & MODE_PLAY)
2156 		dev_mix_adjvol(s->dev);
2157 }
2158 
2159 /*
2160  * put the slot in stopping state (draining play buffers) or
2161  * stop & detach if no data to drain.
2162  */
2163 void
2164 slot_stop(struct slot *s)
2165 {
2166 #ifdef DEBUG
2167 	if (log_level >= 3) {
2168 		slot_log(s);
2169 		log_puts(": stopping\n");
2170 	}
2171 #endif
2172 	if (s->pstate == SLOT_START) {
2173 		/*
2174 		 * If in rec-only mode, we're already in the READY or
2175 		 * RUN states. We're here because the play buffer was
2176 		 * not full enough, try to start so it's drained.
2177 		 */
2178 		s->pstate = SLOT_READY;
2179 		slot_ready(s);
2180 	}
2181 
2182 	if (s->pstate == SLOT_RUN) {
2183 		if (s->mode & MODE_PLAY) {
2184 			/*
2185 			 * Don't detach, dev_cycle() will do it for us
2186 			 * when the buffer is drained.
2187 			 */
2188 			s->pstate = SLOT_STOP;
2189 			return;
2190 		}
2191 		slot_detach(s);
2192 	} else {
2193 #ifdef DEBUG
2194 		if (log_level >= 3) {
2195 			slot_log(s);
2196 			log_puts(": not drained (blocked by mmc)\n");
2197 		}
2198 #endif
2199 	}
2200 
2201 	s->pstate = SLOT_INIT;
2202 	s->ops->eof(s->arg);
2203 	slot_freebufs(s);
2204 }
2205 
2206 void
2207 slot_skip_update(struct slot *s)
2208 {
2209 	int skip;
2210 
2211 	skip = slot_skip(s);
2212 	while (skip > 0) {
2213 #ifdef DEBUG
2214 		if (log_level >= 4) {
2215 			slot_log(s);
2216 			log_puts(": catching skipped block\n");
2217 		}
2218 #endif
2219 		if (s->mode & MODE_RECMASK)
2220 			s->ops->flush(s->arg);
2221 		if (s->mode & MODE_PLAY)
2222 			s->ops->fill(s->arg);
2223 		skip--;
2224 	}
2225 }
2226 
2227 /*
2228  * notify the slot that we just wrote in the play buffer, must be called
2229  * after each write
2230  */
2231 void
2232 slot_write(struct slot *s)
2233 {
2234 	if (s->pstate == SLOT_START && s->mix.buf.used == s->mix.buf.len) {
2235 #ifdef DEBUG
2236 		if (log_level >= 4) {
2237 			slot_log(s);
2238 			log_puts(": switching to READY state\n");
2239 		}
2240 #endif
2241 		s->pstate = SLOT_READY;
2242 		slot_ready(s);
2243 	}
2244 	slot_skip_update(s);
2245 }
2246 
2247 /*
2248  * notify the slot that we freed some space in the rec buffer
2249  */
2250 void
2251 slot_read(struct slot *s)
2252 {
2253 	slot_skip_update(s);
2254 }
2255 
2256 /*
2257  * allocate at control slot
2258  */
2259 struct ctlslot *
2260 ctlslot_new(struct dev *d, struct ctlops *ops, void *arg)
2261 {
2262 	struct ctlslot *s;
2263 	struct ctl *c;
2264 	int i;
2265 
2266 	i = 0;
2267 	for (;;) {
2268 		if (i == DEV_NCTLSLOT)
2269 			return NULL;
2270 		s = d->ctlslot + i;
2271 		if (s->ops == NULL)
2272 			break;
2273 		i++;
2274 	}
2275 	s->dev = d;
2276 	s->mask = 1 << i;
2277 	if (!dev_ref(d))
2278 		return NULL;
2279 	s->ops = ops;
2280 	s->arg = arg;
2281 	for (c = d->ctl_list; c != NULL; c = c->next)
2282 		c->refs_mask |= s->mask;
2283 	return s;
2284 }
2285 
2286 /*
2287  * free control slot
2288  */
2289 void
2290 ctlslot_del(struct ctlslot *s)
2291 {
2292 	struct ctl *c, **pc;
2293 
2294 	pc = &s->dev->ctl_list;
2295 	while ((c = *pc) != NULL) {
2296 		c->refs_mask &= ~s->mask;
2297 		if (c->refs_mask == 0) {
2298 			*pc = c->next;
2299 			xfree(c);
2300 		} else
2301 			pc = &c->next;
2302 	}
2303 	s->ops = NULL;
2304 	dev_unref(s->dev);
2305 }
2306 
2307 void
2308 ctl_node_log(struct ctl_node *c)
2309 {
2310 	log_puts(c->name);
2311 	if (c->unit >= 0)
2312 		log_putu(c->unit);
2313 }
2314 
2315 void
2316 ctl_log(struct ctl *c)
2317 {
2318 	if (c->group[0] != 0) {
2319 		log_puts(c->group);
2320 		log_puts("/");
2321 	}
2322 	ctl_node_log(&c->node0);
2323 	log_puts(".");
2324 	log_puts(c->func);
2325 	log_puts("=");
2326 	switch (c->type) {
2327 	case CTL_NONE:
2328 		log_puts("none");
2329 		break;
2330 	case CTL_NUM:
2331 	case CTL_SW:
2332 		log_putu(c->curval);
2333 		break;
2334 	case CTL_VEC:
2335 	case CTL_LIST:
2336 	case CTL_SEL:
2337 		ctl_node_log(&c->node1);
2338 		log_puts(":");
2339 		log_putu(c->curval);
2340 	}
2341 	log_puts(" at ");
2342 	log_putu(c->addr);
2343 }
2344 
2345 /*
2346  * add a ctl
2347  */
2348 struct ctl *
2349 dev_addctl(struct dev *d, char *gstr, int type, int addr,
2350     char *str0, int unit0, char *func, char *str1, int unit1, int maxval, int val)
2351 {
2352 	struct ctl *c, **pc;
2353 	int i;
2354 
2355 	c = xmalloc(sizeof(struct ctl));
2356 	c->type = type;
2357 	strlcpy(c->func, func, CTL_NAMEMAX);
2358 	strlcpy(c->group, gstr, CTL_NAMEMAX);
2359 	strlcpy(c->node0.name, str0, CTL_NAMEMAX);
2360 	c->node0.unit = unit0;
2361 	if (c->type == CTL_VEC || c->type == CTL_LIST || c->type == CTL_SEL) {
2362 		strlcpy(c->node1.name, str1, CTL_NAMEMAX);
2363 		c->node1.unit = unit1;
2364 	} else
2365 		memset(&c->node1, 0, sizeof(struct ctl_node));
2366 	c->addr = addr;
2367 	c->maxval = maxval;
2368 	c->val_mask = ~0;
2369 	c->desc_mask = ~0;
2370 	c->curval = val;
2371 	c->dirty = 0;
2372 	c->refs_mask = 0;
2373 	for (i = 0; i < DEV_NCTLSLOT; i++) {
2374 		c->refs_mask |= CTL_DEVMASK;
2375 		if (d->ctlslot[i].ops != NULL)
2376 			c->refs_mask |= 1 << i;
2377 	}
2378 	for (pc = &d->ctl_list; *pc != NULL; pc = &(*pc)->next)
2379 		; /* nothing */
2380 	c->next = NULL;
2381 	*pc = c;
2382 #ifdef DEBUG
2383 	if (log_level >= 3) {
2384 		dev_log(d);
2385 		log_puts(": adding ");
2386 		ctl_log(c);
2387 		log_puts("\n");
2388 	}
2389 #endif
2390 	return c;
2391 }
2392 
2393 void
2394 dev_rmctl(struct dev *d, int addr)
2395 {
2396 	struct ctl *c, **pc;
2397 
2398 	pc = &d->ctl_list;
2399 	for (;;) {
2400 		c = *pc;
2401 		if (c == NULL)
2402 			return;
2403 		if (c->type != CTL_NONE && c->addr == addr)
2404 			break;
2405 		pc = &c->next;
2406 	}
2407 	c->type = CTL_NONE;
2408 #ifdef DEBUG
2409 	if (log_level >= 3) {
2410 		dev_log(d);
2411 		log_puts(": removing ");
2412 		ctl_log(c);
2413 		log_puts(", refs_mask = 0x");
2414 		log_putx(c->refs_mask);
2415 		log_puts("\n");
2416 	}
2417 #endif
2418 	c->refs_mask &= ~CTL_DEVMASK;
2419 	if (c->refs_mask == 0) {
2420 		*pc = c->next;
2421 		xfree(c);
2422 		return;
2423 	}
2424 	c->desc_mask = ~0;
2425 }
2426 
2427 void
2428 dev_ctlsync(struct dev *d)
2429 {
2430 	struct ctl *c;
2431 	struct ctlslot *s;
2432 	int found, i;
2433 
2434 	found = 0;
2435 	for (c = d->ctl_list; c != NULL; c = c->next) {
2436 		if (c->addr != CTLADDR_MASTER &&
2437 		    c->type == CTL_NUM &&
2438 		    strcmp(c->group, "") == 0 &&
2439 		    strcmp(c->node0.name, "output") == 0 &&
2440 		    strcmp(c->func, "level") == 0)
2441 			found = 1;
2442 	}
2443 
2444 	if (d->master_enabled && found) {
2445 		if (log_level >= 2) {
2446 			dev_log(d);
2447 			log_puts(": software master level control disabled\n");
2448 		}
2449 		d->master_enabled = 0;
2450 		dev_rmctl(d, CTLADDR_MASTER);
2451 	} else if (!d->master_enabled && !found) {
2452 		if (log_level >= 2) {
2453 			dev_log(d);
2454 			log_puts(": software master level control enabled\n");
2455 		}
2456 		d->master_enabled = 1;
2457 		dev_addctl(d, "", CTL_NUM, CTLADDR_MASTER,
2458 		    "output", -1, "level", NULL, -1, 127, d->master);
2459 	}
2460 
2461 	for (s = d->ctlslot, i = DEV_NCTLSLOT; i > 0; i--, s++) {
2462 		if (s->ops)
2463 			s->ops->sync(s->arg);
2464 	}
2465 }
2466 
2467 int
2468 dev_setctl(struct dev *d, int addr, int val)
2469 {
2470 	struct ctl *c;
2471 	int num;
2472 
2473 	c = d->ctl_list;
2474 	for (;;) {
2475 		if (c == NULL) {
2476 			if (log_level >= 3) {
2477 				dev_log(d);
2478 				log_puts(": ");
2479 				log_putu(addr);
2480 				log_puts(": no such ctl address\n");
2481 			}
2482 			return 0;
2483 		}
2484 		if (c->type != CTL_NONE && c->addr == addr)
2485 			break;
2486 		c = c->next;
2487 	}
2488 	if (c->curval == val) {
2489 		if (log_level >= 3) {
2490 			ctl_log(c);
2491 			log_puts(": already set\n");
2492 		}
2493 		return 1;
2494 	}
2495 	if (val < 0 || val > c->maxval) {
2496 		if (log_level >= 3) {
2497 			dev_log(d);
2498 			log_puts(": ");
2499 			log_putu(val);
2500 			log_puts(": ctl val out of bounds\n");
2501 		}
2502 		return 0;
2503 	}
2504 	if (addr >= CTLADDR_END) {
2505 		if (log_level >= 3) {
2506 			ctl_log(c);
2507 			log_puts(": marked as dirty\n");
2508 		}
2509 		c->dirty = 1;
2510 		dev_ref(d);
2511 	} else {
2512 		if (addr >= CTLADDR_ALT_SEL) {
2513 			if (val) {
2514 				num = addr - CTLADDR_ALT_SEL;
2515 				dev_setalt(d, num);
2516 			}
2517 			return 1;
2518 		} else if (addr == CTLADDR_MASTER) {
2519 			if (d->master_enabled) {
2520 				dev_master(d, val);
2521 				dev_midi_master(d);
2522 			}
2523 		} else {
2524 			num = addr - CTLADDR_SLOT_LEVEL(0);
2525 			slot_setvol(d->slot + num, val);
2526 			dev_midi_vol(d, d->slot + num);
2527 		}
2528 		c->val_mask = ~0U;
2529 	}
2530 	c->curval = val;
2531 	return 1;
2532 }
2533 
2534 int
2535 dev_onval(struct dev *d, int addr, int val)
2536 {
2537 	struct ctl *c;
2538 
2539 	c = d->ctl_list;
2540 	for (;;) {
2541 		if (c == NULL)
2542 			return 0;
2543 		if (c->type != CTL_NONE && c->addr == addr)
2544 			break;
2545 		c = c->next;
2546 	}
2547 	c->curval = val;
2548 	c->val_mask = ~0U;
2549 	return 1;
2550 }
2551 
2552 void
2553 dev_label(struct dev *d, int i)
2554 {
2555 	struct ctl *c;
2556 	char name[CTL_NAMEMAX];
2557 
2558 	slot_ctlname(&d->slot[i], name, CTL_NAMEMAX);
2559 
2560 	c = d->ctl_list;
2561 	for (;;) {
2562 		if (c == NULL) {
2563 			dev_addctl(d, "app", CTL_NUM,
2564 			    CTLADDR_SLOT_LEVEL(i),
2565 			    name, -1, "level",
2566 			    NULL, -1, 127, d->slot[i].vol);
2567 			return;
2568 		}
2569 		if (c->addr == CTLADDR_SLOT_LEVEL(i))
2570 			break;
2571 		c = c->next;
2572 	}
2573 	if (strcmp(c->node0.name, name) == 0)
2574 		return;
2575 	strlcpy(c->node0.name, name, CTL_NAMEMAX);
2576 	c->desc_mask = ~0;
2577 }
2578 
2579 int
2580 dev_nctl(struct dev *d)
2581 {
2582 	struct ctl *c;
2583 	int n;
2584 
2585 	n = 0;
2586 	for (c = d->ctl_list; c != NULL; c = c->next)
2587 		n++;
2588 	return n;
2589 }
2590