Updated VGMStream to r1980-95-g551c0787

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
Christopher Snowhill 2025-02-10 14:30:28 -08:00
parent 6e53cebf5c
commit 591f3ceb18
89 changed files with 2422 additions and 1839 deletions

View file

@ -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 = "<group>"; };
830165981F256BD000CA0941 /* ea_schl_fixed.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ea_schl_fixed.c; sourceTree = "<group>"; };
830165991F256BD000CA0941 /* nds_strm_ffta2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nds_strm_ffta2.c; sourceTree = "<group>"; };
830165991F256BD000CA0941 /* riff_ima.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = riff_ima.c; sourceTree = "<group>"; };
83031ECA243C50CB00C3F3E0 /* blocked_ubi_sce.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_ubi_sce.c; sourceTree = "<group>"; };
83031ECB243C50CB00C3F3E0 /* blocked_vid1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_vid1.c; sourceTree = "<group>"; };
83031ECE243C50DE00C3F3E0 /* encrypted.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = encrypted.c; sourceTree = "<group>"; };
@ -1004,7 +1007,7 @@
8319018328F67F2B00B70711 /* bigrp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bigrp.c; sourceTree = "<group>"; };
831BA60E1EAC61A500CF89B0 /* adx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adx.c; sourceTree = "<group>"; };
831BA60F1EAC61A500CF89B0 /* ogl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ogl.c; sourceTree = "<group>"; };
831BA6101EAC61A500CF89B0 /* ps2_vds_vdm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_vds_vdm.c; sourceTree = "<group>"; };
831BA6101EAC61A500CF89B0 /* vds_vdm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vds_vdm.c; sourceTree = "<group>"; };
831BA6111EAC61A500CF89B0 /* sgxd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sgxd.c; sourceTree = "<group>"; };
831BA6121EAC61A500CF89B0 /* sndx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sndx.c; sourceTree = "<group>"; };
831BA6131EAC61A500CF89B0 /* ubi_raki.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ubi_raki.c; sourceTree = "<group>"; };
@ -1124,7 +1127,7 @@
8349A8F61FE6257E00E26435 /* aix_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = aix_streamfile.h; sourceTree = "<group>"; };
8349A8F71FE6257E00E26435 /* ea_eaac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ea_eaac.c; sourceTree = "<group>"; };
8349A8F81FE6257E00E26435 /* bar_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = bar_streamfile.h; sourceTree = "<group>"; };
8349A8F91FE6257E00E26435 /* vsf_tta.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vsf_tta.c; sourceTree = "<group>"; };
8349A8F91FE6257E00E26435 /* smss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = smss.c; sourceTree = "<group>"; };
8349A8FB1FE6257F00E26435 /* omu.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = omu.c; sourceTree = "<group>"; };
8349A8FD1FE6257F00E26435 /* flx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = flx.c; sourceTree = "<group>"; };
8349A8FE1FE6257F00E26435 /* pc_adp_otns.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pc_adp_otns.c; sourceTree = "<group>"; };
@ -1211,7 +1214,7 @@
834F7D662C7093EA003AC386 /* imuse_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = imuse_decoder.c; sourceTree = "<group>"; };
834F7D672C7093EA003AC386 /* l5_555_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = l5_555_decoder.c; sourceTree = "<group>"; };
834F7D682C7093EA003AC386 /* lsf_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lsf_decoder.c; sourceTree = "<group>"; };
834F7D692C7093EA003AC386 /* mc3_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mc3_decoder.c; sourceTree = "<group>"; };
834F7D692C7093EA003AC386 /* mpc3_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpc3_decoder.c; sourceTree = "<group>"; };
834F7D6A2C7093EA003AC386 /* mp4_aac_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp4_aac_decoder.c; sourceTree = "<group>"; };
834F7D6B2C7093EA003AC386 /* mpeg_custom_utils_ahx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpeg_custom_utils_ahx.c; sourceTree = "<group>"; };
834F7D6C2C7093EA003AC386 /* mpeg_custom_utils_ealayer3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpeg_custom_utils_ealayer3.c; sourceTree = "<group>"; };
@ -1340,7 +1343,7 @@
834FE0C9215C79E7000A5D3D /* wv6.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wv6.c; sourceTree = "<group>"; };
834FE0CA215C79E7000A5D3D /* bnk_sony.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bnk_sony.c; sourceTree = "<group>"; };
834FE0CB215C79E8000A5D3D /* wsi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wsi.c; sourceTree = "<group>"; };
834FE0CC215C79E8000A5D3D /* wv2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wv2.c; sourceTree = "<group>"; };
834FE0CC215C79E8000A5D3D /* wav2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wav2.c; sourceTree = "<group>"; };
834FE0CD215C79E8000A5D3D /* derf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = derf.c; sourceTree = "<group>"; };
834FE0CE215C79E8000A5D3D /* vis.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vis.c; sourceTree = "<group>"; };
834FE0CF215C79E8000A5D3D /* adpcm_capcom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adpcm_capcom.c; sourceTree = "<group>"; };
@ -1351,7 +1354,7 @@
834FE0D4215C79E9000A5D3D /* vpk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vpk.c; sourceTree = "<group>"; };
834FE0D5215C79E9000A5D3D /* ps_headerless.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps_headerless.c; sourceTree = "<group>"; };
834FE0D6215C79E9000A5D3D /* sscf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sscf.c; sourceTree = "<group>"; };
834FE0D7215C79EA000A5D3D /* svg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svg.c; sourceTree = "<group>"; };
834FE0D7215C79EA000A5D3D /* svgp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = svgp.c; sourceTree = "<group>"; };
834FE0D8215C79EA000A5D3D /* csmp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = csmp.c; sourceTree = "<group>"; };
834FE0D9215C79EA000A5D3D /* rfrm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rfrm.c; sourceTree = "<group>"; };
834FE0DA215C79EA000A5D3D /* ea_schl_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ea_schl_streamfile.h; sourceTree = "<group>"; };
@ -1455,7 +1458,7 @@
836F6E6918BDC2180095E648 /* nds_rrds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nds_rrds.c; sourceTree = "<group>"; };
836F6E6B18BDC2180095E648 /* nds_strm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nds_strm.c; sourceTree = "<group>"; };
836F6E6D18BDC2180095E648 /* ngc_adpdtk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_adpdtk.c; sourceTree = "<group>"; };
836F6E7218BDC2180095E648 /* ngc_dsp_mpds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_dsp_mpds.c; sourceTree = "<group>"; };
836F6E7218BDC2180095E648 /* mpds.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpds.c; sourceTree = "<group>"; };
836F6E7318BDC2180095E648 /* ngc_dsp_std.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_dsp_std.c; sourceTree = "<group>"; };
836F6E7418BDC2180095E648 /* dsp_kceje.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dsp_kceje.c; sourceTree = "<group>"; };
836F6E7518BDC2180095E648 /* ngc_ffcc_str.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_ffcc_str.c; sourceTree = "<group>"; };
@ -1466,7 +1469,6 @@
836F6E7B18BDC2180095E648 /* ngc_ssm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_ssm.c; sourceTree = "<group>"; };
836F6E7E18BDC2180095E648 /* ymf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ymf.c; sourceTree = "<group>"; };
836F6E8118BDC2180095E648 /* nwa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nwa.c; sourceTree = "<group>"; };
836F6E8318BDC2180095E648 /* otm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = otm.c; sourceTree = "<group>"; };
836F6E8418BDC2180095E648 /* p3d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = p3d.c; sourceTree = "<group>"; };
836F6E8618BDC2180095E648 /* pc_mxst.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pc_mxst.c; sourceTree = "<group>"; };
836F6E8B18BDC2180095E648 /* pona.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pona.c; sourceTree = "<group>"; };
@ -1541,7 +1543,7 @@
836F6EFF18BDC2190095E648 /* vsf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vsf.c; sourceTree = "<group>"; };
836F6F0018BDC2190095E648 /* bns.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bns.c; sourceTree = "<group>"; };
836F6F0118BDC2190095E648 /* mus_krome.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mus_krome.c; sourceTree = "<group>"; };
836F6F0218BDC2190095E648 /* wii_ras.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wii_ras.c; sourceTree = "<group>"; };
836F6F0218BDC2190095E648 /* ras.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ras.c; sourceTree = "<group>"; };
836F6F0418BDC2190095E648 /* wii_sng.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wii_sng.c; sourceTree = "<group>"; };
836F6F0618BDC2190095E648 /* sts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sts.c; sourceTree = "<group>"; };
836F6F0718BDC2190095E648 /* wpd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wpd.c; sourceTree = "<group>"; };
@ -1561,7 +1563,7 @@
836F6F1C18BDC2190095E648 /* vgmstream.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vgmstream.c; sourceTree = "<group>"; };
836F6F1D18BDC2190095E648 /* vgmstream.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vgmstream.h; sourceTree = "<group>"; };
83709DFF1ECBC1A4005C03D3 /* ghs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ghs.c; sourceTree = "<group>"; };
83709E001ECBC1A4005C03D3 /* mc3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mc3.c; sourceTree = "<group>"; };
83709E001ECBC1A4005C03D3 /* mpc3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mpc3.c; sourceTree = "<group>"; };
83709E011ECBC1A4005C03D3 /* mss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mss.c; sourceTree = "<group>"; };
83709E031ECBC1A4005C03D3 /* aac_triace.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aac_triace.c; sourceTree = "<group>"; };
8373341E23F60CDB00DE14DC /* deblock_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = deblock_streamfile.h; sourceTree = "<group>"; };
@ -1671,6 +1673,10 @@
83B46FD42707FB9A00847FC9 /* endianness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = endianness.h; sourceTree = "<group>"; };
83B69B212845A26600D2435A /* bw_mp3_riff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bw_mp3_riff.c; sourceTree = "<group>"; };
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 = "<group>"; };
83B8FE2A2D5AB1F5005854C1 /* axhd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = axhd.c; sourceTree = "<group>"; };
83B8FE2C2D5AB2A5005854C1 /* shaa.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = shaa.c; sourceTree = "<group>"; };
83B8FE2E2D5AB2F4005854C1 /* xwb_konami.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = xwb_konami.c; sourceTree = "<group>"; };
83B8FE302D5AB421005854C1 /* undefind.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = undefind.c; sourceTree = "<group>"; };
83BAFB6B19F45EB3005DAB60 /* bfstm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bfstm.c; sourceTree = "<group>"; };
83C0C75C2AA435C60056AFD8 /* squeak.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = squeak.c; sourceTree = "<group>"; };
83C0C75E2AA436370056AFD8 /* layout_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = layout_utils.c; sourceTree = "<group>"; };
@ -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 */,

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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;

