VGMStream: Updated libvgmstream code base
Updated VGMStream to r1980-181-g10093db5 Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
parent
c8ce0f3f81
commit
c6bca5aa39
102 changed files with 11949 additions and 4489 deletions
|
@ -139,7 +139,7 @@
|
|||
832BF81C21E0514B006F50F1 /* xpcm.c in Sources */ = {isa = PBXBuildFile; fileRef = 832BF80A21E05148006F50F1 /* xpcm.c */; };
|
||||
832BF81D21E0514B006F50F1 /* msf_tamasoft.c in Sources */ = {isa = PBXBuildFile; fileRef = 832BF80B21E05148006F50F1 /* msf_tamasoft.c */; };
|
||||
832BF81E21E0514B006F50F1 /* xps.c in Sources */ = {isa = PBXBuildFile; fileRef = 832BF80C21E05148006F50F1 /* xps.c */; };
|
||||
832BF81F21E0514B006F50F1 /* ps2_va3.c in Sources */ = {isa = PBXBuildFile; fileRef = 832BF80D21E05148006F50F1 /* ps2_va3.c */; };
|
||||
832BF81F21E0514B006F50F1 /* va3.c in Sources */ = {isa = PBXBuildFile; fileRef = 832BF80D21E05148006F50F1 /* va3.c */; };
|
||||
832BF82021E0514B006F50F1 /* zsnd_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 832BF80E21E05149006F50F1 /* zsnd_streamfile.h */; };
|
||||
832BF82121E0514B006F50F1 /* zsnd.c in Sources */ = {isa = PBXBuildFile; fileRef = 832BF80F21E05149006F50F1 /* zsnd.c */; };
|
||||
832BF82221E0514B006F50F1 /* vs_str.c in Sources */ = {isa = PBXBuildFile; fileRef = 832BF81021E05149006F50F1 /* vs_str.c */; };
|
||||
|
@ -251,7 +251,6 @@
|
|||
834F7DB02C7093EA003AC386 /* circus_vq_lib.h in Headers */ = {isa = PBXBuildFile; fileRef = 834F7D422C7093EA003AC386 /* circus_vq_lib.h */; };
|
||||
834F7DB12C7093EA003AC386 /* circus_vq_lzxpcm.h in Headers */ = {isa = PBXBuildFile; fileRef = 834F7D432C7093EA003AC386 /* circus_vq_lzxpcm.h */; };
|
||||
834F7DB22C7093EA003AC386 /* circus_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D442C7093EA003AC386 /* circus_decoder.c */; };
|
||||
834F7DB32C7093EA003AC386 /* coding_utils_samples.h in Headers */ = {isa = PBXBuildFile; fileRef = 834F7D452C7093EA003AC386 /* coding_utils_samples.h */; };
|
||||
834F7DB42C7093EA003AC386 /* coding_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D462C7093EA003AC386 /* coding_utils.c */; };
|
||||
834F7DB52C7093EA003AC386 /* coding.h in Headers */ = {isa = PBXBuildFile; fileRef = 834F7D472C7093EA003AC386 /* coding.h */; };
|
||||
834F7DB62C7093EA003AC386 /* compresswave_lib.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D482C7093EA003AC386 /* compresswave_lib.c */; };
|
||||
|
@ -326,8 +325,6 @@
|
|||
834F7DFD2C7093EA003AC386 /* tgcadpcm_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D8F2C7093EA003AC386 /* tgcadpcm_decoder.c */; };
|
||||
834F7DFE2C7093EA003AC386 /* ubi_adpcm_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D902C7093EA003AC386 /* ubi_adpcm_decoder.c */; };
|
||||
834F7DFF2C7093EA003AC386 /* vadpcm_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D912C7093EA003AC386 /* vadpcm_decoder.c */; };
|
||||
834F7E002C7093EA003AC386 /* vorbis_custom_data_fsb.h in Headers */ = {isa = PBXBuildFile; fileRef = 834F7D922C7093EA003AC386 /* vorbis_custom_data_fsb.h */; };
|
||||
834F7E012C7093EA003AC386 /* vorbis_custom_data_wwise.h in Headers */ = {isa = PBXBuildFile; fileRef = 834F7D932C7093EA003AC386 /* vorbis_custom_data_wwise.h */; };
|
||||
834F7E022C7093EA003AC386 /* vorbis_custom_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D942C7093EA003AC386 /* vorbis_custom_decoder.c */; };
|
||||
834F7E032C7093EA003AC386 /* vorbis_custom_decoder.h in Headers */ = {isa = PBXBuildFile; fileRef = 834F7D952C7093EA003AC386 /* vorbis_custom_decoder.h */; };
|
||||
834F7E042C7093EA003AC386 /* vorbis_custom_utils_awc.c in Sources */ = {isa = PBXBuildFile; fileRef = 834F7D962C7093EA003AC386 /* vorbis_custom_utils_awc.c */; };
|
||||
|
@ -443,8 +440,8 @@
|
|||
834FE10F215C79ED000A5D3D /* sdf.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0E6215C79EC000A5D3D /* sdf.c */; };
|
||||
834FE110215C79ED000A5D3D /* msv.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0E7215C79EC000A5D3D /* msv.c */; };
|
||||
834FE111215C79ED000A5D3D /* ck.c in Sources */ = {isa = PBXBuildFile; fileRef = 834FE0E8215C79EC000A5D3D /* ck.c */; };
|
||||
835096F22C9979DD00163D93 /* libvgmstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 835096F02C9979DD00163D93 /* libvgmstream.h */; };
|
||||
835096F32C9979DD00163D93 /* libvgmstream_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 835096F12C9979DD00163D93 /* libvgmstream_streamfile.h */; };
|
||||
835096F22C9979DD00163D93 /* libvgmstream.h in Headers */ = {isa = PBXBuildFile; fileRef = 835096F02C9979DD00163D93 /* libvgmstream.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
835096F32C9979DD00163D93 /* libvgmstream_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 835096F12C9979DD00163D93 /* libvgmstream_streamfile.h */; settings = {ATTRIBUTES = (Public, ); }; };
|
||||
8350C0551E071881009E0A93 /* xma.c in Sources */ = {isa = PBXBuildFile; fileRef = 8350C0541E071881009E0A93 /* xma.c */; };
|
||||
8351F32D2212B57000A606E4 /* 208.c in Sources */ = {isa = PBXBuildFile; fileRef = 8351F32A2212B57000A606E4 /* 208.c */; };
|
||||
8351F32E2212B57000A606E4 /* ubi_bao_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 8351F32B2212B57000A606E4 /* ubi_bao_streamfile.h */; };
|
||||
|
@ -557,14 +554,13 @@
|
|||
836F6FD518BDC2190095E648 /* lp_ap_lep.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9918BDC2180095E648 /* lp_ap_lep.c */; };
|
||||
836F6FD718BDC2190095E648 /* filp.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9B18BDC2180095E648 /* filp.c */; };
|
||||
836F6FD818BDC2190095E648 /* gbts.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9C18BDC2180095E648 /* gbts.c */; };
|
||||
836F6FD918BDC2190095E648 /* ps2_gcm.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E9D18BDC2180095E648 /* ps2_gcm.c */; };
|
||||
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 */; };
|
||||
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 */; };
|
||||
836F6FE618BDC2190095E648 /* ps2_mcg.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EAA18BDC2180095E648 /* ps2_mcg.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 */; };
|
||||
|
@ -584,7 +580,6 @@
|
|||
836F700918BDC2190095E648 /* voi.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ECD18BDC2190095E648 /* voi.c */; };
|
||||
836F700B18BDC2190095E648 /* ps2_wad.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ECF18BDC2190095E648 /* ps2_wad.c */; };
|
||||
836F700C18BDC2190095E648 /* wb.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ED018BDC2190095E648 /* wb.c */; };
|
||||
836F700D18BDC2190095E648 /* ps2_wmus.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ED118BDC2190095E648 /* ps2_wmus.c */; };
|
||||
836F701518BDC2190095E648 /* sndp.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6ED918BDC2190095E648 /* sndp.c */; };
|
||||
836F701E18BDC2190095E648 /* redspark.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EE218BDC2190095E648 /* redspark.c */; };
|
||||
836F701F18BDC2190095E648 /* riff.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6EE318BDC2190095E648 /* riff.c */; };
|
||||
|
@ -744,6 +739,37 @@
|
|||
83B46FD52707FB9A00847FC9 /* endianness.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B46FD42707FB9A00847FC9 /* endianness.h */; };
|
||||
83B69B222845A26600D2435A /* bw_mp3_riff.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B69B212845A26600D2435A /* bw_mp3_riff.c */; };
|
||||
83B72E3A27904589006007A3 /* libfdk-aac.2.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 83B72E342790452C006007A3 /* libfdk-aac.2.dylib */; };
|
||||
83B73C232D8FEC3A00A57F08 /* vorbis_codebooks_oor.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C222D8FEC3A00A57F08 /* vorbis_codebooks_oor.h */; };
|
||||
83B73C242D8FEC3A00A57F08 /* oor_helpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C202D8FEC3A00A57F08 /* oor_helpers.h */; };
|
||||
83B73C252D8FEC3A00A57F08 /* oor_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C212D8FEC3A00A57F08 /* oor_helpers.c */; };
|
||||
83B73C272D8FEC5500A57F08 /* vorbis_custom_utils_oor.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C262D8FEC5500A57F08 /* vorbis_custom_utils_oor.c */; };
|
||||
83B73C292D8FEC7B00A57F08 /* oor.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C282D8FEC7B00A57F08 /* oor.c */; };
|
||||
83B73C2C2D8FED0500A57F08 /* vorbis_codebooks_wwise.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C2B2D8FED0500A57F08 /* vorbis_codebooks_wwise.h */; };
|
||||
83B73C2D2D8FED0500A57F08 /* vorbis_codebooks_fsb.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C2A2D8FED0500A57F08 /* vorbis_codebooks_fsb.h */; };
|
||||
83B73C312D8FEF7A00A57F08 /* ubi_mpeg_helpers.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C2F2D8FEF7A00A57F08 /* ubi_mpeg_helpers.h */; };
|
||||
83B73C322D8FEF7A00A57F08 /* minimp3.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C2E2D8FEF7A00A57F08 /* minimp3.h */; };
|
||||
83B73C332D8FEF7A00A57F08 /* ubi_mpeg_helpers.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C302D8FEF7A00A57F08 /* ubi_mpeg_helpers.c */; };
|
||||
83B73C352D8FEFFD00A57F08 /* ubi_mpeg_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C342D8FEFFD00A57F08 /* ubi_mpeg_decoder.c */; };
|
||||
83B73C3F2D8FF15700A57F08 /* mio_xerisa.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C3E2D8FF15700A57F08 /* mio_xerisa.h */; };
|
||||
83B73C402D8FF15700A57F08 /* mio_erisasound.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C3C2D8FF15700A57F08 /* mio_erisasound.h */; };
|
||||
83B73C412D8FF15700A57F08 /* mio_erisacontext.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C362D8FF15700A57F08 /* mio_erisacontext.h */; };
|
||||
83B73C422D8FF15700A57F08 /* mio_erisafile.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C382D8FF15700A57F08 /* mio_erisafile.h */; };
|
||||
83B73C432D8FF15700A57F08 /* mio_erisamatrix.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C3A2D8FF15700A57F08 /* mio_erisamatrix.h */; };
|
||||
83B73C442D8FF15700A57F08 /* mio_erisacontext.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C372D8FF15700A57F08 /* mio_erisacontext.c */; };
|
||||
83B73C452D8FF15700A57F08 /* mio_erisafile.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C392D8FF15700A57F08 /* mio_erisafile.c */; };
|
||||
83B73C462D8FF15700A57F08 /* mio_erisamatrix.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C3B2D8FF15700A57F08 /* mio_erisamatrix.c */; };
|
||||
83B73C472D8FF15700A57F08 /* mio_erisasound.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C3D2D8FF15700A57F08 /* mio_erisasound.c */; };
|
||||
83B73C492D8FF17900A57F08 /* mio_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C482D8FF17900A57F08 /* mio_decoder.c */; };
|
||||
83B73C4B2D8FF19800A57F08 /* mio.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C4A2D8FF19800A57F08 /* mio.c */; };
|
||||
83B73C4F2D8FF1CB00A57F08 /* io_callback_sf.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C4D2D8FF1CB00A57F08 /* io_callback_sf.h */; };
|
||||
83B73C502D8FF1CB00A57F08 /* io_callback.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C4C2D8FF1CB00A57F08 /* io_callback.h */; };
|
||||
83B73C512D8FF1CB00A57F08 /* io_callback_sf.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C4E2D8FF1CB00A57F08 /* io_callback_sf.c */; };
|
||||
83B73C542D8FF1E300A57F08 /* vorbis_codebooks.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C522D8FF1E300A57F08 /* vorbis_codebooks.h */; };
|
||||
83B73C552D8FF1E300A57F08 /* vorbis_codebooks.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C532D8FF1E300A57F08 /* vorbis_codebooks.c */; };
|
||||
83B73C572D8FF27000A57F08 /* 2dx.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C562D8FF27000A57F08 /* 2dx.c */; };
|
||||
83B73C5B2D8FF37700A57F08 /* codec_info.h in Headers */ = {isa = PBXBuildFile; fileRef = 83B73C592D8FF37700A57F08 /* codec_info.h */; };
|
||||
83B73C5C2D8FF37700A57F08 /* codec_info.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C5A2D8FF37700A57F08 /* codec_info.c */; };
|
||||
83B73C5D2D8FF37700A57F08 /* api_libsf_cache.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B73C582D8FF37700A57F08 /* api_libsf_cache.c */; };
|
||||
83B8FE2B2D5AB1F5005854C1 /* axhd.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B8FE2A2D5AB1F5005854C1 /* axhd.c */; };
|
||||
83B8FE2D2D5AB2A5005854C1 /* shaa.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B8FE2C2D5AB2A5005854C1 /* shaa.c */; };
|
||||
83B8FE2F2D5AB2F4005854C1 /* xwb_konami.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B8FE2E2D5AB2F4005854C1 /* xwb_konami.c */; };
|
||||
|
@ -1066,7 +1092,7 @@
|
|||
832BF80A21E05148006F50F1 /* xpcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xpcm.c; sourceTree = "<group>"; };
|
||||
832BF80B21E05148006F50F1 /* msf_tamasoft.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = msf_tamasoft.c; sourceTree = "<group>"; };
|
||||
832BF80C21E05148006F50F1 /* xps.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xps.c; sourceTree = "<group>"; };
|
||||
832BF80D21E05148006F50F1 /* ps2_va3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_va3.c; sourceTree = "<group>"; };
|
||||
832BF80D21E05148006F50F1 /* va3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = va3.c; sourceTree = "<group>"; };
|
||||
832BF80E21E05149006F50F1 /* zsnd_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = zsnd_streamfile.h; sourceTree = "<group>"; };
|
||||
832BF80F21E05149006F50F1 /* zsnd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zsnd.c; sourceTree = "<group>"; };
|
||||
832BF81021E05149006F50F1 /* vs_str.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vs_str.c; sourceTree = "<group>"; };
|
||||
|
@ -1178,7 +1204,6 @@
|
|||
834F7D422C7093EA003AC386 /* circus_vq_lib.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = circus_vq_lib.h; sourceTree = "<group>"; };
|
||||
834F7D432C7093EA003AC386 /* circus_vq_lzxpcm.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = circus_vq_lzxpcm.h; sourceTree = "<group>"; };
|
||||
834F7D442C7093EA003AC386 /* circus_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = circus_decoder.c; sourceTree = "<group>"; };
|
||||
834F7D452C7093EA003AC386 /* coding_utils_samples.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coding_utils_samples.h; sourceTree = "<group>"; };
|
||||
834F7D462C7093EA003AC386 /* coding_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = coding_utils.c; sourceTree = "<group>"; };
|
||||
834F7D472C7093EA003AC386 /* coding.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = coding.h; sourceTree = "<group>"; };
|
||||
834F7D482C7093EA003AC386 /* compresswave_lib.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = compresswave_lib.c; sourceTree = "<group>"; };
|
||||
|
@ -1253,8 +1278,6 @@
|
|||
834F7D8F2C7093EA003AC386 /* tgcadpcm_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tgcadpcm_decoder.c; sourceTree = "<group>"; };
|
||||
834F7D902C7093EA003AC386 /* ubi_adpcm_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ubi_adpcm_decoder.c; sourceTree = "<group>"; };
|
||||
834F7D912C7093EA003AC386 /* vadpcm_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vadpcm_decoder.c; sourceTree = "<group>"; };
|
||||
834F7D922C7093EA003AC386 /* vorbis_custom_data_fsb.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vorbis_custom_data_fsb.h; sourceTree = "<group>"; };
|
||||
834F7D932C7093EA003AC386 /* vorbis_custom_data_wwise.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vorbis_custom_data_wwise.h; sourceTree = "<group>"; };
|
||||
834F7D942C7093EA003AC386 /* vorbis_custom_decoder.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vorbis_custom_decoder.c; sourceTree = "<group>"; };
|
||||
834F7D952C7093EA003AC386 /* vorbis_custom_decoder.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = vorbis_custom_decoder.h; sourceTree = "<group>"; };
|
||||
834F7D962C7093EA003AC386 /* vorbis_custom_utils_awc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = vorbis_custom_utils_awc.c; sourceTree = "<group>"; };
|
||||
|
@ -1484,14 +1507,13 @@
|
|||
836F6E9918BDC2180095E648 /* lp_ap_lep.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = lp_ap_lep.c; sourceTree = "<group>"; };
|
||||
836F6E9B18BDC2180095E648 /* filp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = filp.c; sourceTree = "<group>"; };
|
||||
836F6E9C18BDC2180095E648 /* gbts.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = gbts.c; sourceTree = "<group>"; };
|
||||
836F6E9D18BDC2180095E648 /* ps2_gcm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_gcm.c; sourceTree = "<group>"; };
|
||||
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>"; };
|
||||
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>"; };
|
||||
836F6EAA18BDC2180095E648 /* ps2_mcg.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_mcg.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>"; };
|
||||
|
@ -1511,7 +1533,6 @@
|
|||
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>"; };
|
||||
836F6ED018BDC2190095E648 /* wb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = wb.c; sourceTree = "<group>"; };
|
||||
836F6ED118BDC2190095E648 /* ps2_wmus.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2_wmus.c; sourceTree = "<group>"; };
|
||||
836F6ED918BDC2190095E648 /* sndp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = sndp.c; sourceTree = "<group>"; };
|
||||
836F6EE218BDC2190095E648 /* redspark.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = redspark.c; sourceTree = "<group>"; };
|
||||
836F6EE318BDC2190095E648 /* riff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = riff.c; sourceTree = "<group>"; };
|
||||
|
@ -1673,6 +1694,37 @@
|
|||
83B46FD42707FB9A00847FC9 /* endianness.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = endianness.h; sourceTree = "<group>"; };
|
||||
83B69B212845A26600D2435A /* bw_mp3_riff.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bw_mp3_riff.c; sourceTree = "<group>"; };
|
||||
83B72E342790452C006007A3 /* libfdk-aac.2.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = "libfdk-aac.2.dylib"; path = "../../ThirdParty/fdk-aac/lib/libfdk-aac.2.dylib"; sourceTree = "<group>"; };
|
||||
83B73C202D8FEC3A00A57F08 /* oor_helpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = oor_helpers.h; sourceTree = "<group>"; };
|
||||
83B73C212D8FEC3A00A57F08 /* oor_helpers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = oor_helpers.c; sourceTree = "<group>"; };
|
||||
83B73C222D8FEC3A00A57F08 /* vorbis_codebooks_oor.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = vorbis_codebooks_oor.h; sourceTree = "<group>"; };
|
||||
83B73C262D8FEC5500A57F08 /* vorbis_custom_utils_oor.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = vorbis_custom_utils_oor.c; sourceTree = "<group>"; };
|
||||
83B73C282D8FEC7B00A57F08 /* oor.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = oor.c; sourceTree = "<group>"; };
|
||||
83B73C2A2D8FED0500A57F08 /* vorbis_codebooks_fsb.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = vorbis_codebooks_fsb.h; sourceTree = "<group>"; };
|
||||
83B73C2B2D8FED0500A57F08 /* vorbis_codebooks_wwise.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = vorbis_codebooks_wwise.h; sourceTree = "<group>"; };
|
||||
83B73C2E2D8FEF7A00A57F08 /* minimp3.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = minimp3.h; sourceTree = "<group>"; };
|
||||
83B73C2F2D8FEF7A00A57F08 /* ubi_mpeg_helpers.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ubi_mpeg_helpers.h; sourceTree = "<group>"; };
|
||||
83B73C302D8FEF7A00A57F08 /* ubi_mpeg_helpers.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ubi_mpeg_helpers.c; sourceTree = "<group>"; };
|
||||
83B73C342D8FEFFD00A57F08 /* ubi_mpeg_decoder.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ubi_mpeg_decoder.c; sourceTree = "<group>"; };
|
||||
83B73C362D8FF15700A57F08 /* mio_erisacontext.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mio_erisacontext.h; sourceTree = "<group>"; };
|
||||
83B73C372D8FF15700A57F08 /* mio_erisacontext.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mio_erisacontext.c; sourceTree = "<group>"; };
|
||||
83B73C382D8FF15700A57F08 /* mio_erisafile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mio_erisafile.h; sourceTree = "<group>"; };
|
||||
83B73C392D8FF15700A57F08 /* mio_erisafile.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mio_erisafile.c; sourceTree = "<group>"; };
|
||||
83B73C3A2D8FF15700A57F08 /* mio_erisamatrix.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mio_erisamatrix.h; sourceTree = "<group>"; };
|
||||
83B73C3B2D8FF15700A57F08 /* mio_erisamatrix.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mio_erisamatrix.c; sourceTree = "<group>"; };
|
||||
83B73C3C2D8FF15700A57F08 /* mio_erisasound.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mio_erisasound.h; sourceTree = "<group>"; };
|
||||
83B73C3D2D8FF15700A57F08 /* mio_erisasound.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mio_erisasound.c; sourceTree = "<group>"; };
|
||||
83B73C3E2D8FF15700A57F08 /* mio_xerisa.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = mio_xerisa.h; sourceTree = "<group>"; };
|
||||
83B73C482D8FF17900A57F08 /* mio_decoder.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mio_decoder.c; sourceTree = "<group>"; };
|
||||
83B73C4A2D8FF19800A57F08 /* mio.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = mio.c; sourceTree = "<group>"; };
|
||||
83B73C4C2D8FF1CB00A57F08 /* io_callback.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = io_callback.h; sourceTree = "<group>"; };
|
||||
83B73C4D2D8FF1CB00A57F08 /* io_callback_sf.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = io_callback_sf.h; sourceTree = "<group>"; };
|
||||
83B73C4E2D8FF1CB00A57F08 /* io_callback_sf.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = io_callback_sf.c; sourceTree = "<group>"; };
|
||||
83B73C522D8FF1E300A57F08 /* vorbis_codebooks.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = vorbis_codebooks.h; sourceTree = "<group>"; };
|
||||
83B73C532D8FF1E300A57F08 /* vorbis_codebooks.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = vorbis_codebooks.c; sourceTree = "<group>"; };
|
||||
83B73C562D8FF27000A57F08 /* 2dx.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = 2dx.c; sourceTree = "<group>"; };
|
||||
83B73C582D8FF37700A57F08 /* api_libsf_cache.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = api_libsf_cache.c; sourceTree = "<group>"; };
|
||||
83B73C592D8FF37700A57F08 /* codec_info.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = codec_info.h; sourceTree = "<group>"; };
|
||||
83B73C5A2D8FF37700A57F08 /* codec_info.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = codec_info.c; sourceTree = "<group>"; };
|
||||
83B8FE2A2D5AB1F5005854C1 /* axhd.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = axhd.c; sourceTree = "<group>"; };
|
||||
83B8FE2C2D5AB2A5005854C1 /* shaa.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = shaa.c; sourceTree = "<group>"; };
|
||||
83B8FE2E2D5AB2F4005854C1 /* xwb_konami.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = xwb_konami.c; sourceTree = "<group>"; };
|
||||
|
@ -1896,10 +1948,22 @@
|
|||
834F7D392C7093EA003AC386 /* libacm.h */,
|
||||
834F7D382C7093EA003AC386 /* libacm_decode.c */,
|
||||
834F7D3A2C7093EA003AC386 /* libacm_util.c */,
|
||||
83B73C2E2D8FEF7A00A57F08 /* minimp3.h */,
|
||||
83B73C362D8FF15700A57F08 /* mio_erisacontext.h */,
|
||||
83B73C372D8FF15700A57F08 /* mio_erisacontext.c */,
|
||||
83B73C382D8FF15700A57F08 /* mio_erisafile.h */,
|
||||
83B73C392D8FF15700A57F08 /* mio_erisafile.c */,
|
||||
83B73C3A2D8FF15700A57F08 /* mio_erisamatrix.h */,
|
||||
83B73C3B2D8FF15700A57F08 /* mio_erisamatrix.c */,
|
||||
83B73C3C2D8FF15700A57F08 /* mio_erisasound.h */,
|
||||
83B73C3D2D8FF15700A57F08 /* mio_erisasound.c */,
|
||||
83B73C3E2D8FF15700A57F08 /* mio_xerisa.h */,
|
||||
834F7D792C7093EA003AC386 /* nwa_lib.h */,
|
||||
834F7D342C7093EA003AC386 /* nwa_lib.c */,
|
||||
834F7E7A2C709E66003AC386 /* ongakukan_adp_lib.h */,
|
||||
834F7E792C709E66003AC386 /* ongakukan_adp_lib.c */,
|
||||
83B73C202D8FEC3A00A57F08 /* oor_helpers.h */,
|
||||
83B73C212D8FEC3A00A57F08 /* oor_helpers.c */,
|
||||
834F7D832C7093EA003AC386 /* relic_lib.h */,
|
||||
834F7D822C7093EA003AC386 /* relic_lib.c */,
|
||||
834F7D842C7093EA003AC386 /* relic_mixfft.c */,
|
||||
|
@ -1907,8 +1971,13 @@
|
|||
834F7D8C2C7093EA003AC386 /* tac_lib.h */,
|
||||
834F7D8B2C7093EA003AC386 /* tac_lib.c */,
|
||||
834F7D8A2C7093EA003AC386 /* tac_ops.h */,
|
||||
83B73C2F2D8FEF7A00A57F08 /* ubi_mpeg_helpers.h */,
|
||||
83B73C302D8FEF7A00A57F08 /* ubi_mpeg_helpers.c */,
|
||||
834F7D362C7093EA003AC386 /* utkdec.h */,
|
||||
834F7D352C7093EA003AC386 /* utkdec.c */,
|
||||
83B73C2A2D8FED0500A57F08 /* vorbis_codebooks_fsb.h */,
|
||||
83B73C222D8FEC3A00A57F08 /* vorbis_codebooks_oor.h */,
|
||||
83B73C2B2D8FED0500A57F08 /* vorbis_codebooks_wwise.h */,
|
||||
);
|
||||
path = libs;
|
||||
sourceTree = "<group>";
|
||||
|
@ -1924,7 +1993,6 @@
|
|||
834F7D442C7093EA003AC386 /* circus_decoder.c */,
|
||||
834F7D472C7093EA003AC386 /* coding.h */,
|
||||
834F7D462C7093EA003AC386 /* coding_utils.c */,
|
||||
834F7D452C7093EA003AC386 /* coding_utils_samples.h */,
|
||||
834F7D4A2C7093EA003AC386 /* compresswave_decoder.c */,
|
||||
834F7D4B2C7093EA003AC386 /* derf_decoder.c */,
|
||||
834F7D4C2C7093EA003AC386 /* dpcm_kcej_decoder.c */,
|
||||
|
@ -1949,6 +2017,7 @@
|
|||
834F7D672C7093EA003AC386 /* l5_555_decoder.c */,
|
||||
834F7D372C7093EA003AC386 /* libs */,
|
||||
834F7D682C7093EA003AC386 /* lsf_decoder.c */,
|
||||
83B73C482D8FF17900A57F08 /* mio_decoder.c */,
|
||||
834F7D6A2C7093EA003AC386 /* mp4_aac_decoder.c */,
|
||||
834F7D692C7093EA003AC386 /* mpc3_decoder.c */,
|
||||
834F7D6E2C7093EA003AC386 /* mpeg_custom_utils.c */,
|
||||
|
@ -1980,15 +2049,15 @@
|
|||
834F7D8E2C7093EA003AC386 /* tantalus_decoder.c */,
|
||||
834F7D8F2C7093EA003AC386 /* tgcadpcm_decoder.c */,
|
||||
834F7D902C7093EA003AC386 /* ubi_adpcm_decoder.c */,
|
||||
83B73C342D8FEFFD00A57F08 /* ubi_mpeg_decoder.c */,
|
||||
834F7D912C7093EA003AC386 /* vadpcm_decoder.c */,
|
||||
834F7D922C7093EA003AC386 /* vorbis_custom_data_fsb.h */,
|
||||
834F7D932C7093EA003AC386 /* vorbis_custom_data_wwise.h */,
|
||||
834F7D952C7093EA003AC386 /* vorbis_custom_decoder.h */,
|
||||
834F7D942C7093EA003AC386 /* vorbis_custom_decoder.c */,
|
||||
834F7D9C2C7093EA003AC386 /* vorbis_custom_utils.c */,
|
||||
834F7D962C7093EA003AC386 /* vorbis_custom_utils_awc.c */,
|
||||
834F7D972C7093EA003AC386 /* vorbis_custom_utils_fsb.c */,
|
||||
834F7D982C7093EA003AC386 /* vorbis_custom_utils_ogl.c */,
|
||||
83B73C262D8FEC5500A57F08 /* vorbis_custom_utils_oor.c */,
|
||||
834F7D992C7093EA003AC386 /* vorbis_custom_utils_sk.c */,
|
||||
834F7D9A2C7093EA003AC386 /* vorbis_custom_utils_vid1.c */,
|
||||
834F7D9B2C7093EA003AC386 /* vorbis_custom_utils_wwise.c */,
|
||||
|
@ -2010,7 +2079,10 @@
|
|||
834F7EA02C70A786003AC386 /* api_helpers.c */,
|
||||
834F7EA12C70A786003AC386 /* api_internal.h */,
|
||||
834F7EA22C70A786003AC386 /* api_libsf.c */,
|
||||
83B73C582D8FF37700A57F08 /* api_libsf_cache.c */,
|
||||
834F7EA32C70A786003AC386 /* api_tags.c */,
|
||||
83B73C592D8FF37700A57F08 /* codec_info.h */,
|
||||
83B73C5A2D8FF37700A57F08 /* codec_info.c */,
|
||||
834F7EA62C70A786003AC386 /* decode.h */,
|
||||
834F7EA52C70A786003AC386 /* decode.c */,
|
||||
834845772D27F2E9000E4928 /* decode_state.h */,
|
||||
|
@ -2217,6 +2289,7 @@
|
|||
836F6E2718BDC2180095E648 /* meta */ = {
|
||||
isa = PBXGroup;
|
||||
children = (
|
||||
83B73C562D8FF27000A57F08 /* 2dx.c */,
|
||||
836F6E2918BDC2180095E648 /* 2dx9.c */,
|
||||
836F6E8D18BDC2180095E648 /* 2pfs.c */,
|
||||
83C727FE22BC893900678B4A /* 9tav.c */,
|
||||
|
@ -2420,9 +2493,11 @@
|
|||
836F6E5C18BDC2180095E648 /* mattel_hyperscan.c */,
|
||||
836F6E5D18BDC2180095E648 /* maxis_xa.c */,
|
||||
83EDE5D61A70951A005F5D84 /* mca.c */,
|
||||
836F6E9D18BDC2180095E648 /* mcg.c */,
|
||||
836F6E5E18BDC2180095E648 /* meta.h */,
|
||||
834FE0DE215C79EB000A5D3D /* mib_mih.c */,
|
||||
836F6EAC18BDC2180095E648 /* mic_koei.c */,
|
||||
83B73C4A2D8FF19800A57F08 /* mio.c */,
|
||||
8346D97725BF838C00D1A8B0 /* mjb_mjh.c */,
|
||||
836F6E5F18BDC2180095E648 /* mn_str.c */,
|
||||
8349A9031FE6258100E26435 /* mogg.c */,
|
||||
|
@ -2483,6 +2558,7 @@
|
|||
831BA60F1EAC61A500CF89B0 /* ogl.c */,
|
||||
83AF2CC726226BA400538240 /* ogv_3rdeye.c */,
|
||||
8349A8FB1FE6257F00E26435 /* omu.c */,
|
||||
83B73C282D8FEC7B00A57F08 /* oor.c */,
|
||||
8306B0CE2098458E000302D4 /* opus.c */,
|
||||
8306B0CD2098458E000302D4 /* opus_interleave_streamfile.h */,
|
||||
836F6EB218BDC2180095E648 /* p2bt_move_visa.c */,
|
||||
|
@ -2505,21 +2581,17 @@
|
|||
836F6E9118BDC2180095E648 /* ps2_ass.c */,
|
||||
836F6E9418BDC2180095E648 /* ps2_b1s.c */,
|
||||
836F6E9618BDC2180095E648 /* ps2_bmdx.c */,
|
||||
836F6E9D18BDC2180095E648 /* ps2_gcm.c */,
|
||||
836F6E9F18BDC2180095E648 /* ps2_hsf.c */,
|
||||
836F6EA018BDC2180095E648 /* ps2_iab.c */,
|
||||
836F6EA418BDC2180095E648 /* ps2_joe.c */,
|
||||
836F6EAA18BDC2180095E648 /* ps2_mcg.c */,
|
||||
836F6EB618BDC2180095E648 /* ps2_rnd.c */,
|
||||
836F6EBD18BDC2180095E648 /* ps2_snd.c */,
|
||||
836F6EBF18BDC2190095E648 /* ps2_sps.c */,
|
||||
836F6EC518BDC2190095E648 /* ps2_tec.c */,
|
||||
832BF80D21E05148006F50F1 /* ps2_va3.c */,
|
||||
836F6EC918BDC2190095E648 /* ps2_vbk.c */,
|
||||
836F6ECB18BDC2190095E648 /* ps2_vgv.c */,
|
||||
836F6ECC18BDC2190095E648 /* ps2_vms.c */,
|
||||
836F6ECF18BDC2190095E648 /* ps2_wad.c */,
|
||||
836F6ED118BDC2190095E648 /* ps2_wmus.c */,
|
||||
8315868326F586E200803A3A /* psb.c */,
|
||||
837CEAE823487F2B00E62A4A /* psf.c */,
|
||||
836F6E5518BDC2180095E648 /* psnd.c */,
|
||||
|
@ -2639,6 +2711,7 @@
|
|||
834FE0C5215C79E6000A5D3D /* ue4opus.c */,
|
||||
83B8FE302D5AB421005854C1 /* undefind.c */,
|
||||
834FE0DD215C79EB000A5D3D /* utk.c */,
|
||||
832BF80D21E05148006F50F1 /* va3.c */,
|
||||
83D1189228B2F33400AF3370 /* vab.c */,
|
||||
834FE0E4215C79EC000A5D3D /* vag.c */,
|
||||
834FE0D3215C79E9000A5D3D /* vai.c */,
|
||||
|
@ -2735,42 +2808,47 @@
|
|||
833E82F92A28595A00CD0580 /* bitstream_lsb.h */,
|
||||
836DF620298F83F400CD0580 /* bitstream_msb.h */,
|
||||
833E82C72A28566700CD0580 /* channel_mappings.h */,
|
||||
83D26A8026E66DC2001A9475 /* chunks.c */,
|
||||
83D26A7E26E66DC2001A9475 /* chunks.h */,
|
||||
834F7D132C70861D003AC386 /* cipher_blowfish.c */,
|
||||
83D26A8026E66DC2001A9475 /* chunks.c */,
|
||||
834F7D122C70861D003AC386 /* cipher_blowfish.h */,
|
||||
834F7D1A2C708719003AC386 /* cipher_xxtea.c */,
|
||||
834F7D132C70861D003AC386 /* cipher_blowfish.c */,
|
||||
834F7D1B2C708719003AC386 /* cipher_xxtea.h */,
|
||||
833E82EB2A28587D00CD0580 /* companion_files.c */,
|
||||
834F7D1A2C708719003AC386 /* cipher_xxtea.c */,
|
||||
833E82EF2A28587D00CD0580 /* companion_files.h */,
|
||||
836DF621298F83F400CD0580 /* cri_keys.c */,
|
||||
833E82EB2A28587D00CD0580 /* companion_files.c */,
|
||||
836DF61F298F83F400CD0580 /* cri_keys.h */,
|
||||
836F46B5282087A6005B9B87 /* cri_utf.c */,
|
||||
836DF621298F83F400CD0580 /* cri_keys.c */,
|
||||
836F46B6282087A6005B9B87 /* cri_utf.h */,
|
||||
836F46B5282087A6005B9B87 /* cri_utf.c */,
|
||||
83B46FD42707FB9A00847FC9 /* endianness.h */,
|
||||
83C0C75E2AA436370056AFD8 /* layout_utils.c */,
|
||||
83B73C4C2D8FF1CB00A57F08 /* io_callback.h */,
|
||||
83B73C4D2D8FF1CB00A57F08 /* io_callback_sf.h */,
|
||||
83B73C4E2D8FF1CB00A57F08 /* io_callback_sf.c */,
|
||||
83C0C75F2AA436370056AFD8 /* layout_utils.h */,
|
||||
83D26A7D26E66DC2001A9475 /* log.c */,
|
||||
83C0C75E2AA436370056AFD8 /* layout_utils.c */,
|
||||
83D26A7F26E66DC2001A9475 /* log.h */,
|
||||
8315868826F586F900803A3A /* m2_psb.c */,
|
||||
83D26A7D26E66DC2001A9475 /* log.c */,
|
||||
8315868926F586F900803A3A /* m2_psb.h */,
|
||||
834F7E9A2C70A6E1003AC386 /* meta_utils.c */,
|
||||
8315868826F586F900803A3A /* m2_psb.c */,
|
||||
834F7E992C70A6E1003AC386 /* meta_utils.h */,
|
||||
8319017A28F67EE100B70711 /* miniz.c */,
|
||||
834F7E9A2C70A6E1003AC386 /* meta_utils.c */,
|
||||
8319017928F67EE000B70711 /* miniz.h */,
|
||||
833E82EC2A28587D00CD0580 /* paths.c */,
|
||||
8319017A28F67EE100B70711 /* miniz.c */,
|
||||
833E82ED2A28587D00CD0580 /* paths.h */,
|
||||
833E82C92A2856B200CD0580 /* reader_get_nibbles.h */,
|
||||
833E82EC2A28587D00CD0580 /* paths.c */,
|
||||
833E82F52A2858EF00CD0580 /* reader.c */,
|
||||
833E82CA2A2856B200CD0580 /* reader_get.h */,
|
||||
833E82C92A2856B200CD0580 /* reader_get_nibbles.h */,
|
||||
833E82CB2A2856B200CD0580 /* reader_put.h */,
|
||||
833E82EE2A28587D00CD0580 /* reader_sf.h */,
|
||||
833E82F62A2858EF00CD0580 /* reader_text.h */,
|
||||
833E82F52A2858EF00CD0580 /* reader.c */,
|
||||
83FBB17B2A4FF87200CD0580 /* sf_utils.c */,
|
||||
83FBB17A2A4FF87200CD0580 /* sf_utils.h */,
|
||||
8339B324280FDF4B0076F74B /* text_reader.c */,
|
||||
83FBB17B2A4FF87200CD0580 /* sf_utils.c */,
|
||||
8339B325280FDF4B0076F74B /* text_reader.h */,
|
||||
8339B324280FDF4B0076F74B /* text_reader.c */,
|
||||
834F7E772C709D0E003AC386 /* vgmstream_limits.h */,
|
||||
83B73C522D8FF1E300A57F08 /* vorbis_codebooks.h */,
|
||||
83B73C532D8FF1E300A57F08 /* vorbis_codebooks.c */,
|
||||
834F7E102C709933003AC386 /* zlib_vgmstream.h */,
|
||||
);
|
||||
path = util;
|
||||
|
@ -2811,9 +2889,12 @@
|
|||
834F7DC42C7093EA003AC386 /* g72x_state.h in Headers */,
|
||||
834F7ED62C70A786003AC386 /* plugins.h in Headers */,
|
||||
834F7E782C709D0E003AC386 /* vgmstream_limits.h in Headers */,
|
||||
83B73C5B2D8FF37700A57F08 /* codec_info.h in Headers */,
|
||||
83D26A8226E66DC2001A9475 /* chunks.h in Headers */,
|
||||
835096F32C9979DD00163D93 /* libvgmstream_streamfile.h in Headers */,
|
||||
836F705518BDC2190095E648 /* streamtypes.h in Headers */,
|
||||
83CBF5362D46309100AA2D75 /* ka1a_dec.h in Headers */,
|
||||
835096F22C9979DD00163D93 /* libvgmstream.h in Headers */,
|
||||
83CBF5372D46309100AA2D75 /* ka1a_dec_data.h in Headers */,
|
||||
833E82CF2A2856B200CD0580 /* reader_get_nibbles.h in Headers */,
|
||||
833E82D12A2856B200CD0580 /* reader_put.h in Headers */,
|
||||
|
@ -2848,6 +2929,8 @@
|
|||
83B46FD52707FB9A00847FC9 /* endianness.h in Headers */,
|
||||
834F7D092C7085EB003AC386 /* str_wav_streamfile.h in Headers */,
|
||||
836F705718BDC2190095E648 /* util.h in Headers */,
|
||||
83B73C4F2D8FF1CB00A57F08 /* io_callback_sf.h in Headers */,
|
||||
83B73C502D8FF1CB00A57F08 /* io_callback.h in Headers */,
|
||||
834F7DF82C7093EA003AC386 /* tac_ops.h in Headers */,
|
||||
83256CC128666C620036D9C0 /* index.h in Headers */,
|
||||
834FE0ED215C79ED000A5D3D /* fsb_interleave_streamfile.h in Headers */,
|
||||
|
@ -2871,8 +2954,6 @@
|
|||
83256CD628666C620036D9C0 /* newhuffman.h in Headers */,
|
||||
835C883722CC17BE001B4B3F /* ogg_vorbis_streamfile.h in Headers */,
|
||||
837CEAFE23487F2C00E62A4A /* jstm_streamfile.h in Headers */,
|
||||
835096F22C9979DD00163D93 /* libvgmstream.h in Headers */,
|
||||
835096F32C9979DD00163D93 /* libvgmstream_streamfile.h in Headers */,
|
||||
834F7DB02C7093EA003AC386 /* circus_vq_lib.h in Headers */,
|
||||
832BF82021E0514B006F50F1 /* zsnd_streamfile.h in Headers */,
|
||||
834F7E862C709FED003AC386 /* api_version.h in Headers */,
|
||||
|
@ -2901,6 +2982,8 @@
|
|||
83256CD128666C620036D9C0 /* mpg123lib_intern.h in Headers */,
|
||||
83C7281622BC893D00678B4A /* xwma_konami_streamfile.h in Headers */,
|
||||
834F7D1D2C708719003AC386 /* cipher_xxtea.h in Headers */,
|
||||
83B73C312D8FEF7A00A57F08 /* ubi_mpeg_helpers.h in Headers */,
|
||||
83B73C322D8FEF7A00A57F08 /* minimp3.h in Headers */,
|
||||
833E82C82A28566700CD0580 /* channel_mappings.h in Headers */,
|
||||
83256CC028666C620036D9C0 /* synth_8bit.h in Headers */,
|
||||
834F7DCB2C7093EA003AC386 /* g7221_lib.h in Headers */,
|
||||
|
@ -2925,15 +3008,20 @@
|
|||
834F7E202C709AE0003AC386 /* api_tags.h in Headers */,
|
||||
8396BE7B2935FC2F00CD0580 /* sscf_encrypted.h in Headers */,
|
||||
83FBD506235D31F800D35BCD /* riff_ogg_streamfile.h in Headers */,
|
||||
83B73C3F2D8FF15700A57F08 /* mio_xerisa.h in Headers */,
|
||||
83B73C402D8FF15700A57F08 /* mio_erisasound.h in Headers */,
|
||||
83B73C412D8FF15700A57F08 /* mio_erisacontext.h in Headers */,
|
||||
83B73C422D8FF15700A57F08 /* mio_erisafile.h in Headers */,
|
||||
83B73C432D8FF15700A57F08 /* mio_erisamatrix.h in Headers */,
|
||||
8339B327280FDF4B0076F74B /* text_reader.h in Headers */,
|
||||
834F7E002C7093EA003AC386 /* vorbis_custom_data_fsb.h in Headers */,
|
||||
834F7DD12C7093EA003AC386 /* icelib.h in Headers */,
|
||||
836F6F9A18BDC2190095E648 /* meta.h in Headers */,
|
||||
8319017B28F67EE100B70711 /* miniz.h in Headers */,
|
||||
834F7DA52C7093EA003AC386 /* utkdec.h in Headers */,
|
||||
834F7ECE2C70A786003AC386 /* mixer_priv.h in Headers */,
|
||||
83B73C232D8FEC3A00A57F08 /* vorbis_codebooks_oor.h in Headers */,
|
||||
83B73C242D8FEC3A00A57F08 /* oor_helpers.h in Headers */,
|
||||
833E82FA2A28595A00CD0580 /* bitstream_lsb.h in Headers */,
|
||||
834F7DB32C7093EA003AC386 /* coding_utils_samples.h in Headers */,
|
||||
834F7DF72C7093EA003AC386 /* tac_data.h in Headers */,
|
||||
834F7DFA2C7093EA003AC386 /* tac_lib.h in Headers */,
|
||||
83A8BAE625667AA8000F5F3F /* lp_ap_lep_streamfile.h in Headers */,
|
||||
|
@ -2972,16 +3060,18 @@
|
|||
83256CD728666C620036D9C0 /* synth_mono.h in Headers */,
|
||||
834F7DCE2C7093EA003AC386 /* clhca.h in Headers */,
|
||||
8349A91B1FE6258200E26435 /* adx_keys.h in Headers */,
|
||||
834F7E012C7093EA003AC386 /* vorbis_custom_data_wwise.h in Headers */,
|
||||
836F6F4D18BDC2190095E648 /* layout.h in Headers */,
|
||||
83269DD22399F5DE00F49FE3 /* nus3bank_streamfile.h in Headers */,
|
||||
83AA5D251F6E2F9C0020821C /* hca_keys.h in Headers */,
|
||||
834F7E832C709F5B003AC386 /* apa3_streamfile.h in Headers */,
|
||||
83256CDA28666C620036D9C0 /* l2tables.h in Headers */,
|
||||
83256CC828666C620036D9C0 /* getbits.h in Headers */,
|
||||
83B73C2C2D8FED0500A57F08 /* vorbis_codebooks_wwise.h in Headers */,
|
||||
83B73C2D2D8FED0500A57F08 /* vorbis_codebooks_fsb.h in Headers */,
|
||||
83256CC728666C620036D9C0 /* optimize.h in Headers */,
|
||||
83031ED3243C50DF00C3F3E0 /* fsb5_streamfile.h in Headers */,
|
||||
83256CE328666C620036D9C0 /* decode.h in Headers */,
|
||||
83B73C542D8FF1E300A57F08 /* vorbis_codebooks.h in Headers */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
};
|
||||
|
@ -3179,6 +3269,8 @@
|
|||
832BF82821E0514B006F50F1 /* xwma.c in Sources */,
|
||||
83FC176E23AC58D100E1025F /* csb.c in Sources */,
|
||||
836F46B32820874D005B9B87 /* esf.c in Sources */,
|
||||
83B73C512D8FF1CB00A57F08 /* io_callback_sf.c in Sources */,
|
||||
83B73C352D8FEFFD00A57F08 /* ubi_mpeg_decoder.c in Sources */,
|
||||
8306B0EB20984590000302D4 /* wave_segmented.c in Sources */,
|
||||
836F6F9F18BDC2190095E648 /* musc.c in Sources */,
|
||||
8349A9121FE6258200E26435 /* smss.c in Sources */,
|
||||
|
@ -3229,6 +3321,7 @@
|
|||
836F6F9418BDC2190095E648 /* iivb.c in Sources */,
|
||||
836F6F8D18BDC2190095E648 /* gsnd.c in Sources */,
|
||||
836F704518BDC2190095E648 /* wvs.c in Sources */,
|
||||
83B73C292D8FEC7B00A57F08 /* oor.c in Sources */,
|
||||
839FBFFB26C354E70016A78A /* wxd_wxh.c in Sources */,
|
||||
83EDE5D91A70951A005F5D84 /* btsnd.c in Sources */,
|
||||
834F7DD72C7093EA003AC386 /* mpc3_decoder.c in Sources */,
|
||||
|
@ -3336,6 +3429,7 @@
|
|||
835DF7032C79ABB50008814A /* sbuf.c in Sources */,
|
||||
830EBE142004656E0023AA10 /* ktss.c in Sources */,
|
||||
836F6F6618BDC2190095E648 /* aax.c in Sources */,
|
||||
83B73C272D8FEC5500A57F08 /* vorbis_custom_utils_oor.c in Sources */,
|
||||
8306B0BC20984552000302D4 /* blocked_vs.c in Sources */,
|
||||
83AA7F812519C042004C5298 /* silence.c in Sources */,
|
||||
837CEAF823487F2C00E62A4A /* xwv_valve.c in Sources */,
|
||||
|
@ -3430,6 +3524,7 @@
|
|||
837CEAD823487E8300E62A4A /* bmp_konami.c in Sources */,
|
||||
834F7DDC2C7093EA003AC386 /* mpeg_custom_utils.c in Sources */,
|
||||
834F7E922C70A1AB003AC386 /* vgmstream_init.c in Sources */,
|
||||
83B73C332D8FEF7A00A57F08 /* ubi_mpeg_helpers.c in Sources */,
|
||||
836F700118BDC2190095E648 /* ps2_tec.c in Sources */,
|
||||
832BF82121E0514B006F50F1 /* zsnd.c in Sources */,
|
||||
836F703018BDC2190095E648 /* sqex_scd.c in Sources */,
|
||||
|
@ -3486,8 +3581,9 @@
|
|||
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 */,
|
||||
836F6FE618BDC2190095E648 /* ps2_mcg.c in Sources */,
|
||||
83AA5D241F6E2F9C0020821C /* awc.c in Sources */,
|
||||
8349A8E91FE6253900E26435 /* blocked_ea_1snh.c in Sources */,
|
||||
8306B0E620984590000302D4 /* msb_msh.c in Sources */,
|
||||
|
@ -3520,6 +3616,7 @@
|
|||
83CBF5432D46339200AA2D75 /* skex.c in Sources */,
|
||||
834F7E182C709A1D003AC386 /* ea_schl_standard.c in Sources */,
|
||||
836F6FCD18BDC2190095E648 /* ps2_ass.c in Sources */,
|
||||
83B73C252D8FEC3A00A57F08 /* oor_helpers.c in Sources */,
|
||||
83CBF5412D4631F300AA2D75 /* i3ds.c in Sources */,
|
||||
8349A90B1FE6258200E26435 /* pcm_kceje.c in Sources */,
|
||||
836F6F4A18BDC2190095E648 /* interleave.c in Sources */,
|
||||
|
@ -3541,12 +3638,15 @@
|
|||
834D3A6E19F47C98001C54F6 /* g1l.c in Sources */,
|
||||
832BF82A21E0514B006F50F1 /* vs_square.c in Sources */,
|
||||
8349A9091FE6258200E26435 /* pc_ast.c in Sources */,
|
||||
83B73C442D8FF15700A57F08 /* mio_erisacontext.c in Sources */,
|
||||
83B73C452D8FF15700A57F08 /* mio_erisafile.c in Sources */,
|
||||
83B73C462D8FF15700A57F08 /* mio_erisamatrix.c in Sources */,
|
||||
83B73C472D8FF15700A57F08 /* mio_erisasound.c in Sources */,
|
||||
834F7DEF2C7093EA003AC386 /* ptadpcm_decoder.c in Sources */,
|
||||
832BF81F21E0514B006F50F1 /* ps2_va3.c in Sources */,
|
||||
832BF81F21E0514B006F50F1 /* va3.c in Sources */,
|
||||
8349A91C1FE6258200E26435 /* mogg.c in Sources */,
|
||||
834FE0F5215C79ED000A5D3D /* wav2.c in Sources */,
|
||||
836F703D18BDC2190095E648 /* mus_krome.c in Sources */,
|
||||
836F700D18BDC2190095E648 /* ps2_wmus.c in Sources */,
|
||||
831BA61C1EAC61A500CF89B0 /* sndx.c in Sources */,
|
||||
836F6F9618BDC2190095E648 /* lsf.c in Sources */,
|
||||
834F7E7E2C709E76003AC386 /* ongakukan_adp_decoder.c in Sources */,
|
||||
|
@ -3585,6 +3685,7 @@
|
|||
836F702A18BDC2190095E648 /* sd9.c in Sources */,
|
||||
836F6FB418BDC2190095E648 /* ngc_nst_dsp.c in Sources */,
|
||||
834F7DB92C7093EA003AC386 /* derf_decoder.c in Sources */,
|
||||
83B73C4B2D8FF19800A57F08 /* mio.c in Sources */,
|
||||
836F6FDB18BDC2190095E648 /* ps2_hsf.c in Sources */,
|
||||
836F6FF618BDC2190095E648 /* ster.c in Sources */,
|
||||
834F7E0D2C7093EA003AC386 /* xa_decoder.c in Sources */,
|
||||
|
@ -3610,6 +3711,7 @@
|
|||
834F7D0B2C7085EB003AC386 /* ea_eaac_standard.c in Sources */,
|
||||
834FE0FA215C79ED000A5D3D /* nus3bank.c in Sources */,
|
||||
8306B0B220984552000302D4 /* blocked_mxch.c in Sources */,
|
||||
83B73C492D8FF17900A57F08 /* mio_decoder.c in Sources */,
|
||||
834F7DBC2C7093EA003AC386 /* ea_mt_decoder.c in Sources */,
|
||||
837CEAFA23487F2C00E62A4A /* xa_04sw.c in Sources */,
|
||||
836F6F8618BDC2190095E648 /* excitebots.c in Sources */,
|
||||
|
@ -3633,6 +3735,7 @@
|
|||
831BA6211EAC61A500CF89B0 /* pasx.c in Sources */,
|
||||
832BF82621E0514B006F50F1 /* nwav.c in Sources */,
|
||||
8349A8E81FE6253900E26435 /* blocked_dec.c in Sources */,
|
||||
83B73C552D8FF1E300A57F08 /* vorbis_codebooks.c in Sources */,
|
||||
834F7EDA2C70A786003AC386 /* seek.c in Sources */,
|
||||
834F7DBF2C7093EA003AC386 /* fadpcm_decoder.c in Sources */,
|
||||
834F7DCC2C7093EA003AC386 /* g7221_decoder.c in Sources */,
|
||||
|
@ -3644,6 +3747,7 @@
|
|||
8306B0B620984552000302D4 /* blocked_hwas.c in Sources */,
|
||||
836F6FC218BDC2190095E648 /* pc_mxst.c in Sources */,
|
||||
8375737621F950ED00F01AF5 /* gin.c in Sources */,
|
||||
83B73C572D8FF27000A57F08 /* 2dx.c in Sources */,
|
||||
836F6FC918BDC2190095E648 /* 2pfs.c in Sources */,
|
||||
83AFABBC23795202002F3947 /* xssb.c in Sources */,
|
||||
836F704818BDC2190095E648 /* xbox_ims.c in Sources */,
|
||||
|
@ -3651,7 +3755,7 @@
|
|||
836F6F7518BDC2190095E648 /* bnsf.c in Sources */,
|
||||
836F704318BDC2190095E648 /* wpd.c in Sources */,
|
||||
8349A9081FE6258200E26435 /* ezw.c in Sources */,
|
||||
836F6FD918BDC2190095E648 /* ps2_gcm.c in Sources */,
|
||||
836F6FD918BDC2190095E648 /* mcg.c in Sources */,
|
||||
83A21F88201D8981000F04B9 /* ogg_vorbis.c in Sources */,
|
||||
837CEAF923487F2C00E62A4A /* xavs.c in Sources */,
|
||||
836F6F8E18BDC2190095E648 /* halpst.c in Sources */,
|
||||
|
|
|
@ -1,13 +1,23 @@
|
|||
#include "api_internal.h"
|
||||
#include "mixing.h"
|
||||
|
||||
#define INTERNAL_BUF_SAMPLES 1024
|
||||
|
||||
|
||||
LIBVGMSTREAM_API uint32_t libvgmstream_get_version(void) {
|
||||
return (LIBVGMSTREAM_API_VERSION_MAJOR << 24) | (LIBVGMSTREAM_API_VERSION_MINOR << 16) | (LIBVGMSTREAM_API_VERSION_PATCH << 0);
|
||||
}
|
||||
|
||||
LIBVGMSTREAM_API libvgmstream_t* libvgmstream_create(libstreamfile_t* libsf, int subsong, libvgmstream_config_t* vcfg) {
|
||||
libvgmstream_t* vgmstream = libvgmstream_init();
|
||||
libvgmstream_setup(vgmstream, vcfg);
|
||||
int err = libvgmstream_open_stream(vgmstream, libsf, subsong);
|
||||
if (err < 0) {
|
||||
libvgmstream_free(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
}
|
||||
|
||||
LIBVGMSTREAM_API libvgmstream_t* libvgmstream_init(void) {
|
||||
libvgmstream_t* lib = NULL;
|
||||
|
@ -48,57 +58,79 @@ LIBVGMSTREAM_API void libvgmstream_free(libvgmstream_t* lib) {
|
|||
free(lib);
|
||||
}
|
||||
|
||||
// TODO: allow calling after load
|
||||
|
||||
LIBVGMSTREAM_API void libvgmstream_setup(libvgmstream_t* lib, libvgmstream_config_t* cfg) {
|
||||
if (!lib || !lib->priv)
|
||||
return;
|
||||
|
||||
libvgmstream_priv_t* priv = lib->priv;
|
||||
|
||||
// Can only apply once b/c some options modify the internal mixing chain and there is no clean way to
|
||||
// reset the stream when txtp also manipulates it (maybe could add some flag per mixing item)
|
||||
if (priv->setup_done)
|
||||
return;
|
||||
|
||||
// allow overwritting current config, though will only apply to next load
|
||||
//if (priv->config_loaded)
|
||||
// return;
|
||||
|
||||
if (!cfg) {
|
||||
memset(&priv->cfg , 0, sizeof(libvgmstream_config_t));
|
||||
priv->cfg.loop_count = 1; //TODO: loop 0 means no loop (improve detection)
|
||||
priv->config_loaded = false;
|
||||
}
|
||||
else {
|
||||
|
||||
priv->cfg = *cfg;
|
||||
priv->config_loaded = true;
|
||||
}
|
||||
|
||||
//TODO validate, etc
|
||||
//TODO validate, etc (for now most incorrect values are ignored)
|
||||
|
||||
// apply now if possible to update format info
|
||||
if (priv->vgmstream) {
|
||||
api_apply_config(priv);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void libvgmstream_priv_reset(libvgmstream_priv_t* priv, bool reset_buf) {
|
||||
void libvgmstream_priv_reset(libvgmstream_priv_t* priv, bool full) {
|
||||
//memset(&priv->cfg, 0, sizeof(libvgmstream_config_t)); //config is always valid
|
||||
memset(&priv->fmt, 0, sizeof(libvgmstream_format_t));
|
||||
memset(&priv->dec, 0, sizeof(libvgmstream_decoder_t));
|
||||
//memset(&priv->pos, 0, sizeof(libvgmstream_priv_position_t)); //position info is updated on open
|
||||
|
||||
if (reset_buf) {
|
||||
free(priv->buf.data);
|
||||
memset(&priv->dec, 0, sizeof(libvgmstream_decoder_t));
|
||||
|
||||
if (full) {
|
||||
free(priv->buf.data); //TODO
|
||||
memset(&priv->buf, 0, sizeof(libvgmstream_priv_buf_t));
|
||||
memset(&priv->fmt, 0, sizeof(libvgmstream_format_t));
|
||||
}
|
||||
else {
|
||||
priv->buf.consumed = priv->buf.samples;
|
||||
}
|
||||
|
||||
priv->pos.current = 0;
|
||||
priv->decode_done = false;
|
||||
}
|
||||
|
||||
libvgmstream_sample_t api_get_output_sample_type(libvgmstream_priv_t* priv) {
|
||||
libvgmstream_sfmt_t api_get_output_sample_type(libvgmstream_priv_t* priv) {
|
||||
VGMSTREAM* v = priv->vgmstream;
|
||||
sfmt_t format = mixing_get_output_sample_type(v);
|
||||
switch(format) {
|
||||
case SFMT_S16: return LIBVGMSTREAM_SAMPLE_PCM16;
|
||||
case SFMT_FLT: return LIBVGMSTREAM_SAMPLE_FLOAT;
|
||||
case SFMT_S16: return LIBVGMSTREAM_SFMT_PCM16;
|
||||
case SFMT_FLT: return LIBVGMSTREAM_SFMT_FLOAT;
|
||||
case SFMT_F32: return LIBVGMSTREAM_SFMT_FLOAT; //shouldn't happen?
|
||||
default:
|
||||
return 0x00; //???
|
||||
}
|
||||
}
|
||||
|
||||
int api_get_sample_size(libvgmstream_sample_t sample_type) {
|
||||
switch(sample_type) {
|
||||
case LIBVGMSTREAM_SAMPLE_PCM24:
|
||||
case LIBVGMSTREAM_SAMPLE_PCM32:
|
||||
case LIBVGMSTREAM_SAMPLE_FLOAT:
|
||||
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:
|
||||
return 0x04;
|
||||
case LIBVGMSTREAM_SAMPLE_PCM16:
|
||||
case LIBVGMSTREAM_SFMT_PCM16:
|
||||
default:
|
||||
return 0x02;
|
||||
}
|
||||
|
|
|
@ -3,18 +3,6 @@
|
|||
#include "mixing.h"
|
||||
|
||||
|
||||
static void load_vgmstream(libvgmstream_priv_t* priv, libvgmstream_options_t* opt) {
|
||||
STREAMFILE* sf_api = open_api_streamfile(opt->libsf);
|
||||
if (!sf_api)
|
||||
return;
|
||||
|
||||
//TODO: handle internal format_id
|
||||
|
||||
sf_api->stream_index = opt->subsong_index;
|
||||
priv->vgmstream = init_vgmstream_from_STREAMFILE(sf_api);
|
||||
close_streamfile(sf_api);
|
||||
}
|
||||
|
||||
static void apply_config(libvgmstream_priv_t* priv) {
|
||||
libvgmstream_config_t* cfg = &priv->cfg;
|
||||
|
||||
|
@ -36,23 +24,50 @@ static void apply_config(libvgmstream_priv_t* priv) {
|
|||
if (!vcfg.allow_play_forever)
|
||||
vcfg.play_forever = 0;
|
||||
|
||||
// Traditionally in CLI loop_count = 0 removes loops but this is pretty odd for a lib
|
||||
// (calling _setup with nothing set would remove most audio).
|
||||
// For now loop_count 0 is set to 1, and loop_count <0 is assumed to be same 0
|
||||
if (vcfg.loop_count == 0) {
|
||||
vcfg.loop_count = 1;
|
||||
} else if (vcfg.loop_count < 0)
|
||||
vcfg.loop_count = 0;
|
||||
|
||||
vgmstream_apply_config(priv->vgmstream, &vcfg);
|
||||
}
|
||||
|
||||
static void prepare_mixing(libvgmstream_priv_t* priv, libvgmstream_options_t* opt) {
|
||||
static void prepare_mixing(libvgmstream_priv_t* priv) {
|
||||
libvgmstream_config_t* cfg = &priv->cfg;
|
||||
|
||||
/* enable after config but before outbuf */
|
||||
if (priv->cfg.auto_downmix_channels) {
|
||||
vgmstream_mixing_autodownmix(priv->vgmstream, priv->cfg.auto_downmix_channels);
|
||||
if (cfg->auto_downmix_channels) {
|
||||
vgmstream_mixing_autodownmix(priv->vgmstream, cfg->auto_downmix_channels);
|
||||
}
|
||||
else if (opt && opt->stereo_track >= 1) {
|
||||
vgmstream_mixing_stereo_only(priv->vgmstream, opt->stereo_track - 1);
|
||||
else if (cfg->stereo_track >= 1) {
|
||||
vgmstream_mixing_stereo_only(priv->vgmstream, cfg->stereo_track - 1);
|
||||
}
|
||||
|
||||
if (priv->cfg.force_pcm16) {
|
||||
mixing_macro_output_sample_format(priv->vgmstream, SFMT_S16);
|
||||
if (cfg->force_sfmt) {
|
||||
// external force
|
||||
sfmt_t force_sfmt = SFMT_NONE;
|
||||
switch(cfg->force_sfmt) {
|
||||
case LIBVGMSTREAM_SFMT_PCM16: force_sfmt = SFMT_S16; break;
|
||||
case LIBVGMSTREAM_SFMT_FLOAT: force_sfmt = SFMT_FLT; break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
mixing_macro_output_sample_format(priv->vgmstream, force_sfmt);
|
||||
}
|
||||
else if (priv->cfg.force_float) {
|
||||
mixing_macro_output_sample_format(priv->vgmstream, SFMT_FLT);
|
||||
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;
|
||||
default: break;
|
||||
}
|
||||
|
||||
mixing_macro_output_sample_format(priv->vgmstream, force_sfmt);
|
||||
}
|
||||
|
||||
vgmstream_mixing_enable(priv->vgmstream, INTERNAL_BUF_SAMPLES, NULL /*&input_channels*/, NULL /*&output_channels*/);
|
||||
|
@ -76,11 +91,11 @@ static void update_format_info(libvgmstream_priv_t* priv) {
|
|||
|
||||
fmt->channels = v->channels;
|
||||
fmt->input_channels = 0;
|
||||
vgmstream_mixing_enable(v, 0, &fmt->input_channels, &fmt->channels);
|
||||
vgmstream_mixing_enable(v, 0, &fmt->input_channels, &fmt->channels); //query
|
||||
fmt->channel_layout = v->channel_layout;
|
||||
|
||||
fmt->sample_type = api_get_output_sample_type(priv);
|
||||
fmt->sample_size = api_get_sample_size(fmt->sample_type);
|
||||
fmt->sample_format = api_get_output_sample_type(priv);
|
||||
fmt->sample_size = api_get_sample_size(fmt->sample_format);
|
||||
|
||||
fmt->sample_rate = v->sample_rate;
|
||||
|
||||
|
@ -105,26 +120,58 @@ static void update_format_info(libvgmstream_priv_t* priv) {
|
|||
}
|
||||
}
|
||||
|
||||
LIBVGMSTREAM_API int libvgmstream_open_stream(libvgmstream_t* lib, libvgmstream_options_t* opt) {
|
||||
if (!lib ||!lib->priv)
|
||||
return LIBVGMSTREAM_ERROR_GENERIC;
|
||||
if (!opt || !opt->libsf || opt->subsong_index < 0)
|
||||
// apply config if data + config is loaded and not already loaded
|
||||
void api_apply_config(libvgmstream_priv_t* priv) {
|
||||
if (priv->setup_done)
|
||||
return;
|
||||
if (!priv->vgmstream)
|
||||
return;
|
||||
|
||||
apply_config(priv);
|
||||
prepare_mixing(priv);
|
||||
|
||||
update_position(priv);
|
||||
update_format_info(priv);
|
||||
|
||||
priv->setup_done = true;
|
||||
}
|
||||
|
||||
static void load_vgmstream(libvgmstream_priv_t* priv, libstreamfile_t* libsf, int subsong_index) {
|
||||
STREAMFILE* sf_api = open_api_streamfile(libsf);
|
||||
if (!sf_api)
|
||||
return;
|
||||
|
||||
//TODO: handle format_id
|
||||
|
||||
sf_api->stream_index = subsong_index;
|
||||
priv->vgmstream = init_vgmstream_from_STREAMFILE(sf_api);
|
||||
close_streamfile(sf_api);
|
||||
}
|
||||
|
||||
LIBVGMSTREAM_API int libvgmstream_open_stream(libvgmstream_t* lib, libstreamfile_t* libsf, int subsong_index) {
|
||||
if (!lib ||!lib->priv || !libsf)
|
||||
return LIBVGMSTREAM_ERROR_GENERIC;
|
||||
|
||||
// close loaded song if any + reset
|
||||
libvgmstream_close_stream(lib);
|
||||
|
||||
libvgmstream_priv_t* priv = lib->priv;
|
||||
if (subsong_index < 0)
|
||||
return LIBVGMSTREAM_ERROR_GENERIC;
|
||||
|
||||
load_vgmstream(priv, opt);
|
||||
load_vgmstream(priv, libsf, subsong_index);
|
||||
if (!priv->vgmstream)
|
||||
return LIBVGMSTREAM_ERROR_GENERIC;
|
||||
apply_config(priv);
|
||||
prepare_mixing(priv, opt);
|
||||
update_position(priv);
|
||||
|
||||
update_format_info(priv);
|
||||
|
||||
// apply now if possible to update format info
|
||||
if (priv->config_loaded) {
|
||||
api_apply_config(priv);
|
||||
}
|
||||
else {
|
||||
// no config: just update info (apply_config will be called later)
|
||||
update_position(priv);
|
||||
update_format_info(priv);
|
||||
}
|
||||
|
||||
return LIBVGMSTREAM_OK;
|
||||
}
|
||||
|
@ -138,6 +185,8 @@ LIBVGMSTREAM_API void libvgmstream_close_stream(libvgmstream_t* lib) {
|
|||
|
||||
close_vgmstream(priv->vgmstream);
|
||||
priv->vgmstream = NULL;
|
||||
priv->setup_done = false;
|
||||
//priv->config_loaded = false; // loaded config still applies (_close is also called on _open)
|
||||
|
||||
libvgmstream_priv_reset(priv, true);
|
||||
}
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "api_internal.h"
|
||||
#include "mixing.h"
|
||||
#include "render.h"
|
||||
#include "../util/log.h"
|
||||
|
||||
|
||||
static bool reset_buf(libvgmstream_priv_t* priv) {
|
||||
|
@ -46,15 +47,16 @@ static void update_buf(libvgmstream_priv_t* priv, int samples_done) {
|
|||
priv->buf.bytes = samples_done * priv->buf.sample_size * priv->buf.channels;
|
||||
//priv->buf.consumed = 0; //external
|
||||
|
||||
// mark done if this buf reached EOF
|
||||
if (!priv->pos.play_forever) {
|
||||
priv->decode_done = (priv->pos.current >= priv->pos.play_samples);
|
||||
priv->pos.current += samples_done;
|
||||
priv->decode_done = (priv->pos.current >= priv->pos.play_samples);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// update decoder info based on last render, though at the moment it's all fixed
|
||||
static void update_decoder_info(libvgmstream_priv_t* priv, int samples_done) {
|
||||
static void update_decoder_info(libvgmstream_priv_t* priv) {
|
||||
|
||||
// output copy
|
||||
priv->dec.buf = priv->buf.data;
|
||||
|
@ -68,6 +70,13 @@ LIBVGMSTREAM_API int libvgmstream_render(libvgmstream_t* lib) {
|
|||
return LIBVGMSTREAM_ERROR_GENERIC;
|
||||
|
||||
libvgmstream_priv_t* priv = lib->priv;
|
||||
|
||||
// setup if not called (mainly to make sure mixing is enabled) //TODO: handle internally
|
||||
// (for cases where _open_stream is called but not _setup)
|
||||
if (!priv->setup_done) {
|
||||
api_apply_config(priv);
|
||||
}
|
||||
|
||||
if (priv->decode_done)
|
||||
return LIBVGMSTREAM_ERROR_GENERIC;
|
||||
|
||||
|
@ -84,7 +93,7 @@ LIBVGMSTREAM_API int libvgmstream_render(libvgmstream_t* lib) {
|
|||
|
||||
int decoded = render_main(&ssrc, priv->vgmstream);
|
||||
update_buf(priv, decoded);
|
||||
update_decoder_info(priv, decoded);
|
||||
update_decoder_info(priv);
|
||||
|
||||
return LIBVGMSTREAM_OK;
|
||||
}
|
||||
|
@ -161,6 +170,10 @@ LIBVGMSTREAM_API void libvgmstream_seek(libvgmstream_t* lib, int64_t sample) {
|
|||
seek_vgmstream(priv->vgmstream, sample);
|
||||
|
||||
priv->pos.current = priv->vgmstream->pstate.play_position;
|
||||
|
||||
// update flags just in case
|
||||
update_buf(priv, 0);
|
||||
update_decoder_info(priv);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -12,28 +12,33 @@ static int get_internal_log_level(libvgmstream_loglevel_t level) {
|
|||
}
|
||||
}
|
||||
|
||||
LIBVGMSTREAM_API void libvgmstream_set_log(libvgmstream_log_t* cfg) {
|
||||
if (!cfg)
|
||||
return;
|
||||
|
||||
int ilevel = get_internal_log_level(cfg->level);
|
||||
if (cfg->stdout_callback) {
|
||||
//vgmstream_set_log_stdout(ilevel);
|
||||
vgm_log_set_callback(NULL, ilevel, 1, NULL);
|
||||
LIBVGMSTREAM_API void libvgmstream_set_log(libvgmstream_loglevel_t level, void (*callback)(int level, const char* str)) {
|
||||
int ilevel = get_internal_log_level(level);
|
||||
if (callback) {
|
||||
vgm_log_set_callback(NULL, ilevel, 0, callback);
|
||||
}
|
||||
else {
|
||||
//vgmstream_set_log_callback(ilevel, cfg->callback);
|
||||
vgm_log_set_callback(NULL, ilevel, 0, cfg->callback);
|
||||
vgm_log_set_callback(NULL, ilevel, 1, NULL);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
LIBVGMSTREAM_API const char** libvgmstream_get_extensions(size_t* size) {
|
||||
return vgmstream_get_formats(size);
|
||||
LIBVGMSTREAM_API const char** libvgmstream_get_extensions(int* size) {
|
||||
if (!size)
|
||||
return NULL;
|
||||
size_t tmp = 0;
|
||||
const char** list = vgmstream_get_formats(&tmp);
|
||||
*size = tmp;
|
||||
return list;
|
||||
}
|
||||
|
||||
LIBVGMSTREAM_API const char** libvgmstream_get_common_extensions(size_t* size) {
|
||||
return vgmstream_get_common_formats(size);
|
||||
LIBVGMSTREAM_API const char** libvgmstream_get_common_extensions(int* size) {
|
||||
if (!size)
|
||||
return NULL;
|
||||
size_t tmp = 0;
|
||||
const char** list = vgmstream_get_common_formats(&tmp);
|
||||
*size = tmp;
|
||||
return list;
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -33,31 +33,36 @@ typedef struct {
|
|||
|
||||
} libvgmstream_priv_buf_t;
|
||||
|
||||
// used to calculate and stop stream (to be removed once VGMSTREAM can stop on its own)
|
||||
typedef struct {
|
||||
int64_t play_forever;
|
||||
int64_t play_samples;
|
||||
int64_t current;
|
||||
} libvgmstream_priv_position_t;
|
||||
|
||||
/* vgmstream context/handle */
|
||||
// vgmstream context/handle
|
||||
typedef struct {
|
||||
libvgmstream_format_t fmt; // externally exposed
|
||||
libvgmstream_decoder_t dec; // externally exposed
|
||||
// externally exposed to API
|
||||
libvgmstream_format_t fmt;
|
||||
libvgmstream_decoder_t dec;
|
||||
|
||||
libvgmstream_config_t cfg; // internal copy
|
||||
// internals
|
||||
libvgmstream_config_t cfg;
|
||||
|
||||
VGMSTREAM* vgmstream;
|
||||
|
||||
libvgmstream_priv_buf_t buf;
|
||||
libvgmstream_priv_position_t pos;
|
||||
|
||||
bool config_loaded;
|
||||
bool setup_done;
|
||||
bool decode_done;
|
||||
} libvgmstream_priv_t;
|
||||
|
||||
|
||||
void libvgmstream_priv_reset(libvgmstream_priv_t* priv, bool reset_buf);
|
||||
libvgmstream_sample_t api_get_output_sample_type(libvgmstream_priv_t* priv);
|
||||
int api_get_sample_size(libvgmstream_sample_t sample_type);
|
||||
void libvgmstream_priv_reset(libvgmstream_priv_t* priv, bool full);
|
||||
libvgmstream_sfmt_t api_get_output_sample_type(libvgmstream_priv_t* priv);
|
||||
int api_get_sample_size(libvgmstream_sfmt_t sample_format);
|
||||
void api_apply_config(libvgmstream_priv_t* priv);
|
||||
|
||||
STREAMFILE* open_api_streamfile(libstreamfile_t* libsf);
|
||||
|
||||
|
|
|
@ -5,63 +5,23 @@ static libstreamfile_t* libstreamfile_from_streamfile(STREAMFILE* sf);
|
|||
/* libstreamfile_t for external use, as a default implementation calling some internal SF */
|
||||
|
||||
typedef struct {
|
||||
int64_t offset;
|
||||
int64_t size;
|
||||
STREAMFILE* sf;
|
||||
char name[PATH_LIMIT];
|
||||
} libsf_priv_t;
|
||||
|
||||
static int libsf_read(void* user_data, uint8_t* dst, int dst_size) {
|
||||
static int libsf_read(void* user_data, uint8_t* dst, int64_t offset, int length) {
|
||||
libsf_priv_t* priv = user_data;
|
||||
if (!priv || !dst)
|
||||
return 0;
|
||||
|
||||
int bytes = priv->sf->read(priv->sf, dst, priv->offset, dst_size);
|
||||
priv->offset += bytes;
|
||||
|
||||
return bytes;
|
||||
}
|
||||
|
||||
static int64_t libsf_seek(void* user_data, int64_t offset, int whence) {
|
||||
libsf_priv_t* priv = user_data;
|
||||
if (!priv)
|
||||
return -1;
|
||||
|
||||
switch (whence) {
|
||||
case LIBSTREAMFILE_SEEK_SET: /* absolute */
|
||||
break;
|
||||
case LIBSTREAMFILE_SEEK_CUR: /* relative to current */
|
||||
offset += priv->offset;
|
||||
break;
|
||||
case LIBSTREAMFILE_SEEK_END: /* relative to file end (should be negative) */
|
||||
offset += priv->size;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* clamp offset like fseek */
|
||||
if (offset > priv->size)
|
||||
offset = priv->size;
|
||||
else if (offset < 0)
|
||||
offset = 0;
|
||||
|
||||
/* main seek */
|
||||
priv->offset = offset;
|
||||
return 0;
|
||||
return priv->sf->read(priv->sf, dst, offset, length);
|
||||
}
|
||||
|
||||
static int64_t libsf_get_size(void* user_data) {
|
||||
libsf_priv_t* priv = user_data;
|
||||
if (!priv)
|
||||
return 0;
|
||||
return priv->size;
|
||||
return priv->sf->get_size(priv->sf);
|
||||
}
|
||||
|
||||
static const char* libsf_get_name(void* user_data) {
|
||||
libsf_priv_t* priv = user_data;
|
||||
if (!priv)
|
||||
return NULL;
|
||||
|
||||
if (priv->name[0] == '\0') {
|
||||
priv->sf->get_name(priv->sf, priv->name, sizeof(priv->name));
|
||||
|
@ -72,7 +32,8 @@ static const char* libsf_get_name(void* user_data) {
|
|||
|
||||
static libstreamfile_t* libsf_open(void* user_data, const char* filename) {
|
||||
libsf_priv_t* priv = user_data;
|
||||
if (!priv || !priv->sf || !filename)
|
||||
|
||||
if (!filename)
|
||||
return NULL;
|
||||
|
||||
STREAMFILE* sf = priv->sf->open(priv->sf, filename, 0);
|
||||
|
@ -104,14 +65,11 @@ static libstreamfile_t* libstreamfile_from_streamfile(STREAMFILE* sf) {
|
|||
if (!sf)
|
||||
return NULL;
|
||||
|
||||
libstreamfile_t* libsf = NULL;
|
||||
libsf_priv_t* priv = NULL;
|
||||
|
||||
libsf = calloc(1, sizeof(libstreamfile_t));
|
||||
libstreamfile_t* libsf = calloc(1, sizeof(libstreamfile_t));
|
||||
if (!libsf) goto fail;
|
||||
|
||||
libsf->read = libsf_read;
|
||||
libsf->seek = libsf_seek;
|
||||
libsf->get_size = libsf_get_size;
|
||||
libsf->get_name = libsf_get_name;
|
||||
libsf->open = libsf_open;
|
||||
|
|
|
@ -18,10 +18,10 @@ typedef struct {
|
|||
char name[PATH_LIMIT];
|
||||
} cache_priv_t;
|
||||
|
||||
static int cache_read(void* user_data, uint8_t* dst, int dst_size) {
|
||||
static int cache_read(void* user_data, uint8_t* dst, int64_t offset, int length) {
|
||||
cache_priv_t* priv = user_data;
|
||||
size_t read_total = 0;
|
||||
if (!dst || dst_size <= 0)
|
||||
if (!dst || length <= 0 || offset < 0)
|
||||
return 0;
|
||||
|
||||
/* is the part of the requested length in the buffer? */
|
||||
|
@ -30,19 +30,22 @@ static int cache_read(void* user_data, uint8_t* dst, int dst_size) {
|
|||
int buf_into = (int)(priv->offset - priv->buf_offset);
|
||||
|
||||
buf_limit = priv->valid_size - buf_into;
|
||||
if (buf_limit > dst_size)
|
||||
buf_limit = dst_size;
|
||||
if (buf_limit > length)
|
||||
buf_limit = length;
|
||||
|
||||
memcpy(dst, priv->buf + buf_into, buf_limit);
|
||||
read_total += buf_limit;
|
||||
dst_size -= buf_limit;
|
||||
length -= buf_limit;
|
||||
priv->offset += buf_limit;
|
||||
dst += buf_limit;
|
||||
}
|
||||
|
||||
/* possible if all data was copied to buf and FD closed */
|
||||
if (!priv->libsf)
|
||||
return read_total;
|
||||
|
||||
/* read the rest of the requested length */
|
||||
while (dst_size > 0) {
|
||||
while (length > 0) {
|
||||
size_t buf_limit;
|
||||
|
||||
/* ignore requests at EOF */
|
||||
|
@ -52,18 +55,15 @@ static int cache_read(void* user_data, uint8_t* dst, int dst_size) {
|
|||
break;
|
||||
}
|
||||
|
||||
/* position to new offset */
|
||||
priv->libsf->seek(priv, priv->offset, 0);
|
||||
|
||||
/* fill the buffer (offset now is beyond buf_offset) */
|
||||
priv->buf_offset = priv->offset;
|
||||
priv->valid_size = priv->libsf->read(priv, priv->buf, priv->buf_size);
|
||||
priv->valid_size = priv->libsf->read(priv, priv->buf, priv->buf_offset, priv->buf_size);
|
||||
|
||||
/* decide how much must be read this time */
|
||||
if (dst_size > priv->buf_size)
|
||||
if (length > priv->buf_size)
|
||||
buf_limit = priv->buf_size;
|
||||
else
|
||||
buf_limit = dst_size;
|
||||
buf_limit = length;
|
||||
|
||||
/* give up on partial reads (EOF) */
|
||||
if (priv->valid_size < buf_limit) {
|
||||
|
@ -77,40 +77,14 @@ static int cache_read(void* user_data, uint8_t* dst, int dst_size) {
|
|||
memcpy(dst, priv->buf, buf_limit);
|
||||
priv->offset += buf_limit;
|
||||
read_total += buf_limit;
|
||||
dst_size -= buf_limit;
|
||||
length -= buf_limit;
|
||||
dst += buf_limit;
|
||||
}
|
||||
|
||||
priv->offset = offset; /* last fread offset */
|
||||
return read_total;
|
||||
}
|
||||
|
||||
static int64_t cache_seek(void* user_data, int64_t offset, int whence) {
|
||||
cache_priv_t* priv = user_data;
|
||||
|
||||
switch (whence) {
|
||||
case LIBSTREAMFILE_SEEK_SET: /* absolute */
|
||||
break;
|
||||
case LIBSTREAMFILE_SEEK_CUR: /* relative to current */
|
||||
offset += priv->offset;
|
||||
break;
|
||||
case LIBSTREAMFILE_SEEK_END: /* relative to file end (should be negative) */
|
||||
offset += priv->file_size;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
/* clamp offset like fseek */
|
||||
if (offset > priv->file_size)
|
||||
offset = priv->file_size;
|
||||
else if (offset < 0)
|
||||
offset = 0;
|
||||
|
||||
/* main seek */
|
||||
priv->offset = offset;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int64_t cache_get_size(void* user_data) {
|
||||
cache_priv_t* priv = user_data;
|
||||
return priv->file_size;
|
||||
|
@ -168,7 +142,6 @@ LIBVGMSTREAM_API libstreamfile_t* libstreamfile_open_buffered(libstreamfile_t* e
|
|||
if (!libsf) goto fail;
|
||||
|
||||
libsf->read = cache_read;
|
||||
libsf->seek = cache_seek;
|
||||
libsf->get_size = cache_get_size;
|
||||
libsf->get_name = cache_get_name;
|
||||
libsf->open = cache_open;
|
||||
|
|
43
Frameworks/vgmstream/vgmstream/src/base/codec_info.c
Normal file
43
Frameworks/vgmstream/vgmstream/src/base/codec_info.c
Normal file
|
@ -0,0 +1,43 @@
|
|||
#include "codec_info.h"
|
||||
|
||||
//TODO: move to root folder?
|
||||
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 vorbis_custom_decoder;
|
||||
#endif
|
||||
extern const codec_info_t tac_decoder;
|
||||
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;
|
||||
|
||||
const codec_info_t* codec_get_info(VGMSTREAM* v) {
|
||||
switch(v->coding_type) {
|
||||
case coding_CRI_HCA:
|
||||
return &hca_decoder;
|
||||
case coding_KA1A:
|
||||
return &ka1a_decoder;
|
||||
case coding_UBI_MPEG:
|
||||
return &ubimpeg_decoder;
|
||||
#ifdef VGM_USE_VORBIS
|
||||
case coding_VORBIS_custom:
|
||||
return &vorbis_custom_decoder;
|
||||
#endif
|
||||
case coding_TAC:
|
||||
return &tac_decoder;
|
||||
case coding_COMPRESSWAVE:
|
||||
return &compresswave_decoder;
|
||||
#ifdef VGM_USE_SPEEX
|
||||
case coding_SPEEX:
|
||||
return &speex_decoder;
|
||||
#endif
|
||||
case coding_IMUSE:
|
||||
return &imuse_decoder;
|
||||
case coding_MIO:
|
||||
return &mio_decoder;
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
33
Frameworks/vgmstream/vgmstream/src/base/codec_info.h
Normal file
33
Frameworks/vgmstream/vgmstream/src/base/codec_info.h
Normal file
|
@ -0,0 +1,33 @@
|
|||
#ifndef _CODEC_INFO_H
|
||||
#define _CODEC_INFO_H
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "../vgmstream.h"
|
||||
#include "../base/sbuf.h"
|
||||
|
||||
/* Class-like definition for codecs.
|
||||
*/
|
||||
typedef struct {
|
||||
//int (*init)();
|
||||
sfmt_t sample_type; // fixed for most cases; if not set will be assumed to be PCM16
|
||||
sfmt_t (*get_sample_type)(VGMSTREAM* v); //variable for codecs with variations depending on data
|
||||
|
||||
bool (*decode_frame)(VGMSTREAM* v);
|
||||
void (*free)(void* codec_data);
|
||||
void (*reset)(void* codec_data);
|
||||
void (*seek)(VGMSTREAM* v, int32_t num_sample);
|
||||
|
||||
// info for vgmstream
|
||||
//uint32_t flags;
|
||||
// alloc size of effect's private data (don't set to manage manually in init/free)
|
||||
//int priv_size;
|
||||
|
||||
//int sample_type;
|
||||
//int get_sample_type();
|
||||
} codec_info_t;
|
||||
|
||||
|
||||
const codec_info_t* codec_get_info(VGMSTREAM* v);
|
||||
|
||||
#endif
|
|
@ -5,6 +5,7 @@
|
|||
#include "mixing.h"
|
||||
#include "plugins.h"
|
||||
#include "sbuf.h"
|
||||
#include "codec_info.h"
|
||||
|
||||
#include "../util/log.h"
|
||||
#include "decode_state.h"
|
||||
|
@ -38,15 +39,17 @@ void decode_free(VGMSTREAM* vgmstream) {
|
|||
|
||||
if (!vgmstream->codec_data)
|
||||
return;
|
||||
|
||||
const codec_info_t* codec_info = codec_get_info(vgmstream);
|
||||
if (codec_info) {
|
||||
codec_info->free(vgmstream->codec_data);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
if (vgmstream->coding_type == coding_OGG_VORBIS) {
|
||||
free_ogg_vorbis(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_VORBIS_custom) {
|
||||
free_vorbis_custom(vgmstream->codec_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vgmstream->coding_type == coding_CIRCUS_VQ) {
|
||||
|
@ -57,14 +60,6 @@ void decode_free(VGMSTREAM* vgmstream) {
|
|||
free_relic(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_CRI_HCA) {
|
||||
free_hca(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_TAC) {
|
||||
free_tac(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_ICE_RANGE ||
|
||||
vgmstream->coding_type == coding_ICE_DCT) {
|
||||
free_ice(vgmstream->codec_data);
|
||||
|
@ -74,26 +69,14 @@ void decode_free(VGMSTREAM* vgmstream) {
|
|||
free_ubi_adpcm(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_IMUSE) {
|
||||
free_imuse(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_ONGAKUKAN_ADPCM) {
|
||||
free_ongakukan_adp(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_COMPRESSWAVE) {
|
||||
free_compresswave(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_EA_MT) {
|
||||
free_ea_mt(vgmstream->codec_data, vgmstream->channels);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_KA1A) {
|
||||
free_ka1a(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
if (vgmstream->coding_type == coding_FFmpeg) {
|
||||
free_ffmpeg(vgmstream->codec_data);
|
||||
|
@ -140,12 +123,6 @@ void decode_free(VGMSTREAM* vgmstream) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef VGM_USE_SPEEX
|
||||
if (vgmstream->coding_type == coding_SPEEX) {
|
||||
free_speex(vgmstream->codec_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vgmstream->coding_type == coding_ACM) {
|
||||
free_acm(vgmstream->codec_data);
|
||||
}
|
||||
|
@ -162,6 +139,12 @@ void decode_seek(VGMSTREAM* vgmstream) {
|
|||
if (!vgmstream->codec_data)
|
||||
return;
|
||||
|
||||
const codec_info_t* codec_info = codec_get_info(vgmstream);
|
||||
if (codec_info) {
|
||||
codec_info->seek(vgmstream, vgmstream->loop_current_sample);
|
||||
return;
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_CIRCUS_VQ) {
|
||||
seek_circus_vq(vgmstream->codec_data, vgmstream->loop_current_sample);
|
||||
}
|
||||
|
@ -170,14 +153,6 @@ void decode_seek(VGMSTREAM* vgmstream) {
|
|||
seek_relic(vgmstream->codec_data, vgmstream->loop_current_sample);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_CRI_HCA) {
|
||||
loop_hca(vgmstream->codec_data, vgmstream->loop_current_sample);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_TAC) {
|
||||
seek_tac(vgmstream->codec_data, vgmstream->loop_current_sample);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_ICE_RANGE ||
|
||||
vgmstream->coding_type == coding_ICE_DCT) {
|
||||
seek_ice(vgmstream->codec_data, vgmstream->loop_current_sample);
|
||||
|
@ -187,34 +162,18 @@ void decode_seek(VGMSTREAM* vgmstream) {
|
|||
seek_ubi_adpcm(vgmstream->codec_data, vgmstream->loop_current_sample);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_IMUSE) {
|
||||
seek_imuse(vgmstream->codec_data, vgmstream->loop_current_sample);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_ONGAKUKAN_ADPCM) {
|
||||
seek_ongakukan_adp(vgmstream->codec_data, vgmstream->loop_current_sample);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_COMPRESSWAVE) {
|
||||
seek_compresswave(vgmstream->codec_data, vgmstream->loop_current_sample);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_EA_MT) {
|
||||
seek_ea_mt(vgmstream, vgmstream->loop_current_sample);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_KA1A) {
|
||||
seek_ka1a(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);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_VORBIS_custom) {
|
||||
seek_vorbis_custom(vgmstream, vgmstream->loop_current_sample);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
|
@ -241,12 +200,6 @@ void decode_seek(VGMSTREAM* vgmstream) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef VGM_USE_SPEEX
|
||||
if (vgmstream->coding_type == coding_SPEEX) {
|
||||
seek_speex(vgmstream, vgmstream->loop_current_sample);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VGM_USE_MPEG
|
||||
if (vgmstream->coding_type == coding_MPEG_custom ||
|
||||
vgmstream->coding_type == coding_MPEG_ealayer3 ||
|
||||
|
@ -269,14 +222,16 @@ void decode_reset(VGMSTREAM* vgmstream) {
|
|||
if (!vgmstream->codec_data)
|
||||
return;
|
||||
|
||||
const codec_info_t* codec_info = codec_get_info(vgmstream);
|
||||
if (codec_info) {
|
||||
codec_info->reset(vgmstream->codec_data);
|
||||
return;
|
||||
}
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
if (vgmstream->coding_type == coding_OGG_VORBIS) {
|
||||
reset_ogg_vorbis(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_VORBIS_custom) {
|
||||
reset_vorbis_custom(vgmstream);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (vgmstream->coding_type == coding_CIRCUS_VQ) {
|
||||
|
@ -287,14 +242,6 @@ void decode_reset(VGMSTREAM* vgmstream) {
|
|||
reset_relic(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_CRI_HCA) {
|
||||
reset_hca(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_TAC) {
|
||||
reset_tac(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_ICE_RANGE ||
|
||||
vgmstream->coding_type == coding_ICE_DCT) {
|
||||
reset_ice(vgmstream->codec_data);
|
||||
|
@ -304,26 +251,14 @@ void decode_reset(VGMSTREAM* vgmstream) {
|
|||
reset_ubi_adpcm(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_IMUSE) {
|
||||
reset_imuse(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_ONGAKUKAN_ADPCM) {
|
||||
reset_ongakukan_adp(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_COMPRESSWAVE) {
|
||||
reset_compresswave(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_EA_MT) {
|
||||
reset_ea_mt(vgmstream);
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_KA1A) {
|
||||
reset_ka1a(vgmstream->codec_data);
|
||||
}
|
||||
|
||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||
if (vgmstream->coding_type == coding_MP4_AAC) {
|
||||
reset_mp4_aac(vgmstream);
|
||||
|
@ -364,12 +299,6 @@ void decode_reset(VGMSTREAM* vgmstream) {
|
|||
}
|
||||
#endif
|
||||
|
||||
#ifdef VGM_USE_SPEEX
|
||||
if (vgmstream->coding_type == coding_SPEEX) {
|
||||
reset_speex(vgmstream->codec_data);
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
if (vgmstream->coding_type == coding_FFmpeg) {
|
||||
reset_ffmpeg(vgmstream->codec_data);
|
||||
|
@ -433,7 +362,6 @@ int decode_get_samples_per_frame(VGMSTREAM* vgmstream) {
|
|||
return 1;
|
||||
#ifdef VGM_USE_VORBIS
|
||||
case coding_OGG_VORBIS:
|
||||
case coding_VORBIS_custom:
|
||||
#endif
|
||||
#ifdef VGM_USE_MPEG
|
||||
case coding_MPEG_custom:
|
||||
|
@ -586,18 +514,12 @@ int decode_get_samples_per_frame(VGMSTREAM* vgmstream) {
|
|||
return 0; /* varies per frame */
|
||||
case coding_ONGAKUKAN_ADPCM:
|
||||
return 0; /* actually 1. */
|
||||
case coding_COMPRESSWAVE:
|
||||
return 0; /* multiple of 2 */
|
||||
case coding_EA_MT:
|
||||
return 0; /* 432, but variable in looped files */
|
||||
case coding_CIRCUS_VQ:
|
||||
return 0;
|
||||
case coding_RELIC:
|
||||
return 0; /* 512 */
|
||||
case coding_CRI_HCA:
|
||||
return 0; /* 1024 - delay/padding (which can be bigger than 1024) */
|
||||
case coding_TAC:
|
||||
return 0; /* 1024 - delay/padding */
|
||||
case coding_ICE_RANGE:
|
||||
case coding_ICE_DCT:
|
||||
return 0; /* ~100 (range), ~16 (DCT) */
|
||||
|
@ -612,10 +534,6 @@ int decode_get_samples_per_frame(VGMSTREAM* vgmstream) {
|
|||
#ifdef VGM_USE_CELT
|
||||
case coding_CELT_FSB:
|
||||
return 0; /* 512? */
|
||||
#endif
|
||||
#ifdef VGM_USE_SPEEX
|
||||
case coding_SPEEX:
|
||||
return 0;
|
||||
#endif
|
||||
default:
|
||||
return 0;
|
||||
|
@ -807,12 +725,9 @@ int decode_get_frame_size(VGMSTREAM* vgmstream) {
|
|||
/* UBI_ADPCM: varies per mode? */
|
||||
/* IMUSE: VBR */
|
||||
/* EA_MT: VBR, frames of bit counts or PCM frames */
|
||||
/* COMPRESSWAVE: VBR/huffman bits */
|
||||
/* ATRAC9: CBR around 0x100-200 */
|
||||
/* CELT FSB: varies, usually 0x80-100 */
|
||||
/* SPEEX: varies, usually 0x40-60 */
|
||||
/* TAC: VBR around ~0x200-300 */
|
||||
/* Vorbis, MPEG, ACM, etc: varies */
|
||||
default: /* (VBR or managed by decoder) */
|
||||
return 0;
|
||||
}
|
||||
|
@ -875,6 +790,7 @@ static void decode_frames(sbuf_t* sdst, VGMSTREAM* vgmstream) {
|
|||
decode_state_t* ds = vgmstream->decode_state;
|
||||
sbuf_t* ssrc = &ds->sbuf;
|
||||
|
||||
const codec_info_t* codec_info = codec_get_info(vgmstream);
|
||||
|
||||
// fill the external buf by decoding N times; may read partially that buf
|
||||
while (sdst->filled < sdst->samples) {
|
||||
|
@ -882,12 +798,12 @@ static void decode_frames(sbuf_t* sdst, VGMSTREAM* vgmstream) {
|
|||
// decode new frame if prev one was consumed
|
||||
if (ssrc->filled == 0) {
|
||||
bool ok = false;
|
||||
switch (vgmstream->coding_type) {
|
||||
case coding_KA1A:
|
||||
ok = decode_ka1a_frame(vgmstream);
|
||||
break;
|
||||
default:
|
||||
goto decode_fail;
|
||||
|
||||
if (codec_info) {
|
||||
ok = codec_info->decode_frame(vgmstream);
|
||||
}
|
||||
else {
|
||||
goto decode_fail;
|
||||
}
|
||||
|
||||
if (!ok)
|
||||
|
@ -902,6 +818,9 @@ static void decode_frames(sbuf_t* sdst, VGMSTREAM* vgmstream) {
|
|||
goto decode_fail;
|
||||
}
|
||||
}
|
||||
else {
|
||||
num_empty = 0; //reset for discard loops
|
||||
}
|
||||
|
||||
if (ds->discard) {
|
||||
// decoder may signal that samples need to be discarded (ex. encoder delay or during loops)
|
||||
|
@ -1233,10 +1152,6 @@ void decode_vgmstream(sbuf_t* sdst, VGMSTREAM* vgmstream, int samples_to_do) {
|
|||
case coding_OGG_VORBIS:
|
||||
decode_ogg_vorbis(vgmstream->codec_data, buffer, samples_to_do, vgmstream->channels);
|
||||
break;
|
||||
|
||||
case coding_VORBIS_custom:
|
||||
decode_vorbis_custom(vgmstream, buffer, samples_to_do, vgmstream->channels);
|
||||
break;
|
||||
#endif
|
||||
case coding_CIRCUS_VQ:
|
||||
decode_circus_vq(vgmstream->codec_data, buffer, samples_to_do, vgmstream->channels);
|
||||
|
@ -1244,12 +1159,6 @@ void decode_vgmstream(sbuf_t* sdst, VGMSTREAM* vgmstream, int samples_to_do) {
|
|||
case coding_RELIC:
|
||||
decode_relic(&vgmstream->ch[0], vgmstream->codec_data, buffer, samples_to_do);
|
||||
break;
|
||||
case coding_CRI_HCA:
|
||||
decode_hca(vgmstream->codec_data, buffer, samples_to_do);
|
||||
break;
|
||||
case coding_TAC:
|
||||
decode_tac(vgmstream, buffer, samples_to_do);
|
||||
break;
|
||||
case coding_ICE_RANGE:
|
||||
case coding_ICE_DCT:
|
||||
decode_ice(vgmstream->codec_data, buffer, samples_to_do);
|
||||
|
@ -1482,11 +1391,6 @@ void decode_vgmstream(sbuf_t* sdst, VGMSTREAM* vgmstream, int samples_to_do) {
|
|||
case coding_CELT_FSB:
|
||||
decode_celt_fsb(vgmstream, buffer, samples_to_do, vgmstream->channels);
|
||||
break;
|
||||
#endif
|
||||
#ifdef VGM_USE_SPEEX
|
||||
case coding_SPEEX:
|
||||
decode_speex(vgmstream, buffer, samples_to_do);
|
||||
break;
|
||||
#endif
|
||||
case coding_ACM:
|
||||
decode_acm(vgmstream->codec_data, buffer, samples_to_do, vgmstream->channels);
|
||||
|
@ -1656,18 +1560,10 @@ void decode_vgmstream(sbuf_t* sdst, VGMSTREAM* vgmstream, int samples_to_do) {
|
|||
decode_ubi_adpcm(vgmstream, buffer, samples_to_do);
|
||||
break;
|
||||
|
||||
case coding_IMUSE:
|
||||
decode_imuse(vgmstream, buffer, samples_to_do);
|
||||
break;
|
||||
|
||||
case coding_ONGAKUKAN_ADPCM:
|
||||
decode_ongakukan_adp(vgmstream, buffer, samples_to_do);
|
||||
break;
|
||||
|
||||
case coding_COMPRESSWAVE:
|
||||
decode_compresswave(vgmstream->codec_data, buffer, samples_to_do);
|
||||
break;
|
||||
|
||||
case coding_EA_MT:
|
||||
for (ch = 0; ch < vgmstream->channels; ch++) {
|
||||
decode_ea_mt(vgmstream, buffer+ch, vgmstream->channels, samples_to_do, ch);
|
||||
|
|
|
@ -330,7 +330,7 @@ static STREAMFILE* get_vgmstream_average_bitrate_channel_streamfile(VGMSTREAM* v
|
|||
}
|
||||
|
||||
if (vgmstream->coding_type == coding_COMPRESSWAVE) {
|
||||
return compresswave_get_streamfile(vgmstream->codec_data);
|
||||
return compresswave_get_streamfile(vgmstream);
|
||||
}
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
|
|
|
@ -116,7 +116,7 @@ void mixer_process(mixer_t* mixer, sbuf_t* sbuf, int32_t current_pos) {
|
|||
|
||||
setup_mixbuf(mixer, sbuf);
|
||||
|
||||
// apply mixing ops in order. channesl in mixersmix may increase or decrease per op
|
||||
// apply mixing ops in order. channels in mixers may increase or decrease per op (set in sbuf)
|
||||
// - 2ch w/ "1+2,1u" = ch1+ch2, ch1(add and push rest) = 3ch: ch1' ch1+ch2 ch2
|
||||
// - 2ch w/ "1u" = downmix to 1ch (current_channels decreases once)
|
||||
for (int m = 0; m < mixer->chain_count; m++) {
|
||||
|
|
|
@ -125,8 +125,11 @@ void mixer_op_fade(mixer_t* mixer, mix_op_t* mix) {
|
|||
//TODO optimize for case 0?
|
||||
for (int s = 0; s < smix->filled; s++) {
|
||||
bool fade_applies = get_fade_gain(mix, &new_gain, current_subpos);
|
||||
if (!fade_applies) //TODO optimize?
|
||||
if (!fade_applies) { //TODO optimize?
|
||||
dst += channels;
|
||||
current_subpos++;
|
||||
continue;
|
||||
}
|
||||
|
||||
if (mix->ch_dst < 0) {
|
||||
for (int ch = 0; ch < channels; ch++) {
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
#include "mixer.h"
|
||||
#include "mixer_priv.h"
|
||||
#include "sbuf.h"
|
||||
#include "codec_info.h"
|
||||
|
||||
/* Wrapper/helpers for vgmstream's "mixer", which does main sample buffer transformations */
|
||||
|
||||
|
@ -143,9 +144,20 @@ void mixing_info(VGMSTREAM* vgmstream, int* p_input_channels, int* p_output_chan
|
|||
}
|
||||
|
||||
sfmt_t mixing_get_input_sample_type(VGMSTREAM* vgmstream) {
|
||||
|
||||
const codec_info_t* codec_info = codec_get_info(vgmstream);
|
||||
if (codec_info) {
|
||||
if (codec_info->sample_type)
|
||||
return codec_info->sample_type;
|
||||
if (codec_info->get_sample_type)
|
||||
return codec_info->get_sample_type(vgmstream);
|
||||
}
|
||||
|
||||
// TODO: on layered/segments, detect biggest value and use that (ex. if one of the layers uses flt > flt)
|
||||
switch(vgmstream->coding_type) {
|
||||
case coding_KA1A:
|
||||
#ifdef VGM_USE_VORBIS
|
||||
case coding_VORBIS_custom:
|
||||
#endif
|
||||
return SFMT_FLT;
|
||||
default:
|
||||
return SFMT_S16;
|
||||
|
|
|
@ -569,7 +569,7 @@ void mixing_macro_downmix(VGMSTREAM* vgmstream, int max /*, mapping_t output_map
|
|||
|
||||
void mixing_macro_output_sample_format(VGMSTREAM* vgmstream, sfmt_t type) {
|
||||
mixer_t* mixer = vgmstream->mixer;
|
||||
if (!mixer)
|
||||
if (!mixer || !type)
|
||||
return;
|
||||
|
||||
// optimization (may skip initializing mixer)
|
||||
|
@ -577,4 +577,5 @@ void mixing_macro_output_sample_format(VGMSTREAM* vgmstream, sfmt_t type) {
|
|||
if (input_fmt == type)
|
||||
return;
|
||||
mixer->force_type = type;
|
||||
mixer->has_non_fade = true;
|
||||
}
|
||||
|
|
|
@ -1,10 +1,16 @@
|
|||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
//#include <math.h>
|
||||
#include "../util.h"
|
||||
#include "sbuf.h"
|
||||
#include "../util/log.h"
|
||||
|
||||
// float-to-int modes
|
||||
//#define PCM16_ROUNDING_LRINT // potentially faster in some systems/compilers and much slower in others
|
||||
//#define PCM16_ROUNDING_HALF // rounding half + down (vorbis-style), more 'accurate' but slower
|
||||
|
||||
#ifdef PCM16_ROUNDING_HALF
|
||||
#include <math.h>
|
||||
#endif
|
||||
|
||||
void sbuf_init(sbuf_t* sbuf, sfmt_t format, void* buf, int samples, int channels) {
|
||||
memset(sbuf, 0, sizeof(sbuf_t));
|
||||
|
@ -48,6 +54,8 @@ void* sbuf_get_filled_buf(sbuf_t* sbuf) {
|
|||
}
|
||||
|
||||
void sbuf_consume(sbuf_t* sbuf, int samples) {
|
||||
if (samples == 0) //some discards
|
||||
return;
|
||||
int sample_size = sfmt_get_sample_size(sbuf->fmt);
|
||||
if (sample_size <= 0) //???
|
||||
return;
|
||||
|
@ -67,7 +75,7 @@ void sbuf_consume(sbuf_t* sbuf, int samples) {
|
|||
* alts for more accurate rounding could be:
|
||||
* - (int)floor(f)
|
||||
* - (int)(f < 0 ? f - 0.5f : f + 0.5f)
|
||||
* - (((int) (f1 + 32768.5)) - 32768)
|
||||
* - (((int) (f1 + 32767.5)) - 32767)
|
||||
* - etc
|
||||
* but since +-1 isn't really audible we'll just cast, as it's the fastest
|
||||
*
|
||||
|
@ -77,22 +85,22 @@ void sbuf_consume(sbuf_t* sbuf, int samples) {
|
|||
* It's slightly faster (~5%) but causes fuzzy PCM<>float<>PCM conversions.
|
||||
*/
|
||||
static inline int float_to_int(float val) {
|
||||
#if 1
|
||||
return (int)val;
|
||||
#if PCM16_ROUNDING_LRINT
|
||||
return lrintf(val);
|
||||
#elif defined(_MSC_VER)
|
||||
return (int)val;
|
||||
#else
|
||||
return lrintf(val);
|
||||
return (int)val;
|
||||
#endif
|
||||
}
|
||||
|
||||
static inline int double_to_int(double val) {
|
||||
#if 1
|
||||
return (int)val;
|
||||
#if PCM16_ROUNDING_LRINT
|
||||
return lrint(val);
|
||||
#elif defined(_MSC_VER)
|
||||
return (int)val;
|
||||
#else
|
||||
return lrint(val);
|
||||
return (int)val;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
@ -122,7 +130,7 @@ void sbuf_copy_to_f32(float* dst, sbuf_t* sbuf) {
|
|||
case SFMT_FLT: {
|
||||
float* src = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
dst[s] = src[s] * 32768.0f;
|
||||
dst[s] = src[s] * 32767.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -150,7 +158,7 @@ void sbuf_copy_from_f32(sbuf_t* sbuf, float* src) {
|
|||
case SFMT_FLT: {
|
||||
float* dst = sbuf->buf;
|
||||
for (int s = 0; s < sbuf->filled * sbuf->channels; s++) {
|
||||
dst[s] = src[s] / 32768.0f;
|
||||
dst[s] = src[s] / 32767.0f;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -175,23 +183,35 @@ int sbuf_get_copy_max(sbuf_t* sdst, sbuf_t* ssrc) {
|
|||
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++] = float_to_int(src[src_pos++] * value); \
|
||||
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, ssrc->filled);
|
||||
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) {
|
||||
|
@ -210,49 +230,54 @@ void sbuf_copy_segments(sbuf_t* sdst, sbuf_t* ssrc, int samples_copy) {
|
|||
int src_max = samples_copy * ssrc->channels;
|
||||
|
||||
// define all posible combos, probably there is a better way to handle this but...
|
||||
|
||||
if (sdst->fmt == SFMT_S16 && ssrc->fmt == SFMT_S16) {
|
||||
int16_t* dst = sdst->buf;
|
||||
// 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);
|
||||
}
|
||||
else if (sdst->fmt == SFMT_F32 && ssrc->fmt == SFMT_S16) {
|
||||
float* dst = sdst->buf;
|
||||
// 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);
|
||||
}
|
||||
else if ((sdst->fmt == SFMT_F32 && ssrc->fmt == SFMT_F32) || (sdst->fmt == SFMT_FLT && ssrc->fmt == SFMT_FLT)) {
|
||||
// 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);
|
||||
}
|
||||
// to s16
|
||||
else if (sdst->fmt == SFMT_S16 && ssrc->fmt == SFMT_F32) {
|
||||
// f32 > s16
|
||||
else if (ssrc->fmt == SFMT_F32 && sdst->fmt == SFMT_S16) {
|
||||
float* src = ssrc->buf;
|
||||
int16_t* dst = sdst->buf;
|
||||
float* src = ssrc->buf;
|
||||
sbuf_copy_segments_internal_s16(dst, src, src_pos, dst_pos, src_max, 1.0f);
|
||||
sbuf_copy_segments_internal_f16(dst, src, src_pos, dst_pos, src_max);
|
||||
}
|
||||
else if (sdst->fmt == SFMT_S16 && ssrc->fmt == SFMT_FLT) {
|
||||
// flt > s16
|
||||
else if (ssrc->fmt == SFMT_FLT && sdst->fmt == SFMT_S16) {
|
||||
float* src = ssrc->buf;
|
||||
int16_t* dst = sdst->buf;
|
||||
float* src = ssrc->buf;
|
||||
sbuf_copy_segments_internal_s16(dst, src, src_pos, dst_pos, src_max, 32768.0f);
|
||||
sbuf_copy_segments_internal_s16(dst, src, src_pos, dst_pos, src_max, 32767.0f);
|
||||
}
|
||||
// to f32
|
||||
else if (sdst->fmt == SFMT_F32 && ssrc->fmt == SFMT_FLT) {
|
||||
float* dst = sdst->buf;
|
||||
// f32 > flt
|
||||
else if (ssrc->fmt == SFMT_F32 && sdst->fmt == SFMT_FLT) {
|
||||
float* src = ssrc->buf;
|
||||
sbuf_copy_segments_internal_flt(dst, src, src_pos, dst_pos, src_max, 32768.0f);
|
||||
}
|
||||
// to flt
|
||||
else if (sdst->fmt == SFMT_FLT && ssrc->fmt == SFMT_S16) {
|
||||
float* dst = sdst->buf;
|
||||
int16_t* src = ssrc->buf;
|
||||
sbuf_copy_segments_internal_flt(dst, src, src_pos, dst_pos, src_max, (1/32768.0f));
|
||||
sbuf_copy_segments_internal_flt(dst, src, src_pos, dst_pos, src_max, (1.0f / 32767.0f));
|
||||
}
|
||||
else if (sdst->fmt == SFMT_FLT && ssrc->fmt == SFMT_F32) {
|
||||
float* dst = sdst->buf;
|
||||
// flt > f32
|
||||
else if (ssrc->fmt == SFMT_FLT && sdst->fmt == SFMT_F32) {
|
||||
float* src = ssrc->buf;
|
||||
sbuf_copy_segments_internal_flt(dst, src, src_pos, dst_pos, src_max, (1/32768.0f));
|
||||
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?
|
||||
|
@ -260,6 +285,14 @@ void sbuf_copy_segments(sbuf_t* sdst, sbuf_t* ssrc, int 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) \
|
||||
|
@ -270,14 +303,32 @@ void sbuf_copy_segments(sbuf_t* sdst, sbuf_t* ssrc, int samples_copy) {
|
|||
dst_pos += dst_ch_step; \
|
||||
} \
|
||||
\
|
||||
for (int s = src_filled; s < dst_expected; s++) { \
|
||||
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++] = 0; \
|
||||
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);
|
||||
|
||||
// float +-1.0 <> pcm +-32768.0
|
||||
#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++) { \
|
||||
|
@ -286,14 +337,10 @@ void sbuf_copy_segments(sbuf_t* sdst, sbuf_t* ssrc, int samples_copy) {
|
|||
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; \
|
||||
}
|
||||
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 +-32768.0
|
||||
// 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++) { \
|
||||
|
@ -302,68 +349,72 @@ void sbuf_copy_segments(sbuf_t* sdst, sbuf_t* ssrc, int samples_copy) {
|
|||
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; \
|
||||
}
|
||||
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
|
||||
// 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_expected) {
|
||||
int src_filled = ssrc->filled;
|
||||
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 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_filled, dst_expected, src_channels, dst_ch_step);
|
||||
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_filled, dst_expected, src_channels, dst_ch_step);
|
||||
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_filled, dst_expected, src_channels, dst_ch_step);
|
||||
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_s16(dst, src, src_pos, dst_pos, src_filled, dst_expected, src_channels, dst_ch_step, 1.0f);
|
||||
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_filled, dst_expected, src_channels, dst_ch_step, 32768.0f);
|
||||
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_filled, dst_expected, src_channels, dst_ch_step, 32768.0f);
|
||||
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_filled, dst_expected, src_channels, dst_ch_step, (1/32768.0f));
|
||||
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_filled, dst_expected, src_channels, dst_ch_step, (1/32768.0f));
|
||||
sbuf_copy_layers_internal_flt(dst, src, src_pos, dst_pos, src_copy, dst_max, src_channels, dst_ch_step, (1.0f / 32767.0f));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -428,3 +479,29 @@ void sbuf_fadeout(sbuf_t* sbuf, int start, int to_do, int fade_pos, int fade_dur
|
|||
int count = sbuf->filled - (start + to_do);
|
||||
sbuf_silence_part(sbuf, start + to_do, count);
|
||||
}
|
||||
|
||||
void sbuf_interleave(sbuf_t* sbuf, float** ibuf) {
|
||||
if (sbuf->fmt != SFMT_FLT)
|
||||
return;
|
||||
|
||||
// copy multidimensional buf (pcm[0]=[ch0,ch0,...], pcm[1]=[ch1,ch1,...])
|
||||
// to interleaved buf (buf[0]=ch0, sbuf[1]=ch1, sbuf[2]=ch0, sbuf[3]=ch1, ...)
|
||||
for (int ch = 0; ch < sbuf->channels; ch++) {
|
||||
/* channels should be in standard order unlike Ogg Vorbis (at least in FSB) */
|
||||
float* ptr = sbuf->buf;
|
||||
float* channel = ibuf[ch];
|
||||
|
||||
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 += sbuf->channels;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -57,4 +57,6 @@ 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);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -15,8 +15,7 @@ typedef struct {
|
|||
static size_t api_read(API_STREAMFILE* sf, uint8_t* dst, offv_t offset, size_t length) {
|
||||
void* user_data = sf->libsf->user_data;
|
||||
|
||||
sf->libsf->seek(sf->libsf->user_data, offset, LIBSTREAMFILE_SEEK_SET);
|
||||
return sf->libsf->read(user_data, dst, length);
|
||||
return sf->libsf->read(user_data, dst, offset, length);
|
||||
}
|
||||
|
||||
static size_t api_get_size(API_STREAMFILE* sf) {
|
||||
|
|
|
@ -288,13 +288,8 @@ int32_t ubi_adpcm_get_samples(ubi_adpcm_codec_data* data);
|
|||
|
||||
|
||||
/* imuse_decoder */
|
||||
typedef struct imuse_codec_data imuse_codec_data;
|
||||
|
||||
imuse_codec_data* init_imuse(STREAMFILE* sf, int channels);
|
||||
void decode_imuse(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do);
|
||||
void reset_imuse(imuse_codec_data* data);
|
||||
void seek_imuse(imuse_codec_data* data, int32_t num_sample);
|
||||
void free_imuse(imuse_codec_data* data);
|
||||
void* init_imuse_mcomp(STREAMFILE* sf, int channels);
|
||||
void* init_imuse_aifc(STREAMFILE* sf, uint32_t start_offset, int channels);
|
||||
|
||||
/* ongakukan_adp_decoder */
|
||||
typedef struct ongakukan_adp_data ongakukan_adp_data;
|
||||
|
@ -308,14 +303,8 @@ void free_ongakukan_adp(ongakukan_adp_data* data);
|
|||
int32_t ongakukan_adp_get_samples(ongakukan_adp_data* data);
|
||||
|
||||
/* compresswave_decoder */
|
||||
typedef struct compresswave_codec_data compresswave_codec_data;
|
||||
|
||||
compresswave_codec_data* init_compresswave(STREAMFILE* sf);
|
||||
void decode_compresswave(compresswave_codec_data* data, sample_t* outbuf, int32_t samples_to_do);
|
||||
void reset_compresswave(compresswave_codec_data* data);
|
||||
void seek_compresswave(compresswave_codec_data* data, int32_t num_sample);
|
||||
void free_compresswave(compresswave_codec_data* data);
|
||||
STREAMFILE* compresswave_get_streamfile(compresswave_codec_data* data);
|
||||
void* init_compresswave(STREAMFILE* sf);
|
||||
STREAMFILE* compresswave_get_streamfile(VGMSTREAM* v);
|
||||
|
||||
|
||||
/* ea_mt_decoder*/
|
||||
|
@ -346,10 +335,8 @@ int32_t relic_bytes_to_samples(size_t bytes, int channels, int bitrate);
|
|||
typedef struct hca_codec_data hca_codec_data;
|
||||
|
||||
hca_codec_data* init_hca(STREAMFILE* sf);
|
||||
void decode_hca(hca_codec_data* data, sample_t* outbuf, int32_t samples_to_do);
|
||||
void reset_hca(hca_codec_data* data);
|
||||
void loop_hca(hca_codec_data* data, int32_t num_sample);
|
||||
void free_hca(hca_codec_data* data);
|
||||
void free_hca(void* data);
|
||||
|
||||
clHCA_stInfo* hca_get_info(hca_codec_data* data);
|
||||
|
||||
typedef struct {
|
||||
|
@ -369,13 +356,7 @@ STREAMFILE* hca_get_streamfile(hca_codec_data* data);
|
|||
|
||||
|
||||
/* tac_decoder */
|
||||
typedef struct tac_codec_data tac_codec_data;
|
||||
|
||||
tac_codec_data* init_tac(STREAMFILE* sf);
|
||||
void decode_tac(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do);
|
||||
void reset_tac(tac_codec_data* data);
|
||||
void seek_tac(tac_codec_data* data, int32_t num_sample);
|
||||
void free_tac(tac_codec_data* data);
|
||||
void* init_tac(STREAMFILE* sf);
|
||||
|
||||
|
||||
/* ice_decoder */
|
||||
|
@ -389,13 +370,13 @@ void free_ice(ice_codec_data* data);
|
|||
|
||||
|
||||
/* ka1a_decoder */
|
||||
typedef struct ka1a_codec_data ka1a_codec_data;
|
||||
void* init_ka1a(int bitrate_mode, int channels_tracks);
|
||||
|
||||
ka1a_codec_data* init_ka1a(int bitrate_mode, int channels_tracks);
|
||||
void free_ka1a(ka1a_codec_data* data);
|
||||
void reset_ka1a(ka1a_codec_data* data);
|
||||
bool decode_ka1a_frame(VGMSTREAM* vgmstream);
|
||||
void seek_ka1a(VGMSTREAM* v, int32_t num_sample);
|
||||
/* ubimpeg_decoder */
|
||||
void* init_ubimpeg(uint32_t mode);
|
||||
|
||||
/* mio_decoder */
|
||||
void* init_mio(STREAMFILE* sf, int* p_loop_point);
|
||||
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
|
@ -438,6 +419,7 @@ typedef enum {
|
|||
VORBIS_SK, /* Silicon Knights AUD: "OggS" replaced by "SK" */
|
||||
VORBIS_VID1, /* Neversoft VID1: custom packet blocks/headers */
|
||||
VORBIS_AWC, /* Rockstar AWC: custom packet blocks/headers */
|
||||
VORBIS_OOR, /* Age .OOR: custom bitpacked pages (custom header + setup) */
|
||||
} vorbis_custom_t;
|
||||
|
||||
/* config for Wwise Vorbis (3 types for flexibility though not all combinations exist) */
|
||||
|
@ -466,14 +448,13 @@ typedef struct {
|
|||
|
||||
/* output (kinda ugly here but to simplify) */
|
||||
off_t data_start_offset;
|
||||
int64_t last_granule;
|
||||
|
||||
} vorbis_custom_config;
|
||||
|
||||
vorbis_custom_codec_data* init_vorbis_custom(STREAMFILE* sf, off_t start_offset, vorbis_custom_t type, vorbis_custom_config* config);
|
||||
void decode_vorbis_custom(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do, int channels);
|
||||
void reset_vorbis_custom(VGMSTREAM* vgmstream);
|
||||
void seek_vorbis_custom(VGMSTREAM* vgmstream, int32_t num_sample);
|
||||
void free_vorbis_custom(vorbis_custom_codec_data* data);
|
||||
void free_vorbis_custom(void* data);
|
||||
int32_t vorbis_custom_get_samples(VGMSTREAM* v);
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
|
@ -622,14 +603,8 @@ void free_celt_fsb(celt_codec_data* data);
|
|||
|
||||
#ifdef VGM_USE_SPEEX
|
||||
/* speex_decoder */
|
||||
typedef struct speex_codec_data speex_codec_data;
|
||||
|
||||
speex_codec_data* init_speex_ea(int channels);
|
||||
speex_codec_data* init_speex_torus(int channels);
|
||||
void decode_speex(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do);
|
||||
void reset_speex(speex_codec_data* data);
|
||||
void seek_speex(VGMSTREAM* vgmstream, int32_t num_sample);
|
||||
void free_speex(speex_codec_data* data);
|
||||
void* init_speex_ea(int channels);
|
||||
void* init_speex_torus(int channels);
|
||||
#endif
|
||||
|
||||
|
||||
|
|
|
@ -1,60 +0,0 @@
|
|||
#ifndef _CODING_UTILS_SAMPLES_
|
||||
#define _CODING_UTILS_SAMPLES_
|
||||
|
||||
/* sample helpers */
|
||||
//TODO maybe move to .c
|
||||
// (as .h can be inlined but these probably aren't called enough times that there is a notable boost)
|
||||
|
||||
typedef struct {
|
||||
int16_t* samples; /* current samples (pointer is moved once consumed) */
|
||||
int filled; /* samples left */
|
||||
int channels; /* max channels sample buf handles */
|
||||
//TODO may be more useful with filled+consumed and not moving *samples?
|
||||
} s16buf_t;
|
||||
|
||||
static inline void s16buf_silence(sample_t** p_outbuf, int32_t* p_samples_silence, int channels) {
|
||||
int samples_silence;
|
||||
|
||||
samples_silence = *p_samples_silence;
|
||||
|
||||
memset(*p_outbuf, 0, samples_silence * channels * sizeof(int16_t));
|
||||
|
||||
*p_outbuf += samples_silence * channels;
|
||||
*p_samples_silence -= samples_silence;
|
||||
}
|
||||
|
||||
static inline void s16buf_discard(sample_t** p_outbuf, s16buf_t* sbuf, int32_t* p_samples_discard) {
|
||||
int samples_discard;
|
||||
|
||||
samples_discard = *p_samples_discard;
|
||||
if (samples_discard > sbuf->filled)
|
||||
samples_discard = sbuf->filled;
|
||||
|
||||
/* just ignore part of samples */
|
||||
|
||||
sbuf->samples += samples_discard * sbuf->channels;
|
||||
sbuf->filled -= samples_discard;
|
||||
|
||||
*p_samples_discard -= samples_discard;
|
||||
}
|
||||
|
||||
/* copy, move and mark consumed samples */
|
||||
static inline void s16buf_consume(sample_t** p_outbuf, s16buf_t* sbuf, int32_t* p_samples_consume) {
|
||||
int samples_consume;
|
||||
|
||||
samples_consume = *p_samples_consume;
|
||||
if (samples_consume > sbuf->filled)
|
||||
samples_consume = sbuf->filled;
|
||||
|
||||
/* memcpy is safe when filled/samples_copy is 0 (but must pass non-NULL bufs) */
|
||||
memcpy(*p_outbuf, sbuf->samples, samples_consume * sbuf->channels * sizeof(int16_t));
|
||||
|
||||
sbuf->samples += samples_consume * sbuf->channels;
|
||||
sbuf->filled -= samples_consume;
|
||||
|
||||
*p_outbuf += samples_consume * sbuf->channels;
|
||||
*p_samples_consume -= samples_consume;
|
||||
}
|
||||
|
||||
|
||||
#endif /* _CODING_UTILS_SAMPLES_ */
|
|
@ -1,27 +1,45 @@
|
|||
#include "coding.h"
|
||||
#include "coding_utils_samples.h"
|
||||
#include "../base/decode_state.h"
|
||||
#include "../base/codec_info.h"
|
||||
#include "libs/compresswave_lib.h"
|
||||
|
||||
|
||||
#define COMPRESSWAVE_MAX_FRAME_SAMPLES 0x1000 /* arbitrary but should be multiple of 2 for 22050 mode */
|
||||
#define COMPRESSWAVE_MAX_FRAME_SAMPLES 512 // arbitrary, but should be multiple of 2 for 22050 mode
|
||||
#define COMPRESSWAVE_MAX_CHANNELS 2
|
||||
|
||||
/* opaque struct */
|
||||
struct compresswave_codec_data {
|
||||
/* config */
|
||||
typedef struct {
|
||||
STREAMFILE* sf;
|
||||
TCompressWaveData* cw;
|
||||
TCompressWaveData* handle;
|
||||
|
||||
/* frame state */
|
||||
int16_t* samples;
|
||||
int frame_samples;
|
||||
int16_t pbuf[COMPRESSWAVE_MAX_FRAME_SAMPLES * COMPRESSWAVE_MAX_CHANNELS];
|
||||
int discard;
|
||||
} compresswave_codec_data;
|
||||
|
||||
/* frame state */
|
||||
s16buf_t sbuf;
|
||||
int samples_discard;
|
||||
};
|
||||
static void reset_compresswave(void* priv_data) {
|
||||
compresswave_codec_data* data = priv_data;
|
||||
if (!data) return;
|
||||
|
||||
/* actual way to reset internal flags */
|
||||
TCompressWaveData_Stop(data->handle);
|
||||
TCompressWaveData_Play(data->handle, 0);
|
||||
|
||||
compresswave_codec_data* init_compresswave(STREAMFILE* sf) {
|
||||
data->discard = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
static void free_compresswave(void* priv_data) {
|
||||
compresswave_codec_data* data = priv_data;
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
TCompressWaveData_Free(data->handle);
|
||||
|
||||
close_streamfile(data->sf);
|
||||
free(data);
|
||||
}
|
||||
|
||||
void* init_compresswave(STREAMFILE* sf) {
|
||||
compresswave_codec_data* data = NULL;
|
||||
|
||||
data = calloc(1, sizeof(compresswave_codec_data));
|
||||
|
@ -30,15 +48,10 @@ compresswave_codec_data* init_compresswave(STREAMFILE* sf) {
|
|||
data->sf = reopen_streamfile(sf, 0);
|
||||
if (!data->sf) goto fail;
|
||||
|
||||
data->frame_samples = COMPRESSWAVE_MAX_FRAME_SAMPLES;
|
||||
data->samples = malloc(2 * data->frame_samples * sizeof(int16_t)); /* always stereo */
|
||||
if (!data->samples) goto fail;
|
||||
data->handle = TCompressWaveData_Create();
|
||||
if (!data->handle) goto fail;
|
||||
|
||||
|
||||
data->cw = TCompressWaveData_Create();
|
||||
if (!data->cw) goto fail;
|
||||
|
||||
TCompressWaveData_LoadFromStream(data->cw, data->sf);
|
||||
TCompressWaveData_LoadFromStream(data->handle, data->sf);
|
||||
|
||||
reset_compresswave(data);
|
||||
|
||||
|
@ -49,90 +62,46 @@ fail:
|
|||
}
|
||||
|
||||
|
||||
static int decode_frame(compresswave_codec_data* data, int32_t samples_to_do) {
|
||||
uint32_t Len;
|
||||
int ok;
|
||||
static bool decode_frame_compresswave(VGMSTREAM* v) {
|
||||
compresswave_codec_data* data = v->codec_data;
|
||||
decode_state_t* ds = v->decode_state;
|
||||
|
||||
data->sbuf.samples = data->samples;
|
||||
data->sbuf.channels = 2;
|
||||
data->sbuf.filled = 0;
|
||||
int samples = COMPRESSWAVE_MAX_FRAME_SAMPLES;
|
||||
//if (samples % 2 && samples > 1)
|
||||
// samples -= 1; /* 22khz does 2 samples at once */
|
||||
|
||||
if (samples_to_do > data->frame_samples)
|
||||
samples_to_do = data->frame_samples;
|
||||
if (samples_to_do % 2 && samples_to_do > 1)
|
||||
samples_to_do -= 1; /* 22khz does 2 samples at once */
|
||||
|
||||
Len = samples_to_do * sizeof(int16_t) * 2; /* forced stereo */
|
||||
uint32_t len = samples * sizeof(int16_t) * 2; /* forced stereo */
|
||||
|
||||
ok = TCompressWaveData_Rendering(data->cw, data->sbuf.samples, Len);
|
||||
if (!ok) goto fail;
|
||||
int ok = TCompressWaveData_Rendering(data->handle, data->pbuf, len);
|
||||
if (!ok) return false;
|
||||
|
||||
data->sbuf.filled = samples_to_do;
|
||||
sbuf_init_s16(&ds->sbuf, data->pbuf, samples, v->channels);
|
||||
ds->sbuf.filled = ds->sbuf.samples;
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void decode_compresswave(compresswave_codec_data* data, sample_t* outbuf, int32_t samples_to_do) {
|
||||
int ok;
|
||||
|
||||
|
||||
while (samples_to_do > 0) {
|
||||
s16buf_t* sbuf = &data->sbuf;
|
||||
|
||||
if (sbuf->filled <= 0) {
|
||||
ok = decode_frame(data, samples_to_do);
|
||||
if (!ok) goto fail;
|
||||
}
|
||||
|
||||
if (data->samples_discard)
|
||||
s16buf_discard(&outbuf, sbuf, &data->samples_discard);
|
||||
else
|
||||
s16buf_consume(&outbuf, sbuf, &samples_to_do);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
VGM_LOG("COMPRESSWAVE: decode fail, missing %i samples\n", samples_to_do);
|
||||
s16buf_silence(&outbuf, &samples_to_do, 2);
|
||||
}
|
||||
|
||||
|
||||
void reset_compresswave(compresswave_codec_data* data) {
|
||||
if (!data) return;
|
||||
|
||||
/* actual way to reset internal flags */
|
||||
TCompressWaveData_Stop(data->cw);
|
||||
TCompressWaveData_Play(data->cw, 0);
|
||||
|
||||
data->sbuf.filled = 0;
|
||||
data->samples_discard = 0;
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
void seek_compresswave(compresswave_codec_data* data, int32_t num_sample) {
|
||||
void seek_compresswave(VGMSTREAM* v, int32_t num_sample) {
|
||||
compresswave_codec_data* data = v->codec_data;
|
||||
if (!data) return;
|
||||
|
||||
reset_compresswave(data);
|
||||
data->samples_discard += num_sample;
|
||||
data->discard += num_sample;
|
||||
}
|
||||
|
||||
void free_compresswave(compresswave_codec_data* data) {
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
TCompressWaveData_Free(data->cw);
|
||||
|
||||
close_streamfile(data->sf);
|
||||
free(data->samples);
|
||||
free(data);
|
||||
}
|
||||
|
||||
STREAMFILE* compresswave_get_streamfile(compresswave_codec_data* data) {
|
||||
STREAMFILE* compresswave_get_streamfile(VGMSTREAM* v) {
|
||||
compresswave_codec_data* data = v->codec_data;
|
||||
if (!data) return NULL;
|
||||
return data->sf;
|
||||
}
|
||||
|
||||
const codec_info_t compresswave_decoder = {
|
||||
.sample_type = SFMT_S16,
|
||||
.decode_frame = decode_frame_compresswave,
|
||||
.free = free_compresswave,
|
||||
.reset = reset_compresswave,
|
||||
.seek = seek_compresswave,
|
||||
//.frame_samples = 2-4 (lib handles arbitrary calls)
|
||||
//.frame_size = VBR / huffman codes
|
||||
};
|
||||
|
|
|
@ -1,26 +1,44 @@
|
|||
#include "coding.h"
|
||||
#include "../base/decode_state.h"
|
||||
#include "libs/clhca.h"
|
||||
#include "../base/codec_info.h"
|
||||
|
||||
|
||||
struct hca_codec_data {
|
||||
STREAMFILE* sf;
|
||||
clHCA_stInfo info;
|
||||
|
||||
signed short* sample_buffer;
|
||||
size_t samples_filled;
|
||||
size_t samples_consumed;
|
||||
size_t samples_to_discard;
|
||||
|
||||
void* data_buffer;
|
||||
|
||||
void* buf;
|
||||
float* fbuf;
|
||||
int current_delay;
|
||||
unsigned int current_block;
|
||||
|
||||
void* handle;
|
||||
};
|
||||
|
||||
static void reset_hca(void* priv) {
|
||||
hca_codec_data* data = priv;
|
||||
|
||||
clHCA_DecodeReset(data->handle);
|
||||
data->current_block = 0;
|
||||
data->current_delay = data->info.encoderDelay;
|
||||
}
|
||||
|
||||
void free_hca(void* priv) {
|
||||
hca_codec_data* data = priv;
|
||||
if (!data) return;
|
||||
|
||||
close_streamfile(data->sf);
|
||||
clHCA_done(data->handle);
|
||||
free(data->handle);
|
||||
free(data->buf);
|
||||
free(data->fbuf);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/* init a HCA stream; STREAMFILE will be duplicated for internal use. */
|
||||
hca_codec_data* init_hca(STREAMFILE* sf) {
|
||||
uint8_t header_buffer[0x2000]; /* hca header buffer data (probable max ~0x400) */
|
||||
uint8_t header_buffer[0x1000]; /* hca header buffer data (probable max ~0x400) */
|
||||
hca_codec_data* data = NULL; /* vgmstream HCA context */
|
||||
int header_size;
|
||||
int status;
|
||||
|
@ -51,11 +69,11 @@ hca_codec_data* init_hca(STREAMFILE* sf) {
|
|||
status = clHCA_getInfo(data->handle, &data->info); /* extract header info */
|
||||
if (status < 0) goto fail;
|
||||
|
||||
data->data_buffer = malloc(data->info.blockSize);
|
||||
if (!data->data_buffer) goto fail;
|
||||
data->buf = malloc(data->info.blockSize);
|
||||
if (!data->buf) goto fail;
|
||||
|
||||
data->sample_buffer = malloc(sizeof(signed short) * data->info.channelCount * data->info.samplesPerBlock);
|
||||
if (!data->sample_buffer) goto fail;
|
||||
data->fbuf = malloc(sizeof(float) * data->info.channelCount * data->info.samplesPerBlock);
|
||||
if (!data->fbuf) goto fail;
|
||||
|
||||
/* load streamfile for reads */
|
||||
data->sf = reopen_streamfile(sf, 0);
|
||||
|
@ -71,86 +89,64 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
void decode_hca(hca_codec_data* data, sample_t* outbuf, int32_t samples_to_do) {
|
||||
int samples_done = 0;
|
||||
const unsigned int channels = data->info.channelCount;
|
||||
const unsigned int blockSize = data->info.blockSize;
|
||||
static bool read_packet(VGMSTREAM* v) {
|
||||
hca_codec_data* data = v->codec_data;
|
||||
|
||||
// EOF/error
|
||||
if (data->current_block >= data->info.blockCount)
|
||||
return false;
|
||||
|
||||
while (samples_done < samples_to_do) {
|
||||
// single block of frames
|
||||
const unsigned int block_size = data->info.blockSize;
|
||||
//VGMSTREAMCHANNEL* vs = &v->ch[0];
|
||||
off_t offset = data->info.headerSize + data->current_block * block_size; //vs->offset
|
||||
|
||||
if (data->samples_filled) {
|
||||
int samples_to_get = data->samples_filled;
|
||||
|
||||
if (data->samples_to_discard) {
|
||||
/* discard samples for looping */
|
||||
if (samples_to_get > data->samples_to_discard)
|
||||
samples_to_get = data->samples_to_discard;
|
||||
data->samples_to_discard -= samples_to_get;
|
||||
}
|
||||
else {
|
||||
/* get max samples and copy */
|
||||
if (samples_to_get > samples_to_do - samples_done)
|
||||
samples_to_get = samples_to_do - samples_done;
|
||||
|
||||
memcpy(outbuf + samples_done*channels,
|
||||
data->sample_buffer + data->samples_consumed*channels,
|
||||
samples_to_get*channels * sizeof(sample_t));
|
||||
samples_done += samples_to_get;
|
||||
}
|
||||
|
||||
/* mark consumed samples */
|
||||
data->samples_consumed += samples_to_get;
|
||||
data->samples_filled -= samples_to_get;
|
||||
}
|
||||
else {
|
||||
off_t offset = data->info.headerSize + data->current_block * blockSize;
|
||||
int status;
|
||||
size_t bytes;
|
||||
|
||||
/* EOF/error */
|
||||
if (data->current_block >= data->info.blockCount) {
|
||||
memset(outbuf, 0, (samples_to_do - samples_done) * channels * sizeof(sample_t));
|
||||
break;
|
||||
}
|
||||
|
||||
/* read frame */
|
||||
bytes = read_streamfile(data->data_buffer, offset, blockSize, data->sf);
|
||||
if (bytes != blockSize) {
|
||||
VGM_LOG("HCA: read %x vs expected %x bytes at %x\n", bytes, blockSize, (uint32_t)offset);
|
||||
break;
|
||||
}
|
||||
|
||||
data->current_block++;
|
||||
|
||||
/* decode frame */
|
||||
status = clHCA_DecodeBlock(data->handle, (void*)(data->data_buffer), blockSize);
|
||||
if (status < 0) {
|
||||
VGM_LOG("HCA: decode fail at %x, code=%i\n", (uint32_t)offset, status);
|
||||
break;
|
||||
}
|
||||
|
||||
/* extract samples */
|
||||
clHCA_ReadSamples16(data->handle, data->sample_buffer);
|
||||
|
||||
data->samples_consumed = 0;
|
||||
data->samples_filled += data->info.samplesPerBlock;
|
||||
}
|
||||
int bytes = read_streamfile(data->buf, offset, block_size, data->sf);
|
||||
if (bytes != block_size) {
|
||||
VGM_LOG("HCA: read %x vs expected %x bytes at %x\n", bytes, block_size, (uint32_t)offset);
|
||||
return false;
|
||||
}
|
||||
data->current_block++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void reset_hca(hca_codec_data* data) {
|
||||
if (!data) return;
|
||||
bool decode_frame_hca(VGMSTREAM* v) {
|
||||
bool ok = read_packet(v);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
clHCA_DecodeReset(data->handle);
|
||||
data->current_block = 0;
|
||||
data->samples_filled = 0;
|
||||
data->samples_consumed = 0;
|
||||
data->samples_to_discard = data->info.encoderDelay;
|
||||
decode_state_t* ds = v->decode_state;
|
||||
hca_codec_data* data = v->codec_data;
|
||||
const unsigned int block_size = data->info.blockSize;
|
||||
|
||||
|
||||
/* decode frame */
|
||||
int status = clHCA_DecodeBlock(data->handle, data->buf, block_size);
|
||||
if (status < 0) {
|
||||
VGM_LOG("HCA: decode fail, code=%i\n", status);
|
||||
return false;
|
||||
}
|
||||
|
||||
clHCA_ReadSamples(data->handle, data->fbuf);
|
||||
|
||||
int samples = data->info.samplesPerBlock;
|
||||
sbuf_init_flt(&ds->sbuf, data->fbuf, samples, v->channels);
|
||||
ds->sbuf.filled = samples;
|
||||
|
||||
if (data->current_delay) {
|
||||
ds->discard += data->current_delay;
|
||||
data->current_delay = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void loop_hca(hca_codec_data* data, int32_t num_sample) {
|
||||
if (!data) return;
|
||||
void seek_hca(VGMSTREAM* v, int32_t num_sample) {
|
||||
hca_codec_data* data = v->codec_data;
|
||||
//decode_state_t* ds = v->decode_state;
|
||||
|
||||
//TODO handle arbitrary seek points to block N
|
||||
|
||||
/* manually calc loop values if not set (should only happen with installed/forced looping,
|
||||
* as actual files usually pad encoder delay so earliest loopStartBlock becomes 1-2,
|
||||
|
@ -163,20 +159,9 @@ void loop_hca(hca_codec_data* data, int32_t num_sample) {
|
|||
}
|
||||
|
||||
data->current_block = data->info.loopStartBlock;
|
||||
data->samples_filled = 0;
|
||||
data->samples_consumed = 0;
|
||||
data->samples_to_discard = data->info.loopStartDelay;
|
||||
}
|
||||
data->current_delay = data->info.loopStartDelay;
|
||||
//ds->discard = data->info.loopStartDelay //overwritten on decode
|
||||
|
||||
void free_hca(hca_codec_data* data) {
|
||||
if (!data) return;
|
||||
|
||||
close_streamfile(data->sf);
|
||||
clHCA_done(data->handle);
|
||||
free(data->handle);
|
||||
free(data->data_buffer);
|
||||
free(data->sample_buffer);
|
||||
free(data);
|
||||
}
|
||||
|
||||
clHCA_stInfo* hca_get_info(hca_codec_data* data) {
|
||||
|
@ -235,14 +220,14 @@ static int test_hca_score(hca_codec_data* data, hca_keytest_t* hk) {
|
|||
size_t bytes;
|
||||
|
||||
/* read and test frame */
|
||||
bytes = read_streamfile(data->data_buffer, offset, block_size, data->sf);
|
||||
bytes = read_streamfile(data->buf, offset, block_size, data->sf);
|
||||
if (bytes != block_size) {
|
||||
/* normally this shouldn't happen, but pre-fetch ACB stop with frames in half, so just keep score */
|
||||
//total_score = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
score = clHCA_TestBlock(data->handle, data->data_buffer, block_size);
|
||||
score = clHCA_TestBlock(data->handle, data->buf, block_size);
|
||||
|
||||
/* get first non-blank frame */
|
||||
if (!hk->start_offset && score != 0) {
|
||||
|
@ -315,3 +300,13 @@ void hca_set_encryption_key(hca_codec_data* data, uint64_t keycode, uint64_t sub
|
|||
}
|
||||
clHCA_SetKey(data->handle, (unsigned long long)keycode);
|
||||
}
|
||||
|
||||
const codec_info_t hca_decoder = {
|
||||
.sample_type = SFMT_FLT,
|
||||
.decode_frame = decode_frame_hca,
|
||||
.free = free_hca,
|
||||
.reset = reset_hca,
|
||||
.seek = seek_hca,
|
||||
// frame_samples: 1024 + discard
|
||||
// frame_size: variable
|
||||
};
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -1,19 +1,31 @@
|
|||
#include "coding.h"
|
||||
#include "../base/decode_state.h"
|
||||
#include "../base/codec_info.h"
|
||||
#include "libs/ka1a_dec.h"
|
||||
|
||||
|
||||
/* opaque struct */
|
||||
struct ka1a_codec_data {
|
||||
typedef struct {
|
||||
uint8_t* buf;
|
||||
float* fbuf;
|
||||
|
||||
int frame_size;
|
||||
void* handle;
|
||||
};
|
||||
} ka1a_codec_data;
|
||||
|
||||
|
||||
ka1a_codec_data* init_ka1a(int bitrate_mode, int channels_tracks) {
|
||||
static void free_ka1a(void* priv_data) {
|
||||
ka1a_codec_data* data = priv_data;
|
||||
if (!data) return;
|
||||
|
||||
if (data->handle)
|
||||
ka1a_free(data->handle);
|
||||
free(data->buf);
|
||||
free(data->fbuf);
|
||||
free(data);
|
||||
}
|
||||
|
||||
void* init_ka1a(int bitrate_mode, int channels_tracks) {
|
||||
ka1a_codec_data* data = NULL;
|
||||
int buf_size;
|
||||
|
||||
|
@ -39,7 +51,7 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
static bool read_ka1a_frame(VGMSTREAM* v) {
|
||||
static bool read_frame(VGMSTREAM* v) {
|
||||
ka1a_codec_data* data = v->codec_data;
|
||||
int bytes;
|
||||
|
||||
|
@ -72,8 +84,8 @@ static bool read_ka1a_frame(VGMSTREAM* v) {
|
|||
return true;
|
||||
}
|
||||
|
||||
bool decode_ka1a_frame(VGMSTREAM* v) {
|
||||
bool ok = read_ka1a_frame(v);
|
||||
bool decode_frame_ka1a(VGMSTREAM* v) {
|
||||
bool ok = read_frame(v);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
|
@ -90,13 +102,14 @@ bool decode_ka1a_frame(VGMSTREAM* v) {
|
|||
return true;
|
||||
}
|
||||
|
||||
void reset_ka1a(ka1a_codec_data* data) {
|
||||
static void reset_ka1a(void* priv_data) {
|
||||
ka1a_codec_data* data = priv_data;
|
||||
if (!data || !data->handle) return;
|
||||
|
||||
ka1a_reset(data->handle);
|
||||
}
|
||||
|
||||
void seek_ka1a(VGMSTREAM* v, int32_t num_sample) {
|
||||
static void seek_ka1a(VGMSTREAM* v, int32_t num_sample) {
|
||||
ka1a_codec_data* data = v->codec_data;
|
||||
decode_state_t* ds = v->decode_state;
|
||||
if (!data) return;
|
||||
|
@ -135,12 +148,10 @@ void seek_ka1a(VGMSTREAM* v, int32_t num_sample) {
|
|||
#endif
|
||||
}
|
||||
|
||||
void free_ka1a(ka1a_codec_data* data) {
|
||||
if (!data) return;
|
||||
|
||||
if (data->handle)
|
||||
ka1a_free(data->handle);
|
||||
free(data->buf);
|
||||
free(data->fbuf);
|
||||
free(data);
|
||||
}
|
||||
const codec_info_t ka1a_decoder = {
|
||||
.sample_type = SFMT_FLT,
|
||||
.decode_frame = decode_frame_ka1a,
|
||||
.free = free_ka1a,
|
||||
.reset = reset_ka1a,
|
||||
.seek = seek_ka1a,
|
||||
};
|
||||
|
|
|
@ -329,19 +329,16 @@ int clHCA_getInfo(clHCA* hca, clHCA_stInfo *info) {
|
|||
}
|
||||
|
||||
//HCADecoder_DecodeBlockInt32
|
||||
void clHCA_ReadSamples16(clHCA* hca, signed short *samples) {
|
||||
void clHCA_ReadSamples16(clHCA* hca, short* samples) {
|
||||
const float scale_f = 32768.0f;
|
||||
float f;
|
||||
signed int s;
|
||||
unsigned int i, j, k;
|
||||
|
||||
/* PCM output is generally unused, but lib functions seem to use SIMD for f32 to s32 + round to zero */
|
||||
for (i = 0; i < HCA_SUBFRAMES; i++) {
|
||||
for (j = 0; j < HCA_SAMPLES_PER_SUBFRAME; j++) {
|
||||
for (k = 0; k < hca->channels; k++) {
|
||||
f = hca->channel[k].wave[i][j];
|
||||
for (int i = 0; i < HCA_SUBFRAMES; i++) {
|
||||
for (int j = 0; j < HCA_SAMPLES_PER_SUBFRAME; j++) {
|
||||
for (int k = 0; k < hca->channels; k++) {
|
||||
float f = hca->channel[k].wave[i][j];
|
||||
//f = f * hca->rva_volume; /* rare, won't apply for now */
|
||||
s = (signed int)(f * scale_f);
|
||||
int s = (signed int)(f * scale_f);
|
||||
if (s > 32767)
|
||||
s = 32767;
|
||||
else if (s < -32768)
|
||||
|
@ -352,6 +349,20 @@ void clHCA_ReadSamples16(clHCA* hca, signed short *samples) {
|
|||
}
|
||||
}
|
||||
|
||||
void clHCA_ReadSamples(clHCA* hca, float* samples) {
|
||||
|
||||
/* interleave output */
|
||||
for (int i = 0; i < HCA_SUBFRAMES; i++) {
|
||||
for (int j = 0; j < HCA_SAMPLES_PER_SUBFRAME; j++) {
|
||||
for (int k = 0; k < hca->channels; k++) {
|
||||
float f = hca->channel[k].wave[i][j];
|
||||
//f = f * hca->rva_volume; /* rare, won't apply for now */
|
||||
*samples++ = f;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//--------------------------------------------------
|
||||
// Allocation and creation
|
||||
|
|
|
@ -64,7 +64,9 @@ int clHCA_DecodeBlock(clHCA* hca, void* data, unsigned int size);
|
|||
/* Extracts signed and clipped 16 bit samples into sample buffer.
|
||||
* May be called after clHCA_DecodeBlock, and will return the same data until
|
||||
* next decode. Buffer must be at least (samplesPerBlock*channels) long. */
|
||||
void clHCA_ReadSamples16(clHCA* hca, short* outSamples);
|
||||
void clHCA_ReadSamples16(clHCA* hca, short* samples);
|
||||
void clHCA_ReadSamples(clHCA* hca, float* samples);
|
||||
|
||||
|
||||
/* Sets a 64 bit encryption key, to properly decode blocks. This may be called
|
||||
* multiple times to change the key, before or after clHCA_DecodeHeader.
|
||||
|
|
|
@ -695,7 +695,10 @@ int TCompressWaveData_Rendering(TCompressWaveData* self, int16_t* buf, uint32_t
|
|||
}
|
||||
else { //in case of playback without loop
|
||||
self->FPlay = CW_FALSE;
|
||||
return result; //exit
|
||||
//return result; //exit
|
||||
|
||||
// OG lib returns error if requested more than avaiable, return partial buf here
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -761,10 +764,10 @@ int TCompressWaveData_Rendering(TCompressWaveData* self, int16_t* buf, uint32_t
|
|||
self->FWavePosition += WaveStep;
|
||||
}
|
||||
|
||||
//remainder calcs
|
||||
//depending on buffer lenght remainder may happen
|
||||
//example: 44100 / 4 = 11025...OK 44100 / 8 = 5512.5...NG
|
||||
// in that case appear as noise
|
||||
// remainder calcs
|
||||
// depending on buffer length remainder may happen
|
||||
// example: 44100 / 4 = 11025...OK 44100 / 8 = 5512.5...NG
|
||||
// in that case it appears as noise
|
||||
if (Len % 8 == 4) {
|
||||
TCompressWaveData_Rendering_WriteWave(self, &buf1, RVol, LVol);
|
||||
}
|
||||
|
|
1865
Frameworks/vgmstream/vgmstream/src/coding/libs/minimp3.h
Normal file
1865
Frameworks/vgmstream/vgmstream/src/coding/libs/minimp3.h
Normal file
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,869 @@
|
|||
/*****************************************************************************
|
||||
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 "mio_xerisa.h"
|
||||
|
||||
#define MIO_ERISA_SYMBOL_ERROR -1
|
||||
|
||||
/************************/
|
||||
/* huffman tree helpers */
|
||||
/************************/
|
||||
|
||||
static void EHT_Initialize(ERINA_HUFFMAN_TREE* tree) {
|
||||
for (int i = 0; i < MIO_HUFFMAN_SYMBOLS; i++) {
|
||||
tree->m_iSymLookup[i] = ERINA_HUFFMAN_NULL;
|
||||
}
|
||||
tree->m_iEscape = ERINA_HUFFMAN_NULL;
|
||||
tree->m_iTreePointer = ERINA_HUFFMAN_ROOT;
|
||||
tree->m_hnTree[ERINA_HUFFMAN_ROOT].weight = 0;
|
||||
tree->m_hnTree[ERINA_HUFFMAN_ROOT].parent = ERINA_HUFFMAN_NULL;
|
||||
tree->m_hnTree[ERINA_HUFFMAN_ROOT].child_code = ERINA_HUFFMAN_NULL;
|
||||
}
|
||||
|
||||
static void EHT_RecountOccuredCount(ERINA_HUFFMAN_TREE* tree, int iParent) {
|
||||
int iChild = tree->m_hnTree[iParent].child_code;
|
||||
tree->m_hnTree[iParent].weight = tree->m_hnTree[iChild].weight + tree->m_hnTree[iChild + 1].weight;
|
||||
}
|
||||
|
||||
static void EHT_Normalize(ERINA_HUFFMAN_TREE* tree, int iEntry) {
|
||||
while (iEntry < ERINA_HUFFMAN_ROOT) {
|
||||
// find swap entry
|
||||
int iSwap = iEntry + 1;
|
||||
WORD weight = tree->m_hnTree[iEntry].weight;
|
||||
while (iSwap < ERINA_HUFFMAN_ROOT) {
|
||||
if (tree->m_hnTree[iSwap].weight >= weight) break;
|
||||
++iSwap;
|
||||
}
|
||||
if (iEntry == --iSwap) {
|
||||
iEntry = tree->m_hnTree[iEntry].parent;
|
||||
EHT_RecountOccuredCount(tree, iEntry);
|
||||
continue;
|
||||
}
|
||||
|
||||
// swap
|
||||
int iChild, nCode;
|
||||
if (!(tree->m_hnTree[iEntry].child_code & ERINA_CODE_FLAG)) {
|
||||
iChild = tree->m_hnTree[iEntry].child_code;
|
||||
tree->m_hnTree[iChild].parent = iSwap;
|
||||
tree->m_hnTree[iChild + 1].parent = iSwap;
|
||||
}
|
||||
else {
|
||||
nCode = tree->m_hnTree[iEntry].child_code & ~ERINA_CODE_FLAG;
|
||||
if (nCode != ERINA_HUFFMAN_ESCAPE)
|
||||
tree->m_iSymLookup[nCode & 0xFF] = iSwap;
|
||||
else
|
||||
tree->m_iEscape = iSwap;
|
||||
}
|
||||
if (!(tree->m_hnTree[iSwap].child_code & ERINA_CODE_FLAG)) {
|
||||
int iChild = tree->m_hnTree[iSwap].child_code;
|
||||
tree->m_hnTree[iChild].parent = iEntry;
|
||||
tree->m_hnTree[iChild + 1].parent = iEntry;
|
||||
}
|
||||
else {
|
||||
int nCode = tree->m_hnTree[iSwap].child_code & ~ERINA_CODE_FLAG;
|
||||
if (nCode != ERINA_HUFFMAN_ESCAPE)
|
||||
tree->m_iSymLookup[nCode & 0xFF] = iEntry;
|
||||
else
|
||||
tree->m_iEscape = iEntry;
|
||||
}
|
||||
|
||||
ERINA_HUFFMAN_NODE node;
|
||||
WORD iEntryParent = tree->m_hnTree[iEntry].parent;
|
||||
WORD iSwapParent = tree->m_hnTree[iSwap].parent;
|
||||
node = tree->m_hnTree[iSwap];
|
||||
tree->m_hnTree[iSwap] = tree->m_hnTree[iEntry];
|
||||
tree->m_hnTree[iEntry] = node;
|
||||
tree->m_hnTree[iSwap].parent = iSwapParent;
|
||||
tree->m_hnTree[iEntry].parent = iEntryParent;
|
||||
|
||||
// recalc parent weight
|
||||
EHT_RecountOccuredCount(tree, iSwapParent);
|
||||
iEntry = iSwapParent;
|
||||
}
|
||||
}
|
||||
|
||||
static void EHT_AddNewEntry(ERINA_HUFFMAN_TREE* tree, int nNewCode) {
|
||||
if (tree->m_iTreePointer > 0) {
|
||||
// reserve 2 areas
|
||||
int i = tree->m_iTreePointer = tree->m_iTreePointer - 2;
|
||||
|
||||
// setup new entry
|
||||
ERINA_HUFFMAN_NODE* phnNew = &tree->m_hnTree[i];
|
||||
phnNew->weight = 1;
|
||||
phnNew->child_code = ERINA_CODE_FLAG | nNewCode;
|
||||
tree->m_iSymLookup[nNewCode & 0xFF] = i;
|
||||
|
||||
ERINA_HUFFMAN_NODE* phnRoot = &tree->m_hnTree[ERINA_HUFFMAN_ROOT];
|
||||
if (phnRoot->child_code != ERINA_HUFFMAN_NULL) {
|
||||
// add new entry
|
||||
ERINA_HUFFMAN_NODE* phnParent = &tree->m_hnTree[i + 2];
|
||||
ERINA_HUFFMAN_NODE* phnChild = &tree->m_hnTree[i + 1];
|
||||
tree->m_hnTree[i + 1] = tree->m_hnTree[i + 2];
|
||||
|
||||
if (phnChild->child_code & ERINA_CODE_FLAG) {
|
||||
int nCode = phnChild->child_code & ~ERINA_CODE_FLAG;
|
||||
if (nCode != ERINA_HUFFMAN_ESCAPE)
|
||||
tree->m_iSymLookup[nCode & 0xFF] = i + 1;
|
||||
else
|
||||
tree->m_iEscape = i + 1;
|
||||
}
|
||||
|
||||
phnParent->weight = phnNew->weight + phnChild->weight;
|
||||
phnParent->parent = phnChild->parent;
|
||||
phnParent->child_code = i;
|
||||
|
||||
phnNew->parent = phnChild->parent = i + 2;
|
||||
|
||||
// fix parent entry
|
||||
EHT_Normalize(tree, i + 2);
|
||||
}
|
||||
else {
|
||||
// create initial tree state
|
||||
phnNew->parent = ERINA_HUFFMAN_ROOT;
|
||||
|
||||
ERINA_HUFFMAN_NODE* phnEscape = &tree->m_hnTree[tree->m_iEscape = i + 1];
|
||||
phnEscape->weight = 1;
|
||||
phnEscape->parent = ERINA_HUFFMAN_ROOT;
|
||||
phnEscape->child_code = ERINA_CODE_FLAG | ERINA_HUFFMAN_ESCAPE;
|
||||
|
||||
phnRoot->weight = 2;
|
||||
phnRoot->child_code = i;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// replace least ocurring symbol with new symbol
|
||||
int i = tree->m_iTreePointer;
|
||||
ERINA_HUFFMAN_NODE* phnEntry = &tree->m_hnTree[i];
|
||||
if (phnEntry->child_code == (ERINA_CODE_FLAG | ERINA_HUFFMAN_ESCAPE)) {
|
||||
phnEntry = &tree->m_hnTree[i + 1];
|
||||
}
|
||||
phnEntry->child_code = ERINA_CODE_FLAG | nNewCode;
|
||||
}
|
||||
}
|
||||
|
||||
static void EHT_HalfAndRebuild(ERINA_HUFFMAN_TREE* tree) {
|
||||
// halve ocurrence count and rebuild the tree
|
||||
int iNextEntry = ERINA_HUFFMAN_ROOT;
|
||||
for (int i = ERINA_HUFFMAN_ROOT - 1; i >= tree->m_iTreePointer; i--) {
|
||||
if (tree->m_hnTree[i].child_code & ERINA_CODE_FLAG) {
|
||||
tree->m_hnTree[i].weight = (tree->m_hnTree[i].weight + 1) >> 1;
|
||||
tree->m_hnTree[iNextEntry--] = tree->m_hnTree[i];
|
||||
}
|
||||
}
|
||||
++iNextEntry;
|
||||
|
||||
// rebuild tree
|
||||
int iChild, nCode;
|
||||
int i = tree->m_iTreePointer;
|
||||
for (;;) {
|
||||
// put the smallest 2 entries into the huffman tree
|
||||
tree->m_hnTree[i] = tree->m_hnTree[iNextEntry];
|
||||
tree->m_hnTree[i + 1] = tree->m_hnTree[iNextEntry + 1];
|
||||
iNextEntry += 2;
|
||||
ERINA_HUFFMAN_NODE* phnChild1 = &tree->m_hnTree[i];
|
||||
ERINA_HUFFMAN_NODE* phnChild2 = &tree->m_hnTree[i + 1];
|
||||
|
||||
if (!(phnChild1->child_code & ERINA_CODE_FLAG)) {
|
||||
iChild = phnChild1->child_code;
|
||||
tree->m_hnTree[iChild].parent = i;
|
||||
tree->m_hnTree[iChild + 1].parent = i;
|
||||
}
|
||||
else {
|
||||
nCode = phnChild1->child_code & ~ERINA_CODE_FLAG;
|
||||
if (nCode == ERINA_HUFFMAN_ESCAPE)
|
||||
tree->m_iEscape = i;
|
||||
else
|
||||
tree->m_iSymLookup[nCode & 0xFF] = i;
|
||||
}
|
||||
|
||||
if (!(phnChild2->child_code & ERINA_CODE_FLAG)) {
|
||||
iChild = phnChild2->child_code;
|
||||
tree->m_hnTree[iChild].parent = i + 1;
|
||||
tree->m_hnTree[iChild + 1].parent = i + 1;
|
||||
}
|
||||
else {
|
||||
nCode = phnChild2->child_code & ~ERINA_CODE_FLAG;
|
||||
if (nCode == ERINA_HUFFMAN_ESCAPE)
|
||||
tree->m_iEscape = i + 1;
|
||||
else
|
||||
tree->m_iSymLookup[nCode & 0xFF] = i + 1;
|
||||
}
|
||||
|
||||
WORD weight = phnChild1->weight + phnChild2->weight;
|
||||
|
||||
// include parent entry in list
|
||||
if (iNextEntry <= ERINA_HUFFMAN_ROOT) {
|
||||
int j = iNextEntry;
|
||||
for (;;) {
|
||||
if (weight <= tree->m_hnTree[j].weight) {
|
||||
tree->m_hnTree[j - 1].weight = weight;
|
||||
tree->m_hnTree[j - 1].child_code = i;
|
||||
break;
|
||||
}
|
||||
tree->m_hnTree[j - 1] = tree->m_hnTree[j];
|
||||
if (++j > ERINA_HUFFMAN_ROOT) {
|
||||
tree->m_hnTree[ERINA_HUFFMAN_ROOT].weight = weight;
|
||||
tree->m_hnTree[ERINA_HUFFMAN_ROOT].child_code = i;
|
||||
break;
|
||||
}
|
||||
}
|
||||
--iNextEntry;
|
||||
}
|
||||
else {
|
||||
tree->m_hnTree[ERINA_HUFFMAN_ROOT].weight = weight;
|
||||
tree->m_hnTree[ERINA_HUFFMAN_ROOT].parent = ERINA_HUFFMAN_NULL;
|
||||
tree->m_hnTree[ERINA_HUFFMAN_ROOT].child_code = i;
|
||||
phnChild1->parent = ERINA_HUFFMAN_ROOT;
|
||||
phnChild2->parent = ERINA_HUFFMAN_ROOT;
|
||||
break;
|
||||
}
|
||||
|
||||
i += 2;
|
||||
}
|
||||
}
|
||||
|
||||
static void EHT_IncreaseOccuredCount(ERINA_HUFFMAN_TREE* tree, int iEntry) {
|
||||
tree->m_hnTree[iEntry].weight++;
|
||||
EHT_Normalize(tree, iEntry);
|
||||
|
||||
if (tree->m_hnTree[ERINA_HUFFMAN_ROOT].weight >= ERINA_HUFFMAN_MAX) {
|
||||
EHT_HalfAndRebuild(tree);
|
||||
}
|
||||
}
|
||||
|
||||
/*****************************/
|
||||
/* arithmetic coding helpers */
|
||||
/*****************************/
|
||||
|
||||
static void EPM_Initialize(ERISA_PROB_MODEL* prob) {
|
||||
prob->dwTotalCount = ERISA_SYMBOL_SORTS;
|
||||
prob->dwSymbolSorts = ERISA_SYMBOL_SORTS;
|
||||
|
||||
for (int i = 0; i < 0x100; i++) {
|
||||
prob->acsSymTable[i].wOccured = 1;
|
||||
prob->acsSymTable[i].wSymbol = (SWORD)(BYTE)i;
|
||||
}
|
||||
prob->acsSymTable[0x100].wOccured = 1;
|
||||
prob->acsSymTable[0x100].wSymbol = (SWORD)ERISA_ESCAPE_CODE;
|
||||
|
||||
for (int i = 0; i < ERISA_SUB_SORT_MAX; i++) {
|
||||
prob->acsSubModel[i].wOccured = 0;
|
||||
prob->acsSubModel[i].wSymbol = (SWORD)-1;
|
||||
}
|
||||
}
|
||||
|
||||
static void EPM_HalfOccuredCount(ERISA_PROB_MODEL* prob) {
|
||||
UDWORD i;
|
||||
|
||||
prob->dwTotalCount = 0;
|
||||
for (i = 0; i < prob->dwSymbolSorts; i++) {
|
||||
prob->dwTotalCount += prob->acsSymTable[i].wOccured = ((prob->acsSymTable[i].wOccured + 1) >> 1);
|
||||
}
|
||||
for (i = 0; i < ERISA_SUB_SORT_MAX; i++) {
|
||||
prob->acsSubModel[i].wOccured >>= 1;
|
||||
}
|
||||
}
|
||||
|
||||
static int EPM_IncreaseSymbol(ERISA_PROB_MODEL* prob, int index) {
|
||||
WORD wOccured = ++prob->acsSymTable[index].wOccured;
|
||||
SWORD wSymbol = prob->acsSymTable[index].wSymbol;
|
||||
|
||||
while (--index >= 0) {
|
||||
if (prob->acsSymTable[index].wOccured >= wOccured)
|
||||
break;
|
||||
prob->acsSymTable[index + 1] = prob->acsSymTable[index];
|
||||
}
|
||||
prob->acsSymTable[++index].wOccured = wOccured;
|
||||
prob->acsSymTable[index].wSymbol = wSymbol;
|
||||
|
||||
if (++prob->dwTotalCount >= ERISA_TOTAL_LIMIT) {
|
||||
EPM_HalfOccuredCount(prob);
|
||||
}
|
||||
|
||||
return index;
|
||||
}
|
||||
|
||||
/**************************/
|
||||
/* general decode context */
|
||||
/**************************/
|
||||
|
||||
ULONG MIOContext_DecodeSymbolBytes(MIOContext* context, SBYTE* ptrDst, ULONG nCount) {
|
||||
|
||||
/* (assert) */
|
||||
if (context->m_pfnDecodeSymbolBytes == NULL)
|
||||
return 0;
|
||||
|
||||
return (context->m_pfnDecodeSymbolBytes)(context, ptrDst, nCount);
|
||||
}
|
||||
|
||||
|
||||
static const SBYTE /*BYTE*/ nGammaCodeLookup[512] = {
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4,
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 8, 6, 8, 6, 8, 6, 8, 6, 16, 8, -1, -1, 17, 8, -1, -1, 9, 6, 9, 6, 9, 6, 9, 6, 18,
|
||||
8, -1, -1, 19, 8, -1, -1, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4, 5, 4,
|
||||
5, 4, 10, 6, 10, 6, 10, 6, 10, 6, 20, 8, -1, -1, 21, 8, -1, -1, 11, 6, 11, 6, 11, 6, 11, 6, 22, 8, -1, -1, 23, 8, -1, -1, 3, 2, 3,
|
||||
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2,
|
||||
3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3,
|
||||
2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2,
|
||||
3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 3, 2, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6, 4, 6,
|
||||
4, 6, 4, 6, 4, 6, 4, 6, 4, 12, 6, 12, 6, 12, 6, 12, 6, 24, 8, -1, -1, 25, 8, -1, -1, 13, 6, 13, 6, 13, 6, 13, 6, 26, 8, -1, -1,
|
||||
27, 8, -1, -1, 7, 4, 7, 4, 7, 4, 7, 4, 7, 4, 7, 4, 7, 4, 7, 4, 7, 4, 7, 4, 7, 4, 7, 4, 7, 4, 7, 4, 7, 4, 7, 4, 14,
|
||||
6, 14, 6, 14, 6, 14, 6, 28, 8, -1, -1, 29, 8, -1, -1, 15, 6, 15, 6, 15, 6, 15, 6, 30, 8, -1, -1, 31, 8, -1, -1
|
||||
};
|
||||
|
||||
|
||||
static ESLError MIOContext_PrefetchBuffer(MIOContext* context) {
|
||||
if (context->m_nIntBufCount != 0)
|
||||
return eslErrSuccess;
|
||||
|
||||
if (context->m_pFilePos >= context->m_pFileLength)
|
||||
return eslErrGeneral;
|
||||
|
||||
// read next int32 BE
|
||||
int dwLeft = context->m_pFileLength - context->m_pFilePos;
|
||||
if (dwLeft < 4) {
|
||||
// read partially at buffer edge
|
||||
context->m_dwIntBuffer = 0;
|
||||
for (int i = 0; i < dwLeft; i++) {
|
||||
context->m_dwIntBuffer |= (UDWORD)context->m_pFileBuf[context->m_pFilePos + i] << (24 - 8*i);
|
||||
}
|
||||
context->m_pFilePos += dwLeft;
|
||||
}
|
||||
else {
|
||||
context->m_dwIntBuffer =
|
||||
((UDWORD)context->m_pFileBuf[context->m_pFilePos + 0] << 24) |
|
||||
((UDWORD)context->m_pFileBuf[context->m_pFilePos + 1] << 16) |
|
||||
((UDWORD)context->m_pFileBuf[context->m_pFilePos + 2] << 8) |
|
||||
((UDWORD)context->m_pFileBuf[context->m_pFilePos + 3]);
|
||||
context->m_pFilePos += 4;
|
||||
}
|
||||
|
||||
// get next int32
|
||||
context->m_nIntBufCount = 32;
|
||||
|
||||
return eslErrSuccess;
|
||||
}
|
||||
|
||||
int MIOContext_GetABit(MIOContext* context) {
|
||||
if (MIOContext_PrefetchBuffer(context)) {
|
||||
return 1; // on error does return 1
|
||||
}
|
||||
|
||||
// returns one bit ("0 or -1" according to original comment)
|
||||
int nValue = (int)(((SDWORD)context->m_dwIntBuffer) >> 31);
|
||||
--context->m_nIntBufCount;
|
||||
context->m_dwIntBuffer <<= 1;
|
||||
return nValue;
|
||||
}
|
||||
|
||||
UINT MIOContext_GetNBits(MIOContext* context, int n) {
|
||||
UINT nCode = 0;
|
||||
while (n != 0) {
|
||||
if (MIOContext_PrefetchBuffer(context))
|
||||
break;
|
||||
|
||||
int nCopyBits = n;
|
||||
if (nCopyBits > context->m_nIntBufCount)
|
||||
nCopyBits = context->m_nIntBufCount;
|
||||
|
||||
nCode = (nCode << nCopyBits) | (context->m_dwIntBuffer >> (32 - nCopyBits));
|
||||
n -= nCopyBits;
|
||||
context->m_nIntBufCount -= nCopyBits;
|
||||
context->m_dwIntBuffer <<= nCopyBits;
|
||||
}
|
||||
return nCode;
|
||||
}
|
||||
|
||||
static int MIOContext_GetGammaCode(MIOContext* context) {
|
||||
// test 1
|
||||
if (MIOContext_PrefetchBuffer(context)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*register*/ UDWORD dwIntBuf;
|
||||
context->m_nIntBufCount--;
|
||||
dwIntBuf = context->m_dwIntBuffer;
|
||||
context->m_dwIntBuffer <<= 1;
|
||||
if (!(dwIntBuf & 0x80000000)) {
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
// test end code
|
||||
if (MIOContext_PrefetchBuffer(context)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if ((~context->m_dwIntBuffer & 0x55000000) && (context->m_nIntBufCount >= 8)) {
|
||||
int i = (context->m_dwIntBuffer >> 24) << 1;
|
||||
int nCode = nGammaCodeLookup[i];
|
||||
int nBitCount = nGammaCodeLookup[i + 1];
|
||||
|
||||
/* (assert) */
|
||||
if (nBitCount > context->m_nIntBufCount || nCode <= 0)
|
||||
return 0;
|
||||
|
||||
context->m_nIntBufCount -= nBitCount;
|
||||
context->m_dwIntBuffer <<= nBitCount;
|
||||
return nCode;
|
||||
}
|
||||
|
||||
// regular routine
|
||||
int nCode = 0, nBase = 2;
|
||||
for (;;) {
|
||||
if (context->m_nIntBufCount >= 2) {
|
||||
// process 2 bits
|
||||
dwIntBuf = context->m_dwIntBuffer;
|
||||
context->m_dwIntBuffer <<= 2;
|
||||
nCode = (nCode << 1) | (dwIntBuf >> 31);
|
||||
context->m_nIntBufCount -= 2;
|
||||
if (!(dwIntBuf & 0x40000000)) {
|
||||
return nCode + nBase;
|
||||
}
|
||||
nBase <<= 1;
|
||||
}
|
||||
else {
|
||||
// extract 1-bit
|
||||
if (MIOContext_PrefetchBuffer(context)) {
|
||||
return 0;
|
||||
}
|
||||
nCode = (nCode << 1) | (context->m_dwIntBuffer >> 31);
|
||||
context->m_nIntBufCount--;
|
||||
context->m_dwIntBuffer <<= 1;
|
||||
|
||||
// test end code
|
||||
if (MIOContext_PrefetchBuffer(context)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
dwIntBuf = context->m_dwIntBuffer;
|
||||
context->m_nIntBufCount--;
|
||||
context->m_dwIntBuffer <<= 1;
|
||||
if (!(dwIntBuf & 0x80000000)) {
|
||||
return nCode + nBase;
|
||||
}
|
||||
nBase <<= 1;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* original clones this into 2 functions with different escape codes but here we use a flag */
|
||||
static int MIOContext_GetHuffmanCommon(MIOContext* context, ERINA_HUFFMAN_TREE* tree, int escapeGamma) {
|
||||
// get one huffman code
|
||||
int nCode;
|
||||
if (tree->m_iEscape != ERINA_HUFFMAN_NULL) {
|
||||
int iEntry = ERINA_HUFFMAN_ROOT;
|
||||
int iChild = tree->m_hnTree[ERINA_HUFFMAN_ROOT].child_code;
|
||||
|
||||
// decode codes
|
||||
do {
|
||||
if (MIOContext_PrefetchBuffer(context)) {
|
||||
return ERINA_HUFFMAN_ESCAPE;
|
||||
}
|
||||
|
||||
// extract 1-bit
|
||||
iEntry = iChild + (context->m_dwIntBuffer >> 31);
|
||||
--context->m_nIntBufCount;
|
||||
iChild = tree->m_hnTree[iEntry].child_code;
|
||||
context->m_dwIntBuffer <<= 1;
|
||||
} while (!(iChild & ERINA_CODE_FLAG));
|
||||
|
||||
// increase code occurence
|
||||
if ((context->m_dwERINAFlags != ERINAEncodingFlag_efERINAOrder0) || (tree->m_hnTree[ERINA_HUFFMAN_ROOT].weight < ERINA_HUFFMAN_MAX - 1)) {
|
||||
EHT_IncreaseOccuredCount(tree, iEntry);
|
||||
}
|
||||
|
||||
// regular code
|
||||
nCode = iChild & ~ERINA_CODE_FLAG;
|
||||
if (nCode != ERINA_HUFFMAN_ESCAPE) {
|
||||
return nCode;
|
||||
}
|
||||
}
|
||||
|
||||
if (escapeGamma) {
|
||||
// escape code: gamma code
|
||||
nCode = MIOContext_GetGammaCode(context);
|
||||
if (nCode == -1) {
|
||||
return ERINA_HUFFMAN_ESCAPE;
|
||||
}
|
||||
}
|
||||
else {
|
||||
// escape code: 8-bit code
|
||||
nCode = MIOContext_GetNBits(context, 8);
|
||||
}
|
||||
EHT_AddNewEntry(tree, nCode);
|
||||
|
||||
return nCode;
|
||||
}
|
||||
|
||||
// get one "regular huffman" code
|
||||
static int MIOContext_GetHuffmanCode(MIOContext* context, ERINA_HUFFMAN_TREE* tree) {
|
||||
return MIOContext_GetHuffmanCommon(context, tree, 0);
|
||||
}
|
||||
|
||||
// get one "length huffman" code
|
||||
static int MIOContext_GetHuffmanLength(MIOContext* context, ERINA_HUFFMAN_TREE* tree) {
|
||||
return MIOContext_GetHuffmanCommon(context, tree, 1);
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* decode ERINA (huffman-coded) */
|
||||
ULONG MIOContext_DecodeERINACodeBytes(MIOContext* context, SBYTE* ptrDst, ULONG nCount) {
|
||||
ERINA_HUFFMAN_TREE* tree = context->m_pLastHuffmanTree;
|
||||
int symbol, length;
|
||||
ULONG i = 0;
|
||||
if (context->m_nLength > 0) {
|
||||
length = context->m_nLength;
|
||||
if (length > (int)nCount) {
|
||||
length = nCount;
|
||||
}
|
||||
context->m_nLength -= length;
|
||||
do {
|
||||
ptrDst[i++] = 0;
|
||||
} while (--length);
|
||||
}
|
||||
while (i < nCount) {
|
||||
symbol = MIOContext_GetHuffmanCode(context, tree);
|
||||
if (symbol == ERINA_HUFFMAN_ESCAPE) {
|
||||
break;
|
||||
}
|
||||
ptrDst[i++] = (SBYTE)symbol;
|
||||
|
||||
if (symbol == 0) {
|
||||
length = MIOContext_GetHuffmanLength(context, context->m_ppHuffmanTree[0x100]);
|
||||
if (length == ERINA_HUFFMAN_ESCAPE) {
|
||||
break;
|
||||
}
|
||||
if (--length) {
|
||||
context->m_nLength = length;
|
||||
if (i + length > nCount) {
|
||||
length = nCount - i;
|
||||
}
|
||||
context->m_nLength -= length;
|
||||
if (length > 0) {
|
||||
do {
|
||||
ptrDst[i++] = 0;
|
||||
} while (--length);
|
||||
}
|
||||
}
|
||||
}
|
||||
tree = context->m_ppHuffmanTree[symbol & 0xFF];
|
||||
}
|
||||
context->m_pLastHuffmanTree = tree;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
static int MIOContext_DecodeERISACodeIndex(MIOContext* context, ERISA_PROB_MODEL* pModel) {
|
||||
// serach via index
|
||||
UDWORD dwAcc = context->m_dwCodeRegister * pModel->dwTotalCount / context->m_dwAugendRegister;
|
||||
if (dwAcc >= ERISA_TOTAL_LIMIT) {
|
||||
return MIO_ERISA_SYMBOL_ERROR;
|
||||
}
|
||||
|
||||
int iSym = 0;
|
||||
WORD wAcc = (WORD)dwAcc;
|
||||
WORD wFs = 0;
|
||||
WORD wOccured;
|
||||
for (;;) {
|
||||
wOccured = pModel->acsSymTable[iSym].wOccured;
|
||||
if (wAcc < wOccured) {
|
||||
break;
|
||||
}
|
||||
wAcc -= wOccured;
|
||||
wFs += wOccured;
|
||||
if ((UDWORD)++iSym >= pModel->dwSymbolSorts) {
|
||||
return MIO_ERISA_SYMBOL_ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
// update code and augend registers
|
||||
context->m_dwCodeRegister -= (context->m_dwAugendRegister * wFs + pModel->dwTotalCount - 1) / pModel->dwTotalCount;
|
||||
context->m_dwAugendRegister = context->m_dwAugendRegister * wOccured / pModel->dwTotalCount;
|
||||
|
||||
/* (assert) */
|
||||
if (context->m_dwAugendRegister == 0)
|
||||
return MIO_ERISA_SYMBOL_ERROR;
|
||||
|
||||
// normalize augend register and load into code register
|
||||
while (!(context->m_dwAugendRegister & 0x8000)) {
|
||||
int nNextBit = MIOContext_GetABit(context);
|
||||
if (nNextBit == 1) {
|
||||
if ((++context->m_nPostBitCount) >= 256) {
|
||||
return MIO_ERISA_SYMBOL_ERROR;
|
||||
}
|
||||
nNextBit = 0;
|
||||
}
|
||||
context->m_dwCodeRegister = (context->m_dwCodeRegister << 1) | (nNextBit & 0x01);
|
||||
|
||||
context->m_dwAugendRegister <<= 1;
|
||||
}
|
||||
|
||||
|
||||
/* (assert) */
|
||||
if ((context->m_dwAugendRegister & 0x8000) == 0)
|
||||
return MIO_ERISA_SYMBOL_ERROR;
|
||||
|
||||
context->m_dwCodeRegister &= 0xFFFF;
|
||||
|
||||
return iSym;
|
||||
}
|
||||
|
||||
/* decode ERISA (arithmetic-coded, using designated statistical model) */
|
||||
int MIOContext_DecodeERISACode(MIOContext* context, ERISA_PROB_MODEL* pModel) {
|
||||
int iSym = MIOContext_DecodeERISACodeIndex(context, pModel);
|
||||
int nSymbol = ERISA_ESCAPE_CODE;
|
||||
if (iSym >= 0) {
|
||||
nSymbol = pModel->acsSymTable[iSym].wSymbol;
|
||||
EPM_IncreaseSymbol(pModel, iSym);
|
||||
}
|
||||
return nSymbol;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
MIOContext* MIOContext_Open() {
|
||||
MIOContext* context = malloc(sizeof(MIOContext));
|
||||
if (!context) return NULL;
|
||||
|
||||
context->m_nIntBufCount = 0;
|
||||
|
||||
context->m_pfnDecodeSymbolBytes = NULL;
|
||||
|
||||
context->m_ppHuffmanTree = NULL;
|
||||
context->m_pPhraseLenProb = NULL;
|
||||
context->m_pPhraseIndexProb = NULL;
|
||||
context->m_pRunLenProb = NULL;
|
||||
context->m_ppTableERISA = NULL;
|
||||
|
||||
return context;
|
||||
}
|
||||
|
||||
void MIOContext_Close(MIOContext* context) {
|
||||
if (!context) return;
|
||||
|
||||
free(context->m_ppHuffmanTree);
|
||||
free(context->m_pPhraseLenProb);
|
||||
free(context->m_pPhraseIndexProb);
|
||||
free(context->m_pRunLenProb);
|
||||
free(context->m_ppTableERISA);
|
||||
|
||||
free(context);
|
||||
}
|
||||
|
||||
void MIOContext_AttachInputFile(MIOContext* context, uint8_t* pFileBuf, int pFileLength) {
|
||||
context->m_pFileBuf = pFileBuf;
|
||||
context->m_pFileLength = pFileLength;
|
||||
context->m_pFilePos = 0;
|
||||
}
|
||||
|
||||
void MIOContext_FlushBuffer(MIOContext* context) {
|
||||
context->m_nIntBufCount = 0;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
ESLError MIOContext_PrepareToDecodeERINACode(MIOContext* context, UDWORD dwFlags) {
|
||||
if (context->m_ppHuffmanTree == NULL) {
|
||||
UDWORD dwSize = (sizeof(ERINA_HUFFMAN_TREE*) + sizeof(ERINA_HUFFMAN_TREE)) * 0x101;
|
||||
dwSize = (dwSize + 0x0F) & ~0x0F;
|
||||
context->m_ppHuffmanTree = (ERINA_HUFFMAN_TREE**)malloc(dwSize);
|
||||
if (!context->m_ppHuffmanTree)
|
||||
return eslErrGeneral;
|
||||
|
||||
BYTE* ptrBuf = (BYTE*)(context->m_ppHuffmanTree + 0x101);
|
||||
for (int i = 0; i < 0x101; i++) {
|
||||
void* ptrTmp = ptrBuf;
|
||||
context->m_ppHuffmanTree[i] = ptrTmp;
|
||||
ptrBuf += sizeof(ERINA_HUFFMAN_TREE);
|
||||
}
|
||||
}
|
||||
|
||||
// init huffman
|
||||
context->m_dwERINAFlags = dwFlags;
|
||||
context->m_nLength = 0;
|
||||
if (dwFlags == ERINAEncodingFlag_efERINAOrder0) { // not used in audio actually
|
||||
EHT_Initialize(context->m_ppHuffmanTree[0]);
|
||||
EHT_Initialize(context->m_ppHuffmanTree[0x100]);
|
||||
for (int i = 1; i < 0x100; i++) {
|
||||
context->m_ppHuffmanTree[i] = context->m_ppHuffmanTree[0];
|
||||
}
|
||||
}
|
||||
else {
|
||||
for (int i = 0; i < 0x101; i++) {
|
||||
EHT_Initialize(context->m_ppHuffmanTree[i]);
|
||||
}
|
||||
}
|
||||
|
||||
context->m_pLastHuffmanTree = context->m_ppHuffmanTree[0];
|
||||
|
||||
context->m_pfnDecodeSymbolBytes = &MIOContext_DecodeERINACodeBytes;
|
||||
|
||||
return eslErrSuccess;
|
||||
}
|
||||
|
||||
ESLError MIOContext_PrepareToDecodeERISACode(MIOContext* context) {
|
||||
// init memory
|
||||
if (context->m_ppTableERISA == NULL) { //TODO improve
|
||||
UDWORD dwBytes = sizeof(ERISA_PROB_MODEL*) * 0x104 + sizeof(ERISA_PROB_MODEL) * 0x101;
|
||||
dwBytes = (dwBytes + 0x100F) & (~0xFFF);
|
||||
context->m_ppTableERISA = (ERISA_PROB_MODEL**)malloc(dwBytes);
|
||||
if (!context->m_ppTableERISA)
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
if (context->m_pPhraseLenProb == NULL)
|
||||
context->m_pPhraseLenProb = malloc(sizeof(ERISA_PROB_MODEL));
|
||||
if (context->m_pPhraseIndexProb == NULL)
|
||||
context->m_pPhraseIndexProb = malloc(sizeof(ERISA_PROB_MODEL));
|
||||
if (context->m_pRunLenProb == NULL)
|
||||
context->m_pRunLenProb = malloc(sizeof(ERISA_PROB_MODEL));
|
||||
if (!context->m_pPhraseLenProb || !context->m_pPhraseIndexProb || !context->m_pRunLenProb)
|
||||
return eslErrGeneral;
|
||||
|
||||
// init probability model
|
||||
ERISA_PROB_MODEL* pNextProb = (ERISA_PROB_MODEL*)(context->m_ppTableERISA + 0x104);
|
||||
context->m_pLastERISAProb = pNextProb;
|
||||
for (int i = 0; i < 0x101; i++) {
|
||||
EPM_Initialize(pNextProb);
|
||||
context->m_ppTableERISA[i] = pNextProb;
|
||||
pNextProb++;
|
||||
}
|
||||
EPM_Initialize(context->m_pPhraseLenProb);
|
||||
EPM_Initialize(context->m_pPhraseIndexProb);
|
||||
EPM_Initialize(context->m_pRunLenProb);
|
||||
|
||||
// init register
|
||||
context->m_nLength = 0;
|
||||
context->m_dwCodeRegister = MIOContext_GetNBits(context, 32);
|
||||
context->m_dwAugendRegister = 0xFFFF;
|
||||
context->m_nPostBitCount = 0;
|
||||
|
||||
context->m_pfnDecodeSymbolBytes = &MIOContext_DecodeERISACodeBytes;
|
||||
|
||||
return eslErrSuccess;
|
||||
}
|
||||
|
||||
// init "arithtmetic code"
|
||||
void MIOContext_InitializeERISACode(MIOContext* context) {
|
||||
context->m_nLength = 0;
|
||||
context->m_dwCodeRegister = MIOContext_GetNBits(context, 32);
|
||||
context->m_dwAugendRegister = 0xFFFF;
|
||||
context->m_nPostBitCount = 0;
|
||||
}
|
||||
|
||||
ULONG MIOContext_DecodeERISACodeBytes(MIOContext* context, SBYTE* ptrDst, ULONG nCount) {
|
||||
ERISA_PROB_MODEL* pProb = context->m_pLastERISAProb;
|
||||
int nSymbol, iSym;
|
||||
int i = 0;
|
||||
|
||||
while ((ULONG)i < nCount) {
|
||||
if (context->m_nLength > 0) {
|
||||
// zero-length
|
||||
ULONG nCurrent = nCount - i;
|
||||
if (nCurrent > context->m_nLength)
|
||||
nCurrent = context->m_nLength;
|
||||
|
||||
context->m_nLength -= nCurrent;
|
||||
for (ULONG j = 0; j < nCurrent; j++) {
|
||||
ptrDst[i++] = 0;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// decode next arithmetic code
|
||||
iSym = MIOContext_DecodeERISACodeIndex(context, pProb);
|
||||
if (iSym < 0)
|
||||
break;
|
||||
nSymbol = pProb->acsSymTable[iSym].wSymbol;
|
||||
EPM_IncreaseSymbol(pProb, iSym);
|
||||
ptrDst[i++] = (SBYTE)nSymbol;
|
||||
|
||||
if (nSymbol == 0) {
|
||||
// get zero-length
|
||||
iSym = MIOContext_DecodeERISACodeIndex(context, context->m_pRunLenProb);
|
||||
if (iSym < 0)
|
||||
break;
|
||||
context->m_nLength = context->m_pRunLenProb->acsSymTable[iSym].wSymbol;
|
||||
EPM_IncreaseSymbol(context->m_pRunLenProb, iSym);
|
||||
}
|
||||
|
||||
pProb = context->m_ppTableERISA[(nSymbol & 0xFF)];
|
||||
}
|
||||
context->m_pLastERISAProb = pProb;
|
||||
|
||||
return i;
|
||||
}
|
||||
|
||||
ULONG MIOContext_DecodeERISACodeWords(MIOContext* context, SWORD* ptrDst, ULONG nCount) {
|
||||
ERISA_PROB_MODEL* pProb = context->m_pLastERISAProb;
|
||||
int nSymbol, iSym;
|
||||
int i = 0;
|
||||
|
||||
while ((ULONG)i < nCount) {
|
||||
if (context->m_nLength > 0) {
|
||||
// zero-length
|
||||
ULONG nCurrent = nCount - i;
|
||||
if (nCurrent > context->m_nLength)
|
||||
nCurrent = context->m_nLength;
|
||||
|
||||
context->m_nLength -= nCurrent;
|
||||
for (ULONG j = 0; j < nCurrent; j++) {
|
||||
ptrDst[i++] = 0;
|
||||
}
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
// decode next arithmetic code
|
||||
iSym = MIOContext_DecodeERISACodeIndex(context, pProb);
|
||||
if (iSym < 0)
|
||||
break;
|
||||
nSymbol = pProb->acsSymTable[iSym].wSymbol;
|
||||
EPM_IncreaseSymbol(pProb, iSym);
|
||||
|
||||
|
||||
if (nSymbol == ERISA_ESCAPE_CODE) {
|
||||
iSym = MIOContext_DecodeERISACodeIndex(context, context->m_pPhraseIndexProb);
|
||||
if (iSym < 0)
|
||||
break;
|
||||
nSymbol = context->m_pPhraseIndexProb->acsSymTable[iSym].wSymbol;
|
||||
EPM_IncreaseSymbol(context->m_pPhraseIndexProb, iSym);
|
||||
|
||||
iSym = MIOContext_DecodeERISACodeIndex(context, context->m_pPhraseLenProb);
|
||||
if (iSym < 0)
|
||||
break;
|
||||
nSymbol = (nSymbol << 8) | (context->m_pPhraseLenProb->acsSymTable[iSym].wSymbol & 0xFF);
|
||||
EPM_IncreaseSymbol(context->m_pPhraseLenProb, iSym);
|
||||
|
||||
ptrDst[i++] = (SWORD)nSymbol;
|
||||
pProb = context->m_ppTableERISA[0x100];
|
||||
}
|
||||
else {
|
||||
ptrDst[i++] = (SWORD)(SBYTE)nSymbol;
|
||||
pProb = context->m_ppTableERISA[(nSymbol & 0xFF)];
|
||||
|
||||
if (nSymbol == 0) {
|
||||
// get zero-length
|
||||
iSym = MIOContext_DecodeERISACodeIndex(context, context->m_pRunLenProb);
|
||||
if (iSym < 0)
|
||||
break;
|
||||
context->m_nLength = context->m_pRunLenProb->acsSymTable[iSym].wSymbol;
|
||||
EPM_IncreaseSymbol(context->m_pRunLenProb, iSym);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
context->m_pLastERISAProb = pProb;
|
||||
|
||||
return i;
|
||||
}
|
|
@ -0,0 +1,123 @@
|
|||
/* Handles bitreading from blocks and code unpacking (huffman/arithmetical decoding).
|
||||
*/
|
||||
#ifndef _MIO_ERISA_CONTEXT_H_
|
||||
#define _MIO_ERISA_CONTEXT_H_
|
||||
|
||||
/* tree for huffman coding ("ERINA" codes) */
|
||||
|
||||
#define ERINA_CODE_FLAG 0x80000000u
|
||||
#define ERINA_HUFFMAN_ESCAPE 0x7FFFFFFF
|
||||
#define ERINA_HUFFMAN_NULL 0x8000u
|
||||
#define ERINA_HUFFMAN_MAX 0x4000
|
||||
#define ERINA_HUFFMAN_ROOT 0x200
|
||||
|
||||
#define MIO_HUFFMAN_SYMBOLS 256
|
||||
|
||||
typedef struct {
|
||||
uint16_t weight;
|
||||
uint16_t parent;
|
||||
uint32_t child_code;
|
||||
} ERINA_HUFFMAN_NODE;
|
||||
|
||||
typedef struct {
|
||||
ERINA_HUFFMAN_NODE m_hnTree[0x201];
|
||||
int m_iSymLookup[MIO_HUFFMAN_SYMBOLS];
|
||||
int m_iEscape;
|
||||
int m_iTreePointer;
|
||||
} ERINA_HUFFMAN_TREE;
|
||||
|
||||
|
||||
/* probability model for arithmetic coding ("ERISA" codes) */
|
||||
|
||||
#define ERISA_TOTAL_LIMIT 0x2000 // parameter limit
|
||||
#define ERISA_SYMBOL_SORTS 0x101 // max types
|
||||
#define ERISA_SUB_SORT_MAX 0x80
|
||||
#define ERISA_PROB_SLOT_MAX 0x800 // max slots for probability model
|
||||
#define ERISA_ESCAPE_CODE (-1)
|
||||
|
||||
typedef struct {
|
||||
WORD wOccured; // symbol occurence count
|
||||
SWORD wSymbol; // symbol (lower 8-bit only
|
||||
} ERISA_CODE_SYMBOL;
|
||||
|
||||
typedef struct {
|
||||
UDWORD dwTotalCount; // param < 2000H
|
||||
UDWORD dwSymbolSorts; // number of symbol types
|
||||
ERISA_CODE_SYMBOL acsSymTable[ERISA_SYMBOL_SORTS]; // probability model
|
||||
ERISA_CODE_SYMBOL acsSubModel[ERISA_SUB_SORT_MAX]; // sub-probability model index
|
||||
} ERISA_PROB_MODEL;
|
||||
|
||||
typedef enum {
|
||||
ERINAEncodingFlag_efERINAOrder0 = 0x0000,
|
||||
ERINAEncodingFlag_efERINAOrder1 = 0x0001
|
||||
} ERINAEncodingFlag;
|
||||
|
||||
|
||||
/* coding context for the decoder (AKA ERISADecodeContext), used to extract codes from a bitstream buffer */
|
||||
|
||||
typedef struct MIOContext MIOContext;
|
||||
struct MIOContext {
|
||||
// bitstream buffer
|
||||
int m_nIntBufCount; // helper input buffer bitpos
|
||||
UDWORD m_dwIntBuffer; // helper input buffer
|
||||
|
||||
uint8_t* m_pFileBuf;
|
||||
int m_pFileLength;
|
||||
int m_pFilePos;
|
||||
|
||||
// current symbol expansion
|
||||
ULONG (*m_pfnDecodeSymbolBytes)(MIOContext* context, SBYTE* ptrDst, ULONG nCount);
|
||||
|
||||
// for run-length encoding
|
||||
ULONG m_nLength;
|
||||
|
||||
// ERINA (huffman) code context
|
||||
UDWORD m_dwERINAFlags;
|
||||
ERINA_HUFFMAN_TREE* m_pLastHuffmanTree;
|
||||
ERINA_HUFFMAN_TREE** m_ppHuffmanTree;
|
||||
|
||||
// ERISA (arithmetic) code context
|
||||
UDWORD m_dwCodeRegister; // 16-bit
|
||||
UDWORD m_dwAugendRegister; // 16-bit
|
||||
int m_nPostBitCount; // end bit buffer counter
|
||||
|
||||
// ERISA-N context
|
||||
ERISA_PROB_MODEL* m_pPhraseLenProb;
|
||||
ERISA_PROB_MODEL* m_pPhraseIndexProb;
|
||||
ERISA_PROB_MODEL* m_pRunLenProb;
|
||||
ERISA_PROB_MODEL* m_pLastERISAProb;
|
||||
ERISA_PROB_MODEL** m_ppTableERISA;
|
||||
};
|
||||
|
||||
MIOContext* MIOContext_Open();
|
||||
void MIOContext_Close(MIOContext* context);
|
||||
|
||||
void MIOContext_AttachInputFile(MIOContext* context, uint8_t* pFileBuf, int pFileLength);
|
||||
|
||||
int MIOContext_GetABit(MIOContext* context);
|
||||
|
||||
UINT MIOContext_GetNBits(MIOContext* context, int n);
|
||||
|
||||
void MIOContext_FlushBuffer(MIOContext* context);
|
||||
|
||||
ULONG MIOContext_DecodeSymbolBytes(MIOContext* context, SBYTE* ptrDst, ULONG nCount);
|
||||
|
||||
ESLError MIOContext_PrepareToDecodeERINACode(MIOContext* context, UDWORD dwFlags);
|
||||
|
||||
// (indirect call)
|
||||
ULONG MIOContext_DecodeERINACodeBytes(MIOContext* context, SBYTE* ptrDst, ULONG nCount);
|
||||
|
||||
ESLError MIOContext_PrepareToDecodeERISACode(MIOContext* context);
|
||||
|
||||
void MIOContext_InitializeERISACode(MIOContext* context);
|
||||
|
||||
int MIOContext_DecodeERISACode(MIOContext* context, ERISA_PROB_MODEL* pModel);
|
||||
|
||||
//int MIOContext_DecodeERISACodeIndex(MIOContext* context, ERISA_PROB_MODEL* pModel);
|
||||
|
||||
// (indirect call)
|
||||
ULONG MIOContext_DecodeERISACodeBytes(MIOContext* context, SBYTE* ptrDst, ULONG nCount);
|
||||
|
||||
ULONG MIOContext_DecodeERISACodeWords(MIOContext* context, SWORD* ptrDst, ULONG nCount);
|
||||
|
||||
#endif
|
375
Frameworks/vgmstream/vgmstream/src/coding/libs/mio_erisafile.c
Normal file
375
Frameworks/vgmstream/vgmstream/src/coding/libs/mio_erisafile.c
Normal file
|
@ -0,0 +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;
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
/* iDTC/iLOT/etc helper functions.
|
||||
*/
|
||||
#ifndef _MIO_ERISA_FILE_H_
|
||||
#define _MIO_ERISA_FILE_H_
|
||||
|
||||
/* custom IO (OG lib uses FILEs) */
|
||||
#include "../../util/io_callback.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
EMC_FILE_HEADER emcfh; // base header (EMC = Entis Media Complex)
|
||||
ERI_FILE_HEADER erifh; // common file chunk
|
||||
MIO_INFO_HEADER mioih; // audio audio chunk
|
||||
uint32_t start;
|
||||
|
||||
char* desc; // text info
|
||||
int desc_len; // extra
|
||||
|
||||
MIO_DATA_HEADER miodh; // packet info
|
||||
uint8_t* buf;
|
||||
int buf_size;
|
||||
uint8_t* packet; //m_ptrBuffer
|
||||
int packet_size;
|
||||
|
||||
void* ptrWaveBuf; // not part of the original code but to simplify usage
|
||||
int ptrWaveBuf_len;
|
||||
} MIOFile;
|
||||
|
||||
MIOFile* MIOFile_Open();
|
||||
void MIOFile_Close(MIOFile* mf);
|
||||
ESLError MIOFile_Initialize(MIOFile* mf, io_callback_t* file);
|
||||
ESLError MIOFile_Reset(MIOFile* mf, io_callback_t* file);
|
||||
ESLError MIOFile_NextPacket(MIOFile* mf, io_callback_t* file);
|
||||
|
||||
int MIOFile_GetTagLoop(MIOFile* mf, const char* tag);
|
||||
// extra
|
||||
void* MIOFile_GetCurrentWaveBuffer(MIOFile* mf);
|
||||
int MIOFile_GetCurrentWaveBufferCount(MIOFile* mf);
|
||||
|
||||
#endif
|
392
Frameworks/vgmstream/vgmstream/src/coding/libs/mio_erisamatrix.c
Normal file
392
Frameworks/vgmstream/vgmstream/src/coding/libs/mio_erisamatrix.c
Normal file
|
@ -0,0 +1,392 @@
|
|||
/*****************************************************************************
|
||||
E R I S A - L i b r a r y
|
||||
----------------------------------------------------------------------------
|
||||
Copyright (C) 2000-2003 Leshade Entis. All rights reserved.
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <math.h>
|
||||
#include "mio_xerisa.h"
|
||||
|
||||
static volatile int g_eri_initialized = 0; //extra, not really that important but..
|
||||
|
||||
void ERI_eriInitializeLibrary(void) {
|
||||
if (g_eri_initialized)
|
||||
return;
|
||||
EMT_eriInitializeMatrix();
|
||||
g_eri_initialized = 1;
|
||||
}
|
||||
|
||||
void ERI_eriCloseLibrary(void) {
|
||||
}
|
||||
|
||||
//
|
||||
|
||||
static int round_f32(float r) {
|
||||
if (r >= 0.0) {
|
||||
return (int)floor(r + 0.5);
|
||||
}
|
||||
else {
|
||||
return (int)ceil(r - 0.5);
|
||||
}
|
||||
}
|
||||
|
||||
void EMT_eriRoundR32ToWordArray(SWORD* ptrDst, int nStep, const float* ptrSrc, int nCount) {
|
||||
for (int i = 0; i < nCount; i++) {
|
||||
int nValue = round_f32(ptrSrc[i]);
|
||||
if (nValue <= -0x8000) {
|
||||
*ptrDst = -0x8000;
|
||||
}
|
||||
else if (nValue >= 0x7FFF) {
|
||||
*ptrDst = 0x7FFF;
|
||||
}
|
||||
else {
|
||||
*ptrDst = (SWORD)nValue;
|
||||
}
|
||||
ptrDst += nStep;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static const double ERI_PI = 3.141592653589; // = π
|
||||
static const float ERI_rHalf = 0.5F; // = 1/2
|
||||
//static const float ERI_r2 = 2.0F; // = 2.0
|
||||
|
||||
// revolve 2-point matrix (for MSS)
|
||||
void EMT_eriRevolve2x2(float* ptrBuf1, float* ptrBuf2, float rSin, float rCos, unsigned int nStep, unsigned int nCount) {
|
||||
for (int i = 0; i < nCount; i++) {
|
||||
float r1 = *ptrBuf1;
|
||||
float r2 = *ptrBuf2;
|
||||
|
||||
*ptrBuf1 = r1 * rCos - r2 * rSin;
|
||||
*ptrBuf2 = r1 * rSin + r2 * rCos;
|
||||
|
||||
ptrBuf1 += nStep;
|
||||
ptrBuf2 += nStep;
|
||||
}
|
||||
}
|
||||
|
||||
// create rotation matrix parameter for LOT transformation
|
||||
ERI_SIN_COS* EMT_eriCreateRevolveParameter(unsigned int nDegreeDCT) {
|
||||
int i, nDegreeNum;
|
||||
nDegreeNum = 1 << nDegreeDCT;
|
||||
|
||||
int lc = 1, n = nDegreeNum / 2;
|
||||
while (n >= 8) {
|
||||
n /= 8;
|
||||
++lc;
|
||||
}
|
||||
|
||||
ERI_SIN_COS* ptrRevolve = malloc(lc * 8 * sizeof(ERI_SIN_COS));
|
||||
if (!ptrRevolve)
|
||||
return NULL;
|
||||
|
||||
double k = ERI_PI / (nDegreeNum * 2);
|
||||
ERI_SIN_COS* ptrNextRev = ptrRevolve;
|
||||
int nStep = 2;
|
||||
do {
|
||||
for (i = 0; i < 7; i++) {
|
||||
double ws = 1.0;
|
||||
double a = 0.0;
|
||||
for (int j = 0; j < i; j++) {
|
||||
a += nStep;
|
||||
ws = ws * ptrNextRev[j].rSin + ptrNextRev[j].rCos * cos(a * k);
|
||||
}
|
||||
double r = atan2(ws, cos((a + nStep) * k));
|
||||
ptrNextRev[i].rSin = (float)sin(r);
|
||||
ptrNextRev[i].rCos = (float)cos(r);
|
||||
}
|
||||
ptrNextRev += 7;
|
||||
nStep *= 8;
|
||||
}
|
||||
while (nStep < nDegreeNum);
|
||||
|
||||
return ptrRevolve;
|
||||
}
|
||||
|
||||
void EMT_eriOddGivensInverseMatrix(float* ptrSrc, const ERI_SIN_COS* ptrRevolve, unsigned int nDegreeDCT) {
|
||||
int i, j, k;
|
||||
int nDegreeNum = 1 << nDegreeDCT;
|
||||
|
||||
// odd number rotate operation
|
||||
int nStep, lc, index;
|
||||
index = 1;
|
||||
nStep = 2;
|
||||
lc = (nDegreeNum / 2) / 8;
|
||||
|
||||
for (;;) {
|
||||
ptrRevolve += 7;
|
||||
index += nStep * 7;
|
||||
nStep *= 8;
|
||||
if (lc <= 8)
|
||||
break;
|
||||
lc /= 8;
|
||||
}
|
||||
|
||||
k = index + nStep * (lc - 2);
|
||||
for (j = lc - 2; j >= 0; j--) {
|
||||
float r1 = ptrSrc[k];
|
||||
float r2 = ptrSrc[k + nStep];
|
||||
ptrSrc[k] = r1 * ptrRevolve[j].rCos + r2 * ptrRevolve[j].rSin;
|
||||
ptrSrc[k + nStep] = r2 * ptrRevolve[j].rCos - r1 * ptrRevolve[j].rSin;
|
||||
k -= nStep;
|
||||
}
|
||||
|
||||
for (;;) {
|
||||
if (lc > (nDegreeNum / 2) / 8)
|
||||
break;
|
||||
|
||||
ptrRevolve -= 7;
|
||||
nStep /= 8;
|
||||
index -= nStep * 7;
|
||||
|
||||
for (i = 0; i < lc; i++) {
|
||||
k = i * (nStep * 8) + index + nStep * 6;
|
||||
for (j = 6; j >= 0; j--) {
|
||||
float r1 = ptrSrc[k];
|
||||
float r2 = ptrSrc[k + nStep];
|
||||
ptrSrc[k] = r1 * ptrRevolve[j].rCos + r2 * ptrRevolve[j].rSin;
|
||||
ptrSrc[k + nStep] = r2 * ptrRevolve[j].rCos - r1 * ptrRevolve[j].rSin;
|
||||
k -= nStep;
|
||||
}
|
||||
}
|
||||
|
||||
lc *= 8;
|
||||
}
|
||||
}
|
||||
|
||||
// Inverse Previous LOT
|
||||
void EMT_eriFastIPLOT(float* ptrSrc, unsigned int nDegreeDCT) {
|
||||
unsigned int nDegreeNum = 1 << nDegreeDCT;
|
||||
|
||||
// divide odd and even freqs
|
||||
for (int i = 0; i < nDegreeNum; i += 2) {
|
||||
float r1 = ptrSrc[i];
|
||||
float r2 = ptrSrc[i + 1];
|
||||
ptrSrc[i] = ERI_rHalf * (r1 + r2);
|
||||
ptrSrc[i + 1] = ERI_rHalf * (r1 - r2);
|
||||
}
|
||||
}
|
||||
|
||||
// Inverse LOT
|
||||
void EMT_eriFastILOT(float* ptrDst, const float* ptrSrc1, const float* ptrSrc2, unsigned int nDegreeDCT) {
|
||||
unsigned int nDegreeNum = 1 << nDegreeDCT;
|
||||
|
||||
// reverse duplication
|
||||
for (int i = 0; i < nDegreeNum; i += 2) {
|
||||
float r1 = ptrSrc1[i];
|
||||
float r2 = ptrSrc2[i + 1];
|
||||
ptrDst[i] = r1 + r2;
|
||||
ptrDst[i + 1] = r1 - r2;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static float ERI_rCosPI4; // = cos(pi/4)
|
||||
static float ERI_r2CosPI4; // = 2*cos(pi/4)
|
||||
|
||||
// matrix coefs: k(n,i) = cos( (2*i+1) / (4*n) )
|
||||
//
|
||||
static float ERI_DCTofK2[2]; // = cos( (2*i+1) / 8 )
|
||||
static float ERI_DCTofK4[4]; // = cos( (2*i+1) / 16 )
|
||||
static float ERI_DCTofK8[8]; // = cos( (2*i+1) / 32 )
|
||||
static float ERI_DCTofK16[16]; // = cos( (2*i+1) / 64 )
|
||||
static float ERI_DCTofK32[32]; // = cos( (2*i+1) / 128 )
|
||||
static float ERI_DCTofK64[64]; // = cos( (2*i+1) / 256 )
|
||||
static float ERI_DCTofK128[128]; // = cos( (2*i+1) / 512 )
|
||||
static float ERI_DCTofK256[256]; // = cos( (2*i+1) / 1024 )
|
||||
static float ERI_DCTofK512[512]; // = cos( (2*i+1) / 2048 )
|
||||
static float ERI_DCTofK1024[1024]; // = cos( (2*i+1) / 4096 )
|
||||
static float ERI_DCTofK2048[2048]; // = cos( (2*i+1) / 8192 )
|
||||
|
||||
// matrix coefs table
|
||||
static float* ERI_pMatrixDCTofK[MAX_DCT_DEGREE] = {
|
||||
NULL,
|
||||
ERI_DCTofK2,
|
||||
ERI_DCTofK4,
|
||||
ERI_DCTofK8,
|
||||
ERI_DCTofK16,
|
||||
ERI_DCTofK32,
|
||||
ERI_DCTofK64,
|
||||
ERI_DCTofK128,
|
||||
ERI_DCTofK256,
|
||||
ERI_DCTofK512,
|
||||
ERI_DCTofK1024,
|
||||
ERI_DCTofK2048
|
||||
};
|
||||
|
||||
// initialize tables for DCT matrix operations
|
||||
void EMT_eriInitializeMatrix(void) {
|
||||
// prepare special constants
|
||||
ERI_rCosPI4 = (float)cos(ERI_PI * 0.25);
|
||||
ERI_r2CosPI4 = 2.0F * ERI_rCosPI4;
|
||||
|
||||
// matrix coefs init
|
||||
for (int i = 1; i < MAX_DCT_DEGREE; i++) {
|
||||
int n = (1 << i);
|
||||
float* pDCTofK = ERI_pMatrixDCTofK[i];
|
||||
double nr = ERI_PI / (4.0 * n);
|
||||
double dr = nr + nr;
|
||||
double ir = nr;
|
||||
|
||||
for (int j = 0; j < n; j++) {
|
||||
pDCTofK[j] = (float)cos(ir);
|
||||
ir += dr;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void eriFastDCT(float* ptrDst, unsigned int nDstInterval, float* ptrSrc, float* ptrWorkBuf, unsigned int nDegreeDCT) {
|
||||
if (nDegreeDCT < MIN_DCT_DEGREE || nDegreeDCT > MAX_DCT_DEGREE)
|
||||
return;
|
||||
|
||||
if (nDegreeDCT == MIN_DCT_DEGREE) {
|
||||
// 4th order DCT
|
||||
float r32Buf[4];
|
||||
|
||||
// cross ops
|
||||
r32Buf[0] = ptrSrc[0] + ptrSrc[3];
|
||||
r32Buf[2] = ptrSrc[0] - ptrSrc[3];
|
||||
r32Buf[1] = ptrSrc[1] + ptrSrc[2];
|
||||
r32Buf[3] = ptrSrc[1] - ptrSrc[2];
|
||||
|
||||
// first half: A2 * DCT2
|
||||
ptrDst[0] = ERI_rHalf * (r32Buf[0] + r32Buf[1]);
|
||||
ptrDst[nDstInterval * 2] = ERI_rCosPI4 * (r32Buf[0] - r32Buf[1]);
|
||||
|
||||
// last half: R2 * 2 * A2 * DCT2 * K2
|
||||
r32Buf[2] = ERI_DCTofK2[0] * r32Buf[2];
|
||||
r32Buf[3] = ERI_DCTofK2[1] * r32Buf[3];
|
||||
|
||||
r32Buf[0] = r32Buf[2] + r32Buf[3];
|
||||
r32Buf[1] = ERI_r2CosPI4 * (r32Buf[2] - r32Buf[3]);
|
||||
|
||||
r32Buf[1] -= r32Buf[0];
|
||||
|
||||
ptrDst[nDstInterval] = r32Buf[0];
|
||||
ptrDst[nDstInterval * 3] = r32Buf[1];
|
||||
}
|
||||
else {
|
||||
// regular DCT
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
// | I J |
|
||||
// cross ops = | |
|
||||
// | I -J |
|
||||
unsigned int nDegreeNum = (1 << nDegreeDCT);
|
||||
unsigned int nHalfDegree = (nDegreeNum >> 1);
|
||||
for (int i = 0; i < nHalfDegree; i++) {
|
||||
ptrWorkBuf[i] = ptrSrc[i] + ptrSrc[nDegreeNum - i - 1];
|
||||
ptrWorkBuf[i + nHalfDegree] = ptrSrc[i] - ptrSrc[nDegreeNum - i - 1];
|
||||
}
|
||||
|
||||
// first half DCT : A * DCT
|
||||
unsigned int nDstStep = (nDstInterval << 1);
|
||||
eriFastDCT(ptrDst, nDstStep, ptrWorkBuf, ptrSrc, (nDegreeDCT - 1));
|
||||
|
||||
// last half DCT-IV : R * 2 * A * DCT * K
|
||||
float* pDCTofK = ERI_pMatrixDCTofK[nDegreeDCT - 1];
|
||||
ptrSrc = ptrWorkBuf + nHalfDegree;
|
||||
ptrDst += nDstInterval;
|
||||
|
||||
for (int i = 0; i < nHalfDegree; i++) {
|
||||
ptrSrc[i] *= pDCTofK[i];
|
||||
}
|
||||
|
||||
eriFastDCT(ptrDst, nDstStep, ptrSrc, ptrWorkBuf, (nDegreeDCT - 1));
|
||||
|
||||
float* ptrNext = ptrDst;
|
||||
for (int i = 0; i < nHalfDegree; i++) {
|
||||
*ptrNext += *ptrNext;
|
||||
ptrNext += nDstStep;
|
||||
}
|
||||
|
||||
ptrNext = ptrDst;
|
||||
for (int i = 1; i < nHalfDegree; i++) {
|
||||
ptrNext[nDstStep] -= *ptrNext;
|
||||
ptrNext += nDstStep;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void EMT_eriFastIDCT(float* ptrDst, float* ptrSrc, unsigned int nSrcInterval, float* ptrWorkBuf, unsigned int nDegreeDCT) {
|
||||
if (nDegreeDCT < MIN_DCT_DEGREE || nDegreeDCT > MAX_DCT_DEGREE)
|
||||
return;
|
||||
|
||||
if (nDegreeDCT == MIN_DCT_DEGREE) {
|
||||
// 4th order IDCT
|
||||
float r32Buf1[2];
|
||||
float r32Buf2[4];
|
||||
|
||||
// even rows: IDCT2
|
||||
r32Buf1[0] = ptrSrc[0];
|
||||
r32Buf1[1] = ERI_rCosPI4 * ptrSrc[nSrcInterval * 2];
|
||||
|
||||
r32Buf2[0] = r32Buf1[0] + r32Buf1[1];
|
||||
r32Buf2[1] = r32Buf1[0] - r32Buf1[1];
|
||||
|
||||
// odd rows: R * 2 * A * DCT * K
|
||||
r32Buf1[0] = ERI_DCTofK2[0] * ptrSrc[nSrcInterval];
|
||||
r32Buf1[1] = ERI_DCTofK2[1] * ptrSrc[nSrcInterval * 3];
|
||||
|
||||
r32Buf2[2] = r32Buf1[0] + r32Buf1[1];
|
||||
r32Buf2[3] = ERI_r2CosPI4 * (r32Buf1[0] - r32Buf1[1]);
|
||||
|
||||
r32Buf2[3] -= r32Buf2[2];
|
||||
|
||||
// cross ops
|
||||
ptrDst[0] = r32Buf2[0] + r32Buf2[2];
|
||||
ptrDst[3] = r32Buf2[0] - r32Buf2[2];
|
||||
ptrDst[1] = r32Buf2[1] + r32Buf2[3];
|
||||
ptrDst[2] = r32Buf2[1] - r32Buf2[3];
|
||||
}
|
||||
else {
|
||||
// regular IDCT
|
||||
//////////////////////////////////////////////////////////////////////
|
||||
|
||||
// even rows: IDCT
|
||||
unsigned int nDegreeNum = (1 << nDegreeDCT);
|
||||
unsigned int nHalfDegree = (nDegreeNum >> 1);
|
||||
unsigned int nSrcStep = (nSrcInterval << 1);
|
||||
EMT_eriFastIDCT(ptrDst, ptrSrc, nSrcStep, ptrWorkBuf, (nDegreeDCT - 1));
|
||||
|
||||
// odd rows: R * 2 * A * DCT * K
|
||||
float* pDCTofK = ERI_pMatrixDCTofK[nDegreeDCT - 1];
|
||||
float* pOddSrc = ptrSrc + nSrcInterval;
|
||||
float* pOddDst = ptrDst + nHalfDegree;
|
||||
|
||||
float* ptrNext = pOddSrc;
|
||||
for (int i = 0; i < nHalfDegree; i++) {
|
||||
ptrWorkBuf[i] = *ptrNext * pDCTofK[i];
|
||||
ptrNext += nSrcStep;
|
||||
}
|
||||
|
||||
eriFastDCT(pOddDst, 1, ptrWorkBuf, (ptrWorkBuf + nHalfDegree), (nDegreeDCT - 1));
|
||||
|
||||
for (int i = 0; i < nHalfDegree; i++) {
|
||||
pOddDst[i] += pOddDst[i];
|
||||
}
|
||||
|
||||
for (int i = 1; i < nHalfDegree; i++) {
|
||||
pOddDst[i] -= pOddDst[i - 1];
|
||||
}
|
||||
|
||||
// | I I |
|
||||
// cross ops = | |
|
||||
// | J -J |
|
||||
float r32Buf[4];
|
||||
unsigned int nQuadDegree = (nHalfDegree >> 1);
|
||||
for (int i = 0; i < nQuadDegree; i++) {
|
||||
r32Buf[0] = ptrDst[i] + ptrDst[nHalfDegree + i];
|
||||
r32Buf[3] = ptrDst[i] - ptrDst[nHalfDegree + i];
|
||||
r32Buf[1] = ptrDst[nHalfDegree - 1 - i] + ptrDst[nDegreeNum - 1 - i];
|
||||
r32Buf[2] = ptrDst[nHalfDegree - 1 - i] - ptrDst[nDegreeNum - 1 - i];
|
||||
|
||||
ptrDst[i] = r32Buf[0];
|
||||
ptrDst[nHalfDegree - 1 - i] = r32Buf[1];
|
||||
ptrDst[nHalfDegree + i] = r32Buf[2];
|
||||
ptrDst[nDegreeNum - 1 - i] = r32Buf[3];
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
/* Handles file ops like parsing header and reading blocks.
|
||||
*/
|
||||
#ifndef _MIO_ERISA_MATRIX_H_
|
||||
#define _MIO_ERISA_MATRIX_H_
|
||||
|
||||
#define MIN_DCT_DEGREE 2
|
||||
#define MAX_DCT_DEGREE 12
|
||||
|
||||
typedef struct {
|
||||
float rSin;
|
||||
float rCos;
|
||||
} ERI_SIN_COS;
|
||||
|
||||
|
||||
void EMT_eriInitializeMatrix(void);
|
||||
|
||||
void EMT_eriRoundR32ToWordArray(SWORD* ptrDst, int nStep, const float* ptrSrc, int nCount);
|
||||
|
||||
void EMT_eriRevolve2x2(float* ptrBuf1, float* ptrBuf2, float rSin, float rCos, unsigned int nStep, unsigned int nCount);
|
||||
|
||||
ERI_SIN_COS* EMT_eriCreateRevolveParameter(unsigned int nDegreeDCT);
|
||||
|
||||
void EMT_eriOddGivensInverseMatrix(float* ptrSrc, const ERI_SIN_COS* ptrRevolve, unsigned int nDegreeDCT);
|
||||
|
||||
void EMT_eriFastIPLOT(float* ptrSrc, unsigned int nDegreeDCT);
|
||||
void EMT_eriFastILOT(float* ptrDst, const float* ptrSrc1, const float* ptrSrc2, unsigned int nDegreeDCT);
|
||||
|
||||
void EMT_eriFastIDCT(float* ptrDst, float* ptrSrc, unsigned int nSrcInterval, float* ptrWorkBuf, unsigned int nDegreeDCT);
|
||||
|
||||
#endif
|
991
Frameworks/vgmstream/vgmstream/src/coding/libs/mio_erisasound.c
Normal file
991
Frameworks/vgmstream/vgmstream/src/coding/libs/mio_erisasound.c
Normal file
|
@ -0,0 +1,991 @@
|
|||
/*****************************************************************************
|
||||
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 <math.h>
|
||||
#include "mio_xerisa.h"
|
||||
|
||||
static const double ERI_PI = 3.141592653589;
|
||||
#define MIO_MAX_CHANNELS 2
|
||||
|
||||
|
||||
/*******************/
|
||||
/* audio converter */
|
||||
/*******************/
|
||||
|
||||
MIODecoder* MIODecoder_Open() {
|
||||
MIODecoder* dec = calloc(1, sizeof(MIODecoder));
|
||||
if (!dec)
|
||||
return NULL;
|
||||
|
||||
dec->m_nBufLength = 0;
|
||||
dec->m_ptrBuffer1 = NULL;
|
||||
dec->m_ptrBuffer2 = NULL;
|
||||
dec->m_ptrBuffer3 = NULL;
|
||||
dec->m_ptrDivisionTable = NULL;
|
||||
dec->m_ptrRevolveCode = NULL;
|
||||
dec->m_ptrWeightCode = NULL;
|
||||
dec->m_ptrCoefficient = NULL;
|
||||
dec->m_ptrMatrixBuf = NULL;
|
||||
dec->m_ptrInternalBuf = NULL;
|
||||
dec->m_ptrWorkBuf = NULL;
|
||||
dec->m_ptrWeightTable = NULL;
|
||||
dec->m_ptrLastDCT = NULL;
|
||||
dec->m_pRevolveParam = NULL;
|
||||
return dec;
|
||||
}
|
||||
|
||||
static void MIODecoder_Delete(MIODecoder* dec) {
|
||||
free(dec->m_ptrBuffer1);
|
||||
dec->m_ptrBuffer1 = NULL;
|
||||
free(dec->m_ptrBuffer2);
|
||||
dec->m_ptrBuffer2 = NULL;
|
||||
free(dec->m_ptrBuffer3);
|
||||
dec->m_ptrBuffer3 = NULL;
|
||||
free(dec->m_ptrDivisionTable);
|
||||
dec->m_ptrDivisionTable = NULL;
|
||||
free(dec->m_ptrRevolveCode);
|
||||
dec->m_ptrRevolveCode = NULL;
|
||||
free(dec->m_ptrWeightCode);
|
||||
dec->m_ptrWeightCode = NULL;
|
||||
free(dec->m_ptrCoefficient);
|
||||
dec->m_ptrCoefficient = NULL;
|
||||
free(dec->m_ptrMatrixBuf);
|
||||
dec->m_ptrMatrixBuf = NULL;
|
||||
free(dec->m_ptrInternalBuf);
|
||||
dec->m_ptrInternalBuf = NULL;
|
||||
free(dec->m_ptrWorkBuf);
|
||||
dec->m_ptrWorkBuf = NULL;
|
||||
free(dec->m_ptrWeightTable);
|
||||
dec->m_ptrWeightTable = NULL;
|
||||
free(dec->m_ptrLastDCT);
|
||||
dec->m_ptrLastDCT = NULL;
|
||||
free(dec->m_pRevolveParam);
|
||||
dec->m_pRevolveParam = NULL;
|
||||
|
||||
dec->m_nBufLength = 0;
|
||||
}
|
||||
|
||||
void MIODecoder_Close(MIODecoder* dec) {
|
||||
if (!dec)
|
||||
return;
|
||||
MIODecoder_Delete(dec);
|
||||
free(dec);
|
||||
}
|
||||
|
||||
// recalculate matrix size when params change
|
||||
static int MIODecoder_InitializeWithDegree(MIODecoder* dec, unsigned int nSubbandDegree) {
|
||||
free(dec->m_pRevolveParam);
|
||||
dec->m_pRevolveParam = EMT_eriCreateRevolveParameter(nSubbandDegree);
|
||||
if (!dec->m_pRevolveParam) return eslErrGeneral;
|
||||
|
||||
// params for inverse quantization
|
||||
static const int freq_width[7] = { -6, -6, -5, -4, -3, -2, -1 };
|
||||
for (int i = 0, j = 0; i < 7; i++) {
|
||||
int nFrequencyWidth = 1 << (nSubbandDegree + freq_width[i]);
|
||||
dec->m_nFrequencyPoint[i] = j + (nFrequencyWidth / 2);
|
||||
j += nFrequencyWidth;
|
||||
}
|
||||
|
||||
dec->m_nSubbandDegree = nSubbandDegree;
|
||||
dec->m_nDegreeNum = (1 << nSubbandDegree);
|
||||
|
||||
return eslErrSuccess;
|
||||
}
|
||||
|
||||
ESLError MIODecoder_Initialize(MIODecoder* dec, const MIO_INFO_HEADER* infhdr) {
|
||||
MIODecoder_Delete(dec);
|
||||
|
||||
dec->m_mioih = *infhdr; /* copy */
|
||||
|
||||
if (dec->m_mioih.fdwTransformation == CVTYPE_LOSSLESS_ERI) {
|
||||
if (dec->m_mioih.dwArchitecture != ERI_RUNLENGTH_HUFFMAN)
|
||||
return eslErrGeneral;
|
||||
|
||||
if ((dec->m_mioih.dwChannelCount != 1) && (dec->m_mioih.dwChannelCount != 2))
|
||||
return eslErrGeneral;
|
||||
|
||||
if ((dec->m_mioih.dwBitsPerSample != 8) && (dec->m_mioih.dwBitsPerSample != 16))
|
||||
return eslErrGeneral;
|
||||
}
|
||||
else if ((dec->m_mioih.fdwTransformation == CVTYPE_LOT_ERI) || (dec->m_mioih.fdwTransformation == CVTYPE_LOT_ERI_MSS)) {
|
||||
|
||||
if ((dec->m_mioih.dwArchitecture != ERI_RUNLENGTH_GAMMA) &&
|
||||
(dec->m_mioih.dwArchitecture != ERI_RUNLENGTH_HUFFMAN) &&
|
||||
(dec->m_mioih.dwArchitecture != ERISA_NEMESIS_CODE))
|
||||
return eslErrGeneral; /* unknown code format */
|
||||
|
||||
if ((dec->m_mioih.dwChannelCount != 1) && (dec->m_mioih.dwChannelCount != 2))
|
||||
return eslErrGeneral;
|
||||
|
||||
if (dec->m_mioih.dwBitsPerSample != 16)
|
||||
return eslErrGeneral;
|
||||
|
||||
if ((dec->m_mioih.dwSubbandDegree < 8) || (dec->m_mioih.dwSubbandDegree > MAX_DCT_DEGREE))
|
||||
return eslErrGeneral;
|
||||
|
||||
if (dec->m_mioih.dwLappedDegree != 1)
|
||||
return eslErrGeneral;
|
||||
|
||||
// DCT buffers
|
||||
{
|
||||
int channel_size = sizeof(float) << dec->m_mioih.dwSubbandDegree;
|
||||
int buf_size = dec->m_mioih.dwChannelCount * channel_size;
|
||||
dec->m_ptrBuffer1 = malloc(buf_size);
|
||||
dec->m_ptrMatrixBuf = malloc(buf_size);
|
||||
dec->m_ptrInternalBuf = malloc(buf_size);
|
||||
dec->m_ptrWorkBuf = malloc(channel_size);
|
||||
if (!dec->m_ptrBuffer1 || !dec->m_ptrMatrixBuf || !dec->m_ptrInternalBuf || !dec->m_ptrWorkBuf)
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
// dequantization buffers
|
||||
{
|
||||
int channel_size = sizeof(float) << dec->m_mioih.dwSubbandDegree;
|
||||
dec->m_ptrWeightTable = malloc(channel_size);
|
||||
if (!dec->m_ptrWeightTable)
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
// LOT buffers
|
||||
{
|
||||
int nBlocksetSamples = dec->m_mioih.dwChannelCount << dec->m_mioih.dwSubbandDegree;
|
||||
int nLappedSamples = nBlocksetSamples * dec->m_mioih.dwLappedDegree;
|
||||
if (nLappedSamples > 0) {
|
||||
dec->m_ptrLastDCT = malloc(sizeof(float) * nLappedSamples);
|
||||
if (!dec->m_ptrLastDCT)
|
||||
return eslErrGeneral;
|
||||
|
||||
for (int i = 0; i < nLappedSamples; i++) {
|
||||
dec->m_ptrLastDCT[i] = 0.0F;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (MIODecoder_InitializeWithDegree(dec, dec->m_mioih.dwSubbandDegree))
|
||||
return eslErrGeneral;
|
||||
}
|
||||
else {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
return eslErrSuccess;
|
||||
}
|
||||
|
||||
static ESLError MIODecoder_DecodeSoundPCM8(MIODecoder* dec, MIOContext* context, const MIO_DATA_HEADER* datahdr, void* ptrWaveBuf) {
|
||||
unsigned int nSampleCount = datahdr->dwSampleCount;
|
||||
unsigned int nChannelCount = dec->m_mioih.dwChannelCount;
|
||||
unsigned int nAllSampleCount = nSampleCount * nChannelCount;
|
||||
ULONG nBytes = nAllSampleCount * sizeof(BYTE);
|
||||
|
||||
if (nSampleCount > dec->m_nBufLength) {
|
||||
free(dec->m_ptrBuffer1);
|
||||
dec->m_ptrBuffer1 = malloc(nBytes);
|
||||
if (!dec->m_ptrBuffer1)
|
||||
return eslErrGeneral;
|
||||
|
||||
dec->m_nBufLength = nSampleCount;
|
||||
}
|
||||
|
||||
// prepare huffman codes
|
||||
if (datahdr->bytFlags & MIO_LEAD_BLOCK) {
|
||||
ESLError err = MIOContext_PrepareToDecodeERINACode(context, ERINAEncodingFlag_efERINAOrder1);
|
||||
if (err != eslErrSuccess) return err;
|
||||
}
|
||||
|
||||
if (MIOContext_DecodeSymbolBytes(context, (SBYTE*)dec->m_ptrBuffer1, nBytes) < nBytes) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
// differential processing output
|
||||
BYTE* ptrSrcBuf = dec->m_ptrBuffer1;
|
||||
BYTE* ptrDstBuf;
|
||||
unsigned int nStep = nChannelCount;
|
||||
unsigned int i, j;
|
||||
for (i = 0; i < dec->m_mioih.dwChannelCount; i++) {
|
||||
ptrDstBuf = ptrWaveBuf;
|
||||
ptrDstBuf += i;
|
||||
|
||||
BYTE bytValue = 0;
|
||||
for (j = 0; j < nSampleCount; j++) {
|
||||
bytValue += *(ptrSrcBuf++);
|
||||
*ptrDstBuf = bytValue;
|
||||
ptrDstBuf += nStep;
|
||||
}
|
||||
}
|
||||
|
||||
return eslErrSuccess;
|
||||
}
|
||||
|
||||
static ESLError MIODecoder_DecodeSoundPCM16(MIODecoder* dec, MIOContext* context, const MIO_DATA_HEADER* datahdr, void* ptrWaveBuf) {
|
||||
unsigned int i, j;
|
||||
unsigned int nSampleCount = datahdr->dwSampleCount;
|
||||
unsigned int nChannelCount = dec->m_mioih.dwChannelCount;
|
||||
unsigned int nAllSampleCount = nSampleCount * nChannelCount;
|
||||
ULONG nBytes = nAllSampleCount * sizeof(SWORD);
|
||||
|
||||
if (nSampleCount > dec->m_nBufLength) {
|
||||
free(dec->m_ptrBuffer1);
|
||||
free(dec->m_ptrBuffer2);
|
||||
dec->m_ptrBuffer1 = malloc(nBytes);
|
||||
dec->m_ptrBuffer2 = malloc(nBytes);
|
||||
if (!dec->m_ptrBuffer1 || !dec->m_ptrBuffer2)
|
||||
return eslErrGeneral;
|
||||
|
||||
dec->m_nBufLength = nSampleCount;
|
||||
}
|
||||
|
||||
// prepare huffman codes
|
||||
if (datahdr->bytFlags & MIO_LEAD_BLOCK) {
|
||||
ESLError err = MIOContext_PrepareToDecodeERINACode(context, ERINAEncodingFlag_efERINAOrder1);
|
||||
if (err != eslErrSuccess) return err;
|
||||
}
|
||||
|
||||
if (MIOContext_DecodeSymbolBytes(context, (SBYTE*)dec->m_ptrBuffer1, nBytes) < nBytes) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
// pack hi/lo bytes
|
||||
BYTE* pbytSrcBuf1;
|
||||
BYTE* pbytSrcBuf2;
|
||||
BYTE* pbytDstBuf;
|
||||
for (i = 0; i < nChannelCount; i++) {
|
||||
unsigned int nOffset = i * nSampleCount * sizeof(SWORD);
|
||||
pbytSrcBuf1 = ((BYTE*)dec->m_ptrBuffer1) + nOffset;
|
||||
pbytSrcBuf2 = pbytSrcBuf1 + nSampleCount;
|
||||
pbytDstBuf = ((BYTE*)dec->m_ptrBuffer2) + nOffset;
|
||||
|
||||
for (j = 0; j < nSampleCount; j++) {
|
||||
SBYTE bytLow = pbytSrcBuf2[j];
|
||||
SBYTE bytHigh = pbytSrcBuf1[j];
|
||||
pbytDstBuf[j * sizeof(SWORD) + 0] = bytLow;
|
||||
pbytDstBuf[j * sizeof(SWORD) + 1] = bytHigh ^ (bytLow >> 7);
|
||||
}
|
||||
}
|
||||
|
||||
// differential processing output
|
||||
SWORD* ptrSrcBuf = dec->m_ptrBuffer2;
|
||||
SWORD* ptrDstBuf;
|
||||
unsigned int nStep = dec->m_mioih.dwChannelCount;
|
||||
for (i = 0; i < dec->m_mioih.dwChannelCount; i++) {
|
||||
ptrDstBuf = ptrWaveBuf;
|
||||
ptrDstBuf += i;
|
||||
|
||||
SWORD wValue = 0;
|
||||
SWORD wDelta = 0;
|
||||
for (j = 0; j < nSampleCount; j++) {
|
||||
wDelta += *(ptrSrcBuf++);
|
||||
wValue += wDelta;
|
||||
*ptrDstBuf = wValue;
|
||||
ptrDstBuf += nStep;
|
||||
}
|
||||
}
|
||||
|
||||
return eslErrSuccess;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static void MIODecoder_IQuantumize(MIODecoder* dec, float* ptrDestination, const INT* ptrQuantumized, int nDegreeNum, SDWORD nWeightCode, int nCoefficient) {
|
||||
int i, j;
|
||||
double rMatrixScale = sqrt(2.0 / nDegreeNum);
|
||||
double rCoefficient = rMatrixScale * nCoefficient;
|
||||
|
||||
// generate weight table
|
||||
double rAvgRatio[7];
|
||||
for (i = 0; i < 6; i++) {
|
||||
rAvgRatio[i] = 1.0 / pow(2.0, (((nWeightCode >> (i * 5)) & 0x1F) - 15) * 0.5);
|
||||
}
|
||||
rAvgRatio[6] = 1.0;
|
||||
|
||||
for (i = 0; i < dec->m_nFrequencyPoint[0]; i++) {
|
||||
dec->m_ptrWeightTable[i] = (float)rAvgRatio[0];
|
||||
}
|
||||
|
||||
for (j = 1; j < 7; j++) {
|
||||
double a = rAvgRatio[j - 1];
|
||||
double k = (rAvgRatio[j] - a) / (dec->m_nFrequencyPoint[j] - dec->m_nFrequencyPoint[j - 1]);
|
||||
while (i < dec->m_nFrequencyPoint[j]) {
|
||||
dec->m_ptrWeightTable[i] = (float)(k * (i - dec->m_nFrequencyPoint[j - 1]) + a);
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
while (i < nDegreeNum) {
|
||||
dec->m_ptrWeightTable[i] = (float)rAvgRatio[6];
|
||||
i++;
|
||||
}
|
||||
|
||||
float rOddWeight = (float)((((nWeightCode >> 30) & 0x03) + 0x02) / 2.0);
|
||||
for (i = 15; i < nDegreeNum; i += 16) {
|
||||
dec->m_ptrWeightTable[i] *= rOddWeight;
|
||||
}
|
||||
dec->m_ptrWeightTable[nDegreeNum - 1] = (float)nCoefficient;
|
||||
|
||||
for (i = 0; i < nDegreeNum; i++) {
|
||||
dec->m_ptrWeightTable[i] = 1.0F / dec->m_ptrWeightTable[i];
|
||||
}
|
||||
|
||||
// dequantize
|
||||
for (i = 0; i < nDegreeNum; i++) {
|
||||
ptrDestination[i] = (float)(rCoefficient * dec->m_ptrWeightTable[i] * ptrQuantumized[i]);
|
||||
}
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
/* Dequantizes and transforms block frames. Lib divides them into "lead" (keyframes),
|
||||
* "internal" (standard) and "post" blocks, handled slightly differently. All of them can be MSS
|
||||
* blocks, which OG code handles in a separate function (presumably as a minor optimization to
|
||||
* avoid setting extra FORs), but here are handled with a flag since they are very similar. */
|
||||
|
||||
static ESLError MIODecoder_DecodeLeadBlock_All(MIODecoder* dec, int is_mss) {
|
||||
unsigned int ch, i;
|
||||
unsigned int nHalfDegree = dec->m_nDegreeNum / 2;
|
||||
int internal_channels = is_mss ? 2 : 1;
|
||||
//int output_channels = is_mss ? 2 : dec->m_mioih.dwChannelCount;
|
||||
|
||||
SDWORD nWeightCode = *(dec->m_ptrNextWeight++);
|
||||
int nCoefficient = *(dec->m_ptrNextCoefficient++);
|
||||
|
||||
float* ptrLapBuf;
|
||||
|
||||
|
||||
// dequantize
|
||||
ptrLapBuf = dec->m_ptrLastDCTBuf;
|
||||
for (ch = 0; ch < internal_channels; ch++) {
|
||||
INT* ptrTempBuf = dec->m_ptrBuffer1;
|
||||
for (i = 0; i < nHalfDegree; i++) {
|
||||
ptrTempBuf[i * 2] = 0;
|
||||
ptrTempBuf[i * 2 + 1] = *(dec->m_ptrNextSource++);
|
||||
}
|
||||
MIODecoder_IQuantumize(dec, ptrLapBuf, ptrTempBuf, dec->m_nDegreeNum, nWeightCode, nCoefficient);
|
||||
|
||||
ptrLapBuf += dec->m_nDegreeNum;
|
||||
}
|
||||
|
||||
// revolve
|
||||
if (is_mss) {
|
||||
float rSin, rCos;
|
||||
int nRevCode = *(dec->m_ptrNextRevCode++);
|
||||
|
||||
float* ptrLapBuf1 = dec->m_ptrLastDCT;
|
||||
float* ptrLapBuf2 = dec->m_ptrLastDCT + dec->m_nDegreeNum;
|
||||
|
||||
rSin = (float)sin(nRevCode * ERI_PI / 8);
|
||||
rCos = (float)cos(nRevCode * ERI_PI / 8);
|
||||
EMT_eriRevolve2x2(ptrLapBuf1, ptrLapBuf2, rSin, rCos, 1, dec->m_nDegreeNum);
|
||||
}
|
||||
|
||||
// set duplicate parameters
|
||||
ptrLapBuf = dec->m_ptrLastDCTBuf;
|
||||
for (ch = 0; ch < internal_channels; ch++) {
|
||||
EMT_eriOddGivensInverseMatrix(ptrLapBuf, dec->m_pRevolveParam, dec->m_nSubbandDegree);
|
||||
|
||||
for (i = 0; i < dec->m_nDegreeNum; i += 2) {
|
||||
ptrLapBuf[i] = ptrLapBuf[i + 1];
|
||||
}
|
||||
|
||||
EMT_eriFastIPLOT(ptrLapBuf, dec->m_nSubbandDegree);
|
||||
|
||||
ptrLapBuf += dec->m_nDegreeNum;
|
||||
}
|
||||
|
||||
return eslErrSuccess;
|
||||
}
|
||||
|
||||
static ESLError MIODecoder_DecodeInternalBlock_All(MIODecoder* dec, SWORD* ptrDst, unsigned int nSamples, int is_mss) {
|
||||
unsigned int ch, i;
|
||||
int internal_channels = is_mss ? 2 : 1;
|
||||
int output_channels = is_mss ? 2 : dec->m_mioih.dwChannelCount;
|
||||
|
||||
SDWORD nWeightCode = *(dec->m_ptrNextWeight++);
|
||||
int nCoefficient = *(dec->m_ptrNextCoefficient++);
|
||||
|
||||
float* ptrLapBuf;
|
||||
float* ptrSrcBuf;
|
||||
|
||||
// dequantize
|
||||
ptrSrcBuf = dec->m_ptrMatrixBuf;
|
||||
for (ch = 0; ch < internal_channels; ch++) {
|
||||
MIODecoder_IQuantumize(dec, ptrSrcBuf, dec->m_ptrNextSource, dec->m_nDegreeNum, nWeightCode, nCoefficient);
|
||||
dec->m_ptrNextSource += dec->m_nDegreeNum;
|
||||
|
||||
ptrSrcBuf += dec->m_nDegreeNum;
|
||||
}
|
||||
|
||||
// revolve
|
||||
if (is_mss) {
|
||||
float rSin, rCos;
|
||||
int nRevCode = *(dec->m_ptrNextRevCode++);
|
||||
int nRevCode1 = (nRevCode >> 2) & 0x03;
|
||||
int nRevCode2 = (nRevCode & 0x03);
|
||||
|
||||
float* ptrSrcBuf1 = dec->m_ptrMatrixBuf;
|
||||
float* ptrSrcBuf2 = dec->m_ptrMatrixBuf + dec->m_nDegreeNum;
|
||||
|
||||
rSin = (float)sin(nRevCode1 * ERI_PI / 8);
|
||||
rCos = (float)cos(nRevCode1 * ERI_PI / 8);
|
||||
EMT_eriRevolve2x2(ptrSrcBuf1, ptrSrcBuf2, rSin, rCos, 2, dec->m_nDegreeNum / 2);
|
||||
|
||||
rSin = (float)sin(nRevCode2 * ERI_PI / 8);
|
||||
rCos = (float)cos(nRevCode2 * ERI_PI / 8);
|
||||
EMT_eriRevolve2x2(ptrSrcBuf1 + 1, ptrSrcBuf2 + 1, rSin, rCos, 2, dec->m_nDegreeNum / 2);
|
||||
}
|
||||
|
||||
// inverse LOT + DCT
|
||||
ptrLapBuf = dec->m_ptrLastDCTBuf;
|
||||
ptrSrcBuf = dec->m_ptrMatrixBuf;
|
||||
for (ch = 0; ch < internal_channels; ch++) {
|
||||
EMT_eriOddGivensInverseMatrix(ptrSrcBuf, dec->m_pRevolveParam, dec->m_nSubbandDegree);
|
||||
|
||||
EMT_eriFastIPLOT(ptrSrcBuf, dec->m_nSubbandDegree);
|
||||
EMT_eriFastILOT(dec->m_ptrWorkBuf, ptrLapBuf, ptrSrcBuf, dec->m_nSubbandDegree);
|
||||
|
||||
for (i = 0; i < dec->m_nDegreeNum; i++) {
|
||||
ptrLapBuf[i] = ptrSrcBuf[i];
|
||||
ptrSrcBuf[i] = dec->m_ptrWorkBuf[i];
|
||||
}
|
||||
|
||||
EMT_eriFastIDCT(dec->m_ptrInternalBuf, ptrSrcBuf, 1, dec->m_ptrWorkBuf, dec->m_nSubbandDegree);
|
||||
|
||||
EMT_eriRoundR32ToWordArray(ptrDst + ch, output_channels, dec->m_ptrInternalBuf, nSamples);
|
||||
|
||||
ptrLapBuf += dec->m_nDegreeNum;
|
||||
ptrSrcBuf += dec->m_nDegreeNum;
|
||||
}
|
||||
|
||||
return eslErrSuccess;
|
||||
}
|
||||
|
||||
static ESLError MIODecoder_DecodePostBlock_All(MIODecoder* dec, SWORD* ptrDst, unsigned int nSamples, int is_mss) {
|
||||
unsigned int ch, i;
|
||||
unsigned int nHalfDegree = dec->m_nDegreeNum / 2;
|
||||
int internal_channels = is_mss ? 2 : 1;
|
||||
int output_channels = is_mss ? 2 : dec->m_mioih.dwChannelCount;
|
||||
|
||||
SDWORD nWeightCode = *(dec->m_ptrNextWeight++);
|
||||
int nCoefficient = *(dec->m_ptrNextCoefficient++);
|
||||
|
||||
float* ptrLapBuf;
|
||||
float* ptrSrcBuf;
|
||||
|
||||
|
||||
// dequantize
|
||||
ptrSrcBuf = dec->m_ptrMatrixBuf;
|
||||
for (ch = 0; ch < internal_channels; ch++) {
|
||||
INT* ptrTempBuf = dec->m_ptrBuffer1;
|
||||
for (i = 0; i < nHalfDegree; i++) {
|
||||
ptrTempBuf[i * 2] = 0;
|
||||
ptrTempBuf[i * 2 + 1] = *(dec->m_ptrNextSource++);
|
||||
}
|
||||
MIODecoder_IQuantumize(dec, ptrSrcBuf, ptrTempBuf, dec->m_nDegreeNum, nWeightCode, nCoefficient);
|
||||
|
||||
ptrSrcBuf += dec->m_nDegreeNum;
|
||||
}
|
||||
|
||||
// revolve
|
||||
if (is_mss) {
|
||||
float rSin, rCos;
|
||||
int nRevCode = *(dec->m_ptrNextRevCode++);
|
||||
|
||||
float* ptrSrcBuf1 = dec->m_ptrMatrixBuf; //L
|
||||
float* ptrSrcBuf2 = dec->m_ptrMatrixBuf + dec->m_nDegreeNum; //R
|
||||
|
||||
rSin = (float)sin(nRevCode * ERI_PI / 8);
|
||||
rCos = (float)cos(nRevCode * ERI_PI / 8);
|
||||
EMT_eriRevolve2x2(ptrSrcBuf1, ptrSrcBuf2, rSin, rCos, 1, dec->m_nDegreeNum);
|
||||
}
|
||||
|
||||
// inverse LOT + DCT
|
||||
ptrLapBuf = dec->m_ptrLastDCTBuf;
|
||||
ptrSrcBuf = dec->m_ptrMatrixBuf;
|
||||
for (ch = 0; ch < internal_channels; ch++) {
|
||||
EMT_eriOddGivensInverseMatrix(ptrSrcBuf, dec->m_pRevolveParam, dec->m_nSubbandDegree);
|
||||
|
||||
for (i = 0; i < dec->m_nDegreeNum; i += 2) {
|
||||
ptrSrcBuf[i] = -ptrSrcBuf[i + 1];
|
||||
}
|
||||
|
||||
EMT_eriFastIPLOT(ptrSrcBuf, dec->m_nSubbandDegree);
|
||||
EMT_eriFastILOT(dec->m_ptrWorkBuf, ptrLapBuf, ptrSrcBuf, dec->m_nSubbandDegree);
|
||||
|
||||
for (i = 0; i < dec->m_nDegreeNum; i++) {
|
||||
ptrSrcBuf[i] = dec->m_ptrWorkBuf[i];
|
||||
}
|
||||
|
||||
EMT_eriFastIDCT(dec->m_ptrInternalBuf, ptrSrcBuf, 1, dec->m_ptrWorkBuf, dec->m_nSubbandDegree);
|
||||
|
||||
EMT_eriRoundR32ToWordArray(ptrDst + ch, output_channels, dec->m_ptrInternalBuf, nSamples);
|
||||
|
||||
ptrLapBuf += dec->m_nDegreeNum;
|
||||
ptrSrcBuf += dec->m_nDegreeNum;
|
||||
}
|
||||
|
||||
return eslErrSuccess;
|
||||
}
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
static ESLError MIODecoder_DecodeSoundDCT_Std(MIODecoder* dec, MIOContext* context, const MIO_DATA_HEADER* datahdr, void* ptrWaveBuf) {
|
||||
unsigned int i, j, k;
|
||||
unsigned int nDegreeWidth = (1 << dec->m_mioih.dwSubbandDegree);
|
||||
unsigned int nSampleCount = (datahdr->dwSampleCount + nDegreeWidth - 1) & ~(nDegreeWidth - 1);
|
||||
unsigned int nSubbandCount = (nSampleCount >> dec->m_mioih.dwSubbandDegree);
|
||||
unsigned int nChannelCount = dec->m_mioih.dwChannelCount;
|
||||
unsigned int nAllSampleCount = nSampleCount * nChannelCount;
|
||||
unsigned int nAllSubbandCount = nSubbandCount * nChannelCount;
|
||||
|
||||
if (nSampleCount > dec->m_nBufLength) {
|
||||
free(dec->m_ptrBuffer2);
|
||||
free(dec->m_ptrBuffer3);
|
||||
free(dec->m_ptrDivisionTable);
|
||||
free(dec->m_ptrWeightCode);
|
||||
free(dec->m_ptrCoefficient);
|
||||
|
||||
dec->m_ptrBuffer2 = malloc(nAllSampleCount * sizeof(INT));
|
||||
dec->m_ptrBuffer3 = malloc(nAllSampleCount * sizeof(SWORD));
|
||||
dec->m_ptrDivisionTable = malloc(nAllSubbandCount * sizeof(BYTE));
|
||||
dec->m_ptrWeightCode = malloc(nAllSubbandCount * 5 * sizeof(SDWORD));
|
||||
dec->m_ptrCoefficient = malloc(nAllSubbandCount * 5 * sizeof(INT));
|
||||
if (!dec->m_ptrBuffer2 || !dec->m_ptrBuffer3 || !dec->m_ptrDivisionTable || !dec->m_ptrWeightCode || !dec->m_ptrCoefficient)
|
||||
return eslErrGeneral;
|
||||
|
||||
dec->m_nBufLength = nSampleCount;
|
||||
}
|
||||
|
||||
// decode quantization table
|
||||
if (MIOContext_GetABit(context) != 0) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
unsigned int pLastDivision[MIO_MAX_CHANNELS];
|
||||
for (i = 0; i < nChannelCount; i++) {
|
||||
pLastDivision[i] = -1;
|
||||
}
|
||||
|
||||
dec->m_ptrNextDivision = dec->m_ptrDivisionTable;
|
||||
dec->m_ptrNextWeight = dec->m_ptrWeightCode;
|
||||
dec->m_ptrNextCoefficient = dec->m_ptrCoefficient;
|
||||
|
||||
for (i = 0; i < nSubbandCount; i++) {
|
||||
for (j = 0; j < nChannelCount; j++) {
|
||||
unsigned int nDivisionCode = MIOContext_GetNBits(context, 2);
|
||||
*(dec->m_ptrNextDivision++) = (BYTE)nDivisionCode;
|
||||
|
||||
if (nDivisionCode != pLastDivision[j]) {
|
||||
if (i != 0) {
|
||||
*(dec->m_ptrNextWeight++) = MIOContext_GetNBits(context, 32);
|
||||
*(dec->m_ptrNextCoefficient++) = MIOContext_GetNBits(context, 16);
|
||||
}
|
||||
pLastDivision[j] = nDivisionCode;
|
||||
}
|
||||
|
||||
unsigned int nDivisionCount = (1 << nDivisionCode);
|
||||
for (k = 0; k < nDivisionCount; k++) {
|
||||
*(dec->m_ptrNextWeight++) = MIOContext_GetNBits(context, 32);
|
||||
*(dec->m_ptrNextCoefficient++) = MIOContext_GetNBits(context, 16);
|
||||
}
|
||||
}
|
||||
}
|
||||
if (nSubbandCount > 0) {
|
||||
for (i = 0; i < nChannelCount; i++) {
|
||||
*(dec->m_ptrNextWeight++) = MIOContext_GetNBits(context, 32);
|
||||
*(dec->m_ptrNextCoefficient++) = MIOContext_GetNBits(context, 16);
|
||||
}
|
||||
}
|
||||
|
||||
/* sync? */
|
||||
if (MIOContext_GetABit(context) != 0) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
// init code model if needed
|
||||
if (datahdr->bytFlags & MIO_LEAD_BLOCK) {
|
||||
if (dec->m_mioih.dwArchitecture != ERISA_NEMESIS_CODE) {
|
||||
ESLError err = MIOContext_PrepareToDecodeERINACode(context, ERINAEncodingFlag_efERINAOrder1);
|
||||
if (err != eslErrSuccess) return err;
|
||||
}
|
||||
else {
|
||||
ESLError err = MIOContext_PrepareToDecodeERISACode(context);
|
||||
if (err != eslErrSuccess) return err;
|
||||
}
|
||||
}
|
||||
else if (dec->m_mioih.dwArchitecture == ERISA_NEMESIS_CODE) {
|
||||
MIOContext_InitializeERISACode(context);
|
||||
}
|
||||
|
||||
// decode and deinterleave
|
||||
if (dec->m_mioih.dwArchitecture != ERISA_NEMESIS_CODE) {
|
||||
if (MIOContext_DecodeSymbolBytes(context, dec->m_ptrBuffer3, nAllSampleCount * 2) < nAllSampleCount * 2) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
SBYTE* ptrHBuf = dec->m_ptrBuffer3;
|
||||
SBYTE* ptrLBuf = ptrHBuf + nAllSampleCount;
|
||||
|
||||
for (i = 0; i < nDegreeWidth; i++) {
|
||||
INT* ptrQuantumized = ((INT*)dec->m_ptrBuffer2) + i;
|
||||
|
||||
for (j = 0; j < nAllSubbandCount; j++) {
|
||||
INT nLow = *(ptrLBuf++);
|
||||
INT nHigh = *(ptrHBuf++) ^ (nLow >> 8);
|
||||
*ptrQuantumized = (nLow & 0xFF) | (nHigh << 8);
|
||||
ptrQuantumized += nDegreeWidth;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (MIOContext_DecodeERISACodeWords(context, (SWORD*)dec->m_ptrBuffer3, nAllSampleCount) < nAllSampleCount) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
SWORD* ptrTmp = dec->m_ptrBuffer3;
|
||||
for (i = 0; i < nAllSampleCount; i++) {
|
||||
((INT*)dec->m_ptrBuffer2)[i] = (ptrTmp)[i];
|
||||
}
|
||||
}
|
||||
|
||||
// apply iDCT to subband units
|
||||
unsigned int nSamples;
|
||||
unsigned int pRestSamples[MIO_MAX_CHANNELS];
|
||||
SWORD* ptrDstBuf[MIO_MAX_CHANNELS];
|
||||
|
||||
dec->m_ptrNextDivision = dec->m_ptrDivisionTable;
|
||||
dec->m_ptrNextWeight = dec->m_ptrWeightCode;
|
||||
dec->m_ptrNextCoefficient = dec->m_ptrCoefficient;
|
||||
dec->m_ptrNextSource = dec->m_ptrBuffer2;
|
||||
|
||||
for (i = 0; i < nChannelCount; i++) {
|
||||
pLastDivision[i] = -1;
|
||||
pRestSamples[i] = datahdr->dwSampleCount;
|
||||
ptrDstBuf[i] = ((SWORD*)ptrWaveBuf) + i;
|
||||
}
|
||||
unsigned int nCurrentDivision = -1;
|
||||
|
||||
for (i = 0; i < nSubbandCount; i++) {
|
||||
for (j = 0; j < nChannelCount; j++) {
|
||||
// get division/decomposition code
|
||||
unsigned int nDivisionCode = *(dec->m_ptrNextDivision++);
|
||||
unsigned int nDivisionCount = (1 << nDivisionCode);
|
||||
|
||||
// get buffer for duplicate processing
|
||||
int nChannelStep = nDegreeWidth * dec->m_mioih.dwLappedDegree * j;
|
||||
dec->m_ptrLastDCTBuf = dec->m_ptrLastDCT + nChannelStep;
|
||||
|
||||
// processing when matrix size changes
|
||||
int bLeadBlock = 0;
|
||||
|
||||
if (pLastDivision[j] != nDivisionCode) {
|
||||
// complete until last moment
|
||||
if (i != 0) {
|
||||
if (nCurrentDivision != pLastDivision[j]) {
|
||||
if (MIODecoder_InitializeWithDegree(dec, dec->m_mioih.dwSubbandDegree - pLastDivision[j]))
|
||||
return eslErrGeneral;
|
||||
nCurrentDivision = pLastDivision[j];
|
||||
}
|
||||
nSamples = pRestSamples[j];
|
||||
if (nSamples > dec->m_nDegreeNum) {
|
||||
nSamples = dec->m_nDegreeNum;
|
||||
}
|
||||
if (MIODecoder_DecodePostBlock_All(dec, ptrDstBuf[j], nSamples, 0)) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
pRestSamples[j] -= nSamples;
|
||||
ptrDstBuf[j] += nSamples * nChannelCount;
|
||||
}
|
||||
|
||||
// set params to change matrix size
|
||||
pLastDivision[j] = nDivisionCode;
|
||||
bLeadBlock = 1;
|
||||
}
|
||||
if (nCurrentDivision != nDivisionCode) {
|
||||
if (MIODecoder_InitializeWithDegree(dec, dec->m_mioih.dwSubbandDegree - nDivisionCode))
|
||||
return eslErrGeneral;
|
||||
nCurrentDivision = nDivisionCode;
|
||||
}
|
||||
|
||||
// perform sequential iLOT
|
||||
for (k = 0; k < nDivisionCount; k++) {
|
||||
if (bLeadBlock) {
|
||||
// decode lead block
|
||||
if (MIODecoder_DecodeLeadBlock_All(dec, 0)) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
bLeadBlock = 0;
|
||||
}
|
||||
else {
|
||||
// decode regular block
|
||||
nSamples = pRestSamples[j];
|
||||
if (nSamples > dec->m_nDegreeNum) {
|
||||
nSamples = dec->m_nDegreeNum;
|
||||
}
|
||||
if (MIODecoder_DecodeInternalBlock_All(dec, ptrDstBuf[j], nSamples, 0)) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
pRestSamples[j] -= nSamples;
|
||||
ptrDstBuf[j] += nSamples * nChannelCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// complete the matrix
|
||||
if (nSubbandCount > 0) {
|
||||
for (i = 0; i < nChannelCount; i++) {
|
||||
int nChannelStep = nDegreeWidth * dec->m_mioih.dwLappedDegree * i;
|
||||
dec->m_ptrLastDCTBuf = dec->m_ptrLastDCT + nChannelStep;
|
||||
|
||||
if (nCurrentDivision != pLastDivision[i]) {
|
||||
if (MIODecoder_InitializeWithDegree(dec, dec->m_mioih.dwSubbandDegree - pLastDivision[i]))
|
||||
return eslErrGeneral;
|
||||
nCurrentDivision = pLastDivision[i];
|
||||
}
|
||||
nSamples = pRestSamples[i];
|
||||
if (nSamples > dec->m_nDegreeNum) {
|
||||
nSamples = dec->m_nDegreeNum;
|
||||
}
|
||||
if (MIODecoder_DecodePostBlock_All(dec, ptrDstBuf[i], nSamples, 0)) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
pRestSamples[i] -= nSamples;
|
||||
ptrDstBuf[i] += nSamples * nChannelCount;
|
||||
}
|
||||
}
|
||||
|
||||
return eslErrSuccess;
|
||||
}
|
||||
|
||||
static ESLError MIODecoder_DecodeSoundDCT_MSS(MIODecoder* dec, MIOContext* context, const MIO_DATA_HEADER* datahdr, void* ptrWaveBuf) {
|
||||
unsigned int i, j, k;
|
||||
unsigned int nDegreeWidth = (1 << dec->m_mioih.dwSubbandDegree);
|
||||
unsigned int nSampleCount = (datahdr->dwSampleCount + nDegreeWidth - 1) & ~(nDegreeWidth - 1);
|
||||
unsigned int nSubbandCount = (nSampleCount >> dec->m_mioih.dwSubbandDegree);
|
||||
unsigned int nChannelCount = dec->m_mioih.dwChannelCount; // usually 2
|
||||
unsigned int nAllSampleCount = nSampleCount * nChannelCount;
|
||||
unsigned int nAllSubbandCount = nSubbandCount;
|
||||
|
||||
if (nSampleCount > dec->m_nBufLength) {
|
||||
free(dec->m_ptrBuffer2);
|
||||
free(dec->m_ptrBuffer3);
|
||||
free(dec->m_ptrDivisionTable);
|
||||
free(dec->m_ptrRevolveCode);
|
||||
free(dec->m_ptrWeightCode);
|
||||
free(dec->m_ptrCoefficient);
|
||||
|
||||
dec->m_ptrBuffer2 = malloc(nAllSampleCount * sizeof(INT));
|
||||
dec->m_ptrBuffer3 = malloc(nAllSampleCount * sizeof(SWORD));
|
||||
dec->m_ptrDivisionTable = malloc(nAllSubbandCount * sizeof(BYTE));
|
||||
dec->m_ptrRevolveCode = malloc(nAllSubbandCount * 10 * sizeof(BYTE));
|
||||
dec->m_ptrWeightCode = malloc(nAllSubbandCount * 10 * sizeof(SDWORD));
|
||||
dec->m_ptrCoefficient = malloc(nAllSubbandCount * 10 * sizeof(INT));
|
||||
if (!dec->m_ptrBuffer2 || !dec->m_ptrBuffer3 || !dec->m_ptrDivisionTable || !dec->m_ptrRevolveCode || !dec->m_ptrWeightCode || !dec->m_ptrCoefficient)
|
||||
return eslErrGeneral;
|
||||
|
||||
dec->m_nBufLength = nSampleCount;
|
||||
}
|
||||
|
||||
// decode quantization table
|
||||
if (MIOContext_GetABit(context) != 0) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
unsigned int nLastDivision = -1;
|
||||
|
||||
dec->m_ptrNextDivision = dec->m_ptrDivisionTable;
|
||||
dec->m_ptrNextRevCode = dec->m_ptrRevolveCode;
|
||||
dec->m_ptrNextWeight = dec->m_ptrWeightCode;
|
||||
dec->m_ptrNextCoefficient = dec->m_ptrCoefficient;
|
||||
|
||||
for (i = 0; i < nSubbandCount; i++) {
|
||||
unsigned int nDivisionCode = MIOContext_GetNBits(context, 2);
|
||||
*(dec->m_ptrNextDivision++) = (BYTE)nDivisionCode;
|
||||
|
||||
int bLeadBlock = 0;
|
||||
if (nDivisionCode != nLastDivision) {
|
||||
if (i != 0) {
|
||||
*(dec->m_ptrNextRevCode++) = MIOContext_GetNBits(context, 2);
|
||||
*(dec->m_ptrNextWeight++) = MIOContext_GetNBits(context, 32);
|
||||
*(dec->m_ptrNextCoefficient++) = MIOContext_GetNBits(context, 16);
|
||||
}
|
||||
bLeadBlock = 1;
|
||||
nLastDivision = nDivisionCode;
|
||||
}
|
||||
|
||||
unsigned int nDivisionCount = (1 << nDivisionCode);
|
||||
for (k = 0; k < nDivisionCount; k++) {
|
||||
if (bLeadBlock) {
|
||||
*(dec->m_ptrNextRevCode++) = MIOContext_GetNBits(context, 2);
|
||||
bLeadBlock = 0;
|
||||
}
|
||||
else {
|
||||
*(dec->m_ptrNextRevCode++) = MIOContext_GetNBits(context, 4);
|
||||
}
|
||||
*(dec->m_ptrNextWeight++) = MIOContext_GetNBits(context, 32);
|
||||
*(dec->m_ptrNextCoefficient++) = MIOContext_GetNBits(context, 16);
|
||||
}
|
||||
}
|
||||
if (nSubbandCount > 0) {
|
||||
*(dec->m_ptrNextRevCode++) = MIOContext_GetNBits(context, 2);
|
||||
*(dec->m_ptrNextWeight++) = MIOContext_GetNBits(context, 32);
|
||||
*(dec->m_ptrNextCoefficient++) = MIOContext_GetNBits(context, 16);
|
||||
}
|
||||
|
||||
if (MIOContext_GetABit(context) != 0) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
if (datahdr->bytFlags & MIO_LEAD_BLOCK) {
|
||||
if (dec->m_mioih.dwArchitecture != ERISA_NEMESIS_CODE) {
|
||||
ESLError err = MIOContext_PrepareToDecodeERINACode(context, ERINAEncodingFlag_efERINAOrder1);
|
||||
if (err != eslErrSuccess) return err;
|
||||
}
|
||||
else {
|
||||
ESLError err = MIOContext_PrepareToDecodeERISACode(context);
|
||||
if (err != eslErrSuccess) return err;
|
||||
}
|
||||
}
|
||||
else if (dec->m_mioih.dwArchitecture == ERISA_NEMESIS_CODE) {
|
||||
MIOContext_InitializeERISACode(context);
|
||||
}
|
||||
|
||||
// decode and deinterleave
|
||||
if (dec->m_mioih.dwArchitecture != ERISA_NEMESIS_CODE) {
|
||||
if (MIOContext_DecodeSymbolBytes(context, dec->m_ptrBuffer3, nAllSampleCount * 2) < nAllSampleCount * 2) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
SBYTE* ptrHBuf = dec->m_ptrBuffer3;
|
||||
SBYTE* ptrLBuf = ptrHBuf + nAllSampleCount;
|
||||
|
||||
for (i = 0; i < nDegreeWidth * 2; i++) {
|
||||
INT* ptrQuantumized = ((INT*)dec->m_ptrBuffer2) + i;
|
||||
|
||||
for (j = 0; j < nAllSubbandCount; j++) {
|
||||
INT nLow = *(ptrLBuf++);
|
||||
INT nHigh = *(ptrHBuf++) ^ (nLow >> 8);
|
||||
*ptrQuantumized = (nLow & 0xFF) | (nHigh << 8);
|
||||
ptrQuantumized += nDegreeWidth * 2;
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
if (MIOContext_DecodeERISACodeWords(context, (SWORD*)dec->m_ptrBuffer3, nAllSampleCount) < nAllSampleCount) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
SWORD* ptrTmp = dec->m_ptrBuffer3;
|
||||
for (i = 0; i < nAllSampleCount; i++) {
|
||||
((INT*)dec->m_ptrBuffer2)[i] = (ptrTmp)[i];
|
||||
}
|
||||
}
|
||||
|
||||
// apply iDCT to subband units
|
||||
unsigned int nSamples;
|
||||
unsigned int nRestSamples = datahdr->dwSampleCount;
|
||||
SWORD* ptrDstBuf = ptrWaveBuf;
|
||||
|
||||
nLastDivision = -1;
|
||||
dec->m_ptrNextDivision = dec->m_ptrDivisionTable;
|
||||
dec->m_ptrNextRevCode = dec->m_ptrRevolveCode;
|
||||
dec->m_ptrNextWeight = dec->m_ptrWeightCode;
|
||||
dec->m_ptrNextCoefficient = dec->m_ptrCoefficient;
|
||||
dec->m_ptrNextSource = dec->m_ptrBuffer2;
|
||||
|
||||
for (i = 0; i < nSubbandCount; i++) {
|
||||
// get division/decomposition code
|
||||
unsigned int nDivisionCode = *(dec->m_ptrNextDivision++);
|
||||
unsigned int nDivisionCount = (1 << nDivisionCode);
|
||||
|
||||
// processing when matrix size changes
|
||||
int bLeadBlock = 0;
|
||||
dec->m_ptrLastDCTBuf = dec->m_ptrLastDCT;
|
||||
|
||||
if (nLastDivision != nDivisionCode) {
|
||||
// complete until last moment
|
||||
if (i != 0) {
|
||||
nSamples = nRestSamples;
|
||||
if (nSamples > dec->m_nDegreeNum) {
|
||||
nSamples = dec->m_nDegreeNum;
|
||||
}
|
||||
if (MIODecoder_DecodePostBlock_All(dec, ptrDstBuf, nSamples, 1)) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
nRestSamples -= nSamples;
|
||||
ptrDstBuf += nSamples * nChannelCount;
|
||||
}
|
||||
|
||||
// set params to change matrix size
|
||||
if (MIODecoder_InitializeWithDegree(dec, dec->m_mioih.dwSubbandDegree - nDivisionCode))
|
||||
return eslErrGeneral;
|
||||
nLastDivision = nDivisionCode;
|
||||
bLeadBlock = 1;
|
||||
}
|
||||
|
||||
// perform sequential iLOT
|
||||
for (k = 0; k < nDivisionCount; k++) {
|
||||
if (bLeadBlock) {
|
||||
// decode lead block
|
||||
if (MIODecoder_DecodeLeadBlock_All(dec, 1)) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
|
||||
bLeadBlock = 0;
|
||||
}
|
||||
else {
|
||||
// decode regular block
|
||||
nSamples = nRestSamples;
|
||||
if (nSamples > dec->m_nDegreeNum) {
|
||||
nSamples = dec->m_nDegreeNum;
|
||||
}
|
||||
if (MIODecoder_DecodeInternalBlock_All(dec, ptrDstBuf, nSamples, 1)) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
nRestSamples -= nSamples;
|
||||
ptrDstBuf += nSamples * nChannelCount;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// complete the matrix
|
||||
if (nSubbandCount > 0) {
|
||||
dec->m_ptrLastDCTBuf = dec->m_ptrLastDCT;
|
||||
|
||||
nSamples = nRestSamples;
|
||||
if (nSamples > dec->m_nDegreeNum)
|
||||
nSamples = dec->m_nDegreeNum;
|
||||
|
||||
if (MIODecoder_DecodePostBlock_All(dec, ptrDstBuf, nSamples, 1)) {
|
||||
return eslErrGeneral;
|
||||
}
|
||||
nRestSamples -= nSamples;
|
||||
ptrDstBuf += nSamples * nChannelCount;
|
||||
}
|
||||
|
||||
return eslErrSuccess;
|
||||
}
|
||||
|
||||
ESLError MIODecoder_DecodeSound(MIODecoder* dec, MIOContext* context, const MIO_DATA_HEADER* datahdr, void* ptrWaveBuf) {
|
||||
MIOContext_FlushBuffer(context);
|
||||
|
||||
if (dec->m_mioih.fdwTransformation == CVTYPE_LOSSLESS_ERI) {
|
||||
if (dec->m_mioih.dwBitsPerSample == 8) {
|
||||
return MIODecoder_DecodeSoundPCM8(dec, context, datahdr, ptrWaveBuf);
|
||||
}
|
||||
else if (dec->m_mioih.dwBitsPerSample == 16) {
|
||||
return MIODecoder_DecodeSoundPCM16(dec, context, datahdr, ptrWaveBuf);
|
||||
}
|
||||
}
|
||||
else if ((dec->m_mioih.fdwTransformation == CVTYPE_LOT_ERI) || (dec->m_mioih.fdwTransformation == CVTYPE_LOT_ERI_MSS)) {
|
||||
if ((dec->m_mioih.dwChannelCount != 2) || (dec->m_mioih.fdwTransformation == CVTYPE_LOT_ERI)) {
|
||||
return MIODecoder_DecodeSoundDCT_Std(dec, context, datahdr, ptrWaveBuf);
|
||||
}
|
||||
else {
|
||||
return MIODecoder_DecodeSoundDCT_MSS(dec, context, datahdr, ptrWaveBuf);
|
||||
}
|
||||
}
|
||||
|
||||
return eslErrGeneral;
|
||||
}
|
|
@ -0,0 +1,49 @@
|
|||
/* Decodes audio context data into samples.
|
||||
*/
|
||||
#ifndef _MIO_ERISA_SOUND_H_
|
||||
#define _MIO_ERISA_SOUND_H_
|
||||
|
||||
typedef struct {
|
||||
MIO_INFO_HEADER m_mioih; // voice info header (current file)
|
||||
|
||||
unsigned int m_nBufLength; // block's sample count
|
||||
|
||||
// various internal (alloc'd) bufs
|
||||
void* m_ptrBuffer1; // processing
|
||||
void* m_ptrBuffer2; // reordering
|
||||
void* m_ptrBuffer3; // interleave
|
||||
|
||||
BYTE* m_ptrDivisionTable; // block's division codes
|
||||
BYTE* m_ptrRevolveCode; // block's revolve codes
|
||||
SDWORD* m_ptrWeightCode; // block's quant weights
|
||||
INT* m_ptrCoefficient; // block's scales
|
||||
|
||||
float* m_ptrMatrixBuf; // matrix ops
|
||||
float* m_ptrInternalBuf; // ops helper
|
||||
float* m_ptrWorkBuf; // DCT work buf
|
||||
float* m_ptrWeightTable; // freq weights
|
||||
float* m_ptrLastDCT; // previous DCT values
|
||||
|
||||
// temp pointers for the above (current pos)
|
||||
BYTE* m_ptrNextDivision;
|
||||
BYTE* m_ptrNextRevCode;
|
||||
SDWORD* m_ptrNextWeight;
|
||||
INT* m_ptrNextCoefficient;
|
||||
INT* m_ptrNextSource;
|
||||
float* m_ptrLastDCTBuf;
|
||||
|
||||
// file degree config
|
||||
unsigned int m_nSubbandDegree; // matrix size (N)
|
||||
unsigned int m_nDegreeNum; // derived matrix size (2^N)
|
||||
ERI_SIN_COS* m_pRevolveParam; //
|
||||
|
||||
int m_nFrequencyPoint[7]; // freq center points
|
||||
} MIODecoder;
|
||||
|
||||
MIODecoder* MIODecoder_Open();
|
||||
void MIODecoder_Close(MIODecoder* dec);
|
||||
|
||||
ESLError MIODecoder_Initialize(MIODecoder* dec, const MIO_INFO_HEADER* infhdr);
|
||||
ESLError MIODecoder_DecodeSound(MIODecoder* dec, MIOContext* context, const MIO_DATA_HEADER* datahdr, void* ptrWaveBuf);
|
||||
|
||||
#endif
|
103
Frameworks/vgmstream/vgmstream/src/coding/libs/mio_xerisa.h
Normal file
103
Frameworks/vgmstream/vgmstream/src/coding/libs/mio_xerisa.h
Normal file
|
@ -0,0 +1,103 @@
|
|||
/*****************************************************************************
|
||||
E R I S A - L i b r a r y
|
||||
-----------------------------------------------------------------------------
|
||||
Copyright (C) 2002-2004 Leshade Entis, Entis-soft. All rights reserved.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _MIO_ERISALIB_H_
|
||||
#define _MIO_ERISALIB_H_
|
||||
|
||||
#include <stdint.h>
|
||||
//#include <stdbool.h>
|
||||
|
||||
typedef unsigned char BYTE; //, *PBYTE;
|
||||
typedef unsigned short int WORD; //, *PWORD;
|
||||
typedef unsigned int UDWORD;
|
||||
typedef signed int INT; //, *PINT;
|
||||
typedef unsigned int UINT;
|
||||
//typedef signed long int LONG; //, *PLONG;
|
||||
typedef unsigned long int ULONG;
|
||||
|
||||
typedef signed char SBYTE;
|
||||
typedef signed short int SWORD;
|
||||
typedef signed int SDWORD;
|
||||
|
||||
|
||||
typedef enum {
|
||||
eslErrSuccess = 0,
|
||||
eslErrGeneral = 1,
|
||||
eslErrEof = 2, //extra
|
||||
} ESLError;
|
||||
|
||||
void ERI_eriInitializeLibrary(void);
|
||||
void ERI_eriCloseLibrary(void);
|
||||
|
||||
typedef struct {
|
||||
uint64_t cHeader; // signature
|
||||
UDWORD dwFileID;
|
||||
UDWORD dwReserved; // 0
|
||||
char cFormatDesc[0x30]; // format name
|
||||
} EMC_FILE_HEADER;
|
||||
|
||||
typedef struct {
|
||||
uint64_t nRecordID;
|
||||
uint64_t nRecLength;
|
||||
} EMC_RECORD_HEADER;
|
||||
|
||||
typedef struct {
|
||||
UDWORD dwVersion;
|
||||
UDWORD dwContainedFlag;
|
||||
UDWORD dwKeyFrameCount;
|
||||
UDWORD dwFrameCount;
|
||||
UDWORD dwAllFrameTime;
|
||||
} ERI_FILE_HEADER;
|
||||
|
||||
/* transformation (either lossless or LOT) */
|
||||
#define CVTYPE_LOSSLESS_ERI 0x03020000
|
||||
#define CVTYPE_DCT_ERI 0x00000001 // not used in audio
|
||||
#define CVTYPE_LOT_ERI 0x00000005
|
||||
#define CVTYPE_LOT_ERI_MSS 0x00000105
|
||||
|
||||
/* architecture (huffman for lossless or gamma/nemesis for LOT) */
|
||||
#define ERI_ARITHMETIC_CODE 32 // not used in audio?
|
||||
#define ERI_RUNLENGTH_GAMMA 0xFFFFFFFF //same as huffman with "gamma escape codes"
|
||||
#define ERI_RUNLENGTH_HUFFMAN 0xFFFFFFFC
|
||||
#define ERISA_NEMESIS_CODE 0xFFFFFFF0 // arithmetic coding (sliding window?)
|
||||
|
||||
// per file
|
||||
typedef struct {
|
||||
UDWORD dwVersion;
|
||||
UDWORD fdwTransformation;
|
||||
UDWORD dwArchitecture;
|
||||
UDWORD dwChannelCount;
|
||||
UDWORD dwSamplesPerSec; // input sample rate (output is fixed)
|
||||
UDWORD dwBlocksetCount;
|
||||
UDWORD dwSubbandDegree;
|
||||
UDWORD dwAllSampleCount;
|
||||
UDWORD dwLappedDegree;
|
||||
UDWORD dwBitsPerSample;
|
||||
|
||||
// extra from comments
|
||||
UDWORD rewindPoint;
|
||||
} MIO_INFO_HEADER;
|
||||
|
||||
// per chunk
|
||||
typedef struct {
|
||||
BYTE bytVersion;
|
||||
BYTE bytFlags;
|
||||
BYTE bytReserved1;
|
||||
BYTE bytReserved2;
|
||||
UDWORD dwSampleCount;
|
||||
} MIO_DATA_HEADER;
|
||||
|
||||
// Block is a "keyframe" and can be user to start decoding after flush/seek.
|
||||
// Starting to decode in a non-keyframe returns an error.
|
||||
#define MIO_LEAD_BLOCK 0x01
|
||||
|
||||
|
||||
#include "mio_erisacontext.h"
|
||||
#include "mio_erisafile.h"
|
||||
#include "mio_erisamatrix.h"
|
||||
#include "mio_erisasound.h"
|
||||
|
||||
#endif
|
254
Frameworks/vgmstream/vgmstream/src/coding/libs/oor_helpers.c
Normal file
254
Frameworks/vgmstream/vgmstream/src/coding/libs/oor_helpers.c
Normal file
|
@ -0,0 +1,254 @@
|
|||
#ifdef VGM_USE_VORBIS
|
||||
#include <string.h>
|
||||
#include <math.h>
|
||||
#include "oor_helpers.h"
|
||||
|
||||
|
||||
// .oor is divided into pages like "OggS", but simplified (variable sized)
|
||||
// - v0: 0x01
|
||||
// - v1: 0x0A
|
||||
void oor_read_page(bitstream_t* is, oor_page_t* page) {
|
||||
uint32_t granule_hi = 0, granule_lo = 0; //bitreader only handles 32b
|
||||
|
||||
page->version = bm_read(is, 2);
|
||||
page->flags = bm_read(is, 4); // vorbis packet flags
|
||||
|
||||
// extra fields in V1
|
||||
switch(page->version) {
|
||||
case 0:
|
||||
page->granule = 0;
|
||||
page->padding1 = 0;
|
||||
page->padding2 = 0;
|
||||
// bitstream ends with into bit 6 of current byte
|
||||
break;
|
||||
|
||||
case 1:
|
||||
page->padding1 = bm_read(is, 2); // padding as granule must be byte-aligned
|
||||
granule_hi = bm_read(is, 32);
|
||||
granule_lo = bm_read(is, 32);
|
||||
page->granule = ((uint64_t)granule_hi << 32) | granule_lo;
|
||||
page->padding2 = bm_read(is, 6); // padding to leave bitstream into bit 6, like v0
|
||||
break;
|
||||
|
||||
default: // unknown version
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// each .oor page except the first (header) has N packets:
|
||||
// size is variable but theoretical max is ~0x200 (plus page header)
|
||||
void oor_read_size(bitstream_t* is, oor_size_t* size) {
|
||||
// right after page info (meaning 6 bits into bitstream)
|
||||
size->vps_bits = bm_read(is, 4);
|
||||
size->padding1 = bm_read(is, 1);
|
||||
size->packet_count = bm_read(is, 8);
|
||||
size->bps_selector = bm_read(is, 2);
|
||||
|
||||
switch(size->bps_selector) {
|
||||
case 0: size->base_packet_size = 0; break; // 0 bits
|
||||
case 1: size->base_packet_size = bm_read(is, 8); break;
|
||||
case 2: size->base_packet_size = bm_read(is, 11); break;
|
||||
case 3: //undefined
|
||||
default:
|
||||
size->base_packet_size = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
for (int i = 0; i < size->packet_count; i++) {
|
||||
if (size->vps_bits) {
|
||||
size->variable_packet_size[i] = bm_read(is, size->vps_bits);
|
||||
}
|
||||
else {
|
||||
size->variable_packet_size[i] = 0; //reset in case of reusing struct
|
||||
}
|
||||
}
|
||||
|
||||
uint32_t bit_pos = bm_pos(is) % 8;
|
||||
if (bit_pos > 0) {
|
||||
size->post_padding = bm_read(is, 8 - bit_pos); // aligned to next byte
|
||||
}
|
||||
else {
|
||||
size->post_padding = 0;
|
||||
}
|
||||
|
||||
// bitstream is now byte-aligned, and next is N packets of base + variable packet sizes (in bytes)
|
||||
}
|
||||
|
||||
// bit-packed header (variable-sized):
|
||||
// - v0 (sr_selector!=3): 0x02
|
||||
// - v0 (sr_selector==3): 0x03
|
||||
// - v1 (sr_selector!=3): 0x12
|
||||
// - v1 (sr_selector==3): 0x13
|
||||
void oor_read_header(bitstream_t* is, oor_header_t* hdr) {
|
||||
hdr->pre_padding = bm_read(is, 2); // from first page, header is byte-aligned
|
||||
|
||||
hdr->version = bm_read(is, 2);
|
||||
hdr->channels = bm_read(is, 3);
|
||||
int sr_selector = bm_read(is, 2);
|
||||
|
||||
if (sr_selector == 3) {
|
||||
int sr_index = bm_read(is, 8);
|
||||
|
||||
// few known modes, though they have 8 bits
|
||||
// seems v1 lib can handle v0 files but sample rate is not compatible, maybe an oversight
|
||||
// (note that some games somehow have both v0 and v1 files)
|
||||
switch(hdr->version) {
|
||||
case 0:
|
||||
switch(sr_index) {
|
||||
case 3: hdr->sample_rate = 32000; break;
|
||||
case 4: hdr->sample_rate = 48000; break;
|
||||
case 5: hdr->sample_rate = 96000; break;
|
||||
default: hdr->sample_rate = 0; break;
|
||||
}
|
||||
|
||||
case 1:
|
||||
switch(sr_index) {
|
||||
case 4: hdr->sample_rate = 32000; break;
|
||||
case 5: hdr->sample_rate = 48000; break;
|
||||
case 6: hdr->sample_rate = 64000; break;
|
||||
case 7: hdr->sample_rate = 88200; break;
|
||||
case 8: hdr->sample_rate = 96000; break;
|
||||
default: hdr->sample_rate = 0; break;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
// shouldn't happen, but allow to catch missing cases
|
||||
if (hdr->sample_rate == 0) // && sr_index < 256
|
||||
hdr->sample_rate = 8000;
|
||||
}
|
||||
else {
|
||||
hdr->sample_rate = 11025 * pow(2, sr_selector);
|
||||
}
|
||||
|
||||
if (hdr->version == 1) {
|
||||
uint32_t granule_hi = 0, granule_lo = 0; //bitreader only handles 32b
|
||||
|
||||
hdr->unknown1 = bm_read(is, 1); // always 1?
|
||||
hdr->unknown2 = bm_read(is, 1); // always 1?
|
||||
hdr->unknown3 = bm_read(is, 7); // always 0?
|
||||
|
||||
granule_hi = bm_read(is, 32);
|
||||
granule_lo = bm_read(is, 32);
|
||||
hdr->last_granule = ((uint64_t)granule_hi << 32) | granule_lo;
|
||||
}
|
||||
else {
|
||||
hdr->unknown1 = 0;
|
||||
hdr->unknown2 = 0;
|
||||
hdr->unknown3 = 0;
|
||||
hdr->last_granule = 0;
|
||||
}
|
||||
|
||||
hdr->blocksize1_exp = bm_read(is, 4);
|
||||
hdr->blocksize0_exp = bm_read(is, 4);
|
||||
hdr->framing = bm_read(is, 1); //always 1
|
||||
|
||||
uint32_t bit_pos = bm_pos(is) % 8;
|
||||
if (bit_pos > 0) {
|
||||
hdr->post_padding = bm_read(is, 8 - bit_pos); // aligned to next byte
|
||||
}
|
||||
else {
|
||||
hdr->post_padding = 0;
|
||||
}
|
||||
}
|
||||
|
||||
// bit-packed setup (should be byte-aligned)
|
||||
void oor_read_setup(bitstream_t* is, oor_setup_t* setup) {
|
||||
setup->type = bm_read(is, 2);
|
||||
setup->codebook_id = bm_read(is, 6);
|
||||
// known codebooks:
|
||||
// 1~6: common on PC games
|
||||
// 7: Muv-Luv, Muv-Luv Alternative (Vita)
|
||||
}
|
||||
|
||||
|
||||
// extra validations since bitpacket headers are a bit simple
|
||||
bool oor_validate_header_page(oor_page_t* page, oor_header_t* hdr) {
|
||||
if (page->version > 1 || page->flags != 0x02)
|
||||
return false;
|
||||
|
||||
if (page->granule != 0 || page->padding1 != 0 || page->padding2 != 0)
|
||||
return false;
|
||||
|
||||
if (hdr->pre_padding != 0 || hdr->version > 1 || hdr->version != page->version)
|
||||
return false;
|
||||
if (hdr->channels == 0 || hdr->sample_rate == 0)
|
||||
return false;
|
||||
//if (hdr->channels > OOR_MAX_CHANNELS) // known max is 2, allow to detect other cases
|
||||
// return false;
|
||||
|
||||
if (hdr->version == 1 && hdr->last_granule == 0)
|
||||
return false;
|
||||
|
||||
if (hdr->blocksize0_exp < 6 || hdr->blocksize0_exp > 13 || hdr->blocksize1_exp < 6 || hdr->blocksize1_exp > 13)
|
||||
return false;
|
||||
if (hdr->framing != 1)
|
||||
return false;
|
||||
|
||||
if (hdr->post_padding != 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool oor_validate_setup_page(oor_page_t* page, oor_size_t* size, oor_header_t* hdr) {
|
||||
if (page->version != hdr->version)
|
||||
return false;
|
||||
// oddly enough codebooks may be split into other pages using OOR_FLAG_PARTIAL
|
||||
if (page->flags & OOR_FLAG_CONTINUED || page->flags & OOR_FLAG_BOS || page->flags & OOR_FLAG_EOS)
|
||||
return false;
|
||||
|
||||
if (page->granule != 0 || page->padding1 != 0 || page->padding2 != 0)
|
||||
return false;
|
||||
if (size->padding1 != 0 || size->bps_selector == 3)
|
||||
return false;
|
||||
if (size->post_padding != 0)
|
||||
return false;
|
||||
|
||||
//if (setup->type != 0x01)
|
||||
// return false;
|
||||
//if (setup->codebook_id > OOR_MAX_CODEBOOK_ID) // known max is 7, allow to detect other cases
|
||||
// return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool oor_validate_setup_info(oor_page_t* page, oor_size_t* size, oor_setup_t* setup) {
|
||||
|
||||
// setup packet always has 2 packets: setup info + vorbis codebook
|
||||
if (size->packet_count != 2)
|
||||
return false;
|
||||
int packet0_size = size->base_packet_size + size->variable_packet_size[0];
|
||||
int packet1_size = size->base_packet_size + size->variable_packet_size[1];
|
||||
|
||||
if (packet0_size != 0x01)
|
||||
return false;
|
||||
// size is 0 when using codebook ids
|
||||
if ((setup->codebook_id > 0 && packet1_size != 0) || (setup->codebook_id == 0 && packet1_size == 0))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool oor_validate_audio_page(oor_page_t* page, oor_size_t* size, oor_header_t* hdr) {
|
||||
if (hdr != NULL && page->version != hdr->version)
|
||||
return false;
|
||||
if (page->flags & OOR_FLAG_BOS)
|
||||
return false;
|
||||
if (page->padding1 != 0 || page->padding2 != 0)
|
||||
return false;
|
||||
|
||||
if (size->padding1 != 0 || size->bps_selector == 3)
|
||||
return false;
|
||||
if (size->post_padding != 0)
|
||||
return false;
|
||||
|
||||
if (size->packet_count == 0)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#endif
|
77
Frameworks/vgmstream/vgmstream/src/coding/libs/oor_helpers.h
Normal file
77
Frameworks/vgmstream/vgmstream/src/coding/libs/oor_helpers.h
Normal file
|
@ -0,0 +1,77 @@
|
|||
#ifndef _OOR_HELPERS_H
|
||||
#define _OOR_HELPERS_H
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "../../util/bitstream_msb.h"
|
||||
|
||||
/**
|
||||
* OOR has custom pages similar to OggS but not quite equivalent (needs to fiddle with packets).
|
||||
* Header and setup packets are custom, but audio packets are standard.
|
||||
* Format is bitpacked and some parts may be ambiguous, but it should fail midway on bad data.
|
||||
* Lib expects the whole file in memory and isn't well tuned for streaming though.
|
||||
*
|
||||
* Info from:
|
||||
* - mostly https://github.com/tsudoko/deoptimizeobs (FORMAT doc describes .oor, but some info is slightly off)
|
||||
* - some bits from decompilation
|
||||
*/
|
||||
|
||||
#define OOR_FLAG_CONTINUED (1<<3) // 1000 = continued (first packet in page is part of last; equivalent to OggS 0x01)
|
||||
#define OOR_FLAG_PARTIAL (1<<2) // 0100 = partial (last packet in page is not complete and must be merged with prev; OggS uses size 0xFF for this)
|
||||
#define OOR_FLAG_BOS (1<<1) // 0010 = beginning-of-stream (irst page, OggS 0x02)
|
||||
#define OOR_FLAG_EOS (1<<0) // 0001 = end-of-stream (last page, OggS 0x04)
|
||||
//#define OOR_FLAG_NORMAL 0 // any other regular packet
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint8_t version;
|
||||
uint8_t flags;
|
||||
int64_t granule;
|
||||
int padding1;
|
||||
int padding2;
|
||||
} oor_page_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t vps_bits;
|
||||
uint8_t padding1;
|
||||
uint8_t packet_count;
|
||||
uint8_t bps_selector;
|
||||
int16_t base_packet_size; // max 7FF (may be 0)
|
||||
int16_t variable_packet_size[256]; // max 7FFF of N packet_count (may be 0)
|
||||
uint8_t post_padding;
|
||||
} oor_size_t;
|
||||
|
||||
typedef struct {
|
||||
uint8_t pre_padding;
|
||||
uint8_t version;
|
||||
uint8_t channels;
|
||||
int sample_rate;
|
||||
uint8_t unknown1;
|
||||
uint8_t unknown2;
|
||||
uint8_t unknown3;
|
||||
int64_t last_granule;
|
||||
uint8_t blocksize0_exp;
|
||||
uint8_t blocksize1_exp;
|
||||
uint8_t framing;
|
||||
uint8_t post_padding;
|
||||
} oor_header_t;
|
||||
|
||||
// codebooks are set in plugin with a table of size + codebook
|
||||
typedef struct {
|
||||
int type;
|
||||
int codebook_id;
|
||||
//int codebook_size;
|
||||
//uint8_t* codebook;
|
||||
} oor_setup_t;
|
||||
|
||||
// page headers, assumes buf in bitstream (probable max ~0x200)
|
||||
void oor_read_page(bitstream_t* is, oor_page_t* page);
|
||||
void oor_read_size(bitstream_t* is, oor_size_t* size);
|
||||
void oor_read_header(bitstream_t* is, oor_header_t* hdr);
|
||||
void oor_read_setup(bitstream_t* is, oor_setup_t* setup);
|
||||
|
||||
bool oor_validate_header_page(oor_page_t* page, oor_header_t* hdr);
|
||||
bool oor_validate_setup_page(oor_page_t* page, oor_size_t* size, oor_header_t* hdr);
|
||||
bool oor_validate_setup_info(oor_page_t* page, oor_size_t* size, oor_setup_t* setup);
|
||||
bool oor_validate_audio_page(oor_page_t* page, oor_size_t* size, oor_header_t* hdr);
|
||||
|
||||
#endif
|
|
@ -1260,12 +1260,11 @@ static inline int16_t clamp16f(float sample) {
|
|||
}
|
||||
|
||||
void tac_get_samples_pcm16(tac_handle_t* handle, int16_t* dst) {
|
||||
int ch, i;
|
||||
int chs = TAC_CHANNELS;
|
||||
|
||||
for (ch = 0; ch < chs; ch++) {
|
||||
for (int ch = 0; ch < chs; ch++) {
|
||||
int s = 0;
|
||||
for (i = 0; i < TAC_FRAME_SAMPLES / 4; i++) {
|
||||
for (int i = 0; i < TAC_FRAME_SAMPLES / 4; i++) {
|
||||
dst[(s+0)*chs + ch] = clamp16f(handle->wave[ch][i].f.x);
|
||||
dst[(s+1)*chs + ch] = clamp16f(handle->wave[ch][i].f.y);
|
||||
dst[(s+2)*chs + ch] = clamp16f(handle->wave[ch][i].f.z);
|
||||
|
@ -1275,6 +1274,21 @@ void tac_get_samples_pcm16(tac_handle_t* handle, int16_t* dst) {
|
|||
}
|
||||
}
|
||||
|
||||
// TAC originally returns PCM16 but allow internal floats for flexility
|
||||
void tac_get_samples_float(tac_handle_t* handle, float* dst) {
|
||||
int chs = TAC_CHANNELS;
|
||||
|
||||
for (int ch = 0; ch < chs; ch++) {
|
||||
int s = 0;
|
||||
for (int i = 0; i < TAC_FRAME_SAMPLES / 4; i++) {
|
||||
dst[(s+0)*chs + ch] = (handle->wave[ch][i].f.x);
|
||||
dst[(s+1)*chs + ch] = (handle->wave[ch][i].f.y);
|
||||
dst[(s+2)*chs + ch] = (handle->wave[ch][i].f.z);
|
||||
dst[(s+3)*chs + ch] = (handle->wave[ch][i].f.w);
|
||||
s += 4;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void tac_set_loop(tac_handle_t* handle) {
|
||||
handle->frame_number = handle->header.loop_frame;
|
||||
|
|
|
@ -49,6 +49,7 @@ void tac_free(tac_handle_t* handle);
|
|||
int tac_decode_frame(tac_handle_t* handle, const uint8_t* block);
|
||||
|
||||
void tac_get_samples_pcm16(tac_handle_t* handle, int16_t* dst);
|
||||
void tac_get_samples_float(tac_handle_t* handle, float* dst);
|
||||
|
||||
void tac_set_loop(tac_handle_t* handle);
|
||||
|
||||
|
|
|
@ -0,0 +1,393 @@
|
|||
/* Handles Ubi-MPEG, a modified VBR MP2 (format seems to be called simply 'MPEG').
|
||||
*
|
||||
* Sync is slightly different and MPEG config is fixed (info removed from the bitstream). Frames
|
||||
* are also not byte-aligned, meaning a new frame starts right after prev ends in the bitstream
|
||||
* (in practice frames are aligned to 4-bits though so recognizable in plain sight).
|
||||
* It also has a mode where 1 stereo frame + 1 mono frame are used make surround(?) output.
|
||||
*
|
||||
* TODO: this doesn't handle surround modes at the moment, so it isn't fully accurate.
|
||||
*
|
||||
* Partially reverse engineered from DLLs.
|
||||
* - MPGMXBVR.DLL: regular version, seems to (mostly) not use simd (ex. sub_10001400)
|
||||
* - MPGMXSVR.DLL: xmm version
|
||||
*
|
||||
* Info+crosschecking from spec and libmpg123/various:
|
||||
* - http://www.mp3-tech.org/programmer/frame_header.html
|
||||
* - https://github.com/dreamerc/mpg123/blob/master/src/libmpg123/layer2.c
|
||||
*/
|
||||
|
||||
//TODO: test if files have encoding delay, but some files seem to have very few spare samples vs declared block samples
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "ubi_mpeg_helpers.h"
|
||||
#include "../../util/log.h"
|
||||
|
||||
// forced size to simplify (explained later): (144 * bitrate * 1000 / sample_rate) + (1 optional padding byte)
|
||||
//#define UBIMPEG_STEREO_FRAME_SIZE 0x20B // 128~160kkbps
|
||||
//#define UBIMPEG_MONO_FRAME_SIZE 0x106 // 64~80kbps
|
||||
#define UBIMPEG_FIXED_FRAME_SIZE 0x300 // ~256kbps at 48000hz
|
||||
|
||||
// standard MPEG modes
|
||||
#define CH_MODE_MONO 3
|
||||
#define CH_MODE_JOINT 1
|
||||
#define CH_MODE_STEREO 0
|
||||
#define MAX_BANDS 32 //30?
|
||||
#define MAX_GRANULES 12
|
||||
|
||||
// band <> used allocation bits
|
||||
// table 0 for 27 subbands (out of ~4); Ubi-MPEG only has this table.
|
||||
// (spec's Table 3-B.2a, though we separate it into multiple tables for clarity)
|
||||
static const uint8_t BITALLOC_TABLE_0[32] = {
|
||||
4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 4, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2, 0, 0, 0, 0, 0,
|
||||
};
|
||||
|
||||
// index of "number of steps" to the "bits per codeword" (qbit) table, [band][index]
|
||||
static const uint8_t QINDEX_TABLE_0[32][16] = {
|
||||
{ 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, },
|
||||
{ 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, },
|
||||
{ 0, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, },
|
||||
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 },
|
||||
{ 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 16 },
|
||||
|
||||
{ 0, 1, 2, 3, 4, 5, 16, },
|
||||
{ 0, 1, 2, 3, 4, 5, 16, },
|
||||
{ 0, 1, 2, 3, 4, 5, 16, },
|
||||
{ 0, 1, 2, 3, 4, 5, 16, },
|
||||
{ 0, 1, 2, 3, 4, 5, 16, },
|
||||
{ 0, 1, 2, 3, 4, 5, 16, },
|
||||
{ 0, 1, 2, 3, 4, 5, 16, },
|
||||
{ 0, 1, 2, 3, 4, 5, 16, },
|
||||
{ 0, 1, 2, 3, 4, 5, 16, },
|
||||
{ 0, 1, 2, 3, 4, 5, 16, },
|
||||
{ 0, 1, 2, 3, 4, 5, 16, },
|
||||
{ 0, 1, 2, 3, 4, 5, 16, },
|
||||
|
||||
{ 0, 1, 16, },
|
||||
{ 0, 1, 16, },
|
||||
{ 0, 1, 16, },
|
||||
{ 0, 1, 16, },
|
||||
{ 0, 1, 16, },
|
||||
{ 0, 1, 16, },
|
||||
{ 0, 1, 16, },
|
||||
};
|
||||
|
||||
// "bits per codeword" (qbit) table, number of bits used to quantize a value
|
||||
// usually negative has a special meaning of "3 grouped qs"
|
||||
static const int8_t QBITS_TABLE_0[17] = {
|
||||
-5, -7, 3, -10, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16,
|
||||
};
|
||||
|
||||
#if 0
|
||||
// often QBITS_TABLE uses negative values meaning "grouping" to avoid this table (-5, -7, 3, -10, ...)
|
||||
static const int8_t GROUPING_TABLE[17] = {
|
||||
3, 3, 1, 3, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1,
|
||||
};
|
||||
#endif
|
||||
|
||||
// bands in the bitstream, fixed to index 0 in Ubi MPEG
|
||||
static const int MAX_SUBBANDS[5] = { 27, 30, 8, 12, 30 };
|
||||
|
||||
// number of subbands that are regular stereo, depending on mode extension (rest are intensity stereo)
|
||||
static int JOINT_BOUNDS[4] = { 4, 8, 12, 16 };
|
||||
|
||||
|
||||
// most Ubi MPEG files have frames right after other, but sometimes they'll have some
|
||||
// of padding. This doesn't seem a bitreading issue, their OG libs do seem to manually
|
||||
// try to find sync until EOF on every new frame.
|
||||
static int find_sync(bitstream_t* is) {
|
||||
|
||||
// read until some limit rather than EOF
|
||||
int tests = 0;
|
||||
while (tests < 32) {
|
||||
//TODO: OG lib seems to advance bit-by-bit, but this seems to work
|
||||
uint16_t sync = bm_read(is, 12); // 12 bits unlike 11 in MPEG
|
||||
if (sync != 0)
|
||||
return sync;
|
||||
|
||||
tests++;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// reads a UBI-MPEG frame and transforms it into a regular MP2 frame
|
||||
// Note that UBI-MPEG simply reads and decodes it by itself while handling surround modes,
|
||||
// so this is just a quick hack.
|
||||
int ubimpeg_transform_frame(bitstream_t* is, bitstream_t* os) {
|
||||
//uint32_t offset = bm_pos(is) / 8;
|
||||
|
||||
// config per sample rae + bitrate + channels, fixed in Ubi MPEG
|
||||
const int table = 0;
|
||||
// bit info about how samples in subband are quantized
|
||||
uint8_t bit_alloc[MAX_BANDS][2] = {0};//todo invert ch, todo 'allocation'
|
||||
uint32_t scfsi[MAX_BANDS][2] = {0};
|
||||
|
||||
/* read 16-bit Ubi-MPEG header */
|
||||
uint16_t sync = find_sync(is);
|
||||
if (sync != 0xFFF) {
|
||||
//VGM_LOG("UBI-MPEG: sync not found at %x (+ %i), value=%x\n", is->b_off / 8, is->b_off % 8, sync);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t mode = bm_read(is, 4);
|
||||
|
||||
int extmode = (mode >> 0) & 0x03;
|
||||
int ch_mode = (mode >> 2) & 0x03;
|
||||
int channels = (ch_mode == CH_MODE_MONO) ? 1 : 2;
|
||||
int subbands = MAX_SUBBANDS[table];
|
||||
int joint_bound = (ch_mode != CH_MODE_JOINT) ? subbands : JOINT_BOUNDS[extmode]; // boundary of non-js bands
|
||||
|
||||
// Ubi-MPEG uses VBR and settings close to 44100 + 128~160kbps (stereo) / 64~80kbps (mono). However some
|
||||
// frames spill into 1 more byte than the 0x20b allowed by 160kbps (even with padding bit). Sample rate + bitrate
|
||||
// combo must end up using certain tables in decoders, so use a setting that allows a consistenct bitrate.
|
||||
// Free bitrate (br_index 0) is usable too but decoders need several frames to detect sizes.
|
||||
int frame_size = UBIMPEG_FIXED_FRAME_SIZE;
|
||||
int br_index = 12; // 256kbps
|
||||
int sr_index = 1; // fixed to 48000 (Ubi MPEG is 44100 but shouldn't affect decoding)
|
||||
int padding = 0;
|
||||
|
||||
// real-ish settings, but doesn't work for all frames
|
||||
//frame_size = (channels == 2) ? UBIMPEG_STEREO_FRAME_SIZE : UBIMPEG_MONO_FRAME_SIZE;
|
||||
//br_index = (channels == 2) ? 9 : 5; // 160kbps / 80kbps
|
||||
//sr_index = 0; // fixed to 44100
|
||||
//padding = 1;
|
||||
|
||||
/* write 32-bit MPEG frame header */
|
||||
bm_put(os, 11, 0x7FF); // sync
|
||||
bm_put(os, 2, 3); // MPEG 1 index
|
||||
bm_put(os, 2, 2); // layer II index
|
||||
bm_put(os, 1, 1); // "no CRC" flag
|
||||
bm_put(os, 4, br_index); // bitrate index
|
||||
bm_put(os, 2, sr_index); // sample rate index
|
||||
bm_put(os, 1, padding); // padding
|
||||
bm_put(os, 1, 0); // private
|
||||
bm_put(os, 2, ch_mode); // channel mode
|
||||
bm_put(os, 2, extmode); // mode extension
|
||||
bm_put(os, 1, 1); // copyrighted
|
||||
bm_put(os, 1, 1); // original
|
||||
bm_put(os, 2, 0); // emphasis
|
||||
|
||||
|
||||
// step I: read allocation bits
|
||||
for (int i = 0; i < joint_bound; i++) {
|
||||
int ba_bits = BITALLOC_TABLE_0[i];
|
||||
for (int ch = 0; ch < channels; ch++) {
|
||||
bit_alloc[i][ch] = bm_read(is, ba_bits);
|
||||
bm_put(os, ba_bits, bit_alloc[i][ch]);
|
||||
}
|
||||
}
|
||||
|
||||
// step I: read rest of joint stereo allocation bits (same for L and R)
|
||||
for (int i = joint_bound; i < subbands; i++) {
|
||||
int ba_bits = BITALLOC_TABLE_0[i];
|
||||
|
||||
bit_alloc[i][0] = bm_read(is, ba_bits);
|
||||
bit_alloc[i][1] = bit_alloc[i][0];
|
||||
bm_put(os, ba_bits, bit_alloc[i][0]);
|
||||
}
|
||||
|
||||
// step I: read scalefactor selector information (how many scalefactors are included)
|
||||
for (int i = 0; i < subbands; i++) {
|
||||
for (int ch = 0; ch < channels; ch++) {
|
||||
if (bit_alloc[i][ch] == 0)
|
||||
continue;
|
||||
|
||||
scfsi[i][ch] = bm_read(is, 2);
|
||||
bm_put(os, 2, scfsi[i][ch]);
|
||||
}
|
||||
}
|
||||
|
||||
// step I: read scalefactors from scfsi indexes
|
||||
for (int i = 0; i < subbands; i++) {
|
||||
for (int ch = 0; ch < channels; ch++) {
|
||||
if (bit_alloc[i][ch] == 0)
|
||||
continue;
|
||||
|
||||
int scf;
|
||||
switch(scfsi[i][ch]) {
|
||||
case 0: // 3 scalefactors
|
||||
scf = bm_read(is, 6);
|
||||
bm_put(os, 6, scf);
|
||||
scf = bm_read(is, 6);
|
||||
bm_put(os, 6, scf);
|
||||
scf = bm_read(is, 6);
|
||||
bm_put(os, 6, scf);
|
||||
break;
|
||||
case 1: // 2 scalefactors (reuses 1st for 2nd)
|
||||
case 3: // 2 scalefactors (reuses 2nd for 3rd)
|
||||
scf = bm_read(is, 6);
|
||||
bm_put(os, 6, scf);
|
||||
scf = bm_read(is, 6);
|
||||
bm_put(os, 6, scf);
|
||||
break;
|
||||
case 2: // 1 scalefactor (reuses all 3)
|
||||
scf = bm_read(is, 6);
|
||||
bm_put(os, 6, scf);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// step II: read quantized DCT coefficients
|
||||
// (restored to 3 samples per granule and up to 32 subbands)
|
||||
for (int gr = 0; gr < MAX_GRANULES; gr++) {
|
||||
// regular quants
|
||||
for (int i = 0; i < joint_bound; i++) {
|
||||
for (int ch = 0; ch < channels; ch++) {
|
||||
int ba_index = bit_alloc[i][ch];
|
||||
if (ba_index == 0)
|
||||
continue;
|
||||
|
||||
int qb_index = QINDEX_TABLE_0[i][ba_index - 1];
|
||||
int qbits = QBITS_TABLE_0[qb_index];
|
||||
|
||||
int qs;
|
||||
if (qbits < 0) { // grouping used
|
||||
qbits = -qbits; // remove flag
|
||||
qs = 1; // same value for 3 codes
|
||||
}
|
||||
else {
|
||||
qs = 3; // 3 distinct codes
|
||||
}
|
||||
|
||||
for (int q = 0; q < qs; q++) {
|
||||
int qcode = bm_read(is, qbits);
|
||||
bm_put(os, qbits, qcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// joint stereo quants (1 channel only)
|
||||
for (int i = joint_bound; i < subbands; i++) {
|
||||
{
|
||||
int ba_index = bit_alloc[i][0];
|
||||
if (ba_index == 0)
|
||||
continue;
|
||||
|
||||
int qb_index = QINDEX_TABLE_0[i][ba_index - 1];
|
||||
int qbits = QBITS_TABLE_0[qb_index];
|
||||
|
||||
int qs;
|
||||
if (qbits < 0) { // grouping used
|
||||
qbits = -qbits; // remove flag
|
||||
qs = 1; // same value for 3 codes
|
||||
}
|
||||
else {
|
||||
qs = 3; // 3 distinct codes
|
||||
}
|
||||
|
||||
for (int q = 0; q < qs; q++) {
|
||||
int qcode = bm_read(is, qbits);
|
||||
bm_put(os, qbits, qcode);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// real MPEG frames are byte padded, but not Ubi-MPEG's (usually)
|
||||
uint32_t bitpos = bm_pos(os);
|
||||
if (bitpos % 8) {
|
||||
bm_skip(os, 8 - (bitpos % 8));
|
||||
}
|
||||
|
||||
//uint32_t end_offset = bm_pos(is) / 8;
|
||||
//VGM_LOG("frame: ch_mode=%x, extmode=%x = chs=%i, reg_bands=%i, o=%x + %x\n", ch_mode, extmode, channels, joint_bound, offset, end_offset - offset);
|
||||
|
||||
// 0-pad as may confuse decoders otherwise
|
||||
uint32_t obuf_done = bm_pos(os) / 8;
|
||||
if (obuf_done > frame_size) {
|
||||
//VGM_LOG("error: buf done=%x (%i) vs %x\n", obuf_done, bm_pos(os), frame_size);
|
||||
return 0;
|
||||
}
|
||||
else {
|
||||
memset(os->buf + obuf_done, 0x00, frame_size - obuf_done);
|
||||
}
|
||||
|
||||
return frame_size;
|
||||
}
|
||||
|
||||
|
||||
|
||||
#if 0
|
||||
static bool parse_file(uint8_t* buf, int buf_size, FILE* outfile_mp2a, FILE* outfile_mp2b, FILE* outfile0_wav, FILE* outfile1_wav) {
|
||||
|
||||
printf("UBI-MPEG: samples=%i, 2rus=%i, 1rus=%i\n", samples, is_2rus, is_1rus);
|
||||
|
||||
|
||||
bitstream_t is;
|
||||
bm_setup(&is, buf, buf_size);
|
||||
bm_skip(&is, 0x04 * 8);
|
||||
if (is_1rus || is_2rus)
|
||||
bm_skip(&is, 0x04 * 8);
|
||||
|
||||
uint8_t obuf[0x800];
|
||||
bitstream_t os;
|
||||
|
||||
mp3dec_t mp3d0;
|
||||
mp3dec_init(&mp3d0);
|
||||
mp3dec_frame_info_t info0;
|
||||
short pcm0[MINIMP3_MAX_SAMPLES_PER_FRAME];
|
||||
|
||||
mp3dec_t mp3d1;
|
||||
mp3dec_init(&mp3d1);
|
||||
mp3dec_frame_info_t info1;
|
||||
short pcm1[MINIMP3_MAX_SAMPLES_PER_FRAME];
|
||||
|
||||
int frames = 0;
|
||||
int done = 0;
|
||||
int obuf_size;
|
||||
while (1) {
|
||||
|
||||
// 1st frame
|
||||
{
|
||||
bm_setup(&os, obuf, sizeof(obuf));
|
||||
|
||||
obuf_size = ubimpeg_transform_frame(&is, &os);
|
||||
if (!obuf_size) break;
|
||||
frames++;
|
||||
fwrite(obuf, sizeof(uint8_t), obuf_size, outfile_mp2a);
|
||||
|
||||
int pcm0_samples = mp3dec_decode_frame(&mp3d0, obuf, obuf_size, pcm0, &info0);
|
||||
printf("mpeg0: pcm=%i, br=%i, ch=%i, by=%x\n", pcm0_samples, info0.bitrate_kbps, info0.channels, info0.frame_bytes);
|
||||
fwrite(pcm0, sizeof(short), pcm0_samples * info0.channels, outfile0_wav);
|
||||
}
|
||||
|
||||
// 2nd frame
|
||||
if (is_1rus || is_2rus) {
|
||||
bm_setup(&os, obuf, sizeof(obuf));
|
||||
|
||||
obuf_size = ubimpeg_transform_frame(&is, &os);
|
||||
if (!obuf_size) break;
|
||||
frames++;
|
||||
|
||||
fwrite(obuf, sizeof(uint8_t), obuf_size, outfile_mp2b);
|
||||
|
||||
int pcm1_samples = mp3dec_decode_frame(&mp3d1, obuf, obuf_size, pcm1, &info1);
|
||||
printf("mpeg1: pcm=%i, br=%i, ch=%i, by=%x\n", pcm1_samples, info1.bitrate_kbps, info1.channels, info1.frame_bytes);
|
||||
fwrite(pcm1, sizeof(short), pcm1_samples * info1.channels, outfile1_wav);
|
||||
}
|
||||
|
||||
|
||||
done += 1152;
|
||||
printf("samples: %i / %i, obuf=%x (%x)\n", done, samples, obuf_size);
|
||||
if (done >= samples)
|
||||
break;
|
||||
}
|
||||
printf("frames: done=%i (%x) / samples=%i (%x)\n", done, done, samples, samples);
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,9 @@
|
|||
#ifndef _UBI_MPEG_HELPERS_H
|
||||
#define _UBI_MPEG_HELPERS_H
|
||||
|
||||
#include "../../util/bitstream_msb.h"
|
||||
|
||||
int ubimpeg_transform_frame(bitstream_t* is, bitstream_t* os);
|
||||
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
|
@ -0,0 +1,777 @@
|
|||
#ifndef _VORBIS_CODEBOOKS_OOR_H_
|
||||
#define _VORBIS_CODEBOOKS_OOR_H_
|
||||
#include "../../util/vorbis_codebooks.h"
|
||||
|
||||
/**
|
||||
* Codebooks can be found like this packed in executables or riooor lib
|
||||
* (with a table of size + offset to binary, ID is just an index to entry N though).
|
||||
* Bigger .oor use codebooks in file so there aren't many setups.
|
||||
*/
|
||||
|
||||
/* ******************************************** */
|
||||
/* autogenerated */
|
||||
/* ******************************************** */
|
||||
|
||||
static const uint8_t vcb_1[] = {
|
||||
0x1F,0x42,0x43,0x56,0x01,0x00,0x00,0x01,0x00,0x9C,0x73,0x9A,0x31,0x87,0x99,0x62,0x94,0x52,0x89,0x21,0x94,0xDE,0x39,0x68,0x19,0x63,0x94,0x52,0x69,0x29,0xA5,0x5A,
|
||||
0x4A,0xA9,0xA1,0x83,0x16,0x6B,0xAB,0xBD,0xF7,0xDE,0x7B,0xEF,0xBD,0xF7,0xDE,0x7B,0xEF,0x1D,0x73,0x94,0x31,0x46,0x95,0x52,0x52,0x4A,0xA9,0x9D,0x73,0x96,0x31,0x47,
|
||||
0x15,0x63,0x52,0x4A,0x89,0xA5,0x94,0x56,0x42,0x68,0x21,0x84,0xD6,0x62,0xAB,0xBD,0xF7,0xDE,0x6B,0xEF,0xB5,0xF6,0xDE,0x7B,0xEF,0x99,0x42,0x4C,0x29,0xA4,0x14,0x42,
|
||||
0x08,0x4A,0x28,0x1D,0x53,0x8C,0x29,0xA4,0x94,0x42,0x4A,0x4A,0x08,0x25,0x64,0x0E,0x3A,0xC6,0x1C,0x53,0x8C,0x52,0x09,0x3D,0xD6,0x5E,0x6B,0xCC,0xBD,0xB6,0xD8,0x7B,
|
||||
0xED,0xA1,0x63,0xCE,0x39,0xE6,0x1C,0x53,0x4C,0x4A,0x68,0x21,0x74,0x0E,0x3A,0xE6,0x9C,0x53,0x4C,0x4A,0x68,0xA9,0x84,0x52,0x42,0x06,0xA1,0x53,0xD0,0x52,0x89,0xAD,
|
||||
0xF7,0xDE,0x62,0xEB,0xB9,0xA5,0xDA,0x7B,0xEF,0x81,0xD0,0x90,0x55,0x00,0x00,0x01,0x00,0xC0,0x40,0x10,0x1A,0xB2,0x0A,0x00,0x50,0x00,0x00,0x10,0x8A,0xA1,0x18,0x8A,
|
||||
0x02,0x84,0x86,0xAC,0x02,0x00,0x32,0x00,0x00,0x04,0xE0,0x28,0x8E,0xE3,0x38,0x8E,0xE2,0x38,0x92,0x62,0x39,0x16,0x10,0x1A,0xB2,0x0A,0x00,0x00,0x02,0x00,0x10,0x00,
|
||||
0x00,0xC0,0x90,0x0C,0x4B,0xB1,0x14,0xCD,0xD1,0x24,0x4D,0xD2,0x2C,0xCF,0x13,0x4D,0xD3,0x37,0x7D,0xD3,0x36,0x6D,0x55,0xD7,0x75,0x5D,0xD7,0x75,0x5D,0xD7,0x75,0x20,
|
||||
0x34,0x64,0x15,0x00,0x00,0x01,0x00,0x40,0x40,0xA7,0x19,0xA6,0x1A,0x20,0xC2,0x8C,0x64,0x16,0x08,0x0D,0x59,0x05,0x00,0x20,0x00,0x00,0x00,0x44,0x20,0xC3,0x14,0x03,
|
||||
0x42,0x43,0x56,0x01,0x00,0x00,0x01,0x00,0x00,0x52,0x24,0x39,0x49,0xA2,0xE4,0xA4,0x94,0x52,0x0E,0x83,0x64,0x31,0x49,0x2A,0xE5,0xA4,0x94,0x52,0x1E,0xC5,0xE4,0x51,
|
||||
0x4D,0x32,0x06,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x0A,0x83,0x64,0x39,0x4A,0x2A,0xE5,0xA4,0x94,0x52,0x12,0xA3,0x64,0x31,0x4A,0xAA,
|
||||
0xD4,0xA4,0x94,0x52,0x1E,0xE5,0xE4,0x49,0x4D,0x32,0xF6,0xA4,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x16,0xA4,0xE4,0x49,0x4B,0xBA,0x06,0xA5,
|
||||
0x94,0x52,0x92,0xA3,0xA4,0x41,0x4B,0x36,0xF5,0xA4,0x94,0x52,0xA2,0x14,0x25,0x4A,0x4E,0xB6,0x27,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,
|
||||
0x3E,0x28,0xE5,0x83,0x50,0x4A,0x29,0xA5,0x94,0x52,0xAE,0xF6,0xE4,0x5A,0x4F,0x4A,0x29,0xA5,0x94,0x52,0xC6,0x28,0x25,0x7C,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,
|
||||
0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x32,0x82,0xD0,0x90,0x55,0x00,0x00,0x10,0x00,0x00,0x60,0x9C,0x35,0xCA,0xA1,0xE8,0x24,0x3A,0x5F,0x9C,0xA1,0x9C,0x69,0x0A,0x92,
|
||||
0x0A,0xA5,0x09,0xDD,0x9B,0xE4,0x28,0x79,0x4E,0x72,0x2B,0x2D,0x37,0xA7,0x9B,0x70,0xCE,0xE9,0xE6,0x94,0x73,0x3E,0x39,0xE7,0x9C,0x20,0x34,0x64,0x15,0x00,0x00,0x08,
|
||||
0x00,0x00,0x21,0x84,0x14,0x52,0x48,0x21,0x85,0x14,0x52,0x48,0x21,0x85,0x14,0x62,0x88,0x21,0x86,0x1C,0x72,0xCA,0x29,0xA8,0xA0,0x82,0x4A,0x2A,0xA9,0xA8,0xA2,0x8A,
|
||||
0x2A,0xAB,0x2C,0xB3,0xCC,0x32,0xCB,0x2C,0xB3,0xCC,0x32,0xCB,0x2C,0xB3,0xCC,0x3A,0xEB,0xA8,0xA3,0xCE,0x42,0x0A,0xA1,0xA4,0xD0,0x42,0x6B,0x35,0xC6,0x1A,0x63,0x6C,
|
||||
0xB5,0x37,0x27,0x6D,0xCD,0x51,0x4A,0x27,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x73,0xCE,0x39,0x27,0x08,0x0D,0x59,0x05,0x00,0x80,0x00,0x00,0x10,0x08,0x19,0x64,0x90,0x41,
|
||||
0x46,0x19,0x85,0x14,0x62,0x88,0x29,0xA7,0x9C,0x72,0x0A,0x2A,0xA9,0xA4,0x02,0x42,0x43,0x56,0x01,0x00,0x80,0x00,0x00,0x02,0x00,0x00,0x00,0x44,0xC9,0x74,0x4C,0x47,
|
||||
0x74,0x44,0x45,0x74,0x44,0x47,0x74,0x44,0x47,0x74,0x44,0xC7,0x73,0x3C,0xC7,0x93,0x44,0x49,0xB4,0x3C,0x4B,0xD4,0x4C,0xCF,0x14,0x4D,0xD3,0x74,0x55,0xD9,0x95,0x65,
|
||||
0x5D,0xB6,0x65,0xDB,0xD5,0x65,0xDD,0xD6,0x65,0xDF,0xF6,0x6D,0xDD,0xB6,0x6D,0x5F,0x37,0x76,0xE3,0x37,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,
|
||||
0x8E,0xE3,0x18,0x82,0xD0,0x90,0x55,0x00,0x00,0x08,0x00,0x00,0x80,0x10,0x42,0x08,0x21,0x85,0x14,0x52,0x48,0x21,0xA5,0x98,0x62,0xCC,0x39,0xE8,0x20,0x84,0x50,0x4A,
|
||||
0x20,0x34,0x64,0x15,0x00,0x00,0x08,0x00,0x20,0x00,0x00,0x00,0x40,0x51,0x1C,0xC5,0x71,0x24,0x47,0x92,0x24,0xC9,0x92,0x2C,0x4B,0xB3,0x34,0x4D,0xD3,0x34,0xCD,0x13,
|
||||
0x3D,0xD1,0x33,0x3D,0xD5,0x73,0x45,0x59,0xB4,0x45,0xDB,0x73,0x3D,0x5B,0xB4,0x3D,0xD7,0x53,0x3D,0xD5,0x53,0x45,0xD5,0x54,0x4D,0xD7,0x74,0x55,0xD7,0x75,0x5D,0x57,
|
||||
0x75,0x55,0x59,0x95,0x5D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0x19,0x08,0x0D,0x59,0x05,0x00,0x48,0x00,0x00,0xE8,0x48,0x8E,
|
||||
0xA4,0x48,0x8A,0xA4,0x48,0x8E,0xE3,0x48,0x8E,0x24,0x01,0xA1,0x21,0xAB,0x00,0x00,0x19,0x00,0x00,0x01,0x00,0x28,0x8A,0xA2,0x38,0x8E,0x23,0x39,0x96,0x64,0x49,0x9A,
|
||||
0x24,0x4A,0xA6,0xA5,0x5A,0xAE,0x26,0x7B,0xBA,0xA7,0x8B,0xBA,0xA8,0x03,0xA1,0x21,0xAB,0x00,0x00,0x40,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x18,0xA2,0x21,0x1A,
|
||||
0xA2,0x23,0x5A,0xA2,0x26,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,
|
||||
0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0xE7,0x79,0x9E,0xE7,0x79,0x9E,0xE7,0x79,0x1E,0x10,0x1A,0xB2,0x0A,0x00,0x90,0x00,0x00,0xD0,
|
||||
0x91,0x1C,0xC9,0xB1,0x14,0x4B,0x91,0x14,0x49,0xB1,0x1C,0xCB,0x01,0x42,0x43,0x56,0x01,0x00,0x32,0x00,0x00,0x02,0x00,0x70,0x0C,0xC7,0x90,0x14,0xC9,0xB1,0x2C,0xCB,
|
||||
0xD2,0x34,0xCD,0xF3,0x3C,0xCF,0x13,0x3D,0x51,0x14,0x45,0xD1,0x34,0x55,0x53,0x05,0x42,0x43,0x56,0x01,0x00,0x80,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x50,0x14,
|
||||
0xC5,0x72,0x2C,0x47,0x92,0x34,0xC7,0x93,0x44,0x47,0x94,0x44,0x49,0xB4,0x44,0x49,0xD4,0x44,0x4D,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,
|
||||
0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x20,0x34,0x64,0x25,0x00,0x00,0x04,
|
||||
0x00,0x40,0x49,0x6A,0xB1,0xB5,0xD6,0x28,0x05,0xA1,0xA4,0x98,0x18,0xC2,0x94,0x93,0x1C,0x31,0x06,0x1D,0xA4,0x5E,0x31,0xE4,0x10,0x93,0x9E,0x39,0x06,0x15,0x93,0x5E,
|
||||
0x2A,0x82,0x0C,0x62,0x1E,0x3B,0xC4,0x14,0x93,0x1C,0x08,0x0D,0x59,0x11,0x00,0x44,0x01,0x00,0x00,0xC6,0x20,0xC7,0x10,0x73,0xC8,0x39,0x47,0xA9,0x93,0x14,0x39,0xE7,
|
||||
0xA4,0x74,0x94,0x1A,0xE7,0x1C,0xA5,0x8E,0x52,0x47,0x29,0xC5,0x9A,0x62,0xCD,0x28,0x95,0xDA,0x52,0xAC,0x8D,0x73,0x8E,0x52,0x47,0xA9,0xA3,0x94,0x6A,0x2C,0x2D,0x76,
|
||||
0xD4,0x52,0xAD,0xA9,0xC6,0x02,0x00,0x00,0x02,0x1C,0x00,0x00,0x02,0x2C,0x84,0x42,0x43,0x56,0x04,0x00,0x51,0x00,0x00,0x84,0x31,0x48,0x29,0xA4,0x14,0x62,0x8A,0x39,
|
||||
0xA7,0x98,0x43,0x8A,0x29,0xC7,0x98,0x73,0x88,0x31,0xE6,0x1C,0x73,0x8E,0x39,0xE7,0xA0,0x74,0x52,0x2A,0xE7,0x98,0x74,0x4E,0x4A,0xC4,0x18,0x73,0x8E,0x39,0xA7,0x9C,
|
||||
0x73,0x52,0x32,0x27,0x95,0x73,0x4E,0x4A,0x27,0xA1,0x00,0x00,0x80,0x00,0x07,0x00,0x80,0x00,0x0B,0xA1,0xD0,0x90,0x15,0x01,0x40,0x9C,0x00,0x80,0x41,0x92,0x3C,0x4F,
|
||||
0xD2,0x34,0x51,0x94,0x34,0x4F,0x14,0x3D,0x53,0x74,0x55,0x4F,0x34,0x55,0xD7,0xF2,0x3C,0xD3,0xF4,0x4C,0x53,0x55,0x3D,0xD1,0x54,0x55,0xD3,0x55,0x65,0xD9,0x54,0x55,
|
||||
0x59,0xB6,0x3C,0xCF,0x34,0x3D,0x53,0x54,0x55,0xCF,0x34,0x55,0xD5,0x54,0x55,0x59,0x36,0x55,0x55,0x96,0x45,0x55,0xD5,0x6D,0xD3,0x55,0x75,0xDB,0x74,0x55,0xDD,0x76,
|
||||
0x6D,0xD9,0xD7,0x5D,0x59,0x16,0x76,0x51,0x55,0x6D,0xDB,0x54,0x5D,0x5B,0x37,0x55,0xD7,0x16,0x5E,0xD9,0xD6,0x7D,0x59,0xB6,0x75,0x61,0xF2,0x3C,0x55,0xF5,0x4C,0xD3,
|
||||
0x75,0x3D,0xD3,0x74,0x5D,0xD5,0x75,0x75,0x5B,0x75,0x5D,0x5B,0xF7,0x4C,0x53,0x76,0x4D,0xD7,0x95,0x65,0xD3,0x75,0x6D,0xDB,0x95,0x65,0x5D,0x57,0x65,0x59,0xF7,0x35,
|
||||
0xD3,0x74,0x5D,0xD1,0x55,0x6D,0xD9,0x74,0x5D,0xD9,0x76,0x65,0x57,0xD7,0x5D,0x59,0xF6,0x85,0xD3,0x75,0x75,0xDF,0x95,0x65,0x61,0x57,0x65,0x59,0xF8,0x75,0x5D,0x17,
|
||||
0x86,0x59,0xF7,0x8D,0x63,0x74,0x5D,0x5D,0x58,0x65,0xD7,0xF7,0x55,0x59,0xF6,0x8D,0x5B,0xB7,0x7D,0x5F,0xD6,0x75,0xE1,0x98,0x3C,0x4F,0x55,0x3D,0xD3,0x74,0x5D,0xCF,
|
||||
0x34,0x5D,0xD7,0x74,0x5D,0x5D,0x57,0x5D,0xD7,0xD6,0x35,0xD3,0x74,0x5D,0xD3,0x75,0x6D,0x5B,0x54,0x5D,0x59,0x76,0x65,0xD9,0xF7,0x5D,0x57,0xD6,0x75,0xCF,0x34,0x5D,
|
||||
0xD9,0x74,0x5D,0xD9,0x36,0x5D,0x57,0x96,0x5D,0x59,0xF6,0x7D,0x57,0x96,0x75,0xDD,0x74,0x5D,0xDD,0x57,0x65,0x59,0xF8,0x55,0x57,0x16,0x7E,0x59,0xD7,0x8D,0xE5,0xB6,
|
||||
0x6D,0xE1,0x37,0x5D,0x57,0xD7,0x55,0x59,0xD6,0x7D,0x55,0x96,0x75,0x61,0xD6,0x75,0xE3,0xB9,0x75,0x5D,0x18,0x3E,0x55,0xD5,0x7D,0x53,0x76,0x85,0xDF,0x74,0x65,0x5F,
|
||||
0xD8,0x7D,0xDD,0x59,0x6E,0xDD,0x37,0x96,0xD1,0x75,0x75,0x61,0x95,0x6D,0xE3,0x58,0x65,0x5B,0x18,0x7E,0xE1,0x58,0x96,0xDD,0x37,0x96,0x67,0x74,0x5D,0xDF,0x57,0x6D,
|
||||
0x57,0x18,0x56,0x59,0xF6,0x95,0xDD,0xD7,0x9D,0x65,0xD7,0x75,0x65,0x78,0x6D,0xDB,0x58,0x6E,0x5D,0x57,0x8E,0x59,0xD7,0x8D,0x61,0x38,0x96,0xA7,0xEE,0x0B,0x4F,0x57,
|
||||
0xB7,0x85,0x63,0xF6,0x6D,0xE7,0x99,0x7D,0x5D,0x39,0x7E,0x67,0x78,0x96,0x5F,0xF8,0x29,0x9F,0xAA,0xEA,0xBA,0xE9,0xBA,0xC2,0x70,0xBA,0xB2,0xEF,0xCB,0xB6,0x2E,0x0C,
|
||||
0xBB,0x2F,0x2C,0xCB,0xE8,0xBA,0xBE,0xB0,0xCA,0xB2,0xF1,0xAB,0xB2,0xEC,0x0B,0xB7,0xEE,0x2B,0xC7,0xEE,0x0B,0xC3,0x31,0xBA,0xAE,0xF0,0xAB,0xB6,0xEC,0xFB,0xAE,0x2D,
|
||||
0x0B,0xC7,0xED,0xEB,0xC6,0x32,0x0C,0xC3,0x72,0xBC,0xB6,0xAD,0x0C,0xB3,0xAE,0x0B,0x65,0xDB,0x47,0xF7,0x7D,0xA5,0xEF,0x2B,0x4B,0x57,0xB7,0x95,0x63,0xD6,0x75,0xA5,
|
||||
0xED,0xEB,0x94,0x5D,0x18,0x2A,0xC3,0x31,0x54,0x06,0x00,0x00,0x0C,0x38,0x00,0x00,0x04,0x98,0x50,0x06,0x0A,0x0D,0x59,0x11,0x00,0xC4,0x09,0x00,0x30,0x08,0x39,0x87,
|
||||
0x98,0x82,0x10,0x29,0x06,0x21,0x84,0x90,0x52,0x08,0x21,0xA5,0x88,0x31,0x08,0x99,0x73,0x52,0x2A,0xE6,0xA0,0x94,0x52,0x52,0x0B,0xA5,0xA4,0x16,0x31,0x06,0xA1,0x72,
|
||||
0x4C,0x4A,0xE6,0x9C,0x94,0x50,0x4A,0x4B,0xA5,0x94,0x96,0x42,0x29,0xAD,0x95,0x54,0x62,0x0C,0xA5,0xC4,0xD8,0x5A,0xAB,0x35,0xB5,0x56,0x6B,0x28,0xA5,0xB5,0x50,0x4A,
|
||||
0x8C,0xA5,0x94,0x16,0x53,0x6B,0xB5,0xB6,0xD8,0x6A,0x8D,0x18,0x93,0x92,0x39,0x27,0x25,0x73,0x4E,0x4A,0x29,0x25,0xB6,0x52,0x4A,0x6B,0x99,0x73,0x54,0x3A,0x07,0x25,
|
||||
0x75,0x10,0x52,0x2A,0x25,0xB5,0x58,0x52,0x8A,0xB5,0x72,0x4E,0x4A,0x06,0x1D,0x95,0x0E,0x42,0x4A,0x25,0x95,0x98,0x4A,0x4A,0x31,0x96,0x54,0x62,0x2C,0x25,0xC5,0x5A,
|
||||
0x52,0xAA,0xB1,0xA5,0xD8,0x6A,0x8B,0x31,0xE7,0x50,0x4A,0x8C,0x25,0x95,0x18,0x4B,0x4A,0xB1,0xB6,0x98,0x72,0x6B,0x31,0xD6,0x1C,0x31,0x26,0x21,0x73,0x4E,0x4A,0xE6,
|
||||
0x9C,0x94,0x52,0x4A,0x6B,0xA5,0x94,0x16,0x2B,0xE7,0xA4,0x74,0x10,0x52,0xCA,0x1C,0x94,0x54,0x52,0x8A,0xB1,0x94,0x94,0x6A,0xE6,0x9C,0x94,0x0E,0x42,0x4A,0x1D,0x74,
|
||||
0x54,0x4A,0x4A,0x31,0x96,0x54,0x62,0x0A,0xA5,0xC4,0x58,0x52,0xAA,0xB1,0x94,0xD4,0x62,0x8C,0x31,0xD7,0x96,0x62,0xCB,0xA1,0xA4,0x18,0x4B,0x4A,0xB1,0x96,0x54,0x62,
|
||||
0x6C,0x31,0xE6,0xDC,0x62,0xCA,0xAD,0x93,0x12,0x5B,0x49,0x29,0xC6,0x50,0x52,0x8C,0x31,0xC6,0x9C,0x5B,0x8C,0x39,0x87,0x52,0x62,0x2C,0x29,0xC5,0x5A,0x52,0xAA,0x31,
|
||||
0xC6,0x5A,0x73,0x8C,0xB1,0xE6,0x50,0x4A,0x8C,0x25,0x95,0x1A,0x4B,0x4A,0xB1,0xC6,0x1A,0x73,0x6D,0x31,0xD6,0x9C,0x62,0xCC,0x35,0xA5,0x58,0x73,0xAB,0x31,0xE7,0xD8,
|
||||
0x72,0xEB,0xB5,0xE6,0xE0,0x53,0x6B,0x35,0xA7,0x98,0x72,0x6D,0x31,0xE6,0x5C,0x6B,0x0B,0xB2,0xE6,0x5C,0x7C,0x27,0x25,0xB6,0x50,0x4A,0x8C,0xA5,0xA4,0x18,0x5B,0x8C,
|
||||
0xB5,0xB6,0x18,0x73,0x0E,0xA5,0xC4,0x58,0x52,0xAA,0xB1,0x94,0x14,0x6B,0x8B,0x31,0xE8,0xD6,0x62,0xED,0xA1,0x94,0x18,0x4B,0x4A,0x31,0x96,0x54,0x6A,0x8C,0x31,0xD6,
|
||||
0x1C,0x6B,0xCC,0x39,0xC5,0x56,0x6B,0x8B,0xB1,0xD7,0xD4,0x62,0xCE,0x35,0xF7,0x60,0x6C,0xCB,0xB5,0xA7,0x16,0x6B,0x6E,0x31,0xE6,0x9E,0x62,0xCA,0xB5,0xF6,0xDA,0x83,
|
||||
0xCD,0xAD,0xB7,0x02,0x00,0x00,0x06,0x1C,0x00,0x00,0x02,0x4C,0x28,0x03,0x85,0x86,0xAC,0x04,0x00,0xA2,0x00,0x00,0x00,0x63,0x18,0x73,0x0E,0x42,0xA3,0x90,0x73,0xCE,
|
||||
0x49,0x69,0x90,0x72,0xCE,0x39,0x29,0x99,0x73,0x10,0x42,0x48,0x29,0x73,0x0E,0x42,0x08,0x29,0x75,0xCE,0x49,0x28,0xA9,0xB5,0xCE,0x39,0x08,0x29,0xB5,0x16,0x4A,0x49,
|
||||
0xA9,0xB5,0x18,0x43,0x29,0x29,0xB5,0x16,0x63,0x01,0x00,0x00,0x05,0x0E,0x00,0x00,0x01,0x36,0x68,0x4A,0x2C,0x0E,0x50,0x68,0xC8,0x4A,0x00,0x20,0x15,0x00,0xC0,0xE0,
|
||||
0x38,0x96,0xE5,0x79,0xA6,0x68,0x9A,0xB6,0xED,0x58,0x92,0xE7,0x89,0xA2,0x69,0xAA,0xAA,0x6D,0x3B,0x92,0xE5,0x79,0xA2,0x68,0x9A,0xAA,0x6A,0xDB,0x9A,0xE7,0x89,0xA2,
|
||||
0x69,0xAA,0xAA,0xEB,0xEA,0xBA,0xE6,0x79,0xA2,0x68,0x9A,0xAA,0xEA,0xBA,0xB6,0x2E,0x8A,0xA2,0x69,0xAA,0xAA,0xAB,0xBA,0xAE,0xEE,0x8B,0xA2,0x68,0x9A,0xAA,0xAA,0xAA,
|
||||
0xAE,0xAB,0xEB,0xA6,0x69,0xAA,0xAA,0xAB,0xBA,0xAE,0x2C,0xFB,0xBE,0x69,0x9A,0xAA,0xEA,0xBA,0xAE,0x2B,0xCB,0xBE,0xB0,0xAA,0xAE,0xEB,0xCA,0xB2,0x2D,0xDB,0xB6,0x31,
|
||||
0xAC,0xAA,0xEA,0xBA,0xAE,0x2B,0xDB,0xB6,0x6D,0x1C,0xB7,0x6D,0xEB,0xBA,0xEE,0xFB,0xBE,0x30,0x54,0x6E,0xDB,0xD6,0x75,0x5F,0xF8,0x85,0x61,0x58,0x0A,0x00,0x00,0x4F,
|
||||
0x70,0x00,0x00,0x2A,0xB0,0x61,0x75,0x84,0x93,0xA2,0xB1,0xC0,0x42,0x43,0x56,0x02,0x00,0x19,0x00,0x00,0x84,0x31,0x08,0x19,0x84,0x10,0x32,0x08,0x21,0x84,0x94,0x52,
|
||||
0x0A,0x29,0xA5,0x94,0x00,0x00,0x80,0x01,0x07,0x00,0x80,0x00,0x13,0xCA,0x40,0xA1,0x21,0x2B,0x02,0x80,0x38,0x01,0x00,0x00,0x21,0x4A,0x21,0xA5,0x94,0x52,0x4A,0x29,
|
||||
0xA5,0x94,0x52,0x4A,0x29,0xA5,0xD4,0x51,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x42,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,
|
||||
0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,
|
||||
0x29,0xA5,0x94,0x52,0x4A,0x1D,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,
|
||||
0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,
|
||||
0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x4A,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,
|
||||
0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,
|
||||
0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x2A,
|
||||
0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,
|
||||
0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,
|
||||
0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,
|
||||
0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,
|
||||
0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x00,0x80,
|
||||
0x54,0x84,0x03,0x80,0xD4,0x83,0x09,0x65,0xA0,0xD0,0x90,0x95,0x00,0x40,0x2A,0x00,0x00,0x60,0x8C,0x52,0x8C,0x39,0x07,0xA1,0x94,0x86,0x31,0xE7,0x9C,0x83,0x90,0x4A,
|
||||
0x4B,0x8D,0x62,0xCE,0x31,0x07,0xA1,0xA4,0x96,0x32,0xE7,0x20,0x94,0x92,0x52,0x4B,0x31,0x66,0xCE,0x41,0x29,0x25,0xA5,0xD6,0x5A,0xCC,0x9C,0x93,0xD2,0x5A,0x6C,0x3D,
|
||||
0xC6,0x9A,0x39,0x27,0xA9,0xB5,0xD8,0x62,0xAC,0xB5,0x83,0xD2,0x5A,0x8D,0x3D,0xF7,0xDE,0x73,0x27,0xA5,0xB5,0x1A,0x6B,0xEE,0x3D,0xF7,0x92,0x5A,0xAD,0xB5,0xF6,0xD8,
|
||||
0x73,0xEF,0x25,0xB5,0x18,0x73,0xAD,0xB9,0xF7,0x5A,0x63,0x8D,0xB9,0xF7,0x9E,0x73,0xEF,0xBD,0xA7,0x5C,0x7B,0xAF,0xB5,0xE7,0x5E,0x7B,0x2E,0x00,0x00,0xA7,0xC1,0x01,
|
||||
0x00,0xF4,0xC0,0x86,0xD5,0x11,0x4E,0x8A,0xC6,0x02,0x0B,0x0D,0x59,0x09,0x00,0xA4,0x02,0x00,0x10,0x08,0x29,0xC5,0x98,0x73,0xCE,0x39,0x87,0x90,0x62,0xCC,0x39,0xE7,
|
||||
0x20,0x84,0x10,0x21,0xC4,0x98,0x73,0xCE,0x41,0x08,0xA1,0x62,0x8C,0x39,0xE7,0x20,0x84,0x10,0x42,0xC5,0x98,0x63,0xCE,0x41,0x08,0x21,0x84,0xCE,0x39,0xE7,0x9C,0x83,
|
||||
0x10,0x42,0x08,0x9D,0x73,0xCE,0x39,0x07,0x21,0x84,0x10,0x3A,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x74,0x0E,0x42,0x08,0x1D,0x84,0x10,0x42,0xE8,0x20,0x84,0x10,0x42,
|
||||
0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0xA1,0x83,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x02,0x00,0x00,0x0B,
|
||||
0x1C,0x00,0x00,0x02,0x6C,0x58,0x1D,0xE1,0xA4,0x68,0x2C,0xB0,0xD0,0x90,0x95,0x00,0x00,0x10,0x00,0x00,0xC2,0xAC,0xE4,0x12,0x8A,0x24,0x90,0x72,0x0C,0x9A,0x69,0x8C,
|
||||
0x52,0x8E,0x9A,0x88,0x14,0x62,0x0A,0x9A,0xCA,0x10,0x43,0x4C,0x9A,0xA9,0x98,0x52,0xCA,0x81,0xE8,0x24,0x63,0x08,0x81,0x2A,0xCA,0xC6,0xD0,0x91,0x00,0x00,0x00,0x04,
|
||||
0x01,0x00,0x01,0x26,0x80,0xC0,0x00,0x41,0xC1,0x17,0x42,0x40,0x8C,0x01,0x00,0x08,0x42,0x64,0x86,0x48,0x28,0xAC,0x82,0x05,0x06,0x65,0xD0,0xE0,0x30,0x0F,0x00,0x1E,
|
||||
0x20,0x22,0x24,0x02,0x80,0xC4,0x04,0x45,0xDA,0xC5,0x05,0x74,0x19,0xE0,0x82,0x2E,0xEE,0x3A,0x10,0x42,0x10,0x82,0x10,0xC4,0xE2,0x00,0x0A,0x48,0xC0,0xC1,0x09,0x37,
|
||||
0x3C,0xF1,0x86,0x27,0xDC,0xE0,0x04,0x9D,0xA2,0x52,0x07,0x01,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x0F,0x00,0x00,0x07,0x05,0x10,0x11,0xD1,0x5C,0x85,0xC5,0x05,0x46,
|
||||
0x86,0xC6,0x06,0x47,0x87,0x47,0x00,0x00,0x00,0x00,0x00,0xB8,0x00,0xC0,0x07,0x00,0xC0,0xF1,0x01,0x44,0x44,0x34,0x57,0x61,0x71,0x81,0x91,0xA1,0xB1,0xC1,0xD1,0xE1,
|
||||
0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x04,
|
||||
};
|
||||
static const uint8_t vcb_2[] = {
|
||||
0x1F,0x42,0x43,0x56,0x01,0x00,0x00,0x01,0x00,0x9C,0x73,0x9A,0x31,0x87,0x99,0x62,0x94,0x52,0x89,0x21,0x94,0xDE,0x39,0x68,0x19,0x63,0x94,0x52,0x69,0x29,0xA5,0x5A,
|
||||
0x4A,0xA9,0xA1,0x83,0x16,0x6B,0xAB,0xBD,0xF7,0xDE,0x7B,0xEF,0xBD,0xF7,0xDE,0x7B,0xEF,0x1D,0x73,0x94,0x31,0x46,0x95,0x52,0x52,0x4A,0xA9,0x9D,0x73,0x96,0x31,0x47,
|
||||
0x15,0x63,0x52,0x4A,0x89,0xA5,0x94,0x56,0x42,0x68,0x21,0x84,0xD6,0x62,0xAB,0xBD,0xF7,0xDE,0x6B,0xEF,0xB5,0xF6,0xDE,0x7B,0xEF,0x99,0x42,0x4C,0x29,0xA4,0x14,0x42,
|
||||
0x08,0x4A,0x28,0x1D,0x53,0x8C,0x29,0xA4,0x94,0x42,0x4A,0x4A,0x08,0x25,0x64,0x0E,0x3A,0xC6,0x1C,0x53,0x8C,0x52,0x09,0x3D,0xD6,0x5E,0x6B,0xCC,0xBD,0xB6,0xD8,0x7B,
|
||||
0xED,0xA1,0x63,0xCE,0x39,0xE6,0x1C,0x53,0x4C,0x4A,0x68,0x21,0x74,0x0E,0x3A,0xE6,0x9C,0x53,0x4C,0x4A,0x68,0xA9,0x84,0x52,0x42,0x06,0xA1,0x53,0xD0,0x52,0x89,0xAD,
|
||||
0xF7,0xDE,0x62,0xEB,0xB9,0xA5,0xDA,0x7B,0xEF,0x81,0xD0,0x90,0x55,0x00,0x00,0x01,0x00,0xC0,0x40,0x10,0x1A,0xB2,0x0A,0x00,0x50,0x00,0x00,0x10,0x8A,0xA1,0x18,0x8A,
|
||||
0x02,0x84,0x86,0xAC,0x02,0x00,0x32,0x00,0x00,0x04,0xE0,0x28,0x8E,0xE3,0x38,0x8E,0xE2,0x38,0x92,0x62,0x39,0x16,0x10,0x1A,0xB2,0x0A,0x00,0x00,0x02,0x00,0x10,0x00,
|
||||
0x00,0xC0,0x90,0x0C,0x4B,0xB1,0x14,0xCD,0xD1,0x24,0x4D,0xD2,0x2C,0xCF,0x13,0x4D,0xD3,0x37,0x7D,0xD3,0x36,0x6D,0x55,0xD7,0x75,0x5D,0xD7,0x75,0x5D,0xD7,0x75,0x20,
|
||||
0x34,0x64,0x15,0x00,0x00,0x01,0x00,0x40,0x40,0xA7,0x19,0xA6,0x1A,0x20,0xC2,0x8C,0x64,0x16,0x08,0x0D,0x59,0x05,0x00,0x20,0x00,0x00,0x00,0x44,0x20,0xC3,0x14,0x03,
|
||||
0x42,0x43,0x56,0x01,0x00,0x00,0x01,0x00,0x00,0x52,0x24,0x39,0x49,0xA2,0xE4,0xA4,0x94,0x52,0x0E,0x83,0x64,0x31,0x49,0x2A,0xE5,0xA4,0x94,0x52,0x1E,0xC5,0xE4,0x51,
|
||||
0x4D,0x32,0x06,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x0A,0x83,0x64,0x39,0x4A,0x2A,0xE5,0xA4,0x94,0x52,0x12,0xA3,0x64,0x31,0x4A,0xAA,
|
||||
0xD4,0xA4,0x94,0x52,0x1E,0xE5,0xE4,0x49,0x4D,0x32,0xF6,0xA4,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x16,0xA4,0xE4,0x49,0x4B,0xBA,0x06,0xA5,
|
||||
0x94,0x52,0x92,0xA3,0xA4,0x41,0x4B,0x36,0xF5,0xA4,0x94,0x52,0xA2,0x14,0x25,0x4A,0x4E,0xB6,0x27,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,
|
||||
0x3E,0x28,0xE5,0x83,0x50,0x4A,0x29,0xA5,0x94,0x52,0xAE,0xF6,0xE4,0x5A,0x4F,0x4A,0x29,0xA5,0x94,0x52,0xC6,0x28,0x25,0x7C,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,
|
||||
0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x32,0x82,0xD0,0x90,0x55,0x00,0x00,0x10,0x00,0x00,0x60,0x9C,0x35,0xCA,0xA1,0xE8,0x24,0x3A,0x5F,0x9C,0xA1,0x9C,0x69,0x0A,0x92,
|
||||
0x0A,0xA5,0x09,0xDD,0x9B,0xE4,0x28,0x79,0x4E,0x72,0x2B,0x2D,0x37,0xA7,0x9B,0x70,0xCE,0xE9,0xE6,0x94,0x73,0x3E,0x39,0xE7,0x9C,0x20,0x34,0x64,0x15,0x00,0x00,0x08,
|
||||
0x00,0x00,0x21,0x84,0x14,0x52,0x48,0x21,0x85,0x14,0x52,0x48,0x21,0x85,0x14,0x62,0x88,0x21,0x86,0x1C,0x72,0xCA,0x29,0xA8,0xA0,0x82,0x4A,0x2A,0xA9,0xA8,0xA2,0x8A,
|
||||
0x2A,0xAB,0x2C,0xB3,0xCC,0x32,0xCB,0x2C,0xB3,0xCC,0x32,0xCB,0x2C,0xB3,0xCC,0x3A,0xEB,0xA8,0xA3,0xCE,0x42,0x0A,0xA1,0xA4,0xD0,0x42,0x6B,0x35,0xC6,0x1A,0x63,0x6C,
|
||||
0xB5,0x37,0x27,0x6D,0xCD,0x51,0x4A,0x27,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x73,0xCE,0x39,0x27,0x08,0x0D,0x59,0x05,0x00,0x80,0x00,0x00,0x10,0x08,0x19,0x64,0x90,0x41,
|
||||
0x46,0x19,0x85,0x14,0x62,0x88,0x29,0xA7,0x9C,0x72,0x0A,0x2A,0xA9,0xA4,0x02,0x42,0x43,0x56,0x01,0x00,0x80,0x00,0x00,0x02,0x00,0x00,0x00,0x44,0xC9,0x74,0x4C,0x47,
|
||||
0x74,0x44,0x45,0x74,0x44,0x47,0x74,0x44,0x47,0x74,0x44,0xC7,0x73,0x3C,0xC7,0x93,0x44,0x49,0xB4,0x3C,0x4B,0xD4,0x4C,0xCF,0x14,0x4D,0xD3,0x74,0x55,0xD9,0x95,0x65,
|
||||
0x5D,0xB6,0x65,0xDB,0xD5,0x65,0xDD,0xD6,0x65,0xDF,0xF6,0x6D,0xDD,0xB6,0x6D,0x5F,0x37,0x76,0xE3,0x37,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,
|
||||
0x8E,0xE3,0x18,0x82,0xD0,0x90,0x55,0x00,0x00,0x08,0x00,0x00,0x80,0x10,0x42,0x08,0x21,0x85,0x14,0x52,0x48,0x21,0xA5,0x98,0x62,0xCC,0x39,0xE8,0x20,0x84,0x50,0x4A,
|
||||
0x20,0x34,0x64,0x15,0x00,0x00,0x08,0x00,0x20,0x00,0x00,0x00,0x40,0x51,0x1C,0xC5,0x71,0x24,0x47,0x92,0x24,0xC9,0x92,0x2C,0x4B,0xB3,0x34,0x4D,0xD3,0x34,0xCD,0x13,
|
||||
0x3D,0xD1,0x33,0x3D,0xD5,0x73,0x45,0x59,0xB4,0x45,0xDB,0x73,0x3D,0x5B,0xB4,0x3D,0xD7,0x53,0x3D,0xD5,0x53,0x45,0xD5,0x54,0x4D,0xD7,0x74,0x55,0xD7,0x75,0x5D,0x57,
|
||||
0x75,0x55,0x59,0x95,0x5D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0x19,0x08,0x0D,0x59,0x05,0x00,0x48,0x00,0x00,0xE8,0x48,0x8E,
|
||||
0xA4,0x48,0x8A,0xA4,0x48,0x8E,0xE3,0x48,0x8E,0x24,0x01,0xA1,0x21,0xAB,0x00,0x00,0x19,0x00,0x00,0x01,0x00,0x28,0x8A,0xA2,0x38,0x8E,0x23,0x39,0x96,0x64,0x49,0x9A,
|
||||
0x24,0x4A,0xA6,0xA5,0x5A,0xAE,0x26,0x7B,0xBA,0xA7,0x8B,0xBA,0xA8,0x03,0xA1,0x21,0xAB,0x00,0x00,0x40,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x18,0xA2,0x21,0x1A,
|
||||
0xA2,0x23,0x5A,0xA2,0x26,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,
|
||||
0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0xE7,0x79,0x9E,0xE7,0x79,0x9E,0xE7,0x79,0x1E,0x10,0x1A,0xB2,0x0A,0x00,0x90,0x00,0x00,0xD0,
|
||||
0x91,0x1C,0xC9,0xB1,0x14,0x4B,0x91,0x14,0x49,0xB1,0x1C,0xCB,0x01,0x42,0x43,0x56,0x01,0x00,0x32,0x00,0x00,0x02,0x00,0x70,0x0C,0xC7,0x90,0x14,0xC9,0xB1,0x2C,0xCB,
|
||||
0xD2,0x34,0xCD,0xF3,0x3C,0xCF,0x13,0x3D,0x51,0x14,0x45,0xD1,0x34,0x55,0x53,0x05,0x42,0x43,0x56,0x01,0x00,0x80,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x50,0x14,
|
||||
0xC5,0x72,0x2C,0x47,0x92,0x34,0xC7,0x93,0x44,0x47,0x94,0x44,0x49,0xB4,0x44,0x49,0xD4,0x44,0x4D,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,
|
||||
0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x20,0x34,0x64,0x25,0x00,0x00,0x04,
|
||||
0x00,0x80,0x59,0xAB,0x3D,0xB6,0x5C,0x41,0x89,0x29,0xB5,0xD6,0x20,0xE4,0x10,0x83,0x56,0x31,0x27,0x1D,0xA4,0x1E,0x21,0xC3,0x0C,0x62,0x5C,0x21,0xE4,0x10,0x52,0xDC,
|
||||
0x31,0xC3,0x88,0x41,0x9E,0x53,0xE5,0x90,0x72,0x1E,0x08,0x0D,0x59,0x11,0x00,0x44,0x01,0x00,0x00,0xC6,0x20,0xC7,0x10,0x73,0xC8,0x39,0x47,0xA9,0x93,0x14,0x39,0xE7,
|
||||
0xA8,0x74,0x94,0x1A,0xE7,0x1C,0xA5,0x8E,0x52,0x47,0x29,0xC5,0x9A,0x62,0xED,0x28,0x95,0x9A,0x52,0xAC,0x8D,0x73,0x8E,0x52,0x47,0x29,0xA3,0x94,0x6A,0x2C,0x2D,0x76,
|
||||
0x94,0x52,0xAD,0xA9,0xC6,0x02,0x00,0x00,0x02,0x1C,0x00,0x00,0x02,0x2C,0x84,0x42,0x43,0x56,0x04,0x00,0x51,0x00,0x00,0x04,0x42,0x48,0x29,0xA4,0x14,0x52,0x8A,0x39,
|
||||
0xA7,0x98,0x43,0x4A,0x29,0xC7,0x98,0x73,0x48,0x29,0xE6,0x9C,0x72,0x8E,0x39,0xE7,0xA0,0x74,0x10,0x2A,0xE7,0x18,0x74,0x0E,0x4A,0xA4,0x94,0x72,0x8E,0x39,0xA7,0x9C,
|
||||
0x73,0x12,0x32,0x07,0x99,0x73,0x0E,0x42,0x27,0xA1,0x00,0x00,0x80,0x00,0x07,0x00,0x80,0x00,0x0B,0xA1,0xD0,0x90,0x15,0x01,0x40,0x9C,0x00,0x80,0x43,0x72,0x34,0x4D,
|
||||
0xD2,0x34,0xD1,0x93,0x34,0xCD,0x13,0x3D,0x51,0x54,0x55,0x4F,0x14,0x55,0x55,0xD2,0x34,0xD3,0xD4,0x44,0x51,0x35,0x35,0x51,0x34,0x4D,0x51,0x35,0x65,0x57,0x34,0x4D,
|
||||
0x57,0x96,0x34,0xCD,0x14,0x35,0x51,0x54,0x4D,0x4D,0x14,0x4D,0x55,0x34,0x4D,0xD7,0x35,0x4D,0xD5,0x95,0x3D,0xD3,0xB4,0x65,0x51,0x55,0x75,0x59,0x54,0x55,0x5D,0x76,
|
||||
0x6D,0xD7,0xB7,0x5D,0xD9,0xD5,0x6D,0xCF,0x34,0x65,0x5B,0x54,0x55,0xD9,0x36,0x55,0x55,0xD6,0x5D,0x57,0xB6,0x75,0x57,0xB6,0x6D,0x5F,0xD2,0x34,0xD3,0xD4,0x44,0x51,
|
||||
0x55,0x35,0x51,0x54,0x5D,0x53,0x55,0x6D,0xDB,0x54,0x55,0xDB,0xD6,0x44,0xD1,0x75,0x45,0x55,0x95,0x5D,0x51,0x55,0x65,0xD9,0x75,0x5D,0xDB,0x56,0x5D,0x59,0xD7,0x35,
|
||||
0x51,0x74,0x55,0x51,0x35,0x5D,0x57,0x54,0x55,0x57,0x56,0x5D,0xD5,0xB6,0x55,0xD7,0xD5,0x7D,0x51,0x55,0x75,0x5D,0x75,0x5D,0x5F,0x37,0x5D,0xD7,0xD7,0x6D,0x5D,0x17,
|
||||
0x7E,0xD9,0xB6,0x85,0x61,0x54,0x55,0x5B,0x37,0x5D,0x55,0xD7,0x4D,0xD7,0xD5,0x85,0xD9,0x96,0x7D,0x5D,0xB6,0x75,0x61,0x98,0x34,0xCD,0x34,0x35,0x51,0x74,0x55,0x4D,
|
||||
0x14,0x55,0xD7,0x54,0x55,0xDB,0x36,0x55,0x55,0xB6,0x35,0x51,0x54,0x5D,0x51,0x55,0x65,0x59,0x34,0x55,0xD7,0x55,0x5D,0x57,0xD7,0x55,0xD7,0x95,0x6D,0xCD,0x14,0x5D,
|
||||
0x57,0x54,0x55,0x59,0x16,0x55,0xD5,0x75,0x55,0xD7,0xF5,0x75,0xD5,0x75,0x6D,0x5B,0x54,0x55,0xDD,0x36,0x5D,0xD7,0xD7,0x4D,0xD5,0xD5,0x75,0xD9,0xB6,0x85,0x63,0x96,
|
||||
0x6D,0xDD,0x17,0x55,0x55,0xF7,0x4D,0xD7,0xD5,0x75,0xD5,0x75,0x6D,0x61,0xB6,0x6D,0x61,0xB8,0x6D,0xDB,0x37,0x36,0xD3,0xB4,0x75,0xD3,0x75,0x7D,0xDD,0x54,0x5D,0xDF,
|
||||
0xB7,0x7D,0xDD,0x18,0x66,0xDD,0x16,0x96,0x51,0x75,0x7D,0x5D,0x95,0x65,0xE1,0x37,0x65,0xD9,0xF7,0x75,0xDF,0x17,0x96,0x59,0xD7,0x85,0xE1,0x53,0x55,0x5D,0x37,0x65,
|
||||
0xD5,0xF7,0x4D,0x59,0xF6,0x85,0xDB,0xD7,0x8D,0x65,0xD6,0x75,0x61,0x78,0x6D,0xDB,0x38,0x66,0x5B,0x37,0x96,0xD7,0xD6,0x85,0xE3,0x37,0x8E,0xA5,0xAD,0xFB,0xC6,0xB1,
|
||||
0xDA,0xB2,0x70,0xBC,0xBE,0xAD,0x2C,0xAF,0x6E,0x33,0x76,0xE1,0x37,0x86,0x5B,0xF8,0x8D,0x63,0x33,0x4D,0xDD,0x36,0x5D,0xD5,0xF7,0x4D,0xD5,0xF5,0x7D,0x59,0xB7,0x95,
|
||||
0xE3,0xD6,0x7D,0xE3,0xF8,0x54,0x55,0xD7,0x4D,0xD9,0x15,0x7E,0xD3,0x95,0x7D,0xE1,0xB6,0x75,0xE5,0xB8,0x75,0xDF,0x28,0xAA,0xAA,0xAF,0xAB,0xB2,0xAB,0xFB,0xAA,0x2C,
|
||||
0xFB,0xBE,0xAD,0xDB,0x84,0xDD,0xF7,0x95,0x63,0xB5,0x6D,0x63,0x78,0x6D,0x5D,0x18,0x5E,0x59,0x27,0xDC,0xBA,0x6F,0x0C,0xBF,0x70,0x0C,0xCB,0x6A,0xCB,0xC2,0xF2,0xEA,
|
||||
0xB6,0xB1,0xCC,0xBE,0x4D,0xB9,0x85,0x9D,0xB1,0x1B,0x3F,0x02,0x00,0x00,0x06,0x1C,0x00,0x00,0x02,0x4C,0x28,0x03,0x85,0x86,0xAC,0x08,0x00,0xE2,0x04,0x00,0x18,0x84,
|
||||
0x9C,0x53,0x4C,0x41,0xA8,0x14,0x83,0x10,0x42,0x48,0x29,0x84,0x90,0x52,0xC5,0x18,0x84,0xCC,0x39,0x29,0x15,0x73,0x50,0x4A,0x29,0xA9,0x85,0x50,0x52,0xAB,0x18,0x83,
|
||||
0x50,0x39,0x26,0x21,0x73,0x4E,0x4A,0x28,0xA1,0xA5,0x52,0x4A,0x4B,0xA1,0x94,0xD6,0x4A,0x29,0xB1,0x85,0x52,0x5A,0x6B,0xAD,0xD5,0x9A,0x5A,0x8B,0x35,0x94,0xD2,0x5A,
|
||||
0x28,0x25,0xB6,0x52,0x4A,0x8B,0xAD,0xB5,0x1A,0x5B,0x6B,0xB5,0x46,0x8C,0x41,0xC8,0x1C,0x93,0x92,0x31,0x27,0xA5,0x94,0xD2,0x5A,0x29,0xA5,0xB5,0xCC,0x39,0x29,0x9D,
|
||||
0x83,0x92,0x3A,0xE7,0x28,0x95,0x92,0x52,0x2C,0x29,0xB5,0x58,0x31,0x26,0x25,0x73,0x8E,0x4A,0xE7,0x20,0xA5,0x92,0x4A,0x4C,0x25,0xA5,0xD8,0x4A,0x2A,0xB1,0x95,0x92,
|
||||
0x62,0x2C,0x29,0xC5,0xD8,0x52,0x6C,0xB5,0xC5,0x98,0x73,0x28,0xA5,0xC5,0x92,0x4A,0x8C,0x25,0xA5,0x58,0x5B,0x4C,0xB5,0xB5,0x18,0x6B,0x8E,0x18,0x83,0x92,0x39,0x26,
|
||||
0x25,0x63,0x4E,0x4A,0x29,0xA5,0xB5,0x52,0x4A,0x6B,0x15,0x63,0x52,0x3A,0xE8,0x28,0x65,0xCE,0x49,0x2A,0x29,0xB5,0x58,0x4A,0x4A,0x31,0x73,0x4E,0x4A,0xE7,0x1C,0xA5,
|
||||
0x0E,0x3A,0x2A,0x25,0x95,0xD8,0x4A,0x2A,0xB1,0x85,0x52,0x62,0x2B,0x29,0xC5,0x18,0x4A,0x69,0x31,0xC6,0x98,0x6B,0x4B,0xB1,0xE5,0x52,0x52,0x8B,0x25,0xA5,0x18,0x4B,
|
||||
0x2A,0x31,0xB6,0x18,0x73,0x6E,0x31,0xD5,0xD6,0x49,0x68,0x2D,0x94,0x12,0x63,0x28,0x25,0xC6,0x18,0x63,0xCD,0xAD,0xB5,0x5A,0x43,0x29,0xB1,0x95,0x94,0x62,0x2C,0x29,
|
||||
0xC5,0x16,0x63,0xAD,0xBD,0xC5,0x98,0x6B,0x28,0x25,0xC6,0x92,0x4A,0x8C,0x25,0xA5,0x18,0x63,0x6D,0xB9,0xB6,0x18,0x6B,0x6E,0xAD,0xD5,0x9A,0x5A,0xAB,0xB9,0xC5,0x98,
|
||||
0x6B,0x6D,0xB9,0xF5,0x5A,0x73,0xF0,0xA9,0xB5,0x5A,0x53,0x4B,0xB9,0xB6,0x18,0x73,0x8E,0xB5,0xF5,0x58,0x6B,0x0E,0xBE,0x93,0xD2,0x5A,0x28,0x25,0xB6,0x52,0x4A,0x8C,
|
||||
0x2D,0xB6,0x5A,0x5B,0x8C,0xB9,0x86,0x52,0x62,0x2C,0x29,0xC5,0x58,0x4A,0x6A,0x31,0xC6,0x98,0x73,0x6B,0xB1,0xE6,0x50,0x4A,0x8B,0x25,0xA5,0x16,0x4B,0x2A,0x31,0xB6,
|
||||
0x18,0x6B,0x8E,0x35,0xE6,0x9A,0x5A,0xCB,0xB5,0xC5,0x98,0x6B,0x6A,0xAD,0xE6,0x5A,0x6B,0xD0,0xB1,0xE5,0xD8,0x5B,0x6B,0x35,0xB7,0x18,0x6B,0x4E,0xAD,0xE5,0x5A,0x73,
|
||||
0xED,0x41,0xE6,0xD6,0x5B,0x01,0x00,0x00,0x03,0x0E,0x00,0x00,0x01,0x26,0x94,0x81,0x42,0x43,0x56,0x02,0x00,0x51,0x00,0x00,0x80,0x31,0x8C,0x39,0x27,0xA5,0x51,0xC8,
|
||||
0x39,0xE7,0xA4,0x34,0x48,0x39,0xE7,0x9C,0x94,0xCC,0x31,0x08,0x21,0xA4,0x94,0x39,0x07,0x21,0x84,0x94,0x3A,0xE7,0x20,0x94,0xD4,0x5A,0xE7,0x20,0x84,0x52,0x5A,0x2B,
|
||||
0xA5,0xA4,0xD4,0x5A,0x8C,0xA5,0x94,0x94,0x5A,0x8B,0xB1,0x00,0x00,0x80,0x02,0x07,0x00,0x80,0x00,0x1B,0x34,0x25,0x16,0x07,0x28,0x34,0x64,0x25,0x00,0x90,0x0A,0x00,
|
||||
0x60,0x70,0x1C,0x4D,0x13,0x3D,0x53,0x54,0x4D,0x5B,0x76,0x24,0xC9,0xF3,0x44,0x51,0x55,0x55,0xD5,0xB6,0x1D,0x49,0xF2,0x3C,0x51,0x34,0x55,0x55,0xB5,0x6D,0xCD,0xF3,
|
||||
0x44,0x51,0x35,0x55,0xD5,0x75,0x7D,0x5D,0xF3,0x3C,0x51,0x34,0x55,0x55,0x75,0x5D,0x5D,0x17,0x4D,0x53,0x55,0x55,0xD5,0x75,0x65,0xD9,0xF7,0x45,0xD3,0x54,0x55,0x55,
|
||||
0x75,0x5D,0x57,0xF6,0x75,0x53,0x55,0x55,0xD5,0x75,0x65,0x59,0x96,0x7D,0xE1,0x54,0x55,0x55,0x75,0x5D,0xD7,0x95,0x6D,0xDF,0x57,0x5D,0xD7,0x75,0x65,0xD9,0xB6,0x6D,
|
||||
0xDD,0x18,0x56,0xD7,0x75,0x5D,0x59,0x96,0x6D,0x5B,0x37,0x8E,0xDD,0xD6,0x75,0xDD,0xF7,0x85,0xE1,0x18,0x9E,0xE7,0xD6,0x75,0x5D,0xF7,0x85,0xE1,0x37,0x2A,0x05,0x00,
|
||||
0x80,0x27,0x38,0x00,0x00,0x15,0xD8,0xB0,0x3A,0xC2,0x49,0xD1,0x58,0x60,0xA1,0x21,0x2B,0x01,0x80,0x0C,0x00,0x00,0xC2,0x18,0x84,0x0C,0x42,0x0A,0x19,0x84,0x90,0x42,
|
||||
0x0A,0x29,0x85,0x90,0x52,0x4A,0x00,0x00,0xC0,0x80,0x03,0x00,0x40,0x80,0x09,0x65,0xA0,0xD0,0x90,0x95,0x00,0x40,0x0C,0x00,0x00,0x40,0x08,0x84,0x10,0x22,0xC6,0x20,
|
||||
0x84,0x10,0x29,0xE5,0x9C,0x73,0xCE,0x39,0xE7,0x9C,0x73,0xCE,0x39,0xE7,0x9C,0x73,0xCE,0x39,0xE7,0x9C,0x73,0xCE,0x39,0x27,0x00,0x60,0x3F,0xC2,0x01,0x40,0xEA,0xC1,
|
||||
0xC4,0xC4,0x14,0x16,0x1A,0xB2,0x12,0x00,0x48,0x05,0x00,0x00,0x8C,0x51,0x4A,0x31,0xE7,0x20,0xA4,0xD2,0x30,0xE6,0x9C,0x73,0x10,0x52,0x69,0xA9,0x51,0xCC,0x39,0xE7,
|
||||
0xA4,0x94,0xD4,0x52,0xE6,0x1C,0x84,0x52,0x52,0x6A,0x2D,0xC6,0xCC,0x39,0x08,0xA5,0xA4,0xD4,0x5A,0x8C,0x99,0x73,0x52,0x62,0x8B,0xB1,0xC7,0x58,0x33,0xE7,0x24,0xB5,
|
||||
0x16,0x63,0xAD,0xB5,0x76,0x52,0x62,0x8B,0xB1,0xD7,0x9C,0x7B,0xEE,0x24,0xB5,0x18,0x63,0xEC,0xB9,0xF7,0x5A,0x5A,0xAC,0x39,0xD7,0x5A,0x73,0xCF,0xBD,0xA4,0x16,0x63,
|
||||
0xCE,0xBD,0xF7,0xDA,0x7B,0x8B,0x31,0xD7,0x5C,0x73,0xAE,0xB9,0xF7,0x54,0x6B,0xAE,0x3D,0xF7,0x9A,0x7B,0xCD,0x05,0x00,0xE0,0x34,0x38,0x00,0x80,0x1E,0xD8,0xB0,0x3A,
|
||||
0xC2,0x49,0xD1,0x58,0x60,0xA1,0x21,0x2B,0x01,0x80,0x54,0x00,0x00,0x02,0x21,0xA5,0x18,0x73,0xCE,0x39,0xE7,0x90,0x52,0x8A,0x39,0xE6,0x9C,0x83,0x10,0x22,0xA5,0x18,
|
||||
0x73,0xCE,0x39,0xE7,0x1C,0x54,0x8C,0x31,0xE6,0x9C,0x83,0x10,0x42,0xA8,0x18,0x63,0xCC,0x39,0x08,0x21,0x84,0x90,0x39,0xE7,0x9C,0x73,0xD0,0x41,0x08,0x21,0x73,0xCE,
|
||||
0x39,0xE7,0x20,0x84,0x10,0x42,0xE7,0x20,0x84,0x0E,0x42,0x08,0x21,0x84,0xCE,0x39,0x08,0xA1,0x83,0x10,0x42,0x08,0x1D,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x3A,0x08,
|
||||
0x21,0x84,0x10,0x42,0x08,0x21,0x74,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x50,0x00,0x00,0x60,0x81,0x03,0x00,0x40,0x80,0x0D,
|
||||
0xAB,0x23,0x9C,0x14,0x8D,0x05,0x16,0x1A,0xB2,0x12,0x00,0x00,0x02,0x00,0x60,0x1C,0xA6,0x9A,0x4A,0xAD,0x08,0x52,0x8E,0x41,0x6D,0x0D,0x51,0x88,0x49,0x51,0x95,0x52,
|
||||
0x4A,0x39,0x8F,0x99,0x51,0x46,0x41,0x52,0x95,0x42,0x08,0x31,0x2F,0x1D,0x64,0x50,0x19,0x4B,0xBD,0x28,0x63,0x32,0x0A,0x00,0x00,0x80,0x20,0x00,0x20,0xC0,0x04,0x10,
|
||||
0x18,0x20,0x28,0xF8,0x42,0x08,0x88,0x31,0x00,0x00,0x41,0x88,0xCC,0x10,0x09,0x85,0x55,0xB0,0xC0,0xA0,0x0C,0x1A,0x1C,0xE6,0x01,0xC0,0x03,0x44,0x84,0x44,0x00,0x90,
|
||||
0x98,0xA0,0x48,0xBB,0xB8,0x80,0x2E,0x03,0x5C,0xD0,0xC5,0x5D,0x07,0x42,0x08,0x42,0x10,0x82,0x58,0x1C,0x40,0x01,0x09,0x38,0x38,0xE1,0x86,0x27,0xDE,0xF0,0x84,0x1B,
|
||||
0x9C,0xA0,0x53,0x54,0xEA,0x20,0x00,0x00,0x00,0x00,0x00,0x0C,0x00,0xE0,0x01,0x00,0xE0,0xA0,0x00,0x22,0x22,0x9A,0xAB,0xB0,0xB8,0xC0,0xC8,0xD0,0xD8,0xE0,0xE8,0xF0,
|
||||
0x08,0x00,0x00,0x00,0x00,0x00,0x18,0x00,0xF8,0x00,0x00,0x38,0x3E,0x80,0x88,0x88,0xE6,0x2A,0x2C,0x2E,0x30,0x32,0x34,0x36,0x38,0x3A,0x3C,0x02,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x80,0x80,0x80,0x00,0x00,0x00,0x00,0x00,0x40,0x00,0x00,0x00,0x80,0x80,
|
||||
};
|
||||
static const uint8_t vcb_3[] = {
|
||||
0x24,0x42,0x43,0x56,0x01,0x00,0x40,0x00,0x00,0x18,0x42,0x10,0x2A,0x05,0xAD,0x63,0x8E,0x3A,0xC8,0x15,0x21,0x8C,0x19,0xA2,0xA0,0x42,0xCA,0x29,0xC7,0x1D,0x42,0xD0,
|
||||
0x21,0xA3,0x24,0x43,0x88,0x3A,0xC6,0x35,0xC7,0x18,0x63,0x47,0xB9,0x64,0x8A,0x42,0xC9,0x81,0xD0,0x90,0x55,0x00,0x00,0x40,0x00,0x00,0xA4,0x1C,0x57,0x50,0x72,0x49,
|
||||
0x2D,0xE7,0x9C,0x73,0xA3,0x18,0x57,0xCC,0x71,0xE8,0x20,0xE7,0x9C,0x73,0xE5,0x20,0x67,0xCC,0x71,0x09,0x25,0xE7,0x9C,0x73,0x8E,0x39,0xE7,0x92,0x72,0x8E,0x31,0xE7,
|
||||
0x9C,0x73,0xA3,0x18,0x57,0x0E,0x72,0x29,0x2D,0xE7,0x9C,0x73,0x81,0x14,0x47,0x8A,0x71,0xA7,0x18,0xE7,0x9C,0x73,0xA4,0x1C,0x47,0x8A,0x71,0xA8,0x18,0xE7,0x9C,0x73,
|
||||
0x6D,0x31,0xB7,0x92,0x72,0xCE,0x39,0xE7,0x9C,0x73,0xE6,0x20,0x87,0x52,0x72,0xAE,0x35,0xE7,0x9C,0x73,0xA4,0x18,0x67,0x0E,0x72,0x0B,0x25,0xE7,0x9C,0x73,0xC6,0x20,
|
||||
0x67,0xCC,0x71,0xEB,0x20,0xE7,0x9C,0x73,0x8C,0x35,0xB7,0xD4,0x72,0xCE,0x39,0xE7,0x9C,0x73,0xCE,0x39,0xE7,0x9C,0x73,0xCE,0x39,0xE7,0x9C,0x73,0x8C,0x31,0xE7,0x9C,
|
||||
0x73,0xCE,0x39,0xE7,0x9C,0x73,0x6E,0x31,0xE7,0x16,0x73,0xAE,0x39,0xE7,0x9C,0x73,0xCE,0x39,0xE7,0x1C,0x73,0xCE,0x39,0xE7,0x9C,0x73,0x20,0x34,0x64,0x15,0x00,0x90,
|
||||
0x00,0x00,0xA0,0xA1,0x28,0x8A,0xE2,0x28,0x0E,0x10,0x1A,0xB2,0x0A,0x00,0xC8,0x00,0x00,0x10,0x40,0x71,0x14,0x47,0x91,0x14,0x4B,0xB1,0x1C,0xCB,0xD1,0x24,0x0D,0x08,
|
||||
0x0D,0x59,0x05,0x00,0x00,0x01,0x00,0x08,0x00,0x00,0xA0,0x48,0x86,0xA4,0x48,0x8A,0xA5,0x58,0x8E,0x66,0x69,0x9E,0x26,0x7A,0xA2,0x28,0x9A,0xA2,0x2A,0xAB,0xB2,0x69,
|
||||
0xCA,0xB2,0x2C,0xCB,0xB2,0xEB,0xBA,0x2E,0x10,0x1A,0xB2,0x0A,0x00,0x48,0x00,0x00,0x50,0x51,0x14,0xC5,0x70,0x14,0x07,0x08,0x0D,0x59,0x05,0x00,0x64,0x00,0x00,0x08,
|
||||
0x60,0x28,0x8A,0xA3,0x38,0x8E,0xE4,0x58,0x92,0xA5,0x59,0x9E,0x07,0x84,0x86,0xAC,0x02,0x00,0x80,0x00,0x00,0x04,0x00,0x00,0x50,0x0C,0x47,0xB1,0x14,0x4D,0xF1,0x24,
|
||||
0xCF,0xF2,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0x0D,0x08,0x0D,0x59,0x05,0x00,0x20,0x00,0x00,0x00,0x82,
|
||||
0x28,0x64,0x18,0x03,0x42,0x43,0x56,0x01,0x00,0x40,0x00,0x00,0x08,0x21,0x1A,0x19,0x43,0x9D,0x52,0x12,0x5C,0x0A,0x16,0x42,0x1C,0x11,0x43,0x1D,0x42,0xCE,0x43,0xA9,
|
||||
0xA5,0x83,0xE0,0x29,0x85,0x25,0x63,0xD2,0x53,0xAC,0x41,0x08,0x21,0x7C,0xEF,0x3D,0xF7,0xDE,0x7B,0xEF,0x81,0xD0,0x90,0x55,0x00,0x00,0x10,0x00,0x00,0x61,0x14,0x38,
|
||||
0x88,0x81,0xC7,0x24,0x08,0x21,0x84,0x62,0x14,0x27,0x44,0x71,0xA6,0x20,0x08,0x21,0x84,0xE5,0x24,0x58,0xCA,0x79,0xE8,0x24,0x08,0xDD,0x83,0x10,0x42,0xB8,0x9C,0x7B,
|
||||
0xCB,0xB9,0xF7,0xDE,0x7B,0x20,0x34,0x64,0x15,0x00,0x00,0x08,0x00,0xC0,0x20,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x29,0xA4,0x94,0x52,0x48,0x29,0xA6,0x98,
|
||||
0x62,0x8A,0x29,0xC7,0x1C,0x73,0xCC,0x31,0xC7,0x20,0x83,0x0C,0x32,0xE8,0xA0,0x93,0x4E,0x3A,0xC9,0xA4,0x92,0x4E,0x3A,0xCA,0x24,0xA3,0x8E,0x52,0x6B,0x29,0xB5,0x14,
|
||||
0x53,0x4C,0xB1,0xE5,0x16,0x63,0xAD,0xB5,0xD6,0x9C,0x73,0xAF,0x41,0x29,0x63,0x8C,0x31,0xC6,0x18,0x63,0x8C,0x31,0xC6,0x18,0x63,0x8C,0x31,0xC6,0x18,0x23,0x08,0x0D,
|
||||
0x59,0x05,0x00,0x80,0x00,0x00,0x10,0x06,0x19,0x64,0x90,0x41,0x08,0x21,0x84,0x14,0x52,0x48,0x29,0xA6,0x98,0x72,0xCC,0x31,0xC7,0x1C,0x03,0x42,0x43,0x56,0x01,0x00,
|
||||
0x80,0x00,0x00,0x02,0x00,0x00,0x00,0x1C,0x45,0x52,0x24,0x47,0x72,0x24,0x47,0x92,0x24,0xC9,0x92,0x2C,0x49,0x93,0x3C,0xCB,0xB3,0x3C,0xCB,0xB3,0x3C,0x4D,0xD4,0x44,
|
||||
0x4D,0x15,0x55,0xD5,0x55,0x6D,0xD7,0xF6,0x6D,0x5F,0xF6,0x6D,0xDF,0xD5,0x65,0xDF,0xF6,0x65,0xDB,0xD5,0x65,0x5D,0x96,0x65,0xDD,0xB5,0x6D,0x5D,0xD6,0x5D,0x5D,0xD7,
|
||||
0x75,0x5D,0xD7,0x75,0x5D,0xD7,0x75,0x5D,0xD7,0x75,0x5D,0xD7,0x75,0x5D,0xD7,0x81,0xD0,0x90,0x55,0x00,0x80,0x04,0x00,0x80,0x8E,0xE4,0x38,0x8E,0xE4,0x38,0x8E,0xE4,
|
||||
0x48,0x8E,0xA4,0x48,0x0A,0x10,0x1A,0xB2,0x0A,0x00,0x90,0x01,0x00,0x10,0x00,0x80,0xA3,0x38,0x8A,0xE3,0x48,0x8E,0xE4,0x58,0x8E,0x25,0x59,0x92,0x26,0x69,0x96,0x67,
|
||||
0x79,0x96,0xA7,0x79,0x9A,0xA8,0x89,0x1E,0x10,0x1A,0xB2,0x0A,0x00,0x00,0x04,0x00,0x10,0x00,0x00,0x00,0x00,0x00,0x80,0xA2,0x28,0x8A,0xA3,0x38,0x8E,0x24,0x59,0x96,
|
||||
0xA6,0x69,0x9E,0xA7,0x7A,0xA2,0x28,0x9A,0xAA,0xAA,0x8A,0xA6,0xA9,0xAA,0xAA,0x6A,0x9A,0xA6,0x69,0x9A,0xA6,0x69,0x9A,0xA6,0x69,0x9A,0xA6,0x69,0x9A,0xA6,0x69,0x9A,
|
||||
0xA6,0x69,0x9A,0xA6,0x69,0x9A,0xA6,0x69,0x9A,0xA6,0x69,0x9A,0xA6,0x69,0x9A,0xA6,0x69,0x02,0xA1,0x21,0xAB,0x00,0x00,0x09,0x00,0x00,0x1D,0xC7,0x71,0x1C,0x47,0x71,
|
||||
0x1C,0xC7,0x71,0x24,0x47,0x92,0x24,0x20,0x34,0x64,0x15,0x00,0x20,0x03,0x00,0x20,0x00,0x00,0x43,0x51,0x1C,0x45,0x72,0x2C,0xC7,0x92,0x34,0x4B,0xB3,0x3C,0xCB,0xD3,
|
||||
0x44,0xCF,0xF4,0x5C,0x51,0x36,0x75,0x53,0x57,0x6D,0x20,0x34,0x64,0x15,0x00,0x00,0x08,0x00,0x20,0x00,0x00,0x00,0x00,0x00,0x00,0xC7,0x73,0x3C,0xC7,0x73,0x3C,0xC9,
|
||||
0x93,0x3C,0xCB,0x73,0x3C,0xC7,0x93,0x3C,0x49,0xD3,0x34,0x4D,0xD3,0x34,0x4D,0xD3,0x34,0x4D,0xD3,0x34,0x4D,0xD3,0x34,0x4D,0xD3,0x34,0x4D,0xD3,0x34,0x4D,0xD3,0x34,
|
||||
0x4D,0xD3,0x34,0x4D,0xD3,0x34,0x4D,0xD3,0x34,0x4D,0xD3,0x34,0x4D,0xD3,0x34,0x4D,0xD3,0x34,0x4D,0x03,0x42,0x43,0x56,0x02,0x00,0x64,0x00,0x00,0x1C,0xB5,0x56,0x73,
|
||||
0xEF,0xBD,0x87,0x8C,0x39,0x48,0xB1,0xF6,0x1E,0x33,0xA5,0x18,0xB4,0x98,0x7B,0xCE,0x14,0x32,0x4A,0x52,0xED,0xAD,0x63,0x46,0x18,0x26,0xB5,0xA7,0x90,0x21,0x62,0x14,
|
||||
0xD4,0x9E,0x4A,0xC8,0x10,0x52,0xD0,0x7B,0x29,0xA1,0x53,0x8A,0x49,0xEF,0x29,0xA5,0x52,0x4A,0xAA,0xBD,0xF7,0x5A,0x63,0xED,0xBD,0xF7,0x1E,0x08,0x0D,0x59,0x11,0x00,
|
||||
0x44,0x01,0x00,0x00,0x08,0x21,0xC6,0x10,0x63,0x88,0x31,0x06,0x21,0x83,0x10,0x31,0xC6,0x20,0x64,0x10,0x22,0xC6,0x1C,0x84,0x0C,0x42,0x06,0x21,0x94,0x12,0x4A,0xC9,
|
||||
0x20,0x84,0x52,0x42,0x49,0x11,0x73,0x0E,0x42,0x07,0x21,0x83,0x10,0x4A,0x09,0xA1,0x64,0x10,0x42,0x29,0x21,0x95,0x02,0x00,0x00,0x02,0x1C,0x00,0x00,0x02,0x2C,0x84,
|
||||
0x42,0x43,0x56,0x04,0x00,0x71,0x02,0x00,0x08,0x42,0xCE,0x21,0xC6,0x20,0x44,0x8C,0x41,0x08,0x25,0xA4,0x14,0x42,0x48,0x29,0x62,0x0C,0x42,0xE6,0x9C,0x94,0xCC,0x39,
|
||||
0x29,0xA5,0x94,0xD6,0x42,0x29,0xA9,0x45,0x8C,0x41,0xC8,0x9C,0x93,0x92,0x39,0x27,0x25,0x94,0xD2,0x52,0x29,0xA5,0xB5,0x50,0x4A,0x6B,0x25,0x95,0xD8,0x42,0x29,0xAD,
|
||||
0xB5,0xD6,0x6A,0x4D,0xAD,0xC5,0x1A,0x4A,0x69,0x2D,0x94,0xD2,0x5A,0x29,0xA5,0xB5,0xD4,0x5A,0x8D,0x2D,0xB6,0x5A,0x23,0xC6,0x20,0x64,0xCE,0x49,0xC9,0x9C,0x93,0x52,
|
||||
0x52,0x69,0xAD,0x94,0xD4,0x5A,0xE6,0x9C,0x94,0x0E,0x42,0x4A,0x1D,0x84,0x94,0x52,0x4A,0x2D,0x96,0x94,0x5A,0xCC,0x9C,0x93,0xD2,0x41,0x47,0xA5,0x83,0x90,0x52,0x49,
|
||||
0x25,0xB6,0x92,0x52,0x8C,0x21,0x95,0x18,0x4B,0x4A,0x31,0x96,0x94,0x62,0x6C,0x2D,0xC6,0xDC,0x5A,0xAC,0x39,0x94,0xD2,0x5A,0x49,0x25,0xB6,0x92,0x52,0x8C,0x29,0xA6,
|
||||
0x1A,0x5B,0x8C,0x39,0x47,0x8C,0x41,0xC8,0x9C,0x93,0x92,0x39,0x27,0xA5,0x94,0xD2,0x5A,0x29,0xA9,0xB5,0xCC,0x39,0x29,0x1D,0x84,0x94,0x3A,0x07,0x25,0x95,0x94,0x62,
|
||||
0x2C,0x25,0xB5,0x98,0x39,0x27,0xA9,0x83,0x90,0x52,0x07,0x21,0xA5,0x92,0x52,0x6C,0x29,0xA5,0xD8,0x42,0x29,0xAD,0x95,0x94,0x62,0x2C,0x25,0xB5,0xD8,0x62,0xCC,0x35,
|
||||
0xA5,0xD8,0x6A,0x29,0x29,0xC6,0x92,0x52,0x8C,0x25,0xA5,0x18,0x5B,0x8C,0xB5,0xB6,0xD8,0x6A,0xEC,0x24,0xB4,0x16,0x52,0x89,0x31,0x94,0xD2,0x62,0x8B,0xB1,0xD6,0xD6,
|
||||
0x62,0xAD,0x21,0x95,0x18,0x4B,0x4A,0x31,0x96,0x94,0x62,0x6C,0x31,0xE6,0x1C,0x63,0xAC,0x39,0x94,0xD2,0x62,0x49,0x25,0xB6,0x92,0x52,0x8C,0x2D,0xB6,0x5C,0x63,0x8C,
|
||||
0x35,0xA7,0xD6,0x72,0x6D,0x2D,0xE6,0xDC,0x62,0xCC,0xB5,0xC6,0x5C,0x7B,0xAC,0xB9,0xF7,0xD4,0x5A,0xAD,0xA9,0xB5,0x5C,0x5B,0x8C,0x39,0xC7,0x1A,0x7B,0xAD,0xB5,0xF6,
|
||||
0xDE,0x41,0x68,0x2D,0x94,0x12,0x5B,0x28,0x25,0xC6,0xD6,0x5A,0xAD,0xAD,0xC5,0x9C,0x43,0x29,0xB1,0x95,0x94,0x62,0x2C,0x25,0xC5,0xDA,0x62,0xCC,0xB9,0xB5,0x58,0x73,
|
||||
0x28,0x25,0xC6,0x92,0x52,0x8C,0x25,0xA5,0x18,0x5B,0x8C,0xB5,0xC6,0x1A,0x73,0x4D,0xAD,0xD5,0xDA,0x62,0xCC,0x35,0xB5,0x56,0x73,0xAD,0xB5,0xE7,0xD8,0x6A,0xED,0xA9,
|
||||
0xC5,0x9A,0x5B,0x8C,0xB5,0xB7,0xD8,0x72,0x8D,0xB9,0xF6,0x5E,0x73,0xEC,0xB1,0x00,0x00,0x80,0x01,0x07,0x00,0x80,0x00,0x13,0xCA,0x40,0xA1,0x21,0x2B,0x01,0x80,0x28,
|
||||
0x00,0x00,0xC2,0x18,0xA5,0x18,0x83,0xD0,0x20,0xA4,0x94,0x63,0x10,0x1A,0x84,0x94,0x62,0x0E,0x42,0xA5,0x14,0x63,0xCE,0x49,0xA9,0x94,0x62,0xCC,0x39,0x28,0x99,0x63,
|
||||
0xCE,0x41,0x28,0x25,0x73,0xCE,0x39,0x08,0xA5,0x84,0x10,0x4A,0x28,0x25,0xA5,0x10,0x42,0x29,0xA5,0xA4,0x54,0x00,0x00,0x40,0x81,0x03,0x00,0x40,0x80,0x0D,0x9A,0x12,
|
||||
0x8B,0x03,0x14,0x1A,0xB2,0x12,0x00,0x08,0x09,0x00,0x20,0x8C,0x51,0x8A,0x31,0xE7,0x20,0x94,0x92,0x52,0x4A,0x11,0x42,0x8C,0x39,0x07,0x21,0x84,0x52,0x52,0x6A,0x29,
|
||||
0x42,0x88,0x31,0xE7,0x20,0x84,0x50,0x4A,0x4A,0xAD,0x55,0x8C,0x31,0xE6,0x1C,0x84,0x10,0x4A,0x49,0xA9,0xB5,0x8A,0x31,0xC6,0x9C,0x83,0x10,0x42,0x29,0x29,0xB5,0x96,
|
||||
0x39,0xE7,0x1C,0x84,0x10,0x4A,0x49,0xA9,0xB5,0xD6,0x32,0xE7,0x9C,0x83,0x10,0x42,0x29,0x29,0xA5,0xD6,0x5A,0x08,0x21,0x84,0x50,0x4A,0x29,0x25,0xA5,0xD6,0x62,0xEC,
|
||||
0x20,0x84,0x50,0x42,0x29,0xA5,0xA4,0xD4,0x5A,0x8C,0x21,0x84,0x10,0x4A,0x29,0x25,0xA5,0xD4,0x5A,0x8B,0x31,0x84,0x10,0x42,0x29,0xA5,0xA4,0xD4,0x52,0x6B,0x31,0x96,
|
||||
0x52,0x4A,0x49,0x29,0xA5,0xD4,0x5A,0x6B,0x31,0xD6,0x52,0x4A,0x29,0x29,0xA5,0xD4,0x52,0x6B,0xB1,0xC5,0x98,0x52,0x4A,0xA9,0xB5,0xD6,0x5A,0x8B,0x31,0xC6,0x5A,0x53,
|
||||
0x4A,0x29,0xB5,0xD6,0x5A,0x6B,0xB1,0xC5,0x58,0x6B,0x6A,0xAD,0xB5,0xD6,0x62,0x8C,0x31,0xC6,0x5A,0x6B,0x4D,0xAD,0xB5,0xD6,0x5A,0x8C,0x31,0xD6,0x58,0x6B,0xAD,0x05,
|
||||
0x00,0x00,0x1C,0x38,0x00,0x00,0x04,0x18,0x41,0x27,0x19,0x55,0x16,0x61,0xA3,0x09,0x17,0x1E,0x80,0x42,0x43,0x56,0x04,0x00,0x51,0x00,0x00,0x80,0x31,0x88,0x31,0xC4,
|
||||
0x18,0x82,0x8E,0x49,0xC8,0x24,0x44,0x0E,0x32,0x28,0x19,0x94,0x06,0x42,0x48,0xA9,0xA3,0x94,0x51,0x2A,0x25,0x96,0x1A,0x33,0x4A,0x25,0xA6,0x12,0x6B,0x04,0xA1,0xA3,
|
||||
0x14,0x52,0xCA,0x28,0x95,0x1A,0x4B,0xAB,0x19,0xA5,0x12,0x63,0x89,0xA5,0x00,0x00,0xB0,0x03,0x07,0x00,0xB0,0x03,0x0B,0xA1,0xD0,0x90,0x95,0x00,0x40,0x1E,0x00,0x00,
|
||||
0x81,0x90,0x52,0x8C,0x39,0xE7,0x1C,0x42,0x88,0x31,0xC6,0x9C,0x73,0x0E,0x21,0xC5,0x18,0x63,0xCE,0x39,0xA7,0x18,0x63,0xCC,0x39,0xE7,0x9C,0x53,0x8C,0x31,0xE6,0x9C,
|
||||
0x73,0xCE,0x31,0xC6,0x9C,0x73,0x0E,0x42,0x08,0x19,0x63,0xCE,0x39,0x07,0x21,0x84,0xCE,0x39,0xE7,0x20,0x84,0x10,0x42,0xE7,0x9C,0x73,0x10,0x42,0x08,0xA1,0x73,0xCE,
|
||||
0x39,0x08,0x21,0x84,0xD0,0x39,0xE7,0x1C,0x84,0x10,0x42,0x28,0x00,0x00,0xA8,0xC0,0x01,0x00,0x20,0xC0,0x46,0x91,0xCD,0x09,0x46,0x82,0x0A,0x0D,0x59,0x09,0x00,0xA4,
|
||||
0x02,0x00,0x00,0xC6,0x30,0xE6,0x9C,0x73,0x10,0x4A,0x69,0x94,0x72,0x0E,0x42,0x08,0xA5,0xB4,0xD4,0x28,0xE5,0x1C,0x84,0x10,0x4A,0x49,0x2D,0x73,0x0E,0x42,0x29,0xA5,
|
||||
0xB4,0x16,0x5B,0xE6,0x1C,0x84,0x52,0x4A,0x49,0xAD,0xB5,0x0E,0x42,0x29,0x29,0xA5,0xD4,0x5A,0x8C,0x1D,0x84,0x52,0x52,0x4A,0xA9,0xC5,0x18,0x3B,0x08,0xA5,0xA4,0xD4,
|
||||
0x5A,0x8C,0xB5,0x76,0x10,0x4A,0x49,0xA9,0xB5,0x18,0x6B,0x0D,0xA5,0xA4,0x16,0x5B,0xAC,0xB5,0xD6,0x1A,0x4A,0x49,0xAD,0xC5,0x18,0x6B,0xAD,0xB5,0xA4,0xD4,0x5A,0x8C,
|
||||
0xB5,0xE6,0x9C,0x73,0x49,0xA9,0xB5,0x18,0x6B,0xAD,0x35,0xE7,0x02,0x00,0xC0,0x13,0x1C,0x00,0x80,0x0A,0x6C,0x58,0x1D,0xE1,0xA4,0x68,0x2C,0xB0,0xD0,0x90,0x95,0x00,
|
||||
0x40,0x06,0x00,0x00,0x61,0x0C,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x94,0x42,0x08,0x29,0x25,0x00,0x00,0x60,0xC0,0x01,0x00,0x20,0xC0,0x84,0x32,0x50,0x68,
|
||||
0xC8,0x4A,0x00,0x20,0x15,0x00,0x00,0x30,0x86,0x31,0xC6,0x9C,0x83,0x50,0x4A,0xA3,0x14,0x84,0x10,0x42,0x28,0x25,0xA5,0x46,0x29,0x07,0x21,0x84,0x50,0x52,0x4B,0x99,
|
||||
0x83,0x52,0x4A,0x49,0x25,0xB5,0x16,0x33,0x08,0xA5,0x94,0x52,0x4A,0x6A,0x31,0x66,0xD0,0x49,0x49,0x29,0xB5,0x16,0x63,0xCD,0x20,0x94,0x92,0x52,0x6A,0x31,0xC6,0xD8,
|
||||
0x41,0x28,0x29,0xB5,0xD6,0x62,0x8C,0xB1,0x83,0x50,0x52,0x4A,0xAD,0xC5,0x58,0x6B,0x28,0xA5,0xA5,0x16,0x63,0xAC,0x31,0xC6,0x50,0x4A,0x4A,0xAD,0xC5,0x1A,0x63,0x8D,
|
||||
0x25,0xA5,0x16,0x6B,0xAD,0xB9,0xD6,0x5A,0x4B,0x4A,0xAD,0xC5,0x18,0x6B,0xAD,0xB9,0x16,0x00,0x80,0xD0,0xE0,0x00,0x00,0x76,0x60,0xC3,0xEA,0x08,0x27,0x45,0x63,0x81,
|
||||
0x85,0x86,0xAC,0x04,0x00,0xF2,0x00,0x00,0x10,0x84,0x94,0x62,0x8C,0x31,0xC6,0x90,0x52,0x8C,0x31,0xC6,0x98,0x73,0x48,0x29,0xA5,0x18,0x63,0xCC,0x39,0xA5,0x18,0x63,
|
||||
0x8E,0x39,0xE7,0x9C,0x62,0x8C,0x31,0xC6,0x9C,0x73,0x8E,0x31,0xC6,0x98,0x73,0xCE,0x39,0xC7,0x18,0x63,0xCE,0x39,0xE7,0x9C,0x63,0x8C,0x39,0xE7,0x9C,0x73,0xCE,0x31,
|
||||
0xC6,0x9C,0x73,0xCE,0x39,0xE7,0x98,0x73,0xCE,0x39,0xE7,0x9C,0x73,0xCC,0x39,0xE7,0x9C,0x73,0xCE,0x39,0x01,0x00,0x40,0x05,0x0E,0x00,0x00,0x01,0x36,0x8A,0x6C,0x4E,
|
||||
0x30,0x12,0x54,0x68,0xC8,0x4A,0x00,0x20,0x1C,0x00,0x00,0x40,0x88,0x31,0xE7,0x18,0x73,0x4E,0x42,0x4A,0x8D,0x52,0xCE,0x49,0x08,0x1D,0x84,0x52,0x5A,0x6D,0x14,0x73,
|
||||
0x10,0x4A,0xE8,0x20,0x94,0xD6,0x52,0xE6,0x9C,0x94,0x52,0x42,0x28,0x25,0xC5,0xD8,0x32,0xE7,0x20,0xA5,0x12,0x42,0x2A,0x2D,0xA5,0xDA,0x41,0x48,0x25,0xA5,0x52,0x52,
|
||||
0x8A,0xAD,0xB6,0x0E,0x42,0x6A,0x29,0x95,0xD2,0x52,0x6B,0xAD,0x66,0xCE,0x41,0x28,0xA5,0xA4,0x96,0x62,0xAC,0x2D,0x73,0x10,0x42,0x29,0x29,0xA5,0xD6,0x6A,0xAD,0x9D,
|
||||
0x84,0x92,0x52,0x4A,0xB5,0xB5,0x58,0x6B,0x0C,0x21,0x94,0x94,0x52,0x6B,0xAD,0xB6,0x1A,0x6B,0x29,0xA5,0xA5,0x96,0x6A,0xAC,0xB1,0xD6,0x58,0x43,0x29,0xA9,0xA5,0xD8,
|
||||
0x62,0xAC,0xB5,0xC6,0x5A,0x62,0x6C,0x2D,0xB5,0x1A,0x6B,0xAC,0xAD,0xC6,0x92,0x52,0x4B,0xAD,0xD5,0x5A,0x63,0xAD,0xB5,0x16,0x00,0x60,0xF2,0xE0,0x00,0x00,0x95,0x60,
|
||||
0xE3,0x0C,0x2B,0x49,0x67,0x85,0xA3,0xC1,0x85,0x86,0xAC,0x04,0x00,0x72,0x03,0x00,0x08,0x84,0x18,0x73,0xCE,0x39,0x08,0x25,0x94,0x10,0x42,0x29,0xA5,0x44,0x4A,0x31,
|
||||
0xE6,0x1C,0x84,0x10,0x4A,0x28,0xA5,0x94,0x52,0x52,0x89,0x94,0x62,0xCC,0x39,0x07,0xA1,0x94,0x52,0x4A,0x29,0xA5,0x94,0x92,0x31,0xE6,0x1C,0x74,0x10,0x4A,0x28,0xA5,
|
||||
0x94,0x52,0x52,0x49,0x25,0x63,0xCC,0x39,0x07,0x21,0x94,0x50,0x4A,0x29,0xA5,0x94,0x52,0x4A,0xE7,0x1C,0x84,0x10,0x4A,0x28,0xA5,0x94,0x52,0x4A,0x2A,0x25,0x95,0xCE,
|
||||
0x39,0x07,0x21,0x84,0x52,0x4A,0x29,0xA5,0x94,0x92,0x52,0x29,0x1D,0x84,0x10,0x42,0x28,0xA5,0x94,0x52,0x52,0x49,0x25,0x95,0x54,0x3A,0x08,0x21,0x84,0x52,0x4A,0x29,
|
||||
0xA5,0x94,0x52,0x52,0x2A,0xA5,0x84,0x12,0x42,0x29,0x25,0x95,0x52,0x4A,0x29,0xA5,0xA4,0x94,0x52,0x0A,0x21,0x94,0x50,0x4A,0x29,0xA5,0xA4,0x92,0x4A,0x4A,0x29,0x95,
|
||||
0x12,0x4A,0x28,0xA5,0x94,0x54,0x4A,0x29,0x25,0x95,0x54,0x52,0x29,0x29,0x94,0x52,0x4A,0x29,0xA5,0x94,0x54,0x4A,0x4A,0x25,0xA5,0x94,0x52,0x08,0xA5,0x94,0x52,0x52,
|
||||
0x29,0xA9,0x94,0x54,0x4A,0x4A,0x29,0xA5,0x50,0x4A,0x29,0xA5,0x94,0x54,0x52,0x49,0x25,0xA5,0x94,0x52,0x49,0xA5,0x94,0x52,0x4A,0x29,0x25,0xA5,0x94,0x52,0x4A,0x29,
|
||||
0x95,0x94,0x4A,0x29,0xA5,0xA4,0x52,0x4A,0x2A,0x29,0xA5,0x54,0x5A,0x4A,0xA9,0x94,0x52,0x4A,0x49,0xA5,0x94,0x94,0x5A,0x4A,0x29,0xA5,0x94,0x52,0x2A,0xA5,0xA4,0x92,
|
||||
0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x54,0x4A,0x49,0x25,0x95,0x92,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0xA5,0x94,0x52,0x4A,0x49,0xA9,0xA4,0x54,0x52,0x2A,
|
||||
0x29,0xA5,0x92,0x52,0x01,0x00,0x40,0x07,0x0E,0x00,0x00,0x01,0x46,0x54,0x5A,0x88,0x9D,0x66,0x5C,0x79,0x04,0x8E,0x28,0x64,0x98,0x80,0x0A,0x0D,0x59,0x09,0x00,0x84,
|
||||
0x03,0x00,0x00,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x89,0x8C,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,
|
||||
0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,
|
||||
0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,
|
||||
0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x1A,0x29,0xA5,0x94,
|
||||
0x52,0x4A,0x29,0xA5,0x54,0x0A,0x49,0x29,0x25,0x84,0x10,0x42,0x08,0x21,0x42,0x02,0x40,0xBA,0x32,0x1C,0x00,0x00,0x02,0xAC,0x49,0x57,0x2F,0x52,0x5D,0xC6,0xE8,0x60,
|
||||
0x74,0xE9,0xCA,0x2E,0x68,0x74,0x78,0x91,0xA3,0x43,0x00,0x0A,0x00,0x90,0xAE,0x91,0xD5,0x84,0x25,0x34,0x64,0x25,0x00,0x90,0x16,0x00,0x00,0x58,0x69,0xA5,0x95,0x96,
|
||||
0x5A,0x6B,0xAD,0xB5,0xD6,0x22,0x04,0xA5,0xA5,0xD4,0x5A,0x6B,0xAD,0xB5,0xD6,0x5A,0x6B,0x25,0x84,0x14,0x52,0x6A,0xA9,0xB5,0xD6,0x5A,0x6B,0xAD,0xB5,0xCE,0x49,0x0A,
|
||||
0x2D,0xB5,0xD6,0x5A,0x6B,0xAD,0xB5,0xD6,0x5A,0xE8,0x24,0xB5,0xD4,0x52,0x6B,0xAD,0xB5,0xD6,0x5A,0x6B,0xAD,0x83,0x94,0x4A,0x6B,0xAD,0xB5,0xD6,0x5A,0x6B,0xAD,0xB5,
|
||||
0x16,0x4A,0x6A,0xA9,0xA5,0xD6,0x5A,0x6B,0xAD,0xB5,0xD6,0x5A,0x0B,0x21,0xB5,0xD6,0x5A,0x6B,0xAD,0xB5,0xD6,0x5A,0x6B,0xAD,0xB5,0xD6,0x5A,0x6B,0xAD,0xB5,0xD6,0x5A,
|
||||
0x6B,0xAD,0xB5,0xD6,0x5A,0x6B,0xAD,0xB5,0xD6,0x5A,0x6B,0xAD,0xB5,0xD6,0x5A,0x6B,0xAD,0xB5,0xD6,0x5A,0x6B,0xAD,0xB5,0xD6,0x5A,0x6B,0xAD,0xB5,0xD6,0x5A,0x6B,0xAD,
|
||||
0xB5,0xD6,0x5A,0x6B,0xAD,0xB5,0xD6,0x5A,0x6B,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,
|
||||
0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,
|
||||
0x29,0xA5,0x94,0x52,0x8A,0x1C,0x84,0x8E,0x42,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x11,0x32,0xCE,0x39,0x27,0xA1,0x94,0x94,0x52,0x4A,0x29,0xA5,0xC8,0x08,0x00,0x40,0x8C,
|
||||
0x70,0x00,0x00,0x08,0xB0,0x84,0xD8,0x55,0xB9,0x99,0xA4,0x5E,0x3D,0x1B,0x12,0xC3,0xE4,0x24,0x7D,0x8A,0xE1,0x6A,0x0C,0xDF,0x02,0x00,0x31,0x61,0x8C,0x09,0x0D,0x59,
|
||||
0x05,0x00,0xC4,0x00,0x00,0x00,0x84,0x18,0xC6,0x98,0x63,0x8C,0x31,0xE7,0x9C,0x63,0xCE,0x39,0xE7,0x9C,0x73,0x8E,0x41,0xE8,0x20,0x84,0xCE,0x39,0xE7,0x9C,0x73,0xCE,
|
||||
0x39,0x67,0xAD,0xA4,0x02,0x00,0x00,0x13,0x1C,0x00,0x00,0x02,0xAC,0x60,0x57,0x66,0x69,0xD5,0x46,0x71,0x53,0x27,0x79,0xD1,0x07,0x81,0x4F,0xE8,0x88,0xCD,0xC8,0x90,
|
||||
0x4B,0xA9,0x98,0xC9,0x89,0xA0,0x47,0x6A,0xA8,0xC5,0x4A,0xB0,0x43,0x2B,0xB8,0xC1,0x0B,0xC0,0x42,0x43,0x56,0x02,0x00,0x64,0x00,0x00,0x10,0x93,0x52,0x52,0x8A,0x45,
|
||||
0x59,0x08,0x29,0xE6,0xA0,0x25,0xE5,0x21,0x63,0x14,0x83,0x98,0x94,0x87,0x8C,0x41,0xCA,0x59,0x50,0x1A,0x42,0xC6,0x20,0x66,0xC5,0x78,0x8C,0x29,0x84,0x94,0x14,0x23,
|
||||
0x42,0xE8,0x14,0x52,0x50,0x8C,0x8A,0x31,0x76,0x8C,0x41,0x2F,0x32,0x18,0x9F,0x42,0x08,0xC1,0xE8,0x62,0x8C,0x8E,0xB1,0x16,0x23,0x00,0x00,0x00,0x41,0x00,0x80,0x80,
|
||||
0x90,0x00,0x00,0x03,0x04,0x05,0x33,0x00,0xC0,0xE0,0x00,0x61,0xE4,0x40,0xA0,0x23,0x80,0xC0,0xA1,0x0D,0x00,0x30,0x10,0x21,0x33,0x81,0x41,0x21,0x34,0x38,0xC8,0x04,
|
||||
0x80,0x07,0x88,0x08,0xA9,0x00,0x20,0x31,0x41,0x51,0xBA,0xD0,0x05,0x21,0x44,0x90,0x2E,0x82,0x2C,0x1E,0xB8,0x70,0xE2,0xC6,0x13,0x37,0x9C,0xD0,0xA1,0x0D,0x02,0x00,
|
||||
0x00,0x00,0x00,0x00,0x02,0x00,0x3E,0x00,0x00,0x12,0x0A,0x20,0x22,0x9A,0x99,0xB9,0x0A,0x8B,0x0B,0x8C,0x0C,0x8D,0x0D,0x8E,0x0E,0x8F,0x0F,0x90,0x10,0x91,0x91,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x01,0x80,0x0F,0x00,0x80,0x84,0x04,0x88,0x88,0x66,0x66,0xAE,0xC2,0xE2,0x02,0x23,0x43,0x63,0x83,0xA3,0xC3,0xE3,0x03,0x24,0x44,0x64,0x24,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,0x08,
|
||||
};
|
||||
static const uint8_t vcb_4[] = {
|
||||
0x29,0x42,0x43,0x56,0x01,0x00,0x08,0x00,0x00,0x80,0x22,0x4C,0x20,0xC3,0x80,0xD0,0x90,0x55,0x00,0x00,0x10,0x00,0x00,0x80,0xA8,0x36,0x14,0x6B,0xA9,0xB1,0xD6,0x1A,
|
||||
0x63,0xA1,0x28,0x46,0xD4,0x62,0x6A,0x31,0xC6,0x18,0x63,0xE3,0x2C,0x46,0x90,0x62,0x8B,0x31,0xC6,0x18,0x63,0x8C,0x31,0xC6,0x18,0x63,0x8C,0x31,0xC6,0x18,0x63,0x20,
|
||||
0x34,0x64,0x15,0x00,0x00,0x04,0x00,0x40,0x31,0xEA,0x15,0x93,0x9E,0x42,0xCC,0x39,0xE7,0xDC,0x18,0xA6,0x8D,0x51,0xDA,0x29,0xC7,0x39,0xE7,0xDC,0x18,0xC5,0x89,0x30,
|
||||
0x58,0x21,0xA5,0xB9,0xA5,0x9A,0x52,0xCC,0xA1,0x93,0x9C,0x4A,0xCA,0x39,0xE7,0x1C,0x08,0x0D,0x59,0x05,0x00,0x00,0x02,0x00,0x40,0x48,0x21,0x85,0x14,0x52,0x48,0x21,
|
||||
0x85,0x14,0x52,0x48,0x21,0x85,0x14,0x52,0x4A,0x29,0xA5,0x94,0x62,0x8A,0x29,0xA6,0x98,0x62,0x8A,0x29,0xA6,0x98,0x72,0xCC,0x31,0xC7,0x1C,0x83,0x0C,0x32,0xE8,0xA4,
|
||||
0x93,0x4E,0x3A,0xE9,0x24,0xA4,0x90,0x42,0x09,0xA5,0xA4,0x92,0x52,0x4A,0xAD,0xC5,0x1A,0x6B,0xEF,0xBD,0xF7,0x9E,0x7B,0xEF,0xBD,0xF7,0xDE,0x7B,0xEF,0xBD,0xF7,0xDE,
|
||||
0x7B,0xEF,0xBD,0xF7,0xDE,0x7B,0xCF,0x39,0x07,0x42,0x43,0x56,0x01,0x00,0x20,0x00,0x00,0x04,0x42,0x06,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x14,0x52,0x48,0x21,0xA6,
|
||||
0x98,0x62,0xCA,0x29,0xA7,0x80,0xD0,0x90,0x55,0x00,0x00,0x20,0x00,0x80,0x00,0x00,0x00,0x00,0x4B,0xB1,0x14,0x4D,0xD1,0x1C,0xCF,0xF1,0x1C,0xCF,0x11,0x1D,0x53,0x12,
|
||||
0x25,0x53,0x32,0x25,0x53,0x72,0x2D,0xD7,0x32,0x2D,0x53,0x33,0x3D,0xD3,0x33,0x45,0x55,0x74,0x55,0x53,0x55,0x65,0xD7,0x75,0x65,0x53,0x36,0x65,0x53,0x36,0x65,0x55,
|
||||
0x36,0x65,0x53,0x36,0x65,0x53,0x36,0x65,0xD5,0x95,0x65,0x59,0x96,0x65,0x59,0x96,0x65,0x59,0x96,0x65,0x59,0x96,0x65,0x59,0x96,0x65,0x20,0x34,0x64,0x15,0x00,0x20,
|
||||
0x01,0x00,0xA0,0x23,0x39,0x92,0x23,0x29,0x8E,0xE2,0x38,0x8E,0xE3,0x48,0x92,0x04,0x84,0x86,0xAC,0x02,0x00,0x64,0x00,0x00,0x04,0x00,0x60,0x28,0x8A,0xA3,0x48,0x8E,
|
||||
0x24,0x59,0x92,0x65,0x59,0x96,0x67,0x99,0x9A,0xE9,0x99,0x9E,0x69,0x9A,0xA6,0x69,0x9A,0xA6,0x09,0x84,0x86,0xAC,0x02,0x00,0x00,0x01,0x00,0x04,0x00,0x00,0x00,0x00,
|
||||
0x00,0xA0,0x69,0x9A,0xA6,0x69,0x9A,0xA6,0x69,0x9A,0xA6,0x69,0x9A,0xA6,0x69,0x9A,0xA6,0x69,0x9A,0xA6,0x69,0x9A,0x66,0x59,0x96,0x65,0x59,0x96,0x65,0x59,0x96,0x65,
|
||||
0x59,0x96,0x65,0x59,0x96,0x65,0x59,0x96,0x65,0x59,0x96,0x65,0x59,0x96,0x65,0x59,0x96,0x65,0x59,0x96,0x65,0x59,0x96,0x65,0x59,0x96,0x65,0x59,0x40,0x68,0xC8,0x2A,
|
||||
0x00,0x40,0x02,0x00,0x40,0xC7,0x71,0x1C,0xC7,0x71,0x1C,0xC7,0x71,0x1C,0x47,0x72,0x24,0x07,0x08,0x0D,0x59,0x05,0x00,0xC8,0x00,0x00,0x08,0x00,0x40,0x52,0x24,0xC5,
|
||||
0x72,0x34,0x47,0x73,0x34,0xC7,0x73,0x3C,0x47,0x74,0x44,0x47,0x94,0x4C,0x49,0x95,0x5C,0x4B,0xB6,0x64,0x0D,0x08,0x0D,0x59,0x05,0x00,0x00,0x02,0x00,0x08,0x00,0x00,
|
||||
0x00,0x00,0x00,0x40,0x33,0x2C,0x43,0x53,0x3C,0x47,0xB3,0x44,0x4D,0xD4,0x44,0x51,0xF4,0x44,0x4F,0x14,0x45,0xD1,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,
|
||||
0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x3C,0xCF,0xF3,0x80,0xD0,
|
||||
0x90,0x55,0x00,0x00,0x04,0x00,0x00,0x01,0x9D,0x66,0x98,0x6A,0x80,0x08,0x33,0x92,0x59,0x20,0x34,0x64,0x15,0x00,0x80,0x00,0x00,0x00,0x10,0x81,0x0C,0x53,0x0C,0x08,
|
||||
0x0D,0x59,0x05,0x00,0x00,0x04,0x00,0x00,0x48,0x91,0xE4,0x24,0x89,0x92,0x93,0x52,0x4A,0x39,0x0C,0x92,0xC5,0x24,0xA9,0x94,0x93,0x52,0x4A,0x79,0x14,0x93,0x47,0x35,
|
||||
0xC9,0x18,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0x0C,0x92,0xE5,0x28,0xA9,0x94,0x93,0x52,0x4A,0x49,0x8C,0x92,0xC5,0x28,0xA9,0x52,
|
||||
0x93,0x52,0x4A,0x79,0x94,0x93,0x27,0x35,0xC9,0xD8,0x93,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x59,0x90,0x92,0x27,0x2D,0xE9,0x1A,0x94,0x52,
|
||||
0x4A,0x49,0x8E,0x92,0x06,0x2D,0xD9,0xD4,0x93,0x52,0x4A,0x89,0x52,0x94,0x28,0x39,0xD9,0x9E,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0xF9,
|
||||
0xA0,0x94,0x0F,0x42,0x29,0xA5,0x94,0x52,0x4A,0xB9,0xDA,0x93,0x6B,0x3D,0x29,0xA5,0x94,0x52,0x4A,0x19,0xA3,0x94,0xF0,0x49,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,
|
||||
0x52,0x4A,0x29,0xA5,0x94,0x52,0xCA,0x08,0x42,0x43,0x56,0x01,0x00,0x40,0x00,0x00,0x80,0x71,0xD6,0x28,0x87,0xA2,0x93,0xE8,0x7C,0x71,0x86,0x72,0xA6,0x29,0x48,0x2A,
|
||||
0x94,0x26,0x74,0x6F,0x92,0xA3,0xE4,0x39,0xC9,0xAD,0xB4,0xDC,0x9C,0x6E,0xC2,0x39,0xA7,0x9B,0x53,0xCE,0xF9,0xE4,0x9C,0x73,0x82,0xD0,0x90,0x55,0x00,0x00,0x20,0x00,
|
||||
0x00,0x84,0x10,0x52,0x48,0x21,0x85,0x14,0x52,0x48,0x21,0x85,0x14,0x52,0x88,0x21,0x86,0x18,0x72,0xC8,0x29,0xA7,0xA0,0x82,0x0A,0x2A,0xA9,0xA4,0xA2,0x8A,0x2A,0xAA,
|
||||
0xAC,0xB2,0xCC,0x32,0xCB,0x2C,0xB3,0xCC,0x32,0xCB,0x2C,0xB3,0xCC,0x32,0xEB,0xAC,0xA3,0x8E,0x3A,0x0B,0x29,0x84,0x92,0x42,0x0B,0xAD,0xD5,0x18,0x6B,0x8C,0xB1,0xD5,
|
||||
0xDE,0x9C,0xB4,0x35,0x47,0x29,0x9D,0x94,0x52,0x4A,0x29,0xA5,0x94,0xCE,0x39,0xE7,0x9C,0x20,0x34,0x64,0x15,0x00,0x00,0x02,0x00,0x40,0x20,0x64,0x90,0x41,0x06,0x19,
|
||||
0x65,0x14,0x52,0x88,0x21,0xA6,0x9C,0x72,0xCA,0x29,0xA8,0xA4,0x92,0x0A,0x08,0x0D,0x59,0x05,0x00,0x00,0x02,0x00,0x08,0x00,0x00,0x00,0x10,0x25,0xD3,0x31,0x1D,0xD1,
|
||||
0x11,0x15,0xD1,0x11,0x1D,0xD1,0x11,0x1D,0xD1,0x11,0x1D,0xCF,0xF1,0x1C,0x4F,0x12,0x25,0xD1,0xF2,0x2C,0x51,0x33,0x3D,0x53,0x34,0x4D,0xD3,0x55,0x65,0x57,0x96,0x75,
|
||||
0xD9,0x96,0x6D,0x57,0x97,0x75,0x5B,0x97,0x7D,0xDB,0xB7,0x75,0xDB,0xB6,0x7D,0xDD,0xD8,0x8D,0xDF,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,
|
||||
0x8E,0x63,0x08,0x42,0x43,0x56,0x01,0x00,0x20,0x00,0x00,0x00,0x42,0x08,0x21,0x84,0x14,0x52,0x48,0x21,0x85,0x94,0x62,0x8A,0x31,0xE7,0xA0,0x83,0x10,0x42,0x29,0x81,
|
||||
0xD0,0x90,0x55,0x00,0x00,0x20,0x00,0x80,0x00,0x00,0x00,0x00,0x45,0x71,0x14,0xC7,0x91,0x1C,0x49,0x92,0x24,0x4B,0xB2,0x2C,0xCD,0xD2,0x34,0x4D,0xD3,0x34,0x4F,0xF4,
|
||||
0x44,0xCF,0xF4,0x54,0xCF,0x15,0x65,0xD1,0x16,0x6D,0xCF,0xF5,0x6C,0xD1,0xF6,0x5C,0x4F,0xF5,0x54,0x4F,0x15,0x55,0x53,0x35,0x5D,0xD3,0x55,0x5D,0xD7,0x75,0x5D,0xD5,
|
||||
0x55,0x65,0x55,0x76,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x65,0x20,0x34,0x64,0x15,0x00,0x20,0x01,0x00,0xA0,0x23,0x39,0x92,
|
||||
0x22,0x29,0x92,0x22,0x39,0x8E,0x23,0x39,0x92,0x04,0x84,0x86,0xAC,0x02,0x00,0x64,0x00,0x00,0x04,0x00,0xA0,0x28,0x8A,0xE2,0x38,0x8E,0xE4,0x58,0x92,0x25,0x69,0x92,
|
||||
0x28,0x99,0x96,0x6A,0xB9,0x9A,0xEC,0xE9,0x9E,0x2E,0xEA,0xA2,0x0E,0x84,0x86,0xAC,0x02,0x00,0x00,0x01,0x00,0x04,0x00,0x00,0x00,0x00,0x00,0x60,0x88,0x86,0x68,0x88,
|
||||
0x8E,0x68,0x89,0x9A,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,
|
||||
0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0x9E,0xE7,0x79,0x9E,0xE7,0x79,0x9E,0xE7,0x79,0x40,0x68,0xC8,0x2A,0x00,0x40,0x02,0x00,0x40,0x47,
|
||||
0x72,0x24,0xC7,0x52,0x2C,0x45,0x52,0x24,0xC5,0x72,0x2C,0x07,0x08,0x0D,0x59,0x05,0x00,0xC8,0x00,0x00,0x08,0x00,0xC0,0x31,0x1C,0x43,0x52,0x24,0xC7,0xB2,0x2C,0x4B,
|
||||
0xD3,0x34,0xCF,0xF3,0x3C,0x4F,0xF4,0x44,0x51,0x14,0x45,0xD3,0x54,0x4D,0x15,0x08,0x0D,0x59,0x05,0x00,0x00,0x02,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x40,0x51,0x14,
|
||||
0xCB,0xB1,0x1C,0x49,0xD2,0x1C,0x4F,0x12,0x1D,0x51,0x12,0x25,0xD1,0x12,0x25,0x51,0x13,0x35,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,
|
||||
0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x81,0xD0,0x90,0x95,0x00,0x00,0x19,0x00,
|
||||
0x00,0x03,0xB1,0xF5,0xD4,0x72,0xEE,0x8D,0xA0,0x48,0x2A,0x47,0xB5,0xC6,0xD4,0x51,0xE6,0x24,0x06,0x61,0x1A,0x8A,0xA0,0x82,0x18,0x84,0x0C,0x15,0x44,0x88,0x51,0x0E,
|
||||
0x26,0x62,0x0A,0x19,0x26,0x39,0x97,0x0C,0x3A,0xA6,0x98,0xD4,0x18,0x4B,0x2A,0x1D,0x73,0x52,0x6B,0x4B,0x25,0x54,0x48,0x41,0x0C,0x36,0xA6,0x52,0x29,0xE5,0xA8,0x07,
|
||||
0x42,0x43,0x56,0x08,0x00,0xA1,0x19,0x00,0x0E,0xC7,0x01,0x24,0xCD,0x02,0x24,0x4B,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x49,0xD3,0x00,0xCD,0xF3,0x00,0xCD,0xF3,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x40,0xD2,0x34,0xC0,0xF2,0x3C,0x40,0xF3,0x3C,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1C,0x4D,0x03,0x34,0xD1,0x03,0x34,0xCF,0x03,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x4D,0xF4,0x00,0x4F,0x34,0x01,0x4F,0x14,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0xC0,0xF2,0x3C,0xC0,0x33,0x3D,0xC0,0x13,0x4D,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x1C,0x4D,0x03,0x34,0xCF,0x03,0x34,0xCF,0x03,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCB,0xF3,0x00,0xCF,0x14,0x01,0xCF,0x33,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x40,
|
||||
0xF3,0x44,0xC0,0x13,0x45,0xC0,0x33,0x45,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x01,0x0E,0x00,0x00,0x01,0x16,0x42,0xA1,0x21,0x2B,0x02,0x80,0x38,0x01,
|
||||
0x00,0x87,0x24,0x41,0x92,0x20,0x49,0xD0,0x34,0x80,0x64,0x59,0xF0,0x34,0x68,0x1A,0x4C,0x13,0x20,0x59,0x16,0x34,0x0D,0x9A,0x06,0xD3,0x04,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x40,0xD2,0x34,0x68,0x1A,0x34,0x0D,0xA2,0x08,0x90,0x34,0x0D,0x9A,0x06,0x4D,0x83,0x28,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x20,
|
||||
0x79,0x1A,0x34,0x0D,0x9A,0x06,0x51,0x04,0x48,0x9A,0x07,0x4D,0x83,0xA6,0x41,0x14,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xD0,0x4C,0x13,0xA2,0x08,0x51,
|
||||
0x84,0x69,0x02,0x34,0xD3,0x84,0x28,0x42,0x14,0x61,0x9A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x80,0x00,0x00,0x80,0x01,0x07,0x00,0x80,0x00,0x13,0xCA,0x40,0xA1,0x21,0x2B,0x02,0x80,0x38,0x01,0x00,0x87,0xE2,0x58,0x16,0x00,0x00,0x38,0x92,0x63,0x59,0x00,
|
||||
0x00,0xE0,0x38,0x8E,0x65,0x01,0x00,0x80,0x65,0x59,0x9A,0x06,0x00,0x00,0x96,0x65,0x69,0x1A,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x80,0x00,0x00,0x80,0x01,0x07,0x00,0x80,0x00,0x13,0xCA,0x40,0xA1,0x21,
|
||||
0x2B,0x01,0x80,0x28,0x00,0x00,0x87,0xA2,0x58,0x16,0x70,0x1C,0xCB,0x02,0x8E,0x63,0x59,0x40,0x92,0x2C,0x0B,0x60,0x59,0x00,0xCD,0x03,0x68,0x1A,0x40,0x14,0x01,0x80,
|
||||
0x00,0x00,0x80,0x02,0x07,0x00,0x80,0x00,0x1B,0x34,0x25,0x16,0x07,0x28,0x34,0x64,0x25,0x00,0x10,0x05,0x00,0xE0,0x50,0x14,0xCB,0xD2,0x34,0x51,0xE4,0x38,0x9A,0xA6,
|
||||
0x69,0xA2,0xC8,0x71,0x34,0x4D,0xD3,0x44,0x91,0x65,0x69,0x9A,0xE7,0x99,0x26,0x34,0xCD,0xF3,0x4C,0x13,0x9E,0xE7,0x79,0xA6,0x09,0xCF,0xF3,0x3C,0xD3,0x84,0x69,0x8A,
|
||||
0xA2,0xAA,0x02,0x51,0x54,0x55,0x01,0x00,0x00,0x05,0x0E,0x00,0x00,0x01,0x36,0x68,0x4A,0x2C,0x0E,0x50,0x68,0xC8,0x4A,0x00,0x20,0x24,0x00,0xC0,0xE1,0x38,0x96,0xE5,
|
||||
0x79,0x9E,0x27,0x8A,0xA6,0x68,0x9A,0xAA,0xCA,0x71,0x34,0xCD,0xF3,0x44,0x51,0x14,0x4D,0x53,0x55,0x55,0x95,0xE3,0x58,0x96,0xE7,0x89,0xA2,0x28,0x9A,0xA6,0xAA,0xBA,
|
||||
0x2E,0xCB,0xD2,0x34,0xCF,0x13,0x45,0x51,0x34,0x4D,0x55,0x75,0x5D,0x68,0x9A,0xE7,0x89,0xA2,0x28,0x9A,0xA6,0xAA,0xBA,0x2E,0x3C,0xCF,0xF3,0x44,0xD1,0x14,0x4D,0x55,
|
||||
0x55,0x5D,0x17,0x9E,0xE7,0x79,0xA2,0x68,0x9A,0xAA,0xA9,0xAA,0xAE,0x0B,0x51,0x14,0x45,0xD3,0x34,0x4D,0x55,0x55,0x55,0xD7,0x05,0xA2,0x68,0x9A,0xA6,0xA9,0xAA,0xAE,
|
||||
0xEA,0xBA,0xC0,0xF3,0x44,0xD1,0x34,0x55,0xD5,0x75,0x5D,0x17,0x78,0x9E,0x28,0x9A,0xA6,0xAA,0xBA,0xAE,0xEB,0x02,0x51,0x34,0x4D,0xD5,0x54,0x55,0xD7,0x75,0x5D,0x80,
|
||||
0x69,0x9A,0xA6,0xAA,0xBA,0xAE,0xEC,0x02,0x54,0x55,0x55,0x55,0xD7,0x75,0x65,0x17,0xA0,0xAA,0xAA,0xAA,0xAA,0xAE,0x2B,0xCB,0x00,0x55,0x75,0x5D,0xD7,0x75,0x5D,0x59,
|
||||
0x06,0xA0,0xAA,0xAE,0xEB,0xBA,0xB2,0x2C,0x00,0x00,0xE0,0xC0,0x01,0x00,0x20,0xC0,0x08,0x3A,0xC9,0xA8,0xB2,0x08,0x1B,0x4D,0xB8,0xF0,0x00,0x14,0x1A,0xB2,0x22,0x00,
|
||||
0x88,0x02,0x00,0x00,0x8C,0x51,0x4A,0x31,0xA5,0x0C,0x63,0x12,0x42,0x09,0x21,0x62,0x4C,0x42,0x28,0x21,0x54,0x52,0x4A,0x29,0xA9,0x94,0x0A,0x42,0x29,0xA5,0x94,0x50,
|
||||
0x41,0x28,0xA1,0xA4,0x10,0x32,0x29,0x29,0xA5,0x54,0x4A,0x05,0xA1,0x84,0x50,0x4A,0xA8,0x20,0x94,0x52,0x4A,0x29,0x05,0x00,0x80,0x1D,0x38,0x00,0x80,0x1D,0x58,0x08,
|
||||
0x85,0x86,0xAC,0x04,0x00,0xF2,0x00,0x00,0x08,0x63,0x94,0x62,0xCC,0x39,0xE7,0x24,0x42,0x4A,0x31,0xE6,0x9C,0x73,0x12,0x21,0xA5,0x18,0x73,0xCE,0x39,0xA9,0x14,0x63,
|
||||
0xCE,0x39,0xE7,0x9C,0x94,0x92,0x31,0xE7,0x9C,0x73,0x4E,0x4A,0xC9,0x98,0x73,0xCE,0x39,0x27,0xA5,0x64,0xCC,0x39,0xE7,0x9C,0x93,0x52,0x3A,0xE7,0x9C,0x73,0xCE,0x49,
|
||||
0x29,0xA5,0x74,0xCE,0x39,0xE7,0xA4,0x94,0x52,0x42,0xE8,0x9C,0x83,0x52,0x4A,0x29,0x9D,0x73,0xCE,0x39,0x01,0x00,0x40,0x05,0x0E,0x00,0x00,0x01,0x36,0x8A,0x6C,0x4E,
|
||||
0x30,0x12,0x54,0x68,0xC8,0x4A,0x00,0x20,0x15,0x00,0xC0,0xE0,0x38,0x96,0xE5,0x79,0x9E,0x27,0x8A,0xA6,0x69,0x49,0x92,0xA6,0x79,0x9E,0x28,0x9A,0xA6,0xAA,0x6A,0x92,
|
||||
0xA4,0x69,0x9E,0x27,0x8A,0xA6,0xA9,0xAA,0x3C,0xCF,0xF3,0x44,0x51,0x14,0x4D,0x53,0x55,0x79,0x9E,0xE7,0x89,0xA2,0x28,0x9A,0xA6,0xAA,0x72,0x5D,0x51,0x14,0x45,0xD3,
|
||||
0x34,0x4D,0x55,0xE5,0xBA,0xA2,0x27,0x8A,0xA6,0xA9,0xAA,0xAE,0x0A,0xD1,0x14,0x45,0xD3,0x54,0x55,0xD7,0x85,0x69,0x8A,0xA2,0x69,0xAA,0xAA,0xEB,0x42,0x96,0x4D,0xD3,
|
||||
0x54,0x5D,0xD7,0x75,0x61,0xDB,0xA6,0xA9,0xAA,0xAA,0xEA,0xBA,0x40,0x75,0x55,0xD5,0x75,0x5D,0x19,0xB8,0xAE,0xAA,0xBA,0xAE,0x2C,0x0B,0x00,0x00,0x4F,0x70,0x00,0x00,
|
||||
0x2A,0xB0,0x61,0x75,0x84,0x93,0xA2,0xB1,0xC0,0x42,0x43,0x56,0x02,0x00,0x19,0x00,0x00,0x84,0x31,0x08,0x29,0x84,0x10,0x52,0x06,0x21,0xA4,0x10,0x42,0x48,0x29,0x85,
|
||||
0x90,0x00,0x00,0x80,0x01,0x07,0x00,0x80,0x00,0x13,0xCA,0x40,0xA1,0x21,0x2B,0x01,0x80,0x54,0x00,0x00,0x80,0x10,0x29,0xA5,0x94,0x52,0x4A,0x29,0x11,0x63,0x52,0x4A,
|
||||
0x29,0xA5,0x94,0x52,0x22,0xE6,0xA4,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,
|
||||
0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,
|
||||
0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0x21,0x84,0x50,0x00,0x20,
|
||||
0x76,0x85,0x03,0xC0,0x4E,0x84,0x0D,0xAB,0x23,0x9C,0x14,0x8D,0x05,0x16,0x1A,0xB2,0x12,0x00,0x08,0x07,0x00,0x00,0x8C,0x41,0x8A,0x31,0x08,0x29,0xB5,0xD6,0x62,0x85,
|
||||
0x90,0x62,0xCE,0x49,0x49,0x29,0xC6,0x18,0x2B,0x84,0x18,0x73,0x8E,0x4A,0x4A,0x2D,0xB6,0x18,0x34,0xE6,0x1C,0x84,0x94,0x5A,0x6B,0x31,0xD7,0xA0,0x31,0xE7,0x20,0xA4,
|
||||
0xD2,0x5A,0x8C,0x35,0x06,0xD5,0x42,0x28,0xA5,0xB5,0x18,0x6B,0xAD,0x35,0xB8,0x14,0x3A,0x2A,0xA9,0xC5,0x18,0x6B,0xAD,0x41,0x08,0x95,0x52,0x8A,0x31,0xC6,0x1A,0x73,
|
||||
0x0D,0x42,0xA8,0x92,0x42,0x6C,0xB1,0xE6,0x9A,0x6B,0x10,0xC2,0xD6,0xD4,0x5A,0xAC,0xB5,0xE7,0x9C,0x83,0x10,0x3A,0xB7,0x14,0x53,0x8C,0x31,0xF7,0x1A,0x84,0x10,0x42,
|
||||
0xC6,0x1A,0x6B,0xCD,0xB9,0xE7,0x20,0x84,0x10,0xB6,0xD6,0x56,0x5B,0xAF,0xB9,0x06,0x21,0x84,0xF0,0x41,0xD6,0x9A,0x73,0x0E,0x3A,0x08,0x21,0x84,0x0F,0xB2,0xD6,0x9A,
|
||||
0x83,0xCE,0x05,0x00,0x98,0x3C,0x38,0x00,0x40,0x25,0xD8,0x38,0xC3,0x4A,0xD2,0x59,0xE1,0x68,0x70,0xA1,0x21,0x2B,0x01,0x80,0xDC,0x00,0x00,0x04,0x21,0xA5,0x18,0x73,
|
||||
0xCE,0x39,0x07,0x21,0x84,0x10,0x42,0x08,0x29,0x42,0x8C,0x31,0xE6,0x9C,0x73,0x10,0x42,0x08,0x21,0x84,0x52,0x52,0x84,0x18,0x63,0xCC,0x39,0xE7,0x20,0x84,0x10,0x42,
|
||||
0x08,0x21,0xA4,0x8C,0x31,0xE6,0x9C,0x73,0x10,0x42,0x08,0xA1,0x94,0x52,0x4A,0x49,0x29,0x65,0xCC,0x39,0xE7,0x20,0x84,0x10,0x42,0x29,0xA5,0x94,0x92,0x52,0xEA,0x9C,
|
||||
0x73,0x10,0x42,0x08,0xA1,0x94,0x52,0x4A,0x29,0x25,0xA5,0xD4,0x39,0xE7,0x20,0x84,0x10,0x42,0x09,0xA5,0x94,0x52,0x4A,0x4A,0xA9,0x73,0x0E,0x42,0x08,0x21,0x84,0x52,
|
||||
0x4A,0x29,0xA5,0x94,0x94,0x52,0x4A,0x9D,0x83,0x10,0x42,0x28,0xA5,0x94,0x52,0x4A,0x29,0x29,0xA5,0x94,0x42,0x08,0x21,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x52,0x4A,
|
||||
0x29,0x85,0x10,0x42,0x28,0xA5,0x94,0x52,0x4A,0x29,0xA5,0xA4,0x94,0x52,0x0A,0x21,0x84,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x49,0x29,0xA5,0x94,0x52,0x08,0xA1,0x94,
|
||||
0x52,0x4A,0x29,0xA5,0x94,0x92,0x52,0x4A,0x29,0xA5,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0x25,0xA5,0x94,0x52,0x4A,0xA5,0x84,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,
|
||||
0x4A,0x29,0xA5,0x94,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x94,0x52,0x4A,0x29,0xA5,0x54,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0x29,0xA5,0x94,0x52,0x4A,0xA9,
|
||||
0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x52,0x4A,0x29,0xA5,0x96,0x52,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0xB4,0xD4,0x5A,0x4A,0x29,0xA5,0x52,0x4A,0x29,0xA5,0x94,0x52,
|
||||
0x4A,0x49,0x29,0xA5,0x94,0x52,0x4A,0x29,0x95,0x52,0x4A,0x29,0xA5,0x94,0x52,0x00,0x00,0xD0,0x81,0x03,0x00,0x40,0x80,0x11,0x95,0x16,0x62,0xA7,0x19,0x57,0x1E,0x81,
|
||||
0x23,0x0A,0x19,0x26,0xA0,0x42,0x43,0x56,0x02,0x00,0x64,0x00,0x00,0x08,0xA2,0x14,0x53,0x4A,0xAD,0x45,0x82,0x2A,0xC9,0x9C,0xC4,0x5E,0x42,0x25,0x15,0x73,0x90,0x5A,
|
||||
0x8A,0x28,0x93,0x4E,0x5A,0x0E,0xAE,0x43,0xD0,0x20,0xE6,0xA4,0x95,0x8A,0x39,0x84,0x94,0x93,0x54,0x3A,0x07,0x95,0x52,0x0C,0x4A,0x2A,0x21,0x75,0x4C,0x29,0x06,0x29,
|
||||
0x96,0x1C,0x42,0xC6,0x98,0x93,0x9C,0x82,0x4A,0xA1,0x63,0x0E,0x00,0x00,0x00,0x41,0x00,0x00,0x81,0x90,0x09,0x04,0x0A,0xA0,0xC0,0x40,0x06,0x00,0x1C,0x20,0x24,0x48,
|
||||
0x01,0x00,0x85,0x05,0x86,0x0E,0x11,0x22,0x40,0x8C,0x02,0x03,0xE3,0xE2,0xD2,0x06,0x00,0x20,0x08,0x91,0x19,0x22,0x11,0xB1,0x18,0x24,0x26,0x54,0x03,0x45,0xC5,0x74,
|
||||
0x00,0xB0,0xB8,0xC0,0x90,0x0F,0x00,0x19,0x1A,0x1B,0x69,0x17,0x17,0xD0,0x65,0x80,0x0B,0xBA,0xB8,0xEB,0x40,0x08,0x41,0x08,0x42,0x10,0x8B,0x03,0x28,0x20,0x01,0x07,
|
||||
0x27,0xDC,0xF0,0xC4,0x1B,0x9E,0x70,0x83,0x13,0x74,0x8A,0x4A,0x1D,0x08,0x00,0x00,0x00,0x00,0xC0,0x03,0x00,0x3C,0x00,0x00,0x24,0x1B,0x40,0x44,0x44,0x34,0x73,0x1C,
|
||||
0x1D,0x1E,0x1F,0x20,0x21,0x22,0x23,0x24,0x25,0x26,0x27,0x28,0x02,0x00,0x00,0x00,0x00,0x80,0x07,0x00,0x1F,0x00,0x00,0x49,0x0A,0x10,0x11,0x11,0xCD,0x1C,0x47,0x87,
|
||||
0xC7,0x07,0x48,0x88,0xC8,0x08,0x49,0x89,0xC9,0x09,0x4A,0x00,0x00,0x20,0x80,0x00,0x00,0x00,0x00,0x00,0x08,0x20,0x00,0x01,0x01,0x01,0x00,0x00,0x00,0x00,0x80,0x00,
|
||||
0x00,0x00,0x00,0x01,0x01,
|
||||
};
|
||||
static const uint8_t vcb_5[] = {
|
||||
0x22,0x42,0x43,0x56,0x01,0x00,0x40,0x00,0x00,0x24,0x73,0x5A,0x32,0x66,0xA9,0x73,0xD8,0x7B,0xEF,0x1D,0x42,0x92,0x19,0xE3,0x1C,0x42,0xD0,0x7B,0xEF,0x99,0x41,0x4C,
|
||||
0x11,0xA2,0x1C,0x42,0xCC,0x6B,0xEC,0x21,0x63,0x92,0x19,0xC3,0xA0,0x42,0x8A,0x63,0xAA,0x81,0xD0,0x90,0x55,0x00,0x00,0x40,0x00,0x00,0x67,0xBD,0x97,0xDA,0x7B,0xCB,
|
||||
0xBD,0xF7,0xDE,0x7B,0x46,0xB9,0x67,0xD4,0x7B,0x69,0xBD,0xF7,0xDE,0x7B,0xC8,0xBD,0x87,0xD6,0x7B,0xCA,0xBD,0xF7,0xDE,0x7B,0xEF,0xBD,0xF7,0xDE,0x7B,0xEF,0xBD,0xF7,
|
||||
0xDE,0x7B,0x25,0xB1,0x67,0x92,0x7B,0x48,0xBD,0xF7,0xDE,0x7B,0xE3,0xB0,0x47,0x8E,0x7B,0x06,0xB9,0xF7,0xDE,0x7B,0x65,0xBD,0x57,0x92,0x7B,0x28,0xB5,0xF7,0xDE,0x7B,
|
||||
0xED,0xBD,0xB7,0xDA,0x7B,0xEE,0xBD,0xF7,0xDE,0x7B,0x03,0xA9,0x47,0x10,0x7B,0x06,0xB9,0xF7,0xDE,0x7B,0xC1,0xA8,0x27,0x8A,0x7A,0xC4,0xAC,0xF7,0xDE,0x7B,0x03,0xB5,
|
||||
0x37,0x0C,0x7B,0xE5,0xB0,0xF7,0xDE,0x7B,0xAA,0xBD,0x97,0x5E,0x7B,0xEA,0xBD,0xF7,0xDE,0x7B,0x86,0xBD,0x87,0x98,0x7B,0x8A,0xBD,0xF7,0xDE,0x7B,0x24,0xB5,0x57,0x92,
|
||||
0x7B,0x28,0xBD,0xF7,0xDE,0x7B,0x86,0xBD,0x57,0xD2,0x7B,0x68,0xBD,0xF7,0xDE,0x7B,0xEA,0xBD,0x97,0xDE,0x7B,0xEC,0xBD,0xF7,0xDE,0x7B,0x20,0x34,0x64,0x15,0x00,0x90,
|
||||
0x00,0x00,0xA0,0xA2,0x28,0x8A,0xA2,0x28,0x0A,0x10,0x1A,0xB2,0x0A,0x00,0xC8,0x00,0x00,0x10,0x40,0x51,0x1C,0xC5,0x71,0x1C,0xC9,0x91,0x1C,0xC9,0xB1,0x1C,0x0B,0x08,
|
||||
0x0D,0x59,0x05,0x00,0x00,0x01,0x00,0x08,0x00,0x00,0xA0,0x48,0x8A,0xA4,0x58,0x8E,0xE5,0x58,0x8E,0x25,0x59,0x92,0x25,0x59,0x92,0x25,0x49,0x92,0xA5,0x79,0xA6,0xEB,
|
||||
0xBA,0xAE,0xEB,0xBA,0xAE,0xEB,0xBA,0x2E,0x10,0x1A,0xB2,0x0A,0x00,0x48,0x00,0x00,0x50,0x51,0x14,0xC5,0x70,0x14,0x07,0x08,0x0D,0x59,0x05,0x00,0x64,0x00,0x00,0x08,
|
||||
0xA0,0x48,0x8A,0xA5,0x68,0x8A,0xA7,0x88,0x8A,0xA9,0xA8,0x8E,0x0A,0x84,0x86,0xAC,0x02,0x00,0x80,0x00,0x00,0x04,0x00,0x00,0x10,0x5C,0x43,0x54,0x4C,0xC7,0x95,0x5C,
|
||||
0xCB,0x35,0x5D,0xD5,0x75,0x5D,0xD7,0x75,0x5D,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x15,0x08,0x0D,0x59,0x05,0x00,0x40,0x00,0x00,0x10,0xD0,
|
||||
0x69,0x86,0xA9,0x06,0x88,0x30,0x23,0x99,0x05,0x42,0x43,0x56,0x01,0x00,0x08,0x00,0x00,0x00,0x11,0xC8,0x30,0xC5,0x80,0xD0,0x90,0x55,0x00,0x00,0x40,0x00,0x00,0x80,
|
||||
0x14,0x49,0x4E,0x92,0x28,0x39,0x29,0xA5,0x94,0xC3,0x20,0x59,0x4C,0x92,0x4A,0x39,0x29,0xA5,0x94,0x47,0x31,0x79,0x54,0x93,0x8C,0x41,0x29,0xA5,0x94,0x52,0x4A,0x29,
|
||||
0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0xC2,0x20,0x59,0x8E,0x92,0x4A,0x39,0x29,0xA5,0x94,0xC4,0x28,0x59,0x8C,0x92,0x2A,0x35,0x29,0xA5,0x94,0x47,0x39,0x79,0x52,0x93,
|
||||
0x8C,0x3D,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x05,0x29,0x79,0xD2,0x92,0xAE,0x41,0x29,0xA5,0x94,0xE4,0x28,0x69,0xD0,0x92,0x4D,0x3D,
|
||||
0x29,0xA5,0x94,0x28,0x45,0x89,0x92,0x93,0xED,0x49,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x0F,0x4A,0xF9,0x20,0x94,0x52,0x4A,0x29,0xA5,
|
||||
0x94,0xAB,0x3D,0xB9,0xD6,0x93,0x52,0x4A,0x29,0xA5,0x94,0x31,0x4A,0x09,0x9F,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x8C,0x20,
|
||||
0x34,0x64,0x15,0x00,0x00,0x04,0x00,0x00,0x18,0x67,0x8D,0x72,0x28,0x3A,0x89,0xCE,0x17,0x67,0x28,0x67,0x9A,0x82,0xA4,0x42,0x69,0x42,0xF7,0x26,0x39,0x4A,0x9E,0x93,
|
||||
0xDC,0x4A,0xCB,0xCD,0xE9,0x26,0x9C,0x73,0xBA,0x39,0xE5,0x9C,0x4F,0xCE,0x39,0x27,0x08,0x0D,0x59,0x05,0x00,0x00,0x02,0x00,0x40,0x08,0x21,0x85,0x14,0x52,0x48,0x21,
|
||||
0x85,0x14,0x52,0x48,0x21,0x85,0x18,0x62,0x88,0x21,0x87,0x9C,0x72,0x0A,0x2A,0xA8,0xA0,0x92,0x4A,0x2A,0xAA,0xA8,0xA2,0xCA,0x2A,0xCB,0x2C,0xB3,0xCC,0x32,0xCB,0x2C,
|
||||
0xB3,0xCC,0x32,0xCB,0x2C,0xB3,0xCE,0x3A,0xEA,0xA8,0xB3,0x90,0x42,0x28,0x29,0xB4,0xD0,0x5A,0x8D,0xB1,0xC6,0x18,0x5B,0xED,0xCD,0x49,0x5B,0x73,0x94,0xD2,0x49,0x29,
|
||||
0xA5,0x94,0x52,0x4A,0xE9,0x9C,0x73,0xCE,0x09,0x42,0x43,0x56,0x01,0x00,0x20,0x00,0x00,0x04,0x42,0x06,0x19,0x64,0x90,0x51,0x46,0x21,0x85,0x18,0x62,0xCA,0x29,0xA7,
|
||||
0x9C,0x82,0x4A,0x2A,0xA9,0x80,0xD0,0x90,0x55,0x00,0x00,0x20,0x00,0x80,0x00,0x00,0x00,0x00,0x51,0x32,0x1D,0xD3,0x11,0x1D,0x51,0x11,0x1D,0xD1,0x11,0x1D,0xD1,0x11,
|
||||
0x1D,0xD1,0xF1,0x1C,0xCF,0xF1,0x24,0x51,0x12,0x2D,0xCF,0x12,0x35,0xD3,0x33,0x45,0xD3,0x34,0x5D,0x55,0x76,0x65,0x59,0x97,0x6D,0xD9,0x76,0x75,0x59,0xB7,0x75,0xD9,
|
||||
0xB7,0x7D,0x5B,0xB7,0x6D,0xDB,0xD7,0x8D,0xDD,0xF8,0x8D,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x86,0x20,0x34,0x64,0x15,0x00,0x00,
|
||||
0x02,0x00,0x00,0x20,0x84,0x10,0x42,0x48,0x21,0x85,0x14,0x52,0x48,0x29,0xA6,0x18,0x73,0x0E,0x3A,0x08,0x21,0x94,0x12,0x08,0x0D,0x59,0x05,0x00,0x00,0x02,0x00,0x08,
|
||||
0x00,0x00,0x00,0x50,0x14,0x47,0x71,0x1C,0xC9,0x91,0x24,0x49,0xB2,0x24,0xCB,0xD2,0x2C,0x4D,0xD3,0x34,0x4D,0xF3,0x44,0x4F,0xF4,0x4C,0x4F,0xF5,0x5C,0x51,0x16,0x6D,
|
||||
0xD1,0xF6,0x5C,0xCF,0x16,0x6D,0xCF,0xF5,0x54,0x4F,0xF5,0x54,0x51,0x35,0x55,0xD3,0x35,0x5D,0xD5,0x75,0x5D,0xD7,0x55,0x5D,0x55,0x56,0x65,0xD7,0xB6,0x6D,0xDB,0xB6,
|
||||
0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0x5B,0x06,0x42,0x43,0x56,0x01,0x00,0x12,0x00,0x00,0x3A,0x92,0x23,0x29,0x92,0x22,0x29,0x92,0xE3,0x38,0x92,0x23,
|
||||
0x49,0x40,0x68,0xC8,0x2A,0x00,0x40,0x06,0x00,0x40,0x00,0x00,0x8A,0xA2,0x28,0x8E,0xE3,0x48,0x8E,0x25,0x59,0x92,0x26,0x89,0x92,0x69,0xA9,0x96,0xAB,0xC9,0x9E,0xEE,
|
||||
0xE9,0xA2,0x2E,0xEA,0x40,0x68,0xC8,0x2A,0x00,0x00,0x10,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x86,0x68,0x88,0x86,0xE8,0x88,0x96,0xA8,0x89,0xA2,0x28,0x8A,0xA2,
|
||||
0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,
|
||||
0xA2,0x28,0x8A,0xA2,0xE8,0x79,0x9E,0xE7,0x79,0x9E,0xE7,0x79,0x9E,0x07,0x84,0x86,0xAC,0x02,0x00,0x24,0x00,0x00,0x74,0x24,0x47,0x72,0x2C,0xC5,0x52,0x24,0x45,0x52,
|
||||
0x2C,0xC7,0x72,0x80,0xD0,0x90,0x55,0x00,0x80,0x0C,0x00,0x80,0x00,0x00,0x1C,0xC3,0x31,0x24,0x45,0x72,0x2C,0xCB,0xB2,0x34,0x4D,0xF3,0x3C,0xCF,0xF3,0x44,0x4F,0x14,
|
||||
0x45,0x51,0x34,0x4D,0xD5,0x54,0x81,0xD0,0x90,0x55,0x00,0x00,0x20,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x45,0xB1,0x1C,0xCB,0x91,0x24,0xCD,0xF1,0x24,0xD1,
|
||||
0x11,0x25,0x51,0x12,0x2D,0x51,0x12,0x35,0x51,0x13,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,
|
||||
0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x11,0x08,0x0D,0x59,0x09,0x00,0x00,0x01,0x00,0xF0,0x9C,0x7B,0xED,0xBD,0xF7,0xD0,0x51,
|
||||
0x29,0x25,0xF7,0x8A,0x30,0xC4,0xA0,0xF7,0x94,0x51,0x28,0xAD,0xF7,0xD0,0x38,0x82,0x9C,0xF7,0x54,0x41,0x63,0x98,0xF7,0x14,0x41,0x42,0x90,0xF5,0x5C,0x51,0x84,0x94,
|
||||
0x06,0x42,0x43,0x56,0x04,0x00,0x51,0x00,0x00,0x80,0x31,0xC8,0x31,0xC4,0x1C,0x72,0xCE,0x51,0xEA,0x24,0x45,0xCE,0x39,0x2A,0x1D,0xA5,0xC6,0x39,0x47,0xA9,0xA3,0xD4,
|
||||
0x51,0x4A,0xB1,0xA6,0x18,0x3B,0x4A,0x25,0xB6,0x14,0x6B,0xE3,0x9C,0xA3,0xD4,0x51,0xCA,0x28,0xA5,0x1A,0x4B,0x8B,0x1D,0xA5,0x54,0x63,0x8A,0xB1,0x00,0x00,0x80,0x00,
|
||||
0x07,0x00,0x80,0x00,0x0B,0xA1,0xD0,0x90,0x15,0x01,0x40,0x14,0x00,0x00,0x62,0x0C,0x52,0x0A,0x29,0x85,0x94,0x52,0xCE,0x29,0xE6,0x90,0x52,0xCA,0x31,0xE5,0x1C,0x52,
|
||||
0x4A,0x39,0xA6,0x98,0x53,0xCE,0x39,0x08,0x1D,0x84,0xCA,0x39,0x06,0x9D,0x83,0x10,0x29,0xA5,0x9C,0x53,0xCC,0x29,0xE7,0x1C,0x84,0xCC,0x41,0xE5,0x9C,0x83,0xD0,0x41,
|
||||
0x28,0x00,0x00,0x20,0xC0,0x01,0x00,0x20,0xC0,0x42,0x28,0x34,0x64,0x45,0x00,0x10,0x27,0x00,0xE0,0x70,0x1C,0xCF,0x93,0x34,0x4D,0x14,0x25,0x4D,0x13,0x45,0x4F,0x14,
|
||||
0x5D,0xD7,0x13,0x4D,0xD5,0x95,0x34,0xCD,0x34,0x35,0x51,0x54,0x4D,0xCD,0x13,0x4D,0xD5,0x54,0x4D,0x5B,0x16,0x4D,0xD3,0x95,0x25,0x4D,0x33,0x4D,0x4D,0xF4,0x54,0x53,
|
||||
0x13,0x45,0x55,0x15,0x4D,0x53,0x76,0x4D,0x53,0x95,0x65,0xCF,0x34,0x75,0xD9,0x54,0x55,0x5D,0x16,0x55,0xD5,0x96,0x65,0x5B,0x16,0x76,0x57,0x96,0x75,0xDD,0x33,0x4D,
|
||||
0xD9,0x16,0x55,0x55,0xB6,0x4D,0xD5,0x95,0x7D,0x57,0x96,0x75,0x5D,0x96,0x6D,0x5D,0x98,0x34,0xCD,0x34,0x35,0x51,0x54,0x55,0x4D,0x14,0x55,0xD7,0x54,0x55,0xDB,0x36,
|
||||
0x55,0xD7,0xB6,0x35,0x51,0x74,0x5D,0x51,0x55,0x65,0x57,0x54,0x55,0x59,0x76,0x65,0xD7,0xB6,0x55,0xD7,0xD5,0x6D,0x4D,0x14,0x5D,0x55,0x54,0x4D,0x59,0x15,0x55,0xD5,
|
||||
0x95,0x55,0x57,0xB5,0x65,0xD5,0x75,0x75,0xDD,0x74,0x5D,0x5F,0x57,0x65,0xD9,0xF7,0x4D,0xD7,0xF5,0x7D,0xDB,0xB6,0x85,0x5F,0xB6,0x6D,0xE1,0x18,0x55,0xD5,0xD6,0x4D,
|
||||
0x57,0xD5,0x75,0xD3,0x75,0x75,0x61,0xD6,0x65,0xE1,0x97,0x6D,0x5D,0x58,0x26,0x4D,0x33,0x4D,0x4D,0x14,0x5D,0x55,0x13,0x45,0x55,0x35,0x55,0x55,0xB7,0x4D,0xD5,0x95,
|
||||
0x6D,0x4D,0x14,0x5D,0x57,0x54,0x55,0xD9,0xF5,0x4C,0xD5,0x75,0x55,0xD7,0xD5,0x75,0x55,0x75,0x6D,0x5B,0x13,0x45,0xD7,0x15,0x55,0x55,0x96,0x45,0x55,0x75,0x5D,0xD5,
|
||||
0x75,0x7D,0x5D,0x75,0x65,0xDB,0x16,0x55,0xD5,0xD7,0x4D,0xD7,0xF5,0x75,0x53,0x75,0x6D,0x5B,0xB6,0x75,0x63,0x98,0x65,0xDB,0xF7,0x4D,0xD7,0xD5,0x75,0x53,0x76,0x75,
|
||||
0x61,0x95,0x5D,0xDD,0x97,0x75,0x5B,0x38,0x6E,0xDD,0xD6,0x85,0xCF,0x34,0x75,0xDD,0x74,0x5D,0x61,0x37,0x5D,0x57,0xF8,0x6D,0x5F,0x17,0x86,0xD9,0xD6,0x7D,0x5F,0x54,
|
||||
0x5D,0xDF,0x57,0x65,0xD9,0x17,0x56,0x59,0xF6,0x7D,0xDD,0xF7,0xB1,0x75,0x5D,0x19,0x46,0x55,0x15,0x7E,0x53,0x56,0x7D,0x5F,0x75,0x5D,0x5F,0xD8,0x7D,0x5D,0x59,0x6E,
|
||||
0x5F,0x67,0xBC,0xB6,0x8E,0xAD,0xFB,0xC6,0x31,0xDB,0xBA,0x30,0xFC,0xC6,0x91,0xEE,0xFB,0xCA,0xB1,0xDA,0x32,0x63,0xF6,0x65,0x61,0x98,0x75,0x1B,0x61,0xD8,0x95,0xE3,
|
||||
0xF6,0x7D,0xA5,0x67,0x9A,0xBA,0x6E,0xBA,0xAA,0xEF,0x9B,0xAA,0x2B,0xFC,0xB6,0xAE,0x0B,0xC7,0xAE,0xFB,0x88,0xAA,0xAA,0xEB,0xAA,0xEC,0xFA,0xC6,0xE9,0xCA,0xC2,0x30,
|
||||
0xEB,0xBA,0xB0,0xEC,0xBA,0xAF,0x1C,0xA3,0xAB,0xF2,0x55,0xD9,0xF5,0x7D,0x55,0x96,0x7D,0xE1,0xF6,0x75,0x65,0xD9,0x75,0xDF,0x38,0x5E,0xDB,0x16,0x8E,0xD9,0xD6,0x8D,
|
||||
0xB2,0xAD,0x1B,0xCB,0x2E,0xFC,0x94,0x5F,0x37,0x86,0xE5,0xB5,0x6D,0x65,0x99,0x75,0x9D,0x31,0x0B,0xBB,0x71,0xEC,0xBE,0x50,0x19,0x96,0xE3,0x28,0x00,0x00,0x60,0xC0,
|
||||
0x01,0x00,0x20,0xC0,0x84,0x32,0x50,0x68,0xC8,0x8A,0x00,0x20,0x4E,0x00,0x80,0x41,0x08,0x42,0xC5,0x14,0x84,0x4A,0x31,0x08,0xA1,0x84,0x96,0x42,0x28,0xA9,0x55,0x8C,
|
||||
0x49,0xC9,0x1C,0x93,0x92,0x31,0x27,0xA5,0x94,0xD2,0x5A,0x28,0x25,0xB5,0x8A,0x31,0x29,0x99,0x63,0x52,0x32,0xC6,0xA4,0x84,0x52,0x5A,0x2A,0xA5,0xB4,0x16,0x4A,0x89,
|
||||
0xAD,0x94,0x12,0x63,0x29,0x25,0xB6,0xD6,0x5A,0xAD,0xAD,0xB5,0x5A,0x43,0x29,0x2D,0x86,0x52,0x62,0x2C,0xA5,0xC4,0xD8,0x5A,0xCB,0xB5,0xC5,0x56,0x6B,0xC4,0x98,0x94,
|
||||
0xCC,0x31,0x29,0x19,0x73,0x52,0x4A,0x29,0xAD,0x95,0x52,0x5A,0xCB,0x9C,0x93,0xD2,0x39,0x27,0xA9,0x73,0x8E,0x4A,0x29,0x29,0xC5,0x52,0x52,0x8B,0x15,0x63,0x52,0x32,
|
||||
0xC7,0xA8,0x74,0xCE,0x49,0x2A,0xA9,0xC4,0x54,0x4A,0x89,0xAD,0xA4,0x12,0x63,0x29,0xA5,0xC5,0x92,0x52,0x8C,0x2D,0xC5,0x54,0x5B,0x8C,0xB5,0x86,0x52,0x5A,0x2C,0xA5,
|
||||
0xC4,0x56,0x4A,0x8A,0xB1,0xC5,0x54,0x5B,0x8C,0x31,0xD7,0x88,0x31,0x29,0x19,0x63,0x52,0x32,0xE6,0xA4,0x94,0x52,0x5A,0x2B,0xA5,0xB4,0x58,0x31,0x26,0xA5,0x73,0x8E,
|
||||
0x4A,0xC6,0x9C,0xA4,0x52,0x4A,0x6B,0xA5,0xA4,0x14,0x33,0xE7,0xA4,0x64,0xCE,0x49,0xEA,0x9C,0xA3,0x52,0x52,0x89,0xAD,0xA4,0x12,0x53,0x28,0x25,0xC6,0x92,0x52,0x8C,
|
||||
0xA5,0x94,0x16,0x63,0x8C,0xB5,0xB6,0x14,0x5B,0x2D,0x25,0xC5,0x58,0x52,0x8A,0xB1,0x94,0x12,0x5B,0x8B,0xB1,0xD6,0x16,0x53,0x6E,0xA1,0x94,0x18,0x4B,0x29,0x31,0x96,
|
||||
0x52,0x62,0x8C,0x31,0xE6,0xDC,0x62,0xAC,0x35,0x94,0x12,0x63,0x29,0x29,0xC6,0x92,0x4A,0x6C,0xB1,0xC5,0x9A,0x63,0x8C,0xB9,0x86,0x52,0x62,0x2C,0xA5,0xC4,0x56,0x4A,
|
||||
0x6A,0x31,0xC6,0x96,0x6B,0x8C,0xB1,0xD6,0x16,0x5B,0xAE,0x2D,0xB5,0x5A,0x5B,0x6C,0xB9,0xD6,0x96,0x5B,0xAF,0x35,0xF7,0xDE,0x5A,0xAB,0x39,0xB5,0x94,0x6B,0x8B,0xB1,
|
||||
0xE6,0x5A,0x5B,0x8F,0xB5,0xE6,0xDE,0x43,0x29,0x31,0x96,0x52,0x62,0x2C,0xA5,0xC4,0xD8,0x62,0xAB,0x35,0xC6,0x98,0x73,0x28,0x25,0xC6,0x92,0x4A,0x6C,0xA5,0x94,0x16,
|
||||
0x63,0x8C,0xB5,0xB6,0x16,0x6B,0x0E,0xA5,0xC4,0x58,0x4A,0x6A,0xB1,0xA4,0x12,0x63,0x8C,0xB1,0xE6,0x18,0x63,0xAE,0xAD,0xB5,0x5C,0x5B,0x6C,0xB9,0xA6,0xD4,0x6A,0xAE,
|
||||
0xB5,0x06,0x5F,0x5B,0x8D,0xC1,0xB5,0x58,0x7B,0x8C,0x31,0xE6,0xD6,0x52,0xAD,0x35,0xD7,0xDE,0x6B,0x6D,0xBD,0x15,0x00,0x00,0x30,0xE0,0x00,0x00,0x10,0x60,0x42,0x19,
|
||||
0x28,0x34,0x64,0x25,0x00,0x10,0x05,0x00,0x40,0x18,0xA3,0x14,0x63,0x10,0x1A,0x64,0x18,0x73,0x0C,0x42,0x63,0x0C,0x63,0xCC,0x41,0xA8,0x18,0x73,0xCE,0x41,0x29,0x15,
|
||||
0x63,0xCE,0x41,0x27,0x25,0x73,0xCC,0x41,0x28,0x29,0x65,0xCC,0x41,0x28,0x25,0xA5,0x10,0x42,0x29,0x29,0xB5,0x16,0x42,0x28,0x25,0xA5,0xD6,0x0A,0x00,0x00,0x28,0x70,
|
||||
0x00,0x00,0x08,0xB0,0x41,0x53,0x62,0x71,0x80,0x42,0x43,0x56,0x02,0x00,0xA9,0x00,0x00,0x06,0xC7,0xB1,0x2C,0xCF,0x13,0x4D,0x55,0xB5,0x6D,0xC7,0x92,0x3C,0x4F,0x14,
|
||||
0x55,0x55,0x55,0x6D,0xDB,0x91,0x24,0xCF,0x13,0x45,0x53,0x55,0x5D,0xDB,0xD6,0x3C,0x4F,0x14,0x55,0x53,0x55,0x5D,0x57,0xD7,0x35,0xCF,0x13,0x45,0x55,0x55,0x55,0xD7,
|
||||
0xD5,0x6D,0xD1,0x34,0x55,0x55,0x55,0x5D,0x57,0x76,0x7D,0x5F,0x34,0x4D,0x55,0x55,0x55,0xD7,0x95,0x65,0xDD,0x37,0x55,0x55,0x55,0x5D,0x57,0x96,0x65,0x59,0xF8,0x4D,
|
||||
0x55,0x75,0x5D,0xD7,0x75,0x65,0xDB,0xF6,0x7D,0xD5,0x75,0x5D,0x57,0x96,0x6D,0xDB,0xB6,0x85,0x61,0x75,0x5D,0xD7,0x95,0x65,0xDB,0xD6,0x6D,0x63,0xD8,0x6D,0x5D,0xD7,
|
||||
0x7D,0x5F,0x38,0x96,0x61,0xA9,0xEB,0xBA,0xAE,0xFB,0xC2,0xEF,0x1B,0x43,0x02,0x00,0xC0,0x13,0x1C,0x00,0x80,0x0A,0x6C,0x58,0x1D,0xE1,0xA4,0x68,0x2C,0xB0,0xD0,0x90,
|
||||
0x95,0x00,0x40,0x06,0x00,0x00,0x61,0x0C,0x42,0x06,0x21,0x85,0x0C,0x42,0x08,0x21,0xA5,0x94,0x42,0x48,0x29,0x25,0x00,0x00,0x60,0xC0,0x01,0x00,0x20,0xC0,0x84,0x32,
|
||||
0x50,0x68,0xC8,0x4A,0x00,0x20,0x0A,0x00,0x00,0x20,0x44,0x4A,0x29,0xA5,0x34,0x52,0x4A,0x29,0xA5,0x94,0x46,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x08,0x21,0x84,0x10,0x42,
|
||||
0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x14,0x00,0x20,0x35,0xE1,
|
||||
0x00,0x20,0xF5,0x60,0x83,0xA6,0xC4,0xE2,0x00,0x85,0x86,0xAC,0x04,0x00,0x52,0x01,0x00,0x00,0x63,0x94,0x62,0xCC,0x31,0x08,0xA5,0x34,0x4C,0x39,0xE7,0x9C,0x84,0x54,
|
||||
0x5A,0x6B,0x14,0x73,0xCE,0x39,0x29,0x29,0xB5,0x96,0x39,0x27,0xA1,0x94,0x96,0x62,0x8B,0x31,0x73,0x0E,0x42,0x29,0x29,0xC5,0x58,0x73,0xE6,0xA0,0x94,0x96,0x6A,0x8C,
|
||||
0xB5,0xE6,0xCC,0x41,0x29,0xA9,0xC5,0x98,0x6B,0xCD,0x9D,0x94,0x96,0x62,0xCC,0x39,0x07,0x9D,0x3B,0x29,0xA9,0xD5,0x58,0x73,0xD0,0x39,0x97,0x94,0x6A,0xAC,0x35,0xE7,
|
||||
0x20,0x7C,0x30,0xA9,0xC5,0x58,0x6B,0xCD,0x3D,0xE7,0xA0,0x5A,0xAC,0xB1,0xF7,0x5E,0x83,0x0F,0x42,0xB5,0x98,0x73,0xCE,0x3D,0xE7,0x9C,0x83,0x01,0x00,0x38,0x0D,0x0E,
|
||||
0x00,0xA0,0x07,0x36,0xAC,0x8E,0x70,0x52,0x34,0x16,0x58,0x68,0xC8,0x4A,0x00,0x20,0x15,0x00,0x80,0x40,0x48,0x29,0xC6,0x9C,0x73,0xCE,0x39,0xA4,0x14,0x63,0xCE,0x39,
|
||||
0xE7,0x1C,0x84,0x48,0x29,0xC6,0x1C,0x73,0xCE,0x39,0xE7,0x14,0x63,0x8C,0x39,0xE7,0x1C,0x84,0x10,0x2A,0xC6,0x18,0x73,0xCE,0x39,0x08,0x21,0x64,0xCE,0x39,0xE7,0x9C,
|
||||
0x83,0x10,0x42,0xC8,0x9C,0x73,0xCE,0x39,0x08,0x21,0x84,0xD0,0x39,0x07,0x1D,0x84,0x10,0x42,0x08,0xA1,0x73,0x0E,0x42,0x08,0x21,0x84,0x10,0x42,0x07,0x21,0x84,0x10,
|
||||
0x42,0x08,0x21,0x84,0x0E,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x14,0x00,0x00,0x58,
|
||||
0xE0,0x00,0x00,0x10,0x60,0xC3,0xEA,0x08,0x27,0x45,0x63,0x81,0x85,0x86,0xAC,0x04,0x00,0x80,0x00,0x00,0x38,0xCD,0x39,0xE8,0x16,0x63,0x62,0x98,0x63,0x8E,0x9A,0x43,
|
||||
0x14,0x62,0xD0,0x73,0x85,0x94,0x52,0x8E,0x9B,0x66,0x94,0x41,0x4E,0x7C,0xA6,0x14,0x42,0x4A,0x53,0xE6,0x18,0x43,0x46,0x4A,0xCC,0x3D,0x99,0x4A,0x02,0x00,0x00,0x20,
|
||||
0x08,0x00,0x10,0x10,0x12,0x00,0x60,0x80,0xA0,0x60,0x06,0x00,0x18,0x1C,0x20,0x7C,0x0E,0x82,0x4E,0x80,0xE0,0x68,0x03,0x00,0x10,0x84,0xC8,0x0C,0x91,0x68,0x58,0x08,
|
||||
0x0E,0x0F,0x2A,0x01,0x22,0x62,0x2A,0x00,0x48,0x4C,0x50,0xC8,0x05,0x80,0x0A,0x8B,0x8B,0xB4,0x8B,0x0B,0xE8,0x32,0xC0,0x05,0x5D,0xDC,0x75,0x20,0x84,0x20,0x04,0x21,
|
||||
0x88,0xC5,0x01,0x14,0x90,0x80,0x83,0x13,0x6E,0x78,0xE2,0x0D,0x4F,0xB8,0xC1,0x09,0x3A,0x45,0xA5,0x0E,0x02,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x1E,0x00,0x00,0x8E,
|
||||
0x0B,0x20,0x22,0xA2,0x39,0x8C,0x0C,0x8D,0x0D,0x8E,0x0E,0x8F,0x0F,0x90,0x90,0x00,0x00,0x00,0x00,0x00,0x90,0x01,0x80,0x0F,0x00,0x80,0x43,0x04,0x88,0x88,0x68,0x0E,
|
||||
0x23,0x43,0x63,0x83,0xA3,0xC3,0xE3,0x03,0x24,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,
|
||||
0x08,
|
||||
};
|
||||
static const uint8_t vcb_6[] = {
|
||||
0x22,0x42,0x43,0x56,0x01,0x00,0x40,0x00,0x00,0x24,0x73,0x5A,0x32,0x66,0xA9,0x73,0xD8,0x7B,0xEF,0x1D,0x42,0x92,0x19,0xE3,0x1C,0x42,0xD0,0x7B,0xEF,0x99,0x41,0x4C,
|
||||
0x11,0xA2,0x1C,0x42,0xCC,0x6B,0xEC,0x21,0x63,0x92,0x19,0xC3,0xA0,0x42,0x8A,0x63,0xAA,0x81,0xD0,0x90,0x55,0x00,0x00,0x40,0x00,0x00,0x67,0xBD,0x97,0xDA,0x7B,0xCB,
|
||||
0xBD,0xF7,0xDE,0x7B,0x46,0xB9,0x67,0xD4,0x7B,0x69,0xBD,0xF7,0xDE,0x7B,0xC8,0xBD,0x87,0xD6,0x7B,0xCA,0xBD,0xF7,0xDE,0x7B,0xEF,0xBD,0xF7,0xDE,0x7B,0xEF,0xBD,0xF7,
|
||||
0xDE,0x7B,0x25,0xB1,0x67,0x92,0x7B,0x48,0xBD,0xF7,0xDE,0x7B,0xE3,0xB0,0x47,0x8E,0x7B,0x06,0xB9,0xF7,0xDE,0x7B,0x65,0xBD,0x57,0x92,0x7B,0x28,0xB5,0xF7,0xDE,0x7B,
|
||||
0xED,0xBD,0xB7,0xDA,0x7B,0xEE,0xBD,0xF7,0xDE,0x7B,0x03,0xA9,0x47,0x10,0x7B,0x06,0xB9,0xF7,0xDE,0x7B,0xC1,0xA8,0x27,0x8A,0x7A,0xC4,0xAC,0xF7,0xDE,0x7B,0x03,0xB5,
|
||||
0x37,0x0C,0x7B,0xE5,0xB0,0xF7,0xDE,0x7B,0xAA,0xBD,0x97,0x5E,0x7B,0xEA,0xBD,0xF7,0xDE,0x7B,0x86,0xBD,0x87,0x98,0x7B,0x8A,0xBD,0xF7,0xDE,0x7B,0x24,0xB5,0x57,0x92,
|
||||
0x7B,0x28,0xBD,0xF7,0xDE,0x7B,0x86,0xBD,0x57,0xD2,0x7B,0x68,0xBD,0xF7,0xDE,0x7B,0xEA,0xBD,0x97,0xDE,0x7B,0xEC,0xBD,0xF7,0xDE,0x7B,0x20,0x34,0x64,0x15,0x00,0x90,
|
||||
0x00,0x00,0xA0,0xA2,0x28,0x8A,0xA2,0x28,0x0A,0x10,0x1A,0xB2,0x0A,0x00,0xC8,0x00,0x00,0x10,0x40,0x51,0x1C,0xC5,0x71,0x1C,0xC9,0x91,0x1C,0xC9,0xB1,0x1C,0x0B,0x08,
|
||||
0x0D,0x59,0x05,0x00,0x00,0x01,0x00,0x08,0x00,0x00,0xA0,0x48,0x8A,0xA4,0x58,0x8E,0xE5,0x58,0x8E,0x25,0x59,0x92,0x25,0x59,0x92,0x25,0x49,0x92,0xA5,0x79,0xA6,0xEB,
|
||||
0xBA,0xAE,0xEB,0xBA,0xAE,0xEB,0xBA,0x2E,0x10,0x1A,0xB2,0x0A,0x00,0x48,0x00,0x00,0x50,0x51,0x14,0xC5,0x70,0x14,0x07,0x08,0x0D,0x59,0x05,0x00,0x64,0x00,0x00,0x08,
|
||||
0xA0,0x48,0x8A,0xA5,0x68,0x8A,0xA7,0x88,0x8A,0xA9,0xA8,0x8E,0x0A,0x84,0x86,0xAC,0x02,0x00,0x80,0x00,0x00,0x04,0x00,0x00,0x10,0x5C,0x43,0x54,0x4C,0xC7,0x95,0x5C,
|
||||
0xCB,0x35,0x5D,0xD5,0x75,0x5D,0xD7,0x75,0x5D,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x55,0x15,0x08,0x0D,0x59,0x05,0x00,0x40,0x00,0x00,0x10,0xD0,
|
||||
0x69,0x86,0xA9,0x06,0x88,0x30,0x23,0x99,0x05,0x42,0x43,0x56,0x01,0x00,0x08,0x00,0x00,0x00,0x11,0xC8,0x30,0xC5,0x80,0xD0,0x90,0x55,0x00,0x00,0x40,0x00,0x00,0x80,
|
||||
0x14,0x49,0x4E,0x92,0x28,0x39,0x29,0xA5,0x94,0xC3,0x20,0x59,0x4C,0x92,0x4A,0x39,0x29,0xA5,0x94,0x47,0x31,0x79,0x54,0x93,0x8C,0x41,0x29,0xA5,0x94,0x52,0x4A,0x29,
|
||||
0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0xC2,0x20,0x59,0x8E,0x92,0x4A,0x39,0x29,0xA5,0x94,0xC4,0x28,0x59,0x8C,0x92,0x2A,0x35,0x29,0xA5,0x94,0x47,0x39,0x79,0x52,0x93,
|
||||
0x8C,0x3D,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x05,0x29,0x79,0xD2,0x92,0xAE,0x41,0x29,0xA5,0x94,0xE4,0x28,0x69,0xD0,0x92,0x4D,0x3D,
|
||||
0x29,0xA5,0x94,0x28,0x45,0x89,0x92,0x93,0xED,0x49,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x0F,0x4A,0xF9,0x20,0x94,0x52,0x4A,0x29,0xA5,
|
||||
0x94,0xAB,0x3D,0xB9,0xD6,0x93,0x52,0x4A,0x29,0xA5,0x94,0x31,0x4A,0x09,0x9F,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x8C,0x20,
|
||||
0x34,0x64,0x15,0x00,0x00,0x04,0x00,0x00,0x18,0x67,0x8D,0x72,0x28,0x3A,0x89,0xCE,0x17,0x67,0x28,0x67,0x9A,0x82,0xA4,0x42,0x69,0x42,0xF7,0x26,0x39,0x4A,0x9E,0x93,
|
||||
0xDC,0x4A,0xCB,0xCD,0xE9,0x26,0x9C,0x73,0xBA,0x39,0xE5,0x9C,0x4F,0xCE,0x39,0x27,0x08,0x0D,0x59,0x05,0x00,0x00,0x02,0x00,0x40,0x08,0x21,0x85,0x14,0x52,0x48,0x21,
|
||||
0x85,0x14,0x52,0x48,0x21,0x85,0x18,0x62,0x88,0x21,0x87,0x9C,0x72,0x0A,0x2A,0xA8,0xA0,0x92,0x4A,0x2A,0xAA,0xA8,0xA2,0xCA,0x2A,0xCB,0x2C,0xB3,0xCC,0x32,0xCB,0x2C,
|
||||
0xB3,0xCC,0x32,0xCB,0x2C,0xB3,0xCE,0x3A,0xEA,0xA8,0xB3,0x90,0x42,0x28,0x29,0xB4,0xD0,0x5A,0x8D,0xB1,0xC6,0x18,0x5B,0xED,0xCD,0x49,0x5B,0x73,0x94,0xD2,0x49,0x29,
|
||||
0xA5,0x94,0x52,0x4A,0xE9,0x9C,0x73,0xCE,0x09,0x42,0x43,0x56,0x01,0x00,0x20,0x00,0x00,0x04,0x42,0x06,0x19,0x64,0x90,0x51,0x46,0x21,0x85,0x18,0x62,0xCA,0x29,0xA7,
|
||||
0x9C,0x82,0x4A,0x2A,0xA9,0x80,0xD0,0x90,0x55,0x00,0x00,0x20,0x00,0x80,0x00,0x00,0x00,0x00,0x51,0x32,0x1D,0xD3,0x11,0x1D,0x51,0x11,0x1D,0xD1,0x11,0x1D,0xD1,0x11,
|
||||
0x1D,0xD1,0xF1,0x1C,0xCF,0xF1,0x24,0x51,0x12,0x2D,0xCF,0x12,0x35,0xD3,0x33,0x45,0xD3,0x34,0x5D,0x55,0x76,0x65,0x59,0x97,0x6D,0xD9,0x76,0x75,0x59,0xB7,0x75,0xD9,
|
||||
0xB7,0x7D,0x5B,0xB7,0x6D,0xDB,0xD7,0x8D,0xDD,0xF8,0x8D,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x86,0x20,0x34,0x64,0x15,0x00,0x00,
|
||||
0x02,0x00,0x00,0x20,0x84,0x10,0x42,0x48,0x21,0x85,0x14,0x52,0x48,0x29,0xA6,0x18,0x73,0x0E,0x3A,0x08,0x21,0x94,0x12,0x08,0x0D,0x59,0x05,0x00,0x00,0x02,0x00,0x08,
|
||||
0x00,0x00,0x00,0x50,0x14,0x47,0x71,0x1C,0xC9,0x91,0x24,0x49,0xB2,0x24,0xCB,0xD2,0x2C,0x4D,0xD3,0x34,0x4D,0xF3,0x44,0x4F,0xF4,0x4C,0x4F,0xF5,0x5C,0x51,0x16,0x6D,
|
||||
0xD1,0xF6,0x5C,0xCF,0x16,0x6D,0xCF,0xF5,0x54,0x4F,0xF5,0x54,0x51,0x35,0x55,0xD3,0x35,0x5D,0xD5,0x75,0x5D,0xD7,0x55,0x5D,0x55,0x56,0x65,0xD7,0xB6,0x6D,0xDB,0xB6,
|
||||
0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0x5B,0x06,0x42,0x43,0x56,0x01,0x00,0x12,0x00,0x00,0x3A,0x92,0x23,0x29,0x92,0x22,0x29,0x92,0xE3,0x38,0x92,0x23,
|
||||
0x49,0x40,0x68,0xC8,0x2A,0x00,0x40,0x06,0x00,0x40,0x00,0x00,0x8A,0xA2,0x28,0x8E,0xE3,0x48,0x8E,0x25,0x59,0x92,0x26,0x89,0x92,0x69,0xA9,0x96,0xAB,0xC9,0x9E,0xEE,
|
||||
0xE9,0xA2,0x2E,0xEA,0x40,0x68,0xC8,0x2A,0x00,0x00,0x10,0x00,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x86,0x68,0x88,0x86,0xE8,0x88,0x96,0xA8,0x89,0xA2,0x28,0x8A,0xA2,
|
||||
0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,
|
||||
0xA2,0x28,0x8A,0xA2,0xE8,0x79,0x9E,0xE7,0x79,0x9E,0xE7,0x79,0x9E,0x07,0x84,0x86,0xAC,0x02,0x00,0x24,0x00,0x00,0x74,0x24,0x47,0x72,0x2C,0xC5,0x52,0x24,0x45,0x52,
|
||||
0x2C,0xC7,0x72,0x80,0xD0,0x90,0x55,0x00,0x80,0x0C,0x00,0x80,0x00,0x00,0x1C,0xC3,0x31,0x24,0x45,0x72,0x2C,0xCB,0xB2,0x34,0x4D,0xF3,0x3C,0xCF,0xF3,0x44,0x4F,0x14,
|
||||
0x45,0x51,0x34,0x4D,0xD5,0x54,0x81,0xD0,0x90,0x55,0x00,0x00,0x20,0x00,0x80,0x00,0x00,0x00,0x00,0x00,0x00,0x14,0x45,0xB1,0x1C,0xCB,0x91,0x24,0xCD,0xF1,0x24,0xD1,
|
||||
0x11,0x25,0x51,0x12,0x2D,0x51,0x12,0x35,0x51,0x13,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,
|
||||
0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x11,0x08,0x0D,0x59,0x09,0x00,0x00,0x01,0x00,0xF0,0x9C,0x7B,0xED,0xBD,0xF7,0xD0,0x51,
|
||||
0x29,0x25,0xF7,0x8A,0x30,0xC4,0xA0,0xF7,0x94,0x51,0x28,0xAD,0xF7,0xD0,0x38,0x82,0x9C,0xF7,0x54,0x41,0x63,0x98,0xF7,0x14,0x41,0x42,0x90,0xF5,0x5C,0x51,0x84,0x94,
|
||||
0x06,0x42,0x43,0x56,0x04,0x00,0x51,0x00,0x00,0x80,0x31,0xC8,0x31,0xC4,0x1C,0x72,0xCE,0x51,0xEA,0x24,0x45,0xCE,0x39,0x2A,0x1D,0xA5,0xC6,0x39,0x47,0xA9,0xA3,0xD4,
|
||||
0x51,0x4A,0xB1,0xA6,0x18,0x3B,0x4A,0x25,0xB6,0x14,0x6B,0xE3,0x9C,0xA3,0xD4,0x51,0xCA,0x28,0xA5,0x1A,0x4B,0x8B,0x1D,0xA5,0x54,0x63,0x8A,0xB1,0x00,0x00,0x80,0x00,
|
||||
0x07,0x00,0x80,0x00,0x0B,0xA1,0xD0,0x90,0x15,0x01,0x40,0x14,0x00,0x00,0x62,0x0C,0x52,0x0A,0x29,0x85,0x94,0x52,0xCE,0x29,0xE6,0x90,0x52,0xCA,0x31,0xE5,0x1C,0x52,
|
||||
0x4A,0x39,0xA6,0x98,0x53,0xCE,0x39,0x08,0x1D,0x84,0xCA,0x39,0x06,0x9D,0x83,0x10,0x29,0xA5,0x9C,0x53,0xCC,0x29,0xE7,0x1C,0x84,0xCC,0x41,0xE5,0x9C,0x83,0xD0,0x41,
|
||||
0x28,0x00,0x00,0x20,0xC0,0x01,0x00,0x20,0xC0,0x42,0x28,0x34,0x64,0x45,0x00,0x10,0x27,0x00,0xE0,0x70,0x1C,0xCF,0x93,0x34,0x4D,0x14,0x25,0x4D,0x13,0x45,0x4F,0x14,
|
||||
0x5D,0xD7,0x13,0x4D,0xD5,0x95,0x34,0xCD,0x34,0x35,0x51,0x54,0x4D,0xCD,0x13,0x4D,0xD5,0x54,0x4D,0x5B,0x16,0x4D,0xD3,0x95,0x25,0x4D,0x33,0x4D,0x4D,0xF4,0x54,0x53,
|
||||
0x13,0x45,0x55,0x15,0x4D,0x53,0x76,0x4D,0x53,0x95,0x65,0xCF,0x34,0x75,0xD9,0x54,0x55,0x5D,0x16,0x55,0xD5,0x96,0x65,0x5B,0x16,0x76,0x57,0x96,0x75,0xDD,0x33,0x4D,
|
||||
0xD9,0x16,0x55,0x55,0xB6,0x4D,0xD5,0x95,0x7D,0x57,0x96,0x75,0x5D,0x96,0x6D,0x5D,0x98,0x34,0xCD,0x34,0x35,0x51,0x54,0x55,0x4D,0x14,0x55,0xD7,0x54,0x55,0xDB,0x36,
|
||||
0x55,0xD7,0xB6,0x35,0x51,0x74,0x5D,0x51,0x55,0x65,0x57,0x54,0x55,0x59,0x76,0x65,0xD7,0xB6,0x55,0xD7,0xD5,0x6D,0x4D,0x14,0x5D,0x55,0x54,0x4D,0x59,0x15,0x55,0xD5,
|
||||
0x95,0x55,0x57,0xB5,0x65,0xD5,0x75,0x75,0xDD,0x74,0x5D,0x5F,0x57,0x65,0xD9,0xF7,0x4D,0xD7,0xF5,0x7D,0xDB,0xB6,0x85,0x5F,0xB6,0x6D,0xE1,0x18,0x55,0xD5,0xD6,0x4D,
|
||||
0x57,0xD5,0x75,0xD3,0x75,0x75,0x61,0xD6,0x65,0xE1,0x97,0x6D,0x5D,0x58,0x26,0x4D,0x33,0x4D,0x4D,0x14,0x5D,0x55,0x13,0x45,0x55,0x35,0x55,0x55,0xB7,0x4D,0xD5,0x95,
|
||||
0x6D,0x4D,0x14,0x5D,0x57,0x54,0x55,0xD9,0xF5,0x4C,0xD5,0x75,0x55,0xD7,0xD5,0x75,0x55,0x75,0x6D,0x5B,0x13,0x45,0xD7,0x15,0x55,0x55,0x96,0x45,0x55,0x75,0x5D,0xD5,
|
||||
0x75,0x7D,0x5D,0x75,0x65,0xDB,0x16,0x55,0xD5,0xD7,0x4D,0xD7,0xF5,0x75,0x53,0x75,0x6D,0x5B,0xB6,0x75,0x63,0x98,0x65,0xDB,0xF7,0x4D,0xD7,0xD5,0x75,0x53,0x76,0x75,
|
||||
0x61,0x95,0x5D,0xDD,0x97,0x75,0x5B,0x38,0x6E,0xDD,0xD6,0x85,0xCF,0x34,0x75,0xDD,0x74,0x5D,0x61,0x37,0x5D,0x57,0xF8,0x6D,0x5F,0x17,0x86,0xD9,0xD6,0x7D,0x5F,0x54,
|
||||
0x5D,0xDF,0x57,0x65,0xD9,0x17,0x56,0x59,0xF6,0x7D,0xDD,0xF7,0xB1,0x75,0x5D,0x19,0x46,0x55,0x15,0x7E,0x53,0x56,0x7D,0x5F,0x75,0x5D,0x5F,0xD8,0x7D,0x5D,0x59,0x6E,
|
||||
0x5F,0x67,0xBC,0xB6,0x8E,0xAD,0xFB,0xC6,0x31,0xDB,0xBA,0x30,0xFC,0xC6,0x91,0xEE,0xFB,0xCA,0xB1,0xDA,0x32,0x63,0xF6,0x65,0x61,0x98,0x75,0x1B,0x61,0xD8,0x95,0xE3,
|
||||
0xF6,0x7D,0xA5,0x67,0x9A,0xBA,0x6E,0xBA,0xAA,0xEF,0x9B,0xAA,0x2B,0xFC,0xB6,0xAE,0x0B,0xC7,0xAE,0xFB,0x88,0xAA,0xAA,0xEB,0xAA,0xEC,0xFA,0xC6,0xE9,0xCA,0xC2,0x30,
|
||||
0xEB,0xBA,0xB0,0xEC,0xBA,0xAF,0x1C,0xA3,0xAB,0xF2,0x55,0xD9,0xF5,0x7D,0x55,0x96,0x7D,0xE1,0xF6,0x75,0x65,0xD9,0x75,0xDF,0x38,0x5E,0xDB,0x16,0x8E,0xD9,0xD6,0x8D,
|
||||
0xB2,0xAD,0x1B,0xCB,0x2E,0xFC,0x94,0x5F,0x37,0x86,0xE5,0xB5,0x6D,0x65,0x99,0x75,0x9D,0x31,0x0B,0xBB,0x71,0xEC,0xBE,0x50,0x19,0x96,0xE3,0x28,0x00,0x00,0x60,0xC0,
|
||||
0x01,0x00,0x20,0xC0,0x84,0x32,0x50,0x68,0xC8,0x8A,0x00,0x20,0x4E,0x00,0x80,0x41,0x08,0x42,0xC5,0x14,0x84,0x4A,0x31,0x08,0xA1,0x84,0x96,0x42,0x28,0xA9,0x55,0x8C,
|
||||
0x49,0xC9,0x1C,0x93,0x92,0x31,0x27,0xA5,0x94,0xD2,0x5A,0x28,0x25,0xB5,0x8A,0x31,0x29,0x99,0x63,0x52,0x32,0xC6,0xA4,0x84,0x52,0x5A,0x2A,0xA5,0xB4,0x16,0x4A,0x89,
|
||||
0xAD,0x94,0x12,0x63,0x29,0x25,0xB6,0xD6,0x5A,0xAD,0xAD,0xB5,0x5A,0x43,0x29,0x2D,0x86,0x52,0x62,0x2C,0xA5,0xC4,0xD8,0x5A,0xCB,0xB5,0xC5,0x56,0x6B,0xC4,0x98,0x94,
|
||||
0xCC,0x31,0x29,0x19,0x73,0x52,0x4A,0x29,0xAD,0x95,0x52,0x5A,0xCB,0x9C,0x93,0xD2,0x39,0x27,0xA9,0x73,0x8E,0x4A,0x29,0x29,0xC5,0x52,0x52,0x8B,0x15,0x63,0x52,0x32,
|
||||
0xC7,0xA8,0x74,0xCE,0x49,0x2A,0xA9,0xC4,0x54,0x4A,0x89,0xAD,0xA4,0x12,0x63,0x29,0xA5,0xC5,0x92,0x52,0x8C,0x2D,0xC5,0x54,0x5B,0x8C,0xB5,0x86,0x52,0x5A,0x2C,0xA5,
|
||||
0xC4,0x56,0x4A,0x8A,0xB1,0xC5,0x54,0x5B,0x8C,0x31,0xD7,0x88,0x31,0x29,0x19,0x63,0x52,0x32,0xE6,0xA4,0x94,0x52,0x5A,0x2B,0xA5,0xB4,0x58,0x31,0x26,0xA5,0x73,0x8E,
|
||||
0x4A,0xC6,0x9C,0xA4,0x52,0x4A,0x6B,0xA5,0xA4,0x14,0x33,0xE7,0xA4,0x64,0xCE,0x49,0xEA,0x9C,0xA3,0x52,0x52,0x89,0xAD,0xA4,0x12,0x53,0x28,0x25,0xC6,0x92,0x52,0x8C,
|
||||
0xA5,0x94,0x16,0x63,0x8C,0xB5,0xB6,0x14,0x5B,0x2D,0x25,0xC5,0x58,0x52,0x8A,0xB1,0x94,0x12,0x5B,0x8B,0xB1,0xD6,0x16,0x53,0x6E,0xA1,0x94,0x18,0x4B,0x29,0x31,0x96,
|
||||
0x52,0x62,0x8C,0x31,0xE6,0xDC,0x62,0xAC,0x35,0x94,0x12,0x63,0x29,0x29,0xC6,0x92,0x4A,0x6C,0xB1,0xC5,0x9A,0x63,0x8C,0xB9,0x86,0x52,0x62,0x2C,0xA5,0xC4,0x56,0x4A,
|
||||
0x6A,0x31,0xC6,0x96,0x6B,0x8C,0xB1,0xD6,0x16,0x5B,0xAE,0x2D,0xB5,0x5A,0x5B,0x6C,0xB9,0xD6,0x96,0x5B,0xAF,0x35,0xF7,0xDE,0x5A,0xAB,0x39,0xB5,0x94,0x6B,0x8B,0xB1,
|
||||
0xE6,0x5A,0x5B,0x8F,0xB5,0xE6,0xDE,0x43,0x29,0x31,0x96,0x52,0x62,0x2C,0xA5,0xC4,0xD8,0x62,0xAB,0x35,0xC6,0x98,0x73,0x28,0x25,0xC6,0x92,0x4A,0x6C,0xA5,0x94,0x16,
|
||||
0x63,0x8C,0xB5,0xB6,0x16,0x6B,0x0E,0xA5,0xC4,0x58,0x4A,0x6A,0xB1,0xA4,0x12,0x63,0x8C,0xB1,0xE6,0x18,0x63,0xAE,0xAD,0xB5,0x5C,0x5B,0x6C,0xB9,0xA6,0xD4,0x6A,0xAE,
|
||||
0xB5,0x06,0x5F,0x5B,0x8D,0xC1,0xB5,0x58,0x7B,0x8C,0x31,0xE6,0xD6,0x52,0xAD,0x35,0xD7,0xDE,0x6B,0x6D,0xBD,0x15,0x00,0x00,0x30,0xE0,0x00,0x00,0x10,0x60,0x42,0x19,
|
||||
0x28,0x34,0x64,0x25,0x00,0x10,0x05,0x00,0x40,0x18,0xA3,0x14,0x63,0x10,0x1A,0x64,0x18,0x73,0x0C,0x42,0x63,0x0C,0x63,0xCC,0x41,0xA8,0x18,0x73,0xCE,0x41,0x29,0x15,
|
||||
0x63,0xCE,0x41,0x27,0x25,0x73,0xCC,0x41,0x28,0x29,0x65,0xCC,0x41,0x28,0x25,0xA5,0x10,0x42,0x29,0x29,0xB5,0x16,0x42,0x28,0x25,0xA5,0xD6,0x0A,0x00,0x00,0x28,0x70,
|
||||
0x00,0x00,0x08,0xB0,0x41,0x53,0x62,0x71,0x80,0x42,0x43,0x56,0x02,0x00,0xA9,0x00,0x00,0x06,0xC7,0xB1,0x2C,0xCF,0x13,0x4D,0x55,0xB5,0x6D,0xC7,0x92,0x3C,0x4F,0x14,
|
||||
0x55,0x55,0x55,0x6D,0xDB,0x91,0x24,0xCF,0x13,0x45,0x53,0x55,0x5D,0xDB,0xD6,0x3C,0x4F,0x14,0x55,0x53,0x55,0x5D,0x57,0xD7,0x35,0xCF,0x13,0x45,0x55,0x55,0x55,0xD7,
|
||||
0xD5,0x6D,0xD1,0x34,0x55,0x55,0x55,0x5D,0x57,0x76,0x7D,0x5F,0x34,0x4D,0x55,0x55,0x55,0xD7,0x95,0x65,0xDD,0x37,0x55,0x55,0x55,0x5D,0x57,0x96,0x65,0x59,0xF8,0x4D,
|
||||
0x55,0x75,0x5D,0xD7,0x75,0x65,0xDB,0xF6,0x7D,0xD5,0x75,0x5D,0x57,0x96,0x6D,0xDB,0xB6,0x85,0x61,0x75,0x5D,0xD7,0x95,0x65,0xDB,0xD6,0x6D,0x63,0xD8,0x6D,0x5D,0xD7,
|
||||
0x7D,0x5F,0x38,0x96,0x61,0xA9,0xEB,0xBA,0xAE,0xFB,0xC2,0xEF,0x1B,0x43,0x02,0x00,0xC0,0x13,0x1C,0x00,0x80,0x0A,0x6C,0x58,0x1D,0xE1,0xA4,0x68,0x2C,0xB0,0xD0,0x90,
|
||||
0x95,0x00,0x40,0x06,0x00,0x00,0x61,0x0C,0x42,0x06,0x21,0x85,0x0C,0x42,0x08,0x21,0xA5,0x94,0x42,0x48,0x29,0x25,0x00,0x00,0x60,0xC0,0x01,0x00,0x20,0xC0,0x84,0x32,
|
||||
0x50,0x68,0xC8,0x4A,0x00,0x20,0x0A,0x00,0x00,0x20,0x44,0x4A,0x29,0xA5,0x34,0x52,0x4A,0x29,0xA5,0x94,0x46,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x08,0x21,0x84,0x10,0x42,
|
||||
0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x14,0x00,0x20,0x35,0xE1,
|
||||
0x00,0x20,0xF5,0x60,0x83,0xA6,0xC4,0xE2,0x00,0x85,0x86,0xAC,0x04,0x00,0x52,0x01,0x00,0x00,0x63,0x94,0x62,0xCC,0x31,0x08,0xA5,0x34,0x4C,0x39,0xE7,0x9C,0x84,0x54,
|
||||
0x5A,0x6B,0x14,0x73,0xCE,0x39,0x29,0x29,0xB5,0x96,0x39,0x27,0xA1,0x94,0x96,0x62,0x8B,0x31,0x73,0x0E,0x42,0x29,0x29,0xC5,0x58,0x73,0xE6,0xA0,0x94,0x96,0x6A,0x8C,
|
||||
0xB5,0xE6,0xCC,0x41,0x29,0xA9,0xC5,0x98,0x6B,0xCD,0x9D,0x94,0x96,0x62,0xCC,0x39,0x07,0x9D,0x3B,0x29,0xA9,0xD5,0x58,0x73,0xD0,0x39,0x97,0x94,0x6A,0xAC,0x35,0xE7,
|
||||
0x20,0x7C,0x30,0xA9,0xC5,0x58,0x6B,0xCD,0x3D,0xE7,0xA0,0x5A,0xAC,0xB1,0xF7,0x5E,0x83,0x0F,0x42,0xB5,0x98,0x73,0xCE,0x3D,0xE7,0x9C,0x83,0x01,0x00,0x38,0x0D,0x0E,
|
||||
0x00,0xA0,0x07,0x36,0xAC,0x8E,0x70,0x52,0x34,0x16,0x58,0x68,0xC8,0x4A,0x00,0x20,0x15,0x00,0x80,0x40,0x48,0x29,0xC6,0x9C,0x73,0xCE,0x39,0xA4,0x14,0x63,0xCE,0x39,
|
||||
0xE7,0x1C,0x84,0x48,0x29,0xC6,0x1C,0x73,0xCE,0x39,0xE7,0x14,0x63,0x8C,0x39,0xE7,0x1C,0x84,0x10,0x2A,0xC6,0x18,0x73,0xCE,0x39,0x08,0x21,0x64,0xCE,0x39,0xE7,0x9C,
|
||||
0x83,0x10,0x42,0xC8,0x9C,0x73,0xCE,0x39,0x08,0x21,0x84,0xD0,0x39,0x07,0x1D,0x84,0x10,0x42,0x08,0xA1,0x73,0x0E,0x42,0x08,0x21,0x84,0x10,0x42,0x07,0x21,0x84,0x10,
|
||||
0x42,0x08,0x21,0x84,0x0E,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x14,0x00,0x00,0x58,
|
||||
0xE0,0x00,0x00,0x10,0x60,0xC3,0xEA,0x08,0x27,0x45,0x63,0x81,0x85,0x86,0xAC,0x04,0x00,0x80,0x00,0x00,0x38,0xCD,0x39,0xE8,0x16,0x63,0x62,0x98,0x63,0x8E,0x9A,0x43,
|
||||
0x14,0x62,0xD0,0x73,0x85,0x94,0x52,0x8E,0x9B,0x66,0x94,0x41,0x4E,0x7C,0xA6,0x14,0x42,0x4A,0x53,0xE6,0x18,0x43,0x46,0x4A,0xCC,0x3D,0x99,0x4A,0x02,0x00,0x00,0x20,
|
||||
0x08,0x00,0x10,0x10,0x12,0x00,0x60,0x80,0xA0,0x60,0x06,0x00,0x18,0x1C,0x20,0x7C,0x0E,0x82,0x4E,0x80,0xE0,0x68,0x03,0x00,0x10,0x84,0xC8,0x0C,0x91,0x68,0x58,0x08,
|
||||
0x0E,0x0F,0x2A,0x01,0x22,0x62,0x2A,0x00,0x48,0x4C,0x50,0xC8,0x05,0x80,0x0A,0x8B,0x8B,0xB4,0x8B,0x0B,0xE8,0x32,0xC0,0x05,0x5D,0xDC,0x75,0x20,0x84,0x20,0x04,0x21,
|
||||
0x88,0xC5,0x01,0x14,0x90,0x80,0x83,0x13,0x6E,0x78,0xE2,0x0D,0x4F,0xB8,0xC1,0x09,0x3A,0x45,0xA5,0x0E,0x02,0x00,0x00,0x00,0x00,0xC0,0x00,0x00,0x1E,0x00,0x00,0x8E,
|
||||
0x0B,0x20,0x22,0xA2,0x39,0x8C,0x0C,0x8D,0x0D,0x8E,0x0E,0x8F,0x0F,0x90,0x90,0x00,0x00,0x00,0x00,0x00,0x70,0x01,0x80,0x0F,0x00,0x80,0x43,0x04,0x88,0x88,0x68,0x0E,
|
||||
0x23,0x43,0x63,0x83,0xA3,0xC3,0xE3,0x03,0x24,0x24,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x08,
|
||||
0x08,
|
||||
};
|
||||
static const uint8_t vcb_7[] = {
|
||||
0x1F,0x42,0x43,0x56,0x01,0x00,0x00,0x01,0x00,0x9C,0x73,0x9A,0x31,0x87,0x99,0x62,0x94,0x52,0x89,0x21,0x94,0xDE,0x39,0x68,0x19,0x63,0x94,0x52,0x69,0x29,0xA5,0x5A,
|
||||
0x4A,0xA9,0xA1,0x83,0x16,0x6B,0xAB,0xBD,0xF7,0xDE,0x7B,0xEF,0xBD,0xF7,0xDE,0x7B,0xEF,0x1D,0x73,0x94,0x31,0x46,0x95,0x52,0x52,0x4A,0xA9,0x9D,0x73,0x96,0x31,0x47,
|
||||
0x15,0x63,0x52,0x4A,0x89,0xA5,0x94,0x56,0x42,0x68,0x21,0x84,0xD6,0x62,0xAB,0xBD,0xF7,0xDE,0x6B,0xEF,0xB5,0xF6,0xDE,0x7B,0xEF,0x99,0x42,0x4C,0x29,0xA4,0x14,0x42,
|
||||
0x08,0x4A,0x28,0x1D,0x53,0x8C,0x29,0xA4,0x94,0x42,0x4A,0x4A,0x08,0x25,0x64,0x0E,0x3A,0xC6,0x1C,0x53,0x8C,0x52,0x09,0x3D,0xD6,0x5E,0x6B,0xCC,0xBD,0xB6,0xD8,0x7B,
|
||||
0xED,0xA1,0x63,0xCE,0x39,0xE6,0x1C,0x53,0x4C,0x4A,0x68,0x21,0x74,0x0E,0x3A,0xE6,0x9C,0x53,0x4C,0x4A,0x68,0xA9,0x84,0x52,0x42,0x06,0xA1,0x53,0xD0,0x52,0x89,0xAD,
|
||||
0xF7,0xDE,0x62,0xEB,0xB9,0xA5,0xDA,0x7B,0xEF,0x81,0xD0,0x90,0x55,0x00,0x00,0x01,0x00,0xC0,0x40,0x10,0x1A,0xB2,0x0A,0x00,0x50,0x00,0x00,0x10,0x8A,0xA1,0x18,0x8A,
|
||||
0x02,0x84,0x86,0xAC,0x02,0x00,0x32,0x00,0x00,0x04,0xE0,0x28,0x8E,0xE3,0x38,0x8E,0xE2,0x38,0x92,0x62,0x39,0x16,0x10,0x1A,0xB2,0x0A,0x00,0x00,0x02,0x00,0x10,0x00,
|
||||
0x00,0xC0,0x90,0x0C,0x4B,0xB1,0x14,0xCD,0xD1,0x24,0x4D,0xD2,0x2C,0xCF,0x13,0x4D,0xD3,0x37,0x7D,0xD3,0x36,0x6D,0x55,0xD7,0x75,0x5D,0xD7,0x75,0x5D,0xD7,0x75,0x20,
|
||||
0x34,0x64,0x15,0x00,0x00,0x01,0x00,0x40,0x40,0xA7,0x19,0xA6,0x1A,0x20,0xC2,0x8C,0x64,0x16,0x08,0x0D,0x59,0x05,0x00,0x20,0x00,0x00,0x00,0x44,0x20,0xC3,0x14,0x03,
|
||||
0x42,0x43,0x56,0x01,0x00,0x00,0x01,0x00,0x00,0x52,0x24,0x39,0x49,0xA2,0xE4,0xA4,0x94,0x52,0x0E,0x83,0x64,0x31,0x49,0x2A,0xE5,0xA4,0x94,0x52,0x1E,0xC5,0xE4,0x51,
|
||||
0x4D,0x32,0x06,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x0A,0x83,0x64,0x39,0x4A,0x2A,0xE5,0xA4,0x94,0x52,0x12,0xA3,0x64,0x31,0x4A,0xAA,
|
||||
0xD4,0xA4,0x94,0x52,0x1E,0xE5,0xE4,0x49,0x4D,0x32,0xF6,0xA4,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x16,0xA4,0xE4,0x49,0x4B,0xBA,0x06,0xA5,
|
||||
0x94,0x52,0x92,0xA3,0xA4,0x41,0x4B,0x36,0xF5,0xA4,0x94,0x52,0xA2,0x14,0x25,0x4A,0x4E,0xB6,0x27,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,
|
||||
0x3E,0x28,0xE5,0x83,0x50,0x4A,0x29,0xA5,0x94,0x52,0xAE,0xF6,0xE4,0x5A,0x4F,0x4A,0x29,0xA5,0x94,0x52,0xC6,0x28,0x25,0x7C,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,
|
||||
0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x32,0x82,0xD0,0x90,0x55,0x00,0x00,0x10,0x00,0x00,0x60,0x9C,0x35,0xCA,0xA1,0xE8,0x24,0x3A,0x5F,0x9C,0xA1,0x9C,0x69,0x0A,0x92,
|
||||
0x0A,0xA5,0x09,0xDD,0x9B,0xE4,0x28,0x79,0x4E,0x72,0x2B,0x2D,0x37,0xA7,0x9B,0x70,0xCE,0xE9,0xE6,0x94,0x73,0x3E,0x39,0xE7,0x9C,0x20,0x34,0x64,0x15,0x00,0x00,0x08,
|
||||
0x00,0x00,0x21,0x84,0x14,0x52,0x48,0x21,0x85,0x14,0x52,0x48,0x21,0x85,0x14,0x62,0x88,0x21,0x86,0x1C,0x72,0xCA,0x29,0xA8,0xA0,0x82,0x4A,0x2A,0xA9,0xA8,0xA2,0x8A,
|
||||
0x2A,0xAB,0x2C,0xB3,0xCC,0x32,0xCB,0x2C,0xB3,0xCC,0x32,0xCB,0x2C,0xB3,0xCC,0x3A,0xEB,0xA8,0xA3,0xCE,0x42,0x0A,0xA1,0xA4,0xD0,0x42,0x6B,0x35,0xC6,0x1A,0x63,0x6C,
|
||||
0xB5,0x37,0x27,0x6D,0xCD,0x51,0x4A,0x27,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x73,0xCE,0x39,0x27,0x08,0x0D,0x59,0x05,0x00,0x80,0x00,0x00,0x10,0x08,0x19,0x64,0x90,0x41,
|
||||
0x46,0x19,0x85,0x14,0x62,0x88,0x29,0xA7,0x9C,0x72,0x0A,0x2A,0xA9,0xA4,0x02,0x42,0x43,0x56,0x01,0x00,0x80,0x00,0x00,0x02,0x00,0x00,0x00,0x44,0xC9,0x74,0x4C,0x47,
|
||||
0x74,0x44,0x45,0x74,0x44,0x47,0x74,0x44,0x47,0x74,0x44,0xC7,0x73,0x3C,0xC7,0x93,0x44,0x49,0xB4,0x3C,0x4B,0xD4,0x4C,0xCF,0x14,0x4D,0xD3,0x74,0x55,0xD9,0x95,0x65,
|
||||
0x5D,0xB6,0x65,0xDB,0xD5,0x65,0xDD,0xD6,0x65,0xDF,0xF6,0x6D,0xDD,0xB6,0x6D,0x5F,0x37,0x76,0xE3,0x37,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,0x8E,0xE3,0x38,
|
||||
0x8E,0xE3,0x18,0x82,0xD0,0x90,0x55,0x00,0x00,0x08,0x00,0x00,0x80,0x10,0x42,0x08,0x21,0x85,0x14,0x52,0x48,0x21,0xA5,0x98,0x62,0xCC,0x39,0xE8,0x20,0x84,0x50,0x4A,
|
||||
0x20,0x34,0x64,0x15,0x00,0x00,0x08,0x00,0x20,0x00,0x00,0x00,0x40,0x51,0x1C,0xC5,0x71,0x24,0x47,0x92,0x24,0xC9,0x92,0x2C,0x4B,0xB3,0x34,0x4D,0xD3,0x34,0xCD,0x13,
|
||||
0x3D,0xD1,0x33,0x3D,0xD5,0x73,0x45,0x59,0xB4,0x45,0xDB,0x73,0x3D,0x5B,0xB4,0x3D,0xD7,0x53,0x3D,0xD5,0x53,0x45,0xD5,0x54,0x4D,0xD7,0x74,0x55,0xD7,0x75,0x5D,0x57,
|
||||
0x75,0x55,0x59,0x95,0x5D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0xDB,0xB6,0x6D,0x19,0x08,0x0D,0x59,0x05,0x00,0x48,0x00,0x00,0xE8,0x48,0x8E,
|
||||
0xA4,0x48,0x8A,0xA4,0x48,0x8E,0xE3,0x48,0x8E,0x24,0x01,0xA1,0x21,0xAB,0x00,0x00,0x19,0x00,0x00,0x01,0x00,0x28,0x8A,0xA2,0x38,0x8E,0x23,0x39,0x96,0x64,0x49,0x9A,
|
||||
0x24,0x4A,0xA6,0xA5,0x5A,0xAE,0x26,0x7B,0xBA,0xA7,0x8B,0xBA,0xA8,0x03,0xA1,0x21,0xAB,0x00,0x00,0x40,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x18,0xA2,0x21,0x1A,
|
||||
0xA2,0x23,0x5A,0xA2,0x26,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,
|
||||
0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0x28,0x8A,0xA2,0xE7,0x79,0x9E,0xE7,0x79,0x9E,0xE7,0x79,0x1E,0x10,0x1A,0xB2,0x0A,0x00,0x90,0x00,0x00,0xD0,
|
||||
0x91,0x1C,0xC9,0xB1,0x14,0x4B,0x91,0x14,0x49,0xB1,0x1C,0xCB,0x01,0x42,0x43,0x56,0x01,0x00,0x32,0x00,0x00,0x02,0x00,0x70,0x0C,0xC7,0x90,0x14,0xC9,0xB1,0x2C,0xCB,
|
||||
0xD2,0x34,0xCD,0xF3,0x3C,0xCF,0x13,0x3D,0x51,0x14,0x45,0xD1,0x34,0x55,0x53,0x05,0x42,0x43,0x56,0x01,0x00,0x80,0x00,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x50,0x14,
|
||||
0xC5,0x72,0x2C,0x47,0x92,0x34,0xC7,0x93,0x44,0x47,0x94,0x44,0x49,0xB4,0x44,0x49,0xD4,0x44,0x4D,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,
|
||||
0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x51,0x14,0x45,0x20,0x34,0x64,0x25,0x00,0x00,0x04,
|
||||
0x00,0x40,0x49,0x6A,0xB1,0xB5,0xD6,0x28,0x05,0xA1,0xA4,0x98,0x18,0xC2,0x94,0x93,0x1C,0x31,0x06,0x1D,0xA4,0x5E,0x31,0xE4,0x10,0x93,0x9E,0x39,0x06,0x15,0x93,0x5E,
|
||||
0x2A,0x82,0x0C,0x62,0x1E,0x3B,0xC4,0x14,0x93,0x1C,0x08,0x0D,0x59,0x11,0x00,0x44,0x01,0x00,0x00,0xC6,0x20,0xC7,0x10,0x73,0xC8,0x39,0x47,0xA9,0x93,0x14,0x39,0xE7,
|
||||
0xA4,0x74,0x94,0x1A,0xE7,0x1C,0xA5,0x8E,0x52,0x47,0x29,0xC5,0x9A,0x62,0xCD,0x28,0x95,0xDA,0x52,0xAC,0x8D,0x73,0x8E,0x52,0x47,0xA9,0xA3,0x94,0x6A,0x2C,0x2D,0x76,
|
||||
0xD4,0x52,0xAD,0xA9,0xC6,0x02,0x00,0x00,0x02,0x1C,0x00,0x00,0x02,0x2C,0x84,0x42,0x43,0x56,0x04,0x00,0x51,0x00,0x00,0x84,0x31,0x48,0x29,0xA4,0x14,0x62,0x8A,0x39,
|
||||
0xA7,0x98,0x43,0x8A,0x29,0xC7,0x98,0x73,0x88,0x31,0xE6,0x1C,0x73,0x8E,0x39,0xE7,0xA0,0x74,0x52,0x2A,0xE7,0x98,0x74,0x4E,0x4A,0xC4,0x18,0x73,0x8E,0x39,0xA7,0x9C,
|
||||
0x73,0x52,0x32,0x27,0x95,0x73,0x4E,0x4A,0x27,0xA1,0x00,0x00,0x80,0x00,0x07,0x00,0x80,0x00,0x0B,0xA1,0xD0,0x90,0x15,0x01,0x40,0x9C,0x00,0x80,0x41,0x92,0x3C,0x4F,
|
||||
0xD2,0x34,0x51,0x94,0x34,0x4F,0x14,0x3D,0x53,0x74,0x55,0x4F,0x34,0x55,0xD7,0xF2,0x3C,0xD3,0xF4,0x4C,0x53,0x55,0x3D,0xD1,0x54,0x55,0xD3,0x55,0x65,0xD9,0x54,0x55,
|
||||
0x59,0xB6,0x3C,0xCF,0x34,0x3D,0x53,0x54,0x55,0xCF,0x34,0x55,0xD5,0x54,0x55,0x59,0x36,0x55,0x55,0x96,0x45,0x55,0xD5,0x6D,0xD3,0x55,0x75,0xDB,0x74,0x55,0xDD,0x76,
|
||||
0x6D,0xD9,0xD7,0x5D,0x59,0x16,0x76,0x51,0x55,0x6D,0xDB,0x54,0x5D,0x5B,0x37,0x55,0xD7,0x16,0x5E,0xD9,0xD6,0x7D,0x59,0xB6,0x75,0x61,0xF2,0x3C,0x55,0xF5,0x4C,0xD3,
|
||||
0x75,0x3D,0xD3,0x74,0x5D,0xD5,0x75,0x75,0x5B,0x75,0x5D,0x5B,0xF7,0x4C,0x53,0x76,0x4D,0xD7,0x95,0x65,0xD3,0x75,0x6D,0xDB,0x95,0x65,0x5D,0x57,0x65,0x59,0xF7,0x35,
|
||||
0xD3,0x74,0x5D,0xD1,0x55,0x6D,0xD9,0x74,0x5D,0xD9,0x76,0x65,0x57,0xD7,0x5D,0x59,0xF6,0x85,0xD3,0x75,0x75,0xDF,0x95,0x65,0x61,0x57,0x65,0x59,0xF8,0x75,0x5D,0x17,
|
||||
0x86,0x59,0xF7,0x8D,0x63,0x74,0x5D,0x5D,0x58,0x65,0xD7,0xF7,0x55,0x59,0xF6,0x8D,0x5B,0xB7,0x7D,0x5F,0xD6,0x75,0xE1,0x98,0x3C,0x4F,0x55,0x3D,0xD3,0x74,0x5D,0xCF,
|
||||
0x34,0x5D,0xD7,0x74,0x5D,0x5D,0x57,0x5D,0xD7,0xD6,0x35,0xD3,0x74,0x5D,0xD3,0x75,0x6D,0x5B,0x54,0x5D,0x59,0x76,0x65,0xD9,0xF7,0x5D,0x57,0xD6,0x75,0xCF,0x34,0x5D,
|
||||
0xD9,0x74,0x5D,0xD9,0x36,0x5D,0x57,0x96,0x5D,0x59,0xF6,0x7D,0x57,0x96,0x75,0xDD,0x74,0x5D,0xDD,0x57,0x65,0x59,0xF8,0x55,0x57,0x16,0x7E,0x59,0xD7,0x8D,0xE5,0xB6,
|
||||
0x6D,0xE1,0x37,0x5D,0x57,0xD7,0x55,0x59,0xD6,0x7D,0x55,0x96,0x75,0x61,0xD6,0x75,0xE3,0xB9,0x75,0x5D,0x18,0x3E,0x55,0xD5,0x7D,0x53,0x76,0x85,0xDF,0x74,0x65,0x5F,
|
||||
0xD8,0x7D,0xDD,0x59,0x6E,0xDD,0x37,0x96,0xD1,0x75,0x75,0x61,0x95,0x6D,0xE3,0x58,0x65,0x5B,0x18,0x7E,0xE1,0x58,0x96,0xDD,0x37,0x96,0x67,0x74,0x5D,0xDF,0x57,0x6D,
|
||||
0x57,0x18,0x56,0x59,0xF6,0x95,0xDD,0xD7,0x9D,0x65,0xD7,0x75,0x65,0x78,0x6D,0xDB,0x58,0x6E,0x5D,0x57,0x8E,0x59,0xD7,0x8D,0x61,0x38,0x96,0xA7,0xEE,0x0B,0x4F,0x57,
|
||||
0xB7,0x85,0x63,0xF6,0x6D,0xE7,0x99,0x7D,0x5D,0x39,0x7E,0x67,0x78,0x96,0x5F,0xF8,0x29,0x9F,0xAA,0xEA,0xBA,0xE9,0xBA,0xC2,0x70,0xBA,0xB2,0xEF,0xCB,0xB6,0x2E,0x0C,
|
||||
0xBB,0x2F,0x2C,0xCB,0xE8,0xBA,0xBE,0xB0,0xCA,0xB2,0xF1,0xAB,0xB2,0xEC,0x0B,0xB7,0xEE,0x2B,0xC7,0xEE,0x0B,0xC3,0x31,0xBA,0xAE,0xF0,0xAB,0xB6,0xEC,0xFB,0xAE,0x2D,
|
||||
0x0B,0xC7,0xED,0xEB,0xC6,0x32,0x0C,0xC3,0x72,0xBC,0xB6,0xAD,0x0C,0xB3,0xAE,0x0B,0x65,0xDB,0x47,0xF7,0x7D,0xA5,0xEF,0x2B,0x4B,0x57,0xB7,0x95,0x63,0xD6,0x75,0xA5,
|
||||
0xED,0xEB,0x94,0x5D,0x18,0x2A,0xC3,0x31,0x54,0x06,0x00,0x00,0x0C,0x38,0x00,0x00,0x04,0x98,0x50,0x06,0x0A,0x0D,0x59,0x11,0x00,0xC4,0x09,0x00,0x30,0x08,0x39,0x87,
|
||||
0x98,0x82,0x10,0x29,0x06,0x21,0x84,0x90,0x52,0x08,0x21,0xA5,0x88,0x31,0x08,0x99,0x73,0x52,0x2A,0xE6,0xA0,0x94,0x52,0x52,0x0B,0xA5,0xA4,0x16,0x31,0x06,0xA1,0x72,
|
||||
0x4C,0x4A,0xE6,0x9C,0x94,0x50,0x4A,0x4B,0xA5,0x94,0x96,0x42,0x29,0xAD,0x95,0x54,0x62,0x0C,0xA5,0xC4,0xD8,0x5A,0xAB,0x35,0xB5,0x56,0x6B,0x28,0xA5,0xB5,0x50,0x4A,
|
||||
0x8C,0xA5,0x94,0x16,0x53,0x6B,0xB5,0xB6,0xD8,0x6A,0x8D,0x18,0x93,0x92,0x39,0x27,0x25,0x73,0x4E,0x4A,0x29,0x25,0xB6,0x52,0x4A,0x6B,0x99,0x73,0x54,0x3A,0x07,0x25,
|
||||
0x75,0x10,0x52,0x2A,0x25,0xB5,0x58,0x52,0x8A,0xB5,0x72,0x4E,0x4A,0x06,0x1D,0x95,0x0E,0x42,0x4A,0x25,0x95,0x98,0x4A,0x4A,0x31,0x96,0x54,0x62,0x2C,0x25,0xC5,0x5A,
|
||||
0x52,0xAA,0xB1,0xA5,0xD8,0x6A,0x8B,0x31,0xE7,0x50,0x4A,0x8C,0x25,0x95,0x18,0x4B,0x4A,0xB1,0xB6,0x98,0x72,0x6B,0x31,0xD6,0x1C,0x31,0x26,0x21,0x73,0x4E,0x4A,0xE6,
|
||||
0x9C,0x94,0x52,0x4A,0x6B,0xA5,0x94,0x16,0x2B,0xE7,0xA4,0x74,0x10,0x52,0xCA,0x1C,0x94,0x54,0x52,0x8A,0xB1,0x94,0x94,0x6A,0xE6,0x9C,0x94,0x0E,0x42,0x4A,0x1D,0x74,
|
||||
0x54,0x4A,0x4A,0x31,0x96,0x54,0x62,0x0A,0xA5,0xC4,0x58,0x52,0xAA,0xB1,0x94,0xD4,0x62,0x8C,0x31,0xD7,0x96,0x62,0xCB,0xA1,0xA4,0x18,0x4B,0x4A,0xB1,0x96,0x54,0x62,
|
||||
0x6C,0x31,0xE6,0xDC,0x62,0xCA,0xAD,0x93,0x12,0x5B,0x49,0x29,0xC6,0x50,0x52,0x8C,0x31,0xC6,0x9C,0x5B,0x8C,0x39,0x87,0x52,0x62,0x2C,0x29,0xC5,0x5A,0x52,0xAA,0x31,
|
||||
0xC6,0x5A,0x73,0x8C,0xB1,0xE6,0x50,0x4A,0x8C,0x25,0x95,0x1A,0x4B,0x4A,0xB1,0xC6,0x1A,0x73,0x6D,0x31,0xD6,0x9C,0x62,0xCC,0x35,0xA5,0x58,0x73,0xAB,0x31,0xE7,0xD8,
|
||||
0x72,0xEB,0xB5,0xE6,0xE0,0x53,0x6B,0x35,0xA7,0x98,0x72,0x6D,0x31,0xE6,0x5C,0x6B,0x0B,0xB2,0xE6,0x5C,0x7C,0x27,0x25,0xB6,0x50,0x4A,0x8C,0xA5,0xA4,0x18,0x5B,0x8C,
|
||||
0xB5,0xB6,0x18,0x73,0x0E,0xA5,0xC4,0x58,0x52,0xAA,0xB1,0x94,0x14,0x6B,0x8B,0x31,0xE8,0xD6,0x62,0xED,0xA1,0x94,0x18,0x4B,0x4A,0x31,0x96,0x54,0x6A,0x8C,0x31,0xD6,
|
||||
0x1C,0x6B,0xCC,0x39,0xC5,0x56,0x6B,0x8B,0xB1,0xD7,0xD4,0x62,0xCE,0x35,0xF7,0x60,0x6C,0xCB,0xB5,0xA7,0x16,0x6B,0x6E,0x31,0xE6,0x9E,0x62,0xCA,0xB5,0xF6,0xDA,0x83,
|
||||
0xCD,0xAD,0xB7,0x02,0x00,0x00,0x06,0x1C,0x00,0x00,0x02,0x4C,0x28,0x03,0x85,0x86,0xAC,0x04,0x00,0xA2,0x00,0x00,0x00,0x63,0x18,0x73,0x0E,0x42,0xA3,0x90,0x73,0xCE,
|
||||
0x49,0x69,0x90,0x72,0xCE,0x39,0x29,0x99,0x73,0x10,0x42,0x48,0x29,0x73,0x0E,0x42,0x08,0x29,0x75,0xCE,0x49,0x28,0xA9,0xB5,0xCE,0x39,0x08,0x29,0xB5,0x16,0x4A,0x49,
|
||||
0xA9,0xB5,0x18,0x43,0x29,0x29,0xB5,0x16,0x63,0x01,0x00,0x00,0x05,0x0E,0x00,0x00,0x01,0x36,0x68,0x4A,0x2C,0x0E,0x50,0x68,0xC8,0x4A,0x00,0x20,0x15,0x00,0xC0,0xE0,
|
||||
0x38,0x96,0xE5,0x79,0xA6,0x68,0x9A,0xB6,0xED,0x58,0x92,0xE7,0x89,0xA2,0x69,0xAA,0xAA,0x6D,0x3B,0x92,0xE5,0x79,0xA2,0x68,0x9A,0xAA,0x6A,0xDB,0x9A,0xE7,0x89,0xA2,
|
||||
0x69,0xAA,0xAA,0xEB,0xEA,0xBA,0xE6,0x79,0xA2,0x68,0x9A,0xAA,0xEA,0xBA,0xB6,0x2E,0x8A,0xA2,0x69,0xAA,0xAA,0xAB,0xBA,0xAE,0xEE,0x8B,0xA2,0x68,0x9A,0xAA,0xAA,0xAA,
|
||||
0xAE,0xAB,0xEB,0xA6,0x69,0xAA,0xAA,0xAB,0xBA,0xAE,0x2C,0xFB,0xBE,0x69,0x9A,0xAA,0xEA,0xBA,0xAE,0x2B,0xCB,0xBE,0xB0,0xAA,0xAE,0xEB,0xCA,0xB2,0x2D,0xDB,0xB6,0x31,
|
||||
0xAC,0xAA,0xEA,0xBA,0xAE,0x2B,0xDB,0xB6,0x6D,0x1C,0xB7,0x6D,0xEB,0xBA,0xEE,0xFB,0xBE,0x30,0x54,0x6E,0xDB,0xD6,0x75,0x5F,0xF8,0x85,0x61,0x58,0x0A,0x00,0x00,0x4F,
|
||||
0x70,0x00,0x00,0x2A,0xB0,0x61,0x75,0x84,0x93,0xA2,0xB1,0xC0,0x42,0x43,0x56,0x02,0x00,0x19,0x00,0x00,0x84,0x31,0x08,0x19,0x84,0x10,0x32,0x08,0x21,0x84,0x94,0x52,
|
||||
0x0A,0x29,0xA5,0x94,0x00,0x00,0x80,0x01,0x07,0x00,0x80,0x00,0x13,0xCA,0x40,0xA1,0x21,0x2B,0x02,0x80,0x38,0x01,0x00,0x00,0x21,0x4A,0x21,0xA5,0x94,0x52,0x4A,0x29,
|
||||
0xA5,0x94,0x52,0x4A,0x29,0xA5,0xD4,0x51,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x42,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,
|
||||
0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,
|
||||
0x29,0xA5,0x94,0x52,0x4A,0x1D,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,
|
||||
0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,
|
||||
0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x4A,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,
|
||||
0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,
|
||||
0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x2A,
|
||||
0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,
|
||||
0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,
|
||||
0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,
|
||||
0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,
|
||||
0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x4A,0x29,0xA5,0x94,0x52,0x00,0x80,
|
||||
0x54,0x84,0x03,0x80,0xD4,0x83,0x09,0x65,0xA0,0xD0,0x90,0x95,0x00,0x40,0x2A,0x00,0x00,0x60,0x8C,0x52,0x8C,0x39,0x07,0xA1,0x94,0x86,0x31,0xE7,0x9C,0x83,0x90,0x4A,
|
||||
0x4B,0x8D,0x62,0xCE,0x31,0x07,0xA1,0xA4,0x96,0x32,0xE7,0x20,0x94,0x92,0x52,0x4B,0x31,0x66,0xCE,0x41,0x29,0x25,0xA5,0xD6,0x5A,0xCC,0x9C,0x93,0xD2,0x5A,0x6C,0x3D,
|
||||
0xC6,0x9A,0x39,0x27,0xA9,0xB5,0xD8,0x62,0xAC,0xB5,0x83,0xD2,0x5A,0x8D,0x3D,0xF7,0xDE,0x73,0x27,0xA5,0xB5,0x1A,0x6B,0xEE,0x3D,0xF7,0x92,0x5A,0xAD,0xB5,0xF6,0xD8,
|
||||
0x73,0xEF,0x25,0xB5,0x18,0x73,0xAD,0xB9,0xF7,0x5A,0x63,0x8D,0xB9,0xF7,0x9E,0x73,0xEF,0xBD,0xA7,0x5C,0x7B,0xAF,0xB5,0xE7,0x5E,0x7B,0x2E,0x00,0x00,0xA7,0xC1,0x01,
|
||||
0x00,0xF4,0xC0,0x86,0xD5,0x11,0x4E,0x8A,0xC6,0x02,0x0B,0x0D,0x59,0x09,0x00,0xA4,0x02,0x00,0x10,0x08,0x29,0xC5,0x98,0x73,0xCE,0x39,0x87,0x90,0x62,0xCC,0x39,0xE7,
|
||||
0x20,0x84,0x10,0x21,0xC4,0x98,0x73,0xCE,0x41,0x08,0xA1,0x62,0x8C,0x39,0xE7,0x20,0x84,0x10,0x42,0xC5,0x98,0x63,0xCE,0x41,0x08,0x21,0x84,0xCE,0x39,0xE7,0x9C,0x83,
|
||||
0x10,0x42,0x08,0x9D,0x73,0xCE,0x39,0x07,0x21,0x84,0x10,0x3A,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x74,0x0E,0x42,0x08,0x1D,0x84,0x10,0x42,0xE8,0x20,0x84,0x10,0x42,
|
||||
0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0xA1,0x83,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x10,0x42,0x08,0x21,0x84,0x02,0x00,0x00,0x0B,
|
||||
0x1C,0x00,0x00,0x02,0x6C,0x58,0x1D,0xE1,0xA4,0x68,0x2C,0xB0,0xD0,0x90,0x95,0x00,0x00,0x10,0x00,0x00,0xC2,0xAC,0xE4,0x12,0x8A,0x24,0x90,0x72,0x0C,0x9A,0x69,0x8C,
|
||||
0x52,0x8E,0x9A,0x88,0x14,0x62,0x0A,0x9A,0xCA,0x10,0x43,0x4C,0x9A,0xA9,0x98,0x52,0xCA,0x81,0xE8,0x24,0x63,0x08,0x81,0x2A,0xCA,0xC6,0xD0,0x91,0x00,0x00,0x00,0x04,
|
||||
0x01,0x00,0x01,0x26,0x80,0xC0,0x00,0x41,0xC1,0x17,0x42,0x40,0x8C,0x01,0x00,0x08,0x42,0x64,0x86,0x48,0x28,0xAC,0x82,0x05,0x06,0x65,0xD0,0xE0,0x30,0x0F,0x00,0x1E,
|
||||
0x20,0x22,0x24,0x02,0x80,0xC4,0x04,0x45,0xDA,0xC5,0x05,0x74,0x19,0xE0,0x82,0x2E,0xEE,0x3A,0x10,0x42,0x10,0x82,0x10,0xC4,0xE2,0x00,0x0A,0x48,0xC0,0xC1,0x09,0x37,
|
||||
0x3C,0xF1,0x86,0x27,0xDC,0xE0,0x04,0x9D,0xA2,0x52,0x07,0x01,0x00,0x00,0x00,0x00,0x60,0x00,0x00,0x0F,0x00,0x00,0x07,0x05,0x10,0x11,0xD1,0x5C,0x85,0xC5,0x05,0x46,
|
||||
0x86,0xC6,0x06,0x47,0x87,0x47,0x00,0x00,0x00,0x00,0x00,0xA8,0x00,0xC0,0x07,0x00,0xC0,0xF1,0x01,0x44,0x44,0x34,0x57,0x61,0x71,0x81,0x91,0xA1,0xB1,0xC1,0xD1,0xE1,
|
||||
0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x04,0x04,0x04,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x04,0x04,
|
||||
};
|
||||
|
||||
|
||||
static const vcb_info_t vcb_list[] = {
|
||||
{0x01,0x0CD8,vcb_1},
|
||||
{0x02,0x0B72,vcb_2},
|
||||
{0x03,0x0DF7,vcb_3},
|
||||
{0x04,0x1025,vcb_4},
|
||||
{0x05,0x0C01,vcb_5},
|
||||
{0x06,0x0C01,vcb_6},
|
||||
{0x07,0x0CD8,vcb_7},
|
||||
};
|
||||
|
||||
static const int vcb_list_count = sizeof(vcb_list) / sizeof(vcb_list[0]);
|
||||
|
||||
#endif
|
File diff suppressed because it is too large
Load diff
181
Frameworks/vgmstream/vgmstream/src/coding/mio_decoder.c
Normal file
181
Frameworks/vgmstream/vgmstream/src/coding/mio_decoder.c
Normal file
|
@ -0,0 +1,181 @@
|
|||
#include "coding.h"
|
||||
#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"
|
||||
|
||||
|
||||
/* opaque struct */
|
||||
typedef struct {
|
||||
MIOFile* miofile;
|
||||
MIODecoder* miodec;
|
||||
MIOContext* mioctx;
|
||||
|
||||
/* current buf */
|
||||
void* sbuf;
|
||||
int samples;
|
||||
int channels;
|
||||
int fmtsize;
|
||||
|
||||
io_callback_t cb;
|
||||
io_priv_t io_priv;
|
||||
|
||||
int start_offset;
|
||||
} mio_codec_data;
|
||||
|
||||
|
||||
static void free_mio(void* priv_data) {
|
||||
mio_codec_data* data = priv_data;
|
||||
if (!data) return;
|
||||
|
||||
MIOFile_Close(data->miofile);
|
||||
MIODecoder_Close(data->miodec);
|
||||
MIOContext_Close(data->mioctx);
|
||||
ERI_eriCloseLibrary();
|
||||
free(data);
|
||||
}
|
||||
|
||||
void* init_mio(STREAMFILE* sf, int* p_loop_start) {
|
||||
ERI_eriInitializeLibrary();
|
||||
|
||||
mio_codec_data* data = calloc(1, sizeof(mio_codec_data));
|
||||
if (!data) return NULL;
|
||||
|
||||
io_callbacks_set_sf(&data->cb, &data->io_priv);
|
||||
data->io_priv.offset = 0;
|
||||
data->io_priv.sf = sf; //temp, will be updated later
|
||||
|
||||
data->miofile = MIOFile_Open();
|
||||
if (!data->miofile) goto fail;
|
||||
|
||||
if (MIOFile_Initialize(data->miofile, &data->cb))
|
||||
goto fail;
|
||||
|
||||
data->miodec = MIODecoder_Open();
|
||||
if (!data->miodec) goto fail;
|
||||
|
||||
if (MIODecoder_Initialize(data->miodec, &data->miofile->mioih))
|
||||
goto fail;
|
||||
|
||||
data->mioctx = MIOContext_Open();
|
||||
if (!data->mioctx) goto fail;
|
||||
|
||||
data->start_offset = data->io_priv.offset;
|
||||
|
||||
//TODO: lowest quality files allow 8-bit PCM
|
||||
if (data->miofile->mioih.dwBitsPerSample == 8) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
//TODO: improve get info from libs
|
||||
if (p_loop_start) {
|
||||
*p_loop_start = data->miofile->mioih.rewindPoint;
|
||||
}
|
||||
|
||||
return data;
|
||||
fail:
|
||||
free_mio(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static bool read_frame(mio_codec_data* data, STREAMFILE* sf) {
|
||||
|
||||
data->io_priv.sf = sf;
|
||||
//data->io_priv.offset = ...; // persists between calls
|
||||
|
||||
// read new packet into buffer
|
||||
int err = MIOFile_NextPacket(data->miofile, &data->cb);
|
||||
if (err == eslErrEof)
|
||||
return false;
|
||||
if (err) {
|
||||
VGM_LOG("MIO: decode packet error\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// current block is keyframe and can be used to seek/decode start
|
||||
// number depends on coding mode but usually 1 keyframe per 3-7 non-keyframe blocks (~32768 samples per block)
|
||||
//if (data->miofile->miodh.bytFlags & MIO_LEAD_BLOCK) {
|
||||
// ...
|
||||
//}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool decode_frame(mio_codec_data* data, sbuf_t* sbuf) {
|
||||
|
||||
// calculate current buffer size
|
||||
void* ptrWaveBuf = MIOFile_GetCurrentWaveBuffer(data->miofile);
|
||||
if (!ptrWaveBuf) {
|
||||
VGM_LOG("MIO: buffer error\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
// pass buffer to context (bitreader)
|
||||
MIOContext_AttachInputFile(data->mioctx, data->miofile->packet, data->miofile->packet_size);
|
||||
|
||||
// convert data into samples
|
||||
if (MIODecoder_DecodeSound(data->miodec, data->mioctx, &data->miofile->miodh, ptrWaveBuf)) {
|
||||
VGM_LOG("MIO: decode error\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
//int bufferCount = MIOFile_GetCurrentWaveBufferCount(hnd->miofile);
|
||||
int samples = data->miofile->miodh.dwSampleCount;
|
||||
int channels = data->miofile->mioih.dwChannelCount;
|
||||
sfmt_t format = SFMT_S16;
|
||||
//int fmtsize = data->miofile->mioih.dwBitsPerSample / 8;
|
||||
//if (fmtsize == 8)
|
||||
// format = SFMT_S8;
|
||||
|
||||
sbuf_init(sbuf, format, ptrWaveBuf, samples, channels);
|
||||
sbuf->filled = samples;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
bool decode_frame_mio(VGMSTREAM* v) {
|
||||
VGMSTREAMCHANNEL* vs = &v->ch[0];
|
||||
mio_codec_data* data = v->codec_data;
|
||||
decode_state_t* ds = v->decode_state;
|
||||
|
||||
bool ok = read_frame(data, vs->streamfile);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
ok = decode_frame(data, &ds->sbuf);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void reset_mio(void* priv_data) {
|
||||
mio_codec_data* data = priv_data;
|
||||
if (!data) return;
|
||||
|
||||
data->io_priv.offset = data->start_offset;
|
||||
|
||||
MIOContext_FlushBuffer(data->mioctx);
|
||||
MIOFile_Reset(data->miofile, &data->cb);
|
||||
}
|
||||
|
||||
static void seek_mio(VGMSTREAM* v, int32_t num_sample) {
|
||||
mio_codec_data* data = v->codec_data;
|
||||
decode_state_t* ds = v->decode_state;
|
||||
if (!data) return;
|
||||
|
||||
reset_mio(data);
|
||||
|
||||
// (due to implicit encode delay the above is byte-exact equivalent vs a discard loop)
|
||||
ds->discard = num_sample;
|
||||
}
|
||||
|
||||
const codec_info_t mio_decoder = {
|
||||
.sample_type = SFMT_S16,
|
||||
.decode_frame = decode_frame_mio,
|
||||
.free = free_mio,
|
||||
.reset = reset_mio,
|
||||
.seek = seek_mio,
|
||||
};
|
|
@ -1,82 +1,92 @@
|
|||
#include "coding.h"
|
||||
#include "coding_utils_samples.h"
|
||||
#include "../base/decode_state.h"
|
||||
#include "../base/codec_info.h"
|
||||
|
||||
#ifdef VGM_USE_SPEEX
|
||||
#include "speex/speex.h"
|
||||
|
||||
#define SPEEX_MAX_FRAME_SIZE 0x100 /* frame sizes are stored in a byte */
|
||||
#define SPEEX_MAX_FRAME_SAMPLES 640 /* nb=160, wb/uwb=320*2 */
|
||||
#define SPEEX_MAX_CHANNELS 1 /* nb=160, wb/uwb=320*2 */
|
||||
#define SPEEX_CTL_OK 0 /* -1=request unknown, -2=invalid param */
|
||||
#define SPEEX_DECODE_OK 0 /* -1 for end of stream, -2 corrupt stream */
|
||||
|
||||
|
||||
typedef enum { EA, TORUS } type_t;
|
||||
typedef enum { EA, TORUS } speex_type_t;
|
||||
|
||||
/* opaque struct */
|
||||
struct speex_codec_data {
|
||||
type_t type;
|
||||
typedef struct {
|
||||
speex_type_t type;
|
||||
|
||||
/* config */
|
||||
int channels;
|
||||
int samples_discard;
|
||||
int encoder_delay;
|
||||
int samples_discard;
|
||||
|
||||
uint8_t buf[SPEEX_MAX_FRAME_SIZE];
|
||||
int frame_size;
|
||||
|
||||
int16_t* samples;
|
||||
short pbuf[SPEEX_MAX_FRAME_SAMPLES * SPEEX_MAX_CHANNELS];
|
||||
int frame_samples;
|
||||
|
||||
/* frame state */
|
||||
s16buf_t sbuf;
|
||||
|
||||
void* state;
|
||||
void* handle;
|
||||
SpeexBits bits;
|
||||
};
|
||||
} speex_codec_data;
|
||||
|
||||
|
||||
/* raw SPEEX */
|
||||
static speex_codec_data* init_speex(type_t type, int channels) {
|
||||
static void free_speex(void* priv_data) {
|
||||
speex_codec_data* data = priv_data;
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
if (data->handle) {
|
||||
speex_decoder_destroy(data->handle);
|
||||
speex_bits_destroy(&data->bits);
|
||||
}
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
|
||||
// raw-ish SPEEX (without Ogg)
|
||||
static speex_codec_data* init_speex(speex_type_t type, int channels) {
|
||||
int res, sample_rate;
|
||||
speex_codec_data* data = NULL;
|
||||
|
||||
// not seen, unknown layout (known cases use xN mono decoders)
|
||||
if (channels > SPEEX_MAX_CHANNELS)
|
||||
return NULL;
|
||||
|
||||
data = calloc(1, sizeof(speex_codec_data));
|
||||
if (!data) goto fail;
|
||||
|
||||
data->type = type;
|
||||
|
||||
//TODO: unknown layout (known samples are mono, EA: N decoders, Torus: N too?)
|
||||
data->channels = channels;
|
||||
if (channels != 1)
|
||||
goto fail;
|
||||
|
||||
/* Modes: narrowband=nb, wideband=wb, ultrawideband=uwb modes.
|
||||
* EASpeex seem to always use uwb so use that for now until config is needed.
|
||||
* Examples normally use &speex_*_mode but export seem problematic? */
|
||||
data->state = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB));
|
||||
if (!data->state) goto fail;
|
||||
// Modes: narrowband=nb, wideband=wb, ultrawideband=uwb modes.
|
||||
// Known decoders seem to always use uwb so use that for now until config is needed.
|
||||
// Examples normally use &speex_*_mode but exports seem problematic?
|
||||
data->handle = speex_decoder_init(speex_lib_get_mode(SPEEX_MODEID_UWB));
|
||||
if (!data->handle) goto fail;
|
||||
|
||||
speex_bits_init(&data->bits);
|
||||
|
||||
res = speex_decoder_ctl(data->state, SPEEX_GET_FRAME_SIZE, &data->frame_samples);
|
||||
res = speex_decoder_ctl(data->handle, SPEEX_GET_FRAME_SIZE, &data->frame_samples);
|
||||
if (res != SPEEX_CTL_OK) goto fail;
|
||||
|
||||
if (data->frame_samples > SPEEX_MAX_FRAME_SAMPLES)
|
||||
goto fail;
|
||||
|
||||
/* forced in EA's code, doesn't seem to affect decoding (all EAAC headers use this rate too) */
|
||||
// forced in EA's code, doesn't seem to affect decoding (all EAAC headers use this rate too)
|
||||
sample_rate = 32000;
|
||||
res = speex_decoder_ctl(data->state, SPEEX_SET_SAMPLING_RATE, &sample_rate);
|
||||
res = speex_decoder_ctl(data->handle, SPEEX_SET_SAMPLING_RATE, &sample_rate);
|
||||
if (res != SPEEX_CTL_OK) goto fail;
|
||||
|
||||
/* default "latency" for EASpeex */
|
||||
data->encoder_delay = 509;
|
||||
data->samples_discard = data->encoder_delay;
|
||||
|
||||
data->samples = malloc(channels * data->frame_samples * sizeof(int16_t));
|
||||
if (!data->samples) goto fail;
|
||||
|
||||
return data;
|
||||
|
||||
fail:
|
||||
|
@ -84,38 +94,27 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
speex_codec_data* init_speex_ea(int channels) {
|
||||
void* init_speex_ea(int channels) {
|
||||
return init_speex(EA, channels);
|
||||
}
|
||||
|
||||
speex_codec_data* init_speex_torus(int channels) {
|
||||
void* init_speex_torus(int channels) {
|
||||
return init_speex(TORUS, channels);
|
||||
}
|
||||
|
||||
|
||||
static int decode_frame(speex_codec_data* data) {
|
||||
int res;
|
||||
|
||||
data->sbuf.samples = data->samples;
|
||||
data->sbuf.channels = 1;
|
||||
data->sbuf.filled = 0;
|
||||
|
||||
speex_bits_read_from(&data->bits, (const char*)data->buf, data->frame_size);
|
||||
|
||||
res = speex_decode_int(data->state, &data->bits, data->sbuf.samples);
|
||||
if (res != SPEEX_DECODE_OK) goto fail;
|
||||
// speex_decode() returns samples (F32), but internally speex decodes into pcm16
|
||||
int res = speex_decode_int(data->handle, &data->bits, data->pbuf);
|
||||
if (res != SPEEX_DECODE_OK) return -1;
|
||||
|
||||
data->sbuf.filled = data->frame_samples;
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
return data->frame_samples;
|
||||
}
|
||||
|
||||
/* for simple style speex (seen in EA-Speex and libspeex's sampledec.c) */
|
||||
static int read_frame(speex_codec_data* data, VGMSTREAMCHANNEL* stream) {
|
||||
size_t bytes;
|
||||
|
||||
// for simple style speex (seen in EA-Speex and libspeex's sampledec.c)
|
||||
static bool read_frame(speex_codec_data* data, VGMSTREAMCHANNEL* stream) {
|
||||
switch(data->type) {
|
||||
case EA:
|
||||
data->frame_size = read_u8(stream->offset, stream->streamfile);
|
||||
|
@ -128,87 +127,71 @@ static int read_frame(speex_codec_data* data, VGMSTREAMCHANNEL* stream) {
|
|||
default:
|
||||
break;
|
||||
}
|
||||
if (data->frame_size == 0) goto fail;
|
||||
if (data->frame_size == 0)
|
||||
return false;
|
||||
|
||||
bytes = read_streamfile(data->buf, stream->offset, data->frame_size, stream->streamfile);
|
||||
size_t bytes = read_streamfile(data->buf, stream->offset, data->frame_size, stream->streamfile);
|
||||
stream->offset += data->frame_size;
|
||||
if (bytes != data->frame_size) goto fail;
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
if (bytes != data->frame_size)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void decode_speex(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do) {
|
||||
VGMSTREAMCHANNEL* stream = &vgmstream->ch[0];
|
||||
speex_codec_data* data = vgmstream->codec_data;
|
||||
int ok;
|
||||
static bool decode_frame_speex(VGMSTREAM* v) {
|
||||
VGMSTREAMCHANNEL* stream = &v->ch[0];
|
||||
speex_codec_data* data = v->codec_data;
|
||||
decode_state_t* ds = v->decode_state;
|
||||
|
||||
bool ok = read_frame(data, stream);
|
||||
if (!ok) return false;
|
||||
|
||||
while (samples_to_do > 0) {
|
||||
s16buf_t* sbuf = &data->sbuf;
|
||||
int samples = decode_frame(data);
|
||||
if (samples < 0) return false;
|
||||
|
||||
if (sbuf->filled <= 0) {
|
||||
ok = read_frame(data, stream);
|
||||
if (!ok) goto fail;
|
||||
sbuf_init_s16(&ds->sbuf, data->pbuf, samples, data->channels);
|
||||
ds->sbuf.filled = ds->sbuf.samples;
|
||||
|
||||
ok = decode_frame(data);
|
||||
if (!ok) goto fail;
|
||||
}
|
||||
|
||||
if (data->samples_discard)
|
||||
s16buf_discard(&outbuf, sbuf, &data->samples_discard);
|
||||
else
|
||||
s16buf_consume(&outbuf, sbuf, &samples_to_do);
|
||||
if (data->samples_discard) {
|
||||
ds->discard += data->samples_discard;
|
||||
data->samples_discard = 0;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
/* on error just put some 0 samples */
|
||||
VGM_LOG("SPEEX: decode fail at %x, missing %i samples\n", (uint32_t)stream->offset, samples_to_do);
|
||||
s16buf_silence(&outbuf, &samples_to_do, data->channels);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
void reset_speex(speex_codec_data* data) {
|
||||
int res;
|
||||
|
||||
if (!data) return;
|
||||
|
||||
res = speex_decoder_ctl(data->state, SPEEX_RESET_STATE, NULL);
|
||||
if (res != SPEEX_CTL_OK) goto fail;
|
||||
|
||||
data->sbuf.filled = 0;
|
||||
data->samples_discard = data->encoder_delay;
|
||||
|
||||
return;
|
||||
fail:
|
||||
return; /* ? */
|
||||
}
|
||||
|
||||
void seek_speex(VGMSTREAM* vgmstream, int32_t num_sample) {
|
||||
speex_codec_data* data = vgmstream->codec_data;
|
||||
if (!data) return;
|
||||
|
||||
reset_speex(data);
|
||||
data->samples_discard += num_sample;
|
||||
|
||||
/* loop offsets are set during decode; force them to stream start so discard works */
|
||||
if (vgmstream->loop_ch)
|
||||
vgmstream->loop_ch[0].offset = vgmstream->loop_ch[0].channel_start_offset;
|
||||
}
|
||||
|
||||
void free_speex(speex_codec_data* data) {
|
||||
static void reset_speex(void* priv_data) {
|
||||
speex_codec_data* data = priv_data;
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
if (data->state) {
|
||||
speex_decoder_destroy(data->state);
|
||||
speex_bits_destroy(&data->bits);
|
||||
}
|
||||
int res = speex_decoder_ctl(data->handle, SPEEX_RESET_STATE, NULL);
|
||||
if (res != SPEEX_CTL_OK)
|
||||
return; //???
|
||||
|
||||
free(data->samples);
|
||||
free(data);
|
||||
data->samples_discard = data->encoder_delay;
|
||||
}
|
||||
|
||||
static void seek_speex(VGMSTREAM* v, int32_t num_sample) {
|
||||
decode_state_t* ds = v->decode_state;
|
||||
speex_codec_data* data = v->codec_data;
|
||||
if (!data) return;
|
||||
|
||||
reset_speex(data);
|
||||
|
||||
ds->discard = num_sample;
|
||||
|
||||
// loop offsets are set during decode; force them to stream start so discard works
|
||||
if (v->loop_ch)
|
||||
v->loop_ch[0].offset = v->loop_ch[0].channel_start_offset;
|
||||
}
|
||||
|
||||
const codec_info_t speex_decoder = {
|
||||
.sample_type = SFMT_S16,
|
||||
.decode_frame = decode_frame_speex,
|
||||
.free = free_speex,
|
||||
.reset = reset_speex,
|
||||
.seek = seek_speex,
|
||||
};
|
||||
#endif
|
||||
|
|
|
@ -1,34 +1,31 @@
|
|||
#include "coding.h"
|
||||
#include "coding_utils_samples.h"
|
||||
#if VGM_TEST_DECODER
|
||||
#include "../base/codec_info.h"
|
||||
#include "../base/decode_state.h"
|
||||
#endif
|
||||
#include "libs/tac_lib.h"
|
||||
|
||||
|
||||
/* opaque struct */
|
||||
struct tac_codec_data {
|
||||
/* config */
|
||||
int channels;
|
||||
int samples_discard;
|
||||
int encoder_delay;
|
||||
|
||||
typedef struct {
|
||||
uint8_t buf[TAC_BLOCK_SIZE];
|
||||
bool feed_block;
|
||||
off_t offset;
|
||||
|
||||
int16_t samples[TAC_FRAME_SAMPLES * TAC_CHANNELS];
|
||||
int frame_samples;
|
||||
|
||||
/* frame state */
|
||||
s16buf_t sbuf;
|
||||
float fbuf[TAC_FRAME_SAMPLES * TAC_CHANNELS];
|
||||
int discard;
|
||||
|
||||
void* handle;
|
||||
};
|
||||
} tac_codec_data;
|
||||
|
||||
static void free_tac(void* priv_data) {
|
||||
tac_codec_data* data = priv_data;
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
/* raw SPEEX */
|
||||
tac_codec_data* init_tac(STREAMFILE* sf) {
|
||||
tac_free(data->handle);
|
||||
free(data);
|
||||
}
|
||||
|
||||
void* init_tac(STREAMFILE* sf) {
|
||||
tac_codec_data* data = NULL;
|
||||
int bytes;
|
||||
|
||||
|
@ -40,13 +37,8 @@ tac_codec_data* init_tac(STREAMFILE* sf) {
|
|||
data->handle = tac_init(data->buf, bytes);
|
||||
if (!data->handle) goto fail;
|
||||
|
||||
data->feed_block = false; /* ok to use current block */
|
||||
data->feed_block = false; // ok to use first block
|
||||
data->offset = bytes;
|
||||
data->channels = TAC_CHANNELS;
|
||||
data->frame_samples = TAC_FRAME_SAMPLES;
|
||||
|
||||
data->encoder_delay = 0;
|
||||
data->samples_discard = data->encoder_delay;
|
||||
|
||||
return data;
|
||||
fail:
|
||||
|
@ -55,130 +47,86 @@ fail:
|
|||
}
|
||||
|
||||
|
||||
static bool decode_frame(tac_codec_data* data) {
|
||||
int err;
|
||||
|
||||
data->sbuf.samples = data->samples;
|
||||
data->sbuf.channels = data->channels;
|
||||
data->sbuf.filled = 0;
|
||||
|
||||
err = tac_decode_frame(data->handle, data->buf);
|
||||
static int decode_frame(tac_codec_data* data) {
|
||||
int err = tac_decode_frame(data->handle, data->buf);
|
||||
|
||||
if (err == TAC_PROCESS_NEXT_BLOCK) {
|
||||
data->feed_block = true;
|
||||
return true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (err == TAC_PROCESS_DONE) {
|
||||
VGM_LOG("TAC: process done (EOF) %i\n", err);
|
||||
return false; /* shouldn't reach this */
|
||||
return -1; // shouldn't reach this
|
||||
}
|
||||
|
||||
if (err != TAC_PROCESS_OK) {
|
||||
VGM_LOG("TAC: process error %i\n", err);
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
|
||||
|
||||
tac_get_samples_pcm16(data->handle, data->sbuf.samples);
|
||||
data->sbuf.filled = data->frame_samples;
|
||||
|
||||
return true;
|
||||
tac_get_samples_float(data->handle, data->fbuf);
|
||||
return TAC_FRAME_SAMPLES;
|
||||
}
|
||||
|
||||
static bool read_frame(tac_codec_data* data, STREAMFILE* sf) {
|
||||
|
||||
/* new block must be read only when signaled by lib */
|
||||
// new block must be read only when signaled by lib (a single block has N frames)
|
||||
if (!data->feed_block)
|
||||
return true;
|
||||
|
||||
int bytes = read_streamfile(data->buf, data->offset, sizeof(data->buf), sf);
|
||||
data->offset += bytes;
|
||||
data->feed_block = 0;
|
||||
if (bytes <= 0) return false; /* can read less that buf near EOF */
|
||||
if (bytes <= 0) return false; // will read less that buf near EOF
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void decode_tac(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do) {
|
||||
VGMSTREAMCHANNEL* stream = &vgmstream->ch[0];
|
||||
tac_codec_data* data = vgmstream->codec_data;
|
||||
bool ok;
|
||||
bool decode_frame_tac(VGMSTREAM* v) {
|
||||
VGMSTREAMCHANNEL* stream = &v->ch[0];
|
||||
tac_codec_data* data = v->codec_data;
|
||||
|
||||
bool ok = read_frame(data, stream->streamfile);
|
||||
if (!ok)
|
||||
return false;
|
||||
|
||||
while (samples_to_do > 0) {
|
||||
s16buf_t* sbuf = &data->sbuf;
|
||||
decode_state_t* ds = v->decode_state;
|
||||
|
||||
if (sbuf->filled <= 0) {
|
||||
ok = read_frame(data, stream->streamfile);
|
||||
if (!ok) goto fail;
|
||||
int samples = decode_frame(data);
|
||||
if (samples < 0)
|
||||
return false;
|
||||
|
||||
ok = decode_frame(data);
|
||||
if (!ok) goto fail;
|
||||
}
|
||||
|
||||
if (data->samples_discard)
|
||||
s16buf_discard(&outbuf, sbuf, &data->samples_discard);
|
||||
else
|
||||
s16buf_consume(&outbuf, sbuf, &samples_to_do);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
fail:
|
||||
/* on error just put some 0 samples */
|
||||
VGM_LOG("TAC: decode fail at %x, missing %i samples\n", (uint32_t)data->offset, samples_to_do);
|
||||
s16buf_silence(&outbuf, &samples_to_do, data->sbuf.channels);
|
||||
}
|
||||
|
||||
#if VGM_TEST_DECODER
|
||||
bool decode_tac_frame(VGMSTREAM* vgmstream) {
|
||||
VGMSTREAMCHANNEL* stream = &vgmstream->ch[0];
|
||||
tac_codec_data* data = vgmstream->codec_data;
|
||||
decode_state_t* ds = vgmstream->decode_state;
|
||||
|
||||
sbuf_init_s16(&ds->sbuf, data->samples, TAC_FRAME_SAMPLES, vgmstream->channels);
|
||||
|
||||
bool ok;
|
||||
|
||||
ok = read_frame(data, stream->streamfile);
|
||||
if (!ok) return false;
|
||||
|
||||
ok = decode_frame(data);
|
||||
if (!ok) return false;
|
||||
|
||||
ds->sbuf.filled = TAC_FRAME_SAMPLES; //TODO call sbuf_fill(samples);
|
||||
sbuf_init_f32(&ds->sbuf, data->fbuf, samples, v->channels);
|
||||
ds->sbuf.filled = samples;
|
||||
|
||||
// copy and let decoder handle
|
||||
if (data->samples_discard) {
|
||||
ds->discard = data->samples_discard;
|
||||
data->samples_discard = 0;
|
||||
if (data->discard) {
|
||||
ds->discard += data->discard;
|
||||
data->discard = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void reset_tac(tac_codec_data* data) {
|
||||
static void reset_tac(void* priv_data) {
|
||||
tac_codec_data* data = priv_data;
|
||||
if (!data) return;
|
||||
|
||||
tac_reset(data->handle);
|
||||
|
||||
data->feed_block = true;
|
||||
data->offset = 0x00;
|
||||
data->sbuf.filled = 0;
|
||||
data->samples_discard = data->encoder_delay;
|
||||
}
|
||||
|
||||
void seek_tac(tac_codec_data* data, int32_t num_sample) {
|
||||
static void seek_tac(VGMSTREAM* v, int32_t num_sample) {
|
||||
tac_codec_data* data = v->codec_data;
|
||||
int32_t loop_sample;
|
||||
const tac_header_t* hdr;
|
||||
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
hdr = tac_get_header(data->handle);
|
||||
const tac_header_t* hdr = tac_get_header(data->handle);
|
||||
|
||||
loop_sample = (hdr->loop_frame - 1) * TAC_FRAME_SAMPLES + hdr->loop_discard;
|
||||
if (loop_sample == num_sample) {
|
||||
|
@ -186,23 +134,22 @@ void seek_tac(tac_codec_data* data, int32_t num_sample) {
|
|||
|
||||
data->feed_block = true;
|
||||
data->offset = hdr->loop_offset;
|
||||
data->sbuf.filled = 0;
|
||||
data->samples_discard = hdr->loop_discard;
|
||||
data->discard = hdr->loop_discard;
|
||||
}
|
||||
else {
|
||||
tac_reset(data->handle);
|
||||
|
||||
data->feed_block = true;
|
||||
data->offset = 0x00;
|
||||
data->sbuf.filled = 0;
|
||||
data->samples_discard = num_sample;
|
||||
data->discard = num_sample;
|
||||
}
|
||||
}
|
||||
|
||||
void free_tac(tac_codec_data* data) {
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
tac_free(data->handle);
|
||||
free(data);
|
||||
}
|
||||
const codec_info_t tac_decoder = {
|
||||
.sample_type = SFMT_F32,
|
||||
.decode_frame = decode_frame_tac,
|
||||
.free = free_tac,
|
||||
.reset = reset_tac,
|
||||
.seek = seek_tac,
|
||||
//frame_samples = 1024,
|
||||
};
|
||||
|
|
207
Frameworks/vgmstream/vgmstream/src/coding/ubi_mpeg_decoder.c
Normal file
207
Frameworks/vgmstream/vgmstream/src/coding/ubi_mpeg_decoder.c
Normal file
|
@ -0,0 +1,207 @@
|
|||
|
||||
#include "coding.h"
|
||||
#include "../base/decode_state.h"
|
||||
#include "../base/codec_info.h"
|
||||
#include "libs/ubi_mpeg_helpers.h"
|
||||
|
||||
#define MINIMP3_FLOAT_OUTPUT
|
||||
//#define MINIMP3_NO_SIMD
|
||||
#define MINIMP3_IMPLEMENTATION
|
||||
#include "libs/minimp3.h"
|
||||
|
||||
//TODO: needed for smoother segments, but not sure if block samples counts this
|
||||
// (usually blocks' frames have more samples than defined but not always; maybe should output delay's samples at EOF)
|
||||
#define UBIMPEG_INITIAL_DISCARD 480 //observed
|
||||
#define UBIMPEG_SAMPLES_PER_FRAME 1152
|
||||
#define UBIMPEG_MAX_CHANNELS 2
|
||||
#define UBIMPEG_INPUT_LIMIT 0x400 //enough for 2 stereo + mono frames
|
||||
|
||||
|
||||
/* opaque struct */
|
||||
typedef struct {
|
||||
bool is_sur2;
|
||||
bool is_sur1;
|
||||
|
||||
bitstream_t is;
|
||||
mp3dec_t mp3d;
|
||||
mp3dec_frame_info_t info;
|
||||
|
||||
uint8_t ibuf[0x2000]; // big enough to limit re-reading
|
||||
uint8_t obuf[0x400]; // at least ~300
|
||||
uint8_t rbuf[0x400]; // at least 300 * 2
|
||||
float fbuf[UBIMPEG_SAMPLES_PER_FRAME * UBIMPEG_MAX_CHANNELS];
|
||||
|
||||
int initial_discard;
|
||||
} ubimpeg_codec_data;
|
||||
|
||||
|
||||
static void free_ubimpeg(void* priv_data) {
|
||||
ubimpeg_codec_data* data = priv_data;
|
||||
if (!data) return;
|
||||
|
||||
free(data);
|
||||
}
|
||||
|
||||
void* init_ubimpeg(uint32_t mode) {
|
||||
ubimpeg_codec_data* data = NULL;
|
||||
|
||||
data = calloc(1, sizeof(ubimpeg_codec_data));
|
||||
if (!data) goto fail;
|
||||
|
||||
// data may start with 'surround mode' flag, otherwise a regular frame with a Ubi-MPEG sync
|
||||
if (mode == get_id32be("2RUS")) {
|
||||
data->is_sur2 = true;
|
||||
}
|
||||
else if (mode == get_id32be("1RUS")) {
|
||||
data->is_sur1 = true;
|
||||
VGM_LOG("UBI-MPEG: 1RUS found\n");
|
||||
goto fail;
|
||||
}
|
||||
else if ((mode >> 20) != 0xFFF) {
|
||||
VGM_LOG("UBI-MPEG: unknown format %x\n", mode);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
data->initial_discard = UBIMPEG_INITIAL_DISCARD;
|
||||
|
||||
bm_setup(&data->is, data->ibuf, 0);
|
||||
mp3dec_init(&data->mp3d);
|
||||
|
||||
return data;
|
||||
fail:
|
||||
free_ubimpeg(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
// Ubi-MPEG is made to keep all data in memory, since frames go one after another.
|
||||
// Here we ensure that buf is filled enough for the reader, and move data around if needed
|
||||
// (maybe should make a circular buf bitreader but seems a bit too particular).
|
||||
static bool setup_input_bitstream(VGMSTREAM* v) {
|
||||
ubimpeg_codec_data* data = v->codec_data;
|
||||
VGMSTREAMCHANNEL* vs = &v->ch[0];
|
||||
|
||||
//TODO maybe should clamp to block size, but overreads should result in sync error as new blocks start with samples (technically could match)
|
||||
|
||||
// on init should read buf size
|
||||
int read_size = sizeof(data->ibuf);
|
||||
int pos = 0;
|
||||
|
||||
if (data->is.bufsize > 0) {
|
||||
uint32_t ibuf_offset = bm_pos(&data->is) / 8;
|
||||
uint32_t ibuf_left = read_size - ibuf_offset;
|
||||
|
||||
// move buf to beginning + setup to fill it fully
|
||||
if (ibuf_left < UBIMPEG_INPUT_LIMIT) {
|
||||
int ibuf_bitpos = bm_pos(&data->is) % 8;
|
||||
|
||||
memmove(data->ibuf, data->ibuf + ibuf_offset, ibuf_left);
|
||||
bm_setup(&data->is, data->ibuf, ibuf_left);
|
||||
bm_skip(&data->is, ibuf_bitpos);
|
||||
|
||||
pos = ibuf_left;
|
||||
read_size -= ibuf_left;
|
||||
}
|
||||
else {
|
||||
// enough data in buf
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
int bytes = read_streamfile(data->ibuf + pos, vs->offset, read_size, vs->streamfile);
|
||||
|
||||
bm_fill(&data->is, bytes);
|
||||
vs->offset += bytes;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static int read_frame_ubimpeg(VGMSTREAM* v) {
|
||||
ubimpeg_codec_data* data = v->codec_data;
|
||||
|
||||
// prepare and read data for the bitstream, if needed
|
||||
setup_input_bitstream(v) ;
|
||||
|
||||
// convert input data into 1 regular mpeg frame
|
||||
bitstream_t os = {0};
|
||||
bm_setup(&os, data->obuf, sizeof(data->obuf));
|
||||
|
||||
int obuf_size = ubimpeg_transform_frame(&data->is, &os);
|
||||
if (!obuf_size) return 0;
|
||||
|
||||
// TODO: handle correctly
|
||||
// Ubi-MPEG (MP2) mixes 1 stereo frame + 1 mono frame coefs before synth to (presumably) emulate M/S stereo from MP3.
|
||||
// Ignoring the mono frame usually sounds ok enough (as good as 160kbps JS MP2 by 1998 encoders can sound) but
|
||||
// sometimes stereo frames only have data for left channel and need the mono frame to complete R.
|
||||
if (data->is_sur1 || data->is_sur2) {
|
||||
// consume next frame (should be mono) in a separate buffer as otherwise confuses minimp3
|
||||
bm_setup(&os, data->rbuf, sizeof(data->rbuf));
|
||||
ubimpeg_transform_frame(&data->is, &os);
|
||||
}
|
||||
|
||||
return obuf_size;
|
||||
}
|
||||
|
||||
bool decode_frame_ubimpeg(VGMSTREAM* v) {
|
||||
int obuf_size = read_frame_ubimpeg(v);
|
||||
if (!obuf_size) {
|
||||
return false;
|
||||
}
|
||||
|
||||
decode_state_t* ds = v->decode_state;
|
||||
ubimpeg_codec_data* data = v->codec_data;
|
||||
|
||||
int samples = mp3dec_decode_frame(&data->mp3d, data->obuf, obuf_size, data->fbuf, &data->info);
|
||||
if (samples < 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// TODO: voice .bnm + Ubi-MPEG sets 2 channels but uses mono frames (no xRUS). Possibly the MPEG engine
|
||||
// only handle stereo, maybe should dupe L>R. sbuf copying handles this correctly.
|
||||
// todo fix
|
||||
if (data->info.channels != v->channels) {
|
||||
VGM_LOG_ONCE("UBI MPEG: mismatched channels %i vs %i\n", data->info.channels, v->channels);
|
||||
//return false;
|
||||
}
|
||||
|
||||
sbuf_init_flt(&ds->sbuf, data->fbuf, samples, data->info.channels);
|
||||
ds->sbuf.filled = samples;
|
||||
|
||||
if (data->initial_discard) {
|
||||
ds->discard += data->initial_discard;
|
||||
data->initial_discard = 0;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
static void reset_ubimpeg(void* priv_data) {
|
||||
ubimpeg_codec_data* data = priv_data;
|
||||
if (!data) return;
|
||||
|
||||
data->initial_discard = UBIMPEG_INITIAL_DISCARD;
|
||||
|
||||
bm_setup(&data->is, data->ibuf, 0);
|
||||
mp3dec_init(&data->mp3d);
|
||||
}
|
||||
|
||||
static void seek_ubimpeg(VGMSTREAM* v, int32_t num_sample) {
|
||||
ubimpeg_codec_data* data = v->codec_data;
|
||||
decode_state_t* ds = v->decode_state;
|
||||
if (!data) return;
|
||||
|
||||
reset_ubimpeg(data);
|
||||
|
||||
ds->discard = num_sample;
|
||||
if (v->loop_ch) {
|
||||
v->loop_ch[0].offset = v->loop_ch[0].channel_start_offset;
|
||||
}
|
||||
}
|
||||
|
||||
const codec_info_t ubimpeg_decoder = {
|
||||
.sample_type = SFMT_FLT,
|
||||
.decode_frame = decode_frame_ubimpeg,
|
||||
.free = free_ubimpeg,
|
||||
.reset = reset_ubimpeg,
|
||||
.seek = seek_ubimpeg,
|
||||
};
|
|
@ -1,12 +1,31 @@
|
|||
#include <math.h>
|
||||
#include "../base/decode_state.h"
|
||||
#include "../base/sbuf.h"
|
||||
#include "../base/codec_info.h"
|
||||
#include "coding.h"
|
||||
#include "vorbis_custom_decoder.h"
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
|
||||
#define VORBIS_DEFAULT_BUFFER_SIZE 0x8000 /* should be at least the size of the setup header, ~0x2000 */
|
||||
#define VORBIS_CALL_SAMPLES 1024 // allowed frame 'blocksizes' range from 2^6 ~ 2^13 (64 ~ 8192) but we can return partial samples
|
||||
#define VORBIS_DEFAULT_BUFFER_SIZE 0x8000 // at least the size of the setup header, ~0x2000
|
||||
|
||||
static void pcm_convert_float_to_16(sample_t* outbuf, int samples_to_do, float** pcm, int channels);
|
||||
|
||||
void free_vorbis_custom(void* priv_data) {
|
||||
vorbis_custom_codec_data* data = priv_data;
|
||||
if (!data)
|
||||
return;
|
||||
|
||||
/* internal decoder cleanup */
|
||||
vorbis_block_clear(&data->vb);
|
||||
vorbis_dsp_clear(&data->vd);
|
||||
vorbis_comment_clear(&data->vc);
|
||||
vorbis_info_clear(&data->vi);
|
||||
|
||||
free(data->buffer);
|
||||
free(data->fbuf);
|
||||
free(data);
|
||||
}
|
||||
|
||||
/**
|
||||
* Inits a vorbis stream of some custom variety.
|
||||
|
@ -51,9 +70,11 @@ vorbis_custom_codec_data* init_vorbis_custom(STREAMFILE* sf, off_t start_offset,
|
|||
case VORBIS_SK: ok = vorbis_custom_setup_init_sk(sf, start_offset, data); break;
|
||||
case VORBIS_VID1: ok = vorbis_custom_setup_init_vid1(sf, start_offset, data); break;
|
||||
case VORBIS_AWC: ok = vorbis_custom_setup_init_awc(sf, start_offset, data); break;
|
||||
default: goto fail;
|
||||
case VORBIS_OOR: ok = vorbis_custom_setup_init_oor(sf, start_offset, data); break;
|
||||
default: ok = false; break;
|
||||
}
|
||||
if(!ok) goto fail;
|
||||
if(!ok)
|
||||
goto fail;
|
||||
|
||||
data->op.b_o_s = 0; /* end of fake headers */
|
||||
|
||||
|
@ -63,6 +84,9 @@ vorbis_custom_codec_data* init_vorbis_custom(STREAMFILE* sf, off_t start_offset,
|
|||
|
||||
|
||||
/* write output */
|
||||
config->channels = data->config.channels;
|
||||
config->sample_rate = data->config.sample_rate;
|
||||
config->last_granule = data->config.last_granule;
|
||||
config->data_start_offset = data->config.data_start_offset;
|
||||
|
||||
if (!data->config.stream_end) {
|
||||
|
@ -77,154 +101,175 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Decodes Vorbis packets into a libvorbis sample buffer, and copies them to outbuf */
|
||||
void decode_vorbis_custom(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do, int channels) {
|
||||
VGMSTREAMCHANNEL *stream = &vgmstream->ch[0];
|
||||
vorbis_custom_codec_data* data = vgmstream->codec_data;
|
||||
//data->op.packet = data->buffer;/* implicit from init */
|
||||
int samples_done = 0;
|
||||
static bool read_packet(VGMSTREAM* v) {
|
||||
VGMSTREAMCHANNEL* stream = &v->ch[0];
|
||||
vorbis_custom_codec_data* data = v->codec_data;
|
||||
|
||||
while (samples_done < samples_to_do) {
|
||||
// extra EOF check
|
||||
// (may need to drain samples? not a thing in vorbis due to packet types?)
|
||||
if (stream->offset >= data->config.stream_end)
|
||||
return false;
|
||||
|
||||
if (data->samples_full) { /* read more samples */
|
||||
int samples_to_get;
|
||||
float **pcm;
|
||||
|
||||
/* get PCM samples from libvorbis buffers */
|
||||
samples_to_get = vorbis_synthesis_pcmout(&data->vd, &pcm);
|
||||
if (!samples_to_get) {
|
||||
data->samples_full = 0; /* request more if empty*/
|
||||
continue;
|
||||
}
|
||||
|
||||
if (data->samples_to_discard) {
|
||||
/* discard samples for looping */
|
||||
if (samples_to_get > data->samples_to_discard)
|
||||
samples_to_get = data->samples_to_discard;
|
||||
data->samples_to_discard -= samples_to_get;
|
||||
}
|
||||
else {
|
||||
/* get max samples and convert from Vorbis float pcm to 16bit pcm */
|
||||
if (samples_to_get > samples_to_do - samples_done)
|
||||
samples_to_get = samples_to_do - samples_done;
|
||||
pcm_convert_float_to_16(outbuf + samples_done * channels, samples_to_get, pcm, data->vi.channels);
|
||||
samples_done += samples_to_get;
|
||||
}
|
||||
|
||||
/* mark consumed samples from the buffer
|
||||
* (non-consumed samples are returned in next vorbis_synthesis_pcmout calls) */
|
||||
vorbis_synthesis_read(&data->vd, samples_to_get);
|
||||
}
|
||||
else { /* read more data */
|
||||
int ok, rc;
|
||||
|
||||
/* extra EOF check */
|
||||
if (stream->offset >= data->config.stream_end) {
|
||||
/* may need to drain samples? (not a thing in vorbis due to packet types?) */
|
||||
goto decode_fail;
|
||||
}
|
||||
|
||||
/* not actually needed, but feels nicer */
|
||||
data->op.granulepos += samples_to_do; /* can be changed next if desired */
|
||||
data->op.packetno++;
|
||||
|
||||
/* read/transform data into the ogg_packet buffer and advance offsets */
|
||||
switch(data->type) {
|
||||
case VORBIS_FSB: ok = vorbis_custom_parse_packet_fsb(stream, data); break;
|
||||
case VORBIS_WWISE: ok = vorbis_custom_parse_packet_wwise(stream, data); break;
|
||||
case VORBIS_OGL: ok = vorbis_custom_parse_packet_ogl(stream, data); break;
|
||||
case VORBIS_SK: ok = vorbis_custom_parse_packet_sk(stream, data); break;
|
||||
case VORBIS_VID1: ok = vorbis_custom_parse_packet_vid1(stream, data); break;
|
||||
case VORBIS_AWC: ok = vorbis_custom_parse_packet_awc(stream, data); break;
|
||||
default: goto decode_fail;
|
||||
}
|
||||
if(!ok) {
|
||||
goto decode_fail;
|
||||
}
|
||||
|
||||
|
||||
/* parse the fake ogg packet into a logical vorbis block */
|
||||
rc = vorbis_synthesis(&data->vb,&data->op);
|
||||
if (rc == OV_ENOTAUDIO) {
|
||||
VGM_LOG("Vorbis: not an audio packet (size=0x%x) @ %x\n",(size_t)data->op.bytes,(uint32_t)stream->offset);
|
||||
//VGM_LOGB(data->op.packet, (size_t)data->op.bytes,0);
|
||||
continue; /* rarely happens, seems ok? */
|
||||
} else if (rc != 0) goto decode_fail;
|
||||
|
||||
/* finally decode the logical block into samples */
|
||||
rc = vorbis_synthesis_blockin(&data->vd,&data->vb);
|
||||
if (rc != 0) goto decode_fail; /* ? */
|
||||
|
||||
|
||||
data->samples_full = 1;
|
||||
}
|
||||
// read/transform data into the ogg_packet buffer and advance offsets
|
||||
bool ok;
|
||||
switch(data->type) {
|
||||
case VORBIS_FSB: ok = vorbis_custom_parse_packet_fsb(stream, data); break;
|
||||
case VORBIS_WWISE: ok = vorbis_custom_parse_packet_wwise(stream, data); break;
|
||||
case VORBIS_OGL: ok = vorbis_custom_parse_packet_ogl(stream, data); break;
|
||||
case VORBIS_SK: ok = vorbis_custom_parse_packet_sk(stream, data); break;
|
||||
case VORBIS_VID1: ok = vorbis_custom_parse_packet_vid1(stream, data); break;
|
||||
case VORBIS_AWC: ok = vorbis_custom_parse_packet_awc(stream, data); break;
|
||||
case VORBIS_OOR: ok = vorbis_custom_parse_packet_oor(stream, data); break;
|
||||
default: ok = false; break;
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
decode_fail:
|
||||
/* on error just put some 0 samples */
|
||||
VGM_LOG("VORBIS: decode fail at %x, missing %i samples\n", (uint32_t)stream->offset, (samples_to_do - samples_done));
|
||||
memset(outbuf + samples_done * channels, 0, (samples_to_do - samples_done) * channels * sizeof(sample_t));
|
||||
return ok;
|
||||
}
|
||||
|
||||
/* converts from internal Vorbis format to standard PCM (mostly from Xiph's decoder_example.c) */
|
||||
static void pcm_convert_float_to_16(sample_t* outbuf, int samples_to_do, float** pcm, int channels) {
|
||||
int ch, s;
|
||||
sample_t* ptr;
|
||||
float* channel;
|
||||
static bool decode_frame(VGMSTREAM* v) {
|
||||
decode_state_t* ds = v->decode_state;
|
||||
vorbis_custom_codec_data* data = v->codec_data;
|
||||
int 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++) {
|
||||
/* channels should be in standard order unlike Ogg Vorbis (at least in FSB) */
|
||||
ptr = outbuf + ch;
|
||||
channel = pcm[ch];
|
||||
for (s = 0; s < samples_to_do; s++) {
|
||||
int val = (int)floor(channel[s] * 32767.0f + 0.5f);
|
||||
if (val > 32767) val = 32767;
|
||||
else if (val < -32768) val = -32768;
|
||||
|
||||
*ptr = val;
|
||||
ptr += channels;
|
||||
}
|
||||
// parse the fake ogg packet into a logical vorbis block
|
||||
rc = vorbis_synthesis(&data->vb, &data->op);
|
||||
if (rc == OV_ENOTAUDIO) {
|
||||
// rarely happens, seems ok?
|
||||
VGM_LOG("Vorbis: not an audio packet (size=0x%x) @ %x\n", (size_t)data->op.bytes, (uint32_t)v->ch[0].offset);
|
||||
ds->sbuf.filled = 0;
|
||||
return true;
|
||||
}
|
||||
else if (rc != 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// finally decode the logical vorbis block into samples
|
||||
rc = vorbis_synthesis_blockin(&data->vd,&data->vb);
|
||||
if (rc != 0) return false; /* ? */
|
||||
|
||||
data->op.packetno++;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/* ********************************************** */
|
||||
static int copy_samples(VGMSTREAM* v) {
|
||||
decode_state_t* ds = v->decode_state;
|
||||
vorbis_custom_codec_data* data = v->codec_data;
|
||||
|
||||
void free_vorbis_custom(vorbis_custom_codec_data* data) {
|
||||
if (!data)
|
||||
return;
|
||||
//TODO: helper?
|
||||
//TODO: 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;
|
||||
}
|
||||
|
||||
/* internal decoder cleanup */
|
||||
vorbis_block_clear(&data->vb);
|
||||
vorbis_dsp_clear(&data->vd);
|
||||
vorbis_comment_clear(&data->vc);
|
||||
vorbis_info_clear(&data->vi);
|
||||
// get PCM samples from libvorbis buffers
|
||||
float** pcm;
|
||||
int samples = vorbis_synthesis_pcmout(&data->vd, &pcm);
|
||||
if (samples > VORBIS_CALL_SAMPLES)
|
||||
samples = VORBIS_CALL_SAMPLES;
|
||||
|
||||
free(data->buffer);
|
||||
free(data);
|
||||
// no more samples in vorbis's buffer
|
||||
if (samples == 0)
|
||||
return 0;
|
||||
|
||||
// vorbis's planar buffer to interleaved buffer
|
||||
sbuf_init_flt(&ds->sbuf, data->fbuf, samples, v->channels);
|
||||
ds->sbuf.filled = samples;
|
||||
sbuf_interleave(&ds->sbuf, pcm);
|
||||
|
||||
// mark consumed samples from the buffer
|
||||
// (non-consumed samples are returned in next vorbis_synthesis_pcmout calls)
|
||||
vorbis_synthesis_read(&data->vd, samples);
|
||||
|
||||
// TODO: useful?
|
||||
//data->op.granulepos += samples; // not actually needed
|
||||
|
||||
if (data->current_discard) {
|
||||
ds->discard += data->current_discard;
|
||||
data->current_discard = 0;
|
||||
}
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
void reset_vorbis_custom(VGMSTREAM* vgmstream) {
|
||||
vorbis_custom_codec_data *data = vgmstream->codec_data;
|
||||
static bool decode_frame_vorbis_custom(VGMSTREAM* v) {
|
||||
// vorbis may hold samples, return them first
|
||||
int ret = copy_samples(v);
|
||||
if (ret < 0) return false;
|
||||
if (ret > 0) return true;
|
||||
|
||||
// handle new frame
|
||||
bool read = read_packet(v);
|
||||
if (!read)
|
||||
return false;
|
||||
|
||||
// decode current frame
|
||||
bool decoded = decode_frame(v);
|
||||
if (!decoded)
|
||||
return false;
|
||||
|
||||
// samples will be copied next call
|
||||
return true;
|
||||
}
|
||||
|
||||
static void reset_vorbis_custom(void* priv_data) {
|
||||
vorbis_custom_codec_data* data = priv_data;
|
||||
if (!data) return;
|
||||
|
||||
vorbis_synthesis_restart(&data->vd);
|
||||
data->samples_to_discard = 0;
|
||||
data->current_discard = 0;
|
||||
data->current_packet = 0;
|
||||
data->packet_count = 0;
|
||||
data->flags = 0;
|
||||
}
|
||||
|
||||
void seek_vorbis_custom(VGMSTREAM* vgmstream, int32_t num_sample) {
|
||||
vorbis_custom_codec_data *data = vgmstream->codec_data;
|
||||
static void seek_vorbis_custom(VGMSTREAM* v, int32_t num_sample) {
|
||||
vorbis_custom_codec_data* data = v->codec_data;
|
||||
if (!data) return;
|
||||
|
||||
/* Seeking is provided by the Ogg layer, so with custom vorbis we'd need seek tables instead.
|
||||
* To avoid having to parse different formats we'll just discard until the expected sample */
|
||||
vorbis_synthesis_restart(&data->vd);
|
||||
data->samples_to_discard = num_sample;
|
||||
if (vgmstream->loop_ch)
|
||||
vgmstream->loop_ch[0].offset = vgmstream->loop_ch[0].channel_start_offset;
|
||||
reset_vorbis_custom(data);
|
||||
data->current_discard = num_sample;
|
||||
if (v->loop_ch)
|
||||
v->loop_ch[0].offset = v->loop_ch[0].channel_start_offset;
|
||||
}
|
||||
|
||||
int32_t vorbis_custom_get_samples(VGMSTREAM* v) {
|
||||
vorbis_custom_codec_data* data = v->codec_data;
|
||||
|
||||
//TODO improve (would need to change a bunch)
|
||||
VGMSTREAMCHANNEL* stream = &v->ch[0];
|
||||
uint32_t temp = stream->offset;
|
||||
|
||||
// read packets + sum samples (info from revorb: https://yirkha.fud.cz/progs/foobar2000/revorb.cpp)
|
||||
int prev_blocksize = 0;
|
||||
int32_t samples = 0;
|
||||
while (true) {
|
||||
bool ok = read_packet(v);
|
||||
if (!ok || data->op.bytes == 0) //EOF probably
|
||||
break;
|
||||
|
||||
// get blocksize (somewhat similar to samples-per-frame, but must be adjusted)
|
||||
int blocksize = vorbis_packet_blocksize(&data->vi, &data->op);
|
||||
if (prev_blocksize)
|
||||
samples += (prev_blocksize + blocksize) / 4;
|
||||
prev_blocksize = blocksize;
|
||||
}
|
||||
|
||||
reset_vorbis_custom(data);
|
||||
stream->offset = temp;
|
||||
|
||||
return samples;
|
||||
}
|
||||
|
||||
const codec_info_t vorbis_custom_decoder = {
|
||||
.sample_type = SFMT_FLT,
|
||||
.decode_frame = decode_frame_vorbis_custom,
|
||||
.free = free_vorbis_custom,
|
||||
.reset = reset_vorbis_custom,
|
||||
.seek = seek_vorbis_custom,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -8,6 +8,8 @@
|
|||
#ifdef VGM_USE_VORBIS
|
||||
#include <vorbis/codec.h>
|
||||
|
||||
#define MAX_PACKET_SIZES 160 // max 256 in theory, observed max is ~65, rarely ~130 in
|
||||
|
||||
/* custom Vorbis without Ogg layer */
|
||||
struct vorbis_custom_codec_data {
|
||||
vorbis_info vi; /* stream settings */
|
||||
|
@ -18,24 +20,28 @@ struct vorbis_custom_codec_data {
|
|||
|
||||
uint8_t* buffer; /* internal raw data buffer */
|
||||
size_t buffer_size;
|
||||
float* fbuf;
|
||||
|
||||
size_t samples_to_discard; /* for looping purposes */
|
||||
int samples_full; /* flag, samples available in vorbis buffers */
|
||||
int current_discard; /* for looping purposes */
|
||||
|
||||
vorbis_custom_t type; /* Vorbis subtype */
|
||||
vorbis_custom_config config; /* config depending on the mode */
|
||||
|
||||
|
||||
/* Wwise Vorbis: saved data to reconstruct modified packets */
|
||||
uint8_t mode_blockflag[64+1]; /* max 6b+1; flags 'n stuff */
|
||||
int mode_bits; /* bits to store mode_number */
|
||||
uint8_t prev_blockflag; /* blockflag in the last decoded packet */
|
||||
/* Ogg-style Vorbis: packet within a page */
|
||||
|
||||
/* OOR/OggS: current page info (state) */
|
||||
int current_packet;
|
||||
int packet_count;
|
||||
uint16_t packet_size[MAX_PACKET_SIZES];
|
||||
uint8_t flags;
|
||||
|
||||
/* reference for page/blocks */
|
||||
off_t block_offset;
|
||||
size_t block_size;
|
||||
|
||||
int prev_block_samples; /* count for optimization */
|
||||
};
|
||||
|
||||
|
||||
|
@ -45,6 +51,7 @@ int vorbis_custom_setup_init_ogl(STREAMFILE* sf, off_t start_offset, vorbis_cust
|
|||
int vorbis_custom_setup_init_sk(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data);
|
||||
int vorbis_custom_setup_init_vid1(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data);
|
||||
int vorbis_custom_setup_init_awc(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data);
|
||||
int vorbis_custom_setup_init_oor(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data);
|
||||
|
||||
int vorbis_custom_parse_packet_fsb(VGMSTREAMCHANNEL* stream, vorbis_custom_codec_data* data);
|
||||
int vorbis_custom_parse_packet_wwise(VGMSTREAMCHANNEL* stream, vorbis_custom_codec_data* data);
|
||||
|
@ -52,12 +59,15 @@ int vorbis_custom_parse_packet_ogl(VGMSTREAMCHANNEL* stream, vorbis_custom_codec
|
|||
int vorbis_custom_parse_packet_sk(VGMSTREAMCHANNEL* stream, vorbis_custom_codec_data* data);
|
||||
int vorbis_custom_parse_packet_vid1(VGMSTREAMCHANNEL* stream, vorbis_custom_codec_data* data);
|
||||
int vorbis_custom_parse_packet_awc(VGMSTREAMCHANNEL* stream, vorbis_custom_codec_data* data);
|
||||
int vorbis_custom_parse_packet_oor(VGMSTREAMCHANNEL* stream, vorbis_custom_codec_data* data);
|
||||
|
||||
/* other utils to make/parse vorbis stuff */
|
||||
int build_header_comment(uint8_t* buf, int bufsize);
|
||||
int build_header_identification(uint8_t* buf, int bufsize, vorbis_custom_config* cfg);
|
||||
void load_blocksizes(vorbis_custom_config* cfg, int blocksize_short, int blocksize_long);
|
||||
int vorbis_get_blocksize_exp(int blocksize);
|
||||
bool load_header_packet(STREAMFILE* sf, vorbis_custom_codec_data* data, uint32_t packet_size, int packet_skip, uint32_t* p_offset);
|
||||
#endif/* VGM_USE_VORBIS */
|
||||
|
||||
#endif/*_VORBIS_CUSTOM_DECODER_H_ */
|
||||
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
#include "vorbis_custom_decoder.h"
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
|
||||
int build_header_comment(uint8_t* buf, int bufsize) {
|
||||
int bytes = 0x19;
|
||||
|
||||
|
@ -22,6 +23,7 @@ int build_header_identification(uint8_t* buf, int bufsize, vorbis_custom_config*
|
|||
if (bytes > bufsize)
|
||||
return 0;
|
||||
|
||||
// long (bigger frames) + short (smaller frames) blocksizes (samples per frame)
|
||||
uint8_t blocksizes = (cfg->blocksize_0_exp << 4) | (cfg->blocksize_1_exp);
|
||||
|
||||
put_u8 (buf+0x00, 0x01); /* packet_type (id) */
|
||||
|
@ -46,35 +48,19 @@ bool make_header_identification(vorbis_custom_codec_data* data, vorbis_custom_co
|
|||
return true;
|
||||
}
|
||||
|
||||
void load_blocksizes(vorbis_custom_config* cfg, int blocksize_short, int blocksize_long) {
|
||||
uint8_t exp_blocksize_0, exp_blocksize_1;
|
||||
|
||||
/* guetto log2 for allowed blocksizes (2-exp), could be improved */
|
||||
switch(blocksize_long) {
|
||||
case 64: exp_blocksize_0 = 6; break;
|
||||
case 128: exp_blocksize_0 = 7; break;
|
||||
case 256: exp_blocksize_0 = 8; break;
|
||||
case 512: exp_blocksize_0 = 9; break;
|
||||
case 1024: exp_blocksize_0 = 10; break;
|
||||
case 2048: exp_blocksize_0 = 11; break;
|
||||
case 4096: exp_blocksize_0 = 12; break;
|
||||
case 8192: exp_blocksize_0 = 13; break;
|
||||
default: exp_blocksize_0 = 0;
|
||||
// basic log2 for allowed blocksizes (2-exp)
|
||||
int vorbis_get_blocksize_exp(int blocksize) {
|
||||
switch(blocksize) {
|
||||
case 64: return 6;
|
||||
case 128: return 7;
|
||||
case 256: return 8;
|
||||
case 512: return 9;
|
||||
case 1024: return 10;
|
||||
case 2048: return 11;
|
||||
case 4096: return 12;
|
||||
case 8192: return 13;
|
||||
default: return 0;
|
||||
}
|
||||
switch(blocksize_short) {
|
||||
case 64: exp_blocksize_1 = 6; break;
|
||||
case 128: exp_blocksize_1 = 7; break;
|
||||
case 256: exp_blocksize_1 = 8; break;
|
||||
case 512: exp_blocksize_1 = 9; break;
|
||||
case 1024: exp_blocksize_1 = 10; break;
|
||||
case 2048: exp_blocksize_1 = 11; break;
|
||||
case 4096: exp_blocksize_1 = 12; break;
|
||||
case 8192: exp_blocksize_1 = 13; break;
|
||||
default: exp_blocksize_1 = 0;
|
||||
}
|
||||
|
||||
cfg->blocksize_0_exp = exp_blocksize_0;
|
||||
cfg->blocksize_1_exp = exp_blocksize_1;
|
||||
}
|
||||
|
||||
bool load_header_packet(STREAMFILE* sf, vorbis_custom_codec_data* data, uint32_t packet_size, int packet_skip, uint32_t* p_offset) {
|
||||
|
@ -90,4 +76,5 @@ bool load_header_packet(STREAMFILE* sf, vorbis_custom_codec_data* data, uint32_t
|
|||
fail:
|
||||
return false;
|
||||
}
|
||||
#endif/* VGM_USE_VORBIS */
|
||||
|
||||
#endif
|
||||
|
|
|
@ -3,9 +3,9 @@
|
|||
#ifdef VGM_USE_VORBIS
|
||||
#include <vorbis/codec.h>
|
||||
|
||||
#define FSB_VORBIS_USE_PRECOMPILED_FVS 1 /* if enabled vgmstream weights ~600kb more but doesn't need external .fvs packets */
|
||||
#if FSB_VORBIS_USE_PRECOMPILED_FVS
|
||||
#include "vorbis_custom_data_fsb.h"
|
||||
// if enabled vgmstream weights ~600kb more but doesn't need external setup packets
|
||||
#ifndef VGM_DISABLE_CODEBOOKS
|
||||
#include "libs/vorbis_codebooks_fsb.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -15,11 +15,6 @@
|
|||
|
||||
static int build_header_setup(uint8_t* buf, size_t bufsize, uint32_t setup_id, STREAMFILE* sf);
|
||||
|
||||
#if !(FSB_VORBIS_USE_PRECOMPILED_FVS)
|
||||
static int load_fvs_file(uint8_t* buf, size_t bufsize, uint32_t setup_id, STREAMFILE* sf);
|
||||
#endif
|
||||
static int load_fvs_array(uint8_t* buf, size_t bufsize, uint32_t setup_id, STREAMFILE* sf);
|
||||
|
||||
|
||||
/* **************************************************************************** */
|
||||
/* EXTERNAL API */
|
||||
|
@ -32,11 +27,13 @@ static int load_fvs_array(uint8_t* buf, size_t bufsize, uint32_t setup_id, STREA
|
|||
* fsb-vorbis-extractor (https://github.com/tmiasko/fsb-vorbis-extractor).
|
||||
*/
|
||||
int vorbis_custom_setup_init_fsb(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data) {
|
||||
vorbis_custom_config cfg = data->config;
|
||||
vorbis_custom_config* cfg = &data->config;
|
||||
|
||||
load_blocksizes(&cfg, 256, 2048); /* FSB default */
|
||||
// load FSB default blocksizes
|
||||
cfg->blocksize_0_exp = vorbis_get_blocksize_exp(2048); //long
|
||||
cfg->blocksize_1_exp = vorbis_get_blocksize_exp(256); //short
|
||||
|
||||
data->op.bytes = build_header_identification(data->buffer, data->buffer_size, &cfg);
|
||||
data->op.bytes = build_header_identification(data->buffer, data->buffer_size, cfg);
|
||||
if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) /* identification packet */
|
||||
goto fail;
|
||||
|
||||
|
@ -44,7 +41,7 @@ int vorbis_custom_setup_init_fsb(STREAMFILE* sf, off_t start_offset, vorbis_cust
|
|||
if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) /* comment packet */
|
||||
goto fail;
|
||||
|
||||
data->op.bytes = build_header_setup(data->buffer, data->buffer_size, cfg.setup_id, sf);
|
||||
data->op.bytes = build_header_setup(data->buffer, data->buffer_size, cfg->setup_id, sf);
|
||||
if (vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op) != 0) /* setup packet */
|
||||
goto fail;
|
||||
|
||||
|
@ -77,27 +74,7 @@ fail:
|
|||
/* INTERNAL HELPERS */
|
||||
/* **************************************************************************** */
|
||||
|
||||
static int build_header_setup(uint8_t* buf, size_t bufsize, uint32_t setup_id, STREAMFILE* sf) {
|
||||
int bytes;
|
||||
|
||||
/* try to locate from the precompiled list */
|
||||
bytes = load_fvs_array(buf, bufsize, setup_id, sf);
|
||||
if (bytes)
|
||||
return bytes;
|
||||
|
||||
#if !(FSB_VORBIS_USE_PRECOMPILED_FVS)
|
||||
/* try to load from external files */
|
||||
bytes = load_fvs_file(buf, bufsize, setup_id, sf);
|
||||
if (bytes)
|
||||
return bytes;
|
||||
#endif
|
||||
|
||||
/* not found */
|
||||
VGM_LOG("FSB Vorbis: setup_id %08x not found\n", setup_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !(FSB_VORBIS_USE_PRECOMPILED_FVS)
|
||||
#ifdef VGM_DISABLE_CODEBOOKS
|
||||
static int load_fvs_file(uint8_t* buf, size_t bufsize, uint32_t setup_id, STREAMFILE* sf) {
|
||||
STREAMFILE* sf_setup = NULL;
|
||||
|
||||
|
@ -143,22 +120,22 @@ fail:
|
|||
}
|
||||
#endif
|
||||
|
||||
static int load_fvs_array(uint8_t* buf, size_t bufsize, uint32_t setup_id, STREAMFILE* sf) {
|
||||
#if FSB_VORBIS_USE_PRECOMPILED_FVS
|
||||
int i, list_length;
|
||||
static int build_header_setup(uint8_t* buf, size_t bufsize, uint32_t setup_id, STREAMFILE* sf) {
|
||||
int bytes;
|
||||
|
||||
list_length = sizeof(fvs_list) / sizeof(fvs_info);
|
||||
for (i=0; i < list_length; i++) {
|
||||
if (fvs_list[i].id == setup_id) {
|
||||
if (fvs_list[i].size > bufsize) goto fail;
|
||||
/* found: copy data as-is */
|
||||
memcpy(buf,fvs_list[i].setup, fvs_list[i].size);
|
||||
return fvs_list[i].size;
|
||||
}
|
||||
}
|
||||
|
||||
fail:
|
||||
#ifndef VGM_DISABLE_CODEBOOKS
|
||||
// locate from precompiled list
|
||||
bytes = vcb_load_codebook_array(buf, bufsize, setup_id, vcb_list, vcb_list_count);
|
||||
if (bytes)
|
||||
return bytes;
|
||||
#else
|
||||
// load from external files
|
||||
bytes = load_fvs_file(buf, bufsize, setup_id, sf);
|
||||
if (bytes)
|
||||
return bytes;
|
||||
#endif
|
||||
|
||||
VGM_LOG("FSB Vorbis: setup_id %08x not found\n", setup_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,237 @@
|
|||
#include "vorbis_custom_decoder.h"
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
#include <vorbis/codec.h>
|
||||
#include "libs/oor_helpers.h"
|
||||
|
||||
// if enabled vgmstream weights ~20kb more
|
||||
#ifndef VGM_DISABLE_CODEBOOKS
|
||||
#include "libs/vorbis_codebooks_oor.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
// read current page's info and save it to persist between decode calls
|
||||
static int read_page_info(vorbis_custom_codec_data* data, STREAMFILE* sf, uint32_t page_offset) {
|
||||
|
||||
// bitreader data
|
||||
uint8_t buf[0x200]; // variable but shouldn't need to be bigger than this
|
||||
int buf_size = sizeof(buf);
|
||||
|
||||
//TODO: this will overread a bit; it's possible to load beginning + calc size + load rest, but to simplify...
|
||||
int bytes = read_streamfile(buf, page_offset, buf_size, sf);
|
||||
if (bytes != buf_size) return false;
|
||||
|
||||
bitstream_t is_tmp;
|
||||
bitstream_t* is = &is_tmp;
|
||||
bm_setup(is, buf, bytes);
|
||||
|
||||
// oor bitstream info
|
||||
oor_page_t page = {0};
|
||||
oor_size_t size = {0};
|
||||
|
||||
oor_read_page(is, &page);
|
||||
oor_read_size(is, &size);
|
||||
if (!oor_validate_audio_page(&page, &size, NULL))
|
||||
return 0;
|
||||
|
||||
if (size.packet_count >= MAX_PACKET_SIZES) {
|
||||
VGM_LOG("OOR: packet count %i bigger than observed max (report)\n", size.packet_count);
|
||||
return 0;
|
||||
}
|
||||
|
||||
//TODO: maybe put into a separate struct
|
||||
data->flags = page.flags;
|
||||
data->packet_count = size.packet_count;
|
||||
for (int i = 0; i < size.packet_count; i++) {
|
||||
data->packet_size[i] = size.base_packet_size + size.variable_packet_size[i];
|
||||
}
|
||||
|
||||
int page_size = bm_pos(is) / 8; // aligned
|
||||
return page_size;
|
||||
}
|
||||
|
||||
// Reads a single packet, which may be split into multiple pages (much like OggS).
|
||||
// returns current packet size but also advances offsets, given it may need to read multiple pages.
|
||||
static int read_packet(uint8_t* buf, int buf_size, vorbis_custom_codec_data* data, STREAMFILE* sf, uint32_t* p_offset) {
|
||||
int read_size = 0;
|
||||
|
||||
// handle split packets: (similar to vorbis?)
|
||||
// - OOR_FLAG_CONTINUED and is last packet of a page: packet is joined with next packet
|
||||
// - OOR_FLAG_PARTIAL and is first packet of a page: packet is joined with prev packet
|
||||
// - otherwise: read normally
|
||||
// in OOR, packets may be split like full-size (curr page) + 0-size (next page), or splitsetup packet
|
||||
|
||||
while (true) {
|
||||
|
||||
// OOR allows 0-sized packets marked as partial, but not sure if prev packet can be 0
|
||||
//if ((data->flags & OOR_FLAG_CONTINUED) && read_size == 0)
|
||||
// return 0;
|
||||
|
||||
// new page
|
||||
if (data->current_packet == 0) {
|
||||
|
||||
// no new pages after flag is set
|
||||
if (data->flags & OOR_FLAG_EOS)
|
||||
return 0;
|
||||
|
||||
int page_size = read_page_info(data, sf, *p_offset);
|
||||
if (!page_size) return 0;
|
||||
|
||||
*p_offset += page_size;
|
||||
|
||||
if (data->packet_count == 0) {
|
||||
VGM_LOG("OOR: empty page found\n");
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
// read chunk to buf (note that size 0 is valid in rare cases)
|
||||
int packet_size = data->packet_size[data->current_packet];
|
||||
data->current_packet++;
|
||||
|
||||
if (data->current_packet == data->packet_count)
|
||||
data->current_packet = 0;
|
||||
|
||||
if (read_size + packet_size > buf_size) {
|
||||
VGM_LOG("OOR: packet too big\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
int bytes = read_streamfile(buf + read_size, *p_offset, packet_size, sf);
|
||||
if (bytes != packet_size)
|
||||
return 0;
|
||||
|
||||
*p_offset += packet_size;
|
||||
read_size += packet_size;
|
||||
|
||||
// packet with continued flag must be merged with next packet (typically in next page)
|
||||
bool is_last = data->current_packet == 0; // was reset above
|
||||
if (!(is_last && (data->flags & OOR_FLAG_PARTIAL)))
|
||||
break;
|
||||
}
|
||||
|
||||
return read_size;
|
||||
}
|
||||
|
||||
// read header info (1st page) and extract info to init Vorbis
|
||||
static int read_header_packet(vorbis_custom_codec_data* data, STREAMFILE* sf, uint32_t* p_offset) {
|
||||
|
||||
// bitreader data
|
||||
uint8_t* buf = data->buffer;
|
||||
int hdr_size = 0x20; // variable but should be smaller
|
||||
if (hdr_size > data->buffer_size)
|
||||
return 0;
|
||||
|
||||
int bytes = read_streamfile(buf, *p_offset, hdr_size, sf);
|
||||
if (bytes != hdr_size) return 0;
|
||||
|
||||
bitstream_t is = {0};
|
||||
bm_setup(&is, buf, bytes);
|
||||
|
||||
// oor bitstream info
|
||||
oor_page_t page = {0};
|
||||
oor_header_t hdr = {0};
|
||||
|
||||
// header page
|
||||
oor_read_page(&is, &page);
|
||||
oor_read_header(&is, &hdr);
|
||||
if (!oor_validate_header_page(&page, &hdr))
|
||||
return 0;
|
||||
|
||||
// load info for header (also used for output)
|
||||
vorbis_custom_config* cfg = &data->config;
|
||||
cfg->channels = hdr.channels;
|
||||
cfg->sample_rate = hdr.sample_rate;
|
||||
cfg->blocksize_0_exp = hdr.blocksize0_exp;
|
||||
cfg->blocksize_1_exp = hdr.blocksize1_exp;
|
||||
cfg->last_granule = hdr.last_granule;
|
||||
|
||||
uint32_t packet_size = (bm_pos(&is) / 8);
|
||||
*p_offset += packet_size;
|
||||
return packet_size;
|
||||
}
|
||||
|
||||
// read setup info (2nd page) and load codebooks info buf
|
||||
static int build_header_setup(uint8_t* buf, int buf_size, vorbis_custom_codec_data* data, STREAMFILE* sf, uint32_t* p_offset) {
|
||||
|
||||
// setup info packet
|
||||
int info_size = read_packet(buf, buf_size, data, sf, p_offset);
|
||||
if (!info_size) return 0;
|
||||
|
||||
if (info_size != 0x01) //fixed mini-packet
|
||||
return 0;
|
||||
bitstream_t is = {0};
|
||||
bm_setup(&is, data->buffer, info_size);
|
||||
|
||||
oor_setup_t setup = {0};
|
||||
oor_read_setup(&is, &setup);
|
||||
|
||||
|
||||
// paste missing info
|
||||
if (buf_size <= 0x07)
|
||||
return 0;
|
||||
put_u8 (buf+0x00, 0x05); // packet_type (setup)
|
||||
memcpy (buf+0x01, "vorbis", 6); // id
|
||||
|
||||
// read actual codebook based on prev mini-packet
|
||||
int setup_size;
|
||||
if (setup.codebook_id) {
|
||||
#ifndef VGM_DISABLE_CODEBOOKS
|
||||
// load setup from data in executables
|
||||
setup_size = vcb_load_codebook_array(buf + 0x07, buf_size - 0x07, setup.codebook_id, vcb_list, vcb_list_count);
|
||||
if (!setup_size) return 0;
|
||||
#else
|
||||
setup_size = 0;
|
||||
#endif
|
||||
// next packet is always 0 when codebook id is set
|
||||
int empty_size = read_packet(buf + 0x07 + setup_size, buf_size - 0x07 - setup_size, data, sf, p_offset);
|
||||
if (empty_size != 0) return 0;
|
||||
}
|
||||
else {
|
||||
// load setup from data in file
|
||||
setup_size = read_packet(buf + 0x07, buf_size - 0x07, data, sf, p_offset);
|
||||
if (!setup_size) return 0;
|
||||
}
|
||||
|
||||
return 0x07 + setup_size;
|
||||
}
|
||||
|
||||
|
||||
int vorbis_custom_setup_init_oor(STREAMFILE* sf, off_t start_offset, vorbis_custom_codec_data* data) {
|
||||
int ret;
|
||||
uint32_t offset = start_offset;
|
||||
|
||||
// header
|
||||
int head_size = read_header_packet(data, sf, &offset);
|
||||
if (!head_size) return false;
|
||||
|
||||
// identification packet
|
||||
data->op.bytes = build_header_identification(data->buffer, data->buffer_size, &data->config);
|
||||
ret = vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op);
|
||||
if (ret != 0) return false;
|
||||
|
||||
// comment packet
|
||||
data->op.bytes = build_header_comment(data->buffer, data->buffer_size);
|
||||
ret = vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op);
|
||||
if (ret != 0) return false;
|
||||
|
||||
// setup packet
|
||||
data->op.bytes = build_header_setup(data->buffer, data->buffer_size, data, sf, &offset);
|
||||
ret = vorbis_synthesis_headerin(&data->vi, &data->vc, &data->op);
|
||||
if (ret != 0) return false;
|
||||
|
||||
data->config.data_start_offset = offset;
|
||||
return true;
|
||||
}
|
||||
|
||||
int vorbis_custom_parse_packet_oor(VGMSTREAMCHANNEL* stream, vorbis_custom_codec_data* data) {
|
||||
uint32_t offset = stream->offset;
|
||||
|
||||
data->op.bytes = read_packet(data->buffer, data->buffer_size, data, stream->streamfile, &offset);
|
||||
stream->offset = offset;
|
||||
|
||||
return data->op.bytes != 0;
|
||||
}
|
||||
|
||||
#endif
|
|
@ -4,9 +4,9 @@
|
|||
#include <vorbis/codec.h>
|
||||
#include "../util/bitstream_lsb.h"
|
||||
|
||||
#define WWISE_VORBIS_USE_PRECOMPILED_WVC 1 /* if enabled vgmstream weights ~150kb more but doesn't need external .wvc packets */
|
||||
#if WWISE_VORBIS_USE_PRECOMPILED_WVC
|
||||
#include "vorbis_custom_data_wwise.h"
|
||||
// if enabled vgmstream weights ~150kb more but doesn't need external packets
|
||||
#ifndef VGM_DISABLE_CODEBOOKS
|
||||
#include "libs/vorbis_codebooks_wwise.h"
|
||||
#endif
|
||||
|
||||
|
||||
|
@ -30,11 +30,7 @@ static size_t rebuild_setup(uint8_t* obuf, size_t obufsize, wpacket_t* wp, STREA
|
|||
static int ww2ogg_generate_vorbis_packet(bitstream_t* ow, bitstream_t* iw, wpacket_t* wp, vorbis_custom_codec_data* data);
|
||||
static int ww2ogg_generate_vorbis_setup(bitstream_t* ow, bitstream_t* iw, vorbis_custom_codec_data* data, size_t packet_size, STREAMFILE* sf);
|
||||
|
||||
static int load_wvc(uint8_t* ibuf, size_t ibufsize, uint32_t codebook_id, wwise_setup_t setup_type, STREAMFILE* sf);
|
||||
#if !(WWISE_VORBIS_USE_PRECOMPILED_WVC)
|
||||
static int load_wvc_file(uint8_t* buf, size_t bufsize, uint32_t codebook_id, STREAMFILE* sf);
|
||||
#endif
|
||||
static int load_wvc_array(uint8_t* buf, size_t bufsize, uint32_t codebook_id, wwise_setup_t setup_type);
|
||||
static int load_codebooks(uint8_t* ibuf, size_t ibufsize, uint32_t codebook_id, wwise_setup_t setup_type, STREAMFILE* sf);
|
||||
|
||||
|
||||
/* **************************************************************************** */
|
||||
|
@ -676,7 +672,7 @@ static int ww2ogg_codebook_library_rebuild_by_id(bitstream_t* ow, uint32_t codeb
|
|||
size_t cb_size;
|
||||
bitstream_t iw;
|
||||
|
||||
cb_size = load_wvc(ibuf,ibufsize, codebook_id, setup_type, sf);
|
||||
cb_size = load_codebooks(ibuf,ibufsize, codebook_id, setup_type, sf);
|
||||
if (cb_size == 0) goto fail;
|
||||
|
||||
bl_setup(&iw, ibuf, ibufsize);
|
||||
|
@ -1083,28 +1079,7 @@ fail:
|
|||
/* INTERNAL UTILS */
|
||||
/* **************************************************************************** */
|
||||
|
||||
/* loads an external Wwise Vorbis Codebooks file (wvc) referenced by ID and returns size */
|
||||
static int load_wvc(uint8_t* ibuf, size_t ibufsize, uint32_t codebook_id, wwise_setup_t setup_type, STREAMFILE* sf) {
|
||||
size_t bytes;
|
||||
|
||||
/* try to locate from the precompiled list */
|
||||
bytes = load_wvc_array(ibuf, ibufsize, codebook_id, setup_type);
|
||||
if (bytes)
|
||||
return bytes;
|
||||
|
||||
#if !(WWISE_VORBIS_USE_PRECOMPILED_WVC)
|
||||
/* try to load from external file (ignoring type, just use file if found) */
|
||||
bytes = load_wvc_file(ibuf, ibufsize, codebook_id, sf);
|
||||
if (bytes)
|
||||
return bytes;
|
||||
#endif
|
||||
|
||||
/* not found */
|
||||
VGM_LOG("Wwise Vorbis: codebook_id %04x not found\n", codebook_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if !(WWISE_VORBIS_USE_PRECOMPILED_WVC)
|
||||
#ifdef VGM_DISABLE_CODEBOOKS
|
||||
static int load_wvc_file(uint8_t* buf, size_t bufsize, uint32_t codebook_id, STREAMFILE* sf) {
|
||||
STREAMFILE* sf_setup = NULL;
|
||||
size_t wvc_size = 0;
|
||||
|
@ -1149,36 +1124,25 @@ fail:
|
|||
}
|
||||
#endif
|
||||
|
||||
static int load_wvc_array(uint8_t* buf, size_t bufsize, uint32_t codebook_id, wwise_setup_t setup_type) {
|
||||
#if WWISE_VORBIS_USE_PRECOMPILED_WVC
|
||||
/* loads an external Wwise Vorbis Codebooks file (wvc) referenced by ID and returns size */
|
||||
static int load_codebooks(uint8_t* ibuf, size_t ibufsize, uint32_t codebook_id, wwise_setup_t setup_type, STREAMFILE* sf) {
|
||||
int bytes;
|
||||
|
||||
/* get pointer to array */
|
||||
{
|
||||
int i, list_length;
|
||||
const wvc_info * wvc_list;
|
||||
#ifndef VGM_DISABLE_CODEBOOKS
|
||||
|
||||
switch (setup_type) {
|
||||
case WWV_EXTERNAL_CODEBOOKS:
|
||||
wvc_list = wvc_list_standard;
|
||||
list_length = sizeof(wvc_list_standard) / sizeof(wvc_info);
|
||||
break;
|
||||
case WWV_AOTUV603_CODEBOOKS:
|
||||
wvc_list = wvc_list_aotuv603;
|
||||
list_length = sizeof(wvc_list_standard) / sizeof(wvc_info);
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
for (i=0; i < list_length; i++) {
|
||||
if (wvc_list[i].id == codebook_id) {
|
||||
if (wvc_list[i].size > bufsize) goto fail;
|
||||
/* found: copy data as-is */
|
||||
memcpy(buf,wvc_list[i].codebook, wvc_list[i].size);
|
||||
return wvc_list[i].size;
|
||||
}
|
||||
}
|
||||
// locate from precompiled list
|
||||
switch (setup_type) {
|
||||
case WWV_EXTERNAL_CODEBOOKS:
|
||||
bytes = vcb_load_codebook_array(ibuf, ibufsize, codebook_id, vcb_list_standard, vcb_list_count_standard);
|
||||
break;
|
||||
case WWV_AOTUV603_CODEBOOKS:
|
||||
bytes = vcb_load_codebook_array(ibuf, ibufsize, codebook_id, vcb_list_aotuv603, vcb_list_count_aotuv603);
|
||||
break;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
if (bytes)
|
||||
return bytes;
|
||||
|
||||
// this can be used with 1:1 dump of the codebook file
|
||||
#if 0
|
||||
|
@ -1204,8 +1168,14 @@ static int load_wvc_array(uint8_t* buf, size_t bufsize, uint32_t codebook_id, ww
|
|||
}
|
||||
#endif
|
||||
|
||||
fail:
|
||||
#else
|
||||
// load from external files
|
||||
bytes = load_wvc_file(ibuf, ibufsize, codebook_id, sf);
|
||||
if (bytes)
|
||||
return bytes;
|
||||
#endif
|
||||
|
||||
VGM_LOG("Wwise Vorbis: codebook_id %04x not found\n", codebook_id);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
|
|
@ -350,6 +350,7 @@ static const char* extension_list[] = {
|
|||
"mi4", //fake extension for .mib (renamed, to be removed)
|
||||
"mib",
|
||||
"mic",
|
||||
"mio",
|
||||
"mnstr",
|
||||
"mogg",
|
||||
//"m4a", //common
|
||||
|
@ -418,6 +419,7 @@ static const char* extension_list[] = {
|
|||
"ogv",
|
||||
"oma", //FFmpeg/not parsed (ATRAC3/ATRAC3PLUS/MP3/LPCM/WMA)
|
||||
"omu",
|
||||
"oor",
|
||||
"opu",
|
||||
//"opus", //common
|
||||
"opusx",
|
||||
|
@ -667,7 +669,6 @@ static const char* extension_list[] = {
|
|||
"wic", //txth/reserved [Road Rash (SAT)-videos]
|
||||
"wip", //txth/reserved [Colin McRae DiRT (PC)]
|
||||
"wlv", //txth/reserved [ToeJam & Earl III: Mission to Earth (DC)]
|
||||
"wmus", //fake extension (to be removed)
|
||||
"wp2",
|
||||
"wpd",
|
||||
"wsd",
|
||||
|
@ -924,7 +925,9 @@ static const coding_info coding_info_list[] = {
|
|||
{coding_TAC, "tri-Ace Codec"},
|
||||
{coding_ICE_RANGE, "Inti Creates Range Codec"},
|
||||
{coding_ICE_DCT, "Inti Creates DCT Codec"},
|
||||
{coding_KA1A, "Koei Tecmo KA1A Codec"},
|
||||
{coding_KA1A, "Koei Tecmo KA1A"},
|
||||
{coding_UBI_MPEG, "Ubisoft MPEG"},
|
||||
{coding_MIO, "Entis MIO"},
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
{coding_OGG_VORBIS, "Ogg Vorbis"},
|
||||
|
@ -1178,7 +1181,6 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_PS2_SND, "Might and Magic SSND Header"},
|
||||
{meta_SMSS, "Treasure SMSS header"},
|
||||
{meta_ADS_MIDWAY, "Midway ADS header"},
|
||||
{meta_PS2_MCG, "Gunvari MCG Header"},
|
||||
{meta_ZSD, "Konami ZSD header"},
|
||||
{meta_REDSPARK, "RedSpark header"},
|
||||
{meta_RAGE_AUD, "Rockstar AUD header"},
|
||||
|
@ -1214,7 +1216,7 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_WB, "Triangle Service .WB header"},
|
||||
{meta_S14, "Namco .S14 raw header"},
|
||||
{meta_SSS, "Namco .SSS raw header"},
|
||||
{meta_PS2_GCM, "Namco GCM header"},
|
||||
{meta_MCG, "Namco MCG header"},
|
||||
{meta_SMPL, "Skonec SMPL header"},
|
||||
{meta_MSA, "Success .MSA header"},
|
||||
{meta_VOI, "Irem .VOI header"},
|
||||
|
@ -1250,7 +1252,6 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_LSF_N1NJ4N, "Gizmondo Studios Helsingborg LSF header"},
|
||||
{meta_XWAV, "feelplus XWAV header"},
|
||||
{meta_RAW_SNDS, "PC .snds raw header"},
|
||||
{meta_PS2_WMUS, "assumed The Warriors Sony ADPCM by .wmus extension"},
|
||||
{meta_HYPERSCAN_KVAG, "Mattel Hyperscan KVAG"},
|
||||
{meta_PSND, "Polarbit PSND header"},
|
||||
{meta_ADP_WILDFIRE, "Wildfire ADP! header"},
|
||||
|
@ -1473,7 +1474,9 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_XABP, "cavia XABp header"},
|
||||
{meta_I3DS, "Codemasters i3DS header"},
|
||||
{meta_AXHD, "Angel Studios AXHD header"},
|
||||
{meta_SHAA, "Nintendo Alarmo SHAA header"}
|
||||
{meta_SHAA, "Nintendo SHAA header"},
|
||||
{meta_OOR, "age .OOR header"},
|
||||
{meta_MIO, "Entis .MIO header"},
|
||||
};
|
||||
|
||||
void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) {
|
||||
|
|
|
@ -18,9 +18,9 @@
|
|||
* This may make the API a bit odd, will probably improve later. Probably.
|
||||
*
|
||||
* Notes:
|
||||
* - now there is an API, internals (vgmstream.h) may change in the future so avoid accesing them
|
||||
* - now there is an API, internals (vgmstream.h) will change in the future so avoid accesing them
|
||||
* - some details described in the API may not happen at the moment (defined for future changes)
|
||||
* - uses long-winded libvgmstream_* names since internals alredy use the vgmstream_* 'namespace', #define as needed
|
||||
* - uses long-winded libvgmstream_* names since internals alredy use the vgmstream_* 'namespace', #define if needed
|
||||
* - c-strings should be in UTF-8
|
||||
*/
|
||||
|
||||
|
@ -71,20 +71,20 @@ LIBVGMSTREAM_API uint32_t libvgmstream_get_version(void);
|
|||
/*****************************************************************************/
|
||||
/* DECODE */
|
||||
|
||||
/* interleaved samples: buf[0]=ch0, buf[1]=ch1, buf[2]=ch0, buf[3]=ch0, ... */
|
||||
typedef enum {
|
||||
LIBVGMSTREAM_SAMPLE_PCM16 = 1,
|
||||
LIBVGMSTREAM_SAMPLE_PCM24 = 2,
|
||||
LIBVGMSTREAM_SAMPLE_PCM32 = 3,
|
||||
LIBVGMSTREAM_SAMPLE_FLOAT = 4,
|
||||
} libvgmstream_sample_t;
|
||||
/* 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_FLOAT = 4,
|
||||
} libvgmstream_sfmt_t;
|
||||
|
||||
/* current song info, may be copied around (values are info-only) */
|
||||
typedef struct {
|
||||
/* main (always set) */
|
||||
int channels; // output channels
|
||||
int sample_rate; // output sample rate
|
||||
libvgmstream_sample_t sample_type; // output buffer's sample type
|
||||
libvgmstream_sfmt_t sample_format; // output buffer's sample type
|
||||
int sample_size; // derived from sample_type (pcm16=0x02, float=0x04, etc)
|
||||
|
||||
/* extra info (may be 0 if not known or not relevant) */
|
||||
|
@ -126,8 +126,8 @@ typedef struct {
|
|||
// query description and since libvgmstream returns its own copy it shouldn't be too much of a problem
|
||||
// ** (may be separated later)
|
||||
|
||||
int format_id; // when reopening subfiles or similar formats without checking other all possible formats
|
||||
// ** this value WILL change without warning between vgmstream versions/commits, but usually only add
|
||||
int format_id; // current format's ID (can be set when reopening streams to load a particular format)
|
||||
// ** this value WILL change without warning between vgmstream versions/commits
|
||||
|
||||
} libvgmstream_format_t;
|
||||
|
||||
|
@ -165,6 +165,7 @@ LIBVGMSTREAM_API void libvgmstream_free(libvgmstream_t* lib);
|
|||
|
||||
/* configures how vgmstream behaves internally when playing a file */
|
||||
typedef struct {
|
||||
|
||||
bool disable_config_override; // ignore forced (TXTP) config
|
||||
bool allow_play_forever; // must allow manually as some cases a TXTP may set loop forever but client may not handle it
|
||||
|
||||
|
@ -174,46 +175,39 @@ typedef struct {
|
|||
bool really_force_loop; // forces full loops (0..samples) even if file has loop points
|
||||
bool ignore_fade; // don't fade after N loops and play remaning stream (for files with outros)
|
||||
|
||||
double loop_count; // target loops (values like 1.5 are ok)
|
||||
double loop_count; // target loops (values like 1.5 are ok); defaults to 1; set to -1 to remove the loop section
|
||||
double fade_time; // fade period after target loops
|
||||
double fade_delay; // fade delay after target loops
|
||||
|
||||
int stereo_track; // forces vgmstream to decode one 2ch+2ch+2ch... 'track' and discard other channels, where 0 = disabled, 1..N = Nth track
|
||||
int auto_downmix_channels; // downmix if vgmstream's channels are higher than value
|
||||
// ** for players that can only handle N channels
|
||||
// ** this type of downmixing is very simplistic and not recommended
|
||||
|
||||
bool force_pcm16; // forces output buffer to be remixed into PCM16
|
||||
bool force_float; // forces output buffer to be remixed into float
|
||||
libvgmstream_sfmt_t force_sfmt; // forces output buffer to be remixed into some sample format
|
||||
|
||||
//int format_id; // force a format (for example when loading new subsong of the same archive, for a minuscule speed up)
|
||||
// // ** only applies when called before _open_stream
|
||||
|
||||
} libvgmstream_config_t;
|
||||
|
||||
/* pass default config, that will be applied to song on open
|
||||
* - invalid config or complex cases (ex. some TXTP) may ignore these settings
|
||||
* - should be called without a song loaded (before _open or after _close)
|
||||
* - without config vgmstream will decode the current stream once
|
||||
/* optionally pass config to apply to next _open_stream (or current stream if already loaded and not setup previously)
|
||||
* - some settings may be ignored in invalid or complex cases (ex. TXTP with pre-configured options)
|
||||
* - once config is applied to current stream new _setup calls only apply to next _open_stream
|
||||
* - pass NULL to clear current config
|
||||
* - remember config may change format info like channels or output format (recheck if calling after loading song)
|
||||
*/
|
||||
LIBVGMSTREAM_API void libvgmstream_setup(libvgmstream_t* lib, libvgmstream_config_t* cfg);
|
||||
|
||||
|
||||
/* configures how vgmstream opens the format */
|
||||
typedef struct {
|
||||
libstreamfile_t* libsf; // custom IO streamfile that provides reader info for vgmstream
|
||||
// ** not needed after _open and should be closed, as vgmstream re-opens its own SFs internally as needed
|
||||
|
||||
int subsong_index; // target subsong (1..N) or 0 = default/first
|
||||
// ** to check if a file has subsongs, _open first + check format->total_subsongs (then _open 2nd, 3rd, etc)
|
||||
|
||||
int format_id; // force a format (for example when loading new subsong of the same archive)
|
||||
|
||||
int stereo_track; // forces vgmstream to decode one 2ch+2ch+2ch... 'track' and discard other channels, where 0 = disabled, 1..N = Nth track
|
||||
|
||||
} libvgmstream_options_t;
|
||||
|
||||
/* Opens file based on config and prepares it to play if supported.
|
||||
* - returns < 0 on error (file not recognised, invalid subsong index, etc)
|
||||
* - will close currently loaded song if needed
|
||||
* - libsf (custom IO) is not needed after _open and should be closed, as vgmstream re-opens as needed
|
||||
* - subsong can be 1..N or 0 = default/first
|
||||
* ** to check if a file has subsongs, _open default + check format->total_subsongs (then _open Nth)
|
||||
*/
|
||||
LIBVGMSTREAM_API int libvgmstream_open_stream(libvgmstream_t* lib, libvgmstream_options_t* open_options);
|
||||
LIBVGMSTREAM_API int libvgmstream_open_stream(libvgmstream_t* lib, libstreamfile_t* libsf, int subsong);
|
||||
|
||||
/* Closes current song; may still use libvgmstream to open other songs
|
||||
*/
|
||||
|
@ -222,6 +216,7 @@ LIBVGMSTREAM_API void libvgmstream_close_stream(libvgmstream_t* lib);
|
|||
|
||||
/* Decodes next batch of samples
|
||||
* - vgmstream supplies its own buffer, updated on lib->decoder->* values (may change between calls)
|
||||
* - on last call will return samples + set flag lib->decoder->done (must handle last buf before quitting)
|
||||
* - returns < 0 on error
|
||||
*/
|
||||
LIBVGMSTREAM_API int libvgmstream_render(libvgmstream_t* lib);
|
||||
|
@ -248,6 +243,10 @@ LIBVGMSTREAM_API void libvgmstream_seek(libvgmstream_t* lib, int64_t sample);
|
|||
LIBVGMSTREAM_API void libvgmstream_reset(libvgmstream_t* lib);
|
||||
|
||||
|
||||
/* Helper: calls _init + _setup + _open_stream
|
||||
*/
|
||||
LIBVGMSTREAM_API libvgmstream_t* libvgmstream_create(libstreamfile_t* libsf, int subsong, libvgmstream_config_t* cfg);
|
||||
|
||||
|
||||
/*****************************************************************************/
|
||||
/* HELPERS */
|
||||
|
@ -259,29 +258,25 @@ typedef enum {
|
|||
LIBVGMSTREAM_LOG_LEVEL_NONE = 100,
|
||||
} libvgmstream_loglevel_t;
|
||||
|
||||
typedef struct {
|
||||
libvgmstream_loglevel_t level; // log level
|
||||
void (*callback)(int level, const char* str); // log callback
|
||||
bool stdout_callback; // use default log callback rather than user supplied
|
||||
} libvgmstream_log_t;
|
||||
|
||||
/* Defines a global log callback, as vgmstream sometimes communicates format issues to the user.
|
||||
* - note that log is currently set globally rather than per libvgmstream_t
|
||||
* - call with LOG_LEVEL_NONE to disable current callback
|
||||
* - call with NULL callback to use default stdout callback
|
||||
*/
|
||||
LIBVGMSTREAM_API void libvgmstream_set_log(libvgmstream_log_t* cfg);
|
||||
LIBVGMSTREAM_API void libvgmstream_set_log(libvgmstream_loglevel_t level, void (*callback)(int level, const char* str));
|
||||
|
||||
|
||||
/* Returns a list of supported extensions (WARNING: it's pretty big), such as "adx", "dsp", etc.
|
||||
* Mainly for plugins that want to know which extensions are supported.
|
||||
* - returns NULL if no size is provided
|
||||
*/
|
||||
LIBVGMSTREAM_API const char** libvgmstream_get_extensions(size_t* size);
|
||||
LIBVGMSTREAM_API const char** libvgmstream_get_extensions(int* size);
|
||||
|
||||
/* Same as above, buf returns a list what vgmstream considers "common" formats (such as "wav", "ogg"),
|
||||
* which usually one doesn't want to associate to vgmstream.
|
||||
* - returns NULL if no size is provided
|
||||
*/
|
||||
LIBVGMSTREAM_API const char** libvgmstream_get_common_extensions(size_t* size);
|
||||
LIBVGMSTREAM_API const char** libvgmstream_get_common_extensions(int* size);
|
||||
|
||||
|
||||
typedef struct {
|
||||
|
@ -301,7 +296,7 @@ LIBVGMSTREAM_API bool libvgmstream_is_valid(const char* filename, libvgmstream_v
|
|||
|
||||
|
||||
typedef struct {
|
||||
bool force_title; // TODO: what was this for?
|
||||
bool force_title; // force stream name as title (by default it may be hiddedn if file has no subsongs)
|
||||
bool subsong_range; // print a range of possible subsongs after title 'filename#1~N'
|
||||
bool remove_extension; // remove extension from passed filename
|
||||
bool remove_archive; // remove '(archive)|(subfile)' format of some plugins
|
||||
|
@ -350,11 +345,13 @@ LIBVGMSTREAM_API void libvgmstream_tags_find(libvgmstream_tags_t* tags, const ch
|
|||
|
||||
/* Extracts next valid tag in tagfile to key/val.
|
||||
* - returns false if no more tags are found (meant to be called repeatedly until false)
|
||||
* - key/values are trimmed of beginning/end whitespaces and values are in UTF-8
|
||||
* - key/values are trimmed of beginning/end whitespaces and values are UTF-8
|
||||
*/
|
||||
LIBVGMSTREAM_API bool libvgmstream_tags_next_tag(libvgmstream_tags_t* tags);
|
||||
|
||||
/* Closes tags. */
|
||||
/* Closes tags.
|
||||
* - passed libsf is not closed
|
||||
*/
|
||||
LIBVGMSTREAM_API void libvgmstream_tags_free(libvgmstream_tags_t* tags);
|
||||
|
||||
|
||||
|
|
|
@ -3,44 +3,33 @@
|
|||
#include "libvgmstream.h"
|
||||
|
||||
/* vgmstream's IO API, defined as a "streamfile" ('SF').
|
||||
*
|
||||
* vgmstream mostly assumes there is an underlying filesystem (as usual in games), plus given video game formats are
|
||||
*
|
||||
* vgmstream mostly assumes there is an underlying filesystem (as usual in games), plus given video game formats are
|
||||
* often ill-defined it needs extra ops to handle edge cases: seeking + reading from arbitrary offsets, opening companion
|
||||
* files, filename/size tests, etc.
|
||||
*
|
||||
*
|
||||
* If your case is too different you may still create a partial streamfile: returning a fake filename, only handling "open"
|
||||
* that reopens itself (same filename), etc. Simpler formats should work fine.
|
||||
*/
|
||||
|
||||
|
||||
enum {
|
||||
LIBSTREAMFILE_SEEK_SET = 0,
|
||||
LIBSTREAMFILE_SEEK_CUR = 1,
|
||||
LIBSTREAMFILE_SEEK_END = 2,
|
||||
//LIBSTREAMFILE_SEEK_GET_OFFSET = 3,
|
||||
//LIBSTREAMFILE_SEEK_GET_SIZE = 5,
|
||||
};
|
||||
|
||||
// should be "libvgmstream_streamfile_t" but it was getting unwieldly
|
||||
typedef struct libstreamfile_t {
|
||||
//uint32_t flags; // info flags for vgmstream
|
||||
void* user_data; // any internal structure
|
||||
|
||||
/* read 'length' data at internal offset to 'dst'
|
||||
/* read 'length' data at 'offset' to 'dst'
|
||||
* - assumes 0 = failure/EOF
|
||||
* - note that vgmstream needs to seek + read from arbitrary offset (non-linearly) fairly often
|
||||
*/
|
||||
int (*read)(void* user_data, uint8_t* dst, int dst_size);
|
||||
|
||||
/* seek to offset
|
||||
* - note that vgmstream needs to seek + read fairly often (to be optimized someday)
|
||||
*/
|
||||
int64_t (*seek)(void* user_data, int64_t offset, int whence);
|
||||
int (*read)(void* user_data, uint8_t* dst, int64_t offset, int length);
|
||||
|
||||
/* get max offset (typically for checks or sample calculations)
|
||||
*/
|
||||
int64_t (*get_size)(void* user_data);
|
||||
|
||||
/* get current filename (used to open same or other streamfiles and heuristics; no need to be a real path)
|
||||
/* get current filename
|
||||
* - used to open same or other streamfiles and heuristics; no need to be a real path but extension matters
|
||||
*/
|
||||
const char* (*get_name)(void* user_data);
|
||||
|
||||
|
@ -49,13 +38,14 @@ typedef struct libstreamfile_t {
|
|||
*/
|
||||
struct libstreamfile_t* (*open)(void* user_data, const char* filename);
|
||||
|
||||
/* free current SF */
|
||||
/* free current SF
|
||||
*/
|
||||
void (*close)(struct libstreamfile_t* libsf);
|
||||
|
||||
} libstreamfile_t;
|
||||
|
||||
|
||||
/* helper */
|
||||
/* helpers */
|
||||
static inline void libstreamfile_close(libstreamfile_t* libsf) {
|
||||
if (!libsf || !libsf->close)
|
||||
return;
|
||||
|
|
57
Frameworks/vgmstream/vgmstream/src/meta/2dx.c
Normal file
57
Frameworks/vgmstream/vgmstream/src/meta/2dx.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../layout/layout.h"
|
||||
|
||||
|
||||
/* .2dx - Konami/Bemani beatmania IIDX container [beatmania IIDX 9th Style (AC) - beatmania IIDX 15 DJ TROOPERS (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;
|
||||
|
||||
/* 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;
|
||||
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
total_subsongs = read_u32le(meta_offset + 0x4,sf);
|
||||
if (target_subsong > total_subsongs)
|
||||
goto fail;
|
||||
|
||||
subfile_offset = read_u32le(table_offset + 0x04 * (target_subsong - 1), sf);
|
||||
subfile_size = read_u32le(subfile_offset + 0x8,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);
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_streamfile(temp_sf);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -70,27 +70,27 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||
off_t start_offset = 0, coef_offset = 0;
|
||||
uint32_t aifx_size, file_size;
|
||||
coding_t coding_type = 0;
|
||||
int channels = 0, sample_count = 0, sample_size = 0, sample_rate = 0;
|
||||
int interleave = 0;
|
||||
int loop_flag = 0;
|
||||
int32_t loop_start = 0, loop_end = 0;
|
||||
|
||||
int is_aiff_ext = 0, is_aifc_ext = 0, is_aiff = 0, is_aifc = 0;
|
||||
int fver_found = 0, comm_found = 0, data_found = 0;
|
||||
off_t mark_offset = 0, inst_offset = 0;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "FORM"))
|
||||
return NULL;
|
||||
|
||||
int channels = 0, sample_count = 0, sample_size = 0, sample_rate = 0;
|
||||
int interleave = 0;
|
||||
int loop_flag = 0;
|
||||
int32_t loop_start = 0, loop_end = 0;
|
||||
off_t mark_offset = 0, inst_offset = 0;
|
||||
|
||||
bool is_aiff_ext = false, is_aifc_ext = false, is_aiff = false, is_aifc = false;
|
||||
|
||||
/* .aif: common (AIFF or AIFC)
|
||||
* .wav: SimCity 3000 (Mac) (both AIFF and AIFC)
|
||||
* .aiff: rare and actually AIFC (maybe renamed AIFF too) [Cro-Mag Rally (Mac)]
|
||||
* (extensionless): Doom (3DO)
|
||||
*
|
||||
*
|
||||
* .aifc: renamed AIFC?
|
||||
* .afc: ?
|
||||
* .afc: Waialae Country Club (3D0), Star Wars: Anakin's Speedway (PC)
|
||||
* .cbd2: M2 games
|
||||
* .bgm: Super Street Fighter II Turbo (3DO)
|
||||
* .fda: Homeworld 2 (PC)
|
||||
|
@ -106,14 +106,14 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||
* .mpc: The Godfather (PC) (writercredit.mpc)
|
||||
*/
|
||||
if (check_extensions(sf, "aif,laif,wav,lwav,aiff,laiff,")) {
|
||||
is_aifc_ext = 1;
|
||||
is_aiff_ext = 1;
|
||||
is_aifc_ext = true;
|
||||
is_aiff_ext = true;
|
||||
}
|
||||
else if (check_extensions(sf, "aifc,laifc,afc,cbd2,bgm,fda,n64,xa,caf")) {
|
||||
is_aifc_ext = 1;
|
||||
is_aifc_ext = true;
|
||||
}
|
||||
else if (check_extensions(sf, "acm,adp,ai,pcm,vp6,mpc,lmpc")) {
|
||||
is_aiff_ext = 1;
|
||||
is_aiff_ext = true;
|
||||
}
|
||||
else {
|
||||
return NULL;
|
||||
|
@ -125,15 +125,15 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||
/* AIFF originally allowed only PCM (non-compressed) audio, so newer AIFC was added,
|
||||
* though some AIFF with other codecs exist */
|
||||
if (is_id32be(0x08,sf, "AIFC")) {
|
||||
if (!is_aifc_ext) goto fail;
|
||||
is_aifc = 1;
|
||||
if (!is_aifc_ext) return NULL;
|
||||
is_aifc = true;
|
||||
}
|
||||
else if (is_id32be(0x08,sf, "AIFF")) {
|
||||
if (!is_aiff_ext) goto fail;
|
||||
is_aiff = 1;
|
||||
if (!is_aiff_ext) return NULL;
|
||||
is_aiff = true;
|
||||
}
|
||||
else {
|
||||
goto fail;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* some games have wonky sizes, selectively fix to catch bad rips and new mutations */
|
||||
|
@ -146,31 +146,34 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||
|
||||
if (aifx_size + 0x08 != file_size) {
|
||||
vgm_logi("AIFF: wrong reported size %x + 0x8 vs file size %x\n", aifx_size, file_size);
|
||||
goto fail;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* read through chunks to verify format and find metadata */
|
||||
{
|
||||
bool fver_found = false, comm_found = false, data_found = false;
|
||||
off_t offset = 0x0c; /* start with first chunk within FORM */
|
||||
|
||||
while (offset < file_size) {
|
||||
uint32_t chunk_type = read_u32be(offset + 0x00,sf);
|
||||
uint32_t chunk_size = read_u32be(offset + 0x04,sf);
|
||||
|
||||
/* chunks must be padded to an even number of bytes but chunk
|
||||
* size does not include that padding */
|
||||
offset += 0x08;
|
||||
if (offset + chunk_size > file_size) {
|
||||
VGM_LOG("AIFF: wrong chunk_size %x + %x\n", (int)offset, chunk_size);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
// Chunks must be padded to an even number of bytes but chunk size does not include that padding.
|
||||
// Last chunk it may not be padded so handle after offset check (some tools only?) [Anakin's Speedway (PC)]
|
||||
if (chunk_size % 2)
|
||||
chunk_size++;
|
||||
|
||||
offset += 0x08;
|
||||
if (offset + chunk_size > file_size)
|
||||
goto fail;
|
||||
|
||||
switch(chunk_type) {
|
||||
case 0x46564552: /* "FVER" (version info, officially required but some odd game ommits it [Cro-Mag Rally (Mac)]) */
|
||||
if (fver_found) goto fail;
|
||||
if (is_aiff) goto fail; /* plain AIFF shouldn't have */
|
||||
fver_found = 1;
|
||||
fver_found = true;
|
||||
|
||||
if (chunk_size != 4)
|
||||
goto fail;
|
||||
|
@ -181,7 +184,7 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||
|
||||
case 0x434F4D4D: /* "COMM" (main header) */
|
||||
if (comm_found) goto fail;
|
||||
comm_found = 1;
|
||||
comm_found = true;
|
||||
|
||||
channels = read_u16be(offset + 0x00,sf);
|
||||
sample_count = read_u32be(offset + 0x02,sf); /* sample_frames in theory, depends on codec */
|
||||
|
@ -220,9 +223,10 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||
case 0x434F4D50: { /* "COMP" (generic compression) */
|
||||
uint8_t name_size = read_u8(offset + 0x16, sf);
|
||||
|
||||
if (is_str("Relic Codec v1.6", name_size, offset + 0x17, sf)) {
|
||||
if (is_str("Relic Codec v1.6", name_size, offset + 0x17, sf)) { /* Homeworld 2 (PC) */
|
||||
coding_type = coding_RELIC;
|
||||
sample_count = sample_count * 512;
|
||||
sample_rate = 44100; // fixed output
|
||||
}
|
||||
else {
|
||||
goto fail;
|
||||
|
@ -235,7 +239,14 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||
coding_type = coding_VADPCM;
|
||||
|
||||
/* N64 tools don't create FVER, but it's required by the spec (could skip the check though) */
|
||||
fver_found = 1;
|
||||
fver_found = true;
|
||||
break;
|
||||
}
|
||||
|
||||
case 0x76696D61: { /* "vima" [Star Wars Anakin's Speedway (PC), Star Wars Early Learning Activity Center (PC)] */
|
||||
/* "Variable IMA 16 bit" */
|
||||
coding_type = coding_IMUSE;
|
||||
sample_rate = 22050; // field has garbage (like part of the name) consistently
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -267,7 +278,7 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||
case 0x53534E44: /* "SSND" (main data) */
|
||||
case 0x4150434D: /* "APCM" (main data for XA) */
|
||||
if (data_found) goto fail;
|
||||
data_found = 1;
|
||||
data_found = true;
|
||||
|
||||
/* 00: offset (for aligment, usually 0)
|
||||
* 04: block size (ex. XA: 0x914) */
|
||||
|
@ -315,16 +326,17 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||
|
||||
offset += chunk_size;
|
||||
}
|
||||
|
||||
if (is_aifc) {
|
||||
if (/*!fver_found ||*/ !comm_found || !data_found)
|
||||
goto fail;
|
||||
}
|
||||
else if (is_aiff) {
|
||||
if (!comm_found || !data_found)
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
if (is_aifc) {
|
||||
if (/*!fver_found ||*/ !comm_found || !data_found)
|
||||
goto fail;
|
||||
}
|
||||
else if (is_aiff) {
|
||||
if (!comm_found || !data_found)
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* read loop points */
|
||||
if (inst_offset && mark_offset) {
|
||||
|
@ -399,8 +411,6 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||
vgmstream->codec_data = init_relic(channels, bitrate, sample_rate);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
vgmstream->sample_rate = 44100; /* fixed output */
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -421,6 +431,13 @@ VGMSTREAM* init_vgmstream_aifc(STREAMFILE* sf) {
|
|||
//vgmstream->num_samples = vadpcm_bytes_to_samples(data_size, channels); /* unneeded */
|
||||
break;
|
||||
|
||||
case coding_IMUSE: {
|
||||
vgmstream->codec_data = init_imuse_aifc(sf, start_offset, channels);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->layout_type = layout_none;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
vgmstream->layout_type = (channels > 1) ? layout_interleave : layout_none;
|
||||
vgmstream->interleave_block_size = interleave;
|
||||
|
|
|
@ -4,27 +4,25 @@
|
|||
|
||||
|
||||
/* .BAF - Bizarre Creations bank file [Blur (PS3), Project Gotham Racing 4 (X360), Geometry Wars (PC)] */
|
||||
VGMSTREAM * init_vgmstream_baf(STREAMFILE *sf) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
VGMSTREAM* init_vgmstream_baf(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
char bank_name[0x22+1], stream_name[0x20+1], file_name[STREAM_NAME_SIZE];
|
||||
off_t start_offset, header_offset, name_offset;
|
||||
size_t stream_size;
|
||||
uint32_t channel_count, sample_rate, num_samples, version, codec, tracks;
|
||||
int loop_flag, total_subsongs, target_subsong = sf->stream_index;
|
||||
int big_endian, loop_flag, total_subsongs, target_subsong = sf->stream_index;
|
||||
read_u32_t read_u32;
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00, sf, "BANK"))
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
if (!check_extensions(sf, "baf"))
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
/* use BANK size to check endianness */
|
||||
if (guess_endian32(0x04,sf)) {
|
||||
read_u32 = read_u32be;
|
||||
} else {
|
||||
read_u32 = read_u32le;
|
||||
}
|
||||
big_endian = guess_endian32(0x04, sf);
|
||||
read_u32 = big_endian ? read_u32be : read_u32le;
|
||||
|
||||
/* 0x04: bank size */
|
||||
version = read_u32(0x08,sf);
|
||||
|
@ -69,7 +67,7 @@ VGMSTREAM * init_vgmstream_baf(STREAMFILE *sf) {
|
|||
tracks = 0;
|
||||
|
||||
switch(codec) {
|
||||
case 0x03: /* PCM16LE */
|
||||
case 0x03: /* PCM16 */
|
||||
switch(version) {
|
||||
case 0x03: /* Geometry Wars (PC) */
|
||||
sample_rate = read_u32(header_offset+0x38, sf);
|
||||
|
@ -81,7 +79,13 @@ VGMSTREAM * init_vgmstream_baf(STREAMFILE *sf) {
|
|||
case 0x04: /* Project Gotham Racing 4 (X360) */
|
||||
sample_rate = read_u32(header_offset+0x3c, sf);
|
||||
channel_count = read_u32(header_offset+0x44, sf);
|
||||
loop_flag = read_u8(header_offset+0x4b, sf);
|
||||
loop_flag = read_u8(header_offset+0x4b, sf);
|
||||
break;
|
||||
|
||||
case 0x05: /* Blur 2 (X360) */
|
||||
sample_rate = read_u32(header_offset+0x40, sf);
|
||||
channel_count = read_u32(header_offset+0x48, sf);
|
||||
loop_flag = read_u8(header_offset+0x50, sf) != 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
|
@ -93,14 +97,14 @@ VGMSTREAM * init_vgmstream_baf(STREAMFILE *sf) {
|
|||
|
||||
case 0x07: /* PSX ADPCM (0x21 frame size) */
|
||||
if (version == 0x04 && read_u32(header_offset + 0x3c, sf) != 0) {
|
||||
/* Blur (Prototype) (PS3) */
|
||||
/* The Club (PS3), Blur (Prototype) (PS3) */
|
||||
sample_rate = read_u32(header_offset+0x3c, sf);
|
||||
channel_count = read_u32(header_offset+0x44, sf);
|
||||
loop_flag = read_u8(header_offset+0x4b, sf);
|
||||
|
||||
/* mini-header at the start of the stream */
|
||||
num_samples = read_u32le(start_offset+0x04, sf) / 0x02; /* PCM size? */
|
||||
start_offset += read_u32le(start_offset+0x00, sf);
|
||||
num_samples = read_u32le(start_offset+0x04, sf) / channel_count;
|
||||
start_offset += read_u32le(start_offset+0x00, sf); /* 0x08 */
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -117,14 +121,16 @@ VGMSTREAM * init_vgmstream_baf(STREAMFILE *sf) {
|
|||
channel_count = channel_count * tracks;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
break;
|
||||
|
||||
case 0x08: /* XMA1 */
|
||||
case 0x09: /* XMA2 */
|
||||
switch(version) {
|
||||
case 0x04: /* Project Gotham Racing (X360) */
|
||||
case 0x04: /* Project Gotham Racing 4 (X360) */
|
||||
sample_rate = read_u32(header_offset+0x3c, sf);
|
||||
channel_count = read_u32(header_offset+0x44, sf);
|
||||
loop_flag = read_u8(header_offset+0x54, sf) != 0;
|
||||
|
@ -160,7 +166,7 @@ VGMSTREAM * init_vgmstream_baf(STREAMFILE *sf) {
|
|||
|
||||
switch(codec) {
|
||||
case 0x03:
|
||||
vgmstream->coding_type = coding_PCM16LE;
|
||||
vgmstream->coding_type = big_endian ? coding_PCM16BE : coding_PCM16LE;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x02;
|
||||
|
||||
|
@ -179,44 +185,73 @@ VGMSTREAM * init_vgmstream_baf(STREAMFILE *sf) {
|
|||
vgmstream->loop_end_sample = num_samples;
|
||||
break;
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
case 0x08: {
|
||||
vgmstream->codec_data = init_ffmpeg_xma1_raw(sf, start_offset, stream_size, vgmstream->channels, vgmstream->sample_rate, 0);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
case 0x08:
|
||||
case 0x09: {
|
||||
int is_xma1 = (codec == 0x08);
|
||||
int block_size = 0x10000;
|
||||
|
||||
/* need to manually find sample offsets, it was a thing with XMA1 */
|
||||
{
|
||||
ms_sample_data msd = {0};
|
||||
|
||||
msd.xma_version = 1;
|
||||
msd.xma_version = is_xma1 ? 1 : 2;
|
||||
msd.channels = channel_count;
|
||||
msd.data_offset = start_offset;
|
||||
msd.data_size = stream_size;
|
||||
msd.loop_flag = loop_flag;
|
||||
msd.loop_start_b = read_u32(header_offset+0x4c, sf);
|
||||
msd.loop_end_b = read_u32(header_offset+0x50, sf);
|
||||
msd.loop_start_subframe = (read_u8(header_offset+0x55, sf) >> 0) & 0x0f;
|
||||
msd.loop_end_subframe = (read_u8(header_offset+0x55, sf) >> 4) & 0x0f;
|
||||
|
||||
switch(version) {
|
||||
case 0x04:
|
||||
msd.loop_start_b = read_u32(header_offset+0x4c, sf);
|
||||
msd.loop_end_b = read_u32(header_offset+0x50, sf);
|
||||
msd.loop_start_subframe = (read_u8(header_offset+0x55, sf) >> 0) & 0x0f;
|
||||
msd.loop_end_subframe = (read_u8(header_offset+0x55, sf) >> 4) & 0x0f;
|
||||
break;
|
||||
|
||||
case 0x05:
|
||||
msd.loop_start_b = read_u32(header_offset+0x50, sf);
|
||||
msd.loop_end_b = read_u32(header_offset+0x54, sf);
|
||||
msd.loop_start_subframe = (read_u8(header_offset+0x59, sf) >> 0) & 0x0f;
|
||||
msd.loop_end_subframe = (read_u8(header_offset+0x59, sf) >> 4) & 0x0f;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
xma_get_samples(&msd, sf);
|
||||
|
||||
vgmstream->num_samples = msd.num_samples; /* also at 0x58, but unreliable? */
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
vgmstream->num_samples = msd.num_samples; /* also at 0x58(v4)/0x5C(v5) for XMA1, but unreliable? */
|
||||
vgmstream->loop_start_sample = msd.loop_start_sample;
|
||||
vgmstream->loop_end_sample = msd.loop_end_sample;
|
||||
|
||||
vgmstream->codec_data = is_xma1
|
||||
? init_ffmpeg_xma1_raw(sf, start_offset, stream_size, vgmstream->channels, vgmstream->sample_rate, 0)
|
||||
: init_ffmpeg_xma2_raw(sf, start_offset, stream_size, vgmstream->num_samples, vgmstream->channels, vgmstream->sample_rate, block_size, 0);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
}
|
||||
|
||||
xma_fix_raw_samples_ch(vgmstream, sf, start_offset, stream_size, channel_count, 1,1);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
default:
|
||||
VGM_LOG("BAF: unknown codec %x\n", codec);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
read_string(vgmstream->stream_name,0x20+1, name_offset,sf);
|
||||
read_string(bank_name, sizeof(bank_name), (version == 0x03) ? 0x11 : 0x12, sf);
|
||||
read_string(stream_name, sizeof(stream_name), name_offset, sf);
|
||||
get_streamfile_basename(sf, file_name, STREAM_NAME_SIZE);
|
||||
|
||||
if (bank_name[0] && strcmp(file_name, bank_name) != 0)
|
||||
snprintf(vgmstream->stream_name, STREAM_NAME_SIZE, "%s/%s", bank_name, stream_name);
|
||||
else
|
||||
snprintf(vgmstream->stream_name, STREAM_NAME_SIZE, "%s", stream_name);
|
||||
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
|
|
|
@ -724,8 +724,10 @@ static bool process_names(STREAMFILE* sf, bnk_header_t* h) {
|
|||
/* searches the chunk until it finds the target name/index, or breaks at empty name */
|
||||
while (read_u8(stream_name_offset, sf)) {
|
||||
/* in case it goes somewhere out of bounds unexpectedly */
|
||||
if (((read_u8(stream_name_offset + 0x00, sf) + read_u8(stream_name_offset + 0x04, sf) +
|
||||
read_u8(stream_name_offset + 0x08, sf) + read_u8(stream_name_offset + 0x0C, sf)) & 0x1F) != i)
|
||||
if (((read_u8(stream_name_offset + 0x00, sf)
|
||||
+ read_u8(stream_name_offset + 0x04, sf)
|
||||
+ read_u8(stream_name_offset + 0x08, sf)
|
||||
+ read_u8(stream_name_offset + 0x0C, sf)) & 0x1F) != i)
|
||||
goto fail;
|
||||
if (read_u16(stream_name_offset + 0x10, sf) == table4_entry_id) {
|
||||
read_string(h->stream_name, STREAM_NAME_SIZE, stream_name_offset, sf);
|
||||
|
@ -735,7 +737,7 @@ static bool process_names(STREAMFILE* sf, bnk_header_t* h) {
|
|||
stream_name_offset += 0x14;
|
||||
}
|
||||
}
|
||||
//goto fail; /* didn't find any valid index? */
|
||||
goto fail; /* didn't find any valid index? */
|
||||
loop_break:
|
||||
break;
|
||||
|
||||
|
|
|
@ -10,17 +10,16 @@ VGMSTREAM* init_vgmstream_compresswave(STREAMFILE *sf) {
|
|||
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(sf, "cwav"))
|
||||
goto fail;
|
||||
|
||||
if (!is_id64be(0x00,sf, "CmpWave\0"))
|
||||
goto fail;
|
||||
return NULL;
|
||||
if (!check_extensions(sf, "cwav"))
|
||||
return NULL;
|
||||
|
||||
channels = 2; /* always, header channels is internal config */
|
||||
start_offset = 0x00;
|
||||
loop_flag = 1; //read_u8(0x430, sf) != 0; /* wrong count, see below */
|
||||
/* codec allows to use a cipher value, not seen */
|
||||
/* there is also title and artist, but default to "UnTitled" / "NoName" */
|
||||
loop_flag = true; //read_u8(0x430, sf) != 0; /* wrong count, see below */
|
||||
// codec allows to use a cipher value, not seen
|
||||
// there is also title and artist, but default to "UnTitled" / "NoName"
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
|
@ -28,10 +27,9 @@ VGMSTREAM* init_vgmstream_compresswave(STREAMFILE *sf) {
|
|||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_COMPRESSWAVE;
|
||||
vgmstream->sample_rate = 44100; /* always, header rate is internal config */
|
||||
/* in PCM bytes */
|
||||
vgmstream->num_samples = read_u64le(0x418, sf) / sizeof(int16_t) / channels;
|
||||
/* known files have wrong loop values and just repeat */
|
||||
vgmstream->sample_rate = 44100; // always, header rate is internal config
|
||||
vgmstream->num_samples = read_u64le(0x418, sf) / sizeof(int16_t) / channels; // in PCM bytes
|
||||
// known files have wrong loop values and just repeat
|
||||
vgmstream->loop_start_sample = 0; //read_u64le(0x420, sf) / sizeof(int16_t) / channels;
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples; //read_u64le(0x428, sf) / sizeof(int16_t) / channels;
|
||||
|
||||
|
|
|
@ -385,6 +385,7 @@ VGMSTREAM* init_vgmstream_fsb5(STREAMFILE* sf) {
|
|||
mpeg_custom_config cfg = {0};
|
||||
|
||||
cfg.fsb_padding = (vgmstream->channels > 2 ? 16 : 4); /* observed default */
|
||||
cfg.data_size = fsb5.stream_offset + fsb5.stream_size;
|
||||
|
||||
vgmstream->codec_data = init_mpeg_custom(sb, fsb5.stream_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_FSB, &cfg);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
|
|
|
@ -70,6 +70,7 @@ static const fsbkey_info fsbkey_list[] = {
|
|||
{ MODE_FSB5, FSBKEY_ADD("3cfe772db5b55b806541d3faf894020e") }, // Final Fantasy XV: War for Eos (Android)
|
||||
{ MODE_FSB5, FSBKEY_ADD("aj#$kLucf2lh}eqh") }, // Forza Motorsport 2023 (PC)
|
||||
{ MODE_FSB4, FSBKEY_ADD("dpdjeoqkr") }, // AirRider CrazyRacing (PC)
|
||||
{ MODE_FSB5, FSBKEY_ADD("weareAbsolutelyUnsure2018") }, // Wanderstop (PC)
|
||||
|
||||
/* some games use a key per file, generated from the filename
|
||||
* (could add all of them but there are a lot of songs, so external .fsbkey are probably better) */
|
||||
|
|
|
@ -111,7 +111,7 @@ VGMSTREAM* init_vgmstream_hca_subkey(STREAMFILE* sf, uint16_t subkey) {
|
|||
|
||||
/* Assumed mappings; seems correct vs Atom Viewer, that lists L/R/C/LFE/LS/RS and downmixes HCAs like that.
|
||||
* USM HCA's seem to be L/R/SL/SR/C/LFE though (probably reordered at USM level, no detection done in Atom Viewer). */
|
||||
{
|
||||
if (vgmstream->channels <= 8) { // 8 is max but just in case
|
||||
static const uint32_t hca_mappings[] = {
|
||||
0,
|
||||
mapping_MONO,
|
||||
|
|
|
@ -518,6 +518,7 @@ static const hcakey_info hcakey_list[] = {
|
|||
{0x0c59613fc788cec7}, // music_0210025
|
||||
{0xf61a0cfac4072903}, // music_0210026
|
||||
{0xa316e41cc9303921}, // music_0210027
|
||||
{0x61933afefe5f14c3}, // music_0210028
|
||||
{0x15bb78c31db0a0b6}, // music_0220001
|
||||
{0x59b1257242c40109}, // music_0220002
|
||||
{0xdb402bd08d522f34}, // music_0220003
|
||||
|
@ -711,6 +712,7 @@ static const hcakey_info hcakey_list[] = {
|
|||
{0x9f37cb27968428fa}, // music_0610027
|
||||
{0x36024c4a109520ec}, // music_0610028
|
||||
{0x758ad666ba171bd7}, // music_0610029
|
||||
{0xe3c90dcaed524e49}, // music_0610030
|
||||
{0x8258ddd6a1d0849b}, // music_0620001
|
||||
{0x1dd21a1244ca12f1}, // music_0620002
|
||||
{0xfdec74b23d8b494b}, // music_0620003
|
||||
|
@ -1267,6 +1269,11 @@ static const hcakey_info hcakey_list[] = {
|
|||
{0x34c0f6db642145a0}, // music_5050307
|
||||
{0xb7ecea9165c448da}, // music_5050308
|
||||
{0xa5e9bd945c5caf2c}, // music_5050309
|
||||
{0x91ff4aedae9ce2c3}, // music_5050313
|
||||
{0xeaaa417505d65dd1}, // music_5050322
|
||||
{0x591899d025c3beb7}, // music_5050323
|
||||
{0xa57678c62ef99124}, // music_5050324
|
||||
{0x925f360a8ccb4c32}, // music_5050325
|
||||
{0x52c250eade92393b}, // music_9010001
|
||||
{0xf66e6bb5b0599b07}, // music_9010002
|
||||
{0x8582b5a60dbbf948}, // music_9010003
|
||||
|
@ -1529,6 +1536,9 @@ static const hcakey_info hcakey_list[] = {
|
|||
// Freedom Wars Remastered (Switch)
|
||||
{3258660547165106863}, // 2D391680A55B32AF
|
||||
|
||||
// Suikoden I & II HD Remaster (PC)
|
||||
{14510296783270449627u}, // C95EEE0BA85411DB
|
||||
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -136,7 +136,7 @@ VGMSTREAM* init_vgmstream_imuse(STREAMFILE* sf) {
|
|||
|
||||
vgmstream->coding_type = coding_IMUSE;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->codec_data = init_imuse(sf, channels);
|
||||
vgmstream->codec_data = init_imuse_mcomp(sf, channels);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
|
||||
if (name_offset > 0)
|
||||
|
|
|
@ -1,64 +1,32 @@
|
|||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util/meta_utils.h"
|
||||
|
||||
/* KRAW (from Geometry Wars - Galaxies) */
|
||||
VGMSTREAM * init_vgmstream_kraw(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset;
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
/* KRAW - from Geometry Wars: Galaxies (Wii) */
|
||||
VGMSTREAM* init_vgmstream_kraw(STREAMFILE* sf) {
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("kraw",filename_extension(filename))) goto fail;
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "kRAW"))
|
||||
return NULL;
|
||||
// .kRAW: actual extension
|
||||
if (!check_extensions(sf, "kraw"))
|
||||
return NULL;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x00,streamFile) != 0x6B524157) /* "kRAW" */
|
||||
goto fail;
|
||||
meta_header_t h = {0};
|
||||
h.data_size = read_u32be(0x04,sf);
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = 1;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
h.meta = meta_KRAW;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x8;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 32000;
|
||||
vgmstream->coding_type = coding_PCM16BE;
|
||||
vgmstream->num_samples = read_32bitBE(0x04,streamFile)/2/channel_count;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = read_32bitBE(0x04,streamFile)/2/channel_count;
|
||||
}
|
||||
h.stream_offset = 0x08;
|
||||
h.channels = 1;
|
||||
h.sample_rate = 32000;
|
||||
h.num_samples = pcm16_bytes_to_samples(h.data_size, h.channels);
|
||||
h.allow_dual_stereo = true;
|
||||
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->meta_type = meta_KRAW;
|
||||
vgmstream->allow_dual_stereo = 1;
|
||||
h.coding = coding_PCM16BE;
|
||||
h.layout = layout_none;
|
||||
h.open_stream = true;
|
||||
h.sf = sf;
|
||||
|
||||
/* 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;
|
||||
return alloc_metastream(&h);
|
||||
}
|
||||
|
|
|
@ -512,7 +512,6 @@ static bool parse_ktsr_subfile(ktsr_header_t* ktsr, STREAMFILE* sf, uint32_t off
|
|||
ktsr->stream_sizes[0] = read_u32le(offset + 0x38, sf);
|
||||
}
|
||||
ktsr->is_external = true;
|
||||
VGM_LOG("k=%x\n", ktsr->codec_value);
|
||||
break;
|
||||
|
||||
case 0x41FDBD4E: /* internal [Attack on Titan: Wings of Freedom (Vita)] */
|
||||
|
|
|
@ -8,7 +8,7 @@ VGMSTREAM* init_vgmstream_lp_ap_lep(STREAMFILE* sf) {
|
|||
STREAMFILE* temp_sf = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channels, sample_rate, interleave;
|
||||
int32_t data_size, loop_start;
|
||||
uint32_t data_size, loop_start, loop_end;
|
||||
uint32_t id;
|
||||
|
||||
|
||||
|
@ -25,23 +25,47 @@ VGMSTREAM* init_vgmstream_lp_ap_lep(STREAMFILE* sf) {
|
|||
switch (id) {
|
||||
case 0x41502020: /* "AP " */
|
||||
case 0x4C502020: /* "LP " */
|
||||
data_size = read_u32le(0x04,sf); // end offset after header
|
||||
sample_rate = read_u32le(0x08,sf);
|
||||
interleave = read_u32le(0x0c,sf);
|
||||
loop_start = read_u32le(0x14,sf);
|
||||
data_size = read_u32le(0x18,sf);
|
||||
start_offset = read_u32le(0x1C,sf);
|
||||
// 10: pan/volume?
|
||||
loop_start = read_u32le(0x14,sf); // absolute
|
||||
loop_end = read_u32le(0x18,sf); // end offset after header
|
||||
start_offset= read_u32le(0x1C,sf); // after header
|
||||
|
||||
// tweak values considering (applies to both PS-ADPCM and PCM):
|
||||
// - start_offset with PCM starts 0x20 before data, so must be after header (not a blank frame)
|
||||
// - end offset after 0x20 usually ends when padding (0xFF) starts
|
||||
// - loop end is usually the same except in PCM
|
||||
// - loop start is always aligned to 0x800 (meaning no loop/0 uses 0x800 w/ start offset 0x7E0 + 0x20)
|
||||
// * in PS-ADPCM start after header points to a regular frame, a bit odd since PS-ADPCM should start with blank frames
|
||||
// but correct as LEP starts at 0x800 without them
|
||||
start_offset += 0x20;
|
||||
data_size += 0x20;
|
||||
loop_end += 0x20;
|
||||
data_size -= start_offset;
|
||||
loop_end -= start_offset;
|
||||
loop_start -= start_offset;
|
||||
break;
|
||||
|
||||
case 0x4C455020: /* "LEP " */
|
||||
data_size = read_u32le(0x08,sf);
|
||||
case 0x4C455020: /* "LEP " (memory data?) */
|
||||
// 04: config?
|
||||
data_size = read_u32le(0x08,sf); // within stream
|
||||
// 10: pan/volume?
|
||||
sample_rate = read_u16le(0x12,sf);
|
||||
loop_start = read_u32le(0x58,sf);
|
||||
loop_start = read_u32le(0x58,sf); // within stream?
|
||||
// 5c: loop start?
|
||||
// 60+: related to loop?
|
||||
|
||||
// not sure if loops are absolute, but since values are not 0x800-aligned like AP/LP assuming it's not
|
||||
|
||||
loop_end = data_size;
|
||||
interleave = 0x10;
|
||||
start_offset = 0x800;
|
||||
break;
|
||||
|
||||
default:
|
||||
goto fail;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
loop_flag = loop_start != 0;
|
||||
|
@ -61,9 +85,9 @@ VGMSTREAM* init_vgmstream_lp_ap_lep(STREAMFILE* sf) {
|
|||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = interleave;
|
||||
|
||||
vgmstream->num_samples = pcm_bytes_to_samples(data_size, channels, 16);
|
||||
vgmstream->loop_start_sample = pcm_bytes_to_samples(loop_start, channels, 16);
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
vgmstream->num_samples = pcm16_bytes_to_samples(data_size, channels);
|
||||
vgmstream->loop_start_sample = pcm16_bytes_to_samples(loop_start, channels);
|
||||
vgmstream->loop_end_sample = pcm16_bytes_to_samples(loop_end, channels);
|
||||
|
||||
temp_sf = setup_lp_streamfile(sf, start_offset); /* encrypted/obfuscated PCM */
|
||||
if (!temp_sf) goto fail;
|
||||
|
@ -77,7 +101,7 @@ VGMSTREAM* init_vgmstream_lp_ap_lep(STREAMFILE* sf) {
|
|||
|
||||
vgmstream->num_samples = ps_bytes_to_samples(data_size, channels);
|
||||
vgmstream->loop_start_sample = ps_bytes_to_samples(loop_start, channels);
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
vgmstream->loop_end_sample = ps_bytes_to_samples(loop_end, channels);
|
||||
break;
|
||||
|
||||
default:
|
||||
|
|
|
@ -2,8 +2,8 @@
|
|||
#include "../util.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* .GCM - from PS2 Namco games [Gunvari Collection + Time Crisis (PS2), NamCollection (PS2)] */
|
||||
VGMSTREAM* init_vgmstream_ps2_gcm(STREAMFILE* sf) {
|
||||
/* MCG - from PS2 Namco games [Gunvari Collection + Time Crisis (PS2), NamCollection (PS2)] */
|
||||
VGMSTREAM* init_vgmstream_mcg(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
uint32_t start_offset, name_offset;
|
||||
uint32_t vagp_l_offset, vagp_r_offset, track_size, data_size, channel_size;
|
||||
|
@ -12,11 +12,10 @@ VGMSTREAM* init_vgmstream_ps2_gcm(STREAMFILE* sf) {
|
|||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "MCG\0"))
|
||||
goto fail;
|
||||
|
||||
/* .gcm: actual extension */
|
||||
return NULL;
|
||||
// .gcm: actual extension
|
||||
if (!check_extensions(sf, "gcm"))
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
|
||||
/* format is two v4 "VAGp" headers then interleaved data (even for 6ch files) */
|
||||
|
@ -59,7 +58,7 @@ VGMSTREAM* init_vgmstream_ps2_gcm(STREAMFILE* sf) {
|
|||
vgmstream = allocate_vgmstream(channels, 0);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_PS2_GCM;
|
||||
vgmstream->meta_type = meta_MCG;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = ps_bytes_to_samples(channel_size, 1);
|
||||
vgmstream->coding_type = coding_PSX;
|
|
@ -366,8 +366,6 @@ VGMSTREAM* init_vgmstream_smss(STREAMFILE* sf);
|
|||
|
||||
VGMSTREAM* init_vgmstream_ads_midway(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_mcg(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_zsd(STREAMFILE *streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_vgs_ps(STREAMFILE *streamFile);
|
||||
|
@ -431,7 +429,7 @@ VGMSTREAM* init_vgmstream_wb(STREAMFILE* sf);
|
|||
|
||||
VGMSTREAM* init_vgmstream_raw_s14_sss(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_gcm(STREAMFILE* streamFile);
|
||||
VGMSTREAM * init_vgmstream_mcg(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM* init_vgmstream_smpl(STREAMFILE* sf);
|
||||
|
||||
|
@ -490,8 +488,6 @@ VGMSTREAM * init_vgmstream_xwav_old(STREAMFILE* sf);
|
|||
|
||||
VGMSTREAM * init_vgmstream_raw_snds(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_wmus(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_hyperscan_kvag(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM* init_vgmstream_psnd(STREAMFILE* sf);
|
||||
|
@ -1032,4 +1028,10 @@ VGMSTREAM* init_vgmstream_shaa(STREAMFILE* sf);
|
|||
|
||||
VGMSTREAM* init_vgmstream_undefind(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_oor(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_mio(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_2dx(STREAMFILE* sf);
|
||||
|
||||
#endif
|
||||
|
|
57
Frameworks/vgmstream/vgmstream/src/meta/mio.c
Normal file
57
Frameworks/vgmstream/vgmstream/src/meta/mio.c
Normal file
|
@ -0,0 +1,57 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
/* .MIO - Entis's 'Music Interleaved and Orthogonal transformed' [HAYABUSA (PC), Rakuen no Kantai (PC/Android)] */
|
||||
VGMSTREAM* init_vgmstream_mio(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
uint32_t start_offset;
|
||||
|
||||
/* checks */
|
||||
if (!is_id64be(0x00,sf, "Entis\x1a\x00\x00"))
|
||||
return NULL;
|
||||
// all of Entis's formats have long text descriptors, will be re-checked during codec init
|
||||
if (!is_id64be(0x10,sf, "Music In"))
|
||||
return NULL;
|
||||
|
||||
if (!check_extensions(sf,"mio"))
|
||||
return NULL;
|
||||
|
||||
|
||||
// get info (abridged), could use lib though
|
||||
int channels = read_s32le(0x90,sf);
|
||||
int sample_rate = 44100; // there is input rate at 0x94 put output is fixed
|
||||
int32_t num_samples = read_s32le(0xA0,sf);
|
||||
|
||||
// loops are in UTF16 tags, kinda annoying to read so get from lib below
|
||||
int32_t loop_start = 0;
|
||||
bool loop_flag = 1; //(loop_start > 0);
|
||||
|
||||
start_offset = 0x00;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_MIO;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = num_samples;
|
||||
|
||||
// .mio has multiple modes (lapped/huffman/lossless) but not that interesting to print as info
|
||||
vgmstream->codec_data = init_mio(sf, &loop_start);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_MIO;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
vgmstream->loop_start_sample = loop_start;
|
||||
vgmstream->loop_end_sample = num_samples;
|
||||
vgmstream->loop_flag = (loop_start >= 0);
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -1446,7 +1446,7 @@ VGMSTREAM* init_vgmstream_dsp_wiivoice(STREAMFILE* sf) {
|
|||
}
|
||||
|
||||
|
||||
/* WIIADPCM - Exient wrapper [Need for Speed: Hot Pursuit (Wii), Angry Birds: Star Wars (WiiU)] */
|
||||
/* WIIADPCM - Exient wrapper [Need for Speed: Hot Pursuit (Wii), Angry Birds: Star Wars (Wii/WiiU)] */
|
||||
VGMSTREAM* init_vgmstream_dsp_wiiadpcm(STREAMFILE* sf) {
|
||||
dsp_meta dspm = {0};
|
||||
|
||||
|
@ -1456,18 +1456,33 @@ VGMSTREAM* init_vgmstream_dsp_wiiadpcm(STREAMFILE* sf) {
|
|||
if (!check_extensions(sf, "adpcm"))
|
||||
return NULL;
|
||||
|
||||
dspm.interleave = read_u32be(0x08,sf); /* interleave offset */
|
||||
/* 0x0c: NFS = 0 when RAM (2 DSP headers), interleave size when stream (2 WIIADPCM headers)
|
||||
* AB = 0 (2 WIIADPCM headers) */
|
||||
// no good flag so use v2's loop+type as other values are easy to mistake
|
||||
int test = read_u32be(0x2c,sf);
|
||||
if (!(test == 0x00010000 || test == 0x00000000)) {
|
||||
// V1 (NFSHP)
|
||||
// 08: ch2 offset
|
||||
// 0c: real interleave in streams (xN WIIADPCM headers), null in memory audio (xN DSP headers)
|
||||
dspm.header_offset = 0x10;
|
||||
dspm.max_channels = 2;
|
||||
}
|
||||
else {
|
||||
// V2 (ABSW)
|
||||
// 08-18: chN offset
|
||||
// 1c: real interleave in streams (xN WIIADPCM headers), null in memory audio (xN DSP headers)
|
||||
// (interleave may be set in mono too)
|
||||
dspm.header_offset = 0x20;
|
||||
dspm.max_channels = 6;
|
||||
}
|
||||
|
||||
dspm.channels = (dspm.interleave ? 2 : 1);
|
||||
dspm.max_channels = 2;
|
||||
|
||||
if (read_u32be(0x10,sf) != 0)
|
||||
dspm.header_offset = 0x10; /* NFSHP */
|
||||
else
|
||||
dspm.header_offset = 0x20; /* ABSW */
|
||||
dspm.channels = 1;
|
||||
for (int i = 0; i < dspm.max_channels - 1; i++) {
|
||||
uint32_t offset = read_u32be(0x08 + i * 0x04, sf);
|
||||
if (!offset)
|
||||
break;
|
||||
dspm.channels += 1;
|
||||
}
|
||||
|
||||
dspm.interleave = read_u32be(0x08,sf); // use first channel offset as interleave
|
||||
if (dspm.interleave)
|
||||
dspm.interleave -= dspm.header_offset;
|
||||
dspm.interleave_first_skip = 0x60 + dspm.header_offset;
|
||||
|
@ -1476,7 +1491,6 @@ VGMSTREAM* init_vgmstream_dsp_wiiadpcm(STREAMFILE* sf) {
|
|||
dspm.header_spacing = dspm.interleave;
|
||||
dspm.start_offset = dspm.header_offset + 0x60;
|
||||
|
||||
|
||||
dspm.meta_type = meta_DSP_WIIADPCM;
|
||||
return init_vgmstream_dsp_common(sf, &dspm);
|
||||
}
|
||||
|
|
100
Frameworks/vgmstream/vgmstream/src/meta/oor.c
Normal file
100
Frameworks/vgmstream/vgmstream/src/meta/oor.c
Normal file
|
@ -0,0 +1,100 @@
|
|||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (read_u8(0x00, sf) != 0x08 && read_u32be(0x00, sf) != 0x48000000) //v0 and v1 first page headers
|
||||
return NULL;
|
||||
if (!check_extensions(sf, "oor"))
|
||||
return NULL;
|
||||
|
||||
// bitpacked header, should fail during on init with bad data but do minor validations to skip some allocs
|
||||
if (!is_oor(sf))
|
||||
return NULL;
|
||||
|
||||
#ifdef VGM_USE_VORBIS
|
||||
vorbis_custom_config cfg = {0}; //loads info on success
|
||||
|
||||
data = init_vorbis_custom(sf, 0x00, VORBIS_OOR, &cfg);
|
||||
if (!data) return NULL;
|
||||
|
||||
start_offset = cfg.data_start_offset;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(cfg.channels, 0);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_OOR;
|
||||
vgmstream->sample_rate = cfg.sample_rate;
|
||||
vgmstream->num_samples = cfg.last_granule;
|
||||
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->coding_type = coding_VORBIS_custom;
|
||||
vgmstream->codec_data = data;
|
||||
data = NULL;
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
goto fail;
|
||||
|
||||
//TODO: improve
|
||||
// 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;
|
||||
}
|
||||
|
||||
// OOR is bitpacked but try to determine if bytes look like a .oor (will fail later if we picked a wrong candidate).
|
||||
static bool is_oor(STREAMFILE* sf) {
|
||||
static uint8_t empty_granule[0x09];
|
||||
uint8_t data[0x10] = {0};
|
||||
|
||||
read_streamfile(data, 0x00, sizeof(data), sf);
|
||||
|
||||
int page_version;
|
||||
int head_pos;
|
||||
if (data[0x00] == 0x48 && memcmp(data + 0x01, empty_granule, 9) == 0) {
|
||||
// V1: bits 01 0010 00 + granule + header
|
||||
head_pos = 0x0A;
|
||||
page_version = 1;
|
||||
}
|
||||
else if (data[0x00] == 0x08) {
|
||||
// V0: bits 00 0010 00 + header
|
||||
head_pos = 0x01;
|
||||
page_version = 0;
|
||||
}
|
||||
else {
|
||||
return false;
|
||||
}
|
||||
|
||||
uint16_t head = (data[head_pos] << 8) | data[head_pos+1];
|
||||
int version = (head >> 14) & 0x03; //2b
|
||||
int channels = (head >> 11) & 0x07; //3b
|
||||
int sr_selector = (head >> 9) & 0x03; //3b
|
||||
int srate = (head >> 1) & 0xFF; //3b
|
||||
|
||||
if (version != page_version || channels == 0)
|
||||
return false;
|
||||
|
||||
if (sr_selector == 3 && srate > 10)
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
|
@ -1,67 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* GUN (Gunvari Streams) */
|
||||
VGMSTREAM * init_vgmstream_ps2_mcg(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("mcg",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (!((read_32bitBE(0x00,streamFile) == 0x4D434700) &&
|
||||
(read_32bitBE(0x20,streamFile) == 0x56414770) &&
|
||||
(read_32bitBE(0x50,streamFile) == 0x56414770)))
|
||||
goto fail;
|
||||
|
||||
loop_flag = (read_32bitLE(0x34,streamFile)!=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 = 0x80;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitBE(0x30,streamFile);
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->num_samples = read_32bitBE(0x2C,streamFile)/16*14*channel_count;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = read_32bitLE(0x14,streamFile);
|
||||
vgmstream->meta_type = meta_PS2_MCG;
|
||||
|
||||
if (vgmstream->loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = read_32bitLE(0x34,streamFile);
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
|
||||
/* 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,62 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
/* VA3 - Konami / Sony Atrac3 Container [PS2 DDR Supernova 2 Arcade] */
|
||||
VGMSTREAM * init_vgmstream_va3(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
uint32_t data_size;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
if (!check_extensions(streamFile, "va3"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x00, streamFile) != 0x21334156) /* "!3AV" */
|
||||
goto fail;
|
||||
|
||||
/* va3 header */
|
||||
start_offset = 0x800;
|
||||
data_size = read_32bitLE(0x04, streamFile);// get_streamfile_size(streamFile) - start_offset;
|
||||
// pretty sure 0x4 LE 32 bit is some sort of filesize...
|
||||
|
||||
loop_flag = 0;
|
||||
//0x18 is 1... what is this?
|
||||
channel_count = 2;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_VA3;
|
||||
vgmstream->sample_rate = read_32bitLE(0x14, streamFile);
|
||||
vgmstream->num_samples = read_32bitLE(0x08, streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
{
|
||||
int block_align, encoder_delay;
|
||||
|
||||
block_align = 0xC0 * vgmstream->channels;
|
||||
encoder_delay = 0; //todo
|
||||
|
||||
vgmstream->codec_data = init_ffmpeg_atrac3_raw(streamFile, start_offset,data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
/* open the file for reading */
|
||||
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -1,102 +0,0 @@
|
|||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
//#include <windows.h>
|
||||
//#include <tchar.h>
|
||||
|
||||
/* WMUS - Arbitrary extension chosen for The Warriors (PS2) */
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_wmus(STREAMFILE *streamFile)
|
||||
{
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
|
||||
int loop_flag = 1;
|
||||
int channel_count;
|
||||
off_t start_offset;
|
||||
int i;
|
||||
|
||||
int blockCount;
|
||||
int shortBlockSize;
|
||||
int lastBlockLocation;
|
||||
|
||||
char filenameWHED[PATH_LIMIT];
|
||||
STREAMFILE * streamFileWHED = NULL;
|
||||
|
||||
//_TCHAR szBuffer[100];
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
|
||||
if (strcasecmp("wmus",filename_extension(filename)))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* check for .WHED file */
|
||||
strcpy(filenameWHED, filename);
|
||||
strcpy(filenameWHED + strlen(filenameWHED) - 4, "WHED");
|
||||
|
||||
streamFileWHED = streamFile->open(streamFile, filenameWHED, STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!streamFileWHED)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* check loopand channel */
|
||||
loop_flag = 1;
|
||||
channel_count = read_32bitLE(0x14, streamFileWHED);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||
if (!vgmstream)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x04, streamFileWHED);
|
||||
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
|
||||
vgmstream->interleave_block_size = read_32bitLE(0x18, streamFileWHED);
|
||||
blockCount = read_32bitLE(0x1C, streamFileWHED) * channel_count;
|
||||
shortBlockSize = read_32bitLE(0x20, streamFileWHED);
|
||||
|
||||
vgmstream->num_samples = (vgmstream->interleave_block_size * blockCount) / 16 / channel_count * 28;
|
||||
vgmstream->loop_start_sample = 0;
|
||||
|
||||
lastBlockLocation = (vgmstream->interleave_block_size * blockCount) - (vgmstream->interleave_block_size - shortBlockSize);
|
||||
vgmstream->loop_end_sample = lastBlockLocation / 16 / channel_count * 28;
|
||||
|
||||
//_stprintf(szBuffer, _T("%x"), lastBlockLocation);
|
||||
//MessageBox(NULL, szBuffer, _T("Foo"), MB_OK);
|
||||
|
||||
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->meta_type = meta_PS2_WMUS;
|
||||
|
||||
start_offset = 0;
|
||||
|
||||
/* open the file for reading by each channel */
|
||||
{
|
||||
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=
|
||||
(off_t)(start_offset+vgmstream->interleave_block_size*i);
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (streamFileWHED) close_streamfile(streamFileWHED);
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -4,65 +4,62 @@
|
|||
/* tri-Ace codec file [Star Ocean 3 (PS2), Valkyrie Profile 2 (PS2), Radiata Stories (PS2)] */
|
||||
VGMSTREAM* init_vgmstream_tac(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
int loop_flag, channel_count;
|
||||
uint16_t loop_frame, frame_count, loop_discard, frame_last;
|
||||
uint32_t info_offset, loop_offset, stream_size, file_size;
|
||||
int loop_flag, channels;
|
||||
off_t start_offset;
|
||||
|
||||
|
||||
/* checks */
|
||||
// file is validated on decoder init, catch simple errors (see tac_decoder_lib.h for full header)
|
||||
uint32_t info_offset = read_u32le(0x00,sf);
|
||||
if (info_offset < 0x20 || info_offset > 0x4E000) /* offset points to value inside first "block" */
|
||||
return NULL;
|
||||
|
||||
/* (extensionless): bigfiles have no known names (libs calls mention "St*" and "Sac*" though)
|
||||
* .aac: fake for convenience given it's a tri-Ace AAC's grandpa (but don't use unless you must)
|
||||
* .pk3/.20: extremely ugly fake extensions randomly given by an old extractor, *DON'T* */
|
||||
if (!check_extensions(sf, ",aac,laac"))
|
||||
goto fail;
|
||||
/* file is validated on decoder init, early catch of simple errors (see tac_decoder_lib.h for full header) */
|
||||
info_offset = read_u32le(0x00,sf);
|
||||
if (info_offset > 0x4E000 || info_offset < 0x20) /* offset points to value inside first "block" */
|
||||
goto fail;
|
||||
loop_frame = read_u16le(0x08,sf);
|
||||
loop_discard = read_u16le(0x0a,sf);
|
||||
frame_count = read_u16le(0x0c,sf);
|
||||
frame_last = read_u16le(0x0e,sf);
|
||||
loop_offset = read_u32le(0x10,sf);
|
||||
stream_size = read_u32le(0x14,sf);
|
||||
return NULL;
|
||||
|
||||
uint16_t loop_frame = read_u16le(0x08,sf);
|
||||
uint16_t loop_discard = read_u16le(0x0a,sf);
|
||||
uint16_t frame_count = read_u16le(0x0c,sf);
|
||||
uint16_t frame_last = read_u16le(0x0e,sf);
|
||||
uint32_t loop_offset = read_u32le(0x10,sf);
|
||||
uint32_t stream_size = read_u32le(0x14,sf);
|
||||
if (stream_size % 0x4E000 != 0) /* multiple of blocks */
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
/* actual file can truncate last block */
|
||||
file_size = get_streamfile_size(sf);
|
||||
uint32_t file_size = get_streamfile_size(sf);
|
||||
if (file_size > stream_size || file_size < stream_size - 0x4E000)
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
channel_count = 2; /* always stereo */
|
||||
loop_flag = (loop_offset != stream_size); /* actual check may be loop_frame > 0? */
|
||||
start_offset = 0;
|
||||
channels = 2; // always stereo
|
||||
loop_flag = (loop_offset != stream_size); // actual check may be loop_frame > 0?
|
||||
start_offset = 0; // handled internally
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_TAC;
|
||||
vgmstream->sample_rate = 48000;
|
||||
|
||||
/* Frame at count/loop outputs less than full 1024 samples (thus loop or count-1 + extra).
|
||||
* A few files may pop when looping, but this seems to match game/emulator. */
|
||||
// Frame at count/loop outputs less than full 1024 samples (thus loop or count-1 + extra).
|
||||
// A few files may pop when looping, but this seems to match game/emulator.
|
||||
vgmstream->num_samples = (frame_count - 1) * 1024 + (frame_last + 1);
|
||||
vgmstream->loop_start_sample = (loop_frame - 1) * 1024 + loop_discard;
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
|
||||
{
|
||||
vgmstream->codec_data = init_tac(sf);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_TAC;
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
vgmstream->codec_data = init_tac(sf);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_TAC;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
|
|
|
@ -78,6 +78,11 @@ void txtp_copy_config(play_config_t* dst, play_config_t* src) {
|
|||
if (!src->config_set)
|
||||
return;
|
||||
|
||||
// "no loops" (intro only) and "ignore fade" can't work due to how decoding works, must use @body-* macros
|
||||
if (src->loop_count_set && src->loop_count == 0 && src->ignore_fade) {
|
||||
src->ignore_fade = false;
|
||||
}
|
||||
|
||||
dst->config_set = 1;
|
||||
copy_flag(&dst->play_forever, &src->play_forever);
|
||||
copy_flag(&dst->ignore_fade, &src->ignore_fade);
|
||||
|
@ -94,22 +99,6 @@ void txtp_copy_config(play_config_t* dst, play_config_t* src) {
|
|||
copy_time(&dst->body_time_set, &dst->body_time, &dst->body_time_s, &src->body_time_set, &src->body_time, &src->body_time_s);
|
||||
}
|
||||
|
||||
#if 0
|
||||
static void init_config(VGMSTREAM* vgmstream) {
|
||||
play_config_t* cfg = &vgmstream->config;
|
||||
|
||||
//todo only on segmented/layered?
|
||||
if (cfg->play_forever
|
||||
cfg->loop_count_set || cfg->fade_time_set || cfg->fade_delay_set ||
|
||||
cfg->pad_begin_set || cfg->pad_end_set || cfg->trim_begin_set || cfg->trim_end_set ||
|
||||
cfg->body_time_set) {
|
||||
VGM_LOG("setup!\n");
|
||||
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
void txtp_add_mixing(txtp_entry_t* entry, txtp_mix_data_t* mix, txtp_mix_t command) {
|
||||
if (entry->mixing_count + 1 > TXTP_MIXING_MAX) {
|
||||
VGM_LOG("TXTP: too many mixes\n");
|
||||
|
|
|
@ -21,6 +21,11 @@
|
|||
#define TXTP_GROUP_REPEAT 'R'
|
||||
#define TXTP_POSITION_LOOPS 'L'
|
||||
|
||||
#define TXTP_BODY_INTRO 1
|
||||
#define TXTP_BODY_MAIN 2
|
||||
#define TXTP_BODY_OUTRO 3
|
||||
|
||||
|
||||
/* mixing info */
|
||||
typedef enum {
|
||||
MIX_SWAP,
|
||||
|
@ -104,6 +109,8 @@ typedef struct {
|
|||
double trim_second;
|
||||
int32_t trim_sample;
|
||||
|
||||
int body_mode;
|
||||
|
||||
} txtp_entry_t;
|
||||
|
||||
|
||||
|
|
|
@ -384,6 +384,8 @@ static void add_settings(txtp_entry_t* current, txtp_entry_t* entry, const char*
|
|||
|
||||
current->loop_anchor_start = entry->loop_anchor_start;
|
||||
current->loop_anchor_end = entry->loop_anchor_end;
|
||||
|
||||
current->body_mode = entry->body_mode;
|
||||
}
|
||||
|
||||
//TODO use
|
||||
|
@ -708,6 +710,16 @@ static void parse_params(txtp_entry_t* entry, char* params) {
|
|||
|
||||
txtp_add_mixing(entry, &mix, MACRO_DOWNMIX);
|
||||
}
|
||||
else if (strcmp(command,"@body-intro") == 0) {
|
||||
entry->body_mode = TXTP_BODY_INTRO;
|
||||
VGM_LOG("body: %x\n", entry->body_mode);
|
||||
}
|
||||
else if (strcmp(command,"@body-main") == 0) {
|
||||
entry->body_mode = TXTP_BODY_MAIN;
|
||||
}
|
||||
else if (strcmp(command,"@body-outro") == 0) {
|
||||
entry->body_mode = TXTP_BODY_OUTRO;
|
||||
}
|
||||
else if (params[nc] == ' ') {
|
||||
//;VGM_LOG("TXTP: comment\n");
|
||||
break; /* comment, ignore rest */
|
||||
|
@ -1019,7 +1031,9 @@ static int parse_keyval(txtp_header_t* txtp, const char* key, const char* val) {
|
|||
|
||||
}
|
||||
else {
|
||||
goto fail;
|
||||
// in rare cases a filename may contain a (blah=blah.blah), but it's hard to distinguish
|
||||
// from key=val + setting with dots. Signal unknown command to treat it like a file (should fail later).
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
@ -1066,9 +1080,11 @@ txtp_header_t* txtp_parse(STREAMFILE* sf) {
|
|||
/* try key/val (ignores lead/trail spaces, # may be commands or comments) */
|
||||
ok = sscanf(line, " %[^ \t#=] = %[^\t\r\n] ", key,val);
|
||||
if (ok == 2) { /* key=val */
|
||||
if (!parse_keyval(txtp, key, val)) /* read key/val */
|
||||
goto fail;
|
||||
continue;
|
||||
int ret = parse_keyval(txtp, key, val); /* read key/val */
|
||||
if (ret == 0) goto fail;
|
||||
if (ret > 0)
|
||||
continue;
|
||||
// ret < 0: try to handle as filename below
|
||||
}
|
||||
|
||||
/* must be a filename (only remove spaces from start/end, as filenames con contain mid spaces/#/etc) */
|
||||
|
|
|
@ -13,6 +13,51 @@
|
|||
/*******************************************************************************/
|
||||
|
||||
|
||||
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;
|
||||
|
||||
entry->config.fade_time_set = false;
|
||||
entry->config.fade_delay_set = false;
|
||||
entry->config.ignore_fade = false;
|
||||
entry->config.ignore_loop = true;
|
||||
|
||||
switch(entry->body_mode) {
|
||||
case TXTP_BODY_INTRO:
|
||||
if (vgmstream->loop_start_sample == 0)
|
||||
return;
|
||||
entry->trim_set = true;
|
||||
entry->trim_sample = vgmstream->loop_start_sample;
|
||||
|
||||
entry->config.config_set = true;
|
||||
break;
|
||||
|
||||
case TXTP_BODY_MAIN:
|
||||
entry->config.trim_begin_set = true;
|
||||
entry->config.trim_begin = vgmstream->loop_start_sample;
|
||||
entry->trim_set = true;
|
||||
entry->trim_sample = vgmstream->loop_end_sample;
|
||||
|
||||
entry->config.config_set = true;
|
||||
break;
|
||||
|
||||
case TXTP_BODY_OUTRO:
|
||||
if (vgmstream->loop_end_sample >= vgmstream->num_samples)
|
||||
return;
|
||||
entry->config.trim_begin_set = true;
|
||||
entry->config.trim_begin = vgmstream->loop_end_sample;
|
||||
|
||||
entry->config.config_set = true;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
static void apply_settings(VGMSTREAM* vgmstream, txtp_entry_t* current) {
|
||||
|
||||
/* base settings */
|
||||
|
@ -36,6 +81,8 @@ static void apply_settings(VGMSTREAM* vgmstream, txtp_entry_t* current) {
|
|||
vgmstream_force_loop(vgmstream, current->loop_install_set, current->loop_start_sample, current->loop_end_sample);
|
||||
}
|
||||
|
||||
apply_settings_body(vgmstream, current);
|
||||
|
||||
if (current->trim_set) {
|
||||
if (current->trim_second != 0.0) {
|
||||
/* trim sample can become 0 here when second is too small (rounded) */
|
||||
|
|
|
@ -1011,7 +1011,11 @@ static VGMSTREAM* init_vgmstream_ubi_sb_base(ubi_sb_header* sb, STREAMFILE* sf_h
|
|||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x02;
|
||||
|
||||
if (vgmstream->num_samples == 0) { /* happens in .bnm */
|
||||
// in .bnm samples may be null, or PCM size (similar to Ubi-MPEG)
|
||||
if (sb->is_bnm)
|
||||
vgmstream->num_samples = 0;
|
||||
|
||||
if (vgmstream->num_samples == 0) {
|
||||
vgmstream->num_samples = pcm_bytes_to_samples(sb->stream_size, sb->channels, 16);
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
}
|
||||
|
@ -1221,14 +1225,44 @@ static VGMSTREAM* init_vgmstream_ubi_sb_base(ubi_sb_header* sb, STREAMFILE* sf_h
|
|||
}
|
||||
break;
|
||||
|
||||
case FMT_MPDX:
|
||||
/* a custom, chunked MPEG format (sigh)
|
||||
* 0x00: samples? (related to size)
|
||||
* 0x04: "2RUS" (apparently "1RUS" for mono files)
|
||||
* Rest is a MPEG-like sync but not an actual MPEG header? (DLLs do refer it as MPEG)
|
||||
* Files may have multiple "2RUS" or just a big one
|
||||
* A companion .csb has some not-too-useful info */
|
||||
goto fail;
|
||||
case FMT_MPDX: {
|
||||
/* custom MPEG (.MPD, .MPU. MPX, internal, etc):
|
||||
* 0x00: samples
|
||||
* 0x04: optional ID for 'surround' config ("2RUS" or "1RUS" or none)
|
||||
* Data is custom-ish MP2 packets with odd surround modes
|
||||
* - .MPX have multiple small streams pasted together (subsongs in .bnm point to each)
|
||||
* - .MPD has 1 big-ish stream
|
||||
* A companion .csb has sequence info (maybe before compiled to .bnm)
|
||||
*/
|
||||
|
||||
int32_t block_samples = read_s32le(start_offset + 0x00, sf_data);
|
||||
uint32_t mode = read_u32be(start_offset + 0x04, sf_data);
|
||||
start_offset += 0x04;
|
||||
if ((mode & 0x00FFFFFF) == get_id32be("\0RUS"))
|
||||
start_offset += 0x04;
|
||||
|
||||
// for some reason num_samples is either size of PCM or 0
|
||||
if (sb->num_samples && block_samples * sizeof(short) * sb->channels != sb->num_samples) {
|
||||
VGM_LOG("UBI SB: wrong MPEG block samples found block=%i vs total=%i\n", block_samples, sb->num_samples);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
//TODO: needed for smoother segments, but not sure if block samples counts this
|
||||
// (usually blocks' frames have more samples than defined but not always; maybe should output delay's samples at EOF)
|
||||
int encoder_delay = 480; //observed
|
||||
|
||||
vgmstream->num_samples = block_samples - encoder_delay;
|
||||
vgmstream->loop_end_sample = block_samples - encoder_delay;
|
||||
if (sb->loop_start) {
|
||||
vgmstream->loop_start_sample = sb->loop_start / sizeof(short) / sb->channels;
|
||||
}
|
||||
|
||||
vgmstream->codec_data = init_ubimpeg(mode);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_UBI_MPEG;
|
||||
vgmstream->layout_type = layout_none;
|
||||
break;
|
||||
}
|
||||
|
||||
default:
|
||||
VGM_LOG("UBI SB: unknown codec\n");
|
||||
|
@ -1236,7 +1270,7 @@ static VGMSTREAM* init_vgmstream_ubi_sb_base(ubi_sb_header* sb, STREAMFILE* sf_h
|
|||
}
|
||||
|
||||
/* open the actual for decoding (sf_data can be an internal or external stream) */
|
||||
if ( !vgmstream_open_stream(vgmstream, sf_data, start_offset) )
|
||||
if (!vgmstream_open_stream(vgmstream, sf_data, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
|
@ -3071,10 +3105,10 @@ static int config_sb_version(ubi_sb_header* sb, STREAMFILE* sf) {
|
|||
sb->version = 0x00000000;
|
||||
}
|
||||
|
||||
/* Tonic Touble beta has garbage instead of version */
|
||||
/* Tonic Touble Special Edition has garbage instead of version */
|
||||
if (sb->is_bnm && sb->version > 0x00000000 && sb->platform == UBI_PC) {
|
||||
if (check_project_file(sf, "ED_MAIN.LCB", 0)) {
|
||||
is_ttse_pc = 1;
|
||||
if (check_project_file(sf, "ED_MAIN.LCB", 0) || check_project_file(sf, "../ED_MAIN.LCB", 0)) {
|
||||
is_ttse_pc = true;
|
||||
sb->version = 0x00000000;
|
||||
}
|
||||
}
|
||||
|
|
59
Frameworks/vgmstream/vgmstream/src/meta/va3.c
Normal file
59
Frameworks/vgmstream/vgmstream/src/meta/va3.c
Normal file
|
@ -0,0 +1,59 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
/* VA3 - from Konami games [Dance Dance Revolution Supernova 2 (Arcade)] */
|
||||
VGMSTREAM* init_vgmstream_va3(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channels;
|
||||
uint32_t data_size;
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00, sf, "!3AV"))
|
||||
return NULL;
|
||||
// .va3: actual extension
|
||||
if (!check_extensions(sf, "va3"))
|
||||
return NULL;
|
||||
|
||||
start_offset = 0x800;
|
||||
data_size = read_u32le(0x04, sf);
|
||||
loop_flag = 0;
|
||||
channels = 2;
|
||||
|
||||
//0c: null (loops?)
|
||||
//10: null (loops?)
|
||||
//18: flag? (always 1)
|
||||
//1c: always 0x0200 (channels?)
|
||||
//20: always 100 (volume?)
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_VA3;
|
||||
vgmstream->num_samples = read_s32le(0x08, sf);
|
||||
vgmstream->sample_rate = read_s32le(0x14, sf);
|
||||
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
{
|
||||
int block_align = 0xC0 * vgmstream->channels;
|
||||
int encoder_delay = 0; //TODO
|
||||
|
||||
vgmstream->codec_data = init_ffmpeg_atrac3_raw(sf, start_offset,data_size, vgmstream->num_samples,vgmstream->channels,vgmstream->sample_rate, block_align, encoder_delay);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
#endif
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -28,8 +28,9 @@ VGMSTREAM* init_vgmstream_vag(STREAMFILE* sf) {
|
|||
* .snd: Alien Breed (Vita)
|
||||
* .svg: ModernGroove: Ministry of Sound Edition (PS2)
|
||||
* (extensionless): The Urbz (PS2), The Sims series (PS2)
|
||||
* .wav: Sniper Elite (PS2), The Simpsons Game (PS2/PSP) */
|
||||
if (!check_extensions(sf,"vag,swag,str,vig,l,r,vas,xa2,snd,svg,,wav,lwav"))
|
||||
* .wav: Sniper Elite (PS2), The Simpsons Game (PS2/PSP)
|
||||
* .msv: Casper and the Ghostly Trio (PS2), Earache Extreme Metal Racing (PS2) */
|
||||
if (!check_extensions(sf,"vag,swag,str,vig,l,r,vas,xa2,snd,svg,,wav,lwav,msv"))
|
||||
return NULL;
|
||||
|
||||
file_size = get_streamfile_size(sf);
|
||||
|
|
|
@ -226,8 +226,6 @@ VGMSTREAM* init_vgmstream_vas_kceo_container(STREAMFILE* sf) {
|
|||
}
|
||||
}
|
||||
else if (read_u32le(0x00, sf) == 0x800) { /* Xbox/PC (start?) */
|
||||
VGM_STEP();
|
||||
|
||||
total_subsongs = read_s32le(0x04, sf);
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
|
||||
|
|
|
@ -13,7 +13,7 @@ VGMSTREAM* init_vgmstream_vig_kces(STREAMFILE* sf) {
|
|||
/* checks */
|
||||
if (read_u32be(0x00,sf) != 0x01006408)
|
||||
return NULL;
|
||||
/* .vig: actual extension from DDR exes */
|
||||
/* .vig: actual extension from AC versions + PS2 exes */
|
||||
if (!check_extensions(sf, "vig"))
|
||||
return NULL;
|
||||
|
||||
|
|
|
@ -1,87 +1,87 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "xavs_streamfile.h"
|
||||
|
||||
/* XAVS - Reflections audio and video+audio container [Stuntman (PS2)] */
|
||||
VGMSTREAM * init_vgmstream_xavs(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channel_count;
|
||||
int total_subsongs, target_subsong = streamFile->stream_index;
|
||||
STREAMFILE *temp_streamFile = NULL;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile, "xav"))
|
||||
goto fail;
|
||||
if (read_32bitBE(0x00, streamFile) != 0x58415653) /* "XAVS" */
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = 2;
|
||||
start_offset = 0x00;
|
||||
|
||||
/* 0x04: 16b width + height (0 if file has no video) */
|
||||
/* 0x08: related to video (0 if file has no video) */
|
||||
total_subsongs = read_16bitLE(0x0c, streamFile);
|
||||
/* 0x0c: volume? (0x50, 0x4e) */
|
||||
/* 0x10: biggest video chunk? (0 if file has no video) */
|
||||
/* 0x14: biggest audio chunk? */
|
||||
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
if (target_subsong > total_subsongs || total_subsongs <= 0) goto fail;
|
||||
|
||||
/* could use a blocked layout, but this needs interleaved PCM within blocks which can't be done ATM */
|
||||
temp_streamFile = setup_xavs_streamfile(streamFile, 0x18, target_subsong - 1);
|
||||
if (!temp_streamFile) goto fail;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_XAVS;
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
|
||||
vgmstream->coding_type = coding_PCM16LE;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
|
||||
/* no apparent flags, most videos use 0x41 but not all */
|
||||
{
|
||||
off_t offset = 0x18;
|
||||
while (offset < get_streamfile_size(streamFile)) {
|
||||
uint32_t chunk_id = read_32bitLE(offset+0x00, streamFile) & 0xFF;
|
||||
uint32_t chunk_size = read_32bitLE(offset+0x00, streamFile) >> 8;
|
||||
|
||||
if ((chunk_id & 0xF0) == 0x40) {
|
||||
vgmstream->sample_rate = 48000;
|
||||
vgmstream->interleave_block_size = 0x200;
|
||||
break;
|
||||
} else if ((chunk_id & 0xF0) == 0x60) {
|
||||
vgmstream->sample_rate = 24000;
|
||||
vgmstream->interleave_block_size = 0x100;
|
||||
break;
|
||||
} else if (chunk_id == 0x56) {
|
||||
offset += 0x04 + chunk_size;
|
||||
} else if (chunk_id == 0x21) {
|
||||
offset += 0x04;
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vgmstream->num_samples = pcm_bytes_to_samples(get_streamfile_size(temp_streamFile), channel_count, 16);
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream,temp_streamFile,start_offset))
|
||||
goto fail;
|
||||
|
||||
close_streamfile(temp_streamFile);
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_streamfile(temp_streamFile);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "xavs_streamfile.h"
|
||||
|
||||
/* XAVS - Reflections audio and video+audio container [Stuntman (PS2)] */
|
||||
VGMSTREAM* init_vgmstream_xavs(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
STREAMFILE* temp_sf = NULL;
|
||||
off_t start_offset;
|
||||
int loop_flag, channels;
|
||||
int total_subsongs, target_subsong = sf->stream_index;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00, sf, "XAVS"))
|
||||
return NULL;
|
||||
if (!check_extensions(sf, "xav"))
|
||||
return NULL;
|
||||
|
||||
loop_flag = 0;
|
||||
channels = 2;
|
||||
start_offset = 0x00;
|
||||
|
||||
/* 0x04: 16b width + height (0 if file has no video) */
|
||||
/* 0x08: related to video (0 if file has no video) */
|
||||
total_subsongs = read_u16le(0x0c, sf);
|
||||
/* 0x0c: volume? (0x50, 0x4e) */
|
||||
/* 0x10: biggest video chunk? (0 if file has no video) */
|
||||
/* 0x14: biggest audio chunk? */
|
||||
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
if (target_subsong > total_subsongs || total_subsongs <= 0) goto fail;
|
||||
|
||||
/* could use a blocked layout, but this needs interleaved PCM within blocks which can't be done ATM */
|
||||
temp_sf = setup_xavs_streamfile(sf, 0x18, target_subsong - 1);
|
||||
if (!temp_sf) goto fail;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_XAVS;
|
||||
vgmstream->num_streams = total_subsongs;
|
||||
|
||||
vgmstream->coding_type = coding_PCM16LE;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
|
||||
/* no apparent flags, most videos use 0x41 but not all */
|
||||
{
|
||||
off_t offset = 0x18;
|
||||
while (offset < get_streamfile_size(sf)) {
|
||||
uint32_t chunk_id = read_u32le(offset+0x00, sf) & 0xFF;
|
||||
uint32_t chunk_size = read_u32le(offset+0x00, sf) >> 8;
|
||||
|
||||
if ((chunk_id & 0xF0) == 0x40) {
|
||||
vgmstream->sample_rate = 48000;
|
||||
vgmstream->interleave_block_size = 0x200;
|
||||
break;
|
||||
} else if ((chunk_id & 0xF0) == 0x60) {
|
||||
vgmstream->sample_rate = 24000;
|
||||
vgmstream->interleave_block_size = 0x100;
|
||||
break;
|
||||
} else if (chunk_id == 0x56) {
|
||||
offset += 0x04 + chunk_size;
|
||||
} else if (chunk_id == 0x21) {
|
||||
offset += 0x04;
|
||||
} else {
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
vgmstream->num_samples = pcm_bytes_to_samples(get_streamfile_size(temp_sf), channels, 16);
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, temp_sf, start_offset))
|
||||
goto fail;
|
||||
|
||||
close_streamfile(temp_sf);
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_streamfile(temp_sf);
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -7,28 +7,27 @@ VGMSTREAM* init_vgmstream_xsh_xsd_xss(STREAMFILE* sf) {
|
|||
VGMSTREAM* vgmstream = NULL;
|
||||
STREAMFILE* sf_body = NULL;
|
||||
uint32_t offset;
|
||||
uint32_t stream_type, stream_offset, stream_size;
|
||||
uint32_t name_offset, name_size;
|
||||
uint32_t flags;
|
||||
int32_t num_samples;
|
||||
int version = 0;
|
||||
int loop_flag, channels, codec, sample_rate;
|
||||
int total_subsongs, target_subsong = sf->stream_index;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(sf, "xsh"))
|
||||
goto fail;
|
||||
|
||||
version = read_u32le(0x00, sf);
|
||||
|
||||
uint32_t version = read_u32le(0x00, sf);
|
||||
if (version < 0x009D || version > 0x101)
|
||||
return NULL;
|
||||
if (read_u32le(0x04, sf) != 0)
|
||||
goto fail;
|
||||
return NULL;
|
||||
|
||||
total_subsongs = read_u32le(0x08, sf);
|
||||
if (!check_extensions(sf, "xsh"))
|
||||
return NULL;
|
||||
|
||||
int total_subsongs = read_u32le(0x08, sf);
|
||||
int target_subsong = sf->stream_index;
|
||||
if (target_subsong == 0) target_subsong = 1;
|
||||
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
|
||||
|
||||
uint32_t stream_type, stream_offset, stream_size, flags;
|
||||
uint32_t name_offset, name_size;
|
||||
int32_t num_samples;
|
||||
switch(version) {
|
||||
case 0x009D: /* Spider-Man 2002 (Xbox) */
|
||||
offset = 0x0c + (target_subsong-1) * 0x60;
|
||||
|
@ -74,22 +73,23 @@ VGMSTREAM* init_vgmstream_xsh_xsd_xss(STREAMFILE* sf) {
|
|||
break;
|
||||
|
||||
default:
|
||||
goto fail;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
loop_flag = 0;
|
||||
// full loop flag (ex. Spider-Man city_e.XSH#7,22)
|
||||
loop_flag = (flags & 0x01) != 0;
|
||||
|
||||
if (stream_type < 0 || stream_type > 2)
|
||||
goto fail;
|
||||
if (stream_type > 2)
|
||||
return NULL;
|
||||
|
||||
/* 0x00: floats x4 (volume/pan/etc? usually 1.0, 1.0, 10.0, 10.0) */
|
||||
// 0x00: floats x4 (volume/pan/etc? usually 1.0, 1.0, 10.0, 10.0)
|
||||
codec = read_u16le(offset + 0x10,sf);
|
||||
channels = read_u16le(offset + 0x12,sf);
|
||||
sample_rate = read_u32le(offset + 0x14,sf);
|
||||
/* 0x18: avg bitrate */
|
||||
/* 0x1c: block size */
|
||||
/* 0x1e: bps */
|
||||
/* 0x20: 2? */
|
||||
// 0x18: avg bitrate
|
||||
// 0x1c: block size
|
||||
// 0x1e: bps
|
||||
// 0x20: 2?
|
||||
|
||||
if (stream_type == 0) {
|
||||
vgmstream = init_vgmstream_silence_container(total_subsongs);
|
||||
|
@ -120,6 +120,11 @@ VGMSTREAM* init_vgmstream_xsh_xsd_xss(STREAMFILE* sf) {
|
|||
vgmstream->num_streams = total_subsongs;
|
||||
read_string(vgmstream->stream_name, name_size, name_offset,sf);
|
||||
|
||||
// external .xss shouldn't have loop info though
|
||||
if (loop_flag && !vgmstream->loop_flag) {
|
||||
vgmstream_force_loop(vgmstream, loop_flag, 0, vgmstream->num_samples);
|
||||
}
|
||||
|
||||
close_streamfile(sf_body);
|
||||
return vgmstream;
|
||||
//break;
|
||||
|
@ -138,7 +143,6 @@ VGMSTREAM* init_vgmstream_xsh_xsd_xss(STREAMFILE* sf) {
|
|||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
}
|
||||
else {
|
||||
sf_body = open_streamfile_by_ext(sf,"xsd");
|
||||
|
@ -167,6 +171,8 @@ VGMSTREAM* init_vgmstream_xsh_xsd_xss(STREAMFILE* sf) {
|
|||
num_samples = xbox_ima_bytes_to_samples(stream_size, channels);
|
||||
|
||||
vgmstream->num_samples = num_samples;
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = num_samples;
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
|
@ -6,17 +6,19 @@
|
|||
/* Simple bitreader for MPEG/standard bit style, in 'most significant byte' (MSB) format.
|
||||
* Example: with 0x1234 = 00010010 00110100, reading 5b + 6b = 00010 010001
|
||||
* (first upper 5b, then next lower 3b and next upper 3b = 6b)
|
||||
* Kept in .h since it's slightly faster (compiler can optimize statics better using default compile flags). */
|
||||
* Kept in .h since it's slightly faster (compiler can optimize statics better using default compile flags).
|
||||
* Assumes bufs aren't that big (probable max ~0x20000000)
|
||||
*/
|
||||
|
||||
typedef struct {
|
||||
uint8_t* buf; /* buffer to read/write */
|
||||
size_t bufsize; /* max size */
|
||||
size_t b_max; /* max size in bits */
|
||||
uint32_t b_off; /* current offset in bits inside buffer */
|
||||
uint8_t* buf; // buffer to read/write
|
||||
uint32_t bufsize; // max size
|
||||
uint32_t b_max; // max size in bits
|
||||
uint32_t b_off; // current offset in bits inside buffer
|
||||
} bitstream_t;
|
||||
|
||||
/* convenience util */
|
||||
static inline void bm_setup(bitstream_t* bs, uint8_t* buf, size_t bufsize) {
|
||||
static inline void bm_setup(bitstream_t* bs, uint8_t* buf, uint32_t bufsize) {
|
||||
bs->buf = buf;
|
||||
bs->bufsize = bufsize;
|
||||
bs->b_max = bufsize * 8;
|
||||
|
@ -136,6 +138,14 @@ fail:
|
|||
return 0;
|
||||
}
|
||||
|
||||
static inline uint32_t bm_read(bitstream_t* ib, uint32_t bits) {
|
||||
uint32_t value;
|
||||
int res = bm_get(ib, bits, &value);
|
||||
if (!res)
|
||||
return 0;
|
||||
return value;
|
||||
}
|
||||
|
||||
/* Write bits (max 32) to buf and update the bit offset. Order is BE (MSB). */
|
||||
static inline int bm_put(bitstream_t* ob, uint32_t bits, uint32_t value) {
|
||||
uint32_t shift, pos;
|
||||
|
|
16
Frameworks/vgmstream/vgmstream/src/util/io_callback.h
Normal file
16
Frameworks/vgmstream/vgmstream/src/util/io_callback.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef _IO_CALLBACK_H_
|
||||
#define _IO_CALLBACK_H_
|
||||
|
||||
#include <stdint.h>
|
||||
|
||||
#define IO_CALLBACK_SEEK_SET 0
|
||||
#define IO_CALLBACK_SEEK_CUR 1
|
||||
#define IO_CALLBACK_SEEK_END 2
|
||||
typedef struct {
|
||||
void* arg;
|
||||
int64_t (*read)(void* dst, int size, int n, void* arg);
|
||||
int64_t (*seek)(void* arg, int64_t offset, int whence);
|
||||
int64_t (*tell)(void* arg);
|
||||
} io_callback_t;
|
||||
|
||||
#endif
|
53
Frameworks/vgmstream/vgmstream/src/util/io_callback_sf.c
Normal file
53
Frameworks/vgmstream/vgmstream/src/util/io_callback_sf.c
Normal file
|
@ -0,0 +1,53 @@
|
|||
#include "io_callback_sf.h"
|
||||
#include <stdint.h>
|
||||
|
||||
static int64_t io_sf_read(void* dst, int size, int n, void* arg) {
|
||||
io_priv_t* io = arg;
|
||||
|
||||
int bytes_read = read_streamfile(dst, io->offset, size * n, io->sf);
|
||||
int items_read = bytes_read / size;
|
||||
io->offset += bytes_read;
|
||||
|
||||
return items_read;
|
||||
}
|
||||
|
||||
static int64_t io_sf_seek(void* arg, int64_t offset, int whence) {
|
||||
io_priv_t* io = arg;
|
||||
|
||||
int64_t base_offset;
|
||||
switch (whence) {
|
||||
case IO_CALLBACK_SEEK_SET:
|
||||
base_offset = 0;
|
||||
break;
|
||||
case IO_CALLBACK_SEEK_CUR:
|
||||
base_offset = io->offset;
|
||||
break;
|
||||
case IO_CALLBACK_SEEK_END:
|
||||
base_offset = get_streamfile_size(io->sf);
|
||||
break;
|
||||
default:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int64_t new_offset = base_offset + offset;
|
||||
if (new_offset < 0 /*|| new_offset > get_streamfile_size(config->sf)*/) {
|
||||
return -1; /* unseekable */
|
||||
}
|
||||
else {
|
||||
io->offset = new_offset;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int64_t io_sf_tell(void* arg) {
|
||||
io_priv_t* io = arg;
|
||||
|
||||
return io->offset;
|
||||
}
|
||||
|
||||
void io_callbacks_set_sf(io_callback_t* cb, io_priv_t* arg) {
|
||||
cb->arg = arg;
|
||||
cb->read = io_sf_read;
|
||||
cb->seek = io_sf_seek;
|
||||
cb->tell = io_sf_tell;
|
||||
}
|
16
Frameworks/vgmstream/vgmstream/src/util/io_callback_sf.h
Normal file
16
Frameworks/vgmstream/vgmstream/src/util/io_callback_sf.h
Normal file
|
@ -0,0 +1,16 @@
|
|||
#ifndef _IO_CALLBACK_SF_H_
|
||||
#define _IO_CALLBACK_SF_H_
|
||||
|
||||
#include "io_callback.h"
|
||||
#include "../streamfile.h"
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct {
|
||||
STREAMFILE* sf;
|
||||
int64_t offset;
|
||||
} io_priv_t;
|
||||
|
||||
void io_callbacks_set_sf(io_callback_t* cb, io_priv_t* arg);
|
||||
|
||||
#endif
|
|
@ -15,6 +15,7 @@ logger_t log_impl = {0};
|
|||
//void* log = &log_impl;
|
||||
|
||||
enum {
|
||||
LOG_LEVEL_NONE = 0,
|
||||
LOG_LEVEL_INFO = 1,
|
||||
LOG_LEVEL_DEBUG = 2,
|
||||
LOG_LEVEL_ALL = 100,
|
||||
|
@ -30,6 +31,11 @@ void vgm_log_set_callback(void* ctx_p, int level, int type, void* callback) {
|
|||
|
||||
ctx->level = level;
|
||||
|
||||
if (level == LOG_LEVEL_NONE) {
|
||||
ctx->callback = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
switch(type) {
|
||||
case 0:
|
||||
ctx->callback = callback;
|
||||
|
|
20
Frameworks/vgmstream/vgmstream/src/util/vorbis_codebooks.c
Normal file
20
Frameworks/vgmstream/vgmstream/src/util/vorbis_codebooks.c
Normal file
|
@ -0,0 +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;
|
||||
}
|
17
Frameworks/vgmstream/vgmstream/src/util/vorbis_codebooks.h
Normal file
17
Frameworks/vgmstream/vgmstream/src/util/vorbis_codebooks.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#ifndef _VORBIS_CODEBOOKS_H_
|
||||
#define _VORBIS_CODEBOOKS_H_
|
||||
|
||||
#include <stdint.h>
|
||||
#include "../streamfile.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
uint32_t id;
|
||||
uint32_t size;
|
||||
const uint8_t* codebooks;
|
||||
} vcb_info_t;
|
||||
|
||||
|
||||
int vcb_load_codebook_array(uint8_t* buf, int buf_size, uint32_t setup_id, const vcb_info_t* list, int list_length);
|
||||
//, STREAMFILE* sf
|
||||
#endif
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Reference in a new issue