home *** CD-ROM | disk | FTP | other *** search
- /*
- * Midtomup
- *
- * Convert Midi files to MUP input files
- */
-
- #include <stdio.h>
- #include <ctype.h>
- #include <fcntl.h>
- #include "midifile.h"
- #include "mtm.h"
- #include "version.h"
-
- /* for all forms of DOS we've tried, make sure __DOS__ is defined */
- #if defined(__WATCOMC__)
- #ifndef __DOS__
- #define __DOS__
- #endif
- #endif
-
- /* MIDI file has to be read in binary mode */
- #ifdef __DOS__
- #define MODE O_RDONLY | O_BINARY
- #else
- #define MODE O_RDONLY
- #endif
-
- #define TIE 1
- #define NO_TIE 0
- #define MEASURE -11
-
- static int F;
-
- int SECONDS; /* global that tells whether to display seconds or ticks */
- int division; /* from the file header */
- long tempo = 500000; /* the default tempo is 120 beats/minute */
-
- int FUDGE; /* Take the exact amount, or try to fudge it to a usable */
- /* number of ticks? */
- int FFACTOR;
-
- extern char *optarg;
- extern int optind;
-
- int efopen();
-
-
- /* read and return one character from MIDI file. Return EOF on end of file
- * or read error. */
-
- int
- filegetc()
- {
- unsigned char c;
-
- return (read(F, &c, 1) == 1) ? (c & 0xff) : EOF;
- }
-
- void
- usage(pgmname)
- char *pgmname;
- {
- fprintf(stderr, "usage: %s [-a fudge_factor] [-f inputfile] [-g] [-i cmdfile] [-n] [-v]\n", pgmname);
- fprintf(stderr, "\t-g = turn on fudging\n\t-n = don't add measure number comments\n\t-v = print version number and exit\n");
- exit(1);
- }
-
- main(argc,argv)
- char **argv;
- {
- FILE *fp;
- char ifile[80];
- char buf[80];
- int c;
- int i, j;
- int pmeasure = 1;
-
-
- SECONDS = 0;
- FUDGE = 0;
- for(i = 0; i < 16; i++) {
- track[i].swhre = 0;
- track[i].ewhre = 0;
- }
- twhre = 0;
- bwhre = 0;
- tlwhre = 0;
- F = 0;
- FFACTOR=10;
- ifile[0] = '\0';
-
- while((c = getopt(argc, argv, "f:ga:i:nv")) != EOF)
- switch(c) {
- /**
- case 's': SECONDS = 1;
- break;
- **/
- case 'f': F = efopen(optarg);
- break;
- case 'g': FUDGE = 1;
- break;
- case 'a': FFACTOR = atoi(optarg);
- break;
- case 'i': strcpy(ifile, optarg);
- break;
- case 'n': pmeasure = 0;
- break;
- case 'v': fprintf(stderr, "%s\n", version);
- exit(0);
- break;
- default: printf("%c not understood.\n", c);
- usage(argv[0]);
- break;
- }
-
- initfuncs();
- Mf_getc = filegetc;
- midifile();
- close(F);
- /*
- * Done reading the midi file. Now output the notes.
- */
- /*
- * First read the midtomup init file...
- */
- if(ifile[0] == '\0')
- strcpy(ifile, ".midtomup");
- if((fp = fopen(ifile, "r")) != NULL) {
- while(fgets(buf, 80, fp) != '\0') {
- if(buf[0] != '#' && buf[0] != '/') {
- fprintf(stderr, "Parse error in .midtomup: %s\n", buf);
- break;
- }
- if(buf[0] == '/' && buf[1] == '/') {
- printf("%s", buf);
- continue;
- }
- if(strncmp(buf, "#header", 7) == 0)
- doheader(fp);
- else if(strncmp(buf, "#beamstyle", 10) == 0)
- dobeamstyle(fp);
- else if(strncmp(buf, "#translate", 10) == 0)
- dotranslate(buf);
- else if(strncmp(buf, "#key", 4) == 0)
- dokey(buf);
- else
- fprintf(stderr, "Unknown rc command: %s\n", buf);
- }
- }
- fclose(fp);
-
- /* Init some vars */
- for(i = 0; i < 16; i++) {
- tr[i] = 0;
- }
- measure = 1;
- ticks = 0;
- twhre = 0;
- mwhre = 0;
- h_ticks = 0;
- triplet = 0;
- /* If no time sig specified, set to 4/4 */
- if(tsig[0].num < 1)
- tsig[0].num = 4;
- if(tsig[0].dnom < 1)
- tsig[0].dnom = 4;
- /* Main loop to output notes */
- do {
- if(tsig[twhre].when == h_ticks) {
- printf("score\n");
- printf("\ttime=%d/%d\n", tsig[twhre].num, tsig[twhre].dnom);
- for(i = 0; i < 50; i++) {
- if(bstyles[i].bnum == tsig[twhre].num && bstyles[i].bdnom == tsig[twhre].dnom) {
- printf("\tbeamstyle=%s\n", bstyles[i].style);
- break;
- }
- }
- printf("music\n");
- twhre++;
- }
- if(midikey[mwhre].when == h_ticks) {
- printf("score\n");
- for(i = 0; i <= numtracks; i++) {
- if(track[i].swhre < 1)
- continue;
- /*
- * Print the staff number, remembering translations..
- */
- for(j = 0; j < tlwhre; j++) {
- if(i + 1 == tlate[j].in) {
- printf("staff %d\n", tlate[j].out);
- break;
- }
- }
- if(j == tlwhre)
- printf("staff %d\n", i + 1);
- j = midikey[mwhre].nkey + hkey[i + 1];
- if(j <= 0)
- printf("\tkey=%d&\n", abs(midikey[mwhre].nkey + hkey[i + 1]));
- else
- printf("\tkey=%d#\n", midikey[mwhre].nkey + hkey[i + 1]);
- printf("// New key for track %d = %d\n", i + 1, midikey[mwhre].nkey + hkey[i + 1]);
- key[i + 1] = midikey[mwhre].nkey + hkey[i + 1];
- }
- printf("music\n");
- mwhre++;
- }
- if(pmeasure)
- printf("// Measure %d\n", measure);
- measure++;
- /*
- * Sorry, only quarters and eighths and halfs can be in the denominator
- */
- if(tsig[twhre - 1].dnom == 4)
- endticks = h_ticks + (division * tsig[twhre - 1].num);
- else if(tsig[twhre - 1].dnom == 8)
- endticks = h_ticks + (division/2 * tsig[twhre - 1].num);
- else
- endticks = h_ticks + (division * 2 * tsig[twhre - 1].num);
- /* Remember, we only deal with one note at a time on a track. */
- /*
- * We will deal with one measure at a time, one track at a time.
- */
- for(i = 0; i <= numtracks; i++) {
- for(j = 0; j < 32; j++) {
- accnotes[j] = -1;
- sccnotes[j][0] = -1;
- sccnotes[j][1] = -1;
- sccnotes[j][2] = -1;
- }
- accwhre = -1;
- sccwhre = -1;
- ticks = h_ticks;
- /*
- * If tr[i] < 1, then we have, at most one note in the track.
- * We're ignoring it.
- */
- if(track[i].swhre < 1)
- continue;
- /*
- * Do the requested track translations.
- *
- * Did the user request a translation for this track?
- */
- for(j = 0; j < tlwhre; j++) {
- if(i + 1 == tlate[j].in) {
- printf("\n%d:", tlate[j].out);
- break;
- }
- }
- /*
- * If j == tlwhre, then we didn't find a translation for the
- * track.
- */
- if(j == tlwhre)
- printf("\n%d:", i + 1);
- /* Is there a note in the measure? */
- if(track[i].start[tr[i]] >= ticks && track[i].start[tr[i]] < endticks) {
- do {
- /* have we reached the end of this track? */
- if(tr[i] > track[i].swhre)
- continue;
- /* No, does a note start on current tick? */
- if(track[i].start[tr[i]] != ticks) {
- /* Nope, so output a rest */
- if(tr[i] >= track[i].swhre) {
- dorest(i, endticks - ticks);
- ticks = endticks;
- break;
- } else {
- dorest(i, track[i].start[tr[i]] - ticks);
- ticks = track[i].start[tr[i]];
- }
- } else {
- /* Note is tied to a note not in this measure */
- if(track[i].end[tr[i]] > endticks) {
- #ifdef __STDC
- donote(i, track[i].note[tr[i]], (short) (endticks - track[i].start[tr[i]]), TIE);
- #else
- donote(i, track[i].note[tr[i]], endticks - track[i].start[tr[i]], TIE);
- #endif
- track[i].start[tr[i]] = endticks;
- ticks = endticks;
- /* note is completely contained in this measure. */
- } else {
- j = track[i].end[tr[i]]-track[i].start[tr[i]];
- /* HERE */
- /* printf("j = %d, division = %d\n", j, division); */
- if(FUDGE) {
- j = fudge(j);
- /*
- if(j == 29 || j == 59 || j == 89 || j == 119 || j == 179 || j == 209 || j == 239 || j == 359 || j == 479)
- j++;
- */
- }
- /*
- donote(i, track[i].note[tr[i]], track[i].end[tr[i]]-track[i].start[tr[i]], NO_TIE);
- ticks += track[i].end[tr[i]] - track[i].start[tr[i]];
- */
- donote(i, track[i].note[tr[i]], j, NO_TIE);
- ticks += j;
- tr[i]++;
- }
- }
- /* Next note in track */
- } while(ticks < endticks && track[i].start[tr[i]] < endticks);
- if(ticks < endticks) {
- dorest(i, endticks - ticks);
- ticks = endticks;
- }
- } else {
- dorest(i, MEASURE);
- }
- }
- dobar();
- h_ticks = endticks;
- } while(h_ticks < lasttick);
- exit(0);
- }
-
- int
- efopen(name)
- char *name;
- {
- int f;
- extern int errno;
- extern char *sys_errlist[];
- extern int sys_nerr;
- char *errmess;
-
- if ( (f=open(name,MODE,0)) == NULL ) {
- (void) fprintf(stderr,"Cannot open '%s'!\n",name);
- if ( errno <= sys_nerr )
- errmess = sys_errlist[errno];
- else
- errmess = "Unknown error!";
- (void) fprintf(stderr,"Reason: %s\n",errmess);
- exit(1);
- }
- return(f);
- }
-
- error(s)
- char *s;
- {
- fprintf(stderr,"Error: %s\n",s);
- }
-
- txt_header(format,ntrks,ldivision)
- {
- division = ldivision;
- /*
- printf("Header format=%d ntrks=%d division=%d\n",format,ntrks,division);
- */
- }
-
- txt_trackstart()
- {
- /*
- printf("Track start\n");
- */
- }
-
- txt_trackend()
- {
- /*
- printf("Track end\n");
- */
- }
-
- txt_noteon(chan,pitch,vol)
- {
- /*
- prtime();
- printf("Note on, chan=%d pitch=%d vol=%d\n",chan+1,pitch,vol);
- */
- if(vol == 0) {
- track[chan].end[track[chan].ewhre]=Mf_currtime;
- track[chan].ewhre++;
- if(lasttick < Mf_currtime)
- lasttick = Mf_currtime;
- } else {
- if(chan > numtracks)
- numtracks = chan;
- track[chan].start[track[chan].swhre]=Mf_currtime;
- track[chan].note[track[chan].swhre]=pitch;
- track[chan].swhre++;
- }
- }
-
- txt_noteoff(chan,pitch,vol)
- {
- /*
- prtime();
- */
- track[chan].end[track[chan].ewhre]=Mf_currtime;
- track[chan].ewhre++;
- if(lasttick < Mf_currtime)
- lasttick = Mf_currtime;
- }
-
- txt_pressure(chan,pitch,press)
- {
- /*
- prtime();
- printf("Pressure, chan=%d pitch=%d press=%d\n",chan+1,pitch,press);
- */
- }
-
- txt_parameter(chan,control,value)
- {
- /*
- prtime();
- printf("Parameter, chan=%d c1=%d c2=%d\n",chan+1,control,value);
- */
- }
-
- txt_pitchbend(chan,msb,lsb)
- {
- /*
- prtime();
- printf("Pitchbend, chan=%d msb=%d lsb=%d\n",chan+1,msb,lsb);
- */
- }
-
- txt_program(chan,program)
- {
- /*
- prtime();
- printf("Program, chan=%d program=%d\n",chan+1,program);
- */
- }
-
- txt_chanpressure(chan,press)
- {
- /*
- prtime();
- printf("Channel pressure, chan=%d pressure=%d\n",chan+1,press);
- */
- }
-
- txt_sysex(leng,mess)
- char *mess;
- {
- /*
- prtime();
- printf("Sysex, leng=%d\n",leng);
- */
- }
-
- txt_metamisc(type,leng,mess)
- char *mess;
- {
- /*
- prtime();
- printf("Meta event, unrecognized, type=0x%02x leng=%d\n",type,leng);
- */
- }
-
- txt_metaspecial(type,leng,mess)
- char *mess;
- {
- /*
- prtime();
- printf("Meta event, sequencer-specific, type=0x%02x leng=%d\n",type,leng);
- */
- }
-
- txt_metatext(type,leng,mess)
- char *mess;
- {
- static char *ttype[] = {
- NULL,
- "Text Event", /* type=0x01 */
- "Copyright Notice", /* type=0x02 */
- "Sequence/Track Name",
- "Instrument Name", /* ... */
- "Lyric",
- "Marker",
- "Cue Point", /* type=0x07 */
- "Unrecognized"
- };
- int unrecognized = (sizeof(ttype)/sizeof(char *)) - 1;
- register int n, c;
- register char *p = mess;
-
- if ( type < 1 || type > unrecognized )
- type = unrecognized;
- /*
- prtime();
- printf("Meta Text, type=0x%02x (%s) leng=%d\n",type,ttype[type],leng);
- printf(" Text = <");
- for ( n=0; n<leng; n++ ) {
- c = *p++;
- printf( (isprint(c)||isspace(c)) ? "%c" : "\\0x%02x" , c);
- }
- printf(">\n");
- */
- }
-
- txt_metaseq(num)
- {
- /*
- prtime();
- printf("Meta event, sequence number = %d\n",num);
- */
- }
-
- txt_metaeot()
- {
- /*
- prtime();
- printf("Meta event, end of track\n");
- */
- }
-
- txt_keysig(sf,mi)
- {
- /*
- prtime();
- printf("Key signature, sharp/flats=%d minor=%d\n",sf,mi);
- */
- midikey[mwhre].when=Mf_currtime;
- /* the ? stuff is to compensate for compilers that don't sign
- * extend the sf */
- midikey[mwhre].nkey = (sf & 0x80) ? (sf | ~0xff) : sf;
- mwhre++;
- }
-
- txt_tempo(ltempo)
- long ltempo;
- {
- tempo = ltempo;
- /*
- prtime();
- printf("Tempo, microseconds-per-MIDI-quarter-note=%d\n",tempo);
- */
- }
-
- txt_timesig(nn,dd,cc,bb)
- {
- int denom = 1;
- while ( dd-- > 0 )
- denom *= 2;
- /*
- prtime();
- printf("Time signature=%d/%d MIDI-clocks/click=%d 32nd-notes/24-MIDI-clocks=%d\n",
- nn,denom,cc,bb);
- */
- tsig[twhre].when=Mf_currtime;
- tsig[twhre].num=nn;
- tsig[twhre].dnom = denom;
- twhre++;
- }
-
- txt_smpte(hr,mn,se,fr,ff)
- {
- /*
- prtime();
- printf("SMPTE, hour=%d minute=%d second=%d frame=%d fract-frame=%d\n",
- hr,mn,se,fr,ff);
- */
- }
-
- txt_arbitrary(leng,mess)
- char *mess;
- {
- /*
- prtime();
- printf("Arbitrary bytes, leng=%d\n",leng);
- */
- }
-
- prtime()
- {
- if(SECONDS)
- printf("Time=%f ",mf_ticks2sec(Mf_currtime,division,tempo));
- else
- printf("Time=%ld ",Mf_currtime);
- }
-
- initfuncs()
- {
- Mf_error = error;
- Mf_header = txt_header;
- Mf_trackstart = txt_trackstart;
- Mf_trackend = txt_trackend;
- Mf_noteon = txt_noteon;
- Mf_noteoff = txt_noteoff;
- Mf_pressure = txt_pressure;
- Mf_parameter = txt_parameter;
- Mf_pitchbend = txt_pitchbend;
- Mf_program = txt_program;
- Mf_chanpressure = txt_chanpressure;
- Mf_sysex = txt_sysex;
- Mf_metamisc = txt_metamisc;
- Mf_seqnum = txt_metaseq;
- Mf_eot = txt_metaeot;
- Mf_timesig = txt_timesig;
- Mf_smpte = txt_smpte;
- Mf_tempo = txt_tempo;
- Mf_keysig = txt_keysig;
- Mf_seqspecific = txt_metaspecial;
- Mf_text = txt_metatext;
- Mf_arbitrary = txt_arbitrary;
- }
- dorest(trck, len)
- int trck;
- int len;
- {
- int i;
-
- if(len > 0) {
- do {
- len = plen(len);
- printf("r;");
- } while(len != 0);
- } else
- printf("mr;", trck);
- }
- donote(trck, nval, len, tie)
- short trck, nval, len, tie;
- {
- do {
- len = plen(len);
- pnote(nval, trck);
- accwhre++;
- accnotes[accwhre] = nval;
- if(len != 0) {
- poctave(trck, nval);
- printf("~;");
- if(triplet == 3) {
- printf("}3;");
- triplet = 0;
- }
- tied[trck] = 1;
- }
- } while(len != 0);
- poctave(trck, nval);
- if(tie == TIE) {
- printf("~");
- tied[trck] = 1;
- }
- printf(";");
- if(triplet == 3) {
- printf("}3;");
- triplet = 0;
- }
- }
- dobar()
- {
- printf("\nbar\n");
- }
- plen(len)
- int len;
- {
- float f;
-
- if(len == division) {
- printf("4");
- } else if (len == (1.5 * division)) {
- printf("4.");
- } else if (len == division * 2) {
- printf("2");
- } else if (len == division * 3) {
- printf("2.");
- } else if (len == division * 4) {
- printf("1");
- } else if (len == (division/2)) {
- printf("8");
- } else if (len == (.75 * division)) {
- printf("8.");
- } else if (len == (division/4)) {
- printf("16");
- } else if (len == (division/4 + division/8)) {
- printf("16.");
- } else if (len == (division/8)) {
- printf("32");
- } else if (len == ((division*2)/3)) {
- if(triplet == 0)
- printf("{4");
- else
- printf("4");
- triplet++;
- } else if (len == (division/3)) {
- if(triplet == 0)
- printf("{8");
- else
- printf("8");
- triplet++;
- } else if (len == (division/6)) {
- if(triplet == 0)
- printf("{16");
- else
- printf("16");
- triplet++;
- /*
- * Try to handle some things that *can't* be a single note..
- * things that will have to be a tie, simply because there's
- * no other way to notate that length. (Like a halfnote tied
- * to an eigthnote.)
- */
- } else {
- /*
- * Some wierd stuff to find counts like 2.5
- */
- if(len > division) {
- /* a multiple of quarternotes tied to an 8th note? */
- if((len == (2*division) + (division/2)) || (len == (3*division) + (division/2))) {
- printf("8");
- return(len - (division/2));
- }
- /* one or more quarternotes tied to an 16th note? */
- if((len == (division) + (division/4)) + (len == (2*division) + (division/4)) || (len == (3*division) + (division/4))) {
- printf("16");
- return(len - (division/4));
- }
- /* one or more quarternotes tied to an 32th note? */
- if((len == (division) + (division/8)) + (len == (2*division) + (division/8)) || (len == (3*division) + (division/8))) {
- printf("32");
- return(len - (division/8));
- }
- if(len == (division) + (division/2) + (division/4)) {
- printf("4..");
- return(0);
- }
- /* Nothing yet? You're on your own. */
- printf("(BADLEN=%d,%d: quarters=%f)", len, division, f=(float)len/(float)division);
- triplet = 0;
- /*
- * Now deal with stuff less than a quarter in length.
- * People may not like this, but the assumption here is
- * that we have an 8th tied to a 32nd. Anything else
- * and you're on your own.
- */
- } else {
- if(len == (division/2 + division/8)) {
- printf("32");
- return(len - division/32);
- }
- printf("(BADLEN=%d,%d: quarters=%f)", len, division, f=(float)len/(float)division);
- }
- }
- return 0;
- }
- poctave(trck, nval)
- short trck, nval;
- {
- /* for defoct=2 */
- if(nval >= 0 && nval < 12)
- printf("-----");
- else if(nval > 11 && nval < 24)
- printf("----");
- else if(nval > 23 && nval < 36)
- printf("---");
- else if(nval > 35 && nval < 48)
- printf("--");
- else if(nval > 47 && nval < 60)
- printf("-");
- else if(nval > 59 && nval < 72)
- printf("");
- else if(nval > 71 && nval < 84)
- printf("+");
- else if(nval > 83 && nval < 96)
- printf("++");
- else if(nval > 95 && nval < 108)
- printf("+++");
- else /* if(nval > 23 && nval < 120); */
- printf("++++");
- }
- int
- goctave(trck, nval)
- short trck, nval;
- {
- /* for defoct=2 */
- if(nval >= 0 && nval < 12)
- return(0);
- else if(nval > 11 && nval < 24)
- return(1);
- else if(nval > 23 && nval < 36)
- return(2);
- else if(nval > 35 && nval < 48)
- return(3);
- else if(nval > 47 && nval < 60)
- return(4);
- else if(nval > 59 && nval < 72)
- return(5);
- else if(nval > 71 && nval < 84)
- return(6);
- else if(nval > 83 && nval < 96)
- return(7);
- else if(nval > 95 && nval < 108)
- return(8);
- else /* if(nval > 23 && nval < 120); */
- return(9);
- }
- doheader(fp)
- FILE *fp;
- {
-
- int i;
- char buf[80];
-
- while(fgets(buf, 80, fp) != '\0') {
- if(strncmp("#headend", buf, 8) == 0)
- return;
- else
- printf("%s", buf);
- }
- printf("// NO \"#headend\" STATEMENT?!\n");
- }
- dobeamstyle(fp)
- FILE *fp;
- {
-
- int i, j;
- char buf[80];
- char x[2], y[2];
- int n, d;
-
- while(fgets(buf, 80, fp) != '\0') {
- if(strncmp("#beamend", buf, 8) == 0)
- return;
- else {
- x[0]=buf[0];
- if(buf[1] != '/') {
- x[1]=buf[1];
- y[0]=buf[3];
- if(buf[4] != '=') {
- y[1] = buf[4];
- i = 6;
- } else
- i = 5;
- } else {
- y[0] = buf[2];
- if(buf[3] != '=') {
- y[1] = buf[3];
- i = 5;
- } else
- i = 4;
- }
- n = atoi(x);
- d = atoi(y);
- bstyles[bwhre].bnum = n;
- bstyles[bwhre].bdnom = d;
- j = 0;
- while(i < (strlen(buf) - 1)) {
- bstyles[bwhre].style[j] = buf[i];
- i++;
- j++;
- }
- printf("// beamstyle %d/%d = %s\n", bstyles[bwhre].bnum, bstyles[bwhre].bdnom, bstyles[bwhre].style);
- bwhre++;
- }
- }
- printf("// NO \"#beamend\" STATEMENT?!\n");
- }
- dotranslate(buf)
- char *buf;
- {
-
- int j, i, o;
- char ii[3], oo[3];
-
- for(i = 0; i < 3; i++) {
- ii[i] = '\0';
- oo[i] = '\0';
- }
- for(j = 10; ((buf[j] == ' ') || (buf[j] == '\t')); j++)
- ;
-
- ii[0] = buf[j];
- j++;
- if(buf[j] == '=') {
- j++;
- oo[0] = buf[j];
- } else {
- ii[1] = buf[j];
- j += 2;
- oo[0] = buf[j];
- }
- j++;
- if(buf[j] != '\n')
- oo[1] = buf[j];
- tlate[tlwhre].in = atoi(ii);
- tlate[tlwhre].out = atoi(oo);
- printf("// Translate track %d to %d.\n", tlate[tlwhre].in, tlate[tlwhre].out);
- tlwhre++;
- return;
- }
- dokey(buf)
- char *buf;
- {
-
- int j, i, o;
- char ii[3], oo[3];
-
- for(i = 0; i < 3; i++) {
- ii[i] = '\0';
- oo[i] = '\0';
- }
- for(j = 4; ((buf[j] == ' ') || (buf[j] == '\t')); j++)
- ;
-
- ii[0] = buf[j];
- j++;
- if(buf[j] == '=') {
- j++;
- oo[0] = buf[j];
- } else {
- ii[1] = buf[j];
- j += 2;
- oo[0] = buf[j];
- }
- j++;
- if(buf[j] != '\n')
- oo[1] = buf[j];
- j = hkey[atoi(ii)] = atoi(oo);
- printf("// Key sig for track %d set to %d\n", atoi(ii), j);
- /*
- * printf("staff %d\n", atoi(ii));
- * if(j <= 0)
- * printf("\tkey=%d&\n", j);
- * else
- * printf("\tkey=%d#\n", j);
- * printf("music\n");
- */
- return;
- }
- int
- fudge(len)
- int len;
- {
- float f;
-
- if(abs(division - len) < FFACTOR) {
- return(division);
- } else if (abs((3 * division / 2) - len) < FFACTOR) {
- return(3 * division / 2);
- } else if (abs((division * 2) - len) < FFACTOR) {
- return(division * 2);
- } else if (abs((division * 3) - len) < FFACTOR) {
- return(division * 3);
- } else if (abs((division * 4) - len) < FFACTOR) {
- return(division * 4);
- } else if (abs((division/2) - len) < FFACTOR) {
- return(division/2);
- } else if (abs((3 * division / 4) - len) < FFACTOR) {
- return(3 * division / 4);
- } else if (abs((division/3) - len) < FFACTOR) {
- return(division/3);
- } else if (abs((division/4) - len) < FFACTOR) {
- return(division/4);
- } else if (abs((division/4 + division/8) - len) < FFACTOR) {
- return(division/4 + division/8);
- } else if (abs((division/8) - len) < FFACTOR) {
- return(division/8);
- /*
- * Try to handle some things that *can't* be a single note..
- * things that will have to be a tie, simply because there's
- * no other way to notate that length. (Like a halfnote tied
- * to an eigthnote.)
- */
- } else {
- /*
- * Some wierd stuff to find counts like 2.5
- */
- if(len > division) {
- /* a multiple of quarternotes tied to an 8th note? */
- if(abs(((2*division) + (division/2)) - len) < FFACTOR) {
- return((2*division) + (division/2));
- } else if(abs(((3*division) + (division/2)) - len) < FFACTOR) {
- return((3*division) + (division/2));
- }
- /* one or more quarternotes tied to an 16th note? */
- if(abs(((division) + (division/4)) - len) < FFACTOR) {
- return((division) + (division/4));
- } else if(abs(((division*2) + (division/4)) - len) < FFACTOR) {
- return((division*2) + (division/4));
- } else if(abs(((division*3) + (division/4)) - len) < FFACTOR) {
- return((division*3) + (division/4));
- }
- /* one or more quarternotes tied to an 32th note? */
- if(abs(((division) + (division/8)) - len) < FFACTOR) {
- return((division) + (division/8));
- } else if(abs(((division*2) + (division/8)) - len) < FFACTOR) {
- return((division*2) + (division/8));
- } else if(abs(((division*3) + (division/8)) - len) < FFACTOR) {
- return((division*3) + (division/8));
- }
- if(abs((division) + (division/2) + (division/4) - len) < FFACTOR) {
- return((division) + (division/2) + (division/4));
- }
- /* Nothing yet? You're on your own. */
-
- fprintf(stderr, "FUDGE: BADLEN=%d,%d: quarters=%f, measure %d\n", len, division, f=(float)len/(float)division, measure);
- /*
- * Now deal with stuff less than a quarter in length.
- * People may not like this, but the assumption here is
- * that we have an 8th tied to a 32nd. Anything else
- * and you're on your own.
- */
- } else {
- if(abs((division/2 + division/8) - len) < 10) {
- return(division/2 + division/8);
- }
- fprintf(stderr, "FUDGE: BADLEN=%d,%d: quarters=%f, measure %d\n", len, division, f=(float)len/(float)division, measure);
- }
- }
- return 0;
- }
-
-
- #ifdef __DOS__
- /* for systems that don't have a getopt() function,
- * define one here. This is NOT a general purpose implementation of getopt(),
- * but something good enough to work */
-
- int optind = 1;
- char *optarg;
- static int argoffset;
-
- #define NOARG 1
- #define WITHARG 2
- #define BADOPT 3
-
- int
- getopt(argc, argv, optstring)
-
- int argc;
- char **argv;
- char *optstring;
-
- {
- int option;
-
-
- if (optind >= argc) {
- return(EOF);
- }
-
- if (argoffset == 0) {
- if (argv[optind][argoffset] == '-'
- || argv[optind][argoffset] == '/') {
- argoffset = 1;
- }
- else {
- return(EOF);
- }
- }
-
- /* determine if option is valid and if should have an argument */
- option = argv[optind][argoffset] & 0x7f;
- switch (opttype(option, optstring)) {
- case NOARG:
- /* valid option without argument. Keep track of where
- * to look for next option */
- if (argv[optind][++argoffset] == '\0') {
- optind++;
- argoffset = 0;
- }
- break;
-
- case WITHARG:
- /* valid option with argument. */
- if (argv[optind][++argoffset] != '\0') {
- /* argument immediately follows in same argv */
- optarg = &(argv[optind][argoffset]);
- optind++;
- }
- else {
- /* white space. argument must be in next argv */
- optind++;
- if (optind >= argc) {
- fprintf(stderr, "missing argument to %c%c option\n", Optch, option);
- return('?');
- }
- optarg = &(argv[optind][0]);
- optind++;
- }
- argoffset = 0;
- break;
-
- default:
- fprintf(stderr, "invalid option %c%c\n", Optch, option);
- option = '?';
- }
- return(option);
- }
-
-
- /* look up option in optstring and return type of option */
-
- int
- opttype(option, optstring)
-
- int option;
- char *optstring;
-
- {
- char *p;
-
- for (p = optstring; *p != '\0'; ) {
- if (*p++ == option) {
- return(*p == ':' ? WITHARG : NOARG);
- }
- if (*p == ':') {
- p++;
- }
- }
- return(BADOPT);
- }
-
- #endif