Add .KM9 [Nobunaga no Yabou - Souzou (Vita)]

This commit is contained in:
bnnm 2018-01-13 17:47:40 +01:00
parent 3c37267732
commit cbe4b19b92
9 changed files with 103 additions and 8 deletions

View File

@ -119,7 +119,9 @@ void decode_atrac9(VGMSTREAM *vgmstream, sample * outbuf, int32_t samples_to_do,
/* postadjust */ //todo improve
switch(data->config.type) {
case ATRAC9_XVAG: /* skip other subsong blocks in XVAG */
case ATRAC9_XVAG:
case ATRAC9_KMA9:
/* skip other subsong blocks */
if (data->config.interleave_skip && ((stream->offset - stream->channel_start_offset) % data->config.interleave_skip == 0)) {
stream->offset += data->config.interleave_skip * (data->config.subsong_skip - 1);
}

View File

@ -17,7 +17,7 @@ static const char* extension_list[] = {
"aaap",
"aax",
//"ac3", //FFmpeg, not parsed //common?
"ace", //fake, for tri-Ace's formats
"ace", //fake, for tri-Ace's formats (to be removed)
"acm",
"adm",
"adp",
@ -33,7 +33,7 @@ static const char* extension_list[] = {
"aix",
"akb",
"al2",
"amts", //fake extension (to be removed)
"amts", //fake extension/header id for .stm (to be removed)
"ao", //txth/reserved [Cloudphobia (PC)]
"as4",
"asd",
@ -138,7 +138,7 @@ static const char* extension_list[] = {
"iab",
"iadp",
"idsp",
"idvi", //fake extension (to be removed)
"idvi", //fake extension for .pcm (to be removed)
"ikm",
"ild",
"int",
@ -153,9 +153,10 @@ static const char* extension_list[] = {
"jstm",
"kces",
"kcey", //fake extension (to be removed)
"kcey", //fake extension/header id (to be removed)
"khv",
"kovs",
"km9",
"kovs", //.kvs header id
"kraw",
"ktss",
"kvs",
@ -206,7 +207,7 @@ static const char* extension_list[] = {
"ndp",
"ngca",
"nps",
"npsf", //fake extension (to be removed)
"npsf", //fake extension/header id for .nps (to be removed)
"nus3bank",
"nwa",
@ -226,7 +227,7 @@ static const char* extension_list[] = {
"pnb",
"pona",
"pos",
"ps2stm", //fake extension (to be removed)
"ps2stm", //fake extension for .stm (to be removed)
"psh",
"psnd",
"psw",
@ -944,6 +945,7 @@ static const meta_info meta_info_list[] = {
{meta_OGG_PSYCHIC, "Ogg Vorbis (Psychic Software)"},
{meta_OGG_SNGW, "Ogg Vorbis (Capcom)"},
{meta_OGG_ISD, "Ogg Vorbis (ISD)"},
{meta_KMA9, "Koei Tecmo KMA9 header"},
#ifdef VGM_USE_MP4V2
{meta_MP4, "AAC header"},

View File

@ -472,6 +472,10 @@
RelativePath=".\meta\ivb.c"
>
</File>
<File
RelativePath=".\meta\kma9.c"
>
</File>
<File
RelativePath=".\meta\kraw.c"
>

View File

@ -226,6 +226,7 @@
<ClCompile Include="meta\ish_isd.c" />
<ClCompile Include="meta\ivaud.c" />
<ClCompile Include="meta\ivb.c" />
<ClCompile Include="meta\kma9.c" />
<ClCompile Include="meta\kraw.c" />
<ClCompile Include="meta\maxis_xa.c" />
<ClCompile Include="meta\mc3.c" />

View File

@ -283,6 +283,9 @@
<ClCompile Include="meta\ivb.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\kma9.c">
<Filter>meta\Source Files</Filter>
</ClCompile>
<ClCompile Include="meta\kraw.c">
<Filter>meta\Source Files</Filter>
</ClCompile>

78
src/meta/kma9.c Normal file
View File

@ -0,0 +1,78 @@
#include "meta.h"
#include "../coding/coding.h"
/* KMA9 - Koei Tecmo's custom ATRAC9 [Nobunaga no Yabou - Souzou (Vita)] */
VGMSTREAM * init_vgmstream_kma9(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset;
int loop_flag, channel_count;
int total_subsongs = 0, target_subsong = streamFile->stream_index;
/* check extension */
if ( !check_extensions(streamFile,"km9") )
goto fail;
/* check header */
if (read_32bitBE(0x00,streamFile) != 0x4B4D4139) /* "KMA9" */
goto fail;
start_offset = read_32bitLE(0x04,streamFile);
channel_count = read_16bitLE(0x32,streamFile);
loop_flag = (read_32bitLE(0x28,streamFile) != 0);
total_subsongs = read_32bitLE(0x08,streamFile);
if (target_subsong == 0) target_subsong = 1;
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
/* 0x0c: unknown */
/* 0x14: data size of each subsong */
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = read_32bitLE(0x34,streamFile);
vgmstream->num_samples = read_32bitLE(0x18,streamFile); /* without skip_samples? */
vgmstream->loop_start_sample = read_32bitLE(0x24,streamFile); /* with skip_samples? */
vgmstream->loop_end_sample = vgmstream->num_samples; /* 0x28 looks like end samples but isn't, no idea */
vgmstream->num_streams = total_subsongs;
vgmstream->meta_type = meta_KMA9;
#ifdef VGM_USE_ATRAC9
{
atrac9_config cfg = {0};
cfg.type = ATRAC9_KMA9;
cfg.channels = vgmstream->channels;
cfg.config_data = read_32bitBE(0x5c,streamFile);
cfg.encoder_delay = read_32bitLE(0x20,streamFile);
cfg.interleave_skip = read_32bitLE(0x10,streamFile); /* 1 superframe */
cfg.subsong_skip = total_subsongs;
start_offset += (target_subsong-1) * cfg.interleave_skip * (cfg.subsong_skip-1);
vgmstream->codec_data = init_atrac9(&cfg);
if (!vgmstream->codec_data) goto fail;
vgmstream->coding_type = coding_ATRAC9;
vgmstream->layout_type = layout_none;
if (loop_flag) { /* seems correct but must double check */
vgmstream->loop_start_sample -= cfg.encoder_delay;
//vgmstream->loop_end_sample -= cfg.encoder_delay;
}
}
#else
goto fail;
#endif
/* open the file for reading */
if ( !vgmstream_open_stream(vgmstream, streamFile, start_offset) )
goto fail;
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}

View File

@ -693,4 +693,6 @@ VGMSTREAM * init_vgmstream_flx(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_mogg(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_kma9(STREAMFILE * streamFile);
#endif /*_META_H*/

View File

@ -373,6 +373,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = {
init_vgmstream_ngc_vid1,
init_vgmstream_flx,
init_vgmstream_mogg,
init_vgmstream_kma9,
init_vgmstream_txth, /* should go at the end (lower priority) */
#ifdef VGM_USE_FFMPEG

View File

@ -655,6 +655,7 @@ typedef enum {
meta_OGG_PSYCHIC, /* Ogg Vorbis with all bytes -0x23 */
meta_OGG_SNGW, /* Ogg Vorbis with optional key XOR + nibble swap (Capcom PC games) */
meta_OGG_ISD, /* Ogg Vorbis with key XOR (Azure Striker Gunvolt PC) */
meta_KMA9, /* Koei Tecmo [Nobunaga no Yabou - Souzou (Vita)] */
#ifdef VGM_USE_MP4V2
meta_MP4, /* AAC (iOS) */
@ -996,6 +997,7 @@ typedef struct {
typedef enum {
ATRAC9_DEFAULT = 0, /* ATRAC9 standard */
ATRAC9_XVAG, /* Sony XVAG: interleaved subsongs, Vita multichannel interleaves 2ch xN superframes */
ATRAC9_KMA9, /* Koei Tecmo KMA9: interleaved subsongs */
//ATRAC9_FSB, /* FMOD FSB: Vita multichannel interleaves 2ch xN superframes */
//ATRAC9_EATRAX, /* EA EATrax: buffered ATRAC9 in SPS blocks (superframes can be split between blocks) */
} atrac9_custom_t;