diff --git a/src/layout/xa_blocked.c b/src/layout/xa_blocked.c
index b9678968..0775a036 100644
--- a/src/layout/xa_blocked.c
+++ b/src/layout/xa_blocked.c
@@ -8,14 +8,13 @@ void xa_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
uint8_t currentChannel=0;
uint8_t subAudio=0;
- // i used interleave_block_size to check sector read length
if(vgmstream->samples_into_block!=0)
// don't change this variable in the init process
- vgmstream->interleave_block_size+=128;
+ vgmstream->xa_sector_length+=128;
// We get to the end of a sector ?
- if(vgmstream->interleave_block_size==(18*128)) {
- vgmstream->interleave_block_size=0;
+ if(vgmstream->xa_sector_length==(18*128)) {
+ vgmstream->xa_sector_length=0;
// 0x30 of unused bytes/sector :(
block_offset+=0x30;
diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj
index f48e1eda..f8d21b3d 100644
--- a/src/libvgmstream.vcproj
+++ b/src/libvgmstream.vcproj
@@ -250,6 +250,10 @@
RelativePath=".\meta\ps2_npsf.c"
>
+
+
diff --git a/src/meta/meta.h b/src/meta/meta.h
index 5e674cde..d2687cae 100644
--- a/src/meta/meta.h
+++ b/src/meta/meta.h
@@ -37,4 +37,6 @@ VGMSTREAM * init_vgmstream_rwsd(const char * const filename);
VGMSTREAM * init_vgmstream_cdxa(const char * const filename);
+VGMSTREAM * init_vgmstream_ps2_rxw(const char * const filename);
+
#endif
diff --git a/src/meta/ps2_rxw.c b/src/meta/ps2_rxw.c
new file mode 100644
index 00000000..3864d1ef
--- /dev/null
+++ b/src/meta/ps2_rxw.c
@@ -0,0 +1,79 @@
+#include "meta.h"
+#include "../util.h"
+
+/* RXW file (Arc the Lad) */
+
+VGMSTREAM * init_vgmstream_ps2_rxw(const char * const filename) {
+ VGMSTREAM * vgmstream = NULL;
+ STREAMFILE * infile = NULL;
+
+ int loop_flag=0;
+ int channel_count;
+ off_t start_offset;
+ int i;
+
+ /* check extension, case insensitive */
+ if (strcasecmp("rxw",filename_extension(filename))) goto fail;
+
+ /* try to open the file for header reading */
+ infile = open_streamfile(filename);
+ if (!infile) goto fail;
+
+ /* check NPSF Header */
+ if (!((read_32bitBE(0x00,infile) == 0x52585753) &&
+ (read_32bitBE(0x10,infile) == 0x464F524D)))
+ goto fail;
+
+ /* check loop */
+ loop_flag = (read_32bitLE(0x3C,infile)!=0xFFFFFFFF);
+
+ /* Always stereo files */
+ channel_count=2;
+
+ /* 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_32bitLE(0x2E,infile);
+
+ /* Check for Compression Scheme */
+ vgmstream->coding_type = coding_PSX;
+ vgmstream->num_samples = (read_32bitLE(0x38,infile)*28/16)/2;
+
+ /* Get loop point values */
+ if(vgmstream->loop_flag) {
+ vgmstream->loop_start_sample = read_32bitLE(0x3C,infile)/16*14;
+ vgmstream->loop_end_sample = read_32bitLE(0x38,infile)/16*14;
+ }
+
+ vgmstream->interleave_block_size = read_32bitLE(0x1c,infile)+0x10;
+ vgmstream->layout_type = layout_interleave;
+ vgmstream->meta_type = meta_PS2_RXW;
+
+ start_offset = 0x40;
+
+ close_streamfile(infile); infile=NULL;
+
+ /* open the file for reading by each channel */
+ {
+ for (i=0;ich[i].streamfile = open_streamfile_buffer(filename,0x8000);
+
+ if (!vgmstream->ch[i].streamfile) goto fail;
+
+ 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 (infile) close_streamfile(infile);
+ if (vgmstream) close_vgmstream(vgmstream);
+ return NULL;
+}
diff --git a/src/vgmstream.c b/src/vgmstream.c
index bf72999d..112a5c53 100644
--- a/src/vgmstream.c
+++ b/src/vgmstream.c
@@ -15,7 +15,7 @@
* List of functions that will recognize files. These should correspond pretty
* directly to the metadata types
*/
-#define INIT_VGMSTREAM_FCNS 17
+#define INIT_VGMSTREAM_FCNS 18
VGMSTREAM * (*init_vgmstream_fcns[INIT_VGMSTREAM_FCNS])(const char * const) = {
init_vgmstream_adx,
init_vgmstream_brstm,
@@ -34,6 +34,7 @@ VGMSTREAM * (*init_vgmstream_fcns[INIT_VGMSTREAM_FCNS])(const char * const) = {
init_vgmstream_ps2_npsf,
init_vgmstream_rwsd,
init_vgmstream_cdxa,
+ init_vgmstream_ps2_rxw,
};
@@ -217,7 +218,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
case coding_PSX:
return 16;
case coding_XA:
- return 28;
+ return 14*vgmstream->channels;
default:
return 0;
}
@@ -362,6 +363,8 @@ int vgmstream_do_loop(VGMSTREAM * vgmstream) {
for (i=0;ichannels;i++) {
vgmstream->loop_ch[i].adpcm_history1_16 = vgmstream->ch[i].adpcm_history1_16;
vgmstream->loop_ch[i].adpcm_history2_16 = vgmstream->ch[i].adpcm_history2_16;
+ vgmstream->loop_ch[i].adpcm_history1_32 = vgmstream->ch[i].adpcm_history1_32;
+ vgmstream->loop_ch[i].adpcm_history2_32 = vgmstream->ch[i].adpcm_history2_32;
}
}
#if DEBUG
@@ -583,6 +586,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
break;
case meta_PSX_XA:
snprintf(temp,TEMPSIZE,"RIFF/CDXA Header");
+ break;
+ case meta_PS2_RXW:
+ snprintf(temp,TEMPSIZE,"RXWS File (Arc The Lad)");
break;
default:
snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET");
diff --git a/src/vgmstream.h b/src/vgmstream.h
index 624dd91a..8f8e35d7 100644
--- a/src/vgmstream.h
+++ b/src/vgmstream.h
@@ -76,8 +76,10 @@ typedef enum {
meta_PS2_SShd, /* .ADS with SShd header */
meta_PS2_NPSF, /* Namco Production Sound File */
+ meta_PS2_RXW, /* Sony Arc The Lad Sound File */
+
+ meta_PSX_XA, /* CD-XA with RIFF header */
- meta_PSX_XA,
} meta_t;
typedef struct {
@@ -156,6 +158,7 @@ typedef struct {
off_t loop_next_block_offset; /* saved from next_block_offset */
uint8_t xa_channel; /* Selected XA Channel */
+ int32_t xa_sector_length; /* XA block */
} VGMSTREAM;
/* do format detection, return pointer to a usable VGMSTREAM, or NULL on failure */
diff --git a/winamp/in_vgmstream.c b/winamp/in_vgmstream.c
index d903e284..4fdd3128 100644
--- a/winamp/in_vgmstream.c
+++ b/winamp/in_vgmstream.c
@@ -45,7 +45,7 @@ int fade_samples = 0;
#define EXTENSION_LIST_SIZE 1024
char working_extension_list[EXTENSION_LIST_SIZE] = {0};
-#define EXTENSION_COUNT 16
+#define EXTENSION_COUNT 17
char * extension_list[EXTENSION_COUNT] = {
"adx\0ADX Audio File (*.ADX)\0",
"afc\0AFC Audio File (*.AFC)\0",
@@ -63,6 +63,7 @@ char * extension_list[EXTENSION_COUNT] = {
"npsf\0PS2 NPSF Audio File (*.NPSF)\0",
"rwsd\0RWSD Audio File (*.RWSD)\0",
"xa\0PSX CD-XA File (*.XA)\0",
+ "rxw\0PS2 RXWS File (*.RXW)\0",
};
/* stubs, we don't do anything fancy yet */
@@ -139,7 +140,7 @@ int play(char *fn)
decode_pos_samples = 0;
paused = 0;
stream_length_samples = get_vgmstream_play_samples(loop_count,fade_seconds,vgmstream);
- fade_samples = fade_seconds * vgmstream->sample_rate;
+ fade_samples = (int)(fade_seconds * vgmstream->sample_rate);
decode_thread_handle = CreateThread(
NULL, /* handle cannot be inherited */
@@ -296,7 +297,7 @@ DWORD WINAPI __stdcall decode(void *arg) {
double fadedness = (double)(fade_samples-samples_into_fade)/fade_samples;
for (k=0;kchannels;k++) {
sample_buffer[j*vgmstream->channels+k] =
- sample_buffer[j*vgmstream->channels+k]*fadedness;
+ (short)(sample_buffer[j*vgmstream->channels+k]*fadedness);
}
}
}