Clean FSB5 for future changes, also fix >2.5GB last subsongs

This commit is contained in:
bnnm 2018-08-11 18:01:37 +02:00
parent 36db25e876
commit b27e559e42

View File

@ -2,18 +2,42 @@
#include "../coding/coding.h"
#include "../util.h"
typedef struct {
int total_subsongs;
int version;
int codec;
int flags;
int channel_count;
int sample_rate;
int32_t num_samples;
int32_t loop_start;
int32_t loop_end;
int loop_flag;
off_t sample_header_offset;
size_t sample_header_size;
size_t name_table_size;
size_t sample_data_size;
size_t base_header_size;
off_t extradata_offset;
size_t extradata_size;
off_t stream_offset;
size_t stream_size;
off_t name_offset;
} fsb5_header;
/* FSB5 - FMOD Studio multiplatform format */
VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL;
off_t StartOffset = 0, NameOffset = 0;
off_t SampleHeaderStart = 0, ExtraInfoStart = 0;
size_t SampleHeaderLength, NameTableLength, SampleDataLength, BaseHeaderLength, StreamSize = 0, ExtraInfoSize = 0;
uint32_t NumSamples = 0, LoopStart = 0, LoopEnd = 0;
int LoopFlag = 0, ChannelCount = 0, Version, SampleRate = 0, Codec, Flags = 0;
int TotalSubsongs, TargetSubsong = streamFile->stream_index;
fsb5_header fsb5 = {0};
int target_subsong = streamFile->stream_index;
int i;
/* check extension, case insensitive */
if (!check_extensions(streamFile,"fsb"))
goto fail;
@ -22,125 +46,125 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
goto fail;
/* 0x00 is rare (seen in Tales from Space Vita) */
Version = read_32bitLE(0x04,streamFile);
if (Version != 0x00 && Version != 0x01) goto fail;
fsb5.version = read_32bitLE(0x04,streamFile);
if (fsb5.version != 0x00 && fsb5.version != 0x01) goto fail;
TotalSubsongs = read_32bitLE(0x08,streamFile);
SampleHeaderLength = read_32bitLE(0x0C,streamFile);
NameTableLength = read_32bitLE(0x10,streamFile);
SampleDataLength = read_32bitLE(0x14,streamFile);
Codec = read_32bitLE(0x18,streamFile);
fsb5.total_subsongs = read_32bitLE(0x08,streamFile);
fsb5.sample_header_size = read_32bitLE(0x0C,streamFile);
fsb5.name_table_size = read_32bitLE(0x10,streamFile);
fsb5.sample_data_size = read_32bitLE(0x14,streamFile);
fsb5.codec = read_32bitLE(0x18,streamFile);
/* version 0x01 - 0x1c(4): zero, 0x24(16): hash, 0x34(8): unk
* version 0x00 has an extra field (always 0?) at 0x1c */
if (Version == 0x01) {
Flags = read_32bitLE(0x20,streamFile); /* found by tests and assumed to be flags, no games known */
if (fsb5.version == 0x01) {
/* found by tests and assumed to be flags, no games known */
fsb5.flags = read_32bitLE(0x20,streamFile);
}
BaseHeaderLength = (Version==0x00) ? 0x40 : 0x3C;
fsb5.base_header_size = (fsb5.version==0x00) ? 0x40 : 0x3C;
if ((SampleHeaderLength + NameTableLength + SampleDataLength + BaseHeaderLength) != get_streamfile_size(streamFile)) {
VGM_LOG("FSB5: bad size (%x + %x + %x + %x != %x)\n", SampleHeaderLength, NameTableLength, SampleDataLength, BaseHeaderLength, get_streamfile_size(streamFile));
if ((fsb5.sample_header_size + fsb5.name_table_size + fsb5.sample_data_size + fsb5.base_header_size) != get_streamfile_size(streamFile)) {
VGM_LOG("FSB5: bad size (%x + %x + %x + %x != %x)\n", fsb5.sample_header_size, fsb5.name_table_size, fsb5.sample_data_size, fsb5.base_header_size, get_streamfile_size(streamFile));
goto fail;
}
if (TargetSubsong == 0) TargetSubsong = 1;
if (TargetSubsong > TotalSubsongs || TotalSubsongs <= 0) goto fail;
if (target_subsong == 0) target_subsong = 1;
if (target_subsong > fsb5.total_subsongs || fsb5.total_subsongs <= 0) goto fail;
SampleHeaderStart = BaseHeaderLength;
fsb5.sample_header_offset = fsb5.base_header_size;
/* find target stream header and data offset, and read all needed values for later use
* (reads one by one as the size of a single stream header is variable) */
for (i = 1; i <= TotalSubsongs; i++) {
off_t DataStart = 0;
size_t StreamHeaderLength = 0;
uint32_t SampleMode1, SampleMode2; /* maybe one uint64? */
for (i = 1; i <= fsb5.total_subsongs; i++) {
size_t stream_header_size = 0;
off_t data_offset = 0;
uint32_t sample_mode1, sample_mode2; /* maybe one uint64? */
SampleMode1 = (uint32_t)read_32bitLE(SampleHeaderStart+0x00,streamFile);
SampleMode2 = (uint32_t)read_32bitLE(SampleHeaderStart+0x04,streamFile);
StreamHeaderLength += 0x08;
sample_mode1 = (uint32_t)read_32bitLE(fsb5.sample_header_offset+0x00,streamFile);
sample_mode2 = (uint32_t)read_32bitLE(fsb5.sample_header_offset+0x04,streamFile);
stream_header_size += 0x08;
/* get samples */
NumSamples = ((SampleMode2 >> 2) & 0x3FFFFFFF); /* bits2: 31..2 (30) */
fsb5.num_samples = ((sample_mode2 >> 2) & 0x3FFFFFFF); /* bits2: 31..2 (30) */
/* get offset inside data section */
/* up to 0x07FFFFFF * 0x20 = full 32b offset 0xFFFFFFE0 (recheck, after 0x80000000 some calcs may be off?) */
DataStart = ((SampleMode2 & 0x03) << 25) | ((SampleMode1 >> 7) & 0x1FFFFFF) << 5; /* bits2: 1..0 (2) | bits1: 31..8 (25) */
/* up to 0x07FFFFFF * 0x20 = full 32b offset 0xFFFFFFE0 */
data_offset = ((sample_mode2 & 0x03) << 25) | ((sample_mode1 >> 7) & 0x1FFFFFF) << 5; /* bits2: 1..0 (2) | bits1: 31..8 (25) */
/* get channels */
switch ((SampleMode1 >> 5) & 0x03) { /* bits1: 7..6 (2) */
case 0: ChannelCount = 1; break;
case 1: ChannelCount = 2; break;
case 2: ChannelCount = 6; break;/* some Dark Souls 2 MPEG; some IMA ADPCM */
case 3: ChannelCount = 8; break;/* some IMA ADPCM */
switch ((sample_mode1 >> 5) & 0x03) { /* bits1: 7..6 (2) */
case 0: fsb5.channel_count = 1; break;
case 1: fsb5.channel_count = 2; break;
case 2: fsb5.channel_count = 6; break; /* some Dark Souls 2 MPEG; some IMA ADPCM */
case 3: fsb5.channel_count = 8; break; /* some IMA ADPCM */
/* other channels (ex. 4/10/12ch) use 0 here + set extra flags */
default: /* not possible */
goto fail;
}
/* get sample rate */
switch ((SampleMode1 >> 1) & 0x0f) { /* bits1: 5..1 (4) */
case 0: SampleRate = 4000; break;
case 1: SampleRate = 8000; break;
case 2: SampleRate = 11000; break;
case 3: SampleRate = 11025; break;
case 4: SampleRate = 16000; break;
case 5: SampleRate = 22050; break;
case 6: SampleRate = 24000; break;
case 7: SampleRate = 32000; break;
case 8: SampleRate = 44100; break;
case 9: SampleRate = 48000; break;
case 10: SampleRate = 96000; break;
switch ((sample_mode1 >> 1) & 0x0f) { /* bits1: 5..1 (4) */
case 0: fsb5.sample_rate = 4000; break;
case 1: fsb5.sample_rate = 8000; break;
case 2: fsb5.sample_rate = 11000; break;
case 3: fsb5.sample_rate = 11025; break;
case 4: fsb5.sample_rate = 16000; break;
case 5: fsb5.sample_rate = 22050; break;
case 6: fsb5.sample_rate = 24000; break;
case 7: fsb5.sample_rate = 32000; break;
case 8: fsb5.sample_rate = 44100; break;
case 9: fsb5.sample_rate = 48000; break;
case 10: fsb5.sample_rate = 96000; break;
/* other sample rates (ex. 3000/64000/192000) use 0 here + set extra flags */
default: /* 11-15: rejected (FMOD error) */
goto fail;
}
/* get extra flags */
if (SampleMode1 & 0x01) { /* bits1: 0 (1) */
uint32_t ExtraFlag, ExtraFlagStart, ExtraFlagType, ExtraFlagSize, ExtraFlagEnd;
if (sample_mode1 & 0x01) { /* bits1: 0 (1) */
off_t extraflag_offset = fsb5.sample_header_offset+0x08;
uint32_t extraflag, extraflag_type, extraflag_size, extraflag_end;
ExtraFlagStart = SampleHeaderStart+0x08;
do {
ExtraFlag = read_32bitLE(ExtraFlagStart,streamFile);
ExtraFlagType = (ExtraFlag >> 25) & 0x7F; /* bits 32..26 (7) */
ExtraFlagSize = (ExtraFlag >> 1) & 0xFFFFFF; /* bits 25..1 (24)*/
ExtraFlagEnd = (ExtraFlag & 0x01); /* bit 0 (1) */
extraflag = read_32bitLE(extraflag_offset,streamFile);
extraflag_type = (extraflag >> 25) & 0x7F; /* bits 32..26 (7) */
extraflag_size = (extraflag >> 1) & 0xFFFFFF; /* bits 25..1 (24)*/
extraflag_end = (extraflag & 0x01); /* bit 0 (1) */
switch(ExtraFlagType) {
switch(extraflag_type) {
case 0x01: /* channels */
ChannelCount = read_8bit(ExtraFlagStart+0x04,streamFile);
fsb5.channel_count = read_8bit(extraflag_offset+0x04,streamFile);
break;
case 0x02: /* sample rate */
SampleRate = read_32bitLE(ExtraFlagStart+0x04,streamFile);
fsb5.sample_rate = read_32bitLE(extraflag_offset+0x04,streamFile);
break;
case 0x03: /* loop info */
LoopStart = read_32bitLE(ExtraFlagStart+0x04,streamFile);
if (ExtraFlagSize > 0x04) /* probably not needed */
LoopEnd = read_32bitLE(ExtraFlagStart+0x08,streamFile);
fsb5.loop_start = read_32bitLE(extraflag_offset+0x04,streamFile);
if (extraflag_size > 0x04) /* probably not needed */
fsb5.loop_end = read_32bitLE(extraflag_offset+0x08,streamFile);
/* when start is 0 seems the song repeats with no real looping (ex. Sonic Boom Fire & Ice jingles) */
LoopFlag = (LoopStart != 0x00);
fsb5.loop_flag = (fsb5.loop_start != 0x00);
break;
case 0x04: /* free comment, or maybe SFX info */
break;
//case 0x05: /* Unknown (32b) */
//case 0x05: /* Unknown (32b) */ //todo multistream marker?
// /* found in Tearaway Vita, value 0, first stream only */
// break;
case 0x06: /* XMA seek table */
/* no need for it */
break;
case 0x07: /* DSP coefs */
ExtraInfoStart = ExtraFlagStart + 0x04;
fsb5.extradata_offset = extraflag_offset + 0x04;
break;
case 0x09: /* ATRAC9 config */
ExtraInfoStart = ExtraFlagStart + 0x04;
ExtraInfoSize = ExtraFlagSize;
fsb5.extradata_offset = extraflag_offset + 0x04;
fsb5.extradata_size = extraflag_size;
break;
case 0x0a: /* XWMA config */
ExtraInfoStart = ExtraFlagStart + 0x04;
fsb5.extradata_offset = extraflag_offset + 0x04;
break;
case 0x0b: /* Vorbis setup ID and seek table */
ExtraInfoStart = ExtraFlagStart + 0x04;
fsb5.extradata_offset = extraflag_offset + 0x04;
/* seek table format:
* 0x08: table_size (total_entries = seek_table_size / (4+4)), not counting this value; can be 0
* 0x0C: sample number (only some samples are saved in the table)
@ -152,73 +176,78 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
// /* found in some XMA2/Vorbis/FADPCM */
// break;
default:
VGM_LOG("FSB5: unknown extra flag 0x%x at 0x%04x + 0x04 (size 0x%x)\n", ExtraFlagType, ExtraFlagStart, ExtraFlagSize);
VGM_LOG("FSB5: unknown extraflag 0x%x at %lx + 0x04 (size 0x%x)\n", extraflag_type, extraflag_offset, extraflag_size);
break;
}
ExtraFlagStart += 0x04 + ExtraFlagSize;
StreamHeaderLength += 0x04 + ExtraFlagSize;
} while (ExtraFlagEnd != 0x00);
extraflag_offset += 0x04 + extraflag_size;
stream_header_size += 0x04 + extraflag_size;
} while (extraflag_end != 0x00);
}
/* stream found */
if (i == TargetSubsong) {
StartOffset = BaseHeaderLength + SampleHeaderLength + NameTableLength + DataStart;
if (i == target_subsong) {
fsb5.stream_offset = fsb5.base_header_size + fsb5.sample_header_size + fsb5.name_table_size + data_offset;
/* get stream size from next stream or datasize if there is only one */
if (i == TotalSubsongs) {
StreamSize = SampleDataLength - DataStart;
} else {
uint32_t NextSampleMode = (uint32_t)read_32bitLE(SampleHeaderStart+StreamHeaderLength+0x00,streamFile);
StreamSize = (((NextSampleMode >> 7) & 0x00FFFFFF) << 5) - DataStart;
/* get stream size from next stream offset or full size if there is only one */
if (i == fsb5.total_subsongs) {
fsb5.stream_size = fsb5.sample_data_size - data_offset;
}
else {
off_t next_data_offset;
uint32_t next_sample_mode1, next_sample_mode2;
next_sample_mode1 = (uint32_t)read_32bitLE(fsb5.sample_header_offset+stream_header_size+0x00,streamFile);
next_sample_mode2 = (uint32_t)read_32bitLE(fsb5.sample_header_offset+stream_header_size+0x04,streamFile);
next_data_offset = ((next_sample_mode2 & 0x03) << 25) | ((next_sample_mode1 >> 7) & 0x1FFFFFF) << 5;
fsb5.stream_size = next_data_offset - data_offset;
}
break;
}
/* continue searching */
SampleHeaderStart += StreamHeaderLength;
fsb5.sample_header_offset += stream_header_size;
}
/* target stream not found*/
if (!StartOffset || !StreamSize) goto fail;
if (!fsb5.stream_offset || !fsb5.stream_size) goto fail;
/* get stream name */
if (NameTableLength) {
NameOffset = BaseHeaderLength + SampleHeaderLength + read_32bitLE(BaseHeaderLength + SampleHeaderLength + 0x04*(TargetSubsong-1),streamFile);
if (fsb5.name_table_size) {
off_t name_suboffset = fsb5.base_header_size + fsb5.sample_header_size + 0x04*(target_subsong-1);
fsb5.name_offset = fsb5.base_header_size + fsb5.sample_header_size + read_32bitLE(name_suboffset,streamFile);
}
/* build the VGMSTREAM */
vgmstream = allocate_vgmstream(ChannelCount,LoopFlag);
vgmstream = allocate_vgmstream(fsb5.channel_count,fsb5.loop_flag);
if (!vgmstream) goto fail;
vgmstream->sample_rate = SampleRate;
vgmstream->num_samples = NumSamples;
if (LoopFlag) {
vgmstream->loop_start_sample = LoopStart;
vgmstream->loop_end_sample = LoopEnd;
vgmstream->sample_rate = fsb5.sample_rate;
vgmstream->num_samples = fsb5.num_samples;
if (fsb5.loop_flag) {
vgmstream->loop_start_sample = fsb5.loop_start;
vgmstream->loop_end_sample = fsb5.loop_end;
}
vgmstream->num_streams = TotalSubsongs;
vgmstream->stream_size = StreamSize;
vgmstream->num_streams = fsb5.total_subsongs;
vgmstream->stream_size = fsb5.stream_size;
vgmstream->meta_type = meta_FSB5;
if (NameOffset)
read_string(vgmstream->stream_name,STREAM_NAME_SIZE, NameOffset,streamFile);
if (fsb5.name_offset)
read_string(vgmstream->stream_name,STREAM_NAME_SIZE, fsb5.name_offset,streamFile);
/* parse codec */
switch (Codec) {
switch (fsb5.codec) {
case 0x00: /* FMOD_SOUND_FORMAT_NONE */
goto fail;
case 0x01: /* FMOD_SOUND_FORMAT_PCM8 [Anima - Gate of Memories (PC)] */
vgmstream->coding_type = coding_PCM8_U;
vgmstream->layout_type = ChannelCount == 1 ? layout_none : layout_interleave;
vgmstream->layout_type = fsb5.channel_count == 1 ? layout_none : layout_interleave;
vgmstream->interleave_block_size = 0x01;
break;
case 0x02: /* FMOD_SOUND_FORMAT_PCM16 [Shantae Risky's Revenge (PC)] */
vgmstream->coding_type = (Flags & 0x01) ? coding_PCM16BE : coding_PCM16LE;
vgmstream->layout_type = ChannelCount == 1 ? layout_none : layout_interleave;
vgmstream->coding_type = (fsb5.flags & 0x01) ? coding_PCM16BE : coding_PCM16LE;
vgmstream->layout_type = fsb5.channel_count == 1 ? layout_none : layout_interleave;
vgmstream->interleave_block_size = 0x02;
break;
@ -232,23 +261,22 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
case 0x05: /* FMOD_SOUND_FORMAT_PCMFLOAT [Anima: Gate of Memories (PC)] */
vgmstream->coding_type = coding_PCMFLOAT;
vgmstream->layout_type = (ChannelCount == 1) ? layout_none : layout_interleave;
vgmstream->layout_type = (fsb5.channel_count == 1) ? layout_none : layout_interleave;
vgmstream->interleave_block_size = 0x04;
break;
case 0x06: /* FMOD_SOUND_FORMAT_GCADPCM [Sonic Boom: Fire and Ice (3DS)] */
if (Flags & 0x02) { /* non-interleaved mode */
if (fsb5.flags & 0x02) { /* non-interleaved mode */
vgmstream->coding_type = coding_NGC_DSP;
vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = (StreamSize / ChannelCount);
vgmstream->interleave_block_size = (fsb5.stream_size / fsb5.channel_count);
}
else {
vgmstream->coding_type = coding_NGC_DSP_subint;
vgmstream->layout_type = layout_none;
vgmstream->interleave_block_size = 0x02;
}
dsp_read_coefs_be(vgmstream,streamFile,ExtraInfoStart,0x2E);
dsp_read_coefs_be(vgmstream,streamFile,fsb5.extradata_offset,0x2E);
break;
case 0x07: /* FMOD_SOUND_FORMAT_IMAADPCM [Skylanders] */
@ -259,8 +287,8 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
case 0x08: /* FMOD_SOUND_FORMAT_VAG [from fsbankex tests, no known games] */
vgmstream->coding_type = coding_PSX;
vgmstream->layout_type = layout_interleave;
if (Flags & 0x02) { /* non-interleaved mode */
vgmstream->interleave_block_size = (StreamSize / ChannelCount);
if (fsb5.flags & 0x02) { /* non-interleaved mode */
vgmstream->interleave_block_size = (fsb5.stream_size / fsb5.channel_count);
}
else {
vgmstream->interleave_block_size = 0x10;
@ -279,10 +307,10 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
int bytes, block_size, block_count;
block_size = 0x8000; /* FSB default */
block_count = StreamSize / block_size + (StreamSize % block_size ? 1 : 0);
block_count = fsb5.stream_size / block_size + (fsb5.stream_size % block_size ? 1 : 0);
bytes = ffmpeg_make_riff_xma2(buf, 0x100, vgmstream->num_samples, StreamSize, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, StartOffset,StreamSize);
bytes = ffmpeg_make_riff_xma2(buf, 0x100, vgmstream->num_samples, fsb5.stream_size, vgmstream->channels, vgmstream->sample_rate, block_count, block_size);
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, fsb5.stream_offset,fsb5.stream_size);
if ( !vgmstream->codec_data ) goto fail;
vgmstream->coding_type = coding_FFmpeg;
vgmstream->layout_type = layout_none;
@ -296,14 +324,14 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
cfg.fsb_padding = (vgmstream->channels > 2 ? 16 : 4); /* observed default */
vgmstream->codec_data = init_mpeg_custom(streamFile, StartOffset, &vgmstream->coding_type, vgmstream->channels, MPEG_FSB, &cfg);
vgmstream->codec_data = init_mpeg_custom(streamFile, fsb5.stream_offset, &vgmstream->coding_type, vgmstream->channels, MPEG_FSB, &cfg);
if (!vgmstream->codec_data) goto fail;
vgmstream->layout_type = layout_none;
break;
}
#endif
case 0x0C: /* FMOD_SOUND_FORMAT_CELT [BIT.TRIP Presents Runner2 (PC), Full Bore (PC)] */
VGM_LOG("FSB5: FMOD_SOUND_FORMAT_CELT found\n");
goto fail;
#ifdef VGM_USE_ATRAC9
@ -311,20 +339,20 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
atrac9_config cfg = {0};
cfg.channels = vgmstream->channels;
switch(ExtraInfoSize) {
switch(fsb5.extradata_size) {
case 0x04: /* Little Big Planet 2ch (Vita), Guacamelee (Vita) */
cfg.config_data = read_32bitBE(ExtraInfoStart,streamFile);
cfg.config_data = read_32bitBE(fsb5.extradata_offset,streamFile);
break;
case 0x08: /* Day of the Tentacle Remastered (Vita) */
/* 0x00: superframe size (also in config_data) */
cfg.config_data = read_32bitBE(ExtraInfoStart+0x04,streamFile);
cfg.config_data = read_32bitBE(fsb5.extradata_offset+0x04,streamFile);
break;
//case 0x0c: /* Little Big Planet 6ch (Vita) */
// //todo: this is just 0x04 x3, in case of 4ch would be 0x08 --must improve detection
// //each stream has its own config_data (but seem to be the same), interleaves 1 super frame per stream
// break;
default:
VGM_LOG("FSB5: unknown extra info size 0x%x\n", ExtraInfoSize);
VGM_LOG("FSB5: unknown extra info size 0x%x\n", fsb5.extradata_size);
goto fail;
}
//cfg.encoder_delay = 0x100; //todo not used? num_samples seems to count all data
@ -342,14 +370,14 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
uint8_t buf[0x100];
int bytes, format, average_bps, block_align;
format = read_16bitBE(ExtraInfoStart+0x00,streamFile);
block_align = (uint16_t)read_16bitBE(ExtraInfoStart+0x02,streamFile);
average_bps = (uint32_t)read_32bitBE(ExtraInfoStart+0x04,streamFile);
format = read_16bitBE(fsb5.extradata_offset+0x00,streamFile);
block_align = (uint16_t)read_16bitBE(fsb5.extradata_offset+0x02,streamFile);
average_bps = (uint32_t)read_32bitBE(fsb5.extradata_offset+0x04,streamFile);
/* rest: seek entries + mini seek table? */
/* XWMA encoder only does up to 6ch (doesn't use FSB multistreams for more) */
bytes = ffmpeg_make_riff_xwma(buf,0x100, format, StreamSize, vgmstream->channels, vgmstream->sample_rate, average_bps, block_align);
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, StartOffset,StreamSize);
bytes = ffmpeg_make_riff_xwma(buf,0x100, format, fsb5.stream_size, vgmstream->channels, vgmstream->sample_rate, average_bps, block_align);
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, fsb5.stream_offset,fsb5.stream_size);
if ( !vgmstream->codec_data ) goto fail;
vgmstream->coding_type = coding_FFmpeg;
vgmstream->layout_type = layout_none;
@ -363,11 +391,11 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
cfg.channels = vgmstream->channels;
cfg.sample_rate = vgmstream->sample_rate;
cfg.setup_id = read_32bitLE(ExtraInfoStart,streamFile);
cfg.setup_id = read_32bitLE(fsb5.extradata_offset,streamFile);
vgmstream->layout_type = layout_none;
vgmstream->coding_type = coding_VORBIS_custom;
vgmstream->codec_data = init_vorbis_custom(streamFile, StartOffset, VORBIS_FSB, &cfg);
vgmstream->codec_data = init_vorbis_custom(streamFile, fsb5.stream_offset, VORBIS_FSB, &cfg);
if (!vgmstream->codec_data) goto fail;
break;
@ -381,11 +409,11 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
break;
default:
VGM_LOG("FSB5: unknown codec %x found\n", Codec);
VGM_LOG("FSB5: unknown codec %x found\n", fsb5.codec);
goto fail;
}
if (!vgmstream_open_stream(vgmstream,streamFile,StartOffset))
if (!vgmstream_open_stream(vgmstream,streamFile,fsb5.stream_offset))
goto fail;
return vgmstream;