shithub: sox

Download patch

ref: 32fe572b0053eb1cb694d945766a65de3278d7a2
parent: c153c657fd35a32588290fc5c9c51cd2fd882c57
author: Doug Cook <idigdoug@users.sourceforge.net>
date: Sat Mar 19 20:57:09 EDT 2011

sox should not depend on libsox configuration

The sox program currently uses soxconfig.h as the basis for some of its
runtime behavior. It should instead be less tightly coupled from libsox,
and should get runtime information about libsox by querying libsox.
This adds a new function, sox_version_info(), which reports information about
how libsox was compiled and what options it supports. sox now uses the data
from sox_version_info instead of using #ifdefs.

Also added variable sox_globals.use_threads. This is used instead of having
the client program call omp_set_num_threads. This decouples the underlying
threading implementation used by libsox from the threading implementation used
by the client, i.e. libsox links against OMP, but sox no longer needs to do so.

--- a/msvc10/.gitignore
+++ b/msvc10/.gitignore
@@ -1,7 +1,10 @@
 *.user
-Sox.suo
-Sox.ncb
-Sox.sdf
-Sox.opensdf
+Debug
+ipch
 Makefile
 Makefile.in
+Release
+Sox.ncb
+Sox.opensdf
+Sox.sdf
+Sox.suo
--- a/msvc10/SoX/soxconfig.h
+++ b/msvc10/SoX/soxconfig.h
@@ -18,7 +18,7 @@
 /* Used only by sox.c: */
 #define MORE_INTERACTIVE
 
-#define PACKAGE_VERSION "14.3.1-msvc"
+#define PACKAGE_EXTRA "msvc"
 
 /* Special behavior defined by win32-ltdl: "./" is replaced with the name of the
    directory containing sox.exe. */
--- a/msvc9/Sox/soxconfig.h
+++ b/msvc9/Sox/soxconfig.h
@@ -18,7 +18,7 @@
 /* Used only by sox.c: */
 #define MORE_INTERACTIVE
 
-#define PACKAGE_VERSION "14.3.1-msvc"
+#define PACKAGE_EXTRA "msvc"
 
 /* Special behavior defined by win32-ltdl: "./" is replaced with the name of the
    directory containing sox.exe. */
--- a/src/effects.c
+++ b/src/effects.c
@@ -223,29 +223,41 @@
         chain->ibufc[f][i / effp->flows] = *ibuf++;
 
 #ifdef HAVE_OPENMP
