diff --git a/msvc-build.bat b/msvc-build.bat index 2b026c25..00b6aa05 100644 --- a/msvc-build.bat +++ b/msvc-build.bat @@ -1 +1 @@ -powershell -ExecutionPolicy Bypass -NoProfile -File .\msvc-build.ps1 Build +powershell -ExecutionPolicy Bypass -NoProfile -File .\msvc-build.ps1 Build \ No newline at end of file diff --git a/src/formats.c b/src/formats.c index f7a90af4..823dc393 100644 --- a/src/formats.c +++ b/src/formats.c @@ -431,7 +431,7 @@ static const char* extension_list[] = { "rxx", //txth/reserved [Full Auto (X360)] "s14", - "s3v", //txth/reserved [Sound Voltex 5 (AC)] + "s3v", //Sound Voltex (AC) "sab", "sad", "saf", @@ -1388,6 +1388,7 @@ static const meta_info meta_info_list[] = { {meta_DSP_APEX, "Koei Tecmo APEX header"}, {meta_MPEG, "MPEG header"}, {meta_SSPF, "Konami SSPF header"}, + {meta_S3V, "Konami S3V header"}, }; void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t out_size) { diff --git a/src/libvgmstream.vcxproj b/src/libvgmstream.vcxproj index f2d84dd6..01291886 100644 --- a/src/libvgmstream.vcxproj +++ b/src/libvgmstream.vcxproj @@ -245,6 +245,7 @@ + diff --git a/src/libvgmstream.vcxproj.filters b/src/libvgmstream.vcxproj.filters index a3c74ab1..5dd9e6f2 100644 --- a/src/libvgmstream.vcxproj.filters +++ b/src/libvgmstream.vcxproj.filters @@ -1981,5 +1981,8 @@ meta\Source Files + + meta\Source Files + \ No newline at end of file diff --git a/src/meta/2dx9.c b/src/meta/2dx9.c index 911b6f6a..cefd664e 100644 --- a/src/meta/2dx9.c +++ b/src/meta/2dx9.c @@ -24,7 +24,7 @@ VGMSTREAM * init_vgmstream_2dx9(STREAMFILE *streamFile) { if (read_32bitBE(0x6a,streamFile) != 0x64617461) /* data */ goto fail; - loop_flag = 0; + loop_flag = (read_16bitLE(0x0e,streamFile) > 0); channel_count = read_16bitLE(0x2e,streamFile); start_offset = 0x72; @@ -35,6 +35,11 @@ VGMSTREAM * init_vgmstream_2dx9(STREAMFILE *streamFile) { vgmstream->meta_type = meta_2DX9; vgmstream->sample_rate = read_32bitLE(0x30,streamFile); vgmstream->num_samples = read_32bitLE(0x66,streamFile); + if (loop_flag) { + vgmstream->loop_start_sample = 0; + vgmstream->loop_end_sample = vgmstream->num_samples; + } + vgmstream->coding_type = coding_MSADPCM; vgmstream->layout_type = layout_none; vgmstream->frame_size = read_16bitLE(0x38,streamFile); diff --git a/src/meta/meta.h b/src/meta/meta.h index 3a70308e..034751d2 100644 --- a/src/meta/meta.h +++ b/src/meta/meta.h @@ -980,4 +980,6 @@ VGMSTREAM* init_vgmstream_mpeg(STREAMFILE* sf); VGMSTREAM* init_vgmstream_sspf(STREAMFILE* sf); +VGMSTREAM* init_vgmstream_s3v(STREAMFILE* sf); + #endif /*_META_H*/ diff --git a/src/meta/s3v.c b/src/meta/s3v.c new file mode 100644 index 00000000..d309bed8 --- /dev/null +++ b/src/meta/s3v.c @@ -0,0 +1,62 @@ +#include "meta.h" +#include "../coding/coding.h" + +/* S3V - from Konami arcade games [SOUND VOLTEX series (AC)] */ +VGMSTREAM * init_vgmstream_s3v(STREAMFILE *sf) { + VGMSTREAM * vgmstream = NULL; + off_t start_offset; + int32_t channel_count, loop_flag; + size_t data_size; + + /* checks */ + if (!check_extensions(sf, "s3v")) + goto fail; + + /* check header */ + if (read_32bitBE(0x00,sf) != 0x53335630) /* S3V0 */ + goto fail; + + /* No discernible loop_flag so we'll just use signatures. + Might have to update on a per game basis. */ + switch (read_32bitBE(0x14, sf)) { + case 0x82FA0000: // SOUND VOLTEX EXCEED GEAR ver5 + case 0x1BFD0000: // SOUND VOLTEX EXCEED GEAR ver6 + loop_flag = 1; + break; + + default: + loop_flag = 0; + } + + start_offset = 0x20; + data_size = read_32bitLE(0x08, sf); + channel_count = 2; + + /* build the VGMSTREAM */ + vgmstream = allocate_vgmstream(channel_count,loop_flag); + if (!vgmstream) goto fail; + vgmstream->meta_type = meta_S3V; + +#ifdef VGM_USE_FFMPEG + + vgmstream->codec_data = init_ffmpeg_offset(sf, start_offset, data_size); + if (!vgmstream->codec_data) goto fail; + vgmstream->sample_rate = ffmpeg_get_sample_rate(vgmstream->codec_data); + vgmstream->num_samples = ffmpeg_get_samples(vgmstream->codec_data); + if (loop_flag) { + vgmstream->loop_start_sample = read_32bitLE(0x10, sf); + vgmstream->loop_end_sample = vgmstream->num_samples; + } + vgmstream->coding_type = coding_FFmpeg; + vgmstream->layout_type = layout_none; + +#endif + + if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + goto fail; + return vgmstream; + +fail: + close_vgmstream(vgmstream); + return NULL; +} diff --git a/src/meta/sd9.c b/src/meta/sd9.c index dbe9d264..8fa47d35 100644 --- a/src/meta/sd9.c +++ b/src/meta/sd9.c @@ -22,12 +22,11 @@ VGMSTREAM * init_vgmstream_sd9(STREAMFILE *streamFile) { if (read_32bitBE(0x72, streamFile) != 0x64617461) /* data */ goto fail; - /* Probably better to check if loop end exists and use as loop flag. - Blame SD9s from beatmania IIDX 21: Spada that have a flase flag - but still "loop" */ + /* Some SD9s may loop without any loop points specificed. + If loop_flag is set with no points, loop entire song. */ - //loop_flag = (read_16bitLE(0x0e,streamFile)==0x1); - loop_flag = read_32bitLE(0x18, streamFile); // use loop end + loop_flag = read_16bitLE(0x0e,streamFile); + //loop_flag = read_32bitLE(0x18, streamFile); // use loop end channel_count = read_16bitLE(0x36, streamFile); start_offset = 0x7a; @@ -37,7 +36,17 @@ VGMSTREAM * init_vgmstream_sd9(STREAMFILE *streamFile) { vgmstream->sample_rate = read_32bitLE(0x38, streamFile); vgmstream->num_samples = read_32bitLE(0x6e, streamFile); - if (loop_flag) { + if (loop_flag > 0) { + vgmstream->loop_start_sample = read_32bitLE(0x14, streamFile) / 2 / channel_count; + vgmstream->loop_end_sample = read_32bitLE(0x18, streamFile) / 2 / channel_count; + if (vgmstream->loop_end_sample == 0) { + vgmstream->loop_end_sample = vgmstream->num_samples; + } + } + + /* beatmania IIDX 21: Spada is a special case. Loop flag is false but loops exist. + Konami, Why? */ + if ((loop_flag < 0) && (read_32bitLE(0x18, streamFile) !=0)) { vgmstream->loop_start_sample = read_32bitLE(0x14, streamFile) / 2 / channel_count; vgmstream->loop_end_sample = read_32bitLE(0x18, streamFile) / 2 / channel_count; } diff --git a/src/vgmstream.c b/src/vgmstream.c index 3e0b9b95..bad69dc5 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -521,6 +521,7 @@ VGMSTREAM* (*init_vgmstream_functions[])(STREAMFILE* sf) = { init_vgmstream_ubi_ckd_cwav, init_vgmstream_sspf, init_vgmstream_opus_rsnd, + init_vgmstream_s3v, /* lower priority metas (no clean header identity, somewhat ambiguous, or need extension/companion file to identify) */ init_vgmstream_mpeg, diff --git a/src/vgmstream.h b/src/vgmstream.h index 690aed90..b3142e30 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -755,6 +755,7 @@ typedef enum { meta_DSP_APEX, meta_MPEG, meta_SSPF, + meta_S3V, } meta_t;