From 4ff41aa0ef52feea3bccc9abf82af3197033fa76 Mon Sep 17 00:00:00 2001 From: NicknineTheEagle Date: Mon, 11 Feb 2019 12:37:11 +0300 Subject: [PATCH] Added support for EA TMX format --- src/formats.c | 1 + src/meta/ea_eaac.c | 50 +++++++++++++++++++++++++++++++++++++++++++++- src/meta/gin.c | 39 ++++++++++++++++++++++++------------ src/meta/meta.h | 1 + src/vgmstream.c | 1 + 5 files changed, 78 insertions(+), 14 deletions(-) diff --git a/src/formats.c b/src/formats.c index 658713d7..d16589cd 100644 --- a/src/formats.c +++ b/src/formats.c @@ -427,6 +427,7 @@ static const char* extension_list[] = { "tgq", "thp", "tk5", + "tmx", "tra", "tun", "txth", diff --git a/src/meta/ea_eaac.c b/src/meta/ea_eaac.c index 7bb88023..aae9d432 100644 --- a/src/meta/ea_eaac.c +++ b/src/meta/ea_eaac.c @@ -36,7 +36,7 @@ static VGMSTREAM * init_vgmstream_eaaudiocore_header(STREAMFILE * streamHead, STREAMFILE * streamData, off_t header_offset, off_t start_offset, meta_t meta_type); static size_t get_snr_size(STREAMFILE *streamFile, off_t offset); static VGMSTREAM *parse_s10a_header(STREAMFILE *streamFile, off_t offset, uint16_t target_index, off_t ast_offset); - +VGMSTREAM * init_vgmstream_gin_header(STREAMFILE *streamFile, off_t offset); /* .SNR+SNS - from EA latest games (~2008-2013), v0 header */ @@ -569,6 +569,54 @@ fail: return NULL; } +/* EA TMX - used for engine sounds in NFS games (2007-present) */ +VGMSTREAM * init_vgmstream_ea_tmx(STREAMFILE *streamFile) { + uint32_t num_sounds, sound_type; + off_t table_offset, data_offset, entry_offset, sound_offset, sns_offset; + VGMSTREAM *vgmstream = NULL; + int target_stream = streamFile->stream_index; + + if (!check_extensions(streamFile, "tmx")) + goto fail; + + /* always little endian */ + if (read_32bitLE(0x0c, streamFile) != 0x30303031) /* "0001" */ + goto fail; + + num_sounds = read_32bitLE(0x20, streamFile); + table_offset = read_32bitLE(0x58, streamFile); + data_offset = read_32bitLE(0x5c, streamFile); + + if (target_stream == 0) target_stream = 1; + if (target_stream < 0 || num_sounds == 0 || target_stream > num_sounds) + goto fail; + + entry_offset = table_offset + (target_stream - 1) * 0x24; + sound_type = read_32bitLE(entry_offset + 0x00, streamFile); + sound_offset = read_32bitLE(entry_offset + 0x08, streamFile) + data_offset; + + switch (sound_type) { + case 0x47494E20: /* "GIN " */ + /* FIXME: need to get GIN size somehow */ + vgmstream = init_vgmstream_gin_header(streamFile, sound_offset); + if (!vgmstream) goto fail; + break; + case 0x534E5220: /* "SNR " */ + sns_offset = sound_offset + get_snr_size(streamFile, sound_offset); + vgmstream = init_vgmstream_eaaudiocore_header(streamFile, streamFile, sound_offset, sns_offset, meta_EA_SNR_SNS); + if (!vgmstream) goto fail; + break; + default: + goto fail; + } + + vgmstream->num_streams = num_sounds; + return vgmstream; + +fail: + return NULL; +} + /* EA Harmony Sample Bank - used in 8th gen EA Sports games */ VGMSTREAM * init_vgmstream_ea_sbr_harmony(STREAMFILE *streamFile) { uint32_t num_dsets, set_sounds, chunk_id; diff --git a/src/meta/gin.c b/src/meta/gin.c index 36953a6e..eb9a02a1 100644 --- a/src/meta/gin.c +++ b/src/meta/gin.c @@ -1,18 +1,32 @@ #include "meta.h" #include "../coding/coding.h" +VGMSTREAM * init_vgmstream_gin_header(STREAMFILE *streamFile, off_t offset); + /* .gin - EA engine sounds [Need for Speed: Most Wanted (multi)] */ VGMSTREAM * init_vgmstream_gin(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count, sample_rate, num_samples; - - /* checks */ if (!check_extensions(streamFile, "gin")) goto fail; - if (read_32bitBE(0x00,streamFile) != 0x476E7375) /* "Gnsu" */ + vgmstream = init_vgmstream_gin_header(streamFile, 0x00); + if (!vgmstream) + goto fail; + + return vgmstream; + +fail: + return NULL; +} + +VGMSTREAM * init_vgmstream_gin_header(STREAMFILE *streamFile, off_t offset) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + int loop_flag, channel_count, sample_rate, num_samples; + + /* checks */ + if (read_32bitBE(offset + 0x00, streamFile) != 0x476E7375) /* "Gnsu" */ goto fail; /* contains mapped values for engine RPM sounds but we'll just play the whole thing */ @@ -22,11 +36,11 @@ VGMSTREAM * init_vgmstream_gin(STREAMFILE *streamFile) { /* 0x14: RPM ??? table size */ /* always LE even on X360/PS3 */ - num_samples = read_32bitLE(0x18, streamFile); - sample_rate = read_32bitLE(0x1c, streamFile); - start_offset = 0x20 + - (read_32bitLE(0x10, streamFile) + 1) * 0x04 + - (read_32bitLE(0x14, streamFile) + 1) * 0x04; + num_samples = read_32bitLE(offset + 0x18, streamFile); + sample_rate = read_32bitLE(offset + 0x1c, streamFile); + start_offset = offset + 0x20 + + (read_32bitLE(offset + 0x10, streamFile) + 1) * 0x04 + + (read_32bitLE(offset + 0x14, streamFile) + 1) * 0x04; channel_count = 1; loop_flag = 0; @@ -40,10 +54,9 @@ VGMSTREAM * init_vgmstream_gin(STREAMFILE *streamFile) { vgmstream->num_samples = num_samples; vgmstream->coding_type = coding_EA_XAS_V0; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x13; + vgmstream->layout_type = layout_none; - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) goto fail; return vgmstream; diff --git a/src/meta/meta.h b/src/meta/meta.h index 66b4b4a2..6f031b44 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -684,6 +684,7 @@ VGMSTREAM * init_vgmstream_ea_sps(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_ea_abk_eaac(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_ea_hdr_sth_dat(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_ea_mpf_mus_eaac(STREAMFILE * streamFile); +VGMSTREAM * init_vgmstream_ea_tmx(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_ea_sbr(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_ea_sbr_harmony(STREAMFILE * streamFile); diff --git a/src/vgmstream.c b/src/vgmstream.c index bc8722eb..5ec7deb4 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -381,6 +381,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = { init_vgmstream_ea_abk_eaac, init_vgmstream_ea_hdr_sth_dat, init_vgmstream_ea_mpf_mus_eaac, + init_vgmstream_ea_tmx, init_vgmstream_ea_sbr, init_vgmstream_ea_sbr_harmony, init_vgmstream_ngc_vid1,