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:
@@ -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)
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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;
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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}}},
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
set(TARGET_HEADERS "@TARGET_HEADERS@")
|
||||
set(TARGET_PCS "@TARGET_PCS@")
|
||||
set(TARGET_HEADERS "@TARGET_HEADERS@")
|
||||
set(TARGET_PCS "@TARGET_PCS@")
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -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}
|
||||
|
||||
@@ -1 +1 @@
|
||||
set(TARGET_LIBS "@TARGET_LIBS@")
|
||||
set(TARGET_LIBS "@TARGET_LIBS@")
|
||||
|
||||
@@ -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
@@ -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
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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,
|
||||
};
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -1 +1 @@
|
||||
#include "soxr-lsr.h"
|
||||
#include "soxr-lsr.h"
|
||||
|
||||
@@ -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"
|
||||
|
||||
@@ -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];
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
@@ -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
771
lib-src/libsoxr/src/vr32.c
Normal 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,
|
||||
};
|
||||
Reference in New Issue
Block a user