From 05960b1da15044fe7e2dc0d65d8245574d622fc3 Mon Sep 17 00:00:00 2001 From: Christopher Snowhill Date: Sun, 26 Jun 2022 15:11:23 -0700 Subject: [PATCH] Updated VGMStream to r1745-47-gfa55119d Signed-off-by: Christopher Snowhill --- .../libvgmstream.xcodeproj/project.pbxproj | 4 + .../vgmstream/src/coding/mpeg_decoder.c | 42 ++--- Frameworks/vgmstream/vgmstream/src/formats.c | 3 + .../vgmstream/vgmstream/src/meta/2dx9.c | 6 +- .../vgmstream/vgmstream/src/meta/meta.h | 2 + .../vgmstream/vgmstream/src/meta/mpeg.c | 9 +- .../vgmstream/vgmstream/src/meta/riff.c | 3 +- Frameworks/vgmstream/vgmstream/src/meta/s3v.c | 6 +- .../vgmstream/vgmstream/src/meta/sndz.c | 170 ++++++++++++++++++ .../vgmstream/vgmstream/src/meta/txth.c | 28 +-- Frameworks/vgmstream/vgmstream/src/meta/vag.c | 12 +- .../vgmstream/vgmstream/src/vgmstream.c | 1 + .../vgmstream/vgmstream/src/vgmstream.h | 1 + 13 files changed, 242 insertions(+), 45 deletions(-) create mode 100644 Frameworks/vgmstream/vgmstream/src/meta/sndz.c diff --git a/Frameworks/vgmstream/libvgmstream.xcodeproj/project.pbxproj b/Frameworks/vgmstream/libvgmstream.xcodeproj/project.pbxproj index e499706be..0ce953b65 100644 --- a/Frameworks/vgmstream/libvgmstream.xcodeproj/project.pbxproj +++ b/Frameworks/vgmstream/libvgmstream.xcodeproj/project.pbxproj @@ -279,6 +279,7 @@ 8351F32D2212B57000A606E4 /* 208.c in Sources */ = {isa = PBXBuildFile; fileRef = 8351F32A2212B57000A606E4 /* 208.c */; }; 8351F32E2212B57000A606E4 /* ubi_bao_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8351F32B2212B57000A606E4 /* ubi_bao_streamfile.h */; }; 8351F32F2212B57000A606E4 /* dsf.c in Sources */ = {isa = PBXBuildFile; fileRef = 8351F32C2212B57000A606E4 /* dsf.c */; }; + 835559FC2869102B005FE93A /* sndz.c in Sources */ = {isa = PBXBuildFile; fileRef = 835559FB2869102B005FE93A /* sndz.c */; }; 835B9B8F2730BF2D00F87EE3 /* ast_mv.c in Sources */ = {isa = PBXBuildFile; fileRef = 835B9B8A2730BF2C00F87EE3 /* ast_mv.c */; }; 835B9B902730BF2D00F87EE3 /* ast_mmv.c in Sources */ = {isa = PBXBuildFile; fileRef = 835B9B8B2730BF2C00F87EE3 /* ast_mmv.c */; }; 835B9B912730BF2D00F87EE3 /* lopu_fb.c in Sources */ = {isa = PBXBuildFile; fileRef = 835B9B8C2730BF2C00F87EE3 /* lopu_fb.c */; }; @@ -1102,6 +1103,7 @@ 8351F32A2212B57000A606E4 /* 208.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = 208.c; sourceTree = ""; }; 8351F32B2212B57000A606E4 /* ubi_bao_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ubi_bao_streamfile.h; sourceTree = ""; }; 8351F32C2212B57000A606E4 /* dsf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dsf.c; sourceTree = ""; }; + 835559FB2869102B005FE93A /* sndz.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sndz.c; sourceTree = ""; }; 835B9B8A2730BF2C00F87EE3 /* ast_mv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ast_mv.c; sourceTree = ""; }; 835B9B8B2730BF2C00F87EE3 /* ast_mmv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ast_mmv.c; sourceTree = ""; }; 835B9B8C2730BF2C00F87EE3 /* lopu_fb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lopu_fb.c; sourceTree = ""; }; @@ -2289,6 +2291,7 @@ 837CEAEB23487F2B00E62A4A /* smk.c */, 83F0AA5C21E2028B004BBC04 /* smp.c */, 8306B0C72098458D000302D4 /* smv.c */, + 835559FB2869102B005FE93A /* sndz.c */, 836F6EBE18BDC2190095E648 /* spm.c */, 83A21F82201D8981000F04B9 /* sps_n1.c */, 836F6EF318BDC2190095E648 /* spt_spd.c */, @@ -2750,6 +2753,7 @@ 839E21E31F2EDAF100EE54D7 /* mpeg_custom_utils_ahx.c in Sources */, 8306B0AF20984552000302D4 /* blocked_rws.c in Sources */, 83C7281A22BC893D00678B4A /* mus_vc.c in Sources */, + 835559FC2869102B005FE93A /* sndz.c in Sources */, 839E21EB1F2EDB0600EE54D7 /* sk_aud.c in Sources */, 834FE0F1215C79ED000A5D3D /* a2m.c in Sources */, 8301659A1F256BD000CA0941 /* txth.c in Sources */, diff --git a/Frameworks/vgmstream/vgmstream/src/coding/mpeg_decoder.c b/Frameworks/vgmstream/vgmstream/src/coding/mpeg_decoder.c index d22709c2f..06b5c3a6f 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/mpeg_decoder.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/mpeg_decoder.c @@ -29,43 +29,45 @@ mpeg_codec_data* init_mpeg(STREAMFILE* sf, off_t start_offset, coding_t* coding_ data->m = init_mpg123_handle(); if (!data->m) goto fail; + /* check format */ { - mpg123_handle *main_m = data->m; - off_t read_offset = 0; - int rc; + int rc, pos, bytes_read; + size_t bytes_done; - long sample_rate_per_frame; - int channels_per_frame, encoding; - size_t samples_per_frame; - struct mpg123_frameinfo mi; + bytes_read = read_streamfile(data->buffer, start_offset, data->buffer_size, sf); + /* don't check max as sfx can be smaller than buffer */ - //todo read single big buffer then add +1 up to a few max bytes, or just read once only - /* read first frame(s) */ + /* start_offset should be correct but just in case, read first frame(s) */ + pos = 0; do { - size_t bytes_read, bytes_done; - - /* don't check max as sfx can be smaller than buffer */ - bytes_read = read_streamfile(data->buffer, start_offset + read_offset, data->buffer_size, sf); - read_offset += 1; - - rc = mpg123_decode(main_m, data->buffer, bytes_read, NULL,0, &bytes_done); + rc = mpg123_decode(data->m, data->buffer + pos, bytes_read, NULL,0, &bytes_done); if (rc != MPG123_OK && rc != MPG123_NEW_FORMAT && rc != MPG123_NEED_MORE) { VGM_LOG("MPEG: unable to set up mpg123 at start offset\n"); goto fail; //handle MPG123_DONE? } - if (read_offset > 0x5000) { /* don't hang in some incorrectly detected formats */ + if (bytes_read <= 0x10) { /* don't hang in some incorrectly detected formats */ VGM_LOG("MPEG: unable to find mpeg data at start offset\n"); goto fail; } + pos++; + bytes_read--; } while (rc != MPG123_NEW_FORMAT); + } + + { + size_t samples_per_frame; + long sample_rate_per_frame; + int channels_per_frame, encoding; + int rc; + struct mpg123_frameinfo mi; /* check first frame header and validate */ - rc = mpg123_getformat(main_m, &sample_rate_per_frame, &channels_per_frame, &encoding); + rc = mpg123_getformat(data->m, &sample_rate_per_frame, &channels_per_frame, &encoding); if (rc != MPG123_OK) goto fail; - mpg123_info(main_m, &mi); + mpg123_info(data->m, &mi); if (encoding != MPG123_ENC_SIGNED_16) goto fail; @@ -99,7 +101,7 @@ mpeg_codec_data* init_mpeg(STREAMFILE* sf, off_t start_offset, coding_t* coding_ memcpy(&data->mi, &mi, sizeof(struct mpg123_frameinfo)); /* reinit, to ignore the reading done */ - mpg123_open_feed(main_m); + mpg123_open_feed(data->m); } return data; diff --git a/Frameworks/vgmstream/vgmstream/src/formats.c b/Frameworks/vgmstream/vgmstream/src/formats.c index 9cac65d9b..3b14860f9 100644 --- a/Frameworks/vgmstream/vgmstream/src/formats.c +++ b/Frameworks/vgmstream/vgmstream/src/formats.c @@ -532,6 +532,8 @@ static const char* extension_list[] = { "sxd", "sxd2", "sxd3", + "szd1", + "szd3", "tad", "tec", @@ -1402,6 +1404,7 @@ static const meta_info meta_info_list[] = { {meta_ESF, "Eurocom ESF header"}, {meta_ADM3, "Crankcase ADM3 header"}, {meta_TT_AD, "Traveller's Tales AUDIO_DATA header"}, + {meta_SNDZ, "Sony SNDZ header"}, }; void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) { diff --git a/Frameworks/vgmstream/vgmstream/src/meta/2dx9.c b/Frameworks/vgmstream/vgmstream/src/meta/2dx9.c index be1ccc3d6..8684eb8cc 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/2dx9.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/2dx9.c @@ -24,8 +24,8 @@ VGMSTREAM * init_vgmstream_2dx9(STREAMFILE *streamFile) { if (read_32bitBE(0x6a,streamFile) != 0x64617461) /* data */ goto fail; - /* IIDX 13 has a false flag for looping files. Konami, pls. */ - loop_flag = (read_16bitLE(0x0e,streamFile) > -1); + /* Some data loop from beginning to the end by hardcoded flag so cannot be recognized from sound file */ + loop_flag = (read_32bitLE(0x14,streamFile) > 0); channel_count = read_16bitLE(0x2e,streamFile); start_offset = 0x72; @@ -37,7 +37,7 @@ VGMSTREAM * init_vgmstream_2dx9(STREAMFILE *streamFile) { vgmstream->sample_rate = read_32bitLE(0x30,streamFile); vgmstream->num_samples = read_32bitLE(0x66,streamFile); if (loop_flag) { - vgmstream->loop_start_sample = 0; + vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile) / 2 / channel_count; vgmstream->loop_end_sample = vgmstream->num_samples; } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/meta.h b/Frameworks/vgmstream/vgmstream/src/meta/meta.h index f423926f9..2cd3b9177 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/meta.h +++ b/Frameworks/vgmstream/vgmstream/src/meta/meta.h @@ -991,4 +991,6 @@ VGMSTREAM* init_vgmstream_tt_ad(STREAMFILE* sf); VGMSTREAM* init_vgmstream_bw_mp3_riff(STREAMFILE* sf); VGMSTREAM* init_vgmstream_bw_riff_mp3(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_sndz(STREAMFILE* sf); + #endif /*_META_H*/ diff --git a/Frameworks/vgmstream/vgmstream/src/meta/mpeg.c b/Frameworks/vgmstream/vgmstream/src/meta/mpeg.c index b3fad20ab..da0d806df 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/mpeg.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/mpeg.c @@ -19,7 +19,8 @@ VGMSTREAM* init_vgmstream_mpeg(STREAMFILE* sf) { (header_id & 0xFFFFFF00) != get_id32be("TAG\0")) goto fail; - //TODO: may try init_mpeg as-is, already skips tags + /* detect base offset, since some tags with images are big + * (init_mpeg only skips tags in a small-ish buffer) */ start_offset = 0x00; while (start_offset < get_streamfile_size(sf)) { uint32_t tag_size = mpeg_get_tag_size(sf, start_offset, 0); @@ -52,15 +53,15 @@ VGMSTREAM* init_vgmstream_mpeg(STREAMFILE* sf) { //cfg.skip_samples = ... //vgmstream->codec_data = init_mpeg_custom(sf, start_offset, &vgmstream->coding_type, fmt.channels, MPEG_STANDARD, &cfg); - vgmstream->codec_data = init_mpeg(sf, 0x00, &vgmstream->coding_type, info.channels); + vgmstream->codec_data = init_mpeg(sf, start_offset, &vgmstream->coding_type, info.channels); if (!vgmstream->codec_data) goto fail; vgmstream->layout_type = layout_none; //vgmstream->num_samples = mpeg_bytes_to_samples(data_size, vgmstream->codec_data); - vgmstream->num_samples = mpeg_get_samples(sf, 0x00, get_streamfile_size(sf)); + vgmstream->num_samples = mpeg_get_samples(sf, start_offset, get_streamfile_size(sf)); - if (!vgmstream_open_stream(vgmstream, sf, 0x00)) + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) goto fail; return vgmstream; fail: diff --git a/Frameworks/vgmstream/vgmstream/src/meta/riff.c b/Frameworks/vgmstream/vgmstream/src/meta/riff.c index d17b8518f..644fcd3e8 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/riff.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/riff.c @@ -376,8 +376,9 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { * .nsa: Studio Ring games that uses NScripter [Hajimete no Otetsudai (PC)] * .pcm: Silent Hill Arcade (PC) * .xvag: Uncharted Golden Abyss (Vita)[ATRAC9] + * .ogg/logg: Luftrausers (Vita)[ATRAC9] */ - if ( check_extensions(sf, "wav,lwav,xwav,da,dax,cd,med,snd,adx,adp,xss,xsew,adpcm,adw,wd,,sbv,wvx,str,at3,rws,aud,at9,ckd,saf,ima,nsa,pcm,xvag") ) { + if ( check_extensions(sf, "wav,lwav,xwav,da,dax,cd,med,snd,adx,adp,xss,xsew,adpcm,adw,wd,,sbv,wvx,str,at3,rws,aud,at9,ckd,saf,ima,nsa,pcm,xvag,ogg,logg") ) { ; } else if ( check_extensions(sf, "mwv") ) { diff --git a/Frameworks/vgmstream/vgmstream/src/meta/s3v.c b/Frameworks/vgmstream/vgmstream/src/meta/s3v.c index d309bed8d..bc7b95537 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/s3v.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/s3v.c @@ -19,8 +19,10 @@ VGMSTREAM * init_vgmstream_s3v(STREAMFILE *sf) { /* No discernible loop_flag so we'll just use signatures. Might have to update on a per game basis. */ switch (read_32bitBE(0x14, sf)) { - case 0x82FA0000: // SOUND VOLTEX EXCEED GEAR ver5 - case 0x1BFD0000: // SOUND VOLTEX EXCEED GEAR ver6 + case 0x82FA0000: // SOUND VOLTEX EXCEED GEAR ver5 Theme BGM + case 0x1BFD0000: // SOUND VOLTEX EXCEED GEAR ver6 Theme BGM + case 0x9AFD0000: // SOUND VOLTEX Custom song selection BGM TypeA + case 0x9BFD0000: // SOUND VOLTEX Custom song selection BGM TypeB loop_flag = 1; break; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/sndz.c b/Frameworks/vgmstream/vgmstream/src/meta/sndz.c new file mode 100644 index 000000000..67432b8e1 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/sndz.c @@ -0,0 +1,170 @@ +#include "meta.h" +#include "../coding/coding.h" + + +/* SNDZ - Sony/SCE's lib? (cousin of SXD) [Gran Turismo 7 (PS4)] */ +VGMSTREAM* init_vgmstream_sndz(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + STREAMFILE* sf_b = NULL; + uint32_t stream_offset, stream_size, name_offset, head_size, data_size; + int channels, loop_flag, sample_rate, codec, streamed; + int32_t num_samples, loop_start, loop_end; + uint32_t at9_config; + uint32_t offset; + int total_subsongs, target_subsong = sf->stream_index; + + + if (!is_id32be(0x00, sf, "SNDZ")) + goto fail; + head_size = read_u32le(0x04, sf); + data_size = read_u32le(0x08, sf); + /* 0x0c: version? (0x00010001) */ + /* 0x10: size size? */ + /* 0x14: null */ + /* 0x18/1c: some kind of ID? (shared by some files) */ + /* 0x20: bank name */ + + + /* .szd1: header + .szd2 = data + * .szd3: szd1 + szd2 */ + if (!check_extensions(sf, "szd1,szd3")) + goto fail; + + /* parse chunk table and WAVS with offset to offset to WAVD */ + { + uint32_t wavs_offset; + int i, entries; + + offset = 0x70; + offset += read_u32le(offset, sf); + + entries = read_u32le(offset, sf); + offset += 0x04; + + wavs_offset = 0; + for (i = 0; i < entries; i ++) { + if (is_id32be(offset + 0x00, sf, "WAVS")) { + /* 0x04: size? */ + wavs_offset = read_u32le(offset + 0x08, sf); + offset += 0x0c; + break; + } + + offset += 0x0c; + } + + if (!wavs_offset) + goto fail; + offset += wavs_offset; + + offset += read_u32le(offset, sf); + } + + /* parse WAVD header */ + { + uint32_t entry_size; + + if (!is_id32be(offset + 0x00, sf, "WAVD")) + goto fail; + entry_size = read_u32le(offset + 0x04, sf); + total_subsongs = read_u32le(offset + 0x08, sf); + + if (target_subsong == 0) target_subsong = 1; + if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail; + + offset += 0x0c; + offset += entry_size * (target_subsong - 1); + + /* main header */ + streamed = read_u32le(offset + 0x00, sf); + name_offset = read_u32le(offset + 0x04, sf) + offset + 0x04; /* from here */ + /* 08: null */ + /* 0c: size/offset? */ + codec = read_u8(offset + 0x10, sf); + channels = read_u8(offset + 0x11, sf); + /* 12: null */ + sample_rate = read_u32le(offset + 0x14, sf); + num_samples = read_s32le(offset + 0x18, sf); + at9_config = read_u32le(offset + 0x1c, sf); + loop_start = read_s32le(offset + 0x20, sf); + loop_end = read_s32le(offset + 0x24, sf); + stream_size = read_u32le(offset + 0x28, sf); /* from data start in szd2 or absolute in szd3 */ + stream_offset = read_u32le(offset + 0x2c, sf); + /* rest: null */ + + loop_flag = loop_end > 0; + } + +VGM_LOG("%i, %x, %x, %x\n", streamed, head_size, data_size, get_streamfile_size(sf)); + /* szd3 is streamed but has header+data together, with padding between (data_size is the same as file size)*/ + if (streamed && get_streamfile_size(sf) < data_size) { + sf_b = open_streamfile_by_ext(sf, "szd2"); + if (!sf_b) { + vgm_logi("SNDZ: can't find companion .szd2 file\n"); + goto fail; + } + + if (data_size > get_streamfile_size(sf_b)) + goto fail; + } + else { + /* should have enough data */ + if (stream_offset + stream_size > get_streamfile_size(sf)) + goto fail; + sf_b = sf; + } + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_SNDZ; + vgmstream->sample_rate = sample_rate; + + vgmstream->num_samples = num_samples; + vgmstream->loop_start_sample = loop_start; + vgmstream->loop_end_sample = loop_end; + + vgmstream->num_streams = total_subsongs; + vgmstream->stream_size = stream_size; + if (name_offset) + read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset, sf); + + switch (codec) { + case 0x20: + vgmstream->coding_type = coding_HEVAG; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x10; + break; + +#ifdef VGM_USE_ATRAC9 + case 0x21: { + atrac9_config cfg = {0}; + + cfg.channels = channels; + cfg.config_data = at9_config; + + vgmstream->codec_data = init_atrac9(&cfg); + if (!vgmstream->codec_data) goto fail; + vgmstream->coding_type = coding_ATRAC9; + vgmstream->layout_type = layout_none; + break; + } +#endif + default: + vgm_logi("SNDZ: unknown codec 0x%x\n", codec); + goto fail; + } + + if (!vgmstream_open_stream(vgmstream, sf_b, stream_offset)) + goto fail; + + if (sf_b != sf) close_streamfile(sf_b); + return vgmstream; + +fail: + if (sf_b != sf) close_streamfile(sf_b); + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/txth.c b/Frameworks/vgmstream/vgmstream/src/meta/txth.c index 2a52ad847..2255ad4ce 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/txth.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/txth.c @@ -48,6 +48,7 @@ typedef enum { CP_YM, PCM_FLOAT_LE, IMA_HV, + PCM8_SB, UNKNOWN = 99, } txth_codec_t; @@ -215,13 +216,14 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { if (txth.interleave == 0) { uint32_t interleave = 0; switch(txth.codec) { - case PSX: interleave = 0x10; break; + case PSX: case PSX_bf: interleave = 0x10; break; case NGC_DSP: interleave = 0x08; break; - case PCM16LE: interleave = 0x02; break; + case PCM16LE: case PCM16BE: interleave = 0x02; break; - case PCM8: interleave = 0x01; break; - case PCM8_U: interleave = 0x01; break; + case PCM8: + case PCM8_U: + case PCM8_SB: interleave = 0x01; break; case PCM_FLOAT_LE: interleave = 0x04; break; default: break; @@ -235,9 +237,12 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { case PSX: coding = coding_PSX; break; case XBOX: coding = coding_XBOX_IMA; break; case NGC_DTK: coding = coding_NGC_DTK; break; - case PCM16BE: coding = coding_PCM16BE; break; case PCM16LE: coding = coding_PCM16LE; break; + case PCM16BE: coding = coding_PCM16BE; break; case PCM8: coding = coding_PCM8; break; + case PCM8_U: coding = coding_PCM8_U; break; + case PCM8_U_int: coding = coding_PCM8_U_int; break; + case PCM8_SB: coding = coding_PCM8_SB; break; case PCM_FLOAT_LE: coding = coding_PCMFLOAT; break; case SDX2: coding = coding_SDX2; break; case DVI_IMA: coding = coding_DVI_IMA; break; @@ -249,10 +254,8 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { case AICA: coding = coding_AICA; break; case MSADPCM: coding = coding_MSADPCM; break; case NGC_DSP: coding = coding_NGC_DSP; break; - case PCM8_U_int: coding = coding_PCM8_U_int; break; case PSX_bf: coding = coding_PSX_badflags; break; case MS_IMA: coding = coding_MS_IMA; break; - case PCM8_U: coding = coding_PCM8_U; break; case APPLE_IMA4: coding = coding_APPLE_IMA4; break; #ifdef VGM_USE_FFMPEG case ATRAC3: @@ -310,6 +313,7 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { case coding_PCM16BE: case coding_PCM8: case coding_PCM8_U: + case coding_PCM8_SB: case coding_PCMFLOAT: case coding_PCM4: case coding_PCM4_U: @@ -938,6 +942,9 @@ static txth_codec_t parse_codec(txth_header* txth, const char* val) { else if (is_string(val,"PCM16BE")) return PCM16BE; else if (is_string(val,"PCM16LE")) return PCM16LE; else if (is_string(val,"PCM8")) return PCM8; + else if (is_string(val,"PCM8_U")) return PCM8_U; + else if (is_string(val,"PCM8_U_int")) return PCM8_U_int; + else if (is_string(val,"PCM8_SB")) return PCM8_SB; else if (is_string(val,"SDX2")) return SDX2; else if (is_string(val,"DVI_IMA")) return DVI_IMA; else if (is_string(val,"MPEG")) return MPEG; @@ -946,10 +953,8 @@ static txth_codec_t parse_codec(txth_header* txth, const char* val) { else if (is_string(val,"MSADPCM")) return MSADPCM; else if (is_string(val,"NGC_DSP")) return NGC_DSP; else if (is_string(val,"DSP")) return NGC_DSP; - else if (is_string(val,"PCM8_U_int")) return PCM8_U_int; else if (is_string(val,"PSX_bf")) return PSX_bf; else if (is_string(val,"MS_IMA")) return MS_IMA; - else if (is_string(val,"PCM8_U")) return PCM8_U; else if (is_string(val,"APPLE_IMA4")) return APPLE_IMA4; else if (is_string(val,"ATRAC3")) return ATRAC3; else if (is_string(val,"ATRAC3PLUS")) return ATRAC3PLUS; @@ -2043,11 +2048,12 @@ static int get_bytes_to_samples(txth_header* txth, uint32_t bytes) { return ps_bytes_to_samples(bytes, txth->channels); case PCM16BE: case PCM16LE: - return pcm_bytes_to_samples(bytes, txth->channels, 16); + return pcm16_bytes_to_samples(bytes, txth->channels); case PCM8: case PCM8_U_int: case PCM8_U: - return pcm_bytes_to_samples(bytes, txth->channels, 8); + case PCM8_SB: + return pcm8_bytes_to_samples(bytes, txth->channels); case PCM_FLOAT_LE: return pcm_bytes_to_samples(bytes, txth->channels, 32); case PCM4: diff --git a/Frameworks/vgmstream/vgmstream/src/meta/vag.c b/Frameworks/vgmstream/vgmstream/src/meta/vag.c index 2232c97f0..ff4e1c039 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/vag.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/vag.c @@ -52,12 +52,16 @@ VGMSTREAM* init_vgmstream_vag(STREAMFILE* sf) { /* check variation */ switch(vag_id) { - case 0x56414731: /* "VAG1" (1 channel) [Metal Gear Solid 3 (PS2)] */ - meta_type = meta_PS2_VAG1; + case 0x56414731: /* "VAG1" [Metal Gear Solid 3 (PS2), Cabela's African Safari (PSP)] */ + meta_type = meta_PS2_VAG1; //TODO not always Konami start_offset = 0x40; /* 0x30 is extra data in VAG1 */ - channels = 1; - interleave = 0; + interleave = 0x10; loop_flag = 0; + + /* MGS3 is 0 while Cabela's has this, plus description is 0x10 " " then 0x10 "-" */ + channels = read_u8(0x1e, sf); + if (channels == 0) + channels = 1; break; case 0x56414732: /* "VAG2" (2 channels) [Metal Gear Solid 3 (PS2)] */ diff --git a/Frameworks/vgmstream/vgmstream/src/vgmstream.c b/Frameworks/vgmstream/vgmstream/src/vgmstream.c index 7a9895611..33dd336f8 100644 --- a/Frameworks/vgmstream/vgmstream/src/vgmstream.c +++ b/Frameworks/vgmstream/vgmstream/src/vgmstream.c @@ -526,6 +526,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_tt_ad, init_vgmstream_bw_mp3_riff, init_vgmstream_bw_riff_mp3, + init_vgmstream_sndz, /* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */ init_vgmstream_agsc, diff --git a/Frameworks/vgmstream/vgmstream/src/vgmstream.h b/Frameworks/vgmstream/vgmstream/src/vgmstream.h index 63cd16fbb..5f96d4647 100644 --- a/Frameworks/vgmstream/vgmstream/src/vgmstream.h +++ b/Frameworks/vgmstream/vgmstream/src/vgmstream.h @@ -771,6 +771,7 @@ typedef enum { meta_ESF, meta_ADM3, meta_TT_AD, + meta_SNDZ, } meta_t;