Import of jack-smf-utils 1.0.
[jack-smf-utils.git] / libsmf / smf.h
blob90a5e59db17a5ee8d1eabc65f9bf5156b7773433
1 /*-
2 * Copyright (c) 2007, 2008 Edward Tomasz NapieraƂa <trasz@FreeBSD.org>
3 * All rights reserved.
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
14 * ALTHOUGH THIS SOFTWARE IS MADE OF WIN AND SCIENCE, IT IS PROVIDED BY THE
15 * AUTHOR AND CONTRIBUTORS ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES,
16 * INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY
17 * AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
18 * THE AUTHOR OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
19 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
20 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA,
21 * OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
22 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
23 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
24 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29 * This is the include file for libsmf, Standard Midi File format library.
30 * For questions and comments, contact Edward Tomasz Napierala <trasz@FreeBSD.org>.
33 /**
35 * \mainpage General usage instructions
37 * An smf_t structure represents a "song". Every valid smf contains one or more tracks.
38 * Tracks contain zero or more events. Libsmf doesn't care about actual MIDI data, as long
39 * as it is valid from the MIDI specification point of view - it may be realtime message,
40 * SysEx, whatever.
42 * The only field in smf_t, smf_track_t, smf_event_t and smf_tempo_t structures your
43 * code may modify is event->midi_buffer and event->midi_buffer_length. Do not modify
44 * other fields, _ever_. You may read them, though.
46 * Say you want to load a Standard MIDI File (.mid) file and play it back somehow. This is (roughly)
47 * how you do this:
49 * \code
50 * smf_t *smf = smf_load(file_name);
51 * if (smf == NULL) {
52 * Whoops, something went wrong.
53 * return;
54 * }
56 * for (;;) {
57 * smf_event_t *event = smf_get_next_event(smf);
58 * if (event == NULL) {
59 * No more events, end of the song.
60 * return;
61 * }
63 * if (smf_event_is_metadata(event))
64 * continue;
66 * wait until event->time_seconds.
67 * feed_to_midi_output(event->midi_buffer, event->midi_buffer_length);
68 * }
70 * \endcode
72 * Saving works like this:
74 * \code
76 * smf_t *smf = smf_new();
77 * if (smf == NULL) {
78 * Whoops.
79 * return;
80 * }
82 * for (int i = 1; i <= number of tracks; i++) {
83 * smf_track_t *track = smf_track_new();
84 * if (track == NULL) {
85 * Whoops.
86 * return;
87 * }
89 * smf_add_track(smf, track);
91 * for (int j = 1; j <= number of events in this track; j++) {
92 * smf_event_t *event = smf_event_new_from_pointer(your MIDI message, message length);
93 * if (event == NULL) {
94 * Whoops.
95 * return;
96 * }
98 * smf_track_add_event_seconds(track, event, seconds since start of the song);
99 * }
102 * ret = smf_save(smf, file_name);
103 * if (ret) {
104 * Whoops, saving failed for some reason.
105 * return;
108 * \endcode
110 * There are two basic ways of getting MIDI data out of smf - sequential or by track/event number. You may
111 * mix them if you need to. First one is used in the example above - seek to the point from which you want
112 * the playback to start (using smf_seek_to_seconds, for example) and then do smf_get_next_event in loop,
113 * until it returns NULL. After smf_load smf is rewound to the start of the song.
115 * Getting events by number works like this:
117 * \code
119 * smf_track_t *track = smf_get_track_by_number(smf, track_number);
120 * smf_event_t *event = smf_track_get_event_by_number(track, event_number);
122 * \endcode
124 * Tracks and events are numbered consecutively, starting from one. If you remove a track or event,
125 * the rest of tracks/events will be renumbered. To get number of event in its track, use event->event_number.
126 * To get the number of track in its smf, use track->track_number. To get the number of events in the track,
127 * use track->number_of_events. To get the number of tracks in the smf, use smf->number_of_tracks.
129 * In SMF File Format, each track has to end with End Of Track metaevent. If you load SMF file using smf_load,
130 * that will be the case. If you want to create or edit an SMF, you don't need to worry about EOT events,
131 * libsmf automatically takes care of them for you. If you try to save an SMF with tracks that do not end
132 * with EOTs, smf_save will append them. If you try to add event that happens after EOT metaevent, libsmf
133 * will remove the EOT. If you want to add EOT automatically, you can, of course, using smf_track_add_eot_seconds
134 * or smf_track_add_eot_pulses.
136 * Each event carries three time values - event->time_seconds, which is seconds since the start of the song,
137 * event->time_pulses, which is PPQN clocks since the start of the song, and event->delta_pulses, which is PPQN clocks
138 * since the previous event in that track. These values are invalid if the event is not attached to the track.
139 * If event is attached, all three values are valid. Time of the event is specified when adding the event
140 * (smf_track_add_event_seconds/smf_track_add_event_pulses/smf_track_add_event_delta_pulses); the remaining
141 * two values are computed from that.
143 * Tempo related stuff happens automatically - when you add a metaevent that
144 * is Tempo Change or Time Signature, libsmf adds that event to the tempo map. If you remove
145 * Tempo Change event that is in the middle of the song, the rest of the events will have their
146 * event->time_seconds recomputed from event->time_pulses before smf_track_remove_event function returns.
147 * Adding Tempo Change in the middle of the song works in a similar way.
149 * MIDI data (event->midi_buffer) are always in normalized form - they always begin with status byte
150 * (no running status), there are no system realtime events embedded in them etc. Events like SysExes
151 * are in "on the wire" form, without embedded length that is used in SMF file format. Obviously
152 * libsmf "normalizes" MIDI data during loading and "denormalizes" (adding length to SysExes, escaping
153 * System Common and System Realtime messages etc) during writing.
155 * Note that you always have to first add the track to smf, and then add events to the track.
156 * Doing it the other way around will trip asserts. Also, try to add events at the end of the track and remove
157 * them from the end of the track, that's much more efficient.
159 * All the libsmf functions have prefix "smf_". Library does not use any global variables and is thread-safe,
160 * as long as you don't try to work on the same SMF (smf_t and it's descendant tracks and events) from several
161 * threads at once without protecting it with mutex. Library depends on glib and nothing else. License is
162 * BSD, two clause.
166 #ifndef SMF_H
167 #define SMF_H
169 #ifdef __cplusplus
170 extern "C" {
171 #endif
173 #include <stdio.h>
174 #include <arpa/inet.h>
175 #include <glib.h>
177 struct smf_struct {
178 int format;
179 int expected_number_of_tracks;
181 /** These fields are extracted from "division" field of MThd header. Valid is _either_ ppqn or frames_per_second/resolution. */
182 int ppqn;
183 int frames_per_second;
184 int resolution;
185 int number_of_tracks;
187 /** These are private fields using only by loading and saving routines. */
188 FILE *stream;
189 void *file_buffer;
190 int file_buffer_length;
191 int next_chunk_offset;
193 /** Private, used by smf.c. */
194 GPtrArray *tracks_array;
195 double last_seek_position;
197 /** Private, used by smf_tempo.c. */
198 /** Array of pointers to smf_tempo_struct. */
199 GPtrArray *tempo_array;
202 typedef struct smf_struct smf_t;
204 /** This structure describes a single tempo change. */
205 struct smf_tempo_struct {
206 int time_pulses;
207 double time_seconds;
208 int microseconds_per_quarter_note;
209 int numerator;
210 int denominator;
211 int clocks_per_click;
212 int notes_per_note;
215 typedef struct smf_tempo_struct smf_tempo_t;
217 struct smf_track_struct {
218 smf_t *smf;
220 int track_number;
221 int number_of_events;
223 /** These are private fields using only by loading and saving routines. */
224 void *file_buffer;
225 int file_buffer_length;
226 int last_status; /* Used for "running status". */
228 /** Private, used by smf.c. */
229 /** Offset into buffer, used in parse_next_event(). */
230 int next_event_offset;
231 int next_event_number;
233 /** Absolute time of next event on events_queue. */
234 int time_of_next_event;
235 GPtrArray *events_array;
238 typedef struct smf_track_struct smf_track_t;
240 struct smf_event_struct {
241 /** Pointer to the track, or NULL if event is not attached. */
242 smf_track_t *track;
244 /** Number of this event in the track. Events are numbered consecutively, starting from one. */
245 int event_number;
247 /** Note that the time fields are invalid, if event is not attached to a track. */
248 /** Time, in pulses, since the previous event on this track. */
249 int delta_time_pulses;
251 /** Time, in pulses, since the start of the song. */
252 int time_pulses;
254 /** Time, in seconds, since the start of the song. */
255 double time_seconds;
257 /** Tracks are numbered consecutively, starting from 1. */
258 int track_number;
260 /** Pointer to the buffer containing MIDI message. This is freed by smf_event_delete. */
261 unsigned char *midi_buffer;
263 /** Length of the MIDI message in the buffer, in bytes. */
264 int midi_buffer_length;
267 typedef struct smf_event_struct smf_event_t;
269 /* Routines for manipulating smf_t. */
270 smf_t *smf_new(void);
271 void smf_delete(smf_t *smf);
273 int smf_set_format(smf_t *smf, int format);
274 int smf_set_ppqn(smf_t *smf, int format);
276 char *smf_decode(const smf_t *smf);
278 smf_track_t *smf_get_track_by_number(const smf_t *smf, int track_number);
279 smf_event_t *smf_get_next_event(smf_t *smf);
280 smf_event_t *smf_peek_next_event(smf_t *smf);
281 void smf_rewind(smf_t *smf);
282 int smf_seek_to_seconds(smf_t *smf, double seconds);
283 int smf_seek_to_pulses(smf_t *smf, int pulses);
284 int smf_seek_to_event(smf_t *smf, const smf_event_t *event);
286 int smf_get_length_pulses(const smf_t *smf);
287 double smf_get_length_seconds(const smf_t *smf);
288 int smf_event_is_last(const smf_event_t *event);
290 void smf_add_track(smf_t *smf, smf_track_t *track);
291 void smf_remove_track(smf_track_t *track);
293 /* Routines for manipulating smf_track_t. */
294 smf_track_t *smf_track_new(void);
295 void smf_track_delete(smf_track_t *track);
297 smf_event_t *smf_track_get_next_event(smf_track_t *track);
298 smf_event_t *smf_track_get_event_by_number(const smf_track_t *track, int event_number);
299 smf_event_t *smf_track_get_last_event(const smf_track_t *track);
301 void smf_track_add_event_delta_pulses(smf_track_t *track, smf_event_t *event, int pulses);
302 void smf_track_add_event_pulses(smf_track_t *track, smf_event_t *event, int pulses);
303 void smf_track_add_event_seconds(smf_track_t *track, smf_event_t *event, double seconds);
304 int smf_track_add_eot_delta_pulses(smf_track_t *track, int delta);
305 int smf_track_add_eot_pulses(smf_track_t *track, int pulses);
306 int smf_track_add_eot_seconds(smf_track_t *track, double seconds);
307 void smf_track_remove_event(smf_event_t *event);
309 /* Routines for manipulating smf_event_t. */
310 smf_event_t *smf_event_new(void);
311 smf_event_t *smf_event_new_from_pointer(void *midi_data, int len);
312 smf_event_t *smf_event_new_from_bytes(int first_byte, int second_byte, int third_byte);
313 void smf_event_delete(smf_event_t *event);
315 int smf_event_is_valid(const smf_event_t *event);
316 int smf_event_is_metadata(const smf_event_t *event);
317 int smf_event_is_system_realtime(const smf_event_t *event);
318 int smf_event_is_system_common(const smf_event_t *event);
319 int smf_event_is_eot(const smf_event_t *event);
320 char *smf_event_decode(const smf_event_t *event);
321 char *smf_string_from_event(const smf_event_t *event);
323 /* Routines for loading SMF files. */
324 smf_t *smf_load(const char *file_name);
325 smf_t *smf_load_from_memory(const void *buffer, const int buffer_length);
327 /* Routine for writing SMF files. */
328 int smf_save(smf_t *smf, const char *file_name);
330 /* Routines for manipulating smf_tempo_t. */
331 smf_tempo_t *smf_get_tempo_by_pulses(const smf_t *smf, int pulses);
332 smf_tempo_t *smf_get_tempo_by_seconds(const smf_t *smf, double seconds);
333 smf_tempo_t *smf_get_tempo_by_number(const smf_t *smf, int number);
334 smf_tempo_t *smf_get_last_tempo(const smf_t *smf);
336 const char *smf_get_version(void);
338 #ifdef __cplusplus
340 #endif
342 #endif /* SMF_H */