1
0
mirror of https://github.com/cookiengineer/audacity synced 2026-04-24 23:13:42 +02:00

upgrade to libsoxr 0.0.5 from current git

This commit is contained in:
v.audacity
2012-12-18 05:48:55 +00:00
parent a1a5a75804
commit 61f5cdb82b
94 changed files with 13573 additions and 12511 deletions

View File

@@ -1,112 +1,112 @@
# SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
add_definitions (${PROJECT_C_FLAGS} -DSOXR_LIB)
# Libsoxr configuration:
set (RDFT32 fft4g32)
if (WITH_AVFFT AND AVCODEC_FOUND)
set (RDFT32S avfft32s)
elseif (WITH_PFFFT)
set (RDFT32S pffft32s)
elseif (WITH_SIMD)
set (RDFT32S fft4g32s)
endif ()
if (WITH_DOUBLE_PRECISION)
set (DP_SOURCES rate64)
endif ()
if (WITH_SINGLE_PRECISION)
set (SP_SOURCES rate32 ${RDFT32})
endif ()
if (HAVE_VR)
set (VR_SOURCES vr32)
endif ()
if (HAVE_SIMD)
set (SIMD_SOURCES rate32s ${RDFT32S} simd)
foreach (source ${SIMD_SOURCES})
set_property (SOURCE ${source} PROPERTY COMPILE_FLAGS ${SIMD_C_FLAGS})
endforeach ()
endif ()
# Libsoxr:
add_library (${PROJECT_NAME} ${LIB_TYPE} ${PROJECT_NAME}.c data-io dbesi0 filter fft4g64
${SP_SOURCES} ${VR_SOURCES} ${DP_SOURCES} ${SIMD_SOURCES})
set_target_properties (${PROJECT_NAME} PROPERTIES
VERSION "${SO_VERSION}"
SOVERSION ${SO_VERSION_MAJOR}
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
LINK_INTERFACE_LIBRARIES ""
PUBLIC_HEADER "${PROJECT_NAME}.h")
if (BUILD_FRAMEWORK)
set_target_properties (${PROJECT_NAME} PROPERTIES FRAMEWORK TRUE)
elseif (NOT WIN32)
set (TARGET_PCS ${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.pc)
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/lib${PROJECT_NAME}.pc.in ${TARGET_PCS})
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
endif ()
# LSR bindings:
if (WITH_LSR_BINDINGS)
set (LSR ${PROJECT_NAME}-lsr)
set (LSR_SO_VERSION 0.1.8)
set (LSR_SO_VERSION_MAJOR 0)
add_library (${LSR} ${LIB_TYPE} lsr)
target_link_libraries (${LSR} ${PROJECT_NAME})
set_target_properties (${LSR} PROPERTIES
VERSION "${LSR_SO_VERSION}"
SOVERSION ${LSR_SO_VERSION_MAJOR}
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
LINK_INTERFACE_LIBRARIES ""
PUBLIC_HEADER "${LSR}.h")
if (BUILD_FRAMEWORK)
set_target_properties (${LSR} PROPERTIES FRAMEWORK TRUE)
elseif (NOT WIN32)
set (TARGET_PCS "${TARGET_PCS} ${CMAKE_CURRENT_BINARY_DIR}/lib${LSR}.pc")
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/lib${LSR}.pc.in ${CMAKE_CURRENT_BINARY_DIR}/lib${LSR}.pc)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${LSR}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
endif ()
endif ()
# Installation (from build from source):
install (TARGETS ${PROJECT_NAME} ${LSR}
FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR}
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR})
# Packaging (for unix-like distributions):
get_property (LIB1 TARGET ${PROJECT_NAME} PROPERTY LOCATION)
if (BUILD_SHARED_LIBS)
set (LIB1 ${LIB1}.${SO_VERSION_MAJOR} ${LIB1}.${SO_VERSION})
endif ()
list (APPEND TARGET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.h")
if (WITH_LSR_BINDINGS)
get_property (LIB2 TARGET ${LSR} PROPERTY LOCATION)
if (BUILD_SHARED_LIBS)
set (LIB2 ${LIB2}.${LSR_SO_VERSION_MAJOR} ${LIB2}.${LSR_SO_VERSION})
endif ()
list (APPEND TARGET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${LSR}.h")
endif ()
set (TARGET_LIBS ${LIB1} ${LIB2})
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libsoxr.src.in ${CMAKE_CURRENT_BINARY_DIR}/libsoxr.src)
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libsoxr-dev.src.in ${CMAKE_CURRENT_BINARY_DIR}/libsoxr-dev.src)
# SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
add_definitions (${PROJECT_C_FLAGS} -DSOXR_LIB)
# Libsoxr configuration:
set (RDFT32 fft4g32)
if (WITH_AVFFT AND AVCODEC_FOUND)
set (RDFT32S avfft32s)
elseif (WITH_PFFFT)
set (RDFT32S pffft32s)
elseif (WITH_SIMD)
set (RDFT32S fft4g32s)
endif ()
if (WITH_DOUBLE_PRECISION)
set (DP_SOURCES rate64)
endif ()
if (WITH_SINGLE_PRECISION)
set (SP_SOURCES rate32 ${RDFT32})
endif ()
if (HAVE_VR)
set (VR_SOURCES vr32)
endif ()
if (HAVE_SIMD)
set (SIMD_SOURCES rate32s ${RDFT32S} simd)
foreach (source ${SIMD_SOURCES})
set_property (SOURCE ${source} PROPERTY COMPILE_FLAGS ${SIMD_C_FLAGS})
endforeach ()
endif ()
# Libsoxr:
add_library (${PROJECT_NAME} ${LIB_TYPE} ${PROJECT_NAME}.c data-io dbesi0 filter fft4g64
${SP_SOURCES} ${VR_SOURCES} ${DP_SOURCES} ${SIMD_SOURCES})
set_target_properties (${PROJECT_NAME} PROPERTIES
VERSION "${SO_VERSION}"
SOVERSION ${SO_VERSION_MAJOR}
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
LINK_INTERFACE_LIBRARIES ""
PUBLIC_HEADER "${PROJECT_NAME}.h")
if (BUILD_FRAMEWORK)
set_target_properties (${PROJECT_NAME} PROPERTIES FRAMEWORK TRUE)
elseif (NOT WIN32)
set (TARGET_PCS ${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.pc)
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/lib${PROJECT_NAME}.pc.in ${TARGET_PCS})
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${PROJECT_NAME}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
endif ()
# LSR bindings:
if (WITH_LSR_BINDINGS)
set (LSR ${PROJECT_NAME}-lsr)
set (LSR_SO_VERSION 0.1.8)
set (LSR_SO_VERSION_MAJOR 0)
add_library (${LSR} ${LIB_TYPE} lsr)
target_link_libraries (${LSR} ${PROJECT_NAME})
set_target_properties (${LSR} PROPERTIES
VERSION "${LSR_SO_VERSION}"
SOVERSION ${LSR_SO_VERSION_MAJOR}
INSTALL_NAME_DIR ${LIB_INSTALL_DIR}
LINK_INTERFACE_LIBRARIES ""
PUBLIC_HEADER "${LSR}.h")
if (BUILD_FRAMEWORK)
set_target_properties (${LSR} PROPERTIES FRAMEWORK TRUE)
elseif (NOT WIN32)
set (TARGET_PCS "${TARGET_PCS} ${CMAKE_CURRENT_BINARY_DIR}/lib${LSR}.pc")
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/lib${LSR}.pc.in ${CMAKE_CURRENT_BINARY_DIR}/lib${LSR}.pc)
install (FILES ${CMAKE_CURRENT_BINARY_DIR}/lib${LSR}.pc DESTINATION ${LIB_INSTALL_DIR}/pkgconfig)
endif ()
endif ()
# Installation (from build from source):
install (TARGETS ${PROJECT_NAME} ${LSR}
FRAMEWORK DESTINATION ${FRAMEWORK_INSTALL_DIR}
LIBRARY DESTINATION ${LIB_INSTALL_DIR}
RUNTIME DESTINATION ${BIN_INSTALL_DIR}
ARCHIVE DESTINATION ${LIB_INSTALL_DIR}
PUBLIC_HEADER DESTINATION ${INCLUDE_INSTALL_DIR})
# Packaging (for unix-like distributions):
get_property (LIB1 TARGET ${PROJECT_NAME} PROPERTY LOCATION)
if (BUILD_SHARED_LIBS)
set (LIB1 ${LIB1}.${SO_VERSION_MAJOR} ${LIB1}.${SO_VERSION})
endif ()
list (APPEND TARGET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.h")
if (WITH_LSR_BINDINGS)
get_property (LIB2 TARGET ${LSR} PROPERTY LOCATION)
if (BUILD_SHARED_LIBS)
set (LIB2 ${LIB2}.${LSR_SO_VERSION_MAJOR} ${LIB2}.${LSR_SO_VERSION})
endif ()
list (APPEND TARGET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${LSR}.h")
endif ()
set (TARGET_LIBS ${LIB1} ${LIB2})
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libsoxr.src.in ${CMAKE_CURRENT_BINARY_DIR}/libsoxr.src)
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libsoxr-dev.src.in ${CMAKE_CURRENT_BINARY_DIR}/libsoxr-dev.src)

View File

@@ -1,37 +1,37 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if defined SOXR_LIB
#define lsx_bessel_I_0 _soxr_bessel_I_0
#define lsx_cdft_f _soxr_cdft_f
#define lsx_cdft _soxr_cdft
#define lsx_clear_fft_cache_f _soxr_clear_fft_cache_f
#define lsx_clear_fft_cache _soxr_clear_fft_cache
#define lsx_ddct_f _soxr_ddct_f
#define lsx_ddct _soxr_ddct
#define lsx_ddst_f _soxr_ddst_f
#define lsx_ddst _soxr_ddst
#define lsx_design_lpf _soxr_design_lpf
#define lsx_dfct_f _soxr_dfct_f
#define lsx_dfct _soxr_dfct
#define lsx_dfst_f _soxr_dfst_f
#define lsx_dfst _soxr_dfst
#define lsx_fir_to_phase _soxr_fir_to_phase
#define lsx_init_fft_cache_f _soxr_init_fft_cache_f
#define lsx_init_fft_cache _soxr_init_fft_cache
#define lsx_kaiser_beta _soxr_kaiser_beta
#define lsx_kaiser_params _soxr_kaiser_params
#define lsx_make_lpf _soxr_make_lpf
#define lsx_ordered_convolve_f _soxr_ordered_convolve_f
#define lsx_ordered_convolve _soxr_ordered_convolve
#define lsx_ordered_partial_convolve_f _soxr_ordered_partial_convolve_f
#define lsx_ordered_partial_convolve _soxr_ordered_partial_convolve
#define lsx_rdft_f _soxr_rdft_f
#define lsx_rdft _soxr_rdft
#define lsx_safe_cdft_f _soxr_safe_cdft_f
#define lsx_safe_cdft _soxr_safe_cdft
#define lsx_safe_rdft_f _soxr_safe_rdft_f
#define lsx_safe_rdft _soxr_safe_rdft
#endif
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if defined SOXR_LIB
#define lsx_bessel_I_0 _soxr_bessel_I_0
#define lsx_cdft_f _soxr_cdft_f
#define lsx_cdft _soxr_cdft
#define lsx_clear_fft_cache_f _soxr_clear_fft_cache_f
#define lsx_clear_fft_cache _soxr_clear_fft_cache
#define lsx_ddct_f _soxr_ddct_f
#define lsx_ddct _soxr_ddct
#define lsx_ddst_f _soxr_ddst_f
#define lsx_ddst _soxr_ddst
#define lsx_design_lpf _soxr_design_lpf
#define lsx_dfct_f _soxr_dfct_f
#define lsx_dfct _soxr_dfct
#define lsx_dfst_f _soxr_dfst_f
#define lsx_dfst _soxr_dfst
#define lsx_fir_to_phase _soxr_fir_to_phase
#define lsx_init_fft_cache_f _soxr_init_fft_cache_f
#define lsx_init_fft_cache _soxr_init_fft_cache
#define lsx_kaiser_beta _soxr_kaiser_beta
#define lsx_kaiser_params _soxr_kaiser_params
#define lsx_make_lpf _soxr_make_lpf
#define lsx_ordered_convolve_f _soxr_ordered_convolve_f
#define lsx_ordered_convolve _soxr_ordered_convolve
#define lsx_ordered_partial_convolve_f _soxr_ordered_partial_convolve_f
#define lsx_ordered_partial_convolve _soxr_ordered_partial_convolve
#define lsx_rdft_f _soxr_rdft_f
#define lsx_rdft _soxr_rdft
#define lsx_safe_cdft_f _soxr_safe_cdft_f
#define lsx_safe_cdft _soxr_safe_cdft
#define lsx_safe_rdft_f _soxr_safe_rdft_f
#define lsx_safe_rdft _soxr_safe_rdft
#endif

View File

@@ -1,27 +1,27 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include <math.h>
#include <libavcodec/avfft.h>
#include "filter.h"
static void * forward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),DFT_R2C);}
static void * backward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),IDFT_C2R);}
static void rdft(int length, void * setup, float * h) {av_rdft_calc(setup, h); (void)length;}
static int multiplier(void) {return 2;}
static void nothing(void) {}
typedef void (* fn_t)(void);
fn_t _soxr_rdft32_cb[] = {
(fn_t)forward_setup,
(fn_t)backward_setup,
(fn_t)av_rdft_end,
(fn_t)rdft,
(fn_t)rdft,
(fn_t)rdft,
(fn_t)rdft,
(fn_t)_soxr_ordered_convolve_f,
(fn_t)_soxr_ordered_partial_convolve_f,
(fn_t)multiplier,
(fn_t)nothing,
};
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include <math.h>
#include <libavcodec/avfft.h>
#include "filter.h"
static void * forward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),DFT_R2C);}
static void * backward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),IDFT_C2R);}
static void rdft(int length, void * setup, float * h) {av_rdft_calc(setup, h); (void)length;}
static int multiplier(void) {return 2;}
static void nothing(void) {}
typedef void (* fn_t)(void);
fn_t _soxr_rdft32_cb[] = {
(fn_t)forward_setup,
(fn_t)backward_setup,
(fn_t)av_rdft_end,
(fn_t)rdft,
(fn_t)rdft,
(fn_t)rdft,
(fn_t)rdft,
(fn_t)_soxr_ordered_convolve_f,
(fn_t)_soxr_ordered_partial_convolve_f,
(fn_t)multiplier,
(fn_t)nothing,
};

View File

@@ -1,27 +1,27 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include <math.h>
#include <libavcodec/avfft.h>
#include "simd.h"
static void * forward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),DFT_R2C);}
static void * backward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),IDFT_C2R);}
static void rdft(int length, void * setup, float * h) {av_rdft_calc(setup, h); (void)length;}
static int multiplier(void) {return 2;}
static void nothing(void) {}
typedef void (* fn_t)(void);
fn_t _soxr_rdft32s_cb[] = {
(fn_t)forward_setup,
(fn_t)backward_setup,
(fn_t)av_rdft_end,
(fn_t)rdft,
(fn_t)rdft,
(fn_t)rdft,
(fn_t)rdft,
(fn_t)_soxr_ordered_convolve_simd,
(fn_t)_soxr_ordered_partial_convolve_simd,
(fn_t)multiplier,
(fn_t)nothing,
};
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include <math.h>
#include <libavcodec/avfft.h>
#include "simd.h"
static void * forward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),DFT_R2C);}
static void * backward_setup(int len) {return av_rdft_init((int)(log(len)/log(2)+.5),IDFT_C2R);}
static void rdft(int length, void * setup, float * h) {av_rdft_calc(setup, h); (void)length;}
static int multiplier(void) {return 2;}
static void nothing(void) {}
typedef void (* fn_t)(void);
fn_t _soxr_rdft32s_cb[] = {
(fn_t)forward_setup,
(fn_t)backward_setup,
(fn_t)av_rdft_end,
(fn_t)rdft,
(fn_t)rdft,
(fn_t)rdft,
(fn_t)rdft,
(fn_t)_soxr_ordered_convolve_simd,
(fn_t)_soxr_ordered_partial_convolve_simd,
(fn_t)multiplier,
(fn_t)nothing,
};

View File

@@ -1,73 +1,73 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Concurrent Control with "Readers" and "Writers", P.J. Courtois et al, 1971 */
#if !defined ccrw2_included
#define ccrw2_included
#include "internal.h"
#if defined _OPENMP
#include <omp.h>
typedef struct {
int readcount, writecount; /* initial value = 0 */
omp_lock_t mutex_1, mutex_2, mutex_3, w, r; /* initial value = 1 */
} ccrw2_t; /* Problem #2: `writers-preference' */
#define ccrw2_become_reader(p) do {\
omp_set_lock(&p.mutex_3);\
omp_set_lock(&p.r);\
omp_set_lock(&p.mutex_1);\
if (++p.readcount == 1) omp_set_lock(&p.w);\
omp_unset_lock(&p.mutex_1);\
omp_unset_lock(&p.r);\
omp_unset_lock(&p.mutex_3);\
} while (0)
#define ccrw2_cease_reading(p) do {\
omp_set_lock(&p.mutex_1);\
if (!--p.readcount) omp_unset_lock(&p.w);\
omp_unset_lock(&p.mutex_1);\
} while (0)
#define ccrw2_become_writer(p) do {\
omp_set_lock(&p.mutex_2);\
if (++p.writecount == 1) omp_set_lock(&p.r);\
omp_unset_lock(&p.mutex_2);\
omp_set_lock(&p.w);\
} while (0)
#define ccrw2_cease_writing(p) do {\
omp_unset_lock(&p.w);\
omp_set_lock(&p.mutex_2);\
if (!--p.writecount) omp_unset_lock(&p.r);\
omp_unset_lock(&p.mutex_2);\
} while (0)
#define ccrw2_init(p) do {\
omp_init_lock(&p.mutex_1);\
omp_init_lock(&p.mutex_2);\
omp_init_lock(&p.mutex_3);\
omp_init_lock(&p.w);\
omp_init_lock(&p.r);\
} while (0)
#define ccrw2_clear(p) do {\
omp_destroy_lock(&p.r);\
omp_destroy_lock(&p.w);\
omp_destroy_lock(&p.mutex_3);\
omp_destroy_lock(&p.mutex_2);\
omp_destroy_lock(&p.mutex_1);\
} while (0)
#else
typedef int ccrw2_t;
#define ccrw2_become_reader(x) (void)(x)
#define ccrw2_cease_reading(x) (void)(x)
#define ccrw2_become_writer(x) (void)(x)
#define ccrw2_cease_writing(x) (void)(x)
#define ccrw2_init(x) (void)(x)
#define ccrw2_clear(x) (void)(x)
#endif /* _OPENMP */
#endif
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Concurrent Control with "Readers" and "Writers", P.J. Courtois et al, 1971 */
#if !defined ccrw2_included
#define ccrw2_included
#include "internal.h"
#if defined _OPENMP
#include <omp.h>
typedef struct {
int readcount, writecount; /* initial value = 0 */
omp_lock_t mutex_1, mutex_2, mutex_3, w, r; /* initial value = 1 */
} ccrw2_t; /* Problem #2: `writers-preference' */
#define ccrw2_become_reader(p) do {\
omp_set_lock(&p.mutex_3);\
omp_set_lock(&p.r);\
omp_set_lock(&p.mutex_1);\
if (++p.readcount == 1) omp_set_lock(&p.w);\
omp_unset_lock(&p.mutex_1);\
omp_unset_lock(&p.r);\
omp_unset_lock(&p.mutex_3);\
} while (0)
#define ccrw2_cease_reading(p) do {\
omp_set_lock(&p.mutex_1);\
if (!--p.readcount) omp_unset_lock(&p.w);\
omp_unset_lock(&p.mutex_1);\
} while (0)
#define ccrw2_become_writer(p) do {\
omp_set_lock(&p.mutex_2);\
if (++p.writecount == 1) omp_set_lock(&p.r);\
omp_unset_lock(&p.mutex_2);\
omp_set_lock(&p.w);\
} while (0)
#define ccrw2_cease_writing(p) do {\
omp_unset_lock(&p.w);\
omp_set_lock(&p.mutex_2);\
if (!--p.writecount) omp_unset_lock(&p.r);\
omp_unset_lock(&p.mutex_2);\
} while (0)
#define ccrw2_init(p) do {\
omp_init_lock(&p.mutex_1);\
omp_init_lock(&p.mutex_2);\
omp_init_lock(&p.mutex_3);\
omp_init_lock(&p.w);\
omp_init_lock(&p.r);\
} while (0)
#define ccrw2_clear(p) do {\
omp_destroy_lock(&p.r);\
omp_destroy_lock(&p.w);\
omp_destroy_lock(&p.mutex_3);\
omp_destroy_lock(&p.mutex_2);\
omp_destroy_lock(&p.mutex_1);\
} while (0)
#else
typedef int ccrw2_t;
#define ccrw2_become_reader(x) (void)(x)
#define ccrw2_cease_reading(x) (void)(x)
#define ccrw2_become_writer(x) (void)(x)
#define ccrw2_cease_writing(x) (void)(x)
#define ccrw2_init(x) (void)(x)
#define ccrw2_clear(x) (void)(x)
#endif /* _OPENMP */
#endif

View File

@@ -1,248 +1,249 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include <limits.h>
#include <math.h>
#include <string.h>
#include "data-io.h"
#include "internal.h"
#define DEINTERLEAVE_FROM(T,flag) do { \
unsigned i; \
size_t j; \
T const * src = *src0; \
if (ch > 1) \
for (j = 0; j < n; ++j) for (i = 0; i < ch; ++i) dest[i][j] = (DEINTERLEAVE_TO)*src++; \
else if (flag) memcpy(dest[0], src, n * sizeof(T)), src = &src[n]; \
else for (j = 0; j < n; dest[0][j++] = (DEINTERLEAVE_TO)*src++); \
*src0 = src; \
} while (0)
#if HAVE_DOUBLE_PRECISION
void _soxr_deinterleave(double * * dest, /* Round/clipping not needed here */
soxr_datatype_t data_type, void const * * src0, size_t n, unsigned ch)
{
#define DEINTERLEAVE_TO double
switch (data_type & 3) {
case SOXR_FLOAT32: DEINTERLEAVE_FROM(float, 0); break;
case SOXR_FLOAT64: DEINTERLEAVE_FROM(double, 1); break;
case SOXR_INT32: DEINTERLEAVE_FROM(int32_t, 0); break;
case SOXR_INT16: DEINTERLEAVE_FROM(int16_t, 0); break;
default: break;
}
}
#endif
#if HAVE_SINGLE_PRECISION
void _soxr_deinterleave_f(float * * dest, /* Round/clipping not needed here */
soxr_datatype_t data_type, void const * * src0, size_t n, unsigned ch)
{
#undef DEINTERLEAVE_TO
#define DEINTERLEAVE_TO float
switch (data_type & 3) {
case SOXR_FLOAT32: DEINTERLEAVE_FROM(float, 1); break;
case SOXR_FLOAT64: DEINTERLEAVE_FROM(double, 0); break;
case SOXR_INT32: DEINTERLEAVE_FROM(int32_t, 0); break;
case SOXR_INT16: DEINTERLEAVE_FROM(int16_t, 0); break;
default: break;
}
}
#endif
#include "rint.h"
#if HAVE_FENV_H
#include <fenv.h>
#elif defined _MSC_VER
#define FE_INVALID 1
#define FE_DIVBYZERO 4
#define FE_OVERFLOW 8
#define FE_UNDERFLOW 16
#define FE_INEXACT 32
#define FE_ALL_EXCEPT (FE_INEXACT|FE_DIVBYZERO|FE_UNDERFLOW|FE_OVERFLOW|FE_INVALID)
static __inline int fetestexcept(int excepts)
{
short status_word;
__asm fnstsw status_word
return status_word & excepts & FE_ALL_EXCEPT;
}
static __inline int feclearexcept(int excepts)
{
int16_t status[14];
__asm fnstenv status
status[2] &= ~(excepts & FE_ALL_EXCEPT);
__asm fldenv status
return 0;
}
#endif
#if defined FE_INVALID && defined FPU_RINT32 && defined __STDC_VERSION__
#if __STDC_VERSION__ >= 199901L
#pragma STDC FENV_ACCESS ON
#endif
#endif
#if HAVE_DOUBLE_PRECISION
#define FLOATX double
#define LSX_RINT_CLIP_2 lsx_rint32_clip_2
#define LSX_RINT_CLIP lsx_rint32_clip
#define RINT_CLIP rint32_clip
#define RINT rint32
#if defined FPU_RINT32
#define FPU_RINT
#endif
#define RINT_T int32_t
#define RINT_MAX 2147483647L
#include "rint-clip.h"
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2
#define LSX_RINT_CLIP lsx_rint16_clip
#define RINT_CLIP rint16_clip
#define RINT rint16
#if defined FPU_RINT16
#define FPU_RINT
#endif
#define RINT_T int16_t
#define RINT_MAX 32767
#include "rint-clip.h"
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2_dither
#define LSX_RINT_CLIP lsx_rint16_clip_dither
#define RINT_CLIP rint16_clip_dither
#define RINT rint16
#if defined FPU_RINT16
#define FPU_RINT
#endif
#define RINT_T int16_t
#define RINT_MAX 32767
#define DITHER
#include "rint-clip.h"
#undef FLOATX
#endif
#if HAVE_SINGLE_PRECISION
#define FLOATX float
#define LSX_RINT_CLIP_2 lsx_rint32_clip_2_f
#define LSX_RINT_CLIP lsx_rint32_clip_f
#define RINT_CLIP rint32_clip_f
#define RINT rint32
#if defined FPU_RINT32
#define FPU_RINT
#endif
#define RINT_T int32_t
#define RINT_MAX 2147483647L
#include "rint-clip.h"
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2_f
#define LSX_RINT_CLIP lsx_rint16_clip_f
#define RINT_CLIP rint16_clip_f
#define RINT rint16
#if defined FPU_RINT16
#define FPU_RINT
#endif
#define RINT_T int16_t
#define RINT_MAX 32767
#include "rint-clip.h"
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2_dither_f
#define LSX_RINT_CLIP lsx_rint16_clip_dither_f
#define RINT_CLIP rint16_clip_dither_f
#define RINT rint16
#if defined FPU_RINT16
#define FPU_RINT
#endif
#define RINT_T int16_t
#define RINT_MAX 32767
#define DITHER
#include "rint-clip.h"
#undef FLOATX
#endif
#if defined FE_INVALID && defined FPU_RINT32 && defined __STDC_VERSION__
#if __STDC_VERSION__ >= 199901L
#pragma STDC FENV_ACCESS OFF
#endif
#endif
#define INTERLEAVE_TO(T) do { \
unsigned i; \
size_t j; \
T * dest = *dest0; \
if (ch == 1) \
for (j = 0; j < n; *dest++ = (T)src[0][j++]); \
else for (j = 0; j < n; ++j) for (i = 0; i < ch; ++i) *dest++ = (T)src[i][j]; \
*dest0 = dest; \
return 0; \
} while (0)
#if HAVE_DOUBLE_PRECISION
size_t /* clips */ _soxr_interleave(soxr_datatype_t data_type, void * * dest0,
double const * const * src, size_t n, unsigned ch, unsigned long * seed)
{
switch (data_type & 3) {
case SOXR_FLOAT32: INTERLEAVE_TO(float);
case SOXR_FLOAT64: INTERLEAVE_TO(double);
case SOXR_INT32: if (ch == 1)
return lsx_rint32_clip(dest0, src[0], n);
return lsx_rint32_clip_2(dest0, src, ch, n);
case SOXR_INT16: if (seed) {
if (ch == 1)
return lsx_rint16_clip_dither(dest0, src[0], n, seed);
return lsx_rint16_clip_2_dither(dest0, src, ch, n, seed);
}
if (ch == 1)
return lsx_rint16_clip(dest0, src[0], n);
return lsx_rint16_clip_2(dest0, src, ch, n);
default: break;
}
return 0;
}
#endif
#if HAVE_SINGLE_PRECISION
size_t /* clips */ _soxr_interleave_f(soxr_datatype_t data_type, void * * dest0,
float const * const * src, size_t n, unsigned ch, unsigned long * seed)
{
switch (data_type & 3) {
case SOXR_FLOAT32: INTERLEAVE_TO(float);
case SOXR_FLOAT64: INTERLEAVE_TO(double);
case SOXR_INT32: if (ch == 1)
return lsx_rint32_clip_f(dest0, src[0], n);
return lsx_rint32_clip_2_f(dest0, src, ch, n);
case SOXR_INT16: if (seed) {
if (ch == 1)
return lsx_rint16_clip_dither_f(dest0, src[0], n, seed);
return lsx_rint16_clip_2_dither_f(dest0, src, ch, n, seed);
}
if (ch == 1)
return lsx_rint16_clip_f(dest0, src[0], n);
return lsx_rint16_clip_2_f(dest0, src, ch, n);
default: break;
}
return 0;
}
#endif
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include <limits.h>
#include <math.h>
#include <string.h>
#include "data-io.h"
#include "internal.h"
#define DEINTERLEAVE_FROM(T,flag) do { \
unsigned i; \
size_t j; \
T const * src = *src0; \
if (ch > 1) \
for (j = 0; j < n; ++j) for (i = 0; i < ch; ++i) dest[i][j] = (DEINTERLEAVE_TO)*src++; \
else if (flag) memcpy(dest[0], src, n * sizeof(T)), src = &src[n]; \
else for (j = 0; j < n; dest[0][j++] = (DEINTERLEAVE_TO)*src++); \
*src0 = src; \
} while (0)
#if HAVE_DOUBLE_PRECISION
void _soxr_deinterleave(double * * dest, /* Round/clipping not needed here */
soxr_datatype_t data_type, void const * * src0, size_t n, unsigned ch)
{
#define DEINTERLEAVE_TO double
switch (data_type & 3) {
case SOXR_FLOAT32: DEINTERLEAVE_FROM(float, 0); break;
case SOXR_FLOAT64: DEINTERLEAVE_FROM(double, 1); break;
case SOXR_INT32: DEINTERLEAVE_FROM(int32_t, 0); break;
case SOXR_INT16: DEINTERLEAVE_FROM(int16_t, 0); break;
default: break;
}
}
#endif
#if HAVE_SINGLE_PRECISION
void _soxr_deinterleave_f(float * * dest, /* Round/clipping not needed here */
soxr_datatype_t data_type, void const * * src0, size_t n, unsigned ch)
{
#undef DEINTERLEAVE_TO
#define DEINTERLEAVE_TO float
switch (data_type & 3) {
case SOXR_FLOAT32: DEINTERLEAVE_FROM(float, 1); break;
case SOXR_FLOAT64: DEINTERLEAVE_FROM(double, 0); break;
case SOXR_INT32: DEINTERLEAVE_FROM(int32_t, 0); break;
case SOXR_INT16: DEINTERLEAVE_FROM(int16_t, 0); break;
default: break;
}
}
#endif
#include "rint.h"
#if HAVE_FENV_H
#include <fenv.h>
#elif defined _MSC_VER
#define FE_INVALID 1
#define FE_DIVBYZERO 4
#define FE_OVERFLOW 8
#define FE_UNDERFLOW 16
#define FE_INEXACT 32
#define FE_ALL_EXCEPT (FE_INEXACT|FE_DIVBYZERO|FE_UNDERFLOW|FE_OVERFLOW|FE_INVALID)
static __inline int fetestexcept(int excepts)
{
short status_word;
__asm fnstsw status_word
return status_word & excepts & FE_ALL_EXCEPT;
}
static __inline int feclearexcept(int excepts)
{
int16_t status[14];
__asm fnstenv status
status[2] &= ~(excepts & FE_ALL_EXCEPT);
__asm fldenv status
return 0;
}
#endif
#if defined FE_INVALID && defined FPU_RINT32 && defined __STDC_VERSION__
#if __STDC_VERSION__ >= 199901L
#pragma STDC FENV_ACCESS ON
#endif
#endif
#if HAVE_DOUBLE_PRECISION
#define FLOATX double
#define LSX_RINT_CLIP_2 lsx_rint32_clip_2
#define LSX_RINT_CLIP lsx_rint32_clip
#define RINT_CLIP rint32_clip
#define RINT rint32
#if defined FPU_RINT32
#define FPU_RINT
#endif
#define RINT_T int32_t
#define RINT_MAX 2147483647L
#include "rint-clip.h"
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2
#define LSX_RINT_CLIP lsx_rint16_clip
#define RINT_CLIP rint16_clip
#define RINT rint16
#if defined FPU_RINT16
#define FPU_RINT
#endif
#define RINT_T int16_t
#define RINT_MAX 32767
#include "rint-clip.h"
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2_dither
#define LSX_RINT_CLIP lsx_rint16_clip_dither
#define RINT_CLIP rint16_clip_dither
#define RINT rint16
#if defined FPU_RINT16
#define FPU_RINT
#endif
#define RINT_T int16_t
#define RINT_MAX 32767
#define DITHER
#include "rint-clip.h"
#undef FLOATX
#endif
#if HAVE_SINGLE_PRECISION
#define FLOATX float
#define LSX_RINT_CLIP_2 lsx_rint32_clip_2_f
#define LSX_RINT_CLIP lsx_rint32_clip_f
#define RINT_CLIP rint32_clip_f
#define RINT rint32
#if defined FPU_RINT32
#define FPU_RINT
#endif
#define RINT_T int32_t
#define RINT_MAX 2147483647L
#include "rint-clip.h"
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2_f
#define LSX_RINT_CLIP lsx_rint16_clip_f
#define RINT_CLIP rint16_clip_f
#define RINT rint16
#if defined FPU_RINT16
#define FPU_RINT
#endif
#define RINT_T int16_t
#define RINT_MAX 32767
#include "rint-clip.h"
#define LSX_RINT_CLIP_2 lsx_rint16_clip_2_dither_f
#define LSX_RINT_CLIP lsx_rint16_clip_dither_f
#define RINT_CLIP rint16_clip_dither_f
#define RINT rint16
#if defined FPU_RINT16
#define FPU_RINT
#endif
#define RINT_T int16_t
#define RINT_MAX 32767
#define DITHER
#include "rint-clip.h"
#undef FLOATX
#endif
#if defined FE_INVALID && defined FPU_RINT32 && defined __STDC_VERSION__
#if __STDC_VERSION__ >= 199901L
#pragma STDC FENV_ACCESS OFF
#endif
#endif
#define INTERLEAVE_TO(T,flag) do { \
unsigned i; \
size_t j; \
T * dest = *dest0; \
if (ch > 1) \
for (j = 0; j < n; ++j) for (i = 0; i < ch; ++i) *dest++ = (T)src[i][j]; \
else if (flag) memcpy(dest, src[0], n * sizeof(T)), dest = &dest[n]; \
else for (j = 0; j < n; *dest++ = (T)src[0][j++]); \
*dest0 = dest; \
return 0; \
} while (0)
#if HAVE_DOUBLE_PRECISION
size_t /* clips */ _soxr_interleave(soxr_datatype_t data_type, void * * dest0,
double const * const * src, size_t n, unsigned ch, unsigned long * seed)
{
switch (data_type & 3) {
case SOXR_FLOAT32: INTERLEAVE_TO(float, 0);
case SOXR_FLOAT64: INTERLEAVE_TO(double, 1);
case SOXR_INT32: if (ch == 1)
return lsx_rint32_clip(dest0, src[0], n);
return lsx_rint32_clip_2(dest0, src, ch, n);
case SOXR_INT16: if (seed) {
if (ch == 1)
return lsx_rint16_clip_dither(dest0, src[0], n, seed);
return lsx_rint16_clip_2_dither(dest0, src, ch, n, seed);
}
if (ch == 1)
return lsx_rint16_clip(dest0, src[0], n);
return lsx_rint16_clip_2(dest0, src, ch, n);
default: break;
}
return 0;
}
#endif
#if HAVE_SINGLE_PRECISION
size_t /* clips */ _soxr_interleave_f(soxr_datatype_t data_type, void * * dest0,
float const * const * src, size_t n, unsigned ch, unsigned long * seed)
{
switch (data_type & 3) {
case SOXR_FLOAT32: INTERLEAVE_TO(float, 1);
case SOXR_FLOAT64: INTERLEAVE_TO(double, 0);
case SOXR_INT32: if (ch == 1)
return lsx_rint32_clip_f(dest0, src[0], n);
return lsx_rint32_clip_2_f(dest0, src, ch, n);
case SOXR_INT16: if (seed) {
if (ch == 1)
return lsx_rint16_clip_dither_f(dest0, src[0], n, seed);
return lsx_rint16_clip_2_dither_f(dest0, src, ch, n, seed);
}
if (ch == 1)
return lsx_rint16_clip_f(dest0, src[0], n);
return lsx_rint16_clip_2_f(dest0, src, ch, n);
default: break;
}
return 0;
}
#endif

