~ubuntu-branches/ubuntu/utopic/ardour3/utopic

« back to all changes in this revision

Viewing changes to libs/evoral/src/libsmf/smf.h

  • Committer: Package Import Robot
  • Author(s): Felipe Sateler
  • Date: 2013-09-21 19:05:02 UTC
  • Revision ID: package-import@ubuntu.com-20130921190502-8gsftrku6jnzhd7v
Tags: upstream-3.4~dfsg
ImportĀ upstreamĀ versionĀ 3.4~dfsg

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*-
 
2
 * Copyright (c) 2007, 2008 Edward Tomasz Napierała <trasz@FreeBSD.org>
 
3
 * All rights reserved.
 
4
 *
 
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.
 
13
 *
 
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.
 
25
 *
 
26
 */
 
27
 
 
28
/**
 
29
 * \file
 
30
 *
 
31
 * Public interface declaration for libsmf, Standard MIDI File format library.
 
32
 */
 
33
 
 
34
/**
 
35
 *
 
36
 * \page libsmf libsmf - general usage instructions
 
37
 *
 
38
 * An smf_t structure represents a "song".  Every valid smf contains one or more tracks.
 
39
 * Tracks contain zero or more events.  Libsmf doesn't care about actual MIDI data, as long
 
40
 * as it is valid from the MIDI specification point of view - it may be realtime message,
 
41
 * SysEx, whatever.
 
42
 * 
 
43
 * The only field in smf_t, smf_track_t, smf_event_t and smf_tempo_t structures your
 
44
 * code may modify is event->midi_buffer and event->midi_buffer_length.  Do not modify
 
45
 * other fields, _ever_.  You may read them, though.  Do not declare static instances
 
46
 * of these types, i.e. never do something like this:  "smf_t smf;".  Always use
 
47
 * "smf_t *smf = smf_new();".  The same applies to smf_track_t and smf_event_t.
 
48
 * 
 
49
 * Say you want to load a Standard MIDI File (.mid) file and play it back somehow.
 
50
 * This is (roughly) how you do this:
 
51
 * 
 
52
 * \code
 
53
 *      smf_t *smf;
 
54
 *      smf_event_t *event;
 
55
 *
 
56
 *      smf = smf_load(file_name);
 
57
 *      if (smf == NULL) {
 
58
 *              Whoops, something went wrong.
 
59
 *              return;
 
60
 *      }
 
61
 * 
 
62
 *      while ((event = smf_get_next_event(smf)) != NULL) {
 
63
 *              if (smf_event_is_metadata(event))
 
64
 *                      continue;
 
65
 * 
 
66
 *              wait until event->time_seconds.
 
67
 *              feed_to_midi_output(event->midi_buffer, event->midi_buffer_length);
 
68
 *      }
 
69
 *
 
70
 *      smf_delete(smf);
 
71
 *
 
72
 * \endcode
 
73
 * 
 
74
 * Saving works like this:
 
75
 * 
 
76
 * \code
 
77
 *
 
78
 *      smf_t *smf;
 
79
 *      smf_track_t *track;
 
80
 *      smf_event_t *event;
 
81
 *
 
82
 *      smf = smf_new();
 
83
 *      if (smf == NULL) {
 
84
 *              Whoops.
 
85
 *              return;
 
86
 *      }
 
87
 * 
 
88
 *      for (int i = 1; i <= number of tracks; i++) {
 
89
 *              track = smf_track_new();
 
90
 *              if (track == NULL) {
 
91
 *                      Whoops.
 
92
 *                      return;
 
93
 *              }
 
94
 * 
 
95
 *              smf_add_track(smf, track);
 
96
 * 
 
97
 *              for (int j = 1; j <= number of events you want to put into this track; j++) {
 
98
 *                      event = smf_event_new_from_pointer(your MIDI message, message length);
 
99
 *                      if (event == NULL) {
 
100
 *                              Whoops.
 
101
 *                              return;
 
102
 *                      }
 
103
 * 
 
104
 *                      smf_track_add_event_seconds(track, event, seconds since start of the song);
 
105
 *              }
 
106
 *      }
 
107
 * 
 
108
 *      ret = smf_save(smf, file_name);
 
109
 *      if (ret) {
 
110
 *              Whoops, saving failed for some reason.
 
111
 *              return;
 
112
 *      }
 
113
 *
 
114
 *      smf_delete(smf);
 
115
 *
 
116
 * \endcode
 
117
 *
 
118
 * There are two basic ways of getting MIDI data out of smf - sequential or by track/event number.
 
119
 * You may mix them if you need to.  First one is used in the example above - seek to the point
 
120
 * from which you want the playback to start (using smf_seek_to_seconds(), smf_seek_to_pulses()
 
121
 * or smf_seek_to_event()) and then do smf_get_next_event() in loop, until it returns NULL.
 
122
 * Calling smf_load() causes the smf to be rewound to the start of the song.
 
123
 *
 
124
 * Getting events by number works like this:
 
125
 *
 
126
 * \code
 
127
 *
 
128
 * smf_track_t *track = smf_get_track_by_number(smf, track_number);
 
129
 * smf_event_t *event = smf_track_get_event_by_number(track, event_number);
 
130
 *
 
131
 * \endcode
 
132
 *
 
133
 * To create new event, use smf_event_new(), smf_event_new_from_pointer() or
 
134
 * smf_event_new_from_bytes().  First one creates an empty event - you need to manually allocate
 
135
 * (using malloc(3)) buffer for MIDI data, write MIDI data into it, put the address of that
 
136
 * buffer into event->midi_buffer, and the length of MIDI data into event->midi_buffer_length.
 
137
 * Note that deleting the event (using smf_event_delete()) will free the buffer.
 
138
 *
 
139
 * Second form does most of this for you: it takes an address of the buffer containing MIDI data,
 
140
 * allocates storage and copies MIDI data into it.
 
141
 *
 
142
 * Third form is useful for manually creating short events, up to three bytes in length, for
 
143
 * example Note On or Note Off events.  It simply takes three bytes and creates MIDI event
 
144
 * containing them.  If you need to create MIDI message that takes only two bytes, pass -1 as
 
145
 * the third byte.  For one byte message (System Realtime), pass -1 as second and third byte.
 
146
 *
 
147
 * To free an event, use smf_event_delete().
 
148
 *
 
149
 * To add event to the track, use smf_track_add_event_delta_pulses(), smf_track_add_event_pulses(),
 
150
 * or smf_track_add_event_seconds().  The difference between them is in the way you specify the
 
151
 * time of the event - with the first one, you specify it as an interval, in pulses, from the
 
152
 * previous event in this track; with the second one, you specify it as pulses from the start
 
153
 * of the song, and with the last one, you specify it as seconds from the start of the song.
 
154
 * Obviously, the first version can only append events at the end of the track.
 
155
 *
 
156
 * To remove an event from the track it's attached to, use smf_event_remove_from_track().
 
157
 * You may want to free the event (using smf_event_delete()) afterwards.
 
158
 *
 
159
 * To create new track, use smf_track_new().  To add track to the smf, use smf_add_track().
 
160
 * To remove track from its smf, use smf_track_remove_from_smf().  To free the track structure,
 
161
 * use smf_track_delete().
 
162
 *
 
163
 * Note that libsmf keeps things consistent.  If you free (using smf_track_delete()) a track
 
164
 * that is attached to an smf and contains events, libsmf will detach the events, free them,
 
165
 * detach the track, free it etc.
 
166
 *
 
167
 * Tracks and events are numbered consecutively, starting from one.  If you remove a track
 
168
 * or event, the rest of tracks/events will get renumbered.  To get the number of a given
 
169
 * event in its track, use event->event_number.  To get the number of track in its smf, use
 
170
 * track->track_number.  To get the number of events in the track, use track->number_of_events.
 
171
 * To get the number of tracks in the smf, use smf->number_of_tracks.
 
172
 *
 
173
 * In SMF File Format, each track has to end with End Of Track metaevent.  If you load SMF file
 
174
 * using smf_load(), that will be the case.  If you want to create or edit an SMF, you don't
 
175
 * need to worry about EOT events; libsmf automatically takes care of them for you.  If you
 
176
 * try to save an SMF with tracks that do not end with EOTs, smf_save() will append them.
 
177
 * If you try to add event that happens after EOT metaevent, libsmf will remove the EOT.
 
178
 * If you want to add EOT manually, you can, of course, using smf_track_add_eot_seconds()
 
179
 * or smf_track_add_eot_pulses().
 
180
 *
 
181
 * Each event carries three time values - event->time_seconds, which is seconds since
 
182
 * the start of the song, event->time_pulses, which is PPQN clocks since the start of
 
183
 * the song, and event->delta_pulses, which is PPQN clocks since the previous event
 
184
 * in that track.  These values are invalid if the event is not attached to the track.
 
185
 * If event is attached, all three values are valid.  Time of the event is specified when
 
186
 * adding the event (using smf_track_add_event_seconds(), smf_track_add_event_pulses() or
 
187
 * smf_track_add_event_delta_pulses()); the remaining two values are computed from that.
 
188
 *
 
189
 * Tempo related stuff happens automatically - when you add a metaevent that is Tempo PropertyChange or
 
190
 * Time Signature, libsmf adds that event to the tempo map.  If you remove Tempo PropertyChange event
 
191
 * that is in the middle of the song, the rest of the events will have their event->time_seconds
 
192
 * recomputed from event->time_pulses before smf_event_remove_from_track() function returns.
 
193
 * Adding Tempo PropertyChange in the middle of the song works in a similar way.
 
194
 *
 
195
 * MIDI data (event->midi_buffer) is always kept in normalized form - it always begins with
 
196
 * status byte (no running status), there are no System Realtime events embedded in them etc.
 
197
 * Events like SysExes are in "on the wire" form, without embedded length that is used in SMF
 
198
 * file format.  Obviously libsmf "normalizes" MIDI data during loading and "denormalizes" (adding
 
199
 * length to SysExes, escaping System Common and System Realtime messages etc) during writing.
 
200
 *
 
201
 * Note that you always have to first add the track to smf, and then add events to the track.
 
202
 * Doing it the other way around will trip asserts.  Also, try to add events at the end of the
 
203
 * track and remove them from the end of the track, that's much more efficient.
 
204
 *
 
205
 * All the libsmf functions have prefix "smf_".  First argument for routines whose names start
 
206
 * with "smf_event_" is "smf_event_t *", for routines whose names start with "smf_track_" -
 
207
 * "smf_track_t *", and for plain "smf_" - "smf_t *".  The only exception are smf_whatever_new
 
208
 * routines.  Library does not use any global variables and is thread-safe, as long as you
 
209
 * don't try to work on the same SMF (smf_t and its descendant tracks and events) from several
 
210
 * threads at once without protecting it with mutex.  Library depends on glib and nothing else.
 
211
 * License is BSD, two clause, which basically means you can use it freely in your software,
 
212
 * both Open Source (including GPL) and closed source.
 
213
 *
 
214
 */
 
