If you have an issue with any of our projects. feel free to register.

Commit 4ef5283f authored by Christopher Snowhill's avatar Christopher Snowhill

Updated VGMStream to r1050-3468-gc3ed1fad

parent 24231ecd
......@@ -551,7 +551,7 @@ ffmpeg_codec_data* init_ffmpeg_ue4_opus(STREAMFILE* sf, off_t start_offset, size
ffmpeg_codec_data* init_ffmpeg_ea_opus(STREAMFILE* sf, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate);
ffmpeg_codec_data* init_ffmpeg_x_opus(STREAMFILE* sf, off_t table_offset, int table_count, off_t data_offset, size_t data_size, int channels, int skip);
ffmpeg_codec_data* init_ffmpeg_fsb_opus(STREAMFILE* sf, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate);
ffmpeg_codec_data* init_ffmpeg_wwise_opus(STREAMFILE* sf, off_t table_offset, int table_count, off_t data_offset, size_t data_size, int channels, int skip);
ffmpeg_codec_data* init_ffmpeg_wwise_opus(STREAMFILE* sf, off_t data_offset, size_t data_size, opus_config* cfg);
size_t switch_opus_get_samples(off_t offset, size_t stream_size, STREAMFILE* sf);
......
......@@ -184,7 +184,7 @@ void decode_ea_xa_v2(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspac
#endif
/* EA XA v1 (mono/stereo) */
void decode_ea_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do,int channel, int is_stereo) {
void decode_ea_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel, int is_stereo) {
uint8_t frame_info;
int32_t coef1, coef2;
int i, sample_count, shift;
......@@ -194,8 +194,9 @@ void decode_ea_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing
int frame_samples = 28;
first_sample = first_sample % frame_samples;
/* header */
if (is_stereo) {
/* header (coefs ch0+ch1 + shift ch0+ch1) */
/* coefs ch0+ch1 + shift ch0+ch1 */
frame_info = read_8bit(stream->offset + 0x00, stream->streamfile);
coef1 = EA_XA_TABLE[(hn ? frame_info >> 4 : frame_info & 0x0F) + 0];
coef2 = EA_XA_TABLE[(hn ? frame_info >> 4 : frame_info & 0x0F) + 4];
......@@ -203,7 +204,7 @@ void decode_ea_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing
frame_info = read_8bit(stream->offset + 0x01, stream->streamfile);
shift = (hn ? frame_info >> 4 : frame_info & 0x0F) + 8;
} else {
/* header (coefs + shift ch0) */
/* coefs + shift ch0 */
frame_info = read_8bit(stream->offset + 0x00, stream->streamfile);
coef1 = EA_XA_TABLE[(frame_info >> 4) + 0];
coef2 = EA_XA_TABLE[(frame_info >> 4) + 4];
......@@ -233,7 +234,7 @@ void decode_ea_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing
stream->offset += frame_size;
}
/* Maxis EA-XA v1 (mono+stereo) with byte-interleave layout in stereo mode */
/* Maxis EA-XA v1 (mono/stereo) with byte-interleave layout in stereo mode */
void decode_maxis_xa(VGMSTREAMCHANNEL * stream, sample * outbuf, int channelspacing, int32_t first_sample, int32_t samples_to_do, int channel) {
uint8_t frame_info;
int32_t coef1, coef2;
......
......@@ -490,11 +490,11 @@ static size_t make_opus_header(uint8_t* buf, int buf_size, opus_config *cfg) {
if (mapping_family > 0) {
int i;
/* internal mono/stereo streams (N mono/stereo streams form M channels) */
/* internal mono/stereo streams (N mono/stereo streams that make M channels) */
put_u8(buf+0x13, cfg->stream_count);
/* joint stereo streams (rest would be mono, so 6ch can be 2ch+2ch+1ch+1ch = 2 coupled */
/* joint stereo streams (rest would be mono, so 6ch can be 2ch+2ch+1ch+1ch = 2 coupled in 4 streams */
put_u8(buf+0x14, cfg->coupled_count);
/* mapping bits per channel? */
/* mapping per channel (order of channels, ex: 0x000104050203) */
for (i = 0; i < cfg->channels; i++) {
put_u8(buf+0x15+i, cfg->channel_mapping[i]);
}
......@@ -753,8 +753,8 @@ ffmpeg_codec_data* init_ffmpeg_x_opus(STREAMFILE* sf, off_t table_offset, int ta
ffmpeg_codec_data* init_ffmpeg_fsb_opus(STREAMFILE* sf, off_t start_offset, size_t data_size, int channels, int skip, int sample_rate) {
return init_ffmpeg_custom_opus(sf, start_offset, data_size, channels, skip, sample_rate, OPUS_FSB);
}
ffmpeg_codec_data* init_ffmpeg_wwise_opus(STREAMFILE* sf, off_t table_offset, int table_count, off_t data_offset, size_t data_size, int channels, int skip) {
return init_ffmpeg_custom_table_opus(sf, table_offset, table_count, data_offset, data_size, channels, skip, 0, OPUS_WWISE);
ffmpeg_codec_data* init_ffmpeg_wwise_opus(STREAMFILE* sf, off_t data_offset, size_t data_size, opus_config* cfg) {
return init_ffmpeg_custom_opus_config(sf, data_offset, data_size, cfg, OPUS_WWISE);
}
static opus_type_t get_ue4opus_version(STREAMFILE* sf, off_t offset) {
......
......@@ -197,7 +197,7 @@ void decode_oki4s(VGMSTREAMCHANNEL* stream, sample_t* outbuf, int channelspacing
stream->offset + i : /* stereo: one nibble per channel */
stream->offset + i/2; /* mono: consecutive nibbles (assumed) */
int nibble_shift =
is_stereo ? (!(channel&1) ? 0:4) : (!(i&1) ? 0:4); /* even = low, odd = high */
is_stereo ? ((channel&1) ? 0:4) : ((i&1) ? 0:4); /* even = high, odd = low */
oki4s_expand_nibble(stream, byte_offset,nibble_shift, &hist1, &step_index, &out_sample);
outbuf[sample_count] = (out_sample);
......
......@@ -341,6 +341,7 @@ int get_vgmstream_samples_per_frame(VGMSTREAM* vgmstream) {
case coding_SDX2:
case coding_SDX2_int:
case coding_CBD2:
case coding_CBD2_int:
case coding_ACM:
case coding_DERF:
case coding_WADY:
......@@ -540,6 +541,7 @@ int get_vgmstream_frame_size(VGMSTREAM* vgmstream) {
case coding_SDX2:
case coding_SDX2_int:
case coding_CBD2:
case coding_CBD2_int:
case coding_DERF:
case coding_WADY:
case coding_NWA:
......
......@@ -25,7 +25,8 @@ static const char* extension_list[] = {
"208",
"2dx9",
"2pfs",
"4", // for Game.com audio
"3do",
"4", //for Game.com audio
"8", //txth/reserved [Gungage (PS1)]
"800",
"9tav",
......@@ -333,6 +334,7 @@ static const char* extension_list[] = {
"musc",
"musx",
"mvb", //txth/reserved [Porsche Challenge (PS1)]
"mwa", //txth/reserved [Fatal Frame (Xbox)]
"mwv",
"mxst",
"myspd",
......@@ -942,7 +944,7 @@ static const meta_info meta_info_list[] = {
{meta_DSP_WSI, "Alone in the Dark .WSI header"},
{meta_AIFC, "Apple AIFF-C (Audio Interchange File Format) header"},
{meta_AIFF, "Apple AIFF (Audio Interchange File Format) header"},
{meta_STR_SNDS, "3DO .str header"},
{meta_STR_SNDS, "3DO SNDS header"},
{meta_WS_AUD, "Westwood Studios .aud header"},
{meta_WS_AUD_old, "Westwood Studios .aud (old) header"},
{meta_PS2_IVB, "IVB/BVII header"},
......
#include "layout.h"
#include "../vgmstream.h"
/* set up for the block at the given offset */
void block_update_str_snds(off_t block_offset, VGMSTREAM * vgmstream) {
off_t current_chunk;
size_t file_size;
void block_update_str_snds(off_t block_offset, VGMSTREAM* vgmstream) {
STREAMFILE* sf = vgmstream->ch[0].streamfile;
uint32_t block_type, block_subtype, block_size, block_current;
int i;
STREAMFILE *streamfile;
int FoundSSMP = 0;
off_t SSMP_offset = -1;
current_chunk = block_offset;
streamfile = vgmstream->ch[0].streamfile;
file_size = get_streamfile_size(streamfile);
/* we may have to skip some chunks */
while (!FoundSSMP && current_chunk < file_size) {
if (current_chunk+read_32bitBE(current_chunk+4,streamfile)>=file_size)
break;
switch (read_32bitBE(current_chunk,streamfile)) {
case 0x534e4453: /* SNDS */
/* SSMP */
if (read_32bitBE(current_chunk+0x10,streamfile)==0x53534d50) {
FoundSSMP = 1;
SSMP_offset = current_chunk;
}
break;
case 0x46494c4c: /* FILL, the main culprit */
default:
break;
}
current_chunk += read_32bitBE(current_chunk+4,streamfile);
/* EOF reads: signal we have nothing and let the layout fail */
if (block_offset >= get_streamfile_size(sf)) {
vgmstream->current_block_samples = -1;
return;
}
if (!FoundSSMP) {
/* if we couldn't find it all we can do is try playing the current
* block, which is going to suck */
vgmstream->current_block_offset = block_offset;
block_type = read_u32be(block_offset + 0x00,sf);
block_size = read_u32be(block_offset + 0x04,sf);
block_current = 0; /* ignore block by default (other chunks include MPVD + VHDR/FRAM and FILL) */
if (block_type == 0x534e4453) { /* SNDS */
block_subtype = read_u32be(block_offset + 0x10,sf); /* SNDS */
if (block_subtype == 0x53534d50) {
block_current = read_u32be(block_offset + 0x14, sf) / vgmstream->channels;
}
}
vgmstream->current_block_offset = SSMP_offset;
vgmstream->current_block_size = (read_32bitBE(
vgmstream->current_block_offset+4,
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);
/* seen in Battle Tryst video frames */
if (block_size % 0x04)
block_size += 0x04 - (block_size % 0x04);
vgmstream->current_block_offset = block_offset;
vgmstream->next_block_offset = block_offset + block_size;
vgmstream->current_block_size = block_current;
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;
}
}
......@@ -76,6 +76,18 @@ decode_fail:
}
void seek_layout_layered(VGMSTREAM* vgmstream, int32_t seek_sample) {
int layer;
layered_layout_data* data = vgmstream->layout_data;
for (layer = 0; layer < data->layer_count; layer++) {
seek_vgmstream(data->layers[layer], seek_sample);
}
vgmstream->current_sample = seek_sample;
vgmstream->samples_into_block = seek_sample;
}
void loop_layout_layered(VGMSTREAM* vgmstream, int32_t loop_sample) {
int layer;
layered_layout_data* data = vgmstream->layout_data;
......
......@@ -59,7 +59,8 @@ segmented_layout_data* init_layout_segmented(int segment_count);
int setup_layout_segmented(segmented_layout_data* data);
void free_layout_segmented(segmented_layout_data* data);
void reset_layout_segmented(segmented_layout_data* data);
void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t seek_sample);
void seek_layout_segmented(VGMSTREAM* vgmstream, int32_t seek_sample);
void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample);
VGMSTREAM *allocate_segmented_vgmstream(segmented_layout_data* data, int loop_flag, int loop_start_segment, int loop_end_segment);
void render_vgmstream_layered(sample_t* buffer, int32_t sample_count, VGMSTREAM* vgmstream);
......@@ -67,7 +68,8 @@ layered_layout_data* init_layout_layered(int layer_count);
int setup_layout_layered(layered_layout_data* data);
void free_layout_layered(layered_layout_data* data);
void reset_layout_layered(layered_layout_data* data);
void loop_layout_layered(VGMSTREAM* vgmstream, int32_t seek_sample);
void seek_layout_layered(VGMSTREAM* vgmstream, int32_t seek_sample);
void loop_layout_layered(VGMSTREAM* vgmstream, int32_t loop_sample);
VGMSTREAM *allocate_layered_vgmstream(layered_layout_data* data);
#endif
......@@ -7,6 +7,7 @@
#define VGMSTREAM_MAX_SEGMENTS 1024
#define VGMSTREAM_SEGMENT_SAMPLE_BUFFER 8192
static inline void copy_samples(sample_t* outbuf, segmented_layout_data* data, int current_channels, int32_t samples_to_do, int32_t samples_written);
/* Decodes samples for segmented streams.
* Chains together sequential vgmstreams, for data divided into separate sections or files
......@@ -15,9 +16,10 @@ void render_vgmstream_segmented(sample_t* outbuf, int32_t sample_count, VGMSTREA
int samples_written = 0, samples_this_block;
segmented_layout_data* data = vgmstream->layout_data;
int use_internal_buffer = 0;
int current_channels = 0;
/* normally uses outbuf directly (faster?) but could need internal buffer if downmixing */
if (vgmstream->channels != data->input_channels) {
if (vgmstream->channels != data->input_channels || data->mixed_channels) {
use_internal_buffer = 1;
}
......@@ -27,6 +29,7 @@ void render_vgmstream_segmented(sample_t* outbuf, int32_t sample_count, VGMSTREA
}
samples_this_block = vgmstream_get_samples(data->segments[data->current_segment]);
mixing_info(data->segments[data->current_segment], NULL, &current_channels);
while (samples_written < sample_count) {
int samples_to_do;
......@@ -34,6 +37,7 @@ void render_vgmstream_segmented(sample_t* outbuf, int32_t sample_count, VGMSTREA
if (vgmstream->loop_flag && vgmstream_do_loop(vgmstream)) {
/* handle looping (loop_layout has been called below, changes segments/state) */
samples_this_block = vgmstream_get_samples(data->segments[data->current_segment]);
mixing_info(data->segments[data->current_segment], NULL, &current_channels);
continue;
}
......@@ -50,6 +54,7 @@ void render_vgmstream_segmented(sample_t* outbuf, int32_t sample_count, VGMSTREA
reset_vgmstream(data->segments[data->current_segment]);
samples_this_block = vgmstream_get_samples(data->segments[data->current_segment]);
mixing_info(data->segments[data->current_segment], NULL, &current_channels);
vgmstream->samples_into_block = 0;
continue;
}
......@@ -73,10 +78,7 @@ void render_vgmstream_segmented(sample_t* outbuf, int32_t sample_count, VGMSTREA
data->segments[data->current_segment]);
if (use_internal_buffer) {
int s;
for (s = 0; s < samples_to_do * data->output_channels; s++) {
outbuf[samples_written * data->output_channels + s] = data->buffer[s];
}
copy_samples(outbuf, data, current_channels, samples_to_do, samples_written);
}
samples_written += samples_to_do;
......@@ -89,7 +91,31 @@ decode_fail:
memset(outbuf + samples_written * data->output_channels, 0, (sample_count - samples_written) * data->output_channels * sizeof(sample_t));
}
void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample) {
static inline void copy_samples(sample_t* outbuf, segmented_layout_data* data, int current_channels, int32_t samples_to_do, int32_t samples_written) {
int ch_out = data->output_channels;
int ch_in = current_channels;
int pos = samples_written * ch_out;
int s;
if (ch_in == ch_out) { /* most common and probably faster */
for (s = 0; s < samples_to_do * ch_out; s++) {
outbuf[pos + s] = data->buffer[s];
}
}
else {
int ch;
for (s = 0; s < samples_to_do; s++) {
for (ch = 0; ch < ch_in; ch++) {
outbuf[pos + s*ch_out + ch] = data->buffer[s*ch_in + ch];
}
for (ch = ch_in; ch < ch_out; ch++) {
outbuf[pos + s*ch_out + ch] = 0;
}
}
}
}
void seek_layout_segmented(VGMSTREAM* vgmstream, int32_t seek_sample) {
int segment, total_samples;
segmented_layout_data* data = vgmstream->layout_data;
......@@ -98,13 +124,13 @@ void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample) {
while (total_samples < vgmstream->num_samples) {
int32_t segment_samples = vgmstream_get_samples(data->segments[segment]);
/* find if loop falls within segment's samples */
if (loop_sample >= total_samples && loop_sample < total_samples + segment_samples) {
int32_t loop_relative = loop_sample - total_samples;
/* find if sample falls within segment's samples */
if (seek_sample >= total_samples && seek_sample < total_samples + segment_samples) {
int32_t seek_relative = seek_sample - total_samples;
seek_vgmstream(data->segments[segment], loop_relative);
seek_vgmstream(data->segments[segment], seek_relative);
data->current_segment = segment;
vgmstream->samples_into_block = loop_relative;
vgmstream->samples_into_block = seek_relative;
break;
}
total_samples += segment_samples;
......@@ -112,10 +138,14 @@ void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample) {
}
if (segment == data->segment_count) {
VGM_LOG("SEGMENTED: can't find loop segment\n");
VGM_LOG("SEGMENTED: can't find seek segment\n");
}
}
void loop_layout_segmented(VGMSTREAM* vgmstream, int32_t loop_sample) {
seek_layout_segmented(vgmstream, loop_sample);
}
segmented_layout_data* init_layout_segmented(int segment_count) {
segmented_layout_data* data = NULL;
......@@ -139,7 +169,7 @@ fail:
}
int setup_layout_segmented(segmented_layout_data* data) {
int i, max_input_channels = 0, max_output_channels = 0;
int i, max_input_channels = 0, max_output_channels = 0, mixed_channels = 0;
sample_t *outbuf_re = NULL;
......@@ -170,8 +200,8 @@ int setup_layout_segmented(segmented_layout_data* data) {
}
}
/* different segments may have different input channels, though output should be
* the same for all (ex. 2ch + 1ch segments, but 2ch segment is downmixed to 1ch) */
/* different segments may have different input or output channels, we
* need to know maxs to properly handle */
mixing_info(data->segments[i], &segment_input_channels, &segment_output_channels);
if (max_input_channels < segment_input_channels)
max_input_channels = segment_input_channels;
......@@ -183,11 +213,12 @@ int setup_layout_segmented(segmented_layout_data* data) {
mixing_info(data->segments[i-1], NULL, &prev_output_channels);
if (segment_output_channels != prev_output_channels) {
VGM_LOG("SEGMENTED: segment %i has wrong channels %i vs prev channels %i\n", i, segment_output_channels, prev_output_channels);
goto fail;
mixed_channels = 1;
//VGM_LOG("SEGMENTED: segment %i has wrong channels %i vs prev channels %i\n", i, segment_output_channels, prev_output_channels);
//goto fail;
}
/* a bit weird, but no matter */
/* a bit weird, but no matter (should resample) */
if (data->segments[i]->sample_rate != data->segments[i-1]->sample_rate) {
VGM_LOG("SEGMENTED: segment %i has different sample rate\n", i);
}
......@@ -214,6 +245,7 @@ int setup_layout_segmented(segmented_layout_data* data) {
data->input_channels = max_input_channels;
data->output_channels = max_output_channels;
data->mixed_channels = mixed_channels;
return 1;
fail:
......
......@@ -105,7 +105,7 @@ VGMSTREAM * init_vgmstream_aax(STREAMFILE *streamFile) {
}
}
channel_count = data->segments[0]->channels;
channel_count = data->output_channels;
/* build the VGMSTREAM */
......
......@@ -36,7 +36,6 @@
static VGMSTREAM * init_vgmstream_eaaudiocore_header(STREAMFILE* sf_head, STREAMFILE* sf_data, off_t header_offset, off_t start_offset, meta_t meta_type, int standalone);
static VGMSTREAM *parse_s10a_header(STREAMFILE* sf, off_t offset, uint16_t target_index, off_t ast_offset);
VGMSTREAM * init_vgmstream_gin_header(STREAMFILE* sf, off_t offset);
/* .SNR+SNS - from EA latest games (~2005-2010), v0 header */
......@@ -375,12 +374,13 @@ fail:
/* EA HDR/STH/DAT - seen in older 7th gen games, used for storing speech */
VGMSTREAM * init_vgmstream_ea_hdr_sth_dat(STREAMFILE* sf) {
int target_stream = sf->stream_index;
uint32_t snr_offset, sns_offset, block_size;
uint16_t sth_offset, sth_offset2;
uint8_t userdata_size, total_sounds, block_id;
off_t snr_offset, sns_offset, sth_offset, sth_offset2;
size_t dat_size, block_size;
STREAMFILE *datFile = NULL, *sthFile = NULL;
size_t dat_size;
STREAMFILE *sf_dat = NULL, *sf_sth = NULL;
VGMSTREAM *vgmstream;
int32_t(*read_32bit)(off_t, STREAMFILE*);
uint32_t(*read_u32)(off_t, STREAMFILE*);
/* 0x00: ID */
/* 0x02: parameters (userdata size, ...) */
......@@ -388,46 +388,46 @@ VGMSTREAM * init_vgmstream_ea_hdr_sth_dat(STREAMFILE* sf) {
/* 0x04: sub-ID (used for different police voices in NFS games) */
/* 0x08: sample repeat (alt number of files?) */
/* 0x09: block size (always zero?) */
/* 0x0A: number of blocks (related to size?) */
/* 0x0C: number of sub-banks (always zero?) */
/* 0x0E: padding */
/* 0x0a: number of blocks (related to size?) */
/* 0x0c: number of sub-banks (always zero?) */
/* 0x0e: padding */
/* 0x10: table start */
if (!check_extensions(sf, "hdr"))
goto fail;
if (read_8bit(0x09, sf) != 0)
if (read_u8(0x09, sf) != 0)
goto fail;
if (read_32bitBE(0x0c, sf) != 0)
if (read_u32be(0x0c, sf) != 0)
goto fail;
/* first offset is always zero */
if (read_16bitBE(0x10, sf) != 0)
if (read_u16be(0x10, sf) != 0)
goto fail;
sthFile = open_streamfile_by_ext(sf, "sth");
if (!sthFile)
sf_sth = open_streamfile_by_ext(sf, "sth");
if (!sf_sth)
goto fail;
datFile = open_streamfile_by_ext(sf, "dat");
if (!datFile)
sf_dat = open_streamfile_by_ext(sf, "dat");
if (!sf_dat)
goto fail;
/* STH always starts with the first offset of zero */
sns_offset = read_32bitBE(0x00, sthFile);
sns_offset = read_u32be(0x00, sf_sth);
if (sns_offset != 0)
goto fail;
/* check if DAT starts with a correct SNS block */
block_id = read_8bit(0x00, datFile);
block_id = read_u8(0x00, sf_dat);
if (block_id != EAAC_BLOCKID0_DATA && block_id != EAAC_BLOCKID0_END)
goto fail;
userdata_size = read_8bit(0x02, sf);
total_sounds = read_8bit(0x03, sf);
userdata_size = read_u8(0x02, sf) & 0x0F;
total_sounds = read_u8(0x03, sf);
if (read_8bit(0x08, sf) > total_sounds)
if (read_u8(0x08, sf) > total_sounds)
goto fail;
if (target_stream == 0) target_stream = 1;
......@@ -435,14 +435,14 @@ VGMSTREAM * init_vgmstream_ea_hdr_sth_dat(STREAMFILE* sf) {
goto fail;
/* offsets in HDR are always big endian */
sth_offset = (uint16_t)read_16bitBE(0x10 + (0x02 + userdata_size) * (target_stream - 1), sf);
sth_offset = read_u16be(0x10 + (0x02 + userdata_size) * (target_stream - 1), sf);
#if 0
snr_offset = sth_offset + 0x04;
sns_offset = read_32bit(sth_offset + 0x00, sthFile);
sns_offset = read_u32(sth_offset + 0x00, sf_sth);
#else
/* we can't reliably detect byte endianness so we're going to find the sound the hacky way */
dat_size = get_streamfile_size(datFile);
/* overly intricate way to detect byte endianness because of the simplicity of HDR format */
dat_size = get_streamfile_size(sf_dat);
snr_offset = 0;
sns_offset = 0;
......@@ -456,8 +456,8 @@ VGMSTREAM * init_vgmstream_ea_hdr_sth_dat(STREAMFILE* sf) {
if (sns_offset >= dat_size)
goto fail;
block_id = read_8bit(sns_offset, datFile);
block_size = read_32bitBE(sns_offset, datFile) & 0x00FFFFFF;
block_id = read_u8(sns_offset, sf_dat);
block_size = read_u32be(sns_offset, sf_dat) & 0x00FFFFFF;
if (block_size == 0)
goto fail;
......@@ -470,36 +470,37 @@ VGMSTREAM * init_vgmstream_ea_hdr_sth_dat(STREAMFILE* sf) {
break;
}
sth_offset2 = (uint16_t)read_16bitBE(0x10 + (0x02 + userdata_size) * 1, sf);
if (sns_offset == read_32bitBE(sth_offset2, sthFile)) {
read_32bit = read_32bitBE;
} else if (sns_offset == read_32bitLE(sth_offset2, sthFile)) {
read_32bit = read_32bitLE;
sns_offset = align_size_to_block(sns_offset, 0x40);
sth_offset2 = read_u16be(0x10 + (0x02 + userdata_size) * 1, sf);
if (sns_offset == read_u32be(sth_offset2, sf_sth)) {
read_u32 = read_u32be;
} else if (sns_offset == read_u32le(sth_offset2, sf_sth)) {
read_u32 = read_u32le;
} else {
goto fail;
}
snr_offset = sth_offset + 0x04;
sns_offset = read_32bit(sth_offset + 0x00, sthFile);
sns_offset = read_u32(sth_offset + 0x00, sf_sth);
}
#endif
block_id = read_8bit(sns_offset, datFile);
block_id = read_u8(sns_offset, sf_dat);
if (block_id != EAAC_BLOCKID0_DATA && block_id != EAAC_BLOCKID0_END)
goto fail;
vgmstream = init_vgmstream_eaaudiocore_header(sthFile, datFile, snr_offset, sns_offset, meta_EA_SNR_SNS, 0);
vgmstream = init_vgmstream_eaaudiocore_header(sf_sth, sf_dat, snr_offset, sns_offset, meta_EA_SNR_SNS, 0);
if (!vgmstream)
goto fail;
vgmstream->num_streams = total_sounds;
close_streamfile(sthFile);