View File

@@ -1,39 +1,39 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if !defined soxr_data_io_included
#define soxr_data_io_included
#include "soxr.h"
void _soxr_deinterleave(
double * * dest,
soxr_datatype_t data_type,
void const * * src0,
size_t n,
unsigned ch);
void _soxr_deinterleave_f(
float * * dest,
soxr_datatype_t data_type,
void const * * src0,
size_t n,
unsigned ch);
size_t /* clips */ _soxr_interleave(
soxr_datatype_t data_type,
void * * dest,
double const * const * src,
size_t n,
unsigned ch,
unsigned long * seed);
size_t /* clips */ _soxr_interleave_f(
soxr_datatype_t data_type,
void * * dest,
float const * const * src,
size_t n,
unsigned ch,
unsigned long * seed);
#endif
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if !defined soxr_data_io_included
#define soxr_data_io_included
#include "soxr.h"
void _soxr_deinterleave(
double * * dest,
soxr_datatype_t data_type,
void const * * src0,
size_t n,
unsigned ch);
void _soxr_deinterleave_f(
float * * dest,
soxr_datatype_t data_type,
void const * * src0,
size_t n,
unsigned ch);
size_t /* clips */ _soxr_interleave(
soxr_datatype_t data_type,
void * * dest,
double const * const * src,
size_t n,
unsigned ch,
unsigned long * seed);
size_t /* clips */ _soxr_interleave_f(
soxr_datatype_t data_type,
void * * dest,
float const * const * src,
size_t n,
unsigned ch,
unsigned long * seed);
#endif

View File

@@ -1,149 +1,149 @@
/* Copyright(C) 1996 Takuya OOURA
You may use, copy, modify this code for any purpose and
without fee.
Package home: http://www.kurims.kyoto-u.ac.jp/~ooura/bessel.html
*/
#include "filter.h"
#define dbesi0 lsx_bessel_I_0
/* Bessel I_0(x) function in double precision */
#include <math.h>
double dbesi0(double x)
{
int k;
double w, t, y;
static double a[65] = {
8.5246820682016865877e-11, 2.5966600546497407288e-9,
7.9689994568640180274e-8, 1.9906710409667748239e-6,
4.0312469446528002532e-5, 6.4499871606224265421e-4,
0.0079012345761930579108, 0.071111111109207045212,
0.444444444444724909, 1.7777777777777532045,
4.0000000000000011182, 3.99999999999999998,
1.0000000000000000001,
1.1520919130377195927e-10, 2.2287613013610985225e-9,
8.1903951930694585113e-8, 1.9821560631611544984e-6,
4.0335461940910133184e-5, 6.4495330974432203401e-4,
0.0079013012611467520626, 0.071111038160875566622,
0.44444450319062699316, 1.7777777439146450067,
4.0000000132337935071, 3.9999999968569015366,
1.0000000003426703174,
1.5476870780515238488e-10, 1.2685004214732975355e-9,
9.2776861851114223267e-8, 1.9063070109379044378e-6,
4.0698004389917945832e-5, 6.4370447244298070713e-4,
0.0079044749458444976958, 0.071105052411749363882,
0.44445280640924755082, 1.7777694934432109713,
4.0000055808824003386, 3.9999977081165740932,
1.0000004333949319118,
2.0675200625006793075e-10, -6.1689554705125681442e-10,
1.2436765915401571654e-7, 1.5830429403520613423e-6,
4.2947227560776583326e-5, 6.3249861665073441312e-4,
0.0079454472840953930811, 0.070994327785661860575,
0.44467219586283000332, 1.7774588182255374745,
4.0003038986252717972, 3.9998233869142057195,
1.0000472932961288324,
2.7475684794982708655e-10, -3.8991472076521332023e-9,
1.9730170483976049388e-7, 5.9651531561967674521e-7,
5.1992971474748995357e-5, 5.7327338675433770752e-4,
0.0082293143836530412024, 0.069990934858728039037,
0.44726764292723985087, 1.7726685170014087784,
4.0062907863712704432, 3.9952750700487845355,
1.0016354346654179322
};
static double b[70] = {
6.7852367144945531383e-8, 4.6266061382821826854e-7,
6.9703135812354071774e-6, 7.6637663462953234134e-5,
7.9113515222612691636e-4, 0.0073401204731103808981,
0.060677114958668837046, 0.43994941411651569622,
2.7420017097661750609, 14.289661921740860534,
59.820609640320710779, 188.78998681199150629,
399.8731367825601118, 427.56411572180478514,
1.8042097874891098754e-7, 1.2277164312044637357e-6,
1.8484393221474274861e-5, 2.0293995900091309208e-4,
0.0020918539850246207459, 0.019375315654033949297,
0.15985869016767185908, 1.1565260527420641724,
7.1896341224206072113, 37.354773811947484532,
155.80993164266268457, 489.5211371158540918,
1030.9147225169564806, 1093.5883545113746958,
4.8017305613187493564e-7, 3.261317843912380074e-6,
4.9073137508166159639e-5, 5.3806506676487583755e-4,
0.0055387918291051866561, 0.051223717488786549025,
0.42190298621367914765, 3.0463625987357355872,
18.895299447327733204, 97.915189029455461554,
407.13940115493494659, 1274.3088990480582632,
2670.9883037012547506, 2815.7166284662544712,
1.2789926338424623394e-6, 8.6718263067604918916e-6,
1.3041508821299929489e-4, 0.001428224737372747892,
0.014684070635768789378, 0.13561403190404185755,
1.1152592585977393953, 8.0387088559465389038,
49.761318895895479206, 257.2684232313529138,
1066.8543146269566231, 3328.3874581009636362,
6948.8586598121634874, 7288.4893398212481055,
3.409350368197032893e-6, 2.3079025203103376076e-5,
3.4691373283901830239e-4, 0.003794994977222908545,
0.038974209677945602145, 0.3594948380414878371,
2.9522878893539528226, 21.246564609514287056,
131.28727387146173141, 677.38107093296675421,
2802.3724744545046518, 8718.5731420798254081,
18141.348781638832286, 18948.925349296308859
};
static double c[45] = {
2.5568678676452702768e-15, 3.0393953792305924324e-14,
6.3343751991094840009e-13, 1.5041298011833009649e-11,
4.4569436918556541414e-10, 1.746393051427167951e-8,
1.0059224011079852317e-6, 1.0729838945088577089e-4,
0.05150322693642527738,
5.2527963991711562216e-15, 7.202118481421005641e-15,
7.2561421229904797156e-13, 1.482312146673104251e-11,
4.4602670450376245434e-10, 1.7463600061788679671e-8,
1.005922609132234756e-6, 1.0729838937545111487e-4,
0.051503226936437300716,
1.3365917359358069908e-14, -1.2932643065888544835e-13,
1.7450199447905602915e-12, 1.0419051209056979788e-11,
4.58047881980598326e-10, 1.7442405450073548966e-8,
1.0059461453281292278e-6, 1.0729837434500161228e-4,
0.051503226940658446941,
5.3771611477352308649e-14, -1.1396193006413731702e-12,
1.2858641335221653409e-11, -5.9802086004570057703e-11,
7.3666894305929510222e-10, 1.6731837150730356448e-8,
1.0070831435812128922e-6, 1.0729733111203704813e-4,
0.051503227360726294675,
3.7819492084858931093e-14, -4.8600496888588034879e-13,
1.6898350504817224909e-12, 4.5884624327524255865e-11,
1.2521615963377513729e-10, 1.8959658437754727957e-8,
1.0020716710561353622e-6, 1.073037119856927559e-4,
0.05150322383300230775
};
w = fabs(x);
if (w < 8.5) {
t = w * w * 0.0625;
k = 13 * ((int) t);
y = (((((((((((a[k] * t + a[k + 1]) * t +
a[k + 2]) * t + a[k + 3]) * t + a[k + 4]) * t +
a[k + 5]) * t + a[k + 6]) * t + a[k + 7]) * t +
a[k + 8]) * t + a[k + 9]) * t + a[k + 10]) * t +
a[k + 11]) * t + a[k + 12];
} else if (w < 12.5) {
k = (int) w;
t = w - k;
k = 14 * (k - 8);
y = ((((((((((((b[k] * t + b[k + 1]) * t +
b[k + 2]) * t + b[k + 3]) * t + b[k + 4]) * t +
b[k + 5]) * t + b[k + 6]) * t + b[k + 7]) * t +
b[k + 8]) * t + b[k + 9]) * t + b[k + 10]) * t +
b[k + 11]) * t + b[k + 12]) * t + b[k + 13];
} else {
t = 60 / w;
k = 9 * ((int) t);
y = ((((((((c[k] * t + c[k + 1]) * t +
c[k + 2]) * t + c[k + 3]) * t + c[k + 4]) * t +
c[k + 5]) * t + c[k + 6]) * t + c[k + 7]) * t +
c[k + 8]) * sqrt(t) * exp(w);
}
return y;
}
/* Copyright(C) 1996 Takuya OOURA
You may use, copy, modify this code for any purpose and
without fee.
Package home: http://www.kurims.kyoto-u.ac.jp/~ooura/bessel.html
*/
#include "filter.h"
#define dbesi0 lsx_bessel_I_0
/* Bessel I_0(x) function in double precision */
#include <math.h>
double dbesi0(double x)
{
int k;
double w, t, y;
static double a[65] = {
8.5246820682016865877e-11, 2.5966600546497407288e-9,
7.9689994568640180274e-8, 1.9906710409667748239e-6,
4.0312469446528002532e-5, 6.4499871606224265421e-4,
0.0079012345761930579108, 0.071111111109207045212,
0.444444444444724909, 1.7777777777777532045,
4.0000000000000011182, 3.99999999999999998,
1.0000000000000000001,
1.1520919130377195927e-10, 2.2287613013610985225e-9,
8.1903951930694585113e-8, 1.9821560631611544984e-6,
4.0335461940910133184e-5, 6.4495330974432203401e-4,
0.0079013012611467520626, 0.071111038160875566622,
0.44444450319062699316, 1.7777777439146450067,
4.0000000132337935071, 3.9999999968569015366,
1.0000000003426703174,
1.5476870780515238488e-10, 1.2685004214732975355e-9,
9.2776861851114223267e-8, 1.9063070109379044378e-6,
4.0698004389917945832e-5, 6.4370447244298070713e-4,
0.0079044749458444976958, 0.071105052411749363882,
0.44445280640924755082, 1.7777694934432109713,
4.0000055808824003386, 3.9999977081165740932,
1.0000004333949319118,
2.0675200625006793075e-10, -6.1689554705125681442e-10,
1.2436765915401571654e-7, 1.5830429403520613423e-6,
4.2947227560776583326e-5, 6.3249861665073441312e-4,
0.0079454472840953930811, 0.070994327785661860575,
0.44467219586283000332, 1.7774588182255374745,
4.0003038986252717972, 3.9998233869142057195,
1.0000472932961288324,
2.7475684794982708655e-10, -3.8991472076521332023e-9,
1.9730170483976049388e-7, 5.9651531561967674521e-7,
5.1992971474748995357e-5, 5.7327338675433770752e-4,
0.0082293143836530412024, 0.069990934858728039037,
0.44726764292723985087, 1.7726685170014087784,
4.0062907863712704432, 3.9952750700487845355,
1.0016354346654179322
};
static double b[70] = {
6.7852367144945531383e-8, 4.6266061382821826854e-7,
6.9703135812354071774e-6, 7.6637663462953234134e-5,
7.9113515222612691636e-4, 0.0073401204731103808981,
0.060677114958668837046, 0.43994941411651569622,
2.7420017097661750609, 14.289661921740860534,
59.820609640320710779, 188.78998681199150629,
399.8731367825601118, 427.56411572180478514,
1.8042097874891098754e-7, 1.2277164312044637357e-6,
1.8484393221474274861e-5, 2.0293995900091309208e-4,
0.0020918539850246207459, 0.019375315654033949297,
0.15985869016767185908, 1.1565260527420641724,
7.1896341224206072113, 37.354773811947484532,
155.80993164266268457, 489.5211371158540918,
1030.9147225169564806, 1093.5883545113746958,
4.8017305613187493564e-7, 3.261317843912380074e-6,
4.9073137508166159639e-5, 5.3806506676487583755e-4,
0.0055387918291051866561, 0.051223717488786549025,
0.42190298621367914765, 3.0463625987357355872,
18.895299447327733204, 97.915189029455461554,
407.13940115493494659, 1274.3088990480582632,
2670.9883037012547506, 2815.7166284662544712,
1.2789926338424623394e-6, 8.6718263067604918916e-6,
1.3041508821299929489e-4, 0.001428224737372747892,
0.014684070635768789378, 0.13561403190404185755,
1.1152592585977393953, 8.0387088559465389038,
49.761318895895479206, 257.2684232313529138,
1066.8543146269566231, 3328.3874581009636362,
6948.8586598121634874, 7288.4893398212481055,
3.409350368197032893e-6, 2.3079025203103376076e-5,
3.4691373283901830239e-4, 0.003794994977222908545,
0.038974209677945602145, 0.3594948380414878371,
2.9522878893539528226, 21.246564609514287056,
131.28727387146173141, 677.38107093296675421,
2802.3724744545046518, 8718.5731420798254081,
18141.348781638832286, 18948.925349296308859
};
static double c[45] = {
2.5568678676452702768e-15, 3.0393953792305924324e-14,
6.3343751991094840009e-13, 1.5041298011833009649e-11,
4.4569436918556541414e-10, 1.746393051427167951e-8,
1.0059224011079852317e-6, 1.0729838945088577089e-4,
0.05150322693642527738,
5.2527963991711562216e-15, 7.202118481421005641e-15,
7.2561421229904797156e-13, 1.482312146673104251e-11,
4.4602670450376245434e-10, 1.7463600061788679671e-8,
1.005922609132234756e-6, 1.0729838937545111487e-4,
0.051503226936437300716,
1.3365917359358069908e-14, -1.2932643065888544835e-13,
1.7450199447905602915e-12, 1.0419051209056979788e-11,
4.58047881980598326e-10, 1.7442405450073548966e-8,
1.0059461453281292278e-6, 1.0729837434500161228e-4,
0.051503226940658446941,
5.3771611477352308649e-14, -1.1396193006413731702e-12,
1.2858641335221653409e-11, -5.9802086004570057703e-11,
7.3666894305929510222e-10, 1.6731837150730356448e-8,
1.0070831435812128922e-6, 1.0729733111203704813e-4,
0.051503227360726294675,
3.7819492084858931093e-14, -4.8600496888588034879e-13,
1.6898350504817224909e-12, 4.5884624327524255865e-11,
1.2521615963377513729e-10, 1.8959658437754727957e-8,
1.0020716710561353622e-6, 1.073037119856927559e-4,
0.05150322383300230775
};
w = fabs(x);
if (w < 8.5) {
t = w * w * 0.0625;
k = 13 * ((int) t);
y = (((((((((((a[k] * t + a[k + 1]) * t +
a[k + 2]) * t + a[k + 3]) * t + a[k + 4]) * t +
a[k + 5]) * t + a[k + 6]) * t + a[k + 7]) * t +
a[k + 8]) * t + a[k + 9]) * t + a[k + 10]) * t +
a[k + 11]) * t + a[k + 12];
} else if (w < 12.5) {
k = (int) w;
t = w - k;
k = 14 * (k - 8);
y = ((((((((((((b[k] * t + b[k + 1]) * t +
b[k + 2]) * t + b[k + 3]) * t + b[k + 4]) * t +
b[k + 5]) * t + b[k + 6]) * t + b[k + 7]) * t +
b[k + 8]) * t + b[k + 9]) * t + b[k + 10]) * t +
b[k + 11]) * t + b[k + 12]) * t + b[k + 13];
} else {
t = 60 / w;
k = 9 * ((int) t);
y = ((((((((c[k] * t + c[k + 1]) * t +
c[k + 2]) * t + c[k + 3]) * t + c[k + 4]) * t +
c[k + 5]) * t + c[k + 6]) * t + c[k + 7]) * t +
c[k + 8]) * sqrt(t) * exp(w);
}
return y;
}

File diff suppressed because it is too large Load Diff

View File

@@ -1,23 +1,23 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
void lsx_cdft(int, int, double *, int *, double *);
void lsx_rdft(int, int, double *, int *, double *);
void lsx_ddct(int, int, double *, int *, double *);
void lsx_ddst(int, int, double *, int *, double *);
void lsx_dfct(int, double *, double *, int *, double *);
void lsx_dfst(int, double *, double *, int *, double *);
void lsx_cdft_f(int, int, float *, int *, float *);
void lsx_rdft_f(int, int, float *, int *, float *);
void lsx_ddct_f(int, int, float *, int *, float *);
void lsx_ddst_f(int, int, float *, int *, float *);
void lsx_dfct_f(int, float *, float *, int *, float *);
void lsx_dfst_f(int, float *, float *, int *, float *);
#define dft_br_len(l) (2ul + (1ul << (int)(log(l / 2 + .5) / log(2.)) / 2))
#define dft_sc_len(l) ((unsigned long)l / 2)
/* Over-allocate h by 2 to use these macros */
#define LSX_PACK(h, n) h[1] = h[n]
#define LSX_UNPACK(h, n) h[n] = h[1], h[n + 1] = h[1] = 0;
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
void lsx_cdft(int, int, double *, int *, double *);
void lsx_rdft(int, int, double *, int *, double *);
void lsx_ddct(int, int, double *, int *, double *);
void lsx_ddst(int, int, double *, int *, double *);
void lsx_dfct(int, double *, double *, int *, double *);
void lsx_dfst(int, double *, double *, int *, double *);
void lsx_cdft_f(int, int, float *, int *, float *);
void lsx_rdft_f(int, int, float *, int *, float *);
void lsx_ddct_f(int, int, float *, int *, float *);
void lsx_ddst_f(int, int, float *, int *, float *);
void lsx_dfct_f(int, float *, float *, int *, float *);
void lsx_dfst_f(int, float *, float *, int *, float *);
#define dft_br_len(l) (2ul + (1ul << (int)(log(l / 2 + .5) / log(2.)) / 2))
#define dft_sc_len(l) ((unsigned long)l / 2)
/* Over-allocate h by 2 to use these macros */
#define LSX_PACK(h, n) h[1] = h[n]
#define LSX_UNPACK(h, n) h[n] = h[1], h[n + 1] = h[1] = 0;

View File

@@ -1,27 +1,27 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include "filter.h"
#define FFT4G_FLOAT
#include "fft4g.c"
static void * null(void) {return 0;}
static void forward (int length, void * setup, double * H) {lsx_safe_rdft_f(length, 1, H); (void)setup;}
static void backward(int length, void * setup, double * H) {lsx_safe_rdft_f(length, -1, H); (void)setup;}
static int multiplier(void) {return 2;}
static void nothing(void) {}
typedef void (* fn_t)(void);
fn_t _soxr_rdft32_cb[] = {
(fn_t)null,
(fn_t)null,
(fn_t)nothing,
(fn_t)forward,
(fn_t)forward,
(fn_t)backward,
(fn_t)backward,
(fn_t)_soxr_ordered_convolve_f,
(fn_t)_soxr_ordered_partial_convolve_f,
(fn_t)multiplier,
(fn_t)nothing,
};
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include "filter.h"
#define FFT4G_FLOAT
#include "fft4g.c"
static void * null(void) {return 0;}
static void forward (int length, void * setup, double * H) {lsx_safe_rdft_f(length, 1, H); (void)setup;}
static void backward(int length, void * setup, double * H) {lsx_safe_rdft_f(length, -1, H); (void)setup;}
static int multiplier(void) {return 2;}
static void nothing(void) {}
typedef void (* fn_t)(void);
fn_t _soxr_rdft32_cb[] = {
(fn_t)null,
(fn_t)null,
(fn_t)nothing,
(fn_t)forward,
(fn_t)forward,
(fn_t)backward,
(fn_t)backward,
(fn_t)_soxr_ordered_convolve_f,
(fn_t)_soxr_ordered_partial_convolve_f,
(fn_t)multiplier,
(fn_t)nothing,
};

View File

@@ -1,26 +1,26 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include "filter.h"
#include "simd.h"
static void * null(void) {return 0;}
static void nothing(void) {}
static void forward (int length, void * setup, float * H) {lsx_safe_rdft_f(length, 1, H); (void)setup;}
static void backward(int length, void * setup, float * H) {lsx_safe_rdft_f(length, -1, H); (void)setup;}
static int multiplier(void) {return 2;}
typedef void (* fn_t)(void);
fn_t _soxr_rdft32s_cb[] = {
(fn_t)null,
(fn_t)null,
(fn_t)nothing,
(fn_t)forward,
(fn_t)forward,
(fn_t)backward,
(fn_t)backward,
(fn_t)_soxr_ordered_convolve_simd,
(fn_t)_soxr_ordered_partial_convolve_simd,
(fn_t)multiplier,
(fn_t)nothing,
};
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include "filter.h"
#include "simd.h"
static void * null(void) {return 0;}
static void nothing(void) {}
static void forward (int length, void * setup, float * H) {lsx_safe_rdft_f(length, 1, H); (void)setup;}
static void backward(int length, void * setup, float * H) {lsx_safe_rdft_f(length, -1, H); (void)setup;}
static int multiplier(void) {return 2;}
typedef void (* fn_t)(void);
fn_t _soxr_rdft32s_cb[] = {
(fn_t)null,
(fn_t)null,
(fn_t)nothing,
(fn_t)forward,
(fn_t)forward,
(fn_t)backward,
(fn_t)backward,
(fn_t)_soxr_ordered_convolve_simd,
(fn_t)_soxr_ordered_partial_convolve_simd,
(fn_t)multiplier,
(fn_t)nothing,
};

View File

@@ -1,29 +1,29 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include "filter.h"
#include "fft4g.c"
#include "soxr-config.h"
#if HAVE_DOUBLE_PRECISION
static void * null(void) {return 0;}
static void nothing(void) {}
static void forward (int length, void * setup, double * H) {lsx_safe_rdft(length, 1, H); (void)setup;}
static void backward(int length, void * setup, double * H) {lsx_safe_rdft(length, -1, H); (void)setup;}
static int multiplier(void) {return 2;}
typedef void (* fn_t)(void);
fn_t _soxr_rdft64_cb[] = {
(fn_t)null,
(fn_t)null,
(fn_t)nothing,
(fn_t)forward,
(fn_t)forward,
(fn_t)backward,
(fn_t)backward,
(fn_t)_soxr_ordered_convolve,
(fn_t)_soxr_ordered_partial_convolve,
(fn_t)multiplier,
(fn_t)nothing,
};
#endif
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include "filter.h"
#include "fft4g.c"
#include "soxr-config.h"
#if HAVE_DOUBLE_PRECISION
static void * null(void) {return 0;}
static void nothing(void) {}
static void forward (int length, void * setup, double * H) {lsx_safe_rdft(length, 1, H); (void)setup;}
static void backward(int length, void * setup, double * H) {lsx_safe_rdft(length, -1, H); (void)setup;}
static int multiplier(void) {return 2;}
typedef void (* fn_t)(void);
fn_t _soxr_rdft64_cb[] = {
(fn_t)null,
(fn_t)null,
(fn_t)nothing,
(fn_t)forward,
(fn_t)forward,
(fn_t)backward,
(fn_t)backward,
(fn_t)_soxr_ordered_convolve,
(fn_t)_soxr_ordered_partial_convolve,
(fn_t)multiplier,
(fn_t)nothing,
};
#endif

View File

