Updated VGMStream to r1745-4-g9ef1030d
Signed-off-by: Christopher Snowhill <kode54@gmail.com>CQTexperiment
parent
2aa3ddd545
commit
ace62005db
|
@ -251,6 +251,12 @@
|
|||
836C052C23F62F3100FA07C7 /* libatrac9.framework in CopyFiles */ = {isa = PBXBuildFile; fileRef = 835FC6C623F62AEF006960FA /* libatrac9.framework */; settings = {ATTRIBUTES = (CodeSignOnCopy, RemoveHeadersOnCopy, ); }; };
|
||||
836EF0DB27BB975900BF35B2 /* libvorbis.0.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 836EF0D027BB960A00BF35B2 /* libvorbis.0.dylib */; };
|
||||
836EF0DD27BB97C500BF35B2 /* libvorbisfile.3.dylib in Frameworks */ = {isa = PBXBuildFile; fileRef = 836EF0DC27BB97BA00BF35B2 /* libvorbisfile.3.dylib */; };
|
||||
836F46AE28208735005B9B87 /* blocked_tt_ad.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F46AD28208735005B9B87 /* blocked_tt_ad.c */; };
|
||||
836F46B22820874D005B9B87 /* tt_ad.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F46AF2820874D005B9B87 /* tt_ad.c */; };
|
||||
836F46B32820874D005B9B87 /* esf.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F46B02820874D005B9B87 /* esf.c */; };
|
||||
836F46B42820874D005B9B87 /* adm3.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F46B12820874D005B9B87 /* adm3.c */; };
|
||||
836F46B7282087A6005B9B87 /* cri_utf.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F46B5282087A6005B9B87 /* cri_utf.c */; };
|
||||
836F46B8282087A6005B9B87 /* cri_utf.h in Headers */ = {isa = PBXBuildFile; fileRef = 836F46B6282087A6005B9B87 /* cri_utf.h */; };
|
||||
836F6B4718BDB8880095E648 /* InfoPlist.strings in Resources */ = {isa = PBXBuildFile; fileRef = 836F6B4518BDB8880095E648 /* InfoPlist.strings */; };
|
||||
836F6F1E18BDC2190095E648 /* acm_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6DE018BDC2180095E648 /* acm_decoder.c */; };
|
||||
836F6F2018BDC2190095E648 /* adx_decoder.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6DE218BDC2180095E648 /* adx_decoder.c */; };
|
||||
|
@ -677,8 +683,6 @@
|
|||
83FBD506235D31F800D35BCD /* riff_ogg_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 83FBD502235D31F700D35BCD /* riff_ogg_streamfile.h */; };
|
||||
83FC176D23AC58D100E1025F /* xma_ue3.c in Sources */ = {isa = PBXBuildFile; fileRef = 83FC176A23AC58D100E1025F /* xma_ue3.c */; };
|
||||
83FC176E23AC58D100E1025F /* csb.c in Sources */ = {isa = PBXBuildFile; fileRef = 83FC176B23AC58D100E1025F /* csb.c */; };
|
||||
83FC176F23AC58D100E1025F /* cri_utf.h in Headers */ = {isa = PBXBuildFile; fileRef = 83FC176C23AC58D100E1025F /* cri_utf.h */; };
|
||||
83FC177123AC59A800E1025F /* cri_utf.c in Sources */ = {isa = PBXBuildFile; fileRef = 83FC177023AC59A800E1025F /* cri_utf.c */; };
|
||||
83FC417026D32FF5009A2022 /* hca_decoder_clhca.h in Headers */ = {isa = PBXBuildFile; fileRef = 83FC416E26D32FF5009A2022 /* hca_decoder_clhca.h */; };
|
||||
83FC417126D32FF5009A2022 /* hca_decoder_clhca.c in Sources */ = {isa = PBXBuildFile; fileRef = 83FC416F26D32FF5009A2022 /* hca_decoder_clhca.c */; };
|
||||
83FC417326D3304D009A2022 /* xsh_xsd_xss.c in Sources */ = {isa = PBXBuildFile; fileRef = 83FC417226D3304D009A2022 /* xsh_xsd_xss.c */; };
|
||||
|
@ -1042,6 +1046,12 @@
|
|||
835FC6C123F62AEE006960FA /* libatrac9.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = libatrac9.xcodeproj; path = ../libatrac9/libatrac9.xcodeproj; sourceTree = "<group>"; };
|
||||
836EF0D027BB960A00BF35B2 /* libvorbis.0.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libvorbis.0.dylib; path = ../../ThirdParty/vorbis/lib/libvorbis.0.dylib; sourceTree = "<group>"; };
|
||||
836EF0DC27BB97BA00BF35B2 /* libvorbisfile.3.dylib */ = {isa = PBXFileReference; lastKnownFileType = "compiled.mach-o.dylib"; name = libvorbisfile.3.dylib; path = ../../ThirdParty/vorbis/lib/libvorbisfile.3.dylib; sourceTree = "<group>"; };
|
||||
836F46AD28208735005B9B87 /* blocked_tt_ad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = blocked_tt_ad.c; sourceTree = "<group>"; };
|
||||
836F46AF2820874D005B9B87 /* tt_ad.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = tt_ad.c; sourceTree = "<group>"; };
|
||||
836F46B02820874D005B9B87 /* esf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = esf.c; sourceTree = "<group>"; };
|
||||
836F46B12820874D005B9B87 /* adm3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = adm3.c; sourceTree = "<group>"; };
|
||||
836F46B5282087A6005B9B87 /* cri_utf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cri_utf.c; sourceTree = "<group>"; };
|
||||
836F46B6282087A6005B9B87 /* cri_utf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cri_utf.h; sourceTree = "<group>"; };
|
||||
836F6B3918BDB8880095E648 /* libvgmstream.framework */ = {isa = PBXFileReference; explicitFileType = wrapper.framework; includeInIndex = 0; path = libvgmstream.framework; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
836F6B4418BDB8880095E648 /* libvgmstream-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; path = "libvgmstream-Info.plist"; sourceTree = "<group>"; };
|
||||
836F6B4618BDB8880095E648 /* en */ = {isa = PBXFileReference; lastKnownFileType = text.plist.strings; name = en; path = en.lproj/InfoPlist.strings; sourceTree = "<group>"; };
|
||||
|
@ -1466,8 +1476,6 @@
|
|||
83FBD502235D31F700D35BCD /* riff_ogg_streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = riff_ogg_streamfile.h; sourceTree = "<group>"; };
|
||||
83FC176A23AC58D100E1025F /* xma_ue3.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xma_ue3.c; sourceTree = "<group>"; };
|
||||
83FC176B23AC58D100E1025F /* csb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = csb.c; sourceTree = "<group>"; };
|
||||
83FC176C23AC58D100E1025F /* cri_utf.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = cri_utf.h; sourceTree = "<group>"; };
|
||||
83FC177023AC59A800E1025F /* cri_utf.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = cri_utf.c; sourceTree = "<group>"; };
|
||||
83FC416E26D32FF5009A2022 /* hca_decoder_clhca.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hca_decoder_clhca.h; sourceTree = "<group>"; };
|
||||
83FC416F26D32FF5009A2022 /* hca_decoder_clhca.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = hca_decoder_clhca.c; sourceTree = "<group>"; };
|
||||
83FC417226D3304D009A2022 /* xsh_xsd_xss.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xsh_xsd_xss.c; sourceTree = "<group>"; };
|
||||
|
@ -1775,6 +1783,7 @@
|
|||
8306B09C20984550000302D4 /* blocked_str_snds.c */,
|
||||
8306B09820984550000302D4 /* blocked_thp.c */,
|
||||
8306B09920984550000302D4 /* blocked_tra.c */,
|
||||
836F46AD28208735005B9B87 /* blocked_tt_ad.c */,
|
||||
83031ECA243C50CB00C3F3E0 /* blocked_ubi_sce.c */,
|
||||
83AA5D1A1F6E2F7F0020821C /* blocked_vgs.c */,
|
||||
83031ECB243C50CB00C3F3E0 /* blocked_vid1.c */,
|
||||
|
@ -1810,6 +1819,7 @@
|
|||
837CEAD623487E8300E62A4A /* acb.c */,
|
||||
836F6E2B18BDC2180095E648 /* acm.c */,
|
||||
83F2CCE125A5B41600F46FA8 /* acx.c */,
|
||||
836F46B12820874D005B9B87 /* adm3.c */,
|
||||
83D26A7626E66D98001A9475 /* adp_bos.c */,
|
||||
83AA7F7A2519C042004C5298 /* adp_konami.c */,
|
||||
834FE0CF215C79E8000A5D3D /* adpcm_capcom.c */,
|
||||
|
@ -1863,8 +1873,6 @@
|
|||
834FE0E8215C79EC000A5D3D /* ck.c */,
|
||||
8346D97825BF838C00D1A8B0 /* compresswave.c */,
|
||||
83A8BAE425667AA7000F5F3F /* cpk.c */,
|
||||
83FC177023AC59A800E1025F /* cri_utf.c */,
|
||||
83FC176C23AC58D100E1025F /* cri_utf.h */,
|
||||
83FC176B23AC58D100E1025F /* csb.c */,
|
||||
834FE0D8215C79EA000A5D3D /* csmp.c */,
|
||||
836F6E3C18BDC2180095E648 /* Cstr.c */,
|
||||
|
@ -1896,6 +1904,7 @@
|
|||
83AF2CC826226BA500538240 /* encrypted_bgm_streamfile.h */,
|
||||
832FC36E278FAE3E0056A860 /* encrypted_mc161_streamfile.h */,
|
||||
83031ECE243C50DE00C3F3E0 /* encrypted.c */,
|
||||
836F46B02820874D005B9B87 /* esf.c */,
|
||||
836F6E4918BDC2180095E648 /* exakt_sc.c */,
|
||||
836F6E4A18BDC2180095E648 /* excitebots.c */,
|
||||
83AF2CC626226BA400538240 /* exst.c */,
|
||||
|
@ -2169,6 +2178,7 @@
|
|||
83E7FD6425EF2B2400683FD2 /* tac.c */,
|
||||
8373342E23F60D4100DE14DC /* tgc.c */,
|
||||
836F6EFA18BDC2190095E648 /* thp.c */,
|
||||
836F46AF2820874D005B9B87 /* tt_ad.c */,
|
||||
836F6EFB18BDC2190095E648 /* tun.c */,
|
||||
83C7280122BC893A00678B4A /* txth_streamfile.h */,
|
||||
830165971F256BD000CA0941 /* txth.c */,
|
||||
|
@ -2274,6 +2284,8 @@
|
|||
children = (
|
||||
83D26A8026E66DC2001A9475 /* chunks.c */,
|
||||
83D26A7E26E66DC2001A9475 /* chunks.h */,
|
||||
836F46B5282087A6005B9B87 /* cri_utf.c */,
|
||||
836F46B6282087A6005B9B87 /* cri_utf.h */,
|
||||
83B46FD42707FB9A00847FC9 /* endianness.h */,
|
||||
83D26A7D26E66DC2001A9475 /* log.c */,
|
||||
83D26A7F26E66DC2001A9475 /* log.h */,
|
||||
|
@ -2325,6 +2337,7 @@
|
|||
83D26A8326E66DC2001A9475 /* log.h in Headers */,
|
||||
83C7282222BC893D00678B4A /* mta2_streamfile.h in Headers */,
|
||||
83AA7F802519C042004C5298 /* sab_streamfile.h in Headers */,
|
||||
836F46B8282087A6005B9B87 /* cri_utf.h in Headers */,
|
||||
83A21F87201D8981000F04B9 /* fsb_keys.h in Headers */,
|
||||
83E7FD6325EF2B0C00683FD2 /* tac_decoder_lib_data.h in Headers */,
|
||||
832FC36C278FA4CB0056A860 /* ubi_ckd_cwav_streamfile.h in Headers */,
|
||||
|
@ -2341,7 +2354,6 @@
|
|||
8349A9111FE6258200E26435 /* bar_streamfile.h in Headers */,
|
||||
83D2007A248DDB770048BD24 /* fsb_encrypted_streamfile.h in Headers */,
|
||||
836F6F2718BDC2190095E648 /* g72x_state.h in Headers */,
|
||||
83FC176F23AC58D100E1025F /* cri_utf.h in Headers */,
|
||||
83C7282822BC8C1500678B4A /* mixing.h in Headers */,
|
||||
832BF82C21E0514B006F50F1 /* hca_keys_awb.h in Headers */,
|
||||
839933602591E8C1001855AF /* ubi_sb_garbage_streamfile.h in Headers */,
|
||||
|
@ -2611,6 +2623,7 @@
|
|||
836F6F9B18BDC2190095E648 /* mn_str.c in Sources */,
|
||||
832BF82821E0514B006F50F1 /* xwma.c in Sources */,
|
||||
83FC176E23AC58D100E1025F /* csb.c in Sources */,
|
||||
836F46B32820874D005B9B87 /* esf.c in Sources */,
|
||||
8306B0EB20984590000302D4 /* wave_segmented.c in Sources */,
|
||||
83E7FD5F25EF2B0C00683FD2 /* tac_decoder.c in Sources */,
|
||||
836F6F9F18BDC2190095E648 /* musc.c in Sources */,
|
||||
|
@ -2622,6 +2635,7 @@
|
|||
836F6FD718BDC2190095E648 /* ps2_filp.c in Sources */,
|
||||
8346D97925BF838C00D1A8B0 /* idtech.c in Sources */,
|
||||
83FF0EBC1E93282100C58054 /* wwise.c in Sources */,
|
||||
836F46B42820874D005B9B87 /* adm3.c in Sources */,
|
||||
836F6F7018BDC2190095E648 /* apple_caff.c in Sources */,
|
||||
836F6FB618BDC2190095E648 /* ngc_sck_dsp.c in Sources */,
|
||||
836F6F2818BDC2190095E648 /* ima_decoder.c in Sources */,
|
||||
|
@ -2785,6 +2799,7 @@
|
|||
83C7282022BC893D00678B4A /* dcs_wav.c in Sources */,
|
||||
8306B0F220984590000302D4 /* ubi_jade.c in Sources */,
|
||||
83852B0C2680247900378854 /* ads_midway.c in Sources */,
|
||||
836F46AE28208735005B9B87 /* blocked_tt_ad.c in Sources */,
|
||||
836F6FF918BDC2190095E648 /* ps2_snd.c in Sources */,
|
||||
836F6F2918BDC2190095E648 /* l5_555_decoder.c in Sources */,
|
||||
836F6FF318BDC2190095E648 /* ps2_rstm.c in Sources */,
|
||||
|
@ -2865,6 +2880,7 @@
|
|||
836F6F3118BDC2190095E648 /* ngc_afc_decoder.c in Sources */,
|
||||
836F6F9918BDC2190095E648 /* maxis_xa.c in Sources */,
|
||||
836F702118BDC2190095E648 /* rs03.c in Sources */,
|
||||
836F46B7282087A6005B9B87 /* cri_utf.c in Sources */,
|
||||
836F6F8818BDC2190095E648 /* fsb.c in Sources */,
|
||||
83F2CCE525A5B41600F46FA8 /* acx.c in Sources */,
|
||||
83FC176D23AC58D100E1025F /* xma_ue3.c in Sources */,
|
||||
|
@ -2988,6 +3004,7 @@
|
|||
834FE100215C79ED000A5D3D /* svg.c in Sources */,
|
||||
836F6F2518BDC2190095E648 /* g721_decoder.c in Sources */,
|
||||
836F6FE818BDC2190095E648 /* ps2_mic.c in Sources */,
|
||||
836F46B22820874D005B9B87 /* tt_ad.c in Sources */,
|
||||
836F6F3C18BDC2190095E648 /* xa_decoder.c in Sources */,
|
||||
8317C24C26982CC1007DD0B8 /* sspr.c in Sources */,
|
||||
832BF82521E0514B006F50F1 /* ogg_opus.c in Sources */,
|
||||
|
@ -2995,7 +3012,6 @@
|
|||
836F6F9118BDC2190095E648 /* ios_psnd.c in Sources */,
|
||||
836F700618BDC2190095E648 /* vgs_ps.c in Sources */,
|
||||
834FE10F215C79ED000A5D3D /* sdf.c in Sources */,
|
||||
83FC177123AC59A800E1025F /* cri_utf.c in Sources */,
|
||||
834FE0FF215C79ED000A5D3D /* sqex_scd_sscf.c in Sources */,
|
||||
8373341A23F60C7B00DE14DC /* relic_decoder_mixfft.c in Sources */,
|
||||
836F6FAA18BDC2190095E648 /* ngc_bh2pcm.c in Sources */,
|
||||
|
|
|
@ -265,13 +265,12 @@ size_t ptadpcm_bytes_to_samples(size_t bytes, int channels, size_t frame_size);
|
|||
/* ubi_adpcm_decoder */
|
||||
typedef struct ubi_adpcm_codec_data ubi_adpcm_codec_data;
|
||||
|
||||
ubi_adpcm_codec_data* init_ubi_adpcm(STREAMFILE* sf, off_t offset, int channels);
|
||||
ubi_adpcm_codec_data* init_ubi_adpcm(STREAMFILE* sf, uint32_t offset, uint32_t size, int channels);
|
||||
void decode_ubi_adpcm(VGMSTREAM* vgmstream, sample_t* outbuf, int32_t samples_to_do);
|
||||
void reset_ubi_adpcm(ubi_adpcm_codec_data* data);
|
||||
void seek_ubi_adpcm(ubi_adpcm_codec_data* data, int32_t num_sample);
|
||||
void free_ubi_adpcm(ubi_adpcm_codec_data* data);
|
||||
int32_t ubi_adpcm_get_samples(ubi_adpcm_codec_data* data);
|
||||
int32_t ubi_adpcm_bytes_to_samples(ubi_adpcm_codec_data* data, uint32_t size);
|
||||
|
||||
|
||||
/* imuse_decoder */
|
||||
|
@ -492,6 +491,7 @@ void free_mpeg(mpeg_codec_data* data);
|
|||
int mpeg_get_sample_rate(mpeg_codec_data* data);
|
||||
long mpeg_bytes_to_samples(long bytes, const mpeg_codec_data* data);
|
||||
|
||||
uint32_t mpeg_get_tag_size(STREAMFILE* sf, uint32_t offset, uint32_t header);
|
||||
int mpeg_get_frame_info(STREAMFILE* sf, off_t offset, mpeg_frame_info* info);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -203,8 +203,11 @@ STREAMFILE* hca_get_streamfile(hca_codec_data* data) {
|
|||
* (ex. newer Tales of the Rays files clip a lot) */
|
||||
#define HCA_KEY_MIN_TEST_FRAMES 3 //7
|
||||
#define HCA_KEY_MAX_TEST_FRAMES 7 //12
|
||||
/* score of 10~30 isn't uncommon in a single frame, too many frames over that is unlikely */
|
||||
#define HCA_KEY_MAX_FRAME_SCORE 150
|
||||
/* score of 10~30 isn't uncommon in a single frame, too many frames over that is unlikely
|
||||
* In rare cases of badly mastered frames there are +580. [Iris Mysteria! (Android)]
|
||||
* Lesser is preferable (faster skips) but high scores are less common in the current detection. */
|
||||
//TODO: may need to improve detection by counting silent (0) vs valid samples, as bad keys give lots of 0s
|
||||
#define HCA_KEY_MAX_FRAME_SCORE 600
|
||||
#define HCA_KEY_MAX_TOTAL_SCORE (HCA_KEY_MAX_TEST_FRAMES * 50*HCA_KEY_SCORE_SCALE)
|
||||
|
||||
/* Test a number of frames if key decrypts correctly.
|
||||
|
@ -267,7 +270,7 @@ static int test_hca_score(hca_codec_data* data, hca_keytest_t* hk) {
|
|||
switch(score) {
|
||||
case 1: score = 1; break;
|
||||
case 0: score = 3*HCA_KEY_SCORE_SCALE; break; /* blanks after non-blacks aren't very trustable */
|
||||
default: score = score*HCA_KEY_SCORE_SCALE;
|
||||
default: score = score * HCA_KEY_SCORE_SCALE;
|
||||
}
|
||||
|
||||
total_score += score;
|
||||
|
|
|
@ -563,21 +563,23 @@ void decode_blitz_ima(VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channels
|
|||
/* IMA with custom frame sizes, header and nibble layout. Outputs an odd number of samples per frame,
|
||||
* so to simplify calcs this decodes full frames, thus hist doesn't need to be mantained.
|
||||
* Officially defined in "Microsoft Multimedia Standards Update" doc (RIFFNEW.pdf). */
|
||||
void decode_ms_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample_t * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
void decode_ms_ima(VGMSTREAM* vgmstream, VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
|
||||
int i, samples_read = 0, samples_done = 0, max_samples;
|
||||
int32_t hist1;// = stream->adpcm_history1_32;
|
||||
int step_index;// = stream->adpcm_step_index;
|
||||
int frame_channels = vgmstream->codec_config ? 1 : vgmstream->channels; /* mono or mch modes */
|
||||
int frame_channel = vgmstream->codec_config ? 0 : channel;
|
||||
|
||||
/* internal interleave (configurable size), mixed channels */
|
||||
int block_samples = ((vgmstream->interleave_block_size - 0x04*vgmstream->channels) * 2 / vgmstream->channels) + 1;
|
||||
int block_samples = ((vgmstream->frame_size - 0x04*frame_channels) * 2 / frame_channels) + 1;
|
||||
first_sample = first_sample % block_samples;
|
||||
|
||||
/* normal header (hist+step+reserved), per channel */
|
||||
{ //if (first_sample == 0) {
|
||||
off_t header_offset = stream->offset + 0x04*channel;
|
||||
off_t header_offset = stream->offset + 0x04*frame_channel;
|
||||
|
||||
hist1 = read_16bitLE(header_offset+0x00,stream->streamfile);
|
||||
step_index = read_8bit(header_offset+0x02,stream->streamfile); /* 0x03: reserved */
|
||||
hist1 = read_s16le(header_offset+0x00,stream->streamfile);
|
||||
step_index = read_u8(header_offset+0x02,stream->streamfile); /* 0x03: reserved */
|
||||
if (step_index < 0) step_index = 0;
|
||||
if (step_index > 88) step_index = 88;
|
||||
|
||||
|
@ -595,7 +597,7 @@ void decode_ms_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample_t *
|
|||
|
||||
/* decode nibbles (layout: alternates 4 bytes/4*2 nibbles per channel) */
|
||||
for (i = 0; i < max_samples; i++) {
|
||||
off_t byte_offset = stream->offset + 0x04*vgmstream->channels + 0x04*channel + 0x04*vgmstream->channels*(i/8) + (i%8)/2;
|
||||
off_t byte_offset = stream->offset + 0x04*frame_channels + 0x04*frame_channel + 0x04*frame_channels*(i/8) + (i%8)/2;
|
||||
int nibble_shift = (i&1?4:0); /* low nibble first */
|
||||
|
||||
std_ima_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index); /* original expand */
|
||||
|
@ -609,7 +611,7 @@ void decode_ms_ima(VGMSTREAM * vgmstream, VGMSTREAMCHANNEL * stream, sample_t *
|
|||
|
||||
/* internal interleave: increment offset on complete frame */
|
||||
if (first_sample + samples_done == block_samples) {
|
||||
stream->offset += vgmstream->interleave_block_size;
|
||||
stream->offset += vgmstream->frame_size;
|
||||
}
|
||||
|
||||
//stream->adpcm_history1_32 = hist1;
|
||||
|
|
|
@ -340,6 +340,37 @@ int mpeg_get_frame_info(STREAMFILE* sf, off_t offset, mpeg_frame_info* info) {
|
|||
return mpeg_get_frame_info_h(header, info);
|
||||
}
|
||||
|
||||
|
||||
uint32_t mpeg_get_tag_size(STREAMFILE* sf, uint32_t offset, uint32_t header) {
|
||||
if (!header)
|
||||
header = read_u32be(offset+0x00, sf);
|
||||
|
||||
/* skip ID3v2 */
|
||||
if ((header & 0xFFFFFF00) == get_id32be("ID3\0")) {
|
||||
size_t frame_size = 0;
|
||||
uint8_t flags = read_u8(offset+0x05, sf);
|
||||
/* this is how it's officially read :/ */
|
||||
frame_size += read_u8(offset+0x06, sf) << 21;
|
||||
frame_size += read_u8(offset+0x07, sf) << 14;
|
||||
frame_size += read_u8(offset+0x08, sf) << 7;
|
||||
frame_size += read_u8(offset+0x09, sf) << 0;
|
||||
frame_size += 0x0a;
|
||||
if (flags & 0x10) /* footer? */
|
||||
frame_size += 0x0a;
|
||||
|
||||
return frame_size;
|
||||
|
||||
}
|
||||
|
||||
/* skip ID3v1 */
|
||||
if ((header & 0xFFFFFF00) == get_id32be("TAG\0")) {
|
||||
;VGM_LOG("MPEG: ID3v1 at %x\n", offset);
|
||||
return 0x80;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
size_t mpeg_get_samples(STREAMFILE* sf, off_t start_offset, size_t bytes) {
|
||||
off_t offset = start_offset;
|
||||
off_t max_offset = start_offset + bytes;
|
||||
|
@ -355,32 +386,13 @@ size_t mpeg_get_samples(STREAMFILE* sf, off_t start_offset, size_t bytes) {
|
|||
/* MPEG may use VBR so must read all frames */
|
||||
while (offset < max_offset) {
|
||||
uint32_t header = read_u32be(offset+0x00, sf);
|
||||
|
||||
/* skip ID3v2 */
|
||||
if ((header & 0xFFFFFF00) == 0x49443300) { /* "ID3\0" */
|
||||
size_t frame_size = 0;
|
||||
uint8_t flags = read_u8(offset+0x05, sf);
|
||||
/* this is how it's officially read :/ */
|
||||
frame_size += read_u8(offset+0x06, sf) << 21;
|
||||
frame_size += read_u8(offset+0x07, sf) << 14;
|
||||
frame_size += read_u8(offset+0x08, sf) << 7;
|
||||
frame_size += read_u8(offset+0x09, sf) << 0;
|
||||
frame_size += 0x0a;
|
||||
if (flags & 0x10) /* footer? */
|
||||
frame_size += 0x0a;
|
||||
|
||||
offset += frame_size;
|
||||
size_t tag_size = mpeg_get_tag_size(sf, offset, header);
|
||||
if (tag_size) {
|
||||
offset += tag_size;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* skip ID3v1 */
|
||||
if ((header & 0xFFFFFF00) == 0x54414700) { /* "TAG\0" */
|
||||
;VGM_LOG("MPEG: ID3v1 at %lx\n", offset);
|
||||
offset += 0x80;
|
||||
continue;
|
||||
}
|
||||
|
||||
/* regular frame */
|
||||
/* regular frame (assumed) */
|
||||
if (!mpeg_get_frame_info_h(header, &info)) {
|
||||
VGM_LOG("MPEG: unknown frame at %lx\n", offset);
|
||||
break;
|
||||
|
@ -407,28 +419,31 @@ size_t mpeg_get_samples(STREAMFILE* sf, off_t start_offset, size_t bytes) {
|
|||
}
|
||||
/* other flags indicate seek table and stuff */
|
||||
|
||||
/* vendor specific */
|
||||
if (info.frame_size > xing_offset + 0x78 + 0x24 &&
|
||||
read_u32be(offset + xing_offset + 0x78, sf) == 0x4C414D45) { /* "LAME" */
|
||||
if (info.layer == 3) {
|
||||
uint32_t delays = read_u32be(offset + xing_offset + 0x8C, sf);
|
||||
encoder_delay = ((delays >> 12) & 0xFFF);
|
||||
encoder_padding = ((delays >> 0) & 0xFFF);
|
||||
;VGM_LOG("MPEG: found Xing header\n");
|
||||
|
||||
encoder_delay += (528 + 1); /* implicit MDCT decoder delay (seen in LAME source) */
|
||||
if (encoder_padding > 528 + 1)
|
||||
encoder_padding -= (528 + 1);
|
||||
}
|
||||
else {
|
||||
encoder_delay = 240 + 1;
|
||||
/* vendor specific */
|
||||
if (info.frame_size > xing_offset + 0x78 + 0x24) {
|
||||
uint32_t sub_id = read_u32be(offset + xing_offset + 0x78, sf);
|
||||
if (sub_id == get_id32be("LAME") || /* LAME */
|
||||
sub_id == get_id32be("Lavc")) { /* FFmpeg */
|
||||
if (info.layer == 3) {
|
||||
uint32_t delays = read_u32be(offset + xing_offset + 0x8C, sf);
|
||||
encoder_delay = ((delays >> 12) & 0xFFF);
|
||||
encoder_padding = ((delays >> 0) & 0xFFF);
|
||||
|
||||
encoder_delay += (528 + 1); /* implicit MDCT decoder delay (seen in LAME source) */
|
||||
if (encoder_padding > 528 + 1)
|
||||
encoder_padding -= (528 + 1);
|
||||
}
|
||||
else {
|
||||
encoder_delay = 240 + 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* replay gain and stuff */
|
||||
}
|
||||
|
||||
/* there is also "iTunes" vendor with no apparent extra info, iTunes delays are in "iTunSMPB" ID3 tag */
|
||||
|
||||
;VGM_LOG("MPEG: found Xing header\n");
|
||||
break; /* we got samples */
|
||||
}
|
||||
}
|
||||
|
|
|
@ -71,8 +71,8 @@ struct ubi_adpcm_codec_data {
|
|||
ubi_adpcm_header_data header;
|
||||
ubi_adpcm_channel_data ch[UBI_CHANNELS_MAX];
|
||||
|
||||
off_t start_offset;
|
||||
off_t offset;
|
||||
uint32_t start_offset;
|
||||
uint32_t offset;
|
||||
int subframe_number;
|
||||
|
||||
uint8_t frame[UBI_FRAME_SIZE_MAX];
|
||||
|
@ -86,16 +86,17 @@ struct ubi_adpcm_codec_data {
|
|||
|
||||
/* *********************************************************************** */
|
||||
|
||||
static int parse_header(STREAMFILE* sf, ubi_adpcm_codec_data* data, off_t offset);
|
||||
static int parse_header(STREAMFILE* sf, ubi_adpcm_codec_data* data, uint32_t offset, uint32_t size);
|
||||
static void decode_frame(STREAMFILE* sf, ubi_adpcm_codec_data* data);
|
||||
static void fix_samples(ubi_adpcm_codec_data* data, uint32_t size);
|
||||
|
||||
ubi_adpcm_codec_data* init_ubi_adpcm(STREAMFILE* sf, off_t offset, int channels) {
|
||||
ubi_adpcm_codec_data* init_ubi_adpcm(STREAMFILE* sf, uint32_t offset, uint32_t size, int channels) {
|
||||
ubi_adpcm_codec_data* data = NULL;
|
||||
|
||||
data = calloc(1, sizeof(ubi_adpcm_codec_data));
|
||||
if (!data) goto fail;
|
||||
|
||||
if (!parse_header(sf, data, offset)) {
|
||||
if (!parse_header(sf, data, offset, size)) {
|
||||
VGM_LOG("UBI ADPCM: wrong header\n");
|
||||
goto fail;
|
||||
}
|
||||
|
@ -193,7 +194,7 @@ static void read_header_state(uint8_t* data, ubi_adpcm_header_data* header) {
|
|||
header->channels = get_u32le(data + 0x2c);
|
||||
}
|
||||
|
||||
static int parse_header(STREAMFILE* sf, ubi_adpcm_codec_data* data, off_t offset) {
|
||||
static int parse_header(STREAMFILE* sf, ubi_adpcm_codec_data* data, uint32_t offset, uint32_t size) {
|
||||
uint8_t buf[0x30];
|
||||
size_t bytes;
|
||||
|
||||
|
@ -214,6 +215,11 @@ static int parse_header(STREAMFILE* sf, ubi_adpcm_codec_data* data, off_t offset
|
|||
if (data->header.channels > UBI_CHANNELS_MAX || data->header.channels < UBI_CHANNELS_MIN)
|
||||
goto fail;
|
||||
|
||||
/* some kind of internal bug I guess, seen in a few subsongs in Rayman 3 PC demo */
|
||||
if (data->header.sample_count == 0x77E7A374 * data->header.channels) {
|
||||
fix_samples(data, size);
|
||||
}
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
|
@ -548,8 +554,8 @@ static void decode_frame(STREAMFILE* sf, ubi_adpcm_codec_data* data) {
|
|||
|
||||
bytes = read_streamfile(data->frame, data->offset, frame_size, sf);
|
||||
if (bytes != frame_size) {
|
||||
VGM_LOG("UBI ADPCM: wrong bytes read %x vs %x at %lx\n", bytes, frame_size, data->offset);
|
||||
//goto fail; //?
|
||||
VGM_LOG("UBI ADPCM: wrong bytes read %x vs %x at %x\n", bytes, frame_size, data->offset);
|
||||
//goto fail; //may reach EOF earlier
|
||||
}
|
||||
|
||||
if (channels == 1) {
|
||||
|
@ -587,21 +593,37 @@ int32_t ubi_adpcm_get_samples(ubi_adpcm_codec_data* data) {
|
|||
return data->header.sample_count / data->header.channels;
|
||||
}
|
||||
|
||||
int32_t ubi_adpcm_bytes_to_samples(ubi_adpcm_codec_data* data, uint32_t size) {
|
||||
uint32_t frame_size;
|
||||
static void fix_samples(ubi_adpcm_codec_data* data, uint32_t size) {
|
||||
uint32_t frame_size, setup_size, subframe_size, base_frames, last_size;
|
||||
int subframes;
|
||||
int32_t samples;
|
||||
|
||||
if (!data || !data->header.channels || !data->header.subframes_per_frame)
|
||||
return 0;
|
||||
if (!data || !data->header.channels || !data->header.subframes_per_frame || !size)
|
||||
return;
|
||||
|
||||
size -= 0x30; /* ignore header */
|
||||
|
||||
setup_size = 0x34 * data->header.channels; /* setup per channel */
|
||||
subframe_size = (data->header.codes_per_subframe * data->header.bits_per_sample /*+ 8*/) / 8 + 0x01; /* padding byte */
|
||||
frame_size = setup_size + subframe_size * data->header.subframes_per_frame;
|
||||
|
||||
/* don't trust subframe count */
|
||||
base_frames = ((size - 0x01) / frame_size); /* force smaller size just in case so last frame isn't used */
|
||||
last_size = size - (base_frames * frame_size);
|
||||
subframes = base_frames * data->header.subframes_per_frame;
|
||||
|
||||
size -= 0x30; /* header */
|
||||
samples = base_frames * (data->header.codes_per_subframe * data->header.subframes_per_frame);
|
||||
|
||||
frame_size = 0x34 * data->header.channels; /* setup per channel */
|
||||
frame_size += (data->header.codes_per_subframe * data->header.bits_per_sample /*+ 8*/) * data->header.subframes_per_frame / 8;
|
||||
frame_size += data->header.subframes_per_frame * 0x01; /* padding byte */
|
||||
/* last subframe is shorter (and may contain padding after codes_per_subframe_last), and last frame may not contain all subframes */
|
||||
if (last_size > setup_size + subframe_size) {
|
||||
samples += data->header.codes_per_subframe * (data->header.subframes_per_frame - 1);
|
||||
subframes += (data->header.subframes_per_frame - 1);
|
||||
}
|
||||
|
||||
return ((size - 0x01) / frame_size) * /* force smaller size so last frame isn't used */
|
||||
data->header.codes_per_subframe * data->header.subframes_per_frame +
|
||||
data->header.codes_per_subframe_last * data->header.subframes_per_frame;
|
||||
/* for some reason several files that need fixing seem to have garbage in the 2nd half of last codes */
|
||||
samples += data->header.codes_per_subframe_last / 2;
|
||||
subframes += 1;
|
||||
|
||||
data->header.sample_count = samples; /* for all channels */
|
||||
data->header.subframe_count = subframes;
|
||||
}
|
||||
|
|
|
@ -428,7 +428,9 @@ int get_vgmstream_samples_per_frame(VGMSTREAM* vgmstream) {
|
|||
return 64;
|
||||
case coding_MS_IMA:
|
||||
case coding_REF_IMA:
|
||||
return ((vgmstream->interleave_block_size - 0x04*vgmstream->channels) * 2 / vgmstream->channels) + 1;
|
||||
return ((vgmstream->interleave_block_size - 0x04*vgmstream->channels) * 2 / vgmstream->channels) + 1;/* +1 from header sample */
|
||||
case coding_MS_IMA_mono:
|
||||
return ((vgmstream->frame_size - 0x04) * 2) + 1; /* +1 from header sample */
|
||||
case coding_RAD_IMA:
|
||||
return (vgmstream->interleave_block_size - 0x04*vgmstream->channels) * 2 / vgmstream->channels;
|
||||
case coding_NDS_IMA:
|
||||
|
@ -628,12 +630,14 @@ int get_vgmstream_frame_size(VGMSTREAM* vgmstream) {
|
|||
case coding_OKI4S:
|
||||
case coding_MTF_IMA:
|
||||
return 0x01;
|
||||
case coding_MS_IMA:
|
||||
case coding_RAD_IMA:
|
||||
case coding_NDS_IMA:
|
||||
case coding_DAT4_IMA:
|
||||
case coding_REF_IMA:
|
||||
return vgmstream->interleave_block_size;
|
||||
case coding_MS_IMA:
|
||||
case coding_MS_IMA_mono:
|
||||
return vgmstream->frame_size;
|
||||
case coding_AWC_IMA:
|
||||
return 0x800;
|
||||
case coding_RAD_IMA_mono:
|
||||
|
@ -931,6 +935,9 @@ void decode_vgmstream(VGMSTREAM* vgmstream, int samples_written, int samples_to_
|
|||
}
|
||||
break;
|
||||
case coding_MS_IMA:
|
||||
case coding_MS_IMA_mono:
|
||||
//TODO: improve
|
||||
vgmstream->codec_config = (vgmstream->coding_type == coding_MS_IMA_mono) || vgmstream->channels == 1; /* mono mode */
|
||||
for (ch = 0; ch < vgmstream->channels; ch++) {
|
||||
decode_ms_ima(vgmstream,&vgmstream->ch[ch], buffer+ch,
|
||||
vgmstream->channels, vgmstream->samples_into_block, samples_to_do, ch);
|
||||
|
|
|
@ -82,6 +82,7 @@ static const char* extension_list[] = {
|
|||
"atx",
|
||||
"aud",
|
||||
"audio", //txth/reserved [Grimm Echoes (Android)]
|
||||
"audio_data",
|
||||
"aus",
|
||||
"awa", //txth/reserved [Missing Parts Side A (PS2)]
|
||||
"awb",
|
||||
|
@ -172,6 +173,7 @@ static const char* extension_list[] = {
|
|||
"enm",
|
||||
"eno",
|
||||
"ens",
|
||||
"esf",
|
||||
"exa",
|
||||
"ezw",
|
||||
|
||||
|
@ -431,6 +433,7 @@ static const char* extension_list[] = {
|
|||
"rxx", //txth/reserved [Full Auto (X360)]
|
||||
|
||||
"s14",
|
||||
"s3s", //txth/reserved [DT Racer (PS2)]
|
||||
"s3v", //Sound Voltex (AC)
|
||||
"sab",
|
||||
"sad",
|
||||
|
@ -520,6 +523,7 @@ static const char* extension_list[] = {
|
|||
"swag",
|
||||
"swav",
|
||||
"swd",
|
||||
"switch", //txth/reserved (.m4a-x.switch) [Ikinari Maou (Switch)]
|
||||
"switch_audio",
|
||||
"sx",
|
||||
"sxd",
|
||||
|
@ -778,6 +782,7 @@ static const coding_info coding_info_list[] = {
|
|||
{coding_MTF_IMA, "MT Framework 4-bit IMA ADPCM"},
|
||||
|
||||
{coding_MS_IMA, "Microsoft 4-bit IMA ADPCM"},
|
||||
{coding_MS_IMA_mono, "Microsoft 4-bit IMA ADPCM (mono/interleave)"},
|
||||
{coding_XBOX_IMA, "XBOX 4-bit IMA ADPCM"},
|
||||
{coding_XBOX_IMA_mch, "XBOX 4-bit IMA ADPCM (multichannel)"},
|
||||
{coding_XBOX_IMA_int, "XBOX 4-bit IMA ADPCM (mono/interleave)"},
|
||||
|
@ -925,6 +930,7 @@ static const layout_info layout_info_list[] = {
|
|||
{layout_blocked_vs_square, "blocked (Square VS)"},
|
||||
{layout_blocked_vid1, "blocked (VID1)"},
|
||||
{layout_blocked_ubi_sce, "blocked (Ubi SCE)"},
|
||||
{layout_blocked_tt_ad, "blocked (TT AD)"},
|
||||
};
|
||||
|
||||
static const meta_info meta_info_list[] = {
|
||||
|
@ -1389,6 +1395,9 @@ static const meta_info meta_info_list[] = {
|
|||
{meta_MPEG, "MPEG header"},
|
||||
{meta_SSPF, "Konami SSPF header"},
|
||||
{meta_S3V, "Konami S3V header"},
|
||||
{meta_ESF, "Eurocom ESF header"},
|
||||
{meta_ADM3, "Crankcase ADM3 header"},
|
||||
{meta_TT_AD, "Traveller's Tales AUDIO_DATA header"},
|
||||
};
|
||||
|
||||
void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) {
|
||||
|
|
|
@ -358,7 +358,13 @@ static int get_vgmstream_file_bitrate_main(VGMSTREAM* vgmstream, bitrate_info_t*
|
|||
* segments use only a few samples from a full file (like Wwise transitions), bitrates
|
||||
* become a bit high since its hard to detect only part of the file is needed. */
|
||||
|
||||
if (vgmstream->layout_type == layout_segmented) {
|
||||
if (vgmstream->stream_size != 0) {
|
||||
/* format may report full size for custom layouts that otherwise get odd values */
|
||||
bitrate += get_vgmstream_file_bitrate_from_size(vgmstream->stream_size, vgmstream->sample_rate, vgmstream->num_samples);
|
||||
if (p_uniques)
|
||||
(*p_uniques)++;
|
||||
}
|
||||
else if (vgmstream->layout_type == layout_segmented) {
|
||||
int uniques = 0;
|
||||
segmented_layout_data *data = (segmented_layout_data *) vgmstream->layout_data;
|
||||
for (i = 0; i < data->segment_count; i++) {
|
||||
|
@ -400,20 +406,20 @@ static int get_vgmstream_file_bitrate_main(VGMSTREAM* vgmstream, bitrate_info_t*
|
|||
}
|
||||
|
||||
if (is_unique) {
|
||||
size_t stream_size;
|
||||
|
||||
size_t file_bitrate;
|
||||
|
||||
if (br->count >= br->count_max) goto fail;
|
||||
|
||||
if (vgmstream->stream_size) {
|
||||
/* stream_size applies to both channels but should add once and detect repeats (for current subsong) */
|
||||
stream_size = get_vgmstream_file_bitrate_from_size(vgmstream->stream_size, vgmstream->sample_rate, vgmstream->num_samples);
|
||||
file_bitrate = get_vgmstream_file_bitrate_from_size(vgmstream->stream_size, vgmstream->sample_rate, vgmstream->num_samples);
|
||||
}
|
||||
else {
|
||||
stream_size = get_vgmstream_file_bitrate_from_streamfile(sf_cur, vgmstream->sample_rate, vgmstream->num_samples);
|
||||
file_bitrate = get_vgmstream_file_bitrate_from_streamfile(sf_cur, vgmstream->sample_rate, vgmstream->num_samples);
|
||||
}
|
||||
|
||||
/* possible in cases like using silence codec */
|
||||
if (!stream_size)
|
||||
if (!file_bitrate)
|
||||
break;
|
||||
|
||||
br->hash[br->count] = hash_cur;
|
||||
|
@ -423,7 +429,7 @@ static int get_vgmstream_file_bitrate_main(VGMSTREAM* vgmstream, bitrate_info_t*
|
|||
if (p_uniques)
|
||||
(*p_uniques)++;
|
||||
|
||||
bitrate += stream_size;
|
||||
bitrate += file_bitrate;
|
||||
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -213,6 +213,9 @@ void block_update(off_t block_offset, VGMSTREAM* vgmstream) {
|
|||
case layout_blocked_ubi_sce:
|
||||
block_update_ubi_sce(block_offset,vgmstream);
|
||||
break;
|
||||
case layout_blocked_tt_ad:
|
||||
block_update_tt_ad(block_offset,vgmstream);
|
||||
break;
|
||||
default: /* not a blocked layout */
|
||||
break;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
#include "layout.h"
|
||||
|
||||
/* Traveller's Tales blocks (.AUDIO_DATA) */
|
||||
void block_update_tt_ad(off_t block_offset, VGMSTREAM* vgmstream) {
|
||||
STREAMFILE* sf = vgmstream->ch[0].streamfile;
|
||||
uint32_t header_id, block_size, header_size;
|
||||
int i;
|
||||
|
||||
header_size = 0x00;
|
||||
block_size = vgmstream->frame_size;
|
||||
|
||||
//TODO could be optimized?
|
||||
/* first chunk and last frame has an extra header:
|
||||
* 0x00: id
|
||||
* 0x04: 0 in FRST, left samples in LAST, others not seen (found in exe) */
|
||||
header_id = read_u32be(block_offset, sf);
|
||||
if (header_id == get_id32be("FRST") || header_id == get_id32be("LAST") ||
|
||||
header_id == get_id32be("LSRT") || header_id == get_id32be("LEND")) {
|
||||
header_size = 0x08;
|
||||
}
|
||||
VGM_ASSERT(header_id == get_id32be("LSRT") || header_id == get_id32be("LEND"), "TT-AD: loop found\n");
|
||||
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = block_size /* * vgmstream->channels*/;
|
||||
vgmstream->next_block_offset = block_offset + block_size * vgmstream->channels + header_size;
|
||||
|
||||
/* MS-IMA = same offset per channel */
|
||||
for (i = 0; i < vgmstream->channels; i++) {
|
||||
vgmstream->ch[i].offset = vgmstream->current_block_offset + header_size + block_size * i;
|
||||
}
|
||||
}
|
|
@ -49,6 +49,7 @@ void block_update_xa_aiff(off_t block_offset, VGMSTREAM* vgmstream);
|
|||
void block_update_vs_square(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_vid1(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_ubi_sce(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
void block_update_tt_ad(off_t block_offset, VGMSTREAM* vgmstream);
|
||||
|
||||
/* other layouts */
|
||||
void render_vgmstream_interleave(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
|
||||
|
|
|
@ -1,31 +1,32 @@
|
|||
#include "meta.h"
|
||||
#include "../layout/layout.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "cri_utf.h"
|
||||
#include "../util/cri_utf.h"
|
||||
|
||||
|
||||
#define MAX_SEGMENTS 2 /* usually segment0=intro, segment1=loop/main */
|
||||
|
||||
/* AAX - segmented ADX [Bayonetta (PS3), Pandora's Tower (Wii), Catherine (X360), Binary Domain (PS3)] */
|
||||
VGMSTREAM * init_vgmstream_aax(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
int loop_flag = 0, channel_count = 0;
|
||||
VGMSTREAM* init_vgmstream_aax(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
int loop_flag = 0, channels = 0;
|
||||
int32_t sample_count, loop_start_sample = 0, loop_end_sample = 0;
|
||||
|
||||
segmented_layout_data *data = NULL;
|
||||
segmented_layout_data* data = NULL;
|
||||
int segment_count, loop_segment = 0, is_hca;
|
||||
off_t segment_offset[MAX_SEGMENTS];
|
||||
size_t segment_size[MAX_SEGMENTS];
|
||||
int i;
|
||||
utf_context *utf = NULL;
|
||||
utf_context* utf = NULL;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "@UTF"))
|
||||
goto fail;
|
||||
|
||||
/* .aax: often with extension (with either HCA or AAX tables)
|
||||
* (extensionless): sometimes without [PES 2013 (PC)] */
|
||||
if (!check_extensions(streamFile, "aax,"))
|
||||
goto fail;
|
||||
if (read_32bitBE(0x00,streamFile) != 0x40555446) /* "@UTF" */
|
||||
if (!check_extensions(sf, "aax,"))
|
||||
goto fail;
|
||||
|
||||
/* .aax contains a simple UTF table, each row being a segment pointing to a CRI audio format */
|
||||
|
@ -35,7 +36,7 @@ VGMSTREAM * init_vgmstream_aax(STREAMFILE *streamFile) {
|
|||
uint32_t table_offset = 0x00;
|
||||
|
||||
|
||||
utf = utf_open(streamFile, table_offset, &rows, &name);
|
||||
utf = utf_open(sf, table_offset, &rows, &name);
|
||||
if (!utf) goto fail;
|
||||
|
||||
if (strcmp(name, "AAX") == 0)
|
||||
|
@ -74,7 +75,7 @@ VGMSTREAM * init_vgmstream_aax(STREAMFILE *streamFile) {
|
|||
|
||||
/* open each segment subfile */
|
||||
for (i = 0; i < segment_count; i++) {
|
||||
STREAMFILE* temp_sf = setup_subfile_streamfile(streamFile, segment_offset[i],segment_size[i], (is_hca ? "hca" : "adx"));
|
||||
STREAMFILE* temp_sf = setup_subfile_streamfile(sf, segment_offset[i],segment_size[i], (is_hca ? "hca" : "adx"));
|
||||
if (!temp_sf) goto fail;
|
||||
|
||||
data->segments[i] = is_hca ?
|
||||
|
@ -105,11 +106,11 @@ VGMSTREAM * init_vgmstream_aax(STREAMFILE *streamFile) {
|
|||
}
|
||||
}
|
||||
|
||||
channel_count = data->output_channels;
|
||||
channels = data->output_channels;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
vgmstream = allocate_vgmstream(channels,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = data->segments[0]->sample_rate;
|
||||
|
@ -135,21 +136,22 @@ fail:
|
|||
|
||||
|
||||
/* CRI's UTF wrapper around DSP [Sonic Colors sfx (Wii), NiGHTS: Journey of Dreams sfx (Wii)] */
|
||||
VGMSTREAM * init_vgmstream_utf_dsp(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
VGMSTREAM* init_vgmstream_utf_dsp(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
off_t start_offset;
|
||||
uint8_t loop_flag = 0, channel_count;
|
||||
uint8_t loop_flag = 0, channels;
|
||||
uint32_t sample_rate, num_samples, loop_start, loop_end, interleave;
|
||||
uint32_t data_offset, data_size, header_offset, header_size;
|
||||
utf_context *utf = NULL;
|
||||
utf_context* utf = NULL;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "@UTF"))
|
||||
goto fail;
|
||||
|
||||
/* .aax: assumed
|
||||
* (extensionless): extracted names inside csb/cpk often don't have extensions */
|
||||
if (!check_extensions(streamFile, "aax,"))
|
||||
goto fail;
|
||||
if (read_32bitBE(0x00,streamFile) != 0x40555446) /* "@UTF" */
|
||||
if (!check_extensions(sf, "aax,"))
|
||||
goto fail;
|
||||
|
||||
/* .aax contains a simple UTF table with one row and various columns being header info */
|
||||
|
@ -159,7 +161,7 @@ VGMSTREAM * init_vgmstream_utf_dsp(STREAMFILE *streamFile) {
|
|||
uint32_t table_offset = 0x00;
|
||||
|
||||
|
||||
utf = utf_open(streamFile, table_offset, &rows, &name);
|
||||
utf = utf_open(sf, table_offset, &rows, &name);
|
||||
if (!utf) goto fail;
|
||||
|
||||
if (strcmp(name, "ADPCM_WII") != 0)
|
||||
|
@ -172,7 +174,7 @@ VGMSTREAM * init_vgmstream_utf_dsp(STREAMFILE *streamFile) {
|
|||
goto fail;
|
||||
if (!utf_query_u32(utf, 0, "nsmpl", &num_samples))
|
||||
goto fail;
|
||||
if (!utf_query_u8(utf, 0, "nch", &channel_count))
|
||||
if (!utf_query_u8(utf, 0, "nch", &channels))
|
||||
goto fail;
|
||||
if (!utf_query_u8(utf, 0, "lpflg", &loop_flag)) /* full loops */
|
||||
goto fail;
|
||||
|
@ -182,21 +184,21 @@ VGMSTREAM * init_vgmstream_utf_dsp(STREAMFILE *streamFile) {
|
|||
if (!utf_query_data(utf, 0, "header", &header_offset, &header_size))
|
||||
goto fail;
|
||||
|
||||
if (channel_count < 1 || channel_count > 2)
|
||||
if (channels < 1 || channels > 2)
|
||||
goto fail;
|
||||
if (header_size != channel_count * 0x60)
|
||||
if (header_size != channels * 0x60)
|
||||
goto fail;
|
||||
|
||||
start_offset = data_offset;
|
||||
interleave = (data_size+7) / 8 * 8 / channel_count;
|
||||
interleave = (data_size+7) / 8 * 8 / channels;
|
||||
|
||||
loop_start = read_32bitBE(header_offset + 0x10, streamFile);
|
||||
loop_end = read_32bitBE(header_offset + 0x14, streamFile);
|
||||
loop_start = read_32bitBE(header_offset + 0x10, sf);
|
||||
loop_end = read_32bitBE(header_offset + 0x14, sf);
|
||||
}
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count, loop_flag);
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
|
@ -209,9 +211,9 @@ VGMSTREAM * init_vgmstream_utf_dsp(STREAMFILE *streamFile) {
|
|||
vgmstream->interleave_block_size = interleave;
|
||||
vgmstream->meta_type = meta_UTF_DSP;
|
||||
|
||||
dsp_read_coefs_be(vgmstream, streamFile, header_offset+0x1c, 0x60);
|
||||
dsp_read_coefs_be(vgmstream, sf, header_offset+0x1c, 0x60);
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, streamFile, start_offset))
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "cri_utf.h"
|
||||
#include "../util/cri_utf.h"
|
||||
|
||||
|
||||
/* ACB (Atom Cue sheet Binary) - CRI container of memory audio, often together with a .awb wave bank */
|
||||
|
|
|
@ -0,0 +1,152 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
int total_subsongs;
|
||||
int target_subsong;
|
||||
|
||||
uint32_t stream_offset;
|
||||
uint32_t stream_size;
|
||||
|
||||
int loop_flag;
|
||||
int sample_rate;
|
||||
int channels;
|
||||
int32_t num_samples;
|
||||
} adm3_header_t;
|
||||
|
||||
static int parse_adm3(adm3_header_t* adm3, STREAMFILE* sf);
|
||||
|
||||
|
||||
/* ADM3 - Crankcase Audio REV plugin file [Cyberpunk 2077 (PC), MotoGP 21 (PC)] */
|
||||
VGMSTREAM* init_vgmstream_adm3(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
adm3_header_t adm3 = {0};
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "ADM3"))
|
||||
goto fail;
|
||||
if (!check_extensions(sf, "wem"))
|
||||
goto fail;
|
||||
|
||||
adm3.target_subsong = sf->stream_index;
|
||||
if (adm3.target_subsong == 0) adm3.target_subsong = 1;
|
||||
|
||||
/* ADM3 are files used with the Wwise Crankaudio plugin, that simulate engine noises with
|
||||
* base internal samples and some internal RPM config (probably). Actual file seems to
|
||||
* define some combo of samples, this only plays those separate samples.
|
||||
* Decoder is basically Apple's IMA (internally just "ADPCMDecoder") but transforms to float
|
||||
* each sample during decode by multiplying by 0.000030518509 */
|
||||
|
||||
if (!parse_adm3(&adm3, sf))
|
||||
goto fail;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(adm3.channels, adm3.loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_ADM3;
|
||||
vgmstream->sample_rate = adm3.sample_rate;
|
||||
vgmstream->num_samples = adm3.num_samples; /* slightly lower than bytes-to-samples */
|
||||
vgmstream->num_streams = adm3.total_subsongs;
|
||||
vgmstream->stream_size = adm3.stream_size;
|
||||
|
||||
vgmstream->coding_type = coding_APPLE_IMA4;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x22;
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, adm3.stream_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
static int parse_type(adm3_header_t* adm3, STREAMFILE* sf, uint32_t offset) {
|
||||
|
||||
if (is_id32be(offset, sf, "RMP1")) {
|
||||
offset = read_u32le(offset + 0x1c, sf);
|
||||
if (!parse_type(adm3, sf, offset))
|
||||
goto fail;
|
||||
/* 0x24: offset to GRN1 */
|
||||
}
|
||||
else if (is_id32be(offset, sf, "SMB1")) {
|
||||
uint32_t table_count = read_u32le(offset + 0x10, sf);
|
||||
uint32_t table_offset = read_u32le(offset + 0x18, sf);
|
||||
int i;
|
||||
|
||||
for (i = 0; i < table_count; i++) {
|
||||
uint32_t smp2_unk = read_u32le(table_offset + i * 0x08 + 0x00, sf);
|
||||
uint32_t smp2_offset = read_u32le(table_offset + i * 0x08 + 0x04, sf);
|
||||
|
||||
if (smp2_unk != 1)
|
||||
goto fail;
|
||||
|
||||
if (!parse_type(adm3, sf, smp2_offset)) /* SMP2 */
|
||||
goto fail;
|
||||
}
|
||||
}
|
||||
else if (is_id32be(offset, sf, "SMP2")) {
|
||||
adm3->total_subsongs++;
|
||||
|
||||
if (adm3->target_subsong == adm3->total_subsongs) {
|
||||
/* 0x04 always 0 */
|
||||
/* 0x08 always 0x00040000 */
|
||||
adm3->channels = read_u32le(offset + 0x0c, sf);
|
||||
/* 0x10 float pitch? */
|
||||
/* 0x14 int pitch? */
|
||||
/* 0x18 0x0001? */
|
||||
/* 0x1a 0x0030? (header size?) */
|
||||
adm3->sample_rate = read_s32le(offset + 0x1c, sf);
|
||||
adm3->num_samples = read_s32le(offset + 0x20, sf);
|
||||
adm3->stream_size = read_u32le(offset + 0x24, sf);
|
||||
/* 0x28 1? */
|
||||
adm3->stream_offset = read_u32le(offset + 0x2c, sf);
|
||||
}
|
||||
}
|
||||
else {
|
||||
VGM_LOG("ADM3: unknown at %x\n", offset);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int parse_adm3(adm3_header_t* adm3, STREAMFILE* sf) {
|
||||
uint32_t offset;
|
||||
|
||||
/* 0x04: null */
|
||||
/* 0x08: version? */
|
||||
/* 0x0c: header size */
|
||||
/* 0x10: data start */
|
||||
/* rest unknown, looks mostly the same between files */
|
||||
|
||||
/* higher ramp, N samples from low to high */
|
||||
offset = read_u32le(0x0FC, sf);
|
||||
if (!parse_type(adm3, sf, offset)) goto fail; /* RMP1 */
|
||||
if (read_u32le(0x100, sf) != 1) goto fail;
|
||||
|
||||
/* lower ramp, also N samples */
|
||||
offset = read_u32le(0x104, sf);
|
||||
if (!parse_type(adm3, sf, offset)) goto fail; /* RMP1 */
|
||||
if (read_u32le(0x108, sf) != 1) goto fail;
|
||||
|
||||
/* idle engine */
|
||||
offset = read_u32le(0x10c, sf);
|
||||
if (!parse_type(adm3, sf, offset)) goto fail; /* SMP2 */
|
||||
if (read_u32le(0x110, sf) != 1) goto fail;
|
||||
|
||||
if (adm3->target_subsong < 0 || adm3->target_subsong > adm3->total_subsongs || adm3->total_subsongs < 1)
|
||||
goto fail;
|
||||
|
||||
return 1;
|
||||
fail:
|
||||
return 0;
|
||||
}
|
|
@ -1,6 +1,6 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "cri_utf.h"
|
||||
#include "../util/cri_utf.h"
|
||||
|
||||
|
||||
typedef enum { HCA, CWAV, ADX } cpk_type_t;
|
||||
|
@ -26,10 +26,11 @@ VGMSTREAM* init_vgmstream_cpk_memory(STREAMFILE* sf, STREAMFILE* sf_acb) {
|
|||
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(sf, "awb"))
|
||||
goto fail;
|
||||
if (!is_id32be(0x00,sf, "CPK "))
|
||||
goto fail;
|
||||
if (!check_extensions(sf, "awb"))
|
||||
goto fail;
|
||||
|
||||
if (!is_id32be(0x10,sf, "@UTF"))
|
||||
goto fail;
|
||||
/* 04: 0xFF? */
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "cri_utf.h"
|
||||
#include "../util/cri_utf.h"
|
||||
|
||||
|
||||
/* CSB (Cue Sheet Binary?) - CRI container of memory audio, often together with a .cpk wave bank */
|
||||
|
@ -9,8 +9,8 @@ VGMSTREAM* init_vgmstream_csb(STREAMFILE* sf) {
|
|||
STREAMFILE* temp_sf = NULL;
|
||||
off_t subfile_offset;
|
||||
size_t subfile_size;
|
||||
utf_context *utf = NULL;
|
||||
utf_context *utf_sdl = NULL;
|
||||
utf_context* utf = NULL;
|
||||
utf_context* utf_sdl = NULL;
|
||||
int total_subsongs, target_subsong = sf->stream_index;
|
||||
uint8_t fmt = 0;
|
||||
const char* stream_name = NULL;
|
||||
|
|
|
@ -0,0 +1,46 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* .ESF - from Mortal Kombat 4 (PC) */
|
||||
VGMSTREAM* init_vgmstream_esf(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
uint32_t pcm_size;
|
||||
off_t start_offset;
|
||||
int loop_flag, bps_flag, hq_flag, channels, bps;
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00, sf, "ESF\x06"))
|
||||
goto fail;
|
||||
|
||||
if (!check_extensions(sf, "esf"))
|
||||
goto fail;
|
||||
|
||||
pcm_size = read_u32le(0x04, sf);
|
||||
bps_flag = pcm_size & 0x20000000;
|
||||
hq_flag = pcm_size & 0x40000000;
|
||||
loop_flag = pcm_size & 0x80000000;
|
||||
pcm_size &= 0x1FFFFFFF;
|
||||
|
||||
channels = 1; /* mono only */
|
||||
start_offset = 0x08;
|
||||
bps = bps_flag ? 16 : 8; /* 16 is supposed to mean PCM16 but is actually IMA */
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_ESF;
|
||||
vgmstream->sample_rate = hq_flag ? 22050 : 11025;
|
||||
vgmstream->coding_type = (bps == 8) ? coding_PCM8_U : coding_DVI_IMA;
|
||||
vgmstream->num_samples = pcm_bytes_to_samples(pcm_size, 1, bps);
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = vgmstream->num_samples;
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -982,4 +982,10 @@ VGMSTREAM* init_vgmstream_sspf(STREAMFILE* sf);
|
|||
|
||||
VGMSTREAM* init_vgmstream_s3v(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_esf(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_adm3(STREAMFILE* sf);
|
||||
|
||||
VGMSTREAM* init_vgmstream_tt_ad(STREAMFILE* sf);
|
||||
|
||||
#endif /*_META_H*/
|
||||
|
|
|
@ -2,16 +2,33 @@
|
|||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
/* MPEG - standard MP1/2/3 audio MP3 */
|
||||
/* MPEG - standard MP1/2/3 audio */
|
||||
VGMSTREAM* init_vgmstream_mpeg(STREAMFILE* sf) {
|
||||
#ifdef VGM_USE_MPEG
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
uint32_t start_offset;
|
||||
int loop_flag = 0;
|
||||
mpeg_frame_info info = {0};
|
||||
uint32_t header_id;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!mpeg_get_frame_info(sf, 0x00, &info))
|
||||
header_id = read_u32be(0x00, sf);
|
||||
if ((header_id & 0xFFF00000) != 0xFFF00000 &&
|
||||
(header_id & 0xFFFFFF00) != get_id32be("ID3\0") &&
|
||||
(header_id & 0xFFFFFF00) != get_id32be("TAG\0"))
|
||||
goto fail;
|
||||
|
||||
//TODO: may try init_mpeg as-is, already skips tags
|
||||
start_offset = 0x00;
|
||||
while (start_offset < get_streamfile_size(sf)) {
|
||||
uint32_t tag_size = mpeg_get_tag_size(sf, start_offset, 0);
|
||||
if (tag_size == 0)
|
||||
break;
|
||||
start_offset += tag_size;
|
||||
}
|
||||
|
||||
if (!mpeg_get_frame_info(sf, start_offset, &info))
|
||||
goto fail;
|
||||
|
||||
/* .mp3/mp2: standard (is .mp1 ever used in games?)
|
||||
|
|
|
@ -1,15 +1,17 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util/endianness.h"
|
||||
|
||||
|
||||
/* P3D - from Radical's Prototype 1/2 (PC/PS3/X360), Spider-Man 4 Beta (X360) */
|
||||
VGMSTREAM* init_vgmstream_p3d(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
off_t start_offset, offset, name_offset = 0;
|
||||
uint32_t start_offset, offset, name_offset = 0;
|
||||
size_t header_size, file_size, data_size;
|
||||
uint32_t xma2_offset = 0, xma2_size = 0;
|
||||
int loop_flag, channels, sample_rate, codec;
|
||||
int i, name_count, text_len, block_size = 0, num_samples;
|
||||
uint32_t (*read_u32)(off_t,STREAMFILE*) = NULL;
|
||||
int i, name_count, unk_count, text_len, block_size = 0, num_samples;
|
||||
read_u32_t read_u32;
|
||||
|
||||
|
||||
/* checks */
|
||||
|
@ -19,30 +21,36 @@ VGMSTREAM* init_vgmstream_p3d(STREAMFILE* sf) {
|
|||
if (!check_extensions(sf,"p3d"))
|
||||
goto fail;
|
||||
|
||||
read_u32 = guess_endianness32bit(0x04,sf) ? read_u32be : read_u32le;
|
||||
read_u32 = guess_endian32(0x04,sf) ? read_u32be : read_u32le;
|
||||
file_size = get_streamfile_size(sf);
|
||||
|
||||
/* base header */
|
||||
header_size = read_u32(0x04,sf);
|
||||
if (header_size != 0x0C) goto fail;
|
||||
if (header_size != 0x0c) goto fail;
|
||||
if (read_u32(0x08,sf) != file_size) goto fail;
|
||||
if (read_u32(0x0C,sf) != 0xFE000000) goto fail; /* fixed */
|
||||
if (read_u32(0x10,sf) + header_size != file_size) goto fail;
|
||||
if (read_u32(0x14,sf) + header_size != file_size) goto fail; /* body size again */
|
||||
if (read_u32(0x18,sf) != 0x0000000A) goto fail; /* fixed */
|
||||
offset = 0x0c;
|
||||
|
||||
/* header text */
|
||||
offset = 0x1C;
|
||||
text_len = read_u32(offset,sf);
|
||||
/* P3D is just a generic container used in Radical's games, so we only want "AudioFile".
|
||||
* Rarely some voice files start with a "AudioDialogueSubtitle" section, so skip that first */
|
||||
if (is_id64be(offset+0x14,sf, "AudioDia")) {
|
||||
offset += read_u32(offset + 0x04,sf); /* section size */
|
||||
}
|
||||
|
||||
/* AudioFile section */
|
||||
if (read_u32(offset + 0x00,sf) != 0xFE000000) goto fail; /* section marker */
|
||||
if (read_u32(offset + 0x04,sf) + offset != file_size) goto fail; /* AudioFile size */
|
||||
if (read_u32(offset + 0x08,sf) + offset != file_size) goto fail; /* again */
|
||||
if (read_u32(offset + 0x0c,sf) != 0x0000000A) goto fail; /* fixed */
|
||||
|
||||
text_len = read_u32(offset + 0x10,sf);
|
||||
if (text_len != 9) goto fail;
|
||||
offset += 0x04;
|
||||
offset += 0x14;
|
||||
|
||||
/* check the type as P3D is just a generic container used in Radical's games */
|
||||
if (!is_id64be(offset+0x00,sf, "AudioFil") || read_u16be(offset+0x08,sf) != 0x6500) /* "AudioFile\0" */
|
||||
goto fail;
|
||||
offset += text_len + 0x01;
|
||||
|
||||
/* file names: always 2 (repeated); but if it's 3 there is an extra string later */
|
||||
/* file names: 1 internal stream name + 1 external filename (usually repeated) + 1 an extra string later (P2) */
|
||||
name_count = read_u32(offset,sf);
|
||||
if (name_count != 2 && name_count != 3) goto fail; /* 2: Prototype1, 3: Prototype2 */
|
||||
offset += 0x04;
|
||||
|
@ -55,8 +63,9 @@ VGMSTREAM* init_vgmstream_p3d(STREAMFILE* sf) {
|
|||
offset += 0x04 + text_len;
|
||||
}
|
||||
|
||||
/* info count? */
|
||||
if (0x01 != read_u32(offset,sf)) goto fail;
|
||||
/* 1=music, 0=dialogues */
|
||||
unk_count = read_u32(offset,sf);
|
||||
if (unk_count != 0x00 && unk_count != 0x01) goto fail;
|
||||
offset += 0x04;
|
||||
|
||||
/* next string can be used as a codec id */
|
||||
|
@ -64,8 +73,8 @@ VGMSTREAM* init_vgmstream_p3d(STREAMFILE* sf) {
|
|||
codec = read_u32be(offset+0x04,sf);
|
||||
offset += 0x04 + text_len + 0x01;
|
||||
|
||||
/* extra "Music" string in Prototype 2 */
|
||||
if (name_count == 3) {
|
||||
/* extra "Music" or "Dialogue" string in Prototype 2 */
|
||||
if (name_count >= 3) {
|
||||
text_len = read_u32(offset,sf) + 1; /* null-terminated */
|
||||
offset += 0x04 + text_len;
|
||||
}
|
||||
|
|
|
@ -654,8 +654,8 @@ VGMSTREAM* init_vgmstream_riff(STREAMFILE* sf) {
|
|||
read_u32be(start_offset+0x3c, sf) == 0xFFFFFFFF)
|
||||
goto fail;
|
||||
|
||||
///* MSADPCM .ckd are parsed elsewhere, though they are valid so no big deal if parsed here (just that loops should be ignored) */
|
||||
if (!fmt.is_at9 && check_extensions(sf, "ckd"))
|
||||
/* MSADPCM .ckd are parsed elsewhere, though they are valid so no big deal if parsed here (just that loops should be ignored) */
|
||||
if (fmt.codec == 0x0002 && check_extensions(sf, "ckd"))
|
||||
goto fail;
|
||||
|
||||
/* ignore Gitaroo Man Live! (PSP) multi-RIFF (to allow chunked TXTH) */
|
||||
|
|
|
@ -21,7 +21,7 @@ VGMSTREAM* init_vgmstream_sspf(STREAMFILE* sf) {
|
|||
goto fail;
|
||||
|
||||
/* extra check to ignore .spc, that are a RAM pack of .ssp with a ~0x800 table at the end */
|
||||
file_size = read_u32be(0x08, sf) + 0x08; /* without padding */
|
||||
file_size = read_u32be(0x08, sf); /* without padding */
|
||||
pad_size = 0;
|
||||
if (file_size % 0x800) /* add padding */
|
||||
pad_size = 0x800 - (file_size % 0x800);
|
||||
|
|
|
@ -2,24 +2,36 @@
|
|||
#include "../coding/coding.h"
|
||||
|
||||
/* Tiger Game.com ADPCM file */
|
||||
VGMSTREAM * init_vgmstream_tgc(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
VGMSTREAM* init_vgmstream_tgc(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
uint16_t size;
|
||||
off_t start_offset;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!check_extensions(streamFile, "4"))
|
||||
if (read_u8(0x00, sf) != 0)
|
||||
goto fail;
|
||||
|
||||
if (!check_extensions(sf, "4"))
|
||||
goto fail;
|
||||
|
||||
size = read_u16be(0x01, sf);
|
||||
if (size != get_streamfile_size(sf))
|
||||
goto fail;
|
||||
start_offset = 0x03;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(1, 0);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->sample_rate = 8000;
|
||||
vgmstream->num_samples = ((uint16_t)read_16bitBE(1, streamFile) - 3) * 2;
|
||||
vgmstream->num_samples = (size - 0x03) * 2;
|
||||
vgmstream->meta_type = meta_TGC;
|
||||
vgmstream->layout_type = layout_none;
|
||||
vgmstream->coding_type = coding_TGC;
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, streamFile, 3))
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
goto fail;
|
||||
|
||||
return vgmstream;
|
||||
|
|
|
@ -0,0 +1,94 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
/* .AUDIO_DATA - Traveller's Tales "NTT" engine audio format [Lego Star Wars: The Skywalker Saga (PC/Switch)] */
|
||||
VGMSTREAM* init_vgmstream_tt_ad(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
uint32_t offset, stream_offset, stream_size;
|
||||
int loop_flag, channels, sample_rate, codec, frame_size = 0;
|
||||
int32_t num_samples;
|
||||
|
||||
|
||||
/* checks */
|
||||
if (!is_id32be(0x00,sf, "FMT "))
|
||||
goto fail;
|
||||
|
||||
/* actual extension */
|
||||
if (!check_extensions(sf, "audio_data"))
|
||||
goto fail;
|
||||
|
||||
offset = 0x08;
|
||||
/* 0x00: null */
|
||||
codec = read_u16le(offset + 0x02,sf);
|
||||
sample_rate = read_s32le(offset + 0x04,sf);
|
||||
num_samples = read_s32le(offset + 0x08,sf);
|
||||
channels = read_u8(offset + 0x0c,sf);
|
||||
/* 0x0d: bps (16=IMA, 32=Ogg) */
|
||||
/* 0x10:
|
||||
Ogg = some size?
|
||||
IMA = frame size + flag? */
|
||||
if (codec == 0x0a)
|
||||
frame_size = read_u16le(offset + 0x10,sf);
|
||||
|
||||
|
||||
loop_flag = 0; /* music just repeats? */
|
||||
|
||||
offset += read_u32le(0x04, sf);
|
||||
|
||||
/* Ogg seek table*/
|
||||
if (is_id32be(offset, sf, "SEEK")) {
|
||||
offset += 0x08 + read_u32le(offset + 0x04, sf);
|
||||
}
|
||||
|
||||
/* found with some IMA */
|
||||
if (is_id32be(offset, sf, "RMS ")) {
|
||||
offset += 0x08 + read_u32le(offset + 0x04, sf);
|
||||
}
|
||||
|
||||
if (!is_id32be(offset, sf, "DATA"))
|
||||
goto fail;
|
||||
|
||||
stream_offset = offset + 0x08;
|
||||
stream_size = read_u32le(offset + 0x04, sf);
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channels, loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
vgmstream->meta_type = meta_TT_AD;
|
||||
vgmstream->sample_rate = sample_rate;
|
||||
vgmstream->num_samples = num_samples;
|
||||
|
||||
switch(codec) {
|
||||
#ifdef VGM_USE_VORBIS
|
||||
case 0x01: {
|
||||
vgmstream->codec_data = init_ogg_vorbis(sf, stream_offset, stream_size, NULL);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_OGG_VORBIS;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
case 0x0a:
|
||||
vgmstream->coding_type = coding_MS_IMA_mono;
|
||||
vgmstream->layout_type = layout_blocked_tt_ad;
|
||||
vgmstream->frame_size = frame_size;
|
||||
vgmstream->interleave_block_size = frame_size;
|
||||
break;
|
||||
|
||||
default:
|
||||
vgm_logi("FMT: unsupported codec 0x%x\n", codec);
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, stream_offset))
|
||||
goto fail;
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
|
@ -46,6 +46,7 @@ typedef enum {
|
|||
XA,
|
||||
XA_EA,
|
||||
CP_YM,
|
||||
PCM_FLOAT_LE,
|
||||
|
||||
UNKNOWN = 99,
|
||||
} txth_codec_t;
|
||||
|
@ -213,13 +214,14 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) {
|
|||
if (txth.interleave == 0) {
|
||||
uint32_t interleave = 0;
|
||||
switch(txth.codec) {
|
||||
case PSX: interleave = 0x10; break;
|
||||
case PSX_bf: interleave = 0x10; break;
|
||||
case NGC_DSP: interleave = 0x08; break;
|
||||
case PCM16LE: interleave = 0x02; break;
|
||||
case PCM16BE: interleave = 0x02; break;
|
||||
case PCM8: interleave = 0x01; break;
|
||||
case PCM8_U: interleave = 0x01; break;
|
||||
case PSX: interleave = 0x10; break;
|
||||
case PSX_bf: interleave = 0x10; break;
|
||||
case NGC_DSP: interleave = 0x08; break;
|
||||
case PCM16LE: interleave = 0x02; break;
|
||||
case PCM16BE: interleave = 0x02; break;
|
||||
case PCM8: interleave = 0x01; break;
|
||||
case PCM8_U: interleave = 0x01; break;
|
||||
case PCM_FLOAT_LE: interleave = 0x04; break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -229,26 +231,27 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) {
|
|||
|
||||
/* type to coding conversion */
|
||||
switch (txth.codec) {
|
||||
case PSX: coding = coding_PSX; break;
|
||||
case XBOX: coding = coding_XBOX_IMA; break;
|
||||
case NGC_DTK: coding = coding_NGC_DTK; break;
|
||||
case PCM16BE: coding = coding_PCM16BE; break;
|
||||
case PCM16LE: coding = coding_PCM16LE; break;
|
||||
case PCM8: coding = coding_PCM8; break;
|
||||
case SDX2: coding = coding_SDX2; break;
|
||||
case DVI_IMA: coding = coding_DVI_IMA; break;
|
||||
case PSX: coding = coding_PSX; break;
|
||||
case XBOX: coding = coding_XBOX_IMA; break;
|
||||
case NGC_DTK: coding = coding_NGC_DTK; break;
|
||||
case PCM16BE: coding = coding_PCM16BE; break;
|
||||
case PCM16LE: coding = coding_PCM16LE; break;
|
||||
case PCM8: coding = coding_PCM8; break;
|
||||
case PCM_FLOAT_LE: coding = coding_PCMFLOAT; break;
|
||||
case SDX2: coding = coding_SDX2; break;
|
||||
case DVI_IMA: coding = coding_DVI_IMA; break;
|
||||
#ifdef VGM_USE_MPEG
|
||||
case MPEG: coding = coding_MPEG_layer3; break; /* we later find out exactly which */
|
||||
case MPEG: coding = coding_MPEG_layer3; break; /* we later find out exactly which */
|
||||
#endif
|
||||
case IMA: coding = coding_IMA; break;
|
||||
case AICA: coding = coding_AICA; break;
|
||||
case MSADPCM: coding = coding_MSADPCM; break;
|
||||
case NGC_DSP: coding = coding_NGC_DSP; break;
|
||||
case PCM8_U_int: coding = coding_PCM8_U_int; break;
|
||||
case PSX_bf: coding = coding_PSX_badflags; break;
|
||||
case MS_IMA: coding = coding_MS_IMA; break;
|
||||
case PCM8_U: coding = coding_PCM8_U; break;
|
||||
case APPLE_IMA4: coding = coding_APPLE_IMA4; break;
|
||||
case IMA: coding = coding_IMA; break;
|
||||
case AICA: coding = coding_AICA; break;
|
||||
case MSADPCM: coding = coding_MSADPCM; break;
|
||||
case NGC_DSP: coding = coding_NGC_DSP; break;
|
||||
case PCM8_U_int: coding = coding_PCM8_U_int; break;
|
||||
case PSX_bf: coding = coding_PSX_badflags; break;
|
||||
case MS_IMA: coding = coding_MS_IMA; break;
|
||||
case PCM8_U: coding = coding_PCM8_U; break;
|
||||
case APPLE_IMA4: coding = coding_APPLE_IMA4; break;
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
case ATRAC3:
|
||||
case ATRAC3PLUS:
|
||||
|
@ -256,19 +259,19 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) {
|
|||
case XMA2:
|
||||
case AC3:
|
||||
case AAC:
|
||||
case FFMPEG: coding = coding_FFmpeg; break;
|
||||
case FFMPEG: coding = coding_FFmpeg; break;
|
||||
#endif
|
||||
case PCFX: coding = coding_PCFX; break;
|
||||
case PCM4: coding = coding_PCM4; break;
|
||||
case PCM4_U: coding = coding_PCM4_U; break;
|
||||
case OKI16: coding = coding_OKI16; break;
|
||||
case OKI4S: coding = coding_OKI4S; break;
|
||||
case TGC: coding = coding_TGC; break;
|
||||
case ASF: coding = coding_ASF; break;
|
||||
case EAXA: coding = coding_EA_XA; break;
|
||||
case XA: coding = coding_XA; break;
|
||||
case XA_EA: coding = coding_XA_EA; break;
|
||||
case CP_YM: coding = coding_CP_YM; break;
|
||||
case PCFX: coding = coding_PCFX; break;
|
||||
case PCM4: coding = coding_PCM4; break;
|
||||
case PCM4_U: coding = coding_PCM4_U; break;
|
||||
case OKI16: coding = coding_OKI16; break;
|
||||
case OKI4S: coding = coding_OKI4S; break;
|
||||
case TGC: coding = coding_TGC; break;
|
||||
case ASF: coding = coding_ASF; break;
|
||||
case EAXA: coding = coding_EA_XA; break;
|
||||
case XA: coding = coding_XA; break;
|
||||
case XA_EA: coding = coding_XA_EA; break;
|
||||
case CP_YM: coding = coding_CP_YM; break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
@ -305,6 +308,7 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) {
|
|||
case coding_PCM16BE:
|
||||
case coding_PCM8:
|
||||
case coding_PCM8_U:
|
||||
case coding_PCMFLOAT:
|
||||
case coding_PCM4:
|
||||
case coding_PCM4_U:
|
||||
case coding_SDX2:
|
||||
|
@ -963,6 +967,7 @@ static txth_codec_t parse_codec(txth_header* txth, const char* val) {
|
|||
else if (is_string(val,"XA")) return XA;
|
||||
else if (is_string(val,"XA_EA")) return XA_EA;
|
||||
else if (is_string(val,"CP_YM")) return CP_YM;
|
||||
else if (is_string(val,"PCM_FLOAT_LE")) return PCM_FLOAT_LE;
|
||||
/* special handling */
|
||||
else if (is_string(val,"name_value")) return txth->name_values[0];
|
||||
else if (is_string(val,"name_value1")) return txth->name_values[0];
|
||||
|
@ -2039,6 +2044,8 @@ static int get_bytes_to_samples(txth_header* txth, uint32_t bytes) {
|
|||
case PCM8_U_int:
|
||||
case PCM8_U:
|
||||
return pcm_bytes_to_samples(bytes, txth->channels, 8);
|
||||
case PCM_FLOAT_LE:
|
||||
return pcm_bytes_to_samples(bytes, txth->channels, 32);
|
||||
case PCM4:
|
||||
case PCM4_U:
|
||||
case TGC:
|
||||
|
|
|
@ -705,18 +705,13 @@ static VGMSTREAM* init_vgmstream_ubi_hx_header(ubi_hx_header* hx, STREAMFILE* sf
|
|||
break;
|
||||
|
||||
case UBI:
|
||||
vgmstream->codec_data = init_ubi_adpcm(sb, hx->stream_offset, vgmstream->channels);
|
||||
vgmstream->codec_data = init_ubi_adpcm(sb, hx->stream_offset, hx->stream_size, vgmstream->channels);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_UBI_ADPCM;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
vgmstream->num_samples = ubi_adpcm_get_samples(vgmstream->codec_data);
|
||||
|
||||
/* some kind of internal bug I guess, seen in a few subsongs in Rayman 3 PC demo, other values are also buggy */
|
||||
if (vgmstream->num_samples == 0x77E7A374) {
|
||||
vgmstream->num_samples = ubi_adpcm_bytes_to_samples(vgmstream->codec_data, hx->stream_size);
|
||||
}
|
||||
|
||||
/* XIII has 6-bit stereo music, Rayman 3 4-bit music, both use 6-bit mono) */
|
||||
break;
|
||||
|
||||
|
|
|
@ -1018,7 +1018,7 @@ static VGMSTREAM* init_vgmstream_ubi_sb_base(ubi_sb_header* sb, STREAMFILE* sf_h
|
|||
sb->stream_size -= 0x08;
|
||||
}
|
||||
|
||||
vgmstream->codec_data = init_ubi_adpcm(sf_data, start_offset, vgmstream->channels);
|
||||
vgmstream->codec_data = init_ubi_adpcm(sf_data, start_offset, 0, vgmstream->channels);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_UBI_ADPCM;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
|
|
@ -304,6 +304,7 @@ int render_layout(sample_t* buf, int32_t sample_count, VGMSTREAM* vgmstream) {
|
|||
case layout_blocked_vs_square:
|
||||
case layout_blocked_vid1:
|
||||
case layout_blocked_ubi_sce:
|
||||
case layout_blocked_tt_ad:
|
||||
render_vgmstream_blocked(buf, sample_count, vgmstream);
|
||||
break;
|
||||
case layout_segmented:
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
#include "cri_utf.h"
|
||||
#include "../util/log.h"
|
||||
#include "log.h"
|
||||
|
||||
#define UTF_MAX_SCHEMA_SIZE 0x8000 /* arbitrary max */
|
||||
#define COLUMN_BITMASK_FLAG 0xf0
|
|
@ -470,7 +470,6 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = {
|
|||
init_vgmstream_csb,
|
||||
init_vgmstream_fwse,
|
||||
init_vgmstream_fda,
|
||||
init_vgmstream_tgc,
|
||||
init_vgmstream_kwb,
|
||||
init_vgmstream_lrmd,
|
||||
init_vgmstream_bkhd,
|
||||
|
@ -522,6 +521,9 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = {
|
|||
init_vgmstream_sspf,
|
||||
init_vgmstream_opus_rsnd,
|
||||
init_vgmstream_s3v,
|
||||
init_vgmstream_esf,
|
||||
init_vgmstream_adm3,
|
||||
init_vgmstream_tt_ad,
|
||||
|
||||
/* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */
|
||||
init_vgmstream_mpeg,
|
||||
|
@ -535,6 +537,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = {
|
|||
init_vgmstream_seb,
|
||||
init_vgmstream_ps2_pnb,
|
||||
init_vgmstream_sli_ogg,
|
||||
init_vgmstream_tgc,
|
||||
|
||||
/* lowest priority metas (should go after all metas, and TXTH should go before raw formats) */
|
||||
init_vgmstream_txth, /* proper parsers should supersede TXTH, once added */
|
||||
|
@ -1159,9 +1162,10 @@ int vgmstream_open_stream_bf(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t start_o
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if ((vgmstream->coding_type == coding_MSADPCM ||
|
||||
vgmstream->coding_type == coding_MSADPCM_ck ||
|
||||
vgmstream->coding_type == coding_MSADPCM_int) &&
|
||||
if ((vgmstream->coding_type == coding_MSADPCM || vgmstream->coding_type == coding_MSADPCM_ck ||
|
||||
vgmstream->coding_type == coding_MSADPCM_int ||
|
||||
vgmstream->coding_type == coding_MS_IMA || vgmstream->coding_type == coding_MS_IMA_mono
|
||||
) &&
|
||||
vgmstream->frame_size == 0) {
|
||||
vgmstream->frame_size = vgmstream->interleave_block_size;
|
||||
}
|
||||
|
|
|
@ -123,6 +123,7 @@ typedef enum {
|
|||
coding_BLITZ_IMA, /* Blitz Games 4-bit IMA ADPCM */
|
||||
|
||||
coding_MS_IMA, /* Microsoft IMA ADPCM */
|
||||
coding_MS_IMA_mono, /* Microsoft IMA ADPCM (mono/interleave) */
|
||||
coding_XBOX_IMA, /* XBOX IMA ADPCM */
|
||||
coding_XBOX_IMA_mch, /* XBOX IMA ADPCM (multichannel) */
|
||||
coding_XBOX_IMA_int, /* XBOX IMA ADPCM (mono/interleave) */
|
||||
|
@ -286,6 +287,7 @@ typedef enum {
|
|||
layout_blocked_vs_square,
|
||||
layout_blocked_vid1,
|
||||
layout_blocked_ubi_sce,
|
||||
layout_blocked_tt_ad,
|
||||
|
||||
/* otherwise odd */
|
||||
layout_segmented, /* song divided in segments (song sections) */
|
||||
|
@ -765,6 +767,9 @@ typedef enum {
|
|||
meta_MPEG,
|
||||
meta_SSPF,
|
||||
meta_S3V,
|
||||
meta_ESF,
|
||||
meta_ADM3,
|
||||
meta_TT_AD,
|
||||
|
||||
} meta_t;
|
||||
|
||||
|
|
Loading…
Reference in New Issue