diff options
author | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
---|---|---|
committer | Norbert Preining <norbert@preining.info> | 2019-09-02 13:46:59 +0900 |
commit | e0c6872cf40896c7be36b11dcc744620f10adf1d (patch) | |
tree | 60335e10d2f4354b0674ec22d7b53f0f8abee672 /support/mid2tex/src/readmidi.c |
Initial commit
Diffstat (limited to 'support/mid2tex/src/readmidi.c')
-rw-r--r-- | support/mid2tex/src/readmidi.c | 1040 |
1 files changed, 1040 insertions, 0 deletions
diff --git a/support/mid2tex/src/readmidi.c b/support/mid2tex/src/readmidi.c new file mode 100644 index 0000000000..4d272ac670 --- /dev/null +++ b/support/mid2tex/src/readmidi.c @@ -0,0 +1,1040 @@ +/***************************/ +/* readmidi.c */ +/***************************/ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include "midi.h" +#include "maintypes.h" +#include "defines.h" +#include "readmidi.h" + +#ifdef DEBUG +static void ausgabe() +{ + printf("MThd = %s, chunk_length = %d\n", head.MThd , head.chunk_length); + printf("format = %d, tracks = %d, per_quarter = %x\n", + head.format, head.tracks, head.per_quarter); + + printf("Mtrk = %s, Track_chunk_length = %d\n", + THead.MTrk, THead.chunk_length); +} +#endif + +static unsigned long get_valid_time(ti) + unsigned long ti; +{ + if (ti < bartime) { + if (ti < lastbartime) { + converter = 0; + sequencecounter = 0; + } + else { + converter = lastbartime; + sequencecounter = (double) lastbartime; + } + } + else { + converter = bartime; + sequencecounter = (double) bartime; + } + while (ti > converter) { + lastsc = sequencecounter; + sequencecounter += one64tel; + converter = (unsigned long) sequencecounter; + } + if (ti < converter) ti = (unsigned long) lastsc; + return(ti); +} + +static char midi_getc(fpointer) + FILE *fpointer; +{ + if (THead.chunk_length-- < 0) { + fprintf(stderr, "midi_getc: Length Underflow\n"); + exit(10); + } + return(getc(fpointer)); +} + +static void midi_ungetc(c, fpointer) + FILE *fpointer; + char c; +{ + THead.chunk_length++; + ungetc(c, fpointer); +} + +static unsigned int ReadVarLen() +{ + unsigned int value; + unsigned char c; + + if ((value = midi_getc(fp)) & 0x80) { + value &= 0x7f; + do { + value = (value << 7) + ((c = midi_getc(fp)) & 0x7f); + } + while (c & 0x80); + } + + return(value); +} + + +static void ReadMidiTrackName(delta) + int delta; +{ + int len, i; + + len = ReadVarLen(); + for (i = 0; i < len; i++) { + if (i < 80 - 1) TrackName[Track_Nr][i] = midi_getc(fp); + else midi_getc(fp); + } + if (i<80) TrackName[Track_Nr][i] = '\0'; + else TrackName[Track_Nr][79] = '\0'; + +#ifdef DEBUG + printf("MIDI_TRACK_NAME (%s) at %d\n", TrackName[Track_Nr], delta); +#endif + +} + +static void ReadMidiSequSpec(delta) + int delta; +{ + int len, i; + char Str[80]; +#ifdef DEBUG + int j; +#endif + + len = ReadVarLen(); + for (i = 0; i < len; i++) { + if (i < 80 - 1) Str[i] = midi_getc(fp); + } + Str[i] = '\0'; +#ifdef DEBUG + printf("MIDI_SEQUENCER_SPECIFIC at %d:\n", delta); + for (j = 0; j < i; j++) + printf("\t0x%x\n", Str[j]); +#endif +} + +#ifdef DEBUG +static char *p2str(oct, pit) + int oct, pit; +{ + static char Str[10]; + static char *p_table[12] = {"C", "Cis", "D", "Dis", + "E", "F", "Fis", "G", + "Gis", "A", "B", "H"}; + + sprintf(Str, "%s%d", p_table[pit], oct); + return(Str); +} +#endif + +static void ReadMidiToneVal(oct, pit, laut) + int *oct, *pit, *laut; +{ + int w; + unsigned char inthelp; + + w = midi_getc(fp); + *laut = midi_getc(fp); + + /* allow only octaves 0 - 5 */ + if ((w>24) && (w<95)) { + *oct = (w / 12) - 2; + *pit = (w % 12); + } + else { + *oct = 6; + *pit = 0; + } + + inthelp = 12 * (*oct) + (*pit); + if (max[Track_Nr] < inthelp) max[Track_Nr] = inthelp; + if (min[Track_Nr] > inthelp) min[Track_Nr] = inthelp; +} + +static void erzeuge_note(octave, pitch, laut, begin, dauer, channel) + int octave, pitch, laut, dauer, channel; + unsigned long int begin; +{ + if (firstnotetimeflag == -1) { + firstnotetime = begin; + firstnotetimeflag = 0; + } + /* if there were no TimeSig */ + if ((valid == 0) && (begin > firstnotetime)) { + valid++; + if ((!printonly) || (Track_Nr == (printonly -1))) { + if ((!notes_flag) && (nom0) && (Track_Nr)) + ins_dyn_event(Track_Nr, 't', 0, nom0, denom0, 0, 0, 0, 0, 0); + else + ins_dyn_event(Track_Nr, 't', 0, 4, 4, 0, 0, 0, 0, 0); + } + } + + /* if there were no KeySig */ + if ((valid2 == 0) && (begin > firstnotetime)) { + valid2++; + if ((!printonly) || (Track_Nr == (printonly -1))) { + if ((!notes_flag) && (key0) && (Track_Nr)) + ins_dyn_event(Track_Nr, 'k', 0, key0, 0, 0, 0, 0, 0, 0); + else + ins_dyn_event(Track_Nr, 'k', 0, 0, 0, 0, 0, 0, 0, 0); + } + } + +#ifdef DEBUG + fprintf(stdout, "NOTE into dyn_event_list inserted\n"); + fprintf(stdout, "oct: %d\t pit: %d\t laut: %x\t beg: %lx\t durat: %x\n", + octave, pitch, laut, begin, dauer); +#endif + /* notes_flag shows that notes of first track were read */ + /* */ + /* because f.e. rosegarden writes empty first track */ + /* with takt and key info for all other tracks */ + + if (Track_Nr == 0) notes_flag = 1; + + if (((!printonly) || (Track_Nr == (printonly -1))) && (octave != 6)) + ins_dyn_event(Track_Nr, 'n', 0, 0, 0, octave, pitch, laut, get_valid_time(begin), dauer); +} + +static void ReadMidiNoteOff(channel, delta) + int channel, delta; +{ + int dauer, octave, pitch, laut, la; + unsigned long int begin; + + ReadMidiToneVal(&octave, &pitch, &laut); + +#ifdef DEBUG + printf("MIDI_NOTE_OFF at %d(%ld): Channel: %d, pitch = %s, laut = 0x%x\n", + delta, zeit, channel, p2str(octave, pitch), laut); +#endif + dauer = note_delete(octave, pitch, &la, zeit, &begin, channel); +#ifdef DEBUG + printf("Generate_Note with begin = %ld, absolute time = %ld, duration = %d\n", + begin, zeit, dauer); +#endif + erzeuge_note(octave, pitch, la, begin, dauer, channel); +} + +static void ReadMidiNoteOn(channel, delta) + int channel, delta; +{ + int dauer, octave, pitch, laut, la; + unsigned long int begin; + + ReadMidiToneVal(&octave, &pitch, &laut); + + if (laut) { + note_insert(octave, pitch, laut, zeit, channel); + } + else { + dauer = note_delete(octave, pitch, &la, zeit, &begin, channel); +#ifdef DEBUG + printf("Generate_Note with begin = %ld, absolute time = %ld, duration = %d\n", + begin, zeit, dauer); +#endif + erzeuge_note(octave, pitch, la, begin, dauer, channel); + } +#ifdef DEBUG + printf("MIDI_NOTE_ON at %d(%ld): Channel: %d, pitch = %s, laut = 0x%x\n", + delta, zeit, channel, p2str(octave, pitch), laut); +#endif +} + +static void ReadMidiPolyAftertouch(channel, delta) + int channel, delta; +{ + char dum1, dum2; + + dum1 = midi_getc(fp); dum2 = midi_getc(fp); +#ifdef DEBUG + printf("MIDI_POLY_AFTERTOUCH: 0x%x, 0x%x, 0x%x\n", channel, dum1, dum2); +#endif +} + +static void ReadMidiCtrlChange(channel, delta) + int channel, delta; +{ + char dum1, dum2; + + dum1 = midi_getc(fp); dum2 = midi_getc(fp); +#ifdef DEBUG + printf("MIDI_CTRL_CHANGE: 0x%x, 0x%x, 0x%x\n", channel, dum1, dum2); +#endif +} + +static void ReadMidiProgChange(channel, delta) + int channel, delta; +{ + char dum1; + + dum1 = midi_getc(fp); +#ifdef DEBUG + printf("MIDI_PROG_CHANGE: 0x%x, 0x%x\n", channel, dum1); +#endif +} + +static void ReadMidiChnlAftertouch(channel, delta) + int channel, delta; +{ + char dum1; + + dum1 = midi_getc(fp); +#ifdef DEBUG + printf("MIDI_CHNL_AFTERTOUCH: 0x%x, 0x%x\n", channel, dum1); +#endif +} + +static void ReadMidiPitchBend(channel, delta) + int channel, delta; +{ + char dum1, dum2; + + dum1 = midi_getc(fp); dum2 = midi_getc(fp); +#ifdef DEBUG + printf("MIDI_PITCH_BEND: 0x%x, 0x%x, 0x%x\n", channel, dum1, dum2); +#endif +} + +static void ReadMidiSongPositionPtr(delta) + int delta; +{ + char dum1, dum2; + + dum1 = midi_getc(fp); dum2 = midi_getc(fp); +#ifdef DEBUG + printf("MIDI_SONG_POSITION_PTR: 0x%x, 0x%x\n", dum1, dum2); +#endif +} + +static void ReadMidiSongSelect(delta) + int delta; +{ + char dum1; + + dum1 = midi_getc(fp); +#ifdef DEBUG + printf("MIDI_SONG_SELECT: 0x%x\n", dum1); +#endif +} + +static void ReadMidiSystemExclusive() +{ + int dum; + unsigned int value; + + dum = ReadVarLen(); + while ((value = midi_getc(fp)) != MIDI_EOX); +#ifdef DEBUG + printf("MIDI_SYSTEM_EXCLUSIVE\n"); +#endif +} + +static void ReadMidiSetTempo(delta) + int delta; +{ + unsigned int len, tempo; + + len = midi_getc(fp); + if (len == 0x03) { + tempo = 0; + while(len--) { + tempo *= 0x100; + tempo += (unsigned int) (0xff & midi_getc(fp)); + } +#ifdef DEBUG + D_Tempo = (double) tempo / 1000000.0; + printf("MIDI_SET_TEMPO at %d: Tempo = %d(%f)\n", delta, tempo, D_Tempo); +#endif + } + else { /* system reset detect */ + midi_ungetc(len, fp); + midi_ungetc(0x51, fp); + } +} + +static void ReadMidiTimeSig(delta) + int delta; +{ + int dummy, nn, dd, cc, bb, dominator; + + dummy = midi_getc(fp); + if (dummy == 0x04) { + valid = 1; /* means: TimeSig detected */ + nn = midi_getc(fp); + dd = midi_getc(fp); + cc = midi_getc(fp); + bb = midi_getc(fp); + dominator = (1 << dd); + help = taktzeit; + taktzeit = head.per_quarter * nn * 4 / dominator; + diskrete_tz = diskrete_tz + taktzeit - help; + if ((!Track_Nr) && (!nom0)) { + nom0 = nn; + denom0 = dominator; + } + if ((!printonly) || (Track_Nr == (printonly -1))) + ins_dyn_event(Track_Nr, 't', 0, nn, dominator, 0, 0, 0, get_valid_time(zeit), 0); + +#ifdef DEBUG + printf("Takt: %x\n",taktzeit); + printf("MIDI_TIME_SIGNATURE at %d: Takt:%d/%d\nMIDI-clocks per Metronom: %d,", + delta, nn, dominator, cc); + printf("%d 32nd per MIDI-Quarter\n", bb); +#endif + } + else { /* system reset detect */ + midi_ungetc(dummy, fp); + midi_ungetc(0x58, fp); + } +} + +static void ReadMidiTextEvent(delta) + int delta; +{ + unsigned int len; + int value; + + len = ReadVarLen(); + while (len--) value = midi_getc(fp); +#ifdef DEBUG + printf("MIDI_TEXT_EVENT\n"); +#endif +} + +static void ReadMidiCopyrightNotice(delta) + int delta; +{ + unsigned int len; + int value; + + len = ReadVarLen(); + while (len--) value = midi_getc(fp); +#ifdef DEBUG + printf("MIDI_COPYRIGHT_NOTICE\n"); +#endif +} + +static void ReadMidiInstrumentName(delta) + int delta; +{ + unsigned int len; + int value=0; + + len = ReadVarLen(); + while (len--) Staffs[Track_Nr][value++] = midi_getc(fp); + Staffs[Track_Nr][value] = 0; +#ifdef DEBUG + printf("MIDI_INSTRUMENT_NAME: %s\n",Staffs[Track_Nr]); +#endif +} + +static void ReadMidiLyrik(delta) + int delta; +{ + unsigned int len; + char *ptr, *ptrhelp; + + len = ReadVarLen(); + if ((ptr = (char *) malloc (len+1)) == NULL) { + fprintf(stderr, "mallocC error\n"); + exit(10); + } + ptrhelp = ptr; + while (len--) { + *ptrhelp = midi_getc(fp); + ptrhelp++; + } + *ptrhelp = 0; +#ifdef DEBUG + printf("MIDI_LYRIC\n"); +#endif + if ((!printonly) || (Track_Nr == (printonly -1))) + ins_dyn_event(Track_Nr, 'l', ptr, 0, 0, 0, 0, 0, get_valid_time(zeit), 0); +} + +static void ReadMidiTextMarker(delta) + int delta; +{ + unsigned int len; + int value; + + len = ReadVarLen(); + while (len--) value = midi_getc(fp); +#ifdef DEBUG + printf("MIDI_TEXT_MARKER\n"); +#endif +} + +static void ReadMidiCuePoint(delta) + int delta; +{ + unsigned int len; + int value; + + len = ReadVarLen(); + while (len--) value = midi_getc(fp); +#ifdef DEBUG + printf("MIDI_CUE_POINT\n"); +#endif +} + +static void ReadMidiChannelPrefix(delta) + int delta; +{ + int dum1, dum2; + dum1 = midi_getc(fp); + if (dum1 == 0x01) { + dum2 = midi_getc(fp); +#ifdef DEBUG + printf("MIDI_CHANNEL_PREFIX\n"); +#endif + } + else { /* system reset detect */ + midi_ungetc(dum1, fp); + midi_ungetc(0x20, fp); + } +} + +static void ReadMidiSmpteOffset(delta) + int delta; +{ + int dum; + + if (delta != 0) { /* system reset detect */ + midi_ungetc(0x54, fp); + } + else { + dum = midi_getc(fp); + if (dum == 0x05) { + midi_getc(fp); midi_getc(fp); midi_getc(fp); + midi_getc(fp); midi_getc(fp); +#ifdef DEBUG + printf("MIDI_SMPTE_OFFSET\n"); +#endif + } + else { /* system reset detect */ + midi_ungetc(dum, fp); + midi_ungetc(0x54, fp); + } + } +} + +static void ReadMidiSequenceNumber(MetaEvent, delta) + int delta; + unsigned char MetaEvent; +{ + int value; + + value = midi_getc(fp); + if (value != 0x02) { /* system reset detect */ + midi_ungetc(value, fp); + midi_ungetc(0x00, fp); + } + else { + value = midi_getc(fp); value = midi_getc(fp); + value = midi_getc(fp); value = midi_getc(fp); +#ifdef DEBUG + printf("MIDI_SEQUENCE_NUMBER\n"); +#endif + } +} + +static void ReadMidiKeySig(delta) + int delta; +{ + int dum, sign; + + dum = midi_getc(fp); + if (dum != 0x02) { /* system reset detect */ + midi_ungetc(dum, fp); + midi_ungetc(0x59, fp); + } + else { + valid2 = 1; /* KeySig detected */ + sign = midi_getc(fp); + /* manipulate sign */ + if ((sign & 0x80) && (sign & 0x08)) { + sign = sign ^ 0xf; + sign++; + } + if ((!Track_Nr) && (!key0)) key0 = sign; + if ((!printonly) || (Track_Nr == (printonly -1))) + ins_dyn_event(Track_Nr, 'k', 0, sign, 0, 0, 0, 0, get_valid_time(zeit), 0); + T_genus = (0xff & sign); + Signature = (0xff & midi_getc(fp)); +#ifdef DEBUG + printf("MIDI_KEY_SIGNATURE at %d: T_genus = ", delta); + switch (T_genus) { + case MINOR: printf("MINOR"); break; + case MAJOR: printf("MAJOR"); break; + default: printf("unknown"); break; + } + printf(" Signature = %d\n", Signature); +#endif + } +} + +static void ReadMidiEndOfTrack(delta) + int delta; +{ + int dum, dauer, octave, pitch, laut, channel; + unsigned long int begin; + + dum = midi_getc(fp); + if (dum == 0) { + dum = midi_getc(fp); /* read - deltatime */ + while (dum == 0) { /* falls nach EOTrack noch Folgeelement */ + midi_ungetc(dum, fp); + ReadEvent(); + dum = midi_getc(fp); + } + midi_ungetc(dum, fp); + while ((dauer = search_note(&octave, &pitch, &laut, zeit, &begin, &channel)) != -1) { +#ifdef DEBUG + printf("erzeuge_note mit begin = %ld, zeit = %ld, dauer = %d\n", + begin, zeit, dauer); +#endif + erzeuge_note(octave, pitch, laut, begin, dauer, channel); + } + + if (THead.chunk_length) { + fprintf(stderr, "Warning: ReadMidiEndOfTrack: Sync_Error THead.chunk_length = %d\n", + THead.chunk_length); + while (THead.chunk_length >= 0) midi_getc(fp); + } +#ifdef DEBUG + printf("MIDI_END_OF_TRACK at %d\n", delta); +#endif + } + else { /* system reset detect */ + midi_ungetc(dum, fp); + midi_ungetc(0x2f, fp); + } +} + +static int ReadMidiMetaEvent(delta) + int delta; +{ + unsigned char MetaEvent; + int not_eot = 1; + + switch(MetaEvent = midi_getc(fp)) { + case MIDI_SEQUENCE_NUMBER: ReadMidiSequenceNumber(MetaEvent,delta); break; + case MIDI_TEXT_EVENT: ReadMidiTextEvent(delta); break; + case MIDI_TRACK_NAME: ReadMidiTrackName(delta); break; + case MIDI_SET_TEMPO: ReadMidiSetTempo(delta); break; + case MIDI_TIME_SIGNATURE: ReadMidiTimeSig(delta); break; + case MIDI_END_OF_TRACK: ReadMidiEndOfTrack(delta); not_eot = 0; break; + case MIDI_KEY_SIGNATURE: ReadMidiKeySig(delta); break; + case MIDI_SEQUENCER_SPECIFIC: ReadMidiSequSpec(delta); break; + case MIDI_CHANNEL_PREFIX: ReadMidiChannelPrefix(delta); break; + case MIDI_SMPTE_OFFSET: ReadMidiSmpteOffset(delta); break; + case MIDI_COPYRIGHT_NOTICE: ReadMidiCopyrightNotice(delta); break; + case MIDI_INSTRUMENT_NAME: ReadMidiInstrumentName(delta); break; + case MIDI_LYRIC: ReadMidiLyrik(delta); break; + case MIDI_TEXT_MARKER: ReadMidiTextMarker(delta); break; + case MIDI_CUE_POINT: ReadMidiCuePoint(delta); break; + default: /* system reset detect */ + midi_ungetc(MetaEvent, fp); break; + } + return(not_eot); +} + +static int ReadEvent() +{ + unsigned char Event_Type; + int delta, not_eot = 1; + + delta = ReadVarLen(); + zeit += delta; + + while (zeit >= diskrete_tz) { + if ((!printonly) || (Track_Nr == (printonly -1))) { + lastbartime = bartime; + bartime = diskrete_tz; + ins_dyn_event(Track_Nr, 'b', 0, 0, 0, 0, 0, 0, diskrete_tz, taktzeit); + } + diskrete_tz += taktzeit; + } + + Event_Type = midi_getc(fp); +r_event: + if ((0xf0 & Event_Type) == MIDI_NOTE_OFF) { + ReadMidiNoteOff((Event_Type & 0xf), delta); + } + else if ((0xf0 & Event_Type) == MIDI_NOTE_ON) { + ReadMidiNoteOn((Event_Type & 0xf), delta); + } + else if ((0xf0 & Event_Type) == MIDI_POLY_AFTERTOUCH) { + ReadMidiPolyAftertouch((Event_Type & 0xf), delta); + } + else if ((0xf0 & Event_Type) == MIDI_CTRL_CHANGE) { + ReadMidiCtrlChange((Event_Type & 0xf), delta); + } + else if ((0xf0 & Event_Type) == MIDI_PROG_CHANGE) { + ReadMidiProgChange((Event_Type & 0xf), delta); + } + else if ((0xf0 & Event_Type) == MIDI_CHNL_AFTERTOUCH) { + ReadMidiChnlAftertouch((Event_Type & 0xf), delta); + } + else if ((0xf0 & Event_Type) == MIDI_PITCH_BEND) { + ReadMidiPitchBend((Event_Type & 0xf), delta); + } + else if ((0xf0 & Event_Type) == MIDI_SYSTEM_MSG) { + if (Event_Type == MIDI_FILE_META_EVENT) { + not_eot = ReadMidiMetaEvent(delta); + } + else { + /* treatment of all other 0xfx-events */ + switch (0xf & Event_Type) { + case MIDI_SONG_POSITION_PTR: /* 0xf2 */ + ReadMidiSongPositionPtr(delta); + break; + case MIDI_SONG_SELECT: /* 0xf3 */ + ReadMidiSongSelect(delta); + break; + case MIDI_SYSTEM_EXCLUSIVE: /* 0xf0 */ + ReadMidiSystemExclusive(); + break; + case MIDI_TUNE_REQUEST: /* 0xf6 */ + case MIDI_TIMING_CLOCK: /* 0xf8 */ + case MIDI_START: /* 0xfa */ + case MIDI_CONTINUE: /* 0xfb */ + case MIDI_STOP: /* 0xfc */ + case MIDI_ACTIVE_SENSING: /* 0xfe */ + midi_getc(fp); + break; + default: + fprintf(stderr, "Event: 0x%x unknown\n", Event_Type); + fprintf(stderr, "Fileoffset: %lu\n", ftell(fp)); + exit(10); + } + } + } + else if (Running_Event) { +#ifdef DEBUG + printf("Running Event\n"); +#endif + midi_ungetc(Event_Type, fp); + + Event_Type = Running_Event; + goto r_event; + } + else { + fprintf(stderr, "Event: 0x%x unknown\n", Event_Type); + fprintf(stderr, "Fileoffset: %lu\n", ftell(fp)); + exit(10); + } + Running_Event = Event_Type; + return(not_eot); +} + + +static void read_track() +{ + zeit = 0; + THead.MTrk[0] = getc(fp); THead.MTrk[1] = getc(fp); + THead.MTrk[2] = getc(fp); THead.MTrk[3] = getc(fp); + THead.MTrk[4] = '\0'; + if (strcmp(THead.MTrk, MIDI_TRACK_HEADER)) { + fprintf(stderr, "read_track: Sync_error(%s)\n", THead.MTrk); + exit(10); + } + THead.chunk_length = 0x1000000 * getc(fp); + THead.chunk_length += 0x10000 * getc(fp); + THead.chunk_length += 0x100 * getc(fp); + THead.chunk_length += getc(fp); +#ifdef DEBUG + ausgabe(); +#endif + Running_Event = 0; + while (ReadEvent()); +} + +static void usage(conststrg) + char *conststrg; +{ + fprintf(stderr,"usage:\t%s [-<nr>] <midifile> [<texfile>]\n", conststrg); + fprintf(stderr,"\t%s -c <midifile>\n", conststrg); + exit(10); +} + +void main(argc, argv) + int argc; + char *argv[]; +{ + int lenhelp; + char opthelp; + + if (argc < 2) usage(argv[0]); + + if ((argc == 3) && (!strcmp(argv[1],"-c"))) { + if ((fp = fopen(argv[2], "r")) == NULL) { + fprintf(stderr, "cannot open %s\n", argv[1]); + exit(10); + } + count = 1; + } + else { + count = 0; + if (*argv[1] == '-') { + if ((argc == 2) || (*argv[2] == '-') || (argc > 4)) usage(argv[0]); + opthelp = 1; + printonly = (char) atoi((argv[1])+1); + if (!printonly) printonly = 20; + } + else { + if (argc > 3) usage(argv[0]); + printonly = 0; /* print every track */ + opthelp = 0; + } + + if ((fp = fopen(argv[1+opthelp], "r")) == NULL) { + fprintf(stderr, "cannot open %s\n", argv[1+opthelp]); + exit(10); + } + + /* fill the array for the name of tex file */ + if (argc == (3+opthelp)) { + if (!strcmp(argv[1+opthelp], argv[2+opthelp])) { + fprintf(stderr, "cannot process one file to itself\n"); + exit(10); + } + strcpy(texfilename, argv[2+opthelp]); + } + else { /* mainmark1: try to select a nice name for texfile */ + strcpy(texfilename, argv[1+opthelp]); + lenhelp = strlen(texfilename) - 4; + + /* delete midi file extension */ + if ((!strcmp(&(texfilename[lenhelp]),".mid")) || + (!strcmp(&(texfilename[lenhelp]),".MID"))) + texfilename[lenhelp] = 0; + else { + if ((!strcmp(&(texfilename[lenhelp+1]),".mf")) || + (!strcmp(&(texfilename[lenhelp+1]),".MF"))) + texfilename[lenhelp+1] = 0; + } + if ((texfilename[0] > 64) && (texfilename[0] < 91)) + strcat(texfilename, ".TEX"); + else + strcat(texfilename, ".tex"); + } + + } + + /* mainmark2 */ + head.MThd[0] = getc(fp); head.MThd[1] = getc(fp); + head.MThd[2] = getc(fp); head.MThd[3] = getc(fp); head.MThd[4] = '\0'; + if (strcmp(head.MThd, MIDI_FILE_HEADER)) { + fprintf(stderr, "specified file probably not a midi-file or corrupted\n"); + exit(10); + } + + head.chunk_length = 0x1000000 * getc(fp); + head.chunk_length += 0x10000 * getc(fp); + head.chunk_length += 0x100 * getc(fp); + head.chunk_length += getc(fp); + + if (head.chunk_length != 6) { + fprintf(stderr, "wrong header chunk length\n"); + exit(10); + } + + head.format = 0x100 * getc(fp); head.format += getc(fp); + head.tracks = 0x100 * getc(fp); head.tracks += getc(fp); + + /* mainmark3 */ + if (count) { + printf("%d tracks detected\n", head.tracks); + exit(0); + } + + if (printonly && (printonly > head.tracks)) { + printf("can't build tex-file of specified track \n"); + exit(0); + } + + if ((!printonly) && ((head.tracks) > 9)) + fprintf(stderr, "Warning: printing out so many tracks together may look very ugly\n"); + + head.per_quarter = 0x100 * (0xff & getc(fp)); + head.per_quarter += (0xff & getc(fp)); + if (head.format != 1) { + fprintf(stderr, "Format %d not supported\n", head.format); + exit(10); + } + + if (head.per_quarter & 0x8000) { + fprintf(stderr, "SMPTE-Time Code not supported\n"); + exit(10); + } + + /* mainmark4 */ + one64tel = (double) head.per_quarter / 16; + + /* mainmark5 */ + nom0 = 0; + key0 = 0; + notes_flag = 0; + for (lenhelp = 0; lenhelp < MAXTRACKS; lenhelp++) { + Staffs[lenhelp][0]=0; + max[lenhelp]=0; + min[lenhelp]=255; + } + taktzeit = 4 * head.per_quarter; + dyn_init(); + + /* mainmark6 */ + if (!printonly) + for (Track_Nr = 0; Track_Nr < head.tracks; Track_Nr++) { + valid = 0; /* no TimeSig */ + valid2 = 0; /* no KeySig */ + + /* following variables allow event begin only at fixed time-points */ + lastbartime = 0; + bartime = 0; + + firstnotetimeflag = -1; + diskrete_tz = taktzeit; + read_track(); + if (min[Track_Nr] > 0x1f) region[Track_Nr] = 1; + else if (max[Track_Nr] < 0x2a) region[Track_Nr] = 2; + else region[Track_Nr] = 0; +#ifdef DEBUG + printf("region: %x min: %x max: %x\n", region[Track_Nr], min[Track_Nr], max[Track_Nr]); + printf("call now split_notes()\n"); +#endif + split_notes(Track_Nr, head.per_quarter); +#ifdef DEBUG + printf("call now detect_accords()\n"); +#endif + detect_accords(region[Track_Nr], Track_Nr); +#ifdef DEBUG + printf("call now insert_notetimes_and_slurs()\n"); +#endif + insert_notetimes_and_slurs(region[Track_Nr], Track_Nr, head.per_quarter); +#ifdef DEBUG + printf("call now detect_note_positions_with_signs()\n"); +#endif + detect_note_positions_with_signs(Track_Nr); +#ifdef DEBUG + printf("call now set_slur_regions()\n"); +#endif + set_slur_regions(Track_Nr); +#ifdef DEBUG + printf("call now reset_treat_info()\n"); +#endif + reset_treat_info(Track_Nr); +#ifdef DEBUG + printf("call now beam_detect()\n"); +#endif + beam_detect(region[Track_Nr], Track_Nr); +#ifdef DEBUG + printf("call now set_beam_regions()\n"); +#endif + set_beam_regions(Track_Nr); +#ifdef DEBUG + printf("call now reset_treat_info()\n"); +#endif + reset_treat_info(Track_Nr); +#ifdef DEBUG + printf("call now slur_geometry()\n"); +#endif + slur_geometry(Track_Nr); +#ifdef DEBUG + printf("call now detect_rests()\n"); +#endif + detect_rests(Track_Nr, region[Track_Nr], head.per_quarter); +#ifdef DEBUG + printf("call now reset_treat_info()\n"); +#endif + reset_treat_info(Track_Nr); +#ifdef DEBUG + printf("call now beam_geometry()\n"); +#endif + beam_geometry(Track_Nr); +#ifdef DEBUG + printf("call now reset_treat_info()\n"); +#endif + reset_treat_info(Track_Nr); +#ifdef DEBUG + printf("call now calculate_rest_positions()\n"); +#endif + calculate_rest_positions(Track_Nr); +#ifdef DEBUG + printf("call now set_loudness_infos()\n"); +#endif + set_loudness_infos(Track_Nr); + } + else { + for (Track_Nr = 0; Track_Nr < printonly; Track_Nr++) { + valid = 0; /* no TimeSig */ + valid2 = 0; /* no KeySig */ + + /* following variables allow event begin only at fixed time-points */ + lastbartime = 0; + bartime = 0; + + firstnotetimeflag = -1; + diskrete_tz = taktzeit; + read_track(); + } + if ((printonly == 1) && (notes_flag == 0)) { + fprintf(stderr, "sorry, first track is empty\n"); + } + else { + Track_Nr--; + if (min[Track_Nr] > 0x1f) region[Track_Nr] = 1; + else if (max[Track_Nr] < 0x2a) region[Track_Nr] = 2; + else region[Track_Nr] = 0; +#ifdef DEBUG + printf("region: %x min: %x max: %x\n", region[Track_Nr], min[Track_Nr], max[Track_Nr]); +#endif + split_notes(Track_Nr, head.per_quarter); + detect_accords(region[Track_Nr], Track_Nr); + insert_notetimes_and_slurs(region[Track_Nr], Track_Nr, head.per_quarter); + detect_note_positions_with_signs(Track_Nr); + set_slur_regions(Track_Nr); + reset_treat_info(Track_Nr); + beam_detect(region[Track_Nr], Track_Nr); + set_beam_regions(Track_Nr); + reset_treat_info(Track_Nr); + slur_geometry(Track_Nr); + detect_rests(Track_Nr, region[Track_Nr], head.per_quarter); + reset_treat_info(Track_Nr); + beam_geometry(Track_Nr); + reset_treat_info(Track_Nr); + calculate_rest_positions(Track_Nr); + set_loudness_infos(Track_Nr); + } + } + +#ifdef DEBUG + debug_out(); +#endif + /* mainmark7 */ + if ((tfp = fopen(texfilename, "w")) == NULL) { + fprintf(stderr, "cannot open %s\n", texfilename); + exit(10); + } + +#ifdef DEBUG + printf("writing texfile\n"); +#endif + write_texfile(); + fclose(fp); /* close MIDI-file */ + fclose(tfp); /* close TEX-file */ +} |