[SCM] libsoxr/upstream: Imported Upstream version 0.1.2

bdrung at users.alioth.debian.org bdrung at users.alioth.debian.org
Thu Sep 24 18:53:10 UTC 2015


The following commit has been merged in the upstream branch:
commit 65342b1ee5ab2cb1983dc3e58046762eec459863
Author: Benjamin Drung <bdrung at debian.org>
Date:   Tue Sep 22 20:48:23 2015 +0200

    Imported Upstream version 0.1.2

diff --git a/CMakeLists.txt b/CMakeLists.txt
index 8a24952..406e826 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -12,7 +12,7 @@ set (DESCRIPTION_SUMMARY "High quality, one-dimensional sample-rate conversion l
 
 set (PROJECT_VERSION_MAJOR 0)
 set (PROJECT_VERSION_MINOR 1)
-set (PROJECT_VERSION_PATCH 1)
+set (PROJECT_VERSION_PATCH 2)
 
 # For shared-object; if, since the last public release:
 #  * library code changed at all: ++revision
@@ -21,7 +21,7 @@ set (PROJECT_VERSION_PATCH 1)
 #  * interfaces removed:          age = 0
 
 set (SO_VERSION_CURRENT  1)
-set (SO_VERSION_REVISION 0)
+set (SO_VERSION_REVISION 1)
 set (SO_VERSION_AGE      1)
 
 
@@ -75,10 +75,11 @@ endif ()
 
 if (WITH_OPENMP)
   find_package (OpenMP)
-endif ()
-if (OPENMP_FOUND)
-  set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
-  set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
+  if (OPENMP_FOUND)
+    set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${OpenMP_C_FLAGS}")
+    set (CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} ${OpenMP_EXE_LINKER_FLAGS}")
+    set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} ${OpenMP_SHARED_LINKER_FLAGS}")
+  endif ()
 endif ()
 
 if (WITH_SIMD)
diff --git a/NEWS b/NEWS
index 64f8ffa..f388974 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,16 @@
+Version 0.1.2 (2015-09-05)
+  * Fix conversion failure when I/O types differ but I/O rates don't.
+  * Fix #defines for interpolation order selection.
+  * Fix ineffectual SOXR_MINIMUM_PHASE and SOXR_INTERMEDIATE_PHASE in
+    soxr_quality_spec recipe.
+  * Fix soxr_delay() returning a negative number after end-of-input has been
+    indicated.
+  * Fix crash when using soxr_process() after calling soxr_clear().
+  * Be more POSIX compliant w.r.t. errno in the examples; fixes erroneous
+    reporting of errors on FreeBSD.
+  * Quality improvement for variable-rate.
+  * Various fixes/improvements to build/tests/documentation.
+
 Version 0.1.1 (2013-03-03)
   * Minor fixes/improvements to build/tests.
   * Fix crash (e.g. with k3b) when null error pointer passed to src_create (lsr
diff --git a/README b/README
index 1f9921d..06f11e6 100644
--- a/README
+++ b/README
@@ -8,8 +8,8 @@ should look elsewhere.
 It aims to give fast¹ and very high quality² results for any constant
 (rational or irrational) resampling ratio.  Phase-response, preserved
 bandwidth, aliasing, and rejection level parameters are all configurable;
-alternatively, simple `preset' configurations may be selected.  An
-experimental, variable-rate resampling mode of operation is also included.
+alternatively, simple `preset' configurations may be selected.  A
+variable-rate resampling mode of operation is also included.
 
 The resampler is currently available either as part of `libsox' (the audio
 file-format and effect library), or stand-alone as `libsoxr' (this package).
diff --git a/cmake/Modules/FindOpenMP.cmake b/cmake/Modules/FindOpenMP.cmake
index 654dc30..eef8422 100644
--- a/cmake/Modules/FindOpenMP.cmake
+++ b/cmake/Modules/FindOpenMP.cmake
@@ -9,7 +9,9 @@
 #
 # Supported compilers can be found at http://openmp.org/wp/openmp-compilers/
 #
-# Modified for libsoxr not to rely on presence of C++ compiler.
+# Modifications for soxr:
+#   * don't rely on presence of C++ compiler
+#   * support MINGW
 #
 #=============================================================================
 # Copyright 2009 Kitware, Inc.
@@ -103,6 +105,11 @@ set (OpenMP_C_FLAGS "${OpenMP_C_FLAGS_INTERNAL}"
 
 # handle the standard arguments for find_package
 find_package_handle_standard_args (OpenMP DEFAULT_MSG
-  OpenMP_C_FLAGS OpenMP_C_FLAGS)
+  OpenMP_C_FLAGS)
 
-mark_as_advanced (OpenMP_C_FLAGS)
+if (MINGW)
+  set (OpenMP_SHARED_LINKER_FLAGS "${OpenMP_SHARED_LINKER_FLAGS} ${OpenMP_C_FLAGS}")
+  set (OpenMP_EXE_LINKER_FLAGS "${OpenMP_EXE_LINKER_FLAGS} ${OpenMP_C_FLAGS}")
+endif ()
+
+mark_as_advanced (OpenMP_C_FLAGS OpenMP_SHARED_LINKER_FLAGS OpenMP_EXE_LINKER_FLAGS)
diff --git a/cmake/Modules/FindSIMD.cmake b/cmake/Modules/FindSIMD.cmake
index 6484bbd..6ac51cb 100644
--- a/cmake/Modules/FindSIMD.cmake
+++ b/cmake/Modules/FindSIMD.cmake
@@ -40,12 +40,18 @@
 include (CheckCSourceCompiles)
 include (FindPackageHandleStandardArgs)
 
+if (WIN32) # Safety for when mixed lib/app compilers (but performance hit)
+  set (GCC_WIN32_SIMD_OPTS "-mincoming-stack-boundary=2")
+endif ()
+
 set (SIMD_C_FLAG_CANDIDATES
-  # Microsoft Visual Studio x64
+  # x64
   " "
   # Microsoft Visual Studio x86
   "/arch:SSE /fp:fast -D__SSE__"
-  # Gnu
+  # Gcc x86
+  "-msse -mfpmath=sse ${GCC_WIN32_SIMD_OPTS}"
+  # Gcc x86 (old versions)
   "-msse -mfpmath=sse"
 )
 
diff --git a/examples/2-stream.C b/examples/2-stream.C
index 9d703f6..29c1bf6 100644
--- a/examples/2-stream.C
+++ b/examples/2-stream.C
@@ -72,7 +72,7 @@ int main(int argc, char const * arg[])
   soxr_delete(soxr);
   free(obuf), free(ibuf);
                                                               /* Diagnostics: */
-  fprintf(stderr, "%-26s %s; I/O: %s\n", arg[0],
-      soxr_strerror(error), errno? strerror(errno) : "no error");
-  return error || errno;
+  fprintf(stderr, "%-26s %s; I/O: %s\n", arg[0], soxr_strerror(error),
+      ferror(stdin) || ferror(stdout)? strerror(errno) : "no error");
+  return !!error;
 }
diff --git a/examples/3-options-input-fn.c b/examples/3-options-input-fn.c
index bb0bf2d..38fbb0d 100644
--- a/examples/3-options-input-fn.c
+++ b/examples/3-options-input-fn.c
@@ -47,16 +47,17 @@ int main(int n, char const * arg[])
   double          const orate = n? --n, atof(*arg++) : 44100.;
   unsigned        const chans = n? --n, (unsigned)atoi(*arg++) : 1;
   soxr_datatype_t const itype = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
-  soxr_datatype_t const otype = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
+  unsigned        const ospec = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
   unsigned long const q_recipe= n? --n, strtoul(*arg++, 0, 16) : SOXR_HQ;
   unsigned long const q_flags = n? --n, strtoul(*arg++, 0, 16) : 0;
   double   const passband_end = n? --n, atof(*arg++) : 0;
   double const stopband_begin = n? --n, atof(*arg++) : 0;
   double const phase_response = n? --n, atof(*arg++) : -1;
   int       const use_threads = n? --n, atoi(*arg++) : 1;
+  soxr_datatype_t const otype = ospec & 3;
 
   soxr_quality_spec_t       q_spec = soxr_quality_spec(q_recipe, q_flags);
-  soxr_io_spec_t      const io_spec = soxr_io_spec(itype, otype);
+  soxr_io_spec_t            io_spec = soxr_io_spec(itype, otype);
   soxr_runtime_spec_t const runtime_spec = soxr_runtime_spec(!use_threads);
 
   /* Allocate resampling input and output buffers in proportion to the input
@@ -79,6 +80,7 @@ int main(int n, char const * arg[])
   if (passband_end   > 0) q_spec.passband_end   = passband_end / 100;
   if (stopband_begin > 0) q_spec.stopband_begin = stopband_begin / 100;
   if (phase_response >=0) q_spec.phase_response = phase_response;
+  io_spec.flags = ospec & ~7u;
 
   /* Create a stream resampler: */
   soxr = soxr_create(
@@ -104,7 +106,8 @@ int main(int n, char const * arg[])
   soxr_delete(soxr);
   free(obuf), free(ibuf);
                                                               /* Diagnostics: */
-  fprintf(stderr, "%-26s %s; %lu clips; I/O: %s\n", arg0, soxr_strerror(error),
-      (long unsigned)clips, errno? strerror(errno) : "no error");
-  return error || errno;
+  fprintf(stderr, "%-26s %s; %lu clips; I/O: %s\n",
+      arg0, soxr_strerror(error), (long unsigned)clips,
+      ferror(stdin) || ferror(stdout)? strerror(errno) : "no error");
+  return !!error;
 }
