From 437cb7c4523584bc3c118bfffc9d6c8a6d42a270 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 18 Feb 2020 20:59:08 -0800 Subject: [PATCH 1/4] Fix aif2pcm Pascal string bug, allow flexibility in marker names for loop --- tools/aif2pcm/main.c | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/tools/aif2pcm/main.c b/tools/aif2pcm/main.c index 51dbf1bb9..f2e2349d0 100644 --- a/tools/aif2pcm/main.c +++ b/tools/aif2pcm/main.c @@ -238,18 +238,17 @@ void read_aif(struct Bytes *aif, AifData *aif_data) char *marker_name = (char *)malloc((marker_name_size + 1) * sizeof(char)); memcpy(marker_name, &aif->data[pos], marker_name_size); marker_name[marker_name_size] = '\0'; - pos += marker_name_size; + pos += marker_name_size + !(marker_name_size & 1); - if (strcmp(marker_name, "START") == 0) + if (i == 0) { aif_data->loop_offset = marker_position; aif_data->has_loop = true; } - else if (strcmp(marker_name, "END") == 0) + else if (i == 1) { - if (!aif_data->has_loop) { + if (marker_position < aif_data->loop_offset) { aif_data->loop_offset = marker_position; - aif_data->has_loop = true; } aif_data->num_samples = marker_position; } From 57af90158dd1e4bd11b4ed040495e52f3ac0d74d Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 18 Feb 2020 22:08:38 -0800 Subject: [PATCH 2/4] Follow defined AIFF loop standard --- tools/aif2pcm/main.c | 97 ++++++++++++++++++++++++++++++++++---------- 1 file changed, 76 insertions(+), 21 deletions(-) diff --git a/tools/aif2pcm/main.c b/tools/aif2pcm/main.c index f2e2349d0..97180dfb5 100644 --- a/tools/aif2pcm/main.c +++ b/tools/aif2pcm/main.c @@ -64,6 +64,12 @@ struct Bytes { uint8_t *data; }; +struct Marker { + uint16_t id; + uint32_t position; + // don't care about the name +}; + struct Bytes *read_bytearray(const char *filename) { struct Bytes *bytes = malloc(sizeof(struct Bytes)); @@ -167,6 +173,8 @@ void read_aif(struct Bytes *aif, AifData *aif_data) FATAL_ERROR("FORM Type is '%s', but it must be AIFF!", chunk_type); } + struct Marker *markers = NULL; + unsigned short num_markers = 0; unsigned long num_sample_frames = 0; // Read all the Chunks to populate the AifData struct. @@ -219,10 +227,17 @@ void read_aif(struct Bytes *aif, AifData *aif_data) } else if (strcmp(chunk_name, "MARK") == 0) { - unsigned short num_markers = (aif->data[pos++] << 8); + num_markers = (aif->data[pos++] << 8); num_markers |= (uint8_t)aif->data[pos++]; - // Read each marker and look for the "START" marker. + if (markers) + { + FATAL_ERROR("More than one MARK Chunk in file!\n"); + } + + markers = calloc(num_markers, sizeof(struct Marker)); + + // Read each marker. for (int i = 0; i < num_markers; i++) { unsigned short marker_id = (aif->data[pos++] << 8); @@ -233,27 +248,16 @@ void read_aif(struct Bytes *aif, AifData *aif_data) marker_position |= (aif->data[pos++] << 8); marker_position |= (uint8_t)aif->data[pos++]; - // Marker id is a pascal-style string. + // Marker name is a Pascal-style string. uint8_t marker_name_size = aif->data[pos++]; - char *marker_name = (char *)malloc((marker_name_size + 1) * sizeof(char)); + // We don't actually need the marker name for anything anymore. + /*char *marker_name = (char *)malloc((marker_name_size + 1) * sizeof(char)); memcpy(marker_name, &aif->data[pos], marker_name_size); - marker_name[marker_name_size] = '\0'; + marker_name[marker_name_size] = '\0';*/ pos += marker_name_size + !(marker_name_size & 1); - if (i == 0) - { - aif_data->loop_offset = marker_position; - aif_data->has_loop = true; - } - else if (i == 1) - { - if (marker_position < aif_data->loop_offset) { - aif_data->loop_offset = marker_position; - } - aif_data->num_samples = marker_position; - } - - free(marker_name); + markers[i].id = marker_id; + markers[i].position = marker_position; } } else if (strcmp(chunk_name, "INST") == 0) @@ -263,11 +267,60 @@ void read_aif(struct Bytes *aif, AifData *aif_data) aif_data->midi_note = midi_note; // Skip over data we don't need. - pos += 19; + pos += 7; + + unsigned short loop_type = (aif->data[pos++] << 8); + loop_type |= (uint8_t)aif->data[pos++]; + + if (loop_type) + { + unsigned short marker_id = (aif->data[pos++] << 8); + marker_id |= (uint8_t)aif->data[pos++]; + + struct Marker *cur_marker = markers; + + // Grab loop start point. + for (int i = 0; i < num_markers; i++, cur_marker++) + { + if (cur_marker->id == marker_id) + { + aif_data->loop_offset = cur_marker->position; + aif_data->has_loop = true; + break; + } + } + + marker_id = (aif->data[pos++] << 8); + marker_id |= (uint8_t)aif->data[pos++]; + + cur_marker = markers; + + // Grab loop end point. + for (int i = 0; i < num_markers; i++, cur_marker++) + { + if (cur_marker->id == marker_id) + { + if (cur_marker->position < aif_data->loop_offset) { + aif_data->loop_offset = cur_marker->position; + aif_data->has_loop = true; + } + aif_data->num_samples = cur_marker->position; + break; + } + } + } + else + { + // Skip NoLooping sustain loop. + pos += 6; + } + + // Skip release loop, we don't need it. + pos += 6; } else if (strcmp(chunk_name, "SSND") == 0) { - // SKip offset and blockSize + // Skip offset and blockSize pos += 8; unsigned long num_samples = chunk_size - 8; @@ -284,6 +337,8 @@ void read_aif(struct Bytes *aif, AifData *aif_data) pos += chunk_size; } } + + free(markers); } // This is a table of deltas between sample values in compressed PCM data. From 059e5467f7395c125ec6dcc808b368a5a51feac9 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 18 Feb 2020 22:11:04 -0800 Subject: [PATCH 3/4] Add safety check --- tools/aif2pcm/main.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tools/aif2pcm/main.c b/tools/aif2pcm/main.c index 97180dfb5..714c71343 100644 --- a/tools/aif2pcm/main.c +++ b/tools/aif2pcm/main.c @@ -274,6 +274,11 @@ void read_aif(struct Bytes *aif, AifData *aif_data) if (loop_type) { + if (!markers) + { + FATAL_ERROR("INST chunk loop without MARK chunk in file!\n"); + } + unsigned short marker_id = (aif->data[pos++] << 8); marker_id |= (uint8_t)aif->data[pos++]; From 4dd4c4d077191d7d287ce94a37c19368b5880eb0 Mon Sep 17 00:00:00 2001 From: Diegoisawesome Date: Tue, 18 Feb 2020 22:32:27 -0800 Subject: [PATCH 4/4] Allow INST chunk loops without MARK chunk --- tools/aif2pcm/main.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/tools/aif2pcm/main.c b/tools/aif2pcm/main.c index 714c71343..7cc361d65 100644 --- a/tools/aif2pcm/main.c +++ b/tools/aif2pcm/main.c @@ -272,13 +272,8 @@ void read_aif(struct Bytes *aif, AifData *aif_data) unsigned short loop_type = (aif->data[pos++] << 8); loop_type |= (uint8_t)aif->data[pos++]; - if (loop_type) + if (loop_type && markers) { - if (!markers) - { - FATAL_ERROR("INST chunk loop without MARK chunk in file!\n"); - } - unsigned short marker_id = (aif->data[pos++] << 8); marker_id |= (uint8_t)aif->data[pos++]; @@ -317,7 +312,7 @@ void read_aif(struct Bytes *aif, AifData *aif_data) else { // Skip NoLooping sustain loop. - pos += 6; + pos += 4; } // Skip release loop, we don't need it.