meta/brstm.c: Parse ADPCM header offset for each channel instead of skipping a fixed distance

The parser previously computed the offset of the coefficients field of
channel 0's ADPCM header and then skipped 0x38 bytes to get to the
coefficients field of the next channel's ADPCM header. This breaks for
some files because they have larger 0x3a byte ACPCM headers.

This commit updates the logic to compute the offset of each channel's
ADPCM header. Immediately after the HEAD part 3 header, there's an
8-byte table for each channel, where the second field indicates the
offset of that channel's ADPCM header. With this information, it's just
a matter of adding 0x08 to get the coefficients field.

Fixes: #674

Signed-off-by: Andrew Gunnerson <chillermillerlong@hotmail.com>
This commit is contained in:
Andrew Gunnerson 2020-07-24 21:36:04 -04:00
parent 3db9b74e4c
commit 1f2132ac3f
No known key found for this signature in database
GPG Key ID: 14200B173D8A3BF5

View File

@ -106,26 +106,39 @@ VGMSTREAM * init_vgmstream_brstm(STREAMFILE *streamFile) {
if (vgmstream->coding_type == coding_NGC_DSP) {
off_t coef_offset;
off_t coef_offset1;
off_t coef_offset2;
off_t head_part3_offset;
off_t adpcm_header_offset;
int i,j;
int coef_spacing = 0x38;
int coef_spacing;
if (atlus_shrunken_head)
{
coef_offset = 0x50;
coef_spacing = 0x30;
for (j = 0; j < vgmstream->channels; j++) {
for (i = 0; i < 16; i++) {
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(head_offset + coef_offset + j * coef_spacing + i * 2,streamFile);
}
}
}
else
{
coef_offset1=read_32bitBE(head_offset+0x1c,streamFile);
coef_offset2=read_32bitBE(head_offset+0x10+coef_offset1,streamFile);
coef_offset=coef_offset2+0x10;
}
head_part3_offset = read_32bitBE(head_offset + 0x1c, streamFile);
for (j=0;j<vgmstream->channels;j++) {
for (i=0;i<16;i++) {
vgmstream->ch[j].adpcm_coef[i]=read_16bitBE(head_offset+coef_offset+j*coef_spacing+i*2,streamFile);
for (j = 0; j < vgmstream->channels; j++) {
adpcm_header_offset = head_offset + 0x08
+ head_part3_offset + 0x04 /* skip over HEAD part 3 */
+ j * 0x08 /* skip to channel's ADPCM offset table */
+ 0x04; /* ADPCM header offset field */
coef_offset = head_offset + 0x08
+ read_32bitBE(adpcm_header_offset, streamFile)
+ 0x08; /* coeffs field */
for (i = 0; i < 16; i++) {
vgmstream->ch[j].adpcm_coef[i] = read_16bitBE(coef_offset + i * 2, streamFile);
}
}
}
}