GCC Code Coverage Report
Directory: ./ Exec Total Coverage
File: usr.bin/aucat/aucat.c Lines: 0 773 0.0 %
Date: 2017-11-13 Branches: 0 478 0.0 %

Line Branch Exec Source
1
/*
2
 * Copyright (c) 2008-2014 Alexandre Ratchov <alex@caoua.org>
3
 *
4
 * Permission to use, copy, modify, and distribute this software for any
5
 * purpose with or without fee is hereby granted, provided that the above
6
 * copyright notice and this permission notice appear in all copies.
7
 *
8
 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
9
 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
10
 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
11
 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
12
 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
13
 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
14
 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
15
 */
16
17
#include <errno.h>
18
#include <limits.h>
19
#include <poll.h>
20
#include <signal.h>
21
#include <sndio.h>
22
#include <stdlib.h>
23
#include <string.h>
24
#include <unistd.h>
25
#include "abuf.h"
26
#include "afile.h"
27
#include "dsp.h"
28
#include "sysex.h"
29
#include "utils.h"
30
31
/*
32
 * masks to extract command and channel of status byte
33
 */
34
#define MIDI_CMDMASK	0xf0
35
#define MIDI_CHANMASK	0x0f
36
37
/*
38
 * MIDI status bytes of voice messages
39
 */
40
#define MIDI_NOFF	0x80		/* note off */
41
#define MIDI_NON	0x90		/* note on */
42
#define MIDI_KAT	0xa0		/* key after touch */
43
#define MIDI_CTL	0xb0		/* controller */
44
#define MIDI_PC		0xc0		/* program change */
45
#define MIDI_CAT	0xd0		/* channel after touch */
46
#define MIDI_BEND	0xe0		/* pitch bend */
47
#define MIDI_ACK	0xfe		/* active sensing message */
48
49
/*
50
 * MIDI controller numbers
51
 */
52
#define MIDI_CTL_VOL	7
53
54
/*
55
 * Max coarse value
56
 */
57
#define MIDI_MAXCTL	127
58
59
/*
60
 * MIDI status bytes for sysex
61
 */
62
#define MIDI_SX_START	0xf0
63
#define MIDI_SX_STOP	0xf7
64
65
/*
66
 * audio device defaults
67
 */
68
#define DEFAULT_RATE		48000
69
#define DEFAULT_BUFSZ_MS	200
70
71
struct slot {
72
	struct slot *next;		/* next on the play/rec list */
73
	int vol;			/* dynamic range */
74
	int volctl;			/* volume in the 0..127 range */
75
	struct abuf buf;		/* file i/o buffer */
76
	int bpf;			/* bytes per frame */
77
	int cmin, cmax;			/* file channel range */
78
	struct cmap cmap;		/* channel mapper state */
79
	struct resamp resamp;		/* resampler state */
80
	struct conv conv;		/* format encoder state */
81
	int join;			/* channel join factor */
82
	int expand;			/* channel expand factor */
83
	void *resampbuf, *convbuf;	/* conversion tmp buffers */
84
	int dup;			/* mono-to-stereo and alike */
85
	int round;			/* slot-side block size */
86
	int mode;			/* MODE_{PLAY,REC} */
87
#define SLOT_CFG	0		/* buffers not allocated yet */
88
#define SLOT_INIT	1		/* not trying to do anything */
89
#define SLOT_RUN	2		/* playing/recording */
90
#define SLOT_STOP	3		/* draining (play only) */
91
	int pstate;			/* one of above */
92
	long long skip;			/* frames to skip at the beginning */
93
	long long pos;			/* start position (at device rate) */
94
	struct afile afile;		/* file desc & friends */
95
};
96
97
/*
98
 * device properties
99
 */
100
unsigned int dev_mode;			/* bitmap of SIO_{PLAY,REC} */
101
unsigned int dev_bufsz;			/* device buffer size */
102
unsigned int dev_round;			/* device block size */
103
int dev_rate;				/* device sample rate (Hz) */
104
unsigned int dev_pchan, dev_rchan;	/* play & rec channels count */
105
adata_t *dev_pbuf, *dev_rbuf;		/* play & rec buffers */
106
long long dev_pos;			/* last MMC position in frames */
107
#define DEV_STOP	0		/* stopped */
108
#define DEV_START	1		/* started */
109
unsigned int dev_pstate;		/* one of above */
110
char *dev_name;				/* device sndio(7) name */
111
char *dev_port;				/* control port sndio(7) name */
112
struct sio_hdl *dev_sh;			/* device handle */
113
struct mio_hdl *dev_mh;			/* MIDI control port handle */
114
unsigned int dev_volctl = MIDI_MAXCTL;	/* master volume */
115
116
/*
117
 * MIDI parser state
118
 */
119
#define MIDI_MSGMAX	32		/* max size of MIDI msg */
120
unsigned char dev_msg[MIDI_MSGMAX];	/* parsed input message */
121
unsigned int dev_mst;			/* input MIDI running status */
122
unsigned int dev_mused;			/* bytes used in ``msg'' */
123
unsigned int dev_midx;			/* current ``msg'' size */
124
unsigned int dev_mlen;			/* expected ``msg'' length */
125
unsigned int dev_prime;			/* blocks to write to start */
126
127
unsigned int log_level = 1;
128
volatile sig_atomic_t quit_flag = 0;
129
struct slot *slot_list = NULL;
130
131
/*
132
 * length of voice and common MIDI messages (status byte included)
133
 */
134
unsigned int voice_len[] = { 3, 3, 3, 3, 2, 2, 3 };
135
unsigned int common_len[] = { 0, 2, 3, 2, 0, 0, 1, 1 };
136
137
char usagestr[] = "usage: aucat [-dn] [-b size] "
138
    "[-c min:max] [-e enc] [-f device] [-g position]\n\t"
139
    "[-h fmt] [-i file] [-j flag] [-o file] [-p position] [-q port]\n\t"
140
    "[-r rate] [-v volume]\n";
