mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-31 04:13:47 +01:00
just fixes
git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@788 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
parent
637ff7d24f
commit
c6f5c886e9
11
src/Makefile
11
src/Makefile
@ -46,7 +46,8 @@ LAYOUT_OBJS=layout/ast_blocked.o \
|
||||
layout/aax_layout.o \
|
||||
layout/ivaud_layout.o \
|
||||
layout/mxch_blocked.o \
|
||||
layout/psx_mgav_blocked.o
|
||||
layout/psx_mgav_blocked.o \
|
||||
layout/ps2_adm_blocked.o
|
||||
|
||||
META_OBJS=meta/adx_header.o \
|
||||
meta/afc_header.o \
|
||||
@ -195,7 +196,6 @@ META_OBJS=meta/adx_header.o \
|
||||
meta/redspark.o \
|
||||
meta/ps2_vgs.o \
|
||||
meta/ivaud.o \
|
||||
meta/wii_ndp.o \
|
||||
meta/ps2_sps.o \
|
||||
meta/nds_hwas.o \
|
||||
meta/ngc_lps.o \
|
||||
@ -222,8 +222,7 @@ META_OBJS=meta/adx_header.o \
|
||||
meta/his.o \
|
||||
meta/ps2_ast.o \
|
||||
meta/dmsg_segh.o \
|
||||
meta/ngc_aaap.o \
|
||||
meta/ngc_dsp_tmnt2.o \
|
||||
meta/ngc_dsp_konami.o \
|
||||
meta/ps2_ster.o \
|
||||
meta/ps2_wb.o \
|
||||
meta/bnsf.o \
|
||||
@ -239,6 +238,10 @@ META_OBJS=meta/adx_header.o \
|
||||
meta/ngc_dsp_mpds.o \
|
||||
meta/ps2_khv.o \
|
||||
meta/ps2_voi.o \
|
||||
meta/dsp_sth_str.o \
|
||||
meta/ps2_b1s.o \
|
||||
meta/ps2_wad.o
|
||||
meta/ps2_voi.o \
|
||||
meta/ps2_lpcm.o
|
||||
|
||||
OBJECTS=vgmstream.o streamfile.o util.o $(CODING_OBJS) $(LAYOUT_OBJS) $(META_OBJS)
|
||||
|
@ -31,5 +31,6 @@ liblayout_la_SOURCES += aax_layout.c
|
||||
liblayout_la_SOURCES += ivaud_layout.c
|
||||
liblayout_la_SOURCES += mxch_blocked.c
|
||||
liblayout_la_SOURCES += psx_mgav_blocked.c
|
||||
liblayout_la_SOURCES += ps2_adm_blocked.c
|
||||
|
||||
EXTRA_DIST = layout.h
|
||||
|
@ -115,6 +115,9 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM *
|
||||
case layout_psx_mgav_blocked:
|
||||
psx_mgav_block_update(vgmstream->next_block_offset,vgmstream);
|
||||
break;
|
||||
case layout_ps2_adm_blocked:
|
||||
ps2_adm_block_update(vgmstream->next_block_offset,vgmstream);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
@ -60,4 +60,6 @@ void render_vgmstream_aax(sample * buffer, int32_t sample_count, VGMSTREAM * vgm
|
||||
|
||||
void psx_mgav_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
|
||||
void ps2_adm_block_update(off_t block_offset, VGMSTREAM * vgmstream);
|
||||
|
||||
#endif
|
||||
|
18
src/layout/ps2_adm_blocked.c
Normal file
18
src/layout/ps2_adm_blocked.c
Normal file
@ -0,0 +1,18 @@
|
||||
#include "layout.h"
|
||||
#include "../vgmstream.h"
|
||||
|
||||
/* set up for the block at the given offset */
|
||||
void ps2_adm_block_update(off_t block_offset, VGMSTREAM * vgmstream) {
|
||||
int i;
|
||||
|
||||
vgmstream->current_block_offset = block_offset;
|
||||
vgmstream->current_block_size = 0x1000; /*read_32bitLE(
|
||||
vgmstream->current_block_offset+0x10,
|
||||
vgmstream->ch[0].streamfile); */
|
||||
vgmstream->next_block_offset = vgmstream->current_block_offset + vgmstream->current_block_size;
|
||||
//vgmstream->current_block_size/=vgmstream->channels;
|
||||
|
||||
for (i=0;i<vgmstream->channels;i++) {
|
||||
vgmstream->ch[i].offset = vgmstream->current_block_offset+(0x400*i);
|
||||
}
|
||||
}
|
@ -292,6 +292,10 @@
|
||||
RelativePath=".\meta\dmsg_segh.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\dsp_sth_str.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ea_header.c"
|
||||
>
|
||||
@ -430,10 +434,6 @@
|
||||
RelativePath=".\meta\nds_swav.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ngc_aaap.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ngc_adpdtk.c"
|
||||
>
|
||||
@ -450,6 +450,10 @@
|
||||
RelativePath=".\meta\ngc_caf.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ngc_dsp_konami.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ngc_dsp_mpds.c"
|
||||
>
|
||||
@ -458,10 +462,6 @@
|
||||
RelativePath=".\meta\ngc_dsp_std.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ngc_dsp_tmnt2.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ngc_dsp_ygo.c"
|
||||
>
|
||||
@ -538,6 +538,10 @@
|
||||
RelativePath=".\meta\pos.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ps2_adm.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ps2_ads.c"
|
||||
>
|
||||
@ -558,6 +562,10 @@
|
||||
RelativePath=".\meta\ps2_aus.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ps2_b1s.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ps2_bg00.c"
|
||||
>
|
||||
@ -758,6 +766,10 @@
|
||||
RelativePath=".\meta\ps2_vpk.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ps2_wad.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\ps2_wb.c"
|
||||
>
|
||||
@ -902,10 +914,6 @@
|
||||
RelativePath=".\meta\wii_mus.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\wii_ndp.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\meta\wii_smp.c"
|
||||
>
|
||||
@ -1182,6 +1190,10 @@
|
||||
RelativePath=".\layout\nolayout.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\layout\ps2_adm_blocked.c"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\layout\psx_mgav_blocked.c"
|
||||
>
|
||||
|
@ -150,7 +150,6 @@ libmeta_la_SOURCES += ps2_mcg.c
|
||||
libmeta_la_SOURCES += redspark.c
|
||||
libmeta_la_SOURCES += ivaud.c
|
||||
libmeta_la_SOURCES += ps2_vgs.c
|
||||
libmeta_la_SOURCES += wii_ndp.c
|
||||
libmeta_la_SOURCES += ps2_sps.c
|
||||
libmeta_la_SOURCES += nds_hwas.c
|
||||
libmeta_la_SOURCES += ngc_lps.c
|
||||
@ -177,8 +176,7 @@ libmeta_la_SOURCES += myspd.c
|
||||
libmeta_la_SOURCES += his.c
|
||||
libmeta_la_SOURCES += ps2_ast.c
|
||||
libmeta_la_SOURCES += dmsg_segh.c
|
||||
libmeta_la_SOURCES += ngc_aaap.c
|
||||
libmeta_la_SOURCES += ngc_dsp_tmnt2.c
|
||||
libmeta_la_SOURCES += ngc_dsp_konami.c
|
||||
libmeta_la_SOURCES += ps2_ster.c
|
||||
libmeta_la_SOURCES += bnsf.c
|
||||
libmeta_la_SOURCES += ps2_wb.c
|
||||
@ -194,6 +192,9 @@ libmeta_la_SOURCES += ngc_bo2.c
|
||||
libmeta_la_SOURCES += ngc_dsp_mpds.c
|
||||
libmeta_la_SOURCES += ps2_khv.c
|
||||
libmeta_la_SOURCES += ps2_voi.c
|
||||
libmeta_la_SOURCES += dsp_sth_str.c
|
||||
libmeta_la_SOURCES += ps2_b1s.c
|
||||
libmeta_la_SOURCES += ps2_wad.c
|
||||
libmeta_la_SOURCES += ps2_lpcm.c
|
||||
|
||||
EXTRA_DIST = meta.h
|
||||
|
320
src/meta/dsp_sth_str.c
Normal file
320
src/meta/dsp_sth_str.c
Normal file
@ -0,0 +1,320 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/*
|
||||
STH+STR
|
||||
found in SpongebobSquarepants: Creature From The Krusty Krab (NGC)
|
||||
*/
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_sth_str1(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
STREAMFILE * streamFileSTR = NULL;
|
||||
char filename[260];
|
||||
char filenameSTR[260];
|
||||
int i, j;
|
||||
int channel_count;
|
||||
int loop_flag;
|
||||
off_t coef_table[8] = {0x12C,0x18C,0x1EC,0x24C,0x2AC,0x30C,0x36C,0x3CC};
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("sth",filename_extension(filename))) goto fail;
|
||||
|
||||
strcpy(filenameSTR,filename);
|
||||
strcpy(filenameSTR+strlen(filenameSTR)-3,"str");
|
||||
streamFileSTR = streamFile->open(streamFile,filenameSTR,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!streamFileSTR) goto fail;
|
||||
|
||||
if (read_32bitBE(0x0,streamFile) != 0x0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (read_32bitBE(0x4,streamFile) != 0x800)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Not really channel_count, just 'included tracks * channels per track */
|
||||
loop_flag = (read_32bitBE(0xD8,streamFile) != 0xFFFFFFFF);
|
||||
channel_count = (read_32bitBE(0x70,streamFile)) * (read_32bitBE(0x88,streamFile));
|
||||
|
||||
if (channel_count > 8)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* 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_32bitBE(0x24,streamFile);
|
||||
vgmstream->num_samples=get_streamfile_size(streamFileSTR)/8/channel_count*14;
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
|
||||
if(loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = read_32bitBE(0xD8,streamFile);
|
||||
vgmstream->loop_end_sample = read_32bitBE(0xDC,streamFile);
|
||||
}
|
||||
|
||||
if (channel_count == 1)
|
||||
{
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
else
|
||||
{
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
if (channel_count == 2)
|
||||
{
|
||||
vgmstream->interleave_block_size=0x10000;
|
||||
}
|
||||
else
|
||||
{
|
||||
vgmstream->interleave_block_size=0x8000;
|
||||
}
|
||||
}
|
||||
|
||||
vgmstream->meta_type = meta_NGC_DSP_STH_STR;
|
||||
|
||||
/* open the file for reading */
|
||||
for (i=0;i<channel_count;i++)
|
||||
{
|
||||
vgmstream->ch[i].streamfile = streamFileSTR->open(streamFileSTR,filenameSTR,0x8000);
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
vgmstream->ch[i].channel_start_offset=vgmstream->ch[i].offset=i*vgmstream->interleave_block_size;
|
||||
}
|
||||
|
||||
// COEFFS
|
||||
for (j=0;j<vgmstream->channels;j++)
|
||||
{
|
||||
for (i=0;i<16;i++)
|
||||
{
|
||||
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
|
||||
close_streamfile(streamFileSTR); streamFileSTR=NULL;
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (streamFileSTR) close_streamfile(streamFileSTR);
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
STH+STR
|
||||
found in Taz Wanted (NGC), Cubix Robots for Everyone: Showdown (NGC)
|
||||
*/
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_sth_str2(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
STREAMFILE * streamFileSTR = NULL;
|
||||
char filename[260];
|
||||
char filenameSTR[260];
|
||||
int i, j;
|
||||
int channel_count;
|
||||
int loop_flag;
|
||||
off_t coef_table[8] = {0xDC,0x13C,0x19C,0x1FC,0x25C,0x2BC,0x31C,0x37C};
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("sth",filename_extension(filename))) goto fail;
|
||||
|
||||
strcpy(filenameSTR,filename);
|
||||
strcpy(filenameSTR+strlen(filenameSTR)-3,"str");
|
||||
streamFileSTR = streamFile->open(streamFile,filenameSTR,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!streamFileSTR) goto fail;
|
||||
|
||||
if (read_32bitBE(0x0,streamFile) != 0x0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (read_32bitBE(0x4,streamFile) != 0x900)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Not really channel_count, just 'included tracks * channels per track */
|
||||
loop_flag = (read_32bitBE(0xB8,streamFile) != 0xFFFFFFFF);
|
||||
channel_count = read_32bitBE(0x50,streamFile)*2;
|
||||
|
||||
if (channel_count > 8)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* 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_32bitBE(0x24,streamFile);
|
||||
vgmstream->num_samples=get_streamfile_size(streamFileSTR)/8/channel_count*14;
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
|
||||
if(loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = read_32bitBE(0xB8,streamFile);
|
||||
vgmstream->loop_end_sample = read_32bitBE(0xBC,streamFile);
|
||||
}
|
||||
|
||||
if (channel_count == 1)
|
||||
{
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
else
|
||||
{
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
if (channel_count == 2)
|
||||
{
|
||||
vgmstream->interleave_block_size=0x10000;
|
||||
}
|
||||
else
|
||||
{
|
||||
vgmstream->interleave_block_size=0x8000;
|
||||
}
|
||||
}
|
||||
|
||||
vgmstream->meta_type = meta_NGC_DSP_STH_STR;
|
||||
|
||||
/* open the file for reading */
|
||||
for (i=0;i<channel_count;i++)
|
||||
{
|
||||
vgmstream->ch[i].streamfile = streamFileSTR->open(streamFileSTR,filenameSTR,0x8000);
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
vgmstream->ch[i].channel_start_offset=vgmstream->ch[i].offset=i*vgmstream->interleave_block_size;
|
||||
}
|
||||
|
||||
// COEFFS
|
||||
for (j=0;j<vgmstream->channels;j++)
|
||||
{
|
||||
for (i=0;i<16;i++)
|
||||
{
|
||||
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
|
||||
close_streamfile(streamFileSTR); streamFileSTR=NULL;
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (streamFileSTR) close_streamfile(streamFileSTR);
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/*
|
||||
STH+STR
|
||||
found in Tak and the Guardians of Gross (WII)
|
||||
*/
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_sth_str3(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
STREAMFILE * streamFileSTR = NULL;
|
||||
char filename[260];
|
||||
char filenameSTR[260];
|
||||
int i, j;
|
||||
int channel_count;
|
||||
int loop_flag;
|
||||
off_t coef_table[8] = {read_32bitBE(0x7C,streamFile),read_32bitBE(0x80,streamFile),read_32bitBE(0x84,streamFile),read_32bitBE(0x88,streamFile),read_32bitBE(0x8C,streamFile),read_32bitBE(0x90,streamFile),read_32bitBE(0x94,streamFile),read_32bitBE(0x98,streamFile)};
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("sth",filename_extension(filename))) goto fail;
|
||||
|
||||
strcpy(filenameSTR,filename);
|
||||
strcpy(filenameSTR+strlen(filenameSTR)-3,"str");
|
||||
streamFileSTR = streamFile->open(streamFile,filenameSTR,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!streamFileSTR) goto fail;
|
||||
|
||||
if (read_32bitBE(0x0,streamFile) != 0x0)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if ((read_32bitBE(0x4,streamFile) != 0x700) &&
|
||||
(read_32bitBE(0x4,streamFile) != 0x800))
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* Not really channel_count, just 'included tracks * channels per track */
|
||||
loop_flag = 0;
|
||||
channel_count = read_32bitBE(0x70,streamFile);
|
||||
|
||||
if (channel_count > 8)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* 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_32bitBE(0x38,streamFile);
|
||||
vgmstream->num_samples=get_streamfile_size(streamFileSTR)/8/channel_count*14;
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
|
||||
if(loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = 0;
|
||||
}
|
||||
|
||||
if (channel_count == 1)
|
||||
{
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
else
|
||||
{
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
if (channel_count == 2 || channel_count == 4)
|
||||
{
|
||||
vgmstream->interleave_block_size=0x8000;
|
||||
}
|
||||
else
|
||||
{
|
||||
vgmstream->interleave_block_size=0x4000;
|
||||
}
|
||||
}
|
||||
|
||||
vgmstream->meta_type = meta_NGC_DSP_STH_STR;
|
||||
|
||||
/* open the file for reading */
|
||||
for (i=0;i<channel_count;i++)
|
||||
{
|
||||
vgmstream->ch[i].streamfile = streamFileSTR->open(streamFileSTR,filenameSTR,0x8000);
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
vgmstream->ch[i].channel_start_offset=vgmstream->ch[i].offset=i*vgmstream->interleave_block_size;
|
||||
}
|
||||
|
||||
// COEFFS
|
||||
for (j=0;j<vgmstream->channels;j++)
|
||||
{
|
||||
for (i=0;i<16;i++)
|
||||
{
|
||||
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
|
||||
close_streamfile(streamFileSTR); streamFileSTR=NULL;
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (streamFileSTR) close_streamfile(streamFileSTR);
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -1,84 +1,6 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* IDSP (Chronicles of Narnia Wii) */
|
||||
VGMSTREAM * init_vgmstream_idsp(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
off_t start_offset;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("idsp",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x00,streamFile) != 0x49445350) /* "IDSP" */
|
||||
goto fail;
|
||||
|
||||
channel_count = read_32bitBE(0x04,streamFile);
|
||||
|
||||
if (channel_count > 8)
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0xD0;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitBE(0x28,streamFile);
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = read_32bitBE(0x20,streamFile);
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = read_32bitBE(0x20,streamFile);
|
||||
}
|
||||
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = read_32bitBE(0x0C,streamFile);
|
||||
vgmstream->meta_type = meta_IDSP;
|
||||
|
||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||
int i;
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x3C+i*2,streamFile);
|
||||
}
|
||||
if (vgmstream->channels) {
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x9C+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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+
|
||||
vgmstream->interleave_block_size*i;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* "idsp/IDSP"
|
||||
Soul Calibur Legends (Wii)
|
||||
Sky Crawlers: Innocent Aces (Wii)
|
||||
@ -179,7 +101,6 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* IDSP (Mario Strikers Charged)
|
||||
- Single "IDSP" header... */
|
||||
VGMSTREAM * init_vgmstream_idsp3(STREAMFILE *streamFile) {
|
||||
@ -209,7 +130,7 @@ VGMSTREAM * init_vgmstream_idsp3(STREAMFILE *streamFile) {
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0xD4;
|
||||
start_offset = (channel_count*0x60)+0xC;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitBE(0x14,streamFile);
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
@ -219,9 +140,11 @@ VGMSTREAM * init_vgmstream_idsp3(STREAMFILE *streamFile) {
|
||||
vgmstream->loop_end_sample = (read_32bitBE(0x0C,streamFile));
|
||||
}
|
||||
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = read_32bitBE(0x04,streamFile);
|
||||
vgmstream->meta_type = meta_IDSP;
|
||||
vgmstream->interleave_block_size = read_32bitBE(0x04,streamFile);
|
||||
vgmstream->interleave_smallblock_size = ((vgmstream->num_samples/7*8)%(vgmstream->interleave_block_size)/vgmstream->channels);
|
||||
vgmstream->layout_type = layout_interleave_shortblock;
|
||||
|
||||
vgmstream->meta_type = meta_IDSP;
|
||||
|
||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||
int i;
|
||||
@ -259,7 +182,6 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* IDSP (Defender NGC) */
|
||||
VGMSTREAM * init_vgmstream_idsp4(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
|
@ -153,6 +153,8 @@ VGMSTREAM * init_vgmstream_musc(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_musx_v004(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_musx_v005(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_musx_v006(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_musx_v010(STREAMFILE * streamFile);
|
||||
@ -245,7 +247,7 @@ VGMSTREAM * init_vgmstream_ps2_xa2(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ss_stream(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_idsp(STREAMFILE * streamFile);
|
||||
//VGMSTREAM * init_vgmstream_idsp(STREAMFILE * streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_idsp2(STREAMFILE * streamFile);
|
||||
|
||||
@ -443,9 +445,9 @@ VGMSTREAM * init_vgmstream_ps2_ast(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_dmsg(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_aaap(STREAMFILE* streamFile);
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_aaap(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_tmnt2(STREAMFILE* streamFile);
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_konami(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_ster(STREAMFILE* streamFile);
|
||||
|
||||
@ -483,6 +485,22 @@ VGMSTREAM * init_vgmstream_dsp_str_ig(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_psx_mgav(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_sth_str1(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_sth_str2(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_sth_str3(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_b1s(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_wad(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_dsp_xiii(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_dsp_cabelas(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_adm(STREAMFILE* streamFile);
|
||||
|
||||
VGMSTREAM * init_vgmstream_ps2_lpcm(STREAMFILE* streamFile);
|
||||
|
||||
#endif
|
||||
|
146
src/meta/musc.c
146
src/meta/musc.c
@ -1,72 +1,74 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* MUSC (near all Spyro games and many other using this) */
|
||||
VGMSTREAM * init_vgmstream_musc(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
off_t start_offset;
|
||||
int musc_version;
|
||||
int loop_flag = 0;
|
||||
int channel_count = 2;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("musc",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x0,streamFile) != 0x4D555343) /* MUSC */
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = 2;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
musc_version=read_32bitLE(0x10,streamFile);
|
||||
switch (musc_version) {
|
||||
/* This handles the 'new' MUSC Version, which has only a 32 byte header
|
||||
and doesn't provide any loop info!
|
||||
Spyro - The Eternal Night, Spyro - A new Beginning, Ty - The Tsamanian Tiger */
|
||||
case 0x20:
|
||||
start_offset = 0x20;
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->num_samples = (read_32bitLE(0x14,streamFile))*28/16/channel_count;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = (read_32bitLE(0x14,streamFile))*28/16/channel_count;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x06,streamFile);
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = (read_32bitLE(0x18,streamFile))/2;
|
||||
vgmstream->meta_type = meta_MUSC;
|
||||
|
||||
/* 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+
|
||||
vgmstream->interleave_block_size*i;
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* MUSC (near all Spyro games and many other using this) */
|
||||
VGMSTREAM * init_vgmstream_musc(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
int musc_version;
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
off_t start_offset;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("mus",filename_extension(filename)) &&
|
||||
strcasecmp("musc",filename_extension(filename)))
|
||||
goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x0,streamFile) != 0x4D555343) /* MUSC */
|
||||
goto fail;
|
||||
|
||||
/* check file size */
|
||||
if ((read_32bitLE(0x10,streamFile)+read_32bitLE(0x14,streamFile)) != (get_streamfile_size(streamFile)))
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = 2;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
start_offset = read_32bitLE(0x10,streamFile);
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = (uint16_t) read_16bitLE(0x06,streamFile);
|
||||
|
||||
vgmstream->num_samples = read_32bitLE(0x14,streamFile)/channel_count/16*28;
|
||||
|
||||
#if 0
|
||||
if (loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = (read_32bitLE(0x14,streamFile))*28/16/channel_count;
|
||||
}
|
||||
#endif
|
||||
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = read_32bitLE(0x18,streamFile)/2;
|
||||
vgmstream->meta_type = meta_MUSC;
|
||||
|
||||
/* 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+
|
||||
vgmstream->interleave_block_size*i;
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
271
src/meta/musx.c
271
src/meta/musx.c
@ -1,12 +1,12 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* MUSX */
|
||||
/* Old MUSX formats, found in Spyro, Ty and other games */
|
||||
|
||||
/* MUSX (Version 004) --------------------------------------->*/
|
||||
VGMSTREAM * init_vgmstream_musx_v004(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
int loop_flag = 0;
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
off_t start_offset;
|
||||
|
||||
@ -20,8 +20,7 @@ VGMSTREAM * init_vgmstream_musx_v004(STREAMFILE *streamFile) {
|
||||
if (read_32bitBE(0x08,streamFile) != 0x04000000) /* "0x04000000" */
|
||||
goto fail;
|
||||
|
||||
/* This is tricky, the header changes it's layout if the file is unlooped */
|
||||
loop_flag = (read_32bitLE(0x840,streamFile)!=0xFFFFFFFF);
|
||||
loop_flag = (read_32bitLE(0x840,streamFile) != 0xFFFFFFFF);
|
||||
channel_count = 2;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
@ -30,50 +29,50 @@ VGMSTREAM * init_vgmstream_musx_v004(STREAMFILE *streamFile) {
|
||||
|
||||
switch (read_32bitBE(0x10,streamFile))
|
||||
{
|
||||
case 0x5053325F: /* PS2_ */
|
||||
start_offset = read_32bitLE(0x28,streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 32000;
|
||||
vgmstream->coding_type = coding_PSX; // PS2 ADPCM
|
||||
vgmstream->num_samples = (read_32bitLE(0x0C,streamFile))/16/channel_count*28;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x80;
|
||||
case 0x5053325F: /* PS2_ */
|
||||
start_offset = read_32bitLE(0x28,streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 32000;
|
||||
vgmstream->coding_type = coding_PSX; // PS2 ADPCM
|
||||
vgmstream->num_samples = (read_32bitLE(0x0C,streamFile))/16/channel_count*28;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x80;
|
||||
if (loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = (read_32bitLE(0x890,streamFile))/16/channel_count*28;
|
||||
vgmstream->loop_end_sample = (read_32bitLE(0x89C,streamFile))/16/channel_count*28;
|
||||
}
|
||||
break;
|
||||
case 0x47435F5F: /* GC__ */
|
||||
start_offset = read_32bitBE(0x28,streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 32000;
|
||||
vgmstream->coding_type = coding_DAT4_IMA; // Eurocom DAT4 4-bit IMA ADPCM
|
||||
vgmstream->num_samples = (read_32bitBE(0x2C,streamFile))/16/channel_count*28;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x20;
|
||||
if (loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = (read_32bitBE(0x890,streamFile))/16/channel_count*28;
|
||||
vgmstream->loop_end_sample = (read_32bitBE(0x89C,streamFile))/16/channel_count*28;
|
||||
}
|
||||
break;
|
||||
case 0x58425F5F: /* XB__ */
|
||||
start_offset = read_32bitLE(0x28,streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 44100;
|
||||
vgmstream->coding_type = coding_DAT4_IMA; // Eurocom DAT4 4-bit IMA ADPCM
|
||||
vgmstream->num_samples = (read_32bitLE(0x2C,streamFile))/16/channel_count*28;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x20;
|
||||
if (loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = (read_32bitLE(0x890,streamFile))/16/channel_count*28;
|
||||
vgmstream->loop_end_sample = (read_32bitLE(0x89C,streamFile))/16/channel_count*28;
|
||||
}
|
||||
break;
|
||||
case 0x47435F5F: /* GC__ */
|
||||
start_offset = read_32bitBE(0x28,streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 32000;
|
||||
vgmstream->coding_type = coding_DAT4_IMA; // Eurocom DAT4 4-bit IMA ADPCM
|
||||
vgmstream->num_samples = (read_32bitBE(0x2C,streamFile))/16/channel_count*28;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x20;
|
||||
if (loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = (read_32bitBE(0x890,streamFile))/16/channel_count*28;
|
||||
vgmstream->loop_end_sample = (read_32bitBE(0x89C,streamFile))/16/channel_count*28;
|
||||
}
|
||||
break;
|
||||
case 0x58425F5F: /* XB__ */
|
||||
start_offset = read_32bitLE(0x28,streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 44100;
|
||||
vgmstream->coding_type = coding_DAT4_IMA; // Eurocom DAT4 4-bit IMA ADPCM
|
||||
vgmstream->num_samples = (read_32bitLE(0x2C,streamFile))/16/channel_count*28;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x20;
|
||||
if (loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = (read_32bitLE(0x890,streamFile))/16/channel_count*28;
|
||||
vgmstream->loop_end_sample = (read_32bitLE(0x89C,streamFile))/16/channel_count*28;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
vgmstream->meta_type = meta_MUSX_V004;
|
||||
@ -90,7 +89,6 @@ VGMSTREAM * init_vgmstream_musx_v004(STREAMFILE *streamFile) {
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[i].offset=start_offset+
|
||||
vgmstream->interleave_block_size*i;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@ -101,19 +99,16 @@ fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
/* <--------------------------------------- MUSX (Version 004) */
|
||||
|
||||
|
||||
|
||||
/* MUSX */
|
||||
/* Old MUSX formats, found in Spyro, Ty and other games */
|
||||
VGMSTREAM * init_vgmstream_musx_v006(STREAMFILE *streamFile) {
|
||||
/* MUSX (Version 005) --------------------------------------->*/
|
||||
VGMSTREAM * init_vgmstream_musx_v005(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
off_t start_offset;
|
||||
int musx_type; /* determining the decoder by strings like "PS2_", "GC__" and so on */
|
||||
//int musx_version; /* 0x08 provides a "version" byte */
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
@ -121,53 +116,127 @@ VGMSTREAM * init_vgmstream_musx_v006(STREAMFILE *streamFile) {
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x00,streamFile) != 0x4D555358) /* "MUSX" */
|
||||
goto fail;
|
||||
if (read_32bitBE(0x08,streamFile) != 0x06000000) /* "0x06000000" */
|
||||
goto fail;
|
||||
goto fail;
|
||||
if (read_32bitBE(0x08,streamFile) != 0x05000000) /* "0x04000000" */
|
||||
goto fail;
|
||||
|
||||
loop_flag = (read_32bitLE(0x840,streamFile) != 0xFFFFFFFF);
|
||||
channel_count = 2;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
switch (read_32bitBE(0x10,streamFile))
|
||||
{
|
||||
case 0x47435F5F: /* GC__ */
|
||||
start_offset = read_32bitBE(0x28,streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 32000;
|
||||
vgmstream->coding_type = coding_DAT4_IMA; // Eurocom DAT4 4-bit IMA ADPCM
|
||||
vgmstream->num_samples = (read_32bitBE(0x2C,streamFile))/16/channel_count*28;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x20;
|
||||
if (loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = (read_32bitBE(0x890,streamFile))/16/channel_count*28;
|
||||
vgmstream->loop_end_sample = (read_32bitBE(0x89C,streamFile))/16/channel_count*28;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
vgmstream->meta_type = meta_MUSX_V005;
|
||||
|
||||
/* 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+
|
||||
vgmstream->interleave_block_size*i;
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
/* <--------------------------------------- MUSX (Version 005) */
|
||||
|
||||
|
||||
|
||||
/* MUSX (Version 006) ---------------------------------------> */
|
||||
VGMSTREAM * init_vgmstream_musx_v006(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
off_t start_offset;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("musx",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x00,streamFile) != 0x4D555358) /* "MUSX" */
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x08,streamFile) != 0x06000000) /* "0x06000000" */
|
||||
goto fail;
|
||||
|
||||
loop_flag = (read_32bitLE(0x840,streamFile)!=0xFFFFFFFF);
|
||||
channel_count = 2;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
musx_type=(read_32bitBE(0x10,streamFile));
|
||||
|
||||
switch (musx_type) {
|
||||
case 0x5053325F: /* PS2_ */
|
||||
start_offset = read_32bitLE(0x28,streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 32000;
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->num_samples = (read_32bitLE(0x0C,streamFile))*28/16/channel_count;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x80;
|
||||
vgmstream->meta_type = meta_MUSX_V006;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = (read_32bitLE(0x890,streamFile))*28/16/channel_count;
|
||||
vgmstream->loop_end_sample = (read_32bitLE(0x89C,streamFile))*28/16/channel_count;
|
||||
}
|
||||
break;
|
||||
case 0x47435F5F: /* GC__ */
|
||||
start_offset = read_32bitBE(0x28,streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 32000;
|
||||
vgmstream->coding_type = coding_DAT4_IMA;
|
||||
vgmstream->num_samples = (read_32bitBE(0x2C,streamFile))*28/16/channel_count;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x20;
|
||||
vgmstream->meta_type = meta_MUSX_V006;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = (read_32bitBE(0x890,streamFile))*28/16/channel_count;
|
||||
vgmstream->loop_end_sample = (read_32bitBE(0x89C,streamFile))*28/16/channel_count;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
|
||||
}
|
||||
/* fill in the vital statistics */
|
||||
switch (read_32bitBE(0x10,streamFile))
|
||||
{
|
||||
case 0x5053325F: /* PS2_ */
|
||||
start_offset = read_32bitLE(0x28,streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 32000;
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->num_samples = (read_32bitLE(0x0C,streamFile))*28/16/channel_count;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x80;
|
||||
vgmstream->meta_type = meta_MUSX_V006;
|
||||
if (loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = (read_32bitLE(0x890,streamFile))*28/16/channel_count;
|
||||
vgmstream->loop_end_sample = (read_32bitLE(0x89C,streamFile))*28/16/channel_count;
|
||||
}
|
||||
break;
|
||||
case 0x47435F5F: /* GC__ */
|
||||
start_offset = read_32bitBE(0x28,streamFile);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 32000;
|
||||
vgmstream->coding_type = coding_DAT4_IMA;
|
||||
vgmstream->num_samples = (read_32bitBE(0x2C,streamFile))*28/16/channel_count;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x20;
|
||||
vgmstream->meta_type = meta_MUSX_V006;
|
||||
if (loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = (read_32bitBE(0x890,streamFile))*28/16/channel_count;
|
||||
vgmstream->loop_end_sample = (read_32bitBE(0x89C,streamFile))*28/16/channel_count;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* open the file for reading */
|
||||
{
|
||||
@ -192,10 +261,10 @@ fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
/* <--------------------------------------- MUSX (Version 006) */
|
||||
|
||||
|
||||
/* MUSX */
|
||||
/* New MUSX formats, found in Quantum of Solace, The Mummy 3, possibly more */
|
||||
/* MUSX (Version 010) --------------------------------------->*/
|
||||
/* WII_ in Dead Space: Extraction */
|
||||
VGMSTREAM * init_vgmstream_musx_v010(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
@ -233,7 +302,6 @@ VGMSTREAM * init_vgmstream_musx_v010(STREAMFILE *streamFile) {
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
|
||||
switch (musx_type) {
|
||||
case 0x5053325F: /* PS2_ */
|
||||
start_offset = 0x800;
|
||||
@ -244,7 +312,8 @@ VGMSTREAM * init_vgmstream_musx_v010(STREAMFILE *streamFile) {
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x80;
|
||||
vgmstream->meta_type = meta_MUSX_V010;
|
||||
if (loop_flag) {
|
||||
if (loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = read_32bitLE(0x44,streamFile);
|
||||
vgmstream->loop_end_sample = read_32bitLE(0x40,streamFile);
|
||||
}
|
||||
@ -299,9 +368,10 @@ fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
/* <--------------------------------------- MUSX (Version 010) */
|
||||
|
||||
/* MUSX */
|
||||
/* Old MUSX format, this one handles "Sphinx and the cursed Mummy", it's different from the other formats */
|
||||
|
||||
/* MUSX (Version 201) --------------------------------------->*/
|
||||
VGMSTREAM * init_vgmstream_musx_v201(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
@ -389,3 +459,4 @@ fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
/* <--------------------------------------- MUSX (Version 201) */
|
@ -1,83 +0,0 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* AAAP
|
||||
found in: Turok Evoluttion (NGC)
|
||||
*/
|
||||
VGMSTREAM * init_vgmstream_ngc_aaap(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
int i, j;
|
||||
off_t start_offset;
|
||||
off_t coef_table[8] = {0x24,0x84,0xE4,0x144,0x1A4,0x204,0x264,0x2C4};
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("aaap",filename_extension(filename)))
|
||||
goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x00,streamFile) != 0x41414170) /* "AAAp" */
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = (uint16_t)read_16bitBE(0x06,streamFile);
|
||||
|
||||
if ((read_32bitBE(0x0C,streamFile)+0x8+(channel_count*0x60)) != (get_streamfile_size(streamFile)))
|
||||
goto fail;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x8 + (channel_count * 0x60);
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = read_32bitBE(0x8,streamFile);
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = read_32bitBE(0x8,streamFile);
|
||||
}
|
||||
|
||||
if (channel_count == 1) {
|
||||
vgmstream->layout_type = layout_none;
|
||||
} else if (channel_count > 1) {
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = (uint16_t)read_16bitBE(0x04,streamFile);
|
||||
}
|
||||
|
||||
vgmstream->meta_type = meta_NGC_AAAP;
|
||||
|
||||
{
|
||||
for (j=0;j<vgmstream->channels;j++) {
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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+
|
||||
vgmstream->interleave_block_size*i;
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
/* clean up anything we may have opened */
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -1,75 +1,79 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* DSP
|
||||
Teenage Mutant Ninja Turtles 2 (NGC)
|
||||
*/
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_tmnt2(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
int i, j;
|
||||
off_t start_offset;
|
||||
off_t coef_table[8] = {0x90,0xD0,0x110,0x150,0x190,0x1D0,0x210,0x250};
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("dsp",filename_extension(filename)))
|
||||
goto fail;
|
||||
|
||||
/* check header */
|
||||
if ((read_32bitBE(0x00,streamFile)+0x800) != (get_streamfile_size(streamFile)))
|
||||
goto fail;
|
||||
|
||||
loop_flag = (read_32bitBE(0x10,streamFile) != 0x0);
|
||||
channel_count = 2;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x800;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitBE(0x04,streamFile);
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = (read_32bitBE(0x00,streamFile)/channel_count/8*14);
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = (read_32bitBE(0x14,streamFile)/channel_count/8*14);
|
||||
vgmstream->loop_end_sample = (read_32bitBE(0x00,streamFile)/channel_count/8*14);
|
||||
}
|
||||
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x100;
|
||||
vgmstream->meta_type = meta_NGC_DSP_TMNT2;
|
||||
|
||||
{
|
||||
for (j=0;j<vgmstream->channels;j++) {
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* 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+
|
||||
vgmstream->interleave_block_size*i;
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
/* clean up anything we may have opened */
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* DSP
|
||||
Teenage Mutant Ninja Turtles 2 (NGC)
|
||||
*/
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_konami(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
int i, j;
|
||||
off_t start_offset;
|
||||
off_t ch1_start;
|
||||
off_t ch2_start;
|
||||
off_t coef_table[2] = {0x90, 0xD0};
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("dsp",filename_extension(filename)))
|
||||
goto fail;
|
||||
|
||||
/* check header */
|
||||
if ((read_32bitBE(0x00,streamFile)+0x800) != (get_streamfile_size(streamFile)))
|
||||
goto fail;
|
||||
|
||||
loop_flag = (read_32bitBE(0x10,streamFile) != 0x0);
|
||||
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_32bitBE(0x04,streamFile);
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = (read_32bitBE(0x00,streamFile)/channel_count/8*14);
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = (read_32bitBE(0x14,streamFile)/channel_count/8*14);
|
||||
vgmstream->loop_end_sample = (read_32bitBE(0x00,streamFile)/channel_count/8*14);
|
||||
}
|
||||
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x100;
|
||||
vgmstream->meta_type = meta_NGC_DSP_KONAMI;
|
||||
|
||||
ch1_start = 0x800;
|
||||
ch2_start = 0x800 + vgmstream->interleave_block_size;
|
||||
|
||||
// COEFFS
|
||||
{
|
||||
for (j=0;j<vgmstream->channels;j++) {
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_table[j]+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* open the file for reading */
|
||||
/* Channel 1 */
|
||||
vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!vgmstream->ch[0].streamfile)
|
||||
goto fail;
|
||||
vgmstream->ch[0].channel_start_offset = vgmstream->ch[0].offset=ch1_start;
|
||||
|
||||
/* Channel 1 */
|
||||
vgmstream->ch[1].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!vgmstream->ch[1].streamfile)
|
||||
goto fail;
|
||||
vgmstream->ch[1].channel_start_offset = vgmstream->ch[1].offset=ch2_start;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
/* clean up anything we may have opened */
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -1005,15 +1005,11 @@ fail:
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
|
||||
/* SWD (found in Conflict - Desert Storm 1 & 2 */
|
||||
VGMSTREAM * init_vgmstream_ngc_swd(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
|
||||
off_t start_offset;
|
||||
off_t interleave;
|
||||
|
||||
@ -1122,20 +1118,24 @@ fail:
|
||||
}
|
||||
|
||||
/* IDSP .gcm files, two standard DSP headers */
|
||||
/* found in LEGO Star Wars Complete Collection for Wii */
|
||||
/* found in: Lego Batman (Wii)
|
||||
Lego Indiana Jones - The Original Adventures (Wii)
|
||||
Lego Indiana Jones 2 - The Adventure Continues (Wii)
|
||||
Lego Star Wars - The Complete Saga (Wii)
|
||||
The Chronicles of Narnia - Prince Caspian (Wii) */
|
||||
VGMSTREAM * init_vgmstream_wii_idsp(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
|
||||
off_t start_offset;
|
||||
off_t interleave;
|
||||
|
||||
struct dsp_header ch0_header,ch1_header;
|
||||
int i;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("gcm",filename_extension(filename))) goto fail;
|
||||
if ((strcasecmp("gcm",filename_extension(filename))) &&
|
||||
(strcasecmp("idsp",filename_extension(filename))))
|
||||
goto fail;
|
||||
|
||||
/* check header magic */
|
||||
if (read_32bitBE(0x0,streamFile) != 0x49445350) goto fail; /* "IDSP" */
|
||||
@ -1785,3 +1785,445 @@ fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* .dsp found in Ubisoft games, like "XIII", possibly more
|
||||
always 2 channels and an interleave of 8 */
|
||||
VGMSTREAM * init_vgmstream_dsp_xiii(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
struct dsp_header ch0_header,ch1_header;
|
||||
off_t ch1_header_start, ch2_header_start, ch1_start, ch2_start;
|
||||
int channel_count;
|
||||
int i;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("dsp",filename_extension(filename)))
|
||||
goto fail;
|
||||
|
||||
channel_count = 2;
|
||||
|
||||
ch1_header_start = 0x00;
|
||||
ch2_header_start = 0x60;
|
||||
ch1_start = 0xC0;
|
||||
ch2_start = 0xC8;
|
||||
|
||||
/* get DSP headers */
|
||||
if (read_dsp_header(&ch0_header, ch1_header_start, streamFile)) goto fail;
|
||||
if (read_dsp_header(&ch1_header, ch2_header_start, streamFile)) goto fail;
|
||||
|
||||
/* check initial predictor/scale */
|
||||
if (ch0_header.initial_ps != (uint8_t)read_8bit(ch1_start, streamFile))
|
||||
goto fail;
|
||||
if (ch1_header.initial_ps != (uint8_t)read_8bit(ch2_start, streamFile))
|
||||
goto fail;
|
||||
|
||||
/* check type==0 and gain==0 */
|
||||
if (ch0_header.format || ch0_header.gain)
|
||||
goto fail;
|
||||
if (ch1_header.format || ch1_header.gain)
|
||||
goto fail;
|
||||
|
||||
/* check for agreement */
|
||||
if (
|
||||
ch0_header.sample_count != ch1_header.sample_count ||
|
||||
ch0_header.nibble_count != ch1_header.nibble_count ||
|
||||
ch0_header.sample_rate != ch1_header.sample_rate ||
|
||||
ch0_header.loop_flag != ch1_header.loop_flag ||
|
||||
ch0_header.loop_start_offset != ch1_header.loop_start_offset ||
|
||||
ch0_header.loop_end_offset != ch1_header.loop_end_offset
|
||||
) goto fail;
|
||||
|
||||
if (ch0_header.loop_flag)
|
||||
{
|
||||
off_t loop_off;
|
||||
/* check loop predictor/scale */
|
||||
loop_off = ch0_header.loop_start_offset/16*8;
|
||||
|
||||
if (ch0_header.loop_ps != (uint8_t)read_8bit(ch1_start+loop_off,streamFile))
|
||||
goto fail;
|
||||
if (ch1_header.loop_ps != (uint8_t)read_8bit(ch2_start+loop_off,streamFile))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(2,ch0_header.loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->num_samples = ch0_header.sample_count;
|
||||
vgmstream->sample_rate = ch0_header.sample_rate;
|
||||
|
||||
vgmstream->loop_start_sample = dsp_nibbles_to_samples(
|
||||
ch0_header.loop_start_offset);
|
||||
vgmstream->loop_end_sample = dsp_nibbles_to_samples(
|
||||
ch0_header.loop_end_offset)+1;
|
||||
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x8;
|
||||
vgmstream->meta_type = meta_DSP_XIII;
|
||||
|
||||
/* coeffs */
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[0].adpcm_coef[i] = ch0_header.coef[i];
|
||||
vgmstream->ch[1].adpcm_coef[i] = ch1_header.coef[i];
|
||||
}
|
||||
|
||||
/* initial history */
|
||||
/* always 0 that I've ever seen, but for completeness... */
|
||||
vgmstream->ch[0].adpcm_history1_16 = ch0_header.initial_hist1;
|
||||
vgmstream->ch[0].adpcm_history2_16 = ch0_header.initial_hist2;
|
||||
vgmstream->ch[1].adpcm_history1_16 = ch1_header.initial_hist1;
|
||||
vgmstream->ch[1].adpcm_history2_16 = ch1_header.initial_hist2;
|
||||
|
||||
/* open the file for reading */
|
||||
vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!vgmstream->ch[0].streamfile)
|
||||
goto fail;
|
||||
vgmstream->ch[0].channel_start_offset = vgmstream->ch[0].offset=ch1_start;
|
||||
|
||||
vgmstream->ch[1].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!vgmstream->ch[1].streamfile)
|
||||
goto fail;
|
||||
vgmstream->ch[1].channel_start_offset = vgmstream->ch[1].offset=ch2_start;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
|
||||
fail:
|
||||
/* clean up anything we may have opened */
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
/* .ndp found in Vertigo (WII) */
|
||||
VGMSTREAM * init_vgmstream_wii_ndp(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
struct dsp_header ch0_header,ch1_header;
|
||||
off_t ch1_header_start, ch2_header_start, ch1_start, ch2_start;
|
||||
int channel_count;
|
||||
int i;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("ndp",filename_extension(filename)))
|
||||
goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x0,streamFile) != 0x4E445000) /* NDP */
|
||||
goto fail;
|
||||
|
||||
/* check size */
|
||||
if ((read_32bitLE(0x8,streamFile)+0x18 != get_streamfile_size(streamFile))) /* NDP */
|
||||
goto fail;
|
||||
|
||||
channel_count = (read_16bitLE(0x10,streamFile) != 2);
|
||||
|
||||
ch1_header_start = 0x18;
|
||||
ch2_header_start = 0x78;
|
||||
ch1_start = 0xD8;
|
||||
ch2_start = 0xDC;
|
||||
|
||||
/* get DSP headers */
|
||||
if (read_dsp_header(&ch0_header, ch1_header_start, streamFile)) goto fail;
|
||||
if (read_dsp_header(&ch1_header, ch2_header_start, streamFile)) goto fail;
|
||||
|
||||
/* check initial predictor/scale */
|
||||
if (ch0_header.initial_ps != (uint8_t)read_8bit(ch1_start, streamFile))
|
||||
goto fail;
|
||||
if (ch1_header.initial_ps != (uint8_t)read_8bit(ch2_start, streamFile))
|
||||
goto fail;
|
||||
|
||||
/* check type==0 and gain==0 */
|
||||
if (ch0_header.format || ch0_header.gain)
|
||||
goto fail;
|
||||
if (ch1_header.format || ch1_header.gain)
|
||||
goto fail;
|
||||
|
||||
/* check for agreement */
|
||||
if (
|
||||
ch0_header.sample_count != ch1_header.sample_count ||
|
||||
ch0_header.nibble_count != ch1_header.nibble_count ||
|
||||
ch0_header.sample_rate != ch1_header.sample_rate ||
|
||||
ch0_header.loop_flag != ch1_header.loop_flag ||
|
||||
ch0_header.loop_start_offset != ch1_header.loop_start_offset ||
|
||||
ch0_header.loop_end_offset != ch1_header.loop_end_offset
|
||||
) goto fail;
|
||||
|
||||
if (ch0_header.loop_flag)
|
||||
{
|
||||
off_t loop_off;
|
||||
/* check loop predictor/scale */
|
||||
loop_off = ch0_header.loop_start_offset/16*8;
|
||||
|
||||
if (ch0_header.loop_ps != (uint8_t)read_8bit(ch1_start+loop_off,streamFile))
|
||||
goto fail;
|
||||
if (ch1_header.loop_ps != (uint8_t)read_8bit(ch2_start+loop_off,streamFile))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(2,ch0_header.loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->num_samples = ch0_header.sample_count;
|
||||
vgmstream->sample_rate = ch0_header.sample_rate;
|
||||
|
||||
vgmstream->loop_start_sample = dsp_nibbles_to_samples(
|
||||
ch0_header.loop_start_offset);
|
||||
vgmstream->loop_end_sample = dsp_nibbles_to_samples(
|
||||
ch0_header.loop_end_offset)+1;
|
||||
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->layout_type = layout_interleave_byte;
|
||||
vgmstream->interleave_block_size = 0x4;
|
||||
vgmstream->meta_type = meta_WII_NDP;
|
||||
|
||||
/* coeffs */
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[0].adpcm_coef[i] = ch0_header.coef[i];
|
||||
vgmstream->ch[1].adpcm_coef[i] = ch1_header.coef[i];
|
||||
}
|
||||
|
||||
/* initial history */
|
||||
/* always 0 that I've ever seen, but for completeness... */
|
||||
vgmstream->ch[0].adpcm_history1_16 = ch0_header.initial_hist1;
|
||||
vgmstream->ch[0].adpcm_history2_16 = ch0_header.initial_hist2;
|
||||
vgmstream->ch[1].adpcm_history1_16 = ch1_header.initial_hist1;
|
||||
vgmstream->ch[1].adpcm_history2_16 = ch1_header.initial_hist2;
|
||||
|
||||
/* open the file for reading */
|
||||
vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!vgmstream->ch[0].streamfile)
|
||||
goto fail;
|
||||
vgmstream->ch[0].channel_start_offset = vgmstream->ch[0].offset=ch1_start;
|
||||
|
||||
vgmstream->ch[1].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!vgmstream->ch[1].streamfile)
|
||||
goto fail;
|
||||
vgmstream->ch[1].channel_start_offset = vgmstream->ch[1].offset=ch2_start;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
|
||||
fail:
|
||||
/* clean up anything we may have opened */
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* found in "Cabelas" games, always stereo, looped and an interleave of 0x10 bytes */
|
||||
VGMSTREAM * init_vgmstream_dsp_cabelas(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
struct dsp_header ch0_header,ch1_header;
|
||||
off_t ch1_header_start, ch2_header_start, ch1_start, ch2_start;
|
||||
int channel_count;
|
||||
int i;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("dsp",filename_extension(filename)))
|
||||
goto fail;
|
||||
|
||||
channel_count = 2;
|
||||
|
||||
ch1_header_start = 0x00;
|
||||
ch2_header_start = 0x60;
|
||||
ch1_start = 0xC0;
|
||||
ch2_start = 0xD0;
|
||||
|
||||
/* get DSP headers */
|
||||
if (read_dsp_header(&ch0_header, ch1_header_start, streamFile)) goto fail;
|
||||
if (read_dsp_header(&ch1_header, ch2_header_start, streamFile)) goto fail;
|
||||
|
||||
/* check initial predictor/scale */
|
||||
if (ch0_header.initial_ps != (uint8_t)read_8bit(ch1_start, streamFile))
|
||||
goto fail;
|
||||
if (ch1_header.initial_ps != (uint8_t)read_8bit(ch2_start, streamFile))
|
||||
goto fail;
|
||||
|
||||
/* check type==0 and gain==0 */
|
||||
if (ch0_header.format || ch0_header.gain)
|
||||
goto fail;
|
||||
if (ch1_header.format || ch1_header.gain)
|
||||
goto fail;
|
||||
|
||||
/* check for agreement */
|
||||
if (
|
||||
ch0_header.sample_count != ch1_header.sample_count ||
|
||||
ch0_header.nibble_count != ch1_header.nibble_count ||
|
||||
ch0_header.sample_rate != ch1_header.sample_rate ||
|
||||
ch0_header.loop_flag != ch1_header.loop_flag ||
|
||||
ch0_header.loop_start_offset != ch1_header.loop_start_offset ||
|
||||
ch0_header.loop_end_offset != ch1_header.loop_end_offset
|
||||
) goto fail;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(2,1);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->num_samples = ch0_header.sample_count;
|
||||
vgmstream->sample_rate = ch0_header.sample_rate;
|
||||
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = dsp_nibbles_to_samples(ch0_header.loop_end_offset)+1;
|
||||
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = 0x10;
|
||||
vgmstream->meta_type = meta_DSP_CABELAS;
|
||||
|
||||
/* coeffs */
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[0].adpcm_coef[i] = ch0_header.coef[i];
|
||||
vgmstream->ch[1].adpcm_coef[i] = ch1_header.coef[i];
|
||||
}
|
||||
|
||||
/* initial history */
|
||||
/* always 0 that I've ever seen, but for completeness... */
|
||||
vgmstream->ch[0].adpcm_history1_16 = ch0_header.initial_hist1;
|
||||
vgmstream->ch[0].adpcm_history2_16 = ch0_header.initial_hist2;
|
||||
vgmstream->ch[1].adpcm_history1_16 = ch1_header.initial_hist1;
|
||||
vgmstream->ch[1].adpcm_history2_16 = ch1_header.initial_hist2;
|
||||
|
||||
/* open the file for reading */
|
||||
vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!vgmstream->ch[0].streamfile)
|
||||
goto fail;
|
||||
vgmstream->ch[0].channel_start_offset = vgmstream->ch[0].offset=ch1_start;
|
||||
|
||||
vgmstream->ch[1].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!vgmstream->ch[1].streamfile)
|
||||
goto fail;
|
||||
vgmstream->ch[1].channel_start_offset = vgmstream->ch[1].offset=ch2_start;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
|
||||
fail:
|
||||
/* clean up anything we may have opened */
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* dual dsp header with additional "AAAp" header, found in Vexx (NGC) and Turok: Evolution (NGC) */
|
||||
VGMSTREAM * init_vgmstream_ngc_dsp_aaap(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
struct dsp_header ch0_header,ch1_header;
|
||||
off_t ch1_header_start, ch2_header_start, ch1_start, ch2_start;
|
||||
int channel_count;
|
||||
int i;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("dsp",filename_extension(filename)))
|
||||
goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x0,streamFile) != 0x41414170) /* AAAp */
|
||||
goto fail;
|
||||
|
||||
channel_count = (uint16_t)read_16bitBE(0x6,streamFile);
|
||||
|
||||
ch1_header_start = 0x08;
|
||||
ch2_header_start = 0x68;
|
||||
ch1_start = 0xC8;
|
||||
ch2_start = ch1_start + (uint16_t)read_16bitBE(0x4,streamFile);
|
||||
|
||||
/* get DSP headers */
|
||||
if (read_dsp_header(&ch0_header, ch1_header_start, streamFile)) goto fail;
|
||||
if (read_dsp_header(&ch1_header, ch2_header_start, streamFile)) goto fail;
|
||||
|
||||
/* check initial predictor/scale */
|
||||
if (ch0_header.initial_ps != (uint8_t)read_8bit(ch1_start, streamFile))
|
||||
goto fail;
|
||||
if (ch1_header.initial_ps != (uint8_t)read_8bit(ch2_start, streamFile))
|
||||
goto fail;
|
||||
|
||||
/* check type==0 and gain==0 */
|
||||
if (ch0_header.format || ch0_header.gain)
|
||||
goto fail;
|
||||
if (ch1_header.format || ch1_header.gain)
|
||||
goto fail;
|
||||
|
||||
/* check for agreement */
|
||||
if (
|
||||
ch0_header.sample_count != ch1_header.sample_count ||
|
||||
ch0_header.nibble_count != ch1_header.nibble_count ||
|
||||
ch0_header.sample_rate != ch1_header.sample_rate ||
|
||||
ch0_header.loop_flag != ch1_header.loop_flag ||
|
||||
ch0_header.loop_start_offset != ch1_header.loop_start_offset ||
|
||||
ch0_header.loop_end_offset != ch1_header.loop_end_offset
|
||||
) goto fail;
|
||||
|
||||
if (ch0_header.loop_flag)
|
||||
{
|
||||
off_t loop_off;
|
||||
/* check loop predictor/scale */
|
||||
loop_off = ch0_header.loop_start_offset/16*8;
|
||||
|
||||
if (ch0_header.loop_ps != (uint8_t)read_8bit(ch1_start+loop_off,streamFile))
|
||||
goto fail;
|
||||
if (ch1_header.loop_ps != (uint8_t)read_8bit(ch2_start+loop_off,streamFile))
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,ch0_header.loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
vgmstream->num_samples = ch0_header.sample_count;
|
||||
vgmstream->sample_rate = ch0_header.sample_rate;
|
||||
|
||||
vgmstream->loop_start_sample = dsp_nibbles_to_samples(
|
||||
ch0_header.loop_start_offset);
|
||||
vgmstream->loop_end_sample = dsp_nibbles_to_samples(
|
||||
ch0_header.loop_end_offset)+1;
|
||||
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = ch2_start-ch1_start;
|
||||
vgmstream->meta_type = meta_NGC_DSP_AAAP;
|
||||
|
||||
/* coeffs */
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[0].adpcm_coef[i] = ch0_header.coef[i];
|
||||
vgmstream->ch[1].adpcm_coef[i] = ch1_header.coef[i];
|
||||
}
|
||||
|
||||
/* initial history */
|
||||
/* always 0 that I've ever seen, but for completeness... */
|
||||
vgmstream->ch[0].adpcm_history1_16 = ch0_header.initial_hist1;
|
||||
vgmstream->ch[0].adpcm_history2_16 = ch0_header.initial_hist2;
|
||||
vgmstream->ch[1].adpcm_history1_16 = ch1_header.initial_hist1;
|
||||
vgmstream->ch[1].adpcm_history2_16 = ch1_header.initial_hist2;
|
||||
|
||||
/* open the file for reading */
|
||||
vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!vgmstream->ch[0].streamfile)
|
||||
goto fail;
|
||||
vgmstream->ch[0].channel_start_offset = vgmstream->ch[0].offset=ch1_start;
|
||||
|
||||
vgmstream->ch[1].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
if (!vgmstream->ch[1].streamfile)
|
||||
goto fail;
|
||||
vgmstream->ch[1].channel_start_offset = vgmstream->ch[1].offset=ch2_start;
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
/* clean up anything we may have opened */
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
74
src/meta/ps2_adm.c
Normal file
74
src/meta/ps2_adm.c
Normal file
@ -0,0 +1,74 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* WAD (from The golden Compass) */
|
||||
VGMSTREAM * init_vgmstream_ps2_adm(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
int i;
|
||||
off_t start_offset;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("adm",filename_extension(filename))) goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = 2;
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x0;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = 44100;
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
|
||||
#if 0
|
||||
vgmstream->num_samples = read_32bitLE(0x0,streamFile)/channel_count/16*28;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = read_32bitLE(0x0,streamFile)/channel_count/16*28;
|
||||
}
|
||||
#endif
|
||||
|
||||
vgmstream->layout_type = layout_ps2_adm_blocked;
|
||||
vgmstream->interleave_block_size = 0x400;
|
||||
|
||||
|
||||
vgmstream->meta_type = meta_PS2_ADM;
|
||||
|
||||
/* open the file for reading by each channel */
|
||||
{
|
||||
for (i=0;i<channel_count;i++) {
|
||||
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,vgmstream->interleave_block_size);
|
||||
|
||||
if (!vgmstream->ch[i].streamfile) goto fail;
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[i].offset=i*vgmstream->interleave_block_size;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* Calc num_samples */
|
||||
ps2_adm_block_update(start_offset,vgmstream);
|
||||
vgmstream->num_samples=0; //(get_streamfile_size(streamFile)/0x1000*0xFE0)/32*28;
|
||||
|
||||
do {
|
||||
|
||||
vgmstream->num_samples += 0xFE0*14/16;
|
||||
ps2_adm_block_update(vgmstream->next_block_offset,vgmstream);
|
||||
} while (vgmstream->next_block_offset<get_streamfile_size(streamFile));
|
||||
|
||||
ps2_adm_block_update(start_offset,vgmstream);
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
56
src/meta/ps2_b1s.c
Normal file
56
src/meta/ps2_b1s.c
Normal file
@ -0,0 +1,56 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* B1S (found in 7 Wonders of the Ancient World) */
|
||||
VGMSTREAM * init_vgmstream_ps2_b1s(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
int channel_count;
|
||||
off_t start_offset;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("b1s",filename_extension(filename))) goto fail;
|
||||
|
||||
if ((read_32bitLE(0x04,streamFile)+0x18) != get_streamfile_size(streamFile))
|
||||
goto fail;
|
||||
|
||||
channel_count = read_32bitLE(0x14,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,0);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x18;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->num_samples = read_32bitLE(0x04,streamFile)/16/channel_count*28;
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
vgmstream->interleave_block_size = read_32bitLE(0x0C,streamFile);
|
||||
vgmstream->meta_type = meta_PS2_B1S;
|
||||
|
||||
/* 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+
|
||||
vgmstream->interleave_block_size*i;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
71
src/meta/ps2_wad.c
Normal file
71
src/meta/ps2_wad.c
Normal file
@ -0,0 +1,71 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* WAD (from The golden Compass) */
|
||||
VGMSTREAM * init_vgmstream_ps2_wad(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
int loop_flag = 0;
|
||||
int channel_count;
|
||||
off_t start_offset;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("wad",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if ((read_32bitLE(0x00,streamFile)+0x40) != get_streamfile_size(streamFile))
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = (uint16_t) read_16bitLE(0x4,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x40;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = (uint16_t) read_16bitLE(0x6,streamFile);;
|
||||
vgmstream->coding_type = coding_PSX;
|
||||
vgmstream->num_samples = read_32bitLE(0x0,streamFile)/channel_count/16*28;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = 0;
|
||||
vgmstream->loop_end_sample = read_32bitLE(0x0,streamFile)/channel_count/16*28;
|
||||
}
|
||||
|
||||
if (channel_count == 1)
|
||||
{
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
else
|
||||
{
|
||||
goto fail;
|
||||
}
|
||||
|
||||
vgmstream->meta_type = meta_PS2_WAD;
|
||||
|
||||
/* 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+
|
||||
vgmstream->interleave_block_size*i;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
/* clean up anything we may have opened */
|
||||
fail:
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -159,12 +159,13 @@ VGMSTREAM * init_vgmstream_ss_stream(STREAMFILE *streamFile) {
|
||||
|
||||
start_offset = (read_8bit(0x07,streamFile)+5);
|
||||
|
||||
#if 0
|
||||
if (channel_count == 1){
|
||||
start_offset = 0x3C;
|
||||
} else if (channel_count == 2) {
|
||||
start_offset = 0x44;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
if(channel_count==1)
|
||||
vgmstream->coding_type = coding_IMA;
|
||||
|
@ -1,72 +0,0 @@
|
||||
#include "meta.h"
|
||||
#include "../util.h"
|
||||
|
||||
/* NDP (from Vertigo (Wii)) */
|
||||
VGMSTREAM * init_vgmstream_wii_ndp(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
off_t start_offset;
|
||||
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("ndp",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x0,streamFile) != 0x4E445000) /* NDP */
|
||||
goto fail;
|
||||
|
||||
loop_flag = 0;
|
||||
channel_count = read_16bitLE(0x10,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0xd8;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitLE(0x0c,streamFile);
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->num_samples = read_32bitBE(0x18,streamFile);
|
||||
vgmstream->layout_type = layout_interleave_byte;
|
||||
vgmstream->interleave_block_size = 4;
|
||||
vgmstream->meta_type = meta_WII_NDP;
|
||||
|
||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||
int i;
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x34+i*2,streamFile);
|
||||
}
|
||||
if (vgmstream->channels) {
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x94+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
/* 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+
|
||||
vgmstream->interleave_block_size*i;
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
/* clean up anything we may have opened */
|
||||
if (vgmstream) close_vgmstream(vgmstream);
|
||||
return NULL;
|
||||
}
|
@ -5,61 +5,71 @@
|
||||
VGMSTREAM * init_vgmstream_ydsp(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[260];
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
off_t start_offset;
|
||||
|
||||
int loop_flag;
|
||||
int channel_count;
|
||||
|
||||
/* check extension, case insensitive */
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
if (strcasecmp("ydsp",filename_extension(filename))) goto fail;
|
||||
|
||||
/* check header */
|
||||
if (read_32bitBE(0x00,streamFile) != 0x59445350) /* "YDSP" */
|
||||
goto fail;
|
||||
goto fail;
|
||||
|
||||
loop_flag = (read_32bitBE(0xB0,streamFile)!=0);
|
||||
channel_count = 2; /* (uint32_t)read_16bitBE(0x10,streamFile); */
|
||||
loop_flag = (read_32bitBE(0xB0,streamFile)!=0x0);
|
||||
channel_count = (uint16_t)read_16bitBE(0x10,streamFile);
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(channel_count,loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
||||
/* fill in the vital statistics */
|
||||
/* fill in the vital statistics */
|
||||
start_offset = 0x120;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->channels = channel_count;
|
||||
vgmstream->sample_rate = read_32bitBE(0x0C,streamFile);
|
||||
vgmstream->coding_type = coding_NGC_DSP;
|
||||
vgmstream->meta_type = meta_YDSP;
|
||||
|
||||
vgmstream->num_samples = (read_32bitBE(0x08,streamFile))*14/8/channel_count;
|
||||
if (loop_flag) {
|
||||
vgmstream->loop_start_sample = read_32bitBE(0xB0,streamFile);
|
||||
vgmstream->loop_end_sample = read_32bitBE(0xB4,streamFile);
|
||||
|
||||
if (loop_flag)
|
||||
{
|
||||
vgmstream->loop_start_sample = read_32bitBE(0xB0,streamFile);
|
||||
vgmstream->loop_end_sample = read_32bitBE(0xB4,streamFile);
|
||||
}
|
||||
|
||||
if (channel_count == 1) {
|
||||
vgmstream->layout_type = layout_none;
|
||||
} else if (channel_count == 2) {
|
||||
vgmstream->interleave_block_size = read_32bitBE(0x14,streamFile);
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
}
|
||||
if (channel_count == 1)
|
||||
{
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
else if (channel_count == 2)
|
||||
{
|
||||
vgmstream->interleave_block_size = read_32bitBE(0x14,streamFile);
|
||||
vgmstream->layout_type = layout_interleave;
|
||||
}
|
||||
|
||||
vgmstream->meta_type = meta_YDSP;
|
||||
|
||||
|
||||
/* open the file for reading */
|
||||
|
||||
if (vgmstream->coding_type == coding_NGC_DSP) {
|
||||
int i;
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x20+i*2,streamFile);
|
||||
}
|
||||
if (vgmstream->channels == 2) {
|
||||
for (i=0;i<16;i++) {
|
||||
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x44+i*2,streamFile);
|
||||
}
|
||||
if (vgmstream->coding_type == coding_NGC_DSP)
|
||||
{
|
||||
int i;
|
||||
for (i=0;i<16;i++)
|
||||
{
|
||||
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x20+i*2,streamFile);
|
||||
}
|
||||
if (vgmstream->channels == 2)
|
||||
{
|
||||
for (i=0;i<16;i++)
|
||||
{
|
||||
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x44+i*2,streamFile);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
{
|
||||
|
||||
{
|
||||
int i;
|
||||
STREAMFILE * file;
|
||||
file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
|
||||
@ -70,7 +80,6 @@ VGMSTREAM * init_vgmstream_ydsp(STREAMFILE *streamFile) {
|
||||
vgmstream->ch[i].channel_start_offset=
|
||||
vgmstream->ch[i].offset=start_offset+
|
||||
vgmstream->interleave_block_size*i;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -92,6 +92,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
||||
init_vgmstream_xa30,
|
||||
init_vgmstream_musc,
|
||||
init_vgmstream_musx_v004,
|
||||
init_vgmstream_musx_v005,
|
||||
init_vgmstream_musx_v006,
|
||||
init_vgmstream_musx_v010,
|
||||
init_vgmstream_musx_v201,
|
||||
@ -140,7 +141,7 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
||||
init_vgmstream_kraw,
|
||||
init_vgmstream_ps2_omu,
|
||||
init_vgmstream_ps2_xa2,
|
||||
init_vgmstream_idsp,
|
||||
//init_vgmstream_idsp,
|
||||
init_vgmstream_idsp2,
|
||||
init_vgmstream_idsp3,
|
||||
init_vgmstream_idsp4,
|
||||
@ -242,8 +243,8 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
||||
init_vgmstream_his,
|
||||
init_vgmstream_ps2_ast,
|
||||
init_vgmstream_dmsg,
|
||||
init_vgmstream_ngc_aaap,
|
||||
init_vgmstream_ngc_dsp_tmnt2,
|
||||
init_vgmstream_ngc_dsp_aaap,
|
||||
init_vgmstream_ngc_dsp_konami,
|
||||
init_vgmstream_ps2_ster,
|
||||
init_vgmstream_ps2_wb,
|
||||
init_vgmstream_bnsf,
|
||||
@ -264,7 +265,15 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = {
|
||||
init_vgmstream_ngc_dsp_mpds,
|
||||
init_vgmstream_dsp_str_ig,
|
||||
init_vgmstream_psx_mgav,
|
||||
init_vgmstream_ps2_lpcm,
|
||||
init_vgmstream_ngc_dsp_sth_str1,
|
||||
init_vgmstream_ngc_dsp_sth_str2,
|
||||
init_vgmstream_ngc_dsp_sth_str3,
|
||||
init_vgmstream_ps2_b1s,
|
||||
init_vgmstream_ps2_wad,
|
||||
init_vgmstream_dsp_xiii,
|
||||
init_vgmstream_dsp_cabelas,
|
||||
init_vgmstream_ps2_adm,
|
||||
init_vgmstream_ps2_lpcm,
|
||||
};
|
||||
|
||||
#define INIT_VGMSTREAM_FCNS (sizeof(init_vgmstream_fcns)/sizeof(init_vgmstream_fcns[0]))
|
||||
@ -702,6 +711,7 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
|
||||
case layout_filp_blocked:
|
||||
case layout_ivaud_blocked:
|
||||
case layout_psx_mgav_blocked:
|
||||
case layout_ps2_adm_blocked:
|
||||
render_vgmstream_blocked(buffer,sample_count,vgmstream);
|
||||
break;
|
||||
case layout_interleave_byte:
|
||||
@ -1751,6 +1761,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||
case layout_psx_mgav_blocked:
|
||||
snprintf(temp,TEMPSIZE,"MGAV blocked");
|
||||
break;
|
||||
case layout_ps2_adm_blocked:
|
||||
snprintf(temp,TEMPSIZE,"ADM blocked");
|
||||
break;
|
||||
#ifdef VGM_USE_MPEG
|
||||
case layout_fake_mpeg:
|
||||
snprintf(temp,TEMPSIZE,"MPEG Audio stream with incorrect frame headers");
|
||||
@ -2102,6 +2115,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||
case meta_MUSX_V004:
|
||||
snprintf(temp,TEMPSIZE,"MUSX / Version 004 Header");
|
||||
break;
|
||||
case meta_MUSX_V005:
|
||||
snprintf(temp,TEMPSIZE,"MUSX / Version 005 Header");
|
||||
break;
|
||||
case meta_MUSX_V006:
|
||||
snprintf(temp,TEMPSIZE,"MUSX / Version 006 Header");
|
||||
break;
|
||||
@ -2322,7 +2338,7 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||
snprintf(temp,TEMPSIZE,"ISH+ISD DSP Header");
|
||||
break;
|
||||
case meta_YDSP:
|
||||
snprintf(temp,TEMPSIZE,"YDSP Header");
|
||||
snprintf(temp,TEMPSIZE,"Yuke's DSP (YDSP) Header");
|
||||
break;
|
||||
case meta_MSVP:
|
||||
snprintf(temp,TEMPSIZE,"MSVP Header");
|
||||
@ -2503,11 +2519,11 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||
case meta_PONA_PSX:
|
||||
snprintf(temp,TEMPSIZE,"Policenauts BGM header");
|
||||
break;
|
||||
case meta_NGC_AAAP:
|
||||
snprintf(temp,TEMPSIZE,"Turok: Evolution 'AAAp' dsp header");
|
||||
case meta_NGC_DSP_AAAP:
|
||||
snprintf(temp,TEMPSIZE,"Double standard dsp header in 'AAAp'");
|
||||
break;
|
||||
case meta_NGC_DSP_TMNT2:
|
||||
snprintf(temp,TEMPSIZE,"TMNT2 dsp header");
|
||||
case meta_NGC_DSP_KONAMI:
|
||||
snprintf(temp,TEMPSIZE,"Konami dsp header");
|
||||
break;
|
||||
case meta_PS2_STER:
|
||||
snprintf(temp,TEMPSIZE,"STER Header");
|
||||
@ -2560,7 +2576,22 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length) {
|
||||
case meta_PSX_MGAV:
|
||||
snprintf(temp,TEMPSIZE,"Electronic Arts RVWS header");
|
||||
break;
|
||||
case meta_PS2_LPCM:
|
||||
case meta_PS2_B1S:
|
||||
snprintf(temp,TEMPSIZE,"B1S header");
|
||||
break;
|
||||
case meta_PS2_WAD:
|
||||
snprintf(temp,TEMPSIZE,"WAD header");
|
||||
break;
|
||||
case meta_DSP_XIII:
|
||||
snprintf(temp,TEMPSIZE,"XIII dsp header");
|
||||
break;
|
||||
case meta_NGC_DSP_STH_STR:
|
||||
snprintf(temp,TEMPSIZE,"STH dsp header");
|
||||
break;
|
||||
case meta_DSP_CABELAS:
|
||||
snprintf(temp,TEMPSIZE,"Cabelas games dsp header");
|
||||
break;
|
||||
case meta_PS2_LPCM:
|
||||
snprintf(temp,TEMPSIZE,"LPCM header");
|
||||
break;
|
||||
default:
|
||||
|
@ -149,6 +149,7 @@ typedef enum {
|
||||
layout_filp_blocked,
|
||||
layout_mxch_blocked,
|
||||
layout_psx_mgav_blocked,
|
||||
layout_ps2_adm_blocked,
|
||||
#if 0
|
||||
layout_strm_blocked, /* */
|
||||
#endif
|
||||
@ -264,6 +265,7 @@ typedef enum {
|
||||
meta_XA30, /* Driver - Parallel Lines (PS2) */
|
||||
meta_MUSC, /* Spyro Games, possibly more */
|
||||
meta_MUSX_V004, /* Spyro Games, possibly more */
|
||||
meta_MUSX_V005, /* Spyro Games, possibly more */
|
||||
meta_MUSX_V006, /* Spyro Games, possibly more */
|
||||
meta_MUSX_V010, /* Spyro Games, possibly more */
|
||||
meta_MUSX_V201, /* Sphinx and the cursed Mummy */
|
||||
@ -352,7 +354,7 @@ typedef enum {
|
||||
meta_PS2_SPS, /* Ape Escape 2 */
|
||||
meta_PS2_XA2_RRP, /* RC Revenge Pro */
|
||||
meta_PS2_STM, /* Red Dead Revolver .stm, renamed .ps2stm */
|
||||
meta_NGC_DSP_TMNT2, /* Teenage Mutant Ninja Turtles 2 */
|
||||
meta_NGC_DSP_KONAMI, /* Konami DSP header, found in various games */
|
||||
|
||||
meta_XBOX_WAVM, /* XBOX WAVM File */
|
||||
meta_XBOX_RIFF, /* XBOX RIFF/WAVE File */
|
||||
@ -441,7 +443,7 @@ typedef enum {
|
||||
meta_XBOX_HLWAV, /* Half Life 2 (XBOX) */
|
||||
meta_PS2_AST, /* Some KOEI game (PS2) */
|
||||
meta_DMSG, /* Nightcaster II - Equinox (XBOX) */
|
||||
meta_NGC_AAAP, /* Turok: Evolution (NGC) */
|
||||
meta_NGC_DSP_AAAP, /* Turok: Evolution (NGC), Vexx (NGC) */
|
||||
meta_PS2_STER, /* Juuni Kokuki: Kakukaku Taru Ou Michi Beni Midori no Uka */
|
||||
meta_PS2_WB, /* Shooting Love. ~TRIZEAL~ */
|
||||
meta_S14, /* raw Siren 14, 24kbit mono */
|
||||
@ -460,7 +462,13 @@ typedef enum {
|
||||
meta_NGC_DSP_MPDS, /* Big Air Freestyle, Terminator 3 */
|
||||
meta_DSP_STR_IG, /* Micro Machines, Superman Superman: Shadow of Apokolis */
|
||||
meta_PSX_MGAV, /* Future Cop L.A.P.D. */
|
||||
meta_PS2_LPCM, /* Ah! My Goddess */
|
||||
meta_NGC_DSP_STH_STR, /* SpongeBob Squarepants (NGC), Taz Wanted (NGC), Cubix (NGC), Tak (WII)*/
|
||||
meta_PS2_B1S, /* 7 Wonders of the ancient world */
|
||||
meta_PS2_WAD, /* The golden Compass */
|
||||
meta_DSP_XIII, /* XIII, possibly more (Ubisoft header???) */
|
||||
meta_DSP_CABELAS, /* Cabelas games */
|
||||
meta_PS2_ADM, /* Dragon Quest 5 */
|
||||
meta_PS2_LPCM, /* Ah! My Goddess */
|
||||
} meta_t;
|
||||
|
||||
typedef struct {
|
||||
|
Loading…
x
Reference in New Issue
Block a user