mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-29 00:34:33 +01:00
Add .stx STHD [Kakuto Chojin (Xbox)]
This commit is contained in:
parent
6ce4580683
commit
dfeb1da3ef
@ -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"},
|
||||
|
@ -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
22
src/layout/blocked_sthd.c
Normal 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;
|
||||
}
|
||||
}
|
@ -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);
|
||||
|
@ -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
69
src/meta/sthd.c
Normal 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;
|
||||
}
|
@ -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:
|
||||
|
@ -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) */
|
||||
|
Loading…
Reference in New Issue
Block a user