diff --git a/neotools/autoextract.c b/neotools/autoextract.c index f8a104a..190b2d2 100644 --- a/neotools/autoextract.c +++ b/neotools/autoextract.c @@ -1,4 +1,5 @@ #include +#include #include "neoadpcmextract.h" @@ -12,6 +13,7 @@ int main(int argc, char** argv) if (!file) return 1; + // Error on VGZ's for now. if (fgetc(file) == 0x1F && fgetc(file) == 0x8B) { printf("I'm a little gzip short and stout\n"); @@ -20,7 +22,42 @@ int main(int argc, char** argv) fseek(file, 0, SEEK_SET); - int err = vgmExtractSamples(file); + Buffer smpbuf = {NULL, 0, 0}; + char name[32]; + int smpaCount = 0, smpbCount = 0; + + // Find ADCPM samples. + int scanType; + while ((scanType = vgmScanSample(file))) + { + if (scanType != 'A' && scanType != 'B') + continue; + fprintf(stderr, "ADPCM-%c data found at 0x%08lX\n", scanType, ftell(file)); + + if (vgmReadSample(file, &smpbuf) || smpbuf.size == 0) + continue; + if (scanType == 'A') + { + // decode + snprintf(name, sizeof(name), "smpa_%02x.pcm", smpaCount++); + printf("./adpcm \"%s\" \"$WAVDIR/%s.wav\"\n", name, name); + } + else + { + // decode + snprintf(name, sizeof(name), "smpb_%02x.pcm", smpbCount++); + printf("./adpcmb -d \"%s\" \"$WAVDIR/%s.wav\"\n", name, name); + } + + // Write adpcm sample. + FILE* fout = fopen(name, "wb"); + if (!fout) + continue; + fwrite(smpbuf.data, sizeof(uint8_t), smpbuf.size, fout); + fclose(fout); + } + + free(smpbuf.data); fclose(file); - return err; + return 0; } diff --git a/neotools/neoadpcmextract.c b/neotools/neoadpcmextract.c index 77a4750..67fb669 100644 --- a/neotools/neoadpcmextract.c +++ b/neotools/neoadpcmextract.c @@ -1,5 +1,5 @@ -/* neoadpcmextract.cpp - Copyright (C) 2017, 2019 Nicholas Curtis +/* neoadpcmextract.c + Copyright (C) 2017, 2019, 2020 Nicholas Curtis This software is provided 'as-is', without any express or implied warranty. In no event will the authors be held liable for any damages @@ -18,14 +18,11 @@ 3. This notice may not be removed or altered from any source distribution. */ -#include +#include "neoadpcmextract.h" #include -#include -typedef struct { uint8_t* data; size_t size; } Buffer; - -int DecodeSample(FILE* fin, const char* name, Buffer* buf) +int vgmReadSample(FILE* fin, Buffer* buf) { // Get sample data length. uint32_t sampLen = 0; @@ -35,10 +32,11 @@ int DecodeSample(FILE* fin, const char* name, Buffer* buf) sampLen -= sizeof(uint64_t); // Resize buffer if needed. - if (!buf->data || buf->size < sampLen) + buf->size = sampLen; + if (!buf->data || buf->reserved < sampLen) { free(buf->data); - buf->size = sampLen; + buf->reserved = sampLen; buf->data = malloc(sampLen); if (!buf->data) return 1; @@ -51,25 +49,17 @@ int DecodeSample(FILE* fin, const char* name, Buffer* buf) // Read adpcm data. fread(buf->data, sizeof(uint8_t), sampLen, fin); - // Write adpcm sample. - FILE* fout = fopen(name, "wb"); - if (!fout) - return 1; - fwrite(buf->data, sizeof(uint8_t), sampLen, fout); - fclose(fout); - return 0; } -int vgmExtractSamples(FILE* file) +int vgmScanSample(FILE* file) { - Buffer smpBytes = {NULL, 0}; - char namebuf[32]; - int smpaCount = 0, smpbCount = 0; - // Scan for pcm headers. - while (!feof(file) && !ferror(file)) + while (1) { + if (feof(file) || ferror(file)) + return 0; + // Patterns to match (in hex): // 67 66 82 - ADPCM-A // 67 66 83 - ADPCM-B @@ -78,21 +68,8 @@ int vgmExtractSamples(FILE* file) uint8_t byte = fgetc(file); if (byte == 0x82) - { - printf("ADPCM-A data found at 0x%08lX\n", ftell(file)); - snprintf(namebuf, sizeof(namebuf), "smpa_%x.pcm", smpaCount++); - if (DecodeSample(file, namebuf, &smpBytes)) - break; - } + return 'A'; else if (byte == 0x83) - { - printf("ADPCM-B data found at 0x%08lX\n", ftell(file)); - snprintf(namebuf, sizeof(namebuf), "smpb_%x.pcm", smpbCount++); - if (DecodeSample(file, namebuf, &smpBytes)) - break; - } + return 'B'; } - - free(smpBytes.data); - return 0; } diff --git a/neotools/neoadpcmextract.h b/neotools/neoadpcmextract.h index b55222f..5695435 100644 --- a/neotools/neoadpcmextract.h +++ b/neotools/neoadpcmextract.h @@ -2,7 +2,11 @@ #define __NEOADPCMEXTRACT_H__ #include +#include -int vgmExtractSamples(FILE* file); +typedef struct { uint8_t* data; size_t size, reserved; } Buffer; + +int vgmReadSample(FILE* fin, Buffer* buf); +int vgmScanSample(FILE* file); #endif//__NEOADPCMEXTRACT_H__