From d0211e2d850ef3a76258cbbd47740321a25d6fb1 Mon Sep 17 00:00:00 2001 From: NicknineTheEagle Date: Tue, 25 Feb 2020 21:52:14 +0300 Subject: [PATCH] EAAC: Fixed size calculation --- src/meta/ea_eaac.c | 51 ++++++++++++++++++++++++++-------------------- 1 file changed, 29 insertions(+), 22 deletions(-) diff --git a/src/meta/ea_eaac.c b/src/meta/ea_eaac.c index b8323f9e..5db362cf 100644 --- a/src/meta/ea_eaac.c +++ b/src/meta/ea_eaac.c @@ -965,7 +965,7 @@ typedef struct { static segmented_layout_data* build_segmented_eaaudiocore_looping(STREAMFILE *sf_data, eaac_header *eaac); static layered_layout_data* build_layered_eaaudiocore(STREAMFILE *streamFile, eaac_header *eaac, off_t start_offset); static STREAMFILE *setup_eaac_streamfile(eaac_header *ea, STREAMFILE *streamHead, STREAMFILE *streamData); -static size_t calculate_eaac_size(STREAMFILE *streamFile, eaac_header *ea, uint32_t num_samples, off_t start_offset); +static size_t calculate_eaac_size(STREAMFILE *streamFile, eaac_header *ea, uint32_t num_samples, off_t start_offset, int is_ram); /* EA newest header from RwAudioCore (RenderWare?) / EAAudioCore library (still generated by sx.exe). * Audio "assets" come in separate RAM headers (.SNR/SPH) and raw blocked streams (.SNS/SPS), @@ -1293,43 +1293,50 @@ fail: return NULL; } -static size_t calculate_eaac_size(STREAMFILE *streamFile, eaac_header *ea, uint32_t num_samples, off_t start_offset) { - uint32_t samples_parsed, block_size, block_samples; +static size_t calculate_eaac_size(STREAMFILE *streamFile, eaac_header *ea, uint32_t num_samples, off_t start_offset, int is_ram) { + uint32_t block_size; uint8_t block_id; size_t stream_size, file_size; off_t block_offset; + int looped; file_size = get_streamfile_size(streamFile); block_offset = start_offset; - stream_size = 0, samples_parsed = 0; + stream_size = 0; + looped = 0; - while (block_offset < file_size && samples_parsed < num_samples) { + while (block_offset < file_size) { block_id = read_8bit(block_offset, streamFile); block_size = read_32bitBE(block_offset, streamFile) & 0x00FFFFFF; + /* stop when we reach the end marker */ if (ea->version == EAAC_VERSION_V0) { if (block_id != EAAC_BLOCKID0_DATA && block_id != EAAC_BLOCKID0_END) goto fail; } else { - if (block_id != EAAC_BLOCKID1_DATA) { - if (block_id == EAAC_BLOCKID1_END && ea->codec == EAAC_CODEC_EATRAX) { - /* number of samples in block header is wrong for EATrax so stop when we reach end marker */ - return stream_size; - } + if (block_id == EAAC_BLOCKID1_END) + break; + if (block_id != EAAC_BLOCKID1_DATA) goto fail; - } } - block_samples = read_32bitBE(block_offset + 0x04, streamFile); - stream_size += block_size; - samples_parsed += block_samples; block_offset += block_size; - } - if (samples_parsed != num_samples) - goto fail; + /* RAM data only consists of one block */ + if (is_ram) + break; + + if (ea->version == EAAC_VERSION_V0 && block_id == EAAC_BLOCKID0_END) { + if (ea->loop_offset > 0) { + if (!looped) looped = 1; + else break; + } else { + break; + } + } + } return stream_size; @@ -1348,7 +1355,7 @@ static STREAMFILE *setup_eaac_streamfile(eaac_header *ea, STREAMFILE *streamHead switch (ea->type) { case EAAC_TYPE_RAM: /* both header and data in SNR */ - data_size = calculate_eaac_size(streamHead, ea, ea->num_samples, ea->stream_offset); + data_size = calculate_eaac_size(streamHead, ea, ea->num_samples, ea->stream_offset, 1); if (data_size == 0) goto fail; new_streamFile = open_wrap_streamfile(streamHead); @@ -1361,7 +1368,7 @@ static STREAMFILE *setup_eaac_streamfile(eaac_header *ea, STREAMFILE *streamHead break; case EAAC_TYPE_STREAM: /* header in SNR, data in SNS */ - data_size = calculate_eaac_size(streamData, ea, ea->num_samples, ea->stream_offset); + data_size = calculate_eaac_size(streamData, ea, ea->num_samples, ea->stream_offset, 0); if (data_size == 0) goto fail; new_streamFile = open_wrap_streamfile(streamData); @@ -1375,7 +1382,7 @@ static STREAMFILE *setup_eaac_streamfile(eaac_header *ea, STREAMFILE *streamHead case EAAC_TYPE_GIGASAMPLE: /* header and prefetched data in SNR, rest of data in SNS */ /* open prefetched data */ - data_size = calculate_eaac_size(streamHead, ea, ea->prefetch_samples, ea->prefetch_offset); + data_size = calculate_eaac_size(streamHead, ea, ea->prefetch_samples, ea->prefetch_offset, 1); if (data_size == 0) goto fail; new_streamFile = open_wrap_streamfile(streamHead); @@ -1387,7 +1394,7 @@ static STREAMFILE *setup_eaac_streamfile(eaac_header *ea, STREAMFILE *streamHead stream_segments[0] = new_streamFile; /* open main data */ - data_size = calculate_eaac_size(streamData, ea, ea->num_samples - ea->prefetch_samples, ea->stream_offset); + data_size = calculate_eaac_size(streamData, ea, ea->num_samples - ea->prefetch_samples, ea->stream_offset, 0); if (data_size == 0) goto fail; new_streamFile = open_wrap_streamfile(streamData); @@ -1412,7 +1419,7 @@ static STREAMFILE *setup_eaac_streamfile(eaac_header *ea, STREAMFILE *streamHead goto fail; } - data_size = calculate_eaac_size(streamHead, ea, ea->num_samples, ea->stream_offset); + data_size = calculate_eaac_size(streamHead, ea, ea->num_samples, ea->stream_offset, ea->type == EAAC_TYPE_RAM); if (data_size == 0) goto fail; new_streamFile = open_wrap_streamfile(streamHead);