mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-17 19:19:16 +01:00
FFXI (PC) .bgw
git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@462 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
parent
dd5095b3e5
commit
35409b1c40
@ -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)
|
||||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -227,6 +227,10 @@
|
||||
RelativePath=".\meta\ast.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\bgw.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\brstm.c"
|
||||
>
|
||||
|
@ -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
70
src/meta/bgw.c
Normal 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;
|
||||
}
|
@ -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
|
||||
|
@ -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");
|
||||
}
|
||||
|
@ -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 {
|
||||
|
@ -131,6 +131,7 @@ gchar *vgmstream_exts [] = {
|
||||
"pdt",
|
||||
"asd",
|
||||
"spsd",
|
||||
"bgw",
|
||||
/* terminator */
|
||||
NULL
|
||||
};
|
||||
|
@ -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) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user