├── LICENSE_1_0.txt ├── include └── blastmidi.h ├── readme.txt └── src ├── blastmidi.c └── blastmidi_utility.h /LICENSE_1_0.txt: -------------------------------------------------------------------------------- 1 | Boost Software License - Version 1.0 - August 17th, 2003 2 | 3 | Permission is hereby granted, free of charge, to any person or organization 4 | obtaining a copy of the software and accompanying documentation covered by 5 | this license (the "Software") to use, reproduce, display, distribute, 6 | execute, and transmit the Software, and to prepare derivative works of the 7 | Software, and to permit third-parties to whom the Software is furnished to 8 | do so, all subject to the following: 9 | 10 | The copyright notices in the Software and this entire statement, including 11 | the above license grant, this restriction and the following disclaimer, 12 | must be included in all copies of the Software, in whole or in part, and 13 | all derivative works of the Software, unless such copies or derivative 14 | works are solely in the form of machine-executable object code generated by 15 | a source language processor. 16 | 17 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 18 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 19 | FITNESS FOR A PARTICULAR PURPOSE, TITLE AND NON-INFRINGEMENT. IN NO EVENT 20 | SHALL THE COPYRIGHT HOLDERS OR ANYONE DISTRIBUTING THE SOFTWARE BE LIABLE 21 | FOR ANY DAMAGES OR OTHER LIABILITY, WHETHER IN CONTRACT, TORT OR OTHERWISE, 22 | ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 23 | DEALINGS IN THE SOFTWARE. 24 | -------------------------------------------------------------------------------- /include/blastmidi.h: -------------------------------------------------------------------------------- 1 | /* 2 | * BlastMidi 3 | * 4 | * A library of routines for working with Midi files. 5 | * 6 | * Copyright Blastbay Studios (Philip Bennefall) 2014 - 2015. 7 | * Distributed under the Boost Software License, Version 1.0. 8 | * (See accompanying file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * blastmidi.h 12 | * The main library header which defines the public API. 13 | */ 14 | 15 | #ifndef BLASTMIDI_H 16 | #define BLASTMIDI_H 17 | 18 | #include /* For uint8_t, uint16_t etc */ 19 | 20 | /* 21 | * Error codes. 22 | */ 23 | enum blastmidi_errors 24 | { 25 | BLASTMIDI_OK = 0, /* All is joy */ 26 | BLASTMIDI_INVALIDPARAM, /* One or more invalid parameters were passed to the function */ 27 | BLASTMIDI_OUTOFMEMORY, /* Out of memory */ 28 | BLASTMIDI_ALREADYADDED, /* This event has already been added to a track and is now owned by the given blastmidi instance. */ 29 | BLASTMIDI_NOTADDED, /* This event has not been added to a track in the given blastmidi instance. */ 30 | BLASTMIDI_NOTPARTOFTRACK, /* This event is not part of the specified track. */ 31 | BLASTMIDI_NOCALLBACK, /* No I/O callback provided */ 32 | BLASTMIDI_INVALIDCHUNK, /* The Midi file contained an invalid chunk */ 33 | BLASTMIDI_INCOMPLETECHUNK, /* The Midi file chunk ended unexpectedly */ 34 | BLASTMIDI_UNEXPECTEDEND, /* The Midi file ended unexpectedly */ 35 | BLASTMIDI_WRITINGFAILED, /* Writing failed */ 36 | BLASTMIDI_INVALID /* This is not a valid Midi file */ 37 | }; 38 | 39 | /* 40 | * Meta event types. 41 | */ 42 | enum blastmidi_meta_events 43 | { 44 | BLASTMIDI_META_SEQUENCE_NUMBER = 0, 45 | BLASTMIDI_META_TEXT, 46 | BLASTMIDI_META_COPYRIGHT_NOTICE, 47 | BLASTMIDI_META_SEQUENCE_OR_TRACK_NAME, 48 | BLASTMIDI_META_INSTRUMENT_NAME, 49 | BLASTMIDI_META_LYRICS, 50 | BLASTMIDI_META_MARKER, 51 | BLASTMIDI_META_CUE_POINT, 52 | BLASTMIDI_META_MIDI_CHANNEL_PREFIX = 32, 53 | BLASTMIDI_META_END_OF_TRACK = 47, 54 | BLASTMIDI_META_SET_TEMPO = 81, 55 | BLASTMIDI_META_SMPTE_OFFSET = 84, 56 | BLASTMIDI_META_TIME_SIGNATURE = 88, 57 | BLASTMIDI_META_KEY_SIGNATURE, 58 | BLASTMIDI_META_SEQUENCER_SPECIFIC = 127 59 | }; 60 | 61 | /* 62 | * Midi channel event types. 63 | */ 64 | enum blastmidi_channel_events 65 | { 66 | BLASTMIDI_CHANNEL_NOTE_OFF = 8, 67 | BLASTMIDI_CHANNEL_NOTE_ON, 68 | BLASTMIDI_CHANNEL_NOTE_AFTERTOUCH, 69 | BLASTMIDI_CHANNEL_CONTROLLER, 70 | BLASTMIDI_CHANNEL_PROGRAM_CHANGE, 71 | BLASTMIDI_CHANNEL_CHANNEL_AFTERTOUCH, 72 | BLASTMIDI_CHANNEL_PITCH_BEND 73 | }; 74 | 75 | /* 76 | * Data I/O callback actions. 77 | */ 78 | enum blastmidi_callback_actions 79 | { 80 | BLASTMIDI_CALLBACK_READ, 81 | BLASTMIDI_CALLBACK_WRITE, 82 | BLASTMIDI_CALLBACK_SEEK 83 | }; 84 | 85 | /* 86 | * The blastmidi_data_callback function. 87 | * The first parameter indicates an action that the callback should perform. 88 | * This is one of the values specified in the blastmidi_callback_actions enum. 89 | * The second parameter specifies the number of bytes to seek, read or write depending on the action. 90 | * If the first parameter is BLASTMIDI_CALLBACK_SEEK, the second parameter is an absolute value. 91 | * In all other cases, it is relative. 92 | * The third parameter is a pointer to a buffer which holds at least the number of bytes specified in the second parameter. 93 | * This is where you should either read or write your data. 94 | * If the first parameter is BLASTMIDI_CALLBACK_SEEK, this buffer is not used. 95 | * The fourth parameter is a user controlled void* pointer which is not used in any way by the library, but merely passed along. 96 | * The callback should return 0 on failure and anything else on success. 97 | * The callback must not invoke any function that operates on the blastmidi instance with which this callback is associated. 98 | */ 99 | typedef int blastmidi_data_callback ( int, size_t, uint8_t*, void* ); 100 | 101 | /* 102 | * The custom memory allocation functions. 103 | * It is possible to replace the default malloc and free implementations with your own custom functions. 104 | * These must have the same signature as malloc and free. 105 | * See the blastmidi_initialize function for more information on how to set these. 106 | */ 107 | typedef void* blastmidi_custom_malloc ( size_t ); 108 | typedef void blastmidi_custom_free ( void* ); 109 | 110 | /* 111 | * Midi event types enum. 112 | * This enum lists the three Midi event types (Midi channel event, meta event and system exclusive event. 113 | */ 114 | enum blastmidi_event_types 115 | { 116 | BLASTMIDI_CHANNEL_EVENT = 1, 117 | BLASTMIDI_META_EVENT, 118 | BLASTMIDI_SYSEX_EVENT 119 | }; 120 | 121 | /* 122 | * The blastmidi_event structure. 123 | * This structure represents a Midi event. 124 | * The track member indicates whether this event belongs to a track. If this is -1, the event has not yet been added to any track. 125 | * time specifies the delta time in ticks where this event occurs. 126 | * type specifies the event type (Midi channel event, meta event or system exclusive event as listed in the enum above). 127 | * subtype specifies the type of the event in the given category if applicable. 128 | * If type is BLASTMIDI_META_EVENT, subtype corresponds to one of the values in the blastmidi_meta_events enum. 129 | * If type is BLASTMIDI_CHANNEL_EVENT, subtype corresponds to one of the values in the blastmidi_channel_events enum. 130 | * If type is BLASTMIDI_SYSEX_EVENT, subtype is not used. 131 | * 132 | * If type is BLASTMIDI_CHANNEL_EVENT, channel indicates the channel to which this event applies. 133 | * If type is BLASTMIDI_META_EVENT and subtype is BLASTMIDI_META_MIDI_CHANNEL_PREFIX, channel specifies the channel being referred to. 134 | * Otherwise, channel is not used. 135 | * 136 | * data is a pointer to the first data byte in the event, and data_size specifies the number of bytes present. 137 | * If data_size is 0, do not access data. 138 | * 139 | * If type is BLASTMIDI_CHANNEL_EVENT and subtype is BLASTMIDI_CHANNEL_PITCH_BEND, data should be interpreted as a 140 | * uint16_t (in native endian byte order) representing the bend amount. 141 | * The range is between 0 and 16383 (inclusive) where values below 8192 decrease the pitch, and values above increase it. 142 | * 143 | * end_of_sysex is only applicable when type is BLASTMIDI_SYSEX_EVENT. 144 | * System exclusive messages are sometimes split into several events if the amount of data is large. 145 | * end_of_sysex is nonzero if this is the final chunk of the given system exclusive data. 146 | * If all of the system exclusive data is contained in a single event, end_of_sysex is nonzero. 147 | * Otherwise, end_of_sysex is 0 for all the parts except the last one. 148 | * 149 | * small_pool is an array of two bytes which is used to store very short data buffers. 150 | * Since a lot of Midi events do not have more than two data bytes we can greatly reduce the number of allocations this way. 151 | * The data pointer above will refer to the first byte of small_pool if applicable. 152 | * 153 | * previous and next are pointers to the previous and the next event on the track, respectively. 154 | * 155 | * Do not modify the members in this structure by hand, and do not access them before the structure has been populated by one of 156 | * the library functions. 157 | */ 158 | typedef struct blastmidi_event 159 | { 160 | int16_t track; 161 | uint32_t time; 162 | uint8_t type; 163 | uint8_t subtype; 164 | int8_t channel; 165 | uint8_t* data; 166 | uint32_t data_size; 167 | uint8_t end_of_sysex; 168 | uint8_t small_pool[2]; 169 | struct blastmidi_event* previous; 170 | struct blastmidi_event* next; 171 | } blastmidi_event; 172 | 173 | /* 174 | * The blastmidi structure. 175 | * You should never access the elements in this structure directly. 176 | * It holds the core internal state for the BlastMidi library. 177 | * data_callback is a pointer to the callback which handles data I/O. 178 | * data_callback_data is a user controlled void* pointer which the library passes along to the data callback. 179 | * endian_flag is a flag storing the result of the runtime check for little endian. 180 | * 0 is yet unchecked, 1 is little endian and 2 is not little endian (we assume big endian in this scenario). 181 | * malloc_function and free_function are pointers to memory allocation functions (the system defined malloc and free by default). 182 | * track_count specifies the number of tracks in the file. 183 | * file_type specifies what type of Midi file this is (0, 1 or 2). 184 | * time_type specifies what type of time measurement is used (0 for ticks per beat or 1 for ticks per SMPTE frame). 185 | * ticks_per_beat specifies the number of ticks per beat, and is valid if time_type is 0. 186 | * SMPTE_frames specifies the number of frames per second (24, 25, 29 or 30). Valid only if time_type is 1. 187 | * ticks_per_frame specifies the number of ticks per frame (valid only if time_type is 1). 188 | * valid is a flag that specifies whether the whole Midi file is valid or not(0=not valid, 1=valid). 189 | * tracks is an array of pointers to the first event in each track that makes up the Midi file. 190 | * The events in each track are organized as a linked list. 191 | * track_ends is an array of pointers to the last event in each track that makes up the Midi file. 192 | * The number of items in the track_ends list is specified by chunk_count. 193 | * The next member of the blastmidi_event structures pointed to in this array should always be NULL. 194 | * cursor is an I/O cursor used by the parser. 195 | * running_status holds the last received status byte in a Midi channel event, so that the status can be reused as needed. 196 | * sysex_continuation is a boolean flag which keeps track of whether a divided system exclusive message is being read. 197 | */ 198 | typedef struct blastmidi 199 | { 200 | blastmidi_data_callback* data_callback; 201 | void* data_callback_data; 202 | int8_t endian_flag; 203 | blastmidi_custom_malloc* malloc_function; 204 | blastmidi_custom_free* free_function; 205 | uint16_t track_count; 206 | uint8_t file_type; 207 | uint8_t time_type; 208 | uint16_t ticks_per_beat; 209 | uint8_t SMPTE_frames; 210 | uint8_t ticks_per_frame; 211 | uint8_t valid; 212 | blastmidi_event** tracks; 213 | blastmidi_event** track_ends; 214 | size_t cursor; 215 | uint8_t running_status; 216 | uint8_t sysex_continuation; 217 | } blastmidi; 218 | 219 | /* 220 | * uint8_t blastmidi_initialize(blastmidi* instance, blastmidi_custom_malloc* user_malloc, blastmidi_custom_free* user_free); 221 | * This function should be invoked on each new instance of the blastmidi structure that you instantiate. 222 | * Using a blastmidi structure without invoking this function first will result in undefined behavior. 223 | * The first parameter is a pointer to the structure instance that should be initialized. 224 | * The second and third parameters are pointers to memory allocation functions (normally malloc and free). 225 | * Both of these may be NULL, in which case the system defined malloc and free functions will be used. 226 | * If one of these function pointers is not NULL, the other one must also be valid. 227 | * The return value is one of the defined BlastMidi error codes. 228 | */ 229 | uint8_t blastmidi_initialize ( blastmidi* instance, blastmidi_custom_malloc* user_malloc, blastmidi_custom_free* user_free ); 230 | 231 | /* 232 | * void blastmidi_set_data_callback(blastmidi* instance, blastmidi_data_callback* callback, void* user_data); 233 | * This function associates a data I/O callback with a given blastmidi instance. 234 | * The first parameter is a pointer to the blastmidi instance. 235 | * The second parameter is a pointer to a function of type blastmidi_data_callback. If this is NULL, no I/O can be performed. 236 | * For more information on this callback function, see the comment above. 237 | * The third parameter is a user controlled void* pointer which is passed along to the callback. 238 | */ 239 | void blastmidi_set_data_callback ( blastmidi* instance, blastmidi_data_callback* callback, void* user_data ); 240 | 241 | /* 242 | * uint8_t blastmidi_read(blastmidi* instance) 243 | * Invoke this function to read a new Midi file stream. 244 | * The return value is one of the defined BlastMidi error codes. 245 | */ 246 | uint8_t blastmidi_read ( blastmidi* instance ); 247 | 248 | /* 249 | * void blastmidi_whipe_track(blastmidi* instance, unsigned int track); 250 | * Removes all events from the given track. The track number starts at 0. 251 | * If the track number does not refer to an existing track or if the track is already empty, this function is a no-op. 252 | */ 253 | void blastmidi_whipe_track ( blastmidi* instance, unsigned int track ); 254 | 255 | /* 256 | * void blastmidi_free(blastmidi* instance); 257 | * Frees all resources associated with the given instance. 258 | */ 259 | void blastmidi_free ( blastmidi* instance ); 260 | 261 | /* 262 | * uint8_t blastmidi_event_create_channel_event(blastmidi* instance, uint8_t channel, uint8_t subtype, uint8_t param_1, uint8_t param_2, blastmidi_event** event); 263 | * Creates a Midi channel event. Depending on the event, param_1 and param_2 may or may not be used. 264 | * After a successful call to this function, event points to an initialized blastmidi_event structure representing the new event. 265 | */ 266 | uint8_t blastmidi_event_create_channel_event ( blastmidi* instance, uint8_t channel, uint8_t subtype, uint8_t param_1, uint8_t param_2, blastmidi_event** event ); 267 | 268 | /* 269 | * uint8_t blastmidi_event_create_meta_sequence_number_event(blastmidi* instance, uint16_t sequence_number, blastmidi_event** event); 270 | * Creates a meta sequence number event. 271 | * After a successful call to this function, event points to an initialized blastmidi_event structure representing the new event. 272 | */ 273 | uint8_t blastmidi_event_create_meta_sequence_number_event ( blastmidi* instance, uint16_t sequence_number, blastmidi_event** event ); 274 | 275 | /* 276 | * uint8_t blastmidi_event_create_meta_tempo_event(blastmidi* instance, uint32_t tempo, blastmidi_event** event); 277 | * Creates a meta tempo event. The tempo is specified as the number of microseconds per quarter note. 278 | * After a successful call to this function, event points to an initialized blastmidi_event structure representing the new event. 279 | */ 280 | uint8_t blastmidi_event_create_meta_tempo_event ( blastmidi* instance, uint32_t tempo, blastmidi_event** event ); 281 | 282 | /* 283 | * uint8_t blastmidi_event_create_meta_data_event(blastmidi* instance, uint8_t subtype, uint8_t* data, unsigned int data_size, blastmidi_event** event); 284 | * Creates any one of the data meta events. The exact event type is specified by subtype and may be one of the following: 285 | * BLASTMIDI_META_TEXT, BLASTMIDI_META_COPYRIGHT_NOTICE, BLASTMIDI_META_SEQUENCE_OR_TRACK_NAME, 286 | * BLASTMIDI_META_INSTRUMENT_NAME, BLASTMIDI_META_LYRICS, BLASTMIDI_META_MARKER, BLASTMIDI_META_CUE_POINT 287 | * or BLASTMIDI_META_SEQUENCER_SPECIFIC. 288 | * The contents of data is copied into internal storage, so the memory does not need to be valid once this function returns. 289 | * After a successful call to this function, event points to an initialized blastmidi_event structure representing the new event. 290 | */ 291 | uint8_t blastmidi_event_create_meta_data_event ( blastmidi* instance, uint8_t subtype, uint8_t* data, unsigned int data_size, blastmidi_event** event ); 292 | 293 | /* 294 | * uint8_t blastmidi_event_create_meta_midi_channel_prefix_event(blastmidi *instance, uint8_t channel, blastmidi_event **event); 295 | * Creates a Midi channel prefix event. 296 | * A Midi channel prefix event is used to tell the reader that the following meta events belong to a given channel. 297 | * The effect of a Midi channel prefix event goes away either when another channel prefix event or any non-meta event occurs. 298 | * After a successful call to this function, event points to an initialized blastmidi_event structure representing the new event. 299 | */ 300 | uint8_t blastmidi_event_create_meta_midi_channel_prefix_event ( blastmidi* instance, uint8_t channel, blastmidi_event** event ); 301 | 302 | /* 303 | * uint8_t blastmidi_event_create_meta_time_signature_event(blastmidi *instance, uint8_t numerator, uint8_t denominator, uint8_t metronome, uint8_t thirtyseconds_per_24_signals, blastmidi_event **event); 304 | * Creates a meta time signature event. 305 | * numerator is specified as a literal value, such as 3 or 4. 306 | * denominator is the value to which the power of two must be raised to equal the number of subdivisions per whole note. 307 | * 0 means a whole note, for example, 1 means a half note, 2 means a quarter note and 3 means an eighth note etc. 308 | * metronome specifies how often the metronome should click, in clock ticks per quarter note. 309 | * There are 24 clock ticks per quarter note, so if you want the metronome to click every half note you would pass 48. 310 | * thirtyseconds_per_24_signals specifies the number of thirtyseconds per quarter note, in clock signals per quarter note. 311 | * As mentioned previously, there are 24 clock signals per quarter note. Therefore, thirtyseconds_per_24_signals should 312 | * nearly always be 8 since there are 8 thirtysecond notes per quarter. Only use a value other than 8 if you have a good reason. 313 | * After a successful call to this function, event points to an initialized blastmidi_event structure representing the new event. 314 | */ 315 | uint8_t blastmidi_event_create_meta_time_signature_event ( blastmidi* instance, uint8_t numerator, uint8_t denominator, uint8_t metronome, uint8_t thirtyseconds_per_24_signals, blastmidi_event** event ); 316 | 317 | /* 318 | * uint8_t blastmidi_event_create_meta_key_signature_event(blastmidi* instance, int8_t key, uint8_t scale, blastmidi_event** event); 319 | * Creates a meta key signature event. 320 | * key specifies the key in terms of the number of flats or sharps that exist in the key. 321 | * A negative value indicates the number of flats, and a positive value indicates the number of sharps. 0 means C. 322 | * scale is set to 0 for major and 1 for minor. 323 | * After a successful call to this function, event points to an initialized blastmidi_event structure representing the new event. 324 | */ 325 | uint8_t blastmidi_event_create_meta_key_signature_event ( blastmidi* instance, int8_t key, uint8_t scale, blastmidi_event** event ); 326 | 327 | /* 328 | * Todo: Add a constructor function for the SMPTE offset meta event. 329 | */ 330 | 331 | /* 332 | * uint8_t blastmidi_event_create_sysex_event(blastmidi* instance, uint8_t* data, unsigned int data_size, uint8_t end_of_sysex, blastmidi_event** event); 333 | * Creates a system exclusive event. 334 | * end_of_sysex should be nonzero if this is the last, or indeed the only, event associated with this data chunk. 335 | * If you wish to split up a large chunk of data into many events, specify 0 for end_of_sysex for all events except the last one. 336 | * The contents of data is copied into internal storage, so the memory does not need to be valid once this function returns. 337 | * After a successful call to this function, event points to an initialized blastmidi_event structure representing the new event. 338 | */ 339 | uint8_t blastmidi_event_create_sysex_event ( blastmidi* instance, uint8_t* data, unsigned int data_size, uint8_t end_of_sysex, blastmidi_event** event ); 340 | 341 | /* 342 | * uint8_t blastmidi_add_event(blastmidi* instance, uint16_t track_id, blastmidi_event* event, uint32_t delta_time, blastmidi_event* add_after); 343 | * This function associates the given Midi event with a particular track in a blastmidi instance. 344 | * Note that the blastmidi instance takes ownership of the event after this point, so the event should not be freed manually. 345 | * track_id starts at 0 and specifies the track to which this event should be added. 346 | * add_after specifies the event after which this new one should be inserted. 347 | * The new event is added immediately after add_after, with the appropriate delta time in between (see below). 348 | * If add_after is NULL, the event will be added to the beginning of the track. 349 | * delta_time is the number of ticks that must elapse between add_after and the new event. 350 | * If add_after is NULL, delta_time is the amount of time that must pass from the beginning of the track until the new event occurs. 351 | */ 352 | uint8_t blastmidi_add_event ( blastmidi* instance, uint16_t track_id, blastmidi_event* event, uint32_t delta_time, blastmidi_event* add_after ); 353 | 354 | /* 355 | * uint8_t blastmidi_add_event_to_beginning_of_track(blastmidi* instance, uint16_t track_id, blastmidi_event* event, uint32_t delta_time); 356 | * This function associates the given Midi event with a particular track in a blastmidi instance. 357 | * Note that the blastmidi instance takes ownership of the event after this point, so the event should not be freed manually. 358 | * track_id starts at 0 and specifies the track to which this event should be added. 359 | * The new event is inserted at the very beginning of the track, with the appropriate delta time in between (see below). 360 | * delta_time is the amount of time that must pass from the beginning of the track until this new event occurs. 361 | */ 362 | uint8_t blastmidi_add_event_to_beginning_of_track ( blastmidi* instance, uint16_t track_id, blastmidi_event* event, uint32_t delta_time ); 363 | 364 | /* 365 | * uint8_t blastmidi_add_event_to_end_of_track(blastmidi* instance, uint16_t track_id, blastmidi_event* event, uint32_t delta_time); 366 | * This function associates the given Midi event with a particular track in a blastmidi instance. 367 | * Note that the blastmidi instance takes ownership of the event after this point, so the event should not be freed manually. 368 | * track_id starts at 0 and specifies the track to which this event should be added. 369 | * The new event is inserted at the very end of the track, with the appropriate delta time (see below). 370 | * delta_time is the amount of time that must pass from the current end of the track until this new event occurs. 371 | * If the track is empty, the new event is added as the first event on the track with the appropriate delta time. 372 | */ 373 | uint8_t blastmidi_add_event_to_end_of_track ( blastmidi* instance, uint16_t track_id, blastmidi_event* event, uint32_t delta_time ); 374 | 375 | /* 376 | * uint8_t blastmidi_get_first_event_on_track(blastmidi* instance, uint16_t track_id, blastmidi_event** event); 377 | * This function gets the first event from the given track. 378 | * track_id starts at 0 and specifies the track from which the event should be retrieved. 379 | * Note that the event is not copied. You should therefore not modify the event, as it is still owned by the blastmidi instance. 380 | */ 381 | uint8_t blastmidi_get_first_event_on_track ( blastmidi* instance, uint16_t track_id, blastmidi_event** event ); 382 | 383 | /* 384 | * uint8_t blastmidi_get_last_event_on_track(blastmidi* instance, uint16_t track_id, blastmidi_event** event); 385 | * This function gets the last event from the given track. 386 | * track_id starts at 0 and specifies the track from which the event should be retrieved. 387 | * Note that the event is not copied. You should therefore not modify the event, as it is still owned by the blastmidi instance. 388 | */ 389 | uint8_t blastmidi_get_last_event_on_track ( blastmidi* instance, uint16_t track_id, blastmidi_event** event ); 390 | 391 | /* 392 | * uint8_t blastmidi_get_next_event_on_track(blastmidi* instance, blastmidi_event** event); 393 | * This function gets the next event from the given track. 394 | * event is expected to initially contain a pointer to an event on the given track, based on which the next one will be retrieved. 395 | * The event pointer is updated so that it points to the next event on the track after the call to this function completes. 396 | * If there is no event present after the current one on the track, event will be set to point to NULL. 397 | * Note that the retrieved event is not copied. You should therefore not modify it , as it is still owned by the blastmidi instance. 398 | */ 399 | uint8_t blastmidi_get_next_event_on_track ( blastmidi* instance, blastmidi_event** event ); 400 | 401 | /* 402 | * uint8_t blastmidi_get_previous_event_on_track(blastmidi* instance, blastmidi_event** event); 403 | * This function gets the previous event from the given track. 404 | * event is expected to initially contain a pointer to an event on the given track, based on which the previous one will be retrieved. 405 | * The event pointer is updated so that it points to the previous event on the track after the call to this function completes. 406 | * If there is no event present before the current one on the track, event will be set to point to NULL. 407 | * Note that the retrieved event is not copied. You should therefore not modify it , as it is still owned by the blastmidi instance. 408 | */ 409 | uint8_t blastmidi_get_previous_event_on_track ( blastmidi* instance, blastmidi_event** event ); 410 | 411 | /* 412 | * uint8_t blastmidi_remove_event_from_track(blastmidi* instance, uint16_t track_id, blastmidi_event* event); 413 | * This function removes an event from the track to which it currently belongs. 414 | * track_id starts at 0 and specifies the track from which this event should be removed. 415 | * The event must have been added to the given track in the blastmidi instance prior to this call. 416 | * The event will be removed from the given track, and all its associated resources will be automatically freed. 417 | */ 418 | uint8_t blastmidi_remove_event_from_track ( blastmidi* instance, uint16_t track_id, blastmidi_event* event ); 419 | 420 | /* 421 | * void blastmidi_event_free(blastmidi* instance, blastmidi_event* event); 422 | * Frees all resources associated with the given event. 423 | * Note: This function does not take the linked list into consideration. Pointer bookkeeping has to have been done before 424 | * this function is invoked. 425 | * Note also that after the event has been associated with a track in a blastmidi instance, you should not free it manually. 426 | * The blastmidi instance takes ownership of the event as soon as it is associated. 427 | * To remove an event that has been added to a track, call blastmidi_remove_event_from_track instead. 428 | */ 429 | void blastmidi_event_free ( blastmidi* instance, blastmidi_event* event ); 430 | 431 | #endif /* BLASTMIDI_H */ 432 | -------------------------------------------------------------------------------- /readme.txt: -------------------------------------------------------------------------------- 1 | BlastMidi 2 | 3 | A library of routines for working with Midi files. 4 | 5 | Copyright Blastbay Studios (Philip Bennefall) 2014 - 2015. 6 | 7 | 8 | BlastMidi is a C library that makes it easy to work with Midi files. Currently the library only supports parsing, but support for writing Midi files is planned as well. 9 | 10 | The project is in a very early stage of development, and therefore the documentation is sparse. Currently the only source of usage information for the library is found in the library header located in the include directory. 11 | 12 | To build the library, simply add blastmidi.c to your project and include blastmidi.h. There is only one other file that needs to be present; blastmidi_utility.h which is found in the src directory along with blastmidi.c. The library is written in Ansi C, and should build under any reasonably standards compliant C compiler. The library requires stdint.h, but it is my intent that it shouldn't use any other C99 features. 13 | 14 | If you like this library and would like to see it developed further, feel free to contact me. My email address is philip@blastbay.com. I can only offer very limited support at this time, however, as this is merely a hobby project. 15 | 16 | Thank you for checking out BlastMidi! 17 | 18 | Philip Bennefall -------------------------------------------------------------------------------- /src/blastmidi.c: -------------------------------------------------------------------------------- 1 | //#define BLASTMIDI_DEBUG 2 | /* 3 | * BlastMidi 4 | * 5 | * A library of routines for working with Midi files. 6 | * 7 | * Copyright Blastbay Studios (Philip Bennefall) 2014 - 2015. 8 | * Distributed under the Boost Software License, Version 1.0. 9 | * (See accompanying file LICENSE_1_0.txt or copy at 10 | * http://www.boost.org/LICENSE_1_0.txt) 11 | * 12 | * blastmidi.c 13 | * The main library implementation file. 14 | * 15 | * For the API reference, see blastmidi.h. 16 | */ 17 | 18 | #include /* For malloc and free */ 19 | #include 20 | #include /* For memcpy, memset and strcmp */ 21 | #include 22 | #include "blastmidi_utility.h" /* Utility functions for bit and endian manipulation */ 23 | #include "blastmidi.h" 24 | #include 25 | 26 | void reset ( blastmidi* instance ) 27 | { 28 | if ( instance->tracks ) 29 | { 30 | size_t i; 31 | for ( i = 0; i < instance->track_count; ++i ) 32 | { 33 | blastmidi_whipe_track ( instance, i ); 34 | } 35 | instance->free_function ( instance->tracks ); 36 | instance->tracks = NULL; 37 | } 38 | if ( instance->track_ends ) 39 | { 40 | instance->free_function ( instance->track_ends ); 41 | instance->track_ends = NULL; 42 | } 43 | instance->track_count = 0; 44 | instance->file_type = 0; 45 | instance->time_type = 0; 46 | instance->ticks_per_beat = 0; 47 | instance->SMPTE_frames = 0; 48 | instance->ticks_per_frame = 0; 49 | instance->valid = 0; 50 | instance->cursor = 0; 51 | instance->running_status = 0; 52 | instance->sysex_continuation = 0; 53 | } 54 | 55 | uint8_t blastmidi_initialize ( blastmidi* instance, blastmidi_custom_malloc* user_malloc, blastmidi_custom_free* user_free ) 56 | { 57 | 58 | /* 59 | * Zero out the entire structure. 60 | */ 61 | memset ( ( void* ) instance, 0, sizeof ( blastmidi ) ); 62 | 63 | /* 64 | * Check what the host platform is using (big or little endian), so that we can swap bytes later as needed. 65 | */ 66 | if ( is_little_endian() ) 67 | { 68 | instance->endian_flag = 1; 69 | } 70 | else 71 | { 72 | /* 73 | * This is not little endian, so we assume big endian in this scenario. 74 | */ 75 | instance->endian_flag = 2; 76 | } 77 | 78 | /* 79 | * Did we get bad input for our memory function pointers? 80 | */ 81 | if ( ( user_malloc || user_free ) && ( user_malloc == NULL || user_free == NULL ) ) 82 | { 83 | return BLASTMIDI_INVALIDPARAM; 84 | } 85 | 86 | if ( user_malloc == NULL && user_free == NULL ) 87 | { 88 | instance->malloc_function = malloc; 89 | instance->free_function = free; 90 | } 91 | else 92 | { 93 | instance->malloc_function = user_malloc; 94 | instance->free_function = user_free; 95 | } 96 | return BLASTMIDI_OK; 97 | } 98 | 99 | void blastmidi_set_data_callback ( blastmidi* instance, blastmidi_data_callback* callback, void* user_data ) 100 | { 101 | instance->data_callback = callback; 102 | instance->data_callback_data = user_data; 103 | } 104 | 105 | /* 106 | * The following I/O functions return an error code. 107 | */ 108 | uint8_t read_bytes ( blastmidi* instance, uint8_t* buffer, size_t size ) 109 | { 110 | if ( instance->data_callback ( BLASTMIDI_CALLBACK_READ, size, buffer, instance->data_callback_data ) ) 111 | { 112 | instance->cursor += size; 113 | return BLASTMIDI_OK; 114 | } 115 | return BLASTMIDI_UNEXPECTEDEND; 116 | } 117 | 118 | uint8_t skip_ahead ( blastmidi* instance, size_t size ) 119 | { 120 | if ( instance->data_callback ( BLASTMIDI_CALLBACK_SEEK, instance->cursor + size, NULL, instance->data_callback_data ) ) 121 | { 122 | instance->cursor += size; 123 | return BLASTMIDI_OK; 124 | } 125 | return BLASTMIDI_UNEXPECTEDEND; 126 | } 127 | 128 | uint8_t skip_backwards ( blastmidi* instance, size_t size ) 129 | { 130 | assert ( instance->cursor >= size ); 131 | if ( instance->data_callback ( BLASTMIDI_CALLBACK_SEEK, instance->cursor - size, NULL, instance->data_callback_data ) ) 132 | { 133 | instance->cursor -= size; 134 | return BLASTMIDI_OK; 135 | } 136 | return BLASTMIDI_UNEXPECTEDEND; 137 | } 138 | 139 | uint8_t write_bytes ( blastmidi* instance, uint8_t* buffer, size_t size ) 140 | { 141 | if ( instance->data_callback ( BLASTMIDI_CALLBACK_WRITE, size, buffer, instance->data_callback_data ) ) 142 | { 143 | return BLASTMIDI_OK; 144 | } 145 | return BLASTMIDI_UNEXPECTEDEND; 146 | } 147 | 148 | uint8_t read_byte ( blastmidi* instance, uint8_t* buffer ) 149 | { 150 | return read_bytes ( instance, buffer, 1 ); 151 | } 152 | 153 | /* 154 | * The following integer I/O functions convert to and from big endian as required. 155 | */ 156 | uint8_t read_16_bit ( blastmidi* instance, uint16_t* buffer ) 157 | { 158 | if ( read_bytes ( instance, ( uint8_t* ) buffer, 2 ) == BLASTMIDI_OK ) 159 | { 160 | *buffer = convert_endian_16 ( *buffer, instance->endian_flag ); 161 | return BLASTMIDI_OK; 162 | } 163 | return BLASTMIDI_UNEXPECTEDEND; 164 | } 165 | 166 | uint8_t read_32_bit ( blastmidi* instance, uint32_t* buffer ) 167 | { 168 | if ( read_bytes ( instance, ( uint8_t* ) buffer, 4 ) == BLASTMIDI_OK ) 169 | { 170 | *buffer = convert_endian_32 ( *buffer, instance->endian_flag ); 171 | return BLASTMIDI_OK; 172 | } 173 | return BLASTMIDI_UNEXPECTEDEND; 174 | } 175 | 176 | uint8_t read_24_bit ( blastmidi* instance, uint32_t* buffer ) 177 | { 178 | if ( read_bytes ( instance, ( uint8_t* ) buffer, 3 ) == BLASTMIDI_OK ) 179 | { 180 | *buffer = convert_endian_32 ( *buffer, instance->endian_flag ); 181 | *buffer = extract_bits_32 ( *buffer, 1, 24 ); 182 | return BLASTMIDI_OK; 183 | } 184 | return BLASTMIDI_UNEXPECTEDEND; 185 | } 186 | 187 | uint8_t read_variable_number ( blastmidi* instance, uint32_t* buffer ) 188 | { 189 | uint8_t i; 190 | 191 | *buffer = 0; 192 | 193 | for ( i = 0; i < 4; i++ ) 194 | { 195 | 196 | uint8_t keep_going = 0; 197 | uint8_t current; 198 | 199 | uint8_t result = read_byte ( instance, ¤t ); 200 | if ( result != BLASTMIDI_OK ) 201 | { 202 | return result; 203 | } 204 | keep_going = extract_bits_8 ( current, 1, 1 ); 205 | if ( keep_going == 1 && i == 3 ) 206 | { 207 | return BLASTMIDI_INVALIDCHUNK; 208 | } 209 | *buffer = ( ( *buffer ) << 7 ) | ( current & 0x7f ); 210 | if ( !keep_going ) 211 | { 212 | break; 213 | } 214 | } 215 | return BLASTMIDI_OK; 216 | } 217 | 218 | uint8_t write_16_bit ( blastmidi* instance, uint16_t value ) 219 | { 220 | uint16_t buffer = convert_endian_16 ( value, instance->endian_flag ); 221 | if ( write_bytes ( instance, ( uint8_t* ) &buffer, 2 ) == BLASTMIDI_OK ) 222 | { 223 | return BLASTMIDI_OK; 224 | } 225 | return BLASTMIDI_WRITINGFAILED; 226 | } 227 | 228 | uint8_t write_32_bit ( blastmidi* instance, uint32_t value ) 229 | { 230 | uint32_t buffer = convert_endian_32 ( value, instance->endian_flag ); 231 | if ( write_bytes ( instance, ( uint8_t* ) &buffer, 4 ) == BLASTMIDI_OK ) 232 | { 233 | return BLASTMIDI_OK; 234 | } 235 | return BLASTMIDI_WRITINGFAILED; 236 | } 237 | 238 | uint8_t allocate_tracks ( blastmidi* instance ) 239 | { 240 | 241 | assert ( instance->track_count > 0 ); 242 | assert ( instance->tracks == NULL ); 243 | assert ( instance->track_ends == NULL ); 244 | 245 | instance->tracks = ( blastmidi_event** ) instance->malloc_function ( ( sizeof ( blastmidi_event* ) * instance->track_count ) ); 246 | if ( instance->tracks == NULL ) 247 | { 248 | reset ( instance ); 249 | return BLASTMIDI_OUTOFMEMORY; 250 | } 251 | memset ( ( void* ) instance->tracks, 0, sizeof ( blastmidi_event* ) *instance->track_count ); 252 | instance->track_ends = ( blastmidi_event** ) instance->malloc_function ( ( sizeof ( blastmidi_event* ) * instance->track_count ) ); 253 | if ( instance->track_ends == NULL ) 254 | { 255 | reset ( instance ); 256 | return BLASTMIDI_OUTOFMEMORY; 257 | } 258 | memset ( ( void* ) instance->track_ends, 0, sizeof ( blastmidi_event* ) *instance->track_count ); 259 | return BLASTMIDI_OK; 260 | } 261 | 262 | uint8_t allocate_event ( blastmidi* instance, uint8_t type, uint8_t subtype, uint8_t* data, unsigned int data_size, blastmidi_event** event ) 263 | { 264 | 265 | /* 266 | * This function allocates the memory needed for a Midi event. 267 | * If data is not NULL, its content will be copied into the event's internal storage. 268 | * If data is NULL, the memory to hold the event data is allocated but left uninitialized. 269 | */ 270 | 271 | blastmidi_event* output = NULL; 272 | *event = NULL; 273 | 274 | output = ( blastmidi_event* ) instance->malloc_function ( sizeof ( blastmidi_event ) ); 275 | if ( output == NULL ) 276 | { 277 | return BLASTMIDI_OUTOFMEMORY; 278 | } 279 | memset ( ( void* ) output, 0, sizeof ( blastmidi_event ) ); 280 | output->track = -1; 281 | output->time = 0; 282 | output->type = type; 283 | output->subtype = subtype; 284 | output->channel = -1; 285 | output->data = NULL; 286 | output->data_size = data_size; 287 | output->end_of_sysex = 0; 288 | output->previous = NULL; 289 | output->next = NULL; 290 | if ( data_size > 0 && data_size <= sizeof ( output->small_pool ) ) 291 | { 292 | output->data = output->small_pool; 293 | } 294 | else 295 | { 296 | uint8_t* data_block = ( uint8_t* ) instance->malloc_function ( data_size ); 297 | if ( data_block == NULL ) 298 | { 299 | instance->free_function ( output ); 300 | return BLASTMIDI_OUTOFMEMORY; 301 | } 302 | output->data = data_block; 303 | } 304 | 305 | if ( data ) 306 | { 307 | memcpy ( output->data, data, data_size ); 308 | } 309 | 310 | *event = output; 311 | return BLASTMIDI_OK; 312 | } 313 | 314 | uint8_t blastmidi_event_create_channel_event ( blastmidi* instance, uint8_t channel, uint8_t subtype, uint8_t param_1, uint8_t param_2, blastmidi_event** event ) 315 | { 316 | blastmidi_event* output = NULL; 317 | uint8_t result = 0; 318 | uint8_t data[2]; 319 | unsigned int data_size = 0; 320 | uint8_t* temp_ptr8 = NULL; 321 | uint16_t temp16 = 0; 322 | switch ( subtype ) 323 | { 324 | case BLASTMIDI_CHANNEL_NOTE_OFF: 325 | case BLASTMIDI_CHANNEL_NOTE_ON: 326 | case BLASTMIDI_CHANNEL_NOTE_AFTERTOUCH: 327 | case BLASTMIDI_CHANNEL_CONTROLLER: 328 | data_size = 2; 329 | data[0] = param_1; 330 | data[1] = param_2; 331 | break; 332 | case BLASTMIDI_CHANNEL_PITCH_BEND: 333 | /* 334 | * Extract the last 7 bits of both data bytes and combine them into an unsigned 16 bit integer. 335 | * The resulting integer will be in the native host endian order. 336 | */ 337 | data_size = 2; 338 | param_1 = extract_bits_8 ( param_1, 2, 8 ); 339 | param_2 = extract_bits_8 ( param_2, 2, 8 ); 340 | temp16 = param_1; 341 | temp16 = temp16 << 8; 342 | temp16 |= ( param_2 << 1 ); 343 | temp16 = temp16 >> 1; 344 | temp_ptr8 = ( uint8_t* ) &temp16; 345 | data[0] = temp_ptr8[0]; 346 | data[1] = temp_ptr8[1]; 347 | break; 348 | case BLASTMIDI_CHANNEL_PROGRAM_CHANGE: 349 | case BLASTMIDI_CHANNEL_CHANNEL_AFTERTOUCH: 350 | data_size = 1; 351 | data[0] = param_1; 352 | break; 353 | default: 354 | return BLASTMIDI_INVALIDPARAM; 355 | }; 356 | 357 | result = allocate_event ( instance, BLASTMIDI_CHANNEL_EVENT, subtype, data, data_size, &output ); 358 | if ( result != BLASTMIDI_OK ) 359 | { 360 | return result; 361 | } 362 | output->channel = channel; 363 | *event = output; 364 | return BLASTMIDI_OK; 365 | } 366 | 367 | uint8_t blastmidi_event_create_meta_sequence_number_event ( blastmidi* instance, uint16_t sequence_number, blastmidi_event** event ) 368 | { 369 | uint8_t result = 0; 370 | blastmidi_event* output = NULL; 371 | 372 | assert ( sizeof ( sequence_number ) == 2 ); 373 | 374 | result = allocate_event ( instance, BLASTMIDI_META_EVENT, BLASTMIDI_META_SEQUENCE_NUMBER, ( uint8_t* ) &sequence_number, sizeof ( sequence_number ), &output ); 375 | if ( result != BLASTMIDI_OK ) 376 | { 377 | return result; 378 | } 379 | *event = output; 380 | return BLASTMIDI_OK; 381 | } 382 | 383 | uint8_t blastmidi_event_create_meta_tempo_event ( blastmidi* instance, uint32_t tempo, blastmidi_event** event ) 384 | { 385 | blastmidi_event* output = NULL; 386 | uint8_t result = 0; 387 | 388 | assert ( sizeof ( tempo ) == 4 ); 389 | 390 | result = allocate_event ( instance, BLASTMIDI_META_EVENT, BLASTMIDI_META_SET_TEMPO, ( uint8_t* ) &tempo, sizeof ( tempo ), &output ); 391 | if ( result != BLASTMIDI_OK ) 392 | { 393 | return result; 394 | } 395 | *event = output; 396 | return BLASTMIDI_OK; 397 | } 398 | 399 | uint8_t blastmidi_event_create_meta_data_event ( blastmidi* instance, uint8_t subtype, uint8_t* data, unsigned int data_size, blastmidi_event** event ) 400 | { 401 | blastmidi_event* output = NULL; 402 | uint8_t result = 0; 403 | switch ( subtype ) 404 | { 405 | case BLASTMIDI_META_TEXT: 406 | case BLASTMIDI_META_COPYRIGHT_NOTICE: 407 | case BLASTMIDI_META_SEQUENCE_OR_TRACK_NAME: 408 | case BLASTMIDI_META_INSTRUMENT_NAME: 409 | case BLASTMIDI_META_LYRICS: 410 | case BLASTMIDI_META_MARKER: 411 | case BLASTMIDI_META_CUE_POINT: 412 | case BLASTMIDI_META_SEQUENCER_SPECIFIC: 413 | break; 414 | default: 415 | return BLASTMIDI_INVALIDPARAM; 416 | }; 417 | 418 | result = allocate_event ( instance, BLASTMIDI_META_EVENT, subtype, data, data_size, &output ); 419 | if ( result != BLASTMIDI_OK ) 420 | { 421 | return result; 422 | } 423 | *event = output; 424 | return BLASTMIDI_OK; 425 | } 426 | 427 | uint8_t blastmidi_event_create_meta_midi_channel_prefix_event ( blastmidi* instance, uint8_t channel, blastmidi_event** event ) 428 | { 429 | blastmidi_event* output = NULL; 430 | uint8_t result = 0; 431 | 432 | assert ( sizeof ( channel ) == 1 ); 433 | 434 | result = allocate_event ( instance, BLASTMIDI_META_EVENT, BLASTMIDI_META_MIDI_CHANNEL_PREFIX, ( uint8_t* ) &channel, 1, &output ); 435 | if ( result != BLASTMIDI_OK ) 436 | { 437 | return result; 438 | } 439 | *event = output; 440 | return BLASTMIDI_OK; 441 | } 442 | 443 | uint8_t blastmidi_event_create_meta_time_signature_event ( blastmidi* instance, uint8_t numerator, uint8_t denominator, uint8_t metronome, uint8_t thirtyseconds_per_24_signals, blastmidi_event** event ) 444 | { 445 | uint8_t result = 0; 446 | blastmidi_event* output = NULL; 447 | uint8_t data[4]; 448 | 449 | assert ( sizeof ( numerator ) == 1 ); 450 | 451 | data[0] = numerator; 452 | data[1] = denominator; 453 | data[2] = metronome; 454 | data[3] = thirtyseconds_per_24_signals; 455 | 456 | result = allocate_event ( instance, BLASTMIDI_META_EVENT, BLASTMIDI_META_TIME_SIGNATURE, data, 4, &output ); 457 | if ( result != BLASTMIDI_OK ) 458 | { 459 | return result; 460 | } 461 | *event = output; 462 | return BLASTMIDI_OK; 463 | } 464 | 465 | uint8_t blastmidi_event_create_meta_key_signature_event ( blastmidi* instance, int8_t key, uint8_t scale, blastmidi_event** event ) 466 | { 467 | uint8_t result = 0; 468 | blastmidi_event* output = NULL; 469 | uint8_t data[2]; 470 | 471 | assert ( sizeof ( key ) == 1 ); 472 | 473 | data[0] = ( uint8_t ) key; 474 | data[1] = scale; 475 | 476 | result = allocate_event ( instance, BLASTMIDI_META_EVENT, BLASTMIDI_META_KEY_SIGNATURE, data, 2, &output ); 477 | if ( result != BLASTMIDI_OK ) 478 | { 479 | return result; 480 | } 481 | *event = output; 482 | return BLASTMIDI_OK; 483 | } 484 | 485 | uint8_t blastmidi_event_create_sysex_event ( blastmidi* instance, uint8_t* data, unsigned int data_size, uint8_t end_of_sysex, blastmidi_event** event ) 486 | { 487 | blastmidi_event* output = NULL; 488 | uint8_t result = allocate_event ( instance, BLASTMIDI_SYSEX_EVENT, 0, data, data_size, &output ); 489 | if ( result != BLASTMIDI_OK ) 490 | { 491 | return result; 492 | } 493 | output->end_of_sysex = end_of_sysex; 494 | *event = output; 495 | return BLASTMIDI_OK; 496 | } 497 | 498 | uint8_t read_meta_event ( blastmidi* instance, uint8_t* end_of_track, blastmidi_event** event_ptr ) 499 | { 500 | uint8_t type = 0; 501 | uint32_t event_size = 0; 502 | uint8_t result = read_byte ( instance, &type ); 503 | if ( result != BLASTMIDI_OK ) 504 | { 505 | return result; 506 | } 507 | result = read_variable_number ( instance, &event_size ); 508 | if ( result != BLASTMIDI_OK ) 509 | { 510 | return result; 511 | } 512 | switch ( type ) 513 | { 514 | case BLASTMIDI_META_SEQUENCE_NUMBER: 515 | { 516 | uint16_t sequence_number = 0; 517 | result = read_16_bit ( instance, &sequence_number ); 518 | if ( result != BLASTMIDI_OK ) 519 | { 520 | return result; 521 | } 522 | #ifdef BLASTMIDI_DEBUG 523 | printf ( "Sequence number: %u\n", ( uint32_t ) sequence_number ); 524 | #endif 525 | result = blastmidi_event_create_meta_sequence_number_event ( instance, sequence_number, event_ptr ); 526 | if ( result != BLASTMIDI_OK ) 527 | { 528 | return result; 529 | } 530 | break; 531 | } 532 | case BLASTMIDI_META_TEXT: 533 | case BLASTMIDI_META_COPYRIGHT_NOTICE: 534 | case BLASTMIDI_META_SEQUENCE_OR_TRACK_NAME: 535 | case BLASTMIDI_META_INSTRUMENT_NAME: 536 | case BLASTMIDI_META_LYRICS: 537 | case BLASTMIDI_META_MARKER: 538 | case BLASTMIDI_META_CUE_POINT: 539 | case BLASTMIDI_META_SEQUENCER_SPECIFIC: 540 | #ifdef BLASTMIDI_DEBUG 541 | printf ( "Data event.\n" ); 542 | #endif 543 | result = blastmidi_event_create_meta_data_event ( instance, type, NULL, event_size, event_ptr ); 544 | if ( result != BLASTMIDI_OK ) 545 | { 546 | return result; 547 | } 548 | result = read_bytes ( instance, event_ptr[0]->data, event_size ); 549 | if ( result != BLASTMIDI_OK ) 550 | { 551 | blastmidi_event_free ( instance, *event_ptr ); 552 | *event_ptr = NULL; 553 | return result; 554 | } 555 | break; 556 | case BLASTMIDI_META_MIDI_CHANNEL_PREFIX: 557 | { 558 | uint8_t channel = 0; 559 | result = read_byte ( instance, &channel ); 560 | if ( result != BLASTMIDI_OK ) 561 | { 562 | return result; 563 | } 564 | #ifdef BLASTMIDI_DEBUG 565 | printf ( "Channel prefix event.\nChannel: %u\n", ( uint32_t ) channel ); 566 | #endif 567 | result = blastmidi_event_create_meta_midi_channel_prefix_event ( instance, channel, event_ptr ); 568 | if ( result != BLASTMIDI_OK ) 569 | { 570 | return result; 571 | } 572 | break; 573 | } 574 | case BLASTMIDI_META_END_OF_TRACK: 575 | /* 576 | * Set the end_of_track variable that we were given, to 1. 577 | * This informs the caller that it is time to stop reading events on this particular track. 578 | */ 579 | #ifdef BLASTMIDI_DEBUG 580 | printf ( "End of track.\n" ); 581 | #endif 582 | *end_of_track = 1; 583 | break; 584 | case BLASTMIDI_META_SET_TEMPO: 585 | { 586 | uint32_t tempo = 0; 587 | result = read_24_bit ( instance, &tempo ); 588 | if ( result != BLASTMIDI_OK ) 589 | { 590 | return result; 591 | } 592 | #ifdef BLASTMIDI_DEBUG 593 | printf ( "Tempo: %u\n", ( uint32_t ) tempo ); 594 | #endif 595 | result = blastmidi_event_create_meta_tempo_event ( instance, tempo, event_ptr ); 596 | if ( result != BLASTMIDI_OK ) 597 | { 598 | return result; 599 | } 600 | break; 601 | } 602 | case BLASTMIDI_META_SMPTE_OFFSET: 603 | /* 604 | * Todo: Implement support for this. Right now we just skip ahead. 605 | */ 606 | result = skip_ahead ( instance, 5 ); 607 | if ( result != BLASTMIDI_OK ) 608 | { 609 | return result; 610 | } 611 | #ifdef BLASTMIDI_DEBUG 612 | printf ( "SMPTE offset.\n" ); 613 | #endif 614 | break; 615 | case BLASTMIDI_META_TIME_SIGNATURE: 616 | { 617 | uint8_t numerator = 0; 618 | uint8_t denominator = 0; 619 | uint8_t metronome = 0; 620 | uint8_t thirtyseconds_per_24_signals = 0; 621 | result = read_byte ( instance, &numerator ); 622 | if ( result != BLASTMIDI_OK ) 623 | { 624 | return result; 625 | } 626 | result = read_byte ( instance, &denominator ); 627 | if ( result != BLASTMIDI_OK ) 628 | { 629 | return result; 630 | } 631 | result = read_byte ( instance, &metronome ); 632 | if ( result != BLASTMIDI_OK ) 633 | { 634 | return result; 635 | } 636 | result = read_byte ( instance, &thirtyseconds_per_24_signals ); 637 | if ( result != BLASTMIDI_OK ) 638 | { 639 | return result; 640 | } 641 | #ifdef BLASTMIDI_DEBUG 642 | printf ( "Time signature.\nNumerator: %u\nDenominator: %u\nMetronome: %u\nThirty seconds per 24 signal: %u\n", ( uint32_t ) numerator, ( uint32_t ) denominator, ( uint32_t ) metronome, ( uint32_t ) thirtyseconds_per_24_signals ); 643 | #endif 644 | result = blastmidi_event_create_meta_time_signature_event ( instance, numerator, denominator, metronome, thirtyseconds_per_24_signals, event_ptr ); 645 | if ( result != BLASTMIDI_OK ) 646 | { 647 | return result; 648 | } 649 | break; 650 | } 651 | case BLASTMIDI_META_KEY_SIGNATURE: 652 | { 653 | int8_t key = 0; 654 | uint8_t scale = 0; 655 | result = read_byte ( instance, ( uint8_t* ) &key ); 656 | if ( result != BLASTMIDI_OK ) 657 | { 658 | return result; 659 | } 660 | result = read_byte ( instance, &scale ); 661 | if ( result != BLASTMIDI_OK ) 662 | { 663 | return result; 664 | } 665 | #ifdef BLASTMIDI_DEBUG 666 | printf ( "Key signature.\nKey: %d\nScale: %u\n", ( int32_t ) key, ( uint32_t ) scale ); 667 | #endif 668 | result = blastmidi_event_create_meta_key_signature_event ( instance, key, scale, event_ptr ); 669 | if ( result != BLASTMIDI_OK ) 670 | { 671 | return result; 672 | } 673 | break; 674 | } 675 | default: 676 | #ifdef BLASTMIDI_DEBUG 677 | printf ( "Unknown meta event type.\nType number: %u\nSize: %u\n", ( uint32_t ) type, event_size ); 678 | #endif 679 | result = skip_ahead ( instance, event_size ); 680 | if ( result != BLASTMIDI_OK ) 681 | { 682 | return result; 683 | } 684 | }; 685 | return BLASTMIDI_OK; 686 | } 687 | 688 | uint8_t read_sysex_event ( blastmidi* instance, blastmidi_event** event_ptr ) 689 | { 690 | uint32_t event_size = 0; 691 | uint8_t final_byte = 0; 692 | uint8_t result = read_variable_number ( instance, &event_size ); 693 | if ( result != BLASTMIDI_OK ) 694 | { 695 | return result; 696 | } 697 | if ( event_size == 0 ) 698 | { 699 | /* 700 | * This should never happen, but we allow for it. 701 | */ 702 | return BLASTMIDI_OK; 703 | } 704 | 705 | result = blastmidi_event_create_sysex_event ( instance, NULL, event_size - 1, 1, event_ptr ); 706 | if ( result != BLASTMIDI_OK ) 707 | { 708 | return result; 709 | } 710 | 711 | if ( event_size > 1 ) 712 | { 713 | result = read_bytes ( instance, event_ptr[0]->data, event_size - 1 ); 714 | if ( result != BLASTMIDI_OK ) 715 | { 716 | blastmidi_event_free ( instance, *event_ptr ); 717 | *event_ptr = NULL; 718 | return result; 719 | } 720 | } 721 | 722 | /* 723 | * Read the last data byte in the message, in order to check what scenario this is (continuation or the end of the whole message). 724 | */ 725 | result = read_byte ( instance, &final_byte ); 726 | if ( result != BLASTMIDI_OK ) 727 | { 728 | blastmidi_event_free ( instance, *event_ptr ); 729 | *event_ptr = NULL; 730 | return result; 731 | } 732 | if ( final_byte == 0xF7 ) 733 | { 734 | /* 735 | * This is the end of the entire event. The event structure is set up for this by default. 736 | */ 737 | instance->sysex_continuation = 0; 738 | } 739 | else 740 | { 741 | /* 742 | * This is not the last part of the sysex continuation event, so we remember the fact that one is ongoing. 743 | * We also have to update the end_of_sysex member in our event structure, so that it indicates 0. 744 | */ 745 | instance->sysex_continuation = 1; 746 | event_ptr[0]->end_of_sysex = 0; 747 | } 748 | return BLASTMIDI_OK; 749 | } 750 | 751 | uint8_t read_authorization_sysex_event ( blastmidi* instance, blastmidi_event** event_ptr ) 752 | { 753 | uint32_t event_size = 0; 754 | uint8_t result = read_variable_number ( instance, &event_size ); 755 | if ( result != BLASTMIDI_OK ) 756 | { 757 | return result; 758 | } 759 | if ( event_size == 0 ) 760 | { 761 | /* 762 | * This should never happen, but we allow for it. 763 | */ 764 | return BLASTMIDI_OK; 765 | } 766 | 767 | /* 768 | * Todo: Figure out whether we need a flag in the event structure to indicate that this is a sysex authorization event. 769 | */ 770 | 771 | result = blastmidi_event_create_sysex_event ( instance, NULL, event_size, 1, event_ptr ); 772 | if ( result != BLASTMIDI_OK ) 773 | { 774 | return result; 775 | } 776 | 777 | result = read_bytes ( instance, event_ptr[0]->data, event_size ); 778 | if ( result != BLASTMIDI_OK ) 779 | { 780 | blastmidi_event_free ( instance, *event_ptr ); 781 | *event_ptr = NULL; 782 | return result; 783 | } 784 | 785 | return BLASTMIDI_OK; 786 | } 787 | 788 | uint8_t read_track_events ( blastmidi* instance, uint16_t track_id ) 789 | { 790 | 791 | /* 792 | * Read all the events in a loop, breaking out either when an error occurs or when the end of track meta event is encountered. 793 | */ 794 | 795 | while ( 1 ) 796 | { 797 | 798 | blastmidi_event* event = NULL; 799 | /* 800 | * This is the event that we are about to create. 801 | */ 802 | 803 | /* 804 | * Begin by reading the delta time. 805 | */ 806 | uint32_t delta_time = 0; 807 | uint8_t event_type = 0; 808 | 809 | uint8_t end_of_track = 0; 810 | /* 811 | * This variable is passed to read_meta_event, and gets set to 1 if the end of track meta event is encountered. 812 | */ 813 | 814 | uint8_t result = read_variable_number ( instance, &delta_time ); 815 | if ( result != BLASTMIDI_OK ) 816 | { 817 | return result; 818 | } 819 | #ifdef BLASTMIDI_DEBUG 820 | printf ( "Delta time: %u\n", ( uint32_t ) delta_time ); 821 | #endif 822 | 823 | /* 824 | * Read the event type specifier. 825 | */ 826 | result = read_byte ( instance, &event_type ); 827 | if ( result != BLASTMIDI_OK ) 828 | { 829 | return result; 830 | } 831 | 832 | switch ( event_type ) 833 | { 834 | case 0xFF: 835 | result = read_meta_event ( instance, &end_of_track, &event ); 836 | if ( result != BLASTMIDI_OK ) 837 | { 838 | return result; 839 | } 840 | break; 841 | case 0xF0: 842 | #ifdef BLASTMIDI_DEBUG 843 | printf ( "SysEx event.\n" ); 844 | #endif 845 | result = read_sysex_event ( instance, &event ); 846 | if ( result != BLASTMIDI_OK ) 847 | { 848 | return result; 849 | } 850 | break; 851 | case 0xF7: 852 | /* 853 | * This is either a part of a continuation sysex event, or a single authorization sysex event. 854 | * We determine this by checking the sysex_continuation flag in the blastmidi structure. 855 | */ 856 | if ( instance->sysex_continuation == 1 ) 857 | { 858 | #ifdef BLASTMIDI_DEBUG 859 | printf ( "Continued SysEx event.\n" ); 860 | #endif 861 | result = read_sysex_event ( instance, &event ); 862 | } 863 | else 864 | { 865 | #ifdef BLASTMIDI_DEBUG 866 | printf ( "Authorization SysEx event.\n" ); 867 | #endif 868 | result = read_authorization_sysex_event ( instance, &event ); 869 | } 870 | if ( result != BLASTMIDI_OK ) 871 | { 872 | return result; 873 | } 874 | break; 875 | default: 876 | { 877 | uint8_t midi_event_type = 0; 878 | uint8_t channel = 0; 879 | uint8_t new_status_bit = extract_bits_8 ( event_type, 1, 1 ); 880 | if ( new_status_bit == 0 ) 881 | { 882 | /* 883 | * This is a so called running status event, which means that the status byte is the same as for our last event. 884 | * Therefore, we reuse that status byte and treat this byte as the first data byte of the event. 885 | */ 886 | event_type = instance->running_status; 887 | skip_backwards ( instance, 1 ); 888 | } 889 | instance->running_status = event_type; 890 | midi_event_type = extract_bits_8 ( event_type, 1, 4 ); 891 | channel = extract_bits_8 ( event_type, 5, 8 ); 892 | #ifdef BLASTMIDI_DEBUG 893 | printf ( "Midi event type: %u\nChannel: %u\n", ( uint32_t ) midi_event_type, ( uint32_t ) channel ); 894 | #endif 895 | 896 | switch ( midi_event_type ) 897 | { 898 | case BLASTMIDI_CHANNEL_NOTE_OFF: 899 | case BLASTMIDI_CHANNEL_NOTE_ON: 900 | case BLASTMIDI_CHANNEL_NOTE_AFTERTOUCH: 901 | case BLASTMIDI_CHANNEL_CONTROLLER: 902 | case BLASTMIDI_CHANNEL_PITCH_BEND: 903 | { 904 | uint8_t first = 0; 905 | uint8_t second = 0; 906 | result = read_byte ( instance, &first ); 907 | if ( result != BLASTMIDI_OK ) 908 | { 909 | return result; 910 | } 911 | result = read_byte ( instance, &second ); 912 | if ( result != BLASTMIDI_OK ) 913 | { 914 | return result; 915 | } 916 | result = blastmidi_event_create_channel_event ( instance, channel, midi_event_type, first, second, &event ); 917 | if ( result != BLASTMIDI_OK ) 918 | { 919 | #ifdef BLASTMIDI_DEBUG 920 | printf ( "Event creation error with two arguments.\n" ); 921 | #endif 922 | return result; 923 | } 924 | break; 925 | } 926 | case BLASTMIDI_CHANNEL_PROGRAM_CHANGE: 927 | case BLASTMIDI_CHANNEL_CHANNEL_AFTERTOUCH: 928 | { 929 | uint8_t first = 0; 930 | result = read_byte ( instance, &first ); 931 | if ( result != BLASTMIDI_OK ) 932 | { 933 | return result; 934 | } 935 | result = blastmidi_event_create_channel_event ( instance, channel, midi_event_type, first, 0, &event ); 936 | if ( result != BLASTMIDI_OK ) 937 | { 938 | return result; 939 | } 940 | break; 941 | } 942 | default: 943 | #ifdef BLASTMIDI_DEBUG 944 | printf ( "This is an unknown Midi channel event.\n" ); 945 | #endif 946 | if ( event ) 947 | { 948 | blastmidi_event_free ( instance, event ); 949 | } 950 | return BLASTMIDI_INVALIDCHUNK; 951 | }; 952 | } 953 | }; 954 | 955 | /* 956 | * If event is not NULL, we add it to the end of the track. 957 | */ 958 | if ( event ) 959 | { 960 | result = blastmidi_add_event_to_end_of_track ( instance, track_id, event, delta_time ); 961 | if ( result != BLASTMIDI_OK ) 962 | { 963 | blastmidi_event_free ( instance, event ); 964 | return result; 965 | } 966 | } 967 | 968 | if ( end_of_track ) 969 | { 970 | 971 | /* 972 | * The end of track meta event was encountered, so we break out of the loop and return. 973 | */ 974 | break; 975 | } 976 | 977 | } 978 | 979 | return BLASTMIDI_OK; 980 | } 981 | 982 | uint8_t read_track ( blastmidi* instance, uint16_t track_id ) 983 | { 984 | 985 | /* 986 | * Begin by reading and verifying the header. 987 | * A track chunk should have a type of MTrk. We make a temporary storage of 5 bytes, and NULL terminate the string. 988 | */ 989 | uint8_t temp[5]; 990 | uint32_t chunk_size = 0; 991 | 992 | uint8_t result = read_bytes ( instance, temp, 4 ); 993 | if ( result != BLASTMIDI_OK ) 994 | { 995 | return result; 996 | } 997 | temp[4] = 0; 998 | if ( strcmp ( ( const char* ) temp, "MTrk" ) != 0 ) 999 | { 1000 | #ifdef BLASTMIDI_DEBUG 1001 | printf ( "Invalid chunk.\n" ); 1002 | #endif 1003 | return BLASTMIDI_INVALIDCHUNK; 1004 | } 1005 | 1006 | result = read_32_bit ( instance, &chunk_size ); 1007 | if ( result != BLASTMIDI_OK ) 1008 | { 1009 | return result; 1010 | } 1011 | 1012 | if ( chunk_size == 0 ) 1013 | { 1014 | return BLASTMIDI_INVALIDCHUNK; 1015 | } 1016 | 1017 | instance->running_status = 0; 1018 | instance->sysex_continuation = 0; 1019 | 1020 | return read_track_events ( instance, track_id ); 1021 | } 1022 | 1023 | uint8_t read_header ( blastmidi* instance ) 1024 | { 1025 | 1026 | /* 1027 | * Read the header chunk. 1028 | * This header chunk should have a type of MThd. We make a temporary storage of 5 bytes, and NULL terminate the string. 1029 | */ 1030 | uint8_t temp[5]; 1031 | uint32_t header_size = 0; 1032 | uint16_t file_type = 0; 1033 | uint16_t tracks = 0; 1034 | uint16_t time_division = 0; 1035 | uint8_t time_type = 0; 1036 | 1037 | uint8_t result = read_bytes ( instance, temp, 4 ); 1038 | if ( result != BLASTMIDI_OK ) 1039 | { 1040 | return result; 1041 | } 1042 | temp[4] = 0; 1043 | if ( strcmp ( ( const char* ) temp, "MThd" ) != 0 ) 1044 | { 1045 | #ifdef BLASTMIDI_DEBUG 1046 | printf ( "Invalid chunk.\n" ); 1047 | #endif 1048 | return BLASTMIDI_INVALID; 1049 | } 1050 | 1051 | result = read_32_bit ( instance, &header_size ); 1052 | if ( result != BLASTMIDI_OK ) 1053 | { 1054 | return result; 1055 | } 1056 | 1057 | /* 1058 | * The header chunk should always have a size of 6. 1059 | */ 1060 | if ( header_size != 6 ) 1061 | { 1062 | #ifdef BLASTMIDI_DEBUG 1063 | printf ( "Invalid chunk header size.\nReported: %u\n", ( uint32_t ) header_size ); 1064 | #endif 1065 | return BLASTMIDI_INVALID; 1066 | } 1067 | 1068 | /* 1069 | * First, we read the type of the Midi file. It is stored in the first 2 bytes of the header data. 1070 | */ 1071 | result = read_16_bit ( instance, &file_type ); 1072 | if ( result != BLASTMIDI_OK ) 1073 | { 1074 | return result; 1075 | } 1076 | 1077 | /* 1078 | * The type must be either 0, 1 or 2. Verify this. 1079 | */ 1080 | if ( file_type != 0 && file_type != 1 && file_type != 2 ) 1081 | { 1082 | return BLASTMIDI_INVALID; 1083 | } 1084 | #ifdef BLASTMIDI_DEBUG 1085 | printf ( "File type: %u\n", ( uint32_t ) file_type ); 1086 | #endif 1087 | instance->file_type = ( uint8_t ) file_type; 1088 | 1089 | /* 1090 | * Read the number of track chunks that are supposed to be in the file. 1091 | */ 1092 | result = read_16_bit ( instance, &tracks ); 1093 | if ( result != BLASTMIDI_OK ) 1094 | { 1095 | return result; 1096 | } 1097 | 1098 | /* 1099 | * There must always be at least one track. Verify this. 1100 | */ 1101 | if ( tracks == 0 ) 1102 | { 1103 | return BLASTMIDI_INVALID; 1104 | } 1105 | 1106 | instance->track_count = tracks; 1107 | 1108 | #ifdef BLASTMIDI_DEBUG 1109 | printf ( "Tracks: %u\n", ( uint32_t ) tracks ); 1110 | #endif 1111 | 1112 | /* 1113 | * Read the time division. 1114 | */ 1115 | result = read_16_bit ( instance, &time_division ); 1116 | if ( result != BLASTMIDI_OK ) 1117 | { 1118 | return result; 1119 | } 1120 | 1121 | /* 1122 | * Figure out what the time measurement is, by reading the most significant bit. 1123 | */ 1124 | time_type = ( uint8_t ) extract_bits_16 ( time_division, 1, 1 ); 1125 | #ifdef BLASTMIDI_DEBUG 1126 | printf ( "Time type: %u\n", ( uint32_t ) time_type ); 1127 | #endif 1128 | /* 1129 | * Not really necessary, but we verify anyway just to be pedantic. 1130 | */ 1131 | if ( time_type != 0 && time_type != 1 ) 1132 | { 1133 | #ifdef BLASTMIDI_DEBUG 1134 | printf ( "This should never happen.\nTime type is %u.\n", ( uint32_t ) time_type ); 1135 | #endif 1136 | return BLASTMIDI_INVALID; 1137 | } 1138 | 1139 | /* 1140 | * Handle the time type possibilities. 1141 | */ 1142 | if ( time_type == 0 ) 1143 | { 1144 | 1145 | /* 1146 | * The time type specifies ticks per beat. Extract the following 15 bits to get the correct value. 1147 | */ 1148 | uint16_t ticks_per_beat = extract_bits_16 ( time_division, 2, 16 ); 1149 | 1150 | /* 1151 | * This value must be greater than 0. Verify that. 1152 | */ 1153 | if ( ticks_per_beat == 0 ) 1154 | { 1155 | return BLASTMIDI_INVALID; 1156 | } 1157 | instance->ticks_per_beat = ticks_per_beat; 1158 | #ifdef BLASTMIDI_DEBUG 1159 | printf ( "Ticks per beat: %u\n", ( uint32_t ) ticks_per_beat ); 1160 | #endif 1161 | } 1162 | else 1163 | { 1164 | 1165 | /* 1166 | * The time type specifies frames per second. First figure out the number of SMPTE frames. 1167 | */ 1168 | int8_t SMPTE_frames = 0; 1169 | uint8_t ticks_per_frame = 0; 1170 | 1171 | SMPTE_frames = ( int8_t ) extract_bits_16 ( time_division, 1, 8 ); 1172 | SMPTE_frames = abs ( SMPTE_frames ); 1173 | #ifdef BLASTMIDI_DEBUG 1174 | printf ( "SMPTE frames: %d\n", ( int32_t ) SMPTE_frames ); 1175 | #endif 1176 | /* 1177 | * This value must be either 24, 25, 29 or 30. Verify that it is. 1178 | */ 1179 | if ( SMPTE_frames != 24 && SMPTE_frames != 25 && SMPTE_frames != 29 && SMPTE_frames != 30 ) 1180 | { 1181 | return BLASTMIDI_INVALID; 1182 | } 1183 | 1184 | /* 1185 | * Now extract the ticks per frame. 1186 | */ 1187 | ticks_per_frame = ( uint8_t ) extract_bits_16 ( time_division, 9, 16 ); 1188 | 1189 | /* 1190 | * This value must be greater than 0. Verify that. 1191 | */ 1192 | if ( ticks_per_frame == 0 ) 1193 | { 1194 | return BLASTMIDI_INVALID; 1195 | } 1196 | #ifdef BLASTMIDI_DEBUG 1197 | printf ( "Ticks per frame: %u\n", ( uint32_t ) ticks_per_frame ); 1198 | #endif 1199 | instance->SMPTE_frames = ( uint8_t ) SMPTE_frames; 1200 | instance->ticks_per_frame = ticks_per_frame; 1201 | } 1202 | instance->time_type = time_type; 1203 | return BLASTMIDI_OK; 1204 | } 1205 | 1206 | uint8_t blastmidi_read ( blastmidi* instance ) 1207 | { 1208 | 1209 | uint8_t result = 0; 1210 | uint16_t i; 1211 | 1212 | /* 1213 | * Did the user forget to give us an I/O callback? 1214 | */ 1215 | if ( instance->data_callback == NULL ) 1216 | { 1217 | return BLASTMIDI_NOCALLBACK; 1218 | } 1219 | 1220 | /* 1221 | * First of all, we reset the instance. 1222 | */ 1223 | reset ( instance ); 1224 | 1225 | /* 1226 | * Now it is time to read the header. 1227 | */ 1228 | result = read_header ( instance ); 1229 | if ( result != BLASTMIDI_OK ) 1230 | { 1231 | reset ( instance ); 1232 | return result; 1233 | } 1234 | 1235 | /* 1236 | * Allocate memory for all the tracks. The number of tracks to allocate has already been stored in instance->track_count. 1237 | */ 1238 | result = allocate_tracks ( instance ); 1239 | if ( result != BLASTMIDI_OK ) 1240 | { 1241 | reset ( instance ); 1242 | return result; 1243 | } 1244 | 1245 | /* 1246 | * Read the tracks. 1247 | */ 1248 | for ( i = 0; i < instance->track_count; ++i ) 1249 | { 1250 | result = read_track ( instance, i ); 1251 | if ( result != BLASTMIDI_OK ) 1252 | { 1253 | reset ( instance ); 1254 | return result; 1255 | } 1256 | } 1257 | instance->valid = 1; 1258 | return BLASTMIDI_OK; 1259 | } 1260 | 1261 | void blastmidi_whipe_track ( blastmidi* instance, unsigned int track ) 1262 | { 1263 | blastmidi_event* current = NULL; 1264 | assert ( instance ); 1265 | if ( instance == NULL ) 1266 | { 1267 | return; 1268 | } 1269 | if ( track >= instance->track_count ) 1270 | { 1271 | return; 1272 | } 1273 | current = instance->tracks[track]; 1274 | while ( current ) 1275 | { 1276 | blastmidi_event* next = current->next; 1277 | blastmidi_event_free ( instance, current ); 1278 | current = next; 1279 | } 1280 | } 1281 | 1282 | void blastmidi_event_free ( blastmidi* instance, blastmidi_event* event ) 1283 | { 1284 | /* 1285 | * Note: This function does not take the linked list into consideration. Pointer bookkeeping has to have been done before 1286 | * this function is invoked. 1287 | */ 1288 | assert ( event ); 1289 | if ( event->data && event->data_size > sizeof ( event->small_pool ) ) 1290 | { 1291 | instance->free_function ( event->data ); 1292 | } 1293 | instance->free_function ( event ); 1294 | } 1295 | 1296 | uint8_t blastmidi_add_event ( blastmidi* instance, uint16_t track_id, blastmidi_event* event, uint32_t delta_time, blastmidi_event* add_after ) 1297 | { 1298 | if ( instance == NULL ) 1299 | { 1300 | return BLASTMIDI_INVALIDPARAM; 1301 | } 1302 | if ( event == NULL ) 1303 | { 1304 | return BLASTMIDI_INVALIDPARAM; 1305 | } 1306 | if ( event->track != -1 ) 1307 | { 1308 | return BLASTMIDI_ALREADYADDED; 1309 | } 1310 | if ( track_id >= instance->track_count ) 1311 | { 1312 | return BLASTMIDI_INVALIDPARAM; 1313 | } 1314 | event->track = track_id; 1315 | event->time = delta_time; 1316 | if ( add_after ) 1317 | { 1318 | blastmidi_event* old_next = add_after->next; 1319 | add_after->next = event; 1320 | event->previous = add_after; 1321 | event->next = old_next; 1322 | if ( instance->track_ends[track_id] == add_after ) 1323 | { 1324 | instance->track_ends[track_id] = event; 1325 | } 1326 | } 1327 | else 1328 | { 1329 | blastmidi_event* old_beginning = instance->tracks[track_id]; 1330 | event->previous = NULL; 1331 | event->next = old_beginning; 1332 | instance->tracks[track_id] = event; 1333 | if ( instance->track_ends[track_id] == NULL ) 1334 | { 1335 | instance->track_ends[track_id] = event; 1336 | } 1337 | } 1338 | return BLASTMIDI_OK; 1339 | } 1340 | 1341 | uint8_t blastmidi_add_event_to_beginning_of_track ( blastmidi* instance, uint16_t track_id, blastmidi_event* event, uint32_t delta_time ) 1342 | { 1343 | if ( instance == NULL ) 1344 | { 1345 | return BLASTMIDI_INVALIDPARAM; 1346 | } 1347 | if ( event == NULL ) 1348 | { 1349 | return BLASTMIDI_INVALIDPARAM; 1350 | } 1351 | if ( event->track != -1 ) 1352 | { 1353 | return BLASTMIDI_ALREADYADDED; 1354 | } 1355 | if ( track_id >= instance->track_count ) 1356 | { 1357 | return BLASTMIDI_INVALIDPARAM; 1358 | } 1359 | return blastmidi_add_event ( instance, track_id, event, delta_time, NULL ); 1360 | } 1361 | 1362 | uint8_t blastmidi_add_event_to_end_of_track ( blastmidi* instance, uint16_t track_id, blastmidi_event* event, uint32_t delta_time ) 1363 | { 1364 | if ( instance == NULL ) 1365 | { 1366 | return BLASTMIDI_INVALIDPARAM; 1367 | } 1368 | if ( event == NULL ) 1369 | { 1370 | return BLASTMIDI_INVALIDPARAM; 1371 | } 1372 | if ( event->track != -1 ) 1373 | { 1374 | return BLASTMIDI_ALREADYADDED; 1375 | } 1376 | if ( track_id >= instance->track_count ) 1377 | { 1378 | return BLASTMIDI_INVALIDPARAM; 1379 | } 1380 | return blastmidi_add_event ( instance, track_id, event, delta_time, instance->track_ends[track_id] ); 1381 | } 1382 | 1383 | uint8_t blastmidi_get_first_event_on_track ( blastmidi* instance, uint16_t track_id, blastmidi_event** event ) 1384 | { 1385 | if ( instance == NULL ) 1386 | { 1387 | return BLASTMIDI_INVALIDPARAM; 1388 | } 1389 | if ( event == NULL ) 1390 | { 1391 | return BLASTMIDI_INVALIDPARAM; 1392 | } 1393 | if ( track_id >= instance->track_count ) 1394 | { 1395 | return BLASTMIDI_INVALIDPARAM; 1396 | } 1397 | *event = instance->tracks[track_id]; 1398 | return BLASTMIDI_OK; 1399 | } 1400 | 1401 | uint8_t blastmidi_get_last_event_on_track ( blastmidi* instance, uint16_t track_id, blastmidi_event** event ) 1402 | { 1403 | if ( instance == NULL ) 1404 | { 1405 | return BLASTMIDI_INVALIDPARAM; 1406 | } 1407 | if ( event == NULL ) 1408 | { 1409 | return BLASTMIDI_INVALIDPARAM; 1410 | } 1411 | if ( track_id >= instance->track_count ) 1412 | { 1413 | return BLASTMIDI_INVALIDPARAM; 1414 | } 1415 | *event = instance->track_ends[track_id]; 1416 | return BLASTMIDI_OK; 1417 | } 1418 | 1419 | uint8_t blastmidi_get_next_event_on_track ( blastmidi* instance, blastmidi_event** event ) 1420 | { 1421 | if ( instance == NULL ) 1422 | { 1423 | return BLASTMIDI_INVALIDPARAM; 1424 | } 1425 | if ( event == NULL ) 1426 | { 1427 | return BLASTMIDI_INVALIDPARAM; 1428 | } 1429 | if ( *event == NULL ) 1430 | { 1431 | return BLASTMIDI_INVALIDPARAM; 1432 | } 1433 | *event = event[0]->next; 1434 | return BLASTMIDI_OK; 1435 | } 1436 | 1437 | uint8_t blastmidi_get_previous_event_on_track ( blastmidi* instance, blastmidi_event** event ) 1438 | { 1439 | if ( instance == NULL ) 1440 | { 1441 | return BLASTMIDI_INVALIDPARAM; 1442 | } 1443 | if ( event == NULL ) 1444 | { 1445 | return BLASTMIDI_INVALIDPARAM; 1446 | } 1447 | if ( *event == NULL ) 1448 | { 1449 | return BLASTMIDI_INVALIDPARAM; 1450 | } 1451 | *event = event[0]->previous; 1452 | return BLASTMIDI_OK; 1453 | } 1454 | 1455 | uint8_t blastmidi_remove_event_from_track ( blastmidi* instance, uint16_t track_id, blastmidi_event* event ) 1456 | { 1457 | 1458 | blastmidi_event* previous = NULL; 1459 | blastmidi_event* next = NULL; 1460 | 1461 | if ( instance == NULL ) 1462 | { 1463 | return BLASTMIDI_INVALIDPARAM; 1464 | } 1465 | if ( track_id >= instance->track_count ) 1466 | { 1467 | return BLASTMIDI_INVALIDPARAM; 1468 | } 1469 | if ( event == NULL ) 1470 | { 1471 | return BLASTMIDI_INVALIDPARAM; 1472 | } 1473 | if ( event->track == -1 ) 1474 | { 1475 | return BLASTMIDI_NOTADDED; 1476 | } 1477 | if ( event->track != track_id ) 1478 | { 1479 | return BLASTMIDI_NOTPARTOFTRACK; 1480 | } 1481 | previous = event->previous; 1482 | next = event->next; 1483 | if ( previous ) 1484 | { 1485 | previous->next = next; 1486 | } 1487 | if ( next ) 1488 | { 1489 | next->previous = previous; 1490 | } 1491 | if ( instance->tracks[track_id] == event ) 1492 | { 1493 | instance->tracks[track_id] = next; 1494 | } 1495 | if ( instance->track_ends[track_id] == event ) 1496 | { 1497 | instance->track_ends[track_id] = previous; 1498 | } 1499 | blastmidi_event_free ( instance, event ); 1500 | return BLASTMIDI_OK; 1501 | } 1502 | 1503 | void blastmidi_free ( blastmidi* instance ) 1504 | { 1505 | reset ( instance ); 1506 | } 1507 | -------------------------------------------------------------------------------- /src/blastmidi_utility.h: -------------------------------------------------------------------------------- 1 | /* 2 | * BlastMidi 3 | * 4 | * A library of routines for working with Midi files. 5 | * 6 | * Copyright Blastbay Studios (Philip Bennefall) 2014 - 2015. 7 | * Distributed under the Boost Software License, Version 1.0. 8 | * (See accompanying file LICENSE_1_0.txt or copy at 9 | * http://www.boost.org/LICENSE_1_0.txt) 10 | * 11 | * blastmidi_utility.h 12 | * A collection of utility functions for endian and bit management. 13 | */ 14 | 15 | #ifndef BLASTMIDI_UTILITY_H 16 | #define BLASTMIDI_UTILITY_H 17 | 18 | #include 19 | #include 20 | 21 | /* 22 | * int is_little_endian (); 23 | * This returns nonzero if we are running on a little endian platform. 24 | */ 25 | int is_little_endian () 26 | { 27 | int16_t i = 1; 28 | return ( int ) * ( ( uint8_t* ) &i ) == 1; 29 | } 30 | 31 | /* 32 | * uint32_t extract_bits_32(uint32_t value, uint8_t a, uint8_t b); 33 | * Extract bits from a 32 bit number. 34 | * a is the starting bit and b is the ending bit to extract from the whole. 35 | * a and b can range from 1 to 32. 36 | * a must always be smaller than or equal to b. 37 | * 1 is the most significant bit, and 32 is the least significant. 38 | * The result is shifted right so that the least significant extracted bit ends up as the least significant one in the new number. 39 | */ 40 | uint32_t extract_bits_32 ( uint32_t value, uint8_t a, uint8_t b ) 41 | { 42 | 43 | assert ( a <= b ); 44 | assert ( a >= 1 && a <= 32 && b >= 1 && b <= 32 ); 45 | 46 | value = value << ( a - 1 ); 47 | value = value >> ( 31 - ( b - a ) ); 48 | return value; 49 | } 50 | 51 | /* 52 | * uint32_t swap_32(uint32_t x); 53 | * Swap the bytes of a 32 bit integer. 54 | */ 55 | uint32_t swap_32 ( uint32_t x ) 56 | { 57 | x = ( x & 0x0000FFFF ) << 16 | ( x & 0xFFFF0000 ) >> 16; 58 | return ( x & 0x00FF00FF ) << 8 | ( x & 0xFF00FF00 ) >> 8; 59 | } 60 | 61 | /* 62 | * uint16_t extract_bits_16(uint16_t value, uint8_t a, uint8_t b); 63 | * Extract bits from a 16 bit number. 64 | * a is the starting bit and b is the ending bit to extract from the whole. 65 | * a and b can range from 1 to 16. 66 | * a must always be smaller than or equal to b. 67 | * 1 is the most significant bit, and 16 is the least significant. 68 | * The result is shifted right so that the least significant extracted bit ends up as the least significant one in the new number. 69 | */ 70 | uint16_t extract_bits_16 ( uint16_t value, uint8_t a, uint8_t b ) 71 | { 72 | 73 | assert ( a <= b ); 74 | assert ( a >= 1 && a <= 16 && b >= 1 && b <= 16 ); 75 | 76 | value = value << ( a - 1 ); 77 | value = value >> ( 15 - ( b - a ) ); 78 | return value; 79 | } 80 | 81 | /* 82 | * uint16_t swap_16(uint16_t x); 83 | * Swap the bytes of a 16 bit integer. 84 | */ 85 | uint16_t swap_16 ( uint16_t x ) 86 | { 87 | return ( ( x & 0xff ) << 8 ) | ( ( x & 0xff00 ) >> 8 ); 88 | } 89 | 90 | /* 91 | * uint8_t extract_bits_8(uint8_t value, uint8_t a, uint8_t b); 92 | * Extract bits from an 8 bit number. 93 | * a is the starting bit and b is the ending bit to extract from the whole. 94 | * a and b can range from 1 to 8. 95 | * a must always be smaller than or equal to b. 96 | * 1 is the most significant bit, and 8 is the least significant. 97 | * The result is shifted right so that the least significant extracted bit ends up as the least significant one in the new number. 98 | */ 99 | uint8_t extract_bits_8 ( uint8_t value, uint8_t a, uint8_t b ) 100 | { 101 | 102 | assert ( a <= b ); 103 | assert ( a >= 1 && a <= 8 && b >= 1 && b <= 8 ); 104 | 105 | value = value << ( a - 1 ); 106 | value = value >> ( 7 - ( b - a ) ); 107 | return value; 108 | } 109 | 110 | /* 111 | * uint32_t convert_endian_32(uint32_t x, int8_t endian_flag); 112 | * Midi files are always big endian, so if this is a little endian machine we have to swap. 113 | * This version works on a 32 bit integer. 114 | * The endian flag is 1 if the host is little endian and 2 if it is not (big endian is then assumed). Any other value is an error. 115 | */ 116 | uint32_t convert_endian_32 ( uint32_t x, int8_t endian_flag ) 117 | { 118 | assert ( endian_flag >= 1 && endian_flag <= 2 ); 119 | if ( endian_flag == 1 ) 120 | { 121 | return swap_32 ( x ); 122 | } 123 | return x; 124 | } 125 | 126 | /* 127 | * uint16_t convert_endian_16(uint16_t x, int8_t endian_flag); 128 | * Midi files are always big endian, so if this is a little endian machine we have to swap. 129 | * This version works on a 16 bit integer. 130 | * The endian flag is 1 if the host is little endian and 2 if it is not (big endian is then assumed). Any other value is an error. 131 | */ 132 | uint16_t convert_endian_16 ( uint16_t x, int8_t endian_flag ) 133 | { 134 | assert ( endian_flag >= 1 && endian_flag <= 2 ); 135 | if ( endian_flag == 1 ) 136 | { 137 | return swap_16 ( x ); 138 | } 139 | return x; 140 | } 141 | 142 | #endif /* BLASTMIDI_UTILITY_H */ 143 | --------------------------------------------------------------------------------