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