mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-18 03:26:57 +01:00
Simplify STREAMFILE handling in scd_int_layout
It's not the easiest thing to follow so here is what's going on with STREAMFILEs: - external player opens base-streamfile, with a base FILE - meta scd parses stuff, then per DSP channel/layer: - open temp-streamfile, which does custom IO with base-streamfile (doesn't open any FILE) - pass temp-streamfile to init_vgmstream_ngc_dsp_std - init parses ok, and re-opens temp-streamfile (with custom IO) as its own dsp-vgmstream-streamfile; internally it does fopen/fdopen the original FILE from base-streamfile - scd_int_layout stores the newly created VGMSTREAM (internally has the dsp-vgmstream-streamfile too) - close temp-streamfile, that doesn't close base-streamfile as it's wrapped to avoid doing so, nor affects dsp-vgmstream-streamfile in any way. - meta parsing is done, so external player closes base-streamfile (but the re-fopen'ed dsp-vgmstream-streamfile FILE remains) - vgmstream renders pcm buffers, etc - finally player calls close_vgmstream - scd_int_layout calls close_vgmstream for each stored VGMSTREAM - the VGMSTREAM internally closes the dsp-vgmstream-streamfile, which in turn closes its own FILE So ultimately all FILEs, STREAMFILEs and their clones should be properly handled and closed.
This commit is contained in:
parent
0ff0d864ee
commit
642c833fcd
@ -11,7 +11,6 @@ static void scd_ogg_v3_decryption_callback(void *ptr, size_t size, size_t nmemb,
|
||||
/* SCD - Square-Enix games (FF XIII, XIV) */
|
||||
VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
char filename[PATH_LIMIT];
|
||||
off_t start_offset, tables_offset, meta_offset, extradata_offset, name_offset = 0;
|
||||
int32_t stream_size, extradata_size, loop_start, loop_end;
|
||||
|
||||
@ -26,7 +25,6 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||
/* check extension, case insensitive */
|
||||
if ( !check_extensions(streamFile, "scd") )
|
||||
goto fail;
|
||||
streamFile->get_name(streamFile,filename,sizeof(filename));
|
||||
|
||||
/** main header **/
|
||||
if (read_32bitBE(0x00,streamFile) != 0x53454442 && /* "SEDB" */
|
||||
@ -281,7 +279,6 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||
|
||||
case 0x0A: /* DSP ADPCM [Dragon Quest X (Wii)] */
|
||||
case 0x15: { /* DSP ADPCM [Dragon Quest X (Wii U)] (no apparent differences except higher sample rate) */
|
||||
STREAMFILE * file;
|
||||
int i;
|
||||
const off_t interleave_size = 0x800;
|
||||
const off_t stride_size = interleave_size * channel_count;
|
||||
@ -308,28 +305,22 @@ VGMSTREAM * init_vgmstream_sqex_scd(STREAMFILE *streamFile) {
|
||||
}
|
||||
}
|
||||
|
||||
/* the primary streamfile we'll be using */
|
||||
file = streamFile->open(streamFile,filename,stride_size);
|
||||
if (!file) goto fail;
|
||||
|
||||
vgmstream->ch[0].streamfile = file;
|
||||
|
||||
data = malloc(sizeof(scd_int_codec_data));
|
||||
data->substream_count = channel_count;
|
||||
data->substreams = calloc(channel_count, sizeof(VGMSTREAM *));
|
||||
data->intfiles = calloc(channel_count, sizeof(STREAMFILE *));
|
||||
|
||||
vgmstream->codec_data = data;
|
||||
|
||||
for (i=0;i<channel_count;i++) {
|
||||
STREAMFILE * intfile = setup_scd_dsp_streamfile(file, start_offset+interleave_size*i, interleave_size, stride_size, total_size);
|
||||
if (!intfile) goto fail;
|
||||
STREAMFILE* temp_streamFile = setup_scd_dsp_streamfile(streamFile, start_offset+interleave_size*i, interleave_size, stride_size, total_size);
|
||||
if (!temp_streamFile) goto fail;
|
||||
|
||||
data->substreams[i] = init_vgmstream_ngc_dsp_std(intfile);
|
||||
data->intfiles[i] = intfile;
|
||||
data->substreams[i] = init_vgmstream_ngc_dsp_std(temp_streamFile);
|
||||
close_streamfile(temp_streamFile);
|
||||
if (!data->substreams[i]) goto fail;
|
||||
|
||||
/* TODO: only handles mono substreams, though that's all we have with DSP */
|
||||
|
||||
/* save start things so we can restart for seeking/looping */
|
||||
memcpy(data->substreams[i]->start_ch,data->substreams[i]->ch,sizeof(VGMSTREAMCHANNEL)*1);
|
||||
memcpy(data->substreams[i]->start_vgmstream,data->substreams[i],sizeof(VGMSTREAM));
|
||||
|
@ -804,13 +804,9 @@ void close_vgmstream(VGMSTREAM * vgmstream) {
|
||||
if (data->substreams) {
|
||||
int i;
|
||||
for (i=0;i<data->substream_count;i++) {
|
||||
/* note that the close_streamfile won't do anything but deallocate itself,
|
||||
* there is only one open file in vgmstream->ch[0].streamfile */
|
||||
close_vgmstream(data->substreams[i]);
|
||||
if(data->intfiles[i]) close_streamfile(data->intfiles[i]);
|
||||
}
|
||||
free(data->substreams);
|
||||
free(data->intfiles);
|
||||
}
|
||||
|
||||
free(data);
|
||||
@ -2406,7 +2402,7 @@ static STREAMFILE * get_vgmstream_average_bitrate_channel_streamfile(VGMSTREAM *
|
||||
|
||||
if (vgmstream->layout_type==layout_scd_int) {
|
||||
scd_int_codec_data *data = (scd_int_codec_data *) vgmstream->codec_data;
|
||||
return data->intfiles[channel];
|
||||
return data->substreams[channel]->ch[0].streamfile;
|
||||
}
|
||||
|
||||
if (vgmstream->coding_type==coding_NWA) {
|
||||
|
@ -1073,7 +1073,6 @@ typedef struct {
|
||||
typedef struct {
|
||||
int substream_count;
|
||||
VGMSTREAM **substreams;
|
||||
STREAMFILE **intfiles;
|
||||
} scd_int_codec_data;
|
||||
|
||||
typedef struct {
|
||||
|
Loading…
x
Reference in New Issue
Block a user