aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CMakeLists.txt5
-rw-r--r--config.h.in3
-rw-r--r--utils/getopt.c137
-rw-r--r--utils/getopt.h26
-rw-r--r--utils/makehrtf.c161
5 files changed, 260 insertions, 72 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 5adfac25..25d66d6b 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -652,6 +652,8 @@ int main()
ENDIF()
ENDIF()
+CHECK_SYMBOL_EXISTS(getopt unistd.h HAVE_GETOPT)
+
# Check for a 64-bit type
CHECK_INCLUDE_FILE(stdint.h HAVE_STDINT_H)
IF(NOT HAVE_STDINT_H)
@@ -1395,6 +1397,9 @@ IF(ALSOFT_UTILS)
TARGET_LINK_LIBRARIES(openal-info OpenAL)
ADD_EXECUTABLE(makehrtf utils/makehrtf.c)
+ IF(NOT HAVE_GETOPT)
+ SET_PROPERTY(TARGET makehrtf APPEND PROPERTY SOURCE utils/getopt.c)
+ ENDIF()
SET_PROPERTY(TARGET makehrtf APPEND PROPERTY COMPILE_FLAGS ${EXTRA_CFLAGS})
IF(HAVE_LIBM)
TARGET_LINK_LIBRARIES(makehrtf m)
diff --git a/config.h.in b/config.h.in
index 56a78448..824ea84f 100644
--- a/config.h.in
+++ b/config.h.in
@@ -20,6 +20,9 @@
/* Define if we have the _aligned_malloc function */
#cmakedefine HAVE__ALIGNED_MALLOC
+/* Define if we have the getopt function */
+#cmakedefine HAVE_GETOPT
+
/* Define if we have SSE CPU extensions */
#cmakedefine HAVE_SSE
#cmakedefine HAVE_SSE2
diff --git a/utils/getopt.c b/utils/getopt.c
new file mode 100644
index 00000000..ab1a246e
--- /dev/null
+++ b/utils/getopt.c
@@ -0,0 +1,137 @@
+/* $NetBSD: getopt.c,v 1.26 2003/08/07 16:43:40 agc Exp $ */
+
+/*
+ * Copyright (c) 1987, 1993, 1994
+ * The Regents of the University of California. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
+ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+ * SUCH DAMAGE.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)getopt.c 8.3 (Berkeley) 4/27/95";
+#endif /* LIBC_SCCS and not lint */
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include "getopt.h"
+
+int opterr = 1, /* if error message should be printed */
+ optind = 1, /* index into parent argv vector */
+ optopt, /* character checked for validity */
+ optreset; /* reset getopt */
+char *optarg; /* argument associated with option */
+
+#define BADCH (int)'?'
+#define BADARG (int)':'
+#define EMSG ""
+
+/*
+ * Get program name in Windows
+ */
+const char * _getprogname(void);
+
+/*
+ * getopt --
+ * Parse argc/argv argument vector.
+ */
+int
+getopt(int nargc, char * const nargv[], const char *ostr)
+{
+ static char *place = EMSG; /* option letter processing */
+ char *oli; /* option letter list index */
+
+ if (optreset || *place == 0) { /* update scanning pointer */
+ optreset = 0;
+ place = nargv[optind];
+ if (optind >= nargc || *place++ != '-') {
+ /* Argument is absent or is not an option */
+ place = EMSG;
+ return (-1);
+ }
+ optopt = *place++;
+ if (optopt == '-' && *place == 0) {
+ /* "--" => end of options */
+ ++optind;
+ place = EMSG;
+ return (-1);
+ }
+ if (optopt == 0) {
+ /* Solitary '-', treat as a '-' option
+ if the program (eg su) is looking for it. */
+ place = EMSG;
+ if (strchr(ostr, '-') == NULL)
+ return (-1);
+ optopt = '-';
+ }
+ } else
+ optopt = *place++;
+
+ /* See if option letter is one the caller wanted... */
+ if (optopt == ':' || (oli = strchr(ostr, optopt)) == NULL) {
+ if (*place == 0)
+ ++optind;
+ if (opterr && *ostr != ':')
+ (void)fprintf(stderr,
+ "%s: illegal option -- %c\n", _getprogname(),
+ optopt);
+ return (BADCH);
+ }
+
+ /* Does this option need an argument? */
+ if (oli[1] != ':') {
+ /* don't need argument */
+ optarg = NULL;
+ if (*place == 0)
+ ++optind;
+ } else {
+ /* Option-argument is either the rest of this argument or the
+ entire next argument. */
+ if (*place)
+ optarg = place;
+ else if (nargc > ++optind)
+ optarg = nargv[optind];
+ else {
+ /* option-argument absent */
+ place = EMSG;
+ if (*ostr == ':')
+ return (BADARG);
+ if (opterr)
+ (void)fprintf(stderr,
+ "%s: option requires an argument -- %c\n",
+ _getprogname(), optopt);
+ return (BADCH);
+ }
+ place = EMSG;
+ ++optind;
+ }
+ return (optopt); /* return option letter */
+}
+
+const char * _getprogname() {
+ char *pgmptr = NULL;
+ _get_pgmptr(&pgmptr);
+ return strrchr(pgmptr,'\\')+1;
+}
+
diff --git a/utils/getopt.h b/utils/getopt.h
new file mode 100644
index 00000000..f894d9d9
--- /dev/null
+++ b/utils/getopt.h
@@ -0,0 +1,26 @@
+#ifndef GETOPT_H
+#define GETOPT_H
+
+#ifndef _WIN32
+
+#include <unistd.h>
+
+#else /* _WIN32 */
+
+#ifdef __cplusplus
+extern "C" {
+#endif /* __cplusplus */
+
+extern char *optarg;
+extern int optind, opterr, optopt, optreset;
+
+int getopt(int nargc, char * const nargv[], const char *ostr);
+
+#ifdef __cplusplus
+}
+#endif /* __cplusplus */
+
+#endif /* !_WIN32 */
+
+#endif /* !GETOPT_H */
+
diff --git a/utils/makehrtf.c b/utils/makehrtf.c
index 344754e9..e7dd34c3 100644
--- a/utils/makehrtf.c
+++ b/utils/makehrtf.c
@@ -71,6 +71,11 @@
#ifdef HAVE_STRINGS_H
#include <strings.h>
#endif
+#ifdef HAVE_GETOPT
+#include <unistd.h>
+#else
+#include "getopt.h"
+#endif
// Rely (if naively) on OpenAL's header for the types used for serialization.
#include "AL/al.h"
@@ -2911,26 +2916,26 @@ static void PrintHelp(const char *argv0, FILE *ofile)
fprintf(ofile, " Defaults output to: ./oalsoft_hrtf_%%r.mhr\n");
fprintf(ofile, " -h, --help Displays this help information.\n\n");
fprintf(ofile, "Options:\n");
- fprintf(ofile, " -r=<rate> Change the data set sample rate to the specified value and\n");
+ fprintf(ofile, " -r <rate> Change the data set sample rate to the specified value and\n");
fprintf(ofile, " resample the HRIRs accordingly.\n");
- fprintf(ofile, " -f=<points> Override the FFT window size (default: %u).\n", DEFAULT_FFTSIZE);
- fprintf(ofile, " -e={on|off} Toggle diffuse-field equalization (default: %s).\n", (DEFAULT_EQUALIZE ? "on" : "off"));
- fprintf(ofile, " -s={on|off} Toggle surface-weighted diffuse-field average (default: %s).\n", (DEFAULT_SURFACE ? "on" : "off"));
- fprintf(ofile, " -l={<dB>|none} Specify a limit to the magnitude range of the diffuse-field\n");
+ fprintf(ofile, " -f <points> Override the FFT window size (default: %u).\n", DEFAULT_FFTSIZE);
+ fprintf(ofile, " -e {on|off} Toggle diffuse-field equalization (default: %s).\n", (DEFAULT_EQUALIZE ? "on" : "off"));
+ fprintf(ofile, " -s {on|off} Toggle surface-weighted diffuse-field average (default: %s).\n", (DEFAULT_SURFACE ? "on" : "off"));
+ fprintf(ofile, " -l {<dB>|none} Specify a limit to the magnitude range of the diffuse-field\n");
fprintf(ofile, " average (default: %.2f).\n", DEFAULT_LIMIT);
- fprintf(ofile, " -w=<points> Specify the size of the truncation window that's applied\n");
+ fprintf(ofile, " -w <points> Specify the size of the truncation window that's applied\n");
fprintf(ofile, " after minimum-phase reconstruction (default: %u).\n", DEFAULT_TRUNCSIZE);
- fprintf(ofile, " -d={dataset| Specify the model used for calculating the head-delay timing\n");
+ fprintf(ofile, " -d {dataset| Specify the model used for calculating the head-delay timing\n");
fprintf(ofile, " sphere} values (default: %s).\n", ((DEFAULT_HEAD_MODEL == HM_DATASET) ? "dataset" : "sphere"));
- fprintf(ofile, " -c=<size> Use a customized head radius measured ear-to-ear in meters.\n");
- fprintf(ofile, " -i=<filename> Specify an HRIR definition file to use (defaults to stdin).\n");
- fprintf(ofile, " -o=<filename> Specify an output file. Overrides command-selected default.\n");
+ fprintf(ofile, " -c <size> Use a customized head radius measured ear-to-ear in meters.\n");
+ fprintf(ofile, " -i <filename> Specify an HRIR definition file to use (defaults to stdin).\n");
+ fprintf(ofile, " -o <filename> Specify an output file. Overrides command-selected default.\n");
fprintf(ofile, " Use of '%%r' will be substituted with the data set sample rate.\n");
}
#ifdef _WIN32
#define main my_main
-int main(int argc, const char *argv[]);
+int main(int argc, char *argv[]);
static char **arglist;
static void cleanup_arglist(void)
@@ -2950,12 +2955,12 @@ int wmain(int argc, const wchar_t *wargv[])
for(i = 0;i < argc;i++)
arglist[i] = ToUTF8(wargv[i]);
- return main(argc, (const char**)arglist);
+ return main(argc, arglist);
}
#endif
// Standard command line dispatch.
-int main(int argc, const char *argv[])
+int main(int argc, char *argv[])
{
const char *inName = NULL, *outName = NULL;
OutputFormatT outFormat;
@@ -2967,13 +2972,13 @@ int main(int argc, const char *argv[])
uint truncSize;
double radius;
double limit;
- int argi;
+ int opt;
if(argc < 2 || strcmp(argv[1], "--help") == 0 || strcmp(argv[1], "-h") == 0)
{
fprintf(stdout, "HRTF Processing and Composition Utility\n\n");
PrintHelp(argv[0], stdout);
- return 0;
+ exit(EXIT_SUCCESS);
}
if(strcmp(argv[1], "--make-mhr") == 0 || strcmp(argv[1], "-m") == 0)
@@ -2985,7 +2990,7 @@ int main(int argc, const char *argv[])
{
fprintf(stderr, "Error: Invalid command '%s'.\n\n", argv[1]);
PrintHelp(argv[0], stderr);
- return -1;
+ exit(EXIT_FAILURE);
}
outRate = 0;
@@ -2998,112 +3003,124 @@ int main(int argc, const char *argv[])
radius = DEFAULT_CUSTOM_RADIUS;
experimental = 0;
- argi = 2;
- while(argi < argc)
+ optind = 2;
+ while((opt=getopt(argc, argv, "r:f:e:s:k:w:d:c:e:i:o:xh")) != -1)
{
- if(strncmp(argv[argi], "-r=", 3) == 0)
+ switch(opt)
{
- outRate = strtoul(&argv[argi][3], &end, 10);
+ case 'r':
+ outRate = strtoul(optarg, &end, 10);
if(end[0] != '\0' || outRate < MIN_RATE || outRate > MAX_RATE)
{
fprintf(stderr, "Error: Expected a value from %u to %u for '-r'.\n", MIN_RATE, MAX_RATE);
- return -1;
+ exit(EXIT_FAILURE);
}
- }
- else if(strncmp(argv[argi], "-f=", 3) == 0)
- {
- fftSize = strtoul(&argv[argi][3], &end, 10);
+ break;
+
+ case 'f':
+ fftSize = strtoul(optarg, &end, 10);
if(end[0] != '\0' || (fftSize&(fftSize-1)) || fftSize < MIN_FFTSIZE || fftSize > MAX_FFTSIZE)
{
fprintf(stderr, "Error: Expected a power-of-two value from %u to %u for '-f'.\n", MIN_FFTSIZE, MAX_FFTSIZE);
- return -1;
+ exit(EXIT_FAILURE);
}
- }
- else if(strncmp(argv[argi], "-e=", 3) == 0)
- {
- if(strcmp(&argv[argi][3], "on") == 0)
+ break;
+
+ case 'e':
+ if(strcmp(optarg, "on") == 0)
equalize = 1;
- else if(strcmp(&argv[argi][3], "off") == 0)
+ else if(strcmp(optarg, "off") == 0)
equalize = 0;
else
{
fprintf(stderr, "Error: Expected 'on' or 'off' for '-e'.\n");
- return -1;
+ exit(EXIT_FAILURE);
}
- }
- else if(strncmp(argv[argi], "-s=", 3) == 0)
- {
- if(strcmp(&argv[argi][3], "on") == 0)
+ break;
+
+ case 's':
+ if(strcmp(optarg, "on") == 0)
surface = 1;
- else if(strcmp(&argv[argi][3], "off") == 0)
+ else if(strcmp(optarg, "off") == 0)
surface = 0;
else
{
fprintf(stderr, "Error: Expected 'on' or 'off' for '-s'.\n");
- return -1;
+ exit(EXIT_FAILURE);
}
- }
- else if(strncmp(argv[argi], "-l=", 3) == 0)
- {
- if(strcmp(&argv[argi][3], "none") == 0)
+ break;
+
+ case 'l':
+ if(strcmp(optarg, "none") == 0)
limit = 0.0;
else
{
- limit = strtod(&argv[argi] [3], &end);
+ limit = strtod(optarg, &end);
if(end[0] != '\0' || limit < MIN_LIMIT || limit > MAX_LIMIT)
{
fprintf(stderr, "Error: Expected 'none' or a value from %.2f to %.2f for '-l'.\n", MIN_LIMIT, MAX_LIMIT);
- return -1;
+ exit(EXIT_FAILURE);
}
}
- }
- else if(strncmp(argv[argi], "-w=", 3) == 0)
- {
- truncSize = strtoul(&argv[argi][3], &end, 10);
+ break;
+
+ case 'w':
+ truncSize = strtoul(optarg, &end, 10);
if(end[0] != '\0' || truncSize < MIN_TRUNCSIZE || truncSize > MAX_TRUNCSIZE || (truncSize%MOD_TRUNCSIZE))
{
fprintf(stderr, "Error: Expected a value from %u to %u in multiples of %u for '-w'.\n", MIN_TRUNCSIZE, MAX_TRUNCSIZE, MOD_TRUNCSIZE);
- return -1;
+ exit(EXIT_FAILURE);
}
- }
- else if(strncmp(argv[argi], "-d=", 3) == 0)
- {
- if(strcmp(&argv[argi][3], "dataset") == 0)
+ break;
+
+ case 'd':
+ if(strcmp(optarg, "dataset") == 0)
model = HM_DATASET;
- else if(strcmp(&argv[argi][3], "sphere") == 0)
+ else if(strcmp(optarg, "sphere") == 0)
model = HM_SPHERE;
else
{
fprintf(stderr, "Error: Expected 'dataset' or 'sphere' for '-d'.\n");
- return -1;
+ exit(EXIT_FAILURE);
}
- }
- else if(strncmp(argv[argi], "-c=", 3) == 0)
- {
- radius = strtod(&argv[argi][3], &end);
+ break;
+
+ case 'c':
+ radius = strtod(optarg, &end);
if(end[0] != '\0' || radius < MIN_CUSTOM_RADIUS || radius > MAX_CUSTOM_RADIUS)
{
fprintf(stderr, "Error: Expected a value from %.2f to %.2f for '-c'.\n", MIN_CUSTOM_RADIUS, MAX_CUSTOM_RADIUS);
- return -1;
+ exit(EXIT_FAILURE);
}
- }
- else if(strncmp(argv[argi], "-i=", 3) == 0)
- inName = &argv[argi][3];
- else if(strncmp(argv[argi], "-o=", 3) == 0)
- outName = &argv[argi][3];
- else if(strcmp(argv[argi], "--experimental") == 0)
+ break;
+
+ case 'i':
+ inName = optarg;
+ break;
+
+ case 'o':
+ outName = optarg;
+ break;
+
+ case 'x':
experimental = 1;
- else
- {
- fprintf(stderr, "Error: Invalid option '%s'.\n", argv[argi]);
- return -1;
+ break;
+
+ case 'h':
+ PrintHelp(argv[0], stdout);
+ exit(EXIT_SUCCESS);
+
+ default: /* '?' */
+ PrintHelp(argv[0], stderr);
+ exit(EXIT_FAILURE);
}
- argi++;
}
+
if(!ProcessDefinition(inName, outRate, fftSize, equalize, surface, limit,
truncSize, model, radius, outFormat, experimental,
outName))
return -1;
fprintf(stdout, "Operation completed.\n");
- return 0;
+
+ return EXIT_SUCCESS;
}