mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-20 20:41:08 +01:00
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:
parent
3db9b74e4c
commit
1f2132ac3f
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user