@@ -1,92 +1,92 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
static int * LSX_FFT_BR;
static DFT_FLOAT * LSX_FFT_SC;
static int FFT_LEN = -1;
static ccrw2_t FFT_CACHE_CCRW;
void LSX_INIT_FFT_CACHE(void)
{
if (FFT_LEN >= 0)
return;
assert(LSX_FFT_BR == NULL);
assert(LSX_FFT_SC == NULL);
assert(FFT_LEN == -1);
ccrw2_init(FFT_CACHE_CCRW);
FFT_LEN = 0;
}
void LSX_CLEAR_FFT_CACHE(void)
{
assert(FFT_LEN >= 0);
ccrw2_clear(FFT_CACHE_CCRW);
free(LSX_FFT_BR);
free(LSX_FFT_SC);
LSX_FFT_SC = NULL;
LSX_FFT_BR = NULL;
FFT_LEN = -1;
}
static bool UPDATE_FFT_CACHE(int len)
{
LSX_INIT_FFT_CACHE();
assert(lsx_is_power_of_2(len));
assert(FFT_LEN >= 0);
ccrw2_become_reader(FFT_CACHE_CCRW);
if (len > FFT_LEN) {
ccrw2_cease_reading(FFT_CACHE_CCRW);
ccrw2_become_writer(FFT_CACHE_CCRW);
if (len > FFT_LEN) {
int old_n = FFT_LEN;
FFT_LEN = len;
LSX_FFT_BR = realloc(LSX_FFT_BR, dft_br_len(FFT_LEN) * sizeof(*LSX_FFT_BR));
LSX_FFT_SC = realloc(LSX_FFT_SC, dft_sc_len(FFT_LEN) * sizeof(*LSX_FFT_SC));
if (!old_n) {
LSX_FFT_BR[0] = 0;
#if SOXR_LIB
atexit(LSX_CLEAR_FFT_CACHE);
#endif
}
return true;
}
ccrw2_cease_writing(FFT_CACHE_CCRW);
ccrw2_become_reader(FFT_CACHE_CCRW);
}
return false;
}
static void DONE_WITH_FFT_CACHE(bool is_writer)
{
if (is_writer)
ccrw2_cease_writing(FFT_CACHE_CCRW);
else ccrw2_cease_reading(FFT_CACHE_CCRW);
}
void LSX_SAFE_RDFT(int len, int type, DFT_FLOAT * d)
{
bool is_writer = UPDATE_FFT_CACHE(len);
LSX_RDFT(len, type, d, LSX_FFT_BR, LSX_FFT_SC);
DONE_WITH_FFT_CACHE(is_writer);
}
void LSX_SAFE_CDFT(int len, int type, DFT_FLOAT * d)
{
bool is_writer = UPDATE_FFT_CACHE(len);
LSX_CDFT(len, type, d, LSX_FFT_BR, LSX_FFT_SC);
DONE_WITH_FFT_CACHE(is_writer);
}
#undef UPDATE_FFT_CACHE
#undef LSX_SAFE_RDFT
#undef LSX_SAFE_CDFT
#undef LSX_RDFT
#undef LSX_INIT_FFT_CACHE
#undef LSX_FFT_SC
#undef LSX_FFT_BR
#undef LSX_CLEAR_FFT_CACHE
#undef LSX_CDFT
#undef FFT_LEN
#undef FFT_CACHE_CCRW
#undef DONE_WITH_FFT_CACHE
#undef DFT_FLOAT
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
static int * LSX_FFT_BR;
static DFT_FLOAT * LSX_FFT_SC;
static int FFT_LEN = -1;
static ccrw2_t FFT_CACHE_CCRW;
void LSX_INIT_FFT_CACHE(void)
{
if (FFT_LEN >= 0)
return;
assert(LSX_FFT_BR == NULL);
assert(LSX_FFT_SC == NULL);
assert(FFT_LEN == -1);
ccrw2_init(FFT_CACHE_CCRW);
FFT_LEN = 0;
}
void LSX_CLEAR_FFT_CACHE(void)
{
assert(FFT_LEN >= 0);
ccrw2_clear(FFT_CACHE_CCRW);
free(LSX_FFT_BR);
free(LSX_FFT_SC);
LSX_FFT_SC = NULL;
LSX_FFT_BR = NULL;
FFT_LEN = -1;
}
static bool UPDATE_FFT_CACHE(int len)
{
LSX_INIT_FFT_CACHE();
assert(lsx_is_power_of_2(len));
assert(FFT_LEN >= 0);
ccrw2_become_reader(FFT_CACHE_CCRW);
if (len > FFT_LEN) {
ccrw2_cease_reading(FFT_CACHE_CCRW);
ccrw2_become_writer(FFT_CACHE_CCRW);
if (len > FFT_LEN) {
int old_n = FFT_LEN;
FFT_LEN = len;
LSX_FFT_BR = realloc(LSX_FFT_BR, dft_br_len(FFT_LEN) * sizeof(*LSX_FFT_BR));
LSX_FFT_SC = realloc(LSX_FFT_SC, dft_sc_len(FFT_LEN) * sizeof(*LSX_FFT_SC));
if (!old_n) {
LSX_FFT_BR[0] = 0;
#if SOXR_LIB
atexit(LSX_CLEAR_FFT_CACHE);
#endif
}
return true;
}
ccrw2_cease_writing(FFT_CACHE_CCRW);
ccrw2_become_reader(FFT_CACHE_CCRW);
}
return false;
}
static void DONE_WITH_FFT_CACHE(bool is_writer)
{
if (is_writer)
ccrw2_cease_writing(FFT_CACHE_CCRW);
else ccrw2_cease_reading(FFT_CACHE_CCRW);
}
void LSX_SAFE_RDFT(int len, int type, DFT_FLOAT * d)
{
bool is_writer = UPDATE_FFT_CACHE(len);
LSX_RDFT(len, type, d, LSX_FFT_BR, LSX_FFT_SC);
DONE_WITH_FFT_CACHE(is_writer);
}
void LSX_SAFE_CDFT(int len, int type, DFT_FLOAT * d)
{
bool is_writer = UPDATE_FFT_CACHE(len);
LSX_CDFT(len, type, d, LSX_FFT_BR, LSX_FFT_SC);
DONE_WITH_FFT_CACHE(is_writer);
}
#undef UPDATE_FFT_CACHE
#undef LSX_SAFE_RDFT
#undef LSX_SAFE_CDFT
#undef LSX_RDFT
#undef LSX_INIT_FFT_CACHE
#undef LSX_FFT_SC
#undef LSX_FFT_BR
#undef LSX_CLEAR_FFT_CACHE
#undef LSX_CDFT
#undef FFT_LEN
#undef FFT_CACHE_CCRW
#undef DONE_WITH_FFT_CACHE
#undef DFT_FLOAT

View File

@@ -1,125 +1,124 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#ifndef fifo_included
#define fifo_included
#include <string.h>
#if !defined FIFO_SIZE_T
#define FIFO_SIZE_T size_t
#endif
#if !defined FIFO_REALLOC
#include <stdlib.h>
#define FIFO_REALLOC(a,b,c) realloc(a,b)
#undef FIFO_FREE
#define FIFO_FREE free
#undef FIFO_MALLOC
#define FIFO_MALLOC malloc
#endif
typedef struct {
char * data;
size_t allocation; /* Number of bytes allocated for data. */
size_t item_size; /* Size of each item in data */
size_t begin; /* Offset of the first byte to read. */
size_t end; /* 1 + Offset of the last byte byte to read. */
} fifo_t;
#define FIFO_MIN 0x4000
#if !defined UNUSED
#define UNUSED
#endif
UNUSED static void fifo_clear(fifo_t * f)
{
f->end = f->begin = 0;
}
UNUSED static void * fifo_reserve(fifo_t * f, FIFO_SIZE_T n0)
{
size_t n = (size_t)n0;
n *= f->item_size;
if (f->begin == f->end)
fifo_clear(f);
while (1) {
if (f->end + n <= f->allocation) {
void *p = f->data + f->end;
f->end += n;
return p;
}
if (f->begin > FIFO_MIN) {
memmove(f->data, f->data + f->begin, f->end - f->begin);
f->end -= f->begin;
f->begin = 0;
continue;
}
f->data = FIFO_REALLOC(f->data, f->allocation + n, f->allocation);
f->allocation += n;
if (!f->data)
return 0;
}
}
UNUSED static void * fifo_write(fifo_t * f, FIFO_SIZE_T n0, void const * data)
{
size_t n = (size_t)n0;
void * s = fifo_reserve(f, n0);
if (data)
memcpy(s, data, n * f->item_size);
return s;
}
UNUSED static void fifo_trim_to(fifo_t * f, FIFO_SIZE_T n0)
{
size_t n = (size_t)n0;
n *= f->item_size;
f->end = f->begin + n;
}
UNUSED static void fifo_trim_by(fifo_t * f, FIFO_SIZE_T n0)
{
size_t n = (size_t)n0;
n *= f->item_size;
f->end -= n;
}
UNUSED static FIFO_SIZE_T fifo_occupancy(fifo_t * f)
{
return (FIFO_SIZE_T)((f->end - f->begin) / f->item_size);
}
UNUSED static void * fifo_read(fifo_t * f, FIFO_SIZE_T n0, void * data)
{
size_t n = (size_t)n0;
char * ret = f->data + f->begin;
n *= f->item_size;
if (n > (f->end - f->begin))
return NULL;
if (data)
memcpy(data, ret, (size_t)n);
f->begin += n;
return ret;
}
#define fifo_read_ptr(f) fifo_read(f, (FIFO_SIZE_T)0, NULL)
UNUSED static void fifo_delete(fifo_t * f)
{
FIFO_FREE(f->data);
}
UNUSED static int fifo_create(fifo_t * f, FIFO_SIZE_T item_size)
{
f->item_size = (size_t)item_size;
f->allocation = FIFO_MIN;
fifo_clear(f);
return !(f->data = FIFO_MALLOC(f->allocation));
}
#endif
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#ifndef fifo_included
#define fifo_included
#if !defined FIFO_SIZE_T
#define FIFO_SIZE_T size_t
#endif
#if !defined FIFO_REALLOC
#define FIFO_REALLOC(a,b,c) realloc(a,b)
#undef FIFO_FREE
#define FIFO_FREE free
#undef FIFO_MALLOC
#define FIFO_MALLOC malloc
#endif
typedef struct {
char * data;
size_t allocation; /* Number of bytes allocated for data. */
size_t item_size; /* Size of each item in data */
size_t begin; /* Offset of the first byte to read. */
size_t end; /* 1 + Offset of the last byte byte to read. */
} fifo_t;
#if !defined FIFO_MIN
#define FIFO_MIN 0x4000
#endif
#if !defined UNUSED
#define UNUSED
#endif
UNUSED static void fifo_clear(fifo_t * f)
{
f->end = f->begin = 0;
}
UNUSED static void * fifo_reserve(fifo_t * f, FIFO_SIZE_T n0)
{
size_t n = (size_t)n0;
n *= f->item_size;
if (f->begin == f->end)
fifo_clear(f);
while (1) {
if (f->end + n <= f->allocation) {
void *p = f->data + f->end;
f->end += n;
return p;
}
if (f->begin > FIFO_MIN) {
memmove(f->data, f->data + f->begin, f->end - f->begin);
f->end -= f->begin;
f->begin = 0;
continue;
}
f->data = FIFO_REALLOC(f->data, f->allocation + n, f->allocation);
f->allocation += n;
if (!f->data)
return 0;
}
}
UNUSED static void * fifo_write(fifo_t * f, FIFO_SIZE_T n0, void const * data)
{
size_t n = (size_t)n0;
void * s = fifo_reserve(f, n0);
if (data)
memcpy(s, data, n * f->item_size);
return s;
}
UNUSED static void fifo_trim_to(fifo_t * f, FIFO_SIZE_T n0)
{
size_t n = (size_t)n0;
n *= f->item_size;
f->end = f->begin + n;
}
UNUSED static void fifo_trim_by(fifo_t * f, FIFO_SIZE_T n0)
{
size_t n = (size_t)n0;
n *= f->item_size;
f->end -= n;
}
UNUSED static FIFO_SIZE_T fifo_occupancy(fifo_t * f)
{
return (FIFO_SIZE_T)((f->end - f->begin) / f->item_size);
}
UNUSED static void * fifo_read(fifo_t * f, FIFO_SIZE_T n0, void * data)
{
size_t n = (size_t)n0;
char * ret = f->data + f->begin;
n *= f->item_size;
if (n > (f->end - f->begin))
return NULL;
if (data)
memcpy(data, ret, (size_t)n);
f->begin += n;
return ret;
}
#define fifo_read_ptr(f) fifo_read(f, (FIFO_SIZE_T)0, NULL)
UNUSED static void fifo_delete(fifo_t * f)
{
FIFO_FREE(f->data);
}
UNUSED static int fifo_create(fifo_t * f, FIFO_SIZE_T item_size)
{
f->item_size = (size_t)item_size;
f->allocation = FIFO_MIN;
fifo_clear(f);
return !(f->data = FIFO_MALLOC(f->allocation));
}
#endif

View File

@@ -1,245 +1,245 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include "filter.h"
#include <math.h>
#if !defined M_PI
#define M_PI 3.14159265358979323846
#endif
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "fft4g.h"
#include "ccrw2.h"
#if 1 || HAVE_DOUBLE_PRECISION /* Always need this, for lsx_fir_to_phase. */
#define DFT_FLOAT double
#define DONE_WITH_FFT_CACHE done_with_fft_cache
#define FFT_CACHE_CCRW fft_cache_ccrw
#define FFT_LEN fft_len
#define LSX_CDFT lsx_cdft
#define LSX_CLEAR_FFT_CACHE lsx_clear_fft_cache
#define LSX_FFT_BR lsx_fft_br
#define LSX_FFT_SC lsx_fft_sc
#define LSX_INIT_FFT_CACHE lsx_init_fft_cache
#define LSX_RDFT lsx_rdft
#define LSX_SAFE_CDFT lsx_safe_cdft
#define LSX_SAFE_RDFT lsx_safe_rdft
#define UPDATE_FFT_CACHE update_fft_cache
#include "fft4g_cache.h"
#endif
#if HAVE_SINGLE_PRECISION && !HAVE_AVFFT
#define DFT_FLOAT float
#define DONE_WITH_FFT_CACHE done_with_fft_cache_f
#define FFT_CACHE_CCRW fft_cache_ccrw_f
#define FFT_LEN fft_len_f
#define LSX_CDFT lsx_cdft_f
#define LSX_CLEAR_FFT_CACHE lsx_clear_fft_cache_f
#define LSX_FFT_BR lsx_fft_br_f
#define LSX_FFT_SC lsx_fft_sc_f
#define LSX_INIT_FFT_CACHE lsx_init_fft_cache_f
#define LSX_RDFT lsx_rdft_f
#define LSX_SAFE_CDFT lsx_safe_cdft_f
#define LSX_SAFE_RDFT lsx_safe_rdft_f
#define UPDATE_FFT_CACHE update_fft_cache_f
#include "fft4g_cache.h"
#endif
#if HAVE_DOUBLE_PRECISION || !SOXR_LIB
#define DFT_FLOAT double
#define ORDERED_CONVOLVE lsx_ordered_convolve
#define ORDERED_PARTIAL_CONVOLVE lsx_ordered_partial_convolve
#include "rdft.h"
#endif
#if HAVE_SINGLE_PRECISION
#define DFT_FLOAT float
#define ORDERED_CONVOLVE lsx_ordered_convolve_f
#define ORDERED_PARTIAL_CONVOLVE lsx_ordered_partial_convolve_f
#include "rdft.h"
#endif
double lsx_kaiser_beta(double att, double tr_bw)
{
if (att >= 60) {
static const double coefs[][4] = {
{-6.784957e-10,1.02856e-05,0.1087556,-0.8988365+.001},
{-6.897885e-10,1.027433e-05,0.10876,-0.8994658+.002},
{-1.000683e-09,1.030092e-05,0.1087677,-0.9007898+.003},
{-3.654474e-10,1.040631e-05,0.1087085,-0.8977766+.006},
{8.106988e-09,6.983091e-06,0.1091387,-0.9172048+.015},
{9.519571e-09,7.272678e-06,0.1090068,-0.9140768+.025},
{-5.626821e-09,1.342186e-05,0.1083999,-0.9065452+.05},
{-9.965946e-08,5.073548e-05,0.1040967,-0.7672778+.085},
{1.604808e-07,-5.856462e-05,0.1185998,-1.34824+.1},
{-1.511964e-07,6.363034e-05,0.1064627,-0.9876665+.18},
};
double realm = log(tr_bw/.0005)/log(2.);
double const * c0 = coefs[range_limit( (int)realm, 0, (int)array_length(coefs)-1)];
double const * c1 = coefs[range_limit(1+(int)realm, 0, (int)array_length(coefs)-1)];
double b0 = ((c0[0]*att + c0[1])*att + c0[2])*att + c0[3];
double b1 = ((c1[0]*att + c1[1])*att + c1[2])*att + c1[3];
return b0 + (b1 - b0) * (realm - (int)realm);
}
if (att > 50 ) return .1102 * (att - 8.7);
if (att > 20.96) return .58417 * pow(att -20.96, .4) + .07886 * (att - 20.96);
return 0;
}
double * lsx_make_lpf(
int num_taps, double Fc, double beta, double rho, double scale)
{
int i, m = num_taps - 1;
double * h = malloc((size_t)num_taps * sizeof(*h));
double mult = scale / lsx_bessel_I_0(beta), mult1 = 1 / (.5 * m + rho);
assert(Fc >= 0 && Fc <= 1);
lsx_debug("make_lpf(n=%i Fc=%.7g β=%g ρ=%g scale=%g)",
num_taps, Fc, beta, rho, scale);
if (h) for (i = 0; i <= m / 2; ++i) {
double z = i - .5 * m, x = z * M_PI, y = z * mult1;
h[i] = x? sin(Fc * x) / x : Fc;
h[i] *= lsx_bessel_I_0(beta * sqrt(1 - y * y)) * mult;
if (m - i != i)
h[m - i] = h[i];
}
return h;
}
void lsx_kaiser_params(double att, double Fc, double tr_bw, double * beta, int * num_taps)
{
*beta = *beta < 0? lsx_kaiser_beta(att, tr_bw * .5 / Fc): *beta;
att = att < 60? (att - 7.95) / (2.285 * M_PI * 2) :
((.0007528358-1.577737e-05**beta)**beta+.6248022)**beta+.06186902;
*num_taps = !*num_taps? (int)ceil(att/tr_bw + 1) : *num_taps;
}
double * lsx_design_lpf(
double Fp, /* End of pass-band */
double Fs, /* Start of stop-band */
double Fn, /* Nyquist freq; e.g. 0.5, 1, PI */
double att, /* Stop-band attenuation in dB */
int * num_taps, /* 0: value will be estimated */
int k, /* >0: number of phases; <0: num_taps ≡ 1 (mod -k) */
double beta) /* <0: value will be estimated */
{
int n = *num_taps, phases = max(k, 1), modulo = max(-k, 1);
double tr_bw, Fc, rho = phases == 1? .5 : att < 120? .63 : .75;
Fp /= fabs(Fn), Fs /= fabs(Fn); /* Normalise to Fn = 1 */
tr_bw = .5 * (Fs - Fp); /* Transition band-width: 6dB to stop points */
tr_bw /= phases, Fs /= phases;
tr_bw = min(tr_bw, .5 * Fs);
Fc = Fs - tr_bw;
assert(Fc - tr_bw >= 0);
lsx_kaiser_params(att, Fc, tr_bw, &beta, num_taps);
if (!n)
*num_taps = phases > 1? *num_taps / phases * phases + phases - 1 :
(*num_taps + modulo - 2) / modulo * modulo + 1;
return Fn < 0? 0 : lsx_make_lpf(*num_taps, Fc, beta, rho, (double)phases);
}
static double safe_log(double x)
{
assert(x >= 0);
if (x)
return log(x);
lsx_debug("log(0)");
return -26;
}
void lsx_fir_to_phase(double * * h, int * len, int * post_len, double phase)
{
double * pi_wraps, * work, phase1 = (phase > 50 ? 100 - phase : phase) / 50;
int i, work_len, begin, end, imp_peak = 0, peak = 0;
double imp_sum = 0, peak_imp_sum = 0;
double prev_angle2 = 0, cum_2pi = 0, prev_angle1 = 0, cum_1pi = 0;
for (i = *len, work_len = 2 * 2 * 8; i > 1; work_len <<= 1, i >>= 1);
work = calloc((size_t)work_len + 2, sizeof(*work)); /* +2: (UN)PACK */
pi_wraps = malloc((((size_t)work_len + 2) / 2) * sizeof(*pi_wraps));
memcpy(work, *h, (size_t)*len * sizeof(*work));
lsx_safe_rdft(work_len, 1, work); /* Cepstral: */
LSX_UNPACK(work, work_len);
for (i = 0; i <= work_len; i += 2) {
double angle = atan2(work[i + 1], work[i]);
double detect = 2 * M_PI;
double delta = angle - prev_angle2;
double adjust = detect * ((delta < -detect * .7) - (delta > detect * .7));
prev_angle2 = angle;
cum_2pi += adjust;
angle += cum_2pi;
detect = M_PI;
delta = angle - prev_angle1;
adjust = detect * ((delta < -detect * .7) - (delta > detect * .7));
prev_angle1 = angle;
cum_1pi += fabs(adjust); /* fabs for when 2pi and 1pi have combined */
pi_wraps[i >> 1] = cum_1pi;
work[i] = safe_log(sqrt(sqr(work[i]) + sqr(work[i + 1])));
work[i + 1] = 0;
}
LSX_PACK(work, work_len);
lsx_safe_rdft(work_len, -1, work);
for (i = 0; i < work_len; ++i) work[i] *= 2. / work_len;
for (i = 1; i < work_len / 2; ++i) { /* Window to reject acausal components */
work[i] *= 2;
work[i + work_len / 2] = 0;
}
lsx_safe_rdft(work_len, 1, work);
for (i = 2; i < work_len; i += 2) /* Interpolate between linear & min phase */
work[i + 1] = phase1 * i / work_len * pi_wraps[work_len >> 1] +
(1 - phase1) * (work[i + 1] + pi_wraps[i >> 1]) - pi_wraps[i >> 1];
work[0] = exp(work[0]), work[1] = exp(work[1]);
for (i = 2; i < work_len; i += 2) {
double x = exp(work[i]);
work[i ] = x * cos(work[i + 1]);
work[i + 1] = x * sin(work[i + 1]);
}
lsx_safe_rdft(work_len, -1, work);
for (i = 0; i < work_len; ++i) work[i] *= 2. / work_len;
/* Find peak pos. */
for (i = 0; i <= (int)(pi_wraps[work_len >> 1] / M_PI + .5); ++i) {
imp_sum += work[i];
if (fabs(imp_sum) > fabs(peak_imp_sum)) {
peak_imp_sum = imp_sum;
peak = i;
}
if (work[i] > work[imp_peak]) /* For debug check only */
imp_peak = i;
}
while (peak && fabs(work[peak-1]) > fabs(work[peak]) && work[peak-1] * work[peak] > 0)
--peak;
if (!phase1)
begin = 0;
else if (phase1 == 1)
begin = peak - *len / 2;
else {
begin = (int)((.997 - (2 - phase1) * .22) * *len + .5);
end = (int)((.997 + (0 - phase1) * .22) * *len + .5);
begin = peak - (begin & ~3);
end = peak + 1 + ((end + 3) & ~3);
*len = end - begin;
*h = realloc(*h, (size_t)*len * sizeof(**h));
}
for (i = 0; i < *len; ++i) (*h)[i] =
work[(begin + (phase > 50 ? *len - 1 - i : i) + work_len) & (work_len - 1)];
*post_len = phase > 50 ? peak - begin : begin + *len - (peak + 1);
lsx_debug("nPI=%g peak-sum@%i=%g (val@%i=%g); len=%i post=%i (%g%%)",
pi_wraps[work_len >> 1] / M_PI, peak, peak_imp_sum, imp_peak,
work[imp_peak], *len, *post_len, 100 - 100. * *post_len / (*len - 1));
free(pi_wraps), free(work);
}
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include "filter.h"
#include <math.h>
#if !defined M_PI
#define M_PI 3.14159265358979323846
#endif
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "fft4g.h"
#include "ccrw2.h"
#if 1 || HAVE_DOUBLE_PRECISION /* Always need this, for lsx_fir_to_phase. */
#define DFT_FLOAT double
#define DONE_WITH_FFT_CACHE done_with_fft_cache
#define FFT_CACHE_CCRW fft_cache_ccrw
#define FFT_LEN fft_len
#define LSX_CDFT lsx_cdft
#define LSX_CLEAR_FFT_CACHE lsx_clear_fft_cache
#define LSX_FFT_BR lsx_fft_br
#define LSX_FFT_SC lsx_fft_sc
#define LSX_INIT_FFT_CACHE lsx_init_fft_cache
#define LSX_RDFT lsx_rdft
#define LSX_SAFE_CDFT lsx_safe_cdft
#define LSX_SAFE_RDFT lsx_safe_rdft
#define UPDATE_FFT_CACHE update_fft_cache
#include "fft4g_cache.h"
#endif
#if HAVE_SINGLE_PRECISION && !HAVE_AVFFT
#define DFT_FLOAT float
#define DONE_WITH_FFT_CACHE done_with_fft_cache_f
#define FFT_CACHE_CCRW fft_cache_ccrw_f
#define FFT_LEN fft_len_f
#define LSX_CDFT lsx_cdft_f
#define LSX_CLEAR_FFT_CACHE lsx_clear_fft_cache_f
#define LSX_FFT_BR lsx_fft_br_f
#define LSX_FFT_SC lsx_fft_sc_f
#define LSX_INIT_FFT_CACHE lsx_init_fft_cache_f
#define LSX_RDFT lsx_rdft_f
#define LSX_SAFE_CDFT lsx_safe_cdft_f
#define LSX_SAFE_RDFT lsx_safe_rdft_f
#define UPDATE_FFT_CACHE update_fft_cache_f
#include "fft4g_cache.h"
#endif
#if HAVE_DOUBLE_PRECISION || !SOXR_LIB
#define DFT_FLOAT double
#define ORDERED_CONVOLVE lsx_ordered_convolve
#define ORDERED_PARTIAL_CONVOLVE lsx_ordered_partial_convolve
#include "rdft.h"
#endif
#if HAVE_SINGLE_PRECISION
#define DFT_FLOAT float
#define ORDERED_CONVOLVE lsx_ordered_convolve_f
#define ORDERED_PARTIAL_CONVOLVE lsx_ordered_partial_convolve_f
#include "rdft.h"
#endif
double lsx_kaiser_beta(double att, double tr_bw)
{
if (att >= 60) {
static const double coefs[][4] = {
{-6.784957e-10,1.02856e-05,0.1087556,-0.8988365+.001},
{-6.897885e-10,1.027433e-05,0.10876,-0.8994658+.002},
{-1.000683e-09,1.030092e-05,0.1087677,-0.9007898+.003},
{-3.654474e-10,1.040631e-05,0.1087085,-0.8977766+.006},
{8.106988e-09,6.983091e-06,0.1091387,-0.9172048+.015},
{9.519571e-09,7.272678e-06,0.1090068,-0.9140768+.025},
{-5.626821e-09,1.342186e-05,0.1083999,-0.9065452+.05},
{-9.965946e-08,5.073548e-05,0.1040967,-0.7672778+.085},
{1.604808e-07,-5.856462e-05,0.1185998,-1.34824+.1},
{-1.511964e-07,6.363034e-05,0.1064627,-0.9876665+.18},
};
double realm = log(tr_bw/.0005)/log(2.);
double const * c0 = coefs[range_limit( (int)realm, 0, (int)array_length(coefs)-1)];
double const * c1 = coefs[range_limit(1+(int)realm, 0, (int)array_length(coefs)-1)];
double b0 = ((c0[0]*att + c0[1])*att + c0[2])*att + c0[3];
double b1 = ((c1[0]*att + c1[1])*att + c1[2])*att + c1[3];
return b0 + (b1 - b0) * (realm - (int)realm);
}
if (att > 50 ) return .1102 * (att - 8.7);
if (att > 20.96) return .58417 * pow(att -20.96, .4) + .07886 * (att - 20.96);
return 0;
}
double * lsx_make_lpf(
int num_taps, double Fc, double beta, double rho, double scale)
{
int i, m = num_taps - 1;
double * h = malloc((size_t)num_taps * sizeof(*h));
double mult = scale / lsx_bessel_I_0(beta), mult1 = 1 / (.5 * m + rho);
assert(Fc >= 0 && Fc <= 1);
lsx_debug("make_lpf(n=%i Fc=%.7g β=%g ρ=%g scale=%g)",
num_taps, Fc, beta, rho, scale);
if (h) for (i = 0; i <= m / 2; ++i) {
double z = i - .5 * m, x = z * M_PI, y = z * mult1;
h[i] = x? sin(Fc * x) / x : Fc;
h[i] *= lsx_bessel_I_0(beta * sqrt(1 - y * y)) * mult;
if (m - i != i)
h[m - i] = h[i];
}
return h;
}
void lsx_kaiser_params(double att, double Fc, double tr_bw, double * beta, int * num_taps)
{
*beta = *beta < 0? lsx_kaiser_beta(att, tr_bw * .5 / Fc): *beta;
att = att < 60? (att - 7.95) / (2.285 * M_PI * 2) :
((.0007528358-1.577737e-05**beta)**beta+.6248022)**beta+.06186902;
*num_taps = !*num_taps? (int)ceil(att/tr_bw + 1) : *num_taps;
}
double * lsx_design_lpf(
double Fp, /* End of pass-band */
double Fs, /* Start of stop-band */
double Fn, /* Nyquist freq; e.g. 0.5, 1, PI */
double att, /* Stop-band attenuation in dB */
int * num_taps, /* 0: value will be estimated */
int k, /* >0: number of phases; <0: num_taps ≡ 1 (mod -k) */
double beta) /* <0: value will be estimated */
{
int n = *num_taps, phases = max(k, 1), modulo = max(-k, 1);
double tr_bw, Fc, rho = phases == 1? .5 : att < 120? .63 : .75;
Fp /= fabs(Fn), Fs /= fabs(Fn); /* Normalise to Fn = 1 */
tr_bw = .5 * (Fs - Fp); /* Transition band-width: 6dB to stop points */
tr_bw /= phases, Fs /= phases;
tr_bw = min(tr_bw, .5 * Fs);
Fc = Fs - tr_bw;
assert(Fc - tr_bw >= 0);
lsx_kaiser_params(att, Fc, tr_bw, &beta, num_taps);
if (!n)
*num_taps = phases > 1? *num_taps / phases * phases + phases - 1 :
(*num_taps + modulo - 2) / modulo * modulo + 1;
return Fn < 0? 0 : lsx_make_lpf(*num_taps, Fc, beta, rho, (double)phases);
}
static double safe_log(double x)
{
assert(x >= 0);
if (x)
return log(x);
lsx_debug("log(0)");
return -26;
}
void lsx_fir_to_phase(double * * h, int * len, int * post_len, double phase)
{
double * pi_wraps, * work, phase1 = (phase > 50 ? 100 - phase : phase) / 50;
int i, work_len, begin, end, imp_peak = 0, peak = 0;
double imp_sum = 0, peak_imp_sum = 0;
double prev_angle2 = 0, cum_2pi = 0, prev_angle1 = 0, cum_1pi = 0;
for (i = *len, work_len = 2 * 2 * 8; i > 1; work_len <<= 1, i >>= 1);
work = calloc((size_t)work_len + 2, sizeof(*work)); /* +2: (UN)PACK */
pi_wraps = malloc((((size_t)work_len + 2) / 2) * sizeof(*pi_wraps));
memcpy(work, *h, (size_t)*len * sizeof(*work));
lsx_safe_rdft(work_len, 1, work); /* Cepstral: */
LSX_UNPACK(work, work_len);
for (i = 0; i <= work_len; i += 2) {
double angle = atan2(work[i + 1], work[i]);
double detect = 2 * M_PI;
double delta = angle - prev_angle2;
double adjust = detect * ((delta < -detect * .7) - (delta > detect * .7));
prev_angle2 = angle;
cum_2pi += adjust;
angle += cum_2pi;
detect = M_PI;
delta = angle - prev_angle1;
adjust = detect * ((delta < -detect * .7) - (delta > detect * .7));
prev_angle1 = angle;
cum_1pi += fabs(adjust); /* fabs for when 2pi and 1pi have combined */
pi_wraps[i >> 1] = cum_1pi;
work[i] = safe_log(sqrt(sqr(work[i]) + sqr(work[i + 1])));
work[i + 1] = 0;
}
LSX_PACK(work, work_len);
lsx_safe_rdft(work_len, -1, work);
for (i = 0; i < work_len; ++i) work[i] *= 2. / work_len;
for (i = 1; i < work_len / 2; ++i) { /* Window to reject acausal components */
work[i] *= 2;
work[i + work_len / 2] = 0;
}
lsx_safe_rdft(work_len, 1, work);
for (i = 2; i < work_len; i += 2) /* Interpolate between linear & min phase */
work[i + 1] = phase1 * i / work_len * pi_wraps[work_len >> 1] +
(1 - phase1) * (work[i + 1] + pi_wraps[i >> 1]) - pi_wraps[i >> 1];
work[0] = exp(work[0]), work[1] = exp(work[1]);
for (i = 2; i < work_len; i += 2) {
double x = exp(work[i]);
work[i ] = x * cos(work[i + 1]);
work[i + 1] = x * sin(work[i + 1]);
}
lsx_safe_rdft(work_len, -1, work);
for (i = 0; i < work_len; ++i) work[i] *= 2. / work_len;
/* Find peak pos. */
for (i = 0; i <= (int)(pi_wraps[work_len >> 1] / M_PI + .5); ++i) {
imp_sum += work[i];
if (fabs(imp_sum) > fabs(peak_imp_sum)) {
peak_imp_sum = imp_sum;
peak = i;
}
if (work[i] > work[imp_peak]) /* For debug check only */
imp_peak = i;
}
while (peak && fabs(work[peak-1]) > fabs(work[peak]) && work[peak-1] * work[peak] > 0)
--peak;
if (!phase1)
begin = 0;
else if (phase1 == 1)
begin = peak - *len / 2;
else {
begin = (int)((.997 - (2 - phase1) * .22) * *len + .5);
end = (int)((.997 + (0 - phase1) * .22) * *len + .5);
begin = peak - (begin & ~3);
end = peak + 1 + ((end + 3) & ~3);
*len = end - begin;
*h = realloc(*h, (size_t)*len * sizeof(**h));
}
for (i = 0; i < *len; ++i) (*h)[i] =
work[(begin + (phase > 50 ? *len - 1 - i : i) + work_len) & (work_len - 1)];
*post_len = phase > 50 ? peak - begin : begin + *len - (peak + 1);
lsx_debug("nPI=%g peak-sum@%i=%g (val@%i=%g); len=%i post=%i (%g%%)",
pi_wraps[work_len >> 1] / M_PI, peak, peak_imp_sum, imp_peak,
work[imp_peak], *len, *post_len, 100 - 100. * *post_len / (*len - 1));
free(pi_wraps), free(work);
}

