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); } } }