61 g_critical(
"Cannot allocate smf_t structure: %s", strerror(errno));
67 smf->tracks_array = g_ptr_array_new();
68 assert(
smf->tracks_array);
70 smf->tempo_array = g_ptr_array_new();
71 assert(
smf->tempo_array);
91 while (
smf->tracks_array->len > 0)
96 assert(
smf->tracks_array->len == 0);
97 assert(
smf->number_of_tracks == 0);
98 g_ptr_array_free(
smf->tracks_array, TRUE);
99 g_ptr_array_free(
smf->tempo_array, TRUE);
114 g_critical(
"Cannot allocate smf_track_t structure: %s", strerror(errno));
160 assert(track->
smf == NULL);
163 g_ptr_array_add(
smf->tracks_array, track);
165 smf->number_of_tracks++;
168 if (
smf->number_of_tracks > 1) {
184 assert(track->
smf != NULL);
192 for (i = track->
track_number; i <= track->
smf->number_of_tracks; i++) {
221 g_critical(
"Cannot allocate smf_event_t structure: %s", strerror(errno));
227 event->delta_time_pulses = -1;
228 event->time_pulses = -1;
229 event->time_seconds = -1.0;
230 event->track_number = -1;
251 event->midi_buffer_length = len;
254 g_critical(
"Cannot allocate MIDI buffer structure: %s", strerror(errno));
292 if (first_byte < 0) {
293 g_critical(
"First byte of MIDI message cannot be < 0");
299 if (first_byte > 255) {
300 g_critical(
"smf_event_new_from_bytes: first byte is %d, which is larger than 255.", first_byte);
305 g_critical(
"smf_event_new_from_bytes: first byte is not a valid status byte.");
312 else if (third_byte < 0)
318 if (second_byte > 255) {
319 g_critical(
"smf_event_new_from_bytes: second byte is %d, which is larger than 255.", second_byte);
324 g_critical(
"smf_event_new_from_bytes: second byte cannot be a status byte.");
330 if (third_byte > 255) {
331 g_critical(
"smf_event_new_from_bytes: third byte is %d, which is larger than 255.", third_byte);
336 g_critical(
"smf_event_new_from_bytes: third byte cannot be a status byte.");
341 event->midi_buffer_length = len;
344 g_critical(
"Cannot allocate MIDI buffer structure: %s", strerror(errno));
350 event->midi_buffer[0] = first_byte;
352 event->midi_buffer[1] = second_byte;
354 event->midi_buffer[2] = third_byte;
365 if (event->
track != NULL)
381events_array_compare_function(gconstpointer aa, gconstpointer bb)
415remove_eot_if_before_pulses(
smf_track_t *track,
int pulses)
443 int i, last_pulses = 0;
445 assert(track->
smf != NULL);
446 assert(event->
track == NULL);
451 remove_eot_if_before_pulses(track, event->
time_pulses);
453 event->track = track;
467 if (last_pulses <= event->time_pulses) {
468 event->delta_time_pulses =
event->time_pulses - last_pulses;
477 g_ptr_array_sort(track->
events_array, events_array_compare_function);
543 if (last_event != NULL) {
563 if (last_event != NULL) {
587 assert(event->
track != NULL);
590 track =
event->track;
607 for (i = event->
event_number; i <= track->number_of_events; i++) {
621 event->event_number = -1;
622 event->delta_time_pulses = -1;
623 event->time_pulses = -1;
624 event->time_seconds = -1.0;
654 assert(format == 0 || format == 1);
656 if (
smf->number_of_tracks > 1 && format == 0) {
657 g_critical(
"There is more than one track, cannot set format to 0.");
661 smf->format = format;
705 assert(event != NULL);
752 assert(track_number >= 1);
754 if (track_number >
smf->number_of_tracks)
757 track = (
smf_track_t *)g_ptr_array_index(
smf->tracks_array, track_number - 1);
773 assert(event_number >= 1);
778 event = g_ptr_array_index(track->
events_array, event_number - 1);
813 for (i = 1; i <=
smf->number_of_tracks; i++) {
824 min_time_track = track;
828 return (min_time_track);
842 g_debug(
"End of the song.");
850 assert(event != NULL);
852 event->track->smf->last_seek_position = -1.0;
881 g_debug(
"End of the song.");
887 event = smf_peek_next_event_from_track(track);
889 assert(event != NULL);
907 smf->last_seek_position = 0.0;
909 for (i = 1; i <=
smf->number_of_tracks; i++) {
912 assert(track != NULL);
916 event = smf_peek_next_event_from_track(track);
923 g_warning(
"Warning: empty track.");
956 smf->last_seek_position =
event->time_seconds;
970 assert(seconds >= 0.0);
972 if (seconds ==
smf->last_seek_position) {
974 g_debug(
"Avoiding seek to %f seconds.", seconds);
982 g_debug(
"Seeking to %f seconds.", seconds);
989 g_critical(
"Trying to seek past the end of song.");
999 smf->last_seek_position = seconds;
1013 assert(pulses >= 0);
1018 g_debug(
"Seeking to %d pulses.", pulses);
1024 if (event == NULL) {
1025 g_critical(
"Trying to seek past the end of song.");
1035 smf->last_seek_position =
event->time_seconds;
1048 for (i = 1; i <=
smf->number_of_tracks; i++) {
1061 pulses =
event->time_pulses;
1074 double seconds = 0.0;
1076 for (i = 1; i <=
smf->number_of_tracks; i++) {
1089 seconds =
event->time_seconds;
1114 return (SMF_VERSION);
void smf_event_remove_from_track(smf_event_t *event)
Detaches event from its track.
smf_event_t * smf_event_new(void)
Allocates new smf_event_t structure.
smf_event_t * smf_track_get_event_by_number(const smf_track_t *track, int event_number)
smf_track_t * smf_get_track_by_number(const smf_t *smf, int track_number)
int smf_track_add_eot_seconds(smf_track_t *track, double seconds)
void smf_delete(smf_t *smf)
Frees smf and all it's descendant structures.
double smf_get_length_seconds(const smf_t *smf)
int smf_seek_to_seconds(smf_t *smf, double seconds)
Seeks the SMF to the given position.
int smf_track_add_eot_delta_pulses(smf_track_t *track, int delta)
Add End Of Track metaevent.
smf_track_t * smf_track_new(void)
Allocates new smf_track_t structure.
int smf_event_is_last(const smf_event_t *event)
smf_track_t * smf_find_track_with_next_event(smf_t *smf)
Searches for track that contains next event, in time order.
smf_event_t * smf_peek_next_event(smf_t *smf)
smf_event_t * smf_track_get_next_event(smf_track_t *track)
Returns next event from the track given and advances next event counter.
void smf_track_add_event(smf_track_t *track, smf_event_t *event)
Adds the event to the track and computes ->delta_pulses.
void smf_add_track(smf_t *smf, smf_track_t *track)
Appends smf_track_t to smf.
int smf_get_length_pulses(const smf_t *smf)
void smf_track_delete(smf_track_t *track)
Detaches track from its smf and frees it.
int smf_set_format(smf_t *smf, int format)
Sets "Format" field of MThd header to the specified value.
smf_event_t * smf_track_get_last_event(const smf_track_t *track)
smf_event_t * smf_get_next_event(smf_t *smf)
int smf_seek_to_event(smf_t *smf, const smf_event_t *target)
Seeks the SMF to the given event.
smf_t * smf_new(void)
Allocates new smf_t structure.
void smf_skip_next_event(smf_t *smf)
Advance the "next event counter".
void smf_rewind(smf_t *smf)
Rewinds the SMF.
int smf_event_is_tempo_change_or_time_signature(const smf_event_t *event)
void smf_event_delete(smf_event_t *event)
Detaches event from its track and frees it.
void smf_track_remove_from_smf(smf_track_t *track)
Detaches track from the smf.
int smf_track_add_eot_pulses(smf_track_t *track, int pulses)
const char * smf_get_version(void)
int smf_set_ppqn(smf_t *smf, int ppqn)
Sets the PPQN ("Division") field of MThd header.
int smf_seek_to_pulses(smf_t *smf, int pulses)
Seeks the SMF to the given position.
smf_event_t * smf_event_new_from_bytes(int first_byte, int second_byte, int third_byte)
Allocates an smf_event_t structure and fills it with at most three bytes of data.
smf_event_t * smf_event_new_from_pointer(void *midi_data, int len)
Allocates an smf_event_t structure and fills it with "len" bytes copied from "midi_data".
Public interface declaration for libsmf, Standard MIDI File format library.
void smf_track_add_event_pulses(smf_track_t *track, smf_event_t *event, int pulses)
Adds event to the track at the time "pulses" clocks from the start of song.
int smf_event_is_metadata(const smf_event_t *event) WARN_UNUSED_RESULT
struct smf_event_struct smf_event_t
int smf_event_is_eot(const smf_event_t *event) WARN_UNUSED_RESULT
struct smf_track_struct smf_track_t
void smf_track_add_event_delta_pulses(smf_track_t *track, smf_event_t *event, int pulses)
Adds event to the track at the time "pulses" clocks from the previous event in this track.
void smf_track_add_event_seconds(smf_track_t *track, smf_event_t *event, double seconds)
Adds event to the track at the time "seconds" seconds from the start of song.
int is_status_byte(const unsigned char status)
Returns 1 if the given byte is a valid status byte, 0 otherwise.
void maybe_add_to_tempo_map(smf_event_t *event)
void smf_init_tempo(smf_t *smf)
void smf_create_tempo_map_and_compute_seconds(smf_t *smf)
void remove_last_tempo_with_pulses(smf_t *smf, int pulses)
void smf_fini_tempo(smf_t *smf)
int time_pulses
Time, in pulses, since the start of the song.
int event_number
Number of this event in the track.
unsigned char * midi_buffer
Pointer to the buffer containing MIDI message.
double time_seconds
Time, in seconds, since the start of the song.
int track_number
Tracks are numbered consecutively, starting from 1.
int midi_buffer_length
Length of the MIDI message in the buffer, in bytes.
int delta_time_pulses
Note that the time fields are invalid, if event is not attached to a track.
smf_track_t * track
Pointer to the track, or NULL if event is not attached.
GPtrArray * tracks_array
Private, used by smf.c.
int time_of_next_event
Absolute time of next event on events_queue.