1 // Emacs style mode select   -*- C++ -*-
2 //-----------------------------------------------------------------------------
3 //
4 // Copyright(C) 2009 Simon Howard
5 //
6 // This program is free software; you can redistribute it and/or
7 // modify it under the terms of the GNU General Public License
8 // as published by the Free Software Foundation; either version 2
9 // of the License, or (at your option) any later version.
10 //
11 // This program is distributed in the hope that it will be useful,
12 // but WITHOUT ANY WARRANTY; without even the implied warranty of
13 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
14 // GNU General Public License for more details.
15 //
16 // You should have received a copy of the GNU General Public License
17 // along with this program; if not, write to the Free Software
18 // Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 // 02111-1307, USA.
20 //
21 // DESCRIPTION:
22 //     MIDI file parsing.
23 //
24 //-----------------------------------------------------------------------------
25 
26 #ifndef MIDIFILE_H
27 #define MIDIFILE_H
28 
29 #include "doomtype.h"
30 
31 typedef struct midi_file_s midi_file_t;
32 typedef struct midi_track_iter_s midi_track_iter_t;
33 
34 #define MIDI_CHANNELS_PER_TRACK 16
35 
36 typedef struct
37 {
38     const unsigned char *data;
39     size_t len;
40     size_t pos;
41 } midimem_t;
42 
43 
44 typedef enum
45 {
46     MIDI_EVENT_NOTE_OFF        = 0x80,
47     MIDI_EVENT_NOTE_ON         = 0x90,
48     MIDI_EVENT_AFTERTOUCH      = 0xa0,
49     MIDI_EVENT_CONTROLLER      = 0xb0,
50     MIDI_EVENT_PROGRAM_CHANGE  = 0xc0,
51     MIDI_EVENT_CHAN_AFTERTOUCH = 0xd0,
52     MIDI_EVENT_PITCH_BEND      = 0xe0,
53 
54     MIDI_EVENT_SYSEX           = 0xf0,
55     MIDI_EVENT_SYSEX_SPLIT     = 0xf7,
56     MIDI_EVENT_META            = 0xff,
57 } midi_event_type_t;
58 
59 typedef enum
60 {
61     MIDI_CONTROLLER_BANK_SELECT     = 0x0,
62     MIDI_CONTROLLER_MODULATION      = 0x1,
63     MIDI_CONTROLLER_BREATH_CONTROL  = 0x2,
64     MIDI_CONTROLLER_FOOT_CONTROL    = 0x3,
65     MIDI_CONTROLLER_PORTAMENTO      = 0x4,
66     MIDI_CONTROLLER_DATA_ENTRY      = 0x5,
67 
68     MIDI_CONTROLLER_MAIN_VOLUME     = 0x7,
69     MIDI_CONTROLLER_PAN             = 0xa
70 } midi_controller_t;
71 
72 typedef enum
73 {
74     MIDI_META_SEQUENCE_NUMBER       = 0x0,
75 
76     MIDI_META_TEXT                  = 0x1,
77     MIDI_META_COPYRIGHT             = 0x2,
78     MIDI_META_TRACK_NAME            = 0x3,
79     MIDI_META_INSTR_NAME            = 0x4,
80     MIDI_META_LYRICS                = 0x5,
81     MIDI_META_MARKER                = 0x6,
82     MIDI_META_CUE_POINT             = 0x7,
83 
84     MIDI_META_CHANNEL_PREFIX        = 0x20,
85     MIDI_META_END_OF_TRACK          = 0x2f,
86 
87     MIDI_META_SET_TEMPO             = 0x51,
88     MIDI_META_SMPTE_OFFSET          = 0x54,
89     MIDI_META_TIME_SIGNATURE        = 0x58,
90     MIDI_META_KEY_SIGNATURE         = 0x59,
91     MIDI_META_SEQUENCER_SPECIFIC    = 0x7f,
92 } midi_meta_event_type_t;
93 
94 typedef struct
95 {
96     // Meta event type:
97 
98     unsigned int type;
99 
100     // Length:
101 
102     unsigned int length;
103 
104     // Meta event data:
105 
106     unsigned char *data;
107 } midi_meta_event_data_t;
108 
109 typedef struct
110 {
111     // Length:
112 
113     unsigned int length;
114 
115     // Event data:
116 
117     unsigned char *data;
118 } midi_sysex_event_data_t;
119 
120 typedef struct
121 {
122     // The channel number to which this applies:
123 
124     unsigned int channel;
125 
126     // Extra parameters:
127 
128     unsigned int param1;
129     unsigned int param2;
130 } midi_channel_event_data_t;
131 
132 typedef struct
133 {
134     // Time between the previous event and this event.
135     unsigned int delta_time;
136 
137     // Type of event:
138     midi_event_type_t event_type;
139 
140     union
141     {
142         midi_channel_event_data_t channel;
143         midi_meta_event_data_t meta;
144         midi_sysex_event_data_t sysex;
145     } data;
146 } midi_event_t;
147 
148 // Load a MIDI file.
149 
150 midi_file_t *MIDI_LoadFile(midimem_t *mf);
151 
152 // Free a MIDI file.
153 
154 void MIDI_FreeFile(midi_file_t *file);
155 
156 // Get the time division value from the MIDI header.
157 
158 unsigned int MIDI_GetFileTimeDivision(const midi_file_t *file);
159 
160 // Get the number of tracks in a MIDI file.
161 
162 unsigned int MIDI_NumTracks(const midi_file_t *file);
163 
164 // Start iterating over the events in a track.
165 
166 midi_track_iter_t *MIDI_IterateTrack(const midi_file_t *file, unsigned int track_num);
167 
168 // Free an iterator.
169 
170 void MIDI_FreeIterator(midi_track_iter_t *iter);
171 
172 // Get the time until the next MIDI event in a track.
173 
174 unsigned int MIDI_GetDeltaTime(midi_track_iter_t *iter);
175 
176 // Get a pointer to the next MIDI event.
177 
178 int MIDI_GetNextEvent(midi_track_iter_t *iter, midi_event_t **event);
179 
180 // Reset an iterator to the beginning of a track.
181 
182 void MIDI_RestartIterator(midi_track_iter_t *iter);
183 
184 // NSM: an alternate iterator tool.
185 midi_event_t **MIDI_GenerateFlatList (midi_file_t *file);
186 void MIDI_DestroyFlatList (midi_event_t **evs);
187 
188 // NSM: timing calculator
189 double MIDI_spmc (const midi_file_t *file, const midi_event_t *ev, unsigned sndrate);
190 
191 midi_file_t *MIDI_LoadFileSpecial (midimem_t *mf);
192 
193 #endif /* #ifndef MIDIFILE_H */
194