diff --git a/examples/4-split-channels.c b/examples/4-split-channels.c
index a441598..d6448aa 100644
--- a/examples/4-split-channels.c
+++ b/examples/4-split-channels.c
@@ -141,7 +141,8 @@ int main(int n, char const * arg[])
   free(obuf), free(ibuf), free(obufs), free(ibufs);
   free(obuf_ptrs), free(ibuf_ptrs);
                                                               /* Diagnostics: */
-  fprintf(stderr, "%-26s %s; %lu clips; I/O: %s\n", arg0, soxr_strerror(error),
-      (long unsigned)clips, errno? strerror(errno) : "no error");
-  return error || errno;
+  fprintf(stderr, "%-26s %s; %lu clips; I/O: %s\n",
+      arg0, soxr_strerror(error), (long unsigned)clips,
+      ferror(stdin) || ferror(stdout)? strerror(errno) : "no error");
+  return !!error;
 }
diff --git a/examples/5-variable-rate.c b/examples/5-variable-rate.c
index a2496c9..1a1c63f 100644
--- a/examples/5-variable-rate.c
+++ b/examples/5-variable-rate.c
@@ -1,11 +1,10 @@
 /* SoX Resampler Library      Copyright (c) 2007-13 robs at users.sourceforge.net
  * Licence for this file: LGPL v2.1                  See LICENCE for details. */
 
-/* Example 5:  Variable-rate resampling (N.B. experimental).  A test signal
- * (held in a buffer) is resampled over a wide range of octaves.  Resampled
- * data is sent to stdout as raw, float32 samples.  Choices of 2 test-signals
- * and of 2 ways of varying the sample-rate are combined in a command-line
- * option:
+/* Example 5:  Variable-rate resampling.  A test signal (held in a buffer) is
+ * resampled over a wide range of octaves.  Resampled data is sent to stdout as
+ * raw, float32 samples.  Choices of 2 test-signals and of 2 ways of varying
+ * the sample-rate are combined in a command-line option:
  *
  * Usage: ./5-variable-rate [0|1|2|3]
  */
@@ -30,7 +29,7 @@ int main(int argc, char *arg[])
   int opt = argc <= 1? 2 : (atoi(arg[1]) & 3), saw = opt & 1, fm = opt & 2;
   float ibuf[10 << OCTAVES], obuf[AL(ibuf)];
   int i, wl = 2 << OCTAVES;
-  size_t ilen = AL(ibuf), need_input = 1;
+  size_t ilen = AL(ibuf), need_input = 1, written;
   size_t odone, total_odone, total_olen = OLEN * FS;
   size_t olen1 = fm? 10 : AL(obuf); /* Small block-len if fast-changing ratio */
   soxr_error_t error;
@@ -70,7 +69,7 @@ int main(int argc, char *arg[])
       do {
         size_t len = need_input? ilen : 0;
         error = soxr_process(soxr, ibuf, len, NULL, obuf, block_len, &odone);
-        fwrite(obuf, sizeof(float), odone, stdout);
+        written = fwrite(obuf, sizeof(float), odone, stdout);
 
         /* Update counters for the current block and for the total length: */
         block_len -= odone;
@@ -80,7 +79,7 @@ int main(int argc, char *arg[])
          * again, supplying more input samples: */
         need_input = block_len != 0;
 
-      } while (need_input && !error);
+      } while (need_input && !error && written == odone);
 
       /* Now that the block for the current ioratio is complete, go back
        * round the main `for' loop in order to process the next block. */
@@ -88,7 +87,7 @@ int main(int argc, char *arg[])
     soxr_delete(soxr);
   }
                                                               /* Diagnostics: */
-  fprintf(stderr, "%-26s %s; I/O: %s\n", arg[0],
-      soxr_strerror(error), errno? strerror(errno) : "no error");
-  return error || errno;
+  fprintf(stderr, "%-26s %s; I/O: %s\n", arg[0], soxr_strerror(error),
+      ferror(stdin) || ferror(stdout)? strerror(errno) : "no error");
+  return !!error;
 }
diff --git a/go b/go
index 30adb94..10f3ceb 100755
--- a/go
+++ b/go
@@ -12,6 +12,6 @@ rm -f CMakeCache.txt             # Prevent interference from any in-tree build
 mkdir -p $build
 cd $build
 
-cmake -DCMAKE_BUILD_TYPE=$build .. &&
+cmake -DCMAKE_BUILD_TYPE=$build -Wno-dev .. &&
   make $j &&
     (ctest $j || echo "FAILURE details in $build/Testing/Temporary/LastTest.log")
diff --git a/go.bat b/go.bat
index 7d63de3..c73d4c2 100644
--- a/go.bat
+++ b/go.bat
@@ -11,7 +11,7 @@ del/f CMakeCache.txt
 mkdir %build%
 cd %build%
 
-cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=%build% ..
+cmake -G "NMake Makefiles" -DCMAKE_BUILD_TYPE=%build% -Wno-dev ..
 if errorlevel 1 goto end
 
 nmake
