43 #ifdef PLATFORM_WINDOWS
46 #include <arpa/inet.h>
65 g_critical(
"SMF warning: no more chunks left.");
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.");
85 g_critical(
"SMF error: malformed chunk; truncated file?");
97 if (!memcmp(chunk->
id, signature, 4))
120 g_critical(
"SMF error: file is too short, it cannot be a MIDI file.");
128 g_critical(
"SMF error: MThd signature not found, is that a MIDI file?");
138 assert(mthd == tmp_mthd);
140 len = ntohl(mthd->
length);
142 g_critical(
"SMF error: MThd chunk length %d, must be 6.", len);
156 signed char first_byte_of_division, second_byte_of_division;
169 g_critical(
"SMF error: bad MThd format field value: %d, valid values are 0-2, inclusive.", smf->
format);
174 g_critical(
"SMF file uses format #2, no support for that yet.");
185 first_byte_of_division = *((
signed char *)&(mthd->
division));
186 second_byte_of_division = *((
signed char *)&(mthd->
division) + 1);
188 if (first_byte_of_division >= 0) {
198 if (smf->
ppqn == 0) {
199 g_critical(
"SMF file uses FPS timing instead of PPQN, no support for that yet.");
213 smf_extract_vlq(
const unsigned char *buf,
const size_t buffer_length, uint32_t *value, uint32_t *len)
216 const unsigned char *c = buf;
219 if (c >= buf + buffer_length) {
220 g_critical(
"End of buffer in extract_vlq().");
224 val = (val << 7) + (*c & 0x7F);
237 g_critical(
"SMF error: Variable Length Quantities longer than four bytes are not supported yet.");
250 return (status & 0x80);
279 expected_sysex_length(
const unsigned char status,
const unsigned char *second_byte,
const size_t buffer_length, int32_t *consumed_bytes)
281 uint32_t sysex_length = 0;
287 assert(status == 0xF0);
290 if (buffer_length < 3) {
291 g_critical(
"SMF error: end of buffer in expected_sysex_length().");
297 if (consumed_bytes != NULL)
298 *consumed_bytes = len;
301 return (sysex_length + 1);
305 expected_escaped_length(
const unsigned char status,
const unsigned char *second_byte,
const size_t buffer_length, int32_t *consumed_bytes)
329 if (status == 0xFF) {
330 if (buffer_length < 2) {
331 g_critical(
"SMF error: end of buffer in expected_message_length().");
339 return (*(second_byte + 1) + 3);
342 if ((status & 0xF0) == 0xF0) {
361 g_critical(
"SMF error: unknown 0xFx-type status byte '0x%x'.", status);
382 g_critical(
"SMF error: unknown status byte '0x%x'.", status);
393 int32_t vlq_length, message_length;
394 const unsigned char *c = buf;
399 g_critical(
"Corrupt sysex status byte in extract_sysex_event().");
407 if (message_length < 0)
412 if (vlq_length + (
size_t)message_length >= buffer_length) {
413 g_critical(
"End of buffer in extract_sysex_event().");
417 event->midi_buffer_length = message_length;
420 g_critical(
"Cannot allocate memory in extract_sysex_event(): %s", strerror(errno));
424 event->midi_buffer[0] = status;
425 memcpy(event->
midi_buffer + 1, c, message_length - 1);
427 *len = vlq_length + message_length;
438 int32_t message_length = 0;
439 int32_t vlq_length = 0;
440 const unsigned char *c = buf;
445 g_critical(
"Corrupt escape status byte in extract_escaped_event().");
453 if (message_length < 0)
458 if (vlq_length + (
size_t)message_length >= buffer_length) {
459 g_critical(
"End of buffer in extract_escaped_event().");
463 event->midi_buffer_length = message_length;
466 g_critical(
"Cannot allocate memory in extract_escaped_event(): %s", strerror(errno));
473 g_critical(
"Escaped event is invalid.");
478 g_warning(
"Escaped event is not System Realtime nor System Common.");
481 *len = vlq_length + message_length;
496 int32_t message_length;
497 const unsigned char *c = buf;
499 assert(buffer_length > 0);
508 status = last_status;
512 g_critical(
"SMF error: bad status byte (MSB is zero).");
525 if (message_length < 0)
528 if ((
size_t)message_length > buffer_length - (c - buf) + 1) {
529 g_critical(
"End of buffer in extract_midi_event().");
533 event->midi_buffer_length = message_length;
536 g_critical(
"Cannot allocate memory in extract_midi_event(): %s", strerror(errno));
540 event->midi_buffer[0] = status;
541 memcpy(event->
midi_buffer + 1, c, message_length - 1);
543 *len = c + message_length - 1 - buf;
559 size_t buffer_length;
560 unsigned char *c, *
start;
576 if (buffer_length == 0) {
577 g_warning (
"SMF warning: expected EOT at end of track, but none found");
586 buffer_length -= len;
588 if (buffer_length <= 0)
597 buffer_length -= len;
617 make_string(
const unsigned char *buf,
const size_t buffer_length, uint32_t len)
621 assert(buffer_length > 0);
624 if (len > buffer_length) {
625 g_critical(
"End of buffer in make_string().");
630 str = (
char*)malloc(len + 1);
632 g_critical(
"Cannot allocate memory in make_string().");
636 memcpy(str, buf, len);
670 uint32_t string_length = 0;
671 uint32_t length_length = 0;
677 g_critical(
"smf_event_extract_text: truncated MIDI message.");
683 if (string_length <= 0) {
684 g_critical(
"smf_event_extract_text: truncated MIDI message.");
702 assert(track->
smf != NULL);
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]);
757 if (expected < 0 || event->midi_buffer_length != (
size_t)expected) {
777 g_critical(
"First byte of MIDI message is not a valid status byte.");
828 if (stream == NULL) {
829 g_critical(
"Cannot open input file: %s", strerror(errno));
834 if (fseek(stream, 0, SEEK_END)) {
835 g_critical(
"fseek(3) failed: %s", strerror(errno));
840 offset = ftell(stream);
842 g_critical(
"ftell(3) failed: %s", strerror(errno));
846 *file_buffer_length = (size_t)offset;
848 if (fseek(stream, 0, SEEK_SET)) {
849 g_critical(
"fseek(3) failed: %s", strerror(errno));
854 *file_buffer = malloc(*file_buffer_length);
855 if (*file_buffer == NULL) {
856 g_critical(
"malloc(3) failed: %s", strerror(errno));
861 if (fread(*file_buffer, 1, *file_buffer_length, stream) != *file_buffer_length) {
862 g_critical(
"fread(3) failed: %s", strerror(errno));
904 g_warning(
"SMF warning: Error parsing track, continuing with data loaded so far.");
910 g_warning(
"SMF warning: MThd header declared %d tracks, but only %d found; continuing anyway.",
932 size_t file_buffer_length;
941 memset(file_buffer, 0, file_buffer_length);
void smf_rewind(smf_t *smf)
static int chunk_signature_matches(const struct chunk_header_struct *chunk, const char *signature)
static int extract_midi_event(const unsigned char *buf, const size_t buffer_length, smf_event_t *event, uint32_t *len, int last_status)
static int is_sysex_byte(const unsigned char status)
static int load_file_into_buffer(void **file_buffer, size_t *file_buffer_length, FILE *stream)
static int parse_mtrk_header(smf_track_t *track)
static int extract_sysex_event(const unsigned char *buf, const size_t buffer_length, smf_event_t *event, uint32_t *len, int last_status)
static int32_t expected_message_length(unsigned char status, const unsigned char *second_byte, const size_t buffer_length)
smf_t * smf_load_from_memory(const void *buffer, const size_t buffer_length)
size_t midi_buffer_length
void smf_add_track(smf_t *smf, smf_track_t *track)
LIBPBD_API Transmitter error
int smf_event_is_metadata(const smf_event_t *event) WARN_UNUSED_RESULT
int smf_extract_vlq(const unsigned char *buf, const size_t buffer_length, uint32_t *value, uint32_t *len)
LIBARDOUR_API PBD::PropertyDescriptor< framepos_t > start
void smf_event_delete(smf_event_t *event)
int smf_event_is_system_common(const smf_event_t *event) WARN_UNUSED_RESULT
int expected_number_of_tracks
int smf_event_length_is_valid(const smf_event_t *event)
int smf_event_is_sysex(const smf_event_t *event) WARN_UNUSED_RESULT
smf_track_t * smf_track_new(void)
static int parse_mthd_chunk(smf_t *smf)
smf_event_t * smf_event_new(void)
int smf_event_is_system_realtime(const smf_event_t *event) WARN_UNUSED_RESULT
static struct chunk_header_struct * next_chunk(smf_t *smf)
static int parse_mthd_header(smf_t *smf)
smf_t * smf_load(FILE *file)
static int32_t expected_sysex_length(const unsigned char status, const unsigned char *second_byte, const size_t buffer_length, int32_t *consumed_bytes)
uint16_t number_of_tracks
static int is_escape_byte(const unsigned char status)
int smf_event_is_textual(const smf_event_t *event)
int is_status_byte(const unsigned char status)
size_t file_buffer_length
void smf_track_add_event_delta_pulses(smf_track_t *track, smf_event_t *event, uint32_t delta)
static int32_t expected_escaped_length(const unsigned char status, const unsigned char *second_byte, const size_t buffer_length, int32_t *consumed_bytes)
static int extract_escaped_event(const unsigned char *buf, const size_t buffer_length, smf_event_t *event, uint32_t *len, int last_status)
char * smf_event_extract_text(const smf_event_t *event)
size_t file_buffer_length
static int event_is_end_of_track(const smf_event_t *event)
static char * make_string(const unsigned char *buf, const size_t buffer_length, uint32_t len)
static int parse_mtrk_chunk(smf_track_t *track)
int smf_event_is_valid(const smf_event_t *event)
static smf_event_t * parse_next_event(smf_track_t *track)