-    #pragma omp parallel for
-#endif
-    for (f = 0; f < (int)effp->flows; ++f) {
-      size_t idonec = idone / effp->flows;
-      size_t odonec = obeg / effp->flows;
-      int eff_status_c = effp->handler.flow(&chain->effects[n][f],
-          chain->ibufc[f], chain->obufc[f], &idonec, &odonec);
-#ifndef HAVE_OPENMP
-      if (f && (idonec != idone_last || odonec != odone_last)) {
-        lsx_fail("flowed asymmetrically!");
-        effstatus = SOX_EOF;
+    if (sox_globals.use_threads && effp->flows > 1)
+    {
+      #pragma omp parallel for
+      for (f = 0; f < (int)effp->flows; ++f) {
+        size_t idonec = idone / effp->flows;
+        size_t odonec = obeg / effp->flows;
+        int eff_status_c = effp->handler.flow(&chain->effects[n][f],
+            chain->ibufc[f], chain->obufc[f], &idonec, &odonec);
+        if (!f) {
+          idone_last = idonec;
+          odone_last = odonec;
+        }
+
+        if (eff_status_c != SOX_SUCCESS)
+          effstatus = SOX_EOF;
       }
-      idone_last = idonec;
-      odone_last = odonec;
-#else
-      if (!f) {
+    }
+    else /* sox_globals.use_threads */
+#endif
+    {
+      for (f = 0; f < (int)effp->flows; ++f) {
+        size_t idonec = idone / effp->flows;
+        size_t odonec = obeg / effp->flows;
+        int eff_status_c = effp->handler.flow(&chain->effects[n][f],
+            chain->ibufc[f], chain->obufc[f], &idonec, &odonec);
+        if (f && (idonec != idone_last || odonec != odone_last)) {
+          lsx_fail("flowed asymmetrically!");
+          effstatus = SOX_EOF;
+        }
         idone_last = idonec;
         odone_last = odonec;
-      }
-#endif
 
-      if (eff_status_c != SOX_SUCCESS)
-        effstatus = SOX_EOF;
+        if (eff_status_c != SOX_SUCCESS)
+          effstatus = SOX_EOF;
+      }
     }
 
     for (i = 0; i < odone_last; ++i)
--- a/src/libsox.c
+++ b/src/libsox.c
@@ -32,6 +32,79 @@
   return(versionstr);
 }
 
+sox_version_info_t const * sox_version_info(void)
+{
+#define STRINGIZE1(x) #x
+#define STRINGIZE(x) STRINGIZE1(x)
+    static char arch[30];
+    static sox_version_info_t info = {
+        /* size */
+        sizeof(sox_version_info_t),
+        /* flags */
+        (sox_version_flags_t)(
+#if HAVE_POPEN
+        sox_version_have_popen +
+#endif
+#if  HAVE_MAGIC
+        sox_version_have_magic +
+#endif
+#if HAVE_OPENMP
+        sox_version_have_threads +
+#endif
+        sox_version_none),
+        /* version_code */
+        SOX_LIB_VERSION_CODE,
+        /* version */
+        NULL,
+        /* sox_version_extra */
+#ifdef PACKAGE_EXTRA
+        PACKAGE_EXTRA,
+#else
+        NULL,
+#endif
+        /* sox_time */
+        __DATE__ " " __TIME__,
+        /* sox_distro */
+#ifdef DISTRO
+        DISTRO,
+#else
+        NULL,
+#endif
+        /* sox_compiler */
+#if defined __GNUC__
+        "gcc " __VERSION__,
+#elif defined _MSC_VER
+        "msvc " STRINGIZE(_MSC_FULL_VER),
+#elif defined __SUNPRO_C
+    fprintf(file, "sun c " STRINGIZE(__SUNPRO_C),
+#else
+        NULL,
+#endif
+        /* sox_arch */
+        NULL
+    };
+
+    if (!info.version)
+    {
+        info.version = sox_version();
+    }
+
+    if (!info.arch)
+    {
+        snprintf(arch, sizeof(arch), "%u%u%u%u %u%u %u%u %c %s",
+            (unsigned)sizeof(char), (unsigned)sizeof(short),
+            (unsigned)sizeof(long), (unsigned)sizeof(off_t),
+            (unsigned)sizeof(float), (unsigned)sizeof(double),
+            (unsigned)sizeof(int *), (unsigned)sizeof(int (*)(void)),
+            MACHINE_IS_BIGENDIAN ? 'B' : 'L',
+            (info.flags & sox_version_have_threads) ? "OMP" : "");
+        arch[sizeof(arch) - 1] = 0;
+        info.arch = arch;
+    }
+
+    return &info;
+}
+
 /* Default routine to output messages; can be overridden */
 static void output_message(
     unsigned level, const char *filename, const char *fmt, va_list ap)
@@ -53,7 +126,8 @@
   NULL,            /* char const * stdout_in_use_by */
   NULL,            /* char const * subsystem */
   NULL,            /* char       * tmp_path */
-  sox_false        /* sox_bool     use_magic */
+  sox_false,       /* sox_bool     use_magic */
+  sox_false        /* sox_bool     use_threads */
 };
 
 char const * sox_strerror(int sox_errno)
--- a/src/sox.c
+++ b/src/sox.c
@@ -21,7 +21,7 @@
  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include "soxomp.h"  /* Make this 1st in list (for soxconfig) */
+#include "soxconfig.h"
 #include "sox.h"
 #include "util.h"
 #include "sgetopt.h"
@@ -201,10 +201,6 @@
 static int success = 0;
 static sox_sample_t omax[2], omin[2];
 
-/* Multi-processing */
-
-static sox_bool single_threaded = sox_true;
-
 #ifdef HAVE_TERMIOS_H
 #include <termios.h>
 static struct termios original_termios;
@@ -1679,38 +1675,28 @@
 #if HAVE_SYS_UTSNAME_H
   struct utsname uts;
 #endif
+  const sox_version_info_t* info = sox_version_info();
 
-  fprintf(file, "%s: SoX v%s\n", myname, PACKAGE_VERSION);
+  fprintf(file, "%s:      SoX v%s%s%s\n",
+      myname,
+      info->version,
+      info->version_extra ? "-" : "",
+      info->version_extra ? info->version_extra : "");
 
   if (sox_globals.verbosity > 3) {
-    fprintf(file, "time:  %s %s\n", __DATE__, __TIME__);
-#if HAVE_DISTRO
-    fprintf(file, "issue: %s\n", DISTRO);
-#endif
+    if (info->time)
+      fprintf(file, "time:     %s\n", info->time);
+    if (info->distro)
+      fprintf(file, "issue:    %s\n", info->distro);
 #if HAVE_SYS_UTSNAME_H
     if (!uname(&uts))
-      fprintf(file, "uname: %s %s %s %s %s\n", uts.sysname, uts.nodename,
+      fprintf(file, "uname:    %s %s %s %s %s\n", uts.sysname, uts.nodename,
           uts.release, uts.version, uts.machine);
 #endif
-#if defined __GNUC__
-    fprintf(file, "gcc:   %s\n", __VERSION__);
-#elif defined _MSC_VER
-    fprintf(file, "msc:   %u\n", _MSC_VER);
-#elif defined __SUNPRO_C
-    fprintf(file, "sun c: %x\n", __SUNPRO_C);
-#endif
-    fprintf(file, "arch:  %lu%lu%lu%lu %lu%lu %lu%lu %c %s\n",
-        (unsigned long)sizeof(char), (unsigned long)sizeof(short),
-        (unsigned long)sizeof(long), (unsigned long)sizeof(off_t),
-        (unsigned long)sizeof(float), (unsigned long)sizeof(double),
-        (unsigned long)sizeof(int *), (unsigned long)sizeof(int (*)(void)),
-        "LB"[MACHINE_IS_BIGENDIAN],
-#ifdef HAVE_OPENMP
-        "OMP"
-#else
-        ""
-#endif
-        );
+    if (info->compiler)
+        fprintf(file, "compiler: %s\n", info->compiler);
+    if (info->arch)
+        fprintf(file, "arch:     %s\n", info->arch);
   }
 }
 
@@ -1777,18 +1763,21 @@
 
 static void usage(char const * message)
 {
+  const sox_version_info_t * info = sox_version_info();
   size_t i;
-  static char const * const lines[] = {
+  static char const * const lines1[] = {
 "SPECIAL FILENAMES (infile, outfile):",
 "-                        Pipe/redirect input/output (stdin/stdout); may need -t",
 "-d, --default-device     Use the default audio device (where available)",
 "-n, --null               Use the `null' file handler; e.g. with synth effect",
-"-p, --sox-pipe           Alias for `-t sox -'",
-#ifdef HAVE_POPEN
+"-p, --sox-pipe           Alias for `-t sox -'"
+  };
+  static char const * const linesPopen[] = {
 "\nSPECIAL FILENAMES (infile only):",
 "\"|program [options] ...\" Pipe input from external program (where supported)",
-"http://server/file       Use the given URL as input file (where supported)",
-#endif
+"http://server/file       Use the given URL as input file (where supported)"
+  };
+  static char const * const lines2[] = {
 "",
 "GLOBAL OPTIONS (gopts) (can be specified at any point before the first effect):",
 "--buffer BYTES           Set the size of all processing buffers (default 8192)",
@@ -1806,10 +1795,15 @@
 "--no-clobber             Prompt to overwrite output file",
 "-m, --combine mix        Mix multiple input files (instead of concatenating)",
 "--combine mix-power      Mix to equal power (instead of concatenating)",
-"-M, --combine merge      Merge multiple input files (instead of concatenating)",
-"--magic                  Use `magic' file-type detection",
-"--multi-threaded         Enable parallel effects channels processing (where",
-"                         available)",
+"-M, --combine merge      Merge multiple input files (instead of concatenating)"
+  };
+  static char const * const linesMagic[] = {
+"--magic                  Use `magic' file-type detection"
+  };
+  static char const * const linesThreads[] = {
+"--multi-threaded         Enable parallel effects channels processing"
+  };
+  static char const * const lines3[] = {
 "--norm                   Guard (see --guard) & normalise",
 "--play-rate-arg ARG      Default `rate' argument for auto-resample with `play'",
 "--plot gnuplot|octave    Generate script to plot response of filter effect",
@@ -1850,7 +1844,9 @@
 "--add-comment TEXT       Append output file comment",
 "--comment TEXT           Specify comment text for the output file",
 "--comment-file FILENAME  File containing comment text for the output file",
+#if HAVE_GLOB_H
 "--no-glob                Don't `glob' wildcard match the following filename",
+#endif
 ""};
 
   if (!(sox_globals.verbosity > 2)) {
@@ -1863,8 +1859,21 @@
 
   printf("Usage summary: [gopts] [[fopts] infile]... [fopts]%s [effect [effopt]]...\n\n",
          sox_mode == sox_play? "" : " outfile");
-  for (i = 0; i < array_length(lines); ++i)
-    puts(lines[i]);
+  for (i = 0; i < array_length(lines1); ++i)
+    puts(lines1[i]);
+  if (info->flags & sox_version_have_popen)
+    for (i = 0; i < array_length(linesPopen); ++i)
+      puts(linesPopen[i]);
+  for (i = 0; i < array_length(lines2); ++i)
+    puts(lines2[i]);
+  if (info->flags & sox_version_have_magic)
+    for (i = 0; i < array_length(linesMagic); ++i)
+      puts(linesMagic[i]);
+  if (info->flags & sox_version_have_threads)
+    for (i = 0; i < array_length(linesThreads); ++i)
+      puts(linesThreads[i]);
+  for (i = 0; i < array_length(lines3); ++i)
+    puts(lines3[i]);
   display_supported_formats();
   display_supported_effects();
   printf("EFFECT OPTIONS (effopts): effect dependent; see --help-effect\n");
@@ -2133,6 +2142,7 @@
 
 static char parse_gopts_and_fopts(file_t * f, int argc, char **argv)
 {
+  const sox_version_info_t* info = sox_version_info();
   while (sox_true) {
     int c, option_index;
     int i; /* sscanf silently accepts negative numbers for %u :( */
@@ -2203,18 +2213,19 @@
       case 14: break;
       case 15: effects_filename = strdup(lsx_optarg); break;
       case 16: sox_globals.tmp_path = strdup(lsx_optarg); break;
-      case 17: single_threaded = sox_true; break;
+      case 17: sox_globals.use_threads = sox_false; break;
       case 18: f->signal.length = SOX_IGNORE_LENGTH; break;
       case 19: do_guarded_norm = is_guarded = sox_true; break;
-#if HAVE_MAGIC
-      case 20: sox_globals.use_magic = sox_true; break;
-#else
-      case 20: lsx_warn("this build of SoX does not include `magic'"); break;
-#endif
+      case 20:
+        if (info->flags & sox_version_have_magic)
+          sox_globals.use_magic = sox_true;
+        else
+          lsx_warn("this build of SoX does not include `magic'");
+        break;
       case 21: play_rate_arg = strdup(lsx_optarg); break;
       case 22: no_clobber = sox_false; break;
       case 23: no_clobber = sox_true; break;
-      case 24: single_threaded = sox_false; break;
+      case 24: sox_globals.use_threads = sox_true; break;
       }
       break;
 
@@ -2728,11 +2739,6 @@
           sox_globals.tmp_path = ".";
     sox_globals.tmp_path = lsx_strdup(sox_globals.tmp_path);
   }
-#endif
-
-#ifdef HAVE_OPENMP
-  if (single_threaded)
-    omp_set_num_threads(1);
 #endif
 
   if (sox_globals.verbosity > 2)
--- a/src/sox.h
+++ b/src/sox.h
@@ -45,6 +45,28 @@
 
 const char *sox_version(void);   /* Returns version number */
 
+typedef enum { /* Flags indicating whether optional features are present in this build of SoX */
+    sox_version_none = 0,
+    sox_version_have_popen = 1,
+    sox_version_have_magic = 2,
+    sox_version_have_threads = 4
+} sox_version_flags_t;
+
+typedef struct { /* Information about this build of SoX */
+    unsigned     size;         /* sizeof(sox_version_info_t) */
+    sox_version_flags_t flags; /* feature flags */
+    unsigned     version_code; /* version number, SOX_LIB_VERSION_CODE i.e. 0x140400 */
+    const char * version;      /* version string, sox_version() i.e. "14.4.0" */
+    const char * version_extra;/* version info or null, PACKAGE_EXTRA i.e. "beta" */
+    const char * time;         /* build time, __DATE__ __TIME__ i.e. "Jan  7 2010 03:31:50" */
+    const char * distro;       /* distro or null, DISTRO i.e. Debian */
+    const char * compiler;     /* compiler info or null, i.e. msvc: 1500 */
+    const char * arch;         /* arch: 1248 48 44 L OMP */
+    /* new info should be added at the end for version backwards-compatibility. */
+} sox_version_info_t;
+
+sox_version_info_t const * sox_version_info(void); /* gets information about libsox */
+
 #define SOX_SUCCESS 0            /* Function succeeded (= 0) */
 #define SOX_EOF (-1)             /* End Of File or other error (= -1) */
 
@@ -192,6 +214,7 @@
   char const * subsystem;        /* tracks the name of the handler currently writing an output message */
   char       * tmp_path;         /* client-configured path to use for temporary files */
   sox_bool     use_magic;        /* true if client has requested use of 'magic' file-type detection */
+  sox_bool     use_threads;      /* true if client has requested parallel effects processing */
 } sox_globals_t;
 extern sox_globals_t sox_globals; /* the SoX global settings */