22#include < WaveSabrePlayerLib.h>
33using namespace WaveSabrePlayerLib ;
44
5+ #include < stdlib.h>
6+ #include < stdio.h>
57#include < string.h>
68
79WaveSabreCore::Device *SongFactory (SongRenderer::DeviceId id)
@@ -34,20 +36,135 @@ void progressCallback(double progress, void *data)
3436 printf (" ]" );
3537}
3638
37- int main (int argc, char **argv)
39+ struct player_args
40+ {
41+ const char * infile;
42+ const char * outfile;
43+ int nthreads;
44+ bool prerender;
45+ bool wavwriter;
46+ };
47+
48+ static void print_usage (const char * prgm)
49+ {
50+ printf (" %s: WaveSabre standalone song player/renderer\n "
51+ " Usage:\n "
52+ " \t %s [-p|--prerender] [-w|--wav [out.wav]] [-t|--threads n] <input.bin>\n "
53+ " \n "
54+ " Arguments:\n "
55+ " \t prerender prerender the song instead of rendering while playing.\n "
56+ " \t wav instead of playing back the song, write a WAV file. By default,\n "
57+ " \t the output file is called `out.wav', but another may be supplied\n "
58+ " \t immediately after this argument.\n "
59+ " \t threads the amount of threads to use in parallel for rendering. By\n "
60+ " \t default, this number is 3.\n "
61+ " \t input.bin the input song file, exported by the WaveSabre exporter.\n "
62+ , prgm, prgm);
63+ }
64+ static void parse_args (struct player_args * args, int argc, char ** argv)
3865{
39- bool writeWav = argc >= 3 && !strcmp (argv[2 ], " -w" );
40- bool preRender = argc == 3 && !strcmp (argv[2 ], " -p" );
66+ if (argc < 2 )
67+ {
68+ print_usage (argv[0 ]);
69+ exit (1 );
70+ }
71+
72+ args->infile = NULL ;
73+ args->outfile = NULL ;
74+ args->nthreads = 3 ;
75+ args->prerender = false ;
76+ args->wavwriter = false ;
77+
78+ for (int i = 1 ; i < argc; ++i)
79+ {
80+ if (argv[i][0 ] == ' -' )
81+ {
82+ const char * as = argv[i] + 1 ; // skip arg prefix char ('-')
83+
84+ if (!strcmp (as, " h" ) || !strcmp (as, " -help" ))
85+ {
86+ print_usage (argv[0 ]);
87+ exit (0 );
88+ }
89+ // TODO: option for printing version info
90+ if (!strcmp (as, " p" ) || !strcmp (as, " -prerender" ))
91+ {
92+ args->prerender = true ;
93+ continue ;
94+ }
95+ if (!strcmp (as, " w" ) || !strcmp (as, " -wav" ))
96+ {
97+ args->wavwriter = true ;
98+
99+ if (i+1 < argc && argv[i+1 ][0 ] != ' -' )
100+ {
101+ // last argument, and no input file set yet, so we really
102+ // need to prioritise the input file here
103+ if (argc-1 == i+1 && args->infile == NULL )
104+ {
105+ args->outfile = " out.wav" ;
106+ }
107+ else
108+ {
109+ args->outfile = argv[i+1 ];
110+ ++i;
111+ }
112+ }
113+ else
114+ {
115+ args->outfile = " out.wav" ;
116+ }
117+ continue ;
118+ }
119+ if (!strcmp (as, " t" ) || !strcmp (as, " -threads" ))
120+ {
121+ if (i+1 == argc)
122+ {
123+ printf (" Expecting thread amount\n " );
124+ exit (2 );
125+ }
126+
127+ ++i;
128+ int res = sscanf (argv[i], " %d" , &args->nthreads );
129+ if (res != 1 || args->nthreads < 0 )
130+ {
131+ printf (" Can't parse thread amount '%s'\n " , argv[i]);
132+ exit (2 );
133+ }
134+
135+ continue ;
136+ }
137+
138+ printf (" Unrecognised option '%s', ignoring...\n " , argv[i]);
139+ }
140+ else
141+ {
142+ if (args->infile != NULL )
143+ {
144+ printf (" Unexpected argument '%s'\n " , argv[i]);
145+ exit (2 );
146+ }
41147
42- const int numRenderThreads = 3 ;
148+ args->infile = argv[i];
149+ }
150+ }
151+ }
152+
153+ int main (int argc, char **argv)
154+ {
155+ struct player_args args;
156+ parse_args (&args, argc, argv);
43157
44158 FILE * pFile;
45159 long lSize;
46160 unsigned char * buffer;
47161 size_t result;
48162
49- pFile = fopen (argv[1 ], " rb" );
50- if (pFile == NULL ) { printf (" File error\n " ); exit (1 ); }
163+ pFile = fopen (args.infile , " rb" );
164+ if (pFile == NULL ) {
165+ printf (" Can't open input file '%s'\n " , args.infile );
166+ exit (1 );
167+ }
51168
52169 // obtain file size:
53170 fseek (pFile, 0 , SEEK_END);
@@ -59,7 +176,10 @@ int main(int argc, char **argv)
59176
60177 // copy the file into the buffer:
61178 result = fread (buffer, 1 , lSize, pFile);
62- if (result != lSize) { printf (" Reading error\n " ); exit (3 ); }
179+ if (result != lSize) {
180+ printf (" Can't read from input file '%s'\n " , args.infile );
181+ exit (3 );
182+ }
63183
64184 // terminate
65185 fclose (pFile);
@@ -68,34 +188,41 @@ int main(int argc, char **argv)
68188 song.blob = buffer;
69189 song.factory = SongFactory;
70190
71- if (writeWav )
191+ if (args. wavwriter )
72192 {
73- WavWriter wavWriter (&song, numRenderThreads);
193+ FILE* outf = fopen (args.outfile , " wb" );
194+ if (!outf)
195+ {
196+ printf (" Can't open output file '%s'\n " , args.outfile );
197+ exit (4 );
198+ }
199+ fclose (outf); // close again because WavWriter wants a file path
200+
201+ WavWriter wavWriter (&song, args.nthreads );
74202
75203 printf (" WAV writer activated.\n " );
76204
77- auto fileName = argc >= 4 ? argv[3 ] : " out.wav" ;
78205 printf (" Rendering...\n " );
79- wavWriter.Write (fileName , progressCallback, nullptr );
206+ wavWriter.Write (args. outfile , progressCallback, nullptr );
80207
81- printf (" \n\n WAV file written to \" %s\" . Enjoy.\n " , fileName );
208+ printf (" \n\n WAV file written to \" %s\" . Enjoy.\n " , args. outfile );
82209 }
83210 else
84211 {
85212 IPlayer *player;
86213
87- if (preRender )
214+ if (args. prerender )
88215 {
89216 printf (" Prerender activated.\n " );
90217 printf (" Rendering...\n " );
91218
92- player = new PreRenderPlayer (&song, numRenderThreads , progressCallback, nullptr );
219+ player = new PreRenderPlayer (&song, args. nthreads , progressCallback, nullptr );
93220
94221 printf (" \n\n " );
95222 }
96223 else
97224 {
98- player = new RealtimePlayer (&song, numRenderThreads );
225+ player = new RealtimePlayer (&song, args. nthreads );
99226 }
100227
101228 printf (" Realtime player activated. Press ESC to quit.\n " );
@@ -108,7 +235,6 @@ int main(int argc, char **argv)
108235 int seconds = (int )songPos % 60 ;
109236 int hundredths = (int )(songPos * 100.0 ) % 100 ;
110237 printf (" \r %.1i:%.2i.%.2i" , minutes, seconds, hundredths);
111-
112238 Sleep (10 );
113239 }
114240 printf (" \n " );
@@ -118,4 +244,4 @@ int main(int argc, char **argv)
118244
119245 free (buffer);
120246 return 0 ;
121- }
247+ }
0 commit comments