diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index 07ff4fbf..1f476c7a 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -254,6 +254,10 @@ RelativePath=".\meta\ivb.c" > + + diff --git a/src/meta/fsb.c b/src/meta/fsb.c index b3739de3..71187dc2 100644 --- a/src/meta/fsb.c +++ b/src/meta/fsb.c @@ -7,6 +7,7 @@ VGMSTREAM * init_vgmstream_fsb(STREAMFILE *streamFile) { char filename[260]; off_t start_offset; + /* int fsb3_included_files; */ int fsb3_headerlen = 0x18; int fsb3_format; int loop_flag = 0; @@ -19,14 +20,32 @@ VGMSTREAM * init_vgmstream_fsb(STREAMFILE *streamFile) { /* check header */ if (read_32bitBE(0x00,streamFile) != 0x46534233) /* "FSB3" */ goto fail; + + /* "Check if the FSB is used as + conatiner or as single file" */ + if (read_32bitBE(0x04,streamFile) != 0x01000000) + goto fail; + - if (read_32bitBE(0x48,streamFile) == 0x02000806) { + + if (read_32bitBE(0x48,streamFile) == 0x02000806) { loop_flag = 1; } else { loop_flag = 0; /* (read_32bitLE(0x08,streamFile)!=0); */ } - channel_count = 2; + /* Channel check + if (read_16bitLE(0x56,streamFile) == 2) { + channel_count = 2; + } else { + goto fail; + } + */ + + + channel_count = read_16bitLE(0x56,streamFile); + + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; @@ -37,6 +56,7 @@ VGMSTREAM * init_vgmstream_fsb(STREAMFILE *streamFile) { case 0x40008800: /* PS2 (Agent Hugo, Flat Out 2) */ case 0x41008800: /* PS2 (Flat Out) */ case 0x42008800: /* PS2 (Jackass - The Game) */ + case 0x01008804: /* PS2 (Cold Fear) */ vgmstream->coding_type = coding_PSX; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x10; @@ -60,7 +80,7 @@ VGMSTREAM * init_vgmstream_fsb(STREAMFILE *streamFile) { break; case 0x40004020: /* WII (Guitar Hero III), uses Xbox-ish IMA */ case 0x400040A0: /* WII (Guitar Hero III), uses Xbox-ish IMA */ - case 0x41004800: /* XBOX (FlatOut) */ + case 0x41004800: /* XBOX (FlatOut, Rainbow Six - Lockdown) */ vgmstream->coding_type = coding_XBOX; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 36; @@ -75,7 +95,7 @@ VGMSTREAM * init_vgmstream_fsb(STREAMFILE *streamFile) { } /* fill in the vital statistics */ start_offset = (read_32bitLE(0x08,streamFile))+fsb3_headerlen; - vgmstream->channels = read_16bitLE(0x56,streamFile); + vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitLE(0x4C,streamFile); vgmstream->meta_type = meta_FSB3; diff --git a/src/meta/meta.h b/src/meta/meta.h index 3a690d62..fa0ca1bb 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -135,4 +135,6 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_xa30(STREAMFILE * streamFile); +VGMSTREAM * init_vgmstream_musc(STREAMFILE * streamFile); + #endif diff --git a/src/meta/musc.c b/src/meta/musc.c new file mode 100644 index 00000000..d52c584e --- /dev/null +++ b/src/meta/musc.c @@ -0,0 +1,76 @@ +#include "meta.h" +#include "../util.h" + +/* MUSC/MUSX (near all Spyro games and many other using this) */ +VGMSTREAM * init_vgmstream_musc(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + off_t start_offset; + + int musc_version; + int loop_flag = 0; + int channel_count = 2; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("musc",filename_extension(filename))) goto fail; + + /* check header */ + if (read_32bitBE(0x0,streamFile) != 0x4D555343) /* MUSC */ + goto fail; + + loop_flag = 0; /* (read_32bitLE(0x08,streamFile)!=0); */ + channel_count = 2; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + musc_version=read_32bitLE(0x10,streamFile); + switch (musc_version) { + /* This handles the 'new' MUSC Version, which has only a 32 byte header + and doesn't provide any loop info! + Spyro - The Eternal Night, Spyro - A new Beginning, Ty - The Tsamanian Tiger */ + case 0x20: + start_offset = 0x20; + vgmstream->coding_type = coding_PSX; + vgmstream->num_samples = (read_32bitLE(0x14,streamFile))*28/16/channel_count; + if (loop_flag) { + vgmstream->loop_start_sample = 0; /*(read_32bitLE(0x08,streamFile)-1)*28; */ + vgmstream->loop_end_sample = (read_32bitLE(0x14,streamFile))*28/16/channel_count; + } + break; + default: + goto fail; +} + vgmstream->channels = channel_count; + vgmstream->sample_rate = read_32bitLE(0x06,streamFile); + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = (read_32bitLE(0x18,streamFile))/2; + vgmstream->meta_type = meta_MUSC; + + + + /* 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/ps2_xa30.c b/src/meta/ps2_xa30.c index deda4bf1..4351c633 100644 --- a/src/meta/ps2_xa30.c +++ b/src/meta/ps2_xa30.c @@ -28,7 +28,7 @@ VGMSTREAM * init_vgmstream_xa30(STREAMFILE *streamFile) { /* fill in the vital statistics */ start_offset = read_32bitLE(0x0C,streamFile); vgmstream->channels = channel_count; - vgmstream->sample_rate = 22050; + vgmstream->sample_rate = read_32bitLE(0x04,streamFile); vgmstream->coding_type = coding_PSX; vgmstream->num_samples = read_32bitLE(0x14,streamFile)*28/16/channel_count; if (loop_flag) { diff --git a/src/vgmstream.c b/src/vgmstream.c index 270f44dc..ea9b74e0 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -83,6 +83,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = { init_vgmstream_rwx, init_vgmstream_xwb, init_vgmstream_xa30, + init_vgmstream_musc, }; #define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0])) diff --git a/src/vgmstream.h b/src/vgmstream.h index 4272fbbc..65d361ac 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -179,6 +179,7 @@ typedef enum { meta_RWX, /* Air Force Delta Storm (XBOX) */ meta_XWB, /* King of Fighters (XBOX) */ meta_XA30, /* Driver - Parallel Lines (PS2) */ + meta_MUSC, /* DSpyro Games, possibly more */ meta_XBOX_WAVM, /* XBOX WAVM File */ meta_XBOX_RIFF, /* XBOX RIFF/WAVE File */ diff --git a/winamp/in_vgmstream.c b/winamp/in_vgmstream.c index 7ba95d17..c3f01ba6 100644 --- a/winamp/in_vgmstream.c +++ b/winamp/in_vgmstream.c @@ -139,6 +139,7 @@ char * extension_list[] = { "rwx\0RWX Audio File (*.RWX)\0", "xwb\0XWB Audio File (*.XWB)\0", "xa30\0XA30 Audio File (*.XA30)\0", + "musc\0MUSC Audio File (*.MUSC)\0", }; void about(HWND hwndParent) {