Updated FFmpeg and VGMStream.
parent
89a2ab07a1
commit
e274ec01eb
|
@ -345,6 +345,11 @@
|
||||||
838BDB7B1D3B1FC20022CA6F /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB7A1D3B1FC20022CA6F /* CoreMedia.framework */; };
|
838BDB7B1D3B1FC20022CA6F /* CoreMedia.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB7A1D3B1FC20022CA6F /* CoreMedia.framework */; };
|
||||||
838BDB7D1D3B1FCC0022CA6F /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB7C1D3B1FCC0022CA6F /* CoreVideo.framework */; };
|
838BDB7D1D3B1FCC0022CA6F /* CoreVideo.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB7C1D3B1FCC0022CA6F /* CoreVideo.framework */; };
|
||||||
838BDB7F1D3B1FD10022CA6F /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB7E1D3B1FD10022CA6F /* Cocoa.framework */; };
|
838BDB7F1D3B1FD10022CA6F /* Cocoa.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 838BDB7E1D3B1FD10022CA6F /* Cocoa.framework */; };
|
||||||
|
83A3F0741E3AD8B900D6A794 /* formats.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A3F0711E3AD8B900D6A794 /* formats.c */; };
|
||||||
|
83A3F0751E3AD8B900D6A794 /* formats.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A3F0721E3AD8B900D6A794 /* formats.h */; };
|
||||||
|
83A3F0761E3AD8B900D6A794 /* stack_alloc.h in Headers */ = {isa = PBXBuildFile; fileRef = 83A3F0731E3AD8B900D6A794 /* stack_alloc.h */; };
|
||||||
|
83A3F07C1E3AD92400D6A794 /* ps2.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A3F07A1E3AD92400D6A794 /* ps2.c */; };
|
||||||
|
83A3F07D1E3AD92400D6A794 /* x360.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A3F07B1E3AD92400D6A794 /* x360.c */; };
|
||||||
83A5F75F198DF021009AF94C /* bfwav.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A5F75E198DF021009AF94C /* bfwav.c */; };
|
83A5F75F198DF021009AF94C /* bfwav.c in Sources */ = {isa = PBXBuildFile; fileRef = 83A5F75E198DF021009AF94C /* bfwav.c */; };
|
||||||
83BAFB6C19F45EB3005DAB60 /* bfstm.c in Sources */ = {isa = PBXBuildFile; fileRef = 83BAFB6B19F45EB3005DAB60 /* bfstm.c */; };
|
83BAFB6C19F45EB3005DAB60 /* bfstm.c in Sources */ = {isa = PBXBuildFile; fileRef = 83BAFB6B19F45EB3005DAB60 /* bfstm.c */; };
|
||||||
83D731101A7394BF00CA1366 /* g7221.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83D730EB1A738EB300CA1366 /* g7221.framework */; };
|
83D731101A7394BF00CA1366 /* g7221.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 83D730EB1A738EB300CA1366 /* g7221.framework */; };
|
||||||
|
@ -804,6 +809,11 @@
|
||||||
838BDB7A1D3B1FC20022CA6F /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
|
838BDB7A1D3B1FC20022CA6F /* CoreMedia.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreMedia.framework; path = System/Library/Frameworks/CoreMedia.framework; sourceTree = SDKROOT; };
|
||||||
838BDB7C1D3B1FCC0022CA6F /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
|
838BDB7C1D3B1FCC0022CA6F /* CoreVideo.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = CoreVideo.framework; path = System/Library/Frameworks/CoreVideo.framework; sourceTree = SDKROOT; };
|
||||||
838BDB7E1D3B1FD10022CA6F /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
838BDB7E1D3B1FD10022CA6F /* Cocoa.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = Cocoa.framework; path = System/Library/Frameworks/Cocoa.framework; sourceTree = SDKROOT; };
|
||||||
|
83A3F0711E3AD8B900D6A794 /* formats.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = formats.c; sourceTree = "<group>"; };
|
||||||
|
83A3F0721E3AD8B900D6A794 /* formats.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = formats.h; sourceTree = "<group>"; };
|
||||||
|
83A3F0731E3AD8B900D6A794 /* stack_alloc.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = stack_alloc.h; sourceTree = "<group>"; };
|
||||||
|
83A3F07A1E3AD92400D6A794 /* ps2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ps2.c; sourceTree = "<group>"; };
|
||||||
|
83A3F07B1E3AD92400D6A794 /* x360.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = x360.c; sourceTree = "<group>"; };
|
||||||
83A5F75E198DF021009AF94C /* bfwav.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bfwav.c; sourceTree = "<group>"; };
|
83A5F75E198DF021009AF94C /* bfwav.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bfwav.c; sourceTree = "<group>"; };
|
||||||
83BAFB6B19F45EB3005DAB60 /* bfstm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bfstm.c; sourceTree = "<group>"; };
|
83BAFB6B19F45EB3005DAB60 /* bfstm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bfstm.c; sourceTree = "<group>"; };
|
||||||
83D730E51A738EB200CA1366 /* g7221.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = g7221.xcodeproj; path = ../g7221/g7221.xcodeproj; sourceTree = "<group>"; };
|
83D730E51A738EB200CA1366 /* g7221.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = g7221.xcodeproj; path = ../g7221/g7221.xcodeproj; sourceTree = "<group>"; };
|
||||||
|
@ -945,6 +955,9 @@
|
||||||
836F6DDF18BDC2180095E648 /* coding */,
|
836F6DDF18BDC2180095E648 /* coding */,
|
||||||
836F6DFF18BDC2180095E648 /* layout */,
|
836F6DFF18BDC2180095E648 /* layout */,
|
||||||
836F6E2718BDC2180095E648 /* meta */,
|
836F6E2718BDC2180095E648 /* meta */,
|
||||||
|
83A3F0711E3AD8B900D6A794 /* formats.c */,
|
||||||
|
83A3F0721E3AD8B900D6A794 /* formats.h */,
|
||||||
|
83A3F0731E3AD8B900D6A794 /* stack_alloc.h */,
|
||||||
836F6F1718BDC2190095E648 /* streamfile.c */,
|
836F6F1718BDC2190095E648 /* streamfile.c */,
|
||||||
836F6F1818BDC2190095E648 /* streamfile.h */,
|
836F6F1818BDC2190095E648 /* streamfile.h */,
|
||||||
836F6F1918BDC2190095E648 /* streamtypes.h */,
|
836F6F1918BDC2190095E648 /* streamtypes.h */,
|
||||||
|
@ -1041,6 +1054,8 @@
|
||||||
836F6E2718BDC2180095E648 /* meta */ = {
|
836F6E2718BDC2180095E648 /* meta */ = {
|
||||||
isa = PBXGroup;
|
isa = PBXGroup;
|
||||||
children = (
|
children = (
|
||||||
|
83A3F07A1E3AD92400D6A794 /* ps2.c */,
|
||||||
|
83A3F07B1E3AD92400D6A794 /* x360.c */,
|
||||||
8350C0591E071990009E0A93 /* ps2_svag_snk.c */,
|
8350C0591E071990009E0A93 /* ps2_svag_snk.c */,
|
||||||
8350C0541E071881009E0A93 /* xma.c */,
|
8350C0541E071881009E0A93 /* xma.c */,
|
||||||
838BDB6D1D3B043C0022CA6F /* ffmpeg.c */,
|
838BDB6D1D3B043C0022CA6F /* ffmpeg.c */,
|
||||||
|
@ -1321,7 +1336,9 @@
|
||||||
836F6F3518BDC2190095E648 /* nwa_decoder.h in Headers */,
|
836F6F3518BDC2190095E648 /* nwa_decoder.h in Headers */,
|
||||||
836F6F2718BDC2190095E648 /* g72x_state.h in Headers */,
|
836F6F2718BDC2190095E648 /* g72x_state.h in Headers */,
|
||||||
836F705418BDC2190095E648 /* streamfile.h in Headers */,
|
836F705418BDC2190095E648 /* streamfile.h in Headers */,
|
||||||
|
83A3F0761E3AD8B900D6A794 /* stack_alloc.h in Headers */,
|
||||||
8323894B1D22419B00482226 /* clHCA.h in Headers */,
|
8323894B1D22419B00482226 /* clHCA.h in Headers */,
|
||||||
|
83A3F0751E3AD8B900D6A794 /* formats.h in Headers */,
|
||||||
836F705918BDC2190095E648 /* vgmstream.h in Headers */,
|
836F705918BDC2190095E648 /* vgmstream.h in Headers */,
|
||||||
48C2650F1A5D420800A0A3D6 /* vorbisfile.h in Headers */,
|
48C2650F1A5D420800A0A3D6 /* vorbisfile.h in Headers */,
|
||||||
836F705718BDC2190095E648 /* util.h in Headers */,
|
836F705718BDC2190095E648 /* util.h in Headers */,
|
||||||
|
@ -1533,6 +1550,7 @@
|
||||||
836F6FD218BDC2190095E648 /* ps2_bmdx.c in Sources */,
|
836F6FD218BDC2190095E648 /* ps2_bmdx.c in Sources */,
|
||||||
836F703C18BDC2190095E648 /* wii_bns.c in Sources */,
|
836F703C18BDC2190095E648 /* wii_bns.c in Sources */,
|
||||||
836F6FA718BDC2190095E648 /* nds_strm.c in Sources */,
|
836F6FA718BDC2190095E648 /* nds_strm.c in Sources */,
|
||||||
|
83A3F0741E3AD8B900D6A794 /* formats.c in Sources */,
|
||||||
836F6F6E18BDC2190095E648 /* aix.c in Sources */,
|
836F6F6E18BDC2190095E648 /* aix.c in Sources */,
|
||||||
836F703118BDC2190095E648 /* ss_stream.c in Sources */,
|
836F703118BDC2190095E648 /* ss_stream.c in Sources */,
|
||||||
836F701018BDC2190095E648 /* ps2_xau.c in Sources */,
|
836F701018BDC2190095E648 /* ps2_xau.c in Sources */,
|
||||||
|
@ -1596,6 +1614,7 @@
|
||||||
836F6F8218BDC2190095E648 /* ea_header.c in Sources */,
|
836F6F8218BDC2190095E648 /* ea_header.c in Sources */,
|
||||||
836F700A18BDC2190095E648 /* ps2_vpk.c in Sources */,
|
836F700A18BDC2190095E648 /* ps2_vpk.c in Sources */,
|
||||||
836F6F7318BDC2190095E648 /* bcstm.c in Sources */,
|
836F6F7318BDC2190095E648 /* bcstm.c in Sources */,
|
||||||
|
83A3F07D1E3AD92400D6A794 /* x360.c in Sources */,
|
||||||
836F704018BDC2190095E648 /* wii_sng.c in Sources */,
|
836F704018BDC2190095E648 /* wii_sng.c in Sources */,
|
||||||
8350C0551E071881009E0A93 /* xma.c in Sources */,
|
8350C0551E071881009E0A93 /* xma.c in Sources */,
|
||||||
836F6F3218BDC2190095E648 /* ngc_dsp_decoder.c in Sources */,
|
836F6F3218BDC2190095E648 /* ngc_dsp_decoder.c in Sources */,
|
||||||
|
@ -1647,6 +1666,7 @@
|
||||||
836F6F3118BDC2190095E648 /* ngc_afc_decoder.c in Sources */,
|
836F6F3118BDC2190095E648 /* ngc_afc_decoder.c in Sources */,
|
||||||
836F6FE718BDC2190095E648 /* ps2_mib.c in Sources */,
|
836F6FE718BDC2190095E648 /* ps2_mib.c in Sources */,
|
||||||
836F6FAB18BDC2190095E648 /* ngc_bo2.c in Sources */,
|
836F6FAB18BDC2190095E648 /* ngc_bo2.c in Sources */,
|
||||||
|
83A3F07C1E3AD92400D6A794 /* ps2.c in Sources */,
|
||||||
836F6F9918BDC2190095E648 /* maxis_xa.c in Sources */,
|
836F6F9918BDC2190095E648 /* maxis_xa.c in Sources */,
|
||||||
836F702118BDC2190095E648 /* rs03.c in Sources */,
|
836F702118BDC2190095E648 /* rs03.c in Sources */,
|
||||||
836F6F8418BDC2190095E648 /* emff.c in Sources */,
|
836F6F8418BDC2190095E648 /* emff.c in Sources */,
|
||||||
|
|
|
@ -3,43 +3,42 @@
|
||||||
|
|
||||||
#include "../vgmstream.h"
|
#include "../vgmstream.h"
|
||||||
|
|
||||||
|
/* adx_decoder */
|
||||||
void decode_adx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_adx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void decode_adx_enc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_adx_enc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
void adx_next_key(VGMSTREAMCHANNEL * stream);
|
void adx_next_key(VGMSTREAMCHANNEL * stream);
|
||||||
|
|
||||||
|
/* g721_decoder */
|
||||||
void decode_g721(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_g721(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void g72x_init_state(struct g72x_state *state_ptr);
|
void g72x_init_state(struct g72x_state *state_ptr);
|
||||||
|
|
||||||
|
/* ima_decoder */
|
||||||
void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_nds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void decode_dat4_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_dat4_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void decode_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
void decode_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
||||||
void decode_int_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
void decode_int_xbox_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
||||||
void decode_dvi_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_dvi_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void decode_eacs_ima(VGMSTREAM * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
void decode_eacs_ima(VGMSTREAM * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||||
|
|
||||||
void decode_snds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
void decode_snds_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||||
|
|
||||||
void decode_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_ima(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
void decode_ms_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
|
||||||
|
|
||||||
void decode_rad_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
void decode_rad_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
||||||
|
|
||||||
void decode_rad_ima_mono(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_rad_ima_mono(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
void decode_apple_ima4(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_apple_ima4(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
void decode_ms_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
void decode_ms_ima(VGMSTREAM * vgmstream,VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
||||||
void decode_ngc_afc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
|
/* ngc_dsp_decoder */
|
||||||
void decode_ngc_dsp(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_ngc_dsp(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void decode_ngc_dsp_mem(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, uint8_t * mem);
|
void decode_ngc_dsp_mem(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, uint8_t * mem);
|
||||||
|
|
||||||
int32_t dsp_nibbles_to_samples(int32_t nibbles);
|
int32_t dsp_nibbles_to_samples(int32_t nibbles);
|
||||||
|
void dsp_read_coefs_be(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t offset, off_t spacing);
|
||||||
|
|
||||||
|
/* ngc_dtk_decoder */
|
||||||
void decode_ngc_dtk(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
void decode_ngc_dtk(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||||
|
|
||||||
|
/* ngc_afc_decoder */
|
||||||
|
void decode_ngc_afc(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
|
/* pcm_decoder */
|
||||||
void decode_pcm16LE(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_pcm16LE(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void decode_pcm16LE_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_pcm16LE_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void decode_pcm16LE_XOR_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_pcm16LE_XOR_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
@ -50,98 +49,108 @@ void decode_pcm8_sb_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channels
|
||||||
void decode_pcm8_unsigned_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_pcm8_unsigned_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
void decode_pcm8_unsigned(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_pcm8_unsigned(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
|
/* psx_decoder */
|
||||||
void decode_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
void decode_invert_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
void decode_psx_badflags(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_psx_badflags(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
void decode_psx_bmdx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
void decode_psx_configurable(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int frame_size);
|
||||||
|
void decode_hevag(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
void decode_ffxi_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
/* xa_decoder */
|
||||||
|
|
||||||
void decode_baf_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
void decode_hevag_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
void decode_short_vag_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
void decode_xa(VGMSTREAM * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
void decode_xa(VGMSTREAM * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||||
void init_get_high_nibble(VGMSTREAM * vgmstream);
|
void init_get_high_nibble(VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
void decode_eaxa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
/*eaxa_decoder */
|
||||||
|
void decode_ea_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel);
|
||||||
void decode_ea_adpcm(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
void decode_ea_adpcm(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||||
void decode_maxis_adpcm(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
void decode_maxis_adpcm(VGMSTREAM * vgmstream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
|
||||||
|
|
||||||
|
/* sdx2_decoder */
|
||||||
|
void decode_sdx2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
void decode_sdx2_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
/* sdx2_decoder */
|
||||||
|
void decode_cbd2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
void decode_cbd2_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
|
/* ws_decoder */
|
||||||
|
void decode_ws(VGMSTREAM * vgmstream, int channel, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
|
/* acm_decoder */
|
||||||
|
void decode_acm(ACMStream * acm, sample * outbuf, int32_t samples_to_do, int channelspacing);
|
||||||
|
|
||||||
|
/* nwa_decoder */
|
||||||
|
void decode_nwa(NWAData *nwa, sample *outbuf, int32_t samples_to_do);
|
||||||
|
|
||||||
|
/* msadpcm_decoder */
|
||||||
|
long msadpcm_bytes_to_samples(long bytes, int block_size, int channels);
|
||||||
|
void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
void decode_msadpcm_mono(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
|
/* aica_decoder */
|
||||||
|
void decode_aica(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
|
/* nds_procyon_decoder */
|
||||||
|
void decode_nds_procyon(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
|
/* l5_555_decoder */
|
||||||
|
void decode_l5_555(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
|
/* SASSC_decoder */
|
||||||
|
void decode_SASSC(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
|
/* lsf_decode */
|
||||||
|
void decode_lsf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
|
||||||
|
/* mtaf_decoder */
|
||||||
|
void decode_mtaf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int channels);
|
||||||
|
|
||||||
|
/* hca_decoder */
|
||||||
|
void decode_hca(hca_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels);
|
||||||
|
|
||||||
|
/* ogg_vorbis_decoder */
|
||||||
#ifdef VGM_USE_VORBIS
|
#ifdef VGM_USE_VORBIS
|
||||||
void decode_ogg_vorbis(ogg_vorbis_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels);
|
void decode_ogg_vorbis(ogg_vorbis_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* mpeg_decoder */
|
||||||
|
#ifdef VGM_USE_MPEG
|
||||||
|
mpeg_codec_data *init_mpeg_codec_data(STREAMFILE *streamfile, off_t start_offset, long given_sample_rate, int given_channels, coding_t *coding_type, int * actual_sample_rate, int * actual_channels);
|
||||||
|
void decode_fake_mpeg2_l2(VGMSTREAMCHANNEL * stream, mpeg_codec_data * data, sample * outbuf, int32_t samples_to_do);
|
||||||
|
void decode_mpeg(VGMSTREAMCHANNEL * stream, mpeg_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels);
|
||||||
|
long mpeg_bytes_to_samples(long bytes, const struct mpg123_frameinfo *mi);
|
||||||
|
void mpeg_set_error_logging(mpeg_codec_data * data, int enable);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* g7221_decoder */
|
||||||
|
#ifdef VGM_USE_G7221
|
||||||
|
void decode_g7221(VGMSTREAM *vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* g719_decoder */
|
||||||
|
#ifdef VGM_USE_G719
|
||||||
|
void decode_g719(VGMSTREAM *vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* mp4_aac_decoder */
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
void decode_mp4_aac(mp4_aac_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels);
|
void decode_mp4_aac(mp4_aac_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void decode_sdx2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
/* at3_decoder */
|
||||||
void decode_sdx2_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
void decode_cbd2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
void decode_cbd2_int(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
void decode_ws(VGMSTREAM * vgmstream, int channel, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
#ifdef VGM_USE_MPEG
|
|
||||||
void decode_fake_mpeg2_l2(VGMSTREAMCHANNEL * stream,
|
|
||||||
mpeg_codec_data * data,
|
|
||||||
sample * outbuf, int32_t samples_to_do);
|
|
||||||
mpeg_codec_data *init_mpeg_codec_data(STREAMFILE *streamfile, off_t start_offset, long given_sample_rate, int given_channels, coding_t *coding_type, int * actual_sample_rate, int * actual_channels);
|
|
||||||
long mpeg_bytes_to_samples(long bytes, const struct mpg123_frameinfo *mi);
|
|
||||||
void decode_mpeg(VGMSTREAMCHANNEL * stream,
|
|
||||||
mpeg_codec_data * data,
|
|
||||||
sample * outbuf, int32_t samples_to_do, int channels);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VGM_USE_G7221
|
|
||||||
void decode_g7221(VGMSTREAM *vgmstream,
|
|
||||||
sample * outbuf, int channelspacing, int32_t samples_to_do, int channel);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VGM_USE_G719
|
|
||||||
void decode_g719(VGMSTREAM *vgmstream,
|
|
||||||
sample * outbuf, int channelspacing, int32_t samples_to_do, int channel);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef VGM_USE_MAIATRAC3PLUS
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
||||||
void decode_at3plus(VGMSTREAM *vgmstream,
|
void decode_at3plus(VGMSTREAM *vgmstream, sample * outbuf, int channelspacing, int32_t samples_to_do, int channel);
|
||||||
sample * outbuf, int channelspacing, int32_t samples_to_do, int channel);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
/* ffmpeg_decoder */
|
||||||
#ifdef VGM_USE_FFMPEG
|
#ifdef VGM_USE_FFMPEG
|
||||||
void decode_ffmpeg(VGMSTREAM *stream, sample * outbuf, int32_t samples_to_do, int channels);
|
void decode_ffmpeg(VGMSTREAM *stream, sample * outbuf, int32_t samples_to_do, int channels);
|
||||||
|
|
||||||
void reset_ffmpeg(VGMSTREAM *vgmstream);
|
void reset_ffmpeg(VGMSTREAM *vgmstream);
|
||||||
|
|
||||||
void seek_ffmpeg(VGMSTREAM *vgmstream, int32_t num_sample);
|
void seek_ffmpeg(VGMSTREAM *vgmstream, int32_t num_sample);
|
||||||
#endif
|
|
||||||
|
|
||||||
void decode_acm(ACMStream * acm, sample * outbuf,
|
int ffmpeg_make_riff_atrac3(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int joint_stereo, int encoder_delay);
|
||||||
int32_t samples_to_do, int channelspacing);
|
int ffmpeg_make_riff_xma2(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_count, int block_size);
|
||||||
|
int ffmpeg_make_riff_xma2_from_fmt(uint8_t * buf, size_t buf_size, off_t fmt_offset, size_t fmt_size, size_t data_size, STREAMFILE *streamFile, int big_endian);
|
||||||
void decode_nwa(NWAData *nwa, sample *outbuf, int32_t samples_to_do);
|
|
||||||
|
|
||||||
long msadpcm_bytes_to_samples(long bytes, int block_size, int channels);
|
|
||||||
void decode_msadpcm_stereo(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
void decode_msadpcm_mono(VGMSTREAM * vgmstream, sample * outbuf, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
void decode_aica(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
void decode_nds_procyon(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
void decode_l5_555(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
void decode_SASSC(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
void decode_lsf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
|
||||||
|
|
||||||
void decode_mtaf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int channels);
|
|
||||||
|
|
||||||
void decode_hca(hca_codec_data * data, sample * outbuf, int32_t samples_to_do, int channels);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif /*_CODING_H*/
|
||||||
|
|
|
@ -14,7 +14,7 @@ int32_t EA_TABLE[20]= { 0x00000000, 0x000000F0, 0x000001CC, 0x00000188,
|
||||||
0x00000007, 0x00000008, 0x0000000A, 0x0000000B,
|
0x00000007, 0x00000008, 0x0000000A, 0x0000000B,
|
||||||
0x00000000, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFC};
|
0x00000000, 0xFFFFFFFF, 0xFFFFFFFD, 0xFFFFFFFC};
|
||||||
|
|
||||||
void decode_eaxa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel) {
|
void decode_ea_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel) {
|
||||||
uint8_t frame_info;
|
uint8_t frame_info;
|
||||||
int32_t sample_count;
|
int32_t sample_count;
|
||||||
int32_t coef1,coef2;
|
int32_t coef1,coef2;
|
||||||
|
|
|
@ -239,11 +239,6 @@ end:
|
||||||
data->readNextPacket = readNextPacket;
|
data->readNextPacket = readNextPacket;
|
||||||
data->endOfStream = endOfStream;
|
data->endOfStream = endOfStream;
|
||||||
data->endOfAudio = endOfAudio;
|
data->endOfAudio = endOfAudio;
|
||||||
|
|
||||||
// And pad if we ran short (end of file)
|
|
||||||
if (framesReadNow < samples_to_do) {
|
|
||||||
memset(outbuf + framesReadNow * channels, 0, sizeof(sample) * channels * (samples_to_do - framesReadNow));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -268,42 +263,13 @@ void seek_ffmpeg(VGMSTREAM *vgmstream, int32_t num_sample) {
|
||||||
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
ffmpeg_codec_data *data = (ffmpeg_codec_data *) vgmstream->codec_data;
|
||||||
int64_t ts;
|
int64_t ts;
|
||||||
|
|
||||||
#ifndef VGM_USE_FFMPEG_ACCURATE_LOOPING
|
/* Start from 0 and discard samples until loop_start (slower but not too noticeable) */
|
||||||
/* Seek to loop start by timestamp (closest frame) + adjust skipping some samples */
|
/* Due to various FFmpeg quirks seeking to a sample is erratic in many formats (would need extra steps) */
|
||||||
/* FFmpeg seeks by ts by design (since not all containers can accurately skip to a frame). */
|
|
||||||
/* TODO: this seems to be off by +-1 frames in some cases */
|
|
||||||
ts = num_sample;
|
|
||||||
if (ts >= data->sampleRate * 2) {
|
|
||||||
data->samplesToDiscard = data->sampleRate * 2;
|
|
||||||
ts -= data->samplesToDiscard;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
data->samplesToDiscard = (int)ts;
|
|
||||||
ts = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* todo fix this properly */
|
|
||||||
if (data->totalSamples) {
|
|
||||||
ts = (int)ts * (data->formatCtx->duration) / data->totalSamples;
|
|
||||||
} else {
|
|
||||||
data->samplesToDiscard = num_sample;
|
|
||||||
ts = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
avformat_seek_file(data->formatCtx, data->streamIndex, ts - 1000, ts, ts, AVSEEK_FLAG_ANY);
|
|
||||||
avcodec_flush_buffers(data->codecCtx);
|
|
||||||
#endif /* ifndef VGM_USE_FFMPEG_ACCURATE_LOOPING */
|
|
||||||
|
|
||||||
#ifdef VGM_USE_FFMPEG_ACCURATE_LOOPING
|
|
||||||
/* Start from 0 and discard samples until loop_start for accurate looping (slower but not too noticeable) */
|
|
||||||
/* We could also seek by offset (AVSEEK_FLAG_BYTE) to the frame closest to the loop then discard
|
|
||||||
* some samples, which is fast but would need calculations per format / when frame size is not constant */
|
|
||||||
data->samplesToDiscard = num_sample;
|
data->samplesToDiscard = num_sample;
|
||||||
ts = 0;
|
ts = 0;
|
||||||
|
|
||||||
avformat_seek_file(data->formatCtx, data->streamIndex, ts, ts, ts, AVSEEK_FLAG_ANY);
|
avformat_seek_file(data->formatCtx, data->streamIndex, ts, ts, ts, AVSEEK_FLAG_ANY);
|
||||||
avcodec_flush_buffers(data->codecCtx);
|
avcodec_flush_buffers(data->codecCtx);
|
||||||
#endif /* ifdef VGM_USE_FFMPEG_ACCURATE_LOOPING */
|
|
||||||
|
|
||||||
data->readNextPacket = 1;
|
data->readNextPacket = 1;
|
||||||
data->bytesConsumedFromDecodedFrame = INT_MAX;
|
data->bytesConsumedFromDecodedFrame = INT_MAX;
|
||||||
|
@ -312,4 +278,208 @@ void seek_ffmpeg(VGMSTREAM *vgmstream, int32_t num_sample) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/* ******************************************** */
|
||||||
|
/* FAKE RIFF HELPERS */
|
||||||
|
/* ******************************************** */
|
||||||
|
static int ffmpeg_fmt_chunk_swap_endian(uint8_t * chunk, uint16_t codec);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies a ATRAC3 riff to buf
|
||||||
|
*
|
||||||
|
* returns number of bytes in buf or -1 when buf is not big enough
|
||||||
|
*/
|
||||||
|
int ffmpeg_make_riff_atrac3(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int joint_stereo, int encoder_delay) {
|
||||||
|
uint16_t codec_ATRAC3 = 0x0270;
|
||||||
|
size_t riff_size = 4+4+ 4 + 0x28 + 0x10 + 4+4;
|
||||||
|
|
||||||
|
if (buf_size < riff_size)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
memcpy(buf+0x00, "RIFF", 4);
|
||||||
|
put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */
|
||||||
|
memcpy(buf+0x08, "WAVE", 4);
|
||||||
|
|
||||||
|
memcpy(buf+0x0c, "fmt ", 4);
|
||||||
|
put_32bitLE(buf+0x10, 0x20);/*fmt size*/
|
||||||
|
put_16bitLE(buf+0x14, codec_ATRAC3);
|
||||||
|
put_16bitLE(buf+0x16, channels);
|
||||||
|
put_32bitLE(buf+0x18, sample_rate);
|
||||||
|
put_32bitLE(buf+0x1c, sample_rate*channels / sizeof(sample)); /* average bytes per second (wrong) */
|
||||||
|
put_32bitLE(buf+0x20, (int16_t)(block_align)); /* block align */
|
||||||
|
|
||||||
|
put_16bitLE(buf+0x24, 0x0e); /* extra data size */
|
||||||
|
put_16bitLE(buf+0x26, 1); /* unknown, always 1 */
|
||||||
|
put_16bitLE(buf+0x28, channels==1 ? 0x0800 : 0x1000); /* unknown (some size? 0x1000=2ch, 0x0800=1ch) */
|
||||||
|
put_16bitLE(buf+0x2a, 0); /* unknown, always 0 */
|
||||||
|
put_16bitLE(buf+0x2c, joint_stereo ? 0x0001 : 0x0000);
|
||||||
|
put_16bitLE(buf+0x2e, joint_stereo ? 0x0001 : 0x0000); /* repeated? */
|
||||||
|
put_16bitLE(buf+0x30, 1); /* unknown, always 1 (frame_factor?) */
|
||||||
|
put_16bitLE(buf+0x32, 0); /* unknown, always 0 */
|
||||||
|
|
||||||
|
memcpy(buf+0x34, "fact", 4);
|
||||||
|
put_32bitLE(buf+0x38, 0x8); /* fact size */
|
||||||
|
put_32bitLE(buf+0x3c, sample_count);
|
||||||
|
put_32bitLE(buf+0x40, encoder_delay);
|
||||||
|
|
||||||
|
memcpy(buf+0x44, "data", 4);
|
||||||
|
put_32bitLE(buf+0x48, data_size); /* data size */
|
||||||
|
|
||||||
|
return riff_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies a XMA2 riff to buf
|
||||||
|
*
|
||||||
|
* returns number of bytes in buf or -1 when buf is not big enough
|
||||||
|
*/
|
||||||
|
int ffmpeg_make_riff_xma2(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_count, int block_size) {
|
||||||
|
uint16_t codec_XMA2 = 0x0166;
|
||||||
|
size_t riff_size = 4+4+ 4 + 0x3c + 4+4;
|
||||||
|
size_t bytecount;
|
||||||
|
uint32_t streams = 0;
|
||||||
|
uint32_t speakers = 0; /* see audiodefs.h */
|
||||||
|
|
||||||
|
if (buf_size < riff_size)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
bytecount = sample_count * channels * sizeof(sample);
|
||||||
|
|
||||||
|
/* untested (no support for > 2ch xma for now) */
|
||||||
|
switch (channels) {
|
||||||
|
case 1:
|
||||||
|
streams = 1;
|
||||||
|
speakers = 0x00000004; /* FC */
|
||||||
|
break;
|
||||||
|
case 2:
|
||||||
|
streams = 1;
|
||||||
|
speakers = 0x00000001 | 0x00000002; /* FL FR */
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
streams = 3;
|
||||||
|
speakers = 0x00000001 | 0x00000002 | 0x00000004; /* FL FC FR */
|
||||||
|
break;
|
||||||
|
case 4:
|
||||||
|
streams = 2;
|
||||||
|
speakers = 0x00000001 | 0x00000002 | 0x00000010 | 0x00000020; /* FL FR BL BR */
|
||||||
|
break;
|
||||||
|
case 5:
|
||||||
|
streams = 3;
|
||||||
|
speakers = 0x00000001 | 0x00000002 | 0x00000010 | 0x00000020 | 0x00000004; /* FL C FR BL BR*/
|
||||||
|
break;
|
||||||
|
case 6:
|
||||||
|
streams = 3;
|
||||||
|
speakers = 0x00000001 | 0x00000002 | 0x00000010 | 0x00000020 | 0x00000200 | 0x00000400; /* FL FR BL BR SL SR */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
streams = 1;
|
||||||
|
speakers = 0x80000000;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*memset(buf,0, sizeof(uint8_t) * fmt_size);*/
|
||||||
|
|
||||||
|
memcpy(buf+0x00, "RIFF", 4);
|
||||||
|
put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */
|
||||||
|
memcpy(buf+0x08, "WAVE", 4);
|
||||||
|
|
||||||
|
memcpy(buf+0x0c, "fmt ", 4);
|
||||||
|
put_32bitLE(buf+0x10, 0x34);/*fmt size*/
|
||||||
|
put_16bitLE(buf+0x14, codec_XMA2);
|
||||||
|
put_16bitLE(buf+0x16, channels);
|
||||||
|
put_32bitLE(buf+0x18, sample_rate);
|
||||||
|
put_32bitLE(buf+0x1c, sample_rate*channels / sizeof(sample)); /* average bytes per second (wrong) */
|
||||||
|
put_16bitLE(buf+0x20, (int16_t)(channels*sizeof(sample))); /* block align */
|
||||||
|
put_16bitLE(buf+0x22, sizeof(sample)*8); /* bits per sample */
|
||||||
|
|
||||||
|
put_16bitLE(buf+0x24, 0x22); /* extra data size */
|
||||||
|
put_16bitLE(buf+0x26, streams); /* number of streams */
|
||||||
|
put_32bitLE(buf+0x28, speakers); /* speaker position */
|
||||||
|
put_32bitLE(buf+0x2c, bytecount); /* PCM samples */
|
||||||
|
put_32bitLE(buf+0x30, block_size); /* XMA block size */
|
||||||
|
/* (looping values not set, expected to be handled externally) */
|
||||||
|
put_32bitLE(buf+0x34, 0); /* play begin */
|
||||||
|
put_32bitLE(buf+0x38, 0); /* play length */
|
||||||
|
put_32bitLE(buf+0x3c, 0); /* loop begin */
|
||||||
|
put_32bitLE(buf+0x40, 0); /* loop length */
|
||||||
|
put_8bit(buf+0x44, 0); /* loop count */
|
||||||
|
put_8bit(buf+0x45, 4); /* encoder version */
|
||||||
|
put_16bitLE(buf+0x46, block_count); /* blocks count = entried in seek table */
|
||||||
|
|
||||||
|
memcpy(buf+0x48, "data", 4);
|
||||||
|
put_32bitLE(buf+0x4c, data_size); /* data size */
|
||||||
|
|
||||||
|
return riff_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Copies a XMA2 riff to buf from a fmt chunk offset
|
||||||
|
*
|
||||||
|
* returns number of bytes in buf or -1 when buf is not big enough
|
||||||
|
*/
|
||||||
|
int ffmpeg_make_riff_xma2_from_fmt(uint8_t * buf, size_t buf_size, off_t fmt_offset, size_t fmt_size, size_t data_size, STREAMFILE *streamFile, int big_endian) {
|
||||||
|
size_t riff_size = 4+4+ 4 + 4+4+fmt_size + 4+4;
|
||||||
|
uint8_t chunk[100];
|
||||||
|
|
||||||
|
if (buf_size < riff_size || fmt_size > 100)
|
||||||
|
goto fail;
|
||||||
|
if (read_streamfile(chunk,fmt_offset,fmt_size, streamFile) != fmt_size)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (big_endian)
|
||||||
|
ffmpeg_fmt_chunk_swap_endian(chunk, 0x166);
|
||||||
|
|
||||||
|
memcpy(buf+0x00, "RIFF", 4);
|
||||||
|
put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */
|
||||||
|
memcpy(buf+0x08, "WAVE", 4);
|
||||||
|
|
||||||
|
memcpy(buf+0x0c, "fmt ", 4);
|
||||||
|
put_32bitLE(buf+0x10, fmt_size);/*fmt size*/
|
||||||
|
memcpy(buf+0x14, chunk, fmt_size);
|
||||||
|
|
||||||
|
memcpy(buf+0x14+fmt_size, "data", 4);
|
||||||
|
put_32bitLE(buf+0x14+fmt_size+4, data_size); /* data size */
|
||||||
|
|
||||||
|
return riff_size;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Swaps endianness
|
||||||
|
*
|
||||||
|
* returns 0 on error
|
||||||
|
*/
|
||||||
|
static int ffmpeg_fmt_chunk_swap_endian(uint8_t * chunk, uint16_t codec) {
|
||||||
|
if (codec != 0x166)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
put_16bitLE(chunk + 0x00, get_16bitBE(chunk + 0x00));/*wFormatTag*/
|
||||||
|
put_16bitLE(chunk + 0x02, get_16bitBE(chunk + 0x02));/*nChannels*/
|
||||||
|
put_32bitLE(chunk + 0x04, get_32bitBE(chunk + 0x04));/*nSamplesPerSec*/
|
||||||
|
put_32bitLE(chunk + 0x08, get_32bitBE(chunk + 0x08));/*nAvgBytesPerSec*/
|
||||||
|
put_16bitLE(chunk + 0x0c, get_16bitBE(chunk + 0x0c));/*nBlockAlign*/
|
||||||
|
put_16bitLE(chunk + 0x0e, get_16bitBE(chunk + 0x0e));/*wBitsPerSample*/
|
||||||
|
put_16bitLE(chunk + 0x10, get_16bitBE(chunk + 0x10));/*cbSize*/
|
||||||
|
put_16bitLE(chunk + 0x12, get_16bitBE(chunk + 0x12));/*NumStreams*/
|
||||||
|
put_32bitLE(chunk + 0x14, get_32bitBE(chunk + 0x14));/*ChannelMask*/
|
||||||
|
put_32bitLE(chunk + 0x18, get_32bitBE(chunk + 0x18));/*SamplesEncoded*/
|
||||||
|
put_32bitLE(chunk + 0x1c, get_32bitBE(chunk + 0x1c));/*BytesPerBlock*/
|
||||||
|
put_32bitLE(chunk + 0x20, get_32bitBE(chunk + 0x20));/*PlayBegin*/
|
||||||
|
put_32bitLE(chunk + 0x24, get_32bitBE(chunk + 0x24));/*PlayLength*/
|
||||||
|
put_32bitLE(chunk + 0x28, get_32bitBE(chunk + 0x28));/*LoopBegin*/
|
||||||
|
put_32bitLE(chunk + 0x2c, get_32bitBE(chunk + 0x2c));/*LoopLength*/
|
||||||
|
/* put_8bit(chunk + 0x30, get_8bit(chunk + 0x30));*//*LoopCount*/
|
||||||
|
/* put_8bit(chunk + 0x31, get_8bit(chunk + 0x31));*//*EncoderVersion*/
|
||||||
|
put_16bitLE(chunk + 0x32, get_16bitBE(chunk + 0x32));/*BlockCount*/
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* streamtypes.h - widely used type definitions
|
* g72x_state.h - internal state used by g721 decoder
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -226,4 +226,11 @@ long mpeg_bytes_to_samples(long bytes, const struct mpg123_frameinfo *mi) {
|
||||||
return (int64_t)bytes * mi->rate * 8 / (mi->bitrate * 1000);
|
return (int64_t)bytes * mi->rate * 8 / (mi->bitrate * 1000);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* disables/enables stderr output, useful for MPEG known to contain recoverable errors
|
||||||
|
*/
|
||||||
|
void mpeg_set_error_logging(mpeg_codec_data * data, int enable) {
|
||||||
|
mpg123_param(data->m, MPG123_ADD_FLAGS, MPG123_QUIET, !enable);
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -3,6 +3,8 @@
|
||||||
#include "coding.h"
|
#include "coding.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
|
||||||
|
#define MTAF_BLOCK_SUPPORT 0
|
||||||
|
|
||||||
// A hybrid of IMA and Yamaha ADPCM found in Metal Gear Solid 3
|
// A hybrid of IMA and Yamaha ADPCM found in Metal Gear Solid 3
|
||||||
// Thanks to X_Tra (http://metalgear.in/) for pointing me to the step size table.
|
// Thanks to X_Tra (http://metalgear.in/) for pointing me to the step size table.
|
||||||
|
|
||||||
|
@ -81,62 +83,79 @@ static int16_t step_size[32][16] = {
|
||||||
|
|
||||||
void decode_mtaf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int channels) {
|
void decode_mtaf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int channels) {
|
||||||
int32_t sample_count;
|
int32_t sample_count;
|
||||||
unsigned long cur_off = stream->offset;
|
off_t cur_off = stream->offset;
|
||||||
int i;
|
int i;
|
||||||
int c = channel%2;
|
int c = channel%2; /* global channel to stream channel */
|
||||||
int16_t init_idx;
|
|
||||||
int16_t init_hist;
|
|
||||||
int32_t hist = stream->adpcm_history1_16;
|
int32_t hist = stream->adpcm_history1_16;
|
||||||
int step_idx = stream->adpcm_step_index;
|
int32_t step_idx = stream->adpcm_step_index;
|
||||||
|
uint8_t byte = 0;
|
||||||
|
|
||||||
//printf("channel %d: first_sample = %d, stream->offset = 0x%lx, cur_off = 0x%lx init_idx = %d\n", channel, first_sample, (unsigned long)stream->offset, cur_off, init_idx);
|
|
||||||
|
|
||||||
#if 0
|
#if MTAF_BLOCK_SUPPORT
|
||||||
if (init_idx < 0 || init_idx > 31) {
|
{
|
||||||
fprintf(stderr, "step idx out of range at 0x%lx ch %d\n", cur_off, c);
|
/* "macroblock" support (layout/mtaf_block.c) was removed since the extractor now produces clean files;
|
||||||
exit(1);
|
* this a hack to skip those blocks, left as a reminder (not well tested) */
|
||||||
|
int unk, size, empty, frames, repeat = 1;
|
||||||
|
do {
|
||||||
|
unk = read_32bitLE(cur_off+0x00, stream->streamfile); /* always BE 0x01001100? */
|
||||||
|
size = read_32bitLE(cur_off+0x04, stream->streamfile); /* block size */
|
||||||
|
empty = read_32bitLE(cur_off+0x08, stream->streamfile); /* always 0? */
|
||||||
|
frames = read_32bitLE(cur_off+0x0c, stream->streamfile); /* total frames of 0x110 */
|
||||||
|
if (unk == 0x00110001 && empty == 0 && size > 0) {
|
||||||
|
if (frames == 0) {
|
||||||
|
stream->offset += size; /* full skip */
|
||||||
|
} else if ((size-0x10) == frames*0x110) {
|
||||||
|
stream->offset += 0x10; /* header skip */
|
||||||
|
repeat = 0;
|
||||||
}
|
}
|
||||||
if (0 != read_16bitLE(cur_off+10+c*4, stream->streamfile)) {
|
cur_off = stream->offset;
|
||||||
fprintf(stderr, "exp. zero after hist at 0x%lx ch %d\n", cur_off, c);
|
}
|
||||||
exit(1);
|
else {
|
||||||
|
repeat = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
} while(repeat);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
first_sample = first_sample%0x100;
|
first_sample = first_sample % 0x100;
|
||||||
|
|
||||||
if (first_sample%0x100 == 0) {
|
/* read header when we hit a new frame every 0x100 samples */
|
||||||
while (read_8bit(cur_off, stream->streamfile) != 0) {
|
if (first_sample == 0) {
|
||||||
cur_off += 16;
|
int32_t init_idx, init_hist;
|
||||||
|
|
||||||
|
/* 0x10 header: owner stream, frame count, step-L, step-R, hist-L, hist-R */
|
||||||
|
/* uint32_t stream = read_8bit(cur_off+0+c*2, stream->streamfile); */ /* 0=first */
|
||||||
|
/* uint24_t frames = (uint24_t)read_16bitLE(cur_off+1, stream->streamfile); */ /* 1=first */
|
||||||
|
init_idx = read_16bitLE(cur_off+4+c*2, stream->streamfile); /* step-L/R */
|
||||||
|
init_hist = read_16bitLE(cur_off+4+4+c*4, stream->streamfile); /* hist-L/R: hist 16bit + empty 16bit */
|
||||||
|
|
||||||
|
VGM_ASSERT( read_16bitLE(cur_off+4+4+2+c*4, stream->streamfile) != 0,
|
||||||
|
"init_hist not 16bit at 0x%lx, ch=%d\n", cur_off, c);
|
||||||
|
VGM_ASSERT( init_idx < 0 || init_idx > 31,
|
||||||
|
"init_idx out of range at 0x%lx, ch=%d\n", cur_off, c);
|
||||||
|
VGM_ASSERT( step_idx != init_idx,
|
||||||
|
"step_idx does not match init_idx at 0x%lx, step=%d, init=%d\n",cur_off,step_idx, init_idx);
|
||||||
|
|
||||||
|
/* avoid index out of range in corrupt files */
|
||||||
|
if (init_idx < 0) {
|
||||||
|
init_idx = 0;
|
||||||
|
} else if (init_idx > 31) {
|
||||||
|
init_idx = 31;
|
||||||
}
|
}
|
||||||
|
|
||||||
stream->offset = cur_off;
|
|
||||||
|
|
||||||
init_idx = read_16bitLE(cur_off+4+c*2, stream->streamfile);
|
|
||||||
init_hist = read_16bitLE(cur_off+8+c*4, stream->streamfile);
|
|
||||||
|
|
||||||
hist = init_hist;
|
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (step_idx != init_idx) {
|
|
||||||
fprintf(stderr, "step_idx does not match at 0x%lx, %d!=%d\n",cur_off,step_idx, init_idx);
|
|
||||||
exit(1);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
step_idx = init_idx;
|
step_idx = init_idx;
|
||||||
|
hist = init_hist;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||||
uint8_t byte, nibble;
|
uint8_t nibble;
|
||||||
|
|
||||||
|
if (i%2 != 1) { /* low nibble first */
|
||||||
byte = read_8bit(cur_off + 0x10 + 0x80*c + i/2, stream->streamfile);
|
byte = read_8bit(cur_off + 0x10 + 0x80*c + i/2, stream->streamfile);
|
||||||
if (i%2!=1)
|
nibble = byte & 0x0f;
|
||||||
{
|
} else { /* high nibble last */
|
||||||
// low nibble first
|
|
||||||
nibble = byte&0xf;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// high nibble last
|
|
||||||
nibble = byte >> 4;
|
nibble = byte >> 4;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,12 +164,9 @@ void decode_mtaf(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
|
||||||
outbuf[sample_count] = hist;
|
outbuf[sample_count] = hist;
|
||||||
|
|
||||||
step_idx += index_table[nibble];
|
step_idx += index_table[nibble];
|
||||||
if (step_idx < 0)
|
if (step_idx < 0) { /* clip step */
|
||||||
{
|
|
||||||
step_idx = 0;
|
step_idx = 0;
|
||||||
}
|
} else if (step_idx > 31) {
|
||||||
if (step_idx > 31)
|
|
||||||
{
|
|
||||||
step_idx = 31;
|
step_idx = 31;
|
||||||
}
|
}
|
||||||
} /* end sample loop */
|
} /* end sample loop */
|
||||||
|
|
|
@ -20,11 +20,6 @@ void decode_ngc_dsp(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspaci
|
||||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||||
int sample_byte = read_8bit(framesin*8+stream->offset+1+i/2,stream->streamfile);
|
int sample_byte = read_8bit(framesin*8+stream->offset+1+i/2,stream->streamfile);
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (hist1==stream->loop_history1 && hist2==stream->loop_history2) fprintf(stderr,"yo! %#x (start %#x) %d\n",stream->offset+framesin*8+i/2,stream->channel_start_offset,stream->samples_done);
|
|
||||||
stream->samples_done++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
outbuf[sample_count] = clamp16((
|
outbuf[sample_count] = clamp16((
|
||||||
(((i&1?
|
(((i&1?
|
||||||
get_low_nibble_signed(sample_byte):
|
get_low_nibble_signed(sample_byte):
|
||||||
|
@ -61,11 +56,6 @@ void decode_ngc_dsp_mem(VGMSTREAMCHANNEL * stream, sample * outbuf, int channels
|
||||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
||||||
int sample_byte = mem[framesin*8+1+i/2];
|
int sample_byte = mem[framesin*8+1+i/2];
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
if (hist1==stream->loop_history1 && hist2==stream->loop_history2) fprintf(stderr,"yo! %#x (start %#x) %d\n",stream->offset+framesin*8+i/2,stream->channel_start_offset,stream->samples_done);
|
|
||||||
stream->samples_done++;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
outbuf[sample_count] = clamp16((
|
outbuf[sample_count] = clamp16((
|
||||||
(((i&1?
|
(((i&1?
|
||||||
get_low_nibble_signed(sample_byte):
|
get_low_nibble_signed(sample_byte):
|
||||||
|
@ -104,3 +94,19 @@ int32_t dsp_nibbles_to_samples(int32_t nibbles) {
|
||||||
if (remainder>0) return whole_frames*14+remainder-2;
|
if (remainder>0) return whole_frames*14+remainder-2;
|
||||||
else return whole_frames*14;
|
else return whole_frames*14;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* reads DSP coefs built in the streamfile
|
||||||
|
*/
|
||||||
|
void dsp_read_coefs_be(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t offset, off_t spacing) {
|
||||||
|
int ch, i;
|
||||||
|
/* get ADPCM coefs */
|
||||||
|
for (ch=0; ch < vgmstream->channels; ch++) {
|
||||||
|
for (i=0; i < 16; i++) {
|
||||||
|
vgmstream->ch[ch].adpcm_coef[i] =
|
||||||
|
read_16bitBE(offset + ch*spacing + i*2, streamFile);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -5,7 +5,6 @@
|
||||||
/* for some algos, maybe closer to the real thing */
|
/* for some algos, maybe closer to the real thing */
|
||||||
#define VAG_USE_INTEGER_TABLE 0
|
#define VAG_USE_INTEGER_TABLE 0
|
||||||
|
|
||||||
|
|
||||||
/* PS ADPCM table (precalculated divs) */
|
/* PS ADPCM table (precalculated divs) */
|
||||||
static const double VAG_f[5][2] = {
|
static const double VAG_f[5][2] = {
|
||||||
{ 0.0 , 0.0 },
|
{ 0.0 , 0.0 },
|
||||||
|
@ -14,6 +13,7 @@ static const double VAG_f[5][2] = {
|
||||||
{ 98.0 / 64.0 , -55.0 / 64.0 },
|
{ 98.0 / 64.0 , -55.0 / 64.0 },
|
||||||
{ 122.0 / 64.0 , -60.0 / 64.0 }
|
{ 122.0 / 64.0 , -60.0 / 64.0 }
|
||||||
};
|
};
|
||||||
|
#if VAG_USE_INTEGER_TABLE
|
||||||
/* PS ADPCM table */
|
/* PS ADPCM table */
|
||||||
static const int8_t VAG_coefs[5][2] = {
|
static const int8_t VAG_coefs[5][2] = {
|
||||||
{ 0 , 0 },
|
{ 0 , 0 },
|
||||||
|
@ -22,7 +22,7 @@ static const int8_t VAG_coefs[5][2] = {
|
||||||
{ 98 , -55 },
|
{ 98 , -55 },
|
||||||
{ 122 , -60 }
|
{ 122 , -60 }
|
||||||
};
|
};
|
||||||
|
#endif
|
||||||
|
|
||||||
/* PSVita ADPCM table */
|
/* PSVita ADPCM table */
|
||||||
static const int16_t HEVAG_coefs[128][4] = {
|
static const int16_t HEVAG_coefs[128][4] = {
|
||||||
|
@ -214,7 +214,7 @@ void decode_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing,
|
||||||
stream->adpcm_history2_32=hist2;
|
stream->adpcm_history2_32=hist2;
|
||||||
}
|
}
|
||||||
|
|
||||||
void decode_invert_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
void decode_psx_bmdx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||||
|
|
||||||
int predict_nr, shift_factor, sample;
|
int predict_nr, shift_factor, sample;
|
||||||
int32_t hist1=stream->adpcm_history1_32;
|
int32_t hist1=stream->adpcm_history1_32;
|
||||||
|
@ -294,84 +294,6 @@ void decode_psx_badflags(VGMSTREAMCHANNEL * stream, sample * outbuf, int channel
|
||||||
stream->adpcm_history2_32=hist2;
|
stream->adpcm_history2_32=hist2;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FF XI's Vag-ish format */
|
|
||||||
void decode_ffxi_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
|
||||||
|
|
||||||
int predict_nr, shift_factor, sample;
|
|
||||||
int32_t hist1=stream->adpcm_history1_32;
|
|
||||||
int32_t hist2=stream->adpcm_history2_32;
|
|
||||||
|
|
||||||
short scale;
|
|
||||||
int i;
|
|
||||||
int32_t sample_count;
|
|
||||||
int32_t predictor;
|
|
||||||
|
|
||||||
int framesin = first_sample/16;
|
|
||||||
|
|
||||||
predict_nr = read_8bit(stream->offset+framesin*9,stream->streamfile) >> 4;
|
|
||||||
shift_factor = read_8bit(stream->offset+framesin*9,stream->streamfile) & 0xf;
|
|
||||||
first_sample = first_sample % 16;
|
|
||||||
|
|
||||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
|
||||||
short sample_byte = (short)read_8bit(stream->offset+(framesin*9)+1+i/2,stream->streamfile);
|
|
||||||
|
|
||||||
sample=0;
|
|
||||||
|
|
||||||
scale = ((i&1 ?
|
|
||||||
sample_byte >> 4 :
|
|
||||||
sample_byte & 0x0f)<<12);
|
|
||||||
|
|
||||||
#if !VAG_USE_INTEGER_TABLE
|
|
||||||
predictor =
|
|
||||||
(int)((hist1*VAG_f[predict_nr][0]+hist2*VAG_f[predict_nr][1]));
|
|
||||||
#else
|
|
||||||
predictor =
|
|
||||||
(hist1*VAG_coefs[predict_nr][0]+hist2*VAG_coefs[predict_nr][1])/64;
|
|
||||||
#endif
|
|
||||||
sample=(scale >> shift_factor) + predictor;
|
|
||||||
|
|
||||||
outbuf[sample_count] = clamp16(sample);
|
|
||||||
hist2=hist1;
|
|
||||||
hist1=sample;
|
|
||||||
}
|
|
||||||
stream->adpcm_history1_32=hist1;
|
|
||||||
stream->adpcm_history2_32=hist2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void decode_baf_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
|
||||||
|
|
||||||
int predict_nr, shift_factor, sample;
|
|
||||||
int32_t hist1=stream->adpcm_history1_32;
|
|
||||||
int32_t hist2=stream->adpcm_history2_32;
|
|
||||||
|
|
||||||
short scale;
|
|
||||||
int i;
|
|
||||||
int32_t sample_count;
|
|
||||||
|
|
||||||
int framesin = first_sample/64;
|
|
||||||
|
|
||||||
predict_nr = read_8bit(stream->offset+framesin*33,stream->streamfile) >> 4;
|
|
||||||
shift_factor = read_8bit(stream->offset+framesin*33,stream->streamfile) & 0xf;
|
|
||||||
|
|
||||||
first_sample = first_sample % 64;
|
|
||||||
|
|
||||||
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
|
|
||||||
short sample_byte = (short)read_8bit(stream->offset+(framesin*33)+1+i/2,stream->streamfile);
|
|
||||||
|
|
||||||
scale = ((i&1 ?
|
|
||||||
sample_byte >> 4 :
|
|
||||||
sample_byte & 0x0f)<<12);
|
|
||||||
|
|
||||||
sample=(int)((scale >> shift_factor)+hist1*VAG_f[predict_nr][0]+hist2*VAG_f[predict_nr][1]);
|
|
||||||
|
|
||||||
outbuf[sample_count] = clamp16(sample);
|
|
||||||
hist2=hist1;
|
|
||||||
hist1=sample;
|
|
||||||
}
|
|
||||||
stream->adpcm_history1_32=hist1;
|
|
||||||
stream->adpcm_history2_32=hist2;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Sony's HEVAG (High Efficiency VAG) ADPCM, used in PSVita games (hardware decoded).
|
* Sony's HEVAG (High Efficiency VAG) ADPCM, used in PSVita games (hardware decoded).
|
||||||
|
@ -379,7 +301,7 @@ void decode_baf_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspa
|
||||||
*
|
*
|
||||||
* Original research and algorithm by id-daemon / daemon1.
|
* Original research and algorithm by id-daemon / daemon1.
|
||||||
*/
|
*/
|
||||||
void decode_hevag_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
void decode_hevag(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
||||||
|
|
||||||
uint8_t predict_nr, shift, flag, byte;
|
uint8_t predict_nr, shift, flag, byte;
|
||||||
int32_t scale = 0;
|
int32_t scale = 0;
|
||||||
|
@ -405,6 +327,10 @@ void decode_hevag_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channels
|
||||||
|
|
||||||
first_sample = first_sample % 28;
|
first_sample = first_sample % 28;
|
||||||
|
|
||||||
|
if (first_sample & 1) { /* if first sample is odd, read byte first */
|
||||||
|
byte = read_8bit(stream->offset+(framesin*16)+2+first_sample/2,stream->streamfile);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = first_sample, sample_count = 0; i < first_sample + samples_to_do; i++, sample_count += channelspacing) {
|
for (i = first_sample, sample_count = 0; i < first_sample + samples_to_do; i++, sample_count += channelspacing) {
|
||||||
sample = 0;
|
sample = 0;
|
||||||
|
|
||||||
|
@ -442,11 +368,10 @@ void decode_hevag_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channels
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Short VAG ADPCM, found in PS3 Afrika (SGDX type 5).
|
* PS ADPCM of configurable size, with no flag.
|
||||||
* Uses 8 byte blocks and no flag.
|
* Found in PS3 Afrika (SGDX type 5) in size 4, FF XI in sizes 3/5/9/41, Blur and James Bond in size 33.
|
||||||
*/
|
*/
|
||||||
void decode_short_vag_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
|
void decode_psx_configurable(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int frame_size) {
|
||||||
|
|
||||||
uint8_t predict_nr, shift, byte;
|
uint8_t predict_nr, shift, byte;
|
||||||
int16_t scale = 0;
|
int16_t scale = 0;
|
||||||
|
|
||||||
|
@ -454,37 +379,50 @@ void decode_short_vag_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int chan
|
||||||
int32_t hist1 = stream->adpcm_history1_32;
|
int32_t hist1 = stream->adpcm_history1_32;
|
||||||
int32_t hist2 = stream->adpcm_history2_32;
|
int32_t hist2 = stream->adpcm_history2_32;
|
||||||
|
|
||||||
int i, sample_count;
|
int i, sample_count, bytes_per_frame, samples_per_frame;
|
||||||
|
const int header_size = 1;
|
||||||
|
int framesin;
|
||||||
|
|
||||||
|
bytes_per_frame = frame_size - header_size;
|
||||||
|
samples_per_frame = bytes_per_frame * 2;
|
||||||
|
|
||||||
int framesin = first_sample / 6;
|
framesin = first_sample / samples_per_frame;
|
||||||
|
|
||||||
/* 2 byte header: predictor = 1st, shift = 2nd */
|
/* 1 byte header: predictor = 1st, shift = 2nd */
|
||||||
byte = (uint8_t)read_8bit(stream->offset+framesin*8+0,stream->streamfile);
|
byte = (uint8_t)read_8bit(stream->offset+framesin*frame_size+0,stream->streamfile);
|
||||||
predict_nr = byte >> 4;
|
predict_nr = byte >> 4;
|
||||||
shift = byte & 0x0f;
|
shift = byte & 0x0f;
|
||||||
|
|
||||||
first_sample = first_sample % 6;
|
first_sample = first_sample % samples_per_frame;
|
||||||
|
|
||||||
|
if (first_sample & 1) { /* if restarting on a high nibble, read byte first */
|
||||||
|
byte = (uint8_t)read_8bit(stream->offset+(framesin*frame_size)+header_size+first_sample/2,stream->streamfile);
|
||||||
|
}
|
||||||
|
|
||||||
for (i = first_sample, sample_count = 0; i < first_sample + samples_to_do; i++, sample_count += channelspacing) {
|
for (i = first_sample, sample_count = 0; i < first_sample + samples_to_do; i++, sample_count += channelspacing) {
|
||||||
sample = 0;
|
sample = 0;
|
||||||
|
|
||||||
if (predict_nr < 5) {
|
if (predict_nr < 5) {
|
||||||
|
if (!(i&1)) { /* low nibble first */
|
||||||
if (i & 1) {/* odd/even nibble */
|
byte = (uint8_t)read_8bit(stream->offset+(framesin*frame_size)+header_size+i/2,stream->streamfile);
|
||||||
scale = byte >> 4;
|
|
||||||
} else {
|
|
||||||
byte = (uint8_t)read_8bit(stream->offset+(framesin*8)+1+i/2,stream->streamfile);
|
|
||||||
scale = (byte & 0x0f);
|
scale = (byte & 0x0f);
|
||||||
|
} else { /* high nibble last */
|
||||||
|
scale = byte >> 4;
|
||||||
}
|
}
|
||||||
|
scale = scale << 12; /* shift + sign extend (only if scale is int16_t) */
|
||||||
/*if (scale > 7) {
|
/*if (scale > 7) {
|
||||||
scale = scale - 16;
|
scale = scale - 16;
|
||||||
}*/
|
}*/
|
||||||
scale = scale << 12; /* shift + sign extend only if scale is int16_t */
|
#if VAG_USE_INTEGER_TABLE
|
||||||
|
sample = (scale >> shift) +
|
||||||
sample = (hist1 * VAG_coefs[predict_nr][0] +
|
(hist1 * VAG_coefs[predict_nr][0] +
|
||||||
hist2 * VAG_coefs[predict_nr][1] ) / 64;
|
hist2 * VAG_coefs[predict_nr][1] ) / 64;
|
||||||
sample = sample + (scale >> shift);
|
sample = sample + ;
|
||||||
|
#else
|
||||||
|
sample = (int)( (scale >> shift) +
|
||||||
|
(hist1 * VAG_f[predict_nr][0] +
|
||||||
|
hist2 * VAG_f[predict_nr][1]) );
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
outbuf[sample_count] = clamp16(sample);
|
outbuf[sample_count] = clamp16(sample);
|
||||||
|
|
|
@ -0,0 +1,871 @@
|
||||||
|
#include "formats.h"
|
||||||
|
|
||||||
|
//#define VGM_REGISTER_TYPE(extension) ...
|
||||||
|
//#define VGM_REGISTER_TYPE_COMMON(extension) ... /* for common extensions like aiff */
|
||||||
|
|
||||||
|
|
||||||
|
/* some extensions could be #ifdef but no really needed */
|
||||||
|
/* some formats marked as "not parsed" mean they'll go through FFmpeg, the header/extension is not parsed */
|
||||||
|
|
||||||
|
static const char* extension_list[] = {
|
||||||
|
"2dx9",
|
||||||
|
"2pfs",
|
||||||
|
|
||||||
|
"aa3", //FFmpeg, not parsed (ATRAC3/ATRAC3PLUS/MP3/LPCM/WMA)
|
||||||
|
"aaap",
|
||||||
|
"aax",
|
||||||
|
//"ac3", //FFmpeg, not parsed //common?
|
||||||
|
"acm",
|
||||||
|
"adm",
|
||||||
|
"adp",
|
||||||
|
"adpcm",
|
||||||
|
"ads",
|
||||||
|
"adx",
|
||||||
|
"afc",
|
||||||
|
"agsc",
|
||||||
|
"ahx",
|
||||||
|
"aifc",
|
||||||
|
"aifcl",
|
||||||
|
//"aiff", //common
|
||||||
|
"aix",
|
||||||
|
"akb", //AAC
|
||||||
|
"amts",
|
||||||
|
"as4",
|
||||||
|
"asd",
|
||||||
|
"asf",
|
||||||
|
"asr",
|
||||||
|
"ass",
|
||||||
|
"ast",
|
||||||
|
"at3",
|
||||||
|
"aud",
|
||||||
|
"aus",
|
||||||
|
|
||||||
|
"b1s",
|
||||||
|
"baf",
|
||||||
|
"baka",
|
||||||
|
"bar",
|
||||||
|
"bcstm",
|
||||||
|
"bcwav",
|
||||||
|
"bdsp",
|
||||||
|
"bfstm",
|
||||||
|
"bfwav",
|
||||||
|
"bfwavnsmbu",
|
||||||
|
"bg00",
|
||||||
|
"bgw",
|
||||||
|
"bh2pcm",
|
||||||
|
"bmdx",
|
||||||
|
"bms",
|
||||||
|
"bnk",
|
||||||
|
"bns",
|
||||||
|
"bnsf",
|
||||||
|
"bo2",
|
||||||
|
"brstm",
|
||||||
|
"brstmspm",
|
||||||
|
"btsnd",
|
||||||
|
"bvg",
|
||||||
|
|
||||||
|
"caf",
|
||||||
|
"capdsp",
|
||||||
|
"cbd2",
|
||||||
|
"ccc",
|
||||||
|
"cfn",
|
||||||
|
"ckd",
|
||||||
|
"cnk",
|
||||||
|
"cps",
|
||||||
|
"cxs",
|
||||||
|
|
||||||
|
"dcs",
|
||||||
|
"ddsp",
|
||||||
|
"de2",
|
||||||
|
"dmsg",
|
||||||
|
"dsp",
|
||||||
|
"dspw",
|
||||||
|
"dtk",
|
||||||
|
"dvi",
|
||||||
|
"dxh",
|
||||||
|
|
||||||
|
"eam",
|
||||||
|
"emff",
|
||||||
|
"enth",
|
||||||
|
|
||||||
|
"fag",
|
||||||
|
"ffw",
|
||||||
|
"filp",
|
||||||
|
"fsb",
|
||||||
|
"fwav",
|
||||||
|
|
||||||
|
"g1l",
|
||||||
|
"gbts",
|
||||||
|
"gca",
|
||||||
|
"gcm",
|
||||||
|
"gcub",
|
||||||
|
"gcw",
|
||||||
|
"genh",
|
||||||
|
"gms",
|
||||||
|
"gsb",
|
||||||
|
|
||||||
|
"hca",
|
||||||
|
"hgc1",
|
||||||
|
"his",
|
||||||
|
"hlwav",
|
||||||
|
"hps",
|
||||||
|
"hsf",
|
||||||
|
"hwas",
|
||||||
|
|
||||||
|
"iab",
|
||||||
|
"iadp",
|
||||||
|
"idsp",
|
||||||
|
"idvi",
|
||||||
|
"ikm",
|
||||||
|
"ild",
|
||||||
|
"int",
|
||||||
|
"isd",
|
||||||
|
"isws",
|
||||||
|
"ivaud",
|
||||||
|
"ivag",
|
||||||
|
"ivb",
|
||||||
|
|
||||||
|
"joe",
|
||||||
|
"jstm",
|
||||||
|
|
||||||
|
"kces",
|
||||||
|
"kcey",
|
||||||
|
"khv",
|
||||||
|
"kovs",
|
||||||
|
"kraw",
|
||||||
|
|
||||||
|
"leg",
|
||||||
|
"logg",
|
||||||
|
"lpcm",
|
||||||
|
"lps",
|
||||||
|
"lsf",
|
||||||
|
"lwav",
|
||||||
|
|
||||||
|
"matx",
|
||||||
|
"mca",
|
||||||
|
"mcg",
|
||||||
|
"mi4",
|
||||||
|
"mib",
|
||||||
|
"mic",
|
||||||
|
"mihb",
|
||||||
|
"mnstr",
|
||||||
|
"mpdsp",
|
||||||
|
"mpds",
|
||||||
|
"msa",
|
||||||
|
"msf",
|
||||||
|
"mss",
|
||||||
|
"msvp",
|
||||||
|
"mtaf",
|
||||||
|
"mus",
|
||||||
|
"musc",
|
||||||
|
"musx",
|
||||||
|
"mwv",
|
||||||
|
"mxst",
|
||||||
|
"myspd",
|
||||||
|
|
||||||
|
"ndp",
|
||||||
|
"ngca",
|
||||||
|
"nps",
|
||||||
|
"npsf",
|
||||||
|
"nus3bank", //todo not existing?
|
||||||
|
"nwa",
|
||||||
|
|
||||||
|
"oma", //FFmpeg, not parsed (ATRAC3/ATRAC3PLUS/MP3/LPCM/WMA)
|
||||||
|
"omu",
|
||||||
|
"otm",
|
||||||
|
|
||||||
|
"p2bt",
|
||||||
|
"p3d",
|
||||||
|
"past",
|
||||||
|
"pcm",
|
||||||
|
"pdt",
|
||||||
|
"pnb",
|
||||||
|
"pona",
|
||||||
|
"pos",
|
||||||
|
"ps2stm",
|
||||||
|
"psh",
|
||||||
|
"psnd",
|
||||||
|
"psw",
|
||||||
|
|
||||||
|
"ras",
|
||||||
|
"raw",
|
||||||
|
"rkv",
|
||||||
|
"rnd",
|
||||||
|
"rrds",
|
||||||
|
"rsd",
|
||||||
|
"rsf",
|
||||||
|
"rstm",
|
||||||
|
"rvws",
|
||||||
|
"rwar",
|
||||||
|
"rwav",
|
||||||
|
"rws",
|
||||||
|
"rwsd",
|
||||||
|
"rwx",
|
||||||
|
"rxw",
|
||||||
|
|
||||||
|
"s14",
|
||||||
|
"sab",
|
||||||
|
"sad",
|
||||||
|
"sap",
|
||||||
|
"sc",
|
||||||
|
"scd",
|
||||||
|
"sck",
|
||||||
|
"sd9",
|
||||||
|
"sdt",
|
||||||
|
"seg",
|
||||||
|
"sf0",
|
||||||
|
"sfl",
|
||||||
|
"sfs",
|
||||||
|
"sfx",
|
||||||
|
"sgb",
|
||||||
|
"sgd",
|
||||||
|
"sgx",
|
||||||
|
"sl3",
|
||||||
|
"sli",
|
||||||
|
"smp",
|
||||||
|
"smpl",
|
||||||
|
"snd",
|
||||||
|
"snds",
|
||||||
|
"sng",
|
||||||
|
"sns",
|
||||||
|
"spd",
|
||||||
|
"spm",
|
||||||
|
"sps",
|
||||||
|
"spsd",
|
||||||
|
"spw",
|
||||||
|
"ss2",
|
||||||
|
"ss3",
|
||||||
|
"ss7",
|
||||||
|
"ssm",
|
||||||
|
"sss",
|
||||||
|
"ster",
|
||||||
|
"sth",
|
||||||
|
//"stm", //common
|
||||||
|
"stma",
|
||||||
|
"str",
|
||||||
|
"strm",
|
||||||
|
"sts",
|
||||||
|
"stx",
|
||||||
|
"svag",
|
||||||
|
"svs",
|
||||||
|
"swag",
|
||||||
|
"swav",
|
||||||
|
"swd",
|
||||||
|
|
||||||
|
"tec",
|
||||||
|
"thp",
|
||||||
|
"tk1",
|
||||||
|
"tk5",
|
||||||
|
"tra",
|
||||||
|
"tun",
|
||||||
|
"tydsp",
|
||||||
|
|
||||||
|
"um3",
|
||||||
|
|
||||||
|
"vag",
|
||||||
|
"vas",
|
||||||
|
"vawx",
|
||||||
|
"vb",
|
||||||
|
"vbk",
|
||||||
|
"vgs",
|
||||||
|
"vgv",
|
||||||
|
"vig",
|
||||||
|
|
||||||
|
"vds",
|
||||||
|
"vdm",
|
||||||
|
"vms",
|
||||||
|
"vms",
|
||||||
|
"voi",
|
||||||
|
"vpk",
|
||||||
|
"vs",
|
||||||
|
"vsf",
|
||||||
|
|
||||||
|
"waa",
|
||||||
|
"wac",
|
||||||
|
"wad",
|
||||||
|
"wam",
|
||||||
|
"was",
|
||||||
|
"wavm",
|
||||||
|
"wb",
|
||||||
|
"wii",
|
||||||
|
"wmus",
|
||||||
|
"wp2",
|
||||||
|
"wpd",
|
||||||
|
"wsd",
|
||||||
|
"wsi",
|
||||||
|
"wvs",
|
||||||
|
|
||||||
|
"xa",
|
||||||
|
"xa2",
|
||||||
|
"xa30",
|
||||||
|
"xag",
|
||||||
|
"xau",
|
||||||
|
"xma",
|
||||||
|
"xma2",
|
||||||
|
"xmu",
|
||||||
|
"xnb",
|
||||||
|
"xsf",
|
||||||
|
"xss",
|
||||||
|
"xvag",
|
||||||
|
"xvas",
|
||||||
|
"xwav",
|
||||||
|
"xwb",
|
||||||
|
"xwm", //FFmpeg, not parsed (XWMA)
|
||||||
|
"xwma", //FFmpeg, not parsed (XWMA)
|
||||||
|
"xwv",
|
||||||
|
|
||||||
|
"ydsp",
|
||||||
|
"ymf",
|
||||||
|
|
||||||
|
"zsd",
|
||||||
|
"zwdsp",
|
||||||
|
|
||||||
|
"vgmstream"
|
||||||
|
|
||||||
|
//, NULL //end mark
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* List of supported formats.
|
||||||
|
*
|
||||||
|
* For plugins that need to know (test.exe doesn't use it)
|
||||||
|
*/
|
||||||
|
const char ** vgmstream_get_formats() {
|
||||||
|
return extension_list;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Number of elements in the list.
|
||||||
|
*/
|
||||||
|
int vgmstream_get_formats_length() {
|
||||||
|
return sizeof(extension_list) / sizeof(char*);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* internal description info */
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
coding_t type;
|
||||||
|
const char *description;
|
||||||
|
} coding_info;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
layout_t type;
|
||||||
|
const char *description;
|
||||||
|
} layout_info;
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
meta_t type;
|
||||||
|
const char *description;
|
||||||
|
} meta_info;
|
||||||
|
|
||||||
|
|
||||||
|
static const coding_info coding_info_list[] = {
|
||||||
|
{coding_PCM16BE, "Big Endian 16-bit PCM"},
|
||||||
|
{coding_PCM16LE, "Little Endian 16-bit PCM"},
|
||||||
|
{coding_PCM16LE_int, "Little Endian 16-bit PCM with 2 byte interleave"},
|
||||||
|
{coding_PCM16LE_XOR_int, "Little Endian 16-bit PCM with 2 byte interleave and XOR obfuscation"},
|
||||||
|
{coding_PCM8, "8-bit PCM"},
|
||||||
|
{coding_PCM8_U, "8-bit unsigned PCM"},
|
||||||
|
{coding_PCM8_U_int, "8-bit unsigned PCM with 1 byte interleave"},
|
||||||
|
{coding_PCM8_int, "8-bit PCM with 1 byte interleave"},
|
||||||
|
{coding_PCM8_SB_int, "8-bit PCM with sign bit, 1 byte interleave"},
|
||||||
|
{coding_CRI_ADX, "CRI ADX 4-bit ADPCM"},
|
||||||
|
{coding_CRI_ADX_enc_8, "CRI ADX 4-bit ADPCM (type 8 encryption)"},
|
||||||
|
{coding_CRI_ADX_enc_9, "CRI ADX 4-bit ADPCM (type 8 encryption)"},
|
||||||
|
{coding_NGC_DSP, "Nintendo DSP 4-bit ADPCM"},
|
||||||
|
{coding_NGC_DTK, "Nintendo DTK 4-bit ADPCM"},
|
||||||
|
{coding_NGC_AFC, "Nintendo AFC 4-bit ADPCM"},
|
||||||
|
{coding_CRI_HCA, "CRI HCA"},
|
||||||
|
{coding_NDS_IMA, "NDS-style 4-bit IMA ADPCM"},
|
||||||
|
{coding_DAT4_IMA, "Eurocom DAT4 4-bit IMA ADPCM"},
|
||||||
|
{coding_G721, "CCITT G.721 4-bit ADPCM"},
|
||||||
|
{coding_PSX, "Playstation 4-bit ADPCM"},
|
||||||
|
{coding_PSX_badflags, "Playstation 4-bit ADPCM (bad flags)"},
|
||||||
|
{coding_PSX_bmdx, "Playstation 4-bit ADPCM (BMDX encryption)"},
|
||||||
|
{coding_PSX_cfg, "Playstation 4-bit ADPCM (configurable)"},
|
||||||
|
{coding_HEVAG, "Playstation Vita HEVAG 4-bit ADPCM"},
|
||||||
|
{coding_XA, "CD-ROM XA 4-bit ADPCM"},
|
||||||
|
{coding_XBOX, "XBOX 4-bit IMA ADPCM"},
|
||||||
|
{coding_INT_XBOX, "XBOX 4-bit IMA ADPCM (interleaved)"},
|
||||||
|
{coding_EA_XA, "Electronic Arts 4-bit ADPCM (XA based)"},
|
||||||
|
{coding_EA_ADPCM, "Electronic Arts R1 4-bit ADPCM (XA based)"},
|
||||||
|
{coding_SDX2, "Squareroot-delta-exact (SDX2) 8-bit DPCM"},
|
||||||
|
{coding_SDX2_int, "Squareroot-delta-exact (SDX2) 8-bit DPCM with 1 byte interleave"},
|
||||||
|
{coding_CBD2, "Cuberoot-delta-exact (CBD2) 8-bit DPCM"},
|
||||||
|
{coding_CBD2_int, "Cuberoot-delta-exact (CBD2) 8-bit DPCM with 1 byte interleave"},
|
||||||
|
{coding_DVI_IMA, "Intel DVI 4-bit IMA ADPCM"},
|
||||||
|
{coding_INT_DVI_IMA, "Interleaved Intel DVI 4-bit IMA ADPCM"},
|
||||||
|
{coding_EACS_IMA, "EACS 4-bit IMA ADPCM"},
|
||||||
|
{coding_MAXIS_ADPCM, "Maxis XA (EA ADPCM Variant)"},
|
||||||
|
{coding_INT_IMA, "Interleaved 4-bit IMA ADPCM"},
|
||||||
|
{coding_IMA, "4-bit IMA ADPCM"},
|
||||||
|
{coding_MS_IMA, "Microsoft 4-bit IMA ADPCM"},
|
||||||
|
{coding_RAD_IMA, "'Radical' 4-bit IMA ADPCM"},
|
||||||
|
{coding_RAD_IMA_mono, "'Radical' 4-bit IMA ADPCM (mono)"},
|
||||||
|
{coding_APPLE_IMA4, "Apple Quicktime 4-bit IMA ADPCM"},
|
||||||
|
{coding_SNDS_IMA, "Heavy Iron .snds 4-bit IMA ADPCM"},
|
||||||
|
{coding_WS, "Westwood Studios ADPCM"},
|
||||||
|
{coding_ACM, "InterPlay ACM"},
|
||||||
|
{coding_NWA0, "NWA DPCM Level 0"},
|
||||||
|
{coding_NWA1, "NWA DPCM Level 1"},
|
||||||
|
{coding_NWA2, "NWA DPCM Level 2"},
|
||||||
|
{coding_NWA3, "NWA DPCM Level 3"},
|
||||||
|
{coding_NWA4, "NWA DPCM Level 4"},
|
||||||
|
{coding_NWA5, "NWA DPCM Level 5"},
|
||||||
|
{coding_MSADPCM, "Microsoft 4-bit ADPCM"},
|
||||||
|
{coding_AICA, "Yamaha AICA 4-bit ADPCM"},
|
||||||
|
{coding_NDS_PROCYON, "Procyon Studio Digital Sound Elements NDS 4-bit APDCM"},
|
||||||
|
{coding_L5_555, "Level-5 0x555 4-bit ADPCM"},
|
||||||
|
{coding_SASSC, "Activision / EXAKT SASSC 8-bit DPCM"},
|
||||||
|
{coding_LSF, "lsf 4-bit ADPCM"},
|
||||||
|
{coding_MTAF, "Konami MTAF 4-bit ADPCM"},
|
||||||
|
#ifdef VGM_USE_VORBIS
|
||||||
|
{coding_ogg_vorbis, "Vorbis"},
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_MPEG
|
||||||
|
{coding_fake_MPEG2_L2, "MPEG-2 Layer II Audio"},
|
||||||
|
{coding_MPEG1_L1, "MPEG-1 Layer I Audio"},
|
||||||
|
{coding_MPEG1_L2, "MPEG-1 Layer II Audio"},
|
||||||
|
{coding_MPEG1_L3, "MPEG-1 Layer III Audio (MP3)"},
|
||||||
|
{coding_MPEG2_L1, "MPEG-2 Layer I Audio"},
|
||||||
|
{coding_MPEG2_L2, "MPEG-2 Layer II Audio"},
|
||||||
|
{coding_MPEG2_L3, "MPEG-2 Layer III Audio (MP3)"},
|
||||||
|
{coding_MPEG25_L1, "MPEG-2.5 Layer I Audio"},
|
||||||
|
{coding_MPEG25_L2, "MPEG-2.5 Layer II Audio"},
|
||||||
|
{coding_MPEG25_L3, "MPEG-2.5 Layer III Audio (MP3)"},
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_G7221
|
||||||
|
{coding_G7221, "ITU G.722.1 (Polycom Siren 7)"},
|
||||||
|
{coding_G7221C, "ITU G.722.1 annex C (Polycom Siren 14)"},
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_G719
|
||||||
|
{coding_G719, "ITU G.719 annex B (Polycom Siren 22)"},
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
||||||
|
{coding_AT3plus, "ATRAC3plus"},
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
{coding_FFmpeg, "FFmpeg"},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const layout_info layout_info_list[] = {
|
||||||
|
{layout_none, "flat (no layout)"},
|
||||||
|
{layout_interleave, "interleave"},
|
||||||
|
{layout_interleave_shortblock, "interleave with short last block"},
|
||||||
|
{layout_interleave_byte, "sub-frame interleave"},
|
||||||
|
{layout_mxch_blocked, "MxCh blocked"},
|
||||||
|
{layout_ast_blocked, "AST blocked"},
|
||||||
|
{layout_halpst_blocked, "HALPST blocked"},
|
||||||
|
{layout_xa_blocked, "CD-ROM XA"},
|
||||||
|
{layout_ea_blocked, "Electronic Arts Audio Blocks"},
|
||||||
|
{layout_eacs_blocked, "Electronic Arts (Old Version) Audio Blocks"},
|
||||||
|
{layout_caf_blocked, "CAF blocked"},
|
||||||
|
{layout_wsi_blocked, ".wsi blocked"},
|
||||||
|
{layout_xvas_blocked, ".xvas blocked"},
|
||||||
|
{layout_str_snds_blocked, ".str SNDS blocked"},
|
||||||
|
{layout_ws_aud_blocked, "Westwood Studios .aud blocked"},
|
||||||
|
{layout_matx_blocked, "Matrix .matx blocked"},
|
||||||
|
{layout_de2_blocked, "de2 blocked"},
|
||||||
|
{layout_vs_blocked, "vs blocked"},
|
||||||
|
{layout_emff_ps2_blocked, "EMFF (PS2) blocked"},
|
||||||
|
{layout_emff_ngc_blocked, "EMFF (NGC/WII) blocked"},
|
||||||
|
{layout_gsb_blocked, "GSB blocked"},
|
||||||
|
{layout_thp_blocked, "THP Movie Audio blocked"},
|
||||||
|
{layout_filp_blocked, "FILp blocked"},
|
||||||
|
{layout_psx_mgav_blocked, "MGAV blocked"},
|
||||||
|
{layout_ps2_adm_blocked, "ADM blocked"},
|
||||||
|
{layout_dsp_bdsp_blocked, "DSP blocked"},
|
||||||
|
{layout_ivaud_blocked, "GTA IV blocked"},
|
||||||
|
{layout_ps2_iab_blocked, "IAB blocked"},
|
||||||
|
{layout_ps2_strlr_blocked, "The Bouncer STR blocked"},
|
||||||
|
{layout_tra_blocked, "TRA blocked"},
|
||||||
|
{layout_acm, "ACM blocked"},
|
||||||
|
{layout_mus_acm, "multiple ACM files, ACM blocked"},
|
||||||
|
{layout_aix, "AIX interleave, internally 18-byte interleaved"},
|
||||||
|
{layout_aax, "AAX blocked, 18-byte interleaved"},
|
||||||
|
{layout_scd_int, "SCD multistream interleave"},
|
||||||
|
#ifdef VGM_USE_VORBIS
|
||||||
|
{layout_ogg_vorbis, "Ogg"},
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_MPEG
|
||||||
|
{layout_fake_mpeg, "MPEG Audio stream with incorrect frame headers"},
|
||||||
|
{layout_mpeg, "MPEG Audio stream"},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
static const meta_info meta_info_list[] = {
|
||||||
|
{meta_RSTM, "Nintendo RSTM header"},
|
||||||
|
{meta_STRM, "Nintendo STRM header"},
|
||||||
|
{meta_ADX_03, "CRI ADX header type 03"},
|
||||||
|
{meta_ADX_04, "CRI ADX header type 04"},
|
||||||
|
{meta_ADX_05, "CRI ADX header type 05"},
|
||||||
|
{meta_AIX, "CRI AIX header"},
|
||||||
|
{meta_AAX, "CRI AAX header"},
|
||||||
|
{meta_UTF_DSP, "CRI ADPCM_WII header"},
|
||||||
|
{meta_DSP_AGSC, "Retro Studios AGSC header"},
|
||||||
|
{meta_DSP_CSMP, "Retro Studios CSMP header"},
|
||||||
|
{meta_NGC_ADPDTK, "assumed Nintendo ADP by .adp extension and valid first frame"},
|
||||||
|
{meta_RSF, "assumed Retro Studios RSF by .rsf extension and valid first bytes"},
|
||||||
|
{meta_AFC, "Nintendo AFC header"},
|
||||||
|
{meta_AST, "Nintendo AST header"},
|
||||||
|
{meta_HALPST, "HAL Laboratory HALPST header"},
|
||||||
|
{meta_DSP_RS03, "Retro Studios RS03 header"},
|
||||||
|
{meta_DSP_STD, "Standard Nintendo DSP header"},
|
||||||
|
{meta_DSP_CSTR, "Namco Cstr header"},
|
||||||
|
{meta_GCSW, "GCSW header"},
|
||||||
|
{meta_PS2_SShd, "SShd header"},
|
||||||
|
{meta_PS2_NPSF, "Namco Production Sound File (NPSF) header"},
|
||||||
|
{meta_RWSD, "Nintendo RWSD header (single stream)"},
|
||||||
|
{meta_RWAR, "Nintendo RWAR header (single RWAV stream)"},
|
||||||
|
{meta_RWAV, "Nintendo RWAV header"},
|
||||||
|
{meta_CWAV, "Nintendo CWAV header"},
|
||||||
|
{meta_FWAV, "Nintendo FWAV header"},
|
||||||
|
{meta_PSX_XA, "RIFF/CDXA header"},
|
||||||
|
{meta_PS2_RXW, "RXWS header)"},
|
||||||
|
{meta_PS2_RAW, "assumed RAW Interleaved PCM by .int extension"},
|
||||||
|
{meta_PS2_OMU, "Alter Echo OMU Header"},
|
||||||
|
{meta_DSP_STM, "Nintendo STM header"},
|
||||||
|
{meta_PS2_EXST, "EXST header"},
|
||||||
|
{meta_PS2_SVAG, "Konami SVAG header"},
|
||||||
|
{meta_PS2_MIB, "assumed MIB Interleaved file by .mib extension"},
|
||||||
|
{meta_PS2_MIB_MIH, "assumed MIB with MIH Info Header file by .mib+.mih extension"},
|
||||||
|
{meta_DSP_MPDSP, "Single DSP header stereo by .mpdsp extension"},
|
||||||
|
{meta_PS2_MIC, "assume KOEI MIC file by .mic extension"},
|
||||||
|
{meta_DSP_JETTERS, "Double DSP header stereo by _lr.dsp extension"},
|
||||||
|
{meta_DSP_MSS, "Double DSP header stereo by .mss extension"},
|
||||||
|
{meta_DSP_GCM, "Double DSP header stereo by .gcm extension"},
|
||||||
|
{meta_DSP_WII_IDSP, "Wii IDSP Double DSP header"},
|
||||||
|
{meta_RSTM_SPM, "Nintendo RSTM header and .brstmspm extension"},
|
||||||
|
{meta_RAW, "assumed RAW PCM file by .raw extension"},
|
||||||
|
{meta_PS2_VAGi, "Sony VAG Interleaved header (VAGi)"},
|
||||||
|
{meta_PS2_VAGp, "Sony VAG Mono header (VAGp)"},
|
||||||
|
{meta_PS2_VAGs, "Sony VAG Stereo header (VAGp)"},
|
||||||
|
{meta_PS2_VAGm, "Sony VAG Mono header (VAGm)"},
|
||||||
|
{meta_PS2_pGAV, "Sony VAG Stereo Little Endian header (pGAV)"},
|
||||||
|
{meta_PSX_GMS, "assumed Grandia GMS file by .gms extension"},
|
||||||
|
{meta_PS2_STR, "assumed STR + STH File by .str & .sth extension"},
|
||||||
|
{meta_PS2_ILD, "ILD header"},
|
||||||
|
{meta_PS2_PNB, "assumed PNB (PsychoNauts Bgm File) by .pnb extension"},
|
||||||
|
{meta_XBOX_WAVM, "assumed Xbox WAVM file by .wavm extension"},
|
||||||
|
{meta_XBOX_RIFF, "Xbox RIFF/WAVE file with 0x0069 Codec ID"},
|
||||||
|
{meta_DSP_STR, "assumed Conan Gamecube STR File by .str extension"},
|
||||||
|
{meta_EAXA_R2, "Electronic Arts XA R2"},
|
||||||
|
{meta_EAXA_R3, "Electronic Arts XA R3"},
|
||||||
|
{meta_EA_ADPCM, "Electronic Arts XA R1"},
|
||||||
|
{meta_EA_IMA, "Electronic Arts container with IMA blocks"},
|
||||||
|
{meta_EAXA_PSX, "Electronic Arts With PSX ADPCM"},
|
||||||
|
{meta_EA_PCM, "Electronic Arts With PCM"},
|
||||||
|
{meta_CFN, "Namco CAF Header"},
|
||||||
|
{meta_PS2_VPK, "VPK Header"},
|
||||||
|
{meta_GENH, "GENH Generic Header"},
|
||||||
|
{meta_DSP_SADB, "sadb header"},
|
||||||
|
{meta_SADL, "sadl header"},
|
||||||
|
{meta_PS2_BMDX, "Beatmania .bmdx header"},
|
||||||
|
{meta_DSP_WSI, ".wsi header"},
|
||||||
|
{meta_AIFC, "Audio Interchange File Format AIFF-C"},
|
||||||
|
{meta_AIFF, "Audio Interchange File Format"},
|
||||||
|
{meta_STR_SNDS, ".str SNDS SHDR chunk"},
|
||||||
|
{meta_WS_AUD, "Westwood Studios .aud header"},
|
||||||
|
{meta_WS_AUD_old, "Westwood Studios .aud (old) header"},
|
||||||
|
{meta_PS2_IVB, "IVB/BVII header"},
|
||||||
|
{meta_PS2_SVS, "Square SVS header"},
|
||||||
|
{meta_RIFF_WAVE, "RIFF WAVE header"},
|
||||||
|
{meta_RIFF_WAVE_POS, "RIFF WAVE header and .pos for looping"},
|
||||||
|
{meta_NWA, "Visual Art's NWA header"},
|
||||||
|
{meta_NWA_NWAINFOINI, "Visual Art's NWA header and NWAINFO.INI for looping"},
|
||||||
|
{meta_NWA_GAMEEXEINI, "Visual Art's NWA header and Gameexe.ini for looping"},
|
||||||
|
{meta_XSS, "Dino Crisis 3 XSS File"},
|
||||||
|
{meta_HGC1, "Knights of the Temple 2 hgC1 Header"},
|
||||||
|
{meta_AUS, "Capcom AUS Header"},
|
||||||
|
{meta_RWS, "RWS Header"},
|
||||||
|
{meta_EACS_PC, "EACS Header (PC)"},
|
||||||
|
{meta_EACS_PSX, "EACS Header (PSX)"},
|
||||||
|
{meta_EACS_SAT, "EACS Header (SATURN)"},
|
||||||
|
{meta_SL3, "SL3 Header"},
|
||||||
|
{meta_FSB1, "FMOD Sample Bank (FSB1) Header"},
|
||||||
|
{meta_FSB2, "FMOD Sample Bank (FSB2) Header"},
|
||||||
|
{meta_FSB3, "FMOD Sample Bank (FSB3) Header"},
|
||||||
|
{meta_FSB4, "FMOD Sample Bank (FSB4) Header"},
|
||||||
|
{meta_FSB5, "FMOD Sample Bank (FSB5) Header"},
|
||||||
|
{meta_RWX, "RWX Header"},
|
||||||
|
{meta_XWB, "XWB WBND Header"},
|
||||||
|
{meta_XA30, "XA30 Header"},
|
||||||
|
{meta_MUSC, "MUSC Header"},
|
||||||
|
{meta_MUSX_V004, "MUSX / Version 004 Header"},
|
||||||
|
{meta_MUSX_V005, "MUSX / Version 005 Header"},
|
||||||
|
{meta_MUSX_V006, "MUSX / Version 006 Header"},
|
||||||
|
{meta_MUSX_V010, "MUSX / Version 010 Header"},
|
||||||
|
{meta_MUSX_V201, "MUSX / Version 201 Header"},
|
||||||
|
{meta_LEG, "Legaia 2 - Duel Saga LEG Header"},
|
||||||
|
{meta_FILP, "Bio Hazard - Gun Survivor FILp Header"},
|
||||||
|
{meta_IKM, "Zwei!! IKM Header"},
|
||||||
|
{meta_SFS, "Baroque SFS Header"},
|
||||||
|
{meta_DVI, "DVI Header"},
|
||||||
|
{meta_KCEY, "KCEYCOMP Header"},
|
||||||
|
{meta_BG00, "Falcom BG00 Header"},
|
||||||
|
{meta_PS2_RSTM, "Rockstar Games RSTM Header"},
|
||||||
|
{meta_ACM, "InterPlay ACM Header"},
|
||||||
|
{meta_MUS_ACM, "MUS playlist and multiple InterPlay ACM Headered files"},
|
||||||
|
{meta_PS2_KCES, "Konami KCES Header"},
|
||||||
|
{meta_PS2_DXH, "Tokobot Plus DXH Header"},
|
||||||
|
{meta_PS2_PSH, "Dawn of Mana - Seiken Densetsu 4 PSH Header"},
|
||||||
|
{meta_RIFF_WAVE_labl, "RIFF WAVE header with loop markers"},
|
||||||
|
{meta_RIFF_WAVE_smpl, "RIFF WAVE header with sample looping info"},
|
||||||
|
{meta_RIFX_WAVE, "RIFX WAVE header"},
|
||||||
|
{meta_RIFX_WAVE_smpl, "RIFX WAVE header with sample looping info"},
|
||||||
|
{meta_XNBm, "XNBm header"},
|
||||||
|
{meta_PCM_SCD, "PCM file with custom header (SCD)"},
|
||||||
|
{meta_PCM_PS2, "PCM file with custom header (PS2)"},
|
||||||
|
{meta_PS2_RKV, "Legacy of Kain - Blood Omen 2 RKV Header"},
|
||||||
|
{meta_PS2_PSW, "Rayman Raving Rabbids Riff Container File"},
|
||||||
|
{meta_PS2_VAS, "Pro Baseball Spirits 5 VAS Header"},
|
||||||
|
{meta_PS2_TEC, "assumed TECMO badflagged stream by .tec extension"},
|
||||||
|
{meta_XBOX_WVS, "Metal Arms WVS Header (XBOX)"},
|
||||||
|
{meta_NGC_WVS, "Metal Arms WVS Header (GameCube)"},
|
||||||
|
{meta_XBOX_STMA, "Midnight Club 2 STMA Header"},
|
||||||
|
{meta_XBOX_MATX, "assumed Matrix file by .matx extension"},
|
||||||
|
{meta_DE2, "gurumin .de2 with embedded funky RIFF"},
|
||||||
|
{meta_VS, "Men in Black VS Header"},
|
||||||
|
{meta_DC_STR, "Sega Stream Asset Builder header"},
|
||||||
|
{meta_DC_STR_V2, "variant of Sega Stream Asset Builder header"},
|
||||||
|
{meta_XBOX_XMU, "XMU header"},
|
||||||
|
{meta_XBOX_XVAS, "assumed TMNT file by .xvas extension"},
|
||||||
|
{meta_PS2_XA2, "Acclaim XA2 Header"},
|
||||||
|
{meta_DC_IDVI, "IDVI Header"},
|
||||||
|
{meta_NGC_YMF, "YMF DSP Header"},
|
||||||
|
{meta_PS2_CCC, "CCC Header"},
|
||||||
|
{meta_PSX_FAG, "FAG Header"},
|
||||||
|
{meta_PS2_MIHB, "Merged MIH+MIB"},
|
||||||
|
{meta_DSP_WII_MUS, "mus header"},
|
||||||
|
{meta_WII_SNG, "SNG DSP Header"},
|
||||||
|
{meta_RSD2VAG, "RSD2/VAG Header"},
|
||||||
|
{meta_RSD2PCMB, "RSD2/PCMB Header"},
|
||||||
|
{meta_RSD2XADP, "RSD2/XADP Header"},
|
||||||
|
{meta_RSD3VAG, "RSD3/VAG Header"},
|
||||||
|
{meta_RSD3GADP, "RSD3/GADP Header"},
|
||||||
|
{meta_RSD3PCM, "RSD3/PCM Header"},
|
||||||
|
{meta_RSD3PCMB, "RSD3/PCMB Header"},
|
||||||
|
{meta_RSD4PCMB, "RSD4/PCMB Header"},
|
||||||
|
{meta_RSD4PCM, "RSD4/PCM Header"},
|
||||||
|
{meta_RSD4RADP, "RSD4/RADP Header"},
|
||||||
|
{meta_RSD4VAG, "RSD4/VAG Header"},
|
||||||
|
{meta_RSD6XADP, "RSD6/XADP Header"},
|
||||||
|
{meta_RSD6VAG, "RSD6/VAG Header"},
|
||||||
|
{meta_RSD6WADP, "RSD6/WADP Header"},
|
||||||
|
{meta_RSD6RADP, "RSD6/RADP Header"},
|
||||||
|
{meta_DC_ASD, "ASD Header"},
|
||||||
|
{meta_NAOMI_SPSD, "SPSD Header"},
|
||||||
|
{meta_FFXI_BGW, "BGW BGMStream header"},
|
||||||
|
{meta_FFXI_SPW, "SPW SeWave header"},
|
||||||
|
{meta_PS2_ASS, "ASS Header"},
|
||||||
|
{meta_IDSP, "IDSP Header"},
|
||||||
|
{meta_WAA_WAC_WAD_WAM, "WAA/WAC/WAD/WAM RIFF Header"},
|
||||||
|
{meta_PS2_SEG, "SEG (PS2) Header"},
|
||||||
|
{meta_XBOX_SEG, "SEG (XBOX) Header"},
|
||||||
|
{meta_NDS_STRM_FFTA2, "Final Fantasy Tactics A2 RIFF Header"},
|
||||||
|
{meta_STR_ASR, "Donkey Kong Jet Race KNON/WII Header"},
|
||||||
|
{meta_ZWDSP, "Zack and Wiki custom DSP Header"},
|
||||||
|
{meta_GCA, "GCA DSP Header"},
|
||||||
|
{meta_SPT_SPD, "SPT+SPD DSP Header"},
|
||||||
|
{meta_ISH_ISD, "ISH+ISD DSP Header"},
|
||||||
|
{meta_GSP_GSB, "Tecmo GSP+GSB Header"},
|
||||||
|
{meta_YDSP, "Yuke's DSP (YDSP) Header"},
|
||||||
|
{meta_MSVP, "MSVP Header"},
|
||||||
|
{meta_NGC_SSM, "SSM DSP Header"},
|
||||||
|
{meta_PS2_JOE, "Disney/Pixar JOE Header"},
|
||||||
|
{meta_VGS, "Guitar Hero Encore Rocks the 80's Header"},
|
||||||
|
{meta_DC_DCSW_DCS, "Evil Twin DCS file with helper"},
|
||||||
|
{meta_WII_SMP, "SMP DSP Header"},
|
||||||
|
{meta_EMFF_PS2, "Eidos Music File Format Header"},
|
||||||
|
{meta_EMFF_NGC, "Eidos Music File Format Header"},
|
||||||
|
{meta_THP, "THP Movie File Format Header"},
|
||||||
|
{meta_STS_WII, "Shikigami no Shiro (WII) Header"},
|
||||||
|
{meta_PS2_P2BT, "Pop'n'Music 7 Header"},
|
||||||
|
{meta_PS2_GBTS, "Pop'n'Music 9 Header"},
|
||||||
|
{meta_NGC_DSP_IADP, "IADP Header"},
|
||||||
|
{meta_RSTM_shrunken, "Nintendo RSTM header, corrupted by Atlus"},
|
||||||
|
{meta_RIFF_WAVE_MWV, "RIFF WAVE header with .mwv flavoring"},
|
||||||
|
{meta_RIFF_WAVE_SNS, "RIFF WAVE header with .sns flavoring"},
|
||||||
|
{meta_FFCC_STR, "Final Fantasy: Crystal Chronicles STR header"},
|
||||||
|
{meta_SAT_BAKA, "BAKA header from Crypt Killer"},
|
||||||
|
{meta_NDS_SWAV, "SWAV Header"},
|
||||||
|
{meta_PS2_VSF, "Musashi: Samurai Legend VSF Header"},
|
||||||
|
{meta_NDS_RRDS, "Ridger Racer DS Header"},
|
||||||
|
{meta_PS2_TK5, "Tekken 5 Stream Header"},
|
||||||
|
{meta_PS2_SND, "Might and Magic SSND Header"},
|
||||||
|
{meta_PS2_VSF_TTA, "VSF with SMSS Header"},
|
||||||
|
{meta_ADS, "dhSS Header"},
|
||||||
|
{meta_WII_STR, "HOTD Overkill - STR+STH WII Header"},
|
||||||
|
{meta_PS2_MCG, "Gunvari MCG Header"},
|
||||||
|
{meta_ZSD, "ZSD Header"},
|
||||||
|
{meta_RedSpark, "RedSpark Header"},
|
||||||
|
{meta_PC_IVAUD, "assumed GTA IV Audio file by .ivaud extension"},
|
||||||
|
{meta_DSP_WII_WSD, "Standard Nintendo DSP headers in .wsd"},
|
||||||
|
{meta_WII_NDP, "Vertigo NDP Header"},
|
||||||
|
{meta_PS2_SPS, "Ape Escape 2 SPS Header"},
|
||||||
|
{meta_PS2_XA2_RRP, "Acclaim XA2 Header"},
|
||||||
|
{meta_NDS_HWAS, "NDS 'HWAS' Header"},
|
||||||
|
{meta_NGC_LPS, "Rave Master LPS Header"},
|
||||||
|
{meta_NAOMI_ADPCM, "NAOMI/NAOMI2 Arcade games ADPCM header"},
|
||||||
|
{meta_SD9, "beatmania IIDX SD9 header"},
|
||||||
|
{meta_2DX9, "beatmania IIDX 2DX9 header"},
|
||||||
|
{meta_DSP_YGO, "Konami custom DSP Header"},
|
||||||
|
{meta_PS2_VGV, "Rune: Viking Warlord VGV Header"},
|
||||||
|
{meta_NGC_GCUB, "GCub Header"},
|
||||||
|
{meta_NGC_SCK_DSP, "The Scorpion King SCK Header"},
|
||||||
|
{meta_NGC_SWD, "PSF + Standard DSP Headers"},
|
||||||
|
{meta_CAFF, "Apple Core Audio Format Header"},
|
||||||
|
{meta_PC_MXST, "Lego Island MxSt Header"},
|
||||||
|
{meta_PC_SOB_SAB, "Worms 4: Mayhem SOB/SAB Header"},
|
||||||
|
{meta_MAXIS_XA, "Maxis XAI/XAJ Header"},
|
||||||
|
{meta_EXAKT_SC, "assumed Activision / EXAKT SC by extension"},
|
||||||
|
{meta_WII_BNS, "Nintendo BNS header"},
|
||||||
|
{meta_WII_WAS, "WAS (iSWS) DSP header"},
|
||||||
|
{meta_XBOX_HLWAV, "Half Life 2 bgm header"},
|
||||||
|
{meta_STX, "Nintendo .stx header"},
|
||||||
|
{meta_PS2_STM, "Red Dead Revolver .stm (.ps2stm)"},
|
||||||
|
{meta_MYSPD, "U-Sing .myspd header"},
|
||||||
|
{meta_HIS, "Her Interactive Sound header"},
|
||||||
|
{meta_PS2_AST, "KOEI AST header"},
|
||||||
|
{meta_CAPDSP, "Capcom custom DSP header"},
|
||||||
|
{meta_DMSG, "RIFF/DMSGsegh header"},
|
||||||
|
{meta_PONA_3DO, "Policenauts BGM header"},
|
||||||
|
{meta_PONA_PSX, "Policenauts BGM header"},
|
||||||
|
{meta_NGC_DSP_AAAP, "Double standard dsp header in 'AAAp'"},
|
||||||
|
{meta_NGC_DSP_KONAMI, "Konami dsp header"},
|
||||||
|
{meta_PS2_STER, "STER Header"},
|
||||||
|
{meta_BNSF, "Namco Bandai BNSF header"},
|
||||||
|
{meta_PS2_WB, "Shooting Love. ~TRIZEAL~ WB header"},
|
||||||
|
{meta_S14, "assumed Polycom Siren 14 by .s14 extension"},
|
||||||
|
{meta_SSS, "assumed Polycom Siren 14 by .sss extension"},
|
||||||
|
{meta_PS2_GCM, "GCM 'MCG' Header"},
|
||||||
|
{meta_PS2_SMPL, "Homura 'SMPL' Header"},
|
||||||
|
{meta_PS2_MSA, "Psyvariar -Complete Edition- MSA header"},
|
||||||
|
{meta_PC_SMP, "Ghostbusters .smp Header"},
|
||||||
|
{meta_NGC_PDT, "PDT DSP header"},
|
||||||
|
{meta_NGC_BO2, "Blood Omen 2 DSP header"},
|
||||||
|
{meta_P3D, "Prototype P3D Header"},
|
||||||
|
{meta_PS2_TK1, "Tekken TK5STRM1 Header"},
|
||||||
|
{meta_PS2_ADSC, "ADSC Header"},
|
||||||
|
{meta_NGC_DSP_MPDS, "MPDS DSP header"},
|
||||||
|
{meta_DSP_STR_IG, "Infogrames dual dsp header"},
|
||||||
|
{meta_PSX_MGAV, "Electronic Arts RVWS header"},
|
||||||
|
{meta_PS2_B1S, "B1S header"},
|
||||||
|
{meta_PS2_WAD, "WAD header"},
|
||||||
|
{meta_DSP_XIII, "XIII dsp header"},
|
||||||
|
{meta_NGC_DSP_STH_STR, "STH dsp header"},
|
||||||
|
{meta_DSP_CABELAS, "Cabelas games dsp header"},
|
||||||
|
{meta_PS2_LPCM, "LPCM header"},
|
||||||
|
{meta_PS2_VMS, "VMS Header"},
|
||||||
|
{meta_PS2_XAU, "XAU Header"},
|
||||||
|
{meta_GH3_BAR, "Guitar Hero III Mobile .bar"},
|
||||||
|
{meta_FFW, "Freedom Fighters BGM header"},
|
||||||
|
{meta_DSP_DSPW, "DSPW dsp header"},
|
||||||
|
{meta_PS2_JSTM, "JSTM Header"},
|
||||||
|
{meta_PS3_XVAG, "XVAG Header"},
|
||||||
|
{meta_PS3_CPS, "CPS Header"},
|
||||||
|
{meta_SQEX_SCD, "Square-Enix SCD"},
|
||||||
|
{meta_NGC_NST_DSP, "Animaniacs NST header"},
|
||||||
|
{meta_BAF, ".baf WAVE header"},
|
||||||
|
{meta_PS3_MSF, "PS3 MSF header"},
|
||||||
|
{meta_NUB_VAG, "VAG (NUB) header"},
|
||||||
|
{meta_PS3_PAST, "SNDP header"},
|
||||||
|
{meta_PS3_SGDX, "SGXD header"},
|
||||||
|
{meta_NGCA, "NGCA header"},
|
||||||
|
{meta_WII_RAS, "RAS header"},
|
||||||
|
{meta_PS2_SPM, "SPM header"},
|
||||||
|
{meta_X360_TRA, "assumed DefJam Rapstar Audio File by .tra extension"},
|
||||||
|
{meta_PS2_VGS, "Princess Soft VGS header"},
|
||||||
|
{meta_PS2_IAB, "IAB header"},
|
||||||
|
{meta_PS2_STRLR, "STR L/R header"},
|
||||||
|
{meta_LSF_N1NJ4N, ".lsf !n1nj4n header"},
|
||||||
|
{meta_VAWX, "feelplus VAWX header"},
|
||||||
|
{meta_PC_SNDS, "assumed Heavy Iron IMA by .snds extension"},
|
||||||
|
{meta_PS2_WMUS, "assumed The Warriors Sony ADPCM by .wmus extension"},
|
||||||
|
{meta_HYPERSCAN_KVAG, "Mattel Hyperscan KVAG"},
|
||||||
|
{meta_IOS_PSND, "PSND Header"},
|
||||||
|
{meta_BOS_ADP, "ADP! header"},
|
||||||
|
{meta_EB_SFX, "Excitebots .sfx header"},
|
||||||
|
{meta_EB_SF0, "assumed Excitebots .sf0 by extension"},
|
||||||
|
{meta_PS3_KLBS, "klBS Header"},
|
||||||
|
{meta_PS2_MTAF, "Konami MTAF header"},
|
||||||
|
{meta_PS2_VAG1, "Konami VAG Mono header (VAG1)"},
|
||||||
|
{meta_PS2_VAG2, "Konami VAG Stereo header (VAG2)"},
|
||||||
|
{meta_TUN, "TUN 'ALP' header"},
|
||||||
|
{meta_WPD, "WPD 'DPW' header"},
|
||||||
|
{meta_MN_STR, "Mini Ninjas 'STR' header"},
|
||||||
|
{meta_PS2_MSS, "Guerilla MSCC header"},
|
||||||
|
{meta_PS2_HSF, "Lowrider 'HSF' header"},
|
||||||
|
{meta_PS3_IVAG, "PS3 'IVAG' Header"},
|
||||||
|
{meta_PS2_2PFS, "PS2 '2PFS' Header"},
|
||||||
|
{meta_RSD6OOGV, "RSD6/OOGV Header"},
|
||||||
|
{meta_UBI_CKD, "CKD 'RIFF' Header"},
|
||||||
|
{meta_PS2_VBK, "PS2 VBK Header"},
|
||||||
|
{meta_OTM, "Otomedius OTM Header"},
|
||||||
|
{meta_CSTM, "Nintendo 3DS CSTM Header"},
|
||||||
|
{meta_FSTM, "Nintendo Wii U FSTM Header"},
|
||||||
|
{meta_KT_WIIBGM, "Koei Tecmo WiiBGM Header"},
|
||||||
|
{meta_3DS_IDSP, "Nintendo IDSP Header"},
|
||||||
|
{meta_WIIU_BTSND, "Wii U Menu Boot Sound"},
|
||||||
|
{meta_MCA, "Capcom MCA Header"},
|
||||||
|
{meta_XB3D_ADX, "Xenoblade 3D ADX Header"},
|
||||||
|
{meta_HCA, "CRI MiddleWare HCA Header"},
|
||||||
|
{meta_PS2_SVAG_SNK, "SNK SVAG header"},
|
||||||
|
{meta_PS2_VDS_VDM, "Graffiti Kingdom VDS/VDM Header"},
|
||||||
|
{meta_X360_CXS, "CXS Header"},
|
||||||
|
#ifdef VGM_USE_VORBIS
|
||||||
|
{meta_OGG_VORBIS, "Ogg Vorbis"},
|
||||||
|
{meta_OGG_SLI, "Ogg Vorbis with .sli (start,length) for looping"},
|
||||||
|
{meta_OGG_SLI2, "Ogg Vorbis with .sli (from,to) for looping"},
|
||||||
|
{meta_OGG_SFL, "Ogg Vorbis with SFPL for looping"},
|
||||||
|
{meta_OGG_UM3, "Ogg Vorbis, Ultramarine3 'encryption'"},
|
||||||
|
{meta_OGG_KOVS, "Ogg Vorbis, KOVS header"},
|
||||||
|
{meta_OGG_PSYCH, "Ogg Vorbis, Psychic Software obfuscation"},
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_MPEG
|
||||||
|
{meta_AHX, "CRI AHX header"},
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_MP4V2
|
||||||
|
{meta_MP4, "AAC header"},
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
{meta_FFmpeg, "FFmpeg supported file format"},
|
||||||
|
#endif
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
const char * get_vgmstream_coding_description(coding_t coding_type) {
|
||||||
|
int i, list_length;
|
||||||
|
|
||||||
|
list_length = sizeof(coding_info_list) / sizeof(coding_info);
|
||||||
|
for (i=0; i < list_length; i++) {
|
||||||
|
if (coding_info_list[i].type == coding_type)
|
||||||
|
return coding_info_list[i].description;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
const char * get_vgmstream_layout_description(layout_t layout_type) {
|
||||||
|
int i, list_length;
|
||||||
|
|
||||||
|
list_length = sizeof(layout_info_list) / sizeof(layout_info);
|
||||||
|
for (i=0; i < list_length; i++) {
|
||||||
|
if (layout_info_list[i].type == layout_type)
|
||||||
|
return layout_info_list[i].description;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
const char * get_vgmstream_meta_description(meta_t meta_type) {
|
||||||
|
int i, list_length;
|
||||||
|
|
||||||
|
list_length = sizeof(meta_info_list) / sizeof(meta_info);
|
||||||
|
for (i=0; i < list_length; i++) {
|
||||||
|
if (meta_info_list[i].type == meta_type)
|
||||||
|
return meta_info_list[i].description;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* formats.h - utils to parse supported formats
|
||||||
|
*/
|
||||||
|
#ifndef _FORMATS_H_
|
||||||
|
#define _FORMATS_H_
|
||||||
|
|
||||||
|
#include "vgmstream.h"
|
||||||
|
|
||||||
|
/* rough number of chars counting all extensions (actually <1500 and extra space) */
|
||||||
|
#define VGM_EXTENSION_LIST_CHAR_SIZE 2000
|
||||||
|
|
||||||
|
const char ** vgmstream_get_formats();
|
||||||
|
int vgmstream_get_formats_length();
|
||||||
|
|
||||||
|
const char * get_vgmstream_coding_description(coding_t coding_type);
|
||||||
|
const char * get_vgmstream_layout_description(layout_t layout_type);
|
||||||
|
const char * get_vgmstream_meta_description(meta_t meta_type);
|
||||||
|
|
||||||
|
#endif /* _FORMATS_H_ */
|
|
@ -4,15 +4,25 @@
|
||||||
/* set up for the block at the given offset */
|
/* set up for the block at the given offset */
|
||||||
void gsb_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
void gsb_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||||
int i;
|
int i;
|
||||||
|
int block_header_size = 0x20; /*from header*/
|
||||||
|
int block_channel_size = 0x8000; /*from header, per channel*/
|
||||||
|
|
||||||
vgmstream->current_block_offset = block_offset;
|
vgmstream->current_block_offset = block_offset;
|
||||||
vgmstream->current_block_size = 0x10000; /*read_32bitLE(
|
vgmstream->current_block_size = block_channel_size;
|
||||||
vgmstream->current_block_offset+0x10,
|
vgmstream->next_block_offset = vgmstream->current_block_offset
|
||||||
vgmstream->ch[0].streamfile); */
|
+ block_header_size
|
||||||
vgmstream->next_block_offset = vgmstream->current_block_offset + vgmstream->current_block_size+0x20;
|
+ block_channel_size * vgmstream->channels;
|
||||||
vgmstream->current_block_size/=vgmstream->channels;
|
|
||||||
|
|
||||||
for (i=0;i<vgmstream->channels;i++) {
|
for (i=0;i<vgmstream->channels;i++) {
|
||||||
vgmstream->ch[i].offset = vgmstream->current_block_offset+0x20+(vgmstream->current_block_size*i);
|
int interleave;
|
||||||
|
int filesize = vgmstream->ch[i].streamfile->get_size(vgmstream->ch[i].streamfile);
|
||||||
|
if (vgmstream->next_block_offset > filesize)
|
||||||
|
interleave = (filesize - vgmstream->current_block_offset - block_header_size) / vgmstream->channels;
|
||||||
|
else
|
||||||
|
interleave = block_channel_size;
|
||||||
|
|
||||||
|
vgmstream->ch[i].offset = vgmstream->current_block_offset
|
||||||
|
+ block_header_size
|
||||||
|
+ (interleave*i);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@
|
||||||
#include "../streamtypes.h"
|
#include "../streamtypes.h"
|
||||||
#include "../vgmstream.h"
|
#include "../vgmstream.h"
|
||||||
|
|
||||||
|
/* blocked layouts */
|
||||||
void ast_block_update(off_t block_ofset, VGMSTREAM * vgmstream);
|
void ast_block_update(off_t block_ofset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
void mxch_block_update(off_t block_ofset, VGMSTREAM * vgmstream);
|
void mxch_block_update(off_t block_ofset, VGMSTREAM * vgmstream);
|
||||||
|
@ -46,6 +47,19 @@ void filp_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
void ivaud_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
void ivaud_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
|
void psx_mgav_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
|
void ps2_adm_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
|
void dsp_bdsp_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
|
void tra_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
|
void ps2_iab_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
|
void ps2_strlr_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
|
/* other layouts */
|
||||||
void render_vgmstream_interleave(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
void render_vgmstream_interleave(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
void render_vgmstream_nolayout(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
void render_vgmstream_nolayout(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
||||||
|
@ -60,20 +74,4 @@ void render_vgmstream_aax(sample * buffer, int32_t sample_count, VGMSTREAM * vgm
|
||||||
|
|
||||||
void render_vgmstream_scd_int(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
void render_vgmstream_scd_int(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
void psx_mgav_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
|
||||||
|
|
||||||
void ps2_adm_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
|
||||||
|
|
||||||
void dsp_bdsp_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
|
||||||
|
|
||||||
void tra_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
|
||||||
|
|
||||||
void mtaf_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
|
||||||
|
|
||||||
void ps2_iab_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
|
||||||
|
|
||||||
void ps2_strlr_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
|
||||||
|
|
||||||
void ps2_mtaf_block_update(off_t block_ofset, VGMSTREAM * vgmstream);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -41,7 +41,7 @@ VGMSTREAM * init_vgmstream_2dx(STREAMFILE *streamFile) {
|
||||||
vgmstream->num_samples = read_32bitLE(0x66,streamFile);
|
vgmstream->num_samples = read_32bitLE(0x66,streamFile);
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
vgmstream->interleave_block_size = read_16bitLE(0x38,streamFile);
|
vgmstream->interleave_block_size = read_16bitLE(0x38,streamFile);
|
||||||
vgmstream->meta_type = meta_2DX;
|
vgmstream->meta_type = meta_2DX9;
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
{
|
||||||
|
|
|
@ -273,12 +273,6 @@ VGMSTREAM * init_vgmstream_Cstr(STREAMFILE *streamFile) {
|
||||||
for (i=0;i<16;i++)
|
for (i=0;i<16;i++)
|
||||||
vgmstream->ch[1].adpcm_coef[i]=read_16bitBE(0x9c+i*2,streamFile);
|
vgmstream->ch[1].adpcm_coef[i]=read_16bitBE(0x9c+i*2,streamFile);
|
||||||
}
|
}
|
||||||
#ifdef DEBUG
|
|
||||||
vgmstream->ch[0].loop_history1 = read_16bitBE(0x66,streamFile);
|
|
||||||
vgmstream->ch[0].loop_history2 = read_16bitBE(0x68,streamFile);
|
|
||||||
vgmstream->ch[1].loop_history1 = read_16bitBE(0xc6,streamFile);
|
|
||||||
vgmstream->ch[1].loop_history2 = read_16bitBE(0xc8,streamFile);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* open the file for reading by each channel */
|
/* open the file for reading by each channel */
|
||||||
{
|
{
|
||||||
|
|
|
@ -1,36 +1,41 @@
|
||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../util.h"
|
|
||||||
|
|
||||||
/* .BAF - Bizarre Creations (Blur, James Bond 007: Blood Stone, etc) */
|
/* .BAF - Bizarre Creations (Blur, James Bond 007: Blood Stone, etc) */
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_baf(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_baf(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
off_t WAVE_size, DATA_size;
|
||||||
off_t WAVE_size,DATA_size;
|
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
long sample_count;
|
long sample_count;
|
||||||
|
int sample_rate;
|
||||||
|
|
||||||
const int frame_size = 33;
|
const int frame_size = 33;
|
||||||
const int frame_samples = 64;
|
const int frame_samples = (frame_size-1) * 2;
|
||||||
int channels;
|
int channels;
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extensions */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
if ( !check_extensions(streamFile, "baf") )
|
||||||
if (strcasecmp("baf",filename_extension(filename))) goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* check WAVE */
|
/* check WAVE */
|
||||||
if (read_32bitBE(0,streamFile) != 0x57415645) goto fail;
|
if (read_32bitBE(0,streamFile) != 0x57415645) /* "WAVE" */
|
||||||
|
goto fail;
|
||||||
WAVE_size = read_32bitBE(4,streamFile);
|
WAVE_size = read_32bitBE(4,streamFile);
|
||||||
if (WAVE_size != 0x4c) goto fail;
|
if (WAVE_size != 0x4c) /* && WAVE_size != 0x50*/
|
||||||
|
goto fail;
|
||||||
/* check for DATA after WAVE */
|
/* check for DATA after WAVE */
|
||||||
if (read_32bitBE(WAVE_size,streamFile) != 0x44415441) goto fail;
|
if (read_32bitBE(WAVE_size,streamFile) != 0x44415441) /* "DATA"*/
|
||||||
|
goto fail;
|
||||||
/* check that WAVE size is data size */
|
/* check that WAVE size is data size */
|
||||||
DATA_size = read_32bitBE(0x30,streamFile);
|
DATA_size = read_32bitBE(0x30,streamFile);
|
||||||
if (read_32bitBE(WAVE_size+4,streamFile)-8 != DATA_size) goto fail;
|
if (read_32bitBE(WAVE_size+4,streamFile)-8 != DATA_size) goto fail;
|
||||||
|
|
||||||
|
/*if (WAVE_size == 0x50) sample_count = DATA_size * frame_samples / frame_size / channels;*/
|
||||||
sample_count = read_32bitBE(0x44,streamFile);
|
sample_count = read_32bitBE(0x44,streamFile);
|
||||||
|
|
||||||
|
/*if (WAVE_size == 0x50) sample_rate = read_32bitBE(0x3c,streamFile);*/
|
||||||
|
sample_rate = read_32bitBE(0x40,streamFile);
|
||||||
|
|
||||||
/* unsure how to detect channel count, so use a hack */
|
/* unsure how to detect channel count, so use a hack */
|
||||||
channels = (long long)DATA_size / frame_size * frame_samples / sample_count;
|
channels = (long long)DATA_size / frame_size * frame_samples / sample_count;
|
||||||
|
|
||||||
|
@ -40,33 +45,22 @@ VGMSTREAM * init_vgmstream_baf(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = WAVE_size + 8;
|
start_offset = WAVE_size + 8;
|
||||||
vgmstream->sample_rate = read_32bitBE(0x40,streamFile);
|
vgmstream->sample_rate = sample_rate;
|
||||||
vgmstream->num_samples = sample_count;
|
vgmstream->num_samples = sample_count;
|
||||||
|
|
||||||
vgmstream->coding_type = coding_BAF_ADPCM;
|
vgmstream->coding_type = coding_PSX_cfg;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = frame_size;
|
vgmstream->interleave_block_size = frame_size;
|
||||||
vgmstream->meta_type = meta_BAF;
|
vgmstream->meta_type = meta_BAF;
|
||||||
|
|
||||||
/* open the file for reading by each channel */
|
/* open the file for reading */
|
||||||
{
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
int i;
|
goto fail;
|
||||||
STREAMFILE *file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
if (!file) goto fail;
|
|
||||||
for (i=0;i<channels;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;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
fail:
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -7,13 +7,14 @@ VGMSTREAM * init_vgmstream_bcstm(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
coding_t coding_type;
|
coding_t coding_type;
|
||||||
|
|
||||||
off_t head_offset;
|
off_t info_offset = 0, seek_offset = 0, data_offset = 0;
|
||||||
off_t seek_offset;
|
uint16_t temp_id;
|
||||||
int codec_number;
|
int codec_number;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
int loop_flag;
|
int loop_flag;
|
||||||
int ima = 0;
|
int i, ima = 0;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
|
int section_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile, filename, sizeof(filename));
|
streamFile->get_name(streamFile, filename, sizeof(filename));
|
||||||
|
@ -24,24 +25,46 @@ VGMSTREAM * init_vgmstream_bcstm(STREAMFILE *streamFile) {
|
||||||
/* check header */
|
/* check header */
|
||||||
if ((uint32_t)read_32bitBE(0, streamFile) != 0x4353544D) /* "CSTM" */
|
if ((uint32_t)read_32bitBE(0, streamFile) != 0x4353544D) /* "CSTM" */
|
||||||
goto fail;
|
goto fail;
|
||||||
if ((uint32_t)read_32bitBE(4, streamFile) != 0xFFFE4000)
|
if ((uint16_t)read_16bitLE(4, streamFile) != 0xFEFF)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
section_count = read_16bitLE(0x10, streamFile);
|
||||||
|
for (i = 0; i < section_count; i++) {
|
||||||
|
temp_id = read_16bitLE(0x14 + i * 0xc, streamFile);
|
||||||
|
switch(temp_id) {
|
||||||
|
case 0x4000:
|
||||||
|
info_offset = read_32bitLE(0x18 + i * 0xc, streamFile);
|
||||||
|
/* size_t info_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
case 0x4001:
|
||||||
|
seek_offset = read_32bitLE(0x18 + i * 0xc, streamFile);
|
||||||
|
/* size_t seek_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
case 0x4002:
|
||||||
|
data_offset = read_32bitLE(0x18 + i * 0xc, streamFile);
|
||||||
|
/* size_t data_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
case 0x4003:
|
||||||
|
/* off_t regn_offset = read_32bitLE(0x18 + i * 0xc, streamFile); */
|
||||||
|
/* size_t regn_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
case 0x4004:
|
||||||
|
/* off_t pdat_offset = read_32bitLE(0x18 + i * 0xc, streamFile); */
|
||||||
|
/* size_t pdat_size = read_32bitLE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* get head offset, check */
|
|
||||||
head_offset = read_32bitLE(0x18, streamFile);
|
|
||||||
|
|
||||||
if ((uint32_t)read_32bitBE(head_offset, streamFile) != 0x494E464F) /* "INFO" */
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
seek_offset = read_32bitLE(0x24, streamFile);
|
|
||||||
|
|
||||||
|
|
||||||
/* check type details */
|
/* check type details */
|
||||||
codec_number = read_8bit(head_offset + 0x20, streamFile);
|
if (info_offset == 0) goto fail;
|
||||||
loop_flag = read_8bit(head_offset + 0x21, streamFile);
|
codec_number = read_8bit(info_offset + 0x20, streamFile);
|
||||||
channel_count = read_8bit(head_offset + 0x22, streamFile);
|
loop_flag = read_8bit(info_offset + 0x21, streamFile);
|
||||||
|
channel_count = read_8bit(info_offset + 0x22, streamFile);
|
||||||
|
|
||||||
switch (codec_number) {
|
switch (codec_number) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -51,6 +74,7 @@ VGMSTREAM * init_vgmstream_bcstm(STREAMFILE *streamFile) {
|
||||||
coding_type = coding_PCM16LE;
|
coding_type = coding_PCM16LE;
|
||||||
break;
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
|
if (seek_offset == 0) goto fail;
|
||||||
if ((uint32_t)read_32bitBE(seek_offset, streamFile) != 0x5345454B) { /* "SEEK" If this header doesn't exist, assuming that the file is IMA */
|
if ((uint32_t)read_32bitBE(seek_offset, streamFile) != 0x5345454B) { /* "SEEK" If this header doesn't exist, assuming that the file is IMA */
|
||||||
ima = 1;
|
ima = 1;
|
||||||
coding_type = coding_INT_IMA;
|
coding_type = coding_INT_IMA;
|
||||||
|
@ -70,12 +94,12 @@ VGMSTREAM * init_vgmstream_bcstm(STREAMFILE *streamFile) {
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
vgmstream->num_samples = read_32bitLE(head_offset + 0x2c, streamFile);
|
vgmstream->num_samples = read_32bitLE(info_offset + 0x2c, streamFile);
|
||||||
vgmstream->sample_rate = (uint16_t)read_16bitLE(head_offset + 0x24, streamFile);
|
vgmstream->sample_rate = (uint16_t)read_16bitLE(info_offset + 0x24, streamFile);
|
||||||
/* channels and loop flag are set by allocate_vgmstream */
|
/* channels and loop flag are set by allocate_vgmstream */
|
||||||
if (ima) //Shift the loop points back slightly to avoid stupid pops in some IMA streams due to DC offsetting
|
if (ima) //Shift the loop points back slightly to avoid stupid pops in some IMA streams due to DC offsetting
|
||||||
{
|
{
|
||||||
vgmstream->loop_start_sample = read_32bitLE(head_offset + 0x28, streamFile);
|
vgmstream->loop_start_sample = read_32bitLE(info_offset + 0x28, streamFile);
|
||||||
if (vgmstream->loop_start_sample > 10000)
|
if (vgmstream->loop_start_sample > 10000)
|
||||||
{
|
{
|
||||||
vgmstream->loop_start_sample -= 5000;
|
vgmstream->loop_start_sample -= 5000;
|
||||||
|
@ -86,7 +110,7 @@ VGMSTREAM * init_vgmstream_bcstm(STREAMFILE *streamFile) {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vgmstream->loop_start_sample = read_32bitLE(head_offset + 0x28, streamFile);
|
vgmstream->loop_start_sample = read_32bitLE(info_offset + 0x28, streamFile);
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -105,13 +129,13 @@ VGMSTREAM * init_vgmstream_bcstm(STREAMFILE *streamFile) {
|
||||||
if (ima)
|
if (ima)
|
||||||
vgmstream->interleave_block_size = 0x200;
|
vgmstream->interleave_block_size = 0x200;
|
||||||
else {
|
else {
|
||||||
vgmstream->interleave_block_size = read_32bitLE(head_offset + 0x34, streamFile);
|
vgmstream->interleave_block_size = read_32bitLE(info_offset + 0x34, streamFile);
|
||||||
vgmstream->interleave_smallblock_size = read_32bitLE(head_offset + 0x44, streamFile);
|
vgmstream->interleave_smallblock_size = read_32bitLE(info_offset + 0x44, streamFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||||
off_t coef_offset;
|
off_t coef_offset;
|
||||||
off_t tempoffset = head_offset;
|
off_t tempoffset = info_offset;
|
||||||
int foundcoef = 0;
|
int foundcoef = 0;
|
||||||
int i, j;
|
int i, j;
|
||||||
int coef_spacing = 0x2E;
|
int coef_spacing = 0x2E;
|
||||||
|
@ -120,7 +144,7 @@ VGMSTREAM * init_vgmstream_bcstm(STREAMFILE *streamFile) {
|
||||||
{
|
{
|
||||||
if ((uint32_t)read_32bitLE(tempoffset, streamFile) == 0x00004102)
|
if ((uint32_t)read_32bitLE(tempoffset, streamFile) == 0x00004102)
|
||||||
{
|
{
|
||||||
coef_offset = read_32bitLE(tempoffset + 4, streamFile) + tempoffset + (channel_count * 8) - 4 - head_offset;
|
coef_offset = read_32bitLE(tempoffset + 4, streamFile) + tempoffset + (channel_count * 8) - 4 - info_offset;
|
||||||
foundcoef++;
|
foundcoef++;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -129,17 +153,18 @@ VGMSTREAM * init_vgmstream_bcstm(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
for (j = 0; j<vgmstream->channels; j++) {
|
for (j = 0; j<vgmstream->channels; j++) {
|
||||||
for (i = 0; i<16; i++) {
|
for (i = 0; i<16; i++) {
|
||||||
vgmstream->ch[j].adpcm_coef[i] = read_16bitLE(head_offset + coef_offset + j*coef_spacing + i * 2, streamFile);
|
vgmstream->ch[j].adpcm_coef[i] = read_16bitLE(info_offset + coef_offset + j*coef_spacing + i * 2, streamFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ima) // No SEEK (ADPC) header, so just start where the SEEK header is supposed to be.
|
if (ima) { // No SEEK (ADPC) header, so just start where the SEEK header is supposed to be.
|
||||||
|
if (seek_offset == 0) goto fail;
|
||||||
start_offset = seek_offset;
|
start_offset = seek_offset;
|
||||||
else if (vgmstream->coding_type == coding_NGC_DSP)
|
} else {
|
||||||
start_offset = read_32bitLE(0x30, streamFile) + 0x20;
|
if (data_offset == 0) goto fail;
|
||||||
else // No SEEK header and not IMA, so just start after the DATA header
|
start_offset = data_offset + 0x20;
|
||||||
start_offset = 0x120;
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
#include "../stack_alloc.h"
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_bfstm(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_bfstm(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
@ -7,16 +8,16 @@ VGMSTREAM * init_vgmstream_bfstm(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
coding_t coding_type;
|
coding_t coding_type;
|
||||||
|
|
||||||
off_t head_offset;
|
off_t info_offset = 0, seek_offset = 0, data_offset = 0;
|
||||||
off_t seek_offset;
|
uint16_t temp_id;
|
||||||
off_t data_offset;
|
|
||||||
int codec_number;
|
int codec_number;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
int loop_flag;
|
int loop_flag;
|
||||||
|
int i, j;
|
||||||
int ima = 0;
|
int ima = 0;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int founddata;
|
|
||||||
off_t tempoffset1;
|
off_t tempoffset1;
|
||||||
|
int section_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile, filename, sizeof(filename));
|
streamFile->get_name(streamFile, filename, sizeof(filename));
|
||||||
|
@ -30,33 +31,45 @@ VGMSTREAM * init_vgmstream_bfstm(STREAMFILE *streamFile) {
|
||||||
if ((uint16_t)read_16bitBE(4, streamFile) != 0xFEFF)
|
if ((uint16_t)read_16bitBE(4, streamFile) != 0xFEFF)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
founddata = 0;
|
section_count = read_16bitBE(0x10, streamFile);
|
||||||
tempoffset1 = 0x8;
|
for (i = 0; i < section_count; i++) {
|
||||||
|
temp_id = read_16bitBE(0x14 + i * 0xc, streamFile);
|
||||||
while (!(founddata))
|
switch(temp_id) {
|
||||||
{
|
case 0x4000:
|
||||||
if ((uint32_t)read_32bitBE(tempoffset1, streamFile) == 0x40020000)
|
info_offset = read_32bitBE(0x18 + i * 0xc, streamFile);
|
||||||
{
|
/* size_t info_size = read_32bitBE(0x1c + i * 0xc, streamFile); */
|
||||||
data_offset = read_32bitBE(tempoffset1 + 4, streamFile);
|
break;
|
||||||
founddata++;
|
case 0x4001:
|
||||||
|
seek_offset = read_32bitBE(0x18 + i * 0xc, streamFile);
|
||||||
|
/* size_t seek_size = read_32bitBE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
case 0x4002:
|
||||||
|
data_offset = read_32bitBE(0x18 + i * 0xc, streamFile);
|
||||||
|
/* size_t data_size = read_32bitBE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
case 0x4003:
|
||||||
|
/* off_t regn_offset = read_32bitBE(0x18 + i * 0xc, streamFile); */
|
||||||
|
/* size_t regn_size = read_32bitBE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
case 0x4004:
|
||||||
|
/* off_t pdat_offset = read_32bitBE(0x18 + i * 0xc, streamFile); */
|
||||||
|
/* size_t pdat_size = read_32bitBE(0x1c + i * 0xc, streamFile); */
|
||||||
|
break;
|
||||||
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tempoffset1++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* get head offset, check */
|
|
||||||
head_offset = read_32bitBE(0x18, streamFile);
|
|
||||||
|
|
||||||
if ((uint32_t)read_32bitBE(head_offset, streamFile) != 0x494E464F) /* "INFO" */
|
if (info_offset == 0) goto fail;
|
||||||
|
if ((uint32_t)read_32bitBE(info_offset, streamFile) != 0x494E464F) /* "INFO" */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
seek_offset = read_32bitBE(0x24, streamFile);
|
|
||||||
|
|
||||||
|
|
||||||
/* check type details */
|
/* check type details */
|
||||||
codec_number = read_8bit(head_offset + 0x20, streamFile);
|
codec_number = read_8bit(info_offset + 0x20, streamFile);
|
||||||
loop_flag = read_8bit(head_offset + 0x21, streamFile);
|
loop_flag = read_8bit(info_offset + 0x21, streamFile);
|
||||||
channel_count = read_8bit(head_offset + 0x22, streamFile);
|
channel_count = read_8bit(info_offset + 0x22, streamFile);
|
||||||
|
|
||||||
switch (codec_number) {
|
switch (codec_number) {
|
||||||
case 0:
|
case 0:
|
||||||
|
@ -80,12 +93,12 @@ VGMSTREAM * init_vgmstream_bfstm(STREAMFILE *streamFile) {
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
vgmstream->num_samples = read_32bitBE(head_offset + 0x2c, streamFile);
|
vgmstream->num_samples = read_32bitBE(info_offset + 0x2c, streamFile);
|
||||||
vgmstream->sample_rate = (uint16_t)read_16bitBE(head_offset + 0x26, streamFile);
|
vgmstream->sample_rate = (uint16_t)read_16bitBE(info_offset + 0x26, streamFile);
|
||||||
/* channels and loop flag are set by allocate_vgmstream */
|
/* channels and loop flag are set by allocate_vgmstream */
|
||||||
if (ima) //Shift the loop points back slightly to avoid stupid pops in some IMA streams due to DC offsetting
|
if (ima) //Shift the loop points back slightly to avoid stupid pops in some IMA streams due to DC offsetting
|
||||||
{
|
{
|
||||||
vgmstream->loop_start_sample = read_32bitBE(head_offset + 0x28, streamFile);
|
vgmstream->loop_start_sample = read_32bitBE(info_offset + 0x28, streamFile);
|
||||||
if (vgmstream->loop_start_sample > 10000)
|
if (vgmstream->loop_start_sample > 10000)
|
||||||
{
|
{
|
||||||
vgmstream->loop_start_sample -= 5000;
|
vgmstream->loop_start_sample -= 5000;
|
||||||
|
@ -96,7 +109,7 @@ VGMSTREAM * init_vgmstream_bfstm(STREAMFILE *streamFile) {
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
vgmstream->loop_start_sample = read_32bitBE(head_offset + 0x28, streamFile);
|
vgmstream->loop_start_sample = read_32bitBE(info_offset + 0x28, streamFile);
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,41 +128,36 @@ VGMSTREAM * init_vgmstream_bfstm(STREAMFILE *streamFile) {
|
||||||
if (ima)
|
if (ima)
|
||||||
vgmstream->interleave_block_size = 0x200;
|
vgmstream->interleave_block_size = 0x200;
|
||||||
else {
|
else {
|
||||||
vgmstream->interleave_block_size = read_32bitBE(head_offset + 0x34, streamFile);
|
vgmstream->interleave_block_size = read_32bitBE(info_offset + 0x34, streamFile);
|
||||||
vgmstream->interleave_smallblock_size = read_32bitBE(head_offset + 0x44, streamFile);
|
vgmstream->interleave_smallblock_size = read_32bitBE(info_offset + 0x44, streamFile);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||||
off_t coef_offset;
|
off_t coeff_ptr_table;
|
||||||
off_t tempoffset2 = head_offset;
|
VARDECL(off_t, coef_offset);
|
||||||
int foundcoef = 0;
|
ALLOC(coef_offset, channel_count, off_t);
|
||||||
int i, j;
|
coeff_ptr_table = read_32bitBE(info_offset + 0x1c, streamFile) + info_offset + 8; // Getting pointer for coefficient pointer table
|
||||||
int coef_spacing = 0x2E;
|
|
||||||
|
|
||||||
while (!(foundcoef))
|
for (i = 0; i < channel_count; i++) {
|
||||||
{
|
tempoffset1 = read_32bitBE(coeff_ptr_table + 8 + i * 8, streamFile);
|
||||||
if ((uint32_t)read_32bitBE(tempoffset2, streamFile) == 0x41020000)
|
coef_offset[i] = tempoffset1 + coeff_ptr_table;
|
||||||
{
|
coef_offset[i] += read_32bitBE(coef_offset[i] + 4, streamFile);
|
||||||
coef_offset = read_32bitBE(tempoffset2 + 4, streamFile) + tempoffset2 + (channel_count * 8) - 4 - head_offset;
|
|
||||||
foundcoef++;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
tempoffset2++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (j = 0; j<vgmstream->channels; j++) {
|
for (j = 0; j<vgmstream->channels; j++) {
|
||||||
for (i = 0; i<16; i++) {
|
for (i = 0; i<16; i++) {
|
||||||
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(head_offset + coef_offset + j*coef_spacing + i * 2, streamFile);
|
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_offset[j] + i * 2, streamFile);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ima) // No SEEK (ADPC) header, so just start where the SEEK header is supposed to be.
|
if (ima) { // No SEEK (ADPC) header, so just start where the SEEK header is supposed to be.
|
||||||
|
if (seek_offset == 0) goto fail;
|
||||||
start_offset = seek_offset;
|
start_offset = seek_offset;
|
||||||
else if (vgmstream->coding_type == coding_NGC_DSP)
|
} else {
|
||||||
|
if (data_offset == 0) goto fail;
|
||||||
start_offset = data_offset + 0x20;
|
start_offset = data_offset + 0x20;
|
||||||
else // No SEEK header and not IMA, so just start after the DATA header
|
}
|
||||||
start_offset = 0x120;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -7,7 +7,7 @@ VGMSTREAM * init_vgmstream_bfwav(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
coding_t coding_type;
|
coding_t coding_type;
|
||||||
|
|
||||||
int ima = 0;
|
/*int ima = 0;*/
|
||||||
int nsmbu_flag = 0;
|
int nsmbu_flag = 0;
|
||||||
int32_t(*read_32bit)(off_t, STREAMFILE*) = read_32bitBE;
|
int32_t(*read_32bit)(off_t, STREAMFILE*) = read_32bitBE;
|
||||||
int16_t(*read_16bit)(off_t, STREAMFILE*) = read_16bitBE;
|
int16_t(*read_16bit)(off_t, STREAMFILE*) = read_16bitBE;
|
||||||
|
|
|
@ -1,32 +1,43 @@
|
||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../util.h"
|
|
||||||
|
|
||||||
/* BGW (FF XI) */
|
/* BGW - from Final Fantasy XI (PC) music files
|
||||||
|
* Some info from POLUtils */
|
||||||
VGMSTREAM * init_vgmstream_bgw(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_bgw(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
uint32_t codec, filesize, blocksize, sample_rate;
|
||||||
off_t start_offset;
|
|
||||||
int32_t loop_start;
|
int32_t loop_start;
|
||||||
|
uint8_t block_align;
|
||||||
|
off_t start_offset;
|
||||||
|
|
||||||
int loop_flag = 0;
|
int channel_count, loop_flag = 0;
|
||||||
int channel_count;
|
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extensions */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
if ( !check_extensions(streamFile, "bgw") )
|
||||||
if (strcasecmp("bgw",filename_extension(filename))) goto fail;
|
|
||||||
|
|
||||||
/* "BGMStream" */
|
|
||||||
if (read_32bitBE(0,streamFile) != 0x42474d53 ||
|
|
||||||
read_32bitBE(4,streamFile) != 0x74726561 ||
|
|
||||||
read_32bitBE(8,streamFile) != 0x6d000000 ||
|
|
||||||
read_32bitBE(12,streamFile) != 0) goto fail;
|
|
||||||
|
|
||||||
/* check file size with header value */
|
|
||||||
if (read_32bitLE(0x10,streamFile) != get_streamfile_size(streamFile))
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
channel_count = read_8bit(0x2e,streamFile);
|
/* check header */
|
||||||
|
if (read_32bitBE(0x00,streamFile) != 0x42474d53 || /* "BGMS" */
|
||||||
|
read_32bitBE(0x04,streamFile) != 0x74726561 || /* "trea" */
|
||||||
|
read_32bitBE(0x08,streamFile) != 0x6d000000 ) /* "m\0\0\0" */
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
codec = read_32bitLE(0x0c,streamFile);
|
||||||
|
filesize = read_32bitLE(0x10,streamFile);
|
||||||
|
/*file_id = read_32bitLE(0x14,streamFile);*/
|
||||||
|
blocksize = read_32bitLE(0x18,streamFile);
|
||||||
loop_start = read_32bitLE(0x1c,streamFile);
|
loop_start = read_32bitLE(0x1c,streamFile);
|
||||||
|
sample_rate = (read_32bitLE(0x20,streamFile) + read_32bitLE(0x24,streamFile)) & 0xFFFFFFFF; /* bizarrely obfuscated sample rate */
|
||||||
|
start_offset = read_32bitLE(0x28,streamFile);
|
||||||
|
/*0x2c: unk (vol?) */
|
||||||
|
/*0x2d: unk (0x10?) */
|
||||||
|
channel_count = read_8bit(0x2e,streamFile);
|
||||||
|
block_align = read_8bit(0x2f,streamFile);
|
||||||
|
|
||||||
|
|
||||||
|
/* check file size with header value */
|
||||||
|
if (filesize != get_streamfile_size(streamFile))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
loop_flag = (loop_start > 0);
|
loop_flag = (loop_start > 0);
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
|
@ -34,67 +45,80 @@ VGMSTREAM * init_vgmstream_bgw(STREAMFILE *streamFile) {
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = read_32bitLE(0x28,streamFile);
|
vgmstream->meta_type = meta_FFXI_BGW;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->sample_rate = sample_rate;
|
||||||
vgmstream->sample_rate = 44100;
|
|
||||||
vgmstream->coding_type = coding_FFXI;
|
switch (codec) {
|
||||||
vgmstream->num_samples = read_32bitLE(0x18,streamFile)*16;
|
case 0: /* PS ADPCM */
|
||||||
|
vgmstream->coding_type = coding_PSX_cfg;
|
||||||
|
vgmstream->layout_type = layout_interleave;
|
||||||
|
vgmstream->interleave_block_size = (block_align / 2) + 1; /* half, even if channels = 1 */
|
||||||
|
|
||||||
|
vgmstream->num_samples = blocksize * block_align;
|
||||||
if (loop_flag) {
|
if (loop_flag) {
|
||||||
vgmstream->loop_start_sample = (loop_start-1)*16;
|
vgmstream->loop_start_sample = (loop_start-1) * block_align;
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->layout_type = layout_interleave;
|
break;
|
||||||
vgmstream->interleave_block_size = 9;
|
|
||||||
vgmstream->meta_type = meta_FFXI_BGW;
|
case 3: /* ATRAC3 (encrypted) */
|
||||||
|
default:
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
int i;
|
goto fail;
|
||||||
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+i*9;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
fail:
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* .spw (SEWave, PlayOnline viewer for FFXI), very similar to bgw */
|
/* SPW (SEWave) - from PlayOnline viewer for Final Fantasy XI (PC) */
|
||||||
VGMSTREAM * init_vgmstream_spw(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_spw(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
uint32_t codec, filesize, blocksize, sample_rate;
|
||||||
|
int32_t loop_start;
|
||||||
|
uint8_t block_align;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
|
|
||||||
int loop_flag = 0;
|
int channel_count, loop_flag = 0;
|
||||||
int32_t loop_start;
|
|
||||||
int channel_count;
|
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extensions */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
if ( !check_extensions(streamFile, "spw") )
|
||||||
if (strcasecmp("spw",filename_extension(filename))) goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* "SeWave" */
|
/* check header */
|
||||||
if (read_32bitBE(0,streamFile) != 0x53655761 ||
|
if (read_32bitBE(0,streamFile) != 0x53655761 || /* "SeWa" */
|
||||||
read_32bitBE(4,streamFile) != 0x76650000) goto fail;
|
read_32bitBE(4,streamFile) != 0x76650000) /* "ve\0\0" */
|
||||||
|
goto fail;
|
||||||
|
|
||||||
/* check file size with header value */
|
/* check file size with header value */
|
||||||
if (read_32bitLE(0x8,streamFile) != get_streamfile_size(streamFile))
|
if (read_32bitLE(0x8,streamFile) != get_streamfile_size(streamFile))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
channel_count = read_8bit(0x2a,streamFile);
|
filesize = read_32bitLE(0x08,streamFile);
|
||||||
|
codec = read_32bitLE(0x0c,streamFile);
|
||||||
|
/*file_id = read_32bitLE(0x10,streamFile);*/
|
||||||
|
blocksize = read_32bitLE(0x14,streamFile);
|
||||||
loop_start = read_32bitLE(0x18,streamFile);
|
loop_start = read_32bitLE(0x18,streamFile);
|
||||||
|
sample_rate = (read_32bitLE(0x1c,streamFile) + read_32bitLE(0x20,streamFile)) & 0xFFFFFFFF; /* bizarrely obfuscated sample rate */
|
||||||
|
start_offset = read_32bitLE(0x24,streamFile);
|
||||||
|
/*0x2c: unk (0x00?) */
|
||||||
|
/*0x2d: unk (0x00/01?) */
|
||||||
|
channel_count = read_8bit(0x2a,streamFile);
|
||||||
|
block_align = read_8bit(0x2b,streamFile);
|
||||||
|
/*0x2c: unk (0x01 when PCM, 0x10 when VAG?) */
|
||||||
|
|
||||||
|
/* check file size with header value */
|
||||||
|
if (filesize != get_streamfile_size(streamFile))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
loop_flag = (loop_start > 0);
|
loop_flag = (loop_start > 0);
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
|
@ -102,39 +126,47 @@ VGMSTREAM * init_vgmstream_spw(STREAMFILE *streamFile) {
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
start_offset = read_32bitLE(0x24,streamFile);
|
vgmstream->meta_type = meta_FFXI_SPW;
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->sample_rate = sample_rate;
|
||||||
vgmstream->sample_rate = 44100;
|
|
||||||
vgmstream->coding_type = coding_FFXI;
|
switch (codec) {
|
||||||
vgmstream->num_samples = read_32bitLE(0x14,streamFile)*16;
|
case 0: /* PS ADPCM */
|
||||||
|
vgmstream->coding_type = coding_PSX_cfg;
|
||||||
|
vgmstream->layout_type = layout_interleave;
|
||||||
|
vgmstream->interleave_block_size = (block_align / 2) + 1; /* half, even if channels = 1 */
|
||||||
|
|
||||||
|
vgmstream->num_samples = blocksize * block_align;
|
||||||
if (loop_flag) {
|
if (loop_flag) {
|
||||||
vgmstream->loop_start_sample = (loop_start-1)*16;
|
vgmstream->loop_start_sample = (loop_start-1) * block_align;;
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 1: /* PCM */
|
||||||
|
vgmstream->coding_type = coding_PCM16LE;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = 9;
|
vgmstream->interleave_block_size = 0x02;
|
||||||
vgmstream->meta_type = meta_FFXI_SPW;
|
|
||||||
|
vgmstream->num_samples = blocksize;
|
||||||
|
if (loop_flag) {
|
||||||
|
vgmstream->loop_start_sample = (loop_start-1);
|
||||||
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
int i;
|
goto fail;
|
||||||
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+i*9;
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
fail:
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -8,7 +8,6 @@ Wii U boot sound file for each game/app.
|
||||||
VGMSTREAM * init_vgmstream_btsnd(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_btsnd(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
coding_t coding_type;
|
|
||||||
int channel_count = 2;
|
int channel_count = 2;
|
||||||
int loop_flag;
|
int loop_flag;
|
||||||
off_t start_offset = 0x8;
|
off_t start_offset = 0x8;
|
||||||
|
|
|
@ -225,7 +225,7 @@ VGMSTREAM * init_vgmstream_ea(STREAMFILE *streamFile) {
|
||||||
vgmstream->meta_type=meta_EAXA_R2;
|
vgmstream->meta_type=meta_EAXA_R2;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->coding_type=coding_EAXA;
|
vgmstream->coding_type=coding_EA_XA;
|
||||||
vgmstream->layout_type=layout_ea_blocked;
|
vgmstream->layout_type=layout_ea_blocked;
|
||||||
if((vgmstream->ea_platform==EA_GC) || (vgmstream->ea_platform==EA_X360))
|
if((vgmstream->ea_platform==EA_GC) || (vgmstream->ea_platform==EA_X360))
|
||||||
vgmstream->ea_big_endian=1;
|
vgmstream->ea_big_endian=1;
|
||||||
|
|
|
@ -194,57 +194,6 @@ ffmpeg_codec_data * init_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, u
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Manually init FFmpeg, from an offset and creating a fake RIFF from a streamfile.
|
|
||||||
*/
|
|
||||||
ffmpeg_codec_data * init_ffmpeg_faux_riff(STREAMFILE *streamFile, int64_t fmt_offset, uint64_t start, uint64_t size, int big_endian) {
|
|
||||||
if (fmt_offset > 0) {
|
|
||||||
size_t header_size = 0;
|
|
||||||
int max_header_size = (int)(start - fmt_offset);
|
|
||||||
uint8_t p[100];
|
|
||||||
if (max_header_size < 18 || max_header_size > 100)
|
|
||||||
goto fail;
|
|
||||||
//p = av_malloc(max_header_size + 8 + 4 + 8 + 8);
|
|
||||||
//if (!p) goto fail;
|
|
||||||
if (read_streamfile(p + 8 + 4 + 8, fmt_offset, max_header_size, streamFile) != max_header_size)
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
if (big_endian) {
|
|
||||||
int shift = 8 + 4 + 8;
|
|
||||||
put_16bitLE(p+shift, get_16bitBE(p));
|
|
||||||
put_16bitLE(p+shift + 2, get_16bitBE(p + 2));
|
|
||||||
put_32bitLE(p+shift + 4, get_32bitBE(p + 4));
|
|
||||||
put_32bitLE(p+shift + 8, get_32bitBE(p + 8));
|
|
||||||
put_16bitLE(p+shift + 12, get_16bitBE(p + 12));
|
|
||||||
put_16bitLE(p+shift + 14, get_16bitBE(p + 14));
|
|
||||||
put_16bitLE(p+shift + 16, get_16bitBE(p + 16));
|
|
||||||
}
|
|
||||||
header_size = 8 + 4 + 8 + 8 + 18 + get_16bitLE(p + 8 + 4 + 8 + 16);
|
|
||||||
// Meh, dunno how to handle swapping the extra data
|
|
||||||
// FFmpeg doesn't need most of this data anyway
|
|
||||||
if ((unsigned)(get_16bitLE(p + 8 + 4 + 8) - 0x165) < 2)
|
|
||||||
memset(p + 8 + 4 + 8 + 18, 0, 34);
|
|
||||||
|
|
||||||
// Fill out the RIFF structure
|
|
||||||
memcpy(p, "RIFF", 4);
|
|
||||||
put_32bitLE(p + 4, header_size + size - 8);
|
|
||||||
memcpy(p + 8, "WAVE", 4);
|
|
||||||
memcpy(p + 12, "fmt ", 4);
|
|
||||||
put_32bitLE(p + 16, 18 + get_16bitLE(p + 8 + 4 + 8 + 16));
|
|
||||||
memcpy(p + header_size - 8, "data", 4);
|
|
||||||
put_32bitLE(p + header_size - 4, size);
|
|
||||||
|
|
||||||
|
|
||||||
return init_ffmpeg_header_offset(streamFile, p, header_size, start, size);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return init_ffmpeg_header_offset(streamFile, NULL, 0, start, size);
|
|
||||||
}
|
|
||||||
|
|
||||||
fail:
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Manually init FFmpeg, from a fake header / offset.
|
* Manually init FFmpeg, from a fake header / offset.
|
||||||
*
|
*
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -15,7 +15,7 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
|
||||||
int NumSamples;
|
int NumSamples;
|
||||||
int ChannelCount;
|
int ChannelCount;
|
||||||
int SampleRate;
|
int SampleRate;
|
||||||
int DSPInfoStart;
|
int DSPInfoStart = 0;
|
||||||
|
|
||||||
int SampleHeaderStart, SampleHeaderLength, NameTableLength, SampleDataLength, CodingID, SampleMode;
|
int SampleHeaderStart, SampleHeaderLength, NameTableLength, SampleDataLength, CodingID, SampleMode;
|
||||||
int ExtraFlag, ExtraFlagStart, ExtraFlagType, ExtraFlagSize, ExtraFlagEnd;
|
int ExtraFlag, ExtraFlagStart, ExtraFlagType, ExtraFlagSize, ExtraFlagEnd;
|
||||||
|
@ -298,3 +298,155 @@ fail:
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// FSB5 MPEG
|
||||||
|
VGMSTREAM * init_vgmstream_fsb5_mpeg(STREAMFILE *streamFile) {
|
||||||
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
char filename[PATH_LIMIT];
|
||||||
|
off_t start_offset;
|
||||||
|
int channel_count, channels, loop_flag, fsb_mainheader_len, fsb_subheader_len, FSBFlag, rate;
|
||||||
|
long sample_rate = 0, num_samples = 0;
|
||||||
|
uint16_t mp3ID;
|
||||||
|
|
||||||
|
#ifdef VGM_USE_MPEG
|
||||||
|
mpeg_codec_data *mpeg_data = NULL;
|
||||||
|
coding_t mpeg_coding_type = coding_MPEG1_L3;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* check extension, case insensitive */
|
||||||
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
|
if (strcasecmp("fsb",filename_extension(filename))) goto fail;
|
||||||
|
|
||||||
|
/* check header */
|
||||||
|
if (read_32bitBE(0x00,streamFile) == 0x46534235) /* "FSB5" */
|
||||||
|
{
|
||||||
|
fsb_mainheader_len = 0x3C;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
//fsb_subheader_len = read_16bitLE(fsb_mainheader_len,streamFile);
|
||||||
|
|
||||||
|
/* "Check if the FSB is used as conatiner or as single file" */
|
||||||
|
if (read_32bitBE(0x04,streamFile) != 0x01000000)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
/* Check channel count, multi-channel not supported and will be refused */
|
||||||
|
if ((read_16bitLE(0x6E,streamFile) != 0x2) &&
|
||||||
|
(read_16bitLE(0x6E,streamFile) != 0x1))
|
||||||
|
goto fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
start_offset = fsb_mainheader_len+fsb_subheader_len+0x10;
|
||||||
|
|
||||||
|
/* Check the MPEG Sync Header */
|
||||||
|
mp3ID = read_16bitBE(start_offset,streamFile);
|
||||||
|
if ((mp3ID&0xFFE0) != 0xFFE0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
channel_count = read_16bitLE(fsb_mainheader_len+0x3E,streamFile);
|
||||||
|
if (channel_count != 1 && channel_count != 2)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
FSBFlag = read_32bitLE(fsb_mainheader_len+0x30,streamFile);
|
||||||
|
if (FSBFlag&0x2 || FSBFlag&0x4 || FSBFlag&0x6)
|
||||||
|
loop_flag = 1;
|
||||||
|
|
||||||
|
num_samples = (read_32bitLE(fsb_mainheader_len+0x2C,streamFile));
|
||||||
|
|
||||||
|
#ifdef VGM_USE_MPEG
|
||||||
|
mpeg_data = init_mpeg_codec_data(streamFile, start_offset, -1, -1, &mpeg_coding_type, &rate, &channels); // -1 to not check sample rate or channels
|
||||||
|
if (!mpeg_data) goto fail;
|
||||||
|
|
||||||
|
//channel_count = channels;
|
||||||
|
sample_rate = rate;
|
||||||
|
|
||||||
|
#else
|
||||||
|
// reject if no MPEG support
|
||||||
|
goto fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* build the VGMSTREAM */
|
||||||
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
vgmstream->sample_rate = sample_rate;
|
||||||
|
vgmstream->num_samples = num_samples;
|
||||||
|
vgmstream->channels = channel_count;
|
||||||
|
|
||||||
|
/* Still WIP */
|
||||||
|
if (loop_flag) {
|
||||||
|
vgmstream->loop_start_sample = read_32bitLE(fsb_mainheader_len+0x28,streamFile);
|
||||||
|
vgmstream->loop_end_sample = read_32bitLE(fsb_mainheader_len+0x2C,streamFile);
|
||||||
|
}
|
||||||
|
vgmstream->meta_type = meta_FSB_MPEG;
|
||||||
|
|
||||||
|
#ifdef VGM_USE_MPEG
|
||||||
|
/* NOTE: num_samples seems to be quite wrong for MPEG */
|
||||||
|
vgmstream->codec_data = mpeg_data;
|
||||||
|
vgmstream->layout_type = layout_mpeg;
|
||||||
|
vgmstream->coding_type = mpeg_coding_type;
|
||||||
|
#else
|
||||||
|
// reject if no MPEG support
|
||||||
|
goto fail;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
if (loop_flag) {
|
||||||
|
vgmstream->loop_start_sample = read_32bitBE(0x18,streamFile)/960*1152;
|
||||||
|
vgmstream->loop_end_sample = read_32bitBE(0x1C,streamFile)/960*1152;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* open the file for reading */
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
STREAMFILE * file;
|
||||||
|
if(vgmstream->layout_type == layout_interleave)
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#ifdef VGM_USE_MPEG
|
||||||
|
else if(vgmstream->layout_type == layout_mpeg) {
|
||||||
|
for (i=0;i<channel_count;i++) {
|
||||||
|
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,MPEG_BUFFER_SIZE);
|
||||||
|
vgmstream->ch[i].channel_start_offset= vgmstream->ch[i].offset=start_offset;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
else { goto fail; }
|
||||||
|
}
|
||||||
|
|
||||||
|
return vgmstream;
|
||||||
|
|
||||||
|
/* clean up anything we may have opened */
|
||||||
|
fail:
|
||||||
|
#ifdef VGM_USE_MPEG
|
||||||
|
if (mpeg_data) {
|
||||||
|
mpg123_delete(mpeg_data->m);
|
||||||
|
free(mpeg_data);
|
||||||
|
|
||||||
|
if (vgmstream) {
|
||||||
|
vgmstream->codec_data = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
|
@ -1,118 +1,106 @@
|
||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
// Koei Tecmo G1L, found in the Warriors games
|
#include "../coding/coding.h"
|
||||||
VGMSTREAM * init_vgmstream_g1l(STREAMFILE *streamFile) {
|
|
||||||
|
static VGMSTREAM * init_vgmstream_kt_wiibgm_offset(STREAMFILE *streamFile, off_t offset);
|
||||||
|
|
||||||
|
/* Koei Tecmo G1L - pack format, sometimes containing a single stream
|
||||||
|
*
|
||||||
|
* It probably makes more sense to extract it externally, it's here mainly for Hyrule Warriors */
|
||||||
|
VGMSTREAM * init_vgmstream_kt_g1l(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
int type, num_streams, target_stream = 1;
|
||||||
|
off_t stream_offset;
|
||||||
|
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
|
||||||
|
|
||||||
coding_t coding_type;
|
if (!check_extensions(streamFile,"g1l"))
|
||||||
|
|
||||||
off_t head_offset;
|
|
||||||
|
|
||||||
int channel_count;
|
|
||||||
int loop_flag;
|
|
||||||
off_t start_offset;
|
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
|
||||||
streamFile->get_name(streamFile, filename, sizeof(filename));
|
|
||||||
if (strcasecmp("g1l", filename_extension(filename)))
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|
||||||
/* check header */
|
/* check header */
|
||||||
if ((uint32_t)read_32bitBE(0, streamFile) != 0x47314C5F) /* "G1L_" */
|
if ((read_32bitBE(0x0, streamFile) != 0x47314C5F /* "G1L_" (BE) */
|
||||||
|
|| read_32bitBE(0x0, streamFile) != 0x5F4C3147) /* "_L1G" (LE) */
|
||||||
|
&& read_32bitBE(0x4, streamFile) != 0x30303030) /* "0000" (version?) */
|
||||||
goto fail;
|
goto fail;
|
||||||
if ((uint32_t)read_32bitBE(0x1c, streamFile) != 0x57696942) /* "WiiB" */
|
|
||||||
|
if (read_32bitBE(0x0, streamFile) == 0x47314C5F ) {
|
||||||
|
read_32bit = read_32bitBE;
|
||||||
|
} else {
|
||||||
|
read_32bit = read_32bitLE;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* 0x08 filesize */
|
||||||
|
/* 0x0c first file offset (same as 0x18) */
|
||||||
|
type = read_32bit(0x10,streamFile);
|
||||||
|
num_streams = read_32bit(0x14,streamFile);
|
||||||
|
if (target_stream < 0 || target_stream > num_streams) goto fail;
|
||||||
|
if (target_stream==0) target_stream = 1;
|
||||||
|
stream_offset = read_32bit(0x18 + 0x4*(target_stream-1),streamFile);
|
||||||
|
/* filesize = stream_offset - stream_next_offset*/
|
||||||
|
|
||||||
|
switch(type) { /* type may not be correct */
|
||||||
|
case 0x09: /* DSP (WiiBGM) from Hyrule Warriors (Wii U) */
|
||||||
|
vgmstream = init_vgmstream_kt_wiibgm_offset(streamFile, stream_offset);
|
||||||
|
break;
|
||||||
|
case 0x01: /* ATRAC3plus (RIFF) from One Piece Pirate Warriors 2 (PS3) */
|
||||||
|
case 0x00: /* OGG (KOVS) from Romance Three Kindgoms 13 (PC)*/
|
||||||
|
case 0x0A: /* OGG (KOVS) from Dragon Quest Heroes (PC)*/
|
||||||
|
default:
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
return vgmstream;
|
||||||
|
fail:
|
||||||
|
close_vgmstream(vgmstream);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Koei Tecmo "WiiBGM" DSP format - found in Hyrule Warriors, Romance of the Three Kingdoms 12 */
|
||||||
|
VGMSTREAM * init_vgmstream_kt_wiibgm(STREAMFILE *streamFile) {
|
||||||
|
return init_vgmstream_kt_wiibgm_offset(streamFile, 0x0);
|
||||||
|
}
|
||||||
|
|
||||||
|
static VGMSTREAM * init_vgmstream_kt_wiibgm_offset(STREAMFILE *streamFile, off_t offset) {
|
||||||
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
int loop_flag, channel_count;
|
||||||
|
off_t start_offset;
|
||||||
|
|
||||||
|
if (!check_extensions(streamFile,"g1l,dsp"))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (read_32bitBE(offset+0x0, streamFile) != 0x57696942 && /* "WiiB" */
|
||||||
|
read_32bitBE(offset+0x4, streamFile) != 0x474D0000) /* "GM\0\0" */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* check type details */
|
/* check type details */
|
||||||
if (read_32bitBE(0x30, streamFile) > 0)
|
loop_flag = read_32bitBE(offset+0x14, streamFile) > 0;
|
||||||
loop_flag = 1;
|
channel_count = read_8bit(offset+0x23, streamFile);
|
||||||
else
|
|
||||||
loop_flag = 0;
|
|
||||||
channel_count = read_8bit(0x3f, streamFile);
|
|
||||||
|
|
||||||
|
|
||||||
coding_type = coding_NGC_DSP;
|
|
||||||
|
|
||||||
|
|
||||||
if (channel_count < 1) goto fail;
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
|
|
||||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
vgmstream->num_samples = read_32bitBE(0x2c, streamFile);
|
vgmstream->num_samples = read_32bitBE(offset+0x10, streamFile);
|
||||||
vgmstream->sample_rate = (uint16_t)read_16bitBE(0x42, streamFile);
|
vgmstream->sample_rate = (uint16_t)read_16bitBE(offset+0x26, streamFile);
|
||||||
/* channels and loop flag are set by allocate_vgmstream */
|
vgmstream->loop_start_sample = read_32bitBE(offset+0x14, streamFile);
|
||||||
|
|
||||||
vgmstream->loop_start_sample = read_32bitBE(0x30, streamFile);
|
|
||||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||||
|
|
||||||
|
vgmstream->coding_type = coding_NGC_DSP;
|
||||||
vgmstream->coding_type = coding_type;
|
|
||||||
if (channel_count == 1)
|
|
||||||
vgmstream->layout_type = layout_none;
|
|
||||||
|
|
||||||
vgmstream->layout_type = layout_interleave_byte;
|
vgmstream->layout_type = layout_interleave_byte;
|
||||||
|
vgmstream->meta_type = meta_KT_WIIBGM;
|
||||||
vgmstream->meta_type = meta_G1L;
|
|
||||||
|
|
||||||
vgmstream->interleave_block_size = 0x1;
|
vgmstream->interleave_block_size = 0x1;
|
||||||
|
|
||||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
dsp_read_coefs_be(vgmstream,streamFile, offset+0x5C, 0x60);
|
||||||
off_t coef_offset = 0x78;
|
start_offset = offset+0x800;
|
||||||
|
|
||||||
int i, j;
|
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
|
||||||
int coef_spacing = 0x60;
|
|
||||||
|
|
||||||
for (j = 0; j<vgmstream->channels; j++) {
|
|
||||||
for (i = 0; i<16; i++) {
|
|
||||||
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_offset + j*coef_spacing + i * 2, streamFile);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
start_offset = 0x81c;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef VGM_USE_MAIATRAC3PLUS
|
|
||||||
else if (vgmstream->coding_type == coding_AT3plus) {
|
|
||||||
start_offset = 0xc4;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
else
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/* open the file for reading by each channel */
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
for (i = 0; i<channel_count; i++) {
|
|
||||||
if (vgmstream->layout_type == layout_interleave_shortblock)
|
|
||||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile, filename,
|
|
||||||
vgmstream->interleave_block_size);
|
|
||||||
else if (vgmstream->layout_type == layout_interleave)
|
|
||||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile, filename,
|
|
||||||
STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
else
|
|
||||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile, filename,
|
|
||||||
0x1000);
|
|
||||||
|
|
||||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
|
||||||
|
|
||||||
vgmstream->ch[i].channel_start_offset =
|
|
||||||
vgmstream->ch[i].offset =
|
|
||||||
start_offset + i*vgmstream->interleave_block_size;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
fail:
|
||||||
fail:
|
close_vgmstream(vgmstream);
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -215,7 +215,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) {
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
break;
|
break;
|
||||||
case coding_NGC_DTK:
|
case coding_NGC_DTK:
|
||||||
vgmstream->layout_type = layout_dtk_interleave;
|
vgmstream->layout_type = layout_none;
|
||||||
break;
|
break;
|
||||||
case coding_NGC_DSP:
|
case coding_NGC_DSP:
|
||||||
if (dsp_interleave_type == 0) {
|
if (dsp_interleave_type == 0) {
|
||||||
|
|
|
@ -1,112 +1,145 @@
|
||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../layout/layout.h"
|
#include "../layout/layout.h"
|
||||||
#include "../util.h"
|
#include "../coding/coding.h"
|
||||||
|
|
||||||
/* GSP+GSB - 2008-11-28 - manakoAT
|
/* GSP+GSB - from Tecmo's Super Swing Golf 1 & 2 (WII), Quantum Theory (PS3/X360) */
|
||||||
Super Swing Golf 1 & 2 (WII) */
|
|
||||||
VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
STREAMFILE * streamFileGSP = NULL;
|
STREAMFILE * streamFileGSP = NULL;
|
||||||
char filename[PATH_LIMIT];
|
int loop_flag, channel_count;
|
||||||
char filenameGSP[PATH_LIMIT];
|
off_t start_offset, chunk_offset, first_offset;
|
||||||
int channel_count;
|
size_t datasize;
|
||||||
int loop_flag;
|
int codec_id;
|
||||||
int header_len;
|
|
||||||
int i;
|
|
||||||
off_t coef1_start;
|
|
||||||
off_t coef2_start;
|
|
||||||
off_t start_offset;
|
|
||||||
|
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extensions */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
if (!check_extensions(streamFile,"gsb"))
|
||||||
if (strcasecmp("gsb",filename_extension(filename))) goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
streamFileGSP = open_stream_ext(streamFile, "gsp");
|
||||||
strcpy(filenameGSP,filename);
|
|
||||||
strcpy(filenameGSP+strlen(filenameGSP)-3,"gsp");
|
|
||||||
|
|
||||||
streamFileGSP = streamFile->open(streamFile,filenameGSP,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
if (!streamFileGSP) goto fail;
|
if (!streamFileGSP) goto fail;
|
||||||
|
|
||||||
/* check header */
|
/* check header */
|
||||||
if (read_32bitBE(0x00,streamFileGSP) != 0x47534E44) /* "GSND" */
|
if (read_32bitBE(0x00,streamFileGSP) != 0x47534E44) /* "GSND" */
|
||||||
goto fail;
|
goto fail;
|
||||||
|
/* 0x04: version?, 0x08: 1?, 0x0c: 0?, */
|
||||||
|
first_offset = read_32bitBE(0x10,streamFileGSP); /* usually 0x14*/
|
||||||
|
|
||||||
channel_count = (uint16_t)read_16bitBE(0x3A,streamFileGSP);
|
if (!find_chunk_be(streamFileGSP, 0x44415441,first_offset,1, &chunk_offset,NULL)) goto fail; /*"DATA"*/
|
||||||
loop_flag = (read_32bitBE(0x64,streamFileGSP) != 0xFFFFFFFF);
|
channel_count = read_16bitBE(chunk_offset+0x0e,streamFileGSP);
|
||||||
header_len = read_32bitBE(0x1C,streamFileGSP);
|
if (!find_chunk_be(streamFileGSP, 0x42534943,first_offset,1, &chunk_offset,NULL)) goto fail; /*"BSIC"*/
|
||||||
|
loop_flag = read_8bit(chunk_offset+0x0c,streamFileGSP);
|
||||||
coef1_start = header_len-0x4C;
|
|
||||||
coef2_start = header_len-0x1C;
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
|
||||||
vgmstream->channels = channel_count;
|
if (!find_chunk_be(streamFileGSP, 0x48454144,first_offset,1, &chunk_offset,NULL)) goto fail; /*"HEAD"*/
|
||||||
vgmstream->sample_rate = read_32bitBE(0x34,streamFileGSP);
|
/* 0x00: header_size, 0x04: num_chunks */
|
||||||
|
|
||||||
|
if (!find_chunk_be(streamFileGSP, 0x44415441,first_offset,1, &chunk_offset,NULL)) goto fail; /*"DATA"*/
|
||||||
|
/* 0x00: filesize, 0x0c: always 10?, 0x10: always 0?, 0x18: always 0? */
|
||||||
|
datasize = read_32bitBE(chunk_offset+0x00,streamFileGSP);
|
||||||
|
codec_id = read_32bitBE(chunk_offset+0x04,streamFileGSP);
|
||||||
|
vgmstream->sample_rate = read_32bitBE(chunk_offset+0x08,streamFileGSP);
|
||||||
|
vgmstream->channels = channel_count; /* 0x0e */
|
||||||
|
vgmstream->num_samples = read_32bitBE(chunk_offset+0x14,streamFileGSP);
|
||||||
|
/* 0x1c: unk (varies with codec_id) */
|
||||||
|
|
||||||
|
if (!find_chunk_be(streamFileGSP, 0x42534943,first_offset,1, &chunk_offset,NULL)) goto fail; /*"BSIC"*/
|
||||||
|
/* 0x00+: probably volume/pan/etc */
|
||||||
|
vgmstream->loop_start_sample = read_32bitBE(chunk_offset+0x10,streamFileGSP);
|
||||||
|
vgmstream->loop_end_sample = read_32bitBE(chunk_offset+0x14,streamFileGSP);
|
||||||
|
|
||||||
|
//if (!find_chunk_be(streamFileGSP, 0x4E414D45,first_offset,1, &chunk_offset,NULL)) goto fail; /*"NAME"*/
|
||||||
|
/* 0x00: name_size, 0x04+: name*/
|
||||||
|
|
||||||
|
start_offset = 0x0;
|
||||||
|
|
||||||
|
switch (codec_id) {
|
||||||
|
case 4: { /* DSP */
|
||||||
|
size_t block_header_size;
|
||||||
|
size_t num_blocks;
|
||||||
|
|
||||||
vgmstream->coding_type = coding_NGC_DSP;
|
vgmstream->coding_type = coding_NGC_DSP;
|
||||||
if(loop_flag) {
|
vgmstream->layout_type = layout_gsb_blocked;
|
||||||
vgmstream->loop_start_sample = read_32bitBE(0x64,streamFileGSP);
|
|
||||||
vgmstream->loop_end_sample = read_32bitBE(0x68,streamFileGSP);
|
if (!find_chunk_be(streamFileGSP, 0x47434558,first_offset,1, &chunk_offset,NULL)) goto fail; /*"GCEX"*/
|
||||||
|
|
||||||
|
//vgmstream->current_block_size = read_32bitBE(chunk_offset+0x00,streamFileGSP);
|
||||||
|
block_header_size = read_32bitBE(chunk_offset+0x04,streamFileGSP);
|
||||||
|
num_blocks = read_32bitBE(chunk_offset+0x08,streamFileGSP);
|
||||||
|
vgmstream->num_samples = (datasize - block_header_size * num_blocks) / 8 / vgmstream->channels * 14;
|
||||||
|
/* 0x0c+: unk */
|
||||||
|
|
||||||
|
dsp_read_coefs_be(vgmstream, streamFileGSP, chunk_offset+0x18, 0x30);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case 8: { /* ATRAC3 */
|
||||||
|
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||||
|
uint8_t buf[100];
|
||||||
|
int32_t bytes, block_size, encoder_delay, joint_stereo, max_samples;
|
||||||
|
|
||||||
|
block_size = 0x98 * vgmstream->channels;
|
||||||
|
joint_stereo = 0;
|
||||||
|
max_samples = (datasize / block_size) * 1024;
|
||||||
|
encoder_delay = max_samples - vgmstream->num_samples; /* todo guessed */
|
||||||
|
|
||||||
|
vgmstream->num_samples += encoder_delay;
|
||||||
|
/* make a fake riff so FFmpeg can parse the ATRAC3 */
|
||||||
|
bytes = ffmpeg_make_riff_atrac3(buf,100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, encoder_delay);
|
||||||
|
if (bytes <= 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize);
|
||||||
|
if ( !ffmpeg_data ) goto fail;
|
||||||
|
vgmstream->codec_data = ffmpeg_data;
|
||||||
|
vgmstream->coding_type = coding_FFmpeg;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
|
||||||
|
vgmstream->loop_start_sample = (vgmstream->loop_start_sample / ffmpeg_data->blockAlign) * ffmpeg_data->frameSize;
|
||||||
|
vgmstream->loop_end_sample = (vgmstream->loop_end_sample / ffmpeg_data->blockAlign) * ffmpeg_data->frameSize;
|
||||||
|
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (channel_count == 1) {
|
case 9: { /* XMA2 */
|
||||||
vgmstream->layout_type = layout_gsb_blocked;
|
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||||
} else if (channel_count > 1) {
|
uint8_t buf[200];
|
||||||
vgmstream->layout_type = layout_gsb_blocked;
|
int32_t bytes;
|
||||||
vgmstream->interleave_block_size = read_32bitBE(header_len-0x64,streamFileGSP);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!find_chunk_be(streamFileGSP, 0x584D4558,first_offset,1, &chunk_offset,NULL)) goto fail; /*"XMEX"*/
|
||||||
|
/* 0x00: fmt0x166 header (BE), 0x34: seek table */
|
||||||
|
|
||||||
|
bytes = ffmpeg_make_riff_xma2_from_fmt(buf,200, chunk_offset,0x34, datasize, streamFileGSP, 1);
|
||||||
|
if (bytes <= 0) goto fail;
|
||||||
|
|
||||||
|
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize);
|
||||||
|
if ( !ffmpeg_data ) goto fail;
|
||||||
|
vgmstream->codec_data = ffmpeg_data;
|
||||||
|
vgmstream->coding_type = coding_FFmpeg;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
goto fail;
|
||||||
|
}
|
||||||
vgmstream->meta_type = meta_GSP_GSB;
|
vgmstream->meta_type = meta_GSP_GSB;
|
||||||
|
|
||||||
/* open the file for reading by each channel */
|
|
||||||
{
|
|
||||||
for (i=0;i<channel_count;i++) {
|
|
||||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,vgmstream->interleave_block_size);
|
|
||||||
|
|
||||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
/* open the file for reading */
|
||||||
vgmstream->ch[i].channel_start_offset=
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
vgmstream->ch[i].offset=i*vgmstream->interleave_block_size;
|
goto fail;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
|
||||||
int i;
|
|
||||||
for (i=0;i<16;i++) {
|
|
||||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(coef1_start+i*2,streamFileGSP);
|
|
||||||
}
|
|
||||||
if (vgmstream->channels == 2) {
|
|
||||||
for (i=0;i<16;i++) {
|
|
||||||
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(coef2_start+i*2,streamFileGSP);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Calc num_samples */
|
|
||||||
start_offset = 0x0;
|
|
||||||
gsb_block_update(start_offset,vgmstream);
|
|
||||||
vgmstream->num_samples=0;
|
|
||||||
|
|
||||||
do {
|
|
||||||
|
|
||||||
vgmstream->num_samples += vgmstream->current_block_size*14/8;
|
|
||||||
gsb_block_update(vgmstream->next_block_offset,vgmstream);
|
|
||||||
} while (vgmstream->next_block_offset<get_streamfile_size(streamFile));
|
|
||||||
|
|
||||||
gsb_block_update(start_offset,vgmstream);
|
|
||||||
|
|
||||||
close_streamfile(streamFileGSP); streamFileGSP=NULL;
|
|
||||||
|
|
||||||
|
close_streamfile(streamFileGSP);
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
fail:
|
||||||
if (streamFileGSP) close_streamfile(streamFileGSP);
|
if (streamFileGSP) close_streamfile(streamFileGSP);
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -11,7 +11,7 @@ VGMSTREAM * init_vgmstream_mca(STREAMFILE *streamFile) {
|
||||||
int channel_count;
|
int channel_count;
|
||||||
int loop_flag;
|
int loop_flag;
|
||||||
int version;
|
int version;
|
||||||
size_t head_size, data_size;
|
size_t head_size, data_size, file_size;
|
||||||
off_t start_offset, coef_offset, coef_start, coef_shift;
|
off_t start_offset, coef_offset, coef_start, coef_shift;
|
||||||
int i, j;
|
int i, j;
|
||||||
int coef_spacing;
|
int coef_spacing;
|
||||||
|
@ -78,6 +78,16 @@ VGMSTREAM * init_vgmstream_mca(STREAMFILE *streamFile) {
|
||||||
coef_offset = coef_start + coef_shift * 0x14;
|
coef_offset = coef_start + coef_shift * 0x14;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* sanity check */
|
||||||
|
file_size = get_streamfile_size(streamFile);
|
||||||
|
|
||||||
|
if (start_offset + data_size > file_size) {
|
||||||
|
if (head_size + data_size > file_size)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
start_offset = file_size - data_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* set up ADPCM coefs */
|
/* set up ADPCM coefs */
|
||||||
for (j = 0; j<vgmstream->channels; j++) {
|
for (j = 0; j<vgmstream->channels; j++) {
|
||||||
|
|
|
@ -102,21 +102,24 @@ typedef struct {
|
||||||
meta_t meta_type;
|
meta_t meta_type;
|
||||||
layout_t layout_type;
|
layout_t layout_type;
|
||||||
|
|
||||||
// XOR setup with a single byte (SCD)
|
/* XOR setup (SCD) */
|
||||||
unsigned char scd_xor;
|
int decryption_enabled;
|
||||||
off_t scd_xor_len;
|
void (*decryption_callback)(void *ptr, size_t size, size_t nmemb, void *datasource, int bytes_read);
|
||||||
|
uint8_t scd_xor;
|
||||||
|
off_t scd_xor_length;
|
||||||
|
|
||||||
} vgm_vorbis_info_t;
|
} vgm_vorbis_info_t;
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const char * filename, ov_callbacks *callbacks, off_t other_header_bytes, const vgm_vorbis_info_t *vgm_inf);
|
VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const char * filename, ov_callbacks *callbacks, off_t other_header_bytes, const vgm_vorbis_info_t *vgm_inf);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_sli_ogg(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_sli_ogg(STREAMFILE * streamFile);
|
||||||
|
#endif
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_hca(STREAMFILE *streamFile);
|
VGMSTREAM * init_vgmstream_hca(STREAMFILE *streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_hca_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
VGMSTREAM * init_vgmstream_hca_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||||
|
|
||||||
#ifdef VGM_USE_FFMPEG
|
#ifdef VGM_USE_FFMPEG
|
||||||
ffmpeg_codec_data * init_ffmpeg_faux_riff(STREAMFILE *streamFile, int64_t fmt_offset, uint64_t stream_offset, uint64_t stream_size, int fmt_big_endian);
|
|
||||||
ffmpeg_codec_data * init_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
ffmpeg_codec_data * init_ffmpeg_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||||
ffmpeg_codec_data * init_ffmpeg_header_offset(STREAMFILE *streamFile, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size);
|
ffmpeg_codec_data * init_ffmpeg_header_offset(STREAMFILE *streamFile, uint8_t * header, uint64_t header_size, uint64_t start, uint64_t size);
|
||||||
|
|
||||||
|
@ -138,7 +141,6 @@ VGMSTREAM * init_vgmstream_akb(STREAMFILE *streamFile);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_sfl(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_sfl(STREAMFILE * streamFile);
|
||||||
#endif
|
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_sadb(STREAMFILE *streamFile);
|
VGMSTREAM * init_vgmstream_sadb(STREAMFILE *streamFile);
|
||||||
|
|
||||||
|
@ -182,18 +184,12 @@ VGMSTREAM * init_vgmstream_aus(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_rws(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_rws(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_fsb1(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_fsb(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_fsb3(STREAMFILE * streamFile);
|
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_fsb4(STREAMFILE * streamFile);
|
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_fsb4_wav(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_fsb4_wav(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_fsb5(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_fsb5(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_fsb_mpeg(STREAMFILE * streamFile);
|
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_rwx(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_rwx(STREAMFILE * streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_xwb(STREAMFILE * streamFile);
|
VGMSTREAM * init_vgmstream_xwb(STREAMFILE * streamFile);
|
||||||
|
@ -606,7 +602,7 @@ VGMSTREAM * init_vgmstream_ps2_strlr(STREAMFILE* streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_lsf_n1nj4n(STREAMFILE* streamFile);
|
VGMSTREAM * init_vgmstream_lsf_n1nj4n(STREAMFILE* streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_ps3_vawx(STREAMFILE* streamFile);
|
VGMSTREAM * init_vgmstream_vawx(STREAMFILE* streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_pc_snds(STREAMFILE* streamFile);
|
VGMSTREAM * init_vgmstream_pc_snds(STREAMFILE* streamFile);
|
||||||
|
|
||||||
|
@ -654,7 +650,8 @@ VGMSTREAM * init_vgmstream_bfstm(STREAMFILE* streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_bfwav(STREAMFILE* streamFile);
|
VGMSTREAM * init_vgmstream_bfwav(STREAMFILE* streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_g1l(STREAMFILE* streamFile);
|
VGMSTREAM * init_vgmstream_kt_g1l(STREAMFILE* streamFile);
|
||||||
|
VGMSTREAM * init_vgmstream_kt_wiibgm(STREAMFILE* streamFile);
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_mca(STREAMFILE* streamFile);
|
VGMSTREAM * init_vgmstream_mca(STREAMFILE* streamFile);
|
||||||
|
|
||||||
|
@ -666,4 +663,8 @@ VGMSTREAM * init_vgmstream_ps2_svag_snk(STREAMFILE* streamFile);
|
||||||
VGMSTREAM * init_vgmstream_xma(STREAMFILE* streamFile);
|
VGMSTREAM * init_vgmstream_xma(STREAMFILE* streamFile);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
VGMSTREAM * init_vgmstream_ps2_vds_vdm(STREAMFILE* streamFile);
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_x360_cxs(STREAMFILE* streamFile);
|
||||||
|
|
||||||
|
#endif /*_META_H*/
|
||||||
|
|
|
@ -58,7 +58,7 @@ int mp4_file_close( void* handle )
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
MP4FileProvider mp4_file_provider = { mp4_file_open, mp4_file_seek, mp4_file_get_size, mp4_file_read, mp4_file_write, mp4_file_close };
|
MP4FileProvider mp4_file_provider = { mp4_file_open, mp4_file_seek, mp4_file_read, mp4_file_write, mp4_file_close, mp4_file_get_size };
|
||||||
|
|
||||||
#ifdef VGM_USE_FDKAAC
|
#ifdef VGM_USE_FDKAAC
|
||||||
VGMSTREAM * init_vgmstream_mp4_aac_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
VGMSTREAM * init_vgmstream_mp4_aac_offset(STREAMFILE *streamFile, uint64_t start, uint64_t size);
|
||||||
|
|
|
@ -29,7 +29,7 @@ VGMSTREAM * init_vgmstream_ngc_adpdtk(STREAMFILE *streamFile) {
|
||||||
vgmstream->num_samples = file_size/32*28;
|
vgmstream->num_samples = file_size/32*28;
|
||||||
vgmstream->sample_rate = 48000;
|
vgmstream->sample_rate = 48000;
|
||||||
vgmstream->coding_type = coding_NGC_DTK;
|
vgmstream->coding_type = coding_NGC_DTK;
|
||||||
vgmstream->layout_type = layout_dtk_interleave;
|
vgmstream->layout_type = layout_none;
|
||||||
vgmstream->meta_type = meta_NGC_ADPDTK;
|
vgmstream->meta_type = meta_NGC_ADPDTK;
|
||||||
|
|
||||||
/* locality is such that two streamfiles is silly */
|
/* locality is such that two streamfiles is silly */
|
||||||
|
|
|
@ -597,27 +597,26 @@ fail:
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* 3DS IDSP two standard DSP headers (SSB4) */
|
/* IDSP with multiple standard DSP headers - from SSB4 (3DS), Tekken Tag Tournament 2 (Wii U) */
|
||||||
|
#define MULTI_IDSP_MAX_CHANNELS 8
|
||||||
VGMSTREAM * init_vgmstream_3ds_idsp(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_3ds_idsp(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
|
||||||
|
|
||||||
off_t idsp_offset = 0;
|
off_t idsp_offset = 0;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
off_t interleave;
|
off_t interleave;
|
||||||
|
|
||||||
struct dsp_header ch0_header,ch1_header;
|
struct dsp_header ch_headers[MULTI_IDSP_MAX_CHANNELS];
|
||||||
int i;
|
int i, ch;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
//if (check_extensions(streamFile,"idsp")) goto fail;
|
||||||
//if (strcasecmp("idsp",filename_extension(filename))) goto fail;
|
|
||||||
|
|
||||||
/* check header magic */
|
/* check header magic */
|
||||||
if( read_32bitBE(0x0,streamFile) != 0x49445350 )
|
if( read_32bitBE(0x0,streamFile) != 0x49445350 ) /* "IDSP" */
|
||||||
{
|
{
|
||||||
/* check header magic */
|
/* try NUS3 format instead */
|
||||||
if (read_32bitBE(0,streamFile) != 0x4E555333) goto fail; /* "NUS3" */
|
if (read_32bitBE(0,streamFile) != 0x4E555333) goto fail; /* "NUS3" */
|
||||||
|
|
||||||
/* Header size */
|
/* Header size */
|
||||||
|
@ -630,106 +629,87 @@ VGMSTREAM * init_vgmstream_3ds_idsp(STREAMFILE *streamFile) {
|
||||||
idsp_offset += read_32bitLE( 0x3C, streamFile ) + 8;
|
idsp_offset += read_32bitLE( 0x3C, streamFile ) + 8;
|
||||||
idsp_offset += read_32bitLE( 0x44, streamFile ) + 8;
|
idsp_offset += read_32bitLE( 0x44, streamFile ) + 8;
|
||||||
idsp_offset += 8;
|
idsp_offset += 8;
|
||||||
}
|
|
||||||
|
|
||||||
/* check magic */
|
/* check magic */
|
||||||
if (read_32bitBE(idsp_offset,streamFile) != 0x49445350) goto fail; /* "IDSP" */
|
if (read_32bitBE(idsp_offset,streamFile) != 0x49445350) goto fail; /* "IDSP" */
|
||||||
|
|
||||||
channel_count = read_32bitBE(idsp_offset+0x8, streamFile);
|
|
||||||
if(channel_count != 2 && channel_count != 1) goto fail;
|
|
||||||
|
|
||||||
if (read_dsp_header(&ch0_header, idsp_offset+0x40, streamFile)) goto fail;
|
|
||||||
if (channel_count == 2 && read_dsp_header(&ch1_header, idsp_offset+0xa0, streamFile)) goto fail;
|
|
||||||
|
|
||||||
start_offset = read_32bitBE(idsp_offset+0x28,streamFile) + idsp_offset;
|
|
||||||
interleave = 16;
|
|
||||||
|
|
||||||
/* check initial predictor/scale */
|
|
||||||
if (ch0_header.initial_ps != (uint8_t)read_8bit(start_offset,streamFile))
|
|
||||||
goto fail;
|
|
||||||
if (channel_count == 2 && ch1_header.initial_ps != (uint8_t)read_8bit(start_offset+interleave,streamFile))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* check type==0 and gain==0 */
|
|
||||||
if (ch0_header.format || ch0_header.gain ||
|
|
||||||
(channel_count == 2 &&(ch1_header.format || ch1_header.gain)))
|
|
||||||
goto fail;
|
|
||||||
|
|
||||||
/* check for agreement */
|
|
||||||
if ( channel_count == 2 &&(
|
|
||||||
ch0_header.sample_count != ch1_header.sample_count ||
|
|
||||||
ch0_header.nibble_count != ch1_header.nibble_count ||
|
|
||||||
ch0_header.sample_rate != ch1_header.sample_rate ||
|
|
||||||
ch0_header.sample_rate != read_32bitBE(idsp_offset+0xc, streamFile) ||
|
|
||||||
ch0_header.loop_flag != ch1_header.loop_flag ||
|
|
||||||
ch0_header.loop_start_offset != ch1_header.loop_start_offset ||
|
|
||||||
ch0_header.loop_end_offset != ch1_header.loop_end_offset
|
|
||||||
)) goto fail;
|
|
||||||
|
|
||||||
if (ch0_header.loop_flag) {
|
|
||||||
off_t loop_off;
|
|
||||||
/* check loop predictor/scale */
|
|
||||||
loop_off = ch0_header.loop_start_offset/8/channel_count*8;
|
|
||||||
loop_off = (loop_off/interleave*interleave*channel_count) + (loop_off%interleave);
|
|
||||||
if (ch0_header.loop_ps != (uint8_t)read_8bit(start_offset+loop_off,streamFile))
|
|
||||||
goto fail;
|
|
||||||
if (channel_count == 2 &&
|
|
||||||
ch1_header.loop_ps != (uint8_t)read_8bit(start_offset+loop_off+interleave,streamFile))
|
|
||||||
goto fail;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
channel_count = read_32bitBE(idsp_offset+0x8, streamFile);
|
||||||
|
if (channel_count > MULTI_IDSP_MAX_CHANNELS) goto fail;
|
||||||
|
|
||||||
vgmstream = allocate_vgmstream(channel_count,ch0_header.loop_flag);
|
start_offset = read_32bitBE(idsp_offset+0x28,streamFile) + idsp_offset;
|
||||||
|
interleave = 0x10;
|
||||||
|
|
||||||
|
/* read standard dsp header per channel and do some validations */
|
||||||
|
for (ch=0; ch < channel_count; ch++) {
|
||||||
|
/* read 0x60 header per channel */
|
||||||
|
if (read_dsp_header(&ch_headers[ch], idsp_offset + 0x40 + 0x60*ch, streamFile)) goto fail;
|
||||||
|
|
||||||
|
/* check initial values */
|
||||||
|
if (ch_headers[ch].initial_ps != (uint8_t)read_8bit(start_offset + interleave*ch, streamFile)) goto fail;
|
||||||
|
if (ch_headers[ch].format || ch_headers[ch].gain) goto fail;
|
||||||
|
|
||||||
|
/* check for agreement with prev channel*/
|
||||||
|
if (ch > 0 && (
|
||||||
|
ch_headers[ch].sample_count != ch_headers[ch-1].sample_count ||
|
||||||
|
ch_headers[ch].nibble_count != ch_headers[ch-1].nibble_count ||
|
||||||
|
ch_headers[ch].sample_rate != ch_headers[ch-1].sample_rate ||
|
||||||
|
ch_headers[ch].loop_flag != ch_headers[ch-1].loop_flag ||
|
||||||
|
ch_headers[ch].loop_start_offset != ch_headers[ch-1].loop_start_offset ||
|
||||||
|
ch_headers[ch].loop_end_offset != ch_headers[ch-1].loop_end_offset
|
||||||
|
)) goto fail;
|
||||||
|
|
||||||
|
|
||||||
|
#if 0 //this is wrong for >2ch and will fail
|
||||||
|
/* check loop predictor/scale */
|
||||||
|
if (ch_headers[ch].loop_flag) {
|
||||||
|
off_t loop_off;
|
||||||
|
loop_off = ch_headers[ch].loop_start_offset / 8 / channel_count * 8;
|
||||||
|
loop_off = (loop_off / interleave * interleave * channel_count) + (loop_off%interleave);
|
||||||
|
VGM_LOG("loop_ps=%lx, loop_off=%lx\n", ch_headers[ch].loop_ps, loop_off);
|
||||||
|
if (ch_headers[ch].loop_ps != (uint8_t)read_8bit(start_offset + loop_off + interleave*ch, streamFile)) goto fail;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
/* check first channel (implicitly all ch) agree with main sample rate */
|
||||||
|
if (ch_headers[0].sample_rate != read_32bitBE(idsp_offset+0xc, streamFile)) goto fail;
|
||||||
|
|
||||||
|
|
||||||
|
/* build the VGMSTREAM */
|
||||||
|
vgmstream = allocate_vgmstream(channel_count,ch_headers[0].loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
vgmstream->num_samples = ch_headers[0].sample_count;
|
||||||
vgmstream->num_samples = ch0_header.sample_count;
|
vgmstream->sample_rate = ch_headers[0].sample_rate;
|
||||||
vgmstream->sample_rate = ch0_header.sample_rate;
|
|
||||||
|
|
||||||
/* TODO: adjust for interleave? */
|
/* TODO: adjust for interleave? */
|
||||||
vgmstream->loop_start_sample = dsp_nibbles_to_samples(
|
vgmstream->loop_start_sample = dsp_nibbles_to_samples(ch_headers[0].loop_start_offset);
|
||||||
ch0_header.loop_start_offset);
|
vgmstream->loop_end_sample = dsp_nibbles_to_samples(ch_headers[0].loop_end_offset) + 1;
|
||||||
vgmstream->loop_end_sample = dsp_nibbles_to_samples(
|
|
||||||
ch0_header.loop_end_offset)+1;
|
|
||||||
|
|
||||||
vgmstream->coding_type = coding_NGC_DSP;
|
vgmstream->coding_type = coding_NGC_DSP;
|
||||||
vgmstream->layout_type = channel_count == 2 ? layout_interleave : layout_none;
|
vgmstream->layout_type = channel_count > 1 ? layout_interleave : layout_none;
|
||||||
vgmstream->interleave_block_size = interleave;
|
vgmstream->interleave_block_size = interleave;
|
||||||
vgmstream->meta_type = meta_3DS_IDSP;
|
vgmstream->meta_type = meta_3DS_IDSP;
|
||||||
|
|
||||||
/* coeffs */
|
|
||||||
|
/* set DSP coefs/history */
|
||||||
|
for (ch=0; ch < channel_count; ch++) {
|
||||||
for (i=0;i<16;i++) {
|
for (i=0;i<16;i++) {
|
||||||
vgmstream->ch[0].adpcm_coef[i] = ch0_header.coef[i];
|
vgmstream->ch[ch].adpcm_coef[i] = ch_headers[ch].coef[i];
|
||||||
if (channel_count == 2)
|
|
||||||
vgmstream->ch[1].adpcm_coef[i] = ch1_header.coef[i];
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initial history */
|
|
||||||
/* always 0 that I've ever seen, but for completeness... */
|
/* always 0 that I've ever seen, but for completeness... */
|
||||||
vgmstream->ch[0].adpcm_history1_16 = ch0_header.initial_hist1;
|
vgmstream->ch[ch].adpcm_history1_16 = ch_headers[ch].initial_hist1;
|
||||||
vgmstream->ch[0].adpcm_history2_16 = ch0_header.initial_hist2;
|
vgmstream->ch[ch].adpcm_history2_16 = ch_headers[ch].initial_hist2;
|
||||||
|
|
||||||
vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
|
||||||
|
|
||||||
if (channel_count == 2) {
|
|
||||||
vgmstream->ch[1].adpcm_history1_16 = ch1_header.initial_hist1;
|
|
||||||
vgmstream->ch[1].adpcm_history2_16 = ch1_header.initial_hist2;
|
|
||||||
vgmstream->ch[1].streamfile = vgmstream->ch[0].streamfile;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!vgmstream->ch[0].streamfile) goto fail;
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
for (i=0;i<channel_count;i++) {
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
vgmstream->ch[i].channel_start_offset=
|
goto fail;
|
||||||
vgmstream->ch[i].offset=start_offset+i*interleave;
|
|
||||||
}
|
|
||||||
|
|
||||||
return vgmstream;
|
return vgmstream;
|
||||||
|
|
||||||
fail:
|
fail:
|
||||||
/* clean up anything we may have opened */
|
close_vgmstream(vgmstream);
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2686,9 +2666,9 @@ VGMSTREAM * init_vgmstream_ngc_dsp_csmp(STREAMFILE *streamFile) {
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (header.loop_flag) {
|
if (header.loop_flag) {
|
||||||
off_t loop_off;
|
// off_t loop_off;
|
||||||
/* check loop predictor/scale */
|
/* check loop predictor/scale */
|
||||||
loop_off = header.loop_start_offset/16*8;
|
// loop_off = header.loop_start_offset/16*8;
|
||||||
/* Retro doesn't seem to abide by this */
|
/* Retro doesn't seem to abide by this */
|
||||||
// if (header.loop_ps != (uint8_t)read_8bit(current_offset + start_offset+loop_off,streamFile))
|
// if (header.loop_ps != (uint8_t)read_8bit(current_offset + start_offset+loop_off,streamFile))
|
||||||
// goto fail;
|
// goto fail;
|
||||||
|
|
|
@ -92,14 +92,9 @@ static size_t read_func_scd(void *ptr, size_t size, size_t nmemb, void * datasou
|
||||||
|
|
||||||
items_read = bytes_read / size;
|
items_read = bytes_read / size;
|
||||||
|
|
||||||
/* first bytes are xor'd with a constant byte */
|
/* may be encrypted */
|
||||||
if (ov_streamfile->offset < ov_streamfile->scd_xor_len) {
|
if (ov_streamfile->decryption_enabled) {
|
||||||
int num_crypt = ov_streamfile->scd_xor_len-ov_streamfile->offset;
|
ov_streamfile->decryption_callback(ptr, size, nmemb, ov_streamfile, bytes_read);
|
||||||
int i;
|
|
||||||
|
|
||||||
if (num_crypt > bytes_read) num_crypt=bytes_read;
|
|
||||||
for (i=0;i<num_crypt;i++)
|
|
||||||
((uint8_t*)ptr)[i] ^= ov_streamfile->scd_xor;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
ov_streamfile->offset += items_read * size;
|
ov_streamfile->offset += items_read * size;
|
||||||
|
@ -238,13 +233,13 @@ VGMSTREAM * init_vgmstream_ogg_vorbis(STREAMFILE *streamFile) {
|
||||||
callbacks.tell_func = tell_func;
|
callbacks.tell_func = tell_func;
|
||||||
|
|
||||||
if (um3_ogg) {
|
if (um3_ogg) {
|
||||||
inf.meta_type = meta_um3_ogg;
|
inf.meta_type = meta_OGG_UM3;
|
||||||
} else if (kovs_ogg) {
|
} else if (kovs_ogg) {
|
||||||
inf.meta_type = meta_KOVS_ogg;
|
inf.meta_type = meta_OGG_KOVS;
|
||||||
} else if (psych_ogg) {
|
} else if (psych_ogg) {
|
||||||
inf.meta_type = meta_psych_ogg;
|
inf.meta_type = meta_OGG_PSYCH;
|
||||||
} else {
|
} else {
|
||||||
inf.meta_type = meta_ogg_vorbis;
|
inf.meta_type = meta_OGG_VORBIS;
|
||||||
}
|
}
|
||||||
|
|
||||||
inf.layout_type = layout_ogg_vorbis;
|
inf.layout_type = layout_ogg_vorbis;
|
||||||
|
@ -281,7 +276,7 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
|
||||||
default_callbacks.close_func = close_func;
|
default_callbacks.close_func = close_func;
|
||||||
default_callbacks.tell_func = tell_func;
|
default_callbacks.tell_func = tell_func;
|
||||||
|
|
||||||
if (vgm_inf->scd_xor != 0) {
|
if (vgm_inf->decryption_enabled) {
|
||||||
default_callbacks.read_func = read_func_scd;
|
default_callbacks.read_func = read_func_scd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -292,8 +287,10 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
|
||||||
temp_streamfile.offset = 0;
|
temp_streamfile.offset = 0;
|
||||||
temp_streamfile.size = get_streamfile_size(temp_streamfile.streamfile);
|
temp_streamfile.size = get_streamfile_size(temp_streamfile.streamfile);
|
||||||
temp_streamfile.other_header_bytes = other_header_bytes;
|
temp_streamfile.other_header_bytes = other_header_bytes;
|
||||||
|
temp_streamfile.decryption_enabled = vgm_inf->decryption_enabled;
|
||||||
|
temp_streamfile.decryption_callback = vgm_inf->decryption_callback;
|
||||||
temp_streamfile.scd_xor = vgm_inf->scd_xor;
|
temp_streamfile.scd_xor = vgm_inf->scd_xor;
|
||||||
temp_streamfile.scd_xor_len = vgm_inf->scd_xor_len;
|
temp_streamfile.scd_xor_length = vgm_inf->scd_xor_length;
|
||||||
|
|
||||||
/* can we open this as a proper ogg vorbis file? */
|
/* can we open this as a proper ogg vorbis file? */
|
||||||
memset(&temp_ovf, 0, sizeof(temp_ovf));
|
memset(&temp_ovf, 0, sizeof(temp_ovf));
|
||||||
|
@ -314,8 +311,10 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
|
||||||
data->ov_streamfile.offset = 0;
|
data->ov_streamfile.offset = 0;
|
||||||
data->ov_streamfile.size = get_streamfile_size(data->ov_streamfile.streamfile);
|
data->ov_streamfile.size = get_streamfile_size(data->ov_streamfile.streamfile);
|
||||||
data->ov_streamfile.other_header_bytes = other_header_bytes;
|
data->ov_streamfile.other_header_bytes = other_header_bytes;
|
||||||
|
data->ov_streamfile.decryption_enabled = vgm_inf->decryption_enabled;
|
||||||
|
data->ov_streamfile.decryption_callback = vgm_inf->decryption_callback;
|
||||||
data->ov_streamfile.scd_xor = vgm_inf->scd_xor;
|
data->ov_streamfile.scd_xor = vgm_inf->scd_xor;
|
||||||
data->ov_streamfile.scd_xor_len = vgm_inf->scd_xor_len;
|
data->ov_streamfile.scd_xor_length = vgm_inf->scd_xor_length;
|
||||||
|
|
||||||
/* open the ogg vorbis file for real */
|
/* open the ogg vorbis file for real */
|
||||||
if (ov_open_callbacks(&data->ov_streamfile, &data->ogg_vorbis_file, NULL,
|
if (ov_open_callbacks(&data->ov_streamfile, &data->ogg_vorbis_file, NULL,
|
||||||
|
|
|
@ -0,0 +1,48 @@
|
||||||
|
#include "meta.h"
|
||||||
|
|
||||||
|
/* VDS/VDM - from Grafitti Kingdom / Rakugaki Oukoku 2 */
|
||||||
|
VGMSTREAM * init_vgmstream_ps2_vds_vdm(STREAMFILE *streamFile) {
|
||||||
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
off_t start_offset;
|
||||||
|
int loop_flag, channel_count;
|
||||||
|
|
||||||
|
/* check extension, case insensitive */
|
||||||
|
if ( !check_extensions(streamFile,"vds,vdm"))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (read_32bitBE(0x00,streamFile) != 0x56445320 && /* "VDS " (music)*/
|
||||||
|
read_32bitBE(0x00,streamFile) != 0x56444D20) /* "VDM " (voices) */
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
loop_flag = read_8bit(0x20,streamFile);
|
||||||
|
channel_count = read_32bitLE(0x10,streamFile);
|
||||||
|
|
||||||
|
/* build the VGMSTREAM */
|
||||||
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
vgmstream->coding_type = coding_PSX;
|
||||||
|
vgmstream->layout_type = channel_count > 1 ? layout_interleave : layout_none;
|
||||||
|
vgmstream->meta_type = meta_PS2_VDS_VDM;
|
||||||
|
|
||||||
|
start_offset = 0x800;
|
||||||
|
vgmstream->num_samples = read_32bitLE(0x04,streamFile) * 28 / 16 / channel_count;
|
||||||
|
/* 0x08: unknown, always 10 */
|
||||||
|
vgmstream->sample_rate = read_32bitLE(0x0c,streamFile);
|
||||||
|
vgmstream->channels = channel_count; /*0x10*/
|
||||||
|
vgmstream->interleave_block_size = read_32bitLE(0x14,streamFile);
|
||||||
|
vgmstream->loop_start_sample = (read_32bitLE(0x18,streamFile) - start_offset) * 28 / 16 / channel_count;
|
||||||
|
vgmstream->loop_end_sample = (read_32bitLE(0x1c,streamFile) - start_offset) * 28 / 16 / channel_count;
|
||||||
|
vgmstream->loop_flag = loop_flag; /*0x20*/
|
||||||
|
/*0x21: volume? */
|
||||||
|
/*0x22: pan? */
|
||||||
|
/*0x23: 02=VDS 04=VDM? */
|
||||||
|
|
||||||
|
/* open the file for reading */
|
||||||
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
|
goto fail;
|
||||||
|
return vgmstream;
|
||||||
|
|
||||||
|
fail:
|
||||||
|
close_vgmstream(vgmstream);
|
||||||
|
return NULL;
|
||||||
|
}
|
|
@ -33,7 +33,7 @@ VGMSTREAM * init_vgmstream_ps2_bmdx(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
/* Check for Compression Scheme */
|
/* Check for Compression Scheme */
|
||||||
if (read_32bitLE(0x20,streamFile) == 1)
|
if (read_32bitLE(0x20,streamFile) == 1)
|
||||||
vgmstream->coding_type = coding_invert_PSX;
|
vgmstream->coding_type = coding_PSX_bmdx;
|
||||||
else
|
else
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = read_32bitLE(0x0c,streamFile)*28/16/channel_count;
|
vgmstream->num_samples = read_32bitLE(0x0c,streamFile)*28/16/channel_count;
|
||||||
|
@ -55,7 +55,7 @@ VGMSTREAM * init_vgmstream_ps2_bmdx(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
start_offset = read_32bitLE(0x08,streamFile);
|
start_offset = read_32bitLE(0x08,streamFile);
|
||||||
|
|
||||||
if (vgmstream->coding_type == coding_invert_PSX)
|
if (vgmstream->coding_type == coding_PSX_bmdx)
|
||||||
{
|
{
|
||||||
uint8_t xor = read_8bit(start_offset,streamFile);
|
uint8_t xor = read_8bit(start_offset,streamFile);
|
||||||
uint8_t add = (~(uint8_t)read_8bit(start_offset+2,streamFile))+1;
|
uint8_t add = (~(uint8_t)read_8bit(start_offset+2,streamFile))+1;
|
||||||
|
|
|
@ -91,6 +91,8 @@ VGMSTREAM * init_vgmstream_ps2_mib(STREAMFILE *streamFile) {
|
||||||
fileLength = get_streamfile_size(streamFile);
|
fileLength = get_streamfile_size(streamFile);
|
||||||
|
|
||||||
readOffset+=(off_t)read_streamfile(mibBuffer,0,0x10,streamFile);
|
readOffset+=(off_t)read_streamfile(mibBuffer,0,0x10,streamFile);
|
||||||
|
readOffset=0;
|
||||||
|
mibBuffer[0]=0;
|
||||||
|
|
||||||
do {
|
do {
|
||||||
readOffset+=(off_t)read_streamfile(testBuffer,readOffset,0x10,streamFile);
|
readOffset+=(off_t)read_streamfile(testBuffer,readOffset,0x10,streamFile);
|
||||||
|
@ -106,6 +108,7 @@ VGMSTREAM * init_vgmstream_ps2_mib(STREAMFILE *streamFile) {
|
||||||
bDoUpdateInterleave=1;
|
bDoUpdateInterleave=1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testBuffer[0]=0;
|
||||||
if(!memcmp(testBuffer,mibBuffer,0x10)) {
|
if(!memcmp(testBuffer,mibBuffer,0x10)) {
|
||||||
|
|
||||||
gotEmptyLine=1;
|
gotEmptyLine=1;
|
||||||
|
|
|
@ -1,8 +1,9 @@
|
||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../util.h"
|
#include "../util.h"
|
||||||
|
|
||||||
/* Sony .ADS with SShd & SSbd Headers */
|
/* NPFS - found in Namco PS2/PSP games:
|
||||||
|
* Tekken 5, Ace Combat 5, Yumeria, Venus & Braves (.nps), Ridge Racer PSP, etc
|
||||||
|
*/
|
||||||
VGMSTREAM * init_vgmstream_ps2_npsf(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_ps2_npsf(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
|
@ -14,7 +15,9 @@ VGMSTREAM * init_vgmstream_ps2_npsf(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
if (strcasecmp("npsf",filename_extension(filename))) goto fail;
|
if (strcasecmp("npsf",filename_extension(filename)) &&
|
||||||
|
strcasecmp("nps",filename_extension(filename)))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
/* check NPSF Header */
|
/* check NPSF Header */
|
||||||
if (read_32bitBE(0x00,streamFile) != 0x4E505346)
|
if (read_32bitBE(0x00,streamFile) != 0x4E505346)
|
||||||
|
|
|
@ -1,5 +1,4 @@
|
||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../util.h"
|
|
||||||
|
|
||||||
|
|
||||||
static int vag_find_loop_offsets(STREAMFILE *streamFile, off_t start_offset, off_t * loop_start, off_t * loop_end);
|
static int vag_find_loop_offsets(STREAMFILE *streamFile, off_t start_offset, off_t * loop_start, off_t * loop_end);
|
||||||
|
@ -9,38 +8,38 @@ static int vag_find_loop_offsets(STREAMFILE *streamFile, off_t start_offset, off
|
||||||
*/
|
*/
|
||||||
VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
off_t start_offset, loopStart = 0, loopEnd = 0;
|
||||||
|
|
||||||
off_t loopStart = 0;
|
|
||||||
off_t loopEnd = 0;
|
|
||||||
|
|
||||||
uint8_t vagID;
|
uint8_t vagID;
|
||||||
uint32_t version = 0;
|
uint32_t version = 0;
|
||||||
|
|
||||||
size_t filesize = 0, datasize = 0;
|
size_t filesize = 0, datasize = 0, interleave;
|
||||||
size_t interleave;
|
|
||||||
off_t start_offset;
|
|
||||||
|
|
||||||
int loop_flag=0;
|
int loop_flag = 0, loop_samples_found = 0;
|
||||||
int loop_samples_found = 0;
|
int channel_count = 0;
|
||||||
int channel_count=0;
|
int is_swag = 0;
|
||||||
int i;
|
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
/* check extension, case insensitive */
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
if ( !check_extensions(streamFile,"vag,swag") )
|
||||||
if (strcasecmp("vag",filename_extension(filename))) goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* check VAG Header */
|
/* check VAG Header */
|
||||||
if (((read_32bitBE(0x00,streamFile) & 0xFFFFFF00) != 0x56414700) && /* "VAG\0" */
|
if (((read_32bitBE(0x00,streamFile) & 0xFFFFFF00) != 0x56414700) && /* "VAG" */
|
||||||
((read_32bitLE(0x00,streamFile) & 0xFFFFFF00) != 0x56414700))
|
((read_32bitLE(0x00,streamFile) & 0xFFFFFF00) != 0x56414700))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
|
/* Frantix VAGp .swag: some (not all) fields in LE + 2 VAGp in the same file (full interleave) */
|
||||||
|
is_swag = check_extensions(streamFile,"swag");
|
||||||
|
|
||||||
filesize = get_streamfile_size(streamFile);
|
filesize = get_streamfile_size(streamFile);
|
||||||
|
|
||||||
/* version used to create the file
|
/* version used to create the file
|
||||||
* ex: 00000000 = v1.8 PC, 00000002 = v1.3 Mac, 00000003 = v1.6+ Mac, 00000020 = v2.0+ PC */
|
* ex: 00000000 = v1.8 PC, 00000002 = v1.3 Mac, 00000003 = v1.6+ Mac, 00000020 = v2.0+ PC */
|
||||||
version = read_32bitBE(0x04,streamFile);
|
version = read_32bitBE(0x04,streamFile);
|
||||||
/* 0x08-0c: reserved */
|
/* 0x08-0c: reserved */
|
||||||
|
if (is_swag)
|
||||||
|
datasize = read_32bitLE(0x0c,streamFile);
|
||||||
|
else
|
||||||
datasize = read_32bitBE(0x0c,streamFile);
|
datasize = read_32bitBE(0x0c,streamFile);
|
||||||
/* 0x14-20 reserved */
|
/* 0x14-20 reserved */
|
||||||
/* 0x20-30: name (optional) */
|
/* 0x20-30: name (optional) */
|
||||||
|
@ -66,8 +65,11 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||||
break;
|
break;
|
||||||
case 'p': /* "VAGp" (extended) [most common, ex Ratchet & Clank] */
|
case 'p': /* "VAGp" (extended) [most common, ex Ratchet & Clank] */
|
||||||
|
|
||||||
if ((version <= 0x00000004) && (datasize < filesize / 2)) {
|
if ((version <= 0x00000004) && (datasize < filesize / 2)) { /* two VAGp in the same file */
|
||||||
loop_flag=(read_32bitBE(0x14,streamFile)!=0);
|
if (is_swag)
|
||||||
|
loop_flag = vag_find_loop_offsets(streamFile, 0x30, &loopStart, &loopEnd);
|
||||||
|
else
|
||||||
|
loop_flag = read_32bitBE(0x14,streamFile) != 0;
|
||||||
channel_count=2;
|
channel_count=2;
|
||||||
}
|
}
|
||||||
else if (version == 0x00020001) { /* HEVAG */
|
else if (version == 0x00020001) { /* HEVAG */
|
||||||
|
@ -91,6 +93,9 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* fill in the vital statistics */
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
|
if (is_swag)
|
||||||
|
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
||||||
|
else
|
||||||
vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
|
vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
|
||||||
|
|
||||||
switch(vagID) {
|
switch(vagID) {
|
||||||
|
@ -121,18 +126,24 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||||
|
|
||||||
if ((version == 0x00000004) && (datasize < filesize / 2)) {
|
if ((version == 0x00000004) && (datasize < filesize / 2)) {
|
||||||
vgmstream->channels=2;
|
vgmstream->channels=2;
|
||||||
vgmstream->num_samples = datasize; /* todo test if datasize/16*28? */
|
vgmstream->layout_type=layout_interleave;
|
||||||
|
vgmstream->meta_type=meta_PS2_VAGs;
|
||||||
|
|
||||||
|
if (is_swag) {
|
||||||
|
start_offset = 0x30;
|
||||||
|
interleave = datasize;
|
||||||
|
vgmstream->num_samples = datasize / 16 * 28;
|
||||||
|
vgmstream->loop_start_sample = (loopStart-start_offset) / 16 * 28;
|
||||||
|
vgmstream->loop_end_sample = (loopEnd-start_offset) / 16 * 28;
|
||||||
|
loop_samples_found = 1;
|
||||||
|
|
||||||
|
} else {
|
||||||
|
start_offset=0x80;
|
||||||
|
vgmstream->num_samples = datasize; /* todo test if datasize/16*28? */
|
||||||
if(loop_flag) {
|
if(loop_flag) {
|
||||||
vgmstream->loop_start_sample=read_32bitBE(0x14,streamFile);
|
vgmstream->loop_start_sample=read_32bitBE(0x14,streamFile);
|
||||||
vgmstream->loop_end_sample =read_32bitBE(0x18,streamFile);
|
vgmstream->loop_end_sample =read_32bitBE(0x18,streamFile);
|
||||||
loop_samples_found = 1;
|
loop_samples_found = 1;
|
||||||
}
|
|
||||||
|
|
||||||
start_offset=0x80;
|
|
||||||
vgmstream->layout_type=layout_interleave;
|
|
||||||
vgmstream->meta_type=meta_PS2_VAGs;
|
|
||||||
|
|
||||||
// Double VAG Header @ 0x0000 & 0x1000
|
// Double VAG Header @ 0x0000 & 0x1000
|
||||||
if(read_32bitBE(0,streamFile)==read_32bitBE(0x1000,streamFile)) {
|
if(read_32bitBE(0,streamFile)==read_32bitBE(0x1000,streamFile)) {
|
||||||
vgmstream->num_samples = datasize / 16 * 28;
|
vgmstream->num_samples = datasize / 16 * 28;
|
||||||
|
@ -140,6 +151,8 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||||
start_offset=0;
|
start_offset=0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (version == 0x40000000) { /* Guerilla VAG (little endian) */
|
else if (version == 0x40000000) { /* Guerilla VAG (little endian) */
|
||||||
datasize = read_32bitLE(0x0c,streamFile);
|
datasize = read_32bitLE(0x0c,streamFile);
|
||||||
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
|
||||||
|
@ -150,7 +163,7 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||||
start_offset = 0x30;
|
start_offset = 0x30;
|
||||||
}
|
}
|
||||||
else if (version == 0x00020001) { /* HEVAG */
|
else if (version == 0x00020001) { /* HEVAG */
|
||||||
vgmstream->coding_type = coding_HEVAG_ADPCM;
|
vgmstream->coding_type = coding_HEVAG;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->meta_type = meta_PS2_VAGs;
|
vgmstream->meta_type = meta_PS2_VAGs;
|
||||||
|
|
||||||
|
@ -195,28 +208,14 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* open the file for reading by each channel */
|
/* open the file for reading */
|
||||||
{
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
for (i=0;i<channel_count;i++) {
|
goto fail;
|
||||||
if (vgmstream->interleave_block_size > 0) {
|
|
||||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,vgmstream->interleave_block_size);
|
|
||||||
} else {
|
|
||||||
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;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
fail:
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -10,8 +10,8 @@ VGMSTREAM * init_vgmstream_ps3_klbs(STREAMFILE *streamFile)
|
||||||
size_t fileLength;
|
size_t fileLength;
|
||||||
off_t readOffset = 0;
|
off_t readOffset = 0;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
off_t loop_start_offset;
|
off_t loop_start_offset = 0;
|
||||||
off_t loop_end_offset;
|
off_t loop_end_offset = 0;
|
||||||
|
|
||||||
uint8_t testBuffer[0x10];
|
uint8_t testBuffer[0x10];
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
|
|
|
@ -228,7 +228,7 @@ fail:
|
||||||
#ifdef VGM_USE_FFMPEG
|
#ifdef VGM_USE_FFMPEG
|
||||||
if (ffmpeg_data) {
|
if (ffmpeg_data) {
|
||||||
free_ffmpeg(ffmpeg_data);
|
free_ffmpeg(ffmpeg_data);
|
||||||
vgmstream->codec_data = NULL;
|
if (vgmstream) vgmstream->codec_data = NULL;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
if (vgmstream) close_vgmstream(vgmstream);
|
||||||
|
|
|
@ -195,7 +195,7 @@ VGMSTREAM * init_vgmstream_ps3_sgdx(STREAMFILE *streamFile) {
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
case 0x05: /* Short VAG ADPCM */
|
case 0x05: /* Short VAG ADPCM */
|
||||||
vgmstream->coding_type = coding_SHORT_VAG_ADPCM;
|
vgmstream->coding_type = coding_PSX_cfg;
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = 0x4;
|
vgmstream->interleave_block_size = 0x4;
|
||||||
|
|
||||||
|
|
|
@ -1,77 +1,124 @@
|
||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../util.h"
|
#include "../coding/coding.h"
|
||||||
|
|
||||||
/* VAWX
|
#define FAKE_RIFF_BUFFER_SIZE 100
|
||||||
- No More Heroes: Heroes Paradise (PS3)
|
|
||||||
*/
|
/**
|
||||||
VGMSTREAM * init_vgmstream_ps3_vawx(STREAMFILE *streamFile)
|
* VAWX - found in feelplus games: No More Heroes Heroes Paradise, Moon Diver
|
||||||
{
|
*/
|
||||||
|
VGMSTREAM * init_vgmstream_vawx(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
off_t start_offset, datasize;
|
||||||
|
|
||||||
off_t start_offset;
|
int loop_flag = 0, channel_count, type;
|
||||||
|
|
||||||
int loop_flag = 0;
|
/* check extensions */
|
||||||
int channel_count;
|
if ( !check_extensions(streamFile, "vawx,xwv") )
|
||||||
|
|
||||||
/* check extension, case insensitive */
|
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
|
||||||
if (strcasecmp("vawx",filename_extension(filename))) goto fail;
|
|
||||||
|
|
||||||
/* check header */
|
|
||||||
if (read_32bitBE(0x00,streamFile) != 0x56415758) // "VAWX"
|
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
if (read_8bit(0xF,streamFile) == 2)
|
/* check header */
|
||||||
{
|
if (read_32bitBE(0x00,streamFile) != 0x56415758) /* "VAWX" */
|
||||||
loop_flag = 1;
|
goto fail;
|
||||||
}
|
|
||||||
|
|
||||||
|
loop_flag = read_8bit(0x37,streamFile);
|
||||||
channel_count = read_8bit(0x39,streamFile);;
|
channel_count = read_8bit(0x39,streamFile);;
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
/* fill in the vital statistics */
|
/* 0x04: filesize */
|
||||||
start_offset = 0x800;
|
start_offset = 0x800; /* ? read_32bitLE(0x0c,streamFile); */
|
||||||
vgmstream->channels = channel_count;
|
vgmstream->channels = channel_count;
|
||||||
|
/* 0x16: file id */
|
||||||
|
type = read_8bit(0x36,streamFile); /* could be at 0x38 too */
|
||||||
|
vgmstream->num_samples = read_32bitBE(0x3c,streamFile);
|
||||||
vgmstream->sample_rate = read_32bitBE(0x40,streamFile);
|
vgmstream->sample_rate = read_32bitBE(0x40,streamFile);
|
||||||
|
|
||||||
|
vgmstream->meta_type = meta_VAWX;
|
||||||
|
|
||||||
|
switch(type) {
|
||||||
|
case 2: /* VAG */
|
||||||
vgmstream->coding_type = coding_PSX;
|
vgmstream->coding_type = coding_PSX;
|
||||||
vgmstream->num_samples = ((get_streamfile_size(streamFile)-start_offset)/16/channel_count*28);
|
|
||||||
|
|
||||||
if (loop_flag)
|
|
||||||
{
|
|
||||||
vgmstream->loop_start_sample = read_32bitBE(0x44,streamFile);
|
|
||||||
vgmstream->loop_end_sample = read_32bitBE(0x48,streamFile);;
|
|
||||||
}
|
|
||||||
|
|
||||||
vgmstream->layout_type = layout_interleave;
|
vgmstream->layout_type = layout_interleave;
|
||||||
vgmstream->interleave_block_size = 0x10;
|
vgmstream->interleave_block_size = 0x10;
|
||||||
vgmstream->meta_type = meta_PS3_VAWX;
|
|
||||||
|
vgmstream->loop_start_sample = read_32bitBE(0x44,streamFile);
|
||||||
|
vgmstream->loop_end_sample = read_32bitBE(0x48,streamFile);
|
||||||
|
/* todo 6ch has 0x8000 blocks and must skip last 0x20 each block (or, skip 0x20 every 0x1550*6 */
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
case 1: { /* XMA2 */
|
||||||
|
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||||
|
uint8_t buf[FAKE_RIFF_BUFFER_SIZE];
|
||||||
|
int32_t bytes, block_size, block_count;
|
||||||
|
/* todo not accurate (needed for >2ch) */
|
||||||
|
datasize = get_streamfile_size(streamFile)-start_offset;
|
||||||
|
block_size = 2048;
|
||||||
|
block_count = datasize / block_size; /* read_32bitLE(custom_data_offset +0x14) -1? */
|
||||||
|
|
||||||
|
bytes = ffmpeg_make_riff_xma2(buf, FAKE_RIFF_BUFFER_SIZE, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||||
|
if (bytes <= 0) goto fail;
|
||||||
|
|
||||||
|
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize);
|
||||||
|
if ( !ffmpeg_data ) goto fail;
|
||||||
|
vgmstream->codec_data = ffmpeg_data;
|
||||||
|
vgmstream->coding_type = coding_FFmpeg;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
|
||||||
|
vgmstream->loop_start_sample = read_32bitBE(0x44,streamFile);
|
||||||
|
vgmstream->loop_end_sample = read_32bitBE(0x48,streamFile);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case 7: { /* ATRAC3 */
|
||||||
|
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||||
|
uint8_t buf[FAKE_RIFF_BUFFER_SIZE];
|
||||||
|
int32_t bytes, block_size, encoder_delay, joint_stereo, max_samples;
|
||||||
|
|
||||||
|
datasize = read_32bitBE(0x54,streamFile);
|
||||||
|
block_size = 0x98 * vgmstream->channels;
|
||||||
|
joint_stereo = 0;
|
||||||
|
max_samples = (datasize / block_size) * 1024;
|
||||||
|
encoder_delay = 0x0; /* not used by FFmpeg */
|
||||||
|
if (vgmstream->num_samples > max_samples) {
|
||||||
|
vgmstream->num_samples = max_samples;
|
||||||
|
/*encoder_delay = ?; */ /* todo some tracks need it to skip garbage but not sure how to calculate it */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* make a fake riff so FFmpeg can parse the ATRAC3 */
|
||||||
|
bytes = ffmpeg_make_riff_atrac3(buf, FAKE_RIFF_BUFFER_SIZE, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, encoder_delay);
|
||||||
|
if (bytes <= 0)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize);
|
||||||
|
if ( !ffmpeg_data ) goto fail;
|
||||||
|
vgmstream->codec_data = ffmpeg_data;
|
||||||
|
vgmstream->coding_type = coding_FFmpeg;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
|
||||||
|
vgmstream->loop_start_sample = (read_32bitBE(0x44,streamFile) / ffmpeg_data->blockAlign) * ffmpeg_data->frameSize;
|
||||||
|
vgmstream->loop_end_sample = (read_32bitBE(0x48,streamFile) / ffmpeg_data->blockAlign) * ffmpeg_data->frameSize;
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
default:
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
{
|
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
|
||||||
int i;
|
goto fail;
|
||||||
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;
|
return vgmstream;
|
||||||
|
|
||||||
/* clean up anything we may have opened */
|
|
||||||
fail:
|
fail:
|
||||||
if (vgmstream) close_vgmstream(vgmstream);
|
close_vgmstream(vgmstream);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -503,7 +503,7 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) {
|
||||||
(long long)loop_start_ms*fmt.sample_rate/1000;
|
(long long)loop_start_ms*fmt.sample_rate/1000;
|
||||||
vgmstream->loop_end_sample =
|
vgmstream->loop_end_sample =
|
||||||
(long long)loop_end_ms*fmt.sample_rate/1000;
|
(long long)loop_end_ms*fmt.sample_rate/1000;
|
||||||
vgmstream->meta_type = meta_RIFF_WAVE_labl_Marker;
|
vgmstream->meta_type = meta_RIFF_WAVE_labl;
|
||||||
}
|
}
|
||||||
else if (loop_start_offset >= 0)
|
else if (loop_start_offset >= 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -20,12 +20,40 @@ typedef struct _SCDINTSTREAMFILE
|
||||||
|
|
||||||
static STREAMFILE *open_scdint_with_STREAMFILE(STREAMFILE *file, const char * filename, off_t start_offset, off_t interleave_block_size, off_t stride_size, size_t total_size);
|
static STREAMFILE *open_scdint_with_STREAMFILE(STREAMFILE *file, const char * filename, off_t start_offset, off_t interleave_block_size, off_t stride_size, size_t total_size);
|
||||||
|
|
||||||
|
|
||||||
|
/* V3 decryption table found in the .exe */
|
||||||
|
static const uint8_t scd_ogg_v3_lookuptable[256] = { /* FF XIV Heavensward */
|
||||||
|
0x3A, 0x32, 0x32, 0x32, 0x03, 0x7E, 0x12, 0xF7, 0xB2, 0xE2, 0xA2, 0x67, 0x32, 0x32, 0x22, 0x32, // 00-0F
|
||||||
|
0x32, 0x52, 0x16, 0x1B, 0x3C, 0xA1, 0x54, 0x7B, 0x1B, 0x97, 0xA6, 0x93, 0x1A, 0x4B, 0xAA, 0xA6, // 10-1F
|
||||||
|
0x7A, 0x7B, 0x1B, 0x97, 0xA6, 0xF7, 0x02, 0xBB, 0xAA, 0xA6, 0xBB, 0xF7, 0x2A, 0x51, 0xBE, 0x03, // 20-2F
|
||||||
|
0xF4, 0x2A, 0x51, 0xBE, 0x03, 0xF4, 0x2A, 0x51, 0xBE, 0x12, 0x06, 0x56, 0x27, 0x32, 0x32, 0x36, // 30-3F
|
||||||
|
0x32, 0xB2, 0x1A, 0x3B, 0xBC, 0x91, 0xD4, 0x7B, 0x58, 0xFC, 0x0B, 0x55, 0x2A, 0x15, 0xBC, 0x40, // 40-4F
|
||||||
|
0x92, 0x0B, 0x5B, 0x7C, 0x0A, 0x95, 0x12, 0x35, 0xB8, 0x63, 0xD2, 0x0B, 0x3B, 0xF0, 0xC7, 0x14, // 50-5F
|
||||||
|
0x51, 0x5C, 0x94, 0x86, 0x94, 0x59, 0x5C, 0xFC, 0x1B, 0x17, 0x3A, 0x3F, 0x6B, 0x37, 0x32, 0x32, // 60-6F
|
||||||
|
0x30, 0x32, 0x72, 0x7A, 0x13, 0xB7, 0x26, 0x60, 0x7A, 0x13, 0xB7, 0x26, 0x50, 0xBA, 0x13, 0xB4, // 70-7F
|
||||||
|
0x2A, 0x50, 0xBA, 0x13, 0xB5, 0x2E, 0x40, 0xFA, 0x13, 0x95, 0xAE, 0x40, 0x38, 0x18, 0x9A, 0x92, // 80-8F
|
||||||
|
0xB0, 0x38, 0x00, 0xFA, 0x12, 0xB1, 0x7E, 0x00, 0xDB, 0x96, 0xA1, 0x7C, 0x08, 0xDB, 0x9A, 0x91, // 90-9F
|
||||||
|
0xBC, 0x08, 0xD8, 0x1A, 0x86, 0xE2, 0x70, 0x39, 0x1F, 0x86, 0xE0, 0x78, 0x7E, 0x03, 0xE7, 0x64, // A0-AF
|
||||||
|
0x51, 0x9C, 0x8F, 0x34, 0x6F, 0x4E, 0x41, 0xFC, 0x0B, 0xD5, 0xAE, 0x41, 0xFC, 0x0B, 0xD5, 0xAE, // B0-BF
|
||||||
|
0x41, 0xFC, 0x3B, 0x70, 0x71, 0x64, 0x33, 0x32, 0x12, 0x32, 0x32, 0x36, 0x70, 0x34, 0x2B, 0x56, // C0-CF
|
||||||
|
0x22, 0x70, 0x3A, 0x13, 0xB7, 0x26, 0x60, 0xBA, 0x1B, 0x94, 0xAA, 0x40, 0x38, 0x00, 0xFA, 0xB2, // D0-DF
|
||||||
|
0xE2, 0xA2, 0x67, 0x32, 0x32, 0x12, 0x32, 0xB2, 0x32, 0x32, 0x32, 0x32, 0x75, 0xA3, 0x26, 0x7B, // E0-EF
|
||||||
|
0x83, 0x26, 0xF9, 0x83, 0x2E, 0xFF, 0xE3, 0x16, 0x7D, 0xC0, 0x1E, 0x63, 0x21, 0x07, 0xE3, 0x01, // F0-FF
|
||||||
|
};
|
||||||
|
|
||||||
|
static void scd_ogg_decrypt_v2_callback(void *ptr, size_t size, size_t nmemb, void *datasource, int bytes_read);
|
||||||
|
static void scd_ogg_decrypt_v3_callback(void *ptr, size_t size, size_t nmemb, void *datasource, int bytes_read);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||||
VGMSTREAM * vgmstream = NULL;
|
VGMSTREAM * vgmstream = NULL;
|
||||||
char filename[PATH_LIMIT];
|
char filename[PATH_LIMIT];
|
||||||
off_t start_offset, meta_offset_offset, meta_offset, post_meta_offset;
|
off_t start_offset, tables_offset, headers_offset, meta_offset, post_meta_offset, stream_size;
|
||||||
|
int headers_entries;
|
||||||
int32_t loop_start, loop_end;
|
int32_t loop_start, loop_end;
|
||||||
|
|
||||||
|
int target_stream = 1; /* N=Nth stream, 0=auto (first) */
|
||||||
int loop_flag = 0;
|
int loop_flag = 0;
|
||||||
int channel_count;
|
int channel_count;
|
||||||
int codec_id;
|
int codec_id;
|
||||||
|
@ -42,63 +70,91 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||||
if (read_32bitBE(0,streamFile) != 0x53454442) goto fail;
|
if (read_32bitBE(0,streamFile) != 0x53454442) goto fail;
|
||||||
/* SSCF */
|
/* SSCF */
|
||||||
if (read_32bitBE(4,streamFile) != 0x53534346) goto fail;
|
if (read_32bitBE(4,streamFile) != 0x53534346) goto fail;
|
||||||
if (read_32bitBE(8,streamFile) == 2 ||
|
|
||||||
read_32bitBE(8,streamFile) == 3) {
|
/** main header section **/
|
||||||
/* version 2 BE, as seen in FFXIII demo for PS3 */
|
if (read_32bitBE(8,streamFile) == 2 || /* version 2 BE, as seen in FFXIII demo for PS3 */
|
||||||
/* version 3 BE, as seen in FFXIII for PS3 */
|
read_32bitBE(8,streamFile) == 3) { /* version 3 BE, as seen in FFXIII for PS3 */
|
||||||
|
|
||||||
read_32bit = read_32bitBE;
|
read_32bit = read_32bitBE;
|
||||||
read_16bit = read_16bitBE;
|
read_16bit = read_16bitBE;
|
||||||
//size_offset = 0x14;
|
//size_offset = 0x14;
|
||||||
meta_offset_offset = 0x40 + read_16bit(0xe,streamFile);
|
} else if (read_32bitLE(8,streamFile) == 3 || /* version 2/3 LE, as seen in FFXIV for PC (and others?) */
|
||||||
} else if (read_32bitLE(8,streamFile) == 3 ||
|
|
||||||
read_32bitLE(8,streamFile) == 2) {
|
read_32bitLE(8,streamFile) == 2) {
|
||||||
/* version 2/3 LE, as seen in FFXIV for ?? */
|
|
||||||
read_32bit = read_32bitLE;
|
read_32bit = read_32bitLE;
|
||||||
read_16bit = read_16bitLE;
|
read_16bit = read_16bitLE;
|
||||||
//size_offset = 0x10;
|
//size_offset = 0x10;
|
||||||
meta_offset_offset = 0x40 + read_16bit(0xe,streamFile);
|
|
||||||
} else goto fail;
|
} else goto fail;
|
||||||
|
|
||||||
/* never mind, FFXIII music_68tak.ps3.scd is 0x80 shorter */
|
/* 0xc: probably 00=LE, 01=BE */
|
||||||
|
/* 0xd: unk (always 0x04) */
|
||||||
|
tables_offset = read_16bit(0xe,streamFile);
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
/* never mind, FFXIII music_68tak.ps3.scd is 0x80 shorter */
|
||||||
/* check file size with header value */
|
/* check file size with header value */
|
||||||
if (read_32bit(size_offset,streamFile) != get_streamfile_size(streamFile))
|
if (read_32bit(size_offset,streamFile) != get_streamfile_size(streamFile))
|
||||||
goto fail;
|
goto fail;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
meta_offset = read_32bit(meta_offset_offset,streamFile);
|
/** offset tables **/
|
||||||
|
/* 0x00: table1_unknown entries */
|
||||||
|
/* 0x02: table2_unknown entries */
|
||||||
|
/* 0x04: table_headers entries */
|
||||||
|
/* 0x06: unknown (varies) */
|
||||||
|
/* 0x08: table1_unknown start offset */
|
||||||
|
/* 0x0c: table_headers start offset */
|
||||||
|
/* 0x10: table2_unknown start offset */
|
||||||
|
/* 0x14: unknown (0x0) */
|
||||||
|
/* 0x18: unknown offset */
|
||||||
|
/* 0x1c: unknown (0x0) */
|
||||||
|
headers_entries = read_16bit(tables_offset+0x04,streamFile);
|
||||||
|
VGM_ASSERT(headers_entries > 1, "SCD: multiple streams found (%i entries)\n", headers_entries);
|
||||||
|
if (target_stream == 0) target_stream = 1; /* auto: default to 1 */
|
||||||
|
if (target_stream > headers_entries) goto fail;
|
||||||
|
headers_offset = read_32bit(tables_offset+0x0c,streamFile);
|
||||||
|
|
||||||
|
/** header table entries (each is an uint32_t offset to stream header) **/
|
||||||
|
meta_offset = read_32bit(headers_offset + (target_stream-1)*4,streamFile);
|
||||||
|
|
||||||
|
/** stream header **/
|
||||||
|
stream_size = read_32bit(meta_offset + 0x0, streamFile);
|
||||||
|
channel_count = read_32bit(meta_offset+4,streamFile);
|
||||||
|
/* 0x8 sample rate */
|
||||||
|
codec_id = read_32bit(meta_offset+0xc,streamFile);
|
||||||
|
|
||||||
/* check that chunk size equals stream size (?) */
|
|
||||||
loop_start = read_32bit(meta_offset+0x10,streamFile);
|
loop_start = read_32bit(meta_offset+0x10,streamFile);
|
||||||
loop_end = read_32bit(meta_offset+0x14,streamFile);
|
loop_end = read_32bit(meta_offset+0x14,streamFile);
|
||||||
loop_flag = (loop_end > 0);
|
loop_flag = (loop_end > 0);
|
||||||
|
|
||||||
channel_count = read_32bit(meta_offset+4,streamFile);
|
|
||||||
codec_id = read_32bit(meta_offset+0xc,streamFile);
|
|
||||||
|
|
||||||
post_meta_offset = meta_offset + 0x20;
|
post_meta_offset = meta_offset + 0x20;
|
||||||
|
|
||||||
/* data at meta_offset is only 0x20 bytes, but there may be auxiliary chunks
|
|
||||||
before anything else */
|
|
||||||
|
|
||||||
aux_chunk_count = read_32bit(meta_offset+0x1c,streamFile);
|
|
||||||
for (; aux_chunk_count > 0; aux_chunk_count --)
|
|
||||||
{
|
|
||||||
/* skip aux chunks */
|
|
||||||
/*printf("skipping %08x\n", read_32bitBE(post_meta_offset, streamFile));*/
|
|
||||||
post_meta_offset += read_32bit(post_meta_offset+4,streamFile);
|
|
||||||
}
|
|
||||||
|
|
||||||
start_offset = post_meta_offset + read_32bit(meta_offset+0x18,streamFile);
|
start_offset = post_meta_offset + read_32bit(meta_offset+0x18,streamFile);
|
||||||
|
aux_chunk_count = read_32bit(meta_offset+0x1c,streamFile);
|
||||||
|
|
||||||
#ifdef VGM_USE_VORBIS
|
#ifdef VGM_USE_VORBIS
|
||||||
if (codec_id == 0x6)
|
if (codec_id == 0x6)
|
||||||
{
|
{
|
||||||
vgm_vorbis_info_t inf;
|
vgm_vorbis_info_t inf;
|
||||||
uint32_t seek_table_size = read_32bit(post_meta_offset+0x10, streamFile);
|
uint32_t seek_table_size;
|
||||||
uint32_t vorb_header_size = read_32bit(post_meta_offset+0x14, streamFile);
|
uint32_t vorb_header_size;
|
||||||
VGMSTREAM * result = NULL;
|
VGMSTREAM * result = NULL;
|
||||||
|
|
||||||
|
/* todo this skips the "MARK" chunk for FF XIV "03.scd", but without it actually the start_offset
|
||||||
|
* lands in a "OggS" though will fail in the "try skipping seek table"
|
||||||
|
* maybe this isn't needed and there is another bug, since other games with "MARK" don't need this */
|
||||||
|
if (aux_chunk_count) {
|
||||||
|
post_meta_offset = meta_offset + 0x20;
|
||||||
|
|
||||||
|
/* data at meta_offset is only 0x20 bytes, but there may be auxiliary chunks before anything else */
|
||||||
|
for (; aux_chunk_count > 0; aux_chunk_count--) {
|
||||||
|
post_meta_offset += read_32bit(post_meta_offset+4,streamFile); /* skip aux chunks */
|
||||||
|
}
|
||||||
|
start_offset = post_meta_offset + read_32bit(meta_offset+0x18,streamFile);
|
||||||
|
}
|
||||||
|
|
||||||
|
seek_table_size = read_32bit(post_meta_offset+0x10, streamFile);
|
||||||
|
vorb_header_size = read_32bit(post_meta_offset+0x14, streamFile);
|
||||||
|
|
||||||
memset(&inf, 0, sizeof(inf));
|
memset(&inf, 0, sizeof(inf));
|
||||||
inf.loop_start = loop_start;
|
inf.loop_start = loop_start;
|
||||||
inf.loop_end = loop_end;
|
inf.loop_end = loop_end;
|
||||||
|
@ -130,18 +186,28 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||||
// failed with Ogg, try deobfuscating header
|
// failed with Ogg, try deobfuscating header
|
||||||
{
|
{
|
||||||
// skip chunks before xor_byte
|
// skip chunks before xor_byte
|
||||||
unsigned char xor_byte;
|
uint8_t xor_version, xor_byte;
|
||||||
|
|
||||||
xor_byte = read_8bit(post_meta_offset+2, streamFile);
|
|
||||||
|
|
||||||
|
xor_version = read_8bit(post_meta_offset + 0, streamFile);
|
||||||
|
xor_byte = read_8bit(post_meta_offset + 2, streamFile);
|
||||||
if (xor_byte == 0) {
|
if (xor_byte == 0) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (xor_version <= 2) {
|
||||||
|
inf.decryption_enabled = 1;
|
||||||
|
inf.decryption_callback = scd_ogg_decrypt_v2_callback;
|
||||||
inf.scd_xor = xor_byte;
|
inf.scd_xor = xor_byte;
|
||||||
inf.scd_xor_len = vorb_header_size;
|
inf.scd_xor_length = vorb_header_size; /* header is XOR'ed */
|
||||||
|
|
||||||
|
} else if (xor_version == 3) {
|
||||||
|
inf.decryption_enabled = 1;
|
||||||
|
inf.decryption_callback = scd_ogg_decrypt_v3_callback;
|
||||||
|
inf.scd_xor = stream_size & 0xFF; /* xor_byte is not used? */
|
||||||
|
inf.scd_xor_length = stream_size; /* full file is XOR'ed */
|
||||||
|
}
|
||||||
result = init_vgmstream_ogg_vorbis_callbacks(streamFile, filename, NULL, start_offset, &inf);
|
result = init_vgmstream_ogg_vorbis_callbacks(streamFile, filename, NULL, start_offset, &inf);
|
||||||
|
/* always? */
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +226,7 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||||
/* PCM */
|
/* PCM */
|
||||||
vgmstream->coding_type = coding_PCM16LE_int;
|
vgmstream->coding_type = coding_PCM16LE_int;
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
vgmstream->num_samples = read_32bit(meta_offset+0,streamFile) / 2 / channel_count;
|
vgmstream->num_samples = stream_size / 2 / channel_count;
|
||||||
|
|
||||||
if (loop_flag) {
|
if (loop_flag) {
|
||||||
vgmstream->loop_start_sample = loop_start / 2 / channel_count;
|
vgmstream->loop_start_sample = loop_start / 2 / channel_count;
|
||||||
|
@ -175,6 +241,7 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||||
struct mpg123_frameinfo mi;
|
struct mpg123_frameinfo mi;
|
||||||
coding_t ct;
|
coding_t ct;
|
||||||
|
|
||||||
|
/* Drakengard 3, some Kingdom Hearts */
|
||||||
if (vgmstream->sample_rate == 47999)
|
if (vgmstream->sample_rate == 47999)
|
||||||
vgmstream->sample_rate = 48000;
|
vgmstream->sample_rate = 48000;
|
||||||
if (vgmstream->sample_rate == 44099)
|
if (vgmstream->sample_rate == 44099)
|
||||||
|
@ -189,7 +256,7 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||||
vgmstream->coding_type = ct;
|
vgmstream->coding_type = ct;
|
||||||
vgmstream->layout_type = layout_mpeg;
|
vgmstream->layout_type = layout_mpeg;
|
||||||
if (mi.vbr != MPG123_CBR) goto fail;
|
if (mi.vbr != MPG123_CBR) goto fail;
|
||||||
vgmstream->num_samples = mpeg_bytes_to_samples(read_32bit(meta_offset+0,streamFile), &mi);
|
vgmstream->num_samples = mpeg_bytes_to_samples(stream_size, &mi);
|
||||||
vgmstream->num_samples -= vgmstream->num_samples%576;
|
vgmstream->num_samples -= vgmstream->num_samples%576;
|
||||||
if (loop_flag) {
|
if (loop_flag) {
|
||||||
vgmstream->loop_start_sample = mpeg_bytes_to_samples(loop_start, &mi);
|
vgmstream->loop_start_sample = mpeg_bytes_to_samples(loop_start, &mi);
|
||||||
|
@ -206,14 +273,16 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||||
vgmstream->coding_type = coding_MSADPCM;
|
vgmstream->coding_type = coding_MSADPCM;
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
vgmstream->interleave_block_size = read_16bit(post_meta_offset+0xc,streamFile);
|
vgmstream->interleave_block_size = read_16bit(post_meta_offset+0xc,streamFile);
|
||||||
vgmstream->num_samples = msadpcm_bytes_to_samples(read_32bit(meta_offset+0,streamFile), vgmstream->interleave_block_size, vgmstream->channels);
|
vgmstream->num_samples = msadpcm_bytes_to_samples(stream_size, vgmstream->interleave_block_size, vgmstream->channels);
|
||||||
|
|
||||||
if (loop_flag) {
|
if (loop_flag) {
|
||||||
vgmstream->loop_start_sample = msadpcm_bytes_to_samples(loop_start, vgmstream->interleave_block_size, vgmstream->channels);
|
vgmstream->loop_start_sample = msadpcm_bytes_to_samples(loop_start, vgmstream->interleave_block_size, vgmstream->channels);
|
||||||
vgmstream->loop_end_sample = msadpcm_bytes_to_samples(loop_end, vgmstream->interleave_block_size, vgmstream->channels);
|
vgmstream->loop_end_sample = msadpcm_bytes_to_samples(loop_end, vgmstream->interleave_block_size, vgmstream->channels);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case 0xA:
|
|
||||||
|
case 0xA: /* Dragon Quest X (Wii) */
|
||||||
|
case 0x15: /* Dragon Quest X (Wii U) (no apparent differences except higher sample rate) */
|
||||||
/* GC/Wii DSP ADPCM */
|
/* GC/Wii DSP ADPCM */
|
||||||
{
|
{
|
||||||
STREAMFILE * file;
|
STREAMFILE * file;
|
||||||
|
@ -263,6 +332,8 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||||
for (i=0;i<channel_count;i++) {
|
for (i=0;i<channel_count;i++) {
|
||||||
STREAMFILE * intfile =
|
STREAMFILE * intfile =
|
||||||
open_scdint_with_STREAMFILE(file, "ARBITRARY.DSP", start_offset+interleave_size*i, interleave_size, stride_size, total_size);
|
open_scdint_with_STREAMFILE(file, "ARBITRARY.DSP", start_offset+interleave_size*i, interleave_size, stride_size, total_size);
|
||||||
|
if (!intfile)
|
||||||
|
goto fail;
|
||||||
|
|
||||||
data->substreams[i] = init_vgmstream_ngc_dsp_std(intfile);
|
data->substreams[i] = init_vgmstream_ngc_dsp_std(intfile);
|
||||||
data->intfiles[i] = intfile;
|
data->intfiles[i] = intfile;
|
||||||
|
@ -282,38 +353,74 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||||
break;
|
break;
|
||||||
#ifdef VGM_USE_FFMPEG
|
#ifdef VGM_USE_FFMPEG
|
||||||
case 0xB:
|
case 0xB:
|
||||||
/* XMA1/XMA2 */
|
/* XMA1/XMA2 */ /* Lightning Returns SFX, FFXIII (X360) */
|
||||||
{
|
{
|
||||||
uint16_t codec_id = read_16bit(post_meta_offset, streamFile);
|
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||||
if (codec_id == 0x165 || codec_id == 0x166)
|
uint8_t buf[200];
|
||||||
{
|
int32_t bytes;
|
||||||
ffmpeg_codec_data *ffmpeg_data = init_ffmpeg_faux_riff(streamFile, post_meta_offset, start_offset, streamFile->get_size(streamFile) - start_offset, read_32bit == read_32bitBE);
|
|
||||||
|
/* post_meta_offset+0x00: fmt0x166 header (BE), post_meta_offset+0x34: seek table */
|
||||||
|
|
||||||
|
bytes = ffmpeg_make_riff_xma2_from_fmt(buf,200, post_meta_offset,0x34, stream_size, streamFile, 1);
|
||||||
|
if (bytes <= 0) goto fail;
|
||||||
|
|
||||||
|
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,stream_size);
|
||||||
if (!ffmpeg_data) goto fail;
|
if (!ffmpeg_data) goto fail;
|
||||||
|
|
||||||
vgmstream->codec_data = ffmpeg_data;
|
vgmstream->codec_data = ffmpeg_data;
|
||||||
|
|
||||||
vgmstream->coding_type = coding_FFmpeg;
|
vgmstream->coding_type = coding_FFmpeg;
|
||||||
vgmstream->layout_type = layout_none;
|
vgmstream->layout_type = layout_none;
|
||||||
|
|
||||||
vgmstream->num_samples = ffmpeg_data->totalSamples;
|
vgmstream->num_samples = ffmpeg_data->totalSamples;
|
||||||
|
|
||||||
if (loop_flag) {
|
|
||||||
vgmstream->loop_start_sample = loop_start;
|
vgmstream->loop_start_sample = loop_start;
|
||||||
vgmstream->loop_end_sample = loop_end;
|
vgmstream->loop_end_sample = loop_end;
|
||||||
}
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case 0xE:
|
||||||
|
/* ATRAC3plus */ /* Lord of Arcana (PSP) */
|
||||||
|
{
|
||||||
|
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||||
|
off_t chunk_offset;
|
||||||
|
size_t chunk_size, fact_sample_skip = 0;
|
||||||
|
|
||||||
|
/* full riff header at start_offset/post_meta_offset (same) */
|
||||||
|
ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset,stream_size);
|
||||||
|
if (!ffmpeg_data) goto fail;
|
||||||
|
vgmstream->codec_data = ffmpeg_data;
|
||||||
|
vgmstream->coding_type = coding_FFmpeg;
|
||||||
|
vgmstream->layout_type = layout_none;
|
||||||
|
|
||||||
|
vgmstream->num_samples = ffmpeg_data->totalSamples;
|
||||||
|
vgmstream->loop_start_sample = loop_start;
|
||||||
|
vgmstream->loop_end_sample = loop_end;
|
||||||
|
|
||||||
|
/* manually find encoder_delay to adjust samples since it's not properly used by FFmpeg */
|
||||||
|
if (!find_chunk_le(streamFile, 0x66616374,start_offset+0xc,0, &chunk_offset,&chunk_size)) goto fail; /*"fact"*/
|
||||||
|
if (chunk_size == 0x8) {
|
||||||
|
fact_sample_skip = read_32bitLE(chunk_offset+0x4, streamFile);
|
||||||
|
} else if (chunk_size == 0xc) {
|
||||||
|
fact_sample_skip = read_32bitLE(chunk_offset+0x8, streamFile);
|
||||||
}
|
}
|
||||||
else goto fail;
|
vgmstream->num_samples += fact_sample_skip;
|
||||||
|
vgmstream->loop_start_sample += fact_sample_skip;
|
||||||
|
vgmstream->loop_end_sample += fact_sample_skip;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
default:
|
default:
|
||||||
|
VGM_LOG("SCD: unknown codec_id 0x%x\n", codec_id);
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
vgmstream->meta_type = meta_SQEX_SCD;
|
vgmstream->meta_type = meta_SQEX_SCD;
|
||||||
|
|
||||||
/* open the file for reading */
|
/* open the file for reading */
|
||||||
if (vgmstream->layout_type != layout_scd_int && vgmstream->coding_type != coding_FFmpeg)
|
if (vgmstream->layout_type != layout_scd_int
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
&& vgmstream->coding_type != coding_FFmpeg
|
||||||
|
#endif
|
||||||
|
)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
STREAMFILE * file;
|
STREAMFILE * file;
|
||||||
|
@ -433,8 +540,13 @@ static size_t read_scdint(SCDINTSTREAMFILE *streamfile, uint8_t *dest, off_t off
|
||||||
/* start_offset is for *this* interleaved stream */
|
/* start_offset is for *this* interleaved stream */
|
||||||
static STREAMFILE *open_scdint_with_STREAMFILE(STREAMFILE *file, const char * filename, off_t start_offset, off_t interleave_block_size, off_t stride_size, size_t total_size)
|
static STREAMFILE *open_scdint_with_STREAMFILE(STREAMFILE *file, const char * filename, off_t start_offset, off_t interleave_block_size, off_t stride_size, size_t total_size)
|
||||||
{
|
{
|
||||||
SCDINTSTREAMFILE * scd = malloc(sizeof(SCDINTSTREAMFILE));
|
SCDINTSTREAMFILE * scd = NULL;
|
||||||
|
|
||||||
|
/* _scdint funcs can't handle this case */
|
||||||
|
if (start_offset + total_size > file->get_size(file))
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
scd = malloc(sizeof(SCDINTSTREAMFILE));
|
||||||
if (!scd)
|
if (!scd)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -456,3 +568,43 @@ static STREAMFILE *open_scdint_with_STREAMFILE(STREAMFILE *file, const char * fi
|
||||||
|
|
||||||
return &scd->sf;
|
return &scd->sf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void scd_ogg_decrypt_v2_callback(void *ptr, size_t size, size_t nmemb, void *datasource, int bytes_read) {
|
||||||
|
ogg_vorbis_streamfile * ov_streamfile = (ogg_vorbis_streamfile*)datasource;
|
||||||
|
|
||||||
|
/* header is XOR'd with a constant byte */
|
||||||
|
if (ov_streamfile->offset < ov_streamfile->scd_xor_length) {
|
||||||
|
int i, num_crypt;
|
||||||
|
|
||||||
|
num_crypt = ov_streamfile->scd_xor_length - ov_streamfile->offset;
|
||||||
|
if (num_crypt > bytes_read)
|
||||||
|
num_crypt = bytes_read;
|
||||||
|
|
||||||
|
for (i = 0; i < num_crypt; i++) {
|
||||||
|
((uint8_t*)ptr)[i] ^= (uint8_t)ov_streamfile->scd_xor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void scd_ogg_decrypt_v3_callback(void *ptr, size_t size, size_t nmemb, void *datasource, int bytes_read) {
|
||||||
|
ogg_vorbis_streamfile *ov_streamfile = (ogg_vorbis_streamfile*)datasource;
|
||||||
|
|
||||||
|
/* file is XOR'd with a table (algorithm and table by Ioncannon) */
|
||||||
|
if (ov_streamfile->offset < ov_streamfile->scd_xor_length) {
|
||||||
|
int i, num_crypt;
|
||||||
|
uint8_t byte1, byte2, xorByte;
|
||||||
|
|
||||||
|
num_crypt = bytes_read;
|
||||||
|
byte1 = ov_streamfile->scd_xor & 0x7F;
|
||||||
|
byte2 = ov_streamfile->scd_xor & 0x3F;
|
||||||
|
|
||||||
|
for (i = 0; i < num_crypt; i++) {
|
||||||
|
xorByte = scd_ogg_v3_lookuptable[(byte2 + ov_streamfile->offset + i) & 0xFF];
|
||||||
|
xorByte &= 0xFF;
|
||||||
|
xorByte ^= ((uint8_t*)ptr)[i];
|
||||||
|
xorByte ^= byte1;
|
||||||
|
((uint8_t*)ptr)[i] = (uint8_t)xorByte;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,66 @@
|
||||||
|
#include "meta.h"
|
||||||
|
#include "../coding/coding.h"
|
||||||
|
|
||||||
|
/* CXS - found in Eternal Sonata (Xbox 360) */
|
||||||
|
VGMSTREAM * init_vgmstream_x360_cxs(STREAMFILE *streamFile) {
|
||||||
|
VGMSTREAM * vgmstream = NULL;
|
||||||
|
off_t start_offset;
|
||||||
|
int loop_flag, channel_count;
|
||||||
|
|
||||||
|
/* check extension, case insensitive */
|
||||||
|
if ( !check_extensions(streamFile,"cxs"))
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
if (read_32bitBE(0x00,streamFile) != 0x43585320) /* "CXS " */
|
||||||
|
goto fail;
|
||||||
|
|
||||||
|
loop_flag = read_32bitBE(0x18,streamFile) > 0;
|
||||||
|
channel_count = read_32bitBE(0x0c,streamFile);
|
||||||
|
|
||||||
|
/* build the VGMSTREAM */
|
||||||
|
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||||
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
|
start_offset = read_32bitBE(0x04,streamFile) + read_32bitBE(0x28,streamFile); /* assumed, seek table always at 0x800 */
|
||||||
|
/* 0x04: data start? */
|
||||||
|
vgmstream->sample_rate = read_32bitBE(0x08,streamFile);
|
||||||
|
vgmstream->channels = channel_count; /*0x0c*/
|
||||||
|
vgmstream->num_samples = read_32bitBE(0x10,streamFile) + 576; /*todo add proper encoder_delay*/
|
||||||
|
vgmstream->loop_start_sample = read_32bitBE(0x14,streamFile);
|
||||||
|
vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile);
|
||||||
|
/* 0x1c: below */
|
||||||
|
|
||||||
|
vgmstream->meta_type = meta_X360_CXS;
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
{
|
||||||
|
ffmpeg_codec_data *ffmpeg_data = NULL;
|
||||||
|
uint8_t buf[100];
|
||||||
|
size_t bytes, datasize, block_size, block_count;
|
||||||
|
|
||||||
|
block_count = read_32bitBE(0x1c,streamFile);
|
||||||
|
block_size = read_32bitBE(0x20,streamFile);
|
||||||
|
datasize = read_32bitBE(0x24,streamFile);
|
||||||
|
|
||||||
|
bytes = ffmpeg_make_riff_xma2(buf,100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
|
||||||
|
if (bytes <= 0) goto fail;
|
||||||
|
|
||||||
|
ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize);
|
||||||
|
if ( !ffmpeg_data ) goto fail;
|
||||||
|
vgmstream->codec_data = ffmpeg_data;
|
||||||
|
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;
|
||||||
|
}
|
|
@ -64,6 +64,7 @@ VGMSTREAM * init_vgmstream_xma(STREAMFILE *streamFile) {
|
||||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
if (strcasecmp("xma",filename_extension(filename))
|
if (strcasecmp("xma",filename_extension(filename))
|
||||||
&& strcasecmp("xma2",filename_extension(filename)) /* Skullgirls */
|
&& strcasecmp("xma2",filename_extension(filename)) /* Skullgirls */
|
||||||
|
&& strcasecmp("nps",filename_extension(filename)) /* Beautiful Katamari */
|
||||||
&& strcasecmp("past",filename_extension(filename)) /* SoulCalibur II HD */
|
&& strcasecmp("past",filename_extension(filename)) /* SoulCalibur II HD */
|
||||||
)
|
)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
@ -484,4 +485,3 @@ static int32_t get_xma_sample_rate(int32_t general_rate) {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
|
@ -1,18 +1,22 @@
|
||||||
#ifndef _MSC_VER
|
#ifndef _MSC_VER
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
#endif
|
#endif
|
||||||
#include "vgmstream.h"
|
|
||||||
#include "streamfile.h"
|
#include "streamfile.h"
|
||||||
#include "util.h"
|
#include "util.h"
|
||||||
|
#include "vgmstream.h"
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
STREAMFILE sf;
|
STREAMFILE sf;
|
||||||
FILE * infile;
|
FILE * infile;
|
||||||
|
char name[PATH_LIMIT];
|
||||||
off_t offset;
|
off_t offset;
|
||||||
size_t validsize;
|
size_t validsize;
|
||||||
uint8_t * buffer;
|
uint8_t * buffer;
|
||||||
size_t buffersize;
|
size_t buffersize;
|
||||||
char name[PATH_LIMIT];
|
size_t filesize;
|
||||||
|
#ifdef VGM_DEBUG_OUTPUT
|
||||||
|
int error_notified;
|
||||||
|
#endif
|
||||||
#ifdef PROFILE_STREAMFILE
|
#ifdef PROFILE_STREAMFILE
|
||||||
size_t bytes_read;
|
size_t bytes_read;
|
||||||
int error_count;
|
int error_count;
|
||||||
|
@ -47,9 +51,31 @@ static size_t read_the_rest(uint8_t * dest, off_t offset, size_t length, STDIOST
|
||||||
/* read as much of the beginning of the request as possible, proceed */
|
/* read as much of the beginning of the request as possible, proceed */
|
||||||
while (length>0) {
|
while (length>0) {
|
||||||
size_t length_to_read;
|
size_t length_to_read;
|
||||||
size_t length_read=0;
|
size_t length_read;
|
||||||
streamfile->validsize=0;
|
streamfile->validsize=0;
|
||||||
if (fseeko(streamfile->infile,offset,SEEK_SET)) return length_read;
|
|
||||||
|
/* request outside file: ignore to avoid seek/read */
|
||||||
|
if (offset > streamfile->filesize) {
|
||||||
|
#ifdef VGM_DEBUG_OUTPUT
|
||||||
|
if (!streamfile->error_notified) {
|
||||||
|
VGM_LOG("ERROR: reading outside filesize, at offset 0x%lx + 0x%x (buggy meta?)\n", offset, length);
|
||||||
|
streamfile->error_notified = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
streamfile->offset = streamfile->filesize;
|
||||||
|
memset(dest,0,length);
|
||||||
|
return length; /* return partially-read buffer and 0-set the rest */
|
||||||
|
}
|
||||||
|
|
||||||
|
/* position to new offset */
|
||||||
|
if (fseeko(streamfile->infile,offset,SEEK_SET)) {
|
||||||
|
streamfile->offset = streamfile->filesize;
|
||||||
|
#ifdef PROFILE_STREAMFILE
|
||||||
|
streamfile->error_count++;
|
||||||
|
#endif
|
||||||
|
return 0; //fail miserably
|
||||||
|
}
|
||||||
|
|
||||||
streamfile->offset=offset;
|
streamfile->offset=offset;
|
||||||
|
|
||||||
/* decide how much must be read this time */
|
/* decide how much must be read this time */
|
||||||
|
@ -87,9 +113,8 @@ static size_t read_the_rest(uint8_t * dest, off_t offset, size_t length, STDIOST
|
||||||
return length_read_total;
|
return length_read_total;
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t read_stdio(STDIOSTREAMFILE *streamfile,uint8_t * dest, off_t offset, size_t length)
|
static size_t read_stdio(STDIOSTREAMFILE *streamfile,uint8_t * dest, off_t offset, size_t length) {
|
||||||
{
|
|
||||||
// read
|
|
||||||
if (!streamfile || !dest || length<=0) return 0;
|
if (!streamfile || !dest || length<=0) return 0;
|
||||||
|
|
||||||
/* if entire request is within the buffer */
|
/* if entire request is within the buffer */
|
||||||
|
@ -98,6 +123,21 @@ static size_t read_stdio(STDIOSTREAMFILE *streamfile,uint8_t * dest, off_t offse
|
||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* request outside file: ignore to avoid seek/read in read_the_rest() */
|
||||||
|
if (offset > streamfile->filesize) {
|
||||||
|
#ifdef VGM_DEBUG_OUTPUT
|
||||||
|
if (!streamfile->error_notified) {
|
||||||
|
VGM_LOG("ERROR: reading outside filesize, at offset over 0x%lx (buggy meta?)\n", offset);
|
||||||
|
streamfile->error_notified = 1;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
streamfile->offset = streamfile->filesize;
|
||||||
|
memset(dest,0,length);
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* request outside buffer: new fread */
|
||||||
{
|
{
|
||||||
size_t length_read = read_the_rest(dest,offset,length,streamfile);
|
size_t length_read = read_the_rest(dest,offset,length,streamfile);
|
||||||
#if PROFILE_STREAMFILE
|
#if PROFILE_STREAMFILE
|
||||||
|
@ -115,8 +155,7 @@ static void close_stdio(STDIOSTREAMFILE * streamfile) {
|
||||||
}
|
}
|
||||||
|
|
||||||
static size_t get_size_stdio(STDIOSTREAMFILE * streamfile) {
|
static size_t get_size_stdio(STDIOSTREAMFILE * streamfile) {
|
||||||
fseeko(streamfile->infile,0,SEEK_END);
|
return streamfile->filesize;
|
||||||
return ftello(streamfile->infile);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static off_t get_offset_stdio(STDIOSTREAMFILE *streamFile) {
|
static off_t get_offset_stdio(STDIOSTREAMFILE *streamFile) {
|
||||||
|
@ -195,6 +234,10 @@ static STREAMFILE * open_stdio_streamfile_buffer_by_FILE(FILE *infile,const char
|
||||||
strncpy(streamfile->name,filename,sizeof(streamfile->name));
|
strncpy(streamfile->name,filename,sizeof(streamfile->name));
|
||||||
streamfile->name[sizeof(streamfile->name)-1] = '\0';
|
streamfile->name[sizeof(streamfile->name)-1] = '\0';
|
||||||
|
|
||||||
|
/* cache filesize */
|
||||||
|
fseeko(streamfile->infile,0,SEEK_END);
|
||||||
|
streamfile->filesize = ftello(streamfile->infile);
|
||||||
|
|
||||||
return &streamfile->sf;
|
return &streamfile->sf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -273,6 +316,18 @@ size_t get_streamfile_dos_line(int dst_length, char * dst, off_t offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Opens an stream using the base streamFile name plus a new extension (ex. for headers in a separate file)
|
||||||
|
*/
|
||||||
|
STREAMFILE * open_stream_ext(STREAMFILE *streamFile, const char * ext) {
|
||||||
|
char filename_ext[PATH_LIMIT];
|
||||||
|
|
||||||
|
streamFile->get_name(streamFile,filename_ext,sizeof(filename_ext));
|
||||||
|
strcpy(filename_ext + strlen(filename_ext) - strlen(filename_extension(filename_ext)), ext);
|
||||||
|
|
||||||
|
return streamFile->open(streamFile,filename_ext,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* open file containing decryption keys and copy to buffer
|
* open file containing decryption keys and copy to buffer
|
||||||
* tries combinations of keynames based on the original filename
|
* tries combinations of keynames based on the original filename
|
||||||
|
@ -391,3 +446,72 @@ fail:
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* checks if the stream filename is one of the extensions (comma-separated, ex. "adx" or "adx,aix")
|
||||||
|
*
|
||||||
|
* returns 0 on failure
|
||||||
|
*/
|
||||||
|
int check_extensions(STREAMFILE *streamFile, const char * cmp_exts) {
|
||||||
|
char filename[PATH_LIMIT];
|
||||||
|
const char * ext = NULL;
|
||||||
|
const char * cmp_ext = NULL;
|
||||||
|
size_t ext_len;
|
||||||
|
|
||||||
|
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||||
|
ext = filename_extension(filename);
|
||||||
|
ext_len = strlen(ext);
|
||||||
|
|
||||||
|
cmp_ext = cmp_exts;
|
||||||
|
do {
|
||||||
|
if (strncasecmp(ext,cmp_ext, ext_len)==0 )
|
||||||
|
return 1;
|
||||||
|
cmp_ext = strstr(cmp_ext, ",");
|
||||||
|
if (cmp_ext != NULL)
|
||||||
|
cmp_ext = cmp_ext + 1; /* skip comma */
|
||||||
|
} while (cmp_ext != NULL);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Find a chunk starting from an offset, and save its offset/size (if not NULL), with offset after id/size.
|
||||||
|
* Works for chunked headers in the form of "chunk_id chunk_size (data)"xN (ex. RIFF).
|
||||||
|
* The start_offset should be the first actual chunk (not "RIFF" or "WAVE" but "fmt ").
|
||||||
|
* "full_chunk_size" signals chunk_size includes 4+4+data.
|
||||||
|
*
|
||||||
|
* returns 0 on failure
|
||||||
|
*/
|
||||||
|
static int find_chunk(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, int size_big_endian, off_t *out_chunk_offset, size_t *out_chunk_size);
|
||||||
|
int find_chunk_be(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size) {
|
||||||
|
return find_chunk(streamFile, chunk_id, start_offset, full_chunk_size, 1, out_chunk_offset, out_chunk_size);
|
||||||
|
}
|
||||||
|
int find_chunk_le(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size) {
|
||||||
|
return find_chunk(streamFile, chunk_id, start_offset, full_chunk_size, 0, out_chunk_offset, out_chunk_size);
|
||||||
|
}
|
||||||
|
int find_chunk(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, int size_big_endian, off_t *out_chunk_offset, size_t *out_chunk_size) {
|
||||||
|
size_t filesize;
|
||||||
|
off_t current_chunk = start_offset;
|
||||||
|
|
||||||
|
filesize = get_streamfile_size(streamFile);
|
||||||
|
/* read chunks */
|
||||||
|
while (current_chunk < filesize) {
|
||||||
|
uint32_t chunk_type = read_32bitBE(current_chunk,streamFile);
|
||||||
|
off_t chunk_size = size_big_endian ?
|
||||||
|
read_32bitBE(current_chunk+4,streamFile) :
|
||||||
|
read_32bitLE(current_chunk+4,streamFile);
|
||||||
|
|
||||||
|
if (chunk_type == chunk_id) {
|
||||||
|
if (out_chunk_offset) *out_chunk_offset = current_chunk+8;
|
||||||
|
if (out_chunk_size) *out_chunk_size = chunk_size;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
current_chunk += full_chunk_size ? chunk_size : 4+4+chunk_size;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
#define fseeko fseek
|
#define fseeko fseek
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define STREAMFILE_DEFAULT_BUFFER_SIZE 0x400
|
#define STREAMFILE_DEFAULT_BUFFER_SIZE 0x8000
|
||||||
|
|
||||||
#ifndef DIR_SEPARATOR
|
#ifndef DIR_SEPARATOR
|
||||||
#if defined (_WIN32) || defined (WIN32)
|
#if defined (_WIN32) || defined (WIN32)
|
||||||
|
@ -146,11 +146,17 @@ static inline STREAMFILE * open_stdio_streamfile(const char * const filename) {
|
||||||
return open_stdio_streamfile_buffer(filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
return open_stdio_streamfile_buffer(filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||||
}
|
}
|
||||||
|
|
||||||
size_t get_streamfile_dos_line(int dst_length, char * dst, off_t offset,
|
size_t get_streamfile_dos_line(int dst_length, char * dst, off_t offset, STREAMFILE * infile, int *line_done_ptr);
|
||||||
STREAMFILE * infile, int *line_done_ptr);
|
|
||||||
|
STREAMFILE * open_stream_ext(STREAMFILE *streamFile, const char * ext);
|
||||||
|
|
||||||
int read_key_file(uint8_t * buf, size_t bufsize, STREAMFILE *streamFile);
|
int read_key_file(uint8_t * buf, size_t bufsize, STREAMFILE *streamFile);
|
||||||
|
|
||||||
int read_pos_file(uint8_t * buf, size_t bufsize, STREAMFILE *streamFile);
|
int read_pos_file(uint8_t * buf, size_t bufsize, STREAMFILE *streamFile);
|
||||||
|
|
||||||
|
int check_extensions(STREAMFILE *streamFile, const char * cmp_exts);
|
||||||
|
|
||||||
|
int find_chunk_be(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size);
|
||||||
|
int find_chunk_le(STREAMFILE *streamFile, uint32_t chunk_id, off_t start_offset, int full_chunk_size, off_t *out_chunk_offset, size_t *out_chunk_size);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,13 +7,24 @@
|
||||||
#define _STREAMTYPES_H
|
#define _STREAMTYPES_H
|
||||||
|
|
||||||
#ifdef _MSC_VER
|
#ifdef _MSC_VER
|
||||||
|
|
||||||
|
#if (_MSC_VER >= 1600)
|
||||||
|
#include <stdint.h>
|
||||||
|
#else
|
||||||
#include <pstdint.h>
|
#include <pstdint.h>
|
||||||
|
#endif /* (_MSC_VER >= 1600) */
|
||||||
|
|
||||||
#define inline _inline
|
#define inline _inline
|
||||||
#define strcasecmp _stricmp
|
#define strcasecmp _stricmp
|
||||||
|
#define strncasecmp _strnicmp
|
||||||
|
|
||||||
|
#if (_MSC_VER < 1900)
|
||||||
#define snprintf _snprintf
|
#define snprintf _snprintf
|
||||||
|
#endif /* (_MSC_VER < 1900) */
|
||||||
|
|
||||||
#else
|
#else
|
||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#endif
|
#endif /* _MSC_VER */
|
||||||
|
|
||||||
typedef int16_t sample;
|
typedef int16_t sample;
|
||||||
|
|
||||||
|
|
|
@ -85,75 +85,6 @@ void put_32bitBE(uint8_t * buf, int32_t i) {
|
||||||
buf[3] = (uint8_t)(i & 0xFF);
|
buf[3] = (uint8_t)(i & 0xFF);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make a header for PCM .wav */
|
|
||||||
/* buffer must be 0x2c bytes */
|
|
||||||
void make_wav_header(uint8_t * buf, int32_t sample_count, int32_t sample_rate, int channels) {
|
|
||||||
size_t bytecount;
|
|
||||||
|
|
||||||
bytecount = sample_count*channels*sizeof(sample);
|
|
||||||
|
|
||||||
/* RIFF header */
|
|
||||||
memcpy(buf+0, "RIFF", 4);
|
|
||||||
/* size of RIFF */
|
|
||||||
put_32bitLE(buf+4, (int32_t)(bytecount+0x2c-8));
|
|
||||||
|
|
||||||
/* WAVE header */
|
|
||||||
memcpy(buf+8, "WAVE", 4);
|
|
||||||
|
|
||||||
/* WAVE fmt chunk */
|
|
||||||
memcpy(buf+0xc, "fmt ", 4);
|
|
||||||
/* size of WAVE fmt chunk */
|
|
||||||
put_32bitLE(buf+0x10, 0x10);
|
|
||||||
|
|
||||||
/* compression code 1=PCM */
|
|
||||||
put_16bitLE(buf+0x14, 1);
|
|
||||||
|
|
||||||
/* channel count */
|
|
||||||
put_16bitLE(buf+0x16, channels);
|
|
||||||
|
|
||||||
/* sample rate */
|
|
||||||
put_32bitLE(buf+0x18, sample_rate);
|
|
||||||
|
|
||||||
/* bytes per second */
|
|
||||||
put_32bitLE(buf+0x1c, sample_rate*channels*sizeof(sample));
|
|
||||||
|
|
||||||
/* block align */
|
|
||||||
put_16bitLE(buf+0x20, (int16_t)(channels*sizeof(sample)));
|
|
||||||
|
|
||||||
/* significant bits per sample */
|
|
||||||
put_16bitLE(buf+0x22, sizeof(sample)*8);
|
|
||||||
|
|
||||||
/* PCM has no extra format bytes, so we don't even need to specify a count */
|
|
||||||
|
|
||||||
/* WAVE data chunk */
|
|
||||||
memcpy(buf+0x24, "data", 4);
|
|
||||||
/* size of WAVE data chunk */
|
|
||||||
put_32bitLE(buf+0x28, (int32_t)bytecount);
|
|
||||||
}
|
|
||||||
|
|
||||||
void make_smpl_chunk(uint8_t * buf, int32_t loop_start, int32_t loop_end) {
|
|
||||||
int i;
|
|
||||||
/* RIFF header */
|
|
||||||
memcpy(buf+0, "smpl", 4);
|
|
||||||
/* size of RIFF */
|
|
||||||
put_32bitLE(buf+4, 0x3c);
|
|
||||||
|
|
||||||
for (i = 0; i < 7; i++)
|
|
||||||
put_32bitLE(buf+8 + i * 4, 0);
|
|
||||||
|
|
||||||
put_32bitLE(buf+36, 1);
|
|
||||||
|
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
put_32bitLE(buf+40 + i * 4, 0);
|
|
||||||
|
|
||||||
put_32bitLE(buf+52, loop_start);
|
|
||||||
put_32bitLE(buf+56, loop_end);
|
|
||||||
put_32bitLE(buf+60, 0);
|
|
||||||
put_32bitLE(buf+64, 0);
|
|
||||||
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
void swap_samples_le(sample *buf, int count) {
|
void swap_samples_le(sample *buf, int count) {
|
||||||
int i;
|
int i;
|
||||||
for (i=0;i<count;i++) {
|
for (i=0;i<count;i++) {
|
||||||
|
@ -175,42 +106,3 @@ void concatn(int length, char * dst, const char * src) {
|
||||||
dst[i]=src[j];
|
dst[i]=src[j];
|
||||||
dst[i]='\0';
|
dst[i]='\0';
|
||||||
}
|
}
|
||||||
|
|
||||||
/* length is maximum length of dst. dst will always be double-null-terminated if
|
|
||||||
* length > 1 */
|
|
||||||
void concatn_doublenull(int length, char * dst, const char * src) {
|
|
||||||
int i,j;
|
|
||||||
if (length <= 1) return;
|
|
||||||
for (i=0;i<length-2 && (dst[i] || dst[i+1]);i++); /* find end of dst */
|
|
||||||
if (i==length-2) {
|
|
||||||
dst[i]='\0';
|
|
||||||
dst[i+1]='\0';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (i>0) i++;
|
|
||||||
for (j=0;i<length-2 && (src[j] || src[j+1]);i++,j++) dst[i]=src[j];
|
|
||||||
dst[i]='\0';
|
|
||||||
dst[i+1]='\0';
|
|
||||||
}
|
|
||||||
|
|
||||||
/* length is maximum length of dst. dst will always be double-null-terminated if
|
|
||||||
* length > 1, if src won't fit, truncate */
|
|
||||||
void concatn_fitting_doublenull(int length, char * dst, const char * src) {
|
|
||||||
int i,j,k;
|
|
||||||
if (length <= 1) return;
|
|
||||||
for (i=0;i<length-2 && (dst[i] || dst[i+1]);i++); /* find end of dst */
|
|
||||||
if (i==length-2) {
|
|
||||||
dst[i]='\0';
|
|
||||||
dst[i+1]='\0';
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (i>0) i++;
|
|
||||||
k = i;
|
|
||||||
for (j=0;i<length-2 && (src[j] || src[j+1]);i++,j++) dst[i]=src[j];
|
|
||||||
|
|
||||||
if (i == length-2 && (src[j] || src[j+1])) {
|
|
||||||
i = k;
|
|
||||||
}
|
|
||||||
dst[i]='\0';
|
|
||||||
dst[i+1]='\0';
|
|
||||||
}
|
|
||||||
|
|
|
@ -62,14 +62,28 @@ static inline int clamp16(int32_t val) {
|
||||||
return val;
|
return val;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* make a header for PCM .wav */
|
|
||||||
/* buffer must be 0x2c bytes */
|
|
||||||
void make_wav_header(uint8_t * buf, int32_t sample_count, int32_t sample_rate, int channels);
|
|
||||||
void make_smpl_chunk(uint8_t * buf, int32_t loop_start, int32_t loop_end);
|
|
||||||
void swap_samples_le(sample *buf, int count);
|
void swap_samples_le(sample *buf, int count);
|
||||||
|
|
||||||
void concatn(int length, char * dst, const char * src);
|
void concatn(int length, char * dst, const char * src);
|
||||||
void concatn_doublenull(int length, char * dst, const char * src);
|
|
||||||
void concatn_fitting_doublenull(int length, char * dst, const char * src);
|
|
||||||
|
/* Simple stdout logging for debugging and regression testing purposes.
|
||||||
|
* Needs C99 variadic macros. */
|
||||||
|
#ifdef VGM_DEBUG_OUTPUT
|
||||||
|
|
||||||
|
#define VGM_ASSERT(condition, ...) \
|
||||||
|
do { if (condition) printf(__VA_ARGS__); } while (0)
|
||||||
|
#define VGM_LOG(...) \
|
||||||
|
do { printf(__VA_ARGS__); } while (0)
|
||||||
|
#define VGM_LOGF() \
|
||||||
|
do { printf("%s:%i '%s'\n", __FILE__, __LINE__, __func__); } while (0)
|
||||||
|
|
||||||
|
#else
|
||||||
|
|
||||||
|
#define VGM_ASSERT(condition,fmt, ...) /* nothing */
|
||||||
|
#define VGM_LOG(...) /* nothing */
|
||||||
|
#define VGM_LOGF(...) /* nothing */
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -7,11 +7,12 @@
|
||||||
|
|
||||||
enum { PATH_LIMIT = 32768 };
|
enum { PATH_LIMIT = 32768 };
|
||||||
|
|
||||||
/* Due mostly to licensing issues, Vorbis, MPEG, and G.722.1 decoding are
|
#include "streamfile.h"
|
||||||
|
|
||||||
|
/* Due mostly to licensing issues, Vorbis, MPEG, G.722.1, etc decoding is
|
||||||
* done by external libraries.
|
* done by external libraries.
|
||||||
* If someone wants to do a standalone build, they can do it by simply
|
* If someone wants to do a standalone build, they can do it by simply
|
||||||
* removing these defines (and the references to the libraries in the
|
* removing these defines (and the references to the libraries in the Makefile) */
|
||||||
* Makefile) */
|
|
||||||
#define VGM_USE_VORBIS
|
#define VGM_USE_VORBIS
|
||||||
|
|
||||||
/* can be disabled to decode with FFmpeg instead */
|
/* can be disabled to decode with FFmpeg instead */
|
||||||
|
@ -19,27 +20,25 @@ enum { PATH_LIMIT = 32768 };
|
||||||
#define VGM_USE_MPEG
|
#define VGM_USE_MPEG
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* disabled by default, defined for builds that support it */
|
/* disabled by default, defined on compile-time for builds that support it*/
|
||||||
#define VGM_USE_G7221
|
#define VGM_USE_G7221
|
||||||
#define VGM_USE_G719
|
#define VGM_USE_G719
|
||||||
|
//#define VGM_USE_MP4V2
|
||||||
|
//#define VGM_USE_FDKAAC
|
||||||
|
//#define VGM_USE_MAIATRAC3PLUS
|
||||||
#define VGM_USE_FFMPEG
|
#define VGM_USE_FFMPEG
|
||||||
#define VGM_USE_FFMPEG_ACCURATE_LOOPING
|
|
||||||
|
|
||||||
#include "streamfile.h"
|
|
||||||
#ifdef BUILD_VGMSTREAM
|
|
||||||
#include "coding/g72x_state.h"
|
|
||||||
#else
|
|
||||||
#include "g72x_state.h"
|
|
||||||
#endif
|
|
||||||
#ifdef VGM_USE_VORBIS
|
#ifdef VGM_USE_VORBIS
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
#define __MACOSX__
|
#define __MACOSX__
|
||||||
#endif
|
#endif
|
||||||
#include <vorbis/vorbisfile.h>
|
#include <vorbis/vorbisfile.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VGM_USE_MPEG
|
#ifdef VGM_USE_MPEG
|
||||||
#include <mpg123/mpg123.h>
|
#include <mpg123/mpg123.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VGM_USE_G7221
|
#ifdef VGM_USE_G7221
|
||||||
#include <g7221/g7221.h>
|
#include <g7221/g7221.h>
|
||||||
#endif
|
#endif
|
||||||
|
@ -60,86 +59,105 @@ enum { PATH_LIMIT = 32768 };
|
||||||
#include "maiatrac3plus.h"
|
#include "maiatrac3plus.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "clHCA.h"
|
|
||||||
|
|
||||||
#ifdef VGM_USE_FFMPEG
|
#ifdef VGM_USE_FFMPEG
|
||||||
#include <libavcodec/avcodec.h>
|
#include <libavcodec/avcodec.h>
|
||||||
#include <libavformat/avformat.h>
|
#include <libavformat/avformat.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef BUILD_VGMSTREAM
|
#ifdef BUILD_VGMSTREAM
|
||||||
|
#include "coding/g72x_state.h"
|
||||||
#include "coding/acm_decoder.h"
|
#include "coding/acm_decoder.h"
|
||||||
#include "coding/nwa_decoder.h"
|
#include "coding/nwa_decoder.h"
|
||||||
#else
|
#else
|
||||||
|
#include "g72x_state.h"
|
||||||
#include "acm_decoder.h"
|
#include "acm_decoder.h"
|
||||||
#include "nwa_decoder.h"
|
#include "nwa_decoder.h"
|
||||||
#endif
|
#endif
|
||||||
|
#include "clHCA.h"
|
||||||
|
|
||||||
|
|
||||||
/* The encoding type specifies the format the sound data itself takes */
|
/* The encoding type specifies the format the sound data itself takes */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* 16-bit PCM */
|
/* 16-bit PCM */
|
||||||
coding_PCM16BE, /* big endian 16-bit PCM */
|
|
||||||
coding_PCM16LE, /* little endian 16-bit PCM */
|
coding_PCM16LE, /* little endian 16-bit PCM */
|
||||||
coding_PCM16LE_int, /* little endian 16-bit PCM with sample-level
|
coding_PCM16LE_int, /* little endian 16-bit PCM with sample-level interleave */
|
||||||
interleave handled by the decoder */
|
coding_PCM16LE_XOR_int, /* little endian 16-bit PCM with sample-level xor */
|
||||||
|
coding_PCM16BE, /* big endian 16-bit PCM */
|
||||||
|
|
||||||
/* 8-bit PCM */
|
/* 8-bit PCM */
|
||||||
coding_PCM8, /* 8-bit PCM */
|
coding_PCM8, /* 8-bit PCM */
|
||||||
|
coding_PCM8_int, /* 8-Bit PCM with sample-level interleave */
|
||||||
coding_PCM8_U, /* 8-bit PCM, unsigned (0x80 = 0) */
|
coding_PCM8_U, /* 8-bit PCM, unsigned (0x80 = 0) */
|
||||||
coding_PCM8_int, /* 8-Bit PCM with sample-level interleave handled
|
coding_PCM8_U_int, /* 8-bit PCM, unsigned (0x80 = 0) with sample-level interleave */
|
||||||
by the decoder */
|
coding_PCM8_SB_int, /* 8-bit PCM, sign bit (others are 2's complement) with sample-level interleave */
|
||||||
coding_PCM8_SB_int, /* 8-bit PCM, sign bit (others are 2's complement),
|
|
||||||
sample-level interleave */
|
|
||||||
coding_PCM8_U_int, /* 8-bit PCM, unsigned (0x80 = 0), sample-level
|
|
||||||
interleave */
|
|
||||||
|
|
||||||
/* 4-bit ADPCM */
|
/* 4-bit ADPCM */
|
||||||
coding_NDS_IMA, /* IMA ADPCM w/ NDS layout */
|
|
||||||
coding_CRI_ADX, /* CRI ADX */
|
coding_CRI_ADX, /* CRI ADX */
|
||||||
coding_CRI_ADX_enc_8, /* encrypted CRI ADX, type 8 (God Hand) */
|
coding_CRI_ADX_enc_8, /* CRI ADX, type 8 encryption (God Hand) */
|
||||||
coding_CRI_ADX_enc_9, /* encrypted CRI ADX, type 9 (PSO2) */
|
coding_CRI_ADX_enc_9, /* CRI ADX, type 9 encryption (PSO2) */
|
||||||
coding_NGC_DSP, /* NGC ADPCM, called DSP */
|
|
||||||
coding_NGC_DTK, /* NGC hardware disc ADPCM, called DTK, TRK or ADP */
|
|
||||||
coding_G721, /* CCITT G.721 ADPCM */
|
|
||||||
coding_NGC_AFC, /* NGC ADPCM, called AFC */
|
|
||||||
coding_PSX, /* PSX & PS2 ADPCM */
|
|
||||||
coding_invert_PSX, /* PSX ADPCM with some weirdness */
|
|
||||||
coding_PSX_badflags, /* with garbage in the flags byte */
|
|
||||||
coding_FFXI, /* FF XI PSX-ish ADPCM */
|
|
||||||
coding_BAF_ADPCM, /* Bizarre Creations PSX-ish ADPCM */
|
|
||||||
coding_HEVAG_ADPCM, /* PSVita games */
|
|
||||||
coding_SHORT_VAG_ADPCM, /* SGXD type 5 (PS3 Afrika) */
|
|
||||||
coding_XA, /* PSX CD-XA */
|
|
||||||
coding_XBOX, /* XBOX IMA */
|
|
||||||
coding_INT_XBOX, /* XBOX 'real interleaved' IMA */
|
|
||||||
coding_EAXA, /* EA/XA ADPCM */
|
|
||||||
coding_EA_ADPCM, /* EA ADPCM */
|
|
||||||
coding_MAXIS_ADPCM, /* MAXIS ADPCM */
|
|
||||||
coding_NDS_PROCYON, /* NDS Procyon Studio ADPCM */
|
|
||||||
|
|
||||||
#ifdef VGM_USE_VORBIS
|
coding_NGC_DSP, /* Nintendo DSP ADPCM */
|
||||||
coding_ogg_vorbis, /* vorbis */
|
coding_NGC_DTK, /* Nintendo DTK ADPCM (hardware disc), also called TRK or ADP */
|
||||||
#endif
|
coding_NGC_AFC, /* Nintendo AFC ADPCM */
|
||||||
coding_SDX2, /* SDX2 2:1 Squareroot-Delta-Exact compression */
|
|
||||||
coding_SDX2_int, /* SDX2 2:1 Squareroot-Delta-Exact compression,
|
coding_G721, /* CCITT G.721 */
|
||||||
with smaple-level interleave handled by the
|
|
||||||
decoder */
|
coding_XA, /* CD-ROM XA */
|
||||||
coding_CBD2, /* CBD2 2:1 Cuberoot-Delta-Exact compression */
|
coding_PSX, /* Sony PS ADPCM (VAG) */
|
||||||
coding_CBD2_int, /* CBD2 2:1 Cuberoot-Delta-Exact compression,
|
coding_PSX_badflags, /* Sony PS ADPCM with garbage in the flag byte */
|
||||||
with sample-level interleave handled by the
|
coding_PSX_bmdx, /* Sony PS ADPCM with BMDX encryption */
|
||||||
decoder */
|
coding_PSX_cfg, /* Sony PS ADPCM with configurable frame size (FF XI, SGXD type 5, Bizarre Creations) */
|
||||||
coding_DVI_IMA, /* DVI (bare IMA, high nibble first), aka ADP4 */
|
coding_HEVAG, /* Sony PSVita ADPCM */
|
||||||
coding_INT_DVI_IMA, /* Interleaved DVI */
|
|
||||||
|
coding_EA_XA, /* Electronic Arts XA ADPCM */
|
||||||
|
coding_EA_ADPCM, /* Electronic Arts R1 ADPCM */
|
||||||
|
coding_MAXIS_ADPCM, /* Maxis ADPCM */
|
||||||
|
coding_NDS_PROCYON, /* Procyon Studio ADPCM */
|
||||||
|
|
||||||
|
coding_XBOX, /* XBOX IMA ADPCM */
|
||||||
|
coding_INT_XBOX, /* XBOX IMA ADPCM (interleaved) */
|
||||||
|
coding_IMA, /* IMA ADPCM (low nibble first) */
|
||||||
|
coding_INT_IMA, /* IMA ADPCM (interleaved) */
|
||||||
|
coding_DVI_IMA, /* DVI IMA ADPCM (high nibble first), aka ADP4 */
|
||||||
|
coding_INT_DVI_IMA, /* DVI IMA ADPCM (Interleaved) */
|
||||||
|
coding_NDS_IMA, /* IMA ADPCM w/ NDS layout */
|
||||||
coding_EACS_IMA,
|
coding_EACS_IMA,
|
||||||
coding_IMA, /* bare IMA, low nibble first */
|
|
||||||
coding_INT_IMA, /* */
|
|
||||||
coding_MS_IMA, /* Microsoft IMA */
|
coding_MS_IMA, /* Microsoft IMA */
|
||||||
coding_RAD_IMA, /* "Radical ADPCM" IMA */
|
coding_RAD_IMA, /* "Radical ADPCM" IMA */
|
||||||
coding_RAD_IMA_mono, /* "Radical ADPCM" IMA, mono (for interleave) */
|
coding_RAD_IMA_mono, /* "Radical ADPCM" IMA, mono (for interleave) */
|
||||||
coding_APPLE_IMA4, /* Apple Quicktime IMA4 */
|
coding_APPLE_IMA4, /* Apple Quicktime IMA4 */
|
||||||
coding_DAT4_IMA, /* Eurocom 'DAT4' IMA ADPCM */
|
coding_DAT4_IMA, /* Eurocom 'DAT4' IMA ADPCM */
|
||||||
coding_SNDS_IMA, /* Heavy Iron Studios .snds IMA ADPCM */
|
coding_SNDS_IMA, /* Heavy Iron Studios .snds IMA ADPCM */
|
||||||
coding_WS, /* Westwood Studios' custom VBR ADPCM */
|
|
||||||
|
coding_WS, /* Westwood Studios VBR ADPCM */
|
||||||
|
coding_MSADPCM, /* Microsoft ADPCM */
|
||||||
|
coding_AICA, /* Yamaha AICA ADPCM */
|
||||||
|
coding_L5_555, /* Level-5 0x555 ADPCM */
|
||||||
|
coding_SASSC, /* Activision EXAKT SASSC DPCM */
|
||||||
|
coding_LSF, /* lsf ADPCM (Fastlane Street Racing iPhone)*/
|
||||||
|
coding_MTAF, /* Konami MTAF ADPCM (IMA-derived) */
|
||||||
|
|
||||||
|
/* others */
|
||||||
|
coding_SDX2, /* SDX2 2:1 Squareroot-Delta-Exact compression DPCM */
|
||||||
|
coding_SDX2_int, /* SDX2 2:1 Squareroot-Delta-Exact compression with sample-level interleave */
|
||||||
|
coding_CBD2, /* CBD2 2:1 Cuberoot-Delta-Exact compression DPCM */
|
||||||
|
coding_CBD2_int, /* CBD2 2:1 Cuberoot-Delta-Exact compression, with sample-level interleave */
|
||||||
|
|
||||||
|
coding_ACM, /* InterPlay ACM */
|
||||||
|
|
||||||
|
coding_NWA0, /* Visual Art's NWA (compressed at various levels) */
|
||||||
|
coding_NWA1,
|
||||||
|
coding_NWA2,
|
||||||
|
coding_NWA3,
|
||||||
|
coding_NWA4,
|
||||||
|
coding_NWA5,
|
||||||
|
|
||||||
|
coding_CRI_HCA, /* CRI High Compression Audio (MDCT-based) */
|
||||||
|
|
||||||
|
#ifdef VGM_USE_VORBIS
|
||||||
|
coding_ogg_vorbis, /* Xiph Vorbis (MDCT-based) */
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef VGM_USE_MPEG
|
#ifdef VGM_USE_MPEG
|
||||||
coding_fake_MPEG2_L2, /* MPEG-2 Layer 2 (AHX), with lying headers */
|
coding_fake_MPEG2_L2, /* MPEG-2 Layer 2 (AHX), with lying headers */
|
||||||
/* I don't even know offhand if all these combinations exist... */
|
/* I don't even know offhand if all these combinations exist... */
|
||||||
|
@ -153,43 +171,26 @@ typedef enum {
|
||||||
coding_MPEG25_L2,
|
coding_MPEG25_L2,
|
||||||
coding_MPEG25_L3,
|
coding_MPEG25_L3,
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VGM_USE_G7221
|
#ifdef VGM_USE_G7221
|
||||||
coding_G7221, /* G.722.1 (Polycom Siren 7) */
|
coding_G7221, /* ITU G.722.1 (Polycom Siren 7) */
|
||||||
coding_G7221C, /* G.722.1 with Annex C extension (Polycom Siren 14) */
|
coding_G7221C, /* ITU G.722.1 annex C (Polycom Siren 14) */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VGM_USE_G719
|
#ifdef VGM_USE_G719
|
||||||
coding_G719,
|
coding_G719, /* ITU G.719 annex B (Polycom Siren 22) */
|
||||||
#endif
|
|
||||||
|
|
||||||
coding_ACM, /* InterPlay ACM */
|
|
||||||
/* compressed NWA at various levels */
|
|
||||||
coding_NWA0,
|
|
||||||
coding_NWA1,
|
|
||||||
coding_NWA2,
|
|
||||||
coding_NWA3,
|
|
||||||
coding_NWA4,
|
|
||||||
coding_NWA5,
|
|
||||||
|
|
||||||
coding_MSADPCM, /* Microsoft ADPCM */
|
|
||||||
coding_AICA, /* Yamaha AICA ADPCM */
|
|
||||||
coding_L5_555, /* Level-5 0x555 */
|
|
||||||
coding_SASSC, /* Activision EXAKT SASSC DPCM */
|
|
||||||
coding_PCM16LE_XOR_int, /* sample-level xor */
|
|
||||||
coding_LSF, /* lsf ADPCM */
|
|
||||||
coding_MTAF, /* Konami IMA-derived MTAF ADPCM */
|
|
||||||
|
|
||||||
coding_CRI_HCA, /* CRI High Compression Audio */
|
|
||||||
|
|
||||||
#ifdef VGM_USE_FFMPEG
|
|
||||||
coding_FFmpeg,
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
#if defined(VGM_USE_MP4V2) && defined(VGM_USE_FDKAAC)
|
||||||
coding_MP4_AAC,
|
coding_MP4_AAC, /* AAC (MDCT-based) */
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef VGM_USE_MAIATRAC3PLUS
|
#ifdef VGM_USE_MAIATRAC3PLUS
|
||||||
coding_AT3plus,
|
coding_AT3plus, /* Sony ATRAC3plus (MDCT-based) */
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef VGM_USE_FFMPEG
|
||||||
|
coding_FFmpeg, /* Formats handled by FFmpeg (ATRAC3, XMA, AC3, etc) */
|
||||||
#endif
|
#endif
|
||||||
} coding_t;
|
} coding_t;
|
||||||
|
|
||||||
|
@ -197,15 +198,15 @@ typedef enum {
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* generic */
|
/* generic */
|
||||||
layout_none, /* straight data */
|
layout_none, /* straight data */
|
||||||
|
|
||||||
/* interleave */
|
/* interleave */
|
||||||
layout_interleave, /* equal interleave throughout the stream */
|
layout_interleave, /* equal interleave throughout the stream */
|
||||||
layout_interleave_shortblock, /* interleave with a short last block */
|
layout_interleave_shortblock, /* interleave with a short last block */
|
||||||
|
|
||||||
layout_interleave_byte, /* full byte interleave */
|
layout_interleave_byte, /* full byte interleave */
|
||||||
|
|
||||||
/* headered blocks */
|
/* headered blocks */
|
||||||
layout_ast_blocked, /* .ast STRM with BLCK blocks*/
|
layout_ast_blocked,
|
||||||
layout_halpst_blocked, /* blocks with HALPST-format header */
|
layout_halpst_blocked,
|
||||||
layout_xa_blocked,
|
layout_xa_blocked,
|
||||||
layout_ea_blocked,
|
layout_ea_blocked,
|
||||||
layout_eacs_blocked,
|
layout_eacs_blocked,
|
||||||
|
@ -226,12 +227,18 @@ typedef enum {
|
||||||
layout_ps2_adm_blocked,
|
layout_ps2_adm_blocked,
|
||||||
layout_dsp_bdsp_blocked,
|
layout_dsp_bdsp_blocked,
|
||||||
layout_mxch_blocked,
|
layout_mxch_blocked,
|
||||||
|
layout_ivaud_blocked, /* GTA IV .ivaud blocks */
|
||||||
|
layout_tra_blocked, /* DefJam Rapstar .tra blocks */
|
||||||
|
layout_ps2_iab_blocked,
|
||||||
|
layout_ps2_strlr_blocked,
|
||||||
|
|
||||||
#if 0
|
|
||||||
layout_strm_blocked, /* */
|
|
||||||
#endif
|
|
||||||
/* otherwise odd */
|
/* otherwise odd */
|
||||||
layout_dtk_interleave, /* dtk interleaves channels by nibble */
|
layout_acm, /* libacm layout */
|
||||||
|
layout_mus_acm, /* mus has multi-files to deal with */
|
||||||
|
layout_aix, /* CRI AIX's wheels within wheels */
|
||||||
|
layout_aax, /* CRI AAX's wheels within databases */
|
||||||
|
layout_scd_int, /* deinterleave done by the SCDINTSTREAMFILE */
|
||||||
|
|
||||||
#ifdef VGM_USE_VORBIS
|
#ifdef VGM_USE_VORBIS
|
||||||
layout_ogg_vorbis, /* ogg vorbis file */
|
layout_ogg_vorbis, /* ogg vorbis file */
|
||||||
#endif
|
#endif
|
||||||
|
@ -239,31 +246,22 @@ typedef enum {
|
||||||
layout_fake_mpeg, /* MPEG audio stream with bad frame headers (AHX) */
|
layout_fake_mpeg, /* MPEG audio stream with bad frame headers (AHX) */
|
||||||
layout_mpeg, /* proper MPEG audio stream */
|
layout_mpeg, /* proper MPEG audio stream */
|
||||||
#endif
|
#endif
|
||||||
layout_acm, /* dummy, let libacm handle layout */
|
|
||||||
layout_mus_acm, /* mus has multi-files to deal with */
|
|
||||||
layout_aix, /* CRI AIX's wheels within wheels */
|
|
||||||
layout_aax, /* CRI AAX's wheels within databases */
|
|
||||||
layout_ivaud_blocked, /* GTA IV .ivaud blocks */
|
|
||||||
layout_tra_blocked, /* DefJam Rapstar .tra blocks */
|
|
||||||
layout_ps2_iab_blocked,
|
|
||||||
layout_ps2_strlr_blocked,
|
|
||||||
layout_scd_int, /* deinterleave done by the SCDINTSTREAMFILE */
|
|
||||||
} layout_t;
|
} layout_t;
|
||||||
|
|
||||||
/* The meta type specifies how we know what we know about the file. We may know because of a header we read, some of it may have been guessed from filenames, etc. */
|
/* The meta type specifies how we know what we know about the file.
|
||||||
|
* We may know because of a header we read, some of it may have been guessed from filenames, etc. */
|
||||||
typedef enum {
|
typedef enum {
|
||||||
/* DSP-specific */
|
/* DSP-specific */
|
||||||
meta_DSP_STD, /* standard GC ADPCM (DSP) header */
|
meta_DSP_STD, /* Nintendo standard GC ADPCM (DSP) header */
|
||||||
meta_DSP_CSMP, /* Metroid Prime 3, Donkey Kong Country Returns */
|
meta_DSP_CSMP, /* Retro: Metroid Prime 3, Donkey Kong Country Returns */
|
||||||
meta_DSP_CSTR, /* Star Fox Assault "Cstr" */
|
meta_DSP_CSTR, /* Star Fox Assault "Cstr" */
|
||||||
meta_DSP_RS03, /* Metroid Prime 2 "RS03" */
|
meta_DSP_RS03, /* Retro: Metroid Prime 2 "RS03" */
|
||||||
meta_DSP_STM, /* Paper Mario 2 STM */
|
meta_DSP_STM, /* Paper Mario 2 STM */
|
||||||
meta_DSP_HALP, /* SSB:M "HALPST" */
|
meta_DSP_AGSC, /* Retro: Metroid Prime 2 title */
|
||||||
meta_DSP_AGSC, /* Metroid Prime 2 title */
|
|
||||||
meta_DSP_MPDSP, /* Monopoly Party single header stereo */
|
meta_DSP_MPDSP, /* Monopoly Party single header stereo */
|
||||||
meta_DSP_JETTERS, /* Bomberman Jetters .dsp */
|
meta_DSP_JETTERS, /* Bomberman Jetters .dsp */
|
||||||
meta_DSP_MSS,
|
meta_DSP_MSS, /* ? */
|
||||||
meta_DSP_GCM,
|
meta_DSP_GCM, /* ? */
|
||||||
meta_DSP_STR, /* Conan .str files */
|
meta_DSP_STR, /* Conan .str files */
|
||||||
meta_DSP_SADB, /* .sad */
|
meta_DSP_SADB, /* .sad */
|
||||||
meta_DSP_WSI, /* .wsi */
|
meta_DSP_WSI, /* .wsi */
|
||||||
|
@ -272,11 +270,11 @@ typedef enum {
|
||||||
meta_DSP_WII_MUS, /* .mus */
|
meta_DSP_WII_MUS, /* .mus */
|
||||||
meta_DSP_WII_WSD, /* Phantom Brave (WII) */
|
meta_DSP_WII_WSD, /* Phantom Brave (WII) */
|
||||||
meta_WII_NDP, /* Vertigo (Wii) */
|
meta_WII_NDP, /* Vertigo (Wii) */
|
||||||
meta_DSP_YGO, /* Yu-Gi-Oh! The Falsebound Kingdom (NGC), Hikaru no Go 3 (NGC) */
|
meta_DSP_YGO, /* Konami: Yu-Gi-Oh! The Falsebound Kingdom (NGC), Hikaru no Go 3 (NGC) */
|
||||||
|
|
||||||
/* Nintendo */
|
/* Nintendo */
|
||||||
meta_STRM, /* STRM */
|
meta_STRM, /* Nintendo STRM */
|
||||||
meta_RSTM, /* RSTM (similar to STRM) */
|
meta_RSTM, /* Nintendo RSTM (similar to STRM) */
|
||||||
meta_AFC, /* AFC */
|
meta_AFC, /* AFC */
|
||||||
meta_AST, /* AST */
|
meta_AST, /* AST */
|
||||||
meta_RWSD, /* single-stream RWSD */
|
meta_RWSD, /* single-stream RWSD */
|
||||||
|
@ -285,7 +283,7 @@ typedef enum {
|
||||||
meta_CWAV, /* contents of CWAR */
|
meta_CWAV, /* contents of CWAR */
|
||||||
meta_FWAV, /* contents of FWAR */
|
meta_FWAV, /* contents of FWAR */
|
||||||
meta_RSTM_SPM, /* RSTM with 44->22khz hack */
|
meta_RSTM_SPM, /* RSTM with 44->22khz hack */
|
||||||
meta_THP,
|
meta_THP, /* THP movie files */
|
||||||
meta_RSTM_shrunken, /* Atlus' mutant shortened RSTM */
|
meta_RSTM_shrunken, /* Atlus' mutant shortened RSTM */
|
||||||
meta_NDS_SWAV, /* Asphalt Urban GT 1 & 2 */
|
meta_NDS_SWAV, /* Asphalt Urban GT 1 & 2 */
|
||||||
meta_NDS_RRDS, /* Ridge Racer DS */
|
meta_NDS_RRDS, /* Ridge Racer DS */
|
||||||
|
@ -293,18 +291,16 @@ typedef enum {
|
||||||
meta_STX, /* Pikmin .stx */
|
meta_STX, /* Pikmin .stx */
|
||||||
meta_WIIU_BTSND, /* Wii U Boot Sound */
|
meta_WIIU_BTSND, /* Wii U Boot Sound */
|
||||||
|
|
||||||
/* CRI ADX */
|
meta_ADX_03, /* CRI ADX "type 03" */
|
||||||
meta_ADX_03, /* ADX "type 03" */
|
meta_ADX_04, /* CRI ADX "type 04" */
|
||||||
meta_ADX_04, /* ADX "type 04" */
|
meta_ADX_05, /* CRI ADX "type 05" */
|
||||||
meta_ADX_05, /* ADX "type 05" */
|
|
||||||
meta_AIX, /* CRI AIX */
|
meta_AIX, /* CRI AIX */
|
||||||
meta_AAX, /* CRI AAX */
|
meta_AAX, /* CRI AAX */
|
||||||
meta_UTF_DSP, /* CRI ADPCM_WII, like AAX with DSP */
|
meta_UTF_DSP, /* CRI ADPCM_WII, like AAX with DSP */
|
||||||
|
|
||||||
/* etc */
|
meta_NGC_ADPDTK, /* NGC DTK/ADP (.adp/dkt DTK) [no header_id] */
|
||||||
meta_NGC_ADPDTK, /* NGC DTK/ADP, no header (.adp) */
|
|
||||||
meta_kRAW, /* almost headerless PCM */
|
meta_kRAW, /* almost headerless PCM */
|
||||||
meta_RSF, /* Retro Studios RSF, no header (.rsf) */
|
meta_RSF, /* Retro Studios RSF (Metroid Prime .rsf) [no header_id] */
|
||||||
meta_HALPST, /* HAL Labs HALPST */
|
meta_HALPST, /* HAL Labs HALPST */
|
||||||
meta_GCSW, /* GCSW (PCM) */
|
meta_GCSW, /* GCSW (PCM) */
|
||||||
meta_CFN, /* Namco CAF Audio File */
|
meta_CFN, /* Namco CAF Audio File */
|
||||||
|
@ -312,6 +308,7 @@ typedef enum {
|
||||||
meta_HIS, /* Her Ineractive .his */
|
meta_HIS, /* Her Ineractive .his */
|
||||||
meta_BNSF, /* Bandai Namco Sound Format */
|
meta_BNSF, /* Bandai Namco Sound Format */
|
||||||
|
|
||||||
|
meta_PSX_XA, /* CD-ROM XA with RIFF header */
|
||||||
meta_PS2_SShd, /* .ADS with SShd header */
|
meta_PS2_SShd, /* .ADS with SShd header */
|
||||||
meta_PS2_NPSF, /* Namco Production Sound File */
|
meta_PS2_NPSF, /* Namco Production Sound File */
|
||||||
meta_PS2_RXW, /* Sony Arc The Lad Sound File */
|
meta_PS2_RXW, /* Sony Arc The Lad Sound File */
|
||||||
|
@ -325,11 +322,10 @@ typedef enum {
|
||||||
meta_PS2_VAGp, /* VAGp Mono File */
|
meta_PS2_VAGp, /* VAGp Mono File */
|
||||||
meta_PS2_VAGm, /* VAGp Mono File */
|
meta_PS2_VAGm, /* VAGp Mono File */
|
||||||
meta_PS2_pGAV, /* VAGp with Little Endian Header */
|
meta_PS2_pGAV, /* VAGp with Little Endian Header */
|
||||||
meta_PSX_GMS, /* GMS File (used in PS1 & PS2) */
|
meta_PSX_GMS, /* GMS File (used in PS1 & PS2) [no header_id] */
|
||||||
meta_PS2_STR, /* Pacman STR+STH files */
|
meta_PS2_STR, /* Pacman STR+STH files */
|
||||||
meta_PS2_ILD, /* ILD File */
|
meta_PS2_ILD, /* ILD File */
|
||||||
meta_PS2_PNB, /* PsychoNauts Bgm File */
|
meta_PS2_PNB, /* PsychoNauts Bgm File */
|
||||||
meta_PSX_XA, /* CD-XA with RIFF header */
|
|
||||||
meta_PS2_VAGs, /* VAG Stereo from Kingdom Hearts */
|
meta_PS2_VAGs, /* VAG Stereo from Kingdom Hearts */
|
||||||
meta_PS2_VPK, /* VPK Audio File */
|
meta_PS2_VPK, /* VPK Audio File */
|
||||||
meta_PS2_BMDX, /* Beatmania thing */
|
meta_PS2_BMDX, /* Beatmania thing */
|
||||||
|
@ -339,14 +335,12 @@ typedef enum {
|
||||||
meta_XSS, /* Dino Crisis 3 */
|
meta_XSS, /* Dino Crisis 3 */
|
||||||
meta_SL3, /* Test Drive Unlimited */
|
meta_SL3, /* Test Drive Unlimited */
|
||||||
meta_HGC1, /* Knights of the Temple 2 */
|
meta_HGC1, /* Knights of the Temple 2 */
|
||||||
meta_AUS, /* Variuos Capcom Games */
|
meta_AUS, /* Various Capcom games */
|
||||||
meta_RWS, /* Variuos Konami Games */
|
meta_RWS, /* Various Konami games */
|
||||||
meta_FSB1, /* FMOD Sample Bank, version 1 */
|
meta_FSB1, /* FMOD Sample Bank, version 1 */
|
||||||
meta_FSB3_0, /* FMOD Sample Bank, version 3.0 */
|
meta_FSB2, /* FMOD Sample Bank, version 2 */
|
||||||
meta_FSB3_1, /* FMOD Sample Bank, version 3.1 */
|
meta_FSB3, /* FMOD Sample Bank, version 3.0/3.1 */
|
||||||
meta_FSB4, /* FMOD Sample Bank, version 4 */
|
meta_FSB4, /* FMOD Sample Bank, version 4 */
|
||||||
meta_FSB_MPEG, /* Just Test */
|
|
||||||
meta_FSB4_WAV, /* FMOD Sample Bank, version 4 with "WAV" Header */
|
|
||||||
meta_FSB5, /* FMOD Sample Bank, version 5 */
|
meta_FSB5, /* FMOD Sample Bank, version 5 */
|
||||||
meta_RWX, /* Air Force Delta Storm (XBOX) */
|
meta_RWX, /* Air Force Delta Storm (XBOX) */
|
||||||
meta_XWB, /* King of Fighters (XBOX) */
|
meta_XWB, /* King of Fighters (XBOX) */
|
||||||
|
@ -357,7 +351,7 @@ typedef enum {
|
||||||
meta_MUSX_V006, /* Spyro Games, possibly more */
|
meta_MUSX_V006, /* Spyro Games, possibly more */
|
||||||
meta_MUSX_V010, /* Spyro Games, possibly more */
|
meta_MUSX_V010, /* Spyro Games, possibly more */
|
||||||
meta_MUSX_V201, /* Sphinx and the cursed Mummy */
|
meta_MUSX_V201, /* Sphinx and the cursed Mummy */
|
||||||
meta_LEG, /* Legaia 2 */
|
meta_LEG, /* Legaia 2 [no header_id] */
|
||||||
meta_FILP, /* Resident Evil - Dead Aim */
|
meta_FILP, /* Resident Evil - Dead Aim */
|
||||||
meta_IKM, /* Zwei! */
|
meta_IKM, /* Zwei! */
|
||||||
meta_SFS, /* Baroque */
|
meta_SFS, /* Baroque */
|
||||||
|
@ -366,8 +360,8 @@ typedef enum {
|
||||||
meta_PS2_KCES, /* Dance Dance Revolution */
|
meta_PS2_KCES, /* Dance Dance Revolution */
|
||||||
meta_PS2_DXH, /* Tokobot Plus - Myteries of the Karakuri */
|
meta_PS2_DXH, /* Tokobot Plus - Myteries of the Karakuri */
|
||||||
meta_PS2_PSH, /* Dawn of Mana - Seiken Densetsu 4 */
|
meta_PS2_PSH, /* Dawn of Mana - Seiken Densetsu 4 */
|
||||||
meta_PCM_SCD, /* Ephemeral Fantasia */
|
meta_PCM_SCD, /* Lunar - Eternal Blue */
|
||||||
meta_PCM_PS2, /* Lunar - Eternal Blue */
|
meta_PCM_PS2, /* Konami: Ephemeral Fantasia, Yu-Gi-Oh! The Duelists of the Roses */
|
||||||
meta_PS2_RKV, /* Legacy of Kain - Blood Omen 2 */
|
meta_PS2_RKV, /* Legacy of Kain - Blood Omen 2 */
|
||||||
meta_PS2_PSW, /* Rayman Raving Rabbids */
|
meta_PS2_PSW, /* Rayman Raving Rabbids */
|
||||||
meta_PS2_VAS, /* Pro Baseball Spirits 5 */
|
meta_PS2_VAS, /* Pro Baseball Spirits 5 */
|
||||||
|
@ -376,7 +370,7 @@ typedef enum {
|
||||||
meta_SDT, /* Baldur's Gate - Dark Alliance */
|
meta_SDT, /* Baldur's Gate - Dark Alliance */
|
||||||
meta_NGC_TYDSP, /* Ty - The Tasmanian Tiger */
|
meta_NGC_TYDSP, /* Ty - The Tasmanian Tiger */
|
||||||
meta_NGC_SWD, /* Conflict - Desert Storm 1 & 2 */
|
meta_NGC_SWD, /* Conflict - Desert Storm 1 & 2 */
|
||||||
meta_CAPDSP, /* Capcom DSP Header */
|
meta_CAPDSP, /* Capcom DSP Header [no header_id] */
|
||||||
meta_DC_STR, /* SEGA Stream Asset Builder */
|
meta_DC_STR, /* SEGA Stream Asset Builder */
|
||||||
meta_DC_STR_V2, /* variant of SEGA Stream Asset Builder */
|
meta_DC_STR_V2, /* variant of SEGA Stream Asset Builder */
|
||||||
meta_NGC_BH2PCM, /* Bio Hazard 2 */
|
meta_NGC_BH2PCM, /* Bio Hazard 2 */
|
||||||
|
@ -386,13 +380,12 @@ typedef enum {
|
||||||
meta_PS2_OMU, /* PS2 Int file with Header */
|
meta_PS2_OMU, /* PS2 Int file with Header */
|
||||||
meta_PS2_XA2, /* XG3 Extreme-G Racing */
|
meta_PS2_XA2, /* XG3 Extreme-G Racing */
|
||||||
meta_IDSP, /* Chronicles of Narnia, Soul Calibur Legends, Mario Strikers Charged */
|
meta_IDSP, /* Chronicles of Narnia, Soul Calibur Legends, Mario Strikers Charged */
|
||||||
meta_SPT_SPD, /* Variouis */
|
meta_SPT_SPD, /* Various (SPT+SPT DSP) */
|
||||||
meta_ISH_ISD, /* Various */
|
meta_ISH_ISD, /* Various (ISH+ISD DSP) */
|
||||||
meta_GSP_GSB, /* Various */
|
meta_GSP_GSB, /* Tecmo games (Super Swing Golf 1 & 2, Quamtum Theory) */
|
||||||
meta_YDSP, /* WWE Day of Reckoning */
|
meta_YDSP, /* WWE Day of Reckoning */
|
||||||
meta_FFCC_STR, /* Final Fantasy: Crystal Chronicles */
|
meta_FFCC_STR, /* Final Fantasy: Crystal Chronicles */
|
||||||
|
|
||||||
|
|
||||||
meta_WAA_WAC_WAD_WAM, /* Beyond Good & Evil */
|
meta_WAA_WAC_WAD_WAM, /* Beyond Good & Evil */
|
||||||
meta_GCA, /* Metal Slug Anthology */
|
meta_GCA, /* Metal Slug Anthology */
|
||||||
meta_MSVP, /* Popcap Hits */
|
meta_MSVP, /* Popcap Hits */
|
||||||
|
@ -427,7 +420,7 @@ typedef enum {
|
||||||
|
|
||||||
meta_PS2_ASS, /* ASS */
|
meta_PS2_ASS, /* ASS */
|
||||||
meta_PS2_SEG, /* Eragon */
|
meta_PS2_SEG, /* Eragon */
|
||||||
meta_XBOX_SEG,
|
meta_XBOX_SEG, /* Eragon */
|
||||||
meta_NDS_STRM_FFTA2, /* Final Fantasy Tactics A2 */
|
meta_NDS_STRM_FFTA2, /* Final Fantasy Tactics A2 */
|
||||||
meta_STR_ASR, /* Donkey Kong Jet Race */
|
meta_STR_ASR, /* Donkey Kong Jet Race */
|
||||||
meta_ZWDSP, /* Zack and Wiki */
|
meta_ZWDSP, /* Zack and Wiki */
|
||||||
|
@ -450,7 +443,7 @@ typedef enum {
|
||||||
meta_XBOX_WAVM, /* XBOX WAVM File */
|
meta_XBOX_WAVM, /* XBOX WAVM File */
|
||||||
meta_XBOX_RIFF, /* XBOX RIFF/WAVE File */
|
meta_XBOX_RIFF, /* XBOX RIFF/WAVE File */
|
||||||
meta_XBOX_WVS, /* XBOX WVS */
|
meta_XBOX_WVS, /* XBOX WVS */
|
||||||
meta_NGC_WVS, /* NGC WVS */
|
meta_NGC_WVS, /* Metal Arms - Glitch in the System */
|
||||||
meta_XBOX_STMA, /* XBOX STMA */
|
meta_XBOX_STMA, /* XBOX STMA */
|
||||||
meta_XBOX_MATX, /* XBOX MATX */
|
meta_XBOX_MATX, /* XBOX MATX */
|
||||||
meta_XBOX_XMU, /* XBOX XMU */
|
meta_XBOX_XMU, /* XBOX XMU */
|
||||||
|
@ -462,35 +455,22 @@ typedef enum {
|
||||||
meta_EACS_PC, /* EACS PC */
|
meta_EACS_PC, /* EACS PC */
|
||||||
meta_EACS_PSX, /* EACS PSX */
|
meta_EACS_PSX, /* EACS PSX */
|
||||||
meta_EACS_SAT, /* EACS SATURN */
|
meta_EACS_SAT, /* EACS SATURN */
|
||||||
meta_EA_ADPCM, /* EA XA ADPCM */
|
meta_EA_ADPCM, /* EA header using XA ADPCM */
|
||||||
meta_EA_IMA, /* EA IMA */
|
meta_EA_IMA, /* EA header using IMA */
|
||||||
meta_EA_PCM, /* EA PCM */
|
meta_EA_PCM, /* EA header using PCM */
|
||||||
|
|
||||||
meta_RAW, /* RAW PCM file */
|
meta_RAW, /* RAW PCM file */
|
||||||
|
|
||||||
meta_GENH, /* generic header */
|
meta_GENH, /* generic header */
|
||||||
|
|
||||||
#ifdef VGM_USE_VORBIS
|
|
||||||
meta_ogg_vorbis, /* ogg vorbis */
|
|
||||||
meta_OGG_SLI, /* Ogg Vorbis file w/ companion .sli for looping */
|
|
||||||
meta_OGG_SLI2, /* Ogg Vorbis file w/ different styled .sli for looping */
|
|
||||||
meta_OGG_SFL, /* Ogg Vorbis file w/ .sfl (RIFF SFPL) for looping */
|
|
||||||
meta_um3_ogg, /* Ogg Vorbis with first 0x800 bytes XOR 0xFF */
|
|
||||||
meta_KOVS_ogg, /* Ogg Vorbis with exta header and 0x100 bytes XOR */
|
|
||||||
meta_psych_ogg, /* Ogg Vorbis with all bytes -0x23*/
|
|
||||||
#endif
|
|
||||||
|
|
||||||
meta_AIFC, /* Audio Interchange File Format AIFF-C */
|
meta_AIFC, /* Audio Interchange File Format AIFF-C */
|
||||||
meta_AIFF, /* Audio Interchange File Format */
|
meta_AIFF, /* Audio Interchange File Format */
|
||||||
meta_STR_SNDS, /* .str with SNDS blocks and SHDR header */
|
meta_STR_SNDS, /* .str with SNDS blocks and SHDR header */
|
||||||
meta_WS_AUD, /* Westwood Studios .aud */
|
meta_WS_AUD, /* Westwood Studios .aud */
|
||||||
meta_WS_AUD_old, /* Westwood Studios .aud, old style */
|
meta_WS_AUD_old, /* Westwood Studios .aud, old style */
|
||||||
#ifdef VGM_USE_MPEG
|
|
||||||
meta_AHX, /* CRI AHX header (same structure as ADX) */
|
|
||||||
#endif
|
|
||||||
meta_RIFF_WAVE, /* RIFF, for WAVs */
|
meta_RIFF_WAVE, /* RIFF, for WAVs */
|
||||||
meta_RIFF_WAVE_POS, /* .wav + .pos for looping */
|
meta_RIFF_WAVE_POS, /* .wav + .pos for looping */
|
||||||
meta_RIFF_WAVE_labl_Marker, /* RIFF w/ loop Markers in LIST-adtl-labl */
|
meta_RIFF_WAVE_labl, /* RIFF w/ loop Markers in LIST-adtl-labl */
|
||||||
meta_RIFF_WAVE_smpl, /* RIFF w/ loop data in smpl chunk */
|
meta_RIFF_WAVE_smpl, /* RIFF w/ loop data in smpl chunk */
|
||||||
meta_RIFF_WAVE_MWV, /* .mwv RIFF w/ loop data in ctrl chunk pflt */
|
meta_RIFF_WAVE_MWV, /* .mwv RIFF w/ loop data in ctrl chunk pflt */
|
||||||
meta_RIFF_WAVE_SNS, /* .sns RIFF */
|
meta_RIFF_WAVE_SNS, /* .sns RIFF */
|
||||||
|
@ -500,8 +480,8 @@ typedef enum {
|
||||||
meta_PC_MXST, /* Lego Island MxSt */
|
meta_PC_MXST, /* Lego Island MxSt */
|
||||||
meta_PC_SOB_SAB, /* Worms 4 Mayhem SOB+SAB file */
|
meta_PC_SOB_SAB, /* Worms 4 Mayhem SOB+SAB file */
|
||||||
meta_NWA, /* Visual Art's NWA */
|
meta_NWA, /* Visual Art's NWA */
|
||||||
meta_NWA_NWAINFOINI, /* NWA w/ NWAINFO.INI for looping */
|
meta_NWA_NWAINFOINI, /* Visual Art's NWA w/ NWAINFO.INI for looping */
|
||||||
meta_NWA_GAMEEXEINI, /* NWA w/ Gameexe.ini for looping */
|
meta_NWA_GAMEEXEINI, /* Visual Art's NWA w/ Gameexe.ini for looping */
|
||||||
meta_DVI, /* DVI Interleaved */
|
meta_DVI, /* DVI Interleaved */
|
||||||
meta_KCEY, /* KCEYCOMP */
|
meta_KCEY, /* KCEYCOMP */
|
||||||
meta_ACM, /* InterPlay ACM header */
|
meta_ACM, /* InterPlay ACM header */
|
||||||
|
@ -565,14 +545,14 @@ typedef enum {
|
||||||
meta_PS2_LPCM, /* Ah! My Goddess */
|
meta_PS2_LPCM, /* Ah! My Goddess */
|
||||||
meta_DSP_BDSP, /* Ah! My Goddess */
|
meta_DSP_BDSP, /* Ah! My Goddess */
|
||||||
meta_PS2_VMS, /* Autobahn Raser - Police Madness */
|
meta_PS2_VMS, /* Autobahn Raser - Police Madness */
|
||||||
meta_PS2_XAU, // Spectral Force Chronicle
|
meta_PS2_XAU, /* Spectral Force Chronicle */
|
||||||
meta_GH3_BAR, /* Guitar Hero III Mobile .bar */
|
meta_GH3_BAR, /* Guitar Hero III Mobile .bar */
|
||||||
meta_FFW, /* Freedom Fighters [NGC] */
|
meta_FFW, /* Freedom Fighters [NGC] */
|
||||||
meta_DSP_DSPW, /* Sengoku Basara 3 [WII] */
|
meta_DSP_DSPW, /* Sengoku Basara 3 [WII] */
|
||||||
meta_PS2_JSTM, /* Tantei Jinguji Saburo - Kind of Blue (PS2) */
|
meta_PS2_JSTM, /* Tantei Jinguji Saburo - Kind of Blue (PS2) */
|
||||||
meta_SQEX_SCD, /* Square-Enix SCD */
|
meta_SQEX_SCD, /* Square-Enix SCD */
|
||||||
meta_NGC_NST_DSP, /* Animaniacs [NGC] */
|
meta_NGC_NST_DSP, /* Animaniacs [NGC] */
|
||||||
meta_BAF, /* .baf (Blur) */
|
meta_BAF, /* Bizarre Creations (Blur, James Bond) */
|
||||||
meta_PS3_XVAG, /* Ratchet & Clank Future: Quest for Booty (PS3) */
|
meta_PS3_XVAG, /* Ratchet & Clank Future: Quest for Booty (PS3) */
|
||||||
meta_PS3_CPS, /* Eternal Sonata (PS3) */
|
meta_PS3_CPS, /* Eternal Sonata (PS3) */
|
||||||
meta_PS3_MSF, /* MSF header */
|
meta_PS3_MSF, /* MSF header */
|
||||||
|
@ -583,11 +563,11 @@ typedef enum {
|
||||||
meta_WII_RAS, /* Donkey Kong Country Returns (Wii) */
|
meta_WII_RAS, /* Donkey Kong Country Returns (Wii) */
|
||||||
meta_PS2_SPM, /* Lethal Skies Elite Pilot: Team SW */
|
meta_PS2_SPM, /* Lethal Skies Elite Pilot: Team SW */
|
||||||
meta_X360_TRA, /* Def Jam Rapstar */
|
meta_X360_TRA, /* Def Jam Rapstar */
|
||||||
meta_PS2_VGS, // Princess Soft PS2 games
|
meta_PS2_VGS, /* Princess Soft PS2 games */
|
||||||
meta_PS2_IAB, // Ueki no Housoku - Taosu ze Robert Juudan!! (PS2)
|
meta_PS2_IAB, /* Ueki no Housoku - Taosu ze Robert Juudan!! (PS2) */
|
||||||
meta_PS2_STRLR,
|
meta_PS2_STRLR, /* The Bouncer */
|
||||||
meta_LSF_N1NJ4N, /* .lsf n1nj4n Fastlane Street Racing (iPhone) */
|
meta_LSF_N1NJ4N, /* .lsf n1nj4n Fastlane Street Racing (iPhone) */
|
||||||
meta_PS3_VAWX, // No More Heroes: Heroes Paradise (PS3)
|
meta_VAWX, /* feelplus: No More Heroes Heroes Paradise, Moon Diver */
|
||||||
meta_PC_SNDS, // Incredibles PC .snds
|
meta_PC_SNDS, // Incredibles PC .snds
|
||||||
meta_PS2_WMUS, // The Warriors (PS2)
|
meta_PS2_WMUS, // The Warriors (PS2)
|
||||||
meta_HYPERSCAN_KVAG, // Hyperscan KVAG/BVG
|
meta_HYPERSCAN_KVAG, // Hyperscan KVAG/BVG
|
||||||
|
@ -602,28 +582,45 @@ typedef enum {
|
||||||
meta_TUN, // LEGO Racers (PC)
|
meta_TUN, // LEGO Racers (PC)
|
||||||
meta_WPD, // Shuffle! (PC)
|
meta_WPD, // Shuffle! (PC)
|
||||||
meta_MN_STR, // Mini Ninjas (PC/PS3/WII)
|
meta_MN_STR, // Mini Ninjas (PC/PS3/WII)
|
||||||
meta_PS2_MSS, // ShellShock Nam '67 (PS2)
|
meta_PS2_MSS, // Guerilla: ShellShock Nam '67, Killzone (PS2)
|
||||||
meta_PS2_HSF, // Lowrider (PS2)
|
meta_PS2_HSF, // Lowrider (PS2)
|
||||||
meta_PS3_IVAG, // Interleaved VAG files (PS3)
|
meta_PS3_IVAG, // Interleaved VAG files (PS3)
|
||||||
meta_PS2_2PFS, // Mahoromatic: Moetto - KiraKira Maid-San (PS2)
|
meta_PS2_2PFS, // Konami: Mahoromatic: Moetto - KiraKira Maid-San, GANTZ (PS2)
|
||||||
meta_PS2_VBK,
|
meta_PS2_VBK, // Disney's Stitch - Experiment 626
|
||||||
meta_OTM, // Otomedius (Arcade)
|
meta_OTM, // Otomedius (Arcade)
|
||||||
meta_CSTM, // Nintendo 3DS CSTM
|
meta_CSTM, // Nintendo 3DS CSTM
|
||||||
meta_FSTM, // Nintendo Wii U FSTM
|
meta_FSTM, // Nintendo Wii U FSTM
|
||||||
meta_3DS_IDSP, // Nintendo 3DS IDSP
|
meta_3DS_IDSP, // Nintendo 3DS/Wii U IDSP
|
||||||
meta_G1L, // Tecmo Koei G1L
|
meta_KT_WIIBGM, // Koei Tecmo WiiBGM
|
||||||
meta_MCA, // Capcom MCA "MADP"
|
meta_MCA, // Capcom MCA "MADP"
|
||||||
meta_XB3D_ADX, // Xenoblade Chronicles 3D ADX
|
meta_XB3D_ADX, // Xenoblade Chronicles 3D ADX
|
||||||
meta_HCA,
|
meta_HCA, /* CRI HCA */
|
||||||
meta_PS2_SVAG_SNK, /* SNK PS2 SVAG */
|
meta_PS2_SVAG_SNK, /* SNK PS2 SVAG */
|
||||||
|
meta_PS2_VDS_VDM, /* Graffiti Kingdom */
|
||||||
|
meta_X360_CXS, /* Eternal Sonata (Xbox 360) */
|
||||||
|
|
||||||
|
#ifdef VGM_USE_VORBIS
|
||||||
|
meta_OGG_VORBIS, /* Ogg Vorbis */
|
||||||
|
meta_OGG_SLI, /* Ogg Vorbis file w/ companion .sli for looping */
|
||||||
|
meta_OGG_SLI2, /* Ogg Vorbis file w/ different styled .sli for looping */
|
||||||
|
meta_OGG_SFL, /* Ogg Vorbis file w/ .sfl (RIFF SFPL) for looping */
|
||||||
|
meta_OGG_UM3, /* Ogg Vorbis with first 0x800 bytes XOR 0xFF */
|
||||||
|
meta_OGG_KOVS, /* Ogg Vorbis with exta header and 0x100 bytes XOR */
|
||||||
|
meta_OGG_PSYCH, /* Ogg Vorbis with all bytes -0x23*/
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_MPEG
|
||||||
|
meta_AHX, /* CRI AHX header (same structure as ADX) */
|
||||||
|
#endif
|
||||||
|
#ifdef VGM_USE_MP4V2
|
||||||
|
meta_MP4, /* AAC (iOS) */
|
||||||
|
#endif
|
||||||
#ifdef VGM_USE_FFMPEG
|
#ifdef VGM_USE_FFMPEG
|
||||||
meta_FFmpeg,
|
meta_FFmpeg,
|
||||||
#endif
|
#endif
|
||||||
#ifdef VGM_USE_MP4V2
|
|
||||||
meta_MP4,
|
|
||||||
#endif
|
|
||||||
} meta_t;
|
} meta_t;
|
||||||
|
|
||||||
|
|
||||||
|
/* info for a single vgmstream channel */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
STREAMFILE * streamfile; /* file used by this channel */
|
STREAMFILE * streamfile; /* file used by this channel */
|
||||||
off_t channel_start_offset; /* where data for this channel begins */
|
off_t channel_start_offset; /* where data for this channel begins */
|
||||||
|
@ -660,13 +657,8 @@ typedef struct {
|
||||||
int adpcm_step_index; /* for IMA */
|
int adpcm_step_index; /* for IMA */
|
||||||
int adpcm_scale; /* for MS ADPCM */
|
int adpcm_scale; /* for MS ADPCM */
|
||||||
|
|
||||||
struct g72x_state g72x_state; /* state for G.721 decoder, sort of big but we
|
/* state for G.721 decoder, sort of big but we might as well keep it around */
|
||||||
might as well keep it around */
|
struct g72x_state g72x_state;
|
||||||
|
|
||||||
#ifdef DEBUG
|
|
||||||
int samples_done;
|
|
||||||
int16_t loop_history1,loop_history2;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ADX encryption */
|
/* ADX encryption */
|
||||||
int adx_channels;
|
int adx_channels;
|
||||||
|
@ -682,6 +674,7 @@ typedef struct {
|
||||||
uint16_t key_xor;
|
uint16_t key_xor;
|
||||||
} VGMSTREAMCHANNEL;
|
} VGMSTREAMCHANNEL;
|
||||||
|
|
||||||
|
/* main vgmstream info */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
/* basics */
|
/* basics */
|
||||||
int32_t num_samples; /* the actual number of samples in this stream */
|
int32_t num_samples; /* the actual number of samples in this stream */
|
||||||
|
@ -719,28 +712,28 @@ typedef struct {
|
||||||
|
|
||||||
/* loop layout (saved values) */
|
/* loop layout (saved values) */
|
||||||
int32_t loop_sample; /* saved from current_sample, should be loop_start_sample... */
|
int32_t loop_sample; /* saved from current_sample, should be loop_start_sample... */
|
||||||
int32_t loop_samples_into_block; /* saved from samples_into_block */
|
int32_t loop_samples_into_block;/* saved from samples_into_block */
|
||||||
off_t loop_block_offset; /* saved from current_block_offset */
|
off_t loop_block_offset; /* saved from current_block_offset */
|
||||||
size_t loop_block_size; /* saved from current_block_size */
|
size_t loop_block_size; /* saved from current_block_size */
|
||||||
off_t loop_next_block_offset; /* saved from next_block_offset */
|
off_t loop_next_block_offset; /* saved from next_block_offset */
|
||||||
|
|
||||||
uint8_t xa_channel; /* Selected XA Channel */
|
/* decoder specific */
|
||||||
int32_t xa_sector_length; /* XA block */
|
uint8_t xa_channel; /* XA ADPCM: selected channel */
|
||||||
uint8_t xa_headerless; /* headerless XA block */
|
int32_t xa_sector_length; /* XA ADPCM: XA block */
|
||||||
int8_t get_high_nibble;
|
uint8_t xa_headerless; /* XA ADPCM: headerless XA block */
|
||||||
|
|
||||||
uint8_t ea_big_endian; /* Big Endian ? */
|
int8_t get_high_nibble; /* ADPCM: which nibble (XA, IMA, EA) */
|
||||||
|
|
||||||
|
uint8_t ea_big_endian; /* EA ADPCM stuff */
|
||||||
uint8_t ea_compression_type;
|
uint8_t ea_compression_type;
|
||||||
uint8_t ea_compression_version;
|
uint8_t ea_compression_version;
|
||||||
uint8_t ea_platform;
|
uint8_t ea_platform;
|
||||||
|
|
||||||
int32_t ws_output_size; /* output bytes for this block */
|
int32_t ws_output_size; /* WS ADPCM: output bytes for this block */
|
||||||
|
|
||||||
void * start_vgmstream; /* a copy of the VGMSTREAM as it was at the beginning of the stream */
|
int32_t thpNextFrameSize; /* THP */
|
||||||
|
|
||||||
int32_t thpNextFrameSize;
|
void * start_vgmstream; /* a copy of the VGMSTREAM as it was at the beginning of the stream (for AAX/AIX/SCD) */
|
||||||
|
|
||||||
int skip_last_channel;
|
|
||||||
|
|
||||||
/* Data the codec needs for the whole stream. This is for codecs too
|
/* Data the codec needs for the whole stream. This is for codecs too
|
||||||
* different from vgmstream's structure to be reasonably shoehorned into
|
* different from vgmstream's structure to be reasonably shoehorned into
|
||||||
|
@ -757,9 +750,11 @@ typedef struct {
|
||||||
ogg_int64_t size;
|
ogg_int64_t size;
|
||||||
ogg_int64_t other_header_bytes;
|
ogg_int64_t other_header_bytes;
|
||||||
|
|
||||||
// XOR setup with a single byte (SCD)
|
/* XOR setup (SCD) */
|
||||||
unsigned char scd_xor;
|
int decryption_enabled;
|
||||||
ogg_int64_t scd_xor_len;
|
void (*decryption_callback)(void *ptr, size_t size, size_t nmemb, void *datasource, int bytes_read);
|
||||||
|
uint8_t scd_xor;
|
||||||
|
off_t scd_xor_length;
|
||||||
} ogg_vorbis_streamfile;
|
} ogg_vorbis_streamfile;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -774,6 +769,7 @@ typedef struct {
|
||||||
#define AHX_EXPECTED_FRAME_SIZE 0x414
|
#define AHX_EXPECTED_FRAME_SIZE 0x414
|
||||||
/* MPEG_BUFFER_SIZE should be >= AHX_EXPECTED_FRAME_SIZE */
|
/* MPEG_BUFFER_SIZE should be >= AHX_EXPECTED_FRAME_SIZE */
|
||||||
#define MPEG_BUFFER_SIZE 0x1000
|
#define MPEG_BUFFER_SIZE 0x1000
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
uint8_t buffer[MPEG_BUFFER_SIZE];
|
uint8_t buffer[MPEG_BUFFER_SIZE];
|
||||||
int buffer_used;
|
int buffer_used;
|
||||||
|
@ -806,8 +802,7 @@ typedef struct {
|
||||||
} maiatrac3plus_codec_data;
|
} maiatrac3plus_codec_data;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* with one file this is also used for just
|
/* with one file this is also used for just ACM */
|
||||||
ACM */
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int file_count;
|
int file_count;
|
||||||
int current_file;
|
int current_file;
|
||||||
|
@ -850,6 +845,7 @@ typedef struct {
|
||||||
NWAData *nwa;
|
NWAData *nwa;
|
||||||
} nwa_codec_data;
|
} nwa_codec_data;
|
||||||
|
|
||||||
|
/* SQEX SCD interleaved */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int substream_count;
|
int substream_count;
|
||||||
VGMSTREAM **substreams;
|
VGMSTREAM **substreams;
|
||||||
|
@ -942,6 +938,11 @@ typedef struct {
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------*/
|
||||||
|
/* vgmstream "public" API */
|
||||||
|
/* -------------------------------------------------------------------------*/
|
||||||
|
|
||||||
/* do format detection, return pointer to a usable VGMSTREAM, or NULL on failure */
|
/* do format detection, return pointer to a usable VGMSTREAM, or NULL on failure */
|
||||||
VGMSTREAM * init_vgmstream(const char * const filename);
|
VGMSTREAM * init_vgmstream(const char * const filename);
|
||||||
|
|
||||||
|
@ -950,10 +951,7 @@ VGMSTREAM * init_vgmstream_from_STREAMFILE(STREAMFILE *streamFile);
|
||||||
/* reset a VGMSTREAM to start of stream */
|
/* reset a VGMSTREAM to start of stream */
|
||||||
void reset_vgmstream(VGMSTREAM * vgmstream);
|
void reset_vgmstream(VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
/* allocate a VGMSTREAM and channel stuff */
|
/* close an open vgmstream */
|
||||||
VGMSTREAM * allocate_vgmstream(int channel_count, int looped);
|
|
||||||
|
|
||||||
/* deallocate, close, etc. */
|
|
||||||
void close_vgmstream(VGMSTREAM * vgmstream);
|
void close_vgmstream(VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
/* calculate the number of samples to be played based on looping parameters */
|
/* calculate the number of samples to be played based on looping parameters */
|
||||||
|
@ -962,6 +960,21 @@ int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double
|
||||||
/* render! */
|
/* render! */
|
||||||
void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
|
/* Write a description of the stream into array pointed by desc,
|
||||||
|
* which must be length bytes long. Will always be null-terminated if length > 0 */
|
||||||
|
void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length);
|
||||||
|
|
||||||
|
/* Return the average bitrate in bps of all unique files contained within this
|
||||||
|
* stream. Compares files by absolute paths. */
|
||||||
|
int get_vgmstream_average_bitrate(VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
|
/* -------------------------------------------------------------------------*/
|
||||||
|
/* vgmstream "private" API */
|
||||||
|
/* -------------------------------------------------------------------------*/
|
||||||
|
|
||||||
|
/* allocate a VGMSTREAM and channel stuff */
|
||||||
|
VGMSTREAM * allocate_vgmstream(int channel_count, int looped);
|
||||||
|
|
||||||
/* smallest self-contained group of samples is a frame */
|
/* smallest self-contained group of samples is a frame */
|
||||||
int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream);
|
int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream);
|
||||||
/* number of bytes per frame */
|
/* number of bytes per frame */
|
||||||
|
@ -985,19 +998,14 @@ int vgmstream_samples_to_do(int samples_this_block, int samples_per_frame, VGMST
|
||||||
* Returns 1 if loop was done. */
|
* Returns 1 if loop was done. */
|
||||||
int vgmstream_do_loop(VGMSTREAM * vgmstream);
|
int vgmstream_do_loop(VGMSTREAM * vgmstream);
|
||||||
|
|
||||||
/* Write a description of the stream into array pointed by desc,
|
|
||||||
* which must be length bytes long. Will always be null-terminated if length > 0
|
|
||||||
*/
|
|
||||||
void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length);
|
|
||||||
|
|
||||||
/* See if there is a second file which may be the second channel, given
|
/* See if there is a second file which may be the second channel, given
|
||||||
* already opened mono opened_stream which was opened from filename.
|
* already opened mono opened_stream which was opened from filename.
|
||||||
* If a suitable file is found, open it and change opened_stream to a
|
* If a suitable file is found, open it and change opened_stream to a stereo stream. */
|
||||||
* stereo stream. */
|
|
||||||
void try_dual_file_stereo(VGMSTREAM * opened_stream, STREAMFILE *streamFile);
|
void try_dual_file_stereo(VGMSTREAM * opened_stream, STREAMFILE *streamFile);
|
||||||
|
|
||||||
/* Return the average bitrate in bps of all unique files contained within this
|
|
||||||
* stream. Compares files by absolute paths. */
|
/* Open the stream for reading at offset (standarized taking into account layouts, channels and so on).
|
||||||
int get_vgmstream_average_bitrate(VGMSTREAM * vgmstream);
|
* returns 0 on failure */
|
||||||
|
int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t start_offset);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
--disable-postproc --disable-swresample --disable-avfilter\
|
--disable-postproc --disable-swresample --disable-avfilter\
|
||||||
--disable-swscale --disable-network --disable-swscale-alpha --disable-vdpau\
|
--disable-swscale --disable-network --disable-swscale-alpha --disable-vdpau\
|
||||||
--disable-dxva2 --disable-everything --enable-hwaccels\
|
--disable-dxva2 --disable-everything --enable-hwaccels\
|
||||||
--enable-parser=ac3,mpegaudio\
|
--enable-parser=ac3,mpegaudio,xma\
|
||||||
--enable-demuxer=ac3,asf,xwma,mov,oma,ogg,tak,dsf,wav,aac,dts,dtshd,mp3\
|
--enable-demuxer=ac3,asf,xwma,mov,oma,ogg,tak,dsf,wav,aac,dts,dtshd,mp3\
|
||||||
--enable-demuxer=bink,flac,msf,xmv\
|
--enable-demuxer=bink,flac,msf,xmv\
|
||||||
--enable-decoder=ac3,wmapro,wmav1,wmav2,wmavoice,wmalossless,xma1,xma2\
|
--enable-decoder=ac3,wmapro,wmav1,wmav2,wmavoice,wmalossless,xma1,xma2\
|
||||||
|
|
|
@ -89,7 +89,7 @@
|
||||||
* - Send valid input:
|
* - Send valid input:
|
||||||
* - For decoding, call avcodec_send_packet() to give the decoder raw
|
* - For decoding, call avcodec_send_packet() to give the decoder raw
|
||||||
* compressed data in an AVPacket.
|
* compressed data in an AVPacket.
|
||||||
* - For encoding, call avcodec_send_frame() to give the decoder an AVFrame
|
* - For encoding, call avcodec_send_frame() to give the encoder an AVFrame
|
||||||
* containing uncompressed audio or video.
|
* containing uncompressed audio or video.
|
||||||
* In both cases, it is recommended that AVPackets and AVFrames are
|
* In both cases, it is recommended that AVPackets and AVFrames are
|
||||||
* refcounted, or libavcodec might have to copy the input data. (libavformat
|
* refcounted, or libavcodec might have to copy the input data. (libavformat
|
||||||
|
@ -411,6 +411,9 @@ enum AVCodecID {
|
||||||
AV_CODEC_ID_MAGICYUV,
|
AV_CODEC_ID_MAGICYUV,
|
||||||
AV_CODEC_ID_SHEERVIDEO,
|
AV_CODEC_ID_SHEERVIDEO,
|
||||||
AV_CODEC_ID_YLC,
|
AV_CODEC_ID_YLC,
|
||||||
|
AV_CODEC_ID_PSD,
|
||||||
|
AV_CODEC_ID_PIXLET,
|
||||||
|
AV_CODEC_ID_SPEEDHQ,
|
||||||
|
|
||||||
/* various PCM "codecs" */
|
/* various PCM "codecs" */
|
||||||
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
|
AV_CODEC_ID_FIRST_AUDIO = 0x10000, ///< A dummy id pointing at the start of audio codecs
|
||||||
|
@ -448,6 +451,8 @@ enum AVCodecID {
|
||||||
|
|
||||||
AV_CODEC_ID_PCM_S64LE = 0x10800,
|
AV_CODEC_ID_PCM_S64LE = 0x10800,
|
||||||
AV_CODEC_ID_PCM_S64BE,
|
AV_CODEC_ID_PCM_S64BE,
|
||||||
|
AV_CODEC_ID_PCM_F16LE,
|
||||||
|
AV_CODEC_ID_PCM_F24LE,
|
||||||
|
|
||||||
/* various ADPCM codecs */
|
/* various ADPCM codecs */
|
||||||
AV_CODEC_ID_ADPCM_IMA_QT = 0x11000,
|
AV_CODEC_ID_ADPCM_IMA_QT = 0x11000,
|
||||||
|
@ -1536,7 +1541,13 @@ enum AVPacketSideDataType {
|
||||||
* should be associated with a video stream and containts data in the form
|
* should be associated with a video stream and containts data in the form
|
||||||
* of the AVMasteringDisplayMetadata struct.
|
* of the AVMasteringDisplayMetadata struct.
|
||||||
*/
|
*/
|
||||||
AV_PKT_DATA_MASTERING_DISPLAY_METADATA
|
AV_PKT_DATA_MASTERING_DISPLAY_METADATA,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This side data should be associated with a video stream and corresponds
|
||||||
|
* to the AVSphericalMapping structure.
|
||||||
|
*/
|
||||||
|
AV_PKT_DATA_SPHERICAL,
|
||||||
};
|
};
|
||||||
|
|
||||||
#define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS //DEPRECATED
|
#define AV_PKT_DATA_QUALITY_FACTOR AV_PKT_DATA_QUALITY_STATS //DEPRECATED
|
||||||
|
@ -3564,6 +3575,14 @@ typedef struct AVCodecContext {
|
||||||
*/
|
*/
|
||||||
int trailing_padding;
|
int trailing_padding;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The number of pixels per image to maximally accept.
|
||||||
|
*
|
||||||
|
* - decoding: set by user
|
||||||
|
* - encoding: set by user
|
||||||
|
*/
|
||||||
|
int64_t max_pixels;
|
||||||
|
|
||||||
} AVCodecContext;
|
} AVCodecContext;
|
||||||
|
|
||||||
AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx);
|
AVRational av_codec_get_pkt_timebase (const AVCodecContext *avctx);
|
||||||
|
|
|
@ -34,6 +34,8 @@
|
||||||
#include "libavutil/attributes.h"
|
#include "libavutil/attributes.h"
|
||||||
#include "version.h"
|
#include "version.h"
|
||||||
|
|
||||||
|
#if FF_API_STRUCT_VAAPI_CONTEXT
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @defgroup lavc_codec_hwaccel_vaapi VA API Decoding
|
* @defgroup lavc_codec_hwaccel_vaapi VA API Decoding
|
||||||
* @ingroup lavc_codec_hwaccel
|
* @ingroup lavc_codec_hwaccel
|
||||||
|
@ -48,7 +50,10 @@
|
||||||
* during initialization or through each AVCodecContext.get_buffer()
|
* during initialization or through each AVCodecContext.get_buffer()
|
||||||
* function call. In any case, they must be valid prior to calling
|
* function call. In any case, they must be valid prior to calling
|
||||||
* decoding functions.
|
* decoding functions.
|
||||||
|
*
|
||||||
|
* Deprecated: use AVCodecContext.hw_frames_ctx instead.
|
||||||
*/
|
*/
|
||||||
|
attribute_deprecated
|
||||||
struct vaapi_context {
|
struct vaapi_context {
|
||||||
/**
|
/**
|
||||||
* Window system dependent data
|
* Window system dependent data
|
||||||
|
@ -186,4 +191,6 @@ struct vaapi_context {
|
||||||
|
|
||||||
/* @} */
|
/* @} */
|
||||||
|
|
||||||
|
#endif /* FF_API_STRUCT_VAAPI_CONTEXT */
|
||||||
|
|
||||||
#endif /* AVCODEC_VAAPI_H */
|
#endif /* AVCODEC_VAAPI_H */
|
||||||
|
|
|
@ -28,8 +28,8 @@
|
||||||
#include "libavutil/version.h"
|
#include "libavutil/version.h"
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_MAJOR 57
|
#define LIBAVCODEC_VERSION_MAJOR 57
|
||||||
#define LIBAVCODEC_VERSION_MINOR 64
|
#define LIBAVCODEC_VERSION_MINOR 75
|
||||||
#define LIBAVCODEC_VERSION_MICRO 101
|
#define LIBAVCODEC_VERSION_MICRO 100
|
||||||
|
|
||||||
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
#define LIBAVCODEC_VERSION_INT AV_VERSION_INT(LIBAVCODEC_VERSION_MAJOR, \
|
||||||
LIBAVCODEC_VERSION_MINOR, \
|
LIBAVCODEC_VERSION_MINOR, \
|
||||||
|
@ -226,5 +226,8 @@
|
||||||
#ifndef FF_API_NVENC_OLD_NAME
|
#ifndef FF_API_NVENC_OLD_NAME
|
||||||
#define FF_API_NVENC_OLD_NAME (LIBAVCODEC_VERSION_MAJOR < 59)
|
#define FF_API_NVENC_OLD_NAME (LIBAVCODEC_VERSION_MAJOR < 59)
|
||||||
#endif
|
#endif
|
||||||
|
#ifndef FF_API_STRUCT_VAAPI_CONTEXT
|
||||||
|
#define FF_API_STRUCT_VAAPI_CONTEXT (LIBAVCODEC_VERSION_MAJOR < 59)
|
||||||
|
#endif
|
||||||
|
|
||||||
#endif /* AVCODEC_VERSION_H */
|
#endif /* AVCODEC_VERSION_H */
|
||||||
|
|
|
@ -930,6 +930,9 @@ typedef struct AVStream {
|
||||||
* Decoding: duration of the stream, in stream time base.
|
* Decoding: duration of the stream, in stream time base.
|
||||||
* If a source file does not specify a duration, but does specify
|
* If a source file does not specify a duration, but does specify
|
||||||
* a bitrate, this value will be estimated from bitrate and file size.
|
* a bitrate, this value will be estimated from bitrate and file size.
|
||||||
|
*
|
||||||
|
* Encoding: May be set by the caller before avformat_write_header() to
|
||||||
|
* provide a hint to the muxer about the estimated duration.
|
||||||
*/
|
*/
|
||||||
int64_t duration;
|
int64_t duration;
|
||||||
|
|
||||||
|
@ -1007,7 +1010,7 @@ typedef struct AVStream {
|
||||||
*/
|
*/
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Stream information used internally by av_find_stream_info()
|
* Stream information used internally by avformat_find_stream_info()
|
||||||
*/
|
*/
|
||||||
#define MAX_STD_TIMEBASES (30*12+30+3+6)
|
#define MAX_STD_TIMEBASES (30*12+30+3+6)
|
||||||
struct {
|
struct {
|
||||||
|
@ -1059,7 +1062,7 @@ typedef struct AVStream {
|
||||||
int probe_packets;
|
int probe_packets;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Number of frames that have been demuxed during av_find_stream_info()
|
* Number of frames that have been demuxed during avformat_find_stream_info()
|
||||||
*/
|
*/
|
||||||
int codec_info_nb_frames;
|
int codec_info_nb_frames;
|
||||||
|
|
||||||
|
@ -1899,6 +1902,13 @@ typedef struct AVFormatContext {
|
||||||
* - decoding: set by user through AVOptions (NO direct access)
|
* - decoding: set by user through AVOptions (NO direct access)
|
||||||
*/
|
*/
|
||||||
char *protocol_blacklist;
|
char *protocol_blacklist;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The maximum number of streams.
|
||||||
|
* - encoding: unused
|
||||||
|
* - decoding: set by user through AVOptions (NO direct access)
|
||||||
|
*/
|
||||||
|
int max_streams;
|
||||||
} AVFormatContext;
|
} AVFormatContext;
|
||||||
|
|
||||||
int av_format_get_probe_score(const AVFormatContext *s);
|
int av_format_get_probe_score(const AVFormatContext *s);
|
||||||
|
@ -2048,6 +2058,21 @@ const AVClass *avformat_get_class(void);
|
||||||
*/
|
*/
|
||||||
AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c);
|
AVStream *avformat_new_stream(AVFormatContext *s, const AVCodec *c);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrap an existing array as stream side data.
|
||||||
|
*
|
||||||
|
* @param st stream
|
||||||
|
* @param type side information type
|
||||||
|
* @param data the side data array. It must be allocated with the av_malloc()
|
||||||
|
* family of functions. The ownership of the data is transferred to
|
||||||
|
* st.
|
||||||
|
* @param size side information size
|
||||||
|
* @return zero on success, a negative AVERROR code on failure. On failure,
|
||||||
|
* the stream is unchanged and the data remains owned by the caller.
|
||||||
|
*/
|
||||||
|
int av_stream_add_side_data(AVStream *st, enum AVPacketSideDataType type,
|
||||||
|
uint8_t *data, size_t size);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Allocate new information from stream.
|
* Allocate new information from stream.
|
||||||
*
|
*
|
||||||
|
|
|
@ -703,6 +703,18 @@ int avio_closep(AVIOContext **s);
|
||||||
*/
|
*/
|
||||||
int avio_open_dyn_buf(AVIOContext **s);
|
int avio_open_dyn_buf(AVIOContext **s);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the written size and a pointer to the buffer.
|
||||||
|
* The AVIOContext stream is left intact.
|
||||||
|
* The buffer must NOT be freed.
|
||||||
|
* No padding is added to the buffer.
|
||||||
|
*
|
||||||
|
* @param s IO context
|
||||||
|
* @param pbuffer pointer to a byte buffer
|
||||||
|
* @return the length of the byte buffer
|
||||||
|
*/
|
||||||
|
int avio_get_dyn_buf(AVIOContext *s, uint8_t **pbuffer);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return the written size and a pointer to the buffer. The buffer
|
* Return the written size and a pointer to the buffer. The buffer
|
||||||
* must be freed with av_free().
|
* must be freed with av_free().
|
||||||
|
|
|
@ -32,7 +32,7 @@
|
||||||
// Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium)
|
// Major bumping may affect Ticket5467, 5421, 5451(compatibility with Chromium)
|
||||||
// Also please add any ticket numbers that you believe might be affected here
|
// Also please add any ticket numbers that you believe might be affected here
|
||||||
#define LIBAVFORMAT_VERSION_MAJOR 57
|
#define LIBAVFORMAT_VERSION_MAJOR 57
|
||||||
#define LIBAVFORMAT_VERSION_MINOR 56
|
#define LIBAVFORMAT_VERSION_MINOR 65
|
||||||
#define LIBAVFORMAT_VERSION_MICRO 100
|
#define LIBAVFORMAT_VERSION_MICRO 100
|
||||||
|
|
||||||
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
#define LIBAVFORMAT_VERSION_INT AV_VERSION_INT(LIBAVFORMAT_VERSION_MAJOR, \
|
||||||
|
|
|
@ -118,6 +118,12 @@
|
||||||
*
|
*
|
||||||
* @}
|
* @}
|
||||||
*
|
*
|
||||||
|
* @defgroup lavu_video Video related
|
||||||
|
*
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @}
|
||||||
|
*
|
||||||
* @defgroup lavu_audio Audio related
|
* @defgroup lavu_audio Audio related
|
||||||
*
|
*
|
||||||
* @{
|
* @{
|
||||||
|
|
|
@ -131,21 +131,30 @@ enum AVMatrixEncoding {
|
||||||
* 5.0(side), 5.1, 5.1(side), 7.1, 7.1(wide), downmix);
|
* 5.0(side), 5.1, 5.1(side), 7.1, 7.1(wide), downmix);
|
||||||
* - the name of a single channel (FL, FR, FC, LFE, BL, BR, FLC, FRC, BC,
|
* - the name of a single channel (FL, FR, FC, LFE, BL, BR, FLC, FRC, BC,
|
||||||
* SL, SR, TC, TFL, TFC, TFR, TBL, TBC, TBR, DL, DR);
|
* SL, SR, TC, TFL, TFC, TFR, TBL, TBC, TBR, DL, DR);
|
||||||
* - a number of channels, in decimal, optionally followed by 'c', yielding
|
* - a number of channels, in decimal, followed by 'c', yielding
|
||||||
* the default channel layout for that number of channels (@see
|
* the default channel layout for that number of channels (@see
|
||||||
* av_get_default_channel_layout);
|
* av_get_default_channel_layout);
|
||||||
* - a channel layout mask, in hexadecimal starting with "0x" (see the
|
* - a channel layout mask, in hexadecimal starting with "0x" (see the
|
||||||
* AV_CH_* macros).
|
* AV_CH_* macros).
|
||||||
*
|
*
|
||||||
* @warning Starting from the next major bump the trailing character
|
|
||||||
* 'c' to specify a number of channels will be required, while a
|
|
||||||
* channel layout mask could also be specified as a decimal number
|
|
||||||
* (if and only if not followed by "c").
|
|
||||||
*
|
|
||||||
* Example: "stereo+FC" = "2c+FC" = "2c+1c" = "0x7"
|
* Example: "stereo+FC" = "2c+FC" = "2c+1c" = "0x7"
|
||||||
*/
|
*/
|
||||||
uint64_t av_get_channel_layout(const char *name);
|
uint64_t av_get_channel_layout(const char *name);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return a channel layout and the number of channels based on the specified name.
|
||||||
|
*
|
||||||
|
* This function is similar to (@see av_get_channel_layout), but can also parse
|
||||||
|
* unknown channel layout specifications.
|
||||||
|
*
|
||||||
|
* @param[in] name channel layout specification string
|
||||||
|
* @param[out] channel_layout parsed channel layout (0 if unknown)
|
||||||
|
* @param[out] nb_channels number of channels
|
||||||
|
*
|
||||||
|
* @return 0 on success, AVERROR(EINVAL) if the parsing fails.
|
||||||
|
*/
|
||||||
|
int av_get_extended_channel_layout(const char *name, uint64_t* channel_layout, int* nb_channels);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Return a description of a channel layout.
|
* Return a description of a channel layout.
|
||||||
* If nb_channels is <= 0, it is guessed from the channel_layout.
|
* If nb_channels is <= 0, it is guessed from the channel_layout.
|
||||||
|
|
|
@ -85,8 +85,6 @@ void av_force_cpu_flags(int flags);
|
||||||
* Set a mask on flags returned by av_get_cpu_flags().
|
* Set a mask on flags returned by av_get_cpu_flags().
|
||||||
* This function is mainly useful for testing.
|
* This function is mainly useful for testing.
|
||||||
* Please use av_force_cpu_flags() and av_get_cpu_flags() instead which are more flexible
|
* Please use av_force_cpu_flags() and av_get_cpu_flags() instead which are more flexible
|
||||||
*
|
|
||||||
* @warning this function is not thread safe.
|
|
||||||
*/
|
*/
|
||||||
attribute_deprecated void av_set_cpu_flags_mask(int mask);
|
attribute_deprecated void av_set_cpu_flags_mask(int mask);
|
||||||
|
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
/* Automatically generated by version.sh, do not manually edit! */
|
/* Automatically generated by version.sh, do not manually edit! */
|
||||||
#ifndef AVUTIL_FFVERSION_H
|
#ifndef AVUTIL_FFVERSION_H
|
||||||
#define AVUTIL_FFVERSION_H
|
#define AVUTIL_FFVERSION_H
|
||||||
#define FFMPEG_VERSION "n3.2.2"
|
#define FFMPEG_VERSION "N-83254-gf28299d"
|
||||||
#endif /* AVUTIL_FFVERSION_H */
|
#endif /* AVUTIL_FFVERSION_H */
|
||||||
|
|
|
@ -120,7 +120,13 @@ enum AVFrameSideDataType {
|
||||||
* The GOP timecode in 25 bit timecode format. Data format is 64-bit integer.
|
* The GOP timecode in 25 bit timecode format. Data format is 64-bit integer.
|
||||||
* This is set on the first frame of a GOP that has a temporal reference of 0.
|
* This is set on the first frame of a GOP that has a temporal reference of 0.
|
||||||
*/
|
*/
|
||||||
AV_FRAME_DATA_GOP_TIMECODE
|
AV_FRAME_DATA_GOP_TIMECODE,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The data represents the AVSphericalMapping structure defined in
|
||||||
|
* libavutil/spherical.h.
|
||||||
|
*/
|
||||||
|
AV_FRAME_DATA_SPHERICAL,
|
||||||
};
|
};
|
||||||
|
|
||||||
enum AVActiveFormatDescription {
|
enum AVActiveFormatDescription {
|
||||||
|
|
|
@ -318,6 +318,14 @@ int av_hwframe_get_buffer(AVBufferRef *hwframe_ctx, AVFrame *frame, int flags);
|
||||||
* If dst->format is set, then this format will be used, otherwise (when
|
* If dst->format is set, then this format will be used, otherwise (when
|
||||||
* dst->format is AV_PIX_FMT_NONE) the first acceptable format will be chosen.
|
* dst->format is AV_PIX_FMT_NONE) the first acceptable format will be chosen.
|
||||||
*
|
*
|
||||||
|
* The two frames must have matching allocated dimensions (i.e. equal to
|
||||||
|
* AVHWFramesContext.width/height), since not all device types support
|
||||||
|
* transferring a sub-rectangle of the whole surface. The display dimensions
|
||||||
|
* (i.e. AVFrame.width/height) may be smaller than the allocated dimensions, but
|
||||||
|
* also have to be equal for both frames. When the display dimensions are
|
||||||
|
* smaller than the allocated dimensions, the content of the padding in the
|
||||||
|
* destination frame is unspecified.
|
||||||
|
*
|
||||||
* @param dst the destination frame. dst is not touched on failure.
|
* @param dst the destination frame. dst is not touched on failure.
|
||||||
* @param src the source frame.
|
* @param src the source frame.
|
||||||
* @param flags currently unused, should be set to zero
|
* @param flags currently unused, should be set to zero
|
||||||
|
|
|
@ -20,7 +20,9 @@
|
||||||
#ifndef AVUTIL_HWCONTEXT_CUDA_H
|
#ifndef AVUTIL_HWCONTEXT_CUDA_H
|
||||||
#define AVUTIL_HWCONTEXT_CUDA_H
|
#define AVUTIL_HWCONTEXT_CUDA_H
|
||||||
|
|
||||||
|
#ifndef CUDA_VERSION
|
||||||
#include <cuda.h>
|
#include <cuda.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "pixfmt.h"
|
#include "pixfmt.h"
|
||||||
|
|
||||||
|
@ -32,11 +34,14 @@
|
||||||
* AVBufferRefs whose data pointer is a CUdeviceptr.
|
* AVBufferRefs whose data pointer is a CUdeviceptr.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
typedef struct AVCUDADeviceContextInternal AVCUDADeviceContextInternal;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This struct is allocated as AVHWDeviceContext.hwctx
|
* This struct is allocated as AVHWDeviceContext.hwctx
|
||||||
*/
|
*/
|
||||||
typedef struct AVCUDADeviceContext {
|
typedef struct AVCUDADeviceContext {
|
||||||
CUcontext cuda_ctx;
|
CUcontext cuda_ctx;
|
||||||
|
AVCUDADeviceContextInternal *internal;
|
||||||
} AVCUDADeviceContext;
|
} AVCUDADeviceContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -33,6 +33,26 @@
|
||||||
* with the data pointer set to a VASurfaceID.
|
* with the data pointer set to a VASurfaceID.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
enum {
|
||||||
|
/**
|
||||||
|
* The quirks field has been set by the user and should not be detected
|
||||||
|
* automatically by av_hwdevice_ctx_init().
|
||||||
|
*/
|
||||||
|
AV_VAAPI_DRIVER_QUIRK_USER_SET = (1 << 0),
|
||||||
|
/**
|
||||||
|
* The driver does not destroy parameter buffers when they are used by
|
||||||
|
* vaRenderPicture(). Additional code will be required to destroy them
|
||||||
|
* separately afterwards.
|
||||||
|
*/
|
||||||
|
AV_VAAPI_DRIVER_QUIRK_RENDER_PARAM_BUFFERS = (1 << 1),
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The driver does not support the VASurfaceAttribMemoryType attribute,
|
||||||
|
* so the surface allocation code will not try to use it.
|
||||||
|
*/
|
||||||
|
AV_VAAPI_DRIVER_QUIRK_ATTRIB_MEMTYPE = (1 << 2),
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* VAAPI connection details.
|
* VAAPI connection details.
|
||||||
*
|
*
|
||||||
|
@ -43,6 +63,14 @@ typedef struct AVVAAPIDeviceContext {
|
||||||
* The VADisplay handle, to be filled by the user.
|
* The VADisplay handle, to be filled by the user.
|
||||||
*/
|
*/
|
||||||
VADisplay display;
|
VADisplay display;
|
||||||
|
/**
|
||||||
|
* Driver quirks to apply - this is filled by av_hwdevice_ctx_init(),
|
||||||
|
* with reference to a table of known drivers, unless the
|
||||||
|
* AV_VAAPI_DRIVER_QUIRK_USER_SET bit is already present. The user
|
||||||
|
* may need to refer to this field when performing any later
|
||||||
|
* operations using VAAPI with the same VADisplay.
|
||||||
|
*/
|
||||||
|
unsigned int driver_quirks;
|
||||||
} AVVAAPIDeviceContext;
|
} AVVAAPIDeviceContext;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -191,6 +191,21 @@ int av_image_copy_to_buffer(uint8_t *dst, int dst_size,
|
||||||
*/
|
*/
|
||||||
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx);
|
int av_image_check_size(unsigned int w, unsigned int h, int log_offset, void *log_ctx);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Check if the given dimension of an image is valid, meaning that all
|
||||||
|
* bytes of a plane of an image with the specified pix_fmt can be addressed
|
||||||
|
* with a signed int.
|
||||||
|
*
|
||||||
|
* @param w the width of the picture
|
||||||
|
* @param h the height of the picture
|
||||||
|
* @param max_pixels the maximum number of pixels the user wants to accept
|
||||||
|
* @param pix_fmt the pixel format, can be AV_PIX_FMT_NONE if unknown.
|
||||||
|
* @param log_offset the offset to sum to the log level for logging with log_ctx
|
||||||
|
* @param log_ctx the parent logging context, it may be NULL
|
||||||
|
* @return >= 0 if valid, a negative error code otherwise
|
||||||
|
*/
|
||||||
|
int av_image_check_size2(unsigned int w, unsigned int h, int64_t max_pixels, enum AVPixelFormat pix_fmt, int log_offset, void *log_ctx);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if the given sample aspect ratio of an image is valid.
|
* Check if the given sample aspect ratio of an image is valid.
|
||||||
*
|
*
|
||||||
|
|
|
@ -22,6 +22,8 @@
|
||||||
#ifndef AVUTIL_LFG_H
|
#ifndef AVUTIL_LFG_H
|
||||||
#define AVUTIL_LFG_H
|
#define AVUTIL_LFG_H
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
typedef struct AVLFG {
|
typedef struct AVLFG {
|
||||||
unsigned int state[64];
|
unsigned int state[64];
|
||||||
int index;
|
int index;
|
||||||
|
@ -29,6 +31,13 @@ typedef struct AVLFG {
|
||||||
|
|
||||||
void av_lfg_init(AVLFG *c, unsigned int seed);
|
void av_lfg_init(AVLFG *c, unsigned int seed);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Seed the state of the ALFG using binary data.
|
||||||
|
*
|
||||||
|
* Return value: 0 on success, negative value (AVERROR) on failure.
|
||||||
|
*/
|
||||||
|
int av_lfg_init_from_data(AVLFG *c, const uint8_t *data, unsigned int length);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the next random unsigned 32-bit number using an ALFG.
|
* Get the next random unsigned 32-bit number using an ALFG.
|
||||||
*
|
*
|
||||||
|
|
|
@ -228,6 +228,7 @@ enum AVOptionType{
|
||||||
AV_OPT_TYPE_RATIONAL,
|
AV_OPT_TYPE_RATIONAL,
|
||||||
AV_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length
|
AV_OPT_TYPE_BINARY, ///< offset must point to a pointer immediately followed by an int for the length
|
||||||
AV_OPT_TYPE_DICT,
|
AV_OPT_TYPE_DICT,
|
||||||
|
AV_OPT_TYPE_UINT64,
|
||||||
AV_OPT_TYPE_CONST = 128,
|
AV_OPT_TYPE_CONST = 128,
|
||||||
AV_OPT_TYPE_IMAGE_SIZE = MKBETAG('S','I','Z','E'), ///< offset must point to two consecutive integers
|
AV_OPT_TYPE_IMAGE_SIZE = MKBETAG('S','I','Z','E'), ///< offset must point to two consecutive integers
|
||||||
AV_OPT_TYPE_PIXEL_FMT = MKBETAG('P','F','M','T'),
|
AV_OPT_TYPE_PIXEL_FMT = MKBETAG('P','F','M','T'),
|
||||||
|
|
|
@ -306,6 +306,14 @@ enum AVPixelFormat {
|
||||||
|
|
||||||
AV_PIX_FMT_MEDIACODEC, ///< hardware decoding through MediaCodec
|
AV_PIX_FMT_MEDIACODEC, ///< hardware decoding through MediaCodec
|
||||||
|
|
||||||
|
AV_PIX_FMT_GRAY12BE, ///< Y , 12bpp, big-endian
|
||||||
|
AV_PIX_FMT_GRAY12LE, ///< Y , 12bpp, little-endian
|
||||||
|
AV_PIX_FMT_GRAY10BE, ///< Y , 10bpp, big-endian
|
||||||
|
AV_PIX_FMT_GRAY10LE, ///< Y , 10bpp, little-endian
|
||||||
|
|
||||||
|
AV_PIX_FMT_P016LE, ///< like NV12, with 16bpp per component, little-endian
|
||||||
|
AV_PIX_FMT_P016BE, ///< like NV12, with 16bpp per component, big-endian
|
||||||
|
|
||||||
AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
|
AV_PIX_FMT_NB ///< number of pixel formats, DO NOT USE THIS if you want to link with shared libav* because the number of formats might differ between versions
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -322,6 +330,8 @@ enum AVPixelFormat {
|
||||||
#define AV_PIX_FMT_0RGB32 AV_PIX_FMT_NE(0RGB, BGR0)
|
#define AV_PIX_FMT_0RGB32 AV_PIX_FMT_NE(0RGB, BGR0)
|
||||||
#define AV_PIX_FMT_0BGR32 AV_PIX_FMT_NE(0BGR, RGB0)
|
#define AV_PIX_FMT_0BGR32 AV_PIX_FMT_NE(0BGR, RGB0)
|
||||||
|
|
||||||
|
#define AV_PIX_FMT_GRAY10 AV_PIX_FMT_NE(GRAY10BE, GRAY10LE)
|
||||||
|
#define AV_PIX_FMT_GRAY12 AV_PIX_FMT_NE(GRAY12BE, GRAY12LE)
|
||||||
#define AV_PIX_FMT_GRAY16 AV_PIX_FMT_NE(GRAY16BE, GRAY16LE)
|
#define AV_PIX_FMT_GRAY16 AV_PIX_FMT_NE(GRAY16BE, GRAY16LE)
|
||||||
#define AV_PIX_FMT_YA16 AV_PIX_FMT_NE(YA16BE, YA16LE)
|
#define AV_PIX_FMT_YA16 AV_PIX_FMT_NE(YA16BE, YA16LE)
|
||||||
#define AV_PIX_FMT_RGB48 AV_PIX_FMT_NE(RGB48BE, RGB48LE)
|
#define AV_PIX_FMT_RGB48 AV_PIX_FMT_NE(RGB48BE, RGB48LE)
|
||||||
|
@ -382,6 +392,7 @@ enum AVPixelFormat {
|
||||||
#define AV_PIX_FMT_NV20 AV_PIX_FMT_NE(NV20BE, NV20LE)
|
#define AV_PIX_FMT_NV20 AV_PIX_FMT_NE(NV20BE, NV20LE)
|
||||||
#define AV_PIX_FMT_AYUV64 AV_PIX_FMT_NE(AYUV64BE, AYUV64LE)
|
#define AV_PIX_FMT_AYUV64 AV_PIX_FMT_NE(AYUV64BE, AYUV64LE)
|
||||||
#define AV_PIX_FMT_P010 AV_PIX_FMT_NE(P010BE, P010LE)
|
#define AV_PIX_FMT_P010 AV_PIX_FMT_NE(P010BE, P010LE)
|
||||||
|
#define AV_PIX_FMT_P016 AV_PIX_FMT_NE(P016BE, P016LE)
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Chromaticity coordinates of the source primaries.
|
* Chromaticity coordinates of the source primaries.
|
||||||
|
@ -398,7 +409,8 @@ enum AVColorPrimaries {
|
||||||
AVCOL_PRI_SMPTE240M = 7, ///< functionally identical to above
|
AVCOL_PRI_SMPTE240M = 7, ///< functionally identical to above
|
||||||
AVCOL_PRI_FILM = 8, ///< colour filters using Illuminant C
|
AVCOL_PRI_FILM = 8, ///< colour filters using Illuminant C
|
||||||
AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020
|
AVCOL_PRI_BT2020 = 9, ///< ITU-R BT2020
|
||||||
AVCOL_PRI_SMPTEST428_1 = 10, ///< SMPTE ST 428-1 (CIE 1931 XYZ)
|
AVCOL_PRI_SMPTE428 = 10, ///< SMPTE ST 428-1 (CIE 1931 XYZ)
|
||||||
|
AVCOL_PRI_SMPTEST428_1 = AVCOL_PRI_SMPTE428,
|
||||||
AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011)
|
AVCOL_PRI_SMPTE431 = 11, ///< SMPTE ST 431-2 (2011)
|
||||||
AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 D65 (2010)
|
AVCOL_PRI_SMPTE432 = 12, ///< SMPTE ST 432-1 D65 (2010)
|
||||||
AVCOL_PRI_NB ///< Not part of ABI
|
AVCOL_PRI_NB ///< Not part of ABI
|
||||||
|
@ -424,8 +436,10 @@ enum AVColorTransferCharacteristic {
|
||||||
AVCOL_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC)
|
AVCOL_TRC_IEC61966_2_1 = 13, ///< IEC 61966-2-1 (sRGB or sYCC)
|
||||||
AVCOL_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10-bit system
|
AVCOL_TRC_BT2020_10 = 14, ///< ITU-R BT2020 for 10-bit system
|
||||||
AVCOL_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12-bit system
|
AVCOL_TRC_BT2020_12 = 15, ///< ITU-R BT2020 for 12-bit system
|
||||||
AVCOL_TRC_SMPTEST2084 = 16, ///< SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems
|
AVCOL_TRC_SMPTE2084 = 16, ///< SMPTE ST 2084 for 10-, 12-, 14- and 16-bit systems
|
||||||
AVCOL_TRC_SMPTEST428_1 = 17, ///< SMPTE ST 428-1
|
AVCOL_TRC_SMPTEST2084 = AVCOL_TRC_SMPTE2084,
|
||||||
|
AVCOL_TRC_SMPTE428 = 17, ///< SMPTE ST 428-1
|
||||||
|
AVCOL_TRC_SMPTEST428_1 = AVCOL_TRC_SMPTE428,
|
||||||
AVCOL_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma"
|
AVCOL_TRC_ARIB_STD_B67 = 18, ///< ARIB STD-B67, known as "Hybrid log-gamma"
|
||||||
AVCOL_TRC_NB ///< Not part of ABI
|
AVCOL_TRC_NB ///< Not part of ABI
|
||||||
};
|
};
|
||||||
|
|
|
@ -0,0 +1,140 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2016 Vittorio Giovara <vittorio.giovara@gmail.com>
|
||||||
|
*
|
||||||
|
* This file is part of FFmpeg.
|
||||||
|
*
|
||||||
|
* FFmpeg is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* FFmpeg is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with FFmpeg; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file
|
||||||
|
* Spherical video
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef AVUTIL_SPHERICAL_H
|
||||||
|
#define AVUTIL_SPHERICAL_H
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup lavu_video
|
||||||
|
* @{
|
||||||
|
*
|
||||||
|
* @defgroup lavu_video_spherical Spherical video mapping
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup lavu_video_spherical
|
||||||
|
* A spherical video file contains surfaces that need to be mapped onto a
|
||||||
|
* sphere. Depending on how the frame was converted, a different distortion
|
||||||
|
* transformation or surface recomposition function needs to be applied before
|
||||||
|
* the video should be mapped and displayed.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Projection of the video surface(s) on a sphere.
|
||||||
|
*/
|
||||||
|
enum AVSphericalProjection {
|
||||||
|
/**
|
||||||
|
* Video represents a sphere mapped on a flat surface using
|
||||||
|
* equirectangular projection.
|
||||||
|
*/
|
||||||
|
AV_SPHERICAL_EQUIRECTANGULAR,
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Video frame is split into 6 faces of a cube, and arranged on a
|
||||||
|
* 3x2 layout. Faces are oriented upwards for the front, left, right,
|
||||||
|
* and back faces. The up face is oriented so the top of the face is
|
||||||
|
* forwards and the down face is oriented so the top of the face is
|
||||||
|
* to the back.
|
||||||
|
*/
|
||||||
|
AV_SPHERICAL_CUBEMAP,
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This structure describes how to handle spherical videos, outlining
|
||||||
|
* information about projection, initial layout, and any other view modifier.
|
||||||
|
*
|
||||||
|
* @note The struct must be allocated with av_spherical_alloc() and
|
||||||
|
* its size is not a part of the public ABI.
|
||||||
|
*/
|
||||||
|
typedef struct AVSphericalMapping {
|
||||||
|
/**
|
||||||
|
* Projection type.
|
||||||
|
*/
|
||||||
|
enum AVSphericalProjection projection;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @name Initial orientation
|
||||||
|
* @{
|
||||||
|
* There fields describe additional rotations applied to the sphere after
|
||||||
|
* the video frame is mapped onto it. The sphere is rotated around the
|
||||||
|
* viewer, who remains stationary. The order of transformation is always
|
||||||
|
* yaw, followed by pitch, and finally by roll.
|
||||||
|
*
|
||||||
|
* The coordinate system matches the one defined in OpenGL, where the
|
||||||
|
* forward vector (z) is coming out of screen, and it is equivalent to
|
||||||
|
* a rotation matrix of R = r_y(yaw) * r_x(pitch) * r_z(roll).
|
||||||
|
*
|
||||||
|
* A positive yaw rotates the portion of the sphere in front of the viewer
|
||||||
|
* toward their right. A positive pitch rotates the portion of the sphere
|
||||||
|
* in front of the viewer upwards. A positive roll tilts the portion of
|
||||||
|
* the sphere in front of the viewer to the viewer's right.
|
||||||
|
*
|
||||||
|
* These values are exported as 16.16 fixed point.
|
||||||
|
*
|
||||||
|
* See this equirectangular projection as example:
|
||||||
|
*
|
||||||
|
* @code{.unparsed}
|
||||||
|
* Yaw
|
||||||
|
* -180 0 180
|
||||||
|
* 90 +-------------+-------------+ 180
|
||||||
|
* | | | up
|
||||||
|
* P | | | y| forward
|
||||||
|
* i | ^ | | /z
|
||||||
|
* t 0 +-------------X-------------+ 0 Roll | /
|
||||||
|
* c | | | | /
|
||||||
|
* h | | | 0|/_____right
|
||||||
|
* | | | x
|
||||||
|
* -90 +-------------+-------------+ -180
|
||||||
|
*
|
||||||
|
* X - the default camera center
|
||||||
|
* ^ - the default up vector
|
||||||
|
* @endcode
|
||||||
|
*/
|
||||||
|
int32_t yaw; ///< Rotation around the up vector [-180, 180].
|
||||||
|
int32_t pitch; ///< Rotation around the right vector [-90, 90].
|
||||||
|
int32_t roll; ///< Rotation around the forward vector [-180, 180].
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
} AVSphericalMapping;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allocate a AVSphericalVideo structure and initialize its fields to default
|
||||||
|
* values.
|
||||||
|
*
|
||||||
|
* @return the newly allocated struct or NULL on failure
|
||||||
|
*/
|
||||||
|
AVSphericalMapping *av_spherical_alloc(size_t *size);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @}
|
||||||
|
* @}
|
||||||
|
*/
|
||||||
|
|
||||||
|
#endif /* AVUTIL_SPHERICAL_H */
|
|
@ -79,7 +79,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#define LIBAVUTIL_VERSION_MAJOR 55
|
#define LIBAVUTIL_VERSION_MAJOR 55
|
||||||
#define LIBAVUTIL_VERSION_MINOR 34
|
#define LIBAVUTIL_VERSION_MINOR 45
|
||||||
#define LIBAVUTIL_VERSION_MICRO 100
|
#define LIBAVUTIL_VERSION_MICRO 100
|
||||||
|
|
||||||
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
|
#define LIBAVUTIL_VERSION_INT AV_VERSION_INT(LIBAVUTIL_VERSION_MAJOR, \
|
||||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -1,14 +1,14 @@
|
||||||
prefix=/Users/chris/Source/Repos/cog/ThirdParty/ffmpeg
|
prefix=/Users/Chris/Source/Repos/cog/ThirdParty/ffmpeg
|
||||||
exec_prefix=${prefix}
|
exec_prefix=${prefix}
|
||||||
libdir=${prefix}/lib
|
libdir=${prefix}/lib
|
||||||
includedir=${prefix}/include
|
includedir=${prefix}/include
|
||||||
|
|
||||||
Name: libavcodec
|
Name: libavcodec
|
||||||
Description: FFmpeg codec library
|
Description: FFmpeg codec library
|
||||||
Version: 57.64.101
|
Version: 57.75.100
|
||||||
Requires: libavutil >= 55.34.100
|
Requires: libavutil >= 55.45.100
|
||||||
Requires.private:
|
Requires.private:
|
||||||
Conflicts:
|
Conflicts:
|
||||||
Libs: -L${libdir} -lavcodec -framework QuartzCore -framework CoreFoundation -framework VideoToolbox -framework CoreMedia -framework CoreVideo -framework CoreFoundation -framework AudioToolbox -framework CoreMedia -framework VideoDecodeAcceleration -framework CoreFoundation -framework QuartzCore -liconv -Wl,-framework,CoreFoundation -Wl,-framework,Security -L/usr/local/lib -lSDL2 -lm -lbz2 -lz -pthread -framework CoreServices
|
Libs: -L${libdir} -lavcodec -framework QuartzCore -framework CoreFoundation -framework VideoToolbox -framework CoreMedia -framework CoreVideo -framework CoreFoundation -framework AudioToolbox -framework CoreMedia -framework VideoDecodeAcceleration -framework CoreFoundation -framework QuartzCore -liconv -Wl,-framework,CoreFoundation -Wl,-framework,Security -lm -lbz2 -lz -pthread -framework CoreServices
|
||||||
Libs.private:
|
Libs.private:
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
|
|
|
@ -1,14 +1,14 @@
|
||||||
prefix=/Users/chris/Source/Repos/cog/ThirdParty/ffmpeg
|
prefix=/Users/Chris/Source/Repos/cog/ThirdParty/ffmpeg
|
||||||
exec_prefix=${prefix}
|
exec_prefix=${prefix}
|
||||||
libdir=${prefix}/lib
|
libdir=${prefix}/lib
|
||||||
includedir=${prefix}/include
|
includedir=${prefix}/include
|
||||||
|
|
||||||
Name: libavformat
|
Name: libavformat
|
||||||
Description: FFmpeg container format library
|
Description: FFmpeg container format library
|
||||||
Version: 57.56.100
|
Version: 57.65.100
|
||||||
Requires: libavcodec >= 57.64.101, libavutil >= 55.34.100
|
Requires: libavcodec >= 57.75.100, libavutil >= 55.45.100
|
||||||
Requires.private:
|
Requires.private:
|
||||||
Conflicts:
|
Conflicts:
|
||||||
Libs: -L${libdir} -lavformat -framework QuartzCore -framework CoreFoundation -framework VideoToolbox -framework CoreMedia -framework CoreVideo -framework CoreFoundation -framework AudioToolbox -framework CoreMedia -framework VideoDecodeAcceleration -framework CoreFoundation -framework QuartzCore -liconv -Wl,-framework,CoreFoundation -Wl,-framework,Security -L/usr/local/lib -lSDL2 -lm -lbz2 -lz -pthread -framework CoreServices
|
Libs: -L${libdir} -lavformat -framework QuartzCore -framework CoreFoundation -framework VideoToolbox -framework CoreMedia -framework CoreVideo -framework CoreFoundation -framework AudioToolbox -framework CoreMedia -framework VideoDecodeAcceleration -framework CoreFoundation -framework QuartzCore -liconv -Wl,-framework,CoreFoundation -Wl,-framework,Security -lm -lbz2 -lz -pthread -framework CoreServices
|
||||||
Libs.private:
|
Libs.private:
|
||||||
Cflags: -I${includedir}
|
Cflags: -I${includedir}
|
||||||
|
|
|
@ -1,11 +1,11 @@
|
||||||
prefix=/Users/chris/Source/Repos/cog/ThirdParty/ffmpeg
|
prefix=/Users/Chris/Source/Repos/cog/ThirdParty/ffmpeg
|
||||||
exec_prefix=${prefix}
|
exec_prefix=${prefix}
|
||||||
libdir=${prefix}/lib
|
libdir=${prefix}/lib
|
||||||
includedir=${prefix}/include
|
includedir=${prefix}/include
|
||||||
|
|
||||||
Name: libavutil
|
Name: libavutil
|
||||||
Description: FFmpeg utility library
|
Description: FFmpeg utility library
|
||||||
Version: 55.34.100
|
Version: 55.45.100
|
||||||
Requires:
|
Requires:
|
||||||
Requires.private:
|
Requires.private:
|
||||||
Conflicts:
|
Conflicts:
|
||||||
|
|
Loading…
Reference in New Issue