diff --git a/src/header.c b/src/header.c index b479a8a1..78e05a77 100644 --- a/src/header.c +++ b/src/header.c @@ -5,106 +5,3 @@ #include "streamtypes.h" #include "util.h" -/** - * checks if the stream filename is one of the extensions (comma-separated, ex. "adx" or "adx,aix") - * - * returns 0 on failure - */ -int header_check_extensions(STREAMFILE *streamFile, const char * cmpexts) { - char filename[PATH_LIMIT]; - const char * ext = NULL; - const char * cmpext = NULL; - size_t ext_len; - - streamFile->get_name(streamFile,filename,sizeof(filename)); - ext = filename_extension(filename); - ext_len = strlen(ext); - - cmpext = cmpexts; - do { - if (strncasecmp(ext,cmpext, ext_len)==0 ) - return 1; - cmpext = strstr(cmpext, ","); - if (cmpext != NULL) - cmpext = cmpext + 1; /* skip comma */ - } while (cmpext != NULL); - - return 0; -} - - -/** - * opens a stream at offset - * - * returns 0 on failure - */ -int header_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t start_offset) { - STREAMFILE * file; - char filename[PATH_LIMIT]; - int ch; - int buffer_size = STREAMFILE_DEFAULT_BUFFER_SIZE; - -#ifdef VGM_USE_FFMPEG - if (vgmstream->coding_type == coding_FFmpeg) /* not needed */ - return 1; -#endif - - /* minor optimizations */ - if (vgmstream->layout_type == layout_interleave - &&vgmstream->interleave_block_size > 0 - && vgmstream->interleave_block_size > buffer_size) { - buffer_size = vgmstream->interleave_block_size; - } - - if (buffer_size > 0x8000) { - buffer_size = 0x8000; - /* todo if interleave is big enough open one streamfile per channel so each uses it's own buffer */ - } - - - streamFile->get_name(streamFile,filename,sizeof(filename)); - /* open the file for reading by each channel */ - { - file = streamFile->open(streamFile,filename,buffer_size); - if (!file) return 0; - - for (ch=0; ch < vgmstream->channels; ch++) { - - vgmstream->ch[ch].streamfile = file; - - if (vgmstream->layout_type == layout_none -#ifdef VGM_USE_MPEG - || vgmstream->layout_type == layout_mpeg //todo simplify using flag "start offset" -#endif - ) { /* no appreciable difference for mpeg */ - /* for some codecs like IMA where channels work with the same bytes */ - vgmstream->ch[ch].channel_start_offset = - vgmstream->ch[ch].offset = start_offset; - } - else { - vgmstream->ch[ch].channel_start_offset = - vgmstream->ch[ch].offset = start_offset - + vgmstream->interleave_block_size*ch; - } - } - } - - - return 1; -} - - -#if 0 -/** - * Converts a data offset (without headers) to sample, so full datasize would be num_samples - * - * return -1 on failure - */ -int data_offset_to_samples(layout_t layout, int channels, size_t interleave, size_t data_offset) { - // todo get samples per block - // VAG: datasize * 28 / 16 / channels; - // IMA: (datasize / 0x24 / channels) * ((0x24-4)*2);//0x24 = interleave? - // DSP: datasize / 8 / channel_count * 14; -} - -#endif diff --git a/src/header.h b/src/header.h index d5cd44ce..9c652972 100644 --- a/src/header.h +++ b/src/header.h @@ -10,8 +10,5 @@ #include "vgmstream.h" -int header_check_extensions(STREAMFILE *streamFile, const char * cmpexts); - -int header_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t start_offset); #endif /* _HEADER_H_ */ diff --git a/src/meta/baf.c b/src/meta/baf.c index 8ef6f822..dff1503f 100644 --- a/src/meta/baf.c +++ b/src/meta/baf.c @@ -1,9 +1,6 @@ #include "meta.h" -#include "../util.h" -#include "../header.h" /* .BAF - Bizarre Creations (Blur, James Bond 007: Blood Stone, etc) */ - VGMSTREAM * init_vgmstream_baf(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; off_t WAVE_size, DATA_size; @@ -17,7 +14,7 @@ VGMSTREAM * init_vgmstream_baf(STREAMFILE *streamFile) { int loop_flag = 0; /* check extensions */ - if ( !header_check_extensions(streamFile, "baf") ) + if ( !check_extensions(streamFile, "baf") ) goto fail; /* check WAVE */ @@ -57,7 +54,7 @@ VGMSTREAM * init_vgmstream_baf(STREAMFILE *streamFile) { vgmstream->meta_type = meta_BAF; /* open the file for reading */ - if ( !header_open_stream(vgmstream, streamFile, start_offset) ) + if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) goto fail; return vgmstream; diff --git a/src/meta/bgw.c b/src/meta/bgw.c index 4656fbe5..12830685 100644 --- a/src/meta/bgw.c +++ b/src/meta/bgw.c @@ -1,12 +1,7 @@ #include "meta.h" -#include "../util.h" -#include "../header.h" -/** - * BGW - Final Fantasy XI (PC) music files. - * - * Some info from POLUtils - */ +/* BGW - from Final Fantasy XI (PC) music files + * Some info from POLUtils */ VGMSTREAM * init_vgmstream_bgw(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; uint32_t codec, filesize, blocksize, sample_rate; @@ -17,7 +12,7 @@ VGMSTREAM * init_vgmstream_bgw(STREAMFILE *streamFile) { int channel_count, loop_flag = 0; /* check extensions */ - if ( !header_check_extensions(streamFile, "bgw") ) + if ( !check_extensions(streamFile, "bgw") ) goto fail; /* check header */ @@ -74,7 +69,7 @@ VGMSTREAM * init_vgmstream_bgw(STREAMFILE *streamFile) { /* open the file for reading */ - if ( !header_open_stream(vgmstream, streamFile, start_offset) ) + if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) goto fail; return vgmstream; @@ -84,9 +79,7 @@ fail: return NULL; } -/** - * SPW (SEWave), PlayOnline viewer for Final Fantasy XI (PC) - */ +/* SPW (SEWave) - from PlayOnline viewer for Final Fantasy XI (PC) */ VGMSTREAM * init_vgmstream_spw(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; uint32_t codec, filesize, blocksize, sample_rate; @@ -97,7 +90,7 @@ VGMSTREAM * init_vgmstream_spw(STREAMFILE *streamFile) { int channel_count, loop_flag = 0; /* check extensions */ - if ( !header_check_extensions(streamFile, "spw") ) + if ( !check_extensions(streamFile, "spw") ) goto fail; /* check header */ @@ -168,7 +161,7 @@ VGMSTREAM * init_vgmstream_spw(STREAMFILE *streamFile) { /* open the file for reading */ - if ( !header_open_stream(vgmstream, streamFile, start_offset) ) + if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) goto fail; return vgmstream; diff --git a/src/meta/fsb.c b/src/meta/fsb.c index f7ddaa74..29e3a89e 100644 --- a/src/meta/fsb.c +++ b/src/meta/fsb.c @@ -1,7 +1,5 @@ #include "meta.h" #include "../coding/coding.h" -#include "../util.h" -#include "../header.h" #define FAKE_RIFF_BUFFER_SIZE 100 @@ -122,7 +120,7 @@ VGMSTREAM * init_vgmstream_fsb_offset(STREAMFILE *streamFile, off_t offset) { FSB_HEADER fsbh; /* check extensions */ - if ( !header_check_extensions(streamFile, "fsb,wii") ) + if ( !check_extensions(streamFile, "fsb,wii") ) goto fail; h_off = offset; @@ -396,7 +394,7 @@ VGMSTREAM * init_vgmstream_fsb_offset(STREAMFILE *streamFile, off_t offset) { /* open the file for reading */ - if ( !header_open_stream(vgmstream, streamFile, start_offset) ) + if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) goto fail; return vgmstream; diff --git a/src/meta/ps2.c b/src/meta/ps2.c index efaa0290..dd29f9c8 100644 --- a/src/meta/ps2.c +++ b/src/meta/ps2.c @@ -1,6 +1,4 @@ #include "meta.h" -#include "../util.h" -#include "../header.h" /* VDS/VDM - from Grafitti Kingdom / Rakugaki Oukoku 2 */ VGMSTREAM * init_vgmstream_ps2_vds_vdm(STREAMFILE *streamFile) { @@ -9,7 +7,7 @@ VGMSTREAM * init_vgmstream_ps2_vds_vdm(STREAMFILE *streamFile) { int loop_flag, channel_count; /* check extension, case insensitive */ - if ( !header_check_extensions(streamFile,"vds,vdm")) + if ( !check_extensions(streamFile,"vds,vdm")) goto fail; if (read_32bitBE(0x00,streamFile) != 0x56445320 && /* "VDS " (music)*/ @@ -40,7 +38,7 @@ VGMSTREAM * init_vgmstream_ps2_vds_vdm(STREAMFILE *streamFile) { /*0x23: 02=VDS 04=VDM? */ /* open the file for reading */ - if ( !header_open_stream(vgmstream, streamFile, start_offset) ) + if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) goto fail; return vgmstream; diff --git a/src/meta/ps2_vag.c b/src/meta/ps2_vag.c index 8703a317..6f7b7eba 100644 --- a/src/meta/ps2_vag.c +++ b/src/meta/ps2_vag.c @@ -1,6 +1,4 @@ #include "meta.h" -#include "../util.h" -#include "../header.h" static int vag_find_loop_offsets(STREAMFILE *streamFile, off_t start_offset, off_t * loop_start, off_t * loop_end); @@ -22,16 +20,16 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) { int is_swag = 0; /* check extension, case insensitive */ - if ( !header_check_extensions(streamFile,"vag,swag") ) + if ( !check_extensions(streamFile,"vag,swag") ) + goto fail; + + /* check VAG Header */ + if (((read_32bitBE(0x00,streamFile) & 0xFFFFFF00) != 0x56414700) && /* "VAG" */ + ((read_32bitLE(0x00,streamFile) & 0xFFFFFF00) != 0x56414700)) goto fail; /* Frantix VAGp .swag: some (not all) fields in LE + 2 VAGp in the same file (full interleave) */ - is_swag = header_check_extensions(streamFile,"swag"); - - /* check VAG Header */ - if (((read_32bitBE(0x00,streamFile) & 0xFFFFFF00) != 0x56414700) && /* "VAG\0" */ - ((read_32bitLE(0x00,streamFile) & 0xFFFFFF00) != 0x56414700)) - goto fail; + is_swag = check_extensions(streamFile,"swag"); filesize = get_streamfile_size(streamFile); @@ -211,7 +209,7 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) { /* open the file for reading */ - if ( !header_open_stream(vgmstream, streamFile, start_offset) ) + if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) goto fail; return vgmstream; diff --git a/src/meta/ps3_vawx.c b/src/meta/ps3_vawx.c index 4acb14f9..28e74922 100644 --- a/src/meta/ps3_vawx.c +++ b/src/meta/ps3_vawx.c @@ -1,6 +1,4 @@ #include "meta.h" -#include "../util.h" -#include "../header.h" #include "../coding/coding.h" #define FAKE_RIFF_BUFFER_SIZE 100 @@ -15,7 +13,7 @@ VGMSTREAM * init_vgmstream_vawx(STREAMFILE *streamFile) { int loop_flag = 0, channel_count, type; /* check extensions */ - if ( !header_check_extensions(streamFile, "vawx,xwv") ) + if ( !check_extensions(streamFile, "vawx,xwv") ) goto fail; /* check header */ @@ -115,7 +113,7 @@ VGMSTREAM * init_vgmstream_vawx(STREAMFILE *streamFile) { /* open the file for reading */ - if ( !header_open_stream(vgmstream, streamFile, start_offset) ) + if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) goto fail; return vgmstream; diff --git a/src/meta/x360.c b/src/meta/x360.c index c75c11d6..311cdbc9 100644 --- a/src/meta/x360.c +++ b/src/meta/x360.c @@ -1,5 +1,4 @@ #include "meta.h" -#include "../header.h" #include "../coding/coding.h" /* CXS - found in Eternal Sonata (Xbox 360) */ @@ -9,7 +8,7 @@ VGMSTREAM * init_vgmstream_x360_cxs(STREAMFILE *streamFile) { int loop_flag, channel_count; /* check extension, case insensitive */ - if ( !header_check_extensions(streamFile,"cxs")) + if ( !check_extensions(streamFile,"cxs")) goto fail; if (read_32bitBE(0x00,streamFile) != 0x43585320) /* "CXS " */ @@ -57,7 +56,7 @@ VGMSTREAM * init_vgmstream_x360_cxs(STREAMFILE *streamFile) { #endif /* open the file for reading */ - if ( !header_open_stream(vgmstream, streamFile, start_offset) ) + if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) ) goto fail; return vgmstream; diff --git a/src/streamfile.c b/src/streamfile.c index 0e5f1e68..354eebc7 100644 --- a/src/streamfile.c +++ b/src/streamfile.c @@ -1,9 +1,9 @@ #ifndef _MSC_VER #include #endif -#include "vgmstream.h" #include "streamfile.h" #include "util.h" +#include "vgmstream.h" typedef struct { STREAMFILE sf; @@ -391,3 +391,31 @@ fail: return 0; } + + +/** + * checks if the stream filename is one of the extensions (comma-separated, ex. "adx" or "adx,aix") + * + * returns 0 on failure + */ +int check_extensions(STREAMFILE *streamFile, const char * cmp_exts) { + char filename[PATH_LIMIT]; + const char * ext = NULL; + const char * cmp_ext = NULL; + size_t ext_len; + + streamFile->get_name(streamFile,filename,sizeof(filename)); + ext = filename_extension(filename); + ext_len = strlen(ext); + + cmp_ext = cmp_exts; + do { + if (strncasecmp(ext,cmp_ext, ext_len)==0 ) + return 1; + cmp_ext = strstr(cmp_ext, ","); + if (cmp_ext != NULL) + cmp_ext = cmp_ext + 1; /* skip comma */ + } while (cmp_ext != NULL); + + return 0; +} diff --git a/src/streamfile.h b/src/streamfile.h index f0347744..1127c995 100644 --- a/src/streamfile.h +++ b/src/streamfile.h @@ -146,11 +146,12 @@ static inline STREAMFILE * open_stdio_streamfile(const char * const filename) { return open_stdio_streamfile_buffer(filename,STREAMFILE_DEFAULT_BUFFER_SIZE); } -size_t get_streamfile_dos_line(int dst_length, char * dst, off_t offset, - STREAMFILE * infile, int *line_done_ptr); +size_t get_streamfile_dos_line(int dst_length, char * dst, off_t offset, STREAMFILE * infile, int *line_done_ptr); int read_key_file(uint8_t * buf, size_t bufsize, STREAMFILE *streamFile); int read_pos_file(uint8_t * buf, size_t bufsize, STREAMFILE *streamFile); +int check_extensions(STREAMFILE *streamFile, const char * cmp_exts); + #endif diff --git a/src/vgmstream.c b/src/vgmstream.c index d7366e8b..9249a5a9 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -2234,3 +2234,59 @@ int get_vgmstream_average_bitrate(VGMSTREAM * vgmstream) return bitrate; } + + +int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t start_offset) { + STREAMFILE * file; + char filename[PATH_LIMIT]; + int ch; + int buffer_size = STREAMFILE_DEFAULT_BUFFER_SIZE; + +#ifdef VGM_USE_FFMPEG + if (vgmstream->coding_type == coding_FFmpeg) /* not needed */ + return 1; +#endif + + /* minor optimizations */ + if (vgmstream->layout_type == layout_interleave + &&vgmstream->interleave_block_size > 0 + && vgmstream->interleave_block_size > buffer_size) { + buffer_size = vgmstream->interleave_block_size; + } + + if (buffer_size > 0x8000) { + buffer_size = 0x8000; + /* todo if interleave is big enough open one streamfile per channel so each uses it's own buffer */ + } + + + streamFile->get_name(streamFile,filename,sizeof(filename)); + /* open the file for reading by each channel */ + { + file = streamFile->open(streamFile,filename,buffer_size); + if (!file) return 0; + + for (ch=0; ch < vgmstream->channels; ch++) { + + vgmstream->ch[ch].streamfile = file; + + if (vgmstream->layout_type == layout_none +#ifdef VGM_USE_MPEG + || vgmstream->layout_type == layout_mpeg //todo simplify using flag "start offset" +#endif + ) { /* no appreciable difference for mpeg */ + /* for some codecs like IMA where channels work with the same bytes */ + vgmstream->ch[ch].channel_start_offset = + vgmstream->ch[ch].offset = start_offset; + } + else { + vgmstream->ch[ch].channel_start_offset = + vgmstream->ch[ch].offset = start_offset + + vgmstream->interleave_block_size*ch; + } + } + } + + + return 1; +} diff --git a/src/vgmstream.h b/src/vgmstream.h index 8725cded..696eb3f6 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -994,4 +994,9 @@ int vgmstream_do_loop(VGMSTREAM * vgmstream); * If a suitable file is found, open it and change opened_stream to a stereo stream. */ void try_dual_file_stereo(VGMSTREAM * opened_stream, STREAMFILE *streamFile); + +/* Open the stream for reading at offset (standarized taking into account layouts, channels and so on). + * returns 0 on failure */ +int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t start_offset); + #endif