summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPikalaxALT <PikalaxALT@users.noreply.github.com>2020-02-19 12:48:47 -0500
committerGitHub <noreply@github.com>2020-02-19 12:48:47 -0500
commit6cf22f72d6c00406db59a7516c9708dccd820558 (patch)
tree3e34e7cb057844ced5b381b8c1abc187f18df2be
parent98c6c32bfaeeb0a048d23aa8b177e9343475fb35 (diff)
parent0f7e6403d682567fd92d66e6025a9c0c907a3e61 (diff)
Merge pull request #774 from Diegoisawesome/aif2pcm
Fix aif2pcm Pascal string bug and follow AIFF loop point standard
-rw-r--r--tools/aif2pcm/main.c116
1 files changed, 87 insertions, 29 deletions
diff --git a/tools/aif2pcm/main.c b/tools/aif2pcm/main.c
index fbb024a1d..cd5ac4a50 100644
--- a/tools/aif2pcm/main.c
+++ b/tools/aif2pcm/main.c
@@ -34,8 +34,8 @@ double ieee754_read_extended (uint8_t*);
#define FATAL_ERROR(format, ...) \
do \
{ \
- fprintf(stderr, format, __VA_ARGS__); \
- exit(1); \
+ fprintf(stderr, format, __VA_ARGS__); \
+ exit(1); \
} while (0)
#else
@@ -43,8 +43,8 @@ do \
#define FATAL_ERROR(format, ...) \
do \
{ \
- fprintf(stderr, format, ##__VA_ARGS__); \
- exit(1); \
+ fprintf(stderr, format, ##__VA_ARGS__); \
+ exit(1); \
} while (0)
#endif // _MSC_VER
@@ -64,6 +64,12 @@ struct Bytes {
uint8_t *data;
};
+struct Marker {
+ unsigned short id;
+ unsigned long 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, loop_start = 0, loop_end = 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,28 +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';
- pos += marker_name_size;
-
- if (strcmp(marker_name, "START") == 0)
- {
- aif_data->loop_offset = marker_position;
- aif_data->has_loop = true;
- }
- else if (strcmp(marker_name, "END") == 0)
- {
- if (!aif_data->has_loop) {
- aif_data->loop_offset = marker_position;
- aif_data->has_loop = true;
- }
- aif_data->num_samples = marker_position;
- }
+ marker_name[marker_name_size] = '\0';*/
+ pos += marker_name_size + !(marker_name_size & 1);
- free(marker_name);
+ markers[i].id = marker_id;
+ markers[i].position = marker_position;
}
}
else if (strcmp(chunk_name, "INST") == 0)
@@ -264,11 +267,31 @@ 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)
+ {
+ loop_start = (aif->data[pos++] << 8);
+ loop_start |= (uint8_t)aif->data[pos++];
+
+ loop_end = (aif->data[pos++] << 8);
+ loop_end |= (uint8_t)aif->data[pos++];
+ }
+ else
+ {
+ // Skip NoLooping sustain loop.
+ pos += 4;
+ }
+
+ // 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;
@@ -285,6 +308,41 @@ void read_aif(struct Bytes *aif, AifData *aif_data)
pos += chunk_size;
}
}
+
+ if (markers)
+ {
+ // Resolve loop points.
+ struct Marker *cur_marker = markers;
+
+ // Grab loop start point.
+ for (int i = 0; i < num_markers; i++, cur_marker++)
+ {
+ if (cur_marker->id == loop_start)
+ {
+ aif_data->loop_offset = cur_marker->position;
+ aif_data->has_loop = true;
+ break;
+ }
+ }
+
+ cur_marker = markers;
+
+ // Grab loop end point.
+ for (int i = 0; i < num_markers; i++, cur_marker++)
+ {
+ if (cur_marker->id == loop_end)
+ {
+ 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;
+ }
+ }
+
+ free(markers);
+ }
}
// This is a table of deltas between sample values in compressed PCM data.
@@ -469,12 +527,12 @@ do { \
void aif2pcm(const char *aif_filename, const char *pcm_filename, bool compress)
{
struct Bytes *aif = read_bytearray(aif_filename);
- AifData aif_data = {0};
+ AifData aif_data = {0,0,0,0,0,0,0};
read_aif(aif, &aif_data);
int header_size = 0x10;
struct Bytes *pcm;
- struct Bytes output = {0};
+ struct Bytes output = {0,0};
if (compress)
{