ardour
smf_load.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 #include <ctype.h>
43 #ifdef PLATFORM_WINDOWS
44 #include <winsock2.h>
45 #else
46 #include <arpa/inet.h>
47 #endif
48 #include "smf.h"
49 #include "smf_private.h"
50 
55 static struct chunk_header_struct *
57 {
58  struct chunk_header_struct *chunk;
59  void *next_chunk_ptr;
60 
61  assert(smf->file_buffer != NULL);
62  assert(smf->file_buffer_length > 0);
63 
64  if (smf->next_chunk_offset + sizeof(struct chunk_header_struct) >= smf->file_buffer_length) {
65  g_critical("SMF warning: no more chunks left.");
66  return (NULL);
67  }
68 
69  next_chunk_ptr = (unsigned char *)smf->file_buffer + smf->next_chunk_offset;
70 
71  chunk = (struct chunk_header_struct *)next_chunk_ptr;
72 
73  if (!isalpha(chunk->id[0]) || !isalpha(chunk->id[1]) || !isalpha(chunk->id[2]) || !isalpha(chunk->id[3])) {
74  g_critical("SMF error: chunk signature contains at least one non-alphanumeric byte.");
75  return (NULL);
76  }
77 
78  /*
79  * XXX: On SPARC, after compiling with "-fast" option there will be SIGBUS here.
80  * Please compile with -xmemalign=8i".
81  */
82  smf->next_chunk_offset += sizeof(struct chunk_header_struct) + ntohl(chunk->length);
83 
84  if (smf->next_chunk_offset > smf->file_buffer_length) {
85  g_critical("SMF error: malformed chunk; truncated file?");
86  }
87 
88  return (chunk);
89 }
90 
94 static int
95 chunk_signature_matches(const struct chunk_header_struct *chunk, const char *signature)
96 {
97  if (!memcmp(chunk->id, signature, 4))
98  return (1);
99 
100  return (0);
101 }
102 
106 static int
108 {
109  int len;
110  struct chunk_header_struct *mthd, *tmp_mthd;
111 
112  /* Make sure compiler didn't do anything stupid. */
113  assert(sizeof(struct chunk_header_struct) == 8);
114 
115  /*
116  * We could just do "mthd = smf->file_buffer;" here, but this way we wouldn't
117  * get useful error messages.
118  */
119  if (smf->file_buffer_length < 6) {
120  g_critical("SMF error: file is too short, it cannot be a MIDI file.");
121 
122  return (-1);
123  }
124 
125  tmp_mthd = (struct chunk_header_struct*)smf->file_buffer;
126 
127  if (!chunk_signature_matches(tmp_mthd, "MThd")) {
128  g_critical("SMF error: MThd signature not found, is that a MIDI file?");
129 
130  return (-2);
131  }
132 
133  /* Ok, now use next_chunk(). */
134  mthd = next_chunk(smf);
135  if (mthd == NULL)
136  return (-3);
137 
138  assert(mthd == tmp_mthd);
139 
140  len = ntohl(mthd->length);
141  if (len != 6) {
142  g_critical("SMF error: MThd chunk length %d, must be 6.", len);
143 
144  return (-4);
145  }
146 
147  return (0);
148 }
149 
153 static int
155 {
156  signed char first_byte_of_division, second_byte_of_division;
157 
158  struct mthd_chunk_struct *mthd;
159 
160  assert(sizeof(struct mthd_chunk_struct) == 14);
161 
162  if (parse_mthd_header(smf))
163  return (1);
164 
165  mthd = (struct mthd_chunk_struct *)smf->file_buffer;
166 
167  smf->format = ntohs(mthd->format);
168  if (smf->format < 0 || smf->format > 2) {
169  g_critical("SMF error: bad MThd format field value: %d, valid values are 0-2, inclusive.", smf->format);
170  return (-1);
171  }
172 
173  if (smf->format == 2) {
174  g_critical("SMF file uses format #2, no support for that yet.");
175  return (-2);
176  }
177 
178  smf->expected_number_of_tracks = ntohs(mthd->number_of_tracks);
179  if (smf->expected_number_of_tracks <= 0) {
180  g_critical("SMF error: bad number of tracks: %d, must be greater than zero.", smf->expected_number_of_tracks);
181  return (-3);
182  }
183 
184  /* XXX: endianess? */
185  first_byte_of_division = *((signed char *)&(mthd->division));
186  second_byte_of_division = *((signed char *)&(mthd->division) + 1);
187 
188  if (first_byte_of_division >= 0) {
189  smf->ppqn = ntohs(mthd->division);
190  smf->frames_per_second = 0;
191  smf->resolution = 0;
192  } else {
193  smf->ppqn = 0;
194  smf->frames_per_second = - first_byte_of_division;
195  smf->resolution = second_byte_of_division;
196  }
197 
198  if (smf->ppqn == 0) {
199  g_critical("SMF file uses FPS timing instead of PPQN, no support for that yet.");
200  return (-4);
201  }
202 
203  return (0);
204 }
205 
212 int
213 smf_extract_vlq(const unsigned char *buf, const size_t buffer_length, uint32_t *value, uint32_t *len)
214 {
215  uint32_t val = 0;
216  const unsigned char *c = buf;
217 
218  for (;;) {
219  if (c >= buf + buffer_length) {
220  g_critical("End of buffer in extract_vlq().");
221  return (-1);
222  }
223 
224  val = (val << 7) + (*c & 0x7F);
225 
226  if (*c & 0x80)
227  c++;
228  else
229  break;
230  };
231 
232  assert(c >= buf);
233  *value = val;
234  *len = c - buf + 1;
235 
236  if (*len > 4) {
237  g_critical("SMF error: Variable Length Quantities longer than four bytes are not supported yet.");
238  return (-2);
239  }
240 
241  return (0);
242 }
243 
247 int
248 is_status_byte(const unsigned char status)
249 {
250  return (status & 0x80);
251 }
252 
253 static int
254 is_sysex_byte(const unsigned char status)
255 {
256  if (status == 0xF0)
257  return (1);
258 
259  return (0);
260 }
261 
262 static int
263 is_escape_byte(const unsigned char status)
264 {
265  if (status == 0xF7)
266  return (1);
267 
268  return (0);
269 }
270 
278 static int32_t
279 expected_sysex_length(const unsigned char status, const unsigned char *second_byte, const size_t buffer_length, int32_t *consumed_bytes)
280 {
281  uint32_t sysex_length = 0;
282  uint32_t len = 0;
283 
284 #ifndef NDEBUG
285  (void) status;
286 #else
287  assert(status == 0xF0);
288 #endif
289 
290  if (buffer_length < 3) {
291  g_critical("SMF error: end of buffer in expected_sysex_length().");
292  return (-1);
293  }
294 
295  smf_extract_vlq(second_byte, buffer_length, &sysex_length, &len);
296 
297  if (consumed_bytes != NULL)
298  *consumed_bytes = len;
299 
300  /* +1, because the length does not include status byte. */
301  return (sysex_length + 1);
302 }
303 
304 static int32_t
305 expected_escaped_length(const unsigned char status, const unsigned char *second_byte, const size_t buffer_length, int32_t *consumed_bytes)
306 {
307  /* -1, because we do not want to account for 0x7F status. */
308  return (expected_sysex_length(status, second_byte, buffer_length, consumed_bytes) - 1);
309 }
310 
316 static int32_t
317 expected_message_length(unsigned char status, const unsigned char *second_byte, const size_t buffer_length)
318 {
319  /* Make sure this really is a valid status byte. */
320  assert(is_status_byte(status));
321 
322  /* We cannot use this routine for sysexes. */
323  assert(!is_sysex_byte(status));
324 
325  /* We cannot use this routine for escaped events. */
326  assert(!is_escape_byte(status));
327 
328  /* Is this a metamessage? */
329  if (status == 0xFF) {
330  if (buffer_length < 2) {
331  g_critical("SMF error: end of buffer in expected_message_length().");
332  return (-1);
333  }
334 
335  /*
336  * Format of this kind of messages is like this: 0xFF 0xwhatever 0xlength and then "length" bytes.
337  * Second byte points to this: ^^^^^^^^^^
338  */
339  return (*(second_byte + 1) + 3);
340  }
341 
342  if ((status & 0xF0) == 0xF0) {
343  switch (status) {
344  case 0xF2: /* Song Position Pointer. */
345  return (3);
346 
347  case 0xF1: /* MTC Quarter Frame. */
348  case 0xF3: /* Song Select. */
349  return (2);
350 
351  case 0xF6: /* Tune Request. */
352  case 0xF8: /* MIDI Clock. */
353  case 0xF9: /* Tick. */
354  case 0xFA: /* MIDI Start. */
355  case 0xFB: /* MIDI Continue. */
356  case 0xFC: /* MIDI Stop. */
357  case 0xFE: /* Active Sense. */
358  return (1);
359 
360  default:
361  g_critical("SMF error: unknown 0xFx-type status byte '0x%x'.", status);
362  return (-2);
363  }
364  }
365 
366  /* Filter out the channel. */
367  status &= 0xF0;
368 
369  switch (status) {
370  case 0x80: /* Note Off. */
371  case 0x90: /* Note On. */
372  case 0xA0: /* AfterTouch. */
373  case 0xB0: /* Control Change. */
374  case 0xE0: /* Pitch Wheel. */
375  return (3);
376 
377  case 0xC0: /* Program Change. */
378  case 0xD0: /* Channel Pressure. */
379  return (2);
380 
381  default:
382  g_critical("SMF error: unknown status byte '0x%x'.", status);
383  return (-3);
384  }
385 }
386 
387 static int
388 extract_sysex_event(const unsigned char *buf, const size_t buffer_length, smf_event_t *event, uint32_t *len, int last_status)
389 {
390  (void) last_status;
391 
392  int status;
393  int32_t vlq_length, message_length;
394  const unsigned char *c = buf;
395 
396  status = *buf;
397 
398  if (!(is_sysex_byte(status))) {
399  g_critical("Corrupt sysex status byte in extract_sysex_event().");
400  return (-6);
401  }
402 
403  c++;
404 
405  message_length = expected_sysex_length(status, c, buffer_length - 1, &vlq_length);
406 
407  if (message_length < 0)
408  return (-3);
409 
410  c += vlq_length;
411 
412  if (vlq_length + (size_t)message_length >= buffer_length) {
413  g_critical("End of buffer in extract_sysex_event().");
414  return (-5);
415  }
416 
417  event->midi_buffer_length = message_length;
418  event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length);
419  if (event->midi_buffer == NULL) {
420  g_critical("Cannot allocate memory in extract_sysex_event(): %s", strerror(errno));
421  return (-4);
422  }
423 
424  event->midi_buffer[0] = status;
425  memcpy(event->midi_buffer + 1, c, message_length - 1);
426 
427  *len = vlq_length + message_length;
428 
429  return (0);
430 }
431 
432 static int
433 extract_escaped_event(const unsigned char *buf, const size_t buffer_length, smf_event_t *event, uint32_t *len, int last_status)
434 {
435  (void) last_status;
436 
437  int status;
438  int32_t message_length = 0;
439  int32_t vlq_length = 0;
440  const unsigned char *c = buf;
441 
442  status = *buf;
443 
444  if (!(is_escape_byte(status))) {
445  g_critical("Corrupt escape status byte in extract_escaped_event().");
446  return (-6);
447  }
448 
449  c++;
450 
451  message_length = expected_escaped_length(status, c, buffer_length - 1, &vlq_length);
452 
453  if (message_length < 0)
454  return (-3);
455 
456  c += vlq_length;
457 
458  if (vlq_length + (size_t)message_length >= buffer_length) {
459  g_critical("End of buffer in extract_escaped_event().");
460  return (-5);
461  }
462 
463  event->midi_buffer_length = message_length;
464  event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length);
465  if (event->midi_buffer == NULL) {
466  g_critical("Cannot allocate memory in extract_escaped_event(): %s", strerror(errno));
467  return (-4);
468  }
469 
470  memcpy(event->midi_buffer, c, message_length);
471 
472  if (smf_event_is_valid(event)) {
473  g_critical("Escaped event is invalid.");
474  return (-1);
475  }
476 
478  g_warning("Escaped event is not System Realtime nor System Common.");
479  }
480 
481  *len = vlq_length + message_length;
482 
483  return (0);
484 }
485 
486 
492 static int
493 extract_midi_event(const unsigned char *buf, const size_t buffer_length, smf_event_t *event, uint32_t *len, int last_status)
494 {
495  int status;
496  int32_t message_length;
497  const unsigned char *c = buf;
498 
499  assert(buffer_length > 0);
500 
501  /* Is the first byte the status byte? */
502  if (is_status_byte(*c)) {
503  status = *c;
504  c++;
505 
506  } else {
507  /* No, we use running status then. */
508  status = last_status;
509  }
510 
511  if (!is_status_byte(status)) {
512  g_critical("SMF error: bad status byte (MSB is zero).");
513  return (-1);
514  }
515 
516  if (is_sysex_byte(status))
517  return (extract_sysex_event(buf, buffer_length, event, len, last_status));
518 
519  if (is_escape_byte(status))
520  return (extract_escaped_event(buf, buffer_length, event, len, last_status));
521 
522  /* At this point, "c" points to first byte following the status byte. */
523  message_length = expected_message_length(status, c, buffer_length - (c - buf));
524 
525  if (message_length < 0)
526  return (-3);
527 
528  if ((size_t)message_length > buffer_length - (c - buf) + 1) {
529  g_critical("End of buffer in extract_midi_event().");
530  return (-5);
531  }
532 
533  event->midi_buffer_length = message_length;
534  event->midi_buffer = (uint8_t*)malloc(event->midi_buffer_length);
535  if (event->midi_buffer == NULL) {
536  g_critical("Cannot allocate memory in extract_midi_event(): %s", strerror(errno));
537  return (-4);
538  }
539 
540  event->midi_buffer[0] = status;
541  memcpy(event->midi_buffer + 1, c, message_length - 1);
542 
543  *len = c + message_length - 1 - buf;
544 
545  return (0);
546 }
547 
554 static smf_event_t *
556 {
557  uint32_t etime = 0;
558  uint32_t len;
559  size_t buffer_length;
560  unsigned char *c, *start;
561 
562  smf_event_t *event = smf_event_new();
563  if (event == NULL)
564  goto error;
565 
566  c = start = (unsigned char *)track->file_buffer + track->next_event_offset;
567 
568  assert(track->file_buffer != NULL);
569  assert(track->file_buffer_length > 0);
570  assert(track->next_event_offset > 0);
571 
572  buffer_length = track->file_buffer_length - track->next_event_offset;
573  /* if there was no meta-EOT event, buffer_length can be zero. This is
574  an error in the SMF file, but it shouldn't be treated as fatal.
575  */
576  if (buffer_length == 0) {
577  g_warning ("SMF warning: expected EOT at end of track, but none found");
578  goto error;
579  }
580  /* First, extract time offset from previous event. */
581  if (smf_extract_vlq(c, buffer_length, &etime, &len)) {
582  goto error;
583  }
584 
585  c += len;
586  buffer_length -= len;
587 
588  if (buffer_length <= 0)
589  goto error;
590 
591  /* Now, extract the actual event. */
592  if (extract_midi_event(c, buffer_length, event, &len, track->last_status)) {
593  goto error;
594  }
595 
596  c += len;
597  buffer_length -= len;
598  track->last_status = event->midi_buffer[0];
599  track->next_event_offset += c - start;
600 
601  smf_track_add_event_delta_pulses(track, event, etime);
602 
603  return (event);
604 
605 error:
606  if (event != NULL)
607  smf_event_delete(event);
608 
609  return (NULL);
610 }
611 
616 static char *
617 make_string(const unsigned char *buf, const size_t buffer_length, uint32_t len)
618 {
619  char *str;
620 
621  assert(buffer_length > 0);
622  assert(len > 0);
623 
624  if (len > buffer_length) {
625  g_critical("End of buffer in make_string().");
626 
627  len = buffer_length;
628  }
629 
630  str = (char*)malloc(len + 1);
631  if (str == NULL) {
632  g_critical("Cannot allocate memory in make_string().");
633  return (NULL);
634  }
635 
636  memcpy(str, buf, len);
637  str[len] = '\0';
638 
639  return (str);
640 }
641 
647 int
649 {
650  if (!smf_event_is_metadata(event))
651  return (0);
652 
653  if (event->midi_buffer_length < 4)
654  return (0);
655 
656  if (event->midi_buffer[3] < 1 || event->midi_buffer[3] > 9)
657  return (0);
658 
659  return (1);
660 }
661 
667 char *
669 {
670  uint32_t string_length = 0;
671  uint32_t length_length = 0;
672 
673  if (!smf_event_is_textual(event))
674  return (NULL);
675 
676  if (event->midi_buffer_length < 3) {
677  g_critical("smf_event_extract_text: truncated MIDI message.");
678  return (NULL);
679  }
680 
681  smf_extract_vlq((const unsigned char*)(void *)&(event->midi_buffer[2]), event->midi_buffer_length - 2, &string_length, &length_length);
682 
683  if (string_length <= 0) {
684  g_critical("smf_event_extract_text: truncated MIDI message.");
685  return (NULL);
686  }
687 
688  return (make_string((const unsigned char*)(void *)(&event->midi_buffer[2] + length_length), event->midi_buffer_length - 2 - length_length, string_length));
689 }
690 
695 static int
697 {
698  struct chunk_header_struct *mtrk;
699 
700  /* Make sure compiler didn't do anything stupid. */
701  assert(sizeof(struct chunk_header_struct) == 8);
702  assert(track->smf != NULL);
703 
704  mtrk = next_chunk(track->smf);
705 
706  if (mtrk == NULL)
707  return (-1);
708 
709  if (!chunk_signature_matches(mtrk, "MTrk")) {
710  g_warning("SMF warning: Expected MTrk signature, got %c%c%c%c instead; ignoring this chunk.",
711  mtrk->id[0], mtrk->id[1], mtrk->id[2], mtrk->id[3]);
712 
713  return (-2);
714  }
715 
716  track->file_buffer = mtrk;
717  track->file_buffer_length = sizeof(struct chunk_header_struct) + ntohl(mtrk->length);
718  track->next_event_offset = sizeof(struct chunk_header_struct);
719 
720  return (0);
721 }
722 
726 static int
728 {
729  if (event->midi_buffer[0] == 0xFF && event->midi_buffer[1] == 0x2F)
730  return (1);
731 
732  return (0);
733 }
734 
739 int
741 {
742  assert(event);
743  assert(event->midi_buffer);
744 
745  int32_t expected;
746 
747  if (event->midi_buffer_length < 1)
748  return (0);
749 
750  /* We cannot use expected_message_length on sysexes. */
751  if (smf_event_is_sysex(event))
752  return (1);
753 
754 
755  expected = expected_message_length(event->midi_buffer[0],
756  &(event->midi_buffer[1]), event->midi_buffer_length - 1);
757  if (expected < 0 || event->midi_buffer_length != (size_t)expected) {
758  return (0);
759  }
760 
761  return (1);
762 }
763 
768 /* XXX: this routine requires some more work to detect more errors. */
769 int
771 {
772  assert(event);
773  assert(event->midi_buffer);
774  assert(event->midi_buffer_length >= 1);
775 
776  if (!is_status_byte(event->midi_buffer[0])) {
777  g_critical("First byte of MIDI message is not a valid status byte.");
778 
779  return (0);
780  }
781 
782  if (!smf_event_length_is_valid(event))
783  return (0);
784 
785  return (1);
786 }
787 
791 static int
793 {
794  smf_event_t *event;
795  int ret = 0;
796 
797  if (parse_mtrk_header(track))
798  return (-1);
799 
800  for (;;) {
801  event = parse_next_event(track);
802 
803  /* Couldn't parse an event? */
804  if (event == NULL || !smf_event_is_valid(event)) {
805  ret = -1;
806  break;
807  }
808 
809  if (event_is_end_of_track(event))
810  break;
811  }
812 
813  track->file_buffer = NULL;
814  track->file_buffer_length = 0;
815  track->next_event_offset = -1;
816 
817  return (ret);
818 }
819 
823 static int
824 load_file_into_buffer(void **file_buffer, size_t *file_buffer_length, FILE* stream)
825 {
826  long offset;
827 
828  if (stream == NULL) {
829  g_critical("Cannot open input file: %s", strerror(errno));
830 
831  return (-1);
832  }
833 
834  if (fseek(stream, 0, SEEK_END)) {
835  g_critical("fseek(3) failed: %s", strerror(errno));
836 
837  return (-2);
838  }
839 
840  offset = ftell(stream);
841  if (offset < 0) {
842  g_critical("ftell(3) failed: %s", strerror(errno));
843 
844  return (-3);
845  }
846  *file_buffer_length = (size_t)offset;
847 
848  if (fseek(stream, 0, SEEK_SET)) {
849  g_critical("fseek(3) failed: %s", strerror(errno));
850 
851  return (-4);
852  }
853 
854  *file_buffer = malloc(*file_buffer_length);
855  if (*file_buffer == NULL) {
856  g_critical("malloc(3) failed: %s", strerror(errno));
857 
858  return (-5);
859  }
860 
861  if (fread(*file_buffer, 1, *file_buffer_length, stream) != *file_buffer_length) {
862  g_critical("fread(3) failed: %s", strerror(errno));
863  free (*file_buffer);
864  *file_buffer = NULL;
865  return (-6);
866  }
867 
868  return (0);
869 }
870 
875 smf_t *
876 smf_load_from_memory(const void *buffer, const size_t buffer_length)
877 {
878  int i;
879  int ret;
880 
881  smf_t *smf = smf_new();
882 
883  smf->file_buffer = (void *)buffer;
884  smf->file_buffer_length = buffer_length;
885  smf->next_chunk_offset = 0;
886 
887  if (parse_mthd_chunk(smf))
888  return (NULL);
889 
890  for (i = 1; i <= smf->expected_number_of_tracks; i++) {
891  smf_track_t *track = smf_track_new();
892  if (track == NULL)
893  return (NULL);
894 
895  smf_add_track(smf, track);
896 
897  ret = parse_mtrk_chunk(track);
898 
899  track->file_buffer = NULL;
900  track->file_buffer_length = 0;
901  track->next_event_offset = -1;
902 
903  if (ret) {
904  g_warning("SMF warning: Error parsing track, continuing with data loaded so far.");
905  break;
906  }
907  }
908 
909  if (smf->expected_number_of_tracks != smf->number_of_tracks) {
910  g_warning("SMF warning: MThd header declared %d tracks, but only %d found; continuing anyway.",
912 
914  }
915 
916  smf->file_buffer = NULL;
917  smf->file_buffer_length = 0;
918  smf->next_chunk_offset = 0;
919 
920  return (smf);
921 }
922 
929 smf_t *
930 smf_load(FILE *file)
931 {
932  size_t file_buffer_length;
933  void *file_buffer;
934  smf_t *smf;
935 
936  if (load_file_into_buffer(&file_buffer, &file_buffer_length, file))
937  return (NULL);
938 
939  smf = smf_load_from_memory(file_buffer, file_buffer_length);
940 
941  memset(file_buffer, 0, file_buffer_length);
942  free(file_buffer);
943 
944  if (smf == NULL)
945  return (NULL);
946 
947  smf_rewind(smf);
948 
949  return (smf);
950 }
951 
void smf_rewind(smf_t *smf)
Definition: smf.c:908
static int chunk_signature_matches(const struct chunk_header_struct *chunk, const char *signature)
Definition: smf_load.c:95
static int extract_midi_event(const unsigned char *buf, const size_t buffer_length, smf_event_t *event, uint32_t *len, int last_status)
Definition: smf_load.c:493
static int is_sysex_byte(const unsigned char status)
Definition: smf_load.c:254
static int load_file_into_buffer(void **file_buffer, size_t *file_buffer_length, FILE *stream)
Definition: smf_load.c:824
int last_status
Definition: smf.h:285
int format
Definition: smf.h:235
void * file_buffer
Definition: smf.h:246
static int parse_mtrk_header(smf_track_t *track)
Definition: smf_load.c:696
static int extract_sysex_event(const unsigned char *buf, const size_t buffer_length, smf_event_t *event, uint32_t *len, int last_status)
Definition: smf_load.c:388
static int32_t expected_message_length(unsigned char status, const unsigned char *second_byte, const size_t buffer_length)
Definition: smf_load.c:317
smf_t * smf_load_from_memory(const void *buffer, const size_t buffer_length)
Definition: smf_load.c:876
size_t midi_buffer_length
Definition: smf.h:324
void smf_add_track(smf_t *smf, smf_track_t *track)
Definition: smf.c:156
LIBPBD_API Transmitter error
int smf_event_is_metadata(const smf_event_t *event) WARN_UNUSED_RESULT
Definition: smf_decode.c:57
int smf_extract_vlq(const unsigned char *buf, const size_t buffer_length, uint32_t *value, uint32_t *len)
Definition: smf_load.c:213
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
Definition: region.cc:63
void smf_event_delete(smf_event_t *event)
Definition: smf.c:371
size_t next_chunk_offset
Definition: smf.h:248
int smf_event_is_system_common(const smf_event_t *event) WARN_UNUSED_RESULT
Definition: smf_decode.c:90
smf_t * smf
Definition: smf.h:277
uint16_t ppqn
Definition: smf.h:239
int expected_number_of_tracks
Definition: smf.h:249
int smf_event_length_is_valid(const smf_event_t *event)
Definition: smf_load.c:740
int smf_event_is_sysex(const smf_event_t *event) WARN_UNUSED_RESULT
Definition: smf_decode.c:104
smf_track_t * smf_track_new(void)
Definition: smf.c:110
static int parse_mthd_chunk(smf_t *smf)
Definition: smf_load.c:154
size_t next_event_offset
Definition: smf.h:289
int frames_per_second
Definition: smf.h:240
int number_of_tracks
Definition: smf.h:242
smf_event_t * smf_event_new(void)
Definition: smf.c:225
int smf_event_is_system_realtime(const smf_event_t *event) WARN_UNUSED_RESULT
Definition: smf_decode.c:72
static struct chunk_header_struct * next_chunk(smf_t *smf)
Definition: smf_load.c:56
static int parse_mthd_header(smf_t *smf)
Definition: smf_load.c:107
smf_t * smf_load(FILE *file)
Definition: smf_load.c:930
static int32_t expected_sysex_length(const unsigned char status, const unsigned char *second_byte, const size_t buffer_length, int32_t *consumed_bytes)
Definition: smf_load.c:279
uint16_t number_of_tracks
Definition: smf_private.h:61
static int is_escape_byte(const unsigned char status)
Definition: smf_load.c:263
int resolution
Definition: smf.h:241
int smf_event_is_textual(const smf_event_t *event)
Definition: smf_load.c:648
int is_status_byte(const unsigned char status)
Definition: smf_load.c:248
size_t file_buffer_length
Definition: smf.h:247
void smf_track_add_event_delta_pulses(smf_track_t *track, smf_event_t *event, uint32_t delta)
Definition: smf_tempo.c:400
static int32_t expected_escaped_length(const unsigned char status, const unsigned char *second_byte, const size_t buffer_length, int32_t *consumed_bytes)
Definition: smf_load.c:305
static int extract_escaped_event(const unsigned char *buf, const size_t buffer_length, smf_event_t *event, uint32_t *len, int last_status)
Definition: smf_load.c:433
void * file_buffer
Definition: smf.h:283
uint16_t division
Definition: smf_private.h:62
char * smf_event_extract_text(const smf_event_t *event)
Definition: smf_load.c:668
size_t file_buffer_length
Definition: smf.h:284
static int event_is_end_of_track(const smf_event_t *event)
Definition: smf_load.c:727
smf_t * smf_new(void)
Definition: smf.c:55
uint8_t * midi_buffer
Definition: smf.h:321
static char * make_string(const unsigned char *buf, const size_t buffer_length, uint32_t len)
Definition: smf_load.c:617
static int parse_mtrk_chunk(smf_track_t *track)
Definition: smf_load.c:792
int smf_event_is_valid(const smf_event_t *event)
Definition: smf_load.c:770
static smf_event_t * parse_next_event(smf_track_t *track)
Definition: smf_load.c:555
smf_t * smf
Definition: smfsh.c:51