From 9fd85f667061f31498aef45c102a975716878357 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Mon, 21 Feb 2022 16:44:18 -0800 Subject: [PATCH] Updated VGMStream to r1702-76-g00bdb165 Signed-off-by: Christopher Snowhill --- .../vgmstream/vgmstream/src/coding/coding.h | 21 +++-- .../vgmstream/src/coding/ima_decoder.c | 24 +++++ .../vgmstream/src/layout/blocked_ea_schl.c | 2 +- .../vgmstream/vgmstream/src/meta/ea_eaac.c | 88 +++++++++---------- .../vgmstream/vgmstream/src/meta/ea_schl.c | 2 +- Frameworks/vgmstream/vgmstream/src/meta/fsb.c | 30 ++++--- .../vgmstream/vgmstream/src/meta/hca_keys.h | 5 ++ .../vgmstream/vgmstream/src/meta/ktac.c | 19 ++-- .../vgmstream/vgmstream/src/meta/musx.c | 25 +++++- .../vgmstream/vgmstream/src/meta/ps2_mic.c | 6 +- Frameworks/vgmstream/vgmstream/src/meta/wbk.c | 22 ++++- 11 files changed, 151 insertions(+), 93 deletions(-) diff --git a/Frameworks/vgmstream/vgmstream/src/coding/coding.h b/Frameworks/vgmstream/vgmstream/src/coding/coding.h index eac0cd889..d9c237e86 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/coding.h +++ b/Frameworks/vgmstream/vgmstream/src/coding/coding.h @@ -48,7 +48,7 @@ size_t ms_ima_bytes_to_samples(size_t bytes, int block_align, int channels); size_t xbox_ima_bytes_to_samples(size_t bytes, int channels); size_t dat4_ima_bytes_to_samples(size_t bytes, int channels); size_t apple_ima4_bytes_to_samples(size_t bytes, int channels); - +int xbox_check_format(STREAMFILE* sf, uint32_t offset, uint32_t max, int channels); /* ngc_dsp_decoder */ void decode_ngc_dsp(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); @@ -430,6 +430,15 @@ void seek_vorbis_custom(VGMSTREAM* vgmstream, int32_t num_sample); void free_vorbis_custom(vorbis_custom_codec_data* data); #endif +typedef struct { + int version; + int layer; + int bit_rate; + int sample_rate; + int frame_samples; + int frame_size; /* bytes */ + int channels; +} mpeg_frame_info; #ifdef VGM_USE_MPEG /* mpeg_decoder */ @@ -482,16 +491,6 @@ void free_mpeg(mpeg_codec_data* data); int mpeg_get_sample_rate(mpeg_codec_data* data); long mpeg_bytes_to_samples(long bytes, const mpeg_codec_data* data); -typedef struct { - int version; - int layer; - int bit_rate; - int sample_rate; - int frame_samples; - int frame_size; /* bytes */ - int channels; -} mpeg_frame_info; - int mpeg_get_frame_info(STREAMFILE* sf, off_t offset, mpeg_frame_info* info); #endif diff --git a/Frameworks/vgmstream/vgmstream/src/coding/ima_decoder.c b/Frameworks/vgmstream/vgmstream/src/coding/ima_decoder.c index 14f14a1db..a6ec41acf 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/ima_decoder.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/ima_decoder.c @@ -1326,3 +1326,27 @@ size_t apple_ima4_bytes_to_samples(size_t bytes, int channels) { return (bytes / block_align) * (block_align - 0x02*channels) * 2 / channels + ((bytes % block_align) ? ((bytes % block_align) - 0x02*channels) * 2 / channels : 0); } + + +/* test XBOX-ADPCM frames for correctness */ +int xbox_check_format(STREAMFILE* sf, uint32_t offset, uint32_t max, int channels) { + off_t max_offset = offset + max; + int ch; + + if (max_offset > get_streamfile_size(sf)) + max_offset = get_streamfile_size(sf); + if (!channels) + return 0; + + while (offset < max_offset) { + for (ch = 0; ch < channels; ch++) { + uint16_t step = read_u16le(offset + 0x04 * ch + 0x02,sf); + if (step > 88) + return 0; + } + + offset += 0x24 * channels; + } + + return 1; +} diff --git a/Frameworks/vgmstream/vgmstream/src/layout/blocked_ea_schl.c b/Frameworks/vgmstream/vgmstream/src/layout/blocked_ea_schl.c index d23cbea0d..5f53af65f 100644 --- a/Frameworks/vgmstream/vgmstream/src/layout/blocked_ea_schl.c +++ b/Frameworks/vgmstream/vgmstream/src/layout/blocked_ea_schl.c @@ -192,7 +192,7 @@ void block_update_ea_schl(off_t block_offset, VGMSTREAM * vgmstream) { for (i = 0; i < vgmstream->channels; i++) { //vgmstream->ch[i].adpcm_history1_32 = read_16bit(vgmstream->ch[i].offset+0x00,streamFile); //vgmstream->ch[i].adpcm_history3_32 = read_16bit(vgmstream->ch[i].offset+0x02,streamFile); - vgmstream->ch[i].offset += 4; + vgmstream->ch[i].offset += 0x04; } } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ea_eaac.c b/Frameworks/vgmstream/vgmstream/src/meta/ea_eaac.c index f95f10b49..1c82d55c6 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ea_eaac.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ea_eaac.c @@ -285,48 +285,49 @@ fail: /* EA SBR/SBS - used in older 7th gen games for storing SFX */ VGMSTREAM* init_vgmstream_ea_sbr(STREAMFILE* sf) { - uint32_t i, num_sounds, type_desc; - uint16_t num_metas, meta_type; - off_t table_offset, types_offset, entry_offset, metas_offset, data_offset, snr_offset, sns_offset; - STREAMFILE *sbsFile = NULL; + uint32_t num_sounds, sound_id, type_desc, num_items, item_type, + table_offset, types_offset, entry_offset, items_offset, data_offset, snr_offset, sns_offset; + uint32_t i; + STREAMFILE *sf_sbs = NULL; VGMSTREAM* vgmstream = NULL; int target_stream = sf->stream_index; if (!check_extensions(sf, "sbr")) goto fail; - if (read_32bitBE(0x00, sf) != 0x53424B52) /* "SBKR" */ + if (read_u32be(0x00, sf) != 0x53424B52) /* "SBKR" */ goto fail; /* SBR files are always big endian */ - num_sounds = read_32bitBE(0x1c, sf); - table_offset = read_32bitBE(0x24, sf); - types_offset = read_32bitBE(0x28, sf); + num_sounds = read_u32be(0x1c, sf); + table_offset = read_u32be(0x24, sf); + types_offset = read_u32be(0x28, sf); if (target_stream == 0) target_stream = 1; if (target_stream < 0 || num_sounds == 0 || target_stream > num_sounds) goto fail; entry_offset = table_offset + 0x0a * (target_stream - 1); - num_metas = read_16bitBE(entry_offset + 0x04, sf); - metas_offset = read_32bitBE(entry_offset + 0x06, sf); + sound_id = read_u32be(entry_offset + 0x00, sf); + num_items = read_u16be(entry_offset + 0x04, sf); + items_offset = read_u32be(entry_offset + 0x06, sf); snr_offset = 0; sns_offset = 0; - for (i = 0; i < num_metas; i++) { - entry_offset = metas_offset + 0x06 * i; - meta_type = read_16bitBE(entry_offset + 0x00, sf); - data_offset = read_32bitBE(entry_offset + 0x02, sf); + for (i = 0; i < num_items; i++) { + entry_offset = items_offset + 0x06 * i; + item_type = read_u16be(entry_offset + 0x00, sf); + data_offset = read_u32be(entry_offset + 0x02, sf); - type_desc = read_32bitBE(types_offset + 0x06 * meta_type, sf); + type_desc = read_u32be(types_offset + 0x06 * item_type, sf); switch (type_desc) { case 0x534E5231: /* "SNR1" */ snr_offset = data_offset; break; case 0x534E5331: /* "SNS1" */ - sns_offset = read_32bitBE(data_offset, sf); + sns_offset = read_u32be(data_offset, sf); break; default: break; @@ -336,43 +337,40 @@ VGMSTREAM* init_vgmstream_ea_sbr(STREAMFILE* sf) { if (snr_offset == 0 && sns_offset == 0) goto fail; - if (snr_offset == 0) { - /* SPS file */ - sbsFile = open_streamfile_by_ext(sf, "sbs"); - if (!sbsFile) - goto fail; - - if (read_32bitBE(0x00, sbsFile) != 0x53424B53) /* "SBKS" */ - goto fail; - - vgmstream = init_vgmstream_eaaudiocore_header(sbsFile, NULL, sns_offset, 0x00, meta_EA_SPS, 0); - if (!vgmstream) - goto fail; - } else if (sns_offset == 0) { + if (sns_offset == 0) { /* RAM asset */ - vgmstream = init_vgmstream_eaaudiocore_header(sf, NULL, snr_offset, 0x00, meta_EA_SNR_SNS, 0); - if (!vgmstream) - goto fail; + meta_t meta_type = (read_u8(snr_offset, sf) == 0x48) ? meta_EA_SPS : meta_EA_SNR_SNS; + vgmstream = init_vgmstream_eaaudiocore_header(sf, NULL, snr_offset, 0x00, meta_type, 0); + if (!vgmstream) goto fail; } else { /* streamed asset */ - sbsFile = open_streamfile_by_ext(sf, "sbs"); - if (!sbsFile) + sf_sbs = open_streamfile_by_ext(sf, "sbs"); + if (!sf_sbs) goto fail; + + if (read_u32be(0x00, sf_sbs) != 0x53424B53) /* "SBKS" */ goto fail; - if (read_32bitBE(0x00, sbsFile) != 0x53424B53) /* "SBKS" */ - goto fail; + if (read_u8(sns_offset, sf_sbs) == 0x48) { + /* SPS */ + vgmstream = init_vgmstream_eaaudiocore_header(sf_sbs, NULL, sns_offset, 0x00, meta_EA_SPS, 0); + if (!vgmstream) goto fail; + } else { + /* SNR/SNS */ + if (snr_offset == 0) + goto fail; - vgmstream = init_vgmstream_eaaudiocore_header(sf, sbsFile, snr_offset, sns_offset, meta_EA_SNR_SNS, 0); - if (!vgmstream) - goto fail; + vgmstream = init_vgmstream_eaaudiocore_header(sf, sf_sbs, snr_offset, sns_offset, meta_EA_SNR_SNS, 0); + if (!vgmstream) goto fail; + } } + snprintf(vgmstream->stream_name, STREAM_NAME_SIZE, "%08x", sound_id); vgmstream->num_streams = num_sounds; - close_streamfile(sbsFile); + close_streamfile(sf_sbs); return vgmstream; fail: - close_streamfile(sbsFile); + close_streamfile(sf_sbs); return NULL; } @@ -813,7 +811,7 @@ fail: VGMSTREAM* init_vgmstream_ea_sbr_harmony(STREAMFILE* sf) { uint64_t base_offset, sound_offset, offset, prev_offset; uint32_t chunk_id, data_offset, table_offset, dset_offset, set_values, set_sounds, sound_table_offset; - int32_t flag; + int16_t flag; uint16_t num_dsets; uint8_t set_type, offset_size; uint32_t i, j; @@ -1090,7 +1088,7 @@ static VGMSTREAM* init_vgmstream_eaaudiocore_header(STREAMFILE* sf_head, STREAMF /* common channel configs are mono/stereo/quad/5.1/7.1 (from debug strings), while others are quite rare * [Battlefield 4 (X360)-EAXMA: 3/5/7ch, Army of Two: The Devil's Cartel (PS3)-EALayer3v2P: 11ch] */ eaac.channels = eaac.channel_config + 1; - /* EA 6ch channel mapping is L C R BL BR LFE, but may use stereo layers for dynamic music + /* EA 6ch channel mapping is FL FC FR BL BR LFE, but may use stereo layers for dynamic music * instead, so we can't re-map automatically (use TXTP) */ /* V0: SNR+SNS, V1: SPH+SPS (no apparent differences, other than block flags) */ @@ -1111,8 +1109,8 @@ static VGMSTREAM* init_vgmstream_eaaudiocore_header(STREAMFILE* sf_head, STREAMF goto fail; } - if (eaac.version == EAAC_VERSION_V1 && eaac.type != EAAC_TYPE_STREAM) { - /* should never happen */ + if (eaac.version == EAAC_VERSION_V1 && eaac.type == EAAC_TYPE_GIGASAMPLE) { + /* probably does not exist */ VGM_LOG("EA EAAC: bad stream type for version %x\n", eaac.version); goto fail; } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ea_schl.c b/Frameworks/vgmstream/vgmstream/src/meta/ea_schl.c index c822e0601..d4f271fe3 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ea_schl.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ea_schl.c @@ -1483,7 +1483,7 @@ static VGMSTREAM* init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header* e } else if (vgmstream->coding_type == coding_NGC_DSP && vgmstream->channels > 1 && ea->offsets[0] == ea->offsets[1]) { /* pcstream+gcadpcm with sx.exe v2, not in flag_value, probably a bug (even with this parts of the wave are off) */ int interleave = (ea->num_samples / 14 * 8); /* full interleave */ - for (i = 0; i < ea->channels; i++) { + for (i = 0; i < vgmstream->channels; i++) { vgmstream->ch[i].offset = ea->offsets[0] + interleave*i; } } else if (ea->platform == EA_PLATFORM_PS2 && (ea->flag_value & 0x100)) { diff --git a/Frameworks/vgmstream/vgmstream/src/meta/fsb.c b/Frameworks/vgmstream/vgmstream/src/meta/fsb.c index 2d62556cb..f9271d9ff 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/fsb.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/fsb.c @@ -112,15 +112,18 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) { fsb_header fsb = {0}; - /* checks - * .fsb: standard - * .bnk: Hard Corps Uprising (PS3) */ - if ( !check_extensions(sf, "fsb,bnk") ) + /* checks */ + if ((read_u32be(0x00,sf) & 0xFFFFFF00) != get_id32be("FSB\0")) goto fail; - /* check header */ - fsb.id = read_32bitBE(0x00,sf); - if (fsb.id == 0x46534231) { /* "FSB1" (somewhat different from other fsbs) */ + /* .fsb: standard + * .bnk: Hard Corps Uprising (PS3) + * .sfx: Geon Cube (Wii) */ + if ( !check_extensions(sf, "fsb,bnk,sfx") ) + goto fail; + + fsb.id = read_u32be(0x00,sf); + if (fsb.id == get_id32be("FSB1")) { fsb.meta_type = meta_FSB1; fsb.base_header_size = 0x10; fsb.sample_header_min = 0x40; @@ -132,7 +135,8 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) { fsb.version = 0; fsb.flags = 0; - if (fsb.total_subsongs > 1) goto fail; + if (fsb.total_subsongs > 1) + goto fail; /* sample header (first stream only, not sure if there are multi-FSB1) */ { @@ -159,16 +163,16 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) { fsb.stream_offset = fsb.base_header_size + fsb.sample_headers_size; } } - else { /* other FSBs (common/extended format) */ - if (fsb.id == 0x46534232) { /* "FSB2" */ + else { + if (fsb.id == get_id32be("FSB2")) { fsb.meta_type = meta_FSB2; fsb.base_header_size = 0x10; fsb.sample_header_min = 0x40; /* guessed */ - } else if (fsb.id == 0x46534233) { /* "FSB3" */ + } else if (fsb.id == get_id32be("FSB3")) { fsb.meta_type = meta_FSB3; fsb.base_header_size = 0x18; fsb.sample_header_min = 0x40; - } else if (fsb.id == 0x46534234) { /* "FSB4" */ + } else if (fsb.id == get_id32be("FSB4")) { fsb.meta_type = meta_FSB4; fsb.base_header_size = 0x30; fsb.sample_header_min = 0x50; @@ -183,7 +187,7 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) { if (fsb.base_header_size > 0x10) { fsb.version = read_32bitLE(0x10,sf); fsb.flags = read_32bitLE(0x14,sf); - /* FSB4: 0x18(8):hash 0x20(10):guid */ + /* FSB4: 0x18(8):hash, 0x20(10):guid */ } else { fsb.version = 0; fsb.flags = 0; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h b/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h index 6f3d89aae..1582d0a6c 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h +++ b/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h @@ -858,6 +858,8 @@ static const hcakey_info hcakey_list[] = { {0x0a5d0fc8cc5c4502}, // Sng018 {0x198ea1a17416050b}, // Sng019 {0x2aa3b8abad207a1e}, // Sng020 + {0x08ad2fe12c79bca9}, // Sng022 + {0x18488992b1632ef5}, // Sng023 {0x1175edbbacc1fc18}, // Sng024 {0x0e14d06d7f7a6c8c}, // Sng025 {0x33d98a3a9f9bfdef}, // Sng026 @@ -880,6 +882,9 @@ static const hcakey_info hcakey_list[] = { // Shaman King: Funbari Chronicle (Android) {1620612098671}, // 0000017954022A6F + // Heaven Burns Red (Android) + {7355875239102698567}, // 6615518E8ECED447 + }; #endif/*_HCA_KEYS_H_*/ diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ktac.c b/Frameworks/vgmstream/vgmstream/src/meta/ktac.c index 75789c7f8..14143a8e9 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ktac.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ktac.c @@ -1,7 +1,6 @@ #include "meta.h" #include "../coding/coding.h" - typedef struct { int loop_flag; int32_t loop_start; @@ -15,10 +14,10 @@ typedef struct { /* KTAC - Koei Tecmo custom AAC [Kin'iro no Corda 3 (Vita), Shingeki no Kyojin: Shichi kara no Dasshutsu (3DS), Dynasty Warriors (PS4)] */ VGMSTREAM* init_vgmstream_ktac(STREAMFILE* sf) { +#ifdef VGM_USE_FFMPEG VGMSTREAM* vgmstream = NULL; ktac_header_t ktac = {0}; - /* checks */ /* .ktac: header id */ if (!check_extensions(sf,"ktac")) @@ -53,7 +52,6 @@ VGMSTREAM* init_vgmstream_ktac(STREAMFILE* sf) { if (ktac.type == 1) goto fail; - /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(ktac.mp4.channels, ktac.loop_flag); if (!vgmstream) goto fail; @@ -66,19 +64,14 @@ VGMSTREAM* init_vgmstream_ktac(STREAMFILE* sf) { /* KTAC uses AAC, but not type found in .aac (that has headered frames, like mp3) but raw * packets + frame size table (similar to .mp4/m4a). We set config for FFmpeg's fake M4A header */ -#ifdef VGM_USE_FFMPEG - { - vgmstream->codec_data = init_ffmpeg_mp4_custom_std(sf, &ktac.mp4); - if (!vgmstream->codec_data) goto fail; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - } -#else - goto fail; -#endif + vgmstream->codec_data = init_ffmpeg_mp4_custom_std(sf, &ktac.mp4); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; return vgmstream; fail: close_vgmstream(vgmstream); +#endif return NULL; } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/musx.c b/Frameworks/vgmstream/vgmstream/src/meta/musx.c index 441d4ec43..0e2623cef 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/musx.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/musx.c @@ -1,5 +1,6 @@ #include "meta.h" #include "../coding/coding.h" +#include "../util/endianness.h" typedef enum { MFX, MFX_BANK, SFX_BANK, SBNK, FORM } musx_form; typedef enum { PSX, DSP, XBOX, IMA, DAT, NGCA, PCM } musx_codec; @@ -187,16 +188,24 @@ static int parse_musx_stream(STREAMFILE* sf, musx_header* musx) { musx->platform = get_id32be("GC02"); /* (fake) */ } else { + int channels = musx->channels; off_t offset = musx->stream_offset; size_t max = 0x5000; if (max > musx->stream_size) max = musx->stream_size; + if (!channels) + channels = 2; + /* since engine seems to hardcode codecs no apparent way to detect in some cases + * [Sphinx and the Cursed Mummy (multi), Buffy the Vampire Slayer: Chaos Bleeds (multi)] */ if (ps_check_format(sf, offset, max)) { musx->platform = get_id32be("PS2_"); - } else { + } else if (xbox_check_format(sf, offset, max, channels)) { musx->platform = get_id32be("XB02"); /* (fake) */ } + else { + musx->platform = get_id32be("PC02"); /* (fake) */ + } } } @@ -267,6 +276,12 @@ static int parse_musx_stream(STREAMFILE* sf, musx_header* musx) { musx->codec = DAT; break; + case 0x50433032: /* "PC02" */ + default_channels = 2; + default_sample_rate = 32000; + musx->codec = IMA; + break; + default: VGM_LOG("MUSX: unknown platform %x\n", musx->platform); goto fail; @@ -307,7 +322,7 @@ static int parse_musx_stream(STREAMFILE* sf, musx_header* musx) { } /* other types (0x0a, 0x09) look like section/end markers, 0x06/07 only seems to exist once */ - if (type == 0x06 || type == 0x07) { + if (type == 0x06 || type == 0x07) { /* loop / goto */ musx->loop_start = offset2; musx->loop_end = offset1; musx->loop_flag = 1; @@ -361,6 +376,8 @@ fail: return 0; } +//TODO: check possible info here: +// https://sphinxandthecursedmummy.fandom.com/wiki/SFX static int parse_musx(STREAMFILE* sf, musx_header* musx) { int32_t (*read_s32)(off_t,STREAMFILE*) = NULL; uint32_t (*read_u32)(off_t,STREAMFILE*) = NULL; @@ -378,7 +395,7 @@ static int parse_musx(STREAMFILE* sf, musx_header* musx) { case 1: /* Athens 2004 (PS2) */ musx->platform = 0; /* guess later */ musx->tables_offset = 0x10; - musx->big_endian = guess_endianness32bit(0x10, sf); + musx->big_endian = guess_endian32(0x10, sf); musx->is_old = 1; break; @@ -670,7 +687,7 @@ static int parse_musx(STREAMFILE* sf, musx_header* musx) { data_offset = read_u32(musx->tables_offset+0x3c, sf); target_offset = head_offset + (target_subsong - 1) * 0x1c; - ;VGM_LOG("MUSX: ho=%lx, do=%lx, to=%lx\n", head_offset, data_offset, target_offset); + //;VGM_LOG("MUSX: ho=%lx, do=%lx, to=%lx\n", head_offset, data_offset, target_offset); /* 0x00: subfile ID */ musx->num_samples = read_s32(target_offset + 0x04, sf); diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ps2_mic.c b/Frameworks/vgmstream/vgmstream/src/meta/ps2_mic.c index 84bbfff45..d403e7fe4 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ps2_mic.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ps2_mic.c @@ -18,12 +18,12 @@ VGMSTREAM* init_vgmstream_mic_koei(STREAMFILE* sf) { if (start_offset != 0x800) goto fail; sample_rate = read_u32le(0x04,sf); channels = read_u32le(0x08,sf); - if (channels > 2) goto fail; + if (channels > 4) goto fail; /* 1/2/4 are known */ interleave = read_u32le(0x0c,sf); if (interleave != 0x10) goto fail; - loop_end = read_32bitLE(0x10,sf); - loop_start = read_32bitLE(0x14,sf); + loop_end = read_s32le(0x10,sf); + loop_start = read_s32le(0x14,sf); if (read_u32le(0x18,sf) != 0) goto fail; if (read_u32le(0x1c,sf) != 0) goto fail; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/wbk.c b/Frameworks/vgmstream/vgmstream/src/meta/wbk.c index ff05b2edc..006d9379b 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/wbk.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/wbk.c @@ -1,5 +1,6 @@ #include "meta.h" #include "../coding/coding.h" +//#include /* .WBK - seen in some Treyarch games [Spider-Man 2, Ultimate Spider-Man, Call of Duty 2: Big Red One] */ VGMSTREAM* init_vgmstream_wbk(STREAMFILE* sf) { @@ -154,6 +155,19 @@ fail: return NULL; } +/* Ultimate Spider-Man string hashing algorithm, for reference */ +#if 0 +static uint32_t wbk_hasher(const char* input) { + uint32_t hash = 0; + + for (const char* ch = input; *ch; ch++) { + hash += hash*32 + tolower(*ch); + } + + return hash; +} +#endif + /* .WBK - evolution of the above Treyarch bank format [Call of Duty 3] */ VGMSTREAM* init_vgmstream_wbk_nslb(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; @@ -291,14 +305,18 @@ VGMSTREAM* init_vgmstream_wbk_nslb(STREAMFILE* sf) { off_t riff_fmt_offset, riff_data_offset; size_t bytes, riff_fmt_size, riff_data_size; + sound_offset += 0x0c; + sound_size -= 0x0c; + /* find "fmt" chunk */ - if (!find_chunk_riff_le(sf, 0x666d7420, sound_offset + 0x0c, sound_size - 0x0c, &riff_fmt_offset, &riff_fmt_size)) + if (!find_chunk_riff_le(sf, 0x666d7420, sound_offset, sound_size, &riff_fmt_offset, &riff_fmt_size)) goto fail; /* find "data" chunk */ - if (!find_chunk_riff_le(sf, 0x64617461, sound_offset + 0x0c, sound_size - 0x0c, &riff_data_offset, &riff_data_size)) + if (!find_chunk_riff_le(sf, 0x64617461, sound_offset, sound_size, &riff_data_offset, &riff_data_size)) goto fail; + sound_offset = riff_data_offset; bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf, 0x100, riff_fmt_offset, riff_fmt_size, riff_data_size, sf, 0); vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, riff_data_offset, riff_data_size);