141
142
static void
143
slot_log(struct slot *s)
144
{
145
#ifdef DEBUG
146
	static char *pstates[] = {
147
		"cfg", "ini", "run", "stp"
148
	};
149
#endif
150
	log_puts(s->afile.path);
151
#ifdef DEBUG
152
	if (log_level >= 3) {
153
		log_puts(",pst=");
154
		log_puts(pstates[s->pstate]);
155
	}
156
#endif
157
}
158
159
static void
160
slot_flush(struct slot *s)
161
{
162
	int count, n;
163
	unsigned char *data;
164
165
	for (;;) {
166
		data = abuf_rgetblk(&s->buf, &count);
167
		if (count == 0)
168
			break;
169
		n = afile_write(&s->afile, data, count);
170
		if (n == 0) {
171
			slot_log(s);
172
			log_puts(": can't write, disabled\n");
173
			s->pstate = SLOT_INIT;
174
			return;
175
		}
176
		abuf_rdiscard(&s->buf, n);
177
	}
178
}
179
180
static void
181
slot_fill(struct slot *s)
182
{
183
	int count, n;
184
	unsigned char *data;
185
186
	for (;;) {
187
		data = abuf_wgetblk(&s->buf, &count);
188
		if (count == 0)
189
			break;
190
		n = afile_read(&s->afile, data, count);
191
		if (n == 0) {
192
#ifdef DEBUG
193
			if (log_level >= 3) {
194
				slot_log(s);
195
				log_puts(": eof reached, stopping\n");
196
			}
197
#endif
198
			s->pstate = SLOT_STOP;
199
			break;
200
		}
201
		abuf_wcommit(&s->buf, n);
202
	}
203
}
204
205
static int
206
slot_new(char *path, int mode, struct aparams *par, int hdr,
207
    int cmin, int cmax, int rate, int dup, int vol, long long pos)