View File

@@ -1,39 +1,39 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if !defined soxr_filter_included
#define soxr_filter_included
#include "aliases.h"
double lsx_bessel_I_0(double x);
void lsx_init_fft_cache(void);
void lsx_clear_fft_cache(void);
void lsx_init_fft_cache_f(void);
void lsx_clear_fft_cache_f(void);
#define lsx_is_power_of_2(x) !(x < 2 || (x & (x - 1)))
void lsx_safe_rdft(int len, int type, double * d);
void lsx_safe_cdft(int len, int type, double * d);
void lsx_safe_rdft_f(int len, int type, float * d);
void lsx_safe_cdft_f(int len, int type, float * d);
void lsx_ordered_convolve(int n, void * not_used, double * a, const double * b);
void lsx_ordered_convolve_f(int n, void * not_used, float * a, const float * b);
void lsx_ordered_partial_convolve(int n, double * a, const double * b);
void lsx_ordered_partial_convolve_f(int n, float * a, const float * b);
double lsx_kaiser_beta(double att, double tr_bw);
double * lsx_make_lpf(int num_taps, double Fc, double beta, double rho,
double scale);
void lsx_kaiser_params(double att, double Fc, double tr_bw, double * beta, int * num_taps);
double * lsx_design_lpf(
double Fp, /* End of pass-band */
double Fs, /* Start of stop-band */
double Fn, /* Nyquist freq; e.g. 0.5, 1, PI; < 0: dummy run */
double att, /* Stop-band attenuation in dB */
int * num_taps, /* 0: value will be estimated */
int k, /* >0: number of phases; <0: num_taps ≡ 1 (mod -k) */
double beta); /* <0: value will be estimated */
void lsx_fir_to_phase(double * * h, int * len,
int * post_len, double phase0);
#endif
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if !defined soxr_filter_included
#define soxr_filter_included
#include "aliases.h"
double lsx_bessel_I_0(double x);
void lsx_init_fft_cache(void);
void lsx_clear_fft_cache(void);
void lsx_init_fft_cache_f(void);
void lsx_clear_fft_cache_f(void);
#define lsx_is_power_of_2(x) !(x < 2 || (x & (x - 1)))
void lsx_safe_rdft(int len, int type, double * d);
void lsx_safe_cdft(int len, int type, double * d);
void lsx_safe_rdft_f(int len, int type, float * d);
void lsx_safe_cdft_f(int len, int type, float * d);
void lsx_ordered_convolve(int n, void * not_used, double * a, const double * b);
void lsx_ordered_convolve_f(int n, void * not_used, float * a, const float * b);
void lsx_ordered_partial_convolve(int n, double * a, const double * b);
void lsx_ordered_partial_convolve_f(int n, float * a, const float * b);
double lsx_kaiser_beta(double att, double tr_bw);
double * lsx_make_lpf(int num_taps, double Fc, double beta, double rho,
double scale);
void lsx_kaiser_params(double att, double Fc, double tr_bw, double * beta, int * num_taps);
double * lsx_design_lpf(
double Fp, /* End of pass-band */
double Fs, /* Start of stop-band */
double Fn, /* Nyquist freq; e.g. 0.5, 1, PI; < 0: dummy run */
double att, /* Stop-band attenuation in dB */
int * num_taps, /* 0: value will be estimated */
int k, /* >0: number of phases; <0: num_taps ≡ 1 (mod -k) */
double beta); /* <0: value will be estimated */
void lsx_fir_to_phase(double * * h, int * len,
int * post_len, double phase0);
#endif

View File

@@ -1,151 +1,151 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include "half_coefs.h"
#define FUNCTION h8
#define CONVOLVE _ _ _ _ _ _ _ _
#define h8_l 8
#define COEFS half_fir_coefs_8
#include "half-fir.h"
#define FUNCTION h9
#define CONVOLVE _ _ _ _ _ _ _ _ _
#define h9_l 9
#define COEFS half_fir_coefs_9
#include "half-fir.h"
#define FUNCTION h10
#define CONVOLVE _ _ _ _ _ _ _ _ _ _
#define h10_l 10
#define COEFS half_fir_coefs_10
#include "half-fir.h"
#define FUNCTION h11
#define CONVOLVE _ _ _ _ _ _ _ _ _ _ _
#define h11_l 11
#define COEFS half_fir_coefs_11
#include "half-fir.h"
#define FUNCTION h12
#define CONVOLVE _ _ _ _ _ _ _ _ _ _ _ _
#define h12_l 12
#define COEFS half_fir_coefs_12
#include "half-fir.h"
#define FUNCTION h13
#define CONVOLVE _ _ _ _ _ _ _ _ _ _ _ _ _
#define h13_l 13
#define COEFS half_fir_coefs_13
#include "half-fir.h"
static struct {int num_coefs; stage_fn_t fn; float att;} const half_firs[] = {
{ 8, h8 , 136.51f},
{ 9, h9 , 152.32f},
{10, h10, 168.07f},
{11, h11, 183.78f},
{12, h12, 199.44f},
{13, h13, 212.75f},
};
#define HI_PREC_CLOCK
#define VAR_LENGTH p->n
#define VAR_CONVOLVE while (j < FIR_LENGTH) _
#define VAR_POLY_PHASE_BITS p->phase_bits
#define FUNCTION vpoly0
#define FIR_LENGTH VAR_LENGTH
#define CONVOLVE VAR_CONVOLVE
#include "poly-fir0.h"
#define FUNCTION vpoly1
#define COEF_INTERP 1
#define PHASE_BITS VAR_POLY_PHASE_BITS
#define FIR_LENGTH VAR_LENGTH
#define CONVOLVE VAR_CONVOLVE
#include "poly-fir.h"
#define FUNCTION vpoly2
#define COEF_INTERP 2
#define PHASE_BITS VAR_POLY_PHASE_BITS
#define FIR_LENGTH VAR_LENGTH
#define CONVOLVE VAR_CONVOLVE
#include "poly-fir.h"
#define FUNCTION vpoly3
#define COEF_INTERP 3
#define PHASE_BITS VAR_POLY_PHASE_BITS
#define FIR_LENGTH VAR_LENGTH
#define CONVOLVE VAR_CONVOLVE
#include "poly-fir.h"
#undef HI_PREC_CLOCK
#define U100_l 42
#if RATE_SIMD_POLY
#define U100_l_EXTRA _ _
#define u100_l_EXTRA _
#define U100_l_EXTRA_LENGTH 2
#define u100_l_EXTRA_LENGTH 1
#else
#define U100_l_EXTRA
#define u100_l_EXTRA
#define U100_l_EXTRA_LENGTH 0
#define u100_l_EXTRA_LENGTH 0
#endif
#define poly_fir_convolve_U100 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ U100_l_EXTRA
#define FUNCTION U100_0
#define FIR_LENGTH (U100_l + U100_l_EXTRA_LENGTH)
#define CONVOLVE poly_fir_convolve_U100
#include "poly-fir0.h"
#define u100_l 11
#define poly_fir_convolve_u100 _ _ _ _ _ _ _ _ _ _ _ u100_l_EXTRA
#define FUNCTION u100_0
#define FIR_LENGTH (u100_l + u100_l_EXTRA_LENGTH)
#define CONVOLVE poly_fir_convolve_u100
#include "poly-fir0.h"
#define FUNCTION u100_1
#define COEF_INTERP 1
#define PHASE_BITS 8
#define FIR_LENGTH (u100_l + u100_l_EXTRA_LENGTH)
#define CONVOLVE poly_fir_convolve_u100
#include "poly-fir.h"
#define u100_1_b 8
#define FUNCTION u100_2
#define COEF_INTERP 2
#define PHASE_BITS 6
#define FIR_LENGTH (u100_l + u100_l_EXTRA_LENGTH)
#define CONVOLVE poly_fir_convolve_u100
#include "poly-fir.h"
#define u100_2_b 6
typedef struct {float scalar; stage_fn_t fn;} poly_fir1_t;
typedef struct {float beta; poly_fir1_t interp[3];} poly_fir_t;
static poly_fir_t const poly_firs[] = {
{-1, {{0, vpoly0}, { 7.2f, vpoly1}, {5.0f, vpoly2}}},
{-1, {{0, vpoly0}, { 9.4f, vpoly1}, {6.7f, vpoly2}}},
{-1, {{0, vpoly0}, {12.4f, vpoly1}, {7.8f, vpoly2}}},
{-1, {{0, vpoly0}, {13.6f, vpoly1}, {9.3f, vpoly2}}},
{-1, {{0, vpoly0}, {10.5f, vpoly2}, {8.4f, vpoly3}}},
{-1, {{0, vpoly0}, {11.85f,vpoly2}, {9.0f, vpoly3}}},
{-1, {{0, vpoly0}, { 8.0f, vpoly1}, {5.3f, vpoly2}}},
{-1, {{0, vpoly0}, { 8.6f, vpoly1}, {5.7f, vpoly2}}},
{-1, {{0, vpoly0}, {10.6f, vpoly1}, {6.75f,vpoly2}}},
{-1, {{0, vpoly0}, {12.6f, vpoly1}, {8.6f, vpoly2}}},
{-1, {{0, vpoly0}, { 9.6f, vpoly2}, {7.6f, vpoly3}}},
{-1, {{0, vpoly0}, {11.4f, vpoly2}, {8.65f,vpoly3}}},
{10.62f, {{U100_l, U100_0}, {0, 0}, {0, 0}}},
{11.28f, {{u100_l, u100_0}, {u100_1_b, u100_1}, {u100_2_b, u100_2}}},
{-1, {{0, vpoly0}, { 9, vpoly1}, { 6, vpoly2}}},
{-1, {{0, vpoly0}, { 11, vpoly1}, { 7, vpoly2}}},
{-1, {{0, vpoly0}, { 13, vpoly1}, { 8, vpoly2}}},
{-1, {{0, vpoly0}, { 10, vpoly2}, { 8, vpoly3}}},
{-1, {{0, vpoly0}, { 12, vpoly2}, { 9, vpoly3}}},
};
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include "half_coefs.h"
#define FUNCTION h8
#define CONVOLVE _ _ _ _ _ _ _ _
#define h8_l 8
#define COEFS half_fir_coefs_8
#include "half-fir.h"
#define FUNCTION h9
#define CONVOLVE _ _ _ _ _ _ _ _ _
#define h9_l 9
#define COEFS half_fir_coefs_9
#include "half-fir.h"
#define FUNCTION h10
#define CONVOLVE _ _ _ _ _ _ _ _ _ _
#define h10_l 10
#define COEFS half_fir_coefs_10
#include "half-fir.h"
#define FUNCTION h11
#define CONVOLVE _ _ _ _ _ _ _ _ _ _ _
#define h11_l 11
#define COEFS half_fir_coefs_11
#include "half-fir.h"
#define FUNCTION h12
#define CONVOLVE _ _ _ _ _ _ _ _ _ _ _ _
#define h12_l 12
#define COEFS half_fir_coefs_12
#include "half-fir.h"
#define FUNCTION h13
#define CONVOLVE _ _ _ _ _ _ _ _ _ _ _ _ _
#define h13_l 13
#define COEFS half_fir_coefs_13
#include "half-fir.h"
static struct {int num_coefs; stage_fn_t fn; float att;} const half_firs[] = {
{ 8, h8 , 136.51f},
{ 9, h9 , 152.32f},
{10, h10, 168.07f},
{11, h11, 183.78f},
{12, h12, 199.44f},
{13, h13, 212.75f},
};
#define HI_PREC_CLOCK
#define VAR_LENGTH p->n
#define VAR_CONVOLVE while (j < FIR_LENGTH) _
#define VAR_POLY_PHASE_BITS p->phase_bits
#define FUNCTION vpoly0
#define FIR_LENGTH VAR_LENGTH
#define CONVOLVE VAR_CONVOLVE
#include "poly-fir0.h"
#define FUNCTION vpoly1
#define COEF_INTERP 1
#define PHASE_BITS VAR_POLY_PHASE_BITS
#define FIR_LENGTH VAR_LENGTH
#define CONVOLVE VAR_CONVOLVE
#include "poly-fir.h"
#define FUNCTION vpoly2
#define COEF_INTERP 2
#define PHASE_BITS VAR_POLY_PHASE_BITS
#define FIR_LENGTH VAR_LENGTH
#define CONVOLVE VAR_CONVOLVE
#include "poly-fir.h"
#define FUNCTION vpoly3
#define COEF_INTERP 3
#define PHASE_BITS VAR_POLY_PHASE_BITS
#define FIR_LENGTH VAR_LENGTH
#define CONVOLVE VAR_CONVOLVE
#include "poly-fir.h"
#undef HI_PREC_CLOCK
#define U100_l 42
#if RATE_SIMD_POLY
#define U100_l_EXTRA _ _
#define u100_l_EXTRA _
#define U100_l_EXTRA_LENGTH 2
#define u100_l_EXTRA_LENGTH 1
#else
#define U100_l_EXTRA
#define u100_l_EXTRA
#define U100_l_EXTRA_LENGTH 0
#define u100_l_EXTRA_LENGTH 0
#endif
#define poly_fir_convolve_U100 _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ U100_l_EXTRA
#define FUNCTION U100_0
#define FIR_LENGTH (U100_l + U100_l_EXTRA_LENGTH)
#define CONVOLVE poly_fir_convolve_U100
#include "poly-fir0.h"
#define u100_l 11
#define poly_fir_convolve_u100 _ _ _ _ _ _ _ _ _ _ _ u100_l_EXTRA
#define FUNCTION u100_0
#define FIR_LENGTH (u100_l + u100_l_EXTRA_LENGTH)
#define CONVOLVE poly_fir_convolve_u100
#include "poly-fir0.h"
#define FUNCTION u100_1
#define COEF_INTERP 1
#define PHASE_BITS 8
#define FIR_LENGTH (u100_l + u100_l_EXTRA_LENGTH)
#define CONVOLVE poly_fir_convolve_u100
#include "poly-fir.h"
#define u100_1_b 8
#define FUNCTION u100_2
#define COEF_INTERP 2
#define PHASE_BITS 6
#define FIR_LENGTH (u100_l + u100_l_EXTRA_LENGTH)
#define CONVOLVE poly_fir_convolve_u100
#include "poly-fir.h"
#define u100_2_b 6
typedef struct {float scalar; stage_fn_t fn;} poly_fir1_t;
typedef struct {float beta; poly_fir1_t interp[3];} poly_fir_t;
static poly_fir_t const poly_firs[] = {
{-1, {{0, vpoly0}, { 7.2f, vpoly1}, {5.0f, vpoly2}}},
{-1, {{0, vpoly0}, { 9.4f, vpoly1}, {6.7f, vpoly2}}},
{-1, {{0, vpoly0}, {12.4f, vpoly1}, {7.8f, vpoly2}}},
{-1, {{0, vpoly0}, {13.6f, vpoly1}, {9.3f, vpoly2}}},
{-1, {{0, vpoly0}, {10.5f, vpoly2}, {8.4f, vpoly3}}},
{-1, {{0, vpoly0}, {11.85f,vpoly2}, {9.0f, vpoly3}}},
{-1, {{0, vpoly0}, { 8.0f, vpoly1}, {5.3f, vpoly2}}},
{-1, {{0, vpoly0}, { 8.6f, vpoly1}, {5.7f, vpoly2}}},
{-1, {{0, vpoly0}, {10.6f, vpoly1}, {6.75f,vpoly2}}},
{-1, {{0, vpoly0}, {12.6f, vpoly1}, {8.6f, vpoly2}}},
{-1, {{0, vpoly0}, { 9.6f, vpoly2}, {7.6f, vpoly3}}},
{-1, {{0, vpoly0}, {11.4f, vpoly2}, {8.65f,vpoly3}}},
{10.62f, {{U100_l, U100_0}, {0, 0}, {0, 0}}},
{11.28f, {{u100_l, u100_0}, {u100_1_b, u100_1}, {u100_2_b, u100_2}}},
{-1, {{0, vpoly0}, { 9, vpoly1}, { 6, vpoly2}}},
{-1, {{0, vpoly0}, { 11, vpoly1}, { 7, vpoly2}}},
{-1, {{0, vpoly0}, { 13, vpoly1}, { 8, vpoly2}}},
{-1, {{0, vpoly0}, { 10, vpoly2}, { 8, vpoly3}}},
{-1, {{0, vpoly0}, { 12, vpoly2}, { 9, vpoly3}}},
};

View File

@@ -1,25 +1,25 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Down-sample by a factor of 2 using a FIR with odd length (LEN).*/
/* Input must be preceded and followed by LEN >> 1 samples. */
#define _ sum += (input[-(2*j +1)] + input[(2*j +1)]) * COEFS[j], ++j;
static void FUNCTION(stage_t * p, fifo_t * output_fifo)
{
sample_t const * input = stage_read_p(p);
int i, num_out = (stage_occupancy(p) + 1) / 2;
sample_t * output = fifo_reserve(output_fifo, num_out);
for (i = 0; i < num_out; ++i, input += 2) {
int j = 0;
sample_t sum = input[0] * .5f;
CONVOLVE
output[i] = sum;
}
fifo_read(&p->fifo, 2 * num_out, NULL);
}
#undef _
#undef COEFS
#undef CONVOLVE
#undef FUNCTION
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Down-sample by a factor of 2 using a FIR with odd length (LEN).*/
/* Input must be preceded and followed by LEN >> 1 samples. */
#define _ sum += (input[-(2*j +1)] + input[(2*j +1)]) * COEFS[j], ++j;
static void FUNCTION(stage_t * p, fifo_t * output_fifo)
{
sample_t const * input = stage_read_p(p);
int i, num_out = (stage_occupancy(p) + 1) / 2;
sample_t * output = fifo_reserve(output_fifo, num_out);
for (i = 0; i < num_out; ++i, input += 2) {
int j = 0;
sample_t sum = input[0] * .5f;
CONVOLVE
output[i] = sum;
}
fifo_read(&p->fifo, 2 * num_out, NULL);
}
#undef _
#undef COEFS
#undef CONVOLVE
#undef FUNCTION

View File

@@ -1,57 +1,57 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if defined __GNUC__
#pragma GCC system_header
#elif defined __SUNPRO_C
#pragma disable_warn
#elif defined _MSC_VER
#pragma warning(push, 1)
#endif
static const sample_t half_fir_coefs_8[] = {
0.3115465451887802, -0.08734497241282892, 0.03681452335604365,
-0.01518925831569441, 0.005454118437408876, -0.001564400922162005,
0.0003181701445034203, -3.48001341225749e-5,
};
static const sample_t half_fir_coefs_9[] = {
0.3122703613711853, -0.08922155288172305, 0.03913974805854332,
-0.01725059723447163, 0.006858970092378141, -0.002304518467568703,
0.0006096426006051062, -0.0001132393923815236, 1.119795386287666e-5,
};
static const sample_t half_fir_coefs_10[] = {
0.3128545521327376, -0.09075671986104322, 0.04109637155154835,
-0.01906629512749895, 0.008184039342054333, -0.0030766775017262,
0.0009639607022414314, -0.0002358552746579827, 4.025184282444155e-5,
-3.629779111541012e-6,
};
static const sample_t half_fir_coefs_11[] = {
0.3133358837508807, -0.09203588680609488, 0.04276515428384758,
-0.02067356614745591, 0.00942253142371517, -0.003856330993895144,
0.001363470684892284, -0.0003987400965541919, 9.058629923971627e-5,
-1.428553070915318e-5, 1.183455238783835e-6,
};
static const sample_t half_fir_coefs_12[] = {
0.3137392991811407, -0.0931182192961332, 0.0442050575271454,
-0.02210391200618091, 0.01057473015666001, -0.00462766983973885,
0.001793630226239453, -0.0005961819959665878, 0.0001631475979359577,
-3.45557865639653e-5, 5.06188341942088e-6, -3.877010943315563e-7,
};
static const sample_t half_fir_coefs_13[] = {
0.3140822554324578, -0.0940458550886253, 0.04545990399121566,
-0.02338339450796002, 0.01164429409071052, -0.005380686021429845,
0.002242915773871009, -0.000822047600000082, 0.0002572510962395222,
-6.607320708956279e-5, 1.309926399120154e-5, -1.790719575255006e-6,
1.27504961098836e-7,
};
#if defined __SUNPRO_C
#pragma enable_warn
#elif defined _MSC_VER
#pragma warning(pop)
#endif
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if defined __GNUC__
#pragma GCC system_header
#elif defined __SUNPRO_C
#pragma disable_warn
#elif defined _MSC_VER
#pragma warning(push, 1)
#endif
static const sample_t half_fir_coefs_8[] = {
0.3115465451887802, -0.08734497241282892, 0.03681452335604365,
-0.01518925831569441, 0.005454118437408876, -0.001564400922162005,
0.0003181701445034203, -3.48001341225749e-5,
};
static const sample_t half_fir_coefs_9[] = {
0.3122703613711853, -0.08922155288172305, 0.03913974805854332,
-0.01725059723447163, 0.006858970092378141, -0.002304518467568703,
0.0006096426006051062, -0.0001132393923815236, 1.119795386287666e-5,
};
static const sample_t half_fir_coefs_10[] = {
0.3128545521327376, -0.09075671986104322, 0.04109637155154835,
-0.01906629512749895, 0.008184039342054333, -0.0030766775017262,
0.0009639607022414314, -0.0002358552746579827, 4.025184282444155e-5,
-3.629779111541012e-6,
};
static const sample_t half_fir_coefs_11[] = {
0.3133358837508807, -0.09203588680609488, 0.04276515428384758,
-0.02067356614745591, 0.00942253142371517, -0.003856330993895144,
0.001363470684892284, -0.0003987400965541919, 9.058629923971627e-5,
-1.428553070915318e-5, 1.183455238783835e-6,
};
static const sample_t half_fir_coefs_12[] = {
0.3137392991811407, -0.0931182192961332, 0.0442050575271454,
-0.02210391200618091, 0.01057473015666001, -0.00462766983973885,
0.001793630226239453, -0.0005961819959665878, 0.0001631475979359577,
-3.45557865639653e-5, 5.06188341942088e-6, -3.877010943315563e-7,
};
static const sample_t half_fir_coefs_13[] = {
0.3140822554324578, -0.0940458550886253, 0.04545990399121566,
-0.02338339450796002, 0.01164429409071052, -0.005380686021429845,
0.002242915773871009, -0.000822047600000082, 0.0002572510962395222,
-6.607320708956279e-5, 1.309926399120154e-5, -1.790719575255006e-6,
1.27504961098836e-7,
};
#if defined __SUNPRO_C
#pragma enable_warn
#elif defined _MSC_VER
#pragma warning(pop)
#endif

View File

@@ -1,41 +1,46 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if !defined soxr_internal_included
#define soxr_internal_included
#include "soxr-config.h"
#undef min
#undef max
#define min(a, b) ((a) <= (b) ? (a) : (b))
#define max(a, b) ((a) >= (b) ? (a) : (b))
#define range_limit(x, lower, upper) (min(max(x, lower), upper))
#define linear_to_dB(x) (log10(x) * 20)
#define array_length(a) (sizeof(a)/sizeof(a[0]))
#define sqr(a) ((a) * (a))
#if defined NDEBUG
#ifdef __GNUC__
void lsx_dummy(char const *, ...);
#else
static __inline void lsx_dummy(char const * x, ...) {}
#endif
#define lsx_debug if(0) lsx_dummy
#else
#include <stdarg.h>
#include <stdio.h>
#ifdef __GNUC__
__attribute__ ((unused))
#endif
static void lsx_debug(char const * fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
fputc('\n', stderr);
va_end(args);
}
#endif
#endif
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if !defined soxr_internal_included
#define soxr_internal_included
#include "soxr-config.h"
#undef min
#undef max
#define min(a, b) ((a) <= (b) ? (a) : (b))
#define max(a, b) ((a) >= (b) ? (a) : (b))
#define range_limit(x, lower, upper) (min(max(x, lower), upper))
#define linear_to_dB(x) (log10(x) * 20)
#define array_length(a) (sizeof(a)/sizeof(a[0]))
#define AL(a) array_length(a)
#define iAL(a) (int)AL(a)
#define sqr(a) ((a) * (a))
#ifdef __GNUC__
#define UNUSED __attribute__ ((unused))
#else
#define UNUSED
#endif
#if defined NDEBUG
#ifdef __GNUC__
void lsx_dummy(char const *, ...);
#else
static __inline void lsx_dummy(char const * x, ...) {}
#endif
#define lsx_debug if(0) lsx_dummy
#else
#include <stdarg.h>
#include <stdio.h>
UNUSED static void lsx_debug(char const * fmt, ...)
{
va_list args;
va_start(args, fmt);
vfprintf(stderr, fmt, args);
fputc('\n', stderr);
va_end(args);
}
#endif
#endif

View File

@@ -1,2 +1,2 @@
set(TARGET_HEADERS "@TARGET_HEADERS@")
set(TARGET_PCS "@TARGET_PCS@")
set(TARGET_HEADERS "@TARGET_HEADERS@")
set(TARGET_PCS "@TARGET_PCS@")

View File

@@ -1,11 +1,11 @@
prefix=${CMAKE_INSTALL_PREFIX}
exec_prefix=${CMAKE_INSTALL_PREFIX}
libdir=${LIB_INSTALL_DIR}
includedir=${INCLUDE_INSTALL_DIR}
Name: lib${LSR}
Description: ${DESCRIPTION_SUMMARY} (with libsamplerate-like bindings)
Requires: libsoxr
Version: ${PROJECT_VERSION}
Libs: -L${LIB_INSTALL_DIR} -l${LSR}
Cflags: -I${INCLUDE_INSTALL_DIR}
prefix=${CMAKE_INSTALL_PREFIX}
exec_prefix=${CMAKE_INSTALL_PREFIX}
libdir=${LIB_INSTALL_DIR}
includedir=${INCLUDE_INSTALL_DIR}
Name: lib${LSR}
Description: ${DESCRIPTION_SUMMARY} (with libsamplerate-like bindings)
Requires: libsoxr
Version: ${PROJECT_VERSION}
Libs: -L${LIB_INSTALL_DIR} -l${LSR}
Cflags: -I${INCLUDE_INSTALL_DIR}

View File

@@ -1,11 +1,11 @@
prefix=${CMAKE_INSTALL_PREFIX}
exec_prefix=${CMAKE_INSTALL_PREFIX}
libdir=${LIB_INSTALL_DIR}
includedir=${INCLUDE_INSTALL_DIR}
Name: lib${PROJECT_NAME}
Description: ${DESCRIPTION_SUMMARY}
Requires:
Version: ${PROJECT_VERSION}
Libs: -L${LIB_INSTALL_DIR} -l${PROJECT_NAME}
Cflags: -I${INCLUDE_INSTALL_DIR}
prefix=${CMAKE_INSTALL_PREFIX}
exec_prefix=${CMAKE_INSTALL_PREFIX}
libdir=${LIB_INSTALL_DIR}
includedir=${INCLUDE_INSTALL_DIR}
Name: lib${PROJECT_NAME}
Description: ${DESCRIPTION_SUMMARY}
Requires:
Version: ${PROJECT_VERSION}
Libs: -L${LIB_INSTALL_DIR} -l${PROJECT_NAME}
Cflags: -I${INCLUDE_INSTALL_DIR}

View File

@@ -1 +1 @@
set(TARGET_LIBS "@TARGET_LIBS@")
set(TARGET_LIBS "@TARGET_LIBS@")

View File

