GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/sndiod/dev.c Lines: 0 925 0.0 %
Date: 2017-11-07 Branches: 0 540 0.0 %

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