Fix SNDS with CBD2 [Battle Tryst (Arcade)]

This commit is contained in:
bnnm 2020-12-01 23:25:13 +01:00
parent 2135fea36d
commit 54340f9bcd
2 changed files with 39 additions and 44 deletions

View File

@ -1,54 +1,39 @@
#include "layout.h" #include "layout.h"
#include "../vgmstream.h" #include "../vgmstream.h"
/* set up for the block at the given offset */
void block_update_str_snds(off_t block_offset, VGMSTREAM * vgmstream) { void block_update_str_snds(off_t block_offset, VGMSTREAM* vgmstream) {
off_t current_chunk; STREAMFILE* sf = vgmstream->ch[0].streamfile;
size_t file_size; uint32_t block_type, block_subtype, block_size, block_current;
int i; int i;
STREAMFILE *streamfile;
int FoundSSMP = 0;
off_t SSMP_offset = -1;
current_chunk = block_offset; /* EOF reads: signal we have nothing and let the layout fail */
streamfile = vgmstream->ch[0].streamfile; if (block_offset >= get_streamfile_size(sf)) {
file_size = get_streamfile_size(streamfile); vgmstream->current_block_samples = -1;
return;
}
/* we may have to skip some chunks */
while (!FoundSSMP && current_chunk < file_size) { block_type = read_u32be(block_offset + 0x00,sf);
if (current_chunk+read_32bitBE(current_chunk+4,streamfile)>=file_size) block_size = read_u32be(block_offset + 0x04,sf);
break;
switch (read_32bitBE(current_chunk,streamfile)) { block_current = 0; /* ignore block by default (other chunks include MPVD + VHDR/FRAM and FILL) */
case 0x534e4453: /* SNDS */ if (block_type == 0x534e4453) { /* SNDS */
/* SSMP */ block_subtype = read_u32be(block_offset + 0x10,sf); /* SNDS */
if (read_32bitBE(current_chunk+0x10,streamfile)==0x53534d50) { if (block_subtype == 0x53534d50) {
FoundSSMP = 1; block_current = read_u32be(block_offset + 0x14, sf) / vgmstream->channels;
SSMP_offset = current_chunk;
}
break;
case 0x46494c4c: /* FILL, the main culprit */
default:
break;
} }
current_chunk += read_32bitBE(current_chunk+4,streamfile);
} }
if (!FoundSSMP) { /* seen in Battle Tryst video frames */
/* if we couldn't find it all we can do is try playing the current if (block_size % 0x04)
* block, which is going to suck */ block_size += 0x04 - (block_size % 0x04);
vgmstream->current_block_offset = block_offset;
}
vgmstream->current_block_offset = SSMP_offset; vgmstream->current_block_offset = block_offset;
vgmstream->current_block_size = (read_32bitBE( vgmstream->next_block_offset = block_offset + block_size;
vgmstream->current_block_offset+4, vgmstream->current_block_size = block_current;
vgmstream->ch[0].streamfile) - 0x18) / vgmstream->channels;
vgmstream->next_block_offset = vgmstream->current_block_offset +
read_32bitBE(vgmstream->current_block_offset+4,
vgmstream->ch[0].streamfile);
for (i = 0; i < vgmstream->channels; i++) { for (i = 0; i < vgmstream->channels; i++) {
vgmstream->ch[i].offset = vgmstream->current_block_offset + 0x18 + i * vgmstream->interleave_block_size; vgmstream->ch[i].offset = block_offset + 0x18 + i * vgmstream->interleave_block_size;
} }
} }

View File

@ -13,10 +13,10 @@ VGMSTREAM* init_vgmstream_str_snds(STREAMFILE* sf) {
/* checks */ /* checks */
/* .str: standard /* .str: standard
* .stream: Battle Tryst (Arcade) movies
* .3do: Aqua World - Umimi Monogatari (3DO) movies */ * .3do: Aqua World - Umimi Monogatari (3DO) movies */
if (!check_extensions(sf, "str,3do")) if (!check_extensions(sf, "str,stream,3do"))
goto fail; goto fail;
if (read_u32be(0x00,sf) != 0x4354524c && /* "CTRL" */ if (read_u32be(0x00,sf) != 0x4354524c && /* "CTRL" */
read_u32be(0x00,sf) != 0x534e4453 && /* "SNDS" */ read_u32be(0x00,sf) != 0x534e4453 && /* "SNDS" */
read_u32be(0x00,sf) != 0x53484452) /* "SHDR" */ read_u32be(0x00,sf) != 0x53484452) /* "SHDR" */
@ -96,14 +96,24 @@ VGMSTREAM* init_vgmstream_str_snds(STREAMFILE* sf) {
vgmstream->num_samples /= vgmstream->channels; vgmstream->num_samples /= vgmstream->channels;
switch (read_u32be(shdr_offset + 0x24,sf)) { switch (read_u32be(shdr_offset + 0x24,sf)) {
case 0x53445832: /* "SDX2" */ case 0x53445832: /* "SDX2" (common) */
if (channels > 1) { if (channels > 1) {
vgmstream->coding_type = coding_SDX2_int; vgmstream->coding_type = coding_SDX2_int;
vgmstream->interleave_block_size = 1; vgmstream->interleave_block_size = 0x01;
} else { } else {
vgmstream->coding_type = coding_SDX2; vgmstream->coding_type = coding_SDX2;
} }
break; break;
case 0x43424432: /* "CBD2" (rare, Battle Tryst) */
if (channels > 1) {
vgmstream->coding_type = coding_CBD2_int;
vgmstream->interleave_block_size = 0x01;
} else {
vgmstream->coding_type = coding_CBD2; /* assumed */
}
break;
default: default:
goto fail; goto fail;
} }