Fri Nov 25 01:39:48 2011 UTC ()
- accept "midi0" as an alias for "0" to the -d flag
- verify that the requested unit exists before playing
- if the verbose flag is set, print the selected device name and unit #


(jmcneill)
diff -r1.28 -r1.29 src/usr.bin/midiplay/midiplay.c

cvs diff -r1.28 -r1.29 src/usr.bin/midiplay/midiplay.c (expand / switch to unified diff)

--- src/usr.bin/midiplay/midiplay.c 2011/08/14 13:26:23 1.28
+++ src/usr.bin/midiplay/midiplay.c 2011/11/25 01:39:47 1.29
@@ -1,14 +1,14 @@ @@ -1,14 +1,14 @@
1/* $NetBSD: midiplay.c,v 1.28 2011/08/14 13:26:23 christos Exp $ */ 1/* $NetBSD: midiplay.c,v 1.29 2011/11/25 01:39:47 jmcneill Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc. 4 * Copyright (c) 1998, 2002 The NetBSD Foundation, Inc.
5 * All rights reserved. 5 * All rights reserved.
6 * 6 *
7 * This code is derived from software contributed to The NetBSD Foundation 7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Lennart Augustsson (augustss@NetBSD.org). 8 * by Lennart Augustsson (augustss@NetBSD.org).
9 * 9 *
10 * Redistribution and use in source and binary forms, with or without 10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions 11 * modification, are permitted provided that the following conditions
12 * are met: 12 * are met:
13 * 1. Redistributions of source code must retain the above copyright 13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer. 14 * notice, this list of conditions and the following disclaimer.
@@ -21,34 +21,36 @@ @@ -21,34 +21,36 @@
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR 21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS 22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR 23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF 24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS 25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN 26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) 27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE 28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE. 29 * POSSIBILITY OF SUCH DAMAGE.
30 */ 30 */
31#include <sys/cdefs.h> 31#include <sys/cdefs.h>
32 32
33#ifndef lint 33#ifndef lint
34__RCSID("$NetBSD: midiplay.c,v 1.28 2011/08/14 13:26:23 christos Exp $"); 34__RCSID("$NetBSD: midiplay.c,v 1.29 2011/11/25 01:39:47 jmcneill Exp $");
35#endif 35#endif
36 36
37 37
38#include <stdio.h> 38#include <stdio.h>
39#include <stdlib.h> 39#include <stdlib.h>
40#include <fcntl.h> 40#include <fcntl.h>
41#include <err.h> 41#include <err.h>
 42#include <errno.h>
 43#include <limits.h>
