Changed STREAMFILE to be an abstract structure with function pointers for file operations. These changes have been done to support the audacious plugin which will use audacious-VFS I/O instead of stdio. The winamp plugin uses stdio, and has been tested and is working.

stdio optimizations include the prevention of 'doubly opening' a file.  If a file is opened that is already opened, the file handle is duplicated instead of using the normal fopen call.  

git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@180 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
paladine 2008-05-20 15:18:38 +00:00
parent 85a9518e07
commit 3ae797a88a
33 changed files with 744 additions and 848 deletions

View File

@ -4,9 +4,9 @@
/* .dsp w/ Cstr header, seen in Star Fox Assault and Donkey Konga */
VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
VGMSTREAM * init_vgmstream_Cstr(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int loop_flag;
off_t start_offset;
@ -17,37 +17,34 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
int double_loop_end = 0;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("dsp",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check header */
if ((uint32_t)read_32bitBE(0,infile)!=0x43737472) /* "Cstr" */
if ((uint32_t)read_32bitBE(0,streamFile)!=0x43737472) /* "Cstr" */
goto fail;
#ifdef DEBUG
fprintf(stderr,"header ok\n");
#endif
if (read_8bit(0x1b,infile)==1) {
if (read_8bit(0x1b,streamFile)==1) {
/* mono version, much simpler to handle */
/* Only seen in R Racing Evolution radio sfx */
start_offset = 0x80;
loop_flag = read_16bitBE(0x2c,infile);
loop_flag = read_16bitBE(0x2c,streamFile);
/* check initial predictor/scale */
if (read_16bitBE(0x5e,infile) != (uint8_t)read_8bit(start_offset,infile))
if (read_16bitBE(0x5e,streamFile) != (uint8_t)read_8bit(start_offset,streamFile))
goto fail;
/* check type==0 and gain==0 */
if (read_16bitBE(0x2e,infile) || read_16bitBE(0x5c,infile))
if (read_16bitBE(0x2e,streamFile) || read_16bitBE(0x5c,streamFile))
goto fail;
loop_offset = start_offset+read_32bitBE(0x10,infile);
loop_offset = start_offset+read_32bitBE(0x10,streamFile);
if (loop_flag) {
if (read_16bitBE(0x64,infile) != (uint8_t)read_8bit(loop_offset,infile)) goto fail;
if (read_16bitBE(0x64,streamFile) != (uint8_t)read_8bit(loop_offset,streamFile)) goto fail;
}
/* build the VGMSTREAM */
@ -56,14 +53,14 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->sample_rate = read_32bitBE(0x28,infile);
vgmstream->num_samples = read_32bitBE(0x20,infile);
vgmstream->sample_rate = read_32bitBE(0x28,streamFile);
vgmstream->num_samples = read_32bitBE(0x20,streamFile);
if (loop_flag) {
vgmstream->loop_start_sample = dsp_nibbles_to_samples(
read_32bitBE(0x30,infile));
read_32bitBE(0x30,streamFile));
vgmstream->loop_end_sample = dsp_nibbles_to_samples(
read_32bitBE(0x34,infile))+1;
read_32bitBE(0x34,streamFile))+1;
}
vgmstream->coding_type = coding_NGC_DSP;
@ -73,13 +70,11 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
{
int i;
for (i=0;i<16;i++)
vgmstream->ch[0].adpcm_coef[i]=read_16bitBE(0x3c+i*2,infile);
vgmstream->ch[0].adpcm_coef[i]=read_16bitBE(0x3c+i*2,streamFile);
}
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
vgmstream->ch[0].streamfile = open_streamfile(filename);
vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!vgmstream->ch[0].streamfile) goto fail;
@ -90,10 +85,10 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
return vgmstream;
} /* end mono */
interleave = read_16bitBE(0x06,infile);
interleave = read_16bitBE(0x06,streamFile);
start_offset = 0xe0;
first_data = start_offset+read_32bitBE(0x0c,infile);
loop_flag = read_16bitBE(0x2c,infile);
first_data = start_offset+read_32bitBE(0x0c,streamFile);
loop_flag = read_16bitBE(0x2c,streamFile);
if (!loop_flag) {
/* Nonlooped tracks seem to follow no discernable pattern
@ -101,8 +96,8 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
* But! with the magic of initial p/s redundancy, we can guess.
*/
while (first_data<start_offset+0x800 &&
(read_16bitBE(0x5e,infile) != (uint8_t)read_8bit(first_data,infile) ||
read_16bitBE(0xbe,infile) != (uint8_t)read_8bit(first_data+interleave,infile)))
(read_16bitBE(0x5e,streamFile) != (uint8_t)read_8bit(first_data,streamFile) ||
read_16bitBE(0xbe,streamFile) != (uint8_t)read_8bit(first_data+interleave,streamFile)))
first_data+=8;
#ifdef DEBUG
fprintf(stderr,"guessed first_data at %#x\n",first_data);
@ -110,9 +105,9 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
}
/* check initial predictor/scale */
if (read_16bitBE(0x5e,infile) != (uint8_t)read_8bit(first_data,infile))
if (read_16bitBE(0x5e,streamFile) != (uint8_t)read_8bit(first_data,streamFile))
goto fail;
if (read_16bitBE(0xbe,infile) != (uint8_t)read_8bit(first_data+interleave,infile))
if (read_16bitBE(0xbe,streamFile) != (uint8_t)read_8bit(first_data+interleave,streamFile))
goto fail;
#ifdef DEBUG
@ -120,9 +115,9 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
#endif
/* check type==0 and gain==0 */
if (read_16bitBE(0x2e,infile) || read_16bitBE(0x5c,infile))
if (read_16bitBE(0x2e,streamFile) || read_16bitBE(0x5c,streamFile))
goto fail;
if (read_16bitBE(0x8e,infile) || read_16bitBE(0xbc,infile))
if (read_16bitBE(0x8e,streamFile) || read_16bitBE(0xbc,streamFile))
goto fail;
#ifdef DEBUG
@ -130,14 +125,14 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
#endif
/* check for loop flag agreement */
if (read_16bitBE(0x2c,infile) != read_16bitBE(0x8c,infile))
if (read_16bitBE(0x2c,streamFile) != read_16bitBE(0x8c,streamFile))
goto fail;
#ifdef DEBUG
fprintf(stderr,"loop flags agree\n");
#endif
loop_offset = start_offset+read_32bitBE(0x10,infile)*2;
loop_offset = start_offset+read_32bitBE(0x10,streamFile)*2;
if (loop_flag) {
int loops_ok=0;
/* check loop predictor/scale */
@ -146,8 +141,8 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
#ifdef DEBUG
fprintf(stderr,"looking for loop p/s at %#x,%#x\n",loop_offset-interleave+loop_adjust,loop_offset+loop_adjust);
#endif
if (read_16bitBE(0x64,infile) == (uint8_t)read_8bit(loop_offset-interleave+loop_adjust,infile) &&
read_16bitBE(0xc4,infile) == (uint8_t)read_8bit(loop_offset+loop_adjust,infile)) {
if (read_16bitBE(0x64,streamFile) == (uint8_t)read_8bit(loop_offset-interleave+loop_adjust,streamFile) &&
read_16bitBE(0xc4,streamFile) == (uint8_t)read_8bit(loop_offset+loop_adjust,streamFile)) {
loops_ok=1;
break;
}
@ -157,8 +152,8 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
#ifdef DEBUG
fprintf(stderr,"looking for loop p/s at %#x,%#x\n",loop_offset-interleave+loop_adjust,loop_offset+loop_adjust);
#endif
if (read_16bitBE(0x64,infile) == (uint8_t)read_8bit(loop_offset-interleave+loop_adjust,infile) &&
read_16bitBE(0xc4,infile) == (uint8_t)read_8bit(loop_offset+loop_adjust,infile)) {
if (read_16bitBE(0x64,streamFile) == (uint8_t)read_8bit(loop_offset-interleave+loop_adjust,streamFile) &&
read_16bitBE(0xc4,streamFile) == (uint8_t)read_8bit(loop_offset+loop_adjust,streamFile)) {
loops_ok=1;
break;
}
@ -171,11 +166,11 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
/* check for agreement */
/* loop end (channel 1 & 2 headers) */
if (read_32bitBE(0x34,infile) != read_32bitBE(0x94,infile))
if (read_32bitBE(0x34,streamFile) != read_32bitBE(0x94,streamFile))
goto fail;
/* Mr. Driller oddity */
if (dsp_nibbles_to_samples(read_32bitBE(0x34,infile)*2)+1 <= read_32bitBE(0x20,infile)) {
if (dsp_nibbles_to_samples(read_32bitBE(0x34,streamFile)*2)+1 <= read_32bitBE(0x20,streamFile)) {
#ifdef DEBUG
fprintf(stderr,"loop end <= half total samples, should be doubled\n");
#endif
@ -183,32 +178,32 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
}
/* loop start (Cstr header and channel 1 header) */
if (read_32bitBE(0x30,infile) != read_32bitBE(0x10,infile)
if (read_32bitBE(0x30,streamFile) != read_32bitBE(0x10,streamFile)
#if 0
/* this particular glitch only true for SFA, though it
* seems like something similar happens in Donkey Konga */
/* loop start (Cstr, channel 1 & 2 headers) */
|| (read_32bitBE(0x0c,infile)+read_32bitLE(0x30,infile)) !=
read_32bitBE(0x90,infile)
|| (read_32bitBE(0x0c,streamFile)+read_32bitLE(0x30,streamFile)) !=
read_32bitBE(0x90,streamFile)
#endif
)
/* alternatively (Donkey Konga) the header loop is 0x0c+0x10 */
if (
/* loop start (Cstr header and channel 1 header) */
read_32bitBE(0x30,infile) != read_32bitBE(0x10,infile)+
read_32bitBE(0x0c,infile))
read_32bitBE(0x30,streamFile) != read_32bitBE(0x10,streamFile)+
read_32bitBE(0x0c,streamFile))
/* further alternatively (Donkey Konga), if we loop back to
* the very first frame 0x30 might be 0x00000002 (which
* is a *valid* std dsp loop start, imagine that) while 0x10
* is 0x00000000 */
if (!(read_32bitBE(0x30,infile) == 2 &&
read_32bitBE(0x10,infile) == 0))
if (!(read_32bitBE(0x30,streamFile) == 2 &&
read_32bitBE(0x10,streamFile) == 0))
/* lest there be too few alternatives, in Mr. Driller we
* find that [0x30] + [0x0c] + 8 = [0x10]*2 */
if (!(double_loop_end &&
read_32bitBE(0x30,infile) +
read_32bitBE(0x0c,infile) + 8 ==
read_32bitBE(0x10,infile)*2))
read_32bitBE(0x30,streamFile) +
read_32bitBE(0x0c,streamFile) + 8 ==
read_32bitBE(0x10,streamFile)*2))
goto fail;
#ifdef DEBUG
@ -219,13 +214,13 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
/* assure that sample counts, sample rates agree */
if (
/* sample count (channel 1 & 2 headers) */
read_32bitBE(0x20,infile) != read_32bitBE(0x80,infile) ||
read_32bitBE(0x20,streamFile) != read_32bitBE(0x80,streamFile) ||
/* sample rate (channel 1 & 2 headers) */
read_32bitBE(0x28,infile) != read_32bitBE(0x88,infile) ||
read_32bitBE(0x28,streamFile) != read_32bitBE(0x88,streamFile) ||
/* sample count (Cstr header and channel 1 header) */
read_32bitLE(0x14,infile) != read_32bitBE(0x20,infile) ||
read_32bitLE(0x14,streamFile) != read_32bitBE(0x20,streamFile) ||
/* sample rate (Cstr header and channel 1 header) */
(uint16_t)read_16bitLE(0x18,infile) != read_32bitBE(0x28,infile))
(uint16_t)read_16bitLE(0x18,streamFile) != read_32bitBE(0x28,streamFile))
goto fail;
/* build the VGMSTREAM */
@ -234,7 +229,7 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->sample_rate = read_32bitBE(0x28,infile);
vgmstream->sample_rate = read_32bitBE(0x28,streamFile);
/* This is a slight hack to counteract their hack.
* All the data is ofset by first_data so that the loop
* point occurs at a block boundary. However, I always begin decoding
@ -243,20 +238,20 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
* So we decode a few silent samples at the beginning, and here we make up
* for it by lengthening the track by that much.
*/
vgmstream->num_samples = read_32bitBE(0x20,infile) +
vgmstream->num_samples = read_32bitBE(0x20,streamFile) +
(first_data-start_offset)/8*14;
if (loop_flag) {
off_t loop_start_bytes = loop_offset-start_offset-interleave;
vgmstream->loop_start_sample = dsp_nibbles_to_samples((loop_start_bytes/(2*interleave)*interleave+loop_start_bytes%(interleave*2))*2);
/*dsp_nibbles_to_samples(loop_start_bytes);*/
/*dsp_nibbles_to_samples(read_32bitBE(0x30,infile)*2-inter);*/
/*dsp_nibbles_to_samples(read_32bitBE(0x30,streamFile)*2-inter);*/
vgmstream->loop_end_sample = dsp_nibbles_to_samples(
read_32bitBE(0x34,infile))+1;
read_32bitBE(0x34,streamFile))+1;
if (double_loop_end)
vgmstream->loop_end_sample =
dsp_nibbles_to_samples(read_32bitBE(0x34,infile)*2)+1;
dsp_nibbles_to_samples(read_32bitBE(0x34,streamFile)*2)+1;
if (vgmstream->loop_end_sample > vgmstream->num_samples) {
#ifdef DEBUG
@ -274,24 +269,22 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
{
int i;
for (i=0;i<16;i++)
vgmstream->ch[0].adpcm_coef[i]=read_16bitBE(0x3c+i*2,infile);
vgmstream->ch[0].adpcm_coef[i]=read_16bitBE(0x3c+i*2,streamFile);
for (i=0;i<16;i++)
vgmstream->ch[1].adpcm_coef[i]=read_16bitBE(0x9c+i*2,infile);
vgmstream->ch[1].adpcm_coef[i]=read_16bitBE(0x9c+i*2,streamFile);
}
#ifdef DEBUG
vgmstream->ch[0].loop_history1 = read_16bitBE(0x66,infile);
vgmstream->ch[0].loop_history2 = read_16bitBE(0x68,infile);
vgmstream->ch[1].loop_history1 = read_16bitBE(0xc6,infile);
vgmstream->ch[1].loop_history2 = read_16bitBE(0xc8,infile);
vgmstream->ch[0].loop_history1 = read_16bitBE(0x66,streamFile);
vgmstream->ch[0].loop_history2 = read_16bitBE(0x68,streamFile);
vgmstream->ch[1].loop_history1 = read_16bitBE(0xc6,streamFile);
vgmstream->ch[1].loop_history2 = read_16bitBE(0xc8,streamFile);
#endif
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
int i;
for (i=0;i<2;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,interleave);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,interleave);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -305,7 +298,6 @@ VGMSTREAM * init_vgmstream_Cstr(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -5,9 +5,8 @@
#include "meta.h"
#include "../util.h"
VGMSTREAM * init_vgmstream_adx(const char * const filename) {
VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
off_t stream_offset;
size_t filesize;
uint16_t version_signature;
@ -20,61 +19,59 @@ VGMSTREAM * init_vgmstream_adx(const char * const filename) {
meta_t header_type;
int16_t coef1, coef2;
uint16_t cutoff;
char filename[260];
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("adx",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
filesize = get_streamfile_size(infile);
filesize = get_streamfile_size(streamFile);
/* check first 2 bytes */
if ((uint16_t)read_16bitBE(0,infile)!=0x8000) goto fail;
if ((uint16_t)read_16bitBE(0,streamFile)!=0x8000) goto fail;
/* get stream offset, check for CRI signature just before */
stream_offset = (uint16_t)read_16bitBE(2,infile) + 4;
if ((uint16_t)read_16bitBE(stream_offset-6,infile)!=0x2863 ||/* "(c" */
(uint32_t)read_32bitBE(stream_offset-4,infile)!=0x29435249 /* ")CRI" */
stream_offset = (uint16_t)read_16bitBE(2,streamFile) + 4;
if ((uint16_t)read_16bitBE(stream_offset-6,streamFile)!=0x2863 ||/* "(c" */
(uint32_t)read_32bitBE(stream_offset-4,streamFile)!=0x29435249 /* ")CRI" */
) goto fail;
/* check for encoding type */
/* 2 is for some unknown fixed filter, 3 is standard ADX, 4 is
* ADX with exponential scale, 0x11 is AHX */
if (read_8bit(4,infile) != 3) goto fail;
if (read_8bit(4,streamFile) != 3) goto fail;
/* check for frame size (only 18 is supported at the moment) */
if (read_8bit(5,infile) != 18) goto fail;
if (read_8bit(5,streamFile) != 18) goto fail;
/* check for bits per sample? (only 4 makes sense for ADX) */
if (read_8bit(6,infile) != 4) goto fail;
if (read_8bit(6,streamFile) != 4) goto fail;
/* check version signature, read loop info */
version_signature = read_16bitBE(0x12,infile);
version_signature = read_16bitBE(0x12,streamFile);
if (version_signature == 0x0300) { /* type 03 */
header_type = meta_ADX_03;
if (stream_offset-6 >= 0x2c) { /* enough space for loop info? */
loop_flag = (read_32bitBE(0x18,infile) != 0);
loop_start_sample = read_32bitBE(0x1c,infile);
loop_start_offset = read_32bitBE(0x20,infile);
loop_end_sample = read_32bitBE(0x24,infile);
loop_end_offset = read_32bitBE(0x28,infile);
loop_flag = (read_32bitBE(0x18,streamFile) != 0);
loop_start_sample = read_32bitBE(0x1c,streamFile);
loop_start_offset = read_32bitBE(0x20,streamFile);
loop_end_sample = read_32bitBE(0x24,streamFile);
loop_end_offset = read_32bitBE(0x28,streamFile);
}
} else if (version_signature == 0x0400) {
off_t ainf_info_length=0;
if((uint32_t)read_32bitBE(0x24,infile)==0x41494E46) /* AINF Header */
ainf_info_length = (off_t)read_32bitBE(0x28,infile);
if((uint32_t)read_32bitBE(0x24,streamFile)==0x41494E46) /* AINF Header */
ainf_info_length = (off_t)read_32bitBE(0x28,streamFile);
header_type = meta_ADX_04;
if (stream_offset-ainf_info_length-6 >= 0x38) { /* enough space for loop info? */
loop_flag = (read_32bitBE(0x24,infile) != 0);
loop_start_sample = read_32bitBE(0x28,infile);
loop_start_offset = read_32bitBE(0x2c,infile);
loop_end_sample = read_32bitBE(0x30,infile);
loop_end_offset = read_32bitBE(0x34,infile);
loop_flag = (read_32bitBE(0x24,streamFile) != 0);
loop_start_sample = read_32bitBE(0x28,streamFile);
loop_start_offset = read_32bitBE(0x2c,streamFile);
loop_end_sample = read_32bitBE(0x30,streamFile);
loop_end_offset = read_32bitBE(0x34,streamFile);
}
} else if (version_signature == 0x0500) { /* found in some SFD : Buggy Heat, appears to have no loop */
header_type = meta_ADX_05;
@ -84,15 +81,15 @@ VGMSTREAM * init_vgmstream_adx(const char * const filename) {
* so let's build the VGMSTREAM. */
/* high-pass cutoff frequency, always 500 that I've seen */
cutoff = (uint16_t)read_16bitBE(0x10,infile);
cutoff = (uint16_t)read_16bitBE(0x10,streamFile);
channel_count = read_8bit(7,infile);
channel_count = read_8bit(7,streamFile);
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->num_samples = read_32bitBE(0xc,infile);
vgmstream->sample_rate = read_32bitBE(8,infile);
vgmstream->num_samples = read_32bitBE(0xc,streamFile);
vgmstream->sample_rate = read_32bitBE(8,streamFile);
/* channels and loop flag are set by allocate_vgmstream */
vgmstream->loop_start_sample = loop_start_sample;
vgmstream->loop_end_sample = loop_end_sample;
@ -106,8 +103,6 @@ VGMSTREAM * init_vgmstream_adx(const char * const filename) {
vgmstream->interleave_block_size=18;
close_streamfile(infile); infile=NULL;
/* calculate filter coefficients */
{
double x,y,z,a,b,c;
@ -127,7 +122,7 @@ VGMSTREAM * init_vgmstream_adx(const char * const filename) {
{
int i;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,18*0x400);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,18*0x400);
if (!vgmstream->ch[i].streamfile) goto fail;
vgmstream->ch[i].channel_start_offset=
@ -143,7 +138,6 @@ VGMSTREAM * init_vgmstream_adx(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -1,35 +1,32 @@
#include "meta.h"
#include "../util.h"
VGMSTREAM * init_vgmstream_afc(const char * const filename) {
VGMSTREAM * init_vgmstream_afc(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int loop_flag;
const int channel_count = 2; /* .afc seems to be stereo only */
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("afc",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* we will get a sample rate, that's as close to checking as I think
* we can get */
/* build the VGMSTREAM */
loop_flag = read_32bitBE(0x10,infile);
loop_flag = read_32bitBE(0x10,streamFile);
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->num_samples = read_32bitBE(0x04,infile);
vgmstream->sample_rate = (uint16_t)read_16bitBE(0x08,infile);
vgmstream->num_samples = read_32bitBE(0x04,streamFile);
vgmstream->sample_rate = (uint16_t)read_16bitBE(0x08,streamFile);
/* channels and loop flag are set by allocate_vgmstream */
vgmstream->loop_start_sample = read_32bitBE(0x14,infile);
vgmstream->loop_start_sample = read_32bitBE(0x14,streamFile);
vgmstream->loop_end_sample = vgmstream->num_samples;
vgmstream->coding_type = coding_NGC_AFC;
@ -39,13 +36,11 @@ VGMSTREAM * init_vgmstream_afc(const char * const filename) {
/* frame-level interleave (9 bytes) */
vgmstream->interleave_block_size = 9;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
int i;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,9*0x400);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,9*0x400);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -59,7 +54,6 @@ VGMSTREAM * init_vgmstream_afc(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -3,9 +3,9 @@
/* .agsc - from Metroid Prime 2 */
VGMSTREAM * init_vgmstream_agsc(const char * const filename) {
VGMSTREAM * init_vgmstream_agsc(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
off_t header_offset;
off_t start_offset;
@ -13,18 +13,15 @@ VGMSTREAM * init_vgmstream_agsc(const char * const filename) {
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("agsc",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check header */
if ((uint32_t)read_32bitBE(0,infile)!=0x00000001)
if ((uint32_t)read_32bitBE(0,streamFile)!=0x00000001)
goto fail;
/* count length of name, including terminating 0 */
for (header_offset=4;header_offset < get_streamfile_size(infile) && read_8bit(header_offset,infile)!='\0';header_offset++);
for (header_offset=4;header_offset < get_streamfile_size(streamFile) && read_8bit(header_offset,streamFile)!='\0';header_offset++);
header_offset ++;
@ -36,30 +33,28 @@ VGMSTREAM * init_vgmstream_agsc(const char * const filename) {
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->num_samples = read_32bitBE(header_offset+0xda,infile);
vgmstream->sample_rate = (uint16_t)read_16bitBE(header_offset+0xd8,infile);
vgmstream->num_samples = read_32bitBE(header_offset+0xda,streamFile);
vgmstream->sample_rate = (uint16_t)read_16bitBE(header_offset+0xd8,streamFile);
vgmstream->loop_start_sample = read_32bitBE(header_offset+0xde,infile);
vgmstream->loop_start_sample = read_32bitBE(header_offset+0xde,streamFile);
/* this is cute, we actually have a "loop length" */
vgmstream->loop_end_sample = (vgmstream->loop_start_sample + read_32bitBE(header_offset+0xe2,infile))-1;
vgmstream->loop_end_sample = (vgmstream->loop_start_sample + read_32bitBE(header_offset+0xe2,streamFile))-1;
vgmstream->coding_type = coding_NGC_DSP;
vgmstream->layout_type = layout_none;
vgmstream->meta_type = meta_DSP_AGSC;
for (i=0;i<16;i++) {
vgmstream->ch[0].adpcm_coef[i]=read_16bitBE(header_offset+0xf6+i*2,infile);
vgmstream->ch[0].adpcm_coef[i]=read_16bitBE(header_offset+0xf6+i*2,streamFile);
}
start_offset = header_offset+0x116;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
int i;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile(filename);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -73,7 +68,6 @@ VGMSTREAM * init_vgmstream_agsc(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -2,9 +2,9 @@
#include "../layout/layout.h"
#include "../util.h"
VGMSTREAM * init_vgmstream_ast(const char * const filename) {
VGMSTREAM * init_vgmstream_ast(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
coding_t coding_type;
@ -15,28 +15,25 @@ VGMSTREAM * init_vgmstream_ast(const char * const filename) {
size_t max_block;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("ast",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check header */
if ((uint32_t)read_32bitBE(0,infile)!=0x5354524D || /* "STRM" */
read_16bitBE(0xa,infile)!=0x10 ||
/* check header */
if ((uint32_t)read_32bitBE(0,streamFile)!=0x5354524D || /* "STRM" */
read_16bitBE(0xa,streamFile)!=0x10 ||
/* check that file = header (0x40) + data */
read_32bitBE(4,infile)+0x40!=get_streamfile_size(infile))
read_32bitBE(4,streamFile)+0x40!=get_streamfile_size(streamFile))
goto fail;
/* check for a first block */
if (read_32bitBE(0x40,infile)!=0x424C434B) /* "BLCK" */
if (read_32bitBE(0x40,streamFile)!=0x424C434B) /* "BLCK" */
goto fail;
/* check type details */
codec_number = read_16bitBE(8,infile);
loop_flag = read_16bitBE(0xe,infile);
channel_count = read_16bitBE(0xc,infile);
max_block = read_32bitBE(0x20,infile);
codec_number = read_16bitBE(8,streamFile);
loop_flag = read_16bitBE(0xe,streamFile);
channel_count = read_16bitBE(0xc,streamFile);
max_block = read_32bitBE(0x20,streamFile);
switch (codec_number) {
case 0:
@ -55,23 +52,21 @@ VGMSTREAM * init_vgmstream_ast(const char * const filename) {
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->num_samples = read_32bitBE(0x14,infile);
vgmstream->sample_rate = read_32bitBE(0x10,infile);
vgmstream->num_samples = read_32bitBE(0x14,streamFile);
vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
/* channels and loop flag are set by allocate_vgmstream */
vgmstream->loop_start_sample = read_32bitBE(0x18,infile);
vgmstream->loop_end_sample = read_32bitBE(0x1c,infile);
vgmstream->loop_start_sample = read_32bitBE(0x18,streamFile);
vgmstream->loop_end_sample = read_32bitBE(0x1c,streamFile);
vgmstream->coding_type = coding_type;
vgmstream->layout_type = layout_ast_blocked;
vgmstream->meta_type = meta_AST;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
int i;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
(i==0?
max_block+0x20-4: /* first buffer a bit bigger to
read block header without
@ -91,7 +86,6 @@ VGMSTREAM * init_vgmstream_ast(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -1,9 +1,9 @@
#include "meta.h"
#include "../util.h"
VGMSTREAM * init_vgmstream_brstm(const char * const filename) {
VGMSTREAM * init_vgmstream_brstm(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
coding_t coding_type;
@ -20,30 +20,27 @@ VGMSTREAM * init_vgmstream_brstm(const char * const filename) {
off_t start_offset;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("brstm",filename_extension(filename))) {
if (strcasecmp("brstmspm",filename_extension(filename))) goto fail;
else spm_flag = 1;
}
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check header */
if ((uint32_t)read_32bitBE(0,infile)!=0x5253544D || /* "RSTM" */
(uint32_t)read_32bitBE(4,infile)!=0xFEFF0100)
if ((uint32_t)read_32bitBE(0,streamFile)!=0x5253544D || /* "RSTM" */
(uint32_t)read_32bitBE(4,streamFile)!=0xFEFF0100)
goto fail;
/* get head offset, check */
head_offset = read_32bitBE(0x10,infile);
if ((uint32_t)read_32bitBE(head_offset,infile)!=0x48454144) /* "HEAD" */
head_offset = read_32bitBE(0x10,streamFile);
if ((uint32_t)read_32bitBE(head_offset,streamFile)!=0x48454144) /* "HEAD" */
goto fail;
head_length = read_32bitBE(0x14,infile);
head_length = read_32bitBE(0x14,streamFile);
/* check type details */
codec_number = read_8bit(head_offset+0x20,infile);
loop_flag = read_8bit(head_offset+0x21,infile);
channel_count = read_8bit(head_offset+0x22,infile);
codec_number = read_8bit(head_offset+0x20,streamFile);
loop_flag = read_8bit(head_offset+0x21,streamFile);
channel_count = read_8bit(head_offset+0x22,streamFile);
switch (codec_number) {
case 0:
@ -67,10 +64,10 @@ VGMSTREAM * init_vgmstream_brstm(const char * const filename) {
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->num_samples = read_32bitBE(head_offset+0x2c,infile);
vgmstream->sample_rate = (uint16_t)read_16bitBE(head_offset+0x24,infile);
vgmstream->num_samples = read_32bitBE(head_offset+0x2c,streamFile);
vgmstream->sample_rate = (uint16_t)read_16bitBE(head_offset+0x24,streamFile);
/* channels and loop flag are set by allocate_vgmstream */
vgmstream->loop_start_sample = read_32bitBE(head_offset+0x28,infile);
vgmstream->loop_start_sample = read_32bitBE(head_offset+0x28,streamFile);
vgmstream->loop_end_sample = vgmstream->num_samples;
vgmstream->coding_type = coding_type;
@ -85,8 +82,8 @@ VGMSTREAM * init_vgmstream_brstm(const char * const filename) {
vgmstream->sample_rate = 22050;
}
vgmstream->interleave_block_size = read_32bitBE(head_offset+0x38,infile);
vgmstream->interleave_smallblock_size = read_32bitBE(head_offset+0x48,infile);
vgmstream->interleave_block_size = read_32bitBE(head_offset+0x38,streamFile);
vgmstream->interleave_smallblock_size = read_32bitBE(head_offset+0x48,streamFile);
if (vgmstream->coding_type == coding_NGC_DSP) {
off_t coef_offset;
@ -94,30 +91,28 @@ VGMSTREAM * init_vgmstream_brstm(const char * const filename) {
off_t coef_offset2;
int i,j;
coef_offset1=read_32bitBE(head_offset+0x1c,infile);
coef_offset2=read_32bitBE(head_offset+0x10+coef_offset1,infile);
coef_offset1=read_32bitBE(head_offset+0x1c,streamFile);
coef_offset2=read_32bitBE(head_offset+0x10+coef_offset1,streamFile);
coef_offset=coef_offset2+0x10;
for (j=0;j<vgmstream->channels;j++) {
for (i=0;i<16;i++) {
vgmstream->ch[j].adpcm_coef[i]=read_16bitBE(head_offset+coef_offset+j*0x38+i*2,infile);
vgmstream->ch[j].adpcm_coef[i]=read_16bitBE(head_offset+coef_offset+j*0x38+i*2,streamFile);
}
}
}
start_offset = read_32bitBE(head_offset+0x30,infile);
close_streamfile(infile); infile=NULL;
start_offset = read_32bitBE(head_offset+0x30,streamFile);
/* open the file for reading by each channel */
{
int i;
for (i=0;i<channel_count;i++) {
if (vgmstream->layout_type==layout_interleave_shortblock)
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
vgmstream->interleave_block_size);
else
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
0x1000);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -132,7 +127,6 @@ VGMSTREAM * init_vgmstream_brstm(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -1,28 +1,25 @@
#include "meta.h"
#include "../util.h"
VGMSTREAM * init_vgmstream_gcsw(const char * const filename) {
VGMSTREAM * init_vgmstream_gcsw(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int channel_count;
int loop_flag;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("gcw",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check header */
if ((uint32_t)read_32bitBE(0,infile)!=0x47435357) /* "GCSW" */
/* check header */
if ((uint32_t)read_32bitBE(0,streamFile)!=0x47435357) /* "GCSW" */
goto fail;
/* check type details */
/* guess */
loop_flag = read_32bitBE(0x1c,infile);
channel_count = read_32bitBE(0xc,infile);
loop_flag = read_32bitBE(0x1c,streamFile);
channel_count = read_32bitBE(0xc,streamFile);
/* build the VGMSTREAM */
@ -30,11 +27,11 @@ VGMSTREAM * init_vgmstream_gcsw(const char * const filename) {
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->num_samples = read_32bitBE(0x10,infile);
vgmstream->sample_rate = read_32bitBE(0x8,infile);
vgmstream->num_samples = read_32bitBE(0x10,streamFile);
vgmstream->sample_rate = read_32bitBE(0x8,streamFile);
/* channels and loop flag are set by allocate_vgmstream */
vgmstream->loop_start_sample = read_32bitBE(0x14,infile);
vgmstream->loop_end_sample = read_32bitBE(0x18,infile);
vgmstream->loop_start_sample = read_32bitBE(0x14,streamFile);
vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile);
vgmstream->coding_type = coding_PCM16BE;
vgmstream->layout_type = layout_interleave;
@ -42,14 +39,11 @@ VGMSTREAM * init_vgmstream_gcsw(const char * const filename) {
vgmstream->interleave_block_size = 0x8000;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
int i;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,0x8000
);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x8000);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -63,7 +57,6 @@ VGMSTREAM * init_vgmstream_gcsw(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -3,9 +3,9 @@
#include "../layout/layout.h"
#include "../util.h"
VGMSTREAM * init_vgmstream_halpst(const char * const filename) {
VGMSTREAM * init_vgmstream_halpst(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int channel_count;
int loop_flag = 0;
@ -16,27 +16,24 @@ VGMSTREAM * init_vgmstream_halpst(const char * const filename) {
size_t max_block;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("hps",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile_buffer(filename,0x20);
if (!infile) goto fail;
/* check header */
if ((uint32_t)read_32bitBE(0,infile)!=0x2048414C || /* " HAL" */
read_32bitBE(4,infile)!=0x50535400) /* "PST\0" */
/* check header */
if ((uint32_t)read_32bitBE(0,streamFile)!=0x2048414C || /* " HAL" */
read_32bitBE(4,streamFile)!=0x50535400) /* "PST\0" */
goto fail;
/* details */
channel_count = read_32bitBE(0xc,infile);
max_block = read_32bitBE(0x10,infile);
channel_count = read_32bitBE(0xc,streamFile);
max_block = read_32bitBE(0x10,streamFile);
/* have I ever seen a mono .hps? */
if (channel_count!=2) goto fail;
/* yay for redundancy, gives us something to test */
samples_l = dsp_nibbles_to_samples(read_32bitBE(0x18,infile))+2;
samples_r = dsp_nibbles_to_samples(read_32bitBE(0x50,infile))+2;
samples_l = dsp_nibbles_to_samples(read_32bitBE(0x18,streamFile))+2;
samples_r = dsp_nibbles_to_samples(read_32bitBE(0x50,streamFile))+2;
if (samples_l != samples_r) goto fail;
@ -51,7 +48,7 @@ VGMSTREAM * init_vgmstream_halpst(const char * const filename) {
/* determine if there is a loop */
while (offset > last_offset) {
last_offset = offset;
offset = read_32bitBE(offset+8,infile);
offset = read_32bitBE(offset+8,streamFile);
}
if (offset < 0) loop_flag = 0;
else {
@ -62,8 +59,8 @@ VGMSTREAM * init_vgmstream_halpst(const char * const filename) {
loop_offset = offset;
offset = 0x80;
while (offset != loop_offset) {
start_nibble += read_32bitBE(offset,infile);
offset = read_32bitBE(offset+8,infile);
start_nibble += read_32bitBE(offset,streamFile);
offset = read_32bitBE(offset+8,streamFile);
}
start_sample = dsp_nibbles_to_samples(start_nibble)+2;
@ -78,7 +75,7 @@ VGMSTREAM * init_vgmstream_halpst(const char * const filename) {
/* fill in the vital statistics */
vgmstream->num_samples = samples_l;
vgmstream->sample_rate = read_32bitBE(8,infile);
vgmstream->sample_rate = read_32bitBE(8,streamFile);
/* channels and loop flag are set by allocate_vgmstream */
if (loop_flag) {
vgmstream->loop_start_sample = start_sample;
@ -93,18 +90,16 @@ VGMSTREAM * init_vgmstream_halpst(const char * const filename) {
{
int i;
for (i=0;i<16;i++)
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x20+i*2,infile);
vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x20+i*2,streamFile);
for (i=0;i<16;i++)
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x58+i*2,infile);
vgmstream->ch[1].adpcm_coef[i] = read_16bitBE(0x58+i*2,streamFile);
}
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
int i;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
(i==0?
max_block+0x20: /* first buffer a bit bigger to
read block header without
@ -124,7 +119,6 @@ VGMSTREAM * init_vgmstream_halpst(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -3,62 +3,62 @@
#include "../vgmstream.h"
VGMSTREAM * init_vgmstream_adx(const char * const filename);
VGMSTREAM * init_vgmstream_adx(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_afc(const char * const filename);
VGMSTREAM * init_vgmstream_afc(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_agsc(const char * const filename);
VGMSTREAM * init_vgmstream_agsc(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ast(const char * const filename);
VGMSTREAM * init_vgmstream_ast(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_brstm(const char * const filename);
VGMSTREAM * init_vgmstream_brstm(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_Cstr(const char * const filename);
VGMSTREAM * init_vgmstream_Cstr(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_gcsw(const char * const filename);
VGMSTREAM * init_vgmstream_gcsw(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_halpst(const char * const filename);
VGMSTREAM * init_vgmstream_halpst(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_nds_strm(const char * const filename);
VGMSTREAM * init_vgmstream_nds_strm(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ngc_adpdtk(const char * const filename);
VGMSTREAM * init_vgmstream_ngc_adpdtk(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ngc_dsp_std(const char * const filename);
VGMSTREAM * init_vgmstream_ngc_dsp_std(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ngc_dsp_stm(const char * const filename);
VGMSTREAM * init_vgmstream_ngc_dsp_stm(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ngc_mpdsp(const char * const filename);
VGMSTREAM * init_vgmstream_ngc_mpdsp(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ngc_dsp_std_int(const char * const filename);
VGMSTREAM * init_vgmstream_ngc_dsp_std_int(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ps2_ads(const char * const filename);
VGMSTREAM * init_vgmstream_ps2_ads(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ps2_npsf(const char * const filename);
VGMSTREAM * init_vgmstream_ps2_npsf(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_rs03(const char * const filename);
VGMSTREAM * init_vgmstream_rs03(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_rsf(const char * const filename);
VGMSTREAM * init_vgmstream_rsf(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_rwsd(const char * const filename);
VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_cdxa(const char * const filename);
VGMSTREAM * init_vgmstream_cdxa(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ps2_rxw(const char * const filename);
VGMSTREAM * init_vgmstream_ps2_rxw(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ps2_int(const char * const filename);
VGMSTREAM * init_vgmstream_ps2_int(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ps2_exst(const char * const filename);
VGMSTREAM * init_vgmstream_ps2_exst(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ps2_svag(const char * const filename);
VGMSTREAM * init_vgmstream_ps2_svag(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ps2_mib(const char * const filename);
VGMSTREAM * init_vgmstream_ps2_mib(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ps2_mic(const char * const filename);
VGMSTREAM * init_vgmstream_ps2_mic(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_raw(const char * const filename);
VGMSTREAM * init_vgmstream_raw(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_ps2_vag(const char * const filename);
VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile);
VGMSTREAM * init_vgmstream_psx_gms(const char * const filename);
VGMSTREAM * init_vgmstream_psx_gms(STREAMFILE *streamFile);
#endif

View File

@ -1,9 +1,9 @@
#include "meta.h"
#include "../util.h"
VGMSTREAM * init_vgmstream_nds_strm(const char * const filename) {
VGMSTREAM * init_vgmstream_nds_strm(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
coding_t coding_type;
@ -14,26 +14,23 @@ VGMSTREAM * init_vgmstream_nds_strm(const char * const filename) {
off_t start_offset;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("strm",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check header */
if ((uint32_t)read_32bitBE(0,infile)!=0x5354524D ||
(uint32_t)read_32bitBE(4,infile)!=0xFFFE0001)
if ((uint32_t)read_32bitBE(0,streamFile)!=0x5354524D ||
(uint32_t)read_32bitBE(4,streamFile)!=0xFFFE0001)
goto fail;
/* check for HEAD section */
if ((uint32_t)read_32bitBE(0x10,infile)!=0x48454144 || /* "HEAD" */
(uint32_t)read_32bitLE(0x14,infile)!=0x50) /* 0x50-sized head is all I've seen */
if ((uint32_t)read_32bitBE(0x10,streamFile)!=0x48454144 || /* "HEAD" */
(uint32_t)read_32bitLE(0x14,streamFile)!=0x50) /* 0x50-sized head is all I've seen */
goto fail;
/* check type details */
codec_number = read_8bit(0x18,infile);
loop_flag = read_8bit(0x19,infile);
channel_count = read_8bit(0x1a,infile);
codec_number = read_8bit(0x18,streamFile);
loop_flag = read_8bit(0x19,streamFile);
channel_count = read_8bit(0x1a,streamFile);
switch (codec_number) {
case 0:
@ -58,36 +55,34 @@ VGMSTREAM * init_vgmstream_nds_strm(const char * const filename) {
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->num_samples = read_32bitLE(0x24,infile);
vgmstream->sample_rate = (uint16_t)read_16bitLE(0x1c,infile);
vgmstream->num_samples = read_32bitLE(0x24,streamFile);
vgmstream->sample_rate = (uint16_t)read_16bitLE(0x1c,streamFile);
/* channels and loop flag are set by allocate_vgmstream */
vgmstream->loop_start_sample = read_32bitLE(0x20,infile);
vgmstream->loop_start_sample = read_32bitLE(0x20,streamFile);
vgmstream->loop_end_sample = vgmstream->num_samples;
vgmstream->coding_type = coding_type;
vgmstream->meta_type = meta_STRM;
vgmstream->interleave_block_size = read_32bitLE(0x30,infile);
vgmstream->interleave_smallblock_size = read_32bitLE(0x38,infile);
vgmstream->interleave_block_size = read_32bitLE(0x30,streamFile);
vgmstream->interleave_smallblock_size = read_32bitLE(0x38,streamFile);
if (coding_type==coding_PCM8 || coding_type==coding_PCM16LE)
vgmstream->layout_type = layout_none;
else
vgmstream->layout_type = layout_interleave_shortblock;
start_offset = read_32bitLE(0x28,infile);
close_streamfile(infile); infile=NULL;
start_offset = read_32bitLE(0x28,streamFile);
/* open the file for reading by each channel */
{
int i;
for (i=0;i<channel_count;i++) {
if (vgmstream->layout_type==layout_interleave_shortblock)
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
vgmstream->interleave_block_size);
else
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
0x1000);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -101,7 +96,6 @@ VGMSTREAM * init_vgmstream_nds_strm(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -2,28 +2,22 @@
#include "meta.h"
#include "../util.h"
VGMSTREAM * init_vgmstream_ngc_adpdtk(const char * const filename) {
VGMSTREAM * init_vgmstream_ngc_adpdtk(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
size_t file_size;
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("adp",filename_extension(filename))) goto fail;
/* try to open the file for checking */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* file size is the only way to determine sample count */
file_size = get_streamfile_size(infile);
file_size = get_streamfile_size(streamFile);
/* .adp files have no header, so all we can do is look for a valid first frame */
if (read_8bit(0,infile)!=read_8bit(2,infile) || read_8bit(1,infile)!=read_8bit(3,infile)) goto fail;
/* done with checking */
close_streamfile(infile);
if (read_8bit(0,streamFile)!=read_8bit(2,streamFile) || read_8bit(1,streamFile)!=read_8bit(3,streamFile)) goto fail;
/* Hopefully we haven't falsely detected something else... */
/* build the VGMSTREAM */
@ -40,14 +34,13 @@ VGMSTREAM * init_vgmstream_ngc_adpdtk(const char * const filename) {
vgmstream->ch[i].channel_start_offset =
vgmstream->ch[i].offset = 0;
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,32*0x400);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,32*0x400);
}
return vgmstream;
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -69,25 +69,22 @@ static int read_dsp_header(struct dsp_header *header, off_t offset, STREAMFILE *
/* the standard .dsp, as generated by DSPADPCM.exe */
VGMSTREAM * init_vgmstream_ngc_dsp_std(const char * const filename) {
VGMSTREAM * init_vgmstream_ngc_dsp_std(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
struct dsp_header header;
const off_t start_offset = 0x60;
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("dsp",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
if (read_dsp_header(&header, 0, infile)) goto fail;
if (read_dsp_header(&header, 0, streamFile)) goto fail;
/* check initial predictor/scale */
if (header.initial_ps != (uint8_t)read_8bit(start_offset,infile))
if (header.initial_ps != (uint8_t)read_8bit(start_offset,streamFile))
goto fail;
/* check type==0 and gain==0 */
@ -101,7 +98,7 @@ VGMSTREAM * init_vgmstream_ngc_dsp_std(const char * const filename) {
{
struct dsp_header header2;
read_dsp_header(&header2, 0x60, infile);
read_dsp_header(&header2, 0x60, streamFile);
if (header.sample_count == header2.sample_count &&
header.nibble_count == header2.nibble_count &&
@ -113,14 +110,14 @@ VGMSTREAM * init_vgmstream_ngc_dsp_std(const char * const filename) {
off_t loop_off;
/* check loop predictor/scale */
loop_off = header.loop_start_offset/16*8;
if (header.loop_ps != (uint8_t)read_8bit(start_offset+loop_off,infile))
if (header.loop_ps != (uint8_t)read_8bit(start_offset+loop_off,streamFile))
goto fail;
}
/* compare num_samples with nibble count */
/*
fprintf(stderr,"num samples (literal): %d\n",read_32bitBE(0,infile));
fprintf(stderr,"num samples (nibbles): %d\n",dsp_nibbles_to_samples(read_32bitBE(4,infile)));
fprintf(stderr,"num samples (literal): %d\n",read_32bitBE(0,streamFile));
fprintf(stderr,"num samples (nibbles): %d\n",dsp_nibbles_to_samples(read_32bitBE(4,streamFile)));
*/
/* build the VGMSTREAM */
@ -155,10 +152,8 @@ VGMSTREAM * init_vgmstream_ngc_dsp_std(const char * const filename) {
vgmstream->ch[0].adpcm_history1_16 = header.initial_hist1;
vgmstream->ch[0].adpcm_history2_16 = header.initial_hist2;
close_streamfile(infile); infile=NULL;
/* open the file for reading */
vgmstream->ch[0].streamfile = open_streamfile(filename);
vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!vgmstream->ch[0].streamfile) goto fail;
@ -169,7 +164,6 @@ VGMSTREAM * init_vgmstream_ngc_dsp_std(const char * const filename) {
fail:
/* clean up anything we may have opened */
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}
@ -184,9 +178,9 @@ fail:
* Used in Paper Mario 2, Fire Emblem: Path of Radiance, Cubivore
* I suspected that this was an Intelligent Systems format, but its use in
* Cubivore calls that into question. */
VGMSTREAM * init_vgmstream_ngc_dsp_stm(const char * const filename) {
VGMSTREAM * init_vgmstream_ngc_dsp_stm(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
struct dsp_header ch0_header, ch1_header;
int i;
@ -200,32 +194,29 @@ VGMSTREAM * init_vgmstream_ngc_dsp_stm(const char * const filename) {
/* to avoid collision with Scream Tracker 2 Modules, also ending in .stm
* and supported by default in Winamp, it was policy in the old days to
* rename these files to .dsp */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("stm",filename_extension(filename)) &&
strcasecmp("dsp",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check intro magic */
if (read_16bitBE(0, infile) != 0x0200) goto fail;
if (read_16bitBE(0, streamFile) != 0x0200) goto fail;
channel_count = read_32bitBE(4, infile);
channel_count = read_32bitBE(4, streamFile);
/* only stereo and mono are known */
if (channel_count != 1 && channel_count != 2) goto fail;
first_channel_size = read_32bitBE(8, infile);
first_channel_size = read_32bitBE(8, streamFile);
/* this is bad rounding, wastes space, but it looks like that's what's
* used */
second_channel_start = ((start_offset+first_channel_size)+0x20)/0x20*0x20;
/* an additional check */
stm_header_sample_rate = (uint16_t)read_16bitBE(2, infile);
stm_header_sample_rate = (uint16_t)read_16bitBE(2, streamFile);
/* read the DSP headers */
if (read_dsp_header(&ch0_header, 0x40, infile)) goto fail;
if (read_dsp_header(&ch0_header, 0x40, streamFile)) goto fail;
if (channel_count == 2) {
if (read_dsp_header(&ch1_header, 0xa0, infile)) goto fail;
if (read_dsp_header(&ch1_header, 0xa0, streamFile)) goto fail;
}
/* checks for fist channel */
@ -233,7 +224,7 @@ VGMSTREAM * init_vgmstream_ngc_dsp_stm(const char * const filename) {
if (ch0_header.sample_rate != stm_header_sample_rate) goto fail;
/* check initial predictor/scale */
if (ch0_header.initial_ps != (uint8_t)read_8bit(start_offset, infile))
if (ch0_header.initial_ps != (uint8_t)read_8bit(start_offset, streamFile))
goto fail;
/* check type==0 and gain==0 */
@ -244,7 +235,7 @@ VGMSTREAM * init_vgmstream_ngc_dsp_stm(const char * const filename) {
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(start_offset+loop_off,infile))
if (ch0_header.loop_ps != (uint8_t)read_8bit(start_offset+loop_off,streamFile))
goto fail;
}
}
@ -264,7 +255,7 @@ VGMSTREAM * init_vgmstream_ngc_dsp_stm(const char * const filename) {
) goto fail;
/* check initial predictor/scale */
if (ch1_header.initial_ps != (uint8_t)read_8bit(second_channel_start, infile))
if (ch1_header.initial_ps != (uint8_t)read_8bit(second_channel_start, streamFile))
goto fail;
/* check type==0 and gain==0 */
@ -276,7 +267,7 @@ VGMSTREAM * init_vgmstream_ngc_dsp_stm(const char * const filename) {
/* check loop predictor/scale */
loop_off = ch1_header.loop_start_offset/16*8;
/*printf("loop_start_offset=%x\nloop_ps=%x\nloop_off=%x\n",ch1_header.loop_start_offset,ch1_header.loop_ps,second_channel_start+loop_off);*/
if (ch1_header.loop_ps != (uint8_t)read_8bit(second_channel_start+loop_off,infile))
if (ch1_header.loop_ps != (uint8_t)read_8bit(second_channel_start+loop_off,streamFile))
goto fail;
}
}
@ -323,10 +314,8 @@ VGMSTREAM * init_vgmstream_ngc_dsp_stm(const char * const filename) {
vgmstream->ch[1].adpcm_history2_16 = ch1_header.initial_hist2;
}
close_streamfile(infile); infile=NULL;
/* open the file for reading */
vgmstream->ch[0].streamfile = open_streamfile(filename);
vgmstream->ch[0].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!vgmstream->ch[0].streamfile) goto fail;
@ -334,7 +323,7 @@ VGMSTREAM * init_vgmstream_ngc_dsp_stm(const char * const filename) {
vgmstream->ch[0].offset=start_offset;
if (channel_count == 2) {
vgmstream->ch[1].streamfile = open_streamfile(filename);
vgmstream->ch[1].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!vgmstream->ch[1].streamfile) goto fail;
@ -346,7 +335,6 @@ VGMSTREAM * init_vgmstream_ngc_dsp_stm(const char * const filename) {
fail:
/* clean up anything we may have opened */
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}
@ -357,28 +345,25 @@ fail:
* can catch this.
*/
VGMSTREAM * init_vgmstream_ngc_mpdsp(const char * const filename) {
VGMSTREAM * init_vgmstream_ngc_mpdsp(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
struct dsp_header header;
const off_t start_offset = 0x60;
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("mpdsp",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
if (read_dsp_header(&header, 0, infile)) goto fail;
if (read_dsp_header(&header, 0, streamFile)) goto fail;
/* none have loop flag set, save us from loop code that involves them */
if (header.loop_flag) goto fail;
/* check initial predictor/scale */
if (header.initial_ps != (uint8_t)read_8bit(start_offset,infile))
if (header.initial_ps != (uint8_t)read_8bit(start_offset,streamFile))
goto fail;
/* check type==0 and gain==0 */
@ -414,11 +399,9 @@ VGMSTREAM * init_vgmstream_ngc_mpdsp(const char * const filename) {
vgmstream->ch[1].adpcm_history1_16 = header.initial_hist1;
vgmstream->ch[1].adpcm_history2_16 = header.initial_hist2;
close_streamfile(infile); infile=NULL;
/* open the file for reading */
for (i=0;i<2;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
vgmstream->interleave_block_size);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -432,7 +415,6 @@ VGMSTREAM * init_vgmstream_ngc_mpdsp(const char * const filename) {
fail:
/* clean up anything we may have opened */
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}
@ -440,9 +422,9 @@ fail:
/* a bunch of formats that are identical except for file extension,
* but have different interleaves */
VGMSTREAM * init_vgmstream_ngc_dsp_std_int(const char * const filename) {
VGMSTREAM * init_vgmstream_ngc_dsp_std_int(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
const off_t start_offset = 0xc0;
off_t interleave;
@ -452,6 +434,7 @@ VGMSTREAM * init_vgmstream_ngc_dsp_std_int(const char * const filename) {
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strlen(filename) > 7 && !strcasecmp("_lr.dsp",filename+strlen(filename)-7)) {
/* Bomberman Jetters */
interleave = 0x14180;
@ -464,18 +447,13 @@ VGMSTREAM * init_vgmstream_ngc_dsp_std_int(const char * const filename) {
meta_type = meta_DSP_GCM;
} else goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
if (read_dsp_header(&ch0_header, 0, infile)) goto fail;
if (read_dsp_header(&ch1_header, 0x60, infile)) goto fail;
if (read_dsp_header(&ch0_header, 0, streamFile)) goto fail;
if (read_dsp_header(&ch1_header, 0x60, streamFile)) goto fail;
/* check initial predictor/scale */
if (ch0_header.initial_ps != (uint8_t)read_8bit(start_offset,infile))
if (ch0_header.initial_ps != (uint8_t)read_8bit(start_offset,streamFile))
goto fail;
if (ch1_header.initial_ps != (uint8_t)read_8bit(start_offset+interleave,infile))
if (ch1_header.initial_ps != (uint8_t)read_8bit(start_offset+interleave,streamFile))
goto fail;
/* check type==0 and gain==0 */
@ -498,9 +476,9 @@ VGMSTREAM * init_vgmstream_ngc_dsp_std_int(const char * const filename) {
/* check loop predictor/scale */
loop_off = ch0_header.loop_start_offset/16*8;
loop_off = (loop_off/interleave*interleave*2) + (loop_off%interleave);
if (ch0_header.loop_ps != (uint8_t)read_8bit(start_offset+loop_off,infile))
if (ch0_header.loop_ps != (uint8_t)read_8bit(start_offset+loop_off,streamFile))
goto fail;
if (ch1_header.loop_ps != (uint8_t)read_8bit(start_offset+loop_off+interleave,infile))
if (ch1_header.loop_ps != (uint8_t)read_8bit(start_offset+loop_off+interleave,streamFile))
goto fail;
}
@ -537,11 +515,9 @@ VGMSTREAM * init_vgmstream_ngc_dsp_std_int(const char * const filename) {
vgmstream->ch[1].adpcm_history1_16 = ch1_header.initial_hist1;
vgmstream->ch[1].adpcm_history2_16 = ch1_header.initial_hist2;
close_streamfile(infile); infile=NULL;
/* open the file for reading */
for (i=0;i<2;i++) {
vgmstream->ch[i].streamfile = open_streamfile(filename);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -553,7 +529,6 @@ VGMSTREAM * init_vgmstream_ngc_dsp_std_int(const char * const filename) {
fail:
/* clean up anything we may have opened */
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -3,77 +3,72 @@
/* Sony .ADS with SShd & SSbd Headers */
VGMSTREAM * init_vgmstream_ps2_ads(const char * const filename) {
VGMSTREAM * init_vgmstream_ps2_ads(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int loop_flag=0;
int channel_count;
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("ads",filename_extension(filename)) &&
strcasecmp("ss2",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check SShd Header */
if (read_32bitBE(0x00,infile) != 0x53536864)
if (read_32bitBE(0x00,streamFile) != 0x53536864)
goto fail;
/* check SSbd Header */
if (read_32bitBE(0x20,infile) != 0x53536264)
if (read_32bitBE(0x20,streamFile) != 0x53536264)
goto fail;
/* check if file is not corrupt */
if (get_streamfile_size(infile)<(size_t)(read_32bitLE(0x24,infile) + 0x28))
if (get_streamfile_size(streamFile)<(size_t)(read_32bitLE(0x24,streamFile) + 0x28))
goto fail;
/* check loop */
loop_flag = (read_32bitLE(0x18,infile)!=0xFFFFFFFF);
loop_flag = (read_32bitLE(0x18,streamFile)!=0xFFFFFFFF);
channel_count=read_32bitLE(0x10,infile);
channel_count=read_32bitLE(0x10,streamFile);
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->channels = read_32bitLE(0x10,infile);
vgmstream->sample_rate = read_32bitLE(0x0C,infile);
vgmstream->channels = read_32bitLE(0x10,streamFile);
vgmstream->sample_rate = read_32bitLE(0x0C,streamFile);
/* Check for Compression Scheme */
vgmstream->coding_type = coding_PSX;
vgmstream->num_samples = read_32bitLE(0x24,infile)/16*28/vgmstream->channels;
vgmstream->num_samples = read_32bitLE(0x24,streamFile)/16*28/vgmstream->channels;
/* SS2 container with RAW Interleaved PCM */
if (read_32bitLE(0x08,infile)!=0x10) {
if (read_32bitLE(0x08,streamFile)!=0x10) {
vgmstream->coding_type=coding_PCM16LE;
vgmstream->num_samples = read_32bitLE(0x24,infile)/2/vgmstream->channels;
vgmstream->num_samples = read_32bitLE(0x24,streamFile)/2/vgmstream->channels;
}
/* Get loop point values */
if(vgmstream->loop_flag) {
vgmstream->loop_start_sample = read_32bitLE(0x18,infile);
vgmstream->loop_end_sample = read_32bitLE(0x1C,infile);
vgmstream->loop_start_sample = read_32bitLE(0x18,streamFile);
vgmstream->loop_end_sample = read_32bitLE(0x1C,streamFile);
}
/* don't know why, but it does happen, in ps2 too :( */
if (vgmstream->loop_end_sample > vgmstream->num_samples)
vgmstream->loop_end_sample = vgmstream->num_samples;
vgmstream->interleave_block_size = read_32bitLE(0x14,infile);
vgmstream->interleave_block_size = read_32bitLE(0x14,streamFile);
vgmstream->layout_type = layout_interleave;
vgmstream->meta_type = meta_PS2_SShd;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,0x8000);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x8000);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -87,7 +82,6 @@ VGMSTREAM * init_vgmstream_ps2_ads(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -14,58 +14,53 @@
2008-05-13 - Fastelbja : First version ...
*/
VGMSTREAM * init_vgmstream_ps2_exst(const char * const filename) {
VGMSTREAM * init_vgmstream_ps2_exst(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int loop_flag=0;
int channel_count;
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("sts",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check EXST Header */
if (read_32bitBE(0x00,infile) != 0x45585354)
if (read_32bitBE(0x00,streamFile) != 0x45585354)
goto fail;
/* check loop */
loop_flag = (read_32bitLE(0x0C,infile)==1);
loop_flag = (read_32bitLE(0x0C,streamFile)==1);
channel_count=read_16bitLE(0x06,infile);
channel_count=read_16bitLE(0x06,streamFile);
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->channels = read_16bitLE(0x06,infile);
vgmstream->sample_rate = read_32bitLE(0x08,infile);
vgmstream->channels = read_16bitLE(0x06,streamFile);
vgmstream->sample_rate = read_32bitLE(0x08,streamFile);
/* Compression Scheme */
vgmstream->coding_type = coding_PSX;
vgmstream->num_samples = (read_32bitLE(0x14,infile)*0x400)/16*28;
vgmstream->num_samples = (read_32bitLE(0x14,streamFile)*0x400)/16*28;
/* Get loop point values */
if(vgmstream->loop_flag) {
vgmstream->loop_start_sample = (read_32bitLE(0x10,infile)*0x400)/16*28;
vgmstream->loop_end_sample = (read_32bitLE(0x14,infile)*0x400)/16*28;
vgmstream->loop_start_sample = (read_32bitLE(0x10,streamFile)*0x400)/16*28;
vgmstream->loop_end_sample = (read_32bitLE(0x14,streamFile)*0x400)/16*28;
}
vgmstream->interleave_block_size = 0x400;
vgmstream->layout_type = layout_interleave;
vgmstream->meta_type = meta_PS2_EXST;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,0x8000);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x8000);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -79,7 +74,6 @@ VGMSTREAM * init_vgmstream_ps2_exst(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -12,18 +12,15 @@
2008-05-11 - Fastelbja : First version ...
*/
VGMSTREAM * init_vgmstream_ps2_int(const char * const filename) {
VGMSTREAM * init_vgmstream_ps2_int(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("int",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* No check to do as they are raw pcm */
/* build the VGMSTREAM */
@ -34,17 +31,15 @@ VGMSTREAM * init_vgmstream_ps2_int(const char * const filename) {
vgmstream->channels = 2;
vgmstream->sample_rate = 48000;
vgmstream->coding_type = coding_PCM16LE;
vgmstream->num_samples = (int32_t)(get_streamfile_size(infile)/4);
vgmstream->num_samples = (int32_t)(get_streamfile_size(streamFile)/4);
vgmstream->interleave_block_size = 0x200;
vgmstream->layout_type = layout_interleave;
vgmstream->meta_type = meta_PS2_RAW;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
for (i=0;i<2;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,0x8000);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x8000);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -57,7 +52,6 @@ VGMSTREAM * init_vgmstream_ps2_int(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -30,12 +30,12 @@
2008-05-14 - Fastelbja : First version ...
*/
VGMSTREAM * init_vgmstream_ps2_mib(const char * const filename) {
VGMSTREAM * init_vgmstream_ps2_mib(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
STREAMFILE * infileMIH = NULL;
STREAMFILE * streamFileMIH = NULL;
char filename[260];
uint8_t mibBuffer[0x10];
uint8_t testBuffer[0x10];
@ -46,41 +46,32 @@ VGMSTREAM * init_vgmstream_ps2_mib(const char * const filename) {
off_t interleave = 0;
off_t readOffset = 0;
char * filenameMIH = NULL;
char filenameMIH[260];
uint8_t gotMIH=0;
int i, channel_count=1;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("mib",filename_extension(filename)) &&
strcasecmp("mi4",filename_extension(filename))) goto fail;
/* check for .MIH file */
filenameMIH=(char *)malloc(strlen(filename)+1);
if (!filenameMIH) goto fail;
strcpy(filenameMIH,filename);
strcpy(filenameMIH+strlen(filenameMIH)-3,"MIH");
infileMIH = open_streamfile(filenameMIH);
if (infileMIH) gotMIH = 1;
streamFileMIH = streamFile->open(streamFile,filenameMIH,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (streamFileMIH) gotMIH = 1;
free(filenameMIH); filenameMIH = NULL;
/* Search for interleave value & loop points */
/* Search for interleave value & loop points */
/* Get the first 16 values */
infile=open_streamfile_buffer(filename,0x8000);
if(!infile) goto fail;
fileLength = get_streamfile_size(infile);
fileLength = get_streamfile_size(streamFile);
readOffset+=read_streamfile(mibBuffer,0,0x10,infile);
readOffset+=read_streamfile(mibBuffer,0,0x10,streamFile);
do {
readOffset+=read_streamfile(testBuffer,readOffset,0x10,infile);
readOffset+=read_streamfile(testBuffer,readOffset,0x10,streamFile);
if(!memcmp(testBuffer,mibBuffer,0x10)) {
if(interleave==0) interleave=readOffset-0x10;
@ -101,10 +92,10 @@ VGMSTREAM * init_vgmstream_ps2_mib(const char * const filename) {
if(loopEnd==0) loopEnd = readOffset-0x10;
}
} while (infile->offset<fileLength);
} while (streamFile->get_offset(streamFile)<fileLength);
if(gotMIH)
channel_count=read_32bitLE(0x08,infileMIH);
channel_count=read_32bitLE(0x08,streamFileMIH);
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,(loopStart!=0));
@ -113,12 +104,12 @@ VGMSTREAM * init_vgmstream_ps2_mib(const char * const filename) {
/* fill in the vital statistics */
if(gotMIH) {
// Read stuff from the MIH file
vgmstream->channels = read_32bitLE(0x08,infileMIH);
vgmstream->sample_rate = read_32bitLE(0x0C,infileMIH);
vgmstream->interleave_block_size = read_32bitLE(0x10,infileMIH);
vgmstream->num_samples=((read_32bitLE(0x10,infileMIH)*
(read_32bitLE(0x14,infileMIH)-1)*2)+
((read_32bitLE(0x04,infileMIH)>>8)*2))/16*28/2;
vgmstream->channels = read_32bitLE(0x08,streamFileMIH);
vgmstream->sample_rate = read_32bitLE(0x0C,streamFileMIH);
vgmstream->interleave_block_size = read_32bitLE(0x10,streamFileMIH);
vgmstream->num_samples=((read_32bitLE(0x10,streamFileMIH)*
(read_32bitLE(0x14,streamFileMIH)-1)*2)+
((read_32bitLE(0x04,streamFileMIH)>>8)*2))/16*28/2;
} else {
vgmstream->channels = channel_count;
vgmstream->interleave_block_size = interleave;
@ -143,17 +134,16 @@ VGMSTREAM * init_vgmstream_ps2_mib(const char * const filename) {
vgmstream->layout_type = layout_interleave;
vgmstream->meta_type = meta_PS2_MIB;
close_streamfile(infile); infile=NULL;
if (gotMIH) {
vgmstream->meta_type = meta_PS2_MIB_MIH;
close_streamfile(infileMIH); infileMIH=NULL;
close_streamfile(streamFileMIH); streamFileMIH=NULL;
}
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,0x8000);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x8000);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -166,9 +156,7 @@ VGMSTREAM * init_vgmstream_ps2_mib(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (infileMIH) close_streamfile(infileMIH);
if (filenameMIH) {free(filenameMIH); filenameMIH=NULL;}
if (streamFileMIH) close_streamfile(streamFileMIH);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -10,29 +10,26 @@
2008-05-15 - Fastelbja : First version ...
*/
VGMSTREAM * init_vgmstream_ps2_mic(const char * const filename) {
VGMSTREAM * init_vgmstream_ps2_mic(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int loop_flag=0;
int channel_count;
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("mic",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check Header */
if (read_32bitLE(0x00,infile) != 0x800)
if (read_32bitLE(0x00,streamFile) != 0x800)
goto fail;
/* check loop */
loop_flag = (read_32bitLE(0x14,infile)!=1);
loop_flag = (read_32bitLE(0x14,streamFile)!=1);
channel_count=read_32bitLE(0x08,infile);
channel_count=read_32bitLE(0x08,streamFile);
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
@ -40,28 +37,26 @@ VGMSTREAM * init_vgmstream_ps2_mic(const char * const filename) {
/* fill in the vital statistics */
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitLE(0x04,infile);
vgmstream->sample_rate = read_32bitLE(0x04,streamFile);
/* Compression Scheme */
vgmstream->coding_type = coding_PSX;
vgmstream->num_samples = read_32bitLE(0x10,infile)*14*channel_count;
vgmstream->num_samples = read_32bitLE(0x10,streamFile)*14*channel_count;
/* Get loop point values */
if(vgmstream->loop_flag) {
vgmstream->loop_start_sample = read_32bitLE(0x14,infile)*14*channel_count;
vgmstream->loop_end_sample = read_32bitLE(0x10,infile)*14*channel_count;
vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile)*14*channel_count;
vgmstream->loop_end_sample = read_32bitLE(0x10,streamFile)*14*channel_count;
}
vgmstream->interleave_block_size = read_32bitLE(0x0C,infile);
vgmstream->interleave_block_size = read_32bitLE(0x0C,streamFile);
vgmstream->layout_type = layout_interleave;
vgmstream->meta_type = meta_PS2_MIC;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,vgmstream->interleave_block_size);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,vgmstream->interleave_block_size);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -75,7 +70,6 @@ VGMSTREAM * init_vgmstream_ps2_mic(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -3,9 +3,9 @@
/* Sony .ADS with SShd & SSbd Headers */
VGMSTREAM * init_vgmstream_ps2_npsf(const char * const filename) {
VGMSTREAM * init_vgmstream_ps2_npsf(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int loop_flag=0;
int channel_count;
@ -13,50 +13,45 @@ VGMSTREAM * init_vgmstream_ps2_npsf(const char * const filename) {
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("npsf",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check NPSF Header */
if (read_32bitBE(0x00,infile) != 0x4E505346)
if (read_32bitBE(0x00,streamFile) != 0x4E505346)
goto fail;
/* check loop */
loop_flag = (read_32bitLE(0x14,infile)!=0xFFFFFFFF);
channel_count=read_32bitLE(0x0C,infile);
loop_flag = (read_32bitLE(0x14,streamFile)!=0xFFFFFFFF);
channel_count=read_32bitLE(0x0C,streamFile);
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->channels = read_32bitLE(0x0C,infile);
vgmstream->sample_rate = read_32bitLE(0x18,infile);
vgmstream->channels = read_32bitLE(0x0C,streamFile);
vgmstream->sample_rate = read_32bitLE(0x18,streamFile);
/* Check for Compression Scheme */
vgmstream->coding_type = coding_PSX;
vgmstream->num_samples = read_32bitLE(0x08,infile)*28/16;
vgmstream->num_samples = read_32bitLE(0x08,streamFile)*28/16;
/* Get loop point values */
if(vgmstream->loop_flag) {
vgmstream->loop_start_sample = read_32bitLE(0x14,infile);
vgmstream->loop_end_sample = read_32bitLE(0x08,infile)*28/16;
vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile);
vgmstream->loop_end_sample = read_32bitLE(0x08,streamFile)*28/16;
}
vgmstream->interleave_block_size = read_32bitLE(0x04,infile)/2;
vgmstream->interleave_block_size = read_32bitLE(0x04,streamFile)/2;
vgmstream->layout_type = layout_interleave;
vgmstream->meta_type = meta_PS2_NPSF;
start_offset = (off_t)read_32bitLE(0x10,infile);
close_streamfile(infile); infile=NULL;
start_offset = (off_t)read_32bitLE(0x10,streamFile);
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,0x8000);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x8000);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -70,7 +65,6 @@ VGMSTREAM * init_vgmstream_ps2_npsf(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -3,9 +3,9 @@
/* RXW file (Arc the Lad) */
VGMSTREAM * init_vgmstream_ps2_rxw(const char * const filename) {
VGMSTREAM * init_vgmstream_ps2_rxw(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int loop_flag=0;
int channel_count;
@ -13,19 +13,16 @@ VGMSTREAM * init_vgmstream_ps2_rxw(const char * const filename) {
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("rxw",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check RXWS/FORM Header */
if (!((read_32bitBE(0x00,infile) == 0x52585753) &&
(read_32bitBE(0x10,infile) == 0x464F524D)))
if (!((read_32bitBE(0x00,streamFile) == 0x52585753) &&
(read_32bitBE(0x10,streamFile) == 0x464F524D)))
goto fail;
/* check loop */
loop_flag = (read_32bitLE(0x3C,infile)!=0xFFFFFFFF);
loop_flag = (read_32bitLE(0x3C,streamFile)!=0xFFFFFFFF);
/* Always stereo files */
channel_count=2;
@ -36,29 +33,27 @@ VGMSTREAM * init_vgmstream_ps2_rxw(const char * const filename) {
/* fill in the vital statistics */
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitLE(0x2E,infile);
vgmstream->sample_rate = read_32bitLE(0x2E,streamFile);
vgmstream->coding_type = coding_PSX;
vgmstream->num_samples = (read_32bitLE(0x38,infile)*28/16)/2;
vgmstream->num_samples = (read_32bitLE(0x38,streamFile)*28/16)/2;
/* Get loop point values */
if(vgmstream->loop_flag) {
vgmstream->loop_start_sample = read_32bitLE(0x3C,infile)/16*14;
vgmstream->loop_end_sample = read_32bitLE(0x38,infile)/16*14;
vgmstream->loop_start_sample = read_32bitLE(0x3C,streamFile)/16*14;
vgmstream->loop_end_sample = read_32bitLE(0x38,streamFile)/16*14;
}
vgmstream->interleave_block_size = read_32bitLE(0x1c,infile)+0x10;
vgmstream->interleave_block_size = read_32bitLE(0x1c,streamFile)+0x10;
vgmstream->layout_type = layout_interleave;
vgmstream->meta_type = meta_PS2_RXW;
start_offset = 0x40;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,0x8000);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x8000);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -72,7 +67,6 @@ VGMSTREAM * init_vgmstream_ps2_rxw(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -12,66 +12,61 @@
Thx to HCS for his awesome work on shortblock interleave
*/
VGMSTREAM * init_vgmstream_ps2_svag(const char * const filename) {
VGMSTREAM * init_vgmstream_ps2_svag(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int loop_flag=0;
int channel_count;
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("svag",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check SVAG Header */
if (read_32bitBE(0x00,infile) != 0x53766167)
if (read_32bitBE(0x00,streamFile) != 0x53766167)
goto fail;
/* check loop */
loop_flag = (read_32bitLE(0x14,infile)==1);
loop_flag = (read_32bitLE(0x14,streamFile)==1);
channel_count=read_16bitLE(0x0C,infile);
channel_count=read_16bitLE(0x0C,streamFile);
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->channels = read_16bitLE(0x0C,infile);
vgmstream->sample_rate = read_32bitLE(0x08,infile);
vgmstream->channels = read_16bitLE(0x0C,streamFile);
vgmstream->sample_rate = read_32bitLE(0x08,streamFile);
/* Compression Scheme */
vgmstream->coding_type = coding_PSX;
vgmstream->num_samples = read_32bitLE(0x04,infile)/16*28/vgmstream->channels;
vgmstream->num_samples = read_32bitLE(0x04,streamFile)/16*28/vgmstream->channels;
/* Get loop point values */
if(vgmstream->loop_flag) {
vgmstream->loop_start_sample = read_32bitLE(0x18,infile)/16*28;
vgmstream->loop_end_sample = read_32bitLE(0x04,infile)/16*28/vgmstream->channels;
vgmstream->loop_start_sample = read_32bitLE(0x18,streamFile)/16*28;
vgmstream->loop_end_sample = read_32bitLE(0x04,streamFile)/16*28/vgmstream->channels;
}
vgmstream->interleave_block_size = read_32bitLE(0x10,infile);
vgmstream->interleave_block_size = read_32bitLE(0x10,streamFile);
if (channel_count > 1) {
vgmstream->interleave_smallblock_size = (read_32bitLE(0x04,infile)%(vgmstream->channels*vgmstream->interleave_block_size))/vgmstream->channels;
vgmstream->interleave_smallblock_size = (read_32bitLE(0x04,streamFile)%(vgmstream->channels*vgmstream->interleave_block_size))/vgmstream->channels;
vgmstream->layout_type = layout_interleave_shortblock;
} else {
vgmstream->layout_type = layout_none;
}
vgmstream->meta_type = meta_PS2_SVAG;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
if (channel_count > 1)
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,vgmstream->interleave_block_size);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,vgmstream->interleave_block_size);
else
vgmstream->ch[i].streamfile = open_streamfile(filename);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -85,7 +80,6 @@ VGMSTREAM * init_vgmstream_ps2_svag(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -11,9 +11,9 @@
2008-05-17 - Fastelbja : First version ...
*/
VGMSTREAM * init_vgmstream_ps2_vag(const char * const filename) {
VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
// used for loop points ...
uint8_t eofVAG[16]={0x00,0x07,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77,0x77};
@ -36,49 +36,46 @@ VGMSTREAM * init_vgmstream_ps2_vag(const char * const filename) {
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("vag",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile_buffer(filename,0x8000);
if (!infile) goto fail;
/* check VAG Header */
if (((read_32bitBE(0x00,infile) & 0xFFFFFF00) != 0x56414700) &&
((read_32bitLE(0x00,infile) & 0xFFFFFF00) != 0x56414700))
if (((read_32bitBE(0x00,streamFile) & 0xFFFFFF00) != 0x56414700) &&
((read_32bitLE(0x00,streamFile) & 0xFFFFFF00) != 0x56414700))
goto fail;
/* Check for correct channel count */
vagID=read_8bit(0x03,infile);
vagID=read_8bit(0x03,streamFile);
switch(vagID) {
case 'i':
channel_count=2;
break;
case 'V':
if(read_32bitBE(0x20,infile)==0x53746572) // vag Stereo
if(read_32bitBE(0x20,streamFile)==0x53746572) // vag Stereo
channel_count=2;
case 'p':
/* Search for loop in VAG */
fileLength = get_streamfile_size(infile);
fileLength = get_streamfile_size(streamFile);
do {
readOffset+=0x10;
// Loop Start ...
if(read_8bit(readOffset+0x01,infile)==0x06) {
if(read_8bit(readOffset+0x01,streamFile)==0x06) {
if(loopStart==0) loopStart = readOffset;
}
// Loop End ...
if(read_8bit(readOffset+0x01,infile)==0x03) {
if(read_8bit(readOffset+0x01,streamFile)==0x03) {
if(loopEnd==0) loopEnd = readOffset;
}
// Loop from end to beginning ...
if((read_8bit(readOffset+0x01,infile)==0x01)) {
if((read_8bit(readOffset+0x01,streamFile)==0x01)) {
// Check if we have the eof tag after the loop point ...
// if so we don't loop, if not present, we loop from end to start ...
read_streamfile(readbuf,readOffset+0x10,0x10,infile);
read_streamfile(readbuf,readOffset+0x10,0x10,streamFile);
if((readbuf[0]!=0) && (readbuf[0]!=0x0c)) {
if(memcmp(readbuf,eofVAG,0x10) && (memcmp(readbuf,eofVAG2,0x10))) {
loopStart = 0x40;
@ -87,7 +84,7 @@ VGMSTREAM * init_vgmstream_ps2_vag(const char * const filename) {
}
}
} while (infile->offset<(off_t)fileLength);
} while (streamFile->get_offset(streamFile)<(off_t)fileLength);
loop_flag = (loopEnd!=0);
break;
default:
@ -104,16 +101,16 @@ VGMSTREAM * init_vgmstream_ps2_vag(const char * const filename) {
switch(vagID) {
case 'i': // VAGi
vgmstream->layout_type=layout_interleave;
vgmstream->sample_rate = read_32bitBE(0x10,infile);
vgmstream->num_samples = read_32bitBE(0x0C,infile)/16*28;
interleave = read_32bitLE(0x08,infile);
vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
vgmstream->num_samples = read_32bitBE(0x0C,streamFile)/16*28;
interleave = read_32bitLE(0x08,streamFile);
vgmstream->meta_type=meta_PS2_VAGi;
start_offset=0x800;
break;
case 'p': // VAGp
vgmstream->layout_type=layout_none;
vgmstream->sample_rate = read_32bitBE(0x10,infile);
vgmstream->num_samples = read_32bitBE(0x0C,infile)/16*28;
vgmstream->sample_rate = read_32bitBE(0x10,streamFile);
vgmstream->num_samples = read_32bitBE(0x0C,streamFile)/16*28;
vgmstream->meta_type=meta_PS2_VAGp;
interleave=0x10; // used for loop calc
start_offset=0x30;
@ -123,11 +120,11 @@ VGMSTREAM * init_vgmstream_ps2_vag(const char * const filename) {
interleave=0x2000;
// Jak X hack ...
if(read_32bitLE(0x1000,infile)==0x56414770)
if(read_32bitLE(0x1000,streamFile)==0x56414770)
interleave=0x1000;
vgmstream->sample_rate = read_32bitLE(0x10,infile);
vgmstream->num_samples = read_32bitLE(0x0C,infile)/16*14;
vgmstream->sample_rate = read_32bitLE(0x10,streamFile);
vgmstream->num_samples = read_32bitLE(0x0C,streamFile)/16*14;
vgmstream->meta_type=meta_PS2_pGAV;
start_offset=0;
break;
@ -151,12 +148,10 @@ VGMSTREAM * init_vgmstream_ps2_vag(const char * const filename) {
/* Compression Scheme */
vgmstream->coding_type = coding_PSX;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,vgmstream->interleave_block_size);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,vgmstream->interleave_block_size);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -170,7 +165,6 @@ VGMSTREAM * init_vgmstream_ps2_vag(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -5,7 +5,7 @@
/* Sony PSX CD-XA */
/* No looped file ! */
off_t init_xa_channel(int channel,STREAMFILE *infile);
off_t init_xa_channel(int channel,STREAMFILE *streamFile);
uint8_t AUDIO_CODING_GET_STEREO(uint8_t value) {
return (uint8_t)(value & 3);
@ -15,9 +15,9 @@ uint8_t AUDIO_CODING_GET_FREQ(uint8_t value) {
return (uint8_t)((value >> 2) & 3);
}
VGMSTREAM * init_vgmstream_cdxa(const char * const filename) {
VGMSTREAM * init_vgmstream_cdxa(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int channel_count;
uint8_t bCoding;
@ -26,26 +26,23 @@ VGMSTREAM * init_vgmstream_cdxa(const char * const filename) {
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("xa",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check RIFF Header */
if (!((read_32bitBE(0x00,infile) == 0x52494646) &&
(read_32bitBE(0x08,infile) == 0x43445841) &&
(read_32bitBE(0x0C,infile) == 0x666D7420)))
if (!((read_32bitBE(0x00,streamFile) == 0x52494646) &&
(read_32bitBE(0x08,streamFile) == 0x43445841) &&
(read_32bitBE(0x0C,streamFile) == 0x666D7420)))
goto fail;
/* First init to have the correct info of the channel */
start_offset=init_xa_channel(0,infile);
start_offset=init_xa_channel(0,streamFile);
/* No sound ? */
if(start_offset==0)
goto fail;
bCoding = read_8bit(start_offset-5,infile);
bCoding = read_8bit(start_offset-5,streamFile);
switch (AUDIO_CODING_GET_STEREO(bCoding)) {
case 0: channel_count = 1; break;
@ -69,17 +66,15 @@ VGMSTREAM * init_vgmstream_cdxa(const char * const filename) {
/* Check for Compression Scheme */
vgmstream->coding_type = coding_XA;
vgmstream->num_samples = (int32_t)((((get_streamfile_size(infile) - 0x3C)/2352)*0x1F80)/(2*channel_count));
vgmstream->num_samples = (int32_t)((((get_streamfile_size(streamFile) - 0x3C)/2352)*0x1F80)/(2*channel_count));
vgmstream->layout_type = layout_xa_blocked;
vgmstream->meta_type = meta_PSX_XA;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,0x8000);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x8000);
if (!vgmstream->ch[i].streamfile) goto fail;
}
@ -91,15 +86,14 @@ VGMSTREAM * init_vgmstream_cdxa(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}
off_t init_xa_channel(int channel,STREAMFILE* infile) {
off_t init_xa_channel(int channel,STREAMFILE* streamFile) {
off_t block_offset=0x44;
size_t filelength=get_streamfile_size(infile);
size_t filelength=get_streamfile_size(streamFile);
int8_t currentChannel;
int8_t subAudio;
@ -110,8 +104,8 @@ begin:
if(block_offset>=filelength)
return 0;
currentChannel=read_8bit(block_offset-7,infile);
subAudio=read_8bit(block_offset-6,infile);
currentChannel=read_8bit(block_offset-7,streamFile);
subAudio=read_8bit(block_offset-6,streamFile);
if (!((currentChannel==channel) && (subAudio==0x64))) {
block_offset+=2352;
goto begin;

View File

@ -1,6 +1,6 @@
#include "meta.h"
#include "../util.h"
#include "meta.h"
#include "../util.h"
/* GMS
PSX GMS format has no recognition ID.
@ -10,73 +10,67 @@
known extensions : GMS
2008-05-19 - Fastelbja : First version ...
*/
VGMSTREAM * init_vgmstream_psx_gms(const char * const filename) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
int loop_flag=0;
int channel_count;
off_t start_offset;
int i;
/* check extension, case insensitive */
if (strcasecmp("gms",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check loop */
loop_flag = (read_32bitLE(0x20,infile)==0);
/* Always stereo files */
channel_count=read_32bitLE(0x00,infile);
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitLE(0x04,infile);
vgmstream->coding_type = coding_PSX;
vgmstream->num_samples = read_32bitLE(0x1C,infile);
/* Get loop point values */
if(vgmstream->loop_flag) {
vgmstream->loop_start_sample = read_32bitLE(0x14,infile);
vgmstream->loop_end_sample = read_32bitLE(0x1C,infile);
}
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = 0x800;
vgmstream->meta_type = meta_PSX_GMS;
start_offset = 0x800;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,vgmstream->interleave_block_size);
if (!vgmstream->ch[i].streamfile) goto fail;
vgmstream->ch[i].channel_start_offset=
vgmstream->ch[i].offset=
(off_t)(start_offset+vgmstream->interleave_block_size*i);
}
}
return vgmstream;
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}
*/
VGMSTREAM * init_vgmstream_psx_gms(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
char filename[260];
int loop_flag=0;
int channel_count;
off_t start_offset;
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("gms",filename_extension(filename))) goto fail;
/* check loop */
loop_flag = (read_32bitLE(0x20,streamFile)==0);
/* Always stereo files */
channel_count=read_32bitLE(0x00,streamFile);
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->channels = channel_count;
vgmstream->sample_rate = read_32bitLE(0x04,streamFile);
vgmstream->coding_type = coding_PSX;
vgmstream->num_samples = read_32bitLE(0x1C,streamFile);
/* Get loop point values */
if(vgmstream->loop_flag) {
vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile);
vgmstream->loop_end_sample = read_32bitLE(0x1C,streamFile);
}
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = 0x800;
vgmstream->meta_type = meta_PSX_GMS;
start_offset = 0x800;
/* 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=
(off_t)(start_offset+vgmstream->interleave_block_size*i);
}
}
return vgmstream;
/* clean up anything we may have opened */
fail:
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -9,18 +9,15 @@
2008-05-17 - Fastelbja : First version ...
*/
VGMSTREAM * init_vgmstream_raw(const char * const filename) {
VGMSTREAM * init_vgmstream_raw(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("raw",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* No check to do as they are raw pcm */
/* build the VGMSTREAM */
@ -31,17 +28,15 @@ VGMSTREAM * init_vgmstream_raw(const char * const filename) {
vgmstream->channels = 2;
vgmstream->sample_rate = 44100;
vgmstream->coding_type = coding_PCM16LE;
vgmstream->num_samples = (int32_t)(get_streamfile_size(infile)/4);
vgmstream->num_samples = (int32_t)(get_streamfile_size(streamFile)/4);
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = 2;
vgmstream->meta_type = meta_RAW;
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
for (i=0;i<2;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,0x1000);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x1000);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -54,7 +49,6 @@ VGMSTREAM * init_vgmstream_raw(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -4,9 +4,9 @@
/* .dsp w/ RS03 header - from Metroid Prime 2 */
VGMSTREAM * init_vgmstream_rs03(const char * const filename) {
VGMSTREAM * init_vgmstream_rs03(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
int channel_count;
int loop_flag;
@ -14,34 +14,31 @@ VGMSTREAM * init_vgmstream_rs03(const char * const filename) {
int i;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("dsp",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check header */
if ((uint32_t)read_32bitBE(0,infile)!=0x52530003) /* "RS03" */
if ((uint32_t)read_32bitBE(0,streamFile)!=0x52530003) /* "RS03" */
goto fail;
channel_count = read_32bitBE(4,infile);
channel_count = read_32bitBE(4,streamFile);
if (channel_count != 1 && channel_count != 2) goto fail;
/* build the VGMSTREAM */
loop_flag = read_16bitBE(0x14,infile);
loop_flag = read_16bitBE(0x14,streamFile);
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->num_samples = read_32bitBE(8,infile);
vgmstream->sample_rate = read_32bitBE(0xc,infile);
vgmstream->num_samples = read_32bitBE(8,streamFile);
vgmstream->sample_rate = read_32bitBE(0xc,streamFile);
vgmstream->loop_start_sample = dsp_nibbles_to_samples(
read_32bitBE(0x18,infile));
read_32bitBE(0x18,streamFile));
vgmstream->loop_end_sample = + dsp_nibbles_to_samples(
read_32bitBE(0x1c,infile)*2+16);
read_32bitBE(0x1c,streamFile)*2+16);
start_offset = 0x60;
@ -49,25 +46,23 @@ VGMSTREAM * init_vgmstream_rs03(const char * const filename) {
if (channel_count == 2) {
vgmstream->layout_type = layout_interleave_shortblock;
vgmstream->interleave_block_size = 0x8f00;
vgmstream->interleave_smallblock_size = (((get_streamfile_size(infile)-start_offset)%(0x8f00*2))/2+7)/8*8;
vgmstream->interleave_smallblock_size = (((get_streamfile_size(streamFile)-start_offset)%(0x8f00*2))/2+7)/8*8;
} else
vgmstream->layout_type = layout_none;
vgmstream->meta_type = meta_DSP_RS03;
for (i=0;i<16;i++)
vgmstream->ch[0].adpcm_coef[i]=read_16bitBE(0x20+i*2,infile);
vgmstream->ch[0].adpcm_coef[i]=read_16bitBE(0x20+i*2,streamFile);
if (channel_count==2) {
for (i=0;i<16;i++)
vgmstream->ch[1].adpcm_coef[i]=read_16bitBE(0x40+i*2,infile);
vgmstream->ch[1].adpcm_coef[i]=read_16bitBE(0x40+i*2,streamFile);
}
close_streamfile(infile); infile=NULL;
/* open the file for reading by each channel */
{
int i;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,0x8f00);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,0x8f00);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -81,7 +76,6 @@ VGMSTREAM * init_vgmstream_rs03(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -4,21 +4,18 @@
/* .rsf - from Metroid Prime */
VGMSTREAM * init_vgmstream_rsf(const char * const filename) {
VGMSTREAM * init_vgmstream_rsf(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
size_t file_size;
/* check extension, case insensitive */
/* this is all we have to go on, rsf is completely headerless */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("rsf",filename_extension(filename))) goto fail;
/* try to open the file so we can count the filesize */
infile = open_streamfile(filename);
if (!infile) goto fail;
file_size = get_streamfile_size(infile);
file_size = get_streamfile_size(streamFile);
{
/* extra check: G.721 has no zero nibbles, so we look at
@ -27,19 +24,16 @@ VGMSTREAM * init_vgmstream_rsf(const char * const filename) {
off_t i;
/* 0x20 is arbitrary, all files are much larger */
for (i=0;i<0x20;i++) {
test_byte = read_8bit(i,infile);
test_byte = read_8bit(i,streamFile);
if (!(test_byte&0xf) || !(test_byte&0xf0)) goto fail;
}
/* and also check start of second channel */
for (i=(file_size+1)/2;i<(file_size+1)/2+0x20;i++) {
test_byte = read_8bit(i,infile);
test_byte = read_8bit(i,streamFile);
if (!(test_byte&0xf) || !(test_byte&0xf0)) goto fail;
}
}
close_streamfile(infile);
infile = NULL;
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(2,0);
@ -57,7 +51,7 @@ VGMSTREAM * init_vgmstream_rsf(const char * const filename) {
{
int i;
for (i=0;i<2;i++) {
vgmstream->ch[i].streamfile = open_streamfile(filename);
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -74,7 +68,6 @@ VGMSTREAM * init_vgmstream_rsf(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -5,9 +5,9 @@
/* RWSD is quite similar to BRSTM, but can contain several streams.
* Still, some games use it for single streams. We only support the
* single stream form here */
VGMSTREAM * init_vgmstream_rwsd(const char * const filename) {
VGMSTREAM * init_vgmstream_rwsd(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
STREAMFILE * infile = NULL;
char filename[260];
coding_t coding_type;
@ -21,36 +21,33 @@ VGMSTREAM * init_vgmstream_rwsd(const char * const filename) {
size_t stream_size;
/* check extension, case insensitive */
streamFile->get_name(streamFile,filename,sizeof(filename));
if (strcasecmp("rwsd",filename_extension(filename))) goto fail;
/* try to open the file for header reading */
infile = open_streamfile(filename);
if (!infile) goto fail;
/* check header */
if ((uint32_t)read_32bitBE(0,infile)!=0x52575344 || /* "RWSD" */
(uint32_t)read_32bitBE(4,infile)!=0xFEFF0102)
if ((uint32_t)read_32bitBE(0,streamFile)!=0x52575344 || /* "RWSD" */
(uint32_t)read_32bitBE(4,streamFile)!=0xFEFF0102)
goto fail;
/* ideally we would look through the chunk list for a WAVE chunk,
* but it's always in the same order */
/* get WAVE offset, check */
wave_offset = read_32bitBE(0x18,infile);
if ((uint32_t)read_32bitBE(wave_offset,infile)!=0x57415645) /* "WAVE" */
wave_offset = read_32bitBE(0x18,streamFile);
if ((uint32_t)read_32bitBE(wave_offset,streamFile)!=0x57415645) /* "WAVE" */
goto fail;
/* get WAVE size, check */
wave_length = read_32bitBE(0x1c,infile);
if (read_32bitBE(wave_offset+4,infile)!=wave_length)
wave_length = read_32bitBE(0x1c,streamFile);
if (read_32bitBE(wave_offset+4,streamFile)!=wave_length)
goto fail;
/* check wave count */
if (read_32bitBE(wave_offset+8,infile) != 1)
if (read_32bitBE(wave_offset+8,streamFile) != 1)
goto fail; /* only support 1 */
/* get type details */
codec_number = read_8bit(wave_offset+0x10,infile);
loop_flag = read_8bit(wave_offset+0x11,infile);
channel_count = read_8bit(wave_offset+0x12,infile);
codec_number = read_8bit(wave_offset+0x10,streamFile);
loop_flag = read_8bit(wave_offset+0x11,streamFile);
channel_count = read_8bit(wave_offset+0x12,streamFile);
switch (codec_number) {
case 0:
@ -74,10 +71,10 @@ VGMSTREAM * init_vgmstream_rwsd(const char * const filename) {
if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->num_samples = dsp_nibbles_to_samples(read_32bitBE(wave_offset+0x1c,infile));
vgmstream->sample_rate = (uint16_t)read_16bitBE(wave_offset+0x14,infile);
vgmstream->num_samples = dsp_nibbles_to_samples(read_32bitBE(wave_offset+0x1c,streamFile));
vgmstream->sample_rate = (uint16_t)read_16bitBE(wave_offset+0x14,streamFile);
/* channels and loop flag are set by allocate_vgmstream */
vgmstream->loop_start_sample = dsp_nibbles_to_samples(read_32bitBE(wave_offset+0x18,infile));
vgmstream->loop_start_sample = dsp_nibbles_to_samples(read_32bitBE(wave_offset+0x18,streamFile));
vgmstream->loop_end_sample = vgmstream->num_samples;
vgmstream->coding_type = coding_type;
@ -93,21 +90,19 @@ VGMSTREAM * init_vgmstream_rwsd(const char * const filename) {
for (j=0;j<vgmstream->channels;j++) {
for (i=0;i<16;i++) {
vgmstream->ch[j].adpcm_coef[i]=read_16bitBE(wave_offset+coef_offset+j*0x30+i*2,infile);
vgmstream->ch[j].adpcm_coef[i]=read_16bitBE(wave_offset+coef_offset+j*0x30+i*2,streamFile);
}
}
}
start_offset = read_32bitBE(8,infile);
stream_size = read_32bitBE(wave_offset+0x50,infile);
close_streamfile(infile); infile=NULL;
start_offset = read_32bitBE(8,streamFile);
stream_size = read_32bitBE(wave_offset+0x50,streamFile);
/* open the file for reading by each channel */
{
int i;
for (i=0;i<channel_count;i++) {
vgmstream->ch[i].streamfile = open_streamfile_buffer(filename,
vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,
0x1000);
if (!vgmstream->ch[i].streamfile) goto fail;
@ -122,7 +117,6 @@ VGMSTREAM * init_vgmstream_rwsd(const char * const filename) {
/* clean up anything we may have opened */
fail:
if (infile) close_streamfile(infile);
if (vgmstream) close_vgmstream(vgmstream);
return NULL;
}

View File

@ -1,45 +1,19 @@
#include "streamfile.h"
#include "util.h"
STREAMFILE * open_streamfile(const char * const filename) {
return open_streamfile_buffer(filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
}
STREAMFILE * open_streamfile_buffer(const char * const filename, size_t buffersize) {
typedef struct {
STREAMFILE sf;
FILE * infile;
off_t offset;
size_t validsize;
uint8_t * buffer;
STREAMFILE * streamfile;
infile = fopen(filename,"rb");
if (!infile) return NULL;
size_t buffersize;
char name[260];
} STDIOSTREAMFILE;
buffer = calloc(buffersize,1);
if (!buffer) {
fclose(infile);
return NULL;
}
static STREAMFILE * open_stdio_streamfile_buffer_by_FILE(FILE *infile,const char * const filename, size_t buffersize);
streamfile = calloc(1,sizeof(STREAMFILE));
if (!streamfile) {
fclose(infile);
free(buffer);
return NULL;
}
streamfile->infile = infile;
streamfile->buffersize = buffersize;
streamfile->buffer = buffer;
return streamfile;
}
void close_streamfile(STREAMFILE * streamfile) {
fclose(streamfile->infile);
free(streamfile->buffer);
free(streamfile);
}
size_t read_the_rest(uint8_t * dest, off_t offset, size_t length, STREAMFILE * streamfile) {
static size_t read_the_rest(uint8_t * dest, off_t offset, size_t length, STDIOSTREAMFILE * streamfile) {
size_t length_read_total=0;
/* is the beginning at least there? */
@ -96,7 +70,105 @@ size_t read_the_rest(uint8_t * dest, off_t offset, size_t length, STREAMFILE * s
return length_read_total;
}
size_t get_streamfile_size(STREAMFILE * streamfile) {
static size_t read_stdio(STDIOSTREAMFILE *streamfile,uint8_t * dest, off_t offset, size_t length)
{
// read
if (!streamfile || !dest || length<=0) return 0;
/* if entire request is within the buffer */
if (offset >= streamfile->offset && offset+length <= streamfile->offset+streamfile->validsize) {
memcpy(dest,streamfile->buffer+(offset-streamfile->offset),length);
return length;
}
return read_the_rest(dest,offset,length,streamfile);
}
static void close_stdio(STDIOSTREAMFILE * streamfile) {
fclose(streamfile->infile);
free(streamfile->buffer);
free(streamfile);
}
static size_t get_size_stdio(STDIOSTREAMFILE * streamfile) {
fseeko(streamfile->infile,0,SEEK_END);
return ftello(streamfile->infile);
}
static off_t get_offset_stdio(STDIOSTREAMFILE *streamFile) {
return streamFile->offset;
}
static void get_name_stdio(STDIOSTREAMFILE *streamfile,char *buffer,size_t length) {
strcpy(buffer,streamfile->name);
}
static STREAMFILE *open_stdio(STDIOSTREAMFILE *streamFile,const char * const filename,size_t buffersize) {
int newfd;
FILE *newfile;
STREAMFILE *newstreamFile;
if (!filename)
return NULL;
// if same name, duplicate the file pointer we already have open
if (!strcmp(streamFile->name,filename)) {
if (((newfd = dup(fileno(streamFile->infile))) >= 0) &&
(newfile = fdopen( newfd, "rb" )))
{
newstreamFile = open_stdio_streamfile_buffer_by_FILE(newfile,filename,buffersize);
if (newstreamFile) {
return newstreamFile;
}
// failure, close it and try the default path (which will probably fail a second time)
fclose(newfile);
}
}
// a normal open, open a new file
return open_stdio_streamfile_buffer(filename,buffersize);
}
static STREAMFILE * open_stdio_streamfile_buffer_by_FILE(FILE *infile,const char * const filename, size_t buffersize) {
uint8_t * buffer;
STDIOSTREAMFILE * streamfile;
buffer = calloc(buffersize,1);
if (!buffer) {
return NULL;
}
streamfile = calloc(1,sizeof(STDIOSTREAMFILE));
if (!streamfile) {
free(buffer);
return NULL;
}
streamfile->sf.read = (void*)read_stdio;
streamfile->sf.get_size = (void*)get_size_stdio;
streamfile->sf.get_offset = (void*)get_offset_stdio;
streamfile->sf.get_name = (void*)get_name_stdio;
streamfile->sf.open = (void*)open_stdio;
streamfile->sf.close = (void*)close_stdio;
streamfile->infile = infile;
streamfile->buffersize = buffersize;
streamfile->buffer = buffer;
strcpy(streamfile->name,filename);
return &streamfile->sf;
}
STREAMFILE * open_stdio_streamfile_buffer(const char * const filename, size_t buffersize) {
FILE * infile;
STREAMFILE *streamFile;
infile = fopen(filename,"rb");
if (!infile) return NULL;
streamFile = open_stdio_streamfile_buffer_by_FILE(infile,filename,buffersize);
if (!streamFile) {
fclose(infile);
}
return streamFile;
}

View File

@ -1,6 +1,6 @@
/*
* streamfile.h - definitions for buffered file reading with STREAMFILE
*/
* streamfile.h - definitions for buffered file reading with STREAMFILE
*/
#ifndef _STREAMFILE_H
#define _STREAMFILE_H
@ -17,89 +17,92 @@
#include "util.h"
#if defined(__MSVCRT__) || defined(_MSC_VER)
#include <io.h>
#define fseeko fseek
#define ftello ftell
#define dup _dup
#define fileno _fileno
#define fdopen _fdopen
#endif
#define STREAMFILE_DEFAULT_BUFFER_SIZE 0x400
typedef struct {
FILE * infile;
off_t offset;
size_t validsize;
uint8_t * buffer;
size_t buffersize;
typedef struct _STREAMFILE {
size_t (*read)(struct _STREAMFILE *,uint8_t * dest, off_t offset, size_t length);
size_t (*get_size)(struct _STREAMFILE *);
off_t (*get_offset)(struct _STREAMFILE *);
// for dual-file support
void (*get_name)(struct _STREAMFILE *,char *name,size_t length);
struct _STREAMFILE * (*open)(struct _STREAMFILE *,const char * const filename,size_t buffersize);
void (*close)(struct _STREAMFILE *);
} STREAMFILE;
/* open file with a default buffer size, create a STREAMFILE object
*
* Returns pointer to new STREAMFILE or NULL if open failed
*/
STREAMFILE * open_streamfile(const char * const filename);
/* open file with a set buffer size, create a STREAMFILE object
*
* Returns pointer to new STREAMFILE or NULL if open failed
*/
STREAMFILE * open_streamfile_buffer(const char * const filename, size_t buffersize);
/* close a file, destroy the STREAMFILE object */
void close_streamfile(STREAMFILE * streamfile);
/* */
size_t read_the_rest(uint8_t * dest, off_t offset, size_t length, STREAMFILE * streamfile);
static inline void close_streamfile(STREAMFILE * streamfile) {
streamfile->close(streamfile);
}
/* read from a file
*
* returns number of bytes read
*/
*
* returns number of bytes read
*/
static inline size_t read_streamfile(uint8_t * dest, off_t offset, size_t length, STREAMFILE * streamfile) {
if (!streamfile || !dest || length<=0) return 0;
/* if entire request is within the buffer */
if (offset >= streamfile->offset && offset+length <= streamfile->offset+streamfile->validsize) {
memcpy(dest,streamfile->buffer+(offset-streamfile->offset),length);
return length;
}
return read_the_rest(dest,offset,length,streamfile);
return streamfile->read(streamfile,dest,offset,length);
}
/* return file size */
size_t get_streamfile_size(STREAMFILE * streamfile);
static inline size_t get_streamfile_size(STREAMFILE * streamfile) {
return streamfile->get_size(streamfile);
}
/* Sometimes you just need an int, and we're doing the buffering.
* Note, however, that if these fail to read they'll return -1,
* so that should not be a valid value or there should be some backup. */
* Note, however, that if these fail to read they'll return -1,
* so that should not be a valid value or there should be some backup. */
static inline int16_t read_16bitLE(off_t offset, STREAMFILE * streamfile) {
uint8_t buf[2];
uint8_t buf[2];
if (read_streamfile(buf,offset,2,streamfile)!=2) return -1;
return get_16bitLE(buf);
if (read_streamfile(buf,offset,2,streamfile)!=2) return -1;
return get_16bitLE(buf);
}
static inline int16_t read_16bitBE(off_t offset, STREAMFILE * streamfile) {
uint8_t buf[2];
uint8_t buf[2];
if (read_streamfile(buf,offset,2,streamfile)!=2) return -1;
return get_16bitBE(buf);
if (read_streamfile(buf,offset,2,streamfile)!=2) return -1;
return get_16bitBE(buf);
}
static inline int32_t read_32bitLE(off_t offset, STREAMFILE * streamfile) {
uint8_t buf[4];
uint8_t buf[4];
if (read_streamfile(buf,offset,4,streamfile)!=4) return -1;
return get_32bitLE(buf);
if (read_streamfile(buf,offset,4,streamfile)!=4) return -1;
return get_32bitLE(buf);
}
static inline int32_t read_32bitBE(off_t offset, STREAMFILE * streamfile) {
uint8_t buf[4];
uint8_t buf[4];
if (read_streamfile(buf,offset,4,streamfile)!=4) return -1;
return get_32bitBE(buf);
if (read_streamfile(buf,offset,4,streamfile)!=4) return -1;
return get_32bitBE(buf);
}
static inline int8_t read_8bit(off_t offset, STREAMFILE * streamfile) {
uint8_t buf[1];
uint8_t buf[1];
if (read_streamfile(buf,offset,1,streamfile)!=1) return -1;
return buf[0];
if (read_streamfile(buf,offset,1,streamfile)!=1) return -1;
return buf[0];
}
/* open file with a set buffer size, create a STREAMFILE object
*
* Returns pointer to new STREAMFILE or NULL if open failed
*/
STREAMFILE * open_stdio_streamfile_buffer(const char * const filename, size_t buffersize);
/* open file with a default buffer size, create a STREAMFILE object
*
* Returns pointer to new STREAMFILE or NULL if open failed
*/
static inline STREAMFILE * open_stdio_streamfile(const char * const filename) {
return open_stdio_streamfile_buffer(filename,STREAMFILE_DEFAULT_BUFFER_SIZE);
}
#endif

View File

@ -58,15 +58,15 @@ void interleave_stereo(sample * buffer, int32_t sample_count) {
*/
void put_16bitLE(uint8_t * buf, int16_t i) {
buf[0] = i;
buf[0] = (i & 0xFF);
buf[1] = i >> 8;
}
void put_32bitLE(uint8_t * buf, int32_t i) {
buf[0] = i;
buf[1] = i >> 8;
buf[2] = i >> 16;
buf[3] = i >> 24;
buf[0] = (uint8_t)(i & 0xFF);
buf[1] = (uint8_t)((i >> 8) & 0xFF);
buf[2] = (uint8_t)((i >> 16) & 0xFF);
buf[3] = (uint8_t)((i >> 24) & 0xFF);
}
/* make a header for PCM .wav */
@ -79,7 +79,7 @@ void make_wav_header(uint8_t * buf, int32_t sample_count, int32_t sample_rate, i
/* RIFF header */
memcpy(buf+0, "RIFF", 4);
/* size of RIFF */
put_32bitLE(buf+4, bytecount+0x2c-8);
put_32bitLE(buf+4, (int32_t)(bytecount+0x2c-8));
/* WAVE header */
memcpy(buf+8, "WAVE", 4);
@ -102,7 +102,7 @@ void make_wav_header(uint8_t * buf, int32_t sample_count, int32_t sample_rate, i
put_32bitLE(buf+0x1c, sample_rate*channels*sizeof(sample));
/* block align */
put_16bitLE(buf+0x20, channels*sizeof(sample));
put_16bitLE(buf+0x20, (int16_t)(channels*sizeof(sample)));
/* significant bits per sample */
put_16bitLE(buf+0x22, sizeof(sample)*8);
@ -112,7 +112,7 @@ void make_wav_header(uint8_t * buf, int32_t sample_count, int32_t sample_rate, i
/* WAVE data chunk */
memcpy(buf+0x24, "data", 4);
/* size of WAVE data chunk */
put_32bitLE(buf+0x28, bytecount);
put_32bitLE(buf+0x28, (int32_t)bytecount);
}
/* length is maximum length of dst. dst will always be null-terminated if

View File

@ -16,7 +16,7 @@
* directly to the metadata types
*/
#define INIT_VGMSTREAM_FCNS 29
VGMSTREAM * (*init_vgmstream_fcns[INIT_VGMSTREAM_FCNS])(const char * const) = {
VGMSTREAM * (*init_vgmstream_fcns[INIT_VGMSTREAM_FCNS])(STREAMFILE *streamFile) = {
init_vgmstream_adx, /* 0 */
init_vgmstream_brstm, /* 1 */
init_vgmstream_nds_strm, /* 2 */
@ -48,21 +48,16 @@ VGMSTREAM * (*init_vgmstream_fcns[INIT_VGMSTREAM_FCNS])(const char * const) = {
init_vgmstream_psx_gms /* 28 */
};
/* format detection and VGMSTREAM setup, uses default parameters */
VGMSTREAM * init_vgmstream(const char * const filename) {
return init_vgmstream_internal(filename,
1 /* do dual file detection */
);
}
/* internal version with all parameters */
VGMSTREAM * init_vgmstream_internal(const char * const filename, int do_dfs) {
VGMSTREAM * init_vgmstream_internal(STREAMFILE *streamFile, int do_dfs) {
int i;
if (!streamFile)
return NULL;
/* try a series of formats, see which works */
for (i=0;i<INIT_VGMSTREAM_FCNS;i++) {
VGMSTREAM * vgmstream = (init_vgmstream_fcns[i])(filename);
VGMSTREAM * vgmstream = (init_vgmstream_fcns[i])(streamFile);
if (vgmstream) {
/* these are little hacky checks */
@ -75,7 +70,7 @@ VGMSTREAM * init_vgmstream_internal(const char * const filename, int do_dfs) {
/* dual file stereo */
if (do_dfs && ((vgmstream->meta_type == meta_DSP_STD) || (vgmstream->meta_type == meta_PS2_VAGp)) && vgmstream->channels == 1) {
try_dual_file_stereo(vgmstream, filename);
try_dual_file_stereo(vgmstream, streamFile);
}
/* save start things so we can restart for seeking */
@ -91,6 +86,21 @@ VGMSTREAM * init_vgmstream_internal(const char * const filename, int do_dfs) {
return NULL;
}
/* format detection and VGMSTREAM setup, uses default parameters */
VGMSTREAM * init_vgmstream(const char * const filename) {
VGMSTREAM *vgmstream = NULL;
STREAMFILE *streamFile = open_stdio_streamfile(filename);
if (streamFile) {
vgmstream = init_vgmstream_from_STREAMFILE(streamFile);
close_streamfile(streamFile);
}
return vgmstream;
}
VGMSTREAM * init_vgmstream_from_STREAMFILE(STREAMFILE *streamFile) {
return init_vgmstream_internal(streamFile,1);
}
/* Reset a VGMSTREAM to its state at the start of playback.
* Note that this does not reset the constituent STREAMFILES. */
void reset_vgmstream(VGMSTREAM * vgmstream) {
@ -698,15 +708,19 @@ const char * const dfs_pairs[DFS_PAIR_COUNT][2] = {
{"left","right"},
};
void try_dual_file_stereo(VGMSTREAM * opened_stream, const char * const filename) {
char * filename2;
void try_dual_file_stereo(VGMSTREAM * opened_stream, STREAMFILE *streamFile) {
char filename[260];
char filename2[260];
char * ext;
int dfs_name= -1; /*-1=no stereo, 0=opened_stream is left, 1=opened_stream is right */
VGMSTREAM * new_stream = NULL;
STREAMFILE *dual_stream = NULL;
int i,j;
if (opened_stream->channels != 1) return;
streamFile->get_name(streamFile,filename,sizeof(filename));
/* vgmstream's layout stuff currently assumes a single file */
// fastelbja : no need ... this one works ok with dual file
//if (opened_stream->layout != layout_none) return;
@ -714,11 +728,6 @@ void try_dual_file_stereo(VGMSTREAM * opened_stream, const char * const filename
/* we need at least a base and a name ending to replace */
if (strlen(filename)<2) return;
/* one extra for terminator, one for possible extra character (left>=right) */
filename2 = malloc(strlen(filename)+2);
if (!filename2) return;
strcpy(filename2,filename);
/* look relative to the extension; */
@ -757,9 +766,12 @@ void try_dual_file_stereo(VGMSTREAM * opened_stream, const char * const filename
filename,filename2);
#endif
new_stream = init_vgmstream_internal(filename2,
dual_stream = streamFile->open(streamFile,filename2,STREAMFILE_DEFAULT_BUFFER_SIZE);
// no need to check NULL here since init_vgmstream_internal does it at its beginning
new_stream = init_vgmstream_internal(dual_stream,
0 /* don't do dual file on this, to prevent recursion */
);
close_streamfile(dual_stream);
/* see if we were able to open the file, and if everything matched nicely */
if (new_stream &&
@ -835,10 +847,6 @@ void try_dual_file_stereo(VGMSTREAM * opened_stream, const char * const filename
/* discard the second VGMSTREAM */
free(new_stream);
}
if (filename2) free(filename2);
return;
fail:
if (filename2) free(filename2);
return;
}

View File

@ -182,9 +182,7 @@ typedef struct {
/* do format detection, return pointer to a usable VGMSTREAM, or NULL on failure */
VGMSTREAM * init_vgmstream(const char * const filename);
/* internal vgmstream that takes parameters the library user shouldn't have to know
* about */
VGMSTREAM * init_vgmstream_internal(const char * const filename, int do_dfs);
VGMSTREAM * init_vgmstream_from_STREAMFILE(STREAMFILE *streamFile);
/* reset a VGMSTREAM to start of stream */
void reset_vgmstream(VGMSTREAM * vgmstream);
@ -229,6 +227,6 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length);
* already opened mono opened_stream which was opened from filename.
* If a suitable file is found, open it and change opened_stream to a
* stereo stream. */
void try_dual_file_stereo(VGMSTREAM * opened_stream, const char * const filename);
void try_dual_file_stereo(VGMSTREAM * opened_stream, STREAMFILE *streamFile);
#endif

View File

@ -73,8 +73,7 @@ int fade_samples = 0;
#define EXTENSION_LIST_SIZE 1024
char working_extension_list[EXTENSION_LIST_SIZE] = {0};
#define EXTENSION_COUNT 29
char * extension_list[EXTENSION_COUNT] = {
char * extension_list[] = {
"adx\0ADX Audio File (*.ADX)\0",
"afc\0AFC Audio File (*.AFC)\0",
"agsc\0AGSC Audio File (*.AGSC)\0",
@ -120,7 +119,7 @@ void build_extension_list() {
working_extension_list[0]='\0';
working_extension_list[1]='\0';
for (i=0;i<EXTENSION_COUNT;i++) {
for (i=0;i<sizeof(extension_list)/sizeof(extension_list[0]);i++) {
concatn_doublenull(EXTENSION_LIST_SIZE,working_extension_list,
extension_list[i]);
}
@ -137,13 +136,15 @@ void GetINIFileName(char * iniFile) {
strncat(iniFile, "\\Plugins\\", MAX_PATH);
/* can't be certain that \Plugins already exists in the user dir */
mkdir(iniFile);
CreateDirectory(iniFile,NULL);
strncat(iniFile, INI_NAME, MAX_PATH);
}
else {
char * lastSlash;
GetModuleFileName(NULL, iniFile, MAX_PATH);
char * lastSlash = strrchr(iniFile, '\\');
lastSlash = strrchr(iniFile, '\\');
*(lastSlash + 1) = 0;
strncat(iniFile, "Plugins\\" INI_NAME,MAX_PATH);