VGMStream: Updated libvgmstream code base

Updated VGMStream to r2023-16-gb2fc214a

Signed-off-by: Christopher Snowhill <kode54@gmail.com>
This commit is contained in:
Christopher Snowhill 2025-06-06 00:51:03 -07:00
parent bc8538cdd4
commit 7fe95980d7
33 changed files with 471 additions and 451 deletions

View file

@ -518,7 +518,6 @@
836F6F9818BDC2190095E648 /* mattel_hyperscan.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E5C18BDC2180095E648 /* mattel_hyperscan.c */; };
836F6F9918BDC2190095E648 /* maxis_xa.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E5D18BDC2180095E648 /* maxis_xa.c */; };
836F6F9A18BDC2190095E648 /* meta.h in Headers */ = {isa = PBXBuildFile; fileRef = 836F6E5E18BDC2180095E648 /* meta.h */; };
836F6F9B18BDC2190095E648 /* mn_str.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E5F18BDC2180095E648 /* mn_str.c */; };
836F6F9C18BDC2190095E648 /* mp4.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6018BDC2180095E648 /* mp4.c */; };
836F6F9E18BDC2190095E648 /* mus_acm.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6218BDC2180095E648 /* mus_acm.c */; };
836F6F9F18BDC2190095E648 /* musc.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6E6318BDC2180095E648 /* musc.c */; };
@ -623,7 +622,6 @@
836F704F18BDC2190095E648 /* xwb.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F1318BDC2190095E648 /* xwb.c */; };
836F705018BDC2190095E648 /* ydsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F1418BDC2190095E648 /* ydsp.c */; };
836F705118BDC2190095E648 /* zsd.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F1518BDC2190095E648 /* zsd.c */; };
836F705218BDC2190095E648 /* zwdsp.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F1618BDC2190095E648 /* zwdsp.c */; };
836F705318BDC2190095E648 /* streamfile.c in Sources */ = {isa = PBXBuildFile; fileRef = 836F6F1718BDC2190095E648 /* streamfile.c */; };
836F705418BDC2190095E648 /* streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 836F6F1818BDC2190095E648 /* streamfile.h */; settings = {ATTRIBUTES = (Public, ); }; };
836F705518BDC2190095E648 /* streamtypes.h in Headers */ = {isa = PBXBuildFile; fileRef = 836F6F1918BDC2190095E648 /* streamtypes.h */; settings = {ATTRIBUTES = (Public, ); }; };
@ -779,6 +777,10 @@
83B8FE2F2D5AB2F4005854C1 /* xwb_konami.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B8FE2E2D5AB2F4005854C1 /* xwb_konami.c */; };
83B8FE312D5AB421005854C1 /* undefind.c in Sources */ = {isa = PBXBuildFile; fileRef = 83B8FE302D5AB421005854C1 /* undefind.c */; };
83BAFB6C19F45EB3005DAB60 /* bfstm.c in Sources */ = {isa = PBXBuildFile; fileRef = 83BAFB6B19F45EB3005DAB60 /* bfstm.c */; };
83BB84012DF2D049002077FC /* swar.c in Sources */ = {isa = PBXBuildFile; fileRef = 83BB84002DF2D049002077FC /* swar.c */; };
83BB84032DF2D125002077FC /* rwar.c in Sources */ = {isa = PBXBuildFile; fileRef = 83BB84022DF2D125002077FC /* rwar.c */; };
83BB84062DF2D1C2002077FC /* ivb.c in Sources */ = {isa = PBXBuildFile; fileRef = 83BB84042DF2D1C2002077FC /* ivb.c */; };
83BB84072DF2D1C2002077FC /* ivb_streamfile.h in Headers */ = {isa = PBXBuildFile; fileRef = 83BB84052DF2D1C2002077FC /* ivb_streamfile.h */; };
83C0C75D2AA435C60056AFD8 /* squeak.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C0C75C2AA435C60056AFD8 /* squeak.c */; };
83C0C7602AA436370056AFD8 /* layout_utils.c in Sources */ = {isa = PBXBuildFile; fileRef = 83C0C75E2AA436370056AFD8 /* layout_utils.c */; };
83C0C7612AA436370056AFD8 /* layout_utils.h in Headers */ = {isa = PBXBuildFile; fileRef = 83C0C75F2AA436370056AFD8 /* layout_utils.h */; };
@ -1475,7 +1477,6 @@
836F6E5C18BDC2180095E648 /* mattel_hyperscan.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mattel_hyperscan.c; sourceTree = "<group>"; };
836F6E5D18BDC2180095E648 /* maxis_xa.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = maxis_xa.c; sourceTree = "<group>"; };
836F6E5E18BDC2180095E648 /* meta.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = meta.h; sourceTree = "<group>"; };
836F6E5F18BDC2180095E648 /* mn_str.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mn_str.c; sourceTree = "<group>"; };
836F6E6018BDC2180095E648 /* mp4.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mp4.c; sourceTree = "<group>"; };
836F6E6218BDC2180095E648 /* mus_acm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = mus_acm.c; sourceTree = "<group>"; };
836F6E6318BDC2180095E648 /* musc.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = musc.c; sourceTree = "<group>"; };
@ -1580,7 +1581,6 @@
836F6F1318BDC2190095E648 /* xwb.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = xwb.c; sourceTree = "<group>"; };
836F6F1418BDC2190095E648 /* ydsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = ydsp.c; sourceTree = "<group>"; };
836F6F1518BDC2190095E648 /* zsd.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zsd.c; sourceTree = "<group>"; };
836F6F1618BDC2190095E648 /* zwdsp.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = zwdsp.c; sourceTree = "<group>"; };
836F6F1718BDC2190095E648 /* streamfile.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = streamfile.c; sourceTree = "<group>"; };
836F6F1818BDC2190095E648 /* streamfile.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = streamfile.h; sourceTree = "<group>"; };
836F6F1918BDC2190095E648 /* streamtypes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = streamtypes.h; sourceTree = "<group>"; };
@ -1738,6 +1738,10 @@
83B8FE2E2D5AB2F4005854C1 /* xwb_konami.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = xwb_konami.c; sourceTree = "<group>"; };
83B8FE302D5AB421005854C1 /* undefind.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = undefind.c; sourceTree = "<group>"; };
83BAFB6B19F45EB3005DAB60 /* bfstm.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = bfstm.c; sourceTree = "<group>"; };
83BB84002DF2D049002077FC /* swar.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = swar.c; sourceTree = "<group>"; };
83BB84022DF2D125002077FC /* rwar.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = rwar.c; sourceTree = "<group>"; };
83BB84042DF2D1C2002077FC /* ivb.c */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.c; path = ivb.c; sourceTree = "<group>"; };
83BB84052DF2D1C2002077FC /* ivb_streamfile.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = ivb_streamfile.h; sourceTree = "<group>"; };
83C0C75C2AA435C60056AFD8 /* squeak.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = squeak.c; sourceTree = "<group>"; };
83C0C75E2AA436370056AFD8 /* layout_utils.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = layout_utils.c; sourceTree = "<group>"; };
83C0C75F2AA436370056AFD8 /* layout_utils.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = layout_utils.h; sourceTree = "<group>"; };
@ -2481,6 +2485,8 @@
83AFABBB23795202002F3947 /* isb.c */,
836F6E5618BDC2180095E648 /* ish_isd.c */,
83269DD12399F5DE00F49FE3 /* ivag.c */,
83BB84042DF2D1C2002077FC /* ivb.c */,
83BB84052DF2D1C2002077FC /* ivb_streamfile.h */,
837CEAEF23487F2C00E62A4A /* jstm.c */,
837CEAE923487F2B00E62A4A /* jstm_streamfile.h */,
83CBF5382D4630B400AA2D75 /* ka1a.c */,
@ -2514,7 +2520,6 @@
836F6EAC18BDC2180095E648 /* mic_koei.c */,
83B73C4A2D8FF19800A57F08 /* mio.c */,
8346D97725BF838C00D1A8B0 /* mjb_mjh.c */,
836F6E5F18BDC2180095E648 /* mn_str.c */,
8349A9031FE6258100E26435 /* mogg.c */,
836F6E6018BDC2180095E648 /* mp4.c */,
839FBFF926C354E70016A78A /* mp4_faac.c */,
@ -2623,6 +2628,7 @@
836F6EE518BDC2190095E648 /* rs03.c */,
836F6EE618BDC2190095E648 /* rsd.c */,
83FBB1772A4FF71B00CD0580 /* rstm_rockstar.c */,
83BB84022DF2D125002077FC /* rwar.c */,
836F6EE918BDC2190095E648 /* rwax.c */,
836F6EB818BDC2180095E648 /* rws_80d.c */,
83FBB1762A4FF71B00CD0580 /* rws_809.c */,
@ -2696,6 +2702,7 @@
83AA7F7B2519C042004C5298 /* svag_snk.c */,
834FE0D7215C79EA000A5D3D /* svgp.c */,
836F6EF918BDC2190095E648 /* svs.c */,
83BB84002DF2D049002077FC /* swar.c */,
83D0381724A4129A004CF90F /* swav.c */,
83E7FD6425EF2B2400683FD2 /* tac.c */,
8373342E23F60D4100DE14DC /* tgc.c */,
@ -2799,7 +2806,6 @@
836F6F1518BDC2190095E648 /* zsd.c */,
832BF80F21E05149006F50F1 /* zsnd.c */,
832BF80E21E05149006F50F1 /* zsnd_streamfile.h */,
836F6F1618BDC2190095E648 /* zwdsp.c */,
83AA7F7C2519C042004C5298 /* zwv.c */,
);
path = meta;
@ -2975,6 +2981,7 @@
834F7DDE2C7093EA003AC386 /* mpeg_decoder.h in Headers */,
83031EDB243C510500C3F3E0 /* xnb_lz4mg.h in Headers */,
836F705418BDC2190095E648 /* streamfile.h in Headers */,
83BB84072DF2D1C2002077FC /* ivb_streamfile.h in Headers */,
834F7DB12C7093EA003AC386 /* circus_vq_lzxpcm.h in Headers */,
835B9B922730BF2D00F87EE3 /* hca_bf.h in Headers */,
836DF623298F83F400CD0580 /* bitstream_msb.h in Headers */,
@ -3223,6 +3230,7 @@
8306B0AF20984552000302D4 /* blocked_rws.c in Sources */,
83C7281A22BC893D00678B4A /* mus_vc.c in Sources */,
835559FC2869102B005FE93A /* sndz.c in Sources */,
83BB84032DF2D125002077FC /* rwar.c in Sources */,
839E21EB1F2EDB0600EE54D7 /* sk_aud.c in Sources */,
834FE0F1215C79ED000A5D3D /* a2m.c in Sources */,
8301659A1F256BD000CA0941 /* txth.c in Sources */,
@ -3272,7 +3280,6 @@
83997F5B22D9569E00633184 /* rad.c in Sources */,
834F7DED2C7093EA003AC386 /* psv_decoder.c in Sources */,
837CEAF423487F2C00E62A4A /* xa_xa30.c in Sources */,
836F6F9B18BDC2190095E648 /* mn_str.c in Sources */,
832BF82821E0514B006F50F1 /* xwma.c in Sources */,
83FC176E23AC58D100E1025F /* csb.c in Sources */,
836F46B32820874D005B9B87 /* esf.c in Sources */,
@ -3399,6 +3406,7 @@
836F703618BDC2190095E648 /* thp.c in Sources */,
834F7DFB2C7093EA003AC386 /* tac_decoder.c in Sources */,
836F6F7818BDC2190095E648 /* cstr.c in Sources */,
83BB84012DF2D049002077FC /* swar.c in Sources */,
83F1EE30245D4FC10076E182 /* imuse.c in Sources */,
833E82F02A28587D00CD0580 /* companion_files.c in Sources */,
834F7E072C7093EA003AC386 /* vorbis_custom_utils_sk.c in Sources */,
@ -3542,7 +3550,6 @@
836F6FD518BDC2190095E648 /* lp_ap_lep.c in Sources */,
8306B0DC20984590000302D4 /* sthd.c in Sources */,
836F6FAE18BDC2190095E648 /* mpds.c in Sources */,
836F705218BDC2190095E648 /* zwdsp.c in Sources */,
83FBB1722A4FF4EC00CD0580 /* ego_dic.c in Sources */,
836F6FFB18BDC2190095E648 /* ps2_sps.c in Sources */,
834F7DE12C7093EA003AC386 /* mtaf_decoder.c in Sources */,
@ -3689,6 +3696,7 @@
83031ECD243C50CC00C3F3E0 /* blocked_vid1.c in Sources */,
836F700B18BDC2190095E648 /* ps2_wad.c in Sources */,
8349A9161FE6258200E26435 /* flx.c in Sources */,
83BB84062DF2D1C2002077FC /* ivb.c in Sources */,
832BF82921E0514B006F50F1 /* msf_banpresto.c in Sources */,
834FE0BE215C79A9000A5D3D /* blocked_xa_aiff.c in Sources */,
835B9B902730BF2D00F87EE3 /* ast_mmv.c in Sources */,

