mirror of
https://github.com/ScrelliCopter/VGM-Tools
synced 2025-02-21 04:09:25 +11:00
neotools: neoadpcmextract now converts ADPCM-B to Wave
This commit is contained in:
@@ -1,10 +1,8 @@
|
||||
/*; YM2610 ADPCM-B Codec
|
||||
;
|
||||
;
|
||||
/* adpcmb.c - CLI for encoding & decoding YM2610 ADPCM-B files
|
||||
; Fred/FRONT
|
||||
;
|
||||
;Usage 1: ADPCM_Encode.exe -d [-r:reg,clock] Input.bin Output.wav
|
||||
;Usage 2: ADPCM_Encode.exe -e Input.wav Output.bin
|
||||
;Usage 1: ADPCM_Encode -d [-r:reg,clock] Input.bin Output.wav
|
||||
;Usage 2: ADPCM_Encode -e Input.wav Output.bin
|
||||
;
|
||||
; Valley Bell
|
||||
;----------------------------------------------------------------------------------------------------------------------------*/
|
||||
@@ -17,90 +15,6 @@
|
||||
#include <string.h>
|
||||
|
||||
|
||||
/* 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
|
||||
|
||||
http://www.raregame.ru/file/15/YM2610.pdf YM2610 DATASHEET
|
||||
*/
|
||||
|
||||
static const long stepSizeTable[16] =
|
||||
{
|
||||
57, 57, 57, 57, 77, 102, 128, 153,
|
||||
57, 57, 57, 57, 77, 102, 128, 153
|
||||
};
|
||||
|
||||
void adpcmBEncoderInit(AdpcmBEncoderState* encoder)
|
||||
{
|
||||
encoder->xn = 0;
|
||||
encoder->stepSize = 127;
|
||||
encoder->flag = false;
|
||||
encoder->adpcmPack = 0;
|
||||
}
|
||||
|
||||
void adpcmBEncode(AdpcmBEncoderState* encoder, const int16_t* restrict in, uint8_t* restrict out, int len)
|
||||
{
|
||||
for (int lpc = 0; lpc < len; ++lpc)
|
||||
{
|
||||
long dn = (*in++) - encoder->xn;
|
||||
|
||||
long i = (labs(dn) << 16) / (encoder->stepSize << 14);
|
||||
i = MIN(i, 7);
|
||||
uint8_t adpcm = i;
|
||||
|
||||
i = (adpcm * 2 + 1) * encoder->stepSize / 8;
|
||||
|
||||
if (dn < 0)
|
||||
{
|
||||
adpcm |= 0x8;
|
||||
encoder->xn -= i;
|
||||
}
|
||||
else
|
||||
{
|
||||
encoder->xn += i;
|
||||
}
|
||||
|
||||
encoder->stepSize = (stepSizeTable[adpcm] * encoder->stepSize) / 64;
|
||||
encoder->stepSize = CLAMP(encoder->stepSize, 127, 24576);
|
||||
|
||||
if (!encoder->flag)
|
||||
{
|
||||
encoder->adpcmPack = adpcm << 4;
|
||||
encoder->flag = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
(*out++) = encoder->adpcmPack |= adpcm;
|
||||
encoder->flag = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void adpcmBDecoderInit(AdpcmBDecoderState* decoder)
|
||||
{
|
||||
decoder->xn = 0;
|
||||
decoder->stepSize = 127;
|
||||
}
|
||||
|
||||
void adpcmBDecode(AdpcmBDecoderState* decoder, const uint8_t* restrict in, int16_t* restrict out, int len)
|
||||
{
|
||||
for (long lpc = 0; lpc < len * 2; ++lpc)
|
||||
{
|
||||
uint8_t adpcm = (!(lpc & 0x1) ? (*in) >> 4 : (*in++)) & 0xF;
|
||||
|
||||
long i = ((adpcm & 7) * 2 + 1) * decoder->stepSize / 8;
|
||||
if (adpcm & 8)
|
||||
decoder->xn -= i;
|
||||
else
|
||||
decoder->xn += i;
|
||||
decoder->xn = CLAMP(decoder->xn, -32768, 32767);
|
||||
|
||||
decoder->stepSize = decoder->stepSize * stepSizeTable[adpcm] / 64;
|
||||
decoder->stepSize = CLAMP(decoder->stepSize, 127, 24576);
|
||||
|
||||
(*out++) = (int16_t)decoder->xn;
|
||||
}
|
||||
}
|
||||
|
||||
static FORCE_INLINE uint32_t DeltaTReg2SampleRate(uint16_t DeltaN, uint32_t Clock)
|
||||
{
|
||||
return (uint32_t)(DeltaN * (Clock / 72.0) / 65536.0 + 0.5);
|
||||
@@ -302,7 +216,7 @@ int main(int argc, char* argv[])
|
||||
printf("NeoGeo ADPCM-B En-/Decoder\n--------------------------\n");
|
||||
if (argc < 4)
|
||||
{
|
||||
printf("Usage: ADPCM_Encode.exe -method [-option] InputFile OutputFile\n");
|
||||
printf("Usage: ADPCM_Encode -method [-option] InputFile OutputFile\n");
|
||||
printf("-method - En-/Decoding Method:\n");
|
||||
printf(" -d for decode (bin -> wav)\n");
|
||||
printf(" -e for encode (wav -> bin)\n");
|
||||
|
||||
Reference in New Issue
Block a user