diff --git a/inst-check-soxr b/inst-check-soxr
index 418f65b..5f923b8 100755
--- a/inst-check-soxr
+++ b/inst-check-soxr
@@ -20,7 +20,7 @@ build_examples() {
   if [ x"$arg" = x ]; then
     echo "Examples in `pwd`; using local headers:" # for when dev pkg not installed
     libs=-l$1
-    cflags=-I$dir/src 
+    cflags=-I$dir/src
   else
     echo "Examples in `pwd`; using pkg-config:"
     libs=$(pkg-config --libs $1)
@@ -29,7 +29,7 @@ build_examples() {
   for f in ?$2-*.[cC]; do
     cc=cc; echo $f | grep -q C$ && cc=c++
     out=$tmp/`echo $f | sed "s/.[cC]$//"`
-    cmd="$cc $cflags -o $out $f $libs"
+    cmd="$cc $cflags -o $out $f $libs -lm"
     echo $cmd; $cmd
   done
 }
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 2a21156..56756bf 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -1,6 +1,21 @@
 # SoX Resampler Library       Copyright (c) 2007-13 robs at users.sourceforge.net
 # Licence for this file: LGPL v2.1                  See LICENCE for details.
 
+
+
+# Can generate vr-coefs.h but it complicates cross-compiling & non-cmake builds
+
+if (NOT EXISTS ${CMAKE_CURRENT_SOURCE_DIR}/vr-coefs.h)
+  include_directories(${CMAKE_CURRENT_BINARY_DIR})
+  set_property(SOURCE vr32.c APPEND PROPERTY OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/vr-coefs.h)
+  add_executable (vr-coefs vr-coefs.c)
+  ADD_CUSTOM_COMMAND(OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/vr-coefs.h
+    COMMAND vr-coefs > ${CMAKE_CURRENT_BINARY_DIR}/vr-coefs.h
+    DEPENDS vr-coefs)
+endif ()
+
+
+
 add_definitions (${PROJECT_C_FLAGS} -DSOXR_LIB)
 
 
diff --git a/src/rate.h b/src/rate.h
index 81cabff..f6d055a 100644
--- a/src/rate.h
+++ b/src/rate.h
@@ -1,4 +1,4 @@
-/* SoX Resampler Library      Copyright (c) 2007-13 robs at users.sourceforge.net
+/* SoX Resampler Library      Copyright (c) 2007-14 robs at users.sourceforge.net
  * Licence for this file: LGPL v2.1                  See LICENCE for details. */
 
 #include <math.h>
@@ -447,7 +447,7 @@ static char const * rate_init(
 
   p->num_stages = shift + have_pre_stage + have_arb_stage + have_post_stage;
   if (!p->num_stages && multiplier != 1) {
-    arbL = 0;
+    bits = arbL = 0;                         /* Use cubic_stage in this case. */
     ++p->num_stages;
   }
   p->stages = calloc((size_t)p->num_stages + 1, sizeof(*p->stages));
@@ -483,7 +483,7 @@ static char const * rate_init(
         log2_min_dft_size, log2_large_dft_size);
   }
 
-  if (!bits && have_arb_stage) {                /* Quick and dirty arb stage: */
+  if (!bits && have_arb_stage) {                  /* `Quick' cubic arb stage: */
     arb_stage.type = cubic_stage;
     arb_stage.fn = cubic_stage_fn;
     arb_stage.mult = multiplier, multiplier = 1;
@@ -621,17 +621,19 @@ static void rate_flush(rate_t * p)
   uint64_t samples_out = (uint64_t)((double)p->samples_in / p->factor + .5);
 #endif
   size_t remaining = (size_t)(samples_out - p->samples_out);
-  sample_t * buff = calloc(1024, sizeof(*buff));
 
-  if (samples_out > p->samples_out) {
+  if ((size_t)fifo_occupancy(fifo) < remaining) {
+    uint64_t samples_in = p->samples_in;
+    sample_t * buff = calloc(1024, sizeof(*buff));
+
     while ((size_t)fifo_occupancy(fifo) < remaining) {
       rate_input(p, buff, 1024);
       rate_process(p);
     }
     fifo_trim_to(fifo, (int)remaining);
-    p->samples_in = 0;
+    p->samples_in = samples_in;
+    free(buff);
   }
-  free(buff);
 }
 
 static void rate_close(rate_t * p)
@@ -663,10 +665,10 @@ static double rate_delay(rate_t * p)
 {
 #if defined _MSC_VER && _MSC_VER == 1200
   double samples_out = (double)(int64_t)p->samples_in / p->factor;
-  return samples_out - (double)(int64_t)p->samples_out;
+  return max(0, samples_out - (double)(int64_t)p->samples_out);
 #else
   double samples_out = (double)p->samples_in / p->factor;
-  return samples_out - (double)p->samples_out;
+  return max(0, samples_out - (double)p->samples_out);
 #endif
 }
 
diff --git a/src/rint-clip.h b/src/rint-clip.h
index a501cec..06764a8 100644
--- a/src/rint-clip.h
+++ b/src/rint-clip.h
@@ -61,7 +61,7 @@ static size_t LSX_RINT_CLIP(void * * const dest0, FLOATX const * const src,
   for (i = 0; i < (n & ~7u);) {
     COPY_SEED1;
     DITHER_VARS;
-    _ _ _ _ _ _ _ _ 0;
+    _ _ _ _ _ _ _ _ (void)0;
     if (fe_test_invalid()) {
       fe_clear_invalid();
       RINT_CLIP(dest, src, 1, i - 8, i, &clips PASS_SEED1);
@@ -74,11 +74,11 @@ static size_t LSX_RINT_CLIP(void * * const dest0, FLOATX const * const src,
   double d;
   for (i = 0; i < (n & ~7u);) {
     DITHER_VARS;
-    _ _ _ _ _ _ _ _ 0;
+    _ _ _ _ _ _ _ _ (void)0;
   }
   {
     DITHER_VARS;
-    for (; i < n; _ 0);
+    for (; i < n; _ (void)0);
   }
 #endif
   SAVE_SEED;
@@ -104,7 +104,7 @@ static size_t LSX_RINT_CLIP_2(void * * dest0, FLOATX const * const * srcs,
     for (i = 0; i < (n & ~7u);) {
       COPY_SEED1;
       DITHER_VARS;
-      _ _ _ _ _ _ _ _ 0;
+      _ _ _ _ _ _ _ _ (void)0;
       if (fe_test_invalid()) {
         fe_clear_invalid();
         RINT_CLIP(dest, src, stride, i - 8, i, &clips PASS_SEED1);
@@ -120,11 +120,11 @@ static size_t LSX_RINT_CLIP_2(void * * dest0, FLOATX const * const * srcs,
     FLOATX const * const src = srcs[j];
     for (i = 0; i < (n & ~7u);) {
       DITHER_VARS;
-      _ _ _ _ _ _ _ _ 0;
+      _ _ _ _ _ _ _ _ (void)0;
     }
     {
       DITHER_VARS;
-      for (; i < n; _ 0);
+      for (; i < n; _ (void)0);
     }
   }
 #endif
diff --git a/src/soxr.c b/src/soxr.c
index 93dd9c1..dc61ad9 100644
--- a/src/soxr.c
+++ b/src/soxr.c
@@ -67,6 +67,8 @@ struct soxr {
 
 
 
+#define RESET_ON_CLEAR   (1u<<31)
+
 /* TODO: these should not be here. */
 #define TO_3dB(a)       ((1.6e-6*a-7.5e-4)*a+.646)
 #define LOW_Q_BW0       (1385 / 2048.) /* 0.67625 rounded to be a FP exact. */
@@ -81,11 +83,12 @@ soxr_quality_spec_t soxr_quality_spec(unsigned long recipe, unsigned long flags)
     p->e = "invalid quality type";
     return spec;
   }
+  flags |= quality < SOXR_LSR0Q? RESET_ON_CLEAR : 0;
   if (quality == 13)
     quality = 6;
   else if (quality > 10)
     quality = 0;
-  p->phase_response = "\62\31\144"[(recipe & 0x30)>>8];
+  p->phase_response = "\62\31\144"[(recipe & 0x30) >> 4];
   p->stopband_begin = 1;
   p->precision = !quality? 0: quality < 3? 16 : quality < 8? 4 + quality * 4 : 55 - quality * 4;
   rej = p->precision * linear_to_dB(2.);
@@ -406,7 +409,8 @@ soxr_error_t soxr_clear(soxr_t p) /* TODO: this, properly. */
     memcpy(p->control_block, tmp.control_block, sizeof(p->control_block));
     p->deinterleave = tmp.deinterleave;
     p->interleave = tmp.interleave;
-    return 0;
+    return (p->q_spec.flags & RESET_ON_CLEAR)?
+      soxr_set_io_ratio(p, tmp.io_ratio, 0) : 0;
   }
   return "invalid soxr_t pointer";
 }
diff --git a/src/soxr.h b/src/soxr.h
index d878bb8..8d9622d 100644
--- a/src/soxr.h
+++ b/src/soxr.h
@@ -63,9 +63,10 @@ input or output (e.g. ilen, olen).                                            */
 /* --------------------------- Version management --------------------------- */
 
 /* E.g. #if SOXR_THIS_VERSION >= SOXR_VERSION(0,1,1) ...                      */
+
 #define SOXR_VERSION(x,y,z)     (((x)<<16)|((y)<<8)|(z))
-#define SOXR_THIS_VERSION       SOXR_VERSION(0,1,1)
-#define SOXR_THIS_VERSION_STR               "0.1.1"
+#define SOXR_THIS_VERSION       SOXR_VERSION(0,1,2)
+#define SOXR_THIS_VERSION_STR               "0.1.2"
 
 
 
@@ -105,7 +106,11 @@ SOXR soxr_t soxr_create(
     soxr_error_t *,              /* To report any error during creation. */
     soxr_io_spec_t const *,      /* To specify non-default I/O formats. */
     soxr_quality_spec_t const *, /* To specify non-default resampling quality.*/
-    soxr_runtime_spec_t const *);/* To specify non-default runtime resources. */
+    soxr_runtime_spec_t const *);/* To specify non-default runtime resources.
+
+    Default io_spec      is per soxr_io_spec(SOXR_FLOAT32_I, SOXR_FLOAT32_I)
+    Default quality_spec is per soxr_quality_spec(SOXR_HQ, 0)
+    Default runtime_spec is per soxr_runtime_spec(1)                          */
 
 
 
@@ -176,7 +181,9 @@ SOXR void         soxr_delete(soxr_t);  /* Free resources. */
 
 
 /* `Short-cut', single call to resample a (probably short) signal held entirely
- * in memory.  See soxr_create and soxr_process above for parameter details. */
+ * in memory.  See soxr_create and soxr_process above for parameter details.
+ * Note that unlike soxr_create however, the default quality spec. for
+ * soxr_oneshot is per soxr_quality_spec(SOXR_LQ, 0). */
 
 SOXR soxr_error_t soxr_oneshot(
     double         input_rate,
@@ -190,8 +197,8 @@ SOXR soxr_error_t soxr_oneshot(
 
 
 
-/* For variable-rate resampling (experimental). See example # 5 for how to
- * create a variable-rate resampler and how to use this function. */
+/* For variable-rate resampling. See example # 5 for how to create a
+ * variable-rate resampler and how to use this function. */
 
 SOXR soxr_error_t soxr_set_io_ratio(soxr_t, double io_ratio, size_t slew_len);
 
@@ -245,7 +252,7 @@ struct soxr_quality_spec {                                       /* Typically */
 #define SOXR_MAINTAIN_3DB_PT   4u  /* Reserved for internal use. */
 #define SOXR_HI_PREC_CLOCK     8u  /* Increase `irrational' ratio accuracy. */
 #define SOXR_DOUBLE_PRECISION 16u  /* Use D.P. calcs even if precision <= 20. */
-#define SOXR_VR               32u  /* Experimental, variable-rate resampling. */
+#define SOXR_VR               32u  /* Variable-rate resampling. */
 
 
 
@@ -259,8 +266,8 @@ struct soxr_runtime_spec {                                       /* Typically */
 };
                                    /* For `irrational' ratios only: */
 #define SOXR_COEF_INTERP_AUTO  0u    /* Auto select coef. interpolation. */
-#define SOXR_COEF_INTERP_LOW   1u    /* Man. select: less CPU, more memory. */
-#define SOXR_COEF_INTERP_HIGH  2u    /* Man. select: more CPU, less memory. */
+#define SOXR_COEF_INTERP_LOW   2u    /* Man. select: less CPU, more memory. */
+#define SOXR_COEF_INTERP_HIGH  3u    /* Man. select: more CPU, less memory. */
 
 #define SOXR_STRICT_BUFFERING  4u  /* Reserved for future use. */
 #define SOXR_NOSMALLINTOPT     8u  /* For test purposes only. */
@@ -313,7 +320,19 @@ SOXR soxr_io_spec_t soxr_io_spec(
 
 
 
-/* --------------------------- Internal use only ---------------------------- */
+/* --------------------------- Advanced use only ---------------------------- */
+
+/* For new designs, the following functions/usage will probably not be needed.
+ * They might be useful when adding soxr into an existing design where values
+ * for the resampling-rate and/or number-of-channels parameters to soxr_create
+ * are not available when that function will be called.  In such cases, the
+ * relevant soxr_create parameter(s) can be given as 0, then one or both of the
+ * following (as appropriate) later invoked (but prior to calling soxr_process
+ * or soxr_output):
+ *
+ * soxr_set_error(soxr, soxr_set_io_ratio(soxr, io_ratio, 0));
+ * soxr_set_error(soxr, soxr_set_num_channels(soxr, num_channels));
+ */
 
 SOXR soxr_error_t soxr_set_error(soxr_t, soxr_error_t);
 SOXR soxr_error_t soxr_set_num_channels(soxr_t, unsigned);
diff --git a/src/vr-coefs.c b/src/vr-coefs.c
new file mode 100644
index 0000000..14886df
--- /dev/null
+++ b/src/vr-coefs.c
@@ -0,0 +1,112 @@
+/* SoX Resampler Library         Copyright (c) 2013 robs at users.sourceforge.net
+ * Licence for this file: LGPL v2.1                  See LICENCE for details. */
+
+/* Generate the filter coefficients for variable-rate resampling. */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#define PI 3.14159265358979323846            /* Since M_PI can't be relied on */
+
+static void print(double * h, int m, double l, char const * name)
+{                                                      /* Print out a filter: */
+  int i, N = l? (int)(l*m)-(l>1) : m, R=(N+1)/2;
+  int a = !l||l>1? 0:N-R, b = l>1? R:N;
+  printf("static float const %s[] = {\n", name);
+  if (l>1) printf(" 0.f,"); else if (!l) l=1;
+  for (i=a; h && i<b; ++i, printf("% .9gf,%c",l*h[i-1],"\n "[(i-a)&3 && i<b]));
+  puts("};\n");
+  free(h);
+}
+                                                  /* Parks McClellan FIR LPF: */
+#define even_adj(f) ((N&1)? 1 : cos(PI*.5*(f)))
+#define W(f) (((f) < Fp+1e-9? weight : 1) * even_adj(f))      /* Weighting fn */
+#define D(f) (((f) < Fp+1e-9) / even_adj(f))           /* Desired response fn */
+#define F(i) ((i) <= end[0]? (i)*inc[0] : 1-(end[1]-(i))*inc[1])
+#define EE(x,z) (_1 != x 1 && x E[i] > 0 && x E[i] >= x E[i z 1])
+#define PEAK do {if (k<NP+1) peak[k]=i; ++k,_1=(E[i]>0)-(E[i]<0);} while (0)
+
+typedef struct {double x, beta, gamma;} coef_t;
+
+static double amp_response(coef_t * coef, int R, double f, int i)
+{
+  double n = 0, d = 0, x = cos(PI*f), t;
+  for (; i < R; d += t = coef[i].beta / t, n += coef[i].gamma * t, ++i)
+    if (fabs(t = x - coef[i].x) < 1e-9) return coef[i].gamma;
+  return n/d;
+}
+
+static void fir(int m, double l, double Fp0, double Fs0,
+    double weight0, int density, char const * name)
+{
+  double Fp=Fp0/l, Fs=Fs0/l, weight=1/weight0, inc[2], Ws=1-Fs;
+  int N = (int)(l*m)-(l>1), R=(N+1)/2, NP=R+1, grid_size=1+density*R+1, pass=0;
+  int n1 = Ws>=(2*R-1)*Fp? 1:(int)(R*Fp/(Fp+Ws)+.5), n2=NP-n1, _1, i, j, k;
+  int    * peak = calloc(sizeof(*peak), (size_t)(NP+1)), * P=peak, end[2];
+  coef_t * coef = calloc(sizeof(*coef), (size_t)(NP));
+  float  * E    = calloc(sizeof(*E   ), (size_t)(grid_size));
+  double d, n, e, f, mult, delta, sum, hi, lo, * A = (double*)E, *h=0;
+
+  if (!P || !coef || !E) goto END;
+  end[0] = n1 * density, end[1] = grid_size-1;     /* Create prototype peaks: */
+  inc[0] = Fp/end[0],    inc[1] = n2==1? 0 : Ws / ((n2-1)*density);
+  for (i=0; i<n1; P[n1-1-i] = end[0] - i*density,++i);
+  for (i=0; i<n2; P[n1+i] = 1+end[0] + i*density,++i);
+
+  do {                                               /* Coefs for amp. resp.: */
+    for (i = 0; i<NP; coef[i].x = cos(PI*F(P[i])), ++i);
+    for (_1=-1, n=d=i=0; i < NP; ++i) {
+      for (mult = 1, j = 0; j < R; ++j) if (j != i) mult *= coef[i].x-coef[j].x;
+      if (mult) coef[i].beta = 1/mult; else goto END;
+      if (i != R) mult *= coef[i].x - coef[R].x;
+      f = F(P[i]), n += D(f)/mult, d += (_1=-_1)/(W(f)*mult);
+    }
+    for (delta = n/d, _1 = -1, i = 0; i < R; ++i)
+      f = F(P[i]), coef[i].gamma = D(f)-(_1=-_1)*delta/W(f);
+    for (i = 0; i <= end[1]; ++i)            /* Amplitude response and error: */
+      f = F(i), E[i] = (float)(W(f)*(D(f) - amp_response(coef, R, f, 0)));
+
+    i = k = _1 = 0;                                        /* Find new peaks: */
+    if (end[0]) if (EE(+,+) || EE(-,+)) PEAK;                       /* At F=0 */
+    for (++i, j = 0; j < 2; ++j) {                              /* In band j: */
+      for (; i < end[j]; ++i)
+        if ((EE(+,-) && E[i]>E[i+1]) || (EE(-,-) && E[i]<E[i+1])) PEAK;
+      if (!j) {PEAK; ++i; PEAK; ++i;}                           /* At Fp & Fs */
+    }
+    if (i==end[1]) if (EE(+,-) || EE(-,-)) PEAK;                    /* At F=1 */
+    if ((unsigned)(k = k-NP) > 1) goto END;                  /* Too many/few? */
+    P = peak + k * (fabs(E[peak[0]]) < fabs(E[peak[NP]]));         /* rm 1st? */
+
+    for (lo = hi = fabs(E[P[0]]), i=1; i<NP; ++i)              /* Converged?: */
+      e = fabs(E[P[i]]), lo = e<lo? e:lo, hi = e>hi? e:hi;
+  } while ((hi-lo)/hi > .001 && ++pass < 20);
+                      /* Create impulse response from final amp. resp. coefs: */
+  if (!(h = malloc(sizeof(*h)*(size_t)N))) goto END;
+  for (i = 0; i < R; f = 2.*i/N, A[i++] = amp_response(coef,R,f,0)*even_adj(f));
+  for (i = 0; i < R; h[N-1-i] = h[i] = sum/N, ++i)
+    for (sum=*A, j=1; j<R; sum += 2*cos(2*PI*(i-(N-1)/2.)/N*j)*A[j], ++j);
+  END: free(coef), free(E), free(peak);
+  print(h, m, l, name);
+}
+                                  /* Half-band IIR LPF (Mitra DSP 3/e, 13_9): */
+static void iir(int N, double Fp, char const * name)
+{
+  double d=tan(PI*.5*Fp), r=d*d, t=sqrt(1-r*r), n=(1-sqrt(t))/(1+sqrt(t))*.5;
+  double x=(n*n)*(n*n), Q=(((150*x+15)*x+2)*x+1)*n, q=pow(Q,.25), *h;
+  int i=0, j, _1;
+  if (!(h = malloc(sizeof(*h)*(size_t)N))) goto END;
+  for (; i<N; t=n*q/d, t=t*t, t=sqrt((1-t*r)*(1-t/r))/(1+t), h[i++]=(1-t)/(1+t))
+    for (_1=1, d=-.5, n=j=0, x=(i+1)*PI/(N+.5); j<7; ++j, _1=-_1)
+      n += _1*pow(Q,j*(j+1))*sin(x*(j+.5)), d += _1*pow(Q,j*j)*cos(x*j);
+  END: print(h, N, 0, name);
+}
+
+int main(int argc, char **argv)
+{
+  fir(241,  1, .45,  .5, 160, 32, "half_fir_coefs");
+  fir( 24, .5, .25,  .5,   1, 31, "fast_half_fir_coefs");
+  fir( 20, 12, .9 , 1.5, 160, 58, "coefs0_d");
+  fir( 12,  6, .45, 1.5,  80, 29, "coefs0_u");
+  iir( 15, .492, "iir_coefs");
+  return 0*argc*!argv;
+}
diff --git a/src/vr-coefs.h b/src/vr-coefs.h
new file mode 100644
index 0000000..9790ec0
--- /dev/null
+++ b/src/vr-coefs.h
@@ -0,0 +1,91 @@
+static float const half_fir_coefs[] = {
+ 0.471112154f,  0.316907549f,  0.0286963396f, -0.101927032f,
+-0.0281272982f,  0.0568029535f,  0.027196876f, -0.0360795942f,
+-0.0259313561f,  0.023641162f,  0.0243660538f, -0.0151238564f,
+-0.0225440668f,  0.00886927471f,  0.0205146088f, -0.00411434209f,
+-0.0183312132f,  0.000458525335f,  0.0160497772f,  0.00233248286f,
+-0.0137265989f, -0.0044106884f,  0.011416442f,  0.005885487f,
+-0.00917074467f, -0.00684373006f,  0.00703601669f,  0.00736018933f,
+-0.00505250698f, -0.00750298261f,  0.00325317131f,  0.00733618346f,
+-0.00166298445f, -0.00692082025f,  0.000298598848f,  0.00631493711f,
+ 0.000831644129f, -0.0055731438f, -0.00172737872f,  0.00474591812f,
+ 0.0023955814f, -0.0038788491f, -0.00284969263f,  0.00301194082f,
+ 0.00310854264f, -0.00217906496f, -0.00319514679f,  0.00140761062f,
+ 0.00313542959f, -0.000718361916f, -0.00295694328f,  0.000125607323f,
+ 0.00268763625f,  0.000362527878f, -0.00235472525f, -0.000743552559f,
+ 0.00198371228f,  0.00101991741f, -0.0015975797f, -0.00119820218f,
+ 0.00121618271f,  0.0012882279f, -0.000855849209f, -0.00130214036f,
+ 0.000529184474f,  0.00125350876f, -0.000245067778f, -0.00115647977f,
+ 8.82118676e-06f,  0.00102502052f,  0.000177478031f, -0.000872275256f,
+-0.000314572995f,  0.000710055602f,  0.000405526007f, -0.000548470439f,
+-0.000455174442f,  0.000395698685f,  0.000469579667f, -0.000257895884f,
+-0.000455495078f,  0.000139222702f,  0.000419883982f, -4.19753541e-05f,
+-0.00036950051f, -3.32020844e-05f,  0.000310554015f,  8.7050045e-05f,
+-0.000248456595f, -0.000121389974f,  0.000187662656f,  0.000138813233f,
+-0.000131587954f, -0.000142374865f,  8.26090549e-05f,  0.000135318039f,
+-4.21208043e-05f, -0.000120830917f,  1.06505085e-05f,  0.00010185819f,
+ 1.20015129e-05f, -8.09558888e-05f, -2.65925299e-05f,  6.02101571e-05f,
+ 3.42775752e-05f, -4.11911155e-05f, -3.64462477e-05f,  2.49654252e-05f,
+ 3.46090513e-05f, -1.21078107e-05f, -3.03027209e-05f,  2.73562006e-06f,
+ 2.51329043e-05f,  3.66157998e-06f, -2.0990973e-05f, -9.38752332e-06f,
+ 2.07133365e-05f,  3.2060847e-05f,  1.98462364e-05f,  4.90328648e-06f,
+-5.28550107e-07f,
+};
+
+static float const fast_half_fir_coefs[] = {
+ 0.309418476f, -0.0819805418f,  0.0305513441f, -0.0101582224f,
+ 0.00251293175f, -0.000346895324f,
+};
+
+static float const coefs0_d[] = {
+ 0.f, 1.40520362e-05f,  2.32939994e-05f,  4.00699869e-05f,  6.18938797e-05f,
+ 8.79406317e-05f,  0.000116304226f,  0.000143862785f,  0.000166286173f,
+ 0.000178229431f,  0.00017374107f,  0.00014689118f,  9.25928444e-05f,
+ 7.55567388e-06f, -0.000108723934f, -0.000253061416f, -0.000417917952f,
+-0.000591117466f, -0.000756082504f, -0.000892686881f, -0.000978762367f,
+-0.000992225841f, -0.00091370246f, -0.000729430325f, -0.000434153678f,
+-3.36489703e-05f,  0.000453499646f,  0.000995243588f,  0.00154683724f,
+ 0.00205322353f,  0.00245307376f,  0.0026843294f,  0.0026908874f,
+ 0.00242986868f,  0.00187874742f,  0.00104150259f, -4.70759945e-05f,
+-0.00131972748f, -0.00267834298f, -0.00399923407f, -0.00514205849f,
+-0.00596200535f, -0.00632441105f, -0.00612058374f, -0.00528328869f,
+-0.00380015804f, -0.0017232609f,  0.000826765169f,  0.0036632503f,
+ 0.00654337507f,  0.00918536843f,  0.0112922007f,  0.0125801323f,
+ 0.0128097433f,  0.0118164904f,  0.00953750551f,  0.00603133188f,
+ 0.00148762708f, -0.00377544588f, -0.009327395f, -0.014655127f,
+-0.0192047839f, -0.0224328082f, -0.0238620596f, -0.0231377935f,
+-0.0200777417f, -0.0147104883f, -0.00729690011f,  0.0016694689f,
+ 0.0114853672f,  0.02128446f,  0.0301054204f,  0.03697694f,
+ 0.0410129138f,  0.0415093321f,  0.0380333749f,  0.0304950299f,
+ 0.0191923285f,  0.00482304203f, -0.0115416941f, -0.0285230397f,
+-0.0445368533f, -0.0579264573f, -0.0671158215f, -0.070770308f,
+-0.0679502076f, -0.0582416438f, -0.0418501969f, -0.0196448429f,
+ 0.00685658762f,  0.0355644891f,  0.0639556622f,  0.0892653703f,
+ 0.108720484f,  0.11979613f,  0.120474745f,  0.109484562f,
+ 0.0864946948f,  0.0522461633f,  0.00860233712f, -0.041491734f,
+-0.0941444939f, -0.144742955f, -0.188255118f, -0.219589829f,
+-0.233988169f, -0.227416437f, -0.196929062f, -0.140970726f,
+-0.0595905561f,  0.0454527813f,  0.170708227f,  0.311175511f,
+ 0.460568159f,  0.61168037f,  0.756833088f,  0.888367707f,
+ 0.999151395f,  1.08305644f,  1.13537741f,  1.15315438f,
+};
+
+static float const coefs0_u[] = {
+ 0.f, 2.4378013e-05f,  9.70782157e-05f,  0.000256572953f,  0.000527352928f,
+ 0.000890796838f,  0.00124949518f,  0.00140604793f,  0.00107945998f,
+-2.15586031e-05f, -0.00206589462f, -0.00493342625f, -0.00807135101f,
+-0.0104515787f, -0.0107039866f, -0.00746258988f,  0.000109078838f,
+ 0.0117345872f,  0.0255795186f,  0.0381690155f,  0.0448461522f,
+ 0.0408218138f,  0.0226797758f, -0.00999595371f, -0.0533441602f,
+-0.0987927774f, -0.133827418f, -0.144042973f, -0.116198269f,
+-0.0416493482f,  0.0806808506f,  0.242643854f,  0.427127981f,
+ 0.610413245f,  0.766259257f,  0.8708884f,  0.907742029f,
+};
+
+static float const iir_coefs[] = {
+ 0.0262852045f,  0.0998310478f,  0.206865061f,  0.330224134f,
+ 0.454420362f,  0.568578357f,  0.666944466f,  0.747869771f,
+ 0.812324404f,  0.8626001f,  0.901427744f,  0.931486057f,
+ 0.955191529f,  0.974661783f,  0.991776305f,
+};
+
diff --git a/src/vr32.c b/src/vr32.c
index f804db5..65eed3f 100644
--- a/src/vr32.c
+++ b/src/vr32.c
@@ -1,7 +1,7 @@
 /* SoX Resampler Library      Copyright (c) 2007-13 robs at users.sourceforge.net
  * Licence for this file: LGPL v2.1                  See LICENCE for details. */
 
-/* Experimental variable-rate resampling. */
+/* Variable-rate resampling. */
 
 #include <assert.h>
 #include <math.h>
@@ -17,11 +17,11 @@
 #define FIFO_SIZE_T int
 #define FIFO_MIN 0x8000
 #include "fifo.h"
+#include "vr-coefs.h"
 
 #define FADE_LEN_BITS     9
-#define PHASE_BITS_D      (8 + PHASE_MORE)
-#define PHASE_BITS_U      (7 + PHASE_MORE)
-#define PHASE_MORE        0 /* 2 improves small int, and large u, ratios. */
+#define PHASE_BITS_D      10
+#define PHASE_BITS_U      9
 
 #define PHASES0_D         12
 #define POLY_FIR_LEN_D    20
@@ -32,50 +32,6 @@
 #define PHASES_D          (1 << PHASE_BITS_D)
 #define PHASES_U          (1 << PHASE_BITS_U)
 
-static float const half_fir_coefs[] = {
-  4.7111692735253413e-1f, 3.1690797657656167e-1f, 2.8691667164678896e-2f,
-  -1.0192825848403946e-1f, -2.8122856237424654e-2f, 5.6804928137780292e-2f,
-  2.7192768359197508e-2f, -3.6082309197154230e-2f, -2.5927789156038026e-2f,
-  2.3644444384060669e-2f, 2.4363075319345607e-2f, -1.5127630198606428e-2f,
-  -2.2541790286342567e-2f, 8.8733836742880233e-3f, 2.0513077413933017e-2f,
-  -4.1186431656279818e-3f, -1.8330444480421631e-2f, 4.6288071358217028e-4f,
-  1.6049769308921290e-2f, 2.3282106680446069e-3f, -1.3727327353082214e-2f,
-  -4.4066375505196096e-3f, 1.1417847550661287e-2f, 5.8817724081355978e-3f,
-  -9.1727580349157123e-3f, -6.8404638339394346e-3f, 7.0385357033205332e-3f,
-  7.3574525331962567e-3f, -5.0554197628506353e-3f, -7.5008330890673153e-3f,
-  3.2563575907277676e-3f, 7.3346538206330259e-3f, -1.6663208501478607e-3f,
-  -6.9199171108861694e-3f, 3.0196567996023190e-4f, 6.3146436955438768e-3f,
-  8.2835711466756098e-4f, -5.5734271982033918e-3f, -1.7242765658561860e-3f,
-  4.7467223803576682e-3f, 2.3927523666941205e-3f, -3.8801054688632139e-3f,
-  -2.8472115748114728e-3f, 3.0135659731132642e-3f, 3.1064651802365259e-3f,
-  -2.1809660142807748e-3f, -3.1935061143485862e-3f, 1.4096923923208671e-3f,
-  3.1342382222281609e-3f, -7.2053095076414931e-4f, -2.9561940489039682e-3f,
-  1.2777585046118889e-4f, 2.6873033434313882e-3f, 3.6043554054680685e-4f,
-  -2.3547716396561816e-3f, -7.4160208709749312e-4f, 1.9840894915230177e-3f,
-  1.0181606831615856e-3f, -1.5982325266851590e-3f, -1.1966774804490967e-3f,
-  1.2170528733224913e-3f, 1.2869618709883193e-3f, -8.5687504489877664e-4f,
-  -1.3011452950496001e-3f, 5.3030588389885972e-4f, 1.2527854026453923e-3f,
-  -2.4622758430821288e-4f, -1.1560181289625195e-3f, 9.9661643910782316e-6f,
-  1.0247989665318426e-3f, 1.7639297561664703e-4f, -8.7226452073196350e-4f,
-  -3.1358436147401782e-4f, 7.1022054657665971e-4f, 4.0466151692224986e-4f,
-  -5.4877022848030636e-4f, -4.5444807961399138e-4f, 3.9609542800868769e-4f,
-  4.6899779918507020e-4f, -2.5835154936239735e-4f, -4.5505391611721792e-4f,
-  1.3970512544147175e-4f, 4.1957352577882777e-4f, -4.2458993694471047e-5f,
-  -3.6930861782460262e-4f, -3.2738549063278822e-5f, 3.1046609224355927e-4f,
-  8.6624679037202785e-5f, -2.4845427128026068e-4f, -1.2101300074995281e-4f,
-  1.8773208187021294e-4f, 1.3849844077872591e-4f, -1.3170611080827864e-4f,
-  -1.4212373327156217e-4f, 8.2758595879431528e-5f, 1.3513059684140468e-4f,
-  -4.2284127775471251e-5f, -1.2070298779675768e-4f, 1.0811692847491609e-5f,
-  1.0178008299781669e-4f, 1.1852545451857104e-5f, -8.0914539313342186e-5f,
-  -2.6454558961220653e-5f, 6.0208388858339534e-5f, 3.4169979203255580e-5f,
-  -4.1203296686185329e-5f, -3.6353143441156863e-5f, 2.4999186627094098e-5f,
-  3.4542829080466582e-5f, -1.2148053427488782e-5f, -3.0260855999161159e-5f,
-  2.7687092952335852e-6f, 2.5095689880235108e-5f, 3.6223160417538916e-6f,
-  -2.0960977068565079e-5f, -9.3312292092513232e-6f, 2.0711288605113663e-5f,
-  3.1992093654438569e-5f, 1.9772538588596925e-5f, 4.8667740603532560e-6f,
-  -5.3495033191567977e-7f,
-};
-
 #define CONVOLVE \
     _ _ _ _ _ _ _ _ _ _  _ _ _ _ _ _ _ _ _ _ \
     _ _ _ _ _ _ _ _ _ _  _ _ _ _ _ _ _ _ _ _ \
@@ -119,25 +75,14 @@ static float double_fir1(float const * input)
 
 static float fast_half_fir(float const * input)
 {
-  static const float coefs[] = {
-    .3094188462713818f, -.08198144615199748f, .03055232105456833f,
-    -.01015890277986387f, .002513237297525149f, -.0003469672050347395f,
-  };
   int i = 0;
   float sum = input[0] * .5f;
-#define _ sum += (input[-(2*i+1)] + input[2*i+1]) * coefs[i], ++i;
+#define _ sum += (input[-(2*i+1)] + input[2*i+1]) * fast_half_fir_coefs[i], ++i;
   _ _ _ _ _ _
 #undef _
   return (float)sum;
 }
 
-static const float iir_coefs[] = {
-  .0262852045255816f, .0998310478296204f, .2068650611060755f,
-  .3302241336172489f, .4544203620946318f, .5685783569471244f,
-  .6669444657994612f, .7478697711807407f, .8123244036799226f,
-  .8626000999654434f, .9014277444199280f, .9314860567781748f,
-  .9551915287878752f, .9746617828910630f, .9917763050166036f,
-  };
 #define IIR_FILTER _ _ _ _ _ _ _
 #define _ in1=(in1-p->y[i])*iir_coefs[i]+tmp1;tmp1=p->y[i],p->y[i]=in1;++i;\
           in0=(in0-p->y[i])*iir_coefs[i]+tmp0;tmp0=p->y[i],p->y[i]=in0;++i;
@@ -175,77 +120,18 @@ static void half_phase(half_iir_t * p, float * buf, int len)
 #undef _
 }
 
-#define raw_coef_t float
-static const raw_coef_t coefs0_d[POLY_FIR_LEN_D / 2 * PHASES0_D + 1] = {
-  0.f, 1.4057457935754080e-5f, 2.3302768424632188e-5f, 4.0084897378442095e-5f,
-  6.1916773126231636e-5f, 8.7973434034929016e-5f, 1.1634847507082481e-4f,
-  1.4391931654629385e-4f, 1.6635470822160746e-4f, 1.7830838562749493e-4f,
-  1.7382737311735053e-4f, 1.4698011689178234e-4f, 9.2677933545427018e-5f,
-  7.6288745483685147e-6f, -1.0867156553965507e-4f, -2.5303924530322309e-4f,
-  -4.1793463959360433e-4f, -5.9118012513731508e-4f, -7.5619603440508576e-4f,
-  -8.9285245696990080e-4f, -9.7897684238178358e-4f, -9.9248131798952959e-4f,
-  -9.1398576537725926e-4f, -7.2972364732199553e-4f, -4.3443557115962946e-4f,
-  -3.3895523979487613e-5f, 4.5331297364457429e-4f, 9.9513966802111057e-4f,
-  1.5468348913161652e-3f, 2.0533350794358640e-3f, 2.4533031436958950e-3f,
-  2.6846707315385087e-3f, 2.6913237051575155e-3f, 2.4303724507982708e-3f,
-  1.8792817173578587e-3f, 1.0420231121204950e-3f, -4.6617252898486750e-5f,
-  -1.3193786988492551e-3f, -2.6781478874181100e-3f, -3.9992272197487003e-3f,
-  -5.1422613336274056e-3f, -5.9624224517967755e-3f, -6.3250283969908542e-3f,
-  -6.1213677360236101e-3f, -5.2841872043022185e-3f, -3.8011036067186429e-3f,
-  -1.7241752288145494e-3f, 8.2596463599396213e-4f, 3.6626436307478369e-3f,
-  6.5430316636724021e-3f, 9.1853404499045010e-3f, 1.1292516396583619e-2f,
-  1.2580791345879052e-2f, 1.2810714562937180e-2f, 1.1817712330677889e-2f,
-  9.5388893881204976e-3f, 6.0327678128662696e-3f, 1.4889921444742027e-3f,
-  -3.7742770128030593e-3f, -9.3265389310393538e-3f, -1.4654680466977541e-2f,
-  -1.9204813565928323e-2f, -2.2433342812570076e-2f, -2.3863084249865732e-2f,
-  -2.3139248817097825e-2f, -2.0079526147977360e-2f, -1.4712465100990968e-2f,
-  -7.2989072959128900e-3f, 1.6676055337427264e-3f, 1.1483818597217116e-2f,
-  2.1283378291010333e-2f, 3.0104924254589629e-2f, 3.6977102234817580e-2f,
-  4.1013752396638667e-2f, 4.1510805491867378e-2f, 3.8035383354576423e-2f,
-  3.0497421566956902e-2f, 1.9194910514469185e-2f, 4.8255960959712636e-3f,
-  -1.1539393212932630e-2f, -2.8521204184392364e-2f, -4.4535662544571142e-2f,
-  -5.7926040870466614e-2f, -6.7116245375785713e-2f, -7.0771566186484461e-2f,
-  -6.7952220045636696e-2f, -5.8244261062898019e-2f, -4.1853211028450271e-2f,
-  -1.9648003905967236e-2f, 6.8535507014343263e-3f, 3.5561844452076982e-2f,
-  6.3953651316164553e-2f, 8.9264185854578418e-2f, 1.0872025112127688e-1f,
-  1.1979689474056175e-1f, 1.2047646491371326e-1f, 1.0948710929592399e-1f,
-  8.6497869185231543e-2f, 5.2249701648862154e-2f, 8.6059406690018377e-3f,
-  -4.1488376792262582e-2f, -9.4141677945723271e-2f, -1.4474093381170536e-1f,
-  -1.8825408052888104e-1f, -2.1958987927558168e-1f, -2.3398931875783419e-1f,
-  -2.2741860176576378e-1f, -1.9693206642095332e-1f, -1.4097432039328661e-1f,
-  -5.9594435654526039e-2f, 4.5448949025739843e-2f, 1.7070477403312445e-1f,
-  3.1117273816011837e-1f, 4.6056631075658744e-1f, 6.1167961235662682e-1f,
-  7.5683349228721264e-1f, 8.8836924234920911e-1f, 9.9915393319190682e-1f,
-  1.0830597619389459e+0f, 1.1353812335460003e+0f, 1.1531583819295732e+0f,
-};
-
-static const raw_coef_t coefs0_u[POLY_FIR_LEN_U / 2 * PHASES0_U + 1] = {
-  0.f, 2.4376543962047211e-5f, 9.7074354091545404e-5f, 2.5656573977863553e-4f,
-  5.2734092391248152e-4f, 8.9078135146855391e-4f, 1.2494786883827907e-3f,
-  1.4060353542261659e-3f, 1.0794576035695273e-3f, -2.1547711862939183e-5f,
- -2.0658693124381805e-3f, -4.9333908355966233e-3f, -8.0713165910440213e-3f,
- -1.0451560117817383e-2f, -1.0703998868319438e-2f, -7.4626412699536097e-3f,
-  1.0898921033926621e-4f, 1.1734475997741493e-2f, 2.5579413661660957e-2f,
-  3.8168952738129619e-2f, 4.4846162998312754e-2f, 4.0821915377309274e-2f,
-  2.2679961923658700e-2f, -9.9957152600624218e-3f, -5.3343924460223908e-2f,
- -9.8792607573741240e-2f, -1.3382736970823086e-1f, -1.4404307655147228e-1f,
- -1.1619851747063137e-1f, -4.1649695271274462e-2f, 8.0680482815468343e-2f,
-  2.4264355486537642e-1f, 4.2712782955601925e-1f, 6.1041328492424185e-1f,
-  7.6625948559498691e-1f, 8.7088876549652772e-1f, 9.0774244518772884e-1f,
-};
-
 #define coef(coef_p, interp_order, fir_len, phase_num, coef_interp_num, \
     fir_coef_num) coef_p[(fir_len) * ((interp_order) + 1) * (phase_num) + \
     ((interp_order) + 1) * (fir_coef_num) + (interp_order - coef_interp_num)]
 
 #define COEF(h,l,i) ((i)<0||(i)>=(l)?0:(h)[(i)>(l)/2?(l)-(i):(i)])
 static void prepare_coefs(float * coefs, int n, int phases0, int phases,
-    raw_coef_t const * coefs0, double multiplier)
+    float const * coefs0, double multiplier)
 {
   double k[6];
   int length0 = n * phases0, length = n * phases, K0 = iAL(k)/2 - 1, i, j, pos;
-  raw_coef_t * coefs1 = malloc(((size_t)length / 2  + 1) * sizeof(*coefs1));
-  raw_coef_t * p = coefs1, f0, f1 = 0;
+  float * coefs1 = malloc(((size_t)length / 2  + 1) * sizeof(*coefs1));
+  float * p = coefs1, f0, f1 = 0;
 
   for (j = 0; j < iAL(k); k[j] = COEF(coefs0, length0, j - K0), ++j);
   for (pos = i = 0; i < length0 / 2; ++i) {
@@ -254,18 +140,18 @@ static void prepare_coefs(float * coefs, int n, int phases0, int phases,
     double c=(1/12.)*(k[4]-k[0]-2*(k[3]-k[1])-60*a),e=.5*(k[3]-k[1])-a-c;
     for (; pos / phases == i; pos += phases0) {
       double x = (double)(pos % phases) / phases;
-      *p++ = (raw_coef_t)(k[K0] + ((((a*x + b)*x + c)*x + d)*x + e)*x);
+      *p++ = (float)(k[K0] + ((((a*x + b)*x + c)*x + d)*x + e)*x);
     }
     for (j = 0; j < iAL(k) - 1; k[j] = k[j + 1], ++j);
     k[j] = COEF(coefs0, length0, i + iAL(k) / 2 + 1);
   }
   if (!(length & 1))
-    *p++ = (raw_coef_t)k[K0];
+    *p++ = (float)k[K0];
   assert(p - coefs1 == length / 2  + 1);
 
   for (i = 0; i < n; ++i) for (j = phases - 1; j >= 0; --j, f1 = f0) {
     pos = (n - 1 - i) * phases + j;
-    f0 = COEF(coefs1, length, pos) * (raw_coef_t)multiplier;
+    f0 = COEF(coefs1, length, pos) * (float)multiplier;
     coef(coefs, 1, n, j, 0, i) = (float)f0;
     coef(coefs, 1, n, j, 1, i) = (float)(f1 - f0);
   }
diff --git a/tests/1-delay-clear.c b/tests/1-delay-clear.c
new file mode 100644
index 0000000..ba4d47c
--- /dev/null
+++ b/tests/1-delay-clear.c
@@ -0,0 +1,64 @@
+/* SoX Resampler Library      Copyright (c) 2007-15 robs at users.sourceforge.net
+ * Licence for this file: LGPL v2.1                  See LICENCE for details. */
+
+/* Test 1: exercises soxr_delay and soxr_clear */
+
+#ifdef NDEBUG /* N.B. assert used with active statements so enable always. */
+#undef NDEBUG /* Must undef above assert.h or other that might include it. */
+#endif
+
+#include <soxr.h>
+#include "../examples/examples-common.h"
+
+#define ranqd1(x) ((x) = 1664525 * (x) + 1013904223) /* int32_t x */
+#define franqd1(x) (float)(ranqd1(x) * (1. / (65536. * 32768.))) /* [-1,1) */
+
+#define irate 9600
+#define orate 4410
+
+int main(int argc, char const * arg[])
+{
+  soxr_error_t error;
+  int32_t ran = 0;
+  int j;
+
+  soxr_t soxr = soxr_create(irate, orate, 1, &error, NULL, NULL, NULL);
+  assert(!error);
+
+  for (j=0; j<2; ++j) {
+    float ibuf[irate], out[orate+2], obuf[orate+2], * ibuf1 = ibuf;
+    size_t ilen = AL(ibuf)-1, olen = AL(obuf), i, odone = 0, odone0, odone1=0;
+    soxr_quality_spec_t  q_spec = soxr_quality_spec(SOXR_HQ, 0);
+
+    for (i=0; i<irate; ibuf[i++] = franqd1(ran));
+
+    error = soxr_oneshot(irate, orate, 1, ibuf, ilen, NULL,
+        out, AL(out), &odone0, NULL, &q_spec, NULL);
+    assert(!error);
+    assert(odone0==orate);
+
+    for (i=0; ilen || odone1; ++i) {
+      double out_samples = (double)orate / irate * (double)ilen;
+      double delayed_samples = soxr_delay(soxr);
+      unsigned max_out_samples = (unsigned)(out_samples + delayed_samples + .5);
+      assert(delayed_samples >= 0);
+      fprintf(stderr, "%5u %5u %5u\n",
+          (unsigned)ilen, max_out_samples, (unsigned)odone);
+      assert(max_out_samples+odone==odone0);
+      error = soxr_process(soxr, ibuf1, ilen, NULL, obuf+odone, olen, &odone1);
+      assert(!error);
+      odone += odone1;
+      ibuf1 = NULL, ilen = 0;
+      olen = min(100, AL(obuf)-odone);
+    }
+    assert(odone==odone0);
+
+    for (i=0; i<odone && out[i]==obuf[i]; ++i);
+    assert(i==odone);
+
+    soxr_clear(soxr);
+  }
+  soxr_delete(soxr);
+
+  return 0 * argc * !arg;
+}
diff --git a/tests/CMakeLists.txt b/tests/CMakeLists.txt
index 277fc55..333c0bd 100644
--- a/tests/CMakeLists.txt
+++ b/tests/CMakeLists.txt
@@ -48,3 +48,5 @@ foreach (b ${test_bits})
 endforeach ()
 
 add_custom_target (test-vectors ALL DEPENDS ${vectors})
+
+add_test (1-delay-clear ${BIN}1-delay-clear)
diff --git a/tests/bandwidth-test b/tests/bandwidth-test
new file mode 100755
index 0000000..47c2303
--- /dev/null
+++ b/tests/bandwidth-test
@@ -0,0 +1,40 @@
+#!/bin/bash
+set -e
+
+# SoX Resampler Library       Copyright (c) 2007-15 robs at users.sourceforge.net
+# Licence for this file: LGPL v2.1                  See LICENCE for details.
+
+# Tests varying bandwidth.
+
+
+
+tool=./3-options-input-fn
+
+spec="spectrogram -z120 -Z-20 -wd -ho"
+ext=f32; e=0
+rate1=48000
+rate2=44100
+
+for n in 1 2; do
+
+rate1n=`expr $rate1 / 2`
+
+#sox -r $rate1 -n 0.$ext synth 1s sq pad .03 .03  gain -1
+sox -r $rate1 -n 0.$ext synth 8 sin 0:$rate1n gain -1
+
+for pass in `seq 79 5 99`; do
+	f=bw1-$rate2-p`printf %02u $pass`
+	$tool $rate1 $rate2 1 $e $e 4 0 $pass < 0.$ext | sox -c1 -r$rate2 -t $ext - -n $spec $f.png -c "bw-test pass:$pass stop:100"
+done
+
+for pass in `seq 79 5 99`; do
+	f=bw2-$rate2-p`printf %02u $pass`
+	stop=`expr 200 - $pass`
+	$tool $rate1 $rate2 1 $e $e 4 0 $pass $stop < 0.$ext | sox -c1 -r$rate2 -t $ext - -n $spec $f.png -c "bw-test pass:$pass stop:$stop"
+done
+
+r=$rate1; rate1=$rate2; rate2=$r
+
+done
+
+rm 0.$ext
diff --git a/tests/eg-test b/tests/eg-test
index 797c715..58d085c 100755
--- a/tests/eg-test
+++ b/tests/eg-test
@@ -1,12 +1,24 @@
 #!/bin/bash
-# SoX Resampler Library       Copyright (c) 2007-13 robs at users.sourceforge.net
+set -e
+
+# SoX Resampler Library       Copyright (c) 2007-15 robs at users.sourceforge.net
 # Licence for this file: LGPL v2.1                  See LICENCE for details.
 
+# Exercises each example programme.
+
+
+
 len=8
 #vg="valgrind --leak-check=full --show-reachable=yes"
 
+
+
+# Exercise example 1:
 $vg ./1-single-block
 
+
+
+# Check that examples 2-4 can convert 96k<->44k1 and that results are same for each:
 ir=96000
 or=44100
 for i in 1 2; do
@@ -22,8 +34,14 @@ for i in 1 2; do
 done
 rm *.f32
 
-rm ?.png
+
+
+# Exercise VR making sure that varied internal stage reconfigurations occur:
+variations=(slow-sweep fast-changing)
+signals=(sine-wave saw-tooth-wave)
 for n in 0 1 2 3; do
-  $vg ./5-variable-rate $n | sox -tf32 -r44100 -c1 - -n spectrogram -hwk -o $n.png -X 50
+  signal=${signals[`expr $n % 2 || true`]}
+  variation=${variations[`expr $n / 2 || true`]}
+  $vg ./5-variable-rate $n | sox -tf32 -r44100 -c1 - -n spectrogram -z130 -hwd -o v$n.png -X 50 -c "variation:$variation signal:$signal"
   vg=""
 done
diff --git a/tests/io-test b/tests/io-test
index 537f896..a291c78 100755
--- a/tests/io-test
+++ b/tests/io-test
@@ -1,25 +1,31 @@
 #!/bin/bash
-# SoX Resampler Library       Copyright (c) 2007-13 robs at users.sourceforge.net
+set -e
+
+# SoX Resampler Library       Copyright (c) 2007-15 robs at users.sourceforge.net
 # Licence for this file: LGPL v2.1                  See LICENCE for details.
 
-ir=96000
+# Tests IO
+
+
+
+ir=65537
 or=44100
 len=16
-f=0+48k
-g=48k+0
-ex=./3-options-input-fn
+f=1/32768
+g=32768:0
+tool=./3-options-input-fn
 
 types=(f32 f64 s32 s16)
 
+zs=(180 180 180 180 180 120 120 120 120)
+
 do_one() {
-  $ex $ir $or $c $1 $2 $3 < $c.${types[$1]} |
-  sox -t ${types[$2]} -r $or -c $c - -n spectrogram -X50 -hwk -z180 -o io$n$c.png
+  $tool $ir $or $c $1 $2 $3 < $c.${types[$1]} |
+  sox -t ${types[`expr $2 % 4`]} -r $or -c $c - -n spectrogram -X50 -hwk -z${zs[$n]} -o io$c$n.png -c "io-test i:${types[$1]} o:${types[`expr $2 % 4`]} ($2) q:$3"
   n=`expr $n + 1`
 }
 
-rm io??.png
-
-j=2; test z$1 != z && j=$1
+j=3; test z$1 != z && j=$1
 
 for c in `seq 1 $j`; do
   for n in `seq 0 3`; do
@@ -27,14 +33,27 @@ for c in `seq 1 $j`; do
   done
 
   n=0
-  for m in `seq 0 3`; do do_one $m $m 4; done
   do_one 1 2 5
   do_one 2 0 5
-  do_one 3 2 4
-  do_one 0 3 4
+  for m in `seq 0 3`; do do_one $m $m 5; done
+  do_one 3 2 3
+  do_one 0 3 3
+  do_one 0 11 3
 
   f="$f sin $g"
-  g=48k:0
+  g=0+32768
 done
 
 rm ?.[sf][0-9][0-9]
+
+
+
+# Check conversion between differing I/O types, but no rate-change:
+
+for i in 1 2 3; do
+  prev=""
+  sox -n -c $i 0.f32 synth $len gain -.1
+  $tool 1 1 $i 0 2 < 0.f32 | $tool 1 1 $i 2 0 > 1.f32
+  cmp [01].f32
+done
+rm *.f32
diff --git a/tests/large-ratio b/tests/large-ratio
deleted file mode 100755
index a12bda9..0000000
--- a/tests/large-ratio
+++ /dev/null
@@ -1,22 +0,0 @@
-#!/bin/sh
-# SoX Resampler Library       Copyright (c) 2007-13 robs at users.sourceforge.net
-# Licence for this file: LGPL v2.1                  See LICENCE for details.
-
-# Warning: the intermediate signal (piped) is 3.2 Gbytes so may slug the
-# system somewhat.
-
-ex=../examples/3-options-input-fn
-q=6
-r=1e5
-
-rm lr.png
-
-../tests/vector-gen 1000 0 8 500 .9375 1.s32
-
-$ex 1 $r 1 2 1 $q < 1.s32 | $ex $r 1 1 1 2 $q > 2.s32
-
-sox -M -r 1k 1.s32 -r 1k 2.s32 -n spectrogram -hwk -z180 -o lr.png
-
-display lr.png &
-
-rm [12].s32
diff --git a/tests/large-ratio-test b/tests/large-ratio-test
new file mode 100755
index 0000000..64f1789
--- /dev/null
+++ b/tests/large-ratio-test
@@ -0,0 +1,23 @@
+#!/bin/bash
+set -e
+
+# SoX Resampler Library       Copyright (c) 2007-15 robs at users.sourceforge.net
+# Licence for this file: LGPL v2.1                  See LICENCE for details.
+
+# Tests interpolating then decimating be the same, large ratio.
+
+tool=../examples/3-options-input-fn
+q=6
+ratio=2e4
+srate=8000
+nrate=`expr $srate / 2`
+
+rm -f lr.png
+
+../tests/vector-gen $srate 0 8 $nrate .9375 1.s32
+
+$tool 1 $ratio 1 2 1 $q < 1.s32 | $tool $ratio 1 1 1 2 $q > 2.s32
+
+sox -M -r $srate -c1 1.s32 -r $srate -c1 2.s32 -n spectrogram -hwd -Z-10 -z180 -o lr.png -c "large-ratio-test q:$q ratio:$ratio"
+
+rm [12].s32
diff --git a/tests/phase-test b/tests/phase-test
new file mode 100755
index 0000000..4c491d8
--- /dev/null
+++ b/tests/phase-test
@@ -0,0 +1,38 @@
+#!/bin/bash
+set -e
+
+# SoX Resampler Library       Copyright (c) 2007-15 robs at users.sourceforge.net
+# Licence for this file: LGPL v2.1                  See LICENCE for details.
+
+# Tests varying phase-response.
+
+tool=./3-options-input-fn
+spec="spectrogram -z160 -Z-20 -X 2000 -wd -ho"
+ext=f32; e=0
+rate1=48000
+rate2=44100
+
+for n in 1 2; do
+	sox -r $rate1 -n 0.$ext synth 1s sq pad .03 .03  gain -1
+
+	# Test the following combinations:
+	names=(linear-phase intermediate-phase maximum-phase minimum-phase)
+	filters=(standard-filter steep-filter)
+
+	for q in `seq 0 7`; do
+		f=ph-$rate2-q$q
+		name=${names[`expr $q % 4 || true`]}
+		filter=${filters[`expr $q / 4 || true`]}
+		$tool $rate1 $rate2 1 $e $e $q'6' < 0.$ext | sox -c1 -r$rate2 -t $ext - -n $spec $f.png -c "ph-test $filter $name"
+	done
+
+	# Test specific phase-response percentages:
+	for q in `seq 0 20 100`; do
+		f=ph-$rate2-p`printf %03u $q`
+		$tool $rate1 $rate2 1 $e $e 46 0 0 0 $q < 0.$ext | sox -c1 -r$rate2 -t $ext - -n $spec $f.png -c "ph-test phase:${q}%"
+	done
+
+	r=$rate1; rate1=$rate2; rate2=$r
+done
+
+rm 0.$ext
diff --git a/tests/q-test b/tests/q-test
new file mode 100755
index 0000000..7a0f0a2
--- /dev/null
+++ b/tests/q-test
@@ -0,0 +1,72 @@
+#!/bin/bash
+set -e
+
+# SoX Resampler Library       Copyright (c) 2007-15 robs at users.sourceforge.net
+# Licence for this file: LGPL v2.1                  See LICENCE for details.
+
+# Tests conversion qualities 0..7 & variable-rate.
+
+
+
+tool=./3-options-input-fn
+ext=f64; e=1
+c=1
+q1=0; q2=7
+rates=48000
+zs=(50 87 87 87 111 135 159 180 95)
+
+zz() {
+	echo "spectrogram -z${zs[$1]} -Z-30 -wd -ho"
+}
+
+for rate0 in $rates; do
+
+rate1=$rate0
+rate2=44100
+
+for n in 1 2; do
+
+rate1n=`expr $rate1 / 2`
+
+
+
+# Convert sweep, for spectrogram:
+
+sox -r $rate1 -n -c $c 0.$ext synth 8 sin 0:$rate1n gain -1
+
+for q in `seq $q1 $q2`; do
+	f=qa-$rate1-$rate2-$q
+	$tool $rate1 $rate2 $c $e $e $q  0 < 0.$ext | sox -c$c -r$rate2 -t $ext - -n $(zz $q) $f.png -c $f
+done
+q=8
+f=qa-$rate1-$rate2-v
+$tool $rate1 $rate2 $c $e $e 4 20 < 0.$ext | sox -c$c -r$rate2 -t $ext - -n $(zz $q) $f.png -c $f
+
+
+
+# Convert impulse, for spectrogram:
+
+#: << :
+sox -r $rate1 -n 0.$ext synth 1s sq pad .03 .03  gain -1
+
+for q in `seq $q1 $q2`; do
+	f=qb-$rate1-$rate2-$q
+	$tool $rate1 $rate2 1 $e $e $q  0 < 0.$ext | sox -c1 -r$rate2 -t $ext - $f.wav
+done
+q=8
+f=qb-$rate1-$rate2-v
+$tool $rate1 $rate2 1 $e $e 4 20 < 0.$ext | sox -c1 -r$rate2 -t $ext - $f.wav
+
+# Combine impuse responses into multi-channel file (for inspection in Audacity):
+sox -M qb-$rate1-$rate2-?.wav q$rate1-$rate2.wav
+
+rm qb-$rate1-$rate2-?.wav
+:
+
+rate1=44100
+rate2=$rate0
+
+done
+done
+
+rm 0.$ext
diff --git a/tests/scripts b/tests/scripts
new file mode 100755
index 0000000..f245919
--- /dev/null
+++ b/tests/scripts
@@ -0,0 +1,13 @@
+#!/bin/bash
+set -e
+
+# SoX Resampler Library       Copyright (c) 2007-15 robs at users.sourceforge.net
+# Licence for this file: LGPL v2.1                  See LICENCE for details.
+
+../../tests/bandwidth-test
+../../tests/eg-test
+../../tests/io-test
+../../tests/large-ratio-test
+../../tests/phase-test
+../../tests/q-test
+../../tests/time-test
diff --git a/tests/time-test b/tests/time-test
new file mode 100755
index 0000000..e8904b3
--- /dev/null
+++ b/tests/time-test
@@ -0,0 +1,35 @@
+#!/bin/bash
+set -e
+
+# SoX Resampler Library       Copyright (c) 2007-15 robs at users.sourceforge.net
+# Licence for this file: LGPL v2.1                  See LICENCE for details.
+
+# Tests rate conversion time for qualities 0..7 & variable-rate.
+
+tool=./3-options-input-fn
+ext=f32; e=0
+c=2
+q1=0; q2=7
+rates="48000 77773 96000"
+
+for rate0 in $rates; do
+	rate1=$rate0
+	rate2=44100
+	for n in 1 2; do
+		rate1n=`expr $rate1 / 2`
+		sox -r $rate1 -n -c $c 0.$ext synth 5: sin 0:$rate1n gain -1
+
+		for q in `seq $q1 $q2`; do
+			echo $rate1 '-->' $rate2 c=$c q=$q
+			time $tool $rate1 $rate2 $c $e $e $q < 0.$ext > /dev/null;
+		done
+
+		echo $rate1 '-->' $rate2 c=$c q=v
+		time $tool $rate1 $rate2 $c $e $e 4 20 < 0.$ext > /dev/null
+
+		rate1=44100
+		rate2=$rate0
+	done
+done
+
+rm 0.$ext

-- 
libsoxr packaging



More information about the pkg-multimedia-commits mailing list