/* file rdann.c T. Baker and G. Moody 27 July 1981 Last revised: 30 September 1993 Print an annotation file in ASCII form Copyright (C) Massachusetts Institute of Technology 1993. All rights reserved. Caution: If the output format of 'rdann' is modified, 'wrann' will require modification as well! */ #include #ifndef __STDC__ extern void exit(); #endif #include #define map1 #define map2 #define ammap #define mamap #define annpos #include /* Define the default DB path for CD-ROM versions of this program (the MS-DOS executables found in the `bin' directories of the various CD-ROMs). This program has been revised since the appearance of these CD-ROMs; compiling this file will not produce executables identical to those on the CD-ROMs. Note that the drive letter is not included in these DB path definitions, since it varies among systems. */ #ifdef MITCDROM #define DBP ";\\mitdb;\\nstdb;\\stdb;\\vfdb;\\afdb;\\cdb;\\svdb;\\ltdb;\\cudb" #endif #ifdef STTCDROM #define DBP ";\\edb;\\valedb" #endif #ifdef SLPCDROM #define DBP ";\\slpdb" #endif #ifdef MGHCDROM #define DBP ";\\mghdb" #endif char *pname; main(argc, argv) int argc; char *argv[]; { char *record = NULL, *prog_name(); double sps, spm; int i, j, xflag = 0; long beat_number = 0L, from = 0L, to = 0L, atol(); static char flag[ACMAX+1]; static struct DB_anninfo ai; struct DB_ann annot; void help(); #ifdef DBP char *dbp = getdb(); if (*dbp == '\0') setdb(DBP); #endif pname = prog_name(argv[0]); /* Accept old syntax. */ if (argc >= 3 && argv[1][0] != '-') { ai.name = argv[1]; record = argv[2]; i = 3; if (argc > 3) { from = 3; i = 4; } if (argc > 4) { to = 4; i = 5; } if (argc <= 5) flag[0] = 1; else while (i < argc && argv[i][0] != '-') { if (isann(j = strann(argv[i]))) flag[j] = 1; i++; } } else i = flag[0] = 1; /* Interpret command-line options. */ for ( ; i < argc; i++) { if (*argv[i] == '-') switch (*(argv[i]+1)) { case 'a': /* annotator follows */ if (++i >= argc) { (void)fprintf(stderr, "%s: annotator must follow -a\n", pname); exit(1); } ai.name = argv[i]; break; case 'f': /* starting time follows */ if (++i >= argc) { (void)fprintf(stderr, "%s: starting time must follow -f\n", pname); exit(1); } from = i; /* to be converted to sample intervals below */ break; case 'h': /* print usage summary and quit */ help(); exit(0); break; case 'p': /* annotation mnemonic(s) follow */ if (++i >= argc || !isann(j = strann(argv[i]))) { (void)fprintf(stderr, "%s: annotation mnemonic(s) must follow -p\n", pname); exit(1); } flag[j] = 1; /* The code above not only checks that there is a mnemonic where there should be one, but also allows for the possibility that there might be a (user-defined) mnemonic beginning with `-'. The following lines pick up any other mnemonics, but assume that arguments beginning with `-' are options, not mnemonics. */ while (++i < argc && argv[i][0] != '-') if (isann(j = strann(argv[i]))) flag[j] = 1; if (i == argc || argv[i][0] == '-') i--; flag[0] = 0; break; case 'r': /* input record name follows */ if (++i >= argc) { (void)fprintf(stderr, "%s: input record name must follow -r\n", pname); exit(1); } record = argv[i]; break; case 't': /* ending time follows */ if (++i >= argc) { (void)fprintf(stderr, "%s: end time must follow -t\n", pname); exit(1); } to = i; break; case 'x': /* use alternate time format */ xflag = 1; break; default: (void)fprintf(stderr, "%s: unrecognized option %s\n", pname, argv[i]); exit(1); } else { (void)fprintf(stderr, "%s: unrecognized argument %s\n", pname, argv[i]); exit(1); } } if (record == NULL || ai.name == NULL) { help(); exit(1); } if ((sps = sampfreq(record)) < 0.) (void)setsampfreq(sps = DEFFREQ); spm = 60.0*sps; ai.stat = READ; if (annopen(record, &ai, 1) < 0) /* open annotation file */ exit(2); if (from) { if (*argv[(int)from] == '#') { if ((beat_number = atol(argv[(int)from]+1)) < 0L) beat_number = 0L; while (beat_number > 0L && getann(0, &annot) == 0) if (isqrs(annot.anntyp)) beat_number--; if (beat_number > 0L) exit(2); } else if (iannsettime(strtim(argv[(int)from])) < 0) exit(2); } if (to) { if (*argv[(int)to] == '#') { if ((beat_number = atol(argv[(int)to]+1)) < 1L) beat_number = 1L; to = 0L; } else { beat_number = -1L; to = strtim(argv[(int)to]); } } while (getann(0, &annot) == 0 && (to == 0L || annot.time <= to)) { if (flag[0] || (isann(annot.anntyp) && flag[annot.anntyp])) { if (!xflag) (void)printf("%s %7ld", mstimstr(-annot.time), annot.time); else (void)printf("%.3lf %.5lf", annot.time/sps, annot.time/spm); (void)printf("%6s%5d%5d%5d", annstr(annot.anntyp), annot.subtyp, annot.chan, annot.num); if (annot.aux != NULL) (void)printf("\t%s", annot.aux + 1); (void)printf("\n"); } if (beat_number > 0L && isqrs(annot.anntyp) && --beat_number == 0L) break; } exit(0); /*NOTREACHED*/ } char *prog_name(s) char *s; { char *p = s + strlen(s); #ifdef MSDOS while (p >= s && *p != '\\' && *p != ':') { if (*p == '.') *p = '\0'; /* strip off extension */ if ('A' <= *p && *p <= 'Z') *p += 'a' - 'A'; /* convert to lower case */ p--; } #else while (p >= s && *p != '/') p--; #endif return (p+1); } static char *help_strings[] = { "usage: %s -r RECORD -a ANNOTATOR [OPTIONS ...]\n", "where RECORD and ANNOTATOR specify the input, and OPTIONS may include:", " -f TIME start at specified TIME", " -h print this usage summary", " -p TYPE [TYPE ...] print annotations of specified TYPEs only", " -t TIME stop at specified TIME", " -x use alternate time format (seconds, minutes)", NULL }; void help() { int i; (void)fprintf(stderr, help_strings[0], pname); for (i = 1; help_strings[i] != NULL; i++) (void)fprintf(stderr, "%s\n", help_strings[i]); }