diff --git a/src/meta/ea_schl.c b/src/meta/ea_schl.c index bc80e5a3..6e3411a7 100644 --- a/src/meta/ea_schl.c +++ b/src/meta/ea_schl.c @@ -1337,8 +1337,8 @@ static VGMSTREAM * init_vgmstream_ea_variable_header(STREAMFILE* sf, ea_header* vgmstream->stream_size = ea->stream_size; - /* open files; channel offsets are updated below */ - if (!vgmstream_open_stream(vgmstream, sf, start_offset)) + /* open files; channel offsets are updated below (force multibuffer for bnk) */ + if (!vgmstream_open_stream_bf(vgmstream, sf, start_offset, 1)) goto fail; diff --git a/src/vgmstream.c b/src/vgmstream.c index dd33e8b7..4960b780 100644 --- a/src/vgmstream.c +++ b/src/vgmstream.c @@ -2860,8 +2860,11 @@ int get_vgmstream_average_bitrate(VGMSTREAM * vgmstream) { * - opens its own streamfile from on a base one. One streamfile per channel may be open (to improve read/seeks). * Should be called in metas before returning the VGMSTREAM. */ -int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t start_offset) { - STREAMFILE * file = NULL; +int vgmstream_open_stream(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t start_offset) { + return vgmstream_open_stream_bf(vgmstream, sf, start_offset, 0); +} +int vgmstream_open_stream_bf(VGMSTREAM* vgmstream, STREAMFILE* sf, off_t start_offset, int force_multibuffer) { + STREAMFILE* file = NULL; char filename[PATH_LIMIT]; int ch; int use_streamfile_per_channel = 0; @@ -2953,6 +2956,11 @@ int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t s use_streamfile_per_channel = 1; } + /* for hard-to-detect fixed offsets or full interleave */ + if (force_multibuffer) { + use_streamfile_per_channel = 1; + } + /* for mono or codecs like IMA (XBOX, MS IMA, MS ADPCM) where channels work with the same bytes */ if (vgmstream->layout_type == layout_none) { use_same_offset_per_channel = 1; @@ -2964,17 +2972,16 @@ int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t s is_stereo_codec = 1; } - if (streamFile == NULL || start_offset < 0) { + if (sf == NULL || start_offset < 0) { VGM_LOG("VGMSTREAM: buggy code (null streamfile / wrong start_offset)\n"); goto fail; } - - get_streamfile_name(streamFile,filename,sizeof(filename)); + get_streamfile_name(sf, filename, sizeof(filename)); /* open the file for reading by each channel */ { if (!use_streamfile_per_channel) { - file = open_streamfile(streamFile,filename); + file = open_streamfile(sf, filename); if (!file) goto fail; } @@ -2992,13 +2999,13 @@ int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t s /* open new one if needed, useful to avoid jumping around when each channel data is too apart * (don't use when data is close as it'd make buffers read the full file multiple times) */ if (use_streamfile_per_channel) { - file = open_streamfile(streamFile,filename); + file = open_streamfile(sf,filename); if (!file) goto fail; } vgmstream->ch[ch].streamfile = file; - vgmstream->ch[ch].channel_start_offset = - vgmstream->ch[ch].offset = offset; + vgmstream->ch[ch].channel_start_offset = offset; + vgmstream->ch[ch].offset = offset; } } diff --git a/src/vgmstream.h b/src/vgmstream.h index db5b6d25..413fe5d6 100644 --- a/src/vgmstream.h +++ b/src/vgmstream.h @@ -1374,6 +1374,7 @@ int vgmstream_do_loop(VGMSTREAM * vgmstream); /* Open the stream for reading at offset (taking into account layouts, channels and so on). * Returns 0 on failure */ int vgmstream_open_stream(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t start_offset); +int vgmstream_open_stream_bf(VGMSTREAM * vgmstream, STREAMFILE *streamFile, off_t start_offset, int force_multibuffer); /* Get description info */ void get_vgmstream_coding_description(VGMSTREAM *vgmstream, char *out, size_t out_size);