-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathmidifile.h
228 lines (204 loc) · 12.5 KB
/
midifile.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
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
#ifndef MIDI_FILE_INCLUDED
#define MIDI_FILE_INCLUDED
/*
* Div's Standard MIDI File API
* Copyright 2003-2006 by David G. Slomin
* Provided under the terms of the BSD license
*
* Usage notes:
*
* 1. Running status is eliminated from messages at load time; it should not
* be used at any other time.
*
* 2. MIDI files in formats 0, 1, and 2 are supported, but the caller is
* responsible for placing events into the appropriate tracks. Format
* 0 files should only use a single track. Format 1 files use their
* first track as a "conductor track" for meta events like tempo and
* meter changes.
*
* 3. MidiFile_visitEvents() and MidiFileTrack_visitEvents() are specially
* designed so that you can add, delete, or change the tick of events
* (thereby modifying the sorting order) without upsetting the iterator.
*
* 4. Any data passed into these functions is memory-managed by the caller.
* Any data returned from these functions is memory-managed by the API.
* Don't forget to call MidiFile_free().
*
* 5. This API is not thread-safe.
*
* 6. You can navigate through events one track at a time, or through all
* tracks at once in an interwoven, time-sorted manner.
*
* 7. Because a note on event with a velocity of zero is functionally
* equivalent to a note off event, you cannot simply look at the type of
* an event to see whether it signifies the start or the end of a note.
* To handle this problem, convenience wrappers are provided for pseudo
* "note start" and "note end" events.
*
* 8. Convenience functions are provided for working with tempo and
* absolute time in files of format 1 or 0. Tempo events (a particular
* kind of meta event) are only meaningful when using the PPQ division
* type.
*
* 9. Events other than sysex and meta are considered "voice events". For
* interaction with other APIs, it is sometimes useful to pack their
* messages into 32 bit integers.
*
* 10. All numbers in this API are zero-based, to correspond with the actual
* byte values of the MIDI protocol, rather than one-based, as they are
* commonly displayed to the user. Channels range from 0 to 15, notes
* range from 0 to 127, etc.
*/
#ifdef __cplusplus
extern "C"{
#endif
typedef struct MidiFile *MidiFile_t;
typedef struct MidiFileTrack *MidiFileTrack_t;
typedef struct MidiFileEvent *MidiFileEvent_t;
typedef void (*MidiFileEventVisitorCallback_t)(MidiFileEvent_t event, void *user_data);
typedef enum{
MIDI_FILE_DIVISION_TYPE_INVALID = -1,
MIDI_FILE_DIVISION_TYPE_PPQ,
MIDI_FILE_DIVISION_TYPE_SMPTE24,
MIDI_FILE_DIVISION_TYPE_SMPTE25,
MIDI_FILE_DIVISION_TYPE_SMPTE30DROP,
MIDI_FILE_DIVISION_TYPE_SMPTE30
}MidiFileDivisionType_t;
typedef enum{
MIDI_FILE_EVENT_TYPE_INVALID = -1,
MIDI_FILE_EVENT_TYPE_NOTE_OFF,
MIDI_FILE_EVENT_TYPE_NOTE_ON,
MIDI_FILE_EVENT_TYPE_KEY_PRESSURE,
MIDI_FILE_EVENT_TYPE_CONTROL_CHANGE,
MIDI_FILE_EVENT_TYPE_PROGRAM_CHANGE,
MIDI_FILE_EVENT_TYPE_CHANNEL_PRESSURE,
MIDI_FILE_EVENT_TYPE_PITCH_WHEEL,
MIDI_FILE_EVENT_TYPE_SYSEX,
MIDI_FILE_EVENT_TYPE_META
}MidiFileEventType_t;
MidiFile_t MidiFile_load(char *filename);
int MidiFile_save(MidiFile_t midi_file, const char* filename);
MidiFile_t MidiFile_new(int file_format, MidiFileDivisionType_t division_type, int resolution);
int MidiFile_free(MidiFile_t midi_file);
int MidiFile_getFileFormat(MidiFile_t midi_file);
int MidiFile_setFileFormat(MidiFile_t midi_file, int file_format);
MidiFileDivisionType_t MidiFile_getDivisionType(MidiFile_t midi_file);
int MidiFile_setDivisionType(MidiFile_t midi_file, MidiFileDivisionType_t division_type);
int MidiFile_getResolution(MidiFile_t midi_file);
int MidiFile_setResolution(MidiFile_t midi_file, int resolution);
MidiFileTrack_t MidiFile_createTrack(MidiFile_t midi_file);
int MidiFile_getNumberOfTracks(MidiFile_t midi_file);
MidiFileTrack_t MidiFile_getTrackByNumber(MidiFile_t midi_file, int number, int create);
MidiFileTrack_t MidiFile_getFirstTrack(MidiFile_t midi_file);
MidiFileTrack_t MidiFile_getLastTrack(MidiFile_t midi_file);
MidiFileEvent_t MidiFile_getFirstEvent(MidiFile_t midi_file);
MidiFileEvent_t MidiFile_getLastEvent(MidiFile_t midi_file);
int MidiFile_visitEvents(MidiFile_t midi_file, MidiFileEventVisitorCallback_t visitor_callback, void *user_data);
float MidiFile_getTimeFromTick(MidiFile_t midi_file, long tick); /* time is in seconds */
long MidiFile_getTickFromTime(MidiFile_t midi_file, float time);
float MidiFile_getBeatFromTick(MidiFile_t midi_file, long tick);
long MidiFile_getTickFromBeat(MidiFile_t midi_file, float beat);
int MidiFileTrack_delete(MidiFileTrack_t track);
MidiFile_t MidiFileTrack_getMidiFile(MidiFileTrack_t track);
int MidiFileTrack_getNumber(MidiFileTrack_t track);
long MidiFileTrack_getEndTick(MidiFileTrack_t track);
int MidiFileTrack_setEndTick(MidiFileTrack_t track, long end_tick);
MidiFileTrack_t MidiFileTrack_createTrackBefore(MidiFileTrack_t track);
MidiFileTrack_t MidiFileTrack_getPreviousTrack(MidiFileTrack_t track);
MidiFileTrack_t MidiFileTrack_getNextTrack(MidiFileTrack_t track);
MidiFileEvent_t MidiFileTrack_createNoteOffEvent(MidiFileTrack_t track, long tick, int channel, int note, int velocity);
MidiFileEvent_t MidiFileTrack_createNoteOnEvent(MidiFileTrack_t track, long tick, int channel, int note, int velocity);
MidiFileEvent_t MidiFileTrack_createKeyPressureEvent(MidiFileTrack_t track, long tick, int channel, int note, int amount);
MidiFileEvent_t MidiFileTrack_createControlChangeEvent(MidiFileTrack_t track, long tick, int channel, int number, int value);
MidiFileEvent_t MidiFileTrack_createProgramChangeEvent(MidiFileTrack_t track, long tick, int channel, int number);
MidiFileEvent_t MidiFileTrack_createChannelPressureEvent(MidiFileTrack_t track, long tick, int channel, int amount);
MidiFileEvent_t MidiFileTrack_createPitchWheelEvent(MidiFileTrack_t track, long tick, int channel, int value);
MidiFileEvent_t MidiFileTrack_createSysexEvent(MidiFileTrack_t track, long tick, int data_length, unsigned char *data_buffer);
MidiFileEvent_t MidiFileTrack_createMetaEvent(MidiFileTrack_t track, long tick, int number, int data_length, unsigned char *data_buffer);
MidiFileEvent_t MidiFileTrack_createNoteStartAndEndEvents(MidiFileTrack_t track, long start_tick, long end_tick, int channel, int note, int start_velocity, int end_velocity); /* returns the start event */
MidiFileEvent_t MidiFileTrack_createTempoEvent(MidiFileTrack_t track, long tick, float tempo); /* tempo is in BPM */
MidiFileEvent_t MidiFileTrack_createVoiceEvent(MidiFileTrack_t track, long tick, unsigned long data);
MidiFileEvent_t MidiFileTrack_getFirstEvent(MidiFileTrack_t track);
MidiFileEvent_t MidiFileTrack_getLastEvent(MidiFileTrack_t track);
int MidiFileTrack_visitEvents(MidiFileTrack_t track, MidiFileEventVisitorCallback_t visitor_callback, void *user_data);
int MidiFileEvent_delete(MidiFileEvent_t event);
MidiFileTrack_t MidiFileEvent_getTrack(MidiFileEvent_t event);
MidiFileEvent_t MidiFileEvent_getPreviousEvent(MidiFileEvent_t event); /* deprecated: use MidiFileEvent_getPreviousEventInTrack() */
MidiFileEvent_t MidiFileEvent_getNextEvent(MidiFileEvent_t event); /* deprecated: use MidiFileEvent_getNextEventInTrack() */
MidiFileEvent_t MidiFileEvent_getPreviousEventInTrack(MidiFileEvent_t event);
MidiFileEvent_t MidiFileEvent_getNextEventInTrack(MidiFileEvent_t event);
MidiFileEvent_t MidiFileEvent_getPreviousEventInFile(MidiFileEvent_t event);
MidiFileEvent_t MidiFileEvent_getNextEventInFile(MidiFileEvent_t event);
long MidiFileEvent_getTick(MidiFileEvent_t event);
int MidiFileEvent_setTick(MidiFileEvent_t event, long tick);
MidiFileEventType_t MidiFileEvent_getType(MidiFileEvent_t event);
int MidiFileEvent_isNoteStartEvent(MidiFileEvent_t event);
int MidiFileEvent_isNoteEndEvent(MidiFileEvent_t event);
int MidiFileEvent_isTempoEvent(MidiFileEvent_t event);
int MidiFileEvent_isVoiceEvent(MidiFileEvent_t event);
int MidiFileNoteOffEvent_getChannel(MidiFileEvent_t event);
int MidiFileNoteOffEvent_setChannel(MidiFileEvent_t event, int channel);
int MidiFileNoteOffEvent_getNote(MidiFileEvent_t event);
int MidiFileNoteOffEvent_setNote(MidiFileEvent_t event, int note);
int MidiFileNoteOffEvent_getVelocity(MidiFileEvent_t event);
int MidiFileNoteOffEvent_setVelocity(MidiFileEvent_t event, int velocity);
int MidiFileNoteOnEvent_getChannel(MidiFileEvent_t event);
int MidiFileNoteOnEvent_setChannel(MidiFileEvent_t event, int channel);
int MidiFileNoteOnEvent_getNote(MidiFileEvent_t event);
int MidiFileNoteOnEvent_setNote(MidiFileEvent_t event, int note);
int MidiFileNoteOnEvent_getVelocity(MidiFileEvent_t event);
int MidiFileNoteOnEvent_setVelocity(MidiFileEvent_t event, int velocity);
int MidiFileKeyPressureEvent_getChannel(MidiFileEvent_t event);
int MidiFileKeyPressureEvent_setChannel(MidiFileEvent_t event, int channel);
int MidiFileKeyPressureEvent_getNote(MidiFileEvent_t event);
int MidiFileKeyPressureEvent_setNote(MidiFileEvent_t event, int note);
int MidiFileKeyPressureEvent_getAmount(MidiFileEvent_t event);
int MidiFileKeyPressureEvent_setAmount(MidiFileEvent_t event, int amount);
int MidiFileControlChangeEvent_getChannel(MidiFileEvent_t event);
int MidiFileControlChangeEvent_setChannel(MidiFileEvent_t event, int channel);
int MidiFileControlChangeEvent_getNumber(MidiFileEvent_t event);
int MidiFileControlChangeEvent_setNumber(MidiFileEvent_t event, int number);
int MidiFileControlChangeEvent_getValue(MidiFileEvent_t event);
int MidiFileControlChangeEvent_setValue(MidiFileEvent_t event, int value);
int MidiFileProgramChangeEvent_getChannel(MidiFileEvent_t event);
int MidiFileProgramChangeEvent_setChannel(MidiFileEvent_t event, int channel);
int MidiFileProgramChangeEvent_getNumber(MidiFileEvent_t event);
int MidiFileProgramChangeEvent_setNumber(MidiFileEvent_t event, int number);
int MidiFileChannelPressureEvent_getChannel(MidiFileEvent_t event);
int MidiFileChannelPressureEvent_setChannel(MidiFileEvent_t event, int channel);
int MidiFileChannelPressureEvent_getAmount(MidiFileEvent_t event);
int MidiFileChannelPressureEvent_setAmount(MidiFileEvent_t event, int amount);
int MidiFilePitchWheelEvent_getChannel(MidiFileEvent_t event);
int MidiFilePitchWheelEvent_setChannel(MidiFileEvent_t event, int channel);
int MidiFilePitchWheelEvent_getValue(MidiFileEvent_t event);
int MidiFilePitchWheelEvent_setValue(MidiFileEvent_t event, int value);
int MidiFileSysexEvent_getDataLength(MidiFileEvent_t event);
unsigned char *MidiFileSysexEvent_getData(MidiFileEvent_t event);
int MidiFileSysexEvent_setData(MidiFileEvent_t event, int data_length, unsigned char *data_buffer);
int MidiFileMetaEvent_getNumber(MidiFileEvent_t event);
int MidiFileMetaEvent_setNumber(MidiFileEvent_t event, int number);
int MidiFileMetaEvent_getDataLength(MidiFileEvent_t event);
unsigned char *MidiFileMetaEvent_getData(MidiFileEvent_t event);
int MidiFileMetaEvent_setData(MidiFileEvent_t event, int data_length, unsigned char *data_buffer);
int MidiFileNoteStartEvent_getChannel(MidiFileEvent_t event);
int MidiFileNoteStartEvent_setChannel(MidiFileEvent_t event, int channel);
int MidiFileNoteStartEvent_getNote(MidiFileEvent_t event);
int MidiFileNoteStartEvent_setNote(MidiFileEvent_t event, int note);
int MidiFileNoteStartEvent_getVelocity(MidiFileEvent_t event);
int MidiFileNoteStartEvent_setVelocity(MidiFileEvent_t event, int velocity);
MidiFileEvent_t MidiFileNoteStartEvent_getNoteEndEvent(MidiFileEvent_t event);
int MidiFileNoteEndEvent_getChannel(MidiFileEvent_t event);
int MidiFileNoteEndEvent_setChannel(MidiFileEvent_t event, int channel);
int MidiFileNoteEndEvent_getNote(MidiFileEvent_t event);
int MidiFileNoteEndEvent_setNote(MidiFileEvent_t event, int note);
int MidiFileNoteEndEvent_getVelocity(MidiFileEvent_t event);
int MidiFileNoteEndEvent_setVelocity(MidiFileEvent_t event, int velocity); /* caution: will replace a note on event with a note off */
MidiFileEvent_t MidiFileNoteEndEvent_getNoteStartEvent(MidiFileEvent_t event);
float MidiFileTempoEvent_getTempo(MidiFileEvent_t event);
int MidiFileTempoEvent_setTempo(MidiFileEvent_t event, float tempo);
unsigned long MidiFileVoiceEvent_getData(MidiFileEvent_t event);
int MidiFileVoiceEvent_setData(MidiFileEvent_t event, unsigned long data);
#ifdef __cplusplus
}
#endif
#endif