View file

@ -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:

View file

@ -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

View file

@ -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 */

View file

@ -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;
}

View file

@ -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;

View file

@ -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?

View file

@ -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

View file

@ -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

View file

@ -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 */

View file

@ -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) {

View file

@ -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

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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,

View file

@ -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;

View file

@ -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;
}

View file

@ -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:

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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)

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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 */

View file

@ -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;

View file

@ -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;

View file

@ -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 */

View file

@ -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;
{

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -1,285 +1,298 @@
#include "meta.h"
#include "../coding/coding.h"
#include <string.h>
#include <ctype.h>
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:
* ;
* ;
* ; 99999999
* ;
* ;=========================================================================================================
* ; - - = =
* #DSTRACK = 00000000 - 01896330 - 00088270 = "b_manuke" = "b_manuke"
* #DSTRACK = 00000000 - 01918487 - 00132385 = "c_happy" = "c_happy"
*/
for (found = 0, offset = 0; !found && offset<file_size; offset++) {
off_t suboffset;
uint8_t buf[10];
if (read_8bit(offset,sf_loop)!='#') continue;
if (read_streamfile(buf,offset+1,10,sf_loop)!=10) break;
if (memcmp("DSTRACK = ",buf,10)) continue;
if (read_8bit(offset+44,sf_loop)!='\"') continue;
for (suboffset = offset+45;
suboffset < file_size &&
suboffset-offset-45 < length &&
tolower(read_8bit(suboffset,sf_loop)) == tolower(namebase[suboffset-offset-45]);
suboffset++) {
/* skip */
}
if (suboffset-offset-45==length && read_8bit(suboffset,sf_loop)=='\"') { /* tab */
found = 1;
found_off = offset+22; /* loop end */
}
}
if (found) {
char loopstring[9] = {0};
int start_ok = 0, end_ok = 0;
int32_t total_samples = read_32bitLE(0x1c,sf) / read_16bitLE(0x00,sf);
if (read_streamfile((uint8_t*)loopstring,found_off,8,sf_loop)==8)
{
if (!memcmp("99999999",loopstring,8)) {
loop_end_sample = total_samples;
}
else {
loop_end_sample = atol(loopstring);
}
end_ok = 1;
}
if (read_streamfile((uint8_t*)loopstring,found_off+11,8,sf_loop)==8)
{
if (!memcmp("99999999",loopstring,8)) {
/* not ok to start at last sample,
* don't set start_ok flag */
}
else if (!memcmp("00000000",loopstring,8)) {
/* loops from the start aren't really loops */
}
else {
loop_start_sample = atol(loopstring);
start_ok = 1;
}
}
if (start_ok && end_ok) loop_flag = 1;
} /* if found file name in INI */
*p_loop_flag = loop_flag;
*p_loop_start = loop_start_sample;
*p_loop_end = loop_end_sample;
close_streamfile(sf_loop);
return 1;
fail:
close_streamfile(sf_loop);
return 0;
}
#include "meta.h"
#include "../coding/coding.h"
#include <string.h>
#include <ctype.h>
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:
* ;
* ;
* ; 99999999
* ;
* ;=========================================================================================================
* ; - - = =
* #DSTRACK = 00000000 - 01896330 - 00088270 = "b_manuke" = "b_manuke"
* #DSTRACK = 00000000 - 01918487 - 00132385 = "c_happy" = "c_happy"
*/
for (found = 0, offset = 0; !found && offset<file_size; offset++) {
off_t suboffset;
uint8_t buf[10];
if (read_8bit(offset,sf_loop)!='#') continue;
if (read_streamfile(buf,offset+1,10,sf_loop)!=10) break;
if (memcmp("DSTRACK = ",buf,10)) continue;
if (read_8bit(offset+44,sf_loop)!='\"') continue;
for (suboffset = offset+45;
suboffset < file_size &&
suboffset-offset-45 < length &&
tolower(read_8bit(suboffset,sf_loop)) == tolower(namebase[suboffset-offset-45]);
suboffset++) {
/* skip */
}
if (suboffset-offset-45==length && read_8bit(suboffset,sf_loop)=='\"') { /* tab */
found = 1;
found_off = offset+22; /* loop end */
}
}
if (found) {
char loopstring[9] = {0};
int start_ok = 0, end_ok = 0;
int32_t total_samples = read_32bitLE(0x1c,sf) / read_16bitLE(0x00,sf);
if (read_streamfile((uint8_t*)loopstring,found_off,8,sf_loop)==8)
{
if (!memcmp("99999999",loopstring,8)) {
loop_end_sample = total_samples;
}
else {
loop_end_sample = atol(loopstring);
}
end_ok = 1;
}
if (read_streamfile((uint8_t*)loopstring,found_off+11,8,sf_loop)==8)
{
if (!memcmp("99999999",loopstring,8)) {
/* not ok to start at last sample,
* don't set start_ok flag */
}
else if (!memcmp("00000000",loopstring,8)) {
/* loops from the start aren't really loops */
}
else {
loop_start_sample = atol(loopstring);
start_ok = 1;
}
}
if (start_ok && end_ok) loop_flag = 1;
} /* if found file name in INI */
*p_loop_flag = loop_flag;
*p_loop_start = loop_start_sample;
*p_loop_end = loop_end_sample;
close_streamfile(sf_loop);
return 1;
fail:
close_streamfile(sf_loop);
return 0;
}

View file

@ -16,23 +16,24 @@ VGMSTREAM* init_vgmstream_ogg_opus(STREAMFILE* sf) {
/* checks */
if (!is_id32be(0x00,sf, "OggS"))
goto fail;
return NULL;
/* .opus: standard, .lopus: fake extension for plugins
* .ogg: less common, .logg: same
* .bgm: Utawarerumono: Mask of Truth (PC) */
if (!check_extensions(sf, "opus,lopus,ogg,logg,bgm"))
goto fail;
* .bgm: Utawarerumono: Mask of Truth (PC)
* .oga: niconico app (Switch) */
if (!check_extensions(sf, "opus,lopus,ogg,logg,bgm,oga"))
return NULL;
/* see: https://tools.ietf.org/html/rfc7845.html */
start_offset = 0x00;
/* parse 1st page: opus head */
if (!get_ogg_page_size(sf, start_offset, &data_offset, &page_size))
goto fail;
return NULL;
if (!is_id32be(data_offset+0x00,sf, "Opus") ||
!is_id32be(data_offset+0x04,sf, "Head"))
goto fail;
return NULL;
/* 0x01: version 1, fixed */
channel_count = read_u8(data_offset+0x09,sf);
/* 0x0A: skip samples */

View file

@ -161,7 +161,6 @@ fail:
static int _init_vgmstream_ogg_vorbis_tests(STREAMFILE* sf, ogg_vorbis_io_config_data* cfg, ogg_vorbis_meta_info_t* ovmi) {
/* standard */
if (is_id32be(0x00,sf, "OggS")) {
@ -171,9 +170,12 @@ static int _init_vgmstream_ogg_vorbis_tests(STREAMFILE* sf, ogg_vorbis_io_config
* .acm: Planescape Torment Enhanced Edition (PC)
* .sod: Zone 4 (PC)
* .msa: Metal Slug Attack (Mobile)
* .bin/lbin: Devil May Cry 3: Special Edition (PC) */
if (check_extensions(sf,"ogg,logg,adx,rof,acm,sod,msa,bin,lbin"))
return 1;
* .bin/lbin: Devil May Cry 3: Special Edition (PC)
* .oga: Aqua Panic! (PC), Heroes of Annihilated Empires (PC)-pre-demuxed movie audio
* .ogs: Exodus from the Earth (PC)
* .ogv: Tenshi no Hane wo Fumanaide (PC) */
if (check_extensions(sf,"ogg,logg,adx,rof,acm,sod,msa,bin,lbin,oga,ogs,ogv"))
return true;
/* ignore others to allow stuff like .sngw */
}
@ -266,7 +268,7 @@ static int _init_vgmstream_ogg_vorbis_tests(STREAMFILE* sf, ogg_vorbis_io_config
/* encrypted [Adventure Field 4 (PC)] */
if (read_u32be(0x00,sf) == 0x4F756F71) {
ovmi->decryption_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;

View file

@ -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;i<channel_count;i++) {
vgmstream->ch[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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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)

View file

@ -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;
}

View file

@ -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);

View file

@ -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;

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;i<channel_count;i++) {
vgmstream->ch[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;
}

View file

@ -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;
}

View file

@ -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;

View file

@ -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;

View file

@ -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;
}

View file

@ -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;

View file

@ -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;
}

