1
0
mirror of https://github.com/cookiengineer/audacity synced 2026-01-19 15:06:07 +01:00

Upgrade libsoxr to 0.1.3

This commit is contained in:
Steve Daulton
2018-03-08 16:26:50 +00:00
parent f7f721b52d
commit ccc29c6c76
115 changed files with 4831 additions and 2597 deletions

View File

@@ -0,0 +1,64 @@
/* SoX Resampler Library Copyright (c) 2007-15 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Test 1: exercises soxr_delay and soxr_clear */
#ifdef NDEBUG /* N.B. assert used with active statements so enable always. */
#undef NDEBUG /* Must undef above assert.h or other that might include it. */
#endif
#include <soxr.h>
#include "../examples/examples-common.h"
#define ranqd1(x) ((x) = 1664525 * (x) + 1013904223) /* int32_t x */
#define franqd1(x) (float)(ranqd1(x) * (1. / (65536. * 32768.))) /* [-1,1) */
#define irate 9600
#define orate 4410
int main(int argc, char const * arg[])
{
soxr_error_t error;
int32_t ran = 0;
int j;
soxr_t soxr = soxr_create(irate, orate, 1, &error, NULL, NULL, NULL);
assert(!error);
for (j=0; j<2; ++j) {
float ibuf[irate], out[orate+2], obuf[orate+2], * ibuf1 = ibuf;
size_t ilen = AL(ibuf)-1, olen = AL(obuf), i, odone = 0, odone0, odone1=0;
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_HQ, 0);
for (i=0; i<irate; ibuf[i++] = franqd1(ran));
error = soxr_oneshot(irate, orate, 1, ibuf, ilen, NULL,
out, AL(out), &odone0, NULL, &q_spec, NULL);
assert(!error);
assert(odone0==orate);
for (i=0; ilen || odone1; ++i) {
double out_samples = (double)orate / irate * (double)ilen;
double delayed_samples = soxr_delay(soxr);
unsigned max_out_samples = (unsigned)(out_samples + delayed_samples + .5);
assert(delayed_samples >= 0);
fprintf(stderr, "%5u %5u %5u\n",
(unsigned)ilen, max_out_samples, (unsigned)odone);
assert(max_out_samples+odone==odone0);
error = soxr_process(soxr, ibuf1, ilen, NULL, obuf+odone, olen, &odone1);
assert(!error);
odone += odone1;
ibuf1 = NULL, ilen = 0;
olen = min(100, AL(obuf)-odone);
}
assert(odone==odone0);
for (i=0; i<odone && out[i]==obuf[i]; ++i);
assert(i==odone);
soxr_clear(soxr);
}
soxr_delete(soxr);
return 0 * argc * !arg;
}

View File

