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:
bnnm 2018-03-30 19:14:37 +02:00
parent 0ff0d864ee
commit 642c833fcd
3 changed files with 6 additions and 20 deletions

View File

@ -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));

View File

@ -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) {

View File

@ -1073,7 +1073,6 @@ typedef struct {
typedef struct {
int substream_count;
VGMSTREAM **substreams;
STREAMFILE **intfiles;
} scd_int_codec_data;
typedef struct {