From 27cf174b80498e3725e91a0b12fdfb625c3ddb50 Mon Sep 17 00:00:00 2001 From: NicknineTheEagle Date: Tue, 26 Oct 2021 00:01:27 +0300 Subject: [PATCH] EA SCHl: Removed the hack merging multiple sounds in one bigfile --- src/layout/blocked_ea_schl.c | 33 ++------------------- src/meta/ea_schl.c | 56 +++++++++++------------------------- 2 files changed, 20 insertions(+), 69 deletions(-) diff --git a/src/layout/blocked_ea_schl.c b/src/layout/blocked_ea_schl.c index 8cded149..a2126365 100644 --- a/src/layout/blocked_ea_schl.c +++ b/src/layout/blocked_ea_schl.c @@ -44,36 +44,9 @@ void block_update_ea_schl(off_t block_offset, VGMSTREAM * vgmstream) { block_samples = 0; /* layout ignores this */ } -#ifdef VGM_USE_MPEG - /* "SCHl" start block, when decoding multi files pasted together */ - if (block_id == 0x5343486C) { - switch(vgmstream->coding_type) { - case coding_MPEG_custom: - case coding_MPEG_layer1: - case coding_MPEG_layer2: - case coding_MPEG_layer3: - case coding_MPEG_ealayer3: - /* need to reset MPEG decoder to reset discards and trailing samples in the buffers */ - flush_mpeg(vgmstream->codec_data); - break; - default: - break; - } - } -#endif - /* padding between "SCEl" and next "SCHl" (when subfiles exist) */ - if (block_id == 0x00000000) - block_size = 0x04; - - /* guard against errors (happens in bad rips/endianness, observed max is vid ~0x20000) */ - if (block_size == 0x00 || block_size > 0xFFFFF || block_samples > 0xFFFF) { - block_size = 0x04; - block_samples = 0; - } - - /* "SCEl" end chunk should be 32b-aligned, fixes some multi-SCHl [ex. Need for Speed 2 (PC) .eam] */ - if (((block_offset + block_size) % 0x04) && block_id == 0x5343456C) { - block_size += 0x04 - ((block_offset + block_size) % 0x04); + if (block_id == 0x00000000 || block_id == 0xFFFFFFFF || block_id == 0x5343456C) { /* EOF */ + vgmstream->current_block_samples = -1; + return; } } diff --git a/src/meta/ea_schl.c b/src/meta/ea_schl.c index b57dda35..851bfe6c 100644 --- a/src/meta/ea_schl.c +++ b/src/meta/ea_schl.c @@ -127,8 +127,8 @@ static VGMSTREAM * parse_bnk_header(STREAMFILE* sf, off_t offset, int target_str static int parse_variable_header(STREAMFILE* sf, ea_header* ea, off_t begin_offset, int max_length, int bnk_version); static uint32_t read_patch(STREAMFILE* sf, off_t* offset); static off_t get_ea_stream_mpeg_start_offset(STREAMFILE* sf, off_t start_offset, const ea_header* ea); -static VGMSTREAM* init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header* ea, off_t start_offset, int is_bnk, int standalone); -static void update_ea_stream_size_and_samples(STREAMFILE* sf, off_t start_offset, VGMSTREAM* vgmstream, int standalone); +static VGMSTREAM* init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header* ea, off_t start_offset, int is_bnk); +static void update_ea_stream_size(STREAMFILE* sf, off_t start_offset, VGMSTREAM* vgmstream); /* EA SCHl with variable header - from EA games (roughly 1997~2010); generated by EA Canada's sx.exe/Sound eXchange */ VGMSTREAM* init_vgmstream_ea_schl(STREAMFILE* sf) { @@ -150,9 +150,8 @@ VGMSTREAM* init_vgmstream_ea_schl(STREAMFILE* sf) { * .hab: GoldenEye - Rogue Agent (inside .big) * .xsf: 007 - Agent Under Fire (Xbox) * .gsf: 007 - Everything or Nothing (GC) - * .mus: map/mpf+mus only? * (extensionless): SSX (PS2) (inside .big) */ - if (!check_extensions(sf,"asf,lasf,str,chk,eam,exa,sng,aud,sx,xa,strm,stm,hab,xsf,gsf,mus,")) + if (!check_extensions(sf,"asf,lasf,str,chk,eam,exa,sng,aud,sx,xa,strm,stm,hab,xsf,gsf,")) goto fail; /* check header */ @@ -284,10 +283,9 @@ VGMSTREAM* init_vgmstream_ea_bnk(STREAMFILE* sf) { /* check extension */ /* .bnk: common * .sdt: Harry Potter games - * .mus: streams/jingles (rare) * .abk: GoldenEye - Rogue Agent * .ast: FIFA 2004 (inside .big) */ - if (!check_extensions(sf,"bnk,sdt,mus,abk,ast")) + if (!check_extensions(sf,"bnk,sdt,abk,ast")) goto fail; if (target_stream == 0) target_stream = 1; @@ -1132,7 +1130,7 @@ static VGMSTREAM* parse_schl_block(STREAMFILE* sf, off_t offset, int standalone) start_offset = offset + header_size; /* starts in "SCCl" (skipped in block layout) or very rarely "SCDl" and maybe movie blocks */ /* rest is common */ - return init_vgmstream_ea_variable_header(sf, &ea, start_offset, 0, standalone); + return init_vgmstream_ea_variable_header(sf, &ea, start_offset, 0); fail: return NULL; @@ -1223,7 +1221,7 @@ static VGMSTREAM* parse_bnk_header(STREAMFILE* sf, off_t offset, int target_stre start_offset = ea.offsets[0]; /* first channel, presumably needed for MPEG */ /* rest is common */ - vgmstream = init_vgmstream_ea_variable_header(sf, &ea, start_offset, bnk_version, 0); + vgmstream = init_vgmstream_ea_variable_header(sf, &ea, start_offset, bnk_version); if (!vgmstream) goto fail; if (!is_embedded) { vgmstream->num_streams = real_bnk_sounds; @@ -1236,7 +1234,7 @@ fail: } /* inits VGMSTREAM from a EA header */ -static VGMSTREAM* init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header* ea, off_t start_offset, int bnk_version, int standalone) { +static VGMSTREAM* init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header* ea, off_t start_offset, int bnk_version) { VGMSTREAM* vgmstream = NULL; int i, ch; int is_bnk = bnk_version; @@ -1492,7 +1490,7 @@ static VGMSTREAM* init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header* e /* TODO: Figure out how to get stream size for BNK sounds */ } else { - update_ea_stream_size_and_samples(sf, start_offset, vgmstream, standalone); + update_ea_stream_size(sf, start_offset, vgmstream); } return vgmstream; @@ -1903,18 +1901,18 @@ fail: return 0; } -static void update_ea_stream_size_and_samples(STREAMFILE* sf, off_t start_offset, VGMSTREAM *vgmstream, int standalone) { +static void update_ea_stream_size(STREAMFILE* sf, off_t start_offset, VGMSTREAM *vgmstream) { uint32_t block_id; - int32_t num_samples = 0; size_t stream_size = 0, file_size; - int multiple_schl = 0; - - file_size = get_streamfile_size(sf); /* formats with custom codecs */ - if (vgmstream->layout_type != layout_blocked_ea_schl) { + if (vgmstream->layout_type != layout_blocked_ea_schl) return; - } + + if (vgmstream->stream_size != 0) + return; + + file_size = get_streamfile_size(sf); /* manually read totals */ vgmstream->next_block_offset = start_offset; @@ -1925,20 +1923,10 @@ static void update_ea_stream_size_and_samples(STREAMFILE* sf, off_t start_offset block_id = read_32bitBE(vgmstream->current_block_offset + 0x00, sf); if (block_id == EA_BLOCKID_END) { /* banks should never contain movie "SHxx" */ - if (!standalone) - break; - } - else if (block_id == EA_BLOCKID_HEADER) { /* "SCHl" start block (movie "SHxx" shouldn't use multi files) */ - multiple_schl = 1; + break; } if (vgmstream->current_block_samples > 0) { - /* HACK: fix num_samples for streams with multiple SCHl. Need to eventually get rid of this. - * Get total samples by parsing block headers, needed when multiple files are stitched together. - * Some EA files (.mus/eam/sng/etc) concat many small subfiles, used for interactive/mapped - * music (.map/lin). Subfiles always share header, except num_samples. */ - num_samples += vgmstream->current_block_samples; - /* stream size is almost never provided in bank files so we have to calc it manually */ stream_size += vgmstream->next_block_offset - vgmstream->ch[0].offset; } @@ -1946,17 +1934,7 @@ static void update_ea_stream_size_and_samples(STREAMFILE* sf, off_t start_offset /* reset once we're done */ block_update_ea_schl(start_offset, vgmstream); - - /* only use calculated samples with multiple subfiles (rarely header samples may be less due to padding) */ - if (standalone && multiple_schl) { - VGM_LOG("EA SCHl: multiple SCHl found\n"); - if (num_samples > vgmstream->num_samples) { - vgmstream->num_samples = num_samples; - } - } - - if (vgmstream->stream_size == 0) - vgmstream->stream_size = stream_size; + vgmstream->stream_size = stream_size; } /* find data start offset inside the first SCDl; not very elegant but oh well */