diff --git a/src/formats.c b/src/formats.c index 1eb4585a..7000bb45 100644 --- a/src/formats.c +++ b/src/formats.c @@ -1101,7 +1101,7 @@ static const meta_info meta_info_list[] = { {meta_CAFF, "Apple Core Audio Format File header"}, {meta_PC_MXST, "Lego Island MxSt Header"}, {meta_SAB, "Sensaura SAB header"}, - {meta_MAXIS_XA, "Maxis XAI/XAJ Header"}, + {meta_MAXIS_XA, "Maxis XA Header"}, {meta_EXAKT_SC, "assumed Activision / EXAKT SC by extension"}, {meta_WII_BNS, "Nintendo BNS header"}, {meta_WII_WAS, "Sumo Digital iSWS header"}, diff --git a/src/meta/maxis_xa.c b/src/meta/maxis_xa.c index b0c3a5cb..a3d42134 100644 --- a/src/meta/maxis_xa.c +++ b/src/meta/maxis_xa.c @@ -1,32 +1,46 @@ #include "meta.h" #include "../util.h" -/* Maxis XA - found in Sim City 3000 (PC) */ +/* Maxis XA - found in Sim City 3000 (PC), The Sims 2 (PC) */ VGMSTREAM * init_vgmstream_maxis_xa(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; off_t start_offset; - int loop_flag, channel_count; + int avg_byte_rate, channel_count, loop_flag, resolution, sample_align, sample_rate; /* check extension, case insensitive */ if (!check_extensions(streamFile,"xa")) goto fail; /* check header */ - if ((read_32bitBE(0x00,streamFile) != 0x58414900) && /* "XAI\0" (sound/speech) */ - (read_32bitBE(0x00,streamFile) != 0x58414A00) && /* "XAJ\0" (music, no apparent diffs) */ - (read_32bitBE(0x00,streamFile) != 0x58410000) && /* "XA\0\0" (sound/speech from The Sims 2, no apparent diffs) */ - (read_32bitBE(0x00,streamFile) != 0x58411200)) /* "XA\x12\0" (music from The Sims 2, no apparent diffs) */ + if ((read_16bitBE(0x00,streamFile) != 0x5841)) /* "XA" */ + goto fail; + + /* check format tag */ + if ((read_16bitLE(0x08,streamFile) != 0x0001)) + goto fail; + + channel_count = read_16bitLE(0x0A,streamFile); + sample_rate = read_32bitLE(0x0C,streamFile); + avg_byte_rate = read_32bitLE(0x10,streamFile); + sample_align = read_16bitLE(0x14,streamFile); + resolution = read_16bitLE(0x16,streamFile); + + /* check alignment */ + if (sample_align != (resolution/8)*channel_count) + goto fail; + + /* check average byte rate */ + if (avg_byte_rate != sample_rate*sample_align) goto fail; loop_flag = 0; - channel_count = read_16bitLE(0x0A,streamFile); start_offset = 0x18; /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - vgmstream->sample_rate = read_32bitLE(0x0C,streamFile); + vgmstream->sample_rate = sample_rate; vgmstream->num_samples = read_32bitLE(0x04,streamFile)/2/channel_count; vgmstream->meta_type = meta_MAXIS_XA;