Updated VGMStream to r1050-3682-g5b76dc05
parent
4d7a4ec29d
commit
d23860d2d8
|
@ -26,8 +26,8 @@ static const uint8_t key_rev[] = { 0x31,0x5E,0x37,0x25,0x38,0x32,0x23,0x26,0x35,
|
||||||
/* Dark Souls 3 (PC) */ //"FDPrVuT4fAFvdHJYAgyMzRF4EcBAnKg"
|
/* Dark Souls 3 (PC) */ //"FDPrVuT4fAFvdHJYAgyMzRF4EcBAnKg"
|
||||||
static const uint8_t key_ds3[] = { 0x46,0x44,0x50,0x72,0x56,0x75,0x54,0x34,0x66,0x41,0x46,0x76,0x64,0x48,0x4A,0x59,0x41,0x67,0x79,0x4D,0x7A,0x52,0x46,0x34,0x45,0x63,0x42,0x41,0x6E,0x4B,0x67 };
|
static const uint8_t key_ds3[] = { 0x46,0x44,0x50,0x72,0x56,0x75,0x54,0x34,0x66,0x41,0x46,0x76,0x64,0x48,0x4A,0x59,0x41,0x67,0x79,0x4D,0x7A,0x52,0x46,0x34,0x45,0x63,0x42,0x41,0x6E,0x4B,0x67 };
|
||||||
|
|
||||||
/* Mortal Kombat X */
|
/* Mortal Kombat X/XL (PC) */ //"996164B5FC0F402983F61F220BB51DC6"
|
||||||
static const uint8_t key_mkx[] = { 0x99,0x61,0x64,0xB5,0xFC,0x0F,0x40,0x29,0x83,0xF6,0x1F,0x22,0x0B,0xB5,0x1D,0xC6 };
|
static const uint8_t key_mkx[] = { 0x39,0x39,0x36,0x31,0x36,0x34,0x42,0x35,0x46,0x43,0x30,0x46,0x34,0x30,0x32,0x39,0x38,0x33,0x46,0x36,0x31,0x46,0x32,0x32,0x30,0x42,0x42,0x35,0x31,0x44,0x43,0x36 };
|
||||||
|
|
||||||
/* Xian Xia Chuan (PC) */ //"gat@tcqs2010"
|
/* Xian Xia Chuan (PC) */ //"gat@tcqs2010"
|
||||||
static const uint8_t key_xxc[] = { 0x67,0x61,0x74,0x40,0x74,0x63,0x71,0x73,0x32,0x30,0x31,0x30 };
|
static const uint8_t key_xxc[] = { 0x67,0x61,0x74,0x40,0x74,0x63,0x71,0x73,0x32,0x30,0x31,0x30 };
|
||||||
|
@ -107,8 +107,7 @@ static const fsbkey_info fsbkey_list[] = {
|
||||||
{ 1,0, sizeof(key_rev),key_rev },//FSB5
|
{ 1,0, sizeof(key_rev),key_rev },//FSB5
|
||||||
{ 1,0, sizeof(key_ds3),key_ds3 },//untested
|
{ 1,0, sizeof(key_ds3),key_ds3 },//untested
|
||||||
{ 1,1, sizeof(key_ds3),key_ds3 },
|
{ 1,1, sizeof(key_ds3),key_ds3 },
|
||||||
{ 1,0, sizeof(key_mkx),key_mkx },//untested
|
{ 1,0, sizeof(key_mkx),key_mkx },//FSB5
|
||||||
{ 1,1, sizeof(key_mkx),key_mkx },//untested
|
|
||||||
{ 0,0, sizeof(key_xxc),key_xxc },//untested
|
{ 0,0, sizeof(key_xxc),key_xxc },//untested
|
||||||
{ 0,1, sizeof(key_xxc),key_xxc },//untested
|
{ 0,1, sizeof(key_xxc),key_xxc },//untested
|
||||||
{ 1,0, sizeof(key_xxc),key_xxc },//untested
|
{ 1,0, sizeof(key_xxc),key_xxc },//untested
|
||||||
|
|
|
@ -9,31 +9,54 @@ static VGMSTREAM* init_vgmstream_opus(STREAMFILE* sf, meta_t meta_type, off_t of
|
||||||
VGMSTREAM* vgmstream = NULL;
|
VGMSTREAM* vgmstream = NULL;
|
||||||
off_t start_offset;
|
off_t start_offset;
|
||||||
int loop_flag = 0, channel_count;
|
int loop_flag = 0, channel_count;
|
||||||
off_t data_offset, multichannel_offset = 0;
|
off_t data_offset, samples_offset, multichannel_offset = 0;
|
||||||
size_t data_size, skip = 0;
|
size_t data_size, skip = 0;
|
||||||
|
|
||||||
|
/* header chunk */
|
||||||
if (read_u32le(offset + 0x00,sf) != 0x80000001)
|
if (read_u32le(offset + 0x00,sf) != 0x80000001)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
/* 0x04: chunk size */
|
||||||
|
|
||||||
|
/* 0x08: null */
|
||||||
channel_count = read_u8(offset + 0x09, sf);
|
channel_count = read_u8(offset + 0x09, sf);
|
||||||
/* 0x0a: packet size if CBR, 0 if VBR */
|
/* 0x0a: packet size if CBR, 0 if VBR */
|
||||||
data_offset = offset + read_u32le(offset + 0x10, sf);
|
data_offset = read_u32le(offset + 0x10, sf);
|
||||||
|
/* 0x14: null/reserved? */
|
||||||
|
samples_offset = read_u32le(offset + 0x18, sf);
|
||||||
skip = read_u16le(offset + 0x1c, sf);
|
skip = read_u16le(offset + 0x1c, sf);
|
||||||
/* 0x1e: ? (seen in Lego Movie 2 (Switch)) */
|
/* 0x1e: ? (seen in Lego Movie 2 (Switch)) */
|
||||||
|
|
||||||
/* recent >2ch info [Clannad (Switch)] */
|
/* samples chunk, rare [Famicom Detective Club (Switch)] */
|
||||||
|
if (samples_offset && read_u32le(offset + samples_offset, sf) == 0x80000003) {
|
||||||
|
/* maybe should give priority to external info? */
|
||||||
|
samples_offset += offset;
|
||||||
|
/* 0x08: null*/
|
||||||
|
loop_flag = read_u8 (samples_offset + 0x09, sf);
|
||||||
|
num_samples = read_s32le(samples_offset + 0x0c, sf); /* slightly smaller than manual count */
|
||||||
|
loop_start = read_s32le(samples_offset + 0x10, sf);
|
||||||
|
loop_end = read_s32le(samples_offset + 0x14, sf);
|
||||||
|
/* rest (~0x38) reserved/alignment? */
|
||||||
|
/* values seem to take encoder delay into account */
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
loop_flag = (loop_end > 0); /* -1 when not set */
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* multichannel chunk, rare [Clannad (Switch)] */
|
||||||
if (read_u32le(offset + 0x20, sf) == 0x80000005) {
|
if (read_u32le(offset + 0x20, sf) == 0x80000005) {
|
||||||
multichannel_offset = offset + 0x20;
|
multichannel_offset = offset + 0x20;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* data chunk */
|
||||||
|
data_offset += offset;
|
||||||
if (read_u32le(data_offset, sf) != 0x80000004)
|
if (read_u32le(data_offset, sf) != 0x80000004)
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
data_size = read_u32le(data_offset + 0x04, sf);
|
data_size = read_u32le(data_offset + 0x04, sf);
|
||||||
|
|
||||||
start_offset = data_offset + 0x08;
|
start_offset = data_offset + 0x08;
|
||||||
loop_flag = (loop_end > 0); /* -1 when not set */
|
|
||||||
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
|
|
|
@ -20,6 +20,8 @@ typedef struct {
|
||||||
int subsongs;
|
int subsongs;
|
||||||
int layers;
|
int layers;
|
||||||
|
|
||||||
|
int target_subsong;
|
||||||
|
|
||||||
size_t data_size;
|
size_t data_size;
|
||||||
off_t stream_offset;
|
off_t stream_offset;
|
||||||
} xvag_header;
|
} xvag_header;
|
||||||
|
@ -43,7 +45,7 @@ VGMSTREAM* init_vgmstream_xvag(STREAMFILE* sf) {
|
||||||
* (extensionless): The Last Of Us (PS3) speech files */
|
* (extensionless): The Last Of Us (PS3) speech files */
|
||||||
if (!check_extensions(sf,"xvag,"))
|
if (!check_extensions(sf,"xvag,"))
|
||||||
goto fail;
|
goto fail;
|
||||||
if (read_32bitBE(0x00,sf) != 0x58564147) /* "XVAG" */
|
if (!is_id32be(0x00,sf, "XVAG"))
|
||||||
goto fail;
|
goto fail;
|
||||||
|
|
||||||
/* endian flag (XVAGs of the same game can use BE or LE, usually when reusing from other platforms) */
|
/* endian flag (XVAGs of the same game can use BE or LE, usually when reusing from other platforms) */
|
||||||
|
@ -89,6 +91,7 @@ VGMSTREAM* init_vgmstream_xvag(STREAMFILE* sf) {
|
||||||
total_subsongs = xvag.subsongs;
|
total_subsongs = xvag.subsongs;
|
||||||
if (target_subsong == 0) target_subsong = 1;
|
if (target_subsong == 0) target_subsong = 1;
|
||||||
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
|
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
|
||||||
|
xvag.target_subsong = target_subsong;
|
||||||
|
|
||||||
|
|
||||||
/* other chunks: */
|
/* other chunks: */
|
||||||
|
@ -117,7 +120,7 @@ VGMSTREAM* init_vgmstream_xvag(STREAMFILE* sf) {
|
||||||
|
|
||||||
|
|
||||||
/* build the VGMSTREAM */
|
/* build the VGMSTREAM */
|
||||||
vgmstream = allocate_vgmstream(xvag.channels,xvag.loop_flag);
|
vgmstream = allocate_vgmstream(xvag.channels, xvag.loop_flag);
|
||||||
if (!vgmstream) goto fail;
|
if (!vgmstream) goto fail;
|
||||||
|
|
||||||
vgmstream->meta_type = meta_XVAG;
|
vgmstream->meta_type = meta_XVAG;
|
||||||
|
@ -203,7 +206,6 @@ VGMSTREAM* init_vgmstream_xvag(STREAMFILE* sf) {
|
||||||
|
|
||||||
#ifdef VGM_USE_ATRAC9
|
#ifdef VGM_USE_ATRAC9
|
||||||
case 0x09: { /* ATRAC9: Sly Cooper and the Thievius Raccoonus (Vita), The Last of Us Remastered (PS4) */
|
case 0x09: { /* ATRAC9: Sly Cooper and the Thievius Raccoonus (Vita), The Last of Us Remastered (PS4) */
|
||||||
if (xvag.subsongs > 1 && xvag.layers > 1) goto fail;
|
|
||||||
|
|
||||||
/* "a9in": ATRAC9 info */
|
/* "a9in": ATRAC9 info */
|
||||||
/* 0x00: frame size, 0x04: samples per frame, 0x0c: fact num_samples (no change), 0x10: encoder delay1 */
|
/* 0x00: frame size, 0x04: samples per frame, 0x0c: fact num_samples (no change), 0x10: encoder delay1 */
|
||||||
|
@ -257,8 +259,13 @@ static int init_xvag_atrac9(STREAMFILE* sf, VGMSTREAM* vgmstream, xvag_header *
|
||||||
atrac9_config cfg = {0};
|
atrac9_config cfg = {0};
|
||||||
|
|
||||||
cfg.channels = vgmstream->channels;
|
cfg.channels = vgmstream->channels;
|
||||||
|
/* 0x00: frame size */
|
||||||
|
/* 0x04: frame samples */
|
||||||
cfg.config_data = read_32bitBE(chunk_offset+0x08,sf);
|
cfg.config_data = read_32bitBE(chunk_offset+0x08,sf);
|
||||||
|
/* 0x08: data size (layer only) */
|
||||||
|
/* 0x10: decoder delay? */
|
||||||
cfg.encoder_delay = read_32bit(chunk_offset+0x14,sf);
|
cfg.encoder_delay = read_32bit(chunk_offset+0x14,sf);
|
||||||
|
/* sometimes ATRAC9 data starts with a fake RIFF, that has total channels rather than layer channels */
|
||||||
|
|
||||||
vgmstream->codec_data = init_atrac9(&cfg);
|
vgmstream->codec_data = init_atrac9(&cfg);
|
||||||
if (!vgmstream->codec_data) goto fail;
|
if (!vgmstream->codec_data) goto fail;
|
||||||
|
@ -276,6 +283,7 @@ static layered_layout_data* build_layered_xvag(STREAMFILE* sf, xvag_header * xva
|
||||||
STREAMFILE* temp_sf = NULL;
|
STREAMFILE* temp_sf = NULL;
|
||||||
int32_t (*read_32bit)(off_t,STREAMFILE*) = xvag->big_endian ? read_32bitBE : read_32bitLE;
|
int32_t (*read_32bit)(off_t,STREAMFILE*) = xvag->big_endian ? read_32bitBE : read_32bitLE;
|
||||||
int i, layers = xvag->layers;
|
int i, layers = xvag->layers;
|
||||||
|
int chunk, chunks = layers * xvag->subsongs;
|
||||||
|
|
||||||
|
|
||||||
/* init layout */
|
/* init layout */
|
||||||
|
@ -300,7 +308,14 @@ static layered_layout_data* build_layered_xvag(STREAMFILE* sf, xvag_header * xva
|
||||||
|
|
||||||
if (!init_xvag_atrac9(sf, data->layers[i], xvag, chunk_offset))
|
if (!init_xvag_atrac9(sf, data->layers[i], xvag, chunk_offset))
|
||||||
goto fail;
|
goto fail;
|
||||||
temp_sf = setup_xvag_streamfile(sf, start_offset, frame_size*xvag->factor,frame_size, i, layers);
|
|
||||||
|
/* interleaves N layers for custom multichannel, may rarely use subsongs [Days Gone (PS4) multilayer test]
|
||||||
|
* ex. 2 layers, 1 subsong : [L1][L2][L1][L2]
|
||||||
|
* ex. 2 layers, 2 subsongs: [L1S1][L2S1][L1S2][L2S2] (assumed, could be [L1S1][L1S2][L2S1][L2S2]) */
|
||||||
|
chunk = i + xvag->subsongs * (xvag->target_subsong - 1); /* [L1S1][L2S1][L1S2][L2S2] */
|
||||||
|
//chunk = i * xvag->subsongs + (xvag->target_subsong - 1); /* [L1S1][L1S2][L2S1][L2S2] */
|
||||||
|
|
||||||
|
temp_sf = setup_xvag_streamfile(sf, start_offset, frame_size*xvag->factor, frame_size, chunk, chunks);
|
||||||
if (!temp_sf) goto fail;
|
if (!temp_sf) goto fail;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue