Annotation of src/usr.bin/sndiod/dev.c, Revision 1.45
1.45 ! ratchov 1: /* $OpenBSD: dev.c,v 1.44 2018/06/26 07:42:04 ratchov Exp $ */
1.1 ratchov 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"
1.36 ratchov 26: #include "opt.h"
1.1 ratchov 27: #include "sysex.h"
28: #include "utils.h"
29:
1.14 ratchov 30: void zomb_onmove(void *);
1.25 ratchov 31: void zomb_onvol(void *);
1.1 ratchov 32: void zomb_fill(void *);
33: void zomb_flush(void *);
34: void zomb_eof(void *);
35: void zomb_exit(void *);
36:
1.7 ratchov 37: void dev_log(struct dev *);
38: void dev_midi_qfr(struct dev *, int);
39: void dev_midi_full(struct dev *);
40: void dev_midi_vol(struct dev *, struct slot *);
41: void dev_midi_master(struct dev *);
42: void dev_midi_slotdesc(struct dev *, struct slot *);
43: void dev_midi_dump(struct dev *);
1.1 ratchov 44: void dev_midi_imsg(void *, unsigned char *, int);
45: void dev_midi_omsg(void *, unsigned char *, int);
46: void dev_midi_fill(void *, int);
47: void dev_midi_exit(void *);
1.7 ratchov 48:
49: void dev_mix_badd(struct dev *, struct slot *);
50: void dev_mix_adjvol(struct dev *);
51: void dev_sub_bcopy(struct dev *, struct slot *);
52:
53: void dev_onmove(struct dev *, int);
54: void dev_master(struct dev *, unsigned int);
55: void dev_cycle(struct dev *);
56: int dev_getpos(struct dev *);
57: struct dev *dev_new(char *, struct aparams *, unsigned int, unsigned int,
58: unsigned int, unsigned int, unsigned int, unsigned int);
1.25 ratchov 59: void dev_adjpar(struct dev *, int, int, int);
1.7 ratchov 60: int dev_open(struct dev *);
61: void dev_close(struct dev *);
62: int dev_ref(struct dev *);
63: void dev_unref(struct dev *);
64: int dev_init(struct dev *);
65: void dev_done(struct dev *);
66: struct dev *dev_bynum(int);
67: void dev_del(struct dev *);
68: unsigned int dev_roundof(struct dev *, unsigned int);
69: void dev_wakeup(struct dev *);
70: void dev_sync_attach(struct dev *);
71: void dev_mmcstart(struct dev *);
72: void dev_mmcstop(struct dev *);
73: void dev_mmcloc(struct dev *, unsigned int);
74:
75: void slot_log(struct slot *);
76: void slot_del(struct slot *);
77: void slot_setvol(struct slot *, unsigned int);
78: void slot_attach(struct slot *);
79: void slot_ready(struct slot *);
1.35 ratchov 80: void slot_allocbufs(struct slot *);
81: void slot_freebufs(struct slot *);
1.7 ratchov 82: void slot_start(struct slot *);
83: void slot_detach(struct slot *);
84: void slot_stop(struct slot *);
1.12 ratchov 85: void slot_skip_update(struct slot *);
1.7 ratchov 86: void slot_write(struct slot *);
87: void slot_read(struct slot *);
1.12 ratchov 88: int slot_skip(struct slot *);
1.1 ratchov 89:
90: struct midiops dev_midiops = {
91: dev_midi_imsg,
92: dev_midi_omsg,
93: dev_midi_fill,
94: dev_midi_exit
95: };
96:
97: struct slotops zomb_slotops = {
98: zomb_onmove,
99: zomb_onvol,
100: zomb_fill,
101: zomb_flush,
102: zomb_eof,
103: zomb_exit
104: };
105:
106: struct dev *dev_list = NULL;
107: unsigned int dev_sndnum = 0;
108:
109: void
110: dev_log(struct dev *d)
111: {
1.3 ratchov 112: #ifdef DEBUG
113: static char *pstates[] = {
114: "cfg", "ini", "run"
115: };
116: #endif
1.1 ratchov 117: log_puts("snd");
118: log_putu(d->num);
1.3 ratchov 119: #ifdef DEBUG
120: if (log_level >= 3) {
121: log_puts(" pst=");
122: log_puts(pstates[d->pstate]);
123: }
124: #endif
1.1 ratchov 125: }
126:
127: void
128: slot_log(struct slot *s)
1.3 ratchov 129: {
1.1 ratchov 130: #ifdef DEBUG
131: static char *pstates[] = {
132: "ini", "sta", "rdy", "run", "stp", "mid"
133: };
134: static char *tstates[] = {
135: "off", "sta", "run", "stp"
136: };
137: #endif
138: log_puts(s->name);
139: log_putu(s->unit);
140: #ifdef DEBUG
141: if (log_level >= 3) {
142: log_puts(" vol=");
143: log_putu(s->vol);
144: if (s->ops) {
145: log_puts(",pst=");
146: log_puts(pstates[s->pstate]);
147: log_puts(",mmc=");
148: log_puts(tstates[s->tstate]);
149: }
150: }
151: #endif
152: }
153:
154: void
1.14 ratchov 155: zomb_onmove(void *arg)
1.1 ratchov 156: {
157: }
158:
159: void
1.25 ratchov 160: zomb_onvol(void *arg)
1.1 ratchov 161: {
162: }
163:
164: void
165: zomb_fill(void *arg)
166: {
167: }
168:
169: void
170: zomb_flush(void *arg)
171: {
172: }
173:
174: void
175: zomb_eof(void *arg)
176: {
177: struct slot *s = arg;
178:
179: #ifdef DEBUG
180: if (log_level >= 3) {
181: slot_log(s);
182: log_puts(": zomb_eof\n");
183: }
184: #endif
185: s->ops = NULL;
186: }
187:
188: void
189: zomb_exit(void *arg)
190: {
191: #ifdef DEBUG
192: struct slot *s = arg;
193:
194: if (log_level >= 3) {
195: slot_log(s);
196: log_puts(": zomb_exit\n");
197: }
198: #endif
199: }
200:
201: /*
202: * send a quarter frame MTC message
203: */
204: void
205: dev_midi_qfr(struct dev *d, int delta)
206: {
207: unsigned char buf[2];
208: unsigned int data;
209: int qfrlen;
210:
211: d->mtc.delta += delta * MTC_SEC;
212: qfrlen = d->rate * (MTC_SEC / (4 * d->mtc.fps));
213: while (d->mtc.delta >= qfrlen) {
214: switch (d->mtc.qfr) {
215: case 0:
216: data = d->mtc.fr & 0xf;
217: break;
218: case 1:
219: data = d->mtc.fr >> 4;
220: break;
221: case 2:
222: data = d->mtc.sec & 0xf;
223: break;
224: case 3:
225: data = d->mtc.sec >> 4;
226: break;
227: case 4:
228: data = d->mtc.min & 0xf;
229: break;
230: case 5:
231: data = d->mtc.min >> 4;
232: break;
233: case 6:
234: data = d->mtc.hr & 0xf;
235: break;
236: case 7:
237: data = (d->mtc.hr >> 4) | (d->mtc.fps_id << 1);
238: /*
239: * tick messages are sent 2 frames ahead
240: */
241: d->mtc.fr += 2;
242: if (d->mtc.fr < d->mtc.fps)
243: break;
244: d->mtc.fr -= d->mtc.fps;
245: d->mtc.sec++;
246: if (d->mtc.sec < 60)
247: break;
248: d->mtc.sec = 0;
249: d->mtc.min++;
250: if (d->mtc.min < 60)
251: break;
252: d->mtc.min = 0;
253: d->mtc.hr++;
254: if (d->mtc.hr < 24)
255: break;
256: d->mtc.hr = 0;
257: break;
258: default:
259: /* NOTREACHED */
260: data = 0;
261: }
262: buf[0] = 0xf1;
263: buf[1] = (d->mtc.qfr << 4) | data;
264: d->mtc.qfr++;
265: d->mtc.qfr &= 7;
266: midi_send(d->midi, buf, 2);
267: d->mtc.delta -= qfrlen;
268: }
269: }
270:
271: /*
272: * send a full frame MTC message
273: */
274: void
275: dev_midi_full(struct dev *d)
276: {
277: struct sysex x;
278: unsigned int fps;
279:
280: d->mtc.delta = MTC_SEC * dev_getpos(d);
281: if (d->rate % (30 * 4 * d->round) == 0) {
282: d->mtc.fps_id = MTC_FPS_30;
283: d->mtc.fps = 30;
284: } else if (d->rate % (25 * 4 * d->round) == 0) {
285: d->mtc.fps_id = MTC_FPS_25;
286: d->mtc.fps = 25;
287: } else {
288: d->mtc.fps_id = MTC_FPS_24;
289: d->mtc.fps = 24;
290: }
291: #ifdef DEBUG
292: if (log_level >= 3) {
293: dev_log(d);
294: log_puts(": mtc full frame at ");
295: log_puti(d->mtc.delta);
296: log_puts(", ");
297: log_puti(d->mtc.fps);
298: log_puts(" fps\n");
299: }
300: #endif
301: fps = d->mtc.fps;
302: d->mtc.hr = (d->mtc.origin / (MTC_SEC * 3600)) % 24;
303: d->mtc.min = (d->mtc.origin / (MTC_SEC * 60)) % 60;
304: d->mtc.sec = (d->mtc.origin / (MTC_SEC)) % 60;
305: d->mtc.fr = (d->mtc.origin / (MTC_SEC / fps)) % fps;
306:
307: x.start = SYSEX_START;
308: x.type = SYSEX_TYPE_RT;
1.8 ratchov 309: x.dev = SYSEX_DEV_ANY;
1.1 ratchov 310: x.id0 = SYSEX_MTC;
311: x.id1 = SYSEX_MTC_FULL;
312: x.u.full.hr = d->mtc.hr | (d->mtc.fps_id << 5);
313: x.u.full.min = d->mtc.min;
314: x.u.full.sec = d->mtc.sec;
315: x.u.full.fr = d->mtc.fr;
316: x.u.full.end = SYSEX_END;
317: d->mtc.qfr = 0;
318: midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(full));
319: }
320:
321: /*
322: * send a volume change MIDI message
323: */
324: void
325: dev_midi_vol(struct dev *d, struct slot *s)
326: {
327: unsigned char msg[3];
328:
329: msg[0] = MIDI_CTL | (s - d->slot);
330: msg[1] = MIDI_CTL_VOL;
331: msg[2] = s->vol;
332: midi_send(d->midi, msg, 3);
333: }
334:
335: /*
336: * send a master volume MIDI message
337: */
338: void
339: dev_midi_master(struct dev *d)
340: {
341: struct sysex x;
342:
343: memset(&x, 0, sizeof(struct sysex));
344: x.start = SYSEX_START;
345: x.type = SYSEX_TYPE_RT;
1.8 ratchov 346: x.dev = SYSEX_DEV_ANY;
1.1 ratchov 347: x.id0 = SYSEX_CONTROL;
348: x.id1 = SYSEX_MASTER;
349: x.u.master.fine = 0;
350: x.u.master.coarse = d->master;
351: x.u.master.end = SYSEX_END;
352: midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(master));
353: }
354:
355: /*
356: * send a sndiod-specific slot description MIDI message
357: */
358: void
359: dev_midi_slotdesc(struct dev *d, struct slot *s)
360: {
361: struct sysex x;
362:
363: memset(&x, 0, sizeof(struct sysex));
364: x.start = SYSEX_START;
365: x.type = SYSEX_TYPE_EDU;
1.8 ratchov 366: x.dev = SYSEX_DEV_ANY;
1.1 ratchov 367: x.id0 = SYSEX_AUCAT;
368: x.id1 = SYSEX_AUCAT_SLOTDESC;
369: if (*s->name != '\0') {
370: snprintf((char *)x.u.slotdesc.name, SYSEX_NAMELEN,
371: "%s%u", s->name, s->unit);
372: }
373: x.u.slotdesc.chan = s - d->slot;
374: x.u.slotdesc.end = SYSEX_END;
375: midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(slotdesc));
376: }
377:
378: void
379: dev_midi_dump(struct dev *d)
380: {
381: struct sysex x;
382: struct slot *s;
383: int i;
384:
385: dev_midi_master(d);
386: for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) {
387: dev_midi_slotdesc(d, s);
388: dev_midi_vol(d, s);
389: }
390: x.start = SYSEX_START;
391: x.type = SYSEX_TYPE_EDU;
1.8 ratchov 392: x.dev = SYSEX_DEV_ANY;
1.1 ratchov 393: x.id0 = SYSEX_AUCAT;
394: x.id1 = SYSEX_AUCAT_DUMPEND;
395: x.u.dumpend.end = SYSEX_END;
396: midi_send(d->midi, (unsigned char *)&x, SYSEX_SIZE(dumpend));
397: }
398:
399: void
400: dev_midi_imsg(void *arg, unsigned char *msg, int len)
401: {
402: #ifdef DEBUG
403: struct dev *d = arg;
404:
405: dev_log(d);
406: log_puts(": can't receive midi messages\n");
407: panic();
408: #endif
409: }
410:
411: void
412: dev_midi_omsg(void *arg, unsigned char *msg, int len)
413: {
414: struct dev *d = arg;
415: struct sysex *x;
416: unsigned int fps, chan;
417:
418: if ((msg[0] & MIDI_CMDMASK) == MIDI_CTL && msg[1] == MIDI_CTL_VOL) {
419: chan = msg[0] & MIDI_CHANMASK;
420: if (chan >= DEV_NSLOT)
421: return;
422: slot_setvol(d->slot + chan, msg[2]);
423: return;
424: }
425: x = (struct sysex *)msg;
426: if (x->start != SYSEX_START)
427: return;
428: if (len < SYSEX_SIZE(empty))
429: return;
430: switch (x->type) {
431: case SYSEX_TYPE_RT:
432: if (x->id0 == SYSEX_CONTROL && x->id1 == SYSEX_MASTER) {
433: if (len == SYSEX_SIZE(master))
434: dev_master(d, x->u.master.coarse);
435: return;
436: }
437: if (x->id0 != SYSEX_MMC)
438: return;
439: switch (x->id1) {
440: case SYSEX_MMC_STOP:
441: if (len != SYSEX_SIZE(stop))
442: return;
443: if (log_level >= 2) {
444: dev_log(d);
445: log_puts(": mmc stop\n");
446: }
447: dev_mmcstop(d);
448: break;
449: case SYSEX_MMC_START:
450: if (len != SYSEX_SIZE(start))
451: return;
452: if (log_level >= 2) {
453: dev_log(d);
454: log_puts(": mmc start\n");
455: }
456: dev_mmcstart(d);
457: break;
458: case SYSEX_MMC_LOC:
459: if (len != SYSEX_SIZE(loc) ||
460: x->u.loc.len != SYSEX_MMC_LOC_LEN ||
461: x->u.loc.cmd != SYSEX_MMC_LOC_CMD)
462: return;
463: switch (x->u.loc.hr >> 5) {
464: case MTC_FPS_24:
465: fps = 24;
466: break;
467: case MTC_FPS_25:
468: fps = 25;
469: break;
470: case MTC_FPS_30:
471: fps = 30;
472: break;
473: default:
474: dev_mmcstop(d);
475: return;
476: }
477: dev_mmcloc(d,
478: (x->u.loc.hr & 0x1f) * 3600 * MTC_SEC +
479: x->u.loc.min * 60 * MTC_SEC +
480: x->u.loc.sec * MTC_SEC +
481: x->u.loc.fr * (MTC_SEC / fps) +
482: x->u.loc.cent * (MTC_SEC / 100 / fps));
483: break;
484: }
485: break;
486: case SYSEX_TYPE_EDU:
487: if (x->id0 != SYSEX_AUCAT || x->id1 != SYSEX_AUCAT_DUMPREQ)
488: return;
489: if (len != SYSEX_SIZE(dumpreq))
490: return;
491: dev_midi_dump(d);
492: break;
493: }
494: }
495:
496: void
497: dev_midi_fill(void *arg, int count)
498: {
1.2 ratchov 499: /* nothing to do */
1.1 ratchov 500: }
501:
502: void
503: dev_midi_exit(void *arg)
504: {
505: struct dev *d = arg;
506:
507: if (log_level >= 1) {
508: dev_log(d);
509: log_puts(": midi end point died\n");
510: }
511: if (d->pstate != DEV_CFG)
512: dev_close(d);
513: }
514:
1.12 ratchov 515: int
516: slot_skip(struct slot *s)
1.1 ratchov 517: {
1.12 ratchov 518: unsigned char *data = (unsigned char *)0xdeadbeef; /* please gcc */
519: int max, count;
520:
521: max = s->skip;
522: while (s->skip > 0) {
523: if (s->pstate != SLOT_STOP && (s->mode & MODE_RECMASK)) {
524: data = abuf_wgetblk(&s->sub.buf, &count);
525: if (count < s->round * s->sub.bpf)
526: break;
527: }
528: if (s->mode & MODE_PLAY) {
529: if (s->mix.buf.used < s->round * s->mix.bpf)
530: break;
531: }
1.1 ratchov 532: #ifdef DEBUG
533: if (log_level >= 4) {
534: slot_log(s);
1.12 ratchov 535: log_puts(": skipped a cycle\n");
1.1 ratchov 536: }
537: #endif
1.12 ratchov 538: if (s->pstate != SLOT_STOP && (s->mode & MODE_RECMASK)) {
539: if (s->sub.encbuf)
540: enc_sil_do(&s->sub.enc, data, s->round);
541: else
542: memset(data, 0, s->round * s->sub.bpf);
543: abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf);
544: }
545: if (s->mode & MODE_PLAY) {
546: abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
1.1 ratchov 547: }
1.23 ratchov 548: s->skip--;
1.1 ratchov 549: }
1.12 ratchov 550: return max - s->skip;
1.1 ratchov 551: }
552:
1.32 ratchov 553: /*
554: * Mix the slot input block over the output block
555: */
556: void
557: dev_mix_badd(struct dev *d, struct slot *s)
1.1 ratchov 558: {
1.32 ratchov 559: adata_t *idata, *odata, *in;
560: int icount, i, offs, vol, nch;
561:
562: odata = DEV_PBUF(d);
563: idata = (adata_t *)abuf_rgetblk(&s->mix.buf, &icount);
564: #ifdef DEBUG
565: if (icount < s->round * s->mix.bpf) {
566: slot_log(s);
567: log_puts(": not enough data to mix (");
568: log_putu(icount);
569: log_puts("bytes)\n");
570: panic();
571: }
572: #endif
573:
574: /*
575: * Apply the following processing chain:
576: *
577: * dec -> resamp-> cmap
578: *
579: * where the first two are optional.
580: */
581:
582: in = idata;
583:
584: if (s->mix.decbuf) {
585: dec_do(&s->mix.dec, (void *)in, s->mix.decbuf, s->round);
586: in = s->mix.decbuf;
587: }
1.1 ratchov 588:
589: if (s->mix.resampbuf) {
1.32 ratchov 590: resamp_do(&s->mix.resamp, in, s->mix.resampbuf, s->round);
1.1 ratchov 591: in = s->mix.resampbuf;
1.32 ratchov 592: }
1.1 ratchov 593:
1.10 ratchov 594: nch = s->mix.cmap.nch;
1.1 ratchov 595: vol = ADATA_MUL(s->mix.weight, s->mix.vol) / s->mix.join;
1.32 ratchov 596: cmap_add(&s->mix.cmap, in, odata, vol, d->round);
1.1 ratchov 597:
598: offs = 0;
599: for (i = s->mix.join - 1; i > 0; i--) {
600: offs += nch;
1.32 ratchov 601: cmap_add(&s->mix.cmap, in + offs, odata, vol, d->round);
1.1 ratchov 602: }
1.32 ratchov 603:
1.1 ratchov 604: offs = 0;
605: for (i = s->mix.expand - 1; i > 0; i--) {
606: offs += nch;
1.32 ratchov 607: cmap_add(&s->mix.cmap, in, odata + offs, vol, d->round);
1.1 ratchov 608: }
609:
610: abuf_rdiscard(&s->mix.buf, s->round * s->mix.bpf);
611: }
612:
613: /*
614: * Normalize input levels.
615: */
616: void
617: dev_mix_adjvol(struct dev *d)
618: {
619: unsigned int n;
620: struct slot *i, *j;
1.42 ratchov 621: int jcmax, icmax, weight;
1.1 ratchov 622:
623: for (i = d->slot_list; i != NULL; i = i->next) {
624: if (!(i->mode & MODE_PLAY))
625: continue;
1.42 ratchov 626: icmax = i->opt->pmin + i->mix.nch - 1;
1.1 ratchov 627: weight = ADATA_UNIT;
628: if (d->autovol) {
629: /*
630: * count the number of inputs that have
631: * overlapping channel sets
632: */
633: n = 0;
634: for (j = d->slot_list; j != NULL; j = j->next) {
635: if (!(j->mode & MODE_PLAY))
636: continue;
1.42 ratchov 637: jcmax = j->opt->pmin + j->mix.nch - 1;
638: if (i->opt->pmin <= jcmax &&
639: icmax >= j->opt->pmin)
1.1 ratchov 640: n++;
641: }
642: weight /= n;
643: }
1.38 ratchov 644: if (weight > i->opt->maxweight)
645: weight = i->opt->maxweight;
1.1 ratchov 646: i->mix.weight = ADATA_MUL(weight, MIDI_TO_ADATA(d->master));
647: #ifdef DEBUG
648: if (log_level >= 3) {
649: slot_log(i);
650: log_puts(": set weight: ");
651: log_puti(i->mix.weight);
652: log_puts("/");
1.38 ratchov 653: log_puti(i->opt->maxweight);
1.1 ratchov 654: log_puts("\n");
655: }
656: #endif
657: }
658: }
659:
660: /*
661: * Copy data from slot to device
662: */
663: void
664: dev_sub_bcopy(struct dev *d, struct slot *s)
665: {
1.32 ratchov 666: adata_t *idata, *enc_out, *resamp_out, *cmap_out;
667: void *odata;
1.15 ratchov 668: int ocount, moffs;
1.1 ratchov 669:
1.32 ratchov 670: int i, vol, offs, nch;
671:
672:
1.15 ratchov 673: if (s->mode & MODE_MON) {
674: moffs = d->poffs + d->round;
675: if (moffs == d->psize)
676: moffs = 0;
677: idata = d->pbuf + moffs * d->pchan;
678: } else
679: idata = d->rbuf;
1.1 ratchov 680: odata = (adata_t *)abuf_wgetblk(&s->sub.buf, &ocount);
681: #ifdef DEBUG
682: if (ocount < s->round * s->sub.bpf) {
683: log_puts("dev_sub_bcopy: not enough space\n");
684: panic();
685: }
686: #endif
1.32 ratchov 687:
688: /*
689: * Apply the following processing chain:
690: *
691: * cmap -> resamp -> enc
692: *
693: * where the last two are optional.
694: */
695:
696: enc_out = odata;
697: resamp_out = s->sub.encbuf ? s->sub.encbuf : enc_out;
698: cmap_out = s->sub.resampbuf ? s->sub.resampbuf : resamp_out;
699:
700: nch = s->sub.cmap.nch;
701: vol = ADATA_UNIT / s->sub.join;
702: cmap_copy(&s->sub.cmap, idata, cmap_out, vol, d->round);
703:
704: offs = 0;
705: for (i = s->sub.join - 1; i > 0; i--) {
706: offs += nch;
707: cmap_add(&s->sub.cmap, idata + offs, cmap_out, vol, d->round);
708: }
709:
710: offs = 0;
711: for (i = s->sub.expand - 1; i > 0; i--) {
712: offs += nch;
713: cmap_copy(&s->sub.cmap, idata, cmap_out + offs, vol, d->round);
714: }
715:
716: if (s->sub.resampbuf) {
717: resamp_do(&s->sub.resamp,
718: s->sub.resampbuf, resamp_out, d->round);
719: }
720:
721: if (s->sub.encbuf)
722: enc_do(&s->sub.enc, s->sub.encbuf, (void *)enc_out, s->round);
723:
724: abuf_wcommit(&s->sub.buf, s->round * s->sub.bpf);
1.1 ratchov 725: }
726:
1.16 ratchov 727: /*
728: * run a one block cycle: consume one recorded block from
729: * rbuf and produce one play block in pbuf
730: */
1.1 ratchov 731: void
1.16 ratchov 732: dev_cycle(struct dev *d)
1.1 ratchov 733: {
734: struct slot *s, **ps;
1.12 ratchov 735: unsigned char *base;
736: int nsamp;
1.1 ratchov 737:
1.16 ratchov 738: /*
739: * check if the device is actually used. If it isn't,
740: * then close it
741: */
742: if (d->slot_list == NULL && d->tstate != MMC_RUN) {
743: if (log_level >= 2) {
744: dev_log(d);
745: log_puts(": device stopped\n");
746: }
747: dev_sio_stop(d);
748: d->pstate = DEV_INIT;
749: if (d->refcnt == 0)
750: dev_close(d);
751: return;
752: }
753:
754: if (d->prime > 0) {
755: #ifdef DEBUG
756: if (log_level >= 4) {
757: dev_log(d);
758: log_puts(": empty cycle, prime = ");
759: log_putu(d->prime);
760: log_puts("\n");
761: }
762: #endif
763: base = (unsigned char *)DEV_PBUF(d);
764: nsamp = d->round * d->pchan;
765: memset(base, 0, nsamp * sizeof(adata_t));
766: if (d->encbuf) {
767: enc_do(&d->enc, (unsigned char *)DEV_PBUF(d),
768: d->encbuf, d->round);
769: }
770: d->prime -= d->round;
771: return;
772: }
773:
1.12 ratchov 774: d->delta -= d->round;
1.1 ratchov 775: #ifdef DEBUG
776: if (log_level >= 4) {
777: dev_log(d);
1.16 ratchov 778: log_puts(": full cycle: delta = ");
1.12 ratchov 779: log_puti(d->delta);
780: if (d->mode & MODE_PLAY) {
781: log_puts(", poffs = ");
782: log_puti(d->poffs);
783: }
784: log_puts("\n");
1.1 ratchov 785: }
786: #endif
1.12 ratchov 787: if (d->mode & MODE_PLAY) {
788: base = (unsigned char *)DEV_PBUF(d);
789: nsamp = d->round * d->pchan;
790: memset(base, 0, nsamp * sizeof(adata_t));
791: }
1.1 ratchov 792: if ((d->mode & MODE_REC) && d->decbuf)
793: dec_do(&d->dec, d->decbuf, (unsigned char *)d->rbuf, d->round);
794: ps = &d->slot_list;
795: while ((s = *ps) != NULL) {
1.12 ratchov 796: #ifdef DEBUG
797: if (log_level >= 4) {
798: slot_log(s);
799: log_puts(": running");
800: log_puts(", skip = ");
801: log_puti(s->skip);
802: log_puts("\n");
803: }
804: #endif
805: /*
806: * skip cycles for XRUN_SYNC correction
807: */
808: slot_skip(s);
809: if (s->skip < 0) {
810: s->skip++;
1.1 ratchov 811: ps = &s->next;
812: continue;
813: }
1.12 ratchov 814:
815: #ifdef DEBUG
816: if (s->pstate == SLOT_STOP && !(s->mode & MODE_PLAY)) {
817: slot_log(s);
818: log_puts(": rec-only slots can't be drained\n");
819: panic();
820: }
821: #endif
822: /*
823: * check if stopped stream finished draining
824: */
825: if (s->pstate == SLOT_STOP &&
826: s->mix.buf.used < s->round * s->mix.bpf) {
827: /*
828: * partial blocks are zero-filled by socket
829: * layer, so s->mix.buf.used == 0 and we can
830: * destroy the buffer
831: */
1.35 ratchov 832: *ps = s->next;
1.12 ratchov 833: s->pstate = SLOT_INIT;
834: s->ops->eof(s->arg);
1.35 ratchov 835: slot_freebufs(s);
1.12 ratchov 836: dev_mix_adjvol(d);
1.35 ratchov 837: #ifdef DEBUG
838: if (log_level >= 3) {
839: slot_log(s);
840: log_puts(": drained\n");
841: }
842: #endif
1.1 ratchov 843: continue;
844: }
1.23 ratchov 845:
1.12 ratchov 846: /*
847: * check for xruns
848: */
1.23 ratchov 849: if (((s->mode & MODE_PLAY) &&
1.12 ratchov 850: s->mix.buf.used < s->round * s->mix.bpf) ||
851: ((s->mode & MODE_RECMASK) &&
852: s->sub.buf.len - s->sub.buf.used <
853: s->round * s->sub.bpf)) {
854:
855: #ifdef DEBUG
856: if (log_level >= 3) {
857: slot_log(s);
858: log_puts(": xrun, pause cycle\n");
859: }
860: #endif
1.1 ratchov 861: if (s->xrun == XRUN_IGNORE) {
862: s->delta -= s->round;
1.12 ratchov 863: ps = &s->next;
864: } else if (s->xrun == XRUN_SYNC) {
865: s->skip++;
866: ps = &s->next;
867: } else if (s->xrun == XRUN_ERROR) {
868: s->ops->exit(s->arg);
869: *ps = s->next;
870: } else {
871: #ifdef DEBUG
872: slot_log(s);
873: log_puts(": bad xrun mode\n");
874: panic();
875: #endif
876: }
877: continue;
878: }
879: if ((s->mode & MODE_RECMASK) && !(s->pstate == SLOT_STOP)) {
880: if (s->sub.prime == 0) {
881: dev_sub_bcopy(d, s);
882: s->ops->flush(s->arg);
883: } else {
1.1 ratchov 884: #ifdef DEBUG
885: if (log_level >= 3) {
886: slot_log(s);
1.12 ratchov 887: log_puts(": prime = ");
888: log_puti(s->sub.prime);
889: log_puts("\n");
1.1 ratchov 890: }
891: #endif
1.12 ratchov 892: s->sub.prime--;
1.1 ratchov 893: }
894: }
1.15 ratchov 895: if (s->mode & MODE_PLAY) {
896: dev_mix_badd(d, s);
897: if (s->pstate != SLOT_STOP)
898: s->ops->fill(s->arg);
899: }
1.1 ratchov 900: ps = &s->next;
901: }
1.12 ratchov 902: if ((d->mode & MODE_PLAY) && d->encbuf) {
903: enc_do(&d->enc, (unsigned char *)DEV_PBUF(d),
904: d->encbuf, d->round);
905: }
1.1 ratchov 906: }
907:
908: /*
909: * called at every clock tick by the device
910: */
911: void
912: dev_onmove(struct dev *d, int delta)
913: {
914: long long pos;
1.23 ratchov 915: struct slot *s, *snext;
1.12 ratchov 916:
917: d->delta += delta;
1.1 ratchov 918:
919: for (s = d->slot_list; s != NULL; s = snext) {
1.12 ratchov 920: /*
921: * s->ops->onmove() may remove the slot
922: */
1.1 ratchov 923: snext = s->next;
924: pos = (long long)delta * s->round + s->delta_rem;
925: s->delta_rem = pos % d->round;
926: s->delta += pos / (int)d->round;
927: if (s->delta >= 0)
1.14 ratchov 928: s->ops->onmove(s->arg);
1.1 ratchov 929: }
930: if (d->tstate == MMC_RUN)
931: dev_midi_qfr(d, delta);
932: }
933:
934: void
935: dev_master(struct dev *d, unsigned int master)
936: {
937: if (log_level >= 2) {
938: dev_log(d);
939: log_puts(": master volume set to ");
940: log_putu(master);
941: log_puts("\n");
942: }
943: d->master = master;
944: if (d->mode & MODE_PLAY)
945: dev_mix_adjvol(d);
946: }
947:
948: /*
949: * return the latency that a stream would have if it's attached
950: */
951: int
952: dev_getpos(struct dev *d)
953: {
954: return (d->mode & MODE_PLAY) ? -d->bufsz : 0;
955: }
956:
957: /*
958: * Create a sndio device
959: */
960: struct dev *
961: dev_new(char *path, struct aparams *par,
962: unsigned int mode, unsigned int bufsz, unsigned int round,
963: unsigned int rate, unsigned int hold, unsigned int autovol)
964: {
965: struct dev *d;
966: unsigned int i;
967:
968: if (dev_sndnum == DEV_NMAX) {
969: if (log_level >= 1)
970: log_puts("too many devices\n");
971: return NULL;
972: }
973: d = xmalloc(sizeof(struct dev));
1.21 ratchov 974: d->path = xstrdup(path);
1.1 ratchov 975: d->num = dev_sndnum++;
1.36 ratchov 976: d->opt_list = NULL;
1.1 ratchov 977:
978: /*
979: * XXX: below, we allocate a midi input buffer, since we don't
980: * receive raw midi data, so no need to allocate a input
981: * ibuf. Possibly set imsg & fill callbacks to NULL and
982: * use this to in midi_new() to check if buffers need to be
983: * allocated
984: */
985: d->midi = midi_new(&dev_midiops, d, MODE_MIDIIN | MODE_MIDIOUT);
986: midi_tag(d->midi, d->num);
987: d->reqpar = *par;
988: d->reqmode = mode;
989: d->reqpchan = d->reqrchan = 0;
990: d->reqbufsz = bufsz;
991: d->reqround = round;
992: d->reqrate = rate;
993: d->hold = hold;
994: d->autovol = autovol;
995: d->refcnt = 0;
996: d->pstate = DEV_CFG;
997: d->serial = 0;
998: for (i = 0; i < DEV_NSLOT; i++) {
999: d->slot[i].unit = i;
1000: d->slot[i].ops = NULL;
1001: d->slot[i].vol = MIDI_MAXCTL;
1002: d->slot[i].tstate = MMC_OFF;
1003: d->slot[i].serial = d->serial++;
1.26 ratchov 1004: strlcpy(d->slot[i].name, "prog", SLOT_NAMEMAX);
1.1 ratchov 1005: }
1006: d->slot_list = NULL;
1007: d->master = MIDI_MAXCTL;
1008: d->mtc.origin = 0;
1009: d->tstate = MMC_STOP;
1010: d->next = dev_list;
1011: dev_list = d;
1012: return d;
1013: }
1014:
1015: /*
1016: * adjust device parameters and mode
1017: */
1018: void
1019: dev_adjpar(struct dev *d, int mode,
1.25 ratchov 1020: int pmax, int rmax)
1.1 ratchov 1021: {
1022: d->reqmode |= mode & MODE_AUDIOMASK;
1023: if (mode & MODE_PLAY) {
1024: if (d->reqpchan < pmax + 1)
1025: d->reqpchan = pmax + 1;
1026: }
1027: if (mode & MODE_REC) {
1028: if (d->reqrchan < rmax + 1)
1029: d->reqrchan = rmax + 1;
1030: }
1031: }
1032:
1033: /*
1034: * Open the device with the dev_reqxxx capabilities. Setup a mixer, demuxer,
1035: * monitor, midi control, and any necessary conversions.
1036: */
1037: int
1038: dev_open(struct dev *d)
1039: {
1040: d->mode = d->reqmode;
1041: d->round = d->reqround;
1042: d->bufsz = d->reqbufsz;
1043: d->rate = d->reqrate;
1044: d->pchan = d->reqpchan;
1045: d->rchan = d->reqrchan;
1046: d->par = d->reqpar;
1047: if (d->pchan == 0)
1048: d->pchan = 2;
1049: if (d->rchan == 0)
1050: d->rchan = 2;
1051: if (!dev_sio_open(d)) {
1052: if (log_level >= 1) {
1053: dev_log(d);
1054: log_puts(": ");
1055: log_puts(d->path);
1056: log_puts(": failed to open audio device\n");
1057: }
1058: return 0;
1059: }
1060: if (d->mode & MODE_REC) {
1061: /*
1062: * Create device <-> demuxer buffer
1063: */
1064: d->rbuf = xmalloc(d->round * d->rchan * sizeof(adata_t));
1065:
1066: /*
1067: * Insert a converter, if needed.
1068: */
1069: if (!aparams_native(&d->par)) {
1070: dec_init(&d->dec, &d->par, d->rchan);
1071: d->decbuf = xmalloc(d->round * d->rchan * d->par.bps);
1072: } else
1073: d->decbuf = NULL;
1074: }
1075: if (d->mode & MODE_PLAY) {
1076: /*
1077: * Create device <-> mixer buffer
1078: */
1079: d->poffs = 0;
1.15 ratchov 1080: d->psize = d->bufsz + d->round;
1081: d->pbuf = xmalloc(d->psize * d->pchan * sizeof(adata_t));
1.1 ratchov 1082: d->mode |= MODE_MON;
1083:
1084: /*
1085: * Append a converter, if needed.
1086: */
1087: if (!aparams_native(&d->par)) {
1088: enc_init(&d->enc, &d->par, d->pchan);
1089: d->encbuf = xmalloc(d->round * d->pchan * d->par.bps);
1090: } else
1091: d->encbuf = NULL;
1092: }
1093: d->pstate = DEV_INIT;
1094: if (log_level >= 2) {
1095: dev_log(d);
1096: log_puts(": ");
1097: log_putu(d->rate);
1098: log_puts("Hz, ");
1099: aparams_log(&d->par);
1100: if (d->mode & MODE_PLAY) {
1101: log_puts(", play 0:");
1102: log_puti(d->pchan - 1);
1103: }
1104: if (d->mode & MODE_REC) {
1105: log_puts(", rec 0:");
1106: log_puti(d->rchan - 1);
1107: }
1108: log_puts(", ");
1109: log_putu(d->bufsz / d->round);
1110: log_puts(" blocks of ");
1111: log_putu(d->round);
1112: log_puts(" frames\n");
1113: }
1114: return 1;
1115: }
1116:
1117: /*
1118: * force the device to go in DEV_CFG state, the caller is supposed to
1119: * ensure buffers are drained
1120: */
1121: void
1122: dev_close(struct dev *d)
1123: {
1.3 ratchov 1124: int i;
1125: struct slot *s;
1.1 ratchov 1126:
1127: #ifdef DEBUG
1128: if (log_level >= 3) {
1129: dev_log(d);
1130: log_puts(": closing\n");
1131: }
1132: #endif
1.3 ratchov 1133: d->pstate = DEV_CFG;
1134: for (s = d->slot, i = DEV_NSLOT; i > 0; i--, s++) {
1.1 ratchov 1135: if (s->ops)
1136: s->ops->exit(s->arg);
1137: s->ops = NULL;
1138: }
1.3 ratchov 1139: d->slot_list = NULL;
1.1 ratchov 1140: dev_sio_close(d);
1141: if (d->mode & MODE_PLAY) {
1142: if (d->encbuf != NULL)
1143: xfree(d->encbuf);
1144: xfree(d->pbuf);
1145: }
1146: if (d->mode & MODE_REC) {
1147: if (d->decbuf != NULL)
1148: xfree(d->decbuf);
1149: xfree(d->rbuf);
1150: }
1151: }
1152:
1153: int
1154: dev_ref(struct dev *d)
1155: {
1156: #ifdef DEBUG
1157: if (log_level >= 3) {
1158: dev_log(d);
1159: log_puts(": device requested\n");
1160: }
1161: #endif
1162: if (d->pstate == DEV_CFG && !dev_open(d))
1163: return 0;
1164: d->refcnt++;
1165: return 1;
1166: }
1167:
1168: void
1169: dev_unref(struct dev *d)
1170: {
1171: #ifdef DEBUG
1172: if (log_level >= 3) {
1173: dev_log(d);
1174: log_puts(": device released\n");
1175: }
1176: #endif
1177: d->refcnt--;
1178: if (d->refcnt == 0 && d->pstate == DEV_INIT)
1179: dev_close(d);
1180: }
1181:
1182: /*
1183: * initialize the device with the current parameters
1184: */
1185: int
1186: dev_init(struct dev *d)
1187: {
1188: if ((d->reqmode & MODE_AUDIOMASK) == 0) {
1189: #ifdef DEBUG
1190: dev_log(d);
1191: log_puts(": has no streams\n");
1192: #endif
1193: return 0;
1194: }
1195: if (d->hold && !dev_ref(d))
1196: return 0;
1197: return 1;
1198: }
1199:
1200: /*
1201: * Unless the device is already in process of closing, request it to close
1202: */
1203: void
1204: dev_done(struct dev *d)
1205: {
1206: #ifdef DEBUG
1207: if (log_level >= 3) {
1208: dev_log(d);
1209: log_puts(": draining\n");
1210: }
1211: #endif
1.20 ratchov 1212: if (d->tstate != MMC_STOP)
1213: dev_mmcstop(d);
1.1 ratchov 1214: if (d->hold)
1215: dev_unref(d);
1216: }
1217:
1218: struct dev *
1219: dev_bynum(int num)
1220: {
1221: struct dev *d;
1222:
1223: for (d = dev_list; d != NULL; d = d->next) {
1.19 ratchov 1224: if (d->num == num)
1.1 ratchov 1225: return d;
1226: }
1227: return NULL;
1228: }
1229:
1230: /*
1231: * Free the device
1232: */
1233: void
1234: dev_del(struct dev *d)
1235: {
1236: struct dev **p;
1237:
1238: #ifdef DEBUG
1239: if (log_level >= 3) {
1240: dev_log(d);
1241: log_puts(": deleting\n");
1242: }
1243: #endif
1.36 ratchov 1244: while (d->opt_list != NULL)
1245: opt_del(d, d->opt_list);
1.1 ratchov 1246: if (d->pstate != DEV_CFG)
1247: dev_close(d);
1248: for (p = &dev_list; *p != d; p = &(*p)->next) {
1249: #ifdef DEBUG
1250: if (*p == NULL) {
1251: dev_log(d);
1252: log_puts(": device to delete not on the list\n");
1253: panic();
1254: }
1255: #endif
1256: }
1257: midi_del(d->midi);
1258: *p = d->next;
1.21 ratchov 1259: xfree(d->path);
1.1 ratchov 1260: xfree(d);
1261: }
1262:
1263: unsigned int
1264: dev_roundof(struct dev *d, unsigned int newrate)
1265: {
1266: return (d->round * newrate + d->rate / 2) / d->rate;
1267: }
1268:
1269: /*
1270: * If the device is paused, then resume it.
1271: */
1272: void
1273: dev_wakeup(struct dev *d)
1274: {
1275: if (d->pstate == DEV_INIT) {
1276: if (log_level >= 2) {
1277: dev_log(d);
1278: log_puts(": device started\n");
1279: }
1280: if (d->mode & MODE_PLAY) {
1281: d->prime = d->bufsz;
1282: } else {
1283: d->prime = 0;
1284: }
1.16 ratchov 1285: d->poffs = 0;
1.12 ratchov 1286:
1.23 ratchov 1287: /*
1.16 ratchov 1288: * empty cycles don't increment delta, so it's ok to
1289: * start at 0
1290: **/
1.23 ratchov 1291: d->delta = 0;
1.12 ratchov 1292:
1.1 ratchov 1293: d->pstate = DEV_RUN;
1294: dev_sio_start(d);
1295: }
1296: }
1297:
1298: /*
1299: * check that all clients controlled by MMC are ready to start, if so,
1300: * attach them all at the same position
1301: */
1302: void
1303: dev_sync_attach(struct dev *d)
1304: {
1305: int i;
1306: struct slot *s;
1307:
1308: if (d->tstate != MMC_START) {
1309: if (log_level >= 2) {
1310: dev_log(d);
1311: log_puts(": not started by mmc yet, waiting...\n");
1312: }
1313: return;
1314: }
1315: for (i = 0; i < DEV_NSLOT; i++) {
1316: s = d->slot + i;
1317: if (!s->ops || s->tstate == MMC_OFF)
1318: continue;
1319: if (s->tstate != MMC_START || s->pstate != SLOT_READY) {
1320: #ifdef DEBUG
1321: if (log_level >= 3) {
1322: slot_log(s);
1323: log_puts(": not ready, start delayed\n");
1324: }
1325: #endif
1326: return;
1327: }
1328: }
1329: if (!dev_ref(d))
1330: return;
1331: for (i = 0; i < DEV_NSLOT; i++) {
1332: s = d->slot + i;
1333: if (!s->ops)
1334: continue;
1335: if (s->tstate == MMC_START) {
1336: #ifdef DEBUG
1337: if (log_level >= 3) {
1338: slot_log(s);
1339: log_puts(": started\n");
1340: }
1341: #endif
1342: s->tstate = MMC_RUN;
1343: slot_attach(s);
1344: }
1345: }
1346: d->tstate = MMC_RUN;
1347: dev_midi_full(d);
1348: dev_wakeup(d);
1349: }
1350:
1351: /*
1352: * start all slots simultaneously
1353: */
1354: void
1355: dev_mmcstart(struct dev *d)
1356: {
1357: if (d->tstate == MMC_STOP) {
1358: d->tstate = MMC_START;
1359: dev_sync_attach(d);
1360: #ifdef DEBUG
1361: } else {
1362: if (log_level >= 3) {
1363: dev_log(d);
1364: log_puts(": ignoring mmc start\n");
1365: }
1366: #endif
1367: }
1368: }
1369:
1370: /*
1371: * stop all slots simultaneously
1372: */
1373: void
1374: dev_mmcstop(struct dev *d)
1375: {
1376: switch (d->tstate) {
1377: case MMC_START:
1378: d->tstate = MMC_STOP;
1379: return;
1380: case MMC_RUN:
1381: d->tstate = MMC_STOP;
1382: dev_unref(d);
1383: break;
1384: default:
1385: #ifdef DEBUG
1386: if (log_level >= 3) {
1387: dev_log(d);
1388: log_puts(": ignored mmc stop\n");
1389: }
1390: #endif
1391: return;
1392: }
1393: }
1394:
1395: /*
1396: * relocate all slots simultaneously
1397: */
1398: void
1399: dev_mmcloc(struct dev *d, unsigned int origin)
1400: {
1401: if (log_level >= 2) {
1402: dev_log(d);
1403: log_puts(": relocated to ");
1404: log_putu(origin);
1405: log_puts("\n");
1406: }
1407: if (d->tstate == MMC_RUN)
1408: dev_mmcstop(d);
1409: d->mtc.origin = origin;
1410: if (d->tstate == MMC_RUN)
1411: dev_mmcstart(d);
1412: }
1413:
1.35 ratchov 1414:
1415: /*
1416: * allocate buffers & conversion chain
1417: */
1418: void
1419: slot_allocbufs(struct slot *s)
1420: {
1.42 ratchov 1421: unsigned int dev_nch;
1.35 ratchov 1422: struct dev *d = s->dev;
1423:
1424: if (s->mode & MODE_PLAY) {
1.42 ratchov 1425: s->mix.bpf = s->par.bps * s->mix.nch;
1.35 ratchov 1426: abuf_init(&s->mix.buf, s->appbufsz * s->mix.bpf);
1427:
1.40 ratchov 1428: dev_nch = s->opt->pmax - s->opt->pmin + 1;
1.35 ratchov 1429: s->mix.decbuf = NULL;
1430: s->mix.resampbuf = NULL;
1431: s->mix.join = 1;
1432: s->mix.expand = 1;
1.39 ratchov 1433: if (s->opt->dup) {
1.42 ratchov 1434: if (dev_nch > s->mix.nch)
1435: s->mix.expand = dev_nch / s->mix.nch;
1436: else if (dev_nch < s->mix.nch)
1437: s->mix.join = s->mix.nch / dev_nch;
1.35 ratchov 1438: }
1439: cmap_init(&s->mix.cmap,
1.42 ratchov 1440: s->opt->pmin, s->opt->pmin + s->mix.nch - 1,
1441: s->opt->pmin, s->opt->pmin + s->mix.nch - 1,
1.35 ratchov 1442: 0, d->pchan - 1,
1.40 ratchov 1443: s->opt->pmin, s->opt->pmax);
1.35 ratchov 1444: if (!aparams_native(&s->par)) {
1.42 ratchov 1445: dec_init(&s->mix.dec, &s->par, s->mix.nch);
1.35 ratchov 1446: s->mix.decbuf =
1.42 ratchov 1447: xmalloc(s->round * s->mix.nch * sizeof(adata_t));
1.35 ratchov 1448: }
1449: if (s->rate != d->rate) {
1450: resamp_init(&s->mix.resamp, s->round, d->round,
1.42 ratchov 1451: s->mix.nch);
1.35 ratchov 1452: s->mix.resampbuf =
1.42 ratchov 1453: xmalloc(d->round * s->mix.nch * sizeof(adata_t));
1.35 ratchov 1454: }
1455: }
1456:
1457: if (s->mode & MODE_RECMASK) {
1.42 ratchov 1458: s->sub.bpf = s->par.bps * s->sub.nch;
1.35 ratchov 1459: abuf_init(&s->sub.buf, s->appbufsz * s->sub.bpf);
1460:
1.40 ratchov 1461: dev_nch = s->opt->rmax - s->opt->rmin + 1;
1.35 ratchov 1462: s->sub.encbuf = NULL;
1463: s->sub.resampbuf = NULL;
1464: s->sub.join = 1;
1465: s->sub.expand = 1;
1.39 ratchov 1466: if (s->opt->dup) {
1.42 ratchov 1467: if (dev_nch > s->sub.nch)
1468: s->sub.join = dev_nch / s->sub.nch;
1469: else if (dev_nch < s->sub.nch)
1470: s->sub.expand = s->sub.nch / dev_nch;
1.35 ratchov 1471: }
1472: cmap_init(&s->sub.cmap,
1473: 0, ((s->mode & MODE_MON) ? d->pchan : d->rchan) - 1,
1.40 ratchov 1474: s->opt->rmin, s->opt->rmax,
1.42 ratchov 1475: s->opt->rmin, s->opt->rmin + s->sub.nch - 1,
1476: s->opt->rmin, s->opt->rmin + s->sub.nch - 1);
1.35 ratchov 1477: if (s->rate != d->rate) {
1478: resamp_init(&s->sub.resamp, d->round, s->round,
1.42 ratchov 1479: s->sub.nch);
1.35 ratchov 1480: s->sub.resampbuf =
1.42 ratchov 1481: xmalloc(d->round * s->sub.nch * sizeof(adata_t));
1.35 ratchov 1482: }
1483: if (!aparams_native(&s->par)) {
1.42 ratchov 1484: enc_init(&s->sub.enc, &s->par, s->sub.nch);
1.35 ratchov 1485: s->sub.encbuf =
1.42 ratchov 1486: xmalloc(s->round * s->sub.nch * sizeof(adata_t));
1.35 ratchov 1487: }
1488:
1489: /*
1490: * cmap_copy() doesn't write samples in all channels,
1491: * for instance when mono->stereo conversion is
1492: * disabled. So we have to prefill cmap_copy() output
1493: * with silence.
1494: */
1495: if (s->sub.resampbuf) {
1496: memset(s->sub.resampbuf, 0,
1.42 ratchov 1497: d->round * s->sub.nch * sizeof(adata_t));
1.35 ratchov 1498: } else if (s->sub.encbuf) {
1499: memset(s->sub.encbuf, 0,
1.42 ratchov 1500: s->round * s->sub.nch * sizeof(adata_t));
1.35 ratchov 1501: } else {
1502: memset(s->sub.buf.data, 0,
1.42 ratchov 1503: s->appbufsz * s->sub.nch * sizeof(adata_t));
1.35 ratchov 1504: }
1505: }
1506:
1507: #ifdef DEBUG
1508: if (log_level >= 3) {
1509: slot_log(s);
1510: log_puts(": allocated ");
1511: log_putu(s->appbufsz);
1512: log_puts("/");
1513: log_putu(SLOT_BUFSZ(s));
1514: log_puts(" fr buffers\n");
1515: }
1516: #endif
1517: }
1518:
1519: /*
1520: * free buffers & conversion chain
1521: */
1522: void
1523: slot_freebufs(struct slot *s)
1524: {
1525: if (s->mode & MODE_RECMASK) {
1526: abuf_done(&s->sub.buf);
1527: if (s->sub.encbuf)
1528: xfree(s->sub.encbuf);
1529: if (s->sub.resampbuf)
1530: xfree(s->sub.resampbuf);
1531: }
1532:
1533: if (s->mode & MODE_PLAY) {
1534: abuf_done(&s->mix.buf);
1535: if (s->mix.decbuf)
1536: xfree(s->mix.decbuf);
1537: if (s->mix.resampbuf)
1538: xfree(s->mix.resampbuf);
1539: }
1540: }
1541:
1.1 ratchov 1542: /*
1543: * allocate a new slot and register the given call-backs
1544: */
1545: struct slot *
1.37 ratchov 1546: slot_new(struct dev *d, struct opt *opt, char *who,
1547: struct slotops *ops, void *arg, int mode)
1.1 ratchov 1548: {
1549: char *p;
1550: char name[SLOT_NAMEMAX];
1551: unsigned int i, unit, umap = 0;
1552: unsigned int ser, bestser, bestidx;
1553: struct slot *s;
1554:
1555: /*
1.27 ratchov 1556: * create a ``valid'' control name (lowcase, remove [^a-z], truncate)
1.1 ratchov 1557: */
1558: for (i = 0, p = who; ; p++) {
1559: if (i == SLOT_NAMEMAX - 1 || *p == '\0') {
1560: name[i] = '\0';
1561: break;
1562: } else if (*p >= 'A' && *p <= 'Z') {
1563: name[i++] = *p + 'a' - 'A';
1564: } else if (*p >= 'a' && *p <= 'z')
1565: name[i++] = *p;
1566: }
1567: if (i == 0)
1568: strlcpy(name, "noname", SLOT_NAMEMAX);
1569:
1570: /*
1571: * find the first unused "unit" number for this name
1572: */
1573: for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) {
1574: if (s->ops == NULL)
1575: continue;
1576: if (strcmp(s->name, name) == 0)
1577: umap |= (1 << s->unit);
1578: }
1579: for (unit = 0; ; unit++) {
1580: if ((umap & (1 << unit)) == 0)
1581: break;
1582: }
1583:
1584: /*
1.18 ratchov 1585: * find a free controller slot with the same name/unit
1.1 ratchov 1586: */
1587: for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) {
1588: if (s->ops == NULL &&
1589: strcmp(s->name, name) == 0 &&
1590: s->unit == unit) {
1591: #ifdef DEBUG
1592: if (log_level >= 3) {
1593: log_puts(name);
1594: log_putu(unit);
1595: log_puts(": reused\n");
1596: }
1597: #endif
1598: goto found;
1599: }
1600: }
1601:
1602: /*
1.18 ratchov 1603: * couldn't find a matching slot, pick oldest free slot
1.1 ratchov 1604: * and set its name/unit
1605: */
1606: bestser = 0;
1607: bestidx = DEV_NSLOT;
1608: for (i = 0, s = d->slot; i < DEV_NSLOT; i++, s++) {
1609: if (s->ops != NULL)
1610: continue;
1611: ser = d->serial - s->serial;
1612: if (ser > bestser) {
1613: bestser = ser;
1614: bestidx = i;
1615: }
1616: }
1617: if (bestidx == DEV_NSLOT) {
1618: if (log_level >= 1) {
1619: log_puts(name);
1620: log_putu(unit);
1621: log_puts(": out of sub-device slots\n");
1622: }
1623: return NULL;
1624: }
1625: s = d->slot + bestidx;
1626: if (s->name[0] != '\0')
1627: s->vol = MIDI_MAXCTL;
1628: strlcpy(s->name, name, SLOT_NAMEMAX);
1629: s->serial = d->serial++;
1630: s->unit = unit;
1631: #ifdef DEBUG
1632: if (log_level >= 3) {
1633: log_puts(name);
1634: log_putu(unit);
1635: log_puts(": overwritten slot ");
1636: log_putu(bestidx);
1637: log_puts("\n");
1638: }
1639: #endif
1640:
1641: found:
1.37 ratchov 1642: if ((mode & MODE_REC) && (opt->mode & MODE_MON)) {
1643: mode |= MODE_MON;
1644: mode &= ~MODE_REC;
1645: }
1646: if ((mode & opt->mode) != mode) {
1647: if (log_level >= 1) {
1648: slot_log(s);
1649: log_puts(": requested mode not allowed\n");
1650: }
1651: return 0;
1652: }
1.1 ratchov 1653: if (!dev_ref(d))
1654: return NULL;
1.31 ratchov 1655: if ((mode & d->mode) != mode) {
1.1 ratchov 1656: if (log_level >= 1) {
1657: slot_log(s);
1658: log_puts(": requested mode not supported\n");
1659: }
1.31 ratchov 1660: dev_unref(d);
1.1 ratchov 1661: return 0;
1662: }
1.31 ratchov 1663: s->dev = d;
1.37 ratchov 1664: s->opt = opt;
1.31 ratchov 1665: s->ops = ops;
1666: s->arg = arg;
1667: s->pstate = SLOT_INIT;
1.1 ratchov 1668: s->mode = mode;
1.6 ratchov 1669: aparams_init(&s->par);
1.41 ratchov 1670: if (s->mode & MODE_PLAY)
1.42 ratchov 1671: s->mix.nch = s->opt->pmax - s->opt->pmin + 1;
1.41 ratchov 1672: if (s->mode & MODE_RECMASK)
1.42 ratchov 1673: s->sub.nch = s->opt->rmax - s->opt->rmin + 1;
1.37 ratchov 1674: if (s->opt->mmc) {
1675: s->xrun = XRUN_SYNC;
1676: s->tstate = MMC_STOP;
1677: } else {
1678: s->xrun = XRUN_IGNORE;
1679: s->tstate = MMC_OFF;
1.1 ratchov 1680: }
1681: s->appbufsz = d->bufsz;
1682: s->round = d->round;
1.5 ratchov 1683: s->rate = d->rate;
1.1 ratchov 1684: dev_midi_slotdesc(d, s);
1685: dev_midi_vol(d, s);
1.43 ratchov 1686: #ifdef DEBUG
1687: if (log_level >= 3) {
1688: slot_log(s);
1689: log_puts(": using ");
1690: dev_log(d);
1691: log_puts(".");
1692: log_puts(opt->name);
1693: log_puts(", mode = ");
1694: log_putx(mode);
1695: log_puts("\n");
1696: }
1697: #endif
1.1 ratchov 1698: return s;
1699: }
1700:
1701: /*
1702: * release the given slot
1703: */
1704: void
1705: slot_del(struct slot *s)
1706: {
1707: s->arg = s;
1708: s->ops = &zomb_slotops;
1709: switch (s->pstate) {
1710: case SLOT_INIT:
1711: s->ops = NULL;
1712: break;
1713: case SLOT_START:
1714: case SLOT_READY:
1715: case SLOT_RUN:
1716: slot_stop(s);
1717: /* PASSTHROUGH */
1718: case SLOT_STOP:
1719: break;
1720: }
1721: dev_unref(s->dev);
1722: s->dev = NULL;
1723: }
1724:
1725: /*
1726: * change the slot play volume; called either by the slot or by MIDI
1727: */
1728: void
1729: slot_setvol(struct slot *s, unsigned int vol)
1730: {
1731: #ifdef DEBUG
1732: if (log_level >= 3) {
1733: slot_log(s);
1734: log_puts(": setting volume ");
1735: log_putu(vol);
1736: log_puts("\n");
1737: }
1738: #endif
1739: s->vol = vol;
1740: s->mix.vol = MIDI_TO_ADATA(s->vol);
1741: }
1742:
1743: /*
1744: * attach the slot to the device (ie start playing & recording
1745: */
1746: void
1747: slot_attach(struct slot *s)
1748: {
1749: struct dev *d = s->dev;
1.12 ratchov 1750: long long pos;
1.1 ratchov 1751: int startpos;
1752:
1753: /*
1754: * start the device if not started
1755: */
1756: dev_wakeup(d);
1.23 ratchov 1757:
1.1 ratchov 1758: /*
1759: * get the current position, the origin is when the first sample
1760: * played and/or recorded
1761: */
1762: startpos = dev_getpos(d) * (int)s->round / (int)d->round;
1.12 ratchov 1763:
1764: /*
1765: * adjust initial clock
1766: */
1767: pos = (long long)d->delta * s->round;
1768: s->delta = startpos + pos / (int)d->round;
1769: s->delta_rem = pos % d->round;
1770:
1.1 ratchov 1771: s->pstate = SLOT_RUN;
1772: #ifdef DEBUG
1.17 ratchov 1773: if (log_level >= 2) {
1.1 ratchov 1774: slot_log(s);
1775: log_puts(": attached at ");
1776: log_puti(startpos);
1.12 ratchov 1777: log_puts(", delta = ");
1778: log_puti(d->delta);
1.1 ratchov 1779: log_puts("\n");
1780: }
1781: #endif
1782:
1783: /*
1784: * We dont check whether the device is dying,
1785: * because dev_xxx() functions are supposed to
1786: * work (i.e., not to crash)
1787: */
1788: #ifdef DEBUG
1789: if ((s->mode & d->mode) != s->mode) {
1790: slot_log(s);
1.24 ratchov 1791: log_puts(": mode beyond device mode, not attaching\n");
1.1 ratchov 1792: panic();
1793: }
1794: #endif
1795: s->next = d->slot_list;
1796: d->slot_list = s;
1.12 ratchov 1797: s->skip = 0;
1.1 ratchov 1798: if (s->mode & MODE_PLAY) {
1799: s->mix.vol = MIDI_TO_ADATA(s->vol);
1800: dev_mix_adjvol(d);
1801: }
1802: if (s->mode & MODE_RECMASK) {
1803: /*
1804: * N-th recorded block is the N-th played block
1805: */
1.12 ratchov 1806: s->sub.prime = -startpos / (int)s->round;
1.1 ratchov 1807: }
1808: }
1809:
1810: /*
1811: * if MMC is enabled, and try to attach all slots synchronously, else
1812: * simply attach the slot
1813: */
1814: void
1815: slot_ready(struct slot *s)
1816: {
1.3 ratchov 1817: /*
1818: * device may be disconnected, and if so we're called from
1819: * slot->ops->exit() on a closed device
1.23 ratchov 1820: */
1.3 ratchov 1821: if (s->dev->pstate == DEV_CFG)
1822: return;
1.1 ratchov 1823: if (s->tstate == MMC_OFF)
1824: slot_attach(s);
1825: else {
1826: s->tstate = MMC_START;
1827: dev_sync_attach(s->dev);
1828: }
1829: }
1830:
1831: /*
1832: * setup buffers & conversion layers, prepare the slot to receive data
1833: * (for playback) or start (recording).
1834: */
1835: void
1836: slot_start(struct slot *s)
1837: {
1838: #ifdef DEBUG
1839: if (s->pstate != SLOT_INIT) {
1840: slot_log(s);
1841: log_puts(": slot_start: wrong state\n");
1842: panic();
1843: }
1844: if (s->mode & MODE_PLAY) {
1845: if (log_level >= 3) {
1846: slot_log(s);
1847: log_puts(": playing ");
1848: aparams_log(&s->par);
1849: log_puts(" -> ");
1.35 ratchov 1850: aparams_log(&s->dev->par);
1.1 ratchov 1851: log_puts("\n");
1852: }
1853: }
1854: if (s->mode & MODE_RECMASK) {
1855: if (log_level >= 3) {
1856: slot_log(s);
1857: log_puts(": recording ");
1858: aparams_log(&s->par);
1859: log_puts(" <- ");
1.35 ratchov 1860: aparams_log(&s->dev->par);
1.1 ratchov 1861: log_puts("\n");
1.35 ratchov 1862: }
1.1 ratchov 1863: }
1864: #endif
1.35 ratchov 1865: slot_allocbufs(s);
1.1 ratchov 1866: if (s->mode & MODE_PLAY) {
1867: s->pstate = SLOT_START;
1868: } else {
1869: s->pstate = SLOT_READY;
1870: slot_ready(s);
1871: }
1872: }
1873:
1874: /*
1875: * stop playback and recording, and free conversion layers
1876: */
1877: void
1878: slot_detach(struct slot *s)
1879: {
1880: struct slot **ps;
1881:
1882: #ifdef DEBUG
1883: if (log_level >= 3) {
1884: slot_log(s);
1885: log_puts(": detaching\n");
1886: }
1887: #endif
1888: for (ps = &s->dev->slot_list; *ps != s; ps = &(*ps)->next) {
1889: #ifdef DEBUG
1.28 ratchov 1890: if (*ps == NULL) {
1.1 ratchov 1891: slot_log(s);
1892: log_puts(": can't detach, not on list\n");
1893: panic();
1894: }
1895: #endif
1.23 ratchov 1896: }
1.1 ratchov 1897: *ps = s->next;
1.35 ratchov 1898: if (s->mode & MODE_PLAY)
1.1 ratchov 1899: dev_mix_adjvol(s->dev);
1900: }
1901:
1902: /*
1903: * put the slot in stopping state (draining play buffers) or
1904: * stop & detach if no data to drain.
1905: */
1906: void
1907: slot_stop(struct slot *s)
1908: {
1909: #ifdef DEBUG
1910: if (log_level >= 3) {
1911: slot_log(s);
1912: log_puts(": stopping\n");
1913: }
1914: #endif
1915: if (s->pstate == SLOT_START) {
1.33 ratchov 1916: /*
1917: * If in rec-only mode, we're already in the READY or
1918: * RUN states. We're here because the play buffer was
1919: * not full enough, try to start so it's drained.
1920: */
1921: s->pstate = SLOT_READY;
1922: slot_ready(s);
1.1 ratchov 1923: }
1.34 ratchov 1924:
1925: if (s->tstate != MMC_OFF)
1926: s->tstate = MMC_STOP;
1927:
1928: if (s->pstate == SLOT_RUN) {
1929: if (s->mode & MODE_PLAY) {
1930: /*
1931: * Don't detach, dev_cycle() will do it for us
1932: * when the buffer is drained.
1933: */
1934: s->pstate = SLOT_STOP;
1935: return;
1936: }
1937: slot_detach(s);
1938: } else {
1.1 ratchov 1939: #ifdef DEBUG
1940: if (log_level >= 3) {
1941: slot_log(s);
1942: log_puts(": not drained (blocked by mmc)\n");
1943: }
1944: #endif
1945: }
1.35 ratchov 1946:
1.34 ratchov 1947: s->pstate = SLOT_INIT;
1948: s->ops->eof(s->arg);
1.35 ratchov 1949: slot_freebufs(s);
1.1 ratchov 1950: }
1951:
1.12 ratchov 1952: void
1953: slot_skip_update(struct slot *s)
1954: {
1955: int skip;
1956:
1957: skip = slot_skip(s);
1958: while (skip > 0) {
1959: #ifdef DEBUG
1960: if (log_level >= 4) {
1961: slot_log(s);
1962: log_puts(": catching skipped block\n");
1963: }
1964: #endif
1965: if (s->mode & MODE_RECMASK)
1966: s->ops->flush(s->arg);
1967: if (s->mode & MODE_PLAY)
1968: s->ops->fill(s->arg);
1969: skip--;
1970: }
1971: }
1972:
1.1 ratchov 1973: /*
1974: * notify the slot that we just wrote in the play buffer, must be called
1975: * after each write
1976: */
1977: void
1978: slot_write(struct slot *s)
1979: {
1980: if (s->pstate == SLOT_START && s->mix.buf.used == s->mix.buf.len) {
1981: #ifdef DEBUG
1982: if (log_level >= 4) {
1983: slot_log(s);
1984: log_puts(": switching to READY state\n");
1985: }
1986: #endif
1987: s->pstate = SLOT_READY;
1988: slot_ready(s);
1989: }
1.12 ratchov 1990: slot_skip_update(s);
1.1 ratchov 1991: }
1992:
1993: /*
1994: * notify the slot that we freed some space in the rec buffer
1995: */
1996: void
1997: slot_read(struct slot *s)
1998: {
1.12 ratchov 1999: slot_skip_update(s);
1.1 ratchov 2000: }