ardour
smf.c
Go to the documentation of this file.
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 
35 /* Reference: http://www.borg.com/~jglatt/tech/midifile.htm */
36 
37 #include <stdlib.h>
38 #include <string.h>
39 #include <assert.h>
40 #include <math.h>
41 #include <errno.h>
42 #ifdef PLATFORM_WINDOWS
43 #include <winsock2.h>
44 #else
45 #include <arpa/inet.h>
46 #endif
47 #include "smf.h"
48 #include "smf_private.h"
49 
54 smf_t *
55 smf_new(void)
56 {
57  int cantfail;
58 
59  smf_t *smf = (smf_t*)malloc(sizeof(smf_t));
60  if (smf == NULL) {
61  g_critical("Cannot allocate smf_t structure: %s", strerror(errno));
62  return (NULL);
63  }
64 
65  memset(smf, 0, sizeof(smf_t));
66 
67  smf->tracks_array = g_ptr_array_new();
68  assert(smf->tracks_array);
69 
70  smf->tempo_array = g_ptr_array_new();
71  assert(smf->tempo_array);
72 
73  cantfail = smf_set_ppqn(smf, 120);
74  assert(!cantfail);
75 
76  cantfail = smf_set_format(smf, 0);
77  assert(!cantfail);
78 
79  smf_init_tempo(smf);
80 
81  return (smf);
82 }
83 
87 void
89 {
90  /* Remove all the tracks, from last to first. */
91  while (smf->tracks_array->len > 0)
92  smf_track_delete((smf_track_t*)g_ptr_array_index(smf->tracks_array, smf->tracks_array->len - 1));
93 
94  smf_fini_tempo(smf);
95 
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);
100 
101  memset(smf, 0, sizeof(smf_t));
102  free(smf);
103 }
104 
109 smf_track_t *
111 {
112  smf_track_t *track = (smf_track_t*)malloc(sizeof(smf_track_t));
113  if (track == NULL) {
114  g_critical("Cannot allocate smf_track_t structure: %s", strerror(errno));
115  return (NULL);
116  }
117 
118  memset(track, 0, sizeof(smf_track_t));
119  track->next_event_number = 0;
120 
121  track->events_array = g_ptr_array_new();
122  assert(track->events_array);
123 
124  return (track);
125 }
126 
130 void
132 {
133  assert(track);
134  assert(track->events_array);
135 
136  /* Remove all the events, from last to first. */
137  while (track->events_array->len > 0)
138  smf_event_delete((smf_event_t*)g_ptr_array_index(track->events_array, track->events_array->len - 1));
139 
140  if (track->smf)
142 
143  assert(track->events_array->len == 0);
144  assert(track->number_of_events == 0);
145  g_ptr_array_free(track->events_array, TRUE);
146 
147  memset(track, 0, sizeof(smf_track_t));
148  free(track);
149 }
150 
151 
155 void
157 {
158 #ifndef NDEBUG
159  int cantfail;
160 #endif
161 
162  assert(track->smf == NULL);
163 
164  track->smf = smf;
165  g_ptr_array_add(smf->tracks_array, track);
166 
167  smf->number_of_tracks++;
168  track->track_number = smf->number_of_tracks;
169 
170  if (smf->number_of_tracks > 1) {
171 #ifndef NDEBUG
172  cantfail = smf_set_format(smf, 1);
173  assert(!cantfail);
174 #else
175  smf_set_format(smf, 1);
176 #endif
177 
178  }
179 }
180 
184 void
186 {
187  int i;
188  size_t j;
189  smf_track_t *tmp;
190  smf_event_t *ev;
191 
192  assert(track->smf != NULL);
193 
194  track->smf->number_of_tracks--;
195 
196  assert(track->smf->tracks_array);
197  g_ptr_array_remove(track->smf->tracks_array, track);
198 
199  /* Renumber the rest of the tracks, so they are consecutively numbered. */
200  for (i = track->track_number; i <= track->smf->number_of_tracks; i++) {
201  tmp = smf_get_track_by_number(track->smf, i);
202  tmp->track_number = i;
203 
204  /*
205  * Events have track numbers too. I guess this wasn't a wise
206  * decision. ;-/
207  */
208  for (j = 1; j <= tmp->number_of_events; j++) {
209  ev = smf_track_get_event_by_number(tmp, j);
210  ev->track_number = i;
211  }
212  }
213 
214  track->track_number = -1;
215  track->smf = NULL;
216 }
217 
224 smf_event_t *
226 {
227  smf_event_t *event = (smf_event_t*)malloc(sizeof(smf_event_t));
228  if (event == NULL) {
229  g_critical("Cannot allocate smf_event_t structure: %s", strerror(errno));
230  return (NULL);
231  }
232 
233  memset(event, 0, sizeof(smf_event_t));
234 
235  event->delta_time_pulses = -1;
236  event->time_pulses = -1;
237  event->time_seconds = -1.0;
238  event->track_number = -1;
239 
240  return (event);
241 }
242 
250 smf_event_t *
251 smf_event_new_from_pointer(const void *midi_data, size_t len)
252 {
253  smf_event_t *event;
254 
255  event = smf_event_new();
256  if (event == NULL)
257  return (NULL);
258 
259  event->midi_buffer_length = len;
260  event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length);
261  if (event->midi_buffer == NULL) {
262  g_critical("Cannot allocate MIDI buffer structure: %s", strerror(errno));
263  smf_event_delete(event);
264 
265  return (NULL);
266  }
267 
268  memcpy(event->midi_buffer, midi_data, len);
269 
270  return (event);
271 }
272 
289 smf_event_t *
290 smf_event_new_from_bytes(int first_byte, int second_byte, int third_byte)
291 {
292  size_t len;
293 
294  smf_event_t *event;
295 
296  event = smf_event_new();
297  if (event == NULL)
298  return (NULL);
299 
300  if (first_byte < 0) {
301  g_critical("First byte of MIDI message cannot be < 0");
302  smf_event_delete(event);
303 
304  return (NULL);
305  }
306 
307  if (first_byte > 255) {
308  g_critical("smf_event_new_from_bytes: first byte is %d, which is larger than 255.", first_byte);
309  return (NULL);
310  }
311 
312  if (!is_status_byte(first_byte)) {
313  g_critical("smf_event_new_from_bytes: first byte is not a valid status byte.");
314  return (NULL);
315  }
316 
317 
318  if (second_byte < 0)
319  len = 1;
320  else if (third_byte < 0)
321  len = 2;
322  else
323  len = 3;
324 
325  if (len > 1) {
326  if (second_byte > 255) {
327  g_critical("smf_event_new_from_bytes: second byte is %d, which is larger than 255.", second_byte);
328  return (NULL);
329  }
330 
331  if (is_status_byte(second_byte)) {
332  g_critical("smf_event_new_from_bytes: second byte cannot be a status byte.");
333  return (NULL);
334  }
335  }
336 
337  if (len > 2) {
338  if (third_byte > 255) {
339  g_critical("smf_event_new_from_bytes: third byte is %d, which is larger than 255.", third_byte);
340  return (NULL);
341  }
342 
343  if (is_status_byte(third_byte)) {
344  g_critical("smf_event_new_from_bytes: third byte cannot be a status byte.");
345  return (NULL);
346  }
347  }
348 
349  event->midi_buffer_length = len;
350  event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length);
351  if (event->midi_buffer == NULL) {
352  g_critical("Cannot allocate MIDI buffer structure: %s", strerror(errno));
353  smf_event_delete(event);
354 
355  return (NULL);
356  }
357 
358  event->midi_buffer[0] = first_byte;
359  if (len > 1)
360  event->midi_buffer[1] = second_byte;
361  if (len > 2)
362  event->midi_buffer[2] = third_byte;
363 
364  return (event);
365 }
366 
370 void
372 {
373  if (event->track != NULL)
375 
376  if (event->midi_buffer != NULL) {
377  memset(event->midi_buffer, 0, event->midi_buffer_length);
378  free(event->midi_buffer);
379  }
380 
381  memset(event, 0, sizeof(smf_event_t));
382  free(event);
383 }
384 
388 static gint
389 events_array_compare_function(gconstpointer aa, gconstpointer bb)
390 {
391  const smf_event_t *a, *b;
392 
393  /* "The comparison function for g_ptr_array_sort() doesn't take the pointers
394  from the array as arguments, it takes pointers to the pointers in the array." */
395  a = (const smf_event_t *)*(const gpointer *)aa;
396  b = (const smf_event_t *)*(const gpointer *)bb;
397 
398  if (a->time_pulses < b->time_pulses)
399  return (-1);
400 
401  if (a->time_pulses > b->time_pulses)
402  return (1);
403 
404  /*
405  * We need to preserve original order, otherwise things will break
406  * when there are several events with the same ->time_pulses.
407  * XXX: This is an ugly hack; we should remove sorting altogether.
408  */
409 
410  if (a->event_number < b->event_number)
411  return (-1);
412 
413  if (a->event_number > b->event_number)
414  return (1);
415 
416  return (0);
417 }
418 
419 /*
420  * An assumption here is that if there is an EOT event, it will be at the end of the track.
421  */
422 static void
424 {
425  smf_event_t *event;
426 
427  event = smf_track_get_last_event(track);
428 
429  if (event == NULL)
430  return;
431 
432  if (!smf_event_is_eot(event))
433  return;
434 
435  if (event->time_pulses > pulses)
436  return;
437 
439 }
440 
448 void
450 {
451  size_t i, last_pulses = 0;
452 
453  assert(track->smf != NULL);
454  assert(event->track == NULL);
455  assert(event->delta_time_pulses == -1);
456  assert(event->time_seconds >= 0.0);
457 
459 
460  event->track = track;
461  event->track_number = track->track_number;
462 
463  if (track->number_of_events == 0) {
464  assert(track->next_event_number == 0);
465  track->next_event_number = 1;
466  }
467 
468  if (track->number_of_events > 0)
469  last_pulses = smf_track_get_last_event(track)->time_pulses;
470 
471  track->number_of_events++;
472 
473  /* Are we just appending element at the end of the track? */
474  if (last_pulses <= event->time_pulses) {
475  event->delta_time_pulses = event->time_pulses - last_pulses;
476  assert(event->delta_time_pulses >= 0);
477  g_ptr_array_add(track->events_array, event);
478  event->event_number = track->number_of_events;
479 
480  /* We need to insert in the middle of the track. XXX: This is slow. */
481  } else {
482  /* Append, then sort according to ->time_pulses. */
483  g_ptr_array_add(track->events_array, event);
484  g_ptr_array_sort(track->events_array, events_array_compare_function);
485 
486  /* Renumber entries and fix their ->delta_pulses. */
487  for (i = 1; i <= track->number_of_events; i++) {
489  tmp->event_number = i;
490 
491  if (tmp->delta_time_pulses != -1)
492  continue;
493 
494  if (i == 1) {
495  tmp->delta_time_pulses = tmp->time_pulses;
496  } else {
497  tmp->delta_time_pulses = tmp->time_pulses -
499  assert(tmp->delta_time_pulses >= 0);
500  }
501  }
502 
503  /* Adjust ->delta_time_pulses of the next event. */
504  if (event->event_number < track->number_of_events) {
505  smf_event_t *next_event = smf_track_get_event_by_number(track, event->event_number + 1);
506  assert(next_event);
507  assert(next_event->time_pulses >= event->time_pulses);
508  next_event->delta_time_pulses -= event->delta_time_pulses;
509  assert(next_event->delta_time_pulses >= 0);
510  }
511  }
512 
514  if (smf_event_is_last(event))
515  maybe_add_to_tempo_map(event);
516  else
518  }
519 }
520 
530 int
532 {
533  smf_event_t *event;
534 
535  event = smf_event_new_from_bytes(0xFF, 0x2F, 0x00);
536  if (event == NULL)
537  return (-1);
538 
539  smf_track_add_event_delta_pulses(track, event, delta);
540 
541  return (0);
542 }
543 
544 int
545 smf_track_add_eot_pulses(smf_track_t *track, size_t pulses)
546 {
547  smf_event_t *event, *last_event;
548 
549  last_event = smf_track_get_last_event(track);
550  if (last_event != NULL) {
551  if (last_event->time_pulses > pulses)
552  return (-2);
553  }
554 
555  event = smf_event_new_from_bytes(0xFF, 0x2F, 0x00);
556  if (event == NULL)
557  return (-3);
558 
559  smf_track_add_event_pulses(track, event, pulses);
560 
561  return (0);
562 }
563 
564 int
565 smf_track_add_eot_seconds(smf_track_t *track, double seconds)
566 {
567  smf_event_t *event, *last_event;
568 
569  last_event = smf_track_get_last_event(track);
570  if (last_event != NULL) {
571  if (last_event->time_seconds > seconds)
572  return (-2);
573  }
574 
575  event = smf_event_new_from_bytes(0xFF, 0x2F, 0x00);
576  if (event == NULL)
577  return (-1);
578 
579  smf_track_add_event_seconds(track, event, seconds);
580 
581  return (0);
582 }
583 
587 void
589 {
590  size_t i;
591  int was_last;
592  smf_event_t *tmp;
593  smf_track_t *track;
594 
595  assert(event->track != NULL);
596  assert(event->track->smf != NULL);
597 
598  track = event->track;
599  was_last = smf_event_is_last(event);
600 
601  /* Adjust ->delta_time_pulses of the next event. */
602  if (event->event_number < track->number_of_events) {
603  tmp = smf_track_get_event_by_number(track, event->event_number + 1);
604  assert(tmp);
605  tmp->delta_time_pulses += event->delta_time_pulses;
606  }
607 
608  track->number_of_events--;
609  g_ptr_array_remove(track->events_array, event);
610 
611  if (track->number_of_events == 0)
612  track->next_event_number = 0;
613 
614  /* Renumber the rest of the events, so they are consecutively numbered. */
615  for (i = event->event_number; i <= track->number_of_events; i++) {
616  tmp = smf_track_get_event_by_number(track, i);
617  tmp->event_number = i;
618  }
619 
621  /* XXX: This will cause problems, when there is more than one Tempo Change event at a given time. */
622  if (was_last)
624  else
626  }
627 
628  event->track = NULL;
629  event->event_number = 0;
630  event->delta_time_pulses = -1;
631  event->time_pulses = 0;
632  event->time_seconds = -1.0;
633 }
634 
638 int
640 {
641  if (!smf_event_is_metadata(event))
642  return (0);
643 
644  assert(event->midi_buffer_length >= 2);
645 
646  if (event->midi_buffer[1] == 0x51 || event->midi_buffer[1] == 0x58)
647  return (1);
648 
649  return (0);
650 }
651 
659 int
660 smf_set_format(smf_t *smf, int format)
661 {
662  assert(format == 0 || format == 1);
663 
664  if (smf->number_of_tracks > 1 && format == 0) {
665  g_critical("There is more than one track, cannot set format to 0.");
666  return (-1);
667  }
668 
669  smf->format = format;
670 
671  return (0);
672 }
673 
681 int
682 smf_set_ppqn(smf_t *smf, uint16_t ppqn)
683 {
684  smf->ppqn = ppqn;
685 
686  return (0);
687 }
688 
697 smf_event_t *
699 {
700  smf_event_t *event, *next_event;
701 
702  /* Track is empty? */
703  if (track->number_of_events == 0)
704  return (NULL);
705 
706  /* End of track? */
707  if (track->next_event_number == 0)
708  return (NULL);
709 
710  assert(track->next_event_number >= 1);
711 
712  event = smf_track_get_event_by_number(track, track->next_event_number);
713 
714  assert(event != NULL);
715 
716  /* Is this the last event in the track? */
717  if (track->next_event_number < track->number_of_events) {
718  next_event = smf_track_get_event_by_number(track, track->next_event_number + 1);
719  assert(next_event);
720 
721  track->time_of_next_event = next_event->time_pulses;
722  track->next_event_number++;
723  } else {
724  track->next_event_number = 0;
725  }
726 
727  return (event);
728 }
729 
735 static smf_event_t *
737 {
738  smf_event_t *event;
739 
740  /* End of track? */
741  if (track->next_event_number == 0)
742  return (NULL);
743 
744  assert(track->next_event_number >= 1);
745  assert(track->events_array->len != 0);
746 
747  event = smf_track_get_event_by_number(track, track->next_event_number);
748 
749  return (event);
750 }
751 
756 smf_track_t *
757 smf_get_track_by_number(const smf_t *smf, int track_number)
758 {
759  smf_track_t *track;
760 
761  assert(track_number >= 1);
762 
763  if (track_number > smf->number_of_tracks)
764  return (NULL);
765 
766  track = (smf_track_t *)g_ptr_array_index(smf->tracks_array, track_number - 1);
767 
768  assert(track);
769 
770  return (track);
771 }
772 
777 smf_event_t *
778 smf_track_get_event_by_number(const smf_track_t *track, size_t event_number)
779 {
780  smf_event_t *event;
781 
782  assert(event_number >= 1);
783 
784  if (event_number > track->number_of_events)
785  return (NULL);
786 
787  event = (smf_event_t*)g_ptr_array_index(track->events_array, event_number - 1);
788 
789  assert(event);
790 
791  return (event);
792 }
793 
797 smf_event_t *
799 {
800  smf_event_t *event;
801 
802  if (track->number_of_events == 0)
803  return (NULL);
804 
805  event = smf_track_get_event_by_number(track, track->number_of_events);
806 
807  return (event);
808 }
809 
815 smf_track_t *
817 {
818  int i;
819  size_t min_time = 0;
820  smf_track_t *track = NULL, *min_time_track = NULL;
821 
822  /* Find track with event that should be played next. */
823  for (i = 1; i <= smf->number_of_tracks; i++) {
824  track = smf_get_track_by_number(smf, i);
825 
826  assert(track);
827 
828  /* No more events in this track? */
829  if (track->next_event_number == 0)
830  continue;
831 
832  if (track->time_of_next_event < min_time || min_time_track == NULL) {
833  min_time = track->time_of_next_event;
834  min_time_track = track;
835  }
836  }
837 
838  return (min_time_track);
839 }
840 
844 smf_event_t *
846 {
847  smf_event_t *event;
849 
850  if (track == NULL) {
851 #if 0
852  g_debug("End of the song.");
853 #endif
854 
855  return (NULL);
856  }
857 
858  event = smf_track_get_next_event(track);
859 
860  assert(event != NULL);
861 
862  event->track->smf->last_seek_position = -1.0;
863 
864  return (event);
865 }
866 
871 void
873 {
874  smf_event_t *ignored = smf_get_next_event(smf);
875  (void) ignored;
876 }
877 
882 smf_event_t *
884 {
885  smf_event_t *event;
887 
888  if (track == NULL) {
889 #if 0
890  g_debug("End of the song.");
891 #endif
892 
893  return (NULL);
894  }
895 
896  event = smf_peek_next_event_from_track(track);
897 
898  assert(event != NULL);
899 
900  return (event);
901 }
902 
907 void
909 {
910  int i;
911  smf_track_t *track = NULL;
912  smf_event_t *event;
913 
914  assert(smf);
915 
916  smf->last_seek_position = 0.0;
917 
918  for (i = 1; i <= smf->number_of_tracks; i++) {
919  track = smf_get_track_by_number(smf, i);
920 
921  assert(track != NULL);
922 
923  if (track->number_of_events > 0) {
924  track->next_event_number = 1;
925  event = smf_peek_next_event_from_track(track);
926  assert(event);
927  track->time_of_next_event = event->time_pulses;
928  } else {
929  track->next_event_number = 0;
930  track->time_of_next_event = 0;
931 #if 0
932  g_warning("Warning: empty track.");
933 #endif
934  }
935  }
936 }
937 
942 int
944 {
945  smf_event_t *event;
946 
947  smf_rewind(smf);
948 
949 #if 0
950  g_debug("Seeking to event %d, track %d.", target->event_number, target->track->track_number);
951 #endif
952 
953  for (;;) {
954  event = smf_peek_next_event(smf);
955 
956  /* There can't be NULL here, unless "target" is not in this smf. */
957  assert(event);
958 
959  if (event != target)
960  smf_skip_next_event(smf);
961  else
962  break;
963  }
964 
965  smf->last_seek_position = event->time_seconds;
966 
967  return (0);
968 }
969 
974 int
975 smf_seek_to_seconds(smf_t *smf, double seconds)
976 {
977  smf_event_t *event;
978 
979  assert(seconds >= 0.0);
980 
981  if (seconds == smf->last_seek_position) {
982 #if 0
983  g_debug("Avoiding seek to %f seconds.", seconds);
984 #endif
985  return (0);
986  }
987 
988  smf_rewind(smf);
989 
990 #if 0
991  g_debug("Seeking to %f seconds.", seconds);
992 #endif
993 
994  for (;;) {
995  event = smf_peek_next_event(smf);
996 
997  if (event == NULL) {
998  g_critical("Trying to seek past the end of song.");
999  return (-1);
1000  }
1001 
1002  if (event->time_seconds < seconds)
1003  smf_skip_next_event(smf);
1004  else
1005  break;
1006  }
1007 
1008  smf->last_seek_position = seconds;
1009 
1010  return (0);
1011 }
1012 
1017 int
1018 smf_seek_to_pulses(smf_t *smf, size_t pulses)
1019 {
1020  smf_event_t *event;
1021 
1022  smf_rewind(smf);
1023 
1024 #if 0
1025  g_debug("Seeking to %d pulses.", pulses);
1026 #endif
1027 
1028  for (;;) {
1029  event = smf_peek_next_event(smf);
1030 
1031  if (event == NULL) {
1032  g_critical("Trying to seek past the end of song.");
1033  return (-1);
1034  }
1035 
1036  if (event->time_pulses < pulses)
1037  smf_skip_next_event(smf);
1038  else
1039  break;
1040  }
1041 
1042  smf->last_seek_position = event->time_seconds;
1043 
1044  return (0);
1045 }
1046 
1050 size_t
1052 {
1053  int i;
1054  size_t pulses = 0;
1055 
1056  for (i = 1; i <= smf->number_of_tracks; i++) {
1057  smf_track_t *track;
1058  smf_event_t *event;
1059 
1060  track = smf_get_track_by_number(smf, i);
1061  assert(track);
1062 
1063  event = smf_track_get_last_event(track);
1064  /* Empty track? */
1065  if (event == NULL)
1066  continue;
1067 
1068  if (event->time_pulses > pulses)
1069  pulses = event->time_pulses;
1070  }
1071 
1072  return (pulses);
1073 }
1074 
1078 double
1080 {
1081  int i;
1082  double seconds = 0.0;
1083 
1084  for (i = 1; i <= smf->number_of_tracks; i++) {
1085  smf_track_t *track;
1086  smf_event_t *event;
1087 
1088  track = smf_get_track_by_number(smf, i);
1089  assert(track);
1090 
1091  event = smf_track_get_last_event(track);
1092  /* Empty track? */
1093  if (event == NULL)
1094  continue;
1095 
1096  if (event->time_seconds > seconds)
1097  seconds = event->time_seconds;
1098  }
1099 
1100  return (seconds);
1101 }
1102 
1107 int
1109 {
1110  if (smf_get_length_pulses(event->track->smf) <= event->time_pulses)
1111  return (1);
1112 
1113  return (0);
1114 }
1115 
1119 const char *
1121 {
1122  return (SMF_VERSION);
1123 }
1124 
void smf_rewind(smf_t *smf)
Definition: smf.c:908
double smf_get_length_seconds(const smf_t *smf)
Definition: smf.c:1079
int32_t delta_time_pulses
Definition: smf.h:309
static void remove_eot_if_before_pulses(smf_track_t *track, size_t pulses)
Definition: smf.c:423
int smf_event_is_tempo_change_or_time_signature(const smf_event_t *event)
Definition: smf.c:639
int format
Definition: smf.h:235
void smf_track_add_event(smf_track_t *track, smf_event_t *event)
Definition: smf.c:449
GPtrArray * events_array
Definition: smf.h:294
int smf_set_ppqn(smf_t *smf, uint16_t ppqn)
Definition: smf.c:682
GPtrArray * tempo_array
Definition: smf.h:257
void smf_track_add_event_pulses(smf_track_t *track, smf_event_t *event, size_t pulses)
Definition: smf_tempo.c:418
void smf_track_remove_from_smf(smf_track_t *track)
Definition: smf.c:185
static gint events_array_compare_function(gconstpointer aa, gconstpointer bb)
Definition: smf.c:389
size_t midi_buffer_length
Definition: smf.h:324
GPtrArray * tracks_array
Definition: smf.h:252
size_t event_number
Definition: smf.h:305
int smf_seek_to_event(smf_t *smf, const smf_event_t *target)
Definition: smf.c:943
void smf_add_track(smf_t *smf, smf_track_t *track)
Definition: smf.c:156
int smf_event_is_metadata(const smf_event_t *event) WARN_UNUSED_RESULT
Definition: smf_decode.c:57
int track_number
Definition: smf.h:279
void smf_init_tempo(smf_t *smf)
Definition: smf_tempo.c:364
smf_event_t * smf_track_get_event_by_number(const smf_track_t *track, size_t event_number)
Definition: smf.c:778
void smf_event_delete(smf_event_t *event)
Definition: smf.c:371
void smf_create_tempo_map_and_compute_seconds(smf_t *smf)
Definition: smf_tempo.c:235
int smf_track_add_eot_pulses(smf_track_t *track, size_t pulses)
Definition: smf.c:545
int smf_seek_to_pulses(smf_t *smf, size_t pulses)
Definition: smf.c:1018
smf_t * smf
Definition: smf.h:277
void maybe_add_to_tempo_map(smf_event_t *event)
Definition: smf_tempo.c:125
uint16_t ppqn
Definition: smf.h:239
int smf_event_is_eot(const smf_event_t *event) WARN_UNUSED_RESULT
Definition: smf_save.c:467
smf_event_t * smf_event_new_from_bytes(int first_byte, int second_byte, int third_byte)
Definition: smf.c:290
smf_event_t * smf_event_new_from_pointer(const void *midi_data, size_t len)
Definition: smf.c:251
void smf_delete(smf_t *smf)
Definition: smf.c:88
const char * smf_get_version(void)
Definition: smf.c:1120
smf_track_t * smf_track_new(void)
Definition: smf.c:110
size_t time_pulses
Definition: smf.h:312
static smf_event_t * smf_peek_next_event_from_track(smf_track_t *track)
Definition: smf.c:736
int number_of_tracks
Definition: smf.h:242
smf_event_t * smf_event_new(void)
Definition: smf.c:225
size_t number_of_events
Definition: smf.h:280
double last_seek_position
Definition: smf.h:253
void remove_last_tempo_with_pulses(smf_t *smf, size_t pulses)
Definition: smf_tempo.c:173
int smf_seek_to_seconds(smf_t *smf, double seconds)
Definition: smf.c:975
int smf_event_is_last(const smf_event_t *event)
Definition: smf.c:1108
int is_status_byte(const unsigned char status)
Definition: smf_load.c:248
smf_event_t * smf_track_get_next_event(smf_track_t *track)
Definition: smf.c:698
smf_track_t * smf_find_track_with_next_event(smf_t *smf)
Definition: smf.c:816
smf_track_t * smf_get_track_by_number(const smf_t *smf, int track_number)
Definition: smf.c:757
double time_seconds
Definition: smf.h:315
void smf_track_add_event_delta_pulses(smf_track_t *track, smf_event_t *event, uint32_t delta)
Definition: smf_tempo.c:400
int smf_track_add_eot_delta_pulses(smf_track_t *track, uint32_t delta)
Definition: smf.c:531
void smf_event_remove_from_track(smf_event_t *event)
Definition: smf.c:588
smf_event_t * smf_track_get_last_event(const smf_track_t *track)
Definition: smf.c:798
void smf_fini_tempo(smf_t *smf)
Definition: smf_tempo.c:339
void smf_track_add_event_seconds(smf_track_t *track, smf_event_t *event, double seconds)
Definition: smf_tempo.c:434
void smf_track_delete(smf_track_t *track)
Definition: smf.c:131
int smf_track_add_eot_seconds(smf_track_t *track, double seconds)
Definition: smf.c:565
int track_number
Definition: smf.h:318
smf_event_t * smf_peek_next_event(smf_t *smf)
Definition: smf.c:883
smf_t * smf_new(void)
Definition: smf.c:55
int smf_set_format(smf_t *smf, int format)
Definition: smf.c:660
size_t smf_get_length_pulses(const smf_t *smf)
Definition: smf.c:1051
size_t next_event_number
Definition: smf.h:290
uint8_t * midi_buffer
Definition: smf.h:321
smf_track_t * track
Definition: smf.h:302
smf_t * smf
Definition: smfsh.c:51
smf_event_t * smf_get_next_event(smf_t *smf)
Definition: smf.c:845
size_t time_of_next_event
Definition: smf.h:293
void smf_skip_next_event(smf_t *smf)
Definition: smf.c:872