mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-01-22 11:43:41 +01:00
Merge pull request #1387 from EdnessP/master
Sony BNK (v3): Bank/sound name support
This commit is contained in:
commit
73a4f6b879
@ -8,7 +8,8 @@ typedef enum { PSX, PCM16, ATRAC9, HEVAG } bnk_codec;
|
||||
/* .BNK - Sony's SCREAM bank format [The Sly Collection (PS3), Puyo Puyo Tetris (PS4), NekoBuro: Cats Block (Vita)] */
|
||||
VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) {
|
||||
VGMSTREAM* vgmstream = NULL;
|
||||
uint32_t start_offset, stream_offset, name_offset = 0;
|
||||
char bank_name[STREAM_NAME_SIZE] /*[8]*/, stream_name[STREAM_NAME_SIZE] /*[16]*/;
|
||||
uint32_t start_offset, stream_offset, bank_name_offset = 0, stream_name_offset = 0;
|
||||
uint32_t stream_size, interleave = 0;
|
||||
int channels = 0, loop_flag, sample_rate, big_endian;
|
||||
int32_t loop_start = 0, loop_end = 0;
|
||||
@ -96,7 +97,8 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) {
|
||||
uint32_t table1_suboffset, table2_suboffset;
|
||||
uint32_t table2_entry_offset = 0, table3_entry_offset = 0;
|
||||
int table4_entry_id = -1;
|
||||
uint32_t table4_entries_offset, table4_names_offset;
|
||||
uint32_t table4_entry_idx, table4_entries_offset, table4_names_offset;
|
||||
uint32_t entry_offset, entry_count;
|
||||
|
||||
|
||||
switch(sblk_version) {
|
||||
@ -332,8 +334,56 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) {
|
||||
|
||||
/* parse names */
|
||||
switch(sblk_version) {
|
||||
//case 0x03: /* different format? */
|
||||
case 0x03:
|
||||
for (i = 0; i < section_entries; i++) {
|
||||
entry_offset = read_u32(table1_offset + (i * table1_entry_size) + table1_suboffset, sf);
|
||||
entry_count = read_u8(table1_offset + (i * table1_entry_size) + 0x04, sf);
|
||||
|
||||
/* is table2_entry_offset in the range of the expected section */
|
||||
if (table2_entry_offset >= entry_offset && table2_entry_offset < entry_offset + (entry_count * 0x08))
|
||||
table4_entry_id = i;
|
||||
}
|
||||
|
||||
/* table4:
|
||||
* 0x00: bank name (optional)
|
||||
* 0x08: name section offset
|
||||
* 0x0C-0x14: 3 null pointers (reserved?)
|
||||
* 0x18: 32 name chunk offsets (shorts)
|
||||
*/
|
||||
|
||||
/* Name chunks are organised as
|
||||
* (name[0] + name[4] + name[8] + name[12]) & 0x1F;
|
||||
* and using that as the index for the chunk offsets
|
||||
* name_sect_offset + (chunk_idx[result] * 0x14);
|
||||
*/
|
||||
if (read_u8(table4_offset, sf))
|
||||
bank_name_offset = table4_offset;
|
||||
|
||||
table4_entries_offset = table4_offset + 0x18;
|
||||
table4_names_offset = table4_offset + read_u32(table4_offset + 0x08, sf);
|
||||
|
||||
for (i = 0; i < 32; i++) {
|
||||
table4_entry_idx = read_u16(table4_entries_offset + (i * 2), sf);
|
||||
stream_name_offset = table4_names_offset + (table4_entry_idx * 0x14);
|
||||
/* searches the chunk until it finds the target name/index, or breaks at empty name */
|
||||
while (read_u8(stream_name_offset, sf)) {
|
||||
/* in case it goes somewhere out of bounds unexpectedly */
|
||||
//if ((read_u8(stream_name_offset + 0x00, sf) + read_u8(stream_name_offset + 0x04, sf) +
|
||||
// read_u8(stream_name_offset + 0x08, sf) + read_u8(stream_name_offset + 0x0C, sf)) & 0x1F != i)
|
||||
// goto fail;
|
||||
if (read_u16(stream_name_offset + 0x10, sf) == table4_entry_id)
|
||||
goto loop_break; /* to break out of the for+while loop simultaneously */
|
||||
//break;
|
||||
stream_name_offset += 0x14;
|
||||
}
|
||||
}
|
||||
//goto fail; /* didn't find any valid index? */
|
||||
loop_break:
|
||||
break;
|
||||
|
||||
//case 0x04: /* different format? */
|
||||
//case 0x05: /* different format? */
|
||||
|
||||
case 0x08:
|
||||
case 0x09:
|
||||
case 0x0d:
|
||||
@ -342,7 +392,7 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) {
|
||||
case 0x10:
|
||||
/* find if this sound has an assigned name in table1 */
|
||||
for (i = 0; i < section_entries; i++) {
|
||||
uint32_t entry_offset = read_u16(table1_offset+(i*table1_entry_size)+table1_suboffset+0x00,sf);
|
||||
entry_offset = read_u16(table1_offset+(i*table1_entry_size)+table1_suboffset+0x00,sf);
|
||||
|
||||
/* rarely (ex. Polara sfx) one name applies to multiple materials,
|
||||
* from current entry_offset to next entry_offset (section offsets should be in order) */
|
||||
@ -358,6 +408,9 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) {
|
||||
/* 0x0c: table4 size */
|
||||
/* variable: entries */
|
||||
/* variable: names (null terminated) */
|
||||
if (read_u8(table4_offset, sf))
|
||||
bank_name_offset = table4_offset;
|
||||
|
||||
table4_entries_offset = table4_offset + read_u32(table4_offset+0x08, sf);
|
||||
table4_names_offset = table4_entries_offset + (0x10*section_entries);
|
||||
//;VGM_LOG("BNK: t4_entries=%lx, t4_names=%lx\n", table4_entries_offset, table4_names_offset);
|
||||
@ -366,7 +419,7 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) {
|
||||
for (i = 0; i < section_entries; i++) {
|
||||
int entry_id = read_u32(table4_entries_offset+(i*0x10)+0x0c, sf);
|
||||
if (entry_id == table4_entry_id) {
|
||||
name_offset = table4_names_offset + read_u32(table4_entries_offset+(i*0x10)+0x00, sf);
|
||||
stream_name_offset = table4_names_offset + read_u32(table4_entries_offset+(i*0x10)+0x00, sf);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -376,7 +429,7 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) {
|
||||
break;
|
||||
}
|
||||
|
||||
//;VGM_LOG("BNK: stream_offset=%lx, stream_size=%x, name_offset=%lx\n", stream_offset, stream_size, name_offset);
|
||||
//;VGM_LOG("BNK: stream_offset=%lx, stream_size=%x, stream_name_offset=%lx\n", stream_offset, stream_size, stream_name_offset);
|
||||
}
|
||||
|
||||
|
||||
@ -635,9 +688,13 @@ VGMSTREAM* init_vgmstream_bnk_sony(STREAMFILE* sf) {
|
||||
goto fail;
|
||||
}
|
||||
|
||||
if (name_offset)
|
||||
read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,sf);
|
||||
|
||||
if (!bank_name_offset && stream_name_offset)
|
||||
read_string(vgmstream->stream_name, STREAM_NAME_SIZE, stream_name_offset, sf);
|
||||
else if (bank_name_offset && stream_name_offset) {
|
||||
read_string(bank_name, STREAM_NAME_SIZE, bank_name_offset, sf);
|
||||
read_string(stream_name, STREAM_NAME_SIZE, stream_name_offset, sf);
|
||||
snprintf(vgmstream->stream_name, STREAM_NAME_SIZE, "%s/%s", bank_name, stream_name);
|
||||
}
|
||||
|
||||
if (!vgmstream_open_stream(vgmstream, sf, start_offset))
|
||||
goto fail;
|
||||
|
@ -81,25 +81,24 @@ VGMSTREAM* init_vgmstream_vag(STREAMFILE* sf) {
|
||||
loop_flag = 0;
|
||||
break;
|
||||
|
||||
case 0x70474156: /* pGAV (little endian / stereo) [Jak 3 (PS2), Jak X (PS2)] */
|
||||
case 0x70474156: /* pGAV (little endian / stereo) [Jak II, Jak 3, Jak X (PS2)] */
|
||||
meta_type = meta_VAG_custom;
|
||||
start_offset = 0x30;
|
||||
|
||||
if (is_id32be(0x20,sf, "Ster")) {
|
||||
channels = 2;
|
||||
if (is_id32be(0x2000,sf, "pGAV"))
|
||||
interleave = 0x2000; /* Jak II & Jak 3 interleave, includes header */
|
||||
else if (is_id32be(0x1000,sf, "pGAV"))
|
||||
interleave = 0x1000; /* Jak X interleave, includes header */
|
||||
else
|
||||
interleave = 0;
|
||||
|
||||
if (is_id32be(0x2000,sf, "pGAV"))
|
||||
interleave = 0x2000; /* Jak 3 interleave, includes header */
|
||||
else if (is_id32be(0x1000,sf, "pGAV"))
|
||||
interleave = 0x1000; /* Jak X interleave, includes header */
|
||||
else
|
||||
goto fail;
|
||||
if (interleave) {
|
||||
channels = 2;
|
||||
interleave_first = interleave - start_offset; /* interleave includes header */
|
||||
interleave_first_skip = start_offset;
|
||||
}
|
||||
else {
|
||||
channels = 1;
|
||||
interleave = 0;
|
||||
}
|
||||
|
||||
channel_size = read_u32le(0x0C,sf) / channels;
|
||||
|
Loading…
x
Reference in New Issue
Block a user