Skip to content

Commit

Permalink
cleaner/nicer to use command-line interface (+ help text) for the sta…
Browse files Browse the repository at this point in the history
…ndalone player
  • Loading branch information
PoroCYon committed Sep 14, 2020
1 parent 4d7493e commit aae62ee
Showing 1 changed file with 143 additions and 17 deletions.
160 changes: 143 additions & 17 deletions WaveSabreStandAlonePlayer/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@
#include <WaveSabrePlayerLib.h>
using namespace WaveSabrePlayerLib;

#include <stdlib.h>
#include <stdio.h>
#include <string.h>

WaveSabreCore::Device *SongFactory(SongRenderer::DeviceId id)
Expand Down Expand Up @@ -34,20 +36,135 @@ void progressCallback(double progress, void *data)
printf("]");
}

int main(int argc, char **argv)
struct player_args
{
const char* infile;
const char* outfile;
int nthreads;
bool prerender;
bool wavwriter;
};

static void print_usage(const char* prgm)
{
printf("%s: WaveSabre standalone song player/renderer\n"
"Usage:\n"
"\t%s [-p|--prerender] [-w|--wav [out.wav]] [-t|--threads n] <input.bin>\n"
"\n"
"Arguments:\n"
"\tprerender prerender the song instead of rendering while playing.\n"
"\twav instead of playing back the song, write a WAV file. By default,\n"
"\t the output file is called `out.wav', but another may be supplied\n"
"\t immediately after this argument.\n"
"\tthreads the amount of threads to use in parallel for rendering. By\n"
"\t default, this number is 3.\n"
"\tinput.bin the input song file, exported by the WaveSabre exporter.\n"
, prgm, prgm);
}
static void parse_args(struct player_args* args, int argc, char** argv)
{
bool writeWav = argc >= 3 && !strcmp(argv[2], "-w");
bool preRender = argc == 3 && !strcmp(argv[2], "-p");
if (argc < 2)
{
print_usage(argv[0]);
exit(1);
}

args->infile = NULL;
args->outfile = NULL;
args->nthreads = 3;
args->prerender = false;
args->wavwriter = false;

for (int i = 1; i < argc; ++i)
{
if (argv[i][0] == '-')
{
const char* as = argv[i] + 1; // skip arg prefix char ('-')

if (!strcmp(as, "h") || !strcmp(as, "-help"))
{
print_usage(argv[0]);
exit(0);
}
// TODO: option for printing version info
if (!strcmp(as, "p") || !strcmp(as, "-prerender"))
{
args->prerender = true;
continue;
}
if (!strcmp(as, "w") || !strcmp(as, "-wav"))
{
args->wavwriter = true;

if (i+1 < argc && argv[i+1][0] != '-')
{
// last argument, and no input file set yet, so we really
// need to prioritise the input file here
if (argc-1 == i+1 && args->infile == NULL)
{
args->outfile = "out.wav";
}
else
{
args->outfile = argv[i+1];
++i;
}
}
else
{
args->outfile = "out.wav";
}
continue;
}
if (!strcmp(as, "t") || !strcmp(as, "-threads"))
{
if (i+1 == argc)
{
printf("Expecting thread amount\n");
exit(2);
}

++i;
int res = sscanf(argv[i], "%d", &args->nthreads);
if (res != 1 || args->nthreads < 0)
{
printf("Can't parse thread amount '%s'\n", argv[i]);
exit(2);
}

continue;
}

printf("Unrecognised option '%s', ignoring...\n", argv[i]);
}
else
{
if (args->infile != NULL)
{
printf("Unexpected argument '%s'\n", argv[i]);
exit(2);
}

const int numRenderThreads = 3;
args->infile = argv[i];
}
}
}

int main(int argc, char **argv)
{
struct player_args args;
parse_args(&args, argc, argv);

FILE * pFile;
long lSize;
unsigned char * buffer;
size_t result;

pFile = fopen(argv[1], "rb");
if (pFile == NULL) { printf("File error\n"); exit(1); }
pFile = fopen(args.infile, "rb");
if (pFile == NULL) {
printf("Can't open input file '%s'\n", args.infile);
exit(1);
}

// obtain file size:
fseek(pFile, 0, SEEK_END);
Expand All @@ -59,7 +176,10 @@ int main(int argc, char **argv)

// copy the file into the buffer:
result = fread(buffer, 1, lSize, pFile);
if (result != lSize) { printf("Reading error\n"); exit(3); }
if (result != lSize) {
printf("Can't read from input file '%s'\n", args.infile);
exit(3);
}

// terminate
fclose(pFile);
Expand All @@ -68,34 +188,41 @@ int main(int argc, char **argv)
song.blob = buffer;
song.factory = SongFactory;

if (writeWav)
if (args.wavwriter)
{
WavWriter wavWriter(&song, numRenderThreads);
FILE* outf = fopen(args.outfile, "wb");
if (!outf)
{
printf("Can't open output file '%s'\n", args.outfile);
exit(4);
}
fclose(outf); // close again because WavWriter wants a file path

WavWriter wavWriter(&song, args.nthreads);

printf("WAV writer activated.\n");

auto fileName = argc >= 4 ? argv[3] : "out.wav";
printf("Rendering...\n");
wavWriter.Write(fileName, progressCallback, nullptr);
wavWriter.Write(args.outfile, progressCallback, nullptr);

printf("\n\nWAV file written to \"%s\". Enjoy.\n", fileName);
printf("\n\nWAV file written to \"%s\". Enjoy.\n", args.outfile);
}
else
{
IPlayer *player;

if (preRender)
if (args.prerender)
{
printf("Prerender activated.\n");
printf("Rendering...\n");

player = new PreRenderPlayer(&song, numRenderThreads, progressCallback, nullptr);
player = new PreRenderPlayer(&song, args.nthreads, progressCallback, nullptr);

printf("\n\n");
}
else
{
player = new RealtimePlayer(&song, numRenderThreads);
player = new RealtimePlayer(&song, args.nthreads);
}

printf("Realtime player activated. Press ESC to quit.\n");
Expand All @@ -108,7 +235,6 @@ int main(int argc, char **argv)
int seconds = (int)songPos % 60;
int hundredths = (int)(songPos * 100.0) % 100;
printf("\r %.1i:%.2i.%.2i", minutes, seconds, hundredths);

Sleep(10);
}
printf("\n");
Expand All @@ -118,4 +244,4 @@ int main(int argc, char **argv)

free(buffer);
return 0;
}
}

0 comments on commit aae62ee

Please sign in to comment.