/** * Locates, basing on track->next_event_offset, the next event data in track->buffer, * interprets it, allocates smf_event_t and fills it properly. Returns smf_event_t * or NULL, if there was an error. Allocating event means adding it to the track; * see smf_event_new(). */ static smf_event_t * parse_next_event(smf_track_t *track) { uint32_t etime = 0; uint32_t len; size_t buffer_length; unsigned char *c, *start; smf_event_t *event = smf_event_new(); if (event == NULL) goto error; c = start = (unsigned char *)track->file_buffer + track->next_event_offset; assert(track->file_buffer != NULL); assert(track->file_buffer_length > 0); assert(track->next_event_offset > 0); buffer_length = track->file_buffer_length - track->next_event_offset; /* if there was no meta-EOT event, buffer_length can be zero. This is an error in the SMF file, but it shouldn't be treated as fatal. */ if (buffer_length == 0) { g_warning ("SMF warning: expected EOT at end of track, but none found"); goto error; } /* First, extract time offset from previous event. */ if (smf_extract_vlq(c, buffer_length, &etime, &len)) { goto error; } c += len; buffer_length -= len; if (buffer_length <= 0) goto error; /* Now, extract the actual event. */ if (extract_midi_event(c, buffer_length, event, &len, track->last_status)) { goto error; } c += len; buffer_length -= len; track->last_status = event->midi_buffer[0]; track->next_event_offset += c - start; smf_track_add_event_delta_pulses(track, event, etime); return (event); error: if (event != NULL) smf_event_delete(event); return (NULL); }
/** * Add End Of Track metaevent. Using it is optional, libsmf will automatically * add EOT to the tracks during smf_save, with delta_pulses 0. If you try to add EOT * in the middle of the track, it will fail and nonzero value will be returned. * If you try to add EOT after another EOT event, it will be added, but the existing * EOT event will be removed. * * \return 0 if everything went ok, nonzero otherwise. */ int smf_track_add_eot_delta_pulses(smf_track_t *track, int delta) { smf_event_t *event; event = smf_event_new_from_bytes(0xFF, 0x2F, 0x00); if (event == NULL) return (-1); smf_track_add_event_delta_pulses(track, event, delta); return (0); }