midiprint.c++ 6.23 KB
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <bstring.h>
#include <assert.h>
#include <getopt.h>
#include <math.h>

#include "midifile.h"

static char usage[] = "[-v] -o <outfile> <infile>";

int trackNum = 0;

class MIDIPrint : public MIDIFile
{
  protected:
    virtual void midiHeader(TrackHdr *hdr);
    virtual void midiTrackStart(void);
    virtual void midiTrackEnd(void);

    /* Meta Message handlers */
    virtual void midiTempo(long tempo);
    virtual void midiSeqNum(short num);
    virtual void midiText(int type, char *str, int len);
    virtual void midiEndOfTrack();
    virtual void midiSMPTE(char hours, char min, char sec, char fr, char ff);
    virtual void midiTimeSig(char nn, char dd, char cc, char bb);
    virtual void midiKeySig(char sf, char mi);
    virtual void midiSeqSpecific(char *msg, long len);
    virtual void midiMetaMisc(int type, char *msg, long len);

    /* Channel Message handlers */
    virtual void midiNoteOn(char chan, char note, char velocity);
    virtual void midiNoteOff(char chan, char note, char velocity);
    virtual void midiKeyPressure(char chan, char key, char velocity);
    virtual void midiControlChange(char chan, char control, char value);
    virtual void midiPitchBend(char chan, char msb, char lsb);
    virtual void midiProgramChange(char chan, char program);
    virtual void midiChannelPressure(char chan, char pressure);

    /* System exclusive handlers */
    virtual void midiSysEx(char *buffer, int len);
    virtual void midiSysExStart(char *buffer, int len);
};

void main(int argc, char **argv)
{
    int c;
    extern char *optarg;
    extern int  optind;
    int         errflg=0;
    char        *ifile;
    char        *ofile=0;
    int         verbose=0;
    
    while ((c = getopt(argc, argv, "vo:")) != EOF) {        
        switch (c) {
	    case 'v':
                verbose = 1;
		break;
            case 'o':
                ofile = optarg;
                break;
            case '?':
                errflg++;
                break;
        }
    }

    if (errflg || optind == argc) {
        (void)fprintf(stderr, "%s %s\n", argv[0], usage);
        exit (2);
    }

    ifile = argv[optind++];
    if (optind != argc) {
	fprintf(stderr, "warning: only first file (%s) used, rest ignored\n",
	   ifile);
    }

    if (ofile == 0)
        ofile = "tmp.seq";
    
    MIDIPrint *midifile = new MIDIPrint;
    if (!midifile) exit(1);
    midifile->Open(ifile, "r");
    
    midifile->Parse();
    
    midifile->Close();
}

void MIDIPrint::midiHeader(TrackHdr *hdr)
{
    printf("format = %d, num tracks = %d, division = %d\n", hdr->format,
           hdr->ntrks, hdr->division);
}

void MIDIPrint::midiTrackStart(void)
{
    printf("Track %d\n", trackNum);
}

void MIDIPrint::midiTrackEnd(void)
{
    trackNum++;
    printf("\n");
}

/* Meta Message handlers */
void MIDIPrint::midiTempo(long tempo)
{
    printf("time: %8d meta:\t\ttempo = %d usec per quarter note\n",
           curTime, tempo);
}

void MIDIPrint::midiSeqNum(short num)
{
    printf("time: %8d meta:\t\tsequence #%d\n", curTime, num);
}

void MIDIPrint::midiText(int type, char *str, int len)
{
    char *typeStr;
    char *newStr = (char *)malloc(len+1);

    strncpy(newStr, str, len);
    newStr[len] = 0;
    
    switch (type) {
        case (0):
            typeStr = "Sequence Number";
            break;

        case (1):
            typeStr = "Text Event";
            break;

        case (2):
            typeStr = "Copyright";
            break;

        case (3):
            typeStr = "Sequence/Track Name";
            break;

        case (4):
            typeStr = "Instrument Name";
            break;

        case (5):
            typeStr = "Lyric";
            break;

        case (6):
            typeStr = "Marker";
            break;

        case (7):
            typeStr = "Cue Point";
            break;

        default:
            typeStr = "Unknown";
            break;
            
    }
    
    printf("time: %8d meta:\t\t%s (%s)\n", curTime, typeStr, newStr);
}
        
void MIDIPrint::midiEndOfTrack()
{
    printf("time: %8d meta:\t\tend of track\n", curTime);
}

void MIDIPrint::midiSMPTE(char hours, char min, char sec, char fr, char ff)
{
    printf("time: %8d meta:\t\tSMPTE %.2d:%.2d:%.2d:%.2d:%.2d\n", curTime,
           hours, min, sec, fr, ff);
}

void MIDIPrint::midiTimeSig(char , char , char , char )
{
    printf("time: %8d meta:\t\tTime Sig\n", curTime);
}

void MIDIPrint::midiKeySig(char , char )
{
    printf("time: %8d meta:\t\tKey Sig\n", curTime);
}

void MIDIPrint::midiSeqSpecific(char *, long )
{
    printf("time: %8d meta:\fSequence Specific\n", curTime);
}

void MIDIPrint::midiMetaMisc(int type, char *, long )
{
    printf("time: %8d meta:\t\tUnknowd Meta type %d\n", curTime, type);
}


/* Channel Message handlers */
void MIDIPrint::midiNoteOn(char chan, char note, char velocity)
{
    printf("time: %8d note on:\t\tchan %d, key %d, vel %d\n", curTime,
           chan, note, velocity);
}

void MIDIPrint::midiNoteOff(char chan, char note, char velocity)
{
    printf("time: %8d note off:\tchan %d, key %d, vel %d\n", curTime,
           chan, note, velocity);
}

void MIDIPrint::midiKeyPressure(char chan, char key, char velocity)
{
    printf("time: %8d key pressure:\tchan %d, Key %d, pressure %d\n", curTime,
           chan, key, velocity);
}

void MIDIPrint::midiControlChange(char chan, char control, char value)
{
    printf("time: %8d control change:\tchan %d, control %d, value %d\n",
           curTime, chan, control, value);
}

void MIDIPrint::midiPitchBend(char chan, char lsb, char msb)
{
    printf("time: %8d pitch bend:\tchan %d, msb %d, lsb %d (%d)\n",
           curTime, chan, msb, lsb, ((int)(msb & 0x7f) << 7) + (lsb & 0x7f));
}

void MIDIPrint::midiProgramChange(char chan, char program)
{
    printf("time: %8d program change:\tchan %d, program %d\n",
           curTime, chan, program);
}

void MIDIPrint::midiChannelPressure(char chan, char pressure)
{
    printf("time: %8d chan pressure:\tchan %d, pressure %d\n",
           curTime, chan, pressure);
}

/* System exclusive handlers */
void MIDIPrint::midiSysEx(char *, int)
{
    printf("time: %8d system exclusive\n", curTime);
}

void MIDIPrint::midiSysExStart(char *, int)
{
    printf("time: %8d system exclusive start\n", curTime);
}