208
{
209
	struct slot *s;
210
211
	s = xmalloc(sizeof(struct slot));
212
	if (!afile_open(&s->afile, path, hdr,
213
		mode == SIO_PLAY ? AFILE_FREAD : AFILE_FWRITE,
214
		par, rate, cmax - cmin + 1)) {
215
		xfree(s);
216
		return 0;
217
	}
218
	s->cmin = cmin;
219
	s->cmax = cmin + s->afile.nch - 1;
220
	s->dup = dup;
221
	s->vol = MIDI_TO_ADATA(vol);
222
	s->mode = mode;
223
	s->pstate = SLOT_CFG;
224
	s->pos = pos;
225
	if (log_level >= 2) {
226
		slot_log(s);
227
		log_puts(": ");
228
		log_puts(s->mode == SIO_PLAY ? "play" : "rec");
229
		log_puts(", chan ");
230
		log_putu(s->cmin);
231
		log_puts(":");
232
		log_putu(s->cmax);
233
		log_puts(", ");
234
		log_putu(s->afile.rate);
235
		log_puts("Hz, ");
236
		switch (s->afile.fmt) {
237
		case AFILE_FMT_PCM:
238
			aparams_log(&s->afile.par);
239
			break;
240
		case AFILE_FMT_ULAW:
241
			log_puts("ulaw");
242
			break;
243
		case AFILE_FMT_ALAW:
244
			log_puts("alaw");
245
			break;
246
		case AFILE_FMT_FLOAT:
247
			log_puts("f32le");
248
			break;
249
		}
250
		if (s->mode == SIO_PLAY && s->afile.endpos >= 0) {
251
			log_puts(", bytes ");
252
			log_puti(s->afile.startpos);
253
			log_puts("..");
254
			log_puti(s->afile.endpos);
255
		}
256
		if (s->mode == SIO_PLAY) {
257
			log_puts(", vol ");
258
			log_puti(s->vol);
259
		}
260
		log_puts("\n");
261
	}
262
	s->next = slot_list;
263
	slot_list = s;
264
	return 1;
265
}
266
267
static void
268
slot_init(struct slot *s)
269
{
270
	unsigned int slot_nch, bufsz;
271
272
#ifdef DEBUG
273
	if (s->pstate != SLOT_CFG) {
274
		slot_log(s);
275
		log_puts(": slot_init: wrong state\n");
276
		panic();
277
	}
278
#endif
279
	s->bpf = s->afile.par.bps * (s->cmax - s->cmin + 1);
280
	s->round = (dev_round * s->afile.rate + dev_rate - 1) / dev_rate;
281
282
	bufsz = s->round * (dev_bufsz / dev_round);
283
	bufsz -= bufsz % s->round;
284
	if (bufsz == 0)
285
		bufsz = s->round;
286
	abuf_init(&s->buf, bufsz * s->bpf);
287
#ifdef DEBUG
288
	if (log_level >= 3) {
289
		slot_log(s);
290
		log_puts(": allocated ");
291
		log_putu(bufsz);
292
		log_puts(" frame buffer\n");
293
	}
294
#endif
295
296
	slot_nch = s->cmax - s->cmin + 1;
297
	s->convbuf = NULL;
298
	s->resampbuf = NULL;
299
	s->join = 1;
300
	s->expand = 1;
301
	if (s->mode & SIO_PLAY) {
302
		if (s->dup) {
303
			if (dev_pchan > slot_nch)
304
				s->expand = dev_pchan / slot_nch;
305
			else if (dev_pchan < slot_nch)
306
				s->join = slot_nch / dev_pchan;
307
		}
308
		cmap_init(&s->cmap,
309
		    s->cmin, s->cmax,
310
		    s->cmin, s->cmax,
311
		    0, dev_pchan - 1,
312
		    0, dev_pchan - 1);
313
		if (s->afile.fmt != AFILE_FMT_PCM ||
314
		    !aparams_native(&s->afile.par)) {
315
			dec_init(&s->conv, &s->afile.par, slot_nch);
316
			s->convbuf =
317
			    xmalloc(s->round * slot_nch * sizeof(adata_t));
318
		}
319
		if (s->afile.rate != dev_rate) {
320
			resamp_init(&s->resamp, s->afile.rate, dev_rate,
321
			    slot_nch);
322
			s->resampbuf =
323
			    xmalloc(dev_round * slot_nch * sizeof(adata_t));
324
		}
325
	}
326
	if (s->mode & SIO_REC) {
327
		if (s->dup) {
328
			if (dev_rchan > slot_nch)
329
				s->join = dev_rchan / slot_nch;
330
			else if (dev_rchan < slot_nch)
331
				s->expand = slot_nch / dev_rchan;
332
		}
333
		cmap_init(&s->cmap,
334
		    0, dev_rchan - 1,
335
		    0, dev_rchan - 1,
336
		    s->cmin, s->cmax,
337
		    s->cmin, s->cmax);
338
		if (s->afile.rate != dev_rate) {
339
			resamp_init(&s->resamp, dev_rate, s->afile.rate,
340
			    slot_nch);
341
			s->resampbuf =
342
			    xmalloc(dev_round * slot_nch * sizeof(adata_t));
343
		}
344
		if (!aparams_native(&s->afile.par)) {
345
			enc_init(&s->conv, &s->afile.par, slot_nch);
346
			s->convbuf =
347
			    xmalloc(s->round * slot_nch * sizeof(adata_t));
348
		}
349
350
		/*
351
		 * cmap_copy() doesn't write samples in all channels,
352
	         * for instance when mono->stereo conversion is
353
	         * disabled. So we have to prefill cmap_copy() output
354
	         * with silence.
355
	         */
356
		if (s->resampbuf) {
357
			memset(s->resampbuf, 0,
358
			    dev_round * slot_nch * sizeof(adata_t));
359
		} else if (s->convbuf) {
360
			memset(s->convbuf, 0,
361
			    s->round * slot_nch * sizeof(adata_t));
362
		} else {
363
			memset(s->buf.data, 0,
364
			    bufsz * slot_nch * sizeof(adata_t));
365
		}
366
	}
367
	s->pstate = SLOT_INIT;
368
#ifdef DEBUG
369
	if (log_level >= 3) {
370
		slot_log(s);
371
		log_puts(": chain initialized\n");
372
	}
373
#endif
374
}
375
376
static void
377
slot_start(struct slot *s, long long pos)
378
{
379
#ifdef DEBUG
380
	if (s->pstate != SLOT_INIT) {
381
		slot_log(s);
382
		log_puts(": slot_start: wrong state\n");
383
		panic();
384
	}
385
#endif
386
	pos -= s->pos;
387
	if (pos < 0) {
388
		s->skip = -pos;
389
		pos = 0;
390
	} else
391
		s->skip = 0;
392
393
	/*
394
	 * convert pos to slot sample rate
395
	 *
396
	 * At this stage, we could adjust s->resamp.diff to get
397
	 * sub-frame accuracy.
398
	 */
399
	pos = pos * s->afile.rate / dev_rate;
400
401
	if (!afile_seek(&s->afile, pos * s->bpf)) {
402
		s->pstate = SLOT_INIT;
403
		return;
404
	}
405
	s->pstate = SLOT_RUN;
406
	if (s->mode & SIO_PLAY)
407
		slot_fill(s);
408
#ifdef DEBUG
409
	if (log_level >= 2) {
410
		slot_log(s);
411
		log_puts(": started\n");
412
	}
413
#endif
414
}
415
416
static void
417
slot_stop(struct slot *s)
418
{
419
	if (s->pstate == SLOT_INIT)
420
		return;
421
	if (s->mode & SIO_REC)
422
		slot_flush(s);
423
	if (s->mode & SIO_PLAY)
424
		s->buf.used = s->buf.start = 0;
425
	s->pstate = SLOT_INIT;
426
#ifdef DEBUG
427
	if (log_level >= 2) {
428
		slot_log(s);
429
		log_puts(": stopped\n");
430
	}
431
#endif
432
}
433
434
static void
435
slot_del(struct slot *s)
436
{
437
	struct slot **ps;
438
439
	if (s->pstate != SLOT_CFG) {
440
		slot_stop(s);
441
		afile_close(&s->afile);
442
#ifdef DEBUG
443
		if (log_level >= 3) {
444
			slot_log(s);
445
			log_puts(": closed\n");
446
		}
447
#endif
448
		abuf_done(&s->buf);
449
		if (s->resampbuf)
450
			xfree(s->resampbuf);
451
		if (s->convbuf)
452
			xfree(s->convbuf);
453
	}
454
	for (ps = &slot_list; *ps != s; ps = &(*ps)->next)
455
		; /* nothing */
456
	*ps = s->next;
457
	xfree(s);
458
}
459
460
static void
461
slot_getcnt(struct slot *s, int *icnt, int *ocnt)
462
{
463
	int cnt;
464
465
	if (s->resampbuf)
466
		resamp_getcnt(&s->resamp, icnt, ocnt);
467
	else {
468
		cnt = (*icnt < *ocnt) ? *icnt : *ocnt;
469
		*icnt = cnt;
470
		*ocnt = cnt;
471
	}
472
}
473
474
static void
475
play_filt_resamp(struct slot *s, void *res_in, void *out, int icnt, int ocnt)
476
{
477
	int i, offs, vol, nch;
478
	void *in;
479
480
	if (s->resampbuf) {
481
		resamp_do(&s->resamp, res_in, s->resampbuf, icnt, ocnt);
482
		in = s->resampbuf;
483
	} else
484
		in = res_in;
485
486
	nch = s->cmap.nch;
487
	vol = s->vol / s->join; /* XXX */
488
	cmap_add(&s->cmap, in, out, vol, ocnt);
489
490
	offs = 0;
491
	for (i = s->join - 1; i > 0; i--) {
492
		offs += nch;
493
		cmap_add(&s->cmap, (adata_t *)in + offs, out, vol, ocnt);
494
	}
495
	offs = 0;
496
	for (i = s->expand - 1; i > 0; i--) {
497
		offs += nch;
498
		cmap_add(&s->cmap, in, (adata_t *)out + offs, vol, ocnt);
499
	}
500
}
501
502
static void
503
play_filt_dec(struct slot *s, void *in, void *out, int icnt, int ocnt)
504
{
505
	void *tmp;
506
507
	tmp = s->convbuf;
508
	if (tmp) {
509
		switch (s->afile.fmt) {
510
		case AFILE_FMT_PCM:
511
			dec_do(&s->conv, in, tmp, icnt);
512
			break;
513
		case AFILE_FMT_ULAW:
514
			dec_do_ulaw(&s->conv, in, tmp, icnt, 0);
515
			break;
516
		case AFILE_FMT_ALAW:
517
			dec_do_ulaw(&s->conv, in, tmp, icnt, 1);
518
			break;
519
		case AFILE_FMT_FLOAT:
520
			dec_do_float(&s->conv, in, tmp, icnt);
521
			break;
522
		}
523
	} else
524
		tmp = in;
525
	play_filt_resamp(s, tmp, out, icnt, ocnt);
526
}
527
528
/*
529
 * Mix as many as possible frames (but not more than a block) from the
530
 * slot buffer to the given location. Return the number of frames mixed
531
 * in the output buffer
532
 */
