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