midifile.h 4.98 KB
//====================================================================
// midifile.h
//
// Synopsis:
//
// Author(s)
//  Steve Shepard
//
// Copyright 1993, Silicon Graphics, Inc.
// All Rights Reserved.
//
// This is UNPUBLISHED PROPRIETARY SOURCE CODE of Silicon Graphics, Inc.;
// the contents of this file may not be disclosed to third parties, copied or
// duplicated in any form, in whole or in part, without the prior written
// permission of Silicon Graphics, Inc.
//
// RESTRICTED RIGHTS LEGEND:
// Use, duplication or disclosure by the Government is subject to restrictions
// as set forth in subdivision (c)(1)(ii) of the Rights in Technical Data
// and Computer Software clause at DFARS 252.227-7013, and/or in similar or
// successor clauses in the FAR, DOD or NASA FAR Supplement. Unpublished -
// rights reserved under the Copyright Laws of the United States.
//====================================================================

#pragma once

#include <stdio.h>

enum MIDIstatus {
    /* For distinguishing channel number from status */
    MIDI_ChannelMask		= 0x0F,
    MIDI_StatusMask		= 0xF0,

    /* Channel voice messages */
    MIDI_ChannelVoice		= 0x80,
    MIDI_NoteOff		= 0x80,
    MIDI_NoteOn			= 0x90,
    MIDI_PolyKeyPressure	= 0xA0,
    MIDI_ControlChange		= 0xB0,
    MIDI_ChannelModeSelect	= 0xB0,
    MIDI_ProgramChange		= 0xC0,
    MIDI_ChannelPressure	= 0xD0,
    MIDI_PitchBendChange	= 0xE0,

    /* System messages */
    MIDI_SysEx			= 0xF0,		/* System Exclusive */

    /* System common */
    MIDI_SystemCommon		= 0xF1,
    MIDI_TimeCodeQuarterFrame	= 0xF1,
    MIDI_SongPositionPointer	= 0xF2,
    MIDI_SongSelect		= 0xF3,
    MIDI_Undefined1		= 0xF4,
    MIDI_Undefined2		= 0xF5,
    MIDI_TuneRequest		= 0xF6,
    MIDI_EOX			= 0xF7,		/* End of System Exclusive */

    /* System real time */
    MIDI_SystemRealTime		= 0xF8,
    MIDI_TimingClock		= 0xF8,
    MIDI_Undefined3		= 0xF9,
    MIDI_Start			= 0xFA,
    MIDI_Continue		= 0xFB,
    MIDI_Stop			= 0xFC,
    MIDI_Undefined4		= 0xFD,
    MIDI_ActiveSensing		= 0xFE,
    MIDI_SystemReset		= 0xFF,
    MIDI_Meta			= 0xFF		/* MIDI Files only */
};

#define IFF_ID_MTHD     'MThd'
#define IFF_ID_MTRK     'MTrk'

typedef struct {
    unsigned long       ckID;
    long                ckSize;
} ChunkHdr;

typedef struct {
    unsigned short      format;
    unsigned short      ntrks;
    unsigned short      division;
} TrackHdr;

class MIDIFile
{
  protected:
    FILE        *file;
    long        curTime;
    TrackHdr    hdr;
    char        lastStatus;
    int         endOfTrack;
    
    /* internal stuff */
    void        parseHeader(void);
    void        parseTrack(void);
    void        writeHeader(short format, short ntracks, short division);
    void        writeMidiEvent(long delta, char status, char b1, char b2);
    void        writeMetaEvent(long delta, char type, char *evt, int len);
    long        to32bit(char c1, char c2, char c3, char c4);
    short       to16bit(int c1, int c2);
    void        metaEvent(int type, char *buf, long len);
    void        channelEvent(int type, char byte1, char byte2);

    void        writeVarLen(long value);
    void        write8bit(int val);
    void        write16bit(int val);
    void        write32bit(long val);

    
    /* misc handlers */
    virtual void midiHeader(TrackHdr *hdr);
    virtual void midiTrackStart(void);
    virtual void midiTrackEnd(void);
    virtual void midiError(char *msg);

    /* 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);
    
    /* write handlers */
    virtual long readVarLen();
    virtual void writeTrack(int track);    
    virtual void midiWriteTempoTrack();
    virtual void midiWriteTrack(int track);
    
public:
    char        *name;
    int         fileSize;

    MIDIFile();
    ~MIDIFile();
    
    int         Open(const char *name, const char *rw);
    int         Close();

    void        Parse();
    void        Write(short format, short tracks, short division);

};