Add .stx STHD [Kakuto Chojin (Xbox)]

This commit is contained in:
bnnm 2018-03-29 17:01:46 +02:00
parent 6ce4580683
commit dfeb1da3ef
8 changed files with 103 additions and 0 deletions

View File

@ -596,6 +596,7 @@ static const layout_info layout_info_list[] = {
{layout_blocked_xvag_subsong, "blocked (XVAG subsong)"},
{layout_blocked_ea_wve_au00, "blocked (EA WVE au00)"},
{layout_blocked_ea_wve_ad10, "blocked (EA WVE Ad10)"},
{layout_blocked_sthd, "blocked (STHD)"},
};
static const meta_info meta_info_list[] = {
@ -977,6 +978,7 @@ static const meta_info meta_info_list[] = {
{meta_NXAP, "Nex NXAP header"},
{meta_EA_WVE_AU00, "Electronic Arts WVE (au00) header"},
{meta_EA_WVE_AD10, "Electronic Arts WVE (Ad10) header"},
{meta_STHD, "Dream Factory STHD header"},
#ifdef VGM_USE_MP4V2
{meta_MP4, "AAC header"},

View File

@ -173,6 +173,9 @@ void render_vgmstream_blocked(sample * buffer, int32_t sample_count, VGMSTREAM *
case layout_blocked_ea_wve_ad10:
block_update_ea_wve_ad10(vgmstream->next_block_offset,vgmstream);
break;
case layout_blocked_sthd:
block_update_sthd(vgmstream->next_block_offset,vgmstream);
break;
default:
break;
}

22
src/layout/blocked_sthd.c Normal file
View File

@ -0,0 +1,22 @@
#include "layout.h"
/* Dream Factory STHD blocks */
void block_update_sthd(off_t block_offset, VGMSTREAM * vgmstream) {
STREAMFILE* streamFile = vgmstream->ch[0].streamfile;
size_t block_size, channel_size;
off_t data_offset;
int i;
block_size = 0x800;
data_offset = read_16bitLE(block_offset + 0x04, streamFile);
channel_size = read_16bitLE(block_offset + 0x16, streamFile);
/* 0x06: num channels, 0x10: total blocks, 0x12: block count, 0x14(2): null, 0x18: block count + 1 */
vgmstream->current_block_offset = block_offset;
vgmstream->current_block_size = channel_size;
vgmstream->next_block_offset = block_offset + block_size;
for (i = 0; i < vgmstream->channels; i++) {
vgmstream->ch[i].offset = block_offset + data_offset + channel_size*i;
}
}

View File

@ -63,6 +63,7 @@ void block_update_vawx(off_t block_offset, VGMSTREAM * vgmstream);
void block_update_xvag_subsong(off_t block_offset, VGMSTREAM * vgmstream);
void block_update_ea_wve_au00(off_t block_offset, VGMSTREAM * vgmstream);
void block_update_ea_wve_ad10(off_t block_offset, VGMSTREAM * vgmstream);
void block_update_sthd(off_t block_offset, VGMSTREAM * vgmstream);
/* other layouts */
void render_vgmstream_interleave(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);

View File

@ -721,4 +721,6 @@ VGMSTREAM * init_vgmstream_ea_wve_au00(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_ea_wve_ad10(STREAMFILE * streamFile);
VGMSTREAM * init_vgmstream_sthd(STREAMFILE * streamFile);
#endif /*_META_H*/

69
src/meta/sthd.c Normal file
View File

@ -0,0 +1,69 @@
#include "meta.h"
#include "../coding/coding.h"
#include "../layout/layout.h"
/* STHD - Dream Factory .stx [Kakuto Chojin (Xbox)] */
VGMSTREAM * init_vgmstream_sthd(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t start_offset;
int loop_flag, channel_count;
/* checks */
if (!check_extensions(streamFile, "stx"))
goto fail;
if (read_32bitBE(0x00,streamFile) != 0x53544844) /* "STHD" */
goto fail;
/* first block has special values */
if (read_32bitLE(0x04,streamFile) != 0x0800 &&
read_32bitLE(0x0c,streamFile) != 0x0001 &&
read_32bitLE(0x14,streamFile) != 0x0000)
goto fail;
channel_count = read_16bitLE(0x06,streamFile);
loop_flag = read_16bitLE(0x18,streamFile) != -1;
start_offset = 0x800;
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(channel_count, loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = read_32bitLE(0x20, streamFile); /* repeated ~8 times? */
vgmstream->meta_type = meta_STHD;
vgmstream->coding_type = coding_XBOX_IMA_int;
vgmstream->layout_type = layout_blocked_sthd;
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
goto fail;
/* calc num_samples manually (blocks data varies in size) */
{
/* loop values may change to +1 in first actual block, but this works ok enough */
int loop_start_block = (uint16_t)read_16bitLE(0x1a,streamFile);
int loop_end_block = (uint16_t)read_16bitLE(0x1c,streamFile);
int block_count = 1; /* header block = 0 */
vgmstream->num_samples = 0;
block_update_sthd(start_offset,vgmstream);
do {
if (block_count == loop_start_block)
vgmstream->loop_start_sample = vgmstream->num_samples;
if (block_count == loop_end_block)
vgmstream->loop_end_sample = vgmstream->num_samples;
vgmstream->num_samples += xbox_ima_bytes_to_samples(vgmstream->current_block_size, 1);
block_update_sthd(vgmstream->next_block_offset,vgmstream);
block_count++;
}
while (vgmstream->next_block_offset < get_streamfile_size(streamFile));
}
block_update_sthd(start_offset, vgmstream);
return vgmstream;
fail:
close_vgmstream(vgmstream);
return NULL;
}

View File

@ -389,6 +389,7 @@ VGMSTREAM * (*init_vgmstream_functions[])(STREAMFILE *streamFile) = {
init_vgmstream_nxap,
init_vgmstream_ea_wve_au00,
init_vgmstream_ea_wve_ad10,
init_vgmstream_sthd,
init_vgmstream_txth, /* should go at the end (lower priority) */
#ifdef VGM_USE_FFMPEG
@ -930,6 +931,7 @@ void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstre
case layout_blocked_xvag_subsong:
case layout_blocked_ea_wve_au00:
case layout_blocked_ea_wve_ad10:
case layout_blocked_sthd:
render_vgmstream_blocked(buffer,sample_count,vgmstream);
break;
case layout_aix:

View File

@ -251,6 +251,7 @@ typedef enum {
layout_blocked_xvag_subsong, /* XVAG subsongs [God of War III (PS4)] */
layout_blocked_ea_wve_au00, /* EA WVE au00 blocks */
layout_blocked_ea_wve_ad10, /* EA WVE Ad10 blocks */
layout_blocked_sthd, /* Dream Factory STHD */
/* otherwise odd */
layout_aix, /* CRI AIX's wheels within wheels */
@ -663,6 +664,7 @@ typedef enum {
meta_NXAP, /* Nex Entertainment games [Time Crisis 4 (PS3), Time Crisis Razing Storm (PS3)] */
meta_EA_WVE_AU00, /* Electronic Arts PS movies [Future Cop - L.A.P.D. (PS), Supercross 2000 (PS)] */
meta_EA_WVE_AD10, /* Electronic Arts PS movies [Wing Commander 3/4 (PS)] */
meta_STHD, /* STHD .stx [Kakuto Chojin (Xbox)] */
#ifdef VGM_USE_MP4V2
meta_MP4, /* AAC (iOS) */