mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-30 17:24:31 +01:00
cleanup: move code
This commit is contained in:
parent
06db5fca76
commit
1169b68b99
@ -1601,10 +1601,10 @@ int decode_get_samples_to_do(int samples_this_block, int samples_per_frame, VGMS
|
|||||||
return samples_to_do;
|
return samples_to_do;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detect loop start and save values, or detect loop end and restore (loop back).
|
|
||||||
* Returns 1 if loop was done. */
|
/* Detect loop start and save values, or detect loop end and restore (loop back). Returns true if loop was done. */
|
||||||
int decode_do_loop(VGMSTREAM* vgmstream) {
|
bool decode_do_loop(VGMSTREAM* vgmstream) {
|
||||||
/*if (!vgmstream->loop_flag) return 0;*/
|
//if (!vgmstream->loop_flag) return false;
|
||||||
|
|
||||||
/* is this the loop end? = new loop, continue from loop_start_sample */
|
/* is this the loop end? = new loop, continue from loop_start_sample */
|
||||||
if (vgmstream->current_sample == vgmstream->loop_end_sample) {
|
if (vgmstream->current_sample == vgmstream->loop_end_sample) {
|
||||||
@ -1613,8 +1613,8 @@ int decode_do_loop(VGMSTREAM* vgmstream) {
|
|||||||
* (only needed with the "play stream end after looping N times" option enabled) */
|
* (only needed with the "play stream end after looping N times" option enabled) */
|
||||||
vgmstream->loop_count++;
|
vgmstream->loop_count++;
|
||||||
if (vgmstream->loop_target && vgmstream->loop_target == vgmstream->loop_count) {
|
if (vgmstream->loop_target && vgmstream->loop_target == vgmstream->loop_count) {
|
||||||
vgmstream->loop_flag = 0; /* could be improved but works ok, will be restored on resets */
|
vgmstream->loop_flag = false; /* could be improved but works ok, will be restored on resets */
|
||||||
return 0;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* against everything I hold sacred, preserve adpcm history before looping for certain types */
|
/* against everything I hold sacred, preserve adpcm history before looping for certain types */
|
||||||
@ -1623,8 +1623,7 @@ int decode_do_loop(VGMSTREAM* vgmstream) {
|
|||||||
vgmstream->meta_type == meta_DSP_CSTR ||
|
vgmstream->meta_type == meta_DSP_CSTR ||
|
||||||
vgmstream->coding_type == coding_PSX ||
|
vgmstream->coding_type == coding_PSX ||
|
||||||
vgmstream->coding_type == coding_PSX_badflags) {
|
vgmstream->coding_type == coding_PSX_badflags) {
|
||||||
int ch;
|
for (int ch = 0; ch < vgmstream->channels; ch++) {
|
||||||
for (ch = 0; ch < vgmstream->channels; ch++) {
|
|
||||||
vgmstream->loop_ch[ch].adpcm_history1_16 = vgmstream->ch[ch].adpcm_history1_16;
|
vgmstream->loop_ch[ch].adpcm_history1_16 = vgmstream->ch[ch].adpcm_history1_16;
|
||||||
vgmstream->loop_ch[ch].adpcm_history2_16 = vgmstream->ch[ch].adpcm_history2_16;
|
vgmstream->loop_ch[ch].adpcm_history2_16 = vgmstream->ch[ch].adpcm_history2_16;
|
||||||
vgmstream->loop_ch[ch].adpcm_history1_32 = vgmstream->ch[ch].adpcm_history1_32;
|
vgmstream->loop_ch[ch].adpcm_history1_32 = vgmstream->ch[ch].adpcm_history1_32;
|
||||||
@ -1633,12 +1632,13 @@ int decode_do_loop(VGMSTREAM* vgmstream) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//TODO: improve
|
//TODO: improve
|
||||||
/* loop codecs that need special handling, usually:
|
/* codecs with codec_data that decode_seek need special handling, usually:
|
||||||
* - on hit_loop, current offset is copied to loop_ch[].offset
|
* - during decode, codec uses vgmstream->ch[].offset to handle current offset
|
||||||
* - some codecs will overwrite loop_ch[].offset with a custom value
|
* - on hit_loop, current offset is auto-copied to vgmstream->loop_ch[].offset
|
||||||
* - loop_ch[] is copied to ch[] (with custom value)
|
* - decode_seek codecs may overwrite vgmstream->loop_ch[].offset with a custom value (such as start_offset)
|
||||||
* - then codec will use ch[]'s offset
|
* - vgmstream->loop_ch[] is copied below to vgmstream->ch[] (with the newly assigned custom value)
|
||||||
* regular codecs may use copied loop_ch[] offset without issue */
|
* - then codec will use vgmstream->ch[].offset during decode
|
||||||
|
* regular codecs will use copied vgmstream->loop_ch[].offset without issue */
|
||||||
decode_seek(vgmstream);
|
decode_seek(vgmstream);
|
||||||
|
|
||||||
/* restore! */
|
/* restore! */
|
||||||
@ -1649,7 +1649,7 @@ int decode_do_loop(VGMSTREAM* vgmstream) {
|
|||||||
vgmstream->current_block_samples = vgmstream->loop_block_samples;
|
vgmstream->current_block_samples = vgmstream->loop_block_samples;
|
||||||
vgmstream->current_block_offset = vgmstream->loop_block_offset;
|
vgmstream->current_block_offset = vgmstream->loop_block_offset;
|
||||||
vgmstream->next_block_offset = vgmstream->loop_next_block_offset;
|
vgmstream->next_block_offset = vgmstream->loop_next_block_offset;
|
||||||
//vgmstream->pstate = vgmstream->lstate; /* play state is applied over loops */
|
vgmstream->full_block_size = vgmstream->loop_full_block_size;
|
||||||
|
|
||||||
/* loop layouts (after restore, in case layout needs state manipulations) */
|
/* loop layouts (after restore, in case layout needs state manipulations) */
|
||||||
switch(vgmstream->layout_type) {
|
switch(vgmstream->layout_type) {
|
||||||
@ -1663,24 +1663,30 @@ int decode_do_loop(VGMSTREAM* vgmstream) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return 1; /* looped */
|
/* play state is applied over loops and stream decoding, so it's not restored on loops */
|
||||||
|
//vgmstream->pstate = vgmstream->lstate;
|
||||||
|
|
||||||
|
return true; /* has looped */
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
/* is this the loop start? save if we haven't saved yet (right when first loop starts) */
|
/* is this the loop start? save if we haven't saved yet (right when first loop starts) */
|
||||||
if (!vgmstream->hit_loop && vgmstream->current_sample == vgmstream->loop_start_sample) {
|
if (!vgmstream->hit_loop && vgmstream->current_sample == vgmstream->loop_start_sample) {
|
||||||
/* save! */
|
/* save! */
|
||||||
memcpy(vgmstream->loop_ch, vgmstream->ch, sizeof(VGMSTREAMCHANNEL)*vgmstream->channels);
|
memcpy(vgmstream->loop_ch, vgmstream->ch, sizeof(VGMSTREAMCHANNEL) * vgmstream->channels);
|
||||||
vgmstream->loop_current_sample = vgmstream->current_sample;
|
vgmstream->loop_current_sample = vgmstream->current_sample;
|
||||||
vgmstream->loop_samples_into_block = vgmstream->samples_into_block;
|
vgmstream->loop_samples_into_block = vgmstream->samples_into_block;
|
||||||
vgmstream->loop_block_size = vgmstream->current_block_size;
|
vgmstream->loop_block_size = vgmstream->current_block_size;
|
||||||
vgmstream->loop_block_samples = vgmstream->current_block_samples;
|
vgmstream->loop_block_samples = vgmstream->current_block_samples;
|
||||||
vgmstream->loop_block_offset = vgmstream->current_block_offset;
|
vgmstream->loop_block_offset = vgmstream->current_block_offset;
|
||||||
vgmstream->loop_next_block_offset = vgmstream->next_block_offset;
|
vgmstream->loop_next_block_offset = vgmstream->next_block_offset;
|
||||||
//vgmstream->lstate = vgmstream->pstate; /* play state is applied over loops */
|
vgmstream->loop_full_block_size = vgmstream->full_block_size;
|
||||||
|
|
||||||
|
/* play state is applied over loops and stream decoding, so it's not saved on loops */
|
||||||
|
//vgmstream->lstate = vgmstream->pstate;
|
||||||
|
|
||||||
vgmstream->hit_loop = true; /* info that loop is now ready to use */
|
vgmstream->hit_loop = true; /* info that loop is now ready to use */
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0; /* not looped */
|
return false; /* has not looped */
|
||||||
}
|
}
|
||||||
|
@ -11,8 +11,8 @@ void decode_reset(VGMSTREAM* vgmstream);
|
|||||||
* buffer already, and we have samples_to_do consecutive samples ahead of us. */
|
* buffer already, and we have samples_to_do consecutive samples ahead of us. */
|
||||||
void decode_vgmstream(VGMSTREAM* vgmstream, int samples_written, int samples_to_do, sample_t* buffer);
|
void decode_vgmstream(VGMSTREAM* vgmstream, int samples_written, int samples_to_do, sample_t* buffer);
|
||||||
|
|
||||||
/* Detect loop start and save values, or detect loop end and restore (loop back). Returns 1 if loop was done. */
|
/* Detect loop start and save values, or detect loop end and restore (loop back). Returns true if loop was done. */
|
||||||
int decode_do_loop(VGMSTREAM* vgmstream);
|
bool decode_do_loop(VGMSTREAM* vgmstream);
|
||||||
|
|
||||||
/* Calculate number of consecutive samples to do (taking into account stopping for loop start and end) */
|
/* Calculate number of consecutive samples to do (taking into account stopping for loop start and end) */
|
||||||
int decode_get_samples_to_do(int samples_this_block, int samples_per_frame, VGMSTREAM* vgmstream);
|
int decode_get_samples_to_do(int samples_this_block, int samples_per_frame, VGMSTREAM* vgmstream);
|
||||||
|
@ -6,6 +6,8 @@
|
|||||||
#include "../util/channel_mappings.h"
|
#include "../util/channel_mappings.h"
|
||||||
#include "../util/sf_utils.h"
|
#include "../util/sf_utils.h"
|
||||||
|
|
||||||
|
#define TEMPSIZE (256+32)
|
||||||
|
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
/* TEXT */
|
/* TEXT */
|
||||||
/*******************************************************************************/
|
/*******************************************************************************/
|
||||||
@ -21,7 +23,6 @@ static void describe_get_time(int32_t samples, int sample_rate, double* p_time_m
|
|||||||
/* Write a description of the stream into array pointed by desc, which must be length bytes long.
|
/* Write a description of the stream into array pointed by desc, which must be length bytes long.
|
||||||
* Will always be null-terminated if length > 0 */
|
* Will always be null-terminated if length > 0 */
|
||||||
void describe_vgmstream(VGMSTREAM* vgmstream, char* desc, int length) {
|
void describe_vgmstream(VGMSTREAM* vgmstream, char* desc, int length) {
|
||||||
#define TEMPSIZE (256+32)
|
|
||||||
char temp[TEMPSIZE];
|
char temp[TEMPSIZE];
|
||||||
double time_mm, time_ss;
|
double time_mm, time_ss;
|
||||||
|
|
||||||
|
@ -13,50 +13,50 @@ static void copy_time(bool* dst_flag, int32_t* dst_time, double* dst_time_s, boo
|
|||||||
*dst_time_s = *src_time_s;
|
*dst_time_s = *src_time_s;
|
||||||
}
|
}
|
||||||
|
|
||||||
//todo reuse in txtp?
|
// config that has been set internally via TXTP
|
||||||
static void load_default_config(play_config_t* def, play_config_t* tcfg) {
|
static void load_default_config(play_config_t* def, play_config_t* tcfg) {
|
||||||
|
|
||||||
/* loop limit: txtp #L > txtp #l > player #L > player #l */
|
/* loop limit: txtp #L > txtp #l > player #L > player #l */
|
||||||
if (tcfg->play_forever) {
|
if (tcfg->play_forever) {
|
||||||
def->play_forever = 1;
|
def->play_forever = true;
|
||||||
def->ignore_loop = 0;
|
def->ignore_loop = false;
|
||||||
}
|
}
|
||||||
if (tcfg->loop_count_set) {
|
if (tcfg->loop_count_set) {
|
||||||
def->loop_count = tcfg->loop_count;
|
def->loop_count = tcfg->loop_count;
|
||||||
def->loop_count_set = 1;
|
def->loop_count_set = true;
|
||||||
def->ignore_loop = 0;
|
def->ignore_loop = false;
|
||||||
if (!tcfg->play_forever)
|
if (!tcfg->play_forever)
|
||||||
def->play_forever = 0;
|
def->play_forever = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* fade priority: #F > #f, #d */
|
/* fade priority: #F > #f, #d */
|
||||||
if (tcfg->ignore_fade) {
|
if (tcfg->ignore_fade) {
|
||||||
def->ignore_fade = 1;
|
def->ignore_fade = true;
|
||||||
}
|
}
|
||||||
if (tcfg->fade_delay_set) {
|
if (tcfg->fade_delay_set) {
|
||||||
def->fade_delay = tcfg->fade_delay;
|
def->fade_delay = tcfg->fade_delay;
|
||||||
def->fade_delay_set = 1;
|
def->fade_delay_set = true;
|
||||||
}
|
}
|
||||||
if (tcfg->fade_time_set) {
|
if (tcfg->fade_time_set) {
|
||||||
def->fade_time = tcfg->fade_time;
|
def->fade_time = tcfg->fade_time;
|
||||||
def->fade_time_set = 1;
|
def->fade_time_set = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* loop priority: #i > #e > #E (respect player's ignore too) */
|
/* loop priority: #i > #e > #E (respect player's ignore too) */
|
||||||
if (tcfg->really_force_loop) {
|
if (tcfg->really_force_loop) {
|
||||||
//def->ignore_loop = 0;
|
//def->ignore_loop = false;
|
||||||
def->force_loop = 0;
|
def->force_loop = false;
|
||||||
def->really_force_loop = 1;
|
def->really_force_loop = true;
|
||||||
}
|
}
|
||||||
if (tcfg->force_loop) {
|
if (tcfg->force_loop) {
|
||||||
//def->ignore_loop = 0;
|
//def->ignore_loop = false;
|
||||||
def->force_loop = 1;
|
def->force_loop = true;
|
||||||
def->really_force_loop = 0;
|
def->really_force_loop = false;
|
||||||
}
|
}
|
||||||
if (tcfg->ignore_loop) {
|
if (tcfg->ignore_loop) {
|
||||||
def->ignore_loop = 1;
|
def->ignore_loop = true;
|
||||||
def->force_loop = 0;
|
def->force_loop = false;
|
||||||
def->really_force_loop = 0;
|
def->really_force_loop = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
copy_time(&def->pad_begin_set, &def->pad_begin, &def->pad_begin_s, &tcfg->pad_begin_set, &tcfg->pad_begin, &tcfg->pad_begin_s);
|
copy_time(&def->pad_begin_set, &def->pad_begin, &def->pad_begin_s, &tcfg->pad_begin_set, &tcfg->pad_begin, &tcfg->pad_begin_s);
|
||||||
@ -69,7 +69,8 @@ static void load_default_config(play_config_t* def, play_config_t* tcfg) {
|
|||||||
def->is_txtp = tcfg->is_txtp;
|
def->is_txtp = tcfg->is_txtp;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void load_player_config(play_config_t* def, vgmstream_cfg_t* vcfg) {
|
/* config that has been set externally by plugins */
|
||||||
|
static void load_external_config(play_config_t* def, vgmstream_cfg_t* vcfg) {
|
||||||
def->play_forever = vcfg->play_forever;
|
def->play_forever = vcfg->play_forever;
|
||||||
def->ignore_loop = vcfg->ignore_loop;
|
def->ignore_loop = vcfg->ignore_loop;
|
||||||
def->force_loop = vcfg->force_loop;
|
def->force_loop = vcfg->force_loop;
|
||||||
@ -77,31 +78,32 @@ static void load_player_config(play_config_t* def, vgmstream_cfg_t* vcfg) {
|
|||||||
def->ignore_fade = vcfg->ignore_fade;
|
def->ignore_fade = vcfg->ignore_fade;
|
||||||
|
|
||||||
def->loop_count = vcfg->loop_count;
|
def->loop_count = vcfg->loop_count;
|
||||||
def->loop_count_set = 1;
|
def->loop_count_set = true;
|
||||||
def->fade_delay = vcfg->fade_delay;
|
def->fade_delay = vcfg->fade_delay;
|
||||||
def->fade_delay_set = 1;
|
def->fade_delay_set = true;
|
||||||
def->fade_time = vcfg->fade_time;
|
def->fade_time = vcfg->fade_time;
|
||||||
def->fade_time_set = 1;
|
def->fade_time_set = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* apply play config to vgmstream */
|
||||||
void vgmstream_apply_config(VGMSTREAM* vgmstream, vgmstream_cfg_t* vcfg) {
|
void vgmstream_apply_config(VGMSTREAM* vgmstream, vgmstream_cfg_t* vcfg) {
|
||||||
play_config_t defs = {0};
|
play_config_t defs = {0};
|
||||||
play_config_t* def = &defs; /* for convenience... */
|
play_config_t* def = &defs; /* for convenience... */
|
||||||
play_config_t* tcfg = &vgmstream->config;
|
play_config_t* tcfg = &vgmstream->config;
|
||||||
|
|
||||||
|
|
||||||
load_player_config(def, vcfg);
|
load_external_config(def, vcfg);
|
||||||
def->config_set = 1;
|
def->config_set = true;
|
||||||
|
|
||||||
if (!vcfg->disable_config_override)
|
if (!vcfg->disable_config_override)
|
||||||
load_default_config(def, tcfg);
|
load_default_config(def, tcfg);
|
||||||
|
|
||||||
if (!vcfg->allow_play_forever)
|
if (!vcfg->allow_play_forever)
|
||||||
def->play_forever = 0;
|
def->play_forever = false;
|
||||||
|
|
||||||
/* copy final config back */
|
/* copy final config back */
|
||||||
*tcfg = *def;
|
*tcfg = *def;
|
||||||
|
|
||||||
vgmstream->config_enabled = def->config_set;
|
vgmstream->config_enabled = def->config_set;
|
||||||
setup_state_vgmstream(vgmstream);
|
setup_vgmstream_play_state(vgmstream);
|
||||||
}
|
}
|
185
src/base/play_state.c
Normal file
185
src/base/play_state.c
Normal file
@ -0,0 +1,185 @@
|
|||||||
|
#include "../vgmstream.h"
|
||||||
|
//#include "../layout/layout.h"
|
||||||
|
//#include "render.h"
|
||||||
|
//#include "decode.h"
|
||||||
|
//#include "mixing.h"
|
||||||
|
//#include "plugins.h"
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
int vgmstream_get_play_forever(VGMSTREAM* vgmstream) {
|
||||||
|
return vgmstream->config.play_forever;
|
||||||
|
}
|
||||||
|
|
||||||
|
void vgmstream_set_play_forever(VGMSTREAM* vgmstream, int enabled) {
|
||||||
|
/* sometimes we need to enable/disable right before playback
|
||||||
|
* (play config is left untouched, should mix ok as this flag is only used during
|
||||||
|
* render, while config is always prepared as if play forever wasn't enabled) */
|
||||||
|
vgmstream->config.play_forever = enabled;
|
||||||
|
setup_vgmstream(vgmstream); /* update config */
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t vgmstream_get_samples(VGMSTREAM* vgmstream) {
|
||||||
|
if (!vgmstream->config_enabled || !vgmstream->config.config_set)
|
||||||
|
return vgmstream->num_samples;
|
||||||
|
return vgmstream->pstate.play_duration;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calculate samples based on player's config */
|
||||||
|
int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double fadedelayseconds, VGMSTREAM* vgmstream) {
|
||||||
|
if (vgmstream->loop_flag) {
|
||||||
|
if (vgmstream->loop_target == (int)looptimes) { /* set externally, as this function is info-only */
|
||||||
|
/* Continue playing the file normally after looping, instead of fading.
|
||||||
|
* Most files cut abruply after the loop, but some do have proper endings.
|
||||||
|
* With looptimes = 1 this option should give the same output vs loop disabled */
|
||||||
|
int loop_count = (int)looptimes; /* no half loops allowed */
|
||||||
|
return vgmstream->loop_start_sample
|
||||||
|
+ (vgmstream->loop_end_sample - vgmstream->loop_start_sample) * loop_count
|
||||||
|
+ (vgmstream->num_samples - vgmstream->loop_end_sample);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return vgmstream->loop_start_sample
|
||||||
|
+ (vgmstream->loop_end_sample - vgmstream->loop_start_sample) * looptimes
|
||||||
|
+ (fadedelayseconds + fadeseconds) * vgmstream->sample_rate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return vgmstream->num_samples;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
|
/* apply config like forced loops */
|
||||||
|
static void setup_state_modifiers(VGMSTREAM* vgmstream) {
|
||||||
|
play_config_t* pc = &vgmstream->config;
|
||||||
|
|
||||||
|
/* apply final config */
|
||||||
|
if (pc->really_force_loop) {
|
||||||
|
vgmstream_force_loop(vgmstream, true, 0, vgmstream->num_samples);
|
||||||
|
}
|
||||||
|
if (pc->force_loop && !vgmstream->loop_flag) {
|
||||||
|
vgmstream_force_loop(vgmstream, true, 0, vgmstream->num_samples);
|
||||||
|
}
|
||||||
|
if (pc->ignore_loop) {
|
||||||
|
vgmstream_force_loop(vgmstream, false, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!vgmstream->loop_flag) {
|
||||||
|
pc->play_forever = false;
|
||||||
|
}
|
||||||
|
if (pc->play_forever) {
|
||||||
|
pc->ignore_fade = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* loop N times, but also play stream end instead of fading out */
|
||||||
|
if (pc->ignore_fade) {
|
||||||
|
vgmstream_set_loop_target(vgmstream, (int)pc->loop_count);
|
||||||
|
pc->fade_time = 0;
|
||||||
|
pc->fade_delay = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* apply config like trims */
|
||||||
|
static void setup_state_processing(VGMSTREAM* vgmstream) {
|
||||||
|
play_state_t* ps = &vgmstream->pstate;
|
||||||
|
play_config_t* pc = &vgmstream->config;
|
||||||
|
double sample_rate = vgmstream->sample_rate;
|
||||||
|
|
||||||
|
/* time to samples */
|
||||||
|
if (pc->pad_begin_s)
|
||||||
|
pc->pad_begin = pc->pad_begin_s * sample_rate;
|
||||||
|
if (pc->pad_end_s)
|
||||||
|
pc->pad_end = pc->pad_end_s * sample_rate;
|
||||||
|
if (pc->trim_begin_s)
|
||||||
|
pc->trim_begin = pc->trim_begin_s * sample_rate;
|
||||||
|
if (pc->trim_end_s)
|
||||||
|
pc->trim_end = pc->trim_end_s * sample_rate;
|
||||||
|
if (pc->body_time_s)
|
||||||
|
pc->body_time = pc->body_time_s * sample_rate;
|
||||||
|
//todo fade time also set to samples
|
||||||
|
|
||||||
|
/* samples before all decode */
|
||||||
|
ps->pad_begin_duration = pc->pad_begin;
|
||||||
|
|
||||||
|
/* removed samples from first decode */
|
||||||
|
ps->trim_begin_duration = pc->trim_begin;
|
||||||
|
|
||||||
|
/* main samples part */
|
||||||
|
ps->body_duration = 0;
|
||||||
|
if (pc->body_time) {
|
||||||
|
ps->body_duration += pc->body_time; /* whether it loops or not */
|
||||||
|
}
|
||||||
|
else if (vgmstream->loop_flag) {
|
||||||
|
double loop_count = 1.0;
|
||||||
|
if (pc->loop_count_set) /* may set 0.0 on purpose I guess */
|
||||||
|
loop_count = pc->loop_count;
|
||||||
|
|
||||||
|
ps->body_duration += vgmstream->loop_start_sample;
|
||||||
|
if (pc->ignore_fade) {
|
||||||
|
ps->body_duration += (vgmstream->loop_end_sample - vgmstream->loop_start_sample) * (int)loop_count;
|
||||||
|
ps->body_duration += (vgmstream->num_samples - vgmstream->loop_end_sample);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ps->body_duration += (vgmstream->loop_end_sample - vgmstream->loop_start_sample) * loop_count;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
ps->body_duration += vgmstream->num_samples;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* samples from some modify body */
|
||||||
|
if (pc->trim_begin)
|
||||||
|
ps->body_duration -= pc->trim_begin;
|
||||||
|
if (pc->trim_end)
|
||||||
|
ps->body_duration -= pc->trim_end;
|
||||||
|
if (pc->fade_delay && vgmstream->loop_flag)
|
||||||
|
ps->body_duration += pc->fade_delay * vgmstream->sample_rate;
|
||||||
|
|
||||||
|
/* samples from fade part */
|
||||||
|
if (pc->fade_time && vgmstream->loop_flag)
|
||||||
|
ps->fade_duration = pc->fade_time * vgmstream->sample_rate;
|
||||||
|
|
||||||
|
/* samples from last part (anything beyond this is empty, unless play forever is set) */
|
||||||
|
ps->pad_end_duration = pc->pad_end;
|
||||||
|
|
||||||
|
/* final count */
|
||||||
|
ps->play_duration = ps->pad_begin_duration + ps->body_duration + ps->fade_duration + ps->pad_end_duration;
|
||||||
|
ps->play_position = 0;
|
||||||
|
|
||||||
|
/* values too big can overflow, just ignore */
|
||||||
|
if (ps->pad_begin_duration < 0)
|
||||||
|
ps->pad_begin_duration = 0;
|
||||||
|
if (ps->body_duration < 0)
|
||||||
|
ps->body_duration = 0;
|
||||||
|
if (ps->fade_duration < 0)
|
||||||
|
ps->fade_duration = 0;
|
||||||
|
if (ps->pad_end_duration < 0)
|
||||||
|
ps->pad_end_duration = 0;
|
||||||
|
if (ps->play_duration < 0)
|
||||||
|
ps->play_duration = 0;
|
||||||
|
|
||||||
|
ps->pad_begin_left = ps->pad_begin_duration;
|
||||||
|
ps->trim_begin_left = ps->trim_begin_duration;
|
||||||
|
ps->fade_left = ps->fade_duration;
|
||||||
|
ps->fade_start = ps->pad_begin_duration + ps->body_duration;
|
||||||
|
//ps->pad_end_left = ps->pad_end_duration;
|
||||||
|
ps->pad_end_start = ps->fade_start + ps->fade_duration;
|
||||||
|
|
||||||
|
/* other info (updated once mixing is enabled) */
|
||||||
|
ps->input_channels = vgmstream->channels;
|
||||||
|
ps->output_channels = vgmstream->channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* apply play config to internal state */
|
||||||
|
void setup_vgmstream_play_state(VGMSTREAM* vgmstream) {
|
||||||
|
if (!vgmstream->config.config_set)
|
||||||
|
return;
|
||||||
|
|
||||||
|
setup_state_modifiers(vgmstream);
|
||||||
|
setup_state_processing(vgmstream);
|
||||||
|
|
||||||
|
/* save new config for resets */
|
||||||
|
setup_vgmstream(vgmstream);
|
||||||
|
}
|
@ -47,179 +47,6 @@
|
|||||||
* This mainly applies to TXTP, segments/layers in metas usually don't need to trigger config mode.
|
* This mainly applies to TXTP, segments/layers in metas usually don't need to trigger config mode.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
|
||||||
int vgmstream_get_play_forever(VGMSTREAM* vgmstream) {
|
|
||||||
return vgmstream->config.play_forever;
|
|
||||||
}
|
|
||||||
|
|
||||||
void vgmstream_set_play_forever(VGMSTREAM* vgmstream, int enabled) {
|
|
||||||
/* sometimes we need to enable/disable right before playback
|
|
||||||
* (play config is left untouched, should mix ok as this flag is only used during
|
|
||||||
* render, while config is always prepared as if play forever wasn't enabled) */
|
|
||||||
vgmstream->config.play_forever = enabled;
|
|
||||||
setup_vgmstream(vgmstream); /* update config */
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t vgmstream_get_samples(VGMSTREAM* vgmstream) {
|
|
||||||
if (!vgmstream->config_enabled || !vgmstream->config.config_set)
|
|
||||||
return vgmstream->num_samples;
|
|
||||||
return vgmstream->pstate.play_duration;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* calculate samples based on player's config */
|
|
||||||
int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double fadedelayseconds, VGMSTREAM* vgmstream) {
|
|
||||||
if (vgmstream->loop_flag) {
|
|
||||||
if (vgmstream->loop_target == (int)looptimes) { /* set externally, as this function is info-only */
|
|
||||||
/* Continue playing the file normally after looping, instead of fading.
|
|
||||||
* Most files cut abruply after the loop, but some do have proper endings.
|
|
||||||
* With looptimes = 1 this option should give the same output vs loop disabled */
|
|
||||||
int loop_count = (int)looptimes; /* no half loops allowed */
|
|
||||||
return vgmstream->loop_start_sample
|
|
||||||
+ (vgmstream->loop_end_sample - vgmstream->loop_start_sample) * loop_count
|
|
||||||
+ (vgmstream->num_samples - vgmstream->loop_end_sample);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return vgmstream->loop_start_sample
|
|
||||||
+ (vgmstream->loop_end_sample - vgmstream->loop_start_sample) * looptimes
|
|
||||||
+ (fadedelayseconds + fadeseconds) * vgmstream->sample_rate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return vgmstream->num_samples;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
|
||||||
|
|
||||||
static void setup_state_modifiers(VGMSTREAM* vgmstream) {
|
|
||||||
play_config_t* pc = &vgmstream->config;
|
|
||||||
|
|
||||||
/* apply final config */
|
|
||||||
if (pc->really_force_loop) {
|
|
||||||
vgmstream_force_loop(vgmstream, 1, 0,vgmstream->num_samples);
|
|
||||||
}
|
|
||||||
if (pc->force_loop && !vgmstream->loop_flag) {
|
|
||||||
vgmstream_force_loop(vgmstream, 1, 0,vgmstream->num_samples);
|
|
||||||
}
|
|
||||||
if (pc->ignore_loop) {
|
|
||||||
vgmstream_force_loop(vgmstream, 0, 0,0);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!vgmstream->loop_flag) {
|
|
||||||
pc->play_forever = 0;
|
|
||||||
}
|
|
||||||
if (pc->play_forever) {
|
|
||||||
pc->ignore_fade = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* loop N times, but also play stream end instead of fading out */
|
|
||||||
if (pc->ignore_fade) {
|
|
||||||
vgmstream_set_loop_target(vgmstream, (int)pc->loop_count);
|
|
||||||
pc->fade_time = 0;
|
|
||||||
pc->fade_delay = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void setup_state_processing(VGMSTREAM* vgmstream) {
|
|
||||||
play_state_t* ps = &vgmstream->pstate;
|
|
||||||
play_config_t* pc = &vgmstream->config;
|
|
||||||
double sample_rate = vgmstream->sample_rate;
|
|
||||||
|
|
||||||
/* time to samples */
|
|
||||||
if (pc->pad_begin_s)
|
|
||||||
pc->pad_begin = pc->pad_begin_s * sample_rate;
|
|
||||||
if (pc->pad_end_s)
|
|
||||||
pc->pad_end = pc->pad_end_s * sample_rate;
|
|
||||||
if (pc->trim_begin_s)
|
|
||||||
pc->trim_begin = pc->trim_begin_s * sample_rate;
|
|
||||||
if (pc->trim_end_s)
|
|
||||||
pc->trim_end = pc->trim_end_s * sample_rate;
|
|
||||||
if (pc->body_time_s)
|
|
||||||
pc->body_time = pc->body_time_s * sample_rate;
|
|
||||||
//todo fade time also set to samples
|
|
||||||
|
|
||||||
/* samples before all decode */
|
|
||||||
ps->pad_begin_duration = pc->pad_begin;
|
|
||||||
|
|
||||||
/* removed samples from first decode */
|
|
||||||
ps->trim_begin_duration = pc->trim_begin;
|
|
||||||
|
|
||||||
/* main samples part */
|
|
||||||
ps->body_duration = 0;
|
|
||||||
if (pc->body_time) {
|
|
||||||
ps->body_duration += pc->body_time; /* whether it loops or not */
|
|
||||||
}
|
|
||||||
else if (vgmstream->loop_flag) {
|
|
||||||
double loop_count = 1.0;
|
|
||||||
if (pc->loop_count_set) /* may set 0.0 on purpose I guess */
|
|
||||||
loop_count = pc->loop_count;
|
|
||||||
|
|
||||||
ps->body_duration += vgmstream->loop_start_sample;
|
|
||||||
if (pc->ignore_fade) {
|
|
||||||
ps->body_duration += (vgmstream->loop_end_sample - vgmstream->loop_start_sample) * (int)loop_count;
|
|
||||||
ps->body_duration += (vgmstream->num_samples - vgmstream->loop_end_sample);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ps->body_duration += (vgmstream->loop_end_sample - vgmstream->loop_start_sample) * loop_count;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
ps->body_duration += vgmstream->num_samples;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* samples from some modify body */
|
|
||||||
if (pc->trim_begin)
|
|
||||||
ps->body_duration -= pc->trim_begin;
|
|
||||||
if (pc->trim_end)
|
|
||||||
ps->body_duration -= pc->trim_end;
|
|
||||||
if (pc->fade_delay && vgmstream->loop_flag)
|
|
||||||
ps->body_duration += pc->fade_delay * vgmstream->sample_rate;
|
|
||||||
|
|
||||||
/* samples from fade part */
|
|
||||||
if (pc->fade_time && vgmstream->loop_flag)
|
|
||||||
ps->fade_duration = pc->fade_time * vgmstream->sample_rate;
|
|
||||||
|
|
||||||
/* samples from last part (anything beyond this is empty, unless play forever is set) */
|
|
||||||
ps->pad_end_duration = pc->pad_end;
|
|
||||||
|
|
||||||
/* final count */
|
|
||||||
ps->play_duration = ps->pad_begin_duration + ps->body_duration + ps->fade_duration + ps->pad_end_duration;
|
|
||||||
ps->play_position = 0;
|
|
||||||
|
|
||||||
/* values too big can overflow, just ignore */
|
|
||||||
if (ps->pad_begin_duration < 0)
|
|
||||||
ps->pad_begin_duration = 0;
|
|
||||||
if (ps->body_duration < 0)
|
|
||||||
ps->body_duration = 0;
|
|
||||||
if (ps->fade_duration < 0)
|
|
||||||
ps->fade_duration = 0;
|
|
||||||
if (ps->pad_end_duration < 0)
|
|
||||||
ps->pad_end_duration = 0;
|
|
||||||
if (ps->play_duration < 0)
|
|
||||||
ps->play_duration = 0;
|
|
||||||
|
|
||||||
ps->pad_begin_left = ps->pad_begin_duration;
|
|
||||||
ps->trim_begin_left = ps->trim_begin_duration;
|
|
||||||
ps->fade_left = ps->fade_duration;
|
|
||||||
ps->fade_start = ps->pad_begin_duration + ps->body_duration;
|
|
||||||
//ps->pad_end_left = ps->pad_end_duration;
|
|
||||||
ps->pad_end_start = ps->fade_start + ps->fade_duration;
|
|
||||||
|
|
||||||
/* other info (updated once mixing is enabled) */
|
|
||||||
ps->input_channels = vgmstream->channels;
|
|
||||||
ps->output_channels = vgmstream->channels;
|
|
||||||
}
|
|
||||||
|
|
||||||
void setup_state_vgmstream(VGMSTREAM* vgmstream) {
|
|
||||||
if (!vgmstream->config.config_set)
|
|
||||||
return;
|
|
||||||
|
|
||||||
setup_state_modifiers(vgmstream);
|
|
||||||
setup_state_processing(vgmstream);
|
|
||||||
setup_vgmstream(vgmstream); /* save current config for reset */
|
|
||||||
}
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
|
|
||||||
void render_free(VGMSTREAM* vgmstream) {
|
void render_free(VGMSTREAM* vgmstream) {
|
||||||
@ -333,8 +160,9 @@ int render_layout(sample_t* buf, int32_t sample_count, VGMSTREAM* vgmstream) {
|
|||||||
return sample_count;
|
return sample_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
static void render_trim(VGMSTREAM* vgmstream) {
|
static void render_op_trim(VGMSTREAM* vgmstream) {
|
||||||
sample_t* tmpbuf = vgmstream->tmpbuf;
|
sample_t* tmpbuf = vgmstream->tmpbuf;
|
||||||
size_t tmpbuf_size = vgmstream->tmpbuf_size;
|
size_t tmpbuf_size = vgmstream->tmpbuf_size;
|
||||||
int32_t buf_samples = tmpbuf_size / vgmstream->channels; /* base channels, no need to apply mixing */
|
int32_t buf_samples = tmpbuf_size / vgmstream->channels; /* base channels, no need to apply mixing */
|
||||||
@ -350,7 +178,7 @@ static void render_trim(VGMSTREAM* vgmstream) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int render_pad_begin(VGMSTREAM* vgmstream, sample_t* buf, int samples_to_do) {
|
static int render_op_pad_begin(VGMSTREAM* vgmstream, sample_t* buf, int samples_to_do) {
|
||||||
int channels = vgmstream->pstate.output_channels;
|
int channels = vgmstream->pstate.output_channels;
|
||||||
int to_do = vgmstream->pstate.pad_begin_left;
|
int to_do = vgmstream->pstate.pad_begin_left;
|
||||||
if (to_do > samples_to_do)
|
if (to_do > samples_to_do)
|
||||||
@ -362,7 +190,7 @@ static int render_pad_begin(VGMSTREAM* vgmstream, sample_t* buf, int samples_to_
|
|||||||
return to_do;
|
return to_do;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int render_fade(VGMSTREAM* vgmstream, sample_t* buf, int samples_left) {
|
static int render_op_fade(VGMSTREAM* vgmstream, sample_t* buf, int samples_left) {
|
||||||
play_state_t* ps = &vgmstream->pstate;
|
play_state_t* ps = &vgmstream->pstate;
|
||||||
//play_config_t* pc = &vgmstream->config;
|
//play_config_t* pc = &vgmstream->config;
|
||||||
|
|
||||||
@ -404,7 +232,7 @@ static int render_fade(VGMSTREAM* vgmstream, sample_t* buf, int samples_left) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static int render_pad_end(VGMSTREAM* vgmstream, sample_t* buf, int samples_left) {
|
static int render_op_pad_end(VGMSTREAM* vgmstream, sample_t* buf, int samples_left) {
|
||||||
play_state_t* ps = &vgmstream->pstate;
|
play_state_t* ps = &vgmstream->pstate;
|
||||||
int channels = vgmstream->pstate.output_channels;
|
int channels = vgmstream->pstate.output_channels;
|
||||||
int skip = 0;
|
int skip = 0;
|
||||||
@ -428,6 +256,7 @@ static int render_pad_end(VGMSTREAM* vgmstream, sample_t* buf, int samples_left)
|
|||||||
return skip + to_do;
|
return skip + to_do;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*****************************************************************************/
|
||||||
|
|
||||||
/* Decode data into sample buffer. Controls the "external" part of the decoding,
|
/* Decode data into sample buffer. Controls the "external" part of the decoding,
|
||||||
* while layout/decode control the "internal" part. */
|
* while layout/decode control the "internal" part. */
|
||||||
@ -449,12 +278,12 @@ int render_vgmstream(sample_t* buf, int32_t sample_count, VGMSTREAM* vgmstream)
|
|||||||
|
|
||||||
/* trim may go first since it doesn't need output nor changes totals */
|
/* trim may go first since it doesn't need output nor changes totals */
|
||||||
if (ps->trim_begin_left) {
|
if (ps->trim_begin_left) {
|
||||||
render_trim(vgmstream);
|
render_op_trim(vgmstream);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* adds empty samples to buf */
|
/* adds empty samples to buf */
|
||||||
if (ps->pad_begin_left) {
|
if (ps->pad_begin_left) {
|
||||||
done = render_pad_begin(vgmstream, tmpbuf, samples_to_do);
|
done = render_op_pad_begin(vgmstream, tmpbuf, samples_to_do);
|
||||||
samples_done += done;
|
samples_done += done;
|
||||||
samples_to_do -= done;
|
samples_to_do -= done;
|
||||||
tmpbuf += done * vgmstream->pstate.output_channels; /* as if mixed */
|
tmpbuf += done * vgmstream->pstate.output_channels; /* as if mixed */
|
||||||
@ -464,7 +293,7 @@ int render_vgmstream(sample_t* buf, int32_t sample_count, VGMSTREAM* vgmstream)
|
|||||||
if (!vgmstream->config.play_forever
|
if (!vgmstream->config.play_forever
|
||||||
&& ps->play_position /*+ samples_to_do*/ >= ps->pad_end_start
|
&& ps->play_position /*+ samples_to_do*/ >= ps->pad_end_start
|
||||||
&& samples_to_do) {
|
&& samples_to_do) {
|
||||||
done = render_pad_end(vgmstream, tmpbuf, samples_to_do);
|
done = render_op_pad_end(vgmstream, tmpbuf, samples_to_do);
|
||||||
samples_done += done;
|
samples_done += done;
|
||||||
samples_to_do -= done;
|
samples_to_do -= done;
|
||||||
tmpbuf += done * vgmstream->pstate.output_channels; /* as if mixed */
|
tmpbuf += done * vgmstream->pstate.output_channels; /* as if mixed */
|
||||||
@ -481,12 +310,12 @@ int render_vgmstream(sample_t* buf, int32_t sample_count, VGMSTREAM* vgmstream)
|
|||||||
if (!vgmstream->config.play_forever) {
|
if (!vgmstream->config.play_forever) {
|
||||||
/* simple fadeout */
|
/* simple fadeout */
|
||||||
if (ps->fade_left && ps->play_position + done >= ps->fade_start) {
|
if (ps->fade_left && ps->play_position + done >= ps->fade_start) {
|
||||||
render_fade(vgmstream, tmpbuf, done);
|
render_op_fade(vgmstream, tmpbuf, done);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* silence leftover buf samples (rarely used when no fade is set) */
|
/* silence leftover buf samples (rarely used when no fade is set) */
|
||||||
if (ps->play_position + done >= ps->pad_end_start) {
|
if (ps->play_position + done >= ps->pad_end_start) {
|
||||||
render_pad_end(vgmstream, tmpbuf, done);
|
render_op_pad_end(vgmstream, tmpbuf, done);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -219,7 +219,6 @@
|
|||||||
<ClCompile Include="base\api_helpers.c" />
|
<ClCompile Include="base\api_helpers.c" />
|
||||||
<ClCompile Include="base\api_libsf.c" />
|
<ClCompile Include="base\api_libsf.c" />
|
||||||
<ClCompile Include="base\api_tags.c" />
|
<ClCompile Include="base\api_tags.c" />
|
||||||
<ClCompile Include="base\config.c" />
|
|
||||||
<ClCompile Include="base\decode.c" />
|
<ClCompile Include="base\decode.c" />
|
||||||
<ClCompile Include="base\info.c" />
|
<ClCompile Include="base\info.c" />
|
||||||
<ClCompile Include="base\mixer.c" />
|
<ClCompile Include="base\mixer.c" />
|
||||||
@ -228,6 +227,8 @@
|
|||||||
<ClCompile Include="base\mixing.c" />
|
<ClCompile Include="base\mixing.c" />
|
||||||
<ClCompile Include="base\mixing_commands.c" />
|
<ClCompile Include="base\mixing_commands.c" />
|
||||||
<ClCompile Include="base\mixing_macros.c" />
|
<ClCompile Include="base\mixing_macros.c" />
|
||||||
|
<ClCompile Include="base\play_config.c" />
|
||||||
|
<ClCompile Include="base\play_state.c" />
|
||||||
<ClCompile Include="base\plugins.c" />
|
<ClCompile Include="base\plugins.c" />
|
||||||
<ClCompile Include="base\render.c" />
|
<ClCompile Include="base\render.c" />
|
||||||
<ClCompile Include="base\seek.c" />
|
<ClCompile Include="base\seek.c" />
|
||||||
@ -630,7 +631,6 @@
|
|||||||
<ClCompile Include="meta\ps2_vgv.c" />
|
<ClCompile Include="meta\ps2_vgv.c" />
|
||||||
<ClCompile Include="meta\ps2_vms.c" />
|
<ClCompile Include="meta\ps2_vms.c" />
|
||||||
<ClCompile Include="meta\ps2_wmus.c" />
|
<ClCompile Include="meta\ps2_wmus.c" />
|
||||||
<ClCompile Include="meta\ps2_xa30.c" />
|
|
||||||
<ClCompile Include="meta\psb.c" />
|
<ClCompile Include="meta\psb.c" />
|
||||||
<ClCompile Include="meta\psf.c" />
|
<ClCompile Include="meta\psf.c" />
|
||||||
<ClCompile Include="meta\psnd.c" />
|
<ClCompile Include="meta\psnd.c" />
|
||||||
|
@ -487,9 +487,6 @@
|
|||||||
<ClCompile Include="base\api_tags.c">
|
<ClCompile Include="base\api_tags.c">
|
||||||
<Filter>base\Source Files</Filter>
|
<Filter>base\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="base\config.c">
|
|
||||||
<Filter>base\Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="base\decode.c">
|
<ClCompile Include="base\decode.c">
|
||||||
<Filter>base\Source Files</Filter>
|
<Filter>base\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -514,6 +511,12 @@
|
|||||||
<ClCompile Include="base\mixing_macros.c">
|
<ClCompile Include="base\mixing_macros.c">
|
||||||
<Filter>base\Source Files</Filter>
|
<Filter>base\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
<ClCompile Include="base\play_config.c">
|
||||||
|
<Filter>base\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
|
<ClCompile Include="base\play_state.c">
|
||||||
|
<Filter>base\Source Files</Filter>
|
||||||
|
</ClCompile>
|
||||||
<ClCompile Include="base\plugins.c">
|
<ClCompile Include="base\plugins.c">
|
||||||
<Filter>base\Source Files</Filter>
|
<Filter>base\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
@ -1720,9 +1723,6 @@
|
|||||||
<ClCompile Include="meta\ps2_wmus.c">
|
<ClCompile Include="meta\ps2_wmus.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
<ClCompile Include="meta\ps2_xa30.c">
|
|
||||||
<Filter>meta\Source Files</Filter>
|
|
||||||
</ClCompile>
|
|
||||||
<ClCompile Include="meta\psb.c">
|
<ClCompile Include="meta\psb.c">
|
||||||
<Filter>meta\Source Files</Filter>
|
<Filter>meta\Source Files</Filter>
|
||||||
</ClCompile>
|
</ClCompile>
|
||||||
|
@ -131,7 +131,7 @@ static void apply_settings(VGMSTREAM* vgmstream, txtp_entry_t* current) {
|
|||||||
|
|
||||||
/* default play config (last after sample rate mods/mixing/etc) */
|
/* default play config (last after sample rate mods/mixing/etc) */
|
||||||
txtp_copy_config(&vgmstream->config, ¤t->config);
|
txtp_copy_config(&vgmstream->config, ¤t->config);
|
||||||
setup_state_vgmstream(vgmstream);
|
setup_vgmstream_play_state(vgmstream);
|
||||||
/* config is enabled in layouts or externally (for compatibility, since we don't know yet if this
|
/* config is enabled in layouts or externally (for compatibility, since we don't know yet if this
|
||||||
* VGMSTREAM will part of a layout, or is enabled externally to not mess up plugins's calcs) */
|
* VGMSTREAM will part of a layout, or is enabled externally to not mess up plugins's calcs) */
|
||||||
}
|
}
|
||||||
|
@ -186,8 +186,15 @@ typedef struct {
|
|||||||
bool allow_dual_stereo; /* search for dual stereo (file_L.ext + file_R.ext = single stereo file) */
|
bool allow_dual_stereo; /* search for dual stereo (file_L.ext + file_R.ext = single stereo file) */
|
||||||
int format_id; /* internal format ID */
|
int format_id; /* internal format ID */
|
||||||
|
|
||||||
|
|
||||||
|
/* decoder config/state */
|
||||||
|
int codec_endian; /* little/big endian marker; name is left vague but usually means big endian */
|
||||||
|
int codec_config; /* flags for codecs or layouts with minor variations; meaning is up to them (may change during decode) */
|
||||||
|
bool codec_internal_updates; /* temp(?) kludge (see vgmstream_open_stream/decode) */
|
||||||
|
int32_t ws_output_size; /* WS ADPCM: output bytes for this block */
|
||||||
|
|
||||||
/* layout/block state */
|
/* layout/block state */
|
||||||
int32_t current_sample; /* sample point within the file (for loop detection) */
|
int32_t current_sample; /* sample point within the stream (for loop detection) */
|
||||||
int32_t samples_into_block; /* number of samples into the current block/interleave/segment/etc */
|
int32_t samples_into_block; /* number of samples into the current block/interleave/segment/etc */
|
||||||
off_t current_block_offset; /* start of this block (offset of block header) */
|
off_t current_block_offset; /* start of this block (offset of block header) */
|
||||||
size_t current_block_size; /* size in usable bytes of the block we're in now (used to calculate num_samples per block) */
|
size_t current_block_size; /* size in usable bytes of the block we're in now (used to calculate num_samples per block) */
|
||||||
@ -195,28 +202,24 @@ typedef struct {
|
|||||||
off_t next_block_offset; /* offset of header of the next block */
|
off_t next_block_offset; /* offset of header of the next block */
|
||||||
size_t full_block_size; /* actual data size of an entire block (ie. may be fixed, include padding/headers, etc) */
|
size_t full_block_size; /* actual data size of an entire block (ie. may be fixed, include padding/headers, etc) */
|
||||||
|
|
||||||
/* loop state (saved when loop is hit to restore later) */
|
/* layout/block state copy for loops (saved on loop_start and restored later on loop_end) */
|
||||||
int32_t loop_current_sample; /* saved from current_sample (same as loop_start_sample, but more state-like) */
|
int32_t loop_current_sample; /* saved from current_sample (same as loop_start_sample, but more state-like) */
|
||||||
int32_t loop_samples_into_block;/* saved from samples_into_block */
|
int32_t loop_samples_into_block;/* saved from samples_into_block */
|
||||||
off_t loop_block_offset; /* saved from current_block_offset */
|
off_t loop_block_offset; /* saved from current_block_offset */
|
||||||
size_t loop_block_size; /* saved from current_block_size */
|
size_t loop_block_size; /* saved from current_block_size */
|
||||||
int32_t loop_block_samples; /* saved from current_block_samples */
|
int32_t loop_block_samples; /* saved from current_block_samples */
|
||||||
off_t loop_next_block_offset; /* saved from next_block_offset */
|
off_t loop_next_block_offset; /* saved from next_block_offset */
|
||||||
|
size_t loop_full_block_size; /* saved from full_block_size (probably unnecessary) */
|
||||||
|
|
||||||
bool hit_loop; /* save config when loop is hit, but first time only */
|
bool hit_loop; /* save config when loop is hit, but first time only */
|
||||||
|
|
||||||
|
|
||||||
/* decoder config/state */
|
|
||||||
int codec_endian; /* little/big endian marker; name is left vague but usually means big endian */
|
|
||||||
int codec_config; /* flags for codecs or layouts with minor variations; meaning is up to them */
|
|
||||||
bool codec_internal_updates; /* temp(?) kludge (see vgmstream_open_stream/decode) */
|
|
||||||
int32_t ws_output_size; /* WS ADPCM: output bytes for this block */
|
|
||||||
|
|
||||||
|
|
||||||
/* main state */
|
/* main state */
|
||||||
VGMSTREAMCHANNEL* ch; /* array of channels */
|
VGMSTREAMCHANNEL* ch; /* array of channels with current offset + per-channel codec config */
|
||||||
VGMSTREAMCHANNEL* start_ch; /* shallow copy of channels as they were at the beginning of the stream (for resets) */
|
|
||||||
VGMSTREAMCHANNEL* loop_ch; /* shallow copy of channels as they were at the loop point (for loops) */
|
VGMSTREAMCHANNEL* loop_ch; /* shallow copy of channels as they were at the loop point (for loops) */
|
||||||
|
|
||||||
void* start_vgmstream; /* shallow copy of the VGMSTREAM as it was at the beginning of the stream (for resets) */
|
void* start_vgmstream; /* shallow copy of the VGMSTREAM as it was at the beginning of the stream (for resets) */
|
||||||
|
VGMSTREAMCHANNEL* start_ch; /* shallow copy of channels as they were at the beginning of the stream (for resets) */
|
||||||
|
|
||||||
void* mixer; /* state for mixing effects */
|
void* mixer; /* state for mixing effects */
|
||||||
|
|
||||||
@ -242,7 +245,6 @@ typedef struct {
|
|||||||
} VGMSTREAM;
|
} VGMSTREAM;
|
||||||
|
|
||||||
|
|
||||||
// VGMStream description in structure format
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int sample_rate;
|
int sample_rate;
|
||||||
int channels;
|
int channels;
|
||||||
@ -326,11 +328,10 @@ void get_vgmstream_coding_description(VGMSTREAM* vgmstream, char* out, size_t ou
|
|||||||
void get_vgmstream_layout_description(VGMSTREAM* vgmstream, char* out, size_t out_size);
|
void get_vgmstream_layout_description(VGMSTREAM* vgmstream, char* out, size_t out_size);
|
||||||
void get_vgmstream_meta_description(VGMSTREAM* vgmstream, char* out, size_t out_size);
|
void get_vgmstream_meta_description(VGMSTREAM* vgmstream, char* out, size_t out_size);
|
||||||
|
|
||||||
|
//TODO: remove, unused internally
|
||||||
/* calculate the number of samples to be played based on looping parameters */
|
/* calculate the number of samples to be played based on looping parameters */
|
||||||
int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double fadedelayseconds, VGMSTREAM* vgmstream);
|
int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double fadedelayseconds, VGMSTREAM* vgmstream);
|
||||||
|
|
||||||
void setup_state_vgmstream(VGMSTREAM* vgmstream);
|
|
||||||
|
|
||||||
/* Force enable/disable internal looping. Should be done before playing anything (or after reset),
|
/* Force enable/disable internal looping. Should be done before playing anything (or after reset),
|
||||||
* and not all codecs support arbitrary loop values ATM. */
|
* and not all codecs support arbitrary loop values ATM. */
|
||||||
void vgmstream_force_loop(VGMSTREAM* vgmstream, int loop_flag, int loop_start_sample, int loop_end_sample);
|
void vgmstream_force_loop(VGMSTREAM* vgmstream, int loop_flag, int loop_start_sample, int loop_end_sample);
|
||||||
@ -338,4 +339,6 @@ void vgmstream_force_loop(VGMSTREAM* vgmstream, int loop_flag, int loop_start_sa
|
|||||||
/* Set number of max loops to do, then play up to stream end (for songs with proper endings) */
|
/* Set number of max loops to do, then play up to stream end (for songs with proper endings) */
|
||||||
void vgmstream_set_loop_target(VGMSTREAM* vgmstream, int loop_target);
|
void vgmstream_set_loop_target(VGMSTREAM* vgmstream, int loop_target);
|
||||||
|
|
||||||
|
void setup_vgmstream_play_state(VGMSTREAM* vgmstream);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
Loading…
Reference in New Issue
Block a user