mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-29 19:37:30 +01:00
Tweak EALayer3 discard modes from debug info and EAAC header
This commit is contained in:
parent
22c3266727
commit
6f2999cd3d
@ -29,19 +29,19 @@
|
||||
typedef struct {
|
||||
/* EALayer3 v1 header */
|
||||
uint32_t v1_pcm_flag;
|
||||
uint32_t v1_pcm_decode_discard;
|
||||
uint32_t v1_pcm_number;
|
||||
uint32_t v1_offset_samples;
|
||||
uint32_t v1_pcm_samples;
|
||||
uint32_t v1_pcm_unknown;
|
||||
|
||||
/* EALayer3 v2 header */
|
||||
uint32_t v2_extended_flag;
|
||||
uint32_t v2_stereo_flag;
|
||||
uint32_t v2_unknown; /* unused? */
|
||||
uint32_t v2_reserved;
|
||||
uint32_t v2_frame_size; /* full size including headers and pcm block */
|
||||
uint32_t v2_mode; /* discard mode */
|
||||
uint32_t v2_mode_value; /* samples to use depending on mode */
|
||||
uint32_t v2_pcm_number;
|
||||
uint32_t v2_common_size; /* common header+data size; can be zero */
|
||||
uint32_t v2_offset_mode; /* discard mode */
|
||||
uint32_t v2_offset_samples; /* use depends on mode */
|
||||
uint32_t v2_pcm_samples;
|
||||
uint32_t v2_common_size; /* granule size: common header+data size; can be zero */
|
||||
|
||||
/* EALayer3 common header + side info */
|
||||
uint32_t version_index;
|
||||
@ -275,11 +275,11 @@ static int ealayer3_parse_frame_v1(vgm_bitstream *is, ealayer3_frame_info * eaf,
|
||||
|
||||
/* check PCM block */
|
||||
if (eaf->v1_pcm_flag == 0xEE) {
|
||||
r_bits(is, 16,&eaf->v1_pcm_decode_discard); /* samples to discard of the next decoded (not PCM block) samples */
|
||||
r_bits(is, 16,&eaf->v1_pcm_number); /* number of PCM samples, can be 0 */
|
||||
r_bits(is, 16,&eaf->v1_offset_samples); /* samples to discard of the next decoded (not PCM block) samples */
|
||||
r_bits(is, 16,&eaf->v1_pcm_samples); /* number of PCM samples, can be 0 */
|
||||
|
||||
eaf->pre_size += 2+2; /* 16b+16b */
|
||||
eaf->pcm_size = (2*eaf->v1_pcm_number * channels_per_frame);
|
||||
eaf->pcm_size = (2*eaf->v1_pcm_samples * channels_per_frame);
|
||||
|
||||
if (is_v1b) { /* extra 32b in v1b */
|
||||
r_bits(is, 32,&eaf->v1_pcm_unknown);
|
||||
@ -303,15 +303,15 @@ static int ealayer3_parse_frame_v2(vgm_bitstream *is, ealayer3_frame_info * eaf)
|
||||
/* read EA-frame V2 header */
|
||||
r_bits(is, 1,&eaf->v2_extended_flag);
|
||||
r_bits(is, 1,&eaf->v2_stereo_flag);
|
||||
r_bits(is, 2,&eaf->v2_unknown);
|
||||
r_bits(is, 2,&eaf->v2_reserved);
|
||||
r_bits(is, 12,&eaf->v2_frame_size);
|
||||
|
||||
eaf->pre_size = 2; /* 16b */
|
||||
|
||||
if (eaf->v2_extended_flag) {
|
||||
r_bits(is, 2,&eaf->v2_mode);
|
||||
r_bits(is, 10,&eaf->v2_mode_value);
|
||||
r_bits(is, 10,&eaf->v2_pcm_number);
|
||||
r_bits(is, 2,&eaf->v2_offset_mode);
|
||||
r_bits(is, 10,&eaf->v2_offset_samples);
|
||||
r_bits(is, 10,&eaf->v2_pcm_samples);
|
||||
r_bits(is, 10,&eaf->v2_common_size);
|
||||
|
||||
eaf->pre_size += 4; /* 32b */
|
||||
@ -323,10 +323,10 @@ static int ealayer3_parse_frame_v2(vgm_bitstream *is, ealayer3_frame_info * eaf)
|
||||
if (!ok) goto fail;
|
||||
}
|
||||
VGM_ASSERT(eaf->v2_extended_flag && eaf->v2_common_size == 0, "EA EAL3: v2 empty frame\n"); /* seen in V2S */
|
||||
VGM_ASSERT(eaf->v2_extended_flag && eaf->v2_mode_value > 0, "EA EAL3: v2_mode=%x with value=0x%x\n", eaf->v2_mode, eaf->v2_mode_value);
|
||||
//VGM_ASSERT(eaf->v2_pcm_number > 0, "EA EAL3: v2_pcm_number 0x%x\n", eaf->v2_pcm_number);
|
||||
VGM_ASSERT(eaf->v2_extended_flag && eaf->v2_offset_samples > 0, "EA EAL3: v2_offset_mode=%x with value=0x%x\n", eaf->v2_offset_mode, eaf->v2_offset_samples);
|
||||
//VGM_ASSERT(eaf->v2_pcm_samples > 0, "EA EAL3: v2_pcm_samples 0x%x\n", eaf->v2_pcm_samples);
|
||||
|
||||
eaf->pcm_size = (2*eaf->v2_pcm_number * eaf->channels);
|
||||
eaf->pcm_size = (2*eaf->v2_pcm_samples * eaf->channels);
|
||||
|
||||
eaf->eaframe_size = eaf->pre_size + eaf->common_size + eaf->pcm_size;
|
||||
|
||||
@ -614,43 +614,44 @@ static int ealayer3_write_pcm_block(VGMSTREAMCHANNEL *stream, mpeg_codec_data *d
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (eaf->v1_pcm_number && !eaf->pcm_size) {
|
||||
VGM_LOG("MPEG EAL3: pcm size without pcm number\n");
|
||||
goto fail; //todo ??? first block?
|
||||
if (eaf->v1_pcm_samples && !eaf->pcm_size) {
|
||||
VGM_LOG("MPEG EAL3: pcm_size without pcm_samples\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (eaf->v1_pcm_number) {
|
||||
if (eaf->v1_pcm_samples || eaf->v1_offset_samples) {
|
||||
uint8_t* outbuf = ms->output_buffer + bytes_filled;
|
||||
off_t pcm_offset = stream->offset + eaf->pre_size + eaf->common_size;
|
||||
|
||||
VGM_ASSERT(eaf->v1_pcm_decode_discard > 576, "MPEG EAL3: big discard %i at 0x%x\n", eaf->v1_pcm_decode_discard, (uint32_t)stream->offset);
|
||||
VGM_ASSERT(eaf->v1_pcm_number > 0x100, "MPEG EAL3: big samples %i at 0x%x\n", eaf->v1_pcm_number, (uint32_t)stream->offset);
|
||||
VGM_ASSERT(eaf->v1_offset_samples > 576, "MPEG EAL3: big discard %i at 0x%x\n", eaf->v1_offset_samples, (uint32_t)stream->offset);
|
||||
VGM_ASSERT(eaf->v1_pcm_samples > 0x100, "MPEG EAL3: big samples %i at 0x%x\n", eaf->v1_pcm_samples, (uint32_t)stream->offset);
|
||||
VGM_ASSERT(eaf->v1_offset_samples > 0 && eaf->v1_pcm_samples == 0, "EAL3: offset_samples without pcm_samples\n"); /* not seen but could work */
|
||||
|
||||
//;VGM_LOG("EA EAL3 v1: off=%lx, discard=%x, pcm=%i, pcm_o=%lx\n",
|
||||
// stream->offset, eaf->v1_pcm_decode_discard, eaf->v1_pcm_number, pcm_offset);
|
||||
// stream->offset, eaf->v1_offset_samples, eaf->v1_pcm_samples, pcm_offset);
|
||||
|
||||
/* V1 usually discards + copies samples at the same time
|
||||
* V1b PCM block is interleaved/'planar' format (ex. NFS:U PS3) */
|
||||
ealayer3_copy_pcm_block(outbuf, pcm_offset, eaf->v1_pcm_number, channels_per_frame, (data->type == MPEG_EAL31), stream->streamfile);
|
||||
ms->samples_filled += eaf->v1_pcm_number;
|
||||
ealayer3_copy_pcm_block(outbuf, pcm_offset, eaf->v1_pcm_samples, channels_per_frame, (data->type == MPEG_EAL31), stream->streamfile);
|
||||
ms->samples_filled += eaf->v1_pcm_samples;
|
||||
|
||||
/* skip decoded samples as PCM block 'overwrites' them w/ special meanings */
|
||||
{
|
||||
size_t decode_to_discard = eaf->v1_pcm_decode_discard;
|
||||
size_t decode_to_discard = eaf->v1_offset_samples;
|
||||
|
||||
if (data->type == MPEG_EAL31) {
|
||||
//todo should also discard v1_pcm_number, but block layout samples may be exhausted
|
||||
//todo should also discard v1_pcm_samples, but block layout samples may be exhausted
|
||||
// and won't move (maybe new block if offset = new offset detected)
|
||||
if (decode_to_discard == 576)
|
||||
decode_to_discard = data->samples_per_frame;//+ eaf->v1_pcm_number;
|
||||
decode_to_discard = data->samples_per_frame;//+ eaf->v1_pcm_samples;
|
||||
}
|
||||
else {
|
||||
//todo maybe should be (576 or samples_per_frame - decode_to_discard) but V1b doesn't seem to set discard
|
||||
VGM_ASSERT(decode_to_discard > 0, "EAL3: found offset_samples in V1b\n");
|
||||
/* probably (576 or samples_per_frame - eaf->v1_offset_samples) but V1b seems to always use 0 and ~47 samples */
|
||||
if (decode_to_discard == 0) /* seems ok (ex. comparing NFS:UC PS3 vs PC gets correct waveform this way) */
|
||||
decode_to_discard = data->samples_per_frame;//+ eaf->v1_pcm_number; /* musn't discard pcm_number */
|
||||
else if (decode_to_discard == 576) //todo unsure
|
||||
decode_to_discard = data->samples_per_frame;//+ eaf->v1_pcm_number;
|
||||
decode_to_discard = data->samples_per_frame;//+ eaf->v1_pcm_samples; /* musn't discard pcm_number */
|
||||
}
|
||||
|
||||
ms->decode_to_discard += decode_to_discard;
|
||||
}
|
||||
}
|
||||
@ -658,37 +659,56 @@ static int ealayer3_write_pcm_block(VGMSTREAMCHANNEL *stream, mpeg_codec_data *d
|
||||
if (eaf->v2_extended_flag) {
|
||||
uint8_t* outbuf = ms->output_buffer + bytes_filled;
|
||||
off_t pcm_offset = stream->offset + eaf->pre_size + eaf->common_size;
|
||||
size_t usable_samples, decode_to_discard;
|
||||
|
||||
/* V2P usually only copies big PCM, while V2S discards then copies few samples (similar to V1b).
|
||||
* Unlike V1b, both modes seem to use 'packed' PCM block */
|
||||
ealayer3_copy_pcm_block(outbuf, pcm_offset, eaf->v2_pcm_number, channels_per_frame, 1, stream->streamfile);
|
||||
ms->samples_filled += eaf->v2_pcm_number;
|
||||
ealayer3_copy_pcm_block(outbuf, pcm_offset, eaf->v2_pcm_samples, channels_per_frame, 1, stream->streamfile);
|
||||
ms->samples_filled += eaf->v2_pcm_samples;
|
||||
|
||||
//;VGM_LOG("EA EAL3 v2: off=%lx, mode=%x, value=%i, pcm=%i, c-size=%x, pcm_o=%lx\n",
|
||||
// stream->offset, eaf->v2_mode, eaf->v2_mode_value, eaf->v2_pcm_number, eaf->v2_common_size, pcm_offset);
|
||||
// stream->offset, eaf->v2_offset_mode, eaf->v2_offset_samples, eaf->v2_pcm_samples, eaf->v2_common_size, pcm_offset);
|
||||
|
||||
/* modify decoded samples depending on flag (looks correct in V2P loops, ex. NFS:W) */
|
||||
if (eaf->v2_mode == 0x00) {
|
||||
size_t decode_to_discard = eaf->v2_mode_value; /* (usually 0 in V2P, varies in V2S) */
|
||||
decode_to_discard = 576 - decode_to_discard;
|
||||
//todo improve how discarding works since there could exists a subtle-but-unlikely PCM+granule usage
|
||||
//todo test other modes (only seen IGNORE)
|
||||
|
||||
ms->decode_to_discard += decode_to_discard;
|
||||
/* get how many samples we can use in this granule + pcm block (thus how many we can't) */
|
||||
if (eaf->v2_offset_mode == 0x00) { /* IGNORE (looks correct in V2P loops, ex. NFS:W) */
|
||||
/* offset_samples is usually 0 in V2P (no discard), varies in V2S and may be 576 (full discard).
|
||||
* If block has pcm_samples then usable_samples will be at least that value (for all known files),
|
||||
* and is assumed PCM isn't discarded so only discards the decoded granule. */
|
||||
usable_samples = 576 - eaf->v2_offset_samples;
|
||||
if (eaf->common_size == 0)
|
||||
usable_samples = eaf->v2_pcm_samples;
|
||||
|
||||
if (usable_samples == eaf->v2_pcm_samples) {
|
||||
decode_to_discard = 576;
|
||||
}
|
||||
else {
|
||||
VGM_LOG("EAL3: unknown discard\n");
|
||||
decode_to_discard = 0;
|
||||
}
|
||||
}
|
||||
else if (eaf->v2_offset_mode == 0x01) { /* PRESERVE */
|
||||
usable_samples = 576;
|
||||
if (eaf->common_size == 0)
|
||||
usable_samples = eaf->v2_pcm_samples;
|
||||
decode_to_discard = 0; /* all preserved */
|
||||
}
|
||||
else if (eaf->v2_offset_mode == 0x02) { /* MUTE */
|
||||
usable_samples = 576;
|
||||
if (eaf->common_size == 0)
|
||||
usable_samples = eaf->v2_pcm_samples * 2; // why 2?
|
||||
decode_to_discard = 0; /* not discarded but muted */
|
||||
//mute_samples = eaf->v2_offset_samples; //todo must 0 first N decoded samples
|
||||
}
|
||||
else {
|
||||
VGM_LOG("EAL3: unknown mode\n"); /* not defined */
|
||||
usable_samples = 576;
|
||||
decode_to_discard = 0;
|
||||
}
|
||||
|
||||
/* todo supposed skip modes (only seen 0x00):
|
||||
*
|
||||
* AB00CCCC CCCCCCCC if A is set: DDEEEEEE EEEEFFFF FFFFFFGG GGGGGGGG
|
||||
* D = BLOCKOFFSETMODE: IGNORE = 0x0, PRESERVE = 0x1, MUTE = 0x2, MAX = 0x3
|
||||
* E = samples to discard (mode == 0) or skip (mode == 1 or 2) before outputting the uncompressed samples
|
||||
* (when mode == 3 this is ignored)
|
||||
* F = number of uncompressed sample frames (pcm block)
|
||||
* G = MPEG granule size (can be zero)
|
||||
*
|
||||
* if 0: 576 - E if G == 0 then F
|
||||
* if 1: 576 if G == 0 then F
|
||||
* if 2: 576 if G == 0 then F * 2
|
||||
* if 3: 576
|
||||
*/
|
||||
ms->decode_to_discard += decode_to_discard;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -9,23 +9,24 @@
|
||||
#define EAAC_VERSION_V0 0x00 /* SNR/SNS */
|
||||
#define EAAC_VERSION_V1 0x01 /* SPS */
|
||||
|
||||
#define EAAC_CODEC_NONE 0x00 /* internal 'codec not set' */
|
||||
#define EAAC_CODEC_RESERVED 0x01 /* not used/reserved? /MP30/P6L0/P2B0/P2L0/P8S0/P8U0/PFN0? */
|
||||
#define EAAC_CODEC_PCM 0x02
|
||||
#define EAAC_CODEC_NONE 0x00 /* XAS v0? */
|
||||
#define EAAC_CODEC_RESERVED 0x01 /* EALAYER3 V1a? MP30/P6L0/P2B0/P2L0/P8S0/P8U0/PFN0? */
|
||||
#define EAAC_CODEC_PCM16BE 0x02
|
||||
#define EAAC_CODEC_EAXMA 0x03
|
||||
#define EAAC_CODEC_XAS 0x04
|
||||
#define EAAC_CODEC_XAS1 0x04
|
||||
#define EAAC_CODEC_EALAYER3_V1 0x05
|
||||
#define EAAC_CODEC_EALAYER3_V2_PCM 0x06
|
||||
#define EAAC_CODEC_EALAYER3_V2_SPIKE 0x07
|
||||
#define EAAC_CODEC_DSP 0x08
|
||||
#define EAAC_CODEC_GCADPCM 0x08
|
||||
#define EAAC_CODEC_EASPEEX 0x09
|
||||
#define EAAC_CODEC_EATRAX 0x0a
|
||||
#define EAAC_CODEC_EAMP3 0x0b
|
||||
#define EAAC_CODEC_EAOPUS 0x0c
|
||||
|
||||
#define EAAC_FLAG_NONE 0x00
|
||||
#define EAAC_FLAG_LOOPED 0x02
|
||||
#define EAAC_FLAG_STREAMED 0x04
|
||||
#define EAAC_TYPE_RAM 0x00
|
||||
#define EAAC_TYPE_STREAM 0x01
|
||||
|
||||
#define EAAC_LOOP_SET 0x01
|
||||
|
||||
#define EAAC_BLOCKID0_DATA 0x00
|
||||
#define EAAC_BLOCKID0_END 0x80 /* maybe meant to be a bitflag? */
|
||||
@ -839,7 +840,8 @@ typedef struct {
|
||||
int codec;
|
||||
int channel_config;
|
||||
int sample_rate;
|
||||
int flags;
|
||||
int type;
|
||||
int loop;
|
||||
|
||||
int streamed;
|
||||
int channels;
|
||||
@ -871,34 +873,45 @@ static VGMSTREAM * init_vgmstream_eaaudiocore_header(STREAMFILE * streamHead, ST
|
||||
/* EA SNR/SPH header */
|
||||
header1 = (uint32_t)read_32bitBE(header_offset + 0x00, streamHead);
|
||||
header2 = (uint32_t)read_32bitBE(header_offset + 0x04, streamHead);
|
||||
eaac.version = (header1 >> 28) & 0x0F; /* 4 bits */
|
||||
eaac.codec = (header1 >> 24) & 0x0F; /* 4 bits */
|
||||
eaac.version = (header1 >> 28) & 0x0F; /* 4 bits */
|
||||
eaac.codec = (header1 >> 24) & 0x0F; /* 4 bits */
|
||||
eaac.channel_config = (header1 >> 18) & 0x3F; /* 6 bits */
|
||||
eaac.sample_rate = (header1 & 0x03FFFF); /* 18 bits (some Dead Space 2 (PC) do use 96000) */
|
||||
eaac.flags = (header2 >> 28) & 0x0F; /* 4 bits *//* TODO: maybe even 3 bits and not 4? */
|
||||
eaac.num_samples = (header2 & 0x0FFFFFFF); /* 28 bits */
|
||||
eaac.sample_rate = (header1 >> 0) & 0x03FFFF; /* 18 bits */
|
||||
eaac.type = (header2 >> 30) & 0x03; /* 2 bits */
|
||||
eaac.loop = (header2 >> 29) & 0x01; /* 1 bits */
|
||||
eaac.num_samples = (header2 >> 0) & 0x1FFFFFFF; /* 29 bits */
|
||||
/* rest is optional, depends on used flags and codec (handled below) */
|
||||
eaac.stream_offset = start_offset;
|
||||
|
||||
/* common channel configs are mono/stereo/quad/5.1/7.1 (from debug strings), while others are quite rare
|
||||
* [Battlefield 4 (X360)-EAXMA: 3/5/7ch, Army of Two: The Devil's Cartel (PS3)-EALayer3v2P: 11ch] */
|
||||
eaac.channels = eaac.channel_config + 1;
|
||||
|
||||
/* V0: SNR+SNS, V1: SPR+SPS (no apparent differences, other than block flags) */
|
||||
if (eaac.version != EAAC_VERSION_V0 && eaac.version != EAAC_VERSION_V1) {
|
||||
VGM_LOG("EA EAAC: unknown version\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* catch unknown/garbage values just in case */
|
||||
if (eaac.flags != EAAC_FLAG_NONE && !(eaac.flags & (EAAC_FLAG_LOOPED | EAAC_FLAG_STREAMED))) {
|
||||
VGM_LOG("EA EAAC: unknown flags 0x%02x\n", eaac.flags);
|
||||
/* accepted max (some Dead Space 2 (PC) do use 96000) */
|
||||
if (eaac.sample_rate > 200000) {
|
||||
VGM_LOG("EA EAAC: unknown sample rate\n");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* catch unknown values (0x02: "gigasample"? some kind of memory+stream thing?) */
|
||||
if (eaac.type != EAAC_TYPE_RAM && eaac.type != EAAC_TYPE_STREAM) {
|
||||
VGM_LOG("EA EAAC: unknown type 0x%02x\n", eaac.type);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Non-streamed sounds are stored as a single block (may not set block end flags) */
|
||||
eaac.streamed = (eaac.flags & EAAC_FLAG_STREAMED) != 0;
|
||||
eaac.streamed = (eaac.type == EAAC_TYPE_STREAM);
|
||||
|
||||
/* get loops (fairly involved due to the multiple layouts and mutant streamfiles)
|
||||
* full loops aren't too uncommon [Dead Space (PC) stream sfx/ambiance, FIFA 98 (PS3) RAM sfx],
|
||||
* while actual looping is very rare [Need for Speed: World (PC)-EAL3, The Simpsons Game (X360)-EAXMA] */
|
||||
if (eaac.flags & EAAC_FLAG_LOOPED) {
|
||||
if (eaac.loop == EAAC_LOOP_SET) {
|
||||
eaac.loop_flag = 1;
|
||||
eaac.loop_start = read_32bitBE(header_offset+0x08, streamHead);
|
||||
eaac.loop_end = eaac.num_samples;
|
||||
@ -938,28 +951,14 @@ static VGMSTREAM * init_vgmstream_eaaudiocore_header(STREAMFILE * streamHead, ST
|
||||
eaac.codec == EAAC_CODEC_EALAYER3_V2_PCM ||
|
||||
eaac.codec == EAAC_CODEC_EALAYER3_V2_SPIKE ||
|
||||
eaac.codec == EAAC_CODEC_EAXMA ||
|
||||
eaac.codec == EAAC_CODEC_XAS)) {
|
||||
eaac.codec == EAAC_CODEC_XAS1)) {
|
||||
VGM_LOG("EA EAAC: unknown actual looping for codec %x\n", eaac.codec);
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* common channel configs are mono/stereo/quad/5.1/7.1 (from debug strings) */
|
||||
switch(eaac.channel_config) {
|
||||
case 0x00: eaac.channels = 1; break;
|
||||
case 0x01: eaac.channels = 2; break;
|
||||
case 0x02: eaac.channels = 3; break; /* rare [Battlefield 4 (X360)-EAXMA] */
|
||||
case 0x03: eaac.channels = 4; break;
|
||||
case 0x04: eaac.channels = 5; break; /* rare [Battlefield 4 (X360)-EAXMA] */
|
||||
case 0x05: eaac.channels = 6; break;
|
||||
case 0x06: eaac.channels = 7; break; /* rare [Battlefield 4 (X360)-EAXMA] */
|
||||
case 0x07: eaac.channels = 8; break;
|
||||
case 0x0a: eaac.channels = 11; break; /* rare [Army of Two: The Devil's Cartel (PS3)-EALayer3v2P] */
|
||||
default:
|
||||
/* surely channels = channel_config+1 but fail just in case for now */
|
||||
VGM_LOG("EA EAAC: unknown channel config 0x%02x\n", eaac.channel_config);
|
||||
goto fail;
|
||||
}
|
||||
/* if type is gigasample there seems to be a field with number of "gigasamples in ram",
|
||||
* that goes after loop_start but before streamed/gigasamples' eaac.loop_offset) */
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
@ -975,7 +974,7 @@ static VGMSTREAM * init_vgmstream_eaaudiocore_header(STREAMFILE * streamHead, ST
|
||||
/* EA decoder list and known internal FourCCs */
|
||||
switch(eaac.codec) {
|
||||
|
||||
case EAAC_CODEC_PCM: /* "P6B0": PCM16BE [NBA Jam (Wii)] */
|
||||
case EAAC_CODEC_PCM16BE: /* "P6B0": PCM16BE [NBA Jam (Wii)] */
|
||||
vgmstream->coding_type = coding_PCM16_int;
|
||||
vgmstream->codec_endian = 1;
|
||||
vgmstream->layout_type = layout_blocked_ea_sns;
|
||||
@ -1003,7 +1002,7 @@ static VGMSTREAM * init_vgmstream_eaaudiocore_header(STREAMFILE * streamHead, ST
|
||||
}
|
||||
#endif
|
||||
|
||||
case EAAC_CODEC_XAS: /* "Xas1": EA-XAS [Dead Space (PC/PS3)] */
|
||||
case EAAC_CODEC_XAS1: /* "Xas1": EA-XAS v1 [Dead Space (PC/PS3)] */
|
||||
|
||||
/* special (if hacky) loop handling, see comments */
|
||||
if (eaac.loop_start > 0) {
|
||||
@ -1053,7 +1052,7 @@ static VGMSTREAM * init_vgmstream_eaaudiocore_header(STREAMFILE * streamHead, ST
|
||||
}
|
||||
#endif
|
||||
|
||||
case EAAC_CODEC_DSP: /* "Gca0"?: DSP [Need for Speed: Nitro (Wii) sfx] */
|
||||
case EAAC_CODEC_GCADPCM: /* "Gca0": DSP [Need for Speed: Nitro (Wii) sfx] */
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->layout_type = layout_blocked_ea_sns;
|
||||
/* DSP coefs are read in the blocks */
|
||||
@ -1148,7 +1147,9 @@ fail:
|
||||
}
|
||||
|
||||
static size_t get_snr_size(STREAMFILE *streamFile, off_t offset) {
|
||||
switch (read_8bit(offset + 0x04, streamFile) >> 4 & 0x0F) { /* flags */
|
||||
const int EAAC_FLAG_LOOPED = 0x02;
|
||||
const int EAAC_FLAG_STREAMED = 0x04;
|
||||
switch (read_8bit(offset + 0x04, streamFile) >> 4 & 0x0F) { /* flags */ //todo improve
|
||||
case EAAC_FLAG_LOOPED | EAAC_FLAG_STREAMED: return 0x10;
|
||||
case EAAC_FLAG_LOOPED: return 0x0C;
|
||||
default: return 0x08;
|
||||
@ -1242,8 +1243,7 @@ static segmented_layout_data* build_segmented_eaaudiocore_looping(STREAMFILE *st
|
||||
}
|
||||
#endif
|
||||
|
||||
case EAAC_CODEC_XAS:
|
||||
{
|
||||
case EAAC_CODEC_XAS1: {
|
||||
start_offset = offsets[i];
|
||||
|
||||
data->segments[i]->coding_type = coding_EA_XAS_V1;
|
||||
|
Loading…
x
Reference in New Issue
Block a user