int smf_event_is_unterminated_sysex(const smf_event_t *event) { assert(event->midi_buffer); assert(event->midi_buffer_length > 0); if (!smf_event_is_sysex(event) && !smf_event_is_sysex_continuation(event)) return 0; return event->midi_buffer[event->midi_buffer_length - 1] != 0xF7; }
static char * smf_event_decode_system_common(const smf_event_t *event) { int off = 0; char *buf; assert(smf_event_is_system_common(event)); if (smf_event_is_sysex(event)) return (smf_event_decode_sysex(event)); buf = (char*)malloc(BUFFER_SIZE); if (buf == NULL) { g_critical("smf_event_decode_system_realtime: malloc failed."); return (NULL); } switch (event->midi_buffer[0]) { case 0xF1: off += snprintf(buf + off, BUFFER_SIZE - off, "MTC Quarter Frame"); break; case 0xF2: off += snprintf(buf + off, BUFFER_SIZE - off, "Song Position Pointer"); break; case 0xF3: off += snprintf(buf + off, BUFFER_SIZE - off, "Song Select"); break; case 0xF6: off += snprintf(buf + off, BUFFER_SIZE - off, "Tune Request"); break; default: free(buf); return (NULL); } assert (off <= BUFFER_SIZE); return (buf); }
/** * \return Nonzero, if event is as long as it should be, from the MIDI specification point of view. * Does not work for SysExes - it doesn't recognize internal structure of SysEx. */ int smf_event_length_is_valid(const smf_event_t *event) { assert(event); assert(event->midi_buffer); int32_t expected; if (event->midi_buffer_length < 1) return (0); /* We cannot use expected_message_length on sysexes. */ if (smf_event_is_sysex(event)) return (1); expected = expected_message_length(event->midi_buffer[0], &(event->midi_buffer[1]), event->midi_buffer_length - 1); if (expected < 0 || event->midi_buffer_length != (size_t)expected) { return (0); } return (1); }
static char * smf_event_decode_sysex(const smf_event_t *event) { int off = 0; char *buf, manufacturer, subid, subid2; assert(smf_event_is_sysex(event)); if (event->midi_buffer_length < 5) { g_critical("smf_event_decode_sysex: truncated MIDI message."); return (NULL); } buf = (char*)malloc(BUFFER_SIZE); if (buf == NULL) { g_critical("smf_event_decode_sysex: malloc failed."); return (NULL); } manufacturer = event->midi_buffer[1]; if (manufacturer == 0x7F) { off += snprintf(buf + off, BUFFER_SIZE - off, "SysEx, realtime, channel %d", event->midi_buffer[2]); } else if (manufacturer == 0x7E) { off += snprintf(buf + off, BUFFER_SIZE - off, "SysEx, non-realtime, channel %d", event->midi_buffer[2]); } else { off += snprintf(buf + off, BUFFER_SIZE - off, "SysEx, manufacturer 0x%x", manufacturer); assert (off <= BUFFER_SIZE); return (buf); } subid = event->midi_buffer[3]; subid2 = event->midi_buffer[4]; if (subid == 0x01) off += snprintf(buf + off, BUFFER_SIZE - off, ", Sample Dump Header"); else if (subid == 0x02) off += snprintf(buf + off, BUFFER_SIZE - off, ", Sample Dump Data Packet"); else if (subid == 0x03) off += snprintf(buf + off, BUFFER_SIZE - off, ", Sample Dump Request"); else if (subid == 0x04 && subid2 == 0x01) off += snprintf(buf + off, BUFFER_SIZE - off, ", Master Volume"); else if (subid == 0x05 && subid2 == 0x01) off += snprintf(buf + off, BUFFER_SIZE - off, ", Sample Dump Loop Point Retransmit"); else if (subid == 0x05 && subid2 == 0x02) off += snprintf(buf + off, BUFFER_SIZE - off, ", Sample Dump Loop Point Request"); else if (subid == 0x06 && subid2 == 0x01) off += snprintf(buf + off, BUFFER_SIZE - off, ", Identity Request"); else if (subid == 0x06 && subid2 == 0x02) off += snprintf(buf + off, BUFFER_SIZE - off, ", Identity Reply"); else if (subid == 0x08 && subid2 == 0x00) off += snprintf(buf + off, BUFFER_SIZE - off, ", Bulk Tuning Dump Request"); else if (subid == 0x08 && subid2 == 0x01) off += snprintf(buf + off, BUFFER_SIZE - off, ", Bulk Tuning Dump"); else if (subid == 0x08 && subid2 == 0x02) off += snprintf(buf + off, BUFFER_SIZE - off, ", Single Note Tuning Change"); else if (subid == 0x08 && subid2 == 0x03) off += snprintf(buf + off, BUFFER_SIZE - off, ", Bulk Tuning Dump Request (Bank)"); else if (subid == 0x08 && subid2 == 0x04) off += snprintf(buf + off, BUFFER_SIZE - off, ", Key Based Tuning Dump"); else if (subid == 0x08 && subid2 == 0x05) off += snprintf(buf + off, BUFFER_SIZE - off, ", Scale/Octave Tuning Dump, 1 byte format"); else if (subid == 0x08 && subid2 == 0x06) off += snprintf(buf + off, BUFFER_SIZE - off, ", Scale/Octave Tuning Dump, 2 byte format"); else if (subid == 0x08 && subid2 == 0x07) off += snprintf(buf + off, BUFFER_SIZE - off, ", Single Note Tuning Change (Bank)"); else if (subid == 0x09) off += snprintf(buf + off, BUFFER_SIZE - off, ", General MIDI %s", subid2 == 0 ? "disable" : "enable"); else if (subid == 0x7C) off += snprintf(buf + off, BUFFER_SIZE - off, ", Sample Dump Wait"); else if (subid == 0x7D) off += snprintf(buf + off, BUFFER_SIZE - off, ", Sample Dump Cancel"); else if (subid == 0x7E) off += snprintf(buf + off, BUFFER_SIZE - off, ", Sample Dump NAK"); else if (subid == 0x7F) off += snprintf(buf + off, BUFFER_SIZE - off, ", Sample Dump ACK"); else off += snprintf(buf + off, BUFFER_SIZE - off, ", Unknown"); assert (off <= BUFFER_SIZE); return (buf); }