533
static int
534
slot_mix_badd(struct slot *s, adata_t *odata)
535
{
536
	adata_t *idata;
537
	int len, icnt, ocnt, otodo, odone;
538
539
	odone = 0;
540
	otodo = dev_round;
541
	if (s->skip > 0) {
542
		ocnt = otodo;
543
		if (ocnt > s->skip)
544
			ocnt = s->skip;
545
		s->skip -= ocnt;
546
		odata += dev_pchan * ocnt;
547
		otodo -= ocnt;
548
		odone += ocnt;
549
	}
550
	while (otodo > 0) {
551
		idata = (adata_t *)abuf_rgetblk(&s->buf, &len);
552
		icnt = len / s->bpf;
553
		if (icnt > s->round)
554
			icnt = s->round;
555
		ocnt = otodo;
556
		slot_getcnt(s, &icnt, &ocnt);
557
		if (icnt == 0)
558
			break;
559
		play_filt_dec(s, idata, odata, icnt, ocnt);
560
		abuf_rdiscard(&s->buf, icnt * s->bpf);
561
		otodo -= ocnt;
562
		odone += ocnt;
563
		odata += ocnt * dev_pchan;
564
	}
565
	return odone;
566
}
567
568
static void
569
rec_filt_resamp(struct slot *s, void *in, void *res_out, int icnt, int ocnt)
570
{
571
	int i, vol, offs, nch;
572
	void *out = res_out;
573
574
	out = (s->resampbuf) ? s->resampbuf : res_out;
575
576
	nch = s->cmap.nch;
577
	vol = ADATA_UNIT / s->join;
578
	cmap_copy(&s->cmap, in, out, vol, icnt);
579
580
	offs = 0;
581
	for (i = s->join - 1; i > 0; i--) {
582
		offs += nch;
583
		cmap_add(&s->cmap, (adata_t *)in + offs, out, vol, icnt);
584
	}
585
	offs = 0;
586
	for (i = s->expand - 1; i > 0; i--) {
587
		offs += nch;
588
		cmap_copy(&s->cmap, in, (adata_t *)out + offs, vol, icnt);
589
	}
590
	if (s->resampbuf)
591
		resamp_do(&s->resamp, s->resampbuf, res_out, icnt, ocnt);
592
	else
593
		ocnt = icnt;
594
}
595
596
static void
597
rec_filt_enc(struct slot *s, void *in, void *out, int icnt, int ocnt)
598
{
599
	void *tmp;
600
601
	tmp = s->convbuf;
602
	rec_filt_resamp(s, in, tmp ? tmp : out, icnt, ocnt);
603
	if (tmp)
604
		enc_do(&s->conv, tmp, out, ocnt);
605
}
606
607
/*
608
 * Copy "todo" frames from the given buffer to the slot buffer,
609
 * but not more than a block.
610
 */
611
static void
612
slot_sub_bcopy(struct slot *s, adata_t *idata, int itodo)
613
{
614
	adata_t *odata;
615
	int len, icnt, ocnt;
616
617
	if (s->skip > 0) {
618
		icnt = itodo;
619
		if (icnt > s->skip)
620
			icnt = s->skip;
621
		s->skip -= icnt;
622
		idata += dev_rchan * icnt;
623
		itodo -= icnt;
624
	}
625
626
	while (itodo > 0) {
627
		odata = (adata_t *)abuf_wgetblk(&s->buf, &len);
628
		ocnt = len / s->bpf;
629
		if (ocnt > s->round)
630
			ocnt = s->round;
631
		icnt = itodo;
632
		slot_getcnt(s, &icnt, &ocnt);
633
		if (ocnt == 0)
634
			break;
635
		rec_filt_enc(s, idata, odata, icnt, ocnt);
636
		abuf_wcommit(&s->buf, ocnt * s->bpf);
637
		itodo -= icnt;
638
		idata += icnt * dev_rchan;
639
	}
640
}
641
642
static int
643
dev_open(char *dev, int mode, int bufsz, char *port)
644
{
645
	int rate, pmax, rmax;
646
	struct sio_par par;
647
	struct slot *s;
648
649
	if (port) {
650
		dev_port = port;
651
		dev_mh = mio_open(dev_port, MIO_IN, 0);
652
		if (dev_mh == NULL) {
653
			log_puts(port);
654
			log_puts(": couldn't open midi port\n");
655
			return 0;
656
		}
657
	} else
658
		dev_mh = NULL;
659
660
	dev_name = dev;
661
	dev_sh = sio_open(dev, mode, 0);
662
	if (dev_sh == NULL) {
663
		log_puts(dev_name);
664
		log_puts(": couldn't open audio device\n");
665
		return 0;
666
	}
667
668
	rate = pmax = rmax = 0;
669
	for (s = slot_list; s != NULL; s = s->next) {
670
		if (s->afile.rate > rate)
671
			rate = s->afile.rate;
672
		if (s->mode == SIO_PLAY) {
673
			if (s->cmax > pmax)
674
				pmax = s->cmax;
675
		}
676
		if (s->mode == SIO_REC) {
677
			if (s->cmax > rmax)
678
				rmax = s->cmax;
679
		}
680
	}
681
	sio_initpar(&par);
682
	par.bits = ADATA_BITS;
683
	par.bps = sizeof(adata_t);
684
	par.msb = 0;
685
	par.le = SIO_LE_NATIVE;
686
	par.rate = rate;
687
	if (mode & SIO_PLAY)
688
		par.pchan = pmax + 1;
689
	if (mode & SIO_REC)
690
		par.rchan = rmax + 1;
691
	par.appbufsz = bufsz > 0 ? bufsz : rate * DEFAULT_BUFSZ_MS / 1000;
692
	if (!sio_setpar(dev_sh, &par) || !sio_getpar(dev_sh, &par)) {
693
		log_puts(dev_name);
694
		log_puts(": couldn't set audio params\n");
695
		return 0;
696
	}
697
	if (par.bits != ADATA_BITS ||
698
	    par.bps != sizeof(adata_t) ||
699
	    (par.bps > 1 && par.le != SIO_LE_NATIVE) ||
700
	    (par.bps * 8 > par.bits && par.msb)) {
701
		log_puts(dev_name);
702
		log_puts(": unsupported audio params\n");
703
		return 0;
704
	}
705
	dev_mode = mode;
706
	dev_rate = par.rate;
707
	dev_bufsz = par.bufsz;
708
	dev_round = par.round;
709
	if (mode & SIO_PLAY) {
710
		dev_pchan = par.pchan;
711
		dev_pbuf = xmalloc(sizeof(adata_t) * dev_pchan * dev_round);
712
	}
713
	if (mode & SIO_REC) {
714
		dev_rchan = par.rchan;
715
		dev_rbuf = xmalloc(sizeof(adata_t) * dev_rchan * dev_round);
716
	}
717
	dev_pstate = DEV_STOP;
718
	if (log_level >= 2) {
719
		log_puts(dev_name);
720
		log_puts(": ");
721
		log_putu(dev_rate);
722
		log_puts("Hz");
723
		if (dev_mode & SIO_PLAY) {
724
			log_puts(", play 0:");
725
			log_puti(dev_pchan - 1);
726
		}
727
		if (dev_mode & SIO_REC) {
728
			log_puts(", rec 0:");
729
			log_puti(dev_rchan - 1);
730
		}
731
		log_puts(", ");
732
		log_putu(dev_bufsz / dev_round);
733
		log_puts(" blocks of ");
734
		log_putu(dev_round);
735
		log_puts(" frames\n");
736
	}
737
	return 1;
738
}
739
740
static void
741
dev_close(void)
742
{
743
	sio_close(dev_sh);
744
	if (dev_mh)
745
		mio_close(dev_mh);
746
	if (dev_mode & SIO_PLAY)
747
		xfree(dev_pbuf);
748
	if (dev_mode & SIO_REC)
749
		xfree(dev_rbuf);
750
}
751
752
static void
753
dev_master(int val)
754
{
755
	struct slot *s;
756
	int mastervol, slotvol;
757
758
	mastervol = MIDI_TO_ADATA(dev_volctl);
759
	for (s = slot_list; s != NULL; s = s->next) {
760
		slotvol = MIDI_TO_ADATA(val);
761
		s->vol = ADATA_MUL(mastervol, slotvol);
762
	}
763
#ifdef DEBUG
764
	if (log_level >= 3) {
765
		log_puts("master volume set to ");
766
		log_putu(val);
767
		log_puts("\n");
768
	}
769
#endif
770
}
771
772
static void
773
dev_slotvol(int midich, int val)
774
{
775
	struct slot *s;
776
	int mastervol, slotvol;
777
778
	for (s = slot_list; s != NULL; s = s->next) {
779
		if (midich == 0) {
780
			mastervol = MIDI_TO_ADATA(dev_volctl);
781
			slotvol = MIDI_TO_ADATA(val);
782
			s->vol = ADATA_MUL(mastervol, slotvol);
783
#ifdef DEBUG
784
			if (log_level >= 3) {
785
				slot_log(s);
786
				log_puts(": volume set to ");
787
				log_putu(val);
788
				log_puts("\n");
789
			}
790
#endif
791
			break;
792
		}
793
	}
794
}
795
796
/*
797
 * start all slots simultaneously
798
 */
