ARM/SIMD runtime detection/override; fix cmake/gcc warnings

master
Rob Sykes 2016-03-08 20:17:38 +00:00
parent fa9070cbea
commit b039ef4f60
13 changed files with 134 additions and 59 deletions

View File

@ -1,7 +1,7 @@
# SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
# SoX Resampler Library Copyright (c) 2007-16 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
cmake_minimum_required (VERSION 2.8 FATAL_ERROR)
cmake_minimum_required (VERSION 3.0 FATAL_ERROR)
project (soxr C)
set (DESCRIPTION_SUMMARY "High quality, one-dimensional sample-rate conversion library")
@ -70,7 +70,7 @@ include (TestBigEndian)
check_library_exists (m pow "" NEED_LIBM)
if (NEED_LIBM)
set (CMAKE_REQUIRED_LIBRARIES "m;${CMAKE_REQUIRED_LIBRARIES}")
link_libraries (m)
set (LIBM_LIBRARIES m)
endif ()
if (WITH_OPENMP)
@ -97,13 +97,19 @@ if (WITH_DOUBLE_PRECISION)
set (HAVE_DOUBLE_PRECISION 1)
endif ()
if (WITH_AVFFT OR HAVE_SIMD)
if (WITH_AVFFT)
find_package (LibAVCodec)
if (AVCODEC_FOUND)
include_directories (${AVCODEC_INCLUDE_DIRS})
link_libraries (${AVCODEC_LIBRARIES})
set (HAVE_AVFFT ${WITH_AVFFT})
set (HAVE_AVCODEC 1)
set (HAVE_AVFFT 1)
endif ()
endif ()
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^arm" AND HAVE_SIMD)
find_package (LibAVUtil)
if (AVUTIL_FOUND)
include_directories (${AVUTIL_INCLUDE_DIRS})
set (HAVE_AVUTIL 1)
endif ()
endif ()
@ -117,7 +123,7 @@ test_big_endian (WORDS_BIGENDIAN)
if (CMAKE_COMPILER_IS_GNUCC OR CMAKE_COMPILER_IS_GNUCXX)
set (PROJECT_CXX_FLAGS "-Wconversion -Wall -W -pedantic -Wundef -Wcast-align -Wpointer-arith -Wno-long-long")
set (PROJECT_C_FLAGS "${PROJECT_CXX_FLAGS} -Wnested-externs -Wmissing-prototypes -Wstrict-prototypes")
set (PROJECT_C_FLAGS "${PROJECT_CXX_FLAGS} -std=gnu89 -Wnested-externs -Wmissing-prototypes -Wstrict-prototypes")
if (CMAKE_BUILD_TYPE STREQUAL "Release")
set (CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -s") # strip
endif ()

21
INSTALL
View File

@ -1,4 +1,4 @@
SoX Resampler Library Copyright (c) 2007-13 robs@users.sourceforge.net
SoX Resampler Library Copyright (c) 2007-16 robs@users.sourceforge.net
INSTALLATION GUIDE CONTENTS
@ -6,6 +6,7 @@ INSTALLATION GUIDE CONTENTS
* Build customisation
* Cross-compiling with mingw (linux host)
* Integration with other build systems
* SIMD
@ -42,7 +43,7 @@ STANDARD BUILD
nmake install (on MS-Windows)
or
cd Release; make install (on unix)
cd Release; make install (on unix-like)
4. Configuration:
@ -121,3 +122,19 @@ Autotools-based systems might find it useful to create a file called
(or with other build options as required).
For MS visual studio, see msvc/README
SIMD
A single build of the library can support both SIMD and non-SIMD variants of a
particular CPU, via a run-time selection of which instruction-set to use. The
SOXR_USE_SIMD boolean environment provides manual selection; otherwise,
selection is automatic for x86 CPUs, and can be automatic for ARM CPUs if the
3rd-party library `libavutil' is available when libsoxr is built.
Example #3 can be used to determine the result of the selection on a particular
system. E.g. (on unix-like):
$ ./3-options-input-fn < /dev/null
./3-options-input-fn no error; 0 clips; I/O: no error (single-precision-SIMD)

View File

@ -0,0 +1,23 @@
# SoX Resampler Library Copyright (c) 2007-16 robs@users.sourceforge.net
# Licence for this file: LGPL v2.1 See LICENCE for details.
# - Find AVUTIL
# Find the native installation of this package: includes and libraries.
#
# AVUTIL_INCLUDES - where to find headers for this package.
# AVUTIL_LIBRARIES - List of libraries when using this package.
# AVUTIL_FOUND - True if this package can be found.
if (AVUTIL_INCLUDES)
set (AVUTIL_FIND_QUIETLY TRUE)
endif (AVUTIL_INCLUDES)
find_path (AVUTIL_INCLUDES libavutil/cpu.h)
find_library (AVUTIL_LIBRARIES NAMES avutil)
include (FindPackageHandleStandardArgs)
find_package_handle_standard_args (
AVUTIL DEFAULT_MSG AVUTIL_LIBRARIES AVUTIL_INCLUDES)
mark_as_advanced (AVUTIL_LIBRARIES AVUTIL_INCLUDES)

View File

@ -40,36 +40,45 @@
include (CheckCSourceCompiles)
include (FindPackageHandleStandardArgs)
if (WIN32) # Safety for when mixed lib/app compilers (but performance hit)
set (GCC_WIN32_SIMD_OPTS "-mincoming-stack-boundary=2")
if (CMAKE_SYSTEM_PROCESSOR MATCHES "^arm")
set (SIMD_C_FLAG_CANDIDATES
# Gcc
"-Wno-cast-align -mfpu=neon-vfpv4 -mcpu=cortex-a7"
"-Wno-cast-align -mfpu=neon -mfloat-abi=hard"
"-Wno-cast-align -mfpu=neon -mfloat-abi=softfp"
"-Wno-cast-align -mfpu=neon -mfloat-abi=soft"
)
set (SIMD_C_TEST_SOURCE "
#include <arm_neon.h>
int main() {
float32x4_t a = vdupq_n_f32(0), b = a, c = vaddq_f32(a,b);
return 0;
}
")
else ()
if (WIN32) # Safety for when mixed lib/app compilers (but performance hit)
set (GCC_WIN32_SIMD_OPTS "-mincoming-stack-boundary=2")
endif ()
set (SIMD_C_FLAG_CANDIDATES
# x64
" "
# Microsoft Visual Studio x86
"/arch:SSE /fp:fast -D__SSE__"
# Gcc x86
"-msse -mfpmath=sse ${GCC_WIN32_SIMD_OPTS}"
# Gcc x86 (old versions)
"-msse -mfpmath=sse"
)
set (SIMD_C_TEST_SOURCE "
#include <xmmintrin.h>
int main() {
__m128 a = _mm_setzero_ps(), b = a, c = _mm_add_ps(a,b);
return 0;
}
")
endif ()
set (SIMD_C_FLAG_CANDIDATES
# x64
" "
# Microsoft Visual Studio x86
"/arch:SSE /fp:fast -D__SSE__"
# Gcc x86
"-msse -mfpmath=sse ${GCC_WIN32_SIMD_OPTS}"
# Gcc x86 (old versions)
"-msse -mfpmath=sse"
)
set (SIMD_C_TEST_SOURCE
"
#include <xmmintrin.h>
int main()
{
__m128 a, b;
float vals[4] = {0};
a = _mm_loadu_ps (vals);
b = a;
b = _mm_add_ps (a,b);
_mm_storeu_ps (vals,b);
return 0;
}
")
if (DEFINED SIMD_C_FLAGS)
set (SIMD_C_FLAG_CANDIDATES)
endif ()

View File

@ -19,7 +19,7 @@ if (NOT BUILD_SHARED_LIBS AND OPENMP_FOUND)
endif ()
set (CMAKE_C_FLAGS "${CMAKE_C_FLAGS} ${PROJECT_C_FLAGS}")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${PROJECT_CXX_FLAGS}")
link_libraries (${PROJECT_NAME})
link_libraries (${PROJECT_NAME} ${LIBM_LIBRARIES})
foreach (fe ${SOURCES} ${LSR_SOURCES})
get_filename_component (f ${fe} NAME_WE)

View File

@ -27,7 +27,7 @@ include_directories (${CMAKE_CURRENT_BINARY_DIR})
add_library (tests_lib STATIC util calc_snr)
link_libraries (tests_lib ${PROJECT_NAME}-lsr)
link_libraries (tests_lib ${PROJECT_NAME}-lsr ${LIBM_LIBRARIES})
enable_testing ()

View File

@ -10,7 +10,7 @@
#define HAVE_SINGLE_PRECISION 1
#define HAVE_DOUBLE_PRECISION 1
#define HAVE_AVFFT 0
#define HAVE_AVCODEC 0
#define HAVE_AVUTIL 0
#define HAVE_SIMD 1
#define HAVE_FENV_H 0
#define HAVE_LRINT 0

View File

@ -7,7 +7,7 @@
#cmakedefine01 HAVE_SINGLE_PRECISION
#cmakedefine01 HAVE_DOUBLE_PRECISION
#cmakedefine01 HAVE_AVFFT
#cmakedefine01 HAVE_AVCODEC
#cmakedefine01 HAVE_AVUTIL
#cmakedefine01 HAVE_SIMD
#cmakedefine01 HAVE_FENV_H
#cmakedefine01 HAVE_LRINT

View File

@ -54,6 +54,7 @@ endif ()
add_library (${PROJECT_NAME} ${LIB_TYPE} ${PROJECT_NAME}.c data-io dbesi0 filter fft4g64
${SP_SOURCES} vr32 ${DP_SOURCES} ${SIMD_SOURCES})
target_link_libraries (${PROJECT_NAME} PRIVATE ${AVCODEC_LIBRARIES} ${AVUTIL_LIBRARIES} ${LIBM_LIBRARIES})
set_target_properties (${PROJECT_NAME} PROPERTIES
VERSION "${SO_VERSION}"
SOVERSION ${SO_VERSION_MAJOR}
@ -108,18 +109,22 @@ install (TARGETS ${PROJECT_NAME} ${LSR}
# 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 (UNIX)
set (LIB1 $<TARGET_FILE:${PROJECT_NAME}>)
if (BUILD_SHARED_LIBS)
set (LIB2 ${LIB2}.${LSR_SO_VERSION_MAJOR} ${LIB2}.${LSR_SO_VERSION})
set (LIB1 $<TARGET_SONAME_FILE:${PROJECT_NAME}> ${LIB1})
endif ()
list (APPEND TARGET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${LSR}.h")
list (APPEND TARGET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${PROJECT_NAME}.h")
if (WITH_LSR_BINDINGS)
set (LIB2 $<TARGET_FILE:${LSR}>)
if (BUILD_SHARED_LIBS)
set (LIB2 $<TARGET_SONAME_FILE:${LSR}> ${LIB2})
endif ()
list (APPEND TARGET_HEADERS "${CMAKE_CURRENT_SOURCE_DIR}/${LSR}.h")
endif ()
set (TARGET_LIBS ${LIB1} ${LIB2})
file (GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/libsoxr.src CONTENT
"set(TARGET_LIBS \"${TARGET_LIBS}\")\n")
file (GENERATE OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/libsoxr-dev.src CONTENT
"set(TARGET_HEADERS \"${TARGET_HEADERS}\")\nset(TARGET_PCS \"${TARGET_PCS}\")\n")
endif ()
set (TARGET_LIBS ${LIB1} ${LIB2})
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libsoxr.src.in ${CMAKE_CURRENT_BINARY_DIR}/libsoxr.src)
configure_file (${CMAKE_CURRENT_SOURCE_DIR}/libsoxr-dev.src.in ${CMAKE_CURRENT_BINARY_DIR}/libsoxr-dev.src)

View File

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

View File

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

View File

@ -10,6 +10,10 @@
#include "data-io.h"
#include "internal.h"
#if HAVE_AVUTIL
#include <libavutil/cpu.h>
#endif
char const * soxr_version(void)
@ -73,6 +77,8 @@ struct soxr {
#define TO_3dB(a) ((1.6e-6*a-7.5e-4)*a+.646)
#define LOW_Q_BW0 (1385 / 2048.) /* 0.67625 rounded to be a FP exact. */
soxr_quality_spec_t soxr_quality_spec(unsigned long recipe, unsigned long flags)
{
soxr_quality_spec_t spec, * p = &spec;
@ -190,11 +196,23 @@ static bool cpu_has_simd(void)
mov d, edx
}
return !!(d & 0x06000000);
#elif defined AV_CPU_FLAG_NEON
return !!(av_get_cpu_flags() & AV_CPU_FLAG_NEON);
#endif
return false;
}
static bool should_use_simd(void)
{
char const * e = getenv("SOXR_USE_SIMD");
return e? !!atoi(e) : cpu_has_simd();
}
#endif
extern control_block_t _soxr_rate32s_cb, _soxr_rate32_cb, _soxr_rate64_cb, _soxr_vr32_cb;
@ -248,7 +266,7 @@ soxr_t soxr_create(
memcpy(&p->control_block,
(p->q_spec.flags & SOXR_VR)? &_soxr_vr32_cb :
#if HAVE_SIMD
cpu_has_simd()? &_soxr_rate32s_cb :
should_use_simd()? &_soxr_rate32s_cb :
#endif
&_soxr_rate32_cb, sizeof(p->control_block));
}

View File

@ -2,7 +2,7 @@
# Licence for this file: LGPL v2.1 See LICENCE for details.
add_definitions (${PROJECT_C_FLAGS})
link_libraries (${PROJECT_NAME})
link_libraries (${PROJECT_NAME} ${LIBM_LIBRARIES})
file (GLOB SOURCES ${CMAKE_CURRENT_SOURCE_DIR}/*.c)
foreach (fe ${SOURCES})