cleanup: misc preparations

This commit is contained in:
bnnm 2024-07-25 11:19:00 +02:00
parent a6a113d813
commit 6d1a4bfc03
2 changed files with 117 additions and 84 deletions

View File

@ -6,7 +6,7 @@
#include <string.h> #include <string.h>
#include <math.h> #include <math.h>
#include "vgmstream.h" #include "vgmstream.h"
#include "meta/meta.h" #include "vgmstream_init.h"
#include "layout/layout.h" #include "layout/layout.h"
#include "coding/coding.h" #include "coding/coding.h"
#include "base/decode.h" #include "base/decode.h"
@ -17,7 +17,7 @@
typedef VGMSTREAM* (*init_vgmstream_t)(STREAMFILE*); typedef VGMSTREAM* (*init_vgmstream_t)(STREAMFILE*);
static void try_dual_file_stereo(VGMSTREAM* opened_vgmstream, STREAMFILE* sf, init_vgmstream_t init_vgmstream_function); static void try_dual_file_stereo(VGMSTREAM* opened_vgmstream, STREAMFILE* sf, int format_id);
/* list of metadata parser functions that will recognize files, used on init */ /* list of metadata parser functions that will recognize files, used on init */
init_vgmstream_t init_vgmstream_functions[] = { init_vgmstream_t init_vgmstream_functions[] = {
@ -582,8 +582,7 @@ static const int init_vgmstream_count = LOCAL_ARRAY_LENGTH(init_vgmstream_functi
/* INIT/META */ /* INIT/META */
/*****************************************************************************/ /*****************************************************************************/
/* internal version with all parameters */ VGMSTREAM* detect_vgmstream_format(STREAMFILE* sf) {
static VGMSTREAM* init_vgmstream_internal(STREAMFILE* sf) {
if (!sf) if (!sf)
return NULL; return NULL;
@ -591,24 +590,48 @@ static VGMSTREAM* init_vgmstream_internal(STREAMFILE* sf) {
for (int i = 0; i < init_vgmstream_count; i++) { for (int i = 0; i < init_vgmstream_count; i++) {
init_vgmstream_t init_vgmstream_function = init_vgmstream_functions[i]; init_vgmstream_t init_vgmstream_function = init_vgmstream_functions[i];
/* call init function and see if valid VGMSTREAM was returned */ /* call init function and see if valid VGMSTREAM was returned */
VGMSTREAM* vgmstream = init_vgmstream_function(sf); VGMSTREAM* vgmstream = init_vgmstream_function(sf);
if (!vgmstream) if (!vgmstream)
continue; continue;
int format_id = i + 1;
/* validate + setup vgmstream */
if (!prepare_vgmstream(vgmstream, sf, format_id)) {
/* keep trying if wasn't valid, as simpler formats may return a vgmstream by mistake */
close_vgmstream(vgmstream);
continue;
}
return vgmstream;
}
/* not supported */
return NULL;
}
init_vgmstream_t get_vgmstream_format_init(int format_id) {
// ID is expected to be from 1...N, to distinguish from 0 = not set
if (format_id <= 0 || format_id > init_vgmstream_count)
return NULL;
return init_vgmstream_functions[format_id - 1];
}
bool prepare_vgmstream(VGMSTREAM* vgmstream, STREAMFILE* sf, int format_id) {
/* fail if there is nothing/too much to play (<=0 generates empty files, >N writes GBs of garbage) */ /* fail if there is nothing/too much to play (<=0 generates empty files, >N writes GBs of garbage) */
if (vgmstream->num_samples <= 0 || vgmstream->num_samples > VGMSTREAM_MAX_NUM_SAMPLES) { if (vgmstream->num_samples <= 0 || vgmstream->num_samples > VGMSTREAM_MAX_NUM_SAMPLES) {
VGM_LOG("VGMSTREAM: wrong num_samples %i\n", vgmstream->num_samples); VGM_LOG("VGMSTREAM: wrong num_samples %i\n", vgmstream->num_samples);
close_vgmstream(vgmstream); return false;
continue;
} }
/* everything should have a reasonable sample rate */ /* everything should have a reasonable sample rate */
if (vgmstream->sample_rate < VGMSTREAM_MIN_SAMPLE_RATE || vgmstream->sample_rate > VGMSTREAM_MAX_SAMPLE_RATE) { if (vgmstream->sample_rate < VGMSTREAM_MIN_SAMPLE_RATE || vgmstream->sample_rate > VGMSTREAM_MAX_SAMPLE_RATE) {
VGM_LOG("VGMSTREAM: wrong sample_rate %i\n", vgmstream->sample_rate); VGM_LOG("VGMSTREAM: wrong sample_rate %i\n", vgmstream->sample_rate);
close_vgmstream(vgmstream); return false;
continue;
} }
/* sanify loops and remove bad metadata */ /* sanify loops and remove bad metadata */
@ -626,7 +649,7 @@ static VGMSTREAM* init_vgmstream_internal(STREAMFILE* sf) {
/* test if candidate for dual stereo */ /* test if candidate for dual stereo */
if (vgmstream->channels == 1 && vgmstream->allow_dual_stereo == 1) { if (vgmstream->channels == 1 && vgmstream->allow_dual_stereo == 1) {
try_dual_file_stereo(vgmstream, sf, init_vgmstream_function); try_dual_file_stereo(vgmstream, sf, format_id);
} }
@ -663,8 +686,7 @@ static VGMSTREAM* init_vgmstream_internal(STREAMFILE* sf) {
/* files can have thousands subsongs, but let's put a limit */ /* files can have thousands subsongs, but let's put a limit */
if (vgmstream->num_streams < 0 || vgmstream->num_streams > VGMSTREAM_MAX_SUBSONGS) { if (vgmstream->num_streams < 0 || vgmstream->num_streams > VGMSTREAM_MAX_SUBSONGS) {
VGM_LOG("VGMSTREAM: wrong num_streams (ns=%i)\n", vgmstream->num_streams); VGM_LOG("VGMSTREAM: wrong num_streams (ns=%i)\n", vgmstream->num_streams);
close_vgmstream(vgmstream); return false;
continue;
} }
/* save info */ /* save info */
@ -676,11 +698,7 @@ static VGMSTREAM* init_vgmstream_internal(STREAMFILE* sf) {
setup_vgmstream(vgmstream); /* final setup */ setup_vgmstream(vgmstream); /* final setup */
return vgmstream; return true;
}
/* not supported */
return NULL;
} }
void setup_vgmstream(VGMSTREAM* vgmstream) { void setup_vgmstream(VGMSTREAM* vgmstream) {
@ -728,7 +746,7 @@ VGMSTREAM* init_vgmstream(const char* const filename) {
} }
VGMSTREAM* init_vgmstream_from_STREAMFILE(STREAMFILE* sf) { VGMSTREAM* init_vgmstream_from_STREAMFILE(STREAMFILE* sf) {
return init_vgmstream_internal(sf); return detect_vgmstream_format(sf);
} }
/* Reset a VGMSTREAM to its state at the start of playback (when a plugin seeks back to zero). */ /* Reset a VGMSTREAM to its state at the start of playback (when a plugin seeks back to zero). */
@ -807,7 +825,7 @@ VGMSTREAM* allocate_vgmstream(int channels, int loop_flag) {
vgmstream->mixer = mixer_init(vgmstream->channels); /* pre-init */ vgmstream->mixer = mixer_init(vgmstream->channels); /* pre-init */
//if (!vgmstream->mixer) goto fail; //if (!vgmstream->mixer) goto fail;
/* BEWARE: try_dual_file_stereo does some free'ing too */ /* BEWARE: merge_vgmstream does some free'ing too */
//vgmstream->stream_name_size = STREAM_NAME_SIZE; //vgmstream->stream_name_size = STREAM_NAME_SIZE;
return vgmstream; return vgmstream;
@ -1007,7 +1025,7 @@ fail:
/* See if there is a second file which may be the second channel, given an already opened mono vgmstream. /* See if there is a second file which may be the second channel, given an already opened mono vgmstream.
* If a suitable file is found, open it and change opened_vgmstream to a stereo vgmstream. */ * If a suitable file is found, open it and change opened_vgmstream to a stereo vgmstream. */
static void try_dual_file_stereo(VGMSTREAM* opened_vgmstream, STREAMFILE* sf, init_vgmstream_t init_vgmstream_function) { static void try_dual_file_stereo(VGMSTREAM* opened_vgmstream, STREAMFILE* sf, int format_id) {
/* filename search pairs for dual file stereo */ /* filename search pairs for dual file stereo */
static const char* const dfs_pairs[][2] = { static const char* const dfs_pairs[][2] = {
{"L","R"}, /* most common in .dsp and .vag */ {"L","R"}, /* most common in .dsp and .vag */
@ -1092,9 +1110,13 @@ static void try_dual_file_stereo(VGMSTREAM* opened_vgmstream, STREAMFILE* sf, in
/* filename didn't have a suitable L/R-pair name */ /* filename didn't have a suitable L/R-pair name */
if (dfs_pair == -1) if (dfs_pair == -1)
goto fail; return;
//;VGM_LOG("DFS: match %i filename=%s\n", dfs_pair, new_filename); //;VGM_LOG("DFS: match %i filename=%s\n", dfs_pair, new_filename);
init_vgmstream_t init_vgmstream_function = get_vgmstream_format_init(format_id);
if (init_vgmstream_function == NULL)
goto fail;
new_vgmstream = init_vgmstream_function(dual_sf); /* use the init function that just worked */ new_vgmstream = init_vgmstream_function(dual_sf); /* use the init function that just worked */
close_streamfile(dual_sf); close_streamfile(dual_sf);
if (!new_vgmstream) if (!new_vgmstream)

11
src/vgmstream_init.h Normal file
View File

@ -0,0 +1,11 @@
#ifndef _DETECTION_H_
#define _DETECTION_H_
#include "meta/meta.h"
#include "vgmstream.h"
bool prepare_vgmstream(VGMSTREAM* vgmstream, STREAMFILE* sf, int format_id);
VGMSTREAM* detect_vgmstream_format(STREAMFILE* sf);
init_vgmstream_t get_vgmstream_format_init(int format_id);
#endif