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