mirror of
https://github.com/vgmstream/vgmstream.git
synced 2025-02-17 19:19:16 +01:00
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:
parent
f513b9c63f
commit
599b28e497
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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);
|
||||
|
43
test/test.c
43
test/test.c
@ -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);
|
||||
|
@ -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)) {
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user