215
 
 
216
#ifndef SMF_H
 
217
#define SMF_H
 
218
 
 
219
#ifdef __cplusplus
 
220
extern "C" {
 
221
#endif
 
222
 
 
223
#include <stdio.h>
 
224
#include <stdint.h>
 
225
#include <glib.h>
 
226
 
 
227
#if defined(__GNUC__) && __GNUC__ >= 4
 
228
#define WARN_UNUSED_RESULT __attribute__ ((warn_unused_result))
 
229
#else
 
230
#define WARN_UNUSED_RESULT
 
231
#endif
 
232
 
 
233
/** Represents a "song", that is, collection of one or more tracks. */
 
234
struct smf_struct {
 
235
        int        format;
 
236
 
 
237
        /** These fields are extracted from "division" field of MThd header.
 
238
         * Valid is _either_ ppqn or frames_per_second/resolution. */
 
239
        uint16_t   ppqn;
 
240
        int        frames_per_second;
 
241
        int        resolution;
 
242
        int        number_of_tracks;
 
243
 
 
244
        /** These are private fields using only by loading and saving routines. */
 
245
        FILE      *stream;
 
246
        void      *file_buffer;
 
247
        size_t     file_buffer_length;
 
248
        size_t     next_chunk_offset;
 
249
        int        expected_number_of_tracks;
 
250
 
 
251
        /** Private, used by smf.c. */
 
252
        GPtrArray *tracks_array;
 
253
        double     last_seek_position;
 
254
 
 
255
        /** Private, used by smf_tempo.c. */
 
256
        /** Array of pointers to smf_tempo_struct. */
 
257
        GPtrArray *tempo_array;
 
258
};
 
259
 
 
260
typedef struct smf_struct smf_t;
 
261
 
 
262
/** Describes a single tempo or time signature change. */
 
263
struct smf_tempo_struct {
 
264
        size_t time_pulses;
 
265
        double time_seconds;
 
266
        int    microseconds_per_quarter_note;
 
267
        int    numerator;
 
268
        int    denominator;
 
269
        int    clocks_per_click;
 
270
        int    notes_per_note;
 
271
};
 
272
 
 
273
typedef struct smf_tempo_struct smf_tempo_t;
 
274
 
 
275
/** Represents a single track. */
 
276
struct smf_track_struct {
 
277
        smf_t     *smf;
 
278
 
 
279
        int        track_number;
 
280
        size_t     number_of_events;
 
281
 
 
282
        /** These are private fields using only by loading and saving routines. */
 
283
        void      *file_buffer;
 
284
        size_t     file_buffer_length;
 
285
        int        last_status; /* Used for "running status". */
 
286
 
 
287
        /** Private, used by smf.c. */
 
288
        /** Offset into buffer, used in parse_next_event(). */
 
289
        size_t     next_event_offset;
 
290
        size_t     next_event_number;
 
291
 
 
292
        /** Absolute time of next event on events_queue. */
 
293
        size_t     time_of_next_event;
 
294
        GPtrArray *events_array;
 
295
};
 
296
 
 
297
typedef struct smf_track_struct smf_track_t;
 
298
 
 
299
/** Represents a single MIDI event or metaevent. */
 
300
struct smf_event_struct {
 
301
        /** Pointer to the track, or NULL if event is not attached. */
 
302
        smf_track_t *track;
 
303
 
 
304
        /** Number of this event in the track.  Events are numbered consecutively, starting from 1. */
 
305
        size_t       event_number;
 
306
 
 
307
        /** Note that the time fields are invalid, if event is not attached to a track. */
 
308
        /** Time, in pulses, since the previous event on this track. */
 
309
        int32_t      delta_time_pulses;
 
310
 
 
311
        /** Time, in pulses, since the start of the song. */
 
312
        size_t       time_pulses;
 
313
 
 
314
        /** Time, in seconds, since the start of the song. */
 
315
        double       time_seconds;
 
316
 
 
317
        /** Tracks are numbered consecutively, starting from 1. */
 
318
        int          track_number;
 
319
 
 
320
        /** Pointer to the buffer containing MIDI message.  This is freed by smf_event_delete. */
 
321
        uint8_t     *midi_buffer;
 
322
 
 
323
        /** Length of the MIDI message in the buffer, in bytes. */
 
324
        size_t       midi_buffer_length;
 
325
};
 
326
 
 
327
typedef struct smf_event_struct smf_event_t;
 
328
 
 
329
/* Routines for manipulating smf_t. */
 
330
smf_t *smf_new(void) WARN_UNUSED_RESULT;
 
331
void   smf_delete(smf_t *smf);
 
332
 
 
333
int smf_set_format(smf_t *smf, int format) WARN_UNUSED_RESULT;
 
334
int smf_set_ppqn(smf_t *smf, uint16_t ppqn) WARN_UNUSED_RESULT;
 
335
 
 
336
char *smf_decode(const smf_t *smf) WARN_UNUSED_RESULT;
 
337
 
 
338
smf_track_t *smf_get_track_by_number(const smf_t *smf, int track_number) WARN_UNUSED_RESULT;
 
339
 
 
340
smf_event_t *smf_peek_next_event(smf_t *smf) WARN_UNUSED_RESULT;
 
341
smf_event_t *smf_get_next_event(smf_t *smf) WARN_UNUSED_RESULT;
 
342
void         smf_skip_next_event(smf_t *smf);
 
343
 
 
344
void smf_rewind(smf_t *smf);
 
345
int  smf_seek_to_seconds(smf_t *smf, double seconds) WARN_UNUSED_RESULT;
 
346
int  smf_seek_to_pulses(smf_t *smf, size_t pulses) WARN_UNUSED_RESULT;
 
347
int  smf_seek_to_event(smf_t *smf, const smf_event_t *event) WARN_UNUSED_RESULT;
 
348
 
 
349
size_t smf_get_length_pulses(const smf_t *smf) WARN_UNUSED_RESULT;
 
350
double smf_get_length_seconds(const smf_t *smf) WARN_UNUSED_RESULT;
 
351
int    smf_event_is_last(const smf_event_t *event) WARN_UNUSED_RESULT;
 
352
 
 
353
void smf_add_track(smf_t *smf, smf_track_t *track);
 
354
void smf_track_remove_from_smf(smf_track_t *track);
 
355
 
 
356
/* Routines for manipulating smf_track_t. */
 
357
smf_track_t *smf_track_new(void) WARN_UNUSED_RESULT;
 
358
void         smf_track_delete(smf_track_t *track);
 
359
 
 
360
smf_event_t *smf_track_get_next_event(smf_track_t *track) WARN_UNUSED_RESULT;
 
361
smf_event_t *smf_track_get_event_by_number(const smf_track_t *track, size_t num) WARN_UNUSED_RESULT;
 
362
smf_event_t *smf_track_get_last_event(const smf_track_t *track) WARN_UNUSED_RESULT;
 
363
 
 
364
void smf_track_add_event_delta_pulses(smf_track_t *track, smf_event_t *event, uint32_t delta);
 
365
void smf_track_add_event_pulses(smf_track_t *track, smf_event_t *event, size_t pulses);
 
366
void smf_track_add_event_seconds(smf_track_t *track, smf_event_t *event, double seconds);
 
367
int  smf_track_add_eot_delta_pulses(smf_track_t *track, uint32_t delta) WARN_UNUSED_RESULT;
 
368
int  smf_track_add_eot_pulses(smf_track_t *track, size_t pulses) WARN_UNUSED_RESULT;
 
369
int  smf_track_add_eot_seconds(smf_track_t *track, double seconds) WARN_UNUSED_RESULT;
 
370
void smf_event_remove_from_track(smf_event_t *event);
 
371
 
 
372
/* Routines for manipulating smf_event_t. */
 
373
smf_event_t *smf_event_new(void) WARN_UNUSED_RESULT;
 
374
smf_event_t *smf_event_new_from_pointer(const void *midi_data, size_t len) WARN_UNUSED_RESULT;
 
375
smf_event_t *smf_event_new_from_bytes(int byte1, int byte2, int byte3) WARN_UNUSED_RESULT;
 
376
smf_event_t *smf_event_new_textual(int type, const char *text);
 
377
void         smf_event_delete(smf_event_t *event);
 
378
 
 
379
int   smf_event_is_valid(const smf_event_t *event) WARN_UNUSED_RESULT;
 
380
int   smf_event_is_metadata(const smf_event_t *event) WARN_UNUSED_RESULT;
 
381
int   smf_event_is_system_realtime(const smf_event_t *event) WARN_UNUSED_RESULT;
 
382
int   smf_event_is_system_common(const smf_event_t *event) WARN_UNUSED_RESULT;
 
383
int   smf_event_is_sysex(const smf_event_t *event) WARN_UNUSED_RESULT;
 
384
int   smf_event_is_eot(const smf_event_t *event) WARN_UNUSED_RESULT;
 
385
int   smf_event_is_textual(const smf_event_t *event) WARN_UNUSED_RESULT;
 
386
char *smf_event_decode(const smf_event_t *event) WARN_UNUSED_RESULT;
 
387
char *smf_event_extract_text(const smf_event_t *event) WARN_UNUSED_RESULT;
 
388
 
 
389
/* Routines for dealing with Variable Length Quantities (VLQ's). 
 
390
   Slightly odd names reflect original static names within libsmf
 
391
 */
 
392
int smf_format_vlq (unsigned char *buf, int length, unsigned long value);
 
393
int smf_extract_vlq(const unsigned char *buf, const size_t buffer_length, uint32_t *value, uint32_t *len);
 
394
 
 
395
/* Routines for loading SMF files. */
 
396
smf_t *smf_load(FILE *) WARN_UNUSED_RESULT;
 
397
smf_t *smf_load_from_memory(const void *buffer, const size_t buffer_length) WARN_UNUSED_RESULT;
 
398
 
 
399
/* Routine for writing SMF files. */
 
400
int smf_save(smf_t *smf, FILE *file) WARN_UNUSED_RESULT;
 
401
 
 
402
/* Routines for manipulating smf_tempo_t. */
 
403
smf_tempo_t *smf_get_tempo_by_pulses(const smf_t *smf, size_t pulses) WARN_UNUSED_RESULT;
 
404
smf_tempo_t *smf_get_tempo_by_seconds(const smf_t *smf, double seconds) WARN_UNUSED_RESULT;
 
405
smf_tempo_t *smf_get_tempo_by_number(const smf_t *smf, size_t number) WARN_UNUSED_RESULT;
 
406
smf_tempo_t *smf_get_last_tempo(const smf_t *smf) WARN_UNUSED_RESULT;
 
407
 
 
408
const char *smf_get_version(void) WARN_UNUSED_RESULT;
 
409
 
 
410
#ifdef __cplusplus
 
411
}
 
412
#endif
 
413
 
 
414
#endif /* SMF_H */
 
415