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) {