42#include <unistd.h> 44#include <unistd.h>
43#include <string.h> 45#include <string.h>
44#include <sys/types.h> 46#include <sys/types.h>
45#include <sys/stat.h> 47#include <sys/stat.h>
46#include <sys/ioctl.h> 48#include <sys/ioctl.h>
47#include <sys/midiio.h> 49#include <sys/midiio.h>
48 50
49#define DEVMUSIC "/dev/music" 51#define DEVMUSIC "/dev/music"
50 52
51struct track { 53struct track {
52 struct track *indirect; /* for fast swaps in heap code */ 54 struct track *indirect; /* for fast swaps in heap code */
53 u_char *start, *end; 55 u_char *start, *end;
54 u_long delta; 56 u_long delta;
@@ -386,32 +388,39 @@ playfile(FILE *f, const char *name) @@ -386,32 +388,39 @@ playfile(FILE *f, const char *name)
386 buf = nbuf; 388 buf = nbuf;
387 size *= 2; 389 size *= 2;
388 } 390 }
389 playdata(buf, tot, name); 391 playdata(buf, tot, name);
390 free(buf); 392 free(buf);
391} 393}
392 394
393static void 395static void
394playdata(u_char *buf, u_int tot, const char *name) 396playdata(u_char *buf, u_int tot, const char *name)
395{ 397{
396 int format, ntrks, divfmt, ticks, t; 398 int format, ntrks, divfmt, ticks, t;
397 u_int len, mlen, status, chan; 399 u_int len, mlen, status, chan;
398 u_char *p, *end, byte, meta, *msg; 400 u_char *p, *end, byte, meta, *msg;
 401 struct synth_info info;
399 struct track *tracks; 402 struct track *tracks;
400 struct track *tp; 403 struct track *tp;
401 404
 405 /* verify that the requested midi unit exists */
 406 info.device = unit;
 407 if (ioctl(fd, SEQUENCER_INFO, &info) < 0)
 408 err(1, "ioctl(SEQUENCER_INFO) failed");
 409
402 end = buf + tot; 410 end = buf + tot;
403 if (verbose) 411 if (verbose)
404 printf("Playing %s (%d bytes) ... \n", name, tot); 412 printf("Playing %s (%d bytes) on %s (unit %d)... \n",
 413 name, tot, info.name, info.device);
405 414
406 if (tot < MARK_LEN + 4) { 415 if (tot < MARK_LEN + 4) {
407 warnx("Not a MIDI file, too short"); 416 warnx("Not a MIDI file, too short");
408 return; 417 return;
409 } 418 }
410 419
411 if (memcmp(buf, RMID_SIG, MARK_LEN) == 0) { 420 if (memcmp(buf, RMID_SIG, MARK_LEN) == 0) {
412 u_char *eod; 421 u_char *eod;
413 /* Detected a RMID file, let's just check if it's 422 /* Detected a RMID file, let's just check if it's
414 * a MIDI file */ 423 * a MIDI file */
415 if ((u_int)GET32_LE(buf + MARK_LEN) != tot - 8) { 424 if ((u_int)GET32_LE(buf + MARK_LEN) != tot - 8) {
416 warnx("Not a RMID file, bad header"); 425 warnx("Not a RMID file, bad header");
417 return; 426 return;
@@ -669,45 +678,65 @@ playdata(u_char *buf, u_int tot, const c @@ -669,45 +678,65 @@ playdata(u_char *buf, u_int tot, const c
669 if (0 == ntrks) 678 if (0 == ntrks)
670 break; 679 break;
671 } else 680 } else
672 tp->delta = getvar(tp); 681 tp->delta = getvar(tp);
673 Heapify(tracks, ntrks, 0); 682 Heapify(tracks, ntrks, 0);
674 } 683 }
675 if (ioctl(fd, SEQUENCER_SYNC, 0) < 0) 684 if (ioctl(fd, SEQUENCER_SYNC, 0) < 0)
676 err(1, "SEQUENCER_SYNC"); 685 err(1, "SEQUENCER_SYNC");
677 686
678 ret: 687 ret:
679 free(tracks); 688 free(tracks);
680} 689}
681 690
 691static int
 692parse_unit(const char *sunit)
 693{
 694 const char *osunit = sunit;
 695 long n;
 696 char *ep;
 697
 698 if (strncmp(sunit, "midi", strlen("midi")) == 0)
 699 sunit += strlen("midi");
 700
 701 errno = 0;
 702 n = strtol(sunit, &ep, 10);
 703 if (n < 0 || n > INT_MAX || *ep != '\0' ||
 704 (errno == ERANGE &&
 705 (n == LONG_MAX || n == LONG_MIN)))
 706 errx(1, "bad midi unit -- %s", osunit);
 707
 708 return (int)n;
 709}
 710
682int 711int
683main(int argc, char **argv) 712main(int argc, char **argv)
684{ 713{
685 int ch; 714 int ch;
686 int listdevs = 0; 715 int listdevs = 0;
687 int example = 0; 716 int example = 0;
688 int nmidi; 717 int nmidi;
689 const char *file = DEVMUSIC; 718 const char *file = DEVMUSIC;
690 const char *sunit; 719 const char *sunit;
691 struct synth_info info; 720 struct synth_info info;
692 FILE *f; 721 FILE *f;
693 722
694 if ((sunit = getenv("MIDIUNIT"))) 723 if ((sunit = getenv("MIDIUNIT")))
695 unit = atoi(sunit); 724 unit = parse_unit(sunit);
696 725
697 while ((ch = getopt(argc, argv, "?d:f:lmp:qt:vx")) != -1) { 726 while ((ch = getopt(argc, argv, "?d:f:lmp:qt:vx")) != -1) {
698 switch(ch) { 727 switch(ch) {
699 case 'd': 728 case 'd':
700 unit = atoi(optarg); 729 unit = parse_unit(optarg);
701 break; 730 break;
702 case 'f': 731 case 'f':
703 file = optarg; 732 file = optarg;
704 break; 733 break;
705 case 'l': 734 case 'l':
706 listdevs++; 735 listdevs++;
707 break; 736 break;
708 case 'm': 737 case 'm':
709 showmeta++; 738 showmeta++;
710 break; 739 break;
711 case 'p': 740 case 'p':
712 sameprogram = atoi(optarg); 741 sameprogram = atoi(optarg);
713 break; 742 break;