diff --git a/CMakeLists.txt b/CMakeLists.txt index 477f415..cdd5f19 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -19,14 +19,8 @@ ######################################################################## # Project setup ######################################################################## -cmake_minimum_required(VERSION 3.10.0) - -# workaround for https://gitlab.kitware.com/cmake/cmake/issues/16967 -if(${CMAKE_VERSION} VERSION_LESS "3.12.0") - project(hsdaoh) -else() - project(hsdaoh C) -endif() +cmake_minimum_required(VERSION 3.12.0) +project(hsdaoh C) #select the release build type by default to get optimization flags if(NOT CMAKE_BUILD_TYPE) @@ -62,14 +56,14 @@ elseif(MSVC14 OR MSVC14) ADD_DEFINITIONS(-D_TIMESPEC_DEFINED) endif() -# Enable SIMD instructions on x86 -if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64|i386|i686") - add_compile_options(-mpclmul -msse4.1) -endif() - ######################################################################## # CRC SIMD specific setup ######################################################################## +# Enable SIMD instructions on x86 +if(CMAKE_SYSTEM_PROCESSOR MATCHES "x86_64|AMD64|amd64|i386|i686") + add_compile_options(-mpclmul -mssse3) +endif() + # Enable crypto extensions on ARM64 if(CMAKE_SYSTEM_PROCESSOR MATCHES "arm64|aarch64") # Check if using GCC or Clang @@ -121,6 +115,8 @@ else() set(LIBFLAC_INCLUDE_DIRS "" CACHE STRING "manual FLAC includepath") endif() +find_package(CRCFAST) + if(MSVC) set(THREADS_PTHREADS_LIBRARY "" CACHE STRING "manual pthread-win32 path") set(THREADS_PTHREADS_INCLUDE_DIR "" CACHE STRING "manual pthread-win32 includepath") diff --git a/cmake/Modules/FindCRCFAST.cmake b/cmake/Modules/FindCRCFAST.cmake new file mode 100644 index 0000000..aeab466 --- /dev/null +++ b/cmake/Modules/FindCRCFAST.cmake @@ -0,0 +1,20 @@ +find_path(CRCFAST_INCLUDE_DIR + NAMES libcrc_fast.h +) + +find_library(CRCFAST_LIBRARY + NAMES crc_fast +) + +include(FindPackageHandleStandardArgs) +find_package_handle_standard_args(CRCFAST + REQUIRED_VARS CRCFAST_LIBRARY CRCFAST_INCLUDE_DIR +) + +if(CRCFAST_FOUND) + add_library(CRCFAST::CRCFAST UNKNOWN IMPORTED) + set_target_properties(CRCFAST::CRCFAST PROPERTIES + IMPORTED_LOCATION "${CRCFAST_LIBRARY}" + INTERFACE_INCLUDE_DIRECTORIES "${CRCFAST_INCLUDE_DIR}" + ) +endif() diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 77d2704..809645f 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -15,11 +15,38 @@ # You should have received a copy of the GNU General Public License # along with this program. If not, see . +set(HSDAOH_COMMON_SOURCES + libhsdaoh.c + format_convert.c + iqconverter_float.c +) + +if(NOT CRCFAST_FOUND) + list(APPEND HSDAOH_COMMON_SOURCES + crcspeed.c + crc16speed.c + crc_simd.c + ) +endif() + ######################################################################## # Setup shared library variant ######################################################################## -add_library(hsdaoh SHARED libhsdaoh.c format_convert.c iqconverter_float.c crcspeed.c crc16speed.c crc_simd.c) -target_link_libraries(hsdaoh ${LIBUSB_LIBRARIES} ${LIBUVC_LIBRARIES} ${THREADS_PTHREADS_LIBRARY}) +add_library(hsdaoh SHARED ${HSDAOH_COMMON_SOURCES}) + +target_link_libraries(hsdaoh + ${LIBUSB_LIBRARIES} + ${LIBUVC_LIBRARIES} + ${THREADS_PTHREADS_LIBRARY} +) + +if(CRCFAST_FOUND) + target_link_libraries(hsdaoh CRCFAST::CRCFAST) + target_compile_definitions(hsdaoh PRIVATE HAVE_CRCFAST=1) +else() + target_compile_definitions(hsdaoh PRIVATE HAVE_CRCFAST=0) +endif() + target_include_directories(hsdaoh PUBLIC $ $ # /include @@ -36,8 +63,22 @@ generate_export_header(hsdaoh) ######################################################################## # Setup static library variant ######################################################################## -add_library(hsdaoh_static STATIC libhsdaoh.c format_convert.c iqconverter_float.c) -target_link_libraries(hsdaoh m ${LIBUSB_LIBRARIES} ${LIBUVC_LIBRARIES} ${THREADS_PTHREADS_LIBRARY}) +add_library(hsdaoh_static STATIC ${HSDAOH_COMMON_SOURCES}) + +target_link_libraries(hsdaoh_static + m + ${LIBUSB_LIBRARIES} + ${LIBUVC_LIBRARIES} + ${THREADS_PTHREADS_LIBRARY} +) + +if(CRCFAST_FOUND) + target_link_libraries(hsdaoh_static CRCFAST::CRCFAST) + target_compile_definitions(hsdaoh_static PRIVATE HAVE_CRCFAST=1) +else() + target_compile_definitions(hsdaoh_static PRIVATE HAVE_CRCFAST=0) +endif() + target_include_directories(hsdaoh_static PUBLIC $ $ # /include diff --git a/src/libhsdaoh.c b/src/libhsdaoh.c index 2cbae0c..5d36e80 100644 --- a/src/libhsdaoh.c +++ b/src/libhsdaoh.c @@ -41,14 +41,19 @@ #include #include +#if HAVE_CRCFAST +#include +#else +#include +#include +#endif + #include #include #include #include #include -#include -#include #define DEFAULT_BUFFERS 96 @@ -494,8 +499,10 @@ int hsdaoh_open(hsdaoh_dev_t **out_dev, uint32_t index) dev->cnv_f1 = iqconverter_float_create(HB_KERNEL_FLOAT, HB_KERNEL_FLOAT_LEN); dev->cnv_f2 = iqconverter_float_create(HB_KERNEL_FLOAT, HB_KERNEL_FLOAT_LEN); +#if HAVE_CRCFAST == 0 crc16speed_init(); crc16_simd_init(); +#endif found: *out_dev = dev; @@ -692,6 +699,15 @@ inline int hsdaoh_check_idle_cnt(hsdaoh_dev_t *dev, uint16_t *buf, size_t length return idle_counter_errors; } +inline uint16_t crc16(uint8_t *buf, unsigned int len) +{ +#if HAVE_CRCFAST + return (uint16_t)crc_fast_checksum(Crc16Ibm3740, (const char *)buf, len); +#else + return crc16_simd(0xffff, buf, len); +#endif +} + /* Extract the metadata stored in the upper 4 bits of the last word of each line */ inline void hsdaoh_extract_metadata(uint8_t *data, metadata_t *metadata, unsigned int width) { @@ -775,7 +791,7 @@ void hsdaoh_process_frame(hsdaoh_dev_t *dev, uint8_t *data, int size) frame_errors++; dev->last_crc[1] = dev->last_crc[0]; - dev->last_crc[0] = crc16_simd(0xffff, line_dat, dev->width * sizeof(uint16_t)); + dev->last_crc[0] = crc16(line_dat, dev->width * sizeof(uint16_t)); } if ((payload_len > 0) && dev->stream_synced) {