home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 10 Tools / 10-Tools.zip / midifil2.zip / MIDIFILE.H < prev    next >
Text File  |  1994-07-28  |  19KB  |  442 lines

  1. /* ============================== MIDIFILE.H =================================
  2.  *  C Include file that contains definitions of various structures/constants found within a MIDI
  3.  *  file, and structures/constants used by the MIDIFILE.DLL to read/write MIDI files.
  4.  ========================================================================== */
  5.  
  6.  
  7. /* ===========================================================================
  8.     CALLBACK structure -- allocated and initialized by an app, and passed to the MIDIFILE.DLL
  9.     within the MIDIFILE structure. This contains pointers to various functions within the app to
  10.     handle processing of parts of a MIDI file. The MIDIFILE.DLL calls one of those functions when
  11.     handling its respective part of a MIDI file.
  12.  */
  13.  
  14. typedef long ( EXPENTRY _CALL) ();
  15. typedef _CALL *CALL;
  16.  
  17. typedef struct _CALLBACK
  18. {
  19.   CALL OpenMidi,   /* Opens MIDI file for reading or writing. If 0, then it's assumed that the
  20.              MIDIFILE.DLL will take care of opening the file, and the MIDIFILE
  21.              structure's Handle field contains a pointer to the filename to open. */
  22.   ReadWriteMidi,   /* If reading, this reads the specified number of bytes into the specified
  23.              buffer. If writing, this writes the specified number of bytes within the
  24.              specified buffer. If 0, MIDIFILE.DLL takes care of reading/writing bytes.
  25.               */
  26.   SeekMidi,        /* Seeks forward/backward the specified number of bytes from current position */
  27.   CloseMidi,        /* Closes MIDI file. If 0, MIDIFILE.DLL takes care of closing the file. */
  28.   StartMThd,        /* If reading, called upon load of an Mthd header. If writing, initializes the
  29.             Format, NumTracks, and Division fields of MIDIFILE struct (after which
  30.             MIDIFILE.DLL then writes out the Mthd chunk).
  31.               */
  32.   StartMTrk,        /* If reading, called upon load of an Mtrk header. If writing, the app can use
  33.             this to write app-specific chunks before each MTrk, and set up global
  34.             variables for a particular track. Alternately, the app can use this to have
  35.             the DLL write out a pre-formatted MTrk chunk.
  36.               */
  37.   UnknownChunk,   /* If reading, called upon load of an unknown header. If writing, the app
  38.              should write out the desired app-specific chunk(s) using the DLL's
  39.              MidiWriteHeader(), 1 or more calls to MidiWriteBytes(), and finally
  40.              MidiCloseChunk(). Such chunks appear after all of the MTrks.
  41.               */
  42.   MetaText,        /* If reading, loads in and processes text-based Meta-Event via
  43.              MidiReadBytes(). If writing, writes out the remainder of the Meta-event.
  44.              NOTE: Proprietary Meta-Events (type=0x7F) as well as unknown
  45.              Meta-events are also read/written via this function.
  46.               */
  47.   SysexEvt,        /* For reading, loads in and processes the remainder of the SYSEX event via
  48.              MidiReadBytes(). For writing, writes out the remainder of the SYSEX
  49.              event via MidiWriteBytes(). */
  50.   StandardEvt,        /* If reading, processes loaded MIDI event with status of 0x80 to 0xEF. If
  51.              writing 1 event at a time, reports back to the DLL what event to write.
  52.              First, it sets the MIDIFILE struct's Time field to this event's time (from
  53.              0). Then, for a MIDI event with status of 0x80 to 0xEF, 0xF1, 0xF2,
  54.              0xF3, 0xF6, 0xF8, 0xFA, 0xFB, 0xFC, or 0xFE, stores that status in
  55.              MIDIFILE's Status and the remaining 1 or 2 MIDI data bytes in the Data[0]
  56.              and Data[1] fields. For fixed length Meta-Events (ie, meta type of 0x00,
  57.              0x2F, 0x51, 0x54, 0x58, and 0x59), the Status must be 0xFF, and Data[0]
  58.              must be the meta type. The characters starting at Data[1] must be the rest
  59.              of the message. For example, with the Key Signature event, Data[1] would
  60.              be the length (0x02), Data[2] would be the Key, and Data[3] would be the
  61.              Minor setting. Note that the DLL always sets the length (ie, Data[1]) for
  62.              fixed length Meta-Events. For a Tempo Meta-Event, you have an option.
  63.              Instead of placing the 3 micros bytes in Data[2], Data[3], and Data[4], you
  64.              can alternately place the tempo BPM in Data[2] and set the MIDIFILE's
  65.              Flags MIDIBPM bit. The DLL will format the micros bytes for you.
  66.              If the event to be written is a SYSEX, set Status to 0xF0 or 0xF7, set
  67.              EventSize to the bytes to write (not counting 0xF0), set Time to event's
  68.              time (from 0), and then set a pointer to the data buffer to write in
  69.              Data[2] (ie, ULONG). If the ULONG starting at Data[2] is 0, then the DLL
  70.              will instead call the SysexEvt callback to write out the remaining bytes.
  71.              If the event to be written is a variable length Meta-Event, set Status to
  72.              0xFF, Data[0] is the desired meta type, EventSize to the bytes to
  73.              write (not counting 0xFF and Type), set Time to event's time (from 0),
  74.              then set a pointer to the data buffer to write in Data[2] (ie, ULONG).
  75.              If the ULONG starting at Data[2] is 0, then the DLL will instead call the
  76.              MetaText callback to write out the remaining bytes.
  77.              */
  78.   MetaSeqNum,       /* If reading, processes loaded Sequence Number Meta-Event. If writing,
  79.               returns the METASEQ formatted for a Sequence Number event. NOTE:
  80.               This is the first "event" processing function called when writing out an
  81.               Mtrk chunk, 1 event at a time (ie, it's called one time; before any calls
  82.               to StandardEvt). If NamePtr field is not 0, then this is assumed to be
  83.               a null-terminated string which will be written out as a Track name
  84.               Meta-Event.
  85.               */
  86.   MetaTimeSig,       /* Read only. Processes loaded Time Signature Meta-Event */
  87.   MetaKeySig,        /* Read only. Processes loaded Key Signature Meta-Event */
  88.   MetaTempo,       /* Read only. Processes loaded Tempo Meta-Event */
  89.   MetaSMPTE,      /* Read only. Processes loaded SMPTE Meta-Event */
  90.   MetaEOT;        /* Read only. Processes loaded End Of Track Meta-Event */
  91. } CALLBACK;
  92.  
  93.  
  94. /* ============================================================================
  95.    MIDIFILE structure -- allocated by an app, and passed to the MIDIFILE.DLL in order for the DLL
  96.    to help the app read/write MIDI files). This is also passed to several callbacks.
  97.  */
  98.  
  99. typedef struct _MIDIFILE
  100. {
  101.  CALLBACK * Callbacks; /* Pointer to the Callbacks structure */
  102.  ULONG     Handle;      /* File Handle of the open MIDI file */
  103.  LONG     FileSize;    /* Size of the file. Initially, when the Mthd header is read in, this reflects
  104.                 the number of data bytes in the remainder of the file (ie, after the 8
  105.                 byte Mthd header -- starting at the Mthd's Format). As bytes are read
  106.                 in, this is decremented to reflect how many bytes remain in the file.
  107.                 For writes, this reflects how many bytes the DLL has written out (ie,
  108.                 size of the MIDI file written by the DLL).
  109.              */
  110.  ULONG     ID;          /* ID of the chunk. */
  111.  LONG     ChunkSize;  /* Size of the chunk (Mtrk or Mthd) currently being read. Initially, when
  112.                 the chunk header is read in, this would be the size as specified in the
  113.                 header. As bytes are read in, this is decremented. For writes, this is
  114.                 used for other purposes by the DLL.
  115.              */
  116.  USHORT Format;     /* From Mthd */
  117.  USHORT NumTracks; /* From Mthd */
  118.  USHORT Division;    /* From Mthd */
  119.  USHORT Flags;         /* Flag bits */
  120.  LONG     EventSize;  /* The current event's size. This will be non-zero only if the event is
  121.                 a SYSEX or Meta-Event of variable length. As bytes are read in, this is
  122.                 decremented. For writes, this is used to specify the length of variable
  123.                 length Meta-Events and SYSEX. */
  124.  ULONG    PrevTime;   /* Maintained by DLL. */
  125.  ULONG    Time;         /* The current event's time, referenced from 0 (instead of from the previous
  126.                 event's time as is done with delta-times in the MIDI file) unless
  127.                 MIDIDELTA flag is set.
  128.              */
  129.  UCHAR    TrackNum;   /* The track # that the current event belongs to */
  130.  UCHAR    Status;       /* The event's status. For MIDI events, this is the actual MIDI Status.
  131.                  0xFF for Meta-Event. 0xF7 was sysex continuation.
  132.              */
  133.  UCHAR    Data[7];      /* For MIDI events (other than SYSEX), this will contain the 2 subsequent
  134.                 MIDI data bytes. If there's only 1 data byte, the second byte will be
  135.                 0xFF.
  136.                 For Meta-Events, the first byte will be the Type. For Meta-Events that
  137.                 have a fixed length (ie, Sequence Number, End of Track, Tempo. SMPTE,
  138.                 Time Signature, and Key Signature), the rest of the bytes will be the
  139.                 remainder of that Meta-Event.
  140.                 In other words, the DLL automatically loads MIDI events (except SYSEX)
  141.                 and fixed length Meta-Events directly into the MIDIFILE structure. For
  142.                 Meta-Events of variable length, and SYSEX messages, the DLL loads the
  143.                 Status (0xFF if Meta-Event) and Type (if a Meta-Event), and then loads
  144.                 the variable length quantity bytes that form the Length of the event,
  145.                 setting EventSize to this value. It's up to the app to then load or skip
  146.                 the rest of the event's bytes.
  147.               */
  148.   UCHAR RunStatus;     /* Maintained by DLL */
  149. } MIDIFILE;
  150.  
  151.  
  152. /* MIDIFILE Flags */
  153. #define MIDIWRITE 0x8000 /* Set if callback was called during MidiWriteFile() instead of MidiReadFile() */
  154. #define MIDIBPM   0x4000 /* Set if writing a Tempo Meta-Event, where Data[2] is BPM and
  155.                   DLL calculates micros per quarter */
  156. #define MIDISYSEX 0x2000 /* Set by the DLL when a 0xF0 event is encountered. The DLL doesn't
  157.                   clear this until it encounters a MIDI event with status of 0x80
  158.                   to 0xEF or SYSTEM COMMON. Use this when reading via your SysexEvt
  159.                   callback to help you distinguish SYSEX continuation events from
  160.                   ESCAPED events, both of which have a 0xF7 Status. If an ESCAPED
  161.                   event, the first data byte that you MidiReadBytes() in your
  162.                   SysexEvt callback should be a MIDI REALTIME or SYSTEM
  163.                   COMMON status (bit #7 set). A continuation event can ONLY occur
  164.                   when this flag is set, and it's very unlikely that the first data byte
  165.                   will have bit #7 set (unless it happens to also be 0xF7, unlikely). */
  166. #define MIDIDENOM 0x1000 /* When reading/writing a Time Signature Meta-Event, the
  167.                    denominator isn't expressed as a power of 2, but rather, as the
  168.                    real time sig denominator. In other words for 4/4, instead of a
  169.                    Denom of 2, it's 4. */
  170. #define MIDIDELTA 0x0800 /* Time field is delta instead of referenced from 0 */
  171. #define MIDIREALTIME 0x0400 /* Set this if you want MIDI REALTIME to not cancel running
  172.                       status. This will yield more compression if you're saving
  173.                       REALTIME events (ie, via an ESCAPE event) intermixed with
  174.                       regular MIDI messages. But, some software doesn't follow the
  175.                       MIDI spec with regard to REALTIME not affecting running
  176.                       status, so this is made optional. */
  177. #define MIDIDIRTY 0x0200 /* Don't alter this if not using your own ReadWriteMidi callback.
  178.                      The DLL uses it for an intelligent File I/O buffering */
  179.  
  180. /* ============================================================================
  181.    METATEMPO structure -- Passed by DLL to the app's MetaTempo callback. Most of the fields
  182.    are the same as the app's MIDIFILE structure with a few, noted exceptions. This is just a
  183.    redefinition of the MIDIFILE specifically for Tempo Meta-Events in order to fool the compiler
  184.    into seeing certain fields that were defined as UCHAR in MIDIFILE as ULONG in METATEMPO.
  185.    Used for both reading and writing.
  186.  */
  187.  
  188. typedef struct _METATEMPO
  189. {
  190.  CALLBACK * Callbacks;
  191.  ULONG     Handle;
  192.  LONG     FileSize;
  193.  ULONG     ID;
  194.  LONG     ChunkSize;
  195.  USHORT Format;
  196.  USHORT NumTracks;
  197.  USHORT Division;
  198.  USHORT Flags;
  199.  ULONG     UnUsed1;   /* NOTE: EventSize not used for read/write of Tempo events */
  200.  ULONG    PrevTime;
  201.  ULONG    Time;
  202.  UCHAR    TrackNum;
  203.  UCHAR    Type;        /* Meta Type (ie, 0x51) for reads. 0xFF for writes */
  204.  UCHAR    WriteType;  /* Length (3) for reads. 0x51 for writes. */
  205.  UCHAR    Length;      /* Don't use */
  206.  ULONG    Tempo;        /* Tempo in micros per quarter note */
  207.  UCHAR    TempoBPM; /* Tempo in Beats Per Minute */
  208.  UCHAR    RunStatus;
  209. } METATEMPO;
  210.  
  211.  
  212.  
  213. /* ============================================================================
  214.    METASEQ structure -- Passed by DLL to the app's MetaSeqNum callback. This is used by both
  215.    reading and writing.
  216.  */
  217.  
  218. typedef struct _METASEQ
  219. {
  220.  CALLBACK * Callbacks;
  221.  ULONG     Handle;
  222.  LONG     FileSize;
  223.  ULONG     ID;
  224.  LONG     ChunkSize;
  225.  USHORT Format;
  226.  USHORT NumTracks;
  227.  USHORT Division;
  228.  USHORT Flags;
  229.  UCHAR * NamePtr;   /* For writing, ptr to the null-terminated Track Name to write as a
  230.                 Meta-Event following the Sequence Number Meta-Event, or 0 if none */
  231.  ULONG    PrevTime;
  232.  ULONG    Time;
  233.  UCHAR    TrackNum;
  234.  UCHAR    Type;         /* Meta type (0x00) for reads. 0xFF for writes */
  235.  UCHAR    WriteType;  /* Length (2) for reads. Meta type (0x00) for writes */
  236.  UCHAR    Length;      /* Don't use */
  237.  USHORT SeqNum;    /* Sequence number */
  238.  UCHAR    UnUsed2, UnUsed3, UnUsed4;
  239.  UCHAR    RunStatus;
  240. } METASEQ;
  241.  
  242.  
  243.  
  244. /* ============================================================================
  245.    METASMPTE structure -- Passed by DLL to the app's MetaSMPTE callback.
  246.  */
  247.  
  248. typedef struct _METASMPTE
  249. {
  250.  CALLBACK * Callbacks;
  251.  ULONG     Handle;
  252.  LONG     FileSize;
  253.  ULONG     ID;
  254.  LONG     ChunkSize;
  255.  USHORT Format;
  256.  USHORT NumTracks;
  257.  USHORT Division;
  258.  USHORT Flags;
  259.  ULONG     UnUsed1;
  260.  ULONG     PrevTime;
  261.  ULONG    Time;
  262.  UCHAR    TrackNum;
  263.  UCHAR    Type;        /* Meta Type 0x54 for reads. 0xFF for writes. */
  264.  UCHAR    WriteType; /* Length (5) for reads. Meta type 0x54 for writes */
  265.  UCHAR    Length;     /* Don't use */
  266.  UCHAR    Hours;        /* SMPTE Hours */
  267.  UCHAR    Minutes;    /* SMPTE Minutes */
  268.  UCHAR    Seconds;   /* SMPTE Secs */
  269.  UCHAR    Frames;    /* SMPTE Frames */
  270.  UCHAR    SubFrames; /* SMPTE SubFrames */
  271.  UCHAR    RunStatus;
  272. } METASMPTE;
  273.  
  274.  
  275.  
  276. /* ============================================================================
  277.    METATIME structure -- Passed by DLL to the app's MetaTimeSig callback.
  278.  */
  279.  
  280. typedef struct _METATIME
  281. {
  282.  CALLBACK * Callbacks;
  283.  ULONG     Handle;
  284.  LONG     FileSize;
  285.  ULONG     ID;
  286.  LONG     ChunkSize;
  287.  USHORT Format;
  288.  USHORT NumTracks;
  289.  USHORT Division;
  290.  USHORT Flags;
  291.  LONG     UnUsed1;
  292.  ULONG    PrevTime;
  293.  ULONG    Time;
  294.  UCHAR    TrackNum;
  295.  UCHAR    Type;        /* Meta Type 0x58 for reads. 0xFF for writes */
  296.  UCHAR    WriteType;  /* Length (4) for reads. Meta Type 0x58 for writes */
  297.  UCHAR    Length;      /* Don't use */
  298.  UCHAR    Nom;        /* Time sig nominator */
  299.  UCHAR    Denom;       /* Time sig denominator */
  300.  UCHAR    Clocks;     /* MIDI clocks in metronome click */
  301.  UCHAR    _32nds;    /* number of 32nd notes in 24 MIDI clocks */
  302.  UCHAR    UnUsed2;
  303.  UCHAR    RunStatus;
  304. } METATIME;
  305.  
  306.  
  307.  
  308. /* ============================================================================
  309.    METAKEY structure -- Passed by DLL to the app's MetaKeySig callback.
  310.  */
  311.  
  312. typedef struct _METAKEY
  313. {
  314.  CALLBACK * Callbacks;
  315.  ULONG     Handle;
  316.  LONG     FileSize;
  317.  ULONG     ID;
  318.  LONG     ChunkSize;
  319.  USHORT Format;
  320.  USHORT NumTracks;
  321.  USHORT Division;
  322.  USHORT Flags;
  323.  LONG     UnUsed1;
  324.  ULONG    PrevTime;
  325.  ULONG    Time;
  326.  UCHAR    TrackNum;
  327.  UCHAR    Type;        /* For reads, Meta Type 0x59. 0xFF for writes */
  328.  UCHAR    WriteType; /* Length (2) for reads. meta type 0x59 for writes */
  329.  UCHAR    Length;     /* Don't use */
  330.  CHAR     Key;         /* -7 for 7 flats... 0 for C... 7 for 7 sharps */
  331.  UCHAR    Minor;        /* 0=Major, 1=Minor */
  332.  UCHAR    UnUsed2, UnUsed3, UnUsed4;
  333.  UCHAR    RunStatus;
  334. } METAKEY;
  335.  
  336.  
  337.  
  338. /* ============================================================================
  339.    METAEND structure -- Passed by DLL to the app's MetaEOT callback.
  340.  */
  341.  
  342. typedef struct _METAEND
  343. {
  344.  CALLBACK * Callbacks;
  345.  ULONG     Handle;
  346.  LONG     FileSize;
  347.  ULONG     ID;
  348.  LONG     ChunkSize;
  349.  USHORT Format;
  350.  USHORT NumTracks;
  351.  USHORT Division;
  352.  USHORT Flags;
  353.  LONG     UnUsed1;
  354.  ULONG    PrevTime;
  355.  ULONG    Time;
  356.  UCHAR    TrackNum;
  357.  UCHAR    Type;        /* For reads, Meta Type 0x2F. 0xFF for writes */
  358.  UCHAR    WriteType; /* Length (0) for reads. Meta type 0x2F for writes */
  359.  UCHAR    Length;     /* Don't use */
  360.  UCHAR    UnUsed2, UnUsed3, UnUsed4, UnUsed5, UnUsed6;
  361.  UCHAR    RunStatus;
  362. } METAEND;
  363.  
  364.  
  365. /* ============================================================================
  366.    METATXT structure -- Used by app when formatting SYSEX and MetaText events for writing.
  367.  */
  368.  
  369. typedef struct _METATXT
  370. {
  371.  CALLBACK * Callbacks;
  372.  ULONG     Handle;
  373.  LONG     FileSize;
  374.  ULONG     ID;
  375.  LONG     ChunkSize;
  376.  USHORT Format;
  377.  USHORT NumTracks;
  378.  USHORT Division;
  379.  USHORT Flags;
  380.  ULONG    EventSize;  /* Size of buffer to write out */
  381.  ULONG    PrevTime;
  382.  ULONG    Time;
  383.  UCHAR    TrackNum;
  384.  UCHAR    Type;        /* 0xFF for MetaText, 0xF0 or 0xF7 for SYSEX */
  385.  UCHAR    WriteType;  /* MetaType for MetaText events. */
  386.  UCHAR    Length;    /* Don't use */
  387.  UCHAR * Ptr;         /* Pointer to buffer to write out */
  388.  UCHAR    UnUsed2;
  389.  UCHAR    RunStatus;
  390. } METATXT;
  391.  
  392.  
  393.  
  394. /* =========================================================================
  395.  * Errors returned by the DLL's MidiReadFile() and MidiWriteFile()
  396.  */
  397.  
  398. #define MIDIERRFILE    1  /* Can't open the MIDI file for reading/writing */
  399. #define MIDIERRINFO    2  /* Can't determine the FileSize for reading */
  400. #define MIDIERRNOMIDI 3  /* Tried to read a file that didn't contain a required MThd */
  401. #define MIDIERRREAD   4  /* An error while reading bytes from the file */
  402. #define MIDIERRWRITE  5  /* An error while writing bytes to the file */
  403. #define MIDIERRBAD     6  /* A mal-formed MIDI file -- it's garbage */
  404. #define MIDIERRSTATUS 7  /* Encountered running status where it shouldn't be. (mal-formed MTrk) */
  405. #define MIDIERREVENT   8  /* Encountered an unknown Status while reading in an MTrk.
  406.                    Not a Meta-Event, but not a MIDI event either. */
  407. #define MIDIAPPERR     9   /* App defined errors start with this if positive, or can be
  408.                     negative numbers (except for -1 for ReadWriteMidi callback) */
  409.  
  410.  
  411. /* ==========================================================================
  412.  * The MIDIFILE.DLL functions
  413.  */
  414.  
  415.  /* reading */
  416. extern LONG EXPENTRY MidiReadFile(MIDIFILE * mf);
  417. extern LONG EXPENTRY MidiReadBytes(MIDIFILE * mf, UCHAR * buf, ULONG count);
  418. extern VOID EXPENTRY MidiSkipChunk(MIDIFILE * mf);
  419. extern VOID EXPENTRY MidiSkipEvent(MIDIFILE * mf);
  420. extern LONG EXPENTRY MidiReadVLQ(MIDIFILE * mf);
  421. extern LONG EXPENTRY MidiReadHeader(MIDIFILE * mf);
  422.  
  423.  /* writing */
  424. extern LONG EXPENTRY MidiWriteBytes(MIDIFILE * mf, UCHAR * buf, ULONG count);
  425. extern LONG EXPENTRY MidiWriteVLQ(MIDIFILE * mf, ULONG val);
  426. extern LONG EXPENTRY MidiWriteHeader(MIDIFILE * mf);
  427. extern LONG EXPENTRY MidiWriteFile(MIDIFILE * mf);
  428. extern LONG EXPENTRY MidiCloseChunk(MIDIFILE * mf);
  429. extern LONG EXPENTRY MidiWriteEvt(MIDIFILE * mf);
  430.  
  431.  /* misc */
  432. extern VOID EXPENTRY MidiSeek(MIDIFILE * mf, LONG amt);
  433. extern LONG EXPENTRY MidiFileSize(MIDIFILE * mf);
  434. extern VOID EXPENTRY MidiFlipLong(UCHAR * ptr);
  435. extern VOID EXPENTRY MidiFlipShort(UCHAR * ptr);
  436. extern BOOL EXPENTRY MidiCompareID(UCHAR * id, UCHAR * ptr);
  437. extern VOID EXPENTRY MidiCloseFile(MIDIFILE * mf);
  438. extern LONG EXPENTRY MidiVLQToLong(UCHAR * ptr, ULONG * len);
  439. extern ULONG EXPENTRY MidiLongToVLQ(ULONG val, UCHAR * ptr);
  440. extern ULONG EXPENTRY MidiGetErr(MIDIFILE * mf, LONG err, UCHAR * buf);
  441.  
  442.