Skip to content

Commit aae62ee

Browse files
committed
cleaner/nicer to use command-line interface (+ help text) for the standalone player
1 parent 4d7493e commit aae62ee

File tree

1 file changed

+143
-17
lines changed

1 file changed

+143
-17
lines changed

WaveSabreStandAlonePlayer/main.cpp

Lines changed: 143 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,8 @@
22
#include <WaveSabrePlayerLib.h>
33
using namespace WaveSabrePlayerLib;
44

5+
#include <stdlib.h>
6+
#include <stdio.h>
57
#include <string.h>
68

79
WaveSabreCore::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+
"\tprerender prerender the song instead of rendering while playing.\n"
56+
"\twav 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+
"\tthreads the amount of threads to use in parallel for rendering. By\n"
60+
"\t default, this number is 3.\n"
61+
"\tinput.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\nWAV file written to \"%s\". Enjoy.\n", fileName);
208+
printf("\n\nWAV 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

Comments
 (0)