* Explanation of Variable Length Quantities is here: http://www.borg.com/~jglatt/tech/midifile/vari.htm
* Returns 0 iff everything went OK, different value in case of error.
*/
-static int
-extract_vlq(const unsigned char *buf, const size_t buffer_length, uint32_t *value, uint32_t *len)
+int
+smf_extract_vlq(const unsigned char *buf, const size_t buffer_length, uint32_t *value, uint32_t *len)
{
uint32_t val = 0;
const unsigned char *c = buf;
static int32_t
expected_sysex_length(const unsigned char status, const unsigned char *second_byte, const size_t buffer_length, int32_t *consumed_bytes)
{
- uint32_t sysex_length, len;
+ uint32_t sysex_length = 0;
+ uint32_t len = 0;
+#ifndef NDEBUG
+ (void) status;
+#else
assert(status == 0xF0);
+#endif
if (buffer_length < 3) {
g_critical("SMF error: end of buffer in expected_sysex_length().");
return (-1);
}
- extract_vlq(second_byte, buffer_length, &sysex_length, &len);
+ smf_extract_vlq(second_byte, buffer_length, &sysex_length, &len);
if (consumed_bytes != NULL)
*consumed_bytes = len;
(void) last_status;
int status;
- int32_t message_length, vlq_length;
+ int32_t message_length = 0;
+ int32_t vlq_length = 0;
const unsigned char *c = buf;
status = *buf;
static smf_event_t *
parse_next_event(smf_track_t *track)
{
- uint32_t time = 0;
+ uint32_t etime = 0;
uint32_t len;
size_t buffer_length;
unsigned char *c, *start;
assert(buffer_length > 0);
/* First, extract time offset from previous event. */
- if (extract_vlq(c, buffer_length, &time, &len))
+ if (smf_extract_vlq(c, buffer_length, &etime, &len))
goto error;
c += len;
track->last_status = event->midi_buffer[0];
track->next_event_offset += c - start;
- smf_track_add_event_delta_pulses(track, event, time);
+ smf_track_add_event_delta_pulses(track, event, etime);
return (event);
if (event->midi_buffer_length < 4)
return (0);
- if (event->midi_buffer[3] < 1 && event->midi_buffer[3] > 9)
+ if (event->midi_buffer[3] < 1 || event->midi_buffer[3] > 9)
return (0);
return (1);
char *
smf_event_extract_text(const smf_event_t *event)
{
- uint32_t string_length, length_length;
+ uint32_t string_length = 0;
+ uint32_t length_length = 0;
if (!smf_event_is_textual(event))
return (NULL);
return (NULL);
}
- extract_vlq((void *)&(event->midi_buffer[2]), event->midi_buffer_length - 2, &string_length, &length_length);
+ smf_extract_vlq((void *)&(event->midi_buffer[2]), event->midi_buffer_length - 2, &string_length, &length_length);
if (string_length <= 0) {
g_critical("smf_event_extract_text: truncated MIDI message.");
}
/**
- * Allocate buffer of proper size and read file contents into it. Close file afterwards.
+ * Allocate buffer of proper size and read file contents into it.
*/
static int
-load_file_into_buffer(void **file_buffer, size_t *file_buffer_length, const char *file_name)
+load_file_into_buffer(void **file_buffer, size_t *file_buffer_length, FILE* stream)
{
- FILE *stream = fopen(file_name, "r");
long offset;
if (stream == NULL) {
*file_buffer = malloc(*file_buffer_length);
if (*file_buffer == NULL) {
g_critical("malloc(3) failed: %s", strerror(errno));
-
+
return (-5);
}
if (fread(*file_buffer, 1, *file_buffer_length, stream) != *file_buffer_length) {
g_critical("fread(3) failed: %s", strerror(errno));
-
+ free (*file_buffer);
+ *file_buffer = NULL;
return (-6);
}
- if (fclose(stream)) {
- g_critical("fclose(3) failed: %s", strerror(errno));
-
- return (-7);
- }
-
return (0);
}
if (parse_mtrk_chunk(track)) {
g_warning("SMF warning: Cannot load track.");
smf_track_delete(track);
+ continue;
}
track->file_buffer = NULL;
/**
* Loads SMF file.
*
- * \param file_name Path to the file.
+ * \param file Open file.
* \return SMF or NULL, if loading failed.
*/
smf_t *
-smf_load(const char *file_name)
+smf_load(FILE *file)
{
size_t file_buffer_length;
void *file_buffer;
smf_t *smf;
- if (load_file_into_buffer(&file_buffer, &file_buffer_length, file_name))
+ if (load_file_into_buffer(&file_buffer, &file_buffer_length, file))
return (NULL);
smf = smf_load_from_memory(file_buffer, file_buffer_length);