Updated VGMStream to r1702-76-g00bdb165
Signed-off-by: Christopher Snowhill <kode54@gmail.com>CQTexperiment
parent
d70e1da126
commit
9fd85f6670
|
@ -48,7 +48,7 @@ size_t ms_ima_bytes_to_samples(size_t bytes, int block_align, int channels);
|
|||
size_t xbox_ima_bytes_to_samples(size_t bytes, int channels);
|
||||
size_t dat4_ima_bytes_to_samples(size_t bytes, int channels);
|
||||
size_t apple_ima4_bytes_to_samples(size_t bytes, int channels);
|
||||
|
||||
int xbox_check_format(STREAMFILE* sf, uint32_t offset, uint32_t max, int channels);
|
||||
|
||||
/* ngc_dsp_decoder */
|
||||
void decode_ngc_dsp(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||
|
@ -430,6 +430,15 @@ void seek_vorbis_custom(VGMSTREAM* vgmstream, int32_t num_sample);
|
|||
void free_vorbis_custom(vorbis_custom_codec_data* data);
|
||||
#endif
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int layer;
|
||||
int bit_rate;
|
||||
int sample_rate;
|
||||
int frame_samples;
|
||||
int frame_size; /* bytes */
|
||||
int channels;
|
||||
} mpeg_frame_info;
|
||||
|
||||
#ifdef VGM_USE_MPEG
|
||||
/* mpeg_decoder */
|
||||
|
@ -482,16 +491,6 @@ void free_mpeg(mpeg_codec_data* data);
|
|||
int mpeg_get_sample_rate(mpeg_codec_data* data);
|
||||
long mpeg_bytes_to_samples(long bytes, const mpeg_codec_data* data);
|
||||
|
||||
typedef struct {
|
||||
int version;
|
||||
int layer;
|
||||
int bit_rate;
|
||||
int sample_rate;
|
||||
int frame_samples;
|
||||
int frame_size; /* bytes */
|
||||
int channels;
|
||||
} mpeg_frame_info;
|
||||
|
||||
int mpeg_get_frame_info(STREAMFILE* sf, off_t offset, mpeg_frame_info* info);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -1326,3 +1326,27 @@ size_t apple_ima4_bytes_to_samples(size_t bytes, int channels) {
|
|||
return (bytes / block_align) * (block_align - 0x02*channels) * 2 / channels
|
||||
+ ((bytes % block_align) ? ((bytes % block_align) - 0x02*channels) * 2 / channels : 0);
|
||||
}
|
||||
|
||||
|
||||
/* test XBOX-ADPCM frames for correctness */
|
||||
int xbox_check_format(STREAMFILE* sf, uint32_t offset, uint32_t max, int channels) {
|
||||
off_t max_offset = offset + max;
|
||||
int ch;
|
||||
|
||||
if (max_offset > get_streamfile_size(sf))
|
||||
max_offset = get_streamfile_size(sf);
|
||||
if (!channels)
|
||||
return 0;
|
||||
|
||||
while (offset < max_offset) {
|
||||
for (ch = 0; ch < channels; ch++) {
|
||||
uint16_t step = read_u16le(offset + 0x04 * ch + 0x02,sf);
|
||||
if (step > 88)
|
||||
return 0;
|
||||
}
|
||||
|
||||
offset += 0x24 * channels;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -192,7 +192,7 @@ void block_update_ea_schl(off_t block_offset, VGMSTREAM * vgmstream) {
|
|||
for (i = 0; i < vgmstream->channels; i++) {
|
||||
//vgmstream->ch[i].adpcm_history1_32 = read_16bit(vgmstream->ch[i].offset+0x00,streamFile);
|
||||
//vgmstream->ch[i].adpcm_history3_32 = read_16bit(vgmstream->ch[i].offset+0x02,streamFile);
|
||||
vgmstream->ch[i].offset += 4;
|
||||
vgmstream->ch[i].offset += 0x04;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -285,48 +285,49 @@ fail:
|
|||
|
||||
/* EA SBR/SBS - used in older 7th gen games for storing SFX */
|
||||
VGMSTREAM* init_vgmstream_ea_sbr(STREAMFILE* sf) {
|
||||
uint32_t i, num_sounds, type_desc;
|
||||
uint16_t num_metas, meta_type;
|
||||
off_t table_offset, types_offset, entry_offset, metas_offset, data_offset, snr_offset, sns_offset;
|
||||
STREAMFILE *sbsFile = NULL;
|
||||
uint32_t num_sounds, sound_id, type_desc, num_items, item_type,
|
||||
table_offset, types_offset, entry_offset, items_offset, data_offset, snr_offset, sns_offset;
|
||||
uint32_t i;
|
||||
STREAMFILE *sf_sbs = NULL;
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
int target_stream = sf->stream_index;
|
||||
|
||||
if (!check_extensions(sf, "sbr"))
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x00, sf) != 0x53424B52) /* "SBKR" */
|
||||
if (read_u32be(0x00, sf) != 0x53424B52) /* "SBKR" */
|
||||
goto fail;
|
||||
|
||||
/* SBR files are always big endian */
|
||||
num_sounds = read_32bitBE(0x1c, sf);
|
||||
table_offset = read_32bitBE(0x24, sf);
|
||||
types_offset = read_32bitBE(0x28, sf);
|
||||
num_sounds = read_u32be(0x1c, sf);
|
||||
table_offset = read_u32be(0x24, sf);
|
||||
types_offset = read_u32be(0x28, sf);
|
||||
|
||||
if (target_stream == 0) target_stream = 1;
|
||||
if (target_stream < 0 || num_sounds == 0 || target_stream > num_sounds)
|
||||
goto fail;
|
||||
|
||||
entry_offset = table_offset + 0x0a * (target_stream - 1);
|
||||
num_metas = read_16bitBE(entry_offset + 0x04, sf);
|
||||
metas_offset = read_32bitBE(entry_offset + 0x06, sf);
|
||||
sound_id = read_u32be(entry_offset + 0x00, sf);
|
||||
num_items = read_u16be(entry_offset + 0x04, sf);
|
||||
items_offset = read_u32be(entry_offset + 0x06, sf);
|
||||
|
||||
snr_offset = 0;
|
||||
sns_offset = 0;
|
||||
|
||||
for (i = 0; i < num_metas; i++) {
|
||||
entry_offset = metas_offset + 0x06 * i;
|
||||
meta_type = read_16bitBE(entry_offset + 0x00, sf);
|
||||
data_offset = read_32bitBE(entry_offset + 0x02, sf);
|
||||
for (i = 0; i < num_items; i++) {
|
||||
entry_offset = items_offset + 0x06 * i;
|
||||
item_type = read_u16be(entry_offset + 0x00, sf);
|
||||
data_offset = read_u32be(entry_offset + 0x02, sf);
|
||||
|
||||
type_desc = read_32bitBE(types_offset + 0x06 * meta_type, sf);
|
||||
type_desc = read_u32be(types_offset + 0x06 * item_type, sf);
|
||||
|
||||
switch (type_desc) {
|
||||
case 0x534E5231: /* "SNR1" */
|
||||
snr_offset = data_offset;
|
||||
break;
|
||||
case 0x534E5331: /* "SNS1" */
|
||||
sns_offset = read_32bitBE(data_offset, sf);
|
||||
sns_offset = read_u32be(data_offset, sf);
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
|
@ -336,43 +337,40 @@ VGMSTREAM* init_vgmstream_ea_sbr(STREAMFILE* sf) {
|
|||
if (snr_offset == 0 && sns_offset == 0)
|
||||
goto fail;
|
||||
|
||||
if (snr_offset == 0) {
|
||||
/* SPS file */
|
||||
sbsFile = open_streamfile_by_ext(sf, "sbs");
|
||||
if (!sbsFile)
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x00, sbsFile) != 0x53424B53) /* "SBKS" */
|
||||
goto fail;
|
||||
|
||||
vgmstream = init_vgmstream_eaaudiocore_header(sbsFile, NULL, sns_offset, 0x00, meta_EA_SPS, 0);
|
||||
if (!vgmstream)
|
||||
goto fail;
|
||||
} else if (sns_offset == 0) {
|
||||
if (sns_offset == 0) {
|
||||
/* RAM asset */
|
||||
vgmstream = init_vgmstream_eaaudiocore_header(sf, NULL, snr_offset, 0x00, meta_EA_SNR_SNS, 0);
|
||||
if (!vgmstream)
|
||||
goto fail;
|
||||
meta_t meta_type = (read_u8(snr_offset, sf) == 0x48) ? meta_EA_SPS : meta_EA_SNR_SNS;
|
||||
vgmstream = init_vgmstream_eaaudiocore_header(sf, NULL, snr_offset, 0x00, meta_type, 0);
|
||||
if (!vgmstream) goto fail;
|
||||
} else {
|
||||
/* streamed asset */
|
||||
sbsFile = open_streamfile_by_ext(sf, "sbs");
|
||||
if (!sbsFile)
|
||||
sf_sbs = open_streamfile_by_ext(sf, "sbs");
|
||||
if (!sf_sbs) goto fail;
|
||||
|
||||
if (read_u32be(0x00, sf_sbs) != 0x53424B53) /* "SBKS" */
|
||||
goto fail;
|
||||
|
||||
if (read_32bitBE(0x00, sbsFile) != 0x53424B53) /* "SBKS" */
|
||||
goto fail;
|
||||
if (read_u8(sns_offset, sf_sbs) == 0x48) {
|
||||
/* SPS */
|
||||
vgmstream = init_vgmstream_eaaudiocore_header(sf_sbs, NULL, sns_offset, 0x00, meta_EA_SPS, 0);
|
||||
if (!vgmstream) goto fail;
|
||||
} else {
|
||||
/* SNR/SNS */
|
||||
if (snr_offset == 0)
|
||||
goto fail;
|
||||
|
||||
vgmstream = init_vgmstream_eaaudiocore_header(sf, sbsFile, snr_offset, sns_offset, meta_EA_SNR_SNS, 0);
|
||||
if (!vgmstream)
|
||||
goto fail;
|
||||
vgmstream = init_vgmstream_eaaudiocore_header(sf, sf_sbs, snr_offset, sns_offset, meta_EA_SNR_SNS, 0);
|
||||
if (!vgmstream) goto fail;
|
||||
}
|
||||
}
|
||||
|
||||
snprintf(vgmstream->stream_name, STREAM_NAME_SIZE, "%08x", sound_id);
|
||||
vgmstream->num_streams = num_sounds;
|
||||
close_streamfile(sbsFile);
|
||||
close_streamfile(sf_sbs);
|
||||
return vgmstream;
|
||||
|
||||
fail:
|
||||
close_streamfile(sbsFile);
|
||||
close_streamfile(sf_sbs);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
|
@ -813,7 +811,7 @@ fail:
|
|||
VGMSTREAM* init_vgmstream_ea_sbr_harmony(STREAMFILE* sf) {
|
||||
uint64_t base_offset, sound_offset, offset, prev_offset;
|
||||
uint32_t chunk_id, data_offset, table_offset, dset_offset, set_values, set_sounds, sound_table_offset;
|
||||
int32_t flag;
|
||||
int16_t flag;
|
||||
uint16_t num_dsets;
|
||||
uint8_t set_type, offset_size;
|
||||
uint32_t i, j;
|
||||
|
@ -1090,7 +1088,7 @@ static VGMSTREAM* init_vgmstream_eaaudiocore_header(STREAMFILE* sf_head, STREAMF
|
|||
/* common channel configs are mono/stereo/quad/5.1/7.1 (from debug strings), while others are quite rare
|
||||
* [Battlefield 4 (X360)-EAXMA: 3/5/7ch, Army of Two: The Devil's Cartel (PS3)-EALayer3v2P: 11ch] */
|
||||
eaac.channels = eaac.channel_config + 1;
|
||||
/* EA 6ch channel mapping is L C R BL BR LFE, but may use stereo layers for dynamic music
|
||||
/* EA 6ch channel mapping is FL FC FR BL BR LFE, but may use stereo layers for dynamic music
|
||||
* instead, so we can't re-map automatically (use TXTP) */
|
||||
|
||||
/* V0: SNR+SNS, V1: SPH+SPS (no apparent differences, other than block flags) */
|
||||
|
@ -1111,8 +1109,8 @@ static VGMSTREAM* init_vgmstream_eaaudiocore_header(STREAMFILE* sf_head, STREAMF
|
|||
goto fail;
|
||||
}
|
||||
|
||||
if (eaac.version == EAAC_VERSION_V1 && eaac.type != EAAC_TYPE_STREAM) {
|
||||
/* should never happen */
|
||||
if (eaac.version == EAAC_VERSION_V1 && eaac.type == EAAC_TYPE_GIGASAMPLE) {
|
||||
/* probably does not exist */
|
||||
VGM_LOG("EA EAAC: bad stream type for version %x\n", eaac.version);
|
||||
goto fail;
|
||||
}
|
||||
|
|
|
@ -1483,7 +1483,7 @@ static VGMSTREAM* init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header* e
|
|||
} else if (vgmstream->coding_type == coding_NGC_DSP && vgmstream->channels > 1 && ea->offsets[0] == ea->offsets[1]) {
|
||||
/* pcstream+gcadpcm with sx.exe v2, not in flag_value, probably a bug (even with this parts of the wave are off) */
|
||||
int interleave = (ea->num_samples / 14 * 8); /* full interleave */
|
||||
for (i = 0; i < ea->channels; i++) {
|
||||
for (i = 0; i < vgmstream->channels; i++) {
|
||||
vgmstream->ch[i].offset = ea->offsets[0] + interleave*i;
|
||||
}
|
||||
} else if (ea->platform == EA_PLATFORM_PS2 && (ea->flag_value & 0x100)) {
|
||||
|
|
|
@ -112,15 +112,18 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) {
|
|||
fsb_header fsb = {0};
|
||||
|
||||
|
||||
/* checks
|
||||
* .fsb: standard
|
||||
* .bnk: Hard Corps Uprising (PS3) */
|
||||
if ( !check_extensions(sf, "fsb,bnk") )
|
||||
/* checks */
|
||||
if ((read_u32be(0x00,sf) & 0xFFFFFF00) != get_id32be("FSB\0"))
|
||||
goto fail;
|
||||
|
||||
/* check header */
|
||||
fsb.id = read_32bitBE(0x00,sf);
|
||||
if (fsb.id == 0x46534231) { /* "FSB1" (somewhat different from other fsbs) */
|
||||
/* .fsb: standard
|
||||
* .bnk: Hard Corps Uprising (PS3)
|
||||
* .sfx: Geon Cube (Wii) */
|
||||
if ( !check_extensions(sf, "fsb,bnk,sfx") )
|
||||
goto fail;
|
||||
|
||||
fsb.id = read_u32be(0x00,sf);
|
||||
if (fsb.id == get_id32be("FSB1")) {
|
||||
fsb.meta_type = meta_FSB1;
|
||||
fsb.base_header_size = 0x10;
|
||||
fsb.sample_header_min = 0x40;
|
||||
|
@ -132,7 +135,8 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) {
|
|||
fsb.version = 0;
|
||||
fsb.flags = 0;
|
||||
|
||||
if (fsb.total_subsongs > 1) goto fail;
|
||||
if (fsb.total_subsongs > 1)
|
||||
goto fail;
|
||||
|
||||
/* sample header (first stream only, not sure if there are multi-FSB1) */
|
||||
{
|
||||
|
@ -159,16 +163,16 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) {
|
|||
fsb.stream_offset = fsb.base_header_size + fsb.sample_headers_size;
|
||||
}
|
||||
}
|
||||
else { /* other FSBs (common/extended format) */
|
||||
if (fsb.id == 0x46534232) { /* "FSB2" */
|
||||
else {
|
||||
if (fsb.id == get_id32be("FSB2")) {
|
||||
fsb.meta_type = meta_FSB2;
|
||||
fsb.base_header_size = 0x10;
|
||||
fsb.sample_header_min = 0x40; /* guessed */
|
||||
} else if (fsb.id == 0x46534233) { /* "FSB3" */
|
||||
} else if (fsb.id == get_id32be("FSB3")) {
|
||||
fsb.meta_type = meta_FSB3;
|
||||
fsb.base_header_size = 0x18;
|
||||
fsb.sample_header_min = 0x40;
|
||||
} else if (fsb.id == 0x46534234) { /* "FSB4" */
|
||||
} else if (fsb.id == get_id32be("FSB4")) {
|
||||
fsb.meta_type = meta_FSB4;
|
||||
fsb.base_header_size = 0x30;
|
||||
fsb.sample_header_min = 0x50;
|
||||
|
@ -183,7 +187,7 @@ VGMSTREAM* init_vgmstream_fsb(STREAMFILE* sf) {
|
|||
if (fsb.base_header_size > 0x10) {
|
||||
fsb.version = read_32bitLE(0x10,sf);
|
||||
fsb.flags = read_32bitLE(0x14,sf);
|
||||
/* FSB4: 0x18(8):hash 0x20(10):guid */
|
||||
/* FSB4: 0x18(8):hash, 0x20(10):guid */
|
||||
} else {
|
||||
fsb.version = 0;
|
||||
fsb.flags = 0;
|
||||
|
|
|
@ -858,6 +858,8 @@ static const hcakey_info hcakey_list[] = {
|
|||
{0x0a5d0fc8cc5c4502}, // Sng018
|
||||
{0x198ea1a17416050b}, // Sng019
|
||||
{0x2aa3b8abad207a1e}, // Sng020
|
||||
{0x08ad2fe12c79bca9}, // Sng022
|
||||
{0x18488992b1632ef5}, // Sng023
|
||||
{0x1175edbbacc1fc18}, // Sng024
|
||||
{0x0e14d06d7f7a6c8c}, // Sng025
|
||||
{0x33d98a3a9f9bfdef}, // Sng026
|
||||
|
@ -880,6 +882,9 @@ static const hcakey_info hcakey_list[] = {
|
|||
// Shaman King: Funbari Chronicle (Android)
|
||||
{1620612098671}, // 0000017954022A6F
|
||||
|
||||
// Heaven Burns Red (Android)
|
||||
{7355875239102698567}, // 6615518E8ECED447
|
||||
|
||||
};
|
||||
|
||||
#endif/*_HCA_KEYS_H_*/
|
||||
|
|
|
@ -1,7 +1,6 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
|
||||
|
||||
typedef struct {
|
||||
int loop_flag;
|
||||
int32_t loop_start;
|
||||
|
@ -15,10 +14,10 @@ typedef struct {
|
|||
|
||||
/* KTAC - Koei Tecmo custom AAC [Kin'iro no Corda 3 (Vita), Shingeki no Kyojin: Shichi kara no Dasshutsu (3DS), Dynasty Warriors (PS4)] */
|
||||
VGMSTREAM* init_vgmstream_ktac(STREAMFILE* sf) {
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
ktac_header_t ktac = {0};
|
||||
|
||||
|
||||
/* checks */
|
||||
/* .ktac: header id */
|
||||
if (!check_extensions(sf,"ktac"))
|
||||
|
@ -53,7 +52,6 @@ VGMSTREAM* init_vgmstream_ktac(STREAMFILE* sf) {
|
|||
if (ktac.type == 1)
|
||||
goto fail;
|
||||
|
||||
|
||||
/* build the VGMSTREAM */
|
||||
vgmstream = allocate_vgmstream(ktac.mp4.channels, ktac.loop_flag);
|
||||
if (!vgmstream) goto fail;
|
||||
|
@ -66,19 +64,14 @@ VGMSTREAM* init_vgmstream_ktac(STREAMFILE* sf) {
|
|||
|
||||
/* KTAC uses AAC, but not type found in .aac (that has headered frames, like mp3) but raw
|
||||
* packets + frame size table (similar to .mp4/m4a). We set config for FFmpeg's fake M4A header */
|
||||
#ifdef VGM_USE_FFMPEG
|
||||
{
|
||||
vgmstream->codec_data = init_ffmpeg_mp4_custom_std(sf, &ktac.mp4);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
}
|
||||
#else
|
||||
goto fail;
|
||||
#endif
|
||||
vgmstream->codec_data = init_ffmpeg_mp4_custom_std(sf, &ktac.mp4);
|
||||
if (!vgmstream->codec_data) goto fail;
|
||||
vgmstream->coding_type = coding_FFmpeg;
|
||||
vgmstream->layout_type = layout_none;
|
||||
|
||||
return vgmstream;
|
||||
fail:
|
||||
close_vgmstream(vgmstream);
|
||||
#endif
|
||||
return NULL;
|
||||
}
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
#include "../util/endianness.h"
|
||||
|
||||
typedef enum { MFX, MFX_BANK, SFX_BANK, SBNK, FORM } musx_form;
|
||||
typedef enum { PSX, DSP, XBOX, IMA, DAT, NGCA, PCM } musx_codec;
|
||||
|
@ -187,16 +188,24 @@ static int parse_musx_stream(STREAMFILE* sf, musx_header* musx) {
|
|||
musx->platform = get_id32be("GC02"); /* (fake) */
|
||||
}
|
||||
else {
|
||||
int channels = musx->channels;
|
||||
off_t offset = musx->stream_offset;
|
||||
size_t max = 0x5000;
|
||||
if (max > musx->stream_size)
|
||||
max = musx->stream_size;
|
||||
if (!channels)
|
||||
channels = 2;
|
||||
|
||||
/* since engine seems to hardcode codecs no apparent way to detect in some cases
|
||||
* [Sphinx and the Cursed Mummy (multi), Buffy the Vampire Slayer: Chaos Bleeds (multi)] */
|
||||
if (ps_check_format(sf, offset, max)) {
|
||||
musx->platform = get_id32be("PS2_");
|
||||
} else {
|
||||
} else if (xbox_check_format(sf, offset, max, channels)) {
|
||||
musx->platform = get_id32be("XB02"); /* (fake) */
|
||||
}
|
||||
else {
|
||||
musx->platform = get_id32be("PC02"); /* (fake) */
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -267,6 +276,12 @@ static int parse_musx_stream(STREAMFILE* sf, musx_header* musx) {
|
|||
musx->codec = DAT;
|
||||
break;
|
||||
|
||||
case 0x50433032: /* "PC02" */
|
||||
default_channels = 2;
|
||||
default_sample_rate = 32000;
|
||||
musx->codec = IMA;
|
||||
break;
|
||||
|
||||
default:
|
||||
VGM_LOG("MUSX: unknown platform %x\n", musx->platform);
|
||||
goto fail;
|
||||
|
@ -307,7 +322,7 @@ static int parse_musx_stream(STREAMFILE* sf, musx_header* musx) {
|
|||
}
|
||||
|
||||
/* other types (0x0a, 0x09) look like section/end markers, 0x06/07 only seems to exist once */
|
||||
if (type == 0x06 || type == 0x07) {
|
||||
if (type == 0x06 || type == 0x07) { /* loop / goto */
|
||||
musx->loop_start = offset2;
|
||||
musx->loop_end = offset1;
|
||||
musx->loop_flag = 1;
|
||||
|
@ -361,6 +376,8 @@ fail:
|
|||
return 0;
|
||||
}
|
||||
|
||||
//TODO: check possible info here:
|
||||
// https://sphinxandthecursedmummy.fandom.com/wiki/SFX
|
||||
static int parse_musx(STREAMFILE* sf, musx_header* musx) {
|
||||
int32_t (*read_s32)(off_t,STREAMFILE*) = NULL;
|
||||
uint32_t (*read_u32)(off_t,STREAMFILE*) = NULL;
|
||||
|
@ -378,7 +395,7 @@ static int parse_musx(STREAMFILE* sf, musx_header* musx) {
|
|||
case 1: /* Athens 2004 (PS2) */
|
||||
musx->platform = 0; /* guess later */
|
||||
musx->tables_offset = 0x10;
|
||||
musx->big_endian = guess_endianness32bit(0x10, sf);
|
||||
musx->big_endian = guess_endian32(0x10, sf);
|
||||
musx->is_old = 1;
|
||||
break;
|
||||
|
||||
|
@ -670,7 +687,7 @@ static int parse_musx(STREAMFILE* sf, musx_header* musx) {
|
|||
data_offset = read_u32(musx->tables_offset+0x3c, sf);
|
||||
|
||||
target_offset = head_offset + (target_subsong - 1) * 0x1c;
|
||||
;VGM_LOG("MUSX: ho=%lx, do=%lx, to=%lx\n", head_offset, data_offset, target_offset);
|
||||
//;VGM_LOG("MUSX: ho=%lx, do=%lx, to=%lx\n", head_offset, data_offset, target_offset);
|
||||
|
||||
/* 0x00: subfile ID */
|
||||
musx->num_samples = read_s32(target_offset + 0x04, sf);
|
||||
|
|
|
@ -18,12 +18,12 @@ VGMSTREAM* init_vgmstream_mic_koei(STREAMFILE* sf) {
|
|||
if (start_offset != 0x800) goto fail;
|
||||
sample_rate = read_u32le(0x04,sf);
|
||||
channels = read_u32le(0x08,sf);
|
||||
if (channels > 2) goto fail;
|
||||
if (channels > 4) goto fail; /* 1/2/4 are known */
|
||||
interleave = read_u32le(0x0c,sf);
|
||||
if (interleave != 0x10) goto fail;
|
||||
|
||||
loop_end = read_32bitLE(0x10,sf);
|
||||
loop_start = read_32bitLE(0x14,sf);
|
||||
loop_end = read_s32le(0x10,sf);
|
||||
loop_start = read_s32le(0x14,sf);
|
||||
if (read_u32le(0x18,sf) != 0) goto fail;
|
||||
if (read_u32le(0x1c,sf) != 0) goto fail;
|
||||
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
#include "meta.h"
|
||||
#include "../coding/coding.h"
|
||||
//#include <ctype.h>
|
||||
|
||||
/* .WBK - seen in some Treyarch games [Spider-Man 2, Ultimate Spider-Man, Call of Duty 2: Big Red One] */
|
||||
VGMSTREAM* init_vgmstream_wbk(STREAMFILE* sf) {
|
||||
|
@ -154,6 +155,19 @@ fail:
|
|||
return NULL;
|
||||
}
|
||||
|
||||
/* Ultimate Spider-Man string hashing algorithm, for reference */
|
||||
#if 0
|
||||
static uint32_t wbk_hasher(const char* input) {
|
||||
uint32_t hash = 0;
|
||||
|
||||
for (const char* ch = input; *ch; ch++) {
|
||||
hash += hash*32 + tolower(*ch);
|
||||
}
|
||||
|
||||
return hash;
|
||||
}
|
||||
#endif
|
||||
|
||||
/* .WBK - evolution of the above Treyarch bank format [Call of Duty 3] */
|
||||
VGMSTREAM* init_vgmstream_wbk_nslb(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
|
@ -291,14 +305,18 @@ VGMSTREAM* init_vgmstream_wbk_nslb(STREAMFILE* sf) {
|
|||
off_t riff_fmt_offset, riff_data_offset;
|
||||
size_t bytes, riff_fmt_size, riff_data_size;
|
||||
|
||||
sound_offset += 0x0c;
|
||||
sound_size -= 0x0c;
|
||||
|
||||
/* find "fmt" chunk */
|
||||
if (!find_chunk_riff_le(sf, 0x666d7420, sound_offset + 0x0c, sound_size - 0x0c, &riff_fmt_offset, &riff_fmt_size))
|
||||
if (!find_chunk_riff_le(sf, 0x666d7420, sound_offset, sound_size, &riff_fmt_offset, &riff_fmt_size))
|
||||
goto fail;
|
||||
|
||||
/* find "data" chunk */
|
||||
if (!find_chunk_riff_le(sf, 0x64617461, sound_offset + 0x0c, sound_size - 0x0c, &riff_data_offset, &riff_data_size))
|
||||
if (!find_chunk_riff_le(sf, 0x64617461, sound_offset, sound_size, &riff_data_offset, &riff_data_size))
|
||||
goto fail;
|
||||
|
||||
sound_offset = riff_data_offset;
|
||||
bytes = ffmpeg_make_riff_xma_from_fmt_chunk(buf, 0x100, riff_fmt_offset, riff_fmt_size, riff_data_size, sf, 0);
|
||||
|
||||
vgmstream->codec_data = init_ffmpeg_header_offset(sf, buf, bytes, riff_data_offset, riff_data_size);
|
||||
|
|
Loading…
Reference in New Issue