-
Notifications
You must be signed in to change notification settings - Fork 0
/
midstuff.h
138 lines (113 loc) · 4.66 KB
/
midstuff.h
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
/*==========================================================================
*
* Copyright (C) 1995-1996 Microsoft Corporation. All Rights Reserved.
*
* File: midstuff.h
* Content: MIDI structures and definitions used by the MSTREAM sample
* application in converting a MID file to a MIDI stream for
* playback using the midiStream API.
*
***************************************************************************/
#ifndef __MIDSTUFF_H__
#define __MIDSTUFF_H__
// MIDI file constants
//
#define MThd 0x6468544D // Start of file
#define MTrk 0x6B72544D // Start of track
#define MIDI_SYSEX ((BYTE)0xF0) // SysEx begin
#define MIDI_SYSEXEND ((BYTE)0xF7) // SysEx begin
#define MIDI_META ((BYTE)0xFF) // Meta event begin
#define MIDI_META_TEMPO ((BYTE)0x51) // Tempo change
#define MIDI_META_EOT ((BYTE)0x2F) // End-of-track
#define MIDI_NOTEOFF ((BYTE)0x80) // + note + velocity
#define MIDI_NOTEON ((BYTE)0x90) // + note + velocity
#define MIDI_POLYPRESS ((BYTE)0xA0) // + pressure (2 bytes)
#define MIDI_CTRLCHANGE ((BYTE)0xB0) // + ctrlr + value
#define MIDI_PRGMCHANGE ((BYTE)0xC0) // + new patch
#define MIDI_CHANPRESS ((BYTE)0xD0) // + pressure (1 byte)
#define MIDI_PITCHBEND ((BYTE)0xE0) // + pitch bend (2 bytes)
#define NUM_CHANNELS 16
#define MIDICTRL_VOLUME ((BYTE)0x07)
#define MIDICTRL_VOLUME_LSB ((BYTE)0x27)
#define MIDICTRL_PAN ((BYTE)0x0A)
#define MIDIEVENT_CHANNEL(dw) (dw & 0x0000000F)
#define MIDIEVENT_TYPE(dw) (dw & 0x000000F0)
#define MIDIEVENT_DATA1(dw) ((dw & 0x0000FF00) >> 8)
#define MIDIEVENT_VOLUME(dw) ((dw & 0x007F0000) >> 16)
// Macros for swapping hi/lo-endian data
//
#define WORDSWAP(w) (((w) >> 8) | \
(((w) << 8) & 0xFF00))
#define DWORDSWAP(dw) (((dw) >> 24) | \
(((dw) >> 8) & 0x0000FF00) | \
(((dw) << 8) & 0x00FF0000) | \
(((dw) << 24) & 0xFF000000))
// In debug builds, TRACKERR will show us where the parser died
//
#ifdef DEBUG
#define TRACKERR(p,sz) ShowTrackError(p,sz);
#else
#define TRACKERR(p,sz)
#endif
// Make a little distinction here so the various structure members are a bit
// more clearly labelled -- we have offsets and byte counts to keep track of
// that deal with both in-memory buffers and the file on disk
#define FILEOFF DWORD
// These structures are stored in MIDI files; they need to be byte aligned.
//
#pragma pack(1)
// Chunk header. dwTag is either MTrk or MThd.
//
typedef struct
{
DWORD dwTag; // Type
DWORD dwChunkLength; // Length (hi-lo)
} MIDICHUNK;
// Contents of MThd chunk.
typedef struct
{
WORD wFormat; // Format (hi-lo)
WORD wTrackCount; // # tracks (hi-lo)
WORD wTimeDivision; // Time division (hi-lo)
} MIDIFILEHDR;
#pragma pack() // End of need for byte-aligned structures
// Temporary event structure which stores event data until we're ready to
// dump it into a stream buffer
//
typedef struct
{
DWORD tkEvent; // Absolute time of event
BYTE byShortData[4]; // Event type and parameters if channel msg
DWORD dwEventLength; // Length of data which follows if meta or sysex
LPBYTE pLongData; // -> Event data if applicable
} TEMPEVENT, *PTEMPEVENT;
#define ITS_F_ENDOFTRK 0x00000001
// Description of a track open for read
//
typedef struct
{
DWORD fdwTrack; // Track status
DWORD dwTrackLength; // Total bytes in track
DWORD dwLeftInBuffer; // Bytes left unread in track buffer
LPBYTE pTrackStart; // -> start of track data buffer
LPBYTE pTrackCurrent; // -> next byte to read in buffer
DWORD tkNextEventDue; // Absolute time of next event in track
BYTE byRunningStatus;// Running status from last channel msg
FILEOFF foTrackStart; // Start of track -- used for walking the file
FILEOFF foNextReadStart;// File offset of next read from disk
DWORD dwLeftOnDisk; // Bytes left unread on disk
#ifdef DEBUG
DWORD nTrack; // # of this track for debugging
#endif
} INTRACKSTATE, *PINTRACKSTATE;
// Description of the input MIDI file
//
typedef struct
{
DWORD cbFileLength; // Total bytes in file
DWORD dwTimeDivision; // Original time division
DWORD dwFormat; // Original format
DWORD dwTrackCount; // Track count (specifies pitsTracks size)
INTRACKSTATE *pitsTracks; // -> array of tracks in this file
} INFILESTATE, *PINFILESTATE;
#endif