TXTH: Added EA-XA support

This commit is contained in:
NicknineTheEagle 2020-06-09 21:32:18 +03:00
parent 062ce3efed
commit b456cb84c6
4 changed files with 30 additions and 3 deletions

View File

@ -147,6 +147,8 @@ as explained below, but often will use default values. Accepted codec strings:
# * For Tiger Game.com
# - ASF Argonaut ASF ADPCM
# * For rare Argonaut games [Croc (SAT)]
# - EAXA Electronis Arts EA-XA ADPCM
# * For rare EA games [Harry Potter and the Chamber of Secrets (PC)]
codec = (codec string)
```
@ -155,7 +157,7 @@ Changes the behavior of some codecs:
```
# - NGC_DSP: 0=normal interleave, 1=byte interleave, 2=no interleave
# - XMA1|XMA2: 0=dual multichannel (2ch xN), 1=single multichannel (1ch xN)
# - XBOX: 0=standard (mono or stereo interleave), 1=force mono interleave mode
# - XBOX|EAXA: 0=standard (mono or stereo interleave), 1=force mono interleave mode
# - PCFX: 0=standard, 1='buggy encoder' mode, 2/3=same as 0/1 but with double volume
# - PCM4|PCM4_U: 0=low nibble first, 1=high nibble first
# - others: ignored

View File

@ -106,10 +106,11 @@ void decode_ea_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing
void decode_ea_xa_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
void decode_ea_xa_v2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
void decode_maxis_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
int32_t ea_xa_bytes_to_samples(size_t bytes, int channels);
/* ea_xas_decoder */
void decode_ea_xas_v0(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
void decode_ea_xas_v1(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
void decode_ea_xas_v1(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
/* sdx2_decoder */
void decode_sdx2(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
@ -236,7 +237,7 @@ void free_relic(relic_codec_data* data);
/* hca_decoder */
hca_codec_data *init_hca(STREAMFILE *streamFile);
void decode_hca(hca_codec_data * data, sample_t * outbuf, int32_t samples_to_do);
void decode_hca(hca_codec_data * data, sample * outbuf, int32_t samples_to_do);
void reset_hca(hca_codec_data * data);
void loop_hca(hca_codec_data * data, int32_t num_sample);
void free_hca(hca_codec_data * data);

View File

@ -303,3 +303,8 @@ void decode_maxis_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspac
if (i == frame_samples)
stream->offset += frame_size;
}
int32_t ea_xa_bytes_to_samples(size_t bytes, int channels) {
if (channels <= 0) return 0;
return bytes / channels / 0x0f * 28;
}

View File

@ -38,6 +38,7 @@ typedef enum {
AAC = 28, /* Advanced Audio Coding (raw without .mp4) */
TGC = 29, /* Tiger Game.com 4-bit ADPCM */
ASF = 30, /* Argonaut ASF 4-bit ADPCM */
EAXA = 31, /* Electronic Arts EA-XA 4-bit ADPCM v1 */
} txth_type;
typedef struct {
@ -225,6 +226,7 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) {
case OKI16: coding = coding_OKI16; break;
case TGC: coding = coding_TGC; break;
case ASF: coding = coding_ASF; break;
case EAXA: coding = coding_EA_XA; break;
default:
goto fail;
}
@ -341,6 +343,20 @@ VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) {
vgmstream->interleave_block_size = 0x11;
break;
case coding_EA_XA:
if (vgmstream->channels == 1 || txth.codec_mode == 1) { /* mono/interleave */
coding = coding_EA_XA_int;
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = txth.interleave;
vgmstream->interleave_last_block_size = txth.interleave_last;
} else { /* stereo */
if (vgmstream->channels > 2)
goto fail; /* only 2ch is known */
vgmstream->layout_type = layout_none;
}
break;
case coding_MS_IMA:
if (!txth.interleave) goto fail; /* creates garbage */
@ -856,6 +872,7 @@ static int parse_keyval(STREAMFILE * streamFile_, txth_header * txth, const char
else if (is_string(val,"TGC")) txth->codec = TGC;
else if (is_string(val,"GCOM_ADPCM")) txth->codec = TGC;
else if (is_string(val,"ASF")) txth->codec = ASF;
else if (is_string(val,"EAXA")) txth->codec = EAXA;
else goto fail;
/* set common interleaves to simplify usage
@ -1740,6 +1757,8 @@ static int get_bytes_to_samples(txth_header * txth, uint32_t bytes) {
return ac3_bytes_to_samples(bytes, txth->interleave, txth->channels);
case ASF:
return asf_bytes_to_samples(bytes, txth->channels);
case EAXA:
return ea_xa_bytes_to_samples(bytes, txth->channels);
/* XMA bytes-to-samples is done at the end as the value meanings are a bit different */
case XMA1: