Updated VGMStream to r1980-95-g551c0787
Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
b1deca3fcf
commit
ce91cc5d6c
89 changed files with 2422 additions and 1839 deletions
|
@ -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 */,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
195
Frameworks/vgmstream/vgmstream/src/base/api_libsf_cache.c
Normal file
195
Frameworks/vgmstream/vgmstream/src/base/api_libsf_cache.c
Normal 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;
|
||||
}
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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?
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
|
@ -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 */
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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:
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
118
Frameworks/vgmstream/vgmstream/src/meta/axhd.c
Normal file
118
Frameworks/vgmstream/vgmstream/src/meta/axhd.c
Normal 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;
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
||||
|
|
46
Frameworks/vgmstream/vgmstream/src/meta/mpc3.c
Normal file
46
Frameworks/vgmstream/vgmstream/src/meta/mpc3.c
Normal 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;
|
||||
}
|
78
Frameworks/vgmstream/vgmstream/src/meta/mpds.c
Normal file
78
Frameworks/vgmstream/vgmstream/src/meta/mpds.c
Normal 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;
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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 */
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
{
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
||||
|
|
|
@ -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:
|
||||
* ; ■BGMの登録:DirectSound
|
||||
* ;(※必要ない場合は登録しないで下さい。)
|
||||
* ; 終了位置の設定が 99999999 なら最後まで演奏します。
|
||||
* ; ※設定値はサンプル数で指定して下さい。(旧システムではバイト指定でしたので注意してください。)
|
||||
* ;=========================================================================================================
|
||||
* ; 開始位置 - 終了位置 - リピート = ファイル名 = 登録名
|
||||
* #DSTRACK = 00000000 - 01896330 - 00088270 = "b_manuke" = "b_manuke"
|
||||
* #DSTRACK = 00000000 - 01918487 - 00132385 = "c_happy" = "c_happy"
|
||||
*/
|
||||
|
||||
for (found = 0, offset = 0; !found && offset<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:
|
||||
* ; ■BGMの登録:DirectSound
|
||||
* ;(※必要ない場合は登録しないで下さい。)
|
||||
* ; 終了位置の設定が 99999999 なら最後まで演奏します。
|
||||
* ; ※設定値はサンプル数で指定して下さい。(旧システムではバイト指定でしたので注意してください。)
|
||||
* ;=========================================================================================================
|
||||
* ; 開始位置 - 終了位置 - リピート = ファイル名 = 登録名
|
||||
* #DSTRACK = 00000000 - 01896330 - 00088270 = "b_manuke" = "b_manuke"
|
||||
* #DSTRACK = 00000000 - 01918487 - 00132385 = "c_happy" = "c_happy"
|
||||
*/
|
||||
|
||||
for (found = 0, offset = 0; !found && offset<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;
|
||||
}
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
|
55
Frameworks/vgmstream/vgmstream/src/meta/ras.c
Normal file
55
Frameworks/vgmstream/vgmstream/src/meta/ras.c
Normal 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;
|
||||
}
|
|
@ -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)
|
||||
|
|
48
Frameworks/vgmstream/vgmstream/src/meta/riff_ima.c
Normal file
48
Frameworks/vgmstream/vgmstream/src/meta/riff_ima.c
Normal 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;
|
||||
}
|
|
@ -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);
|
||||
|
|
|
@ -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;
|
||||
|
|
66
Frameworks/vgmstream/vgmstream/src/meta/shaa.c
Normal file
66
Frameworks/vgmstream/vgmstream/src/meta/shaa.c
Normal 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;
|
||||
}
|
41
Frameworks/vgmstream/vgmstream/src/meta/smss.c
Normal file
41
Frameworks/vgmstream/vgmstream/src/meta/smss.c
Normal 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);
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
47
Frameworks/vgmstream/vgmstream/src/meta/svgp.c
Normal file
47
Frameworks/vgmstream/vgmstream/src/meta/svgp.c
Normal 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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
57
Frameworks/vgmstream/vgmstream/src/meta/undefind.c
Normal file
57
Frameworks/vgmstream/vgmstream/src/meta/undefind.c
Normal 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;
|
||||
}
|
49
Frameworks/vgmstream/vgmstream/src/meta/vds_vdm.c
Normal file
49
Frameworks/vgmstream/vgmstream/src/meta/vds_vdm.c
Normal 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;
|
||||
}
|
|
@ -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;
|
||||
}
|
49
Frameworks/vgmstream/vgmstream/src/meta/wav2.c
Normal file
49
Frameworks/vgmstream/vgmstream/src/meta/wav2.c
Normal 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;
|
||||
}
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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.
|
||||
|
|
79
Frameworks/vgmstream/vgmstream/src/meta/xwb_konami.c
Normal file
79
Frameworks/vgmstream/vgmstream/src/meta/xwb_konami.c
Normal 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);
|
||||
}
|
|
@ -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;
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in a new issue