diff --git a/readme.txt b/readme.txt index ed49f642..482e344e 100644 --- a/readme.txt +++ b/readme.txt @@ -186,6 +186,7 @@ multi: - .genh (lots) - .nwa (16 bit PCM, NWA DPCM) - .psw (PSX ADPCM, GC DSP ADPCM) +- .rwar (GC DSP ADPCM, 8/16 bit PCM) - .rwsd (GC DSP ADPCM, 8/16 bit PCM) - .rsd (PSX ADPCM, 16 bit PCM, GC DSP ADPCM, Xbox IMA ADPCM) - .sad (GC DSP ADPCM, NDS IMA ADPCM) diff --git a/src/Makefile b/src/Makefile index 15778394..571c6e6f 100644 --- a/src/Makefile +++ b/src/Makefile @@ -123,7 +123,6 @@ META_OBJS=meta/adx_header.o \ meta/sdt.o \ meta/aix.o \ meta/ngc_tydsp.o \ - meta/ngc_vjdsp.o \ meta/xbox_wvs.o \ meta/xbox_ims.o \ meta/xbox_stma.o \ diff --git a/src/meta/Makefile.unix.am b/src/meta/Makefile.unix.am index c4fc96f0..c170b024 100644 --- a/src/meta/Makefile.unix.am +++ b/src/meta/Makefile.unix.am @@ -88,7 +88,6 @@ libmeta_la_SOURCES += sdt.c libmeta_la_SOURCES += aix.c libmeta_la_SOURCES += ngc_tydsp.c libmeta_la_SOURCES += xbox_wvs.c -libmeta_la_SOURCES += ngc_vjdsp.c libmeta_la_SOURCES += xbox_stma.c libmeta_la_SOURCES += xbox_ims.c libmeta_la_SOURCES += de2.c diff --git a/src/meta/rwsd.c b/src/meta/rwsd.c index db66292b..62b9c38f 100644 --- a/src/meta/rwsd.c +++ b/src/meta/rwsd.c @@ -2,6 +2,31 @@ #include "../coding/coding.h" #include "../util.h" +static off_t read_rwar(off_t offset, int *version, STREAMFILE *streamFile) +{ + off_t wave_offset; + if ((uint32_t)read_32bitBE(offset,streamFile)!=0x52574152) /* "RWAR" */ + goto fail; + + switch (read_32bitBE(offset+4,streamFile)) + { + case 0xFEFF0100: + if ((uint32_t)read_32bitBE(offset+0x60,streamFile)!=0x52574156) /* "RWAV" */ + goto fail; + + wave_offset = offset+0x78; + *version = 0; + + break; + default: + goto fail; + } + + return wave_offset; +fail: + return -1; +} + /* RWSD is quite similar to BRSTM, but can contain several streams. * Still, some games use it for single streams. We only support the * single stream form here */ @@ -16,6 +41,7 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) { int codec_number; int channel_count; int loop_flag; + int rwar = 0; int version = -1; off_t start_offset; @@ -23,45 +49,56 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) { /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("rwsd",filename_extension(filename))) goto fail; + if (strcasecmp("rwsd",filename_extension(filename))) + { + if (strcasecmp("rwar",filename_extension(filename))) + goto fail; + else + rwar = 1; + } /* check header */ - if ((uint32_t)read_32bitBE(0,streamFile)!=0x52575344) /* "RWSD" */ - goto fail; - - switch (read_32bitBE(4,streamFile)) + if (rwar) { - case 0xFEFF0102: - /* ideally we would look through the chunk list for a WAVE chunk, - * but it's always in the same order */ - /* get WAVE offset, check */ - wave_offset = read_32bitBE(0x18,streamFile); - if ((uint32_t)read_32bitBE(wave_offset,streamFile)!=0x57415645) /* "WAVE" */ - goto fail; - /* get WAVE size, check */ - wave_length = read_32bitBE(0x1c,streamFile); - if (read_32bitBE(wave_offset+4,streamFile)!=wave_length) - goto fail; + wave_offset = read_rwar(0,&version,streamFile); + if (wave_offset < 0) goto fail; + } + else + { + if ((uint32_t)read_32bitBE(0,streamFile)!=0x52575344) /* "RWSD" */ + goto fail; - /* check wave count */ - if (read_32bitBE(wave_offset+8,streamFile) != 1) - goto fail; /* only support 1 */ - - version = 2; - - break; - case 0xFEFF0103: - { - if ((uint32_t)read_32bitBE(0x140,streamFile)!=0x52574156) /* "RWAV" */ + switch (read_32bitBE(4,streamFile)) + { + case 0xFEFF0102: + /* ideally we would look through the chunk list for a WAVE chunk, + * but it's always in the same order */ + /* get WAVE offset, check */ + wave_offset = read_32bitBE(0x18,streamFile); + if ((uint32_t)read_32bitBE(wave_offset,streamFile)!=0x57415645) /* "WAVE" */ + goto fail; + /* get WAVE size, check */ + wave_length = read_32bitBE(0x1c,streamFile); + if (read_32bitBE(wave_offset+4,streamFile)!=wave_length) goto fail; - wave_offset = 0x158; + /* check wave count */ + if (read_32bitBE(wave_offset+8,streamFile) != 1) + goto fail; /* only support 1 */ + + version = 2; + + break; + case 0xFEFF0103: + wave_offset = read_rwar(0xe0,&version,streamFile); + if (wave_offset < 0) goto fail; + + rwar = 1; + break; + default: + goto fail; + } - version = 3; - } - break; - default: - goto fail; } /* get type details */ @@ -100,7 +137,10 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) { vgmstream->coding_type = coding_type; vgmstream->layout_type = layout_none; - vgmstream->meta_type = meta_RWSD; + if (rwar) + vgmstream->meta_type = meta_RWAR; + else + vgmstream->meta_type = meta_RWSD; if (vgmstream->coding_type == coding_NGC_DSP) { off_t coef_offset; @@ -115,10 +155,16 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) { } } - if (version == 2) - start_offset = read_32bitBE(8,streamFile); + if (rwar) + { + if (version == 0) + start_offset = wave_offset + 0xF0; + } else - start_offset = 0x248; + { + if (version == 2) + start_offset = read_32bitBE(8,streamFile); + } stream_size = read_32bitBE(wave_offset+0x50,streamFile); /* open the file for reading by each channel */ diff --git a/src/vgmstream.c b/src/vgmstream.c index 53ac3728..1157b136 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -1476,6 +1476,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) { case meta_RWSD: snprintf(temp,TEMPSIZE,"Nintendo RWSD header (single stream)"); break; + case meta_RWAR: + snprintf(temp,TEMPSIZE,"Nintendo RWAR header (single stream)"); + break; case meta_PSX_XA: snprintf(temp,TEMPSIZE,"RIFF/CDXA header"); break; diff --git a/src/vgmstream.h b/src/vgmstream.h index 7389b8fb..5355aba3 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -169,6 +169,7 @@ typedef enum { meta_AFC, /* AFC */ meta_AST, /* AST */ meta_RWSD, /* single-stream RWSD */ + meta_RWAR, /* single-stream RWAR */ meta_RSTM_SPM, /* RSTM with 44->22khz hack */ meta_THP, diff --git a/unix/data.c b/unix/data.c index c0b751f4..6b1c4b20 100644 --- a/unix/data.c +++ b/unix/data.c @@ -155,6 +155,7 @@ gchar *vgmstream_exts [] = { "smp", "emff", "thp", + "rwar", /* terminator */ NULL };