/* ** JUST -- Justify (clean-up) rhythm ** psl 12/85, threshold added 12/88 */ #include #include #include #define MAXCHAN MIDI_MAX_CHANS #define MAXKEY 128 int Dflg = 1; /* what to do with durations */ int Dt[MAXCHAN][MAXKEY]; /* offsets used for starts of notes */ long Quant = (MPU_CLOCK_PERIOD / 24);/* clocks in justification quantum */ int Thresh = 1; /* ignore time-tags <= this */ syntax(prog) char *prog; { fprintf(stderr, "Usage: %s [-d] [-q#] [files or stdin]\n", prog); fprintf(stderr, "-d\tPreserve original durations exactly.\n"); fprintf(stderr, "-i\tJustify key-offs independently of key-ons.\n"); fprintf(stderr, "-q#\tQuantify to # beats per bar.\n"); fprintf(stderr, "-t#\tIgnore time differences < # (threshold).\n"); exit(2); } main(argc, argv) char *argv[]; { int i, n; FILE *f; for (i = 1; i < argc; i++) { if (argv[i][0] == '-') { switch (argv[i][1]) { case 'd': Dflg = 2; break; case 'i': Dflg = 0; break; case 'q': Quant = 1; if (Quant = atoi(&argv[i][2])) Quant = (2 * MPU_CLOCK_PERIOD) / Quant; break; case 't': Thresh = atoi(&argv[i][2]); break; default: syntax(argv[0]); } } } n = 0; for (i = 1; i < argc; i++) { if (argv[i][0] != '-') { if ((f = sopen(argv[i], "r")) != NULL) { just(f, stdout); sclose(f); n++; } else perror(argv[i]); } } if (n == 0) just(stdin, stdout); } just(ifp, ofp) FILE *ifp, *ofp; { int status, type, chan, key, vel; long inow, onow, anow, last; MCMD *mp; for (inow = last = 0; mp = getmcmd(ifp, inow); putmcmd(ofp, mp)) { anow = (mp->when - inow) <= Thresh? last : mp->when; inow = mp->when; status = mp->cmd[0]; type = (status & M_CMD_MASK); onow = -1; if (type == CH_KEY_OFF) { type = CH_KEY_ON; mp->cmd[2] = 0; } if (type == CH_KEY_ON) { /* calc chan, key, & vel */ chan = (status & M_CHAN_MASK); key = mp->cmd[1]; vel = mp->cmd[2]; if (!vel && Dflg == 2) /* preserve exact duration */ onow = inow + Dt[chan][key]; if (!vel && Dflg == 1) /* preserve approx. duration */ anow += Dt[chan][key]; } if (onow == -1) { /* justify */ onow = anow + Quant / 2; onow -= (onow % Quant); } onow = onow < last? last : onow; /* just in case */ if (Dflg && type == CH_KEY_ON && vel) Dt[chan][key] = onow - anow; /* remember change to input */ last = mp->when = onow; } Rt_tcwme.when = anow > last? anow : last; putmcmd(ofp, &Rt_tcwme); }