mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-29 08:44:32 +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_xvag_subsong, "blocked (XVAG subsong)"},
|
||||||
{layout_blocked_ea_wve_au00, "blocked (EA WVE au00)"},
|
{layout_blocked_ea_wve_au00, "blocked (EA WVE au00)"},
|
||||||
{layout_blocked_ea_wve_ad10, "blocked (EA WVE Ad10)"},
|
{layout_blocked_ea_wve_ad10, "blocked (EA WVE Ad10)"},
|
||||||
|
{layout_blocked_sthd, "blocked (STHD)"},
|
||||||
};
|
};
|
||||||
|
|
||||||
static const meta_info meta_info_list[] = {
|
static const meta_info meta_info_list[] = {
|
||||||
@ -977,6 +978,7 @@ static const meta_info meta_info_list[] = {
|
|||||||
{meta_NXAP, "Nex NXAP header"},
|
{meta_NXAP, "Nex NXAP header"},
|
||||||
{meta_EA_WVE_AU00, "Electronic Arts WVE (au00) header"},
|
{meta_EA_WVE_AU00, "Electronic Arts WVE (au00) header"},
|
||||||
{meta_EA_WVE_AD10, "Electronic Arts WVE (Ad10) header"},
|
{meta_EA_WVE_AD10, "Electronic Arts WVE (Ad10) header"},
|
||||||
|
{meta_STHD, "Dream Factory STHD header"},
|
||||||
|
|
||||||
#ifdef VGM_USE_MP4V2
|
#ifdef VGM_USE_MP4V2
|
||||||
{meta_MP4, "AAC header"},
|
{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:
|
case layout_blocked_ea_wve_ad10:
|
||||||
block_update_ea_wve_ad10(vgmstream->next_block_offset,vgmstream);
|
block_update_ea_wve_ad10(vgmstream->next_block_offset,vgmstream);
|
||||||
break;
|
break;
|
||||||
|
case layout_blocked_sthd:
|
||||||
|
block_update_sthd(vgmstream->next_block_offset,vgmstream);
|
||||||
|
break;
|
||||||
default:
|
default:
|
||||||
break;
|
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_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_au00(off_t block_offset, VGMSTREAM * vgmstream);
|
||||||
void block_update_ea_wve_ad10(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 */
|
/* other layouts */
|
||||||
void render_vgmstream_interleave(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);
|
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_ea_wve_ad10(STREAMFILE * streamFile);
|
||||||
|
|
||||||
|
VGMSTREAM * init_vgmstream_sthd(STREAMFILE * streamFile);
|
||||||
|
|
||||||
#endif /*_META_H*/
|
#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_nxap,
|
||||||
init_vgmstream_ea_wve_au00,
|
init_vgmstream_ea_wve_au00,
|
||||||
init_vgmstream_ea_wve_ad10,
|
init_vgmstream_ea_wve_ad10,
|
||||||
|
init_vgmstream_sthd,
|
||||||
|
|
||||||
init_vgmstream_txth, /* should go at the end (lower priority) */
|
init_vgmstream_txth, /* should go at the end (lower priority) */
|
||||||
#ifdef VGM_USE_FFMPEG
|
#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_xvag_subsong:
|
||||||
case layout_blocked_ea_wve_au00:
|
case layout_blocked_ea_wve_au00:
|
||||||
case layout_blocked_ea_wve_ad10:
|
case layout_blocked_ea_wve_ad10:
|
||||||
|
case layout_blocked_sthd:
|
||||||
render_vgmstream_blocked(buffer,sample_count,vgmstream);
|
render_vgmstream_blocked(buffer,sample_count,vgmstream);
|
||||||
break;
|
break;
|
||||||
case layout_aix:
|
case layout_aix:
|
||||||
|
@ -251,6 +251,7 @@ typedef enum {
|
|||||||
layout_blocked_xvag_subsong, /* XVAG subsongs [God of War III (PS4)] */
|
layout_blocked_xvag_subsong, /* XVAG subsongs [God of War III (PS4)] */
|
||||||
layout_blocked_ea_wve_au00, /* EA WVE au00 blocks */
|
layout_blocked_ea_wve_au00, /* EA WVE au00 blocks */
|
||||||
layout_blocked_ea_wve_ad10, /* EA WVE Ad10 blocks */
|
layout_blocked_ea_wve_ad10, /* EA WVE Ad10 blocks */
|
||||||
|
layout_blocked_sthd, /* Dream Factory STHD */
|
||||||
|
|
||||||
/* otherwise odd */
|
/* otherwise odd */
|
||||||
layout_aix, /* CRI AIX's wheels within wheels */
|
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_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_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_EA_WVE_AD10, /* Electronic Arts PS movies [Wing Commander 3/4 (PS)] */
|
||||||
|
meta_STHD, /* STHD .stx [Kakuto Chojin (Xbox)] */
|
||||||
|
|
||||||
#ifdef VGM_USE_MP4V2
|
#ifdef VGM_USE_MP4V2
|
||||||
meta_MP4, /* AAC (iOS) */
|
meta_MP4, /* AAC (iOS) */
|
||||||
|
Loading…
Reference in New Issue
Block a user