@@ -1,8 +1,8 @@
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
add_definitions (${PROJECT_C_FLAGS})
link_libraries (${PROJECT_NAME})
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PROJECT_C_FLAGS}")
link_libraries (${PROJECT_NAME} ${LIBM_LIBRARIES})
file (GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.c)
foreach (fe ${SOURCES})
@@ -10,7 +10,10 @@ foreach (fe ${SOURCES})
add_executable (${f} ${fe})
endforeach ()
enable_testing ()
# Can't use c89 for this file:
if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang")
set_property (SOURCE throughput APPEND_STRING PROPERTY COMPILE_FLAGS "-std=gnu89")
endif ()
set (sweep_to_freq 22050)
set (leader 1)
@@ -20,31 +23,40 @@ math (EXPR base_rate "${sweep_to_freq} + ${sweep_to_freq}")
macro (add_vector r)
set (output ${CMAKE_CURRENT_BINARY_DIR}/ref-${r}.s32)
add_custom_command (OUTPUT ${output} DEPENDS vector-gen ${CMAKE_CURRENT_LIST_FILE}
COMMAND vector-gen ${r} ${leader} ${len} ${sweep_to_freq} 1 ${output})
COMMAND vector-gen ${r} ${leader} ${len} 0 ${sweep_to_freq} 1 ${output})
set (vectors ${output} ${vectors})
endmacro ()
macro (add_cmp_test from to bits)
set (name ${bits}-bit-perfect-${from}-${to})
add_test (NAME ${name} COMMAND ${CMAKE_COMMAND} -Dbits=${bits} -DBIN=${BIN} -DEXAMPLES_BIN=${EXAMPLES_BIN} -Dleader=${leader} -Dto=${to}
-Dfrom=${from} -Dlen=${len} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmp-test.cmake)
add_vector (${from})
add_vector (${to})
macro (add_cmp_test irate orate bits)
set (name ${bits}-bit-perfect-${irate}-${orate})
add_test (NAME ${name} COMMAND ${CMAKE_COMMAND} -Dbits=${bits} -DBIN=${BIN}
-DEXAMPLES_BIN=${EXAMPLES_BIN} -DlenToSkip=${leader} -Dorate=${orate}
-Dirate=${irate} -Dlen=${len} -P ${CMAKE_CURRENT_SOURCE_DIR}/cmp-test.cmake)
add_vector (${irate})
add_vector (${orate})
endmacro ()
unset (test_bits)
if (WITH_SINGLE_PRECISION)
if (WITH_CR32 OR WITH_CR32S OR WITH_CR64 OR WITH_CR64S)
set (test_bits 20)
endif ()
if (WITH_DOUBLE_PRECISION)
set (test_bits ${test_bits} 24)
if (WITH_CR64 OR WITH_CR64S)
set (test_bits ${test_bits} 28)
endif ()
set (rates 192000)
if (WITH_HI_PREC_CLOCK)
set (rates ${rates} 65537)
endif ()
foreach (b ${test_bits})
foreach (r 96000 65537)
foreach (r ${rates})
add_cmp_test (${base_rate} ${r} ${b})
add_cmp_test (${r} ${base_rate} ${b})
endforeach ()
endforeach ()
add_custom_target (test-vectors ALL DEPENDS ${vectors})
if (NOT CMAKE_CROSSCOMPILING)
add_custom_target (test-vectors ALL DEPENDS ${vectors})
endif ()
add_test (1-delay-clear ${BIN}1-delay-clear)

View File

@@ -0,0 +1,41 @@
#!/usr/bin/env bash
set -e
# SoX Resampler Library Copyright (c) 2007-15 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
# Tests varying bandwidth.
tool=./3-options-input-fn
w=$(echo -e "`sox --ver |sed 's/.*SoX v//'` d\n14.4.1 k"|sort -Vr|head -1|sed 's/.* //')
spec="spectrogram -z120 -Z-20 -w$w -ho"
ext=f32; e=0
rate1=48000
rate2=44100
for n in 1 2; do
rate1n=`expr $rate1 / 2`
#sox -r $rate1 -n 0.$ext synth 1s sq pad .03 .03 gain -1
sox -r $rate1 -n 0.$ext synth 8 sin 0:$rate1n gain -1
for pass in `seq 79 5 99`; do
f=bw1-$rate2-p`printf %02u $pass`-$w
$tool $rate1 $rate2 1 $e $e 4 0 $pass < 0.$ext | sox -c1 -r$rate2 -t $ext - -n $spec $f.png -c "bw-test pass:$pass stop:100"
done
for pass in `seq 79 5 99`; do
f=bw2-$rate2-p`printf %02u $pass`-$w
stop=`expr 200 - $pass`
$tool $rate1 $rate2 1 $e $e 4 0 $pass $stop < 0.$ext | sox -c1 -r$rate2 -t $ext - -n $spec $f.png -c "bw-test pass:$pass stop:$stop"
done
r=$rate1; rate1=$rate2; rate2=$r
done
rm 0.$ext

View File

