From 0c40610f7fc8673807d734a1c68c09f22f26f2e7 Mon Sep 17 00:00:00 2001 From: bnnm Date: Sat, 19 Jan 2019 20:01:34 +0100 Subject: [PATCH] Fix KOEI .mic loops [Dynasty Tactics 2 (PS2)] --- src/formats.c | 2 +- src/meta/ps2_mic.c | 81 ++++++++++++++++------------------------------ 2 files changed, 28 insertions(+), 55 deletions(-) diff --git a/src/formats.c b/src/formats.c index bddd4db8..40367c6d 100644 --- a/src/formats.c +++ b/src/formats.c @@ -769,7 +769,7 @@ static const meta_info meta_info_list[] = { {meta_PS_HEADERLESS, "Headerless PS-ADPCM raw header"}, {meta_PS2_MIB_MIH, "Sony MultiStream MIH+MIB header"}, {meta_DSP_MPDSP, "Single DSP header stereo by .mpdsp extension"}, - {meta_PS2_MIC, "assume KOEI MIC file by .mic extension"}, + {meta_PS2_MIC, "KOEI .MIC header"}, {meta_DSP_JETTERS, "Double DSP header stereo by _lr.dsp extension"}, {meta_DSP_MSS, "Double DSP header stereo by .mss extension"}, {meta_DSP_GCM, "Double DSP header stereo by .gcm extension"}, diff --git a/src/meta/ps2_mic.c b/src/meta/ps2_mic.c index ee7c917d..14850d20 100644 --- a/src/meta/ps2_mic.c +++ b/src/meta/ps2_mic.c @@ -1,75 +1,48 @@ #include "meta.h" -#include "../util.h" - -/* MIC - - PS2 MIC format is an interleaved format found in most of KOEI Games - The header always start the long value 0x800 which is the start - of the BGM datas. - - 2008-05-15 - Fastelbja : First version ... -*/ +#include "../coding/coding.h" +/* .MIC - from KOEI games [Crimson Sea 2 (PS2), Dynasty Tactics 2 (PS2)] */ VGMSTREAM * init_vgmstream_ps2_mic(STREAMFILE *streamFile) { VGMSTREAM * vgmstream = NULL; - char filename[PATH_LIMIT]; + off_t start_offset; + int loop_flag, channel_count, loop_start, loop_end, sample_rate; + size_t interleave, block_size; - int loop_flag=0; - int channel_count; - int i; - /* check extension, case insensitive */ - streamFile->get_name(streamFile,filename,sizeof(filename)); - if (strcasecmp("mic",filename_extension(filename))) goto fail; - - /* check Header */ - if (read_32bitLE(0x00,streamFile) != 0x800) + /* checks */ + if (!check_extensions(streamFile, "mic")) goto fail; - /* check loop */ - loop_flag = (read_32bitLE(0x14,streamFile)!=1); - - channel_count=read_32bitLE(0x08,streamFile); + start_offset = read_32bitLE(0x00,streamFile); + if (start_offset != 0x800) goto fail; + sample_rate = read_32bitLE(0x04,streamFile); + channel_count = read_32bitLE(0x08,streamFile); + interleave = read_32bitLE(0x0c,streamFile); + loop_end = read_32bitLE(0x10,streamFile); + loop_start = read_32bitLE(0x14,streamFile); + loop_flag = (loop_start != 1); + block_size = interleave * channel_count; /* build the VGMSTREAM */ - vgmstream = allocate_vgmstream(channel_count,loop_flag); + vgmstream = allocate_vgmstream(channel_count, loop_flag); if (!vgmstream) goto fail; - /* fill in the vital statistics */ - vgmstream->channels = channel_count; - vgmstream->sample_rate = read_32bitLE(0x04,streamFile); - - /* Compression Scheme */ - vgmstream->coding_type = coding_PSX; - vgmstream->num_samples = read_32bitLE(0x10,streamFile)*14*channel_count; - - /* Get loop point values */ - if(vgmstream->loop_flag) { - vgmstream->loop_start_sample = read_32bitLE(0x14,streamFile)*14*channel_count; - vgmstream->loop_end_sample = read_32bitLE(0x10,streamFile)*14*channel_count; - } - - vgmstream->interleave_block_size = read_32bitLE(0x0C,streamFile); - vgmstream->layout_type = layout_interleave; vgmstream->meta_type = meta_PS2_MIC; + vgmstream->sample_rate = sample_rate; - /* open the file for reading by each channel */ - { - for (i=0;ich[i].streamfile = streamFile->open(streamFile,filename,STREAMFILE_DEFAULT_BUFFER_SIZE); + vgmstream->coding_type = coding_PSX; + vgmstream->interleave_block_size = interleave; + vgmstream->layout_type = layout_interleave; - if (!vgmstream->ch[i].streamfile) goto fail; - - vgmstream->ch[i].channel_start_offset= - vgmstream->ch[i].offset= - (off_t)(0x800+vgmstream->interleave_block_size*i); - } - } + vgmstream->num_samples = ps_bytes_to_samples(loop_end * block_size, channel_count); + vgmstream->loop_start_sample = ps_bytes_to_samples(loop_start * block_size, channel_count); + vgmstream->loop_end_sample = vgmstream->num_samples; + if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) + goto fail; return vgmstream; - /* clean up anything we may have opened */ fail: - if (vgmstream) close_vgmstream(vgmstream); + close_vgmstream(vgmstream); return NULL; }