diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index e1be1714..ab110c19 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -678,6 +678,10 @@ RelativePath=".\meta\wii_smp.c" > + + diff --git a/src/meta/meta.h b/src/meta/meta.h index 0bc84055..149e49f7 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -318,4 +318,6 @@ VGMSTREAM * init_vgmstream_emff(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_thp(STREAMFILE *streamFile); +VGMSTREAM * init_vgmstream_wii_sts(STREAMFILE *streamFile); + #endif diff --git a/src/meta/wii_sts.c b/src/meta/wii_sts.c new file mode 100644 index 00000000..9111988d --- /dev/null +++ b/src/meta/wii_sts.c @@ -0,0 +1,87 @@ +#include "meta.h" +#include "../util.h" + +/* STS + + STS (found in Shikigami No Shiro 3) + Don't confuse with ps2 .STS (EXST) format, this one is for WII +*/ + +VGMSTREAM * init_vgmstream_wii_sts(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + char filename[260]; + + int loop_flag=0; + int channel_count; + int i,j; + off_t start_offset; + + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("sts",filename_extension(filename))) goto fail; + + /* First bytes contain the size of the file (-4) */ + if(read_32bitBE(0x0,streamFile)!=get_streamfile_size(streamFile)-4) + goto fail; + + loop_flag = (read_32bitLE(0x4C,streamFile)!=0xFFFFFFFF); + channel_count=read_8bit(0x8,streamFile)+1; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + vgmstream->channels = channel_count; + vgmstream->sample_rate = read_32bitBE(0x0A,streamFile); + vgmstream->coding_type = coding_NGC_DSP; + + if(vgmstream->channels==1) + vgmstream->num_samples = (read_32bitBE(0x0,streamFile)+4-0x70)/8*14; + else + vgmstream->num_samples = (read_32bitBE(0x0,streamFile)+4-0x50-0x26)/8*14/2; + + vgmstream->layout_type = layout_none; + vgmstream->meta_type = meta_STS_WII; + + if(loop_flag) { + vgmstream->loop_start_sample=read_32bitLE(0x24,streamFile); + vgmstream->loop_end_sample=vgmstream->num_samples; + } + + /* setting coef tables */ + if(vgmstream->channels==1) + start_offset = 0x70; + else + start_offset = 0x50; + + // First channel + for(j=0;j<16;j++) { + vgmstream->ch[0].adpcm_coef[j]=read_16bitBE(0x1E+(j*2),streamFile); + } + + // Second channel ? + if(vgmstream->channels==2) { + start_offset+=read_32bitBE(0x1a,streamFile); + for(j=0;j<16;j++) { + vgmstream->ch[1].adpcm_coef[j]=read_16bitBE(start_offset+(j*2),streamFile); + } + } + + /* open the file for reading by each channel */ + { + for (i=0;ich[i].streamfile = streamFile->open(streamFile,filename,36); + vgmstream->ch[i].offset = 0x50+(i*(start_offset+0x26-0x50)); + + if (!vgmstream->ch[i].streamfile) goto fail; + } + } + + return vgmstream; + + /* clean up anything we may have opened */ +fail: + if (vgmstream) close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/vgmstream.c b/src/vgmstream.c index 19d56749..8203ca95 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -176,6 +176,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = { init_vgmstream_emff, init_vgmstream_ss_stream, init_vgmstream_thp, + init_vgmstream_wii_sts, }; #define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0])) @@ -1909,6 +1910,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { break; case meta_THP: snprintf(temp,TEMPSIZE,"THP Movie File Format Header"); + break; + case meta_STS_WII: + snprintf(temp,TEMPSIZE,"Shikigami no Shiro (WII) Header"); break; default: snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET"); diff --git a/src/vgmstream.h b/src/vgmstream.h index 889808f4..cc8d5da9 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -344,6 +344,7 @@ typedef enum { meta_VS, /* Men in Black .vs */ meta_FFXI_BGW, /* FFXI BGW */ meta_FFXI_SPW, /* FFXI SPW */ + meta_STS_WII, /* Shikigami No Shiro 3 STS Audio File */ } meta_t; typedef struct {