diff --git a/tools/aif2pcm/Makefile b/tools/aif2pcm/Makefile index af7d19fe90..dd48a87597 100644 --- a/tools/aif2pcm/Makefile +++ b/tools/aif2pcm/Makefile @@ -1,4 +1,4 @@ -CC = gcc +CC ?= gcc CFLAGS = -Wall -Wextra -Wno-switch -Werror -std=c11 -O2 @@ -6,12 +6,18 @@ LIBS = -lm SRCS = main.c extended.c +ifeq ($(OS),Windows_NT) +EXE := .exe +else +EXE := +endif + .PHONY: all clean -all: aif2pcm +all: aif2pcm$(EXE) @: -aif2pcm: $(SRCS) +aif2pcm$(EXE): $(SRCS) $(CC) $(CFLAGS) $(SRCS) -o $@ $(LDFLAGS) $(LIBS) clean: diff --git a/tools/aif2pcm/main.c b/tools/aif2pcm/main.c index cd5ac4a505..0824b92da8 100644 --- a/tools/aif2pcm/main.c +++ b/tools/aif2pcm/main.c @@ -51,8 +51,12 @@ do \ typedef struct { unsigned long num_samples; - uint8_t *samples; + union { + uint8_t *samples8; + uint16_t *samples16; + }; uint8_t midi_note; + uint8_t sample_size; bool has_loop; unsigned long loop_offset; double sample_rate; @@ -208,11 +212,11 @@ void read_aif(struct Bytes *aif, AifData *aif_data) num_sample_frames |= (aif->data[pos++] << 8); num_sample_frames |= (uint8_t)aif->data[pos++]; - short sample_size = (aif->data[pos++] << 8); - sample_size |= (uint8_t)aif->data[pos++]; - if (sample_size != 8) + aif_data->sample_size = (aif->data[pos++] << 8); + aif_data->sample_size |= (uint8_t)aif->data[pos++]; + if (aif_data->sample_size != 8 && aif_data->sample_size != 16) { - FATAL_ERROR("sampleSize (%d) in the COMM Chunk must be 8!\n", sample_size); + FATAL_ERROR("sampleSize (%d) in the COMM Chunk must be 8 or 16!\n", aif_data->sample_size); } double sample_rate = ieee754_read_extended((uint8_t*)(aif->data + pos)); @@ -234,7 +238,7 @@ void read_aif(struct Bytes *aif, AifData *aif_data) { FATAL_ERROR("More than one MARK Chunk in file!\n"); } - + markers = calloc(num_markers, sizeof(struct Marker)); // Read each marker. @@ -285,7 +289,7 @@ void read_aif(struct Bytes *aif, AifData *aif_data) // Skip NoLooping sustain loop. pos += 4; } - + // Skip release loop, we don't need it. pos += 6; } @@ -295,11 +299,28 @@ void read_aif(struct Bytes *aif, AifData *aif_data) pos += 8; unsigned long num_samples = chunk_size - 8; - uint8_t *sample_data = (uint8_t *)malloc(num_samples * sizeof(uint8_t)); - memcpy(sample_data, &aif->data[pos], num_samples); + if (aif_data->sample_size == 8) + { + uint8_t *sample_data = (uint8_t *)malloc(num_samples * sizeof(uint8_t)); + memcpy(sample_data, &aif->data[pos], num_samples); + + aif_data->samples8 = sample_data; + aif_data->real_num_samples = num_samples; + } + else + { + uint16_t *sample_data = (uint16_t *)malloc(num_samples * sizeof(uint16_t)); + uint16_t *sample_data_swapped = (uint16_t *)malloc(num_samples * sizeof(uint16_t)); + memcpy(sample_data, &aif->data[pos], num_samples); + for (long unsigned i = 0; i < num_samples; i++) + { + sample_data_swapped[i] = __builtin_bswap16(sample_data[i]); + } - aif_data->samples = sample_data; - aif_data->real_num_samples = num_samples; + aif_data->samples16 = sample_data_swapped; + aif_data->real_num_samples = num_samples; + free(sample_data); + } pos += chunk_size - 8; } else @@ -308,12 +329,12 @@ 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++) { @@ -351,6 +372,12 @@ const int gDeltaEncodingTable[] = { -64, -49, -36, -25, -16, -9, -4, -1, }; +#define POSITIVE_DELTAS_START 0 +#define POSITIVE_DELTAS_END 8 + +#define NEGATIVE_DELTAS_START 8 +#define NEGATIVE_DELTAS_END 16 + struct Bytes *delta_decompress(struct Bytes *delta, unsigned int expected_length) { struct Bytes *pcm = malloc(sizeof(struct Bytes)); @@ -418,15 +445,32 @@ struct Bytes *delta_decompress(struct Bytes *delta, unsigned int expected_length return pcm; } +#define U8_TO_S8(value) ((value) < 128 ? (value) : (value) - 256) +#define ABS(value) ((value) >= 0 ? (value) : -(value)) + int get_delta_index(uint8_t sample, uint8_t prev_sample) { int best_error = INT_MAX; int best_index = -1; + int delta_table_start_index; + int delta_table_end_index; + int sample_signed = U8_TO_S8(sample); + int prev_sample_signed = U8_TO_S8(prev_sample); + + // if we're going up (or equal), only choose positive deltas + if (prev_sample_signed <= sample_signed) { + delta_table_start_index = POSITIVE_DELTAS_START; + delta_table_end_index = POSITIVE_DELTAS_END; + } else { + delta_table_start_index = NEGATIVE_DELTAS_START; + delta_table_end_index = NEGATIVE_DELTAS_END; + } - for (int i = 0; i < 16; i++) + for (int i = delta_table_start_index; i < delta_table_end_index; i++) { uint8_t new_sample = prev_sample + gDeltaEncodingTable[i]; - int error = sample > new_sample ? sample - new_sample : new_sample - sample; + int new_sample_signed = U8_TO_S8(new_sample); + int error = ABS(new_sample_signed - sample_signed); if (error < best_error) { @@ -527,9 +571,22 @@ do { \ void aif2pcm(const char *aif_filename, const char *pcm_filename, bool compress) { struct Bytes *aif = read_bytearray(aif_filename); - AifData aif_data = {0,0,0,0,0,0,0}; + AifData aif_data = {0}; read_aif(aif, &aif_data); + // Convert 16-bit to 8-bit if necessary + if (aif_data.sample_size == 16) + { + aif_data.real_num_samples /= 2; + uint8_t *converted_samples = malloc(aif_data.real_num_samples * sizeof(uint8_t)); + for (unsigned long i = 0; i < aif_data.real_num_samples; i++) + { + converted_samples[i] = aif_data.samples16[i] >> 8; + } + free(aif_data.samples16); + aif_data.samples8 = converted_samples; + } + int header_size = 0x10; struct Bytes *pcm; struct Bytes output = {0,0}; @@ -537,7 +594,7 @@ void aif2pcm(const char *aif_filename, const char *pcm_filename, bool compress) if (compress) { struct Bytes *input = malloc(sizeof(struct Bytes)); - input->data = aif_data.samples; + input->data = aif_data.samples8; input->length = aif_data.real_num_samples; pcm = delta_compress(input); free(input); @@ -545,7 +602,7 @@ void aif2pcm(const char *aif_filename, const char *pcm_filename, bool compress) else { pcm = malloc(sizeof(struct Bytes)); - pcm->data = aif_data.samples; + pcm->data = aif_data.samples8; pcm->length = aif_data.real_num_samples; } output.length = header_size + pcm->length; @@ -568,7 +625,7 @@ void aif2pcm(const char *aif_filename, const char *pcm_filename, bool compress) free(aif); free(pcm); free(output.data); - free(aif_data.samples); + free(aif_data.samples8); } // Reads a .pcm file containing an array of 8-bit samples and produces an .aif file. @@ -608,8 +665,8 @@ void pcm2aif(const char *pcm_filename, const char *aif_filename, uint32_t base_n pcm->data += 0x10; } - aif_data->samples = malloc(pcm->length); - memcpy(aif_data->samples, pcm->data, pcm->length); + aif_data->samples8 = malloc(pcm->length); + memcpy(aif_data->samples8, pcm->data, pcm->length); struct Bytes *aif = malloc(sizeof(struct Bytes)); aif->length = 54 + 60 + pcm->length; @@ -796,14 +853,14 @@ void pcm2aif(const char *pcm_filename, const char *aif_filename, uint32_t base_n // Sound Data Chunk soundData for (unsigned int i = 0; i < aif_data->loop_offset; i++) { - aif->data[pos++] = aif_data->samples[i]; + aif->data[pos++] = aif_data->samples8[i]; } int j = 0; for (unsigned int i = aif_data->loop_offset; i < pcm->length; i++) { int pcm_index = aif_data->loop_offset + (j++ % (pcm->length - aif_data->loop_offset)); - aif->data[pos++] = aif_data->samples[pcm_index]; + aif->data[pos++] = aif_data->samples8[pcm_index]; } aif->length = pos; diff --git a/tools/bin2c/Makefile b/tools/bin2c/Makefile index ab11e1b61a..4dbfab94fe 100644 --- a/tools/bin2c/Makefile +++ b/tools/bin2c/Makefile @@ -1,4 +1,4 @@ -CC = gcc +CC ?= gcc CFLAGS = -Wall -Wextra -Werror -std=c11 -O2 @@ -6,10 +6,16 @@ CFLAGS = -Wall -Wextra -Werror -std=c11 -O2 SRCS = bin2c.c -all: bin2c +ifeq ($(OS),Windows_NT) +EXE := .exe +else +EXE := +endif + +all: bin2c$(EXE) @: -bin2c: $(SRCS) +bin2c$(EXE): $(SRCS) $(CC) $(CFLAGS) $(SRCS) -o $@ $(LDFLAGS) clean: diff --git a/tools/gbafix/Makefile b/tools/gbafix/Makefile index 5b410da08f..efb016c97e 100644 --- a/tools/gbafix/Makefile +++ b/tools/gbafix/Makefile @@ -1,12 +1,18 @@ -CC = gcc +CC ?= gcc .PHONY: all clean SRCS = gbafix.c -all: gbafix +ifeq ($(OS),Windows_NT) +EXE := .exe +else +EXE := +endif + +all: gbafix$(EXE) @: -gbafix: $(SRCS) +gbafix$(EXE): $(SRCS) $(CC) $(SRCS) -o $@ $(LDFLAGS) clean: diff --git a/tools/mid2agb/Makefile b/tools/mid2agb/Makefile index 77f96db5af..553b7859ed 100644 --- a/tools/mid2agb/Makefile +++ b/tools/mid2agb/Makefile @@ -1,4 +1,4 @@ -CXX := g++ +CXX ?= g++ CXXFLAGS := -std=c++11 -O2 -Wall -Wno-switch -Werror @@ -6,12 +6,18 @@ SRCS := agb.cpp error.cpp main.cpp midi.cpp tables.cpp HEADERS := agb.h error.h main.h midi.h tables.h +ifeq ($(OS),Windows_NT) +EXE := .exe +else +EXE := +endif + .PHONY: all clean -all: mid2agb +all: mid2agb$(EXE) @: -mid2agb: $(SRCS) $(HEADERS) +mid2agb$(EXE): $(SRCS) $(HEADERS) $(CXX) $(CXXFLAGS) $(SRCS) -o $@ $(LDFLAGS) clean: diff --git a/tools/ramscrgen/Makefile b/tools/ramscrgen/Makefile index 858db1a778..a9375c87ab 100644 --- a/tools/ramscrgen/Makefile +++ b/tools/ramscrgen/Makefile @@ -1,4 +1,4 @@ -CXX := g++ +CXX ?= g++ CXXFLAGS := -std=c++11 -O2 -Wall -Wno-switch -Werror @@ -8,10 +8,16 @@ HEADERS := ramscrgen.h sym_file.h elf.h char_util.h .PHONY: all clean -all: ramscrgen +ifeq ($(OS),Windows_NT) +EXE := .exe +else +EXE := +endif + +all: ramscrgen$(EXE) @: -ramscrgen: $(SRCS) $(HEADERS) +ramscrgen$(EXE): $(SRCS) $(HEADERS) $(CXX) $(CXXFLAGS) $(SRCS) -o $@ $(LDFLAGS) clean: diff --git a/tools/rsfont/Makefile b/tools/rsfont/Makefile index 55b2e8ab2f..92e44b5459 100644 --- a/tools/rsfont/Makefile +++ b/tools/rsfont/Makefile @@ -1,4 +1,4 @@ -CC = gcc +CC ?= gcc CFLAGS = -Wall -Wextra -Werror -std=c11 -O2 -DPNG_SKIP_SETJMP_CHECK CFLAGS += $(shell pkg-config --cflags libpng) @@ -10,10 +10,16 @@ SRCS = main.c convert_png.c util.c font.c .PHONY: all clean -all: rsfont +ifeq ($(OS),Windows_NT) +EXE := .exe +else +EXE := +endif + +all: rsfont$(EXE) @: -rsfont: $(SRCS) convert_png.h gfx.h global.h util.h font.h +rsfont$(EXE): $(SRCS) convert_png.h gfx.h global.h util.h font.h $(CC) $(CFLAGS) $(SRCS) -o $@ $(LDFLAGS) $(LIBS) clean: