268 lines
7 KiB
C
268 lines
7 KiB
C
/*
|
|
THE COMPUTER CODE CONTAINED HEREIN IS THE SOLE PROPERTY OF PARALLAX
|
|
SOFTWARE CORPORATION ("PARALLAX"). PARALLAX, IN DISTRIBUTING THE CODE TO
|
|
END-USERS, AND SUBJECT TO ALL OF THE TERMS AND CONDITIONS HEREIN, GRANTS A
|
|
ROYALTY-FREE, PERPETUAL LICENSE TO SUCH END-USERS FOR USE BY SUCH END-USERS
|
|
IN USING, DISPLAYING, AND CREATING DERIVATIVE WORKS THEREOF, SO LONG AS
|
|
SUCH USE, DISPLAY OR CREATION IS FOR NON-COMMERCIAL, ROYALTY OR REVENUE
|
|
FREE PURPOSES. IN NO EVENT SHALL THE END-USER USE THE COMPUTER CODE
|
|
CONTAINED HEREIN FOR REVENUE-BEARING PURPOSES. THE END-USER UNDERSTANDS
|
|
AND AGREES TO THE TERMS HEREIN AND ACCEPTS THE SAME BY USE OF THIS FILE.
|
|
COPYRIGHT 1993-1999 PARALLAX SOFTWARE CORPORATION. ALL RIGHTS RESERVED.
|
|
*/
|
|
|
|
|
|
|
|
#ifndef _MIDIFILE_H
|
|
#define _MIDIFILE_H
|
|
|
|
#include "global.h"
|
|
|
|
typedef DWORD SMFRESULT;
|
|
typedef DWORD TICKS;
|
|
typedef TICKS FAR *PTICKS;
|
|
typedef BYTE HUGE *HPBYTE;
|
|
|
|
#define MAX_TICKS ((TICKS)0xFFFFFFFFL)
|
|
|
|
#define SMF_SUCCESS (0L)
|
|
#define SMF_INVALID_FILE (1L)
|
|
#define SMF_NO_MEMORY (2L)
|
|
#define SMF_OPEN_FAILED (3L)
|
|
#define SMF_INVALID_TRACK (4L)
|
|
#define SMF_META_PENDING (5L)
|
|
#define SMF_ALREADY_OPEN (6L)
|
|
#define SMF_END_OF_TRACK (7L)
|
|
#define SMF_NO_META (8L)
|
|
#define SMF_INVALID_PARM (9L)
|
|
#define SMF_INVALID_BUFFER (10L)
|
|
#define SMF_END_OF_FILE (11L)
|
|
#define SMF_REACHED_TKMAX (12L)
|
|
|
|
DECLARE_HANDLE(HSMF);
|
|
|
|
typedef struct tag_smfopenstruct
|
|
{
|
|
LPSTR pstrName;
|
|
DWORD dwTimeDivision;
|
|
HSMF hSmf;
|
|
} SMFOPENFILESTRUCT,
|
|
FAR *PSMFOPENFILESTRUCT;
|
|
|
|
extern SMFRESULT FNLOCAL smfOpenFile(
|
|
BYTE *data, UINT length, HSMF *pph);
|
|
|
|
extern SMFRESULT FNLOCAL smfCloseFile(
|
|
HSMF hsmf);
|
|
|
|
typedef struct tag_smffileinfo
|
|
{
|
|
DWORD dwTracks;
|
|
DWORD dwFormat;
|
|
DWORD dwTimeDivision;
|
|
TICKS tkLength;
|
|
} SMFFILEINFO,
|
|
FAR *PSMFFILEINFO;
|
|
|
|
extern SMFRESULT FNLOCAL smfGetFileInfo(
|
|
HSMF hsmf,
|
|
PSMFFILEINFO psfi);
|
|
|
|
extern DWORD FNLOCAL smfTicksToMillisecs(
|
|
HSMF hsmf,
|
|
TICKS tkOffset);
|
|
|
|
extern DWORD FNLOCAL smfMillisecsToTicks(
|
|
HSMF hsmf,
|
|
DWORD msOffset);
|
|
|
|
extern SMFRESULT FNLOCAL smfReadEvents(
|
|
HSMF hsmf,
|
|
LPMIDIHDR lpmh,
|
|
TICKS tkMax);
|
|
|
|
extern SMFRESULT FNLOCAL smfSeek(
|
|
HSMF hsmf,
|
|
TICKS tkPosition,
|
|
LPMIDIHDR lpmh);
|
|
|
|
extern DWORD FNLOCAL smfGetStateMaxSize(
|
|
void);
|
|
|
|
/* Buffer described by LPMIDIHDR is in polymsg format, except that it
|
|
** can contain meta-events (which will be ignored during playback by
|
|
** the current system). This means we can use the pack functions, etc.
|
|
*/
|
|
#define PMSG_META ((BYTE)0xC0)
|
|
|
|
|
|
|
|
|
|
/*****************************************************************************/
|
|
/*****************************************************************************/
|
|
|
|
|
|
/* Handle structure for HSMF
|
|
*/
|
|
|
|
#define SMF_TF_EOT 0x00000001L
|
|
#define SMF_TF_INVALID 0x00000002L
|
|
|
|
typedef struct tag_tempomapentry
|
|
{
|
|
TICKS tkTempo;
|
|
DWORD msBase;
|
|
DWORD dwTempo;
|
|
} TEMPOMAPENTRY,
|
|
*PTEMPOMAPENTRY;
|
|
|
|
typedef struct tag_smf *PSMF;
|
|
|
|
typedef struct tag_track
|
|
{
|
|
PSMF pSmf;
|
|
|
|
DWORD idxTrack;
|
|
|
|
TICKS tkPosition;
|
|
DWORD cbLeft;
|
|
HPBYTE hpbImage;
|
|
BYTE bRunningStatus;
|
|
|
|
DWORD fdwTrack;
|
|
|
|
struct
|
|
{
|
|
TICKS tkLength;
|
|
DWORD cbLength;
|
|
}
|
|
smti;
|
|
|
|
} TRACK,
|
|
*PTRACK;
|
|
|
|
#define SMF_F_EOF 0x00000001L
|
|
#define SMF_F_INSERTSYSEX 0x00000002L
|
|
|
|
#define C_TEMPO_MAP_CHK 16
|
|
typedef struct tag_smf
|
|
{
|
|
char szName[128];
|
|
HPBYTE hpbImage;
|
|
DWORD cbImage;
|
|
HTASK htask;
|
|
|
|
TICKS tkPosition;
|
|
TICKS tkLength;
|
|
DWORD dwFormat;
|
|
DWORD dwTracks;
|
|
DWORD dwTimeDivision;
|
|
DWORD fdwSMF;
|
|
|
|
DWORD cTempoMap;
|
|
DWORD cTempoMapAlloc;
|
|
HLOCAL hTempoMap;
|
|
PTEMPOMAPENTRY pTempoMap;
|
|
|
|
DWORD dwPendingUserEvent;
|
|
DWORD cbPendingUserEvent;
|
|
HPBYTE hpbPendingUserEvent;
|
|
|
|
TRACK rTracks[];
|
|
} SMF;
|
|
|
|
typedef struct tagEVENT
|
|
{
|
|
TICKS tkDelta;
|
|
BYTE abEvent[3];
|
|
|
|
|
|
|
|
DWORD cbParm;
|
|
HPBYTE hpbParm;
|
|
} EVENT,
|
|
BSTACK *SPEVENT;
|
|
|
|
#define EVENT_TYPE(event) ((event).abEvent[0])
|
|
#define EVENT_CH_B1(event) ((event).abEvent[1])
|
|
#define EVENT_CH_B2(event) ((event).abEvent[2])
|
|
|
|
#define EVENT_META_TYPE(event) ((event).abEvent[1])
|
|
|
|
SMFRESULT FNLOCAL smfBuildFileIndex(
|
|
PSMF BSTACK * ppsmf);
|
|
|
|
DWORD FNLOCAL smfGetVDword(
|
|
HPBYTE hpbImage,
|
|
DWORD dwLeft,
|
|
DWORD BSTACK * pdw);
|
|
|
|
SMFRESULT FNLOCAL smfGetNextEvent(
|
|
PSMF psmf,
|
|
SPEVENT pevent,
|
|
TICKS tkMax);
|
|
|
|
/*
|
|
** Useful macros when dealing with hi-lo format integers
|
|
*/
|
|
#define DWORDSWAP(dw) \
|
|
((((dw)>>24)&0x000000FFL)|\
|
|
(((dw)>>8)&0x0000FF00L)|\
|
|
(((dw)<<8)&0x00FF0000L)|\
|
|
(((dw)<<24)&0xFF000000L))
|
|
|
|
#define WORDSWAP(w) \
|
|
((((w)>>8)&0x00FF)|\
|
|
(((w)<<8)&0xFF00))
|
|
|
|
#define FOURCC_RMID mmioFOURCC('R','M','I','D')
|
|
#define FOURCC_data mmioFOURCC('d','a','t','a')
|
|
#define FOURCC_MThd mmioFOURCC('M','T','h','d')
|
|
#define FOURCC_MTrk mmioFOURCC('M','T','r','k')
|
|
|
|
typedef struct tag_chunkhdr
|
|
{
|
|
FOURCC fourccType;
|
|
DWORD dwLength;
|
|
} CHUNKHDR,
|
|
*PCHUNKHDR;
|
|
|
|
#pragma pack(1) // override cl32 default packing, to match disk file.
|
|
typedef struct tag_filehdr
|
|
{
|
|
WORD wFormat;
|
|
WORD wTracks;
|
|
WORD wDivision;
|
|
} FILEHDR,
|
|
*PFILEHDR;
|
|
#pragma pack()
|
|
|
|
/* NOTE: This is arbitrary and only used if there is a tempo map but no
|
|
** entry at tick 0.
|
|
*/
|
|
#define MIDI_DEFAULT_TEMPO (500000L)
|
|
|
|
#define MIDI_MSG ((BYTE)0x80)
|
|
#define MIDI_NOTEOFF ((BYTE)0x80)
|
|
#define MIDI_NOTEON ((BYTE)0x90)
|
|
#define MIDI_POLYPRESSURE ((BYTE)0xA0)
|
|
#define MIDI_CONTROLCHANGE ((BYTE)0xB0)
|
|
#define MIDI_PROGRAMCHANGE ((BYTE)0xC0)
|
|
#define MIDI_CHANPRESSURE ((BYTE)0xD0)
|
|
#define MIDI_PITCHBEND ((BYTE)0xE0)
|
|
#define MIDI_META ((BYTE)0xFF)
|
|
#define MIDI_SYSEX ((BYTE)0xF0)
|
|
#define MIDI_SYSEXEND ((BYTE)0xF7)
|
|
|
|
#define MIDI_META_TRACKNAME ((BYTE)0x03)
|
|
#define MIDI_META_EOT ((BYTE)0x2F)
|
|
#define MIDI_META_TEMPO ((BYTE)0x51)
|
|
#define MIDI_META_TIMESIG ((BYTE)0x58)
|
|
#define MIDI_META_KEYSIG ((BYTE)0x59)
|
|
#define MIDI_META_SEQSPECIFIC ((BYTE)0x7F)
|
|
|
|
|
|
|
|
|
|
#endif
|