mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-17 19:19:16 +01:00
Merge pull request #1082 from bnnm/musx-mic
- Add HCA key - Fix Koei .mic with 4 channels - Fix some MUSX .sfx [Sphinx and the Cursed Mummy (PC)]
This commit is contained in:
commit
4a057260a2
@ -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 xbox_ima_bytes_to_samples(size_t bytes, int channels);
|
||||||
size_t dat4_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);
|
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 */
|
/* ngc_dsp_decoder */
|
||||||
void decode_ngc_dsp(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
void decode_ngc_dsp(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do);
|
||||||
|
@ -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
|
return (bytes / block_align) * (block_align - 0x02*channels) * 2 / channels
|
||||||
+ ((bytes % block_align) ? ((bytes % block_align) - 0x02*channels) * 2 / channels : 0);
|
+ ((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;
|
||||||
|
}
|
||||||
|
@ -882,6 +882,9 @@ static const hcakey_info hcakey_list[] = {
|
|||||||
// Shaman King: Funbari Chronicle (Android)
|
// Shaman King: Funbari Chronicle (Android)
|
||||||
{1620612098671}, // 0000017954022A6F
|
{1620612098671}, // 0000017954022A6F
|
||||||
|
|
||||||
|
// Heaven Burns Red (Android)
|
||||||
|
{7355875239102698567}, // 6615518E8ECED447
|
||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif/*_HCA_KEYS_H_*/
|
#endif/*_HCA_KEYS_H_*/
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
#include "meta.h"
|
#include "meta.h"
|
||||||
#include "../coding/coding.h"
|
#include "../coding/coding.h"
|
||||||
|
#include "../util/endianness.h"
|
||||||
|
|
||||||
typedef enum { MFX, MFX_BANK, SFX_BANK, SBNK, FORM } musx_form;
|
typedef enum { MFX, MFX_BANK, SFX_BANK, SBNK, FORM } musx_form;
|
||||||
typedef enum { PSX, DSP, XBOX, IMA, DAT, NGCA, PCM } musx_codec;
|
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) */
|
musx->platform = get_id32be("GC02"); /* (fake) */
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
int channels = musx->channels;
|
||||||
off_t offset = musx->stream_offset;
|
off_t offset = musx->stream_offset;
|
||||||
size_t max = 0x5000;
|
size_t max = 0x5000;
|
||||||
if (max > musx->stream_size)
|
if (max > musx->stream_size)
|
||||||
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)) {
|
if (ps_check_format(sf, offset, max)) {
|
||||||
musx->platform = get_id32be("PS2_");
|
musx->platform = get_id32be("PS2_");
|
||||||
} else {
|
} else if (xbox_check_format(sf, offset, max, channels)) {
|
||||||
musx->platform = get_id32be("XB02"); /* (fake) */
|
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;
|
musx->codec = DAT;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case 0x50433032: /* "PC02" */
|
||||||
|
default_channels = 2;
|
||||||
|
default_sample_rate = 32000;
|
||||||
|
musx->codec = IMA;
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
VGM_LOG("MUSX: unknown platform %x\n", musx->platform);
|
VGM_LOG("MUSX: unknown platform %x\n", musx->platform);
|
||||||
goto fail;
|
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 */
|
/* 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_start = offset2;
|
||||||
musx->loop_end = offset1;
|
musx->loop_end = offset1;
|
||||||
musx->loop_flag = 1;
|
musx->loop_flag = 1;
|
||||||
@ -361,6 +376,8 @@ fail:
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//TODO: check possible info here:
|
||||||
|
// https://sphinxandthecursedmummy.fandom.com/wiki/SFX
|
||||||
static int parse_musx(STREAMFILE* sf, musx_header* musx) {
|
static int parse_musx(STREAMFILE* sf, musx_header* musx) {
|
||||||
int32_t (*read_s32)(off_t,STREAMFILE*) = NULL;
|
int32_t (*read_s32)(off_t,STREAMFILE*) = NULL;
|
||||||
uint32_t (*read_u32)(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) */
|
case 1: /* Athens 2004 (PS2) */
|
||||||
musx->platform = 0; /* guess later */
|
musx->platform = 0; /* guess later */
|
||||||
musx->tables_offset = 0x10;
|
musx->tables_offset = 0x10;
|
||||||
musx->big_endian = guess_endianness32bit(0x10, sf);
|
musx->big_endian = guess_endian32(0x10, sf);
|
||||||
musx->is_old = 1;
|
musx->is_old = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -670,7 +687,7 @@ static int parse_musx(STREAMFILE* sf, musx_header* musx) {
|
|||||||
data_offset = read_u32(musx->tables_offset+0x3c, sf);
|
data_offset = read_u32(musx->tables_offset+0x3c, sf);
|
||||||
|
|
||||||
target_offset = head_offset + (target_subsong - 1) * 0x1c;
|
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 */
|
/* 0x00: subfile ID */
|
||||||
musx->num_samples = read_s32(target_offset + 0x04, sf);
|
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;
|
if (start_offset != 0x800) goto fail;
|
||||||
sample_rate = read_u32le(0x04,sf);
|
sample_rate = read_u32le(0x04,sf);
|
||||||
channels = read_u32le(0x08,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);
|
interleave = read_u32le(0x0c,sf);
|
||||||
if (interleave != 0x10) goto fail;
|
if (interleave != 0x10) goto fail;
|
||||||
|
|
||||||
loop_end = read_32bitLE(0x10,sf);
|
loop_end = read_s32le(0x10,sf);
|
||||||
loop_start = read_32bitLE(0x14,sf);
|
loop_start = read_s32le(0x14,sf);
|
||||||
if (read_u32le(0x18,sf) != 0) goto fail;
|
if (read_u32le(0x18,sf) != 0) goto fail;
|
||||||
if (read_u32le(0x1c,sf) != 0) goto fail;
|
if (read_u32le(0x1c,sf) != 0) goto fail;
|
||||||
|
|
||||||
|
Loading…
x
Reference in New Issue
Block a user