Add support for encoding type 4 ADX

This commit is contained in:
Alex Barney 2017-05-13 17:37:24 -05:00
parent ab647cc155
commit 89cdaa83e9
6 changed files with 66 additions and 6 deletions

View File

@ -35,6 +35,41 @@ void decode_adx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
stream->adpcm_history2_32 = hist2;
}
void decode_adx_exp(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes) {
int i;
int32_t sample_count;
int32_t frame_samples = (frame_bytes - 2) * 2;
int framesin = first_sample/frame_samples;
int32_t scale = read_16bitBE(stream->offset+framesin*frame_bytes,stream->streamfile);
scale = 1 << (12 - scale);
int32_t hist1 = stream->adpcm_history1_32;
int32_t hist2 = stream->adpcm_history2_32;
int coef1 = stream->adpcm_coef[0];
int coef2 = stream->adpcm_coef[1];
first_sample = first_sample%frame_samples;
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
int sample_byte = read_8bit(stream->offset+framesin*frame_bytes +2+i/2,stream->streamfile);
outbuf[sample_count] = clamp16(
(i&1?
get_low_nibble_signed(sample_byte):
get_high_nibble_signed(sample_byte)
) * scale +
((coef1 * hist1 + coef2 * hist2) >> 12)
);
hist2 = hist1;
hist1 = outbuf[sample_count];
}
stream->adpcm_history1_32 = hist1;
stream->adpcm_history2_32 = hist2;
}
void decode_adx_fixed(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes) {
int i;
int32_t sample_count;

View File

@ -5,6 +5,7 @@
/* adx_decoder */
void decode_adx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes);
void decode_adx_exp(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes);
void decode_adx_fixed(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes);
void decode_adx_enc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int32_t frame_bytes);
void adx_next_key(VGMSTREAMCHANNEL * stream);

View File

@ -388,6 +388,7 @@ static const coding_info coding_info_list[] = {
{coding_PCM8_int, "8-bit PCM with 1 byte interleave"},
{coding_PCM8_SB_int, "8-bit PCM with sign bit, 1 byte interleave"},
{coding_CRI_ADX, "CRI ADX 4-bit ADPCM"},
{coding_CRI_ADX_exp, "CRI ADX 4-bit ADPCM with exponential scale"},
{coding_CRI_ADX_fixed, "CRI ADX 4-bit ADPCM with fixed coefficients"},
{coding_CRI_ADX_enc_8, "CRI ADX 4-bit ADPCM (type 8 encryption)"},
{coding_CRI_ADX_enc_9, "CRI ADX 4-bit ADPCM (type 8 encryption)"},

View File

@ -22,7 +22,7 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
uint8_t frame_size;
meta_t header_type;
coding_t coding_type = coding_CRI_ADX;
coding_t coding_type;
int16_t coef1, coef2;
uint16_t xor_start=0,xor_mult=0,xor_add=0;
@ -43,9 +43,20 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
/* 0x02 is for some unknown fixed filter, 0x03 is standard ADX, 0x04 is
* ADX with exponential scale, 0x10 is AHX for DC, 0x11 is AHX */
encoding_type = read_8bit(0x04, streamFile);
if (encoding_type != 2 && encoding_type != 3) goto fail;
if (encoding_type == 2)
coding_type = coding_CRI_ADX_fixed;
switch (encoding_type) {
case 2:
coding_type = coding_CRI_ADX_fixed;
break;
case 3:
coding_type = coding_CRI_ADX;
break;
case 4:
coding_type = coding_CRI_ADX_exp;
break;
default:
goto fail;
}
frame_size = read_8bit(0x05, streamFile);
@ -182,8 +193,8 @@ VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
int i;
for (i = 0; i < channel_count; i++) {
vgmstream->ch[i].adpcm_coef[0] == coef1;
vgmstream->ch[i].adpcm_coef[1] == coef2;
vgmstream->ch[i].adpcm_coef[0] = coef1;
vgmstream->ch[i].adpcm_coef[1] = coef2;
}
}

View File

@ -935,6 +935,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
switch (vgmstream->coding_type) {
case coding_CRI_ADX:
case coding_CRI_ADX_fixed:
case coding_CRI_ADX_exp:
case coding_CRI_ADX_enc_8:
case coding_CRI_ADX_enc_9:
return (vgmstream->interleave_block_size - 2) * 2;
@ -1087,6 +1088,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
switch (vgmstream->coding_type) {
case coding_CRI_ADX:
case coding_CRI_ADX_fixed:
case coding_CRI_ADX_exp:
case coding_CRI_ADX_enc_8:
case coding_CRI_ADX_enc_9:
return vgmstream->interleave_block_size;
@ -1223,6 +1225,15 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
vgmstream->interleave_block_size);
}
break;
case coding_CRI_ADX_exp:
for (chan=0;chan<vgmstream->channels;chan++) {
decode_adx_exp(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
vgmstream->channels,vgmstream->samples_into_block,
samples_to_do,
vgmstream->interleave_block_size);
}
break;
case coding_CRI_ADX_fixed:
for (chan=0;chan<vgmstream->channels;chan++) {

View File

@ -87,6 +87,7 @@ typedef enum {
/* 4-bit ADPCM */
coding_CRI_ADX, /* CRI ADX */
coding_CRI_ADX_fixed, /* CRI ADX, encoding type 2 with fixed coefficients */
coding_CRI_ADX_exp, /* CRI ADX, encoding type 4 with exponential scale */
coding_CRI_ADX_enc_8, /* CRI ADX, type 8 encryption (God Hand) */
coding_CRI_ADX_enc_9, /* CRI ADX, type 9 encryption (PSO2) */