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