mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-12 01:30:49 +01:00
rwav and improved rwar support in rwsd
git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@563 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
parent
85d14007c7
commit
48075dedd6
@ -186,7 +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)
|
||||
- .rwar,.rwav (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, Procyon Studios NDS ADPCM)
|
||||
|
102
src/meta/rwsd.c
102
src/meta/rwsd.c
@ -2,27 +2,46 @@
|
||||
#include "../coding/coding.h"
|
||||
#include "../util.h"
|
||||
|
||||
static off_t read_rwar(off_t offset, int *version, STREAMFILE *streamFile)
|
||||
static off_t read_rwav(off_t offset, int *version, off_t *start_offset, off_t *info_chunkp, STREAMFILE *streamFile)
|
||||
{
|
||||
off_t info_chunk;
|
||||
off_t data_chunk;
|
||||
off_t wave_offset;
|
||||
|
||||
if ((uint32_t)read_32bitBE(offset,streamFile)!=0x52574156) /* "RWAV" */
|
||||
goto fail;
|
||||
if ((uint32_t)read_32bitBE(offset+4,streamFile)!=0xFEFF0102) /* version 2 */
|
||||
goto fail;
|
||||
|
||||
info_chunk = offset+read_32bitBE(offset+0x10,streamFile);
|
||||
if ((uint32_t)read_32bitBE(info_chunk,streamFile)!=0x494e464f) /* "INFO" */
|
||||
goto fail;
|
||||
data_chunk = offset+read_32bitBE(offset+0x18,streamFile);
|
||||
if ((uint32_t)read_32bitBE(data_chunk,streamFile)!=0x44415441) /* "DATA" */
|
||||
goto fail;
|
||||
|
||||
*start_offset = data_chunk + 8;
|
||||
*info_chunkp = info_chunk + 8;
|
||||
*version = 2;
|
||||
wave_offset = info_chunk - 8;
|
||||
|
||||
return wave_offset;
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
|
||||
static off_t read_rwar(off_t offset, int *version, off_t *start_offset, off_t *info_chunk, STREAMFILE *streamFile)
|
||||
{
|
||||
off_t wave_offset;
|
||||
if ((uint32_t)read_32bitBE(offset,streamFile)!=0x52574152) /* "RWAR" */
|
||||
goto fail;
|
||||
if ((uint32_t)read_32bitBE(offset+4,streamFile)!=0xFEFF0100) /* version 0 */
|
||||
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;
|
||||
}
|
||||
|
||||
wave_offset = read_rwav(offset+0x60,version,start_offset,info_chunk,streamFile);
|
||||
*version = 0;
|
||||
return wave_offset;
|
||||
|
||||
fail:
|
||||
return -1;
|
||||
}
|
||||
@ -36,12 +55,14 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
||||
|
||||
coding_t coding_type;
|
||||
|
||||
off_t info_chunk;
|
||||
off_t wave_offset;
|
||||
size_t wave_length;
|
||||
int codec_number;
|
||||
int channel_count;
|
||||
int loop_flag;
|
||||
int rwar = 0;
|
||||
int rwav = 0;
|
||||
int version = -1;
|
||||
|
||||
off_t start_offset = 0;
|
||||
@ -52,15 +73,31 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
||||
if (strcasecmp("rwsd",filename_extension(filename)))
|
||||
{
|
||||
if (strcasecmp("rwar",filename_extension(filename)))
|
||||
goto fail;
|
||||
{
|
||||
if (strcasecmp("rwav",filename_extension(filename)))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
else
|
||||
{
|
||||
rwav = 1;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rwar = 1;
|
||||
}
|
||||
}
|
||||
|
||||
/* check header */
|
||||
if (rwar)
|
||||
{
|
||||
wave_offset = read_rwar(0,&version,streamFile);
|
||||
wave_offset = read_rwar(0,&version,&start_offset,&info_chunk,streamFile);
|
||||
if (wave_offset < 0) goto fail;
|
||||
}
|
||||
else if (rwav)
|
||||
{
|
||||
wave_offset = read_rwav(0,&version,&start_offset,&info_chunk,streamFile);
|
||||
if (wave_offset < 0) goto fail;
|
||||
}
|
||||
else
|
||||
@ -90,7 +127,7 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
||||
|
||||
break;
|
||||
case 0xFEFF0103:
|
||||
wave_offset = read_rwar(0xe0,&version,streamFile);
|
||||
wave_offset = read_rwar(0xe0,&version,&start_offset,&info_chunk,streamFile);
|
||||
if (wave_offset < 0) goto fail;
|
||||
|
||||
rwar = 1;
|
||||
@ -139,6 +176,8 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
||||
|
||||
if (rwar)
|
||||
vgmstream->meta_type = meta_RWAR;
|
||||
else if (rwav)
|
||||
vgmstream->meta_type = meta_RWAV;
|
||||
else
|
||||
vgmstream->meta_type = meta_RWSD;
|
||||
|
||||
@ -146,19 +185,34 @@ VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
|
||||
off_t coef_offset;
|
||||
int i,j;
|
||||
|
||||
coef_offset=0x6c;
|
||||
|
||||
for (j=0;j<vgmstream->channels;j++) {
|
||||
if (rwar || rwav)
|
||||
{
|
||||
/* This is pretty nasty, so an explaination is in order.
|
||||
* At 0x10 in the info_chunk is the offset of a table with
|
||||
* one entry per channel. Each entry in this table is itself
|
||||
* an offset to a set of information for the channel. The
|
||||
* first element in the set is the offset into DATA of the
|
||||
* channel. The stream_size read far below just happens to
|
||||
* hit on this properly for stereo. The second element is the
|
||||
* offset of the coefficient table for the channel. */
|
||||
coef_offset = info_chunk +
|
||||
read_32bitBE(info_chunk +
|
||||
read_32bitBE(info_chunk+
|
||||
read_32bitBE(info_chunk+0x10,streamFile)+j*4,
|
||||
streamFile) + 4, streamFile);
|
||||
} else {
|
||||
coef_offset=wave_offset+0x6c+j*0x30;
|
||||
}
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[j].adpcm_coef[i]=read_16bitBE(wave_offset+coef_offset+j*0x30+i*2,streamFile);
|
||||
vgmstream->ch[j].adpcm_coef[i]=read_16bitBE(coef_offset+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (rwar)
|
||||
if (rwar || rwav)
|
||||
{
|
||||
if (version == 0)
|
||||
start_offset = wave_offset + 0xF0;
|
||||
/* */
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -1565,7 +1565,10 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||
snprintf(temp,TEMPSIZE,"Nintendo RWSD header (single stream)");
|
||||
break;
|
||||
case meta_RWAR:
|
||||
snprintf(temp,TEMPSIZE,"Nintendo RWAR header (single stream)");
|
||||
snprintf(temp,TEMPSIZE,"Nintendo RWAR header (single RWAV stream)");
|
||||
break;
|
||||
case meta_RWAV:
|
||||
snprintf(temp,TEMPSIZE,"Nintendo RWAV header");
|
||||
break;
|
||||
case meta_PSX_XA:
|
||||
snprintf(temp,TEMPSIZE,"RIFF/CDXA header");
|
||||
|
@ -174,6 +174,7 @@ typedef enum {
|
||||
meta_AST, /* AST */
|
||||
meta_RWSD, /* single-stream RWSD */
|
||||
meta_RWAR, /* single-stream RWAR */
|
||||
meta_RWAV, /* contents of RWAR */
|
||||
meta_RSTM_SPM, /* RSTM with 44->22khz hack */
|
||||
meta_THP,
|
||||
meta_RSTM_shrunken, /* Atlus' mutant shortened RSTM */
|
||||
|
@ -160,6 +160,7 @@ gchar *vgmstream_exts [] = {
|
||||
"mwv",
|
||||
"gbts",
|
||||
"p2bt",
|
||||
"rwav",
|
||||
/* terminator */
|
||||
NULL
|
||||
};
|
||||
|
@ -222,6 +222,7 @@ char * extension_list[] = {
|
||||
"gbts\0GBTS Audio File (*.GBTS)\0",
|
||||
"aax\0AAX Audio File (*.AAX)\0",
|
||||
"mwv\0MWV Audio File (*.MWV)\0",
|
||||
"rwav\0RWAV Audio File (*.RWAV)\0",
|
||||
};
|
||||
|
||||
void about(HWND hwndParent) {
|
||||
|
Loading…
Reference in New Issue
Block a user