@@ -1,114 +1,114 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Wrapper mostly compatible with `libsamplerate'. */
#include <assert.h>
#include <stdlib.h>
#include "soxr.h"
/* Runtime casts: */
typedef struct io_t {
float *in,*out; long ilen,olen,idone,odone; int eoi; double oi_ratio;} io_t;
#define SRC_DATA io_t
typedef struct soxr SRC_STATE;
#define src_callback_t soxr_input_fn_t
#define SRC_ERROR soxr_error_t
#define SRC_SRCTYPE unsigned
#include "soxr-lsr.h"
#include "rint.h"
soxr_error_t src_simple(io_t * p, unsigned id, int channels)
{
size_t idone, odone;
soxr_error_t error;
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_LSR0Q + id, 0);
char const * e = getenv("SOXR_LSR_NUM_THREADS");
soxr_runtime_spec_t r_spec = soxr_runtime_spec(!(e && atoi(e) != 1));
assert (channels > 0);
assert (p->ilen >= 0);
assert (p->olen >= 0);
error = soxr_oneshot(1, p->oi_ratio, (unsigned)channels,
p->in, (size_t)p->ilen, &idone, p->out, (size_t)p->olen, &odone,
0, &q_spec, &r_spec);
p->idone = (long)idone, p->odone = (long)odone;
return error;
}
soxr_t src_callback_new(soxr_input_fn_t fn, unsigned id, int channels, SRC_ERROR * error0, void * p)
{
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_LSR0Q + id, 0);
char const * e = getenv("SOXR_LSR_NUM_THREADS");
soxr_runtime_spec_t r_spec = soxr_runtime_spec(!(e && atoi(e) != 1));
soxr_error_t error;
soxr_t soxr = 0;
assert (channels > 0);
/* To minimise latency e.g. for real-time playback:
if (id == 2)
r_spec.log2_large_dft_size = r_spec.log2_min_dft_size = 8;
*/
soxr = soxr_create(0, 0, (unsigned)channels, &error, 0, &q_spec, &r_spec);
if (soxr)
error = soxr_set_input_fn(soxr, fn, p);
*(int *)error0 = (int)(long)error;
return soxr;
}
soxr_error_t src_process(soxr_t p, io_t * io)
{
if (!p || !io) return "null pointer";
soxr_set_error(p, soxr_set_oi_ratio(p, io->oi_ratio));
{ size_t idone , odone;
soxr_process(p, io->in, (size_t)(io->eoi? ~io->ilen : io->ilen), /* hack */
&idone, io->out, (size_t)io->olen, &odone);
io->idone = (long)idone, io->odone = (long)odone;
return soxr_error(p); }
}
long src_callback_read(soxr_t p, double oi_ratio, long olen, float * obuf)
{
if (!p || olen < 0) return -1;
soxr_set_error(p, soxr_set_oi_ratio(p, oi_ratio));
return (long)soxr_output(p, obuf, (size_t)olen);
}
void src_float_to_short_array(float const * src, short * dest, int len)
{
double d, N = 1. + SHRT_MAX;
assert (src && dest);
while (len--) d = src[len] * N, dest[len] = (short)(d > N - 1? (short)(N - 1) : d < -N? (short)-N : rint16(d));
}
void src_short_to_float_array(short const * src, float * dest, int len)
{
assert (src && dest);
while (len--) dest[len] = (float)(src[len] * (1 / (1. + SHRT_MAX)));
}
void src_float_to_int_array(float const * src, int * dest, int len)
{
double d, N = 32768. * 65536.; /* N.B. int32, not int! (Also next fn.) */
assert (src && dest);
while (len--) d = src[len] * N, dest[len] = d >= N - 1? (int)(N - 1) : d < -N? (int)(-N) : rint32(d);
}
void src_int_to_float_array(int const * src, float * dest, int len)
{
assert (src && dest);
while (len--) dest[len] = (float)(src[len] * (1 / (32768. * 65536.)));
}
static char const * const names[] = {"LSR best sinc", "LSR medium sinc", "LSR fastest sinc", "LSR ZOH", "LSR linear", "SoX VHQ"};
char const * src_get_name(unsigned n) {return n < 5u + !getenv("SOXR_LSR_STRICT")? names[n] : 0;}
char const * src_get_description(unsigned id) {return src_get_name(id);}
char const * src_get_version(void) {return soxr_version();}
char const * src_strerror(soxr_error_t error) {return error == (soxr_error_t)1? "Placeholder." : soxr_strerror(error);}
int src_is_valid_ratio(double oi_ratio) {return getenv("SOXR_LSR_STRICT")? oi_ratio >= 1./256 && oi_ratio <= 256 : oi_ratio > 0;}
soxr_error_t src_error(soxr_t p) {return soxr_error(p);}
soxr_error_t src_reset(soxr_t p) {return soxr_clear(p);}
soxr_t src_delete(soxr_t p) {soxr_delete(p); return 0;}
soxr_error_t src_set_ratio(soxr_t p, double oi_ratio) {return soxr_set_oi_ratio(p, oi_ratio);}
soxr_t src_new(unsigned id, int channels, SRC_ERROR * error) {return src_callback_new(0, id, channels, error, 0);}
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Wrapper mostly compatible with `libsamplerate'. */
#include <assert.h>
#include <stdlib.h>
#include "soxr.h"
/* Runtime casts: */
typedef struct io_t {
float *in,*out; long ilen,olen,idone,odone; int eoi; double oi_ratio;} io_t;
#define SRC_DATA io_t
typedef struct soxr SRC_STATE;
#define src_callback_t soxr_input_fn_t
#define SRC_ERROR soxr_error_t
#define SRC_SRCTYPE unsigned
#include "soxr-lsr.h"
#include "rint.h"
soxr_error_t src_simple(io_t * p, unsigned id, int channels)
{
size_t idone, odone;
soxr_error_t error;
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_LSR0Q + id, 0);
char const * e = getenv("SOXR_LSR_NUM_THREADS");
soxr_runtime_spec_t r_spec = soxr_runtime_spec(!(e && atoi(e) != 1));
assert (channels > 0);
assert (p->ilen >= 0);
assert (p->olen >= 0);
error = soxr_oneshot(1, p->oi_ratio, (unsigned)channels,
p->in, (size_t)p->ilen, &idone, p->out, (size_t)p->olen, &odone,
0, &q_spec, &r_spec);
p->idone = (long)idone, p->odone = (long)odone;
return error;
}
soxr_t src_callback_new(soxr_input_fn_t fn, unsigned id, int channels, SRC_ERROR * error0, void * p)
{
soxr_quality_spec_t q_spec = soxr_quality_spec(SOXR_LSR0Q + id, 0);
char const * e = getenv("SOXR_LSR_NUM_THREADS");
soxr_runtime_spec_t r_spec = soxr_runtime_spec(!(e && atoi(e) != 1));
soxr_error_t error;
soxr_t soxr = 0;
assert (channels > 0);
/* To minimise latency e.g. for real-time playback:
if (id == 2)
r_spec.log2_large_dft_size = r_spec.log2_min_dft_size = 8;
*/
soxr = soxr_create(0, 0, (unsigned)channels, &error, 0, &q_spec, &r_spec);
if (soxr)
error = soxr_set_input_fn(soxr, fn, p, 0);
*(int *)error0 = (int)(long)error;
return soxr;
}
soxr_error_t src_process(soxr_t p, io_t * io)
{
if (!p || !io) return "null pointer";
soxr_set_error(p, soxr_set_io_ratio(p, 1/io->oi_ratio, (size_t)io->olen));
{ size_t idone , odone;
soxr_process(p, io->in, (size_t)(io->eoi? ~io->ilen : io->ilen), /* hack */
&idone, io->out, (size_t)io->olen, &odone);
io->idone = (long)idone, io->odone = (long)odone;
return soxr_error(p); }
}
long src_callback_read(soxr_t p, double oi_ratio, long olen, float * obuf)
{
if (!p || olen < 0) return -1;
soxr_set_error(p, soxr_set_io_ratio(p, 1/oi_ratio, (size_t)olen));
return (long)soxr_output(p, obuf, (size_t)olen);
}
void src_float_to_short_array(float const * src, short * dest, int len)
{
double d, N = 1. + SHRT_MAX;
assert (src && dest);
while (len--) d = src[len] * N, dest[len] = (short)(d > N - 1? (short)(N - 1) : d < -N? (short)-N : rint16(d));
}
void src_short_to_float_array(short const * src, float * dest, int len)
{
assert (src && dest);
while (len--) dest[len] = (float)(src[len] * (1 / (1. + SHRT_MAX)));
}
void src_float_to_int_array(float const * src, int * dest, int len)
{
double d, N = 32768. * 65536.; /* N.B. int32, not int! (Also next fn.) */
assert (src && dest);
while (len--) d = src[len] * N, dest[len] = d >= N - 1? (int)(N - 1) : d < -N? (int)(-N) : rint32(d);
}
void src_int_to_float_array(int const * src, float * dest, int len)
{
assert (src && dest);
while (len--) dest[len] = (float)(src[len] * (1 / (32768. * 65536.)));
}
static char const * const names[] = {"LSR best sinc", "LSR medium sinc", "LSR fastest sinc", "LSR ZOH", "LSR linear", "SoX VHQ"};
char const * src_get_name(unsigned n) {return n < 5u + !getenv("SOXR_LSR_STRICT")? names[n] : 0;}
char const * src_get_description(unsigned id) {return src_get_name(id);}
char const * src_get_version(void) {return soxr_version();}
char const * src_strerror(soxr_error_t error) {return error == (soxr_error_t)1? "Placeholder." : soxr_strerror(error);}
int src_is_valid_ratio(double oi_ratio) {return getenv("SOXR_LSR_STRICT")? oi_ratio >= 1./256 && oi_ratio <= 256 : oi_ratio > 0;}
soxr_error_t src_error(soxr_t p) {return soxr_error(p);}
soxr_error_t src_reset(soxr_t p) {return soxr_clear(p);}
soxr_t src_delete(soxr_t p) {soxr_delete(p); return 0;}
soxr_error_t src_set_ratio(soxr_t p, double oi_ratio) {return soxr_set_io_ratio(p, 1/oi_ratio, 0);}
soxr_t src_new(unsigned id, int channels, SRC_ERROR * error) {return src_callback_new(0, id, channels, error, 0);}

File diff suppressed because it is too large Load Diff

View File

@@ -1,177 +1,177 @@
/* Copyright (c) 2011 Julien Pommier ( pommier@modartt.com )
Based on original fortran 77 code from FFTPACKv4 from NETLIB,
authored by Dr Paul Swarztrauber of NCAR, in 1985.
As confirmed by the NCAR fftpack software curators, the following
FFTPACKv5 license applies to FFTPACKv4 sources. My changes are
released under the same terms.
FFTPACK license:
http://www.cisl.ucar.edu/css/software/fftpack5/ftpk.html
Copyright (c) 2004 the University Corporation for Atmospheric
Research ("UCAR"). All rights reserved. Developed by NCAR's
Computational and Information Systems Laboratory, UCAR,
www.cisl.ucar.edu.
Redistribution and use of the Software in source and binary forms,
with or without modification, is permitted provided that the
following conditions are met:
- Neither the names of NCAR's Computational and Information Systems
Laboratory, the University Corporation for Atmospheric Research,
nor the names of its sponsors or contributors may be used to
endorse or promote products derived from this Software without
specific prior written permission.
- Redistributions of source code must retain the above copyright
notices, this list of conditions, and the disclaimer below.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the disclaimer below in the
documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
*/
/*
PFFFT : a Pretty Fast FFT.
This is basically an adaptation of the single precision fftpack
(v4) as found on netlib taking advantage of SIMD instruction found
on cpus such as intel x86 (SSE1), powerpc (Altivec), and arm (NEON).
For architectures where no SIMD instruction is available, the code
falls back to a scalar version.
Restrictions:
- 1D transforms only, with 32-bit single precision.
- supports only transforms for inputs of length N of the form
N=(2^a)*(3^b), a >= 5 and b >=0 (32, 48, 64, 96, 128, 144 etc
are all acceptable lengths). Performance is best for 128<=N<=8192.
- all (float*) pointers in the functions below are expected to
have an "simd-compatible" alignment, that is 16 bytes on x86 and
powerpc CPUs.
You can allocate such buffers with the functions
pffft_aligned_malloc / pffft_aligned_free (or with stuff like
posix_memalign..)
*/
#ifndef PFFFT_H
#define PFFFT_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* opaque struct holding internal stuff (precomputed twiddle factors)
this struct can be shared by many threads as it contains only
read-only data.
*/
typedef struct PFFFT_Setup PFFFT_Setup;
/* direction of the transform */
typedef enum { PFFFT_FORWARD, PFFFT_BACKWARD } pffft_direction_t;
/* type of transform */
typedef enum { PFFFT_REAL, PFFFT_COMPLEX } pffft_transform_t;
/*
prepare for performing transforms of size N -- the returned
PFFFT_Setup structure is read-only so it can safely be shared by
multiple concurrent threads.
*/
static PFFFT_Setup *pffft_new_setup(int N, pffft_transform_t transform);
static void pffft_destroy_setup(PFFFT_Setup *);
/*
Perform a Fourier transform , The z-domain data is stored in the
most efficient order for transforming it back, or using it for
convolution. If you need to have its content sorted in the
"usual" way, that is as an array of interleaved complex numbers,
either use pffft_transform_ordered , or call pffft_zreorder after
the forward fft, and before the backward fft.
Transforms are not scaled: PFFFT_BACKWARD(PFFFT_FORWARD(x)) = N*x.
Typically you will want to scale the backward transform by 1/N.
The 'work' pointer should point to an area of N (2*N for complex
fft) floats, properly aligned. [del]If 'work' is NULL, then stack will
be used instead (this is probably the beest strategy for small
FFTs, say for N < 16384).[/del]
input and output may alias.
*/
static void pffft_transform(PFFFT_Setup *setup, const float *input, float *output, float *work, pffft_direction_t direction);
/*
Similar to pffft_transform, but makes sure that the output is
ordered as expected (interleaved complex numbers). This is
similar to calling pffft_transform and then pffft_zreorder.
input and output may alias.
*/
static void pffft_transform_ordered(PFFFT_Setup *setup, const float *input, float *output, float *work, pffft_direction_t direction);
/*
call pffft_zreorder(.., PFFFT_FORWARD) after pffft_transform(...,
PFFFT_FORWARD) if you want to have the frequency components in
the correct "canonical" order, as interleaved complex numbers.
(for real transforms, both 0-frequency and half frequency
components, which are real, are assembled in the first entry as
F(0)+i*F(n/2+1). Note that the original fftpack did place
F(n/2+1) at the end of the arrays).
input and output should not alias.
*/
static void pffft_zreorder(PFFFT_Setup *setup, const float *input, float *output, pffft_direction_t direction);
/*
Perform a multiplication of the frequency components of dft_a and
dft_b and accumulate them into dft_ab. The arrays should have
been obtained with pffft_transform(.., PFFFT_FORWARD) and should
*not* have been reordered with pffft_zreorder (otherwise just
perform the operation yourself as the dft coefs are stored as
interleaved complex numbers).
the operation performed is: dft_ab += (dft_a * fdt_b)*scaling
The dft_a, dft_b and dft_ab pointers may alias.
void pffft_zconvolve_accumulate(PFFFT_Setup *setup, const float *dft_a, const float *dft_b, float *dft_ab, float scaling);
*/
/*
the operation performed is: dft_ab = (dft_a * fdt_b)
The dft_a, dft_b and dft_ab pointers may alias.
*/
static void pffft_zconvolve(PFFFT_Setup *setup, const float *dft_a, const float *dft_b, float *dft_ab);
/* return 4 or 1 wether support SSE/Altivec instructions was enable when building pffft.c */
int pffft_simd_size(void);
static void pffft_reorder_back(int length, void * setup, float * data, float * work);
#ifdef __cplusplus
}
#endif
#endif
/* Copyright (c) 2011 Julien Pommier ( pommier@modartt.com )
Based on original fortran 77 code from FFTPACKv4 from NETLIB,
authored by Dr Paul Swarztrauber of NCAR, in 1985.
As confirmed by the NCAR fftpack software curators, the following
FFTPACKv5 license applies to FFTPACKv4 sources. My changes are
released under the same terms.
FFTPACK license:
http://www.cisl.ucar.edu/css/software/fftpack5/ftpk.html
Copyright (c) 2004 the University Corporation for Atmospheric
Research ("UCAR"). All rights reserved. Developed by NCAR's
Computational and Information Systems Laboratory, UCAR,
www.cisl.ucar.edu.
Redistribution and use of the Software in source and binary forms,
with or without modification, is permitted provided that the
following conditions are met:
- Neither the names of NCAR's Computational and Information Systems
Laboratory, the University Corporation for Atmospheric Research,
nor the names of its sponsors or contributors may be used to
endorse or promote products derived from this Software without
specific prior written permission.
- Redistributions of source code must retain the above copyright
notices, this list of conditions, and the disclaimer below.
- Redistributions in binary form must reproduce the above copyright
notice, this list of conditions, and the disclaimer below in the
documentation and/or other materials provided with the
distribution.
THIS SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING, BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE CONTRIBUTORS OR COPYRIGHT
HOLDERS BE LIABLE FOR ANY CLAIM, INDIRECT, INCIDENTAL, SPECIAL,
EXEMPLARY, OR CONSEQUENTIAL DAMAGES OR OTHER LIABILITY, WHETHER IN AN
ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS WITH THE
SOFTWARE.
*/
/*
PFFFT : a Pretty Fast FFT.
This is basically an adaptation of the single precision fftpack
(v4) as found on netlib taking advantage of SIMD instruction found
on cpus such as intel x86 (SSE1), powerpc (Altivec), and arm (NEON).
For architectures where no SIMD instruction is available, the code
falls back to a scalar version.
Restrictions:
- 1D transforms only, with 32-bit single precision.
- supports only transforms for inputs of length N of the form
N=(2^a)*(3^b), a >= 5 and b >=0 (32, 48, 64, 96, 128, 144 etc
are all acceptable lengths). Performance is best for 128<=N<=8192.
- all (float*) pointers in the functions below are expected to
have an "simd-compatible" alignment, that is 16 bytes on x86 and
powerpc CPUs.
You can allocate such buffers with the functions
pffft_aligned_malloc / pffft_aligned_free (or with stuff like
posix_memalign..)
*/
#ifndef PFFFT_H
#define PFFFT_H
#include <stddef.h>
#ifdef __cplusplus
extern "C" {
#endif
/* opaque struct holding internal stuff (precomputed twiddle factors)
this struct can be shared by many threads as it contains only
read-only data.
*/
typedef struct PFFFT_Setup PFFFT_Setup;
/* direction of the transform */
typedef enum { PFFFT_FORWARD, PFFFT_BACKWARD } pffft_direction_t;
/* type of transform */
typedef enum { PFFFT_REAL, PFFFT_COMPLEX } pffft_transform_t;
/*
prepare for performing transforms of size N -- the returned
PFFFT_Setup structure is read-only so it can safely be shared by
multiple concurrent threads.
*/
static PFFFT_Setup *pffft_new_setup(int N, pffft_transform_t transform);
static void pffft_destroy_setup(PFFFT_Setup *);
/*
Perform a Fourier transform , The z-domain data is stored in the
most efficient order for transforming it back, or using it for
convolution. If you need to have its content sorted in the
"usual" way, that is as an array of interleaved complex numbers,
either use pffft_transform_ordered , or call pffft_zreorder after
the forward fft, and before the backward fft.
Transforms are not scaled: PFFFT_BACKWARD(PFFFT_FORWARD(x)) = N*x.
Typically you will want to scale the backward transform by 1/N.
The 'work' pointer should point to an area of N (2*N for complex
fft) floats, properly aligned. [del]If 'work' is NULL, then stack will
be used instead (this is probably the beest strategy for small
FFTs, say for N < 16384).[/del]
input and output may alias.
*/
static void pffft_transform(PFFFT_Setup *setup, const float *input, float *output, float *work, pffft_direction_t direction);
/*
Similar to pffft_transform, but makes sure that the output is
ordered as expected (interleaved complex numbers). This is
similar to calling pffft_transform and then pffft_zreorder.
input and output may alias.
*/
static void pffft_transform_ordered(PFFFT_Setup *setup, const float *input, float *output, float *work, pffft_direction_t direction);
/*
call pffft_zreorder(.., PFFFT_FORWARD) after pffft_transform(...,
PFFFT_FORWARD) if you want to have the frequency components in
the correct "canonical" order, as interleaved complex numbers.
(for real transforms, both 0-frequency and half frequency
components, which are real, are assembled in the first entry as
F(0)+i*F(n/2+1). Note that the original fftpack did place
F(n/2+1) at the end of the arrays).
input and output should not alias.
*/
static void pffft_zreorder(PFFFT_Setup *setup, const float *input, float *output, pffft_direction_t direction);
/*
Perform a multiplication of the frequency components of dft_a and
dft_b and accumulate them into dft_ab. The arrays should have
been obtained with pffft_transform(.., PFFFT_FORWARD) and should
*not* have been reordered with pffft_zreorder (otherwise just
perform the operation yourself as the dft coefs are stored as
interleaved complex numbers).
the operation performed is: dft_ab += (dft_a * fdt_b)*scaling
The dft_a, dft_b and dft_ab pointers may alias.
void pffft_zconvolve_accumulate(PFFFT_Setup *setup, const float *dft_a, const float *dft_b, float *dft_ab, float scaling);
*/
/*
the operation performed is: dft_ab = (dft_a * fdt_b)
The dft_a, dft_b and dft_ab pointers may alias.
*/
static void pffft_zconvolve(PFFFT_Setup *setup, const float *dft_a, const float *dft_b, float *dft_ab);
/* return 4 or 1 wether support SSE/Altivec instructions was enable when building pffft.c */
int pffft_simd_size(void);
static void pffft_reorder_back(int length, void * setup, float * data, float * work);
#ifdef __cplusplus
}
#endif
#endif

View File

