From ae148689530ff56a21b26019023a7ce4c7e1cd21 Mon Sep 17 00:00:00 2001 From: a dinosaur Date: Sun, 10 Dec 2023 11:36:05 +1100 Subject: [PATCH] neotools: adpcm-a split backend code --- neotools/CMakeLists.txt | 2 +- neotools/adpcm.c | 49 ----------------------------------- neotools/libadpcma.c | 57 +++++++++++++++++++++++++++++++++++++++++ 3 files changed, 58 insertions(+), 50 deletions(-) create mode 100644 neotools/libadpcma.c diff --git a/neotools/CMakeLists.txt b/neotools/CMakeLists.txt index 6d3c22a..156963b 100644 --- a/neotools/CMakeLists.txt +++ b/neotools/CMakeLists.txt @@ -4,7 +4,7 @@ if (USE_ZLIB AND NOT ZLIB_FOUND) message(FATAL_ERROR "USE_ZLIB specified but Zlib was not found") endif() -add_executable(adpcm adpcm.h adpcm.c) +add_executable(adpcm adpcm.h libadpcma.c adpcm.c) set_property(TARGET adpcm PROPERTY C_STANDARD 99) target_compile_options(adpcm PRIVATE ${WARNINGS}) target_link_libraries(adpcm Common::wave $<$:m>) diff --git a/neotools/adpcm.c b/neotools/adpcm.c index a11bcc1..43269b2 100644 --- a/neotools/adpcm.c +++ b/neotools/adpcm.c @@ -3,25 +3,13 @@ */ #include "adpcm.h" -#include "util.h" #include "wave.h" #include #include -#include #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) -static const int decodeTableA1[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 -}; - int main(int argc, char* argv[]) { fprintf(stderr, "**** ADPCM to PCM converter v 1.01\n\n"); @@ -98,40 +86,3 @@ int main(int argc, char* argv[]) return 0; } - -void adpcmAInit(AdpcmADecoderState* decoder) -{ - for (int step = 0; step <= 48; step++) - { - int stepval = floor(16.0 * pow(11.0 / 10.0, step) * ADPCMA_VOLUME_RATE); - // Loop over all nibbles and compute the difference - for (int nib = 0; nib < 16; nib++) - { - int value = stepval * ((nib & 0x07) * 2 + 1) / 8; - decoder->jediTable[step * 16 + nib] = (nib & 0x08) ? -value : value; - } - } - - decoder->delta = 0; - decoder->cursignal = 0; -} - -void adpcmADecode(AdpcmADecoderState* restrict decoder, char* restrict in, short* restrict out, int len) -{ - for (int i = 0; i < len * 2; ++i) - { - int data = (!(i & 0x1) ? ((*in) >> 4) : (*in++)) & 0x0F; - int oldsignal = decoder->cursignal; - decoder->cursignal = CLAMP(decoder->cursignal + decoder->jediTable[data + decoder->delta], - ADPCMA_DECODE_MIN, ADPCMA_DECODE_MAX); - decoder->delta = CLAMP(decoder->delta + decodeTableA1[data], 0 * 16, 48 * 16); - if (abs(oldsignal - decoder->cursignal) > 2500) - { - fprintf(stderr, "WARNING: Suspicious signal evolution %06x,%06x pos:%06x delta:%06x\n", - oldsignal, decoder->cursignal, i % len, decoder->delta); - fprintf(stderr, "data:%02x dx:%08x\n", - data, decoder->jediTable[data + decoder->delta]); - } - *(out++) = (decoder->cursignal & 0xffff) * 32; - } -} diff --git a/neotools/libadpcma.c b/neotools/libadpcma.c new file mode 100644 index 0000000..587da4b --- /dev/null +++ b/neotools/libadpcma.c @@ -0,0 +1,57 @@ +/* libadpcma.c (C) 2023 a dinosaur (zlib) + Original ADPCM to PCM converter v 1.01 By MARTINEZ Fabrice aka SNK of SUPREMACY */ + +#include "adpcm.h" +#include "util.h" +#include +#include +#include + +#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) + + +void adpcmAInit(AdpcmADecoderState* decoder) +{ + for (int step = 0; step <= 48; step++) + { + int stepval = floor(16.0 * pow(11.0 / 10.0, step) * ADPCMA_VOLUME_RATE); + // Loop over all nibbles and compute the difference + for (int nib = 0; nib < 16; nib++) + { + int value = stepval * ((nib & 0x07) * 2 + 1) / 8; + decoder->jediTable[step * 16 + nib] = (nib & 0x08) ? -value : value; + } + } + + decoder->delta = 0; + decoder->cursignal = 0; +} + +static const int decodeTableA1[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 +}; + +void adpcmADecode(AdpcmADecoderState* restrict decoder, char* restrict in, short* restrict out, int len) +{ + for (int i = 0; i < len * 2; ++i) + { + int data = (!(i & 0x1) ? ((*in) >> 4) : (*in++)) & 0x0F; + int oldsignal = decoder->cursignal; + decoder->cursignal = CLAMP(decoder->cursignal + decoder->jediTable[data + decoder->delta], + ADPCMA_DECODE_MIN, ADPCMA_DECODE_MAX); + decoder->delta = CLAMP(decoder->delta + decodeTableA1[data], 0 * 16, 48 * 16); + if (abs(oldsignal - decoder->cursignal) > 2500) + { + fprintf(stderr, "WARNING: Suspicious signal evolution %06x,%06x pos:%06x delta:%06x\n", + oldsignal, decoder->cursignal, i % len, decoder->delta); + fprintf(stderr, "data:%02x dx:%08x\n", + data, decoder->jediTable[data + decoder->delta]); + } + *(out++) = (decoder->cursignal & 0xffff) * 32; + } +}