View file

@ -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.

View file

@ -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);
}

View file

@ -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;

View file

@ -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,

View file

@ -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

View file

@ -354,6 +354,7 @@
<key>CFBundleTypeExtensions</key>
<array>
<string>208</string>
<string>2dx</string>
<string>2dx9</string>
<string>3do</string>
<string>3ds</string>
@ -585,6 +586,7 @@
<string>ivag</string>
<string>ivb</string>
<string>ivs</string>
<string>ixa</string>
<string>joe</string>
<string>jstm</string>
<string>k2sb</string>
@ -709,14 +711,15 @@
<string>nwav</string>
<string>nxa</string>
<string>nxopus</string>
<string>oga</string>
<string>ogg_</string>
<string>ogl</string>
<string>ogs</string>
<string>ogv</string>
<string>oma</string>
<string>omu</string>
<string>opu</string>
<string>opusx</string>
<string>otm</string>
<string>oto</string>
<string>ovb</string>
<string>p04</string>
@ -726,7 +729,9 @@
<string>p2a</string>
<string>p2bt</string>
<string>p3d</string>
<string>paf</string>
<string>past</string>
<string>patch3audio</string>
<string>pcm</string>
<string>pdt</string>
<string>phd</string>
@ -739,6 +744,7 @@
<string>psh</string>
<string>psn</string>
<string>pwb</string>
<string>qwv</string>
<string>r</string>
<string>rac</string>
<string>rad</string>
@ -818,6 +824,8 @@
<string>sgb</string>
<string>sgd</string>
<string>sgt</string>
<string>shaa</string>
<string>shsa</string>
<string>skx</string>
<string>slb</string>
<string>sli</string>
@ -972,6 +980,7 @@
<string>xau</string>
<string>xav</string>
<string>xb</string>
<string>xhd</string>
<string>xen</string>
<string>xma</string>
<string>xma2</string>