mirror of
https://github.com/vgmstream/vgmstream.git
synced 2024-11-28 00:20:47 +01:00
Apply TXTP looping/time config in foobar/winamp/test
This commit is contained in:
parent
311f4c1689
commit
ea88c85304
@ -254,7 +254,8 @@ static void print_info(VGMSTREAM * vgmstream, cli_config *cfg) {
|
||||
|
||||
static void apply_config(VGMSTREAM * vgmstream, cli_config *cfg) {
|
||||
|
||||
/* honor suggested config, if any (note that defined order matters) */
|
||||
/* honor suggested config, if any (defined order matters)
|
||||
* note that ignore_fade and play_forever should take priority */
|
||||
if (vgmstream->config_loop_count) {
|
||||
cfg->loop_count = vgmstream->config_loop_count;
|
||||
}
|
||||
@ -274,7 +275,13 @@ static void apply_config(VGMSTREAM * vgmstream, cli_config *cfg) {
|
||||
cfg->ignore_fade = 1;
|
||||
}
|
||||
|
||||
/* change loop stuff, in no particular order */
|
||||
/* remove non-compatible options */
|
||||
if (cfg->play_forever) {
|
||||
cfg->ignore_fade = 0;
|
||||
cfg->ignore_loop = 0;
|
||||
}
|
||||
|
||||
/* change vgmstream's loop stuff (ignore loop goes last) */
|
||||
if (cfg->force_loop && !vgmstream->loop_flag) {
|
||||
vgmstream_force_loop(vgmstream, 1, 0,vgmstream->num_samples);
|
||||
}
|
||||
@ -288,6 +295,7 @@ static void apply_config(VGMSTREAM * vgmstream, cli_config *cfg) {
|
||||
/* loop N times, but also play stream end instead of fading out */
|
||||
if (cfg->loop_count > 0 && cfg->ignore_fade) {
|
||||
vgmstream_set_loop_target(vgmstream, (int)cfg->loop_count);
|
||||
cfg->fade_time = 0;
|
||||
}
|
||||
|
||||
/* write loops in the wav, but don't actually loop it */
|
||||
|
@ -201,7 +201,7 @@ bool input_vgmstream::decode_run(audio_chunk & p_chunk,abort_callback & p_abort)
|
||||
t_size bytes;
|
||||
|
||||
{
|
||||
bool loop_okay = loop_forever && vgmstream->loop_flag && !ignore_loop && !force_ignore_loop;
|
||||
bool loop_okay = config.song_play_forever && vgmstream->loop_flag && !config.song_ignore_loop && !force_ignore_loop;
|
||||
if (decode_pos_samples+max_buffer_samples>stream_length_samples && !loop_okay)
|
||||
samples_to_do=stream_length_samples-decode_pos_samples;
|
||||
else
|
||||
@ -234,7 +234,7 @@ bool input_vgmstream::decode_run(audio_chunk & p_chunk,abort_callback & p_abort)
|
||||
|
||||
/* downmix enabled (foobar refuses to do more than 8 channels) */
|
||||
if (downmix_channels > 0 && downmix_channels < vgmstream->channels) {
|
||||
short temp_buffer[OUTBUF_SIZE];
|
||||
short temp_buffer[SAMPLE_BUFFER_SIZE];
|
||||
int s, ch;
|
||||
|
||||
for (s = 0; s < samples_to_do; s++) {
|
||||
@ -275,7 +275,7 @@ bool input_vgmstream::decode_run(audio_chunk & p_chunk,abort_callback & p_abort)
|
||||
void input_vgmstream::decode_seek(double p_seconds,abort_callback & p_abort) {
|
||||
seek_pos_samples = (int) audio_math::time_to_samples(p_seconds, vgmstream->sample_rate);
|
||||
int max_buffer_samples = sizeof(sample_buffer)/sizeof(sample_buffer[0])/vgmstream->channels;
|
||||
bool loop_okay = loop_forever && vgmstream->loop_flag && !ignore_loop && !force_ignore_loop;
|
||||
bool loop_okay = config.song_play_forever && vgmstream->loop_flag && !config.song_ignore_loop && !force_ignore_loop;
|
||||
|
||||
int corrected_pos_samples = seek_pos_samples;
|
||||
|
||||
@ -296,9 +296,8 @@ void input_vgmstream::decode_seek(double p_seconds,abort_callback & p_abort) {
|
||||
// Reset of backwards seek
|
||||
else if(corrected_pos_samples < decode_pos_samples) {
|
||||
reset_vgmstream(vgmstream);
|
||||
if (ignore_loop) {
|
||||
vgmstream_force_loop(vgmstream, 0, 0,0);
|
||||
}
|
||||
apply_config(vgmstream, &config); /* config is undone by reset */
|
||||
|
||||
decode_pos_samples = 0;
|
||||
}
|
||||
|
||||
@ -389,21 +388,20 @@ void input_vgmstream::setup_vgmstream(abort_callback & p_abort) {
|
||||
if (subsong == 0)
|
||||
subsong = 1;
|
||||
|
||||
|
||||
if (ignore_loop) {
|
||||
vgmstream_force_loop(vgmstream, 0, 0,0);
|
||||
}
|
||||
set_config_defaults(&config);
|
||||
apply_config(vgmstream, &config);
|
||||
|
||||
decode_pos_ms = 0;
|
||||
decode_pos_samples = 0;
|
||||
paused = 0;
|
||||
stream_length_samples = get_vgmstream_play_samples(loop_count,fade_seconds,fade_delay_seconds,vgmstream);
|
||||
|
||||
fade_samples = (int)(fade_seconds * vgmstream->sample_rate);
|
||||
stream_length_samples = get_vgmstream_play_samples(config.song_loop_count,config.song_fade_time,config.song_fade_delay,vgmstream);
|
||||
fade_samples = (int)(config.song_fade_time * vgmstream->sample_rate);
|
||||
}
|
||||
|
||||
void input_vgmstream::get_subsong_info(t_uint32 p_subsong, pfc::string_base & title, int *length_in_ms, int *total_samples, int *loop_start, int *loop_end, int *sample_rate, int *channels, int *bitrate, pfc::string_base & description, abort_callback & p_abort) {
|
||||
VGMSTREAM * infostream = NULL;
|
||||
bool is_infostream = false;
|
||||
foobar_song_config infoconfig;
|
||||
char temp[1024];
|
||||
|
||||
// reuse current vgmstream if not querying a new subsong
|
||||
@ -411,19 +409,21 @@ void input_vgmstream::get_subsong_info(t_uint32 p_subsong, pfc::string_base & ti
|
||||
// there is no need to recreate the infostream, there is only one subsong used
|
||||
if (subsong != p_subsong && !direct_subsong) {
|
||||
infostream = init_vgmstream_foo(p_subsong, filename, p_abort);
|
||||
if (ignore_loop) {
|
||||
vgmstream_force_loop(infostream, 0, 0,0);
|
||||
}
|
||||
set_config_defaults(&infoconfig);
|
||||
apply_config(infostream,&infoconfig);
|
||||
is_infostream = true;
|
||||
} else {
|
||||
// vgmstream ready as get_info is valid after open() with any reason
|
||||
infostream = vgmstream;
|
||||
infoconfig = config;
|
||||
}
|
||||
|
||||
|
||||
if (length_in_ms) {
|
||||
*length_in_ms = -1000;
|
||||
if (infostream) {
|
||||
*length_in_ms = get_vgmstream_play_samples(loop_count,fade_seconds,fade_delay_seconds,infostream)*1000LL/infostream->sample_rate;
|
||||
int num_samples = get_vgmstream_play_samples(infoconfig.song_loop_count,infoconfig.song_fade_time,infoconfig.song_fade_delay,infostream);
|
||||
*length_in_ms = num_samples*1000LL / infostream->sample_rate;
|
||||
*sample_rate = infostream->sample_rate;
|
||||
*channels = infostream->channels;
|
||||
*total_samples = infostream->num_samples;
|
||||
@ -463,7 +463,7 @@ void input_vgmstream::get_subsong_info(t_uint32 p_subsong, pfc::string_base & ti
|
||||
}
|
||||
|
||||
// and only close if was querying a new subsong
|
||||
if (subsong != p_subsong && !direct_subsong) {
|
||||
if (is_infostream) {
|
||||
close_vgmstream(infostream);
|
||||
infostream = NULL;
|
||||
}
|
||||
@ -484,6 +484,60 @@ bool input_vgmstream::get_description_tag(pfc::string_base & temp, pfc::string_b
|
||||
return false;
|
||||
}
|
||||
|
||||
void input_vgmstream::set_config_defaults(foobar_song_config *current) {
|
||||
current->song_play_forever = loop_forever;
|
||||
current->song_loop_count = loop_count;
|
||||
current->song_fade_time = fade_seconds;
|
||||
current->song_fade_delay = fade_delay_seconds;
|
||||
current->song_ignore_loop = ignore_loop;
|
||||
current->song_really_force_loop = 0;
|
||||
current->song_ignore_fade = 0;
|
||||
}
|
||||
|
||||
void input_vgmstream::apply_config(VGMSTREAM * vgmstream, foobar_song_config *current) {
|
||||
|
||||
/* honor suggested config, if any (defined order matters)
|
||||
* note that ignore_fade and play_forever should take priority */
|
||||
if (vgmstream->config_loop_count) {
|
||||
current->song_loop_count = vgmstream->config_loop_count;
|
||||
}
|
||||
if (vgmstream->config_fade_delay) {
|
||||
current->song_fade_delay = vgmstream->config_fade_delay;
|
||||
}
|
||||
if (vgmstream->config_fade_time) {
|
||||
current->song_fade_time = vgmstream->config_fade_time;
|
||||
}
|
||||
if (vgmstream->config_force_loop) {
|
||||
current->song_really_force_loop = 1;
|
||||
}
|
||||
if (vgmstream->config_ignore_loop) {
|
||||
current->song_ignore_loop = 1;
|
||||
}
|
||||
if (vgmstream->config_ignore_fade) {
|
||||
current->song_ignore_fade = 1;
|
||||
}
|
||||
|
||||
/* remove non-compatible options */
|
||||
if (current->song_play_forever) {
|
||||
current->song_ignore_fade = 0;
|
||||
current->song_ignore_loop = 0;
|
||||
}
|
||||
|
||||
/* change loop stuff, in no particular order */
|
||||
if (current->song_really_force_loop) {
|
||||
vgmstream_force_loop(vgmstream, 1, 0,vgmstream->num_samples);
|
||||
}
|
||||
if (current->song_ignore_loop) {
|
||||
vgmstream_force_loop(vgmstream, 0, 0,0);
|
||||
current->song_fade_time = 0;
|
||||
}
|
||||
|
||||
/* loop N times, but also play stream end instead of fading out */
|
||||
if (current->song_loop_count > 0 && current->song_ignore_fade) {
|
||||
vgmstream_set_loop_target(vgmstream, (int)current->song_loop_count);
|
||||
}
|
||||
}
|
||||
|
||||
GUID input_vgmstream::g_get_guid()
|
||||
{
|
||||
static const GUID guid = { 0x9e7263c7, 0x4cdd, 0x482c,{ 0x9a, 0xec, 0x5e, 0x71, 0x28, 0xcb, 0xc3, 0x4 } };
|
||||
|
@ -1,7 +1,19 @@
|
||||
#ifndef _FOO_VGMSTREAM_
|
||||
#define _FOO_VGMSTREAM_
|
||||
|
||||
#define OUTBUF_SIZE 1024 /* Samples */
|
||||
#define SAMPLE_BUFFER_SIZE 1024
|
||||
|
||||
/* current song settings */
|
||||
typedef struct {
|
||||
int song_play_forever;
|
||||
double song_loop_count;
|
||||
double song_fade_time;
|
||||
double song_fade_delay;
|
||||
int song_ignore_loop;
|
||||
int song_really_force_loop;
|
||||
int song_ignore_fade;
|
||||
} foobar_song_config;
|
||||
|
||||
|
||||
class input_vgmstream : public input_stubs {
|
||||
public:
|
||||
@ -51,7 +63,7 @@ class input_vgmstream : public input_stubs {
|
||||
int stream_length_samples;
|
||||
int fade_samples;
|
||||
int seek_pos_samples;
|
||||
short sample_buffer[OUTBUF_SIZE];
|
||||
short sample_buffer[SAMPLE_BUFFER_SIZE];
|
||||
|
||||
/* config */
|
||||
double fade_seconds;
|
||||
@ -63,12 +75,16 @@ class input_vgmstream : public input_stubs {
|
||||
bool disable_subsongs;
|
||||
int downmix_channels;
|
||||
|
||||
foobar_song_config config;
|
||||
|
||||
/* helpers */
|
||||
VGMSTREAM * init_vgmstream_foo(t_uint32 p_subsong, const char * const filename, abort_callback & p_abort);
|
||||
void setup_vgmstream(abort_callback & p_abort);
|
||||
void load_settings();
|
||||
void get_subsong_info(t_uint32 p_subsong, pfc::string_base & title, int *length_in_ms, int *total_samples, int *loop_start, int *loop_end, int *sample_rate, int *channels, int *bitrate, pfc::string_base & description, abort_callback & p_abort);
|
||||
bool get_description_tag(pfc::string_base & temp, pfc::string_base const& description, const char *tag, char delimiter = '\n');
|
||||
void set_config_defaults(foobar_song_config *current);
|
||||
void apply_config(VGMSTREAM * vgmstream, foobar_song_config *current);
|
||||
};
|
||||
|
||||
/* foo_streamfile.cpp */
|
||||
|
@ -48,18 +48,32 @@ DWORD WINAPI __stdcall decode(void *arg);
|
||||
#define EXT_BUFFER_SIZE 200
|
||||
char working_extension_list[EXTENSION_LIST_SIZE] = {0};
|
||||
|
||||
/* defaults */
|
||||
typedef struct {
|
||||
double fade_seconds;
|
||||
double fade_delay_seconds;
|
||||
double loop_count;
|
||||
int thread_priority;
|
||||
int loop_forever;
|
||||
int ignore_loop;
|
||||
int loop_forever;
|
||||
int thread_priority;
|
||||
int disable_subsongs;
|
||||
int downmix_channels;
|
||||
} winamp_config;
|
||||
} winamp_settings;
|
||||
|
||||
/* current song settings */
|
||||
typedef struct {
|
||||
int song_play_forever;
|
||||
double song_loop_count;
|
||||
double song_fade_time;
|
||||
double song_fade_delay;
|
||||
int song_ignore_loop;
|
||||
int song_really_force_loop;
|
||||
int song_ignore_fade;
|
||||
} winamp_song_config;
|
||||
|
||||
winamp_settings settings;
|
||||
winamp_song_config config;
|
||||
|
||||
winamp_config config;
|
||||
|
||||
/* plugin state */
|
||||
VGMSTREAM * vgmstream = NULL;
|
||||
@ -75,6 +89,7 @@ int stream_length_samples = 0;
|
||||
int fade_samples = 0;
|
||||
int output_channels = 0;
|
||||
|
||||
|
||||
in_char lastfn[PATH_LIMIT] = {0}; /* name of the currently playing file */
|
||||
|
||||
/* ************************************* */
|
||||
@ -389,58 +404,58 @@ static void load_config() {
|
||||
|
||||
GetINIFileName(iniFile);
|
||||
|
||||
config.thread_priority = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_THREAD_PRIORITY,DEFAULT_THREAD_PRIORITY,iniFile);
|
||||
if (config.thread_priority < 0 || config.thread_priority > 6) {
|
||||
settings.thread_priority = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_THREAD_PRIORITY,DEFAULT_THREAD_PRIORITY,iniFile);
|
||||
if (settings.thread_priority < 0 || settings.thread_priority > 6) {
|
||||
cfg_sprintf(buf, TEXT("%d"),DEFAULT_THREAD_PRIORITY);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_THREAD_PRIORITY,buf,iniFile);
|
||||
config.thread_priority = DEFAULT_THREAD_PRIORITY;
|
||||
settings.thread_priority = DEFAULT_THREAD_PRIORITY;
|
||||
}
|
||||
|
||||
GetPrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_FADE_SECONDS,DEFAULT_FADE_SECONDS,buf,buf_size,iniFile);
|
||||
res = cfg_sscanf(buf, TEXT("%lf%n"),&config.fade_seconds,&consumed);
|
||||
if (res < 1 || consumed != cfg_strlen(buf) || config.fade_seconds < 0) {
|
||||
res = cfg_sscanf(buf, TEXT("%lf%n"),&settings.fade_seconds,&consumed);
|
||||
if (res < 1 || consumed != cfg_strlen(buf) || settings.fade_seconds < 0) {
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_FADE_SECONDS,DEFAULT_FADE_SECONDS,iniFile);
|
||||
cfg_sscanf(DEFAULT_FADE_SECONDS, TEXT("%lf"),&config.fade_seconds);
|
||||
cfg_sscanf(DEFAULT_FADE_SECONDS, TEXT("%lf"),&settings.fade_seconds);
|
||||
}
|
||||
|
||||
GetPrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_FADE_DELAY_SECONDS,DEFAULT_FADE_DELAY_SECONDS,buf,buf_size,iniFile);
|
||||
res = cfg_sscanf(buf, TEXT("%lf%n"),&config.fade_delay_seconds,&consumed);
|
||||
res = cfg_sscanf(buf, TEXT("%lf%n"),&settings.fade_delay_seconds,&consumed);
|
||||
if (res < 1 || consumed != cfg_strlen(buf)) {
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_FADE_DELAY_SECONDS,DEFAULT_FADE_DELAY_SECONDS,iniFile);
|
||||
cfg_sscanf(DEFAULT_FADE_DELAY_SECONDS, TEXT("%lf"),&config.fade_delay_seconds);
|
||||
cfg_sscanf(DEFAULT_FADE_DELAY_SECONDS, TEXT("%lf"),&settings.fade_delay_seconds);
|
||||
}
|
||||
|
||||
GetPrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_LOOP_COUNT,DEFAULT_LOOP_COUNT,buf,buf_size,iniFile);
|
||||
res = cfg_sscanf(buf, TEXT("%lf%n"),&config.loop_count,&consumed);
|
||||
if (res < 1 || consumed != cfg_strlen(buf) || config.loop_count < 0) {
|
||||
res = cfg_sscanf(buf, TEXT("%lf%n"),&settings.loop_count,&consumed);
|
||||
if (res < 1 || consumed != cfg_strlen(buf) || settings.loop_count < 0) {
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_LOOP_COUNT,DEFAULT_LOOP_COUNT,iniFile);
|
||||
cfg_sscanf(DEFAULT_LOOP_COUNT, TEXT("%lf"),&config.loop_count);
|
||||
cfg_sscanf(DEFAULT_LOOP_COUNT, TEXT("%lf"),&settings.loop_count);
|
||||
}
|
||||
|
||||
config.loop_forever = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_LOOP_FOREVER,DEFAULT_LOOP_FOREVER,iniFile);
|
||||
config.ignore_loop = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_IGNORE_LOOP,DEFAULT_IGNORE_LOOP,iniFile);
|
||||
if (config.loop_forever && config.ignore_loop) {
|
||||
settings.loop_forever = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_LOOP_FOREVER,DEFAULT_LOOP_FOREVER,iniFile);
|
||||
settings.ignore_loop = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_IGNORE_LOOP,DEFAULT_IGNORE_LOOP,iniFile);
|
||||
if (settings.loop_forever && settings.ignore_loop) {
|
||||
cfg_sprintf(buf, TEXT("%d"),DEFAULT_LOOP_FOREVER);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_LOOP_FOREVER,buf,iniFile);
|
||||
config.loop_forever = DEFAULT_LOOP_FOREVER;
|
||||
settings.loop_forever = DEFAULT_LOOP_FOREVER;
|
||||
|
||||
cfg_sprintf(buf, TEXT("%d"),DEFAULT_IGNORE_LOOP);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_IGNORE_LOOP,buf,iniFile);
|
||||
config.ignore_loop = DEFAULT_IGNORE_LOOP;
|
||||
settings.ignore_loop = DEFAULT_IGNORE_LOOP;
|
||||
}
|
||||
|
||||
config.disable_subsongs = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_DISABLE_SUBSONGS,DEFAULT_DISABLE_SUBSONGS,iniFile);
|
||||
//if (config.disable_subsongs < 0) { //unneeded?
|
||||
settings.disable_subsongs = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_DISABLE_SUBSONGS,DEFAULT_DISABLE_SUBSONGS,iniFile);
|
||||
//if (settings.disable_subsongs < 0) { //unneeded?
|
||||
// sprintf(buf, TEXT("%d"),DEFAULT_DISABLE_SUBSONGS);
|
||||
// WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_DISABLE_SUBSONGS,buf,iniFile);
|
||||
// config.disable_subsongs = DEFAULT_DISABLE_SUBSONGS;
|
||||
// settings.disable_subsongs = DEFAULT_DISABLE_SUBSONGS;
|
||||
//}
|
||||
|
||||
config.downmix_channels = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_DOWNMIX_CHANNELS,DEFAULT_DOWNMIX_CHANNELS,iniFile);
|
||||
if (config.downmix_channels < 0) {
|
||||
settings.downmix_channels = GetPrivateProfileInt(CONFIG_APP_NAME,INI_ENTRY_DOWNMIX_CHANNELS,DEFAULT_DOWNMIX_CHANNELS,iniFile);
|
||||
if (settings.downmix_channels < 0) {
|
||||
cfg_sprintf(buf, TEXT("%d"),DEFAULT_DOWNMIX_CHANNELS);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_DOWNMIX_CHANNELS,buf,iniFile);
|
||||
config.downmix_channels = DEFAULT_DOWNMIX_CHANNELS;
|
||||
settings.downmix_channels = DEFAULT_DOWNMIX_CHANNELS;
|
||||
}
|
||||
|
||||
}
|
||||
@ -467,30 +482,30 @@ INT_PTR CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
|
||||
(LPARAM) MAKELONG(1, 7)); /* min. & max. positions */
|
||||
SendMessage(hSlider, TBM_SETPOS,
|
||||
(WPARAM) TRUE, /* redraw flag */
|
||||
(LPARAM) config.thread_priority+1);
|
||||
mypri = config.thread_priority;
|
||||
SetDlgItemText(hDlg,IDC_THREAD_PRIORITY_TEXT,priority_strings[config.thread_priority]);
|
||||
(LPARAM) settings.thread_priority+1);
|
||||
mypri = settings.thread_priority;
|
||||
SetDlgItemText(hDlg,IDC_THREAD_PRIORITY_TEXT,priority_strings[settings.thread_priority]);
|
||||
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),config.fade_seconds);
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),settings.fade_seconds);
|
||||
SetDlgItemText(hDlg,IDC_FADE_SECONDS,buf);
|
||||
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),config.fade_delay_seconds);
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),settings.fade_delay_seconds);
|
||||
SetDlgItemText(hDlg,IDC_FADE_DELAY_SECONDS,buf);
|
||||
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),config.loop_count);
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),settings.loop_count);
|
||||
SetDlgItemText(hDlg,IDC_LOOP_COUNT,buf);
|
||||
|
||||
if (config.loop_forever)
|
||||
if (settings.loop_forever)
|
||||
CheckDlgButton(hDlg,IDC_LOOP_FOREVER,BST_CHECKED);
|
||||
else if (config.ignore_loop)
|
||||
else if (settings.ignore_loop)
|
||||
CheckDlgButton(hDlg,IDC_IGNORE_LOOP,BST_CHECKED);
|
||||
else
|
||||
CheckDlgButton(hDlg,IDC_LOOP_NORMALLY,BST_CHECKED);
|
||||
|
||||
if (config.disable_subsongs)
|
||||
if (settings.disable_subsongs)
|
||||
CheckDlgButton(hDlg,IDC_DISABLE_SUBSONGS,BST_CHECKED);
|
||||
|
||||
cfg_sprintf(buf, TEXT("%d"),config.downmix_channels);
|
||||
cfg_sprintf(buf, TEXT("%d"),settings.downmix_channels);
|
||||
SetDlgItemText(hDlg,IDC_DOWNMIX_CHANNELS,buf);
|
||||
|
||||
break;
|
||||
@ -548,40 +563,40 @@ INT_PTR CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lPara
|
||||
|
||||
GetINIFileName(iniFile);
|
||||
|
||||
config.thread_priority = mypri;
|
||||
cfg_sprintf(buf, TEXT("%d"),config.thread_priority);
|
||||
settings.thread_priority = mypri;
|
||||
cfg_sprintf(buf, TEXT("%d"),settings.thread_priority);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_THREAD_PRIORITY,buf,iniFile);
|
||||
|
||||
config.fade_seconds = temp_fade_seconds;
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),config.fade_seconds);
|
||||
settings.fade_seconds = temp_fade_seconds;
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),settings.fade_seconds);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_FADE_SECONDS,buf,iniFile);
|
||||
|
||||
config.fade_delay_seconds = temp_fade_delay_seconds;
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),config.fade_delay_seconds);
|
||||
settings.fade_delay_seconds = temp_fade_delay_seconds;
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),settings.fade_delay_seconds);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_FADE_DELAY_SECONDS,buf,iniFile);
|
||||
|
||||
config.loop_count = temp_loop_count;
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),config.loop_count);
|
||||
settings.loop_count = temp_loop_count;
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),settings.loop_count);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_LOOP_COUNT,buf,iniFile);
|
||||
|
||||
config.loop_forever = (IsDlgButtonChecked(hDlg,IDC_LOOP_FOREVER) == BST_CHECKED);
|
||||
cfg_sprintf(buf, TEXT("%d"),config.loop_forever);
|
||||
settings.loop_forever = (IsDlgButtonChecked(hDlg,IDC_LOOP_FOREVER) == BST_CHECKED);
|
||||
cfg_sprintf(buf, TEXT("%d"),settings.loop_forever);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_LOOP_FOREVER,buf,iniFile);
|
||||
|
||||
config.ignore_loop = (IsDlgButtonChecked(hDlg,IDC_IGNORE_LOOP) == BST_CHECKED);
|
||||
cfg_sprintf(buf, TEXT("%d"),config.ignore_loop);
|
||||
settings.ignore_loop = (IsDlgButtonChecked(hDlg,IDC_IGNORE_LOOP) == BST_CHECKED);
|
||||
cfg_sprintf(buf, TEXT("%d"),settings.ignore_loop);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_IGNORE_LOOP,buf,iniFile);
|
||||
|
||||
config.disable_subsongs = (IsDlgButtonChecked(hDlg,IDC_DISABLE_SUBSONGS) == BST_CHECKED);
|
||||
cfg_sprintf(buf, TEXT("%d"),config.disable_subsongs);
|
||||
settings.disable_subsongs = (IsDlgButtonChecked(hDlg,IDC_DISABLE_SUBSONGS) == BST_CHECKED);
|
||||
cfg_sprintf(buf, TEXT("%d"),settings.disable_subsongs);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_DISABLE_SUBSONGS,buf,iniFile);
|
||||
|
||||
config.loop_count = temp_loop_count;
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),config.loop_count);
|
||||
settings.loop_count = temp_loop_count;
|
||||
cfg_sprintf(buf, TEXT("%.2lf"),settings.loop_count);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_LOOP_COUNT,buf,iniFile);
|
||||
|
||||
config.downmix_channels = temp_downmix_channels;
|
||||
cfg_sprintf(buf, TEXT("%d"),config.downmix_channels);
|
||||
settings.downmix_channels = temp_downmix_channels;
|
||||
cfg_sprintf(buf, TEXT("%d"),settings.downmix_channels);
|
||||
WritePrivateProfileString(CONFIG_APP_NAME,INI_ENTRY_DOWNMIX_CHANNELS,buf,iniFile);
|
||||
}
|
||||
|
||||
@ -657,7 +672,7 @@ static int split_subsongs(const in_char * filename, int stream_index, VGMSTREAM
|
||||
HWND hPlaylistWindow;
|
||||
|
||||
|
||||
if (config.disable_subsongs || vgmstream->num_streams <= 1)
|
||||
if (settings.disable_subsongs || vgmstream->num_streams <= 1)
|
||||
return 0; /* don't split if no subsongs */
|
||||
if (stream_index > 0 || vgmstream->stream_index > 0)
|
||||
return 0; /* no split if already playing subsong */
|
||||
@ -828,6 +843,60 @@ static void get_title(in_char * dst, int dst_size, const in_char * fn, VGMSTREAM
|
||||
}
|
||||
}
|
||||
|
||||
static void set_config_defaults(winamp_song_config *current) {
|
||||
current->song_play_forever = settings.loop_forever;
|
||||
current->song_loop_count = settings.loop_count;
|
||||
current->song_fade_time = settings.fade_seconds;
|
||||
current->song_fade_delay = settings.fade_delay_seconds;
|
||||
current->song_ignore_loop = settings.ignore_loop;
|
||||
current->song_really_force_loop = 0;
|
||||
current->song_ignore_fade = 0;
|
||||
}
|
||||
|
||||
static void apply_config(VGMSTREAM * vgmstream, winamp_song_config *current) {
|
||||
|
||||
/* honor suggested config, if any (defined order matters)
|
||||
* note that ignore_fade and play_forever should take priority */
|
||||
if (vgmstream->config_loop_count) {
|
||||
current->song_loop_count = vgmstream->config_loop_count;
|
||||
}
|
||||
if (vgmstream->config_fade_delay) {
|
||||
current->song_fade_delay = vgmstream->config_fade_delay;
|
||||
}
|
||||
if (vgmstream->config_fade_time) {
|
||||
current->song_fade_time = vgmstream->config_fade_time;
|
||||
}
|
||||
if (vgmstream->config_force_loop) {
|
||||
current->song_really_force_loop = 1;
|
||||
}
|
||||
if (vgmstream->config_ignore_loop) {
|
||||
current->song_ignore_loop = 1;
|
||||
}
|
||||
if (vgmstream->config_ignore_fade) {
|
||||
current->song_ignore_fade = 1;
|
||||
}
|
||||
|
||||
/* remove non-compatible options */
|
||||
if (current->song_play_forever) {
|
||||
current->song_ignore_fade = 0;
|
||||
current->song_ignore_loop = 0;
|
||||
}
|
||||
|
||||
/* change loop stuff, in no particular order */
|
||||
if (current->song_really_force_loop) {
|
||||
vgmstream_force_loop(vgmstream, 1, 0,vgmstream->num_samples);
|
||||
}
|
||||
if (current->song_ignore_loop) {
|
||||
vgmstream_force_loop(vgmstream, 0, 0,0);
|
||||
current->song_fade_time = 0;
|
||||
}
|
||||
|
||||
/* loop N times, but also play stream end instead of fading out */
|
||||
if (current->song_loop_count > 0 && current->song_ignore_fade) {
|
||||
vgmstream_set_loop_target(vgmstream, (int)current->song_loop_count);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/* ***************************************** */
|
||||
/* IN_VGMSTREAM */
|
||||
@ -862,7 +931,7 @@ void winamp_Init() {
|
||||
|
||||
/* XMPlay with in_vgmstream doesn't support most IPC_x messages so no playlist manipulation */
|
||||
if (is_xmplay()) {
|
||||
config.disable_subsongs = 1;
|
||||
settings.disable_subsongs = 1;
|
||||
}
|
||||
|
||||
/* dynamically make a list of supported extensions */
|
||||
@ -900,6 +969,7 @@ int winamp_IsOurFile(const in_char *fn) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
/* request to start playing a file */
|
||||
int winamp_Play(const in_char *fn) {
|
||||
int max_latency;
|
||||
@ -926,13 +996,12 @@ int winamp_Play(const in_char *fn) {
|
||||
}
|
||||
|
||||
/* config */
|
||||
if (config.ignore_loop) {
|
||||
vgmstream_force_loop(vgmstream, 0, 0,0);
|
||||
}
|
||||
set_config_defaults(&config);
|
||||
apply_config(vgmstream, &config);
|
||||
|
||||
output_channels = vgmstream->channels;
|
||||
if (config.downmix_channels > 0 && config.downmix_channels < vgmstream->channels)
|
||||
output_channels = config.downmix_channels;
|
||||
if (settings.downmix_channels > 0 && settings.downmix_channels < vgmstream->channels)
|
||||
output_channels = settings.downmix_channels;
|
||||
|
||||
|
||||
/* save original name */
|
||||
@ -959,8 +1028,8 @@ int winamp_Play(const in_char *fn) {
|
||||
decode_pos_ms = 0;
|
||||
decode_pos_samples = 0;
|
||||
paused = 0;
|
||||
stream_length_samples = get_vgmstream_play_samples(config.loop_count,config.fade_seconds,config.fade_delay_seconds,vgmstream);
|
||||
fade_samples = (int)(config.fade_seconds * vgmstream->sample_rate);
|
||||
stream_length_samples = get_vgmstream_play_samples(config.song_loop_count,config.song_fade_time,config.song_fade_delay,vgmstream);
|
||||
fade_samples = (int)(config.song_fade_time * vgmstream->sample_rate);
|
||||
|
||||
/* start */
|
||||
decode_thread_handle = CreateThread(
|
||||
@ -971,7 +1040,7 @@ int winamp_Play(const in_char *fn) {
|
||||
0, /* run thread immediately */
|
||||
NULL); /* don't keep track of the thread id */
|
||||
|
||||
SetThreadPriority(decode_thread_handle,priority_values[config.thread_priority]); //todo don't use priority values directly?
|
||||
SetThreadPriority(decode_thread_handle,priority_values[settings.thread_priority]); //todo don't use priority values directly?
|
||||
|
||||
return 0; /* success */
|
||||
}
|
||||
@ -1057,6 +1126,7 @@ int winamp_InfoBox(const in_char *fn, HWND hwnd) {
|
||||
else {
|
||||
/* some other file in playlist given by filename */
|
||||
VGMSTREAM * infostream = NULL;
|
||||
winamp_song_config infoconfig = {0};
|
||||
in_char filename[PATH_LIMIT];
|
||||
int stream_index = 0;
|
||||
|
||||
@ -1065,12 +1135,10 @@ int winamp_InfoBox(const in_char *fn, HWND hwnd) {
|
||||
parse_fn_int(fn, wa_L("$s"), &stream_index);
|
||||
|
||||
infostream = init_vgmstream_winamp(filename, stream_index);
|
||||
if (!infostream)
|
||||
return 0;
|
||||
if (!infostream) return 0;
|
||||
|
||||
if (config.ignore_loop) {
|
||||
vgmstream_force_loop(infostream, 0, 0,0);
|
||||
}
|
||||
set_config_defaults(&infoconfig);
|
||||
apply_config(infostream, &infoconfig);
|
||||
|
||||
describe_vgmstream(infostream,description,description_size);
|
||||
|
||||
@ -1109,6 +1177,7 @@ void winamp_GetFileInfo(const in_char *fn, in_char *title, int *length_in_ms) {
|
||||
else {
|
||||
/* some other file in playlist given by filename */
|
||||
VGMSTREAM * infostream = NULL;
|
||||
winamp_song_config infoconfig = {0};
|
||||
in_char filename[PATH_LIMIT];
|
||||
int stream_index = 0;
|
||||
|
||||
@ -1119,9 +1188,8 @@ void winamp_GetFileInfo(const in_char *fn, in_char *title, int *length_in_ms) {
|
||||
infostream = init_vgmstream_winamp(filename, stream_index);
|
||||
if (!infostream) return;
|
||||
|
||||
if (config.ignore_loop) {
|
||||
vgmstream_force_loop(infostream, 0, 0,0);
|
||||
}
|
||||
set_config_defaults(&infoconfig);
|
||||
apply_config(infostream, &infoconfig);
|
||||
|
||||
if (title) {
|
||||
get_title(title,GETFILEINFO_TITLE_LENGTH, fn, infostream);
|
||||
@ -1130,7 +1198,7 @@ void winamp_GetFileInfo(const in_char *fn, in_char *title, int *length_in_ms) {
|
||||
if (length_in_ms) {
|
||||
*length_in_ms = -1000;
|
||||
if (infostream) {
|
||||
int num_samples = get_vgmstream_play_samples(config.loop_count,config.fade_seconds,config.fade_delay_seconds,infostream);
|
||||
int num_samples = get_vgmstream_play_samples(infoconfig.song_loop_count,infoconfig.song_fade_time,infoconfig.song_fade_delay,infostream);
|
||||
*length_in_ms = num_samples * 1000LL /infostream->sample_rate;
|
||||
}
|
||||
}
|
||||
@ -1147,14 +1215,14 @@ void winamp_EQSet(int on, char data[10], int preamp) {
|
||||
/* the decode thread */
|
||||
DWORD WINAPI __stdcall decode(void *arg) {
|
||||
int max_buffer_samples = sizeof(sample_buffer) / sizeof(sample_buffer[0]) / 2 / vgmstream->channels;
|
||||
int max_samples = get_vgmstream_play_samples(config.loop_count,config.fade_seconds,config.fade_delay_seconds,vgmstream);
|
||||
int max_samples = stream_length_samples;
|
||||
|
||||
while (!decode_abort) {
|
||||
int samples_to_do;
|
||||
int output_bytes;
|
||||
|
||||
if (decode_pos_samples + max_buffer_samples > stream_length_samples
|
||||
&& (!config.loop_forever || !vgmstream->loop_flag))
|
||||
&& (!settings.loop_forever || !vgmstream->loop_flag))
|
||||
samples_to_do = stream_length_samples - decode_pos_samples;
|
||||
else
|
||||
samples_to_do = max_buffer_samples;
|
||||
@ -1164,10 +1232,7 @@ DWORD WINAPI __stdcall decode(void *arg) {
|
||||
/* reset if we need to seek backwards */
|
||||
if (seek_needed_samples < decode_pos_samples) {
|
||||
reset_vgmstream(vgmstream);
|
||||
|
||||
if (config.ignore_loop) {
|
||||
vgmstream_force_loop(vgmstream, 0, 0,0);
|
||||
}
|
||||
apply_config(vgmstream, &config); /* config is undone by reset */
|
||||
|
||||
decode_pos_samples = 0;
|
||||
decode_pos_ms = 0;
|
||||
@ -1216,7 +1281,7 @@ DWORD WINAPI __stdcall decode(void *arg) {
|
||||
render_vgmstream(sample_buffer,samples_to_do,vgmstream);
|
||||
|
||||
/* fade near the end */
|
||||
if (vgmstream->loop_flag && fade_samples > 0 && !config.loop_forever) {
|
||||
if (vgmstream->loop_flag && fade_samples > 0 && !settings.loop_forever) {
|
||||
int samples_into_fade = decode_pos_samples - (stream_length_samples - fade_samples);
|
||||
if (samples_into_fade + samples_to_do > 0) {
|
||||
int j,k;
|
||||
@ -1233,28 +1298,28 @@ DWORD WINAPI __stdcall decode(void *arg) {
|
||||
}
|
||||
|
||||
/* downmix enabled (useful when the stream's channels are too much for Winamp's output) */
|
||||
if (config.downmix_channels > 0 && config.downmix_channels < vgmstream->channels) {
|
||||
if (settings.downmix_channels > 0 && settings.downmix_channels < vgmstream->channels) {
|
||||
short temp_buffer[(576*2) * 2];
|
||||
int s, ch;
|
||||
|
||||
for (s = 0; s < samples_to_do; s++) {
|
||||
/* copy channels up to max */
|
||||
for (ch = 0; ch < config.downmix_channels; ch++) {
|
||||
temp_buffer[s*config.downmix_channels + ch] = sample_buffer[s*vgmstream->channels + ch];
|
||||
for (ch = 0; ch < settings.downmix_channels; ch++) {
|
||||
temp_buffer[s*settings.downmix_channels + ch] = sample_buffer[s*vgmstream->channels + ch];
|
||||
}
|
||||
/* then mix the rest */
|
||||
for (ch = config.downmix_channels; ch < vgmstream->channels; ch++) {
|
||||
int downmix_ch = ch % config.downmix_channels;
|
||||
int new_sample = ((int)temp_buffer[s*config.downmix_channels + downmix_ch] + (int)sample_buffer[s*vgmstream->channels + ch]);
|
||||
for (ch = settings.downmix_channels; ch < vgmstream->channels; ch++) {
|
||||
int downmix_ch = ch % settings.downmix_channels;
|
||||
int new_sample = ((int)temp_buffer[s*settings.downmix_channels + downmix_ch] + (int)sample_buffer[s*vgmstream->channels + ch]);
|
||||
new_sample = (int)(new_sample * 0.7); /* limit clipping without removing too much loudness... hopefully */
|
||||
if (new_sample > 32767) new_sample = 32767;
|
||||
else if (new_sample < -32768) new_sample = -32768;
|
||||
temp_buffer[s*config.downmix_channels + downmix_ch] = (short)new_sample;
|
||||
temp_buffer[s*settings.downmix_channels + downmix_ch] = (short)new_sample;
|
||||
}
|
||||
}
|
||||
|
||||
/* copy back to global buffer... in case of multithreading stuff? */
|
||||
memcpy(sample_buffer,temp_buffer, samples_to_do*config.downmix_channels*sizeof(short));
|
||||
memcpy(sample_buffer,temp_buffer, samples_to_do*settings.downmix_channels*sizeof(short));
|
||||
}
|
||||
|
||||
/* output samples */
|
||||
|
Loading…
Reference in New Issue
Block a user