From 80d1f3c470c0e3506e76f83b05f831e0238ca22e Mon Sep 17 00:00:00 2001 From: halleyscometsw Date: Tue, 6 May 2008 01:01:06 +0000 Subject: [PATCH] Beginning rwsd supprot git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@86 51a99a44-fe44-0410-b1ba-c3e57ba2b86b --- src/Makefile | 3 +- src/meta/rwsd.c | 129 ++++++++++++++++++++++++++++++++++++++++++++++++ src/meta/rwsd.h | 8 +++ src/vgmstream.c | 7 ++- src/vgmstream.h | 1 + 5 files changed, 146 insertions(+), 2 deletions(-) create mode 100644 src/meta/rwsd.c create mode 100644 src/meta/rwsd.h diff --git a/src/Makefile b/src/Makefile index 35493889..e315ae8b 100644 --- a/src/Makefile +++ b/src/Makefile @@ -27,7 +27,8 @@ META_OBJS=meta/adx_header.o \ meta/Cstr.o \ meta/gcsw.o \ meta/ps2_ads.o \ - meta/ps2_npsf.o + meta/ps2_npsf.o \ + meta/rwsd.o OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS) diff --git a/src/meta/rwsd.c b/src/meta/rwsd.c new file mode 100644 index 00000000..c0035a22 --- /dev/null +++ b/src/meta/rwsd.c @@ -0,0 +1,129 @@ +#include "rwsd.h" +#include "../util.h" + +/* RWSD is quite similar to BRSTM, but can contain several streams. + * Still, a lot of games use it for single streams. We only support the + * single stream form here */ +VGMSTREAM * init_vgmstream_rwsd(const char * const filename) { + VGMSTREAM * vgmstream = NULL; + STREAMFILE * infile = NULL; + + coding_t coding_type; + + off_t head_offset; + size_t head_length; + int codec_number; + int channel_count; + int loop_flag; + + off_t start_offset; + + /* check extension, case insensitive */ + if (strcasecmp("brstm",filename_extension(filename))) goto fail; + + /* try to open the file for header reading */ + infile = open_streamfile(filename); + if (!infile) goto fail; + + /* check header */ + if ((uint32_t)read_32bitBE(0,infile)!=0x5253544D || /* "RSTM" */ + (uint32_t)read_32bitBE(4,infile)!=0xFEFF0100) + goto fail; + + /* get head offset, check */ + head_offset = read_32bitBE(0x10,infile); + if ((uint32_t)read_32bitBE(head_offset,infile)!=0x48454144) /* "HEAD" */ + goto fail; + head_length = read_32bitBE(0x14,infile); + + /* check type details */ + codec_number = read_8bit(head_offset+0x20,infile); + loop_flag = read_8bit(head_offset+0x21,infile); + channel_count = read_8bit(head_offset+0x22,infile); + + switch (codec_number) { + case 0: + coding_type = coding_PCM8; + break; + case 1: + coding_type = coding_PCM16BE; + break; + case 2: + coding_type = coding_NGC_DSP; + break; + default: + goto fail; + } + + if (channel_count < 1) goto fail; + + /* build the VGMSTREAM */ + + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + vgmstream->num_samples = read_32bitBE(head_offset+0x2c,infile); + vgmstream->sample_rate = (uint16_t)read_16bitBE(head_offset+0x24,infile); + /* channels and loop flag are set by allocate_vgmstream */ + vgmstream->loop_start_sample = read_32bitBE(head_offset+0x28,infile); + vgmstream->loop_end_sample = vgmstream->num_samples; + + vgmstream->coding_type = coding_type; + if (channel_count==1) + vgmstream->layout_type = layout_none; + else + vgmstream->layout_type = layout_interleave_shortblock; + vgmstream->meta_type = meta_RSTM; + + vgmstream->interleave_block_size = read_32bitBE(head_offset+0x38,infile); + vgmstream->interleave_smallblock_size = read_32bitBE(head_offset+0x48,infile); + + if (vgmstream->coding_type == coding_NGC_DSP) { + off_t coef_offset; + off_t coef_offset1; + off_t coef_offset2; + int i,j; + + coef_offset1=read_32bitBE(head_offset+0x1c,infile); + coef_offset2=read_32bitBE(head_offset+0x10+coef_offset1,infile); + coef_offset=coef_offset2+0x10; + + for (j=0;jchannels;j++) { + for (i=0;i<16;i++) { + vgmstream->ch[j].adpcm_coef[i]=read_16bitBE(head_offset+coef_offset+j*0x38+i*2,infile); + } + } + } + + start_offset = read_32bitBE(head_offset+0x30,infile); + + close_streamfile(infile); infile=NULL; + + /* open the file for reading by each channel */ + { + int i; + for (i=0;ilayout_type==layout_interleave_shortblock) + vgmstream->ch[i].streamfile = open_streamfile_buffer(filename, + vgmstream->interleave_block_size); + else + vgmstream->ch[i].streamfile = open_streamfile_buffer(filename, + 0x1000); + + if (!vgmstream->ch[i].streamfile) goto fail; + + vgmstream->ch[i].channel_start_offset= + vgmstream->ch[i].offset= + start_offset + i*vgmstream->interleave_block_size; + } + } + + return vgmstream; + + /* clean up anything we may have opened */ +fail: + if (infile) close_streamfile(infile); + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/rwsd.h b/src/meta/rwsd.h new file mode 100644 index 00000000..d12bae95 --- /dev/null +++ b/src/meta/rwsd.h @@ -0,0 +1,8 @@ +#include "../vgmstream.h" + +#ifndef _RWSD_H +#define _RWSD_H + +VGMSTREAM * init_vgmstream_rwsd(const char * const filename); + +#endif diff --git a/src/vgmstream.c b/src/vgmstream.c index 13967fb5..0e60e7bd 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -21,6 +21,7 @@ #include "meta/gcsw.h" #include "meta/ps2_ads.h" #include "meta/ps2_npsf.h" +#include "meta/rwsd.h" #include "layout/interleave.h" #include "layout/nolayout.h" #include "layout/blocked.h" @@ -38,7 +39,7 @@ * List of functions that will recognize files. These should correspond pretty * directly to the metadata types */ -#define INIT_VGMSTREAM_FCNS 15 +#define INIT_VGMSTREAM_FCNS 16 VGMSTREAM * (*init_vgmstream_fcns[INIT_VGMSTREAM_FCNS])(const char * const) = { init_vgmstream_adx, init_vgmstream_brstm, @@ -55,6 +56,7 @@ VGMSTREAM * (*init_vgmstream_fcns[INIT_VGMSTREAM_FCNS])(const char * const) = { init_vgmstream_gcsw, init_vgmstream_ps2_ads, init_vgmstream_ps2_npsf, + init_vgmstream_rwsd, }; @@ -582,6 +584,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case meta_PS2_NPSF: snprintf(temp,TEMPSIZE,"Namco Production Sound File (NPSF)"); break; + case meta_RWSD: + snprintf(temp,TEMPSIZE,"Nintendo RWSD header (single stream)"); + break; default: snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET"); } diff --git a/src/vgmstream.h b/src/vgmstream.h index a7c28be6..c6194478 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -59,6 +59,7 @@ typedef enum { meta_RSTM, /* RSTM (similar to STRM) */ meta_AFC, /* AFC */ meta_AST, /* AST */ + meta_RWSD, /* single-stream RWSD */ /* CRI ADX */ meta_ADX_03, /* ADX "type 03" */ meta_ADX_04, /* ADX "type 04" */