FFXI (PC) .bgw

git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@462 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
halleyscometsw 2008-11-06 23:30:33 +00:00
parent dd5095b3e5
commit 35409b1c40
11 changed files with 152 additions and 3 deletions

View File

@ -140,9 +140,10 @@ META_OBJS=meta/adx_header.o \
meta/psx_fag.o \
meta/ps2_mihb.o \
meta/ngc_pdt.o \
meta/wii_mus.o \
meta/dc_asd.o \
meta/naomi_spsd.o
meta/wii_mus.o \
meta/dc_asd.o \
meta/naomi_spsd.o \
meta/bgw.o
OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS)

View File

@ -37,6 +37,8 @@ void decode_invert_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelsp
void decode_psx_badflags(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_ffxi_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
void decode_xa(VGMSTREAM * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel);
void init_get_high_nibble(VGMSTREAM * vgmstream);

View File

@ -7,6 +7,11 @@ double VAG_f[5][2] = { { 0.0 , 0.0 },
{ 115.0 / 64.0 , -52.0 / 64.0 },
{ 98.0 / 64.0 , -55.0 / 64.0 } ,
{ 122.0 / 64.0 , -60.0 / 64.0 } } ;
long VAG_coefs[5][2] = { { 0 , 0 },
{ 60 , 0 },
{ 115 , -52 },
{ 98 , -55 } ,
{ 122 , -60 } } ;
void decode_psx(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
@ -130,3 +135,47 @@ void decode_psx_badflags(VGMSTREAMCHANNEL * stream, sample * outbuf, int channel
stream->adpcm_history2_32=hist2;
}
/* FF XI's Vag-ish format */
void decode_ffxi_adpcm(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do) {
int predict_nr, shift_factor, sample;
int32_t hist1=stream->adpcm_history1_32;
int32_t hist2=stream->adpcm_history2_32;
short scale;
int i;
int32_t sample_count;
long predictor;
int framesin = first_sample/16;
predict_nr = read_8bit(stream->offset+framesin*9,stream->streamfile) >> 4;
shift_factor = read_8bit(stream->offset+framesin*9,stream->streamfile) & 0xf;
first_sample = first_sample % 16;
for (i=first_sample,sample_count=0; i<first_sample+samples_to_do; i++,sample_count+=channelspacing) {
short sample_byte = (short)read_8bit(stream->offset+(framesin*9)+1+i/2,stream->streamfile);
sample=0;
scale = ((i&1 ?
sample_byte >> 4 :
sample_byte & 0x0f)<<12);
#if 1
predictor =
(int)((hist1*VAG_f[predict_nr][0]+hist2*VAG_f[predict_nr][1]));
#else
predictor =
(hist1*VAG_coefs[predict_nr][0]+hist2*VAG_coefs[predict_nr][1])/64;
#endif
sample=(scale >> shift_factor) + predictor;
outbuf[sample_count] = clamp16(sample);
hist2=hist1;
hist1=sample;
}
stream->adpcm_history1_32=hist1;
stream->adpcm_history2_32=hist2;
}

View File

@ -227,6 +227,10 @@
RelativePath=".\meta\ast.c"
>
</File>
<File
RelativePath=".\meta\bgw.c"
>
</File>
<File
RelativePath=".\meta\brstm.c"
>

View File

@ -111,4 +111,5 @@ libmeta_la_SOURCES += ngc_pdt.c
libmeta_la_SOURCES += wii_mus.c
libmeta_la_SOURCES += dc_asd.c
libmeta_la_SOURCES += naomi_spsd.c
libmeta_la_SOURCES += bgw.c
EXTRA_DIST = meta.h

70
src/meta/bgw.c Normal file
View File

@ -0,0 +1,70 @@
#include "meta.h"
#include "../util.h"
/* BGW (FF XI) */
VGMSTREAM * init_vgmstream_bgw(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
char filename[260];
off_t start_offset;
int loop_flag = 0;
int channel_count;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("bgw",filename_extension(filename))) goto fail;
/* "BGMStream" */
if (read_32bitBE(0,streamFile) != 0x42474d53 ||
read_32bitBE(4,streamFile) != 0x74726561 ||
read_32bitBE(8,streamFile) != 0x6d000000 |
read_32bitBE(12,streamFile) != 0) goto fail;
/* check file size with header value */
if (read_32bitLE(0x10,streamFile) != get_streamfile_size(streamFile))
goto fail;
channel_count = 2;
loop_flag = read_32bitLE(0x1c,streamFile) != 0;
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
start_offset = 0x30;
vgmstream->channels = channel_count;
vgmstream->sample_rate = 44100;
vgmstream->coding_type = coding_FFXI;
vgmstream->num_samples = read_32bitLE(0x18,streamFile)*16;
if (loop_flag) {
vgmstream->loop_start_sample = (read_32bitLE(0x1c,streamFile)-1)*16;
vgmstream->loop_end_sample = vgmstream->num_samples;
}
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = 9;
vgmstream->meta_type = meta_FFXI_BGW;
/* open the file for reading */
{
int i;
STREAMFILE * file;
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!file) goto fail;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = file;
vgmstream->ch[i].channel_start_offset=
vgmstream->ch[i].offset=start_offset+i*9;
}
}
return vgmstream;
/* clean up anything we may have opened */
fail:
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -257,4 +257,6 @@ VGMSTREAM * init_vgmstream_dc_asd(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_naomi_spsd(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_bgw(STREAMFILE * streamFile);
#endif

View File

@ -145,6 +145,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
init_vgmstream_rsd6vag,
init_vgmstream_rsd6wadp,
init_vgmstream_rsd6xadp,
init_vgmstream_bgw,
};
#define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0]))
@ -566,6 +567,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM * vgmstream) {
case coding_AICA:
return 2;
case coding_NGC_AFC:
case coding_FFXI:
return 16;
case coding_PSX:
case coding_PSX_badflags:
@ -631,6 +633,7 @@ int get_vgmstream_frame_size(VGMSTREAM * vgmstream) {
case coding_G721:
return 0;
case coding_NGC_AFC:
case coding_FFXI:
return 9;
case coding_PSX:
case coding_PSX_badflags:
@ -796,6 +799,13 @@ void decode_vgmstream(VGMSTREAM * vgmstream, int samples_written, int samples_to
vgmstream->channels,vgmstream->samples_into_block,
samples_to_do);
}
break;
case coding_FFXI:
for (chan=0;chan<vgmstream->channels;chan++) {
decode_ffxi_adpcm(&vgmstream->ch[chan],buffer+samples_written*vgmstream->channels+chan,
vgmstream->channels,vgmstream->samples_into_block,
samples_to_do);
}
break;
case coding_XA:
for (chan=0;chan<vgmstream->channels;chan++) {
@ -1132,6 +1142,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
case coding_invert_PSX:
snprintf(temp,TEMPSIZE,"Inverted (?) Playstation 4-bit ADPCM");
break;
case coding_FFXI:
snprintf(temp,TEMPSIZE,"FFXI Playstation-ish 4-bit ADPCM");
break;
case coding_XA:
snprintf(temp,TEMPSIZE,"CD-ROM XA 4-bit ADPCM");
break;
@ -1750,6 +1763,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
case meta_NAOMI_SPSD:
snprintf(temp,TEMPSIZE,"SPSD Header");
break;
case meta_FFXI_BGW:
snprintf(temp,TEMPSIZE,"BGW BGMStream header");
break;
default:
snprintf(temp,TEMPSIZE,"THEY SHOULD HAVE SENT A POET");
}

View File

@ -48,6 +48,7 @@ typedef enum {
coding_PSX, /* PSX & PS2 ADPCM */
coding_invert_PSX, /* PSX ADPCM with first byte of frame inverted */
coding_PSX_badflags, /* with garbage in the flags byte */
coding_FFXI, /* FF XI PSX-ish ADPCM */
coding_XA, /* PSX CD-XA */
coding_XBOX, /* XBOX IMA */
coding_EAXA, /* EA/XA ADPCM */
@ -303,6 +304,7 @@ typedef enum {
meta_ACM, /* InterPlay ACM header */
meta_MUS_ACM, /* MUS playlist of InterPlay ACM files */
meta_DE2, /* Falcom (Gurumin) .de2 */
meta_FFXI_BGW, /* FFXI BGW */
} meta_t;
typedef struct {

View File

@ -131,6 +131,7 @@ gchar *vgmstream_exts [] = {
"pdt",
"asd",
"spsd",
"bgw",
/* terminator */
NULL
};

View File

@ -192,6 +192,7 @@ char * extension_list[] = {
"pdt\0PDT Audio File (*.PDT)\0",
"asd\0ASD Audio File (*.ASD)\0",
"spsd\0SPSD Audio File (*.SPSD)\0",
"bgw\0BGW Audio File (*.BGW)\0",
};
void about(HWND hwndParent) {