799
static void
800
dev_mmcstart(void)
801
{
802
	struct slot *s;
803
804
	if (dev_pstate == DEV_STOP) {
805
		dev_pstate = DEV_START;
806
		for (s = slot_list; s != NULL; s = s->next)
807
			slot_start(s, dev_pos);
808
		dev_prime = (dev_mode & SIO_PLAY) ? dev_bufsz / dev_round : 0;
809
		sio_start(dev_sh);
810
		if (log_level >= 2)
811
			log_puts("started\n");
812
	} else {
813
#ifdef DEBUG
814
		if (log_level >= 3)
815
			log_puts("ignoring mmc start\n");
816
#endif
817
	}
818
}
819
820
/*
821
 * stop all slots simultaneously
822
 */
823
static void
824
dev_mmcstop(void)
825
{
826
	struct slot *s;
827
828
	if (dev_pstate == DEV_START) {
829
		dev_pstate = DEV_STOP;
830
		for (s = slot_list; s != NULL; s = s->next)
831
			slot_stop(s);
832
		sio_stop(dev_sh);
833
		if (log_level >= 2)
834
			log_puts("stopped\n");
835
	} else {
836
#ifdef DEBUG
837
		if (log_level >= 3)
838
			log_puts("ignored mmc stop\n");
839
#endif
840
	}
841
}
842
843
/*
844
 * relocate all slots simultaneously
845
 */
846
static void
847
dev_mmcloc(int hr, int min, int sec, int fr, int cent, int fps)
848
{
849
	long long pos;
850
851
	pos = (long long)dev_rate * hr * 3600 +
852
	    (long long)dev_rate * min * 60 +
853
	    (long long)dev_rate * sec +
854
	    (long long)dev_rate * fr / fps +
855
	    (long long)dev_rate * cent / (100 * fps);
856
	if (dev_pos == pos)
857
		return;
858
	dev_pos = pos;
859
	if (log_level >= 2) {
860
		log_puts("relocated to ");
861
		log_putu(hr);
862
		log_puts(":");
863
		log_putu(min);
864
		log_puts(":");
865
		log_putu(sec);
866
		log_puts(".");
867
		log_putu(fr);
868
		log_puts(".");
869
		log_putu(cent);
870
		log_puts(" at ");
871
		log_putu(fps);
872
		log_puts("fps\n");
873
	}
874
	if (dev_pstate == DEV_START) {
875
		dev_mmcstop();
876
		dev_mmcstart();
877
	}
878
}
879
880
static void
881
dev_imsg(unsigned char *msg, unsigned int len)
882
{
883
	struct sysex *x;
884
	unsigned int fps, chan;
885
886
	if ((msg[0] & MIDI_CMDMASK) == MIDI_CTL && msg[1] == MIDI_CTL_VOL) {
887
		chan = msg[0] & MIDI_CHANMASK;
888
		dev_slotvol(chan, msg[2]);
889
		return;
890
	}
891
	x = (struct sysex *)msg;
892
	if (x->start != SYSEX_START)
893
		return;
894
	if (len < SYSEX_SIZE(empty))
895
		return;
896
	if (x->type != SYSEX_TYPE_RT)
897
		return;
898
	if (x->id0 == SYSEX_CONTROL && x->id1 == SYSEX_MASTER) {
899
		if (len == SYSEX_SIZE(master))
900
			dev_master(x->u.master.coarse);
901
		return;
902
	}
903
	if (x->id0 != SYSEX_MMC)
904
		return;
905
	switch (x->id1) {
906
	case SYSEX_MMC_STOP:
907
		if (len != SYSEX_SIZE(stop))
908
			return;
909
		dev_mmcstop();
910
		break;
911
	case SYSEX_MMC_START:
912
		if (len != SYSEX_SIZE(start))
913
			return;
914
		dev_mmcstart();
915
		break;
916
	case SYSEX_MMC_LOC:
917
		if (len != SYSEX_SIZE(loc) ||
918
		    x->u.loc.len != SYSEX_MMC_LOC_LEN ||
919
		    x->u.loc.cmd != SYSEX_MMC_LOC_CMD)
920
			return;
921
		switch (x->u.loc.hr >> 5) {
922
		case MTC_FPS_24:
923
			fps = 24;
924
			break;
925
		case MTC_FPS_25:
926
			fps = 25;
927
			break;
928
		case MTC_FPS_30:
929
			fps = 30;
930
			break;
931
		default:
932
			dev_mmcstop();
933
			return;
934
		}
935
		dev_mmcloc(x->u.loc.hr & 0x1f,
936
		    x->u.loc.min,
937
		    x->u.loc.sec,
938
		    x->u.loc.fr,
939
		    x->u.loc.cent,
940
		    fps);
941
		break;
942
	}
943
}
944
945
/*
946
 * parse the given data chunk and call imsg() for each message
947
 */
