mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-28 07:31:12 +01:00
EA SCHl: Fixed channel offsets for some cases
This commit is contained in:
parent
48a618e532
commit
a8a35cecb8
@ -90,6 +90,7 @@ void block_update_ea_schl(off_t block_offset, VGMSTREAM * vgmstream) {
|
|||||||
/* set new channel offsets and ADPCM history */
|
/* set new channel offsets and ADPCM history */
|
||||||
/* ADPCM hist could be considered part of the stream/decoder (some EAXA decoders call it "EAXA R1" when it has hist), and BNKs
|
/* ADPCM hist could be considered part of the stream/decoder (some EAXA decoders call it "EAXA R1" when it has hist), and BNKs
|
||||||
* (with no blocks) may also have them in the first offset, but also may not. To simplify we just read them here. */
|
* (with no blocks) may also have them in the first offset, but also may not. To simplify we just read them here. */
|
||||||
|
/* FIXME: Saturn PCM streams are most likely non-interleaved and need to have offsets fixed */
|
||||||
switch(vgmstream->coding_type) {
|
switch(vgmstream->coding_type) {
|
||||||
/* id, size, unk1, unk2, interleaved data */
|
/* id, size, unk1, unk2, interleaved data */
|
||||||
case coding_PSX:
|
case coding_PSX:
|
||||||
@ -112,6 +113,14 @@ void block_update_ea_schl(off_t block_offset, VGMSTREAM * vgmstream) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
/* id, size, samples */
|
||||||
|
case coding_PCM8_int:
|
||||||
|
for (i = 0; i < vgmstream->channels; i++) {
|
||||||
|
vgmstream->ch[i].offset = block_offset + 0x0c + (i*0x01);
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
/* id, size, samples */
|
/* id, size, samples */
|
||||||
case coding_PCM16_int:
|
case coding_PCM16_int:
|
||||||
for (i = 0; i < vgmstream->channels; i++) {
|
for (i = 0; i < vgmstream->channels; i++) {
|
||||||
|
@ -1152,40 +1152,7 @@ static VGMSTREAM * init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header*
|
|||||||
vgmstream->codec_config = ea->codec_config;
|
vgmstream->codec_config = ea->codec_config;
|
||||||
|
|
||||||
vgmstream->meta_type = is_bnk ? meta_EA_BNK : meta_EA_SCHL;
|
vgmstream->meta_type = is_bnk ? meta_EA_BNK : meta_EA_SCHL;
|
||||||
|
vgmstream->layout_type = is_bnk ? layout_none : layout_blocked_ea_schl;
|
||||||
if (is_bnk) {
|
|
||||||
vgmstream->layout_type = layout_none;
|
|
||||||
|
|
||||||
/* BNKs usually have absolute offsets for all channels ("full" interleave) except in some versions */
|
|
||||||
if (ea->channels > 1 && ea->codec1 == EA_CODEC1_PCM) {
|
|
||||||
int interleave = (ea->num_samples * (ea->bps == 8 ? 0x01 : 0x02)); /* full interleave */
|
|
||||||
for (i = 0; i < ea->channels; i++) {
|
|
||||||
ea->offsets[i] = ea->offsets[0] + interleave*i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ea->channels > 1 && ea->codec1 == EA_CODEC1_VAG) {
|
|
||||||
int interleave = (ea->num_samples / 28 * 16); /* full interleave */
|
|
||||||
for (i = 0; i < ea->channels; i++) {
|
|
||||||
ea->offsets[i] = ea->offsets[0] + interleave*i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ea->channels > 1 && ea->codec2 == EA_CODEC2_GCADPCM && ea->offsets[0] == ea->offsets[1]) {
|
|
||||||
/* pcstream+gcadpcm with sx.exe v2, not in flag_value, probably a bug (even with this parts of the wave are off) */
|
|
||||||
int interleave = (ea->num_samples / 14 * 8); /* full interleave */
|
|
||||||
for (i = 0; i < ea->channels; i++) {
|
|
||||||
ea->offsets[i] = ea->offsets[0] + interleave*i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (ea->channels > 1 && ea->codec2 == EA_CODEC2_N64 && ea->offsets[1] == 0) {
|
|
||||||
uint32_t interleave = ea->flag_value;
|
|
||||||
for (i = 0; i < ea->channels; i++) {
|
|
||||||
ea->offsets[i] = ea->offsets[0] + interleave * i;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
vgmstream->layout_type = layout_blocked_ea_schl;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* EA usually implements their codecs in all platforms (PS2/WII do EAXA/MT/EALAYER3) and
|
/* EA usually implements their codecs in all platforms (PS2/WII do EAXA/MT/EALAYER3) and
|
||||||
* favors them over platform's natives (ex. EAXA vs VAG/DSP).
|
* favors them over platform's natives (ex. EAXA vs VAG/DSP).
|
||||||
@ -1205,12 +1172,22 @@ static VGMSTREAM * init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header*
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case EA_CODEC2_S8_INT: /* PCM8 (interleaved) */
|
case EA_CODEC2_S8_INT: /* PCM8 (interleaved) */
|
||||||
|
if (ea->platform == EA_PLATFORM_N64) {
|
||||||
|
/* FIXME: Saturn most likely has non-interleaved PCM, too */
|
||||||
|
vgmstream->coding_type = coding_PCM8;
|
||||||
|
} else {
|
||||||
vgmstream->coding_type = coding_PCM8_int;
|
vgmstream->coding_type = coding_PCM8_int;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EA_CODEC2_S16LE_INT: /* PCM16LE (interleaved) */
|
case EA_CODEC2_S16LE_INT: /* PCM16LE (interleaved) */
|
||||||
case EA_CODEC2_S16BE_INT: /* PCM16BE (interleaved) */
|
case EA_CODEC2_S16BE_INT: /* PCM16BE (interleaved) */
|
||||||
|
if (ea->platform == EA_PLATFORM_N64) {
|
||||||
|
/* FIXME: Saturn most likely has non-interleaved PCM, too */
|
||||||
|
vgmstream->coding_type = coding_PCM16BE;
|
||||||
|
} else {
|
||||||
vgmstream->coding_type = coding_PCM16_int;
|
vgmstream->coding_type = coding_PCM16_int;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case EA_CODEC2_S8: /* PCM8 */
|
case EA_CODEC2_S8: /* PCM8 */
|
||||||
@ -1250,7 +1227,6 @@ static VGMSTREAM * init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header*
|
|||||||
|
|
||||||
case EA_CODEC2_N64: /* VADPCM */
|
case EA_CODEC2_N64: /* VADPCM */
|
||||||
vgmstream->coding_type = coding_VADPCM;
|
vgmstream->coding_type = coding_VADPCM;
|
||||||
vgmstream->layout_type = layout_none;
|
|
||||||
|
|
||||||
for (ch = 0; ch < ea->channels; ch++) {
|
for (ch = 0; ch < ea->channels; ch++) {
|
||||||
int order = read_u32be(ea->coefs[ch] + 0x00, sf);
|
int order = read_u32be(ea->coefs[ch] + 0x00, sf);
|
||||||
@ -1352,37 +1328,76 @@ static VGMSTREAM * init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header*
|
|||||||
|
|
||||||
|
|
||||||
if (is_bnk) {
|
if (is_bnk) {
|
||||||
/* setup channel offsets */
|
/* BNKs usually have absolute offsets for all channels ("full" interleave) except in some versions */
|
||||||
if (vgmstream->coding_type == coding_EA_XA) {
|
if (ea->version == EA_VERSION_V0) {
|
||||||
/* shared (stereo/mono codec) */
|
switch (vgmstream->coding_type) {
|
||||||
|
case coding_EA_XA:
|
||||||
|
/* shared (stereo version) */
|
||||||
for (i = 0; i < vgmstream->channels; i++) {
|
for (i = 0; i < vgmstream->channels; i++) {
|
||||||
vgmstream->ch[i].offset = ea->offsets[0];
|
vgmstream->ch[i].offset = ea->offsets[0];
|
||||||
}
|
}
|
||||||
}
|
break;
|
||||||
//else if (vgmstream->layout_type == layout_interleave) { /* interleaved */
|
case coding_EA_XA_int: {
|
||||||
// for (i = 0; i < vgmstream->channels; i++) {
|
int interleave = ea->num_samples / 28 * 0x0f; /* full interleave */
|
||||||
// vgmstream->ch[i].offset = ea->offsets[0] + vgmstream->interleave_block_size*i;
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
else if (vgmstream->coding_type == coding_PCM8_int) {
|
|
||||||
/* fix interleaved PCM offsets */
|
|
||||||
for (i = 0; i < vgmstream->channels; i++) {
|
for (i = 0; i < vgmstream->channels; i++) {
|
||||||
vgmstream->ch[i].offset = ea->offsets[0] + 0x01*i;
|
vgmstream->ch[i].offset = ea->offsets[0] * interleave*i;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (vgmstream->coding_type == coding_PCM16_int) {
|
case coding_PCM8_int:
|
||||||
/* fix interleaved PCM offsets */
|
case coding_PCM16_int: {
|
||||||
|
int interleave = ea->bps==8 ? 0x01 : 0x02;
|
||||||
for (i = 0; i < vgmstream->channels; i++) {
|
for (i = 0; i < vgmstream->channels; i++) {
|
||||||
vgmstream->ch[i].offset = ea->offsets[0] + 0x02*i;
|
vgmstream->ch[i].offset = ea->offsets[0] + interleave*i;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
else if (vgmstream->coding_type == coding_PCM8 && ea->platform == EA_PLATFORM_PS2 && ea->version == EA_VERSION_V3) {
|
case coding_PCM8:
|
||||||
|
case coding_PCM16LE:
|
||||||
|
case coding_PCM16BE: {
|
||||||
|
int interleave = ea->num_samples * (ea->bps==8 ? 0x01 : 0x02); /* full interleave */
|
||||||
|
for (i = 0; i < vgmstream->channels; i++) {
|
||||||
|
vgmstream->ch[i].offset = ea->offsets[0] + interleave*i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case coding_PSX: {
|
||||||
|
int interleave = ea->num_samples / 28 * 0x10; /* full interleave */
|
||||||
|
for (i = 0; i < vgmstream->channels; i++) {
|
||||||
|
vgmstream->ch[i].offset = ea->offsets[0] + interleave*i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case coding_VADPCM: {
|
||||||
|
uint32_t interleave = ea->flag_value;
|
||||||
|
for (i = 0; i < vgmstream->channels; i++) {
|
||||||
|
vgmstream->ch[i].offset = ea->offsets[0] + interleave*i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case coding_EA_MT: {
|
||||||
|
uint32_t interleave = ea->flag_value;
|
||||||
|
for (i = 0; i < vgmstream->channels; i++) {
|
||||||
|
vgmstream->ch[i].offset = ea->offsets[0] + interleave*i;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
VGM_LOG("EA SCHl: Unknown interleave for codec 0x%02x in version %d\n", ea->codec1, ea->version);
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
} else if (vgmstream->coding_type == coding_NGC_DSP && vgmstream->channels > 1 && ea->offsets[0] == ea->offsets[1]) {
|
||||||
|
/* pcstream+gcadpcm with sx.exe v2, not in flag_value, probably a bug (even with this parts of the wave are off) */
|
||||||
|
int interleave = (ea->num_samples / 14 * 8); /* full interleave */
|
||||||
|
for (i = 0; i < ea->channels; i++) {
|
||||||
|
ea->offsets[i] = ea->offsets[0] + interleave*i;
|
||||||
|
}
|
||||||
|
} else if (vgmstream->coding_type == coding_PCM8 && ea->platform == EA_PLATFORM_PS2 && ea->version == EA_VERSION_V3) {
|
||||||
/* SSX3 (PS2) weird 0x10 mini header (codec/loop start/loop end/samples) */
|
/* SSX3 (PS2) weird 0x10 mini header (codec/loop start/loop end/samples) */
|
||||||
for (i = 0; i < vgmstream->channels; i++) {
|
for (i = 0; i < vgmstream->channels; i++) {
|
||||||
vgmstream->ch[i].offset = ea->offsets[0] + 0x10;
|
vgmstream->ch[i].offset = ea->offsets[i] + 0x10;
|
||||||
}
|
}
|
||||||
}
|
} else {
|
||||||
else {
|
|
||||||
/* absolute */
|
/* absolute */
|
||||||
for (i = 0; i < vgmstream->channels; i++) {
|
for (i = 0; i < vgmstream->channels; i++) {
|
||||||
vgmstream->ch[i].offset = ea->offsets[i];
|
vgmstream->ch[i].offset = ea->offsets[i];
|
||||||
|
Loading…
x
Reference in New Issue
Block a user