summaryrefslogtreecommitdiff
path: root/lib/libsamplerate/libsamplerate-0.2.2/tests
diff options
context:
space:
mode:
Diffstat (limited to 'lib/libsamplerate/libsamplerate-0.2.2/tests')
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/CMakeLists.txt95
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/calc_snr.c243
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/callback_hang_test.c127
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/callback_test.c238
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/clone_test.c134
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/downsample_test.c61
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/float_short_test.c192
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/misc_test.c208
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/multi_channel_test.c368
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/multichan_throughput_test.c261
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/nullptr_test.c108
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/reset_test.c236
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/simple_test.c168
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/snr_bw_test.c404
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/src-evaluate.c530
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/streaming_test.c149
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/termination_test.c342
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/throughput_test.c253
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/util.c228
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/util.h41
-rwxr-xr-xlib/libsamplerate/libsamplerate-0.2.2/tests/varispeed_test.c275
21 files changed, 4661 insertions, 0 deletions
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/CMakeLists.txt b/lib/libsamplerate/libsamplerate-0.2.2/tests/CMakeLists.txt
new file mode 100755
index 00000000..eefa60b3
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/CMakeLists.txt
@@ -0,0 +1,95 @@
+check_include_file(sys/times.h HAVE_SYS_TIMES_H)
+
+check_function_exists(alarm HAVE_ALARM)
+check_function_exists(signal HAVE_SIGNAL)
+
+check_symbol_exists(SIGALRM signal.h HAVE_SIGALRM)
+
+if((NOT VCPKG_TOOLCHAIN) AND PKG_CONFIG_FOUND AND (NOT CMAKE_VERSION VERSION_LESS 3.6))
+ pkg_check_modules(FFTW3 fftw3 IMPORTED_TARGET)
+ if(FFTW3_FOUND)
+ add_library(FFTW3::fftw3 INTERFACE IMPORTED)
+ target_link_libraries(FFTW3::fftw3 INTERFACE PkgConfig::FFTW3)
+ endif()
+else()
+ find_package(FFTW3)
+endif()
+
+set(HAVE_FFTW3 ${FFTW3_FOUND} PARENT_SCOPE)
+
+add_executable(misc_test misc_test.c util.c util.h)
+target_link_libraries(misc_test PRIVATE samplerate)
+add_test(NAME misc_test COMMAND misc_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
+
+add_executable(termination_test termination_test.c util.c util.h)
+target_link_libraries(termination_test PRIVATE samplerate)
+add_test(NAME termination_test COMMAND termination_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
+
+add_executable(callback_hang_test callback_hang_test.c util.c util.h)
+target_link_libraries(callback_hang_test PRIVATE samplerate)
+add_test(NAME callback_hang_test COMMAND callback_hang_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
+
+add_executable(downsample_test downsample_test.c util.c util.h)
+target_link_libraries(downsample_test PRIVATE samplerate)
+add_test(NAME downsample_test COMMAND downsample_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
+
+add_executable(simple_test simple_test.c util.c util.h)
+target_link_libraries(simple_test PRIVATE samplerate)
+add_test(NAME simple_test COMMAND simple_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
+
+add_executable(callback_test callback_test.c util.c util.h)
+target_link_libraries(callback_test PRIVATE samplerate)
+add_test(NAME callback_test COMMAND callback_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
+
+add_executable(reset_test reset_test.c util.c util.h)
+target_link_libraries(reset_test PRIVATE samplerate)
+add_test(NAME reset_test COMMAND reset_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
+
+add_executable(clone_test clone_test.c util.c util.h)
+target_link_libraries(clone_test PRIVATE samplerate)
+add_test(NAME clone_test COMMAND clone_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
+
+add_executable(nullptr_test nullptr_test.c util.c util.h)
+target_link_libraries(nullptr_test PRIVATE samplerate)
+add_test(NAME nullptr_test COMMAND nullptr_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
+
+add_executable(multi_channel_test multi_channel_test.c calc_snr.c util.c util.h)
+target_link_libraries(multi_channel_test
+ PRIVATE
+ samplerate
+ $<$<BOOL:${FFTW3_FOUND}>:FFTW3::fftw3>
+ )
+add_test(NAME multi_channel_test COMMAND multi_channel_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
+
+add_executable(varispeed_test varispeed_test.c calc_snr.c util.c util.h)
+target_link_libraries(varispeed_test
+ PRIVATE samplerate
+ $<$<BOOL:${FFTW3_FOUND}>:FFTW3::fftw3>
+ )
+add_test(NAME varispeed_test COMMAND varispeed_test util.c util.h WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
+
+add_executable(float_short_test float_short_test.c)
+target_link_libraries(float_short_test PRIVATE samplerate)
+add_test(NAME float_short_test COMMAND float_short_test WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
+
+add_executable(snr_bw_test snr_bw_test.c calc_snr.c util.c util.h)
+target_link_libraries(snr_bw_test
+ PRIVATE
+ samplerate
+ $<$<BOOL:${FFTW3_FOUND}>:FFTW3::fftw3>
+ )
+add_test(NAME snr_bw_test COMMAND snr_bw_test util.c util.h WORKING_DIRECTORY ${PROJECT_BINARY_DIR}/src)
+
+add_executable(throughput_test throughput_test.c util.c util.h)
+target_link_libraries(throughput_test PRIVATE samplerate)
+
+add_executable(multichan_throughput_test multichan_throughput_test.c util.c util.h)
+target_link_libraries(multichan_throughput_test PRIVATE samplerate)
+
+add_executable(src-evaluate src-evaluate.c util.c util.h calc_snr.c)
+target_link_libraries(src-evaluate
+ PRIVATE
+ samplerate
+ $<$<BOOL:${FFTW3_FOUND}>:FFTW3::fftw3>
+ $<$<BOOL:${SndFile_FOUND}>:${SNDFILE_TARGET}>
+ )
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/calc_snr.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/calc_snr.c
new file mode 100755
index 00000000..35a37f77
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/calc_snr.c
@@ -0,0 +1,243 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "util.h"
+
+#if (HAVE_FFTW3)
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <fftw3.h>
+
+#define MAX_SPEC_LEN (1<<18)
+#define MAX_PEAKS 10
+
+static void log_mag_spectrum (double *input, int len, double *magnitude) ;
+static void smooth_mag_spectrum (double *magnitude, int len) ;
+static double find_snr (const double *magnitude, int len, int expected_peaks) ;
+
+typedef struct
+{ double peak ;
+ int index ;
+} PEAK_DATA ;
+
+double
+calculate_snr (float *data, int len, int expected_peaks)
+{ static double magnitude [MAX_SPEC_LEN] ;
+ static double datacopy [MAX_SPEC_LEN] ;
+
+ double snr = 200.0 ;
+ int k ;
+
+ if (len > MAX_SPEC_LEN)
+ { printf ("%s : line %d : data length too large.\n", __FILE__, __LINE__) ;
+ exit (1) ;
+ } ;
+
+ for (k = 0 ; k < len ; k++)
+ datacopy [k] = data [k] ;
+
+ /* Pad the data just a little to speed up the FFT. */
+ while ((len & 0x1F) && len < MAX_SPEC_LEN)
+ { datacopy [len] = 0.0 ;
+ len ++ ;
+ } ;
+
+ log_mag_spectrum (datacopy, len, magnitude) ;
+ smooth_mag_spectrum (magnitude, len / 2) ;
+
+ snr = find_snr (magnitude, len, expected_peaks) ;
+
+ return snr ;
+} /* calculate_snr */
+
+/*==============================================================================
+** There is a slight problem with trying to measure SNR with the method used
+** here; the side lobes of the windowed FFT can look like a noise/aliasing peak.
+** The solution is to smooth the magnitude spectrum by wiping out troughs
+** between adjacent peaks as done here.
+** This removes side lobe peaks without affecting noise/aliasing peaks.
+*/
+
+static void linear_smooth (double *mag, PEAK_DATA *larger, PEAK_DATA *smaller) ;
+
+static void
+smooth_mag_spectrum (double *mag, int len)
+{ PEAK_DATA peaks [2] ;
+
+ int k ;
+
+ memset (peaks, 0, sizeof (peaks)) ;
+
+ /* Find first peak. */
+ for (k = 1 ; k < len - 1 ; k++)
+ { if (mag [k - 1] < mag [k] && mag [k] >= mag [k + 1])
+ { peaks [0].peak = mag [k] ;
+ peaks [0].index = k ;
+ break ;
+ } ;
+ } ;
+
+ /* Find subsequent peaks ans smooth between peaks. */
+ for (k = peaks [0].index + 1 ; k < len - 1 ; k++)
+ { if (mag [k - 1] < mag [k] && mag [k] >= mag [k + 1])
+ { peaks [1].peak = mag [k] ;
+ peaks [1].index = k ;
+
+ if (peaks [1].peak > peaks [0].peak)
+ linear_smooth (mag, &peaks [1], &peaks [0]) ;
+ else
+ linear_smooth (mag, &peaks [0], &peaks [1]) ;
+ peaks [0] = peaks [1] ;
+ } ;
+ } ;
+
+} /* smooth_mag_spectrum */
+
+static void
+linear_smooth (double *mag, PEAK_DATA *larger, PEAK_DATA *smaller)
+{ int k ;
+
+ if (smaller->index < larger->index)
+ { for (k = smaller->index + 1 ; k < larger->index ; k++)
+ mag [k] = (mag [k] < mag [k - 1]) ? 0.999 * mag [k - 1] : mag [k] ;
+ }
+ else
+ { for (k = smaller->index - 1 ; k >= larger->index ; k--)
+ mag [k] = (mag [k] < mag [k + 1]) ? 0.999 * mag [k + 1] : mag [k] ;
+ } ;
+
+} /* linear_smooth */
+
+/*==============================================================================
+*/
+
+static int
+peak_compare (const void *vp1, const void *vp2)
+{ const PEAK_DATA *peak1, *peak2 ;
+
+ peak1 = (const PEAK_DATA*) vp1 ;
+ peak2 = (const PEAK_DATA*) vp2 ;
+
+ return (peak1->peak < peak2->peak) ? 1 : -1 ;
+} /* peak_compare */
+
+static double
+find_snr (const double *magnitude, int len, int expected_peaks)
+{ PEAK_DATA peaks [MAX_PEAKS] ;
+
+ int k, peak_count = 0 ;
+ double snr ;
+
+ memset (peaks, 0, sizeof (peaks)) ;
+
+ /* Find the MAX_PEAKS largest peaks. */
+ for (k = 1 ; k < len - 1 ; k++)
+ { if (magnitude [k - 1] < magnitude [k] && magnitude [k] >= magnitude [k + 1])
+ { if (peak_count < MAX_PEAKS)
+ { peaks [peak_count].peak = magnitude [k] ;
+ peaks [peak_count].index = k ;
+ peak_count ++ ;
+ qsort (peaks, peak_count, sizeof (PEAK_DATA), peak_compare) ;
+ }
+ else if (magnitude [k] > peaks [MAX_PEAKS - 1].peak)
+ { peaks [MAX_PEAKS - 1].peak = magnitude [k] ;
+ peaks [MAX_PEAKS - 1].index = k ;
+ qsort (peaks, MAX_PEAKS, sizeof (PEAK_DATA), peak_compare) ;
+ } ;
+ } ;
+ } ;
+
+ if (peak_count < expected_peaks)
+ { printf ("\n%s : line %d : bad peak_count (%d), expected %d.\n\n", __FILE__, __LINE__, peak_count, expected_peaks) ;
+ return -1.0 ;
+ } ;
+
+ /* Sort the peaks. */
+ qsort (peaks, peak_count, sizeof (PEAK_DATA), peak_compare) ;
+
+ snr = peaks [0].peak ;
+ for (k = 1 ; k < peak_count ; k++)
+ if (fabs (snr - peaks [k].peak) > 10.0)
+ return fabs (peaks [k].peak) ;
+
+ return snr ;
+} /* find_snr */
+
+static void
+log_mag_spectrum (double *input, int len, double *magnitude)
+{ fftw_plan plan = NULL ;
+
+ double maxval ;
+ int k ;
+
+ if (input == NULL || magnitude == NULL)
+ return ;
+
+ plan = fftw_plan_r2r_1d (len, input, magnitude, FFTW_R2HC, FFTW_ESTIMATE | FFTW_PRESERVE_INPUT) ;
+ if (plan == NULL)
+ { printf ("%s : line %d : create plan failed.\n", __FILE__, __LINE__) ;
+ exit (1) ;
+ } ;
+
+ fftw_execute (plan) ;
+
+ fftw_destroy_plan (plan) ;
+
+ maxval = 0.0 ;
+ for (k = 1 ; k < len / 2 ; k++)
+ { /*
+ ** From : http://www.fftw.org/doc/Real_002dto_002dReal-Transform-Kinds.html#Real_002dto_002dReal-Transform-Kinds
+ **
+ ** FFTW_R2HC computes a real-input DFT with output in “halfcomplex” format, i.e. real and imaginary parts
+ ** for a transform of size n stored as:
+ **
+ ** r0, r1, r2, ..., rn/2, i(n+1)/2-1, ..., i2, i1
+ */
+ double re = magnitude [k] ;
+ double im = magnitude [len - k] ;
+ magnitude [k] = sqrt (re * re + im * im) ;
+ maxval = (maxval < magnitude [k]) ? magnitude [k] : maxval ;
+ } ;
+
+ memset (magnitude + len / 2, 0, len / 2 * sizeof (magnitude [0])) ;
+
+ /* Don't care about DC component. Make it zero. */
+ magnitude [0] = 0.0 ;
+
+ /* log magnitude. */
+ for (k = 0 ; k < len ; k++)
+ { magnitude [k] = magnitude [k] / maxval ;
+ magnitude [k] = (magnitude [k] < 1e-15) ? -200.0 : 20.0 * log10 (magnitude [k]) ;
+ } ;
+
+ return ;
+} /* log_mag_spectrum */
+
+#else /* ! (HAVE_LIBFFTW && HAVE_LIBRFFTW) */
+
+double
+calculate_snr (float *data, int len, int expected_peaks)
+{ double snr = 200.0 ;
+
+ data = data ;
+ len = len ;
+ expected_peaks = expected_peaks ;
+
+ return snr ;
+} /* calculate_snr */
+
+#endif
+
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/callback_hang_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/callback_hang_test.c
new file mode 100755
index 00000000..42a1bb03
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/callback_hang_test.c
@@ -0,0 +1,127 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <math.h>
+
+#if HAVE_ALARM && HAVE_SIGNAL && HAVE_SIGALRM
+
+#include <signal.h>
+
+#include <samplerate.h>
+
+#include "util.h"
+
+#define SHORT_BUFFER_LEN 512
+#define LONG_BUFFER_LEN (1 << 14)
+
+typedef struct
+{ double ratio ;
+ int count ;
+} SRC_PAIR ;
+
+static void callback_hang_test (int converter) ;
+
+static void alarm_handler (int number) ;
+static long input_callback (void *cb_data, float **data) ;
+
+
+int
+main (void)
+{
+ /* Set up SIGALRM handler. */
+ signal (SIGALRM, alarm_handler) ;
+
+ puts ("") ;
+ callback_hang_test (SRC_ZERO_ORDER_HOLD) ;
+ callback_hang_test (SRC_LINEAR) ;
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ callback_hang_test (SRC_SINC_FASTEST) ;
+#endif
+ puts ("") ;
+
+ return 0 ;
+} /* main */
+
+
+static void
+callback_hang_test (int converter)
+{ static float output [LONG_BUFFER_LEN] ;
+ static SRC_PAIR pairs [] =
+ {
+ { 1.2, 5 }, { 1.1, 1 }, { 1.0, 1 }, { 3.0, 1 }, { 2.0, 1 }, { 0.3, 1 },
+ { 1.2, 0 }, { 1.1, 10 }, { 1.0, 1 }
+ } ;
+
+
+ SRC_STATE *src_state ;
+
+ double src_ratio = 1.0 ;
+ int k, error ;
+
+ printf ("\tcallback_hang_test (%-28s) ....... ", src_get_name (converter)) ;
+ fflush (stdout) ;
+
+ /* Perform sample rate conversion. */
+ src_state = src_callback_new (input_callback, converter, 1, &error, NULL) ;
+ if (src_state == NULL)
+ { printf ("\n\nLine %d : src_callback_new () failed : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ for (k = 0 ; k < ARRAY_LEN (pairs) ; k++)
+ { alarm (1) ;
+ src_ratio = pairs [k].ratio ;
+ src_callback_read (src_state, src_ratio, pairs [k].count, output) ;
+ } ;
+
+ src_state = src_delete (src_state) ;
+
+ alarm (0) ;
+ puts ("ok") ;
+
+ return ;
+} /* callback_hang_test */
+
+static void
+alarm_handler (int number)
+{
+ (void) number ;
+ printf ("\n\n Error : Hang inside src_callback_read() detected. Exiting!\n\n") ;
+ exit (1) ;
+} /* alarm_handler */
+
+static long
+input_callback (void *cb_data, float **data)
+{
+ static float buffer [20] ;
+
+ (void) cb_data ;
+ *data = buffer ;
+
+ return ARRAY_LEN (buffer) ;
+} /* input_callback */
+
+#else
+
+int
+main (void)
+{
+ puts ("\tCan't run this test on this platform.") ;
+ return 0 ;
+} /* main */
+
+#endif
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/callback_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/callback_test.c
new file mode 100755
index 00000000..c13d2061
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/callback_test.c
@@ -0,0 +1,238 @@
+/*
+** Copyright (c) 2003-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <samplerate.h>
+
+#include "util.h"
+
+#define BUFFER_LEN 10000
+#define CB_READ_LEN 256
+
+static void callback_test (int converter, double ratio) ;
+static void end_of_stream_test (int converter) ;
+
+int
+main (void)
+{ static double src_ratios [] =
+ { 1.0, 0.099, 0.1, 0.33333333, 0.789, 1.0001, 1.9, 3.1, 9.9
+ } ;
+
+ int k ;
+
+ puts ("") ;
+
+ puts (" Zero Order Hold interpolator :") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ callback_test (SRC_ZERO_ORDER_HOLD, src_ratios [k]) ;
+
+ puts (" Linear interpolator :") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ callback_test (SRC_LINEAR, src_ratios [k]) ;
+
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ puts (" Sinc interpolator :") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ callback_test (SRC_SINC_FASTEST, src_ratios [k]) ;
+#endif
+ puts ("") ;
+
+ puts (" End of stream test :") ;
+ end_of_stream_test (SRC_ZERO_ORDER_HOLD) ;
+ end_of_stream_test (SRC_LINEAR) ;
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ end_of_stream_test (SRC_SINC_FASTEST) ;
+#endif
+
+ puts ("") ;
+ return 0 ;
+} /* main */
+
+/*=====================================================================================
+*/
+
+typedef struct
+{ int channels ;
+ long count, total ;
+ int end_of_data ;
+ float data [BUFFER_LEN] ;
+} TEST_CB_DATA ;
+
+static long
+test_callback_func (void *cb_data, float **data)
+{ TEST_CB_DATA *pcb_data ;
+
+ long frames ;
+
+ if ((pcb_data = cb_data) == NULL)
+ return 0 ;
+
+ if (data == NULL)
+ return 0 ;
+
+ if (pcb_data->total - pcb_data->count > CB_READ_LEN)
+ frames = CB_READ_LEN / pcb_data->channels ;
+ else
+ frames = (pcb_data->total - pcb_data->count) / pcb_data->channels ;
+
+ *data = pcb_data->data + pcb_data->count ;
+ pcb_data->count += frames ;
+
+ return frames ;
+} /* test_callback_func */
+
+
+static void
+callback_test (int converter, double src_ratio)
+{ static TEST_CB_DATA test_callback_data ;
+ static float output [BUFFER_LEN] ;
+
+ SRC_STATE *src_state ;
+
+ long read_count, read_total ;
+ int error ;
+
+ printf ("\tcallback_test (SRC ratio = %6.4f) ........... ", src_ratio) ;
+ fflush (stdout) ;
+
+ test_callback_data.channels = 2 ;
+ test_callback_data.count = 0 ;
+ test_callback_data.end_of_data = 0 ;
+ test_callback_data.total = ARRAY_LEN (test_callback_data.data) ;
+
+ if ((src_state = src_callback_new (test_callback_func, converter, test_callback_data.channels, &error, &test_callback_data)) == NULL)
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ read_total = 0 ;
+ do
+ { /* We will be throwing away output data, so just grab as much as possible. */
+ read_count = ARRAY_LEN (output) / test_callback_data.channels ;
+ read_count = src_callback_read (src_state, src_ratio, read_count, output) ;
+ read_total += read_count ;
+ }
+ while (read_count > 0) ;
+
+ if ((error = src_error (src_state)) != 0)
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ src_delete (src_state) ;
+
+ if (fabs (read_total / src_ratio - ARRAY_LEN (test_callback_data.data)) > 2.0)
+ { printf ("\n\nLine %d : input / output length mismatch.\n\n", __LINE__) ;
+ printf (" input len : %d\n", ARRAY_LEN (test_callback_data.data)) ;
+ printf (" output len : %ld (should be %g +/- 2)\n\n", read_total,
+ floor (0.5 + src_ratio * ARRAY_LEN (test_callback_data.data))) ;
+ exit (1) ;
+ } ;
+
+ puts ("ok") ;
+
+ return ;
+} /* callback_test */
+
+/*=====================================================================================
+*/
+
+static long
+eos_callback_func (void *cb_data, float **data)
+{
+ TEST_CB_DATA *pcb_data ;
+ long frames ;
+
+ if (data == NULL)
+ return 0 ;
+
+ if ((pcb_data = cb_data) == NULL)
+ return 0 ;
+
+ /*
+ ** Return immediately if there is no more data.
+ ** In this case, the output pointer 'data' will not be set and
+ ** valgrind should not warn about it.
+ */
+ if (pcb_data->end_of_data)
+ return 0 ;
+
+ if (pcb_data->total - pcb_data->count > CB_READ_LEN)
+ frames = CB_READ_LEN / pcb_data->channels ;
+ else
+ frames = (pcb_data->total - pcb_data->count) / pcb_data->channels ;
+
+ *data = pcb_data->data + pcb_data->count ;
+ pcb_data->count += frames ;
+
+ /*
+ ** Set end_of_data so that the next call to the callback function will
+ ** return zero ocunt without setting the 'data' pointer.
+ */
+ if (pcb_data->total < 2 * pcb_data->count)
+ pcb_data->end_of_data = 1 ;
+
+ return frames ;
+} /* eos_callback_data */
+
+
+static void
+end_of_stream_test (int converter)
+{ static TEST_CB_DATA test_callback_data ;
+ static float output [BUFFER_LEN] ;
+
+ SRC_STATE *src_state ;
+
+ double src_ratio = 0.3 ;
+ long read_count ;
+ int error ;
+
+ printf ("\t%-30s ........... ", src_get_name (converter)) ;
+ fflush (stdout) ;
+
+ test_callback_data.channels = 2 ;
+ test_callback_data.count = 0 ;
+ test_callback_data.end_of_data = 0 ;
+ test_callback_data.total = ARRAY_LEN (test_callback_data.data) ;
+
+ if ((src_state = src_callback_new (eos_callback_func, converter, test_callback_data.channels, &error, &test_callback_data)) == NULL)
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ do
+ { /* We will be throwing away output data, so just grab as much as possible. */
+ read_count = ARRAY_LEN (output) / test_callback_data.channels ;
+ read_count = src_callback_read (src_state, src_ratio, read_count, output) ;
+ }
+ while (read_count > 0) ;
+
+ if ((error = src_error (src_state)) != 0)
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ src_delete (src_state) ;
+
+ if (test_callback_data.end_of_data == 0)
+ { printf ("\n\nLine %d : test_callback_data.end_of_data should not be 0."
+ " This is a bug in the test.\n\n", __LINE__) ;
+ exit (1) ;
+ } ;
+
+ puts ("ok") ;
+ return ;
+} /* end_of_stream_test */
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/clone_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/clone_test.c
new file mode 100755
index 00000000..0e420e1f
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/clone_test.c
@@ -0,0 +1,134 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <samplerate.h>
+
+#include "util.h"
+
+#define BUFFER_LEN (1 << 16)
+#define NUM_CHANNELS 2
+#define FRAMES_PER_PASS (BUFFER_LEN >> 1)
+
+static void
+clone_test (int converter)
+{ static float input_serial [BUFFER_LEN * NUM_CHANNELS], input_interleaved [BUFFER_LEN * NUM_CHANNELS] ;
+ static float output [BUFFER_LEN * NUM_CHANNELS], output_cloned [BUFFER_LEN * NUM_CHANNELS] ;
+ double sine_freq ;
+
+ SRC_STATE* src_state ;
+ SRC_STATE* src_state_cloned ;
+ SRC_DATA src_data, src_data_cloned ;
+
+ int error, frame, ch, idx ;
+
+ printf (" clone_test (%-28s) ....... ", src_get_name (converter)) ;
+ fflush (stdout) ;
+
+ memset (input_serial, 0, sizeof (input_serial)) ;
+ memset (input_interleaved, 0, sizeof (input_interleaved)) ;
+ memset (output, 0, sizeof (output)) ;
+ memset (output_cloned, 0, sizeof (output_cloned)) ;
+
+ /* Fill input buffer with an n-channel interleaved sine wave */
+ sine_freq = 0.0111 ;
+ gen_windowed_sines (1, &sine_freq, 1.0, input_serial, BUFFER_LEN) ;
+ gen_windowed_sines (1, &sine_freq, 1.0, input_serial + BUFFER_LEN, BUFFER_LEN) ;
+ interleave_data (input_serial, input_interleaved, BUFFER_LEN, NUM_CHANNELS) ;
+
+ if ((src_state = src_new (converter, NUM_CHANNELS, &error)) == NULL)
+ { printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ /* Perform initial pass using first half of buffer so that src_state has non-trivial state */
+ src_data.src_ratio = 1.1 ;
+ src_data.input_frames = FRAMES_PER_PASS ;
+ src_data.output_frames = FRAMES_PER_PASS ;
+ src_data.data_in = input_interleaved ;
+ src_data.data_out = output ;
+ src_data.output_frames_gen = 0 ;
+
+ if ((error = src_process (src_state, &src_data)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
+ printf (" src_data.output_frames : %ld\n\n", src_data.output_frames) ;
+ exit (1) ;
+ } ;
+
+ /* Clone handle */
+ if ((src_state_cloned = src_clone (src_state, &error)) == NULL)
+ { printf ("\n\nLine %d : src_clone() failed : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ /* Process second half of buffer with both handles */
+ src_data.data_in = input_interleaved + FRAMES_PER_PASS ;
+
+ src_data_cloned = src_data ;
+ src_data_cloned.data_out = output_cloned ;
+
+ if ((error = src_process (src_state, &src_data)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
+ printf (" src_data.output_frames : %ld\n\n", src_data.output_frames) ;
+ exit (1) ;
+ } ;
+
+ if ((error = src_process (src_state_cloned, &src_data_cloned)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
+ printf (" src_data.output_frames : %ld\n\n", src_data.output_frames) ;
+ exit (1) ;
+ } ;
+
+ /* Check that both handles generated the same number of output frames */
+ if (src_data.output_frames_gen != src_data_cloned.output_frames_gen)
+ { printf ("\n\nLine %d : cloned output_frames_gen (%ld) != original (%ld)\n\n", __LINE__,
+ src_data_cloned.output_frames_gen, src_data.output_frames_gen) ;
+ exit (1) ;
+ } ;
+
+ for (ch = 0 ; ch < NUM_CHANNELS ; ch++)
+ { for (frame = 0 ; frame < src_data.output_frames_gen ; frame++)
+ { idx = ch * NUM_CHANNELS + ch ;
+ if (output[idx] != output_cloned[idx])
+ { printf ("\n\nLine %d : cloned data does not equal original data at channel %d, frame %d\n\n",
+ __LINE__, ch, frame) ;
+ exit (1) ;
+ } ;
+ } ;
+ } ;
+
+ src_delete (src_state) ;
+ src_delete (src_state_cloned) ;
+
+ puts ("ok") ;
+} /* clone_test */
+
+int
+main (void)
+{
+ puts("");
+
+ clone_test (SRC_ZERO_ORDER_HOLD) ;
+ clone_test (SRC_LINEAR) ;
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ clone_test (SRC_SINC_FASTEST) ;
+#endif
+ puts("");
+
+ return 0 ;
+} /* main */
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/downsample_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/downsample_test.c
new file mode 100755
index 00000000..6a4a75e1
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/downsample_test.c
@@ -0,0 +1,61 @@
+/*
+** Copyright (c) 2008-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <samplerate.h>
+
+#include "util.h"
+
+static void
+downsample_test (int converter)
+{ static float in [1000], out [10] ;
+ SRC_DATA data ;
+
+ printf (" downsample_test (%-28s) ....... ", src_get_name (converter)) ;
+ fflush (stdout) ;
+
+ data.src_ratio = 1.0 / 255.0 ;
+ data.input_frames = ARRAY_LEN (in) ;
+ data.output_frames = ARRAY_LEN (out) ;
+ data.data_in = in ;
+ data.data_out = out ;
+
+ if (src_simple (&data, converter, 1))
+ { puts ("src_simple failed.") ;
+ exit (1) ;
+ } ;
+
+ puts ("ok") ;
+} /* downsample_test */
+
+int
+main (void)
+{
+ puts ("") ;
+
+ downsample_test (SRC_ZERO_ORDER_HOLD) ;
+ downsample_test (SRC_LINEAR) ;
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ downsample_test (SRC_SINC_FASTEST) ;
+#endif
+#ifdef ENABLE_SINC_MEDIUM_CONVERTER
+ downsample_test (SRC_SINC_MEDIUM_QUALITY) ;
+#endif
+#ifdef ENABLE_SINC_BEST_CONVERTER
+ downsample_test (SRC_SINC_BEST_QUALITY) ;
+#endif
+
+ puts ("") ;
+
+ return 0 ;
+} /* main */
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/float_short_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/float_short_test.c
new file mode 100755
index 00000000..8c423e18
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/float_short_test.c
@@ -0,0 +1,192 @@
+/*
+** Copyright (c) 2003-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <samplerate.h>
+
+#include "util.h"
+
+#define BUFFER_LEN 10000
+
+static void float_to_short_test (void) ;
+static void short_to_float_test (void) ;
+
+static void float_to_int_test (void) ;
+static void int_to_float_test (void) ;
+
+int
+main (void)
+{
+ puts ("") ;
+
+ float_to_short_test () ;
+ short_to_float_test () ;
+
+ float_to_int_test () ;
+ int_to_float_test () ;
+
+ puts ("") ;
+
+ return 0 ;
+} /* main */
+
+/*=====================================================================================
+*/
+
+static void
+float_to_short_test (void)
+{
+ static float fpos [] =
+ { 0.95f, 0.99f, 1.0f, 1.01f, 1.1f, 2.0f, 11.1f, 111.1f, 2222.2f, 33333.3f,
+ // Some "almost 1" as corner cases
+ (float) (32767.0 / 32768.0), (float) ((32767.0 + 0.4) / 32768.0), (float) ((32767. + 0.5) / 32768.0),
+ (float) ((32767.0 + 0.6) / 32768.0), (float) ((32767.0 + 0.9) / 32768.0),
+ } ;
+ static float fneg [] =
+ { -0.95f, -0.99f, -1.0f, -1.01f, -1.1f, -2.0f, -11.1f, -111.1f, -2222.2f, -33333.3f,
+ // Some "almost 1" as corner cases
+ (float) (-32767.0 / 32768.0), (float) (-(32767.0 + 0.4) / 32768.0), (float) (-(32767.0 + 0.5) / 32768.0),
+ (float) (-(32767.0 + 0.6) / 32768.0), (float) (-(32767.0 + 0.9) / 32768.0),
+ } ;
+
+ static short out [MAX (ARRAY_LEN (fpos), ARRAY_LEN (fneg))] ;
+
+ int k ;
+
+ printf ("\tfloat_to_short_test ............................. ") ;
+
+ src_float_to_short_array (fpos, out, ARRAY_LEN (fpos)) ;
+
+ for (k = 0 ; k < ARRAY_LEN (fpos) ; k++)
+ if (out [k] < 30000)
+ { printf ("\n\n\tLine %d : out [%d] == %d\n", __LINE__, k, out [k]) ;
+ exit (1) ;
+ } ;
+
+ src_float_to_short_array (fneg, out, ARRAY_LEN (fneg)) ;
+
+ for (k = 0 ; k < ARRAY_LEN (fneg) ; k++)
+ if (out [k] > -30000)
+ { printf ("\n\n\tLine %d : out [%d] == %d\n", __LINE__, k, out [k]) ;
+ exit (1) ;
+ } ;
+
+ puts ("ok") ;
+
+ return ;
+} /* float_to_short_test */
+
+/*-------------------------------------------------------------------------------------
+*/
+
+static void
+short_to_float_test (void)
+{
+ static short input [BUFFER_LEN] ;
+ static short output [BUFFER_LEN] ;
+ static float temp [BUFFER_LEN] ;
+
+ int k ;
+
+ printf ("\tshort_to_float_test ............................. ") ;
+
+ for (k = 0 ; k < ARRAY_LEN (input) ; k++)
+ input [k] = (k * 0x8000) / ARRAY_LEN (input) ;
+
+ src_short_to_float_array (input, temp, ARRAY_LEN (temp)) ;
+ src_float_to_short_array (temp, output, ARRAY_LEN (output)) ;
+
+ for (k = 0 ; k < ARRAY_LEN (input) ; k++)
+ if (ABS (input [k] - output [k]) > 0)
+ { printf ("\n\n\tLine %d : index %d %d -> %d\n", __LINE__, k, input [k], output [k]) ;
+ exit (1) ;
+ } ;
+
+ puts ("ok") ;
+
+ return ;
+} /* short_to_float_test */
+
+/*=====================================================================================
+*/
+
+static void
+float_to_int_test (void)
+{
+ static float fpos [] =
+ { 0.95f, 0.99f, 1.0f, 1.01f, 1.1f, 2.0f, 11.1f, 111.1f, 2222.2f, 33333.3f
+ } ;
+ static float fneg [] =
+ { -0.95f, -0.99f, -1.0f, -1.01f, -1.1f, -2.0f, -11.1f, -111.1f, -2222.2f, -33333.3f
+ } ;
+
+ static int out [MAX (ARRAY_LEN (fpos), ARRAY_LEN (fneg))] ;
+
+ int k ;
+
+ printf ("\tfloat_to_int_test ............................... ") ;
+
+ src_float_to_int_array (fpos, out, ARRAY_LEN (fpos)) ;
+
+ for (k = 0 ; k < ARRAY_LEN (fpos) ; k++)
+ if (out [k] < 30000 * 0x10000)
+ { printf ("\n\n\tLine %d : out [%d] == %d\n", __LINE__, k, out [k]) ;
+ exit (1) ;
+ } ;
+
+ src_float_to_int_array (fneg, out, ARRAY_LEN (fneg)) ;
+
+ for (k = 0 ; k < ARRAY_LEN (fneg) ; k++)
+ if (out [k] > -30000 * 0x1000)
+ { printf ("\n\n\tLine %d : out [%d] == %d\n", __LINE__, k, out [k]) ;
+ exit (1) ;
+ } ;
+
+ puts ("ok") ;
+
+ return ;
+} /* float_to_int_test */
+
+/*-------------------------------------------------------------------------------------
+*/
+
+static void
+int_to_float_test (void)
+{
+ static int input [BUFFER_LEN] ;
+ static int output [BUFFER_LEN] ;
+ static float temp [BUFFER_LEN] ;
+
+ int k ;
+
+ printf ("\tint_to_float_test ............................... ") ;
+
+ for (k = 0 ; k < ARRAY_LEN (input) ; k++)
+ input [k] = (k * 0x80000000) / ARRAY_LEN (input) ;
+
+ src_int_to_float_array (input, temp, ARRAY_LEN (temp)) ;
+ src_float_to_int_array (temp, output, ARRAY_LEN (output)) ;
+
+ for (k = 0 ; k < ARRAY_LEN (input) ; k++)
+ if (ABS (input [k] - output [k]) > 0)
+ { printf ("\n\n\tLine %d : index %d %d -> %d\n", __LINE__, k, input [k], output [k]) ;
+ exit (1) ;
+ } ;
+
+ puts ("ok") ;
+
+ return ;
+} /* int_to_float_test */
+
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/misc_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/misc_test.c
new file mode 100755
index 00000000..6d3c0d4e
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/misc_test.c
@@ -0,0 +1,208 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <samplerate.h>
+
+#include "util.h"
+
+static void name_test (void) ;
+static void error_test (void) ;
+static void src_ratio_test (void) ;
+static void zero_input_test (int converter) ;
+static void get_channels_test (int converter);
+
+int
+main (void)
+{
+ puts ("") ;
+
+ printf (" version : %s\n\n", src_get_version ()) ;
+
+ /* Current max converter is SRC_LINEAR. */
+ name_test () ;
+
+ error_test () ;
+
+ src_ratio_test () ;
+
+ zero_input_test (SRC_ZERO_ORDER_HOLD) ;
+ zero_input_test (SRC_LINEAR) ;
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ zero_input_test (SRC_SINC_FASTEST) ;
+#endif
+ get_channels_test (SRC_ZERO_ORDER_HOLD) ;
+ get_channels_test (SRC_LINEAR) ;
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ get_channels_test (SRC_SINC_FASTEST) ;
+#endif
+ puts ("") ;
+ return 0 ;
+} /* main */
+
+static void
+name_test (void)
+{ const char *name ;
+ int k = 0 ;
+
+ puts (" name_test :") ;
+
+ while (1)
+ { name = src_get_name (k) ;
+ if (name == NULL)
+ break ;
+ printf ("\tName %d : %s\n", k, name) ;
+ printf ("\tDesc %d : %s\n", k, src_get_description (k)) ;
+ k ++ ;
+ } ;
+
+ puts ("") ;
+
+ return ;
+} /* name_test */
+
+/*------------------------------------------------------------------------------
+*/
+
+typedef struct
+{ double ratio ;
+ int should_pass ;
+} RATIO_TEST ;
+
+static RATIO_TEST ratio_test [] =
+{ { 1.0 / 256.1, 0 },
+ { 1.0 / 256.0, 1 },
+ { 1.0, 1 },
+ { 256.0, 1 },
+ { 256.1, 0 },
+ { -1.0, 0 }
+} ;
+
+static void
+src_ratio_test (void)
+{ int k ;
+
+ puts (" src_ratio_test (SRC ratio must be in range [1/256, 256]):" ) ;
+
+
+ for (k = 0 ; k < ARRAY_LEN (ratio_test) ; k++)
+ { if (ratio_test [k].should_pass && src_is_valid_ratio (ratio_test [k].ratio) == 0)
+ { printf ("\n\nLine %d : SRC ratio %f should have passed.\n\n", __LINE__, ratio_test [k].ratio) ;
+ exit (1) ;
+ } ;
+ if (! ratio_test [k].should_pass && src_is_valid_ratio (ratio_test [k].ratio) != 0)
+ { printf ("\n\nLine %d : SRC ratio %f should not have passed.\n\n", __LINE__, ratio_test [k].ratio) ;
+ exit (1) ;
+ } ;
+ printf ("\t SRC ratio (%9.5f) : %s ................... ok\n", ratio_test [k].ratio,
+ (ratio_test [k].should_pass ? "pass" : "fail")) ;
+ } ;
+
+ puts ("") ;
+
+ return ;
+} /* src_ratio_test */
+
+static void
+error_test (void)
+{ const char *errorstr ;
+ int k, errors = 0 ;
+
+ puts (" error_test :") ;
+
+ for (k = 0 ; 1 ; k++)
+ { errorstr = src_strerror (k) ;
+ printf ("\t%-2d : %s\n", k, errorstr) ;
+ if (errorstr == NULL)
+ { errors ++ ;
+ continue ;
+ } ;
+ if (strstr (errorstr, "Placeholder.") == errorstr)
+ break ;
+ } ;
+
+ if (errors != 0)
+ { printf ("\n\nLine %d : Missing error numbers above.\n\n", __LINE__) ;
+ exit (1) ;
+ } ;
+
+ puts ("") ;
+
+ return ;
+} /* error_test */
+
+static void
+zero_input_test (int converter)
+{ SRC_DATA data ;
+ SRC_STATE *state ;
+ float out [100] ;
+ int error ;
+
+ printf (" %s (%-26s) ........ ", __func__, src_get_name (converter)) ;
+ fflush (stdout) ;
+
+ if ((state = src_new (converter, 1, &error)) == NULL)
+ { printf ("\n\nLine %d : src_new failed : %s.\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ data.data_in = (float *) (size_t) 0xdeadbeef ;
+ data.input_frames = 0 ;
+ data.data_out = out ;
+ data.output_frames = ARRAY_LEN (out) ;
+ data.end_of_input = 0 ;
+ data.src_ratio = 1.0 ;
+
+ if ((error = src_process (state, &data)))
+ { printf ("\n\nLine %d : src_new failed : %s.\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ state = src_delete (state) ;
+
+ puts ("ok") ;
+} /* zero_input_test */
+
+static void get_channels_test(int converter)
+{
+ SRC_STATE *state;
+ int channels_in, channels_out;
+ const char *errorstr;
+
+ state = NULL;
+ if ((channels_out = src_get_channels(state)) >= 0)
+ {
+ printf ("\n\nLine %d : Return value should be negative, was : %d.\n\n", __LINE__, channels_out) ;
+ exit (1) ;
+ }
+ errorstr = src_strerror(-channels_out);
+ if (!strstr(errorstr, "NULL"))
+ {
+ printf ("\n\nLine %d : Inverted output should be valid error code mentioning a NULL pointer, was : %s.\n\n", __LINE__, errorstr) ;
+ exit (1) ;
+ }
+
+ for (channels_in = 1; channels_in <= 8; channels_in++)
+ {
+ int error;
+ state = src_new(converter, channels_in, &error);
+ if ((channels_out = src_get_channels(state)) != channels_in)
+ {
+ printf ("\n\nLine %d : Return value should be %d, was : %d.\n\n", __LINE__, channels_in, channels_out) ;
+ exit (1) ;
+ }
+ state = src_delete(state);
+ }
+}
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/multi_channel_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/multi_channel_test.c
new file mode 100755
index 00000000..0afb6398
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/multi_channel_test.c
@@ -0,0 +1,368 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <assert.h>
+
+#if (HAVE_FFTW3)
+#include <fftw3.h>
+#else
+static inline void
+fftw_cleanup (void)
+{ return ;
+}
+#endif
+
+#include <samplerate.h>
+
+#include "util.h"
+#define BUFFER_LEN 50000
+#define BLOCK_LEN (12)
+
+#define MAX_CHANNELS 10
+
+static void simple_test (int converter, int channel_count, double target_snr) ;
+static void process_test (int converter, int channel_count, double target_snr) ;
+static void callback_test (int converter, int channel_count, double target_snr) ;
+
+int
+main (void)
+{ double target ;
+ int k ;
+
+ puts ("\n Zero Order Hold interpolator :") ;
+ target = 38.0 ;
+ for (k = 1 ; k <= 3 ; k++)
+ { simple_test (SRC_ZERO_ORDER_HOLD, k, target) ;
+ process_test (SRC_ZERO_ORDER_HOLD, k, target) ;
+ callback_test (SRC_ZERO_ORDER_HOLD, k, target) ;
+ } ;
+
+ puts ("\n Linear interpolator :") ;
+ target = 79.0 ;
+ for (k = 1 ; k <= 3 ; k++)
+ { simple_test (SRC_LINEAR, k, target) ;
+ process_test (SRC_LINEAR, k, target) ;
+ callback_test (SRC_LINEAR, k, target) ;
+ } ;
+
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ puts ("\n Sinc interpolator :") ;
+ target = 100.0 ;
+ for (k = 1 ; k <= MAX_CHANNELS ; k++)
+ { simple_test (SRC_SINC_FASTEST, k, target) ;
+ process_test (SRC_SINC_FASTEST, k, target) ;
+ callback_test (SRC_SINC_FASTEST, k, target) ;
+ } ;
+#endif
+
+ fftw_cleanup () ;
+ puts ("") ;
+
+ return 0 ;
+} /* main */
+
+/*==============================================================================
+*/
+
+static float input_serial [BUFFER_LEN * MAX_CHANNELS] ;
+static float input_interleaved [BUFFER_LEN * MAX_CHANNELS] ;
+static float output_interleaved [BUFFER_LEN * MAX_CHANNELS] ;
+static float output_serial [BUFFER_LEN * MAX_CHANNELS] ;
+
+static void
+simple_test (int converter, int channel_count, double target_snr)
+{ SRC_DATA src_data ;
+
+ double freq, snr ;
+ int ch, error, frames ;
+
+ printf ("\t%-22s (%2d channel%c) ............ ", "simple_test", channel_count, channel_count > 1 ? 's' : ' ') ;
+ fflush (stdout) ;
+
+ assert (channel_count <= MAX_CHANNELS) ;
+
+ memset (input_serial, 0, sizeof (input_serial)) ;
+ memset (input_interleaved, 0, sizeof (input_interleaved)) ;
+ memset (output_interleaved, 0, sizeof (output_interleaved)) ;
+ memset (output_serial, 0, sizeof (output_serial)) ;
+
+ frames = BUFFER_LEN ;
+
+ /* Calculate channel_count separate windowed sine waves. */
+ for (ch = 0 ; ch < channel_count ; ch++)
+ { freq = (200.0 + 33.333333333 * ch) / 44100.0 ;
+ gen_windowed_sines (1, &freq, 1.0, input_serial + ch * frames, frames) ;
+ } ;
+
+ /* Interleave the data in preparation for SRC. */
+ interleave_data (input_serial, input_interleaved, frames, channel_count) ;
+
+ /* Choose a converstion ratio <= 1.0. */
+ src_data.src_ratio = 0.95 ;
+
+ src_data.data_in = input_interleaved ;
+ src_data.input_frames = frames ;
+
+ src_data.data_out = output_interleaved ;
+ src_data.output_frames = frames ;
+
+ if ((error = src_simple (&src_data, converter, channel_count)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ if (fabs (src_data.output_frames_gen - src_data.src_ratio * src_data.input_frames) > 2)
+ { printf ("\n\nLine %d : bad output data length %ld should be %d.\n", __LINE__,
+ src_data.output_frames_gen, (int) floor (src_data.src_ratio * src_data.input_frames)) ;
+ printf ("\tsrc_ratio : %.4f\n", src_data.src_ratio) ;
+ printf ("\tinput_len : %ld\n", src_data.input_frames) ;
+ printf ("\toutput_len : %ld\n\n", src_data.output_frames_gen) ;
+ exit (1) ;
+ } ;
+
+ /* De-interleave data so SNR can be calculated for each channel. */
+ deinterleave_data (output_interleaved, output_serial, frames, channel_count) ;
+
+ for (ch = 0 ; ch < channel_count ; ch++)
+ { snr = calculate_snr (output_serial + ch * frames, frames, 1) ;
+ if (snr < target_snr)
+ { printf ("\n\nLine %d: channel %d snr %f should be %f\n", __LINE__, ch, snr, target_snr) ;
+ save_oct_float ("output.dat", input_serial, channel_count * frames, output_serial, channel_count * frames) ;
+ exit (1) ;
+ } ;
+ } ;
+
+ puts ("ok") ;
+
+ return ;
+} /* simple_test */
+
+/*==============================================================================
+*/
+
+static void
+process_test (int converter, int channel_count, double target_snr)
+{ SRC_STATE *src_state ;
+ SRC_DATA src_data ;
+
+ double freq, snr ;
+ int ch, error, frames, current_in, current_out ;
+
+ printf ("\t%-22s (%2d channel%c) ............ ", "process_test", channel_count, channel_count > 1 ? 's' : ' ') ;
+ fflush (stdout) ;
+
+ assert (channel_count <= MAX_CHANNELS) ;
+
+ memset (input_serial, 0, sizeof (input_serial)) ;
+ memset (input_interleaved, 0, sizeof (input_interleaved)) ;
+ memset (output_interleaved, 0, sizeof (output_interleaved)) ;
+ memset (output_serial, 0, sizeof (output_serial)) ;
+
+ frames = BUFFER_LEN ;
+
+ /* Calculate channel_count separate windowed sine waves. */
+ for (ch = 0 ; ch < channel_count ; ch++)
+ { freq = (400.0 + 11.333333333 * ch) / 44100.0 ;
+ gen_windowed_sines (1, &freq, 1.0, input_serial + ch * frames, frames) ;
+ } ;
+
+ /* Interleave the data in preparation for SRC. */
+ interleave_data (input_serial, input_interleaved, frames, channel_count) ;
+
+ /* Perform sample rate conversion. */
+ if ((src_state = src_new (converter, channel_count, &error)) == NULL)
+ { printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ src_data.end_of_input = 0 ; /* Set this later. */
+
+ /* Choose a converstion ratio < 1.0. */
+ src_data.src_ratio = 0.95 ;
+
+ src_data.data_in = input_interleaved ;
+ src_data.data_out = output_interleaved ;
+
+ current_in = current_out = 0 ;
+
+ while (1)
+ { src_data.input_frames = MAX (MIN (BLOCK_LEN, frames - current_in), 0) ;
+ src_data.output_frames = MAX (MIN (BLOCK_LEN, frames - current_out), 0) ;
+
+ if ((error = src_process (src_state, &src_data)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ if (src_data.end_of_input && src_data.output_frames_gen == 0)
+ break ;
+
+ current_in += src_data.input_frames_used ;
+ current_out += src_data.output_frames_gen ;
+
+ src_data.data_in += src_data.input_frames_used * channel_count ;
+ src_data.data_out += src_data.output_frames_gen * channel_count ;
+
+ src_data.end_of_input = (current_in >= frames) ? 1 : 0 ;
+ } ;
+
+ src_state = src_delete (src_state) ;
+
+ if (fabs (current_out - src_data.src_ratio * current_in) > 2)
+ { printf ("\n\nLine %d : bad output data length %d should be %d.\n", __LINE__,
+ current_out, (int) floor (src_data.src_ratio * current_in)) ;
+ printf ("\tsrc_ratio : %.4f\n", src_data.src_ratio) ;
+ printf ("\tinput_len : %d\n", frames) ;
+ printf ("\toutput_len : %d\n\n", current_out) ;
+ exit (1) ;
+ } ;
+
+ /* De-interleave data so SNR can be calculated for each channel. */
+ deinterleave_data (output_interleaved, output_serial, frames, channel_count) ;
+
+ for (ch = 0 ; ch < channel_count ; ch++)
+ { snr = calculate_snr (output_serial + ch * frames, frames, 1) ;
+ if (snr < target_snr)
+ { printf ("\n\nLine %d: channel %d snr %f should be %f\n", __LINE__, ch, snr, target_snr) ;
+ save_oct_float ("output.dat", input_serial, channel_count * frames, output_serial, channel_count * frames) ;
+ exit (1) ;
+ } ;
+ } ;
+
+ puts ("ok") ;
+
+ return ;
+} /* process_test */
+
+/*==============================================================================
+*/
+
+typedef struct
+{ int channels ;
+ long total_frames ;
+ long current_frame ;
+ float *data ;
+} TEST_CB_DATA ;
+
+static long
+test_callback_func (void *cb_data, float **data)
+{ TEST_CB_DATA *pcb_data ;
+
+ long frames ;
+
+ if ((pcb_data = cb_data) == NULL)
+ return 0 ;
+
+ if (data == NULL)
+ return 0 ;
+
+ *data = pcb_data->data + (pcb_data->current_frame * pcb_data->channels) ;
+
+ if (pcb_data->total_frames - pcb_data->current_frame < BLOCK_LEN)
+ frames = pcb_data->total_frames - pcb_data->current_frame ;
+ else
+ frames = BLOCK_LEN ;
+
+ pcb_data->current_frame += frames ;
+
+ return frames ;
+} /* test_callback_func */
+
+static void
+callback_test (int converter, int channel_count, double target_snr)
+{ TEST_CB_DATA test_callback_data ;
+ SRC_STATE *src_state = NULL ;
+
+ double freq, snr, src_ratio ;
+ int ch, error, frames, read_total, read_count ;
+
+ printf ("\t%-22s (%2d channel%c) ............ ", "callback_test", channel_count, channel_count > 1 ? 's' : ' ') ;
+ fflush (stdout) ;
+
+ assert (channel_count <= MAX_CHANNELS) ;
+
+ memset (input_serial, 0, sizeof (input_serial)) ;
+ memset (input_interleaved, 0, sizeof (input_interleaved)) ;
+ memset (output_interleaved, 0, sizeof (output_interleaved)) ;
+ memset (output_serial, 0, sizeof (output_serial)) ;
+ memset (&test_callback_data, 0, sizeof (test_callback_data)) ;
+
+ frames = BUFFER_LEN ;
+
+ /* Calculate channel_count separate windowed sine waves. */
+ for (ch = 0 ; ch < channel_count ; ch++)
+ { freq = (200.0 + 33.333333333 * ch) / 44100.0 ;
+ gen_windowed_sines (1, &freq, 1.0, input_serial + ch * frames, frames) ;
+ } ;
+
+ /* Interleave the data in preparation for SRC. */
+ interleave_data (input_serial, input_interleaved, frames, channel_count) ;
+
+ /* Perform sample rate conversion. */
+ src_ratio = 0.95 ;
+ test_callback_data.channels = channel_count ;
+ test_callback_data.total_frames = frames ;
+ test_callback_data.current_frame = 0 ;
+ test_callback_data.data = input_interleaved ;
+
+ if ((src_state = src_callback_new (test_callback_func, converter, channel_count, &error, &test_callback_data)) == NULL)
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ read_total = 0 ;
+ while (read_total < frames)
+ { read_count = src_callback_read (src_state, src_ratio, frames - read_total, output_interleaved + read_total * channel_count) ;
+
+ if (read_count <= 0)
+ break ;
+
+ read_total += read_count ;
+ } ;
+
+ if ((error = src_error (src_state)) != 0)
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ src_state = src_delete (src_state) ;
+
+ if (fabs (read_total - src_ratio * frames) > 2)
+ { printf ("\n\nLine %d : bad output data length %d should be %d.\n", __LINE__,
+ read_total, (int) floor (src_ratio * frames)) ;
+ printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
+ printf ("\tinput_len : %d\n", frames) ;
+ printf ("\toutput_len : %d\n\n", read_total) ;
+ exit (1) ;
+ } ;
+
+ /* De-interleave data so SNR can be calculated for each channel. */
+ deinterleave_data (output_interleaved, output_serial, frames, channel_count) ;
+
+ for (ch = 0 ; ch < channel_count ; ch++)
+ { snr = calculate_snr (output_serial + ch * frames, frames, 1) ;
+ if (snr < target_snr)
+ { printf ("\n\nLine %d: channel %d snr %f should be %f\n", __LINE__, ch, snr, target_snr) ;
+ save_oct_float ("output.dat", input_serial, channel_count * frames, output_serial, channel_count * frames) ;
+ exit (1) ;
+ } ;
+ } ;
+
+ puts ("ok") ;
+
+ return ;
+} /* callback_test */
+
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/multichan_throughput_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/multichan_throughput_test.c
new file mode 100755
index 00000000..5cab44a1
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/multichan_throughput_test.c
@@ -0,0 +1,261 @@
+/*
+** Copyright (c) 2008-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <math.h>
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#endif
+
+#include <samplerate.h>
+
+#include "util.h"
+
+#define BUFFER_LEN (1<<17)
+
+static float input [BUFFER_LEN] ;
+
+#if (defined(ENABLE_SINC_FAST_CONVERTER) || defined(ENABLE_SINC_MEDIUM_CONVERTER) || \
+ defined(ENABLE_SINC_BEST_CONVERTER))
+static float output [BUFFER_LEN] ;
+
+static void
+throughput_test (int converter, int channels, long *best_throughput)
+{ SRC_DATA src_data ;
+ clock_t start_time, clock_time ;
+ double duration ;
+ long total_frames = 0, throughput ;
+ int error ;
+
+ printf (" %-30s %2d ", src_get_name (converter), channels) ;
+ fflush (stdout) ;
+
+ src_data.data_in = input ;
+ src_data.input_frames = ARRAY_LEN (input) / channels ;
+
+ src_data.data_out = output ;
+ src_data.output_frames = ARRAY_LEN (output) / channels ;
+
+ src_data.src_ratio = 0.99 ;
+
+#ifdef _WIN32
+ Sleep (2000) ;
+#else
+ sleep (2) ;
+#endif
+
+ start_time = clock () ;
+
+ do
+ {
+ if ((error = src_simple (&src_data, converter, channels)) != 0)
+ { puts (src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ total_frames += src_data.output_frames_gen ;
+
+ clock_time = clock () - start_time ;
+ duration = (1.0 * clock_time) / CLOCKS_PER_SEC ;
+ }
+ while (duration < 5.0) ;
+
+ if (src_data.input_frames_used != src_data.input_frames)
+ { printf ("\n\nLine %d : input frames used %ld should be %ld\n", __LINE__, src_data.input_frames_used, src_data.input_frames) ;
+ exit (1) ;
+ } ;
+
+ if (fabs (src_data.src_ratio * src_data.input_frames_used - src_data.output_frames_gen) > 2)
+ { printf ("\n\nLine %d : input / output length mismatch.\n\n", __LINE__) ;
+ printf (" input len : %d\n", ARRAY_LEN (input) / channels) ;
+ printf (" output len : %ld (should be %g +/- 2)\n\n", src_data.output_frames_gen,
+ floor (0.5 + src_data.src_ratio * src_data.input_frames_used)) ;
+ exit (1) ;
+ } ;
+
+ throughput = lrint (floor (total_frames / duration)) ;
+
+ if (!best_throughput)
+ { printf ("%5.2f %10ld\n", duration, throughput) ;
+ }
+ else
+ { *best_throughput = MAX (throughput, *best_throughput) ;
+ printf ("%5.2f %10ld %10ld\n", duration, throughput, *best_throughput) ;
+ }
+
+} /* throughput_test */
+#endif
+
+static void
+single_run (void)
+{
+#if (defined(ENABLE_SINC_FAST_CONVERTER) || defined(ENABLE_SINC_MEDIUM_CONVERTER) || \
+ defined(ENABLE_SINC_BEST_CONVERTER))
+ const int max_channels = 10 ;
+ int k ;
+#endif
+
+ printf ("\n CPU name : %s\n", get_cpu_name ()) ;
+
+ puts (
+ "\n"
+ " Converter Channels Duration Throughput\n"
+ " ---------------------------------------------------------------------"
+ ) ;
+
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ for (k = 1 ; k <= max_channels / 2 ; k++)
+ throughput_test (SRC_SINC_FASTEST, k, 0) ;
+
+ puts ("") ;
+#endif
+
+#ifdef ENABLE_SINC_MEDIUM_CONVERTER
+ for (k = 1 ; k <= max_channels / 2 ; k++)
+ throughput_test (SRC_SINC_MEDIUM_QUALITY, k, 0) ;
+
+ puts ("") ;
+#endif
+
+#ifdef ENABLE_SINC_BEST_CONVERTER
+ for (k = 1 ; k <= max_channels ; k++)
+ throughput_test (SRC_SINC_BEST_QUALITY, k, 0) ;
+ puts ("") ;
+#endif
+ return ;
+} /* single_run */
+
+static void
+multi_run (int run_count)
+{ int channels[] = {1, 2, 3, 4, 5, 6, 8, 10, 12, 14, 16, 18};
+
+ printf ("\n CPU name : %s\n", get_cpu_name ()) ;
+
+ puts (
+ "\n"
+ " Converter Channels Duration Throughput Best Throughput\n"
+ " ----------------------------------------------------------------------------------------"
+ ) ;
+
+ for (int i = 0 ; i < ARRAY_LEN(channels) ; i++)
+ {
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ long sinc_fastest = 0 ;
+#endif
+#ifdef ENABLE_SINC_MEDIUM_CONVERTER
+ long sinc_medium = 0 ;
+#endif
+#ifdef ENABLE_SINC_BEST_CONVERTER
+ long sinc_best = 0 ;
+#endif
+ int ch = channels[i];
+
+ for (int k = 0 ; k < run_count ; k++)
+ {
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ throughput_test (SRC_SINC_FASTEST, ch, &sinc_fastest) ;
+#endif
+#ifdef ENABLE_SINC_MEDIUM_CONVERTER
+ throughput_test (SRC_SINC_MEDIUM_QUALITY, ch, &sinc_medium) ;
+#endif
+#ifdef ENABLE_SINC_BEST_CONVERTER
+ throughput_test (SRC_SINC_BEST_QUALITY, ch, &sinc_best) ;
+#endif
+
+ puts ("") ;
+
+ /* Let the CPU cool down. We might be running on a laptop. */
+#ifdef _WIN32
+ Sleep (10000) ;
+#else
+ sleep (10) ;
+#endif
+ } ;
+
+ printf (
+ "\n"
+ " Converter (channels: %d) Best Throughput\n"
+ " ------------------------------------------------\n",
+ ch
+ ) ;
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ printf (" %-30s %10ld\n", src_get_name (SRC_SINC_FASTEST), sinc_fastest) ;
+#endif
+#ifdef ENABLE_SINC_MEDIUM_CONVERTER
+ printf (" %-30s %10ld\n", src_get_name (SRC_SINC_MEDIUM_QUALITY), sinc_medium) ;
+#endif
+#ifdef ENABLE_SINC_BEST_CONVERTER
+ printf (" %-30s %10ld\n", src_get_name (SRC_SINC_BEST_QUALITY), sinc_best) ;
+#endif
+ } ;
+
+ puts ("") ;
+} /* multi_run */
+
+static void
+usage_exit (const char * argv0)
+{ const char * cptr ;
+
+ if ((cptr = strrchr (argv0, '/')) != NULL)
+ argv0 = cptr ;
+
+ printf (
+ "Usage :\n"
+ " %s - Single run of the throughput test.\n"
+ " %s --best-of N - Do N runs of test a print bext result.\n"
+ "\n",
+ argv0, argv0) ;
+
+ exit (0) ;
+} /* usage_exit */
+
+int
+main (int argc, char ** argv)
+{ double freq ;
+
+ memset (input, 0, sizeof (input)) ;
+ freq = 0.01 ;
+ gen_windowed_sines (1, &freq, 1.0, input, BUFFER_LEN) ;
+
+ if (argc == 1)
+ single_run () ;
+ else if (argc == 3 && strcmp (argv [1], "--best-of") == 0)
+ { int run_count = atoi (argv [2]) ;
+
+ if (run_count < 1 || run_count > 20)
+ { printf ("Please be sensible. Run count should be in range (1, 10].\n") ;
+ exit (1) ;
+ } ;
+
+ multi_run (run_count) ;
+ }
+ else
+ usage_exit (argv [0]) ;
+
+ puts (
+ " Duration is in seconds.\n"
+ " Throughput is in frames/sec (more is better).\n"
+ ) ;
+
+ return 0 ;
+} /* main */
+
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/nullptr_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/nullptr_test.c
new file mode 100755
index 00000000..02ac00e5
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/nullptr_test.c
@@ -0,0 +1,108 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <samplerate.h>
+
+#include "util.h"
+
+#define BUFFER_LEN (1 << 16)
+#define NUM_CHANNELS 1
+
+static void
+nullptr_test (int converter)
+{ static float input [BUFFER_LEN * NUM_CHANNELS] ;
+ static float output [BUFFER_LEN * NUM_CHANNELS] ;
+
+ SRC_STATE* src_state ;
+ SRC_DATA src_data, src_data2 ;
+
+ int error ;
+
+ printf (" nullptr_test (%-28s) ....... ", src_get_name (converter)) ;
+ fflush (stdout) ;
+
+ memset (input, 0, sizeof (input)) ;
+ memset (output, 0, sizeof (output)) ;
+
+ if ((src_state = src_new (converter, NUM_CHANNELS, &error)) == NULL)
+ { printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ src_data.src_ratio = 1.1 ;
+ src_data.input_frames = BUFFER_LEN ;
+ src_data.output_frames = BUFFER_LEN ;
+ src_data.data_in = input ;
+ src_data.data_out = output ;
+ src_data.output_frames_gen = 0 ;
+
+ if ((error = src_process (src_state, &src_data)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ //Input is zero-length
+ src_data2 = src_data;
+ src_data2.data_in = NULL;
+ src_data2.input_frames = 0;
+
+ if ((error = src_process (src_state, &src_data2)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ //Output is zero-length
+ src_data2 = src_data;
+ src_data2.data_out = NULL;
+ src_data2.output_frames = 0;
+
+ if ((error = src_process (src_state, &src_data2)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ //Input and output are zero-length
+ src_data2 = src_data;
+ src_data2.data_in = NULL;
+ src_data2.data_out = NULL;
+ src_data2.input_frames = 0;
+ src_data2.output_frames = 0;
+
+ if ((error = src_process (src_state, &src_data2)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+
+ src_state = src_delete (src_state) ;
+
+ puts ("ok") ;
+} /* nullptr_test */
+
+int
+main (void)
+{
+ puts("");
+
+ nullptr_test (SRC_ZERO_ORDER_HOLD) ;
+ nullptr_test (SRC_LINEAR) ;
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ nullptr_test (SRC_SINC_FASTEST) ;
+#endif
+ puts("");
+
+ return 0 ;
+} /* main */
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/reset_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/reset_test.c
new file mode 100755
index 00000000..736f376d
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/reset_test.c
@@ -0,0 +1,236 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <samplerate.h>
+
+#include "util.h"
+
+#define BUFFER_LEN 2048
+#define CB_READ_LEN 256
+
+static void process_reset_test (int converter) ;
+static void callback_reset_test (int converter) ;
+
+static float data_one [BUFFER_LEN] ;
+static float data_zero [BUFFER_LEN] ;
+
+int
+main (void)
+{
+ puts ("") ;
+
+ process_reset_test (SRC_ZERO_ORDER_HOLD) ;
+ process_reset_test (SRC_LINEAR) ;
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ process_reset_test (SRC_SINC_FASTEST) ;
+#endif
+
+ callback_reset_test (SRC_ZERO_ORDER_HOLD) ;
+ callback_reset_test (SRC_LINEAR) ;
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ callback_reset_test (SRC_SINC_FASTEST) ;
+#endif
+
+ puts ("") ;
+
+ return 0 ;
+} /* main */
+
+static void
+process_reset_test (int converter)
+{ static float output [BUFFER_LEN] ;
+
+ SRC_STATE *src_state ;
+ SRC_DATA src_data ;
+ int k, error ;
+
+ printf ("\tprocess_reset_test (%-28s) ....... ", src_get_name (converter)) ;
+ fflush (stdout) ;
+
+ for (k = 0 ; k < BUFFER_LEN ; k++)
+ { data_one [k] = 1.0 ;
+ data_zero [k] = 0.0 ;
+ } ;
+
+ /* Get a converter. */
+ if ((src_state = src_new (converter, 1, &error)) == NULL)
+ { printf ("\n\nLine %d : src_new() failed : %s.\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ /* Process a bunch of 1.0 valued samples. */
+ src_data.data_in = data_one ;
+ src_data.data_out = output ;
+ src_data.input_frames = BUFFER_LEN ;
+ src_data.output_frames = BUFFER_LEN ;
+ src_data.src_ratio = 0.9 ;
+ src_data.end_of_input = 1 ;
+
+ if ((error = src_process (src_state, &src_data)) != 0)
+ { printf ("\n\nLine %d : src_simple () returned error : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ /* Reset the state of the converter.*/
+ src_reset (src_state) ;
+
+ /* Now process some zero data. */
+ src_data.data_in = data_zero ;
+ src_data.data_out = output ;
+ src_data.input_frames = BUFFER_LEN ;
+ src_data.output_frames = BUFFER_LEN ;
+ src_data.src_ratio = 0.9 ;
+ src_data.end_of_input = 1 ;
+
+ if ((error = src_process (src_state, &src_data)) != 0)
+ { printf ("\n\nLine %d : src_simple () returned error : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ /* Finally make sure that the output data is zero ie reset was successful. */
+ for (k = 0 ; k < BUFFER_LEN / 2 ; k++)
+ if (output [k] != 0.0)
+ { printf ("\n\nLine %d : output [%d] should be 0.0, is %f.\n", __LINE__, k, output [k]) ;
+ exit (1) ;
+ } ;
+
+ /* Make sure that this function has been exported. */
+ src_set_ratio (src_state, 1.0) ;
+
+ /* Delete converter. */
+ src_state = src_delete (src_state) ;
+
+ puts ("ok") ;
+} /* process_reset_test */
+
+/*==============================================================================
+*/
+
+typedef struct
+{ int channels ;
+ long count, total ;
+ float *data ;
+} TEST_CB_DATA ;
+
+static long
+test_callback_func (void *cb_data, float **data)
+{ TEST_CB_DATA *pcb_data ;
+
+ long frames ;
+
+ if ((pcb_data = cb_data) == NULL)
+ return 0 ;
+
+ if (data == NULL)
+ return 0 ;
+
+ if (pcb_data->total - pcb_data->count > 0)
+ frames = pcb_data->total - pcb_data->count ;
+ else
+ frames = 0 ;
+
+ *data = pcb_data->data + pcb_data->count ;
+ pcb_data->count += frames ;
+
+ return frames ;
+} /* test_callback_func */
+
+static void
+callback_reset_test (int converter)
+{ static TEST_CB_DATA test_callback_data ;
+
+ static float output [BUFFER_LEN] ;
+
+ SRC_STATE *src_state ;
+
+ double src_ratio = 1.1 ;
+ long read_count, read_total ;
+ int k, error ;
+
+ printf ("\tcallback_reset_test (%-28s) ....... ", src_get_name (converter)) ;
+ fflush (stdout) ;
+
+ for (k = 0 ; k < ARRAY_LEN (data_one) ; k++)
+ { data_one [k] = 1.0 ;
+ data_zero [k] = 0.0 ;
+ } ;
+
+ if ((src_state = src_callback_new (test_callback_func, converter, 1, &error, &test_callback_data)) == NULL)
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ /* Process a bunch of 1.0 valued samples. */
+ test_callback_data.channels = 1 ;
+ test_callback_data.count = 0 ;
+ test_callback_data.total = ARRAY_LEN (data_one) ;
+ test_callback_data.data = data_one ;
+
+ read_total = 0 ;
+ do
+ { read_count = (ARRAY_LEN (output) - read_total > CB_READ_LEN) ? CB_READ_LEN : ARRAY_LEN (output) - read_total ;
+ read_count = src_callback_read (src_state, src_ratio, read_count, output + read_total) ;
+ read_total += read_count ;
+ }
+ while (read_count > 0) ;
+
+ /* Check for errors. */
+ if ((error = src_error (src_state)) != 0)
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ /* Reset the state of the converter.*/
+ src_reset (src_state) ;
+
+ /* Process a bunch of 0.0 valued samples. */
+ test_callback_data.channels = 1 ;
+ test_callback_data.count = 0 ;
+ test_callback_data.total = ARRAY_LEN (data_zero) ;
+ test_callback_data.data = data_zero ;
+
+ /* Now process some zero data. */
+ read_total = 0 ;
+ do
+ { read_count = (ARRAY_LEN (output) - read_total > CB_READ_LEN) ? CB_READ_LEN : ARRAY_LEN (output) - read_total ;
+ read_count = src_callback_read (src_state, src_ratio, read_count, output + read_total) ;
+ read_total += read_count ;
+ }
+ while (read_count > 0) ;
+
+ /* Check for errors. */
+ if ((error = src_error (src_state)) != 0)
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ /* Finally make sure that the output data is zero ie reset was successful. */
+ for (k = 0 ; k < BUFFER_LEN / 2 ; k++)
+ if (output [k] != 0.0)
+ { printf ("\n\nLine %d : output [%d] should be 0.0, is %f.\n\n", __LINE__, k, output [k]) ;
+ save_oct_float ("output.dat", data_one, ARRAY_LEN (data_one), output, ARRAY_LEN (output)) ;
+ exit (1) ;
+ } ;
+
+ /* Make sure that this function has been exported. */
+ src_set_ratio (src_state, 1.0) ;
+
+ /* Delete converter. */
+ src_state = src_delete (src_state) ;
+
+ puts ("ok") ;
+} /* callback_reset_test */
+
+
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/simple_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/simple_test.c
new file mode 100755
index 00000000..f9014fd2
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/simple_test.c
@@ -0,0 +1,168 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+
+#include <samplerate.h>
+
+#include "util.h"
+
+#define BUFFER_LEN 2048
+
+static void simple_test (int converter, double ratio) ;
+static void src_simple_produces_output (int converter, int channels, double src_ratio) ;
+static void src_simple_produces_output_test (int converter, double src_ratio) ;
+
+int
+main (void)
+{ static double src_ratios [] =
+ { 1.0001, 0.099, 0.1, 0.33333333, 0.789, 1.9, 3.1, 9.9, 256.0, 1.0 / 256.0
+ } ;
+
+ int k ;
+
+ puts ("") ;
+
+ puts (" Zero Order Hold interpolator :") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ { simple_test (SRC_ZERO_ORDER_HOLD, src_ratios [k]) ;
+ src_simple_produces_output_test (SRC_ZERO_ORDER_HOLD, src_ratios [k]) ;
+ }
+
+ puts (" Linear interpolator :") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ { simple_test (SRC_LINEAR, src_ratios [k]) ;
+ src_simple_produces_output_test (SRC_LINEAR, src_ratios [k]) ;
+ }
+
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ puts (" Sinc interpolator :") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ { simple_test (SRC_SINC_FASTEST, src_ratios [k]) ;
+ src_simple_produces_output_test (SRC_SINC_FASTEST, src_ratios [k]) ;
+ }
+#endif
+
+ puts ("") ;
+
+ return 0 ;
+} /* main */
+
+static void
+src_simple_produces_output_test (int converter, double src_ratio)
+{
+ for (int channels = 1; channels <= 9; channels++)
+ src_simple_produces_output(converter, channels, src_ratio);
+}
+
+static void
+src_simple_produces_output (int converter, int channels, double src_ratio)
+{
+ // Choose a suitable number of frames.
+ // At least 256 so a conversion ratio of 1/256 can produce any output
+ const long NUM_FRAMES = 1000;
+ int error;
+
+ printf ("\tproduces_output\t(SRC ratio = %6.4f, channels = %d) ... ", src_ratio, channels) ;
+ fflush (stdout) ;
+
+ float *input = calloc (NUM_FRAMES * channels, sizeof (float));
+ float *output = calloc (NUM_FRAMES * channels, sizeof (float));
+
+ SRC_DATA src_data;
+ memset (&src_data, 0, sizeof (src_data)) ;
+ src_data.data_in = input;
+ src_data.data_out = output;
+ src_data.input_frames = NUM_FRAMES;
+ src_data.output_frames = NUM_FRAMES;
+ src_data.src_ratio = src_ratio;
+
+ if ((error = src_simple (&src_data, converter, channels)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+ if (src_data.input_frames_used == 0)
+ { printf ("\n\nLine %d : No input frames used.\n\n", __LINE__) ;
+ exit (1) ;
+ } ;
+ if (src_data.output_frames_gen == 0)
+ { printf ("\n\nLine %d : No output frames generated.\n\n", __LINE__) ;
+ exit (1) ;
+ } ;
+ free(input);
+ free(output);
+ puts ("ok") ;
+}
+
+
+static void
+simple_test (int converter, double src_ratio)
+{ static float input [BUFFER_LEN], output [BUFFER_LEN] ;
+
+ SRC_DATA src_data ;
+
+ int input_len, output_len, error, terminate ;
+
+ printf ("\tsimple_test\t(SRC ratio = %6.4f) ................. ", src_ratio) ;
+ fflush (stdout) ;
+
+ /* Calculate maximun input and output lengths. */
+ if (src_ratio >= 1.0)
+ { output_len = BUFFER_LEN ;
+ input_len = (int) floor (BUFFER_LEN / src_ratio) ;
+ }
+ else
+ { input_len = BUFFER_LEN ;
+ output_len = (int) floor (BUFFER_LEN * src_ratio) ;
+ } ;
+
+ /* Reduce input_len by 10 so output is longer than necessary. */
+ input_len -= 10 ;
+
+ if (output_len > BUFFER_LEN)
+ { printf ("\n\nLine %d : output_len > BUFFER_LEN\n\n", __LINE__) ;
+ exit (1) ;
+ } ;
+
+ memset (&src_data, 0, sizeof (src_data)) ;
+
+ src_data.data_in = input ;
+ src_data.input_frames = input_len ;
+
+ src_data.src_ratio = src_ratio ;
+
+ src_data.data_out = output ;
+ src_data.output_frames = BUFFER_LEN ;
+
+ if ((error = src_simple (&src_data, converter, 1)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ terminate = (int) ceil ((src_ratio >= 1.0) ? src_ratio : 1.0 / src_ratio) ;
+
+ if (fabs (src_data.output_frames_gen - src_ratio * input_len) > 2 * terminate)
+ { printf ("\n\nLine %d : bad output data length %ld should be %d.\n", __LINE__,
+ src_data.output_frames_gen, (int) floor (src_ratio * input_len)) ;
+ printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
+ printf ("\tinput_len : %d\n\toutput_len : %d\n\n", input_len, output_len) ;
+ exit (1) ;
+ } ;
+
+ puts ("ok") ;
+
+ return ;
+} /* simple_test */
+
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/snr_bw_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/snr_bw_test.c
new file mode 100755
index 00000000..223a637f
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/snr_bw_test.c
@@ -0,0 +1,404 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <math.h>
+#include <time.h>
+
+#if (HAVE_FFTW3)
+
+#include <fftw3.h>
+
+#include <samplerate.h>
+
+#include "util.h"
+
+#define BUFFER_LEN 50000
+#define MAX_FREQS 4
+#define MAX_RATIOS 6
+#define MAX_SPEC_LEN (1<<15)
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846264338
+#endif
+
+enum
+{ BOOLEAN_FALSE = 0,
+ BOOLEAN_TRUE = 1
+} ;
+
+typedef struct
+{ int freq_count ;
+ double freqs [MAX_FREQS] ;
+
+ double src_ratio ;
+ int pass_band_peaks ;
+
+ double snr ;
+ double peak_value ;
+} SINGLE_TEST ;
+
+typedef struct
+{ int converter ;
+ int tests ;
+ int do_bandwidth_test ;
+ SINGLE_TEST test_data [10] ;
+} CONVERTER_TEST ;
+
+static double snr_test (SINGLE_TEST *snr_test_data, int number, int converter, int verbose) ;
+static double find_peak (float *output, int output_len) ;
+static double bandwidth_test (int converter, int verbose) ;
+
+int
+main (int argc, char *argv [])
+{ CONVERTER_TEST snr_test_data [] =
+ {
+ { SRC_ZERO_ORDER_HOLD,
+ 8,
+ BOOLEAN_FALSE,
+ { { 1, { 0.01111111111 }, 3.0, 1, 28.0, 1.0 },
+ { 1, { 0.01111111111 }, 0.6, 1, 36.0, 1.0 },
+ { 1, { 0.01111111111 }, 0.3, 1, 36.0, 1.0 },
+ { 1, { 0.01111111111 }, 1.0, 1, 150.0, 1.0 },
+ { 1, { 0.01111111111 }, 1.001, 1, 38.0, 1.0 },
+ { 2, { 0.011111, 0.324 }, 1.9999, 2, 14.0, 1.0 },
+ { 2, { 0.012345, 0.457 }, 0.456789, 1, 12.0, 1.0 },
+ { 1, { 0.3511111111 }, 1.33, 1, 10.0, 1.0 }
+ }
+ },
+
+ { SRC_LINEAR,
+ 8,
+ BOOLEAN_FALSE,
+ { { 1, { 0.01111111111 }, 3.0, 1, 73.0, 1.0 },
+ { 1, { 0.01111111111 }, 0.6, 1, 73.0, 1.0 },
+ { 1, { 0.01111111111 }, 0.3, 1, 73.0, 1.0 },
+ { 1, { 0.01111111111 }, 1.0, 1, 150.0, 1.0 },
+ { 1, { 0.01111111111 }, 1.001, 1, 77.0, 1.0 },
+ { 2, { 0.011111, 0.324 }, 1.9999, 2, 15.0, 0.94 },
+ { 2, { 0.012345, 0.457 }, 0.456789, 1, 25.0, 0.96 },
+ { 1, { 0.3511111111 }, 1.33, 1, 22.0, 0.99 }
+ }
+ },
+
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ { SRC_SINC_FASTEST,
+ 9,
+ BOOLEAN_TRUE,
+ { { 1, { 0.01111111111 }, 3.0, 1, 100.0, 1.0 },
+ { 1, { 0.01111111111 }, 0.6, 1, 99.0, 1.0 },
+ { 1, { 0.01111111111 }, 0.3, 1, 100.0, 1.0 },
+ { 1, { 0.01111111111 }, 1.0, 1, 150.0, 1.0 },
+ { 1, { 0.01111111111 }, 1.001, 1, 100.0, 1.0 },
+ { 2, { 0.011111, 0.324 }, 1.9999, 2, 97.0, 1.0 },
+ { 2, { 0.012345, 0.457 }, 0.456789, 1, 100.0, 0.5 },
+ { 2, { 0.011111, 0.45 }, 0.6, 1, 97.0, 0.5 },
+ { 1, { 0.3511111111 }, 1.33, 1, 97.0, 1.0 }
+ }
+ },
+#endif
+
+#ifdef ENABLE_SINC_MEDIUM_CONVERTER
+ { SRC_SINC_MEDIUM_QUALITY,
+ 9,
+ BOOLEAN_TRUE,
+ { { 1, { 0.01111111111 }, 3.0, 1, 145.0, 1.0 },
+ { 1, { 0.01111111111 }, 0.6, 1, 132.0, 1.0 },
+ { 1, { 0.01111111111 }, 0.3, 1, 138.0, 1.0 },
+ { 1, { 0.01111111111 }, 1.0, 1, 157.0, 1.0 },
+ { 1, { 0.01111111111 }, 1.001, 1, 148.0, 1.0 },
+ { 2, { 0.011111, 0.324 }, 1.9999, 2, 127.0, 1.0 },
+ { 2, { 0.012345, 0.457 }, 0.456789, 1, 123.0, 0.5 },
+ { 2, { 0.011111, 0.45 }, 0.6, 1, 126.0, 0.5 },
+ { 1, { 0.43111111111 }, 1.33, 1, 121.0, 1.0 }
+ }
+ },
+#endif
+
+#ifdef ENABLE_SINC_BEST_CONVERTER
+ { SRC_SINC_BEST_QUALITY,
+ 9,
+ BOOLEAN_TRUE,
+ { { 1, { 0.01111111111 }, 3.0, 1, 147.0, 1.0 },
+ { 1, { 0.01111111111 }, 0.6, 1, 147.0, 1.0 },
+ { 1, { 0.01111111111 }, 0.3, 1, 148.0, 1.0 },
+ { 1, { 0.01111111111 }, 1.0, 1, 155.0, 1.0 },
+ { 1, { 0.01111111111 }, 1.001, 1, 148.0, 1.0 },
+ { 2, { 0.011111, 0.324 }, 1.9999, 2, 146.0, 1.0 },
+ { 2, { 0.012345, 0.457 }, 0.456789, 1, 147.0, 0.5 },
+ { 2, { 0.011111, 0.45 }, 0.6, 1, 144.0, 0.5 },
+ { 1, { 0.43111111111 }, 1.33, 1, 145.0, 1.0 }
+ }
+ },
+#endif
+
+ } ; /* snr_test_data */
+
+ double best_snr, snr, freq3dB ;
+ int j, k, converter, verbose = 0 ;
+
+ if (argc == 2 && strcmp (argv [1], "--verbose") == 0)
+ verbose = 1 ;
+
+ puts ("") ;
+
+ for (j = 0 ; j < ARRAY_LEN (snr_test_data) ; j++)
+ { best_snr = 5000.0 ;
+
+ converter = snr_test_data [j].converter ;
+
+ printf (" Converter %d : %s\n", converter, src_get_name (converter)) ;
+ printf (" %s\n", src_get_description (converter)) ;
+
+ for (k = 0 ; k < snr_test_data [j].tests ; k++)
+ { snr = snr_test (&(snr_test_data [j].test_data [k]), k, converter, verbose) ;
+ if (best_snr > snr)
+ best_snr = snr ;
+ } ;
+
+ printf (" Worst case Signal-to-Noise Ratio : %.2f dB.\n", best_snr) ;
+
+ if (snr_test_data [j].do_bandwidth_test == BOOLEAN_FALSE)
+ { puts (" Bandwith test not performed on this converter.\n") ;
+ continue ;
+ }
+
+ freq3dB = bandwidth_test (converter, verbose) ;
+
+ printf (" Measured -3dB rolloff point : %5.2f %%.\n\n", freq3dB) ;
+ } ;
+
+ fftw_cleanup () ;
+
+ return 0 ;
+} /* main */
+
+/*==============================================================================
+*/
+
+static double
+snr_test (SINGLE_TEST *test_data, int number, int converter, int verbose)
+{ static float data [BUFFER_LEN + 1] ;
+ static float output [MAX_SPEC_LEN] ;
+
+ SRC_STATE *src_state ;
+ SRC_DATA src_data ;
+
+ double output_peak, snr ;
+ int k, output_len, input_len, error ;
+
+ if (verbose != 0)
+ { printf ("\tSignal-to-Noise Ratio Test %d.\n"
+ "\t=====================================\n", number) ;
+ printf ("\tFrequencies : [ ") ;
+ for (k = 0 ; k < test_data->freq_count ; k++)
+ printf ("%6.4f ", test_data->freqs [k]) ;
+
+ printf ("]\n\tSRC Ratio : %8.4f\n", test_data->src_ratio) ;
+ }
+ else
+ { printf ("\tSignal-to-Noise Ratio Test %d : ", number) ;
+ fflush (stdout) ;
+ } ;
+
+ /* Set up the output array. */
+ if (test_data->src_ratio >= 1.0)
+ { output_len = MAX_SPEC_LEN ;
+ input_len = (int) ceil (MAX_SPEC_LEN / test_data->src_ratio) ;
+ if (input_len > BUFFER_LEN)
+ input_len = BUFFER_LEN ;
+ }
+ else
+ { input_len = BUFFER_LEN ;
+ output_len = (int) ceil (BUFFER_LEN * test_data->src_ratio) ;
+ output_len &= ((~0u) << 4) ;
+ if (output_len > MAX_SPEC_LEN)
+ output_len = MAX_SPEC_LEN ;
+ input_len = (int) ceil (output_len / test_data->src_ratio) ;
+ } ;
+
+ memset (output, 0, sizeof (output)) ;
+
+ /* Generate input data array. */
+ gen_windowed_sines (test_data->freq_count, test_data->freqs, 1.0, data, input_len) ;
+
+ /* Perform sample rate conversion. */
+ if ((src_state = src_new (converter, 1, &error)) == NULL)
+ { printf ("\n\nLine %d : src_new() failed : %s.\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ src_data.end_of_input = 1 ; /* Only one buffer worth of input. */
+
+ src_data.data_in = data ;
+ src_data.input_frames = input_len ;
+
+ src_data.src_ratio = test_data->src_ratio ;
+
+ src_data.data_out = output ;
+ src_data.output_frames = output_len ;
+
+ if ((error = src_process (src_state, &src_data)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ src_state = src_delete (src_state) ;
+
+ if (verbose != 0)
+ printf ("\tOutput Len : %ld\n", src_data.output_frames_gen) ;
+
+ if (abs ((int) (src_data.output_frames_gen - output_len)) > 4)
+ { printf ("\n\nLine %d : output data length should be %d.\n\n", __LINE__, output_len) ;
+ exit (1) ;
+ } ;
+
+ /* Check output peak. */
+ output_peak = find_peak (output, src_data.output_frames_gen) ;
+
+ if (verbose != 0)
+ printf ("\tOutput Peak : %6.4f\n", output_peak) ;
+
+ if (fabs (output_peak - test_data->peak_value) > 0.01)
+ { printf ("\n\nLine %d : output peak (%6.4f) should be %6.4f\n\n", __LINE__, output_peak, test_data->peak_value) ;
+ save_oct_float ("snr_test.dat", data, BUFFER_LEN, output, output_len) ;
+ exit (1) ;
+ } ;
+
+ /* Calculate signal-to-noise ratio. */
+ snr = calculate_snr (output, src_data.output_frames_gen, test_data->pass_band_peaks) ;
+
+ if (snr < 0.0)
+ { /* An error occurred. */
+ save_oct_float ("snr_test.dat", data, BUFFER_LEN, output, src_data.output_frames_gen) ;
+ exit (1) ;
+ } ;
+
+ if (verbose != 0)
+ printf ("\tSNR Ratio : %.2f dB\n", snr) ;
+
+ if (snr < test_data->snr)
+ { printf ("\n\nLine %d : SNR (%5.2f) should be > %6.2f dB\n\n", __LINE__, snr, test_data->snr) ;
+ exit (1) ;
+ } ;
+
+ if (verbose != 0)
+ puts ("\t-------------------------------------\n\tPass\n") ;
+ else
+ puts ("Pass") ;
+
+ return snr ;
+} /* snr_test */
+
+static double
+find_peak (float *data, int len)
+{ double peak = 0.0 ;
+ int k = 0 ;
+
+ for (k = 0 ; k < len ; k++)
+ if (fabs (data [k]) > peak)
+ peak = fabs (data [k]) ;
+
+ return peak ;
+} /* find_peak */
+
+
+static double
+find_attenuation (double freq, int converter, int verbose)
+{ static float input [BUFFER_LEN] ;
+ static float output [2 * BUFFER_LEN] ;
+
+ SRC_DATA src_data ;
+ double output_peak ;
+ int error ;
+
+ gen_windowed_sines (1, &freq, 1.0, input, BUFFER_LEN) ;
+
+ src_data.end_of_input = 1 ; /* Only one buffer worth of input. */
+
+ src_data.data_in = input ;
+ src_data.input_frames = BUFFER_LEN ;
+
+ src_data.src_ratio = 1.999 ;
+
+ src_data.data_out = output ;
+ src_data.output_frames = ARRAY_LEN (output) ;
+
+ if ((error = src_simple (&src_data, converter, 1)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ output_peak = find_peak (output, ARRAY_LEN (output)) ;
+
+ if (verbose)
+ printf ("\tFreq : %6f InPeak : %6f OutPeak : %6f Atten : %6.2f dB\n",
+ freq, 1.0, output_peak, 20.0 * log10 (1.0 / output_peak)) ;
+
+ return 20.0 * log10 (1.0 / output_peak) ;
+} /* find_attenuation */
+
+static double
+bandwidth_test (int converter, int verbose)
+{ double f1, f2, a1, a2 ;
+ double freq, atten ;
+
+ f1 = 0.35 ;
+ a1 = find_attenuation (f1, converter, verbose) ;
+
+ f2 = 0.495 ;
+ a2 = find_attenuation (f2, converter, verbose) ;
+
+ if (a1 > 3.0 || a2 < 3.0)
+ { printf ("\n\nLine %d : cannot bracket 3dB point.\n\n", __LINE__) ;
+ exit (1) ;
+ } ;
+
+ while (a2 - a1 > 1.0)
+ { freq = f1 + 0.5 * (f2 - f1) ;
+ atten = find_attenuation (freq, converter, verbose) ;
+
+ if (atten < 3.0)
+ { f1 = freq ;
+ a1 = atten ;
+ }
+ else
+ { f2 = freq ;
+ a2 = atten ;
+ } ;
+ } ;
+
+ freq = f1 + (3.0 - a1) * (f2 - f1) / (a2 - a1) ;
+
+ return 200.0 * freq ;
+} /* bandwidth_test */
+
+#else /* (HAVE_FFTW3) == 0 */
+
+/* Alternative main function when librfftw is not available. */
+
+int
+main (void)
+{ puts ("\n"
+ "****************************************************************\n"
+ " This test cannot be run without FFTW (http://www.fftw.org/).\n"
+ " Both the real and the complex versions of the library are\n"
+ " required.") ;
+ puts ("****************************************************************\n") ;
+
+ return 0 ;
+} /* main */
+
+#endif
+
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/src-evaluate.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/src-evaluate.c
new file mode 100755
index 00000000..d55d6483
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/src-evaluate.c
@@ -0,0 +1,530 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <string.h>
+#include <ctype.h>
+
+#if defined(_WIN32)
+#define popen _popen
+#define pclose _pclose
+#endif
+
+#if (HAVE_FFTW3 && HAVE_SNDFILE && HAVE_SYS_TIMES_H)
+
+#include <time.h>
+#include <sys/times.h>
+
+#include <sndfile.h>
+#include <math.h>
+#include <sys/utsname.h>
+
+#include "util.h"
+
+#define MAX_FREQS 4
+#define BUFFER_LEN 80000
+
+#define SAFE_STRNCAT(dest,src,len) \
+ { int safe_strncat_count ; \
+ safe_strncat_count = (len) - strlen (dest) - 1 ; \
+ strncat ((dest), (src), safe_strncat_count) ; \
+ (dest) [(len) - 1] = 0 ; \
+ } ;
+
+typedef struct
+{ int freq_count ;
+ double freqs [MAX_FREQS] ;
+
+ int output_samplerate ;
+ int pass_band_peaks ;
+
+ double peak_value ;
+} SNR_TEST ;
+
+typedef struct
+{ const char *progname ;
+ const char *version_cmd ;
+ const char *version_start ;
+ const char *convert_cmd ;
+ int format ;
+} RESAMPLE_PROG ;
+
+static char *get_progname (char *) ;
+static void usage_exit (const char *, const RESAMPLE_PROG *prog, int count) ;
+static void measure_program (const RESAMPLE_PROG *prog, int verbose) ;
+static void generate_source_wav (const char *filename, const double *freqs, int freq_count, int format) ;
+static const char* get_machine_details (void) ;
+
+static char version_string [512] ;
+
+int
+main (int argc, char *argv [])
+{ static RESAMPLE_PROG resample_progs [] =
+ { { "sndfile-resample",
+ "examples/sndfile-resample --version",
+ "libsamplerate",
+ "examples/sndfile-resample --max-speed -c 0 -to %d source.wav destination.wav",
+ SF_FORMAT_WAV | SF_FORMAT_PCM_32
+ },
+ { "sox",
+ "sox -h 2>&1",
+ "sox",
+ "sox source.wav -r %d destination.wav resample 0.835",
+ SF_FORMAT_WAV | SF_FORMAT_PCM_32
+ },
+ { "ResampAudio",
+ "ResampAudio --version",
+ "ResampAudio",
+ "ResampAudio -f cutoff=0.41,atten=100,ratio=128 -s %d source.wav destination.wav",
+ SF_FORMAT_WAV | SF_FORMAT_PCM_32
+ },
+
+ /*-
+ { /+*
+ ** The Shibatch converter doesn't work for all combinations of
+ ** source and destination sample rates. Therefore it can't be
+ ** included in this test.
+ *+/
+ "shibatch",
+ "ssrc",
+ "Shibatch",
+ "ssrc --rate %d source.wav destination.wav",
+ SF_FORMAT_WAV | SF_FORMAT_PCM_32
+ },-*/
+
+ /*-
+ { /+*
+ ** The resample program is not able to match the bandwidth and SNR
+ ** specs or sndfile-resample and hence will not be tested.
+ *+/
+ "resample",
+ "resample -version",
+ "resample",
+ "resample -to %d source.wav destination.wav",
+ SF_FORMAT_WAV | SF_FORMAT_FLOAT
+ },-*/
+
+ /*-
+ { "mplayer",
+ "mplayer -v 2>&1",
+ "MPlayer ",
+ "mplayer -ao pcm -srate %d source.wav >/dev/null 2>&1 && mv audiodump.wav destination.wav",
+ SF_FORMAT_WAV | SF_FORMAT_PCM_32
+ },-*/
+
+ } ; /* resample_progs */
+
+ char *progname ;
+ int prog = 0, verbose = 0 ;
+
+ progname = get_progname (argv [0]) ;
+
+ printf ("\n %s : evaluate a sample rate converter.\n", progname) ;
+
+ if (argc == 3 && strcmp ("--verbose", argv [1]) == 0)
+ { verbose = 1 ;
+ prog = atoi (argv [2]) ;
+ }
+ else if (argc == 2)
+ { verbose = 0 ;
+ prog = atoi (argv [1]) ;
+ }
+ else
+ usage_exit (progname, resample_progs, ARRAY_LEN (resample_progs)) ;
+
+ if (prog < 0 || prog >= ARRAY_LEN (resample_progs))
+ usage_exit (progname, resample_progs, ARRAY_LEN (resample_progs)) ;
+
+ measure_program (& (resample_progs [prog]), verbose) ;
+
+ puts ("") ;
+
+ return 0 ;
+} /* main */
+
+/*==============================================================================
+*/
+
+static char *
+get_progname (char *progname)
+{ char *cptr ;
+
+ if ((cptr = strrchr (progname, '/')) != NULL)
+ progname = cptr + 1 ;
+
+ if ((cptr = strrchr (progname, '\\')) != NULL)
+ progname = cptr + 1 ;
+
+ return progname ;
+} /* get_progname */
+
+static void
+usage_exit (const char *progname, const RESAMPLE_PROG *prog, int count)
+{ int k ;
+
+ printf ("\n Usage : %s <number>\n\n", progname) ;
+
+ puts (" where <number> specifies the program to test:\n") ;
+
+ for (k = 0 ; k < count ; k++)
+ printf (" %d : %s\n", k, prog [k].progname) ;
+
+ puts ("\n"
+ " Obviously to test a given program you have to have it available on\n"
+ " your system. See http://libsndfile.github.io/libsamplerate/quality.html for\n"
+ " the download location of these programs.\n") ;
+
+ exit (1) ;
+} /* usage_exit */
+
+static const char*
+get_machine_details (void)
+{ static char namestr [262] ;
+
+ struct utsname name ;
+
+ if (uname (&name) != 0)
+ { snprintf (namestr, sizeof (namestr), "Unknown") ;
+ return namestr ;
+ } ;
+
+ snprintf (namestr, sizeof (namestr), "%s (%s %s %s)", name.nodename,
+ name.machine, name.sysname, name.release) ;
+
+ return namestr ;
+} /* get_machine_details */
+
+
+/*==============================================================================
+*/
+
+static void
+get_version_string (const RESAMPLE_PROG *prog)
+{ FILE *file ;
+ char *cptr ;
+
+ /* Default. */
+ snprintf (version_string, sizeof (version_string), "no version") ;
+
+ if (prog->version_cmd == NULL)
+ return ;
+
+ if ((file = popen (prog->version_cmd, "r")) == NULL)
+ return ;
+
+ while ((cptr = fgets (version_string, sizeof (version_string), file)) != NULL)
+ {
+ if (strstr (cptr, prog->version_start) != NULL)
+ break ;
+
+ version_string [0] = 0 ;
+ } ;
+
+ pclose (file) ;
+
+ /* Remove trailing newline. */
+ if ((cptr = strchr (version_string, '\n')) != NULL)
+ cptr [0] = 0 ;
+
+ /* Remove leading whitespace from version string. */
+ cptr = version_string ;
+ while (cptr [0] != 0 && isspace (cptr [0]))
+ cptr ++ ;
+
+ if (cptr != version_string)
+ { strncpy (version_string, cptr, sizeof (version_string) - 1) ;
+ version_string [sizeof (version_string) - 1] = 0 ;
+ } ;
+
+ return ;
+} /* get_version_string */
+
+static void
+generate_source_wav (const char *filename, const double *freqs, int freq_count, int format)
+{ static float buffer [BUFFER_LEN] ;
+
+ SNDFILE *sndfile ;
+ SF_INFO sfinfo ;
+
+ sfinfo.channels = 1 ;
+ sfinfo.samplerate = 44100 ;
+ sfinfo.format = format ;
+
+ if ((sndfile = sf_open (filename, SFM_WRITE, &sfinfo)) == NULL)
+ { printf ("Line %d : cound not open '%s' : %s\n", __LINE__, filename, sf_strerror (NULL)) ;
+ exit (1) ;
+ } ;
+
+ sf_command (sndfile, SFC_SET_ADD_PEAK_CHUNK, NULL, SF_FALSE) ;
+
+ gen_windowed_sines (freq_count, freqs, 0.9, buffer, ARRAY_LEN (buffer)) ;
+
+ if (sf_write_float (sndfile, buffer, ARRAY_LEN (buffer)) != ARRAY_LEN (buffer))
+ { printf ("Line %d : sf_write_float short write.\n", __LINE__) ;
+ exit (1) ;
+ } ;
+
+ sf_close (sndfile) ;
+} /* generate_source_wav */
+
+static double
+measure_destination_wav (char *filename, int *output_samples, int expected_peaks)
+{ static float buffer [250000] ;
+
+ SNDFILE *sndfile ;
+ SF_INFO sfinfo ;
+ double snr ;
+
+ if ((sndfile = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
+ { printf ("Line %d : Cound not open '%s' : %s\n", __LINE__, filename, sf_strerror (NULL)) ;
+ exit (1) ;
+ } ;
+
+ if (sfinfo.channels != 1)
+ { printf ("Line %d : Bad channel count (%d). Should be 1.\n", __LINE__, sfinfo.channels) ;
+ exit (1) ;
+ } ;
+
+ if (sfinfo.frames > ARRAY_LEN (buffer))
+ { printf ("Line %d : Too many frames (%ld) of data in file.\n", __LINE__, (long) sfinfo.frames) ;
+ exit (1) ;
+ } ;
+
+ *output_samples = (int) sfinfo.frames ;
+
+ if (sf_read_float (sndfile, buffer, sfinfo.frames) != sfinfo.frames)
+ { printf ("Line %d : Bad read.\n", __LINE__) ;
+ exit (1) ;
+ } ;
+
+ sf_close (sndfile) ;
+
+ snr = calculate_snr (buffer, sfinfo.frames, expected_peaks) ;
+
+ return snr ;
+} /* measure_desination_wav */
+
+static double
+measure_snr (const RESAMPLE_PROG *prog, int *output_samples, int verbose)
+{ static SNR_TEST snr_test [] =
+ {
+ { 1, { 0.211111111111 }, 48000, 1, 1.0 },
+ { 1, { 0.011111111111 }, 132301, 1, 1.0 },
+ { 1, { 0.111111111111 }, 92301, 1, 1.0 },
+ { 1, { 0.011111111111 }, 26461, 1, 1.0 },
+ { 1, { 0.011111111111 }, 13231, 1, 1.0 },
+ { 1, { 0.011111111111 }, 44101, 1, 1.0 },
+ { 2, { 0.311111, 0.49 }, 78199, 2, 1.0 },
+ { 2, { 0.011111, 0.49 }, 12345, 1, 0.5 },
+ { 2, { 0.0123456, 0.4 }, 20143, 1, 0.5 },
+ { 2, { 0.0111111, 0.4 }, 26461, 1, 0.5 },
+ { 1, { 0.381111111111 }, 58661, 1, 1.0 }
+ } ; /* snr_test */
+ static char command [256] ;
+
+ double snr, worst_snr = 500.0 ;
+ int k , retval, sample_count ;
+
+ *output_samples = 0 ;
+
+ for (k = 0 ; k < ARRAY_LEN (snr_test) ; k++)
+ { remove ("source.wav") ;
+ remove ("destination.wav") ;
+
+ if (verbose)
+ printf (" SNR test #%d : ", k) ;
+ fflush (stdout) ;
+ generate_source_wav ("source.wav", snr_test [k].freqs, snr_test [k].freq_count, prog->format) ;
+
+ snprintf (command, sizeof (command), prog->convert_cmd, snr_test [k].output_samplerate) ;
+ SAFE_STRNCAT (command, " >/dev/null 2>&1", sizeof (command)) ;
+ if ((retval = system (command)) != 0)
+ printf ("system returned %d\n", retval) ;
+
+ snr = measure_destination_wav ("destination.wav", &sample_count, snr_test->pass_band_peaks) ;
+
+ *output_samples += sample_count ;
+
+ if (fabs (snr) < fabs (worst_snr))
+ worst_snr = fabs (snr) ;
+
+ if (verbose)
+ printf ("%6.2f dB\n", snr) ;
+ } ;
+
+ return worst_snr ;
+} /* measure_snr */
+
+/*------------------------------------------------------------------------------
+*/
+
+static double
+measure_destination_peak (const char *filename)
+{ static float data [2 * BUFFER_LEN] ;
+ SNDFILE *sndfile ;
+ SF_INFO sfinfo ;
+ double peak = 0.0 ;
+ int k = 0 ;
+
+ if ((sndfile = sf_open (filename, SFM_READ, &sfinfo)) == NULL)
+ { printf ("Line %d : failed to open file %s\n", __LINE__, filename) ;
+ exit (1) ;
+ } ;
+
+ if (sfinfo.channels != 1)
+ { printf ("Line %d : bad channel count.\n", __LINE__) ;
+ exit (1) ;
+ } ;
+
+ if (sfinfo.frames > ARRAY_LEN (data) + 4 || sfinfo.frames < ARRAY_LEN (data) - 100)
+ { printf ("Line %d : bad frame count (got %d, expected %d).\n", __LINE__, (int) sfinfo.frames, ARRAY_LEN (data)) ;
+ exit (1) ;
+ } ;
+
+ if (sf_read_float (sndfile, data, sfinfo.frames) != sfinfo.frames)
+ { printf ("Line %d : bad read.\n", __LINE__) ;
+ exit (1) ;
+ } ;
+
+ sf_close (sndfile) ;
+
+ for (k = 0 ; k < (int) sfinfo.frames ; k++)
+ if (fabs (data [k]) > peak)
+ peak = fabs (data [k]) ;
+
+ return peak ;
+} /* measure_destination_peak */
+
+static double
+find_attenuation (double freq, const RESAMPLE_PROG *prog, int verbose)
+{ static char command [256] ;
+ double output_peak ;
+ int retval ;
+ char *filename ;
+
+ filename = "destination.wav" ;
+
+ generate_source_wav ("source.wav", &freq, 1, prog->format) ;
+
+ remove (filename) ;
+
+ snprintf (command, sizeof (command), prog->convert_cmd, 88189) ;
+ SAFE_STRNCAT (command, " >/dev/null 2>&1", sizeof (command)) ;
+ if ((retval = system (command)) != 0)
+ printf ("system returned %d\n", retval) ;
+
+ output_peak = measure_destination_peak (filename) ;
+
+ if (verbose)
+ printf (" freq : %f peak : %f\n", freq, output_peak) ;
+
+ return fabs (20.0 * log10 (output_peak)) ;
+} /* find_attenuation */
+
+static double
+bandwidth_test (const RESAMPLE_PROG *prog, int verbose)
+{ double f1, f2, a1, a2 ;
+ double freq, atten ;
+
+ f1 = 0.35 ;
+ a1 = find_attenuation (f1, prog, verbose) ;
+
+ f2 = 0.49999 ;
+ a2 = find_attenuation (f2, prog, verbose) ;
+
+
+ if (fabs (a1) < 1e-2 && a2 < 3.0)
+ return -1.0 ;
+
+ if (a1 > 3.0 || a2 < 3.0)
+ { printf ("\n\nLine %d : cannot bracket 3dB point.\n\n", __LINE__) ;
+ exit (1) ;
+ } ;
+
+ while (a2 - a1 > 1.0)
+ { freq = f1 + 0.5 * (f2 - f1) ;
+ atten = find_attenuation (freq, prog, verbose) ;
+
+ if (atten < 3.0)
+ { f1 = freq ;
+ a1 = atten ;
+ }
+ else
+ { f2 = freq ;
+ a2 = atten ;
+ } ;
+ } ;
+
+ freq = f1 + (3.0 - a1) * (f2 - f1) / (a2 - a1) ;
+
+ return 200.0 * freq ;
+} /* bandwidth_test */
+
+static void
+measure_program (const RESAMPLE_PROG *prog, int verbose)
+{ double snr, bandwidth, conversion_rate ;
+ int output_samples ;
+ struct tms time_data ;
+ time_t time_now ;
+
+ printf ("\n Machine : %s\n", get_machine_details ()) ;
+ time_now = time (NULL) ;
+ printf (" Date : %s", ctime (&time_now)) ;
+
+ get_version_string (prog) ;
+ printf (" Program : %s\n", version_string) ;
+ printf (" Command : %s\n\n", prog->convert_cmd) ;
+
+ snr = measure_snr (prog, &output_samples, verbose) ;
+
+ printf (" Worst case SNR : %6.2f dB\n", snr) ;
+
+ times (&time_data) ;
+
+ conversion_rate = (1.0 * output_samples * sysconf (_SC_CLK_TCK)) / time_data.tms_cutime ;
+
+ printf (" Conversion rate : %5.0f samples/sec\n", conversion_rate) ;
+
+ bandwidth = bandwidth_test (prog, verbose) ;
+
+ if (bandwidth > 0.0)
+ printf (" Measured bandwidth : %5.2f %%\n", bandwidth) ;
+ else
+ printf (" Could not measure bandwidth (no -3dB point found).\n") ;
+
+ return ;
+} /* measure_program */
+
+/*##############################################################################
+*/
+
+#else
+
+int
+main (void)
+{ puts ("\n"
+ "****************************************************************\n"
+ " This program has been compiled without :\n"
+ " 1) FFTW (http://www.fftw.org/).\n"
+ " 2) libsndfile (http://www.zip.com.au/~erikd/libsndfile/).\n"
+ " Without these two libraries there is not much it can do.\n"
+ "****************************************************************\n") ;
+
+ return 0 ;
+} /* main */
+
+#endif /* (HAVE_FFTW3 && HAVE_SNDFILE) */
+
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/streaming_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/streaming_test.c
new file mode 100755
index 00000000..45ad2516
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/streaming_test.c
@@ -0,0 +1,149 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <math.h>
+
+#include <samplerate.h>
+
+#include "util.h"
+
+#define BUFFER_LEN (1<<15)
+
+#define BLOCK_LEN 100
+
+static void stream_test (int converter, double ratio) ;
+
+int
+main (void)
+{ static double src_ratios [] =
+ { 0.3, 0.9, 1.1, 3.0
+ } ;
+
+ int k ;
+
+ puts ("\n Zero Order Hold interpolator:") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ stream_test (SRC_ZERO_ORDER_HOLD, src_ratios [k]) ;
+
+ puts ("\n Linear interpolator:") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ stream_test (SRC_LINEAR, src_ratios [k]) ;
+
+ puts ("\n Sinc interpolator:") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ stream_test (SRC_SINC_FASTEST, src_ratios [k]) ;
+
+ puts ("") ;
+
+ return 0 ;
+} /* main */
+
+static void
+stream_test (int converter, double src_ratio)
+{ static float input [BUFFER_LEN], output [BUFFER_LEN] ;
+
+ SRC_STATE *src_state ;
+ SRC_DATA src_data ;
+
+ int input_len, output_len, current_in, current_out ;
+ int error, terminate ;
+
+ printf ("\tstreaming_test (SRC ratio = %6.4f) ........... ", src_ratio) ;
+ fflush (stdout) ;
+
+ /* Calculate maximun input and output lengths. */
+ if (src_ratio >= 1.0)
+ { output_len = BUFFER_LEN ;
+ input_len = (int) floor (BUFFER_LEN / src_ratio) ;
+ }
+ else
+ { input_len = BUFFER_LEN ;
+ output_len = (int) floor (BUFFER_LEN * src_ratio) ;
+ } ;
+
+ /* Reduce input_len by 10 so output is longer than necessary. */
+ input_len -= 10 ;
+
+ if (output_len > BUFFER_LEN)
+ { printf ("\n\nLine %d : output_len > BUFFER_LEN\n\n", __LINE__) ;
+ exit (1) ;
+ } ;
+
+ current_in = current_out = 0 ;
+
+ /* Perform sample rate conversion. */
+ if ((src_state = src_new (converter, 1, &error)) == NULL)
+ { printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ src_data.end_of_input = 0 ; /* Set this later. */
+
+ src_data.data_in = input ;
+ src_data.input_frames = BLOCK_LEN ;
+
+ src_data.src_ratio = src_ratio ;
+
+ src_data.data_out = output ;
+ src_data.output_frames = BLOCK_LEN ;
+
+ while (1)
+ { if ((error = src_process (src_state, &src_data)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+
+printf ("src_data.input_frames : %ld\n", src_data.input_frames) ;
+printf ("src_data.output_frames : %ld\n", src_data.output_frames) ;
+
+ exit (1) ;
+ } ;
+
+ if (src_data.end_of_input && src_data.output_frames_gen == 0)
+ break ;
+
+ current_in += src_data.input_frames_used ;
+ current_out += src_data.output_frames_gen ;
+
+ src_data.data_in += src_data.input_frames_used ;
+ src_data.data_out += src_data.output_frames_gen ;
+
+ src_data.input_frames = MIN (BLOCK_LEN, input_len - current_in) ;
+ src_data.output_frames = MIN (BLOCK_LEN, output_len - current_out) ;
+
+ src_data.end_of_input = (current_in >= input_len) ? 1 : 0 ;
+ } ;
+
+ src_state = src_delete (src_state) ;
+
+ terminate = (int) ceil ((src_ratio >= 1.0) ? src_ratio : 1.0 / src_ratio) ;
+
+ if (fabs (current_out - src_ratio * input_len) > 2 * terminate)
+ { printf ("\n\nLine %d : bad output data length %d should be %d.\n", __LINE__,
+ current_out, (int) floor (src_ratio * input_len)) ;
+ printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
+ printf ("\tinput_len : %d\n\toutput_len : %d\n\n", input_len, output_len) ;
+ exit (1) ;
+ } ;
+
+ if (current_in != input_len)
+ { printf ("\n\nLine %d : unused input.\n", __LINE__) ;
+ printf ("\tinput_len : %d\n", input_len) ;
+ printf ("\tinput_frames_used : %d\n\n", current_in) ;
+ exit (1) ;
+ } ;
+
+ puts ("ok") ;
+
+ return ;
+} /* stream_test */
+
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/termination_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/termination_test.c
new file mode 100755
index 00000000..0b27a217
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/termination_test.c
@@ -0,0 +1,342 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+
+#include <samplerate.h>
+
+#include "util.h"
+
+#define SHORT_BUFFER_LEN 2048
+#define LONG_BUFFER_LEN ((1 << 16) - 20)
+
+#ifdef ENABLE_SINC_FAST_CONVERTER
+static void simple_test (int converter) ;
+#endif
+static void stream_test (int converter, double ratio) ;
+static void init_term_test (int converter, double ratio) ;
+
+static int next_block_length (int reset) ;
+
+int
+main (void)
+{ static double src_ratios [] =
+ { 0.999900, 1.000100, 0.789012, 1.200000, 0.333333, 3.100000,
+ 0.125000, 8.000000, 0.099900, 9.990000, 0.100000, 10.00000
+ } ;
+
+ int k ;
+
+ puts ("\n Zero Order Hold interpolator:") ;
+
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ init_term_test (SRC_ZERO_ORDER_HOLD, src_ratios [k]) ;
+ puts ("") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ stream_test (SRC_ZERO_ORDER_HOLD, src_ratios [k]) ;
+
+
+ puts ("\n Linear interpolator:") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ init_term_test (SRC_LINEAR, src_ratios [k]) ;
+ puts ("") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ stream_test (SRC_LINEAR, src_ratios [k]) ;
+
+
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ puts ("\n Sinc interpolator:") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ init_term_test (SRC_SINC_FASTEST, src_ratios [k]) ;
+ puts ("") ;
+ for (k = 0 ; k < ARRAY_LEN (src_ratios) ; k++)
+ stream_test (SRC_SINC_FASTEST, src_ratios [k]) ;
+
+ puts ("") ;
+
+ simple_test (SRC_SINC_FASTEST) ;
+#endif
+
+ return 0 ;
+} /* main */
+
+#ifdef ENABLE_SINC_FAST_CONVERTER
+static void
+simple_test (int converter)
+{
+ // MSVC doesn't support variable-length arrays
+ #define ilen 199030
+ #define olen 1000
+ int error ;
+
+ {
+ float in [ilen] ;
+ float out [olen] ;
+ double ratio = (1.0 * olen) / ilen ;
+ SRC_DATA src_data =
+ { in, out,
+ ilen, olen,
+ 0, 0, 0,
+ ratio
+ } ;
+
+ error = src_simple (&src_data, converter, 1) ;
+ if (error)
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+ } ;
+
+ return ;
+} /* simple_test */
+#endif
+
+static void
+init_term_test (int converter, double src_ratio)
+{ static float input [SHORT_BUFFER_LEN], output [SHORT_BUFFER_LEN] ;
+
+ SRC_DATA src_data ;
+
+ int k, input_len, output_len, error, terminate ;
+
+ printf ("\tinit_term_test (SRC ratio = %7.4f) .......... ", src_ratio) ;
+ fflush (stdout) ;
+
+ /* Calculate maximun input and output lengths. */
+ if (src_ratio >= 1.0)
+ { output_len = SHORT_BUFFER_LEN ;
+ input_len = (int) floor (SHORT_BUFFER_LEN / src_ratio) ;
+ }
+ else
+ { input_len = SHORT_BUFFER_LEN ;
+ output_len = (int) floor (SHORT_BUFFER_LEN * src_ratio) ;
+ } ;
+
+ /* Reduce input_len by 10 so output is longer than necessary. */
+ input_len -= 10 ;
+
+ for (k = 0 ; k < ARRAY_LEN (input) ; k++)
+ input [k] = 1.0 ;
+
+ if (output_len > SHORT_BUFFER_LEN)
+ { printf ("\n\nLine %d : output_len > SHORT_BUFFER_LEN\n\n", __LINE__) ;
+ exit (1) ;
+ } ;
+
+ src_data.data_in = input ;
+ src_data.input_frames = input_len ;
+
+ src_data.src_ratio = src_ratio ;
+
+ src_data.data_out = output ;
+ src_data.output_frames = SHORT_BUFFER_LEN ;
+
+ if ((error = src_simple (&src_data, converter, 1)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ terminate = (int) ceil ((src_ratio >= 1.0) ? 1 : 1.0 / src_ratio) ;
+
+ if (fabs (src_ratio * input_len - src_data.output_frames_gen) > terminate)
+ { printf ("\n\nLine %d : Bad output frame count.\n\n", __LINE__) ;
+ printf ("\tterminate : %d\n", terminate) ;
+ printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
+ printf ("\tinput_len : %d\n"
+ "\tinput_len * src_ratio : %f\n", input_len, input_len * src_ratio) ;
+ printf ("\toutput_frames_gen : %ld\n\n", src_data.output_frames_gen) ;
+ exit (1) ;
+ } ;
+
+ if (labs (src_data.input_frames_used - input_len) > 1)
+ { printf ("\n\nLine %d : input_frames_used should be %d, is %ld.\n\n",
+ __LINE__, input_len, src_data.input_frames_used) ;
+ printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
+ printf ("\tinput_len : %d\n\tinput_used : %ld\n\n", input_len, src_data.input_frames_used) ;
+ exit (1) ;
+ } ;
+
+ if (fabs (output [0]) < 0.1)
+ { printf ("\n\nLine %d : First output sample is bad.\n\n", __LINE__) ;
+ printf ("\toutput [0] == %f\n\n", output [0]) ;
+ exit (1) ;
+ }
+
+ puts ("ok") ;
+
+ return ;
+} /* init_term_test */
+
+static void
+stream_test (int converter, double src_ratio)
+{ static float input [LONG_BUFFER_LEN], output [LONG_BUFFER_LEN] ;
+
+ SRC_STATE *src_state ;
+ SRC_DATA src_data ;
+
+ int input_len, output_len, current_in, current_out ;
+ int k, error, terminate ;
+
+ printf ("\tstream_test (SRC ratio = %7.4f) .......... ", src_ratio) ;
+ fflush (stdout) ;
+
+/* Erik */
+for (k = 0 ; k < LONG_BUFFER_LEN ; k++) input [k] = k * 1.0f ;
+
+ /* Calculate maximun input and output lengths. */
+ if (src_ratio >= 1.0)
+ { output_len = LONG_BUFFER_LEN ;
+ input_len = (int) floor (LONG_BUFFER_LEN / src_ratio) ;
+ }
+ else
+ { input_len = LONG_BUFFER_LEN ;
+ output_len = (int) floor (LONG_BUFFER_LEN * src_ratio) ;
+ } ;
+
+ /* Reduce input_len by 10 so output is longer than necessary. */
+ input_len -= 20 ;
+
+ if (output_len > LONG_BUFFER_LEN)
+ { printf ("\n\nLine %d : output_len > LONG_BUFFER_LEN\n\n", __LINE__) ;
+ exit (1) ;
+ } ;
+
+ current_in = current_out = 0 ;
+
+ /* Perform sample rate conversion. */
+ if ((src_state = src_new (converter, 1, &error)) == NULL)
+ { printf ("\n\nLine %d : src_new() failed : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ src_data.end_of_input = 0 ; /* Set this later. */
+
+ src_data.data_in = input ;
+
+ src_data.src_ratio = src_ratio ;
+
+ src_data.data_out = output ;
+ src_data.output_frames = ARRAY_LEN (output) / 10 ;
+
+ terminate = 1 + (int) ceil ((src_ratio >= 1.0) ? src_ratio : 1.0 / src_ratio) ;
+
+ while (1)
+ {
+ src_data.input_frames = next_block_length (0) ;
+ src_data.input_frames = MIN (src_data.input_frames, input_len - current_in) ;
+
+ src_data.output_frames = ARRAY_LEN (output) - current_out ;
+ /*-Erik MIN (src_data.output_frames, output_len - current_out) ;-*/
+
+ src_data.end_of_input = (current_in >= input_len) ? 1 : 0 ;
+
+ if ((error = src_process (src_state, &src_data)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
+ printf (" src_data.output_frames : %ld\n\n", src_data.output_frames) ;
+ exit (1) ;
+ } ;
+
+ if (src_data.end_of_input && src_data.output_frames_gen == 0)
+ break ;
+
+ if (src_data.input_frames_used > src_data.input_frames)
+ { printf ("\n\nLine %d : input_frames_used > input_frames\n\n", __LINE__) ;
+ printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
+ printf (" src_data.input_frames_used : %ld\n", src_data.input_frames_used) ;
+ printf (" src_data.output_frames : %ld\n", src_data.output_frames) ;
+ printf (" src_data.output_frames_gen : %ld\n\n", src_data.output_frames_gen) ;
+ exit (1) ;
+ } ;
+
+ if (src_data.input_frames_used < 0)
+ { printf ("\n\nLine %d : input_frames_used (%ld) < 0\n\n", __LINE__, src_data.input_frames_used) ;
+ exit (1) ;
+ } ;
+
+ if (src_data.output_frames_gen < 0)
+ { printf ("\n\nLine %d : output_frames_gen (%ld) < 0\n\n", __LINE__, src_data.output_frames_gen) ;
+ exit (1) ;
+ } ;
+
+ current_in += src_data.input_frames_used ;
+ current_out += src_data.output_frames_gen ;
+
+ if (current_in > input_len + terminate)
+ { printf ("\n\nLine %d : current_in (%d) > input_len (%d + %d)\n\n", __LINE__, current_in, input_len, terminate) ;
+ exit (1) ;
+ } ;
+
+ if (current_out > output_len)
+ { printf ("\n\nLine %d : current_out (%d) > output_len (%d)\n\n", __LINE__, current_out, output_len) ;
+ exit (1) ;
+ } ;
+
+ if (src_data.input_frames_used > input_len)
+ { printf ("\n\nLine %d : input_frames_used (%ld) > %d\n\n", __LINE__, src_data.input_frames_used, input_len) ;
+ exit (1) ;
+ } ;
+
+ if (src_data.output_frames_gen > output_len)
+ { printf ("\n\nLine %d : output_frames_gen (%ld) > %d\n\n", __LINE__, src_data.output_frames_gen, output_len) ;
+ exit (1) ;
+ } ;
+
+ if (src_data.data_in == NULL && src_data.output_frames_gen == 0)
+ break ;
+
+
+ src_data.data_in += src_data.input_frames_used ;
+ src_data.data_out += src_data.output_frames_gen ;
+ } ;
+
+ src_state = src_delete (src_state) ;
+
+ if (fabs (current_out - src_ratio * input_len) > terminate)
+ { printf ("\n\nLine %d : bad output data length %d should be %2.1f +/- %d.\n", __LINE__,
+ current_out, src_ratio * input_len, terminate) ;
+ printf ("\tsrc_ratio : %.4f\n", src_ratio) ;
+ printf ("\tinput_len : %d\n\tinput_used : %d\n", input_len, current_in) ;
+ printf ("\toutput_len : %d\n\toutput_gen : %d\n\n", output_len, current_out) ;
+ exit (1) ;
+ } ;
+
+ if (current_in != input_len)
+ { printf ("\n\nLine %d : unused input.\n", __LINE__) ;
+ printf ("\tinput_len : %d\n", input_len) ;
+ printf ("\tinput_frames_used : %d\n\n", current_in) ;
+ exit (1) ;
+ } ;
+
+ puts ("ok") ;
+
+ return ;
+} /* stream_test */
+
+static int
+next_block_length (int reset)
+{ static int block_lengths [] = /* Should be an odd length. */
+ { /*-2, 500, 5, 400, 10, 300, 20, 200, 50, 100, 70 -*/
+ 5, 400, 10, 300, 20, 200, 50, 100, 70
+ } ;
+ static int block_len_index = 0 ;
+
+ if (reset)
+ block_len_index = 0 ;
+ else
+ block_len_index = (block_len_index + 1) % ARRAY_LEN (block_lengths) ;
+
+ return block_lengths [block_len_index] ;
+} /* next_block_length */
+
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/throughput_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/throughput_test.c
new file mode 100755
index 00000000..e9974800
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/throughput_test.c
@@ -0,0 +1,253 @@
+/*
+** Copyright (c) 2004-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <time.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <math.h>
+
+#ifdef _WIN32
+#ifndef WIN32_LEAN_AND_MEAN
+#define WIN32_LEAN_AND_MEAN
+#endif
+#include <windows.h>
+#endif
+
+#include <samplerate.h>
+
+#include "util.h"
+
+#define BUFFER_LEN (1<<16)
+
+static float input [BUFFER_LEN] ;
+static float output [BUFFER_LEN] ;
+
+static long
+throughput_test (int converter, long best_throughput)
+{ SRC_DATA src_data ;
+ clock_t start_time, clock_time ;
+ double duration ;
+ long total_frames = 0, throughput ;
+ int error ;
+
+ printf (" %-30s ", src_get_name (converter)) ;
+ fflush (stdout) ;
+
+ src_data.data_in = input ;
+ src_data.input_frames = ARRAY_LEN (input) ;
+
+ src_data.data_out = output ;
+ src_data.output_frames = ARRAY_LEN (output) ;
+
+ src_data.src_ratio = 0.99 ;
+
+#ifdef _WIN32
+ Sleep (2000) ;
+#else
+ sleep (2) ;
+#endif
+
+ start_time = clock () ;
+
+ do
+ {
+ if ((error = src_simple (&src_data, converter, 1)) != 0)
+ { puts (src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ total_frames += src_data.output_frames_gen ;
+
+ clock_time = clock () - start_time ;
+#ifdef __GNU__ /* Clock resolution is 10ms on GNU/Hurd */
+ duration = (10000.0 * clock_time) / CLOCKS_PER_SEC ;
+#else
+ duration = (1.0 * clock_time) / CLOCKS_PER_SEC ;
+#endif
+ }
+ while (duration < 3.0) ;
+
+ if (src_data.input_frames_used != ARRAY_LEN (input))
+ { printf ("\n\nLine %d : input frames used %ld should be %d\n", __LINE__, src_data.input_frames_used, ARRAY_LEN (input)) ;
+ exit (1) ;
+ } ;
+
+ if (fabs (src_data.src_ratio * src_data.input_frames_used - src_data.output_frames_gen) > 2)
+ { printf ("\n\nLine %d : input / output length mismatch.\n\n", __LINE__) ;
+ printf (" input len : %d\n", ARRAY_LEN (input)) ;
+ printf (" output len : %ld (should be %g +/- 2)\n\n", src_data.output_frames_gen,
+ floor (0.5 + src_data.src_ratio * src_data.input_frames_used)) ;
+ exit (1) ;
+ } ;
+
+ throughput = lrint (floor (total_frames / duration)) ;
+
+ if (best_throughput == 0)
+ { best_throughput = MAX (throughput, best_throughput) ;
+ printf ("%5.2f %10ld\n", duration, throughput) ;
+ }
+ else
+ { best_throughput = MAX (throughput, best_throughput) ;
+ printf ("%5.2f %10ld %10ld\n", duration, throughput, best_throughput) ;
+ }
+
+
+ return best_throughput ;
+} /* throughput_test */
+
+static void
+single_run (void)
+{
+
+ printf ("\n CPU name : %s\n", get_cpu_name ()) ;
+
+ puts (
+ "\n"
+ " Converter Duration Throughput\n"
+ " -----------------------------------------------------------"
+ ) ;
+
+ throughput_test (SRC_ZERO_ORDER_HOLD, 0) ;
+ throughput_test (SRC_LINEAR, 0) ;
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ throughput_test (SRC_SINC_FASTEST, 0) ;
+#endif
+#ifdef ENABLE_SINC_MEDIUM_CONVERTER
+ throughput_test (SRC_SINC_MEDIUM_QUALITY, 0) ;
+#endif
+#ifdef ENABLE_SINC_BEST_CONVERTER
+ throughput_test (SRC_SINC_BEST_QUALITY, 0) ;
+#endif
+
+ puts ("") ;
+ return ;
+} /* single_run */
+
+static void
+multi_run (int run_count)
+{ long zero_order_hold = 0, linear = 0 ;
+
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ long sinc_fastest = 0 ;
+#endif
+
+#ifdef ENABLE_SINC_MEDIUM_CONVERTER
+ long sinc_medium = 0 ;
+#endif
+
+#ifdef ENABLE_SINC_BEST_CONVERTER
+ long sinc_best = 0 ;
+#endif
+ int k ;
+
+ puts (
+ "\n"
+ " Converter Duration Throughput Best Throughput\n"
+ " --------------------------------------------------------------------------------"
+ ) ;
+
+ for (k = 0 ; k < run_count ; k++)
+ { zero_order_hold = throughput_test (SRC_ZERO_ORDER_HOLD, zero_order_hold) ;
+ linear = throughput_test (SRC_LINEAR, linear) ;
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ sinc_fastest = throughput_test (SRC_SINC_FASTEST, sinc_fastest) ;
+#endif
+#ifdef ENABLE_SINC_MEDIUM_CONVERTER
+ sinc_medium = throughput_test (SRC_SINC_MEDIUM_QUALITY, sinc_medium) ;
+#endif
+#ifdef ENABLE_SINC_BEST_CONVERTER
+ sinc_best = throughput_test (SRC_SINC_BEST_QUALITY, sinc_best) ;
+#endif
+ puts ("") ;
+
+ /* Let the CPU cool down. We might be running on a laptop. */
+#ifdef _WIN32
+ Sleep (10000) ;
+#else
+ sleep (10) ;
+#endif
+ } ;
+
+ printf ("\n CPU name : %s\n", get_cpu_name ()) ;
+
+ puts (
+ "\n"
+ " Converter Best Throughput\n"
+ " ------------------------------------------------"
+ ) ;
+ printf (" %-30s %10ld\n", src_get_name (SRC_ZERO_ORDER_HOLD), zero_order_hold) ;
+ printf (" %-30s %10ld\n", src_get_name (SRC_LINEAR), linear) ;
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ printf (" %-30s %10ld\n", src_get_name (SRC_SINC_FASTEST), sinc_fastest) ;
+#endif
+#ifdef ENABLE_SINC_MEDIUM_CONVERTER
+ printf (" %-30s %10ld\n", src_get_name (SRC_SINC_MEDIUM_QUALITY), sinc_medium) ;
+#endif
+#ifdef ENABLE_SINC_BEST_CONVERTER
+ printf (" %-30s %10ld\n", src_get_name (SRC_SINC_BEST_QUALITY), sinc_best) ;
+#endif
+
+ puts ("") ;
+} /* multi_run */
+
+static void
+usage_exit (const char * argv0)
+{ const char * cptr ;
+
+ if ((cptr = strrchr (argv0, '/')) != NULL)
+ argv0 = cptr ;
+
+ printf (
+ "Usage :\n"
+ " %s - Single run of the throughput test.\n"
+ " %s --best-of N - Do N runs of test a print bext result.\n"
+ "\n",
+ argv0, argv0) ;
+
+ exit (0) ;
+} /* usage_exit */
+
+int
+main (int argc, char ** argv)
+{ double freq ;
+
+ memset (input, 0, sizeof (input)) ;
+ freq = 0.01 ;
+ gen_windowed_sines (1, &freq, 1.0, input, BUFFER_LEN) ;
+
+ if (argc == 1)
+ single_run () ;
+ else if (argc == 3 && strcmp (argv [1], "--best-of") == 0)
+ { int run_count = atoi (argv [2]) ;
+
+ if (run_count < 1 || run_count > 20)
+ { printf ("Please be sensible. Run count should be in range (1, 10].\n") ;
+ exit (1) ;
+ } ;
+
+ multi_run (run_count) ;
+ }
+ else
+ usage_exit (argv [0]) ;
+
+ puts (
+ " Duration is in seconds.\n"
+ " Throughput is in samples/sec (more is better).\n"
+ ) ;
+
+ return 0 ;
+} /* main */
+
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/util.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/util.c
new file mode 100755
index 00000000..0e4a2337
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/util.c
@@ -0,0 +1,228 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include <math.h>
+
+#include "util.h"
+
+#ifndef M_PI
+#define M_PI 3.14159265358979323846264338
+#endif
+
+void
+gen_windowed_sines (int freq_count, const double *freqs, double max, float *output, int output_len)
+{ int k, freq ;
+ double amplitude, phase ;
+
+ amplitude = max / freq_count ;
+
+ for (k = 0 ; k < output_len ; k++)
+ output [k] = 0.0 ;
+
+ for (freq = 0 ; freq < freq_count ; freq++)
+ { phase = 0.9 * M_PI / freq_count ;
+
+ if (freqs [freq] <= 0.0 || freqs [freq] >= 0.5)
+ { printf ("\n%s : Error : freq [%d] == %g is out of range. Should be < 0.5.\n", __FILE__, freq, freqs [freq]) ;
+ exit (1) ;
+ } ;
+
+ for (k = 0 ; k < output_len ; k++)
+ output [k] = (float) (output [k] + (amplitude * sin (freqs [freq] * (2 * k) * M_PI + phase))) ;
+ } ;
+
+ /* Apply Hanning Window. */
+ for (k = 0 ; k < output_len ; k++)
+ output [k] = (float) (output [k] * (0.5 - 0.5 * cos ((2 * k) * M_PI / (output_len - 1)))) ;
+
+ /* data [k] *= 0.3635819 - 0.4891775 * cos ((2 * k) * M_PI / (output_len - 1))
+ + 0.1365995 * cos ((4 * k) * M_PI / (output_len - 1))
+ - 0.0106411 * cos ((6 * k) * M_PI / (output_len - 1)) ;
+ */
+
+ return ;
+} /* gen_windowed_sines */
+
+void
+save_oct_float (char *filename, float *input, int in_len, float *output, int out_len)
+{ FILE *file ;
+ int k ;
+
+ printf ("Dumping input and output data to file : %s.\n\n", filename) ;
+
+ if (! (file = fopen (filename, "w")))
+ return ;
+
+ fprintf (file, "# Not created by Octave\n") ;
+
+ fprintf (file, "# name: input\n") ;
+ fprintf (file, "# type: matrix\n") ;
+ fprintf (file, "# rows: %d\n", in_len) ;
+ fprintf (file, "# columns: 1\n") ;
+
+ for (k = 0 ; k < in_len ; k++)
+ fprintf (file, "% g\n", input [k]) ;
+
+ fprintf (file, "# name: output\n") ;
+ fprintf (file, "# type: matrix\n") ;
+ fprintf (file, "# rows: %d\n", out_len) ;
+ fprintf (file, "# columns: 1\n") ;
+
+ for (k = 0 ; k < out_len ; k++)
+ fprintf (file, "% g\n", output [k]) ;
+
+ fclose (file) ;
+ return ;
+} /* save_oct_float */
+
+void
+save_oct_double (char *filename, double *input, int in_len, double *output, int out_len)
+{ FILE *file ;
+ int k ;
+
+ printf ("Dumping input and output data to file : %s.\n\n", filename) ;
+
+ if (! (file = fopen (filename, "w")))
+ return ;
+
+ fprintf (file, "# Not created by Octave\n") ;
+
+ fprintf (file, "# name: input\n") ;
+ fprintf (file, "# type: matrix\n") ;
+ fprintf (file, "# rows: %d\n", in_len) ;
+ fprintf (file, "# columns: 1\n") ;
+
+ for (k = 0 ; k < in_len ; k++)
+ fprintf (file, "% g\n", input [k]) ;
+
+ fprintf (file, "# name: output\n") ;
+ fprintf (file, "# type: matrix\n") ;
+ fprintf (file, "# rows: %d\n", out_len) ;
+ fprintf (file, "# columns: 1\n") ;
+
+ for (k = 0 ; k < out_len ; k++)
+ fprintf (file, "% g\n", output [k]) ;
+
+ fclose (file) ;
+ return ;
+} /* save_oct_double */
+
+void
+interleave_data (const float *in, float *out, int frames, int channels)
+{ int fr, ch ;
+
+ for (fr = 0 ; fr < frames ; fr++)
+ for (ch = 0 ; ch < channels ; ch++)
+ out [ch + channels * fr] = in [fr + frames * ch] ;
+
+ return ;
+} /* interleave_data */
+
+void
+deinterleave_data (const float *in, float *out, int frames, int channels)
+{ int fr, ch ;
+
+ for (ch = 0 ; ch < channels ; ch++)
+ for (fr = 0 ; fr < frames ; fr++)
+ out [fr + frames * ch] = in [ch + channels * fr] ;
+
+ return ;
+} /* deinterleave_data */
+
+void
+reverse_data (float *data, int datalen)
+{ int left, right ;
+ float temp ;
+
+ left = 0 ;
+ right = datalen - 1 ;
+
+ while (left < right)
+ { temp = data [left] ;
+ data [left] = data [right] ;
+ data [right] = temp ;
+ left ++ ;
+ right -- ;
+ } ;
+
+} /* reverse_data */
+
+const char *
+get_cpu_name (void)
+{
+ const char *name = "Unknown", *search = NULL ;
+ static char buffer [512] ;
+ FILE * file = NULL ;
+ int is_pipe = 0 ;
+
+#if defined (__linux__)
+ file = fopen ("/proc/cpuinfo", "r") ;
+ search = "model name" ;
+#elif defined (__APPLE__)
+ file = popen ("/usr/sbin/system_profiler -detailLevel full SPHardwareDataType", "r") ;
+ search = "Processor Name" ;
+ is_pipe = 1 ;
+#elif defined (__FreeBSD__)
+ file = popen ("sysctl -a", "r") ;
+ search = "hw.model" ;
+ is_pipe = 1 ;
+#else
+ (void) search ;
+ (void) buffer ;
+ (void) file ;
+ (void) is_pipe ;
+
+ return name;
+#endif
+
+#if defined (__linux__) || defined (__APPLE__) || defined (__FreeBSD__)
+ if (search == NULL)
+ { printf ("Error : search is NULL in function %s.\n", __func__) ;
+ return name ;
+ } ;
+
+ while (fgets (buffer, sizeof (buffer), file) != NULL)
+ if (strstr (buffer, search))
+ { char *src, *dest ;
+
+ if ((src = strchr (buffer, ':')) != NULL)
+ { src ++ ;
+ while (isspace (src [0]))
+ src ++ ;
+ name = src ;
+
+ /* Remove consecutive spaces. */
+ src ++ ;
+ for (dest = src ; src [0] ; src ++)
+ { if (isspace (src [0]) && isspace (dest [-1]))
+ continue ;
+ dest [0] = src [0] ;
+ dest ++ ;
+ } ;
+ dest [0] = 0 ;
+ break ;
+ } ;
+ } ;
+
+ if (is_pipe)
+ pclose (file) ;
+ else
+ fclose (file) ;
+
+ return name ;
+#endif
+} /* get_cpu_name */
+
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/util.h b/lib/libsamplerate/libsamplerate-0.2.2/tests/util.h
new file mode 100755
index 00000000..3303a29d
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/util.h
@@ -0,0 +1,41 @@
+/*
+** Copyright (c) 2002-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#define ABS(a) (((a) < 0) ? - (a) : (a))
+
+#ifndef MAX
+#define MAX(a,b) (((a) > (b)) ? (a) : (b))
+#endif
+
+#ifndef MIN
+#define MIN(a,b) (((a) < (b)) ? (a) : (b))
+#endif
+
+#define ARRAY_LEN(x) ((int) (sizeof (x) / sizeof ((x) [0])))
+
+void gen_windowed_sines (int freq_count, const double *freqs, double max, float *output, int output_len) ;
+
+void save_oct_float (char *filename, float *input, int in_len, float *output, int out_len) ;
+void save_oct_double (char *filename, double *input, int in_len, double *output, int out_len) ;
+
+void interleave_data (const float *in, float *out, int frames, int channels) ;
+
+void deinterleave_data (const float *in, float *out, int frames, int channels) ;
+
+void reverse_data (float *data, int datalen) ;
+
+double calculate_snr (float *data, int len, int expected_peaks) ;
+
+const char * get_cpu_name (void) ;
+
+#define ASSERT(condition) \
+ if (!(condition)) \
+ { printf ("Condition failed on Line %d : %s\n\n", __LINE__, #condition) ; \
+ exit (1) ; \
+ } ;
+
diff --git a/lib/libsamplerate/libsamplerate-0.2.2/tests/varispeed_test.c b/lib/libsamplerate/libsamplerate-0.2.2/tests/varispeed_test.c
new file mode 100755
index 00000000..3c9531c0
--- /dev/null
+++ b/lib/libsamplerate/libsamplerate-0.2.2/tests/varispeed_test.c
@@ -0,0 +1,275 @@
+/*
+** Copyright (c) 2006-2016, Erik de Castro Lopo <erikd@mega-nerd.com>
+** All rights reserved.
+**
+** This code is released under 2-clause BSD license. Please see the
+** file at : https://github.com/libsndfile/libsamplerate/blob/master/COPYING
+*/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <math.h>
+#include <string.h>
+
+#include <samplerate.h>
+
+#include "util.h"
+
+#if HAVE_FFTW3
+#include <fftw3.h>
+#else
+#define fftw_cleanup()
+#endif
+
+#define BUFFER_LEN (1 << 14)
+
+static void varispeed_test (int converter, double target_snr) ;
+static void varispeed_bounds_test (int converter) ;
+static void set_ratio_test (int converter, int channels, double initial_ratio, double second_ratio) ;
+
+int
+main (void)
+{
+ puts ("\n Varispeed SNR test") ;
+ printf (" Zero Order Hold interpolator : ") ;
+ fflush (stdout) ;
+ varispeed_test (SRC_ZERO_ORDER_HOLD, 10.0) ;
+ puts ("ok") ;
+
+ printf (" Linear interpolator : ") ;
+ fflush (stdout) ;
+ varispeed_test (SRC_LINEAR, 10.0) ;
+ puts ("ok") ;
+
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ printf (" Sinc interpolator : ") ;
+ fflush (stdout) ;
+ varispeed_test (SRC_SINC_FASTEST, 115.0) ;
+ puts ("ok") ;
+#endif
+
+ puts ("\n Varispeed bounds test") ;
+ printf (" Zero Order Hold interpolator : ") ;
+ fflush (stdout) ;
+ varispeed_bounds_test (SRC_ZERO_ORDER_HOLD) ;
+ puts ("ok") ;
+
+ printf (" Linear interpolator : ") ;
+ fflush (stdout) ;
+ varispeed_bounds_test (SRC_LINEAR) ;
+ puts ("ok") ;
+
+#ifdef ENABLE_SINC_FAST_CONVERTER
+ printf (" Sinc interpolator : ") ;
+ fflush (stdout) ;
+ varispeed_bounds_test (SRC_SINC_FASTEST) ;
+ puts ("ok") ;
+#endif
+
+ fftw_cleanup () ;
+ puts ("") ;
+
+ return 0 ;
+} /* main */
+
+static void
+varispeed_test (int converter, double target_snr)
+{ static float input [BUFFER_LEN], output [BUFFER_LEN] ;
+ double sine_freq, snr ;
+
+ SRC_STATE *src_state ;
+ SRC_DATA src_data ;
+
+ int input_len, error ;
+
+ memset (input, 0, sizeof (input)) ;
+
+ input_len = ARRAY_LEN (input) / 2 ;
+
+ sine_freq = 0.0111 ;
+ gen_windowed_sines (1, &sine_freq, 1.0, input, input_len) ;
+
+ /* Perform sample rate conversion. */
+ if ((src_state = src_new (converter, 1, &error)) == NULL)
+ { printf ("\n\nLine %d : src_new () failed : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ src_data.end_of_input = 1 ;
+
+ src_data.data_in = input ;
+ src_data.input_frames = input_len ;
+
+ src_data.src_ratio = 3.0 ;
+
+ src_data.data_out = output ;
+ src_data.output_frames = ARRAY_LEN (output) ;
+
+ if ((error = src_set_ratio (src_state, 1.0 / src_data.src_ratio)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ if ((error = src_process (src_state, &src_data)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
+ printf (" src_data.output_frames : %ld\n\n", src_data.output_frames) ;
+ exit (1) ;
+ } ;
+
+ if (src_data.input_frames_used != input_len)
+ { printf ("\n\nLine %d : unused input.\n", __LINE__) ;
+ printf ("\tinput_len : %d\n", input_len) ;
+ printf ("\tinput_frames_used : %ld\n\n", src_data.input_frames_used) ;
+ exit (1) ;
+ } ;
+
+ /* Copy the last output to the input. */
+ memcpy (input, output, sizeof (input)) ;
+ reverse_data (input, src_data.output_frames_gen) ;
+
+ if ((error = src_reset (src_state)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ src_data.end_of_input = 1 ;
+
+ src_data.data_in = input ;
+ input_len = src_data.input_frames = src_data.output_frames_gen ;
+
+ src_data.data_out = output ;
+ src_data.output_frames = ARRAY_LEN (output) ;
+
+ if ((error = src_set_ratio (src_state, 1.0 / src_data.src_ratio)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ if ((error = src_process (src_state, &src_data)))
+ { printf ("\n\nLine %d : %s\n\n", __LINE__, src_strerror (error)) ;
+ printf (" src_data.input_frames : %ld\n", src_data.input_frames) ;
+ printf (" src_data.output_frames : %ld\n\n", src_data.output_frames) ;
+ exit (1) ;
+ } ;
+
+ if (src_data.input_frames_used != input_len)
+ { printf ("\n\nLine %d : unused input.\n", __LINE__) ;
+ printf ("\tinput_len : %d\n", input_len) ;
+ printf ("\tinput_frames_used : %ld\n\n", src_data.input_frames_used) ;
+ exit (1) ;
+ } ;
+
+ src_state = src_delete (src_state) ;
+
+ snr = calculate_snr (output, src_data.output_frames_gen, 1) ;
+
+ if (target_snr > snr)
+ { printf ("\n\nLine %d : snr (%3.1f) does not meet target (%3.1f)\n\n", __LINE__, snr, target_snr) ;
+ save_oct_float ("varispeed.mat", input, src_data.input_frames, output, src_data.output_frames_gen) ;
+ exit (1) ;
+ } ;
+
+ return ;
+} /* varispeed_test */
+
+static void
+varispeed_bounds_test (int converter)
+{ double ratios [] = { 0.1, 0.01, 20 } ;
+ int chan, r1, r2 ;
+
+ for (chan = 1 ; chan <= 9 ; chan ++)
+ for (r1 = 0 ; r1 < ARRAY_LEN (ratios) ; r1++)
+ for (r2 = 0 ; r2 < ARRAY_LEN (ratios) ; r2 ++)
+ if (r1 != r2)
+ set_ratio_test (converter, chan, ratios [r1], ratios [r2]) ;
+} /* varispeed_bounds_test */
+
+static void
+set_ratio_test (int converter, int channels, double initial_ratio, double second_ratio)
+{ const int total_input_frames = BUFFER_LEN ;
+ /* Maximum upsample ratio is 20, use a value beigger. */
+ const int total_output_frames = 25 * BUFFER_LEN ;
+
+ /* Interested in array boundary conditions, so all zero data here is fine. */
+ float *input = calloc (total_input_frames * channels, sizeof (float)) ;
+ float *output = calloc (total_output_frames * channels, sizeof (float)) ;
+
+ char details [128] ;
+
+ const int max_loop_count = 100000 ;
+ const int chunk_size = 128 ;
+
+ SRC_STATE *src_state ;
+ SRC_DATA src_data ;
+
+ int error, k, total_frames_used, total_frames_gen ;
+
+ snprintf (details, sizeof (details), "%d channels, ratio %g -> %g", channels, initial_ratio, second_ratio) ;
+
+ if ((src_state = src_new (converter, channels, &error)) == NULL)
+ { printf ("\n\nLine %d : src_new () failed : %s\n\n", __LINE__, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ total_frames_used = 0 ;
+ total_frames_gen = 0 ;
+
+ memset (&src_data, 0, sizeof (src_data)) ;
+ src_data.end_of_input = 0 ;
+ src_data.src_ratio = initial_ratio ;
+ src_data.data_in = input ;
+ src_data.data_out = output ;
+ src_data.input_frames = chunk_size ;
+ src_data.output_frames = total_output_frames ;
+
+ /* Use a max_loop_count here to enable the detection of infinite loops
+ ** (due to end of input not being detected.
+ */
+ for (k = 0 ; k < max_loop_count ; k ++)
+ { if (k == 1)
+ { /* Hard switch to second_ratio after processing one chunk. */
+ src_data.src_ratio = second_ratio ;
+ if ((error = src_set_ratio (src_state, second_ratio)))
+ { printf ("\n\nLine %d : %s : %s\n\n", __LINE__, details, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+ } ;
+
+ if ((error = src_process (src_state, &src_data)) != 0)
+ { printf ("\n\nLine %d : %s : %s\n\n", __LINE__, details, src_strerror (error)) ;
+ exit (1) ;
+ } ;
+
+ if (src_data.end_of_input && src_data.output_frames_gen == 0)
+ break ;
+
+ total_frames_used += src_data.input_frames_used ;
+ total_frames_gen += src_data.output_frames_gen ;
+
+ src_data.data_in += src_data.input_frames_used * channels ;
+ src_data.data_out += src_data.output_frames_gen * channels ;
+
+ src_data.input_frames = total_input_frames - total_frames_used ;
+ src_data.output_frames = total_output_frames - total_frames_gen ;
+
+ src_data.end_of_input = total_frames_used >= total_input_frames ? 1 : 0 ;
+ } ;
+
+ ASSERT (k < max_loop_count) ;
+ ASSERT (total_frames_gen > 0) ;
+
+ for (k = 0 ; k < total_frames_gen * channels ; k ++)
+ ASSERT (! isnan (output [k])) ;
+
+ src_state = src_delete (src_state) ;
+
+ free (input) ;
+ free (output) ;
+
+ return ;
+} /* set_ratio_test */