add fade delay option, validation for in_vgmstream configurables

git-svn-id: https://vgmstream.svn.sourceforge.net/svnroot/vgmstream@134 51a99a44-fe44-0410-b1ba-c3e57ba2b86b
This commit is contained in:
halleyscometsw 2008-05-16 20:28:36 +00:00
parent f513b9c63f
commit 599b28e497
6 changed files with 150 additions and 58 deletions

View File

@ -145,9 +145,9 @@ void close_vgmstream(VGMSTREAM * vgmstream) {
free(vgmstream);
}
int32_t get_vgmstream_play_samples(double looptimes, double fadetime, VGMSTREAM * vgmstream) {
int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double fadedelayseconds, VGMSTREAM * vgmstream) {
if (vgmstream->loop_flag) {
return vgmstream->loop_start_sample+(vgmstream->loop_end_sample-vgmstream->loop_start_sample)*looptimes+fadetime*vgmstream->sample_rate;
return vgmstream->loop_start_sample+(vgmstream->loop_end_sample-vgmstream->loop_start_sample)*looptimes+(fadedelayseconds+fadeseconds)*vgmstream->sample_rate;
} else return vgmstream->num_samples;
}

View File

@ -185,7 +185,7 @@ VGMSTREAM * allocate_vgmstream(int channel_count, int looped);
void close_vgmstream(VGMSTREAM * vgmstream);
/* calculate the number of samples to be played based on looping parameters */
int32_t get_vgmstream_play_samples(double looptimes, double fadetime, VGMSTREAM * vgmstream);
int32_t get_vgmstream_play_samples(double looptimes, double fadeseconds, double fadedelayseconds, VGMSTREAM * vgmstream);
/* render! */
void render_vgmstream(sample * buffer, int32_t sample_count, VGMSTREAM * vgmstream);

View File

