VGMStream: Updated libvgmstream code base
Updated VGMStream to r1980-242-gfccbb05f Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
f96cfea2d3
commit
4232fb3949
88 changed files with 5949 additions and 5749 deletions
|
@ -24,7 +24,7 @@
|
|||
8306B0A420984552000302D4 /* segmented.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B0892098454D000302D4 /* segmented.c */; };
|
||||
8306B0A520984552000302D4 /* blocked_ea_wve_au00.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B08A2098454D000302D4 /* blocked_ea_wve_au00.c */; };
|
||||
8306B0A620984552000302D4 /* blocked_ea_wve_ad10.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B08B2098454D000302D4 /* blocked_ea_wve_ad10.c */; };
|
||||
8306B0A720984552000302D4 /* blocked_xvas.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B08C2098454D000302D4 /* blocked_xvas.c */; };
|
||||
8306B0A720984552000302D4 /* blocked_vas_kceo.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B08C2098454D000302D4 /* blocked_vas_kceo.c */; };
|
||||
8306B0A820984552000302D4 /* blocked_ps2_iab.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B08D2098454D000302D4 /* blocked_ps2_iab.c */; };
|
||||
8306B0A920984552000302D4 /* blocked_adm.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B08E2098454E000302D4 /* blocked_adm.c */; };
|
||||
8306B0AA20984552000302D4 /* blocked_sthd.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B08F2098454E000302D4 /* blocked_sthd.c */; };
|
||||
|
@ -41,7 +41,7 @@
|
|||
8306B0B820984552000302D4 /* blocked_ws_aud.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B09D20984551000302D4 /* blocked_ws_aud.c */; };
|
||||
8306B0B920984552000302D4 /* blocked_matx.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B09E20984551000302D4 /* blocked_matx.c */; };
|
||||
8306B0BA20984552000302D4 /* blocked_wsi.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B09F20984551000302D4 /* blocked_wsi.c */; };
|
||||
8306B0BB20984552000302D4 /* blocked_gsb.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B0A020984551000302D4 /* blocked_gsb.c */; };
|
||||
8306B0BB20984552000302D4 /* blocked_gsnd.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B0A020984551000302D4 /* blocked_gsnd.c */; };
|
||||
8306B0BC20984552000302D4 /* blocked_vs.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B0A120984551000302D4 /* blocked_vs.c */; };
|
||||
8306B0D820984590000302D4 /* ea_eaac_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8306B0BD2098458B000302D4 /* ea_eaac_streamfile.h */; };
|
||||
8306B0D920984590000302D4 /* ngc_str_cauldron.c in Sources */ = {isa = PBXBuildFile; fileRef = 8306B0BE2098458C000302D4 /* ngc_str_cauldron.c */; };
|
||||
|
@ -185,6 +185,8 @@
|
|||
8346D97C25BF838C00D1A8B0 /* mjb_mjh.c in Sources */ = {isa = PBXBuildFile; fileRef = 8346D97725BF838C00D1A8B0 /* mjb_mjh.c */; };
|
||||
8346D97D25BF838C00D1A8B0 /* compresswave.c in Sources */ = {isa = PBXBuildFile; fileRef = 8346D97825BF838C00D1A8B0 /* compresswave.c */; };
|
||||
834845782D27F2E9000E4928 /* decode_state.h in Headers */ = {isa = PBXBuildFile; fileRef = 834845772D27F2E9000E4928 /* decode_state.h */; };
|
||||
834960FC2DB5FD430019C8CA /* ssp.c in Sources */ = {isa = PBXBuildFile; fileRef = 834960FB2DB5FD430019C8CA /* ssp.c */; };
|
||||
834960FE2DB5FEF90019C8CA /* ualaw_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 834960FD2DB5FEF90019C8CA /* ualaw_decoder.c */; };
|
||||
8349A8E81FE6253900E26435 /* blocked_dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8E21FE6253800E26435 /* blocked_dec.c */; };
|
||||
8349A8E91FE6253900E26435 /* blocked_ea_1snh.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8E31FE6253800E26435 /* blocked_ea_1snh.c */; };
|
||||
8349A8EA1FE6253900E26435 /* blocked_ea_schl.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8E41FE6253800E26435 /* blocked_ea_schl.c */; };
|
||||
|
@ -192,7 +194,7 @@
|
|||
8349A8ED1FE6253900E26435 /* blocked_ea_sns.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8E71FE6253900E26435 /* blocked_ea_sns.c */; };
|
||||
8349A9071FE6258200E26435 /* dec.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8EE1FE6257C00E26435 /* dec.c */; };
|
||||
8349A9081FE6258200E26435 /* ezw.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8EF1FE6257C00E26435 /* ezw.c */; };
|
||||
8349A9091FE6258200E26435 /* pc_ast.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8F01FE6257C00E26435 /* pc_ast.c */; };
|
||||
8349A9091FE6258200E26435 /* astl.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8F01FE6257C00E26435 /* astl.c */; };
|
||||
8349A90A1FE6258200E26435 /* sab.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8F11FE6257D00E26435 /* sab.c */; };
|
||||
8349A90B1FE6258200E26435 /* pcm_kceje.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8F21FE6257D00E26435 /* pcm_kceje.c */; };
|
||||
8349A90D1FE6258200E26435 /* ubi_sb.c in Sources */ = {isa = PBXBuildFile; fileRef = 8349A8F41FE6257D00E26435 /* ubi_sb.c */; };
|
||||
|
@ -229,7 +231,7 @@
|
|||
834F7D192C708701003AC386 /* awc_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 834F7D172C708701003AC386 /* awc_streamfile.h */; };
|
||||
834F7D1C2C708719003AC386 /* cipher_xxtea.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D1A2C708719003AC386 /* cipher_xxtea.c */; };
|
||||
834F7D1D2C708719003AC386 /* cipher_xxtea.h in Headers */ = {isa = PBXBuildFile; fileRef = 834F7D1B2C708719003AC386 /* cipher_xxtea.h */; };
|
||||
834F7D252C7088B9003AC386 /* cbx.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D242C7088B9003AC386 /* cbx.c */; };
|
||||
834F7D252C7088B9003AC386 /* chatterbox.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D242C7088B9003AC386 /* chatterbox.c */; };
|
||||
834F7D292C708A2F003AC386 /* vas_rockstar.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D282C708A2F003AC386 /* vas_rockstar.c */; };
|
||||
834F7D2B2C708A5B003AC386 /* blocked_vas.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D2A2C708A5B003AC386 /* blocked_vas.c */; };
|
||||
834F7D2F2C708D32003AC386 /* rage_aud_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 834F7D2E2C708D31003AC386 /* rage_aud_streamfile.h */; };
|
||||
|
@ -420,7 +422,7 @@
|
|||
834FE0F8215C79ED000A5D3D /* adpcm_capcom.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0CF215C79E8000A5D3D /* adpcm_capcom.c */; };
|
||||
834FE0F9215C79ED000A5D3D /* wavebatch.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D0215C79E8000A5D3D /* wavebatch.c */; };
|
||||
834FE0FA215C79ED000A5D3D /* nus3bank.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D1215C79E9000A5D3D /* nus3bank.c */; };
|
||||
834FE0FB215C79ED000A5D3D /* xau_konami.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D2215C79E9000A5D3D /* xau_konami.c */; };
|
||||
834FE0FB215C79ED000A5D3D /* sfxb.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D2215C79E9000A5D3D /* sfxb.c */; };
|
||||
834FE0FC215C79ED000A5D3D /* vai.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D3215C79E9000A5D3D /* vai.c */; };
|
||||
834FE0FD215C79ED000A5D3D /* vpk.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D4215C79E9000A5D3D /* vpk.c */; };
|
||||
834FE0FE215C79ED000A5D3D /* ps_headerless.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0D5215C79E9000A5D3D /* ps_headerless.c */; };
|
||||
|
@ -499,7 +501,7 @@
|
|||
836F6F7F18BDC2190095E648 /* dmsg_segh.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E4318BDC2180095E648 /* dmsg_segh.c */; };
|
||||
836F6F8218BDC2190095E648 /* ea_schl.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E4618BDC2180095E648 /* ea_schl.c */; };
|
||||
836F6F8518BDC2190095E648 /* exakt_sc.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E4918BDC2180095E648 /* exakt_sc.c */; };
|
||||
836F6F8618BDC2190095E648 /* excitebots.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E4A18BDC2180095E648 /* excitebots.c */; };
|
||||
836F6F8618BDC2190095E648 /* sfx0_monster.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E4A18BDC2180095E648 /* sfx0_monster.c */; };
|
||||
836F6F8818BDC2190095E648 /* fsb.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E4C18BDC2180095E648 /* fsb.c */; };
|
||||
836F6F8918BDC2190095E648 /* gca.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E4D18BDC2180095E648 /* gca.c */; };
|
||||
836F6F8A18BDC2190095E648 /* gcsw.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E4E18BDC2180095E648 /* gcsw.c */; };
|
||||
|
@ -531,9 +533,9 @@
|
|||
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 */; };
|
||||
836F6FB318BDC2190095E648 /* ngc_lps.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7718BDC2180095E648 /* ngc_lps.c */; };
|
||||
836F6FB418BDC2190095E648 /* ngc_nst_dsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7818BDC2180095E648 /* ngc_nst_dsp.c */; };
|
||||
836F6FB118BDC2190095E648 /* str_sqex.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7518BDC2180095E648 /* str_sqex.c */; };
|
||||
836F6FB318BDC2190095E648 /* lps.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7718BDC2180095E648 /* lps.c */; };
|
||||
836F6FB418BDC2190095E648 /* nst_monster.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7818BDC2180095E648 /* nst_monster.c */; };
|
||||
836F6FB518BDC2190095E648 /* ngc_pdt.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7918BDC2180095E648 /* ngc_pdt.c */; };
|
||||
836F6FB618BDC2190095E648 /* ngc_sck_dsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7A18BDC2180095E648 /* ngc_sck_dsp.c */; };
|
||||
836F6FB718BDC2190095E648 /* ngc_ssm.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E7B18BDC2180095E648 /* ngc_ssm.c */; };
|
||||
|
@ -557,13 +559,12 @@
|
|||
836F6FD918BDC2190095E648 /* mcg.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9D18BDC2180095E648 /* mcg.c */; };
|
||||
836F6FDA18BDC2190095E648 /* hgc1.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9E18BDC2180095E648 /* hgc1.c */; };
|
||||
836F6FDB18BDC2190095E648 /* ps2_hsf.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9F18BDC2180095E648 /* ps2_hsf.c */; };
|
||||
836F6FDC18BDC2190095E648 /* ps2_iab.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EA018BDC2180095E648 /* ps2_iab.c */; };
|
||||
836F6FDC18BDC2190095E648 /* iab.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EA018BDC2180095E648 /* iab.c */; };
|
||||
836F6FDE18BDC2190095E648 /* ild.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EA218BDC2180095E648 /* ild.c */; };
|
||||
836F6FE018BDC2190095E648 /* ps2_joe.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EA418BDC2180095E648 /* ps2_joe.c */; };
|
||||
836F6FE218BDC2190095E648 /* vig_kces.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EA618BDC2180095E648 /* vig_kces.c */; };
|
||||
836F6FE818BDC2190095E648 /* mic_koei.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EAC18BDC2180095E648 /* mic_koei.c */; };
|
||||
836F6FEE18BDC2190095E648 /* p2bt_move_visa.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EB218BDC2180095E648 /* p2bt_move_visa.c */; };
|
||||
836F6FF218BDC2190095E648 /* ps2_rnd.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EB618BDC2180095E648 /* ps2_rnd.c */; };
|
||||
836F6FF418BDC2190095E648 /* rws_80d.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EB818BDC2180095E648 /* rws_80d.c */; };
|
||||
836F6FF618BDC2190095E648 /* ster.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EBA18BDC2180095E648 /* ster.c */; };
|
||||
836F6FF718BDC2190095E648 /* sl3.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EBB18BDC2180095E648 /* sl3.c */; };
|
||||
|
@ -575,7 +576,7 @@
|
|||
836F700418BDC2190095E648 /* vas_kceo.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EC818BDC2190095E648 /* vas_kceo.c */; };
|
||||
836F700518BDC2190095E648 /* ps2_vbk.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EC918BDC2190095E648 /* ps2_vbk.c */; };
|
||||
836F700618BDC2190095E648 /* vgs_ps.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ECA18BDC2190095E648 /* vgs_ps.c */; };
|
||||
836F700718BDC2190095E648 /* ps2_vgv.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ECB18BDC2190095E648 /* ps2_vgv.c */; };
|
||||
836F700718BDC2190095E648 /* vgv.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ECB18BDC2190095E648 /* vgv.c */; };
|
||||
836F700818BDC2190095E648 /* ps2_vms.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ECC18BDC2190095E648 /* ps2_vms.c */; };
|
||||
836F700918BDC2190095E648 /* voi.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ECD18BDC2190095E648 /* voi.c */; };
|
||||
836F700B18BDC2190095E648 /* ps2_wad.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ECF18BDC2190095E648 /* ps2_wad.c */; };
|
||||
|
@ -612,7 +613,7 @@
|
|||
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 /* ras.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0218BDC2190095E648 /* ras.c */; };
|
||||
836F704018BDC2190095E648 /* wii_sng.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0418BDC2190095E648 /* wii_sng.c */; };
|
||||
836F704018BDC2190095E648 /* song_monster.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0418BDC2190095E648 /* song_monster.c */; };
|
||||
836F704218BDC2190095E648 /* sts.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0618BDC2190095E648 /* sts.c */; };
|
||||
836F704318BDC2190095E648 /* wpd.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0718BDC2190095E648 /* wpd.c */; };
|
||||
836F704418BDC2190095E648 /* ws_aud.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F0818BDC2190095E648 /* ws_aud.c */; };
|
||||
|
@ -632,7 +633,7 @@
|
|||
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 /* mpc3.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E001ECBC1A4005C03D3 /* mpc3.c */; };
|
||||
83709E071ECBC1A4005C03D3 /* mss.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E011ECBC1A4005C03D3 /* mss.c */; };
|
||||
83709E071ECBC1A4005C03D3 /* mcss.c in Sources */ = {isa = PBXBuildFile; fileRef = 83709E011ECBC1A4005C03D3 /* mcss.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 */; };
|
||||
8373342723F60CDC00DE14DC /* lrmd_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8373341F23F60CDB00DE14DC /* lrmd_streamfile.h */; };
|
||||
|
@ -832,7 +833,7 @@
|
|||
83E22FC12772FD06000015EE /* libbz2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = 83E22FBD2772FD06000015EE /* libbz2.tbd */; };
|
||||
83E22FC32772FD16000015EE /* AudioToolbox.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83E22FC22772FD16000015EE /* AudioToolbox.framework */; };
|
||||
83E7FD6525EF2B2400683FD2 /* tac.c in Sources */ = {isa = PBXBuildFile; fileRef = 83E7FD6425EF2B2400683FD2 /* tac.c */; };
|
||||
83EDE5D81A70951A005F5D84 /* mca.c in Sources */ = {isa = PBXBuildFile; fileRef = 83EDE5D61A70951A005F5D84 /* mca.c */; };
|
||||
83EDE5D81A70951A005F5D84 /* madp.c in Sources */ = {isa = PBXBuildFile; fileRef = 83EDE5D61A70951A005F5D84 /* madp.c */; };
|
||||
83EDE5D91A70951A005F5D84 /* btsnd.c in Sources */ = {isa = PBXBuildFile; fileRef = 83EDE5D71A70951A005F5D84 /* btsnd.c */; };
|
||||
83EED5D3203A8BC7008BEB45 /* ea_swvr.c in Sources */ = {isa = PBXBuildFile; fileRef = 83EED5D1203A8BC7008BEB45 /* ea_swvr.c */; };
|
||||
83EED5D4203A8BC7008BEB45 /* aus.c in Sources */ = {isa = PBXBuildFile; fileRef = 83EED5D2203A8BC7008BEB45 /* aus.c */; };
|
||||
|
@ -977,7 +978,7 @@
|
|||
8306B0892098454D000302D4 /* segmented.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = segmented.c; sourceTree = "<group>"; };
|
||||
8306B08A2098454D000302D4 /* blocked_ea_wve_au00.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_ea_wve_au00.c; sourceTree = "<group>"; };
|
||||
8306B08B2098454D000302D4 /* blocked_ea_wve_ad10.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_ea_wve_ad10.c; sourceTree = "<group>"; };
|
||||
8306B08C2098454D000302D4 /* blocked_xvas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_xvas.c; sourceTree = "<group>"; };
|
||||
8306B08C2098454D000302D4 /* blocked_vas_kceo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_vas_kceo.c; sourceTree = "<group>"; };
|
||||
8306B08D2098454D000302D4 /* blocked_ps2_iab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_ps2_iab.c; sourceTree = "<group>"; };
|
||||
8306B08E2098454E000302D4 /* blocked_adm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_adm.c; sourceTree = "<group>"; };
|
||||
8306B08F2098454E000302D4 /* blocked_sthd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_sthd.c; sourceTree = "<group>"; };
|
||||
|
@ -994,7 +995,7 @@
|
|||
8306B09D20984551000302D4 /* blocked_ws_aud.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_ws_aud.c; sourceTree = "<group>"; };
|
||||
8306B09E20984551000302D4 /* blocked_matx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_matx.c; sourceTree = "<group>"; };
|
||||
8306B09F20984551000302D4 /* blocked_wsi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_wsi.c; sourceTree = "<group>"; };
|
||||
8306B0A020984551000302D4 /* blocked_gsb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_gsb.c; sourceTree = "<group>"; };
|
||||
8306B0A020984551000302D4 /* blocked_gsnd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_gsnd.c; sourceTree = "<group>"; };
|
||||
8306B0A120984551000302D4 /* blocked_vs.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_vs.c; sourceTree = "<group>"; };
|
||||
8306B0BD2098458B000302D4 /* ea_eaac_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = ea_eaac_streamfile.h; sourceTree = "<group>"; };
|
||||
8306B0BE2098458C000302D4 /* ngc_str_cauldron.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_str_cauldron.c; sourceTree = "<group>"; };
|
||||
|
@ -1138,6 +1139,8 @@
|
|||
8346D97725BF838C00D1A8B0 /* mjb_mjh.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mjb_mjh.c; sourceTree = "<group>"; };
|
||||
8346D97825BF838C00D1A8B0 /* compresswave.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compresswave.c; sourceTree = "<group>"; };
|
||||
834845772D27F2E9000E4928 /* decode_state.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = decode_state.h; sourceTree = "<group>"; };
|
||||
834960FB2DB5FD430019C8CA /* ssp.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ssp.c; sourceTree = "<group>"; };
|
||||
834960FD2DB5FEF90019C8CA /* ualaw_decoder.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ualaw_decoder.c; sourceTree = "<group>"; };
|
||||
8349A8E21FE6253800E26435 /* blocked_dec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_dec.c; sourceTree = "<group>"; };
|
||||
8349A8E31FE6253800E26435 /* blocked_ea_1snh.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_ea_1snh.c; sourceTree = "<group>"; };
|
||||
8349A8E41FE6253800E26435 /* blocked_ea_schl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_ea_schl.c; sourceTree = "<group>"; };
|
||||
|
@ -1145,7 +1148,7 @@
|
|||
8349A8E71FE6253900E26435 /* blocked_ea_sns.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_ea_sns.c; sourceTree = "<group>"; };
|
||||
8349A8EE1FE6257C00E26435 /* dec.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dec.c; sourceTree = "<group>"; };
|
||||
8349A8EF1FE6257C00E26435 /* ezw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ezw.c; sourceTree = "<group>"; };
|
||||
8349A8F01FE6257C00E26435 /* pc_ast.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pc_ast.c; sourceTree = "<group>"; };
|
||||
8349A8F01FE6257C00E26435 /* astl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = astl.c; sourceTree = "<group>"; };
|
||||
8349A8F11FE6257D00E26435 /* sab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sab.c; sourceTree = "<group>"; };
|
||||
8349A8F21FE6257D00E26435 /* pcm_kceje.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = pcm_kceje.c; sourceTree = "<group>"; };
|
||||
8349A8F41FE6257D00E26435 /* ubi_sb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ubi_sb.c; sourceTree = "<group>"; };
|
||||
|
@ -1182,7 +1185,7 @@
|
|||
834F7D172C708701003AC386 /* awc_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = awc_streamfile.h; sourceTree = "<group>"; };
|
||||
834F7D1A2C708719003AC386 /* cipher_xxtea.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cipher_xxtea.c; sourceTree = "<group>"; };
|
||||
834F7D1B2C708719003AC386 /* cipher_xxtea.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cipher_xxtea.h; sourceTree = "<group>"; };
|
||||
834F7D242C7088B9003AC386 /* cbx.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cbx.c; sourceTree = "<group>"; };
|
||||
834F7D242C7088B9003AC386 /* chatterbox.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = chatterbox.c; sourceTree = "<group>"; };
|
||||
834F7D282C708A2F003AC386 /* vas_rockstar.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vas_rockstar.c; sourceTree = "<group>"; };
|
||||
834F7D2A2C708A5B003AC386 /* blocked_vas.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_vas.c; sourceTree = "<group>"; };
|
||||
834F7D2E2C708D31003AC386 /* rage_aud_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = rage_aud_streamfile.h; sourceTree = "<group>"; };
|
||||
|
@ -1372,7 +1375,7 @@
|
|||
834FE0CF215C79E8000A5D3D /* adpcm_capcom.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adpcm_capcom.c; sourceTree = "<group>"; };
|
||||
834FE0D0215C79E8000A5D3D /* wavebatch.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wavebatch.c; sourceTree = "<group>"; };
|
||||
834FE0D1215C79E9000A5D3D /* nus3bank.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nus3bank.c; sourceTree = "<group>"; };
|
||||
834FE0D2215C79E9000A5D3D /* xau_konami.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xau_konami.c; sourceTree = "<group>"; };
|
||||
834FE0D2215C79E9000A5D3D /* sfxb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sfxb.c; sourceTree = "<group>"; };
|
||||
834FE0D3215C79E9000A5D3D /* vai.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vai.c; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
|
@ -1452,7 +1455,7 @@
|
|||
836F6E4318BDC2180095E648 /* dmsg_segh.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dmsg_segh.c; sourceTree = "<group>"; };
|
||||
836F6E4618BDC2180095E648 /* ea_schl.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ea_schl.c; sourceTree = "<group>"; };
|
||||
836F6E4918BDC2180095E648 /* exakt_sc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = exakt_sc.c; sourceTree = "<group>"; };
|
||||
836F6E4A18BDC2180095E648 /* excitebots.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = excitebots.c; sourceTree = "<group>"; };
|
||||
836F6E4A18BDC2180095E648 /* sfx0_monster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sfx0_monster.c; sourceTree = "<group>"; };
|
||||
836F6E4C18BDC2180095E648 /* fsb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = fsb.c; sourceTree = "<group>"; };
|
||||
836F6E4D18BDC2180095E648 /* gca.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gca.c; sourceTree = "<group>"; };
|
||||
836F6E4E18BDC2180095E648 /* gcsw.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gcsw.c; sourceTree = "<group>"; };
|
||||
|
@ -1484,9 +1487,9 @@
|
|||
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>"; };
|
||||
836F6E7718BDC2180095E648 /* ngc_lps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_lps.c; sourceTree = "<group>"; };
|
||||
836F6E7818BDC2180095E648 /* ngc_nst_dsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_nst_dsp.c; sourceTree = "<group>"; };
|
||||
836F6E7518BDC2180095E648 /* str_sqex.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = str_sqex.c; sourceTree = "<group>"; };
|
||||
836F6E7718BDC2180095E648 /* lps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lps.c; sourceTree = "<group>"; };
|
||||
836F6E7818BDC2180095E648 /* nst_monster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = nst_monster.c; sourceTree = "<group>"; };
|
||||
836F6E7918BDC2180095E648 /* ngc_pdt.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_pdt.c; sourceTree = "<group>"; };
|
||||
836F6E7A18BDC2180095E648 /* ngc_sck_dsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_sck_dsp.c; sourceTree = "<group>"; };
|
||||
836F6E7B18BDC2180095E648 /* ngc_ssm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ngc_ssm.c; sourceTree = "<group>"; };
|
||||
|
@ -1510,13 +1513,12 @@
|
|||
836F6E9D18BDC2180095E648 /* mcg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mcg.c; sourceTree = "<group>"; };
|
||||
836F6E9E18BDC2180095E648 /* hgc1.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hgc1.c; sourceTree = "<group>"; };
|
||||
836F6E9F18BDC2180095E648 /* ps2_hsf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_hsf.c; sourceTree = "<group>"; };
|
||||
836F6EA018BDC2180095E648 /* ps2_iab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_iab.c; sourceTree = "<group>"; };
|
||||
836F6EA018BDC2180095E648 /* iab.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = iab.c; sourceTree = "<group>"; };
|
||||
836F6EA218BDC2180095E648 /* ild.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ild.c; sourceTree = "<group>"; };
|
||||
836F6EA418BDC2180095E648 /* ps2_joe.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_joe.c; sourceTree = "<group>"; };
|
||||
836F6EA618BDC2180095E648 /* vig_kces.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vig_kces.c; sourceTree = "<group>"; };
|
||||
836F6EAC18BDC2180095E648 /* mic_koei.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mic_koei.c; sourceTree = "<group>"; };
|
||||
836F6EB218BDC2180095E648 /* p2bt_move_visa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = p2bt_move_visa.c; sourceTree = "<group>"; };
|
||||
836F6EB618BDC2180095E648 /* ps2_rnd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_rnd.c; sourceTree = "<group>"; };
|
||||
836F6EB818BDC2180095E648 /* rws_80d.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = rws_80d.c; sourceTree = "<group>"; };
|
||||
836F6EBA18BDC2180095E648 /* ster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ster.c; sourceTree = "<group>"; };
|
||||
836F6EBB18BDC2180095E648 /* sl3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sl3.c; sourceTree = "<group>"; };
|
||||
|
@ -1528,7 +1530,7 @@
|
|||
836F6EC818BDC2190095E648 /* vas_kceo.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vas_kceo.c; sourceTree = "<group>"; };
|
||||
836F6EC918BDC2190095E648 /* ps2_vbk.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_vbk.c; sourceTree = "<group>"; };
|
||||
836F6ECA18BDC2190095E648 /* vgs_ps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vgs_ps.c; sourceTree = "<group>"; };
|
||||
836F6ECB18BDC2190095E648 /* ps2_vgv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_vgv.c; sourceTree = "<group>"; };
|
||||
836F6ECB18BDC2190095E648 /* vgv.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vgv.c; sourceTree = "<group>"; };
|
||||
836F6ECC18BDC2190095E648 /* ps2_vms.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_vms.c; sourceTree = "<group>"; };
|
||||
836F6ECD18BDC2190095E648 /* voi.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = voi.c; sourceTree = "<group>"; };
|
||||
836F6ECF18BDC2190095E648 /* ps2_wad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_wad.c; sourceTree = "<group>"; };
|
||||
|
@ -1565,7 +1567,7 @@
|
|||
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 /* 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>"; };
|
||||
836F6F0418BDC2190095E648 /* song_monster.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = song_monster.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>"; };
|
||||
836F6F0818BDC2190095E648 /* ws_aud.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ws_aud.c; sourceTree = "<group>"; };
|
||||
|
@ -1585,7 +1587,7 @@
|
|||
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 /* 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>"; };
|
||||
83709E011ECBC1A4005C03D3 /* mcss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mcss.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>"; };
|
||||
8373341F23F60CDB00DE14DC /* lrmd_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = lrmd_streamfile.h; sourceTree = "<group>"; };
|
||||
|
@ -1785,7 +1787,7 @@
|
|||
83E22FBD2772FD06000015EE /* libbz2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbz2.tbd; path = usr/lib/libbz2.tbd; sourceTree = SDKROOT; };
|
||||
83E22FC22772FD16000015EE /* AudioToolbox.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = AudioToolbox.framework; path = System/Library/Frameworks/AudioToolbox.framework; sourceTree = SDKROOT; };
|
||||
83E7FD6425EF2B2400683FD2 /* tac.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tac.c; sourceTree = "<group>"; };
|
||||
83EDE5D61A70951A005F5D84 /* mca.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mca.c; sourceTree = "<group>"; };
|
||||
83EDE5D61A70951A005F5D84 /* madp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = madp.c; sourceTree = "<group>"; };
|
||||
83EDE5D71A70951A005F5D84 /* btsnd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = btsnd.c; sourceTree = "<group>"; };
|
||||
83EED5D1203A8BC7008BEB45 /* ea_swvr.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ea_swvr.c; sourceTree = "<group>"; };
|
||||
83EED5D2203A8BC7008BEB45 /* aus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = aus.c; sourceTree = "<group>"; };
|
||||
|
@ -2048,6 +2050,7 @@
|
|||
834F7D8D2C7093EA003AC386 /* tac_decoder.c */,
|
||||
834F7D8E2C7093EA003AC386 /* tantalus_decoder.c */,
|
||||
834F7D8F2C7093EA003AC386 /* tgcadpcm_decoder.c */,
|
||||
834960FD2DB5FEF90019C8CA /* ualaw_decoder.c */,
|
||||
834F7D902C7093EA003AC386 /* ubi_adpcm_decoder.c */,
|
||||
83B73C342D8FEFFD00A57F08 /* ubi_mpeg_decoder.c */,
|
||||
834F7D912C7093EA003AC386 /* vadpcm_decoder.c */,
|
||||
|
@ -2236,6 +2239,7 @@
|
|||
836F6DFF18BDC2180095E648 /* layout */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
836F6E0418BDC2180095E648 /* blocked.c */,
|
||||
8306B08E2098454E000302D4 /* blocked_adm.c */,
|
||||
8306B0882098454C000302D4 /* blocked_ast.c */,
|
||||
83AA5D1B1F6E2F7F0020821C /* blocked_awc.c */,
|
||||
|
@ -2248,7 +2252,7 @@
|
|||
8306B08B2098454D000302D4 /* blocked_ea_wve_ad10.c */,
|
||||
8306B08A2098454D000302D4 /* blocked_ea_wve_au00.c */,
|
||||
8306B0932098454F000302D4 /* blocked_filp.c */,
|
||||
8306B0A020984551000302D4 /* blocked_gsb.c */,
|
||||
8306B0A020984551000302D4 /* blocked_gsnd.c */,
|
||||
8342469520C4D23D00926E48 /* blocked_h4m.c */,
|
||||
8306B0962098454F000302D4 /* blocked_halpst.c */,
|
||||
8306B09B20984550000302D4 /* blocked_hwas.c */,
|
||||
|
@ -2264,19 +2268,18 @@
|
|||
836F46AD28208735005B9B87 /* blocked_tt_ad.c */,
|
||||
83031ECA243C50CB00C3F3E0 /* blocked_ubi_sce.c */,
|
||||
834F7D2A2C708A5B003AC386 /* blocked_vas.c */,
|
||||
8306B08C2098454D000302D4 /* blocked_vas_kceo.c */,
|
||||
83AA5D1A1F6E2F7F0020821C /* blocked_vgs.c */,
|
||||
83031ECB243C50CB00C3F3E0 /* blocked_vid1.c */,
|
||||
8306B0A120984551000302D4 /* blocked_vs.c */,
|
||||
832BF80321E050DC006F50F1 /* blocked_vs_square.c */,
|
||||
832BF80421E050DC006F50F1 /* blocked_vs_str.c */,
|
||||
8306B0A120984551000302D4 /* blocked_vs.c */,
|
||||
8306B09D20984551000302D4 /* blocked_ws_aud.c */,
|
||||
8306B09F20984551000302D4 /* blocked_wsi.c */,
|
||||
834FE0BC215C79A8000A5D3D /* blocked_xa_aiff.c */,
|
||||
8306B0912098454E000302D4 /* blocked_xa.c */,
|
||||
834FE0BC215C79A8000A5D3D /* blocked_xa_aiff.c */,
|
||||
83A21F7A201D895B000F04B9 /* blocked_xvag.c */,
|
||||
8306B08C2098454D000302D4 /* blocked_xvas.c */,
|
||||
83A8BADE256679E3000F5F3F /* blocked_xwav.c */,
|
||||
836F6E0418BDC2180095E648 /* blocked.c */,
|
||||
834FE0BD215C79A9000A5D3D /* flat.c */,
|
||||
836F6E0D18BDC2180095E648 /* interleave.c */,
|
||||
8306B0902098454E000302D4 /* layered.c */,
|
||||
|
@ -2332,6 +2335,7 @@
|
|||
835B9B8B2730BF2C00F87EE3 /* ast_mmv.c */,
|
||||
835B9B8A2730BF2C00F87EE3 /* ast_mv.c */,
|
||||
83AB8C741E8072A100086084 /* astb.c */,
|
||||
8349A8F01FE6257C00E26435 /* astl.c */,
|
||||
8306B0D520984590000302D4 /* atsl.c */,
|
||||
83EED5D2203A8BC7008BEB45 /* aus.c */,
|
||||
83A16D2722D2ADE700B90C4C /* awb.c */,
|
||||
|
@ -2365,7 +2369,7 @@
|
|||
83B69B212845A26600D2435A /* bw_mp3_riff.c */,
|
||||
835C883122CC17BD001B4B3F /* bwav.c */,
|
||||
8306B0CF2098458F000302D4 /* caf.c */,
|
||||
834F7D242C7088B9003AC386 /* cbx.c */,
|
||||
834F7D242C7088B9003AC386 /* chatterbox.c */,
|
||||
834FE0E8215C79EC000A5D3D /* ck.c */,
|
||||
8346D97825BF838C00D1A8B0 /* compresswave.c */,
|
||||
83A8BAE425667AA7000F5F3F /* cpk.c */,
|
||||
|
@ -2415,7 +2419,6 @@
|
|||
832FC36E278FAE3E0056A860 /* encrypted_mc161_streamfile.h */,
|
||||
836F46B02820874D005B9B87 /* esf.c */,
|
||||
836F6E4918BDC2180095E648 /* exakt_sc.c */,
|
||||
836F6E4A18BDC2180095E648 /* excitebots.c */,
|
||||
83AF2CC626226BA400538240 /* exst.c */,
|
||||
8349A8EF1FE6257C00E26435 /* ezw.c */,
|
||||
832BF80821E05135006F50F1 /* fag.c */,
|
||||
|
@ -2455,6 +2458,7 @@
|
|||
836F6E5318BDC2180095E648 /* his.c */,
|
||||
836F6E9818BDC2180095E648 /* hxd.c */,
|
||||
83CBF5402D4631F300AA2D75 /* i3ds.c */,
|
||||
836F6EA018BDC2180095E648 /* iab.c */,
|
||||
834FE0E0215C79EB000A5D3D /* idsp_ie.c */,
|
||||
8346D97425BF838C00D1A8B0 /* idtech.c */,
|
||||
8346D97525BF838C00D1A8B0 /* idtech_streamfile.h */,
|
||||
|
@ -2487,13 +2491,15 @@
|
|||
83A8BAE125667AA7000F5F3F /* lp_ap_lep_streamfile.h */,
|
||||
839C3D22270D49FF00E13653 /* lpcm_fb.c */,
|
||||
835B9B8E2730BF2D00F87EE3 /* lpcm_shade.c */,
|
||||
836F6E7718BDC2180095E648 /* lps.c */,
|
||||
8373342223F60CDB00DE14DC /* lrmd.c */,
|
||||
8373341F23F60CDB00DE14DC /* lrmd_streamfile.h */,
|
||||
836F6E5A18BDC2180095E648 /* lsf.c */,
|
||||
83EDE5D61A70951A005F5D84 /* madp.c */,
|
||||
836F6E5C18BDC2180095E648 /* mattel_hyperscan.c */,
|
||||
836F6E5D18BDC2180095E648 /* maxis_xa.c */,
|
||||
83EDE5D61A70951A005F5D84 /* mca.c */,
|
||||
836F6E9D18BDC2180095E648 /* mcg.c */,
|
||||
83709E011ECBC1A4005C03D3 /* mcss.c */,
|
||||
836F6E5E18BDC2180095E648 /* meta.h */,
|
||||
834FE0DE215C79EB000A5D3D /* mib_mih.c */,
|
||||
836F6EAC18BDC2180095E648 /* mic_koei.c */,
|
||||
|
@ -2512,7 +2518,6 @@
|
|||
832BF81721E0514A006F50F1 /* msf_banpresto.c */,
|
||||
83C7280D22BC893D00678B4A /* msf_konami.c */,
|
||||
832BF80B21E05148006F50F1 /* msf_tamasoft.c */,
|
||||
83709E011ECBC1A4005C03D3 /* mss.c */,
|
||||
834FE0E7215C79EC000A5D3D /* msv.c */,
|
||||
83C727FF22BC893900678B4A /* mta2.c */,
|
||||
83C7280E22BC893D00678B4A /* mta2_streamfile.h */,
|
||||
|
@ -2535,14 +2540,12 @@
|
|||
836F6E6D18BDC2180095E648 /* ngc_adpdtk.c */,
|
||||
834F7D322C70932C003AC386 /* ngc_dsp_asura.c */,
|
||||
836F6E7318BDC2180095E648 /* ngc_dsp_std.c */,
|
||||
836F6E7518BDC2180095E648 /* ngc_ffcc_str.c */,
|
||||
836F6E7718BDC2180095E648 /* ngc_lps.c */,
|
||||
836F6E7818BDC2180095E648 /* ngc_nst_dsp.c */,
|
||||
836F6E7918BDC2180095E648 /* ngc_pdt.c */,
|
||||
836F6E7A18BDC2180095E648 /* ngc_sck_dsp.c */,
|
||||
836F6E7B18BDC2180095E648 /* ngc_ssm.c */,
|
||||
8306B0BE2098458C000302D4 /* ngc_str_cauldron.c */,
|
||||
83C727FC22BC893900678B4A /* npsf.c */,
|
||||
836F6E7818BDC2180095E648 /* nst_monster.c */,
|
||||
837CEAE223487F2A00E62A4A /* nub.c */,
|
||||
832BF81B21E0514B006F50F1 /* nus3audio.c */,
|
||||
834FE0D1215C79E9000A5D3D /* nus3bank.c */,
|
||||
|
@ -2565,7 +2568,6 @@
|
|||
836F6E8418BDC2180095E648 /* p3d.c */,
|
||||
831BA6171EAC61A500CF89B0 /* pasx.c */,
|
||||
8349A8FE1FE6257F00E26435 /* pc_adp_otns.c */,
|
||||
8349A8F01FE6257C00E26435 /* pc_ast.c */,
|
||||
836F6E8618BDC2180095E648 /* pc_mxst.c */,
|
||||
8349A8F21FE6257D00E26435 /* pcm_kceje.c */,
|
||||
8306B0D12098458F000302D4 /* pcm_sre.c */,
|
||||
|
@ -2582,14 +2584,11 @@
|
|||
836F6E9418BDC2180095E648 /* ps2_b1s.c */,
|
||||
836F6E9618BDC2180095E648 /* ps2_bmdx.c */,
|
||||
836F6E9F18BDC2180095E648 /* ps2_hsf.c */,
|
||||
836F6EA018BDC2180095E648 /* ps2_iab.c */,
|
||||
836F6EA418BDC2180095E648 /* ps2_joe.c */,
|
||||
836F6EB618BDC2180095E648 /* ps2_rnd.c */,
|
||||
836F6EBD18BDC2180095E648 /* ps2_snd.c */,
|
||||
836F6EBF18BDC2190095E648 /* ps2_sps.c */,
|
||||
836F6EC518BDC2190095E648 /* ps2_tec.c */,
|
||||
836F6EC918BDC2190095E648 /* ps2_vbk.c */,
|
||||
836F6ECB18BDC2190095E648 /* ps2_vgv.c */,
|
||||
836F6ECC18BDC2190095E648 /* ps2_vms.c */,
|
||||
836F6ECF18BDC2190095E648 /* ps2_wad.c */,
|
||||
8315868326F586E200803A3A /* psb.c */,
|
||||
|
@ -2640,6 +2639,8 @@
|
|||
83C7280822BC893C00678B4A /* sfh.c */,
|
||||
83C7280422BC893B00678B4A /* sfh_streamfile.h */,
|
||||
836F6EF118BDC2190095E648 /* sfl.c */,
|
||||
836F6E4A18BDC2180095E648 /* sfx0_monster.c */,
|
||||
834FE0D2215C79E9000A5D3D /* sfxb.c */,
|
||||
831BA6111EAC61A500CF89B0 /* sgxd.c */,
|
||||
83B8FE2C2D5AB2A5005854C1 /* shaa.c */,
|
||||
83AA7F782519C042004C5298 /* silence.c */,
|
||||
|
@ -2657,6 +2658,7 @@
|
|||
83C0C7622AA436B90056AFD8 /* snds.c */,
|
||||
831BA6121EAC61A500CF89B0 /* sndx.c */,
|
||||
835559FB2869102B005FE93A /* sndz.c */,
|
||||
836F6F0418BDC2190095E648 /* song_monster.c */,
|
||||
836F6EBE18BDC2190095E648 /* spm.c */,
|
||||
83A21F82201D8981000F04B9 /* sps_n1.c */,
|
||||
836F6E6718BDC2180095E648 /* spsd.c */,
|
||||
|
@ -2668,6 +2670,7 @@
|
|||
834FE0D6215C79E9000A5D3D /* sscf.c */,
|
||||
8396BE792935FC2F00CD0580 /* sscf_encrypted.h */,
|
||||
8396BE782935FC2F00CD0580 /* sscf_encrypted.c */,
|
||||
834960FB2DB5FD430019C8CA /* ssp.c */,
|
||||
8339B322280FDF250076F74B /* sspf.c */,
|
||||
8317C24826982CC1007DD0B8 /* sspr.c */,
|
||||
836F6EBA18BDC2180095E648 /* ster.c */,
|
||||
|
@ -2675,6 +2678,7 @@
|
|||
83AA5D231F6E2F9C0020821C /* stma.c */,
|
||||
836F6E4118BDC2180095E648 /* str_sega.c */,
|
||||
836F6EF718BDC2190095E648 /* str_snds.c */,
|
||||
836F6E7518BDC2180095E648 /* str_sqex.c */,
|
||||
834FE0C2215C79E6000A5D3D /* str_wav.c */,
|
||||
834F7CFF2C7085EA003AC386 /* str_wav_streamfile.h */,
|
||||
83C7280722BC893B00678B4A /* strm_abylight.c */,
|
||||
|
@ -2720,6 +2724,7 @@
|
|||
831BA6101EAC61A500CF89B0 /* vds_vdm.c */,
|
||||
836F6EFD18BDC2190095E648 /* vgs.c */,
|
||||
836F6ECA18BDC2190095E648 /* vgs_ps.c */,
|
||||
836F6ECB18BDC2190095E648 /* vgv.c */,
|
||||
83031ED7243C510400C3F3E0 /* vid1.c */,
|
||||
836F6EA618BDC2180095E648 /* vig_kces.c */,
|
||||
834FE0CE215C79E8000A5D3D /* vis.c */,
|
||||
|
@ -2740,7 +2745,6 @@
|
|||
834FE0D0215C79E8000A5D3D /* wavebatch.c */,
|
||||
836F6ED018BDC2190095E648 /* wb.c */,
|
||||
83349715275DD2AC00302E21 /* wbk.c */,
|
||||
836F6F0418BDC2190095E648 /* wii_sng.c */,
|
||||
836F6F0718BDC2190095E648 /* wpd.c */,
|
||||
836F6F0818BDC2190095E648 /* ws_aud.c */,
|
||||
834FE0CB215C79E8000A5D3D /* wsi.c */,
|
||||
|
@ -2754,7 +2758,6 @@
|
|||
83FBB16E2A4FF4EC00CD0580 /* xa2_acclaim.c */,
|
||||
83CBF53C2D46318F00AA2D75 /* xabp.c */,
|
||||
833A7A2D1ED11961003EC53E /* xau.c */,
|
||||
834FE0D2215C79E9000A5D3D /* xau_konami.c */,
|
||||
837CEAE423487F2A00E62A4A /* xavs.c */,
|
||||
837CEAEE23487F2C00E62A4A /* xavs_streamfile.h */,
|
||||
836F6F0C18BDC2190095E648 /* xbox_ims.c */,
|
||||
|
@ -3390,14 +3393,13 @@
|
|||
834F7E072C7093EA003AC386 /* vorbis_custom_utils_sk.c in Sources */,
|
||||
836F6FD818BDC2190095E648 /* gbts.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 */,
|
||||
83CBF53B2D46314900AA2D75 /* pphd.c in Sources */,
|
||||
834F7DCF2C7093EA003AC386 /* hca_decoder.c in Sources */,
|
||||
83CBF5352D46309100AA2D75 /* ka1a_dec.c in Sources */,
|
||||
83CBF53D2D46318F00AA2D75 /* xabp.c in Sources */,
|
||||
834FE0FB215C79ED000A5D3D /* xau_konami.c in Sources */,
|
||||
834FE0FB215C79ED000A5D3D /* sfxb.c in Sources */,
|
||||
83F0AA6121E2028C004BBC04 /* vsv.c in Sources */,
|
||||
8351F32F2212B57000A606E4 /* dsf.c in Sources */,
|
||||
837CEAF723487F2C00E62A4A /* nub.c in Sources */,
|
||||
|
@ -3437,7 +3439,7 @@
|
|||
836F6F8A18BDC2190095E648 /* gcsw.c in Sources */,
|
||||
836F6F9C18BDC2190095E648 /* mp4.c in Sources */,
|
||||
834FE101215C79ED000A5D3D /* csmp.c in Sources */,
|
||||
8306B0A720984552000302D4 /* blocked_xvas.c in Sources */,
|
||||
8306B0A720984552000302D4 /* blocked_vas_kceo.c in Sources */,
|
||||
8349A9101FE6258200E26435 /* ea_eaac.c in Sources */,
|
||||
835B9B912730BF2D00F87EE3 /* lopu_fb.c in Sources */,
|
||||
8319017C28F67EE100B70711 /* miniz.c in Sources */,
|
||||
|
@ -3457,12 +3459,14 @@
|
|||
839FBFFC26C354E70016A78A /* mp4_faac.c in Sources */,
|
||||
832BF81D21E0514B006F50F1 /* msf_tamasoft.c in Sources */,
|
||||
83C0C75D2AA435C60056AFD8 /* squeak.c in Sources */,
|
||||
83709E071ECBC1A4005C03D3 /* mss.c in Sources */,
|
||||
83709E071ECBC1A4005C03D3 /* mcss.c in Sources */,
|
||||
836F6F8F18BDC2190095E648 /* his.c in Sources */,
|
||||
834960FE2DB5FEF90019C8CA /* ualaw_decoder.c in Sources */,
|
||||
834FE0E9215C79ED000A5D3D /* ao.c in Sources */,
|
||||
834F7D112C7085EB003AC386 /* ea_eaac_tmx.c in Sources */,
|
||||
836F6FE218BDC2190095E648 /* vig_kces.c in Sources */,
|
||||
836F6FCB18BDC2190095E648 /* ads.c in Sources */,
|
||||
834960FC2DB5FD430019C8CA /* ssp.c in Sources */,
|
||||
834FE108215C79ED000A5D3D /* hd3_bd3.c in Sources */,
|
||||
834F7DF42C7093EA003AC386 /* SASSC_decoder.c in Sources */,
|
||||
83C7281C22BC893D00678B4A /* sfh.c in Sources */,
|
||||
|
@ -3488,7 +3492,7 @@
|
|||
836F6F7318BDC2190095E648 /* bcstm.c in Sources */,
|
||||
834F7DBB2C7093EA003AC386 /* dsa_decoder.c in Sources */,
|
||||
83299FD11E7660C7003A3242 /* dsp_adx.c in Sources */,
|
||||
836F704018BDC2190095E648 /* wii_sng.c in Sources */,
|
||||
836F704018BDC2190095E648 /* song_monster.c in Sources */,
|
||||
834F7E0A2C7093EA003AC386 /* vorbis_custom_utils.c in Sources */,
|
||||
834F7DFD2C7093EA003AC386 /* tgcadpcm_decoder.c in Sources */,
|
||||
834FE10D215C79ED000A5D3D /* vag.c in Sources */,
|
||||
|
@ -3570,14 +3574,14 @@
|
|||
836F6F8818BDC2190095E648 /* fsb.c in Sources */,
|
||||
83F2CCE525A5B41600F46FA8 /* acx.c in Sources */,
|
||||
83FC176D23AC58D100E1025F /* xma_ue3.c in Sources */,
|
||||
836F6FB318BDC2190095E648 /* ngc_lps.c in Sources */,
|
||||
836F6FB318BDC2190095E648 /* lps.c in Sources */,
|
||||
836F6FC018BDC2190095E648 /* p3d.c in Sources */,
|
||||
834F7CFD2C70834D003AC386 /* nxof.c in Sources */,
|
||||
836F6FC718BDC2190095E648 /* pona.c in Sources */,
|
||||
8306B0B820984552000302D4 /* blocked_ws_aud.c in Sources */,
|
||||
83B73C5C2D8FF37700A57F08 /* codec_info.c in Sources */,
|
||||
83B73C5D2D8FF37700A57F08 /* api_libsf_cache.c in Sources */,
|
||||
834F7D252C7088B9003AC386 /* cbx.c in Sources */,
|
||||
834F7D252C7088B9003AC386 /* chatterbox.c in Sources */,
|
||||
83AA5D241F6E2F9C0020821C /* awc.c in Sources */,
|
||||
8349A8E91FE6253900E26435 /* blocked_ea_1snh.c in Sources */,
|
||||
8306B0E620984590000302D4 /* msb_msh.c in Sources */,
|
||||
|
@ -3616,7 +3620,7 @@
|
|||
836F6F4A18BDC2190095E648 /* interleave.c in Sources */,
|
||||
834F7EDC2C70A786003AC386 /* streamfile_buffer.c in Sources */,
|
||||
83C7281F22BC893D00678B4A /* xwma_konami.c in Sources */,
|
||||
83EDE5D81A70951A005F5D84 /* mca.c in Sources */,
|
||||
83EDE5D81A70951A005F5D84 /* madp.c in Sources */,
|
||||
834FE0F3215C79ED000A5D3D /* bnk_sony.c in Sources */,
|
||||
8306B0AE20984552000302D4 /* blocked_filp.c in Sources */,
|
||||
831BA61B1EAC61A500CF89B0 /* sgxd.c in Sources */,
|
||||
|
@ -3631,7 +3635,7 @@
|
|||
83C7281B22BC893D00678B4A /* strm_abylight.c in Sources */,
|
||||
834D3A6E19F47C98001C54F6 /* g1l.c in Sources */,
|
||||
832BF82A21E0514B006F50F1 /* vs_square.c in Sources */,
|
||||
8349A9091FE6258200E26435 /* pc_ast.c in Sources */,
|
||||
8349A9091FE6258200E26435 /* astl.c in Sources */,
|
||||
83B73C442D8FF15700A57F08 /* mio_erisacontext.c in Sources */,
|
||||
83B73C452D8FF15700A57F08 /* mio_erisafile.c in Sources */,
|
||||
83B73C462D8FF15700A57F08 /* mio_erisamatrix.c in Sources */,
|
||||
|
@ -3662,7 +3666,7 @@
|
|||
834FE0FE215C79ED000A5D3D /* ps_headerless.c in Sources */,
|
||||
834F7ED72C70A786003AC386 /* render.c in Sources */,
|
||||
83AF2CCB26226BA500538240 /* ogv_3rdeye.c in Sources */,
|
||||
8306B0BB20984552000302D4 /* blocked_gsb.c in Sources */,
|
||||
8306B0BB20984552000302D4 /* blocked_gsnd.c in Sources */,
|
||||
83031ECC243C50CC00C3F3E0 /* blocked_ubi_sce.c in Sources */,
|
||||
8315868A26F586F900803A3A /* m2_psb.c in Sources */,
|
||||
836F6FB018BDC2190095E648 /* dsp_kceje.c in Sources */,
|
||||
|
@ -3677,7 +3681,7 @@
|
|||
834FE0BE215C79A9000A5D3D /* blocked_xa_aiff.c in Sources */,
|
||||
835B9B902730BF2D00F87EE3 /* ast_mmv.c in Sources */,
|
||||
836F702A18BDC2190095E648 /* sd9.c in Sources */,
|
||||
836F6FB418BDC2190095E648 /* ngc_nst_dsp.c in Sources */,
|
||||
836F6FB418BDC2190095E648 /* nst_monster.c in Sources */,
|
||||
834F7DB92C7093EA003AC386 /* derf_decoder.c in Sources */,
|
||||
83B73C4B2D8FF19800A57F08 /* mio.c in Sources */,
|
||||
836F6FDB18BDC2190095E648 /* ps2_hsf.c in Sources */,
|
||||
|
@ -3708,7 +3712,7 @@
|
|||
83B73C492D8FF17900A57F08 /* mio_decoder.c in Sources */,
|
||||
834F7DBC2C7093EA003AC386 /* ea_mt_decoder.c in Sources */,
|
||||
837CEAFA23487F2C00E62A4A /* xa_04sw.c in Sources */,
|
||||
836F6F8618BDC2190095E648 /* excitebots.c in Sources */,
|
||||
836F6F8618BDC2190095E648 /* sfx0_monster.c in Sources */,
|
||||
8385D4E6245174C700FF8E67 /* diva.c in Sources */,
|
||||
836F6FF418BDC2190095E648 /* rws_80d.c in Sources */,
|
||||
834FE100215C79ED000A5D3D /* svgp.c in Sources */,
|
||||
|
@ -3737,7 +3741,7 @@
|
|||
83852B0B2680247900378854 /* rxws.c in Sources */,
|
||||
831BA6181EAC61A500CF89B0 /* adx.c in Sources */,
|
||||
832BF82321E0514B006F50F1 /* imc.c in Sources */,
|
||||
836F6FB118BDC2190095E648 /* ngc_ffcc_str.c in Sources */,
|
||||
836F6FB118BDC2190095E648 /* str_sqex.c in Sources */,
|
||||
8306B0B620984552000302D4 /* blocked_hwas.c in Sources */,
|
||||
836F6FC218BDC2190095E648 /* pc_mxst.c in Sources */,
|
||||
8375737621F950ED00F01AF5 /* gin.c in Sources */,
|
||||
|
@ -3772,7 +3776,7 @@
|
|||
83D2007D248DDB770048BD24 /* kat.c in Sources */,
|
||||
836F6F7618BDC2190095E648 /* brstm.c in Sources */,
|
||||
834F7E0E2C7093EA003AC386 /* xmd_decoder.c in Sources */,
|
||||
836F700718BDC2190095E648 /* ps2_vgv.c in Sources */,
|
||||
836F700718BDC2190095E648 /* vgv.c in Sources */,
|
||||
834F7D0A2C7085EB003AC386 /* gwb_gwd.c in Sources */,
|
||||
836F704F18BDC2190095E648 /* xwb.c in Sources */,
|
||||
834F7DE52C7093EA003AC386 /* ngc_dtk_decoder.c in Sources */,
|
||||
|
@ -3783,7 +3787,7 @@
|
|||
8306B0AA20984552000302D4 /* blocked_sthd.c in Sources */,
|
||||
834F7D292C708A2F003AC386 /* vas_rockstar.c in Sources */,
|
||||
836F6FA918BDC2190095E648 /* ngc_adpdtk.c in Sources */,
|
||||
836F6FDC18BDC2190095E648 /* ps2_iab.c in Sources */,
|
||||
836F6FDC18BDC2190095E648 /* iab.c in Sources */,
|
||||
83C7282122BC893D00678B4A /* msf_konami.c in Sources */,
|
||||
833E82F72A2858EF00CD0580 /* reader.c in Sources */,
|
||||
83B69B222845A26600D2435A /* bw_mp3_riff.c in Sources */,
|
||||
|
|
|
@ -118,18 +118,24 @@ libvgmstream_sfmt_t api_get_output_sample_type(libvgmstream_priv_t* priv) {
|
|||
switch(format) {
|
||||
case SFMT_S16: return LIBVGMSTREAM_SFMT_PCM16;
|
||||
case SFMT_FLT: return LIBVGMSTREAM_SFMT_FLOAT;
|
||||
case SFMT_F32: return LIBVGMSTREAM_SFMT_FLOAT; //shouldn't happen?
|
||||
case SFMT_S32: return LIBVGMSTREAM_SFMT_PCM32;
|
||||
case SFMT_O24: return LIBVGMSTREAM_SFMT_PCM24;
|
||||
|
||||
// internal use only, shouldn't happen (misconfigured, see prepare_mixing)
|
||||
case SFMT_S24:
|
||||
case SFMT_F16:
|
||||
default:
|
||||
return 0x00; //???
|
||||
return 0x00;
|
||||
}
|
||||
}
|
||||
|
||||
int api_get_sample_size(libvgmstream_sfmt_t sample_format) {
|
||||
switch(sample_format) {
|
||||
//case LIBVGMSTREAM_SFMT_PCM24:
|
||||
//case LIBVGMSTREAM_SFMT_PCM32:
|
||||
case LIBVGMSTREAM_SFMT_FLOAT:
|
||||
case LIBVGMSTREAM_SFMT_PCM32:
|
||||
return 0x04;
|
||||
case LIBVGMSTREAM_SFMT_PCM24:
|
||||
return 0x03;
|
||||
case LIBVGMSTREAM_SFMT_PCM16:
|
||||
default:
|
||||
return 0x02;
|
||||
|
|
|
@ -52,6 +52,8 @@ static void prepare_mixing(libvgmstream_priv_t* priv) {
|
|||
switch(cfg->force_sfmt) {
|
||||
case LIBVGMSTREAM_SFMT_PCM16: force_sfmt = SFMT_S16; break;
|
||||
case LIBVGMSTREAM_SFMT_FLOAT: force_sfmt = SFMT_FLT; break;
|
||||
case LIBVGMSTREAM_SFMT_PCM24: force_sfmt = SFMT_O24; break;
|
||||
case LIBVGMSTREAM_SFMT_PCM32: force_sfmt = SFMT_S32; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
@ -60,10 +62,10 @@ static void prepare_mixing(libvgmstream_priv_t* priv) {
|
|||
else {
|
||||
// internal force, swap certain internal bufs into standard output
|
||||
sfmt_t force_sfmt = SFMT_NONE;
|
||||
|
||||
sfmt_t input_sfmt = mixing_get_input_sample_type(priv->vgmstream);
|
||||
switch(input_sfmt) {
|
||||
case SFMT_F32: force_sfmt = SFMT_FLT; break;
|
||||
case SFMT_F16: force_sfmt = SFMT_FLT; break;
|
||||
case SFMT_S24: force_sfmt = SFMT_O24; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
|
|
|
@ -5,6 +5,7 @@ extern const codec_info_t ka1a_decoder;
|
|||
extern const codec_info_t ubimpeg_decoder;
|
||||
extern const codec_info_t hca_decoder;
|
||||
#ifdef VGM_USE_VORBIS
|
||||
extern const codec_info_t ogg_vorbis_decoder;
|
||||
extern const codec_info_t vorbis_custom_decoder;
|
||||
#endif
|
||||
extern const codec_info_t tac_decoder;
|
||||
|
@ -12,6 +13,9 @@ extern const codec_info_t compresswave_decoder;
|
|||
extern const codec_info_t speex_decoder;
|
||||
extern const codec_info_t imuse_decoder;
|
||||
extern const codec_info_t mio_decoder;
|
||||
extern const codec_info_t pcm32_decoder;
|
||||
extern const codec_info_t pcm24_decoder;
|
||||
extern const codec_info_t pcmfloat_decoder;
|
||||
|
||||
const codec_info_t* codec_get_info(VGMSTREAM* v) {
|
||||
switch(v->coding_type) {
|
||||
|
@ -22,6 +26,8 @@ const codec_info_t* codec_get_info(VGMSTREAM* v) {
|
|||
case coding_UBI_MPEG:
|
||||
return &ubimpeg_decoder;
|
||||
#ifdef VGM_USE_VORBIS
|
||||
case coding_OGG_VORBIS:
|
||||
return &ogg_vorbis_decoder;
|
||||
case coding_VORBIS_custom:
|
||||
return &vorbis_custom_decoder;
|
||||
#endif
|
||||
|
@ -37,6 +43,13 @@ const codec_info_t* codec_get_info(VGMSTREAM* v) {
|
|||
return &imuse_decoder;
|
||||
case coding_MIO:
|
||||
return &mio_decoder;
|
||||
case coding_PCM32LE:
|
||||
return &pcm32_decoder;
|
||||
case coding_PCM24LE:
|
||||
case coding_PCM24BE:
|
||||
return &pcm24_decoder;
|
||||
case coding_PCMFLOAT:
|
||||
return &pcmfloat_decoder;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -18,6 +18,8 @@ typedef struct {
|
|||
void (*reset)(void* codec_data);
|
||||
void (*seek)(VGMSTREAM* v, int32_t num_sample);
|
||||
|
||||
bool (*decode_buf)(VGMSTREAM* v, sbuf_t* sdst); // alternate decoding for codecs that don't provide their own buffer
|
||||
|
||||
// info for vgmstream
|
||||
//uint32_t flags;
|
||||
// alloc size of effect's private data (don't set to manage manually in init/free)
|
||||
|
|
|
@ -46,12 +46,6 @@ void decode_free(VGMSTREAM* vgmstream) {
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
if (vgmstream->coding_type == coding_OGG_VORBIS) {
|
||||
free_ogg_vorbis(vgmstream->codec_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vgmstream->coding_type == coding_CIRCUS_VQ) {
|
||||
free_circus_vq(vgmstream->codec_data);
|
||||
}
|
||||
|
@ -170,12 +164,6 @@ void decode_seek(VGMSTREAM* vgmstream) {
|
|||
seek_ea_mt(vgmstream, vgmstream->loop_current_sample);
|
||||
}
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
if (vgmstream->coding_type == coding_OGG_VORBIS) {
|
||||
seek_ogg_vorbis(vgmstream->codec_data, vgmstream->loop_current_sample);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
if (vgmstream->coding_type == coding_FFmpeg) {
|
||||
seek_ffmpeg(vgmstream->codec_data, vgmstream->loop_current_sample);
|
||||
|
@ -228,12 +216,6 @@ void decode_reset(VGMSTREAM* vgmstream) {
|
|||
return;
|
||||
}
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
if (vgmstream->coding_type == coding_OGG_VORBIS) {
|
||||
reset_ogg_vorbis(vgmstream->codec_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vgmstream->coding_type == coding_CIRCUS_VQ) {
|
||||
reset_circus_vq(vgmstream->codec_data);
|
||||
}
|
||||
|
@ -360,9 +342,6 @@ int decode_get_samples_per_frame(VGMSTREAM* vgmstream) {
|
|||
case coding_PCM24BE:
|
||||
case coding_PCM32LE:
|
||||
return 1;
|
||||
#ifdef VGM_USE_VORBIS
|
||||
case coding_OGG_VORBIS:
|
||||
#endif
|
||||
#ifdef VGM_USE_MPEG
|
||||
case coding_MPEG_custom:
|
||||
case coding_MPEG_ealayer3:
|
||||
|
@ -784,13 +763,23 @@ bool decode_uses_internal_offset_updates(VGMSTREAM* vgmstream) {
|
|||
|
||||
|
||||
// decode frames for decoders which decode frame by frame and have their own sample buffer
|
||||
static void decode_frames(sbuf_t* sdst, VGMSTREAM* vgmstream) {
|
||||
static void decode_frames(sbuf_t* sdst, VGMSTREAM* vgmstream, int samples_to_do) {
|
||||
const int max_empty = 1000;
|
||||
int num_empty = 0;
|
||||
decode_state_t* ds = vgmstream->decode_state;
|
||||
sbuf_t* ssrc = &ds->sbuf;
|
||||
|
||||
const codec_info_t* codec_info = codec_get_info(vgmstream);
|
||||
ds->samples_left = samples_to_do; //sdst->samples; // TODO this can be slow for interleaved decoders
|
||||
|
||||
// old-style decoding
|
||||
if (codec_info && codec_info->decode_buf) {
|
||||
bool ok = codec_info->decode_buf(vgmstream, sdst);
|
||||
if (!ok) goto decode_fail;
|
||||
|
||||
sdst->filled += ds->samples_left;
|
||||
return;
|
||||
}
|
||||
|
||||
// fill the external buf by decoding N times; may read partially that buf
|
||||
while (sdst->filled < sdst->samples) {
|
||||
|
@ -838,6 +827,8 @@ static void decode_frames(sbuf_t* sdst, VGMSTREAM* vgmstream) {
|
|||
|
||||
sbuf_copy_segments(sdst, ssrc, samples_copy);
|
||||
sbuf_consume(ssrc, samples_copy);
|
||||
|
||||
ds->samples_left -= samples_copy;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -864,7 +855,7 @@ void decode_vgmstream(sbuf_t* sdst, VGMSTREAM* vgmstream, int samples_to_do) {
|
|||
|
||||
switch (vgmstream->coding_type) {
|
||||
case coding_SILENCE:
|
||||
sbuf_silence_s16(buffer, samples_to_do, vgmstream->channels, 0);
|
||||
sbuf_silence_rest(sdst);
|
||||
break;
|
||||
|
||||
case coding_CRI_ADX:
|
||||
|
@ -972,35 +963,6 @@ void decode_vgmstream(sbuf_t* sdst, VGMSTREAM* vgmstream, int samples_to_do) {
|
|||
vgmstream->channels, vgmstream->samples_into_block, samples_to_do);
|
||||
}
|
||||
break;
|
||||
case coding_PCMFLOAT:
|
||||
for (ch = 0; ch < vgmstream->channels; ch++) {
|
||||
decode_pcmfloat(&vgmstream->ch[ch], buffer+ch,
|
||||
vgmstream->channels, vgmstream->samples_into_block, samples_to_do,
|
||||
vgmstream->codec_endian);
|
||||
}
|
||||
break;
|
||||
|
||||
case coding_PCM24LE:
|
||||
for (ch = 0; ch < vgmstream->channels; ch++) {
|
||||
decode_pcm24le(&vgmstream->ch[ch], buffer+ch,
|
||||
vgmstream->channels, vgmstream->samples_into_block, samples_to_do);
|
||||
}
|
||||
break;
|
||||
|
||||
case coding_PCM24BE:
|
||||
for (ch = 0; ch < vgmstream->channels; ch++) {
|
||||
decode_pcm24be(&vgmstream->ch[ch], buffer + ch,
|
||||
vgmstream->channels, vgmstream->samples_into_block, samples_to_do);
|
||||
}
|
||||
break;
|
||||
|
||||
case coding_PCM32LE:
|
||||
for (ch = 0; ch < vgmstream->channels; ch++) {
|
||||
decode_pcm32le(&vgmstream->ch[ch], buffer+ch,
|
||||
vgmstream->channels, vgmstream->samples_into_block, samples_to_do);
|
||||
}
|
||||
break;
|
||||
|
||||
case coding_NDS_IMA:
|
||||
for (ch = 0; ch < vgmstream->channels; ch++) {
|
||||
decode_nds_ima(&vgmstream->ch[ch], buffer+ch,
|
||||
|
@ -1148,11 +1110,6 @@ void decode_vgmstream(sbuf_t* sdst, VGMSTREAM* vgmstream, int samples_to_do) {
|
|||
vgmstream->channels, vgmstream->samples_into_block, samples_to_do, ch);
|
||||
}
|
||||
break;
|
||||
#ifdef VGM_USE_VORBIS
|
||||
case coding_OGG_VORBIS:
|
||||
decode_ogg_vorbis(vgmstream->codec_data, buffer, samples_to_do, vgmstream->channels);
|
||||
break;
|
||||
#endif
|
||||
case coding_CIRCUS_VQ:
|
||||
decode_circus_vq(vgmstream->codec_data, buffer, samples_to_do, vgmstream->channels);
|
||||
break;
|
||||
|
@ -1574,7 +1531,7 @@ void decode_vgmstream(sbuf_t* sdst, VGMSTREAM* vgmstream, int samples_to_do) {
|
|||
sbuf_t stmp = *sdst;
|
||||
stmp.samples = stmp.filled + samples_to_do; //TODO improve
|
||||
|
||||
decode_frames(&stmp, vgmstream);
|
||||
decode_frames(&stmp, vgmstream, samples_to_do);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
typedef struct {
|
||||
int discard;
|
||||
sbuf_t sbuf;
|
||||
int samples_left; //info for some decoders
|
||||
} decode_state_t;
|
||||
|
||||
#endif
|
||||
|
|
|
@ -176,8 +176,11 @@ void describe_vgmstream(VGMSTREAM* vgmstream, char* desc, int length) {
|
|||
const char* sfmt_desc;
|
||||
switch(sfmt) {
|
||||
case SFMT_FLT: sfmt_desc = "float"; break;
|
||||
case SFMT_F32: sfmt_desc = "float32"; break;
|
||||
case SFMT_F16: sfmt_desc = "float16"; break;
|
||||
case SFMT_S16: sfmt_desc = "pcm16"; break;
|
||||
case SFMT_S24: sfmt_desc = "pcm24"; break;
|
||||
case SFMT_S32: sfmt_desc = "pcm32"; break;
|
||||
case SFMT_O24: sfmt_desc = "pcm24"; break;
|
||||
default: sfmt_desc = "???";
|
||||
}
|
||||
|
||||
|
|
|
@ -74,11 +74,12 @@ bool mixer_is_active(mixer_t* mixer) {
|
|||
static void setup_mixbuf(mixer_t* mixer, sbuf_t* sbuf) {
|
||||
sbuf_t* smix = &mixer->smix;
|
||||
|
||||
// mixbuf can be interpreted as FLT or F32; try to use src's to keep buf as-is (less rounding errors)
|
||||
if (sbuf->fmt == SFMT_F32 || sbuf->fmt == SFMT_FLT)
|
||||
sbuf_init(smix, sbuf->fmt, mixer->mixbuf, sbuf->filled, sbuf->channels); //mixer->input_channels
|
||||
// mixbuf (float) can be interpreted as F16, for 1:1 mapping with PCM16 (and possibly less rounding errors with mixops)
|
||||
// for PCM24 regular float seems ok and 1:1 as well
|
||||
if (sbuf->fmt == SFMT_S16)
|
||||
sbuf_init(smix, SFMT_F16, mixer->mixbuf, sbuf->filled, sbuf->channels);
|
||||
else
|
||||
sbuf_init(smix, SFMT_F32, mixer->mixbuf, sbuf->filled, sbuf->channels);
|
||||
sbuf_init(smix, sbuf->fmt, mixer->mixbuf, sbuf->filled, sbuf->channels);
|
||||
|
||||
// remix to temp buf (somehow using float buf rather than int32 is faster?)
|
||||
sbuf_copy_segments(smix, sbuf, sbuf->filled);
|
||||
|
@ -100,12 +101,20 @@ static void setup_outbuf(mixer_t* mixer, sbuf_t* sbuf) {
|
|||
|
||||
void mixer_process(mixer_t* mixer, sbuf_t* sbuf, int32_t current_pos) {
|
||||
|
||||
/* external */
|
||||
// external
|
||||
//if (!mixer_is_active(mixer))
|
||||
// return;
|
||||
|
||||
/* try to skip if no fades apply (set but does nothing yet) + only has fades
|
||||
* (could be done in mix op but avoids upgrading bufs in some cases) */
|
||||
#if 0
|
||||
// TODO: not possible to copy from src to dst directly at the moment, since src doubles as dst
|
||||
// optimize copy only ops to skip temp buffer
|
||||
if (mixer->chain_count == 0 && mixer->force_type != SFMT_NONE) {
|
||||
...
|
||||
}
|
||||
#endif
|
||||
|
||||
// try to skip if no fades apply (set but does nothing yet) + only has fades
|
||||
// (could be done in mix op but avoids upgrading bufs in some cases)
|
||||
if (mixer->has_fade) {
|
||||
//;VGM_LOG("MIX: fade test %i, %i\n", data->has_non_fade, mixer_op_fade_is_active(data, current_pos, current_pos + sample_count));
|
||||
if (!mixer->has_non_fade && !mixer_op_fade_is_active(mixer, current_pos, current_pos + sbuf->filled))
|
||||
|
|
|
@ -107,8 +107,8 @@ int render_layout(sbuf_t* sbuf, VGMSTREAM* vgmstream) {
|
|||
case layout_blocked_dec:
|
||||
case layout_blocked_vs_mh:
|
||||
case layout_blocked_mul:
|
||||
case layout_blocked_gsb:
|
||||
case layout_blocked_xvas:
|
||||
case layout_blocked_gsnd:
|
||||
case layout_blocked_vas_kceo:
|
||||
case layout_blocked_thp:
|
||||
case layout_blocked_filp:
|
||||
case layout_blocked_rage_aud:
|
||||
|
|
|
@ -12,6 +12,119 @@
|
|||
#include <math.h>
|
||||
#endif
|
||||
|
||||
/* when casting float to int, value is simply truncated:
|
||||
* - (int)1.7 = 1, (int)-1.7 = -1
|
||||
* alts for more accurate rounding could be:
|
||||
* - (int)floor(f)
|
||||
* - (int)(f < 0 ? f - 0.5f : f + 0.5f)
|
||||
* - (((int) (f1 + 32767.5)) - 32767)
|
||||
* - etc
|
||||
* but since +-1 isn't really audible we'll just cast, as it's the fastest
|
||||
*
|
||||
* Regular C float-to-int casting ("int i = (int)f") is somewhat slow due to IEEE
|
||||
* float requirements, but C99 adds some faster-but-less-precise casting functions.
|
||||
* MSVC added this in VS2015 (_MSC_VER 1900) but doesn't seem inlined and is very slow.
|
||||
* It's slightly faster (~5%) but causes fuzzy PCM<>float<>PCM conversions.
|
||||
*/
|
||||
static inline int float_to_int(float val) {
|
||||
#if PCM16_ROUNDING_LRINT
|
||||
return lrintf(val);
|
||||
#elif defined(_MSC_VER)
|
||||
return (int)val;
|
||||
#else
|
||||
return (int)val;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if 0
|
||||
static inline int double_to_int(double val) {
|
||||
#if PCM16_ROUNDING_LRINT
|
||||
return lrint(val);
|
||||
#elif defined(_MSC_VER)
|
||||
return (int)val;
|
||||
#else
|
||||
return (int)val;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline float double_to_float(double val) {
|
||||
return (float)val;
|
||||
}
|
||||
#endif
|
||||
|
||||
static inline int64_t float_to_i64(float val) {
|
||||
return (int64_t)val;
|
||||
}
|
||||
|
||||
// TO-DO: investigate if BE machines need BE 24-bit
|
||||
static inline int32_t get_s24ne(const uint8_t* p) {
|
||||
#if PCM24_BIG_ENDIAN
|
||||
return (((int32_t)p[0]<<24) | ((int32_t)p[1]<<16) | ((int32_t)p[2]<<8)) >> 8; //force signedness
|
||||
#else
|
||||
return (((int32_t)p[0]<<8) | ((int32_t)p[1]<<16) | ((int32_t)p[2]<<24)) >> 8; //force signedness
|
||||
#endif
|
||||
}
|
||||
|
||||
static void put_u24ne(uint8_t* buf, uint32_t v) {
|
||||
#if PCM24_BIG_ENDIAN
|
||||
buf[0] = (uint8_t)((v >> 16) & 0xFF);
|
||||
buf[1] = (uint8_t)((v >> 8) & 0xFF);
|
||||
buf[2] = (uint8_t)((v >> 0) & 0xFF);
|
||||
#else
|
||||
buf[0] = (uint8_t)((v >> 0) & 0xFF);
|
||||
buf[1] = (uint8_t)((v >> 8) & 0xFF);
|
||||
buf[2] = (uint8_t)((v >> 16) & 0xFF);
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int clamp_pcm16(int32_t val) {
|
||||
return clamp16(val);
|
||||
}
|
||||
|
||||
static inline int clamp_pcm24(int32_t val) {
|
||||
if (val > 8388607) return 8388607;
|
||||
else if (val < -8388608) return -8388608;
|
||||
else return val;
|
||||
}
|
||||
|
||||
static inline int clamp_pcm32(int64_t val) {
|
||||
if (val > 2147483647) return 2147483647;
|
||||
else if (val < -2147483648) return -2147483648;
|
||||
else return val;
|
||||
}
|
||||
|
||||
//TODO float can't fully represent s32, but since it mainly affects lower bytes (noise) it may be ok
|
||||
|
||||
#define CONV_NOOP(x) (x)
|
||||
#define CONV_S16_FLT(x) (x * (1.0f / 32767.0f))
|
||||
#define CONV_S16_S24(x) (x << 8)
|
||||
#define CONV_S16_S32(x) (x << 16)
|
||||
|
||||
#define CONV_F16_S16(x) (clamp_pcm16(float_to_int(x)))
|
||||
#define CONV_F16_FLT(x) (x * (1.0f / 32767.0f))
|
||||
#define CONV_F16_S24(x) (clamp_pcm16(float_to_int(x)) << 8)
|
||||
#define CONV_F16_S32(x) (clamp_pcm16(float_to_int(x)) << 16)
|
||||
|
||||
#ifdef PCM16_ROUNDING_HALF
|
||||
#define CONV_FLT_S16(x) (clamp_pcm16(float_to_int( floor(x * 32767.0f + 0.5f) )))
|
||||
#else
|
||||
#define CONV_FLT_S16(x) (clamp_pcm16(float_to_int(x * 32767.0f)))
|
||||
#endif
|
||||
#define CONV_FLT_F16(x) (x * 32767.0f)
|
||||
#define CONV_FLT_S24(x) (clamp_pcm24(float_to_int(x * 8388607.0f)))
|
||||
#define CONV_FLT_S32(x) (clamp_pcm32(float_to_i64(x * 2147483647)))
|
||||
|
||||
#define CONV_S24_S16(x) (x >> 8)
|
||||
#define CONV_S24_F16(x) (x >> 8)
|
||||
#define CONV_S24_S32(x) (x << 8)
|
||||
#define CONV_S24_FLT(x) (x * (1.0f / 8388607.0f))
|
||||
|
||||
#define CONV_S32_S16(x) (x >> 16)
|
||||
#define CONV_S32_F16(x) (x >> 16)
|
||||
#define CONV_S32_FLT(x) (x * (1.0f / 2147483647.0f))
|
||||
#define CONV_S32_S24(x) (x >> 8)
|
||||
|
||||
|
||||
void sbuf_init(sbuf_t* sbuf, sfmt_t format, void* buf, int samples, int channels) {
|
||||
memset(sbuf, 0, sizeof(sbuf_t));
|
||||
sbuf->buf = buf;
|
||||
|
@ -24,8 +137,8 @@ void sbuf_init_s16(sbuf_t* sbuf, int16_t* buf, int samples, int channels) {
|
|||
sbuf_init(sbuf, SFMT_S16, buf, samples, channels);
|
||||
}
|
||||
|
||||
void sbuf_init_f32(sbuf_t* sbuf, float* buf, int samples, int channels) {
|
||||
sbuf_init(sbuf, SFMT_F32, buf, samples, channels);
|
||||
void sbuf_init_f16(sbuf_t* sbuf, float* buf, int samples, int channels) {
|
||||
sbuf_init(sbuf, SFMT_F16, buf, samples, channels);
|
||||
}
|
||||
|
||||
void sbuf_init_flt(sbuf_t* sbuf, float* buf, int samples, int channels) {
|
||||
|
@ -35,13 +148,18 @@ void sbuf_init_flt(sbuf_t* sbuf, float* buf, int samples, int channels) {
|
|||
|
||||
int sfmt_get_sample_size(sfmt_t fmt) {
|
||||
switch(fmt) {
|
||||
case SFMT_F32:
|
||||
case SFMT_F16:
|
||||
case SFMT_FLT:
|
||||
case SFMT_S24:
|
||||
case SFMT_S32:
|
||||
return 0x04;
|
||||
case SFMT_S16:
|
||||
return 0x02;
|
||||
case SFMT_O24:
|
||||
return 0x03;
|
||||
default:
|
||||
return 0;
|
||||
VGM_LOG("SBUF: undefined sample format %i found\n", fmt);
|
||||
return 0; //TODO return 4 to avoid crashes?
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -70,102 +188,6 @@ void sbuf_consume(sbuf_t* sbuf, int samples) {
|
|||
sbuf->samples -= samples;
|
||||
}
|
||||
|
||||
/* when casting float to int, value is simply truncated:
|
||||
* - (int)1.7 = 1, (int)-1.7 = -1
|
||||
* alts for more accurate rounding could be:
|
||||
* - (int)floor(f)
|
||||
* - (int)(f < 0 ? f - 0.5f : f + 0.5f)
|
||||
* - (((int) (f1 + 32767.5)) - 32767)
|
||||
* - etc
|
||||
* but since +-1 isn't really audible we'll just cast, as it's the fastest
|
||||
*
|
||||
* Regular C float-to-int casting ("int i = (int)f") is somewhat slow due to IEEE
|
||||
* float requirements, but C99 adds some faster-but-less-precise casting functions.
|
||||
* MSVC added this in VS2015 (_MSC_VER 1900) but doesn't seem inlined and is very slow.
|
||||
* It's slightly faster (~5%) but causes fuzzy PCM<>float<>PCM conversions.
|
||||
*/
|
||||
static inline int float_to_int(float val) {
|
||||
#if PCM16_ROUNDING_LRINT
|
||||
return lrintf(val);
|
||||
#elif defined(_MSC_VER)
|
||||
return (int)val;
|
||||
#else
|
||||
return (int)val;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int double_to_int(double val) {
|
||||
#if PCM16_ROUNDING_LRINT
|
||||
return lrint(val);
|
||||
#elif defined(_MSC_VER)
|
||||
return (int)val;
|
||||
#else
|
||||
return (int)val;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline float double_to_float(double val) {
|
||||
return (float)val;
|
||||
}
|
||||
|
||||
//TODO decide if using float 1.0 style or 32767 style (fuzzy PCM when doing that)
|
||||
//TODO: maybe use macro-style templating (but kinda ugly)
|
||||
void sbuf_copy_to_f32(float* dst, sbuf_t* sbuf) {
|
||||
|
||||
switch(sbuf->fmt) {
|
||||
case SFMT_S16: {
|
||||
int16_t* src = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
dst[s] = (float)src[s]; // / 32767.0f
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SFMT_F32: {
|
||||
float* src = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
dst[s] = src[s];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SFMT_FLT: {
|
||||
float* src = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
dst[s] = src[s] * 32767.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void sbuf_copy_from_f32(sbuf_t* sbuf, float* src) {
|
||||
switch(sbuf->fmt) {
|
||||
case SFMT_S16: {
|
||||
int16_t* dst = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
dst[s] = clamp16(float_to_int(src[s]));
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SFMT_F32: {
|
||||
float* dst = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
dst[s] = src[s];
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SFMT_FLT: {
|
||||
float* dst = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
dst[s] = src[s] / 32767.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// max samples to copy from ssrc to sdst, considering that dst may be partially filled
|
||||
int sbuf_get_copy_max(sbuf_t* sdst, sbuf_t* ssrc) {
|
||||
|
@ -176,252 +198,6 @@ int sbuf_get_copy_max(sbuf_t* sdst, sbuf_t* ssrc) {
|
|||
return samples_copy;
|
||||
}
|
||||
|
||||
|
||||
/* ugly thing to avoid repeating functions */
|
||||
#define sbuf_copy_segments_internal(dst, src, src_pos, dst_pos, src_max) \
|
||||
while (src_pos < src_max) { \
|
||||
dst[dst_pos++] = src[src_pos++]; \
|
||||
}
|
||||
|
||||
#define sbuf_copy_segments_internal_f16(dst, src, src_pos, dst_pos, src_max) \
|
||||
while (src_pos < src_max) { \
|
||||
dst[dst_pos++] = clamp16(float_to_int(src[src_pos++])); \
|
||||
}
|
||||
|
||||
#ifdef PCM16_ROUNDING_HALF
|
||||
#define sbuf_copy_segments_internal_s16(dst, src, src_pos, dst_pos, src_max, value) \
|
||||
while (src_pos < src_max) { \
|
||||
dst[dst_pos++] = clamp16(float_to_int( floor(src[src_pos++] * value + 0.5f) )); \
|
||||
}
|
||||
#else
|
||||
#define sbuf_copy_segments_internal_s16(dst, src, src_pos, dst_pos, src_max, value) \
|
||||
while (src_pos < src_max) { \
|
||||
dst[dst_pos++] = clamp16(float_to_int(src[src_pos++] * value)); \
|
||||
}
|
||||
#endif
|
||||
|
||||
#define sbuf_copy_segments_internal_flt(dst, src, src_pos, dst_pos, src_max, value) \
|
||||
while (src_pos < src_max) { \
|
||||
dst[dst_pos++] = (src[src_pos++] * value); \
|
||||
}
|
||||
|
||||
// copy N samples from ssrc into dst (should be clamped externally)
|
||||
void sbuf_copy_segments(sbuf_t* sdst, sbuf_t* ssrc, int samples_copy) {
|
||||
|
||||
if (ssrc->channels != sdst->channels) {
|
||||
// 0'd other channels first (uncommon so probably fine albeit slower-ish)
|
||||
sbuf_silence_part(sdst, sdst->filled, samples_copy);
|
||||
sbuf_copy_layers(sdst, ssrc, 0, samples_copy);
|
||||
#if 0
|
||||
// "faster" but lots of extra ifs per sample format, not worth it
|
||||
while (src_pos < src_max) {
|
||||
for (int ch = 0; ch < dst_channels; ch++) {
|
||||
dst[dst_pos++] = ch >= src_channels ? 0 : src[src_pos++];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
//TODO: may want to handle externally?
|
||||
sdst->filled += samples_copy;
|
||||
return;
|
||||
}
|
||||
|
||||
int src_pos = 0;
|
||||
int dst_pos = sdst->filled * sdst->channels;
|
||||
int src_max = samples_copy * ssrc->channels;
|
||||
|
||||
// define all posible combos, probably there is a better way to handle this but...
|
||||
// s16 > s16
|
||||
if (ssrc->fmt == SFMT_S16 && sdst->fmt == SFMT_S16) {
|
||||
int16_t* src = ssrc->buf;
|
||||
int16_t* dst = sdst->buf;
|
||||
sbuf_copy_segments_internal(dst, src, src_pos, dst_pos, src_max);
|
||||
}
|
||||
// s16 > f32
|
||||
else if (ssrc->fmt == SFMT_S16 && sdst->fmt == SFMT_F32) {
|
||||
int16_t* src = ssrc->buf;
|
||||
float* dst = sdst->buf;
|
||||
sbuf_copy_segments_internal(dst, src, src_pos, dst_pos, src_max);
|
||||
}
|
||||
// s16 > flt
|
||||
else if (ssrc->fmt == SFMT_S16 && sdst->fmt == SFMT_FLT) {
|
||||
int16_t* src = ssrc->buf;
|
||||
float* dst = sdst->buf;
|
||||
sbuf_copy_segments_internal_flt(dst, src, src_pos, dst_pos, src_max, (1.0f / 32767.0f));
|
||||
}
|
||||
// f32 > f32 / flt > flt
|
||||
else if ((ssrc->fmt == SFMT_F32 && sdst->fmt == SFMT_F32) ||
|
||||
(ssrc->fmt == SFMT_FLT && sdst->fmt == SFMT_FLT)) {
|
||||
float* src = ssrc->buf;
|
||||
float* dst = sdst->buf;
|
||||
sbuf_copy_segments_internal(dst, src, src_pos, dst_pos, src_max);
|
||||
}
|
||||
// f32 > s16
|
||||
else if (ssrc->fmt == SFMT_F32 && sdst->fmt == SFMT_S16) {
|
||||
float* src = ssrc->buf;
|
||||
int16_t* dst = sdst->buf;
|
||||
sbuf_copy_segments_internal_f16(dst, src, src_pos, dst_pos, src_max);
|
||||
}
|
||||
// flt > s16
|
||||
else if (ssrc->fmt == SFMT_FLT && sdst->fmt == SFMT_S16) {
|
||||
float* src = ssrc->buf;
|
||||
int16_t* dst = sdst->buf;
|
||||
sbuf_copy_segments_internal_s16(dst, src, src_pos, dst_pos, src_max, 32767.0f);
|
||||
}
|
||||
// f32 > flt
|
||||
else if (ssrc->fmt == SFMT_F32 && sdst->fmt == SFMT_FLT) {
|
||||
float* src = ssrc->buf;
|
||||
float* dst = sdst->buf;
|
||||
sbuf_copy_segments_internal_flt(dst, src, src_pos, dst_pos, src_max, (1.0f / 32767.0f));
|
||||
}
|
||||
// flt > f32
|
||||
else if (ssrc->fmt == SFMT_FLT && sdst->fmt == SFMT_F32) {
|
||||
float* src = ssrc->buf;
|
||||
float* dst = sdst->buf;
|
||||
sbuf_copy_segments_internal_flt(dst, src, src_pos, dst_pos, src_max, 32767.0f);
|
||||
}
|
||||
|
||||
//TODO: may want to handle externally?
|
||||
sdst->filled += samples_copy;
|
||||
}
|
||||
|
||||
|
||||
#define sbuf_copy_layers_internal_blank(dst, src, src_pos, dst_pos, src_filled, dst_expected, src_channels, dst_ch_step) \
|
||||
for (int s = src_filled; s < dst_expected; s++) { \
|
||||
for (int src_ch = 0; src_ch < src_channels; src_ch++) { \
|
||||
dst[dst_pos++] = 0; \
|
||||
} \
|
||||
dst_pos += dst_ch_step; \
|
||||
}
|
||||
|
||||
//TODO fix missing ->channels
|
||||
/* ugly thing to avoid repeating functions */
|
||||
#define sbuf_copy_layers_internal(dst, src, src_pos, dst_pos, src_filled, dst_expected, src_channels, dst_ch_step) \
|
||||
for (int s = 0; s < src_filled; s++) { \
|
||||
for (int src_ch = 0; src_ch < src_channels; src_ch++) { \
|
||||
dst[dst_pos++] = src[src_pos++]; \
|
||||
} \
|
||||
dst_pos += dst_ch_step; \
|
||||
} \
|
||||
\
|
||||
sbuf_copy_layers_internal_blank(dst, src, src_pos, dst_pos, src_filled, dst_expected, src_channels, dst_ch_step);
|
||||
|
||||
// float +-1.0 <> pcm +-32767.0
|
||||
#define sbuf_copy_layers_internal_f16(dst, src, src_pos, dst_pos, src_filled, dst_expected, src_channels, dst_ch_step) \
|
||||
for (int s = 0; s < src_filled; s++) { \
|
||||
for (int src_ch = 0; src_ch < src_channels; src_ch++) { \
|
||||
dst[dst_pos++] = clamp16(float_to_int(src[src_pos++])); \
|
||||
} \
|
||||
dst_pos += dst_ch_step; \
|
||||
} \
|
||||
\
|
||||
sbuf_copy_layers_internal_blank(dst, src, src_pos, dst_pos, src_filled, dst_expected, src_channels, dst_ch_step);
|
||||
|
||||
#ifdef PCM16_ROUNDING_HALF
|
||||
// float +-1.0 <> pcm +-32767.0
|
||||
#define sbuf_copy_layers_internal_s16(dst, src, src_pos, dst_pos, src_filled, dst_expected, src_channels, dst_ch_step, value) \
|
||||
for (int s = 0; s < src_filled; s++) { \
|
||||
for (int src_ch = 0; src_ch < src_channels; src_ch++) { \
|
||||
dst[dst_pos++] = clamp16(float_to_int( floor(src[src_pos++] * value + 0.5f) )); \
|
||||
} \
|
||||
dst_pos += dst_ch_step; \
|
||||
} \
|
||||
\
|
||||
sbuf_copy_layers_internal_blank(dst, src, src_pos, dst_pos, src_filled, dst_expected, src_channels, dst_ch_step);
|
||||
#else
|
||||
// float +-1.0 <> pcm +-32767.0
|
||||
#define sbuf_copy_layers_internal_s16(dst, src, src_pos, dst_pos, src_filled, dst_expected, src_channels, dst_ch_step, value) \
|
||||
for (int s = 0; s < src_filled; s++) { \
|
||||
for (int src_ch = 0; src_ch < src_channels; src_ch++) { \
|
||||
dst[dst_pos++] = clamp16(float_to_int(src[src_pos++] * value)); \
|
||||
} \
|
||||
dst_pos += dst_ch_step; \
|
||||
} \
|
||||
\
|
||||
sbuf_copy_layers_internal_blank(dst, src, src_pos, dst_pos, src_filled, dst_expected, src_channels, dst_ch_step);
|
||||
#endif
|
||||
|
||||
// float +-1.0 <> pcm +-32767.0
|
||||
#define sbuf_copy_layers_internal_flt(dst, src, src_pos, dst_pos, src_filled, dst_expected, src_channels, dst_ch_step, value) \
|
||||
for (int s = 0; s < src_filled; s++) { \
|
||||
for (int src_ch = 0; src_ch < src_channels; src_ch++) { \
|
||||
dst[dst_pos++] = float_to_int(src[src_pos++] * value); \
|
||||
} \
|
||||
dst_pos += dst_ch_step; \
|
||||
} \
|
||||
\
|
||||
sbuf_copy_layers_internal_blank(dst, src, src_pos, dst_pos, src_filled, dst_expected, src_channels, dst_ch_step);
|
||||
|
||||
// copy interleaving: dst ch1 ch2 ch3 ch4 w/ src ch1 ch2 ch1 ch2 = only fill dst ch1 ch2
|
||||
// dst_channels == src_channels isn't likely so ignore that optimization (dst must be >= than src).
|
||||
// dst_ch_start indicates it should write to dst's chN,chN+1,etc
|
||||
// sometimes one layer has less samples than others and need to 0-fill rest
|
||||
void sbuf_copy_layers(sbuf_t* sdst, sbuf_t* ssrc, int dst_ch_start, int dst_max) {
|
||||
int src_copy = dst_max;
|
||||
int src_channels = ssrc->channels;
|
||||
int dst_ch_step = (sdst->channels - ssrc->channels);
|
||||
int src_pos = 0;
|
||||
int dst_pos = sdst->filled * sdst->channels + dst_ch_start;
|
||||
|
||||
if (src_copy > ssrc->filled)
|
||||
src_copy = ssrc->filled;
|
||||
|
||||
if (ssrc->channels > sdst->channels) {
|
||||
VGM_LOG("SBUF: wrong copy\n");
|
||||
return;
|
||||
}
|
||||
|
||||
// define all posible combos, probably there is a better way to handle this but...
|
||||
|
||||
// 1:1
|
||||
if (sdst->fmt == SFMT_S16 && ssrc->fmt == SFMT_S16) {
|
||||
int16_t* dst = sdst->buf;
|
||||
int16_t* src = ssrc->buf;
|
||||
sbuf_copy_layers_internal(dst, src, src_pos, dst_pos, src_copy, dst_max, src_channels, dst_ch_step);
|
||||
}
|
||||
else if (sdst->fmt == SFMT_F32 && ssrc->fmt == SFMT_S16) {
|
||||
float* dst = sdst->buf;
|
||||
int16_t* src = ssrc->buf;
|
||||
sbuf_copy_layers_internal(dst, src, src_pos, dst_pos, src_copy, dst_max, src_channels, dst_ch_step);
|
||||
}
|
||||
else if ((sdst->fmt == SFMT_F32 && ssrc->fmt == SFMT_F32) || (sdst->fmt == SFMT_FLT && ssrc->fmt == SFMT_FLT)) {
|
||||
float* dst = sdst->buf;
|
||||
float* src = ssrc->buf;
|
||||
sbuf_copy_layers_internal(dst, src, src_pos, dst_pos, src_copy, dst_max, src_channels, dst_ch_step);
|
||||
}
|
||||
// to s16
|
||||
else if (sdst->fmt == SFMT_S16 && ssrc->fmt == SFMT_F32) {
|
||||
int16_t* dst = sdst->buf;
|
||||
float* src = ssrc->buf;
|
||||
sbuf_copy_layers_internal_f16(dst, src, src_pos, dst_pos, src_copy, dst_max, src_channels, dst_ch_step);
|
||||
}
|
||||
else if (sdst->fmt == SFMT_S16 && ssrc->fmt == SFMT_FLT) {
|
||||
int16_t* dst = sdst->buf;
|
||||
float* src = ssrc->buf;
|
||||
sbuf_copy_layers_internal_s16(dst, src, src_pos, dst_pos, src_copy, dst_max, src_channels, dst_ch_step, 32767.0f);
|
||||
}
|
||||
// to f32
|
||||
else if (sdst->fmt == SFMT_F32 && ssrc->fmt == SFMT_FLT) {
|
||||
float* dst = sdst->buf;
|
||||
float* src = ssrc->buf;
|
||||
sbuf_copy_layers_internal_flt(dst, src, src_pos, dst_pos, src_copy, dst_max, src_channels, dst_ch_step, 32767.0f);
|
||||
}
|
||||
// to flt
|
||||
else if (sdst->fmt == SFMT_FLT && ssrc->fmt == SFMT_S16) {
|
||||
float* dst = sdst->buf;
|
||||
int16_t* src = ssrc->buf;
|
||||
sbuf_copy_layers_internal_flt(dst, src, src_pos, dst_pos, src_copy, dst_max, src_channels, dst_ch_step, (1.0f / 32767.0f));
|
||||
}
|
||||
else if (sdst->fmt == SFMT_FLT && ssrc->fmt == SFMT_F32) {
|
||||
float* dst = sdst->buf;
|
||||
float* src = ssrc->buf;
|
||||
sbuf_copy_layers_internal_flt(dst, src, src_pos, dst_pos, src_copy, dst_max, src_channels, dst_ch_step, (1.0f / 32767.0f));
|
||||
}
|
||||
}
|
||||
|
||||
void sbuf_silence_s16(sample_t* dst, int samples, int channels, int filled) {
|
||||
memset(dst + filled * channels, 0, (samples - filled) * channels * sizeof(sample_t));
|
||||
}
|
||||
|
||||
void sbuf_silence_part(sbuf_t* sbuf, int from, int count) {
|
||||
int sample_size = sfmt_get_sample_size(sbuf->fmt);
|
||||
|
||||
|
@ -434,44 +210,291 @@ void sbuf_silence_rest(sbuf_t* sbuf) {
|
|||
sbuf_silence_part(sbuf, sbuf->filled, sbuf->samples - sbuf->filled);
|
||||
}
|
||||
|
||||
|
||||
|
||||
typedef void (*sbuf_copy_t)(void* vsrc, void* vdst, int src_pos, int dst_pos, int src_max);
|
||||
|
||||
// Ugly generic copy function definition with different parameters, to avoid repeating code.
|
||||
// Must define various functions below, to be set in the copy matrix.
|
||||
// Uses void params to allow callbacks.
|
||||
#define DEFINE_SBUF_COPY(suffix, srctype, dsttype, func) \
|
||||
static void sbuf_copy_##suffix(void* vsrc, void* vdst, int src_pos, int dst_pos, int src_max) { \
|
||||
srctype* src = vsrc; \
|
||||
dsttype* dst = vdst; \
|
||||
while (src_pos < src_max) { \
|
||||
dst[dst_pos++] = func(src[src_pos++]); \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DEFINE_SBUF_CP24(suffix, srctype, dsttype, func) \
|
||||
static void sbuf_copy_##suffix(void* vsrc, void* vdst, int src_pos, int dst_pos, int src_max) { \
|
||||
srctype* src = vsrc; \
|
||||
dsttype* dst = vdst; \
|
||||
while (src_pos < src_max) { \
|
||||
put_u24ne(dst + dst_pos, func(src[src_pos++]) ); \
|
||||
dst_pos += 3; \
|
||||
} \
|
||||
}
|
||||
|
||||
DEFINE_SBUF_COPY(s16_s16, int16_t, int16_t, CONV_NOOP);
|
||||
DEFINE_SBUF_COPY(s16_f16, int16_t, float, CONV_NOOP);
|
||||
DEFINE_SBUF_COPY(s16_flt, int16_t, float, CONV_S16_FLT);
|
||||
DEFINE_SBUF_COPY(s16_s24, int16_t, int32_t, CONV_S16_S24);
|
||||
DEFINE_SBUF_COPY(s16_s32, int16_t, int32_t, CONV_S16_S32);
|
||||
DEFINE_SBUF_CP24(s16_o24, int16_t, uint8_t, CONV_S16_S24);
|
||||
|
||||
DEFINE_SBUF_COPY(f16_s16, float, int16_t, CONV_F16_S16);
|
||||
DEFINE_SBUF_COPY(f16_f16, float, float, CONV_NOOP);
|
||||
DEFINE_SBUF_COPY(f16_flt, float, float, CONV_F16_FLT);
|
||||
DEFINE_SBUF_COPY(f16_s24, float, int32_t, CONV_F16_S24);
|
||||
DEFINE_SBUF_COPY(f16_s32, float, int32_t, CONV_F16_S32);
|
||||
DEFINE_SBUF_CP24(f16_o24, float, uint8_t, CONV_F16_S24);
|
||||
|
||||
DEFINE_SBUF_COPY(flt_s16, float, int16_t, CONV_FLT_S16);
|
||||
DEFINE_SBUF_COPY(flt_f16, float, float, CONV_FLT_F16);
|
||||
DEFINE_SBUF_COPY(flt_flt, float, float, CONV_NOOP);
|
||||
DEFINE_SBUF_COPY(flt_s24, float, int32_t, CONV_FLT_S24);
|
||||
DEFINE_SBUF_COPY(flt_s32, float, int32_t, CONV_FLT_S32);
|
||||
DEFINE_SBUF_CP24(flt_o24, float, uint8_t, CONV_FLT_S24);
|
||||
|
||||
DEFINE_SBUF_COPY(s24_s16, int32_t, int16_t, CONV_S24_S16);
|
||||
DEFINE_SBUF_COPY(s24_f16, int32_t, float, CONV_S24_F16);
|
||||
DEFINE_SBUF_COPY(s24_flt, int32_t, float, CONV_S24_FLT);
|
||||
DEFINE_SBUF_COPY(s24_s24, int32_t, int32_t, CONV_NOOP);
|
||||
DEFINE_SBUF_COPY(s24_s32, int32_t, int32_t, CONV_S24_S32);
|
||||
DEFINE_SBUF_CP24(s24_o24, int32_t, uint8_t, CONV_NOOP);
|
||||
|
||||
DEFINE_SBUF_COPY(s32_s16, int32_t, int16_t, CONV_S32_S16);
|
||||
DEFINE_SBUF_COPY(s32_f16, int32_t, float, CONV_S32_F16);
|
||||
DEFINE_SBUF_COPY(s32_flt, int32_t, float, CONV_S32_FLT);
|
||||
DEFINE_SBUF_COPY(s32_s24, int32_t, int32_t, CONV_S32_S24);
|
||||
DEFINE_SBUF_COPY(s32_s32, int32_t, int32_t, CONV_NOOP);
|
||||
DEFINE_SBUF_CP24(s32_o24, int32_t, uint8_t, CONV_S32_S24);
|
||||
|
||||
static sbuf_copy_t copy_matrix[SFMT_MAX][SFMT_MAX] = {
|
||||
{ NULL, NULL, NULL, NULL, NULL }, //NONE
|
||||
{ NULL, sbuf_copy_s16_s16, sbuf_copy_s16_f16, sbuf_copy_s16_flt, sbuf_copy_s16_s24, sbuf_copy_s16_s32, sbuf_copy_s16_o24 },
|
||||
{ NULL, sbuf_copy_f16_s16, sbuf_copy_f16_f16, sbuf_copy_f16_flt, sbuf_copy_f16_s24, sbuf_copy_f16_s32, sbuf_copy_f16_o24 },
|
||||
{ NULL, sbuf_copy_flt_s16, sbuf_copy_flt_f16, sbuf_copy_flt_flt, sbuf_copy_flt_s24, sbuf_copy_flt_s32, sbuf_copy_flt_o24 },
|
||||
{ NULL, sbuf_copy_s24_s16, sbuf_copy_s24_f16, sbuf_copy_s24_flt, sbuf_copy_s24_s24, sbuf_copy_s24_s32, sbuf_copy_s24_o24 },
|
||||
{ NULL, sbuf_copy_s32_s16, sbuf_copy_s32_f16, sbuf_copy_s32_flt, sbuf_copy_s32_s24, sbuf_copy_s32_s32, sbuf_copy_s32_o24 },
|
||||
{ NULL, NULL, NULL, NULL, NULL }, //O24
|
||||
};
|
||||
|
||||
|
||||
// copy N samples from ssrc into dst (should be clamped externally)
|
||||
//TODO: may want to handle sdst->flled + samples externally?
|
||||
void sbuf_copy_segments(sbuf_t* sdst, sbuf_t* ssrc, int samples) {
|
||||
// rarely when decoding with empty frames, may not setup ssrc
|
||||
if (samples == 0)
|
||||
return;
|
||||
|
||||
if (ssrc->channels != sdst->channels) {
|
||||
// 0'd other channels first (uncommon so probably fine albeit slower-ish)
|
||||
sbuf_silence_part(sdst, sdst->filled, samples);
|
||||
sbuf_copy_layers(sdst, ssrc, 0, samples);
|
||||
#if 0
|
||||
// "faster" but lots of extra ifs per sample format, not worth it
|
||||
while (src_pos < src_max) {
|
||||
for (int ch = 0; ch < dst_channels; ch++) {
|
||||
dst[dst_pos++] = ch >= src_channels ? 0 : src[src_pos++];
|
||||
}
|
||||
}
|
||||
#endif
|
||||
sdst->filled += samples;
|
||||
return;
|
||||
}
|
||||
|
||||
sbuf_copy_t sbuf_copy_src_dst = copy_matrix[ssrc->fmt][sdst->fmt];
|
||||
if (!sbuf_copy_src_dst) {
|
||||
VGM_LOG("SBUF: undefined copy function sfmt %i to %i\n", ssrc->fmt, sdst->fmt);
|
||||
sdst->filled += samples;
|
||||
return;
|
||||
}
|
||||
|
||||
int src_pos = 0;
|
||||
int dst_pos = sdst->filled * sdst->channels;
|
||||
int src_max = samples * ssrc->channels;
|
||||
|
||||
sbuf_copy_src_dst(ssrc->buf, sdst->buf, src_pos, dst_pos, src_max);
|
||||
sdst->filled += samples;
|
||||
}
|
||||
|
||||
typedef void (*sbuf_layer_t)(void* vsrc, void* vdst, int src_pos, int dst_pos, int src_max, int dst_expected, int src_channels, int dst_channels);
|
||||
|
||||
// See above
|
||||
#define DEFINE_SBUF_LAYER(suffix, srctype, dsttype, func) \
|
||||
static void sbuf_layer_##suffix(void* vsrc, void* vdst, int src_pos, int dst_pos, int src_filled, int dst_expected, int src_channels, int dst_channels) { \
|
||||
srctype* src = vsrc; \
|
||||
dsttype* dst = vdst; \
|
||||
int dst_ch_step = (dst_channels - src_channels); \
|
||||
for (int s = 0; s < src_filled; s++) { \
|
||||
for (int src_ch = 0; src_ch < src_channels; src_ch++) { \
|
||||
dst[dst_pos++] = func(src[src_pos++]); \
|
||||
} \
|
||||
dst_pos += dst_ch_step; \
|
||||
} \
|
||||
\
|
||||
for (int s = src_filled; s < dst_expected; s++) { \
|
||||
for (int src_ch = 0; src_ch < src_channels; src_ch++) { \
|
||||
dst[dst_pos++] = 0; \
|
||||
} \
|
||||
dst_pos += dst_ch_step; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DEFINE_SBUF_LYR24(suffix, srctype, dsttype, func) \
|
||||
static void sbuf_layer_##suffix(void* vsrc, void* vdst, int src_pos, int dst_pos, int src_filled, int dst_expected, int src_channels, int dst_channels) { \
|
||||
srctype* src = vsrc; \
|
||||
dsttype* dst = vdst; \
|
||||
int dst_ch_step = (dst_channels - src_channels); \
|
||||
for (int s = 0; s < src_filled; s++) { \
|
||||
for (int src_ch = 0; src_ch < src_channels; src_ch++) { \
|
||||
put_u24ne(dst + dst_pos, func(src[src_pos++]) ); \
|
||||
dst_pos += 3; \
|
||||
} \
|
||||
dst_pos += dst_ch_step * 3; \
|
||||
} \
|
||||
\
|
||||
for (int s = src_filled; s < dst_expected; s++) { \
|
||||
for (int src_ch = 0; src_ch < src_channels; src_ch++) { \
|
||||
put_u24ne(dst + dst_pos, 0); \
|
||||
dst_pos += 3; \
|
||||
} \
|
||||
dst_pos += dst_ch_step * 3; \
|
||||
} \
|
||||
}
|
||||
|
||||
DEFINE_SBUF_LAYER(s16_s16, int16_t, int16_t, CONV_NOOP);
|
||||
DEFINE_SBUF_LAYER(s16_f16, int16_t, float, CONV_NOOP);
|
||||
DEFINE_SBUF_LAYER(s16_flt, int16_t, float, CONV_S16_FLT);
|
||||
DEFINE_SBUF_LAYER(s16_s24, int16_t, int32_t, CONV_S16_S24);
|
||||
DEFINE_SBUF_LAYER(s16_s32, int16_t, int32_t, CONV_S16_S32);
|
||||
DEFINE_SBUF_LYR24(s16_o24, int16_t, uint8_t, CONV_S16_S24);
|
||||
|
||||
DEFINE_SBUF_LAYER(f16_s16, float, int16_t, CONV_F16_S16);
|
||||
DEFINE_SBUF_LAYER(f16_f16, float, float, CONV_NOOP);
|
||||
DEFINE_SBUF_LAYER(f16_flt, float, float, CONV_F16_FLT);
|
||||
DEFINE_SBUF_LAYER(f16_s24, float, int32_t, CONV_F16_S24);
|
||||
DEFINE_SBUF_LAYER(f16_s32, float, int32_t, CONV_F16_S32);
|
||||
DEFINE_SBUF_LYR24(f16_o24, float, uint8_t, CONV_F16_S24);
|
||||
|
||||
DEFINE_SBUF_LAYER(flt_s16, float, int16_t, CONV_FLT_S16);
|
||||
DEFINE_SBUF_LAYER(flt_f16, float, float, CONV_FLT_F16);
|
||||
DEFINE_SBUF_LAYER(flt_flt, float, float, CONV_NOOP);
|
||||
DEFINE_SBUF_LAYER(flt_s24, float, int32_t, CONV_FLT_S24);
|
||||
DEFINE_SBUF_LAYER(flt_s32, float, int32_t, CONV_FLT_S32);
|
||||
DEFINE_SBUF_LYR24(flt_o24, float, uint8_t, CONV_FLT_S24);
|
||||
|
||||
DEFINE_SBUF_LAYER(s24_s16, int32_t, int16_t, CONV_S24_S16);
|
||||
DEFINE_SBUF_LAYER(s24_f16, int32_t, float, CONV_S24_F16);
|
||||
DEFINE_SBUF_LAYER(s24_flt, int32_t, float, CONV_S24_FLT);
|
||||
DEFINE_SBUF_LAYER(s24_s24, int32_t, int32_t, CONV_NOOP);
|
||||
DEFINE_SBUF_LAYER(s24_s32, int32_t, int32_t, CONV_S24_S32);
|
||||
DEFINE_SBUF_LYR24(s24_o24, int32_t, uint8_t, CONV_NOOP);
|
||||
|
||||
DEFINE_SBUF_LAYER(s32_s16, int32_t, int16_t, CONV_S32_S16);
|
||||
DEFINE_SBUF_LAYER(s32_f16, int32_t, float, CONV_S32_F16);
|
||||
DEFINE_SBUF_LAYER(s32_flt, int32_t, float, CONV_S32_FLT);
|
||||
DEFINE_SBUF_LAYER(s32_s24, int32_t, int32_t, CONV_S32_S24);
|
||||
DEFINE_SBUF_LAYER(s32_s32, int32_t, int32_t, CONV_NOOP);
|
||||
DEFINE_SBUF_LYR24(s32_o24, int32_t, uint8_t, CONV_NOOP);
|
||||
|
||||
static sbuf_layer_t layer_matrix[SFMT_MAX][SFMT_MAX] = {
|
||||
{ NULL, NULL, NULL, NULL, NULL }, //NONE
|
||||
{ NULL, sbuf_layer_s16_s16, sbuf_layer_s16_f16, sbuf_layer_s16_flt, sbuf_layer_s16_s24, sbuf_layer_s16_s32, sbuf_layer_s16_o24 },
|
||||
{ NULL, sbuf_layer_f16_s16, sbuf_layer_f16_f16, sbuf_layer_f16_flt, sbuf_layer_f16_s24, sbuf_layer_f16_s32, sbuf_layer_f16_o24 },
|
||||
{ NULL, sbuf_layer_flt_s16, sbuf_layer_flt_f16, sbuf_layer_flt_flt, sbuf_layer_flt_s24, sbuf_layer_flt_s32, sbuf_layer_flt_o24 },
|
||||
{ NULL, sbuf_layer_s24_s16, sbuf_layer_s24_f16, sbuf_layer_s24_flt, sbuf_layer_s24_s24, sbuf_layer_s24_s32, sbuf_layer_s24_o24 },
|
||||
{ NULL, sbuf_layer_s32_s16, sbuf_layer_s32_f16, sbuf_layer_s32_flt, sbuf_layer_s32_s24, sbuf_layer_s32_s32, sbuf_layer_s32_o24 },
|
||||
{ NULL, NULL, NULL, NULL, NULL }, //O32
|
||||
};
|
||||
|
||||
// copy interleaving: dst ch1 ch2 ch3 ch4 w/ src ch1 ch2 ch1 ch2 = only fill dst ch1 ch2
|
||||
// dst_channels == src_channels isn't likely so ignore that optimization (dst must be >= than src).
|
||||
// dst_ch_start indicates it should write to dst's chN,chN+1,etc
|
||||
// sometimes one layer has less samples than others and need to 0-fill rest up to dst_max
|
||||
void sbuf_copy_layers(sbuf_t* sdst, sbuf_t* ssrc, int dst_ch_start, int dst_max) {
|
||||
int src_pos = 0;
|
||||
int dst_pos = sdst->filled * sdst->channels + dst_ch_start;
|
||||
|
||||
int src_copy = dst_max;
|
||||
if (src_copy > ssrc->filled)
|
||||
src_copy = ssrc->filled;
|
||||
|
||||
if (ssrc->channels > sdst->channels) {
|
||||
VGM_LOG("SBUF: src channels bigger than dst\n");
|
||||
return;
|
||||
}
|
||||
|
||||
sbuf_layer_t sbuf_layer_src_dst = layer_matrix[ssrc->fmt][sdst->fmt];
|
||||
if (!sbuf_layer_src_dst) {
|
||||
VGM_LOG("SBUF: undefined layer function sfmt %i to %i\n", ssrc->fmt, sdst->fmt);
|
||||
return;
|
||||
}
|
||||
|
||||
sbuf_layer_src_dst(ssrc->buf, sdst->buf, src_pos, dst_pos, src_copy, dst_max, ssrc->channels, sdst->channels);
|
||||
}
|
||||
|
||||
|
||||
typedef void (*sbuf_fade_t)(void* vsrc, int start, int to_do, int fade_pos, int fade_duration);
|
||||
|
||||
#define DEFINE_SBUF_FADE(suffix, buftype) \
|
||||
static void sbuf_fade_##suffix(sbuf_t* sbuf, int start, int to_do, int fade_pos, int fade_duration) { \
|
||||
buftype* buf = sbuf->buf; \
|
||||
int s = start * sbuf->channels; \
|
||||
int s_end = (start + to_do) * sbuf->channels; \
|
||||
while (s < s_end) { \
|
||||
float fadedness = (float)(fade_duration - fade_pos) / fade_duration; \
|
||||
for (int i = 0; i < sbuf->channels; i++) { \
|
||||
buf[s] = float_to_int(buf[s] * fadedness); \
|
||||
s++; \
|
||||
} \
|
||||
fade_pos++; \
|
||||
} \
|
||||
}
|
||||
|
||||
#define DEFINE_SBUF_FD24(suffix, buftype) \
|
||||
static void sbuf_fade_##suffix(sbuf_t* sbuf, int start, int to_do, int fade_pos, int fade_duration) { \
|
||||
buftype* buf = sbuf->buf; \
|
||||
int s = start * sbuf->channels; \
|
||||
int s_end = (start + to_do) * sbuf->channels; \
|
||||
while (s < s_end) { \
|
||||
float fadedness = (float)(fade_duration - fade_pos) / fade_duration; \
|
||||
for (int i = 0; i < sbuf->channels; i++) { \
|
||||
put_u24ne(buf + s * 3, float_to_int(get_s24ne(buf + s * 3) * fadedness) ); \
|
||||
s++; \
|
||||
} \
|
||||
fade_pos++; \
|
||||
} \
|
||||
}
|
||||
|
||||
DEFINE_SBUF_FADE(i16, int16_t);
|
||||
DEFINE_SBUF_FADE(i32, int32_t);
|
||||
DEFINE_SBUF_FADE(flt, float);
|
||||
DEFINE_SBUF_FD24(o24, uint8_t);
|
||||
|
||||
void sbuf_fadeout(sbuf_t* sbuf, int start, int to_do, int fade_pos, int fade_duration) {
|
||||
//TODO: use interpolated fadedness to improve performance?
|
||||
//TODO: use float fadedness?
|
||||
|
||||
int s = start * sbuf->channels;
|
||||
int s_end = (start + to_do) * sbuf->channels;
|
||||
|
||||
|
||||
switch(sbuf->fmt) {
|
||||
case SFMT_S16: {
|
||||
int16_t* buf = sbuf->buf;
|
||||
while (s < s_end) {
|
||||
double fadedness = (double)(fade_duration - fade_pos) / fade_duration;
|
||||
fade_pos++;
|
||||
|
||||
for (int ch = 0; ch < sbuf->channels; ch++) {
|
||||
buf[s] = double_to_int(buf[s] * fadedness);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
case SFMT_S16:
|
||||
sbuf_fade_i16(sbuf, start, to_do, fade_pos, fade_duration);
|
||||
break;
|
||||
case SFMT_S24:
|
||||
case SFMT_S32:
|
||||
sbuf_fade_i32(sbuf, start, to_do, fade_pos, fade_duration);
|
||||
break;
|
||||
}
|
||||
|
||||
case SFMT_FLT:
|
||||
case SFMT_F32: {
|
||||
float* buf = sbuf->buf;
|
||||
while (s < s_end) {
|
||||
double fadedness = (double)(fade_duration - fade_pos) / fade_duration;
|
||||
fade_pos++;
|
||||
|
||||
for (int ch = 0; ch < sbuf->channels; ch++) {
|
||||
buf[s] = double_to_float(buf[s] * fadedness);
|
||||
s++;
|
||||
}
|
||||
}
|
||||
case SFMT_F16:
|
||||
sbuf_fade_flt(sbuf, start, to_do, fade_pos, fade_duration);
|
||||
break;
|
||||
case SFMT_O24:
|
||||
sbuf_fade_o24(sbuf, start, to_do, fade_pos, fade_duration);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
VGM_LOG("SBUF: missing fade for fmt=%i\n", sbuf->fmt);
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -505,3 +528,46 @@ void sbuf_interleave(sbuf_t* sbuf, float** ibuf) {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* vorbis encodes channels in non-standard order, so we remap during conversion to fix this oddity.
|
||||
* (feels a bit weird as one would think you could leave as-is and set the player's output order,
|
||||
* but that isn't possible and remapping like this is what FFmpeg and every other plugin does). */
|
||||
static const int xiph_channel_map[8][8] = {
|
||||
{ 0 }, // 1ch: FC > same
|
||||
{ 0, 1 }, // 2ch: FL FR > same
|
||||
{ 0, 2, 1 }, // 3ch: FL FC FR > FL FR FC
|
||||
{ 0, 1, 2, 3 }, // 4ch: FL FR BL BR > same
|
||||
{ 0, 2, 1, 3, 4 }, // 5ch: FL FC FR BL BR > FL FR FC BL BR
|
||||
{ 0, 2, 1, 5, 3, 4 }, // 6ch: FL FC FR BL BR LFE > FL FR FC LFE BL BR
|
||||
{ 0, 2, 1, 6, 5, 3, 4 }, // 7ch: FL FC FR SL SR BC LFE > FL FR FC LFE BC SL SR
|
||||
{ 0, 2, 1, 7, 5, 6, 3, 4 }, // 8ch: FL FC FR SL SR BL BR LFE > FL FR FC LFE BL BR SL SR
|
||||
};
|
||||
|
||||
// converts from internal Vorbis format to standard PCM and remaps (mostly from Xiph's decoder_example.c)
|
||||
void sbuf_interleave_vorbis(sbuf_t* sbuf, float** src) {
|
||||
if (sbuf->fmt != SFMT_FLT)
|
||||
return;
|
||||
int channels = sbuf->channels;
|
||||
|
||||
/* convert float PCM (multichannel float array, with pcm[0]=ch0, pcm[1]=ch1, pcm[2]=ch0, etc)
|
||||
* to 16 bit signed PCM ints (host order) and interleave + fix clipping */
|
||||
for (int ch = 0; ch < channels; ch++) {
|
||||
int ch_map = (channels > 8) ? ch : xiph_channel_map[channels - 1][ch]; // put Vorbis' ch to other outbuf's ch
|
||||
float* ptr = sbuf->buf;
|
||||
float* channel = src[ch_map];
|
||||
|
||||
ptr += ch;
|
||||
for (int s = 0; s < sbuf->filled; s++) {
|
||||
float val = channel[s];
|
||||
|
||||
#if 0 //to pcm16 from vorbis
|
||||
int val = (int)floor(channel[s] * 32767.0f + 0.5f);
|
||||
if (val > 32767) val = 32767;
|
||||
else if (val < -32768) val = -32768;
|
||||
#endif
|
||||
|
||||
*ptr = val;
|
||||
ptr += channels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,29 +11,33 @@
|
|||
* rather than planar (buffer per channel = [ch][s] = c1 c1 c1 c1 ... c2 c2 c2 c2 ...) */
|
||||
typedef enum {
|
||||
SFMT_NONE,
|
||||
SFMT_S16, /* standard PCM16 */
|
||||
//SFMT_S24,
|
||||
//SFMT_S32,
|
||||
SFMT_F32, /* pcm-like float (+-32768), for internal use (simpler pcm > f32 plus some decoders use this) */
|
||||
SFMT_FLT, /* standard float (+-1.0), for external players */
|
||||
SFMT_S16, // PCM16
|
||||
SFMT_F16, // PCM16-like float (+-32767.0f), for internal use (simpler s16 <> f16, plus some decoders use it)
|
||||
SFMT_FLT, // standard float (+-1.0), for external players
|
||||
SFMT_S24, // PCM24 for internal use (32-bit buffers)
|
||||
SFMT_S32, // PCM32
|
||||
|
||||
SFMT_O24, // PCM24 LE for output (24-bit buffers), for external use only (can't handle as a regular buf internally)
|
||||
|
||||
SFMT_MAX,
|
||||
} sfmt_t;
|
||||
|
||||
|
||||
/* simple buffer info to pass around, for internal mixing
|
||||
* meant to held existing sound buffer pointers rather than alloc'ing directly (some ops will swap/move its internals) */
|
||||
typedef struct {
|
||||
void* buf; /* current sample buffer */
|
||||
sfmt_t fmt; /* buffer type */
|
||||
int channels; /* interleaved step or planar buffers */
|
||||
int samples; /* max samples */
|
||||
int filled; /* samples in buffer */
|
||||
void* buf; // current sample buffer
|
||||
sfmt_t fmt; // buffer type
|
||||
int channels; // interleaved step or planar buffers
|
||||
int samples; // max samples
|
||||
int filled; // samples in buffer
|
||||
} sbuf_t;
|
||||
|
||||
/* it's probably slightly faster to make some function inline'd, but aren't called that often to matter (given big enough total samples) */
|
||||
|
||||
void sbuf_init(sbuf_t* sbuf, sfmt_t format, void* buf, int samples, int channels);
|
||||
void sbuf_init_s16(sbuf_t* sbuf, int16_t* buf, int samples, int channels);
|
||||
void sbuf_init_f32(sbuf_t* sbuf, float* buf, int samples, int channels);
|
||||
void sbuf_init_f16(sbuf_t* sbuf, float* buf, int samples, int channels);
|
||||
void sbuf_init_flt(sbuf_t* sbuf, float* buf, int samples, int channels);
|
||||
|
||||
int sfmt_get_sample_size(sfmt_t fmt);
|
||||
|
@ -46,17 +50,15 @@ void sbuf_consume(sbuf_t* sbuf, int count);
|
|||
/* helpers to copy between buffers; note they assume dst and src aren't the same buf */
|
||||
int sbuf_get_copy_max(sbuf_t* sdst, sbuf_t* ssrc);
|
||||
|
||||
void sbuf_copy_to_f32(float* dst, sbuf_t* sbuf);
|
||||
void sbuf_copy_from_f32(sbuf_t* sbuf, float* src);
|
||||
void sbuf_copy_segments(sbuf_t* sdst, sbuf_t* ssrc, int samples_copy);
|
||||
void sbuf_copy_layers(sbuf_t* sdst, sbuf_t* ssrc, int dst_ch_start, int expected);
|
||||
|
||||
void sbuf_silence_s16(sample_t* dst, int samples, int channels, int filled);
|
||||
void sbuf_silence_rest(sbuf_t* sbuf);
|
||||
void sbuf_silence_part(sbuf_t* sbuf, int from, int count);
|
||||
|
||||
void sbuf_fadeout(sbuf_t* sbuf, int start, int to_do, int fade_pos, int fade_duration);
|
||||
|
||||
void sbuf_interleave(sbuf_t* sbuf, float** ibuf);
|
||||
void sbuf_interleave_vorbis(sbuf_t* sbuf, float** ibuf);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -92,18 +92,15 @@ void decode_pcm8_unsigned_int(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int ch
|
|||
void decode_pcm8_sb(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_pcm4(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_pcm4_unsigned(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||
void decode_ulaw(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_ulaw_int(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_alaw(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_pcmfloat(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int big_endian);
|
||||
void decode_pcm24le(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_pcm24be(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_pcm32le(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
int32_t pcm_bytes_to_samples(size_t bytes, int channels, int bits_per_sample);
|
||||
int32_t pcm24_bytes_to_samples(size_t bytes, int channels);
|
||||
int32_t pcm16_bytes_to_samples(size_t bytes, int channels);
|
||||
int32_t pcm8_bytes_to_samples(size_t bytes, int channels);
|
||||
|
||||
/* pcm_decoder */
|
||||
void decode_ulaw(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_ulaw_int(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
void decode_alaw(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
|
||||
/* psx_decoder */
|
||||
void decode_psx(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int is_badflags, int config);
|
||||
|
@ -382,6 +379,7 @@ void* init_mio(STREAMFILE* sf, int* p_loop_point);
|
|||
#ifdef VGM_USE_VORBIS
|
||||
/* ogg_vorbis_decoder */
|
||||
typedef struct ogg_vorbis_codec_data ogg_vorbis_codec_data;
|
||||
|
||||
typedef struct { //todo simplify
|
||||
STREAMFILE *streamfile;
|
||||
int64_t start; /* file offset where the Ogg starts */
|
||||
|
@ -396,16 +394,12 @@ typedef struct { //todo simplify
|
|||
} ogg_vorbis_io;
|
||||
|
||||
ogg_vorbis_codec_data* init_ogg_vorbis(STREAMFILE* sf, off_t start, off_t size, ogg_vorbis_io* io);
|
||||
void decode_ogg_vorbis(ogg_vorbis_codec_data* data, sample_t* outbuf, int32_t samples_to_do, int channels);
|
||||
void reset_ogg_vorbis(ogg_vorbis_codec_data* data);
|
||||
void seek_ogg_vorbis(ogg_vorbis_codec_data* data, int32_t num_sample);
|
||||
void free_ogg_vorbis(ogg_vorbis_codec_data* data);
|
||||
|
||||
int ogg_vorbis_get_comment(ogg_vorbis_codec_data* data, const char** comment);
|
||||
void ogg_vorbis_get_info(ogg_vorbis_codec_data* data, int* p_channels, int* p_sample_rate);
|
||||
void ogg_vorbis_get_samples(ogg_vorbis_codec_data* data, int* p_samples);
|
||||
void ogg_vorbis_set_disable_reordering(ogg_vorbis_codec_data* data, int set);
|
||||
void ogg_vorbis_set_force_seek(ogg_vorbis_codec_data* data, int set);
|
||||
void ogg_vorbis_set_disable_reordering(ogg_vorbis_codec_data* data, bool set);
|
||||
void ogg_vorbis_set_force_seek(ogg_vorbis_codec_data* data, bool set);
|
||||
STREAMFILE* ogg_vorbis_get_streamfile(ogg_vorbis_codec_data* data);
|
||||
|
||||
|
||||
|
@ -699,7 +693,7 @@ typedef struct {
|
|||
int frame_samples;
|
||||
} mp4_custom_t;
|
||||
|
||||
ffmpeg_codec_data* init_ffmpeg_mp4_custom_std(STREAMFILE* sf, mp4_custom_t* mp4);
|
||||
ffmpeg_codec_data* init_ffmpeg_mp4_custom_ktac(STREAMFILE* sf, mp4_custom_t* mp4);
|
||||
ffmpeg_codec_data* init_ffmpeg_mp4_custom_lyn(STREAMFILE* sf, mp4_custom_t* mp4);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -763,7 +763,7 @@ static void samples_dblp_to_s16(sample_t* obuf, double** inbuf, int ichs, int sa
|
|||
}
|
||||
}
|
||||
|
||||
static void copy_samples(ffmpeg_codec_data* data, sample_t* outbuf, int samples_to_do) {
|
||||
static void copy_samples(ffmpeg_codec_data* data, sample_t* outbuf, int samples_to_do, int max_channels) {
|
||||
#if LIBAVCODEC_VERSION_INT < AV_VERSION_INT(59, 24, 100)
|
||||
int channels = data->codecCtx->channels;
|
||||
#else
|
||||
|
@ -779,6 +779,12 @@ static void copy_samples(ffmpeg_codec_data* data, sample_t* outbuf, int samples_
|
|||
ibuf = data->frame->data[0];
|
||||
}
|
||||
|
||||
// decoder may return more channels than expected in rare/buggy cases
|
||||
if (channels > max_channels) {
|
||||
VGM_LOG_ONCE("FFMPEG: buggy channels\n");
|
||||
channels = max_channels;
|
||||
}
|
||||
|
||||
switch (data->codecCtx->sample_fmt) {
|
||||
/* unused? */
|
||||
case AV_SAMPLE_FMT_U8P: if (is_planar) { samples_u8p_to_s16(outbuf, ibuf, channels, samples_to_do, data->samples_consumed); break; }
|
||||
|
@ -835,7 +841,7 @@ void decode_ffmpeg(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do
|
|||
if (samples_to_get > samples_to_do)
|
||||
samples_to_get = samples_to_do;
|
||||
|
||||
copy_samples(data, outbuf, samples_to_get);
|
||||
copy_samples(data, outbuf, samples_to_get, channels);
|
||||
|
||||
samples_to_do -= samples_to_get;
|
||||
outbuf += samples_to_get * channels;
|
||||
|
|
|
@ -4,7 +4,7 @@
|
|||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
|
||||
typedef enum { MP4_STD, MP4_LYN } mp4_type_t;
|
||||
typedef enum { MP4_KTAC, MP4_LYN } mp4_type_t;
|
||||
|
||||
/**
|
||||
* Makes a MP4 header for MP4 raw data with a separate frame table, simulating a real MP4 that
|
||||
|
@ -54,7 +54,7 @@ static void add_u16b(m4a_header_t* h, uint16_t value) {
|
|||
h->bytes += 0x02;
|
||||
}
|
||||
|
||||
static void add_u8(m4a_header_t* h, uint32_t value) {
|
||||
static void add_u8b(m4a_header_t* h, uint32_t value) {
|
||||
put_u8(h->out, value);
|
||||
h->out += 0x01;
|
||||
h->bytes += 0x01;
|
||||
|
@ -77,7 +77,7 @@ static void save_atom(m4a_header_t* h, m4a_state_t* s) {
|
|||
s->bytes = h->bytes;
|
||||
}
|
||||
|
||||
static void load_atom(m4a_header_t* h, m4a_state_t* s) {
|
||||
static void mend_atom(m4a_header_t* h, m4a_state_t* s) {
|
||||
put_u32be(s->out, h->bytes - s->bytes);
|
||||
}
|
||||
|
||||
|
@ -172,6 +172,7 @@ static void add_stts(m4a_header_t* h) {
|
|||
/* from mpeg4audio.c (also see ff_mp4_read_dec_config_descr) */
|
||||
static const int m4a_sample_rates[16] = {
|
||||
96000, 88200, 64000, 48000, 44100, 32000, 24000, 22050, 16000, 12000, 11025, 8000, 7350
|
||||
// index 15 means sample rate is stored in 24-bit after index
|
||||
};
|
||||
static const uint8_t m4a_channels[14] = {
|
||||
0,
|
||||
|
@ -191,64 +192,88 @@ static const uint8_t m4a_channels[14] = {
|
|||
};
|
||||
|
||||
static void add_esds(m4a_header_t* h) {
|
||||
uint16_t config = 0;
|
||||
|
||||
/* ES_descriptor (TLV format see ISO 14496-1) and DecSpecificInfoTag define actual decoding
|
||||
- config (channels/rate/etc), other atoms with the same stuff is just info
|
||||
* - http://ecee.colorado.edu/~ecen5653/ecen5653/papers/ISO%2014496-1%202004.PDF */
|
||||
|
||||
{
|
||||
uint8_t object_type = 0x02; /* 0x00=none, 0x01=AAC main, 0x02=AAC LC */
|
||||
uint8_t sr_index = 0;
|
||||
uint8_t ch_index = 0;
|
||||
uint8_t unknown = 0;
|
||||
int i;
|
||||
for (i = 0; i < 16; i++) {
|
||||
if (m4a_sample_rates[i] == h->mp4->sample_rate) {
|
||||
sr_index = i;
|
||||
break;
|
||||
}
|
||||
* config (channels/rate/etc), other atoms with the same stuff is just info
|
||||
* - see ISO/IEC 14496-3:2001 > 1.6.2. Syntax (AudioSpecificConfig + GASpecificConfig) */
|
||||
uint16_t config = 0;
|
||||
uint8_t object_type = 0x02; /* 0x00=none, 0x01=AAC main, 0x02=AAC LC, etc */
|
||||
uint8_t sr_index = 0;
|
||||
uint8_t ch_index = 0;
|
||||
uint8_t extra = 0;
|
||||
for (int i = 0; i < 16; i++) {
|
||||
if (m4a_sample_rates[i] == h->mp4->sample_rate) {
|
||||
sr_index = i;
|
||||
break;
|
||||
}
|
||||
for (i = 0; i < 8; i++) {
|
||||
if (m4a_channels[i] == h->mp4->channels) {
|
||||
ch_index = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (int i = 0; i < 8; i++) {
|
||||
if (m4a_channels[i] == h->mp4->channels) {
|
||||
ch_index = i;
|
||||
break;
|
||||
}
|
||||
|
||||
config |= (object_type & 0x1F) << 11; /* 5b */
|
||||
config |= (sr_index & 0x0F) << 7; /* 4b */
|
||||
config |= (ch_index & 0x0F) << 3; /* 4b */
|
||||
config |= (unknown & 0x07) << 0; /* 3b */
|
||||
}
|
||||
|
||||
add_atom(h, "esds", 0x33);
|
||||
extra = 0 ; // frameLength (1b) + dependsOnCoreCoder (1b) + extensionFlag (1b)
|
||||
|
||||
// KTAC uses 'quad' (2/2) rather than standard 4.0 (3/1) [Winning Post 9 2022 (PC)]
|
||||
if (h->mp4->channels == 4 && h->type == MP4_KTAC) {
|
||||
ch_index = 0;
|
||||
}
|
||||
|
||||
config |= (object_type & 0x1F) << 11; /* 5b */
|
||||
config |= (sr_index & 0x0F) << 7; /* 4b */
|
||||
config |= (ch_index & 0x0F) << 3; /* 4b */
|
||||
config |= (extra & 0x07) << 0; /* 3b */
|
||||
|
||||
uint8_t slcfg_size = 0x01;
|
||||
uint8_t config_size = 0x02 + (ch_index == 0 ? 0x07 : 0x00);
|
||||
uint8_t deccfg_size = 0x14;
|
||||
uint8_t descr_size = 0x03 + 0x08 + deccfg_size + config_size + slcfg_size;
|
||||
|
||||
m4a_state_t s;
|
||||
|
||||
save_atom(h, &s);
|
||||
add_atom(h, "esds", 0x00);
|
||||
add_u32b(h, 0); /* Version (1 byte) + Flags (3 byte) */
|
||||
|
||||
add_u8 (h, 0x03); /* ES_DescrTag */
|
||||
add_u32b(h, 0x80808022); /* size 0x22 */
|
||||
add_u8b (h, 0x03); /* ES_DescrTag */
|
||||
add_u32b(h, 0x80808000 + descr_size); /* tag size (all subtags) */
|
||||
add_u16b(h, 0x0000); /* stream Id */
|
||||
add_u8 (h, 0x00); /* flags */
|
||||
add_u8b (h, 0x00); /* flags */
|
||||
|
||||
add_u8 (h, 0x04); /* DecoderConfigDescrTag */
|
||||
add_u32b(h, 0x80808014); /* size 0x14 */
|
||||
add_u8 (h, 0x40); /* object type (0x40=audio) */
|
||||
add_u8 (h, 0x15); /* stream type (6b: 0x5=audio) + upstream (1b) + reserved (1b: const 1) */
|
||||
add_u8b (h, 0x04); /* DecoderConfigDescrTag */
|
||||
add_u32b(h, 0x80808000 + deccfg_size); /* subtag size */
|
||||
add_u8b (h, 0x40); /* object type (0x40=audio) */
|
||||
add_u8b (h, 0x15); /* stream type (6b: 0x5=audio) + upstream (1b) + reserved (1b: const 1) */
|
||||
add_u24b(h, 0x000000); /* buffer size */
|
||||
add_u32b(h, 0); /* max bitrate (256000?)*/
|
||||
add_u32b(h, 0); /* average bitrate (256000?) */
|
||||
|
||||
add_u8 (h, 0x05); /* DecSpecificInfoTag */
|
||||
add_u32b(h, 0x80808002); /* size 0x02 */
|
||||
add_u8b (h, 0x05); /* DecSpecificInfoTag */
|
||||
add_u32b(h, 0x80808000 + config_size); /* subtag size */
|
||||
add_u16b(h, config); /* actual decoder info */
|
||||
|
||||
add_u8 (h, 0x06); /* SLConfigDescrTag */
|
||||
add_u32b(h, 0x80808001); /* size 0x01 */
|
||||
add_u8 (h, 0x02); /* predefined (2=default) */
|
||||
// config for quad, abridged (see spec's program_config_element)
|
||||
if (ch_index == 0 && h->mp4->channels == 4) {
|
||||
uint16_t ch_config1 = 0x0004 | (object_type << 10) | (sr_index << 6); // config + channel info (part 1)
|
||||
uint32_t ch_config2 = 0x04002110; // channel info (part 2)
|
||||
uint8_t comment_len = 0x00;
|
||||
add_u16b(h, ch_config1);
|
||||
add_u32b(h, ch_config2);
|
||||
add_u8b (h, comment_len);
|
||||
}
|
||||
|
||||
add_u8b (h, 0x06); /* SLConfigDescrTag */
|
||||
add_u32b(h, 0x80808000 + slcfg_size); /* tag size */
|
||||
add_u8b (h, 0x02); /* predefined (2=default) */
|
||||
mend_atom(h, &s);
|
||||
}
|
||||
|
||||
static void add_mp4a(m4a_header_t* h) {
|
||||
add_atom(h, "mp4a", 0x57);
|
||||
m4a_state_t s;
|
||||
|
||||
save_atom(h, &s);
|
||||
add_atom(h, "mp4a", 0x00);
|
||||
add_u32b(h, 0); /* ? */
|
||||
add_u32b(h, 1); /* Data reference index */
|
||||
add_u32b(h, 0); /* Reserved */
|
||||
|
@ -259,13 +284,18 @@ static void add_mp4a(m4a_header_t* h) {
|
|||
add_u16b(h, h->mp4->sample_rate); /* Sample rate */
|
||||
add_u16b(h, 0); /* ? */
|
||||
add_esds(h); /* elementary stream descriptor */
|
||||
mend_atom(h, &s);
|
||||
}
|
||||
|
||||
static void add_stsd(m4a_header_t* h) {
|
||||
add_atom(h, "stsd", 0x67);
|
||||
m4a_state_t s;
|
||||
|
||||
save_atom(h, &s);
|
||||
add_atom(h, "stsd", 0x00);
|
||||
add_u32b(h, 0); /* Version (1 byte) + Flags (3 byte) */
|
||||
add_u32b(h, 1); /* Number of entries */
|
||||
add_mp4a(h);
|
||||
mend_atom(h, &s);
|
||||
}
|
||||
|
||||
static void add_stbl(m4a_header_t* h) {
|
||||
|
@ -278,7 +308,7 @@ static void add_stbl(m4a_header_t* h) {
|
|||
add_stsc(h); /* Sample-to-chunk */
|
||||
add_stsz(h); /* Sample size */
|
||||
add_stco(h); /* Chunk offset */
|
||||
load_atom(h, &s);
|
||||
mend_atom(h, &s);
|
||||
}
|
||||
|
||||
static void add_dinf(m4a_header_t* h) {
|
||||
|
@ -305,7 +335,7 @@ static void add_minf(m4a_header_t* h) {
|
|||
add_smhd(h);
|
||||
add_dinf(h);
|
||||
add_stbl(h);
|
||||
load_atom(h, &s);
|
||||
mend_atom(h, &s);
|
||||
}
|
||||
|
||||
static void add_hdlr(m4a_header_t* h) {
|
||||
|
@ -338,7 +368,7 @@ static void add_mdia(m4a_header_t* h) {
|
|||
add_mdhd(h);
|
||||
add_hdlr(h);
|
||||
add_minf(h);
|
||||
load_atom(h, &s);
|
||||
mend_atom(h, &s);
|
||||
}
|
||||
|
||||
static void add_tkhd(m4a_header_t* h) {
|
||||
|
@ -375,7 +405,7 @@ static void add_trak(m4a_header_t* h) {
|
|||
add_atom(h, "trak", 0x00);
|
||||
add_tkhd(h);
|
||||
add_mdia(h);
|
||||
load_atom(h, &s);
|
||||
mend_atom(h, &s);
|
||||
}
|
||||
|
||||
static void add_mvhd(m4a_header_t* h) {
|
||||
|
@ -416,7 +446,7 @@ static void add_moov(m4a_header_t* h) {
|
|||
add_mvhd(h);
|
||||
add_trak(h);
|
||||
//add_udta(h);
|
||||
load_atom(h, &s);
|
||||
mend_atom(h, &s);
|
||||
}
|
||||
|
||||
/* *** */
|
||||
|
@ -494,7 +524,7 @@ static ffmpeg_codec_data* init_ffmpeg_mp4_custom(STREAMFILE* sf, mp4_custom_t* m
|
|||
bytes = make_m4a_header(buf, buf_len, mp4, sf, type); /* before changing stream_offset/size */
|
||||
|
||||
switch(type) {
|
||||
case MP4_STD: /* regular raw data */
|
||||
case MP4_KTAC: /* regular raw data */
|
||||
temp_sf = sf;
|
||||
break;
|
||||
case MP4_LYN: /* frames have size before them, but also a seek table */
|
||||
|
@ -523,8 +553,8 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
ffmpeg_codec_data* init_ffmpeg_mp4_custom_std(STREAMFILE* sf, mp4_custom_t* mp4) {
|
||||
return init_ffmpeg_mp4_custom(sf, mp4, MP4_STD);
|
||||
ffmpeg_codec_data* init_ffmpeg_mp4_custom_ktac(STREAMFILE* sf, mp4_custom_t* mp4) {
|
||||
return init_ffmpeg_mp4_custom(sf, mp4, MP4_KTAC);
|
||||
}
|
||||
|
||||
ffmpeg_codec_data* init_ffmpeg_mp4_custom_lyn(STREAMFILE* sf, mp4_custom_t* mp4) {
|
||||
|
|
|
@ -21,77 +21,77 @@
|
|||
|
||||
#define LIBACM_VERSION "1.1"
|
||||
|
||||
#define ACM_ID 0x032897
|
||||
#define ACM_WORD 2
|
||||
#define ACM_ID 0x032897
|
||||
#define ACM_WORD 2
|
||||
|
||||
#define ACM_OK 0
|
||||
#define ACM_ERR_OTHER -1
|
||||
#define ACM_ERR_OPEN -2
|
||||
#define ACM_ERR_NOT_ACM -3
|
||||
#define ACM_ERR_READ_ERR -4
|
||||
#define ACM_ERR_BADFMT -5
|
||||
#define ACM_ERR_CORRUPT -6
|
||||
#define ACM_ERR_UNEXPECTED_EOF -7
|
||||
#define ACM_ERR_NOT_SEEKABLE -8
|
||||
#define ACM_OK 0
|
||||
#define ACM_ERR_OTHER -1
|
||||
#define ACM_ERR_OPEN -2
|
||||
#define ACM_ERR_NOT_ACM -3
|
||||
#define ACM_ERR_READ_ERR -4
|
||||
#define ACM_ERR_BADFMT -5
|
||||
#define ACM_ERR_CORRUPT -6
|
||||
#define ACM_ERR_UNEXPECTED_EOF -7
|
||||
#define ACM_ERR_NOT_SEEKABLE -8
|
||||
|
||||
typedef struct ACMInfo {
|
||||
unsigned channels;
|
||||
unsigned rate;
|
||||
unsigned acm_id;
|
||||
unsigned acm_version;
|
||||
unsigned acm_channels; /* channels from header (usually wrong) */
|
||||
unsigned acm_level;
|
||||
unsigned acm_cols; /* 1 << acm_level */
|
||||
unsigned acm_rows;
|
||||
unsigned channels;
|
||||
unsigned rate;
|
||||
unsigned acm_id;
|
||||
unsigned acm_version;
|
||||
unsigned acm_channels; /* channels from header (usually wrong) */
|
||||
unsigned acm_level;
|
||||
unsigned acm_cols; /* 1 << acm_level */
|
||||
unsigned acm_rows;
|
||||
} ACMInfo;
|
||||
|
||||
typedef struct {
|
||||
/* read bytes */
|
||||
int (*read_func)(void *ptr, int size, int n, void *datasrc);
|
||||
/* optional, must support seeking into start*/
|
||||
int (*seek_func)(void *datasrc, int offset, int whence);
|
||||
/* optional, called on acm_close */
|
||||
int (*close_func)(void *datasrc);
|
||||
/* returns size in bytes*/
|
||||
int (*get_length_func)(void *datasrc);
|
||||
/* read bytes */
|
||||
int (*read_func)(void *ptr, int size, int n, void *datasrc);
|
||||
/* optional, must support seeking into start*/
|
||||
int (*seek_func)(void *datasrc, int offset, int whence);
|
||||
/* optional, called on acm_close */
|
||||
int (*close_func)(void *datasrc);
|
||||
/* returns size in bytes*/
|
||||
int (*get_length_func)(void *datasrc);
|
||||
} acm_io_callbacks;
|
||||
|
||||
struct ACMStream {
|
||||
ACMInfo info;
|
||||
unsigned total_values;
|
||||
ACMInfo info;
|
||||
unsigned total_values;
|
||||
|
||||
/* acm data stream */
|
||||
void *io_arg;
|
||||
acm_io_callbacks io;
|
||||
unsigned data_len;
|
||||
/* acm data stream */
|
||||
void *io_arg;
|
||||
acm_io_callbacks io;
|
||||
unsigned data_len;
|
||||
|
||||
/* acm stream buffer */
|
||||
unsigned char *buf;
|
||||
unsigned buf_max, buf_size, buf_pos, bit_avail;
|
||||
unsigned bit_data;
|
||||
unsigned buf_start_ofs;
|
||||
/* acm stream buffer */
|
||||
unsigned char *buf;
|
||||
unsigned buf_max, buf_size, buf_pos, bit_avail;
|
||||
unsigned bit_data;
|
||||
unsigned buf_start_ofs;
|
||||
|
||||
/* block lengths (in samples) */
|
||||
unsigned block_len;
|
||||
unsigned wrapbuf_len;
|
||||
/* buffers */
|
||||
int *block;
|
||||
int *wrapbuf;
|
||||
int *ampbuf;
|
||||
int *midbuf; /* pointer into ampbuf */
|
||||
/* result */
|
||||
unsigned block_ready:1;
|
||||
unsigned file_eof:1;
|
||||
unsigned wavc_file:1;
|
||||
unsigned stream_pos; /* in words. absolute */
|
||||
unsigned block_pos; /* in words, relative */
|
||||
/* block lengths (in samples) */
|
||||
unsigned block_len;
|
||||
unsigned wrapbuf_len;
|
||||
/* buffers */
|
||||
int *block;
|
||||
int *wrapbuf;
|
||||
int *ampbuf;
|
||||
int *midbuf; /* pointer into ampbuf */
|
||||
/* result */
|
||||
unsigned block_ready:1;
|
||||
unsigned file_eof:1;
|
||||
unsigned wavc_file:1;
|
||||
unsigned stream_pos; /* in words. absolute */
|
||||
unsigned block_pos; /* in words, relative */
|
||||
};
|
||||
typedef struct ACMStream ACMStream;
|
||||
|
||||
/* decode.c */
|
||||
int acm_open_decoder(ACMStream **res, void *io_arg, acm_io_callbacks io, int force_chans);
|
||||
int acm_read(ACMStream *acm, void *buf, unsigned nbytes,
|
||||
int bigendianp, int wordlen, int sgned);
|
||||
int bigendianp, int wordlen, int sgned);
|
||||
void acm_close(ACMStream *acm);
|
||||
|
||||
/* util.c */
|
||||
|
@ -108,7 +108,7 @@ unsigned acm_pcm_tell(ACMStream *acm);
|
|||
unsigned acm_time_total(ACMStream *acm);
|
||||
unsigned acm_time_tell(ACMStream *acm);
|
||||
int acm_read_loop(ACMStream *acm, void *dst, unsigned len,
|
||||
int bigendianp, int wordlen, int sgned);
|
||||
int bigendianp, int wordlen, int sgned);
|
||||
int acm_seek_pcm(ACMStream *acm, unsigned pcm_pos);
|
||||
int acm_seek_time(ACMStream *acm, unsigned pos_ms);
|
||||
const char *acm_strerror(int err);
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -25,30 +25,30 @@
|
|||
|
||||
#include "libacm.h"
|
||||
|
||||
#define WAVC_HEADER_LEN 28
|
||||
#define ACM_HEADER_LEN 14
|
||||
#define WAVC_HEADER_LEN 28
|
||||
#define ACM_HEADER_LEN 14
|
||||
|
||||
/*
|
||||
* error strings
|
||||
*/
|
||||
static const char *_errlist[] = {
|
||||
"No error",
|
||||
"ACM error",
|
||||
"Cannot open file",
|
||||
"Not an ACM file",
|
||||
"Read error",
|
||||
"Bad format",
|
||||
"Corrupt file",
|
||||
"Unexcpected EOF",
|
||||
"Stream not seekable"
|
||||
"No error",
|
||||
"ACM error",
|
||||
"Cannot open file",
|
||||
"Not an ACM file",
|
||||
"Read error",
|
||||
"Bad format",
|
||||
"Corrupt file",
|
||||
"Unexcpected EOF",
|
||||
"Stream not seekable"
|
||||
};
|
||||
|
||||
const char *acm_strerror(int err)
|
||||
{
|
||||
int nerr = sizeof(_errlist) / sizeof(char *);
|
||||
if ((-err) < 0 || (-err) >= nerr)
|
||||
return "Unknown error";
|
||||
return _errlist[-err];
|
||||
int nerr = sizeof(_errlist) / sizeof(char *);
|
||||
if ((-err) < 0 || (-err) >= nerr)
|
||||
return "Unknown error";
|
||||
return _errlist[-err];
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -57,61 +57,61 @@ const char *acm_strerror(int err)
|
|||
|
||||
static int _read_file(void *ptr, int size, int n, void *arg)
|
||||
{
|
||||
FILE *f = (FILE *)arg;
|
||||
return fread(ptr, size, n, f);
|
||||
FILE *f = (FILE *)arg;
|
||||
return fread(ptr, size, n, f);
|
||||
}
|
||||
|
||||
static int _close_file(void *arg)
|
||||
{
|
||||
FILE *f = (FILE *)arg;
|
||||
return fclose(f);
|
||||
FILE *f = (FILE *)arg;
|
||||
return fclose(f);
|
||||
}
|
||||
|
||||
static int _seek_file(void *arg, int offset, int whence)
|
||||
{
|
||||
FILE *f = (FILE *)arg;
|
||||
return fseek(f, offset, whence);
|
||||
FILE *f = (FILE *)arg;
|
||||
return fseek(f, offset, whence);
|
||||
}
|
||||
|
||||
static int _get_length_file(void *arg)
|
||||
{
|
||||
FILE *f = (FILE *)arg;
|
||||
int res, pos, len = -1;
|
||||
FILE *f = (FILE *)arg;
|
||||
int res, pos, len = -1;
|
||||
|
||||
pos = ftell(f);
|
||||
if (pos < 0)
|
||||
return -1;
|
||||
pos = ftell(f);
|
||||
if (pos < 0)
|
||||
return -1;
|
||||
|
||||
res = fseek(f, 0, SEEK_END);
|
||||
if (res >= 0) {
|
||||
len = ftell(f);
|
||||
fseek(f, pos, SEEK_SET);
|
||||
}
|
||||
return len;
|
||||
res = fseek(f, 0, SEEK_END);
|
||||
if (res >= 0) {
|
||||
len = ftell(f);
|
||||
fseek(f, pos, SEEK_SET);
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int acm_open_file(ACMStream **res, const char *filename, int force_chans)
|
||||
{
|
||||
int err;
|
||||
FILE *f;
|
||||
acm_io_callbacks io;
|
||||
ACMStream *acm;
|
||||
int err;
|
||||
FILE *f;
|
||||
acm_io_callbacks io;
|
||||
ACMStream *acm;
|
||||
|
||||
if ((f = fopen(filename, "rb")) == NULL)
|
||||
return ACM_ERR_OPEN;
|
||||
if ((f = fopen(filename, "rb")) == NULL)
|
||||
return ACM_ERR_OPEN;
|
||||
|
||||
memset(&io, 0, sizeof(io));
|
||||
io.read_func = _read_file;
|
||||
io.seek_func = _seek_file;
|
||||
io.close_func = _close_file;
|
||||
io.get_length_func = _get_length_file;
|
||||
memset(&io, 0, sizeof(io));
|
||||
io.read_func = _read_file;
|
||||
io.seek_func = _seek_file;
|
||||
io.close_func = _close_file;
|
||||
io.get_length_func = _get_length_file;
|
||||
|
||||
if ((err = acm_open_decoder(&acm, f, io, force_chans)) < 0) {
|
||||
fclose(f);
|
||||
return err;
|
||||
}
|
||||
*res = acm;
|
||||
return 0;
|
||||
if ((err = acm_open_decoder(&acm, f, io, force_chans)) < 0) {
|
||||
fclose(f);
|
||||
return err;
|
||||
}
|
||||
*res = acm;
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -120,14 +120,14 @@ int acm_open_file(ACMStream **res, const char *filename, int force_chans)
|
|||
|
||||
static unsigned pcm2time(ACMStream *acm, unsigned long long pcm)
|
||||
{
|
||||
return pcm * 1000 / acm->info.rate;
|
||||
/* return ((10 * pcm) / acm->info.rate) * 100; */
|
||||
return pcm * 1000 / acm->info.rate;
|
||||
/* return ((10 * pcm) / acm->info.rate) * 100; */
|
||||
}
|
||||
|
||||
static unsigned time2pcm(ACMStream *acm, unsigned long long time_ms)
|
||||
{
|
||||
return time_ms * acm->info.rate / 1000;
|
||||
/* return (time_ms / 100) * (acm->info.rate / 10); */
|
||||
return time_ms * acm->info.rate / 1000;
|
||||
/* return (time_ms / 100) * (acm->info.rate / 10); */
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -136,67 +136,67 @@ static unsigned time2pcm(ACMStream *acm, unsigned long long time_ms)
|
|||
|
||||
const ACMInfo *acm_info(ACMStream *acm)
|
||||
{
|
||||
return &acm->info;
|
||||
return &acm->info;
|
||||
}
|
||||
|
||||
unsigned acm_rate(ACMStream *acm)
|
||||
{
|
||||
return acm->info.rate;
|
||||
return acm->info.rate;
|
||||
}
|
||||
|
||||
unsigned acm_channels(ACMStream *acm)
|
||||
{
|
||||
return acm->info.channels;
|
||||
return acm->info.channels;
|
||||
}
|
||||
|
||||
int acm_seekable(ACMStream *acm)
|
||||
{
|
||||
return acm->data_len > 0;
|
||||
return acm->data_len > 0;
|
||||
}
|
||||
|
||||
unsigned acm_bitrate(ACMStream *acm)
|
||||
{
|
||||
unsigned long long bits, time, bitrate = 0;
|
||||
unsigned long long bits, time, bitrate = 0;
|
||||
|
||||
if (acm_raw_total(acm) == 0)
|
||||
return 13000;
|
||||
if (acm_raw_total(acm) == 0)
|
||||
return 13000;
|
||||
|
||||
time = acm_time_total(acm);
|
||||
if (time > 0) {
|
||||
bits = 8 * acm_raw_total(acm);
|
||||
bitrate = 1000 * bits / time;
|
||||
}
|
||||
return bitrate;
|
||||
time = acm_time_total(acm);
|
||||
if (time > 0) {
|
||||
bits = 8 * acm_raw_total(acm);
|
||||
bitrate = 1000 * bits / time;
|
||||
}
|
||||
return bitrate;
|
||||
}
|
||||
|
||||
unsigned acm_pcm_tell(ACMStream *acm)
|
||||
{
|
||||
return acm->stream_pos / acm->info.channels;
|
||||
return acm->stream_pos / acm->info.channels;
|
||||
}
|
||||
|
||||
unsigned acm_pcm_total(ACMStream *acm)
|
||||
{
|
||||
return acm->total_values / acm->info.channels;
|
||||
return acm->total_values / acm->info.channels;
|
||||
}
|
||||
|
||||
unsigned acm_time_tell(ACMStream *acm)
|
||||
{
|
||||
return pcm2time(acm, acm_pcm_tell(acm));
|
||||
return pcm2time(acm, acm_pcm_tell(acm));
|
||||
}
|
||||
|
||||
unsigned acm_time_total(ACMStream *acm)
|
||||
{
|
||||
return pcm2time(acm, acm_pcm_total(acm));
|
||||
return pcm2time(acm, acm_pcm_total(acm));
|
||||
}
|
||||
|
||||
unsigned acm_raw_tell(ACMStream *acm)
|
||||
{
|
||||
return acm->buf_start_ofs + acm->buf_pos;
|
||||
return acm->buf_start_ofs + acm->buf_pos;
|
||||
}
|
||||
|
||||
unsigned acm_raw_total(ACMStream *acm)
|
||||
{
|
||||
return acm->data_len;
|
||||
return acm->data_len;
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -205,74 +205,74 @@ unsigned acm_raw_total(ACMStream *acm)
|
|||
|
||||
int acm_seek_time(ACMStream *acm, unsigned time_ms)
|
||||
{
|
||||
int res = acm_seek_pcm(acm, time2pcm(acm, time_ms));
|
||||
if (res <= 0)
|
||||
return res;
|
||||
return pcm2time(acm, res);
|
||||
int res = acm_seek_pcm(acm, time2pcm(acm, time_ms));
|
||||
if (res <= 0)
|
||||
return res;
|
||||
return pcm2time(acm, res);
|
||||
}
|
||||
|
||||
int acm_seek_pcm(ACMStream *acm, unsigned pcm_pos)
|
||||
{
|
||||
unsigned word_pos = pcm_pos * acm->info.channels;
|
||||
unsigned start_ofs;
|
||||
unsigned word_pos = pcm_pos * acm->info.channels;
|
||||
unsigned start_ofs;
|
||||
|
||||
if (word_pos < acm->stream_pos) {
|
||||
if (acm->io.seek_func == NULL)
|
||||
return ACM_ERR_NOT_SEEKABLE;
|
||||
if (word_pos < acm->stream_pos) {
|
||||
if (acm->io.seek_func == NULL)
|
||||
return ACM_ERR_NOT_SEEKABLE;
|
||||
|
||||
start_ofs = ACM_HEADER_LEN;
|
||||
if (acm->wavc_file)
|
||||
start_ofs += WAVC_HEADER_LEN;
|
||||
start_ofs = ACM_HEADER_LEN;
|
||||
if (acm->wavc_file)
|
||||
start_ofs += WAVC_HEADER_LEN;
|
||||
|
||||
if (acm->io.seek_func(acm->io_arg, start_ofs, SEEK_SET) < 0)
|
||||
return ACM_ERR_NOT_SEEKABLE;
|
||||
|
||||
acm->file_eof = 0;
|
||||
acm->buf_pos = 0;
|
||||
acm->buf_size = 0;
|
||||
acm->bit_avail = 0;
|
||||
acm->bit_data = 0;
|
||||
if (acm->io.seek_func(acm->io_arg, start_ofs, SEEK_SET) < 0)
|
||||
return ACM_ERR_NOT_SEEKABLE;
|
||||
|
||||
acm->file_eof = 0;
|
||||
acm->buf_pos = 0;
|
||||
acm->buf_size = 0;
|
||||
acm->bit_avail = 0;
|
||||
acm->bit_data = 0;
|
||||
|
||||
acm->stream_pos = 0;
|
||||
acm->block_pos = 0;
|
||||
acm->block_ready = 0;
|
||||
acm->buf_start_ofs = ACM_HEADER_LEN;
|
||||
acm->stream_pos = 0;
|
||||
acm->block_pos = 0;
|
||||
acm->block_ready = 0;
|
||||
acm->buf_start_ofs = ACM_HEADER_LEN;
|
||||
|
||||
memset(acm->wrapbuf, 0, acm->wrapbuf_len * sizeof(int));
|
||||
}
|
||||
while (acm->stream_pos < word_pos) {
|
||||
int step = 2048, res;
|
||||
if (acm->stream_pos + step > word_pos)
|
||||
step = word_pos - acm->stream_pos;
|
||||
memset(acm->wrapbuf, 0, acm->wrapbuf_len * sizeof(int));
|
||||
}
|
||||
while (acm->stream_pos < word_pos) {
|
||||
int step = 2048, res;
|
||||
if (acm->stream_pos + step > word_pos)
|
||||
step = word_pos - acm->stream_pos;
|
||||
|
||||
res = acm_read(acm, NULL, step*2, 0,2,1);
|
||||
if (res < 1)
|
||||
break;
|
||||
}
|
||||
return acm->stream_pos / acm->info.channels;
|
||||
res = acm_read(acm, NULL, step*2, 0,2,1);
|
||||
if (res < 1)
|
||||
break;
|
||||
}
|
||||
return acm->stream_pos / acm->info.channels;
|
||||
}
|
||||
|
||||
/*
|
||||
* read loop - full block reading
|
||||
*/
|
||||
int acm_read_loop(ACMStream *acm, void *dst, unsigned bytes,
|
||||
int bigendianp, int wordlen, int sgned)
|
||||
int bigendianp, int wordlen, int sgned)
|
||||
{
|
||||
unsigned char *dstp = dst;
|
||||
int res, got = 0;
|
||||
while (bytes > 0) {
|
||||
res = acm_read(acm, dstp, bytes, bigendianp, wordlen, sgned);
|
||||
if (res > 0) {
|
||||
if (dstp)
|
||||
dstp += res;
|
||||
got += res;
|
||||
bytes -= res;
|
||||
} else {
|
||||
if (res < 0 && got == 0)
|
||||
return res;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return got;
|
||||
unsigned char *dstp = dst;
|
||||
int res, got = 0;
|
||||
while (bytes > 0) {
|
||||
res = acm_read(acm, dstp, bytes, bigendianp, wordlen, sgned);
|
||||
if (res > 0) {
|
||||
if (dstp)
|
||||
dstp += res;
|
||||
got += res;
|
||||
bytes -= res;
|
||||
} else {
|
||||
if (res < 0 && got == 0)
|
||||
return res;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return got;
|
||||
}
|
||||
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,375 +1,375 @@
|
|||
/*****************************************************************************
|
||||
E R I S A - L i b r a r y
|
||||
-----------------------------------------------------------------------------
|
||||
Copyright (C) 2002-2003 Leshade Entis, Entis-soft. All rights reserved.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "mio_xerisa.h"
|
||||
#include "../../util/reader_get.h"
|
||||
|
||||
#define MIO_PACKET_BUFFER_MAX 0x20000 /* observed max is ~0x1d000 */
|
||||
#define MIO_PACKET_HEADER_SIZE 0x08
|
||||
#define MIO_PACKET_BYTES_MAX (32768 * 2 * 2) /* observed max: samples * channels * pcm16 */
|
||||
|
||||
|
||||
static inline /*const*/ uint64_t get_id64le(const char* s) {
|
||||
return (uint64_t)(
|
||||
((uint64_t)s[7] << 56) |
|
||||
((uint64_t)s[6] << 48) |
|
||||
((uint64_t)s[5] << 40) |
|
||||
((uint64_t)s[4] << 32) |
|
||||
((uint64_t)s[3] << 24) |
|
||||
((uint64_t)s[2] << 16) |
|
||||
((uint64_t)s[1] << 8) |
|
||||
((uint64_t)s[0] << 0)
|
||||
);
|
||||
}
|
||||
|
||||
MIOFile* MIOFile_Open() {
|
||||
MIOFile* mf = calloc(1, sizeof(MIOFile));
|
||||
if (!mf)
|
||||
return NULL;
|
||||
|
||||
return mf;
|
||||
}
|
||||
|
||||
void MIOFile_Close(MIOFile* mf) {
|
||||
if (!mf) return;
|
||||
|
||||
free(mf->ptrWaveBuf);
|
||||
free(mf->desc);
|
||||
free(mf->buf);
|
||||
free(mf);
|
||||
}
|
||||
|
||||
|
||||
static int read_chunk(EMC_RECORD_HEADER* rh, io_callback_t* file) {
|
||||
uint8_t chunk[0x10];
|
||||
|
||||
int len = file->read(chunk, 1, 0x10, file->arg);
|
||||
if (len != 0x10) goto fail;
|
||||
|
||||
rh->nRecordID = get_u64le(chunk + 0x00);
|
||||
rh->nRecLength = get_u64le(chunk + 0x08);
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* reads string (possibly utf16) in the form of "KEY\r\nVAL\r\n" */
|
||||
static int read_tag(char* tag, int tag_len, char* buf, int buf_len, int is_utf16le) {
|
||||
int step = is_utf16le ? 2 : 1;
|
||||
|
||||
int buf_pos = 0;
|
||||
int tag_pos = 0;
|
||||
|
||||
tag[0] = '\0';
|
||||
while (1) {
|
||||
if (buf_pos + step >= buf_len)
|
||||
break;
|
||||
if (tag_pos + 1 >= tag_len)
|
||||
break;
|
||||
|
||||
char elem = buf[buf_pos++];
|
||||
if (is_utf16le) /* ignore high byte for now (only seen simple tags) */
|
||||
buf_pos++;
|
||||
|
||||
if (elem == '\0')
|
||||
break;
|
||||
|
||||
tag[tag_pos++] = elem;
|
||||
}
|
||||
|
||||
tag[tag_pos] = '\0';
|
||||
return buf_pos;
|
||||
}
|
||||
|
||||
static int read_int(const char* params, UDWORD *value) {
|
||||
int n,m;
|
||||
int temp;
|
||||
|
||||
m = sscanf(params, " %d%n", &temp,&n);
|
||||
if (m != 1 || temp < 0)
|
||||
return 0;
|
||||
|
||||
*value = temp;
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Originally this is parsed into a list then returned when requested (ex. ERIFile::ETagInfo::GetRewindPoint)
|
||||
* but pre-read to simplify. Tags format:
|
||||
* - optional BOM (text is char16, possibly SHIFT-JIS), only seen files with utf-16
|
||||
* - key\r\nvalue\r\n (keys usually start with '#') xN (probably null-separated but only seen 1 tag)
|
||||
* - null padding (tag block is usually 0x80 even if only one short string is used) */
|
||||
static void read_tags(MIOFile* mf) {
|
||||
char tag[128];
|
||||
int tag_len = sizeof(tag);
|
||||
char* desc = mf->desc;
|
||||
int desc_len = mf->desc_len;
|
||||
int is_utf16le = 0;
|
||||
|
||||
if (desc[0] == '\xff' && desc[1] == '\xfe') {
|
||||
is_utf16le = 1;
|
||||
}
|
||||
|
||||
desc += 2;
|
||||
desc_len -= 2;
|
||||
|
||||
while (1) {
|
||||
int read = read_tag(tag, tag_len, desc, desc_len, is_utf16le);
|
||||
if (read <= 0)
|
||||
break;
|
||||
|
||||
if (memcmp(tag, "#rewind-point\r\n", 15) == 0)
|
||||
read_int(tag + 15, &mf->mioih.rewindPoint);
|
||||
|
||||
desc += read;
|
||||
desc_len -= read;
|
||||
}
|
||||
}
|
||||
|
||||
ESLError MIOFile_Initialize(MIOFile* mf, io_callback_t* file) {
|
||||
EMC_RECORD_HEADER rh;
|
||||
uint8_t buf[0x40];
|
||||
int len, ok;
|
||||
int size, to_read;
|
||||
|
||||
file->seek(file->arg, 0, IO_CALLBACK_SEEK_SET);
|
||||
|
||||
/* read base chunk */
|
||||
{
|
||||
to_read = 0x40;
|
||||
|
||||
len = file->read(buf, 1, to_read, file->arg);
|
||||
if (len < to_read) goto fail;
|
||||
|
||||
mf->emcfh.cHeader = get_u64le(buf + 0x00);
|
||||
mf->emcfh.dwFileID = get_u32le(buf + 0x08);
|
||||
mf->emcfh.dwReserved = get_u32le(buf + 0x0c);
|
||||
memcpy(mf->emcfh.cFormatDesc, buf + 0x10, 0x20);
|
||||
/* 0x30: extra info 0x10 */
|
||||
|
||||
if (mf->emcfh.cHeader != get_id64le("Entis\x1a\x00\x00"))
|
||||
goto fail;
|
||||
|
||||
/* each format has a fixed description, not checked in OG lib though */
|
||||
if (memcmp(mf->emcfh.cFormatDesc, "Music Interleaved and Orthogonal", 0x20) != 0)
|
||||
goto fail;
|
||||
/* older files end with " transformed\0\0\0\0", and newer with null + data size */
|
||||
}
|
||||
|
||||
|
||||
/* read header chunks */
|
||||
{
|
||||
ok = read_chunk(&rh, file);
|
||||
if (!ok) goto fail;
|
||||
|
||||
if (rh.nRecordID != get_id64le("Header "))
|
||||
goto fail;
|
||||
|
||||
size = rh.nRecLength;
|
||||
while (size > 0) {
|
||||
|
||||
ok = read_chunk(&rh, file);
|
||||
if (!ok) goto fail;
|
||||
|
||||
size -= 0x10;
|
||||
|
||||
/* common info */
|
||||
if (rh.nRecordID == get_id64le("FileHdr ")) {
|
||||
to_read = rh.nRecLength;
|
||||
if (to_read > sizeof(buf) || to_read != 0x14) goto fail;
|
||||
|
||||
len = file->read(buf, 1, to_read, file->arg);
|
||||
if (len != to_read) goto fail;
|
||||
|
||||
mf->erifh.dwVersion = get_u32le(buf + 0x00);
|
||||
mf->erifh.dwContainedFlag = get_u32le(buf + 0x04);
|
||||
mf->erifh.dwKeyFrameCount = get_u32le(buf + 0x08);
|
||||
mf->erifh.dwFrameCount = get_u32le(buf + 0x0c);
|
||||
mf->erifh.dwAllFrameTime = get_u32le(buf + 0x10);
|
||||
}
|
||||
|
||||
/* audio header */
|
||||
if (rh.nRecordID == get_id64le("SoundInf")) {
|
||||
to_read = rh.nRecLength;
|
||||
if (to_read > sizeof(buf) || to_read != 0x28) goto fail;
|
||||
|
||||
len = file->read(buf, 1, to_read, file->arg);
|
||||
if (len != to_read) goto fail;
|
||||
|
||||
mf->mioih.dwVersion = get_u32le(buf + 0x00);
|
||||
mf->mioih.fdwTransformation= get_u32le(buf + 0x04);
|
||||
mf->mioih.dwArchitecture = get_u32le(buf + 0x08);
|
||||
mf->mioih.dwChannelCount = get_u32le(buf + 0x0c);
|
||||
|
||||
mf->mioih.dwSamplesPerSec = get_u32le(buf + 0x10);
|
||||
mf->mioih.dwBlocksetCount = get_u32le(buf + 0x14);
|
||||
mf->mioih.dwSubbandDegree = get_u32le(buf + 0x18);
|
||||
mf->mioih.dwAllSampleCount = get_u32le(buf + 0x1c);
|
||||
|
||||
mf->mioih.dwLappedDegree = get_u32le(buf + 0x20);
|
||||
mf->mioih.dwBitsPerSample = get_u32le(buf + 0x24);
|
||||
}
|
||||
|
||||
/* other defaults */
|
||||
mf->mioih.rewindPoint = -1; /* not looped (since #rewind-point 0 means loop from the beginning) */
|
||||
|
||||
/* tags */
|
||||
if (rh.nRecordID == get_id64le("descript")) {
|
||||
/* OG lib supports:
|
||||
"title", "vocal-player", "composer", "arranger", "source", "track", "release-date", "genre",
|
||||
"rewind-point" (loop start), "hot-spot", "resolution", "comment", "words" (lyrics)
|
||||
Only seen loops though.
|
||||
*/
|
||||
|
||||
/* sometimes chunk exists with just size 0x02 (empty but probably for BOM) */
|
||||
to_read = rh.nRecLength;
|
||||
if (to_read < 0x02 || to_read > 0x10000) goto fail;
|
||||
|
||||
mf->desc = calloc(1, to_read + 2);
|
||||
if (!mf->desc) goto fail;
|
||||
|
||||
len = file->read(mf->desc, 1, to_read, file->arg);
|
||||
if (len != to_read) goto fail;
|
||||
|
||||
/* doesn't always end with null */
|
||||
mf->desc[to_read+0] = '\0';
|
||||
mf->desc[to_read+1] = '\0';
|
||||
mf->desc_len = to_read;
|
||||
|
||||
read_tags(mf);
|
||||
}
|
||||
|
||||
/* other chunks (not seen / for other non-MIO formats?):
|
||||
* - "PrevwInf" (image preview)
|
||||
* - "ImageInf" (image header)
|
||||
* - "Sequence" (image?)
|
||||
* - "cpyright" (text info)
|
||||
*/
|
||||
|
||||
size -= rh.nRecLength;
|
||||
}
|
||||
|
||||
if (mf->erifh.dwVersion > 0x00020100) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* read file data */
|
||||
{
|
||||
ok = read_chunk(&rh, file);
|
||||
if (!ok) goto fail;
|
||||
|
||||
if (rh.nRecordID != get_id64le("Stream "))
|
||||
goto fail;
|
||||
|
||||
//printf("stream chunk reached\n");
|
||||
/* packets are in "SoundStm" chunks ("ImageFrm" in images) */
|
||||
mf->start = file->tell(file->arg);
|
||||
}
|
||||
|
||||
return eslErrSuccess;
|
||||
fail:
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
ESLError MIOFile_Reset(MIOFile* mf, io_callback_t* file) {
|
||||
if (!mf) goto fail;
|
||||
|
||||
file->seek(file->arg, mf->start, IO_CALLBACK_SEEK_SET);
|
||||
|
||||
return eslErrSuccess;
|
||||
fail:
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
static int parse_packet_header(uint8_t* buf, int buf_size, MIO_DATA_HEADER* dh) {
|
||||
if (buf_size < MIO_PACKET_HEADER_SIZE)
|
||||
goto fail;
|
||||
|
||||
dh->bytVersion = get_u8(buf + 0x00);
|
||||
dh->bytFlags = get_u8(buf + 0x01);
|
||||
dh->bytReserved1 = get_u8(buf + 0x02);
|
||||
dh->bytReserved2 = get_u8(buf + 0x03);
|
||||
dh->dwSampleCount = get_u32le(buf + 0x04);
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
ESLError MIOFile_NextPacket(MIOFile* mf, io_callback_t* file) {
|
||||
EMC_RECORD_HEADER rh;
|
||||
int ok, len;
|
||||
|
||||
ok = read_chunk(&rh, file);
|
||||
if (!ok) return eslErrEof;
|
||||
|
||||
if (rh.nRecordID != get_id64le("SoundStm"))
|
||||
goto fail;
|
||||
|
||||
/* prepare buf */
|
||||
if (mf->buf_size < rh.nRecLength) {
|
||||
if (rh.nRecLength > MIO_PACKET_BUFFER_MAX)
|
||||
goto fail;
|
||||
if (rh.nRecLength <= MIO_PACKET_HEADER_SIZE)
|
||||
goto fail;
|
||||
|
||||
free(mf->buf);
|
||||
mf->buf_size = rh.nRecLength;
|
||||
mf->buf = malloc(mf->buf_size);
|
||||
if (!mf->buf) goto fail;
|
||||
}
|
||||
|
||||
len = file->read(mf->buf, 1, rh.nRecLength, file->arg);
|
||||
if (len != rh.nRecLength) goto fail;
|
||||
|
||||
ok = parse_packet_header(mf->buf, rh.nRecLength, &mf->miodh);
|
||||
if (!ok) goto fail;
|
||||
|
||||
mf->packet = mf->buf + MIO_PACKET_HEADER_SIZE;
|
||||
mf->packet_size = rh.nRecLength - MIO_PACKET_HEADER_SIZE;
|
||||
|
||||
return eslErrSuccess;
|
||||
fail:
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
|
||||
int MIOFile_GetTagLoop(MIOFile* mf, const char* tag) {
|
||||
return mf->mioih.rewindPoint;
|
||||
}
|
||||
|
||||
void* MIOFile_GetCurrentWaveBuffer(MIOFile* mf) {
|
||||
int channels = mf->mioih.dwChannelCount;
|
||||
int bps = mf->mioih.dwBitsPerSample;
|
||||
int bytes_per_sample = channels * (bps / 8);
|
||||
int chunk_samples = mf->miodh.dwSampleCount;
|
||||
|
||||
/* usually same for all except less in last packet */
|
||||
UDWORD dwBytesAudio = chunk_samples * bytes_per_sample;
|
||||
if (dwBytesAudio > MIO_PACKET_BYTES_MAX) goto fail;
|
||||
|
||||
if (dwBytesAudio > mf->ptrWaveBuf_len) {
|
||||
free(mf->ptrWaveBuf);
|
||||
mf->ptrWaveBuf = malloc(dwBytesAudio);
|
||||
if (!mf->ptrWaveBuf) goto fail;
|
||||
mf->ptrWaveBuf_len = dwBytesAudio;
|
||||
}
|
||||
|
||||
return mf->ptrWaveBuf;
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int MIOFile_GetCurrentWaveBufferCount(MIOFile* mf) {
|
||||
int channels = mf->mioih.dwChannelCount;
|
||||
int chunk_samples = mf->miodh.dwSampleCount;
|
||||
return chunk_samples * channels;
|
||||
}
|
||||
/*****************************************************************************
|
||||
E R I S A - L i b r a r y
|
||||
-----------------------------------------------------------------------------
|
||||
Copyright (C) 2002-2003 Leshade Entis, Entis-soft. All rights reserved.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include "mio_xerisa.h"
|
||||
#include "../../util/reader_get.h"
|
||||
|
||||
#define MIO_PACKET_BUFFER_MAX 0x20000 /* observed max is ~0x1d000 */
|
||||
#define MIO_PACKET_HEADER_SIZE 0x08
|
||||
#define MIO_PACKET_BYTES_MAX (32768 * 2 * 2) /* observed max: samples * channels * pcm16 */
|
||||
|
||||
|
||||
static inline /*const*/ uint64_t get_id64le(const char* s) {
|
||||
return (uint64_t)(
|
||||
((uint64_t)s[7] << 56) |
|
||||
((uint64_t)s[6] << 48) |
|
||||
((uint64_t)s[5] << 40) |
|
||||
((uint64_t)s[4] << 32) |
|
||||
((uint64_t)s[3] << 24) |
|
||||
((uint64_t)s[2] << 16) |
|
||||
((uint64_t)s[1] << 8) |
|
||||
((uint64_t)s[0] << 0)
|
||||
);
|
||||
}
|
||||
|
||||
MIOFile* MIOFile_Open() {
|
||||
MIOFile* mf = calloc(1, sizeof(MIOFile));
|
||||
if (!mf)
|
||||
return NULL;
|
||||
|
||||
return mf;
|
||||
}
|
||||
|
||||
void MIOFile_Close(MIOFile* mf) {
|
||||
if (!mf) return;
|
||||
|
||||
free(mf->ptrWaveBuf);
|
||||
free(mf->desc);
|
||||
free(mf->buf);
|
||||
free(mf);
|
||||
}
|
||||
|
||||
|
||||
static int read_chunk(EMC_RECORD_HEADER* rh, io_callback_t* file) {
|
||||
uint8_t chunk[0x10];
|
||||
|
||||
int len = file->read(chunk, 1, 0x10, file->arg);
|
||||
if (len != 0x10) goto fail;
|
||||
|
||||
rh->nRecordID = get_u64le(chunk + 0x00);
|
||||
rh->nRecLength = get_u64le(chunk + 0x08);
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* reads string (possibly utf16) in the form of "KEY\r\nVAL\r\n" */
|
||||
static int read_tag(char* tag, int tag_len, char* buf, int buf_len, int is_utf16le) {
|
||||
int step = is_utf16le ? 2 : 1;
|
||||
|
||||
int buf_pos = 0;
|
||||
int tag_pos = 0;
|
||||
|
||||
tag[0] = '\0';
|
||||
while (1) {
|
||||
if (buf_pos + step >= buf_len)
|
||||
break;
|
||||
if (tag_pos + 1 >= tag_len)
|
||||
break;
|
||||
|
||||
char elem = buf[buf_pos++];
|
||||
if (is_utf16le) /* ignore high byte for now (only seen simple tags) */
|
||||
buf_pos++;
|
||||
|
||||
if (elem == '\0')
|
||||
break;
|
||||
|
||||
tag[tag_pos++] = elem;
|
||||
}
|
||||
|
||||
tag[tag_pos] = '\0';
|
||||
return buf_pos;
|
||||
}
|
||||
|
||||
static int read_int(const char* params, UDWORD *value) {
|
||||
int n,m;
|
||||
int temp;
|
||||
|
||||
m = sscanf(params, " %d%n", &temp,&n);
|
||||
if (m != 1 || temp < 0)
|
||||
return 0;
|
||||
|
||||
*value = temp;
|
||||
return n;
|
||||
}
|
||||
|
||||
/* Originally this is parsed into a list then returned when requested (ex. ERIFile::ETagInfo::GetRewindPoint)
|
||||
* but pre-read to simplify. Tags format:
|
||||
* - optional BOM (text is char16, possibly SHIFT-JIS), only seen files with utf-16
|
||||
* - key\r\nvalue\r\n (keys usually start with '#') xN (probably null-separated but only seen 1 tag)
|
||||
* - null padding (tag block is usually 0x80 even if only one short string is used) */
|
||||
static void read_tags(MIOFile* mf) {
|
||||
char tag[128];
|
||||
int tag_len = sizeof(tag);
|
||||
char* desc = mf->desc;
|
||||
int desc_len = mf->desc_len;
|
||||
int is_utf16le = 0;
|
||||
|
||||
if (desc[0] == '\xff' && desc[1] == '\xfe') {
|
||||
is_utf16le = 1;
|
||||
}
|
||||
|
||||
desc += 2;
|
||||
desc_len -= 2;
|
||||
|
||||
while (1) {
|
||||
int read = read_tag(tag, tag_len, desc, desc_len, is_utf16le);
|
||||
if (read <= 0)
|
||||
break;
|
||||
|
||||
if (memcmp(tag, "#rewind-point\r\n", 15) == 0)
|
||||
read_int(tag + 15, &mf->mioih.rewindPoint);
|
||||
|
||||
desc += read;
|
||||
desc_len -= read;
|
||||
}
|
||||
}
|
||||
|
||||
ESLError MIOFile_Initialize(MIOFile* mf, io_callback_t* file) {
|
||||
EMC_RECORD_HEADER rh;
|
||||
uint8_t buf[0x40];
|
||||
int len, ok;
|
||||
int size, to_read;
|
||||
|
||||
file->seek(file->arg, 0, IO_CALLBACK_SEEK_SET);
|
||||
|
||||
/* read base chunk */
|
||||
{
|
||||
to_read = 0x40;
|
||||
|
||||
len = file->read(buf, 1, to_read, file->arg);
|
||||
if (len < to_read) goto fail;
|
||||
|
||||
mf->emcfh.cHeader = get_u64le(buf + 0x00);
|
||||
mf->emcfh.dwFileID = get_u32le(buf + 0x08);
|
||||
mf->emcfh.dwReserved = get_u32le(buf + 0x0c);
|
||||
memcpy(mf->emcfh.cFormatDesc, buf + 0x10, 0x20);
|
||||
/* 0x30: extra info 0x10 */
|
||||
|
||||
if (mf->emcfh.cHeader != get_id64le("Entis\x1a\x00\x00"))
|
||||
goto fail;
|
||||
|
||||
/* each format has a fixed description, not checked in OG lib though */
|
||||
if (memcmp(mf->emcfh.cFormatDesc, "Music Interleaved and Orthogonal", 0x20) != 0)
|
||||
goto fail;
|
||||
/* older files end with " transformed\0\0\0\0", and newer with null + data size */
|
||||
}
|
||||
|
||||
|
||||
/* read header chunks */
|
||||
{
|
||||
ok = read_chunk(&rh, file);
|
||||
if (!ok) goto fail;
|
||||
|
||||
if (rh.nRecordID != get_id64le("Header "))
|
||||
goto fail;
|
||||
|
||||
size = rh.nRecLength;
|
||||
while (size > 0) {
|
||||
|
||||
ok = read_chunk(&rh, file);
|
||||
if (!ok) goto fail;
|
||||
|
||||
size -= 0x10;
|
||||
|
||||
/* common info */
|
||||
if (rh.nRecordID == get_id64le("FileHdr ")) {
|
||||
to_read = rh.nRecLength;
|
||||
if (to_read > sizeof(buf) || to_read != 0x14) goto fail;
|
||||
|
||||
len = file->read(buf, 1, to_read, file->arg);
|
||||
if (len != to_read) goto fail;
|
||||
|
||||
mf->erifh.dwVersion = get_u32le(buf + 0x00);
|
||||
mf->erifh.dwContainedFlag = get_u32le(buf + 0x04);
|
||||
mf->erifh.dwKeyFrameCount = get_u32le(buf + 0x08);
|
||||
mf->erifh.dwFrameCount = get_u32le(buf + 0x0c);
|
||||
mf->erifh.dwAllFrameTime = get_u32le(buf + 0x10);
|
||||
}
|
||||
|
||||
/* audio header */
|
||||
if (rh.nRecordID == get_id64le("SoundInf")) {
|
||||
to_read = rh.nRecLength;
|
||||
if (to_read > sizeof(buf) || to_read != 0x28) goto fail;
|
||||
|
||||
len = file->read(buf, 1, to_read, file->arg);
|
||||
if (len != to_read) goto fail;
|
||||
|
||||
mf->mioih.dwVersion = get_u32le(buf + 0x00);
|
||||
mf->mioih.fdwTransformation= get_u32le(buf + 0x04);
|
||||
mf->mioih.dwArchitecture = get_u32le(buf + 0x08);
|
||||
mf->mioih.dwChannelCount = get_u32le(buf + 0x0c);
|
||||
|
||||
mf->mioih.dwSamplesPerSec = get_u32le(buf + 0x10);
|
||||
mf->mioih.dwBlocksetCount = get_u32le(buf + 0x14);
|
||||
mf->mioih.dwSubbandDegree = get_u32le(buf + 0x18);
|
||||
mf->mioih.dwAllSampleCount = get_u32le(buf + 0x1c);
|
||||
|
||||
mf->mioih.dwLappedDegree = get_u32le(buf + 0x20);
|
||||
mf->mioih.dwBitsPerSample = get_u32le(buf + 0x24);
|
||||
}
|
||||
|
||||
/* other defaults */
|
||||
mf->mioih.rewindPoint = -1; /* not looped (since #rewind-point 0 means loop from the beginning) */
|
||||
|
||||
/* tags */
|
||||
if (rh.nRecordID == get_id64le("descript")) {
|
||||
/* OG lib supports:
|
||||
"title", "vocal-player", "composer", "arranger", "source", "track", "release-date", "genre",
|
||||
"rewind-point" (loop start), "hot-spot", "resolution", "comment", "words" (lyrics)
|
||||
Only seen loops though.
|
||||
*/
|
||||
|
||||
/* sometimes chunk exists with just size 0x02 (empty but probably for BOM) */
|
||||
to_read = rh.nRecLength;
|
||||
if (to_read < 0x02 || to_read > 0x10000) goto fail;
|
||||
|
||||
mf->desc = calloc(1, to_read + 2);
|
||||
if (!mf->desc) goto fail;
|
||||
|
||||
len = file->read(mf->desc, 1, to_read, file->arg);
|
||||
if (len != to_read) goto fail;
|
||||
|
||||
/* doesn't always end with null */
|
||||
mf->desc[to_read+0] = '\0';
|
||||
mf->desc[to_read+1] = '\0';
|
||||
mf->desc_len = to_read;
|
||||
|
||||
read_tags(mf);
|
||||
}
|
||||
|
||||
/* other chunks (not seen / for other non-MIO formats?):
|
||||
* - "PrevwInf" (image preview)
|
||||
* - "ImageInf" (image header)
|
||||
* - "Sequence" (image?)
|
||||
* - "cpyright" (text info)
|
||||
*/
|
||||
|
||||
size -= rh.nRecLength;
|
||||
}
|
||||
|
||||
if (mf->erifh.dwVersion > 0x00020100) {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* read file data */
|
||||
{
|
||||
ok = read_chunk(&rh, file);
|
||||
if (!ok) goto fail;
|
||||
|
||||
if (rh.nRecordID != get_id64le("Stream "))
|
||||
goto fail;
|
||||
|
||||
//printf("stream chunk reached\n");
|
||||
/* packets are in "SoundStm" chunks ("ImageFrm" in images) */
|
||||
mf->start = file->tell(file->arg);
|
||||
}
|
||||
|
||||
return eslErrSuccess;
|
||||
fail:
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
ESLError MIOFile_Reset(MIOFile* mf, io_callback_t* file) {
|
||||
if (!mf) goto fail;
|
||||
|
||||
file->seek(file->arg, mf->start, IO_CALLBACK_SEEK_SET);
|
||||
|
||||
return eslErrSuccess;
|
||||
fail:
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
static int parse_packet_header(uint8_t* buf, int buf_size, MIO_DATA_HEADER* dh) {
|
||||
if (buf_size < MIO_PACKET_HEADER_SIZE)
|
||||
goto fail;
|
||||
|
||||
dh->bytVersion = get_u8(buf + 0x00);
|
||||
dh->bytFlags = get_u8(buf + 0x01);
|
||||
dh->bytReserved1 = get_u8(buf + 0x02);
|
||||
dh->bytReserved2 = get_u8(buf + 0x03);
|
||||
dh->dwSampleCount = get_u32le(buf + 0x04);
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
ESLError MIOFile_NextPacket(MIOFile* mf, io_callback_t* file) {
|
||||
EMC_RECORD_HEADER rh;
|
||||
int ok, len;
|
||||
|
||||
ok = read_chunk(&rh, file);
|
||||
if (!ok) return eslErrEof;
|
||||
|
||||
if (rh.nRecordID != get_id64le("SoundStm"))
|
||||
goto fail;
|
||||
|
||||
/* prepare buf */
|
||||
if (mf->buf_size < rh.nRecLength) {
|
||||
if (rh.nRecLength > MIO_PACKET_BUFFER_MAX)
|
||||
goto fail;
|
||||
if (rh.nRecLength <= MIO_PACKET_HEADER_SIZE)
|
||||
goto fail;
|
||||
|
||||
free(mf->buf);
|
||||
mf->buf_size = rh.nRecLength;
|
||||
mf->buf = malloc(mf->buf_size);
|
||||
if (!mf->buf) goto fail;
|
||||
}
|
||||
|
||||
len = file->read(mf->buf, 1, rh.nRecLength, file->arg);
|
||||
if (len != rh.nRecLength) goto fail;
|
||||
|
||||
ok = parse_packet_header(mf->buf, rh.nRecLength, &mf->miodh);
|
||||
if (!ok) goto fail;
|
||||
|
||||
mf->packet = mf->buf + MIO_PACKET_HEADER_SIZE;
|
||||
mf->packet_size = rh.nRecLength - MIO_PACKET_HEADER_SIZE;
|
||||
|
||||
return eslErrSuccess;
|
||||
fail:
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
|
||||
int MIOFile_GetTagLoop(MIOFile* mf, const char* tag) {
|
||||
return mf->mioih.rewindPoint;
|
||||
}
|
||||
|
||||
void* MIOFile_GetCurrentWaveBuffer(MIOFile* mf) {
|
||||
int channels = mf->mioih.dwChannelCount;
|
||||
int bps = mf->mioih.dwBitsPerSample;
|
||||
int bytes_per_sample = channels * (bps / 8);
|
||||
int chunk_samples = mf->miodh.dwSampleCount;
|
||||
|
||||
/* usually same for all except less in last packet */
|
||||
UDWORD dwBytesAudio = chunk_samples * bytes_per_sample;
|
||||
if (dwBytesAudio > MIO_PACKET_BYTES_MAX) goto fail;
|
||||
|
||||
if (dwBytesAudio > mf->ptrWaveBuf_len) {
|
||||
free(mf->ptrWaveBuf);
|
||||
mf->ptrWaveBuf = malloc(dwBytesAudio);
|
||||
if (!mf->ptrWaveBuf) goto fail;
|
||||
mf->ptrWaveBuf_len = dwBytesAudio;
|
||||
}
|
||||
|
||||
return mf->ptrWaveBuf;
|
||||
fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int MIOFile_GetCurrentWaveBufferCount(MIOFile* mf) {
|
||||
int channels = mf->mioih.dwChannelCount;
|
||||
int chunk_samples = mf->miodh.dwSampleCount;
|
||||
return chunk_samples * channels;
|
||||
}
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -2,9 +2,33 @@
|
|||
#include "../base/decode_state.h"
|
||||
#include "../base/codec_info.h"
|
||||
#include "libs/mio_xerisa.h"
|
||||
//#include "Source/reader_get.h"
|
||||
#include "../util/io_callback_sf.h"
|
||||
|
||||
/* Decodes MIO ("Music Interleaved and Orthogonal transformed") audio files.
|
||||
* Adapted to C from original C++ lib source by Leshade Entis:
|
||||
* - http://www.entis.jp/eridev/download/
|
||||
* - http://www.amatsukami.jp/entis/bin/erinalib.lzh
|
||||
* (licensed under a custom license somewhat equivalent to GPL).
|
||||
*
|
||||
* Full lib is called "ERINA-Library" (2000~2022) / "ERISA-Library" (2004~2005), and handles various
|
||||
* Entis's formats, while this code just handles "MIO" (audio) decoding. "ERISA" uses a new coding
|
||||
* type but also handles older files.
|
||||
*
|
||||
* MIO has a RIFF-like chunk header, and then is divided into big-ish VBR blocks. "Lead" blocks
|
||||
* (first one, but also others that act as "keyframes") setup code model, which can be huffman (ERINA)
|
||||
* or arithmetic (ERISA) coding depending on header. Lib reads per-block config then codes, then
|
||||
* dequantizes per sub-band with iLOT (lapped orthogonal transform) and iDCT after some
|
||||
* pre/post-processing. There is a lossless mode with huffman codes + PCM16/8 as well.
|
||||
*
|
||||
* Original C++ lib audio parts has roughly 4 modules, adapted and simplified to C like this:
|
||||
* - erisafile (MIOFile): file ops like parsing header and reading blocks
|
||||
* - erisacontext (MIOContext): bitreading from blocks and code unpacking (huffman/arithmetical decoding)
|
||||
* - erisasound (MIODecoder): decodes audio context data into samples
|
||||
* - erisamatrix (EMT_eri*): iDTC/iLOT/etc helper functions
|
||||
*
|
||||
* (this conversion removes encoder/non-MIO parts, hides non-public methods, unifies dupes, tweaks exceptions, improves errors, etc)
|
||||
*/
|
||||
|
||||
|
||||
/* opaque struct */
|
||||
typedef struct {
|
||||
|
|
|
@ -1,37 +1,53 @@
|
|||
#include <math.h>
|
||||
#include "coding.h"
|
||||
#include "../base/decode_state.h"
|
||||
#include "../base/sbuf.h"
|
||||
#include "../base/codec_info.h"
|
||||
#include "../util.h"
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
#define OV_EXCLUDE_STATIC_CALLBACKS
|
||||
#include <vorbis/vorbisfile.h>
|
||||
|
||||
#define VORBIS_CALL_SAMPLES 1024 // allowed frame 'blocksizes' range from 2^6 ~ 2^13 (64 ~ 8192) but we can return partial samples
|
||||
#define OGG_DEFAULT_BITSTREAM 0
|
||||
|
||||
/* opaque struct */
|
||||
struct ogg_vorbis_codec_data {
|
||||
OggVorbis_File ogg_vorbis_file;
|
||||
int ovf_init;
|
||||
int bitstream;
|
||||
int disable_reordering; /* Xiph Ogg must reorder channels on output, but some pre-ordered games don't need it */
|
||||
int force_seek; /* Ogg with wrong granules can't seek correctly */
|
||||
int bitstream; // special flag for current stream (in practice can be ignored)
|
||||
|
||||
bool ovf_init;
|
||||
bool disable_reordering; /* Xiph Ogg must reorder channels on output, but some pre-ordered games don't need it */
|
||||
bool force_seek; /* Ogg with wrong granules can't seek correctly */
|
||||
int32_t discard;
|
||||
|
||||
ogg_vorbis_io io;
|
||||
vorbis_comment* comment;
|
||||
int comment_number;
|
||||
vorbis_info* info;
|
||||
|
||||
float* fbuf;
|
||||
};
|
||||
|
||||
|
||||
static void pcm_convert_float_to_16(int channels, sample_t* outbuf, int start_sample, int samples_to_do, float** pcm, int disable_ordering);
|
||||
|
||||
static size_t ov_read_func(void* ptr, size_t size, size_t nmemb, void* datasource);
|
||||
static int ov_seek_func(void* datasource, ogg_int64_t offset, int whence);
|
||||
static long ov_tell_func(void* datasource);
|
||||
static int ov_close_func(void* datasource);
|
||||
|
||||
static void free_ogg_vorbis(void* priv_data) {
|
||||
ogg_vorbis_codec_data* data = priv_data;
|
||||
if (!data) return;
|
||||
|
||||
if (data->ovf_init) {
|
||||
ov_clear(&data->ogg_vorbis_file);
|
||||
}
|
||||
|
||||
close_streamfile(data->io.streamfile);
|
||||
free(data->fbuf);
|
||||
free(data);
|
||||
}
|
||||
|
||||
ogg_vorbis_codec_data* init_ogg_vorbis(STREAMFILE* sf, off_t start, off_t size, ogg_vorbis_io* io) {
|
||||
ogg_vorbis_codec_data* data = NULL;
|
||||
|
@ -98,7 +114,7 @@ ogg_vorbis_codec_data* init_ogg_vorbis(STREAMFILE* sf, off_t start, off_t size,
|
|||
/* open the ogg vorbis file for real */
|
||||
if (ov_open_callbacks(&data->io, &data->ogg_vorbis_file, NULL, 0, callbacks))
|
||||
goto fail;
|
||||
data->ovf_init = 1;
|
||||
data->ovf_init = true;
|
||||
}
|
||||
|
||||
//todo could set bitstreams as subsongs?
|
||||
|
@ -179,106 +195,48 @@ static int ov_close_func(void* datasource) {
|
|||
|
||||
/* ********************************************** */
|
||||
|
||||
void decode_ogg_vorbis(ogg_vorbis_codec_data* data, sample_t* outbuf, int32_t samples_to_do, int channels) {
|
||||
int samples_done = 0;
|
||||
long start, rc;
|
||||
float** pcm_channels; /* pointer to Xiph's double array buffer */
|
||||
static bool decode_frame_ogg_vorbis(VGMSTREAM* v) {
|
||||
ogg_vorbis_codec_data* data = v->codec_data;
|
||||
decode_state_t* ds = v->decode_state;
|
||||
float** pcm_channels;
|
||||
|
||||
while (samples_done < samples_to_do) {
|
||||
rc = ov_read_float(
|
||||
&data->ogg_vorbis_file, /* context */
|
||||
&pcm_channels, /* buffer pointer */
|
||||
(samples_to_do - samples_done), /* samples to produce */
|
||||
&data->bitstream); /* bitstream */
|
||||
if (rc <= 0) goto fail; /* rc is samples done */
|
||||
|
||||
if (data->discard) {
|
||||
start = data->discard;
|
||||
if (start > rc)
|
||||
start = rc;
|
||||
|
||||
data->discard -= start;
|
||||
if (start == rc) /* consume all */
|
||||
continue;
|
||||
}
|
||||
else {
|
||||
start = 0;
|
||||
}
|
||||
|
||||
pcm_convert_float_to_16(channels, outbuf, start, rc, pcm_channels, data->disable_reordering);
|
||||
|
||||
outbuf += (rc - start) * channels;
|
||||
samples_done += (rc - start);
|
||||
|
||||
|
||||
#if 0 // alt decoding
|
||||
/* we use ov_read_float as to reuse the xiph's buffer for easier remapping,
|
||||
* but seems ov_read is slightly faster due to optimized (asm) float-to-int. */
|
||||
rc = ov_read(
|
||||
&data->ogg_vorbis_file, /* context */
|
||||
(char *)(outbuf), /* buffer */
|
||||
(samples_to_do - samples_done) * sizeof(sample_t) * channels, /* length in bytes */
|
||||
0, /* pcm endianness */
|
||||
sizeof(sample_t), /* pcm size */
|
||||
1, /* pcm signedness */
|
||||
&data->bitstream); /* bitstream */
|
||||
if (rc <= 0) goto fail; /* rc is bytes done (for all channels) */
|
||||
|
||||
swap_samples_le(outbuf, rc / sizeof(sample_t)); /* endianness is a bit weird with ov_read though */
|
||||
|
||||
outbuf += rc / sizeof(sample_t);
|
||||
samples_done += rc / sizeof(sample_t) / channels;
|
||||
#endif
|
||||
//TODO: helper? maybe should init in init_vorbis_custom but right now not all vorbises pass channels
|
||||
if (data->fbuf == NULL) {
|
||||
data->fbuf = malloc(VORBIS_CALL_SAMPLES * sizeof(float) * v->channels);
|
||||
if (!data->fbuf) return -1;
|
||||
}
|
||||
|
||||
return;
|
||||
fail:
|
||||
VGM_LOG("OGG: error %lx during decode\n", rc);
|
||||
memset(outbuf, 0, (samples_to_do - samples_done) * channels * sizeof(sample_t));
|
||||
}
|
||||
// Ogg frame samples vary per frame, and API allows to ask for arbitrary max (may return less).
|
||||
// Limit totals as loop end needs to stop at exact point, since seeking is smoothed between current + loop start
|
||||
// (decoding a bit more than loop end results in slightly different loops, very minor but done to match older code).
|
||||
int max_samples = ds->samples_left;
|
||||
if (max_samples > VORBIS_CALL_SAMPLES)
|
||||
max_samples = VORBIS_CALL_SAMPLES;
|
||||
|
||||
/* vorbis encodes channels in non-standard order, so we remap during conversion to fix this oddity.
|
||||
* (feels a bit weird as one would think you could leave as-is and set the player's output order,
|
||||
* but that isn't possible and remapping like this is what FFmpeg and every other plugin does). */
|
||||
static const int xiph_channel_map[8][8] = {
|
||||
{ 0 }, /* 1ch: FC > same */
|
||||
{ 0, 1 }, /* 2ch: FL FR > same */
|
||||
{ 0, 2, 1 }, /* 3ch: FL FC FR > FL FR FC */
|
||||
{ 0, 1, 2, 3 }, /* 4ch: FL FR BL BR > same */
|
||||
{ 0, 2, 1, 3, 4 }, /* 5ch: FL FC FR BL BR > FL FR FC BL BR */
|
||||
{ 0, 2, 1, 5, 3, 4 }, /* 6ch: FL FC FR BL BR LFE > FL FR FC LFE BL BR */
|
||||
{ 0, 2, 1, 6, 5, 3, 4 }, /* 7ch: FL FC FR SL SR BC LFE > FL FR FC LFE BC SL SR */
|
||||
{ 0, 2, 1, 7, 5, 6, 3, 4 }, /* 8ch: FL FC FR SL SR BL BR LFE > FL FR FC LFE BL BR SL SR */
|
||||
};
|
||||
long rc = ov_read_float(&data->ogg_vorbis_file, &pcm_channels, max_samples, &data->bitstream);
|
||||
if (rc <= 0) // rc is samples done
|
||||
return false;
|
||||
|
||||
/* converts from internal Vorbis format to standard PCM and remaps (mostly from Xiph's decoder_example.c) */
|
||||
static void pcm_convert_float_to_16(int channels, sample_t* outbuf, int start_sample, int samples_to_do, float** pcm, int disable_ordering) {
|
||||
int ch, s, ch_map;
|
||||
sample_t *ptr;
|
||||
float *channel;
|
||||
sbuf_init_flt(&ds->sbuf, data->fbuf, rc, v->channels);
|
||||
ds->sbuf.filled = rc;
|
||||
|
||||
/* convert float PCM (multichannel float array, with pcm[0]=ch0, pcm[1]=ch1, pcm[2]=ch0, etc)
|
||||
* to 16 bit signed PCM ints (host order) and interleave + fix clipping */
|
||||
for (ch = 0; ch < channels; ch++) {
|
||||
ch_map = disable_ordering ?
|
||||
ch :
|
||||
(channels > 8) ? ch : xiph_channel_map[channels - 1][ch]; /* put Vorbis' ch to other outbuf's ch */
|
||||
ptr = outbuf + ch;
|
||||
channel = pcm[ch_map];
|
||||
for (s = start_sample; s < samples_to_do; s++) {
|
||||
int val = (int)floor(channel[s] * 32767.0f + 0.5f); /* use floorf? doesn't seem any faster */
|
||||
if (val > 32767) val = 32767;
|
||||
else if (val < -32768) val = -32768;
|
||||
if (data->disable_reordering)
|
||||
sbuf_interleave(&ds->sbuf, pcm_channels);
|
||||
else
|
||||
sbuf_interleave_vorbis(&ds->sbuf, pcm_channels);
|
||||
|
||||
*ptr = val;
|
||||
ptr += channels;
|
||||
}
|
||||
if (data->discard) {
|
||||
ds->discard = data->discard;
|
||||
data->discard = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ********************************************** */
|
||||
|
||||
void reset_ogg_vorbis(ogg_vorbis_codec_data* data) {
|
||||
static void reset_ogg_vorbis(void* priv_data) {
|
||||
ogg_vorbis_codec_data* data = priv_data;
|
||||
if (!data) return;
|
||||
|
||||
/* this raw seek cleans internal buffers, and it's preferable to
|
||||
|
@ -289,7 +247,8 @@ void reset_ogg_vorbis(ogg_vorbis_codec_data* data) {
|
|||
data->discard = 0;
|
||||
}
|
||||
|
||||
void seek_ogg_vorbis(ogg_vorbis_codec_data* data, int32_t num_sample) {
|
||||
static void seek_ogg_vorbis(VGMSTREAM* v, int32_t num_sample) {
|
||||
ogg_vorbis_codec_data* data = v->codec_data;
|
||||
if (!data) return;
|
||||
|
||||
/* special seek for games with bad granule positions (since ov_*_seek uses granules to seek) */
|
||||
|
@ -305,16 +264,6 @@ void seek_ogg_vorbis(ogg_vorbis_codec_data* data, int32_t num_sample) {
|
|||
//VGM_ASSERT(res != 0, "OGG: bad seek=%i\n", res); /* not seen, in theory could give error */
|
||||
}
|
||||
|
||||
void free_ogg_vorbis(ogg_vorbis_codec_data* data) {
|
||||
if (!data) return;
|
||||
|
||||
if (data->ovf_init)
|
||||
ov_clear(&data->ogg_vorbis_file);
|
||||
|
||||
close_streamfile(data->io.streamfile);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/* ********************************************** */
|
||||
|
||||
int ogg_vorbis_get_comment(ogg_vorbis_codec_data* data, const char** comment) {
|
||||
|
@ -354,13 +303,13 @@ void ogg_vorbis_get_samples(ogg_vorbis_codec_data* data, int* p_samples) {
|
|||
if (p_samples) *p_samples = ov_pcm_total(&data->ogg_vorbis_file,-1);
|
||||
}
|
||||
|
||||
void ogg_vorbis_set_disable_reordering(ogg_vorbis_codec_data* data, int set) {
|
||||
void ogg_vorbis_set_disable_reordering(ogg_vorbis_codec_data* data, bool set) {
|
||||
if (!data) return;
|
||||
|
||||
data->disable_reordering = set;
|
||||
}
|
||||
|
||||
void ogg_vorbis_set_force_seek(ogg_vorbis_codec_data* data, int set) {
|
||||
void ogg_vorbis_set_force_seek(ogg_vorbis_codec_data* data, bool set) {
|
||||
if (!data) return;
|
||||
|
||||
data->force_seek = set;
|
||||
|
@ -371,4 +320,13 @@ STREAMFILE* ogg_vorbis_get_streamfile(ogg_vorbis_codec_data* data) {
|
|||
return data->io.streamfile;
|
||||
}
|
||||
|
||||
|
||||
const codec_info_t ogg_vorbis_decoder = {
|
||||
.sample_type = SFMT_FLT,
|
||||
.decode_frame = decode_frame_ogg_vorbis,
|
||||
.free = free_ogg_vorbis,
|
||||
.reset = reset_ogg_vorbis,
|
||||
.seek = seek_ogg_vorbis,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,9 @@
|
|||
#include "coding.h"
|
||||
#include "../util.h"
|
||||
#include <math.h>
|
||||
#include "../base/decode_state.h"
|
||||
#include "../base/codec_info.h"
|
||||
#include "../util/endianness.h"
|
||||
|
||||
void decode_pcm16le(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i;
|
||||
|
@ -124,139 +127,173 @@ void decode_pcm4_unsigned(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL* stream, sampl
|
|||
}
|
||||
}
|
||||
|
||||
static int expand_ulaw(uint8_t ulawbyte) {
|
||||
int sign, segment, quantization, sample;
|
||||
const int bias = 0x84;
|
||||
|
||||
ulawbyte = ~ulawbyte; /* stored in complement */
|
||||
sign = (ulawbyte & 0x80);
|
||||
segment = (ulawbyte & 0x70) >> 4; /* exponent */
|
||||
quantization = ulawbyte & 0x0F; /* mantissa */
|
||||
|
||||
sample = (quantization << 3) + bias; /* add bias */
|
||||
sample <<= segment;
|
||||
sample = (sign) ? (bias - sample) : (sample - bias); /* remove bias */
|
||||
|
||||
#if 0 // the above follows Sun's implementation, but this works too
|
||||
{
|
||||
static int exp_lut[8] = {0,132,396,924,1980,4092,8316,16764}; /* precalcs from bias */
|
||||
new_sample = exp_lut[segment] + (quantization << (segment + 3));
|
||||
if (sign != 0) new_sample = -new_sample;
|
||||
}
|
||||
#endif
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
||||
/* decodes u-law (ITU G.711 non-linear PCM), from g711.c */
|
||||
void decode_ulaw(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i, sample_count;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
uint8_t ulawbyte = read_8bit(stream->offset+i,stream->streamfile);
|
||||
outbuf[sample_count] = expand_ulaw(ulawbyte);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void decode_ulaw_int(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i, sample_count;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
uint8_t ulawbyte = read_8bit(stream->offset+i*channelspacing,stream->streamfile);
|
||||
outbuf[sample_count] = expand_ulaw(ulawbyte);
|
||||
}
|
||||
}
|
||||
|
||||
static int expand_alaw(uint8_t alawbyte) {
|
||||
int sign, segment, quantization, sample;
|
||||
|
||||
alawbyte ^= 0x55;
|
||||
sign = (alawbyte & 0x80);
|
||||
segment = (alawbyte & 0x70) >> 4; /* exponent */
|
||||
quantization = alawbyte & 0x0F; /* mantissa */
|
||||
|
||||
sample = (quantization << 4);
|
||||
switch (segment) {
|
||||
case 0:
|
||||
sample += 8;
|
||||
break;
|
||||
case 1:
|
||||
sample += 0x108;
|
||||
break;
|
||||
default:
|
||||
sample += 0x108;
|
||||
sample <<= segment - 1;
|
||||
break;
|
||||
}
|
||||
sample = (sign) ? sample : -sample;
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
||||
/* decodes a-law (ITU G.711 non-linear PCM), from g711.c */
|
||||
void decode_alaw(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i, sample_count;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
uint8_t alawbyte = read_8bit(stream->offset+i,stream->streamfile);
|
||||
outbuf[sample_count] = expand_alaw(alawbyte);;
|
||||
}
|
||||
}
|
||||
|
||||
void decode_pcmfloat(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int big_endian) {
|
||||
int i, sample_count;
|
||||
float (*read_f32)(off_t,STREAMFILE*) = big_endian ? read_f32be : read_f32le;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
float sample_float = read_f32(stream->offset+i*4,stream->streamfile);
|
||||
// TODO: remove after public API is used
|
||||
static void decode_pcmfloat_i16(VGMSTREAMCHANNEL* stream, int16_t* outbuf, int channels, int samples_to_do, bool big_endian) {
|
||||
read_f32_t read_f32 = big_endian ? read_f32be : read_f32le;
|
||||
int s = 0;
|
||||
off_t offset = stream->offset;
|
||||
while (s < samples_to_do) {
|
||||
float sample_float = read_f32(offset, stream->streamfile);
|
||||
int sample_pcm = (int)floor(sample_float * 32767.f + .5f);
|
||||
|
||||
outbuf[sample_count] = clamp16(sample_pcm);
|
||||
outbuf[s] = clamp16(sample_pcm);
|
||||
s += channels;
|
||||
offset += 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
void decode_pcm24be(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i;
|
||||
int32_t sample_count;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count += channelspacing) {
|
||||
off_t offset = stream->offset + i * 0x03;
|
||||
int v = read_u8(offset+0x02, stream->streamfile) | (read_s16be(offset + 0x00, stream->streamfile) << 8);
|
||||
outbuf[sample_count] = (v >> 8);
|
||||
static void decode_pcmfloat(VGMSTREAMCHANNEL* stream, float* buf, int channels, int samples_to_do, bool big_endian) {
|
||||
read_f32_t read_f32 = big_endian ? read_f32be : read_f32le;
|
||||
int s = 0;
|
||||
off_t offset = stream->offset;
|
||||
while (s < samples_to_do) {
|
||||
buf[s] = read_f32(offset, stream->streamfile);
|
||||
s += channels;
|
||||
offset += 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
void decode_pcm24le(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i;
|
||||
int32_t sample_count;
|
||||
bool decode_buf_pcmfloat(VGMSTREAM* v, sbuf_t* sdst) {
|
||||
decode_state_t* ds = v->decode_state;
|
||||
bool big_endian = v->codec_endian;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
off_t offset = stream->offset + i * 0x03;
|
||||
int v = read_u8(offset+0x00, stream->streamfile) | (read_s16le(offset + 0x01, stream->streamfile) << 8);
|
||||
outbuf[sample_count] = (v >> 8);
|
||||
if (sdst->fmt == SFMT_S16) {
|
||||
//TODO remove
|
||||
// using vgmstream without API (render_vgmstream) usually passes a S16 buf
|
||||
// could handle externally but blah blah, allow as-is for now
|
||||
int16_t* buffer = sdst->buf;
|
||||
buffer += sdst->filled * v->channels;
|
||||
for (int ch = 0; ch < v->channels; ch++) {
|
||||
decode_pcmfloat_i16(&v->ch[ch], buffer + ch, v->channels, ds->samples_left, big_endian);
|
||||
}
|
||||
}
|
||||
else {
|
||||
float* buffer = sdst->buf;
|
||||
buffer += sdst->filled * v->channels;
|
||||
for (int ch = 0; ch < v->channels; ch++) {
|
||||
decode_pcmfloat(&v->ch[ch], buffer + ch, v->channels, ds->samples_left, big_endian);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static inline int32_t read_s24be(off_t offset, STREAMFILE* sf) {
|
||||
return (read_s16be(offset + 0x00, sf) << 8) | read_u8(offset + 0x02, sf);
|
||||
}
|
||||
|
||||
static inline int32_t read_s24le(off_t offset, STREAMFILE* sf) {
|
||||
return read_u8(offset + 0x00, sf) | (read_s16le(offset + 0x01, sf) << 8);
|
||||
}
|
||||
|
||||
// TODO: remove after public API is used
|
||||
static void decode_pcm24_i16(VGMSTREAMCHANNEL* stream, int16_t* buf, int channels, int samples_to_do, bool big_endian) {
|
||||
read_s32_t read_s24 = big_endian ? read_s24be : read_s24le;
|
||||
int s = 0;
|
||||
off_t offset = stream->offset;
|
||||
while (s < samples_to_do) {
|
||||
buf[s] = read_s24(offset, stream->streamfile) >> 8;
|
||||
s += channels;
|
||||
offset += 0x03;
|
||||
}
|
||||
}
|
||||
|
||||
void decode_pcm32le(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i;
|
||||
int32_t sample_count;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
off_t offset = stream->offset + i * 0x04;
|
||||
int32_t v = read_s32le(offset, stream->streamfile);
|
||||
outbuf[sample_count] = (v >> 16);
|
||||
static void decode_pcm24(VGMSTREAMCHANNEL* stream, int32_t* buf, int channels, int samples_to_do, bool big_endian) {
|
||||
read_s32_t read_s24 = big_endian ? read_s24be : read_s24le;
|
||||
int s = 0;
|
||||
off_t offset = stream->offset;
|
||||
while (s < samples_to_do) {
|
||||
buf[s] = read_s24(offset, stream->streamfile);
|
||||
s += channels;
|
||||
offset += 0x03;
|
||||
}
|
||||
}
|
||||
|
||||
bool decode_buf_pcm24(VGMSTREAM* v, sbuf_t* sdst) {
|
||||
decode_state_t* ds = v->decode_state;
|
||||
bool big_endian = v->coding_type == coding_PCM24BE;
|
||||
|
||||
if (sdst->fmt == SFMT_S16) {
|
||||
//TODO remove
|
||||
// using vgmstream without API (render_vgmstream) usually passes a S16 buf
|
||||
// could handle externally but blah blah, allow as-is for now
|
||||
int16_t* buffer = sdst->buf;
|
||||
buffer += sdst->filled * v->channels;
|
||||
for (int ch = 0; ch < v->channels; ch++) {
|
||||
decode_pcm24_i16(&v->ch[ch], buffer + ch, v->channels, ds->samples_left, big_endian);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int32_t* buffer = sdst->buf;
|
||||
buffer += sdst->filled * v->channels;
|
||||
for (int ch = 0; ch < v->channels; ch++) {
|
||||
decode_pcm24(&v->ch[ch], buffer + ch, v->channels, ds->samples_left, big_endian);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
// TODO: remove after public API is used
|
||||
static void decode_pcm32_i16(VGMSTREAMCHANNEL* stream, int16_t* buf, int channels, int samples_to_do, bool big_endian) {
|
||||
read_s32_t read_s32 = big_endian ? read_s32be : read_s32le;
|
||||
int s = 0;
|
||||
off_t offset = stream->offset;
|
||||
while (s < samples_to_do) {
|
||||
buf[s] = read_s32(offset, stream->streamfile) >> 16;
|
||||
s += channels;
|
||||
offset += 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
static void decode_pcm32(VGMSTREAMCHANNEL* stream, int32_t* buf, int channels, int samples_to_do, bool big_endian) {
|
||||
read_s32_t read_s32 = big_endian ? read_s32be : read_s32le;
|
||||
int s = 0;
|
||||
off_t offset = stream->offset;
|
||||
while (s < samples_to_do) {
|
||||
buf[s] = read_s32(offset, stream->streamfile);
|
||||
s += channels;
|
||||
offset += 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
bool decode_buf_pcm32(VGMSTREAM* v, sbuf_t* sdst) {
|
||||
decode_state_t* ds = v->decode_state;
|
||||
bool big_endian = false;
|
||||
|
||||
if (sdst->fmt == SFMT_S16) {
|
||||
//TODO remove
|
||||
// using vgmstream without API (render_vgmstream) usually passes a S16 buf
|
||||
// could handle externally but blah blah, allow as-is for now
|
||||
int16_t* buffer = sdst->buf;
|
||||
buffer += sdst->filled * v->channels;
|
||||
for (int ch = 0; ch < v->channels; ch++) {
|
||||
decode_pcm32_i16(&v->ch[ch], buffer + ch, v->channels, ds->samples_left, big_endian);
|
||||
}
|
||||
}
|
||||
else {
|
||||
int32_t* buffer = sdst->buf;
|
||||
buffer += sdst->filled * v->channels;
|
||||
for (int ch = 0; ch < v->channels; ch++) {
|
||||
decode_pcm32(&v->ch[ch], buffer + ch, v->channels, ds->samples_left, big_endian);
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
int32_t pcm_bytes_to_samples(size_t bytes, int channels, int bits_per_sample) {
|
||||
if (channels <= 0 || bits_per_sample <= 0) return 0;
|
||||
return ((int64_t)bytes * 8) / channels / bits_per_sample;
|
||||
}
|
||||
|
||||
#if 0
|
||||
int32_t pcm32_bytes_to_samples(size_t bytes, int channels) {
|
||||
return pcm_bytes_to_samples(bytes, channels, 32);
|
||||
}
|
||||
#endif
|
||||
|
||||
int32_t pcm24_bytes_to_samples(size_t bytes, int channels) {
|
||||
return pcm_bytes_to_samples(bytes, channels, 24);
|
||||
|
@ -269,3 +306,18 @@ int32_t pcm16_bytes_to_samples(size_t bytes, int channels) {
|
|||
int32_t pcm8_bytes_to_samples(size_t bytes, int channels) {
|
||||
return pcm_bytes_to_samples(bytes, channels, 8);
|
||||
}
|
||||
|
||||
const codec_info_t pcm32_decoder = {
|
||||
.sample_type = SFMT_S32,
|
||||
.decode_buf = decode_buf_pcm32,
|
||||
};
|
||||
|
||||
const codec_info_t pcm24_decoder = {
|
||||
.sample_type = SFMT_S24,
|
||||
.decode_buf = decode_buf_pcm24,
|
||||
};
|
||||
|
||||
const codec_info_t pcmfloat_decoder = {
|
||||
.sample_type = SFMT_FLT,
|
||||
.decode_buf = decode_buf_pcmfloat,
|
||||
};
|
||||
|
|
|
@ -97,7 +97,7 @@ bool decode_frame_tac(VGMSTREAM* v) {
|
|||
if (samples < 0)
|
||||
return false;
|
||||
|
||||
sbuf_init_f32(&ds->sbuf, data->fbuf, samples, v->channels);
|
||||
sbuf_init_f16(&ds->sbuf, data->fbuf, samples, v->channels);
|
||||
ds->sbuf.filled = samples;
|
||||
|
||||
// copy and let decoder handle
|
||||
|
@ -146,7 +146,7 @@ static void seek_tac(VGMSTREAM* v, int32_t num_sample) {
|
|||
}
|
||||
|
||||
const codec_info_t tac_decoder = {
|
||||
.sample_type = SFMT_F32,
|
||||
.sample_type = SFMT_F16,
|
||||
.decode_frame = decode_frame_tac,
|
||||
.free = free_tac,
|
||||
.reset = reset_tac,
|
||||
|
|
84
Frameworks/vgmstream/vgmstream/src/coding/ualaw_decoder.c
Normal file
84
Frameworks/vgmstream/vgmstream/src/coding/ualaw_decoder.c
Normal file
|
@ -0,0 +1,84 @@
|
|||
#include "coding.h"
|
||||
#include "../util.h"
|
||||
#include <math.h>
|
||||
|
||||
|
||||
static int expand_ulaw(uint8_t ulawbyte) {
|
||||
int sign, segment, quantization, sample;
|
||||
const int bias = 0x84;
|
||||
|
||||
ulawbyte = ~ulawbyte; /* stored in complement */
|
||||
sign = (ulawbyte & 0x80);
|
||||
segment = (ulawbyte & 0x70) >> 4; /* exponent */
|
||||
quantization = ulawbyte & 0x0F; /* mantissa */
|
||||
|
||||
sample = (quantization << 3) + bias; /* add bias */
|
||||
sample <<= segment;
|
||||
sample = (sign) ? (bias - sample) : (sample - bias); /* remove bias */
|
||||
|
||||
#if 0 // the above follows Sun's implementation, but this works too
|
||||
{
|
||||
static int exp_lut[8] = {0,132,396,924,1980,4092,8316,16764}; /* precalcs from bias */
|
||||
new_sample = exp_lut[segment] + (quantization << (segment + 3));
|
||||
if (sign != 0) new_sample = -new_sample;
|
||||
}
|
||||
#endif
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
||||
/* decodes u-law (ITU G.711 non-linear PCM), from g711.c */
|
||||
void decode_ulaw(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i, sample_count;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
uint8_t ulawbyte = read_u8(stream->offset+i,stream->streamfile);
|
||||
outbuf[sample_count] = expand_ulaw(ulawbyte);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void decode_ulaw_int(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i, sample_count;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
uint8_t ulawbyte = read_u8(stream->offset+i*channelspacing,stream->streamfile);
|
||||
outbuf[sample_count] = expand_ulaw(ulawbyte);
|
||||
}
|
||||
}
|
||||
|
||||
static int expand_alaw(uint8_t alawbyte) {
|
||||
int sign, segment, quantization, sample;
|
||||
|
||||
alawbyte ^= 0x55;
|
||||
sign = (alawbyte & 0x80);
|
||||
segment = (alawbyte & 0x70) >> 4; /* exponent */
|
||||
quantization = alawbyte & 0x0F; /* mantissa */
|
||||
|
||||
sample = (quantization << 4);
|
||||
switch (segment) {
|
||||
case 0:
|
||||
sample += 8;
|
||||
break;
|
||||
case 1:
|
||||
sample += 0x108;
|
||||
break;
|
||||
default:
|
||||
sample += 0x108;
|
||||
sample <<= segment - 1;
|
||||
break;
|
||||
}
|
||||
sample = (sign) ? sample : -sample;
|
||||
|
||||
return sample;
|
||||
}
|
||||
|
||||
/* decodes a-law (ITU G.711 non-linear PCM), from g711.c */
|
||||
void decode_alaw(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||
int i, sample_count;
|
||||
|
||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||
uint8_t alawbyte = read_8bit(stream->offset+i,stream->streamfile);
|
||||
outbuf[sample_count] = expand_alaw(alawbyte);;
|
||||
}
|
||||
}
|
|
@ -422,6 +422,7 @@ static const char* extension_list[] = {
|
|||
"oor",
|
||||
"opu",
|
||||
//"opus", //common
|
||||
"opusnx",
|
||||
"opusx",
|
||||
"oto", //txth/reserved [Vampire Savior (SAT)]
|
||||
"ovb", //txth/semi [namCollection: Tekken (PS2), Tekken 5: Tekken 1-3 (PS2)]
|
||||
|
@ -460,7 +461,6 @@ static const char* extension_list[] = {
|
|||
"rda", //FFmpeg/reserved [Rhythm Destruction (PC)]
|
||||
"res", //txth/reserved [Spider-Man: Web of Shadows (PSP)]
|
||||
"rkv",
|
||||
"rnd",
|
||||
"rof",
|
||||
"rpgmvo",
|
||||
"rrds",
|
||||
|
@ -501,7 +501,7 @@ static const char* extension_list[] = {
|
|||
"sbr",
|
||||
"sbv",
|
||||
"sig",
|
||||
"slb", //txth/reserved [Vingt-et-un Systems PS2 games (Last Escort, etc]
|
||||
"slb", //txth/reserved [Vingt-et-un Systems PS2 games (Last Escort, etc)]
|
||||
"sm0",
|
||||
"sm1",
|
||||
"sm2",
|
||||
|
@ -540,6 +540,7 @@ static const char* extension_list[] = {
|
|||
"smk",
|
||||
"smp",
|
||||
"smv",
|
||||
"sn0",
|
||||
"snb",
|
||||
"snd",
|
||||
"snds",
|
||||
|
@ -559,6 +560,7 @@ static const char* extension_list[] = {
|
|||
"srsa",
|
||||
"ss2",
|
||||
"ssd", //txth/reserved [Zack & Wiki (Wii)]
|
||||
"ssf",
|
||||
"ssm",
|
||||
"sspr",
|
||||
"ssp",
|
||||
|
@ -617,7 +619,6 @@ static const char* extension_list[] = {
|
|||
"vai",
|
||||
"vam", //txth/reserved [Rocket Power: Beach Bandits (PS2)]
|
||||
"vas",
|
||||
"vawx",
|
||||
"vb", //txth/reserved [Tantei Jinguji Saburo: Mikan no Rupo (PS1)]
|
||||
"vbk",
|
||||
"vbx", //txth/reserved [THE Taxi 2 (PS2)]
|
||||
|
@ -703,6 +704,7 @@ static const char* extension_list[] = {
|
|||
"xnb",
|
||||
"xsh",
|
||||
"xsf",
|
||||
"xst",
|
||||
"xse",
|
||||
"xsew",
|
||||
"xss",
|
||||
|
@ -978,13 +980,13 @@ static const layout_info layout_info_list[] = {
|
|||
{layout_blocked_ea_1snh, "blocked (EA 1SNh)"},
|
||||
{layout_blocked_caf, "blocked (CAF)"},
|
||||
{layout_blocked_wsi, "blocked (WSI)"},
|
||||
{layout_blocked_xvas, "blocked (.vas)"},
|
||||
{layout_blocked_vas_kceo, "blocked (.vas)"},
|
||||
{layout_blocked_str_snds, "blocked (.str SNDS)"},
|
||||
{layout_blocked_ws_aud, "blocked (Westwood Studios .aud)"},
|
||||
{layout_blocked_dec, "blocked (DEC)"},
|
||||
{layout_blocked_vs_mh, "blocked (Melbourne House VS)"},
|
||||
{layout_blocked_mul, "blocked (MUL)"},
|
||||
{layout_blocked_gsb, "blocked (GSB)"},
|
||||
{layout_blocked_gsnd, "blocked (GSND)"},
|
||||
{layout_blocked_thp, "blocked (THP)"},
|
||||
{layout_blocked_filp, "blocked (FILP)"},
|
||||
{layout_blocked_ea_swvr, "blocked (EA SWVR)"},
|
||||
|
@ -1163,7 +1165,7 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_YDSP, "Yuke's YDSP Header"},
|
||||
{meta_SSM, "HAL Laboratory .SSM Header"},
|
||||
{meta_PS2_JOE, "Asobo Studio .JOE header"},
|
||||
{meta_VGS, "Guitar Hero VGS Header"},
|
||||
{meta_VGS, "Harmonix VGS Header"},
|
||||
{meta_DCS_WAV, "In Utero DCS+WAV header"},
|
||||
{meta_SMP, "Infernal Engine .smp header"},
|
||||
{meta_MUL, "Crystal Dynamics .MUL header"},
|
||||
|
@ -1173,7 +1175,7 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_GBTS, "Konami GBTS header"},
|
||||
{meta_NGC_DSP_IADP, "IADP Header"},
|
||||
{meta_RIFF_WAVE_ctrl, "RIFF WAVE header (ctrl looping)"},
|
||||
{meta_FFCC_STR, "Final Fantasy: Crystal Chronicles STR header"},
|
||||
{meta_STR_SQEX, "Square Enix STR header"},
|
||||
{meta_SAT_BAKA, "Konami BAKA header"},
|
||||
{meta_SWAV, "Nintendo SWAV header"},
|
||||
{meta_VSF, "Square Enix VSF header"},
|
||||
|
@ -1188,12 +1190,12 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_WII_NDP, "Icon Games NDP header"},
|
||||
{meta_PS2_SPS, "Ape Escape 2 SPS Header"},
|
||||
{meta_NDS_HWAS, "Vicarious Visions HWAS header"},
|
||||
{meta_NGC_LPS, "Rave Master LPS Header"},
|
||||
{meta_LPS, "Konami .LPS Header"},
|
||||
{meta_NAOMI_ADPCM, "NAOMI/NAOMI2 Arcade games ADPCM 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_VGV, "Human Head .VGV header"},
|
||||
{meta_GCUB, "Sega GCub header"},
|
||||
{meta_NGC_SCK_DSP, "The Scorpion King SCK Header"},
|
||||
{meta_CAFF, "Apple Core Audio Format File header"},
|
||||
|
@ -1239,7 +1241,7 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_XVAG, "Sony XVAG header"},
|
||||
{meta_CPS, "tri-Crescendo CPS Header"},
|
||||
{meta_SQEX_SCD, "Square Enix SCD header"},
|
||||
{meta_NGC_NST_DSP, "Animaniacs NST header"},
|
||||
{meta_NST_MONSTER, "Monster .NST header"},
|
||||
{meta_BAF, "Bizarre Creations .baf header"},
|
||||
{meta_MSF, "Sony MSF header"},
|
||||
{meta_SNDP, "Premium Agency SNDP header"},
|
||||
|
@ -1247,7 +1249,7 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_RAS, "Retro RAS_ header"},
|
||||
{meta_SPM, "Square SPM header"},
|
||||
{meta_VGS_PS, "Princess Soft VGS header"},
|
||||
{meta_PS2_IAB, "Runtime .IAB header"},
|
||||
{meta_IAB, "Runtime .IAB header"},
|
||||
{meta_VS_STR, "Square .VS STRx header"},
|
||||
{meta_LSF_N1NJ4N, "Gizmondo Studios Helsingborg LSF header"},
|
||||
{meta_XWAV, "feelplus XWAV header"},
|
||||
|
@ -1256,13 +1258,13 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_PSND, "Polarbit PSND header"},
|
||||
{meta_ADP_WILDFIRE, "Wildfire ADP! header"},
|
||||
{meta_QD_ADP, "Quantic Dream .ADP header"},
|
||||
{meta_EB_SFX, "Excitebots .sfx header"},
|
||||
{meta_EB_SF0, "assumed Excitebots .sf0 by extension"},
|
||||
{meta_SFX0_MONSTER, "Monster SFX0 header"},
|
||||
{meta_SONG_MONSTER, "Monster SONG header"},
|
||||
{meta_MTAF, "Konami MTAF header"},
|
||||
{meta_ALP, "High Voltage ALP header"},
|
||||
{meta_WPD, "Navel WPD header"},
|
||||
{meta_MN_STR, "Mini Ninjas 'STR' header"},
|
||||
{meta_MSS, "Guerilla MCSS header"},
|
||||
{meta_MCSS, "Guerilla MCSS header"},
|
||||
{meta_PS2_HSF, "Lowrider 'HSF' header"},
|
||||
{meta_IVAG, "Namco IVAG header"},
|
||||
{meta_2PFS, "Konami 2PFS header"},
|
||||
|
@ -1275,7 +1277,7 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_KTSS, "Koei Tecmo KTSS header"},
|
||||
{meta_IDSP_NAMCO, "Namco IDSP header"},
|
||||
{meta_BTSND, "Nintendo Wii U Menu Boot Sound header"},
|
||||
{meta_MCA, "Capcom MCA header"},
|
||||
{meta_MADP, "Capcom MADP header"},
|
||||
{meta_ADX_MONSTER, "Monster Games .ADX header"},
|
||||
{meta_HCA, "CRI HCA header"},
|
||||
{meta_SVAG_SNK, "SNK SVAG header"},
|
||||
|
@ -1306,11 +1308,11 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_EA_SNU, "Electronic Arts SNU header"},
|
||||
{meta_AWC, "Rockstar AWC header"},
|
||||
{meta_OPUS, "Nintendo Switch OPUS header"},
|
||||
{meta_PC_AST, "Capcom AST (PC) header"},
|
||||
{meta_ASTL, "Capcom ASTL header"},
|
||||
{meta_UBI_SB, "Ubisoft SBx header"},
|
||||
{meta_UBI_APM, "Ubisoft APM header"},
|
||||
{meta_NAAC, "Namco NAAC header"},
|
||||
{meta_EZW, "EZ2DJ EZWAVE header"},
|
||||
{meta_EZW, "AmuseWorld EZW header"},
|
||||
{meta_VXN, "Gameloft VXN header"},
|
||||
{meta_EA_SNR_SNS, "Electronic Arts SNR+SNS header"},
|
||||
{meta_EA_SPS, "Electronic Arts SPS header"},
|
||||
|
@ -1367,7 +1369,7 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_AO, "AlphaOgg .AO header"},
|
||||
{meta_APC, "Cryo APC header"},
|
||||
{meta_WAV2, "Infogrames North America WAV2 header"},
|
||||
{meta_XAU_KONAMI, "Konami XAU header"},
|
||||
{meta_SFXB, "Konami SFXB header"},
|
||||
{meta_DERF, "Xilam DERF header"},
|
||||
{meta_UTK, "Maxis UTK header"},
|
||||
{meta_NXA1, "Entergram NXA1 header"},
|
||||
|
@ -1462,7 +1464,7 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_SNDS, "Sony SNDS header"},
|
||||
{meta_NXOF, "Nihon Falcom FDK header"},
|
||||
{meta_GWB_GWD, "Ubisoft GWB+GWD header"},
|
||||
{meta_CBX, "Traveller's Tales CBX header"},
|
||||
{meta_CBX, "Traveller's Tales/Warthog Chatterbox header"},
|
||||
{meta_VAS_ROCKSTAR, "Rockstar .VAS header"},
|
||||
{meta_EA_SBK, "Electronic Arts SBK header"},
|
||||
{meta_DSP_ASURA, "Rebellion DSP header"},
|
||||
|
|
|
@ -133,14 +133,14 @@ void block_update(off_t block_offset, VGMSTREAM* vgmstream) {
|
|||
case layout_blocked_mul:
|
||||
block_update_mul(block_offset,vgmstream);
|
||||
break;
|
||||
case layout_blocked_gsb:
|
||||
block_update_gsb(block_offset,vgmstream);
|
||||
case layout_blocked_gsnd:
|
||||
block_update_gsnd(block_offset,vgmstream);
|
||||
break;
|
||||
case layout_blocked_vs_mh:
|
||||
block_update_vs_mh(block_offset,vgmstream);
|
||||
break;
|
||||
case layout_blocked_xvas:
|
||||
block_update_xvas(block_offset,vgmstream);
|
||||
case layout_blocked_vas_kceo:
|
||||
block_update_vas_kceo(block_offset,vgmstream);
|
||||
break;
|
||||
case layout_blocked_thp:
|
||||
block_update_thp(block_offset,vgmstream);
|
||||
|
|
|
@ -3,17 +3,14 @@
|
|||
|
||||
/* set up for the block at the given offset */
|
||||
void block_update_filp(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
int i;
|
||||
STREAMFILE* sf = vgmstream->ch[0].streamfile;
|
||||
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = read_32bitLE(
|
||||
vgmstream->current_block_offset+0x18,
|
||||
vgmstream->ch[0].streamfile)-0x800;
|
||||
vgmstream->next_block_offset = vgmstream->current_block_offset+vgmstream->current_block_size+0x800;
|
||||
vgmstream->current_block_size/=vgmstream->channels;
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = read_u32le(block_offset + 0x18,sf) - 0x800;
|
||||
vgmstream->next_block_offset = block_offset + vgmstream->current_block_size + 0x800;
|
||||
vgmstream->current_block_size /= vgmstream->channels;
|
||||
|
||||
for (i=0;i<vgmstream->channels;i++) {
|
||||
vgmstream->ch[i].offset = vgmstream->current_block_offset+0x800+(vgmstream->current_block_size*i);
|
||||
|
||||
for (int i = 0; i < vgmstream->channels; i++) {
|
||||
vgmstream->ch[i].offset = block_offset + 0x800+(vgmstream->current_block_size*i);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,28 +0,0 @@
|
|||
#include "layout.h"
|
||||
#include "../vgmstream.h"
|
||||
|
||||
/* set up for the block at the given offset */
|
||||
void block_update_gsb(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
int i;
|
||||
int block_header_size = 0x20; /*from header*/
|
||||
int block_channel_size = 0x8000; /*from header, per channel*/
|
||||
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = block_channel_size;
|
||||
vgmstream->next_block_offset = vgmstream->current_block_offset
|
||||
+ block_header_size
|
||||
+ block_channel_size * vgmstream->channels;
|
||||
|
||||
for (i=0;i<vgmstream->channels;i++) {
|
||||
int interleave;
|
||||
int filesize = vgmstream->ch[i].streamfile->get_size(vgmstream->ch[i].streamfile);
|
||||
if (vgmstream->next_block_offset > filesize)
|
||||
interleave = (filesize - vgmstream->current_block_offset - block_header_size) / vgmstream->channels;
|
||||
else
|
||||
interleave = block_channel_size;
|
||||
|
||||
vgmstream->ch[i].offset = vgmstream->current_block_offset
|
||||
+ block_header_size
|
||||
+ (interleave*i);
|
||||
}
|
||||
}
|
25
Frameworks/vgmstream/vgmstream/src/layout/blocked_gsnd.c
Normal file
25
Frameworks/vgmstream/vgmstream/src/layout/blocked_gsnd.c
Normal file
|
@ -0,0 +1,25 @@
|
|||
#include "layout.h"
|
||||
#include "../vgmstream.h"
|
||||
|
||||
/* set up for the block at the given offset */
|
||||
void block_update_gsnd(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
STREAMFILE* sf = vgmstream->ch[0].streamfile;
|
||||
|
||||
int block_header_size = 0x20; // from header
|
||||
int block_channel_size = 0x8000; // from header, per channel
|
||||
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = block_channel_size;
|
||||
vgmstream->next_block_offset = block_offset + block_header_size + block_channel_size * vgmstream->channels;
|
||||
|
||||
uint32_t file_size = get_streamfile_size(sf);
|
||||
for (int i = 0; i < vgmstream->channels; i++) {
|
||||
int interleave;
|
||||
if (vgmstream->next_block_offset > file_size)
|
||||
interleave = (file_size - block_offset - block_header_size) / vgmstream->channels;
|
||||
else
|
||||
interleave = block_channel_size;
|
||||
|
||||
vgmstream->ch[i].offset = block_offset + block_header_size + (interleave * i);
|
||||
}
|
||||
}
|
22
Frameworks/vgmstream/vgmstream/src/layout/blocked_vas_kceo.c
Normal file
22
Frameworks/vgmstream/vgmstream/src/layout/blocked_vas_kceo.c
Normal file
|
@ -0,0 +1,22 @@
|
|||
#include "layout.h"
|
||||
#include "../vgmstream.h"
|
||||
|
||||
/* set up for the block at the given offset */
|
||||
void block_update_vas_kceo(off_t block_offset, VGMSTREAM* vgmstream) {
|
||||
STREAMFILE* sf = vgmstream->ch[0].streamfile;
|
||||
|
||||
// last block is smaller in a few non-looped files
|
||||
int file_size = get_streamfile_size(sf);
|
||||
int block_size = 0x20000;
|
||||
if (block_offset + block_size > file_size) {
|
||||
block_size = file_size - block_offset;
|
||||
}
|
||||
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = (block_size - 0x20) / vgmstream->channels;
|
||||
vgmstream->next_block_offset = block_offset + block_size;
|
||||
|
||||
for (int i = 0; i < vgmstream->channels; i++) {
|
||||
vgmstream->ch[i].offset = block_offset; //stereo XBOX-IMA
|
||||
}
|
||||
}
|
|
@ -1,24 +0,0 @@
|
|||
#include "layout.h"
|
||||
#include "../vgmstream.h"
|
||||
|
||||
/* set up for the block at the given offset */
|
||||
void block_update_xvas(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
int i;
|
||||
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
|
||||
if((vgmstream->current_block_offset-get_streamfile_size(vgmstream->ch[0].streamfile))>(0x20000-0x20))
|
||||
vgmstream->current_block_size = 0x20000-0x20;
|
||||
else
|
||||
vgmstream->current_block_size = vgmstream->current_block_offset-get_streamfile_size(vgmstream->ch[0].streamfile)-0x20;
|
||||
|
||||
vgmstream->next_block_offset =
|
||||
vgmstream->current_block_offset +
|
||||
(vgmstream->current_block_size + 0x20);
|
||||
|
||||
for (i=0;i<vgmstream->channels;i++) {
|
||||
vgmstream->ch[i].offset = vgmstream->current_block_offset;
|
||||
}
|
||||
vgmstream->current_block_size /=2;
|
||||
|
||||
}
|
|
@ -39,7 +39,7 @@ void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample);
|
|||
typedef struct {
|
||||
int layer_count;
|
||||
VGMSTREAM** layers;
|
||||
sample_t* buffer;
|
||||
void* buffer;
|
||||
int input_channels; /* internal buffer channels */
|
||||
int output_channels; /* resulting channels (after mixing, if applied) */
|
||||
int external_looping; /* don't loop using per-layer loops, but layout's own looping */
|
||||
|
@ -72,8 +72,8 @@ void block_update_ws_aud(off_t block_offset, VGMSTREAM* vgmstream);
|
|||
void block_update_dec(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_vs_mh(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_mul(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_gsb(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_xvas(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_gsnd(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_vas_kceo(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_thp(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_filp(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_rage_aud(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
|
|
|
@ -64,7 +64,7 @@
|
|||
LIBVGMSTREAM_API uint32_t libvgmstream_get_version(void);
|
||||
|
||||
/* CHANGELOG:
|
||||
* - 1.0.0: initial version
|
||||
* - 1.0.0: beta version
|
||||
*/
|
||||
|
||||
|
||||
|
@ -74,8 +74,8 @@ LIBVGMSTREAM_API uint32_t libvgmstream_get_version(void);
|
|||
/* available sample formats, interleaved: buf[0]=ch0, buf[1]=ch1, buf[2]=ch0, buf[3]=ch0, ... */
|
||||
typedef enum {
|
||||
LIBVGMSTREAM_SFMT_PCM16 = 1,
|
||||
//LIBVGMSTREAM_SFMT_PCM24 = 2,
|
||||
//LIBVGMSTREAM_SFMT_PCM32 = 3,
|
||||
LIBVGMSTREAM_SFMT_PCM24 = 2,
|
||||
LIBVGMSTREAM_SFMT_PCM32 = 3,
|
||||
LIBVGMSTREAM_SFMT_FLOAT = 4,
|
||||
} libvgmstream_sfmt_t;
|
||||
|
||||
|
|
|
@ -3,48 +3,58 @@
|
|||
#include "../layout/layout.h"
|
||||
|
||||
|
||||
/* .2dx - Konami/Bemani beatmania IIDX container [beatmania IIDX 9th Style (AC) - beatmania IIDX 15 DJ TROOPERS (AC)] */
|
||||
/* .2dx - Konami/Bemani beatmania IIDX container [beatmania IIDX 9th Style (AC) - beatmania IIDX 15 DJ TROOPERS (AC), Bishi Bashi Channel (AC)] */
|
||||
VGMSTREAM* init_vgmstream_2dx(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
STREAMFILE* temp_sf = NULL;
|
||||
int target_subsong = sf->stream_index, total_subsongs;
|
||||
uint32_t meta_offset, table_offset, subfile_offset, subfile_size;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(sf, "2dx"))
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
/* Check for leftover crypto header */
|
||||
/*
|
||||
if (read_u32be(0x00, sf) == 0x25654E63 || //IIDX 9th Style
|
||||
read_u32be(0x00, sf) == 0x25653130 || //IIDX 10th Style
|
||||
read_u32be(0x00, sf) == 0x25653131 || //IIDX 11 RED
|
||||
read_u32be(0x00, sf) == 0x25653132 || //IIDX 12 HAPPY SKY
|
||||
read_u32be(0x00, sf) == 0x25686964 || //IIDX 15 DJ TROOPERS
|
||||
read_u32be(0x00, sf) == 0x25694F30) //IIDX 16 EMPRESS
|
||||
meta_offset = 0x18;
|
||||
else */
|
||||
meta_offset = 0x10;
|
||||
table_offset = meta_offset + 0x38;
|
||||
// check for leftover crypto header (not part of the file):
|
||||
// - "%eNc" IIDX 9th Style
|
||||
// - "%e10" IIDX 10th Style
|
||||
// - "%e11" IIDX 11 RED
|
||||
// - "%e12" IIDX 12 HAPPY SKY
|
||||
// - "%hid" IIDX 15 DJ TROOPERS
|
||||
// - "%iO0" IIDX 16 EMPRESS
|
||||
uint32_t skip_offset = 0x00;
|
||||
uint32_t header_id = read_u32be(0x00, sf);
|
||||
uint32_t data_size = read_u32le(0x04, sf); // without padding (0x04 or 0x10)
|
||||
if ((header_id >> 24) == '%' && data_size + 0x10 > get_streamfile_size(sf)) {
|
||||
skip_offset = 0x08;
|
||||
}
|
||||
|
||||
// 00: bank name
|
||||
// 10: first subsong offset
|
||||
// 14: subsongs
|
||||
// 18+: memory garbage?
|
||||
// 48: table
|
||||
uint32_t table_offset = 0x48 + skip_offset;
|
||||
uint32_t first_offset = read_u32le(0x10 + skip_offset,sf);
|
||||
|
||||
int target_subsong = sf->stream_index;
|
||||
int total_subsongs = read_u32le(0x14 + skip_offset,sf);
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
total_subsongs = read_u32le(meta_offset + 0x4,sf);
|
||||
if (target_subsong > total_subsongs)
|
||||
goto fail;
|
||||
if (target_subsong > total_subsongs || total_subsongs < 1) // arbitrary max
|
||||
return NULL;
|
||||
|
||||
subfile_offset = read_u32le(table_offset + 0x04 * (target_subsong - 1), sf);
|
||||
subfile_size = read_u32le(subfile_offset + 0x8,sf) + 0x18;
|
||||
// extra checks to fail faster
|
||||
if (total_subsongs > 1024) // arbitrary max
|
||||
return NULL;
|
||||
if (first_offset != read_u32le(table_offset, sf))
|
||||
return NULL;
|
||||
|
||||
uint32_t subfile_offset = read_u32le(table_offset + 0x04 * (target_subsong - 1), sf) + skip_offset;
|
||||
uint32_t subfile_size = read_u32le(subfile_offset + 0x08, sf) + 0x18;
|
||||
|
||||
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "2dx9");
|
||||
if (!temp_sf) goto fail;
|
||||
|
||||
temp_sf->stream_index = 1;
|
||||
vgmstream = init_vgmstream_2dx9(temp_sf);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
if (vgmstream->num_streams > 1)
|
||||
goto fail;
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
|
||||
close_streamfile(temp_sf);
|
||||
|
|
|
@ -6,26 +6,35 @@ VGMSTREAM* init_vgmstream_astb(STREAMFILE* sf) {
|
|||
VGMSTREAM* vgmstream = NULL;
|
||||
off_t start_offset, data_size;
|
||||
int loop_flag, channels;
|
||||
int i, xma_streams;
|
||||
|
||||
/* check */
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "ASTB"))
|
||||
goto fail;
|
||||
return NULL;
|
||||
if (!check_extensions(sf,"ast"))
|
||||
goto fail;
|
||||
|
||||
if (read_u32be(0x04,sf) != get_streamfile_size(sf))
|
||||
goto fail;
|
||||
if (read_u16be(0x30,sf) != 0x165) /* only seen XMA1 */
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
// 04: file size
|
||||
// 08: 0x200?
|
||||
// 0c: version?
|
||||
start_offset = read_u32be(0x10,sf);
|
||||
// 14: -1?
|
||||
// 18: -1?
|
||||
// 1c: -1?
|
||||
data_size = read_u32be(0x20,sf);
|
||||
xma_streams = read_u16be(0x38,sf);
|
||||
// 24: -1?
|
||||
// 28: -1?
|
||||
// 2c: -1?
|
||||
|
||||
if (read_u16be(0x30,sf) != 0x0165) // XMA1 only
|
||||
return NULL;
|
||||
// 32: xma info size
|
||||
// 34: xma config
|
||||
int xma_streams = read_u16be(0x38,sf);
|
||||
loop_flag = read_u8(0x3a,sf);
|
||||
channels = 0; /* sum of all stream channels (though only 1/2ch ever seen) */
|
||||
for (i = 0; i < xma_streams; i++) {
|
||||
|
||||
int sample_rate = read_s32be(0x3c + 0x04,sf); // first stream
|
||||
channels = 0; // sum of all stream channels (though only 1/2ch are ever seen)
|
||||
for (int i = 0; i < xma_streams; i++) {
|
||||
channels += read_u8(0x3c + 0x14 * i + 0x11,sf);
|
||||
}
|
||||
|
||||
|
@ -34,8 +43,8 @@ VGMSTREAM* init_vgmstream_astb(STREAMFILE* sf) {
|
|||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = read_s32be(0x40,sf);
|
||||
vgmstream->meta_type = meta_ASTB;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
|
||||
{
|
||||
/* manually find sample offsets (XMA1 nonsense again) */
|
||||
|
|
57
Frameworks/vgmstream/vgmstream/src/meta/astl.c
Normal file
57
Frameworks/vgmstream/vgmstream/src/meta/astl.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* ASTL - found in Dead Rising (PC) */
|
||||
VGMSTREAM* init_vgmstream_astl(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
off_t start_offset, data_size;
|
||||
int loop_flag, channels;
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "ASTL"))
|
||||
return NULL;
|
||||
if (!check_extensions(sf,"ast"))
|
||||
return NULL;
|
||||
|
||||
// 04: null
|
||||
// 08: 0x201?
|
||||
// 0c: version?
|
||||
start_offset = read_u32le(0x10,sf);
|
||||
// 14: null?
|
||||
// 18: null?
|
||||
// 1c: null?
|
||||
data_size = read_u32le(0x20,sf);
|
||||
// 24: -1?
|
||||
// 28: -1?
|
||||
// 2c: -1?
|
||||
|
||||
if (read_u16le(0x30,sf) != 0x0001) // PCM only
|
||||
return NULL;
|
||||
channels = read_u16le(0x32, sf);
|
||||
int sample_rate = read_s32le(0x34,sf);
|
||||
// 38: bitrate
|
||||
// 3a: block size
|
||||
// 3c: bps
|
||||
|
||||
loop_flag = 0; // unlike X360 no apparent loop info in the files
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_ASTL;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = pcm16_bytes_to_samples(data_size, channels);
|
||||
|
||||
vgmstream->coding_type = coding_PCM16LE;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x2;
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -67,7 +67,7 @@ VGMSTREAM* init_vgmstream_axhd(STREAMFILE* sf) {
|
|||
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);
|
||||
|
|
|
@ -2,17 +2,19 @@
|
|||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
/* !B0X - Traveller's Tales speech files [Lego Batman 2 (PC), Lego Dimensions (PS3)] */
|
||||
VGMSTREAM* init_vgmstream_cbx(STREAMFILE* sf) {
|
||||
/* !B0X/CB03 - Traveller's Tales (!B0X) / Warthog (CB03) speech files [Lego Batman 2 (PC), Lego Dimensions (PS3), Animaniacs: The Great Edgar Hunt (GC)] */
|
||||
VGMSTREAM* init_vgmstream_chatterbox(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
uint32_t start_offset, pcm_size;
|
||||
int loop_flag, channels, sample_rate;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "!B0X"))
|
||||
if (!is_id32be(0x00,sf, "!B0X") && !is_id32be(0x00,sf, "CB03"))
|
||||
return NULL;
|
||||
if (!check_extensions(sf, "cbx"))
|
||||
// .cbx: Traveller's Tales
|
||||
// .box: Warthog
|
||||
if (!check_extensions(sf, "cbx,box"))
|
||||
return NULL;
|
||||
|
||||
/* debug strings identify this as "Chatterbox"/"CBOX"/"CBX", while sound lib seems called "NuSound"
|
|
@ -1,169 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* a few formats from Excitebots */
|
||||
|
||||
/* .sfx, some .sf0 - DSP and PCM */
|
||||
VGMSTREAM * init_vgmstream_eb_sfx(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
int coding_type;
|
||||
|
||||
long body_size;
|
||||
long header_size;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("sfx",filename_extension(filename)) &&
|
||||
strcasecmp("sf0",filename_extension(filename)))
|
||||
goto fail;
|
||||
|
||||
/* check sizes */
|
||||
body_size = read_32bitLE(0x00,streamFile);
|
||||
header_size = read_32bitLE(0x04,streamFile);
|
||||
|
||||
if (body_size + header_size != get_streamfile_size(streamFile))
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
|
||||
switch (read_8bit(0x09,streamFile))
|
||||
{
|
||||
case 0:
|
||||
if (header_size != 0x20)
|
||||
goto fail;
|
||||
coding_type = coding_PCM16BE;
|
||||
break;
|
||||
case 1:
|
||||
if (header_size != 0x80)
|
||||
goto fail;
|
||||
coding_type = coding_NGC_DSP;
|
||||
loop_flag = 1;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
channel_count = 1;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = header_size;
|
||||
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
||||
vgmstream->coding_type = coding_type;
|
||||
|
||||
if (coding_NGC_DSP == coding_type)
|
||||
{
|
||||
vgmstream->num_samples = dsp_nibbles_to_samples(body_size*2);
|
||||
|
||||
if (loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = dsp_nibbles_to_samples(read_32bitBE(0x30,streamFile));
|
||||
vgmstream->loop_end_sample = dsp_nibbles_to_samples(read_32bitBE(0x34,streamFile));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
vgmstream->num_samples = body_size / 2;
|
||||
|
||||
if (loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
}
|
||||
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_EB_SFX;
|
||||
vgmstream->allow_dual_stereo = 1;
|
||||
|
||||
/* open the file for reading */
|
||||
{
|
||||
STREAMFILE * file;
|
||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!file) goto fail;
|
||||
vgmstream->ch[0].streamfile = file;
|
||||
|
||||
vgmstream->ch[0].channel_start_offset=
|
||||
vgmstream->ch[0].offset=start_offset;
|
||||
|
||||
if (coding_NGC_DSP == coding_type)
|
||||
{
|
||||
int i;
|
||||
for (i = 0; i < 16; i++)
|
||||
{
|
||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x3C+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* .sf0 - PCM (degenerate stereo .sfx?) */
|
||||
VGMSTREAM * init_vgmstream_eb_sf0(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
long file_size;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("sf0",filename_extension(filename)))
|
||||
goto fail;
|
||||
|
||||
/* no header, check file size and go on faith */
|
||||
file_size = get_streamfile_size(streamFile);
|
||||
if (file_size % 0x8000)
|
||||
goto fail;
|
||||
|
||||
channel_count = 2;
|
||||
loop_flag = 0;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->sample_rate = 32000;
|
||||
vgmstream->num_samples = file_size / 4;
|
||||
vgmstream->coding_type = coding_PCM16BE;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->meta_type = meta_EB_SF0;
|
||||
vgmstream->interleave_block_size = 0x4000;
|
||||
|
||||
/* open the file for reading by each channel */
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[i].offset = vgmstream->interleave_block_size*i;
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* don't know what to do about .sng and .sn0 */
|
|
@ -1,41 +1,45 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util/meta_utils.h"
|
||||
|
||||
/* EZWAVE - EZ2DJ (Arcade) */
|
||||
VGMSTREAM * init_vgmstream_ezw(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset, data_size;
|
||||
int loop_flag, channel_count;
|
||||
/* EZW - from AmuseWorld games [EZ2DJ 5TH (AC)] */
|
||||
VGMSTREAM* init_vgmstream_ezw(STREAMFILE* sf) {
|
||||
|
||||
/* check extension, case insensitive */
|
||||
if ( !check_extensions(streamFile,"ezw"))
|
||||
goto fail;
|
||||
/* checks */
|
||||
int channels = read_s16le(0x00,sf);
|
||||
if (channels < 1 || channels > 16) //arbitrary max
|
||||
return NULL;
|
||||
|
||||
// .ezw: EZ2DJ
|
||||
// .ssf: EZ2AC
|
||||
if (!check_extensions(sf,"ezw,ssf"))
|
||||
return NULL;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = read_8bit(0x0, streamFile);
|
||||
data_size = read_32bitLE(0xE,streamFile);
|
||||
// no header ID but internally it's referred as the "EZW Format"
|
||||
// (some early games use regular .wav instead)
|
||||
|
||||
meta_header_t h = {0};
|
||||
h.meta = meta_EZW;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
h.channels = read_s16le(0x00, sf);
|
||||
h.sample_rate = read_s32le(0x02, sf);
|
||||
// 06: bitrate
|
||||
h.interleave = read_s16le(0x0A, sf) / channels;
|
||||
int bps = read_s16le(0x0C, sf);
|
||||
h.stream_size = read_u32le(0x0E,sf);
|
||||
|
||||
if (h.interleave != 0x02)
|
||||
return NULL;
|
||||
if (bps != 16)
|
||||
return NULL;
|
||||
|
||||
start_offset = 0x12;
|
||||
vgmstream->sample_rate = read_32bitLE(0x2,streamFile);
|
||||
vgmstream->coding_type = coding_PCM16LE;
|
||||
vgmstream->num_samples = data_size/(channel_count*2);
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x2;
|
||||
vgmstream->meta_type = meta_EZW;
|
||||
h.stream_offset = 0x12;
|
||||
h.num_samples = pcm16_bytes_to_samples(h.stream_size, channels);
|
||||
|
||||
/* open the file for reading */
|
||||
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
h.coding = coding_PCM16LE;
|
||||
h.layout = layout_interleave;
|
||||
h.open_stream = true;
|
||||
h.sf = sf;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
return alloc_metastream(&h);
|
||||
}
|
||||
|
|
|
@ -620,6 +620,7 @@ 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");
|
||||
|
||||
#ifdef VGM_USE_MPEG
|
||||
// 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);
|
||||
|
@ -639,6 +640,7 @@ static bool parse_fsb(fsb_header_t* fsb, STREAMFILE* sf) {
|
|||
// 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
|
||||
}
|
||||
#endif
|
||||
|
||||
return true;
|
||||
fail:
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
#include "../coding/coding.h"
|
||||
#include "../util/endianness.h"
|
||||
|
||||
typedef enum { PCM16LE, MSADPCM, XMA2, ATRAC9 } gtd_codec_t;
|
||||
typedef enum { NONE, PCM16LE, MSADPCM, XMA2, ATRAC9, HEVAG } gtd_codec_t;
|
||||
|
||||
static void read_name(VGMSTREAM* vgmstream, STREAMFILE* sf, uint32_t offset);
|
||||
|
||||
|
@ -10,12 +10,11 @@ static void read_name(VGMSTREAM* vgmstream, STREAMFILE* sf, uint32_t offset);
|
|||
/* GHS - Hexadrive's HexaEngine games [Gunslinger Stratos (AC), Knights Contract (X360), Valhalla Knights 3 (Vita)] */
|
||||
VGMSTREAM* init_vgmstream_ghs(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
uint32_t stream_offset, stream_size, stpr_offset = 0, loop_start_offset = 0, loop_end_offset = 0;
|
||||
uint32_t chunk_offset, chunk_size = 0, at9_config_data = 0, block_size = 0;
|
||||
int loop_flag, channels, sample_rate;
|
||||
uint32_t stream_offset, stream_size = 0, stpr_offset = 0, loop_start_offset = 0, loop_end_offset = 0;
|
||||
uint32_t chunk_offset = 0, chunk_size = 0, block_size, at9_config_data = 0;
|
||||
int loop_flag = 0, channels, sample_rate;
|
||||
int32_t num_samples, loop_start_sample, loop_end_sample;
|
||||
gtd_codec_t codec;
|
||||
int total_subsongs = 0, target_subsong = sf->stream_index;
|
||||
gtd_codec_t codec = NONE;
|
||||
|
||||
|
||||
/* checks */
|
||||
|
@ -28,32 +27,90 @@ VGMSTREAM* init_vgmstream_ghs(STREAMFILE* sf) {
|
|||
read_u32_t read_u32 = big_endian ? read_u32be : read_u32le;
|
||||
read_u16_t read_u16 = big_endian ? read_u16be : read_u16le;
|
||||
|
||||
int is_old = 0x34 + read_u32le(0x30,sf) + read_u32le(0x0c,sf) == get_streamfile_size(sf);
|
||||
|
||||
total_subsongs = read_u32(0x04, sf); /* seen in sfx packs inside .ged */
|
||||
int target_subsong = sf->stream_index;
|
||||
int total_subsongs = read_u32(0x04, sf); /* seen in sfx packs inside .ged */
|
||||
if (!check_subsongs(&target_subsong, total_subsongs))
|
||||
return NULL;
|
||||
|
||||
/* not seen */
|
||||
if (target_subsong > 1 && is_old)
|
||||
goto fail;
|
||||
|
||||
/* header version, not formally specified */
|
||||
if (!is_old) {
|
||||
/* 0x08: size of all seek tables (XMA2, all tables go together after headers) / null */
|
||||
// header version is not formally specified, use v1 channels as test (v2 has sample rate in that position)
|
||||
uint32_t version_test = read_u32le(0x10, sf);
|
||||
bool is_v1 = (version_test < 16);
|
||||
|
||||
if (is_v1) {
|
||||
uint32_t offset = 0x08;
|
||||
stream_offset = 0x00;
|
||||
for (int i = 0; i < total_subsongs; i++) {
|
||||
int format = read_u32(offset + 0x00,sf);
|
||||
int temp_size = read_u32(offset + 0x04,sf);
|
||||
|
||||
if (i + 1 == target_subsong) {
|
||||
if (format == 0x0000) {
|
||||
codec = PCM16LE; /* VK3 voices */
|
||||
block_size = 0x02;
|
||||
}
|
||||
else if (format == 0x0001) {
|
||||
codec = HEVAG; /* VK3 voices */
|
||||
block_size = 0x10;
|
||||
}
|
||||
else if (format == 0x0002) {
|
||||
codec = ATRAC9; /* VK3 bgm */
|
||||
block_size = 0;
|
||||
}
|
||||
else {
|
||||
VGM_LOG("GHS: unknown v1 format %x\n", format);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
stream_size = read_u32(offset + 0x04,sf);
|
||||
channels = read_u32(offset + 0x08,sf);
|
||||
sample_rate = read_u32(offset + 0x0c,sf);
|
||||
// 10: null/bps in PCM?
|
||||
loop_start_offset = read_u32(offset + 0x14,sf);
|
||||
loop_end_offset = read_u32(offset + 0x18,sf);
|
||||
// 1c: channel layout in ATRAC9?
|
||||
at9_config_data = read_u32be(offset + 0x20,sf);
|
||||
|
||||
loop_flag = loop_end_offset > loop_start_offset;
|
||||
}
|
||||
|
||||
offset += 0x24;
|
||||
if (i + 1 < target_subsong) {
|
||||
stream_offset += temp_size;
|
||||
}
|
||||
}
|
||||
|
||||
if (codec == NONE)
|
||||
goto fail;
|
||||
|
||||
stream_offset += offset;
|
||||
|
||||
// STPR subheader
|
||||
if (codec == ATRAC9) {
|
||||
if (target_subsong > 1) //unknown STPR position for other subsongs
|
||||
return NULL;
|
||||
stpr_offset = stream_offset;
|
||||
stream_offset = read_u32(stpr_offset + 0x04,sf) + 0x34;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// 0x08: size of all seek tables (XMA2, all tables go together after headers) / null
|
||||
uint32_t offset = 0x0c + (target_subsong - 1) * 0x64;
|
||||
|
||||
int format = read_u16(offset + 0x00,sf);
|
||||
if (format == 0x0001)
|
||||
if (format == 0x0001) {
|
||||
codec = PCM16LE; /* GS bgm */
|
||||
else if (format == 0x0002)
|
||||
}
|
||||
else if (format == 0x0002) {
|
||||
codec = MSADPCM; /* GS sfx */
|
||||
}
|
||||
else if (format == 0x0166) {
|
||||
codec = XMA2;
|
||||
chunk_offset = offset; /* "fmt " */
|
||||
chunk_size = 0x34;
|
||||
}
|
||||
else {
|
||||
VGM_LOG("GHS: unknown v2 format %x\n", format);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
@ -78,24 +135,6 @@ VGMSTREAM* init_vgmstream_ghs(STREAMFILE* sf) {
|
|||
|
||||
stpr_offset = read_u32(offset + 0x54,sf) + read_u32(offset + 0x58,sf);
|
||||
}
|
||||
else {
|
||||
codec = ATRAC9;
|
||||
|
||||
/* 08: always 02? */
|
||||
stream_size = read_u32(0x0c,sf);
|
||||
channels = read_u32(0x10,sf);
|
||||
sample_rate = read_u32(0x14,sf);
|
||||
/* 18: null? */
|
||||
loop_start_offset = read_u32(0x1c,sf);
|
||||
loop_end_offset = read_u32(0x20,sf);
|
||||
/* 24: channel layout? */
|
||||
at9_config_data = read_u32be(0x28,sf);
|
||||
/* 2c: STPR */
|
||||
stream_offset = read_u32(0x30,sf) + 0x34;
|
||||
loop_flag = loop_end_offset > loop_start_offset;
|
||||
|
||||
stpr_offset = 0x2c;
|
||||
}
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
|
@ -130,6 +169,15 @@ VGMSTREAM* init_vgmstream_ghs(STREAMFILE* sf) {
|
|||
|
||||
break;
|
||||
|
||||
case HEVAG:
|
||||
vgmstream->coding_type = coding_HEVAG;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->frame_size = block_size;
|
||||
|
||||
vgmstream->num_samples = ps_bytes_to_samples(stream_size, channels);
|
||||
|
||||
break;
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
case XMA2:
|
||||
vgmstream->codec_data = init_ffmpeg_xma_chunk(sf, stream_offset, stream_size, chunk_offset, chunk_size);
|
||||
|
|
|
@ -14,10 +14,10 @@ VGMSTREAM* init_vgmstream_gsnd(STREAMFILE* sf) {
|
|||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "GSND"))
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
if (!check_extensions(sf,"gsp"))
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
sb = open_streamfile_by_ext(sf, "gsb");
|
||||
if (!sb) goto fail;
|
||||
|
@ -78,7 +78,7 @@ VGMSTREAM* init_vgmstream_gsnd(STREAMFILE* sf) {
|
|||
size_t num_blocks;
|
||||
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->layout_type = layout_blocked_gsb;
|
||||
vgmstream->layout_type = layout_blocked_gsnd;
|
||||
|
||||
if (!find_chunk_be(sf, get_id32be("GCEX"),first_offset,1, &chunk_offset,NULL))
|
||||
goto fail;
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#ifndef _HCA_BF_
|
||||
#define _HCA_BF_
|
||||
|
||||
#include <inttypes.h>
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
|
@ -9,30 +10,37 @@
|
|||
|
||||
static void bruteforce_process_result(hca_keytest_t* hk, unsigned long long* p_keycode) {
|
||||
*p_keycode = hk->best_key;
|
||||
if (hk->best_score < 0 || hk->best_score > 10000) {
|
||||
if (hk->best_score <= 0 || hk->best_score > 10000) {
|
||||
VGM_LOG("HCA BF: no good key found\n");
|
||||
}
|
||||
else {
|
||||
VGM_LOG("HCA BF: best key=%08x%08x (score=%i)\n",
|
||||
(uint32_t)((*p_keycode >> 32) & 0xFFFFFFFF), (uint32_t)(*p_keycode & 0xFFFFFFFF), hk->best_score);
|
||||
VGM_LOG("HCA BF: best key=%"PRIu64" / %08x%08x (score=%i)\n",
|
||||
*p_keycode, (uint32_t)((*p_keycode >> 32) & 0xFFFFFFFF), (uint32_t)(*p_keycode & 0xFFFFFFFF), hk->best_score);
|
||||
}
|
||||
}
|
||||
|
||||
const char* hbf_info[] = {
|
||||
"64LE",
|
||||
"64BE",
|
||||
"32LE",
|
||||
"32BE",
|
||||
};
|
||||
|
||||
typedef enum {
|
||||
HBF_TYPE_64LE_1,
|
||||
HBF_TYPE_64BE_1,
|
||||
HBF_TYPE_32LE_1,
|
||||
HBF_TYPE_32BE_1,
|
||||
HBF_TYPE_64LE_4,
|
||||
HBF_TYPE_64BE_4,
|
||||
HBF_TYPE_32LE_4,
|
||||
HBF_TYPE_32BE_4,
|
||||
} HBF_type_t;
|
||||
//HBF_TYPE_64LE_4,
|
||||
//HBF_TYPE_64BE_4,
|
||||
//HBF_TYPE_32LE_4,
|
||||
//HBF_TYPE_32BE_4,
|
||||
} hbf_type_t;
|
||||
|
||||
/* Bruteforce binary keys in executables and similar files, mainly for some mobile games.
|
||||
* Kinda slow but acceptable for ~100MB exes, not very optimized. Unity usually has keys
|
||||
* in plaintext (inside levelX or other base files) instead though, use test below. */
|
||||
static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data, unsigned long long* p_keycode, uint16_t subkey, HBF_type_t type) {
|
||||
static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data, unsigned long long* p_keycode, uint16_t subkey, hbf_type_t type) {
|
||||
STREAMFILE* sf_keys = NULL;
|
||||
uint8_t* buf = NULL;
|
||||
uint64_t keys_offset;
|
||||
|
@ -48,7 +56,8 @@ static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data
|
|||
sf_keys = open_streamfile_by_filename(sf, "keys.bin");
|
||||
if (!sf_keys) return;
|
||||
|
||||
VGM_LOG("HCA BF: test keys.bin (type %i)\n", type);
|
||||
const char* type_info = hbf_info[type];
|
||||
VGM_LOG("HCA BF: using keys.bin (%s mode)\n", type_info);
|
||||
|
||||
buf = malloc(HCA_BF_CHUNK);
|
||||
if (!buf) {
|
||||
|
@ -64,10 +73,10 @@ static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data
|
|||
case HBF_TYPE_64BE_1:
|
||||
case HBF_TYPE_32LE_1:
|
||||
case HBF_TYPE_32BE_1: step = 0x01; break;
|
||||
case HBF_TYPE_64LE_4:
|
||||
case HBF_TYPE_64BE_4:
|
||||
case HBF_TYPE_32LE_4:
|
||||
case HBF_TYPE_32BE_4: step = 0x04; break;
|
||||
//case HBF_TYPE_64LE_4:
|
||||
//case HBF_TYPE_64BE_4:
|
||||
//case HBF_TYPE_32LE_4:
|
||||
//case HBF_TYPE_32BE_4: step = 0x04; break;
|
||||
default: goto done;
|
||||
}
|
||||
|
||||
|
@ -83,7 +92,7 @@ static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data
|
|||
if (keys_limit >= 8)
|
||||
keys_offset += keys_limit - 8;
|
||||
|
||||
VGM_LOG("HCA: reading %llx + ...\n", (long long)keys_offset);
|
||||
VGM_LOG("HCA BF: reading %llx + ...\n", (long long)keys_offset);
|
||||
keys_limit = read_streamfile(buf, keys_offset, HCA_BF_CHUNK, sf_keys);
|
||||
if (keys_limit == 0)
|
||||
return;
|
||||
|
@ -92,7 +101,7 @@ static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data
|
|||
|
||||
if (pos % 0x1000000 == 0) {
|
||||
uint64_t pos_out = keys_offset + pos;
|
||||
VGM_LOG("HCA: pos %llx...\n", (long long)pos_out);
|
||||
VGM_LOG("HCA BF: pos %llx...\n", (long long)pos_out);
|
||||
}
|
||||
|
||||
#ifdef HCA_BF_IGNORE_BAD_KEYS
|
||||
|
@ -108,10 +117,10 @@ static void bruteforce_hca_key_bin_type(STREAMFILE* sf, hca_codec_data* hca_data
|
|||
case HBF_TYPE_64BE_1: key = get_u64be(buf + pos); break;
|
||||
case HBF_TYPE_32LE_1: key = get_u32le(buf + pos); break;
|
||||
case HBF_TYPE_32BE_1: key = get_u32be(buf + pos); break;
|
||||
case HBF_TYPE_64LE_4: key = get_u64le(buf + pos); break;
|
||||
case HBF_TYPE_64BE_4: key = get_u64be(buf + pos); break;
|
||||
case HBF_TYPE_32LE_4: key = get_u32le(buf + pos); break;
|
||||
case HBF_TYPE_32BE_4: key = get_u32be(buf + pos); break;
|
||||
//case HBF_TYPE_64LE_4: key = get_u64le(buf + pos); break;
|
||||
//case HBF_TYPE_64BE_4: key = get_u64be(buf + pos); break;
|
||||
//case HBF_TYPE_32LE_4: key = get_u32le(buf + pos); break;
|
||||
//case HBF_TYPE_32BE_4: key = get_u32be(buf + pos); break;
|
||||
default: goto done;
|
||||
}
|
||||
pos += step;
|
||||
|
@ -130,13 +139,15 @@ done:
|
|||
bruteforce_process_result(&hk, p_keycode);
|
||||
close_streamfile(sf_keys);
|
||||
free(buf);
|
||||
|
||||
VGM_LOG("HCA BF: done\n\n");
|
||||
}
|
||||
|
||||
static void bruteforce_hca_key_bin(STREAMFILE* sf, hca_codec_data* hca_data, unsigned long long* p_keycode, uint16_t subkey) {
|
||||
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_64LE_1);
|
||||
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_32LE_1);
|
||||
//bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_64BE_1);
|
||||
//bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_32BE_1);
|
||||
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_64BE_1);
|
||||
bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_32BE_1);
|
||||
|
||||
//bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_64LE_4);
|
||||
//bruteforce_hca_key_bin_type(sf, hca_data, p_keycode, subkey, HBF_TYPE_32LE_4);
|
||||
|
@ -145,9 +156,6 @@ static void bruteforce_hca_key_bin(STREAMFILE* sf, hca_codec_data* hca_data, uns
|
|||
}
|
||||
|
||||
|
||||
#include <inttypes.h>
|
||||
//#include <stdio.h>
|
||||
|
||||
/* same as the above but for txt lines. */
|
||||
static void bruteforce_hca_key_txt(STREAMFILE* sf, hca_codec_data* hca_data, unsigned long long* p_keycode, uint16_t subkey) {
|
||||
STREAMFILE* sf_keys = NULL;
|
||||
|
@ -165,7 +173,7 @@ static void bruteforce_hca_key_txt(STREAMFILE* sf, hca_codec_data* hca_data, uns
|
|||
sf_keys = open_streamfile_by_filename(sf, "keys.txt");
|
||||
if (!sf_keys) return;
|
||||
|
||||
VGM_LOG("HCA BF: test keys.txt\n");
|
||||
VGM_LOG("HCA BF: using keys.txt\n");
|
||||
|
||||
keys_size = get_streamfile_size(sf_keys);
|
||||
|
||||
|
@ -192,7 +200,7 @@ static void bruteforce_hca_key_txt(STREAMFILE* sf, hca_codec_data* hca_data, uns
|
|||
count = sscanf(line, "%" SCNd64, &key);
|
||||
if (count != 1) continue;
|
||||
|
||||
VGM_ASSERT(pos % 10000 == 0, "HCA: count %i...\n", i);
|
||||
VGM_ASSERT(pos % 10000 == 0, "HCA BF: count %i...\n", i);
|
||||
|
||||
if (key == 0)
|
||||
continue;
|
||||
|
@ -208,6 +216,8 @@ done:
|
|||
bruteforce_process_result(&hk, p_keycode);
|
||||
close_streamfile(sf_keys);
|
||||
free(buf);
|
||||
|
||||
VGM_LOG("HCA BF: done\n\n");
|
||||
}
|
||||
|
||||
/* same as the above but good ol' bruteforce numbers (useful for games with keys that are dates) */
|
||||
|
@ -225,7 +235,7 @@ static void bruteforce_hca_key_num(STREAMFILE* sf, hca_codec_data* hca_data, uns
|
|||
sf_keys = open_streamfile_by_filename(sf, "keys.num");
|
||||
if (!sf_keys) return;
|
||||
|
||||
VGM_LOG("HCA BF: test keys.num\n");
|
||||
VGM_LOG("HCA BF: using keys.num\n");
|
||||
|
||||
keys_size = get_streamfile_size(sf_keys);
|
||||
|
||||
|
@ -245,7 +255,7 @@ static void bruteforce_hca_key_num(STREAMFILE* sf, hca_codec_data* hca_data, uns
|
|||
key = min;
|
||||
|
||||
min++;
|
||||
VGM_ASSERT(min % 0x100000 == 0, "HCA: count %x...\n", (uint32_t)min);
|
||||
VGM_ASSERT(min % 0x100000 == 0, "HCA BF: count %x...\n", (uint32_t)min);
|
||||
|
||||
hk.key = key;
|
||||
test_hca_key(hca_data, &hk);
|
||||
|
@ -256,9 +266,13 @@ static void bruteforce_hca_key_num(STREAMFILE* sf, hca_codec_data* hca_data, uns
|
|||
done:
|
||||
bruteforce_process_result(&hk, p_keycode);
|
||||
close_streamfile(sf_keys);
|
||||
|
||||
VGM_LOG("HCA BF: done\n\n");
|
||||
}
|
||||
|
||||
static void bruteforce_hca_key(STREAMFILE* sf, hca_codec_data* hca_data, unsigned long long* p_keycode, uint16_t subkey) {
|
||||
VGM_LOG("HCA bruteforcer start\n");
|
||||
|
||||
bruteforce_hca_key_bin(sf, hca_data, p_keycode, subkey);
|
||||
if (*p_keycode != 0)
|
||||
return;
|
||||
|
@ -270,6 +284,8 @@ static void bruteforce_hca_key(STREAMFILE* sf, hca_codec_data* hca_data, unsigne
|
|||
bruteforce_hca_key_num(sf, hca_data, p_keycode, subkey);
|
||||
if (*p_keycode != 0)
|
||||
return;
|
||||
|
||||
VGM_LOG("HCA bruteforcer done\n");
|
||||
}
|
||||
|
||||
#endif
|
||||
|
|
|
@ -568,6 +568,7 @@ static const hcakey_info hcakey_list[] = {
|
|||
{0xb58259c9d1f9ebc1}, // music_0310025
|
||||
{0xbd9e17f5262e3f09}, // music_0310026
|
||||
{0xba8c9e65cf055de}, // music_0310027
|
||||
{0xf8cad906044f1b35}, // music_0310028
|
||||
{0xb921c3992807dadd}, // music_0320001
|
||||
{0x38ad99a045dc971f}, // music_0320002
|
||||
{0xf616642579ba5850}, // music_0320003
|
||||
|
@ -733,6 +734,7 @@ static const hcakey_info hcakey_list[] = {
|
|||
{0x1ad8db767d9ba4a7}, // music_0620018
|
||||
{0x9bc820aa161b0f08}, // music_0620019
|
||||
{0x7d1d8c5dd43cabfc}, // music_0620020
|
||||
{0x5a216f2660d870c0}, // music_0620021
|
||||
{0x6cccc0684c8b2664}, // music_0640001
|
||||
{0x85f26fa7befc2b5a}, // music_0810000
|
||||
{0xd1df27a57399613e}, // music_0810001
|
||||
|
@ -761,6 +763,7 @@ static const hcakey_info hcakey_list[] = {
|
|||
{0x6cb33fe1e8506d0f}, // music_0910008
|
||||
{0xfaf9830ee551c6c4}, // music_0910009
|
||||
{0xf7c51ef55106e4a0}, // music_0910010
|
||||
{0xcd35d39900ebaedc}, // music_0910011
|
||||
{0x4683c57919dbdeee}, // music_0920001
|
||||
{0x126d0d20ad7f0401}, // music_0920002
|
||||
{0x1652eb8bf3cea8f5}, // music_0920003
|
||||
|
@ -1274,6 +1277,7 @@ static const hcakey_info hcakey_list[] = {
|
|||
{0x591899d025c3beb7}, // music_5050323
|
||||
{0xa57678c62ef99124}, // music_5050324
|
||||
{0x925f360a8ccb4c32}, // music_5050325
|
||||
{0x2a9281f77161e068}, // music_5050326
|
||||
{0x52c250eade92393b}, // music_9010001
|
||||
{0xf66e6bb5b0599b07}, // music_9010002
|
||||
{0x8582b5a60dbbf948}, // music_9010003
|
||||
|
|
|
@ -1,55 +1,56 @@
|
|||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* .IAB - from Runtime(?) games [Ueki no Housoku - Taosu ze Robert Juudan!! (PS2), RPG Maker 3 (PS2)] */
|
||||
VGMSTREAM * init_vgmstream_ps2_iab(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile,"iab"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x00,streamFile) != 0x10000000)
|
||||
goto fail;
|
||||
if (read_32bitLE(0x1C,streamFile) != get_streamfile_size(streamFile))
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = 2;
|
||||
start_offset = 0x40;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = read_32bitLE(0x04,streamFile);
|
||||
vgmstream->meta_type = meta_PS2_IAB;
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->layout_type = layout_blocked_ps2_iab;
|
||||
//vgmstream->interleave_block_size = read_32bitLE(0x0C, streamFile); /* unneeded */
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||
goto fail;
|
||||
|
||||
/* calc num_samples */
|
||||
{
|
||||
vgmstream->next_block_offset = start_offset;
|
||||
do {
|
||||
block_update(vgmstream->next_block_offset, vgmstream);
|
||||
vgmstream->num_samples += ps_bytes_to_samples(vgmstream->current_block_size, 1);
|
||||
}
|
||||
while (vgmstream->next_block_offset < get_streamfile_size(streamFile));
|
||||
block_update(start_offset, vgmstream);
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util.h"
|
||||
|
||||
|
||||
/* .IAB - from Runtime(?) games [Ueki no Housoku: Taosu ze Robert Juudan!! (PS2), RPG Maker 3 (PS2)] */
|
||||
VGMSTREAM* init_vgmstream_iab(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channels;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (read_u32be(0x00,sf) != 0x10000000)
|
||||
return NULL;
|
||||
if (!check_extensions(sf,"iab"))
|
||||
return NULL;
|
||||
if (read_u32le(0x1c,sf) != get_streamfile_size(sf))
|
||||
return NULL;
|
||||
|
||||
loop_flag = 0;
|
||||
channels = 2;
|
||||
start_offset = 0x40;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_IAB;
|
||||
vgmstream->sample_rate = read_s32le(0x04,sf);
|
||||
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->layout_type = layout_blocked_ps2_iab;
|
||||
//vgmstream->interleave_block_size = read_32bitLE(0x0C, streamFile); /* unneeded */
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream,sf,start_offset))
|
||||
goto fail;
|
||||
|
||||
/* calc num_samples */
|
||||
{
|
||||
vgmstream->next_block_offset = start_offset;
|
||||
do {
|
||||
block_update(vgmstream->next_block_offset, vgmstream);
|
||||
vgmstream->num_samples += ps_bytes_to_samples(vgmstream->current_block_size, 1);
|
||||
}
|
||||
while (vgmstream->next_block_offset < get_streamfile_size(sf));
|
||||
block_update(start_offset, vgmstream);
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -5,6 +5,8 @@ typedef struct {
|
|||
int loop_flag;
|
||||
int32_t loop_start;
|
||||
int32_t loop_end;
|
||||
uint16_t loop_start_adjust;
|
||||
uint16_t loop_end_padding;
|
||||
uint32_t file_size;
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
mp4_custom_t mp4;
|
||||
|
@ -23,50 +25,68 @@ VGMSTREAM* init_vgmstream_ktac(STREAMFILE* sf) {
|
|||
if (!is_id32be(0x00,sf, "KTAC"))
|
||||
return NULL;
|
||||
|
||||
/* .ktac: header id (probable extension from debug strings is "kac" */
|
||||
// .ktac: header id (probable extension from debug strings is "kac"
|
||||
if (!check_extensions(sf,"ktac"))
|
||||
return NULL;
|
||||
|
||||
/* 0x04: version? (always 1) */
|
||||
// 0x04: version? (0x01000000=common, 0x01010000=WP9 2022)
|
||||
ktac.file_size = read_u32le(0x08,sf);
|
||||
if (ktac.file_size != get_streamfile_size(sf))
|
||||
return NULL;
|
||||
ktac.mp4.stream_offset = read_u32le(0x0c,sf);
|
||||
ktac.mp4.stream_size = read_u32le(0x10,sf);
|
||||
ktac.type = read_u32le(0x14,sf);
|
||||
ktac.type = read_u32le(0x14,sf); // 0=AoT, KnC3 bgm, type 1=KnC3 1ch voices, type 2=DW4, Atelier Ryza, others
|
||||
ktac.mp4.sample_rate = read_u32le(0x18,sf);
|
||||
ktac.mp4.num_samples = read_u32le(0x1c,sf); /* full samples */
|
||||
ktac.mp4.num_samples = read_u32le(0x1c,sf); // full samples (total_frames * frame_size)
|
||||
ktac.mp4.channels = read_u16le(0x20,sf);
|
||||
ktac.mp4.frame_samples = read_u16le(0x22,sf);
|
||||
ktac.mp4.encoder_delay = read_u16le(0x24,sf);
|
||||
ktac.mp4.end_padding = read_u16le(0x26,sf);
|
||||
ktac.loop_start = read_u32le(0x28,sf);
|
||||
ktac.loop_end = read_u32le(0x2c,sf);
|
||||
/* 0x30: ? (big, related to loops) */
|
||||
/* 0x34: ? (always null) */
|
||||
ktac.loop_start_adjust = read_u16le(0x30,sf);
|
||||
ktac.loop_end_padding = read_u16le(0x32,sf); // usually same as end_padding
|
||||
// 0x34: reserved? (always null)
|
||||
ktac.mp4.table_offset = read_u32le(0x38,sf);
|
||||
ktac.mp4.table_entries = read_u32le(0x3c,sf);
|
||||
ktac.mp4.table_entries = read_u32le(0x3c,sf); // total_frames
|
||||
|
||||
ktac.loop_flag = (ktac.loop_end > 0);
|
||||
|
||||
/* type 1 files crash during sample_copy, wrong fake header/esds?
|
||||
* (0=AoT, KnC3 bgm, 1=KnC3 1ch voices, 2=DW4, Atelier Ryza) */
|
||||
if (ktac.type == 1)
|
||||
goto fail;
|
||||
// loop handling, correct vs full loops too [Winning Post 9 2022 (PC)]
|
||||
// - loop_start == 1 = 2048 + adjust 64 == 2112 == encoder delay
|
||||
// - (loop_end + 1) == total_frames, loop_end_adjust = 96 = end_padding
|
||||
ktac.loop_start = ktac.loop_start * ktac.mp4.frame_samples + ktac.loop_start_adjust;
|
||||
ktac.loop_end = (ktac.loop_end + 1) * ktac.mp4.frame_samples - ktac.loop_end_padding;
|
||||
|
||||
int channels = ktac.mp4.channels;
|
||||
int sample_rate = ktac.mp4.sample_rate;
|
||||
int num_samples = ktac.mp4.num_samples;
|
||||
|
||||
// type 1 has some odd behavior. FFmpeg returns 2 channels with dupe samples (must decode x2),
|
||||
// Possibly fake mp4's add_esds config is off, but internal sample_rate/etc seems correct (matters for decoding).
|
||||
// It's not impossible it's just some KT decoder trickery, so for now force double values.
|
||||
if (ktac.type == 1) {
|
||||
vgm_logi("KTAC: type %i found\n", ktac.type);
|
||||
if (channels != 1)
|
||||
goto fail;
|
||||
channels *= 2; //could use 1 channel + let copy-samples ignore extra channel?
|
||||
sample_rate *= 2;
|
||||
num_samples *= 2;
|
||||
}
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(ktac.mp4.channels, ktac.loop_flag);
|
||||
vgmstream = allocate_vgmstream(channels, ktac.loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_KTAC;
|
||||
vgmstream->sample_rate = ktac.mp4.sample_rate;
|
||||
vgmstream->num_samples = ktac.mp4.num_samples - ktac.mp4.encoder_delay - ktac.mp4.end_padding;
|
||||
vgmstream->loop_start_sample = ktac.loop_start * ktac.mp4.frame_samples - ktac.mp4.encoder_delay;
|
||||
vgmstream->loop_end_sample = ktac.loop_end * ktac.mp4.frame_samples - ktac.mp4.encoder_delay;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = num_samples - ktac.mp4.end_padding - ktac.mp4.encoder_delay;
|
||||
vgmstream->loop_start_sample = ktac.loop_start - ktac.mp4.encoder_delay;
|
||||
vgmstream->loop_end_sample = ktac.loop_end - ktac.mp4.encoder_delay;
|
||||
|
||||
/* KTAC uses AAC, but not type found in .aac (that has headered frames, like mp3) but raw
|
||||
* packets + frame size table (similar to .mp4/m4a). We set config for FFmpeg's fake M4A header */
|
||||
vgmstream->codec_data = init_ffmpeg_mp4_custom_std(sf, &ktac.mp4);
|
||||
// KTAC uses AAC, but not type found in .aac (that has headered frames, like mp3) but raw
|
||||
// packets + frame size table (similar to .mp4/m4a). We set config for FFmpeg's fake M4A header
|
||||
vgmstream->codec_data = init_ffmpeg_mp4_custom_ktac(sf, &ktac.mp4);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
|
49
Frameworks/vgmstream/vgmstream/src/meta/lps.c
Normal file
49
Frameworks/vgmstream/vgmstream/src/meta/lps.c
Normal file
|
@ -0,0 +1,49 @@
|
|||
#include "meta.h"
|
||||
#include "../util/meta_utils.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* .LPS - from Rave Master (GC) */
|
||||
VGMSTREAM* init_vgmstream_lps(STREAMFILE* sf) {
|
||||
|
||||
/* checks */
|
||||
uint32_t data_size = read_u32be(0x00, sf);
|
||||
if (data_size + 0xE0 != get_streamfile_size(sf))
|
||||
return NULL;
|
||||
|
||||
if (read_u32be(0x04, sf) != 0x01)
|
||||
return NULL;
|
||||
if (read_u32be(0x08, sf) != 0x10000000)
|
||||
return NULL;
|
||||
if (read_u32be(0x0c, sf) != 0x00)
|
||||
return NULL;
|
||||
if (!check_extensions(sf, "lps"))
|
||||
return NULL;
|
||||
|
||||
meta_header_t h = {0};
|
||||
h.meta = meta_LPS;
|
||||
|
||||
//TODO: standard(?) DSP header, maybe handle like others
|
||||
h.num_samples = read_s32be(0x20 + 0x00,sf);
|
||||
// 04: nibbles
|
||||
h.sample_rate = read_s32be(0x20 + 0x08,sf);
|
||||
h.loop_flag = read_s16be(0x20 + 0x0c,sf) == 0x0001;
|
||||
h.loop_start = read_u32be(0x20 + 0x10,sf);
|
||||
h.loop_end = read_s32be(0x20 + 0x14,sf);
|
||||
h.coefs_offset = 0x20 + 0x1c;
|
||||
h.hists_offset = 0x20 + 0x1c + 0x20 + 0x04;
|
||||
|
||||
h.loop_start = dsp_nibbles_to_samples(h.loop_start);
|
||||
h.loop_end = dsp_nibbles_to_samples(h.loop_end); //+ 1;
|
||||
|
||||
h.channels = 1;
|
||||
h.allow_dual_stereo = true;
|
||||
h.big_endian = true;
|
||||
h.stream_offset = 0xE0;
|
||||
|
||||
h.coding = coding_NGC_DSP;
|
||||
h.layout = layout_none;
|
||||
h.open_stream = true;
|
||||
h.sf = sf;
|
||||
|
||||
return alloc_metastream(&h);
|
||||
}
|
70
Frameworks/vgmstream/vgmstream/src/meta/madp.c
Normal file
70
Frameworks/vgmstream/vgmstream/src/meta/madp.c
Normal file
|
@ -0,0 +1,70 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util/meta_utils.h"
|
||||
|
||||
/* MADP - from Capcom 3DS games */
|
||||
VGMSTREAM* init_vgmstream_madp(STREAMFILE* sf) {
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "MADP"))
|
||||
return NULL;
|
||||
if (!check_extensions(sf, "mca"))
|
||||
return NULL;
|
||||
|
||||
meta_header_t h = {0};
|
||||
h.meta = meta_MADP;
|
||||
|
||||
int version = read_u16le(0x04, sf);
|
||||
h.channels = read_u16le(0x08, sf);
|
||||
h.interleave = read_u16le(0x0a, sf); // assumed, only seen 0x100
|
||||
h.num_samples = read_s32le(0x0c, sf);
|
||||
h.sample_rate = read_s32le(0x10, sf);
|
||||
h.loop_start = read_s32le(0x14, sf);
|
||||
h.loop_end = read_s32le(0x18, sf);
|
||||
h.head_size = read_u32le(0x1c, sf); // v3=loop related?, v5=partial size?
|
||||
h.stream_size = read_u32le(0x20, sf);
|
||||
// 24: duration (f32)
|
||||
// rest: varies between versions
|
||||
|
||||
int cues = 0;
|
||||
if (version >= 0x04) {
|
||||
cues = read_u16le(0x28, sf); //seems to be some kind of seek table with start ps + hist per channel
|
||||
// 0x2a: id-ish value? (same for all files in a game)
|
||||
}
|
||||
|
||||
// format is kind of inconsistent between games but the following seems to work
|
||||
if (version == 3)
|
||||
h.head_size = get_streamfile_size(sf) - h.stream_size; // probably 0x2c + 0x30*ch
|
||||
h.coefs_spacing = 0x30;
|
||||
uint32_t coefs_start = (h.head_size - h.coefs_spacing * h.channels);
|
||||
h.coefs_offset = coefs_start + cues * 0x14;
|
||||
// hist + start/loop ps seem to follow after coefs
|
||||
|
||||
switch(version) {
|
||||
case 0x03: // Resident Evil Mercenaries 3D, Super Street Fighter IV 3D
|
||||
h.stream_offset = h.head_size;
|
||||
break;
|
||||
|
||||
case 0x04: // EX Troopers, Ace Attourney 5
|
||||
h.stream_offset = get_streamfile_size(sf) - h.stream_size; // usually head_size but not for some MH3U songs
|
||||
break;
|
||||
|
||||
case 0x05: // Ace Attourney 6, Monster Hunter Generations
|
||||
h.stream_offset = read_u32le(coefs_start - 0x04, sf);
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
h.loop_flag = h.loop_end > 0;
|
||||
if (h.loop_end > h.num_samples) // some MH3U songs, somehow
|
||||
h.loop_end = h.num_samples;
|
||||
|
||||
h.coding = coding_NGC_DSP;
|
||||
h.layout = layout_interleave;
|
||||
h.open_stream = true;
|
||||
h.sf = sf;
|
||||
|
||||
return alloc_metastream(&h);
|
||||
}
|
|
@ -1,95 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* Capcom MADP - found in Capcom 3DS games */
|
||||
VGMSTREAM * init_vgmstream_mca(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
int channel_count, loop_flag, version;
|
||||
size_t head_size, data_size, file_size;
|
||||
off_t start_offset, coef_offset, coef_start, coef_shift;
|
||||
int coef_spacing;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
if (!check_extensions(streamFile,"mca"))
|
||||
goto fail;
|
||||
|
||||
/* check header */
|
||||
if ((uint32_t)read_32bitBE(0, streamFile) != 0x4D414450) /* "MADP" */
|
||||
goto fail;
|
||||
|
||||
channel_count = read_8bit(0x8, streamFile);
|
||||
if (channel_count < 1) goto fail;
|
||||
loop_flag = read_32bitLE(0x18, streamFile) > 0;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->interleave_block_size = read_16bitLE(0xa, streamFile); /* guessed, only seen 0x100 */
|
||||
vgmstream->num_samples = read_32bitLE(0xc, streamFile);
|
||||
vgmstream->sample_rate = (uint16_t)read_16bitLE(0x10, streamFile);
|
||||
vgmstream->loop_start_sample = read_32bitLE(0x14, streamFile);
|
||||
vgmstream->loop_end_sample = read_32bitLE(0x18, streamFile);
|
||||
|
||||
if (vgmstream->loop_end_sample > vgmstream->num_samples) /* some MH3U songs, somehow */
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->layout_type = channel_count == 1 ? layout_none : layout_interleave;
|
||||
vgmstream->meta_type = meta_MCA;
|
||||
|
||||
|
||||
/* find data/coef offsets (guessed, formula may change with version) */
|
||||
version = read_16bitLE(0x04, streamFile);
|
||||
coef_spacing = 0x30;
|
||||
data_size = read_32bitLE(0x20, streamFile);
|
||||
|
||||
if (version <= 0x3) { /* v3: Resident Evil Mercenaries 3D, Super Street Fighter IV 3D */
|
||||
head_size = get_streamfile_size(streamFile) - data_size; /* probably 0x2c + 0x30*ch */
|
||||
coef_shift = 0x0;
|
||||
coef_start = head_size - coef_spacing * channel_count;
|
||||
|
||||
start_offset = head_size;
|
||||
coef_offset = coef_start + coef_shift * 0x14;
|
||||
|
||||
} else if (version == 0x4) { /* v4: EX Troopers, Ace Attourney 5 */
|
||||
head_size = read_16bitLE(0x1c, streamFile);
|
||||
coef_shift = read_16bitLE(0x28, streamFile);
|
||||
coef_start = head_size - coef_spacing * channel_count;
|
||||
|
||||
start_offset = get_streamfile_size(streamFile) - data_size; /* usually head_size but not for some MH3U songs */
|
||||
coef_offset = coef_start + coef_shift * 0x14;
|
||||
|
||||
} else { /* v5: Ace Attourney 6, Monster Hunter Generations, v6+? */
|
||||
head_size = read_16bitLE(0x1c, streamFile); /* partial size */
|
||||
coef_shift = read_16bitLE(0x28, streamFile);
|
||||
coef_start = head_size - coef_spacing * channel_count;
|
||||
|
||||
start_offset = read_32bitLE(coef_start - 0x4, streamFile);
|
||||
coef_offset = coef_start + coef_shift * 0x14;
|
||||
}
|
||||
|
||||
/* sanity check (for bad rips with the header manually truncated to in attempt to "fix" v5 headers) */
|
||||
file_size = get_streamfile_size(streamFile);
|
||||
|
||||
if (start_offset + data_size > file_size) {
|
||||
if (head_size + data_size > file_size)
|
||||
goto fail;
|
||||
|
||||
start_offset = file_size - data_size;
|
||||
}
|
||||
|
||||
/* set up ADPCM coefs */
|
||||
dsp_read_coefs_le(vgmstream, streamFile, coef_offset, coef_spacing);
|
||||
|
||||
/* open the file for reading */
|
||||
if ( !vgmstream_open_stream(vgmstream,streamFile, start_offset) )
|
||||
goto fail;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
65
Frameworks/vgmstream/vgmstream/src/meta/mcss.c
Normal file
65
Frameworks/vgmstream/vgmstream/src/meta/mcss.c
Normal file
|
@ -0,0 +1,65 @@
|
|||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* Guerrilla's MSS - Found in ShellShock Nam '67 (PS2/Xbox), Killzone (PS2) */
|
||||
VGMSTREAM* init_vgmstream_mcss(STREAMFILE *sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
off_t start_offset, data_size;
|
||||
int loop_flag = 0, channels;
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "MCSS"))
|
||||
return NULL;
|
||||
if (!check_extensions(sf, "mss"))
|
||||
return NULL;
|
||||
|
||||
loop_flag = 0;
|
||||
|
||||
// 04: version? (always 0x00000100 LE)
|
||||
start_offset = read_u32le(0x08,sf);
|
||||
data_size = read_u32le(0x0c,sf);
|
||||
int sample_rate = read_s32le(0x10,sf);
|
||||
// 14(1): 1/2/3/4 if 2/4/6/8ch
|
||||
// 15(1): 0/1?
|
||||
channels = read_u16le(0x16,sf);
|
||||
int interleave = read_u32le(0x18,sf);
|
||||
uint32_t chan_size = read_u32le(0x1C,sf); //without padding
|
||||
// 20: "Guerrilla MSS"
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_MCSS;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = interleave;
|
||||
|
||||
// no other way to know
|
||||
if (vgmstream->interleave_block_size == 0x4800) {
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
|
||||
/* in stereo multichannel this value is distance between 2ch pair, but we need
|
||||
* interleave*ch = full block (2ch 0x4800 + 2ch 0x4800 = 4ch, 0x4800+4800 / 4 = 0x2400) */
|
||||
vgmstream->interleave_block_size = vgmstream->interleave_block_size / 2;
|
||||
if (vgmstream->channels > 2 && vgmstream->channels % 2 != 0)
|
||||
goto fail; // only 2ch+..+2ch layout is known
|
||||
|
||||
/* header values are somehow off? */
|
||||
data_size = get_streamfile_size(sf) - start_offset;
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
|
||||
}
|
||||
else {
|
||||
// 0x800 interleave
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->num_samples = ps_bytes_to_samples(chan_size, 1);
|
||||
}
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream,sf,start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -275,8 +275,6 @@ VGMSTREAM * init_vgmstream_sat_sap(STREAMFILE *streamFile);
|
|||
|
||||
VGMSTREAM * init_vgmstream_dc_idvi(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_rnd(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_kraw(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM* init_vgmstream_omu(STREAMFILE* sf);
|
||||
|
@ -334,7 +332,8 @@ VGMSTREAM* init_vgmstream_ssm(STREAMFILE* sf);
|
|||
|
||||
VGMSTREAM * init_vgmstream_ps2_joe(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_vgs(STREAMFILE * streamFile);
|
||||
VGMSTREAM* init_vgmstream_vgs(STREAMFILE* sf);
|
||||
VGMSTREAM* init_vgmstream_vgs_old(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_dcs_wav(STREAMFILE * streamFile);
|
||||
|
||||
|
@ -348,11 +347,11 @@ VGMSTREAM* init_vgmstream_p2bt_move_visa(STREAMFILE* sf);
|
|||
|
||||
VGMSTREAM* init_vgmstream_gbts(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_wii_sng(STREAMFILE *streamFile);
|
||||
VGMSTREAM* init_vgmstream_song_monster(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_aax(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_ffcc_str(STREAMFILE *streamFile);
|
||||
VGMSTREAM* init_vgmstream_str_sqex(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_sat_baka(STREAMFILE *streamFile);
|
||||
|
||||
|
@ -378,7 +377,7 @@ VGMSTREAM * init_vgmstream_ps2_sps(STREAMFILE *streamFile);
|
|||
|
||||
VGMSTREAM * init_vgmstream_nds_hwas(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_lps(STREAMFILE * streamFile);
|
||||
VGMSTREAM* init_vgmstream_lps(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_snd(STREAMFILE * streamFile);
|
||||
|
||||
|
@ -390,7 +389,7 @@ VGMSTREAM * init_vgmstream_2dx9(STREAMFILE * streamFile);
|
|||
|
||||
VGMSTREAM* init_vgmstream_dsp_kceje(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_vgv(STREAMFILE * streamFile);
|
||||
VGMSTREAM* init_vgmstream_vgv(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_gcub(STREAMFILE * streamFile);
|
||||
|
||||
|
@ -463,7 +462,7 @@ VGMSTREAM* init_vgmstream_cps(STREAMFILE* sf);
|
|||
|
||||
VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_nst_dsp(STREAMFILE* streamFile);
|
||||
VGMSTREAM* init_vgmstream_nst_monster(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_baf(STREAMFILE* streamFile);
|
||||
|
||||
|
@ -477,7 +476,7 @@ VGMSTREAM* init_vgmstream_ras(STREAMFILE* sf);
|
|||
|
||||
VGMSTREAM * init_vgmstream_spm(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_iab(STREAMFILE* streamFile);
|
||||
VGMSTREAM* init_vgmstream_iab(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_vs_str(STREAMFILE* streamFile);
|
||||
|
||||
|
@ -496,8 +495,8 @@ VGMSTREAM* init_vgmstream_adp_wildfire(STREAMFILE* sf);
|
|||
|
||||
VGMSTREAM* init_vgmstream_adp_qd(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_eb_sfx(STREAMFILE* streamFile);
|
||||
VGMSTREAM * init_vgmstream_eb_sf0(STREAMFILE* streamFile);
|
||||
VGMSTREAM* init_vgmstream_sfx0_monster(STREAMFILE* sf);
|
||||
VGMSTREAM* init_vgmstream_sfx0_monster_old(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_mtaf(STREAMFILE* streamFile);
|
||||
|
||||
|
@ -507,7 +506,7 @@ VGMSTREAM * init_vgmstream_wpd(STREAMFILE* streamFile);
|
|||
|
||||
VGMSTREAM * init_vgmstream_mn_str(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_mss(STREAMFILE* streamFile);
|
||||
VGMSTREAM* init_vgmstream_mcss(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_hsf(STREAMFILE* streamFile);
|
||||
|
||||
|
@ -534,7 +533,7 @@ VGMSTREAM * init_vgmstream_kt_g1l(STREAMFILE* streamFile);
|
|||
VGMSTREAM * init_vgmstream_kt_wiibgm(STREAMFILE* streamFile);
|
||||
VGMSTREAM * init_vgmstream_ktss(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_mca(STREAMFILE* streamFile);
|
||||
VGMSTREAM* init_vgmstream_madp(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_btsnd(STREAMFILE* streamFile);
|
||||
|
||||
|
@ -620,7 +619,7 @@ VGMSTREAM* init_vgmstream_opus_nsopus(STREAMFILE* sf);
|
|||
VGMSTREAM* init_vgmstream_opus_sqex(STREAMFILE* sf);
|
||||
VGMSTREAM* init_vgmstream_opus_rsnd(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_pc_ast(STREAMFILE * streamFile);
|
||||
VGMSTREAM* init_vgmstream_astl(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_naac(STREAMFILE * streamFile);
|
||||
|
||||
|
@ -759,7 +758,7 @@ VGMSTREAM * init_vgmstream_apc(STREAMFILE *streamFile);
|
|||
|
||||
VGMSTREAM* init_vgmstream_wav2(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_xau_konami(STREAMFILE *streamFile);
|
||||
VGMSTREAM* init_vgmstream_sfxb(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_derf(STREAMFILE *streamFile);
|
||||
|
||||
|
@ -998,7 +997,7 @@ VGMSTREAM* init_vgmstream_nxof(STREAMFILE* sf);
|
|||
|
||||
VGMSTREAM* init_vgmstream_gwb_gwd(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_cbx(STREAMFILE* sf);
|
||||
VGMSTREAM* init_vgmstream_chatterbox(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_vas_rockstar(STREAMFILE* sf);
|
||||
|
||||
|
@ -1034,4 +1033,6 @@ VGMSTREAM* init_vgmstream_mio(STREAMFILE* sf);
|
|||
|
||||
VGMSTREAM* init_vgmstream_2dx(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_ssp(STREAMFILE* sf);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,68 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* Guerrilla's MSS - Found in ShellShock Nam '67 (PS2/Xbox), Killzone (PS2) */
|
||||
VGMSTREAM * init_vgmstream_mss(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
size_t data_size;
|
||||
int loop_flag = 0, channel_count;
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile, "mss"))
|
||||
goto fail;
|
||||
if (read_32bitBE(0x00,streamFile) != 0x4D435353) /* "MCSS" */
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = read_16bitLE(0x16,streamFile);
|
||||
|
||||
/* 0x04: version? (always 0x00000100 LE) */
|
||||
start_offset = read_32bitLE(0x08,streamFile);
|
||||
data_size = read_32bitLE(0x0c,streamFile);
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
||||
/* 0x14(1): 1/2/3/4 if 2/4/6/8ch, 0x15(1): 0/1?, 0x16: ch */
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = read_32bitLE(0x18,streamFile);
|
||||
vgmstream->num_samples = read_32bitLE(0x1C,streamFile);
|
||||
vgmstream->meta_type = meta_MSS;
|
||||
|
||||
/* no other way to know */
|
||||
if (vgmstream->interleave_block_size == 0x4800) {
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
|
||||
/* in stereo multichannel this value is distance between 2ch pair, but we need
|
||||
* interleave*ch = full block (2ch 0x4800 + 2ch 0x4800 = 4ch, 0x4800+4800 / 4 = 0x2400) */
|
||||
vgmstream->interleave_block_size = vgmstream->interleave_block_size / 2;
|
||||
if (vgmstream->channels > 2 && vgmstream->channels % 2 != 0)
|
||||
goto fail; /* only 2ch+..+2ch layout is known */
|
||||
|
||||
/* header values are somehow off? */
|
||||
data_size = get_streamfile_size(streamFile) - start_offset;
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(data_size, vgmstream->channels);
|
||||
}
|
||||
else {
|
||||
/* 0x800 interleave */
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
|
||||
if (vgmstream->num_samples * vgmstream->channels <= data_size)
|
||||
vgmstream->num_samples = vgmstream->num_samples / 16 * 28;
|
||||
}
|
||||
|
||||
/* open the file for reading */
|
||||
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||
goto fail;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -1,85 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* STR (Final Fantasy: Crystal Chronicles) */
|
||||
VGMSTREAM * init_vgmstream_ngc_ffcc_str(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("str",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x00,streamFile) != 0x53545200 || /* "STR\0" */
|
||||
read_32bitBE(0x08,streamFile) != get_streamfile_size(streamFile) ||
|
||||
read_32bitBE(0x10,streamFile) != -1) /* this might be loop point */
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = read_32bitBE(0x18,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x1000;
|
||||
vgmstream->channels = channel_count;
|
||||
if (read_32bitBE(0x14,streamFile)==0)
|
||||
vgmstream->sample_rate = 32000;
|
||||
else
|
||||
vgmstream->sample_rate = 44100;
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = read_32bitBE(0x0C,streamFile)*14;
|
||||
|
||||
if (channel_count > 1)
|
||||
{
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x1000;
|
||||
}
|
||||
else
|
||||
{
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->interleave_block_size = 0x1000;
|
||||
}
|
||||
vgmstream->meta_type = meta_FFCC_STR;
|
||||
|
||||
|
||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||
int c;
|
||||
for (c=0;c<channel_count;c++)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[c].adpcm_coef[i] = read_16bitBE(0x20 + c * 0x2e + i * 2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
|
@ -1,70 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* LPS (found in Rave Master (Groove Adventure Rave)(GC) */
|
||||
VGMSTREAM * init_vgmstream_ngc_lps(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("lps",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x8,streamFile) != 0x10000000)
|
||||
goto fail;
|
||||
|
||||
loop_flag = read_32bitBE(0x30,streamFile);
|
||||
channel_count = 1;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x60;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitBE(0x28,streamFile);
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = (read_32bitBE(0x34,streamFile))/16*14;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = (read_32bitBE(0x30,streamFile))/16*14;
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_NGC_LPS;
|
||||
vgmstream->allow_dual_stereo = 1;
|
||||
|
||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||
int i;
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x3C+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
/* 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;
|
||||
}
|
|
@ -1,89 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* DSP (Animaniacs: The Great Edgar Hunt) */
|
||||
// NOTE: The second dsp header is just a dummy, both channels
|
||||
// use the same coef table (0x20)
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_nst_dsp(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("dsp",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x0,streamFile) != read_32bitBE(0x54,streamFile))
|
||||
goto fail;
|
||||
if (read_32bitBE(0x4,streamFile) != read_32bitBE(0x58,streamFile))
|
||||
goto fail;
|
||||
if (read_32bitBE(0x8,streamFile) != read_32bitBE(0x5C,streamFile))
|
||||
goto fail;
|
||||
if (read_32bitBE(0xC,streamFile) != read_32bitBE(0x60,streamFile))
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = 2;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0xAC;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitBE(0x14,streamFile);
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = read_32bitBE(0x8,streamFile);
|
||||
|
||||
#if 0
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x10;
|
||||
vgmstream->meta_type = meta_NGC_NST_DSP;
|
||||
|
||||
|
||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||
int i;
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x20+i*2,streamFile);
|
||||
}
|
||||
if (vgmstream->channels) {
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x20+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
48
Frameworks/vgmstream/vgmstream/src/meta/nst_monster.c
Normal file
48
Frameworks/vgmstream/vgmstream/src/meta/nst_monster.c
Normal file
|
@ -0,0 +1,48 @@
|
|||
#include "meta.h"
|
||||
#include "../util/meta_utils.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* .NST - from Animaniacs: The Great Edgar Hunt (GC) */
|
||||
VGMSTREAM* init_vgmstream_nst_monster(STREAMFILE* sf) {
|
||||
|
||||
/* checks */
|
||||
if (read_u32be(0x00,sf) != 1)
|
||||
return NULL;
|
||||
// .nst: original
|
||||
// .dsp: renamed for plugins (to be removed?)
|
||||
if (!check_extensions(sf, "nst,dsp"))
|
||||
return NULL;
|
||||
|
||||
// DSP header but second is just a dummy, both channels use the same coef table (0x20)
|
||||
if (read_u32be(0x00,sf) != read_u32be(0x54,sf))
|
||||
return NULL;
|
||||
if (read_u32be(0x04,sf) != read_u32be(0x58,sf))
|
||||
return NULL;
|
||||
if (read_u32be(0x08,sf) != read_u32be(0x5C,sf))
|
||||
return NULL;
|
||||
if (read_u32be(0x0C,sf) != read_u32be(0x60,sf))
|
||||
return NULL;
|
||||
|
||||
meta_header_t h = {0};
|
||||
h.meta = meta_NST_MONSTER;
|
||||
|
||||
h.num_samples = read_s32be(0x08, sf);
|
||||
h.sample_rate = read_s32be(0x14, sf);
|
||||
|
||||
h.channels = 2;
|
||||
h.interleave = 0x10;
|
||||
h.coefs_offset = 0x20;
|
||||
h.coefs_spacing = 0x00;
|
||||
h.big_endian = true;
|
||||
//h.hists_offset = 0x00; //?
|
||||
//h.hists_spacing = h.coefs_spacing;
|
||||
|
||||
h.stream_offset = 0xAC;
|
||||
|
||||
h.coding = coding_NGC_DSP;
|
||||
h.layout = layout_interleave;
|
||||
h.open_stream = true;
|
||||
h.sf = sf;
|
||||
|
||||
return alloc_metastream(&h);
|
||||
}
|
|
@ -8,7 +8,6 @@ static bool is_oor(STREAMFILE* sf);
|
|||
/* .OOR ("OptimizedObsforR") - rUGP/AGES engine audio [Muv-Luv (multi), Liberation Maiden SIN (PS3/Vita)] */
|
||||
VGMSTREAM* init_vgmstream_oor(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
vorbis_custom_codec_data* data = NULL;
|
||||
off_t start_offset;
|
||||
|
||||
|
||||
|
@ -23,6 +22,7 @@ VGMSTREAM* init_vgmstream_oor(STREAMFILE* sf) {
|
|||
return NULL;
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
vorbis_custom_codec_data* data = NULL;
|
||||
vorbis_custom_config cfg = {0}; //loads info on success
|
||||
|
||||
data = init_vorbis_custom(sf, 0x00, VORBIS_OOR, &cfg);
|
||||
|
@ -50,15 +50,15 @@ VGMSTREAM* init_vgmstream_oor(STREAMFILE* sf) {
|
|||
// v0 files don't set last granule (must be done after opening streamfiles)
|
||||
if (!cfg.last_granule)
|
||||
vgmstream->num_samples = vorbis_custom_get_samples(vgmstream);
|
||||
#else
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
return vgmstream;
|
||||
fail:
|
||||
free_vorbis_custom(data);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
#else
|
||||
return NULL;
|
||||
#endif
|
||||
}
|
||||
|
||||
// OOR is bitpacked but try to determine if bytes look like a .oor (will fail later if we picked a wrong candidate).
|
||||
|
|
|
@ -136,8 +136,9 @@ VGMSTREAM* init_vgmstream_opus_std(STREAMFILE* sf) {
|
|||
/* .opus: standard / .lopus: for plugins
|
||||
* .bgm: Cotton Reboot (Switch)
|
||||
* .opu: Ys Memoire: The Oath in Felghana (Switch)
|
||||
* .ogg: Trouble Witches Origin (Switch) */
|
||||
if (!check_extensions(sf,"opus,lopus,bgm,opu,ogg,logg"))
|
||||
* .ogg: Trouble Witches Origin (Switch)
|
||||
* .opusnx: Sweet Café Collection (Switch) */
|
||||
if (!check_extensions(sf,"opus,lopus,bgm,opu,ogg,logg,opusnx"))
|
||||
goto fail;
|
||||
|
||||
offset = 0x00;
|
||||
|
|
|
@ -1,44 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* ASTL - found in Dead Rising (PC) */
|
||||
VGMSTREAM * init_vgmstream_pc_ast(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset, data_size;
|
||||
int loop_flag, channel_count;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
if ( !check_extensions(streamFile,"ast"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x00,streamFile) != 0x4153544C) /* "ASTL" */
|
||||
goto fail;
|
||||
|
||||
|
||||
loop_flag = 0; //TODO - Find hidden loop point calc and flag
|
||||
channel_count = read_8bit(0x32, streamFile);
|
||||
data_size = read_32bitLE(0x20,streamFile);
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* TODO - Find non-obvious loop points and flag (if any) */
|
||||
start_offset = read_32bitLE(0x10,streamFile);
|
||||
vgmstream->sample_rate = read_32bitLE(0x34,streamFile);
|
||||
vgmstream->coding_type = coding_PCM16LE;
|
||||
vgmstream->num_samples = data_size/(channel_count*2);
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x2;
|
||||
vgmstream->meta_type = meta_PC_AST;
|
||||
|
||||
/* open the file for reading */
|
||||
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -1,56 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* rnd (from Karaoke Revolution) */
|
||||
VGMSTREAM * init_vgmstream_ps2_rnd(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("rnd",filename_extension(filename))) goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = read_32bitLE(0x00,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x10;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x04,streamFile);
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->num_samples = (get_streamfile_size(streamFile)-0x10)/16*28/vgmstream->channels;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x2000;
|
||||
vgmstream->meta_type = meta_HGC1;
|
||||
|
||||
/* 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;
|
||||
}
|
|
@ -1,64 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* VGV (from Rune: Viking Warlord) */
|
||||
VGMSTREAM * init_vgmstream_ps2_vgv(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("vgv",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x08,streamFile) != 0x0)
|
||||
goto fail;
|
||||
if (read_32bitBE(0x0C,streamFile) != 0x0)
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = 1;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x10;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x0,streamFile);
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->num_samples = (get_streamfile_size(streamFile))*28/16/channel_count;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = (get_streamfile_size(streamFile)-start_offset)*28/16/channel_count;
|
||||
}
|
||||
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_PS2_VGV;
|
||||
|
||||
/* 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;
|
||||
}
|
|
@ -185,7 +185,7 @@ typedef struct {
|
|||
bool is_at9;
|
||||
} riff_fmt_chunk;
|
||||
|
||||
static int read_fmt(int big_endian, STREAMFILE* sf, off_t offset, riff_fmt_chunk* fmt) {
|
||||
static bool read_fmt(bool big_endian, STREAMFILE* sf, off_t offset, riff_fmt_chunk* fmt) {
|
||||
uint32_t (*read_u32)(off_t,STREAMFILE*) = big_endian ? read_u32be : read_u32le;
|
||||
uint16_t (*read_u16)(off_t,STREAMFILE*) = big_endian ? read_u16be : read_u16le;
|
||||
|
||||
|
@ -235,19 +235,19 @@ static int read_fmt(int big_endian, STREAMFILE* sf, off_t offset, riff_fmt_chunk
|
|||
|
||||
case 0x0001: /* PCM */
|
||||
switch (fmt->bps) {
|
||||
case 32:
|
||||
case 32: /* Get Off My Lawn! (PC) */
|
||||
fmt->coding_type = coding_PCM32LE;
|
||||
break;
|
||||
case 24: /* Omori (PC) */
|
||||
case 24: /* Tinertia (PC), Beatbuddy (WiiU) */
|
||||
fmt->coding_type = coding_PCM24LE;
|
||||
break;
|
||||
case 16:
|
||||
case 16: /* common */
|
||||
fmt->coding_type = big_endian ? coding_PCM16BE : coding_PCM16LE;
|
||||
/* broken block size [Rayman 2 (DC)] */
|
||||
if (fmt->block_size == 0x02 && fmt->channels > 1)
|
||||
fmt->block_size = 0x02 * fmt->channels;
|
||||
break;
|
||||
case 8:
|
||||
case 8: /* The Lost Vikings 2 (PC), Phoenix Wright: Ace Attorney (iOS) */
|
||||
fmt->coding_type = coding_PCM8_U;
|
||||
break;
|
||||
default:
|
||||
|
@ -256,7 +256,7 @@ static int read_fmt(int big_endian, STREAMFILE* sf, off_t offset, riff_fmt_chunk
|
|||
fmt->interleave = fmt->block_size / fmt->channels;
|
||||
break;
|
||||
|
||||
case 0x0002: /* MSADPCM */
|
||||
case 0x0002: /* MSADPCM [Descent: Freespace (PC)] */
|
||||
if (fmt->bps == 4) {
|
||||
/* ADPCMWAVEFORMAT extra data:
|
||||
* - samples per frame (16b)
|
||||
|
@ -273,10 +273,12 @@ static int read_fmt(int big_endian, STREAMFILE* sf, off_t offset, riff_fmt_chunk
|
|||
goto fail;
|
||||
}
|
||||
break;
|
||||
case 0x0003: /* floating point PCM */
|
||||
|
||||
case 0x0003: /* floating point PCM [Cube World (PC), SphereZor (WiiU)] */
|
||||
if (fmt->bps == 32) {
|
||||
fmt->coding_type = coding_PCMFLOAT;
|
||||
} else {
|
||||
}
|
||||
else {
|
||||
goto fail;
|
||||
}
|
||||
fmt->interleave = fmt->block_size / fmt->channels;
|
||||
|
@ -407,10 +409,10 @@ static int read_fmt(int big_endian, STREAMFILE* sf, off_t offset, riff_fmt_chunk
|
|||
goto fail;
|
||||
}
|
||||
|
||||
return 1;
|
||||
return true;
|
||||
|
||||
fail:
|
||||
return 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool is_ue4_msadpcm(STREAMFILE* sf, riff_fmt_chunk* fmt, int fact_sample_count, off_t start_offset, uint32_t data_size);
|
||||
|
@ -481,8 +483,9 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
|
|||
* .voi: Sol Trigger (PSP)[ATRAC3]
|
||||
* .se: Rockman X4 (PC)
|
||||
* .v: Rozen Maiden: Duellwalzer (PS2)
|
||||
* .xst: Animaniacs: The Great Edgar Hunt (Xbox)
|
||||
*/
|
||||
if (!check_extensions(sf, "wav,lwav,xwav,mwv,da,dax,cd,med,snd,adx,adp,xss,xsew,adpcm,adw,wd,,sbv,wvx,str,at3,rws,aud,at9,ckd,saf,ima,nsa,pcm,xvag,ogg,logg,p1d,xms,mus,dat,ldat,wma,lwma,caf,wax,voi,se,v")) {
|
||||
if (!check_extensions(sf, "wav,lwav,xwav,mwv,da,dax,cd,med,snd,adx,adp,xss,xsew,adpcm,adw,wd,,sbv,wvx,str,at3,rws,aud,at9,ckd,saf,ima,nsa,pcm,xvag,ogg,logg,p1d,xms,mus,dat,ldat,wma,lwma,caf,wax,voi,se,v,xst")) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -589,7 +592,7 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
|
|||
goto fail; /* only one per file */
|
||||
fmt_chunk_found = true;
|
||||
|
||||
if (!read_fmt(0, sf, current_chunk, &fmt))
|
||||
if (!read_fmt(false, sf, current_chunk, &fmt))
|
||||
goto fail;
|
||||
|
||||
/* some Dreamcast/Naomi games again [Headhunter (DC), Bomber hehhe (DC), Rayman 2 (DC)] */
|
||||
|
@ -1291,7 +1294,7 @@ VGMSTREAM* init_vgmstream_rifx(STREAMFILE* sf) {
|
|||
if (FormatChunkFound) goto fail;
|
||||
FormatChunkFound = 1;
|
||||
|
||||
if (!read_fmt(1, sf, current_chunk, &fmt))
|
||||
if (!read_fmt(true, sf, current_chunk, &fmt))
|
||||
goto fail;
|
||||
|
||||
break;
|
||||
|
|
|
@ -1,68 +1,68 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* SD9 - from Konami arcade games [beatmania IIDX series (AC), BeatStream (AC)] */
|
||||
VGMSTREAM * init_vgmstream_sd9(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile, "sd9"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x0, streamFile) != 0x53443900) /* SD9 */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x20, streamFile) != 0x52494646) /* RIFF */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x28, streamFile) != 0x57415645) /* WAVE */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x2c, streamFile) != 0x666D7420) /* fmt */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x72, streamFile) != 0x64617461) /* data */
|
||||
goto fail;
|
||||
|
||||
/* Some SD9s may loop without any loop points specificed.
|
||||
If loop_flag is set with no points, loop entire song. */
|
||||
|
||||
loop_flag = read_16bitLE(0x0e,streamFile);
|
||||
//loop_flag = read_32bitLE(0x18, streamFile); // use loop end
|
||||
channel_count = read_16bitLE(0x36, streamFile);
|
||||
start_offset = 0x7a;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = read_32bitLE(0x38, streamFile);
|
||||
vgmstream->num_samples = read_32bitLE(0x6e, streamFile);
|
||||
if (loop_flag > 0) {
|
||||
vgmstream->loop_start_sample = read_32bitLE(0x14, streamFile) / 2 / channel_count;
|
||||
vgmstream->loop_end_sample = read_32bitLE(0x18, streamFile) / 2 / channel_count;
|
||||
if (vgmstream->loop_end_sample == 0) {
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
}
|
||||
|
||||
/* beatmania IIDX 21: Spada is a special case. Loop flag is false but loops exist.
|
||||
Konami, Why? */
|
||||
if ((loop_flag < 0) && (read_32bitLE(0x18, streamFile) !=0)) {
|
||||
vgmstream->loop_start_sample = read_32bitLE(0x14, streamFile) / 2 / channel_count;
|
||||
vgmstream->loop_end_sample = read_32bitLE(0x18, streamFile) / 2 / channel_count;
|
||||
}
|
||||
|
||||
vgmstream->coding_type = coding_MSADPCM;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->frame_size = read_16bitLE(0x40, streamFile);
|
||||
vgmstream->meta_type = meta_SD9;
|
||||
if (!msadpcm_check_coefs(streamFile, 0x48))
|
||||
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"
|
||||
|
||||
|
||||
/* SD9 - from Konami arcade games [beatmania IIDX series (AC), BeatStream (AC)] */
|
||||
VGMSTREAM* init_vgmstream_sd9(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channels;
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00, sf, "SD9\0"))
|
||||
return NULL;
|
||||
// .sd9: header ID
|
||||
if (!check_extensions(sf, "sd9"))
|
||||
return NULL;
|
||||
|
||||
// 04: header size
|
||||
// 08: data size
|
||||
// 0c: 0x3231?
|
||||
int loop_count = read_s16le(0x0e,sf); //-1 or N;
|
||||
uint32_t loop_start = read_u32le(0x14, sf);
|
||||
uint32_t loop_end = read_u32le(0x18, sf);
|
||||
// 1c: loop flag? (1=loop_end defined)
|
||||
// 1e: category id?
|
||||
|
||||
// Some SD9s sets count > 0 without any loop points specificed, loop entire song.
|
||||
// However can't tell apart from songs that shouldn't do full loops. (ex. IIDX 16 sys_sound.ssp #3 vs #26).
|
||||
// In IIDX 21 loop count < 0 w/ loops exist; in other cases count < 0 usually has no loops defined.
|
||||
loop_flag = (loop_count > 0) || (loop_count < 0 && loop_end);
|
||||
|
||||
// regular RIFF header with fmt + fact + data
|
||||
if (!is_id32be(0x20, sf, "RIFF"))
|
||||
return NULL;
|
||||
if (!is_id32be(0x28, sf, "WAVE"))
|
||||
return NULL;
|
||||
if (!is_id32be(0x2c, sf, "fmt "))
|
||||
return NULL;
|
||||
|
||||
channels = read_u16le(0x36, sf);
|
||||
start_offset = 0x7a;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_SD9;
|
||||
vgmstream->sample_rate = read_s32le(0x38, sf);
|
||||
vgmstream->num_samples = read_s32le(0x6e, sf);
|
||||
vgmstream->loop_start_sample = pcm16_bytes_to_samples(loop_start, channels);
|
||||
vgmstream->loop_end_sample = pcm16_bytes_to_samples(loop_end, channels);
|
||||
if (vgmstream->loop_end_sample == 0)
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
|
||||
vgmstream->coding_type = coding_MSADPCM;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->frame_size = read_u16le(0x40, sf);
|
||||
if (!msadpcm_check_coefs(sf, 0x48))
|
||||
goto fail;
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
|
159
Frameworks/vgmstream/vgmstream/src/meta/sfx0_monster.c
Normal file
159
Frameworks/vgmstream/vgmstream/src/meta/sfx0_monster.c
Normal file
|
@ -0,0 +1,159 @@
|
|||
#include "meta.h"
|
||||
#include "../util/meta_utils.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
/* SFX0 - from Monster Games [NASCAR Heat 2002 (Xbox), NASCAR: Dirt to Daytona (PS2/GC), Excite Truck (Wii), ExciteBots (Wii)] */
|
||||
VGMSTREAM* init_vgmstream_sfx0_monster(STREAMFILE* sf) {
|
||||
|
||||
/* checks*/
|
||||
uint32_t data_size = read_u32le(0x00,sf);
|
||||
uint32_t head_size = read_u32le(0x04,sf);
|
||||
if (!data_size || !head_size || data_size + head_size != get_streamfile_size(sf))
|
||||
return NULL;
|
||||
// .sfx: common
|
||||
// .sf0: tiny .sn0 (preload?)
|
||||
if (!check_extensions(sf, "sfx,sf0"))
|
||||
return NULL;
|
||||
|
||||
// SFX0 is the internal fourCC used for .sfx
|
||||
|
||||
meta_header_t h = {0};
|
||||
h.meta = meta_SFX0_MONSTER;
|
||||
|
||||
h.loop_flag = read_u8 (0x08, sf);
|
||||
int extra_flag = read_u8 (0x09, sf); // always 1 in DSP
|
||||
// 0a: null?
|
||||
int codec = read_u16le(0x0c, sf);
|
||||
h.channels = read_u16le(0x0e, sf);
|
||||
h.sample_rate = read_s32le(0x10, sf);
|
||||
// 14: bitrate (not always accurate?)
|
||||
uint32_t config1 = read_u32le(0x18, sf); // block size + bps
|
||||
uint32_t config2 = read_u32le(0x1c, sf); // usually 0
|
||||
// 20: 0x10 padding (Xbox), partial DSP header on DSP or data
|
||||
|
||||
if (h.channels != 1) // not seen (late games use .sfx + .2.sfx dual tracks)
|
||||
return NULL;
|
||||
h.stream_offset = head_size;
|
||||
|
||||
// .sf0 mini files
|
||||
if (codec == 0x00 && extra_flag == 0 && head_size <= 0x20) {
|
||||
codec = 0x0002;
|
||||
h.loop_flag = 0;
|
||||
}
|
||||
|
||||
switch (codec) {
|
||||
case 0xCFFF: // PS2 games
|
||||
if (config1 != 0x00040002 || config2 != 0)
|
||||
return NULL;
|
||||
h.coding = coding_PSX;
|
||||
h.layout = layout_none;
|
||||
|
||||
h.num_samples = ps_bytes_to_samples(data_size, h.channels);
|
||||
break;
|
||||
|
||||
case 0x0069: // Xbox games
|
||||
if (config1 != 0x00040024 || config2 != 0x00400002)
|
||||
return NULL;
|
||||
h.coding = coding_XBOX_IMA;
|
||||
h.layout = layout_none;
|
||||
|
||||
h.num_samples = xbox_ima_bytes_to_samples(data_size, h.channels);
|
||||
break;
|
||||
|
||||
case 0x0001: // GC games
|
||||
if (config1 != 0x00100002 || config2 != 0)
|
||||
return NULL;
|
||||
h.coding = coding_PCM16LE; //LE!
|
||||
h.layout = layout_none;
|
||||
|
||||
h.num_samples = pcm16_bytes_to_samples(data_size, h.channels);
|
||||
break;
|
||||
|
||||
case 0x0000: // Wii games
|
||||
if (config1 != 0x00100000 || config2 != 0)
|
||||
return NULL;
|
||||
h.coding = coding_NGC_DSP;
|
||||
h.layout = layout_none;
|
||||
|
||||
h.num_samples = dsp_bytes_to_samples(data_size, h.channels);
|
||||
|
||||
h.big_endian = true;
|
||||
h.coefs_offset = 0x3c;
|
||||
break;
|
||||
|
||||
case 0x0002: // fake codec for .sf0 [ExciteBots (Wii)]
|
||||
if (config1 != 0x00100000 || config2 != 0)
|
||||
return NULL;
|
||||
h.coding = coding_PCM16BE;
|
||||
h.layout = layout_none;
|
||||
|
||||
h.num_samples = pcm16_bytes_to_samples(data_size, h.channels);
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// full loops only
|
||||
h.loop_start = 0;
|
||||
h.loop_end = h.num_samples;
|
||||
|
||||
h.open_stream = true;
|
||||
h.sf = sf;
|
||||
|
||||
return alloc_metastream(&h);
|
||||
}
|
||||
|
||||
/* SFX0 - from early Monster Games [NASCAR Heat 2002 (PS2)] */
|
||||
VGMSTREAM* init_vgmstream_sfx0_monster_old(STREAMFILE* sf) {
|
||||
|
||||
/* checks*/
|
||||
uint32_t data_size = read_u32le(0x00,sf);
|
||||
uint32_t head_size = 0x16;
|
||||
if (!data_size || data_size + head_size != get_streamfile_size(sf))
|
||||
return NULL;
|
||||
if (!check_extensions(sf, "sfx"))
|
||||
return NULL;
|
||||
|
||||
// SFX0 is the internal fourCC used for .sfx
|
||||
|
||||
meta_header_t h = {0};
|
||||
h.meta = meta_SFX0_MONSTER;
|
||||
|
||||
int codec = read_u16le(0x04, sf);
|
||||
h.channels = read_u16le(0x06, sf);
|
||||
h.sample_rate = read_s32le(0x08, sf);
|
||||
// 0c: bitrate (not always accurate?)
|
||||
uint32_t config1 = read_u32le(0x10, sf);
|
||||
uint16_t config2 = read_u16le(0x14, sf);
|
||||
|
||||
if (h.channels != 1) //not seen
|
||||
return NULL;
|
||||
h.stream_offset = head_size;
|
||||
|
||||
switch (codec) {
|
||||
case 0xCFFF:
|
||||
if (config1 != 0x00040002 || config2 != 0x6164)
|
||||
return NULL;
|
||||
h.coding = coding_PSX;
|
||||
h.layout = layout_none;
|
||||
|
||||
h.num_samples = ps_bytes_to_samples(data_size, h.channels);
|
||||
|
||||
h.loop_flag = read_u8(0x17, sf) == 0x06; //PSX loop flags
|
||||
break;
|
||||
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// full loops only
|
||||
h.loop_start = 0;
|
||||
h.loop_end = h.num_samples;
|
||||
|
||||
h.open_stream = true;
|
||||
h.sf = sf;
|
||||
|
||||
return alloc_metastream(&h);
|
||||
}
|
103
Frameworks/vgmstream/vgmstream/src/meta/sfxb.c
Normal file
103
Frameworks/vgmstream/vgmstream/src/meta/sfxb.c
Normal file
|
@ -0,0 +1,103 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* SFXB - from Konami games [Yu-Gi-Oh: The Dawn of Destiny (Xbox)] */
|
||||
VGMSTREAM* init_vgmstream_sfxb(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
int loop_flag, channels, sample_rate;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "SFXB"))
|
||||
return NULL;
|
||||
if (!check_extensions(sf,"xau"))
|
||||
return NULL;
|
||||
// 04: version? (2)
|
||||
// 08: file id
|
||||
// 0c: file size
|
||||
// 10: possibly chunk definitions (all files have 4)
|
||||
// 00: type (00030200=subsong info, 00030201=headers, 00030202=data)
|
||||
// 04: size
|
||||
// 08: relative offset (after chunks = 0x50)
|
||||
// 0c: always 0x00000202
|
||||
|
||||
uint32_t subs_offset = 0x50 + read_u32le(0x28,sf); //always 0x00
|
||||
uint32_t head_offset = 0x50 + read_u32le(0x38,sf); //always 0x10
|
||||
uint32_t data_offset = 0x50 + read_u32le(0x48,sf); //varies
|
||||
|
||||
// subsong chunk
|
||||
// 00: file id again
|
||||
// 04: subsongs
|
||||
// 08: always 0x7F
|
||||
// 0c: null
|
||||
int target_subsong = sf->stream_index;
|
||||
int total_subsongs = read_u32le(subs_offset + 0x04, sf);
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
if (target_subsong > total_subsongs)
|
||||
return NULL;
|
||||
|
||||
uint32_t entry_offset = head_offset + 0x60 * (target_subsong - 1);
|
||||
// 00: type
|
||||
// 04: flags?
|
||||
// 08: flags? (always 0x00020000)
|
||||
// 0c: offset
|
||||
// 10: size
|
||||
// 14: null
|
||||
// 18: loop start
|
||||
// 1c: loop end
|
||||
// 20: RIFF + "XWV" + "fmt" + "loop" (same as loop start/end) + "data" (same as size)
|
||||
|
||||
uint32_t stream_type = read_u32le(entry_offset + 0x00, sf);
|
||||
uint32_t stream_offset = read_u32le(entry_offset + 0x0c, sf) + data_offset;
|
||||
uint32_t stream_size = read_u32le(entry_offset + 0x10, sf);
|
||||
uint32_t loop_start = read_u32le(entry_offset + 0x18, sf);
|
||||
uint32_t loop_end = read_u32le(entry_offset + 0x1c, sf) + loop_start;
|
||||
if (!is_id32be(entry_offset + 0x20,sf, "RIFF"))
|
||||
return NULL;
|
||||
if (read_u16le(entry_offset + 0x34,sf) != 0x01) /* codec */
|
||||
return NULL;
|
||||
channels = read_u16le(entry_offset + 0x36, sf);
|
||||
sample_rate = read_u32le(entry_offset + 0x38, sf);
|
||||
|
||||
loop_flag = (loop_end > 0);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_SFXB;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
vgmstream->stream_size = stream_size;
|
||||
|
||||
switch(stream_type) {
|
||||
case 0x0001:
|
||||
vgmstream->coding_type = coding_SILENCE;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->num_samples = sample_rate;
|
||||
|
||||
// stream info is repeat of first subsong
|
||||
break;
|
||||
|
||||
case 0x0F01:
|
||||
vgmstream->coding_type = coding_PCM16LE;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x02;
|
||||
|
||||
vgmstream->num_samples = pcm16_bytes_to_samples(stream_size, channels);
|
||||
vgmstream->loop_start_sample = pcm16_bytes_to_samples(loop_start, channels);
|
||||
vgmstream->loop_end_sample = pcm16_bytes_to_samples(loop_end, channels);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, stream_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
60
Frameworks/vgmstream/vgmstream/src/meta/song_monster.c
Normal file
60
Frameworks/vgmstream/vgmstream/src/meta/song_monster.c
Normal file
|
@ -0,0 +1,60 @@
|
|||
#include "meta.h"
|
||||
#include "../util/meta_utils.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
static STREAMFILE* setup_song_streamfile(STREAMFILE* sf) {
|
||||
STREAMFILE* new_sf = NULL;
|
||||
STREAMFILE* multi_sf[2] = {0};
|
||||
|
||||
multi_sf[0] = open_wrap_streamfile(sf);
|
||||
multi_sf[1] = open_streamfile_by_ext(sf, "sf0");
|
||||
new_sf = open_multifile_streamfile_f(multi_sf, 2);
|
||||
return new_sf;
|
||||
}
|
||||
|
||||
/* Song - from Monster Games with split data [ExciteBots (Wii)] */
|
||||
VGMSTREAM* init_vgmstream_song_monster(STREAMFILE* sf) {
|
||||
|
||||
/* checks*/
|
||||
int sample_rate = read_s32le(0x00,sf);
|
||||
if (sample_rate != 32000)
|
||||
return NULL;
|
||||
if (read_u32be(0x04,sf))
|
||||
return NULL;
|
||||
// .sn0/sng: common
|
||||
if (!check_extensions(sf, "sn0,sng"))
|
||||
return NULL;
|
||||
|
||||
|
||||
meta_header_t h = {0};
|
||||
h.meta = meta_SONG_MONSTER;
|
||||
|
||||
h.chan_size = read_u32le(0x08,sf);
|
||||
h.interleave = read_u32le(0x0c,sf);
|
||||
if (read_u32be(0x10,sf))
|
||||
return NULL;
|
||||
h.stream_offset = 0x14;
|
||||
|
||||
h.sample_rate = sample_rate;
|
||||
h.channels = 2;
|
||||
if (h.interleave * h.channels + 0x14 != get_streamfile_size(sf))
|
||||
return NULL;
|
||||
|
||||
h.coding = coding_PCM16BE;
|
||||
h.layout = layout_interleave;
|
||||
|
||||
uint32_t total_size = (h.chan_size + h.interleave) * h.channels;
|
||||
h.num_samples = pcm16_bytes_to_samples(total_size, h.channels);
|
||||
|
||||
// first block is in this header, rest of data in separate sf0; join both to play as one (could use segments too)
|
||||
STREAMFILE* temp_sf = setup_song_streamfile(sf);
|
||||
if (!temp_sf)
|
||||
return NULL;
|
||||
h.open_stream = true;
|
||||
h.sf = temp_sf;
|
||||
|
||||
VGMSTREAM* v = alloc_metastream(&h);
|
||||
close_streamfile(temp_sf);
|
||||
return v;
|
||||
}
|
|
@ -31,7 +31,7 @@ VGMSTREAM* init_vgmstream_spsd(STREAMFILE *sf) {
|
|||
/* At 0x30(4*ch) is some config per channel but doesn't seem to affect ADPCM (found with PCM too) */
|
||||
|
||||
|
||||
//todo with 0x80 seems 0x2c is a loop_start_sample but must be adjusted to +1 block? (uncommon flag though)
|
||||
// With 0x80, 0x2c is a loop_start_sample but must be adjusted to +1 block (uncommon flag though)
|
||||
loop_flag = (flags & 0x80);
|
||||
channels = ((flags & 0x01) || (flags & 0x02)) ? 2 : 1; /* 0x02 is rare (Virtua Tennis 2) */
|
||||
start_offset = 0x40;
|
||||
|
@ -63,7 +63,7 @@ VGMSTREAM* init_vgmstream_spsd(STREAMFILE *sf) {
|
|||
case 0x03: /* standard */
|
||||
vgmstream->coding_type = coding_AICA_int;
|
||||
vgmstream->num_samples = yamaha_bytes_to_samples(data_size, channels);
|
||||
vgmstream->loop_start_sample = /*read_s32le(0x2c,streamFile) +*/ yamaha_bytes_to_samples(0x2000,1);
|
||||
vgmstream->loop_start_sample = read_s32le(0x2c,sf) + yamaha_bytes_to_samples(0x2000,1);
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
break;
|
||||
|
||||
|
|
74
Frameworks/vgmstream/vgmstream/src/meta/ssp.c
Normal file
74
Frameworks/vgmstream/vgmstream/src/meta/ssp.c
Normal file
|
@ -0,0 +1,74 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../layout/layout.h"
|
||||
|
||||
|
||||
/* .ssp - Konami/Bemani beatmania IIDX container [beatmania IIDX 16 (AC) ~ beatmania IIDX 19 (AC), Bishi Bashi Channel (AC)] */
|
||||
VGMSTREAM* init_vgmstream_ssp(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
STREAMFILE* temp_sf = NULL;
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(sf, "ssp"))
|
||||
return NULL;
|
||||
|
||||
|
||||
// 00: bank name
|
||||
// 10: first subsong offset
|
||||
// 14: max subsongs
|
||||
// 18+: memory garbage?
|
||||
// 48: table
|
||||
uint32_t table_offset = 0x48;
|
||||
uint32_t first_offset = read_u32le(0x10,sf);
|
||||
|
||||
int target_subsong = sf->stream_index;
|
||||
int total_subsongs = read_u32le(0x14,sf);
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
if (target_subsong > total_subsongs || total_subsongs < 1) // arbitrary max
|
||||
return NULL;
|
||||
|
||||
// extra checks to fail faster
|
||||
if (total_subsongs > 1024) // arbitrary max
|
||||
return NULL;
|
||||
if (first_offset != read_u32le(table_offset, sf))
|
||||
return NULL;
|
||||
|
||||
// unlike .2dx table seems to have many blanks (total subsongs seems accurate)
|
||||
uint32_t subfile_offset = 0;
|
||||
int current_subsong = 0;
|
||||
uint32_t offset = table_offset;
|
||||
while (offset < first_offset) {
|
||||
uint32_t entry_offset = read_u32le(offset, sf);
|
||||
offset += 0x04;
|
||||
|
||||
if (entry_offset == 0)
|
||||
continue;
|
||||
current_subsong++;
|
||||
|
||||
if (current_subsong == target_subsong) {
|
||||
subfile_offset = entry_offset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (subfile_offset == 0)
|
||||
return NULL;
|
||||
|
||||
uint32_t subfile_size = read_u32le(subfile_offset + 0x08, sf) + 0x18;
|
||||
|
||||
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "sd9");
|
||||
if (!temp_sf) goto fail;
|
||||
|
||||
vgmstream = init_vgmstream_sd9(temp_sf);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
|
||||
close_streamfile(temp_sf);
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_streamfile(temp_sf);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
43
Frameworks/vgmstream/vgmstream/src/meta/str_sqex.c
Normal file
43
Frameworks/vgmstream/vgmstream/src/meta/str_sqex.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include "meta.h"
|
||||
#include "../util/meta_utils.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
/* STR - from Final Fantasy Crystal Chronicles (GC) */
|
||||
VGMSTREAM* init_vgmstream_str_sqex(STREAMFILE* sf) {
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "STR\0"))
|
||||
return NULL;
|
||||
if (!check_extensions(sf, "str"))
|
||||
return NULL;
|
||||
|
||||
if (read_u32be(0x04,sf) != 0)
|
||||
return NULL;
|
||||
if (read_u32be(0x08,sf) != get_streamfile_size(sf))
|
||||
return NULL;
|
||||
|
||||
meta_header_t h = {0};
|
||||
h.meta = meta_STR_SQEX;
|
||||
|
||||
h.num_samples = read_s32be(0x0C, sf) * 14;
|
||||
// 10: always -1 (loop point?)
|
||||
h.sample_rate = read_u32be(0x14, sf) != 0 ? 44100 : 32000; // unknown value
|
||||
h.channels = read_s32be(0x18, sf);
|
||||
// 1c: volume? (128)
|
||||
h.coefs_offset = 0x20;
|
||||
h.coefs_spacing = 0x2e;
|
||||
h.big_endian = true;
|
||||
// 40: initial ps
|
||||
// 48: hist?
|
||||
|
||||
h.interleave = 0x1000;
|
||||
h.stream_offset = 0x1000;
|
||||
|
||||
h.coding = coding_NGC_DSP;
|
||||
h.layout = layout_interleave;
|
||||
h.open_stream = true;
|
||||
h.sf = sf;
|
||||
|
||||
return alloc_metastream(&h);
|
||||
}
|
|
@ -226,8 +226,7 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) {
|
|||
}
|
||||
|
||||
|
||||
/* set common interleaves to simplify usage
|
||||
* (maybe should ignore if manually overwritten, possibly with 0 on purpose?) */
|
||||
/* set common interleaves to simplify usage */
|
||||
if (txth.interleave == 0) {
|
||||
uint32_t interleave = 0;
|
||||
switch(txth.codec) {
|
||||
|
@ -244,7 +243,7 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) {
|
|||
case PCM8_U:
|
||||
case PCM8_SB:
|
||||
case ULAW:
|
||||
case ALAW:
|
||||
case ALAW: interleave = 0x01; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -16,8 +16,6 @@
|
|||
static void apply_settings_body(VGMSTREAM* vgmstream, txtp_entry_t* entry) {
|
||||
// tweak playable part, which only makes sense
|
||||
|
||||
VGM_LOG("tesst: %i,%i\n", entry->body_mode , vgmstream->loop_flag);
|
||||
|
||||
if (!entry->body_mode || !vgmstream->loop_flag)
|
||||
return;
|
||||
|
||||
|
|
|
@ -1,45 +1,47 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* .VAI - from Asobo Studio games [Ratatouille (GC)] */
|
||||
VGMSTREAM * init_vgmstream_vai(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
size_t data_size;
|
||||
int loop_flag, channel_count;
|
||||
|
||||
|
||||
/* checks */
|
||||
if ( !check_extensions(streamFile,"vai") )
|
||||
goto fail;
|
||||
|
||||
start_offset = 0x4060;
|
||||
data_size = get_streamfile_size(streamFile) - start_offset;
|
||||
if (read_32bitBE(0x04,streamFile) != data_size)
|
||||
goto fail;
|
||||
|
||||
channel_count = 2;
|
||||
loop_flag = 0;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_VAI;
|
||||
vgmstream->sample_rate = read_32bitBE(0x00,streamFile);
|
||||
vgmstream->num_samples = dsp_bytes_to_samples(data_size,channel_count);
|
||||
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x4000;
|
||||
dsp_read_coefs_be(vgmstream,streamFile,0x0c,0x20);
|
||||
|
||||
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"
|
||||
|
||||
/* .VAI - from Asobo Studio games [Ratatouille (GC)] */
|
||||
VGMSTREAM* init_vgmstream_vai(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
size_t data_size;
|
||||
int loop_flag, channels;
|
||||
|
||||
|
||||
/* checks */
|
||||
int sample_rate = read_s32be(0x00,sf);
|
||||
if (sample_rate < 8000 || sample_rate > 48000) //arbitrary max
|
||||
return NULL;
|
||||
if (!check_extensions(sf,"vai"))
|
||||
return NULL;
|
||||
|
||||
start_offset = 0x4060;
|
||||
data_size = read_s32be(0x04,sf);
|
||||
if (data_size != get_streamfile_size(sf) - start_offset)
|
||||
return NULL;
|
||||
|
||||
channels = 2;
|
||||
loop_flag = 0;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_VAI;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = dsp_bytes_to_samples(data_size,channels);
|
||||
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x4000;
|
||||
dsp_read_coefs_be(vgmstream, sf, 0x0c, 0x20);
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -123,9 +123,9 @@ VGMSTREAM* init_vgmstream_vas_kceo(STREAMFILE* sf) {
|
|||
|
||||
case IMA:
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_blocked_xvas;
|
||||
vgmstream->layout_type = layout_blocked_vas_kceo;
|
||||
|
||||
/* blocks of 0x20000 with padding */
|
||||
// blocks of 0x20000 with 0x20 padding, remove it to calculate samples
|
||||
data_size -= (data_size / 0x20000) * 0x20;
|
||||
loop_start -= (loop_start / 0x20000) * 0x20;
|
||||
loop_end -= (loop_end / 0x20000) * 0x20;
|
||||
|
|
|
@ -2,71 +2,95 @@
|
|||
#include "../util.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../util/meta_utils.h"
|
||||
|
||||
/* VGS - from Guitar Hero Encore - Rocks the 80s, Guitar Hero II PS2 */
|
||||
/* VGS - from Harmonix games [Guitar Hero II (PS2), Guitar Hero Encore: Rocks the 80s (PS2)] */
|
||||
VGMSTREAM* init_vgmstream_vgs(STREAMFILE *sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
size_t channel_size = 0, stream_data_size, stream_frame_count;
|
||||
int channels = 0, loop_flag = 0, sample_rate = 0, stream_sample_rate;
|
||||
int i;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "VgS!"))
|
||||
goto fail;
|
||||
/* 0x04: version? */
|
||||
|
||||
return NULL;
|
||||
// 0x04: version?
|
||||
if (!check_extensions(sf,"vgs"))
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
meta_header_t h = {0};
|
||||
h.meta = meta_VGS;
|
||||
|
||||
/* contains N streams, which can have one less frame, or half frame and sample rate */
|
||||
for (i = 0; i < 8; i++) {
|
||||
stream_sample_rate = read_32bitLE(0x08 + 0x08*i + 0x00,sf);
|
||||
stream_frame_count = read_32bitLE(0x08 + 0x08*i + 0x04,sf);
|
||||
stream_data_size = stream_frame_count*0x10;
|
||||
for (int i = 0; i < 8; i++) {
|
||||
int stream_sample_rate = read_s32le(0x08 + 0x08 * i + 0x00,sf);
|
||||
uint32_t stream_frame_count = read_u32le(0x08 + 0x08 * i + 0x04,sf);
|
||||
uint32_t stream_data_size = stream_frame_count * 0x10;
|
||||
|
||||
if (stream_sample_rate == 0)
|
||||
break;
|
||||
|
||||
if (!sample_rate || !channel_size) {
|
||||
sample_rate = stream_sample_rate;
|
||||
channel_size = stream_data_size;
|
||||
if (!h.sample_rate || !h.chan_size) {
|
||||
h.sample_rate = stream_sample_rate;
|
||||
h.chan_size = stream_data_size;
|
||||
}
|
||||
|
||||
/* some streams end 1 frame early */
|
||||
if (channel_size - 0x10 == stream_data_size) {
|
||||
channel_size -= 0x10;
|
||||
if (h.chan_size - 0x10 == stream_data_size) {
|
||||
h.chan_size -= 0x10;
|
||||
}
|
||||
|
||||
/* Guitar Hero II sometimes uses half sample rate for last stream */
|
||||
if (sample_rate != stream_sample_rate) {
|
||||
if (h.sample_rate != stream_sample_rate) {
|
||||
VGM_LOG("VGS: ignoring stream %i\n", i);
|
||||
//total_streams++; // todo handle substreams
|
||||
break;
|
||||
}
|
||||
|
||||
channels++;
|
||||
h.channels++;
|
||||
}
|
||||
|
||||
start_offset = 0x80;
|
||||
h.stream_offset = 0x80;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
h.num_samples = ps_bytes_to_samples(h.chan_size, 1);
|
||||
|
||||
vgmstream->meta_type = meta_VGS;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = ps_bytes_to_samples(channel_size * channels, channels);
|
||||
h.coding = coding_PSX_badflags; // flag = stream/channel number
|
||||
h.layout = layout_blocked_vgs;
|
||||
h.open_stream = true;
|
||||
h.sf = sf;
|
||||
|
||||
vgmstream->coding_type = coding_PSX_badflags; /* flag = stream/channel number */
|
||||
vgmstream->layout_type = layout_blocked_vgs;
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
return alloc_metastream(&h);
|
||||
}
|
||||
|
||||
/* .vgs - from Harmonix games [Karaoke Revolution (PS2), EyeToy: AntiGrav (PS2)] */
|
||||
VGMSTREAM* init_vgmstream_vgs_old(STREAMFILE* sf) {
|
||||
|
||||
/* checks */
|
||||
int channels = read_s32le(0x00,sf);
|
||||
if (channels < 1 || channels > 4)
|
||||
return NULL;
|
||||
|
||||
// .vgs: actual extension in bigfiles
|
||||
if (!check_extensions(sf,"vgs"))
|
||||
return NULL;
|
||||
|
||||
meta_header_t h = {0};
|
||||
h.meta = meta_VGS;
|
||||
|
||||
h.channels = read_s32le(0x00, sf);
|
||||
h.sample_rate = read_s32le(0x04, sf);
|
||||
int frame_count = read_u32le(0x08, sf);
|
||||
// 0c: usually 0, sometimes garbage
|
||||
|
||||
h.stream_offset = 0x10;
|
||||
h.stream_size = get_streamfile_size(sf) - h.stream_offset;
|
||||
|
||||
if (frame_count * h.channels * 0x10 > h.stream_size)
|
||||
return NULL;
|
||||
|
||||
h.num_samples = ps_bytes_to_samples(h.stream_size, channels);
|
||||
h.interleave = 0x2000;
|
||||
|
||||
h.coding = coding_PSX;
|
||||
h.layout = layout_interleave;
|
||||
h.open_stream = true;
|
||||
h.sf = sf;
|
||||
|
||||
return alloc_metastream(&h);
|
||||
}
|
||||
|
|
33
Frameworks/vgmstream/vgmstream/src/meta/vgv.c
Normal file
33
Frameworks/vgmstream/vgmstream/src/meta/vgv.c
Normal file
|
@ -0,0 +1,33 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util/meta_utils.h"
|
||||
|
||||
/* .VGV - from Rune: Viking Warlord (PS2) */
|
||||
VGMSTREAM* init_vgmstream_vgv(STREAMFILE* sf) {
|
||||
|
||||
/* checks */
|
||||
if (read_u32le(0x00,sf) < 22050 || read_u32le(0x00,sf) > 48000) // always 22050?
|
||||
return NULL;
|
||||
if (read_f32le(0x04,sf) == 0.0 || read_f32le(0x04,sf) > 500.0) //duration, known max is ~432.08 = 7:12
|
||||
return NULL;
|
||||
if (read_u32le(0x08,sf) != 0x00 || read_u32le(0x0c,sf) != 0x00)
|
||||
return NULL;
|
||||
|
||||
if (!check_extensions(sf, "vgv"))
|
||||
return NULL;
|
||||
|
||||
meta_header_t h = {0};
|
||||
h.meta = meta_VGV;
|
||||
|
||||
h.channels = 1;
|
||||
h.sample_rate = read_s32le(0x00, sf);
|
||||
h.stream_offset = 0x10;
|
||||
h.stream_size = get_streamfile_size(sf);
|
||||
h.num_samples = ps_bytes_to_samples(h.stream_size, h.channels);
|
||||
|
||||
h.coding = coding_PSX;
|
||||
h.open_stream = true;
|
||||
h.sf = sf;
|
||||
|
||||
return alloc_metastream(&h);
|
||||
}
|
|
@ -1,125 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* SNG (from Excite Truck [WII]) */
|
||||
VGMSTREAM * init_vgmstream_wii_sng(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int i;
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
int coef1;
|
||||
int coef2;
|
||||
int first_block_len;
|
||||
int second_channel_start;
|
||||
int dataBuffer = 0;
|
||||
int Founddata = 0;
|
||||
size_t file_size;
|
||||
off_t current_chunk;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("sng",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x00,streamFile) != 0x30545352) /* "0STR" */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x04,streamFile) != 0x34000000) /* 0x34000000 */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x08,streamFile) != 0x08000000) /* 0x08000000" */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x0C,streamFile) != 0x01000000) /* 0x01000000 */
|
||||
goto fail;
|
||||
if (read_32bitLE(0x10,streamFile) != (get_streamfile_size(streamFile)))
|
||||
goto fail;
|
||||
|
||||
loop_flag = (read_32bitLE(0x130,streamFile) !=0); /* not sure */
|
||||
channel_count = 2;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x180;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x110,streamFile);
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = read_32bitLE(0x100,streamFile)/16*14*2;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = read_32bitBE(0x130,streamFile)/16*14;
|
||||
vgmstream->loop_end_sample = read_32bitBE(0x134,streamFile)/16*14;
|
||||
}
|
||||
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_WII_SNG;
|
||||
|
||||
|
||||
/* scan file until we find a "data" string */
|
||||
first_block_len = read_32bitLE(0x100,streamFile);
|
||||
file_size = get_streamfile_size(streamFile);
|
||||
{
|
||||
current_chunk = first_block_len;
|
||||
/* Start at 0 and loop until we reached the
|
||||
file size, or until we found a "data string */
|
||||
while (!Founddata && current_chunk < file_size) {
|
||||
dataBuffer = (read_32bitLE(current_chunk,streamFile));
|
||||
if (dataBuffer == first_block_len) { /* The value from the first block length */
|
||||
/* if "data" string found, retrieve the needed infos */
|
||||
Founddata = 1;
|
||||
second_channel_start = current_chunk+0x80;
|
||||
/* We will cancel the search here if we have a match */
|
||||
break;
|
||||
}
|
||||
/* else we will increase the search offset by 1 */
|
||||
current_chunk = current_chunk + 1;
|
||||
}
|
||||
}
|
||||
|
||||
coef1 = 0x13C;
|
||||
if (Founddata == 0) {
|
||||
goto fail;
|
||||
} else if (Founddata == 1) {
|
||||
coef2 = current_chunk+0x3C;
|
||||
}
|
||||
|
||||
|
||||
for (i=0;i<16;i++)
|
||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(coef1+i*2,streamFile);
|
||||
if (channel_count == 2) {
|
||||
for (i=0;i<16;i++)
|
||||
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(coef2+i*2,streamFile);
|
||||
}
|
||||
|
||||
/* open the file for reading */
|
||||
{
|
||||
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;
|
||||
|
||||
/* The first channel */
|
||||
vgmstream->ch[0].channel_start_offset=
|
||||
vgmstream->ch[0].offset=start_offset;
|
||||
|
||||
/* The second channel */
|
||||
if (channel_count == 2) {
|
||||
vgmstream->ch[1].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
|
||||
if (!vgmstream->ch[1].streamfile) goto fail;
|
||||
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[1].offset=second_channel_start;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -1,60 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* XAU - from Konami games [Yu-Gi-Oh - The Dawn of Destiny (Xbox)] */
|
||||
VGMSTREAM * init_vgmstream_xau_konami(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset, header_offset;
|
||||
size_t stream_size;
|
||||
int loop_flag, channel_count, sample_rate;
|
||||
off_t loop_start, loop_end;
|
||||
|
||||
|
||||
/* checks */
|
||||
if ( !check_extensions(streamFile,"xau") )
|
||||
goto fail;
|
||||
if (read_32bitBE(0x00,streamFile) != 0x53465842) /* "SFXB" */
|
||||
goto fail;
|
||||
|
||||
//todo: subsongs used in sfx packs (rare)
|
||||
if (read_32bitLE(0x54,streamFile) != 1) /* subsong count */
|
||||
goto fail;
|
||||
|
||||
start_offset = 0x60 + read_32bitLE(0x34,streamFile);
|
||||
header_offset = 0x60 + 0x20 + 0x40*0; /* target subsong */
|
||||
|
||||
if (read_32bitBE(header_offset+0x00,streamFile) != 0x52494646) /* "RIFF" */
|
||||
goto fail;
|
||||
if (read_16bitLE(header_offset+0x14,streamFile) != 0x01) /* codec */
|
||||
goto fail;
|
||||
channel_count = read_16bitLE(header_offset+0x16,streamFile);
|
||||
sample_rate = read_32bitLE(header_offset+0x18,streamFile);
|
||||
loop_start = read_32bitLE(header_offset+030,streamFile);
|
||||
loop_end = read_32bitLE(header_offset+0x34,streamFile);
|
||||
loop_flag = (loop_end > 0);
|
||||
|
||||
stream_size = get_streamfile_size(streamFile) - start_offset;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_XAU_KONAMI;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = pcm_bytes_to_samples(stream_size,channel_count,16);
|
||||
vgmstream->loop_start_sample = pcm_bytes_to_samples(loop_start,channel_count,16);
|
||||
vgmstream->loop_end_sample = pcm_bytes_to_samples(loop_end,channel_count,16);
|
||||
|
||||
vgmstream->coding_type = coding_PCM16LE;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x02;
|
||||
|
||||
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -1,69 +1,69 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* XMD - from Konami Xbox games [Silent Hill 4 (Xbox), Castlevania Curse of Darkness (Xbox)] */
|
||||
VGMSTREAM * init_vgmstream_xmd(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count, sample_rate;
|
||||
size_t data_size, loop_start, frame_size;
|
||||
|
||||
|
||||
/* checks (.xmd comes from bigfiles with filenames) */
|
||||
if (!check_extensions(streamFile, "xmd"))
|
||||
goto fail;
|
||||
|
||||
if ((read_32bitBE(0x00,streamFile) & 0xFFFFFF00) == 0x786D6400) { /* "xmd\0" */
|
||||
/* v2 from Castlevania: Curse of Darkness */
|
||||
channel_count = read_8bit(0x03,streamFile);
|
||||
sample_rate = (uint16_t)read_16bitLE(0x04, streamFile);
|
||||
data_size = read_32bitLE(0x06, streamFile);
|
||||
loop_flag = read_8bit(0x0a,streamFile);
|
||||
loop_start = read_32bitLE(0x0b, streamFile);
|
||||
/* 0x0f(2): unknown+config? */
|
||||
frame_size = 0x15;
|
||||
start_offset = 0x11;
|
||||
}
|
||||
else {
|
||||
/* v1 from Silent Hill 4 */
|
||||
channel_count = read_8bit(0x00,streamFile);
|
||||
sample_rate = (uint16_t)read_16bitLE(0x01, streamFile);
|
||||
data_size = read_32bitLE(0x03, streamFile);
|
||||
loop_flag = read_8bit(0x07,streamFile);
|
||||
loop_start = read_32bitLE(0x08, streamFile);
|
||||
|
||||
frame_size = 0x0d;
|
||||
start_offset = 0x0c;
|
||||
}
|
||||
|
||||
/* extra checks just in case */
|
||||
if (data_size > get_streamfile_size(streamFile))
|
||||
goto fail; /* v1 .xmd are sector-aligned with padding */
|
||||
if (channel_count > 2)
|
||||
goto fail;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = data_size / frame_size / channel_count * ((frame_size-0x06)*2 + 2); /* bytes to samples */
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = loop_start / frame_size / channel_count * ((frame_size-0x06)*2 + 2); /* bytes to samples */
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
|
||||
vgmstream->meta_type = meta_XMD;
|
||||
vgmstream->coding_type = coding_XMD;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = frame_size;
|
||||
|
||||
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"
|
||||
|
||||
/* XMD - from Konami Xbox games [Silent Hill 4 (Xbox), Castlevania: Curse of Darkness (Xbox)] */
|
||||
VGMSTREAM* init_vgmstream_xmd(STREAMFILE *sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channels, sample_rate;
|
||||
size_t data_size, loop_start, frame_size;
|
||||
|
||||
|
||||
/* checks (.xmd comes from bigfiles with filenames) */
|
||||
if (!check_extensions(sf, "xmd"))
|
||||
return NULL;
|
||||
|
||||
if ((read_u32be(0x00,sf) & 0xFFFFFF00) == get_id32be("xmd\0")) {
|
||||
/* v2 from Castlevania: Curse of Darkness */
|
||||
channels = read_u8 (0x03,sf);
|
||||
sample_rate = read_u16le(0x04, sf);
|
||||
data_size = read_u32le(0x06, sf);
|
||||
loop_flag = read_u8 (0x0a,sf);
|
||||
loop_start = read_u32le(0x0b, sf);
|
||||
/* 0x0f(2): unknown+config? */
|
||||
|
||||
frame_size = 0x15;
|
||||
start_offset = 0x11;
|
||||
}
|
||||
else {
|
||||
// v1 from Silent Hill 4
|
||||
channels = read_u8 (0x00,sf);
|
||||
// 01: volume? always 0x80
|
||||
sample_rate = read_u16le(0x01, sf);
|
||||
data_size = read_u32le(0x03, sf);
|
||||
loop_flag = read_u8 (0x07,sf);
|
||||
loop_start = read_u32le(0x08, sf);
|
||||
|
||||
frame_size = 0x0d;
|
||||
start_offset = 0x0c;
|
||||
}
|
||||
|
||||
/* extra checks just in case */
|
||||
if (data_size > get_streamfile_size(sf))
|
||||
return NULL; // v1 .xmd are sector-aligned with padding
|
||||
if (channels < 1 || channels > 2)
|
||||
return NULL;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = data_size / frame_size / channels * ((frame_size - 0x06) * 2 + 2); // bytes to samples
|
||||
vgmstream->loop_start_sample = loop_start / frame_size / channels * ((frame_size - 0x06)*2 + 2); // bytes to samples
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
|
||||
vgmstream->meta_type = meta_XMD;
|
||||
vgmstream->coding_type = coding_XMD;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = frame_size;
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,223 +1,236 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
static void read_xps_name(VGMSTREAM *vgmstream, STREAMFILE *streamFile, int file_id);
|
||||
|
||||
/* .XPS+DAT - From Software games streams [Metal Wolf Chaos (Xbox), Otogi (Xbox)] */
|
||||
VGMSTREAM * init_vgmstream_xps_dat(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
STREAMFILE * streamData = NULL;
|
||||
off_t start_offset, header_offset;
|
||||
size_t stream_size;
|
||||
int loop_flag, channel_count, sample_rate, codec, loop_start_sample, loop_end_sample, file_id;
|
||||
int total_subsongs, target_subsong = streamFile->stream_index;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile, "xps"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitLE(0x00,streamFile) != get_streamfile_size(streamFile))
|
||||
goto fail;
|
||||
if (read_32bitBE(0x0c,streamFile) != 0x64696666) /* "diff" */
|
||||
goto fail;
|
||||
|
||||
/* handle .xps+dat (bank .xps are done below) */
|
||||
streamData = open_streamfile_by_ext(streamFile, "dat");
|
||||
if (!streamData) goto fail;
|
||||
|
||||
/* 0x00: approximate file size */
|
||||
|
||||
total_subsongs = read_32bitLE(0x04,streamData);
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
|
||||
|
||||
header_offset = 0x20 + 0x94*(target_subsong-1); /* could start at 0x0c too */
|
||||
|
||||
file_id = read_32bitLE(header_offset+0x00,streamData);
|
||||
start_offset = read_32bitLE(header_offset+0x04,streamData);
|
||||
stream_size = read_32bitLE(header_offset+0x08,streamData);
|
||||
/* 0x0c: loop start offset? */
|
||||
/* 0x10: loop end offset? */
|
||||
/* 0x14: always null? */
|
||||
codec = read_16bitLE(header_offset+0x18,streamData);
|
||||
channel_count = read_16bitLE(header_offset+0x1a,streamData);
|
||||
sample_rate = read_32bitLE(header_offset+0x1c,streamData);
|
||||
/* 0x20: average bitrate */
|
||||
/* 0x24: block size, bps */
|
||||
loop_flag = read_32bitLE(header_offset+0x5c,streamData);
|
||||
loop_start_sample = read_32bitLE(header_offset+0x6c,streamData);
|
||||
loop_end_sample = read_32bitLE(header_offset+0x70,streamData) + 1; /* a "smpl" chunk basically */
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->meta_type = meta_XPS_DAT;
|
||||
vgmstream->loop_start_sample = loop_start_sample;
|
||||
vgmstream->loop_end_sample = loop_end_sample;
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
vgmstream->stream_size = stream_size;
|
||||
|
||||
switch(codec) {
|
||||
case 0x01:
|
||||
vgmstream->coding_type = coding_PCM16LE;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x02;
|
||||
vgmstream->num_samples = pcm_bytes_to_samples(stream_size, channel_count, 16);
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(stream_size, channel_count);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
read_xps_name(vgmstream, streamFile, file_id);
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream,streamData,start_offset))
|
||||
goto fail;
|
||||
|
||||
close_streamfile(streamData);
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_streamfile(streamData);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void read_xps_name(VGMSTREAM *vgmstream, STREAMFILE *streamFile, int file_id) {
|
||||
int i, entries;
|
||||
int name_id = -1, udss_name_id;
|
||||
off_t entry_offset = 0x10;
|
||||
|
||||
|
||||
/* main section + stream sections (usually same number but not always) */
|
||||
entries = read_32bitLE(0x04,streamFile);
|
||||
|
||||
/* "sid\0" entries: find name_id of file_id */
|
||||
for (i = 0; i < entries; i++) {
|
||||
off_t entry_base = entry_offset;
|
||||
size_t entry_size = read_32bitLE(entry_base+0x00,streamFile);
|
||||
uint32_t entry_id = read_32bitBE(entry_base+0x04,streamFile);
|
||||
size_t entry_pad = read_32bitLE(entry_base+0x08,streamFile);
|
||||
/* 0x0c: always null, rest: entry (format varies) */
|
||||
|
||||
entry_offset += entry_size + entry_pad + 0x10;
|
||||
|
||||
/* sound info entry */
|
||||
if (entry_id == 0x73696400) { /* "sid\0" */
|
||||
int entry_file_id = read_32bitLE(entry_base+0x10,streamFile);
|
||||
int entry_name_id = read_32bitLE(entry_base+0x14,streamFile);
|
||||
if (entry_file_id == file_id && name_id == -1) {
|
||||
name_id = entry_name_id;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* sound stream entry, otherwise no good */
|
||||
if (entry_id != 0x75647373) { /* "udss" */
|
||||
goto fail;
|
||||
}
|
||||
|
||||
udss_name_id = read_32bitLE(entry_base+0x10,streamFile);
|
||||
if (udss_name_id == name_id) {
|
||||
off_t name_offset = entry_base + 0x10 + 0x08;
|
||||
size_t name_size = entry_size - 0x08; /* includes null */
|
||||
read_string(vgmstream->stream_name,name_size, name_offset,streamFile);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
return;
|
||||
}
|
||||
|
||||
/* .XPS - From Software games banks [Metal Wolf Chaos (Xbox), Otogi (Xbox)] */
|
||||
VGMSTREAM * init_vgmstream_xps(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
STREAMFILE * streamData = NULL;
|
||||
int i, entries;
|
||||
off_t entry_offset = 0x10;
|
||||
int total_subsongs, target_subsong = streamFile->stream_index;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile, "xps"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitLE(0x00,streamFile) != get_streamfile_size(streamFile))
|
||||
goto fail;
|
||||
if (read_32bitBE(0x0c,streamFile) != 0x64696666) /* "diff" */
|
||||
goto fail;
|
||||
|
||||
/* handle .xps alone (stream .xps+data are done above) */
|
||||
streamData = open_streamfile_by_ext(streamFile, "dat");
|
||||
if (streamData) goto fail;
|
||||
|
||||
/* main section + bank sections (usually same number but not always) */
|
||||
entries = read_32bitLE(0x04,streamFile);
|
||||
|
||||
total_subsongs = 0;
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
if (target_subsong < 0 /*|| target_subsong > total_subsongs || total_subsongs < 1*/) goto fail;
|
||||
|
||||
|
||||
/* parse entries: skip (there is probably a stream/bank flag here) */
|
||||
for (i = 0; i < entries; i++) {
|
||||
off_t entry_base = entry_offset;
|
||||
size_t entry_size = read_32bitLE(entry_base+0x00,streamFile);
|
||||
uint32_t entry_id = read_32bitBE(entry_base+0x04,streamFile);
|
||||
size_t entry_pad = read_32bitLE(entry_base+0x08,streamFile);
|
||||
/* 0x0c: always null, rest: entry (format varies) */
|
||||
|
||||
entry_offset += entry_size + entry_pad + 0x10;
|
||||
|
||||
/* sound info entry */
|
||||
if (entry_id == 0x73696400) { /* "sid\0" */
|
||||
/* keep looking for sound banks */
|
||||
continue;
|
||||
}
|
||||
|
||||
/* sound bank entry, otherwise no good */
|
||||
if (entry_id != 0x75647362) { /* "udsb" */
|
||||
goto fail;
|
||||
}
|
||||
|
||||
total_subsongs++;
|
||||
|
||||
/* open internal RIFF */
|
||||
if (target_subsong == total_subsongs && vgmstream == NULL) {
|
||||
STREAMFILE* temp_streamFile;
|
||||
off_t subsong_offset = entry_base+0x18;
|
||||
size_t subsong_size = read_32bitLE(entry_base+0x14,streamFile);
|
||||
|
||||
temp_streamFile = setup_subfile_streamfile(streamFile, subsong_offset,subsong_size, "wav");
|
||||
if (!temp_streamFile) goto fail;
|
||||
|
||||
vgmstream = init_vgmstream_riff(temp_streamFile);
|
||||
close_streamfile(temp_streamFile);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
/* subsong not found */
|
||||
if (!vgmstream)
|
||||
goto fail;
|
||||
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_streamfile(streamData);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
static void read_xps_name(VGMSTREAM *vgmstream, STREAMFILE *streamFile, int file_id);
|
||||
|
||||
/* .XPS+DAT - From Software games streams [Metal Wolf Chaos (Xbox), Otogi (Xbox)] */
|
||||
VGMSTREAM* init_vgmstream_xps_dat(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
STREAMFILE* sf_data = NULL;
|
||||
off_t start_offset, header_offset;
|
||||
size_t stream_size;
|
||||
int loop_flag, channels, sample_rate, codec, loop_start_sample, loop_end_sample, file_id;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (read_u32le(0x00,sf) != get_streamfile_size(sf))
|
||||
return NULL;
|
||||
if (!check_extensions(sf, "xps"))
|
||||
return NULL;
|
||||
|
||||
// 04: bank subsongs
|
||||
if (read_u32le(0x08,sf) != 0x02) // type 2=xps
|
||||
return NULL;
|
||||
if (!is_id32be(0x0c,sf, "diff"))
|
||||
return NULL;
|
||||
|
||||
// handle .xps+dat (bank .xps are done below)
|
||||
sf_data = open_streamfile_by_ext(sf, "dat");
|
||||
if (!sf_data) return NULL;
|
||||
|
||||
// 00: approximate file size
|
||||
// 04: subsongs
|
||||
// 08: type 1=dat
|
||||
|
||||
int target_subsong = sf->stream_index;
|
||||
int total_subsongs = read_s32le(0x04,sf_data);
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) return NULL;
|
||||
|
||||
header_offset = 0x20 + 0x94 * (target_subsong-1); // could start at 0x0c or 0x10 too
|
||||
|
||||
file_id = read_s32le(header_offset+0x00,sf_data);
|
||||
start_offset = read_u32le(header_offset+0x04,sf_data);
|
||||
stream_size = read_u32le(header_offset+0x08,sf_data);
|
||||
/* 0x0c: loop start offset? */
|
||||
/* 0x10: loop end offset? */
|
||||
/* 0x14: always null? */
|
||||
codec = read_u16le(header_offset+0x18,sf_data);
|
||||
channels = read_u16le(header_offset+0x1a,sf_data);
|
||||
sample_rate = read_s32le(header_offset+0x1c,sf_data);
|
||||
/* 0x20: average bitrate */
|
||||
/* 0x24: block size, bps */
|
||||
loop_flag = read_s32le(header_offset+0x5c,sf_data);
|
||||
loop_start_sample = read_s32le(header_offset+0x6c,sf_data);
|
||||
loop_end_sample = read_s32le(header_offset+0x70,sf_data) + 1; // a "smpl" chunk basically
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->meta_type = meta_XPS_DAT;
|
||||
vgmstream->loop_start_sample = loop_start_sample;
|
||||
vgmstream->loop_end_sample = loop_end_sample;
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
vgmstream->stream_size = stream_size;
|
||||
|
||||
switch(codec) {
|
||||
case 0x01:
|
||||
vgmstream->coding_type = coding_PCM16LE;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x02;
|
||||
vgmstream->num_samples = pcm_bytes_to_samples(stream_size, channels, 16);
|
||||
break;
|
||||
|
||||
case 0x69:
|
||||
vgmstream->coding_type = coding_XBOX_IMA;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->num_samples = xbox_ima_bytes_to_samples(stream_size, channels);
|
||||
break;
|
||||
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
read_xps_name(vgmstream, sf, file_id);
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream,sf_data,start_offset))
|
||||
goto fail;
|
||||
|
||||
close_streamfile(sf_data);
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_streamfile(sf_data);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static void read_xps_name(VGMSTREAM* vgmstream, STREAMFILE* sf, int file_id) {
|
||||
int name_id = -1;
|
||||
|
||||
/* main section + stream sections (usually same number but not always) */
|
||||
int entries = read_s32le(0x04,sf);
|
||||
|
||||
/* "sid\0" entries: find name_id of file_id */
|
||||
uint32_t entry_offset = 0x10;
|
||||
for (int i = 0; i < entries; i++) {
|
||||
uint32_t entry_base = entry_offset;
|
||||
uint32_t entry_size = read_u32le(entry_base+0x00,sf);
|
||||
uint32_t entry_id = read_u32be(entry_base+0x04,sf);
|
||||
uint32_t entry_pad = read_u32le(entry_base+0x08,sf);
|
||||
/* 0x0c: always null, rest: entry (format varies) */
|
||||
|
||||
entry_offset += entry_size + entry_pad + 0x10;
|
||||
|
||||
/* sound info entry */
|
||||
if (entry_id == get_id32be("sid\0")) {
|
||||
int entry_file_id = read_s32le(entry_base+0x10,sf);
|
||||
int entry_name_id = read_s32le(entry_base+0x14,sf);
|
||||
if (entry_file_id == file_id && name_id == -1) {
|
||||
name_id = entry_name_id;
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
/* sound stream entry, otherwise no good */
|
||||
if (entry_id != get_id32be("udss")) {
|
||||
return;
|
||||
}
|
||||
|
||||
int udss_name_id = read_s32le(entry_base+0x10,sf);
|
||||
if (udss_name_id == name_id) {
|
||||
off_t name_offset = entry_base + 0x10 + 0x08;
|
||||
size_t name_size = entry_size - 0x08; /* includes null */
|
||||
read_string(vgmstream->stream_name,name_size, name_offset,sf);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* .XPS - From Software games banks [Metal Wolf Chaos (Xbox), Otogi (Xbox)] */
|
||||
VGMSTREAM * init_vgmstream_xps(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
STREAMFILE* sf_data = NULL;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (read_u32le(0x00,sf) != get_streamfile_size(sf))
|
||||
return NULL;
|
||||
if (!check_extensions(sf, "xps"))
|
||||
return NULL;
|
||||
|
||||
// 04: bank subsongs
|
||||
if (read_u32le(0x08,sf) != 0x02) // 2=.xps, 1=.dat
|
||||
return NULL;
|
||||
if (!is_id32be(0x0c,sf, "diff"))
|
||||
return NULL;
|
||||
|
||||
/* handle .xps alone (stream .xps+data are done above) */
|
||||
sf_data = open_streamfile_by_ext(sf, "dat");
|
||||
if (sf_data) return NULL;
|
||||
|
||||
/* main section + bank sections (usually same number but not always) */
|
||||
int entries = read_s32le(0x04,sf);
|
||||
|
||||
int target_subsong = sf->stream_index;
|
||||
int total_subsongs = 0;
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
if (target_subsong < 0 /*|| target_subsong > total_subsongs || total_subsongs < 1*/)
|
||||
return NULL;
|
||||
|
||||
//TODO: should probably unify
|
||||
// - there is one "sid" per subsong with base config and one "udsb" per memory or external .dat stream
|
||||
// - each "sid" is linked to a udsb by internal+external ids
|
||||
// - however sids don't seem to be defined in the same order as streams
|
||||
// - streams in .dat also don't seem to follow the sid order
|
||||
|
||||
/* parse entries */
|
||||
uint32_t entry_offset = 0x10;
|
||||
for (int i = 0; i < entries; i++) {
|
||||
uint32_t entry_base = entry_offset;
|
||||
uint32_t entry_size = read_u32le(entry_base+0x00,sf);
|
||||
uint32_t entry_id = read_u32be(entry_base+0x04,sf);
|
||||
uint32_t entry_pad = read_u32le(entry_base+0x08,sf);
|
||||
// 0c: null or garbage from other entries
|
||||
// rest: entry (format varies)
|
||||
|
||||
entry_offset += entry_size + entry_pad + 0x10;
|
||||
|
||||
// sound info entry
|
||||
if (entry_id == get_id32be("sid\0")) {
|
||||
// 10: external id
|
||||
// 14: internal id
|
||||
// 30: external flag
|
||||
|
||||
/* keep looking for stream entries */
|
||||
continue;
|
||||
}
|
||||
|
||||
// stream entry
|
||||
if (entry_id != get_id32be("udsb")) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
|
||||
|
||||
total_subsongs++;
|
||||
|
||||
/* open internal RIFF */
|
||||
if (target_subsong == total_subsongs && vgmstream == NULL) {
|
||||
STREAMFILE* temp_sf;
|
||||
// 10: internal id
|
||||
uint32_t subsong_size = read_u32le(entry_base + 0x14,sf);
|
||||
uint32_t subsong_offset = entry_base + 0x18;
|
||||
|
||||
temp_sf = setup_subfile_streamfile(sf, subsong_offset, subsong_size, "wav");
|
||||
if (!temp_sf) goto fail;
|
||||
|
||||
vgmstream = init_vgmstream_riff(temp_sf);
|
||||
close_streamfile(temp_sf);
|
||||
if (!vgmstream) goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
/* subsong not found */
|
||||
if (!vgmstream)
|
||||
goto fail;
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
return vgmstream;
|
||||
fail:
|
||||
close_streamfile(sf_data);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -12,13 +12,12 @@ VGMSTREAM* init_vgmstream_xwav_new(STREAMFILE* sf) {
|
|||
|
||||
|
||||
/* checks */
|
||||
if (!is_id32le(0x00,sf, "XWAV"))
|
||||
goto fail;
|
||||
if (!is_id32be(0x00,sf, "VAWX")) //LE XWAV
|
||||
return NULL;
|
||||
|
||||
/* .xwv: actual extension [Moon Diver (PS3/X360)]
|
||||
* .vawx: header id */
|
||||
if (!check_extensions(sf, "xwv,vawx"))
|
||||
goto fail;
|
||||
// .xwv: actual extension [Moon Diver (PS3/X360)]
|
||||
if (!check_extensions(sf, "xwv"))
|
||||
return NULL;
|
||||
|
||||
/* similar to older version but BE and a bit less complex */
|
||||
/* 0x04: data size
|
||||
|
@ -143,9 +142,9 @@ VGMSTREAM* init_vgmstream_xwav_old(STREAMFILE* sf) {
|
|||
if (!is_id32be(0x00,sf, "XWAV"))
|
||||
goto fail;
|
||||
|
||||
/* .xwv: actual extension [Bullet Witch (X360), Lost Odyssey Demo (X360)] */
|
||||
// .xwv: actual extension [Bullet Witch (X360), Lost Odyssey Demo (X360)]
|
||||
if (!check_extensions(sf, "xwv"))
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
/* similar to newer version but LE and a bit more complex */
|
||||
/* 0x04: data size
|
||||
|
|
|
@ -1411,15 +1411,15 @@ static int tdefl_flush_block(tdefl_compressor *d, int flush)
|
|||
#ifdef MINIZ_UNALIGNED_USE_MEMCPY
|
||||
static mz_uint16 TDEFL_READ_UNALIGNED_WORD(const mz_uint8* p)
|
||||
{
|
||||
mz_uint16 ret;
|
||||
memcpy(&ret, p, sizeof(mz_uint16));
|
||||
return ret;
|
||||
mz_uint16 ret;
|
||||
memcpy(&ret, p, sizeof(mz_uint16));
|
||||
return ret;
|
||||
}
|
||||
static mz_uint16 TDEFL_READ_UNALIGNED_WORD2(const mz_uint16* p)
|
||||
{
|
||||
mz_uint16 ret;
|
||||
memcpy(&ret, p, sizeof(mz_uint16));
|
||||
return ret;
|
||||
mz_uint16 ret;
|
||||
memcpy(&ret, p, sizeof(mz_uint16));
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#define TDEFL_READ_UNALIGNED_WORD(p) *(const mz_uint16 *)(p)
|
||||
|
@ -1527,9 +1527,9 @@ static MZ_FORCEINLINE void tdefl_find_match(tdefl_compressor *d, mz_uint lookahe
|
|||
#ifdef MINIZ_UNALIGNED_USE_MEMCPY
|
||||
static mz_uint32 TDEFL_READ_UNALIGNED_WORD32(const mz_uint8* p)
|
||||
{
|
||||
mz_uint32 ret;
|
||||
memcpy(&ret, p, sizeof(mz_uint32));
|
||||
return ret;
|
||||
mz_uint32 ret;
|
||||
memcpy(&ret, p, sizeof(mz_uint32));
|
||||
return ret;
|
||||
}
|
||||
#else
|
||||
#define TDEFL_READ_UNALIGNED_WORD32(p) *(const mz_uint32 *)(p)
|
||||
|
@ -1604,7 +1604,7 @@ static mz_bool tdefl_compress_fast(tdefl_compressor *d)
|
|||
|
||||
pLZ_code_buf[0] = (mz_uint8)(cur_match_len - TDEFL_MIN_MATCH_LEN);
|
||||
#ifdef MINIZ_UNALIGNED_USE_MEMCPY
|
||||
memcpy(&pLZ_code_buf[1], &cur_match_dist, sizeof(cur_match_dist));
|
||||
memcpy(&pLZ_code_buf[1], &cur_match_dist, sizeof(cur_match_dist));
|
||||
#else
|
||||
*(mz_uint16 *)(&pLZ_code_buf[1]) = (mz_uint16)cur_match_dist;
|
||||
#endif
|
||||
|
@ -2801,7 +2801,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
|
|||
do
|
||||
{
|
||||
#ifdef MINIZ_UNALIGNED_USE_MEMCPY
|
||||
memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32)*2);
|
||||
memcpy(pOut_buf_cur, pSrc, sizeof(mz_uint32)*2);
|
||||
#else
|
||||
((mz_uint32 *)pOut_buf_cur)[0] = ((const mz_uint32 *)pSrc)[0];
|
||||
((mz_uint32 *)pOut_buf_cur)[1] = ((const mz_uint32 *)pSrc)[1];
|
||||
|
@ -2828,7 +2828,7 @@ tinfl_status tinfl_decompress(tinfl_decompressor *r, const mz_uint8 *pIn_buf_nex
|
|||
pOut_buf_cur[2] = pSrc[2];
|
||||
pOut_buf_cur += 3;
|
||||
pSrc += 3;
|
||||
counter -= 3;
|
||||
counter -= 3;
|
||||
}
|
||||
if (counter > 0)
|
||||
{
|
||||
|
@ -3802,47 +3802,47 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag
|
|||
|
||||
if (extra_size_remaining)
|
||||
{
|
||||
const mz_uint8 *pExtra_data;
|
||||
void* buf = NULL;
|
||||
const mz_uint8 *pExtra_data;
|
||||
void* buf = NULL;
|
||||
|
||||
if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size > n)
|
||||
{
|
||||
buf = MZ_MALLOC(ext_data_size);
|
||||
if(buf==NULL)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
|
||||
if (MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size + ext_data_size > n)
|
||||
{
|
||||
buf = MZ_MALLOC(ext_data_size);
|
||||
if(buf==NULL)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_ALLOC_FAILED);
|
||||
|
||||
if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size, buf, ext_data_size) != ext_data_size)
|
||||
{
|
||||
MZ_FREE(buf);
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
|
||||
}
|
||||
if (pZip->m_pRead(pZip->m_pIO_opaque, cdir_ofs + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size, buf, ext_data_size) != ext_data_size)
|
||||
{
|
||||
MZ_FREE(buf);
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_FILE_READ_FAILED);
|
||||
}
|
||||
|
||||
pExtra_data = (mz_uint8*)buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size;
|
||||
}
|
||||
pExtra_data = (mz_uint8*)buf;
|
||||
}
|
||||
else
|
||||
{
|
||||
pExtra_data = p + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + filename_size;
|
||||
}
|
||||
|
||||
do
|
||||
{
|
||||
mz_uint32 field_id;
|
||||
mz_uint32 field_data_size;
|
||||
|
||||
if (extra_size_remaining < (sizeof(mz_uint16) * 2))
|
||||
{
|
||||
MZ_FREE(buf);
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
|
||||
}
|
||||
if (extra_size_remaining < (sizeof(mz_uint16) * 2))
|
||||
{
|
||||
MZ_FREE(buf);
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
|
||||
}
|
||||
|
||||
field_id = MZ_READ_LE16(pExtra_data);
|
||||
field_data_size = MZ_READ_LE16(pExtra_data + sizeof(mz_uint16));
|
||||
|
||||
if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining)
|
||||
{
|
||||
MZ_FREE(buf);
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
|
||||
}
|
||||
if ((field_data_size + sizeof(mz_uint16) * 2) > extra_size_remaining)
|
||||
{
|
||||
MZ_FREE(buf);
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_INVALID_HEADER_OR_CORRUPTED);
|
||||
}
|
||||
|
||||
if (field_id == MZ_ZIP64_EXTENDED_INFORMATION_FIELD_HEADER_ID)
|
||||
{
|
||||
|
@ -3856,7 +3856,7 @@ static mz_bool mz_zip_reader_read_central_dir(mz_zip_archive *pZip, mz_uint flag
|
|||
extra_size_remaining = extra_size_remaining - sizeof(mz_uint16) * 2 - field_data_size;
|
||||
} while (extra_size_remaining);
|
||||
|
||||
MZ_FREE(buf);
|
||||
MZ_FREE(buf);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -4061,7 +4061,7 @@ mz_bool mz_zip_reader_init_file_v2(mz_zip_archive *pZip, const char *pFilename,
|
|||
|
||||
if (file_size < MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE)
|
||||
{
|
||||
MZ_FCLOSE(pFile);
|
||||
MZ_FCLOSE(pFile);
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_NOT_AN_ARCHIVE);
|
||||
}
|
||||
|
||||
|
@ -6273,16 +6273,16 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
|
|||
}
|
||||
#endif /* #ifndef MINIZ_NO_TIME */
|
||||
|
||||
if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
|
||||
{
|
||||
uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size);
|
||||
uncomp_size = buf_size;
|
||||
if (uncomp_size <= 3)
|
||||
{
|
||||
level = 0;
|
||||
store_data_uncompressed = MZ_TRUE;
|
||||
}
|
||||
}
|
||||
if (!(level_and_flags & MZ_ZIP_FLAG_COMPRESSED_DATA))
|
||||
{
|
||||
uncomp_crc32 = (mz_uint32)mz_crc32(MZ_CRC32_INIT, (const mz_uint8 *)pBuf, buf_size);
|
||||
uncomp_size = buf_size;
|
||||
if (uncomp_size <= 3)
|
||||
{
|
||||
level = 0;
|
||||
store_data_uncompressed = MZ_TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
archive_name_size = strlen(pArchive_name);
|
||||
if (archive_name_size > MZ_UINT16_MAX)
|
||||
|
@ -6298,9 +6298,9 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
|
|||
{
|
||||
/* Bail early if the archive would obviously become too large */
|
||||
if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size
|
||||
+ MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len +
|
||||
pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len
|
||||
+ MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF)
|
||||
+ MZ_ZIP_CENTRAL_DIR_HEADER_SIZE + archive_name_size + comment_size + user_extra_data_len +
|
||||
pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + user_extra_data_central_len
|
||||
+ MZ_ZIP_DATA_DESCRIPTER_SIZE32) > 0xFFFFFFFF)
|
||||
{
|
||||
pState->m_zip64 = MZ_TRUE;
|
||||
/*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
|
||||
|
@ -6399,13 +6399,13 @@ mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const char *pArchive_n
|
|||
cur_archive_file_ofs += archive_name_size;
|
||||
}
|
||||
|
||||
if (user_extra_data_len > 0)
|
||||
{
|
||||
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
|
||||
if (user_extra_data_len > 0)
|
||||
{
|
||||
if (pZip->m_pWrite(pZip->m_pIO_opaque, cur_archive_file_ofs, user_extra_data, user_extra_data_len) != user_extra_data_len)
|
||||
return mz_zip_set_error(pZip, MZ_ZIP_FILE_WRITE_FAILED);
|
||||
|
||||
cur_archive_file_ofs += user_extra_data_len;
|
||||
}
|
||||
cur_archive_file_ofs += user_extra_data_len;
|
||||
}
|
||||
|
||||
if (store_data_uncompressed)
|
||||
{
|
||||
|
@ -6559,8 +6559,8 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
|
|||
{
|
||||
/* Bail early if the archive would obviously become too large */
|
||||
if ((pZip->m_archive_size + num_alignment_padding_bytes + MZ_ZIP_LOCAL_DIR_HEADER_SIZE + archive_name_size + MZ_ZIP_CENTRAL_DIR_HEADER_SIZE
|
||||
+ archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024
|
||||
+ MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF)
|
||||
+ archive_name_size + comment_size + user_extra_data_len + pState->m_central_dir.m_size + MZ_ZIP_END_OF_CENTRAL_DIR_HEADER_SIZE + 1024
|
||||
+ MZ_ZIP_DATA_DESCRIPTER_SIZE32 + user_extra_data_central_len) > 0xFFFFFFFF)
|
||||
{
|
||||
pState->m_zip64 = MZ_TRUE;
|
||||
/*return mz_zip_set_error(pZip, MZ_ZIP_ARCHIVE_TOO_LARGE); */
|
||||
|
@ -6851,20 +6851,20 @@ mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pA
|
|||
|
||||
static size_t mz_file_read_func_stdio(void *pOpaque, mz_uint64 file_ofs, void *pBuf, size_t n)
|
||||
{
|
||||
MZ_FILE *pSrc_file = (MZ_FILE *)pOpaque;
|
||||
mz_int64 cur_ofs = MZ_FTELL64(pSrc_file);
|
||||
MZ_FILE *pSrc_file = (MZ_FILE *)pOpaque;
|
||||
mz_int64 cur_ofs = MZ_FTELL64(pSrc_file);
|
||||
|
||||
if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pSrc_file, (mz_int64)file_ofs, SEEK_SET))))
|
||||
return 0;
|
||||
if (((mz_int64)file_ofs < 0) || (((cur_ofs != (mz_int64)file_ofs)) && (MZ_FSEEK64(pSrc_file, (mz_int64)file_ofs, SEEK_SET))))
|
||||
return 0;
|
||||
|
||||
return MZ_FREAD(pBuf, 1, n, pSrc_file);
|
||||
return MZ_FREAD(pBuf, 1, n, pSrc_file);
|
||||
}
|
||||
|
||||
mz_bool mz_zip_writer_add_cfile(mz_zip_archive *pZip, const char *pArchive_name, MZ_FILE *pSrc_file, mz_uint64 max_size, const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags,
|
||||
const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len)
|
||||
const char *user_extra_data, mz_uint user_extra_data_len, const char *user_extra_data_central, mz_uint user_extra_data_central_len)
|
||||
{
|
||||
return mz_zip_writer_add_read_buf_callback(pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size, pFile_time, pComment, comment_size, level_and_flags,
|
||||
user_extra_data, user_extra_data_len, user_extra_data_central, user_extra_data_central_len);
|
||||
return mz_zip_writer_add_read_buf_callback(pZip, pArchive_name, mz_file_read_func_stdio, pSrc_file, max_size, pFile_time, pComment, comment_size, level_and_flags,
|
||||
user_extra_data, user_extra_data_len, user_extra_data_central, user_extra_data_central_len);
|
||||
}
|
||||
|
||||
mz_bool mz_zip_writer_add_file(mz_zip_archive *pZip, const char *pArchive_name, const char *pSrc_filename, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags)
|
||||
|
@ -7186,10 +7186,10 @@ mz_bool mz_zip_writer_add_from_zip_reader(mz_zip_archive *pZip, mz_zip_archive *
|
|||
{
|
||||
/* src is zip64, dest must be zip64 */
|
||||
|
||||
/* name uint32_t's */
|
||||
/* id 1 (optional in zip64?) */
|
||||
/* crc 1 */
|
||||
/* comp_size 2 */
|
||||
/* name uint32_t's */
|
||||
/* id 1 (optional in zip64?) */
|
||||
/* crc 1 */
|
||||
/* comp_size 2 */
|
||||
/* uncomp_size 2 */
|
||||
if (pSource_zip->m_pRead(pSource_zip->m_pIO_opaque, cur_src_file_ofs, pBuf, (sizeof(mz_uint32) * 6)) != (sizeof(mz_uint32) * 6))
|
||||
{
|
||||
|
@ -7725,7 +7725,7 @@ const char *mz_zip_get_error_string(mz_zip_error mz_err)
|
|||
return "validation failed";
|
||||
case MZ_ZIP_WRITE_CALLBACK_FAILED:
|
||||
return "write callback failed";
|
||||
case MZ_ZIP_TOTAL_ERRORS:
|
||||
case MZ_ZIP_TOTAL_ERRORS:
|
||||
return "total errors";
|
||||
default:
|
||||
break;
|
||||
|
|
|
@ -1294,13 +1294,13 @@ MINIZ_EXPORT mz_bool mz_zip_reader_extract_file_to_cfile(mz_zip_archive *pZip, c
|
|||
|
||||
#if 0
|
||||
/* TODO */
|
||||
typedef void *mz_zip_streaming_extract_state_ptr;
|
||||
mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
|
||||
mz_uint64 mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
||||
mz_uint64 mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
||||
mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, mz_uint64 new_ofs);
|
||||
size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size);
|
||||
mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
||||
typedef void *mz_zip_streaming_extract_state_ptr;
|
||||
mz_zip_streaming_extract_state_ptr mz_zip_streaming_extract_begin(mz_zip_archive *pZip, mz_uint file_index, mz_uint flags);
|
||||
mz_uint64 mz_zip_streaming_extract_get_size(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
||||
mz_uint64 mz_zip_streaming_extract_get_cur_ofs(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
||||
mz_bool mz_zip_streaming_extract_seek(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, mz_uint64 new_ofs);
|
||||
size_t mz_zip_streaming_extract_read(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState, void *pBuf, size_t buf_size);
|
||||
mz_bool mz_zip_streaming_extract_end(mz_zip_archive *pZip, mz_zip_streaming_extract_state_ptr pState);
|
||||
#endif
|
||||
|
||||
/* This function compares the archive's local headers, the optional local zip64 extended information block, and the optional descriptor following the compressed data vs. the data in the central directory. */
|
||||
|
@ -1364,8 +1364,8 @@ MINIZ_EXPORT mz_bool mz_zip_writer_add_mem_ex_v2(mz_zip_archive *pZip, const cha
|
|||
/* Adds the contents of a file to an archive. This function also records the disk file's modified time into the archive. */
|
||||
/* File data is supplied via a read callback function. User mz_zip_writer_add_(c)file to add a file directly.*/
|
||||
MINIZ_EXPORT mz_bool mz_zip_writer_add_read_buf_callback(mz_zip_archive *pZip, const char *pArchive_name, mz_file_read_func read_callback, void* callback_opaque, mz_uint64 max_size,
|
||||
const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
|
||||
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
|
||||
const MZ_TIME_T *pFile_time, const void *pComment, mz_uint16 comment_size, mz_uint level_and_flags, const char *user_extra_data_local, mz_uint user_extra_data_local_len,
|
||||
const char *user_extra_data_central, mz_uint user_extra_data_central_len);
|
||||
|
||||
|
||||
#ifndef MINIZ_NO_STDIO
|
||||
|
|
|
@ -1,20 +1,20 @@
|
|||
#include "vorbis_codebooks.h"
|
||||
|
||||
|
||||
int vcb_load_codebook_array(uint8_t* buf, int buf_size, uint32_t setup_id, const vcb_info_t* list, int list_length) {
|
||||
|
||||
for (int i = 0; i < list_length; i++) {
|
||||
|
||||
if (list[i].id != setup_id)
|
||||
continue;
|
||||
|
||||
if (list[i].size > buf_size) // can't handle
|
||||
return 0;
|
||||
|
||||
// found: copy data as-is
|
||||
memcpy(buf, list[i].codebooks, list[i].size);
|
||||
return list[i].size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
#include "vorbis_codebooks.h"
|
||||
|
||||
|
||||
int vcb_load_codebook_array(uint8_t* buf, int buf_size, uint32_t setup_id, const vcb_info_t* list, int list_length) {
|
||||
|
||||
for (int i = 0; i < list_length; i++) {
|
||||
|
||||
if (list[i].id != setup_id)
|
||||
continue;
|
||||
|
||||
if (list[i].size > buf_size) // can't handle
|
||||
return 0;
|
||||
|
||||
// found: copy data as-is
|
||||
memcpy(buf, list[i].codebooks, list[i].size);
|
||||
return list[i].size;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -92,7 +92,6 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
|||
init_vgmstream_xmu,
|
||||
init_vgmstream_sat_sap,
|
||||
init_vgmstream_dc_idvi,
|
||||
init_vgmstream_ps2_rnd,
|
||||
init_vgmstream_idsp_tt,
|
||||
init_vgmstream_kraw,
|
||||
init_vgmstream_omu,
|
||||
|
@ -130,11 +129,10 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
|||
init_vgmstream_sts,
|
||||
init_vgmstream_p2bt_move_visa,
|
||||
init_vgmstream_gbts,
|
||||
init_vgmstream_wii_sng,
|
||||
init_vgmstream_ngc_dsp_iadp,
|
||||
init_vgmstream_aax,
|
||||
init_vgmstream_utf_dsp,
|
||||
init_vgmstream_ngc_ffcc_str,
|
||||
init_vgmstream_str_sqex,
|
||||
init_vgmstream_sat_baka,
|
||||
init_vgmstream_swav,
|
||||
init_vgmstream_vsf,
|
||||
|
@ -148,13 +146,12 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
|||
init_vgmstream_dsp_ndp,
|
||||
init_vgmstream_ps2_sps,
|
||||
init_vgmstream_nds_hwas,
|
||||
init_vgmstream_ngc_lps,
|
||||
init_vgmstream_lps,
|
||||
init_vgmstream_ps2_snd,
|
||||
init_vgmstream_naomi_adpcm,
|
||||
init_vgmstream_sd9,
|
||||
init_vgmstream_2dx9,
|
||||
init_vgmstream_dsp_kceje,
|
||||
init_vgmstream_ps2_vgv,
|
||||
init_vgmstream_gcub,
|
||||
init_vgmstream_maxis_xa,
|
||||
init_vgmstream_ngc_sck_dsp,
|
||||
|
@ -195,14 +192,13 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
|||
init_vgmstream_xvag,
|
||||
init_vgmstream_cps,
|
||||
init_vgmstream_sqex_scd,
|
||||
init_vgmstream_ngc_nst_dsp,
|
||||
init_vgmstream_nst_monster,
|
||||
init_vgmstream_baf,
|
||||
init_vgmstream_msf,
|
||||
init_vgmstream_sndp,
|
||||
init_vgmstream_sgxd,
|
||||
init_vgmstream_ras,
|
||||
init_vgmstream_spm,
|
||||
init_vgmstream_ps2_iab,
|
||||
init_vgmstream_vs_str,
|
||||
init_vgmstream_lsf_n1nj4n,
|
||||
init_vgmstream_xwav_new,
|
||||
|
@ -211,13 +207,11 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
|||
init_vgmstream_psnd,
|
||||
init_vgmstream_adp_wildfire,
|
||||
init_vgmstream_adp_qd,
|
||||
init_vgmstream_eb_sfx,
|
||||
init_vgmstream_eb_sf0,
|
||||
init_vgmstream_mtaf,
|
||||
init_vgmstream_alp,
|
||||
init_vgmstream_wpd,
|
||||
init_vgmstream_mn_str,
|
||||
init_vgmstream_mss,
|
||||
init_vgmstream_mcss,
|
||||
init_vgmstream_ps2_hsf,
|
||||
init_vgmstream_ivag,
|
||||
init_vgmstream_2pfs,
|
||||
|
@ -230,7 +224,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
|||
init_vgmstream_kt_g1l,
|
||||
init_vgmstream_kt_wiibgm,
|
||||
init_vgmstream_bfstm,
|
||||
init_vgmstream_mca,
|
||||
init_vgmstream_madp,
|
||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||
init_vgmstream_mp4_aac,
|
||||
#endif
|
||||
|
@ -281,7 +275,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
|||
init_vgmstream_opus_shinen,
|
||||
init_vgmstream_opus_nus3,
|
||||
init_vgmstream_opus_sps_n1,
|
||||
init_vgmstream_pc_ast,
|
||||
init_vgmstream_astl,
|
||||
init_vgmstream_naac,
|
||||
init_vgmstream_ubi_sb,
|
||||
init_vgmstream_ubi_sm,
|
||||
|
@ -290,7 +284,6 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
|||
init_vgmstream_ubi_dat,
|
||||
init_vgmstream_ubi_blk,
|
||||
init_vgmstream_ubi_apm,
|
||||
init_vgmstream_ezw,
|
||||
init_vgmstream_vxn,
|
||||
init_vgmstream_ea_snr_sns,
|
||||
init_vgmstream_ea_sps,
|
||||
|
@ -352,12 +345,11 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
|||
init_vgmstream_msv,
|
||||
init_vgmstream_sdf,
|
||||
init_vgmstream_svgp,
|
||||
init_vgmstream_vai,
|
||||
init_vgmstream_aif_asobo,
|
||||
init_vgmstream_ao,
|
||||
init_vgmstream_apc,
|
||||
init_vgmstream_wav2,
|
||||
init_vgmstream_xau_konami,
|
||||
init_vgmstream_sfxb,
|
||||
init_vgmstream_derf,
|
||||
init_vgmstream_utk,
|
||||
init_vgmstream_nxa1,
|
||||
|
@ -498,7 +490,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
|||
init_vgmstream_nxof,
|
||||
init_vgmstream_gwb_gwd,
|
||||
init_vgmstream_s_pack,
|
||||
init_vgmstream_cbx,
|
||||
init_vgmstream_chatterbox,
|
||||
init_vgmstream_vas_rockstar,
|
||||
init_vgmstream_ea_sbk,
|
||||
init_vgmstream_dsp_asura,
|
||||
|
@ -519,7 +511,6 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
|||
init_vgmstream_undefind,
|
||||
init_vgmstream_oor,
|
||||
init_vgmstream_mio,
|
||||
init_vgmstream_2dx,
|
||||
|
||||
/* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */
|
||||
init_vgmstream_agsc,
|
||||
|
@ -537,6 +528,16 @@ init_vgmstream_t init_vgmstream_functions[] = {
|
|||
init_vgmstream_vs_mh,
|
||||
init_vgmstream_adpcm_capcom,
|
||||
init_vgmstream_ima,
|
||||
init_vgmstream_vgv,
|
||||
init_vgmstream_iab,
|
||||
init_vgmstream_2dx,
|
||||
init_vgmstream_ssp,
|
||||
init_vgmstream_sfx0_monster,
|
||||
init_vgmstream_sfx0_monster_old,
|
||||
init_vgmstream_song_monster,
|
||||
init_vgmstream_vai,
|
||||
init_vgmstream_ezw,
|
||||
init_vgmstream_vgs_old,
|
||||
/* need companion files */
|
||||
init_vgmstream_pos,
|
||||
init_vgmstream_sli_loops,
|
||||
|
|
|
@ -211,10 +211,10 @@ typedef enum {
|
|||
layout_blocked_str_snds,
|
||||
layout_blocked_ws_aud,
|
||||
layout_blocked_dec,
|
||||
layout_blocked_xvas,
|
||||
layout_blocked_vas_kceo,
|
||||
layout_blocked_vs_mh,
|
||||
layout_blocked_mul,
|
||||
layout_blocked_gsb,
|
||||
layout_blocked_gsnd,
|
||||
layout_blocked_thp,
|
||||
layout_blocked_filp,
|
||||
layout_blocked_ea_swvr,
|
||||
|
@ -302,7 +302,7 @@ typedef enum {
|
|||
meta_HIS, /* Her Ineractive .his */
|
||||
meta_BNSF, /* Bandai Namco Sound Format */
|
||||
|
||||
meta_XA, /* CD-ROM XA */
|
||||
meta_XA,
|
||||
meta_ADS,
|
||||
meta_NPS,
|
||||
meta_RXWS,
|
||||
|
@ -367,7 +367,7 @@ typedef enum {
|
|||
meta_ISH_ISD, /* Various (ISH+ISD DSP) */
|
||||
meta_GSND,
|
||||
meta_YDSP, /* WWE Day of Reckoning */
|
||||
meta_FFCC_STR, /* Final Fantasy: Crystal Chronicles */
|
||||
meta_STR_SQEX,
|
||||
meta_UBI_JADE, /* Beyond Good & Evil, Rayman Raving Rabbids */
|
||||
meta_GCA, /* Metal Slug Anthology */
|
||||
meta_SSM,
|
||||
|
@ -441,11 +441,11 @@ typedef enum {
|
|||
meta_REDSPARK, /* "RedSpark" RSD (MadWorld) */
|
||||
meta_RAGE_AUD, /* Rockstar AUD - MC:LA, GTA IV */
|
||||
meta_NDS_HWAS, /* Spider-Man 3, Tony Hawk's Downhill Jam, possibly more... */
|
||||
meta_NGC_LPS, /* Rave Master (Groove Adventure Rave)(GC) */
|
||||
meta_LPS,
|
||||
meta_NAOMI_ADPCM, /* NAOMI/NAOMI2 Arcade games */
|
||||
meta_SD9, /* Konami/Bemani Arcade Games */
|
||||
meta_2DX9, /* beatmania IIDX Arcade Games */
|
||||
meta_PS2_VGV, /* Rune: Viking Warlord */
|
||||
meta_SD9,
|
||||
meta_2DX9,
|
||||
meta_VGV,
|
||||
meta_GCUB,
|
||||
meta_MAXIS_XA, /* Sim City 3000 (PC) */
|
||||
meta_NGC_SCK_DSP, /* Scorpion King (NGC) */
|
||||
|
@ -481,18 +481,18 @@ typedef enum {
|
|||
meta_GH3_BAR, /* Guitar Hero III Mobile .bar */
|
||||
meta_DSP_DSPW, /* Sengoku Basara 3 [WII] */
|
||||
meta_PS2_JSTM, /* Tantei Jinguji Saburo - Kind of Blue (PS2) */
|
||||
meta_SQEX_SCD, /* Square-Enix SCD */
|
||||
meta_NGC_NST_DSP, /* Animaniacs [NGC] */
|
||||
meta_BAF, /* Bizarre Creations (Blur, James Bond) */
|
||||
meta_XVAG, /* Ratchet & Clank Future: Quest for Booty (PS3) */
|
||||
meta_SQEX_SCD,
|
||||
meta_NST_MONSTER,
|
||||
meta_BAF,
|
||||
meta_XVAG,
|
||||
meta_CPS,
|
||||
meta_MSF,
|
||||
meta_SNDP,
|
||||
meta_SGXD, /* Sony: Folklore, Genji, Tokyo Jungle (PS3), Brave Story, Kurohyo (PSP) */
|
||||
meta_SGXD,
|
||||
meta_RAS,
|
||||
meta_SPM,
|
||||
meta_VGS_PS,
|
||||
meta_PS2_IAB, /* Ueki no Housoku - Taosu ze Robert Juudan!! (PS2) */
|
||||
meta_IAB,
|
||||
meta_VS_STR, /* The Bouncer */
|
||||
meta_LSF_N1NJ4N, /* .lsf n1nj4n Fastlane Street Racing (iPhone) */
|
||||
meta_XWAV,
|
||||
|
@ -501,13 +501,13 @@ typedef enum {
|
|||
meta_PSND,
|
||||
meta_ADP_WILDFIRE,
|
||||
meta_QD_ADP,
|
||||
meta_EB_SFX, /* Excitebots .sfx */
|
||||
meta_EB_SF0, /* Excitebots .sf0 */
|
||||
meta_SFX0_MONSTER,
|
||||
meta_SONG_MONSTER,
|
||||
meta_MTAF,
|
||||
meta_ALP,
|
||||
meta_WPD,
|
||||
meta_MN_STR, /* Mini Ninjas (PC/PS3/WII) */
|
||||
meta_MSS, /* Guerilla: ShellShock Nam '67 (PS2/Xbox), Killzone (PS2) */
|
||||
meta_MCSS,
|
||||
meta_PS2_HSF, /* Lowrider (PS2) */
|
||||
meta_IVAG,
|
||||
meta_2PFS,
|
||||
|
@ -518,7 +518,7 @@ typedef enum {
|
|||
meta_IDSP_NAMCO,
|
||||
meta_KT_WIIBGM, /* Koei Tecmo WiiBGM */
|
||||
meta_KTSS, /* Koei Tecmo Nintendo Stream (KNS) */
|
||||
meta_MCA, /* Capcom MCA "MADP" */
|
||||
meta_MADP,
|
||||
meta_ADX_MONSTER,
|
||||
meta_HCA,
|
||||
meta_SVAG_SNK,
|
||||
|
@ -533,7 +533,7 @@ typedef enum {
|
|||
meta_WWISE_RIFF, /* Audiokinetic Wwise RIFF/RIFX */
|
||||
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_OGL,
|
||||
meta_MPC3,
|
||||
meta_GHS,
|
||||
meta_AAC_TRIACE,
|
||||
|
@ -548,11 +548,11 @@ typedef enum {
|
|||
meta_EA_SNU, /* Electronic Arts SNU (Dead Space) */
|
||||
meta_AWC, /* Rockstar AWC (GTA5, RDR) */
|
||||
meta_OPUS, /* Nintendo Opus [Lego City Undercover (Switch)] */
|
||||
meta_PC_AST, /* Dead Rising (PC) */
|
||||
meta_NAAC, /* Namco AAC (3DS) */
|
||||
meta_UBI_SB, /* Ubisoft banks */
|
||||
meta_UBI_APM, /* Ubisoft APM */
|
||||
meta_EZW, /* EZ2DJ (Arcade) EZWAV */
|
||||
meta_ASTL,
|
||||
meta_NAAC,
|
||||
meta_UBI_SB,
|
||||
meta_UBI_APM,
|
||||
meta_EZW,
|
||||
meta_VXN, /* Gameloft mobile games */
|
||||
meta_EA_SNR_SNS, /* Electronic Arts SNR+SNS (Burnout Paradise) */
|
||||
meta_EA_SPS, /* Electronic Arts SPS (Burnout Crash) */
|
||||
|
@ -610,7 +610,7 @@ typedef enum {
|
|||
meta_AO, /* Cloudphobia (PC) */
|
||||
meta_APC, /* MegaRace 3 (PC) */
|
||||
meta_WAV2,
|
||||
meta_XAU_KONAMI, /* Yu-Gi-Oh - The Dawn of Destiny (Xbox) */
|
||||
meta_SFXB,
|
||||
meta_DERF, /* Stupid Invaders (PC) */
|
||||
meta_SADF,
|
||||
meta_UTK,
|
||||
|
@ -618,7 +618,7 @@ typedef enum {
|
|||
meta_ADPCM_CAPCOM,
|
||||
meta_UE4OPUS,
|
||||
meta_XWMA,
|
||||
meta_VA3, /* DDR Supernova 2 AC */
|
||||
meta_VA3,
|
||||
meta_XOPUS,
|
||||
meta_VS_SQUARE,
|
||||
meta_NWAV,
|
||||
|
|
Loading…
Reference in a new issue