#ifndef __midiparse_h__ #define __midiparse_h__ /* * Copyright 1999 Kelvin W Sherlock * * $Id: midi_parse.h,v 1.2 1999/03/05 21:20:09 baron Exp baron $ * */ typedef unsigned long uint32 ; typedef unsigned short uint16; typedef unsigned char uint8 ; //typedef basic_string IntString; enum MIDI_STATUS { NOTE_OFF = 0x80, NOTE_ON = 0x90, POLY_AFTERTOUCH = 0xa0, CONTROL_CHANGE = 0xb0, PROGRAM_CHANGE = 0xc0, CHANNEL_AFTERTOUCH = 0xd0, PITCH_BEND = 0xe0, SYSTEM_EXCLUSIVE = 0xf0, delay_packet = 1111, //??? /* 7 bit controllers */ damper_pedal = 0x40, portamento = 0x41, sostenuto = 0x42, soft_pedal = 0x43, general_4 = 0x44, hold_2 = 0x45, general_5 = 0x50, general_6 = 0x51, general_7 = 0x52, general_8 = 0x53, tremolo_depth = 0x5c, chorus_depth = 0x5d, detune = 0x5e, phaser_depth = 0x5f, /* parameter values */ data_inc = 0x60, data_dec = 0x61, /* parameter selection */ non_reg_lsb = 0x62, non_reg_msb = 0x63, reg_lsb = 0x64, reg_msb = 0x65, /* Standard MIDI Files meta event definitions */ META_EVENT = 0xFF, SEQUENCE_NUMBER = 0x00, TEXT_EVENT = 0x01, COPYRIGHT_NOTICE = 0x02, SEQUENCE_NAME = 0x03, INSTRUMENT_NAME = 0x04, LYRIC = 0x05, MARKER = 0x06, CUE_POINT = 0x07, CHANNEL_PREFIX = 0x20, //?? END_OF_TRACK = 0x2f, SET_TEMPO = 0x51, SMPTE_OFFSET = 0x54, TIME_SIGNATURE = 0x58, KEY_SIGNATURE = 0x59, SEQUENCER_SPECIFIC = 0x74, }; enum MIDI_ERR { BAD_HEADER = 1, EARLY_EOF, EXIT_OK = 65816, }; const uint32 MTHD = 'MThd'; const uint32 MTRK = 'MTrk'; class midi_parse { public: midi_parse(); virtual ~midi_parse(); int Run(void); //do it! int ReadHeader(void); int ReadTrack(void); /* * Tells time of last event */ uint32 CurrentTime(void) const {return currTime;}; uint32 DeltaTime(void) const {return deltaTime;}; virtual void error(int err_no = -1) {}; /* * these functions are called as needed * when their respective data is gleaned * from the file */ virtual void M_header(int format, int trackCount, int qnDivision) {}; virtual void M_trackstart(uint32 trackLength) {}; virtual void M_trackEnd(void) {}; virtual void M_noteOn(int channel, int note, int velocity) {}; virtual void M_noteOff(int channel, int note, int velocity) {}; virtual void M_pitchBend(int channel, int value) {}; virtual void M_programChange(int channel, int instrument) {}; virtual void M_controlChange(int channel, int controller, int value) {}; virtual void M_polyAfterTouch(int channel, int pitch, int pressure) {};//aka pressure virtual void M_channelAfterTouch(int channel, int pressure) {};//aka channel pressure virtual void M_sysEx(int length, const char *data) {}; virtual void M_metaMisc(int length, const char * data) {}; virtual void M_seqSpecific(int length, const char *msg) {}; virtual void M_seqnum(int num) {}; virtual void M_text(int type, int length, const char *msg) {}; virtual void M_eot(void) {}; virtual void M_timesig(int num, int den, int click, int clock) {}; virtual void M_smpte(int hour, int minute, int second, int frame, int fract_frame) {}; virtual void M_tempo(long tempo) {}; virtual void M_keysig(int sharp_flat, int minor) {}; virtual void M_prefixChannel(int ch) {}; virtual void M_error() {}; /* * routines for writing info * */ virtual void M_writetrack() {}; virtual void M_writetempotrack() {}; virtual void M_write() {}; protected: uint16 Read16(void); uint32 Read32(void); virtual uint8 Read8(void) = 0; void Write16(uint16); void Write32(uint32); virtual void Write8(uint8) = 0; /* * Tell me there was a error reading data */ void SetError(void); private: void WriteVarLength(unsigned long); uint32 ReadVarLength(void); void MetaEvent(int type, uint8 const *data, int dataLength); /* * Data * * */ long currTime; long deltaTime; int format; // midi format 0, 1, 2 int trackCount; // # of tracks int qnDivision; // 1/4 note division bool headerParsed; int currentTrack; int lastError; bool doneTrack; }; #include class midiFILE: public midi_parse { public: midiFILE(); midiFILE(const char *); ~midiFILE(); int SetFile(const char *); protected: virtual uint8 Read8(void); virtual void Write8(uint8); private: FILE *file; int err; }; #endif