@@ -1,17 +1,13 @@
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
if (${bits} STREQUAL 24)
set (quality 45)
else ()
set (quality 44)
endif ()
math (EXPR quality "43 + (${bits} - 13) / 4")
set (ofile ${irate}-${orate}-${quality}.s32)
#message (STATUS "Output file = [${ofile}]")
set (output ${from}-${to}-${quality}.s32)
execute_process(COMMAND ${EXAMPLES_BIN}3-options-input-fn ${from} ${to} 1 2 2 ${quality} a
INPUT_FILE ref-${from}.s32
OUTPUT_FILE ${output}
execute_process(COMMAND ${EXAMPLES_BIN}3-options-input-fn ${irate} ${orate} 1 2 2 ${quality} a
INPUT_FILE ref-${irate}.s32
OUTPUT_FILE ${ofile}
ERROR_VARIABLE test_error
RESULT_VARIABLE test_result)
@@ -19,7 +15,11 @@ if (test_result)
message (FATAL_ERROR "Resampling failure: ${test_error}")
endif ()
execute_process(COMMAND ${BIN}vector-cmp ref-${to}.s32 ${output} ${to} ${leader} ${len} ${bits} 98
set (percentageToCheck 98)
math (EXPR lenToCheck "${len} * ${percentageToCheck}")
string (REGEX REPLACE "(..)$" ".\\1" lenToCheck "${lenToCheck}") # Divide by 100
execute_process(COMMAND ${BIN}vector-cmp ref-${orate}.s32 ${ofile} ${orate} ${lenToSkip} ${lenToCheck} ${bits}
OUTPUT_VARIABLE test_output
RESULT_VARIABLE test_result)

27
lib-src/libsoxr/tests/eg-test Normal file → Executable file
View File

@@ -1,12 +1,25 @@
#!/bin/bash
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
#!/usr/bin/env bash
set -e
# SoX Resampler Library Copyright (c) 2007-15 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
# Exercises each example programme.
len=8
w=$(echo -e "`sox --ver |sed 's/.*SoX v//'` d\n14.4.1 k"|sort -Vr|head -1|sed 's/.* //')
#vg="valgrind --leak-check=full --show-reachable=yes"
# Exercise example 1:
$vg ./1-single-block
# Check that examples 2-4 can convert 96k<->44k1 and that results are same for each:
ir=96000
or=44100
for i in 1 2; do
@@ -22,8 +35,14 @@ for i in 1 2; do
done
rm *.f32
rm ?.png
# Exercise VR making sure that varied internal stage reconfigurations occur:
variations=(slow-sweep fast-changing)
signals=(sine-wave saw-tooth-wave)
for n in 0 1 2 3; do
$vg ./5-variable-rate $n | sox -tf32 -r44100 -c1 - -n spectrogram -hwk -o $n.png -X 50
signal=${signals[`expr $n % 2 || true`]}
variation=${variations[`expr $n / 2 || true`]}
$vg ./5-variable-rate $n | sox -tf32 -r44100 -c1 - -n spectrogram -z130 -hw$w -o v$n-$w.png -X 50 -c "variation:$variation signal:$signal"
vg=""
done

57
lib-src/libsoxr/tests/io-test Normal file → Executable file
View File

@@ -1,40 +1,65 @@
#!/bin/bash
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
#!/usr/bin/env bash
set -e
# SoX Resampler Library Copyright (c) 2007-16 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
ir=96000
# Tests IO
ir=65537
or=44100
len=16
f=0+48k
g=48k+0
ex=./3-options-input-fn
f=1/32768
g=32768:0
tool=./3-options-input-fn
w=$(echo -e "`sox --ver |sed 's/.*SoX v//'` d\n14.4.1 k"|sort -Vr|head -1|sed 's/.* //')
types=(f32 f64 s32 s16)
zs=(180 180 180 180 180 120 120 120 120)
do_one() {
$ex $ir $or $c $1 $2 $3 < $c.${types[$1]} |
sox -t ${types[$2]} -r $or -c $c - -n spectrogram -X50 -hwk -z180 -o io$n$c.png
it=${types[$1]}; ot=${types[`expr $2 % 4 || true`]}
$tool $ir $or $c $1 $2 $3 < $c.$it > a.$ot
sox -r $or -c $c a.$ot -n spectrogram -X50 -hw$w -z${zs[$n]} -o io$c$n-$w.png -c "io-test i:$it o:$ot ($2) q:$3"
./4-split-channels $ir $or $c $1 $2 $3 < $c.$it > b.$ot
[ $2 != 3 ] && cmp a.$ot b.$ot ||
test $(sox -mv-1 -r$or -c$c a.$ot -r$or -c$c b.$ot -n stats 2>&1 |grep Pk\ l|tr ' ' '\n'|grep '[0-9]'|uniq) = -84.29
rm [ab].$ot
n=`expr $n + 1`
}
rm io??.png
j=2; test z$1 != z && j=$1
test z$1 != z && j=$1 || j=1
for c in `seq 1 $j`; do
for n in `seq 0 3`; do
sox -r $ir -n $c.${types[$n]} synth $len sin $f gain -.1
sox -R -r $ir -n $c.${types[$n]} synth $len sin $f gain -.1
done
n=0
for m in `seq 0 3`; do do_one $m $m 4; done
do_one 1 2 5
do_one 2 0 5
do_one 3 2 4
do_one 0 3 4
for m in `seq 0 3`; do do_one $m $m 5; done
do_one 3 2 3
do_one 0 3 3
do_one 0 11 3
f="$f sin $g"
g=48k:0
g=0+32768
done
rm ?.[sf][0-9][0-9]
# Check conversion between differing I/O types, but no rate-change:
for i in 1 2 3; do
prev=""
sox -n -c $i 0.f32 synth $len gain -.1
$tool 1 1 $i 0 2 < 0.f32 | $tool 1 1 $i 2 0 > 1.f32
cmp [01].f32
done
rm *.f32

View File

@@ -1,22 +0,0 @@
#!/bin/sh
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
# Warning: the intermediate signal (piped) is 3.2 Gbytes so may slug the
# system somewhat.
ex=../examples/3-options-input-fn
q=6
r=1e5
rm lr.png
../tests/vector-gen 1000 0 8 500 .9375 1.s32
$ex 1 $r 1 2 1 $q < 1.s32 | $ex $r 1 1 1 2 $q > 2.s32
sox -M -r 1k 1.s32 -r 1k 2.s32 -n spectrogram -hwk -z180 -o lr.png
display lr.png &
rm [12].s32

View File

@@ -0,0 +1,22 @@
#!/usr/bin/env bash
set -e
# SoX Resampler Library Copyright (c) 2007-16 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
# Tests interpolating then decimating by the same, large ratio.
tool=../examples/3-options-input-fn
w=$(echo -e "`sox --ver |sed 's/.*SoX v//'` d\n14.4.1 k"|sort -Vr|head -1|sed 's/.* //')
q=4
test x$1 = x && ratio=1e5 || ratio=$1
test x$2 = x && rate=8000 || rate=$2
sox -r$rate -n 1.s32 synth 10 sin 0:`expr $rate / 2` vol .9375
sync
time { $tool 1 $ratio 1 2 1 $q a < 1.s32 | $tool $ratio 1 1 1 2 $q a > 2.s32;}
sox -mv-1 -r$rate -c1 1.s32 -r$rate -c1 2.s32 -n spectrogram -hw$w -z150 -o lr-$w.png -c "large-ratio-test q:$q ratio:$ratio"
rm [12].s32

View File

@@ -0,0 +1,39 @@
#!/usr/bin/env bash
set -e
# SoX Resampler Library Copyright (c) 2007-15 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
# Tests varying phase-response.
tool=./3-options-input-fn
w=$(echo -e "`sox --ver |sed 's/.*SoX v//'` d\n14.4.1 k"|sort -Vr|head -1|sed 's/.* //')
spec="spectrogram -z160 -Z-20 -X 2000 -w$w -ho"
ext=f32; e=0
rate1=48000
rate2=44100
for n in 1 2; do
sox -r $rate1 -n 0.$ext synth 1s sq pad .03 .03 gain -1
# Test the following combinations:
names=(linear-phase intermediate-phase maximum-phase minimum-phase)
filters=(standard-filter steep-filter)
for q in `seq 0 7`; do
f=ph-$rate2-q$q-$w
name=${names[`expr $q % 4 || true`]}
filter=${filters[`expr $q / 4 || true`]}
$tool $rate1 $rate2 1 $e $e $q'6' < 0.$ext | sox -c1 -r$rate2 -t $ext - -n $spec $f.png -c "ph-test $filter $name"
done
# Test specific phase-response percentages:
for q in `seq 0 20 100`; do
f=ph-$rate2-p`printf %03u $q`-$w
$tool $rate1 $rate2 1 $e $e 46 0 0 0 $q < 0.$ext | sox -c1 -r$rate2 -t $ext - -n $spec $f.png -c "ph-test phase:${q}%"
done
r=$rate1; rate1=$rate2; rate2=$r
done
rm 0.$ext

73
lib-src/libsoxr/tests/q-test Executable file
View File

@@ -0,0 +1,73 @@
#!/usr/bin/env bash
set -e
# SoX Resampler Library Copyright (c) 2007-15 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
# Tests conversion qualities 0..7 & variable-rate.
tool=./3-options-input-fn
w=$(echo -e "`sox --ver |sed 's/.*SoX v//'` d\n14.4.1 k"|sort -Vr|head -1|sed 's/.* //')
ext=f64; e=1
c=1
q1=0; q2=7
rates=48000
zs=(50 87 87 87 111 135 159 180 95)
zz() {
echo "spectrogram -z${zs[$1]} -Z-30 -w$w -ho"
}
for rate0 in $rates; do
rate1=$rate0
rate2=44100
for n in 1 2; do
rate1n=`expr $rate1 / 2`
# Convert sweep, for spectrogram:
sox -r $rate1 -n -c $c 0.$ext synth 8 sin 0:$rate1n gain -1
for q in `seq $q1 $q2`; do
f=qa-$rate1-$rate2-$q
$tool $rate1 $rate2 $c $e $e $q 0 < 0.$ext | sox -c$c -r$rate2 -t $ext - -n $(zz $q) $f-$w.png -c $f
done
q=8
f=qa-$rate1-$rate2-v
$tool $rate1 $rate2 $c $e $e 4 20 < 0.$ext | sox -c$c -r$rate2 -t $ext - -n $(zz $q) $f-$w.png -c $f
# Convert impulse, for spectrogram:
#: << :
sox -r $rate1 -n 0.$ext synth 1s sq pad .03 .03 gain -1
for q in `seq $q1 $q2`; do
f=qb-$rate1-$rate2-$q
$tool $rate1 $rate2 1 $e $e $q 0 < 0.$ext | sox -c1 -r$rate2 -t $ext - $f.wav
done
q=8
f=qb-$rate1-$rate2-v
$tool $rate1 $rate2 1 $e $e 4 20 < 0.$ext | sox -c1 -r$rate2 -t $ext - $f.wav
# Combine impuse responses into multi-channel file (for inspection in Audacity):
sox -M qb-$rate1-$rate2-?.wav q$rate1-$rate2.wav
rm qb-$rate1-$rate2-?.wav
:
rate1=44100
rate2=$rate0
done
done
rm 0.$ext

14
lib-src/libsoxr/tests/scripts Executable file
View File

@@ -0,0 +1,14 @@
#!/usr/bin/env bash
set -e
# SoX Resampler Library Copyright (c) 2007-15 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
../../tests/bandwidth-test
../../tests/eg-test
../../tests/io-test 3
../../tests/large-ratio-test
../../tests/phase-test
../../tests/q-test
../../tests/time-test 1
../../tests/time-test 2

View File

@@ -0,0 +1,11 @@
#!/bin/sh
set -e
# SoX Resampler Library Copyright (c) 2007-16 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
test -r throughput.exe && wine=wine
test /$1 = / && list="`seq 0 3`" || list="$*"
for n in $list; do $wine ./throughput 44.1 48 1 0 $n 4; done

View File

@@ -0,0 +1,5 @@
@echo off
rem SoX Resampler Library Copyright (c) 2007-16 robs@users.sourceforge.net
rem Licence for this file: LGPL v2.1 See LICENCE for details.
for /L %%i in (0,1,3) DO throughput 44.1 48 1 0 %%i

View File

@@ -0,0 +1,141 @@
/* SoX Resampler Library Copyright (c) 2007-16 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include <soxr.h>
#include "rint.h"
#include "../examples/examples-common.h"
#define k 1000
#if defined _WIN32
#define WIN32_LEAN_AND_MEAN
#include <windows.h>
#define timerStart(msecs) LARGE_INTEGER start, stop, tmp; \
QueryPerformanceCounter(&start), QueryPerformanceFrequency(&tmp), \
stop.QuadPart = (msecs * tmp.QuadPart + k/2) / k
#define timerRunning() (QueryPerformanceCounter(&tmp), \
(tmp.QuadPart-start.QuadPart < stop.QuadPart))
#else
#include <sys/time.h>
#if defined timeradd
#define K k
#define tv_frac tv_usec
#define timespec timeval
#define get_time(x) gettimeofday(x, NULL)
#else
#include <time.h>
#include <unistd.h>
#if defined _POSIX_TIMERS && _POSIX_TIMERS > 0
#define K (k*k)
#define tv_frac tv_nsec
#if defined _POSIX_MONOTONIC_CLOCK
#define get_time(x) clock_gettime(CLOCK_MONOTONIC, x)
#else
#define get_time(x) clock_gettime(CLOCK_REALTIME, x)
#endif
#else
#include <sys/timeb.h>
#define K 1
#define tv_frac millitm
#define tv_sec time
#define timespec timeb
#define get_time(x) ftime(x)
#endif
#endif
#define timerStart(msecs) struct timespec stop, tmp; get_time(&stop), \
stop.tv_frac += (msecs%k)*K, \
stop.tv_sec += msecs/k + stop.tv_frac/(K*k), \
stop.tv_frac %= K*k
#define timerRunning() (get_time(&tmp), \
(tmp.tv_sec < stop.tv_sec || tmp.tv_frac < stop.tv_frac))
#endif
int main(int n, char const * arg[])
{
char const * const arg0 = n? --n, *arg++ : "", * engine = "";
double const irate = n? --n, atof(*arg++) : 96000.;
double const orate = n? --n, atof(*arg++) : 44100.;
unsigned const chans = n? --n, (unsigned)atoi(*arg++) : 1;
soxr_datatype_t const itype = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
unsigned const ospec = n? --n, (soxr_datatype_t)atoi(*arg++) : 0;
unsigned long const q_recipe= n? --n, strtoul(*arg++, 0, 16) : SOXR_HQ;
unsigned long const q_flags = n? --n, strtoul(*arg++, 0, 16) : 0;
double const passband_end = n? --n, atof(*arg++) : 0;
double const stopband_begin = n? --n, atof(*arg++) : 0;
double const phase_response = n? --n, atof(*arg++) : -1;
int const use_threads = n? --n, atoi(*arg++) : 1;
soxr_datatype_t const otype = ospec & 3;
soxr_quality_spec_t q_spec = soxr_quality_spec(q_recipe, q_flags);
soxr_io_spec_t io_spec = soxr_io_spec(itype, otype);
soxr_runtime_spec_t const runtime_spec = soxr_runtime_spec(!use_threads);
/* Allocate resampling input and output buffers in proportion to the input
* and output rates: */
#define buf_total_len 15000 /* In samples per channel. */
size_t const osize = soxr_datatype_size(otype) * chans;
size_t const isize = soxr_datatype_size(itype) * chans;
size_t const olen0= (size_t)(orate * buf_total_len / (irate + orate) + .5);
size_t const olen = min(max(olen0, 1), buf_total_len - 1);
size_t const ilen = buf_total_len - olen;
void * const obuf = malloc(osize * olen);
void * const ibuf = malloc(isize * ilen);
size_t odone = 0, clips = 0, omax = 0, i;
soxr_error_t error;
soxr_t soxr;
int32_t seed = 0;
char const * e = getenv("SOXR_THROUGHPUT_GAIN");
double gain = e? atof(e) : .5;
/* Overrides (if given): */
if (passband_end > 0) q_spec.passband_end = passband_end / 100;
if (stopband_begin > 0) q_spec.stopband_begin = stopband_begin / 100;
if (phase_response >=0) q_spec.phase_response = phase_response;
io_spec.flags = ospec & ~7u;
/* Create a stream resampler: */
soxr = soxr_create(
irate, orate, chans, /* Input rate, output rate, # of channels. */
&error, /* To report any error during creation. */
&io_spec, &q_spec, &runtime_spec);
#define ranqd1(x) ((x) = 1664525 * (x) + 1013904223) /* int32_t x */
#define dranqd1(x) (ranqd1(x) * (1. / (65536. * 32768.))) /* [-1,1) */
#define RAND (dranqd1(seed) * gain)
#define DURATION_MSECS 125
#define NUM_ATTEMPTS 8
if (!error) { /* If all is well, run the resampler: */
engine = soxr_engine(soxr);
switch (itype & 3) {
case 0: for (i=0;i<ilen*chans; ((float *)ibuf)[i]=(float )RAND, ++i); break;
case 1: for (i=0;i<ilen*chans; ((double *)ibuf)[i]=(double )RAND, ++i); break;
case 2: for (i=0;i<ilen*chans; ((int32_t *)ibuf)[i]=rint32(65536.*32768*RAND), ++i); break;
case 3: for (i=0;i<ilen*chans; ((int16_t *)ibuf)[i]=rint16( 1.*32768*RAND), ++i); break;
}
/* Resample in blocks: */
for (i=0; i<NUM_ATTEMPTS; ++i) {
size_t itotal = 0, ototal = 0;
timerStart(DURATION_MSECS);
do {
size_t const ilen1 = odone < olen? ilen : 0;
error = soxr_process(soxr, ibuf, ilen1, NULL, obuf, olen, &odone);
itotal += ilen1;
ototal += odone;
} while (!error && timerRunning());
omax = max(omax, ototal);
}
}
/* Tidy up: */
clips = *soxr_num_clips(soxr); /* Can occur only with integer output. */
soxr_delete(soxr);
free(obuf), free(ibuf);
/* Diagnostics: */
fprintf(stderr, "%-26s %s; %lu clips; I/O: %s (%-5s) %.2f Ms/s\n",
arg0, soxr_strerror(error), (long unsigned)clips,
ferror(stdin) || ferror(stdout)? strerror(errno) : "no error", engine,
1e-6 * k / DURATION_MSECS * chans * (double)omax);
return !!error;
}

36
lib-src/libsoxr/tests/time-test Executable file
View File

@@ -0,0 +1,36 @@
#!/usr/bin/env bash
set -e
# SoX Resampler Library Copyright (c) 2007-15 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
# Tests rate conversion time for qualities 0..7 & variable-rate.
tool=./3-options-input-fn
ext=f32; e=0
test z"$1" != z && c="$1" || c=2
test z"$2" != z && qs="$2" || qs="`seq 0 7` v"
rates="48000 77773 96000"
time=`which time`
BASE=`basename $0`
TIME=/tmp/$BASE-time-$$
ERR=/tmp/$BASE-err-$$
uname -m |grep -q ^arm && len=60 || len=600
export OMP_NUM_THREADS=2
for rate0 in $rates; do
rate1=44100
rate2=$rate0
for n in 1 2; do
sox -R -r $rate1 -n -c $c 0.$ext synth $len noise; sync
for q in $qs; do
test $q = v && Q="4 20" || Q=$q
$time -f %e -o $TIME $tool $rate1 $rate2 $c $e $e $Q < 0.$ext > /dev/null 2> $ERR
echo $rate1 '-->' $rate2 c=$c q=$q t=`cat $TIME` `cat $ERR | sed 's/.*(/(/'`
done
rate1=$rate0
rate2=44100
done
done
rm 0.$ext

View File

@@ -1,53 +1,56 @@
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
/* SoX Resampler Library Copyright (c) 2007-16 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Utility used to help test the library; not for general consumption.
*
* Compare two swept-sine files. */
* Measure the peak bit difference between two files. */
#include <stdlib.h>
#include <stdio.h>
#include <math.h>
#include "../src/rint.h"
#include "../examples/examples-common.h"
int main(int bit, char const * arg[])
#define TYPE 0 /* As vector-gen */
#if TYPE
#define sample_t double
#define N 50
#define DIFF(s1,s2) abs(rint32((s1-s2)*ldexp(1,N-1)))
#else
#define sample_t int32_t
#define N 32
#define DIFF(s1,s2) abs((int)(s1-s2))
#endif
int main(int argc, char const * arg[])
{
FILE * f1 = fopen(arg[1], "rb"),
* f2 = fopen(arg[2], "rb");
double rate = atof (arg[3]), /* Rate for this vector */
leader_len = atof (arg[4]), /* Leader length in seconds */
len = atof (arg[5]), /* Sweep length (excl. leader_len) */
expect_bits= atof (arg[6]),
expect_bw = atof (arg[7]);
int two = !!arg[2][0];
FILE * f1 = fopen(arg[1], "rb"), * f2 = two? fopen(arg[2], "rb") : 0;
double rate = atof (arg[3]), /* Sample-rate */
skip_len = atof (arg[4]), /* Skip length in seconds */
len = atof (arg[5]), /* Compare length in seconds */ r;
int i = 0, count = rint32(rate * len), max = 0, diff;
sample_t s1, s2;
int32_t s1, s2;
long count = 0;
static long thresh[32];
double bw, prev = 0;
for (; fread(&s1, sizeof(s1), 1, f1) == 1 &&
fread(&s2, sizeof(s2), 1, f2) == 1; ++count) {
long diff = abs((int)(s1 - s2));
for (bit = 0; diff && bit < 32; bit++, diff >>= 1)
if ((diff & 1) && !thresh[bit])
thresh[bit] = count + 1;
}
if (count != (long)((leader_len + len) * rate + .5)) {
printf("incorrect file length\n");
exit(1);
}
for (bit = 0; bit < 32; ++bit) {
bw = ((double)thresh[bit] - 1) / rate - leader_len;
if (bit && bw >= 0 && (bw - prev) * 100 / len < .08) {
--bit;
break;
fseek(f1, rint32(rate * skip_len) * (int)sizeof(s1), SEEK_CUR);
if (two) {
fseek(f2, rint32(rate * skip_len) * (int)sizeof(s2), SEEK_CUR);
for (; i < count &&
fread(&s1, sizeof(s1), 1, f1) &&
fread(&s2, sizeof(s2), 1, f2); ++i) {
diff = DIFF(s1, s2);
max = max(max, diff);
}
prev = bw;
}
bit = 32 - bit;
bw = bw * 100 / len;
printf("Bit perfect to %i bits, from DC to %.2f%% nyquist.\n", bit, bw);
return !(bit >= expect_bits && bw >= expect_bw);
else for (; i < count && fread(&s1, sizeof(s1), 1, f1); ++i) {
diff = DIFF(s1, 0);
max = max(max, diff);
}
if (i != count) {
fprintf(stderr, "incorrect file length\n");
return 1;
}
printf("%f\n", r = N-log(max)/log(2));
return argc>6? r<atof(arg[6]) : 0;
}

View File

@@ -1,56 +1,61 @@
/* SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
/* SoX Resampler Library Copyright (c) 2007-16 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Utility used to help test the library; not for general consumption.
*
* Generate a swept sine to a file, with faded `lead-in' section. */
* Generate a swept sine to a file, with `lead-in' section. */
#define QUAD 0
#define TYPE 0 /* calc/store: 0:flt64/int32 1:flt80/flt64 2:flt128/flt64 */
#if QUAD
#if TYPE > 1
#include <quadmath.h>
#endif
#include "../examples/examples-common.h"
#include "math-wrap.h"
#include <stdlib.h>
#include <stdio.h>
#if QUAD
#define modf modfq
#define cos cosq
#define sin sinq
#undef M_PI
#define M_PI M_PIq
#define real __float128
#define atof(x) strtoflt128(x, 0)
#if TYPE
#if TYPE > 1
#define modf modfq
#define cos cosq
#define sin sinq
#define PI M_PIq
#define real __float128
#define atof(x) strtoflt128(x, 0)
#else
#define modf modfl
#define cos cosl
#define sin sinl
#define PI M_PIl
#define real long double
#endif
#define MULT 1
#define OUT(d) double output = d
#else
#define PI M_PI
#define real double
#include "rint.h"
#define MULT (32768. * 65536 - 1/scale)
#define OUT(d) int32_t output = rint32(d)
#endif
int main(int i, char const * argv[])
int main(int argc, char const * argv[])
{
real rate = atof(argv[1]), /* Rate for this vector */
lead_in_len = atof(argv[2]), /* Lead-in length in seconds */
len = atof(argv[3]), /* Sweep length (excl. lead_in_len) */
sweep_to_freq = atof(argv[4]), /* Sweep from DC to this freq. */
multiplier = atof(argv[5]), /* For headroom */
f1 = -sweep_to_freq / len * lead_in_len, f2 = sweep_to_freq,
n1 = rate * -lead_in_len, n2 = rate * len,
m = (f2 - f1) / (n2 - n1) / 2, dummy;
FILE * file = fopen(argv[6], "wb");
i = (int)n1;
if (!file || i != n1)
exit(1);
for (; i < (int)(n2 + .5); ++i) {
double d1 = multiplier * sin(2 * M_PI * modf(i * m * i / rate, &dummy));
double d = i < 0? d1 * (1 - cos(M_PI * (i + n1) / n1)) * .5 : d1;
#if QUAD
size_t actual = fwrite(&d, sizeof(d), 1, file);
#else
int32_t out = rint32(d * (32768. * 65536 - 1));
size_t actual = fwrite(&out, sizeof(out), 1, file);
#endif
if (actual != 1)
return 1;
real rate = atof(argv[1]), /* Rate for this vector */
lead_in_len = atof(argv[2]), /* Lead-in length in seconds */
len = atof(argv[3]), /* Sweep length (excl. lead_in_len) */
f1 = atof(argv[4]),
f2 = atof(argv[5]),
scale = atof(argv[6]), /* For headroom */
n1 = rate * -lead_in_len,
m = (f2 - f1) / (rate * len * 2), dummy;
FILE * file = fopen(argv[7], "wb");
int i = (int)n1, err = !file || i != n1;
for (; !err && i < (int)(rate*(len+lead_in_len)+.5); ++i) {
real d = sin(2 * PI * modf((f1 + i * m) * i / rate, &dummy));
OUT((double)(scale * MULT * d));
err = fwrite(&output, sizeof(output), 1, file) != 1;
}
return 0;
return err |!argc;
}