diff --git a/dsptools/common.h b/common/endian.h similarity index 93% rename from dsptools/common.h rename to common/endian.h index af034af..b78ff83 100644 --- a/dsptools/common.h +++ b/common/endian.h @@ -1,5 +1,5 @@ -#ifndef COMMON_H -#define COMMON_H +#ifndef COMMON_ENDIAN_H +#define COMMON_ENDIAN_H #ifdef __APPLE__ # include @@ -66,7 +66,4 @@ static inline uint16_t swap16(uint16_t v) # define SWAP_BE16(V) (V) #endif -#define MIN(A, B) (((A) < (B)) ? (A) : (B)) -#define MAX(A, B) (((A) > (B)) ? (A) : (B)) - -#endif//COMMON_H +#endif//COMMON_ENDIAN_H diff --git a/common/util.h b/common/util.h new file mode 100644 index 0000000..8eff871 --- /dev/null +++ b/common/util.h @@ -0,0 +1,16 @@ +#ifndef COMMON_UTIL_H +#define COMMON_UTIL_H + +#define MIN(A, B) (((A) < (B)) ? (A) : (B)) +#define MAX(A, B) (((A) > (B)) ? (A) : (B)) +#define CLAMP(X, A, B) (MIN(MAX((X), (A)), (B))) + +#if ( defined( __GNUC__ ) && ( __GNUC__ >= 4 ) ) || defined( __clang__ ) + #define FORCE_INLINE inline __attribute__((always_inline)) +#elif defined( _MSC_VER ) + #define FORCE_INLINE __forceinline +#else + #define FORCE_INLINE inline +#endif + +#endif//COMMON_UTIL_H diff --git a/dsptools/wave.c b/common/wave.c similarity index 97% rename from dsptools/wave.c rename to common/wave.c index 3403cfa..44986f6 100644 --- a/dsptools/wave.c +++ b/common/wave.c @@ -1,7 +1,7 @@ /* wave.c (c) 2023 a dinosaur (zlib) */ #include "wave.h" -#include "common.h" +#include "endian.h" #define FOURCC_RIFF "RIFF" #define FOURCC_WAVE "WAVE" @@ -116,15 +116,13 @@ static int waveWriteHeader(const WaveSpec* spec, size_t dataLen, const WaveStrea int waveWrite(const WaveSpec* spec, const void* data, size_t dataLen, const WaveStreamCb* cb, void* user) { - if (!data) - return 1; - // Write RIFF/Wave header and raw interleaved samples int res = waveWriteHeader(spec, dataLen, cb, user); if (res) return res; //FIXME: not endian safe - cb->write(user, data, 1, dataLen); + if (data) + cb->write(user, data, 1, dataLen); return 0; } diff --git a/dsptools/wave.h b/common/wave.h similarity index 96% rename from dsptools/wave.h rename to common/wave.h index 0822086..7b39ab2 100644 --- a/dsptools/wave.h +++ b/common/wave.h @@ -34,6 +34,8 @@ typedef struct int (*eof)(void* user); } WaveStreamCb; +extern const WaveStreamCb waveStreamDefaultCb; + int waveWrite(const WaveSpec* spec, const void* data, size_t dataLen, const WaveStreamCb* cb, void* user); int waveWriteFile(const WaveSpec* spec, const void* data, size_t dataLen, const char* path); int waveWriteBlock(const WaveSpec* spec, const void* blocks[], size_t blockLen, const WaveStreamCb* cb, void* user); diff --git a/dsptools/wavefile.c b/common/wavefile.c similarity index 76% rename from dsptools/wavefile.c rename to common/wavefile.c index 750db9a..53328f1 100644 --- a/dsptools/wavefile.c +++ b/common/wavefile.c @@ -32,14 +32,22 @@ static int waveFileEof(void* user) return feof((FILE*)user) || ferror((FILE*)user); } +const WaveStreamCb waveStreamDefaultCb = +{ + .read = waveFileRead, + .write = waveFileWrite, + .seek = waveFileSeek, + .tell = waveFileTell, + .eof = waveFileEof +}; + int waveWriteFile(const WaveSpec* spec, const void* data, size_t dataLen, const char* path) { FILE* file = fopen(path, "wb"); if (!file) return 1; - const WaveStreamCb cb = { .write = waveFileWrite }; - int res = waveWrite(spec, data, dataLen, &cb, (void*)file); + int res = waveWrite(spec, data, dataLen, &waveStreamDefaultCb, (void*)file); fclose(file); return res; } @@ -50,8 +58,7 @@ int waveWriteBlockFile(const WaveSpec* spec, const void* blocks[], size_t blockL if (!file) return 1; - const WaveStreamCb cb = { .write = waveFileWrite }; - int res = waveWriteBlock(spec, blocks, blockLen, &cb, (void*)file); + int res = waveWriteBlock(spec, blocks, blockLen, &waveStreamDefaultCb, (void*)file); fclose(file); return res; } diff --git a/dsptools/CMakeLists.txt b/dsptools/CMakeLists.txt index 9add31a..867a440 100644 --- a/dsptools/CMakeLists.txt +++ b/dsptools/CMakeLists.txt @@ -1,14 +1,17 @@ cmake_minimum_required(VERSION 3.15 FATAL_ERROR) project(dsptools LANGUAGES C) +set(COMMON "${CMAKE_SOURCE_DIR}/../common") + add_subdirectory(libdsptool) -set(HEADERS wave.h) -set(SOURCES wavefile.c wave.c dspdecode.c) +set(HEADERS ${COMMON}/wave.h ${COMMON}/endian.h) +set(SOURCES ${COMMON}/wavefile.c ${COMMON}/wave.c dspdecode.c) add_executable(dspdecode ${HEADERS} ${SOURCES}) set_property(TARGET dspdecode PROPERTY C_STANDARD 99) +target_include_directories(dspdecode PRIVATE ${COMMON}) target_link_libraries(dspdecode DspTool::DspTool) target_compile_options(dspdecode PRIVATE $<$:-Wall -Wextra -pedantic> diff --git a/dsptools/dspdecode.c b/dsptools/dspdecode.c index 50226f7..08b0e61 100644 --- a/dsptools/dspdecode.c +++ b/dsptools/dspdecode.c @@ -2,7 +2,7 @@ #include "dsptool.h" #include "wave.h" -#include "common.h" +#include "endian.h" #include #include #include diff --git a/dsptools/libdsptool/CMakeLists.txt b/dsptools/libdsptool/CMakeLists.txt index 6a75c83..939faeb 100644 --- a/dsptools/libdsptool/CMakeLists.txt +++ b/dsptools/libdsptool/CMakeLists.txt @@ -3,14 +3,16 @@ project(DspTool LANGUAGES C) option(BUILD_SHARED_LIBS "Build as a Shared Object or DLL" OFF) -set(HEADERS ../common.h dsptool.h) +set(HEADERS dsptool.h ${COMMON}/util.h) set(SOURCES math.c decode.c encode.c) add_library(DspTool ${HEADERS} ${SOURCES}) add_library(DspTool::DspTool ALIAS DspTool) -target_include_directories(DspTool PUBLIC ${CMAKE_CURRENT_SOURCE_DIR}) set_property(TARGET DspTool PROPERTY C_STANDARD 99) +target_include_directories(DspTool + PUBLIC ${CMAKE_CURRENT_SOURCE_DIR} + PRIVATE ${COMMON}) if (BUILD_SHARED_LIBS) target_compile_definitions(DspTool PRIVATE BUILD_SHARED) endif() diff --git a/dsptools/libdsptool/decode.c b/dsptools/libdsptool/decode.c index 3742fb9..3232eb1 100644 --- a/dsptools/libdsptool/decode.c +++ b/dsptools/libdsptool/decode.c @@ -1,7 +1,7 @@ /* (c) 2017 Alex Barney (MIT) */ #include -#include "../common.h" +#include "util.h" #include "dsptool.h" static inline uint8_t GetHighNibble(uint8_t value) diff --git a/dsptools/libdsptool/encode.c b/dsptools/libdsptool/encode.c index faf16d2..337a360 100644 --- a/dsptools/libdsptool/encode.c +++ b/dsptools/libdsptool/encode.c @@ -6,7 +6,7 @@ #include #include #include -#include "../common.h" +#include "util.h" #include "dsptool.h" /* Temporal Vector diff --git a/neotools/CMakeLists.txt b/neotools/CMakeLists.txt index 43789f0..fb9d78c 100644 --- a/neotools/CMakeLists.txt +++ b/neotools/CMakeLists.txt @@ -1,18 +1,21 @@ -project(neoadpcmtools) +project(neoadpcmtools LANGUAGES C) cmake_minimum_required(VERSION "3.1" FATAL_ERROR) -add_executable(adpcm adpcm.c) -target_compile_options(adpcm PRIVATE - -fomit-frame-pointer -Werror -Wall - -W -Wno-sign-compare -Wno-unused - -Wpointer-arith -Wbad-function-cast -Wcast-align -Waggregate-return - -pedantic - -Wshadow - -Wstrict-prototypes) -target_link_libraries(adpcm m) +set(COMMON "${CMAKE_SOURCE_DIR}/../common") +set(WARNINGS + $<$:-Wall -Wextra -pedantic -Wno-unused-parameter> + $<$:/Wall /wd4100>) -add_executable(adpcmb adpcmb.c) +add_executable(adpcm ${COMMON}/util.h ${COMMON}/wave.h ${COMMON}/wave.c ${COMMON}/wavefile.c adpcm.c) +set_property(TARGET adpcm PROPERTY C_STANDARD 99) +target_compile_options(adpcm PRIVATE ${WARNINGS}) +target_include_directories(adpcm PRIVATE ${COMMON}) +target_link_libraries(adpcm $<$:m>) + +add_executable(adpcmb ${COMMON}/util.h adpcmb.c) +target_compile_options(adpcmb PRIVATE ${WARNINGS}) +target_include_directories(adpcmb PRIVATE ${COMMON}) add_executable(neoadpcmextract autoextract.c neoadpcmextract.c) set_property(TARGET neoadpcmextract PROPERTY C_STANDARD 99) -target_compile_options(neoadpcmextract PRIVATE -Wall -Wextra -pedantic) +target_compile_options(neoadpcmextract PRIVATE ${WARNINGS}) diff --git a/neotools/adpcm.c b/neotools/adpcm.c index e778de3..d7a8ab5 100644 --- a/neotools/adpcm.c +++ b/neotools/adpcm.c @@ -1,159 +1,165 @@ +/* adpcm.c +* original ADPCM to PCM converter v 1.01 By MARTINEZ Fabrice aka SNK of SUPREMACY +*/ + #include #include #include +#include "util.h" +#include "wave.h" -#define BUFFER_SIZE 1024*256 +#define BUFFER_SIZE (1024 * 256) #define ADPCMA_VOLUME_RATE 1 #define ADPCMA_DECODE_RANGE 1024 -#define ADPCMA_DECODE_MIN (-(ADPCMA_DECODE_RANGE*ADPCMA_VOLUME_RATE)) -#define ADPCMA_DECODE_MAX ((ADPCMA_DECODE_RANGE*ADPCMA_VOLUME_RATE)-1) -#define ADPCMA_VOLUME_DIV 1 +#define ADPCMA_DECODE_MIN (-(ADPCMA_DECODE_RANGE * ADPCMA_VOLUME_RATE)) +#define ADPCMA_DECODE_MAX ((ADPCMA_DECODE_RANGE * ADPCMA_VOLUME_RATE) - 1) -unsigned char RiffWave[44] = { - 0x52, 0x49, 0x46, 0x46, 0x24, 0x00, 0x00, 0x00, 0x57, 0x41, 0x56, 0x45, 0x66, 0x6D, 0x74, - 0x20, 0x10, 0x00, 0x00, 0x00, 0x01, 0x00, 0x01, 0x00, 0x44, 0x48, 0x00, 0x00, 0x88, 0x90, - 0x00, 0x00, 0x02, 0x00, 0x10, 0x00, 0x64, 0x61, 0x74, 0x61, 0x00, 0x00, 0x00, 0x00 - } ; - -static int decode_tableA1[16] = { - -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16, - -1*16, -1*16, -1*16, -1*16, 2*16, 5*16, 7*16, 9*16 +static int decode_tableA1[16] = +{ + -1 * 16, -1 * 16, -1 * 16, -1 * 16, 2 * 16, 5 * 16, 7 * 16, 9 * 16, + -1 * 16, -1 * 16, -1 * 16, -1 * 16, 2 * 16, 5 * 16, 7 * 16, 9 * 16 }; -static int jedi_table[49*16]; -static int signal; -static int delta; -void adpcm_init(void); -void adpcm_decode(void *, void *, int); -int Limit(int, int, int); -FILE* errorlog; +static int jedi_table[49 * 16]; +static int cursignal; +static int delta; + +void adpcm_init(void); +void adpcm_decode(void *, void *, int); + +FILE* errorlog; int main(int argc, char *argv[]) { - FILE *Fp1, *Fp2; - void *InputBuffer, *OutputBuffer; - int Readed; - unsigned int Filelen; - + FILE *InputFile, *OutputFile; + void *InputBuffer, *OutputBuffer; + int bytesRead; + unsigned int Filelen; + puts("**** ADPCM to PCM converter v 1.01\n"); - if (argc!=3) { + if (argc != 3) + { puts("USAGE: adpcm "); exit(-1); } - - Fp1 = fopen(argv[1], "rb"); - if (Fp1==NULL) { + + InputFile = fopen(argv[1], "rb"); + if (!InputFile) + { printf("Could not open inputfile %s\n", argv[1]); exit(-2); } - Fp2 = fopen(argv[2], "wb"); - if (Fp2==NULL) { + OutputFile = fopen(argv[2], "wb"); + if (!OutputFile) + { printf("Could not open outputfile %s\n", argv[2]); exit(-3); } errorlog = fopen("error.log", "wb"); - + InputBuffer = malloc(BUFFER_SIZE); - if (InputBuffer == NULL) { + if (InputBuffer == NULL) + { printf("Could not allocate input buffer. (%d bytes)\n", BUFFER_SIZE); exit(-4); } - - OutputBuffer = malloc(BUFFER_SIZE*10); - if (OutputBuffer == NULL) { - printf("Could not allocate output buffer. (%d bytes)\n", BUFFER_SIZE*4); + + OutputBuffer = malloc(BUFFER_SIZE * 10); + if (OutputBuffer == NULL) + { + printf("Could not allocate output buffer. (%d bytes)\n", BUFFER_SIZE * 4); exit(-5); } adpcm_init(); - fseek(Fp1, 0, SEEK_END); - Filelen = ftell(Fp1); - fseek(Fp1, 0, SEEK_SET); + fseek(InputFile, 0, SEEK_END); + Filelen = ftell(InputFile); + fseek(InputFile, 0, SEEK_SET); - *((unsigned int*)(&RiffWave[4])) = Filelen*4 + 0x2C; - *((unsigned int*)(&RiffWave[0x28])) = Filelen*4; - - fwrite(RiffWave, 0x2c, 1, Fp2); - - do { - Readed = fread(InputBuffer, 1, BUFFER_SIZE, Fp1); - if (Readed>0) { - adpcm_decode(InputBuffer, OutputBuffer, Readed); - fwrite(OutputBuffer, Readed*4, 1, Fp2); + // Write wave header + waveWrite(&(const WaveSpec) + { + .format = WAVE_FMT_PCM, + .channels = 1, + .rate = 18500, + .bytedepth = 2 + }, + NULL, Filelen * 4, &waveStreamDefaultCb, OutputFile); + + // Convert ADPCM to PCM and write to wave + do + { + bytesRead = fread(InputBuffer, 1, BUFFER_SIZE, InputFile); + if (bytesRead > 0) + { + adpcm_decode(InputBuffer, OutputBuffer, bytesRead); + fwrite(OutputBuffer, bytesRead * 4, 1, OutputFile); } - } while (Readed==BUFFER_SIZE); - + } while (bytesRead == BUFFER_SIZE); + free(InputBuffer); free(OutputBuffer); - fclose(Fp1); - fclose(Fp2); - + fclose(InputFile); + fclose(OutputFile); + puts("Done..."); - + return 0; } -void adpcm_init(void) +void adpcm_init(void) { int step, nib; for (step = 0; step <= 48; step++) { - int stepval = floor (16.0 * pow (11.0 / 10.0, (double)step) * ADPCMA_VOLUME_RATE); - /* loop over all nibbles and compute the difference */ + int stepval = floor(16.0 * pow (11.0 / 10.0, (double)step) * ADPCMA_VOLUME_RATE); + // Loop over all nibbles and compute the difference for (nib = 0; nib < 16; nib++) { - int value = stepval*((nib&0x07)*2+1)/8; - jedi_table[step*16+nib] = (nib&0x08) ? -value : value; + int value = stepval * ((nib & 0x07) * 2 + 1) / 8; + jedi_table[step * 16 + nib] = (nib & 0x08) ? -value : value; } } delta = 0; - signal = 0; + cursignal = 0; } -void adpcm_decode(void *InputBuffer, void *OutputBuffer, int Length) +void adpcm_decode(void *InputBuffer, void *OutputBuffer, int Length) { - char *in; - short *out; - int i, data, oldsignal; - + char *in; + short *out; + int i, data, oldsignal; + in = (char *)InputBuffer; out = (short *)OutputBuffer; - - for(i=0;i>4)&0x0F; - oldsignal = signal; - signal = Limit(signal + (jedi_table[data+delta]), ADPCMA_DECODE_MAX, ADPCMA_DECODE_MIN); - delta = Limit(delta + decode_tableA1[data], 48*16, 0*16); - if (abs(oldsignal-signal)>2500) { - fprintf(errorlog, "WARNING: Suspicious signal evolution %06x,%06x pos:%06x delta:%06x\n", oldsignal, signal, i, delta); - fprintf(errorlog, "data:%02x dx:%08x\n", data, jedi_table[data+delta]); - } - *(out++) = (signal&0xffff)*32; - data = (*in++)&0x0F; - oldsignal = signal; - signal = Limit(signal + (jedi_table[data+delta]), ADPCMA_DECODE_MAX, ADPCMA_DECODE_MIN); - delta = Limit(delta + decode_tableA1[data], 48*16, 0*16); - if (abs(oldsignal-signal)>2500) { - fprintf(errorlog, "WARNING: Suspicious signal evolution %06x,%06x pos:%06x delta:%06x\n", oldsignal, signal, i, delta); - fprintf(errorlog, "data:%02x dx:%08x\n", data, jedi_table[data+delta]); + for (i = 0; i < Length; i++) + { + data = ((*in) >> 4) & 0x0F; + oldsignal = cursignal; + cursignal = CLAMP(cursignal + (jedi_table[data + delta]), ADPCMA_DECODE_MIN, ADPCMA_DECODE_MAX); + delta = CLAMP(delta + decode_tableA1[data], 0 * 16, 48 * 16); + if (abs(oldsignal - cursignal) > 2500) + { + fprintf(errorlog, "WARNING: Suspicious signal evolution %06x,%06x pos:%06x delta:%06x\n", oldsignal, cursignal, i, delta); + fprintf(errorlog, "data:%02x dx:%08x\n", data, jedi_table[data + delta]); } - *(out++) = (signal&0xffff)*32; + *(out++) = (cursignal & 0xffff) * 32; + + data = (*in++) & 0x0F; + oldsignal = cursignal; + cursignal = CLAMP(cursignal + (jedi_table[data + delta]), ADPCMA_DECODE_MIN, ADPCMA_DECODE_MAX); + delta = CLAMP(delta + decode_tableA1[data], 0 * 16, 48 * 16); + if (abs(oldsignal - cursignal) > 2500) + { + fprintf(errorlog, "WARNING: Suspicious signal evolution %06x,%06x pos:%06x delta:%06x\n", oldsignal, cursignal, i, delta); + fprintf(errorlog, "data:%02x dx:%08x\n", data, jedi_table[data + delta]); + } + *(out++) = (cursignal & 0xffff) * 32; } } - -int Limit( int val, int max, int min ) { - - if ( val > max ) - val = max; - else if ( val < min ) - val = min; - - return val; -} - diff --git a/neotools/adpcm.txt b/neotools/adpcm.txt deleted file mode 100644 index 9124501..0000000 --- a/neotools/adpcm.txt +++ /dev/null @@ -1,16 +0,0 @@ -**** ADPCM to PCM converter v 1.01 - -USAGE: adpcm - -By MARTINEZ Fabrice aka SNK of SUPREMACY - - - ---(ADPCM.diz.txt)-- - - ADPCM To WAV Converter -This simple utility converts ADPCM files from NeoGeo cartridge systems -(*_v?.rom) or NeoGeo CD systems (*.PCM). This tool converts ADPCM A type -samples (99% of the samples), ADPCM B type samples will sound distorted... -Get it here - diff --git a/neotools/adpcmb.c b/neotools/adpcmb.c index 24f4ac4..ba2002b 100644 --- a/neotools/adpcmb.c +++ b/neotools/adpcmb.c @@ -1,4 +1,4 @@ -/*; YM2610 ADPCM-B Codec +/*; YM2610 ADPCM-B Codec ; ;**** PCM to ADPCM-B & ADPCM-B to PCM converters for NEO-GEO System **** ;ADPCM-B - 1 channel 1.8-55.5 KHz, 16 MB Sample ROM size, 256 B min size of sample, 16 MB max, compatable with YM2608 @@ -15,59 +15,26 @@ #include #include -#include -#include #include - -#if defined(_MSC_VER) -#define INLINE static __inline -#elif defined(__GNUC__) -#define INLINE static __inline__ -#else -#define INLINE static inline -#endif - -#ifdef USE_STDINT - #include -typedef uint8_t UINT8; -typedef int8_t INT8; -typedef uint16_t UINT16; -typedef int16_t INT16; -typedef uint32_t UINT32; -typedef int32_t INT32; - -#else - -typedef unsigned char UINT8; -typedef signed char INT8; -typedef unsigned short UINT16; -typedef signed short INT16; -typedef unsigned int UINT32; -typedef signed int INT32; - -#endif - - -typedef UINT8 BYTE; -typedef UINT16 WORD; -typedef UINT32 DWORD; +#include "util.h" // -- from mmsystem.h -- -#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ - ((DWORD)(BYTE)(ch0) | ((DWORD)(BYTE)(ch1) << 8) | \ - ((DWORD)(BYTE)(ch2) << 16) | ((DWORD)(BYTE)(ch3) << 24 )) +//FIXME: DEELT THIS +#define MAKEFOURCC(ch0, ch1, ch2, ch3) \ + ((uint32_t)(uint8_t)(ch0) | ((uint32_t)(uint8_t)(ch1) << 8) | \ + ((uint32_t)(uint8_t)(ch2) << 16) | ((uint32_t)(uint8_t)(ch3) << 24 )) // -- from mmreg.h, slightly modified -- /* general waveform format structure (information common to all formats) */ typedef struct waveformat_tag { - WORD wFormatTag; /* format type */ - WORD nChannels; /* number of channels (i.e. mono, stereo...) */ - DWORD nSamplesPerSec; /* sample rate */ - DWORD nAvgBytesPerSec; /* for buffer estimation */ - WORD nBlockAlign; /* block size of data */ - WORD wBitsPerSample; + uint16_t wFormatTag; /* format type */ + uint16_t nChannels; /* number of channels (i.e. mono, stereo...) */ + uint32_t nSamplesPerSec; /* sample rate */ + uint32_t nAvgBytesPerSec; /* for buffer estimation */ + uint16_t nBlockAlign; /* block size of data */ + uint16_t wBitsPerSample; } WAVEFORMAT; /* flags for wFormatTag field of WAVEFORMAT */ @@ -75,21 +42,21 @@ typedef struct waveformat_tag { // -- from mm*.h end -- -#define FOURCC_RIFF MAKEFOURCC('R', 'I', 'F', 'F') -#define FOURCC_WAVE MAKEFOURCC('W', 'A', 'V', 'E') -#define FOURCC_fmt_ MAKEFOURCC('f', 'm', 't', ' ') -#define FOURCC_data MAKEFOURCC('d', 'a', 't', 'a') +#define FOURCC_RIFF MAKEFOURCC('R', 'I', 'F', 'F') +#define FOURCC_WAVE MAKEFOURCC('W', 'A', 'V', 'E') +#define FOURCC_fmt_ MAKEFOURCC('f', 'm', 't', ' ') +#define FOURCC_data MAKEFOURCC('d', 'a', 't', 'a') typedef struct { - UINT32 RIFFfcc; // 'RIFF' - UINT32 RIFFLen; - UINT32 WAVEfcc; // 'WAVE' - UINT32 fmt_fcc; // 'fmt ' - UINT32 fmt_Len; + uint32_t RIFFfcc; // 'RIFF' + uint32_t RIFFLen; + uint32_t WAVEfcc; // 'WAVE' + uint32_t fmt_fcc; // 'fmt ' + uint32_t fmt_Len; WAVEFORMAT fmt_Data; - UINT32 datafcc; // 'data' - UINT32 dataLen; + uint32_t datafcc; // 'data' + uint32_t dataLen; } WAVE_FILE; @@ -99,29 +66,29 @@ static const long stepsizeTable[16] = 57, 57, 57, 57, 77, 102, 128, 153 }; -static int YM2610_ADPCM_Encode(INT16 *src, UINT8 *dest, int len) +static int YM2610_ADPCM_Encode(int16_t *src, uint8_t *dest, int len) { int lpc, flag; long i, dn, xn, stepSize; - UINT8 adpcm; - UINT8 adpcmPack; - + uint8_t adpcm; + uint8_t adpcmPack; + xn = 0; stepSize = 127; flag = 0; - + for (lpc = 0; lpc < len; lpc ++) { dn = *src - xn; src ++; - - i = (abs(dn) << 16) / (stepSize << 14); + + i = (labs(dn) << 16) / (stepSize << 14); if (i > 7) i = 7; - adpcm = (UINT8)i; - + adpcm = (uint8_t)i; + i = (adpcm * 2 + 1) * stepSize / 8; - + if (dn < 0) { adpcm |= 0x8; @@ -131,14 +98,14 @@ static int YM2610_ADPCM_Encode(INT16 *src, UINT8 *dest, int len) { xn += i; } - + stepSize = (stepsizeTable[adpcm] * stepSize) / 64; - + if (stepSize < 127) stepSize = 127; else if (stepSize > 24576) stepSize = 24576; - + if (flag == 0) { adpcmPack = (adpcm << 4); @@ -152,76 +119,72 @@ static int YM2610_ADPCM_Encode(INT16 *src, UINT8 *dest, int len) flag = 0; } } - + return 0; } -static int YM2610_ADPCM_Decode(UINT8 *src, INT16 *dest, int len) +static int YM2610_ADPCM_Decode(uint8_t *src, int16_t *dest, int len) { - int lpc, flag, shift, step; + int lpc, shift, step; long i, xn, stepSize; - UINT8 adpcm; - + uint8_t adpcm; + xn = 0; stepSize = 127; - flag = 0; shift = 4; step = 0; - + for (lpc = 0; lpc < len; lpc ++) { adpcm = (*src >> shift) & 0xf; - + i = ((adpcm & 7) * 2 + 1) * stepSize / 8; if (adpcm & 8) xn -= i; else xn += i; - - if (xn > 32767) - xn = 32767; - else if (xn < -32768) - xn = -32768; - + + xn = CLAMP(xn, -32768, 32767); + stepSize = stepSize * stepsizeTable[adpcm] / 64; - + if (stepSize < 127) stepSize = 127; else if (stepSize > 24576) stepSize = 24576; - - *dest = (INT16)xn; + + *dest = (int16_t)xn; dest ++; - + src += step; step = step ^ 1; shift = shift ^ 4; } - + return 0; } -INLINE UINT32 DeltaTReg2SampleRate(UINT16 DeltaN, UINT32 Clock) +static FORCE_INLINE uint32_t DeltaTReg2SampleRate(uint16_t DeltaN, uint32_t Clock) { - return (UINT32)(DeltaN * (Clock / 72.0) / 65536.0 + 0.5); + return (uint32_t)(DeltaN * (Clock / 72.0) / 65536.0 + 0.5); } int main(int argc, char* argv[]) { int ErrVal; int ArgBase; - DWORD OutSmplRate; + uint32_t OutSmplRate; FILE* hFile; unsigned int AdpcmSize; - UINT8* AdpcmData; + uint8_t* AdpcmData; unsigned int WaveSize; - UINT16* WaveData; + uint16_t* WaveData; WAVE_FILE WaveFile; WAVEFORMAT* TempFmt; unsigned int TempLng; - UINT16 DTRegs; + uint16_t DTRegs; char* TempPnt; - + printf("NeoGeo ADPCM-B En-/Decoder\n--------------------------\n"); if (argc < 4) { @@ -237,18 +200,18 @@ int main(int argc, char* argv[]) printf("Wave In-/Output is 16-bit, Mono\n"); return 1; } - + if (strcmp(argv[1], "-d") && strcmp(argv[1], "-e")) { printf("Wrong option! Use -d or -e!\n"); return 1; } - + ErrVal = 0; AdpcmData = NULL; WaveData = NULL; OutSmplRate = 0; - + ArgBase = 2; if (argv[2][0] == '-' && argv[2][2] == ':') { @@ -258,7 +221,7 @@ int main(int argc, char* argv[]) OutSmplRate = strtol(argv[2] + 3, NULL, 0); break; case 'r': - DTRegs = (UINT16)strtoul(argv[2] + 3, &TempPnt, 0); + DTRegs = (uint16_t)strtoul(argv[2] + 3, &TempPnt, 0); TempLng = 0; if (*TempPnt == ',') { @@ -276,7 +239,7 @@ int main(int argc, char* argv[]) return 1; } } - + switch(argv[1][1]) { case 'd': @@ -287,26 +250,26 @@ int main(int argc, char* argv[]) ErrVal = 2; goto Finish; } - + fseek(hFile, 0x00, SEEK_END); AdpcmSize = ftell(hFile); - + fseek(hFile, 0x00, SEEK_SET); - AdpcmData = (UINT8*)malloc(AdpcmSize); + AdpcmData = (uint8_t*)malloc(AdpcmSize); fread(AdpcmData, 0x01, AdpcmSize, hFile); fclose(hFile); - - WaveSize = AdpcmSize * 2; // 4-bit ADPCM -> 2 values per byte - WaveData = (UINT16*)malloc(WaveSize * 2); + + WaveSize = AdpcmSize * 2; // 4-bit ADPCM -> 2 values per byte + WaveData = (uint16_t*)malloc(WaveSize * 2); printf("Decoding ..."); YM2610_ADPCM_Decode(AdpcmData, WaveData, WaveSize); printf(" OK\n"); - + WaveFile.RIFFfcc = FOURCC_RIFF; WaveFile.WAVEfcc = FOURCC_WAVE; WaveFile.fmt_fcc = FOURCC_fmt_; WaveFile.fmt_Len = sizeof(WAVEFORMAT); - + TempFmt = &WaveFile.fmt_Data; TempFmt->wFormatTag = WAVE_FORMAT_PCM; TempFmt->nChannels = 1; @@ -314,11 +277,11 @@ int main(int argc, char* argv[]) TempFmt->nSamplesPerSec = OutSmplRate ? OutSmplRate : 22050; TempFmt->nBlockAlign = TempFmt->nChannels * TempFmt->wBitsPerSample / 8; TempFmt->nAvgBytesPerSec = TempFmt->nBlockAlign * TempFmt->nSamplesPerSec; - + WaveFile.datafcc = FOURCC_data; WaveFile.dataLen = WaveSize * 2; WaveFile.RIFFLen = 0x04 + 0x08 + WaveFile.fmt_Len + 0x08 + WaveFile.dataLen; - + hFile = fopen(argv[ArgBase + 1], "wb"); if (hFile == NULL) { @@ -326,12 +289,12 @@ int main(int argc, char* argv[]) ErrVal = 3; goto Finish; } - + fwrite(&WaveFile, sizeof(WAVE_FILE), 0x01, hFile); fwrite(WaveData, 0x02, WaveSize, hFile); fclose(hFile); printf("File written.\n"); - + break; case 'e': hFile = fopen(argv[ArgBase + 0], "rb"); @@ -341,7 +304,7 @@ int main(int argc, char* argv[]) ErrVal = 2; goto Finish; } - + fread(&WaveFile.RIFFfcc, 0x0C, 0x01, hFile); if (WaveFile.RIFFfcc != FOURCC_RIFF || WaveFile.WAVEfcc != FOURCC_WAVE) { @@ -350,12 +313,12 @@ int main(int argc, char* argv[]) ErrVal = 4; goto Finish; } - + TempLng = fread(&WaveFile.fmt_fcc, 0x04, 0x01, hFile); fread(&WaveFile.fmt_Len, 0x04, 0x01, hFile); while(WaveFile.fmt_fcc != FOURCC_fmt_) { - if (! TempLng) // TempLng == 0 -> EOF reached + if (! TempLng) // TempLng == 0 -> EOF reached { fclose(hFile); printf("Error in wave file: Can't find format-tag!\n"); @@ -363,14 +326,14 @@ int main(int argc, char* argv[]) goto Finish; } fseek(hFile, WaveFile.fmt_Len, SEEK_CUR); - + TempLng = fread(&WaveFile.fmt_fcc, 0x04, 0x01, hFile); fread(&WaveFile.fmt_Len, 0x04, 0x01, hFile); }; TempLng = ftell(hFile) + WaveFile.fmt_Len; fread(&WaveFile.fmt_Data, sizeof(WAVEFORMAT), 0x01, hFile); fseek(hFile, TempLng, SEEK_SET); - + TempFmt = &WaveFile.fmt_Data; if (TempFmt->wFormatTag != WAVE_FORMAT_PCM) { @@ -393,12 +356,12 @@ int main(int argc, char* argv[]) ErrVal = 4; goto Finish; } - + TempLng = fread(&WaveFile.datafcc, 0x04, 0x01, hFile); fread(&WaveFile.dataLen, 0x04, 0x01, hFile); while(WaveFile.datafcc != FOURCC_data) { - if (! TempLng) // TempLng == 0 -> EOF reached + if (! TempLng) // TempLng == 0 -> EOF reached { fclose(hFile); printf("Error in wave file: Can't find data-tag!\n"); @@ -406,22 +369,22 @@ int main(int argc, char* argv[]) goto Finish; } fseek(hFile, WaveFile.dataLen, SEEK_CUR); - + TempLng = fread(&WaveFile.datafcc, 0x04, 0x01, hFile); fread(&WaveFile.dataLen, 0x04, 0x01, hFile); }; WaveSize = WaveFile.dataLen / 2; - WaveData = (UINT16*)malloc(WaveSize * 2); + WaveData = (uint16_t*)malloc(WaveSize * 2); fread(WaveData, 0x02, WaveSize, hFile); - + fclose(hFile); - + AdpcmSize = WaveSize / 2; - AdpcmData = (UINT8*)malloc(AdpcmSize); + AdpcmData = (uint8_t*)malloc(AdpcmSize); printf("Encoding ..."); YM2610_ADPCM_Encode(WaveData, AdpcmData, WaveSize); printf(" OK\n"); - + hFile = fopen(argv[ArgBase + 1], "wb"); if (hFile == NULL) { @@ -429,17 +392,17 @@ int main(int argc, char* argv[]) ErrVal = 3; goto Finish; } - + fwrite(AdpcmData, 0x01, AdpcmSize, hFile); fclose(hFile); printf("File written.\n"); - + break; } - + Finish: free(AdpcmData); free(WaveData); - + return ErrVal; }