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