EA SCHl: Calculate stream size for bitrate

This commit is contained in:
NicknineTheEagle 2018-12-27 21:20:28 +03:00
parent 268a6a4319
commit 54cf2e04fc

View File

@ -103,6 +103,7 @@ static int parse_variable_header(STREAMFILE* streamFile, ea_header* ea, off_t be
static uint32_t read_patch(STREAMFILE* streamFile, off_t* offset);
static off_t get_ea_stream_mpeg_start_offset(STREAMFILE* streamFile, off_t start_offset, const ea_header* ea);
static VGMSTREAM * init_vgmstream_ea_variable_header(STREAMFILE *streamFile, ea_header *ea, off_t start_offset, int is_bnk);
static int get_ea_stream_size(STREAMFILE* streamFile, 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 *streamFile) {
@ -378,10 +379,10 @@ VGMSTREAM * init_vgmstream_ea_map_mus(STREAMFILE *streamFile) {
* 0x07: userdata entry size (incorrect?)
* 0x08: three zeroes
* 0x0b: number of userdata entries
* 0x0c: section 1 start
*/
num_sounds = read_8bit(0x06, streamFile);
num_userdata = read_8bit(0x0b, streamFile);
section_offset = 0x0c;
/* section 1: contains information about segment playback order */
@ -456,7 +457,7 @@ VGMSTREAM * init_vgmstream_ea_mpf_mus(STREAMFILE *streamFile) {
section_offset = 0x20;
entry_offset = read_16bit(section_offset + (sec1_num - 1) * 0x02, streamFile) * 0x04;
/* HACK: there's some weird bitstream here that's store differently in LE and BE */
/* HACK: there's some weird bitstream here that's stored differently in LE and BE */
/* I can't figure it out, so let's just use a workaround for now */
if (read_32bitBE(0x00, streamFile) == 0x50464478) {
subentry_num = (read_32bitBE(entry_offset + 0x04, streamFile) >> 15) & 0xFF;
@ -673,8 +674,6 @@ static VGMSTREAM * init_vgmstream_ea_variable_header(STREAMFILE *streamFile, ea_
vgmstream->layout_type = layout_blocked_ea_schl;
}
//vgmstream->stream_size = ; //todo needed for kbps info
/* 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).
* Unneeded codecs are removed over time (ex. LAYER3 when EALAYER3 was introduced). */
@ -856,6 +855,11 @@ static VGMSTREAM * init_vgmstream_ea_variable_header(STREAMFILE *streamFile, ea_
vgmstream->ch[i].offset = ea->offsets[i];
}
}
/* TODO: Figure out how to get stream size for BNK sounds */
}
else {
vgmstream->stream_size = get_ea_stream_size(streamFile, start_offset, vgmstream);
}
return vgmstream;
@ -1245,6 +1249,33 @@ fail:
return 0;
}
/* Stream size is almost never provided in bank files so we have to calc it manually */
static int get_ea_stream_size(STREAMFILE* streamFile, off_t start_offset, VGMSTREAM *vgmstream) {
size_t stream_size, block_size;
uint32_t block_id;
off_t block_offset;
stream_size = 0;
block_offset = start_offset;
while (1) {
block_id = read_32bitBE(block_offset + 0x00, streamFile);
if (block_id == EA_BLOCKID_END)
break;
if (vgmstream->codec_config & 0x02) /* size is always LE, except in early SS/MAC */
block_size = read_32bitBE(block_offset + 0x04, streamFile);
else
block_size = read_32bitLE(block_offset + 0x04, streamFile);
stream_size += block_size - 0x08;
block_offset += block_size;
}
return stream_size;
}
/* find data start offset inside the first SCDl; not very elegant but oh well */
static off_t get_ea_stream_mpeg_start_offset(STREAMFILE* streamFile, off_t start_offset, const ea_header* ea) {
size_t file_size = get_streamfile_size(streamFile);