www.pudn.com > readmidifile.rar > rdmid.h


/*
    rdmid.h version 0.10, march 18, 2004.
    C API headerfile. Include this file in your sourcefile.

    RDMID, a MIDI file parser.
    Latest version available at: http://www.hku.nl/~pieter/EDU/c/rdmid/

    Copyright (c) 2004 Pieter Suurmond

    Permission is hereby granted, free of charge, to any person obtaining
    a copy of this software and associated documentation files
    (the "Software"), to deal in the Software without restriction,
    including without limitation the rights to use, copy, modify, merge,
    publish, distribute, sublicense, and/or sell copies of the Software,
    and to permit persons to whom the Software is furnished to do so,
    subject to the following conditions:

    The above copyright notice and this permission notice shall be
    included in all copies or substantial portions of the Software.

    Any person wishing to distribute modifications to the Software is
    requested to send the modifications to the original developer so that
    they can be incorporated into the canonical version.

    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR
    ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
    CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
    WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.


      - Portable ISO/ANSI C.
      - Thread-safe, no global variables, no static data.
      - Endian-safe (no endian-awareness though).
      - Memory-safe (needs revision or test).
      - Reads standard MIDI file formats 0, 1 and 2, accept sysex of any 
        length (below 2^31).


    The one and only function that you have to call is rdmid(). As first
    argument, you may supply anything you like, it will be passed to all your
    event handlers, whenever they are called. The second argument should be a 
    file pointer. Before calling, you must thus open a standard MIDI file 
    yourself, and, of course, after returning from rdmid() you must close it.
*/

int rdmid(void* userdata,
          FILE* fp,
          int   no_sysex_merge,
          /* The following 21 arguments are function pointers to your event handlers (or NULL). */
          /* 3 handlers for header and tracks: */
          int   (*eh_header)    (void* userdata, int format,               /* 0, 1 or 2. */
                                                 int tracks,
                                                 int division),
          int   (*eh_trackstart)(void* userdata, int track),
          int   (*eh_trackend)  (void* userdata, int track),
          /* 7 channel messages: */                                        /* 0 <= time < 2^31.    */
          int   (*eh_note_off)  (void* userdata, long time, int channel,   /* 0 <= channel < 16.   */
                                                            int note,      /* 0 <= note < 128.     */
                                                            int velocity), /* 0 <= velocity < 128. */
          int   (*eh_note_on)   (void* userdata, long time, int channel,
                                                            int note,
                                                            int velocity),
          int   (*eh_poly_press)(void* userdata, long time, int channel,
                                                            int note,
                                                            int pressure), /* 0 <= pressure < 128. */
          int   (*eh_controller)(void* userdata, long time, int channel,
                                                            int number,    /* 0 <= number < 128.   */
                                                            int value),    /* 0 <= value < 128.    */
          int   (*eh_program)   (void* userdata, long time, int channel,
                                                            int number),
          int   (*eh_chan_press)(void* userdata, long time, int channel,
                                                            int pressure),
          int   (*eh_pitchbend) (void* userdata, long time, int channel,
                                                            int bend),     /* -8192 <= bend < 8192.*/
          /* 1 system exclusive message: */
          int   (*eh_sysex)     (void* userdata, long time, long  length,
                                                            char* data),
          /* 10 meta events: */
          int   (*eh_seqnum)    (void* userdata, long time, int   number), /* 0 <= number < 65536. */
          int   (*eh_text)      (void* userdata, long time, int   type,
                                                            long  length,
                                                            char* data),
          int   (*eh_eot)       (void* userdata, long time),              /* End of track. */
          int   (*eh_tempo)     (void* userdata, long time, long  tempo), /* 0 <= tempo < 1677716. */
                                                                          /* microsecs/qrter note. */
          int   (*eh_smpte)     (void* userdata, long time, int   hour,
                                                            int   min,
                                                            int   sec,
                                                            int   frame,
                                                            int   frac),
          int   (*eh_timesig)   (void* userdata, long time, int   numer,
                                                            int   denom,   /* 1, 2, 4, 8, etc. */
                                                            int   mclck,
                                                            int   m32),    /* Often 8. */
          int   (*eh_keysig)    (void* userdata, long time, int   sharps,  /* -7 <= sharps <= +7. */
                                                            int   minor),  /* 0=major; 1=minor.   */
          int   (*eh_seq_spec)  (void* userdata, long time, long  length,
                                                            char* data),
          int   (*eh_metamisc)  (void* userdata, long time, int   type,
                                                            long  length,
                                                            char* data),
          int   (*eh_arbitrary) (void* userdata, long time, long  length,
                                                            char* data)
         );
/*
    Here is what rdmid() returns:
*/
#define RDMID_OK          (0) /* No errors, all went well. */
#define RDMID_USER_TERM   (1) /* User's callback stopped parser by returning non-zero. */
#define RDMID_EOF         (2) /* Premature end of file. */
#define RDMID_CHUNK_END   (3) /* Premature end of chunk. */
#define RDMID_BAD_MT      (4) /* Wrong 'MThd' or 'MTrk' in header or track. */
#define RDMID_BAD_BYTE    (5) /* Unexpected byte in track. */
#define RDMID_SYSEX_CONT  (6) /* Didn't find expected continuation of sysex. */
#define RDMID_RUN_STATUS  (7) /* Unexpected running status. */
#define RDMID_TOO_BIG     (8) /* When a variable length number exceeds 4 bytes,
                                 when current time exceeds 31 bits, or when a
                                 sysex or meta message's length exceeds 31 bits. */
#define RDMID_MEM_FAIL    (9) /* Memory allocation failure. */
#define RDMID_BAD_INTS   (10) /* When sizes of integers are insufficient. */