From bfcde9ae8ac4cd3ecdb128397eec2913ba90142d Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 26 Aug 2017 03:50:51 -0700 Subject: Allow specifying the output filename with bsincgen --- utils/bsincgen.c | 171 +++++++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 140 insertions(+), 31 deletions(-) (limited to 'utils') diff --git a/utils/bsincgen.c b/utils/bsincgen.c index 0064060f..ba0116cb 100644 --- a/utils/bsincgen.c +++ b/utils/bsincgen.c @@ -33,9 +33,66 @@ * accessed October 2012. */ +#define _UNICODE #include #include #include +#include + +#ifdef _WIN32 +#define WIN32_LEAN_AND_MEAN +#include + +static char *ToUTF8(const wchar_t *from) +{ + char *out = NULL; + int len; + if((len=WideCharToMultiByte(CP_UTF8, 0, from, -1, NULL, 0, NULL, NULL)) > 0) + { + out = calloc(sizeof(*out), len); + WideCharToMultiByte(CP_UTF8, 0, from, -1, out, len, NULL, NULL); + out[len-1] = 0; + } + return out; +} + +static WCHAR *FromUTF8(const char *str) +{ + WCHAR *out = NULL; + int len; + + if((len=MultiByteToWideChar(CP_UTF8, 0, str, -1, NULL, 0)) > 0) + { + out = calloc(sizeof(WCHAR), len); + MultiByteToWideChar(CP_UTF8, 0, str, -1, out, len); + out[len-1] = 0; + } + return out; +} + + +static FILE *my_fopen(const char *fname, const char *mode) +{ + WCHAR *wname=NULL, *wmode=NULL; + FILE *file = NULL; + + wname = FromUTF8(fname); + wmode = FromUTF8(mode); + if(!wname) + fprintf(stderr, "Failed to convert UTF-8 filename: \"%s\"\n", fname); + else if(!wmode) + fprintf(stderr, "Failed to convert UTF-8 mode: \"%s\"\n", mode); + else + file = _wfopen(wname, wmode); + + free(wname); + free(wmode); + + return file; +} +#define fopen my_fopen +#endif + #ifndef M_PI #define M_PI (3.14159265358979323846) @@ -128,7 +185,7 @@ static double CalcKaiserBeta(const double rejection) } /* Generates the coefficient, delta, and index tables required by the bsinc resampler */ -static void BsiGenerateTables(const char *tabname, const double rejection, const int order) +static void BsiGenerateTables(FILE *output, const char *tabname, const double rejection, const int order) { static double filter[BSINC_SCALE_COUNT][BSINC_PHASE_COUNT + 1][BSINC_POINTS_MAX]; static double scDeltas[BSINC_SCALE_COUNT][BSINC_PHASE_COUNT ][BSINC_POINTS_MAX]; @@ -239,7 +296,7 @@ static void BsiGenerateTables(const char *tabname, const double rejection, const for(si = 0; si < BSINC_SCALE_COUNT; si++) mt[si] = (mt[si]+3) & ~3; - fprintf(stdout, + fprintf(output, "/* This %d%s order filter has a rejection of -%.0fdB, yielding a transition width\n" " * of ~%.3f (normalized frequency). Order increases when downsampling to a\n" " * limit of one octave, after which the quality of the filter (transition\n" @@ -258,31 +315,31 @@ static void BsiGenerateTables(const char *tabname, const double rejection, const the signal. The limit in octaves can be calculated by taking the base-2 logarithm of its inverse: log_2(1 / scaleBase) */ - fprintf(stdout, " /* scaleBase */ %.9ef, /* scaleRange */ %.9ef,\n", scaleBase, 1.0 / scaleRange); + fprintf(output, " /* scaleBase */ %.9ef, /* scaleRange */ %.9ef,\n", scaleBase, 1.0 / scaleRange); - fprintf(stdout, " /* m */ {"); - fprintf(stdout, " %d", mt[0]); + fprintf(output, " /* m */ {"); + fprintf(output, " %d", mt[0]); for(si = 1; si < BSINC_SCALE_COUNT; si++) - fprintf(stdout, ", %d", mt[si]); - fprintf(stdout, " },\n"); + fprintf(output, ", %d", mt[si]); + fprintf(output, " },\n"); - fprintf(stdout, " /* filterOffset */ {"); - fprintf(stdout, " %d", 0); + fprintf(output, " /* filterOffset */ {"); + fprintf(output, " %d", 0); i = mt[0]*4*BSINC_PHASE_COUNT; for(si = 1; si < BSINC_SCALE_COUNT; si++) { - fprintf(stdout, ", %d", i); + fprintf(output, ", %d", i); i += mt[si]*4*BSINC_PHASE_COUNT; } - fprintf(stdout, " },\n"); + fprintf(output, " },\n"); // Calculate the table size. i = 0; for(si = 0; si < BSINC_SCALE_COUNT; si++) i += 4 * BSINC_PHASE_COUNT * mt[si]; - fprintf(stdout, "\n /* Tab (%d entries) */ {\n", i); + fprintf(output, "\n /* Tab (%d entries) */ {\n", i); for(si = 0; si < BSINC_SCALE_COUNT; si++) { const int m = mt[si]; @@ -290,23 +347,23 @@ static void BsiGenerateTables(const char *tabname, const double rejection, const for(pi = 0; pi < BSINC_PHASE_COUNT; pi++) { - fprintf(stdout, " /* %2d,%2d (%d) */", si, pi, m); - fprintf(stdout, "\n "); + fprintf(output, " /* %2d,%2d (%d) */", si, pi, m); + fprintf(output, "\n "); for(i = 0; i < m; i++) - fprintf(stdout, " %+14.9ef,", filter[si][pi][o + i]); - fprintf(stdout, "\n "); + fprintf(output, " %+14.9ef,", filter[si][pi][o + i]); + fprintf(output, "\n "); for(i = 0; i < m; i++) - fprintf(stdout, " %+14.9ef,", scDeltas[si][pi][o + i]); - fprintf(stdout, "\n "); + fprintf(output, " %+14.9ef,", scDeltas[si][pi][o + i]); + fprintf(output, "\n "); for(i = 0; i < m; i++) - fprintf(stdout, " %+14.9ef,", phDeltas[si][pi][o + i]); - fprintf(stdout, "\n "); + fprintf(output, " %+14.9ef,", phDeltas[si][pi][o + i]); + fprintf(output, "\n "); for(i = 0; i < m; i++) - fprintf(stdout, " %+14.9ef,", spDeltas[si][pi][o + i]); - fprintf(stdout, "\n"); + fprintf(output, " %+14.9ef,", spDeltas[si][pi][o + i]); + fprintf(output, "\n"); } } - fprintf(stdout, " }\n};\n\n"); + fprintf(output, " }\n};\n\n"); } @@ -319,7 +376,7 @@ static void BsiGenerateTables(const char *tabname, const double rejection, const #define FRACTIONBITS (12) #define FRACTIONONE (1< 2) + { + fprintf(stderr, "Usage: %s [output file]\n", argv[0]); + return 1; + } + + if(argc == 2) + { + output = fopen(argv[1], "rb"); + if(!output) + { + fprintf(stderr, "Failed to open %s for writing\n", argv[1]); + return 1; + } + } + else + output = stdout; + + fprintf(output, "/* Generated by bsincgen, do not edit! */\n\n" "typedef struct BSincTable {\n" " const float scaleBase, scaleRange;\n" " const int m[BSINC_SCALE_COUNT];\n" @@ -361,7 +465,12 @@ int main(void) " alignas(16) const float Tab[];\n" "} BSincTable;\n\n"); /* An 11th order filter with a -60dB drop at nyquist. */ - BsiGenerateTables("bsinc12", 60.0, 11); - Sinc4GenerateTables(60.0); + BsiGenerateTables(output, "bsinc12", 60.0, 11); + Sinc4GenerateTables(output, 60.0); + + if(output != stdout) + fclose(output); + output = NULL; + return 0; } -- cgit v1.2.3