@ -10,20 +10,21 @@ extern int optind, opterr, optopt;
void usage(const char * name) {
fprintf(stderr,"vgmstream test decoder " VERSION " " __DATE__ "\n"
"Usage: %s [-o outfile.wav] [-l loop count]\n"
"\t[-f fade time] [-ipcmxeE] infile\n"
"Options:\n"
"\t-o outfile.wav: name of output .wav file, default is dump.wav\n"
"\t-l loop count: loop count, default 2.0\n"
"\t-f fade time: fade time (seconds), default 10.0\n"
"\t-i: ignore looping information and play the whole stream once\n"
"\t-p: output to stdout (for piping into another program)\n"
"\t-P: output to stdout even if stdout is a terminal\n"
"\t-c: loop forever (continuously)\n"
"\t-m: print metadata only, don't decode\n"
"\t-x: decode and print adxencd command line to encode as ADX\n"
"\t-e: force end-to-end looping\n"
"\t-E: force end-to-end looping even if file has real loop points\n"
"Usage: %s [-o outfile.wav] [-l loop count]\n"
" [-f fade time] [-d fade delay] [-ipcmxeE] infile\n"
"Options:\n"
" -o outfile.wav: name of output .wav file, default is dump.wav\n"
" -l loop count: loop count, default 2.0\n"
" -f fade time: fade time (seconds), default 10.0\n"
" -d fade delay: fade delay (seconds, default 0.0\n"
" -i: ignore looping information and play the whole stream once\n"
" -p: output to stdout (for piping into another program)\n"
" -P: output to stdout even if stdout is a terminal\n"
" -c: loop forever (continuously)\n"
" -m: print metadata only, don't decode\n"
" -x: decode and print adxencd command line to encode as ADX\n"
" -e: force end-to-end looping\n"
" -E: force end-to-end looping even if file has real loop points\n"
,name);
}
@ -46,9 +47,10 @@ int main(int argc, char ** argv) {
int metaonly = 0;
int adxencd = 0;
double loop_count = 2.0;
double fade_time = 10.0;
double fade_seconds = 10.0;
double fade_delay_seconds = 0.0;
while ((opt = getopt(argc, argv, "o:l:f:ipPcmxeE")) != -1) {
while ((opt = getopt(argc, argv, "o:l:f:d:ipPcmxeE")) != -1) {
switch (opt) {
case 'o':
outfilename = optarg;
@ -57,7 +59,10 @@ int main(int argc, char ** argv) {
loop_count = atof(optarg);
break;
case 'f':
fade_time = atof(optarg);
fade_seconds = atof(optarg);
break;
case 'd':
fade_delay_seconds = atof(optarg);
break;
case 'i':
ignore_loop = 1;
@ -188,9 +193,9 @@ int main(int argc, char ** argv) {
buf = malloc(BUFSIZE*sizeof(sample)*s->channels);
len = get_vgmstream_play_samples(loop_count,fade_time,s);
len = get_vgmstream_play_samples(loop_count,fade_seconds,fade_delay_seconds,s);
if (!play && !adxencd) printf("samples to play: %d (%.2lf seconds)\n",len,(double)len/s->sample_rate);
fade_samples = fade_time * s->sample_rate;
fade_samples = fade_seconds * s->sample_rate;
/* slap on a .wav header */
make_wav_header((uint8_t*)buf, len, s->sample_rate, s->channels);

View File

@ -35,17 +35,20 @@ DWORD WINAPI __stdcall decode(void *arg);
char lastfn[MAX_PATH+1] = {0}; /* name of the currently playing file */
short sample_buffer[576*2*2]; /* 576 16-bit samples, stereo, possibly doubled in size for DSP */
#define DEFAULT_FADE_SECONDS "10"
#define DEFAULT_LOOP_COUNT "2"
#define DEFAULT_FADE_SECONDS "10.00"
#define DEFAULT_FADE_DELAY_SECONDS "0.00"
#define DEFAULT_LOOP_COUNT "2.00"
#define DEFAULT_THREAD_PRIORITY 3
#define DEFAULT_LOOP_FOREVER 0
#define FADE_SECONDS_INI_ENTRY "fade_seconds"
#define FADE_DELAY_SECONDS_INI_ENTRY "fade_delay"
#define LOOP_COUNT_INI_ENTRY "loop_count"
#define THREAD_PRIORITY_INI_ENTRY "thread_priority"
#define LOOP_FOREVER_INI_ENTRY "loop_forever"
double fade_seconds;
double fade_delay_seconds;
double loop_count;
int thread_priority;
int loop_forever;
@ -127,16 +130,34 @@ void GetINIFileName(char * iniFile) {
void init() {
char iniFile[MAX_PATH+1];
char buf[256];
int consumed;
GetINIFileName(iniFile);
thread_priority=GetPrivateProfileInt(APP_NAME,THREAD_PRIORITY_INI_ENTRY,DEFAULT_THREAD_PRIORITY,iniFile);
if (thread_priority < 0 || thread_priority > 6) {
sprintf(buf,"%d",DEFAULT_THREAD_PRIORITY);
WritePrivateProfileString(APP_NAME,THREAD_PRIORITY_INI_ENTRY,buf,iniFile);
thread_priority = DEFAULT_THREAD_PRIORITY;
}
GetPrivateProfileString(APP_NAME,FADE_SECONDS_INI_ENTRY,DEFAULT_FADE_SECONDS,buf,sizeof(buf),iniFile);
sscanf(buf,"%lf",&fade_seconds);
if (sscanf(buf,"%lf%n",&fade_seconds,&consumed)<1 || consumed!=strlen(buf) || fade_seconds < 0) {
WritePrivateProfileString(APP_NAME,FADE_SECONDS_INI_ENTRY,DEFAULT_FADE_SECONDS,iniFile);
sscanf(DEFAULT_FADE_SECONDS,"%lf",&fade_seconds);
}
GetPrivateProfileString(APP_NAME,FADE_DELAY_SECONDS_INI_ENTRY,DEFAULT_FADE_DELAY_SECONDS,buf,sizeof(buf),iniFile);
if (sscanf(buf,"%lf%n",&fade_delay_seconds,&consumed)<1 || consumed!=strlen(buf)) {
WritePrivateProfileString(APP_NAME,FADE_DELAY_SECONDS_INI_ENTRY,DEFAULT_FADE_DELAY_SECONDS,iniFile);
sscanf(DEFAULT_FADE_DELAY_SECONDS,"%lf",&fade_delay_seconds);
}
GetPrivateProfileString(APP_NAME,LOOP_COUNT_INI_ENTRY,DEFAULT_LOOP_COUNT,buf,sizeof(buf),iniFile);
sscanf(buf,"%lf",&loop_count);
if (sscanf(buf,"%lf%n",&loop_count,&consumed)!=1 || consumed!=strlen(buf) || loop_count < 0) {
WritePrivateProfileString(APP_NAME,LOOP_COUNT_INI_ENTRY,DEFAULT_LOOP_COUNT,iniFile);
sscanf(DEFAULT_LOOP_COUNT,"%lf",&loop_count);
}
loop_forever=GetPrivateProfileInt(APP_NAME,LOOP_FOREVER_INI_ENTRY,DEFAULT_LOOP_FOREVER,iniFile);
@ -196,7 +217,7 @@ int play(char *fn)
decode_pos_ms = 0;
decode_pos_samples = 0;
paused = 0;
stream_length_samples = get_vgmstream_play_samples(loop_count,fade_seconds,vgmstream);
stream_length_samples = get_vgmstream_play_samples(loop_count,fade_seconds,fade_delay_seconds,vgmstream);
fade_samples = (int)(fade_seconds * vgmstream->sample_rate);
@ -304,7 +325,7 @@ void getfileinfo(char *filename, char *title, int *length_in_ms) {
*length_in_ms=-1000;
if ((infostream=init_vgmstream(filename)))
{
*length_in_ms = get_vgmstream_play_samples(loop_count,fade_seconds,infostream)*1000LL/infostream->sample_rate;
*length_in_ms = get_vgmstream_play_samples(loop_count,fade_seconds,fade_delay_seconds,infostream)*1000LL/infostream->sample_rate;
close_vgmstream(infostream);
infostream=NULL;
@ -405,9 +426,11 @@ BOOL CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
mypri=thread_priority;
SetDlgItemText(hDlg,IDC_THREAD_PRIORITY_TEXT,priority_strings[thread_priority]);
sprintf(buf,"%.1lf",fade_seconds);
sprintf(buf,"%.2lf",fade_seconds);
SetDlgItemText(hDlg,IDC_FADE_SECONDS,buf);
sprintf(buf,"%.1lf",loop_count);
sprintf(buf,"%.2lf",fade_delay_seconds);
SetDlgItemText(hDlg,IDC_FADE_DELAY_SECONDS,buf);
sprintf(buf,"%.2lf",loop_count);
SetDlgItemText(hDlg,IDC_LOOP_COUNT,buf);
CheckDlgButton(hDlg,IDC_LOOP_FOREVER,(loop_forever?BST_CHECKED:BST_UNCHECKED));
@ -417,31 +440,89 @@ BOOL CALLBACK configDlgProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam)
switch (GET_WM_COMMAND_ID(wParam, lParam)) {
case IDOK:
{
/* verify before we do anything */
double temp_fade_seconds;
double temp_fade_delay_seconds;
double temp_loop_count;
int consumed;
/* read and verify */
GetDlgItemText(hDlg,IDC_FADE_SECONDS,buf,sizeof(buf));
if (sscanf(buf,"%lf%n",&temp_fade_seconds,&consumed)<1
|| consumed!=strlen(buf) ||
temp_fade_seconds<0) {
MessageBox(hDlg,
"Invalid value for Fade Length\n"
"Must be a number greater than or equal to zero",
"Error",MB_OK|MB_ICONERROR);
break;
}
GetDlgItemText(hDlg,IDC_FADE_DELAY_SECONDS,buf,sizeof(buf));
if (sscanf(buf,"%lf%n",&temp_fade_delay_seconds,
&consumed)<1 || consumed!=strlen(buf)) {
MessageBox(hDlg,
"Invalid valid for Fade Delay\n"
"Must be a number",
"Error",MB_OK|MB_ICONERROR);
break;
}
GetDlgItemText(hDlg,IDC_LOOP_COUNT,buf,sizeof(buf));
if (sscanf(buf,"%lf%n",&temp_loop_count,&consumed)<1 ||
consumed!=strlen(buf) ||
temp_loop_count<0) {
MessageBox(hDlg,
"Invalid value for Loop Count\n"
"Must be a number greater than or equal to zero",
"Error",MB_OK|MB_ICONERROR);
break;
}
GetINIFileName(iniFile);
thread_priority=mypri;
sprintf(buf,"%d",thread_priority);
WritePrivateProfileString(APP_NAME,THREAD_PRIORITY_INI_ENTRY,buf,iniFile);
fade_seconds = temp_fade_seconds;
sprintf(buf,"%.2lf",fade_seconds);
WritePrivateProfileString(APP_NAME,FADE_SECONDS_INI_ENTRY,buf,iniFile);
fade_delay_seconds = temp_fade_delay_seconds;
sprintf(buf,"%.2lf",fade_delay_seconds);
WritePrivateProfileString(APP_NAME,FADE_DELAY_SECONDS_INI_ENTRY,buf,iniFile);
loop_count = temp_loop_count;
sprintf(buf,"%.2lf",loop_count);
WritePrivateProfileString(APP_NAME,LOOP_COUNT_INI_ENTRY,buf,iniFile);
loop_forever = (IsDlgButtonChecked(hDlg,IDC_LOOP_FOREVER) == BST_CHECKED);
sprintf(buf,"%d",loop_forever);
WritePrivateProfileString(APP_NAME,LOOP_FOREVER_INI_ENTRY,buf,iniFile);
}
GetINIFileName(iniFile);
thread_priority=mypri;
sprintf(buf,"%d",thread_priority);
WritePrivateProfileString(APP_NAME,THREAD_PRIORITY_INI_ENTRY,buf,iniFile);
GetDlgItemText(hDlg,IDC_FADE_SECONDS,buf,sizeof(buf));
sscanf(buf,"%lf",&fade_seconds);
WritePrivateProfileString(APP_NAME,FADE_SECONDS_INI_ENTRY,buf,iniFile);
GetDlgItemText(hDlg,IDC_LOOP_COUNT,buf,sizeof(buf));
sscanf(buf,"%lf",&loop_count);
WritePrivateProfileString(APP_NAME,LOOP_COUNT_INI_ENTRY,buf,iniFile);
loop_forever = (IsDlgButtonChecked(hDlg,IDC_LOOP_FOREVER) == BST_CHECKED);
sprintf(buf,"%d",loop_forever);
WritePrivateProfileString(APP_NAME,LOOP_FOREVER_INI_ENTRY,buf,iniFile);
EndDialog(hDlg,TRUE);
break;
case IDCANCEL:
EndDialog(hDlg,TRUE);
break;
case IDC_DEFAULT:
/* set CPU Priority slider */
hSlider=GetDlgItem(hDlg,IDC_THREAD_PRIORITY_SLIDER);
SendMessage(hSlider, TBM_SETRANGE,
(WPARAM) TRUE, /* redraw flag */
(LPARAM) MAKELONG(1, 7)); /* min. & max. positions */
SendMessage(hSlider, TBM_SETPOS,
(WPARAM) TRUE, /* redraw flag */
(LPARAM) DEFAULT_THREAD_PRIORITY+1);
mypri=DEFAULT_THREAD_PRIORITY;
SetDlgItemText(hDlg,IDC_THREAD_PRIORITY_TEXT,priority_strings[mypri]);
SetDlgItemText(hDlg,IDC_FADE_SECONDS,DEFAULT_FADE_SECONDS);
SetDlgItemText(hDlg,IDC_FADE_DELAY_SECONDS,DEFAULT_FADE_DELAY_SECONDS);
SetDlgItemText(hDlg,IDC_LOOP_COUNT,DEFAULT_LOOP_COUNT);
CheckDlgButton(hDlg,IDC_LOOP_FOREVER,(DEFAULT_LOOP_FOREVER?BST_CHECKED:BST_UNCHECKED));
}
case WM_HSCROLL:
if ((struct HWND__ *)lParam==GetDlgItem(hDlg,IDC_THREAD_PRIORITY_SLIDER)) {

View File

@ -1,6 +1,8 @@
#define IDD_CONFIG 101
#define IDC_LOOP_COUNT 1000
#define IDC_FADE_SECONDS 1001
#define IDC_LOOP_FOREVER 1002
#define IDC_THREAD_PRIORITY_SLIDER 1003
#define IDC_THREAD_PRIORITY_TEXT 1004
#define IDC_FADE_DELAY_SECONDS 1002
#define IDC_LOOP_FOREVER 1003
#define IDC_THREAD_PRIORITY_SLIDER 1004
#define IDC_THREAD_PRIORITY_TEXT 1005
#define IDC_DEFAULT 1006

View File

@ -1,21 +1,25 @@
#include "resource.h"
#include "afxres.h"
IDD_CONFIG DIALOGEX 0, 0, 187, 92
IDD_CONFIG DIALOGEX 0, 0, 187, 119
STYLE DS_SETFONT | DS_MODALFRAME | WS_POPUP | WS_CAPTION | WS_SYSMENU
CAPTION "in_vgmstream configuration"
FONT 8, "MS Sans Serif", 0, 0, 0x0
BEGIN
DEFPUSHBUTTON "OK",IDOK,129,7,50,14
PUSHBUTTON "Cancel",IDCANCEL,129,24,50,14
EDITTEXT IDC_LOOP_COUNT,52,7,39,14,ES_AUTOHSCROLL
PUSHBUTTON "Default",IDC_DEFAULT,129,58,50,14
LTEXT "Loop Count",IDC_STATIC,7,10,44,12
EDITTEXT IDC_LOOP_COUNT,52,7,39,14,ES_AUTOHSCROLL
LTEXT "Fade Length",IDC_STATIC,7,25,41,8
EDITTEXT IDC_FADE_SECONDS,52,23,39,14,ES_AUTOHSCROLL
LTEXT "seconds",IDC_STATIC,93,24,29,11
CONTROL "Loop forever",IDC_LOOP_FOREVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,40,77,10
LTEXT "Thread Priority",IDC_STATIC,21,53,46,8
CONTROL "Slider1",IDC_THREAD_PRIORITY_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,7,61,77,10
CTEXT "DATARIFIC",IDC_THREAD_PRIORITY_TEXT,18,74,54,11
LTEXT "seconds",IDC_STATIC,93,25,29,11
LTEXT "Fade Delay",IDC_STATIC,7,40,41,8
EDITTEXT IDC_FADE_DELAY_SECONDS,52,38,39,14,ES_AUTOHSCROLL
LTEXT "seconds",IDC_STATIC,93,40,29,11
CONTROL "Loop forever",IDC_LOOP_FOREVER,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,7,60,77,10
LTEXT "Thread Priority",IDC_STATIC,21,73,46,8
CONTROL "Slider1",IDC_THREAD_PRIORITY_SLIDER,"msctls_trackbar32",TBS_AUTOTICKS | WS_TABSTOP,7,81,77,10
CTEXT "DATARIFIC",IDC_THREAD_PRIORITY_TEXT,7,94,77,18
END