Fix KOEI .mic loops [Dynasty Tactics 2 (PS2)]

This commit is contained in:
bnnm 2019-01-19 20:01:34 +01:00
parent c23662bb89
commit 0c40610f7f
2 changed files with 28 additions and 55 deletions

View File

@ -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"},

View File

@ -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;i<channel_count;i++) {
vgmstream->ch[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;
}