diff --git a/src/coding/fadpcm_decoder.c b/src/coding/fadpcm_decoder.c index c8de0883..331e94c4 100644 --- a/src/coding/fadpcm_decoder.c +++ b/src/coding/fadpcm_decoder.c @@ -1,5 +1,5 @@ #include "coding.h" -#include "../util.h" + /* FADPCM table */ static const int8_t fadpcm_coefs[8][2] = { @@ -20,7 +20,7 @@ void decode_fadpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacin off_t frame_offset; int i, j, k; int block_samples, num_frame, samples_done = 0, sample_count = 0; - int coef_index[8], shift_factor[8]; + uint32_t coefs, shifts; int32_t hist1; //= stream->adpcm_history1_32; int32_t hist2; //= stream->adpcm_history2_32; @@ -32,29 +32,25 @@ void decode_fadpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacin frame_offset = stream->offset + 0x8c*num_frame; - /* parse 0xc header */ - { - uint32_t coefs, shifts; - coefs = read_32bitLE(frame_offset + 0x00, stream->streamfile); - shifts = read_32bitLE(frame_offset + 0x04, stream->streamfile); - hist1 = read_16bitLE(frame_offset + 0x08, stream->streamfile); - hist2 = read_16bitLE(frame_offset + 0x0a, stream->streamfile); - - for (i = 0; i < 8; i++) { - coef_index[i] = (coefs >> i*4) & 0x0f; - shift_factor[i] = (shifts >> i*4) & 0x0f; - } - - /* header samples are not written to outbuf */ - } + /* parse 0xc header (header samples are not written to outbuf) */ + coefs = read_32bitLE(frame_offset + 0x00, stream->streamfile); + shifts = read_32bitLE(frame_offset + 0x04, stream->streamfile); + hist1 = read_16bitLE(frame_offset + 0x08, stream->streamfile); + hist2 = read_16bitLE(frame_offset + 0x0a, stream->streamfile); - /* decode nibbles, grouped in 0x10 * 0x04 * 2 */ + /* decode nibbles, grouped in 8 sets of 0x10 * 0x04 * 2 */ for (i = 0; i < 8; i++) { + int32_t coef1, coef2, shift, coef_index, shift_factor; off_t group_offset = frame_offset + 0x0c + 0x10*i; - int32_t coef1 = fadpcm_coefs[(coef_index[i] % 0x07)][0]; /* indexes > 7 are repeats (ex. 0x9 is 0x2) */ - int32_t coef2 = fadpcm_coefs[(coef_index[i] % 0x07)][1]; - int32_t shift = 0x16 - shift_factor[i]; + + /* each set has its own coefs/shifts (indexes > 7 are repeat, ex. 0x9 is 0x2) */ + coef_index = ((coefs >> i*4) & 0x0f) % 0x07; + shift_factor = (shifts >> i*4) & 0x0f; + + coef1 = fadpcm_coefs[coef_index][0]; + coef2 = fadpcm_coefs[coef_index][1]; + shift = 0x16 - shift_factor; for (j = 0; j < 4; j++) { uint32_t nibbles = read_32bitLE(group_offset + 0x04*j, stream->streamfile); diff --git a/src/formats.c b/src/formats.c index 9bd66259..e919bd3d 100644 --- a/src/formats.c +++ b/src/formats.c @@ -500,7 +500,7 @@ static const coding_info coding_info_list[] = { {coding_MTAF, "Konami MTAF 4-bit ADPCM"}, {coding_MTA2, "Konami MTA2 4-bit ADPCM"}, {coding_MC3, "Paradigm MC3 3-bit ADPCM"}, - {coding_FADPCM, "FMOD FADPCM 4-bit ADCPM"}, + {coding_FADPCM, "FMOD FADPCM 4-bit ADPCM"}, {coding_SDX2, "Squareroot-delta-exact (SDX2) 8-bit DPCM"}, {coding_SDX2_int, "Squareroot-delta-exact (SDX2) 8-bit DPCM with 1 byte interleave"}, diff --git a/src/vgmstream.h b/src/vgmstream.h index 39c60dde..b18a0e82 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -152,7 +152,7 @@ typedef enum { coding_MTAF, /* Konami MTAF ADPCM */ coding_MTA2, /* Konami MTA2 ADPCM */ coding_MC3, /* Paradigm MC3 3-bit ADPCM */ - coding_FADPCM, /* FMOD FADPCM 4-bit ADCPM */ + coding_FADPCM, /* FMOD FADPCM 4-bit ADPCM */ /* others */ coding_SDX2, /* SDX2 2:1 Squareroot-Delta-Exact compression DPCM */