diff --git a/src/Makefile b/src/Makefile index 22ff2f65..ca4f16f2 100644 --- a/src/Makefile +++ b/src/Makefile @@ -268,9 +268,9 @@ META_OBJS=meta/adx_header.o \ meta/ngc_nst_dsp.o \ meta/baf.o \ meta/ps3_msf.o \ - meta/nub.o \ + meta/nub_vag.o \ meta/ps3_past.o \ - meta/ps3_sgh_sgb.o \ + meta/sgxd.o \ meta/ngca.o \ meta/wii_ras.o \ meta/ps2_spm.o \ @@ -279,7 +279,7 @@ META_OBJS=meta/adx_header.o \ meta/ps2_iab.o \ meta/ps2_strlr.o \ meta/lsf.o \ - meta/ps3_vawx.o \ + meta/vawx.o \ meta/pc_snds.o \ meta/ps2_wmus.o \ meta/mattel_hyperscan.o \ @@ -309,11 +309,12 @@ META_OBJS=meta/adx_header.o \ meta/ffmpeg.o \ meta/mp4.o \ meta/xma.o \ - meta/ps2.o \ - meta/x360.o \ + meta/ps2_vds_vdm.o \ + meta/x360_cxs.o \ meta/dsp_adx.o \ meta/bik.o \ - meta/akb.o + meta/akb.o \ + meta/x360_ast.o EXT_LIBS = ../ext_libs/clHCA.o diff --git a/src/coding/coding.h b/src/coding/coding.h index b2e01497..458b157a 100644 --- a/src/coding/coding.h +++ b/src/coding/coding.h @@ -164,12 +164,12 @@ void seek_ffmpeg(VGMSTREAM *vgmstream, int32_t num_sample); void ffmpeg_set_skip_samples(ffmpeg_codec_data * data, int skip_samples); /* ffmpeg_decoder_utils */ -int ffmpeg_fmt_chunk_swap_endian(uint8_t * chunk, uint16_t codec); +int ffmpeg_fmt_chunk_swap_endian(uint8_t * chunk, size_t chunk_size, uint16_t codec); 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); int ffmpeg_make_riff_atrac3plus(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int block_align, int encoder_delay); int ffmpeg_make_riff_xma1(uint8_t * buf, size_t buf_size, size_t sample_count, size_t data_size, int channels, int sample_rate, int stream_mode); 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); +int ffmpeg_make_riff_xma_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); int ffmpeg_make_riff_xwma(uint8_t * buf, size_t buf_size, int codec, size_t sample_count, size_t data_size, int channels, int sample_rate, int avg_bps, int block_align); /* XMA sample parser info (struct to avoid passing so much stuff, separate for reusing) */ diff --git a/src/coding/ffmpeg_decoder_utils.c b/src/coding/ffmpeg_decoder_utils.c index cb92f775..8ce1409a 100644 --- a/src/coding/ffmpeg_decoder_utils.c +++ b/src/coding/ffmpeg_decoder_utils.c @@ -256,7 +256,7 @@ int ffmpeg_make_riff_xma2(uint8_t * buf, size_t buf_size, size_t sample_count, s return riff_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) { +int ffmpeg_make_riff_xma_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]; @@ -265,8 +265,10 @@ int ffmpeg_make_riff_xma2_from_fmt(uint8_t * buf, size_t buf_size, off_t fmt_off if (read_streamfile(chunk,fmt_offset,fmt_size, streamFile) != fmt_size) goto fail; - if (big_endian) - ffmpeg_fmt_chunk_swap_endian(chunk, 0x166); + if (big_endian) { + int codec = read_16bitBE(fmt_offset,streamFile); + ffmpeg_fmt_chunk_swap_endian(chunk, fmt_size, codec); + } memcpy(buf+0x00, "RIFF", 4); put_32bitLE(buf+0x04, (int32_t)(riff_size-4-4 + data_size)); /* riff size */ @@ -313,28 +315,54 @@ int ffmpeg_make_riff_xwma(uint8_t * buf, size_t buf_size, int codec, size_t samp } -int ffmpeg_fmt_chunk_swap_endian(uint8_t * chunk, uint16_t codec) { - if (codec != 0x166)/* XMA2 */ - goto fail; +int ffmpeg_fmt_chunk_swap_endian(uint8_t * chunk, size_t chunk_size, uint16_t codec) { + int i; + /* swap from LE to BE or the other way around, doesn't matter */ + switch(codec) { + case 0x165: { /* XMA1 */ + put_16bitLE(chunk + 0x00, get_16bitBE(chunk + 0x00));/*FormatTag*/ + put_16bitLE(chunk + 0x02, get_16bitBE(chunk + 0x02));/*BitsPerSample*/ + put_16bitLE(chunk + 0x04, get_16bitBE(chunk + 0x04));/*EncodeOptions*/ + put_16bitLE(chunk + 0x06, get_16bitBE(chunk + 0x06));/*LargestSkip*/ + put_16bitLE(chunk + 0x08, get_16bitBE(chunk + 0x08));/*NumStreams*/ + // put_8bit(chunk + 0x0a, get_8bit(chunk + 0x0a));/*LoopCount*/ + // put_8bit(chunk + 0x0b, get_8bit(chunk + 0x0b));/*Version*/ + for (i = 0xc; i < chunk_size; i += 0x14) { /* reverse endianness for each stream */ + put_32bitLE(chunk + i + 0x00, get_32bitBE(chunk + i + 0x00));/*PsuedoBytesPerSec*/ + put_32bitLE(chunk + i + 0x04, get_32bitBE(chunk + i + 0x04));/*SampleRate*/ + put_32bitLE(chunk + i + 0x08, get_32bitBE(chunk + i + 0x08));/*LoopStart*/ + put_32bitLE(chunk + i + 0x0c, get_32bitBE(chunk + i + 0x0c));/*LoopEnd*/ + // put_8bit(chunk + i + 0x10, get_8bit(chunk + i + 0x10));/*SubframeData*/ + // put_8bit(chunk + i + 0x11, get_8bit(chunk + i + 0x11));/*Channels*/ + put_16bitLE(chunk + i + 0x12, get_16bitBE(chunk + i + 0x12));/*ChannelMask*/ + } + break; + } - 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*/ + case 0x166: { /* XMA2 */ + 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*/ + break; + } + default: + goto fail; + } return 1; diff --git a/src/coding/psx_decoder.c b/src/coding/psx_decoder.c index f04457ee..80fecc8d 100644 --- a/src/coding/psx_decoder.c +++ b/src/coding/psx_decoder.c @@ -369,7 +369,7 @@ void decode_hevag(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing /** * PS ADPCM of configurable size, with 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. + * Found in PS3 Afrika (SGXD type 5) in size 4, FF XI in sizes 3/5/9/41, Blur and James Bond in size 33. */ 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; @@ -417,7 +417,6 @@ void decode_psx_configurable(VGMSTREAMCHANNEL * stream, sample * outbuf, int cha sample = (scale >> shift) + (hist1 * VAG_coefs[predict_nr][0] + hist2 * VAG_coefs[predict_nr][1] ) / 64; - sample = sample + ; #else sample = (int)( (scale >> shift) + (hist1 * VAG_f[predict_nr][0] + diff --git a/src/formats.c b/src/formats.c index 88a50e75..4b53cc4b 100644 --- a/src/formats.c +++ b/src/formats.c @@ -562,7 +562,7 @@ static const meta_info meta_info_list[] = { {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_XBOX_RIFF, "Microsoft XWAV RIFF header"}, {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"}, @@ -570,7 +570,7 @@ static const meta_info meta_info_list[] = { {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_CFN, "tri-Crescendo CAF Header"}, {meta_PS2_VPK, "VPK Header"}, {meta_GENH, "GENH Generic Header"}, {meta_DSP_SADB, "sadb header"}, @@ -742,12 +742,12 @@ static const meta_info meta_info_list[] = { {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_CAPDSP, "Capcom 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_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"}, @@ -778,14 +778,14 @@ static const meta_info meta_info_list[] = { {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_PS3_CPS, "tri-Crescendo CPS Header"}, + {meta_SQEX_SCD, "Square-Enix SCD header"}, {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_MSF, "Sony MSF header"}, + {meta_NUB_VAG, "Namco NUB VAG header"}, {meta_PS3_PAST, "SNDP header"}, - {meta_PS3_SGDX, "SGXD header"}, + {meta_SGXD, "Sony SGXD header"}, {meta_NGCA, "NGCA header"}, {meta_WII_RAS, "RAS header"}, {meta_PS2_SPM, "SPM header"}, @@ -813,7 +813,7 @@ static const meta_info meta_info_list[] = { {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_PS2_2PFS, "Konami 2PFS header"}, {meta_RSD6OOGV, "RSD6/OOGV Header"}, {meta_UBI_CKD, "CKD 'RIFF' Header"}, {meta_PS2_VBK, "PS2 VBK Header"}, @@ -822,14 +822,19 @@ static const meta_info meta_info_list[] = { {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_WIIU_BTSND, "Nintendo 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"}, - {meta_AKB, "Square Enix AKB Header"}, + {meta_PS2_VDS_VDM, "Graffiti Kingdom VDS/VDM header"}, + {meta_X360_CXS, "tri-Crescendo CXS header"}, + {meta_AKB, "Square-Enix AKB header"}, + {meta_NUB_XMA, "Namco NUB XMA header"}, + {meta_X360_PASX, "Namco PASX header"}, + {meta_XMA_RIFF, "Microsoft XMA RIFF header"}, + {meta_X360_AST, "Capcom AST header"}, + #ifdef VGM_USE_VORBIS {meta_OGG_VORBIS, "Ogg Vorbis"}, {meta_OGG_SLI, "Ogg Vorbis with .sli (start,length) for looping"}, diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index 425119dc..7dec4499 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -595,7 +595,7 @@ > + + - + @@ -159,14 +159,15 @@ - - + + - + + @@ -271,7 +272,7 @@ - + diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index 2e6fb949..39a541b0 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -367,7 +367,7 @@ meta\Source Files - + meta\Source Files @@ -883,13 +883,13 @@ layout\Source Files - + meta\Source Files meta\Source Files - + meta\Source Files @@ -928,7 +928,7 @@ meta\Source Files - + meta\Source Files @@ -1027,7 +1027,7 @@ meta\Source Files - + meta\Source Files @@ -1036,5 +1036,8 @@ meta\Source Files + + meta\Source Files + \ No newline at end of file diff --git a/src/meta/Makefile.unix.am b/src/meta/Makefile.unix.am index 9320a527..d918fc57 100644 --- a/src/meta/Makefile.unix.am +++ b/src/meta/Makefile.unix.am @@ -209,9 +209,9 @@ libmeta_la_SOURCES += sqex_scd.c libmeta_la_SOURCES += ngc_nst_dsp.c libmeta_la_SOURCES += baf.c libmeta_la_SOURCES += ps3_msf.c -libmeta_la_SOURCES += nub.c +libmeta_la_SOURCES += nub_vag.c libmeta_la_SOURCES += ps3_past.c -libmeta_la_SOURCES += ps3_sgh_sgb.c +libmeta_la_SOURCES += sgxd.c libmeta_la_SOURCES += ngca.c libmeta_la_SOURCES += wii_ras.c libmeta_la_SOURCES += ps2_spm.c @@ -219,7 +219,7 @@ libmeta_la_SOURCES += x360_tra.c libmeta_la_SOURCES += ps2_iab.c libmeta_la_SOURCES += ps2_strlr.c libmeta_la_SOURCES += lsf.c -libmeta_la_SOURCES += ps3_vawx.c +libmeta_la_SOURCES += vawx.c libmeta_la_SOURCES += pc_snds.c libmeta_la_SOURCES += ps2_wmus.c libmeta_la_SOURCES += mattel_hyperscan.c @@ -248,10 +248,11 @@ libmeta_la_SOURCES += hca.c libmeta_la_SOURCES += ps2_svag_snk.c libmeta_la_SOURCES += mp4.c libmeta_la_SOURCES += xma.c -libmeta_la_SOURCES += ps2.c -libmeta_la_SOURCES += x360.c +libmeta_la_SOURCES += ps2_vds_vdm.c +libmeta_la_SOURCES += x360_cxs.c libmeta_la_SOURCES += dsp_adx.c libmeta_la_SOURCES += bik.c libmeta_la_SOURCES += akb.c +libmeta_la_SOURCES += x360_ast.c EXTRA_DIST = meta.h diff --git a/src/meta/bik.c b/src/meta/bik.c index be396b16..61db4322 100644 --- a/src/meta/bik.c +++ b/src/meta/bik.c @@ -91,9 +91,8 @@ static uint32_t bik_get_num_samples(STREAMFILE *streamFile, int bits_per_sample) /* multistream support just for fun (FFmpeg should select the same target stream) * (num_samples for other streams seem erratic though) */ - if (target_stream > num_tracks) goto fail; if (target_stream == 0) target_stream = 1; - //VGM_ASSERT(num_tracks > 1, "BIK: multiple streams found (%i entries)\n", num_tracks);//FFmpeg data has this + if (target_stream < 0 || target_stream > num_tracks || num_tracks < 1) goto fail; /* read each frame header and sum all samples * a frame has N audio packets with header (one per track) + video packet */ diff --git a/src/meta/fsb.c b/src/meta/fsb.c index 26e0261f..8189e27a 100644 --- a/src/meta/fsb.c +++ b/src/meta/fsb.c @@ -200,8 +200,8 @@ VGMSTREAM * init_vgmstream_fsb_offset(STREAMFILE *streamFile, off_t offset) { } if (fsbh.shdrsize < fsbh.shdrsize_min) goto fail; - if (target_stream > fsbh.numsamples || target_stream < 0) goto fail; if (target_stream == 0) target_stream = 1; + if (target_stream < 0 || target_stream > fsbh.numsamples || fsbh.numsamples < 1) goto fail; /* sample header (N-stream) */ { diff --git a/src/meta/g1l.c b/src/meta/g1l.c index 7ea4efe3..43e7e6eb 100644 --- a/src/meta/g1l.c +++ b/src/meta/g1l.c @@ -33,8 +33,9 @@ VGMSTREAM * init_vgmstream_kt_g1l(STREAMFILE *streamFile) { /* 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; + if (target_stream < 0 || target_stream > num_streams || num_streams < 1) goto fail; + stream_offset = read_32bit(0x18 + 0x4*(target_stream-1),streamFile); /* filesize = stream_offset - stream_next_offset*/ diff --git a/src/meta/gsp_gsb.c b/src/meta/gsp_gsb.c index d4c06d44..549707b8 100644 --- a/src/meta/gsp_gsb.c +++ b/src/meta/gsp_gsb.c @@ -113,7 +113,7 @@ VGMSTREAM * init_vgmstream_gsp_gsb(STREAMFILE *streamFile) { 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); + bytes = ffmpeg_make_riff_xma_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); diff --git a/src/meta/meta.h b/src/meta/meta.h index 7d5ef2a2..1848a7c9 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -582,7 +582,7 @@ VGMSTREAM * init_vgmstream_nub_vag(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_ps3_past(STREAMFILE* streamFile); -VGMSTREAM * init_vgmstream_ps3_sgdx(STREAMFILE* streamFile); +VGMSTREAM * init_vgmstream_sgxd(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_ngca(STREAMFILE* streamFile); @@ -672,4 +672,6 @@ VGMSTREAM * init_vgmstream_akb_multi(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_akb2_multi(STREAMFILE *streamFile); +VGMSTREAM * init_vgmstream_x360_ast(STREAMFILE *streamFile); + #endif /*_META_H*/ diff --git a/src/meta/nub.c b/src/meta/nub.c deleted file mode 100644 index 5a86426a..00000000 --- a/src/meta/nub.c +++ /dev/null @@ -1,70 +0,0 @@ -#include "meta.h" -#include "../util.h" - -/* Stuff from NUB archives */ - -/* VAG (from Ridge Racer 7) */ -VGMSTREAM * init_vgmstream_nub_vag(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; - off_t start_offset; - - int loop_flag; - int channel_count; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("vag",filename_extension(filename))) goto fail; - - /* check header */ - if (read_32bitBE(0x00,streamFile) != 0x76616700) /* "vag" */ - goto fail; - - if (read_32bitBE(0x30,streamFile)==0x3F800000) - loop_flag = 1; - else - loop_flag = 0; - - channel_count = 1; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - /* fill in the vital statistics */ - start_offset = 0xC0; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitBE(0xBC,streamFile); - vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = read_32bitBE(0x14,streamFile)*28/32*2; - if (loop_flag) { - vgmstream->loop_start_sample = read_32bitBE(0x20,streamFile)*28/32*2; - vgmstream->loop_end_sample = read_32bitBE(0x24,streamFile)*28/32*2; - } - - vgmstream->layout_type = layout_none; - vgmstream->meta_type = meta_NUB_VAG; - - /* open the file for reading */ - { - int i; - STREAMFILE * file; - file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (!file) goto fail; - for (i=0;ich[i].streamfile = file; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset=start_offset+ - vgmstream->interleave_block_size*i; - - } - } - - return vgmstream; - - /* clean up anything we may have opened */ -fail: - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} diff --git a/src/meta/nub_vag.c b/src/meta/nub_vag.c new file mode 100644 index 00000000..c74393e9 --- /dev/null +++ b/src/meta/nub_vag.c @@ -0,0 +1,46 @@ +#include "meta.h" +#include "../util.h" + +/* vag - from Namco's PS3 NUB archives (Ridge Racer 7) */ +VGMSTREAM * init_vgmstream_nub_vag(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + int loop_flag, channel_count; + + + /* check extension, case insensitive */ + if ( !check_extensions(streamFile, "vag")) goto fail; + + /* check header */ + if (read_32bitBE(0x00,streamFile) != 0x76616700) /* "vag\0" */ + goto fail; + + loop_flag = read_32bitBE(0x30,streamFile)==0x3F800000; + channel_count = 1; /* dual file stereo */ + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + vgmstream->sample_rate = read_32bitBE(0xBC,streamFile); + vgmstream->coding_type = coding_PSX; + vgmstream->num_samples = read_32bitBE(0x14,streamFile)*28/32*2; + if (loop_flag) { + vgmstream->loop_start_sample = read_32bitBE(0x20,streamFile)*28/32*2; + vgmstream->loop_end_sample = read_32bitBE(0x24,streamFile)*28/32*2; + } + + vgmstream->layout_type = layout_none; + vgmstream->meta_type = meta_NUB_VAG; + + start_offset = 0xC0; + + /* open the file for reading */ + if ( !vgmstream_open_stream(vgmstream,streamFile,start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/ps2_vag.c b/src/meta/ps2_vag.c index 94e633a6..6b6d6da2 100644 --- a/src/meta/ps2_vag.c +++ b/src/meta/ps2_vag.c @@ -3,9 +3,7 @@ static int vag_find_loop_offsets(STREAMFILE *streamFile, off_t start_offset, off_t * loop_start, off_t * loop_end); -/** - * VAGp - SDK format, created by Sony's tools (like AIFF2VAG) -*/ +/* VAGp - SDK format, created by various Sony's tools (like AIFF2VAG) */ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; off_t start_offset, loopStart = 0, loopEnd = 0; @@ -74,9 +72,16 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) { } else if (version == 0x00020001) { /* HEVAG */ loop_flag = vag_find_loop_offsets(streamFile, 0x30, &loopStart, &loopEnd); - channel_count = read_8bit(0x1e,streamFile); - if (channel_count == 0) - channel_count = 1; /* ex. Lumines */ + + /* channels are usually at 0x1e, but not in Ukiyo no Roushi which has some kind + * of loop-like values instead (who designs this crap?) */ + if (read_32bitBE(0x18,streamFile) != 0 || read_32bitBE(0x1c,streamFile) > 0x20) { + channel_count = 1; + } else { + channel_count = read_8bit(0x1e,streamFile); + if (channel_count == 0) + channel_count = 1; /* ex. early Vita vag (Lumines) */ + } } else { loop_flag = vag_find_loop_offsets(streamFile, 0x30, &loopStart, &loopEnd); diff --git a/src/meta/ps2.c b/src/meta/ps2_vds_vdm.c similarity index 100% rename from src/meta/ps2.c rename to src/meta/ps2_vds_vdm.c diff --git a/src/meta/ps3_msf.c b/src/meta/ps3_msf.c index 36882e0b..2df65199 100644 --- a/src/meta/ps3_msf.c +++ b/src/meta/ps3_msf.c @@ -39,8 +39,9 @@ VGMSTREAM * init_vgmstream_ps3_msf(STREAMFILE *streamFile) { * 0x40: joint stereo MP3 (apparently interleaved stereo for other formats) * 0x80+: (none/reserved) */ flags = read_32bitBE(header_offset+0x14,streamFile); - /* sometimes loop_start/end is set but not flag 0x01, but from tests it only loops with 0x01 */ - loop_flag = flags != 0xffffffff && (flags & 0x10) && (flags & 0x01); + /* sometimes loop_start/end is set but not flag 0x01, but from tests it only loops with 0x01 + * Malicious PS3 uses flag 0x2 instead */ + loop_flag = flags != 0xffffffff && (((flags & 0x10) && (flags & 0x01)) || (flags & 0x02)); /* loop markers (marker N @ 0x18 + N*(4+4), but in practice only marker 0 is used) */ if (loop_flag) { diff --git a/src/meta/riff.c b/src/meta/riff.c index 6a41732a..065c1959 100644 --- a/src/meta/riff.c +++ b/src/meta/riff.c @@ -250,7 +250,7 @@ VGMSTREAM * init_vgmstream_riff(STREAMFILE *streamFile) { if (strcasecmp("wav",filename_extension(filename)) && strcasecmp("lwav",filename_extension(filename)) #ifndef VGM_USE_FFMPEG - && strcasecmp("sgb",filename_extension(filename)) /* SGB has proper support with FFmpeg in ps3_sgdx */ + && strcasecmp("sgb",filename_extension(filename)) /* SGB has proper support with FFmpeg in sgxd */ #endif ) { diff --git a/src/meta/ps3_sgh_sgb.c b/src/meta/sgxd.c similarity index 93% rename from src/meta/ps3_sgh_sgb.c rename to src/meta/sgxd.c index 1204ca12..5e5e0f3b 100644 --- a/src/meta/ps3_sgh_sgb.c +++ b/src/meta/sgxd.c @@ -22,9 +22,9 @@ static int get_at3_riff_info(at3_riff_info* info, STREAMFILE *streamFile, int32_ * WSUR, WMRK, BUSS: unknown * RGND, SEQD: unknown (related to SE) * Then data, containing the original header if applicable (ex. AT3 RIFF). - * The SGDX header has priority over it (ex. some ATRAC3plus files have 48000 while the data RIFF 44100) + * The SGXD header has priority over it (ex. some ATRAC3plus files have 48000 while the data RIFF 44100) */ -VGMSTREAM * init_vgmstream_ps3_sgdx(STREAMFILE *streamFile) { +VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; STREAMFILE * streamHeader = NULL; @@ -81,7 +81,7 @@ VGMSTREAM * init_vgmstream_ps3_sgdx(STREAMFILE *streamFile) { /* check multi-streams (usually only SE containers; Puppeteer) */ total_streams = read_32bitLE(chunk_offset+0x04,streamHeader); if (target_stream == 0) target_stream = 1; - if (target_stream > total_streams) goto fail; + if (target_stream < 0 || target_stream > total_streams || total_streams < 1) goto fail; /* read stream header */ { @@ -126,7 +126,7 @@ VGMSTREAM * init_vgmstream_ps3_sgdx(STREAMFILE *streamFile) { vgmstream->loop_start_sample = loop_start_sample; vgmstream->loop_end_sample = loop_end_sample; vgmstream->num_streams = total_streams; - vgmstream->meta_type = meta_PS3_SGDX; + vgmstream->meta_type = meta_SGXD; switch (type) { case 0x03: /* PSX ADPCM */ @@ -202,7 +202,7 @@ fail: /** * AT3 RIFF headers have a "skip samples at the beginning" value that the decoder should use, - * and absolute loop values. However the SGDX header loop values assume those samples are skipped. + * and absolute loop values. However the SGXD header loop values assume those samples are skipped. * * FFmpeg doesn't support/export this, so we have to manually get the absolute values to fix looping. */ diff --git a/src/meta/sqex_scd.c b/src/meta/sqex_scd.c index a4c436e5..2d849e57 100644 --- a/src/meta/sqex_scd.c +++ b/src/meta/sqex_scd.c @@ -109,7 +109,8 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) { /* 0x1c: unknown (0x0) */ headers_entries = read_16bit(tables_offset+0x04,streamFile); if (target_stream == 0) target_stream = 1; /* auto: default to 1 */ - if (headers_entries <= 0 || target_stream > headers_entries) goto fail; + if (target_stream < 0 || target_stream > headers_entries || headers_entries < 1) goto fail; + headers_offset = read_32bit(tables_offset+0x0c,streamFile); /** header table entries (each is an uint32_t offset to stream header) **/ @@ -349,7 +350,7 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) { break; #ifdef VGM_USE_FFMPEG case 0xB: - /* XMA1/XMA2 */ /* Lightning Returns SFX, FFXIII (X360) */ + /* XMA2 */ /* Lightning Returns SFX, FFXIII (X360) */ { ffmpeg_codec_data *ffmpeg_data = NULL; uint8_t buf[200]; @@ -357,7 +358,7 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) { /* 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); + bytes = ffmpeg_make_riff_xma_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); diff --git a/src/meta/ps3_vawx.c b/src/meta/vawx.c similarity index 100% rename from src/meta/ps3_vawx.c rename to src/meta/vawx.c diff --git a/src/meta/x360_ast.c b/src/meta/x360_ast.c new file mode 100644 index 00000000..b9d060f4 --- /dev/null +++ b/src/meta/x360_ast.c @@ -0,0 +1,91 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* ASTB - found in Dead Rising (X360) */ +VGMSTREAM * init_vgmstream_x360_ast(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset, data_size; + int loop_flag, channel_count; + int i, xma_streams; + + /* check extension, case insensitive */ + if ( !check_extensions(streamFile,"ast")) + goto fail; + + if (read_32bitBE(0x00,streamFile) != 0x41535442) /* "ASTB" */ + goto fail; + + if (read_32bitBE(0x04,streamFile) != get_streamfile_size(streamFile)) goto fail; + if (read_16bitBE(0x30,streamFile) != 0x165) goto fail; /* only seen XMA1 */ + + xma_streams = read_16bitBE(0x38,streamFile); + + loop_flag = read_8bit(0x3a,streamFile); + channel_count = 0; /* sum of all stream channels (though only 1/2ch ever seen) */ + for (i = 0; i < xma_streams; i++) { + channel_count += read_8bit(0x3c + 0x14*i + 0x11,streamFile); + } + + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + start_offset = read_32bitBE(0x10,streamFile); + data_size = read_32bitBE(0x20,streamFile); + + vgmstream->sample_rate = read_32bitBE(0x40,streamFile); + vgmstream->meta_type = meta_X360_AST; + +#ifdef VGM_USE_FFMPEG + { + /* manually find sample offsets (XMA1 nonsense again) */ + xma_sample_data xma_sd; + memset(&xma_sd,0,sizeof(xma_sample_data)); + + xma_sd.xma_version = 1; + xma_sd.channels = channel_count; + xma_sd.data_offset = start_offset; + xma_sd.data_size = data_size; + xma_sd.loop_flag = loop_flag; + xma_sd.loop_start_b = read_32bitBE(0x44,streamFile); + xma_sd.loop_end_b = read_32bitBE(0x48,streamFile); + xma_sd.loop_start_subframe = read_8bit(0x4c,streamFile) & 0xF; /* lower 4b: subframe where the loop starts, 0..4 */ + xma_sd.loop_end_subframe = read_8bit(0x4c,streamFile) >> 4; /* upper 4b: subframe where the loop ends, 0..3 */ + + xma_get_samples(&xma_sd, streamFile); + vgmstream->num_samples = xma_sd.num_samples; + vgmstream->loop_start_sample = xma_sd.loop_start_sample; + vgmstream->loop_end_sample = xma_sd.loop_end_sample; + //skip_samples = xma_sd.skip_samples; //todo add skip samples + } + + { + uint8_t buf[100]; + size_t bytes; + + off_t fmt_offset = 0x30; + size_t fmt_size = 0x0c + xma_streams * 0x14; + + /* XMA1 "fmt" chunk @ 0x20 (BE, unlike the usual LE) */ + bytes = ffmpeg_make_riff_xma_from_fmt(buf,100, fmt_offset,fmt_size, data_size, streamFile, 1); + if (bytes <= 0) goto fail; + + vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size); + if ( !vgmstream->codec_data ) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + } +#else + goto fail; +#endif + + /* open the file for reading */ + if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/x360.c b/src/meta/x360_cxs.c similarity index 100% rename from src/meta/x360.c rename to src/meta/x360_cxs.c diff --git a/src/meta/xma.c b/src/meta/xma.c index f1ffe58e..cdeb1c08 100644 --- a/src/meta/xma.c +++ b/src/meta/xma.c @@ -33,6 +33,8 @@ typedef struct { int32_t loop_start_b; int32_t loop_end_b; int32_t loop_subframe; + + meta_t meta; } xma_header_data; static int parse_header(xma_header_data * xma, STREAMFILE *streamFile); @@ -83,7 +85,7 @@ VGMSTREAM * init_vgmstream_xma(STREAMFILE *streamFile) { vgmstream->codec_data = data; vgmstream->coding_type = coding_FFmpeg; vgmstream->layout_type = layout_none; - vgmstream->meta_type = meta_FFmpeg; + vgmstream->meta_type = xma.meta; vgmstream->sample_rate = data->sampleRate; @@ -166,11 +168,12 @@ static int parse_header(xma_header_data * xma, STREAMFILE *streamFile) { xma->file_size = streamFile->get_size(streamFile); /* find offsets */ - if (id == id_RIFF || id == id_RIFX) { /* regular RIFF header */ + if (id == id_RIFF || id == id_RIFX) { /* regular RIFF header / RIFX (BE, wwsize?) */ off_t current_chunk = 0xc; off_t fmt_offset = 0, xma2_offset = 0; size_t riff_size = 0, fmt_size = 0, xma2_size = 0; + xma->meta = meta_XMA_RIFF; riff_size = read_32bit(4,streamFile); if (riff_size != xma->file_size && /* some Beautiful Katamari, unsure if bad rip */ riff_size+8 > xma->file_size) goto fail; @@ -223,9 +226,12 @@ static int parse_header(xma_header_data * xma, STREAMFILE *streamFile) { goto fail; } } - else if (id == id_NXMA) { /* Namco (Tekken 6, Galaga Legions DX) */ - /* custom header with a "XMA2" or "fmt " data chunk inside, most other values are unknown */ + else if (id == id_NXMA) { /* Namco NUB xma (Tekken 6, Galaga Legions DX) */ + /* Custom header with a "XMA2" or "fmt " data chunk inside; most other values are unknown + * It's here rather than its own meta to reuse the chunk parsing (probably intended to be .nub) */ uint32_t chunk_type = read_32bit(0xC,streamFile); + + xma->meta = meta_NUB_XMA; xma->data_offset = 0x100; xma->data_size = read_32bit(0x14,streamFile); xma->chunk_offset = 0xBC; @@ -243,7 +249,10 @@ static int parse_header(xma_header_data * xma, STREAMFILE *streamFile) { if (xma->data_size + xma->data_offset > xma->file_size) goto fail; } else if (id == id_PASX) { /* SoulCalibur II HD */ - /* custom header with a "fmt " data chunk inside */ + /* Custom header with a "fmt " data chunk inside + * It's here rather than its own meta to reuse the chunk parsing */ + + xma->meta = meta_X360_PASX; xma->chunk_size = read_32bit(0x08,streamFile); xma->data_size = read_32bit(0x0c,streamFile); xma->chunk_offset = read_32bit(0x10,streamFile); @@ -376,7 +385,7 @@ static int create_riff_header(uint8_t * buf, size_t buf_size, xma_header_data * internal_size = 4+4+xma->chunk_size; if (xma->force_little_endian ) { - if ( !ffmpeg_fmt_chunk_swap_endian(chunk, xma->fmt_codec) ) + if ( !ffmpeg_fmt_chunk_swap_endian(chunk, xma->chunk_size, xma->fmt_codec) ) goto fail; } diff --git a/src/meta/xwb.c b/src/meta/xwb.c index 0da9807e..5565a033 100644 --- a/src/meta/xwb.c +++ b/src/meta/xwb.c @@ -15,7 +15,7 @@ static const int32_t wma_block_align_index[] = { /*17*/ }; -typedef enum { PCM, XBOX_ADPCM, MS_ADPCM, XMA1, XMA2, WMA, XWMA } xact_codec; +typedef enum { PCM, XBOX_ADPCM, MS_ADPCM, XMA1, XMA2, WMA, XWMA, ATRAC3 } xact_codec; typedef struct { int little_endian; int xact; /* rough XACT version (1/2/3) */ @@ -103,8 +103,11 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { //0x14: XACT1: none (ENTRYWAVEDATA), XACT2: EXTRA, XACT3: ENTRYNAMES suboff = xwb.xact >= 2 ? 0x08+0x08 : 0x08; xwb.data_offset = read_32bit(off+0x10+suboff, streamFile);//ENTRYWAVEDATA - xwb.data_size = read_32bit(off+0x10+suboff, streamFile); + xwb.data_size = read_32bit(off+0x14+suboff, streamFile); + /* for Silent Hill 4 Xbox fake XWB and Techland's XWB with no data */ + if (xwb.base_offset == 0) goto fail; + if (xwb.data_offset + xwb.data_size != get_streamfile_size(streamFile)) goto fail; /* read base entry (WAVEBANKDATA) */ off = xwb.base_offset; @@ -119,7 +122,7 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { /* suboff+0x10: build time 64b (XACT2/3) */ if (target_stream == 0) target_stream = 1; /* auto: default to 1 */ - if (xwb.streams < 1 || target_stream > xwb.streams) goto fail; + if (target_stream < 0 || target_stream > xwb.streams || xwb.streams < 1) goto fail; /* read stream entry (WAVEBANKENTRY) */ @@ -215,6 +218,17 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { } } + /* Techland's bizarre format hijack (Nail'd, Sniper: Ghost Warrior PS3). + * Somehow they used XWB + ATRAC3 in their PS3 games, very creative */ + if (xwb.version == 0x10000 && xwb.codec == XMA2 /* v 0x10000 is used in their X360 games too */ + && (xwb.block_align == 0x60 || xwb.block_align == 0x98 || xwb.block_align == 0xc0) ) { + xwb.codec = ATRAC3; /* standard ATRAC3 blocks sizes; no other way to identify (other than reading data) */ + + /* num samples uses a modified entry_info format (maybe skip samples + samples? sfx use the standard format) + * ignore for now and just calc max samples */ //todo + xwb.num_samples = xwb.stream_size / (xwb.block_align * xwb.channels) * 1024; + } + /* fix samples */ if ((xwb.xact == 1 || xwb.xact == 2) && xwb.codec == PCM) { @@ -241,6 +255,7 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { } else if (xwb.xact == 2 && xwb.version <= 38 /* v38: byte offset, v40+: sample offset, v39: ? */ && (xwb.codec == XMA1 || xwb.codec == XMA2) && xwb.loop_flag) { +#ifdef VGM_USE_FFMPEG /* need to manually find sample offsets, thanks to Microsoft dumb headers */ xma_sample_data xma_sd; memset(&xma_sd,0,sizeof(xma_sample_data)); @@ -268,6 +283,9 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { //add padding back until it's fixed (affects looping) // (in rare cases this causes a glitch in FFmpeg since it has a bug where it's missing some samples) xwb.num_samples += 64 + 512; +#else + goto fail; +#endif } @@ -372,6 +390,24 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { vgmstream->layout_type = layout_none; break; } + + case ATRAC3: { /* Techland extension */ + uint8_t buf[200]; + int bytes; + + int block_size = xwb.block_align * vgmstream->channels; + int joint_stereo = xwb.block_align == 0x60; /* untested, ATRAC3 default */ + int skip_samples = 0; /* unknown */ + + bytes = ffmpeg_make_riff_atrac3(buf, 200, vgmstream->num_samples, xwb.stream_size, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, skip_samples); + if (bytes <= 0) goto fail; + + vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, xwb.stream_offset,xwb.stream_size); + if ( !vgmstream->codec_data ) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + break; + } #endif default: diff --git a/src/vgmstream.c b/src/vgmstream.c index 21bf9dda..9d4af2db 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -298,7 +298,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = { init_vgmstream_ps3_msf, init_vgmstream_nub_vag, init_vgmstream_ps3_past, - init_vgmstream_ps3_sgdx, + init_vgmstream_sgxd, init_vgmstream_ngca, init_vgmstream_wii_ras, init_vgmstream_ps2_spm, @@ -340,6 +340,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = { init_vgmstream_dsp_adx, init_vgmstream_akb_multi, init_vgmstream_akb2_multi, + init_vgmstream_x360_ast, #ifdef VGM_USE_FFMPEG init_vgmstream_xma, @@ -384,8 +385,10 @@ VGMSTREAM * init_vgmstream_internal(STREAMFILE *streamFile, int do_dfs) { if (vgmstream->loop_flag) { if ((vgmstream->loop_end_sample <= vgmstream->loop_start_sample) || (vgmstream->loop_end_sample > vgmstream->num_samples) - || (vgmstream->loop_start_sample < 0) ) + || (vgmstream->loop_start_sample < 0) ) { vgmstream->loop_flag = 0; + VGM_LOG("VGMSTREAM: wrong loops ignored (lss==%i, lse=%i, ns=%i)\n", vgmstream->loop_start_sample, vgmstream->loop_end_sample, vgmstream->num_samples); + } } /* dual file stereo */ diff --git a/src/vgmstream.h b/src/vgmstream.h index 91696ce8..e2f6502a 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -336,7 +336,7 @@ typedef enum { meta_FSB4, /* FMOD Sample Bank, version 4 */ meta_FSB5, /* FMOD Sample Bank, version 5 */ meta_RWX, /* Air Force Delta Storm (XBOX) */ - meta_XWB, /* King of Fighters (XBOX) */ + meta_XWB, /* Microsoft XACT framework (Xbox, X360, Windows) */ meta_XA30, /* Driver - Parallel Lines (PS2) */ meta_MUSC, /* Spyro Games, possibly more */ meta_MUSX_V004, /* Spyro Games, possibly more */ @@ -549,9 +549,9 @@ typedef enum { meta_PS3_XVAG, /* Ratchet & Clank Future: Quest for Booty (PS3) */ meta_PS3_CPS, /* Eternal Sonata (PS3) */ meta_PS3_MSF, /* MSF header */ - meta_NUB_VAG, /* VAG from Nub archives */ + meta_NUB_VAG, /* Namco VAG from NUB archives */ meta_PS3_PAST, /* Bakugan Battle Brawlers (PS3) */ - meta_PS3_SGDX, /* Folklore, Genji, Tokyo Jungle (PS3), Brave Story, Kurohyo (PSP) */ + meta_SGXD, /* Sony: Folklore, Genji, Tokyo Jungle (PS3), Brave Story, Kurohyo (PSP) */ meta_NGCA, /* GoldenEye 007 (Wii) */ meta_WII_RAS, /* Donkey Kong Country Returns (Wii) */ meta_PS2_SPM, /* Lethal Skies Elite Pilot: Team SW */ @@ -593,6 +593,10 @@ typedef enum { meta_PS2_VDS_VDM, /* Graffiti Kingdom */ meta_X360_CXS, /* Eternal Sonata (Xbox 360) */ meta_AKB, /* SQEX iOS */ + meta_NUB_XMA, /* Namco XMA from NUB archives */ + meta_X360_PASX, /* Namco PASX (Soul Calibur II HD X360) */ + meta_XMA_RIFF, /* Microsoft RIFF XMA */ + meta_X360_AST, /* Dead Rising (X360) */ #ifdef VGM_USE_VORBIS meta_OGG_VORBIS, /* Ogg Vorbis */