370 lines
13 KiB
C
370 lines
13 KiB
C
/*******************************Module*Header*********************************
|
|
* Module Name: mmseqi.h
|
|
*
|
|
* MultiMedia Systems MIDI Sequencer DLL Internal prototypes and data struct's
|
|
*
|
|
* Created: 4/10/90
|
|
* Author: GREGSI
|
|
*
|
|
* History:
|
|
*
|
|
* Copyright (c) 1985-1998 Microsoft Corporation
|
|
*
|
|
\****************************************************************************/
|
|
/*****************************************************************************
|
|
*
|
|
* Constants
|
|
*
|
|
****************************************************************************/
|
|
//#define SEQDEBUG 1
|
|
|
|
// max. tracks allowed in a sequence
|
|
|
|
#define MAXTRACKS 100
|
|
|
|
// MIDI real time data:
|
|
|
|
#define SysExCode 257
|
|
#define MetaEventCode 258
|
|
|
|
#define METAEVENT 0XFF
|
|
#define SYSEX 0XF0
|
|
#define SYSEXF7 0XF7
|
|
#define PROGRAMCHANGE 0xC0
|
|
|
|
// packet codes: these are flags
|
|
|
|
#define LASTPACKET 0X1
|
|
#define FIRSTPACKET 0X2
|
|
|
|
// META EVENT TYPES
|
|
|
|
#define ENDOFTRACK 0X2F
|
|
#define TEMPOCHANGE 0X51
|
|
#define SMPTEOFFSET 0X54
|
|
#define TIMESIG 0X58
|
|
#define SEQSTAMP 0X7F
|
|
|
|
// PORT TYPES
|
|
|
|
#define TRACKPORT 0
|
|
#define OUTPORT 1
|
|
#define CONTROLPORT 2
|
|
#define METAPORT 3
|
|
|
|
/* fileStatus codes */
|
|
|
|
#define NoErr 256
|
|
#define EndOfStream 257
|
|
#define AllTracksEmpty 258
|
|
#define OnlyBlockedTracks 259
|
|
#define AtLimit 260
|
|
#define InSysEx 261
|
|
|
|
/* Blocking types */
|
|
|
|
#define not_blocked 0
|
|
|
|
// these imply that you're blocked on input (waiting for free input buffer)
|
|
|
|
#define between_msg_out 270
|
|
#define in_rewind_1 271
|
|
#define in_rewind_2 272
|
|
#define in_ScanEarlyMetas 273
|
|
#define in_Normal_Meta 274
|
|
#define in_SysEx 275
|
|
#define in_Seek_Tick 276
|
|
#define in_Seek_Meta 277
|
|
#define in_SkipBytes_Seek 278
|
|
#define in_SkipBytes_ScanEM 279
|
|
#define in_SkipBytes_Play 280
|
|
|
|
/* Generic types -- used temporarily at a low level */
|
|
#define on_input 350
|
|
|
|
// End of blocking types.
|
|
|
|
#define NAMELENGTH 32
|
|
|
|
/*
|
|
codes to pass to SendAllEventB4 (called in normal course of playing, and
|
|
by song pointer code for chase-lock)
|
|
*/
|
|
|
|
#define MODE_SEEK_TICKS 1
|
|
#define MODE_PLAYING 2
|
|
#define MODE_SILENT 3
|
|
#define MODE_SCANEM 4
|
|
|
|
|
|
// Code to hold in seq->SeekTickToBe when there is no seek pending
|
|
|
|
#define NotInUse ((DWORD)-1L)
|
|
|
|
/* delta-time escapes ("legal" deltas only use 28 bits) */
|
|
|
|
#define MAXDelta 0X8FFFFFFF
|
|
#define TrackEmpty 0X8FFFFFFE
|
|
|
|
#define MHDR_LASTBUFF 2
|
|
extern UINT MINPERIOD;
|
|
|
|
typedef int FileStatus; // this not thoroughly defined
|
|
|
|
/*****************************************************************************
|
|
*
|
|
* Data Stuctures & Typedefs
|
|
*
|
|
****************************************************************************/
|
|
|
|
/* USED FOR BYTE MANIPULATION OF MIDI DWORDS */
|
|
typedef struct fbm // 32 bit -- passed in lparam
|
|
{
|
|
BYTE status; // (order may change for optimization)
|
|
BYTE byte2;
|
|
BYTE byte3;
|
|
BYTE time;
|
|
} FourByteMIDI;
|
|
|
|
typedef union
|
|
{
|
|
DWORD wordMsg;
|
|
FourByteMIDI byteMsg;
|
|
} ShortMIDI;
|
|
|
|
/* USED TO HOLD LONG MIDI (SYSEX) INFORMATION */
|
|
// size of data buffer
|
|
#define LONGBUFFSIZE 0x100
|
|
// number of buffers in array (held in seq struct)
|
|
#define NUMSYSEXHDRS 2
|
|
|
|
#define pSEQ(h) ((NPSEQ)(h))
|
|
#define hSEQ(p) ((HMIDISEQ)(p))
|
|
|
|
typedef struct lm // ptr to this passed in lparam
|
|
{
|
|
MIDIHDR midihdr; // embedded midihdr struct
|
|
BYTE data[LONGBUFFSIZE];
|
|
} LongMIDI;
|
|
|
|
typedef LongMIDI NEAR * NPLONGMIDI;
|
|
|
|
/* USED FOR KEEPING TRACK OF CERTAIN EVENTS (META/KEY/PATCH) */
|
|
typedef struct // bit vector of booleans
|
|
{
|
|
WORD filter[8]; // yields 128 booleans
|
|
} BitVector128;
|
|
|
|
/* DATA STRUCTURES TO HOLD CONTENTS OF META EVENT READ IN */
|
|
|
|
typedef struct
|
|
{
|
|
BYTE hour;
|
|
BYTE minute;
|
|
BYTE second;
|
|
BYTE frame;
|
|
BYTE fractionalFrame;
|
|
} SMPTEType;
|
|
|
|
typedef struct
|
|
{
|
|
int numerator;
|
|
int denominator;
|
|
int midiClocksMetro;
|
|
int thirtySecondQuarter;
|
|
} TimeSigType;
|
|
|
|
|
|
/* TEMPO MAP ELEMENT (for list of tempo changes to facilitate ms <-> beat
|
|
conversion) */
|
|
|
|
typedef struct tag_TempoMapElement
|
|
{
|
|
DWORD dwMs;
|
|
DWORD dwTicks;
|
|
DWORD dwTempo;
|
|
} TempoMapElement;
|
|
|
|
typedef TempoMapElement *NPTEMPOMAPELEMENT;
|
|
|
|
typedef struct t1
|
|
{
|
|
LPBYTE currentPtr; //points at current byte in stream
|
|
LPBYTE endPtr; //points at last byte in buffer
|
|
LPBYTE previousPtr; //points at beginning of previous message
|
|
LPMIDISEQHDR hdrList; // list of track data headers
|
|
} TLevel1;
|
|
|
|
|
|
/* SEQUENCE TRACK DATA STRUCTURE */
|
|
|
|
typedef struct trk
|
|
{
|
|
int blockedOn; // how blocked, if at all?
|
|
LONG delta; // time in ticks 'till next event fired
|
|
DWORD length; // length of this track in ticks
|
|
BYTE lastStatus; // used for running status
|
|
ShortMIDI shortMIDIData; // staging area for next event
|
|
LONG sysExRemLength; // remaining length when sysex pending
|
|
TLevel1 inPort; // low level data pertaining to file
|
|
BOOL endOfTrack; // whether track is at end of its data
|
|
int iTrackNum; // track number (0-based)
|
|
DWORD_PTR dwCallback; // address of callback routine in mciseq
|
|
// used to return buffer to it (so it
|
|
// can be refilled and received again)
|
|
DWORD_PTR dwInstance; // mciseq's private instance information
|
|
// (usually contains file handle...)
|
|
DWORD dwBytesLeftToSkip;
|
|
} TRACK;
|
|
|
|
typedef TRACK NEAR *NPTRACK;
|
|
|
|
typedef struct trackarray_tag
|
|
{
|
|
NPTRACK trkArr[];
|
|
} TRACKARRAY;
|
|
typedef TRACKARRAY NEAR * NPTRACKARRAY;
|
|
|
|
// fwFlags:
|
|
#define LEGALFILE 0x0001 // Is a legal MIDI file
|
|
#define GENERALMSMIDI 0x0002 // Is an MS General MIDI file
|
|
|
|
typedef struct seq_tag
|
|
{
|
|
int divType; // PPQN, SMPTE24, SMPTE25, SMPTE30,
|
|
// or SMPTE30Drop
|
|
int resolution; // if SMPTE, ticks/frame, if MIDI,
|
|
// ticks/q-note
|
|
BOOL playing; // whether sequence playing or not
|
|
DWORD playTo; // what tick to play to, if not end
|
|
// (used for mci_play_to command)
|
|
DWORD length; // length of sequence in ticks
|
|
BOOL readyToPlay; // whether sequence is set up to play
|
|
DWORD currentTick; // where we are rel. to beginning of song
|
|
DWORD nextExactTime; // system time (ms) that next event
|
|
// *should* occur at
|
|
BOOL withinMsgOut; // true iff in middle of sending a message
|
|
DWORD seekTicks; // temp for seektick or song ptr operation
|
|
DWORD tempo; // tempo of sequence in ticks per Usec.
|
|
MMTIME smpteOffset; // absolute smpte time of start of seq.
|
|
// from meta event, or user)
|
|
TimeSigType timeSignature; // current time signature of piece (can
|
|
// change)
|
|
ListHandle trackList; // track list handle
|
|
NPTRACK nextEventTrack; // track that next event resides in
|
|
NPTRACK firstTrack; // track holding tempos, smpte offset...
|
|
char Name[NAMELENGTH]; // name of the sequence
|
|
|
|
// sync-related stuff below
|
|
|
|
DWORD nextSyncEventTick; // global tick at which the next sync
|
|
// event is expected
|
|
WORD slaveOf; // what you're slave of (mtc, clock,
|
|
// file, or nothing)
|
|
WORD masterOf; // what you're slave of (mtc, clock,
|
|
// or nothing)
|
|
BOOL waitingForSync; // tells if currently 'blocked' waiting
|
|
// for a sync pulse
|
|
// BitVector128 extMetaFilter; // for each meta type, whether to send it.
|
|
// (unused for now)
|
|
BitVector128 intMetaFilter; // for each meta type, whether it
|
|
// affects seq.
|
|
DWORD dwTimerParam; // used after timer interrupt to remember
|
|
// how many ticks elapsed
|
|
UINT wTimerID; // handle to timer (used to cancel
|
|
// next interrupt.
|
|
HMIDIOUT hMIDIOut; // handle to midi output driver
|
|
HANDLE hStream; // handle to stream
|
|
UINT wCBMessage; // message type that notify is for
|
|
ListHandle tempoMapList; // list of tempo map items for
|
|
// ms <-> ppqn conversion.
|
|
BOOL bSetPeriod; // whether timer period is currently
|
|
// set or not.
|
|
PATCHARRAY patchArray; // arrays to keep track of which
|
|
// patches used
|
|
KEYARRAY drumKeyArray; // array for drum cacheing
|
|
BitVector128 keyOnBitVect[16]; // arrays to keep track of which
|
|
// patches used
|
|
BOOL bSending; // currently in sendevent loop
|
|
// (used to prevent reentrancy)
|
|
BOOL bTimerEntered; // (used to prevent timer reentrancy)
|
|
#ifdef DEBUG
|
|
DWORD dwDebug; // debug signature (for detecting bogus
|
|
// seq ptr)
|
|
#endif
|
|
NPTRACKARRAY npTrkArr; // pointer to track array
|
|
// (used for routing incoming trk data)
|
|
UINT wNumTrks; // number of tracks
|
|
LongMIDI longMIDI[NUMSYSEXHDRS + 1]; // list of long midi buffers
|
|
BYTE bSysExBlock; // whether blocked waiting for long buff
|
|
BYTE bSendingSysEx; // whether in mid sysex out
|
|
UINT fwFlags; // various flags
|
|
} SEQ;
|
|
|
|
typedef SEQ NEAR *NPSEQ;
|
|
|
|
/****************************************************************************
|
|
*
|
|
* Prototypes
|
|
*
|
|
***************************************************************************/
|
|
|
|
// MMSEQ.C
|
|
PRIVATE VOID NEAR PASCAL SeekTicks(NPSEQ npSeq);
|
|
PUBLIC UINT NEAR PASCAL GetInfo(NPSEQ npSeq, LPMIDISEQINFO lpInfo);
|
|
PUBLIC UINT NEAR PASCAL CreateSequence(LPMIDISEQOPENDESC lpOpen,
|
|
LPHMIDISEQ lphMIDISeq);
|
|
PUBLIC VOID NEAR PASCAL FillInDelta(NPTRACK npTrack);
|
|
PUBLIC UINT NEAR PASCAL Play(NPSEQ npSeq, DWORD dwPlayTo);
|
|
PUBLIC VOID NEAR PASCAL Stop(NPSEQ npSeq);
|
|
PUBLIC UINT NEAR PASCAL TimerIntRoutine(NPSEQ npSeq, LONG elapsedTick);
|
|
PUBLIC VOID NEAR PASCAL SetBlockedTracksTo(NPSEQ npSeq,
|
|
int fromState, int toState);
|
|
PUBLIC VOID NEAR PASCAL ResetToBeginning(NPSEQ npSeq) ;
|
|
PUBLIC BOOL NEAR PASCAL HandleMetaEvent(NPSEQ npSeq, NPTRACK npTrack,
|
|
UINT wMode);
|
|
PUBLIC BOOL NEAR PASCAL ScanEarlyMetas(NPSEQ npSeq, NPTRACK npTrack,
|
|
DWORD dwUntil);
|
|
PUBLIC FileStatus NEAR PASCAL SendAllEventsB4(NPSEQ npSeq,
|
|
LONG elapsedTick, int mode);
|
|
PUBLIC FileStatus NEAR PASCAL GetNextEvent(NPSEQ npSeq);
|
|
PUBLIC VOID NEAR PASCAL FillInNextTrack(NPTRACK npTrack);
|
|
PUBLIC UINT NEAR PASCAL SendPatchCache(NPSEQ npSeq, BOOL cache);
|
|
PUBLIC VOID NEAR PASCAL SendSysEx(NPSEQ npSeq);
|
|
PUBLIC VOID NEAR PASCAL SkipBytes(NPTRACK npTrack, LONG length);
|
|
|
|
|
|
// UTIL.C
|
|
|
|
PUBLIC VOID NEAR PASCAL seqCallback(NPTRACK npTrack, UINT msg,
|
|
DWORD_PTR dw1, DWORD_PTR dw2);
|
|
PUBLIC BYTE NEAR PASCAL LookByte(NPTRACK npTrack);
|
|
PUBLIC BYTE NEAR PASCAL GetByte(NPTRACK npTrack);
|
|
PUBLIC VOID NEAR PASCAL MarkLocation(NPTRACK npTrack);
|
|
PUBLIC VOID NEAR PASCAL ResetLocation(NPTRACK npTrack);
|
|
PUBLIC VOID NEAR PASCAL RewindToStart(NPSEQ npSeq, NPTRACK npTrack);
|
|
PUBLIC BOOL NEAR PASCAL AllTracksUnblocked(NPSEQ npSeq);
|
|
PUBLIC VOID FAR PASCAL _LOADDS OneShotTimer(UINT wId, UINT msg, DWORD_PTR dwUser,
|
|
DWORD_PTR dwTime, DWORD_PTR dw2);
|
|
PUBLIC UINT NEAR PASCAL SetTimerCallback(NPSEQ npSeq, UINT msInterval,
|
|
DWORD elapsedTicks);
|
|
PUBLIC VOID NEAR PASCAL DestroyTimer(NPSEQ npSeq);
|
|
PUBLIC VOID NEAR PASCAL SendLongMIDI(NPSEQ npSeq,
|
|
LongMIDI FAR *pLongMIDIData);
|
|
PUBLIC UINT NEAR PASCAL NewTrackData(NPSEQ npSeq, LPMIDISEQHDR msgHdr);
|
|
PUBLIC NPLONGMIDI NEAR PASCAL GetSysExBuffer(NPSEQ npSeq);
|
|
|
|
|
|
// CRIT.ASM
|
|
|
|
extern FAR PASCAL EnterCrit(void);
|
|
extern FAR PASCAL LeaveCrit(void);
|
|
|
|
// CALLBACK.C
|
|
|
|
PUBLIC VOID FAR PASCAL _LOADDS MIDICallback(HMIDIOUT hMIDIOut, UINT wMsg,
|
|
DWORD_PTR dwInstance, DWORD_PTR dwParam1, DWORD_PTR dwParam2);
|
|
|
|
PUBLIC VOID FAR PASCAL NotifyCallback(HANDLE hStream);
|
|
|