Fix bitrate for subsongs and rename streams > subsongs

This commit is contained in:
bnnm 2018-01-28 00:41:25 +01:00
parent 694cded587
commit 528b5c3197
18 changed files with 167 additions and 147 deletions

View File

@ -7,7 +7,7 @@ typedef struct {
int is_encrypted; int is_encrypted;
int is_music; int is_music;
int total_streams; int total_subsongs;
int channel_count; int channel_count;
int sample_rate; int sample_rate;
@ -47,7 +47,8 @@ VGMSTREAM * init_vgmstream_awc(STREAMFILE *streamFile) {
vgmstream->sample_rate = awc.sample_rate; vgmstream->sample_rate = awc.sample_rate;
vgmstream->num_samples = awc.num_samples; vgmstream->num_samples = awc.num_samples;
vgmstream->num_streams = awc.total_streams; vgmstream->num_streams = awc.total_subsongs;
vgmstream->stream_size = awc.stream_size;
vgmstream->meta_type = meta_AWC; vgmstream->meta_type = meta_AWC;
@ -113,7 +114,7 @@ static int parse_awc_header(STREAMFILE* streamFile, awc_header* awc) {
int i, ch, entries; int i, ch, entries;
uint32_t flags, info_header, tag_count = 0, tags_skip = 0; uint32_t flags, info_header, tag_count = 0, tags_skip = 0;
off_t off; off_t off;
int target_stream = streamFile->stream_index; int target_subsong = streamFile->stream_index;
memset(awc,0,sizeof(awc_header)); memset(awc,0,sizeof(awc_header));
@ -161,13 +162,13 @@ static int parse_awc_header(STREAMFILE* streamFile, awc_header* awc) {
* Music seems layered (N-1/2 stereo pairs), maybe set with events? */ * Music seems layered (N-1/2 stereo pairs), maybe set with events? */
awc->is_music = (read_32bit(off + 0x00,streamFile) & 0x1FFFFFFF) == 0x00000000; awc->is_music = (read_32bit(off + 0x00,streamFile) & 0x1FFFFFFF) == 0x00000000;
if (awc->is_music) { /* all streams except id 0 is a channel */ if (awc->is_music) { /* all streams except id 0 is a channel */
awc->total_streams = 1; awc->total_subsongs = 1;
target_stream = 1; /* we only need id 0, though channels may have its own tags/chunks */ target_subsong = 1; /* we only need id 0, though channels may have its own tags/chunks */
} }
else { /* each stream is a single sound */ else { /* each stream is a single sound */
awc->total_streams = entries; awc->total_subsongs = entries;
if (target_stream == 0) target_stream = 1; if (target_subsong == 0) target_subsong = 1;
if (target_stream < 0 || target_stream > awc->total_streams || awc->total_streams < 1) goto fail; if (target_subsong < 0 || target_subsong > awc->total_subsongs || awc->total_subsongs < 1) goto fail;
} }
@ -176,7 +177,7 @@ static int parse_awc_header(STREAMFILE* streamFile, awc_header* awc) {
info_header = read_32bit(off + 0x04*i, streamFile); info_header = read_32bit(off + 0x04*i, streamFile);
tag_count = (info_header >> 29) & 0x7; /* 3b */ tag_count = (info_header >> 29) & 0x7; /* 3b */
//id = (info_header >> 0) & 0x1FFFFFFF; /* 29b */ //id = (info_header >> 0) & 0x1FFFFFFF; /* 29b */
if (target_stream-1 == i) if (target_subsong-1 == i)
break; break;
tags_skip += tag_count; /* tags to skip to reach target's tags, in the next header */ tags_skip += tag_count; /* tags to skip to reach target's tags, in the next header */
} }

View File

@ -2,13 +2,14 @@
#include "../coding/coding.h" #include "../coding/coding.h"
#include "../util.h" #include "../util.h"
static int bink_get_info(STREAMFILE *streamFile, int * out_total_streams, int * out_channel_count, int * out_sample_rate, int * out_num_samples); static int bink_get_info(STREAMFILE *streamFile, int * out_total_streams, size_t *out_stream_size, int * out_channel_count, int * out_sample_rate, int * out_num_samples);
/* BINK 1/2 - RAD Game Tools movies (audio/video format) */ /* BINK 1/2 - RAD Game Tools movies (audio/video format) */
VGMSTREAM * init_vgmstream_bik(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_bik(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
int channel_count = 0, loop_flag = 0, sample_rate = 0, num_samples = 0, total_streams = 0; int channel_count = 0, loop_flag = 0, sample_rate = 0, num_samples = 0;
int stream_index = streamFile->stream_index; int total_subsongs = 0, stream_index = streamFile->stream_index;
size_t stream_size;
/* check extension, case insensitive (bika = manually demuxed audio) */ /* check extension, case insensitive (bika = manually demuxed audio) */
@ -19,7 +20,7 @@ VGMSTREAM * init_vgmstream_bik(STREAMFILE *streamFile) {
(read_32bitBE(0x00,streamFile) & 0xffffff00) != 0x4B423200 ) goto fail; (read_32bitBE(0x00,streamFile) & 0xffffff00) != 0x4B423200 ) goto fail;
/* find target stream info and samples */ /* find target stream info and samples */
if (!bink_get_info(streamFile, &total_streams, &channel_count, &sample_rate, &num_samples)) if (!bink_get_info(streamFile, &total_subsongs, &stream_size, &channel_count, &sample_rate, &num_samples))
goto fail; goto fail;
/* build the VGMSTREAM */ /* build the VGMSTREAM */
@ -29,7 +30,8 @@ VGMSTREAM * init_vgmstream_bik(STREAMFILE *streamFile) {
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;
vgmstream->sample_rate = sample_rate; vgmstream->sample_rate = sample_rate;
vgmstream->num_samples = num_samples; vgmstream->num_samples = num_samples;
vgmstream->num_streams = total_streams; vgmstream->num_streams = total_subsongs;
vgmstream->stream_size = stream_size;
vgmstream->meta_type = meta_BINK; vgmstream->meta_type = meta_BINK;
#ifdef VGM_USE_FFMPEG #ifdef VGM_USE_FFMPEG
@ -58,12 +60,13 @@ fail:
* as they are not in the main header. The header for BINK1 and 2 is the same. * as they are not in the main header. The header for BINK1 and 2 is the same.
* (a ~3 min movie needs ~6000-7000 frames = fseeks, should be fast enough) * (a ~3 min movie needs ~6000-7000 frames = fseeks, should be fast enough)
*/ */
static int bink_get_info(STREAMFILE *streamFile, int * out_total_streams, int * out_channel_count, int * out_sample_rate, int * out_num_samples) { static int bink_get_info(STREAMFILE *streamFile, int * out_total_subsongs, size_t * out_stream_size, int * out_channel_count, int * out_sample_rate, int * out_num_samples) {
uint32_t *offsets = NULL; uint32_t *offsets = NULL;
uint32_t num_frames, num_samples_b = 0; uint32_t num_frames, num_samples_b = 0;
off_t cur_offset; off_t cur_offset;
int i, j, sample_rate, channel_count; int i, j, sample_rate, channel_count;
int total_streams, target_stream = streamFile->stream_index; int total_subsongs, target_subsong = streamFile->stream_index;
size_t stream_size = 0;
size_t filesize = get_streamfile_size(streamFile); size_t filesize = get_streamfile_size(streamFile);
uint32_t signature = (read_32bitBE(0x00,streamFile) & 0xffffff00); uint32_t signature = (read_32bitBE(0x00,streamFile) & 0xffffff00);
@ -76,20 +79,20 @@ static int bink_get_info(STREAMFILE *streamFile, int * out_total_streams, int *
if (num_frames == 0 || num_frames > 0x100000) goto fail; /* something must be off (avoids big allocs below) */ if (num_frames == 0 || num_frames > 0x100000) goto fail; /* something must be off (avoids big allocs below) */
/* multichannel/multilanguage audio is usually N streams of stereo/mono, no way to know channel layout */ /* multichannel/multilanguage audio is usually N streams of stereo/mono, no way to know channel layout */
total_streams = read_32bitLE(0x28,streamFile); total_subsongs = read_32bitLE(0x28,streamFile);
if (target_stream == 0) target_stream = 1; if (target_subsong == 0) target_subsong = 1;
if (target_stream < 0 || target_stream > total_streams || total_streams < 1 || total_streams > 255) goto fail; if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1 || total_subsongs > 255) goto fail;
/* find stream info and position in offset table */ /* find stream info and position in offset table */
cur_offset = 0x2c; cur_offset = 0x2c;
if ((signature == 0x42494B00 && (revision == 0x6b)) || /* k */ if ((signature == 0x42494B00 && (revision == 0x6b)) || /* k */
(signature == 0x4B423200 && (revision == 0x69 || revision == 0x6a || revision == 0x6b))) /* i,j,k */ (signature == 0x4B423200 && (revision == 0x69 || revision == 0x6a || revision == 0x6b))) /* i,j,k */
cur_offset += 0x04; /* unknown v2 header field */ cur_offset += 0x04; /* unknown v2 header field */
cur_offset += 0x04*total_streams; /* skip streams max packet bytes */ cur_offset += 0x04*total_subsongs; /* skip streams max packet bytes */
sample_rate = (uint16_t)read_16bitLE(cur_offset+0x04*(target_stream-1)+0x00,streamFile); sample_rate = (uint16_t)read_16bitLE(cur_offset+0x04*(target_subsong-1)+0x00,streamFile);
channel_count = (uint16_t)read_16bitLE(cur_offset+0x04*(target_stream-1)+0x02,streamFile) & 0x2000 ? 2 : 1; /* stereo flag */ channel_count = (uint16_t)read_16bitLE(cur_offset+0x04*(target_subsong-1)+0x02,streamFile) & 0x2000 ? 2 : 1; /* stereo flag */
cur_offset += 0x04*total_streams; /* skip streams info */ cur_offset += 0x04*total_subsongs; /* skip streams info */
cur_offset += 0x04*total_streams; /* skip streams ids */ cur_offset += 0x04*total_subsongs; /* skip streams ids */
/* read frame offsets in a buffer, to avoid fseeking to the table back and forth */ /* read frame offsets in a buffer, to avoid fseeking to the table back and forth */
@ -111,10 +114,11 @@ static int bink_get_info(STREAMFILE *streamFile, int * out_total_streams, int *
cur_offset = offsets[i]; cur_offset = offsets[i];
/* read audio packet headers per stream */ /* read audio packet headers per stream */
for (j=0; j < total_streams; j++) { for (j=0; j < total_subsongs; j++) {
uint32_t ap_size = read_32bitLE(cur_offset+0x00,streamFile); /* not counting this int */ uint32_t ap_size = read_32bitLE(cur_offset+0x00,streamFile); /* not counting this int */
if (j == target_stream-1) { if (j == target_subsong-1) {
stream_size += 0x04 + ap_size;
if (ap_size > 0) if (ap_size > 0)
num_samples_b += read_32bitLE(cur_offset+0x04,streamFile); /* decoded samples in bytes */ num_samples_b += read_32bitLE(cur_offset+0x04,streamFile); /* decoded samples in bytes */
break; /* next frame */ break; /* next frame */
@ -128,7 +132,8 @@ static int bink_get_info(STREAMFILE *streamFile, int * out_total_streams, int *
free(offsets); free(offsets);
if (out_total_streams) *out_total_streams = total_streams; if (out_total_subsongs) *out_total_subsongs = total_subsongs;
if (out_stream_size) *out_stream_size = stream_size;
if (out_sample_rate) *out_sample_rate = sample_rate; if (out_sample_rate) *out_sample_rate = sample_rate;
if (out_channel_count) *out_channel_count = channel_count; if (out_channel_count) *out_channel_count = channel_count;
//todo returns a few more samples (~48) than binkconv.exe? //todo returns a few more samples (~48) than binkconv.exe?

View File

@ -7,7 +7,8 @@ VGMSTREAM * init_vgmstream_flx(STREAMFILE *streamFile) {
off_t start_offset, stream_offset = 0; off_t start_offset, stream_offset = 0;
size_t data_size; size_t data_size;
int loop_flag, channel_count, codec; int loop_flag, channel_count, codec;
int total_streams = 0, target_stream = streamFile->stream_index; int total_subsongs = 0, target_subsong = streamFile->stream_index;
size_t stream_size = 0;
/* check extensions (.flx: name of archive, files inside don't have extensions) */ /* check extensions (.flx: name of archive, files inside don't have extensions) */
@ -24,23 +25,26 @@ VGMSTREAM * init_vgmstream_flx(STREAMFILE *streamFile) {
|| read_32bitLE(0x58,streamFile) != get_streamfile_size(streamFile)) || read_32bitLE(0x58,streamFile) != get_streamfile_size(streamFile))
goto fail; goto fail;
if (target_stream == 0) target_stream = 1; if (target_subsong == 0) target_subsong = 1;
for (i = 0; i < entries; i++) { for (i = 0; i < entries; i++) {
off_t entry_offset = read_32bitLE(offset + 0x00, streamFile); off_t entry_offset = read_32bitLE(offset + 0x00, streamFile);
/* 0x04: stream size */ size_t entry_size = read_32bitLE(offset + 0x04, streamFile);
offset += 0x08; offset += 0x08;
if (entry_offset != 0x00) if (entry_offset != 0x00)
total_streams++; /* many entries are empty */ total_subsongs++; /* many entries are empty */
if (total_streams == target_stream && stream_offset == 0) if (total_subsongs == target_subsong && stream_offset == 0) {
stream_offset = entry_offset; /* found but let's keep adding total_streams */ stream_offset = entry_offset; /* found but let's keep adding total_streams */
stream_size = entry_size;
}
} }
if (target_stream < 0 || target_stream > total_streams || total_streams < 1) goto fail; if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
if (stream_offset == 0x00) goto fail; if (stream_offset == 0x00) goto fail;
} }
else { else {
stream_offset = 0x00; stream_offset = 0x00;
stream_size = get_streamfile_size(streamFile);
} }
if (read_32bitLE(stream_offset + 0x30,streamFile) != 0x10) if (read_32bitLE(stream_offset + 0x30,streamFile) != 0x10)
@ -57,7 +61,8 @@ VGMSTREAM * init_vgmstream_flx(STREAMFILE *streamFile) {
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
vgmstream->sample_rate = read_32bitLE(stream_offset + 0x2c,streamFile); vgmstream->sample_rate = read_32bitLE(stream_offset + 0x2c,streamFile);
vgmstream->num_streams = total_streams; vgmstream->num_streams = total_subsongs;
vgmstream->stream_size = stream_size;
vgmstream->meta_type = meta_PC_FLX; vgmstream->meta_type = meta_PC_FLX;
switch(codec) { switch(codec) {

View File

@ -100,7 +100,7 @@ VGMSTREAM * init_vgmstream_fsb(STREAMFILE *streamFile) {
off_t start_offset; off_t start_offset;
size_t custom_data_offset; size_t custom_data_offset;
int loop_flag = 0; int loop_flag = 0;
int target_stream = streamFile->stream_index; int target_subsong = streamFile->stream_index;
fsb_header fsb = {0}; fsb_header fsb = {0};
@ -185,8 +185,8 @@ VGMSTREAM * init_vgmstream_fsb(STREAMFILE *streamFile) {
} }
if (fsb.sample_header_size < fsb.sample_header_min) goto fail; if (fsb.sample_header_size < fsb.sample_header_min) goto fail;
if (target_stream == 0) target_stream = 1; if (target_subsong == 0) target_subsong = 1;
if (target_stream < 0 || target_stream > fsb.total_subsongs || fsb.total_subsongs < 1) goto fail; if (target_subsong < 0 || target_subsong > fsb.total_subsongs || fsb.total_subsongs < 1) goto fail;
/* sample header (N-stream) */ /* sample header (N-stream) */
{ {
@ -210,7 +210,7 @@ VGMSTREAM * init_vgmstream_fsb(STREAMFILE *streamFile) {
/* FSB3.1/4: 0x40:mindistance 0x44:maxdistance 0x48:varfreq/size_32bits 0x4c:varvol 0x4e:fsb.varpan */ /* FSB3.1/4: 0x40:mindistance 0x44:maxdistance 0x48:varfreq/size_32bits 0x4c:varvol 0x4e:fsb.varpan */
/* FSB3/4: 0x50:extended_data size_32bits (not always given) */ /* FSB3/4: 0x50:extended_data size_32bits (not always given) */
if (i+1 == target_stream) /* d_off found */ if (i+1 == target_subsong) /* d_off found */
break; break;
s_off += stream_header_size; s_off += stream_header_size;
@ -259,6 +259,7 @@ VGMSTREAM * init_vgmstream_fsb(STREAMFILE *streamFile) {
vgmstream->loop_start_sample = fsb.loop_start; vgmstream->loop_start_sample = fsb.loop_start;
vgmstream->loop_end_sample = fsb.loop_end; vgmstream->loop_end_sample = fsb.loop_end;
vgmstream->num_streams = fsb.total_subsongs; vgmstream->num_streams = fsb.total_subsongs;
vgmstream->stream_size = fsb.stream_size;
vgmstream->meta_type = fsb.meta_type; vgmstream->meta_type = fsb.meta_type;
if (fsb.name_offset) if (fsb.name_offset)
read_string(vgmstream->stream_name,fsb.name_size+1, fsb.name_offset,streamFile); read_string(vgmstream->stream_name,fsb.name_size+1, fsb.name_offset,streamFile);

View File

@ -11,7 +11,7 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
uint32_t NumSamples = 0, LoopStart = 0, LoopEnd = 0; uint32_t NumSamples = 0, LoopStart = 0, LoopEnd = 0;
int LoopFlag = 0, ChannelCount = 0, Version, SampleRate = 0, CodingID; int LoopFlag = 0, ChannelCount = 0, Version, SampleRate = 0, CodingID;
int TotalStreams, TargetStream = streamFile->stream_index; int TotalSubsongs, TargetSubsong = streamFile->stream_index;
int i; int i;
/* check extension, case insensitive */ /* check extension, case insensitive */
@ -25,7 +25,7 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
Version = read_32bitLE(0x04,streamFile); Version = read_32bitLE(0x04,streamFile);
if (Version != 0x00 && Version != 0x01) goto fail; if (Version != 0x00 && Version != 0x01) goto fail;
TotalStreams = read_32bitLE(0x08,streamFile); TotalSubsongs = read_32bitLE(0x08,streamFile);
SampleHeaderLength = read_32bitLE(0x0C,streamFile); SampleHeaderLength = read_32bitLE(0x0C,streamFile);
NameTableLength = read_32bitLE(0x10,streamFile); NameTableLength = read_32bitLE(0x10,streamFile);
SampleDataLength = read_32bitLE(0x14,streamFile); SampleDataLength = read_32bitLE(0x14,streamFile);
@ -37,14 +37,14 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
if ((SampleHeaderLength + NameTableLength + SampleDataLength + BaseHeaderLength) != get_streamfile_size(streamFile)) if ((SampleHeaderLength + NameTableLength + SampleDataLength + BaseHeaderLength) != get_streamfile_size(streamFile))
goto fail; goto fail;
if (TargetStream == 0) TargetStream = 1; /* default to 1 */ if (TargetSubsong == 0) TargetSubsong = 1; /* default to 1 */
if (TargetStream > TotalStreams || TotalStreams <= 0) goto fail; if (TargetSubsong > TotalSubsongs || TotalSubsongs <= 0) goto fail;
SampleHeaderStart = BaseHeaderLength; SampleHeaderStart = BaseHeaderLength;
/* find target stream header and data offset, and read all needed values for later use /* 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) */ * (reads one by one as the size of a single stream header is variable) */
for (i = 1; i <= TotalStreams; i++) { for (i = 1; i <= TotalSubsongs; i++) {
off_t DataStart = 0; off_t DataStart = 0;
size_t StreamHeaderLength = 0; size_t StreamHeaderLength = 0;
uint32_t SampleMode1, SampleMode2; uint32_t SampleMode1, SampleMode2;
@ -156,11 +156,11 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
} }
/* stream found */ /* stream found */
if (i == TargetStream) { if (i == TargetSubsong) {
StartOffset = BaseHeaderLength + SampleHeaderLength + NameTableLength + DataStart; StartOffset = BaseHeaderLength + SampleHeaderLength + NameTableLength + DataStart;
/* get stream size from next stream or datasize if there is only one */ /* get stream size from next stream or datasize if there is only one */
if (i == TotalStreams) { if (i == TotalSubsongs) {
StreamSize = SampleDataLength - DataStart; StreamSize = SampleDataLength - DataStart;
} else { } else {
uint32_t NextSampleMode = (uint32_t)read_32bitLE(SampleHeaderStart+StreamHeaderLength+0x00,streamFile); uint32_t NextSampleMode = (uint32_t)read_32bitLE(SampleHeaderStart+StreamHeaderLength+0x00,streamFile);
@ -178,7 +178,7 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
/* get stream name */ /* get stream name */
if (NameTableLength) { if (NameTableLength) {
NameOffset = BaseHeaderLength + SampleHeaderLength + read_32bitLE(BaseHeaderLength + SampleHeaderLength + 0x04*(TargetStream-1),streamFile); NameOffset = BaseHeaderLength + SampleHeaderLength + read_32bitLE(BaseHeaderLength + SampleHeaderLength + 0x04*(TargetSubsong-1),streamFile);
} }
@ -187,12 +187,13 @@ VGMSTREAM * init_vgmstream_fsb5(STREAMFILE *streamFile) {
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
vgmstream->sample_rate = SampleRate; vgmstream->sample_rate = SampleRate;
vgmstream->num_streams = TotalStreams;
vgmstream->num_samples = NumSamples; vgmstream->num_samples = NumSamples;
if (LoopFlag) { if (LoopFlag) {
vgmstream->loop_start_sample = LoopStart; vgmstream->loop_start_sample = LoopStart;
vgmstream->loop_end_sample = LoopEnd; vgmstream->loop_end_sample = LoopEnd;
} }
vgmstream->num_streams = TotalSubsongs;
vgmstream->stream_size = StreamSize;
vgmstream->meta_type = meta_FSB5; vgmstream->meta_type = meta_FSB5;
if (NameOffset) if (NameOffset)
read_string(vgmstream->stream_name,STREAM_NAME_SIZE, NameOffset,streamFile); read_string(vgmstream->stream_name,STREAM_NAME_SIZE, NameOffset,streamFile);

View File

@ -5,6 +5,7 @@
VGMSTREAM * init_vgmstream_kma9(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_kma9(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
off_t start_offset; off_t start_offset;
size_t stream_size;
int loop_flag, channel_count; int loop_flag, channel_count;
int total_subsongs = 0, target_subsong = streamFile->stream_index; int total_subsongs = 0, target_subsong = streamFile->stream_index;
@ -25,7 +26,7 @@ VGMSTREAM * init_vgmstream_kma9(STREAMFILE *streamFile) {
if (target_subsong == 0) target_subsong = 1; if (target_subsong == 0) target_subsong = 1;
if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail; if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
/* 0x0c: unknown */ /* 0x0c: unknown */
/* 0x14: data size of each subsong */ stream_size = read_32bitLE(0x14,streamFile); /* per subsong */
/* build the VGMSTREAM */ /* build the VGMSTREAM */
@ -37,7 +38,7 @@ VGMSTREAM * init_vgmstream_kma9(STREAMFILE *streamFile) {
vgmstream->loop_start_sample = read_32bitLE(0x24,streamFile); /* with skip_samples? */ vgmstream->loop_start_sample = read_32bitLE(0x24,streamFile); /* with skip_samples? */
vgmstream->loop_end_sample = vgmstream->num_samples; /* 0x28 looks like end samples but isn't, no idea */ vgmstream->loop_end_sample = vgmstream->num_samples; /* 0x28 looks like end samples but isn't, no idea */
vgmstream->num_streams = total_subsongs; vgmstream->num_streams = total_subsongs;
vgmstream->stream_size = stream_size;
vgmstream->meta_type = meta_KMA9; vgmstream->meta_type = meta_KMA9;
#ifdef VGM_USE_ATRAC9 #ifdef VGM_USE_ATRAC9

View File

@ -274,6 +274,9 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
int32_t loop_length = vgm_inf->loop_length; int32_t loop_length = vgm_inf->loop_length;
int loop_end_found = vgm_inf->loop_end_found; int loop_end_found = vgm_inf->loop_end_found;
int32_t loop_end = vgm_inf->loop_end; int32_t loop_end = vgm_inf->loop_end;
size_t stream_size = vgm_inf->stream_size ?
vgm_inf->stream_size :
get_streamfile_size(streamFile) - start;
ov_callbacks default_callbacks; ov_callbacks default_callbacks;
@ -295,9 +298,7 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
temp_streamfile.start = start; temp_streamfile.start = start;
temp_streamfile.offset = 0; temp_streamfile.offset = 0;
temp_streamfile.size = vgm_inf->stream_size ? temp_streamfile.size = stream_size;
vgm_inf->stream_size :
get_streamfile_size(temp_streamfile.streamfile) - start;
temp_streamfile.decryption_callback = vgm_inf->decryption_callback; temp_streamfile.decryption_callback = vgm_inf->decryption_callback;
temp_streamfile.scd_xor = vgm_inf->scd_xor; temp_streamfile.scd_xor = vgm_inf->scd_xor;
@ -324,9 +325,7 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
data->ov_streamfile.start = start; data->ov_streamfile.start = start;
data->ov_streamfile.offset = 0; data->ov_streamfile.offset = 0;
data->ov_streamfile.size = vgm_inf->stream_size ? data->ov_streamfile.size = stream_size;
vgm_inf->stream_size :
get_streamfile_size(data->ov_streamfile.streamfile) - start;
data->ov_streamfile.decryption_callback = vgm_inf->decryption_callback; data->ov_streamfile.decryption_callback = vgm_inf->decryption_callback;
data->ov_streamfile.scd_xor = vgm_inf->scd_xor; data->ov_streamfile.scd_xor = vgm_inf->scd_xor;
@ -412,6 +411,7 @@ VGMSTREAM * init_vgmstream_ogg_vorbis_callbacks(STREAMFILE *streamFile, const ch
vgmstream->channels = vi->channels; vgmstream->channels = vi->channels;
vgmstream->sample_rate = vi->rate; vgmstream->sample_rate = vi->rate;
vgmstream->num_streams = vgm_inf->total_subsongs; vgmstream->num_streams = vgm_inf->total_subsongs;
vgmstream->stream_size = stream_size;
vgmstream->num_samples = ov_pcm_total(ovf,-1); /* let libvorbisfile find total samples */ vgmstream->num_samples = ov_pcm_total(ovf,-1); /* let libvorbisfile find total samples */
if (loop_flag) { if (loop_flag) {

View File

@ -7,10 +7,10 @@ VGMSTREAM * init_vgmstream_ps2_rxws(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
STREAMFILE * streamHeader = NULL; STREAMFILE * streamHeader = NULL;
off_t start_offset, chunk_offset, name_offset = 0; off_t start_offset, chunk_offset, name_offset = 0;
size_t data_size, chunk_size; size_t stream_size, chunk_size;
int loop_flag = 0, channel_count, is_separate = 0, type, sample_rate; int loop_flag = 0, channel_count, is_separate = 0, type, sample_rate;
int32_t loop_start, loop_end; int32_t loop_start, loop_end;
int total_streams, target_stream = streamFile->stream_index; int total_subsongs, target_subsong = streamFile->stream_index;
/* check extensions */ /* check extensions */
/* .xws: header and data, .xwh+xwb: header + data (.bin+dat are also found in Wild Arms 4/5) */ /* .xws: header and data, .xwh+xwb: header + data (.bin+dat are also found in Wild Arms 4/5) */
@ -46,14 +46,14 @@ VGMSTREAM * init_vgmstream_ps2_rxws(STREAMFILE *streamFile) {
/* check multi-streams */ /* check multi-streams */
total_streams = read_32bitLE(chunk_offset+0x00,streamHeader); total_subsongs = read_32bitLE(chunk_offset+0x00,streamHeader);
if (target_stream == 0) target_stream = 1; if (target_subsong == 0) target_subsong = 1;
if (target_stream < 0 || target_stream > total_streams || total_streams < 1) goto fail; if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
/* read stream header */ /* read stream header */
{ {
off_t header_offset = chunk_offset + 0x4 + 0x1c * (target_stream-1); /* position in FORM */ off_t header_offset = chunk_offset + 0x4 + 0x1c * (target_subsong-1); /* position in FORM */
off_t stream_offset, next_stream_offset, data_offset = 0; off_t stream_offset, next_stream_offset, data_offset = 0;
type = read_8bit(header_offset+0x00, streamHeader); type = read_8bit(header_offset+0x00, streamHeader);
@ -83,22 +83,22 @@ VGMSTREAM * init_vgmstream_ps2_rxws(STREAMFILE *streamFile) {
if (!data_offset) goto fail; if (!data_offset) goto fail;
} }
if (target_stream == total_streams) { if (target_subsong == total_subsongs) {
next_stream_offset = data_offset + get_streamfile_size(is_separate ? streamFile : streamHeader); next_stream_offset = data_offset + get_streamfile_size(is_separate ? streamFile : streamHeader);
} else { } else {
off_t next_header_offset = chunk_offset + 0x4 + 0x1c * (target_stream); off_t next_header_offset = chunk_offset + 0x4 + 0x1c * (target_subsong);
next_stream_offset = read_32bitLE(next_header_offset+0x10,streamHeader); next_stream_offset = read_32bitLE(next_header_offset+0x10,streamHeader);
} }
data_size = next_stream_offset - stream_offset; stream_size = next_stream_offset - stream_offset;
start_offset = data_offset + stream_offset; start_offset = data_offset + stream_offset;
} }
/* get stream name (always follows FORM) */ /* get stream name (always follows FORM) */
if (read_32bitBE(0x10+0x10 + chunk_size,streamHeader) == 0x46545854) { /* "FTXT" */ if (read_32bitBE(0x10+0x10 + chunk_size,streamHeader) == 0x46545854) { /* "FTXT" */
chunk_offset = 0x10+0x10 + chunk_size + 0x10; chunk_offset = 0x10+0x10 + chunk_size + 0x10;
if (read_32bitLE(chunk_offset+0x00,streamHeader) == total_streams) { if (read_32bitLE(chunk_offset+0x00,streamHeader) == total_subsongs) {
name_offset = chunk_offset + read_32bitLE(chunk_offset+0x04 + (target_stream-1)*0x04,streamHeader); name_offset = chunk_offset + read_32bitLE(chunk_offset+0x04 + (target_subsong-1)*0x04,streamHeader);
} }
} }
@ -108,7 +108,8 @@ VGMSTREAM * init_vgmstream_ps2_rxws(STREAMFILE *streamFile) {
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
vgmstream->sample_rate = sample_rate; vgmstream->sample_rate = sample_rate;
vgmstream->num_streams = total_streams; vgmstream->num_streams = total_subsongs;
vgmstream->stream_size = stream_size;
vgmstream->meta_type = meta_PS2_RXWS; vgmstream->meta_type = meta_PS2_RXWS;
if (name_offset) if (name_offset)
read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,streamHeader); read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,streamHeader);
@ -143,10 +144,10 @@ VGMSTREAM * init_vgmstream_ps2_rxws(STREAMFILE *streamFile) {
joint_stereo = 0; joint_stereo = 0;
encoder_delay = 0x0; encoder_delay = 0x0;
bytes = ffmpeg_make_riff_atrac3(buf, 0x100, vgmstream->num_samples, data_size, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, encoder_delay); bytes = ffmpeg_make_riff_atrac3(buf, 0x100, vgmstream->num_samples, stream_size, vgmstream->channels, vgmstream->sample_rate, block_size, joint_stereo, encoder_delay);
if (bytes <= 0) goto fail; if (bytes <= 0) goto fail;
vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,data_size); vgmstream->codec_data = init_ffmpeg_header_offset(streamFile, buf,bytes, start_offset,stream_size);
if (!vgmstream->codec_data) goto fail; if (!vgmstream->codec_data) goto fail;
vgmstream->coding_type = coding_FFmpeg; vgmstream->coding_type = coding_FFmpeg;
vgmstream->layout_type = layout_none; vgmstream->layout_type = layout_none;

View File

@ -15,7 +15,7 @@ VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) {
size_t block_size = 0, block_size_total = 0; size_t block_size = 0, block_size_total = 0;
int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL; int32_t (*read_32bit)(off_t,STREAMFILE*) = NULL;
int i, total_segments; int i, total_segments;
int total_streams, target_stream = streamFile->stream_index; int total_subsongs, target_subsong = streamFile->stream_index;
if (!check_extensions(streamFile,"rws")) if (!check_extensions(streamFile,"rws"))
@ -49,7 +49,7 @@ VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) {
* 0x1c: null? 0x30: 0x800?, 0x34: block_size_total?, 0x38: data offset, 0x3c: 0?, 0x40-50: file uuid */ * 0x1c: null? 0x30: 0x800?, 0x34: block_size_total?, 0x38: data offset, 0x3c: 0?, 0x40-50: file uuid */
read_32bit = (read_32bitLE(off+0x00,streamFile) > header_size) ? read_32bitBE : read_32bitLE; /* GC/Wii/X360 = BE */ read_32bit = (read_32bitLE(off+0x00,streamFile) > header_size) ? read_32bitBE : read_32bitLE; /* GC/Wii/X360 = BE */
total_segments = read_32bit(off+0x20,streamFile); total_segments = read_32bit(off+0x20,streamFile);
total_streams = read_32bit(off+0x28,streamFile); total_subsongs = read_32bit(off+0x28,streamFile);
/* skip audio file name */ /* skip audio file name */
off += 0x50 + get_rws_string_size(off+0x50, streamFile); off += 0x50 + get_rws_string_size(off+0x50, streamFile);
@ -58,8 +58,8 @@ VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) {
/* Data is divided into "segments" (cues/divisions within data, ex. intro+main, voice1+2+..N) and "streams" /* Data is divided into "segments" (cues/divisions within data, ex. intro+main, voice1+2+..N) and "streams"
* of interleaved blocks (for multichannel?). last stream (only?) has padding. Segments divide all streams. * of interleaved blocks (for multichannel?). last stream (only?) has padding. Segments divide all streams.
* ex.- 0x1800 data + 0 pad of stream_0 2ch, 0x1800 data + 0x200 pad of stream1 2ch (xN). */ * ex.- 0x1800 data + 0 pad of stream_0 2ch, 0x1800 data + 0x200 pad of stream1 2ch (xN). */
if (target_stream == 0) target_stream = 1; if (target_subsong == 0) target_subsong = 1;
if (target_stream < 0 || target_stream > total_streams || total_streams < 1) goto fail; if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
/* get segment info, for all streams */ /* get segment info, for all streams */
/* 0x00/04/0c: command?, 0x18: full segment size (including all streams), 0x1c: offset, others: ?) */ /* 0x00/04/0c: command?, 0x18: full segment size (including all streams), 0x1c: offset, others: ?) */
@ -70,9 +70,9 @@ VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) {
/* get usable segment sizes (usually ok but sometimes > stream_size), per stream */ /* get usable segment sizes (usually ok but sometimes > stream_size), per stream */
for (i = 0; i < total_segments; i++) { /* sum usable segment sizes (no padding) */ for (i = 0; i < total_segments; i++) { /* sum usable segment sizes (no padding) */
stream_size += read_32bit(off + 0x04*i + 0x04*total_segments*(target_stream-1),streamFile); stream_size += read_32bit(off + 0x04*i + 0x04*total_segments*(target_subsong-1),streamFile);
} }
off += 0x04 * (total_segments * total_streams); off += 0x04 * (total_segments * total_subsongs);
/* skip segment uuids */ /* skip segment uuids */
off += 0x10 * total_segments; off += 0x10 * total_segments;
@ -85,21 +85,21 @@ VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) {
/* get stream layout */ /* get stream layout */
/* 0x00/04/14: command?, 0x08: null? 0x0c: spf related? (XADPCM=07, VAG=1C, DSP=0E, PCM=01) /* 0x00/04/14: command?, 0x08: null? 0x0c: spf related? (XADPCM=07, VAG=1C, DSP=0E, PCM=01)
* 0x24: offset within data chunk, 0x1c: codec related?, others: ?) */ * 0x24: offset within data chunk, 0x1c: codec related?, others: ?) */
for (i = 0; i < total_streams; i++) { /* get block_sizes */ for (i = 0; i < total_subsongs; i++) { /* get block_sizes */
block_size_total += read_32bit(off + 0x10 + 0x28*i, streamFile); /* for all streeams, to skip during decode */ block_size_total += read_32bit(off + 0x10 + 0x28*i, streamFile); /* for all streeams, to skip during decode */
if (i+1 == target_stream) { if (i+1 == target_subsong) {
//block_size_full = read_32bit(off + 0x10 + 0x28*i, streamFile); /* with padding, can be different per stream */ //block_size_full = read_32bit(off + 0x10 + 0x28*i, streamFile); /* with padding, can be different per stream */
block_size = read_32bit(off + 0x20 + 0x28*i, streamFile); /* without padding */ block_size = read_32bit(off + 0x20 + 0x28*i, streamFile); /* without padding */
stream_offset = read_32bit(off + 0x24 + 0x28*i, streamFile); /* within data */ stream_offset = read_32bit(off + 0x24 + 0x28*i, streamFile); /* within data */
} }
} }
off += 0x28 * total_streams; off += 0x28 * total_subsongs;
/* get stream config */ /* get stream config */
/* 0x04: command?, 0x0c(1): bits per sample, others: null? */ /* 0x04: command?, 0x0c(1): bits per sample, others: null? */
for (i = 0; i < total_streams; i++) { /* size depends on codec so we must parse it */ for (i = 0; i < total_subsongs; i++) { /* size depends on codec so we must parse it */
int prev_codec = 0; int prev_codec = 0;
if (i+1 == target_stream) { if (i+1 == target_subsong) {
sample_rate = read_32bit(off+0x00, streamFile); sample_rate = read_32bit(off+0x00, streamFile);
//unk_size = read_32bit(off+0x08, streamFile); /* segment size again? loop-related? */ //unk_size = read_32bit(off+0x08, streamFile); /* segment size again? loop-related? */
channel_count = read_8bit(off+0x0d, streamFile); channel_count = read_8bit(off+0x0d, streamFile);
@ -110,7 +110,7 @@ VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) {
if (prev_codec == 0xF86215B0) { /* if codec is DSP there is an extra field per stream */ if (prev_codec == 0xF86215B0) { /* if codec is DSP there is an extra field per stream */
/* 0x00: approx num samples? 0x04: approx size/loop related? (can be 0) */ /* 0x00: approx num samples? 0x04: approx size/loop related? (can be 0) */
if (i+1 == target_stream) { if (i+1 == target_subsong) {
coefs_offset = off + 0x1c; coefs_offset = off + 0x1c;
} }
off += 0x60; off += 0x60;
@ -120,11 +120,11 @@ VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) {
} }
/* skip stream uuids */ /* skip stream uuids */
off += 0x10 * total_streams; off += 0x10 * total_subsongs;
/* get stream name */ /* get stream name */
for (i = 0; i < total_streams; i++) { for (i = 0; i < total_subsongs; i++) {
if (i+1 == target_stream) { if (i+1 == target_subsong) {
name_offset = off; name_offset = off;
} }
off += get_rws_string_size(off, streamFile); off += get_rws_string_size(off, streamFile);
@ -137,7 +137,7 @@ VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) {
start_offset = 0x0c + 0x0c + header_size + 0x0c + stream_offset; start_offset = 0x0c + 0x0c + header_size + 0x0c + stream_offset;
/* sometimes it's wrong for no apparent reason (probably a bug in RWS) */ /* sometimes it's wrong for no apparent reason (probably a bug in RWS) */
stream_size_expected = (stream_size_full / block_size_total) * (block_size * total_streams) / total_streams; stream_size_expected = (stream_size_full / block_size_total) * (block_size * total_subsongs) / total_subsongs;
if (stream_size > stream_size_expected) { if (stream_size > stream_size_expected) {
VGM_LOG("RWS: readjusting wrong stream size %x vs expected %x\n", stream_size, stream_size_expected); VGM_LOG("RWS: readjusting wrong stream size %x vs expected %x\n", stream_size, stream_size_expected);
stream_size = stream_size_expected; stream_size = stream_size_expected;
@ -149,7 +149,8 @@ VGMSTREAM * init_vgmstream_rws(STREAMFILE *streamFile) {
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
vgmstream->sample_rate = sample_rate; vgmstream->sample_rate = sample_rate;
vgmstream->num_streams = total_streams; vgmstream->num_streams = total_subsongs;
vgmstream->stream_size = stream_size;
vgmstream->meta_type = meta_RWS; vgmstream->meta_type = meta_RWS;
if (name_offset) if (name_offset)
read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,streamFile); read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,streamFile);

View File

@ -8,8 +8,8 @@ static void get_stream_name(char * stream_name, STREAMFILE *streamFile, int targ
VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
off_t start_offset; off_t start_offset;
int loop_flag, channel_count = 0, is_stream, align, codec, sample_rate, data_size, loop_start, loop_end; int loop_flag, channel_count = 0, is_stream, align, codec, sample_rate, stream_size, loop_start, loop_end;
int total_streams, target_stream = streamFile->stream_index; int total_subsongs, target_subsong = streamFile->stream_index;
/* .sab: main, .sob: config/names */ /* .sab: main, .sob: config/names */
if (!check_extensions(streamFile,"sab")) if (!check_extensions(streamFile,"sab"))
@ -20,29 +20,29 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) {
goto fail; goto fail;
is_stream = read_32bitLE(0x04,streamFile) & 0x04; /* other flags don't seem to matter */ is_stream = read_32bitLE(0x04,streamFile) & 0x04; /* other flags don't seem to matter */
total_streams = is_stream ? 1 : read_32bitLE(0x08,streamFile); total_subsongs = is_stream ? 1 : read_32bitLE(0x08,streamFile);
if (target_stream == 0) target_stream = 1; if (target_subsong == 0) target_subsong = 1;
if (target_stream < 0 || target_stream > total_streams || total_streams < 1) goto fail; if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
align = read_32bitLE(0x0c,streamFile); /* doubles as interleave */ align = read_32bitLE(0x0c,streamFile); /* doubles as interleave */
/* stream config */ /* stream config */
codec = read_32bitLE(0x18 + 0x1c*(target_stream-1) + 0x00,streamFile); codec = read_32bitLE(0x18 + 0x1c*(target_subsong-1) + 0x00,streamFile);
channel_count = read_32bitLE(0x18 + 0x1c*(target_stream-1) + 0x04,streamFile); channel_count = read_32bitLE(0x18 + 0x1c*(target_subsong-1) + 0x04,streamFile);
sample_rate = read_32bitLE(0x18 + 0x1c*(target_stream-1) + 0x08,streamFile); sample_rate = read_32bitLE(0x18 + 0x1c*(target_subsong-1) + 0x08,streamFile);
data_size = read_32bitLE(0x18 + 0x1c*(target_stream-1) + 0x0c,streamFile); stream_size = read_32bitLE(0x18 + 0x1c*(target_subsong-1) + 0x0c,streamFile);
loop_start = read_32bitLE(0x18 + 0x1c*(target_stream-1) + 0x10,streamFile); loop_start = read_32bitLE(0x18 + 0x1c*(target_subsong-1) + 0x10,streamFile);
loop_end = read_32bitLE(0x18 + 0x1c*(target_stream-1) + 0x14,streamFile); loop_end = read_32bitLE(0x18 + 0x1c*(target_subsong-1) + 0x14,streamFile);
loop_flag = (loop_end > 0); loop_flag = (loop_end > 0);
start_offset = 0x18 + 0x1c*total_streams; start_offset = 0x18 + 0x1c*total_subsongs;
if (start_offset % align) if (start_offset % align)
start_offset += align - (start_offset % align); start_offset += align - (start_offset % align);
start_offset += read_32bitLE(0x18 + 0x1c*(target_stream-1) + 0x18,streamFile); start_offset += read_32bitLE(0x18 + 0x1c*(target_subsong-1) + 0x18,streamFile);
if (is_stream) { if (is_stream) {
channel_count = read_32bitLE(0x08,streamFile); /* uncommon, but non-stream stereo exists */ channel_count = read_32bitLE(0x08,streamFile); /* uncommon, but non-stream stereo exists */
data_size *= channel_count; stream_size *= channel_count;
} }
/* build the VGMSTREAM */ /* build the VGMSTREAM */
@ -50,8 +50,8 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) {
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
vgmstream->sample_rate = sample_rate; vgmstream->sample_rate = sample_rate;
vgmstream->num_streams = total_subsongs;
vgmstream->num_streams = total_streams; vgmstream->stream_size = stream_size;
vgmstream->meta_type = meta_SAB; vgmstream->meta_type = meta_SAB;
switch(codec) { switch(codec) {
@ -60,7 +60,7 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) {
vgmstream->layout_type = layout_interleave; vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = is_stream ? align : 0x02; vgmstream->interleave_block_size = is_stream ? align : 0x02;
vgmstream->num_samples = pcm_bytes_to_samples(data_size, vgmstream->channels, 16); vgmstream->num_samples = pcm_bytes_to_samples(stream_size, vgmstream->channels, 16);
vgmstream->loop_start_sample = pcm_bytes_to_samples(loop_start, vgmstream->channels, 16); vgmstream->loop_start_sample = pcm_bytes_to_samples(loop_start, vgmstream->channels, 16);
vgmstream->loop_end_sample = pcm_bytes_to_samples(loop_end, vgmstream->channels, 16); vgmstream->loop_end_sample = pcm_bytes_to_samples(loop_end, vgmstream->channels, 16);
@ -71,7 +71,7 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) {
vgmstream->layout_type = layout_interleave; vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = is_stream ? align : 0x10; vgmstream->interleave_block_size = is_stream ? align : 0x10;
vgmstream->num_samples = ps_bytes_to_samples(data_size, vgmstream->channels); vgmstream->num_samples = ps_bytes_to_samples(stream_size, vgmstream->channels);
vgmstream->loop_start_sample = ps_bytes_to_samples(loop_start, vgmstream->channels); vgmstream->loop_start_sample = ps_bytes_to_samples(loop_start, vgmstream->channels);
vgmstream->loop_end_sample = ps_bytes_to_samples(loop_end, vgmstream->channels); vgmstream->loop_end_sample = ps_bytes_to_samples(loop_end, vgmstream->channels);
break; break;
@ -81,7 +81,7 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) {
vgmstream->layout_type = is_stream ? layout_interleave : layout_none; vgmstream->layout_type = is_stream ? layout_interleave : layout_none;
vgmstream->interleave_block_size = is_stream ? align : 0x00; vgmstream->interleave_block_size = is_stream ? align : 0x00;
vgmstream->num_samples = ms_ima_bytes_to_samples(data_size, 0x24*vgmstream->channels, vgmstream->channels); vgmstream->num_samples = ms_ima_bytes_to_samples(stream_size, 0x24*vgmstream->channels, vgmstream->channels);
vgmstream->loop_start_sample = ms_ima_bytes_to_samples(loop_start, 0x24*vgmstream->channels, vgmstream->channels); vgmstream->loop_start_sample = ms_ima_bytes_to_samples(loop_start, 0x24*vgmstream->channels, vgmstream->channels);
vgmstream->loop_end_sample = ms_ima_bytes_to_samples(loop_end, 0x24*vgmstream->channels, vgmstream->channels); vgmstream->loop_end_sample = ms_ima_bytes_to_samples(loop_end, 0x24*vgmstream->channels, vgmstream->channels);
break; break;
@ -91,7 +91,7 @@ VGMSTREAM * init_vgmstream_sab(STREAMFILE *streamFile) {
goto fail; goto fail;
} }
get_stream_name(vgmstream->stream_name, streamFile, target_stream); get_stream_name(vgmstream->stream_name, streamFile, target_subsong);
if (!vgmstream_open_stream(vgmstream,streamFile,start_offset)) if (!vgmstream_open_stream(vgmstream,streamFile,start_offset))
goto fail; goto fail;

View File

@ -2,19 +2,17 @@
#include "../coding/coding.h" #include "../coding/coding.h"
/* SGXD - Sony/SCEI's format (SGB+SGH / SGD / SGX), found in: /* SGXD - Sony/SCEI's format (SGB+SGH / SGD / SGX) */
* PS3: Genji, Folklore, Afrika (Short VAG), Tokyo Jungle
* PSP: Brave Story, Sarugetchu Sarusaru Daisakusen, Kurohyo 1/2, Pathwork Heroes */
VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) { VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
STREAMFILE * streamHeader = NULL; STREAMFILE * streamHeader = NULL;
off_t start_offset, data_offset, chunk_offset, name_offset = 0; off_t start_offset, data_offset, chunk_offset, name_offset = 0;
size_t data_size; size_t stream_size;
int is_sgx, is_sgb = 0; int is_sgx, is_sgb = 0;
int loop_flag, channels, type; int loop_flag, channels, type;
int sample_rate, num_samples, loop_start_sample, loop_end_sample; int sample_rate, num_samples, loop_start_sample, loop_end_sample;
int total_streams, target_stream = streamFile->stream_index; int total_subsongs, target_subsong = streamFile->stream_index;
/* check extension, case insensitive */ /* check extension, case insensitive */
@ -59,14 +57,14 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) {
/* 0x04 SGX: unknown; SGD/SGH: chunk length, 0x08 null */ /* 0x04 SGX: unknown; SGD/SGH: chunk length, 0x08 null */
/* check multi-streams (usually only SE containers; Puppeteer) */ /* check multi-streams (usually only SE containers; Puppeteer) */
total_streams = read_32bitLE(chunk_offset+0x04,streamHeader); total_subsongs = read_32bitLE(chunk_offset+0x04,streamHeader);
if (target_stream == 0) target_stream = 1; if (target_subsong == 0) target_subsong = 1;
if (target_stream < 0 || target_stream > total_streams || total_streams < 1) goto fail; if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
/* read stream header */ /* read stream header */
{ {
off_t stream_offset; off_t stream_offset;
chunk_offset += 0x08 + 0x38 * (target_stream-1); /* position in target header*/ chunk_offset += 0x08 + 0x38 * (target_subsong-1); /* position in target header*/
/* 0x00 ? (00/01/02) */ /* 0x00 ? (00/01/02) */
if (!is_sgx) /* meaning unknown in .sgx; offset 0 = not a stream (a RGND sample) */ if (!is_sgx) /* meaning unknown in .sgx; offset 0 = not a stream (a RGND sample) */
@ -85,7 +83,7 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) {
num_samples = read_32bitLE(chunk_offset+0x20,streamHeader); num_samples = read_32bitLE(chunk_offset+0x20,streamHeader);
loop_start_sample = read_32bitLE(chunk_offset+0x24,streamHeader); loop_start_sample = read_32bitLE(chunk_offset+0x24,streamHeader);
loop_end_sample = read_32bitLE(chunk_offset+0x28,streamHeader); loop_end_sample = read_32bitLE(chunk_offset+0x28,streamHeader);
data_size = read_32bitLE(chunk_offset+0x2c,streamHeader); /* stream size (without padding) / interleave (for type3) */ stream_size = read_32bitLE(chunk_offset+0x2c,streamHeader); /* stream size (without padding) / interleave (for type3) */
if (is_sgx) { if (is_sgx) {
stream_offset = 0x0; stream_offset = 0x0;
@ -107,7 +105,8 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) {
vgmstream->num_samples = num_samples; vgmstream->num_samples = num_samples;
vgmstream->loop_start_sample = loop_start_sample; vgmstream->loop_start_sample = loop_start_sample;
vgmstream->loop_end_sample = loop_end_sample; vgmstream->loop_end_sample = loop_end_sample;
vgmstream->num_streams = total_streams; vgmstream->num_streams = total_subsongs;
vgmstream->stream_size = stream_size;
vgmstream->meta_type = meta_SGXD; vgmstream->meta_type = meta_SGXD;
if (name_offset) if (name_offset)
read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,streamHeader); read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,streamHeader);
@ -118,23 +117,23 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) {
vgmstream->loop_end_sample -= 1; vgmstream->loop_end_sample -= 1;
switch (type) { switch (type) {
case 0x03: /* PS-ADPCM */ case 0x03: /* PS-ADPCM [Genji (PS3), Ape Escape Move (PS3)]*/
vgmstream->coding_type = coding_PSX; vgmstream->coding_type = coding_PSX;
vgmstream->layout_type = layout_interleave; vgmstream->layout_type = layout_interleave;
if (is_sgx || is_sgb) { if (is_sgx || is_sgb) {
vgmstream->interleave_block_size = 0x10; vgmstream->interleave_block_size = 0x10;
} else { /* this only seems to happen with SFX */ } else { /* this only seems to happen with SFX */
vgmstream->interleave_block_size = data_size; vgmstream->interleave_block_size = stream_size;
} }
break; break;
#ifdef VGM_USE_FFMPEG #ifdef VGM_USE_FFMPEG
case 0x04: { /* ATRAC3plus */ case 0x04: { /* ATRAC3plus [Kurohyo 1/2 (PSP), BraveStory (PSP)] */
ffmpeg_codec_data *ffmpeg_data; ffmpeg_codec_data *ffmpeg_data;
/* internally has a RIFF header; but the SGXD header / sample rate has priority over it (may not match) */ /* internally has a RIFF header; but the SGXD header / sample rate has priority over it (may not match) */
ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset, data_size); ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset, stream_size);
if ( !ffmpeg_data ) goto fail; if ( !ffmpeg_data ) goto fail;
vgmstream->codec_data = ffmpeg_data; vgmstream->codec_data = ffmpeg_data;
vgmstream->coding_type = coding_FFmpeg; vgmstream->coding_type = coding_FFmpeg;
@ -158,7 +157,7 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) {
break; break;
} }
#endif #endif
case 0x05: /* Short PS-ADPCM */ case 0x05: /* Short PS-ADPCM [Afrika (PS3)] */
vgmstream->coding_type = coding_PSX_cfg; vgmstream->coding_type = coding_PSX_cfg;
vgmstream->layout_type = layout_interleave; vgmstream->layout_type = layout_interleave;
vgmstream->interleave_block_size = 0x4; vgmstream->interleave_block_size = 0x4;
@ -166,10 +165,10 @@ VGMSTREAM * init_vgmstream_sgxd(STREAMFILE *streamFile) {
break; break;
#ifdef VGM_USE_FFMPEG #ifdef VGM_USE_FFMPEG
case 0x06: { /* AC3 */ case 0x06: { /* AC3 [Tokyo Jungle (PS3), Afrika (PS3)] */
ffmpeg_codec_data *ffmpeg_data; ffmpeg_codec_data *ffmpeg_data;
ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset, data_size); ffmpeg_data = init_ffmpeg_offset(streamFile, start_offset, stream_size);
if ( !ffmpeg_data ) goto fail; if ( !ffmpeg_data ) goto fail;
vgmstream->codec_data = ffmpeg_data; vgmstream->codec_data = ffmpeg_data;
vgmstream->coding_type = coding_FFmpeg; vgmstream->coding_type = coding_FFmpeg;

View File

@ -185,10 +185,9 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
vgmstream = allocate_vgmstream(channel_count,loop_flag); vgmstream = allocate_vgmstream(channel_count,loop_flag);
if (!vgmstream) goto fail; if (!vgmstream) goto fail;
/* fill in the vital statistics */
vgmstream->channels = channel_count;
vgmstream->sample_rate = sample_rate; vgmstream->sample_rate = sample_rate;
vgmstream->num_streams = total_subsongs; vgmstream->num_streams = total_subsongs;
vgmstream->stream_size = stream_size;
vgmstream->meta_type = meta_SQEX_SCD; vgmstream->meta_type = meta_SQEX_SCD;
switch (codec) { switch (codec) {

View File

@ -140,6 +140,7 @@ VGMSTREAM * init_vgmstream_sqex_sead(STREAMFILE * streamFile) {
vgmstream->sample_rate = sample_rate; vgmstream->sample_rate = sample_rate;
vgmstream->num_streams = total_subsongs; vgmstream->num_streams = total_subsongs;
vgmstream->stream_size = stream_size;
vgmstream->meta_type = is_sab ? meta_SQEX_SAB : meta_SQEX_MAB; vgmstream->meta_type = is_sab ? meta_SQEX_SAB : meta_SQEX_MAB;
switch(codec) { switch(codec) {
@ -219,6 +220,7 @@ VGM_LOG("2\n");
if (temp_vgmstream) { if (temp_vgmstream) {
/* loops can be slightly different (~1000 samples) but probably HCA's are more accurate */ /* loops can be slightly different (~1000 samples) but probably HCA's are more accurate */
temp_vgmstream->num_streams = vgmstream->num_streams; temp_vgmstream->num_streams = vgmstream->num_streams;
temp_vgmstream->stream_size = vgmstream->stream_size;
temp_vgmstream->meta_type = vgmstream->meta_type; temp_vgmstream->meta_type = vgmstream->meta_type;
close_streamfile(temp_streamFile); close_streamfile(temp_streamFile);

View File

@ -7,13 +7,13 @@ VGMSTREAM * init_vgmstream_sxd(STREAMFILE *streamFile) {
VGMSTREAM * vgmstream = NULL; VGMSTREAM * vgmstream = NULL;
STREAMFILE * streamHeader = NULL; STREAMFILE * streamHeader = NULL;
off_t start_offset, chunk_offset, first_offset = 0x60, name_offset = 0; off_t start_offset, chunk_offset, first_offset = 0x60, name_offset = 0;
size_t chunk_size; size_t chunk_size, stream_size = 0;
int is_separate; int is_separate;
int loop_flag, channels, codec; int loop_flag, channels, codec;
int sample_rate, num_samples, loop_start_sample, loop_end_sample; int sample_rate, num_samples, loop_start_sample, loop_end_sample;
uint32_t at9_config_data = 0; uint32_t at9_config_data = 0;
int total_streams, target_stream = streamFile->stream_index; int total_subsongs, target_subsong = streamFile->stream_index;
/* check extension, case insensitive */ /* check extension, case insensitive */
@ -38,16 +38,16 @@ VGMSTREAM * init_vgmstream_sxd(STREAMFILE *streamFile) {
if (!find_chunk_le(streamHeader, 0x57415645,first_offset,0, &chunk_offset,&chunk_size)) goto fail; /* "WAVE" */ if (!find_chunk_le(streamHeader, 0x57415645,first_offset,0, &chunk_offset,&chunk_size)) goto fail; /* "WAVE" */
/* check multi-streams (usually only in SFX containers) */ /* check multi-streams (usually only in SFX containers) */
total_streams = read_32bitLE(chunk_offset+0x04,streamHeader); total_subsongs = read_32bitLE(chunk_offset+0x04,streamHeader);
if (target_stream == 0) target_stream = 1; if (target_subsong == 0) target_subsong = 1;
if (target_stream < 0 || target_stream > total_streams || total_streams < 1) goto fail; if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
/* read stream header */ /* read stream header */
{ {
off_t table_offset, header_offset, stream_offset; off_t table_offset, header_offset, stream_offset;
/* get target offset using table of relative offsets within WAVE */ /* get target offset using table of relative offsets within WAVE */
table_offset = chunk_offset + 0x08 + 4*(target_stream-1); table_offset = chunk_offset + 0x08 + 4*(target_subsong-1);
header_offset = table_offset + read_32bitLE(table_offset,streamHeader); header_offset = table_offset + read_32bitLE(table_offset,streamHeader);
/* 0x00(4): type/location? (00/01=sxd/RAM?, 02/03=sxd2/stream?) */ /* 0x00(4): type/location? (00/01=sxd/RAM?, 02/03=sxd2/stream?) */
@ -59,7 +59,7 @@ VGMSTREAM * init_vgmstream_sxd(STREAMFILE *streamFile) {
num_samples = read_32bitLE(header_offset+0x14,streamHeader); num_samples = read_32bitLE(header_offset+0x14,streamHeader);
loop_start_sample = read_32bitLE(header_offset+0x18,streamHeader); loop_start_sample = read_32bitLE(header_offset+0x18,streamHeader);
loop_end_sample = read_32bitLE(header_offset+0x1c,streamHeader); loop_end_sample = read_32bitLE(header_offset+0x1c,streamHeader);
/* 0x20(4): data size */ stream_size = read_32bitLE(header_offset+0x20,streamHeader);
stream_offset = read_32bitLE(header_offset+0x24,streamHeader); stream_offset = read_32bitLE(header_offset+0x24,streamHeader);
/* Extra data, variable sized and uses some kind of TLVs (HEVAG's is optional and much smaller). /* Extra data, variable sized and uses some kind of TLVs (HEVAG's is optional and much smaller).
@ -100,7 +100,7 @@ VGMSTREAM * init_vgmstream_sxd(STREAMFILE *streamFile) {
int num_entries = read_16bitLE(chunk_offset+0x04,streamHeader); /* can be bigger than streams */ int num_entries = read_16bitLE(chunk_offset+0x04,streamHeader); /* can be bigger than streams */
for (i = 0; i < num_entries; i++) { for (i = 0; i < num_entries; i++) {
uint32_t index = (uint32_t)read_32bitLE(chunk_offset+0x08 + 0x08 + i*0x0c,streamHeader); uint32_t index = (uint32_t)read_32bitLE(chunk_offset+0x08 + 0x08 + i*0x0c,streamHeader);
if (index+1 == target_stream) { if (index+1 == target_subsong) {
name_offset = chunk_offset+0x08 + 0x00 + i*0x0c + read_32bitLE(chunk_offset+0x08 + 0x00 + i*0x0c,streamHeader); name_offset = chunk_offset+0x08 + 0x00 + i*0x0c + read_32bitLE(chunk_offset+0x08 + 0x00 + i*0x0c,streamHeader);
break; break;
} }
@ -116,7 +116,8 @@ VGMSTREAM * init_vgmstream_sxd(STREAMFILE *streamFile) {
vgmstream->num_samples = num_samples; vgmstream->num_samples = num_samples;
vgmstream->loop_start_sample = loop_start_sample; vgmstream->loop_start_sample = loop_start_sample;
vgmstream->loop_end_sample = loop_end_sample; vgmstream->loop_end_sample = loop_end_sample;
vgmstream->num_streams = total_streams; vgmstream->num_streams = total_subsongs;
vgmstream->stream_size = stream_size;
vgmstream->meta_type = meta_SXD; vgmstream->meta_type = meta_SXD;
if (name_offset) if (name_offset)
read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,streamHeader); read_string(vgmstream->stream_name,STREAM_NAME_SIZE, name_offset,streamHeader);
@ -148,7 +149,7 @@ VGMSTREAM * init_vgmstream_sxd(STREAMFILE *streamFile) {
break; break;
} }
#endif #endif
//case 0x28: /* dummy codec? (found with 0 samples) */ //case 0x28: /* dummy codec? (found with 0 samples) [Hot Shots Golf: World Invitational (Vita) sfx] */
default: default:
VGM_LOG("SXD: unknown codec 0x%x\n", codec); VGM_LOG("SXD: unknown codec 0x%x\n", codec);
goto fail; goto fail;

View File

@ -127,6 +127,7 @@ VGMSTREAM * init_vgmstream_ubi_sb(STREAMFILE *streamFile) {
vgmstream->sample_rate = sb.sample_rate; vgmstream->sample_rate = sb.sample_rate;
vgmstream->num_streams = sb.total_streams; vgmstream->num_streams = sb.total_streams;
vgmstream->stream_size = sb.stream_size;
vgmstream->meta_type = meta_UBI_SB; vgmstream->meta_type = meta_UBI_SB;

View File

@ -7,7 +7,7 @@ VGMSTREAM * init_vgmstream_vxn(STREAMFILE *streamFile) {
int loop_flag = 0, channel_count, codec, sample_rate, block_align, bits, num_samples; int loop_flag = 0, channel_count, codec, sample_rate, block_align, bits, num_samples;
off_t start_offset, stream_offset, chunk_offset, first_offset = 0x00; off_t start_offset, stream_offset, chunk_offset, first_offset = 0x00;
size_t stream_size; size_t stream_size;
int total_streams, target_stream = streamFile->stream_index; int total_subsongs, target_subsong = streamFile->stream_index;
/* check extensions */ /* check extensions */
if (!check_extensions(streamFile,"vxn")) if (!check_extensions(streamFile,"vxn"))
@ -31,13 +31,13 @@ VGMSTREAM * init_vgmstream_vxn(STREAMFILE *streamFile) {
* (the "Plst" and "Rule" chunks may have order info) */ * (the "Plst" and "Rule" chunks may have order info) */
if (!find_chunk_le(streamFile, 0x5365676D,first_offset,0, &chunk_offset,NULL)) /* "Segm" */ if (!find_chunk_le(streamFile, 0x5365676D,first_offset,0, &chunk_offset,NULL)) /* "Segm" */
goto fail; goto fail;
total_streams = read_32bitLE(chunk_offset+0x00, streamFile); total_subsongs = read_32bitLE(chunk_offset+0x00, streamFile);
if (target_stream == 0) target_stream = 1; if (target_subsong == 0) target_subsong = 1;
if (target_stream < 0 || target_stream > total_streams || total_streams < 1) goto fail; if (target_subsong < 0 || target_subsong > total_subsongs || total_subsongs < 1) goto fail;
stream_offset = read_32bitLE(chunk_offset+0x04 + (target_stream-1)*0x18 + 0x00, streamFile); stream_offset = read_32bitLE(chunk_offset+0x04 + (target_subsong-1)*0x18 + 0x00, streamFile);
stream_size = read_32bitLE(chunk_offset+0x04 + (target_stream-1)*0x18 + 0x04, streamFile); stream_size = read_32bitLE(chunk_offset+0x04 + (target_subsong-1)*0x18 + 0x04, streamFile);
num_samples = read_32bitLE(chunk_offset+0x04 + (target_stream-1)*0x18 + 0x08, streamFile); num_samples = read_32bitLE(chunk_offset+0x04 + (target_subsong-1)*0x18 + 0x08, streamFile);
if (!find_chunk_le(streamFile, 0x44617461,first_offset,0, &chunk_offset,NULL)) /* "Data" */ if (!find_chunk_le(streamFile, 0x44617461,first_offset,0, &chunk_offset,NULL)) /* "Data" */
goto fail; goto fail;
@ -50,8 +50,8 @@ VGMSTREAM * init_vgmstream_vxn(STREAMFILE *streamFile) {
vgmstream->sample_rate = sample_rate; vgmstream->sample_rate = sample_rate;
vgmstream->num_samples = num_samples; vgmstream->num_samples = num_samples;
vgmstream->num_streams = total_streams; vgmstream->num_streams = total_subsongs;
vgmstream->stream_size = stream_size;
vgmstream->meta_type = meta_VXN; vgmstream->meta_type = meta_VXN;
switch (codec) { switch (codec) {

View File

@ -16,7 +16,7 @@ VGMSTREAM * init_vgmstream_xvag(STREAMFILE *streamFile) {
off_t start_offset, loop_start = 0, loop_end = 0, chunk_offset; off_t start_offset, loop_start = 0, loop_end = 0, chunk_offset;
off_t first_offset = 0x20; off_t first_offset = 0x20;
size_t chunk_size; size_t chunk_size, stream_size;
/* check extension, case insensitive */ /* check extension, case insensitive */
if (!check_extensions(streamFile,"xvag")) if (!check_extensions(streamFile,"xvag"))
@ -51,7 +51,7 @@ VGMSTREAM * init_vgmstream_xvag(STREAMFILE *streamFile) {
interleave_factor = read_32bit(chunk_offset+0x10,streamFile); interleave_factor = read_32bit(chunk_offset+0x10,streamFile);
sample_rate = read_32bit(chunk_offset+0x14,streamFile); sample_rate = read_32bit(chunk_offset+0x14,streamFile);
/* 0x18: datasize */ stream_size = read_32bit(chunk_offset+0x18,streamFile);
/* extra data, seen in versions 0x61+ */ /* extra data, seen in versions 0x61+ */
if (chunk_size > 0x1c) { if (chunk_size > 0x1c) {
@ -86,6 +86,7 @@ VGMSTREAM * init_vgmstream_xvag(STREAMFILE *streamFile) {
vgmstream->sample_rate = sample_rate; vgmstream->sample_rate = sample_rate;
vgmstream->num_samples = num_samples; vgmstream->num_samples = num_samples;
vgmstream->num_streams = total_subsongs; vgmstream->num_streams = total_subsongs;
vgmstream->stream_size = (stream_size / total_subsongs);
vgmstream->meta_type = meta_XVAG; vgmstream->meta_type = meta_XVAG;
switch (codec) { switch (codec) {

View File

@ -354,6 +354,7 @@ VGMSTREAM * init_vgmstream_xwb(STREAMFILE *streamFile) {
vgmstream->loop_start_sample = xwb.loop_start_sample; vgmstream->loop_start_sample = xwb.loop_start_sample;
vgmstream->loop_end_sample = xwb.loop_end_sample; vgmstream->loop_end_sample = xwb.loop_end_sample;
vgmstream->num_streams = xwb.streams; vgmstream->num_streams = xwb.streams;
vgmstream->stream_size = xwb.stream_size;
vgmstream->meta_type = meta_XWB; vgmstream->meta_type = meta_XWB;
get_xsb_name(vgmstream->stream_name,STREAM_NAME_SIZE, target_stream, &xwb, streamFile); get_xsb_name(vgmstream->stream_name,STREAM_NAME_SIZE, target_stream, &xwb, streamFile);