diff --git a/Frameworks/vgmstream/libvgmstream.xcodeproj/project.pbxproj b/Frameworks/vgmstream/libvgmstream.xcodeproj/project.pbxproj index 52d686cb0..3d3f02bdb 100644 --- a/Frameworks/vgmstream/libvgmstream.xcodeproj/project.pbxproj +++ b/Frameworks/vgmstream/libvgmstream.xcodeproj/project.pbxproj @@ -9,7 +9,7 @@ /* Begin PBXBuildFile section */ 8301659A1F256BD000CA0941 /* txth.c in Sources */ = {isa = PBXBuildFile; fileRef = 830165971F256BD000CA0941 /* txth.c */; }; 8301659B1F256BD000CA0941 /* ea_schl_fixed.c in Sources */ = {isa = PBXBuildFile; fileRef = 830165981F256BD000CA0941 /* ea_schl_fixed.c */; }; - 8301659C1F256BD000CA0941 /* nds_strm_ffta2.c in Sources */ = {isa = PBXBuildFile; fileRef = 830165991F256BD000CA0941 /* nds_strm_ffta2.c */; }; + 8301659C1F256BD000CA0941 /* riff_ima.c in Sources */ = {isa = PBXBuildFile; fileRef = 830165991F256BD000CA0941 /* riff_ima.c */; }; 83031ECC243C50CC00C3F3E0 /* blocked_ubi_sce.c in Sources */ = {isa = PBXBuildFile; fileRef = 83031ECA243C50CB00C3F3E0 /* blocked_ubi_sce.c */; }; 83031ECD243C50CC00C3F3E0 /* blocked_vid1.c in Sources */ = {isa = PBXBuildFile; fileRef = 83031ECB243C50CB00C3F3E0 /* blocked_vid1.c */; }; 83031ED1243C50DF00C3F3E0 /* encrypted.c in Sources */ = {isa = PBXBuildFile; fileRef = 83031ECE243C50DE00C3F3E0 /* encrypted.c */; }; @@ -80,7 +80,7 @@ 8319018428F67F2B00B70711 /* bigrp.c in Sources */ = {isa = PBXBuildFile; fileRef = 8319018328F67F2B00B70711 /* bigrp.c */; }; 831BA6181EAC61A500CF89B0 /* adx.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA60E1EAC61A500CF89B0 /* adx.c */; }; 831BA6191EAC61A500CF89B0 /* ogl.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA60F1EAC61A500CF89B0 /* ogl.c */; }; - 831BA61A1EAC61A500CF89B0 /* ps2_vds_vdm.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6101EAC61A500CF89B0 /* ps2_vds_vdm.c */; }; + 831BA61A1EAC61A500CF89B0 /* vds_vdm.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6101EAC61A500CF89B0 /* vds_vdm.c */; }; 831BA61B1EAC61A500CF89B0 /* sgxd.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6111EAC61A500CF89B0 /* sgxd.c */; }; 831BA61C1EAC61A500CF89B0 /* sndx.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6121EAC61A500CF89B0 /* sndx.c */; }; 831BA61D1EAC61A500CF89B0 /* ubi_raki.c in Sources */ = {isa = PBXBuildFile; fileRef = 831BA6131EAC61A500CF89B0 /* ubi_raki.c */; }; @@ -200,7 +200,7 @@ 8349A90F1FE6258200E26435 /* aix_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8349A8F61FE6257E00E26435 /* aix_streamfile.h */; }; 8349A9101FE6258200E26435 /* ea_eaac.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8F71FE6257E00E26435 /* ea_eaac.c */; }; 8349A9111FE6258200E26435 /* bar_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8349A8F81FE6257E00E26435 /* bar_streamfile.h */; }; - 8349A9121FE6258200E26435 /* vsf_tta.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8F91FE6257E00E26435 /* vsf_tta.c */; }; + 8349A9121FE6258200E26435 /* smss.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8F91FE6257E00E26435 /* smss.c */; }; 8349A9141FE6258200E26435 /* omu.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8FB1FE6257F00E26435 /* omu.c */; }; 8349A9161FE6258200E26435 /* flx.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8FD1FE6257F00E26435 /* flx.c */; }; 8349A9171FE6258200E26435 /* pc_adp_otns.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8FE1FE6257F00E26435 /* pc_adp_otns.c */; }; @@ -287,7 +287,7 @@ 834F7DD42C7093EA003AC386 /* imuse_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D662C7093EA003AC386 /* imuse_decoder.c */; }; 834F7DD52C7093EA003AC386 /* l5_555_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D672C7093EA003AC386 /* l5_555_decoder.c */; }; 834F7DD62C7093EA003AC386 /* lsf_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D682C7093EA003AC386 /* lsf_decoder.c */; }; - 834F7DD72C7093EA003AC386 /* mc3_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D692C7093EA003AC386 /* mc3_decoder.c */; }; + 834F7DD72C7093EA003AC386 /* mpc3_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D692C7093EA003AC386 /* mpc3_decoder.c */; }; 834F7DD82C7093EA003AC386 /* mp4_aac_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D6A2C7093EA003AC386 /* mp4_aac_decoder.c */; }; 834F7DD92C7093EA003AC386 /* mpeg_custom_utils_ahx.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D6B2C7093EA003AC386 /* mpeg_custom_utils_ahx.c */; }; 834F7DDA2C7093EA003AC386 /* mpeg_custom_utils_ealayer3.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D6C2C7093EA003AC386 /* mpeg_custom_utils_ealayer3.c */; }; @@ -417,7 +417,7 @@ 834FE0F2215C79ED000A5D3D /* wv6.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0C9215C79E7000A5D3D /* wv6.c */; }; 834FE0F3215C79ED000A5D3D /* bnk_sony.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0CA215C79E7000A5D3D /* bnk_sony.c */; }; 834FE0F4215C79ED000A5D3D /* wsi.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0CB215C79E8000A5D3D /* wsi.c */; }; - 834FE0F5215C79ED000A5D3D /* wv2.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0CC215C79E8000A5D3D /* wv2.c */; }; + 834FE0F5215C79ED000A5D3D /* wav2.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0CC215C79E8000A5D3D /* wav2.c */; }; 834FE0F6215C79ED000A5D3D /* derf.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0CD215C79E8000A5D3D /* derf.c */; }; 834FE0F7215C79ED000A5D3D /* vis.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0CE215C79E8000A5D3D /* vis.c */; }; 834FE0F8215C79ED000A5D3D /* adpcm_capcom.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0CF215C79E8000A5D3D /* adpcm_capcom.c */; }; @@ -428,7 +428,7 @@ 834FE0FD215C79ED000A5D3D /* vpk.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D4215C79E9000A5D3D /* vpk.c */; }; 834FE0FE215C79ED000A5D3D /* ps_headerless.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D5215C79E9000A5D3D /* ps_headerless.c */; }; 834FE0FF215C79ED000A5D3D /* sscf.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D6215C79E9000A5D3D /* sscf.c */; }; - 834FE100215C79ED000A5D3D /* svg.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D7215C79EA000A5D3D /* svg.c */; }; + 834FE100215C79ED000A5D3D /* svgp.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D7215C79EA000A5D3D /* svgp.c */; }; 834FE101215C79ED000A5D3D /* csmp.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D8215C79EA000A5D3D /* csmp.c */; }; 834FE102215C79ED000A5D3D /* rfrm.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D9215C79EA000A5D3D /* rfrm.c */; }; 834FE103215C79ED000A5D3D /* ea_schl_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 834FE0DA215C79EA000A5D3D /* ea_schl_streamfile.h */; }; @@ -531,7 +531,7 @@ 836F6FA518BDC2190095E648 /* nds_rrds.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6918BDC2180095E648 /* nds_rrds.c */; }; 836F6FA718BDC2190095E648 /* nds_strm.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6B18BDC2180095E648 /* nds_strm.c */; }; 836F6FA918BDC2190095E648 /* ngc_adpdtk.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6D18BDC2180095E648 /* ngc_adpdtk.c */; }; - 836F6FAE18BDC2190095E648 /* ngc_dsp_mpds.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7218BDC2180095E648 /* ngc_dsp_mpds.c */; }; + 836F6FAE18BDC2190095E648 /* mpds.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7218BDC2180095E648 /* mpds.c */; }; 836F6FAF18BDC2190095E648 /* ngc_dsp_std.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7318BDC2180095E648 /* ngc_dsp_std.c */; }; 836F6FB018BDC2190095E648 /* dsp_kceje.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7418BDC2180095E648 /* dsp_kceje.c */; }; 836F6FB118BDC2190095E648 /* ngc_ffcc_str.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7518BDC2180095E648 /* ngc_ffcc_str.c */; }; @@ -542,7 +542,6 @@ 836F6FB718BDC2190095E648 /* ngc_ssm.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7B18BDC2180095E648 /* ngc_ssm.c */; }; 836F6FBA18BDC2190095E648 /* ymf.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7E18BDC2180095E648 /* ymf.c */; }; 836F6FBD18BDC2190095E648 /* nwa.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E8118BDC2180095E648 /* nwa.c */; }; - 836F6FBF18BDC2190095E648 /* otm.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E8318BDC2180095E648 /* otm.c */; }; 836F6FC018BDC2190095E648 /* p3d.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E8418BDC2180095E648 /* p3d.c */; }; 836F6FC218BDC2190095E648 /* pc_mxst.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E8618BDC2180095E648 /* pc_mxst.c */; }; 836F6FC718BDC2190095E648 /* pona.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E8B18BDC2180095E648 /* pona.c */; }; @@ -617,7 +616,7 @@ 836F703B18BDC2190095E648 /* vsf.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EFF18BDC2190095E648 /* vsf.c */; }; 836F703C18BDC2190095E648 /* bns.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0018BDC2190095E648 /* bns.c */; }; 836F703D18BDC2190095E648 /* mus_krome.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0118BDC2190095E648 /* mus_krome.c */; }; - 836F703E18BDC2190095E648 /* wii_ras.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0218BDC2190095E648 /* wii_ras.c */; }; + 836F703E18BDC2190095E648 /* ras.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0218BDC2190095E648 /* ras.c */; }; 836F704018BDC2190095E648 /* wii_sng.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0418BDC2190095E648 /* wii_sng.c */; }; 836F704218BDC2190095E648 /* sts.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0618BDC2190095E648 /* sts.c */; }; 836F704318BDC2190095E648 /* wpd.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0718BDC2190095E648 /* wpd.c */; }; @@ -637,7 +636,7 @@ 836F705818BDC2190095E648 /* vgmstream.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F1C18BDC2190095E648 /* vgmstream.c */; }; 836F705918BDC2190095E648 /* vgmstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 836F6F1D18BDC2190095E648 /* vgmstream.h */; settings = {ATTRIBUTES = (Public, ); }; }; 83709E051ECBC1A4005C03D3 /* ghs.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709DFF1ECBC1A4005C03D3 /* ghs.c */; }; - 83709E061ECBC1A4005C03D3 /* mc3.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E001ECBC1A4005C03D3 /* mc3.c */; }; + 83709E061ECBC1A4005C03D3 /* mpc3.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E001ECBC1A4005C03D3 /* mpc3.c */; }; 83709E071ECBC1A4005C03D3 /* mss.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E011ECBC1A4005C03D3 /* mss.c */; }; 83709E091ECBC1A4005C03D3 /* aac_triace.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E031ECBC1A4005C03D3 /* aac_triace.c */; }; 8373342623F60CDC00DE14DC /* deblock_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8373341E23F60CDB00DE14DC /* deblock_streamfile.h */; }; @@ -745,6 +744,10 @@ 83B46FD52707FB9A00847FC9 /* endianness.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B46FD42707FB9A00847FC9 /* endianness.h */; }; 83B69B222845A26600D2435A /* bw_mp3_riff.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B69B212845A26600D2435A /* bw_mp3_riff.c */; }; 83B72E3A27904589006007A3 /* libfdk-aac.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83B72E342790452C006007A3 /* libfdk-aac.2.dylib */; }; + 83B8FE2B2D5AB1F5005854C1 /* axhd.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B8FE2A2D5AB1F5005854C1 /* axhd.c */; }; + 83B8FE2D2D5AB2A5005854C1 /* shaa.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B8FE2C2D5AB2A5005854C1 /* shaa.c */; }; + 83B8FE2F2D5AB2F4005854C1 /* xwb_konami.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B8FE2E2D5AB2F4005854C1 /* xwb_konami.c */; }; + 83B8FE312D5AB421005854C1 /* undefind.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B8FE302D5AB421005854C1 /* undefind.c */; }; 83BAFB6C19F45EB3005DAB60 /* bfstm.c in Sources */ = {isa = PBXBuildFile; fileRef = 83BAFB6B19F45EB3005DAB60 /* bfstm.c */; }; 83C0C75D2AA435C60056AFD8 /* squeak.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C0C75C2AA435C60056AFD8 /* squeak.c */; }; 83C0C7602AA436370056AFD8 /* layout_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C0C75E2AA436370056AFD8 /* layout_utils.c */; }; @@ -933,7 +936,7 @@ /* Begin PBXFileReference section */ 830165971F256BD000CA0941 /* txth.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = txth.c; sourceTree = ""; }; 830165981F256BD000CA0941 /* ea_schl_fixed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ea_schl_fixed.c; sourceTree = ""; }; - 830165991F256BD000CA0941 /* nds_strm_ffta2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nds_strm_ffta2.c; sourceTree = ""; }; + 830165991F256BD000CA0941 /* riff_ima.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = riff_ima.c; sourceTree = ""; }; 83031ECA243C50CB00C3F3E0 /* blocked_ubi_sce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_ubi_sce.c; sourceTree = ""; }; 83031ECB243C50CB00C3F3E0 /* blocked_vid1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_vid1.c; sourceTree = ""; }; 83031ECE243C50DE00C3F3E0 /* encrypted.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = encrypted.c; sourceTree = ""; }; @@ -1004,7 +1007,7 @@ 8319018328F67F2B00B70711 /* bigrp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bigrp.c; sourceTree = ""; }; 831BA60E1EAC61A500CF89B0 /* adx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adx.c; sourceTree = ""; }; 831BA60F1EAC61A500CF89B0 /* ogl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ogl.c; sourceTree = ""; }; - 831BA6101EAC61A500CF89B0 /* ps2_vds_vdm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_vds_vdm.c; sourceTree = ""; }; + 831BA6101EAC61A500CF89B0 /* vds_vdm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vds_vdm.c; sourceTree = ""; }; 831BA6111EAC61A500CF89B0 /* sgxd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sgxd.c; sourceTree = ""; }; 831BA6121EAC61A500CF89B0 /* sndx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sndx.c; sourceTree = ""; }; 831BA6131EAC61A500CF89B0 /* ubi_raki.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ubi_raki.c; sourceTree = ""; }; @@ -1124,7 +1127,7 @@ 8349A8F61FE6257E00E26435 /* aix_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aix_streamfile.h; sourceTree = ""; }; 8349A8F71FE6257E00E26435 /* ea_eaac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ea_eaac.c; sourceTree = ""; }; 8349A8F81FE6257E00E26435 /* bar_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bar_streamfile.h; sourceTree = ""; }; - 8349A8F91FE6257E00E26435 /* vsf_tta.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vsf_tta.c; sourceTree = ""; }; + 8349A8F91FE6257E00E26435 /* smss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = smss.c; sourceTree = ""; }; 8349A8FB1FE6257F00E26435 /* omu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = omu.c; sourceTree = ""; }; 8349A8FD1FE6257F00E26435 /* flx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = flx.c; sourceTree = ""; }; 8349A8FE1FE6257F00E26435 /* pc_adp_otns.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pc_adp_otns.c; sourceTree = ""; }; @@ -1211,7 +1214,7 @@ 834F7D662C7093EA003AC386 /* imuse_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = imuse_decoder.c; sourceTree = ""; }; 834F7D672C7093EA003AC386 /* l5_555_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = l5_555_decoder.c; sourceTree = ""; }; 834F7D682C7093EA003AC386 /* lsf_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lsf_decoder.c; sourceTree = ""; }; - 834F7D692C7093EA003AC386 /* mc3_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mc3_decoder.c; sourceTree = ""; }; + 834F7D692C7093EA003AC386 /* mpc3_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpc3_decoder.c; sourceTree = ""; }; 834F7D6A2C7093EA003AC386 /* mp4_aac_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp4_aac_decoder.c; sourceTree = ""; }; 834F7D6B2C7093EA003AC386 /* mpeg_custom_utils_ahx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpeg_custom_utils_ahx.c; sourceTree = ""; }; 834F7D6C2C7093EA003AC386 /* mpeg_custom_utils_ealayer3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpeg_custom_utils_ealayer3.c; sourceTree = ""; }; @@ -1340,7 +1343,7 @@ 834FE0C9215C79E7000A5D3D /* wv6.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wv6.c; sourceTree = ""; }; 834FE0CA215C79E7000A5D3D /* bnk_sony.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bnk_sony.c; sourceTree = ""; }; 834FE0CB215C79E8000A5D3D /* wsi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wsi.c; sourceTree = ""; }; - 834FE0CC215C79E8000A5D3D /* wv2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wv2.c; sourceTree = ""; }; + 834FE0CC215C79E8000A5D3D /* wav2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wav2.c; sourceTree = ""; }; 834FE0CD215C79E8000A5D3D /* derf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = derf.c; sourceTree = ""; }; 834FE0CE215C79E8000A5D3D /* vis.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vis.c; sourceTree = ""; }; 834FE0CF215C79E8000A5D3D /* adpcm_capcom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adpcm_capcom.c; sourceTree = ""; }; @@ -1351,7 +1354,7 @@ 834FE0D4215C79E9000A5D3D /* vpk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vpk.c; sourceTree = ""; }; 834FE0D5215C79E9000A5D3D /* ps_headerless.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps_headerless.c; sourceTree = ""; }; 834FE0D6215C79E9000A5D3D /* sscf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sscf.c; sourceTree = ""; }; - 834FE0D7215C79EA000A5D3D /* svg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svg.c; sourceTree = ""; }; + 834FE0D7215C79EA000A5D3D /* svgp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svgp.c; sourceTree = ""; }; 834FE0D8215C79EA000A5D3D /* csmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = csmp.c; sourceTree = ""; }; 834FE0D9215C79EA000A5D3D /* rfrm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rfrm.c; sourceTree = ""; }; 834FE0DA215C79EA000A5D3D /* ea_schl_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ea_schl_streamfile.h; sourceTree = ""; }; @@ -1455,7 +1458,7 @@ 836F6E6918BDC2180095E648 /* nds_rrds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nds_rrds.c; sourceTree = ""; }; 836F6E6B18BDC2180095E648 /* nds_strm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nds_strm.c; sourceTree = ""; }; 836F6E6D18BDC2180095E648 /* ngc_adpdtk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_adpdtk.c; sourceTree = ""; }; - 836F6E7218BDC2180095E648 /* ngc_dsp_mpds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_dsp_mpds.c; sourceTree = ""; }; + 836F6E7218BDC2180095E648 /* mpds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpds.c; sourceTree = ""; }; 836F6E7318BDC2180095E648 /* ngc_dsp_std.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_dsp_std.c; sourceTree = ""; }; 836F6E7418BDC2180095E648 /* dsp_kceje.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dsp_kceje.c; sourceTree = ""; }; 836F6E7518BDC2180095E648 /* ngc_ffcc_str.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_ffcc_str.c; sourceTree = ""; }; @@ -1466,7 +1469,6 @@ 836F6E7B18BDC2180095E648 /* ngc_ssm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_ssm.c; sourceTree = ""; }; 836F6E7E18BDC2180095E648 /* ymf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ymf.c; sourceTree = ""; }; 836F6E8118BDC2180095E648 /* nwa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nwa.c; sourceTree = ""; }; - 836F6E8318BDC2180095E648 /* otm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = otm.c; sourceTree = ""; }; 836F6E8418BDC2180095E648 /* p3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = p3d.c; sourceTree = ""; }; 836F6E8618BDC2180095E648 /* pc_mxst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pc_mxst.c; sourceTree = ""; }; 836F6E8B18BDC2180095E648 /* pona.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pona.c; sourceTree = ""; }; @@ -1541,7 +1543,7 @@ 836F6EFF18BDC2190095E648 /* vsf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vsf.c; sourceTree = ""; }; 836F6F0018BDC2190095E648 /* bns.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bns.c; sourceTree = ""; }; 836F6F0118BDC2190095E648 /* mus_krome.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mus_krome.c; sourceTree = ""; }; - 836F6F0218BDC2190095E648 /* wii_ras.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wii_ras.c; sourceTree = ""; }; + 836F6F0218BDC2190095E648 /* ras.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ras.c; sourceTree = ""; }; 836F6F0418BDC2190095E648 /* wii_sng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wii_sng.c; sourceTree = ""; }; 836F6F0618BDC2190095E648 /* sts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sts.c; sourceTree = ""; }; 836F6F0718BDC2190095E648 /* wpd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wpd.c; sourceTree = ""; }; @@ -1561,7 +1563,7 @@ 836F6F1C18BDC2190095E648 /* vgmstream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vgmstream.c; sourceTree = ""; }; 836F6F1D18BDC2190095E648 /* vgmstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vgmstream.h; sourceTree = ""; }; 83709DFF1ECBC1A4005C03D3 /* ghs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ghs.c; sourceTree = ""; }; - 83709E001ECBC1A4005C03D3 /* mc3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mc3.c; sourceTree = ""; }; + 83709E001ECBC1A4005C03D3 /* mpc3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpc3.c; sourceTree = ""; }; 83709E011ECBC1A4005C03D3 /* mss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mss.c; sourceTree = ""; }; 83709E031ECBC1A4005C03D3 /* aac_triace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aac_triace.c; sourceTree = ""; }; 8373341E23F60CDB00DE14DC /* deblock_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = deblock_streamfile.h; sourceTree = ""; }; @@ -1671,6 +1673,10 @@ 83B46FD42707FB9A00847FC9 /* endianness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = endianness.h; sourceTree = ""; }; 83B69B212845A26600D2435A /* bw_mp3_riff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bw_mp3_riff.c; sourceTree = ""; }; 83B72E342790452C006007A3 /* libfdk-aac.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libfdk-aac.2.dylib"; path = "../../ThirdParty/fdk-aac/lib/libfdk-aac.2.dylib"; sourceTree = ""; }; + 83B8FE2A2D5AB1F5005854C1 /* axhd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = axhd.c; sourceTree = ""; }; + 83B8FE2C2D5AB2A5005854C1 /* shaa.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = shaa.c; sourceTree = ""; }; + 83B8FE2E2D5AB2F4005854C1 /* xwb_konami.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = xwb_konami.c; sourceTree = ""; }; + 83B8FE302D5AB421005854C1 /* undefind.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = undefind.c; sourceTree = ""; }; 83BAFB6B19F45EB3005DAB60 /* bfstm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bfstm.c; sourceTree = ""; }; 83C0C75C2AA435C60056AFD8 /* squeak.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = squeak.c; sourceTree = ""; }; 83C0C75E2AA436370056AFD8 /* layout_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = layout_utils.c; sourceTree = ""; }; @@ -1943,8 +1949,8 @@ 834F7D672C7093EA003AC386 /* l5_555_decoder.c */, 834F7D372C7093EA003AC386 /* libs */, 834F7D682C7093EA003AC386 /* lsf_decoder.c */, - 834F7D692C7093EA003AC386 /* mc3_decoder.c */, 834F7D6A2C7093EA003AC386 /* mp4_aac_decoder.c */, + 834F7D692C7093EA003AC386 /* mpc3_decoder.c */, 834F7D6E2C7093EA003AC386 /* mpeg_custom_utils.c */, 834F7D6B2C7093EA003AC386 /* mpeg_custom_utils_ahx.c */, 834F7D6C2C7093EA003AC386 /* mpeg_custom_utils_ealayer3.c */, @@ -2261,6 +2267,7 @@ 834F7D172C708701003AC386 /* awc_streamfile.h */, 8306B0C32098458C000302D4 /* awc_xma_streamfile.h */, 83FBB1702A4FF4EC00CD0580 /* awd.c */, + 83B8FE2A2D5AB1F5005854C1 /* axhd.c */, 836F6E3618BDC2180095E648 /* baf.c */, 8349A9051FE6258100E26435 /* bar.c */, 8349A8F81FE6257E00E26435 /* bar_streamfile.h */, @@ -2412,7 +2419,6 @@ 836F6E5A18BDC2180095E648 /* lsf.c */, 836F6E5C18BDC2180095E648 /* mattel_hyperscan.c */, 836F6E5D18BDC2180095E648 /* maxis_xa.c */, - 83709E001ECBC1A4005C03D3 /* mc3.c */, 83EDE5D61A70951A005F5D84 /* mca.c */, 836F6E5E18BDC2180095E648 /* meta.h */, 834FE0DE215C79EB000A5D3D /* mib_mih.c */, @@ -2422,6 +2428,8 @@ 8349A9031FE6258100E26435 /* mogg.c */, 836F6E6018BDC2180095E648 /* mp4.c */, 839FBFF926C354E70016A78A /* mp4_faac.c */, + 83709E001ECBC1A4005C03D3 /* mpc3.c */, + 836F6E7218BDC2180095E648 /* mpds.c */, 83FB238D27B14696003F3062 /* mpeg.c */, 83FBB17E2A4FF94C00CD0580 /* msa.c */, 8306B0CB2098458E000302D4 /* msb_msh.c */, @@ -2449,10 +2457,8 @@ 836F6E6818BDC2180095E648 /* nds_hwas.c */, 836F6E6918BDC2180095E648 /* nds_rrds.c */, 836F6E6B18BDC2180095E648 /* nds_strm.c */, - 830165991F256BD000CA0941 /* nds_strm_ffta2.c */, 836F6E6D18BDC2180095E648 /* ngc_adpdtk.c */, 834F7D322C70932C003AC386 /* ngc_dsp_asura.c */, - 836F6E7218BDC2180095E648 /* ngc_dsp_mpds.c */, 836F6E7318BDC2180095E648 /* ngc_dsp_std.c */, 836F6E7518BDC2180095E648 /* ngc_ffcc_str.c */, 836F6E7718BDC2180095E648 /* ngc_lps.c */, @@ -2479,7 +2485,6 @@ 8349A8FB1FE6257F00E26435 /* omu.c */, 8306B0CE2098458E000302D4 /* opus.c */, 8306B0CD2098458E000302D4 /* opus_interleave_streamfile.h */, - 836F6E8318BDC2180095E648 /* otm.c */, 836F6EB218BDC2180095E648 /* p2bt_move_visa.c */, 836F6E8418BDC2180095E648 /* p3d.c */, 831BA6171EAC61A500CF89B0 /* pasx.c */, @@ -2511,7 +2516,6 @@ 836F6EC518BDC2190095E648 /* ps2_tec.c */, 832BF80D21E05148006F50F1 /* ps2_va3.c */, 836F6EC918BDC2190095E648 /* ps2_vbk.c */, - 831BA6101EAC61A500CF89B0 /* ps2_vds_vdm.c */, 836F6ECB18BDC2190095E648 /* ps2_vgv.c */, 836F6ECC18BDC2190095E648 /* ps2_vms.c */, 836F6ECF18BDC2190095E648 /* ps2_wad.c */, @@ -2523,6 +2527,7 @@ 83997F5722D9569E00633184 /* rad.c */, 836F6E5718BDC2180095E648 /* rage_aud.c */, 834F7D2E2C708D31003AC386 /* rage_aud_streamfile.h */, + 836F6F0218BDC2190095E648 /* ras.c */, 837CEAED23487F2C00E62A4A /* raw_int.c */, 837CEADD23487F2A00E62A4A /* raw_pcm.c */, 836F6EE718BDC2190095E648 /* raw_rsf.c */, @@ -2532,6 +2537,7 @@ 836F6EE218BDC2190095E648 /* redspark.c */, 834FE0D9215C79EA000A5D3D /* rfrm.c */, 836F6EE318BDC2190095E648 /* riff.c */, + 830165991F256BD000CA0941 /* riff_ima.c */, 83FBD502235D31F700D35BCD /* riff_ogg_streamfile.h */, 836F6EE418BDC2190095E648 /* rkv.c */, 836F6EE518BDC2190095E648 /* rs03.c */, @@ -2563,6 +2569,7 @@ 83C7280422BC893B00678B4A /* sfh_streamfile.h */, 836F6EF118BDC2190095E648 /* sfl.c */, 831BA6111EAC61A500CF89B0 /* sgxd.c */, + 83B8FE2C2D5AB2A5005854C1 /* shaa.c */, 83AA7F782519C042004C5298 /* silence.c */, 839E21EA1F2EDB0500EE54D7 /* sk_aud.c */, 83CBF5422D46339200AA2D75 /* skex.c */, @@ -2572,6 +2579,7 @@ 837CEAEB23487F2B00E62A4A /* smk.c */, 83F0AA5C21E2028B004BBC04 /* smp.c */, 836F6EBC18BDC2180095E648 /* smpl.c */, + 8349A8F91FE6257E00E26435 /* smss.c */, 8306B0C72098458D000302D4 /* smv.c */, 836F6ED918BDC2190095E648 /* sndp.c */, 83C0C7622AA436B90056AFD8 /* snds.c */, @@ -2601,7 +2609,7 @@ 836F6F0618BDC2190095E648 /* sts.c */, 83AA7F752519C041004C5298 /* svag_kcet.c */, 83AA7F7B2519C042004C5298 /* svag_snk.c */, - 834FE0D7215C79EA000A5D3D /* svg.c */, + 834FE0D7215C79EA000A5D3D /* svgp.c */, 836F6EF918BDC2190095E648 /* svs.c */, 83D0381724A4129A004CF90F /* swav.c */, 83E7FD6425EF2B2400683FD2 /* tac.c */, @@ -2629,12 +2637,14 @@ 8399335D2591E8C0001855AF /* ubi_sb_garbage_streamfile.h */, 8375737521F950EC00F01AF5 /* ubi_sb_streamfile.h */, 834FE0C5215C79E6000A5D3D /* ue4opus.c */, + 83B8FE302D5AB421005854C1 /* undefind.c */, 834FE0DD215C79EB000A5D3D /* utk.c */, 83D1189228B2F33400AF3370 /* vab.c */, 834FE0E4215C79EC000A5D3D /* vag.c */, 834FE0D3215C79E9000A5D3D /* vai.c */, 836F6EC818BDC2190095E648 /* vas_kceo.c */, 834F7D282C708A2F003AC386 /* vas_rockstar.c */, + 831BA6101EAC61A500CF89B0 /* vds_vdm.c */, 836F6EFD18BDC2190095E648 /* vgs.c */, 836F6ECA18BDC2190095E648 /* vgs_ps.c */, 83031ED7243C510400C3F3E0 /* vid1.c */, @@ -2646,23 +2656,21 @@ 832BF81821E0514A006F50F1 /* vs_square.c */, 832BF81021E05149006F50F1 /* vs_str.c */, 836F6EFF18BDC2190095E648 /* vsf.c */, - 8349A8F91FE6257E00E26435 /* vsf_tta.c */, 83F0AA5E21E2028C004BBC04 /* vsv.c */, 83F0AA5D21E2028B004BBC04 /* vsv_streamfile.h */, 8349A9011FE6258000E26435 /* vxn.c */, 83A8BAE025667AA7000F5F3F /* wady.c */, 8306B0C22098458C000302D4 /* waf.c */, + 834FE0CC215C79E8000A5D3D /* wav2.c */, 8306B0C92098458E000302D4 /* wave.c */, 8306B0D02098458F000302D4 /* wave_segmented.c */, 834FE0D0215C79E8000A5D3D /* wavebatch.c */, 836F6ED018BDC2190095E648 /* wb.c */, 83349715275DD2AC00302E21 /* wbk.c */, - 836F6F0218BDC2190095E648 /* wii_ras.c */, 836F6F0418BDC2190095E648 /* wii_sng.c */, 836F6F0718BDC2190095E648 /* wpd.c */, 836F6F0818BDC2190095E648 /* ws_aud.c */, 834FE0CB215C79E8000A5D3D /* wsi.c */, - 834FE0CC215C79E8000A5D3D /* wv2.c */, 834FE0C9215C79E7000A5D3D /* wv6.c */, 836F6F0918BDC2190095E648 /* wvs.c */, 83FF0EBB1E93282100C58054 /* wwise.c */, @@ -2694,6 +2702,7 @@ 834FE0C6215C79E7000A5D3D /* xvag_streamfile.h */, 83A8BAE325667AA7000F5F3F /* xwav.c */, 836F6F1318BDC2190095E648 /* xwb.c */, + 83B8FE2E2D5AB2F4005854C1 /* xwb_konami.c */, 83C727FB22BC893800678B4A /* xwb_xsb.h */, 83A21F7D201D8980000F04B9 /* xwc.c */, 832BF81621E0514A006F50F1 /* xwma.c */, @@ -3107,6 +3116,7 @@ files = ( 834F7DAD2C7093EA003AC386 /* celt_fsb_decoder.c in Sources */, 834FE104215C79ED000A5D3D /* nxa1.c in Sources */, + 83B8FE312D5AB421005854C1 /* undefind.c in Sources */, 8349A9071FE6258200E26435 /* dec.c in Sources */, 83C7281422BC893D00678B4A /* ffdl.c in Sources */, 832BF80721E050DC006F50F1 /* blocked_vs_str.c in Sources */, @@ -3121,7 +3131,7 @@ 8383A62C281203C60062E49E /* s3v.c in Sources */, 8301659B1F256BD000CA0941 /* ea_schl_fixed.c in Sources */, 834F7DEB2C7093EA003AC386 /* oki_decoder.c in Sources */, - 8301659C1F256BD000CA0941 /* nds_strm_ffta2.c in Sources */, + 8301659C1F256BD000CA0941 /* riff_ima.c in Sources */, 83C0C7632AA436B90056AFD8 /* snds.c in Sources */, 834F7ECD2C70A786003AC386 /* mixer_ops_fade.c in Sources */, 834F7EDD2C70A786003AC386 /* streamfile_clamp.c in Sources */, @@ -3170,7 +3180,7 @@ 836F46B32820874D005B9B87 /* esf.c in Sources */, 8306B0EB20984590000302D4 /* wave_segmented.c in Sources */, 836F6F9F18BDC2190095E648 /* musc.c in Sources */, - 8349A9121FE6258200E26435 /* vsf_tta.c in Sources */, + 8349A9121FE6258200E26435 /* smss.c in Sources */, 834F7DDF2C7093EA003AC386 /* msadpcm_decoder.c in Sources */, 836F6FCA18BDC2190095E648 /* ps2_adm.c in Sources */, 836F6FA118BDC2190095E648 /* myspd.c in Sources */, @@ -3205,6 +3215,7 @@ 834F7DCD2C7093EA003AC386 /* clhca.c in Sources */, 834F7DFF2C7093EA003AC386 /* vadpcm_decoder.c in Sources */, 834F7D1C2C708719003AC386 /* cipher_xxtea.c in Sources */, + 83B8FE2D2D5AB2A5005854C1 /* shaa.c in Sources */, 8306B0EF20984590000302D4 /* ubi_bao.c in Sources */, 83AF2CCA26226BA500538240 /* exst.c in Sources */, 8306B0E220984590000302D4 /* smv.c in Sources */, @@ -3219,7 +3230,7 @@ 836F704518BDC2190095E648 /* wvs.c in Sources */, 839FBFFB26C354E70016A78A /* wxd_wxh.c in Sources */, 83EDE5D91A70951A005F5D84 /* btsnd.c in Sources */, - 834F7DD72C7093EA003AC386 /* mc3_decoder.c in Sources */, + 834F7DD72C7093EA003AC386 /* mpc3_decoder.c in Sources */, 834F7ED12C70A786003AC386 /* mixing_commands.c in Sources */, 8306B0E420984590000302D4 /* wave.c in Sources */, 8349A9171FE6258200E26435 /* pc_adp_otns.c in Sources */, @@ -3228,6 +3239,7 @@ 8306B0ED20984590000302D4 /* txtp.c in Sources */, 836F6FA018BDC2190095E648 /* musx.c in Sources */, 836F705818BDC2190095E648 /* vgmstream.c in Sources */, + 83B8FE2F2D5AB2F4005854C1 /* xwb_konami.c in Sources */, 835C883622CC17BE001B4B3F /* bwav.c in Sources */, 8349A90A1FE6258200E26435 /* sab.c in Sources */, 83AF2CC926226BA500538240 /* gcub.c in Sources */, @@ -3289,7 +3301,7 @@ 833E82F02A28587D00CD0580 /* companion_files.c in Sources */, 834F7E072C7093EA003AC386 /* vorbis_custom_utils_sk.c in Sources */, 836F6FD818BDC2190095E648 /* gbts.c in Sources */, - 831BA61A1EAC61A500CF89B0 /* ps2_vds_vdm.c in Sources */, + 831BA61A1EAC61A500CF89B0 /* vds_vdm.c in Sources */, 836F6FF218BDC2190095E648 /* ps2_rnd.c in Sources */, 832BF80521E050DC006F50F1 /* blocked_mul.c in Sources */, 8306B0D920984590000302D4 /* ngc_str_cauldron.c in Sources */, @@ -3366,6 +3378,7 @@ 834F7DF42C7093EA003AC386 /* SASSC_decoder.c in Sources */, 83C7281C22BC893D00678B4A /* sfh.c in Sources */, 834FE0FC215C79ED000A5D3D /* vai.c in Sources */, + 83B8FE2B2D5AB1F5005854C1 /* axhd.c in Sources */, 83D2007F248DDB770048BD24 /* mups.c in Sources */, 83D20080248DDB770048BD24 /* sadf.c in Sources */, 83345A521F8AEB2800B2EAA4 /* xvag.c in Sources */, @@ -3423,7 +3436,7 @@ 834F7DA82C7093EA003AC386 /* libacm_util.c in Sources */, 836F6FD518BDC2190095E648 /* lp_ap_lep.c in Sources */, 8306B0DC20984590000302D4 /* sthd.c in Sources */, - 836F6FAE18BDC2190095E648 /* ngc_dsp_mpds.c in Sources */, + 836F6FAE18BDC2190095E648 /* mpds.c in Sources */, 836F705218BDC2190095E648 /* zwdsp.c in Sources */, 83FBB1722A4FF4EC00CD0580 /* ego_dic.c in Sources */, 836F6FFB18BDC2190095E648 /* ps2_sps.c in Sources */, @@ -3501,7 +3514,7 @@ 831BA6191EAC61A500CF89B0 /* ogl.c in Sources */, 834F7DD32C7093EA003AC386 /* ima_decoder.c in Sources */, 834F7E0B2C7093EA003AC386 /* wady_decoder.c in Sources */, - 83709E061ECBC1A4005C03D3 /* mc3.c in Sources */, + 83709E061ECBC1A4005C03D3 /* mpc3.c in Sources */, 831BA61F1EAC61A500CF89B0 /* cxs.c in Sources */, 83CBF5432D46339200AA2D75 /* skex.c in Sources */, 834F7E182C709A1D003AC386 /* ea_schl_standard.c in Sources */, @@ -3530,7 +3543,7 @@ 834F7DEF2C7093EA003AC386 /* ptadpcm_decoder.c in Sources */, 832BF81F21E0514B006F50F1 /* ps2_va3.c in Sources */, 8349A91C1FE6258200E26435 /* mogg.c in Sources */, - 834FE0F5215C79ED000A5D3D /* wv2.c in Sources */, + 834FE0F5215C79ED000A5D3D /* wav2.c in Sources */, 836F703D18BDC2190095E648 /* mus_krome.c in Sources */, 836F700D18BDC2190095E648 /* ps2_wmus.c in Sources */, 831BA61C1EAC61A500CF89B0 /* sndx.c in Sources */, @@ -3601,7 +3614,7 @@ 836F6F8618BDC2190095E648 /* excitebots.c in Sources */, 8385D4E6245174C700FF8E67 /* diva.c in Sources */, 836F6FF418BDC2190095E648 /* rws_80d.c in Sources */, - 834FE100215C79ED000A5D3D /* svg.c in Sources */, + 834FE100215C79ED000A5D3D /* svgp.c in Sources */, 836F6FE818BDC2190095E648 /* mic_koei.c in Sources */, 834F7DEE2C7093EA003AC386 /* psx_decoder.c in Sources */, 836F46B22820874D005B9B87 /* tt_ad.c in Sources */, @@ -3654,7 +3667,7 @@ 83AA7F822519C042004C5298 /* ktsc.c in Sources */, 836F6FDE18BDC2190095E648 /* ild.c in Sources */, 834F7D332C70932C003AC386 /* ngc_dsp_asura.c in Sources */, - 836F703E18BDC2190095E648 /* wii_ras.c in Sources */, + 836F703E18BDC2190095E648 /* ras.c in Sources */, 834FE0EE215C79ED000A5D3D /* ue4opus.c in Sources */, 8306B0E520984590000302D4 /* ubi_lyn.c in Sources */, 83D2007D248DDB770048BD24 /* kat.c in Sources */, @@ -3681,7 +3694,6 @@ 834F7DAF2C7093EA003AC386 /* circus_vq_lib.c in Sources */, 834FE0F2215C79ED000A5D3D /* wv6.c in Sources */, 836F6FA218BDC2190095E648 /* naomi_adpcm.c in Sources */, - 836F6FBF18BDC2190095E648 /* otm.c in Sources */, 8399335F2591E8C1001855AF /* ifs.c in Sources */, 8373342A23F60CDC00DE14DC /* lrmd.c in Sources */, 836F6FBD18BDC2190095E648 /* nwa.c in Sources */, diff --git a/Frameworks/vgmstream/vgmstream/src/base/api_decode_base.c b/Frameworks/vgmstream/vgmstream/src/base/api_decode_base.c index 82dcf9f80..09ce3d4e9 100644 --- a/Frameworks/vgmstream/vgmstream/src/base/api_decode_base.c +++ b/Frameworks/vgmstream/vgmstream/src/base/api_decode_base.c @@ -1,6 +1,5 @@ #include "api_internal.h" #include "mixing.h" -#if LIBVGMSTREAM_ENABLE #define INTERNAL_BUF_SAMPLES 1024 @@ -104,5 +103,3 @@ int api_get_sample_size(libvgmstream_sample_t sample_type) { return 0x02; } } - -#endif diff --git a/Frameworks/vgmstream/vgmstream/src/base/api_decode_open.c b/Frameworks/vgmstream/vgmstream/src/base/api_decode_open.c index 299e177be..5c6e2a7e7 100644 --- a/Frameworks/vgmstream/vgmstream/src/base/api_decode_open.c +++ b/Frameworks/vgmstream/vgmstream/src/base/api_decode_open.c @@ -1,7 +1,6 @@ #include "api_internal.h" #include "sbuf.h" #include "mixing.h" -#if LIBVGMSTREAM_ENABLE static void load_vgmstream(libvgmstream_priv_t* priv, libvgmstream_options_t* opt) { @@ -106,14 +105,14 @@ static void update_format_info(libvgmstream_priv_t* priv) { } } -LIBVGMSTREAM_API int libvgmstream_open_song(libvgmstream_t* lib, libvgmstream_options_t* opt) { +LIBVGMSTREAM_API int libvgmstream_open_stream(libvgmstream_t* lib, libvgmstream_options_t* opt) { if (!lib ||!lib->priv) return LIBVGMSTREAM_ERROR_GENERIC; if (!opt || !opt->libsf || opt->subsong_index < 0) return LIBVGMSTREAM_ERROR_GENERIC; // close loaded song if any + reset - libvgmstream_close_song(lib); + libvgmstream_close_stream(lib); libvgmstream_priv_t* priv = lib->priv; @@ -131,7 +130,7 @@ LIBVGMSTREAM_API int libvgmstream_open_song(libvgmstream_t* lib, libvgmstream_op } -LIBVGMSTREAM_API void libvgmstream_close_song(libvgmstream_t* lib) { +LIBVGMSTREAM_API void libvgmstream_close_stream(libvgmstream_t* lib) { if (!lib || !lib->priv) return; @@ -142,5 +141,3 @@ LIBVGMSTREAM_API void libvgmstream_close_song(libvgmstream_t* lib) { libvgmstream_priv_reset(priv, true); } - -#endif diff --git a/Frameworks/vgmstream/vgmstream/src/base/api_decode_play.c b/Frameworks/vgmstream/vgmstream/src/base/api_decode_play.c index 31b7173b9..9441e98ef 100644 --- a/Frameworks/vgmstream/vgmstream/src/base/api_decode_play.c +++ b/Frameworks/vgmstream/vgmstream/src/base/api_decode_play.c @@ -2,8 +2,6 @@ #include "mixing.h" #include "render.h" -#if LIBVGMSTREAM_ENABLE - static bool reset_buf(libvgmstream_priv_t* priv) { // state reset @@ -98,24 +96,45 @@ LIBVGMSTREAM_API int libvgmstream_fill(libvgmstream_t* lib, void* buf, int buf_s return LIBVGMSTREAM_ERROR_GENERIC; libvgmstream_priv_t* priv = lib->priv; - if (priv->decode_done) - return LIBVGMSTREAM_ERROR_GENERIC; - if (priv->buf.consumed >= priv->buf.samples) { - int err = libvgmstream_render(lib); - if (err < 0) return err; + bool done = false; + int buf_copied = 0; + while (buf_copied < buf_samples) { + + // decode if no samples in internal buf + if (priv->buf.consumed >= priv->buf.samples) { + if (priv->decode_done) { + done = true; + break; + } + + int err = libvgmstream_render(lib); + if (err < 0) return err; + } + + // copy from partial decode src to partial dst + int buf_left = buf_samples - buf_copied; + int copy_samples = priv->buf.samples - priv->buf.consumed; + if (copy_samples > buf_left) + copy_samples = buf_left; + + int copy_bytes = priv->buf.sample_size * priv->buf.channels * copy_samples; + int skip_bytes = priv->buf.sample_size * priv->buf.channels * priv->buf.consumed; + int copied_bytes = priv->buf.sample_size * priv->buf.channels * buf_copied; + + memcpy( ((uint8_t*)buf) + copied_bytes, ((uint8_t*)priv->buf.data) + skip_bytes, copy_bytes); + priv->buf.consumed += copy_samples; + + buf_copied += copy_samples; } - int copy_samples = priv->buf.samples; - if (copy_samples > buf_samples) - copy_samples = buf_samples; - int copy_bytes = priv->buf.sample_size * priv->buf.channels * copy_samples; - int skip_bytes = priv->buf.sample_size * priv->buf.channels * priv->buf.consumed; + // TODO improve + priv->dec.buf = buf; + priv->dec.buf_samples = buf_copied; + priv->dec.buf_bytes = buf_copied * priv->buf.sample_size * priv->buf.channels; + priv->dec.done = done; - memcpy(buf, ((uint8_t*)priv->buf.data) + skip_bytes, copy_bytes); - priv->buf.consumed += copy_samples; - - return copy_samples; + return 0; } @@ -155,5 +174,3 @@ LIBVGMSTREAM_API void libvgmstream_reset(libvgmstream_t* lib) { } libvgmstream_priv_reset(priv, false); } - -#endif diff --git a/Frameworks/vgmstream/vgmstream/src/base/api_helpers.c b/Frameworks/vgmstream/vgmstream/src/base/api_helpers.c index 42b498d21..e8155de48 100644 --- a/Frameworks/vgmstream/vgmstream/src/base/api_helpers.c +++ b/Frameworks/vgmstream/vgmstream/src/base/api_helpers.c @@ -1,5 +1,4 @@ #include "api_internal.h" -#if LIBVGMSTREAM_ENABLE static int get_internal_log_level(libvgmstream_loglevel_t level) { @@ -60,7 +59,7 @@ LIBVGMSTREAM_API bool libvgmstream_is_valid(const char* filename, libvgmstream_v vgmstream_ctx_valid_cfg icfg = { .is_extension = cfg->is_extension, - .skip_standard = cfg->skip_default, + .skip_standard = cfg->skip_standard, .reject_extensionless = cfg->reject_extensionless, .accept_unknown = cfg->accept_unknown, .accept_common = cfg->accept_common @@ -91,5 +90,3 @@ LIBVGMSTREAM_API int libvgmstream_get_title(libvgmstream_t* lib, libvgmstream_ti LIBVGMSTREAM_API bool libvgmstream_is_virtual_filename(const char* filename) { return vgmstream_is_virtual_filename(filename); } - -#endif diff --git a/Frameworks/vgmstream/vgmstream/src/base/api_internal.h b/Frameworks/vgmstream/vgmstream/src/base/api_internal.h index 289944fd8..1472d4ba4 100644 --- a/Frameworks/vgmstream/vgmstream/src/base/api_internal.h +++ b/Frameworks/vgmstream/vgmstream/src/base/api_internal.h @@ -5,7 +5,6 @@ #include "../vgmstream.h" #include "plugins.h" -#if LIBVGMSTREAM_ENABLE #define LIBVGMSTREAM_OK 0 #define LIBVGMSTREAM_ERROR_GENERIC -1 @@ -63,4 +62,3 @@ int api_get_sample_size(libvgmstream_sample_t sample_type); STREAMFILE* open_api_streamfile(libstreamfile_t* libsf); #endif -#endif diff --git a/Frameworks/vgmstream/vgmstream/src/base/api_libsf.c b/Frameworks/vgmstream/vgmstream/src/base/api_libsf.c index e08e24948..a81fe7c30 100644 --- a/Frameworks/vgmstream/vgmstream/src/base/api_libsf.c +++ b/Frameworks/vgmstream/vgmstream/src/base/api_libsf.c @@ -1,5 +1,4 @@ #include "api_internal.h" -#if LIBVGMSTREAM_ENABLE static libstreamfile_t* libstreamfile_from_streamfile(STREAMFILE* sf); @@ -8,75 +7,75 @@ static libstreamfile_t* libstreamfile_from_streamfile(STREAMFILE* sf); typedef struct { int64_t offset; int64_t size; - STREAMFILE* inner_sf; + STREAMFILE* sf; char name[PATH_LIMIT]; -} libsf_data_t; +} libsf_priv_t; static int libsf_read(void* user_data, uint8_t* dst, int dst_size) { - libsf_data_t* data = user_data; - if (!data || !dst) + libsf_priv_t* priv = user_data; + if (!priv || !dst) return 0; - int bytes = data->inner_sf->read(data->inner_sf, dst, data->offset, dst_size); - data->offset += bytes; + int bytes = priv->sf->read(priv->sf, dst, priv->offset, dst_size); + priv->offset += bytes; return bytes; } static int64_t libsf_seek(void* user_data, int64_t offset, int whence) { - libsf_data_t* data = user_data; - if (!data) + libsf_priv_t* priv = user_data; + if (!priv) return -1; switch (whence) { case LIBSTREAMFILE_SEEK_SET: /* absolute */ break; case LIBSTREAMFILE_SEEK_CUR: /* relative to current */ - offset += data->offset; + offset += priv->offset; break; case LIBSTREAMFILE_SEEK_END: /* relative to file end (should be negative) */ - offset += data->size; + offset += priv->size; break; default: break; } /* clamp offset like fseek */ - if (offset > data->size) - offset = data->size; + if (offset > priv->size) + offset = priv->size; else if (offset < 0) offset = 0; /* main seek */ - data->offset = offset; + priv->offset = offset; return 0; } static int64_t libsf_get_size(void* user_data) { - libsf_data_t* data = user_data; - if (!data) + libsf_priv_t* priv = user_data; + if (!priv) return 0; - return data->size; + return priv->size; } static const char* libsf_get_name(void* user_data) { - libsf_data_t* data = user_data; - if (!data) + libsf_priv_t* priv = user_data; + if (!priv) return NULL; - if (data->name[0] == '\0') { - data->inner_sf->get_name(data->inner_sf, data->name, sizeof(data->name)); + if (priv->name[0] == '\0') { + priv->sf->get_name(priv->sf, priv->name, sizeof(priv->name)); } - return data->name; + return priv->name; } static libstreamfile_t* libsf_open(void* user_data, const char* filename) { - libsf_data_t* data = user_data; - if (!data || !data->inner_sf || !filename) + libsf_priv_t* priv = user_data; + if (!priv || !priv->sf || !filename) return NULL; - STREAMFILE* sf = data->inner_sf->open(data->inner_sf, filename, 0); + STREAMFILE* sf = priv->sf->open(priv->sf, filename, 0); if (!sf) return NULL; @@ -93,11 +92,11 @@ static void libsf_close(libstreamfile_t* libsf) { if (!libsf) return; - libsf_data_t* data = libsf->user_data; - if (data && data->inner_sf) { - data->inner_sf->close(data->inner_sf); + libsf_priv_t* priv = libsf->user_data; + if (priv && priv->sf) { + priv->sf->close(priv->sf); } - free(data); + free(priv); free(libsf); } @@ -106,7 +105,7 @@ static libstreamfile_t* libstreamfile_from_streamfile(STREAMFILE* sf) { return NULL; libstreamfile_t* libsf = NULL; - libsf_data_t* data = NULL; + libsf_priv_t* priv = NULL; libsf = calloc(1, sizeof(libstreamfile_t)); if (!libsf) goto fail; @@ -118,12 +117,12 @@ static libstreamfile_t* libstreamfile_from_streamfile(STREAMFILE* sf) { libsf->open = libsf_open; libsf->close = libsf_close; - libsf->user_data = calloc(1, sizeof(libsf_data_t)); + libsf->user_data = calloc(1, sizeof(libsf_priv_t)); if (!libsf->user_data) goto fail; - data = libsf->user_data; - data->inner_sf = sf; - data->size = get_streamfile_size(sf); + priv = libsf->user_data; + priv->sf = sf; + priv->size = get_streamfile_size(sf); return libsf; fail: @@ -145,4 +144,18 @@ LIBVGMSTREAM_API libstreamfile_t* libstreamfile_open_from_stdio(const char* file return libsf; } -#endif + +LIBVGMSTREAM_API libstreamfile_t* libstreamfile_open_from_file(void* file_, const char* filename) { + FILE* file = file_; + STREAMFILE* sf = open_stdio_streamfile_by_file(file, filename); + if (!sf) + return NULL; + + libstreamfile_t* libsf = libstreamfile_from_streamfile(sf); + if (!libsf) { + close_streamfile(sf); + return NULL; + } + + return libsf; +} diff --git a/Frameworks/vgmstream/vgmstream/src/base/api_libsf_cache.c b/Frameworks/vgmstream/vgmstream/src/base/api_libsf_cache.c new file mode 100644 index 000000000..e73b3108a --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/base/api_libsf_cache.c @@ -0,0 +1,195 @@ +#include "api_internal.h" + +/* libstreamfile_t for external use, that caches some external libsf */ + +/* value can be adjusted freely but 8k is a good enough compromise. */ +#define CACHE_DEFAULT_BUFFER_SIZE 0x8000 + +typedef struct { + libstreamfile_t* libsf; + + int64_t offset; /* last read offset (info) */ + int64_t buf_offset; /* current buffer data start */ + uint8_t* buf; /* data buffer */ + size_t buf_size; /* max buffer size */ + size_t valid_size; /* current buffer size */ + size_t file_size; /* buffered file size */ + + char name[PATH_LIMIT]; +} cache_priv_t; + +static int cache_read(void* user_data, uint8_t* dst, int dst_size) { + cache_priv_t* priv = user_data; + size_t read_total = 0; + if (!dst || dst_size <= 0) + return 0; + + /* is the part of the requested length in the buffer? */ + if (priv->offset >= priv->buf_offset && priv->offset < priv->buf_offset + priv->valid_size) { + size_t buf_limit; + int buf_into = (int)(priv->offset - priv->buf_offset); + + buf_limit = priv->valid_size - buf_into; + if (buf_limit > dst_size) + buf_limit = dst_size; + + memcpy(dst, priv->buf + buf_into, buf_limit); + read_total += buf_limit; + dst_size -= buf_limit; + priv->offset += buf_limit; + dst += buf_limit; + } + + + /* read the rest of the requested length */ + while (dst_size > 0) { + size_t buf_limit; + + /* ignore requests at EOF */ + if (priv->offset >= priv->file_size) { + //offset = priv->file_size; /* seems fseek doesn't clamp offset */ + //VGM_ASSERT_ONCE(offset > sf->file_size, "STDIO: reading over file_size 0x%x @ 0x%lx + 0x%x\n", sf->file_size, offset, length); + break; + } + + /* position to new offset */ + priv->libsf->seek(priv, priv->offset, 0); + + /* fill the buffer (offset now is beyond buf_offset) */ + priv->buf_offset = priv->offset; + priv->valid_size = priv->libsf->read(priv, priv->buf, priv->buf_size); + + /* decide how much must be read this time */ + if (dst_size > priv->buf_size) + buf_limit = priv->buf_size; + else + buf_limit = dst_size; + + /* give up on partial reads (EOF) */ + if (priv->valid_size < buf_limit) { + memcpy(dst, priv->buf, priv->valid_size); + priv->offset += priv->valid_size; + read_total += priv->valid_size; + break; + } + + /* use the new buffer */ + memcpy(dst, priv->buf, buf_limit); + priv->offset += buf_limit; + read_total += buf_limit; + dst_size -= buf_limit; + dst += buf_limit; + } + + return read_total; +} + +static int64_t cache_seek(void* user_data, int64_t offset, int whence) { + cache_priv_t* priv = user_data; + + switch (whence) { + case LIBSTREAMFILE_SEEK_SET: /* absolute */ + break; + case LIBSTREAMFILE_SEEK_CUR: /* relative to current */ + offset += priv->offset; + break; + case LIBSTREAMFILE_SEEK_END: /* relative to file end (should be negative) */ + offset += priv->file_size; + break; + default: + break; + } + + /* clamp offset like fseek */ + if (offset > priv->file_size) + offset = priv->file_size; + else if (offset < 0) + offset = 0; + + /* main seek */ + priv->offset = offset; + return 0; +} + +static int64_t cache_get_size(void* user_data) { + cache_priv_t* priv = user_data; + return priv->file_size; +} + +static const char* cache_get_name(void* user_data) { + cache_priv_t* priv = user_data; + return priv->name; +} + +static libstreamfile_t* cache_open(void* user_data, const char* filename) { + cache_priv_t* priv = user_data; + if (!priv || !priv->libsf || !filename) + return NULL; + + libstreamfile_t* inner_libsf = priv->libsf->open(priv->libsf->user_data, filename); + if (!inner_libsf) + return NULL; + + libstreamfile_t* libsf = libstreamfile_open_buffered(inner_libsf); + if (!libsf) { + libstreamfile_close(inner_libsf); + return NULL; + } + + return libsf; +} + +static void cache_close(libstreamfile_t* libsf) { + if (!libsf) + return; + + cache_priv_t* priv = libsf->user_data; + if (priv && priv->libsf) { + libstreamfile_close(priv->libsf); + } + if (priv) { + free(priv->buf); + } + free(priv); + free(libsf); +} + + +LIBVGMSTREAM_API libstreamfile_t* libstreamfile_open_buffered(libstreamfile_t* ext_libsf) { + if (!ext_libsf) + return NULL; + // not selectable since vgmstream's read patterns don't really fit one buf size + int buf_size = CACHE_DEFAULT_BUFFER_SIZE; + + libstreamfile_t* libsf = NULL; + cache_priv_t* priv = NULL; + + libsf = calloc(1, sizeof(libstreamfile_t)); + if (!libsf) goto fail; + + libsf->read = cache_read; + libsf->seek = cache_seek; + libsf->get_size = cache_get_size; + libsf->get_name = cache_get_name; + libsf->open = cache_open; + libsf->close = cache_close; + + libsf->user_data = calloc(1, sizeof(cache_priv_t)); + if (!libsf->user_data) goto fail; + + priv = libsf->user_data; + priv->libsf = ext_libsf; + priv->buf_size = buf_size; + priv->buf = calloc(buf_size, sizeof(uint8_t)); + if (!priv->buf) goto fail; + + priv->file_size = priv->libsf->get_size(priv->libsf->user_data); + + snprintf(priv->name, sizeof(priv->name), "%s", priv->libsf->get_name(priv->libsf->user_data)); + priv->name[sizeof(priv->name) - 1] = '\0'; + + return libsf; +fail: + cache_close(libsf); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/base/api_tags.c b/Frameworks/vgmstream/vgmstream/src/base/api_tags.c index ed1ed1b2d..320bd5134 100644 --- a/Frameworks/vgmstream/vgmstream/src/base/api_tags.c +++ b/Frameworks/vgmstream/vgmstream/src/base/api_tags.c @@ -1,5 +1,4 @@ #include "api_internal.h" -#if LIBVGMSTREAM_ENABLE typedef struct { VGMSTREAM_TAGS* vtags; @@ -65,5 +64,3 @@ LIBVGMSTREAM_API void libvgmstream_tags_free(libvgmstream_tags_t* tags) { free(tags->priv); free(tags); } - -#endif diff --git a/Frameworks/vgmstream/vgmstream/src/base/decode.c b/Frameworks/vgmstream/vgmstream/src/base/decode.c index 94de7d6f9..52b5d09bb 100644 --- a/Frameworks/vgmstream/vgmstream/src/base/decode.c +++ b/Frameworks/vgmstream/vgmstream/src/base/decode.c @@ -467,12 +467,12 @@ int decode_get_samples_per_frame(VGMSTREAM* vgmstream) { return 1; case coding_PCM4: case coding_PCM4_U: - case coding_IMA_int: - case coding_DVI_IMA_int: + case coding_IMA_mono: + case coding_DVI_IMA_mono: case coding_CAMELOT_IMA: case coding_WV6_IMA: case coding_HV_IMA: - case coding_FFTA2_IMA: + case coding_SQEX_IMA: case coding_BLITZ_IMA: case coding_PCFX: return 2; @@ -566,7 +566,7 @@ int decode_get_samples_per_frame(VGMSTREAM* vgmstream) { return 128*2; case coding_MTA2: return 128*2; - case coding_MC3: + case coding_MPC3: return 10; case coding_FADPCM: return 256; /* (0x8c - 0xc) * 2 */ @@ -682,13 +682,13 @@ int decode_get_frame_size(VGMSTREAM* vgmstream) { case coding_PCM4: case coding_PCM4_U: case coding_IMA: - case coding_IMA_int: + case coding_IMA_mono: case coding_DVI_IMA: - case coding_DVI_IMA_int: + case coding_DVI_IMA_mono: case coding_CAMELOT_IMA: case coding_WV6_IMA: case coding_HV_IMA: - case coding_FFTA2_IMA: + case coding_SQEX_IMA: case coding_BLITZ_IMA: case coding_PCFX: case coding_OKI16: @@ -790,7 +790,7 @@ int decode_get_frame_size(VGMSTREAM* vgmstream) { return vgmstream->interleave_block_size; case coding_MTA2: return 0x90; - case coding_MC3: + case coding_MPC3: return 0x04; case coding_FADPCM: return 0x8c; @@ -1314,13 +1314,13 @@ void decode_vgmstream(sbuf_t* sdst, VGMSTREAM* vgmstream, int samples_to_do) { break; case coding_IMA: - case coding_IMA_int: + case coding_IMA_mono: case coding_DVI_IMA: - case coding_DVI_IMA_int: { + case coding_DVI_IMA_mono: { int is_stereo = (vgmstream->channels > 1 && vgmstream->coding_type == coding_IMA) || (vgmstream->channels > 1 && vgmstream->coding_type == coding_DVI_IMA); int is_high_first = vgmstream->coding_type == coding_DVI_IMA - || vgmstream->coding_type == coding_DVI_IMA_int; + || vgmstream->coding_type == coding_DVI_IMA_mono; for (ch = 0; ch < vgmstream->channels; ch++) { decode_standard_ima(&vgmstream->ch[ch], buffer+ch, vgmstream->channels, vgmstream->samples_into_block, samples_to_do, ch, @@ -1354,9 +1354,9 @@ void decode_vgmstream(sbuf_t* sdst, VGMSTREAM* vgmstream, int samples_to_do) { vgmstream->channels, vgmstream->samples_into_block, samples_to_do); } break; - case coding_FFTA2_IMA: + case coding_SQEX_IMA: for (ch = 0; ch < vgmstream->channels; ch++) { - decode_ffta2_ima(&vgmstream->ch[ch], buffer+ch, + decode_sqex_ima(&vgmstream->ch[ch], buffer+ch, vgmstream->channels, vgmstream->samples_into_block, samples_to_do); } break; @@ -1587,9 +1587,9 @@ void decode_vgmstream(sbuf_t* sdst, VGMSTREAM* vgmstream, int samples_to_do) { vgmstream->channels, vgmstream->samples_into_block, samples_to_do, ch, vgmstream->codec_config); } break; - case coding_MC3: + case coding_MPC3: for (ch = 0; ch < vgmstream->channels; ch++) { - decode_mc3(vgmstream, &vgmstream->ch[ch], buffer+ch, + decode_mpc3(vgmstream, &vgmstream->ch[ch], buffer+ch, vgmstream->channels, vgmstream->samples_into_block, samples_to_do, ch); } break; diff --git a/Frameworks/vgmstream/vgmstream/src/base/info.c b/Frameworks/vgmstream/vgmstream/src/base/info.c index f6610ed60..eea570afc 100644 --- a/Frameworks/vgmstream/vgmstream/src/base/info.c +++ b/Frameworks/vgmstream/vgmstream/src/base/info.c @@ -134,7 +134,7 @@ void describe_vgmstream(VGMSTREAM* vgmstream, char* desc, int length) { case coding_MSADPCM_ck: case coding_MS_IMA: case coding_MS_IMA_mono: - case coding_MC3: + case coding_MPC3: case coding_WWISE_IMA: case coding_REF_IMA: case coding_PSX_cfg: @@ -255,7 +255,7 @@ void describe_vgmstream_info(VGMSTREAM* vgmstream, vgmstream_info* info) { case coding_MSADPCM_ck: case coding_MS_IMA: case coding_MS_IMA_mono: - case coding_MC3: + case coding_MPC3: case coding_WWISE_IMA: case coding_REF_IMA: case coding_PSX_cfg: diff --git a/Frameworks/vgmstream/vgmstream/src/base/streamfile_api.c b/Frameworks/vgmstream/vgmstream/src/base/streamfile_api.c index 4ba8deb07..a4d2acfda 100644 --- a/Frameworks/vgmstream/vgmstream/src/base/streamfile_api.c +++ b/Frameworks/vgmstream/vgmstream/src/base/streamfile_api.c @@ -1,5 +1,4 @@ #include "api_internal.h" -#if LIBVGMSTREAM_ENABLE /* STREAMFILE for internal use, that bridges calls to external libstreamfile_t */ @@ -90,5 +89,3 @@ static STREAMFILE* open_api_streamfile_internal(libstreamfile_t* libsf, bool ext STREAMFILE* open_api_streamfile(libstreamfile_t* libsf) { return open_api_streamfile_internal(libsf, true); } - -#endif diff --git a/Frameworks/vgmstream/vgmstream/src/coding/coding.h b/Frameworks/vgmstream/vgmstream/src/coding/coding.h index 7d2600a60..d4f261735 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/coding.h +++ b/Frameworks/vgmstream/vgmstream/src/coding/coding.h @@ -25,7 +25,7 @@ void decode_snds_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspac void decode_otns_ima(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); void decode_wv6_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); void decode_hv_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); -void decode_ffta2_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); +void decode_sqex_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); void decode_blitz_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do); void decode_mtf_ima(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo); @@ -218,8 +218,8 @@ void decode_mtaf(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, void decode_mta2(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int config); -/* mc3_decoder */ -void decode_mc3(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); +/* mpc3_decoder */ +void decode_mpc3(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel); /* fadpcm_decoder */ diff --git a/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder_utils.c b/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder_utils.c index b048dcb14..3d66f053d 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder_utils.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/ffmpeg_decoder_utils.c @@ -108,15 +108,30 @@ ffmpeg_codec_data* init_ffmpeg_atrac3_riff(STREAMFILE* sf, off_t offset, int* p_ /* well behaved .at3 define "fact" but official tools accept files without it */ if (find_chunk_le(sf, get_id32be("fact"), offset + 0x0c,0, &fact_offset, &fact_size)) { - if (fact_size == 0x08) { /* early AT3 (mainly PSP games) */ + if (fact_size == 0x08) { + /* early AT3 (mainly PSP games) */ fact_samples = read_s32le(fact_offset + 0x00, sf); skip_samples = read_s32le(fact_offset + 0x04, sf); /* base skip samples */ } - else if (fact_size == 0x0c) { /* late AT3 (mainly PS3 games and few PSP games) */ + else if (fact_size == 0x0c) { + /* late AT3 (mainly PS3 games and few PSP games) */ fact_samples = read_s32le(fact_offset + 0x00, sf); /* 0x04: base skip samples, ignored by decoder */ skip_samples = read_s32le(fact_offset + 0x08, sf); /* skip samples with implicit skip of 184 added */ } + else if (fact_size == 0x04) { + /* some ATRAC3 in rare cases [Up (PSP), Flash Motor Karen (PSP)-SND0.at3, Harajuku Tantei Gakuen (PSP)] */ + if (is_at3) // observed default vs sony's tools + skip_samples = 1024; // 1 frame + else if (is_at3p) + skip_samples = 2048; // 1 frame + else + skip_samples = 0; + fact_samples = read_s32le(fact_offset + 0x00, sf); + + //TODO: seems like some at3 made by soundforge may define more fact samples than possible; + // original tools only decode up to EOF [Up (PSP)] + } else { VGM_LOG("ATRAC3: unknown fact size\n"); goto fail; @@ -125,9 +140,9 @@ ffmpeg_codec_data* init_ffmpeg_atrac3_riff(STREAMFILE* sf, off_t offset, int* p_ else { fact_samples = 0; /* tools output 0 samples in this case unless loop end is defined */ if (is_at3) - skip_samples = 1024; /* 1 frame */ + skip_samples = 1024; // 1 frame else if (is_at3p) - skip_samples = 2048; /* 1 frame */ + skip_samples = 2048; // 1 frame else skip_samples = 0; } diff --git a/Frameworks/vgmstream/vgmstream/src/coding/ima_decoder.c b/Frameworks/vgmstream/vgmstream/src/coding/ima_decoder.c index 69f83db38..a4f158a22 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/ima_decoder.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/ima_decoder.c @@ -528,7 +528,7 @@ void decode_hv_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspac } /* FFTA2 IMA, DVI IMA with custom nibble expand/rounding */ -void decode_ffta2_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { +void decode_sqex_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) { int i, sample_count; int32_t hist1 = stream->adpcm_history1_32; int step_index = stream->adpcm_step_index; diff --git a/Frameworks/vgmstream/vgmstream/src/coding/libs/ka1a_dec_data.h b/Frameworks/vgmstream/vgmstream/src/coding/libs/ka1a_dec_data.h index fb7271b32..9243ffb70 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/libs/ka1a_dec_data.h +++ b/Frameworks/vgmstream/vgmstream/src/coding/libs/ka1a_dec_data.h @@ -14,17 +14,17 @@ // default number of quantized coefficients encoded per band, for each bitrate modes static const int BAND_CODES[MAX_BITRATES][MAX_BANDS] = { - {5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, }, - {5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, }, - {5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, }, - {5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, }, - {5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, }, - {5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, }, - {5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, }, - {5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, }, - {5, 5, 5, 5, 5, 5, 5, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, }, - {5, 5, 5, 5, 5, 5, 5, 5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, }, - {5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, }, + {5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, }, + {5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, 3, 3, 3, 3, 3, }, + {5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 3, 3, 3, 3, }, + {5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, }, + {5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 5, 5, 5, 5, 5, 5, }, + {5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, }, + {5, 5, 5, 5, 5, 5, 5, 5, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, 6, }, + {5, 5, 5, 5, 5, 5, 5, 5, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, 7, }, + {5, 5, 5, 5, 5, 5, 5, 5, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, 8, }, + {5, 5, 5, 5, 5, 5, 5, 5, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, 9, }, + {5, 5, 5, 5, 5, 5, 5, 5, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, }, }; // Number of modified coefs to be added/substracted to some bands, for each bitrate mode (varies per frame) @@ -43,7 +43,7 @@ static const int BAND_STEPS[MAX_BANDS] = { // lower bands are 0 since all tables above are fixed to 8 static const int BAND_STEP_BITS[MAX_BANDS] = { - 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 7, 7, + 0, 0, 0, 0, 0, 0, 0, 0, 4, 4, 4, 4, 5, 5, 5, 5, 5, 6, 6, 7, 7, }; // 360 cosine, close to: for (0..256) t[i] = cos(2 * PI * i / points) with some rounding? diff --git a/Frameworks/vgmstream/vgmstream/src/coding/mp4_aac_decoder.c b/Frameworks/vgmstream/vgmstream/src/coding/mp4_aac_decoder.c index 8b550293f..81157b783 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/mp4_aac_decoder.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/mp4_aac_decoder.c @@ -22,218 +22,218 @@ struct mp4_aac_codec_data { MP4FileHandle h_mp4file; MP4TrackId track_id; unsigned long sampleId; - unsigned long numSamples; + unsigned long numSamples; UINT codec_init_data_size; HANDLE_AACDECODER h_aacdecoder; unsigned int sample_ptr; - unsigned int samples_per_frame - unsigned int samples_discard; + unsigned int samples_per_frame + unsigned int samples_discard; INT_PCM sample_buffer[( (6) * (2048)*4 )]; }; // VGM_USE_MP4V2 static void* mp4_file_open( const char* name, MP4FileMode mode ) { - char * endptr; + char * endptr; #ifdef _MSC_VER - unsigned __int64 ptr = _strtoui64( name, &endptr, 16 ); + unsigned __int64 ptr = _strtoui64( name, &endptr, 16 ); #else - unsigned long ptr = strtoul( name, &endptr, 16 ); + unsigned long ptr = strtoul( name, &endptr, 16 ); #endif - return (void*) ptr; + return (void*) ptr; } static int mp4_file_seek( void* handle, int64_t pos ) { - mp4_streamfile * file = ( mp4_streamfile * ) handle; - if ( pos > file->size ) pos = file->size; - pos += file->start; - file->offset = pos; - return 0; + mp4_streamfile * file = ( mp4_streamfile * ) handle; + if ( pos > file->size ) pos = file->size; + pos += file->start; + file->offset = pos; + return 0; } static int mp4_file_get_size( void* handle, int64_t* size ) { - mp4_streamfile * file = ( mp4_streamfile * ) handle; - *size = file->size; - return 0; + mp4_streamfile * file = ( mp4_streamfile * ) handle; + *size = file->size; + return 0; } static int mp4_file_read( void* handle, void* buffer, int64_t size, int64_t* nin, int64_t maxChunkSize ) { - mp4_streamfile * file = ( mp4_streamfile * ) handle; - int64_t max_size = file->size - file->offset - file->start; - if ( size > max_size ) size = max_size; - if ( size > 0 ) - { - *nin = read_streamfile( (uint8_t *) buffer, file->offset, size, file->streamfile ); - file->offset += *nin; - } - else - { - *nin = 0; - return 1; - } - return 0; + mp4_streamfile * file = ( mp4_streamfile * ) handle; + int64_t max_size = file->size - file->offset - file->start; + if ( size > max_size ) size = max_size; + if ( size > 0 ) + { + *nin = read_streamfile( (uint8_t *) buffer, file->offset, size, file->streamfile ); + file->offset += *nin; + } + else + { + *nin = 0; + return 1; + } + return 0; } static int mp4_file_write( void* handle, const void* buffer, int64_t size, int64_t* nout, int64_t maxChunkSize ) { - return 1; + return 1; } static int mp4_file_close( void* handle ) { - return 0; + return 0; } MP4FileProvider mp4_file_provider = { mp4_file_open, mp4_file_seek, mp4_file_read, mp4_file_write, mp4_file_close, mp4_file_get_size }; mp4_aac_codec_data* init_mp4_aac(STREAMFILE* sf) { - char filename[PATH_LIMIT]; - uint32_t start = 0; - uint32_t size = get_streamfile_size(sf); + char filename[PATH_LIMIT]; + uint32_t start = 0; + uint32_t size = get_streamfile_size(sf); - CStreamInfo* stream_info = NULL; + CStreamInfo* stream_info = NULL; - uint8_t* buffer = NULL; - uint32_t buffer_size; - UINT ubuffer_size, bytes_valid; + uint8_t* buffer = NULL; + uint32_t buffer_size; + UINT ubuffer_size, bytes_valid; - mp4_aac_codec_data* data = calloc(1, sizeof(mp4_aac_codec_data)); - if (!data) goto fail; + mp4_aac_codec_data* data = calloc(1, sizeof(mp4_aac_codec_data)); + if (!data) goto fail; - data->if_file.streamfile = sf; - data->if_file.start = start; - data->if_file.offset = start; - data->if_file.size = size; + data->if_file.streamfile = sf; + data->if_file.start = start; + data->if_file.offset = start; + data->if_file.size = size; - /* Big ol' kludge! */ - sprintf( filename, "%p", &data->if_file ); - data->h_mp4file = MP4ReadProvider( filename, &mp4_file_provider ); - if ( !data->h_mp4file ) goto fail; + /* Big ol' kludge! */ + sprintf( filename, "%p", &data->if_file ); + data->h_mp4file = MP4ReadProvider( filename, &mp4_file_provider ); + if ( !data->h_mp4file ) goto fail; - if ( MP4GetNumberOfTracks(data->h_mp4file, MP4_AUDIO_TRACK_TYPE, '\000') != 1 ) goto fail; + if ( MP4GetNumberOfTracks(data->h_mp4file, MP4_AUDIO_TRACK_TYPE, '\000') != 1 ) goto fail; - data->track_id = MP4FindTrackId( data->h_mp4file, 0, MP4_AUDIO_TRACK_TYPE, '\000' ); + data->track_id = MP4FindTrackId( data->h_mp4file, 0, MP4_AUDIO_TRACK_TYPE, '\000' ); - data->h_aacdecoder = aacDecoder_Open( TT_MP4_RAW, 1 ); - if ( !data->h_aacdecoder ) goto fail; + data->h_aacdecoder = aacDecoder_Open( TT_MP4_RAW, 1 ); + if ( !data->h_aacdecoder ) goto fail; - MP4GetTrackESConfiguration( data->h_mp4file, data->track_id, (uint8_t**)(&buffer), (uint32_t*)(&buffer_size)); + MP4GetTrackESConfiguration( data->h_mp4file, data->track_id, (uint8_t**)(&buffer), (uint32_t*)(&buffer_size)); - ubuffer_size = buffer_size; - if ( aacDecoder_ConfigRaw( data->h_aacdecoder, &buffer, &ubuffer_size ) ) goto fail; + ubuffer_size = buffer_size; + if ( aacDecoder_ConfigRaw( data->h_aacdecoder, &buffer, &ubuffer_size ) ) goto fail; - free( buffer ); buffer = NULL; + free( buffer ); buffer = NULL; - data->sampleId = 1; - data->numSamples = MP4GetTrackNumberOfSamples( data->h_mp4file, data->track_id ); + data->sampleId = 1; + data->numSamples = MP4GetTrackNumberOfSamples( data->h_mp4file, data->track_id ); - if (!MP4ReadSample(data->h_mp4file, data->track_id, data->sampleId, (uint8_t**)(&buffer), (uint32_t*)(&buffer_size), 0, 0, 0, 0)) goto fail; + if (!MP4ReadSample(data->h_mp4file, data->track_id, data->sampleId, (uint8_t**)(&buffer), (uint32_t*)(&buffer_size), 0, 0, 0, 0)) goto fail; - ubuffer_size = buffer_size; - bytes_valid = buffer_size; - if ( aacDecoder_Fill( data->h_aacdecoder, &buffer, &ubuffer_size, &bytes_valid ) || bytes_valid ) goto fail; - if ( aacDecoder_DecodeFrame( data->h_aacdecoder, data->sample_buffer, ( (6) * (2048)*4 ), 0 ) ) goto fail; + ubuffer_size = buffer_size; + bytes_valid = buffer_size; + if ( aacDecoder_Fill( data->h_aacdecoder, &buffer, &ubuffer_size, &bytes_valid ) || bytes_valid ) goto fail; + if ( aacDecoder_DecodeFrame( data->h_aacdecoder, data->sample_buffer, ( (6) * (2048)*4 ), 0 ) ) goto fail; - free( buffer ); buffer = NULL; + free( buffer ); buffer = NULL; - data->sample_ptr = 0; + data->sample_ptr = 0; - stream_info = aacDecoder_GetStreamInfo( data->h_aacdecoder ); + stream_info = aacDecoder_GetStreamInfo( data->h_aacdecoder ); - data->samples_per_frame = stream_info->frameSize; - data->samples_discard = 0; + data->samples_per_frame = stream_info->frameSize; + data->samples_discard = 0; - sf->get_name( sf, filename, sizeof(filename) ); + sf->get_name( sf, filename, sizeof(filename) ); - data->if_file.streamfile = sf->open(sf, filename, 0); - if (!data->if_file.streamfile) goto fail; + data->if_file.streamfile = sf->open(sf, filename, 0); + if (!data->if_file.streamfile) goto fail; - return data; + return data; fail: - free( buffer ); buffer = NULL; - free_mp4_aac(data); + free( buffer ); buffer = NULL; + free_mp4_aac(data); } static void convert_samples(INT_PCM * src, sample_t* dest, int32_t count) { - int32_t i; - for ( i = 0; i < count; i++ ) { - INT_PCM sample = *src++; - sample >>= SAMPLE_BITS - 16; - if ( ( sample + 0x8000 ) & 0xFFFF0000 ) sample = 0x7FFF ^ ( sample >> 31 ); - *dest++ = sample; - } + int32_t i; + for ( i = 0; i < count; i++ ) { + INT_PCM sample = *src++; + sample >>= SAMPLE_BITS - 16; + if ( ( sample + 0x8000 ) & 0xFFFF0000 ) sample = 0x7FFF ^ ( sample >> 31 ); + *dest++ = sample; + } } void decode_mp4_aac(mp4_aac_codec_data * data, sample_t* outbuf, int32_t samples_to_do, int channels) { - int samples_done = 0; + int samples_done = 0; - uint8_t * buffer = NULL; - uint32_t buffer_size; - UINT ubuffer_size, bytes_valid; + uint8_t * buffer = NULL; + uint32_t buffer_size; + UINT ubuffer_size, bytes_valid; - CStreamInfo * stream_info = aacDecoder_GetStreamInfo( data->h_aacdecoder ); + CStreamInfo * stream_info = aacDecoder_GetStreamInfo( data->h_aacdecoder ); - int32_t samples_remain = data->samples_per_frame - data->sample_ptr; + int32_t samples_remain = data->samples_per_frame - data->sample_ptr; - if ( data->samples_discard ) { - if ( samples_remain <= data->samples_discard ) { - data->samples_discard -= samples_remain; - samples_remain = 0; - } - else { - samples_remain -= data->samples_discard; - data->sample_ptr += data->samples_discard; - data->samples_discard = 0; - } - } + if ( data->samples_discard ) { + if ( samples_remain <= data->samples_discard ) { + data->samples_discard -= samples_remain; + samples_remain = 0; + } + else { + samples_remain -= data->samples_discard; + data->sample_ptr += data->samples_discard; + data->samples_discard = 0; + } + } - if ( samples_remain > samples_to_do ) samples_remain = samples_to_do; + if ( samples_remain > samples_to_do ) samples_remain = samples_to_do; - convert_samples( data->sample_buffer + data->sample_ptr * stream_info->numChannels, outbuf, samples_remain * stream_info->numChannels ); + convert_samples( data->sample_buffer + data->sample_ptr * stream_info->numChannels, outbuf, samples_remain * stream_info->numChannels ); - outbuf += samples_remain * stream_info->numChannels; + outbuf += samples_remain * stream_info->numChannels; - data->sample_ptr += samples_remain; + data->sample_ptr += samples_remain; - samples_done += samples_remain; + samples_done += samples_remain; - while ( samples_done < samples_to_do ) { - if (data->sampleId >= data->numSamples) { - memset(outbuf, 0, (samples_to_do - samples_done) * stream_info->numChannels * sizeof(sample_t)); - break; - } - if (!MP4ReadSample( data->h_mp4file, data->track_id, ++data->sampleId, (uint8_t**)(&buffer), (uint32_t*)(&buffer_size), 0, 0, 0, 0)) return; - ubuffer_size = buffer_size; - bytes_valid = buffer_size; - if ( aacDecoder_Fill( data->h_aacdecoder, &buffer, &ubuffer_size, &bytes_valid ) || bytes_valid ) { - free( buffer ); - return; - } - if ( aacDecoder_DecodeFrame( data->h_aacdecoder, data->sample_buffer, ( (6) * (2048)*4 ), 0 ) ) { - free( buffer ); - return; - } - free( buffer ); buffer = NULL; - stream_info = aacDecoder_GetStreamInfo( data->h_aacdecoder ); - samples_remain = data->samples_per_frame = stream_info->frameSize; - data->sample_ptr = 0; - if ( data->samples_discard ) { - if ( samples_remain <= data->samples_discard ) { - data->samples_discard -= samples_remain; - samples_remain = 0; - } - else { - samples_remain -= data->samples_discard; - data->sample_ptr = data->samples_discard; - data->samples_discard = 0; - } - } - if ( samples_remain > samples_to_do - samples_done ) samples_remain = samples_to_do - samples_done; - convert_samples( data->sample_buffer + data->sample_ptr * stream_info->numChannels, outbuf, samples_remain * stream_info->numChannels ); - samples_done += samples_remain; - outbuf += samples_remain * stream_info->numChannels; - data->sample_ptr = samples_remain; - } + while ( samples_done < samples_to_do ) { + if (data->sampleId >= data->numSamples) { + memset(outbuf, 0, (samples_to_do - samples_done) * stream_info->numChannels * sizeof(sample_t)); + break; + } + if (!MP4ReadSample( data->h_mp4file, data->track_id, ++data->sampleId, (uint8_t**)(&buffer), (uint32_t*)(&buffer_size), 0, 0, 0, 0)) return; + ubuffer_size = buffer_size; + bytes_valid = buffer_size; + if ( aacDecoder_Fill( data->h_aacdecoder, &buffer, &ubuffer_size, &bytes_valid ) || bytes_valid ) { + free( buffer ); + return; + } + if ( aacDecoder_DecodeFrame( data->h_aacdecoder, data->sample_buffer, ( (6) * (2048)*4 ), 0 ) ) { + free( buffer ); + return; + } + free( buffer ); buffer = NULL; + stream_info = aacDecoder_GetStreamInfo( data->h_aacdecoder ); + samples_remain = data->samples_per_frame = stream_info->frameSize; + data->sample_ptr = 0; + if ( data->samples_discard ) { + if ( samples_remain <= data->samples_discard ) { + data->samples_discard -= samples_remain; + samples_remain = 0; + } + else { + samples_remain -= data->samples_discard; + data->sample_ptr = data->samples_discard; + data->samples_discard = 0; + } + } + if ( samples_remain > samples_to_do - samples_done ) samples_remain = samples_to_do - samples_done; + convert_samples( data->sample_buffer + data->sample_ptr * stream_info->numChannels, outbuf, samples_remain * stream_info->numChannels ); + samples_done += samples_remain; + outbuf += samples_remain * stream_info->numChannels; + data->sample_ptr = samples_remain; + } } @@ -265,9 +265,9 @@ void free_mp4_aac(mp4_aac_codec_data * data) { } void mp4_aac_get_streamfile(mp4_aac_codec_data* data) { - if (!data) - return NULL; - return data->if_file.streamfile; + if (!data) + return NULL; + return data->if_file.streamfile; } int32_t mp4_aac_get_samples(mp4_aac_codec_data* data) { @@ -286,7 +286,7 @@ int mp4_aac_get_sample_rate(mp4_aac_codec_data* data) { if (!data) return 0; - CStreamInfo* stream_info = aacDecoder_GetStreamInfo( data->h_aacdecoder ); + CStreamInfo* stream_info = aacDecoder_GetStreamInfo( data->h_aacdecoder ); return stream_info->sample_rate; } @@ -294,8 +294,8 @@ int mp4_aac_get_channels(mp4_aac_codec_data* data) { if (!data) return 0; - CStreamInfo* stream_info = aacDecoder_GetStreamInfo( data->h_aacdecoder ); - return stream_info->numChannels; + CStreamInfo* stream_info = aacDecoder_GetStreamInfo( data->h_aacdecoder ); + return stream_info->numChannels; } #endif diff --git a/Frameworks/vgmstream/vgmstream/src/coding/mc3_decoder.c b/Frameworks/vgmstream/vgmstream/src/coding/mpc3_decoder.c similarity index 95% rename from Frameworks/vgmstream/vgmstream/src/coding/mc3_decoder.c rename to Frameworks/vgmstream/vgmstream/src/coding/mpc3_decoder.c index 808318a90..c85eacb0f 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/mc3_decoder.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/mpc3_decoder.c @@ -6,7 +6,7 @@ static const int step_table[4] = { 5, 1, -1, -3 }; -static const int mc3_table[4][4][64] = { +static const int mpc3_table[4][4][64] = { { { 2, 2, 3, 7, 15, 27, 45, 70, 104, 148, 202, 268, 347, 441, 551, 677, @@ -122,7 +122,7 @@ static const int mc3_table[4][4][64] = { * * Tables and original algorithm by daemon1 */ -void decode_mc3(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) { +void decode_mpc3(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) { int i, sample_count = 0; int32_t hist = stream->adpcm_history1_32; @@ -135,7 +135,7 @@ void decode_mc3(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf /* block header */ if (first_sample == 0) { - uint32_t header = (uint32_t)read_32bitLE(stream->offset, stream->streamfile); + uint32_t header = read_u32le(stream->offset, stream->streamfile); header = (header >> channel*16); /* lower 16=ch1, upper 16b=ch2 */ step_index = header & 0x3f; /* 6b */ hist = header & 0xffc0; /* 16b sans 6b */ @@ -148,17 +148,17 @@ void decode_mc3(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf uint32_t subblock, mode, samples, index, sign, diff; /* header + ch shift + sub-block number (ex. ch0 i=10: sub-block 1, ch0 i=23: sub-block 2) */ - off_t subblock_offset = stream->offset + 4 + 4*channel + (i/10)*(4*vgmstream->channels); + off_t subblock_offset = stream->offset + 0x04 + 0x04 * channel + (i/10)*(4*vgmstream->channels); int sample_shift = (i%10)*3; /* expand 3b */ - subblock = (uint32_t)read_32bitLE(subblock_offset, stream->streamfile); + subblock = read_u32le(subblock_offset, stream->streamfile); mode = (subblock >> 30) & 0x3; /* upper 2b */ samples = (subblock) & 0x3FFFFFFF; /* lower 3b*10 */ index = (samples >> sample_shift) & 3; /* lower 2b */ sign = (samples >> sample_shift) & 4; /* upper 1b */ - diff = mc3_table[mode][index][step_index]; + diff = mpc3_table[mode][index][step_index]; if (sign == 0) hist += (- 1 - diff); else diff --git a/Frameworks/vgmstream/vgmstream/src/coding/mpeg_custom_utils.c b/Frameworks/vgmstream/vgmstream/src/coding/mpeg_custom_utils.c index d76aa4f9d..cf508a552 100644 --- a/Frameworks/vgmstream/vgmstream/src/coding/mpeg_custom_utils.c +++ b/Frameworks/vgmstream/vgmstream/src/coding/mpeg_custom_utils.c @@ -144,8 +144,13 @@ int mpeg_custom_parse_frame_default(VGMSTREAMCHANNEL* stream, mpeg_codec_data* d current_interleave_pre = current_interleave*num_stream; current_interleave_post = current_interleave*(data->streams_size-1) - current_interleave_pre; + if (stream->offset >= data->config.data_size) { + VGM_LOG_ONCE("MPEG: fsb overread\n"); + return false; + } + if (!mpeg_get_frame_info(stream->streamfile, stream->offset + current_interleave_pre, &info)) - goto fail; + return false; current_data_size = info.frame_size; /* get FSB padding for Layer III or multichannel Layer II (Layer I isn't supported by FMOD). @@ -207,7 +212,7 @@ int mpeg_custom_parse_frame_default(VGMSTREAMCHANNEL* stream, mpeg_codec_data* d else if (ms->current_size_count == data->config.max_chunks) current_interleave = data->config.interleave_last; else - goto fail; + return false; current_interleave_pre = current_interleave*num_stream; current_interleave_post = current_interleave*(data->streams_size-1) - current_interleave_pre; @@ -218,14 +223,14 @@ int mpeg_custom_parse_frame_default(VGMSTREAMCHANNEL* stream, mpeg_codec_data* d break; default: /* standard frames (CBR or VBR) */ - if ( !mpeg_get_frame_info(stream->streamfile, stream->offset, &info) ) - goto fail; + if (!mpeg_get_frame_info(stream->streamfile, stream->offset, &info)) + return false; current_data_size = info.frame_size; break; } if (!current_data_size || current_data_size > ms->buffer_size) { VGM_LOG("MPEG: incorrect data_size 0x%x vs buffer 0x%x\n", current_data_size, ms->buffer_size); - goto fail; + return false; } /* This assumes all streams' offsets start in the first stream, and advances @@ -248,9 +253,7 @@ int mpeg_custom_parse_frame_default(VGMSTREAMCHANNEL* stream, mpeg_codec_data* d } - return 1; -fail: - return 0; + return true; } #endif @@ -359,7 +362,6 @@ uint32_t mpeg_get_tag_size(STREAMFILE* sf, uint32_t offset, uint32_t header) { frame_size += 0x0a; return frame_size; - } /* skip ID3v1 */ diff --git a/Frameworks/vgmstream/vgmstream/src/formats.c b/Frameworks/vgmstream/vgmstream/src/formats.c index 8f6ec98f6..0c07791fd 100644 --- a/Frameworks/vgmstream/vgmstream/src/formats.c +++ b/Frameworks/vgmstream/vgmstream/src/formats.c @@ -23,6 +23,7 @@ static const char* extension_list[] = { //"", /* vgmstream can play extensionless files too, but plugins must accept them manually */ "208", + "2dx", "2dx9", "3do", "3ds", @@ -270,6 +271,7 @@ static const char* extension_list[] = { "ivag", "ivb", "ivs", //txth/reserved [Burnout 2 (PS2)] + "ixa", "joe", "jstm", @@ -408,16 +410,17 @@ static const char* extension_list[] = { "nxa", "nxopus", + "oga", //"ogg", //common "ogg_", "ogl", + "ogs", "ogv", "oma", //FFmpeg/not parsed (ATRAC3/ATRAC3PLUS/MP3/LPCM/WMA) "omu", "opu", //"opus", //common "opusx", - "otm", "oto", //txth/reserved [Vampire Savior (SAT)] "ovb", //txth/semi [namCollection: Tekken (PS2), Tekken 5: Tekken 1-3 (PS2)] @@ -428,7 +431,9 @@ static const char* extension_list[] = { "p2a", //txth/reserved [Thunderhawk Operation Phoenix (PS2)] "p2bt", "p3d", + "paf", "past", + "patch3audio", "pcm", "pdt", "phd", @@ -442,6 +447,8 @@ static const char* extension_list[] = { "psn", "pwb", + "qwv", //txth/reserved [Bishi Bashi Champ Online (AC)] + "r", "rac", //txth/reserved [Manhunt (Xbox)] "rad", @@ -522,6 +529,8 @@ static const char* extension_list[] = { "sgb", "sgd", "sgt", + "shaa", + "shsa", "skx", "slb", //txth/reserved [THE Nekomura no Hitobito (PS2)] "sli", @@ -683,6 +692,7 @@ static const char* extension_list[] = { "xau", "xav", "xb", //txth/reserved [Scooby-Doo! Unmasked (Xbox)] + "xhd", "xen", "xma", "xma2", @@ -833,15 +843,15 @@ static const coding_info coding_info_list[] = { {coding_EA_XAS_V1, "Electronic Arts EA-XAS 4-bit ADPCM v1"}, {coding_IMA, "IMA 4-bit ADPCM"}, - {coding_IMA_int, "IMA 4-bit ADPCM (mono/interleave)"}, + {coding_IMA_mono, "IMA 4-bit ADPCM (mono)"}, {coding_DVI_IMA, "Intel DVI 4-bit IMA ADPCM"}, - {coding_DVI_IMA_int, "Intel DVI 4-bit IMA ADPCM (mono/interleave)"}, + {coding_DVI_IMA_mono, "Intel DVI 4-bit IMA ADPCM (mono)"}, {coding_CAMELOT_IMA, "Camelot IMA 4-bit ADPCM"}, {coding_SNDS_IMA, "Heavy Iron .snds 4-bit IMA ADPCM"}, {coding_QD_IMA, "Quantic Dream 4-bit IMA ADPCM"}, {coding_WV6_IMA, "Gorilla Systems WV6 4-bit IMA ADPCM"}, {coding_HV_IMA, "High Voltage 4-bit IMA ADPCM"}, - {coding_FFTA2_IMA, "Final Fantasy Tactics A2 4-bit IMA ADPCM"}, + {coding_SQEX_IMA, "Square Enix 4-bit IMA ADPCM"}, {coding_BLITZ_IMA, "Blitz Games 4-bit IMA ADPCM"}, {coding_MTF_IMA, "MT Framework 4-bit IMA ADPCM"}, @@ -880,7 +890,7 @@ static const coding_info coding_info_list[] = { {coding_LSF, "Gizmondo Studios Helsingborg LSF 4-bit ADPCM"}, {coding_MTAF, "Konami MTAF 4-bit ADPCM"}, {coding_MTA2, "Konami MTA2 4-bit ADPCM"}, - {coding_MC3, "Paradigm MC3 3-bit ADPCM"}, + {coding_MPC3, "Paradigm MPC3 3-bit ADPCM"}, {coding_FADPCM, "FMOD FADPCM 4-bit ADPCM"}, {coding_ASF, "Argonaut ASF 4-bit ADPCM"}, {coding_TANTALUS, "Tantalus 4-bit ADPCM"}, @@ -1140,7 +1150,7 @@ static const meta_info meta_info_list[] = { {meta_IDSP_IE, "Inevitable Entertainment IDSP Header"}, {meta_UBI_JADE, "Ubisoft Jade RIFF header"}, {meta_SEG, "Stormfront SEG header"}, - {meta_NDS_STRM_FFTA2, "Final Fantasy Tactics A2 RIFF Header"}, + {meta_RIFF_IMA, "Square Enix RIFF IMA eader"}, {meta_KNON, "Paon KNON header"}, {meta_ZWDSP, "Zack and Wiki custom DSP Header"}, {meta_GCA, "GCA DSP Header"}, @@ -1166,7 +1176,7 @@ static const meta_info meta_info_list[] = { {meta_VSF, "Square Enix VSF header"}, {meta_NDS_RRDS, "Ridger Racer DS Header"}, {meta_PS2_SND, "Might and Magic SSND Header"}, - {meta_PS2_VSF_TTA, "VSF with SMSS Header"}, + {meta_SMSS, "Treasure SMSS header"}, {meta_ADS_MIDWAY, "Midway ADS header"}, {meta_PS2_MCG, "Gunvari MCG Header"}, {meta_ZSD, "Konami ZSD header"}, @@ -1178,8 +1188,8 @@ static const meta_info meta_info_list[] = { {meta_NDS_HWAS, "Vicarious Visions HWAS header"}, {meta_NGC_LPS, "Rave Master LPS Header"}, {meta_NAOMI_ADPCM, "NAOMI/NAOMI2 Arcade games ADPCM header"}, - {meta_SD9, "beatmania IIDX SD9 header"}, - {meta_2DX9, "beatmania IIDX 2DX9 header"}, + {meta_SD9, "Konami SD9 header"}, + {meta_2DX9, "Konami 2DX9 header"}, {meta_DSP_KCEJE, "Konami .DSP Header"}, {meta_PS2_VGV, "Rune: Viking Warlord VGV Header"}, {meta_GCUB, "Sega GCub header"}, @@ -1212,7 +1222,7 @@ static const meta_info meta_info_list[] = { {meta_NGC_RKV, "Legacy of Kain - Blood Omen 2 RKV GC header"}, {meta_DSP_DDSP, ".DDSP header"}, {meta_P3D, "Radical P3D header"}, - {meta_NGC_DSP_MPDS, "MPDS DSP header"}, + {meta_MPDS, "Paradigm MPDS header"}, {meta_DSP_STR_IG, "Infogrames .DSP header"}, {meta_EA_SWVR, "Electronic Arts SWVR header"}, {meta_DSP_XIII, "XIII dsp header"}, @@ -1232,7 +1242,7 @@ static const meta_info meta_info_list[] = { {meta_MSF, "Sony MSF header"}, {meta_SNDP, "Premium Agency SNDP header"}, {meta_SGXD, "Sony SGXD header"}, - {meta_WII_RAS, "RAS header"}, + {meta_RAS, "Retro RAS_ header"}, {meta_SPM, "Square SPM header"}, {meta_VGS_PS, "Princess Soft VGS header"}, {meta_PS2_IAB, "Runtime .IAB header"}, @@ -1257,7 +1267,7 @@ static const meta_info meta_info_list[] = { {meta_2PFS, "Konami 2PFS header"}, {meta_UBI_CKD, "Ubisoft CKD RIFF header"}, {meta_PS2_VBK, "PS2 VBK Header"}, - {meta_OTM, "Otomedius OTM Header"}, + {meta_XWB_KONAMI, "Konami .XWB header"}, {meta_CSTM, "Nintendo CSTM Header"}, {meta_FSTM, "Nintendo FSTM Header"}, {meta_KT_WIIBGM, "Koei Tecmo WiiBGM Header"}, @@ -1268,7 +1278,7 @@ static const meta_info meta_info_list[] = { {meta_ADX_MONSTER, "Monster Games .ADX header"}, {meta_HCA, "CRI HCA header"}, {meta_SVAG_SNK, "SNK SVAG header"}, - {meta_PS2_VDS_VDM, "Procyon Studio VDS/VDM header"}, + {meta_VDS_VDM, "Procyon Studio VDS/VDM header"}, {meta_FFMPEG, "FFmpeg supported format"}, {meta_FFMPEG_faulty, "FFmpeg supported format (check log)"}, {meta_CXS, "tri-Crescendo CXS header"}, @@ -1280,7 +1290,7 @@ static const meta_info meta_info_list[] = { {meta_UBI_RAKI, "Ubisoft RAKI header"}, {meta_SNDX, "Sony SNDX header"}, {meta_OGL, "Shin'en OGL header"}, - {meta_MC3, "Paradigm MC3 header"}, + {meta_MPC3, "Paradigm MPC3 header"}, {meta_GHS, "Hexadrive GHS/S_P_STH header"}, {meta_AAC_TRIACE, "tri-Ace AAC header"}, {meta_MTA2, "Konami MTA2 header"}, @@ -1350,12 +1360,12 @@ static const meta_info meta_info_list[] = { {meta_AHV, "Amuze AHV header"}, {meta_MSV, "Sony MultiStream MSV header"}, {meta_SDF, "Beyond Reality SDF header"}, - {meta_SVG, "High Voltage SVG header"}, + {meta_SVGP, "High Voltage SVGp header"}, {meta_VAI, "Asobo Studio .VAI header"}, {meta_AIF_ASOBO, "Asobo Studio .AIF header"}, {meta_AO, "AlphaOgg .AO header"}, {meta_APC, "Cryo APC header"}, - {meta_WV2, "Infogrames North America WAV2 header"}, + {meta_WAV2, "Infogrames North America WAV2 header"}, {meta_XAU_KONAMI, "Konami XAU header"}, {meta_DERF, "Xilam DERF header"}, {meta_UTK, "Maxis UTK header"}, @@ -1462,6 +1472,8 @@ static const meta_info meta_info_list[] = { {meta_PPHD, "Sony PPHD header"}, {meta_XABP, "cavia XABp header"}, {meta_I3DS, "Codemasters i3DS header"}, + {meta_AXHD, "Angel Studios AXHD header"}, + {meta_SHAA, "Nintendo Alarmo SHAA header"} }; void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) { diff --git a/Frameworks/vgmstream/vgmstream/src/libvgmstream.h b/Frameworks/vgmstream/vgmstream/src/libvgmstream.h index 5afd47872..2cc9eba8c 100644 --- a/Frameworks/vgmstream/vgmstream/src/libvgmstream.h +++ b/Frameworks/vgmstream/vgmstream/src/libvgmstream.h @@ -1,18 +1,16 @@ #ifndef _LIBVGMSTREAM_H_ #define _LIBVGMSTREAM_H_ -#define LIBVGMSTREAM_ENABLE 1 -#if LIBVGMSTREAM_ENABLE /* libvgmstream: vgmstream's public API * * Basic usage (also see api_example.c): - * - libvgmstream_init(...) // create context - * - libvgmstream_setup(...) // setup config (if needed) - * - libvgmstream_open_song(...) // open format - * - libvgmstream_render(...) // main decode - * - output samples + repeat libvgmstream_render until stream is done - * - libvgmstream_free(...) // cleanup + * - libvgmstream_init(...) // create context + * - libvgmstream_setup(...) // setup config (if needed) + * - libvgmstream_open_stream(...) // open format + * - libvgmstream_render(...) // main decode + * - output samples + repeat libvgmstream_render until 'done' is set + * - libvgmstream_free(...) // cleanup * * By default vgmstream behaves like a decoder (returns samples until stream end), but you can configure * it to loop N times or even downmix. In other words, it also behaves a bit like a player. @@ -56,9 +54,9 @@ * - only refers to the API itself, changes related to formats/etc don't alter this * - vgmstream's features are mostly stable, but this API may be tweaked from time to time */ -#define LIBVGMSTREAM_API_VERSION_MAJOR 1 // breaking API/ABI changes -#define LIBVGMSTREAM_API_VERSION_MINOR 0 // compatible API/ABI changes -#define LIBVGMSTREAM_API_VERSION_PATCH 0 // fixes +#define LIBVGMSTREAM_API_VERSION_MAJOR 0x01 // breaking API/ABI changes +#define LIBVGMSTREAM_API_VERSION_MINOR 0x00 // compatible API/ABI changes +#define LIBVGMSTREAM_API_VERSION_PATCH 0x00 // fixes /* Current API version, for dynamic checks. returns hex value: 0xMMmmpppp = MM-major, mm-minor, pppp-patch * - use when loading vgmstream as a dynamic library to ensure API/ABI compatibility @@ -75,10 +73,10 @@ LIBVGMSTREAM_API uint32_t libvgmstream_get_version(void); /* interleaved samples: buf[0]=ch0, buf[1]=ch1, buf[2]=ch0, buf[3]=ch0, ... */ typedef enum { - LIBVGMSTREAM_SAMPLE_PCM16 = 0x01, - LIBVGMSTREAM_SAMPLE_PCM24 = 0x02, - LIBVGMSTREAM_SAMPLE_PCM32 = 0x03, - LIBVGMSTREAM_SAMPLE_FLOAT = 0x04, + LIBVGMSTREAM_SAMPLE_PCM16 = 1, + LIBVGMSTREAM_SAMPLE_PCM24 = 2, + LIBVGMSTREAM_SAMPLE_PCM32 = 3, + LIBVGMSTREAM_SAMPLE_FLOAT = 4, } libvgmstream_sample_t; /* current song info, may be copied around (values are info-only) */ @@ -86,12 +84,11 @@ typedef struct { /* main (always set) */ int channels; // output channels int sample_rate; // output sample rate - libvgmstream_sample_t sample_type; // output buffer's sample type int sample_size; // derived from sample_type (pcm16=0x02, float=0x04, etc) /* extra info (may be 0 if not known or not relevant) */ - uint32_t channel_layout; // standard WAVE bitflags + uint32_t channel_layout; // standard WAVE bitflags, 0 if unset or non-standard int subsong_index; // 0 = none, N = loaded subsong N (1=first) int subsong_count; // 0 = format has no concept of subsongs, N = has N subsongs @@ -110,6 +107,7 @@ typedef struct { bool loop_flag; // if file loops // ** false + defined loops means looping was forcefully disabled // ** true + undefined loops means the file loops in a way not representable by loop points + //bool rough_samples; // signal cases where loop points or sample count can't exactly reflect actual behavior bool play_forever; // if file loops forever based on current config (meaning _play never stops) int64_t play_samples; // totals after all calculations (after applying loop/fade/etc config) @@ -117,32 +115,29 @@ typedef struct { // ** if play_forever is set this is still provided for reference based on non-forever config int stream_bitrate; // average bitrate of the subsong (slightly bloated vs codec_bitrate; incorrect in rare cases) - //int codec_bitrate; // average bitrate of the codec data - // ** not possible / slow to calculate in most cases + //int codec_bitrate; // average bitrate of the codec data [not possible / slow to calculate in most cases] /* descriptions */ - char codec_name[128]; // - char layout_name[128]; // - char meta_name[128]; // (not internal "tag" metadata) - char stream_name[256]; // some internal name or representation, not always useful - // ** these are a bit big for a struct, but the typical use case of vgsmtream is opening a file > immediately + char codec_name[128]; // represention of main decoder name + char layout_name[128]; // represention of how data is laid out + char meta_name[128]; // represention of format's name (not internal "tag" metadata) + char stream_name[256]; // stream's internal name or representation (not an internal filename not always useful) + // ** these are a bit big for a struct, but the typical use case of vgmstream is opening a file > immediately // query description and since libvgmstream returns its own copy it shouldn't be too much of a problem // ** (may be separated later) - /* misc */ - //bool rough_samples; // signal cases where loop points or sample count can't exactly reflect actual behavior - int format_id; // when reopening subfiles or similar formats without checking other all possible formats - // ** this value WILL change without warning between vgmstream versions/commits + // ** this value WILL change without warning between vgmstream versions/commits, but usually only add } libvgmstream_format_t; +/* current decoder state */ typedef struct { void* buf; // current decoded buf (valid after _decode until next call; may change between calls) int buf_samples; // current buffer samples (0 is possible in some cases) int buf_bytes; // current buffer bytes (channels * sample_size * samples) - bool done; // when stream is done based on config + bool done; // when stream is done, based on config // ** note that with play_forever this flag is never set } libvgmstream_decoder_t; @@ -183,7 +178,7 @@ typedef struct { double fade_time; // fade period after target loops double fade_delay; // fade delay after target loops - int auto_downmix_channels; // downmixing if vgmstream's channels are higher than value + int auto_downmix_channels; // downmix if vgmstream's channels are higher than value // ** for players that can only handle N channels // ** this type of downmixing is very simplistic and not recommended @@ -218,11 +213,11 @@ typedef struct { * - returns < 0 on error (file not recognised, invalid subsong index, etc) * - will close currently loaded song if needed */ -LIBVGMSTREAM_API int libvgmstream_open_song(libvgmstream_t* lib, libvgmstream_options_t* open_options); +LIBVGMSTREAM_API int libvgmstream_open_stream(libvgmstream_t* lib, libvgmstream_options_t* open_options); /* Closes current song; may still use libvgmstream to open other songs */ -LIBVGMSTREAM_API void libvgmstream_close_song(libvgmstream_t* lib); +LIBVGMSTREAM_API void libvgmstream_close_stream(libvgmstream_t* lib); /* Decodes next batch of samples @@ -232,8 +227,9 @@ LIBVGMSTREAM_API void libvgmstream_close_song(libvgmstream_t* lib); LIBVGMSTREAM_API int libvgmstream_render(libvgmstream_t* lib); /* Same as _play, but fills some external buffer (also updates lib->decoder->* values) - * - returns < 0 on error, or N = number of filled samples. + * - returns < 0 on error * - buf must be at least as big as channels * sample_size * buf_samples + * - note that may return less than requested samples (such as near EOF) * - needs copying around from internal bufs so may be slightly slower; mainly for cases when you have buf constraints */ LIBVGMSTREAM_API int libvgmstream_fill(libvgmstream_t* lib, void* buf, int buf_samples); @@ -289,14 +285,14 @@ LIBVGMSTREAM_API const char** libvgmstream_get_common_extensions(size_t* size); typedef struct { - bool is_extension; /* set if filename is just an extension */ - bool skip_default; /* set if shouldn't check default formats */ - bool reject_extensionless; /* set if player can't play extensionless files */ - bool accept_unknown; /* set to allow any extension (for txth) */ - bool accept_common; /* set to allow known-but-common extension (when player has plugin priority) */ + bool is_extension; /* set if filename is just an extension (otherwise may be seen as 'extensionless') */ + bool skip_standard; /* disable extension check vs default formats */ + bool reject_extensionless; /* enable if player can't play extensionless files */ + bool accept_unknown; /* enable to allow any extension even if not known by vgmstream (for .txth) */ + bool accept_common; /* enable to allow known-but-common extension (when player has plugin priority) */ } libvgmstream_valid_t; -/* Returns if vgmstream can parse a filename by extension, to reject some files earlier +/* Returns if vgmstream can parse a filename by extension, to reject some files earlier. * - doesn't check file contents (that's only done on _open) * - config may be NULL * - mainly for plugins that want to fail early; libvgmstream doesn't use this @@ -363,4 +359,3 @@ LIBVGMSTREAM_API void libvgmstream_tags_free(libvgmstream_tags_t* tags); #endif -#endif diff --git a/Frameworks/vgmstream/vgmstream/src/libvgmstream_streamfile.h b/Frameworks/vgmstream/vgmstream/src/libvgmstream_streamfile.h index 06315b00b..dd52a373f 100644 --- a/Frameworks/vgmstream/vgmstream/src/libvgmstream_streamfile.h +++ b/Frameworks/vgmstream/vgmstream/src/libvgmstream_streamfile.h @@ -1,13 +1,15 @@ #ifndef _LIBVGMSTREAM_STREAMFILE_H_ #define _LIBVGMSTREAM_STREAMFILE_H_ #include "libvgmstream.h" -#if LIBVGMSTREAM_ENABLE -/* vgmstream's IO API, defined as a "streamfile" (SF). +/* vgmstream's IO API, defined as a "streamfile" ('SF'). * - * vgmstream roughly assumes there is an underlying filesystem (as usual in games): seeking + reading from arbitrary offsets, - * opening companion files, filename tests, etc. If your case is too different you may still create a partial streamfile: returning - * a fake filename, only handling "open" that reopens itself (same filename), etc. Simpler formats will probably work just fine. + * vgmstream mostly assumes there is an underlying filesystem (as usual in games), plus given video game formats are + * often ill-defined it needs extra ops to handle edge cases: seeking + reading from arbitrary offsets, opening companion + * files, filename/size tests, etc. + * + * If your case is too different you may still create a partial streamfile: returning a fake filename, only handling "open" + * that reopens itself (same filename), etc. Simpler formats should work fine. */ @@ -19,7 +21,7 @@ enum { //LIBSTREAMFILE_SEEK_GET_SIZE = 5, }; -// maybe "libvgmstream_streamfile_t" but it was getting unwieldly +// should be "libvgmstream_streamfile_t" but it was getting unwieldly typedef struct libstreamfile_t { //uint32_t flags; // info flags for vgmstream void* user_data; // any internal structure @@ -30,11 +32,11 @@ typedef struct libstreamfile_t { int (*read)(void* user_data, uint8_t* dst, int dst_size); /* seek to offset - * - note that vgmstream needs to seek + read fairly often (to be optimized later) + * - note that vgmstream needs to seek + read fairly often (to be optimized someday) */ int64_t (*seek)(void* user_data, int64_t offset, int whence); - /* get max offset (typically for checks or calculations) + /* get max offset (typically for checks or sample calculations) */ int64_t (*get_size)(void* user_data); @@ -47,7 +49,7 @@ typedef struct libstreamfile_t { */ struct libstreamfile_t* (*open)(void* user_data, const char* filename); - /* free current SF (needed for copied streamfiles) */ + /* free current SF */ void (*close)(struct libstreamfile_t* libsf); } libstreamfile_t; @@ -60,8 +62,13 @@ static inline void libstreamfile_close(libstreamfile_t* libsf) { libsf->close(libsf); } - +/* base libstreamfile using STDIO (cached) */ LIBVGMSTREAM_API libstreamfile_t* libstreamfile_open_from_stdio(const char* filename); -#endif +/* base libstreamfile using a FILE (cached); the filename is needed as metadata */ +LIBVGMSTREAM_API libstreamfile_t* libstreamfile_open_from_file(void* file, const char* filename); + + /* cached streamfile (recommended to wrap your external libsf since vgmstream needs to seek a lot) */ +LIBVGMSTREAM_API libstreamfile_t* libstreamfile_open_buffered(libstreamfile_t* ext_libsf); + #endif diff --git a/Frameworks/vgmstream/vgmstream/src/meta/2dx9.c b/Frameworks/vgmstream/vgmstream/src/meta/2dx9.c index 8684eb8cc..464849b60 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/2dx9.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/2dx9.c @@ -1,57 +1,66 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* 2DX9 - from Konami arcade games [beatmaniaIIDX16: EMPRESS (AC), BeatStream (AC), REFLEC BEAT (AC)] */ -VGMSTREAM * init_vgmstream_2dx9(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int channel_count, loop_flag; - - - /* checks */ - if (!check_extensions(streamFile, "2dx9")) - goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x32445839) /* 2DX9 */ - goto fail; - if (read_32bitBE(0x18,streamFile) != 0x52494646) /* RIFF */ - goto fail; - if (read_32bitBE(0x20,streamFile) != 0x57415645) /* WAVE */ - goto fail; - if (read_32bitBE(0x24,streamFile) != 0x666D7420) /* fmt */ - goto fail; - if (read_32bitBE(0x6a,streamFile) != 0x64617461) /* data */ - goto fail; - - /* 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; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = meta_2DX9; - vgmstream->sample_rate = read_32bitLE(0x30,streamFile); - vgmstream->num_samples = read_32bitLE(0x66,streamFile); - if (loop_flag) { - vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile) / 2 / channel_count; - vgmstream->loop_end_sample = vgmstream->num_samples; - } - - vgmstream->coding_type = coding_MSADPCM; - vgmstream->layout_type = layout_none; - vgmstream->frame_size = read_16bitLE(0x38,streamFile); - if (!msadpcm_check_coefs(streamFile, 0x40)) - goto fail; - - if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../coding/coding.h" + +/* 2DX9 - from Konami arcade games [beatmaniaIIDX16: EMPRESS (AC), BeatStream (AC), REFLEC BEAT (AC), Bishi Bashi Channel (AC)] */ +VGMSTREAM* init_vgmstream_2dx9(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int channels, loop_flag; + + + /* checks */ + if (!is_id32be(0x00,sf, "2DX9")) + return NULL; + + // .2dx: container extension (with multiple 2dx9) and debug strings + // .2dx9: header ID + if (!check_extensions(sf, "2dx,2dx9")) + return NULL; + + // 04: RIFF offset + // 08: RIFF size + // 0c: flags? + // 10: samples related? + // 14: loop start + // 18: full RIFF (always MSADPCM w/ fact) + + if (!is_id32be(0x18,sf, "RIFF")) + return NULL; + if (!is_id32be(0x20,sf, "WAVE")) + return NULL; + if (!is_id32be(0x24,sf, "fmt ")) + return NULL; + if (!is_id32be(0x6a,sf, "data")) + return NULL; + + // some data loop from beginning to the end by hardcoded flag so cannot be recognized from sound file + loop_flag = (read_s32le(0x14,sf) > 0); + channels = read_s16le(0x2e,sf); + start_offset = 0x72; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_2DX9; + vgmstream->sample_rate = read_s32le(0x30,sf); + vgmstream->num_samples = read_s32le(0x66,sf); + if (loop_flag) { + vgmstream->loop_start_sample = read_u32le(0x14,sf) / 2 / channels; + vgmstream->loop_end_sample = vgmstream->num_samples; + } + + vgmstream->coding_type = coding_MSADPCM; + vgmstream->layout_type = layout_none; + vgmstream->frame_size = read_u16le(0x38,sf); + if (!msadpcm_check_coefs(sf, 0x40)) + goto fail; + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/a2m.c b/Frameworks/vgmstream/vgmstream/src/meta/a2m.c index 93d41832b..408a61480 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/a2m.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/a2m.c @@ -1,45 +1,45 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* A2M - from Artificial Mind & Movement games [Scooby-Doo! Unmasked (PS2)] */ -VGMSTREAM * init_vgmstream_a2m(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - size_t data_size; - int loop_flag, channel_count; - - - /* checks */ - if ( !check_extensions(streamFile,"int") ) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x41324D00) /* "A2M\0" */ - goto fail; - if (read_32bitBE(0x04,streamFile) != 0x50533200) /* "PS2\0" */ - goto fail; - - start_offset = 0x30; - data_size = get_streamfile_size(streamFile) - start_offset; - channel_count = 2; - loop_flag = 0; - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = meta_A2M; - vgmstream->sample_rate = read_32bitBE(0x10,streamFile); - vgmstream->num_samples = ps_bytes_to_samples(data_size,channel_count); - - vgmstream->coding_type = coding_PSX; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x6000; - - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../coding/coding.h" + +/* A2M - from Artificial Mind & Movement games [Scooby-Doo! Unmasked (PS2)] */ +VGMSTREAM* init_vgmstream_a2m(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + size_t data_size; + int loop_flag, channels; + + + /* checks */ + if (!is_id32be(0x00,sf, "A2M\0")) + return NULL; + if (!is_id32be(0x04,sf, "PS2\0")) + return NULL; + if (!check_extensions(sf,"int") ) + return NULL; + + start_offset = 0x30; + data_size = get_streamfile_size(sf) - start_offset; + channels = 2; + loop_flag = 0; + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_A2M; + vgmstream->sample_rate = read_s32be(0x10,sf); + vgmstream->num_samples = ps_bytes_to_samples(data_size,channels); + + vgmstream->coding_type = coding_PSX; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x6000; + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/adp_ongakukan.c b/Frameworks/vgmstream/vgmstream/src/meta/adp_ongakukan.c index 4bff2e1f4..281003745 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/adp_ongakukan.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/adp_ongakukan.c @@ -9,7 +9,7 @@ VGMSTREAM* init_vgmstream_adp_ongakukan(STREAMFILE* sf) { bool sound_is_adpcm = false; int32_t fmt_size, fmt_offset; int32_t sample_rate, data_size; - int16_t channels; + int16_t channels; int32_t expected_size, pcm_size, diff, fact_offset; /* checks */ @@ -20,12 +20,12 @@ VGMSTREAM* init_vgmstream_adp_ongakukan(STREAMFILE* sf) { /* Format starts like RIFF but doesn't have valid chunks beyond fmt (ADPCM data overwrites anything after 0x2c). */ - start_offset = 0x2c; /* fixed values, basically how Ongakukan does it */ + start_offset = 0x2c; data_size = get_streamfile_size(sf) - start_offset; /* RIFF size seem to match original PCM .wav, while encoded .adp data equals or is slightly smaller that that */ expected_size = (read_u32le(0x04, sf) - 0x24); - pcm_size = data_size * 2 * sizeof(short); // * channels + pcm_size = data_size * 2 * sizeof(short); // * channels diff = expected_size - pcm_size; if (diff < 0 || diff > 14) return NULL; @@ -33,13 +33,13 @@ VGMSTREAM* init_vgmstream_adp_ongakukan(STREAMFILE* sf) { if (!is_id32be(0x08, sf, "WAVE")) return NULL; if (!is_id32be(0x0c, sf, "fmt ")) - return NULL; + return NULL; fmt_size = read_s32le(0x10, sf); /* depending on the adp, fmt_size alternates between 0x10 and 0x12 */ if (fmt_size < 0x10 || fmt_size > 0x12) goto fail; - fmt_offset = 0x14; + fmt_offset = 0x14; if (read_s16le(fmt_offset + 0x00, sf) != 0x0001) /* PCM format */ goto fail; @@ -50,17 +50,17 @@ VGMSTREAM* init_vgmstream_adp_ongakukan(STREAMFILE* sf) { if (read_s16le(fmt_offset + 0x0e, sf) != 16) /* PCM bit depth */ goto fail; /* rest of fmt header is the usual header for 16-bit PCM wav files: bitrate, block size, and the like (see riff.c) */ - /* if fmt_size == 0x12 there is an additional s16 field that may or may not be zero. */ - - /* depending on the adp, "fact" chunk is "movable" as we'll see later. */ - fact_offset = fmt_offset + fmt_size; - if (fact_offset < 0x24 || fact_offset > 0x28) - goto fail; - - /* for next chunk, if "data" then it's at fixed offset (0x24), regardless of fmt_size (fmt_size 0x12 with "data" at 0x24 is possible). - * if "fact" however, offset goes AFTER fmt_size (mostly 0x26 and rarely 0x24). - * "data" has chunk size (does not match ADP size but original WAV) and "fact" chunk size is always 0x04 (whether cut off or otherwise). */ - if (!is_id32be(0x24, sf, "data") && !is_id32be(fact_offset, sf, "fact")) + /* if fmt_size == 0x12 there is an additional s16 field that may or may not be zero. */ + + /* depending on the adp, "fact" chunk is "movable" as we'll see later. */ + fact_offset = fmt_offset + fmt_size; + if (fact_offset < 0x24 || fact_offset > 0x28) + goto fail; + + /* for next chunk, if "data" then it's at fixed offset (0x24), regardless of fmt_size (fmt_size 0x12 with "data" at 0x24 is possible). + * if "fact" however, offset goes AFTER fmt_size (mostly 0x26 and rarely 0x24). + * "data" has chunk size (does not match ADP size but original WAV) and "fact" chunk size is always 0x04 (whether cut off or otherwise). */ + if (!is_id32be(0x24, sf, "data") && !is_id32be(fact_offset, sf, "fact")) goto fail; /* Ongagukan games using this format just read it by checking "ADP" extension in a provided file name, diff --git a/Frameworks/vgmstream/vgmstream/src/meta/adp_wildfire.c b/Frameworks/vgmstream/vgmstream/src/meta/adp_wildfire.c index 0ce5b89d2..d8222d374 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/adp_wildfire.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/adp_wildfire.c @@ -1,6 +1,6 @@ #include "meta.h" -/* ADP - from Wildfire Studios games [Balls of Steel (PC)] */ +/* ADP! - from Wildfire Studios games [Balls of Steel (PC)] */ VGMSTREAM* init_vgmstream_adp_wildfire(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; uint32_t start_offset; @@ -28,7 +28,7 @@ VGMSTREAM* init_vgmstream_adp_wildfire(STREAMFILE* sf) { vgmstream->loop_start_sample = read_s32le(0x08,sf); vgmstream->loop_end_sample = vgmstream->num_samples; - vgmstream->coding_type = coding_DVI_IMA_int; + vgmstream->coding_type = coding_DVI_IMA_mono; vgmstream->layout_type = layout_none; vgmstream->meta_type = meta_ADP_WILDFIRE; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/adpcm_capcom.c b/Frameworks/vgmstream/vgmstream/src/meta/adpcm_capcom.c index c6e83a51c..e90d8c296 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/adpcm_capcom.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/adpcm_capcom.c @@ -1,50 +1,59 @@ -#include "meta.h" -#include "../coding/coding.h" -#include "../util.h" - - -/* .ADX - from Capcom games [Resident Evil: Revelations (Switch), Monster Hunter XX (Switch)] */ -VGMSTREAM * init_vgmstream_adpcm_capcom(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count; - - - /* checks */ - /* .mca: Monster Hunter Generations Ultimate / XX */ - if (!check_extensions(streamFile,"adpcm,mca")) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x02000000) - goto fail; - - channel_count = read_16bitLE(0x04, streamFile); - if (channel_count > 2) goto fail; /* header size seems fixed for mono/stereo */ - /* 0x08: channel size */ - /* 0x0c-14: some config/id? (may be shared between files) */ - loop_flag = read_16bitLE(0x68, streamFile); - - start_offset = 0xd8; /* also fixed for mono/stereo */ - - - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = meta_ADPCM_CAPCOM; - vgmstream->sample_rate = read_32bitLE(0x64,streamFile); /* from first headerm repeated at +0x60 */ - vgmstream->num_samples = read_32bitLE(0x60, streamFile); - vgmstream->loop_start_sample = read_32bitLE(0x6c, streamFile); - vgmstream->loop_end_sample = read_32bitLE(0x70, streamFile) + 1; - - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = read_16bitLE(0x06, streamFile); - dsp_read_coefs_le(vgmstream,streamFile, 0x18, 0x60); - - if (!vgmstream_open_stream(vgmstream,streamFile, start_offset)) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../coding/coding.h" +#include "../util.h" + + +/* .ADPCM - from Capcom games [Resident Evil: Revelations (Switch), Monster Hunter XX (Switch)] */ +VGMSTREAM* init_vgmstream_adpcm_capcom(STREAMFILE* sf) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + int loop_flag, channels; + + + /* checks */ + if (read_u32be(0x00,sf) != 0x02000000) + return NULL; + /* .adpcm: common + * .mca: Monster Hunter Generations Ultimate / XX */ + if (!check_extensions(sf,"adpcm,mca")) + return NULL; + + channels = read_u16le(0x04, sf); + if (channels < 1 || channels > 2) + return NULL; + int interleave = read_u16le(0x06, sf); + if (interleave != 0x100) //even in mono + return NULL; + int channel_size = read_u32le(0x08, sf); + if (channel_size == 0 || channel_size * channels > get_streamfile_size(sf)) + return NULL; + + /* 0x0c-14: some config/id? (may be shared between files) */ + loop_flag = read_s16le(0x68, sf); + + // header seems fixed for mono/stereo + start_offset = 0xd8; + + + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_ADPCM_CAPCOM; + vgmstream->sample_rate = read_s32le(0x64,sf); /* from first header repeated at +0x60 */ + vgmstream->num_samples = read_s32le(0x60, sf); + vgmstream->loop_start_sample = read_s32le(0x6c, sf); + vgmstream->loop_end_sample = read_s32le(0x70, sf) + 1; + + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = interleave; + dsp_read_coefs_le(vgmstream,sf, 0x18, 0x60); + + if (!vgmstream_open_stream(vgmstream,sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ads.c b/Frameworks/vgmstream/vgmstream/src/meta/ads.c index aa0c8ce65..b8e97eb9e 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ads.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ads.c @@ -15,7 +15,7 @@ VGMSTREAM* init_vgmstream_ads(STREAMFILE* sf) { /* checks */ if (!is_id32be(0x00,sf,"SShd")) - goto fail; + return NULL; /* .ads: actual extension * .ss2: demuxed videos (fake?) @@ -25,15 +25,15 @@ VGMSTREAM* init_vgmstream_ads(STREAMFILE* sf) { * .800: Mobile Suit Gundam: The One Year War (PS2) * .sdl: Innocent Life: A Futuristic Harvest Moon (Special Edition) (PS2) */ if (!check_extensions(sf, "ads,ss2,pcm,adx,,800,sdl")) - goto fail; + return NULL; if (read_u32le(0x04,sf) != 0x18 && /* standard header size */ read_u32le(0x04,sf) != 0x20 && /* True Fortune (PS2) */ read_u32le(0x04,sf) != get_streamfile_size(sf) - 0x08) /* Katamari Damacy videos */ - goto fail; + return NULL; if (!is_id32be(0x20,sf,"SSbd")) - goto fail; + return NULL; /* base values (a bit unorderly since devs hack ADS too much and detection is messy) */ { @@ -52,7 +52,7 @@ VGMSTREAM* init_vgmstream_ads(STREAMFILE* sf) { if (sample_rate == 12000 && interleave == 0x200) { sample_rate = 48000; interleave = 0x40; - coding_type = coding_DVI_IMA_int; + coding_type = coding_DVI_IMA_mono; /* should try to detect IMA data but it's not so easy, this works ok since * no known games use these settings, videos normally are 48000/24000hz */ } @@ -281,7 +281,7 @@ VGMSTREAM* init_vgmstream_ads(STREAMFILE* sf) { case coding_PSX: vgmstream->num_samples = ps_bytes_to_samples(stream_size, channels); break; - case coding_DVI_IMA_int: + case coding_DVI_IMA_mono: vgmstream->num_samples = ima_bytes_to_samples(stream_size, channels); break; default: diff --git a/Frameworks/vgmstream/vgmstream/src/meta/aifc.c b/Frameworks/vgmstream/vgmstream/src/meta/aifc.c index ec376a1ce..34fc6aa01 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/aifc.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/aifc.c @@ -206,7 +206,7 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) { break; case 0x41445034: /* "ADP4" */ - coding_type = coding_DVI_IMA_int; + coding_type = coding_DVI_IMA_mono; if (channels != 1) break; /* don't know how stereo DVI is laid out */ break; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/apple_caff.c b/Frameworks/vgmstream/vgmstream/src/meta/apple_caff.c index 979bda1ca..7942c1f81 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/apple_caff.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/apple_caff.c @@ -6,10 +6,9 @@ VGMSTREAM* init_vgmstream_apple_caff(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; off_t start_offset = 0, chunk_offset; size_t file_size, data_size = 0; - int loop_flag, channel_count = 0, sample_rate = 0; + int loop_flag, channels = 0, sample_rate = 0; - int found_desc = 0 /*, found_pakt = 0*/, found_data = 0; - uint32_t codec = 0 /*, codec_flags = 0*/; + uint32_t codec = 0, codec_flags = 0; uint32_t bytes_per_packet = 0, samples_per_packet = 0, channels_per_packet = 0, bits_per_sample = 0; int valid_samples = 0 /*, priming_samples = 0, unused_samples = 0*/; @@ -17,7 +16,7 @@ VGMSTREAM* init_vgmstream_apple_caff(STREAMFILE* sf) { /* checks */ if (!is_id32be(0x00,sf, "caff")) return NULL; - if (read_32bitBE(0x04,sf) != 0x00010000) /* version/flags */ + if (read_u32be(0x04,sf) != 0x00010000) /* version/flags */ return NULL; if (!check_extensions(sf, "caf")) return NULL; @@ -25,6 +24,7 @@ VGMSTREAM* init_vgmstream_apple_caff(STREAMFILE* sf) { file_size = get_streamfile_size(sf); chunk_offset = 0x08; + bool found_desc = false, found_data = false; while (chunk_offset < file_size) { uint32_t chunk_type = read_u32be(chunk_offset+0x00,sf); uint32_t chunk_size = (uint32_t)read_u64be(chunk_offset+0x04,sf); @@ -33,22 +33,15 @@ VGMSTREAM* init_vgmstream_apple_caff(STREAMFILE* sf) { switch (chunk_type) { case 0x64657363: /* "desc" */ - found_desc = 1; + found_desc = true; - { - uint64_t sample_long = read_u64be(chunk_offset+0x00, sf); - double* sample_double; /* double sample rate, double the fun */ - - sample_double = (double*)&sample_long; - sample_rate = (int)(*sample_double); - } - - codec = read_32bitBE(chunk_offset+0x08, sf); - //codec_flags = read_32bitBE(chunk_offset+0x0c, streamFile); - bytes_per_packet = read_32bitBE(chunk_offset+0x10, sf); - samples_per_packet = read_32bitBE(chunk_offset+0x14, sf); - channels_per_packet = read_32bitBE(chunk_offset+0x18, sf); - bits_per_sample = read_32bitBE(chunk_offset+0x1C, sf); + sample_rate = (int)read_d64be(chunk_offset+0x00, sf); /* double sample rate, double the fun */ + codec = read_u32be(chunk_offset+0x08, sf); + codec_flags = read_u32be(chunk_offset+0x0c, sf); + bytes_per_packet = read_u32be(chunk_offset+0x10, sf); + samples_per_packet = read_u32be(chunk_offset+0x14, sf); + channels_per_packet = read_u32be(chunk_offset+0x18, sf); + bits_per_sample = read_u32be(chunk_offset+0x1C, sf); break; case 0x70616b74: /* "pakt" */ @@ -56,12 +49,12 @@ VGMSTREAM* init_vgmstream_apple_caff(STREAMFILE* sf) { //packets_table_size = (uint32_t)read_u64be(chunk_offset+0x00,streamFile); /* 0 for constant bitrate */ valid_samples = (uint32_t)read_u64be(chunk_offset+0x08,sf); - //priming_samples = read_32bitBE(chunk_offset+0x10,streamFile); /* encoder delay samples */ - //unused_samples = read_32bitBE(chunk_offset+0x14,streamFile); /* footer samples */ + //priming_samples = read_u32be(chunk_offset+0x10,streamFile); /* encoder delay samples */ + //unused_samples = read_u32be(chunk_offset+0x14,streamFile); /* footer samples */ break; case 0x64617461: /* "data" */ - found_data = 1; + found_data = true; /* 0x00: version? 0x00/0x01 */ start_offset = chunk_offset + 0x04; @@ -83,11 +76,11 @@ VGMSTREAM* init_vgmstream_apple_caff(STREAMFILE* sf) { loop_flag = 0; - channel_count = channels_per_packet; + channels = channels_per_packet; /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); + vgmstream = allocate_vgmstream(channels, loop_flag); if (!vgmstream) goto fail; vgmstream->meta_type = meta_CAFF; @@ -97,12 +90,19 @@ VGMSTREAM* init_vgmstream_apple_caff(STREAMFILE* sf) { case 0x6C70636D: /* "lpcm" */ vgmstream->num_samples = valid_samples; if (!vgmstream->num_samples) - vgmstream->num_samples = pcm_bytes_to_samples(data_size, channel_count, bits_per_sample); + vgmstream->num_samples = pcm_bytes_to_samples(data_size, channels, bits_per_sample); - //todo check codec_flags for BE/LE, signed/etc if (bits_per_sample == 8) { vgmstream->coding_type = coding_PCM8; } + else if (bits_per_sample == 16) { + if (codec_flags == 0) + vgmstream->coding_type = coding_PCM16BE; // Treasure Story (iOS)-fertilize_crop + else if (codec_flags == 2) + vgmstream->coding_type = coding_PCM16LE; // Katamari Amore (iOS), Soul Tamer Kiki HD (iOS) + else + goto fail; + } else { goto fail; } @@ -114,7 +114,7 @@ VGMSTREAM* init_vgmstream_apple_caff(STREAMFILE* sf) { case 0x696D6134: /* "ima4" [Vectros (iOS), Dragon Quest (iOS)] */ vgmstream->num_samples = valid_samples; if (!vgmstream->num_samples) /* rare [Endless Fables 2 (iOS) */ - vgmstream->num_samples = apple_ima4_bytes_to_samples(data_size, channel_count); + vgmstream->num_samples = apple_ima4_bytes_to_samples(data_size, channels); vgmstream->coding_type = coding_APPLE_IMA4; vgmstream->layout_type = layout_interleave; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/axhd.c b/Frameworks/vgmstream/vgmstream/src/meta/axhd.c new file mode 100644 index 000000000..1f15868f6 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/axhd.c @@ -0,0 +1,118 @@ +#include "meta.h" +#include "../coding/coding.h" +#include "../util/meta_utils.h" + + + /* AXHD - Anges Studios bank format [Red Dead Revolver (Xbox), Spy Hunter 2 (Xbox)] */ +VGMSTREAM* init_vgmstream_axhd(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + + + /* checks */ + if (!is_id32be(0x00,sf, "AXHD")) + return NULL; + if (read_u8(0x04, sf) != 0x82) //version? + return NULL; + + /* .xhd+xbd: from bigfiles */ + if (!check_extensions(sf, "xhd")) + return NULL; + + meta_header_t h = { + .meta = meta_AXHD, + }; + + h.target_subsong = sf->stream_index; + if (h.target_subsong == 0) + h.target_subsong = 1; + + // bank format somewhat like hd+bd from the PS2 versions + int codec = 0; + uint32_t table1_offset = 0x05; + + // base sections (typically only 1) + int sections = read_u8(table1_offset,sf); + table1_offset += 0x01; + for (int i = 0; i < sections; i++) { + uint32_t table2_offset = read_u16le(table1_offset, sf); + table1_offset += 0x02; + + // entries per section (usually 1 per subsong) + uint32_t subsections = read_u8(table2_offset, sf); + // 01: flags? + table2_offset += 0x01 + 0x04; + for (int j = 0; j < subsections; j++) { + uint32_t table3_offset = read_u16le(table2_offset, sf); + table2_offset += 0x02; + + int sounds = read_u8(table3_offset, sf); + // 01: flags? + // 05: subflags? + table3_offset += 0x01 + 0x04 + 0x02; + for (int k = 0; k < sounds; k++) { + uint32_t sound_offset = read_u16le(table3_offset, sf); + table3_offset += 0x02; + + h.total_subsongs++; + if (h.target_subsong != h.total_subsongs) + continue; + + h.stream_offset = read_u32le(sound_offset + 0x00, sf); + // 04: flags (volume/pitch related?) + info? + int fmt_size = read_u8(sound_offset + 0x21, sf); + h.stream_size = read_u32le(sound_offset + 0x22, sf); + if (fmt_size == 0) { //dummy entry + codec = 0; + h.channels = 1; + h.sample_rate = 44100; + continue; + } +VGM_LOG("%x: %x + %x\n", sound_offset, h.stream_offset, h.stream_size ); + // fmt + codec = read_u16le(sound_offset + 0x26, sf); + h.channels = read_u16le(sound_offset + 0x28, sf); + h.sample_rate = read_s32le(sound_offset + 0x2a, sf); + // 2e: average bitrate + // 32: block size + // 34: bits + + //TODO: this format repeats streams offsets for different entries + } + } + } + + switch (codec) { + case 0x00: + h.coding = coding_SILENCE; + h.layout = layout_none; + h.num_samples = h.sample_rate; + break; + case 0x01: + h.coding = coding_PCM16LE; + h.interleave = 0x02; + h.layout = layout_interleave; + h.num_samples = pcm16_bytes_to_samples(h.stream_size, h.channels); + break; + case 0x69: + h.coding = coding_XBOX_IMA; + h.layout = layout_none; + h.num_samples = xbox_ima_bytes_to_samples(h.stream_size, h.channels); + break; + default: + goto fail; + } + h.open_stream = true; + h.has_subsongs = true; + + h.sf_head = sf; + h.sf_body = open_streamfile_by_ext(sf,"xbd"); + if (!h.sf_body) goto fail; + + vgmstream = alloc_metastream(&h); + close_streamfile(h.sf_body); + return vgmstream; +fail: + close_streamfile(h.sf_body); + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/bfwav.c b/Frameworks/vgmstream/vgmstream/src/meta/bfwav.c index 4bf7f1ba1..48a2d0941 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/bfwav.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/bfwav.c @@ -227,7 +227,7 @@ static VGMSTREAM* init_vgmstream_bxwav(STREAMFILE* sf, bxwav_type_t type) { break; case 0x03: - vgmstream->coding_type = coding_IMA_int; // 3DS eShop applet (3DS) + vgmstream->coding_type = coding_IMA_mono; // 3DS eShop applet (3DS) /* hist is read below */ break; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/bnk_sony.c b/Frameworks/vgmstream/vgmstream/src/meta/bnk_sony.c index 67d2890ed..32e52f8f6 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/bnk_sony.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/bnk_sony.c @@ -43,16 +43,23 @@ typedef struct { int32_t num_samples; int32_t loop_start; int32_t loop_end; + int32_t loop_length; int32_t encoder_delay; uint32_t start_offset; uint32_t stream_offset; uint32_t stream_size; - uint32_t interleave; + uint32_t interleave; //hardcoded in most versions uint16_t stream_flags; + uint32_t atrac9_info; + + uint32_t extradata_size; + uint32_t postdata_size; + + uint32_t subtype; } bnk_header_t; static bool parse_bnk_v3(STREAMFILE* sf, bnk_header_t* h); @@ -63,15 +70,15 @@ static bool parse_bnk_v3(STREAMFILE* sf, bnk_header_t* h); VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) { VGMSTREAM* vgmstream = NULL; char file_name[STREAM_NAME_SIZE]; - bnk_header_t h = {0}; /* checks */ if (!check_extensions(sf, "bnk")) return NULL; + + bnk_header_t h = {0}; if (!parse_bnk_v3(sf, &h)) return NULL; - /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(h.channels, h.loop_flag); if (!vgmstream) goto fail; @@ -107,7 +114,6 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) { VGMSTREAM* temp_vs = NULL; STREAMFILE* temp_sf = NULL; - /* try with both stream_name and bank_name/stream_name? */ temp_sf = open_streamfile_by_filename(sf, h.stream_name); if (!temp_sf) { /* create dummy stream if it can't be found */ @@ -159,7 +165,6 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) { VGMSTREAM* temp_vs = NULL; STREAMFILE* temp_sf = NULL; - temp_sf = setup_subfile_streamfile(sf, h.start_offset, h.stream_size, "at9"); if (!temp_sf) goto fail; @@ -215,6 +220,9 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) { #endif case PCM16: + if (h.interleave == 0) + h.interleave = 0x02; + vgmstream->coding_type = h.big_endian ? coding_PCM16BE : coding_PCM16LE; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = h.interleave; @@ -225,6 +233,9 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) { break; case PSX: + if (h.interleave == 0) + h.interleave = 0x10; + vgmstream->coding_type = coding_PSX; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = h.interleave; @@ -235,6 +246,9 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) { break; case HEVAG: + if (h.interleave == 0) + h.interleave = 0x10; + vgmstream->coding_type = coding_HEVAG; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = h.interleave; @@ -386,7 +400,7 @@ static bool process_tables(STREAMFILE* sf, bnk_header_t* h) { * - find if one section points to the selected material, and get section name = stream name */ switch(h->sblk_version) { - case 0x01: /* Ratchet & Clank (PS2) */ + case 0x01: /* NHL FaceOff 2003 (PS2), Ratchet & Clank (PS2) */ h->sounds_entries = read_u16(h->sblk_offset+0x16,sf); /* entry size: ~0x0c */ h->grains_entries = read_u16(h->sblk_offset+0x18,sf); /* entry size: ~0x28 */ h->stream_entries = read_u16(h->sblk_offset+0x1a,sf); /* entry size: none (count) */ @@ -638,6 +652,8 @@ static bool process_headers(STREAMFILE* sf, bnk_header_t* h) { case 0x1c: case 0x23: h->stream_offset = read_u32(sndh_offset+0x00,sf); + h->sample_rate = 48000; // no sample rate (probably fixed to 48000/system's, but seen in RIFF) + /* rest is part of data, handled later */ break; @@ -720,7 +736,7 @@ static bool process_names(STREAMFILE* sf, bnk_header_t* h) { } } //goto fail; /* didn't find any valid index? */ -loop_break: + loop_break: break; case 0x04: @@ -814,9 +830,64 @@ fail: return false; } +static void process_extradata_base(STREAMFILE* sf, bnk_header_t* h, uint32_t info_offset) { + read_u32_t read_u32 = h->big_endian ? read_u32be : read_u32le; + + h->subtype = read_u32(info_offset + 0x00, sf); //maybe flags? + // 0x04: type? always 1 + h->extradata_size = read_u32(info_offset + 0x08, sf); + // 0x0c: null? (part of size?) */ + + h->extradata_size += 0x10; +} + +static void process_extradata_0x10_pcm_psx(STREAMFILE* sf, bnk_header_t* h, uint32_t info_offset) { + read_u32_t read_u32 = h->big_endian ? read_u32be : read_u32le; + read_s32_t read_s32 = h->big_endian ? read_s32be : read_s32le; + + h->num_samples = read_s32(info_offset + 0x10, sf); // typically null, see rarely in v0x09 (PSX) and v0x1a~0x23 (PCM)) + h->channels = read_u32(info_offset + 0x14, sf); + h->loop_start = read_s32(info_offset + 0x18, sf); + h->loop_length = read_s32(info_offset + 0x1c, sf); +} + +static void process_extradata_0x14_atrac9(STREAMFILE* sf, bnk_header_t* h, uint32_t info_offset) { + read_u32_t read_u32 = h->big_endian ? read_u32be : read_u32le; + read_s32_t read_s32 = h->big_endian ? read_s32be : read_s32le; + + if (read_u32(info_offset + 0x08, sf) != 0x14) { + vgm_logi("BNK: unexpected extradata size (report)\n"); + return; + } + + // 0x08: extradata size (0x14) + h->atrac9_info = read_u32be(info_offset + 0x0c, sf); + // 0x10: null? + h->loop_length = read_s32(info_offset + 0x14, sf); + h->loop_start = read_s32(info_offset + 0x18, sf); // *after* length unlike PCM/PSX +} + +static void process_extradata_0x80_atrac9(STREAMFILE* sf, bnk_header_t* h, uint32_t info_offset) { + read_u32_t read_u32 = h->big_endian ? read_u32be : read_u32le; + read_s32_t read_s32 = h->big_endian ? read_s32be : read_s32le; + + if (read_u32(info_offset + 0x10, sf) != 0x80) { + vgm_logi("BNK: unexpected extradata size (report)\n"); + return; + } + + // 0x10: extradata size (0x80) + h->atrac9_info = read_u32be(info_offset + 0x14, sf); + // 0x18: null? + h->channels = read_u32(info_offset + 0x1c, sf); + // 0x20: null? + h->loop_length = read_s32(info_offset + 0x24, sf); + h->loop_start = read_s32(info_offset + 0x28, sf); // *after* length unlike PCM/PSX (confirmed in both raw and RIFF) + // rest: padding +} + /* data part: parse extradata before the codec */ static bool process_data(STREAMFILE* sf, bnk_header_t* h) { - read_u16_t read_u16 = h->big_endian ? read_u16be : read_u16le; read_u32_t read_u32 = h->big_endian ? read_u32be : read_u32le; read_s32_t read_s32 = h->big_endian ? read_s32be : read_s32le; read_u64_t read_u64 = h->big_endian ? read_u64be : read_u64le; @@ -825,12 +896,7 @@ static bool process_data(STREAMFILE* sf, bnk_header_t* h) { if (h->zlsd_offset && h->target_subsong > h->total_subsongs) return true; - int subtype, loop_length; - uint32_t extradata_size = 0, postdata_size = 0; - uint32_t stream_name_size, stream_name_offset; - h->start_offset = h->data_offset + h->stream_offset; - uint32_t info_offset = h->start_offset; switch(h->sblk_version) { case 0x01: @@ -903,112 +969,75 @@ static bool process_data(STREAMFILE* sf, bnk_header_t* h) { case 0x08: case 0x09: - subtype = read_u32(h->start_offset+0x00,sf); - extradata_size = 0x08 + read_u32(h->start_offset+0x04,sf); /* 0x14 for AT9, 0x10 for PCM, 0x90 for MPEG */ + h->subtype = read_u32(h->start_offset+0x00,sf); + h->extradata_size = read_u32(h->start_offset+0x04,sf); /* 0x14 for AT9, 0x10/0x18 for PCM, 0x90 for MPEG */ + h->extradata_size += 0x08; - switch(subtype) { - case 0x00: + switch(h->subtype) { + case 0x00000000: h->channels = 1; h->codec = PSX; - h->interleave = 0x10; break; - case 0x01: - h->channels = 1; + case 0x00000001: /* PCM 1ch */ + case 0x00000004: /* PCM 2ch */ + h->channels = (h->subtype == 0x01) ? 1 : 2; h->codec = PCM16; - h->interleave = 0x01; break; - case 0x02: /* ATRAC9 / MPEG mono */ - case 0x05: /* ATRAC9 / MPEG stereo */ - h->channels = (subtype == 0x02) ? 1 : 2; + case 0x00000002: /* ATRAC9 / MPEG 1ch */ + case 0x00000005: /* ATRAC9 / MPEG 2ch */ + h->channels = (h->subtype == 0x02) ? 1 : 2; if (h->big_endian) { - /* The Last of Us demo (PS3) */ - - /* 0x08: mpeg version? (1) */ - /* 0x0C: mpeg layer? (3) */ - /* 0x10: ? (related to frame size, 0xC0 > 0x40, 0x120 > 0x60) */ - /* 0x14: sample rate */ - /* 0x18: mpeg layer? (3) */ - /* 0x1c: mpeg version? (1) */ - /* 0x20: channels? */ - /* 0x24: frame size */ - /* 0x28: encoder delay */ - /* 0x2c: num samples */ - /* 0x30: ? */ - /* 0x34: ? */ - /* 0x38: 0? */ - /* 0x3c: data size */ - /* padding up to 0x90 */ - + /* The Last of Us demo (PS3) (size 0x90) */ + // 0x08: mpeg version? (1) + // 0x0C: mpeg layer? (3) + // 0x10: ? (related to frame size, 0xC0 > 0x40, 0x120 > 0x60) + // 0x14: sample rate + // 0x18: mpeg layer? (3) + // 0x1c: mpeg version? (1) + // 0x20: channels? + // 0x24: frame size h->encoder_delay = read_s32(h->start_offset+0x28,sf); h->num_samples = read_s32(h->start_offset+0x2c,sf); - + // 0x30: ? + // 0x34: ? + // 0x38: 0? + // 0x3c: data size + // padding up to 0x90 h->codec = MPEG; } else { /* Puyo Puyo Tetris (PS4) */ - if (read_u32(h->start_offset+0x08,sf) + 0x08 != extradata_size) { /* repeat? */ - VGM_LOG("BNK: unknown subtype\n"); - goto fail; - } - - h->atrac9_info = read_u32be(h->start_offset+0x0c,sf); - /* 0x10: null? */ - loop_length = read_u32(h->start_offset+0x14,sf); - h->loop_start = read_u32(h->start_offset+0x18,sf); - h->loop_end = h->loop_start + loop_length; /* loop_start is -1 if not set */ - + process_extradata_0x14_atrac9(sf, h, h->start_offset); h->codec = ATRAC9; } break; default: - vgm_logi("BNK: unknown subtype %x (report)\n", subtype); + vgm_logi("BNK: unknown subtype %08x (report)\n", h->subtype); goto fail; } break; case 0x0c: - /* has two different variants under the same version - one for PS3 and another for PS4 */ - - subtype = read_u16(h->start_offset + 0x02, sf); - if (read_u32(h->start_offset + 0x04, sf) != 0x01) { /* type? */ - VGM_LOG("BNK: unknown subtype\n"); - goto fail; - } - extradata_size = 0x10 + read_u32(h->start_offset + 0x08, sf); /* 0x80 for MP3, 0x10 for PCM/PS-ADPCM */ - /* 0x0c: null? */ - + /* two different variants under the same version (SingStar Ultimate Party PS3 vs PS4) */ + process_extradata_base(sf, h, h->start_offset); if (h->big_endian) { - switch (subtype) { /* PS3 */ - case 0x00: /* PS-ADPCM */ - /* 0x10: null? */ - h->channels = read_u32(h->start_offset + 0x14, sf); - h->interleave = 0x10; - - h->loop_start = read_u32(h->start_offset + 0x18, sf); - loop_length = read_u32(h->start_offset + 0x1c, sf); - h->loop_end = h->loop_start + loop_length; /* loop_start is -1 if not set */ - + switch (h->subtype) { /* PS3 */ + case 0x00000000: /* PS-ADPCM 1ch */ + process_extradata_0x10_pcm_psx(sf, h, h->start_offset); h->codec = PSX; break; - case 0x01: /* PCM */ - /* 0x10: null? */ - h->channels = read_u32(h->start_offset + 0x14, sf); - h->interleave = 0x02; - - h->loop_start = read_u32(h->start_offset + 0x18, sf); - loop_length = read_u32(h->start_offset + 0x1c, sf); - h->loop_end = h->loop_start + loop_length; /* loop_start is -1 if not set */ - + case 0x00000001: /* PCM 1ch */ + process_extradata_0x10_pcm_psx(sf, h, h->start_offset); h->codec = PCM16; break; - case 0x03: /* MP3 */ - /* largely the same layout as descibed in v9 above, except +0x08 to all the offsets */ + case 0x00000003: /* MP3 */ + /* largely the same layout as described in v9 above, except +0x08 to all the offsets (size 0x80) */ h->channels = read_u32(h->start_offset + 0x28, sf); h->encoder_delay = read_u32(h->start_offset + 0x30, sf); @@ -1018,38 +1047,25 @@ static bool process_data(STREAMFILE* sf, bnk_header_t* h) { break; default: - vgm_logi("BNK: unknown subtype %x (report)\n", subtype); + vgm_logi("BNK: unknown v08+ subtype %08x (report)\n", h->subtype); goto fail; } } else { - switch (subtype) { /* PS4 */ - case 0x00: /* PCM */ - /* 0x10: null? */ - h->channels = read_u32(h->start_offset + 0x14, sf); - h->interleave = 0x02; - - h->loop_start = read_u32(h->start_offset + 0x18, sf); - loop_length = read_u32(h->start_offset + 0x1c, sf); - h->loop_end = h->loop_start + loop_length; /* loop_start is -1 if not set */ - + switch (h->subtype) { /* PS4 */ + case 0x00000000: /* PCM 1ch */ + case 0x00000001: /* PCM 2ch */ + process_extradata_0x10_pcm_psx(sf, h, h->start_offset); h->codec = PCM16; break; - case 0x01: /* PS-ADPCM (HEVAG?) */ - /* 0x10: num samples */ - h->channels = read_u32(h->start_offset + 0x14, sf); - h->interleave = 0x10; - - h->loop_start = read_u32(h->start_offset + 0x18, sf); - loop_length = read_u32(h->start_offset + 0x1c, sf); - h->loop_end = h->loop_start + loop_length; /* loop_start is -1 if not set */ - + case 0x00010000: /* PS-ADPCM 1ch (HEVAG?) */ + process_extradata_0x10_pcm_psx(sf, h, h->start_offset); h->codec = PSX; break; default: - vgm_logi("BNK: unknown subtype %x (report)\n", subtype); + vgm_logi("BNK: unknown v08+ subtype %08x (report)\n", h->subtype); goto fail; } } @@ -1060,144 +1076,120 @@ static bool process_data(STREAMFILE* sf, bnk_header_t* h) { case 0x0e: case 0x0f: case 0x10: - subtype = read_u16(h->start_offset+0x00,sf); - if (read_u32(h->start_offset+0x04,sf) != 0x01) { /* type? */ - VGM_LOG("BNK: unknown subtype\n"); - goto fail; - } - extradata_size = 0x10 + read_u32(h->start_offset+0x08,sf); /* 0x80 for AT9, 0x10 for PCM/PS-ADPCM */ - /* 0x0c: null? */ - - switch(subtype) { - case 0x02: /* ATRAC9 mono */ - case 0x05: /* ATRAC9 stereo */ - if (read_u32(h->start_offset+0x10,sf) + 0x10 != extradata_size) /* repeat? */ - goto fail; - h->channels = (subtype == 0x02) ? 1 : 2; - - h->atrac9_info = read_u32be(h->start_offset+0x14,sf); - /* 0x18: null? */ - /* 0x1c: channels? */ - /* 0x20: null? */ - - loop_length = read_u32(h->start_offset+0x24,sf); - h->loop_start = read_u32(h->start_offset+0x28,sf); - h->loop_end = h->loop_start + loop_length; /* loop_start is -1 if not set */ - - h->codec = ATRAC9; - break; - - case 0x01: /* PCM16LE mono? (NekoBuro/Polara sfx) */ - case 0x04: /* PCM16LE stereo? (NekoBuro/Polara sfx) */ - /* 0x10: null? */ - h->channels = read_u32(h->start_offset+0x14,sf); - h->interleave = 0x02; - - h->loop_start = read_u32(h->start_offset+0x18,sf); - loop_length = read_u32(h->start_offset+0x1c,sf); - h->loop_end = h->loop_start + loop_length; /* loop_start is -1 if not set */ - + //TODO: in v0x0f/10 some codecs have the original filename right before this, see if offset can be found + process_extradata_base(sf, h, h->start_offset); + switch(h->subtype) { + case 0x00000001: /* PCM16LE 1ch [NekoBuro/Polara (Vita)-v0d sfx] */ + case 0x00000004: /* PCM16LE 2ch [NekoBuro/Polara (Vita)-v0d sfx] */ + process_extradata_0x10_pcm_psx(sf, h, h->start_offset); h->codec = PCM16; break; - case 0x00: /* HEVAG (test banks) - likely standard VAG */ - case 0x03: /* HEVAG (Ikaruga) */ - /* 0x10: null? */ - h->channels = read_u32(h->start_offset+0x14,sf); - h->interleave = 0x10; - - h->loop_start = read_u32(h->start_offset+0x18,sf); - loop_length = read_u32(h->start_offset+0x1c,sf); - h->loop_end = h->loop_start + loop_length; /* loop_start is -1 if not set */ - + case 0x00000000: /* HEVAG 1ch [Hero Must Die (Vita)-v0d, v0d test banks) - likely standard VAG */ + case 0x00000003: /* HEVAG 2ch [Ikaruga (PS4)-v0f] */ + process_extradata_0x10_pcm_psx(sf, h, h->start_offset); h->codec = HEVAG; - //TODO: in v0x0f right before start_offset is the .vag filename, see if offset can be found break; + case 0x00000002: /* ATRAC9 1ch [Crypt of the Necrodancer (Vita)-v0d] */ + case 0x00000005: /* ATRAC9 2ch [Crypt of the Necrodancer (Vita)-v0d, Ikaruga (PS4)-v0f] */ + process_extradata_0x80_atrac9(sf, h, h->start_offset); + h->codec = ATRAC9; + break; + + case 0x00030000: /* ATRAC9 1ch [Days Gone (PS4)-v10] */ + case 0x00030001: /* ATRAC9 2ch [Days Gone (PS4)-v10] */ + case 0x00030002: /* ATRAC9 4ch [Days Gone (PS4)-v10] */ + process_extradata_0x80_atrac9(sf, h, h->start_offset); + h->codec = RIFF_ATRAC9; + break; + default: - vgm_logi("BNK: unknown subtype %x (report)\n", subtype); + vgm_logi("BNK: unknown v0d+ subtype %08x (report)\n", h->subtype); goto fail; } break; case 0x1a: case 0x1c: - case 0x23: + case 0x23: { + // common [Demon's Souls (PS5), The Last of Us Part 2 (PC)] if (h->stream_offset == 0xFFFFFFFF) { h->channels = 1; h->codec = DUMMY; break; } - /* pre-info */ - stream_name_size = read_u64(info_offset+0x00,sf); - stream_name_offset = info_offset + 0x08; - info_offset += stream_name_size + 0x08; + /* pre-header with string + size */ + uint32_t info_offset = h->start_offset; - h->stream_size = read_u64(info_offset + 0x00,sf); /* after this offset */ - h->stream_size += 0x08 + stream_name_size + 0x08; - /* 0x08: 0/1 for PCM (Mono/Stereo?), 0/1/2/3 for ATRAC9 (channels/2)? */ - subtype = read_u16(info_offset + 0x0a, sf); - /* 0x0c: always 1 - using this to detect whether it's an SBlk or ZLSD/exteral sound for now */ - extradata_size = read_u64(info_offset + 0x10,sf) + 0x08 + stream_name_size + 0x18; + uint32_t stream_name_size = read_u64(info_offset + 0x00,sf); + uint32_t stream_name_offset = info_offset + 0x08; + info_offset += stream_name_size + 0x08; if (stream_name_size >= STREAM_NAME_SIZE || stream_name_size <= 0) stream_name_size = STREAM_NAME_SIZE; read_string(h->stream_name, stream_name_size, stream_name_offset, sf); - /* size check is necessary, otherwise it risks a false positive with the ZLSD version number */ - if (info_offset + 0x10 > h->data_offset + h->data_size || read_u32(info_offset + 0x0c, sf) != 0x01) { + h->stream_size = read_u64(info_offset + 0x00,sf); /* after this offset */ + h->stream_size += 0x08 + stream_name_size + 0x08; + info_offset += 0x08; + + // size check is necessary, otherwise it risks a false positive with the ZLSD version number + // (using 0x01 flag to detect whether it's an SBlk or ZLSD/exteral sound for now) + if (info_offset + 0x08 > h->data_offset + h->data_size || read_u32(info_offset + 0x04, sf) != 0x01) { h->channels = 1; h->codec = EXTERNAL; break; } - info_offset += 0x18; - - /* actual stream info */ - switch (subtype) { - case 0x00: /* PCM */ - h->num_samples = read_s32(info_offset + 0x00, sf); - h->channels = read_u32(info_offset + 0x04, sf); - /* 0x08: loop flag? (always -1) */ + /* actual stream info; */ + process_extradata_base(sf, h, info_offset); + h->extradata_size += 0x08 + stream_name_size + 0x08; + // lower 16bit: 0/1 for PCM, 0/1/2/3 for ATRAC9 (possibly channels / 2) + switch (h->subtype >> 16) { + case 0x0000: /* PCM [The Last of Us Part 1 (PC)-v23] */ + process_extradata_0x10_pcm_psx(sf, h, info_offset); h->codec = PCM16; break; - /* should be split, but 0x1A/0x1C has no other known codecs yet */ - case 0x01: /* ATRAC9 (0x23) */ - case 0x03: /* ATRAC9 (0x1A/0x1C) */ - /* 0x00: extradata size (without pre-info, also above) */ - h->atrac9_info = read_u32be(info_offset + 0x04, sf); - h->num_samples = read_s32(info_offset + 0x08, sf); - h->channels = read_u32(info_offset + 0x0c, sf); - h->loop_start = read_s32(info_offset + 0x10, sf); - h->loop_end = read_s32(info_offset + 0x14, sf); - /* 0x18: loop flag (0=loop, -1=no) */ - /* rest: null */ - + case 0x0003: /* ATRAC9 [The Last of Us Part 2 (PC)-v1c, Demon's Souls (PS5)-v1a] */ + case 0x0001: /* ATRAC9 [The Last of Us Part 1 (PC)-v23] */ + process_extradata_0x80_atrac9(sf, h, info_offset); h->codec = RIFF_ATRAC9; break; default: - vgm_logi("BNK: unknown subtype %x (report)\n", subtype); + vgm_logi("BNK: unknown v1c+ subtype %08x (report)\n", h->subtype); goto fail; } - /* no sample rate (probably fixed to 48000/system's, but seen in RIFF) */ - h->sample_rate = 48000; break; + } default: vgm_logi("BNK: unknown data version %x (report)\n", h->sblk_version); goto fail; } - h->start_offset += extradata_size; - h->stream_size -= extradata_size; - h->stream_size -= postdata_size; + h->start_offset += h->extradata_size; + h->stream_size -= h->extradata_size; + h->stream_size -= h->postdata_size; //;VGM_LOG("BNK: offset=%x, size=%x\n", h->start_offset, h->stream_size); + // loop_start is typically -1 if not set + if (h->loop_start < 0) { + h->loop_start = 0; + h->loop_length = 0; + } + + if (h->loop_length) { + h->loop_end = h->loop_start + h->loop_length; + } + + h->loop_flag = (h->loop_start >= 0) && (h->loop_end > 0); + return true; fail: return false; @@ -1352,8 +1344,6 @@ static bool parse_bnk_v3(STREAMFILE* sf, bnk_header_t* h) { if (!process_zlsd(sf, h)) goto fail; - h->loop_flag = (h->loop_start >= 0) && (h->loop_end > 0); - return true; fail: return false; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/dc_idvi.c b/Frameworks/vgmstream/vgmstream/src/meta/dc_idvi.c index 4498204a8..7aacd70c3 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/dc_idvi.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/dc_idvi.c @@ -34,7 +34,7 @@ VGMSTREAM * init_vgmstream_dc_idvi(STREAMFILE *streamFile) { vgmstream->loop_end_sample = vgmstream->num_samples; vgmstream->meta_type = meta_DC_IDVI; - vgmstream->coding_type = coding_DVI_IMA_int; + vgmstream->coding_type = coding_DVI_IMA_mono; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x400; if (vgmstream->interleave_block_size) diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ffmpeg.c b/Frameworks/vgmstream/vgmstream/src/meta/ffmpeg.c index c2df0abec..531c3b9d2 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ffmpeg.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ffmpeg.c @@ -29,18 +29,20 @@ VGMSTREAM* init_vgmstream_ffmpeg(STREAMFILE* sf) { /* no checks */ //if (!check_extensions(sf, "...")) - // goto fail; + // return NULL; /* don't try to open headers and other mini files */ if (get_streamfile_size(sf) <= 0x1000) - goto fail; + return NULL; - // many PSP rips have poorly demuxed videos with a failty RIFF, allow for now -#if 0 /* reject some formats handled elsewhere (better fail and check there than let buggy FFmpeg take over) */ - if (check_extensions(sf, "at3")) - goto fail; -#endif + uint32_t id = read_u32be(0x00, sf); + // rejected FSB may play as wonky .mp3 + if ((id & 0xFFFFFF00) == get_id32be("FSB\0")) + return NULL; + // typically incorrectly extracted files with padding, best handle in riff.c that reads loops points + if (id == get_id32be("RIFF") && (read_u16le(0x14, sf) == 0x0270 || check_extensions(sf, "at3"))) + return NULL; if (target_subsong == 0) target_subsong = 1; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/fsb.c b/Frameworks/vgmstream/vgmstream/src/meta/fsb.c index afd83639f..8239aa8eb 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/fsb.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/fsb.c @@ -4,7 +4,7 @@ #include "fsb_interleave_streamfile.h" -typedef enum { MPEG, XBOX_IMA, FSB_IMA, PSX, XMA1, XMA2, DSP, CELT, PCM8, PCM8U, PCM16LE, PCM16BE } fsb_codec_t; +typedef enum { MPEG, XBOX_IMA, FSB_IMA, PSX, XMA1, XMA2, DSP, CELT, PCM8, PCM8U, PCM16LE, PCM16BE, SILENCE } fsb_codec_t; typedef struct { /* main header */ uint32_t id; @@ -36,7 +36,7 @@ typedef struct { bool loop_flag; - off_t stream_offset; + uint32_t stream_offset; fsb_codec_t codec; } fsb_header_t; @@ -82,10 +82,13 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) { read_string(vgmstream->stream_name, fsb.name_size + 1, fsb.name_offset, sf); switch(fsb.codec) { + #ifdef VGM_USE_MPEG - case MPEG: { /* FSB4: Shatter (PS3), Way of the Samurai 3/4 (PS3) */ + case MPEG: { /* FSB3: Spider-man 3 (PC/PS3), Rise of the Argonauts (PC), FSB4: Shatter (PS3), Way of the Samurai 3/4 (PS3) */ mpeg_custom_config cfg = {0}; - cfg.fsb_padding = fsb.mpeg_padding; /* frames are sometimes padded for alignment */ + + cfg.fsb_padding = fsb.mpeg_padding; // frames are sometimes padded for alignment + cfg.data_size = fsb.stream_offset + fsb.stream_size; vgmstream->codec_data = init_mpeg_custom(sf, fsb.stream_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_FSB, &cfg); if (!vgmstream->codec_data) goto fail; @@ -188,20 +191,25 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) { } #endif - case PCM8: /* no games known */ - case PCM8U: /* FSB4: Crash Time 4: The Syndicate (X360) */ + case PCM8: /* no known games */ + case PCM8U: /* FSB4: Crash Time 4: The Syndicate (X360), Zoombinis (PC) */ vgmstream->coding_type = (fsb.codec == PCM8U) ? coding_PCM8_U : coding_PCM8; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x1; break; - case PCM16LE: /* FSB4: Rocket Knight (PC), Another Century's Episode R (PS3), Toy Story 3 (Wii) */ - case PCM16BE: /* FSB4: SpongeBob's Truth or Square (X360) */ + case PCM16LE: /* FSB2: Hot Wheels World Race (PC)-bigfile-sfx, FSB3: Bee Movie (Wii), FSB4: Rocket Knight (PC), Another Century's Episode R (PS3), Toy Story 3 (Wii) */ + case PCM16BE: /* FSB4: SpongeBob's Truth or Square (X360), Crash Time 4: The Syndicate (X360) */ vgmstream->coding_type = (fsb.codec == PCM16BE) ? coding_PCM16BE : coding_PCM16LE; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x2; break; + case SILENCE: /* special case for broken MPEG */ + vgmstream->coding_type = coding_SILENCE; + vgmstream->layout_type = layout_none; + break; + default: goto fail; } @@ -220,7 +228,7 @@ fail: static layered_layout_data* build_layered_fsb_celt(STREAMFILE* sf, fsb_header_t* fsb, bool is_new_lib) { layered_layout_data* data = NULL; STREAMFILE* temp_sf = NULL; - int i, layers = (fsb->channels+1) / 2; + int layers = (fsb->channels+1) / 2; /* init layout */ @@ -228,7 +236,7 @@ static layered_layout_data* build_layered_fsb_celt(STREAMFILE* sf, fsb_header_t* if (!data) goto fail; /* open each layer subfile (1/2ch CELT streams: 2ch+2ch..+1ch or 2ch+2ch..+2ch) */ - for (i = 0; i < layers; i++) { + for (int i = 0; i < layers; i++) { int layer_channels = (i+1 == layers && fsb->channels % 2 == 1) ? 1 : 2; /* last layer can be 1/2ch */ @@ -464,7 +472,7 @@ static bool parse_fsb(fsb_header_t* fsb, STREAMFILE* sf) { if (fsb->id == get_id32be("FSB2")) { fsb->meta_type = meta_FSB2; fsb->base_header_size = 0x10; - fsb->sample_header_min = 0x40; /* guessed */ + fsb->sample_header_min = 0x40; } else if (fsb->id == get_id32be("FSB3")) { fsb->meta_type = meta_FSB3; @@ -528,7 +536,6 @@ static bool parse_fsb(fsb_header_t* fsb, STREAMFILE* sf) { /* XMA basic headers have extra data [Forza Motorsport 3 (X360)] */ if (fsb->mode & FSOUND_XMA) { - VGM_LOG("h=%x\n", (uint32_t)header_offset); // 0x08: flags? (0x00=none?, 0x20=standard) // 0x0c: sample related? (may be 0 with no seek table) // 0x10: low number (may be 0 with no seek table) @@ -613,6 +620,26 @@ static bool parse_fsb(fsb_header_t* fsb, STREAMFILE* sf) { /* XOR encryption for some FSB4, though the flag is only seen after decrypting */ //;VGM_ASSERT(fsb->flags & FMOD_FSB_SOURCE_ENCRYPTED, "FSB ENCRYPTED found\n"); + // rare FSB3 have odd cases [Rise of the Argonauts (PC)] + if (fsb->codec == MPEG && fsb->version == FMOD_FSB_VERSION_3_1) { + uint32_t mpeg_id = read_u32be(fsb->stream_offset, sf); + + if ((mpeg_id & 0xFFFFFF00) == get_id32be("ID3\0")) { + // starts with ID3, probably legal but otherwise not seen (stripped?): Lykas_Atalanta_Join_DLG.fsb, Support_Of_The_Gods*.fsb + uint32_t tag_size = mpeg_get_tag_size(sf, fsb->stream_offset, mpeg_id); // always 0x1000, has 'PeakLevel' info + fsb->stream_offset += tag_size; + fsb->stream_size -= tag_size; + } + + // completely empty MPEG, probably works by chance with OG decoder ignoring bad data: DLG_Lycomedes_Statue_*.fsb + if (mpeg_id == 0) { + fsb->codec = SILENCE; + } + + // rarely sets more samples than data, must clamp reads to avoid spilling into next subsong: Player_Death_DLG.fsb, Lykas_Atalanta_Join_DLG.fsb + // probably a bug as samples don't seem to match MPEG's 'Info' headers and can be both bigger and smaller than loop_end + } + return true; fail: return false; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/fsb5.c b/Frameworks/vgmstream/vgmstream/src/meta/fsb5.c index 00f566002..cdbbf8133 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/fsb5.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/fsb5.c @@ -42,22 +42,22 @@ VGMSTREAM* init_vgmstream_fsb5(STREAMFILE* sf) { fsb5_header fsb5 = {0}; uint32_t offset; int target_subsong = sf->stream_index; - int i; /* checks */ if (!is_id32be(0x00,sf, "FSB5")) - goto fail; + return NULL; /* .fsb: standard - * .snd: Alchemy engine (also Unity) */ - if (!check_extensions(sf,"fsb,snd")) - goto fail; + * .snd: Alchemy engine (also Unity) + * .fsb.ps3: Guacamelee! (PS3) */ + if (!check_extensions(sf,"fsb,snd,ps3")) + return NULL; /* v0 is rare, seen in Tales from Space (Vita) */ fsb5.version = read_u32le(0x04,sf); if (fsb5.version != 0x00 && fsb5.version != 0x01) - goto fail; + return NULL; fsb5.total_subsongs = read_u32le(0x08,sf); fsb5.sample_header_size = read_u32le(0x0C,sf); @@ -81,7 +81,7 @@ VGMSTREAM* init_vgmstream_fsb5(STREAMFILE* sf) { if ((fsb5.sample_header_size + fsb5.name_table_size + fsb5.sample_data_size + fsb5.base_header_size) != get_streamfile_size(sf)) { vgm_logi("FSB5: wrong size, expected %x + %x + %x + %x vs %x (re-rip)\n", fsb5.sample_header_size, fsb5.name_table_size, fsb5.sample_data_size, fsb5.base_header_size, (uint32_t)get_streamfile_size(sf)); - goto fail; + return NULL; } if (target_subsong == 0) target_subsong = 1; @@ -90,7 +90,7 @@ VGMSTREAM* init_vgmstream_fsb5(STREAMFILE* sf) { /* find target stream header and data offset, and read all needed values for later use * (reads one by one as the size of a single stream header is variable) */ offset = fsb5.base_header_size; - for (i = 0; i < fsb5.total_subsongs; i++) { + for (int i = 0; i < fsb5.total_subsongs; i++) { uint32_t stream_header_size = 0; uint32_t data_offset = 0; uint64_t sample_mode; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/genh.c b/Frameworks/vgmstream/vgmstream/src/meta/genh.c index f4f4d051e..176e5f1e9 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/genh.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/genh.c @@ -169,9 +169,9 @@ VGMSTREAM* init_vgmstream_genh(STREAMFILE *sf) { else { vgmstream->layout_type = layout_interleave; if (coding == coding_DVI_IMA) - coding = coding_DVI_IMA_int; + coding = coding_DVI_IMA_mono; if (coding == coding_IMA) - coding = coding_IMA_int; + coding = coding_IMA_mono; if (coding == coding_AICA) coding = coding_AICA_int; } @@ -180,8 +180,8 @@ VGMSTREAM* init_vgmstream_genh(STREAMFILE *sf) { if (!genh.interleave && ( coding == coding_PSX || coding == coding_PSX_badflags || - coding == coding_IMA_int || - coding == coding_DVI_IMA_int || + coding == coding_IMA_mono || + coding == coding_DVI_IMA_mono || coding == coding_SDX2_int) ) { goto fail; } diff --git a/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h b/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h index 0d97d3dd9..07ae29b6b 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h +++ b/Frameworks/vgmstream/vgmstream/src/meta/hca_keys.h @@ -465,6 +465,7 @@ static const hcakey_info hcakey_list[] = { {0x9eb82f449eb4f3f6}, // music_0110036 {0x417822c4c107541c}, // music_0110037 {0x9e55fe333fe182dd}, // music_0110038 + {0x86c5e597cdcf2c4e}, // music_0110039 {0xfb647d074e53fab6}, // music_0120001 {0xc24049b9f7ed3105}, // music_0120002 {0x0dc128f2fd48bf4b}, // music_0120003 @@ -741,6 +742,7 @@ static const hcakey_info hcakey_list[] = { {0x1f3c1d0817b3d4be}, // music_0810008 {0x2e5c9e00274e0f2a}, // music_0810009 {0xfd59b4043bf88390}, // music_0810010 + {0xad90dc83d09aeaf1}, // music_0810011 {0x1e99d14d97ab82c5}, // music_0820001 {0x5bf7cefecda8bcb2}, // music_0820002 {0x9cf7ab0ccafa374e}, // music_0820003 @@ -1254,6 +1256,11 @@ static const hcakey_info hcakey_list[] = { {0x775610e63d2b622b}, // music_5050294 {0xcc73017924bfaaae}, // music_5050295 {0xd2197c8cf0ea08f9}, // music_5050296 + {0xad6592b9a7f59dd4}, // music_5050298 + {0x26577d8c85702e9}, // music_5050299 + {0x8886b6ab9e5642a6}, // music_5050300 + {0xf02f820d32f0abe7}, // music_5050301 + {0x67d0a863e87d513a}, // music_5050302 {0x481c17fb41e25dbb}, // music_5050303 {0xe259362b1d601f93}, // music_5050304 {0x7698628d25ad406b}, // music_5050305 @@ -1504,7 +1511,7 @@ static const hcakey_info hcakey_list[] = { // DRAGON BALL: Sparking! ZERO (multi) {13238534807163085345u}, // B7B8B9442F99A221 - // TOUHOU GENSOU MAHJONG (PC) [demo and release] + // TOUHOU GENSOU MAHJONG (PC) {7757726886}, // 00000001CE6584A6 // NARUTO X BORUTO NINJA VOLTAGE (Android) @@ -1518,6 +1525,10 @@ static const hcakey_info hcakey_list[] = { // Tales of Graces f Remastered (PC) {51485416730473395}, // 00B6E9B6B75533B3 + + // Freedom Wars Remastered (Switch) + {3258660547165106863}, // 2D391680A55B32AF + }; #endif diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ima.c b/Frameworks/vgmstream/vgmstream/src/meta/ima.c index 7ef9349d4..69cbbceeb 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ima.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ima.c @@ -1,52 +1,52 @@ -#include "meta.h" -#include "../coding/coding.h" - - -/* .IMA - Blitz Games early games [Lilo & Stitch: Trouble in Paradise (PC)] */ -VGMSTREAM * init_vgmstream_ima(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count, num_samples, sample_rate; - - - /* checks */ - if (!check_extensions(streamFile, "ima")) - goto fail; - - if (read_32bitBE(0x00,streamFile) != 0x02000000) /* version? */ - goto fail; - if (read_32bitBE(0x04,streamFile) != 0) - goto fail; - - num_samples = read_32bitLE(0x08, streamFile); - channel_count = read_32bitLE(0x0c,streamFile); - sample_rate = read_32bitLE(0x10, streamFile); - - loop_flag = 0; - start_offset = 0x14; - - if (channel_count > 1) /* unknown interleave */ - goto fail; - if (num_samples != ima_bytes_to_samples(get_streamfile_size(streamFile) - start_offset, channel_count)) - goto fail; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count, loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = meta_IMA; - vgmstream->sample_rate = sample_rate; - - vgmstream->coding_type = coding_BLITZ_IMA; - vgmstream->layout_type = layout_none; - - vgmstream->num_samples = num_samples; - - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../coding/coding.h" + + +/* .IMA - Blitz Games early games [Lilo & Stitch: Trouble in Paradise (PC)] */ +VGMSTREAM* init_vgmstream_ima(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag, channels, num_samples, sample_rate; + + + /* checks */ + if (read_u32be(0x00,sf) != 0x02000000) /* version? */ + return NULL; + if (read_u32be(0x04,sf) != 0) + return NULL; + if (!check_extensions(sf, "ima")) + return NULL; + + num_samples = read_s32le(0x08, sf); + channels = read_s32le(0x0c,sf); + sample_rate = read_s32le(0x10, sf); + + loop_flag = 0; + start_offset = 0x14; + + if (channels > 1) /* unknown interleave */ + return NULL; + if (sample_rate < 11025 || sample_rate > 44100) /* arbitrary values */ + return NULL; + if (num_samples != ima_bytes_to_samples(get_streamfile_size(sf) - start_offset, channels)) + return NULL; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_IMA; + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = num_samples; + + vgmstream->coding_type = coding_BLITZ_IMA; + vgmstream->layout_type = layout_none; + + if (!vgmstream_open_stream(vgmstream,sf,start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/mc3.c b/Frameworks/vgmstream/vgmstream/src/meta/mc3.c deleted file mode 100644 index bd9904067..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/mc3.c +++ /dev/null @@ -1,46 +0,0 @@ -#include "meta.h" - - -/* MC3 - from Paradigm games [Spy Hunter, MX Rider, Terminator 3] */ -VGMSTREAM * init_vgmstream_mc3(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count; - - /* check extension, case insensitive */ - if ( !check_extensions(streamFile,"mc3")) - goto fail; - - if (read_32bitBE(0x00,streamFile) != 0x4D504333) /* "MPC3" */ - goto fail; - if (read_32bitBE(0x04,streamFile) != 0x00011400) /* version? */ - goto fail; - - start_offset = 0x1c; - loop_flag = 0; - channel_count = read_32bitLE(0x08, streamFile); - if (channel_count > 2) goto fail; /* not seen, decoder must be adapted */ - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - vgmstream->coding_type = coding_MC3; - vgmstream->layout_type = layout_none; - vgmstream->meta_type = meta_MC3; - - vgmstream->sample_rate = read_32bitLE(0x0c, streamFile); - vgmstream->num_samples = read_32bitLE(0x10, streamFile) * 10; /* sizes in sub-blocks of 10 samples (without headers) */ - vgmstream->interleave_block_size = (read_32bitLE(0x14, streamFile) * 4 * channel_count) + 4; - if (read_32bitLE(0x18, streamFile) + start_offset != get_streamfile_size(streamFile)) - goto fail; - - - /* open the file for reading */ - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/meta.h b/Frameworks/vgmstream/vgmstream/src/meta/meta.h index 194a00528..3f1e9d800 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/meta.h +++ b/Frameworks/vgmstream/vgmstream/src/meta/meta.h @@ -314,7 +314,7 @@ VGMSTREAM * init_vgmstream_ubi_jade_container(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_seg(STREAMFILE * streamFile); -VGMSTREAM * init_vgmstream_nds_strm_ffta2(STREAMFILE * streamFile); +VGMSTREAM* init_vgmstream_riff_ima(STREAMFILE* sf); VGMSTREAM * init_vgmstream_knon(STREAMFILE * streamFile); @@ -362,7 +362,7 @@ VGMSTREAM * init_vgmstream_vsf(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_nds_rrds(STREAMFILE *streamFile); -VGMSTREAM * init_vgmstream_ps2_vsf_tta(STREAMFILE *streamFile); +VGMSTREAM* init_vgmstream_smss(STREAMFILE* sf); VGMSTREAM* init_vgmstream_ads_midway(STREAMFILE* sf); @@ -443,7 +443,7 @@ VGMSTREAM * init_vgmstream_ngc_rkv(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_p3d(STREAMFILE* streamFile); -VGMSTREAM * init_vgmstream_ngc_dsp_mpds(STREAMFILE* streamFile); +VGMSTREAM* init_vgmstream_mpds(STREAMFILE* sf); VGMSTREAM * init_vgmstream_ea_swvr(STREAMFILE* streamFile); @@ -475,7 +475,7 @@ VGMSTREAM* init_vgmstream_sndp(STREAMFILE* sf); VGMSTREAM * init_vgmstream_sgxd(STREAMFILE* streamFile); -VGMSTREAM * init_vgmstream_wii_ras(STREAMFILE* streamFile); +VGMSTREAM* init_vgmstream_ras(STREAMFILE* sf); VGMSTREAM * init_vgmstream_spm(STREAMFILE* streamFile); @@ -523,7 +523,7 @@ VGMSTREAM * init_vgmstream_ubi_ckd(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_ps2_vbk(STREAMFILE* streamFile); -VGMSTREAM * init_vgmstream_otm(STREAMFILE* streamFile); +VGMSTREAM* init_vgmstream_xwb_konami(STREAMFILE* sf); VGMSTREAM * init_vgmstream_bcstm(STREAMFILE* streamFile); @@ -544,12 +544,12 @@ VGMSTREAM * init_vgmstream_btsnd(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_svag_snk(STREAMFILE* streamFile); +VGMSTREAM* init_vgmstream_vds_vdm(STREAMFILE* sf); + VGMSTREAM * init_vgmstream_xma(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_bik(STREAMFILE* streamFile); -VGMSTREAM * init_vgmstream_ps2_vds_vdm(STREAMFILE* streamFile); - VGMSTREAM * init_vgmstream_cxs(STREAMFILE* streamFile); VGMSTREAM* init_vgmstream_adx_monster(STREAMFILE* sf); @@ -570,7 +570,7 @@ VGMSTREAM * init_vgmstream_sndx(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_ogl(STREAMFILE *streamFile); -VGMSTREAM * init_vgmstream_mc3(STREAMFILE *streamFile); +VGMSTREAM* init_vgmstream_mpc3(STREAMFILE* sf); VGMSTREAM* init_vgmstream_ghs(STREAMFILE* sf); VGMSTREAM* init_vgmstream_s_p_sth(STREAMFILE* sf); @@ -751,7 +751,7 @@ VGMSTREAM * init_vgmstream_msv(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_sdf(STREAMFILE *streamFile); -VGMSTREAM * init_vgmstream_svg(STREAMFILE *streamFile); +VGMSTREAM* init_vgmstream_svgp(STREAMFILE* sf); VGMSTREAM * init_vgmstream_vai(STREAMFILE *streamFile); @@ -761,7 +761,7 @@ VGMSTREAM * init_vgmstream_ao(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_apc(STREAMFILE *streamFile); -VGMSTREAM * init_vgmstream_wv2(STREAMFILE *streamFile); +VGMSTREAM* init_vgmstream_wav2(STREAMFILE* sf); VGMSTREAM * init_vgmstream_xau_konami(STREAMFILE *streamFile); @@ -1026,4 +1026,10 @@ VGMSTREAM* init_vgmstream_i3ds(STREAMFILE* sf); VGMSTREAM* init_vgmstream_skex(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_axhd(STREAMFILE* sf); + +VGMSTREAM* init_vgmstream_shaa(STREAMFILE* sf); + +VGMSTREAM* init_vgmstream_undefind(STREAMFILE* sf); + #endif diff --git a/Frameworks/vgmstream/vgmstream/src/meta/mpc3.c b/Frameworks/vgmstream/vgmstream/src/meta/mpc3.c new file mode 100644 index 000000000..c8ec5cd65 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/mpc3.c @@ -0,0 +1,46 @@ +#include "meta.h" + + +/* MPC3 - from Paradigm games [Spy Hunter (PS2), MX Rider (PS2), Terminator 3 (PS2)] */ +VGMSTREAM* init_vgmstream_mpc3(STREAMFILE* sf) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + int loop_flag, channels; + + /* checks */ + if (!is_id32be(0x00,sf, "MPC3")) + return NULL; + if (read_u32be(0x04,sf) != 0x00011400) /* version? */ + return NULL; + if (!check_extensions(sf,"mc3")) + return NULL; + + start_offset = 0x1c; + loop_flag = 0; + channels = read_u32le(0x08, sf); + if (channels > 2) /* decoder max */ + return NULL; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_MPC3; + vgmstream->coding_type = coding_MPC3; + vgmstream->layout_type = layout_none; + + vgmstream->sample_rate = read_s32le(0x0c, sf); + vgmstream->num_samples = read_s32le(0x10, sf) * 10; /* sizes in sub-blocks of 10 samples (without headers) */ + vgmstream->interleave_block_size = (read_u32le(0x14, sf) * 0x04 * channels) + 0x04; + if (read_u32le(0x18, sf) + start_offset != get_streamfile_size(sf)) + goto fail; + + + /* open the file for reading */ + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/mpds.c b/Frameworks/vgmstream/vgmstream/src/meta/mpds.c new file mode 100644 index 000000000..3a9e16233 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/mpds.c @@ -0,0 +1,78 @@ +#include "meta.h" +#include "../util.h" +#include "../coding/coding.h" + +/* MPDS - found in Paradigm Entertainment GC games */ +VGMSTREAM* init_vgmstream_mpds(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag = 0, channels, short_mpds; + + + /* checks */ + if (!is_id32be(0x00,sf, "MPDS")) + return NULL; + /* .dsp: Big Air Freestyle */ + /* .mds: Terminator 3 The Redemption, Mission Impossible: Operation Surma */ + if (!check_extensions(sf, "dsp,mds")) + return NULL; + + /* version byte? */ + short_mpds = read_u32be(0x04,sf) != 0x00010000 && check_extensions(sf, "mds"); + + channels = short_mpds ? + read_u16be(0x0a, sf) : + read_u32be(0x14, sf); + if (channels > 2) + return NULL; + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_MPDS; + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_interleave; + + if (!short_mpds) { /* Big Air Freestyle */ + start_offset = 0x80; + vgmstream->num_samples = read_32bitBE(0x08,sf); + vgmstream->sample_rate = read_32bitBE(0x10,sf); + vgmstream->interleave_block_size = channels==1 ? 0 : read_32bitBE(0x18,sf); + + /* compare sample count with body size */ + if ((vgmstream->num_samples / 7 * 8) != (read_32bitBE(0x0C,sf))) goto fail; + + dsp_read_coefs_be(vgmstream,sf,0x24, 0x28); + } + else { /* Terminator 3 The Redemption, Mission Impossible: Operation Surma */ + start_offset = 0x20; + vgmstream->num_samples = read_32bitBE(0x04,sf); + vgmstream->sample_rate = (uint16_t)read_16bitBE(0x08,sf); + vgmstream->interleave_block_size = channels==1 ? 0 : 0x200; + /* some kind of hist after 0x0c? */ + + /* set coefs, debugged from the MI:OS ELF (helpfully marked as "sMdsCoefs") */ + static const int16_t coefs[16] = { + 0x0000,0x0000,0x0780,0x0000,0x0e60,0xf980,0x0c40,0xf920, + 0x0f40,0xf880,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 + }; + + for (int ch = 0; ch < channels; ch++) { + for (int i = 0; i < 16; i++) { + vgmstream->ch[ch].adpcm_coef[i] = coefs[i]; + } + } + } + + + if ( !vgmstream_open_stream(vgmstream,sf,start_offset)) + goto fail; + + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/mpeg.c b/Frameworks/vgmstream/vgmstream/src/meta/mpeg.c index 6e76bc4ef..3e2e27d7d 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/mpeg.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/mpeg.c @@ -11,7 +11,7 @@ VGMSTREAM* init_vgmstream_mpeg(STREAMFILE* sf) { /* checks */ uint32_t header_id = read_u32be(0x00, sf); - if ((header_id & 0xFFF00000) != 0xFFF00000 && + if ((header_id & 0xFFE00000) != 0xFFE00000 && (header_id & 0xFFFFFF00) != get_id32be("ID3\0") && (header_id & 0xFFFFFF00) != get_id32be("TAG\0")) return NULL; @@ -26,11 +26,13 @@ VGMSTREAM* init_vgmstream_mpeg(STREAMFILE* sf) { start_offset += tag_size; } + // could check size but there are some tiny <0x1000 low bitrate files do exist in flash games + mpeg_frame_info info = {0}; if (!mpeg_get_frame_info(sf, start_offset, &info)) return NULL; - /* .mp3/mp2: standard + /* .mp3/mp2: standard * .lmp3/lmp2: for plugins * .mus: Marc Ecko's Getting Up (PC) * .imf: Colors (Gizmondo) @@ -44,7 +46,7 @@ VGMSTREAM* init_vgmstream_mpeg(STREAMFILE* sf) { bool loop_flag = 0; - /* build VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(info.channels, loop_flag); if (!vgmstream) goto fail; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/msf.c b/Frameworks/vgmstream/vgmstream/src/meta/msf.c index f51ad0e01..c00630194 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/msf.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/msf.c @@ -16,7 +16,7 @@ VGMSTREAM* init_vgmstream_msf(STREAMFILE* sf) { // "MSF" + n.n version: // - 0x01: Megazone 23: Aoi Garland (PS3) // - 0x02: Switchball (PS3) - // - 0x30 ('0'): ? + // - 0x30 ('0'): Saints Row 2 (PS3) // - 0x35 ('5'): SDKs // - 0x43 ('C'): latest/most common @@ -49,7 +49,8 @@ VGMSTREAM* init_vgmstream_msf(STREAMFILE* sf) { * 0x10 often goes with 0x01 but not always (Castlevania HoD); Malicious PS3 uses flag 0x2 instead */ loop_flag = (flags != 0xffffffff) && ((flags & 0x01) || (flags & 0x02)); - /* loop offset markers (marker N @ 0x18 + N*(4+4), but in practice only marker 0 is used) */ + /* loop offset markers: marker N = 0x18 + N * (0x08), but in practice only marker 0 is used + * (Saints Row 2 saves original filename in 0x28) */ if (loop_flag) { loop_start = read_u32be(0x18,sf); loop_end = read_u32be(0x1C,sf); /* loop duration */ diff --git a/Frameworks/vgmstream/vgmstream/src/meta/musx.c b/Frameworks/vgmstream/vgmstream/src/meta/musx.c index 05b62d8c5..78246bc10 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/musx.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/musx.c @@ -91,7 +91,7 @@ VGMSTREAM* init_vgmstream_musx(STREAMFILE* sf) { vgmstream->loop_start_sample = musx.loop_start / 4; /* weird but needed */ vgmstream->loop_end_sample = musx.loop_end / 4; - vgmstream->coding_type = coding_DVI_IMA_int; + vgmstream->coding_type = coding_DVI_IMA_mono; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x01; break; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/myspd.c b/Frameworks/vgmstream/vgmstream/src/meta/myspd.c index f4bf58b6c..af7eb0546 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/myspd.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/myspd.c @@ -29,7 +29,7 @@ VGMSTREAM* init_vgmstream_myspd(STREAMFILE* sf) { vgmstream->sample_rate = read_s32be(0x04,sf); vgmstream->meta_type = meta_MYSPD; - vgmstream->coding_type = coding_IMA_int; + vgmstream->coding_type = coding_IMA_mono; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = channel_size; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/nds_hwas.c b/Frameworks/vgmstream/vgmstream/src/meta/nds_hwas.c index 963a8c748..689078904 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/nds_hwas.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/nds_hwas.c @@ -31,7 +31,7 @@ VGMSTREAM * init_vgmstream_nds_hwas(STREAMFILE *streamFile) { vgmstream->loop_start_sample = ima_bytes_to_samples(read_32bitLE(0x10,streamFile), channel_count); //assumed, always 0 vgmstream->loop_end_sample = ima_bytes_to_samples(read_32bitLE(0x18,streamFile), channel_count); - vgmstream->coding_type = coding_IMA_int; + vgmstream->coding_type = coding_IMA_mono; vgmstream->layout_type = layout_blocked_hwas; vgmstream->full_block_size = read_32bitLE(0x04,streamFile); /* usually 0x2000, 0x4000 or 0x8000 */ diff --git a/Frameworks/vgmstream/vgmstream/src/meta/nds_rrds.c b/Frameworks/vgmstream/vgmstream/src/meta/nds_rrds.c index b43ad83d1..dc572c3d8 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/nds_rrds.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/nds_rrds.c @@ -32,7 +32,7 @@ VGMSTREAM * init_vgmstream_nds_rrds(STREAMFILE *streamFile) { } vgmstream->meta_type = meta_NDS_RRDS; - vgmstream->coding_type = coding_IMA_int; + vgmstream->coding_type = coding_IMA_mono; vgmstream->layout_type = layout_none; { diff --git a/Frameworks/vgmstream/vgmstream/src/meta/nds_strm_ffta2.c b/Frameworks/vgmstream/vgmstream/src/meta/nds_strm_ffta2.c deleted file mode 100644 index 077404ac2..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/nds_strm_ffta2.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "meta.h" - -/* STRM - from Final Fantasy Tactics A2 (NDS) */ -VGMSTREAM * init_vgmstream_nds_strm_ffta2(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count; - - - /* checks*/ - /* .bin: actual extension - * .strm: header id */ - if (!check_extensions(streamFile,"bin,strm")) - goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x52494646 || /* "RIFF" */ - read_32bitBE(0x08,streamFile) != 0x494D4120) /* "IMA " */ - goto fail; - - loop_flag = (read_32bitLE(0x20,streamFile) !=0); - channel_count = read_32bitLE(0x24,streamFile); - start_offset = 0x2C; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitLE(0x0C,streamFile); - vgmstream->num_samples = (read_32bitLE(0x04,streamFile)-start_offset); - vgmstream->loop_start_sample = read_32bitLE(0x20,streamFile); - vgmstream->loop_end_sample = read_32bitLE(0x28,streamFile); - - vgmstream->meta_type = meta_NDS_STRM_FFTA2; - - vgmstream->coding_type = coding_FFTA2_IMA; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x80; - - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ngc_dsp_mpds.c b/Frameworks/vgmstream/vgmstream/src/meta/ngc_dsp_mpds.c deleted file mode 100644 index fc492dce3..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/ngc_dsp_mpds.c +++ /dev/null @@ -1,80 +0,0 @@ -#include "meta.h" -#include "../util.h" -#include "../coding/coding.h" - -/* MPDS - found in Paradigm Entertainment GC games */ -VGMSTREAM * init_vgmstream_ngc_dsp_mpds(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag = 0, channel_count, short_mpds; - - - /* checks */ - /* .dsp: Big Air Freestyle */ - /* .mds: Terminator 3 The Redemption, Mission Impossible: Operation Surma */ - if (!check_extensions(streamFile, "dsp,mds")) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x4D504453) /* "MPDS" */ - goto fail; - - short_mpds = read_32bitBE(0x04,streamFile) != 0x00010000 && /* version byte? */ - check_extensions(streamFile, "mds"); - - channel_count = short_mpds ? - read_16bitBE(0x0a, streamFile) : - read_32bitBE(0x14, streamFile); - if (channel_count > 2) goto fail; - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = meta_NGC_DSP_MPDS; - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->layout_type = layout_interleave; - - if (!short_mpds) { /* Big Air Freestyle */ - start_offset = 0x80; - vgmstream->num_samples = read_32bitBE(0x08,streamFile); - vgmstream->sample_rate = read_32bitBE(0x10,streamFile); - vgmstream->interleave_block_size = channel_count==1 ? 0 : read_32bitBE(0x18,streamFile); - - /* compare sample count with body size */ - if ((vgmstream->num_samples / 7 * 8) != (read_32bitBE(0x0C,streamFile))) goto fail; - - dsp_read_coefs_be(vgmstream,streamFile,0x24, 0x28); - } - else { /* Terminator 3 The Redemption, Mission Impossible: Operation Surma */ - start_offset = 0x20; - vgmstream->num_samples = read_32bitBE(0x04,streamFile); - vgmstream->sample_rate = (uint16_t)read_16bitBE(0x08,streamFile); - vgmstream->interleave_block_size = channel_count==1 ? 0 : 0x200; - /* some kind of hist after 0x0c? */ - - /* set coefs, debugged from the MI:OS ELF (helpfully marked as "sMdsCoefs") */ - { - static const int16_t coefs[16] = { - 0x0000,0x0000,0x0780,0x0000,0x0e60,0xf980,0x0c40,0xf920, - 0x0f40,0xf880,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000 - }; - int i, ch; - - for (ch = 0; ch < channel_count; ch++) { - for (i = 0; i < 16; i++) { - vgmstream->ch[ch].adpcm_coef[i] = coefs[i]; - } - } - } - } - - - if ( !vgmstream_open_stream(vgmstream,streamFile,start_offset)) - goto fail; - - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/nus3audio.c b/Frameworks/vgmstream/vgmstream/src/meta/nus3audio.c index 3b7c9fdff..8adea14b3 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/nus3audio.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/nus3audio.c @@ -21,7 +21,9 @@ VGMSTREAM* init_vgmstream_nus3audio(STREAMFILE* sf) { if (!is_id32be(0x08,sf, "AUDI")) return NULL; - if (!check_extensions(sf, "nus3audio")) + /* .nus3audio: original + * .patch3audio: fake extension for some files used by the ARCropolis modding framework for SSBU (Switch) */ + if (!check_extensions(sf, "nus3audio,patch3audio")) return NULL; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/nwa.c b/Frameworks/vgmstream/vgmstream/src/meta/nwa.c index d5f634b1b..01341b445 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/nwa.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/nwa.c @@ -1,285 +1,298 @@ -#include "meta.h" -#include "../coding/coding.h" -#include -#include - - -static int get_loops_nwainfo_ini(STREAMFILE *sf, int *p_loop_flag, int32_t *p_loop_start); -static int get_loops_gameexe_ini(STREAMFILE *sf, int *p_loop_flag, int32_t *p_loop_start, int32_t *p_loop_end); - -/* NWA - Visual Art's streams [Air (PC), Clannad (PC)] */ -VGMSTREAM* init_vgmstream_nwa(STREAMFILE* sf) { - VGMSTREAM* vgmstream = NULL; - off_t start_offset; - int channel_count, loop_flag = 0; - int32_t loop_start_sample = 0, loop_end_sample = 0; - int nwainfo_ini_found = 0, gameexe_ini_found = 0; - int compression_level; - - - /* checks */ - if (!check_extensions(sf, "nwa")) - goto fail; - - channel_count = read_16bitLE(0x00,sf); - if (channel_count != 1 && channel_count != 2) goto fail; - - /* check if we're using raw pcm */ - if ( read_32bitLE(0x08,sf)==-1 || /* compression level */ - read_32bitLE(0x10,sf)==0 || /* block count */ - read_32bitLE(0x18,sf)==0 || /* compressed data size */ - read_32bitLE(0x20,sf)==0 || /* block size */ - read_32bitLE(0x24,sf)==0 ) { /* restsize */ - compression_level = -1; - } else { - compression_level = read_32bitLE(0x08,sf); - } - - /* loop points come from external files */ - nwainfo_ini_found = get_loops_nwainfo_ini(sf, &loop_flag, &loop_start_sample); - gameexe_ini_found = !nwainfo_ini_found && get_loops_gameexe_ini(sf, &loop_flag, &loop_start_sample, &loop_end_sample); - - start_offset = 0x2c; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = read_32bitLE(0x04,sf); - vgmstream->num_samples = read_32bitLE(0x1c,sf) / channel_count; - - switch(compression_level) { - case -1: - switch (read_16bitLE(0x02,sf)) { - case 8: - vgmstream->coding_type = coding_PCM8; - vgmstream->interleave_block_size = 0x01; - break; - case 16: - vgmstream->coding_type = coding_PCM16LE; - vgmstream->interleave_block_size = 0x02; - break; - default: - goto fail; - } - vgmstream->layout_type = layout_interleave; - break; - - case 0: - case 1: - case 2: - case 3: - case 4: - case 5: - vgmstream->coding_type = coding_NWA; - vgmstream->layout_type = layout_none; - vgmstream->codec_data = init_nwa(sf); - if (!vgmstream->codec_data) goto fail; - break; - - default: - goto fail; - break; - } - - - if (nwainfo_ini_found) { - vgmstream->meta_type = meta_NWA_NWAINFOINI; - if (loop_flag) { - vgmstream->loop_start_sample = loop_start_sample; - vgmstream->loop_end_sample = vgmstream->num_samples; - } - } else if (gameexe_ini_found) { - vgmstream->meta_type = meta_NWA_GAMEEXEINI; - if (loop_flag) { - vgmstream->loop_start_sample = loop_start_sample; - vgmstream->loop_end_sample = loop_end_sample; - } - } else { - vgmstream->meta_type = meta_NWA; - } - - - if (!vgmstream_open_stream(vgmstream,sf,start_offset)) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} - - -/* try to locate NWAINFO.INI in the same directory */ -static int get_loops_nwainfo_ini(STREAMFILE *sf, int *p_loop_flag, int32_t *p_loop_start) { - STREAMFILE *sf_loop; - char namebase[PATH_LIMIT]; - const char * ext; - int length; - int found; - off_t offset; - size_t file_size; - off_t found_off = -1; - int loop_flag = 0; - int32_t loop_start_sample = 0; - - - sf_loop = open_streamfile_by_filename(sf, "NWAINFO.INI"); - if (!sf_loop) goto fail; - - get_streamfile_filename(sf,namebase,PATH_LIMIT); - - /* ini found, try to find our name */ - ext = filename_extension(namebase); - length = ext - 1 - namebase; - file_size = get_streamfile_size(sf_loop); - - for (found = 0, offset = 0; !found && offset < file_size; offset++) { - off_t suboffset; - /* Go for an n*m search 'cause it's easier than building an - * FSA for the search string. Just wanted to make the point that - * I'm not ignorant, just lazy. */ - for (suboffset = offset; - suboffset < file_size && - suboffset-offset < length && - read_8bit(suboffset,sf_loop) == namebase[suboffset-offset]; - suboffset++) { - /* skip */ - } - - if (suboffset-offset==length && read_8bit(suboffset,sf_loop)==0x09) { /* tab */ - found = 1; - found_off = suboffset+1; - } - } - - /* if found file name in INI */ - if (found) { - char loopstring[9] = {0}; - - if (read_streamfile((uint8_t*)loopstring,found_off,8,sf_loop) == 8) { - loop_start_sample = atol(loopstring); - if (loop_start_sample > 0) - loop_flag = 1; - } - } - - - *p_loop_flag = loop_flag; - *p_loop_start = loop_start_sample; - - close_streamfile(sf_loop); - return 1; - -fail: - close_streamfile(sf_loop); - return 0; -} - -/* try to locate Gameexe.ini in the same directory */ -static int get_loops_gameexe_ini(STREAMFILE* sf, int* p_loop_flag, int32_t* p_loop_start, int32_t* p_loop_end) { - STREAMFILE*sf_loop; - char namebase[PATH_LIMIT]; - const char* ext; - int length; - int found; - off_t offset; - off_t file_size; - off_t found_off = -1; - int loop_flag = 0; - int32_t loop_start_sample = 0, loop_end_sample = 0; - - - sf_loop = open_streamfile_by_filename(sf, "Gameexe.ini"); - if (!sf_loop) goto fail; - - get_streamfile_filename(sf,namebase,PATH_LIMIT); - - /* ini found, try to find our name */ - ext = filename_extension(namebase); - length = ext-1-namebase; - file_size = get_streamfile_size(sf_loop); - - /* According to the official documentation of RealLiveMax (the public version of RealLive), format of line is: - * #DSTRACK = 00000000 - eeeeeeee - ssssssss = "filename" = "alias for game script" - * ^22 ^33 ^45 ^57? - * - * Original text from the documentation (written in Japanese) is: - * ; ■BGMの登録:DirectSound - * ;(※必要ない場合は登録しないで下さい。) - * ; 終了位置の設定が 99999999 なら最後まで演奏します。 - * ; ※設定値はサンプル数で指定して下さい。(旧システムではバイト指定でしたので注意してください。) - * ;========================================================================================================= - * ; 開始位置 - 終了位置 - リピート = ファイル名 = 登録名 - * #DSTRACK = 00000000 - 01896330 - 00088270 = "b_manuke" = "b_manuke" - * #DSTRACK = 00000000 - 01918487 - 00132385 = "c_happy" = "c_happy" - */ - - for (found = 0, offset = 0; !found && offset +#include + + +static int get_loops_nwainfo_ini(STREAMFILE *sf, int *p_loop_flag, int32_t *p_loop_start); +static int get_loops_gameexe_ini(STREAMFILE *sf, int *p_loop_flag, int32_t *p_loop_start, int32_t *p_loop_end); + +/* .NWA - Visual Art's streams [Air (PC), Clannad (PC)] */ +VGMSTREAM* init_vgmstream_nwa(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int channels, sample_rate, bps, loop_flag = 0; + int32_t loop_start_sample = 0, loop_end_sample = 0; + bool nwainfo_ini_found = false, gameexe_ini_found = false; + int compression_level; + + + /* checks */ + if (!check_extensions(sf, "nwa")) + return NULL; + + channels = read_s16le(0x00,sf); + bps = read_s16le(0x02,sf); + sample_rate = read_s32le(0x04,sf); + if (channels != 1 && channels != 2) + return NULL; + if (bps != 0 && bps != 8 && bps != 16) + return NULL; + if (sample_rate < 8000 || sample_rate > 48000) //unsure if can go below 44100 + return NULL; + + /* check if we're using raw pcm */ + if ( read_s32le(0x08,sf) == -1 || /* compression level */ + read_s32le(0x10,sf) == 0 || /* block count */ + read_s32le(0x18,sf) == 0 || /* compressed data size */ + read_s32le(0x20,sf) == 0 || /* block size */ + read_s32le(0x24,sf) == 0 ) { /* restsize */ + compression_level = -1; + } + else { + compression_level = read_s32le(0x08,sf); + } + + if (compression_level > 5) + return NULL; + + /* loop points come from external files */ + nwainfo_ini_found = get_loops_nwainfo_ini(sf, &loop_flag, &loop_start_sample); + gameexe_ini_found = !nwainfo_ini_found && get_loops_gameexe_ini(sf, &loop_flag, &loop_start_sample, &loop_end_sample); + + start_offset = 0x2c; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = read_s32le(0x04,sf); + vgmstream->num_samples = read_s32le(0x1c,sf) / channels; + + switch(compression_level) { + case -1: + switch (bps) { + case 8: + vgmstream->coding_type = coding_PCM8; + vgmstream->interleave_block_size = 0x01; + break; + case 16: + vgmstream->coding_type = coding_PCM16LE; + vgmstream->interleave_block_size = 0x02; + break; + default: + goto fail; + } + vgmstream->layout_type = layout_interleave; + break; + + case 0: + case 1: + case 2: + case 3: + case 4: + case 5: + vgmstream->coding_type = coding_NWA; + vgmstream->layout_type = layout_none; + vgmstream->codec_data = init_nwa(sf); + if (!vgmstream->codec_data) goto fail; + break; + + default: + goto fail; + break; + } + + + if (nwainfo_ini_found) { + vgmstream->meta_type = meta_NWA_NWAINFOINI; + if (loop_flag) { + vgmstream->loop_start_sample = loop_start_sample; + vgmstream->loop_end_sample = vgmstream->num_samples; + } + } + else if (gameexe_ini_found) { + vgmstream->meta_type = meta_NWA_GAMEEXEINI; + if (loop_flag) { + vgmstream->loop_start_sample = loop_start_sample; + vgmstream->loop_end_sample = loop_end_sample; + } + } + else { + vgmstream->meta_type = meta_NWA; + } + + + if (!vgmstream_open_stream(vgmstream,sf,start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} + + +/* try to locate NWAINFO.INI in the same directory */ +static int get_loops_nwainfo_ini(STREAMFILE *sf, int *p_loop_flag, int32_t *p_loop_start) { + STREAMFILE *sf_loop; + char namebase[PATH_LIMIT]; + const char * ext; + int length; + int found; + off_t offset; + size_t file_size; + off_t found_off = -1; + int loop_flag = 0; + int32_t loop_start_sample = 0; + + + sf_loop = open_streamfile_by_filename(sf, "NWAINFO.INI"); + if (!sf_loop) goto fail; + + get_streamfile_filename(sf,namebase,PATH_LIMIT); + + /* ini found, try to find our name */ + ext = filename_extension(namebase); + length = ext - 1 - namebase; + file_size = get_streamfile_size(sf_loop); + + for (found = 0, offset = 0; !found && offset < file_size; offset++) { + off_t suboffset; + /* Go for an n*m search 'cause it's easier than building an + * FSA for the search string. Just wanted to make the point that + * I'm not ignorant, just lazy. */ + for (suboffset = offset; + suboffset < file_size && + suboffset-offset < length && + read_8bit(suboffset,sf_loop) == namebase[suboffset-offset]; + suboffset++) { + /* skip */ + } + + if (suboffset-offset==length && read_8bit(suboffset,sf_loop)==0x09) { /* tab */ + found = 1; + found_off = suboffset+1; + } + } + + /* if found file name in INI */ + if (found) { + char loopstring[9] = {0}; + + if (read_streamfile((uint8_t*)loopstring,found_off,8,sf_loop) == 8) { + loop_start_sample = atol(loopstring); + if (loop_start_sample > 0) + loop_flag = 1; + } + } + + + *p_loop_flag = loop_flag; + *p_loop_start = loop_start_sample; + + close_streamfile(sf_loop); + return 1; + +fail: + close_streamfile(sf_loop); + return 0; +} + +/* try to locate Gameexe.ini in the same directory */ +static int get_loops_gameexe_ini(STREAMFILE* sf, int* p_loop_flag, int32_t* p_loop_start, int32_t* p_loop_end) { + STREAMFILE*sf_loop; + char namebase[PATH_LIMIT]; + const char* ext; + int length; + int found; + off_t offset; + off_t file_size; + off_t found_off = -1; + int loop_flag = 0; + int32_t loop_start_sample = 0, loop_end_sample = 0; + + + sf_loop = open_streamfile_by_filename(sf, "Gameexe.ini"); + if (!sf_loop) goto fail; + + get_streamfile_filename(sf,namebase,PATH_LIMIT); + + /* ini found, try to find our name */ + ext = filename_extension(namebase); + length = ext-1-namebase; + file_size = get_streamfile_size(sf_loop); + + /* According to the official documentation of RealLiveMax (the public version of RealLive), format of line is: + * #DSTRACK = 00000000 - eeeeeeee - ssssssss = "filename" = "alias for game script" + * ^22 ^33 ^45 ^57? + * + * Original text from the documentation (written in Japanese) is: + * ; ■BGMの登録:DirectSound + * ;(※必要ない場合は登録しないで下さい。) + * ; 終了位置の設定が 99999999 なら最後まで演奏します。 + * ; ※設定値はサンプル数で指定して下さい。(旧システムではバイト指定でしたので注意してください。) + * ;========================================================================================================= + * ; 開始位置 - 終了位置 - リピート = ファイル名 = 登録名 + * #DSTRACK = 00000000 - 01896330 - 00088270 = "b_manuke" = "b_manuke" + * #DSTRACK = 00000000 - 01918487 - 00132385 = "c_happy" = "c_happy" + */ + + for (found = 0, offset = 0; !found && offsetdecryption_callback = at4_ogg_decryption_callback; //TODO replace with generic descryption? + ovmi->decryption_callback = at4_ogg_decryption_callback; //TODO replace with generic decryption? if (!check_extensions(sf,"ogg,logg")) goto fail; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/otm.c b/Frameworks/vgmstream/vgmstream/src/meta/otm.c deleted file mode 100644 index 500771c07..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/otm.c +++ /dev/null @@ -1,73 +0,0 @@ -#include "meta.h" -#include "../coding/coding.h" -#include "../layout/layout.h" -#include "../util.h" - -/* Otomedius OTM (Arcade) */ -VGMSTREAM * init_vgmstream_otm(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; - off_t start_offset; - - int loop_flag; - int channel_count; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("otm",filename_extension(filename))) goto fail; - - /* check header */ - if (read_32bitBE(0x20,streamFile) != 0x10B10200) - goto fail; - if (read_32bitBE(0x24,streamFile) != 0x04001000) - goto fail; - - if (read_32bitBE(0x14,streamFile) != 0x00000000) - loop_flag = 1; - else - loop_flag = 0; - channel_count = read_16bitLE(0x1A,streamFile); - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - start_offset = 0x2C; - vgmstream->num_samples = (get_streamfile_size(streamFile)- start_offset)/channel_count/2; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitLE(0x1C,streamFile); - if (loop_flag) { - vgmstream->loop_start_sample = (read_32bitLE(0x10,streamFile))/channel_count/2; - vgmstream->loop_end_sample = (read_32bitLE(0xC,streamFile) - start_offset)/channel_count/2; - } - vgmstream->coding_type = coding_PCM16LE; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 2; - vgmstream->meta_type = meta_OTM; - - /* open the file for reading */ - { - int i; - STREAMFILE * file; - file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (!file) goto fail; - for (i=0;ich[i].streamfile = file; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset=start_offset+ - vgmstream->interleave_block_size*i; - - } - - } - - return vgmstream; - -fail: - /* clean up anything we may have opened */ - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} - diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ps2_snd.c b/Frameworks/vgmstream/vgmstream/src/meta/ps2_snd.c index 42378f97d..0b8be53ea 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ps2_snd.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ps2_snd.c @@ -1,53 +1,53 @@ -#include "meta.h" -#include "../util.h" - -/* SND - Might and Magic games [Warriors of M&M (PS2), Heroes of M&M: Quest for the DragonBone Staff (PS2)] */ -VGMSTREAM * init_vgmstream_ps2_snd(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - size_t data_size; - int loop_flag, channel_count; - - /* checks */ - if (!check_extensions(streamFile, "snd")) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x53534E44) /* "SSND" */ - goto fail; - - start_offset = read_32bitLE(0x04,streamFile)+0x08; - data_size = get_streamfile_size(streamFile) - start_offset; - - loop_flag = 1; /* force full Loop */ - channel_count = read_16bitLE(0x0a,streamFile); - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = (uint16_t)read_16bitLE(0x0e,streamFile); - vgmstream->num_samples = read_32bitLE(0x16,streamFile); - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = vgmstream->num_samples; - - vgmstream->meta_type = meta_PS2_SND; - - if (read_8bit(0x08,streamFile)==1) { - vgmstream->coding_type = coding_DVI_IMA_int; /* Warriors of M&M DragonBone */ - } - else { - vgmstream->coding_type = coding_PCM16LE; /* Heroes of M&M */ - } - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = (uint16_t)read_16bitLE(0x12,streamFile); - if (vgmstream->interleave_block_size) - vgmstream->interleave_last_block_size = (data_size % (vgmstream->interleave_block_size*vgmstream->channels)) / vgmstream->channels; - - - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} +#include "meta.h" +#include "../util.h" + +/* SND - Might and Magic games [Warriors of M&M (PS2), Heroes of M&M: Quest for the DragonBone Staff (PS2)] */ +VGMSTREAM * init_vgmstream_ps2_snd(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + size_t data_size; + int loop_flag, channel_count; + + /* checks */ + if (!check_extensions(streamFile, "snd")) + goto fail; + if (read_32bitBE(0x00,streamFile) != 0x53534E44) /* "SSND" */ + goto fail; + + start_offset = read_32bitLE(0x04,streamFile)+0x08; + data_size = get_streamfile_size(streamFile) - start_offset; + + loop_flag = 1; /* force full Loop */ + channel_count = read_16bitLE(0x0a,streamFile); + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = (uint16_t)read_16bitLE(0x0e,streamFile); + vgmstream->num_samples = read_32bitLE(0x16,streamFile); + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = vgmstream->num_samples; + + vgmstream->meta_type = meta_PS2_SND; + + if (read_8bit(0x08,streamFile)==1) { + vgmstream->coding_type = coding_DVI_IMA_mono; /* Warriors of M&M DragonBone */ + } + else { + vgmstream->coding_type = coding_PCM16LE; /* Heroes of M&M */ + } + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = (uint16_t)read_16bitLE(0x12,streamFile); + if (vgmstream->interleave_block_size) + vgmstream->interleave_last_block_size = (data_size % (vgmstream->interleave_block_size*vgmstream->channels)) / vgmstream->channels; + + + if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ps2_vds_vdm.c b/Frameworks/vgmstream/vgmstream/src/meta/ps2_vds_vdm.c deleted file mode 100644 index 1b4006a45..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/ps2_vds_vdm.c +++ /dev/null @@ -1,51 +0,0 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* VDS/VDM - from Procyon Studio games [Grafitti Kingdom / Rakugaki Oukoku 2 (PS2), Tsukiyo ni Saraba (PS2)] */ -VGMSTREAM * init_vgmstream_ps2_vds_vdm(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count; - - - /* checks */ - if ( !check_extensions(streamFile,"vds,vdm")) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x56445320 && /* "VDS " (music)*/ - read_32bitBE(0x00,streamFile) != 0x56444D20) /* "VDM " (voices) */ - goto fail; - - loop_flag = read_8bit(0x20,streamFile); - channel_count = read_32bitLE(0x10,streamFile); - start_offset = 0x800; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* 0x08: unknown, always 0x10 */ - vgmstream->sample_rate = read_32bitLE(0x0c,streamFile); - - /* when looping (or maybe when stereo) data_size at 0x04 is actually smaller than file_size, - * sometimes cutting outros with loop disabled; doesn't affect looping though */ - if (!loop_flag) - vgmstream->num_samples = ps_bytes_to_samples(read_32bitLE(0x04,streamFile), channel_count); - else - vgmstream->num_samples = ps_bytes_to_samples(get_streamfile_size(streamFile) - start_offset, channel_count); - vgmstream->loop_start_sample = ps_bytes_to_samples(read_32bitLE(0x18,streamFile) - start_offset, channel_count); - vgmstream->loop_end_sample = ps_bytes_to_samples(read_32bitLE(0x1c,streamFile) - start_offset, channel_count); - /* 0x21: volume?, 0x22: pan?, 0x23: 02=VDS 04=VDM? 02/05=VDM in Tsukiyo ni Saraba? */ - - vgmstream->meta_type = meta_PS2_VDS_VDM; - vgmstream->coding_type = coding_PSX; - vgmstream->layout_type = (channel_count == 1) ? layout_none : layout_interleave; - vgmstream->interleave_block_size = read_32bitLE(0x14,streamFile); - - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/rage_aud.c b/Frameworks/vgmstream/vgmstream/src/meta/rage_aud.c index 0c9f7f49f..c9c11eb9c 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/rage_aud.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/rage_aud.c @@ -110,7 +110,7 @@ VGMSTREAM* init_vgmstream_rage_aud(STREAMFILE* sf) { #endif case 0x0400: /* PC */ - vgmstream->coding_type = coding_IMA_int; + vgmstream->coding_type = coding_IMA_mono; vgmstream->layout_type = aud.is_streamed ? layout_blocked_rage_aud : layout_none; vgmstream->full_block_size = aud.block_chunk; break; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ras.c b/Frameworks/vgmstream/vgmstream/src/meta/ras.c new file mode 100644 index 000000000..9fc302f8e --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/ras.c @@ -0,0 +1,55 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* RAS_ - from Donkey Kong Country Returns (Wii) */ +VGMSTREAM* init_vgmstream_ras(STREAMFILE *sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag, channels; + + /* checks */ + if (!is_id32be(0x00,sf, "RAS_")) + return NULL; + if (!check_extensions(sf, "ras")) + return NULL; + + loop_flag = 0; + if (read_u32be(0x30,sf) != 0 || + read_u32be(0x34,sf) != 0 || + read_u32be(0x38,sf) != 0 || + read_u32be(0x3C,sf) != 0) { + loop_flag = 1; + } + channels = 2; + start_offset = read_u32be(0x18,sf); + int interleave = read_u32be(0x20,sf); + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = read_s32be(0x14,sf); + vgmstream->meta_type = meta_RAS; + + vgmstream->coding_type = coding_NGC_DSP; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = interleave; + + vgmstream->num_samples = dsp_bytes_to_samples(read_u32be(0x1c,sf), channels); + if (loop_flag) { /* loop is block + samples into block */ + vgmstream->loop_start_sample = dsp_bytes_to_samples(read_u32be(0x30,sf) * interleave, 1) + read_s32be(0x34,sf); + vgmstream->loop_end_sample = dsp_bytes_to_samples(read_u32be(0x38,sf) * interleave, 1) + read_s32be(0x3C,sf); + } + + dsp_read_coefs_be(vgmstream,sf,0x40,0x30); + + + if (!vgmstream_open_stream(vgmstream,sf,start_offset)) + goto fail; + return vgmstream; + + /* clean up anything we may have opened */ +fail: + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/riff.c b/Frameworks/vgmstream/vgmstream/src/meta/riff.c index 86a66e48c..4191dc984 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/riff.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/riff.c @@ -474,7 +474,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) { * .p1d: Farming Simulator 15 (Vita)[ATRAC9] * .xms: Ty the Tasmanian Tiger (Xbox) * .mus: Burnout Legends/Dominator (PSP) - * .dat/ldat: RollerCoaster Tycoon 1/2 (PC) + * .dat/ldat: RollerCoaster Tycoon 1/2 (PC), Winning Eleven 2008 (AC) * .wma/lwma: SRS: Street Racing Syndicate (Xbox), Fast and the Furious (Xbox) * .caf: Topple (iOS) * .wax: Lamborghini (Xbox) diff --git a/Frameworks/vgmstream/vgmstream/src/meta/riff_ima.c b/Frameworks/vgmstream/vgmstream/src/meta/riff_ima.c new file mode 100644 index 000000000..4c6fa54ba --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/riff_ima.c @@ -0,0 +1,48 @@ +#include "meta.h" + +/* RIFF IMA - from Final Fantasy Tactics A2 (NDS) */ +VGMSTREAM* init_vgmstream_riff_ima(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag, channels; + + + /* checks*/ + if (!is_id32be(0x00,sf, "RIFF")) + return NULL; + // 04: full filesize + if (!is_id32be(0x08,sf, "IMA ")) + return NULL; + + /* .bin: actual extension + * .strm: folder */ + if (!check_extensions(sf,"bin,lbin,strm")) + return NULL; + + loop_flag = (read_s32le(0x20,sf) !=0); + channels = read_s32le(0x24,sf); + start_offset = 0x2C; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->channels = channels; + vgmstream->sample_rate = read_s32le(0x0C,sf); + vgmstream->num_samples = (read_s32le(0x04,sf)-start_offset); + vgmstream->loop_start_sample = read_s32le(0x20,sf); + vgmstream->loop_end_sample = read_s32le(0x28,sf); + + vgmstream->meta_type = meta_RIFF_IMA; + vgmstream->coding_type = coding_SQEX_IMA; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x80; + + if (!vgmstream_open_stream(vgmstream,sf,start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/sadl.c b/Frameworks/vgmstream/vgmstream/src/meta/sadl.c index 78cc0654e..3fc59304e 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/sadl.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/sadl.c @@ -66,7 +66,7 @@ VGMSTREAM* init_vgmstream_sadl(STREAMFILE* sf) { switch(flags & 0xf0) { /* possibly >> 6? (0/1/2) */ case 0x00: /* Luminous Arc (DS) (non-int IMA? all files are mono though) */ case 0x70: /* Ni no Kuni (DS), Professor Layton and the Curious Village (DS), Soma Bringer (DS) */ - vgmstream->coding_type = coding_IMA_int; + vgmstream->coding_type = coding_IMA_mono; vgmstream->num_samples = ima_bytes_to_samples(data_size, channels); vgmstream->loop_start_sample = ima_bytes_to_samples(loop_start, channels); diff --git a/Frameworks/vgmstream/vgmstream/src/meta/sat_dvi.c b/Frameworks/vgmstream/vgmstream/src/meta/sat_dvi.c index 95dfb526f..538f86603 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/sat_dvi.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/sat_dvi.c @@ -29,7 +29,7 @@ VGMSTREAM* init_vgmstream_sat_dvi(STREAMFILE* sf) { vgmstream->loop_start_sample = read_s32be(0x0C,sf); vgmstream->loop_end_sample = read_s32be(0x08,sf); - vgmstream->coding_type = coding_DVI_IMA_int; + vgmstream->coding_type = coding_DVI_IMA_mono; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x4; vgmstream->meta_type = meta_SAT_DVI; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/shaa.c b/Frameworks/vgmstream/vgmstream/src/meta/shaa.c new file mode 100644 index 000000000..d2ea01ec4 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/shaa.c @@ -0,0 +1,66 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* SHAA/SHSA: Audio format for Nintendo Sound Clock: Alarmo */ +VGMSTREAM* init_vgmstream_shaa(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + uint32_t start_offset, info_offset, adpcm_offset; + int channels, loop_flag, loop_start, loop_end, codec; + + /* Validate header */ + if (!is_id32be(0x00, sf, "SHAA")) + goto fail; + + /* Validate extension */ + if (!check_extensions(sf, "shaa,shsa")) + goto fail; + + info_offset = 0x10; + + codec = read_u8(info_offset + 0x00, sf); + channels = 1; // Not sure if file is stereo or mono, so assuming mono for now + + start_offset = read_u32le(0x08, sf); + + /* Loop start and end points */ + loop_start = read_s32le(info_offset + 0x14, sf); + loop_end = read_s32le(info_offset + 0x18, sf); + loop_flag = loop_start + loop_end; // Loop flag is 0 if loop start and loop end are both 0 + + /* Alloc vgmstream */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_SHAA; + + vgmstream->sample_rate = read_u16le(info_offset + 0x04, sf); + vgmstream->num_samples = read_s32le(info_offset + 0x08, sf); + vgmstream->loop_start_sample = loop_start; + vgmstream->loop_end_sample = loop_end; + + + vgmstream->layout_type = layout_none; + switch (codec) { + case 1: // PCM16LE: Seen in "factory" sound files + vgmstream->coding_type = coding_PCM16LE; + break; + case 2: // NGC DSP: Used for everything else + vgmstream->coding_type = coding_NGC_DSP; + break; + default: + goto fail; + } + + if (vgmstream->coding_type == coding_NGC_DSP) { + adpcm_offset = read_u32le(info_offset + 0x0C, sf); + dsp_read_coefs_le(vgmstream, sf, adpcm_offset + 0x1C, 0); // 0 spacing because there's only 1 channel + } + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/smss.c b/Frameworks/vgmstream/vgmstream/src/meta/smss.c new file mode 100644 index 000000000..eb8859e83 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/smss.c @@ -0,0 +1,41 @@ +#include "meta.h" +#include "../util/meta_utils.h" +#include "../coding/coding.h" + + +/* SMSS - from Tiny Toon Adventures: Defenders of the Universe (PS2) */ +VGMSTREAM* init_vgmstream_smss(STREAMFILE *sf) { + + if (!is_id32be(0x00,sf, "SMSS")) + return NULL; + if (!check_extensions(sf, "vsf")) + return NULL; + + meta_header_t h = {0}; + h.meta = meta_SMSS; + + // 04: header size? + h.interleave = read_u32le(0x08,sf); + h.channels = read_s32le(0x0c,sf); + h.sample_rate = read_s32le(0x10,sf); + // 14: null? + h.loop_start = read_u32le(0x18,sf); + h.loop_end = read_u32le(0x1c,sf); + // rest: padding + + + h.loop_flag = h.loop_start > 0; + h.stream_offset = 0x800; + h.stream_size = get_streamfile_size(sf) - h.stream_offset; + + h.num_samples = ps_bytes_to_samples(h.stream_size, h.channels); + h.loop_start = ps_bytes_to_samples(h.loop_start, 1); + h.loop_end = ps_bytes_to_samples(h.loop_end, 1); + + h.coding = coding_PSX; + h.layout = layout_interleave; + h.open_stream = true; + h.sf = sf; + + return alloc_metastream(&h); +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/stma.c b/Frameworks/vgmstream/vgmstream/src/meta/stma.c index 65e20493e..b7a3da3bf 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/stma.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/stma.c @@ -82,7 +82,7 @@ VGMSTREAM* init_vgmstream_stma(STREAMFILE* sf) { dsp_read_hist_be(vgmstream, sf, 0x60, 0x60); } else { /* DVI IMA ADPCM (Red Dead Revolver, Midnight Club 2) */ - vgmstream->coding_type = coding_DVI_IMA_int; + vgmstream->coding_type = coding_DVI_IMA_mono; /* 'interleave not' reliable, strange values and rarely needs 0x80 */ vgmstream->interleave_block_size = (interleave == 0xc000) ? 0x80 : 0x40; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/svg.c b/Frameworks/vgmstream/vgmstream/src/meta/svg.c deleted file mode 100644 index 99aad3445..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/svg.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* SVG - from High Voltage games [Hunter: The Reckoning - Wayward (PS2)] */ -VGMSTREAM * init_vgmstream_svg(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - size_t data_size, interleave; - int loop_flag, channel_count; - int32_t loop_start = 0, loop_end = 0; - - - /* checks */ - if ( !check_extensions(streamFile,"svg") ) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x53564770) /* "SVGp" */ - goto fail; - - start_offset = 0x800; - data_size = read_32bitLE(0x18,streamFile); - interleave = read_32bitLE(0x14,streamFile); - channel_count = 2; - loop_flag = ps_find_loop_offsets(streamFile, start_offset, data_size, channel_count, interleave,&loop_start, &loop_end); - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = meta_SVG; - vgmstream->sample_rate = read_32bitBE(0x2c,streamFile); - vgmstream->num_samples = ps_bytes_to_samples(data_size,channel_count); - vgmstream->loop_start_sample = loop_start; - vgmstream->loop_end_sample = loop_end; - - vgmstream->coding_type = coding_PSX; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = interleave; - read_string(vgmstream->stream_name,0x10+1, 0x04,streamFile); - - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/svgp.c b/Frameworks/vgmstream/vgmstream/src/meta/svgp.c new file mode 100644 index 000000000..c1c8e2a73 --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/svgp.c @@ -0,0 +1,47 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* SVGp - from High Voltage games [Hunter: The Reckoning - Wayward (PS2)] */ +VGMSTREAM* init_vgmstream_svgp(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + size_t data_size, interleave; + int loop_flag, channels; + int32_t loop_start = 0, loop_end = 0; + + + /* checks */ + if (!is_id32be(0x00,sf, "SVGp")) + return NULL; + if (!check_extensions(sf,"svg")) + return NULL; + + start_offset = 0x800; + data_size = read_u32le(0x18,sf); + interleave = read_u32le(0x14,sf); + channels = 2; + loop_flag = ps_find_loop_offsets(sf, start_offset, data_size, channels, interleave,&loop_start, &loop_end); + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels, loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_SVGP; + vgmstream->sample_rate = read_s32be(0x2c,sf); + vgmstream->num_samples = ps_bytes_to_samples(data_size,channels); + vgmstream->loop_start_sample = loop_start; + vgmstream->loop_end_sample = loop_end; + + vgmstream->coding_type = coding_PSX; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = interleave; + read_string(vgmstream->stream_name,0x10+1, 0x04,sf); + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/swav.c b/Frameworks/vgmstream/vgmstream/src/meta/swav.c index 6fdaa5a48..1713cba4c 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/swav.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/swav.c @@ -60,7 +60,7 @@ VGMSTREAM* init_vgmstream_swav(STREAMFILE* sf) { bits_per_sample = 16; break; case 2: - coding_type = coding_IMA_int; + coding_type = coding_IMA_mono; bits_per_sample = 4; break; default: @@ -79,7 +79,7 @@ VGMSTREAM* init_vgmstream_swav(STREAMFILE* sf) { vgmstream->loop_end_sample = loop_end * 32 / bits_per_sample + vgmstream->loop_start_sample; } - if (coding_type == coding_IMA_int) { + if (coding_type == coding_IMA_mono) { /* handle IMA frame header */ vgmstream->loop_start_sample -= 32 / bits_per_sample; vgmstream->loop_end_sample -= 32 / bits_per_sample; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/txth.c b/Frameworks/vgmstream/vgmstream/src/meta/txth.c index ac0acba52..9c07d2696 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/txth.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/txth.c @@ -84,7 +84,7 @@ typedef struct { uint32_t sample_rate; uint32_t data_size; - int data_size_set; + bool data_size_set; uint32_t start_offset; uint32_t next_offset; uint32_t padding_size; @@ -94,22 +94,22 @@ typedef struct { uint32_t loop_start_sample; uint32_t loop_end_sample; uint32_t loop_adjust; - int skip_samples_set; + bool skip_samples_set; uint32_t skip_samples; uint32_t loop_flag; txth_loop_t loop_behavior; - int loop_flag_set; + bool loop_flag_set; int loop_flag_auto; uint32_t coef_offset; uint32_t coef_spacing; uint32_t coef_big_endian; uint32_t coef_mode; - int coef_table_set; + bool coef_table_set; uint8_t coef_table[0x02*16 * 16]; /* reasonable max */ - int hist_set; + bool hist_set; uint32_t hist_offset; uint32_t hist_spacing; uint32_t hist_big_endian; @@ -125,7 +125,7 @@ typedef struct { uint32_t name_offset; uint32_t name_size; - int subfile_set; + bool subfile_set; uint32_t subfile_offset; uint32_t subfile_size; char subfile_extension[16]; @@ -140,11 +140,11 @@ typedef struct { uint32_t chunk_bsize_offset; uint32_t chunk_dsize_offset; uint32_t chunk_big_endian; - int chunk_start_set; - int chunk_size_set; - int chunk_count_set; - int chunk_bsize_set; - int chunk_dsize_set; + bool chunk_start_set; + bool chunk_size_set; + bool chunk_count_set; + bool chunk_bsize_set; + bool chunk_dsize_set; uint32_t base_offset; uint32_t is_offset_absolute; @@ -162,11 +162,11 @@ typedef struct { STREAMFILE* sf_text; STREAMFILE* sf_head; STREAMFILE* sf_body; - int sf_text_opened; - int sf_head_opened; - int sf_body_opened; + bool sf_text_opened; + bool sf_head_opened; + bool sf_body_opened; - int debug; + bool debug; } txth_header; @@ -193,9 +193,9 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { txth.sf_text = sf; txth.sf_head = NULL; txth.sf_body = NULL; - txth.sf_text_opened = 0; - txth.sf_head_opened = 0; - txth.sf_body_opened = 0; + txth.sf_text_opened = false; + txth.sf_head_opened = false; + txth.sf_body_opened = false; } else { /* accept base file (no need for ID or ext checks --if a companion .TXTH exists all is good). @@ -209,14 +209,14 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { txth.sf_text = sf_text; txth.sf_head = sf; txth.sf_body = sf; - txth.sf_text_opened = 1; - txth.sf_head_opened = 0; - txth.sf_body_opened = 0; + txth.sf_text_opened = true; + txth.sf_head_opened = false; + txth.sf_body_opened = false; } /* process the text file */ if (!parse_txth(&txth)) - goto fail; + return NULL; /* special case of parsing subfiles */ if (txth.subfile_set) { @@ -371,9 +371,9 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { else { vgmstream->layout_type = layout_interleave; if (coding == coding_DVI_IMA) - coding = coding_DVI_IMA_int; + coding = coding_DVI_IMA_mono; if (coding == coding_IMA) - coding = coding_IMA_int; + coding = coding_IMA_mono; if (coding == coding_AICA) coding = coding_AICA_int; } @@ -383,8 +383,8 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) { coding == coding_PSX || coding == coding_PSX_badflags || coding == coding_HEVAG || - coding == coding_IMA_int || - coding == coding_DVI_IMA_int || + coding == coding_IMA_mono || + coding == coding_DVI_IMA_mono || coding == coding_SDX2_int || coding == coding_AICA_int) ) { goto fail; @@ -720,8 +720,12 @@ static VGMSTREAM* init_subfile(txth_header* txth) { strcpy(extension, ".subfile_txth."); strcat(extension, txth->subfile_extension); + if (txth->debug) + vgm_logi("TXTH: subfile offset=%x, size=%x\n", txth->subfile_offset, txth->subfile_size); + sf_sub = setup_subfile_streamfile(txth->sf_body, txth->subfile_offset, txth->subfile_size, extension); if (!sf_sub) goto fail; + //;dump_streamfile(sf_sub, txth->sf->stream_index); sf_sub->stream_index = txth->sf->stream_index; @@ -902,9 +906,9 @@ static void set_body_chunk(txth_header* txth) { txth->sf_body_opened = 1; /* cancel values once set, to avoid weirdness and possibly allow chunks-in-chunks? */ - txth->chunk_start_set = 0; - txth->chunk_size_set = 0; - txth->chunk_count_set = 0; + txth->chunk_start_set = false; + txth->chunk_size_set = false; + txth->chunk_count_set = false; /* re-apply */ if (!txth->data_size_set) { @@ -1221,7 +1225,7 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha } else if (is_string(key,"data_size")) { if (!parse_num(txth->sf_head,txth,val, &txth->data_size)) goto fail; - txth->data_size_set = 1; + txth->data_size_set = true; } /* SAMPLES */ @@ -1269,7 +1273,7 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha } else if (is_string(key,"skip_samples")) { if (!parse_num(txth->sf_head,txth,val, &txth->skip_samples)) goto fail; - txth->skip_samples_set = 1; + txth->skip_samples_set = true; if (txth->sample_type==1) txth->skip_samples = get_bytes_to_samples(txth, txth->skip_samples); if (txth->sample_type==2) @@ -1284,15 +1288,15 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha } else if (is_string(key,"loop_flag")) { if (is_string(val,"auto")) { - txth->loop_flag_auto = 1; + txth->loop_flag_auto = true; } else { if (!parse_num(txth->sf_head,txth,val, &txth->loop_flag)) goto fail; - txth->loop_flag_set = 1; + txth->loop_flag_set = true; if (txth->loop_behavior == DEFAULT) { if ((txth->loop_flag == 0xFFFF || txth->loop_flag == 0xFFFFFFFF) ) - txth->loop_flag = 0; + txth->loop_flag = false; } else if (txth->loop_behavior == NEGATIVE) { if (txth->loop_flag == 0xFF || txth->loop_flag == 0xFFFF || txth->loop_flag == 0xFFFFFFFF) @@ -1342,13 +1346,13 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha } else if (is_string(key,"coef_table")) { if (!parse_coef_table(txth->sf_head,txth,val, txth->coef_table, sizeof(txth->coef_table))) goto fail; - txth->coef_table_set = 1; + txth->coef_table_set = true; } /* HIST */ else if (is_string(key,"hist_offset")) { if (!parse_num(txth->sf_head,txth,val, &txth->hist_offset)) goto fail; - txth->hist_set = 1; + txth->hist_set = true; /* special adjustment */ txth->hist_offset += txth->hist_offset; if (txth->subsong_spacing && !txth->is_offset_absolute) @@ -1387,7 +1391,7 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha else if (is_string(key,"name_offset")) { if (!parse_num(txth->sf_head,txth,val, &txth->name_offset)) goto fail; - txth->name_offset_set = 1; + txth->name_offset_set = true; /* special adjustment */ txth->name_offset += txth->base_offset; if (txth->subsong_spacing && !txth->is_offset_absolute) @@ -1395,7 +1399,7 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha } else if (is_string(key,"name_offset_absolute")) { //TODO: remove if (!parse_num(txth->sf_head,txth,val, &txth->name_offset)) goto fail; - txth->name_offset_set = 1; + txth->name_offset_set = true; /* special adjustment */ txth->name_offset += txth->base_offset; /* unlike the above this is meant for reads that point to somewhere in the file, regardless subsong number */ @@ -1407,15 +1411,17 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha /* SUBFILES */ else if (is_string(key,"subfile_offset")) { if (!parse_num(txth->sf_head,txth,val, &txth->subfile_offset)) goto fail; - txth->subfile_set = 1; + txth->subfile_set = true; + /* special adjustment */ + //txth->subfile_offset += txth->base_offset; //TODO: useful? typically absolute } else if (is_string(key,"subfile_size")) { if (!parse_num(txth->sf_head,txth,val, &txth->subfile_size)) goto fail; - txth->subfile_set = 1; + txth->subfile_set = true; } else if (is_string(key,"subfile_extension")) { if (!parse_string(txth->sf_head,txth,val, txth->subfile_extension, sizeof(txth->subfile_extension))) goto fail; - txth->subfile_set = 1; + txth->subfile_set = true; } /* HEADER/BODY CONFIG */ @@ -1503,17 +1509,17 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha /* CHUNKS */ else if (is_string(key,"chunk_count")) { if (!parse_num(txth->sf_head,txth,val, &txth->chunk_count)) goto fail; - txth->chunk_count_set = 1; + txth->chunk_count_set = true; set_body_chunk(txth); } else if (is_string(key,"chunk_start")) { if (!parse_num(txth->sf_head,txth,val, &txth->chunk_start)) goto fail; - txth->chunk_start_set = 1; + txth->chunk_start_set = true; set_body_chunk(txth); } else if (is_string(key,"chunk_size")) { if (!parse_num(txth->sf_head,txth,val, &txth->chunk_size)) goto fail; - txth->chunk_size_set = 1; + txth->chunk_size_set = true; set_body_chunk(txth); } /* optional and should go before the above */ @@ -1531,13 +1537,13 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha } else if (is_string(key,"chunk_size_offset")) { if (!parse_num(txth->sf_head,txth,val, &txth->chunk_bsize_offset)) goto fail; - txth->chunk_size_set = 1; - txth->chunk_bsize_set = 1; + txth->chunk_size_set = true; + txth->chunk_bsize_set = true; } else if (is_string(key,"chunk_data_size_offset")) { if (!parse_num(txth->sf_head,txth,val, &txth->chunk_dsize_offset)) goto fail; - txth->chunk_size_set = 1; - txth->chunk_dsize_set = 1; + txth->chunk_size_set = true; + txth->chunk_dsize_set = true; } else if (is_string(key,"chunk_endianness")) { if (!parse_endianness(txth, val, &txth->chunk_big_endian, NULL)) goto fail; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ubi_apm.c b/Frameworks/vgmstream/vgmstream/src/meta/ubi_apm.c index a5bb4a75b..086142261 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ubi_apm.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ubi_apm.c @@ -60,7 +60,7 @@ VGMSTREAM* init_vgmstream_ubi_apm(STREAMFILE* sf) { if (!vgmstream) goto fail; vgmstream->meta_type = meta_UBI_APM; - vgmstream->coding_type = coding_DVI_IMA_int; + vgmstream->coding_type = coding_DVI_IMA_mono; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x01; vgmstream->sample_rate = sample_rate; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ubi_sb.c b/Frameworks/vgmstream/vgmstream/src/meta/ubi_sb.c index efa5aba32..03c5877c3 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ubi_sb.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ubi_sb.c @@ -1198,7 +1198,7 @@ static VGMSTREAM* init_vgmstream_ubi_sb_base(ubi_sb_header* sb, STREAMFILE* sf_h /* APM is a full format though most fields are repeated from .bnm * see ubi_apm.c for documentation */ - vgmstream->coding_type = coding_DVI_IMA_int; + vgmstream->coding_type = coding_DVI_IMA_mono; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x01; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/undefind.c b/Frameworks/vgmstream/vgmstream/src/meta/undefind.c new file mode 100644 index 000000000..860c8ebbb --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/undefind.c @@ -0,0 +1,57 @@ +#include "meta.h" +#include "../coding/coding.h" +#include "../util/endianness.h" + +/* UNDEFIND - Kylotonn games wrapper [Hunter's Trophy 2 (multi), WRC 5 (multi)] */ +VGMSTREAM* init_vgmstream_undefind(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + STREAMFILE* temp_sf = NULL; + + + /* checks */ + if (!is_id64be(0x00,sf,"UNDEFIND")) //odd but consistent + return NULL; + if (!check_extensions(sf,"paf")) + return NULL; + + read_u32_t read_u32 = guess_read_u32(0x0c, sf); + + // 08: IDNE in machine endianness + // 0c: always 3 (version?) + // 10: null + // 14: null + int name_size = read_u32(0x18, sf); + // 1c: platform string (WIIU, PSVITA, PS3, PC, X360) + uint32_t offset = 0x1c + name_size; + + uint32_t subfile_offset = read_u32(offset + 0x00, sf) + offset + 0x04; + // 04: always 1 (subsongs? internal FSB is always single stream) + uint32_t subfile_size = read_u32(offset + 0x08, sf); + // 0c: 2 or 7? + // 10: empty + // 20: 50.0? + // 24: 500.0? + + temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "fsb"); + if (!temp_sf) goto fail; + + // no apparent flag + if (is_id32be(subfile_offset, sf, "FSB4")) { // The Cursed Crusade (multi), Hunter's Trophy (multi) + vgmstream = init_vgmstream_fsb(temp_sf); + if (!vgmstream) goto fail; + } + else if (is_id32be(subfile_offset, sf, "FSB5")) { // WRC 5 (multi) + vgmstream = init_vgmstream_fsb5(temp_sf); + if (!vgmstream) goto fail; + } + else { + goto fail; + } + + close_streamfile(temp_sf); + return vgmstream; +fail: + close_streamfile(temp_sf); + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/vds_vdm.c b/Frameworks/vgmstream/vgmstream/src/meta/vds_vdm.c new file mode 100644 index 000000000..44b3c1f4b --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/vds_vdm.c @@ -0,0 +1,49 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* VDS/VDM - from Procyon Studio games [Grafitti Kingdom / Rakugaki Oukoku 2 (PS2), Tsukiyo ni Saraba (PS2)] */ +VGMSTREAM* init_vgmstream_vds_vdm(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + int loop_flag, channels; + + + /* checks */ + if (!is_id32be(0x00,sf, "VDS ") && !is_id32be(0x00,sf, "VDM ")) + return NULL; + if (!check_extensions(sf,"vds,vdm")) + return NULL; + + channels = read_s32le(0x10,sf); // VDM = mono, VDS = stereo + loop_flag = read_u8(0x20,sf); + start_offset = 0x800; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels,loop_flag); + if (!vgmstream) goto fail; + + /* 0x08: unknown, always 0x10 */ + vgmstream->sample_rate = read_s32le(0x0c,sf); + + /* when looping (or maybe when stereo) data_size at 0x04 is actually smaller than file_size, + * sometimes cutting outros with loop disabled; doesn't affect looping though */ + if (!loop_flag) + vgmstream->num_samples = ps_bytes_to_samples(read_u32le(0x04,sf), channels); + else + vgmstream->num_samples = ps_bytes_to_samples(get_streamfile_size(sf) - start_offset, channels); + vgmstream->loop_start_sample = ps_bytes_to_samples(read_u32le(0x18,sf) - start_offset, channels); + vgmstream->loop_end_sample = ps_bytes_to_samples(read_u32le(0x1c,sf) - start_offset, channels); + /* 0x21: volume?, 0x22: pan?, 0x23: 02=VDS 04=VDM? 02/05=VDM in Tsukiyo ni Saraba? */ + + vgmstream->meta_type = meta_VDS_VDM; + vgmstream->coding_type = coding_PSX; + vgmstream->layout_type = (channels == 1) ? layout_none : layout_interleave; + vgmstream->interleave_block_size = read_u32le(0x14,sf); + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/vsf_tta.c b/Frameworks/vgmstream/vgmstream/src/meta/vsf_tta.c deleted file mode 100644 index 03ba72fff..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/vsf_tta.c +++ /dev/null @@ -1,66 +0,0 @@ -#include "meta.h" - - -/* VSF with SMSS header (from Tiny Toon Adventures: Defenders of the Universe) */ -VGMSTREAM * init_vgmstream_ps2_vsf_tta(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; - off_t start_offset; - - int loop_flag; - int channel_count; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("vsf",filename_extension(filename))) goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x534D5353) /* "SMSS" */ - goto fail; - - - loop_flag = read_32bitLE(0x18,streamFile); - channel_count = read_32bitLE(0x0c,streamFile); - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - start_offset = 0x800; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitLE(0x10,streamFile); - vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = (get_streamfile_size(streamFile)-0x800)*28/16/channel_count; - if (loop_flag) { - vgmstream->loop_start_sample = (read_32bitLE(0x18,streamFile)*2)*28/16/channel_count; - vgmstream->loop_end_sample = (read_32bitLE(0x1c,streamFile)*2)*28/16/channel_count; - } - - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = read_32bitLE(0x8,streamFile); - vgmstream->meta_type = meta_PS2_VSF_TTA; - - /* open the file for reading */ - { - int i; - STREAMFILE * file; - file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (!file) goto fail; - for (i=0;ich[i].streamfile = file; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset=start_offset+ - vgmstream->interleave_block_size*i; - - } - } - - return vgmstream; - - /* clean up anything we may have opened */ -fail: - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/wav2.c b/Frameworks/vgmstream/vgmstream/src/meta/wav2.c new file mode 100644 index 000000000..fdebe2e0c --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/wav2.c @@ -0,0 +1,49 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* WAV2 - from Infogrames North America(?) games [Slave Zero (PC), Outcast (PC)] */ +VGMSTREAM* init_vgmstream_wav2(STREAMFILE* sf) { + VGMSTREAM* vgmstream = NULL; + off_t start_offset; + size_t data_size; + int loop_flag, channels, sample_rate; + + + /* checks */ + if (!is_id32be(0x00, sf, "WAV2")) + return NULL; + if (!check_extensions(sf,"wv2")) + return NULL; + + + // 04: offset? + // 08: pcm samples? + channels = read_u16le(0x0c,sf); + // 0e: bps + sample_rate = read_s32le(0x10,sf); + // 14: average bitrate? + data_size = read_u32le(0x18, sf); + loop_flag = 0; + start_offset = 0x1c; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channels,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->meta_type = meta_WAV2; + vgmstream->sample_rate = sample_rate; + vgmstream->num_samples = ima_bytes_to_samples(data_size, channels); /* also 0x18 */ + + vgmstream->coding_type = coding_DVI_IMA_mono; + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0xFA; + vgmstream->interleave_last_block_size = (data_size % (vgmstream->interleave_block_size * channels)) / channels; + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/wave.c b/Frameworks/vgmstream/vgmstream/src/meta/wave.c index c22d2efa5..8d124c4ea 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/wave.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/wave.c @@ -118,7 +118,7 @@ VGMSTREAM* init_vgmstream_wave(STREAMFILE* sf) { } case 0x03: //IMA (DS uses codec 02 for IMA, common; 3DS: uses 03 but not seen) - vgmstream->coding_type = coding_IMA_int; + vgmstream->coding_type = coding_IMA_mono; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = interleave; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/wave_segmented.c b/Frameworks/vgmstream/vgmstream/src/meta/wave_segmented.c index 8891cdf26..41ab46a6a 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/wave_segmented.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/wave_segmented.c @@ -85,7 +85,7 @@ VGMSTREAM * init_vgmstream_wave_segmented(STREAMFILE *sf) { data->segments[i]->sample_rate = sample_rate; data->segments[i]->meta_type = meta_WAVE; - data->segments[i]->coding_type = coding_IMA_int; + data->segments[i]->coding_type = coding_IMA_mono; data->segments[i]->layout_type = layout_none; data->segments[i]->num_samples = segment_samples; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/wii_ras.c b/Frameworks/vgmstream/vgmstream/src/meta/wii_ras.c deleted file mode 100644 index fe3c0d8bc..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/wii_ras.c +++ /dev/null @@ -1,58 +0,0 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* RAS_ - from Donkey Kong Country Returns (Wii) */ -VGMSTREAM * init_vgmstream_wii_ras(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - - int loop_flag, channel_count; - - /* checks */ - if (!check_extensions(streamFile, "ras")) - goto fail; - - if (read_32bitBE(0x00,streamFile) != 0x5241535F) /* "RAS_" */ - goto fail; - - loop_flag = 0; - if (read_32bitBE(0x30,streamFile) != 0 || - read_32bitBE(0x34,streamFile) != 0 || - read_32bitBE(0x38,streamFile) != 0 || - read_32bitBE(0x3C,streamFile) != 0) { - loop_flag = 1; - } - channel_count = 2; - start_offset = read_32bitBE(0x18,streamFile); - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->sample_rate = read_32bitBE(0x14,streamFile); - vgmstream->meta_type = meta_WII_RAS; - - vgmstream->coding_type = coding_NGC_DSP; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = read_32bitBE(0x20,streamFile); - - vgmstream->num_samples = read_32bitBE(0x1c,streamFile)/channel_count/8*14; - if (loop_flag) { /* loop is block + samples into block */ - vgmstream->loop_start_sample = read_32bitBE(0x30,streamFile)*vgmstream->interleave_block_size/8*14 + - read_32bitBE(0x34,streamFile); - vgmstream->loop_end_sample = read_32bitBE(0x38,streamFile)*vgmstream->interleave_block_size/8*14 + - read_32bitBE(0x3C,streamFile); - } - - dsp_read_coefs_be(vgmstream,streamFile,0x40,0x30); - - - if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) - goto fail; - return vgmstream; - - /* clean up anything we may have opened */ -fail: - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/ws_aud.c b/Frameworks/vgmstream/vgmstream/src/meta/ws_aud.c index f9ae1c03e..2b8d1f5ac 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/ws_aud.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/ws_aud.c @@ -76,7 +76,7 @@ VGMSTREAM* init_vgmstream_ws_aud(STREAMFILE* sf) { break; case 0x63: /* IMA ADPCM [Blade Runner (PC)] */ - vgmstream->coding_type = coding_IMA_int; + vgmstream->coding_type = coding_IMA_mono; break; default: goto fail; diff --git a/Frameworks/vgmstream/vgmstream/src/meta/wv2.c b/Frameworks/vgmstream/vgmstream/src/meta/wv2.c deleted file mode 100644 index c9592ff62..000000000 --- a/Frameworks/vgmstream/vgmstream/src/meta/wv2.c +++ /dev/null @@ -1,43 +0,0 @@ -#include "meta.h" -#include "../coding/coding.h" - -/* WAV2 - from Infrogrames North America games [Slave Zero (PC) (PS2)] */ -VGMSTREAM * init_vgmstream_wv2(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - size_t data_size; - int loop_flag, channel_count; - - - /* checks */ - if ( !check_extensions(streamFile,"wv2") ) - goto fail; - if (read_32bitBE(0x00,streamFile) != 0x57415632) /* "WAV2" */ - goto fail; - - start_offset = 0x1c; - data_size = get_streamfile_size(streamFile) - start_offset; - channel_count = read_8bit(0x0c,streamFile); - loop_flag = 0; - - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - vgmstream->meta_type = meta_WV2; - vgmstream->sample_rate = read_32bitLE(0x10,streamFile); - vgmstream->num_samples = ima_bytes_to_samples(data_size,channel_count); /* also 0x18 */ - - vgmstream->coding_type = coding_DVI_IMA_int; - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0xFA; - - if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/Frameworks/vgmstream/vgmstream/src/meta/xa.c b/Frameworks/vgmstream/vgmstream/src/meta/xa.c index 8dae8951d..badb1c913 100644 --- a/Frameworks/vgmstream/vgmstream/src/meta/xa.c +++ b/Frameworks/vgmstream/vgmstream/src/meta/xa.c @@ -38,10 +38,11 @@ VGMSTREAM* init_vgmstream_xa(STREAMFILE* sf) { * .pxa: Mortal Kombat 4 (PS1) * .grn: Micro Machines (CDi) * .an2: Croc (PS1) movies - * .xai: Quake II (PS1) * .no: Incredible Crisis (PS1) - * (extensionless): bigfiles [Castlevania: Symphony of the Night (PS1)] */ - if (!check_extensions(sf,"xa,str,pxa,grn,an2,,xai")) + * (extensionless): bigfiles [Castlevania: Symphony of the Night (PS1)] + * .xai: Quake II (PS1) + * .ixa: Wild Arms (PS1) */ + if (!check_extensions(sf,"xa,str,pxa,grn,an2,no,,xai,ixa")) return NULL; /* Proper XA comes in raw (BIN 2352 mode2/form2) CD sectors, that contain XA subheaders. diff --git a/Frameworks/vgmstream/vgmstream/src/meta/xwb_konami.c b/Frameworks/vgmstream/vgmstream/src/meta/xwb_konami.c new file mode 100644 index 000000000..aa9b98c1f --- /dev/null +++ b/Frameworks/vgmstream/vgmstream/src/meta/xwb_konami.c @@ -0,0 +1,79 @@ +#include "meta.h" +#include "../util/meta_utils.h" +#include "../coding/coding.h" + + +/* .XWB - from Otomedius (AC) */ +VGMSTREAM* init_vgmstream_xwb_konami(STREAMFILE* sf) { + + /* checks */ + int file_id = read_u16le(0x00, sf); + if (file_id < 0x01 || file_id > 0x40) //observed max is 0x3d + return NULL; + int entries = read_u16le(0x02, sf); + if (entries < 1 || entries > 2) + return NULL; + if (!check_extensions(sf, "xwb")) + return NULL; + + // format doesn't look much like actual XACT .xwb and it was made after many Konami Xbox games, but comes with a fake-ish .xgs too + meta_header_t h = { + .meta = meta_XWB_KONAMI + }; + + h.target_subsong = sf->stream_index; + if (h.target_subsong == 0) + h.target_subsong = 1; + h.total_subsongs = entries; + + uint32_t offset = 0x04; + uint32_t stream_offset = 0x04 + 0x14 * entries; + for (int i = 0; i < entries; i++) { + uint32_t offset = 0x04 + 0x14 * i; + uint32_t chunk_size = read_u32le(offset + 0x00, sf); + // 04: always 0 + h.stream_size = read_u32le(offset + 0x08, sf); + h.loop_start = read_u32le(offset + 0x0c, sf); + h.loop_end = read_u32le(offset + 0x10, sf) + h.loop_start; + + h.stream_offset = stream_offset; + stream_offset += chunk_size; + offset += 0x14; + + if (i + 1 == h.target_subsong) + break; + } + + if (h.stream_size == 0) + return NULL; + + // fmt header (size 0x12) before data + offset = h.stream_offset; + h.stream_offset += 0x12; + + if (read_u16le(offset + 0x00, sf) != 0x0001) + return NULL; + h.channels = read_u16le(offset + 0x02, sf); + h.sample_rate = read_u16le(offset + 0x04, sf); + // 08: avg bitrate + // 0c: block size + // 0e: bps + if (read_u16le(offset + 0x0e, sf) != 16) //bps + return NULL; + // 10: usually 0x5F18 + + h.loop_flag = h.loop_end > 0; + h.num_samples = pcm16_bytes_to_samples(h.stream_size, h.channels); + h.loop_start = pcm16_bytes_to_samples(h.loop_start, h.channels); + h.loop_end = pcm16_bytes_to_samples(h.loop_end, h.channels); + + h.coding = coding_PCM16LE; + h.layout = layout_interleave; + h.interleave = 0x02; + h.has_subsongs = true; + + h.open_stream = true; + h.sf = sf; + + return alloc_metastream(&h); +} diff --git a/Frameworks/vgmstream/vgmstream/src/util/reader_sf.h b/Frameworks/vgmstream/vgmstream/src/util/reader_sf.h index ac6465976..c030e8b2b 100644 --- a/Frameworks/vgmstream/vgmstream/src/util/reader_sf.h +++ b/Frameworks/vgmstream/vgmstream/src/util/reader_sf.h @@ -73,7 +73,7 @@ static inline float read_f32be(off_t offset, STREAMFILE* sf) { return -1; return get_f32be(buf); } -static inline float read_f32le(off_t offset, STREAMFILE* sf) { +static inline float read_f32le(off_t offset, STREAMFILE* sf) { uint8_t buf[4]; if (read_streamfile(buf, offset, sizeof(buf), sf) != sizeof(buf)) @@ -81,6 +81,23 @@ static inline float read_f32le(off_t offset, STREAMFILE* sf) { return get_f32le(buf); } +static inline double read_d64be(off_t offset, STREAMFILE* sf) { + uint8_t buf[8]; + + if (read_streamfile(buf, offset, sizeof(buf), sf) != sizeof(buf)) + return -1; + return get_d64be(buf); +} +#if 0 +static inline double read_d64le(off_t offset, STREAMFILE* sf) { + uint8_t buf[8]; + + if (read_streamfile(buf, offset, sizeof(buf), sf) != sizeof(buf)) + return -1; + return get_d64le(buf); +} +#endif + #if 0 // on GCC, this reader will be correctly optimized out (as long as it's static/inline), would be same as declaring: // uintXX_t (*read_uXX)(off_t,uint8_t*) = be ? get_uXXbe : get_uXXle; diff --git a/Frameworks/vgmstream/vgmstream/src/vgmstream_init.c b/Frameworks/vgmstream/vgmstream/src/vgmstream_init.c index fd514a1c3..122d99fcd 100644 --- a/Frameworks/vgmstream/vgmstream/src/vgmstream_init.c +++ b/Frameworks/vgmstream/vgmstream/src/vgmstream_init.c @@ -114,7 +114,7 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_ubi_jade, init_vgmstream_ubi_jade_container, init_vgmstream_seg, - init_vgmstream_nds_strm_ffta2, + init_vgmstream_riff_ima, init_vgmstream_knon, init_vgmstream_gca, init_vgmstream_spt_spd, @@ -139,7 +139,7 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_swav, init_vgmstream_vsf, init_vgmstream_nds_rrds, - init_vgmstream_ps2_vsf_tta, + init_vgmstream_smss, init_vgmstream_ads_midway, init_vgmstream_ps2_mcg, init_vgmstream_zsd, @@ -182,7 +182,7 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_ngc_rkv, init_vgmstream_dsp_ddsp, init_vgmstream_p3d, - init_vgmstream_ngc_dsp_mpds, + init_vgmstream_mpds, init_vgmstream_dsp_str_ig, init_vgmstream_ea_swvr, init_vgmstream_dsp_xiii, @@ -201,7 +201,7 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_msf, init_vgmstream_sndp, init_vgmstream_sgxd, - init_vgmstream_wii_ras, + init_vgmstream_ras, init_vgmstream_spm, init_vgmstream_ps2_iab, init_vgmstream_vs_str, @@ -225,7 +225,7 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_xnb, init_vgmstream_ubi_ckd, init_vgmstream_ps2_vbk, - init_vgmstream_otm, + init_vgmstream_xwb_konami, init_vgmstream_bcstm, init_vgmstream_idsp_namco, init_vgmstream_kt_g1l, @@ -238,7 +238,7 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_ktss, init_vgmstream_hca, init_vgmstream_svag_snk, - init_vgmstream_ps2_vds_vdm, + init_vgmstream_vds_vdm, init_vgmstream_cxs, init_vgmstream_adx_monster, init_vgmstream_akb, @@ -254,7 +254,7 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_xma, init_vgmstream_sndx, init_vgmstream_ogl, - init_vgmstream_mc3, + init_vgmstream_mpc3, init_vgmstream_ghs, init_vgmstream_aac_triace, init_vgmstream_va3, @@ -352,17 +352,16 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_ahv, init_vgmstream_msv, init_vgmstream_sdf, - init_vgmstream_svg, + init_vgmstream_svgp, init_vgmstream_vai, init_vgmstream_aif_asobo, init_vgmstream_ao, init_vgmstream_apc, - init_vgmstream_wv2, + init_vgmstream_wav2, init_vgmstream_xau_konami, init_vgmstream_derf, init_vgmstream_utk, init_vgmstream_nxa1, - init_vgmstream_adpcm_capcom, init_vgmstream_ue4opus, init_vgmstream_xwma, init_vgmstream_xopus, @@ -408,7 +407,6 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_psf_segmented, init_vgmstream_dsp_itl, init_vgmstream_sch, - init_vgmstream_ima, init_vgmstream_nub, init_vgmstream_nub_wav, init_vgmstream_nub_vag, @@ -517,6 +515,9 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_i3ds, init_vgmstream_sdbs, init_vgmstream_skex, + init_vgmstream_axhd, + init_vgmstream_shaa, + init_vgmstream_undefind, /* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */ init_vgmstream_agsc, @@ -533,6 +534,8 @@ init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_asd_naxat, init_vgmstream_pcm_kceje, init_vgmstream_vs_mh, + init_vgmstream_adpcm_capcom, + init_vgmstream_ima, /* need companion files */ init_vgmstream_pos, init_vgmstream_sli_loops, diff --git a/Frameworks/vgmstream/vgmstream/src/vgmstream_types.h b/Frameworks/vgmstream/vgmstream/src/vgmstream_types.h index 24ade7411..53082275f 100644 --- a/Frameworks/vgmstream/vgmstream/src/vgmstream_types.h +++ b/Frameworks/vgmstream/vgmstream/src/vgmstream_types.h @@ -60,15 +60,15 @@ typedef enum { coding_EA_XAS_V1, /* Electronic Arts EA-XAS ADPCM v1 */ coding_IMA, /* IMA ADPCM (stereo or mono, low nibble first) */ - coding_IMA_int, /* IMA ADPCM (mono/interleave, low nibble first) */ + coding_IMA_mono, /* IMA ADPCM (mono, low nibble first) */ coding_DVI_IMA, /* DVI IMA ADPCM (stereo or mono, high nibble first) */ - coding_DVI_IMA_int, /* DVI IMA ADPCM (mono/interleave, high nibble first) */ + coding_DVI_IMA_mono, /* DVI IMA ADPCM (mono, high nibble first) */ coding_CAMELOT_IMA, coding_SNDS_IMA, /* Heavy Iron Studios .snds IMA ADPCM */ coding_QD_IMA, coding_WV6_IMA, /* Gorilla Systems WV6 4-bit IMA ADPCM */ coding_HV_IMA, /* High Voltage 4-bit IMA ADPCM */ - coding_FFTA2_IMA, /* Final Fantasy Tactics A2 4-bit IMA ADPCM */ + coding_SQEX_IMA, /* Square Enix 4-bit IMA ADPCM */ coding_BLITZ_IMA, /* Blitz Games 4-bit IMA ADPCM */ coding_MS_IMA, /* Microsoft IMA ADPCM */ @@ -110,7 +110,7 @@ typedef enum { coding_LSF, /* lsf ADPCM (Fastlane Street Racing iPhone)*/ coding_MTAF, /* Konami MTAF ADPCM */ coding_MTA2, /* Konami MTA2 ADPCM */ - coding_MC3, /* Paradigm MC3 3-bit ADPCM */ + coding_MPC3, /* Paradigm MPC3 3-bit ADPCM */ coding_FADPCM, /* FMOD FADPCM 4-bit ADPCM */ coding_ASF, /* Argonaut ASF 4-bit ADPCM */ coding_DSA, /* Ocean DSA 4-bit ADPCM */ @@ -379,7 +379,7 @@ typedef enum { meta_RSD, meta_PS2_ASS, meta_SEG, - meta_NDS_STRM_FFTA2, /* Final Fantasy Tactics A2 */ + meta_RIFF_IMA, meta_KNON, meta_ZWDSP, /* Zack and Wiki */ meta_VGS, /* Guitar Hero Encore - Rocks the 80s */ @@ -389,7 +389,7 @@ typedef enum { meta_MUL, meta_SAT_BAKA, /* Crypt Killer */ meta_VSF, - meta_PS2_VSF_TTA, /* Tiny Toon Adventures: Defenders of the Universe */ + meta_SMSS, meta_ADS_MIDWAY, meta_PS2_SPS, /* Ape Escape 2 */ meta_UBI_CKD, /* Ubisoft CKD RIFF header (Rayman Origins Wii) */ @@ -467,7 +467,7 @@ typedef enum { meta_P3D, /* Prototype P3D */ meta_NGC_RKV, /* Legacy of Kain - Blood Omen 2 (GC) */ meta_DSP_DDSP, /* Various (2 dsp files stuck together */ - meta_NGC_DSP_MPDS, /* Big Air Freestyle, Terminator 3 */ + meta_MPDS, meta_DSP_STR_IG, /* Micro Machines, Superman Superman: Shadow of Apokolis */ meta_EA_SWVR, /* Future Cop L.A.P.D., Freekstyle */ meta_DSP_XIII, /* XIII, possibly more (Ubisoft header???) */ @@ -487,7 +487,7 @@ typedef enum { meta_MSF, meta_SNDP, meta_SGXD, /* Sony: Folklore, Genji, Tokyo Jungle (PS3), Brave Story, Kurohyo (PSP) */ - meta_WII_RAS, /* Donkey Kong Country Returns (Wii) */ + meta_RAS, meta_SPM, meta_VGS_PS, meta_PS2_IAB, /* Ueki no Housoku - Taosu ze Robert Juudan!! (PS2) */ @@ -511,7 +511,7 @@ typedef enum { meta_IVAG, meta_2PFS, meta_PS2_VBK, /* Disney's Stitch - Experiment 626 */ - meta_OTM, /* Otomedius (Arcade) */ + meta_XWB_KONAMI, meta_CSTM, /* Nintendo 3DS CSTM (Century Stream) */ meta_FSTM, /* Nintendo Wii U FSTM (caFe? Stream) */ meta_IDSP_NAMCO, @@ -519,9 +519,9 @@ typedef enum { meta_KTSS, /* Koei Tecmo Nintendo Stream (KNS) */ meta_MCA, /* Capcom MCA "MADP" */ meta_ADX_MONSTER, - meta_HCA, /* CRI HCA */ + meta_HCA, meta_SVAG_SNK, - meta_PS2_VDS_VDM, /* Graffiti Kingdom */ + meta_VDS_VDM, meta_FFMPEG, meta_FFMPEG_faulty, meta_CXS, @@ -533,7 +533,7 @@ typedef enum { meta_UBI_RAKI, /* Ubisoft RAKI header (Rayman Legends, Just Dance 2017) */ meta_SNDX, meta_OGL, /* Shin'en Wii/WiiU (Jett Rocket (Wii), FAST Racing NEO (WiiU)) */ - meta_MC3, /* Paradigm games (T3 PS2, MX Rider PS2, MI: Operation Surma PS2) */ + meta_MPC3, meta_GHS, meta_AAC_TRIACE, meta_MTA2, @@ -603,12 +603,12 @@ typedef enum { meta_AHV, /* Headhunter (PS2) */ meta_MSV, meta_SDF, - meta_SVG, /* Hunter - The Reckoning - Wayward (PS2) */ + meta_SVGP, meta_VAI, /* Ratatouille (GC) */ meta_AIF_ASOBO, /* Ratatouille (PC) */ meta_AO, /* Cloudphobia (PC) */ meta_APC, /* MegaRace 3 (PC) */ - meta_WV2, /* Slave Zero (PC) */ + meta_WAV2, meta_XAU_KONAMI, /* Yu-Gi-Oh - The Dawn of Destiny (Xbox) */ meta_DERF, /* Stupid Invaders (PC) */ meta_SADF, @@ -716,7 +716,8 @@ typedef enum { meta_PPHD, meta_XABP, meta_I3DS, - + meta_AXHD, + meta_SHAA /* Nintendo Alarmo SHAA */ } meta_t; #endif diff --git a/Info.plist.template b/Info.plist.template index 555f94bc9..a9145e825 100644 --- a/Info.plist.template +++ b/Info.plist.template @@ -354,6 +354,7 @@ CFBundleTypeExtensions 208 + 2dx 2dx9 3do 3ds @@ -585,6 +586,7 @@ ivag ivb ivs + ixa joe jstm k2sb @@ -709,14 +711,15 @@ nwav nxa nxopus + oga ogg_ ogl + ogs ogv oma omu opu opusx - otm oto ovb p04 @@ -726,7 +729,9 @@ p2a p2bt p3d + paf past + patch3audio pcm pdt phd @@ -739,6 +744,7 @@ psh psn pwb + qwv r rac rad @@ -818,6 +824,8 @@ sgb sgd sgt + shaa + shsa skx slb sli @@ -972,6 +980,7 @@ xau xav xb + xhd xen xma xma2