948
static void
949
midi_in(unsigned char *idata, int icount)
950
{
951
	int i;
952
	unsigned char c;
953
954
	for (i = 0; i < icount; i++) {
955
		c = *idata++;
956
		if (c >= 0xf8) {
957
			/* we don't use real-time events */
958
		} else if (c == SYSEX_END) {
959
			if (dev_mst == SYSEX_START) {
960
				dev_msg[dev_midx++] = c;
961
				dev_imsg(dev_msg, dev_midx);
962
			}
963
			dev_mst = 0;
964
			dev_midx = 0;
965
		} else if (c >= 0xf0) {
966
			dev_msg[0] = c;
967
			dev_mlen = common_len[c & 7];
968
			dev_mst = c;
969
			dev_midx = 1;
970
		} else if (c >= 0x80) {
971
			dev_msg[0] = c;
972
			dev_mlen = voice_len[(c >> 4) & 7];
973
			dev_mst = c;
974
			dev_midx = 1;
975
		} else if (dev_mst) {
976
			if (dev_midx == 0 && dev_mst != SYSEX_START)
977
				dev_msg[dev_midx++] = dev_mst;
978
			dev_msg[dev_midx++] = c;
979
			if (dev_midx == dev_mlen) {
980
				dev_imsg(dev_msg, dev_midx);
981
				if (dev_mst >= 0xf0)
982
					dev_mst = 0;
983
				dev_midx = 0;
984
			} else if (dev_midx == MIDI_MSGMAX) {
985
				/* sysex too long */
986
				dev_mst = 0;
987
			}
988
		}
989
	}
990
}
991
992
static int
993
slot_list_mix(unsigned int round, unsigned int pchan, adata_t *pbuf)
994
{
995
	unsigned int done, n;
996
	struct slot *s;
997
998
	memset(pbuf, 0, pchan * round * sizeof(adata_t));
999
	done = 0;
1000
	for (s = slot_list; s != NULL; s = s->next) {
1001
		if (s->pstate == SLOT_INIT || !(s->mode & SIO_PLAY))
1002
			continue;
1003
		if (s->pstate == SLOT_STOP && s->buf.used < s->bpf) {
1004
#ifdef DEBUG
1005
			if (log_level >= 3) {
1006
				slot_log(s);
1007
				log_puts(": drained, done\n");
1008
			}
1009
#endif
1010
			slot_stop(s);
1011
			continue;
1012
		}
1013
		n = slot_mix_badd(s, dev_pbuf);
1014
		if (n > done)
1015
			done = n;
1016
	}
1017
	return done;
1018
}
1019
1020
static int
1021
slot_list_copy(unsigned int count, unsigned int rchan, adata_t *rbuf)
1022
{
1023
	unsigned int done;
1024
	struct slot *s;
1025
1026
	done = 0;
1027
	for (s = slot_list; s != NULL; s = s->next) {
1028
		if (s->pstate == SLOT_INIT || !(s->mode & SIO_REC))
1029
			continue;
1030
		slot_sub_bcopy(s, rbuf, count);
1031
		done = count;
1032
	}
1033
	return done;
1034
}
1035
1036
static void
1037
slot_list_iodo(void)
1038
{
1039
	struct slot *s;
1040
1041
	for (s = slot_list; s != NULL; s = s->next) {
1042
		if (s->pstate != SLOT_RUN)
1043
			continue;
1044
		if ((s->mode & SIO_PLAY) &&
1045
		    (s->buf.used < s->round * s->bpf))
1046
			slot_fill(s);
1047
		if ((s->mode & SIO_REC) &&
1048
		    (s->buf.len - s->buf.used < s->round * s->bpf))
1049
			slot_flush(s);
1050
	}
1051
}
1052
1053
static int
1054
offline(void)
1055
{
1056
	unsigned int todo;
1057
	int rate, cmax;
1058
	struct slot *s;
1059
1060
	rate = cmax = 0;
1061
	for (s = slot_list; s != NULL; s = s->next) {
1062
		if (s->afile.rate > rate)
1063
			rate = s->afile.rate;
1064
		if (s->cmax > cmax)
1065
			cmax = s->cmax;
1066
	}
1067
	dev_sh = NULL;
1068
	dev_name = "offline";
1069
	dev_mode = SIO_PLAY | SIO_REC;
1070
	dev_rate = rate;
1071
	dev_bufsz = rate;
1072
	dev_round = rate;
1073
	dev_pchan = dev_rchan = cmax + 1;
1074
	dev_pbuf = dev_rbuf = xmalloc(sizeof(adata_t) * dev_pchan * dev_round);
1075
	dev_pstate = DEV_STOP;
1076
	for (s = slot_list; s != NULL; s = s->next)
1077
		slot_init(s);
1078
	for (s = slot_list; s != NULL; s = s->next)
1079
		slot_start(s, 0);
1080
	for (;;) {
1081
		todo = slot_list_mix(dev_round, dev_pchan, dev_pbuf);
1082
		if (todo == 0)
1083
			break;
1084
		slot_list_copy(todo, dev_pchan, dev_pbuf);
1085
		slot_list_iodo();
1086
	}
1087
	xfree(dev_pbuf);
1088
	while (slot_list)
1089
		slot_del(slot_list);
1090
	return 1;
1091
}
1092
1093
static int
1094
playrec_cycle(void)
1095
{
1096
	unsigned int n, todo;
1097
	unsigned char *p;
1098
	int pcnt, rcnt;
1099
1100
#ifdef DEBUG
1101
	if (log_level >= 4) {
1102
		log_puts(dev_name);
1103
		log_puts(": cycle, prime = ");
1104
		log_putu(dev_prime);
1105
		log_puts("\n");
1106
	}
1107
#endif
1108
	pcnt = rcnt = 0;
1109
	if (dev_mode & SIO_REC) {
1110
		if (dev_prime > 0)
1111
			dev_prime--;
1112
		else {
1113
			todo = dev_round * dev_rchan * sizeof(adata_t);
1114
			p = (unsigned char *)dev_rbuf;
1115
			while (todo > 0) {
1116
				n = sio_read(dev_sh, p, todo);
1117
				if (n == 0) {
1118
					log_puts(dev_name);
1119
					log_puts(": failed to read "
1120
					    "from device\n");
1121
					return 0;
1122
				}
1123
				p += n;
1124
				todo -= n;
1125
			}
1126
			rcnt = slot_list_copy(dev_round, dev_rchan, dev_rbuf);
1127
		}
1128
	}
1129
	if (dev_mode & SIO_PLAY) {
1130
		pcnt = slot_list_mix(dev_round, dev_pchan, dev_pbuf);
1131
		todo = sizeof(adata_t) * dev_pchan * dev_round;
1132
		n = sio_write(dev_sh, dev_pbuf, todo);
1133
		if (n == 0) {
1134
			log_puts(dev_name);
1135
			log_puts(": failed to write to device\n");
1136
			return 0;
1137
		}
1138
	}
1139
	slot_list_iodo();
1140
	return pcnt > 0 || rcnt > 0;
1141
}
1142
1143
static void
1144
sigint(int s)
1145
{
1146
	if (quit_flag)
1147
		_exit(1);
1148
	quit_flag = 1;
1149
}
1150
1151
static int
1152
playrec(char *dev, int mode, int bufsz, char *port)
1153
{
1154
#define MIDIBUFSZ 0x100
1155
	unsigned char mbuf[MIDIBUFSZ];
1156
	struct sigaction sa;
1157
	struct pollfd *pfds;
1158
	struct slot *s;
1159
	int n, ns, nm, ev;
1160
1161
	if (!dev_open(dev, mode, bufsz, port))
1162
		return 0;
1163
	n = sio_nfds(dev_sh);
1164
	if (dev_mh)
1165
		n += mio_nfds(dev_mh);
1166
	pfds = xmalloc(n * sizeof(struct pollfd));
1167
	for (s = slot_list; s != NULL; s = s->next)
1168
		slot_init(s);
1169
	if (dev_mh == NULL)
1170
		dev_mmcstart();
1171
	else {
1172
		if (log_level >= 2)
1173
			log_puts("ready, waiting for mmc messages\n");
1174
	}
1175
1176
	quit_flag = 0;
1177
	sigfillset(&sa.sa_mask);
1178
	sa.sa_flags = SA_RESTART;
1179
	sa.sa_handler = sigint;
1180
	sigaction(SIGINT, &sa, NULL);
1181
	sigaction(SIGTERM, &sa, NULL);
1182
	sigaction(SIGHUP, &sa, NULL);
1183
	while (!quit_flag) {
1184
		if (dev_pstate == DEV_START) {
1185
			ev = 0;
1186
			if (mode & SIO_PLAY)
1187
				ev |= POLLOUT;
1188
			if (mode & SIO_REC)
1189
				ev |= POLLIN;
1190
			ns = sio_pollfd(dev_sh, pfds, ev);
1191
		} else
1192
			ns = 0;
1193
		if (dev_mh)
1194
			nm = mio_pollfd(dev_mh, pfds + ns, POLLIN);
1195
		else
1196
			nm = 0;
1197
		if (poll(pfds, ns + nm, -1) < 0) {
1198
			if (errno == EINTR)
1199
				continue;
1200
			log_puts("poll failed\n");
1201
			panic();
1202
		}
1203
		if (dev_pstate == DEV_START) {
1204
			ev = sio_revents(dev_sh, pfds);
1205
			if (ev & POLLHUP) {
1206
				log_puts(dev);
1207
				log_puts(": audio device gone, stopping\n");
1208
				break;
1209
			}
1210
			if (ev & (POLLIN | POLLOUT)) {
1211
				if (!playrec_cycle() && dev_mh == NULL)
1212
					break;
1213
			}
1214
		}
1215
		if (dev_mh) {
1216
			ev = mio_revents(dev_mh, pfds + ns);
1217
			if (ev & POLLHUP) {
1218
				log_puts(dev_port);
1219
				log_puts(": midi port gone, stopping\n");
1220
				break;
1221
			}
1222
			if (ev & POLLIN) {
1223
				n = mio_read(dev_mh, mbuf, MIDIBUFSZ);
1224
				midi_in(mbuf, n);
1225
			}
1226
		}
1227
	}
1228
	sigfillset(&sa.sa_mask);
1229
	sa.sa_flags = SA_RESTART;
1230
	sa.sa_handler = SIG_DFL;
1231
	sigaction(SIGINT, &sa, NULL);
1232
	sigaction(SIGTERM, &sa, NULL);
1233
	sigaction(SIGHUP, &sa, NULL);
1234
1235
	if (dev_pstate == DEV_START)
1236
		dev_mmcstop();
1237
	xfree(pfds);
1238
	dev_close();
1239
	while (slot_list)
1240
		slot_del(slot_list);
1241
	return 1;
1242
}
1243
1244
static int
1245
opt_onoff(char *s, int *flag)
1246
{
1247
	if (strcmp("off", s) == 0) {
1248
		*flag = 0;
1249
		return 1;
1250
	}
1251
	if (strcmp("on", s) == 0) {
1252
		*flag = 1;
1253
		return 1;
1254
	}
1255
	log_puts(s);
1256
	log_puts(": on/off expected\n");
1257
	return 0;
1258
}
1259
1260
static int
1261
opt_enc(char *s, struct aparams *par)
1262
{
1263
	int len;
1264
1265
	len = aparams_strtoenc(par, s);
1266
	if (len == 0 || s[len] != '\0') {
1267
		log_puts(s);
1268
		log_puts(": bad encoding\n");
1269
		return 0;
1270
	}
1271
	return 1;
1272
}
1273
1274
static int
1275
opt_hdr(char *s, int *hdr)
1276
{
1277
	if (strcmp("auto", s) == 0) {
1278
		*hdr = AFILE_HDR_AUTO;
1279
		return 1;
1280
	}
1281
	if (strcmp("raw", s) == 0) {
1282
		*hdr = AFILE_HDR_RAW;
1283
		return 1;
1284
	}
1285
	if (strcmp("wav", s) == 0) {
1286
		*hdr = AFILE_HDR_WAV;
1287
		return 1;
1288
	}
1289
	if (strcmp("aiff", s) == 0) {
1290
		*hdr = AFILE_HDR_AIFF;
1291
		return 1;
1292
	}
1293
	if (strcmp("au", s) == 0) {
1294
		*hdr = AFILE_HDR_AU;
1295
		return 1;
1296
	}
1297
	log_puts(s);
1298
	log_puts(": bad header type\n");
1299
	return 0;
1300
}
1301
1302
static int
1303
opt_ch(char *s, int *rcmin, int *rcmax)
1304
{
1305
	char *next, *end;
1306
	long cmin, cmax;
1307
1308
	errno = 0;
1309
	cmin = strtol(s, &next, 10);
1310
	if (next == s || *next != ':')
1311
		goto failed;
1312
	cmax = strtol(++next, &end, 10);
1313
	if (end == next || *end != '\0')
1314
		goto failed;
1315
	if (cmin < 0 || cmax < cmin || cmax >= NCHAN_MAX)
1316
		goto failed;
1317
	*rcmin = cmin;
1318
	*rcmax = cmax;
1319
	return 1;
1320
failed:
1321
	log_puts(s);
1322
	log_puts(": channel range expected\n");
1323
	return 0;
1324
}
1325
1326
static int
1327
opt_num(char *s, int min, int max, int *num)
1328
{
1329
	const char *errstr;
1330
1331
	*num = strtonum(s, min, max, &errstr);
1332
	if (errstr) {
1333
		log_puts(s);
1334
		log_puts(": expected integer between ");
1335
		log_puti(min);
1336
		log_puts(" and ");
1337
		log_puti(max);
1338
		log_puts("\n");
1339
		return 0;
1340
	}
1341
	return 1;
1342
}
1343
1344
static int
1345
opt_pos(char *s, long long *pos)
1346
{
1347
	const char *errstr;
1348
1349
	*pos = strtonum(s, 0, LLONG_MAX, &errstr);
1350
	if (errstr) {
1351
		log_puts(s);
1352
		log_puts(": positive number of samples expected\n");
1353
		return 0;
1354
	}
1355
	return 1;
1356
}
1357
1358
int
1359
main(int argc, char **argv)
1360
{
1361
	int dup, cmin, cmax, rate, vol, bufsz, hdr, mode;
1362
	char *port, *dev;
1363
	struct aparams par;
1364
	int n_flag, c;
1365
	long long pos;
1366
1367
	vol = 127;
1368
	dup = 0;
1369
	bufsz = 0;
1370
	rate = DEFAULT_RATE;
1371
	cmin = 0;
1372
	cmax = 1;
1373
	aparams_init(&par);
1374
	hdr = AFILE_HDR_AUTO;
1375
	n_flag = 0;
1376
	port = NULL;
1377
	dev = NULL;
1378
	mode = 0;
1379
	pos = 0;
1380
1381
	while ((c = getopt(argc, argv,
1382
		"b:c:de:f:g:h:i:j:no:p:q:r:t:v:")) != -1) {
1383
		switch (c) {
1384
		case 'b':
1385
			if (!opt_num(optarg, 1, RATE_MAX, &bufsz))
1386
				return 1;
1387
			break;
1388
		case 'c':
1389
			if (!opt_ch(optarg, &cmin, &cmax))
1390
				return 1;
1391
			break;
1392
		case 'd':
1393
			log_level++;
1394
			break;
1395
		case 'e':
1396
			if (!opt_enc(optarg, &par))
1397
				return 1;
1398
			break;
1399
		case 'f':
1400
			dev = optarg;
1401
			break;
1402
		case 'g':
1403
			if (!opt_pos(optarg, &dev_pos))
1404
				return 1;
1405
			break;
1406
		case 'h':
1407
			if (!opt_hdr(optarg, &hdr))
1408
				return 1;
1409
			break;
1410
		case 'i':
1411
			if (!slot_new(optarg, SIO_PLAY,
1412
				&par, hdr, cmin, cmax, rate, dup, vol, pos))
1413
				return 1;
1414
			mode |= SIO_PLAY;
1415
			break;
1416
		case 'j':
1417
			if (!opt_onoff(optarg, &dup))
1418
				return 1;
1419
			break;
1420
		case 'n':
1421
			n_flag = 1;
1422
			break;
1423
		case 'o':
1424
			if (!slot_new(optarg, SIO_REC,
1425
				&par, hdr, cmin, cmax, rate, dup, 0, pos))
1426
				return 1;
1427
			mode |= SIO_REC;
1428
			break;
1429
		case 'p':
1430
			if (!opt_pos(optarg, &pos))
1431
				return 1;
1432
			break;
1433
		case 'q':
1434
			port = optarg;
1435
			break;
1436
		case 'r':
1437
			if (!opt_num(optarg, RATE_MIN, RATE_MAX, &rate))
1438
				return 1;
1439
			break;
1440
		case 'v':
1441
			if (!opt_num(optarg, 0, MIDI_MAXCTL, &vol))
1442
				return 1;
1443
			break;
1444
		default:
1445
			goto bad_usage;
1446
		}
1447
	}
1448
	argc -= optind;
1449
	argv += optind;
1450
	if (argc != 0) {
1451
	bad_usage:
1452
		log_puts(usagestr);
1453
		return 1;
1454
	}
1455
	if (n_flag) {
1456
		if (dev != NULL || port != NULL) {
1457
			log_puts("-f and -q make no sense in off-line mode\n");
1458
			return 1;
1459
		}
1460
		if (mode != (SIO_PLAY | SIO_REC)) {
1461
			log_puts("both -i and -o required\n");
1462
			return 1;
1463
		}
1464
		if (!offline())
1465
			return 1;
1466
	} else {
1467
		if (dev == NULL)
1468
			dev = SIO_DEVANY;
1469
		if (mode == 0) {
1470
			log_puts("at least -i or -o required\n");
1471
			return 1;
1472
		}
1473
		if (!playrec(dev, mode, bufsz, port))
1474
			return 1;
1475
	}
1476
	return 0;
1477
}