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 */