@@ -1,30 +1,30 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#define PFFFT_SIMD_DISABLE
#include "pffft.c"
#include "filter.h"
static void * setup(int len) {return pffft_new_setup(len, PFFFT_REAL);}
static void delete_setup(void * setup) {pffft_destroy_setup(setup);}
static void forward (int length, void * setup, float * h, float * scratch) {pffft_transform (setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
static void oforward (int length, void * setup, float * h, float * scratch) {pffft_transform_ordered(setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
static void backward (int length, void * setup, float * H, float * scratch) {pffft_transform (setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
static void obackward(int length, void * setup, float * H, float * scratch) {pffft_transform_ordered(setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
static void convolve(int length, void * setup, float * H, float const * with) { pffft_zconvolve(setup, H, with, H); (void)length;}
static int multiplier(void) {return 1;}
typedef void (* fn_t)(void);
fn_t _soxr_rdft32_cb[] = {
(fn_t)setup,
(fn_t)setup,
(fn_t)delete_setup,
(fn_t)forward,
(fn_t)oforward,
(fn_t)backward,
(fn_t)obackward,
(fn_t)convolve,
(fn_t)_soxr_ordered_partial_convolve_f,
(fn_t)multiplier,
(fn_t)pffft_reorder_back,
};
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#define PFFFT_SIMD_DISABLE
#include "pffft.c"
#include "filter.h"
static void * setup(int len) {return pffft_new_setup(len, PFFFT_REAL);}
static void delete_setup(void * setup) {pffft_destroy_setup(setup);}
static void forward (int length, void * setup, float * h, float * scratch) {pffft_transform (setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
static void oforward (int length, void * setup, float * h, float * scratch) {pffft_transform_ordered(setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
static void backward (int length, void * setup, float * H, float * scratch) {pffft_transform (setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
static void obackward(int length, void * setup, float * H, float * scratch) {pffft_transform_ordered(setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
static void convolve(int length, void * setup, float * H, float const * with) { pffft_zconvolve(setup, H, with, H); (void)length;}
static int multiplier(void) {return 1;}
typedef void (* fn_t)(void);
fn_t _soxr_rdft32_cb[] = {
(fn_t)setup,
(fn_t)setup,
(fn_t)delete_setup,
(fn_t)forward,
(fn_t)oforward,
(fn_t)backward,
(fn_t)obackward,
(fn_t)convolve,
(fn_t)_soxr_ordered_partial_convolve_f,
(fn_t)multiplier,
(fn_t)pffft_reorder_back,
};

View File

@@ -1,27 +1,27 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include "pffft.c"
static void * setup(int len) {return pffft_new_setup(len, PFFFT_REAL);}
static void forward (int length, void * setup, float * h, float * scratch) {pffft_transform (setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
static void oforward (int length, void * setup, float * h, float * scratch) {pffft_transform_ordered(setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
static void backward (int length, void * setup, float * H, float * scratch) {pffft_transform (setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
static void obackward(int length, void * setup, float * H, float * scratch) {pffft_transform_ordered(setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
static void convolve(int length, void * setup, float * H, float const * with) { pffft_zconvolve(setup, H, with, H); (void)length;}
static int multiplier(void) {return 1;}
typedef void (* fn_t)(void);
fn_t _soxr_rdft32s_cb[] = {
(fn_t)setup,
(fn_t)setup,
(fn_t)pffft_destroy_setup,
(fn_t)forward,
(fn_t)oforward,
(fn_t)backward,
(fn_t)obackward,
(fn_t)convolve,
(fn_t)_soxr_ordered_partial_convolve_simd,
(fn_t)multiplier,
(fn_t)pffft_reorder_back,
};
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include "pffft.c"
static void * setup(int len) {return pffft_new_setup(len, PFFFT_REAL);}
static void forward (int length, void * setup, float * h, float * scratch) {pffft_transform (setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
static void oforward (int length, void * setup, float * h, float * scratch) {pffft_transform_ordered(setup, h, h, scratch, PFFFT_FORWARD); (void)length;}
static void backward (int length, void * setup, float * H, float * scratch) {pffft_transform (setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
static void obackward(int length, void * setup, float * H, float * scratch) {pffft_transform_ordered(setup, H, H, scratch, PFFFT_BACKWARD);(void)length;}
static void convolve(int length, void * setup, float * H, float const * with) { pffft_zconvolve(setup, H, with, H); (void)length;}
static int multiplier(void) {return 1;}
typedef void (* fn_t)(void);
fn_t _soxr_rdft32s_cb[] = {
(fn_t)setup,
(fn_t)setup,
(fn_t)pffft_destroy_setup,
(fn_t)forward,
(fn_t)oforward,
(fn_t)backward,
(fn_t)obackward,
(fn_t)convolve,
(fn_t)_soxr_ordered_partial_convolve_simd,
(fn_t)multiplier,
(fn_t)pffft_reorder_back,
};

View File

@@ -1,98 +1,98 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Resample using an interpolated poly-phase FIR with length LEN.*/
/* Input must be followed by LEN-1 samples. */
#define a (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 0,j))
#define b (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 1,j))
#define c (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 2,j))
#define d (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 3,j))
#if COEF_INTERP == 0
#define _ sum += a *in[j], ++j;
#elif COEF_INTERP == 1
#define _ sum += (b *x + a)*in[j], ++j;
#elif COEF_INTERP == 2
#define _ sum += ((c *x + b)*x + a)*in[j], ++j;
#elif COEF_INTERP == 3
#define _ sum += (((d*x + c)*x + b)*x + a)*in[j], ++j;
#else
#error COEF_INTERP
#endif
static void FUNCTION(stage_t * p, fifo_t * output_fifo)
{
sample_t const * input = stage_read_p(p);
int i, num_in = stage_occupancy(p), max_num_out = 1 + (int)(num_in*p->out_in_ratio);
sample_t * output = fifo_reserve(output_fifo, max_num_out);
#if defined HI_PREC_CLOCK
#if FLOAT_HI_PREC_CLOCK
if (p->use_hi_prec_clock) {
float_step_t at = p->at.flt;
for (i = 0; (int)at < num_in; ++i, at += p->step.flt) {
sample_t const * in = input + (int)at;
float_step_t frac = at - (int)at;
int phase = (int)(frac * (1 << PHASE_BITS));
#if COEF_INTERP > 0
sample_t x = (sample_t)(frac * (1 << PHASE_BITS) - phase);
#endif
sample_t sum = 0;
int j = 0;
CONVOLVE
output[i] = sum;
}
fifo_read(&p->fifo, (int)at, NULL);
p->at.flt = at - (int)at;
} else
#else
if (p->use_hi_prec_clock) {
for (i = 0; p->at.integer < num_in; ++i,
p->at.fix.ls.all += p->step.fix.ls.all,
p->at.whole += p->step.whole + (p->at.fix.ls.all < p->step.fix.ls.all)) {
sample_t const * in = input + p->at.integer;
uint32_t frac = p->at.fraction;
int phase = (int)(frac >> (32 - PHASE_BITS)); /* high-order bits */
#if COEF_INTERP > 0 /* low-order bits, scaled to [0,1) */
sample_t x = (sample_t)((frac << PHASE_BITS) * (1 / MULT32));
#endif
sample_t sum = 0;
int j = 0;
CONVOLVE
output[i] = sum;
}
fifo_read(&p->fifo, p->at.integer, NULL);
p->at.integer = 0;
} else
#endif
#endif
{
for (i = 0; p->at.integer < num_in; ++i, p->at.whole += p->step.whole) {
sample_t const * in = input + p->at.integer;
uint32_t frac = p->at.fraction;
int phase = (int)(frac >> (32 - PHASE_BITS)); /* high-order bits */
#if COEF_INTERP > 0 /* low-order bits, scaled to [0,1) */
sample_t x = (sample_t)((frac << PHASE_BITS) * (1 / MULT32));
#endif
sample_t sum = 0;
int j = 0;
CONVOLVE
output[i] = sum;
}
fifo_read(&p->fifo, p->at.integer, NULL);
p->at.integer = 0;
}
assert(max_num_out - i >= 0);
fifo_trim_by(output_fifo, max_num_out - i);
}
#undef _
#undef a
#undef b
#undef c
#undef d
#undef COEF_INTERP
#undef CONVOLVE
#undef FIR_LENGTH
#undef FUNCTION
#undef PHASE_BITS
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Resample using an interpolated poly-phase FIR with length LEN.*/
/* Input must be followed by LEN-1 samples. */
#define a (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 0,j))
#define b (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 1,j))
#define c (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 2,j))
#define d (coef(p->shared->poly_fir_coefs, COEF_INTERP, FIR_LENGTH, phase, 3,j))
#if COEF_INTERP == 0
#define _ sum += a *in[j], ++j;
#elif COEF_INTERP == 1
#define _ sum += (b *x + a)*in[j], ++j;
#elif COEF_INTERP == 2
#define _ sum += ((c *x + b)*x + a)*in[j], ++j;
#elif COEF_INTERP == 3
#define _ sum += (((d*x + c)*x + b)*x + a)*in[j], ++j;
#else
#error COEF_INTERP
#endif
static void FUNCTION(stage_t * p, fifo_t * output_fifo)
{
sample_t const * input = stage_read_p(p);
int i, num_in = stage_occupancy(p), max_num_out = 1 + (int)(num_in*p->out_in_ratio);
sample_t * output = fifo_reserve(output_fifo, max_num_out);
#if defined HI_PREC_CLOCK
#if FLOAT_HI_PREC_CLOCK
if (p->use_hi_prec_clock) {
float_step_t at = p->at.flt;
for (i = 0; (int)at < num_in; ++i, at += p->step.flt) {
sample_t const * in = input + (int)at;
float_step_t frac = at - (int)at;
int phase = (int)(frac * (1 << PHASE_BITS));
#if COEF_INTERP > 0
sample_t x = (sample_t)(frac * (1 << PHASE_BITS) - phase);
#endif
sample_t sum = 0;
int j = 0;
CONVOLVE
output[i] = sum;
}
fifo_read(&p->fifo, (int)at, NULL);
p->at.flt = at - (int)at;
} else
#else
if (p->use_hi_prec_clock) {
for (i = 0; p->at.integer < num_in; ++i,
p->at.fix.ls.all += p->step.fix.ls.all,
p->at.whole += p->step.whole + (p->at.fix.ls.all < p->step.fix.ls.all)) {
sample_t const * in = input + p->at.integer;
uint32_t frac = p->at.fraction;
int phase = (int)(frac >> (32 - PHASE_BITS)); /* high-order bits */
#if COEF_INTERP > 0 /* low-order bits, scaled to [0,1) */
sample_t x = (sample_t)((frac << PHASE_BITS) * (1 / MULT32));
#endif
sample_t sum = 0;
int j = 0;
CONVOLVE
output[i] = sum;
}
fifo_read(&p->fifo, p->at.integer, NULL);
p->at.integer = 0;
} else
#endif
#endif
{
for (i = 0; p->at.integer < num_in; ++i, p->at.whole += p->step.whole) {
sample_t const * in = input + p->at.integer;
uint32_t frac = p->at.fraction;
int phase = (int)(frac >> (32 - PHASE_BITS)); /* high-order bits */
#if COEF_INTERP > 0 /* low-order bits, scaled to [0,1) */
sample_t x = (sample_t)((frac << PHASE_BITS) * (1 / MULT32));
#endif
sample_t sum = 0;
int j = 0;
CONVOLVE
output[i] = sum;
}
fifo_read(&p->fifo, p->at.integer, NULL);
p->at.integer = 0;
}
assert(max_num_out - i >= 0);
fifo_trim_by(output_fifo, max_num_out - i);
}
#undef _
#undef a
#undef b
#undef c
#undef d
#undef COEF_INTERP
#undef CONVOLVE
#undef FIR_LENGTH
#undef FUNCTION
#undef PHASE_BITS

View File

@@ -1,34 +1,32 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Resample using a non-interpolated poly-phase FIR with length LEN.*/
/* Input must be followed by LEN-1 samples. */
#define _ sum += (coef(p->shared->poly_fir_coefs, 0, FIR_LENGTH, divided.rem, 0, j)) *at[j], ++j;
static void FUNCTION(stage_t * p, fifo_t * output_fifo)
{
sample_t const * input = stage_read_p(p);
int i, num_in = stage_occupancy(p), max_num_out = 1 + (int)(num_in*p->out_in_ratio);
sample_t * output = fifo_reserve(output_fifo, max_num_out);
div_t divided2;
for (i = 0; p->at.integer < num_in * p->L; ++i, p->at.integer += p->step.integer) {
div_t divided = div(p->at.integer, p->L);
sample_t const * at = input + divided.quot;
sample_t sum = 0;
int j = 0;
CONVOLVE
output[i] = sum;
}
assert(max_num_out - i >= 0);
fifo_trim_by(output_fifo, max_num_out - i);
divided2 = div(p->at.integer, p->L);
fifo_read(&p->fifo, divided2.quot, NULL);
p->at.integer = divided2.rem;
}
#undef _
#undef CONVOLVE
#undef FIR_LENGTH
#undef FUNCTION
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Resample using a non-interpolated poly-phase FIR with length LEN.*/
/* Input must be followed by LEN-1 samples. */
#define _ sum += (coef(p->shared->poly_fir_coefs, 0, FIR_LENGTH, rem, 0, j)) *at[j], ++j;
static void FUNCTION(stage_t * p, fifo_t * output_fifo)
{
sample_t const * input = stage_read_p(p);
int i, num_in = stage_occupancy(p), max_num_out = 1 + (int)(num_in*p->out_in_ratio);
sample_t * output = fifo_reserve(output_fifo, max_num_out);
for (i = 0; p->at.integer < num_in * p->L; ++i, p->at.integer += p->step.integer) {
int div = p->at.integer / p->L, rem = p->at.integer % p->L;
sample_t const * at = input + div;
sample_t sum = 0;
int j = 0;
CONVOLVE
output[i] = sum;
}
assert(max_num_out - i >= 0);
fifo_trim_by(output_fifo, max_num_out - i);
fifo_read(&p->fifo, p->at.integer / p->L, NULL);
p->at.integer = p->at.integer % p->L;
}
#undef _
#undef CONVOLVE
#undef FIR_LENGTH
#undef FUNCTION

File diff suppressed because it is too large Load Diff

View File

@@ -1,9 +1,9 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#define sample_t float
#define RATE_SIMD 0
#define RDFT_CB _soxr_rdft32_cb
#define RATE_CB _soxr_rate32_cb
#define RATE_ID "single-precision"
#include "rate.h"
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#define sample_t float
#define RATE_SIMD 0
#define RDFT_CB _soxr_rdft32_cb
#define RATE_CB _soxr_rate32_cb
#define RATE_ID "single-precision"
#include "rate.h"

View File

@@ -1,9 +1,9 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#define sample_t float
#define RATE_SIMD 1
#define RDFT_CB _soxr_rdft32s_cb
#define RATE_CB _soxr_rate32s_cb
#define RATE_ID "single-precision-SIMD"
#include "rate.h"
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#define sample_t float
#define RATE_SIMD 1
#define RDFT_CB _soxr_rdft32s_cb
#define RATE_CB _soxr_rate32s_cb
#define RATE_ID "single-precision-SIMD"
#include "rate.h"

View File

@@ -1,9 +1,9 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#define sample_t double
#define RATE_SIMD 0
#define RDFT_CB _soxr_rdft64_cb
#define RATE_CB _soxr_rate64_cb
#define RATE_ID "double-precision"
#include "rate.h"
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#define sample_t double
#define RATE_SIMD 0
#define RDFT_CB _soxr_rdft64_cb
#define RATE_CB _soxr_rate64_cb
#define RATE_ID "double-precision"
#include "rate.h"

View File

@@ -1,31 +1,31 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
void ORDERED_CONVOLVE(int n, void * not_used, DFT_FLOAT * a, const DFT_FLOAT * b)
{
int i;
a[0] *= b[0];
a[1] *= b[1];
for (i = 2; i < n; i += 2) {
DFT_FLOAT tmp = a[i];
a[i ] = b[i ] * tmp - b[i+1] * a[i+1];
a[i+1] = b[i+1] * tmp + b[i ] * a[i+1];
}
(void)not_used;
}
void ORDERED_PARTIAL_CONVOLVE(int n, DFT_FLOAT * a, const DFT_FLOAT * b)
{
int i;
a[0] *= b[0];
for (i = 2; i < n; i += 2) {
DFT_FLOAT tmp = a[i];
a[i ] = b[i ] * tmp - b[i+1] * a[i+1];
a[i+1] = b[i+1] * tmp + b[i ] * a[i+1];
}
a[1] = b[i] * a[i] - b[i+1] * a[i+1];
}
#undef ORDERED_CONVOLVE
#undef ORDERED_PARTIAL_CONVOLVE
#undef DFT_FLOAT
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
void ORDERED_CONVOLVE(int n, void * not_used, DFT_FLOAT * a, const DFT_FLOAT * b)
{
int i;
a[0] *= b[0];
a[1] *= b[1];
for (i = 2; i < n; i += 2) {
DFT_FLOAT tmp = a[i];
a[i ] = b[i ] * tmp - b[i+1] * a[i+1];
a[i+1] = b[i+1] * tmp + b[i ] * a[i+1];
}
(void)not_used;
}
void ORDERED_PARTIAL_CONVOLVE(int n, DFT_FLOAT * a, const DFT_FLOAT * b)
{
int i;
a[0] *= b[0];
for (i = 2; i < n; i += 2) {
DFT_FLOAT tmp = a[i];
a[i ] = b[i ] * tmp - b[i+1] * a[i+1];
a[i+1] = b[i+1] * tmp + b[i ] * a[i+1];
}
a[1] = b[i] * a[i] - b[i+1] * a[i+1];
}
#undef ORDERED_CONVOLVE
#undef ORDERED_PARTIAL_CONVOLVE
#undef DFT_FLOAT

View File

@@ -1,153 +1,153 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if defined DITHER
#define DITHERING (1./32)*(int)(((ran1>>=3)&31)-((ran2>>=3)&31))
#define DITHER_RAND (seed = 1664525UL * seed + 1013904223UL) >> 3
#define DITHER_VARS unsigned long ran1 = DITHER_RAND, ran2 = DITHER_RAND
#define SEED_ARG , unsigned long * seed0
#define SAVE_SEED *seed0 = seed
#define COPY_SEED unsigned long seed = *seed0;
#define COPY_SEED1 unsigned long seed1 = seed
#define PASS_SEED1 , &seed1
#define PASS_SEED0 , seed0
#else
#define DITHERING 0
#define DITHER_VARS
#define SEED_ARG
#define SAVE_SEED
#define COPY_SEED
#define COPY_SEED1
#define PASS_SEED1
#define PASS_SEED0
#endif
#if defined FE_INVALID && defined FPU_RINT
static void RINT_CLIP(RINT_T * const dest, FLOATX const * const src,
unsigned stride, size_t i, size_t const n, size_t * const clips SEED_ARG)
{
COPY_SEED
DITHER_VARS;
for (; i < n; ++i) {
double d = src[i] + DITHERING;
dest[stride * i] = RINT(d);
if (fetestexcept(FE_INVALID)) {
feclearexcept(FE_INVALID);
dest[stride * i] = d > 0? RINT_MAX : -RINT_MAX - 1;
++*clips;
}
}
SAVE_SEED;
}
#endif
static size_t LSX_RINT_CLIP(void * * const dest0, FLOATX const * const src,
size_t const n SEED_ARG)
{
size_t i, clips = 0;
RINT_T * dest = *dest0;
COPY_SEED
#if defined FE_INVALID && defined FPU_RINT
#define _ dest[i] = RINT(src[i] + DITHERING), ++i,
feclearexcept(FE_INVALID);
for (i = 0; i < (n & ~7u);) {
COPY_SEED1;
DITHER_VARS;
_ _ _ _ _ _ _ _ 0;
if (fetestexcept(FE_INVALID)) {
feclearexcept(FE_INVALID);
RINT_CLIP(dest, src, 1, i - 8, i, &clips PASS_SEED1);
}
}
RINT_CLIP(dest, src, 1, i, n, &clips PASS_SEED0);
#else
#define _ d = src[i] + DITHERING, dest[i++] = (RINT_T)(d > N - 1? ++clips, (RINT_T)(N - 1) : d < -N? ++clips, (RINT_T)(-N) : RINT(d)),
const double N = 1. + RINT_MAX;
double d;
for (i = 0; i < (n & ~7u);) {
DITHER_VARS;
_ _ _ _ _ _ _ _ 0;
}
{
DITHER_VARS;
for (; i < n; _ 0);
}
#endif
SAVE_SEED;
*dest0 = dest + n;
return clips;
}
#undef _
static size_t LSX_RINT_CLIP_2(void * * dest0, FLOATX const * const * srcs,
unsigned const stride, size_t const n SEED_ARG)
{
unsigned j;
size_t i, clips = 0;
RINT_T * dest = *dest0;
COPY_SEED
#if defined FE_INVALID && defined FPU_RINT
#define _ dest[stride * i] = RINT(src[i] + DITHERING), ++i,
feclearexcept(FE_INVALID);
for (j = 0; j < stride; ++j, ++dest) {
FLOATX const * const src = srcs[j];
for (i = 0; i < (n & ~7u);) {
COPY_SEED1;
DITHER_VARS;
_ _ _ _ _ _ _ _ 0;
if (fetestexcept(FE_INVALID)) {
feclearexcept(FE_INVALID);
RINT_CLIP(dest, src, stride, i - 8, i, &clips PASS_SEED1);
}
}
RINT_CLIP(dest, src, stride, i, n, &clips PASS_SEED0);
}
#else
#define _ d = src[i] + DITHERING, dest[stride * i++] = (RINT_T)(d > N - 1? ++clips, (RINT_T)(N - 1) : d < -N? ++clips, (RINT_T)(-N) : RINT(d)),
const double N = 1. + RINT_MAX;
double d;
for (j = 0; j < stride; ++j, ++dest) {
FLOATX const * const src = srcs[j];
for (i = 0; i < (n & ~7u);) {
DITHER_VARS;
_ _ _ _ _ _ _ _ 0;
}
{
DITHER_VARS;
for (; i < n; _ 0);
}
}
#endif
SAVE_SEED;
*dest0 = dest + stride * (n - 1);
return clips;
}
#undef _
#undef PASS_SEED0
#undef PASS_SEED1
#undef COPY_SEED1
#undef COPY_SEED
#undef SAVE_SEED
#undef SEED_ARG
#undef DITHER_VARS
#undef DITHERING
#undef DITHER
#undef RINT_MAX
#undef RINT_T
#undef FPU_RINT
#undef RINT
#undef RINT_CLIP
#undef LSX_RINT_CLIP
#undef LSX_RINT_CLIP_2
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if defined DITHER
#define DITHERING (1./32)*(int)(((ran1>>=3)&31)-((ran2>>=3)&31))
#define DITHER_RAND (seed = 1664525UL * seed + 1013904223UL) >> 3
#define DITHER_VARS unsigned long ran1 = DITHER_RAND, ran2 = DITHER_RAND
#define SEED_ARG , unsigned long * seed0
#define SAVE_SEED *seed0 = seed
#define COPY_SEED unsigned long seed = *seed0;
#define COPY_SEED1 unsigned long seed1 = seed
#define PASS_SEED1 , &seed1
#define PASS_SEED0 , seed0
#else
#define DITHERING 0
#define DITHER_VARS
#define SEED_ARG
#define SAVE_SEED
#define COPY_SEED
#define COPY_SEED1
#define PASS_SEED1
#define PASS_SEED0
#endif
#if defined FE_INVALID && defined FPU_RINT
static void RINT_CLIP(RINT_T * const dest, FLOATX const * const src,
unsigned stride, size_t i, size_t const n, size_t * const clips SEED_ARG)
{
COPY_SEED
DITHER_VARS;
for (; i < n; ++i) {
double d = src[i] + DITHERING;
dest[stride * i] = RINT(d);
if (fetestexcept(FE_INVALID)) {
feclearexcept(FE_INVALID);
dest[stride * i] = d > 0? RINT_MAX : -RINT_MAX - 1;
++*clips;
}
}
SAVE_SEED;
}
#endif
static size_t LSX_RINT_CLIP(void * * const dest0, FLOATX const * const src,
size_t const n SEED_ARG)
{
size_t i, clips = 0;
RINT_T * dest = *dest0;
COPY_SEED
#if defined FE_INVALID && defined FPU_RINT
#define _ dest[i] = RINT(src[i] + DITHERING), ++i,
feclearexcept(FE_INVALID);
for (i = 0; i < (n & ~7u);) {
COPY_SEED1;
DITHER_VARS;
_ _ _ _ _ _ _ _ 0;
if (fetestexcept(FE_INVALID)) {
feclearexcept(FE_INVALID);
RINT_CLIP(dest, src, 1, i - 8, i, &clips PASS_SEED1);
}
}
RINT_CLIP(dest, src, 1, i, n, &clips PASS_SEED0);
#else
#define _ d = src[i] + DITHERING, dest[i++] = (RINT_T)(d > N - 1? ++clips, (RINT_T)(N - 1) : d < -N? ++clips, (RINT_T)(-N) : RINT(d)),
const double N = 1. + RINT_MAX;
double d;
for (i = 0; i < (n & ~7u);) {
DITHER_VARS;
_ _ _ _ _ _ _ _ 0;
}
{
DITHER_VARS;
for (; i < n; _ 0);
}
#endif
SAVE_SEED;
*dest0 = dest + n;
return clips;
}
#undef _
static size_t LSX_RINT_CLIP_2(void * * dest0, FLOATX const * const * srcs,
unsigned const stride, size_t const n SEED_ARG)
{
unsigned j;
size_t i, clips = 0;
RINT_T * dest = *dest0;
COPY_SEED
#if defined FE_INVALID && defined FPU_RINT
#define _ dest[stride * i] = RINT(src[i] + DITHERING), ++i,
feclearexcept(FE_INVALID);
for (j = 0; j < stride; ++j, ++dest) {
FLOATX const * const src = srcs[j];
for (i = 0; i < (n & ~7u);) {
COPY_SEED1;
DITHER_VARS;
_ _ _ _ _ _ _ _ 0;
if (fetestexcept(FE_INVALID)) {
feclearexcept(FE_INVALID);
RINT_CLIP(dest, src, stride, i - 8, i, &clips PASS_SEED1);
}
}
RINT_CLIP(dest, src, stride, i, n, &clips PASS_SEED0);
}
#else
#define _ d = src[i] + DITHERING, dest[stride * i++] = (RINT_T)(d > N - 1? ++clips, (RINT_T)(N - 1) : d < -N? ++clips, (RINT_T)(-N) : RINT(d)),
const double N = 1. + RINT_MAX;
double d;
for (j = 0; j < stride; ++j, ++dest) {
FLOATX const * const src = srcs[j];
for (i = 0; i < (n & ~7u);) {
DITHER_VARS;
_ _ _ _ _ _ _ _ 0;
}
{
DITHER_VARS;
for (; i < n; _ 0);
}
}
#endif
SAVE_SEED;
*dest0 = dest + stride * (n - 1);
return clips;
}
#undef _
#undef PASS_SEED0
#undef PASS_SEED1
#undef COPY_SEED1
#undef COPY_SEED
#undef SAVE_SEED
#undef SEED_ARG
#undef DITHER_VARS
#undef DITHERING
#undef DITHER
#undef RINT_MAX
#undef RINT_T
#undef FPU_RINT
#undef RINT
#undef RINT_CLIP
#undef LSX_RINT_CLIP
#undef LSX_RINT_CLIP_2

View File

@@ -1,68 +1,68 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if !defined soxr_rint_included
#define soxr_rint_included
#include "soxr-config.h"
#if HAVE_LRINT && LONG_MAX == 2147483647L
#include <math.h>
#define FPU_RINT32
#define rint32 lrint
#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
#define FPU_RINT32
static __inline int32_t rint32(double input) {
int32_t result;
__asm__ __volatile__("fistpl %0": "=m"(result): "t"(input): "st");
return result;
}
#elif defined __GNUC__ && defined __arm__
#define FPU_RINT32
static __inline int32_t rint32(double input) {
register int32_t result;
__asm__ __volatile__ ("ftosid %0, %P1": "=w"(result): "w"(input));
return result;
}
#elif defined _MSC_VER && defined _M_IX86
#define FPU_RINT32
static __inline int32_t rint32(double input) {
int32_t result;
_asm {
fld input
fistp result
}
return result;
}
#else
#define rint32(x) (int32_t)((x) < 0? x - .5 : x + .5)
#endif
#if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
#define FPU_RINT16
static __inline int16_t rint16(double input) {
int16_t result;
__asm__ __volatile__("fistps %0": "=m"(result): "t"(input): "st");
return result;
}
#elif defined _MSC_VER && defined _M_IX86
#define FPU_RINT16
static __inline int16_t rint16(double input) {
int16_t result;
_asm {
fld input
fistp result
}
return result;
}
#else
#define rint16(x) (int16_t)floor((x)+.5) /* Is this faster than in rint32? */
#endif
#endif
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if !defined soxr_rint_included
#define soxr_rint_included
#include "soxr-config.h"
#if HAVE_LRINT && LONG_MAX == 2147483647L
#include <math.h>
#define FPU_RINT32
#define rint32 lrint
#elif defined __GNUC__ && (defined __i386__ || defined __x86_64__)
#define FPU_RINT32
static __inline int32_t rint32(double input) {
int32_t result;
__asm__ __volatile__("fistpl %0": "=m"(result): "t"(input): "st");
return result;
}
#elif defined __GNUC__ && defined __arm__
#define FPU_RINT32
static __inline int32_t rint32(double input) {
register int32_t result;
__asm__ __volatile__ ("ftosid %0, %P1": "=w"(result): "w"(input));
return result;
}
#elif defined _MSC_VER && defined _M_IX86
#define FPU_RINT32
static __inline int32_t rint32(double input) {
int32_t result;
_asm {
fld input
fistp result
}
return result;
}
#else
#define rint32(x) (int32_t)((x) < 0? x - .5 : x + .5)
#endif
#if defined __GNUC__ && (defined __i386__ || defined __x86_64__)
#define FPU_RINT16
static __inline int16_t rint16(double input) {
int16_t result;
__asm__ __volatile__("fistps %0": "=m"(result): "t"(input): "st");
return result;
}
#elif defined _MSC_VER && defined _M_IX86
#define FPU_RINT16
static __inline int16_t rint16(double input) {
int16_t result;
_asm {
fld input
fistp result
}
return result;
}
#else
#define rint16(x) (int16_t)floor((x)+.5) /* Is this faster than in rint32? */
#endif
#endif

View File

@@ -1 +1 @@
#include "soxr-lsr.h"
#include "soxr-lsr.h"

View File

@@ -1,5 +1,5 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#define PFFT_MACROS_ONLY
#include "pffft.c"
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#define PFFT_MACROS_ONLY
#include "pffft.c"

View File

@@ -1,84 +1,84 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "simd.h"
#include "simd-dev.h"
#define SIMD_ALIGNMENT (sizeof(float) * 4)
void * _soxr_simd_aligned_malloc(size_t size)
{
char * p1 = 0, * p = malloc(size + SIMD_ALIGNMENT);
if (p) {
p1 = (char *)((size_t)(p + SIMD_ALIGNMENT) & ~(SIMD_ALIGNMENT - 1));
*((void * *)p1 - 1) = p;
}
return p1;
}
void * _soxr_simd_aligned_calloc(size_t nmemb, size_t size)
{
void * p = _soxr_simd_aligned_malloc(nmemb * size);
if (p)
memset(p, 0, nmemb * size);
return p;
}
void _soxr_simd_aligned_free(void * p1)
{
if (p1)
free(*((void * *)p1 - 1));
}
void _soxr_ordered_convolve_simd(int n, void * not_used, float * a, const float * b)
{
int i;
float ab0, ab1;
v4sf * /*RESTRICT*/ va = (v4sf *)a;
v4sf const * RESTRICT vb = (v4sf const *)b;
assert(VALIGNED(a) && VALIGNED(b));
ab0 = a[0] * b[0], ab1 = a[1] * b[1];
for (i = 0; i < n / 4; i += 2) {
v4sf a1r = va[i+0], a1i = va[i+1];
v4sf b1r = vb[i+0], b1i = vb[i+1];
UNINTERLEAVE2(a1r, a1i, a1r, a1i);
UNINTERLEAVE2(b1r, b1i, b1r, b1i);
VCPLXMUL(a1r, a1i, b1r, b1i);
INTERLEAVE2(a1r, a1i, a1r, a1i);
va[i+0] = a1r, va[i+1] = a1i;
}
a[0] = ab0, a[1] = ab1;
(void)not_used;
}
void _soxr_ordered_partial_convolve_simd(int n, float * a, const float * b)
{
int i;
float ab0;
v4sf * /*RESTRICT*/ va = (v4sf *)a;
v4sf const * RESTRICT vb = (v4sf const *)b;
assert(VALIGNED(a) && VALIGNED(b));
ab0 = a[0] * b[0];
for (i = 0; i < n / 4; i += 2) {
v4sf a1r = va[i+0], a1i = va[i+1];
v4sf b1r = vb[i+0], b1i = vb[i+1];
UNINTERLEAVE2(a1r, a1i, a1r, a1i);
UNINTERLEAVE2(b1r, b1i, b1r, b1i);
VCPLXMUL(a1r, a1i, b1r, b1i);
INTERLEAVE2(a1r, a1i, a1r, a1i);
va[i+0] = a1r, va[i+1] = a1i;
}
a[0] = ab0;
a[1] = b[n] * a[n] - b[n+1] * a[n+1];
}
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#include <assert.h>
#include <string.h>
#include <stdlib.h>
#include "simd.h"
#include "simd-dev.h"
#define SIMD_ALIGNMENT (sizeof(float) * 4)
void * _soxr_simd_aligned_malloc(size_t size)
{
char * p1 = 0, * p = malloc(size + SIMD_ALIGNMENT);
if (p) {
p1 = (char *)((size_t)(p + SIMD_ALIGNMENT) & ~(SIMD_ALIGNMENT - 1));
*((void * *)p1 - 1) = p;
}
return p1;
}
void * _soxr_simd_aligned_calloc(size_t nmemb, size_t size)
{
void * p = _soxr_simd_aligned_malloc(nmemb * size);
if (p)
memset(p, 0, nmemb * size);
return p;
}
void _soxr_simd_aligned_free(void * p1)
{
if (p1)
free(*((void * *)p1 - 1));
}
void _soxr_ordered_convolve_simd(int n, void * not_used, float * a, const float * b)
{
int i;
float ab0, ab1;
v4sf * /*RESTRICT*/ va = (v4sf *)a;
v4sf const * RESTRICT vb = (v4sf const *)b;
assert(VALIGNED(a) && VALIGNED(b));
ab0 = a[0] * b[0], ab1 = a[1] * b[1];
for (i = 0; i < n / 4; i += 2) {
v4sf a1r = va[i+0], a1i = va[i+1];
v4sf b1r = vb[i+0], b1i = vb[i+1];
UNINTERLEAVE2(a1r, a1i, a1r, a1i);
UNINTERLEAVE2(b1r, b1i, b1r, b1i);
VCPLXMUL(a1r, a1i, b1r, b1i);
INTERLEAVE2(a1r, a1i, a1r, a1i);
va[i+0] = a1r, va[i+1] = a1i;
}
a[0] = ab0, a[1] = ab1;
(void)not_used;
}
void _soxr_ordered_partial_convolve_simd(int n, float * a, const float * b)
{
int i;
float ab0;
v4sf * /*RESTRICT*/ va = (v4sf *)a;
v4sf const * RESTRICT vb = (v4sf const *)b;
assert(VALIGNED(a) && VALIGNED(b));
ab0 = a[0] * b[0];
for (i = 0; i < n / 4; i += 2) {
v4sf a1r = va[i+0], a1i = va[i+1];
v4sf b1r = vb[i+0], b1i = vb[i+1];
UNINTERLEAVE2(a1r, a1i, a1r, a1i);
UNINTERLEAVE2(b1r, b1i, b1r, b1i);
VCPLXMUL(a1r, a1i, b1r, b1i);
INTERLEAVE2(a1r, a1i, a1r, a1i);
va[i+0] = a1r, va[i+1] = a1i;
}
a[0] = ab0;
a[1] = b[n] * a[n] - b[n+1] * a[n+1];
}

View File

@@ -1,16 +1,16 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if !defined simd_included
#define simd_included
#include <stddef.h>
void * _soxr_simd_aligned_malloc(size_t);
void * _soxr_simd_aligned_calloc(size_t, size_t);
void _soxr_simd_aligned_free(void *);
void _soxr_ordered_convolve_simd(int n, void * not_used, float * a, const float * b);
void _soxr_ordered_partial_convolve_simd(int n, float * a, const float * b);
#endif
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
#if !defined simd_included
#define simd_included
#include <stddef.h>
void * _soxr_simd_aligned_malloc(size_t);
void * _soxr_simd_aligned_calloc(size_t, size_t);
void _soxr_simd_aligned_free(void *);
void _soxr_ordered_convolve_simd(int n, void * not_used, float * a, const float * b);
void _soxr_ordered_partial_convolve_simd(int n, float * a, const float * b);
#endif

View File

@@ -1,78 +1,78 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Wrapper mostly compatible with `libsamplerate'.
* (Libsoxr's native API can be found in soxr.h). */
#if !defined SAMPLERATE_H
#define SAMPLERATE_H
#if defined __cplusplus
extern "C" {
#endif
#if defined SOXR_DLL
#if defined soxr_lsr_EXPORTS
#define SOXR __declspec(dllexport)
#else
#define SOXR __declspec(dllimport)
#endif
#else
#define SOXR
#endif
typedef float SRC_SAMPLE;
#if !defined SOXR_LIB
enum SRC_SRCTYPE_e {SRC_SINC_BEST_QUALITY, SRC_SINC_MEDIUM_QUALITY,
SRC_SINC_FASTEST, SRC_ZERO_ORDER_HOLD, SRC_LINEAR};
typedef int SRC_SRCTYPE;
typedef int SRC_ERROR;
typedef long (* src_callback_t)(void *, SRC_SAMPLE * *);
typedef struct SRC_STATE SRC_STATE;
typedef struct SRC_DATA {
SRC_SAMPLE * data_in, * data_out;
long input_frames, output_frames;
long input_frames_used, output_frames_gen;
int end_of_input;
double src_ratio;
} SRC_DATA;
#endif
SOXR SRC_STATE * src_new(SRC_SRCTYPE, int num_channels, SRC_ERROR *);
SOXR SRC_ERROR src_process (SRC_STATE *, SRC_DATA *);
SOXR SRC_ERROR src_set_ratio(SRC_STATE *, double);
SOXR SRC_ERROR src_reset (SRC_STATE *);
SOXR SRC_ERROR src_error (SRC_STATE *);
SOXR SRC_STATE * src_delete (SRC_STATE *);
SOXR SRC_STATE * src_callback_new(
src_callback_t, SRC_SRCTYPE, int, SRC_ERROR *, void *);
SOXR long src_callback_read(
SRC_STATE *, double src_ratio, long, SRC_SAMPLE *);
SOXR SRC_ERROR src_simple(SRC_DATA *, SRC_SRCTYPE, int);
SOXR char const * src_get_name(SRC_SRCTYPE);
SOXR char const * src_get_description(SRC_SRCTYPE);
SOXR char const * src_get_version(void);
SOXR char const * src_strerror(SRC_ERROR);
SOXR int src_is_valid_ratio(double);
SOXR void src_short_to_float_array(short const *, float *, int);
SOXR void src_float_to_short_array(float const *, short *, int);
SOXR void src_int_to_float_array(int const *, float *, int);
SOXR void src_float_to_int_array(float const *, int *, int);
#undef SOXR
#if defined __cplusplus
}
#endif
#endif
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* Wrapper mostly compatible with `libsamplerate'.
* (Libsoxr's native API can be found in soxr.h). */
#if !defined SAMPLERATE_H
#define SAMPLERATE_H
#if defined __cplusplus
extern "C" {
#endif
#if defined SOXR_DLL
#if defined soxr_lsr_EXPORTS
#define SOXR __declspec(dllexport)
#else
#define SOXR __declspec(dllimport)
#endif
#else
#define SOXR
#endif
typedef float SRC_SAMPLE;
#if !defined SOXR_LIB
enum SRC_SRCTYPE_e {SRC_SINC_BEST_QUALITY, SRC_SINC_MEDIUM_QUALITY,
SRC_SINC_FASTEST, SRC_ZERO_ORDER_HOLD, SRC_LINEAR};
typedef int SRC_SRCTYPE;
typedef int SRC_ERROR;
typedef long (* src_callback_t)(void *, SRC_SAMPLE * *);
typedef struct SRC_STATE SRC_STATE;
typedef struct SRC_DATA {
SRC_SAMPLE * data_in, * data_out;
long input_frames, output_frames;
long input_frames_used, output_frames_gen;
int end_of_input;
double src_ratio;
} SRC_DATA;
#endif
SOXR SRC_STATE * src_new(SRC_SRCTYPE, int num_channels, SRC_ERROR *);
SOXR SRC_ERROR src_process (SRC_STATE *, SRC_DATA *);
SOXR SRC_ERROR src_set_ratio(SRC_STATE *, double);
SOXR SRC_ERROR src_reset (SRC_STATE *);
SOXR SRC_ERROR src_error (SRC_STATE *);
SOXR SRC_STATE * src_delete (SRC_STATE *);
SOXR SRC_STATE * src_callback_new(
src_callback_t, SRC_SRCTYPE, int, SRC_ERROR *, void *);
SOXR long src_callback_read(
SRC_STATE *, double src_ratio, long, SRC_SAMPLE *);
SOXR SRC_ERROR src_simple(SRC_DATA *, SRC_SRCTYPE, int);
SOXR char const * src_get_name(SRC_SRCTYPE);
SOXR char const * src_get_description(SRC_SRCTYPE);
SOXR char const * src_get_version(void);
SOXR char const * src_strerror(SRC_ERROR);
SOXR int src_is_valid_ratio(double);
SOXR void src_short_to_float_array(short const *, float *, int);
SOXR void src_float_to_short_array(float const *, short *, int);
SOXR void src_int_to_float_array(int const *, float *, int);
SOXR void src_float_to_int_array(float const *, int *, int);
#undef SOXR
#if defined __cplusplus
}
#endif
#endif

File diff suppressed because it is too large Load Diff

View File

@@ -1,311 +1,318 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* -------------------------------- Gubbins --------------------------------- */
#if !defined soxr_included
#define soxr_included
#if defined __cplusplus
#include <cstddef>
extern "C" {
#else
#include <stddef.h>
#endif
#if defined SOXR_DLL
#if defined soxr_EXPORTS
#define SOXR __declspec(dllexport)
#else
#define SOXR __declspec(dllimport)
#endif
#else
#define SOXR
#endif
typedef struct soxr_io_spec soxr_io_spec_t;
typedef struct soxr_quality_spec soxr_quality_spec_t;
typedef struct soxr_runtime_spec soxr_runtime_spec_t;
/* ---------------------------- API conventions --------------------------------
Buffer lengths (and occupancies) are expressed as the number of contained
samples per channel.
Parameter names for buffer lengths have the suffix `len'.
A single-character `i' or 'o' is often used in names to give context as
input or output (e.g. ilen, olen). */
/* --------------------------- Type declarations ---------------------------- */
typedef struct soxr * soxr_t; /* A resampler for 1 or more channels. */
typedef char const * soxr_error_t; /* 0:no-error; non-0:error. */
typedef void * soxr_buf_t; /* 1 buffer of channel-interleaved samples. */
typedef void const * soxr_cbuf_t; /* Ditto; read-only. */
typedef soxr_buf_t const * soxr_bufs_t;/* Or, a separate buffer for each ch. */
typedef soxr_cbuf_t const * soxr_cbufs_t; /* Ditto; read-only. */
typedef void const * soxr_in_t; /* Either a soxr_cbuf_t or soxr_cbufs_t,
depending on itype in soxr_io_spec_t. */
typedef void * soxr_out_t; /* Either a soxr_buf_t or soxr_bufs_t,
depending on otype in soxr_io_spec_t. */
/* --------------------------- API main functions --------------------------- */
SOXR char const * soxr_version(void); /* Query library version: "x.y.z". */
#define soxr_strerror(e) /* Soxr counterpart to strerror. */ \
((e)?(e):"no error")
/* Create a stream resampler: */
SOXR soxr_t soxr_create(
double input_rate, /* Input sample-rate. */
double output_rate, /* Output sample-rate. */
unsigned num_channels, /* Number of channels to be used. */
/* All following arguments are optional (may be set to NULL). */
soxr_error_t *, /* To report any error during creation. */
soxr_io_spec_t const *, /* To specify non-default I/O formats. */
soxr_quality_spec_t const *, /* To specify non-default resampling quality.*/
soxr_runtime_spec_t const *);/* To specify non-default runtime resources. */
/* If not using an app-supplied input function, after creating a stream
* resampler, repeatedly call: */
SOXR soxr_error_t soxr_process(
soxr_t resampler, /* As returned by soxr_create. */
/* Input (to be resampled): */
soxr_in_t in, /* Input buffer(s); may be NULL (see below). */
size_t ilen, /* Input buf. length (samples per channel). */
size_t * idone, /* To return actual # samples used (<= ilen). */
/* Output (resampled): */
soxr_out_t out, /* Output buffer(s).*/
size_t olen, /* Output buf. length (samples per channel). */
size_t * odone); /* To return actual # samples out (<= olen).
Note that no special meaning is associated with ilen or olen equal to
zero. End-of-input (i.e. no data is available nor shall be available)
may be indicated by seting in to zero. */
/* If using an app-supplied input function, it must look and behave like this:*/
typedef size_t /* data_len */
(* soxr_input_fn_t)( /* Supply data to be resampled. */
void * input_fn_state, /* As given to soxr_set_input_fn (below). */
soxr_in_t * data, /* Returned data; see below. N.B. ptr to ptr(s)*/
size_t requested_len); /* Samples per channel, >= returned data_len.
data_len *data Indicates Meaning
------- ------- ------------ -------------------------
!=0 !=0 Success *data contains data to be
input to the resampler.
0 !=0 (or End-of-input No data is available nor
not set) shall be available.
0 0 Failure An error occurred whilst trying to
source data to be input to the resampler. */
/* and be registered with a previously created stream resampler using: */
SOXR soxr_error_t soxr_set_input_fn(/* Set (or reset) an input function.*/
soxr_t resampler, /* As returned by soxr_create. */
soxr_input_fn_t, /* Function to supply data to be resampled.*/
void * input_fn_state); /* If needed by the input function. */
/* then repeatedly call: */
SOXR size_t /*odone*/ soxr_output(/* Resample and output a block of data.*/
soxr_t resampler, /* As returned by soxr_create. */
soxr_out_t data, /* App-supplied buffer(s) for resampled data.*/
size_t olen); /* Amount of data to output; >= odone. */
/* Common stream resampler operations: */
SOXR soxr_error_t soxr_error(soxr_t); /* Query error status. */
SOXR size_t * soxr_num_clips(soxr_t); /* Query int. clip counter (for R/W). */
SOXR double soxr_delay(soxr_t); /* Query current delay in output samples.*/
SOXR char const * soxr_engine(soxr_t p);/* Query resampling engine name. */
SOXR soxr_error_t soxr_clear(soxr_t); /* Ready for fresh signal, same config. */
SOXR void soxr_delete(soxr_t); /* Free resources. */
/* `Short-cut', single call to resample a (probably short) signal held entirely
* in memory. See soxr_create and soxr_process above for parameter details. */
SOXR soxr_error_t soxr_oneshot(
double input_rate,
double output_rate,
unsigned num_channels,
soxr_in_t in , size_t ilen, size_t * idone,
soxr_out_t out, size_t olen, size_t * odone,
soxr_io_spec_t const *,
soxr_quality_spec_t const *,
soxr_runtime_spec_t const *);
/* -------------------------- API type definitions -------------------------- */
typedef enum { /* Datatypes supported for I/O to/from the resampler: */
/* Internal; do not use: */
SOXR_FLOAT32, SOXR_FLOAT64, SOXR_INT32, SOXR_INT16, SOXR_SPLIT = 4,
/* Use for interleaved channels: */
SOXR_FLOAT32_I = SOXR_FLOAT32, SOXR_FLOAT64_I, SOXR_INT32_I, SOXR_INT16_I,
/* Use for split channels: */
SOXR_FLOAT32_S = SOXR_SPLIT , SOXR_FLOAT64_S, SOXR_INT32_S, SOXR_INT16_S
} soxr_datatype_t;
#define soxr_datatype_size(x) /* Returns `sizeof' a soxr_datatype_t sample. */\
((unsigned char *)"\4\10\4\2")[(x)&3]
struct soxr_io_spec { /* Typically */
soxr_datatype_t itype; /* Input datatype. SOXR_FLOAT32_I */
soxr_datatype_t otype; /* Output datatype. SOXR_FLOAT32_I */
double scale; /* Linear gain to apply during resampling. 1 */
void * e; /* Reserved for internal use 0 */
unsigned long flags; /* Per the following #defines. 0 */
};
#define SOXR_TPDF 0 /* Applicable only if otype is INT16. */
#define SOXR_NO_DITHER 8u /* Disable the above. */
struct soxr_quality_spec { /* Typically */
double bits; /* Required bit-accuracy (pass + stop). 20 */
double phase; /* Linear/minimum etc. phase. [0,100] 50 */
double bw_pc; /* Pass-band % (0dB pt.) to preserve. 91.3 */
double anti_aliasing_pc; /* % bandwidth without aliasing. 100 */
void * e; /* Reserved for internal use. 0 */
unsigned long flags; /* Per the following #defines. 0 */
};
#define SOXR_ROLLOFF_SMALL 0u /* <= 0.01 dB */
#define SOXR_ROLLOFF_MEDIUM 1u /* <= 0.35 dB */
#define SOXR_ROLLOFF_NONE 2u /* For Chebyshev bandwidth. */
#define SOXR_MAINTAIN_3DB_PT 4u /* Reserved for internal use. */
#define SOXR_HI_PREC_CLOCK 8u /* Increase `irrational' ratio accuracy. */
#define SOXR_DOUBLE_PRECISION 16u /* Use double prec. even @ bitdepths <= 20.*/
#define SOXR_VR 32u /* Reserved for future use. */
struct soxr_runtime_spec { /* Typically */
unsigned log2_min_dft_size;/* For DFT efficiency. [8,15] 10 */
unsigned log2_large_dft_size;/* For DFT efficiency. [16,20] 17 */
unsigned coef_size_kbytes; /* For SOXR_COEF_INTERP_AUTO (below). 400 */
unsigned num_threads; /* If built so. 0 means `automatic'. 1 */
void * e; /* Reserved for internal use. 0 */
unsigned long flags; /* Per the following #defines. 0 */
};
/* For `irrational' ratios only: */
#define SOXR_COEF_INTERP_AUTO 0u /* Auto select coef. interpolation. */
#define SOXR_COEF_INTERP_LOW 1u /* Man. select: less CPU, more memory. */
#define SOXR_COEF_INTERP_HIGH 2u /* Man. select: more CPU, less memory. */
#define SOXR_STRICT_BUFFERING 4u /* Reserved for future use. */
#define SOXR_NOSMALLINTOPT 8u /* More CPU, less latency for 3/2, 3/4 etc.*/
/* -------------------------- API type constructors ------------------------- */
/* These functions allow setting of the most commonly-used structure
* parameters, with other parameters being given default values. The default
* values may then be overridden, directly in the structure, if needed. */
SOXR soxr_quality_spec_t soxr_quality_spec(
unsigned long recipe, /* Per the #defines immediately below. */
unsigned long flags); /* As soxr_quality_spec_t.flags. */
/* The 5 standard qualities found in SoX: */
#define SOXR_QQ 0 /* 'Quick' cubic interpolation. */
#define SOXR_LQ 1 /* 'Low' 16-bit with larger rolloff. */
#define SOXR_MQ 2 /* 'Medium' 16-bit with medium rolloff. */
#define SOXR_HQ SOXR_20_BITQ /* 'High quality'. */
#define SOXR_VHQ SOXR_28_BITQ /* 'Very high quality'. */
#define SOXR_16_BITQ 3
#define SOXR_20_BITQ 4
#define SOXR_24_BITQ 5
#define SOXR_28_BITQ 6
#define SOXR_32_BITQ 7
/* Libsamplerate equivalent qualities: */
#define SOXR_LSR0Q 8 /* 'Best sinc'. */
#define SOXR_LSR1Q 9 /* 'Medium sinc'. */
#define SOXR_LSR2Q 10 /* 'Fast sinc'. */
#define SOXR_LINEAR_PHASE 0x00
#define SOXR_INTERMEDIATE_PHASE 0x10
#define SOXR_MINIMUM_PHASE 0x30
#define SOXR_STEEP_FILTER 0x40
#define SOXR_ALLOW_ALIASING 0x80 /* Reserved for future use. */
SOXR soxr_runtime_spec_t soxr_runtime_spec(
unsigned num_threads);
SOXR soxr_io_spec_t soxr_io_spec(
soxr_datatype_t itype,
soxr_datatype_t otype);
/* --------------------------- Internal use only ---------------------------- */
SOXR soxr_error_t soxr_set_error(soxr_t, soxr_error_t);
SOXR soxr_error_t soxr_set_num_channels(soxr_t, unsigned);
SOXR soxr_error_t soxr_set_oi_ratio(soxr_t, double);
#undef SOXR
#if defined __cplusplus
}
#endif
#endif
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
*
* This library is free software; you can redistribute it and/or modify it
* under the terms of the GNU Lesser General Public License as published by
* the Free Software Foundation; either version 2.1 of the License, or (at
* your option) any later version.
*
* This library is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser
* General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this library; if not, write to the Free Software Foundation,
* Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*/
/* -------------------------------- Gubbins --------------------------------- */
#if !defined soxr_included
#define soxr_included
#if defined __cplusplus
#include <cstddef>
extern "C" {
#else
#include <stddef.h>
#endif
#if defined SOXR_DLL
#if defined soxr_EXPORTS
#define SOXR __declspec(dllexport)
#else
#define SOXR __declspec(dllimport)
#endif
#else
#define SOXR
#endif
typedef struct soxr_io_spec soxr_io_spec_t;
typedef struct soxr_quality_spec soxr_quality_spec_t;
typedef struct soxr_runtime_spec soxr_runtime_spec_t;
/* ---------------------------- API conventions --------------------------------
Buffer lengths (and occupancies) are expressed as the number of contained
samples per channel.
Parameter names for buffer lengths have the suffix `len'.
A single-character `i' or 'o' is often used in names to give context as
input or output (e.g. ilen, olen). */
/* --------------------------- Type declarations ---------------------------- */
typedef struct soxr * soxr_t; /* A resampler for 1 or more channels. */
typedef char const * soxr_error_t; /* 0:no-error; non-0:error. */
typedef void * soxr_buf_t; /* 1 buffer of channel-interleaved samples. */
typedef void const * soxr_cbuf_t; /* Ditto; read-only. */
typedef soxr_buf_t const * soxr_bufs_t;/* Or, a separate buffer for each ch. */
typedef soxr_cbuf_t const * soxr_cbufs_t; /* Ditto; read-only. */
typedef void const * soxr_in_t; /* Either a soxr_cbuf_t or soxr_cbufs_t,
depending on itype in soxr_io_spec_t. */
typedef void * soxr_out_t; /* Either a soxr_buf_t or soxr_bufs_t,
depending on otype in soxr_io_spec_t. */
/* --------------------------- API main functions --------------------------- */
SOXR char const * soxr_version(void); /* Query library version: "x.y.z". */
#define soxr_strerror(e) /* Soxr counterpart to strerror. */ \
((e)?(e):"no error")
/* Create a stream resampler: */
SOXR soxr_t soxr_create(
double input_rate, /* Input sample-rate. */
double output_rate, /* Output sample-rate. */
unsigned num_channels, /* Number of channels to be used. */
/* All following arguments are optional (may be set to NULL). */
soxr_error_t *, /* To report any error during creation. */
soxr_io_spec_t const *, /* To specify non-default I/O formats. */
soxr_quality_spec_t const *, /* To specify non-default resampling quality.*/
soxr_runtime_spec_t const *);/* To specify non-default runtime resources. */
/* If not using an app-supplied input function, after creating a stream
* resampler, repeatedly call: */
SOXR soxr_error_t soxr_process(
soxr_t resampler, /* As returned by soxr_create. */
/* Input (to be resampled): */
soxr_in_t in, /* Input buffer(s); may be NULL (see below). */
size_t ilen, /* Input buf. length (samples per channel). */
size_t * idone, /* To return actual # samples used (<= ilen). */
/* Output (resampled): */
soxr_out_t out, /* Output buffer(s).*/
size_t olen, /* Output buf. length (samples per channel). */
size_t * odone); /* To return actual # samples out (<= olen).
Note that no special meaning is associated with ilen or olen equal to
zero. End-of-input (i.e. no data is available nor shall be available)
may be indicated by seting `in' to NULL. */
/* If using an app-supplied input function, it must look and behave like this:*/
typedef size_t /* data_len */
(* soxr_input_fn_t)( /* Supply data to be resampled. */
void * input_fn_state, /* As given to soxr_set_input_fn (below). */
soxr_in_t * data, /* Returned data; see below. N.B. ptr to ptr(s)*/
size_t requested_len); /* Samples per channel, >= returned data_len.
data_len *data Indicates Meaning
------- ------- ------------ -------------------------
!=0 !=0 Success *data contains data to be
input to the resampler.
0 !=0 (or End-of-input No data is available nor
not set) shall be available.
0 0 Failure An error occurred whilst trying to
source data to be input to the resampler. */
/* and be registered with a previously created stream resampler using: */
SOXR soxr_error_t soxr_set_input_fn(/* Set (or reset) an input function.*/
soxr_t resampler, /* As returned by soxr_create. */
soxr_input_fn_t, /* Function to supply data to be resampled.*/
void * input_fn_state, /* If needed by the input function. */
size_t max_ilen); /* Maximum value for input fn. requested_len.*/
/* then repeatedly call: */
SOXR size_t /*odone*/ soxr_output(/* Resample and output a block of data.*/
soxr_t resampler, /* As returned by soxr_create. */
soxr_out_t data, /* App-supplied buffer(s) for resampled data.*/
size_t olen); /* Amount of data to output; >= odone. */
/* Common stream resampler operations: */
SOXR soxr_error_t soxr_error(soxr_t); /* Query error status. */
SOXR size_t * soxr_num_clips(soxr_t); /* Query int. clip counter (for R/W). */
SOXR double soxr_delay(soxr_t); /* Query current delay in output samples.*/
SOXR char const * soxr_engine(soxr_t p);/* Query resampling engine name. */
SOXR soxr_error_t soxr_clear(soxr_t); /* Ready for fresh signal, same config. */
SOXR void soxr_delete(soxr_t); /* Free resources. */
/* `Short-cut', single call to resample a (probably short) signal held entirely
* in memory. See soxr_create and soxr_process above for parameter details. */
SOXR soxr_error_t soxr_oneshot(
double input_rate,
double output_rate,
unsigned num_channels,
soxr_in_t in , size_t ilen, size_t * idone,
soxr_out_t out, size_t olen, size_t * odone,
soxr_io_spec_t const *,
soxr_quality_spec_t const *,
soxr_runtime_spec_t const *);
/* For variable-rate resampling (experimental). See example # 5 for how to
* create a variable-rate resampler and how to use this function. */
SOXR soxr_error_t soxr_set_io_ratio(soxr_t, double io_ratio, size_t slew_len);
/* -------------------------- API type definitions -------------------------- */
typedef enum { /* Datatypes supported for I/O to/from the resampler: */
/* Internal; do not use: */
SOXR_FLOAT32, SOXR_FLOAT64, SOXR_INT32, SOXR_INT16, SOXR_SPLIT = 4,
/* Use for interleaved channels: */
SOXR_FLOAT32_I = SOXR_FLOAT32, SOXR_FLOAT64_I, SOXR_INT32_I, SOXR_INT16_I,
/* Use for split channels: */
SOXR_FLOAT32_S = SOXR_SPLIT , SOXR_FLOAT64_S, SOXR_INT32_S, SOXR_INT16_S
} soxr_datatype_t;
#define soxr_datatype_size(x) /* Returns `sizeof' a soxr_datatype_t sample. */\
((unsigned char *)"\4\10\4\2")[(x)&3]
struct soxr_io_spec { /* Typically */
soxr_datatype_t itype; /* Input datatype. SOXR_FLOAT32_I */
soxr_datatype_t otype; /* Output datatype. SOXR_FLOAT32_I */
double scale; /* Linear gain to apply during resampling. 1 */
void * e; /* Reserved for internal use 0 */
unsigned long flags; /* Per the following #defines. 0 */
};
#define SOXR_TPDF 0 /* Applicable only if otype is INT16. */
#define SOXR_NO_DITHER 8u /* Disable the above. */
struct soxr_quality_spec { /* Typically */
double bits; /* Required bit-accuracy (pass + stop). 20 */
double phase; /* Linear/minimum etc. phase. [0,100] 50 */
double bw_pc; /* Pass-band % (0dB pt.) to preserve. 91.3 */
double anti_aliasing_pc; /* % bandwidth without aliasing. 100 */
void * e; /* Reserved for internal use. 0 */
unsigned long flags; /* Per the following #defines. 0 */
};
#define SOXR_ROLLOFF_SMALL 0u /* <= 0.01 dB */
#define SOXR_ROLLOFF_MEDIUM 1u /* <= 0.35 dB */
#define SOXR_ROLLOFF_NONE 2u /* For Chebyshev bandwidth. */
#define SOXR_MAINTAIN_3DB_PT 4u /* Reserved for internal use. */
#define SOXR_HI_PREC_CLOCK 8u /* Increase `irrational' ratio accuracy. */
#define SOXR_DOUBLE_PRECISION 16u /* Use double prec. even @ bitdepths <= 20.*/
#define SOXR_VR 32u /* Experimental, variable-rate resampling. */
struct soxr_runtime_spec { /* Typically */
unsigned log2_min_dft_size;/* For DFT efficiency. [8,15] 10 */
unsigned log2_large_dft_size;/* For DFT efficiency. [16,20] 17 */
unsigned coef_size_kbytes; /* For SOXR_COEF_INTERP_AUTO (below). 400 */
unsigned num_threads; /* If built so. 0 means `automatic'. 1 */
void * e; /* Reserved for internal use. 0 */
unsigned long flags; /* Per the following #defines. 0 */
};
/* For `irrational' ratios only: */
#define SOXR_COEF_INTERP_AUTO 0u /* Auto select coef. interpolation. */
#define SOXR_COEF_INTERP_LOW 1u /* Man. select: less CPU, more memory. */
#define SOXR_COEF_INTERP_HIGH 2u /* Man. select: more CPU, less memory. */
#define SOXR_STRICT_BUFFERING 4u /* Reserved for future use. */
#define SOXR_NOSMALLINTOPT 8u /* For test purposes only. */
/* -------------------------- API type constructors ------------------------- */
/* These functions allow setting of the most commonly-used structure
* parameters, with other parameters being given default values. The default
* values may then be overridden, directly in the structure, if needed. */
SOXR soxr_quality_spec_t soxr_quality_spec(
unsigned long recipe, /* Per the #defines immediately below. */
unsigned long flags); /* As soxr_quality_spec_t.flags. */
/* The 5 standard qualities found in SoX: */
#define SOXR_QQ 0 /* 'Quick' cubic interpolation. */
#define SOXR_LQ 1 /* 'Low' 16-bit with larger rolloff. */
#define SOXR_MQ 2 /* 'Medium' 16-bit with medium rolloff. */
#define SOXR_HQ SOXR_20_BITQ /* 'High quality'. */
#define SOXR_VHQ SOXR_28_BITQ /* 'Very high quality'. */
#define SOXR_16_BITQ 3
#define SOXR_20_BITQ 4
#define SOXR_24_BITQ 5
#define SOXR_28_BITQ 6
#define SOXR_32_BITQ 7
/* Libsamplerate equivalent qualities: */
#define SOXR_LSR0Q 8 /* 'Best sinc'. */
#define SOXR_LSR1Q 9 /* 'Medium sinc'. */
#define SOXR_LSR2Q 10 /* 'Fast sinc'. */
#define SOXR_LINEAR_PHASE 0x00
#define SOXR_INTERMEDIATE_PHASE 0x10
#define SOXR_MINIMUM_PHASE 0x30
#define SOXR_STEEP_FILTER 0x40
#define SOXR_ALLOW_ALIASING 0x80 /* Reserved for future use. */
SOXR soxr_runtime_spec_t soxr_runtime_spec(
unsigned num_threads);
SOXR soxr_io_spec_t soxr_io_spec(
soxr_datatype_t itype,
soxr_datatype_t otype);
/* --------------------------- Internal use only ---------------------------- */
SOXR soxr_error_t soxr_set_error(soxr_t, soxr_error_t);
SOXR soxr_error_t soxr_set_num_channels(soxr_t, unsigned);
#undef SOXR
#if defined __cplusplus
}
#endif
#endif

771
lib-src/libsoxr/src/vr32.c Normal file
View File

@@ -0,0 +1,771 @@
/* SoX Resampler Library Copyright (c) 2007-12 robs@users.sourceforge.net
* Licence for this file: LGPL v2.1 See LICENCE for details. */
/* Experimental variable-rate resampling. */
#include <assert.h>
#include <math.h>
#if !defined M_PI
#define M_PI 3.14159265358979323846
#endif
#if !defined M_LN2
#define M_LN2 0.69314718055994530942
#endif
#include <string.h>
#include <stdlib.h>
#include "internal.h"
#define FIFO_SIZE_T int
#define FIFO_MIN 0x8000
#include "fifo.h"
#define FADE_LEN_BITS 9
#define PHASE_BITS_D (8 + PHASE_MORE)
#define PHASE_BITS_U (7 + PHASE_MORE)
#define PHASE_MORE 0 /* 2 improves small int, and large u, ratios. */
#define PHASES0_D 12
#define POLY_FIR_LEN_D 20
#define PHASES0_U 6
#define POLY_FIR_LEN_U 12
#define MULT32 (65536. * 65536.)
#define PHASES_D (1 << PHASE_BITS_D)
#define PHASES_U (1 << PHASE_BITS_U)
static float const half_fir_coefs[] = {
4.7111692735253413e-1f, 3.1690797657656167e-1f, 2.8691667164678896e-2f,
-1.0192825848403946e-1f, -2.8122856237424654e-2f, 5.6804928137780292e-2f,
2.7192768359197508e-2f, -3.6082309197154230e-2f, -2.5927789156038026e-2f,
2.3644444384060669e-2f, 2.4363075319345607e-2f, -1.5127630198606428e-2f,
-2.2541790286342567e-2f, 8.8733836742880233e-3f, 2.0513077413933017e-2f,
-4.1186431656279818e-3f, -1.8330444480421631e-2f, 4.6288071358217028e-4f,
1.6049769308921290e-2f, 2.3282106680446069e-3f, -1.3727327353082214e-2f,
-4.4066375505196096e-3f, 1.1417847550661287e-2f, 5.8817724081355978e-3f,
-9.1727580349157123e-3f, -6.8404638339394346e-3f, 7.0385357033205332e-3f,
7.3574525331962567e-3f, -5.0554197628506353e-3f, -7.5008330890673153e-3f,
3.2563575907277676e-3f, 7.3346538206330259e-3f, -1.6663208501478607e-3f,
-6.9199171108861694e-3f, 3.0196567996023190e-4f, 6.3146436955438768e-3f,
8.2835711466756098e-4f, -5.5734271982033918e-3f, -1.7242765658561860e-3f,
4.7467223803576682e-3f, 2.3927523666941205e-3f, -3.8801054688632139e-3f,
-2.8472115748114728e-3f, 3.0135659731132642e-3f, 3.1064651802365259e-3f,
-2.1809660142807748e-3f, -3.1935061143485862e-3f, 1.4096923923208671e-3f,
3.1342382222281609e-3f, -7.2053095076414931e-4f, -2.9561940489039682e-3f,
1.2777585046118889e-4f, 2.6873033434313882e-3f, 3.6043554054680685e-4f,
-2.3547716396561816e-3f, -7.4160208709749312e-4f, 1.9840894915230177e-3f,
1.0181606831615856e-3f, -1.5982325266851590e-3f, -1.1966774804490967e-3f,
1.2170528733224913e-3f, 1.2869618709883193e-3f, -8.5687504489877664e-4f,
-1.3011452950496001e-3f, 5.3030588389885972e-4f, 1.2527854026453923e-3f,
-2.4622758430821288e-4f, -1.1560181289625195e-3f, 9.9661643910782316e-6f,
1.0247989665318426e-3f, 1.7639297561664703e-4f, -8.7226452073196350e-4f,
-3.1358436147401782e-4f, 7.1022054657665971e-4f, 4.0466151692224986e-4f,
-5.4877022848030636e-4f, -4.5444807961399138e-4f, 3.9609542800868769e-4f,
4.6899779918507020e-4f, -2.5835154936239735e-4f, -4.5505391611721792e-4f,
1.3970512544147175e-4f, 4.1957352577882777e-4f, -4.2458993694471047e-5f,
-3.6930861782460262e-4f, -3.2738549063278822e-5f, 3.1046609224355927e-4f,
8.6624679037202785e-5f, -2.4845427128026068e-4f, -1.2101300074995281e-4f,
1.8773208187021294e-4f, 1.3849844077872591e-4f, -1.3170611080827864e-4f,
-1.4212373327156217e-4f, 8.2758595879431528e-5f, 1.3513059684140468e-4f,
-4.2284127775471251e-5f, -1.2070298779675768e-4f, 1.0811692847491609e-5f,
1.0178008299781669e-4f, 1.1852545451857104e-5f, -8.0914539313342186e-5f,
-2.6454558961220653e-5f, 6.0208388858339534e-5f, 3.4169979203255580e-5f,
-4.1203296686185329e-5f, -3.6353143441156863e-5f, 2.4999186627094098e-5f,
3.4542829080466582e-5f, -1.2148053427488782e-5f, -3.0260855999161159e-5f,
2.7687092952335852e-6f, 2.5095689880235108e-5f, 3.6223160417538916e-6f,
-2.0960977068565079e-5f, -9.3312292092513232e-6f, 2.0711288605113663e-5f,
3.1992093654438569e-5f, 1.9772538588596925e-5f, 4.8667740603532560e-6f,
-5.3495033191567977e-7f,
};
#define CONVOLVE \
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ \
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
#define HALF_FIR_LEN_2 (iAL(half_fir_coefs) - 1)
#define HALF_FIR_LEN_4 (HALF_FIR_LEN_2 / 2)
#define _ sum += (input[-i] + input[i]) * half_fir_coefs[i], ++i;
static float half_fir(float const * input)
{
long i = 1;
float sum = input[0] * half_fir_coefs[0];
CONVOLVE CONVOLVE
assert(i == HALF_FIR_LEN_2 + 1);
return (float)sum;
}
#undef _
#define _ sum += (input[-i] + input[i]) * half_fir_coefs[2*i], ++i;
static float double_fir0(float const * input)
{
int i = 1;
float sum = input[0] * half_fir_coefs[0];
CONVOLVE
assert(i == HALF_FIR_LEN_4 + 1);
return (float)(sum * 2);
}
#undef _
#define _ sum += (input[-i] + input[1+i]) * half_fir_coefs[2*i+1], ++i;
static float double_fir1(float const * input)
{
int i = 0;
float sum = 0;
CONVOLVE
assert(i == HALF_FIR_LEN_4 + 0);
return (float)(sum * 2);
}
#undef _
static float fast_half_fir(float const * input)
{
static const float coefs[] = {
.3094188462713818f, -.08198144615199748f, .03055232105456833f,
-.01015890277986387f, .002513237297525149f, -.0003469672050347395f,
};
int i = 0;
float sum = input[0] * .5f;
#define _ sum += (input[-(2*i+1)] + input[2*i+1]) * coefs[i], ++i;
_ _ _ _ _ _
#undef _
return (float)sum;
}
static const float iir_coefs[] = {
.0262852045255816f, .0998310478296204f, .2068650611060755f,
.3302241336172489f, .4544203620946318f, .5685783569471244f,
.6669444657994612f, .7478697711807407f, .8123244036799226f,
.8626000999654434f, .9014277444199280f, .9314860567781748f,
.9551915287878752f, .9746617828910630f, .9917763050166036f,
};
#define IIR_FILTER _ _ _ _ _ _ _
#define _ in1=(in1-p->y[i])*iir_coefs[i]+tmp1;tmp1=p->y[i],p->y[i]=in1;++i;\
in0=(in0-p->y[i])*iir_coefs[i]+tmp0;tmp0=p->y[i],p->y[i]=in0;++i;
typedef struct {float x[2], y[AL(iir_coefs)];} half_iir_t;
static float half_iir1(half_iir_t * p, float in0, float in1)
{
int i = 0;
float tmp0, tmp1;
tmp0 = p->x[0], p->x[0] = in0;
tmp1 = p->x[1], p->x[1] = in1;
IIR_FILTER
p->y[i] = in1 = (in1 - p->y[i]) * iir_coefs[i] + tmp1;
return in1 + in0;
}
#undef _
static void half_iir(half_iir_t * p, float * obuf, float const * ibuf, int olen)
{
int i;
for (i=0; i < olen; obuf[i] = (float)half_iir1(p, ibuf[i*2], ibuf[i*2+1]),++i);
}
static void half_phase(half_iir_t * p, float * buf, int len)
{
float const small_normal = 1/MULT32/MULT32; /* To quash denormals on path 0.*/
int i;
for (i = 0; i < len; buf[i] = (float)half_iir1(p, buf[i], 0), ++i);
#define _ p->y[i] += small_normal, i += 2;
i = 0, _ IIR_FILTER
#undef _
#define _ p->y[i] -= small_normal, i += 2;
i = 0, _ IIR_FILTER
#undef _
}
#define raw_coef_t float
static const raw_coef_t coefs0_d[POLY_FIR_LEN_D / 2 * PHASES0_D + 1] = {
0.f, 1.4057457935754080e-5f, 2.3302768424632188e-5f, 4.0084897378442095e-5f,
6.1916773126231636e-5f, 8.7973434034929016e-5f, 1.1634847507082481e-4f,
1.4391931654629385e-4f, 1.6635470822160746e-4f, 1.7830838562749493e-4f,
1.7382737311735053e-4f, 1.4698011689178234e-4f, 9.2677933545427018e-5f,
7.6288745483685147e-6f, -1.0867156553965507e-4f, -2.5303924530322309e-4f,
-4.1793463959360433e-4f, -5.9118012513731508e-4f, -7.5619603440508576e-4f,
-8.9285245696990080e-4f, -9.7897684238178358e-4f, -9.9248131798952959e-4f,
-9.1398576537725926e-4f, -7.2972364732199553e-4f, -4.3443557115962946e-4f,
-3.3895523979487613e-5f, 4.5331297364457429e-4f, 9.9513966802111057e-4f,
1.5468348913161652e-3f, 2.0533350794358640e-3f, 2.4533031436958950e-3f,
2.6846707315385087e-3f, 2.6913237051575155e-3f, 2.4303724507982708e-3f,
1.8792817173578587e-3f, 1.0420231121204950e-3f, -4.6617252898486750e-5f,
-1.3193786988492551e-3f, -2.6781478874181100e-3f, -3.9992272197487003e-3f,
-5.1422613336274056e-3f, -5.9624224517967755e-3f, -6.3250283969908542e-3f,
-6.1213677360236101e-3f, -5.2841872043022185e-3f, -3.8011036067186429e-3f,
-1.7241752288145494e-3f, 8.2596463599396213e-4f, 3.6626436307478369e-3f,
6.5430316636724021e-3f, 9.1853404499045010e-3f, 1.1292516396583619e-2f,
1.2580791345879052e-2f, 1.2810714562937180e-2f, 1.1817712330677889e-2f,
9.5388893881204976e-3f, 6.0327678128662696e-3f, 1.4889921444742027e-3f,
-3.7742770128030593e-3f, -9.3265389310393538e-3f, -1.4654680466977541e-2f,
-1.9204813565928323e-2f, -2.2433342812570076e-2f, -2.3863084249865732e-2f,
-2.3139248817097825e-2f, -2.0079526147977360e-2f, -1.4712465100990968e-2f,
-7.2989072959128900e-3f, 1.6676055337427264e-3f, 1.1483818597217116e-2f,
2.1283378291010333e-2f, 3.0104924254589629e-2f, 3.6977102234817580e-2f,
4.1013752396638667e-2f, 4.1510805491867378e-2f, 3.8035383354576423e-2f,
3.0497421566956902e-2f, 1.9194910514469185e-2f, 4.8255960959712636e-3f,
-1.1539393212932630e-2f, -2.8521204184392364e-2f, -4.4535662544571142e-2f,
-5.7926040870466614e-2f, -6.7116245375785713e-2f, -7.0771566186484461e-2f,
-6.7952220045636696e-2f, -5.8244261062898019e-2f, -4.1853211028450271e-2f,
-1.9648003905967236e-2f, 6.8535507014343263e-3f, 3.5561844452076982e-2f,
6.3953651316164553e-2f, 8.9264185854578418e-2f, 1.0872025112127688e-1f,
1.1979689474056175e-1f, 1.2047646491371326e-1f, 1.0948710929592399e-1f,
8.6497869185231543e-2f, 5.2249701648862154e-2f, 8.6059406690018377e-3f,
-4.1488376792262582e-2f, -9.4141677945723271e-2f, -1.4474093381170536e-1f,
-1.8825408052888104e-1f, -2.1958987927558168e-1f, -2.3398931875783419e-1f,
-2.2741860176576378e-1f, -1.9693206642095332e-1f, -1.4097432039328661e-1f,
-5.9594435654526039e-2f, 4.5448949025739843e-2f, 1.7070477403312445e-1f,
3.1117273816011837e-1f, 4.6056631075658744e-1f, 6.1167961235662682e-1f,
7.5683349228721264e-1f, 8.8836924234920911e-1f, 9.9915393319190682e-1f,
1.0830597619389459e+0f, 1.1353812335460003e+0f, 1.1531583819295732e+0f,
};
static const raw_coef_t coefs0_u[POLY_FIR_LEN_U / 2 * PHASES0_U + 1] = {
0.f, 2.4376543962047211e-5f, 9.7074354091545404e-5f, 2.5656573977863553e-4f,
5.2734092391248152e-4f, 8.9078135146855391e-4f, 1.2494786883827907e-3f,
1.4060353542261659e-3f, 1.0794576035695273e-3f, -2.1547711862939183e-5f,
-2.0658693124381805e-3f, -4.9333908355966233e-3f, -8.0713165910440213e-3f,
-1.0451560117817383e-2f, -1.0703998868319438e-2f, -7.4626412699536097e-3f,
1.0898921033926621e-4f, 1.1734475997741493e-2f, 2.5579413661660957e-2f,
3.8168952738129619e-2f, 4.4846162998312754e-2f, 4.0821915377309274e-2f,
2.2679961923658700e-2f, -9.9957152600624218e-3f, -5.3343924460223908e-2f,
-9.8792607573741240e-2f, -1.3382736970823086e-1f, -1.4404307655147228e-1f,
-1.1619851747063137e-1f, -4.1649695271274462e-2f, 8.0680482815468343e-2f,
2.4264355486537642e-1f, 4.2712782955601925e-1f, 6.1041328492424185e-1f,
7.6625948559498691e-1f, 8.7088876549652772e-1f, 9.0774244518772884e-1f,
};
#define coef(coef_p, interp_order, fir_len, phase_num, coef_interp_num, \
fir_coef_num) coef_p[(fir_len) * ((interp_order) + 1) * (phase_num) + \
((interp_order) + 1) * (fir_coef_num) + (interp_order - coef_interp_num)]
#define COEF(h,l,i) ((i)<0||(i)>=(l)?0:(h)[(i)>(l)/2?(l)-(i):(i)])
static void prepare_coefs(float * coefs, int n, int phases0, int phases,
raw_coef_t const * coefs0, double multiplier)
{
double k[6];
int length0 = n * phases0, length = n * phases, K0 = iAL(k)/2 - 1, i, j, pos;
raw_coef_t * coefs1 = malloc(((size_t)length / 2 + 1) * sizeof(*coefs1));
raw_coef_t * p = coefs1, f0, f1 = 0;
for (j = 0; j < iAL(k); k[j] = COEF(coefs0, length0, j - K0), ++j);
for (pos = i = 0; i < length0 / 2; ++i) {
double b=(1/24.)*(k[0]+k[4]+6*k[2]-4*(k[1]+k[3])),d=.5*(k[1]+k[3])-k[2]-b;
double a=(1/120.)*(k[5]-k[2]-9*(9*b+d)+2.5*(k[3]-k[1])-2*(k[4]-k[0]));
double c=(1/12.)*(k[4]-k[0]-2*(k[3]-k[1])-60*a),e=.5*(k[3]-k[1])-a-c;
for (; pos / phases == i; pos += phases0) {
double x = (double)(pos % phases) / phases;
*p++ = (raw_coef_t)(k[K0] + ((((a*x + b)*x + c)*x + d)*x + e)*x);
}
for (j = 0; j < iAL(k) - 1; k[j] = k[j + 1], ++j);
k[j] = COEF(coefs0, length0, i + iAL(k) / 2 + 1);
}
if (!(length & 1))
*p++ = (raw_coef_t)k[K0];
assert(p - coefs1 == length / 2 + 1);
for (i = 0; i < n; ++i) for (j = phases - 1; j >= 0; --j, f1 = f0) {
pos = (n - 1 - i) * phases + j;
f0 = COEF(coefs1, length, pos) * (raw_coef_t)multiplier;
coef(coefs, 1, n, j, 0, i) = (float)f0;
coef(coefs, 1, n, j, 1, i) = (float)(f1 - f0);
}
free(coefs1);
}
#define _ sum += (b *x + a)*input[i], ++i;
#define a (coef(poly_fir_coefs_d, 1, POLY_FIR_LEN_D, phase, 0,i))
#define b (coef(poly_fir_coefs_d, 1, POLY_FIR_LEN_D, phase, 1,i))
static float poly_fir_coefs_d[POLY_FIR_LEN_D * PHASES_D * 2];
static float poly_fir1_d(float const * input, uint32_t frac)
{
int i = 0, phase = (int)(frac >> (32 - PHASE_BITS_D));
float sum = 0, x = (float)(frac << PHASE_BITS_D) * (float)(1 / MULT32);
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _
assert(i == POLY_FIR_LEN_D);
return (float)sum;
}
#undef a
#undef b
#define a (coef(poly_fir_coefs_u, 1, POLY_FIR_LEN_U, phase, 0,i))
#define b (coef(poly_fir_coefs_u, 1, POLY_FIR_LEN_U, phase, 1,i))
static float poly_fir_coefs_u[POLY_FIR_LEN_U * PHASES_U * 2];
static float poly_fir1_u(float const * input, uint32_t frac)
{
int i = 0, phase = (int)(frac >> (32 - PHASE_BITS_U));
float sum = 0, x = (float)(frac << PHASE_BITS_U) * (float)(1 / MULT32);
_ _ _ _ _ _ _ _ _ _ _ _
assert(i == POLY_FIR_LEN_U);
return (float)sum;
}
#undef a
#undef b
#undef _
#define ADD_TO(x,y) x.all += y.all
#define SUBTRACT_FROM(x,y) x.all -= y.all
#define FRAC(x) x.part.frac
#define INT(x) x.part.integer
typedef struct {
union {
int64_t all;
#if WORDS_BIGENDIAN
struct {int32_t integer; uint32_t frac;} part;
#else
struct {uint32_t frac; int32_t integer;} part;
#endif
} at, step, step_step;
float const * input;
int len, stage_num;
bool is_d; /* true: downsampling at x2 rate; false: upsampling at 1x rate. */
double step_mult;
} stream_t;
static int poly_fir_d(stream_t * s, float * output, int olen)
{
int i;
float const * input = s->input - POLY_FIR_LEN_D / 2 + 1;
for (i = 0; i < olen && INT(s->at) < s->len; ++i) {
output[i] = poly_fir1_d(input + INT(s->at), FRAC(s->at));
ADD_TO(s->at, s->step);
if (!(INT(s->at) < s->len)) {
SUBTRACT_FROM(s->at, s->step);
break;
}
output[++i] = poly_fir1_d(input + INT(s->at), FRAC(s->at));
ADD_TO(s->at, s->step);
ADD_TO(s->step, s->step_step);
}
return i;
}
static int poly_fir_fade_d(
stream_t * s, float const * vol, int step, float * output, int olen)
{
int i;
float const * input = s->input - POLY_FIR_LEN_D / 2 + 1;
for (i = 0; i < olen && INT(s->at) < s->len; ++i, vol += step) {
output[i] += *vol * poly_fir1_d(input + INT(s->at), FRAC(s->at));
ADD_TO(s->at, s->step);
if (!(INT(s->at) < s->len)) {
SUBTRACT_FROM(s->at, s->step);
break;
}
output[++i] += *(vol += step) * poly_fir1_d(input + INT(s->at),FRAC(s->at));
ADD_TO(s->at, s->step);
ADD_TO(s->step, s->step_step);
}
return i;
}
static int poly_fir_u(stream_t * s, float * output, int olen)
{
int i;
float const * input = s->input - POLY_FIR_LEN_U / 2 + 1;
for (i = 0; i < olen && INT(s->at) < s->len; ++i) {
output[i] = poly_fir1_u(input + INT(s->at), FRAC(s->at));
ADD_TO(s->at, s->step);
ADD_TO(s->step, s->step_step);
}
return i;
}
static int poly_fir_fade_u(
stream_t * s, float const * vol, int step, float * output, int olen)
{
int i;
float const * input = s->input - POLY_FIR_LEN_U / 2 + 1;
for (i = 0; i < olen && INT(s->at) < s->len; i += 2, vol += step) {
output[i] += *vol * poly_fir1_u(input + INT(s->at), FRAC(s->at));
ADD_TO(s->at, s->step);
ADD_TO(s->step, s->step_step);
}
return i;
}
#define shiftr(x,by) ((by) < 0? (x) << (-(by)) : (x) >> (by))
#define shiftl(x,by) shiftr(x,-(by))
#define stage_occupancy(s) (fifo_occupancy(&(s)->fifo) - 4*HALF_FIR_LEN_2)
#define stage_read_p(s) ((float *)fifo_read_ptr(&(s)->fifo) + 2*HALF_FIR_LEN_2)
#define stage_preload(s) memset(fifo_reserve(&(s)->fifo, (s)->preload), \
0, sizeof(float) * (size_t)(s)->preload);
typedef struct {
fifo_t fifo;
double step_mult;
int is_fast, x_fade_len, preload;
} stage_t;
typedef struct {
int num_stages0, num_stages, flushing;
int fade_len, slew_len, xfade, stage_inc, switch_stage_num;
double new_io_ratio, default_io_ratio;
stage_t * stages;
fifo_t output_fifo;
half_iir_t halfer;
stream_t current, fadeout; /* Current/fade-in, fadeout streams. */
} rate_t;
static float fade_coefs[(2 << FADE_LEN_BITS) + 1];
static void vr_init(rate_t * p, double default_io_ratio, int num_stages, double mult)
{
int i;
assert(num_stages >= 0);
memset(p, 0, sizeof(*p));
p->num_stages0 = num_stages;
p->num_stages = num_stages = max(num_stages, 1);
p->stages = (stage_t *)calloc((unsigned)num_stages + 1, sizeof(*p->stages)) + 1;
for (i = -1; i < p->num_stages; ++i) {
stage_t * s = &p->stages[i];
fifo_create(&s->fifo, sizeof(float));
s->step_mult = 2 * MULT32 / shiftl(2, i);
s->preload = i < 0? 0 : i == 0? 2 * HALF_FIR_LEN_2 : 3 * HALF_FIR_LEN_2 / 2;
stage_preload(s);
s->is_fast = true;
lsx_debug("%-3i preload=%i", i, s->preload);
}
fifo_create(&p->output_fifo, sizeof(float));
p->default_io_ratio = default_io_ratio;
if (!fade_coefs[0]) {
for (i = 0; i < iAL(fade_coefs); ++i)
fade_coefs[i] = (float)(.5 * (1 + cos(M_PI * i / (AL(fade_coefs) - 1))));
prepare_coefs(poly_fir_coefs_u, POLY_FIR_LEN_U, PHASES0_U, PHASES_U, coefs0_u, mult);
prepare_coefs(poly_fir_coefs_d, POLY_FIR_LEN_D, PHASES0_D, PHASES_D, coefs0_d, mult *.5);
}
assert(fade_coefs[0]);
}
static void enter_new_stage(rate_t * p, int occupancy0)
{
p->current.len = shiftr(occupancy0, p->current.stage_num);
p->current.input = stage_read_p(&p->stages[p->current.stage_num]);
p->current.step_mult = p->stages[p->current.stage_num].step_mult;
p->current.is_d = p->current.stage_num >= 0;
if (p->current.is_d)
p->current.step_mult *= .5;
}
static void set_step(stream_t * p, double io_ratio)
{
p->step.all = (int64_t)(io_ratio * p->step_mult + .5);
}
static bool set_step_step(stream_t * p, double io_ratio, int slew_len)
{
int64_t dif;
int difi;
stream_t tmp = *p;
set_step(&tmp, io_ratio);
dif = tmp.step.all - p->step.all;
dif = dif < 0? dif - (slew_len >> 1) : dif + (slew_len >> 1);
difi = (int)dif; /* Try to avoid int64_t div. */
p->step_step.all = difi == dif? difi / slew_len : dif / slew_len;
return p->step_step.all != 0;
}
static void vr_set_io_ratio(rate_t * p, double io_ratio, size_t slew_len)
{
assert(io_ratio > 0);
if (slew_len) {
if (!set_step_step(&p->current, io_ratio, p->slew_len = (int)slew_len))
p->slew_len = 0, p->new_io_ratio = 0, p->fadeout.step_step.all = 0;
else {
p->new_io_ratio = io_ratio;
if (p->fade_len)
set_step_step(&p->fadeout, io_ratio, p->slew_len);
}
}
else {
if (p->default_io_ratio) { /* Then this is the first call to this fn. */
int octave = (int)floor(log(io_ratio) / M_LN2);
p->current.stage_num = octave < 0? -1 : min(octave, p->num_stages0-1);
enter_new_stage(p, 0);
}
else if (p->fade_len)
set_step(&p->fadeout, io_ratio);
set_step(&p->current, io_ratio);
if (p->default_io_ratio) FRAC(p->current.at) = FRAC(p->current.step) >> 1;
p->default_io_ratio = 0;
}
}
static bool do_input_stage(rate_t * p, int stage_num, int sign, int min_stage_num)
{
int i = 0;
float * dest;
stage_t * s = &p->stages[stage_num];
stage_t * s1 = &p->stages[stage_num - sign];
float const * src = (float *)fifo_read_ptr(&s1->fifo) + HALF_FIR_LEN_2;
int len = shiftr(fifo_occupancy(&s1->fifo) - HALF_FIR_LEN_2 * 2, sign);
int already_done = fifo_occupancy(&s->fifo) - s->preload;
if ((len -= already_done) <= 0)
return false;
src += shiftl(already_done, sign);
dest = fifo_reserve(&s->fifo, len);
if (stage_num < 0) for (; i < len; ++src)
dest[i++] = double_fir0(src), dest[i++] = double_fir1(src);
else {
bool should_be_fast = p->stage_inc;
if (!s->x_fade_len && stage_num == p->switch_stage_num) {
p->switch_stage_num = 0;
if (s->is_fast != should_be_fast) {
s->x_fade_len = 1 << FADE_LEN_BITS, s->is_fast = should_be_fast, ++p->xfade;
lsx_debug("xfade level %i, inc?=%i", stage_num, p->stage_inc);
}
}
if (s->x_fade_len) {
float const * vol1 = fade_coefs + (s->x_fade_len << 1);
float const * vol2 = fade_coefs + (((1 << FADE_LEN_BITS) - s->x_fade_len) << 1);
int n = min(len, s->x_fade_len);
/*lsx_debug("xfade level %i, inc?=%i len=%i n=%i", stage_num, p->stage_inc, s->x_fade_len, n);*/
if (should_be_fast)
for (; i < n; vol2 += 2, vol1 -= 2, src += 2)
dest[i++] = *vol1 * fast_half_fir(src) + *vol2 * half_fir(src);
else for (; i < n; vol2 += 2, vol1 -= 2, src += 2)
dest[i++] = *vol2 * fast_half_fir(src) + *vol1 * half_fir(src);
s->x_fade_len -= n;
p->xfade -= !s->x_fade_len;
}
if (stage_num < min_stage_num)
for (; i < len; dest[i++] = fast_half_fir(src), src += 2);
else for (; i < len; dest[i++] = half_fir(src), src += 2);
}
if (p->flushing > 0)
stage_preload(s);
return true;
}
static int vr_process(rate_t * p, int olen0)
{
assert(p->num_stages > 0);
if (p->default_io_ratio)
vr_set_io_ratio(p, p->default_io_ratio, 0);
{
float * output = fifo_reserve(&p->output_fifo, olen0);
int j, odone0 = 0, min_stage_num = p->current.stage_num;
int occupancy0, max_stage_num = min_stage_num;
if (p->fade_len) {
min_stage_num = min(min_stage_num, p->fadeout.stage_num);
max_stage_num = max(max_stage_num, p->fadeout.stage_num);
}
for (j = min(min_stage_num, 0); j <= max_stage_num; ++j)
if (j && !do_input_stage(p, j, j < 0? -1 : 1, min_stage_num))
break;
if (p->flushing > 0)
p->flushing = -1;
occupancy0 = shiftl(max(0,stage_occupancy(&p->stages[max_stage_num])), max_stage_num);
p->current.len = shiftr(occupancy0, p->current.stage_num);
p->current.input = stage_read_p(&p->stages[p->current.stage_num]);
if (p->fade_len) {
p->fadeout.len = shiftr(occupancy0, p->fadeout.stage_num);
p->fadeout.input = stage_read_p(&p->stages[p->fadeout.stage_num]);
}
while (odone0 < olen0) {
int odone, odone2, olen = olen0 - odone0, stage_dif = 0, shift;
float buf[64 << 1];
olen = min(olen, (int)(AL(buf) >> 1));
if (p->slew_len)
olen = min(olen, p->slew_len);
else if (p->new_io_ratio) {
set_step(&p->current, p->new_io_ratio);
set_step(&p->fadeout, p->new_io_ratio);
p->fadeout.step_step.all = p->current.step_step.all = 0;
p->new_io_ratio = 0;
}
if (!p->flushing && !p->fade_len && !p->xfade) {
if (p->current.is_d) {
if (INT(p->current.step) && FRAC(p->current.step))
stage_dif = 1, ++max_stage_num;
else if (!INT(p->current.step) && FRAC(p->current.step) < (1u << 31))
stage_dif = -1, --min_stage_num;
} else if (INT(p->current.step) > 1 && FRAC(p->current.step))
stage_dif = 1, ++max_stage_num;
}
if (stage_dif) {
int n = p->current.stage_num + stage_dif;
if (n >= p->num_stages)
--max_stage_num;
else {
p->stage_inc = stage_dif > 0;
p->fadeout = p->current;
p->current.stage_num += stage_dif;
if (!p->stage_inc)
p->switch_stage_num = p->current.stage_num;
if ((p->current.stage_num < 0 && stage_dif < 0) ||
(p->current.stage_num > 0 && stage_dif > 0)) {
stage_t * s = &p->stages[p->current.stage_num];
fifo_clear(&s->fifo);
stage_preload(s);
s->is_fast = false;
do_input_stage(p, p->current.stage_num, stage_dif, p->current.stage_num);
}
if (p->current.stage_num > 0 && stage_dif < 0) {
int idone = INT(p->current.at);
stage_t * s = &p->stages[p->current.stage_num];
fifo_trim_to(&s->fifo, 2 * HALF_FIR_LEN_2 + idone + (POLY_FIR_LEN_D >> 1));
do_input_stage(p, p->current.stage_num, 1, p->current.stage_num);
}
enter_new_stage(p, occupancy0);
shift = -stage_dif;
#define lshift(x,by) (x)=(by)>0?(x)<<(by):(x)>>-(by)
lshift(p->current.at.all, shift);
shift += p->fadeout.is_d - p->current.is_d;
lshift(p->current.step.all, shift);
lshift(p->current.step_step.all, shift);
p->fade_len = AL(fade_coefs) - 1;
lsx_debug("switch from stage %i to %i, x2 from %i to %i", p->fadeout.stage_num, p->current.stage_num, p->fadeout.is_d, p->current.is_d);
}
}
if (p->fade_len) {
float const * vol1 = fade_coefs + p->fade_len;
float const * vol2 = fade_coefs + (iAL(fade_coefs) - 1 - p->fade_len);
int olen2 = (olen = min(olen, p->fade_len >> 1)) << 1;
/* x2 is more fine-grained so may fail to produce a pair of samples
* where x1 would not (the x1 second sample is a zero so is always
* available). So do x2 first, then feed odone to the second one. */
memset(buf, 0, sizeof(*buf) * (size_t)olen2);
if (p->current.is_d && p->fadeout.is_d) {
odone = poly_fir_fade_d(&p->current, vol1,-1, buf, olen2);
odone2 = poly_fir_fade_d(&p->fadeout, vol2, 1, buf, odone);
} else if (p->current.is_d) {
odone = poly_fir_fade_d(&p->current, vol1,-1, buf, olen2);
odone2 = poly_fir_fade_u(&p->fadeout, vol2, 2, buf, odone);
} else {
assert(p->fadeout.is_d);
odone = poly_fir_fade_d(&p->fadeout, vol2, 1, buf, olen2);
odone2 = poly_fir_fade_u(&p->current, vol1,-2, buf, odone);
}
assert(odone == odone2);
(void)odone2;
p->fade_len -= odone;
if (!p->fade_len) {
if (p->stage_inc)
p->switch_stage_num = min_stage_num++;
else
--max_stage_num;
}
half_iir(&p->halfer, &output[odone0], buf, odone >>= 1);
}
else if (p->current.is_d) {
odone = poly_fir_d(&p->current, buf, olen << 1) >> 1;
half_iir(&p->halfer, &output[odone0], buf, odone);
}
else {
odone = poly_fir_u(&p->current, &output[odone0], olen);
if (p->num_stages0)
half_phase(&p->halfer, &output[odone0], odone);
}
odone0 += odone;
if (p->slew_len)
p->slew_len -= odone;
if (odone != olen)
break; /* Need more input. */
} {
int from = max(0, max_stage_num), to = min(0, min_stage_num);
int i, idone = shiftr(INT(p->current.at), from - p->current.stage_num);
INT(p->current.at) -= shiftl(idone, from - p->current.stage_num);
if (p->fade_len)
INT(p->fadeout.at) -= shiftl(idone, from - p->fadeout.stage_num);
for (i = from; i >= to; --i, idone <<= 1)
fifo_read(&p->stages[i].fifo, idone, NULL);
}
fifo_trim_by(&p->output_fifo, olen0 - odone0);
return odone0;
}
}
static float * vr_input(rate_t * p, float const * input, size_t n)
{
return fifo_write(&p->stages[0].fifo, (int)n, input);
}
static float const * vr_output(rate_t * p, float * output, size_t * n)
{
fifo_t * fifo = &p->output_fifo;
if (1 || !p->num_stages0)
return fifo_read(fifo, (int)(*n = min(*n, (size_t)fifo_occupancy(fifo))), output);
else { /* Ignore this complication for now. */
int const IIR_DELAY = 2;
float * ptr = fifo_read_ptr(fifo);
int olen = min((int)*n, max(0, fifo_occupancy(fifo) - IIR_DELAY));
*n = (size_t)olen;
if (output)
memcpy(output, ptr + IIR_DELAY, *n * sizeof(*output));
fifo_read(fifo, olen, NULL);
return ptr + IIR_DELAY;
}
}
static void vr_flush(rate_t * p)
{
if (!p->flushing) {
stage_preload(&p->stages[0]);
++p->flushing;
}
}
static void vr_close(rate_t * p)
{
int i;
fifo_delete(&p->output_fifo);
for (i = -1; i < p->num_stages; ++i) {
stage_t * s = &p->stages[i];
fifo_delete(&s->fifo);
}
free(p->stages - 1);
}
static double vr_delay(rate_t * p)
{
return 100; /* TODO */
(void)p;
}
static void vr_sizes(size_t * shared, size_t * channel)
{
*shared = 0;
*channel = sizeof(rate_t);
}
static char const * vr_create(void * channel, void * shared,double max_io_ratio,
void * q_spec, void * r_spec, double scale)
{
double x = max_io_ratio;
int n;
for (n = 0; x > 1; x *= .5, ++n);
vr_init(channel, max_io_ratio, n, scale);
return 0;
(void)shared, (void)q_spec, (void)r_spec;
}
static char const * vr_id(void)
{
return "single-precision variable-rate";
}
typedef void (* fn_t)(void);
fn_t _soxr_vr32_cb[] = {
(fn_t)vr_input,
(fn_t)vr_process,
(fn_t)vr_output,
(fn_t)vr_flush,
(fn_t)vr_close,
(fn_t)vr_delay,
(fn_t)vr_sizes,
(fn_t)vr_create,
(fn_t)vr_set_io_ratio,
(fn_t)vr_id,
};