diff --git a/BUILD.md b/BUILD.md index fa792abd..7f863543 100644 --- a/BUILD.md +++ b/BUILD.md @@ -129,7 +129,9 @@ git clean -fd ## Development ### Structure -vgmstream uses C89 when possible (so VS2010 can compile it), and C++ for the foobar2000 and Audacious plugins. +vgmstream uses C (C89 when possible), and C++ for the foobar2000 and Audacious plugins. + +C is restricted to features VS2010 can understand. This mainly means means declaring variables at the start of a { .. } block (declare+initialize is fine, as long as it doesn't reference variables declared in that block) and avoiding C99 like variable-length arrays (but others like // comments are fine). ``` ./ docs, scripts @@ -162,11 +164,17 @@ Very simplified it goes like this: ### Adding new formats For new simple formats, assuming existing layout/coding: -- *src/meta/(format-name).c*: create new format parser that reads all needed info from the stream header and inits VGMSTREAM -- *src/meta/meta.h*: register parser's init -- *src/vgmstream.h*: register new meta +- *src/meta/(format-name).c*: create new init_vgmstream_(format-name) parser that reads all needed info from the stream header and inits VGMSTREAM +- *src/meta/meta.h*: define parser's init +- *src/vgmstream.h*: define meta description in the meta_t list - *src/vgmstream.c*: add parser init to the init list - *src/formats.c*: add new extension to the format list, add meta description - *fb2k/foo_filetypes.h*: add new extension to the file register list (optional) - *src/libvgmstream.vcproj/vcxproj/filters*: add to compile new (format-name).c parser in VS - if the format needs an external library don't forget to mark optional parts with: *#ifdef VGM_USE_X ... #endif* + +A STREAMFILE is passed to init_vgmstream_(format-name) function, and I/O must be done using its functions and not STDIO/FILEs, as this lets plugins do their own I/O. This includes reading data from the header or opening other STREAMFILEs (if the header has companion files that need to be parsed). + +When a parser is successful (allocates VGMSTREAM and sets values) it also needs to open and assign to the VGMSTREAM one or several STREAMFILEs (usually reopens the one passed, but could be any other file) to do I/O during decode. The STREAMFILE passed to the meta will be discarded and must not be reused. + +If it supports subsongs it should read and handle the stream index (subsong number) in the passed STREAMFILE, and report the number of subsongs in the VGMSTREAM, to signal the plugins this feature. The index is 1-based (first subsong is 1, not 0). diff --git a/audacious/plugin.cc b/audacious/plugin.cc index db517b41..bb00b8c2 100644 --- a/audacious/plugin.cc +++ b/audacious/plugin.cc @@ -15,7 +15,6 @@ extern "C" { -#include "../src/formats.h" #include "../src/vgmstream.h" } #include "plugin.h" @@ -95,8 +94,8 @@ bool VgmstreamPlugin::is_our_file(const char *filename, VFSFile &file) { else ext = ext+1; /* skip the dot */ - const char ** ext_list = vgmstream_get_formats(); - int ext_list_len = vgmstream_get_formats_length(); + size_t ext_list_len = 0; + const char ** ext_list = vgmstream_get_formats(&ext_list_len); for (int i=0; i < ext_list_len; i++) { if (!strcasecmp(ext, ext_list[i])) diff --git a/fb2k/foo_filetypes.h b/fb2k/foo_filetypes.h index 4cb0f75d..6e15da73 100644 --- a/fb2k/foo_filetypes.h +++ b/fb2k/foo_filetypes.h @@ -161,6 +161,7 @@ VGMSTREAM_DECLARE_FILE_TYPE("KOVS", kovs); VGMSTREAM_DECLARE_FILE_TYPE("KRAW", kraw); VGMSTREAM_DECLARE_FILE_TYPE("LAAC", laac); +VGMSTREAM_DECLARE_FILE_TYPE("LAC3", lac3); VGMSTREAM_DECLARE_FILE_TYPE("LEG", leg); VGMSTREAM_DECLARE_FILE_TYPE("LMP4", lmp4); VGMSTREAM_DECLARE_FILE_TYPE("LOGG", logg); @@ -282,8 +283,6 @@ VGMSTREAM_DECLARE_FILE_TYPE("SPS", sps); VGMSTREAM_DECLARE_FILE_TYPE("SPSD", spsd); VGMSTREAM_DECLARE_FILE_TYPE("SPW", spw); VGMSTREAM_DECLARE_FILE_TYPE("SS2", ss2); -VGMSTREAM_DECLARE_FILE_TYPE("SS3", ss3); -VGMSTREAM_DECLARE_FILE_TYPE("SS7", ss7); VGMSTREAM_DECLARE_FILE_TYPE("SSM", ssm); VGMSTREAM_DECLARE_FILE_TYPE("SSS", sss); VGMSTREAM_DECLARE_FILE_TYPE("STER", ster); diff --git a/fb2k/foo_vgmstream.cpp b/fb2k/foo_vgmstream.cpp index a15d4243..c6ad17d7 100644 --- a/fb2k/foo_vgmstream.cpp +++ b/fb2k/foo_vgmstream.cpp @@ -16,7 +16,6 @@ #include extern "C" { -#include "../src/formats.h" #include "../src/vgmstream.h" } #include "foo_vgmstream.h" @@ -184,19 +183,19 @@ void input_vgmstream::decode_initialize(t_uint32 p_subsong, unsigned p_flags, ab bool input_vgmstream::decode_run(audio_chunk & p_chunk,abort_callback & p_abort) { if (!decoding) return false; + if (!vgmstream) return false; int max_buffer_samples = sizeof(sample_buffer)/sizeof(sample_buffer[0])/vgmstream->channels; - int l = 0, samples_to_do = max_buffer_samples; + int samples_to_do = max_buffer_samples; + t_size bytes; - if(vgmstream) { + { bool loop_okay = loop_forever && vgmstream->loop_flag && !ignore_loop && !force_ignore_loop; if (decode_pos_samples+max_buffer_samples>stream_length_samples && !loop_okay) samples_to_do=stream_length_samples-decode_pos_samples; else samples_to_do=max_buffer_samples; - l = (samples_to_do*vgmstream->channels * sizeof(sample_buffer[0])); - if (samples_to_do /*< DECODE_SIZE*/ == 0) { decoding = false; return false; @@ -222,15 +221,14 @@ bool input_vgmstream::decode_run(audio_chunk & p_chunk,abort_callback & p_abort) } } - p_chunk.set_data_fixedpoint((char*)sample_buffer, l, vgmstream->sample_rate, vgmstream->channels, 16, audio_chunk::g_guess_channel_config(vgmstream->channels)); + bytes = (samples_to_do*vgmstream->channels * sizeof(sample_buffer[0])); + p_chunk.set_data_fixedpoint((char*)sample_buffer, bytes, vgmstream->sample_rate, vgmstream->channels, 16, audio_chunk::g_guess_channel_config(vgmstream->channels)); decode_pos_samples+=samples_to_do; decode_pos_ms=decode_pos_samples*1000LL/vgmstream->sample_rate; return samples_to_do==max_buffer_samples; - } - return false; } void input_vgmstream::decode_seek(double p_seconds,abort_callback & p_abort) { @@ -295,11 +293,10 @@ void input_vgmstream::retag_commit(abort_callback & p_abort) { /*throw exception bool input_vgmstream::g_is_our_content_type(const char * p_content_type) {return false;} bool input_vgmstream::g_is_our_path(const char * p_path,const char * p_extension) { const char ** ext_list; - int ext_list_len; + size_t ext_list_len; int i; - ext_list = vgmstream_get_formats(); - ext_list_len = vgmstream_get_formats_length(); + ext_list = vgmstream_get_formats(&ext_list_len); for (i=0; i < ext_list_len; i++) { if (!stricmp_utf8(p_extension, ext_list[i])) diff --git a/src/formats.c b/src/formats.c index 562b7266..747337ea 100644 --- a/src/formats.c +++ b/src/formats.c @@ -1,4 +1,4 @@ -#include "formats.h" +#include "vgmstream.h" //#define VGM_REGISTER_TYPE(extension) ... //#define VGM_REGISTER_TYPE_COMMON(extension) ... /* for common extensions like aiff */ @@ -154,6 +154,7 @@ static const char* extension_list[] = { "kraw", "laac", //fake extension, for AAC (tri-Ace/FFmpeg) + "lac3", //fake extension, for AC3 "leg", "lmp4", //fake extension, for MP4s "logg", //fake extension, for OGGs @@ -276,8 +277,6 @@ static const char* extension_list[] = { "spsd", "spw", "ss2", - "ss3", - "ss7", "ssm", "sss", "ster", @@ -374,22 +373,11 @@ static const char* extension_list[] = { //, NULL //end mark }; -/** - * List of supported formats. - * - * For plugins that need to know (test.exe doesn't use it) - */ -const char ** vgmstream_get_formats() { +const char ** vgmstream_get_formats(size_t * size) { + *size = sizeof(extension_list) / sizeof(char*); return extension_list; } -/** - * Number of elements in the list. - */ -int vgmstream_get_formats_length() { - return sizeof(extension_list) / sizeof(char*); -} - /* internal description info */ diff --git a/src/formats.h b/src/formats.h deleted file mode 100644 index 2fe6d910..00000000 --- a/src/formats.h +++ /dev/null @@ -1,19 +0,0 @@ -/* - * formats.h - utils to parse supported formats - */ -#ifndef _FORMATS_H_ -#define _FORMATS_H_ - -#include "vgmstream.h" - -/* rough number of chars counting all extensions (actually <1500 and extra space) */ -#define VGM_EXTENSION_LIST_CHAR_SIZE 2000 - -const char ** vgmstream_get_formats(); -int vgmstream_get_formats_length(); - -const char * get_vgmstream_coding_description(coding_t coding_type); -const char * get_vgmstream_layout_description(layout_t layout_type); -const char * get_vgmstream_meta_description(meta_t meta_type); - -#endif /* _FORMATS_H_ */ diff --git a/src/libvgmstream.vcproj b/src/libvgmstream.vcproj index d4208198..e90ca7d1 100644 --- a/src/libvgmstream.vcproj +++ b/src/libvgmstream.vcproj @@ -147,10 +147,6 @@ Filter="h;hpp;hxx;hm;inl;inc;xsd" UniqueIdentifier="{93995380-89BD-4b04-88EB-625FBE52EBFB}" > - - @@ -662,6 +658,10 @@ RelativePath=".\meta\pc_adp.c" > + + @@ -1122,10 +1122,6 @@ RelativePath=".\meta\sqex_scd.c" > - - diff --git a/src/libvgmstream.vcxproj b/src/libvgmstream.vcxproj index 45c51ae3..bcebddb0 100644 --- a/src/libvgmstream.vcxproj +++ b/src/libvgmstream.vcxproj @@ -113,7 +113,6 @@ - @@ -162,6 +161,7 @@ + @@ -388,7 +388,6 @@ - diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index 6abd87a7..fc39f79e 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -47,9 +47,6 @@ - - Header Files - Header Files @@ -685,9 +682,6 @@ meta\Source Files - - meta\Source Files - meta\Source Files @@ -1081,6 +1075,9 @@ meta\Source Files + + meta\Source Files + meta\Source Files diff --git a/src/meta/bcstm.c b/src/meta/bcstm.c index 93bb1d3e..399e1f59 100644 --- a/src/meta/bcstm.c +++ b/src/meta/bcstm.c @@ -3,166 +3,166 @@ /* BCSTM - Nintendo 3DS format */ VGMSTREAM * init_vgmstream_bcstm(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - coding_t coding_type; + VGMSTREAM * vgmstream = NULL; + coding_t coding_type; - off_t info_offset = 0, seek_offset = 0, data_offset = 0; - uint16_t temp_id; - int codec_number; - int channel_count, loop_flag; - int i, ima = 0; - off_t start_offset; - int section_count; + off_t info_offset = 0, seek_offset = 0, data_offset = 0; + uint16_t temp_id; + int codec_number; + int channel_count, loop_flag; + int i, ima = 0; + off_t start_offset; + int section_count; - /* check extension, case insensitive */ + /* check extension, case insensitive */ if ( !check_extensions(streamFile,"bcstm") ) - goto fail; + goto fail; - /* check header */ - if ((uint32_t)read_32bitBE(0, streamFile) != 0x4353544D) /* "CSTM" */ - goto fail; + /* check header */ + if ((uint32_t)read_32bitBE(0, streamFile) != 0x4353544D) /* "CSTM" */ + goto fail; + + if ((uint16_t)read_16bitLE(4, streamFile) != 0xFEFF) + goto fail; + + section_count = read_16bitLE(0x10, streamFile); + for (i = 0; i < section_count; i++) { + temp_id = read_16bitLE(0x14 + i * 0xc, streamFile); + switch(temp_id) { + case 0x4000: + info_offset = read_32bitLE(0x18 + i * 0xc, streamFile); + /* size_t info_size = read_32bitLE(0x1c + i * 0xc, streamFile); */ + break; + case 0x4001: + seek_offset = read_32bitLE(0x18 + i * 0xc, streamFile); + /* size_t seek_size = read_32bitLE(0x1c + i * 0xc, streamFile); */ + break; + case 0x4002: + data_offset = read_32bitLE(0x18 + i * 0xc, streamFile); + /* size_t data_size = read_32bitLE(0x1c + i * 0xc, streamFile); */ + break; + case 0x4003: + /* off_t regn_offset = read_32bitLE(0x18 + i * 0xc, streamFile); */ + /* size_t regn_size = read_32bitLE(0x1c + i * 0xc, streamFile); */ + break; + case 0x4004: + /* off_t pdat_offset = read_32bitLE(0x18 + i * 0xc, streamFile); */ + /* size_t pdat_size = read_32bitLE(0x1c + i * 0xc, streamFile); */ + break; + default: + break; + } + } - if ((uint16_t)read_16bitLE(4, streamFile) != 0xFEFF) - goto fail; - - section_count = read_16bitLE(0x10, streamFile); - for (i = 0; i < section_count; i++) { - temp_id = read_16bitLE(0x14 + i * 0xc, streamFile); - switch(temp_id) { - case 0x4000: - info_offset = read_32bitLE(0x18 + i * 0xc, streamFile); - /* size_t info_size = read_32bitLE(0x1c + i * 0xc, streamFile); */ - break; - case 0x4001: - seek_offset = read_32bitLE(0x18 + i * 0xc, streamFile); - /* size_t seek_size = read_32bitLE(0x1c + i * 0xc, streamFile); */ - break; - case 0x4002: - data_offset = read_32bitLE(0x18 + i * 0xc, streamFile); - /* size_t data_size = read_32bitLE(0x1c + i * 0xc, streamFile); */ - break; - case 0x4003: - /* off_t regn_offset = read_32bitLE(0x18 + i * 0xc, streamFile); */ - /* size_t regn_size = read_32bitLE(0x1c + i * 0xc, streamFile); */ - break; - case 0x4004: - /* off_t pdat_offset = read_32bitLE(0x18 + i * 0xc, streamFile); */ - /* size_t pdat_size = read_32bitLE(0x1c + i * 0xc, streamFile); */ - break; - default: - break; - } - } - if (info_offset == 0) goto fail; if ((uint32_t)read_32bitBE(info_offset, streamFile) != 0x494E464F) /* "INFO" */ goto fail; - - /* check type details */ - codec_number = read_8bit(info_offset + 0x20, streamFile); - loop_flag = read_8bit(info_offset + 0x21, streamFile); - channel_count = read_8bit(info_offset + 0x22, streamFile); - switch (codec_number) { - case 0: - coding_type = coding_PCM8; - break; - case 1: - coding_type = coding_PCM16LE; - break; - case 2: - if (seek_offset == 0) goto fail; - if ((uint32_t)read_32bitBE(seek_offset, streamFile) != 0x5345454B) { /* "SEEK" If this header doesn't exist, assuming that the file is IMA */ - ima = 1; - coding_type = coding_IMA_int; - } - else - coding_type = coding_NGC_DSP; - break; - default: - goto fail; - } + /* check type details */ + codec_number = read_8bit(info_offset + 0x20, streamFile); + loop_flag = read_8bit(info_offset + 0x21, streamFile); + channel_count = read_8bit(info_offset + 0x22, streamFile); - if (channel_count < 1) goto fail; + switch (codec_number) { + case 0: + coding_type = coding_PCM8; + break; + case 1: + coding_type = coding_PCM16LE; + break; + case 2: + if (seek_offset == 0) goto fail; + if ((uint32_t)read_32bitBE(seek_offset, streamFile) != 0x5345454B) { /* "SEEK" If this header doesn't exist, assuming that the file is IMA */ + ima = 1; + coding_type = coding_IMA_int; + } + else + coding_type = coding_NGC_DSP; + break; + default: + goto fail; + } - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count, loop_flag); - if (!vgmstream) goto fail; + if (channel_count < 1) goto fail; - /* fill in the vital statistics */ - vgmstream->num_samples = read_32bitLE(info_offset + 0x2c, streamFile); - vgmstream->sample_rate = read_32bitLE(info_offset + 0x24, streamFile); - /* channels and loop flag are set by allocate_vgmstream */ - if (ima) //Shift the loop points back slightly to avoid stupid pops in some IMA streams due to DC offsetting - { - vgmstream->loop_start_sample = read_32bitLE(info_offset + 0x28, streamFile); - if (vgmstream->loop_start_sample > 10000) - { - vgmstream->loop_start_sample -= 5000; - vgmstream->loop_end_sample = vgmstream->num_samples - 5000; - } - else - vgmstream->loop_end_sample = vgmstream->num_samples; - } - else - { - vgmstream->loop_start_sample = read_32bitLE(info_offset + 0x28, streamFile); - vgmstream->loop_end_sample = vgmstream->num_samples; - } + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count, loop_flag); + if (!vgmstream) goto fail; - vgmstream->coding_type = coding_type; - if (channel_count == 1) - vgmstream->layout_type = layout_none; - else - { - if (ima) - vgmstream->layout_type = layout_interleave; - else - vgmstream->layout_type = layout_interleave_shortblock; - } - vgmstream->meta_type = meta_CSTM; - - if (ima) - vgmstream->interleave_block_size = 0x200; - else { - vgmstream->interleave_block_size = read_32bitLE(info_offset + 0x34, streamFile); - vgmstream->interleave_smallblock_size = read_32bitLE(info_offset + 0x44, streamFile); - } - - if (vgmstream->coding_type == coding_NGC_DSP) { - off_t coef_offset; - off_t tempoffset = info_offset; - int foundcoef = 0; - int i, j; - int coef_spacing = 0x2E; - - while (!(foundcoef)) - { - if ((uint32_t)read_32bitLE(tempoffset, streamFile) == 0x00004102) - { - coef_offset = read_32bitLE(tempoffset + 4, streamFile) + tempoffset + (channel_count * 8) - 4 - info_offset; - foundcoef++; - break; - } - tempoffset++; - } + /* fill in the vital statistics */ + vgmstream->num_samples = read_32bitLE(info_offset + 0x2c, streamFile); + vgmstream->sample_rate = read_32bitLE(info_offset + 0x24, streamFile); + /* channels and loop flag are set by allocate_vgmstream */ + if (ima) //Shift the loop points back slightly to avoid stupid pops in some IMA streams due to DC offsetting + { + vgmstream->loop_start_sample = read_32bitLE(info_offset + 0x28, streamFile); + if (vgmstream->loop_start_sample > 10000) + { + vgmstream->loop_start_sample -= 5000; + vgmstream->loop_end_sample = vgmstream->num_samples - 5000; + } + else + vgmstream->loop_end_sample = vgmstream->num_samples; + } + else + { + vgmstream->loop_start_sample = read_32bitLE(info_offset + 0x28, streamFile); + vgmstream->loop_end_sample = vgmstream->num_samples; + } + + vgmstream->coding_type = coding_type; + if (channel_count == 1) + vgmstream->layout_type = layout_none; + else + { + if (ima) + vgmstream->layout_type = layout_interleave; + else + vgmstream->layout_type = layout_interleave_shortblock; + } + vgmstream->meta_type = meta_CSTM; + + if (ima) + vgmstream->interleave_block_size = 0x200; + else { + vgmstream->interleave_block_size = read_32bitLE(info_offset + 0x34, streamFile); + vgmstream->interleave_smallblock_size = read_32bitLE(info_offset + 0x44, streamFile); + } + + if (vgmstream->coding_type == coding_NGC_DSP) { + off_t coef_offset; + off_t tempoffset = info_offset; + int foundcoef = 0; + int i, j; + int coef_spacing = 0x2E; + + while (!(foundcoef)) + { + if ((uint32_t)read_32bitLE(tempoffset, streamFile) == 0x00004102) + { + coef_offset = read_32bitLE(tempoffset + 4, streamFile) + tempoffset + (channel_count * 8) - 4 - info_offset; + foundcoef++; + break; + } + tempoffset++; + } + + for (j = 0; jchannels; j++) { + for (i = 0; i<16; i++) { + vgmstream->ch[j].adpcm_coef[i] = read_16bitLE(info_offset + coef_offset + j*coef_spacing + i * 2, streamFile); + } + } + } + + if (ima) { // No SEEK (ADPC) header, so just start where the SEEK header is supposed to be. + if (seek_offset == 0) goto fail; + start_offset = seek_offset; + } else { + if (data_offset == 0) goto fail; + start_offset = data_offset + 0x20; + } - for (j = 0; jchannels; j++) { - for (i = 0; i<16; i++) { - vgmstream->ch[j].adpcm_coef[i] = read_16bitLE(info_offset + coef_offset + j*coef_spacing + i * 2, streamFile); - } - } - } - - if (ima) { // No SEEK (ADPC) header, so just start where the SEEK header is supposed to be. - if (seek_offset == 0) goto fail; - start_offset = seek_offset; - } else { - if (data_offset == 0) goto fail; - start_offset = data_offset + 0x20; - } - /* open the file for reading by each channel */ if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) diff --git a/src/meta/fsb.c b/src/meta/fsb.c index cd84c40c..bffa349d 100644 --- a/src/meta/fsb.c +++ b/src/meta/fsb.c @@ -254,7 +254,8 @@ VGMSTREAM * init_vgmstream_fsb_offset(STREAMFILE *streamFile, off_t offset) { /* sometimes there is garbage at the end or missing bytes due to improper demuxing */ VGM_ASSERT(fsbh.hdrsize + fsbh.shdrsize + fsbh.datasize != streamFile->get_size(streamFile) - offset, - "FSB wrong head/datasize found\n"); + "FSB wrong head/datasize found (expected 0x%x vs 0x%lx)\n", + fsbh.hdrsize + fsbh.shdrsize + fsbh.datasize, streamFile->get_size(streamFile) - offset); /* Loops unless disabled. FMOD default seems full loops (0/num_samples-1) without flags, for repeating tracks * that should loop and jingles/sfx that shouldn't. We'll try to disable looping is it looks jingly enough. */ diff --git a/src/meta/genh.c b/src/meta/genh.c index 0849aa8a..b4a7e36b 100644 --- a/src/meta/genh.c +++ b/src/meta/genh.c @@ -3,6 +3,8 @@ #include "../layout/layout.h" #include "../util.h" + + /* known GENH types */ typedef enum { PSX = 0, /* PSX ADPCM */ @@ -28,26 +30,45 @@ typedef enum { XMA1 = 20, /* raw XMA1 */ XMA2 = 21, /* raw XMA2 */ FFMPEG = 22, /* any headered FFmpeg format */ + AC3 = 23, /* AC3/SPDIF */ } genh_type; +typedef struct { + genh_type codec; + int codec_mode; + size_t interleave; + + int channels; + int32_t sample_rate; + + size_t data_size; + off_t start_offset; + + int32_t num_samples; + int32_t loop_start_sample; + int32_t loop_end_sample; + int skip_samples_mode; + int32_t skip_samples; + + int loop_flag; + + int32_t coef[2]; + int32_t coef_splitted[2]; + int32_t coef_type; + int32_t coef_interleave_type; + int coef_big_endian; + +} genh_header; + +static int parse_genh(STREAMFILE * streamFile, genh_header * genh); + /* GENH is an artificial "generic" header for headerless streams */ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; - - int channel_count, loop_flag, sample_rate, interleave; - int32_t num_samples = 0, loop_start, loop_end, skip_samples = 0; - int32_t start_offset, header_size; - off_t datasize = 0; - - int32_t coef[2]; - int32_t coef_splitted[2]; - int32_t dsp_interleave_type; - int32_t coef_type; - int skip_samples_mode, atrac3_mode, xma_mode; + genh_header genh = {0}; + coding_t coding; int i, j; - coding_t coding; - genh_type type; /* check extension, case insensitive */ if (!check_extensions(streamFile,"genh")) goto fail; @@ -55,12 +76,13 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { /* check header magic */ if (read_32bitBE(0x0,streamFile) != 0x47454e48) goto fail; - channel_count = read_32bitLE(0x4,streamFile); - if (channel_count < 1) goto fail; + /* process the header */ + if (!parse_genh(streamFile, &genh)) + goto fail; + - type = read_32bitLE(0x18,streamFile); /* type to coding conversion */ - switch (type) { + switch (genh.codec) { case PSX: coding = coding_PSX; break; case XBOX: coding = coding_XBOX; break; case NGC_DTK: coding = coding_NGC_DTK; break; @@ -86,68 +108,27 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { case ATRAC3PLUS: case XMA1: case XMA2: + case AC3: case FFMPEG: coding = coding_FFmpeg; break; #endif default: goto fail; } - start_offset = read_32bitLE(0x1C,streamFile); - header_size = read_32bitLE(0x20,streamFile); - - /* HACK to support old genh */ - if (header_size == 0) { - start_offset = 0x800; - header_size = 0x800; - } - - /* check for audio data start past header end */ - if (header_size > start_offset) goto fail; - - interleave = read_32bitLE(0x8,streamFile); - sample_rate = read_32bitLE(0xc,streamFile); - loop_start = read_32bitLE(0x10,streamFile); - loop_end = read_32bitLE(0x14,streamFile); - - coef[0] = read_32bitLE(0x24,streamFile); - coef[1] = read_32bitLE(0x28,streamFile); - dsp_interleave_type = read_32bitLE(0x2C,streamFile); - - /* DSP coefficient variants */ - /* bit 0 - split coefs (2 arrays) */ - /* bit 1 - little endian coefs */ - coef_type = read_32bitLE(0x30,streamFile); - /* when using split coefficients, 2nd array is at: */ - coef_splitted[0] = read_32bitLE(0x34,streamFile); - coef_splitted[1] = read_32bitLE(0x38,streamFile); - - /* other fields */ - num_samples = read_32bitLE(0x40,streamFile); - skip_samples = read_32bitLE(0x44,streamFile); /* for FFmpeg based codecs */ - skip_samples_mode = read_8bit(0x48,streamFile); /* 0=autodetect, 1=force manual value @ 0x44 */ - atrac3_mode = read_8bit(0x49,streamFile); /* 0=autodetect, 1=force joint stereo, 2=force full stereo */ - xma_mode = read_8bit(0x4a,streamFile); /* 0=default (4ch = 2ch + 2ch), 1=single (4ch = 1ch + 1ch + 1ch + 1ch) */ - datasize = read_32bitLE(0x50,streamFile); - if (!datasize) - datasize = get_streamfile_size(streamFile)-start_offset; - - num_samples = num_samples > 0 ? num_samples : loop_end; - loop_flag = loop_start != -1; - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); + vgmstream = allocate_vgmstream(genh.channels,genh.loop_flag); if (!vgmstream) goto fail; - vgmstream->sample_rate = sample_rate; - vgmstream->num_samples = num_samples; - vgmstream->loop_start_sample = loop_start; - vgmstream->loop_end_sample = loop_end; + vgmstream->sample_rate = genh.sample_rate; + vgmstream->num_samples = genh.num_samples; + vgmstream->loop_start_sample = genh.loop_start_sample; + vgmstream->loop_end_sample = genh.loop_end_sample; /* codec specific */ switch (coding) { case coding_PCM8_U_int: - vgmstream->layout_type=layout_none; + vgmstream->layout_type = layout_none; break; case coding_PCM16LE: case coding_PCM16BE: @@ -160,14 +141,14 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { case coding_IMA: case coding_AICA: case coding_APPLE_IMA4: - vgmstream->interleave_block_size = interleave; - if (channel_count > 1) + vgmstream->interleave_block_size = genh.interleave; + if (vgmstream->channels > 1) { if (coding == coding_SDX2) { coding = coding_SDX2_int; } - if (vgmstream->interleave_block_size==0xffffffff) { + if (vgmstream->interleave_block_size==0xffffffff) {// || vgmstream->interleave_block_size == 0) { vgmstream->layout_type = layout_none; } else { @@ -179,7 +160,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { } /* to avoid endless loops */ - if (!interleave && ( + if (!genh.interleave && ( coding == coding_PSX || coding == coding_PSX_badflags || coding == coding_IMA_int || @@ -194,64 +175,61 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { /* setup adpcm */ if (coding == coding_AICA) { int i; - for (i=0;ichannels;i++) { vgmstream->ch[i].adpcm_step_index = 0x7f; } } break; case coding_MS_IMA: - if (!interleave) goto fail; /* creates garbage */ + if (!genh.interleave) goto fail; /* creates garbage */ - vgmstream->interleave_block_size = interleave; + vgmstream->interleave_block_size = genh.interleave; vgmstream->layout_type = layout_none; break; case coding_MSADPCM: - if (channel_count > 2) goto fail; - if (!interleave) goto fail; /* creates garbage */ + if (vgmstream->channels > 2) goto fail; + if (!genh.interleave) goto fail; /* creates garbage */ - vgmstream->interleave_block_size = interleave; + vgmstream->interleave_block_size = genh.interleave; vgmstream->layout_type = layout_none; break; case coding_XBOX: vgmstream->layout_type = layout_none; break; case coding_NGC_DTK: - if (channel_count != 2) goto fail; + if (vgmstream->channels != 2) goto fail; vgmstream->layout_type = layout_none; break; case coding_NGC_DSP: - if (dsp_interleave_type == 0) { - if (!interleave) goto fail; + if (genh.coef_interleave_type == 0) { + if (!genh.interleave) goto fail; vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = interleave; - } else if (dsp_interleave_type == 1) { - if (!interleave) goto fail; + vgmstream->interleave_block_size = genh.interleave; + } else if (genh.coef_interleave_type == 1) { + if (!genh.interleave) goto fail; vgmstream->layout_type = layout_interleave_byte; - vgmstream->interleave_block_size = interleave; - } else if (dsp_interleave_type == 2) { + vgmstream->interleave_block_size = genh.interleave; + } else if (genh.coef_interleave_type == 2) { vgmstream->layout_type = layout_none; - } + }// else { + // goto fail; + //} /* get coefs */ - for (i=0;ichannels;i++) { + int16_t (*read_16bit)(off_t , STREAMFILE*) = genh.coef_big_endian ? read_16bitBE : read_16bitLE; - /* bit 0 - split coefs (2 arrays) */ - if ((coef_type & 1) == 0) { + /* normal/split coefs */ + if ((genh.coef_type & 1) == 0) { /* bit 0 - split coefs (2 arrays) */ for (j=0;j<16;j++) { - vgmstream->ch[i].adpcm_coef[j] = read_16bit(coef[i]+j*2,streamFile); + vgmstream->ch[i].adpcm_coef[j] = read_16bit(genh.coef[i]+j*2,streamFile); } - } else { + } + else { for (j=0;j<8;j++) { - vgmstream->ch[i].adpcm_coef[j*2]=read_16bit(coef[i]+j*2,streamFile); - vgmstream->ch[i].adpcm_coef[j*2+1]=read_16bit(coef_splitted[i]+j*2,streamFile); + vgmstream->ch[i].adpcm_coef[j*2]=read_16bit(genh.coef[i]+j*2,streamFile); + vgmstream->ch[i].adpcm_coef[j*2+1]=read_16bit(genh.coef_splitted[i]+j*2,streamFile); } } } @@ -260,7 +238,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { #ifdef VGM_USE_MPEG case coding_MPEG_layer3: vgmstream->layout_type = layout_none; - vgmstream->codec_data = init_mpeg_codec_data(streamFile, start_offset, &coding, vgmstream->channels); + vgmstream->codec_data = init_mpeg_codec_data(streamFile, genh.start_offset, &coding, vgmstream->channels); if (!vgmstream->codec_data) goto fail; break; @@ -269,50 +247,53 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { case coding_FFmpeg: { ffmpeg_codec_data *ffmpeg_data = NULL; - if (type == FFMPEG) { + if (genh.codec == FFMPEG || genh.codec == AC3) { /* default FFmpeg */ - ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset,datasize); + ffmpeg_data = init_ffmpeg_offset(streamFile, genh.start_offset,genh.data_size); if ( !ffmpeg_data ) goto fail; + + //if (vgmstream->num_samples == 0) + // vgmstream->num_samples = ffmpeg_data->totalSamples; /* sometimes works */ } else { /* fake header FFmpeg */ uint8_t buf[200]; int32_t bytes; - if (type == ATRAC3) { - int block_size = interleave; + if (genh.codec == ATRAC3) { + int block_size = genh.interleave; int joint_stereo; - switch(atrac3_mode) { - case 0: joint_stereo = vgmstream->channels > 1 && interleave/vgmstream->channels==0x60 ? 1 : 0; break; /* autodetect */ + switch(genh.codec_mode) { + case 0: joint_stereo = vgmstream->channels > 1 && genh.interleave/vgmstream->channels==0x60 ? 1 : 0; break; /* autodetect */ case 1: joint_stereo = 1; break; /* force joint stereo */ case 2: joint_stereo = 0; break; /* force stereo */ default: goto fail; } - bytes = ffmpeg_make_riff_atrac3(buf, 200, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, skip_samples); + bytes = ffmpeg_make_riff_atrac3(buf, 200, vgmstream->num_samples, genh.data_size, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, genh.skip_samples); } - else if (type == ATRAC3PLUS) { - int block_size = interleave; + else if (genh.codec == ATRAC3PLUS) { + int block_size = genh.interleave; - bytes = ffmpeg_make_riff_atrac3plus(buf, 200, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_size, skip_samples); + bytes = ffmpeg_make_riff_atrac3plus(buf, 200, vgmstream->num_samples, genh.data_size, vgmstream->channels, vgmstream->sample_rate, block_size, genh.skip_samples); } - else if (type == XMA1) { - int xma_stream_mode = xma_mode == 1 ? 1 : 0; + else if (genh.codec == XMA1) { + int xma_stream_mode = genh.codec_mode == 1 ? 1 : 0; - bytes = ffmpeg_make_riff_xma1(buf, 100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, xma_stream_mode); + bytes = ffmpeg_make_riff_xma1(buf, 100, vgmstream->num_samples, genh.data_size, vgmstream->channels, vgmstream->sample_rate, xma_stream_mode); } - else if (type == XMA2) { - int block_size = interleave ? interleave : 2048; - int block_count = datasize / block_size; + else if (genh.codec == XMA2) { + int block_size = genh.interleave ? genh.interleave : 2048; + int block_count = genh.data_size / block_size; - bytes = ffmpeg_make_riff_xma2(buf, 200, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); + bytes = ffmpeg_make_riff_xma2(buf, 200, vgmstream->num_samples, genh.data_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); } else { goto fail; } if (bytes <= 0) goto fail; - ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,datasize); + ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf,bytes, genh.start_offset,genh.data_size); if ( !ffmpeg_data ) goto fail; } @@ -320,8 +301,8 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { vgmstream->layout_type = layout_none; /* force encoder delay */ - if (skip_samples_mode && skip_samples >= 0) { - ffmpeg_set_skip_samples(ffmpeg_data, skip_samples); + if (genh.skip_samples_mode && genh.skip_samples >= 0) { + ffmpeg_set_skip_samples(ffmpeg_data, genh.skip_samples); } break; @@ -335,7 +316,7 @@ VGMSTREAM * init_vgmstream_genh(STREAMFILE *streamFile) { vgmstream->meta_type = meta_GENH; - if ( !vgmstream_open_stream(vgmstream,streamFile,start_offset) ) + if ( !vgmstream_open_stream(vgmstream,streamFile,genh.start_offset) ) goto fail; return vgmstream; @@ -344,3 +325,60 @@ fail: close_vgmstream(vgmstream); return NULL; } + + +static int parse_genh(STREAMFILE * streamFile, genh_header * genh) { + size_t header_size; + + genh->channels = read_32bitLE(0x4,streamFile); + + genh->interleave = read_32bitLE(0x8,streamFile); + genh->sample_rate = read_32bitLE(0xc,streamFile); + genh->loop_start_sample = read_32bitLE(0x10,streamFile); + genh->loop_end_sample = read_32bitLE(0x14,streamFile); + + genh->codec = read_32bitLE(0x18,streamFile); + genh->start_offset = read_32bitLE(0x1C,streamFile); + header_size = read_32bitLE(0x20,streamFile); + /* HACK to support old genh */ + if (header_size == 0) { + genh->start_offset = 0x800; + header_size = 0x800; + } + /* check for audio data start past header end */ + if (header_size > genh->start_offset) goto fail; + + genh->coef[0] = read_32bitLE(0x24,streamFile); + genh->coef[1] = read_32bitLE(0x28,streamFile); + genh->coef_interleave_type = read_32bitLE(0x2C,streamFile); + + /* DSP coefficient variants */ + /* bit 0 - split coefs (2 arrays) */ + /* bit 1 - little endian coefs */ + genh->coef_type = read_32bitLE(0x30,streamFile); + genh->coef_big_endian = ((genh->coef_type & 2) == 0); + + /* when using split coefficients, 2nd array is at: */ + genh->coef_splitted[0] = read_32bitLE(0x34,streamFile); + genh->coef_splitted[1] = read_32bitLE(0x38,streamFile); + + /* other fields */ + genh->num_samples = read_32bitLE(0x40,streamFile); + genh->skip_samples = read_32bitLE(0x44,streamFile); /* for FFmpeg based codecs */ + genh->skip_samples_mode = read_8bit(0x48,streamFile); /* 0=autodetect, 1=force manual value @ 0x44 */ + if (genh->codec == ATRAC3 || genh->codec == ATRAC3PLUS) + genh->codec_mode = read_8bit(0x49,streamFile); /* 0=autodetect, 1=force joint stereo, 2=force full stereo */ + if (genh->codec == XMA1 || genh->codec == XMA2) + genh->codec_mode = read_8bit(0x4a,streamFile); /* 0=default (4ch = 2ch + 2ch), 1=single (4ch = 1ch + 1ch + 1ch + 1ch) */ + genh->data_size = read_32bitLE(0x50,streamFile); + if (genh->data_size == 0) + genh->data_size = get_streamfile_size(streamFile) - genh->start_offset; + + genh->num_samples = genh->num_samples > 0 ? genh->num_samples : genh->loop_end_sample; + genh->loop_flag = genh->loop_start_sample != -1; + + return 1; + +fail: + return 0; +} diff --git a/src/meta/meta.h b/src/meta/meta.h index 8e23fd37..fe194a95 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -276,8 +276,6 @@ VGMSTREAM * init_vgmstream_ps2_omu(STREAMFILE *streamFile); VGMSTREAM * init_vgmstream_ps2_xa2(STREAMFILE * streamFile); -VGMSTREAM * init_vgmstream_ss_stream(STREAMFILE * streamFile); - //VGMSTREAM * init_vgmstream_idsp(STREAMFILE * streamFile); VGMSTREAM * init_vgmstream_idsp2(STREAMFILE * streamFile); @@ -581,6 +579,7 @@ VGMSTREAM * init_vgmstream_hyperscan_kvag(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_ios_psnd(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_pc_adp_bos(STREAMFILE* streamFile); + VGMSTREAM * init_vgmstream_pc_adp_otns(STREAMFILE* streamFile); VGMSTREAM * init_vgmstream_eb_sfx(STREAMFILE* streamFile); diff --git a/src/meta/nds_strm.c b/src/meta/nds_strm.c index c41cd9ed..adef717a 100644 --- a/src/meta/nds_strm.c +++ b/src/meta/nds_strm.c @@ -19,11 +19,11 @@ VGMSTREAM * init_vgmstream_nds_strm(STREAMFILE *streamFile) { if (strcasecmp("strm",filename_extension(filename))) goto fail; /* check header */ - if ((uint32_t)read_32bitBE(0x00,streamFile)!=0x5354524D) /* STRM */ + if ((uint32_t)read_32bitBE(0x00,streamFile)!=0x5354524D) /* STRM */ + goto fail; + if ((uint32_t)read_32bitBE(0x04,streamFile)!=0xFFFE0001 && /* Old Header Check */ + ((uint32_t)read_32bitBE(0x04,streamFile)!=0xFEFF0001)) /* Some newer games have a new flag */ goto fail; - if ((uint32_t)read_32bitBE(0x04,streamFile)!=0xFFFE0001 && /* Old Header Check */ - ((uint32_t)read_32bitBE(0x04,streamFile)!=0xFEFF0001)) /* Some newer games have a new flag */ - goto fail; diff --git a/src/meta/ngc_dsp_ygo.c b/src/meta/ngc_dsp_ygo.c index 76de70ba..77608018 100644 --- a/src/meta/ngc_dsp_ygo.c +++ b/src/meta/ngc_dsp_ygo.c @@ -2,17 +2,17 @@ #include "../util.h" /* .dsp found in: - Hikaru No Go 3 (NGC) - Yu-Gi-Oh! The Falsebound Kingdom (NGC) + Hikaru No Go 3 (NGC) + Yu-Gi-Oh! The Falsebound Kingdom (NGC) - 2010-01-31 - added loop stuff and some header checks... + 2010-01-31 - added loop stuff and some header checks... */ VGMSTREAM * init_vgmstream_dsp_ygo(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[PATH_LIMIT]; - int loop_flag; - int channel_count; + int loop_flag; + int channel_count; off_t start_offset; int i; @@ -24,29 +24,29 @@ VGMSTREAM * init_vgmstream_dsp_ygo(STREAMFILE *streamFile) { if ((read_32bitBE(0x0,streamFile)+0xE0) != (get_streamfile_size(streamFile))) goto fail; - loop_flag = (uint16_t)(read_16bitBE(0x2C,streamFile) != 0x0); + loop_flag = (uint16_t)(read_16bitBE(0x2C,streamFile) != 0x0); channel_count = 1; - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - start_offset = 0xE0; - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitBE(0x28,streamFile); + /* fill in the vital statistics */ + start_offset = 0xE0; + vgmstream->channels = channel_count; + vgmstream->sample_rate = read_32bitBE(0x28,streamFile); vgmstream->coding_type = coding_NGC_DSP; vgmstream->num_samples = read_32bitBE(0x20,streamFile); vgmstream->layout_type = layout_none; - vgmstream->meta_type = meta_DSP_YGO; - if (loop_flag) { - vgmstream->loop_start_sample = (read_32bitBE(0x30,streamFile)*14/16); - vgmstream->loop_end_sample = (read_32bitBE(0x34,streamFile)*14/16); - } + vgmstream->meta_type = meta_DSP_YGO; + if (loop_flag) { + vgmstream->loop_start_sample = (read_32bitBE(0x30,streamFile)*14/16); + vgmstream->loop_end_sample = (read_32bitBE(0x34,streamFile)*14/16); + } - // read coef stuff - { - for (i=0;i<16;i++) { + // read coef stuff + { + for (i=0;i<16;i++) { vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x3C+i*2,streamFile); } } diff --git a/src/meta/ngc_sck_dsp.c b/src/meta/ngc_sck_dsp.c index ad9e1498..edf1ed67 100644 --- a/src/meta/ngc_sck_dsp.c +++ b/src/meta/ngc_sck_dsp.c @@ -8,63 +8,63 @@ VGMSTREAM * init_vgmstream_ngc_sck_dsp(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; + VGMSTREAM * vgmstream = NULL; STREAMFILE * streamFileDSP = NULL; char filename[PATH_LIMIT]; - char filenameDSP[PATH_LIMIT]; - - int i; - int channel_count; - int loop_flag; + char filenameDSP[PATH_LIMIT]; + + int i; + int channel_count; + int loop_flag; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); if (strcasecmp("sck",filename_extension(filename))) goto fail; - strcpy(filenameDSP,filename); - strcpy(filenameDSP+strlen(filenameDSP)-3,"dsp"); + strcpy(filenameDSP,filename); + strcpy(filenameDSP+strlen(filenameDSP)-3,"dsp"); + + streamFileDSP = streamFile->open(streamFile,filenameDSP,STREAMFILE_DEFAULT_BUFFER_SIZE); - streamFileDSP = streamFile->open(streamFile,filenameDSP,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (read_32bitBE(0x5C,streamFile) != 0x60A94000) goto fail; - if (!streamFile) goto fail; - - channel_count = 2; - loop_flag = 0; + if (!streamFile) goto fail; + + channel_count = 2; + loop_flag = 0; /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; /* fill in the vital statistics */ - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitBE(0x18,streamFile); - vgmstream->num_samples=read_32bitBE(0x14,streamFile)/8/channel_count*14; - vgmstream->coding_type = coding_NGC_DSP; - - if(loop_flag) { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = read_32bitBE(0x10,streamFile)/8/channel_count*14; - } + vgmstream->channels = channel_count; + vgmstream->sample_rate = read_32bitBE(0x18,streamFile); + vgmstream->num_samples=read_32bitBE(0x14,streamFile)/8/channel_count*14; + vgmstream->coding_type = coding_NGC_DSP; - if (channel_count == 1) { - vgmstream->layout_type = layout_none; - } else if (channel_count == 2) { - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size=read_32bitBE(0xC,streamFile); - } + if(loop_flag) { + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = read_32bitBE(0x10,streamFile)/8/channel_count*14; + } + + if (channel_count == 1) { + vgmstream->layout_type = layout_none; + } else if (channel_count == 2) { + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size=read_32bitBE(0xC,streamFile); + } vgmstream->meta_type = meta_NGC_SCK_DSP; - + /* open the file for reading */ { for (i=0;ich[i].streamfile = streamFile->open(streamFileDSP,filenameDSP,0x8000); vgmstream->ch[i].offset = 0; @@ -74,7 +74,7 @@ VGMSTREAM * init_vgmstream_ngc_sck_dsp(STREAMFILE *streamFile) { - if (vgmstream->coding_type == coding_NGC_DSP) { + if (vgmstream->coding_type == coding_NGC_DSP) { int i; for (i=0;i<16;i++) { vgmstream->ch[0].adpcm_coef[i] = read_16bitBE(0x2C+i*2,streamFile); @@ -87,7 +87,7 @@ VGMSTREAM * init_vgmstream_ngc_sck_dsp(STREAMFILE *streamFile) { } - close_streamfile(streamFileDSP); streamFileDSP=NULL; + close_streamfile(streamFileDSP); streamFileDSP=NULL; return vgmstream; /* clean up anything we may have opened */ diff --git a/src/meta/pc_adp.c b/src/meta/pc_adp.c index e534a93b..3475a8bc 100644 --- a/src/meta/pc_adp.c +++ b/src/meta/pc_adp.c @@ -1,5 +1,4 @@ #include "meta.h" -#include "../util.h" /* ADP - from Balls of Steel */ VGMSTREAM * init_vgmstream_pc_adp_bos(STREAMFILE *streamFile) { @@ -48,45 +47,3 @@ fail: close_vgmstream(vgmstream); return NULL; } - -/* ADP - from Omikron: The Nomad Soul (PC/DC) */ -VGMSTREAM * init_vgmstream_pc_adp_otns(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset, datasize; - int loop_flag = 0, channel_count, stereo_flag; - - if (!check_extensions(streamFile,"adp")) goto fail; - - /* no ID, only a basic 0x10 header with filesize and nulls; do some extra checks */ - datasize = read_32bitLE(0x00,streamFile) & 0x00FFFFFF; /*24 bit*/ - if (datasize + 0x10 != streamFile->get_size(streamFile) - || read_32bitLE(0x04,streamFile) != 0 - || read_32bitLE(0x08,streamFile) != 0 - || read_32bitLE(0x0c,streamFile) != 0) - goto fail; - - stereo_flag = read_8bit(0x03, streamFile); - if (stereo_flag > 1 || stereo_flag < 0) goto fail; - channel_count = stereo_flag ? 2 : 1; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; - - start_offset = 0x10; - vgmstream->channels = channel_count; - vgmstream->sample_rate = 22050; - vgmstream->num_samples = channel_count== 1 ? datasize*2 : datasize; - - vgmstream->coding_type = coding_OTNS_IMA; - vgmstream->layout_type = layout_none; - vgmstream->meta_type = meta_OTNS_ADP; - - if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) - goto fail; - return vgmstream; - -fail: - close_vgmstream(vgmstream); - return NULL; -} diff --git a/src/meta/pc_adp_otns.c b/src/meta/pc_adp_otns.c new file mode 100644 index 00000000..6efc43d5 --- /dev/null +++ b/src/meta/pc_adp_otns.c @@ -0,0 +1,43 @@ +#include "meta.h" + +/* ADP - from Omikron: The Nomad Soul (PC/DC) */ +VGMSTREAM * init_vgmstream_pc_adp_otns(STREAMFILE *streamFile) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset, datasize; + int loop_flag = 0, channel_count, stereo_flag; + + if (!check_extensions(streamFile,"adp")) goto fail; + + /* no ID, only a basic 0x10 header with filesize and nulls; do some extra checks */ + datasize = read_32bitLE(0x00,streamFile) & 0x00FFFFFF; /*24 bit*/ + if (datasize + 0x10 != streamFile->get_size(streamFile) + || read_32bitLE(0x04,streamFile) != 0 + || read_32bitLE(0x08,streamFile) != 0 + || read_32bitLE(0x0c,streamFile) != 0) + goto fail; + + stereo_flag = read_8bit(0x03, streamFile); + if (stereo_flag > 1 || stereo_flag < 0) goto fail; + channel_count = stereo_flag ? 2 : 1; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + start_offset = 0x10; + vgmstream->channels = channel_count; + vgmstream->sample_rate = 22050; + vgmstream->num_samples = channel_count== 1 ? datasize*2 : datasize; + + vgmstream->coding_type = coding_OTNS_IMA; + vgmstream->layout_type = layout_none; + vgmstream->meta_type = meta_OTNS_ADP; + + if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/pcm.c b/src/meta/pcm.c index ff637106..30ca247e 100644 --- a/src/meta/pcm.c +++ b/src/meta/pcm.c @@ -4,41 +4,41 @@ /* PCM (from Lunar: Eternal Blue (Sega CD) */ VGMSTREAM * init_vgmstream_pcm_scd(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; - off_t start_offset; + VGMSTREAM * vgmstream = NULL; + char filename[PATH_LIMIT]; + off_t start_offset; int loop_flag; int channel_count; - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("pcm",filename_extension(filename))) goto fail; + /* check extension, case insensitive */ + streamFile->get_name(streamFile,filename,sizeof(filename)); + if (strcasecmp("pcm",filename_extension(filename))) goto fail; /* check header */ if (read_32bitBE(0x0,streamFile) != 0x00020000) - goto fail; + goto fail; - loop_flag = (read_32bitLE(0x02,streamFile)!=0); - channel_count = 1; - - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); - if (!vgmstream) goto fail; + loop_flag = (read_32bitLE(0x02,streamFile)!=0); + channel_count = 1; - /* fill in the vital statistics */ - start_offset = 0x200; - vgmstream->channels = channel_count; - vgmstream->sample_rate = 32000; - vgmstream->coding_type = coding_PCM8_SB_int; - vgmstream->num_samples = read_32bitBE(0x06,streamFile)*2; - if(loop_flag) { - vgmstream->loop_start_sample = read_32bitBE(0x02,streamFile)*0x400*2; - vgmstream->loop_end_sample = read_32bitBE(0x06,streamFile)*2; - } - vgmstream->layout_type = layout_interleave; - vgmstream->interleave_block_size = 0x1; - vgmstream->meta_type = meta_PCM_SCD; + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + + /* fill in the vital statistics */ + start_offset = 0x200; + vgmstream->channels = channel_count; + vgmstream->sample_rate = 32000; + vgmstream->coding_type = coding_PCM8_SB_int; + vgmstream->num_samples = read_32bitBE(0x06,streamFile)*2; + if(loop_flag) { + vgmstream->loop_start_sample = read_32bitBE(0x02,streamFile)*0x400*2; + vgmstream->loop_end_sample = read_32bitBE(0x06,streamFile)*2; + } + vgmstream->layout_type = layout_interleave; + vgmstream->interleave_block_size = 0x1; + vgmstream->meta_type = meta_PCM_SCD; /* open the file for reading */ { @@ -54,7 +54,7 @@ VGMSTREAM * init_vgmstream_pcm_scd(STREAMFILE *streamFile) { } } - return vgmstream; + return vgmstream; /* clean up anything we may have opened */ fail: @@ -64,41 +64,41 @@ fail: /* PCM - Custom header from Konami, which contains only loop infos... - found in: Ephemeral Fantasia [Reiselied] - Yu-Gi-Oh! The Duelists of the Roses [Yu-Gi-Oh! Shin Duel Monsters II] + found in: Ephemeral Fantasia [Reiselied] + Yu-Gi-Oh! The Duelists of the Roses [Yu-Gi-Oh! Shin Duel Monsters II] */ VGMSTREAM * init_vgmstream_pcm_ps2(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[PATH_LIMIT]; off_t start_offset; int loop_flag = 0; - int channel_count; + int channel_count; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); if (strcasecmp("pcm",filename_extension(filename))) goto fail; - // if ((read_32bitLE(0x00,streamFile)+0x800) != (get_streamfile_size(streamFile))) - // goto fail; - if ((read_32bitLE(0x00,streamFile)) != (read_32bitLE(0x04,streamFile)*4)) - goto fail; + // if ((read_32bitLE(0x00,streamFile)+0x800) != (get_streamfile_size(streamFile))) + // goto fail; + if ((read_32bitLE(0x00,streamFile)) != (read_32bitLE(0x04,streamFile)*4)) + goto fail; - loop_flag = (read_32bitLE(0x08,streamFile) != 0x0); + loop_flag = (read_32bitLE(0x08,streamFile) != 0x0); channel_count = 2; - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ + /* fill in the vital statistics */ start_offset = 0x800; - vgmstream->channels = channel_count; + vgmstream->channels = channel_count; vgmstream->sample_rate = 24000; vgmstream->coding_type = coding_PCM16LE; vgmstream->num_samples = read_32bitLE(0x0,streamFile)/2/channel_count; if (loop_flag) { - vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile); - vgmstream->loop_end_sample = read_32bitLE(0x0C,streamFile); + vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile); + vgmstream->loop_end_sample = read_32bitLE(0x0C,streamFile); } vgmstream->layout_type = layout_interleave; diff --git a/src/meta/ps2_ads.c b/src/meta/ps2_ads.c index e8316ebd..628aba3e 100644 --- a/src/meta/ps2_ads.c +++ b/src/meta/ps2_ads.c @@ -9,17 +9,17 @@ VGMSTREAM * init_vgmstream_ps2_ads(STREAMFILE *streamFile) { int loop_flag=0; int channel_count; - off_t start_offset; - off_t check_offset; - int32_t streamSize; + off_t start_offset; + off_t check_offset; + int32_t streamSize; - uint8_t testBuffer[0x10]; - uint8_t isPCM = 0; + uint8_t testBuffer[0x10]; + uint8_t isPCM = 0; - off_t readOffset = 0; - off_t loopEnd = 0; + off_t readOffset = 0; + off_t loopEnd = 0; - int i; + int i; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -35,27 +35,27 @@ VGMSTREAM * init_vgmstream_ps2_ads(STREAMFILE *streamFile) { goto fail; /* check if file is not corrupt */ - /* seems the Gran Turismo 4 ADS files are considered corrupt,*/ - /* so I changed it to adapt the stream size if that's the case */ - /* instead of failing playing them at all*/ - streamSize = read_32bitLE(0x24,streamFile); + /* seems the Gran Turismo 4 ADS files are considered corrupt,*/ + /* so I changed it to adapt the stream size if that's the case */ + /* instead of failing playing them at all*/ + streamSize = read_32bitLE(0x24,streamFile); - if (get_streamfile_size(streamFile) < (size_t)(streamSize + 0x28)) - { - streamSize = get_streamfile_size(streamFile) - 0x28; - } + if (get_streamfile_size(streamFile) < (size_t)(streamSize + 0x28)) + { + streamSize = get_streamfile_size(streamFile) - 0x28; + } /* check loop */ - if ((read_32bitLE(0x1C,streamFile) == 0xFFFFFFFF) || - ((read_32bitLE(0x18,streamFile) == 0) && (read_32bitLE(0x1C,streamFile) == 0))) - { - loop_flag = 0; - } - else - { - loop_flag = 1; - } - + if ((read_32bitLE(0x1C,streamFile) == 0xFFFFFFFF) || + ((read_32bitLE(0x18,streamFile) == 0) && (read_32bitLE(0x1C,streamFile) == 0))) + { + loop_flag = 0; + } + else + { + loop_flag = 1; + } + channel_count=read_32bitLE(0x10,streamFile); /* build the VGMSTREAM */ @@ -70,9 +70,9 @@ VGMSTREAM * init_vgmstream_ps2_ads(STREAMFILE *streamFile) { vgmstream->coding_type = coding_PSX; vgmstream->num_samples = ((streamSize-0x40)/16*28)/vgmstream->channels; - /* SS2 container with RAW Interleaved PCM */ + /* SS2 container with RAW Interleaved PCM */ if (read_32bitLE(0x08,streamFile)!=0x10) - { + { vgmstream->coding_type=coding_PCM16LE; vgmstream->num_samples = streamSize/2/vgmstream->channels; @@ -84,100 +84,100 @@ VGMSTREAM * init_vgmstream_ps2_ads(STREAMFILE *streamFile) { /* Get loop point values */ if(vgmstream->loop_flag) { - if((read_32bitLE(0x1C,streamFile)*0x10*vgmstream->channels+0x800)==get_streamfile_size(streamFile)) - { - // Search for Loop Value - readOffset=(off_t)get_streamfile_size(streamFile)-(4*vgmstream->interleave_block_size); + if((read_32bitLE(0x1C,streamFile)*0x10*vgmstream->channels+0x800)==get_streamfile_size(streamFile)) + { + // Search for Loop Value + readOffset=(off_t)get_streamfile_size(streamFile)-(4*vgmstream->interleave_block_size); - do { - readOffset+=(off_t)read_streamfile(testBuffer,readOffset,0x10,streamFile); - - // Loop End ... - if(testBuffer[0x01]==0x01) { - if(loopEnd==0) loopEnd = readOffset-0x10; - break; - } + do { + readOffset+=(off_t)read_streamfile(testBuffer,readOffset,0x10,streamFile); - } while (streamFile->get_offset(streamFile)<(int32_t)get_streamfile_size(streamFile)); + // Loop End ... + if(testBuffer[0x01]==0x01) { + if(loopEnd==0) loopEnd = readOffset-0x10; + break; + } - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = (loopEnd/(vgmstream->interleave_block_size)*vgmstream->interleave_block_size)/16*28; - vgmstream->loop_end_sample += (loopEnd%vgmstream->interleave_block_size)/16*28; - vgmstream->loop_end_sample /=vgmstream->channels; + } while (streamFile->get_offset(streamFile)<(int32_t)get_streamfile_size(streamFile)); - } else { - if(read_32bitLE(0x1C,streamFile)<=vgmstream->num_samples) { - vgmstream->loop_start_sample = read_32bitLE(0x18,streamFile); - vgmstream->loop_end_sample = read_32bitLE(0x1C,streamFile); - } else { - vgmstream->loop_start_sample = (read_32bitLE(0x18,streamFile)*0x10)/16*28/vgmstream->channels;; - vgmstream->loop_end_sample = (read_32bitLE(0x1C,streamFile)*0x10)/16*28/vgmstream->channels; - } - } + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = (loopEnd/(vgmstream->interleave_block_size)*vgmstream->interleave_block_size)/16*28; + vgmstream->loop_end_sample += (loopEnd%vgmstream->interleave_block_size)/16*28; + vgmstream->loop_end_sample /=vgmstream->channels; + + } else { + if(read_32bitLE(0x1C,streamFile)<=vgmstream->num_samples) { + vgmstream->loop_start_sample = read_32bitLE(0x18,streamFile); + vgmstream->loop_end_sample = read_32bitLE(0x1C,streamFile); + } else { + vgmstream->loop_start_sample = (read_32bitLE(0x18,streamFile)*0x10)/16*28/vgmstream->channels;; + vgmstream->loop_end_sample = (read_32bitLE(0x1C,streamFile)*0x10)/16*28/vgmstream->channels; + } + } } /* 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; - { - start_offset=0x28; - } + { + start_offset=0x28; + } - - if ((streamSize * 2) == (get_streamfile_size(streamFile) - 0x18)) - { - // True Fortune PS2 - streamSize = (read_32bitLE(0x24,streamFile) * 2) - 0x10; - vgmstream->num_samples = streamSize / 16 * 28 / vgmstream->channels; - } - else if(get_streamfile_size(streamFile) - read_32bitLE(0x24,streamFile) >= 0x800) - { - // Hack for files with start_offset = 0x800 - start_offset=0x800; - } - if((vgmstream->coding_type == coding_PSX) && (start_offset==0x28)) - { - start_offset=0x800; - - for(i=0;i<0x1f6;i+=4) - { - if(read_32bitLE(0x28+(i*4),streamFile)!=0) - { - start_offset=0x28; - break; - } - } - } + if ((streamSize * 2) == (get_streamfile_size(streamFile) - 0x18)) + { + // True Fortune PS2 + streamSize = (read_32bitLE(0x24,streamFile) * 2) - 0x10; + vgmstream->num_samples = streamSize / 16 * 28 / vgmstream->channels; + } + else if(get_streamfile_size(streamFile) - read_32bitLE(0x24,streamFile) >= 0x800) + { + // Hack for files with start_offset = 0x800 + start_offset=0x800; + } - // check if we got a real pcm (ex: Clock Tower 3) - if(vgmstream->coding_type==coding_PCM16LE) - { - check_offset=start_offset; - do - { - if(read_8bit(check_offset+1,streamFile)>7) - { - isPCM=1; - break; - } - else - { - check_offset+=0x10; - } - - } while (check_offsetcoding_type == coding_PSX) && (start_offset==0x28)) + { + start_offset=0x800; - if(!isPCM) - { - vgmstream->num_samples=(get_streamfile_size(streamFile)-start_offset)/16*28/vgmstream->channels; - vgmstream->coding_type=coding_PSX; - } - } + for(i=0;i<0x1f6;i+=4) + { + if(read_32bitLE(0x28+(i*4),streamFile)!=0) + { + start_offset=0x28; + break; + } + } + } - /* expect pcm format allways start @ 0x800, don't know if it's true :P */ - /*if(vgmstream->coding_type == coding_PCM16LE) - start_offset=0x800;*/ + // check if we got a real pcm (ex: Clock Tower 3) + if(vgmstream->coding_type==coding_PCM16LE) + { + check_offset=start_offset; + do + { + if(read_8bit(check_offset+1,streamFile)>7) + { + isPCM=1; + break; + } + else + { + check_offset+=0x10; + } + + } while (check_offsetnum_samples=(get_streamfile_size(streamFile)-start_offset)/16*28/vgmstream->channels; + vgmstream->coding_type=coding_PSX; + } + } + + /* expect pcm format allways start @ 0x800, don't know if it's true :P */ + /*if(vgmstream->coding_type == coding_PCM16LE) + start_offset=0x800;*/ /* open the file for reading by each channel */ { diff --git a/src/meta/ps2_filp.c b/src/meta/ps2_filp.c index 4f888bdc..ec5d6757 100644 --- a/src/meta/ps2_filp.c +++ b/src/meta/ps2_filp.c @@ -8,8 +8,8 @@ VGMSTREAM * init_vgmstream_filp(STREAMFILE *streamFile) { char filename[PATH_LIMIT]; off_t start_offset; int loop_flag = 0; - int channel_count; - int i; + int channel_count; + int i; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -18,23 +18,23 @@ VGMSTREAM * init_vgmstream_filp(STREAMFILE *streamFile) { /* check header */ if (read_32bitBE(0x0,streamFile) != 0x46494C70) /* "FILp" */ goto fail; - if (read_32bitBE(0x100,streamFile) != 0x56414770) /* "VAGp" */ + if (read_32bitBE(0x100,streamFile) != 0x56414770) /* "VAGp" */ goto fail; - if (read_32bitBE(0x130,streamFile) != 0x56414770) /* "VAGp" */ + if (read_32bitBE(0x130,streamFile) != 0x56414770) /* "VAGp" */ + goto fail; + if (get_streamfile_size(streamFile) != read_32bitLE(0xC,streamFile)) goto fail; - if (get_streamfile_size(streamFile) != read_32bitLE(0xC,streamFile)) - goto fail; loop_flag = (read_32bitLE(0x34,streamFile) == 0); channel_count = read_32bitLE(0x4,streamFile); - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ + /* fill in the vital statistics */ start_offset = 0x0; - vgmstream->channels = channel_count; + vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitLE(0x110,streamFile); vgmstream->coding_type = coding_PSX; vgmstream->layout_type = layout_filp_blocked; @@ -47,9 +47,9 @@ VGMSTREAM * init_vgmstream_filp(STREAMFILE *streamFile) { if (!file) goto fail; for (i=0;ich[i].streamfile = file; - } - } - + } + } + filp_block_update(start_offset,vgmstream); vgmstream->num_samples = read_32bitLE(0x10C,streamFile)/16*28; if (loop_flag) { @@ -57,7 +57,7 @@ VGMSTREAM * init_vgmstream_filp(STREAMFILE *streamFile) { vgmstream->loop_end_sample = vgmstream->num_samples; } - + return vgmstream; /* clean up anything we may have opened */ diff --git a/src/meta/ps2_gcm.c b/src/meta/ps2_gcm.c index 92a07800..aea990a3 100644 --- a/src/meta/ps2_gcm.c +++ b/src/meta/ps2_gcm.c @@ -8,7 +8,7 @@ VGMSTREAM * init_vgmstream_ps2_gcm(STREAMFILE *streamFile) { off_t start_offset; int loop_flag; - int channel_count; + int channel_count; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -17,19 +17,19 @@ VGMSTREAM * init_vgmstream_ps2_gcm(STREAMFILE *streamFile) { /* check header */ if (read_32bitBE(0x00,streamFile) != 0x4D434700) /* "MCG" */ goto fail; - if (read_32bitBE(0x20,streamFile) != 0x56414770) /* "VAGp" */ + if (read_32bitBE(0x20,streamFile) != 0x56414770) /* "VAGp" */ goto fail; loop_flag = 0; channel_count= 2; - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ + /* fill in the vital statistics */ start_offset = 0x80; - vgmstream->channels = channel_count; + vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitBE(0x30,streamFile); vgmstream->coding_type = coding_PSX; vgmstream->num_samples = read_32bitLE(0x10,streamFile)*28/32; diff --git a/src/meta/ps2_hsf.c b/src/meta/ps2_hsf.c index 67979239..8c00a312 100644 --- a/src/meta/ps2_hsf.c +++ b/src/meta/ps2_hsf.c @@ -8,14 +8,14 @@ VGMSTREAM * init_vgmstream_ps2_hsf(STREAMFILE *streamFile) char filename[PATH_LIMIT]; off_t start_offset; int loop_flag = 0; - int channel_count; - size_t fileLength; - size_t frequencyFlag; - + int channel_count; + size_t fileLength; + size_t frequencyFlag; + #if 0 - off_t readOffset = 0; - uint8_t testBuffer[0x10]; - off_t loopEndOffset; + off_t readOffset = 0; + uint8_t testBuffer[0x10]; + off_t loopEndOffset; #endif /* check extension, case insensitive */ @@ -26,56 +26,56 @@ VGMSTREAM * init_vgmstream_ps2_hsf(STREAMFILE *streamFile) if (read_32bitBE(0x00,streamFile) != 0x48534600) // "HSF" goto fail; - loop_flag = 0; + loop_flag = 0; channel_count = 2; fileLength = get_streamfile_size(streamFile); - frequencyFlag = read_32bitLE(0x08, streamFile); + frequencyFlag = read_32bitLE(0x08, streamFile); - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - start_offset = 0x10; - vgmstream->channels = channel_count; + /* fill in the vital statistics */ + start_offset = 0x10; + vgmstream->channels = channel_count; - if (frequencyFlag == 0x0EB3) - { - vgmstream->sample_rate = 44100; - } - else if (frequencyFlag == 0x1000) - { - vgmstream->sample_rate = 48000; - } - - vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = ((fileLength - 0x10) / 16 * 28) / vgmstream->channels; + if (frequencyFlag == 0x0EB3) + { + vgmstream->sample_rate = 44100; + } + else if (frequencyFlag == 0x1000) + { + vgmstream->sample_rate = 48000; + } + + vgmstream->coding_type = coding_PSX; + vgmstream->num_samples = ((fileLength - 0x10) / 16 * 28) / vgmstream->channels; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = read_32bitLE(0x0C, streamFile); vgmstream->meta_type = meta_PS2_HSF; - if (vgmstream->loop_flag) - { - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = vgmstream->num_samples; + if (vgmstream->loop_flag) + { + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = vgmstream->num_samples; #if 0 - readOffset = fileLength - 0x10; + readOffset = fileLength - 0x10; - do - { - readOffset -=(off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile); + do + { + readOffset -=(off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile); - if (testBuffer[1] == 0x07) - { - loopEndOffset = readOffset + 0x10; - vgmstream->loop_end_sample = ((loopEndOffset - 0x10) / 16 * 28) / vgmstream->channels; - break; - } + if (testBuffer[1] == 0x07) + { + loopEndOffset = readOffset + 0x10; + vgmstream->loop_end_sample = ((loopEndOffset - 0x10) / 16 * 28) / vgmstream->channels; + break; + } - } while (readOffset > 0); + } while (readOffset > 0); #endif - } + } /* open the file for reading */ { diff --git a/src/meta/ps2_ild.c b/src/meta/ps2_ild.c index ea6a846f..7ef439ef 100644 --- a/src/meta/ps2_ild.c +++ b/src/meta/ps2_ild.c @@ -7,7 +7,7 @@ VGMSTREAM * init_vgmstream_ps2_ild(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[PATH_LIMIT]; int loop_flag=0; - int channel_count; + int channel_count; off_t start_offset; int i; @@ -19,33 +19,33 @@ VGMSTREAM * init_vgmstream_ps2_ild(STREAMFILE *streamFile) { if (read_32bitBE(0x00,streamFile) != 0x494C4400) goto fail; - /* check loop */ - loop_flag = (read_32bitLE(0x2C,streamFile)!=0); + /* check loop */ + loop_flag = (read_32bitLE(0x2C,streamFile)!=0); channel_count=read_32bitLE(0x04,streamFile); - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - vgmstream->channels = read_32bitLE(0x04,streamFile); + /* fill in the vital statistics */ + vgmstream->channels = read_32bitLE(0x04,streamFile); vgmstream->sample_rate = read_32bitLE(0x28,streamFile); - /* Check for Compression Scheme */ - vgmstream->coding_type = coding_PSX; + /* Check for Compression Scheme */ + vgmstream->coding_type = coding_PSX; vgmstream->num_samples = read_32bitLE(0x0C,streamFile)/16*28/vgmstream->channels; - /* Get loop point values */ - if(vgmstream->loop_flag) { - vgmstream->loop_start_sample = read_32bitLE(0x2C,streamFile)/16*28; - vgmstream->loop_end_sample = read_32bitLE(0x30,streamFile)/16*28; - } + /* Get loop point values */ + if(vgmstream->loop_flag) { + vgmstream->loop_start_sample = read_32bitLE(0x2C,streamFile)/16*28; + vgmstream->loop_end_sample = read_32bitLE(0x30,streamFile)/16*28; + } - vgmstream->interleave_block_size = read_32bitLE(0x18,streamFile)/2; + vgmstream->interleave_block_size = read_32bitLE(0x18,streamFile)/2; vgmstream->layout_type = layout_interleave; vgmstream->meta_type = meta_PS2_ILD; - start_offset = (off_t)read_32bitLE(0x08,streamFile); + start_offset = (off_t)read_32bitLE(0x08,streamFile); /* open the file for reading by each channel */ { diff --git a/src/meta/ps2_mcg.c b/src/meta/ps2_mcg.c index 0cb4c057..ba3eaec9 100644 --- a/src/meta/ps2_mcg.c +++ b/src/meta/ps2_mcg.c @@ -7,7 +7,7 @@ VGMSTREAM * init_vgmstream_ps2_mcg(STREAMFILE *streamFile) { char filename[PATH_LIMIT]; off_t start_offset; int loop_flag = 0; - int channel_count; + int channel_count; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -16,31 +16,31 @@ VGMSTREAM * init_vgmstream_ps2_mcg(STREAMFILE *streamFile) { /* check header */ if (!((read_32bitBE(0x00,streamFile) == 0x4D434700) && (read_32bitBE(0x20,streamFile) == 0x56414770) && - (read_32bitBE(0x50,streamFile) == 0x56414770))) + (read_32bitBE(0x50,streamFile) == 0x56414770))) goto fail; - loop_flag = (read_32bitLE(0x34,streamFile)!=0); + loop_flag = (read_32bitLE(0x34,streamFile)!=0); channel_count = 2; - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - start_offset = 0x80; - vgmstream->channels = channel_count; + /* fill in the vital statistics */ + start_offset = 0x80; + vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitBE(0x30,streamFile); vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = read_32bitBE(0x2C,streamFile)/16*14*channel_count; + vgmstream->num_samples = read_32bitBE(0x2C,streamFile)/16*14*channel_count; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = read_32bitLE(0x14,streamFile); vgmstream->meta_type = meta_PS2_MCG; - if (vgmstream->loop_flag) - { - vgmstream->loop_start_sample = read_32bitLE(0x34,streamFile); - vgmstream->loop_end_sample = vgmstream->num_samples; - } + if (vgmstream->loop_flag) + { + vgmstream->loop_start_sample = read_32bitLE(0x34,streamFile); + vgmstream->loop_end_sample = vgmstream->num_samples; + } /* open the file for reading */ { diff --git a/src/meta/ps2_mihb.c b/src/meta/ps2_mihb.c index b1dcbea6..826d1d5c 100644 --- a/src/meta/ps2_mihb.c +++ b/src/meta/ps2_mihb.c @@ -6,9 +6,9 @@ VGMSTREAM * init_vgmstream_ps2_mihb(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[PATH_LIMIT]; off_t start_offset; - int mib_blocks; + int mib_blocks; int loop_flag = 0; - int channel_count; + int channel_count; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -17,18 +17,18 @@ VGMSTREAM * init_vgmstream_ps2_mihb(STREAMFILE *streamFile) { /* check header */ if (read_32bitBE(0x00,streamFile) != 0x40000000) goto fail; - - mib_blocks = read_32bitLE(0x14,streamFile); + + mib_blocks = read_32bitLE(0x14,streamFile); loop_flag = 0; channel_count = read_32bitLE(0x08,streamFile); - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ + /* fill in the vital statistics */ start_offset = 0x40; - vgmstream->channels = channel_count; + vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitLE(0x0C,streamFile); vgmstream->coding_type = coding_PSX; vgmstream->num_samples = ((read_32bitLE(0x10,streamFile))*mib_blocks)*28/16; diff --git a/src/meta/ps2_npsf.c b/src/meta/ps2_npsf.c index 5289bdaa..76ec20b2 100644 --- a/src/meta/ps2_npsf.c +++ b/src/meta/ps2_npsf.c @@ -14,20 +14,20 @@ VGMSTREAM * init_vgmstream_ps2_npsf(STREAMFILE *streamFile) { if (read_32bitBE(0x00,streamFile) != 0x4E505346) /* "NPSF" */ goto fail; - loop_flag = (read_32bitLE(0x14,streamFile) != 0xFFFFFFFF); + loop_flag = (read_32bitLE(0x14,streamFile) != 0xFFFFFFFF); channel_count = read_32bitLE(0x0C,streamFile); - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - vgmstream->channels = read_32bitLE(0x0C,streamFile); + vgmstream->channels = read_32bitLE(0x0C,streamFile); vgmstream->sample_rate = read_32bitLE(0x18,streamFile); vgmstream->num_samples = ps_bytes_to_samples(read_32bitLE(0x08,streamFile), 1); /* single channel data */ - if(vgmstream->loop_flag) { - vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile); - vgmstream->loop_end_sample = ps_bytes_to_samples(read_32bitLE(0x08,streamFile), 1); - } + if(vgmstream->loop_flag) { + vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile); + vgmstream->loop_end_sample = ps_bytes_to_samples(read_32bitLE(0x08,streamFile), 1); + } vgmstream->coding_type = coding_PSX; vgmstream->layout_type = layout_interleave; diff --git a/src/meta/ps2_rxws.c b/src/meta/ps2_rxws.c index 01b0ea90..d5906243 100644 --- a/src/meta/ps2_rxws.c +++ b/src/meta/ps2_rxws.c @@ -186,30 +186,30 @@ VGMSTREAM * init_vgmstream_ps2_rxw(STREAMFILE *streamFile) { /* check RXWS/FORM Header */ if (!((read_32bitBE(0x00,streamFile) == 0x52585753) && - (read_32bitBE(0x10,streamFile) == 0x464F524D))) + (read_32bitBE(0x10,streamFile) == 0x464F524D))) goto fail; - loop_flag = (read_32bitLE(0x3C,streamFile)!=0xFFFFFFFF); - channel_count=2; /* Always stereo files */ + loop_flag = (read_32bitLE(0x3C,streamFile)!=0xFFFFFFFF); + channel_count=2; /* Always stereo files */ - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; vgmstream->sample_rate = read_32bitLE(0x2E,streamFile); 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,streamFile)/16*14; - vgmstream->loop_end_sample = read_32bitLE(0x38,streamFile)/16*14; - } + /* Get loop point values */ + if(vgmstream->loop_flag) { + 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,streamFile)+0x10; vgmstream->coding_type = coding_PSX; vgmstream->layout_type = layout_interleave; vgmstream->meta_type = meta_PS2_RXWS; - start_offset = 0x40; + start_offset = 0x40; /* open the file for reading */ if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) diff --git a/src/meta/ps2_tk5.c b/src/meta/ps2_tk5.c index 631e7f78..bf7efc3a 100644 --- a/src/meta/ps2_tk5.c +++ b/src/meta/ps2_tk5.c @@ -8,7 +8,7 @@ VGMSTREAM * init_vgmstream_ps2_tk5(STREAMFILE *streamFile) { char filename[PATH_LIMIT]; off_t start_offset; int loop_flag = 0; - int channel_count; + int channel_count; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -18,28 +18,28 @@ VGMSTREAM * init_vgmstream_ps2_tk5(STREAMFILE *streamFile) { if (read_32bitBE(0x00,streamFile) != 0x544B3553) goto fail; - loop_flag = (read_32bitLE(0x0C,streamFile)!=0); + loop_flag = (read_32bitLE(0x0C,streamFile)!=0); channel_count = 2; - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - start_offset = 0x800; - vgmstream->channels = channel_count; - vgmstream->sample_rate = 48000; + /* fill in the vital statistics */ + start_offset = 0x800; + vgmstream->channels = channel_count; + vgmstream->sample_rate = 48000; vgmstream->coding_type = coding_PSX_badflags; - vgmstream->num_samples = ((get_streamfile_size(streamFile)-0x800))/16*28/2; + vgmstream->num_samples = ((get_streamfile_size(streamFile)-0x800))/16*28/2; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x10; vgmstream->meta_type = meta_PS2_TK5; - if (vgmstream->loop_flag) - { - vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile)/16*28; - vgmstream->loop_end_sample = vgmstream->loop_start_sample + (read_32bitLE(0x0C,streamFile)/16*28); - } + if (vgmstream->loop_flag) + { + vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile)/16*28; + vgmstream->loop_end_sample = vgmstream->loop_start_sample + (read_32bitLE(0x0C,streamFile)/16*28); + } /* open the file for reading */ { @@ -71,7 +71,7 @@ VGMSTREAM * init_vgmstream_ps2_tk1(STREAMFILE *streamFile) { char filename[PATH_LIMIT]; off_t start_offset; int loop_flag = 0; - int channel_count; + int channel_count; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -81,28 +81,28 @@ VGMSTREAM * init_vgmstream_ps2_tk1(STREAMFILE *streamFile) { if (read_32bitBE(0x00,streamFile) != 0x544B3553) goto fail; - loop_flag = (read_32bitLE(0x0C,streamFile)!=0); + loop_flag = (read_32bitLE(0x0C,streamFile)!=0); channel_count = 2; - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - start_offset = 0x800; - vgmstream->channels = channel_count; - vgmstream->sample_rate = 44100; + /* fill in the vital statistics */ + start_offset = 0x800; + vgmstream->channels = channel_count; + vgmstream->sample_rate = 44100; vgmstream->coding_type = coding_PSX_badflags; - vgmstream->num_samples = read_32bitLE(0x08,streamFile)/16*28; + vgmstream->num_samples = read_32bitLE(0x08,streamFile)/16*28; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x10; vgmstream->meta_type = meta_PS2_TK1; - if (vgmstream->loop_flag) - { - vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile)/16*28; - vgmstream->loop_end_sample = vgmstream->loop_start_sample + (read_32bitLE(0x0C,streamFile)/16*28); - } + if (vgmstream->loop_flag) + { + vgmstream->loop_start_sample = read_32bitLE(0x08,streamFile)/16*28; + vgmstream->loop_end_sample = vgmstream->loop_start_sample + (read_32bitLE(0x0C,streamFile)/16*28); + } /* open the file for reading */ { diff --git a/src/meta/ps2_vag.c b/src/meta/ps2_vag.c index 96f9552d..b983c8e6 100644 --- a/src/meta/ps2_vag.c +++ b/src/meta/ps2_vag.c @@ -79,13 +79,16 @@ VGMSTREAM * init_vgmstream_ps2_vag(STREAMFILE *streamFile) { /* channels are usually at 0x1e, but not in Ukiyo no Roushi which has some kind * of loop-like values instead (who designs this crap?) */ - if (read_32bitBE(0x18,streamFile) != 0 || read_32bitBE(0x1c,streamFile) > 0x20) { - channel_count = 1; - } else { + if (read_32bitBE(0x18,streamFile) == 0 + && (read_32bitBE(0x1c,streamFile) & 0xFFFF00FF) == 0 + && read_8bit(0x1e,streamFile) < 16) { channel_count = read_8bit(0x1e,streamFile); if (channel_count == 0) channel_count = 1; /* ex. early Vita vag (Lumines) */ } + else { + channel_count = 1; + } } else { loop_flag = vag_find_loop_offsets(streamFile, 0x30, &loopStart, &loopEnd); diff --git a/src/meta/ps2_vgs.c b/src/meta/ps2_vgs.c index 8196aa17..ea19558e 100644 --- a/src/meta/ps2_vgs.c +++ b/src/meta/ps2_vgs.c @@ -9,15 +9,15 @@ VGMSTREAM * init_vgmstream_ps2_vgs(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[PATH_LIMIT]; - size_t fileLength; - off_t readOffset = 0; - off_t start_offset; - off_t loop_start_offset = 0; - off_t loop_end_offset = 0; + size_t fileLength; + off_t readOffset = 0; + off_t start_offset; + off_t loop_start_offset = 0; + off_t loop_end_offset = 0; - uint8_t testBuffer[0x10]; - int loop_flag = 0; - int channel_count; + uint8_t testBuffer[0x10]; + int loop_flag = 0; + int channel_count; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -27,71 +27,71 @@ VGMSTREAM * init_vgmstream_ps2_vgs(STREAMFILE *streamFile) { if (read_32bitBE(0x00,streamFile) != 0x56475300) goto fail; - // get file length - fileLength = get_streamfile_size(streamFile); + // get file length + fileLength = get_streamfile_size(streamFile); - // Find loop start - do { - readOffset += (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile); - - // Loop Start ... - if(testBuffer[0x01] == 0x06) - { - loop_start_offset = readOffset - 0x10; - break; - } + // Find loop start + do { + readOffset += (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile); - } while (streamFile->get_offset(streamFile)<((int32_t)fileLength)); + // Loop Start ... + if(testBuffer[0x01] == 0x06) + { + loop_start_offset = readOffset - 0x10; + break; + } - // start at last line of file and move up - readOffset = (int32_t)fileLength - 0x10; - - // Find loop end - do { - readOffset -= (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile); - - // Loop End ... - if((testBuffer[0x01]==0x03) && (testBuffer[0x03]!=0x77)) - { - loop_end_offset = readOffset + 0x20; - break; - } - } while (readOffset > 0); + } while (streamFile->get_offset(streamFile)<((int32_t)fileLength)); - // setup loops - if (loop_start_offset > 0) - { - loop_flag = 1; - - // if we have a start loop, use EOF if end loop is not found - if (loop_end_offset == 0) - { - loop_end_offset = (int32_t)fileLength - 0x10; - } - } - else - { - loop_flag = 0; - } + // start at last line of file and move up + readOffset = (int32_t)fileLength - 0x10; + + // Find loop end + do { + readOffset -= (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile); + + // Loop End ... + if((testBuffer[0x01]==0x03) && (testBuffer[0x03]!=0x77)) + { + loop_end_offset = readOffset + 0x20; + break; + } + } while (readOffset > 0); + + // setup loops + if (loop_start_offset > 0) + { + loop_flag = 1; + + // if we have a start loop, use EOF if end loop is not found + if (loop_end_offset == 0) + { + loop_end_offset = (int32_t)fileLength - 0x10; + } + } + else + { + loop_flag = 0; + } channel_count = 2; - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - start_offset = 0x30; - vgmstream->channels = channel_count; + /* fill in the vital statistics */ + start_offset = 0x30; + vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitBE(0x10,streamFile); vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = ((get_streamfile_size(streamFile)-0x30)/16/channel_count*28); + vgmstream->num_samples = ((get_streamfile_size(streamFile)-0x30)/16/channel_count*28); - if (loop_flag) - { - vgmstream->loop_start_sample = loop_start_offset/16/channel_count*28; - vgmstream->loop_end_sample = loop_end_offset/16/channel_count*28; - } + if (loop_flag) + { + vgmstream->loop_start_sample = loop_start_offset/16/channel_count*28; + vgmstream->loop_end_sample = loop_end_offset/16/channel_count*28; + } vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = read_32bitBE(0x04,streamFile)*0x1000; diff --git a/src/meta/ps2_vms.c b/src/meta/ps2_vms.c index fb11ad7c..274047fa 100644 --- a/src/meta/ps2_vms.c +++ b/src/meta/ps2_vms.c @@ -7,9 +7,9 @@ VGMSTREAM * init_vgmstream_ps2_vms(STREAMFILE *streamFile) { char filename[PATH_LIMIT]; off_t start_offset; - int loop_flag = 0; - int channel_count; - int header_size; + int loop_flag = 0; + int channel_count; + int header_size; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -19,27 +19,27 @@ VGMSTREAM * init_vgmstream_ps2_vms(STREAMFILE *streamFile) { if (read_32bitBE(0x00,streamFile) != 0x564D5320) goto fail; - loop_flag = 1; - channel_count = read_8bit(0x08,streamFile); - header_size = read_32bitLE(0x1C, streamFile); + loop_flag = 1; + channel_count = read_8bit(0x08,streamFile); + header_size = read_32bitLE(0x1C, streamFile); - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - start_offset = header_size; - - vgmstream->channels = channel_count; + /* fill in the vital statistics */ + start_offset = header_size; + + vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitLE(0x14,streamFile); vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = ((get_streamfile_size(streamFile) - header_size)/16/ channel_count * 28); + vgmstream->num_samples = ((get_streamfile_size(streamFile) - header_size)/16/ channel_count * 28); vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = read_32bitLE(0x10,streamFile); - vgmstream->meta_type = meta_PS2_VMS; - vgmstream->loop_start_sample = 0; - vgmstream->loop_end_sample = (get_streamfile_size(streamFile))/16/ channel_count * 28; + vgmstream->meta_type = meta_PS2_VMS; + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = (get_streamfile_size(streamFile))/16/ channel_count * 28; /* open the file for reading */ { diff --git a/src/meta/ps2_vpk.c b/src/meta/ps2_vpk.c index 4fc58fc4..2f1622b3 100644 --- a/src/meta/ps2_vpk.c +++ b/src/meta/ps2_vpk.c @@ -8,7 +8,7 @@ VGMSTREAM * init_vgmstream_ps2_vpk(STREAMFILE *streamFile) { char filename[PATH_LIMIT]; int loop_flag=0; - int channel_count; + int channel_count; off_t start_offset; int i; @@ -20,33 +20,33 @@ VGMSTREAM * init_vgmstream_ps2_vpk(STREAMFILE *streamFile) { if (read_32bitBE(0x00,streamFile) != 0x204B5056) goto fail; - /* check loop */ - loop_flag = (read_32bitLE(0x7FC,streamFile)!=0); + /* check loop */ + loop_flag = (read_32bitLE(0x7FC,streamFile)!=0); channel_count=read_32bitLE(0x14,streamFile); - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - vgmstream->channels = read_32bitLE(0x14,streamFile); + /* fill in the vital statistics */ + vgmstream->channels = read_32bitLE(0x14,streamFile); vgmstream->sample_rate = read_32bitLE(0x10,streamFile); - /* Check for Compression Scheme */ - vgmstream->coding_type = coding_PSX; + /* Check for Compression Scheme */ + vgmstream->coding_type = coding_PSX; vgmstream->num_samples = read_32bitLE(0x04,streamFile)/16*28; - /* Get loop point values */ - if(vgmstream->loop_flag) { - vgmstream->loop_start_sample = read_32bitLE(0x7FC,streamFile); - vgmstream->loop_end_sample = vgmstream->num_samples; - } + /* Get loop point values */ + if(vgmstream->loop_flag) { + vgmstream->loop_start_sample = read_32bitLE(0x7FC,streamFile); + vgmstream->loop_end_sample = vgmstream->num_samples; + } - vgmstream->interleave_block_size = read_32bitLE(0x0C,streamFile)/2; + vgmstream->interleave_block_size = read_32bitLE(0x0C,streamFile)/2; vgmstream->layout_type = layout_interleave; vgmstream->meta_type = meta_PS2_VPK; - start_offset = (off_t)read_32bitLE(0x08,streamFile); + start_offset = (off_t)read_32bitLE(0x08,streamFile); /* open the file for reading by each channel */ { diff --git a/src/meta/ps3_ivag.c b/src/meta/ps3_ivag.c index 0f3fa2c5..1348cced 100644 --- a/src/meta/ps3_ivag.c +++ b/src/meta/ps3_ivag.c @@ -2,19 +2,19 @@ #include "../util.h" /* IVAG - - The Idolm@ster: Gravure For You! Vol. 3 (PS3) + - The Idolm@ster: Gravure For You! Vol. 3 (PS3) - Appears to be two VAGp streams interleaved. + Appears to be two VAGp streams interleaved. */ VGMSTREAM * init_vgmstream_ps3_ivag(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; char filename[PATH_LIMIT]; - off_t start_offset; + off_t start_offset; - int loop_flag = 0; - int channel_count; + int loop_flag = 0; + int channel_count; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -24,34 +24,34 @@ VGMSTREAM * init_vgmstream_ps3_ivag(STREAMFILE *streamFile) if (read_32bitBE(0x00,streamFile) != 0x49564147) // "IVAG" goto fail; - // channel count - channel_count = read_32bitBE(0x08, streamFile); + // channel count + channel_count = read_32bitBE(0x08, streamFile); - // header size - start_offset = 0x40 + (0x40 * channel_count); + // header size + start_offset = 0x40 + (0x40 * channel_count); - // loop flag - if ((read_32bitBE(0x14, streamFile) != 0 || - (read_32bitBE(0x18, streamFile) != 0))) - { - loop_flag = 1; - } + // loop flag + if ((read_32bitBE(0x14, streamFile) != 0 || + (read_32bitBE(0x18, streamFile) != 0))) + { + loop_flag = 1; + } - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - vgmstream->channels = channel_count; + /* fill in the vital statistics */ + vgmstream->channels = channel_count; vgmstream->sample_rate = read_32bitBE(0x0C,streamFile); vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = read_32bitBE(0x10,streamFile); + vgmstream->num_samples = read_32bitBE(0x10,streamFile); - if (loop_flag) - { - vgmstream->loop_start_sample = read_32bitBE(0x14,streamFile); - vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile); - } + if (loop_flag) + { + vgmstream->loop_start_sample = read_32bitBE(0x14,streamFile); + vgmstream->loop_end_sample = read_32bitBE(0x18,streamFile); + } vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = read_32bitBE(0x1C,streamFile); @@ -64,15 +64,15 @@ VGMSTREAM * init_vgmstream_ps3_ivag(STREAMFILE *streamFile) file = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); if (!file) goto fail; - for (i=0;ich[i].streamfile = file; vgmstream->ch[i].channel_start_offset= vgmstream->ch[i].offset=start_offset + (vgmstream->interleave_block_size * i); } - + } return vgmstream; diff --git a/src/meta/ps3_klbs.c b/src/meta/ps3_klbs.c index 0951945b..272c5c53 100644 --- a/src/meta/ps3_klbs.c +++ b/src/meta/ps3_klbs.c @@ -7,15 +7,15 @@ VGMSTREAM * init_vgmstream_ps3_klbs(STREAMFILE *streamFile) VGMSTREAM * vgmstream = NULL; char filename[PATH_LIMIT]; - size_t fileLength; - off_t readOffset = 0; - off_t start_offset; - off_t loop_start_offset = 0; - off_t loop_end_offset = 0; + size_t fileLength; + off_t readOffset = 0; + off_t start_offset; + off_t loop_start_offset = 0; + off_t loop_end_offset = 0; - uint8_t testBuffer[0x10]; - int loop_flag = 0; - int channel_count; + uint8_t testBuffer[0x10]; + int loop_flag = 0; + int channel_count; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -25,77 +25,77 @@ VGMSTREAM * init_vgmstream_ps3_klbs(STREAMFILE *streamFile) if (read_32bitBE(0x20,streamFile) != 0x6B6C4253) goto fail; - // get file length - fileLength = get_streamfile_size(streamFile); + // get file length + fileLength = get_streamfile_size(streamFile); - // Find loop start - start_offset = read_32bitBE(0x10,streamFile); - readOffset = start_offset; + // Find loop start + start_offset = read_32bitBE(0x10,streamFile); + readOffset = start_offset; - do { - readOffset += (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile); - - // Loop Start ... - if(testBuffer[0x01] == 0x06) - { - loop_start_offset = readOffset - 0x10; - break; - } + do { + readOffset += (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile); - } while (streamFile->get_offset(streamFile)<((int32_t)fileLength)); + // Loop Start ... + if(testBuffer[0x01] == 0x06) + { + loop_start_offset = readOffset - 0x10; + break; + } - // start at last line of file and move up - readOffset = (int32_t)fileLength - 0x10; - - // Find loop end - do { - readOffset -= (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile); - - // Loop End ... - if((testBuffer[0x01]==0x03) && (testBuffer[0x03]!=0x77)) - { - loop_end_offset = readOffset + 0x20; - break; - } - } while (readOffset > 0); + } while (streamFile->get_offset(streamFile)<((int32_t)fileLength)); - // setup loops - if (loop_start_offset > 0) - { - loop_flag = 1; - - // if we have a start loop, use EOF if end loop is not found - if (loop_end_offset == 0) - { - loop_end_offset = (int32_t)fileLength - 0x10; - } - } - else - { - loop_flag = 0; - } + // start at last line of file and move up + readOffset = (int32_t)fileLength - 0x10; + + // Find loop end + do { + readOffset -= (off_t)read_streamfile(testBuffer, readOffset, 0x10, streamFile); + + // Loop End ... + if((testBuffer[0x01]==0x03) && (testBuffer[0x03]!=0x77)) + { + loop_end_offset = readOffset + 0x20; + break; + } + } while (readOffset > 0); + + // setup loops + if (loop_start_offset > 0) + { + loop_flag = 1; + + // if we have a start loop, use EOF if end loop is not found + if (loop_end_offset == 0) + { + loop_end_offset = (int32_t)fileLength - 0x10; + } + } + else + { + loop_flag = 0; + } channel_count = 2; - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ + /* fill in the vital statistics */ vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = read_32bitBE(0x90, streamFile); vgmstream->meta_type = meta_PS3_KLBS; - vgmstream->channels = channel_count; + vgmstream->channels = channel_count; vgmstream->sample_rate = 48000; vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = ((vgmstream->interleave_block_size * channel_count)/16/channel_count*28); + vgmstream->num_samples = ((vgmstream->interleave_block_size * channel_count)/16/channel_count*28); - if (loop_flag) - { - vgmstream->loop_start_sample = loop_start_offset/16/channel_count*28; - vgmstream->loop_end_sample = loop_end_offset/16/channel_count*28; - } + if (loop_flag) + { + vgmstream->loop_start_sample = loop_start_offset/16/channel_count*28; + vgmstream->loop_end_sample = loop_end_offset/16/channel_count*28; + } /* open the file for reading */ { diff --git a/src/meta/psx_fag.c b/src/meta/psx_fag.c index d58a8c6b..e4934429 100644 --- a/src/meta/psx_fag.c +++ b/src/meta/psx_fag.c @@ -7,7 +7,7 @@ VGMSTREAM * init_vgmstream_psx_fag(STREAMFILE *streamFile) { char filename[PATH_LIMIT]; off_t start_offset; int loop_flag = 0; - int channel_count; + int channel_count; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -15,27 +15,27 @@ VGMSTREAM * init_vgmstream_psx_fag(STREAMFILE *streamFile) { /* check header */ - /* Look if there's more than 1 one file... */ + /* Look if there's more than 1 one file... */ if (read_32bitBE(0x00,streamFile) != 0x01000000) goto fail; - loop_flag = 0; + loop_flag = 0; channel_count = 2; - /* build the VGMSTREAM */ + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - start_offset = read_32bitLE(0x04,streamFile); - vgmstream->channels = channel_count; + /* fill in the vital statistics */ + start_offset = read_32bitLE(0x04,streamFile); + vgmstream->channels = channel_count; vgmstream->sample_rate = 24000; vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = (read_32bitLE(0x08,streamFile))/channel_count/32*28; + vgmstream->num_samples = (read_32bitLE(0x08,streamFile))/channel_count/32*28; if (loop_flag) { vgmstream->loop_start_sample = 0; vgmstream->loop_end_sample = (read_32bitLE(0x08,streamFile))/channel_count/32*28; - } + } vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x8000; diff --git a/src/meta/ss_stream.c b/src/meta/ss_stream.c deleted file mode 100644 index 5c29495d..00000000 --- a/src/meta/ss_stream.c +++ /dev/null @@ -1,203 +0,0 @@ -#include "meta.h" -#include "../util.h" - -/* SS_STREAM - - SS_STREAM is format used by various UBI Soft Games - - 2008-11-15 - Fastelbja : First version ... - - - Some infos, sorry for messing up the meta (regards, manako) - -Splinter Cell - *.SS0; PC (except Music_*.SS0) -Splinter Cell: Pandora Tomorrow - *.SS0, *.LS0; PC -Splinter Cell: Chaos Theory - *.SS0, *.LS0; PC -Splinter Cell: Double Agent - *.SS0, *.LS0; PC - -UbiSoft Old Simple Stream (version 3) -UbiSoft Simple Stream (version 5) -UbiSoft Old Interleaved Stream (version 2) -UbiSoft Interleaved Stream (version 8 ) - -Note: if the version number is 3, then all values in this file are big-endian. If the version is 5, then all values are little-endian. - -Header: -byte {1} - Version number (3 or 5) -byte {3} - Unknown -byte {4} - Unknown -uint32 {4} - Unknown -uint16 {2} - Unknown -uint16 {2} - Number of extra uncompressed samples before the data (always 10) -int16 {2} - First left sample for decompression -byte {1} - First left index for decompression -byte {1} - Unknown -int16 {2} - First right sample for decompression -byte {1} - First right index for decompression -byte {1} - Unknown -byte {4} - Unknown - -Extra Uncompressed Samples: -if the sound is mono: -int16 {Number of extra uncompressed samples * 2} - Uncompressed samples - -if the sound is stereo: -int16 {Number of extra uncompressed samples * 4} - Uncompressed samples - -Data: -byte {?} - Compressed data - - - -And here is the format of the old interleaved streams: - -Code: -Little-endian - -uint32 {4} - Signature (2) -uint32 {4} - Number of Layers (always 3) -uint32 {4} - Total File Size -uint32 {4} - Unknown (always 20) -uint32 {4} - Unknown (always 1104) -uint32 {4} - Average Block Size (always 361) - -For Each Block: { - uint32 {4} - Block Index (begins at 1) - uint32 {4} - Unknown (always 20) - - For Each Layer (Chunk): { - uint32 {4} - Layer Chunk Size - } - - For Each Layer (Chunk): { - uint32 {Layer Chunk Size} - Chunk of an Encapsulated UbiSoft Old Simple Stream - } -} - - -And the new interleaved streams: - -Code: -Little-endian - -uint16 {2} - Signature (8) -uint16 {2} - Unknown -uint32 {4} - Unknown -uint32 {4} - Number of Layers -uint32 {4} - Number of Blocks -uint32 {4} - Number of Bytes after This to the Headers -uint32 {4} - The Sum of (Number of Layers * 4) Plus the Header Lengths -uint32 {4} - Average Sum of Chunk Data Lengths - -For Each Layer: { - uint32 {4} - Layer Header Size -} - -For Each Layer: { - uint32 {Layer Header Size} - Header of an Encapsulated Stream (PCM, UbiSoft Simple Stream, Ogg Vorbis) -} - -For Each Block: { - uint32 {4} - Signature (3) - uint32 {4} - Number of bytes from the start of this block to the next block, 0 if no more blocks - - For Each Layer (Chunk): { - uint32 {4} - Layer Chunk Size - } - - For Each Layer (Chunk): { - uint32 {Layer Chunk Size} - Chunk of an Encapsulated Stream (PCM, UbiSoft Simple Stream, Ogg Vorbis) - } -} - - -*/ - -VGMSTREAM * init_vgmstream_ss_stream(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; - int loop_flag=0; - int channels; - int channel_count; - off_t start_offset; - int i; - - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("ss3",filename_extension(filename)) && - strcasecmp("ss7",filename_extension(filename))) goto fail; - - loop_flag = 0; - //freq_flag = read_8bit(0x08,streamFile); - - if (read_8bit(0x0C,streamFile) == 0) { - channels = 1; - } else { - channels = read_8bit(0x0C,streamFile)*2; - } - - channel_count = channels; - - - /* 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 = 48000; - - -#if 0 - if (!strcasecmp("ss3",filename_extension(filename))) { - vgmstream->sample_rate = 32000; - } else if (!strcasecmp("ss7",filename_extension(filename))) { - vgmstream->sample_rate = 48000; - } -#endif - - start_offset = (read_8bit(0x07,streamFile)+5); - -#if 0 - if (channel_count == 1){ - start_offset = 0x3C; - } else if (channel_count == 2) { - start_offset = 0x44; - } -#endif - - if(channel_count==1) - vgmstream->coding_type = coding_IMA; - else - vgmstream->coding_type = coding_EACS_IMA; - - vgmstream->num_samples = (int32_t)((get_streamfile_size(streamFile)-start_offset)* 2 / vgmstream->channels); - vgmstream->layout_type = layout_none; - - vgmstream->meta_type = meta_XBOX_WAVM; - vgmstream->get_high_nibble=0; - - /* open the file for reading by each channel */ - { - for (i=0;ich[i].offset = start_offset; - } else if (channel_count == 2) { - vgmstream->ch[i].offset = start_offset; - } - - vgmstream->ch[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - vgmstream->ch[i].adpcm_history1_32=(int32_t)read_16bitLE(0x10+i*4,streamFile); - vgmstream->ch[i].adpcm_step_index =(int)read_8bit(0x12+i*4,streamFile); - if (!vgmstream->ch[i].streamfile) goto fail; - } - } - - return vgmstream; - - /* clean up anything we may have opened */ -fail: - if (vgmstream) close_vgmstream(vgmstream); - return NULL; -} diff --git a/src/meta/ta_aac.c b/src/meta/ta_aac.c index 6d4958bc..136ef057 100644 --- a/src/meta/ta_aac.c +++ b/src/meta/ta_aac.c @@ -8,93 +8,93 @@ VGMSTREAM * init_vgmstream_ta_aac_x360(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; off_t start_offset; int loop_flag, channel_count; - size_t sampleRate, numSamples, startSample, dataSize, blockSize, blockCount; // A mess + size_t sampleRate, numSamples, startSample, dataSize, blockSize, blockCount; // A mess /* check extension, case insensitive */ - /* .aac: expected, .laac/ace: for players to avoid hijacking MP4/AAC */ + /* .aac: expected, .laac/ace: for players to avoid hijacking MP4/AAC */ if ( !check_extensions(streamFile,"aac,laac,ace")) goto fail; if (read_32bitBE(0x00,streamFile) != 0x41414320) /* "AAC " */ goto fail; - /* Ok, let's check what's behind door number 1 */ - if (read_32bitBE(0x1000, streamFile) == 0x41534320) /* "ASC " */ - { - loop_flag = read_32bitBE(0x1118, streamFile); + /* Ok, let's check what's behind door number 1 */ + if (read_32bitBE(0x1000, streamFile) == 0x41534320) /* "ASC " */ + { + loop_flag = read_32bitBE(0x1118, streamFile); - /*Funky Channel Count Checking */ - if (read_32bitBE(0x1184, streamFile) == 0x7374726D) - channel_count = 6; - else if (read_32bitBE(0x1154, streamFile) == 0x7374726D) - channel_count = 4; - else - channel_count = read_8bit(0x1134, streamFile); + /*Funky Channel Count Checking */ + if (read_32bitBE(0x1184, streamFile) == 0x7374726D) + channel_count = 6; + else if (read_32bitBE(0x1154, streamFile) == 0x7374726D) + channel_count = 4; + else + channel_count = read_8bit(0x1134, streamFile); - sampleRate = read_32bitBE(0x10F4, streamFile); - numSamples = read_32bitBE(0x10FC, streamFile); - startSample = read_32bitBE(0x10F8, streamFile); - dataSize = read_32bitBE(0x10F0, streamFile); - blockSize = read_32bitBE(0x1100, streamFile); - blockCount = read_32bitBE(0x110C, streamFile); - } - else if (read_32bitBE(0x1000, streamFile) == 0x57415645) /* "WAVE" */ - { - loop_flag = read_32bitBE(0x1048, streamFile); + sampleRate = read_32bitBE(0x10F4, streamFile); + numSamples = read_32bitBE(0x10FC, streamFile); + startSample = read_32bitBE(0x10F8, streamFile); + dataSize = read_32bitBE(0x10F0, streamFile); + blockSize = read_32bitBE(0x1100, streamFile); + blockCount = read_32bitBE(0x110C, streamFile); + } + else if (read_32bitBE(0x1000, streamFile) == 0x57415645) /* "WAVE" */ + { + loop_flag = read_32bitBE(0x1048, streamFile); - /*Funky Channel Count Checking */ - if (read_32bitBE(0x10B0, streamFile) == 0x7374726D) - channel_count = 6; - else if (read_32bitBE(0x1080, streamFile) == 0x7374726D) - channel_count = 4; - else - channel_count = read_8bit(0x1060, streamFile); + /*Funky Channel Count Checking */ + if (read_32bitBE(0x10B0, streamFile) == 0x7374726D) + channel_count = 6; + else if (read_32bitBE(0x1080, streamFile) == 0x7374726D) + channel_count = 4; + else + channel_count = read_8bit(0x1060, streamFile); - sampleRate = read_32bitBE(0x1024, streamFile); - numSamples = read_32bitBE(0x102C, streamFile); - startSample = read_32bitBE(0x1028, streamFile); - dataSize = read_32bitBE(0x1020, streamFile); - blockSize = read_32bitBE(0x1030, streamFile); - blockCount = read_32bitBE(0x103C, streamFile); - } - else if (read_32bitBE(0x1000, streamFile) == 0x00000000) /* some like to be special */ - { - loop_flag = read_32bitBE(0x6048, streamFile); + sampleRate = read_32bitBE(0x1024, streamFile); + numSamples = read_32bitBE(0x102C, streamFile); + startSample = read_32bitBE(0x1028, streamFile); + dataSize = read_32bitBE(0x1020, streamFile); + blockSize = read_32bitBE(0x1030, streamFile); + blockCount = read_32bitBE(0x103C, streamFile); + } + else if (read_32bitBE(0x1000, streamFile) == 0x00000000) /* some like to be special */ + { + loop_flag = read_32bitBE(0x6048, streamFile); - /*Funky Channel Count Checking */ - if (read_32bitBE(0x60B0, streamFile) == 0x7374726D) - channel_count = 6; - else if (read_32bitBE(0x6080, streamFile) == 0x7374726D) - channel_count = 4; - else - channel_count = read_8bit(0x6060, streamFile); + /*Funky Channel Count Checking */ + if (read_32bitBE(0x60B0, streamFile) == 0x7374726D) + channel_count = 6; + else if (read_32bitBE(0x6080, streamFile) == 0x7374726D) + channel_count = 4; + else + channel_count = read_8bit(0x6060, streamFile); - sampleRate = read_32bitBE(0x6024, streamFile); - numSamples = read_32bitBE(0x602C, streamFile); - startSample = read_32bitBE(0x6028, streamFile); - dataSize = read_32bitBE(0x6020, streamFile); - blockSize = read_32bitBE(0x6030, streamFile); - blockCount = read_32bitBE(0x603C, streamFile); - } - else - goto fail; //cuz I don't know if there are other variants + sampleRate = read_32bitBE(0x6024, streamFile); + numSamples = read_32bitBE(0x602C, streamFile); + startSample = read_32bitBE(0x6028, streamFile); + dataSize = read_32bitBE(0x6020, streamFile); + blockSize = read_32bitBE(0x6030, streamFile); + blockCount = read_32bitBE(0x603C, streamFile); + } + else + goto fail; //cuz I don't know if there are other variants /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); if (!vgmstream) goto fail; - if (read_32bitBE(0x1000, streamFile) == 0x00000000) - start_offset = 0x7000; - else - start_offset = 0x2000; + if (read_32bitBE(0x1000, streamFile) == 0x00000000) + start_offset = 0x7000; + else + start_offset = 0x2000; vgmstream->sample_rate = sampleRate; vgmstream->channels = channel_count; vgmstream->num_samples = numSamples; - if (loop_flag) { - vgmstream->loop_start_sample = startSample; - vgmstream->loop_end_sample = vgmstream->num_samples; - } + if (loop_flag) { + vgmstream->loop_start_sample = startSample; + vgmstream->loop_end_sample = vgmstream->num_samples; + } vgmstream->meta_type = meta_TA_AAC_X360; #ifdef VGM_USE_FFMPEG @@ -103,9 +103,9 @@ VGMSTREAM * init_vgmstream_ta_aac_x360(STREAMFILE *streamFile) { uint8_t buf[100]; size_t bytes, datasize, block_size, block_count; - block_count = blockCount; - block_size = blockSize; - datasize = dataSize; + block_count = blockCount; + block_size = blockSize; + datasize = dataSize; bytes = ffmpeg_make_riff_xma2(buf,100, vgmstream->num_samples, datasize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size); if (bytes <= 0) goto fail; @@ -132,79 +132,79 @@ fail: /* PlayStation 3 Variants (Star Ocean International, Resonance of Fate) */ VGMSTREAM * init_vgmstream_ta_aac_ps3(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; - off_t start_offset; - int loop_flag, channel_count; - uint32_t data_size, loop_start, loop_end, codec_id; + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + int loop_flag, channel_count; + uint32_t data_size, loop_start, loop_end, codec_id; - /* check extension, case insensitive */ - /* .aac: expected, .laac/ace: for players to avoid hijacking MP4/AAC */ - if (!check_extensions(streamFile, "aac,laac,ace")) - goto fail; + /* check extension, case insensitive */ + /* .aac: expected, .laac/ace: for players to avoid hijacking MP4/AAC */ + if (!check_extensions(streamFile, "aac,laac,ace")) + goto fail; - if (read_32bitBE(0x00, streamFile) != 0x41414320) /* "AAC " */ - goto fail; + if (read_32bitBE(0x00, streamFile) != 0x41414320) /* "AAC " */ + goto fail; - /* Haven't Found a codec flag yet. Let's just use this for now */ - if (read_32bitBE(0x10000, streamFile) != 0x41534320) /* "ASC " */ - goto fail; + /* Haven't Found a codec flag yet. Let's just use this for now */ + if (read_32bitBE(0x10000, streamFile) != 0x41534320) /* "ASC " */ + goto fail; - if (read_32bitBE(0x10104, streamFile) != 0xFFFFFFFF) - loop_flag = 1; - else - loop_flag = 0; + if (read_32bitBE(0x10104, streamFile) != 0xFFFFFFFF) + loop_flag = 1; + else + loop_flag = 0; - channel_count = read_32bitBE(0x100F4, streamFile); - codec_id = read_32bitBE(0x100F0, streamFile); + channel_count = read_32bitBE(0x100F4, streamFile); + codec_id = read_32bitBE(0x100F0, streamFile); - /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count, loop_flag); - if (!vgmstream) goto fail; + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count, loop_flag); + if (!vgmstream) goto fail; - /* Useless header, let's play the guessing game */ - start_offset = 0x10110; - vgmstream->sample_rate = read_32bitBE(0x100FC, streamFile); - vgmstream->channels = channel_count; - vgmstream->meta_type = meta_TA_AAC_PS3; - data_size = read_32bitBE(0x100F8, streamFile); - loop_start = read_32bitBE(0x10104, streamFile); - loop_end = read_32bitBE(0x10108, streamFile); + /* Useless header, let's play the guessing game */ + start_offset = 0x10110; + vgmstream->sample_rate = read_32bitBE(0x100FC, streamFile); + vgmstream->channels = channel_count; + vgmstream->meta_type = meta_TA_AAC_PS3; + data_size = read_32bitBE(0x100F8, streamFile); + loop_start = read_32bitBE(0x10104, streamFile); + loop_end = read_32bitBE(0x10108, streamFile); #ifdef VGM_USE_FFMPEG - { - ffmpeg_codec_data *ffmpeg_data = NULL; - uint8_t buf[100]; - int32_t bytes, samples_size = 1024, block_size, encoder_delay, joint_stereo, max_samples; - block_size = (codec_id == 4 ? 0x60 : (codec_id == 5 ? 0x98 : 0xC0)) * vgmstream->channels; - max_samples = (data_size / block_size) * samples_size; - encoder_delay = 0x0; - joint_stereo = 0; + { + ffmpeg_codec_data *ffmpeg_data = NULL; + uint8_t buf[100]; + int32_t bytes, samples_size = 1024, block_size, encoder_delay, joint_stereo, max_samples; + block_size = (codec_id == 4 ? 0x60 : (codec_id == 5 ? 0x98 : 0xC0)) * vgmstream->channels; + max_samples = (data_size / block_size) * samples_size; + encoder_delay = 0x0; + joint_stereo = 0; /* make a fake riff so FFmpeg can parse the ATRAC3 */ - bytes = ffmpeg_make_riff_atrac3(buf, 100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, encoder_delay); - if (bytes <= 0) goto fail; + bytes = ffmpeg_make_riff_atrac3(buf, 100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, encoder_delay); + if (bytes <= 0) goto fail; - ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf, bytes, start_offset, data_size); - if (!ffmpeg_data) goto fail; - vgmstream->codec_data = ffmpeg_data; - vgmstream->coding_type = coding_FFmpeg; - vgmstream->layout_type = layout_none; - vgmstream->num_samples = max_samples; + ffmpeg_data = init_ffmpeg_header_offset(streamFile, buf, bytes, start_offset, data_size); + if (!ffmpeg_data) goto fail; + vgmstream->codec_data = ffmpeg_data; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + vgmstream->num_samples = max_samples; - if (loop_flag) { - vgmstream->loop_start_sample = (loop_start / block_size) * samples_size; - vgmstream->loop_end_sample = (loop_end / block_size) * samples_size; - } + if (loop_flag) { + vgmstream->loop_start_sample = (loop_start / block_size) * samples_size; + vgmstream->loop_end_sample = (loop_end / block_size) * samples_size; + } - } + } #endif - /* open the file for reading */ - if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) - goto fail; - return vgmstream; + /* open the file for reading */ + if (!vgmstream_open_stream(vgmstream, streamFile, start_offset)) + goto fail; + return vgmstream; fail: - close_vgmstream(vgmstream); - return NULL; + close_vgmstream(vgmstream); + return NULL; } diff --git a/src/meta/thp.c b/src/meta/thp.c index b4b9d240..53e10979 100644 --- a/src/meta/thp.c +++ b/src/meta/thp.c @@ -7,74 +7,74 @@ VGMSTREAM * init_vgmstream_thp(STREAMFILE *streamFile) { - VGMSTREAM * vgmstream = NULL; + VGMSTREAM * vgmstream = NULL; + + char filename[PATH_LIMIT]; + off_t start_offset; - char filename[PATH_LIMIT]; - off_t start_offset; - - uint32_t maxAudioSize=0; + uint32_t maxAudioSize=0; - uint32_t numComponents; - off_t componentTypeOffset; - off_t componentDataOffset; - - char thpVersion; + uint32_t numComponents; + off_t componentTypeOffset; + off_t componentDataOffset; - int loop_flag; - int channel_count=-1; - int i; + char thpVersion; + + int loop_flag; + int channel_count=-1; + int i; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); if (strcasecmp("thp",filename_extension(filename)) && - strcasecmp("dsp",filename_extension(filename))) goto fail; + strcasecmp("dsp",filename_extension(filename))) goto fail; /* check header */ if (read_32bitBE(0x00,streamFile) != 0x54485000) goto fail; - maxAudioSize = read_32bitBE(0x0C,streamFile); - thpVersion = read_8bit(0x06,streamFile); + maxAudioSize = read_32bitBE(0x0C,streamFile); + thpVersion = read_8bit(0x06,streamFile); - if(maxAudioSize==0) // no sound - goto fail; + if(maxAudioSize==0) // no sound + goto fail; loop_flag = 0; // allways unloop - /* fill in the vital statistics */ - if(thpVersion==0x10) { - start_offset = read_32bitBE(0x24,streamFile); - /* No idea what's up with this */ - if (start_offset == 0) - start_offset = read_32bitBE(0x28,streamFile); - } else - start_offset = read_32bitBE(0x28,streamFile); + /* fill in the vital statistics */ + if(thpVersion==0x10) { + start_offset = read_32bitBE(0x24,streamFile); + /* No idea what's up with this */ + if (start_offset == 0) + start_offset = read_32bitBE(0x28,streamFile); + } else + start_offset = read_32bitBE(0x28,streamFile); - // Get info from the first block - componentTypeOffset = read_32bitBE(0x20,streamFile); - numComponents = read_32bitBE(componentTypeOffset ,streamFile); - componentDataOffset=componentTypeOffset+0x14; - componentTypeOffset+=4; + // Get info from the first block + componentTypeOffset = read_32bitBE(0x20,streamFile); + numComponents = read_32bitBE(componentTypeOffset ,streamFile); + componentDataOffset=componentTypeOffset+0x14; + componentTypeOffset+=4; - for(i=0;ichannels=channel_count; - vgmstream->sample_rate=read_32bitBE(componentDataOffset+4,streamFile); - vgmstream->num_samples=read_32bitBE(componentDataOffset+8,streamFile); - break; - } else { - if(thpVersion==0x10) - componentDataOffset+=0x0c; - else - componentDataOffset+=0x08; - } - } + vgmstream->channels=channel_count; + vgmstream->sample_rate=read_32bitBE(componentDataOffset+4,streamFile); + vgmstream->num_samples=read_32bitBE(componentDataOffset+8,streamFile); + break; + } else { + if(thpVersion==0x10) + componentDataOffset+=0x0c; + else + componentDataOffset+=0x08; + } + } /* open the file for reading */ { @@ -87,10 +87,10 @@ VGMSTREAM * init_vgmstream_thp(STREAMFILE *streamFile) { } } - vgmstream->thpNextFrameSize=read_32bitBE(0x18,streamFile); - thp_block_update(start_offset,vgmstream); + vgmstream->thpNextFrameSize=read_32bitBE(0x18,streamFile); + thp_block_update(start_offset,vgmstream); - vgmstream->coding_type = coding_NGC_DSP; + vgmstream->coding_type = coding_NGC_DSP; vgmstream->layout_type = layout_thp_blocked; vgmstream->meta_type = meta_THP; diff --git a/src/meta/tun.c b/src/meta/tun.c index 533ed0af..8402c1ec 100644 --- a/src/meta/tun.c +++ b/src/meta/tun.c @@ -7,7 +7,7 @@ VGMSTREAM * init_vgmstream_tun(STREAMFILE *streamFile) { char filename[PATH_LIMIT]; off_t start_offset; int channel_count; - int loop_flag; + int loop_flag; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -17,8 +17,8 @@ VGMSTREAM * init_vgmstream_tun(STREAMFILE *streamFile) { if (read_32bitBE(0x00,streamFile) != 0x414C5020) /* "ALP " */ goto fail; - channel_count = 2; - loop_flag = 0; + channel_count = 2; + loop_flag = 0; /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); diff --git a/src/meta/txth.c b/src/meta/txth.c index 1432ca9b..1e7850a8 100644 --- a/src/meta/txth.c +++ b/src/meta/txth.c @@ -30,11 +30,12 @@ typedef enum { XMA1 = 20, /* raw XMA1 */ XMA2 = 21, /* raw XMA2 */ FFMPEG = 22, /* any headered FFmpeg format */ + AC3 = 23, /* AC3/SPDIF */ } txth_type; typedef struct { txth_type codec; - txth_type codec_mode; + uint32_t codec_mode; uint32_t interleave; uint32_t id_value; @@ -60,11 +61,12 @@ typedef struct { uint32_t coef_offset; uint32_t coef_spacing; - uint32_t coef_mode; uint32_t coef_big_endian; + uint32_t coef_mode; } txth_header; +static STREAMFILE * open_txth(STREAMFILE * streamFile); static int parse_txth(STREAMFILE * streamFile, STREAMFILE * streamText, txth_header * txth); static int parse_keyval(STREAMFILE * streamFile, STREAMFILE * streamText, txth_header * txth, const char * key, const char * val); static int parse_num(STREAMFILE * streamFile, const char * val, uint32_t * out_value); @@ -76,44 +78,16 @@ static int get_bytes_to_samples(txth_header * txth, uint32_t bytes); VGMSTREAM * init_vgmstream_txth(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; STREAMFILE * streamText = NULL; - txth_header txth; + txth_header txth = {0}; coding_t coding; int i, j; /* no need for ID or ext checks -- if a .TXTH exists all is good * (player still needs to accept the ext, so at worst rename to .vgmstream) */ - { - char filename[PATH_LIMIT]; - char fileext[PATH_LIMIT]; - - /* try "(path/)(name.ext).txth" */ - if (!get_streamfile_name(streamFile,filename,PATH_LIMIT)) goto fail; - strcat(filename, ".txth"); - streamText = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (streamText) goto found; - - /* try "(path/)(.ext).txth" */ - if (!get_streamfile_path(streamFile,filename,PATH_LIMIT)) goto fail; - if (!get_streamfile_ext(streamFile,fileext,PATH_LIMIT)) goto fail; - strcat(filename,"."); - strcat(filename, fileext); - strcat(filename, ".txth"); - streamText = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (streamText) goto found; - - /* try "(path/).txth" */ - if (!get_streamfile_path(streamFile,filename,PATH_LIMIT)) goto fail; - strcat(filename, ".txth"); - streamText = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); - if (streamText) goto found; - - /* not found */ - goto fail; - } -found: + streamText = open_txth(streamFile); + if (!streamText) goto fail; /* process the text file */ - memset(&txth,0,sizeof(txth_header)); if (!parse_txth(streamFile, streamText, &txth)) goto fail; @@ -145,6 +119,7 @@ found: case ATRAC3PLUS: case XMA1: case XMA2: + case AC3: case FFMPEG: coding = coding_FFmpeg; break; #endif default: @@ -261,7 +236,8 @@ found: for (j=0;j<16;j++) { vgmstream->ch[i].adpcm_coef[j] = read_16bit(txth.coef_offset + i*txth.coef_spacing + j*2,streamFile); } - } else { + } + else { goto fail; //IDK what is this /* for (j=0;j<8;j++) { @@ -285,7 +261,7 @@ found: case coding_FFmpeg: { ffmpeg_codec_data *ffmpeg_data = NULL; - if (txth.codec == FFMPEG) { + if (txth.codec == FFMPEG || txth.codec == AC3) { /* default FFmpeg */ ffmpeg_data = init_ffmpeg_offset(streamFile, txth.start_offset,txth.data_size); if ( !ffmpeg_data ) goto fail; @@ -390,6 +366,38 @@ fail: return NULL; } + +static STREAMFILE * open_txth(STREAMFILE * streamFile) { + char filename[PATH_LIMIT]; + char fileext[PATH_LIMIT]; + STREAMFILE * streamText; + + /* try "(path/)(name.ext).txth" */ + if (!get_streamfile_name(streamFile,filename,PATH_LIMIT)) goto fail; + strcat(filename, ".txth"); + streamText = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (streamText) return streamText; + + /* try "(path/)(.ext).txth" */ + if (!get_streamfile_path(streamFile,filename,PATH_LIMIT)) goto fail; + if (!get_streamfile_ext(streamFile,fileext,PATH_LIMIT)) goto fail; + strcat(filename,"."); + strcat(filename, fileext); + strcat(filename, ".txth"); + streamText = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (streamText) return streamText; + + /* try "(path/).txth" */ + if (!get_streamfile_path(streamFile,filename,PATH_LIMIT)) goto fail; + strcat(filename, ".txth"); + streamText = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + if (streamText) return streamText; + +fail: + /* not found */ + return 0; +} + /* Simple text parser of "key = value" lines. * The code is meh and error handling not exactly the best. */ static int parse_txth(STREAMFILE * streamFile, STREAMFILE * streamText, txth_header * txth) { @@ -472,6 +480,7 @@ static int parse_keyval(STREAMFILE * streamFile, STREAMFILE * streamText, txth_h else if (0==strcmp(val,"XMA1")) txth->codec = XMA1; else if (0==strcmp(val,"XMA2")) txth->codec = XMA2; else if (0==strcmp(val,"FFMPEG")) txth->codec = FFMPEG; + else if (0==strcmp(val,"AC3")) txth->codec = AC3; else goto fail; } else if (0==strcmp(key,"codec_mode")) { @@ -663,6 +672,10 @@ static int get_bytes_to_samples(txth_header * txth, uint32_t bytes) { case XMA2: return bytes; /* preserve */ + case AC3: + if (!txth->interleave) return 0; + return bytes / txth->interleave * 256 * txth->channels; + /* untested */ case IMA: case DVI_IMA: diff --git a/src/meta/ubi_sb.c b/src/meta/ubi_sb.c index c06ffc28..68943b87 100644 --- a/src/meta/ubi_sb.c +++ b/src/meta/ubi_sb.c @@ -34,6 +34,8 @@ typedef struct { size_t stream_id_offset; int has_short_channels; int has_internal_names; + int has_extra_name_flag; + int has_rotating_ids; /* derived */ size_t main_size; @@ -73,8 +75,6 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) { /* check extension (number represents the platform, see later) */ if ( !check_extensions(streamFile,"sb0,sb1,sb2,sb3,sb4,sb5,sb6,sb7") ) goto fail; - //memset(&sb,0,sizeof(ubi_sb_header)); //todo test for VC2010's init = {0} above (should be C89 but...) - if (sb.flag1 != 0 || sb.codec!=0 || sb.stream_samples != 0) { VGM_LOG("UBI SB: not init ok\n"); goto fail; } /* .sb0 (sound bank) is a small multisong format (loaded in memory?) that contains SFX data @@ -119,7 +119,7 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) { start_offset = sb.main_size + sb.section1_size + sb.section2_size + sb.extra_size + sb.section3_size; start_offset += sb.stream_offset; } - ;VGM_LOG("so=%lx, main=%x, s1=%x, s2=%x, ex=%x, s3=%x, so=%lx\n", start_offset, sb.main_size, sb.section1_size, sb.section2_size, sb.extra_size, sb.section3_size, sb.stream_offset); + /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(sb.channels,loop_flag); @@ -131,7 +131,7 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) { switch(sb.codec) { - case UBI_ADPCM: { //todo move to its own decoder + case UBI_ADPCM: { vgmstream->coding_type = coding_UBI_IMA; vgmstream->layout_type = layout_none; vgmstream->num_samples = ubi_ima_bytes_to_samples(sb.stream_size, sb.channels, streamData, start_offset); @@ -139,11 +139,10 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) { } case RAW_PCM: - vgmstream->coding_type = coding_PCM16LE; + vgmstream->coding_type = coding_PCM16LE; /* always LE even on Wii */ vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = 0x02; vgmstream->num_samples = pcm_bytes_to_samples(sb.stream_size, sb.channels, 16); - if (sb.channels > 1) { VGM_LOG("UBI SB: >1 channel\n"); goto fail; } //todo break; case RAW_PSX: @@ -183,7 +182,8 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) { vgmstream->coding_type = coding_PSX; vgmstream->layout_type = layout_interleave; vgmstream->interleave_block_size = sb.stream_size / sb.channels; - vgmstream->num_samples = ps_bytes_to_samples(sb.stream_size, sb.channels) ; + vgmstream->num_samples = ps_bytes_to_samples(sb.stream_size, sb.channels); + if (sb.channels > 1) { VGM_LOG("UBI SB: >1 channel\n"); goto fail; } //todo break; @@ -264,7 +264,7 @@ fail: static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) { int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL; int16_t (*read_16bit)(off_t,STREAMFILE*) = NULL; - int i, ok; + int i, ok, current_type = -1, current_id = -1; int target_stream = streamFile->stream_index; if (target_stream == 0) target_stream = 1; @@ -284,7 +284,7 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) { sb->section1_num = read_32bit(0x04, streamFile); /* group headers? */ sb->section2_num = read_32bit(0x08, streamFile); /* streams headers (internal or external) */ sb->section3_num = read_32bit(0x0c, streamFile); /* internal streams table */ - sb->extra_size = read_32bit(0x10, streamFile); /* extra table, unknown except with DSP = coefs */ + sb->extra_size = read_32bit(0x10, streamFile); /* extra table, unknown (config for non-audio types) except with DSP = coefs */ sb->flag1 = read_32bit(0x14, streamFile); /* unknown, usually -1 but can be others (0/1/2/etc) */ sb->flag2 = read_32bit(0x18, streamFile); /* unknown, usually -1 but can be others */ @@ -307,11 +307,39 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) { if (read_32bit(offset + 0x04, streamFile) != 0x01) continue; + /* weird case when there is no internal substream ID and just seem to rotate every time type changes, joy */ + if (sb->has_rotating_ids) { /* assumes certain configs can't happen in this case */ + int current_is_external = 0; + int type = read_32bit(offset + sb->stream_type_offset, streamFile); + + if (current_type == -1) + current_type = type; + if (current_id == -1) /* use first ID in section3 */ + current_id = read_32bit(sb->main_size + sb->section1_size + sb->section2_size + sb->extra_size + 0x00, streamFile); + + if (sb->external_flag_offset) { + current_is_external = read_32bit(offset + sb->external_flag_offset, streamFile); + } else if (sb->has_extra_name_flag && read_32bit(offset + sb->extra_name_offset, streamFile) != 0xFFFFFFFF) { + current_is_external = 1; /* -1 in extra_name means internal */ + } + + + if (!current_is_external) { + if (current_type != type) { + current_type = type; + current_id++; /* rotate */ + if (current_id >= sb->section3_num) + current_id = 0; /* reset */ + } + + } + } + /* update streams (total_stream also doubles as current) */ sb->total_streams++; if (sb->total_streams != target_stream) continue; - ;VGM_LOG("target at offset=%lx (size=%x)\n", offset, sb->section2_entry_size); + //;VGM_LOG("target at offset=%lx (size=%x)\n", offset, sb->section2_entry_size); sb->header_id = read_32bit(offset + 0x00, streamFile); /* 16b+16b group+sound id */ sb->header_type = read_32bit(offset + 0x04, streamFile); @@ -327,8 +355,11 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) { if (sb->num_samples_offset) sb->stream_samples = read_32bit(offset + sb->num_samples_offset, streamFile); - if (sb->stream_id_offset) + if (sb-> has_rotating_ids) { + sb->stream_id = current_id; + } else if (sb->stream_id_offset) { sb->stream_id = read_32bit(offset + sb->stream_id_offset, streamFile); + } /* external stream name can be found in the header (first versions) or the extra table (later versions) */ if (sb->stream_name_offset) { @@ -341,6 +372,8 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) { /* not always set and must be derived */ if (sb->external_flag_offset) { sb->is_external = read_32bit(offset + sb->external_flag_offset, streamFile); + } else if (sb->has_extra_name_flag && read_32bit(offset + sb->extra_name_offset, streamFile) != 0xFFFFFFFF) { + sb->is_external = 1; /* -1 in extra_name means internal */ } else if (sb->section3_num == 0) { sb->is_external = 1; } else { @@ -361,7 +394,7 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) { goto fail; } - if (!sb->stream_id_offset && sb->section3_num > 1) { + if (!(sb->stream_id_offset || sb->has_rotating_ids) && sb->section3_num > 1) { VGM_LOG("UBI SB: unexpected number of internal streams %i\n", sb->section3_num); goto fail; } @@ -392,6 +425,10 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) { } break; + case 0x01: /* PCM (Wii, rarely used) */ + sb->codec = RAW_PCM; + break; + case 0x03: /* Ubi ADPCM (main external stream codec, has subtypes) */ sb->codec = UBI_ADPCM; break; @@ -404,7 +441,6 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) { sb->codec = FMT_AT3; break; - case 0x01: /* PCM? (Wii, rarely used) */ default: VGM_LOG("UBI SB: unknown stream_type %x\n", sb->stream_type); goto fail; @@ -413,12 +449,11 @@ static int parse_sb_header(ubi_sb_header * sb, STREAMFILE *streamFile) { /* uncommon but possible */ //VGM_ASSERT(sb->is_external && sb->section3_num != 0, "UBI SS: mixed external and internal streams\n"); - /* seems can be safely ignored */ + /* seems that can be safely ignored */ //VGM_ASSERT(sb->is_external && sb->stream_id_offset && sb->stream_id > 0, "UBI SB: unexpected external stream with stream id\n"); - //todo fix, wrong /* section 3: substreams within the file, adjust stream offset (rarely used but table is always present) */ - if (!sb->is_external && sb->stream_id_offset && sb->section3_num > 1) { + if (!sb->is_external && (sb->stream_id_offset || sb->has_rotating_ids) && sb->section3_num > 1) { for (i = 0; i < sb->section3_num; i++) { off_t offset = sb->main_size + sb->section1_size + sb->section2_size + sb->extra_size + sb->section3_entry_size * i; @@ -620,13 +655,14 @@ static int config_sb_header_version(ubi_sb_header * sb, STREAMFILE *streamFile) sb->section2_entry_size = 0x78; sb->external_flag_offset = 0x2c; - sb->stream_id_offset = 0x34;//todo test + sb->stream_id_offset = 0x34; sb->num_samples_offset = 0x40; sb->sample_rate_offset = 0x54; sb->channels_offset = 0x5c; sb->stream_type_offset = 0x60; sb->extra_name_offset = 0x64; + sb->has_extra_name_flag = 1; return 1; } @@ -635,13 +671,14 @@ static int config_sb_header_version(ubi_sb_header * sb, STREAMFILE *streamFile) sb->section1_entry_size = 0x48; sb->section2_entry_size = 0x5c; - sb->external_flag_offset = 0; /* no apparent flag */ + sb->external_flag_offset = 0; sb->channels_offset = 0x2c; sb->sample_rate_offset = 0x30; sb->num_samples_offset = 0x3c; sb->extra_name_offset = 0x4c; sb->stream_type_offset = 0x50; + sb->has_extra_name_flag = 1; return 1; } @@ -650,15 +687,16 @@ static int config_sb_header_version(ubi_sb_header * sb, STREAMFILE *streamFile) sb->section1_entry_size = 0x48; sb->section2_entry_size = 0x58; - sb->external_flag_offset = 0; /* no apparent flag */ + sb->external_flag_offset = 0; sb->num_samples_offset = 0x28; - sb->stream_id_offset = 0x34;//todo test + sb->stream_id_offset = 0; sb->sample_rate_offset = 0x3c; sb->channels_offset = 0x44; sb->stream_type_offset = 0x48; sb->extra_name_offset = 0x4c; - sb->has_internal_names = 1; + sb->has_extra_name_flag = 1; + sb->has_rotating_ids = 1; return 1; } @@ -677,18 +715,34 @@ static int config_sb_header_version(ubi_sb_header * sb, STREAMFILE *streamFile) return 1; } + /* Red Steel (2006)(Wii) */ + if (sb->version == 0x00180006 && is_sb7) { /* same as 0x00150000 */ + sb->section1_entry_size = 0x68; + sb->section2_entry_size = 0x6c; + + sb->external_flag_offset = 0x28; /* maybe 0x2c */ + sb->num_samples_offset = 0x3c; + sb->sample_rate_offset = 0x50; + sb->channels_offset = 0x58; + sb->stream_type_offset = 0x5c; + sb->extra_name_offset = 0x60; + + return 1; + } + /* Prince of Persia: Rival Swords (2007)(PSP) */ if (sb->version == 0x00180005 && is_sb5) { sb->section1_entry_size = 0x48; sb->section2_entry_size = 0x54; - sb->external_flag_offset = 0; /* no apparent flag */ + sb->external_flag_offset = 0; sb->channels_offset = 0x28; sb->sample_rate_offset = 0x2c; //sb->num_samples_offset = 0x34 or 0x3c /* varies */ sb->extra_name_offset = 0x44; sb->stream_type_offset = 0x48; + sb->has_extra_name_flag = 1; return 1; } @@ -699,7 +753,7 @@ static int config_sb_header_version(ubi_sb_header * sb, STREAMFILE *streamFile) sb->external_flag_offset = 0x28; /* maybe 0x2c */ sb->channels_offset = 0x3c; - sb->sample_rate_offset = 0x44; + sb->sample_rate_offset = 0x40; sb->num_samples_offset = 0x48; sb->extra_name_offset = 0x58; sb->stream_type_offset = 0x5c; diff --git a/src/meta/wpd.c b/src/meta/wpd.c index 3bb37a2d..21d81cee 100644 --- a/src/meta/wpd.c +++ b/src/meta/wpd.c @@ -7,7 +7,7 @@ VGMSTREAM * init_vgmstream_wpd(STREAMFILE *streamFile) { char filename[PATH_LIMIT]; off_t start_offset; int channel_count; - int loop_flag; + int loop_flag; /* check extension, case insensitive */ streamFile->get_name(streamFile,filename,sizeof(filename)); @@ -17,8 +17,8 @@ VGMSTREAM * init_vgmstream_wpd(STREAMFILE *streamFile) { if (read_32bitBE(0x00,streamFile) != 0x20445057) /* " DPW" */ goto fail; - channel_count = read_32bitLE(0x4,streamFile); - loop_flag = 0; + channel_count = read_32bitLE(0x4,streamFile); + loop_flag = 0; /* build the VGMSTREAM */ vgmstream = allocate_vgmstream(channel_count,loop_flag); diff --git a/src/meta/wwise.c b/src/meta/wwise.c index ace0ca29..b871da8a 100644 --- a/src/meta/wwise.c +++ b/src/meta/wwise.c @@ -128,8 +128,8 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) { } /* other Wwise specific: */ - //"JUNK": optional padding so that raw data starts in an offset multiple of 0x10 (0-size JUNK exists too) - //"akd ": unknown (IMA/PCM; "audiokinetic data"?) + //"JUNK": optional padding for usually aligment (0-size JUNK exists too) + //"akd ": seem to store extra info for Wwise editor (wave peaks/loudness/HDR envelope?) } /* format to codec */ @@ -158,7 +158,7 @@ VGMSTREAM * init_vgmstream_wwise(STREAMFILE *streamFile) { ww.codec = DSP; } - /* Some Wwise files (ex. Oddworld PSV, Bayonetta 2 WiiU sfx) are truncated mirrors of another file. + /* Some Wwise files (ex. Oddworld PSV, Bayonetta 2 WiiU, often in BGM.bnk) are truncated mirrors of another file. * They come in RAM banks, probably to play the beginning while the rest of the real stream loads. * We'll add basic support to avoid complaints of this or that .wem not playing */ if (ww.data_size > ww.file_size) { @@ -560,50 +560,50 @@ fail: 0x00 (4): num_samples 0x04 (4): skip samples? 0x08 (4): ? (small if loop, 0 otherwise) -0x0c (4): loop offset after seek table+setup (offset after setup if file doesn't loop) +0x0c (4): data start offset after seek table+setup, or loop start when "smpl" is present 0x10 (4): ? (small, 0..~0x400) 0x14 (4): approximate data size without seek table? (almost setup+packets) 0x18 (4): setup_offset within data (0 = no seek table) 0x1c (4): audio_offset within data -0x20 (4): biggest packet size (not including header)? -0x24 (4): ? (mid, 0~0x5000) -0x28 (4): ? (mid, 0~0x5000) -0x2c (4): parent bank/event id? (shared by several .wem a game, but not all need to share it) +0x20 (2): biggest packet size (not including header)? +0x22 (2): ? (small, N..~0x100) uLastGranuleExtra? +0x24 (4): ? (mid, 0~0x5000) dwDecodeAllocSize? +0x28 (4): ? (mid, 0~0x5000) dwDecodeX64AllocSize? +0x2c (4): parent bank/event id? uHashCodebook? (shared by several .wem a game, but not all need to share it) 0x30 (1): blocksize_1_exp (small) 0x31 (1): blocksize_0_exp (large) 0x32 (2): empty "vorb" size 0x28 / 0x2a 0x00 (4): num_samples -0x04 (4): loop offset after seek table+setup (offset after setup if file doesn't loop) -0x08 (4): data size without seek table (setup+packets) +0x04 (4): data start offset after seek table+setup, or loop start when "smpl" is present +0x08 (4): data end offset after seek table (setup+packets), or loop end when "smpl" is present 0x0c (2): ? (small, 0..~0x400) 0x10 (4): setup_offset within data (0 = no seek table) 0x14 (4): audio_offset within data -0x18 (2): ? (small, 0..~0x400) -0x1a (2): ? (small, N..~0x100) -0x1c (4): ? (mid, 0~0x5000) -0x20 (4): ? (mid, 0~0x5000) -0x24 (4): parent bank/event id? (shared by several .wem a game, but not all need to share it) -0x28 (1): blocksize_1_exp (small) [removed when size is 0x28] -0x29 (1): blocksize_0_exp (large) [removed when size is 0x28] - +0x18 (2): biggest packet size (not including header)? +0x1a (2): ? (small, N..~0x100) uLastGranuleExtra? +0x1c (4): ? (mid, 0~0x5000) dwDecodeAllocSize? +0x20 (4): ? (mid, 0~0x5000) dwDecodeX64AllocSize? +0x24 (4): parent bank/event id? uHashCodebook? (shared by several .wem a game, but not all need to share it) +0x28 (1): blocksize_1_exp (small) [removed when size is 0x28] +0x29 (1): blocksize_0_exp (large) [removed when size is 0x28] - new format: "fmt" size 0x42, extra size 0x30 0x12 (2): flag? (00,10,18): not related to seek table, codebook type, chunk count, looping, etc 0x14 (4): channel config 0x18 (4): num_samples -0x1c (4): loop offset after seek table+setup (offset after setup if file doesn't loop) -0x20 (4): data size without seek table (setup+packets) +0x1c (4): data start offset after seek table+setup, or loop start when "smpl" is present +0x20 (4): data end offset after seek table (setup+packets), or loop end when "smpl" is present 0x24 (2): ?1 (small, 0..~0x400) 0x26 (2): ?2 (small, N..~0x100): not related to seek table, codebook type, chunk count, looping, packet size, samples, etc 0x28 (4): setup offset within data (0 = no seek table) 0x2c (4): audio offset within data 0x30 (2): biggest packet size (not including header) -0x32 (2): ?4 (small, 0..~0x100): may be same than ?2 (something related to the avg bitrate?) -0x34 (4): bitrate config? (mid, 0~0x5000) -0x38 (4): bitrate config? (mid, 0~0x5000) (2 byte with max/min?) +0x32 (2): (small, 0..~0x100) uLastGranuleExtra? +0x34 (4): ? (mid, 0~0x5000) dwDecodeAllocSize? +0x38 (4): ? (mid, 0~0x5000) dwDecodeX64AllocSize? 0x40 (1): blocksize_1_exp (small) 0x41 (1): blocksize_0_exp (large) diff --git a/src/meta/xwb.c b/src/meta/xwb.c index 6e17169b..403f0d98 100644 --- a/src/meta/xwb.c +++ b/src/meta/xwb.c @@ -25,7 +25,7 @@ static const int wma_block_align_index[17] = { }; -typedef enum { PCM, XBOX_ADPCM, MS_ADPCM, XMA1, XMA2, WMA, XWMA, ATRAC3 } xact_codec; +typedef enum { PCM, XBOX_ADPCM, MS_ADPCM, XMA1, XMA2, WMA, XWMA, ATRAC3, OGG } xact_codec; typedef struct { int little_endian; int version; @@ -124,8 +124,6 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { /* for Techland's XWB with no data */ if (xwb.base_offset == 0) goto fail; - /* some BlazBlue Centralfiction songs have padding after data size */ - if (xwb.data_offset + xwb.data_size > get_streamfile_size(streamFile)) goto fail; /* read base entry (WAVEBANKDATA) */ off = xwb.base_offset; @@ -168,8 +166,6 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { xwb.loop_start = (uint32_t)read_32bit(off+0x0c, streamFile); xwb.loop_end = (uint32_t)read_32bit(off+0x10, streamFile);//length - - xwb.loop_flag = (xwb.loop_end > 0 || xwb.loop_end_sample > xwb.loop_start); } else { uint32_t entry_info = (uint32_t)read_32bit(off+0x00, streamFile); @@ -190,9 +186,6 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { xwb.loop_start_sample = (uint32_t)read_32bit(off+0x10, streamFile); xwb.loop_end_sample = (uint32_t)read_32bit(off+0x14, streamFile) + xwb.loop_start_sample; } - - xwb.loop_flag = (xwb.loop_end > 0 || xwb.loop_end_sample > xwb.loop_start) - && !(xwb.entry_flags & WAVEBANKENTRY_FLAGS_IGNORELOOP); } @@ -231,14 +224,17 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { case 1: xwb.codec = XBOX_ADPCM; break; default: goto fail; } - } else if (xwb.version <= XACT1_1_MAX) { + } + else if (xwb.version <= XACT1_1_MAX) { switch(xwb.tag){ case 0: xwb.codec = PCM; break; case 1: xwb.codec = XBOX_ADPCM; break; case 2: xwb.codec = WMA; break; + case 3: xwb.codec = OGG; break; /* extension */ default: goto fail; } - } else if (xwb.version <= XACT2_2_MAX) { + } + else if (xwb.version <= XACT2_2_MAX) { switch(xwb.tag) { case 0: xwb.codec = PCM; break; /* Table Tennis (v34): XMA1, Prey (v38): XMA2, v35/36/37: ? */ @@ -246,7 +242,8 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { case 2: xwb.codec = MS_ADPCM; break; default: goto fail; } - } else { + } + else { switch(xwb.tag) { case 0: xwb.codec = PCM; break; case 1: xwb.codec = XMA2; break; @@ -267,6 +264,26 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { xwb.num_samples = atrac3_bytes_to_samples(xwb.stream_size, xwb.block_align * xwb.channels); } + /* Oddworld: Stranger's Wrath iOS/Android format hijack, with changed meanings */ + if (xwb.codec == OGG) { + xwb.num_samples = xwb.stream_size / (2 * xwb.channels); /* uncompressed bytes */ + xwb.stream_size = xwb.loop_end; + xwb.loop_start = 0; + xwb.loop_end = 0; + } + + + /* test loop after the above fixes */ + xwb.loop_flag = (xwb.loop_end > 0 || xwb.loop_end_sample > xwb.loop_start) + && !(xwb.entry_flags & WAVEBANKENTRY_FLAGS_IGNORELOOP); + + if (xwb.codec != OGG) { + /* for Oddworld OGG the data_size value is size of uncompressed bytes instead */ + /* some BlazBlue Centralfiction songs have padding after data size (maybe wrong rip?) */ + if (xwb.data_offset + xwb.data_size > get_streamfile_size(streamFile)) + goto fail; + } + /* fix samples */ if (xwb.version <= XACT2_2_MAX && xwb.codec == PCM) { @@ -435,7 +452,7 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { break; } - case ATRAC3: { /* Techland extension */ + case ATRAC3: { /* Techland PS3 extension */ uint8_t buf[200]; int bytes; @@ -452,6 +469,15 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) { vgmstream->layout_type = layout_none; break; } + + case OGG: { /* Oddworld: Strangers Wrath iOS/Android extension */ + vgmstream->codec_data = init_ffmpeg_offset(streamFile, xwb.stream_offset, xwb.stream_size); + if ( !vgmstream->codec_data ) goto fail; + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + break; + } + #endif default: diff --git a/src/vgmstream.c b/src/vgmstream.c index f3f8f64a..52098270 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -5,7 +5,6 @@ #include #include #include -#include "formats.h" #include "vgmstream.h" #include "meta/meta.h" #include "layout/layout.h" @@ -202,7 +201,6 @@ VGMSTREAM * (*init_vgmstream_fcns[])(STREAMFILE *streamFile) = { init_vgmstream_wii_smp, init_vgmstream_emff_ps2, init_vgmstream_emff_ngc, - init_vgmstream_ss_stream, init_vgmstream_thp, init_vgmstream_wii_sts, init_vgmstream_ps2_p2bt, diff --git a/src/vgmstream.h b/src/vgmstream.h index f2a85116..794963b7 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -1147,6 +1147,7 @@ typedef struct { /* do format detection, return pointer to a usable VGMSTREAM, or NULL on failure */ VGMSTREAM * init_vgmstream(const char * const filename); +/* init with custom IO via streamfile */ VGMSTREAM * init_vgmstream_from_STREAMFILE(STREAMFILE *streamFile); /* reset a VGMSTREAM to start of stream */ @@ -1169,6 +1170,9 @@ void describe_vgmstream(VGMSTREAM * vgmstream, char * desc, int length); * stream. Compares files by absolute paths. */ int get_vgmstream_average_bitrate(VGMSTREAM * vgmstream); +/* List of supported formats and elements in the list, for plugins that need to know. */ +const char ** vgmstream_get_formats(size_t * size); + /* -------------------------------------------------------------------------*/ /* vgmstream "private" API */ /* -------------------------------------------------------------------------*/ @@ -1203,4 +1207,9 @@ int vgmstream_do_loop(VGMSTREAM * vgmstream); * returns 0 on failure */ int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t start_offset); +/* get description info */ +const char * get_vgmstream_coding_description(coding_t coding_type); +const char * get_vgmstream_layout_description(layout_t layout_type); +const char * get_vgmstream_meta_description(meta_t meta_type); + #endif diff --git a/test/vrts.bat b/test/vrts.bat index d8f2fb75..438afae4 100644 --- a/test/vrts.bat +++ b/test/vrts.bat @@ -14,8 +14,9 @@ REM #TODO: escape & ! % in file/folder names setlocal enableDelayedExpansion - +REM #------------------------------------------------------------------------- REM #options +REM #------------------------------------------------------------------------- REM # -vo -vn : path to old/new exe set OP_CMD_OLD=test_old.exe set OP_CMD_NEW=test.exe @@ -27,6 +28,8 @@ REM # -nd: don't delete compared files set OP_NODELETE= REM # -nc: don't report correct files set OP_NOCORRECT= +REM # -p: performance test (decode with new exe and no comparison done) +set OP_PERFORMANCE= REM # parse options @@ -38,6 +41,7 @@ if "%~1"=="-f" set OP_SEARCH=%2 if "%~1"=="-r" set OP_RECURSIVE=/s if "%~1"=="-nd" set OP_NODELETE=true if "%~1"=="-nc" set OP_NOCORRECT=true +if "%~1"=="-p" set OP_PERFORMANCE=true shift goto set_options :end_options @@ -61,7 +65,8 @@ if %OP_SEARCH%=="" ( ) REM # process start -echo VRTS: start @%time% +set TIME_START=%time% +echo VRTS: start @%TIME_START% REM # search for files set CMD_DIR=dir /a:-d /b %OP_RECURSIVE% %OP_SEARCH% @@ -70,18 +75,39 @@ set CMD_FIND=findstr /i /v "\.exe$ \.dll$ \.zip$ \.7z$ \.rar$ \.bat$ \.sh$ \.txt REM # process files for /f "delims=" %%x in ('%CMD_DIR% ^| %CMD_FIND%') do ( set CMD_FILE=%%x - call :process_file "!CMD_FILE!" + + if "%OP_PERFORMANCE%" == "" ( + call :process_file "!CMD_FILE!" + ) else ( + call :performance_file "!CMD_FILE!" + ) ) +REM # find time elapsed +set TIME_END=%time% +for /F "tokens=1-4 delims=:.," %%a in ("%TIME_START%") do ( + set /A "TIME_START_S=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100" +) +for /F "tokens=1-4 delims=:.," %%a in ("%TIME_END%") do ( + set /A "TIME_END_S=(((%%a*60)+1%%b %% 100)*60+1%%c %% 100)*100+1%%d %% 100" +) +set /A TIME_ELAPSED_S=(TIME_END_S-TIME_START_S)/100 +set /A TIME_ELAPSED_C=(TIME_END_S-TIME_START_S)%%100 + + REM # process end (ok) -goto done +echo VRTS: done @%TIME_END% (%TIME_ELAPSED_S%,%TIME_ELAPSED_C%s) + +goto exit +REM # ######################################################################## REM # test a single file +REM # ######################################################################## :process_file outer REM # ignore files starting with dot (no filename) set CMD_SHORTNAME=%~n1 - if "%CMD_SHORTNAME%" == "" goto continue + if "%CMD_SHORTNAME%" == "" goto process_file_continue REM # get file set CMD_FILE=%1 @@ -105,7 +131,7 @@ REM # test a single file REM echo VRTS: nothing created for file %CMD_FILE% if exist "%TXT_NEW%" del /a:a "%TXT_NEW%" if exist "%TXT_OLD%" del /a:a "%TXT_OLD%" - goto continue + goto process_file_continue ) ) @@ -146,12 +172,42 @@ REM # test a single file if exist "%TXT_NEW%" del /a:a "%TXT_NEW%" ) -:continue +:process_file_continue exit /B REM :process_file end, continue from last call +REM # ######################################################################## +REM # decode only (no comparisons done), for performance testing +REM # ######################################################################## +:performance_file + REM # ignore files starting with dot (no filename) + set CMD_SHORTNAME=%~n1 + if "%CMD_SHORTNAME%" == "" goto performance_file_continue + + REM # get file + set CMD_FILE=%1 + set CMD_FILE=%CMD_FILE:"=% + REM echo VTRS: file %CMD_FILE% + + REM # new temp output + set WAV_NEW=%CMD_FILE%.test.wav + set CMD_VGM_NEW="%OP_CMD_NEW%" -o "%WAV_NEW%" "%CMD_FILE%" + %CMD_VGM_NEW% 1> nul 2>&1 & REM || goto error + + call :echo_color %C_O% "%CMD_FILE%" "done" + + REM # ignore output + if exist "%WAV_NEW%" del /a:a "%WAV_NEW%" + +:performance_file_continue +exit /B +REM :performance_file end, continue from last call + + +REM # ######################################################################## REM # hack to get colored output in Windows CMD using findstr + temp file +REM # ######################################################################## :echo_color set TEMP_FILE=%2-result set TEMP_FILE=%TEMP_FILE:"=% @@ -165,14 +221,10 @@ exit /B REM :echo_color end, continue from last call -:done -echo VRTS: done @%time% -goto exit - +REM # ######################################################################## :error -echo VRTS: error @%time% +echo VRTS: error goto exit - :exit diff --git a/winamp/in_vgmstream.c b/winamp/in_vgmstream.c index 9ca571bd..5d2afec1 100644 --- a/winamp/in_vgmstream.c +++ b/winamp/in_vgmstream.c @@ -5,8 +5,9 @@ /* Normally Winamp opens unicode files by their DOS 8.3 name. #define this to use wchar_t filenames, * which must be opened with _wfopen in a WINAMP_STREAMFILE (needed for dual files like .pos). * Only for Winamp paths, other parts would need #define UNICODE for Windows. */ -//#define UNICODE_INPUT_PLUGIN - +#ifdef VGM_WINAMP_UNICODE +#define UNICODE_INPUT_PLUGIN +#endif #ifdef _MSC_VER #define _CRT_SECURE_NO_DEPRECATE @@ -19,7 +20,6 @@ #include #include -#include "../src/formats.h" #include "../src/vgmstream.h" #include "in2.h" #include "wa_ipc.h" @@ -68,7 +68,7 @@ In_Module input_module; DWORD WINAPI __stdcall decode(void *arg); /* Winamp Play extension list, needed to accept/play and associate extensions in Windows */ -#define EXTENSION_LIST_SIZE VGM_EXTENSION_LIST_CHAR_SIZE * 6 +#define EXTENSION_LIST_SIZE (0x2000 * 6) #define EXT_BUFFER_SIZE 200 char working_extension_list[EXTENSION_LIST_SIZE] = {0}; @@ -463,14 +463,13 @@ static void add_extension(int length, char * dst, const char * ext) { * Each extension must be in this format: "extension\0Description\0" */ static void build_extension_list() { const char ** ext_list; - int ext_list_len; + size_t ext_list_len; int i; working_extension_list[0]='\0'; working_extension_list[1]='\0'; - ext_list = vgmstream_get_formats(); - ext_list_len = vgmstream_get_formats_length(); + ext_list = vgmstream_get_formats(&ext_list_len); for (i=0; i < ext_list_len; i++) { add_extension(EXTENSION_LIST_SIZE, working_extension_list, ext_list[i]); diff --git a/xmplay/xmp_vgmstream.c b/xmplay/xmp_vgmstream.c index 3b7b5de9..74551a11 100644 --- a/xmplay/xmp_vgmstream.c +++ b/xmplay/xmp_vgmstream.c @@ -11,7 +11,6 @@ #include #include -#include "../src/formats.h" #include "../src/vgmstream.h" #include "xmpin.h" @@ -27,7 +26,7 @@ /* XMPlay extension list, only needed to associate extensions in Windows */ /* todo: as of v3.8.2.17, any more than ~1000 will crash XMplay's file list screen (but not using the non-native Winamp plugin...) */ -#define EXTENSION_LIST_SIZE 1000 /*VGM_EXTENSION_LIST_CHAR_SIZE * 2*/ +#define EXTENSION_LIST_SIZE 1000 /* (0x2000 * 2) */ #define XMPLAY_MAX_PATH 32768 /* XMPlay function library */ @@ -205,13 +204,12 @@ static int add_extension(int length, char * dst, const char * ext) { * Extensions must be in this format: "Description\0extension1/.../extensionN" */ static void build_extension_list() { const char ** ext_list; - int ext_list_len; + size_t ext_list_len; int i, written; written = sprintf(working_extension_list, "%s%c", "vgmstream files",'\0'); - ext_list = vgmstream_get_formats(); - ext_list_len = vgmstream_get_formats_length(); + ext_list = vgmstream_get_formats(&ext_list_len); for (i=0; i < ext_list_len; i++) { written += add_extension(EXTENSION_LIST_SIZE-written, working_extension_list + written, ext_list[i]);