mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-30 17:24:31 +01:00
cleanup: misc preparations
This commit is contained in:
parent
a6a113d813
commit
6d1a4bfc03
@ -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
11
src/vgmstream_init.h
Normal 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
|
Loading…
Reference in New Issue
Block a user