View file

@ -345,7 +345,7 @@ int render_main(sbuf_t* sbuf, VGMSTREAM* vgmstream) {
return sbuf->filled;
}
int render_vgmstream(sample_t* buf, int32_t sample_count, VGMSTREAM* vgmstream) {
int render_vgmstream2(sample_t* buf, int32_t sample_count, VGMSTREAM* vgmstream) {
sbuf_t sbuf = {0};
sbuf_init_s16(&sbuf, buf, sample_count, vgmstream->channels);

View file

@ -62,7 +62,7 @@ void* init_atrac9(atrac9_config* cfg) {
if (!data->buf) goto fail;
// while ATRAC9 uses float internally, Sony's API only returns PCM16
data->sbuf = calloc(data->info.channels * data->info.frameSamples * data->info.framesInSuperframe, sizeof(sample_t));
data->sbuf = calloc(data->info.channels * data->info.frameSamples * data->info.framesInSuperframe, sizeof(int16_t));
if (!data->sbuf) goto fail;
data->discard = cfg->encoder_delay;

View file

@ -22,7 +22,7 @@ static int ffmpeg_make_riff_atrac3(uint8_t* buf, size_t buf_size, size_t sample_
put_u16le(buf+0x14, 0x0270); /* ATRAC3 codec */
put_u16le(buf+0x16, channels);
put_u32le(buf+0x18, sample_rate);
put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample_t)); /* average bytes per second (wrong) */
put_u32le(buf+0x1c, sample_rate * channels / sizeof(int16_t)); /* average bytes per second (wrong) */
put_u16le(buf+0x20, block_align); /* block align */
put_u16le(buf+0x24, 0x0e); /* extra data size */
@ -230,7 +230,7 @@ static int ffmpeg_make_riff_atrac3plus(uint8_t* buf, int buf_size, uint32_t data
put_u16le(buf+0x14, 0xfffe); /* WAVEFORMATEXTENSIBLE */
put_u16le(buf+0x16, channels);
put_u32le(buf+0x18, sample_rate);
put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample_t)); /* average bytes per second (wrong) */
put_u32le(buf+0x1c, sample_rate * channels / sizeof(int16_t)); /* average bytes per second (wrong) */
put_u32le(buf+0x20, block_align); /* block align */
put_u16le(buf+0x24, 0x22); /* extra data size */
@ -432,7 +432,7 @@ static int ffmpeg_make_riff_xma1(uint8_t* buf, size_t buf_size, size_t data_size
}
}
put_u32le(buf+off+0x00, sample_rate*stream_channels / sizeof(sample_t)); /* average bytes per second (wrong, unneeded) */
put_u32le(buf+off+0x00, sample_rate*stream_channels / sizeof(int16_t)); /* average bytes per second (wrong, unneeded) */
put_u32le(buf+off+0x04, sample_rate);
put_u32le(buf+off+0x08, 0); /* loop start */
put_u32le(buf+off+0x0c, 0); /* loop end */
@ -492,7 +492,7 @@ static int ffmpeg_make_riff_xma2(uint8_t* buf, size_t buf_size, size_t data_size
default: speakers = 0; break;
}
bytecount = sample_count * channels * sizeof(sample_t);
bytecount = sample_count * channels * sizeof(int16_t);
memcpy (buf+0x00, "RIFF", 0x04);
put_u32le(buf+0x04, buf_max - (0x04 * 2) + data_size); /* riff size */
@ -503,8 +503,8 @@ static int ffmpeg_make_riff_xma2(uint8_t* buf, size_t buf_size, size_t data_size
put_u16le(buf+0x14, 0x0166); /* XMA2 */
put_u16le(buf+0x16, channels);
put_u32le(buf+0x18, sample_rate);
put_u32le(buf+0x1c, sample_rate * channels / sizeof(sample_t)); /* average bytes per second (wrong, unneeded) */
put_u16le(buf+0x20, (uint16_t)(channels * sizeof(sample_t))); /* block align */
put_u32le(buf+0x1c, sample_rate * channels / sizeof(int16_t)); /* average bytes per second (wrong, unneeded) */
put_u16le(buf+0x20, (uint16_t)(channels * sizeof(int16_t))); /* block align */
put_u16le(buf+0x22, 16); /* bits per sample */
put_u16le(buf+0x24, 0x22); /* extra data size */

View file

@ -480,10 +480,10 @@ static int decode_vima_comp(imuse_codec_data* data, block_entry_t* entry) {
VGM_LOG("IMUSE: found PCM block %i\n", data->current_block);
/* presumably PCM data (not seen) */
for (int i = 0, j = pos; i < copy_size / sizeof(sample_t); i++, j += 2) {
for (int i = 0, j = pos; i < copy_size / sizeof(int16_t); i++, j += 2) {
data->pbuf[i] = get_s16le(data->block + j);
}
filled += copy_size / chs / sizeof(sample_t);
filled += copy_size / chs / sizeof(int16_t);
pos += copy_size;
data_left -= copy_size;

View file

@ -352,7 +352,6 @@ static const char* extension_list[] = {
"mib",
"mic",
"mio",
"mnstr",
"mogg",
//"m4a", //common
//"m4v", //common
@ -580,6 +579,7 @@ static const char* extension_list[] = {
"svs",
"svg",
"swag",
"swar",
"swav",
"swd",
"switch", //txth/reserved (.m4a-x.switch) [Ikinari Maou (Switch)]
@ -728,7 +728,6 @@ static const char* extension_list[] = {
"zsd",
"zsm",
"zss",
"zwdsp",
"zwv",
"vgmstream" /* fake extension, catch-all for FFmpeg/txth/etc */
@ -833,10 +832,10 @@ static const coding_info coding_info_list[] = {
{coding_XA, "CD-ROM XA 4-bit ADPCM"},
{coding_XA8, "CD-ROM XA 8-bit ADPCM"},
{coding_XA_EA, "Electronic Arts XA 4-bit ADPCM"},
{coding_PSX, "Playstation 4-bit ADPCM"},
{coding_PSX_badflags, "Playstation 4-bit ADPCM (bad flags)"},
{coding_PSX_cfg, "Playstation 4-bit ADPCM (configurable)"},
{coding_PSX_pivotal, "Playstation 4-bit ADPCM (Pivotal)"},
{coding_PSX, "PlayStation 4-bit ADPCM"},
{coding_PSX_badflags, "PlayStation 4-bit ADPCM (bad flags)"},
{coding_PSX_cfg, "PlayStation 4-bit ADPCM (configurable)"},
{coding_PSX_pivotal, "PlayStation 4-bit ADPCM (Pivotal)"},
{coding_HEVAG, "Sony HEVAG 4-bit ADPCM"},
{coding_EA_XA, "Electronic Arts EA-XA 4-bit ADPCM v1"},
@ -1158,7 +1157,6 @@ static const meta_info meta_info_list[] = {
{meta_SEG, "Stormfront SEG header"},
{meta_RIFF_IMA, "Square Enix RIFF IMA eader"},
{meta_KNON, "Paon KNON header"},
{meta_ZWDSP, "Zack and Wiki custom DSP Header"},
{meta_GCA, "GCA DSP Header"},
{meta_SPT_SPD, "SPT+SPD DSP Header"},
{meta_ISH_ISD, "ISH+ISD DSP Header"},
@ -1264,7 +1262,6 @@ static const meta_info meta_info_list[] = {
{meta_MTAF, "Konami MTAF header"},
{meta_ALP, "High Voltage ALP header"},
{meta_WPD, "Navel WPD header"},
{meta_MN_STR, "Mini Ninjas 'STR' header"},
{meta_MCSS, "Guerilla MCSS header"},
{meta_PS2_HSF, "Lowrider 'HSF' header"},
{meta_IVAG, "Namco IVAG header"},
@ -1358,7 +1355,6 @@ static const meta_info meta_info_list[] = {
{meta_HD3_BD3, "Sony HD3+BD3 header"},
{meta_BNK_SONY, "Sony BNK header"},
{meta_SSCF, "Square Enix SSCF header"},
{meta_DSP_VAG, ".VAG DSP header"},
{meta_DSP_ITL, ".ITL DSP header"},
{meta_A2M, "Artificial Mind & Movement A2M header"},
{meta_AHV, "Amuze AHV header"},
@ -1481,6 +1477,8 @@ static const meta_info meta_info_list[] = {
{meta_OOR, "age .OOR header"},
{meta_MIO, "Entis .MIO header"},
{meta_AUDIOPKG, "Inevitable .AUDIOPKG header"},
{meta_SWAR, "Nintendo SWAR header"},
{meta_IVB, "Metro IVB header"},
};
void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) {

View file

@ -64,7 +64,7 @@
LIBVGMSTREAM_API uint32_t libvgmstream_get_version(void);
/* CHANGELOG:
* - 1.0.0: beta version
* - 1.0.0: initial version
*/

View file

@ -324,73 +324,3 @@ fail:
close_vgmstream(vgmstream);
return NULL;
}
/* ************************************************************************* */
/* RWAR - NintendoWare container [BIT.TRIP BEAT (Wii), Dance Dance Revolution Hottest Party 2 (Wii)] */
VGMSTREAM* init_vgmstream_brwar(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* temp_sf = NULL;
uint32_t tabl_offset, data_offset;
uint32_t subfile_offset, subfile_size;
int total_subsongs, target_subsong = sf->stream_index;
/* checks */
if (!is_id32be(0x00, sf, "RWAR"))
goto fail;
if (!check_extensions(sf,"rwar"))
goto fail;
/* simple container of .rwavs (inside .brsar), rarely used with single siles (DDR) */
/* abridged, see RWAV (same header) */
/* 0x04(2): BOM */
/* 0x06(2): version (usually 0100) */
/* 0x08: file size */
/* 0x0c(2): header size (0x20) */
/* 0x0e(2): sections (2) */
tabl_offset = read_u32be(0x10, sf);
/* 0x14: tabl size */
data_offset = read_u32be(0x18, sf);
/* 0x1c: data size */
/* TABL section */
if (!is_id32be(tabl_offset + 0x00, sf, "TABL"))
goto fail;
/* 0x04: size */
total_subsongs = read_u32be(tabl_offset + 0x08,sf);
if (target_subsong == 0) target_subsong = 1;
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
/* 0x00: always 0x01000000? */
subfile_offset = read_u32be(tabl_offset + 0x0c + (target_subsong-1) * 0x0c + 0x04,sf) + data_offset;
subfile_size = read_u32be(tabl_offset + 0x0c + (target_subsong-1) * 0x0c + 0x08,sf);
/* DATA section */
if (!is_id32be(data_offset + 0x00, sf, "DATA"))
goto fail;
/* 0x04: size */
//VGM_LOG("BRWAR: of=%x, sz=%x\n", subfile_offset, subfile_size);
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "rwav");
if (!temp_sf) goto fail;
vgmstream = init_vgmstream_brwav(temp_sf);
if (!vgmstream) goto fail;
vgmstream->num_streams = total_subsongs;
close_streamfile(temp_sf);
return vgmstream;
fail:
close_streamfile(temp_sf);
close_vgmstream(vgmstream);
return NULL;
}

View file

@ -3,7 +3,6 @@
#ifdef VGM_USE_FFMPEG
static int read_pos_file(uint8_t* buf, size_t bufsize, STREAMFILE* sf);
static int find_meta_loops(ffmpeg_codec_data* data, int32_t* p_loop_start, int32_t* p_loop_end);
/* parses any format supported by FFmpeg and not handled elsewhere:
@ -53,19 +52,6 @@ VGMSTREAM* init_vgmstream_ffmpeg(STREAMFILE* sf) {
total_subsongs = ffmpeg_get_subsong_count(data); /* uncommon, ex. wmv [Lost Odyssey (X360)] */
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
/* try to get .pos data */
{
uint8_t posbuf[0x04*3];
if (read_pos_file(posbuf, sizeof(posbuf), sf)) {
loop_start = get_s32le(posbuf+0x00);
loop_end = get_s32le(posbuf+0x04);
loop_flag = 1; /* incorrect looping will be validated outside */
/* FFmpeg can't always determine samples correctly so optionally load it (can be 0/NULL)
* won't crash and will output silence if no loop points and bigger than actual stream's samples */
num_samples = get_s32le(posbuf+8);
}
}
/* try to read Ogg/Flac loop tags (abridged) */
if (!loop_flag && (is_id32be(0x00, sf, "OggS") || is_id32be(0x00, sf, "fLaC"))) {
@ -160,45 +146,6 @@ fail:
}
/* open file containing looping data and copy to buffer, returns true if found and copied */
int read_pos_file(uint8_t* buf, size_t bufsize, STREAMFILE* sf) {
char posname[PATH_LIMIT];
char filename[PATH_LIMIT];
/*size_t bytes_read;*/
STREAMFILE* sf_pos = NULL;
get_streamfile_name(sf,filename,sizeof(filename));
if (strlen(filename)+4 > sizeof(posname))
goto fail;
/* try to open a posfile using variations: "(name.ext).pos" */
{
strcpy(posname, filename);
strcat(posname, ".pos");
sf_pos = open_streamfile(sf, posname);;
if (sf_pos) goto found;
goto fail;
}
found:
//if (get_streamfile_size(sf_pos) != bufsize) goto fail;
/* allow pos files to be of different sizes in case of new features, just fill all we can */
memset(buf, 0, bufsize);
read_streamfile(buf, 0, bufsize, sf_pos);
close_streamfile(sf_pos);
return 1;
fail:
close_streamfile(sf_pos);
return 0;
}
/* loop tag handling could be unified with ogg_vorbis.c, but that one has a extra features too.
* Also has support for flac meta loops, that can be used by stuff like Platformer Game Engine
* or ZDoom/Duke Nukem 3D source ports (maybe RPG Maker too). */

View file

@ -72,6 +72,7 @@ static const fsbkey_info fsbkey_list[] = {
{ MODE_FSB4, FSBKEY_ADD("dpdjeoqkr") }, // AirRider CrazyRacing (PC)
{ MODE_FSB5, FSBKEY_ADD("weareAbsolutelyUnsure2018") }, // Wanderstop (PC)
{ MODE_FSB5, FSBKEY_ADD(".xW3uXQ8q79yunvMjL6nahLXts9esEXX2VgetuPCxdLrAjUUbZAmB7R*A6KjW24NU_8ifMZ8TC4Qk@_oEsjsK2QLpAaG-Fy!wYKP") }, // UNBEATABLE Demo (PC)
{ MODE_FSB5, FSBKEY_ADD(",H9}:p?`bRlQG5_yJ\"\"/L,X_{:=Gs1") }, // Rennsport (PC)
/* some games use a key per file, generated from the filename
* (could add all of them but there are a lot of songs, so external .fsbkey are probably better) */

View file

@ -0,0 +1,59 @@
#include "meta.h"
#include "../util.h"
#include "../util/meta_utils.h"
#include "ivb_streamfile.h"
/* IVB - from Metro PS2 games [Bomberman Jetters (PS2), Dance Summit 2001: Bust A Move (PS2)] */
VGMSTREAM* init_vgmstream_ivb(STREAMFILE* sf) {
/* checks */
if (!is_id32be(0x00, sf, "IVB\0"))
return NULL;
if (!check_extensions(sf,"ivb"))
return NULL;
meta_header_t h = {0};
h.meta = meta_IVB;
// N stereo tracks, treat as subsongs instead of channels as both may have different total time
// and aren't meant to play at once, though data is padded so tracks have same size
h.total_subsongs = read_s32le(0x04, sf); // always 2 tracks
h.interleave = read_s32le(0x08, sf);
// 0c: null
// per track
// 00: channel size
// 04: channel blocks (may be less than channel size due to padding and different per track)
// 08: size of last block (1 channel)
// 0c: null
int target_subsong = sf->stream_index;
if (target_subsong == 0)
target_subsong = 1;
uint32_t head_offset = 0x10 + (target_subsong - 1) * 0x10;
//uint32_t chan_size = read_u32le(head_offset + 0x00, sf); //with padding
uint32_t chan_blocks = read_u32le(head_offset + 0x04, sf);
uint32_t last_size = read_u32le(head_offset + 0x08, sf); // last block without padding
h.channels = 2;
h.sample_rate = 44100;
h.has_subsongs = true;
h.coding = coding_PSX;
h.layout = layout_interleave;
h.stream_offset = 0x00;
h.stream_size = (chan_blocks - 1) * h.interleave * h.channels + last_size * h.channels;
h.num_samples = ps_bytes_to_samples(h.stream_size, h.channels);
h.sf = setup_ivb_streamfile(sf, 0x800, h.total_subsongs, target_subsong - 1, h.interleave * h.channels);
h.open_stream = true;
VGMSTREAM* v = alloc_metastream(&h);
close_streamfile(h.sf);
return v;
}

View file

@ -0,0 +1,21 @@
#ifndef _STR_WAV_STREAMFILE_H_
#define _STR_WAV_STREAMFILE_H_
#include "deblock_streamfile.h"
/* Deblocks streams */
static STREAMFILE* setup_ivb_streamfile(STREAMFILE* sf, uint32_t stream_start, int stream_count, int stream_number, uint32_t chunk_size) {
STREAMFILE* new_sf = NULL;
deblock_config_t cfg = {0};
cfg.stream_start = stream_start;
cfg.chunk_size = chunk_size;
cfg.step_start = stream_number;
cfg.step_count = stream_count;
/* setup sf */
new_sf = open_wrap_streamfile(sf);
new_sf = open_io_deblock_streamfile_f(new_sf, &cfg);
return new_sf;
}
#endif

View file

@ -57,7 +57,6 @@ VGMSTREAM* init_vgmstream_dsp_dspw(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_ngc_dsp_iadp(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_dsp_mcadpcm(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_dsp_switch_audio(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_dsp_sps_n1(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_dsp_itl_ch(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_dsp_adpy(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_dsp_adpx(STREAMFILE* sf);
@ -316,8 +315,6 @@ VGMSTREAM* init_vgmstream_riff_ima(STREAMFILE* sf);
VGMSTREAM * init_vgmstream_knon(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_zwdsp(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_gca(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_spt_spd(STREAMFILE * streamFile);
@ -504,8 +501,6 @@ VGMSTREAM* init_vgmstream_alp(STREAMFILE* sf);
VGMSTREAM * init_vgmstream_wpd(STREAMFILE* streamFile);
VGMSTREAM * init_vgmstream_mn_str(STREAMFILE* streamFile);
VGMSTREAM* init_vgmstream_mcss(STREAMFILE* sf);
VGMSTREAM * init_vgmstream_ps2_hsf(STREAMFILE* streamFile);
@ -527,7 +522,8 @@ VGMSTREAM * init_vgmstream_bfstm(STREAMFILE* streamFile);
VGMSTREAM* init_vgmstream_brwav(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_bfwav(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_bcwav(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_brwar(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_rwar(STREAMFILE* sf);
VGMSTREAM * init_vgmstream_kt_g1l(STREAMFILE* streamFile);
VGMSTREAM * init_vgmstream_kt_wiibgm(STREAMFILE* streamFile);
@ -1037,4 +1033,8 @@ VGMSTREAM* init_vgmstream_ssp(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_audiopkg(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_swar(STREAMFILE* sf);
VGMSTREAM* init_vgmstream_ivb(STREAMFILE* sf);
#endif

View file

@ -1,81 +0,0 @@
#include "meta.h"
#include "../util.h"
VGMSTREAM * init_vgmstream_mn_str(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT];
off_t start_offset;
int loop_flag = 0;
int channel_count;
int bitspersample;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("mnstr",filename_extension(filename))) goto fail;
loop_flag = 0;
channel_count = read_32bitLE(0x50,streamFile);
bitspersample = read_32bitLE(0x58,streamFile);
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
start_offset = read_32bitLE(0x20,streamFile)+0x48;
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitLE(0x54,streamFile);
switch (bitspersample) {
case 0x10:
vgmstream->coding_type = coding_PCM16LE;
if (channel_count == 1)
{
vgmstream->layout_type = layout_none;
}
else
{
vgmstream->interleave_block_size = 0x2;
vgmstream->layout_type = layout_interleave;
}
break;
case 0x4:
if (read_32bitLE(0x20,streamFile) == 0x24)
{
vgmstream->interleave_block_size = 0x800;
vgmstream->layout_type = layout_none;
}
break;
default:
goto fail;
}
vgmstream->num_samples = read_32bitLE(0x4C,streamFile);
//vgmstream->layout_type = layout_interleave;
//vgmstream->interleave_block_size = 0x2;
vgmstream->meta_type = meta_MN_STR;
/* open the file for reading */
{
int i;
STREAMFILE * file;
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!file) goto fail;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = file;
vgmstream->ch[i].channel_start_offset=
vgmstream->ch[i].offset=start_offset+
vgmstream->interleave_block_size*i;
}
}
return vgmstream;
/* clean up anything we may have opened */
fail:
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View file

@ -1206,38 +1206,6 @@ fail:
return NULL;
}
/* .vag - Nippon Ichi SPS wrapper [Penny-Punching Princess (Switch), Ys VIII (Switch)] */
VGMSTREAM* init_vgmstream_dsp_sps_n1(STREAMFILE* sf) {
dsp_meta dspm = {0};
/* checks */
if (read_u32be(0x00,sf) != 0x08000000) /* file type (see other N1 SPS) */
goto fail;
/* .vag: Penny-Punching Princess (Switch)
* .nlsd: Ys VIII (Switch) */
if (!check_extensions(sf, "vag,nlsd"))
goto fail;
if (read_u16le(0x08,sf) != read_u32le(0x24,sf)) /* header has various repeated values */
goto fail;
dspm.channels = 1;
dspm.max_channels = 1;
dspm.little_endian = 1;
dspm.header_offset = 0x1c;
dspm.header_spacing = 0x60;
dspm.start_offset = dspm.header_offset + dspm.header_spacing*dspm.channels;
dspm.interleave = 0;
dspm.meta_type = meta_DSP_VAG;
return init_vgmstream_dsp_common(sf, &dspm);
fail:
return NULL;
}
/* .itl - from Chanrinko Hero (GC) */
VGMSTREAM* init_vgmstream_dsp_itl_ch(STREAMFILE* sf) {
dsp_meta dspm = {0};

View file

@ -547,15 +547,23 @@ VGMSTREAM* init_vgmstream_nub_dsp(STREAMFILE* sf) {
/* paste header+data together and pass to meta, which has loop info too */
header_offset = 0xBC;
stream_size = read_32bitBE(0x14, sf);
header_size = read_32bitBE(0x1c, sf);
stream_size = read_u32be(0x14, sf);
header_size = read_u32be(0x1c, sf);
stream_offset = align_size_to_block(header_offset + header_size, 0x10);
temp_sf = setup_nub_streamfile(sf, header_offset, header_size, stream_offset, stream_size, "dsp");
if (!temp_sf) goto fail;
vgmstream = init_vgmstream_ngc_dsp_std(temp_sf);
if (!vgmstream) goto fail;
if (stream_size <= 0x10) {
// SoulCalibur Legends (Wii) empty subsongs (tc_jp0b.nub#4)
vgmstream = init_vgmstream_silence(0, 0, 0);
if (!vgmstream) goto fail;
}
else {
vgmstream = init_vgmstream_ngc_dsp_std(temp_sf);
if (!vgmstream) goto fail;
}
close_streamfile(temp_sf);
return vgmstream;
@ -576,6 +584,7 @@ VGMSTREAM* init_vgmstream_nub_idsp(STREAMFILE* sf) {
/* checks */
if (!is_id32be(0x00,sf, "idsp"))
return NULL;
// .idsp: internal extension before packing, seen in debug files with filenames
if (!check_extensions(sf,"idsp"))
return NULL;

View file

@ -400,7 +400,7 @@ static int _init_vgmstream_ogg_vorbis_tests(STREAMFILE* sf, ogg_vorbis_io_config
/* try in ../(file) too since that's how the .isl is stored on disc */
char isl_path[PATH_LIMIT];
snprintf(isl_path, sizeof(isl_path), "../%s", isl_name);
sf_isl = open_streamfile_by_filename(sf, isl_path);
sf_isl = open_streamfile_by_pathname(sf, isl_path);
}
if (sf_isl) {
@ -741,6 +741,14 @@ static VGMSTREAM* _init_vgmstream_ogg_vorbis_config(STREAMFILE* sf, off_t start,
loop_end_found = 1;
}
}
else if (strstr(comment,"COMMENT=SetSample ") == comment) { /* Ore no Tsure wa Hito de Nashi (PC) */
int unk0; // always 0 (delay?)
int m = sscanf(comment,"COMMENT=SetSample %d,%d,%d", &unk0, &loop_start, &loop_end);
if (m == 3) {
loop_flag = true;
loop_end_found = true;
}
}
else if (strstr(comment,"L=") == comment) { /* Kamaitachi no Yoru 2 (PS2) */
//sscanf(strrchr(comment,'=')+1,"%d", &loop_start);
loop_start = atol(strrchr(comment,'=')+1);

View file

@ -0,0 +1,72 @@
#include "meta.h"
#include "../coding/coding.h"
#include "../util/endianness.h"
/* RWAR - NintendoWare container [BIT.TRIP BEAT (Wii), Dance Dance Revolution Hottest Party 2 (Wii)] */
VGMSTREAM* init_vgmstream_rwar(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* temp_sf = NULL;
uint32_t tabl_offset, data_offset;
uint32_t subfile_offset, subfile_size;
int total_subsongs, target_subsong = sf->stream_index;
/* checks */
if (!is_id32be(0x00, sf, "RWAR"))
goto fail;
if (!check_extensions(sf,"rwar"))
goto fail;
/* simple container of .rwavs (inside .brsar), rarely used with single siles (DDR) */
/* abridged, see RWAV (same header) */
/* 0x04(2): BOM */
/* 0x06(2): version (usually 0100) */
/* 0x08: file size */
/* 0x0c(2): header size (0x20) */
/* 0x0e(2): sections (2) */
tabl_offset = read_u32be(0x10, sf);
/* 0x14: tabl size */
data_offset = read_u32be(0x18, sf);
/* 0x1c: data size */
/* TABL section */
if (!is_id32be(tabl_offset + 0x00, sf, "TABL"))
return NULL;
/* 0x04: size */
total_subsongs = read_u32be(tabl_offset + 0x08,sf);
if (target_subsong == 0) target_subsong = 1;
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
/* 0x00: always 0x01000000? */
subfile_offset = read_u32be(tabl_offset + 0x0c + (target_subsong-1) * 0x0c + 0x04,sf) + data_offset;
subfile_size = read_u32be(tabl_offset + 0x0c + (target_subsong-1) * 0x0c + 0x08,sf);
/* DATA section */
if (!is_id32be(data_offset + 0x00, sf, "DATA"))
goto fail;
/* 0x04: size */
//VGM_LOG("BRWAR: of=%x, sz=%x\n", subfile_offset, subfile_size);
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, "rwav");
if (!temp_sf) goto fail;
vgmstream = init_vgmstream_brwav(temp_sf);
if (!vgmstream) goto fail;
vgmstream->num_streams = total_subsongs;
close_streamfile(temp_sf);
return vgmstream;
fail:
close_streamfile(temp_sf);
close_vgmstream(vgmstream);
return NULL;
}

View file

@ -4,26 +4,27 @@
#include "../util/endianness.h"
#include "../util/layout_utils.h"
/* also see init_vgmstream_dsp_sps_n1 and init_vgmstream_opus_sps_n1 */
/* Nippon Ichi SPS wrapper [ClaDun (PSP), Legasista (PS3)] */
VGMSTREAM* init_vgmstream_sps_n1(STREAMFILE* sf) {
VGMSTREAM* vgmstream = NULL;
STREAMFILE* temp_sf = NULL;
int type, sample_rate;
off_t subfile_offset;
size_t subfile_size;
init_vgmstream_t init_vgmstream = NULL;
const char* extension = NULL;
uint32_t (*read_u32)(off_t,STREAMFILE*);
uint16_t (*read_u16)(off_t,STREAMFILE*);
read_u32_t read_u32;
read_u16_t read_u16;
/* checks */
if (!check_extensions(sf,"sps"))
goto fail;
int type = read_u32le(0x00,sf);
if (!((type > 0 && type < 10) || type == 0x01000000 || type == 0x02000000))
return NULL;
if (guess_endian32(0x00, sf)) { /* PS3 */
/* .sps: common, ClaDun X3 (Switch)
* .vag: Penny-Punching Princess (Switch)
* .nlsd: Ys VIII (Switch) */
if (!check_extensions(sf,"sps,vag,nlsd"))
return NULL;
if (guess_endian32(0x00, sf)) { // PS3
read_u32 = read_u32be;
read_u16 = read_u16be;
}
@ -31,12 +32,25 @@ VGMSTREAM* init_vgmstream_sps_n1(STREAMFILE* sf) {
read_u32 = read_u32le;
read_u16 = read_u16le;
}
type = read_u32(0x00,sf);
subfile_size = read_u32(0x04,sf);
sample_rate = read_u16(0x08,sf);
/* 0x0a: flag? (stereo?) */
/* 0x0b: flag? */
/* 0x0c: num_samples */
uint32_t subfile_size = read_u32(0x04,sf);
int sample_rate = read_u16(0x08,sf);
// 0x0a: flag? (stereo?)
// 0x0b: flag?
// 0x0c: num_samples
// newer games with loop section (>7?):
// 0x10: loop start
// 0x14: loop end
// some games extra value (>8?):
// 0x18: null?
if (sample_rate < 8000 || sample_rate > 48000) //arbitrary max
return NULL;
uint32_t subfile_offset = get_streamfile_size(sf) - subfile_size;
if (subfile_offset <= 0 || subfile_offset > 0x1c)
return NULL;
switch(type) {
case 1:
@ -49,13 +63,21 @@ VGMSTREAM* init_vgmstream_sps_n1(STREAMFILE* sf) {
extension = "at3";
break;
case 8:
init_vgmstream = init_vgmstream_ngc_dsp_std_le;
extension = "adpcm";
break;
case 7:
// init_vgmstream_ogg_vorbis (init_vgmstream_sps_n1_segmented)
case 9:
// init_vgmstream_opus_sps_n1
// init_vgmstream_opus_std (init_vgmstream_sps_n1_segmented)
default:
goto fail;
return NULL;
}
subfile_offset = 0x10;
if (subfile_size + subfile_offset != get_streamfile_size(sf))
goto fail;
/* init the VGMSTREAM */
temp_sf = setup_subfile_streamfile(sf, subfile_offset, subfile_size, extension);
@ -64,7 +86,14 @@ VGMSTREAM* init_vgmstream_sps_n1(STREAMFILE* sf) {
vgmstream = init_vgmstream(temp_sf);
if (!vgmstream) goto fail;
vgmstream->sample_rate = sample_rate; /* .vag header doesn't match */
vgmstream->sample_rate = sample_rate; // internal header isn't always correct vs .sps info
if (type == 8) {
// most files set loops in DSP header but don't loop, though some do full loops
uint32_t loop_start = read_u32(0x10, sf);
if (loop_start == 0)
vgmstream->loop_flag = false;
}
close_streamfile(temp_sf);
return vgmstream;
@ -91,7 +120,7 @@ VGMSTREAM* init_vgmstream_sps_n1_segmented(STREAMFILE* sf) {
/* checks */
type = read_u32le(0x00,sf);
if (type > 10)
if (type < 7 || type > 10)
return NULL;
/* .at9: Penny-Punching Princess (Switch), Labyrinth of Galleria (PC)

View file

@ -0,0 +1,97 @@
#include "meta.h"
#include "../coding/coding.h"
#include "../util/meta_utils.h"
/* SWAR - wave container generated by the DS SDK */
VGMSTREAM* init_vgmstream_swar(STREAMFILE* sf) {
/* checks */
if (!is_id32be(0x00,sf, "SWAR"))
return NULL;
if (!check_extensions(sf, "swar"))
return NULL;
meta_header_t h = {0};
h.meta = meta_SWAV;
h.target_subsong = sf->stream_index;
if (h.target_subsong == 0)
h.target_subsong = 1;
// wave container mainly for sequences, accesed through .sbnk
// 0x04: BOM mark
// 0x06: version? (1.00)
h.data_size = read_u32le(0x08,sf);
// 0x0c: always 16?
// 0x0e: always 1?
if (!is_id32be(0x10, sf, "DATA"))
return NULL;
// 0x14: chunk size (full)
h.total_subsongs = read_s32le(0x38,sf);
uint32_t head_offset = read_s32le(0x3c + (h.target_subsong - 1) * 0x04, sf);
// "sample" header, similar to SWAV
int codec = read_u8 (head_offset + 0x00, sf);
h.loop_flag = read_u8 (head_offset + 0x01, sf) != 0;
h.sample_rate = read_u16le(head_offset + 0x02, sf);
// 04 time units? (33.513982MHz/2 * time = samples?)
h.loop_start = read_u16le(head_offset + 0x06,sf); //in units
h.loop_end = read_s32le(head_offset + 0x08,sf); //length in units
h.stream_offset = head_offset;
uint32_t next_offset = h.target_subsong < h.total_subsongs ?
read_s32le(0x3c + (h.target_subsong) * 0x04, sf) :
h.data_size;
h.stream_size = next_offset - h.stream_offset;
h.stream_offset += 0x10;
h.stream_size -= 0x10;
h.channels = 1;
// same as SWAV
int bits_per_sample;
switch (codec) {
case 0: // Phoenix Wright: Ace Attorney (DS)
h.coding = coding_PCM8;
bits_per_sample = 8;
h.num_samples = pcm8_bytes_to_samples(h.stream_size, h.channels);
break;
case 1: // Electroplankton (DS)
h.coding = coding_PCM16LE;
bits_per_sample = 16;
h.num_samples = pcm16_bytes_to_samples(h.stream_size, h.channels);
break;
case 2: // common
h.coding = coding_IMA;
bits_per_sample = 4;
h.num_samples = ima_bytes_to_samples(h.stream_size, h.channels);
break;
default:
VGM_LOG("SWAR: unknown format\n");
return NULL;
}
h.loop_start = h.loop_start * 32 / bits_per_sample;
h.loop_end = h.loop_end * 32 / bits_per_sample + h.loop_start;
if (codec == 2) {
// handle IMA frame header
h.loop_start -= 32 / bits_per_sample;
h.loop_end -= 32 / bits_per_sample;
}
h.layout = layout_none;
h.sf = sf;
h.open_stream = true;
h.has_subsongs = true;
VGMSTREAM* v = alloc_metastream(&h);
if (!v) return NULL;
v->ch[0].adpcm_history1_32 = read_s16le(head_offset + 0x0c, sf);
v->ch[0].adpcm_step_index = read_u8(head_offset + 0x0e, sf);
return v;
}

View file

@ -414,8 +414,22 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) {
vgmstream->codec_config = 1; /* CONFIG_HIGH_NIBBLE */
}
/* get hist */
if (txth.hist_set) {
read_s16_t read_s16 = txth.hist_big_endian ? read_s16be : read_s16le;
if (txth.codec == IMA || txth.codec == DVI_IMA) {
for (int i = 0; i < txth.channels; i++) {
vgmstream->ch[i].adpcm_history1_32 = read_s16(txth.hist_offset + i * txth.hist_spacing + 0x00, sf);
vgmstream->ch[i].adpcm_step_index = read_u8(txth.hist_offset + i * txth.hist_spacing + 0x02, sf);
}
}
}
//TODO recheck and use only for needed cases
vgmstream->allow_dual_stereo = 1; /* known to be used in: PSX, AICA, YMZ */
vgmstream->allow_dual_stereo = true; /* known to be used in: PSX, AICA, YMZ */
break;
case coding_DPCM_KCEJ:
@ -555,7 +569,7 @@ VGMSTREAM* init_vgmstream_txth(STREAMFILE* sf) {
/* get hist */
if (txth.hist_set) {
read_s16_t read_s16 = txth.coef_big_endian ? read_s16be : read_s16le;
read_s16_t read_s16 = txth.hist_big_endian ? read_s16be : read_s16le;
for (i = 0; i < vgmstream->channels; i++) {
off_t offset = txth.hist_offset + i*txth.hist_spacing;
@ -1094,7 +1108,7 @@ static STREAMFILE* open_path_streamfile(STREAMFILE* sf, char* path) {
if (is_absolute(path))
return open_streamfile(sf, path); /* from path as is */
else
return open_streamfile_by_filename(sf, path); /* from current path */
return open_streamfile_by_pathname(sf, path); /* from current path */
}
static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, char* val) {
@ -1354,7 +1368,7 @@ static int parse_keyval(STREAMFILE* sf_, txth_header* txth, const char* key, cha
if (!parse_num(txth->sf_head,txth,val, &txth->hist_offset)) goto fail;
txth->hist_set = true;
/* special adjustment */
txth->hist_offset += txth->hist_offset;
txth->hist_offset += txth->base_offset;
if (txth->subsong_spacing && !txth->is_offset_absolute)
txth->hist_offset += txth->subsong_spacing * (txth->target_subsong - 1);
}

View file

@ -253,7 +253,7 @@ static bool parse_entries(txtp_header_t* txtp, STREAMFILE* sf) {
if (is_absolute(filename))
temp_sf = open_streamfile(sf, filename); /* from path as is */
else
temp_sf = open_streamfile_by_filename(sf, filename); /* from current path */
temp_sf = open_streamfile_by_pathname(sf, filename); /* from current path */
if (!temp_sf) {
vgm_logi("TXTP: cannot open %s\n", filename);
goto fail;

View file

@ -2779,8 +2779,8 @@ static void config_sb_random_old(ubi_sb_header* sb, off_t sequence_count, off_t
sb->cfg.random_percent_int = 1;
}
static int check_project_file(STREAMFILE *sf_header, const char *name, int has_localized_banks) {
STREAMFILE *sf_test = open_streamfile_by_filename(sf_header, name);
static int check_project_file(STREAMFILE* sf_header, const char *name, bool has_localized_banks) {
STREAMFILE *sf_test = open_streamfile_by_pathname(sf_header, name);
if (sf_test) {
close_streamfile(sf_test);
return 1;
@ -3107,7 +3107,7 @@ static int config_sb_version(ubi_sb_header* sb, STREAMFILE* sf) {
/* Tonic Touble Special Edition has garbage instead of version */
if (sb->is_bnm && sb->version > 0x00000000 && sb->platform == UBI_PC) {
if (check_project_file(sf, "ED_MAIN.LCB", 0) || check_project_file(sf, "../ED_MAIN.LCB", 0)) {
if (check_project_file(sf, "ED_MAIN.LCB", true)) {
is_ttse_pc = true;
sb->version = 0x00000000;
}

View file

@ -1,5 +1,6 @@
#include "meta.h"
#include "../coding/coding.h"
#include "../util/endianness.h"
#include <string.h>
#include "xwb_xsb.h"
@ -9,14 +10,14 @@
#define WAVEBANKENTRY_FLAGS_IGNORELOOP 0x00000008 // Used internally when the loop region can't be used (no idea...)
/* the x.x version is just to make it clearer, MS only classifies XACT as 1/2/3 */
#define XACT1_0_MAX 1 /* Project Gotham Racing 2 (Xbox)-v01, Silent Hill 4 (Xbox)-v01, Shin Megami Tensei NINE (Xbox)-v01 */
#define XACT1_1_MAX 3 /* Unreal Championship (Xbox)-v02, The King of Fighters 2003 (Xbox)-v03 */
#define XACT2_0_MAX 34 /* Project Gotham Racing 3 (X360)-v22, Dead or Alive 4 (X360)-v23, Table Tennis (X360)-v34 */ // v35/36/37 too?
#define XACT2_1_MAX 38 /* Prey (X360)-v38 */
#define XACT2_2_MAX 41 /* Just Cause (X360)-v39, Blue Dragon (X360)-v40 */
#define XACT3_0_MAX 46 /* Ninja Blade (X360)-t43-v42, Saints Row 2 (PC)-t44-v42, Persona 4 Ultimax NESSICA (PC)-t45-v43, BlazBlue (X360)-t46-v44 */
#define XACT_TECHLAND 0x10000 /* Sniper Ghost Warrior (PS3/X360), Nail'd (PS3/X360), equivalent to XACT3_0 */
#define XACT_CRACKDOWN 0x87 /* Crackdown 1, equivalent to XACT2_2 */
#define XACT1_0_MAX 1 // 0x01 // Project Gotham Racing 2 (Xbox)-v01, Silent Hill 4 (Xbox)-v01, Shin Megami Tensei NINE (Xbox)-v01
#define XACT1_1_MAX 3 // 0x03 // Unreal Championship (Xbox)-v02, The King of Fighters 2003 (Xbox)-v03
#define XACT2_0_MAX 34 // 0x22 // Project Gotham Racing 3 (X360)-v22, Dead or Alive 4 (X360)-v23, Table Tennis (X360)-v34 // v35/36/37 too?
#define XACT2_1_MAX 38 // 0x26 // Prey (X360)-v38
#define XACT2_2_MAX 41 // 0x29 // Just Cause (X360)-v39, Blue Dragon (X360)-v40
#define XACT3_0_MAX 46 // 0x2E // Ninja Blade (X360)-t43-v42, Saints Row 2 (PC)-t44-v42, Persona 4 Ultimax NESSICA (PC)-t45-v43, BlazBlue (X360)-t46-v44
#define XACT_TECHLAND 0x10000 // Sniper Ghost Warrior (PS3/X360), Nail'd (PS3/X360), equivalent to XACT3_0
#define XACT_CRACKDOWN 0x87 // Crackdown 1, equivalent to XACT2_2
static const int wma_avg_bps_index[7] = {
12000, 24000, 4000, 6000, 8000, 20000, 2500
@ -84,8 +85,8 @@ VGMSTREAM* init_vgmstream_xwb(STREAMFILE* sf) {
off_t start_offset, offset, suboffset;
xwb_header xwb = {0};
int target_subsong = sf->stream_index;
uint32_t (*read_u32)(off_t,STREAMFILE*) = NULL;
int32_t (*read_s32)(off_t,STREAMFILE*) = NULL;
read_u32_t read_u32 = NULL;
read_s32_t read_s32 = NULL;
char stream_name[STREAM_NAME_SIZE], file_name[STREAM_NAME_SIZE];
@ -313,8 +314,8 @@ VGMSTREAM* init_vgmstream_xwb(STREAMFILE* sf) {
else if (xwb.version <= XACT2_2_MAX) {
switch(xwb.tag) {
case 0: xwb.codec = PCM; break;
/* Table Tennis (v34): XMA1, Prey (v38): XMA2, v35/36/37: ? */
case 1: xwb.codec = xwb.version <= XACT2_0_MAX ? XMA1 : XMA2; break;
/* Table Tennis (v34)~Prey (v38): XMA1, Just Cause (v39): XMA2 */
case 1: xwb.codec = xwb.version <= XACT2_1_MAX ? XMA1 : XMA2; break;
case 2: xwb.codec = MS_ADPCM; break;
default: goto fail;
}

View file

@ -3,12 +3,12 @@
#include "meta.h"
#include "../util/companion_files.h"
#define XSB_XACT1_0_MAX 5 /* Unreal Championship (Xbox) */
#define XSB_XACT1_1_MAX 8 /* Die Hard: Vendetta (Xbox) */
#define XSB_XACT1_2_MAX 11 /* other Xbox games */
#define XSB_XACT2_0_MAX 34 /* Table Tennis (v34) */
//#define XSB_XACT2_1_MAX 38 /* Prey (v38) */ // v39 too?
#define XSB_XACT2_2_MAX 41 /* other PC/X360 games */
#define XSB_XACT1_0_MAX 5 // 0x05 // Unreal Championship (Xbox)
#define XSB_XACT1_1_MAX 8 // 0x08 // Die Hard: Vendetta (Xbox)
#define XSB_XACT1_2_MAX 11 // 0x0B // other Xbox games
#define XSB_XACT2_0_MAX 34 // 0x22 // Table Tennis (v34)
//#define XSB_XACT2_1_MAX 38 // 0x26 // Prey (v38) // v39 too?
#define XSB_XACT2_2_MAX 41 // 0x29 // other PC/X360 games
typedef struct {
@ -83,8 +83,8 @@ static void xsb_check_stream(xsb_header *xsb, int stream_index, int wavebank_ind
static int parse_xsb_old_cue_entry(xsb_header *xsb, STREAMFILE *sf, off_t name_offset, int entry) {
int32_t (*read_s32)(off_t,STREAMFILE*) = xsb->big_endian ? read_s32be : read_s32le;
int16_t (*read_s16)(off_t,STREAMFILE*) = xsb->big_endian ? read_s16be : read_s16le;
read_s32_t read_s32 = xsb->big_endian ? read_s32be : read_s32le;
read_s16_t read_s16 = xsb->big_endian ? read_s16be : read_s16le;
uint8_t flags, subflags;
uint32_t sound_type, sound_size;
int stream_index, wavebank_index;
@ -259,8 +259,8 @@ fail:
* - others
*/
static int parse_xsb_old_cues(xsb_header *xsb, STREAMFILE *sf) {
int32_t (*read_s32)(off_t,STREAMFILE*) = xsb->big_endian ? read_s32be : read_s32le;
int16_t (*read_s16)(off_t,STREAMFILE*) = xsb->big_endian ? read_s16be : read_s16le;
read_s32_t read_s32 = xsb->big_endian ? read_s32be : read_s32le;
read_s16_t read_s16 = xsb->big_endian ? read_s16be : read_s16le;
//uint16_t flags;
int cue_entry;
off_t offset, name_offset, jump_offset;
@ -313,8 +313,8 @@ static int parse_xsb_old_cues(xsb_header *xsb, STREAMFILE *sf) {
}
static int parse_xsb_clip(xsb_header *xsb, off_t offset, off_t name_offset, STREAMFILE *sf) {
uint32_t (*read_u32)(off_t,STREAMFILE*) = xsb->big_endian ? read_u32be : read_u32le;
int16_t (*read_s16)(off_t,STREAMFILE*) = xsb->big_endian ? read_s16be : read_s16le;
read_u32_t read_u32 = xsb->big_endian ? read_u32be : read_u32le;
read_s16_t read_s16 = xsb->big_endian ? read_s16be : read_s16le;
uint32_t flags;
int stream_index, wavebank_index;
@ -478,8 +478,8 @@ fail:
}
static int parse_xsb_sound(xsb_header *xsb, off_t offset, off_t name_offset, STREAMFILE *sf) {
int32_t (*read_s32)(off_t,STREAMFILE*) = xsb->big_endian ? read_s32be : read_s32le;
int16_t (*read_s16)(off_t,STREAMFILE*) = xsb->big_endian ? read_s16be : read_s16le;
read_s32_t read_s32 = xsb->big_endian ? read_s32be : read_s32le;
read_s16_t read_s16 = xsb->big_endian ? read_s16be : read_s16le;
uint8_t flags;
int stream_index = 0, wavebank_index = 0;
@ -548,9 +548,9 @@ static int parse_xsb_sound(xsb_header *xsb, off_t offset, off_t name_offset, STR
}
static int parse_xsb_variation(xsb_header *xsb, off_t offset, off_t name_offset, STREAMFILE *sf) {
int32_t (*read_s32)(off_t,STREAMFILE*) = xsb->big_endian ? read_s32be : read_s32le;
uint16_t (*read_u16)(off_t,STREAMFILE*) = xsb->big_endian ? read_u16be : read_u16le;
int16_t (*read_s16)(off_t,STREAMFILE*) = xsb->big_endian ? read_s16be : read_s16le;
read_s32_t read_s32 = xsb->big_endian ? read_s32be : read_s32le;
read_u16_t read_u16 = xsb->big_endian ? read_u16be : read_u16le;
read_s16_t read_s16 = xsb->big_endian ? read_s16be : read_s16le;
uint16_t flags;
int stream_index, wavebank_index;
@ -639,7 +639,7 @@ fail:
static int parse_xsb_cues(xsb_header *xsb, STREAMFILE *sf) {
int32_t (*read_s32)(off_t,STREAMFILE*) = xsb->big_endian ? read_s32be : read_s32le;
read_s32_t read_s32 = xsb->big_endian ? read_s32be : read_s32le;
uint8_t flags;
off_t offset, name_offset, sound_offset;
@ -712,9 +712,6 @@ static int parse_xsb_cues(xsb_header *xsb, STREAMFILE *sf) {
* - https://github.com/espes/MacTerrariaWrapper/tree/master/xactxtract
*/
static int parse_xsb(xsb_header *xsb, STREAMFILE *sf, char *xwb_wavebank_name) {
int32_t (*read_s32)(off_t,STREAMFILE*) = NULL;
int16_t (*read_s16)(off_t,STREAMFILE*) = NULL;
/* check header */
if ((read_u32be(0x00,sf) != 0x5344424B) && /* "SDBK" (LE) */
@ -722,14 +719,14 @@ static int parse_xsb(xsb_header *xsb, STREAMFILE *sf, char *xwb_wavebank_name) {
goto fail;
xsb->big_endian = (read_u32be(0x00,sf) == 0x4B424453); /* "KBDS" */
read_s32 = xsb->big_endian ? read_s32be : read_s32le;
read_s16 = xsb->big_endian ? read_s16be : read_s16le;
read_s32_t read_s32 = xsb->big_endian ? read_s32be : read_s32le;
read_s16_t read_s16 = xsb->big_endian ? read_s16be : read_s16le;
/* parse sound bank header */
xsb->version = read_s16(0x04, sf); /* tool version */
if (xsb->version <= XSB_XACT1_0_MAX) {
/* 06(2): crc */
/* 06(2): CRC-16/IBM-SDLC of data starting from 0x08 */
xsb->wavebanks_offset = read_s32(0x08, sf);
/* 0c(4): unknown1 offset (entry: 0x04) */
/* 10(4): unknown2 offset */
@ -748,7 +745,7 @@ static int parse_xsb(xsb_header *xsb, STREAMFILE *sf, char *xwb_wavebank_name) {
}
else if (xsb->version <= XSB_XACT1_1_MAX) {
/* 06(2): crc */
/* 06(2): CRC-16/IBM-SDLC of data starting from 0x08 */
xsb->wavebanks_offset = read_s32(0x08, sf);
/* 0c(4): unknown1 offset (entry: 0x04) */
/* 10(4): unknown2 offset */
@ -767,7 +764,7 @@ static int parse_xsb(xsb_header *xsb, STREAMFILE *sf, char *xwb_wavebank_name) {
xsb->entry_size = 0x14;
}
else if (xsb->version <= XSB_XACT1_2_MAX) {
/* 06(2): crc */
/* 06(2): CRC-16/IBM-SDLC of data starting from 0x08 */
xsb->wavebanks_offset = read_s32(0x08, sf);
/* 0c(4): unknown1 offset (entry: 0x14) */
/* 10(4): unknown2 offset (entry: variable) */
@ -787,7 +784,7 @@ static int parse_xsb(xsb_header *xsb, STREAMFILE *sf, char *xwb_wavebank_name) {
xsb->entry_size = 0x14;
}
else if (xsb->version <= XSB_XACT2_2_MAX) {
/* 06(2): crc */
/* 06(2): CRC-16/IBM-SDLC of data starting from 0x08 (always LE) */
/* 08(1): platform? (3=X360) */
xsb->simple_cues_count = read_s16(0x09, sf);
xsb->complex_cues_count = read_s16(0x0B, sf);
@ -813,7 +810,7 @@ static int parse_xsb(xsb_header *xsb, STREAMFILE *sf, char *xwb_wavebank_name) {
}
else {
/* 06(2): format version */
/* 08(2): crc (fcs16 checksum of all following data) */
/* 08(2): CRC-16/IBM-SDLC of data starting from 0x12 (always LE) */
/* 0a(4): last modified low */
/* 0e(4): last modified high */
/* 12(1): platform? (1=PC, 3=X360) */

View file

@ -1,93 +0,0 @@
#include "meta.h"
#include "../util.h"
/* ZWDSP (hcs' custom DSP files from Zack & Wiki) */
VGMSTREAM * init_vgmstream_zwdsp(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
char filename[PATH_LIMIT];
int second_channel_start;
int loop_flag;
int channel_count = 2;
off_t start_offset;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("zwdsp",filename_extension(filename))) goto fail;
/* check header */
if (read_32bitBE(0x00,streamFile) != 0x00000000) /* 0x0 */
goto fail;
/* Retrieve the loop flag, some files have 0x0 and some 0x02 as "no loop" */
switch (read_32bitBE(0x10, streamFile)) {
case 0:
case 2:
loop_flag = 0;
break;
default:
loop_flag = 1;
}
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
start_offset = 0x90;
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitBE(0x08,streamFile);
vgmstream->coding_type = coding_NGC_DSP;
vgmstream->num_samples = read_32bitBE(0x18,streamFile)*14/8/channel_count;
if (loop_flag) {
vgmstream->loop_start_sample = read_32bitBE(0x10,streamFile)*14/8/channel_count;
vgmstream->loop_end_sample = read_32bitBE(0x14,streamFile)*14/8/channel_count;
// frequently end sample is one more than total samples in file
if (vgmstream->loop_end_sample > vgmstream->num_samples)
{
vgmstream->loop_end_sample = vgmstream->num_samples;
}
}
vgmstream->layout_type = layout_none;
vgmstream->meta_type = meta_ZWDSP;
if (vgmstream->coding_type == coding_NGC_DSP) {
int i;
for (i=0;i<16;i++) {
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x20+i*2,streamFile);
}
if (vgmstream->channels == 2) {
for (i=0;i<16;i++) {
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x60+i*2,streamFile);
}
}
}
second_channel_start = (get_streamfile_size(streamFile)+start_offset)/2;
{
int i;
STREAMFILE * file;
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!file) goto fail;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = file;
vgmstream->ch[0].channel_start_offset=start_offset;
if (channel_count == 2) {
if (second_channel_start == -1) goto fail;
vgmstream->ch[1].channel_start_offset=second_channel_start;
}
vgmstream->ch[i].offset = vgmstream->ch[i].channel_start_offset;
}
}
return vgmstream;
/* clean up anything we may have opened */
fail:
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View file

@ -15,6 +15,11 @@ VGMSTREAM* alloc_metastream(meta_header_t* h) {
return NULL;
}
if (h->has_subsongs && h->has_empty_banks && h->total_subsongs == 0) {
vgm_logi("VGMSTREAM: bank has no subsongs (ignore)\n");
return NULL;
}
if (h->has_subsongs && (h->target_subsong < 0 || h->target_subsong > h->total_subsongs || h->total_subsongs < 1)) {
VGM_LOG("meta: wrong subsongs %i vs %i\n", h->target_subsong, h->total_subsongs);
return NULL;

View file

@ -56,6 +56,7 @@ typedef struct {
bool open_stream;
bool has_subsongs;
bool has_empty_banks;
bool allow_dual_stereo;
} meta_header_t;

View file

@ -2,6 +2,7 @@
#include "../vgmstream.h"
#include "reader_sf.h"
#include "paths.h"
#include "log.h"
/* change pathname's extension to another (or add it if extensionless) */
@ -34,12 +35,25 @@ STREAMFILE* open_streamfile_by_ext(STREAMFILE* sf, const char* ext) {
return open_streamfile(sf, filename);
}
STREAMFILE* open_streamfile_by_filename(STREAMFILE* sf, const char* filename) {
static STREAMFILE* open_streamfile_internal(STREAMFILE* sf, const char* filename, bool allow_relpaths) {
char fullname[PATH_LIMIT];
char partname[PATH_LIMIT];
char *path, *name, *otherpath;
if (!sf || !filename || !filename[0]) return NULL;
if (!sf || !filename || !filename[0])
return NULL;
// Some formats open companion files in current dir or subfolders. Relative paths are restricted by default
// for better control access. Mainly for doc purposes (most formats wouldn't need that), since
// the security risk of a format opening an arbitrary file is low given regular .m3u allow arbitrary paths
// anyway, and without RCE it can't leave your system (and web player can't read the filesystem).
if (!allow_relpaths) {
// disallow relative or absolute paths (crafty users could mimic plugin's internal URIs though)
if (strstr(filename, "..") || strstr(filename, ":\\") || filename[0] == '/') {
VGM_LOG("SF: ignored relative path %s\n", filename);
return NULL;
}
}
get_streamfile_name(sf, fullname, sizeof(fullname));
@ -93,6 +107,14 @@ STREAMFILE* open_streamfile_by_filename(STREAMFILE* sf, const char* filename) {
return open_streamfile(sf, fullname);
}
STREAMFILE* open_streamfile_by_filename(STREAMFILE* sf, const char* filename) {
return open_streamfile_internal(sf, filename, false);
}
STREAMFILE* open_streamfile_by_pathname(STREAMFILE* sf, const char* filename) {
return open_streamfile_internal(sf, filename, true);
}
/* ************************************************************************* */
int check_extensions(STREAMFILE* sf, const char* cmp_exts) {

View file

@ -8,11 +8,14 @@
* Can be used to get companion headers. */
STREAMFILE* open_streamfile_by_ext(STREAMFILE* sf, const char* ext);
/* Opens a STREAMFILE from a base path + new filename.
* Can be used to get companion files. Relative paths like
* './filename', '../filename', 'dir/filename' also work. */
/* Opens a STREAMFILE from a base path + new filename. Can be used to get companion files.
* Subfolders like 'dir/filename' also work (not as common but some formats do use it). */
STREAMFILE* open_streamfile_by_filename(STREAMFILE* sf, const char* filename);
/* Same as above, but relative paths like '../filename' also work.
* Not much difference but helps identifying which formats need prev folders */
STREAMFILE* open_streamfile_by_pathname(STREAMFILE* sf, const char* filename);
/* various STREAMFILE helpers functions */
/* Checks if the stream filename is one of the extensions (comma-separated, ex. "adx" or "adx,aix").

View file

@ -300,8 +300,14 @@ void reset_vgmstream(VGMSTREAM* vgmstream);
/* close an open vgmstream */
void close_vgmstream(VGMSTREAM* vgmstream);
// If you are using vgmstream as a library and wonder what happened to render_vgmstream(), you can use
// render_vgmstream2() for the time being, it's 100% the same (it was renamed to bring this into attention,
// typedef as needed). However, please migrate to the public API (see libvgmstream.h) instead, it's
// fairly straightforward (see "Use external API" and related commits for various plugins).
// In next versions the "API" in this .h will be removed without warning as it wasn't really intended to be
// used by external projects. I hate breaking things but it's becoming very hard to improve anything otherwise, sorry.
/* Decode data into sample buffer. Returns < sample_count on stream end */
int render_vgmstream(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
int render_vgmstream2(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
/* Seek to sample position (next render starts from that point). Use only after config is set (vgmstream_apply_config) */
void seek_vgmstream(VGMSTREAM* vgmstream, int32_t seek_sample);

View file

@ -9,7 +9,7 @@ init_vgmstream_t init_vgmstream_functions[] = {
init_vgmstream_brwav,
init_vgmstream_bfwav,
init_vgmstream_bcwav,
init_vgmstream_brwar,
init_vgmstream_rwar,
init_vgmstream_nds_strm,
init_vgmstream_afc,
init_vgmstream_ast,
@ -210,7 +210,6 @@ init_vgmstream_t init_vgmstream_functions[] = {
init_vgmstream_mtaf,
init_vgmstream_alp,
init_vgmstream_wpd,
init_vgmstream_mn_str,
init_vgmstream_mcss,
init_vgmstream_ps2_hsf,
init_vgmstream_ivag,
@ -338,7 +337,6 @@ init_vgmstream_t init_vgmstream_functions[] = {
init_vgmstream_bnk_sony,
init_vgmstream_nus3bank,
init_vgmstream_sscf,
init_vgmstream_dsp_sps_n1,
init_vgmstream_dsp_itl_ch,
init_vgmstream_a2m,
init_vgmstream_ahv,
@ -512,6 +510,8 @@ init_vgmstream_t init_vgmstream_functions[] = {
init_vgmstream_oor,
init_vgmstream_mio,
init_vgmstream_audiopkg,
init_vgmstream_swar,
init_vgmstream_ivb,
/* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */
init_vgmstream_agsc,
@ -559,7 +559,6 @@ init_vgmstream_t init_vgmstream_functions[] = {
init_vgmstream_raw_pcm, /* .raw raw PCM */
init_vgmstream_raw_s14_sss, /* .s14/sss raw siren14 */
init_vgmstream_exakt_sc, /* .sc raw PCM */
init_vgmstream_zwdsp, /* fake format */
init_vgmstream_ps2_adm, /* weird non-constant PSX blocks */
init_vgmstream_rwsd, /* crap, to be removed */
#ifdef VGM_USE_FFMPEG

View file

@ -384,7 +384,6 @@ typedef enum {
meta_SEG,
meta_RIFF_IMA,
meta_KNON,
meta_ZWDSP, /* Zack and Wiki */
meta_VGS, /* Guitar Hero Encore - Rocks the 80s */
meta_DCS_WAV,
meta_SMP,
@ -506,7 +505,6 @@ typedef enum {
meta_MTAF,
meta_ALP,
meta_WPD,
meta_MN_STR, /* Mini Ninjas (PC/PS3/WII) */
meta_MCSS,
meta_PS2_HSF, /* Lowrider (PS2) */
meta_IVAG,
@ -598,7 +596,6 @@ typedef enum {
meta_HD3_BD3, /* Sony PS3 bank */
meta_BNK_SONY, /* Sony Scream Tool bank */
meta_SSCF,
meta_DSP_VAG, /* Penny-Punching Princess (Switch) sfx */
meta_DSP_ITL, /* Charinko Hero (GC) */
meta_A2M, /* Scooby-Doo! Unmasked (PS2) */
meta_AHV, /* Headhunter (PS2) */
@ -722,6 +719,8 @@ typedef enum {
meta_OOR,
meta_MIO,
meta_AUDIOPKG,
meta_SWAR,
meta_IVB,
} meta_t;
#endif