/* ** MPUCLEAN -- Clean up mpu data files: ** 1) remove multiple mode commands ** 2) remove multiple note-ons (unless -m used) ** 3) remove unneeded note-offs ** 4) remove pressure change info (unless -p used) ** 5) remove Timing Clock In Stop messages (unless -tcis used) ** 6) insert TCWME commands every specified number of clocks (if -b used) ** 7) remove multiple TCWME commands (unless -tcwme used) ** 8) generate note-off commands for any notes left on ** & assure that a TCWME code is the last datum ** psl 9/85 */ #include #include #define MAXCHAN 16 #define DEFBARLEN 2*MPU_CLOCK_PERIOD int key[MAXCHAN][128]; main(argc, argv) char *argv[]; { register int i, k, v, dt, curmode, lastmode; int chan, Mflg, mflg, pflg, tcisflg, tcwmeflg, barlen, status; long now, lasttcwme, nexttcwme; Mflg = mflg = pflg = tcisflg = tcwmeflg = barlen = 0; while (--argc > 0) { if (argv[argc][0] == '-') { switch (argv[argc][1]) { case 'L': barlen = atoi(&argv[argc][2]); if (barlen == 0) barlen = DEFBARLEN; break; case 'M': Mflg++; break; case 'm': mflg++; break; case 'p': pflg++; break; case 't': if (argv[argc][2] != 'c') goto syntax; if (argv[argc][3] == 'i') tcisflg++; else if (argv[argc][3] == 'w') tcwmeflg++; else goto syntax; break; default: goto syntax; } } else { syntax: fprintf(stderr, "Usage: %s [options] new\n", argv[0]); fprintf(stderr, "options are:\n"); fprintf(stderr, "-L# put TCWMEs in every # clocks.\n"); fprintf(stderr, "-multiple allow duplicated notes.\n"); fprintf(stderr, "-Multiple make duplicated notes 'short'.\n"); fprintf(stderr, "-pressure allow after-touch.\n"); fprintf(stderr, "-tcis allow RT_TCIS.\n"); fprintf(stderr, "-tcwme allow multiple RT_TCWMEs.\n"); exit(2); } } curmode = lastmode = 0; lasttcwme = -1; dt = 0; now = 0; nexttcwme = barlen; while ((i = getc(stdin)) != EOF) { if (i == RT_TCIP || i == RT_TCIS) { dt += MPU_CLOCK_PERIOD; now += MPU_CLOCK_PERIOD; if (barlen && now >= nexttcwme) { i = now - nexttcwme; putdt(dt - i); putc(RT_TCWME, stdout); dt = i; lasttcwme = nexttcwme; nexttcwme += barlen; } else if (i == RT_TCIS && tcisflg) { putc(i, stdout); dt -= MPU_CLOCK_PERIOD; } continue; } dt += i; now += i; if (barlen && now >= nexttcwme) { i = now - nexttcwme; putdt(dt - i); putc(RT_TCWME, stdout); dt = i; lasttcwme = nexttcwme; nexttcwme += barlen; } if ((k = getc(stdin)) == EOF) { fprintf(stderr, "EOF after 0x%x (dt=%d)\n", i, dt); exit(1); } if (k & M_CMD) { if ((k & M_CMD_MASK) == 0xF0) { /* those F# weirdos */ if (k < 0xF8) { /* sys excl or sys common */ dt = putdt(dt); putc(k, stdout); if (k == SX_CMD) { /* sys excl */ do { k = getc(stdin); putc(k, stdout); } while (k != SX_EOB); } else if (k == SC_MSEL) { /* song position */ putc(getc(stdin), stdout); putc(getc(stdin), stdout); } else if (k == SC_SSEL) /* song select */ putc(getc(stdin), stdout); } else if (k == RT_TCWME) { if (lasttcwme != now || tcwmeflg) { dt = putdt(dt); putc(k, stdout); } lasttcwme = now; } else { dt = putdt(dt); putc(k, stdout); } continue; } curmode = k; if ((k = getc(stdin)) == EOF) { fprintf(stderr, "EOF after %x (mode)\n", curmode); exit(1); } } status = (curmode & M_CMD_MASK); if (status == CH_POLY_KPRS || status == CH_CTL || status == CH_P_BEND) { dt = putdt(dt); if (curmode != lastmode) putc(lastmode = curmode, stdout); putc(k, stdout); if ((v = getc(stdin)) == EOF) { fprintf(stderr, "EOF after %x (mode)\n", curmode); exit(1); } putc(v, stdout); continue; } else if (status == CH_PRG || status == CH_PRESSURE) { if (status != CH_PRESSURE || pflg) { dt = putdt(dt); if (curmode != lastmode) putc(lastmode = curmode, stdout); putc(k, stdout); } continue; } else if (status == CH_KEY_ON || status == CH_KEY_OFF) { chan = curmode % MAXCHAN; if ((v = getc(stdin)) == EOF) { fprintf(stderr, "unexpected EOF in mode %x\n", curmode); exit(1); } if (status == CH_KEY_OFF) { status = CH_KEY_ON; curmode = (status | chan); v = 0; } if (v == 0) { --key[chan][k]; if (key[chan][k] < 0) { /* extra note-off */ key[chan][k] = 0; continue; } if (!mflg && key[chan][k]) continue; /* not the last note-off */ } else { key[chan][k]++; if (key[chan][k] > 1 && !mflg) { if (Mflg) key[chan][k] = 1; /* defeat nesting */ continue; /* extra note-on */ } } dt = putdt(dt); if (curmode != lastmode) putc(lastmode = curmode, stdout); putc(k, stdout); putc(v, stdout); } else fprintf(stderr, "mode=%x?\n", curmode); } for (chan = MAXCHAN; --chan >= 0; ) { /* clear any stuck notes */ curmode = CH_KEY_ON | chan; for (i = 0; i < 128; i++) { while (--key[chan][i] >= 0) { putc(0, stdout); if (lastmode != curmode) putc(lastmode = curmode, stdout); putc(i, stdout); putc(0, stdout); } } } if (lasttcwme != now) { putc(0, stdout); /* a final command */ putc(RT_TCWME, stdout); } } putdt(dt) { while (dt >= 240) { putc(RT_TCIP, stdout); dt -= 240; } putc(dt, stdout); return(0); }