Merge remote-tracking branch 'origin/master' into code_quality

This commit is contained in:
Charles J. Cliffe 2019-03-14 21:15:07 -04:00
commit 3009da6194
40 changed files with 9369 additions and 12271 deletions

View File

@ -468,6 +468,7 @@ SET (cubicsdr_headers
src/util/GLExt.h
src/util/GLFont.h
src/util/DataTree.h
src/util/SpinMutex.h
src/panel/ScopePanel.h
src/panel/SpectrumPanel.h
src/panel/WaterfallPanel.h

View File

@ -4,7 +4,7 @@
- Add mingw32 and mingw64 compiler to the Msys2 installation.
- Copy config.h, makefile.mingw32, makefile.mingw64 in the liquid-dsp root directory.
- Run a Msys2 Win32 shell (mingw32.exe) and execute 'make -f makefile.mingw32 -j clean' then 'make -f makefile.mingw32 -j' to compile a libliquid.dll 32bit Windows Dll.
- Run a Msys2 Win64 shell (mingw64.exe) and execute 'make -f makefile.mingw64 -j clean' then 'make -f makefile.mingw32 -j' to compile a libliquid.dll 64bit Windows Dll.
- Run a Msys2 Win64 shell (mingw64.exe) and execute 'make -f makefile.mingw64 -j clean' then 'make -f makefile.mingw64 -j' to compile a libliquid.dll 64bit Windows Dll.
This process generates a .dll, .a together with libliquid.def the listing exported functions, and libliquid.lib the import lib matching the dll.

View File

@ -5,9 +5,16 @@
#ifndef __LIQUID_CONFIG_H__
#define __LIQUID_CONFIG_H__
/* Support AVX (Advanced Vector Extensions) instructions */
#define HAVE_AVX 1
/* Define to 1 if you have the <complex.h> header file. */
#define HAVE_COMPLEX_H 1
/* Define to 1 if you have the <emmintrin.h> header file. */
#define HAVE_EMMINTRIN_H 1
/* Define to 1 if you have the <fec.h> header file. */
/* #undef HAVE_FEC_H */
@ -20,6 +27,9 @@
/* Define to 1 if you have the <getopt.h> header file. */
#define HAVE_GETOPT_H 1
/* Define to 1 if you have the <immintrin.h> header file. */
#define HAVE_IMMINTRIN_H 1
/* Define to 1 if you have the <inttypes.h> header file. */
#define HAVE_INTTYPES_H 1
@ -45,57 +55,39 @@
/* Define to 1 if you have the <memory.h> header file. */
#define HAVE_MEMORY_H 1
/* Define to 1 if you have the <mmintrin.h> header file. */ //MMX
/* Define to 1 if you have the <mmintrin.h> header file. */
#define HAVE_MMINTRIN_H 1
/* Define to 1 if you have the <xmmintrin.h> header file. */ //SSE
#define HAVE_XMMINTRIN_H 1
/* Support MMX instructions */
#define HAVE_MMX 1
/* Define to 1 if you have the <emmintrin.h> header file. */ //SSE2
#define HAVE_EMMINTRIN_H 1
/* Define to 1 if you have the <pmmintrin.h> header file. */ //SSE3
/* Define to 1 if you have the <pmmintrin.h> header file. */
#define HAVE_PMMINTRIN_H 1
/* Define to 1 if you have the <smmintrin.h> header file. */ //SSE4.1
//#define HAVE_SMMINTRIN_H 1
/* Define to 1 if you have the <immintrin.h> header file. */ //AVX
//#define HAVE_IMMINTRIN_H 1
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT 4
/* The size of `unsigned int', as computed by sizeof. */
#define SIZEOF_UNSIGNED_INT 4
/* Define to 1 if your system has a GNU libc compatible `realloc' function,
and to 0 otherwise. */
#define HAVE_REALLOC 1
/* Support MMX instructions */
#define HAVE_MMX /**/
/* Define to 1 if you have the <smmintrin.h> header file. */
#define HAVE_SMMINTRIN_H 1
/* Support SSE (Streaming SIMD Extensions) instructions */
#define HAVE_SSE /**/
#define HAVE_SSE 1
/* Support SSE2 (Streaming SIMD Extensions 2) instructions */
#define HAVE_SSE2 /**/
#define HAVE_SSE2 1
/* Support SSE3 (Streaming SIMD Extensions 3) instructions */
#define HAVE_SSE3 /**/
#define HAVE_SSE3 1
/* Support SSE4.1 (Streaming SIMD Extensions 4.1) instructions */
#define HAVE_SSE41 /**/
#define HAVE_SSE41 1
/* Support SSE4.2 (Streaming SIMD Extensions 4.2) instructions */
#define HAVE_SSE42 1
/* Support SSSE3 (Supplemental Streaming SIMD Extensions 3) instructions */
#define HAVE_SSSE3 /**/
/* Support AVX (Advanced Vector Extensions) instructions */
#define HAVE_AVX /**/
#define HAVE_SSSE3 1
/* Define to 1 if you have the <stdint.h> header file. */
#define HAVE_STDINT_H 1
@ -127,8 +119,11 @@
/* Define to 1 if you have the <unistd.h> header file. */
#define HAVE_UNISTD_H 1
/* Define to 1 if you have the <xmmintrin.h> header file. */
#define HAVE_XMMINTRIN_H 1
/* Force internal FFT even if libfftw is available */
/* #undef LIQUID_FFTOVERRIDE */
#define LIQUID_FFTOVERRIDE 1
/* Force overriding of SIMD (use portable C code) */
/* #undef LIQUID_SIMDOVERRIDE */
@ -140,7 +135,7 @@
#define PACKAGE_NAME "liquid-dsp"
/* Define to the full name and version of this package. */
#define PACKAGE_STRING "liquid-dsp 1.3.0"
#define PACKAGE_STRING "liquid-dsp 1.3.1"
/* Define to the one symbol short name of this package. */
#define PACKAGE_TARNAME "liquid-dsp"
@ -149,7 +144,13 @@
#define PACKAGE_URL ""
/* Define to the version of this package. */
#define PACKAGE_VERSION "1.3.0"
#define PACKAGE_VERSION "1.3.1"
/* The size of `int', as computed by sizeof. */
#define SIZEOF_INT 4
/* The size of `unsigned int', as computed by sizeof. */
#define SIZEOF_UNSIGNED_INT 4
/* Define to 1 if you have the ANSI C header files. */
#define STDC_HEADERS 1

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

File diff suppressed because it is too large Load Diff

View File

@ -1,4 +1,4 @@
# Copyright (c) 2007 - 2016 Joseph Gaeddert
# Copyright (c) 2007 - 2018 Joseph Gaeddert
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@ -23,8 +23,7 @@
#
# Targets:
# all : dynamic shared-library object (e.g. libliquid.so)
# install : install the dynamic shared library object and
# header file(s)
# install : install the dynamic shared library object and headers
# uninstall : uninstall the library and header file(s)
# clean : clean all targets (bench, check, examples, etc)
# distclean : removes everything except the originally distributed files
@ -57,9 +56,10 @@ include_dirs := . include
CC := gcc
MV := mv -f
RM := rm -f
SED := /usr/bin/sed
GREP := /usr/bin/grep
SED := /bin/sed
GREP := /bin/grep
AR := ar
LIBTOOL :=
RANLIB := ranlib
# flags
@ -71,7 +71,6 @@ CFLAGS = $(CONFIG_CFLAGS) -Wall -fPIC
LDFLAGS =
#MINGW:
LIBS += -lmsvcrt
ARFLAGS = r
PATHSEP = /
#
@ -446,10 +445,13 @@ filter_includes := \
src/filter/src/iirdecim.c \
src/filter/src/iirfilt.c \
src/filter/src/iirfiltsos.c \
src/filter/src/iirhilb.c \
src/filter/src/iirinterp.c \
src/filter/src/msresamp.c \
src/filter/src/msresamp2.c \
src/filter/src/resamp.c \
src/filter/src/ordfilt.c \
src/filter/src/rresamp.c \
src/filter/src/resamp.fixed.c \
src/filter/src/resamp2.c \
src/filter/src/symsync.c \
@ -489,6 +491,7 @@ filter_autotests := \
src/filter/tests/iirfilt_xxxf_autotest.c \
src/filter/tests/iirfiltsos_rrrf_autotest.c \
src/filter/tests/msresamp_crcf_autotest.c \
src/filter/tests/rresamp_crcf_autotest.c \
src/filter/tests/resamp_crcf_autotest.c \
src/filter/tests/resamp2_crcf_autotest.c \
src/filter/tests/symsync_crcf_autotest.c \
@ -573,6 +576,7 @@ filter_benchmarks := \
src/filter/bench/iirdecim_crcf_benchmark.c \
src/filter/bench/iirfilt_crcf_benchmark.c \
src/filter/bench/iirinterp_crcf_benchmark.c \
src/filter/bench/rresamp_crcf_benchmark.c \
src/filter/bench/resamp_crcf_benchmark.c \
src/filter/bench/resamp2_crcf_benchmark.c \
src/filter/bench/symsync_crcf_benchmark.c \
@ -589,6 +593,8 @@ framing_objects := \
src/framing/src/bsync_crcf.o \
src/framing/src/bsync_cccf.o \
src/framing/src/detector_cccf.o \
src/framing/src/dsssframegen.o \
src/framing/src/dsssframesync.o \
src/framing/src/framedatastats.o \
src/framing/src/framesyncstats.o \
src/framing/src/framegen64.o \
@ -618,6 +624,8 @@ src/framing/src/bsync_rrrf.o : %.o : %.c $(include_headers) src/framing/s
src/framing/src/bsync_crcf.o : %.o : %.c $(include_headers) src/framing/src/bsync.c
src/framing/src/bsync_cccf.o : %.o : %.c $(include_headers) src/framing/src/bsync.c
src/framing/src/detector_cccf.o : %.o : %.c $(include_headers)
src/framing/src/dsssframegen.o : %.o : %.c $(include_headers)
src/framing/src/dsssframesync.o : %.o : %.c $(include_headers)
src/framing/src/framedatastats.o : %.o : %.c $(include_headers)
src/framing/src/framesyncstats.o : %.o : %.c $(include_headers)
src/framing/src/framegen64.o : %.o : %.c $(include_headers)
@ -694,12 +702,14 @@ src/math/src/windows.o : %.o : %.c $(include_headers)
math_autotests := \
src/math/tests/gcd_autotest.c \
src/math/tests/kbd_autotest.c \
src/math/tests/math_autotest.c \
src/math/tests/math_bessel_autotest.c \
src/math/tests/math_gamma_autotest.c \
src/math/tests/math_complex_autotest.c \
src/math/tests/polynomial_autotest.c \
src/math/tests/prime_autotest.c \
math_benchmarks := \
@ -887,15 +897,18 @@ multichannel_benchmarks := \
nco_objects := \
src/nco/src/nco_crcf.o \
src/nco/src/nco.utilities.o \
src/nco/src/synth_crcf.o \
src/nco/src/nco_crcf.o : %.o : %.c $(include_headers) src/nco/src/nco.c
src/nco/src/nco.utilities.o : %.o : %.c $(include_headers)
src/nco/src/synth_crcf.o : %.o : %.c $(include_headers) src/nco/src/synth.c
# autotests
nco_autotests := \
src/nco/tests/nco_crcf_frequency_autotest.c \
src/nco/tests/nco_crcf_mix_autotest.c \
src/nco/tests/nco_crcf_phase_autotest.c \
src/nco/tests/nco_crcf_pll_autotest.c \
src/nco/tests/unwrap_phase_autotest.c \
@ -1023,6 +1036,7 @@ utility_objects := \
src/utility/src/msb_index.o \
src/utility/src/pack_bytes.o \
src/utility/src/shift_array.o \
src/utility/src/utility.o \
$(utility_objects) : %.o : %.c $(include_headers)
@ -1033,9 +1047,9 @@ utility_autotests := \
src/utility/tests/pack_bytes_autotest.c \
src/utility/tests/shift_array_autotest.c \
# benchmarks
utility_benchmarks :=
utility_benchmarks := \
src/utility/bench/byte_utilities_benchmark.c \
#
@ -1155,28 +1169,35 @@ benchmark_sources := \
.PHONY: all
# Shared library
ARCHIVE_LIB = libliquid.a
#MINGW:
SHARED_LIB = libliquid.dll
# liquid library definition
libliquid.a: $(objects)
$(AR) $(ARFLAGS) $@ $^
$(RANLIB) $@
#
# darwin
#
libliquid.ar: $(objects)
${LIBTOOL} -static -o $@ $^
# gcc -dynamiclib -install_name libliquid.dylib -o libliquid.dylib libmodem.a libutility.a
libliquid.dylib: $(objects)
$(CC) -dynamiclib -install_name $@ -o $@ $^ $(LDFLAGS) $(LIBS)
#
# linux, et al
#
libliquid.a: $(objects)
${AR} r $@ $^
${RANLIB} $@
libliquid.so: libliquid.a
$(CC) $(CFLAGS) $(LDFLAGS) -shared -Xlinker -soname=$@ -o $@ -Wl,-whole-archive $^ -Wl,-no-whole-archive $(LIBS)
#MINGW:
libliquid.dll: libliquid.a
$(CC) -shared -Xlinker -soname=$@ -o $@ -Wl,-whole-archive $^ -Wl,-no-whole-archive -Wl,--output-def,libliquid.def -Wl,--out-implib,libliquid.lib $(LIBS)
all: libliquid.a $(SHARED_LIB)
# static archive and library objects
all: ${ARCHIVE_LIB} ${SHARED_LIB}
##
## TARGET : help - print list of targets
@ -1196,7 +1217,7 @@ install: all
@echo ""
mkdir -p $(DESTDIR)$(exec_prefix)$(libdir)
mkdir -p $(DESTDIR)$(prefix)/include/liquid
install -m 644 -p $(SHARED_LIB) libliquid.a $(DESTDIR)$(exec_prefix)$(libdir)
install -m 644 -p ${ARCHIVE_LIB} ${SHARED_LIB} $(DESTDIR)$(exec_prefix)$(libdir)
install -m 644 -p $(addprefix include/,$(headers_install)) $(DESTDIR)$(prefix)/include/liquid
@echo ""
@echo "---------------------------------------------------------"
@ -1219,8 +1240,8 @@ install: all
uninstall:
@echo "uninstalling..."
$(RM) $(addprefix $(DESTDIR)$(prefix)/include/liquid/, $(headers_install))
$(RM) $(DESTDIR)$(exec_prefix)$(libdir)/libliquid.a
$(RM) $(DESTDIR)$(exec_prefix)$(libdir)/$(SHARED_LIB)
$(RM) $(DESTDIR)$(exec_prefix)$(libdir)/${ARCHIVE_LIB}
$(RM) $(DESTDIR)$(exec_prefix)$(libdir)/${SHARED_LIB}
@echo "done."
##
@ -1274,12 +1295,12 @@ $(autotest_prog).o : autotest/autotest.c autotest/autotest.h autotest_include.h
# link the autotest program with the objects
# NOTE: linked libraries must come _after_ the target program
$(autotest_prog): $(autotest_prog).o $(autotest_obj) $(autotest_extra_obj) autotest/autotestlib.o libliquid.a
$(autotest_prog): $(autotest_prog).o $(autotest_obj) $(autotest_extra_obj) autotest/autotestlib.o ${ARCHIVE_LIB}
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS)
# run the autotest program
check: $(autotest_prog)
./$(autotest_prog) -v
./$(autotest_prog) -v -o autotest.json
# let 'make test' be an alias for 'make check'
test: check
@ -1290,6 +1311,7 @@ clean-check:
$(RM) autotest/autotestlib.o
$(RM) $(autotest_obj)
$(RM) $(autotest_extra_obj)
$(RM) autotest.json
##
@ -1326,7 +1348,7 @@ $(bench_prog).o: bench/bench.c benchmark_include.h bench/bench.c
# link the benchmark program with the library objects
# NOTE: linked libraries must come _after_ the target program
$(bench_prog): $(bench_prog).o $(benchmark_obj) $(benchmark_extra_obj) libliquid.a
$(bench_prog): $(bench_prog).o $(benchmark_obj) $(benchmark_extra_obj) ${ARCHIVE_LIB}
$(CC) $(BENCH_CFLAGS) $(BENCH_LDFLAGS) $^ -o $(bench_prog) $(BENCH_LIBS)
# run the benchmark program
@ -1341,7 +1363,7 @@ scripts/benchmark_compare : % : %.c
bench/fftbench.o : %.o : %.c
$(CC) $(BENCH_CPPFLAGS) $(BENCH_CFLAGS) $< -c -o $@
bench/fftbench : % : %.o libliquid.a
bench/fftbench : % : %.o ${ARCHIVE_LIB}
$(CC) $(BENCH_CFLAGS) $(BENCH_LDFLAGS) $^ -o $@ $(BENCH_LIBS)
# clean up the generated files
@ -1383,6 +1405,7 @@ example_programs := \
examples/cpfskmodem_psd_example \
examples/cvsd_example \
examples/detector_cccf_example \
examples/dsssframesync_example \
examples/dotprod_rrrf_example \
examples/dotprod_cccf_example \
examples/eqlms_cccf_block_example \
@ -1405,9 +1428,11 @@ example_programs := \
examples/firdespm_lowpass_example \
examples/firhilb_example \
examples/firhilb_decim_example \
examples/firhilb_filter_example \
examples/firhilb_interp_example \
examples/firpfbch2_crcf_example \
examples/firinterp_crcf_example \
examples/firinterp_firdecim_crcf_example \
examples/firpfbch_crcf_example \
examples/firpfbch_crcf_analysis_example \
examples/firpfbch_crcf_synthesis_example \
@ -1416,6 +1441,7 @@ example_programs := \
examples/framesync64_example \
examples/freqmodem_example \
examples/fskmodem_example \
examples/fskmodem_waterfall_example \
examples/gasearch_example \
examples/gasearch_knapsack_example \
examples/gmskframesync_example \
@ -1432,6 +1458,8 @@ example_programs := \
examples/iirfilt_cccf_example \
examples/iirfilt_crcf_example \
examples/iirfilt_crcf_dcblocker_example \
examples/iirhilb_example \
examples/iirhilb_filter_example \
examples/iirinterp_crcf_example \
examples/kbd_window_example \
examples/lpc_example \
@ -1446,13 +1474,16 @@ example_programs := \
examples/msequence_example \
examples/msourcecf_example \
examples/msresamp_crcf_example \
examples/msresamp_crcf_noise_example \
examples/msresamp2_crcf_example \
examples/nco_crcf_mix_example \
examples/nco_example \
examples/nco_pll_example \
examples/nco_pll_modem_example \
examples/nyquist_filter_example \
examples/ofdmflexframesync_example \
examples/ofdmframesync_example \
examples/ordfilt_rrrf_example \
examples/packetizer_example \
examples/packetizer_soft_example \
examples/pll_example \
@ -1467,7 +1498,9 @@ example_programs := \
examples/quantize_example \
examples/random_histogram_example \
examples/repack_bytes_example \
examples/rresamp_crcf_example \
examples/resamp_crcf_example \
examples/resamp_crcf_noise_example \
examples/resamp2_cccf_example \
examples/resamp2_crcf_example \
examples/resamp2_crcf_decim_example \
@ -1477,7 +1510,6 @@ example_programs := \
examples/scramble_example \
examples/smatrix_example \
examples/spgramcf_example \
examples/spgramcf_waterfall_example \
examples/spgramf_example \
examples/spwaterfallcf_example \
examples/symsync_crcf_example \
@ -1499,7 +1531,7 @@ examples: $(example_programs)
# NOTE: linked libraries must come _after_ the target program
$(example_objects): %.o : %.c
$(example_programs): % : %.o libliquid.a
$(example_programs): % : %.o ${ARCHIVE_LIB}
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS)
# clean examples
@ -1605,6 +1637,7 @@ sandbox_programs = \
sandbox/symsync_eqlms_test \
sandbox/svd_test \
sandbox/thiran_allpass_iir_test \
sandbox/throttle_test \
sandbox/vectorcf_test \
# sandbox/packetizer_persistent_ber_test
@ -1621,7 +1654,7 @@ SANDBOX_LDFLAGS = $(LDFLAGS) -lfftw3f
# NOTE: linked libraries must come _after_ the target program
$(sandbox_objects): %.o : %.c
$(sandbox_programs): % : %.o libliquid.a
$(sandbox_programs): % : %.o ${ARCHIVE_LIB}
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(LIBS)
# clean sandbox
@ -1630,6 +1663,22 @@ clean-sandbox:
$(RM) $(sandbox_programs)
.PHONY: tools
tools_programs = \
tools/msequence_generator \
tools_objects = $(patsubst %,%.o,$(tools_programs))
tools: $(tools_programs)
$(tools_objects): %.o: %.c
$(tools_programs): % : %.o ${ARCHIVE_LIB}
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
clean-tools:
$(RM) tools/*.o
$(RM) $(tools_programs)
##
## TARGET : world - build absolutely everything
##
@ -1666,10 +1715,8 @@ clean-modules:
$(RM) src/vector/src/*.o src/vector/bench/*.o src/vector/tests/*.o
$(RM) src/libliquid.o
clean: clean-modules clean-autoscript clean-check clean-bench clean-examples clean-sandbox
$(RM) $(extra_clean)
$(RM) libliquid.a
$(RM) $(SHARED_LIB)
clean: clean-modules clean-autoscript clean-check clean-bench clean-examples clean-sandbox clean-tools
$(RM) ${ARCHIVE_LIB} ${SHARED_LIB} $(extra_clean)
##
## TARGET : distclean - removes everything except the originally distributed files

View File

@ -1,4 +1,4 @@
# Copyright (c) 2007 - 2016 Joseph Gaeddert
# Copyright (c) 2007 - 2018 Joseph Gaeddert
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
@ -23,8 +23,7 @@
#
# Targets:
# all : dynamic shared-library object (e.g. libliquid.so)
# install : install the dynamic shared library object and
# header file(s)
# install : install the dynamic shared library object and headers
# uninstall : uninstall the library and header file(s)
# clean : clean all targets (bench, check, examples, etc)
# distclean : removes everything except the originally distributed files
@ -57,21 +56,21 @@ include_dirs := . include
CC := gcc
MV := mv -f
RM := rm -f
SED := /usr/bin/sed
GREP := /usr/bin/grep
SED := /bin/sed
GREP := /bin/grep
AR := ar
LIBTOOL :=
RANLIB := ranlib
# flags
INCLUDE_CFLAGS = $(addprefix -I ,$(include_dirs))
#MINGW: optimizations goes here
CONFIG_CFLAGS = -O3 -msse3 -ffast-math -static-libgcc -static-libstdc++
#MINGW: optimizations goes here, use SSSE42 for 64bit
CONFIG_CFLAGS = -O3 -msse4.2 -ffast-math
CPPFLAGS = $(INCLUDE_CFLAGS)
CFLAGS = $(CONFIG_CFLAGS) -Wall -fPIC
LDFLAGS =
#MINGW:
LIBS += -static-libgcc -static-libstdc++
ARFLAGS = r
LIBS += -static-libgcc
PATHSEP = /
#
@ -446,10 +445,13 @@ filter_includes := \
src/filter/src/iirdecim.c \
src/filter/src/iirfilt.c \
src/filter/src/iirfiltsos.c \
src/filter/src/iirhilb.c \
src/filter/src/iirinterp.c \
src/filter/src/msresamp.c \
src/filter/src/msresamp2.c \
src/filter/src/resamp.c \
src/filter/src/ordfilt.c \
src/filter/src/rresamp.c \
src/filter/src/resamp.fixed.c \
src/filter/src/resamp2.c \
src/filter/src/symsync.c \
@ -489,6 +491,7 @@ filter_autotests := \
src/filter/tests/iirfilt_xxxf_autotest.c \
src/filter/tests/iirfiltsos_rrrf_autotest.c \
src/filter/tests/msresamp_crcf_autotest.c \
src/filter/tests/rresamp_crcf_autotest.c \
src/filter/tests/resamp_crcf_autotest.c \
src/filter/tests/resamp2_crcf_autotest.c \
src/filter/tests/symsync_crcf_autotest.c \
@ -573,6 +576,7 @@ filter_benchmarks := \
src/filter/bench/iirdecim_crcf_benchmark.c \
src/filter/bench/iirfilt_crcf_benchmark.c \
src/filter/bench/iirinterp_crcf_benchmark.c \
src/filter/bench/rresamp_crcf_benchmark.c \
src/filter/bench/resamp_crcf_benchmark.c \
src/filter/bench/resamp2_crcf_benchmark.c \
src/filter/bench/symsync_crcf_benchmark.c \
@ -589,6 +593,8 @@ framing_objects := \
src/framing/src/bsync_crcf.o \
src/framing/src/bsync_cccf.o \
src/framing/src/detector_cccf.o \
src/framing/src/dsssframegen.o \
src/framing/src/dsssframesync.o \
src/framing/src/framedatastats.o \
src/framing/src/framesyncstats.o \
src/framing/src/framegen64.o \
@ -618,6 +624,8 @@ src/framing/src/bsync_rrrf.o : %.o : %.c $(include_headers) src/framing/s
src/framing/src/bsync_crcf.o : %.o : %.c $(include_headers) src/framing/src/bsync.c
src/framing/src/bsync_cccf.o : %.o : %.c $(include_headers) src/framing/src/bsync.c
src/framing/src/detector_cccf.o : %.o : %.c $(include_headers)
src/framing/src/dsssframegen.o : %.o : %.c $(include_headers)
src/framing/src/dsssframesync.o : %.o : %.c $(include_headers)
src/framing/src/framedatastats.o : %.o : %.c $(include_headers)
src/framing/src/framesyncstats.o : %.o : %.c $(include_headers)
src/framing/src/framegen64.o : %.o : %.c $(include_headers)
@ -694,12 +702,14 @@ src/math/src/windows.o : %.o : %.c $(include_headers)
math_autotests := \
src/math/tests/gcd_autotest.c \
src/math/tests/kbd_autotest.c \
src/math/tests/math_autotest.c \
src/math/tests/math_bessel_autotest.c \
src/math/tests/math_gamma_autotest.c \
src/math/tests/math_complex_autotest.c \
src/math/tests/polynomial_autotest.c \
src/math/tests/prime_autotest.c \
math_benchmarks := \
@ -887,15 +897,18 @@ multichannel_benchmarks := \
nco_objects := \
src/nco/src/nco_crcf.o \
src/nco/src/nco.utilities.o \
src/nco/src/synth_crcf.o \
src/nco/src/nco_crcf.o : %.o : %.c $(include_headers) src/nco/src/nco.c
src/nco/src/nco.utilities.o : %.o : %.c $(include_headers)
src/nco/src/synth_crcf.o : %.o : %.c $(include_headers) src/nco/src/synth.c
# autotests
nco_autotests := \
src/nco/tests/nco_crcf_frequency_autotest.c \
src/nco/tests/nco_crcf_mix_autotest.c \
src/nco/tests/nco_crcf_phase_autotest.c \
src/nco/tests/nco_crcf_pll_autotest.c \
src/nco/tests/unwrap_phase_autotest.c \
@ -1023,6 +1036,7 @@ utility_objects := \
src/utility/src/msb_index.o \
src/utility/src/pack_bytes.o \
src/utility/src/shift_array.o \
src/utility/src/utility.o \
$(utility_objects) : %.o : %.c $(include_headers)
@ -1033,9 +1047,9 @@ utility_autotests := \
src/utility/tests/pack_bytes_autotest.c \
src/utility/tests/shift_array_autotest.c \
# benchmarks
utility_benchmarks :=
utility_benchmarks := \
src/utility/bench/byte_utilities_benchmark.c \
#
@ -1155,28 +1169,35 @@ benchmark_sources := \
.PHONY: all
# Shared library
ARCHIVE_LIB = libliquid.a
#MINGW:
SHARED_LIB = libliquid.dll
# liquid library definition
libliquid.a: $(objects)
$(AR) $(ARFLAGS) $@ $^
$(RANLIB) $@
#
# darwin
#
libliquid.ar: $(objects)
${LIBTOOL} -static -o $@ $^
# gcc -dynamiclib -install_name libliquid.dylib -o libliquid.dylib libmodem.a libutility.a
libliquid.dylib: $(objects)
$(CC) -dynamiclib -install_name $@ -o $@ $^ $(LDFLAGS) $(LIBS)
#
# linux, et al
#
libliquid.a: $(objects)
${AR} r $@ $^
${RANLIB} $@
libliquid.so: libliquid.a
$(CC) $(CFLAGS) $(LDFLAGS) -shared -Xlinker -soname=$@ -o $@ -Wl,-whole-archive $^ -Wl,-no-whole-archive $(LIBS)
#MINGW:
libliquid.dll: libliquid.a
$(CC) -shared -Xlinker -soname=$@ -o $@ -Wl,-whole-archive $^ -Wl,-no-whole-archive -Wl,--output-def,libliquid.def -Wl,--out-implib,libliquid.lib $(LIBS)
all: libliquid.a $(SHARED_LIB)
# static archive and library objects
all: ${ARCHIVE_LIB} ${SHARED_LIB}
##
## TARGET : help - print list of targets
@ -1196,7 +1217,7 @@ install: all
@echo ""
mkdir -p $(DESTDIR)$(exec_prefix)$(libdir)
mkdir -p $(DESTDIR)$(prefix)/include/liquid
install -m 644 -p $(SHARED_LIB) libliquid.a $(DESTDIR)$(exec_prefix)$(libdir)
install -m 644 -p ${ARCHIVE_LIB} ${SHARED_LIB} $(DESTDIR)$(exec_prefix)$(libdir)
install -m 644 -p $(addprefix include/,$(headers_install)) $(DESTDIR)$(prefix)/include/liquid
@echo ""
@echo "---------------------------------------------------------"
@ -1219,8 +1240,8 @@ install: all
uninstall:
@echo "uninstalling..."
$(RM) $(addprefix $(DESTDIR)$(prefix)/include/liquid/, $(headers_install))
$(RM) $(DESTDIR)$(exec_prefix)$(libdir)/libliquid.a
$(RM) $(DESTDIR)$(exec_prefix)$(libdir)/$(SHARED_LIB)
$(RM) $(DESTDIR)$(exec_prefix)$(libdir)/${ARCHIVE_LIB}
$(RM) $(DESTDIR)$(exec_prefix)$(libdir)/${SHARED_LIB}
@echo "done."
##
@ -1274,12 +1295,12 @@ $(autotest_prog).o : autotest/autotest.c autotest/autotest.h autotest_include.h
# link the autotest program with the objects
# NOTE: linked libraries must come _after_ the target program
$(autotest_prog): $(autotest_prog).o $(autotest_obj) $(autotest_extra_obj) autotest/autotestlib.o libliquid.a
$(autotest_prog): $(autotest_prog).o $(autotest_obj) $(autotest_extra_obj) autotest/autotestlib.o ${ARCHIVE_LIB}
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS)
# run the autotest program
check: $(autotest_prog)
./$(autotest_prog) -v
./$(autotest_prog) -v -o autotest.json
# let 'make test' be an alias for 'make check'
test: check
@ -1290,6 +1311,7 @@ clean-check:
$(RM) autotest/autotestlib.o
$(RM) $(autotest_obj)
$(RM) $(autotest_extra_obj)
$(RM) autotest.json
##
@ -1326,7 +1348,7 @@ $(bench_prog).o: bench/bench.c benchmark_include.h bench/bench.c
# link the benchmark program with the library objects
# NOTE: linked libraries must come _after_ the target program
$(bench_prog): $(bench_prog).o $(benchmark_obj) $(benchmark_extra_obj) libliquid.a
$(bench_prog): $(bench_prog).o $(benchmark_obj) $(benchmark_extra_obj) ${ARCHIVE_LIB}
$(CC) $(BENCH_CFLAGS) $(BENCH_LDFLAGS) $^ -o $(bench_prog) $(BENCH_LIBS)
# run the benchmark program
@ -1341,7 +1363,7 @@ scripts/benchmark_compare : % : %.c
bench/fftbench.o : %.o : %.c
$(CC) $(BENCH_CPPFLAGS) $(BENCH_CFLAGS) $< -c -o $@
bench/fftbench : % : %.o libliquid.a
bench/fftbench : % : %.o ${ARCHIVE_LIB}
$(CC) $(BENCH_CFLAGS) $(BENCH_LDFLAGS) $^ -o $@ $(BENCH_LIBS)
# clean up the generated files
@ -1383,6 +1405,7 @@ example_programs := \
examples/cpfskmodem_psd_example \
examples/cvsd_example \
examples/detector_cccf_example \
examples/dsssframesync_example \
examples/dotprod_rrrf_example \
examples/dotprod_cccf_example \
examples/eqlms_cccf_block_example \
@ -1405,9 +1428,11 @@ example_programs := \
examples/firdespm_lowpass_example \
examples/firhilb_example \
examples/firhilb_decim_example \
examples/firhilb_filter_example \
examples/firhilb_interp_example \
examples/firpfbch2_crcf_example \
examples/firinterp_crcf_example \
examples/firinterp_firdecim_crcf_example \
examples/firpfbch_crcf_example \
examples/firpfbch_crcf_analysis_example \
examples/firpfbch_crcf_synthesis_example \
@ -1416,6 +1441,7 @@ example_programs := \
examples/framesync64_example \
examples/freqmodem_example \
examples/fskmodem_example \
examples/fskmodem_waterfall_example \
examples/gasearch_example \
examples/gasearch_knapsack_example \
examples/gmskframesync_example \
@ -1432,6 +1458,8 @@ example_programs := \
examples/iirfilt_cccf_example \
examples/iirfilt_crcf_example \
examples/iirfilt_crcf_dcblocker_example \
examples/iirhilb_example \
examples/iirhilb_filter_example \
examples/iirinterp_crcf_example \
examples/kbd_window_example \
examples/lpc_example \
@ -1446,13 +1474,16 @@ example_programs := \
examples/msequence_example \
examples/msourcecf_example \
examples/msresamp_crcf_example \
examples/msresamp_crcf_noise_example \
examples/msresamp2_crcf_example \
examples/nco_crcf_mix_example \
examples/nco_example \
examples/nco_pll_example \
examples/nco_pll_modem_example \
examples/nyquist_filter_example \
examples/ofdmflexframesync_example \
examples/ofdmframesync_example \
examples/ordfilt_rrrf_example \
examples/packetizer_example \
examples/packetizer_soft_example \
examples/pll_example \
@ -1467,7 +1498,9 @@ example_programs := \
examples/quantize_example \
examples/random_histogram_example \
examples/repack_bytes_example \
examples/rresamp_crcf_example \
examples/resamp_crcf_example \
examples/resamp_crcf_noise_example \
examples/resamp2_cccf_example \
examples/resamp2_crcf_example \
examples/resamp2_crcf_decim_example \
@ -1477,7 +1510,6 @@ example_programs := \
examples/scramble_example \
examples/smatrix_example \
examples/spgramcf_example \
examples/spgramcf_waterfall_example \
examples/spgramf_example \
examples/spwaterfallcf_example \
examples/symsync_crcf_example \
@ -1499,7 +1531,7 @@ examples: $(example_programs)
# NOTE: linked libraries must come _after_ the target program
$(example_objects): %.o : %.c
$(example_programs): % : %.o libliquid.a
$(example_programs): % : %.o ${ARCHIVE_LIB}
$(CC) $(CFLAGS) $(LDFLAGS) $^ -o $@ $(LIBS)
# clean examples
@ -1605,6 +1637,7 @@ sandbox_programs = \
sandbox/symsync_eqlms_test \
sandbox/svd_test \
sandbox/thiran_allpass_iir_test \
sandbox/throttle_test \
sandbox/vectorcf_test \
# sandbox/packetizer_persistent_ber_test
@ -1621,7 +1654,7 @@ SANDBOX_LDFLAGS = $(LDFLAGS) -lfftw3f
# NOTE: linked libraries must come _after_ the target program
$(sandbox_objects): %.o : %.c
$(sandbox_programs): % : %.o libliquid.a
$(sandbox_programs): % : %.o ${ARCHIVE_LIB}
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS) $(LIBS)
# clean sandbox
@ -1630,6 +1663,22 @@ clean-sandbox:
$(RM) $(sandbox_programs)
.PHONY: tools
tools_programs = \
tools/msequence_generator \
tools_objects = $(patsubst %,%.o,$(tools_programs))
tools: $(tools_programs)
$(tools_objects): %.o: %.c
$(tools_programs): % : %.o ${ARCHIVE_LIB}
$(CC) $(CFLAGS) $^ -o $@ $(LDFLAGS)
clean-tools:
$(RM) tools/*.o
$(RM) $(tools_programs)
##
## TARGET : world - build absolutely everything
##
@ -1666,10 +1715,8 @@ clean-modules:
$(RM) src/vector/src/*.o src/vector/bench/*.o src/vector/tests/*.o
$(RM) src/libliquid.o
clean: clean-modules clean-autoscript clean-check clean-bench clean-examples clean-sandbox
$(RM) $(extra_clean)
$(RM) libliquid.a
$(RM) $(SHARED_LIB)
clean: clean-modules clean-autoscript clean-check clean-bench clean-examples clean-sandbox clean-tools
$(RM) ${ARCHIVE_LIB} ${SHARED_LIB} $(extra_clean)
##
## TARGET : distclean - removes everything except the originally distributed files

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -34,7 +34,7 @@
#include <wx/numformatter.h>
#include <stddef.h>
#ifdef __linux__
#if defined(__linux__) || defined(__FreeBSD__)
#include "CubicSDR.xpm"
#endif
@ -79,7 +79,7 @@ std::vector<std::string> str_explode(const std::string &seperator, const std::st
AppFrame::AppFrame() :
wxFrame(NULL, wxID_ANY, CUBICSDR_TITLE), activeDemodulator(nullptr) {
#ifdef __linux__
#if defined(__linux__) || defined(__FreeBSD__)
SetIcon(wxICON(cubicsdr));
#endif

View File

@ -3,6 +3,10 @@
#pragma once
#if defined(__linux__) || defined(__FreeBSD__)
#include <sys/param.h>
#endif
#define CUBICSDR_TITLE "" CUBICSDR_BUILD_TITLE
#ifndef __BYTE_ORDER
@ -16,7 +20,11 @@
#ifdef __APPLE__
#include <machine/endian.h>
#else
#include <endian.h>
#ifdef __FreeBSD__
#include <sys/endian.h>
#else
#include <endian.h>
#endif
#endif
#endif
#endif
@ -62,4 +70,4 @@ const char filePathSeparator =
//The maximum number of listed sample rates for a device, to be able to handle
//devices returning an insane amount because they have quasi-continuous ranges (UHD...)
#define DEVICE_SAMPLE_RATES_MAX_NB 25
#define DEVICE_SAMPLE_RATES_MAX_NB 25

View File

@ -83,7 +83,7 @@ void DemodLabelDialog::OnChar(wxKeyEvent& event) {
}
else {
#ifdef __linux__
#if defined(__linux__) || defined(__FreeBSD__)
dialogText->OnChar(event);
event.Skip();
#else

View File

@ -218,7 +218,7 @@ void FrequencyDialog::OnChar(wxKeyEvent& event) {
if (allowed.find_first_of(c) != std::string::npos || c == WXK_DELETE || c == WXK_BACK || c == WXK_NUMPAD_DECIMAL
|| (c >= WXK_NUMPAD0 && c <= WXK_NUMPAD9)) {
#ifdef __linux__
#if defined(__linux__) || defined(__FreeBSD__)
dialogText->OnChar(event);
event.Skip();
#else

View File

@ -15,6 +15,7 @@
#include <climits>
#include "ThreadBlockingQueue.h"
#include "Timer.h"
#include "SpinMutex.h"
struct map_string_less : public std::binary_function<std::string,std::string,bool>
{
@ -62,7 +63,7 @@ public:
/// Return a new ReBuffer_ptr usable by the application.
ReBufferPtr getBuffer() {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
// iterate the ReBufferAge list: if the std::shared_ptr count == 1, it means
//it is only referenced in outputBuffers itself, so available for re-use.
@ -131,7 +132,7 @@ public:
/// Purge the cache.
void purge() {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
// since outputBuffers are full std::shared_ptr,
//purging if will effectively loose the local reference,
@ -152,7 +153,7 @@ private:
typedef typename std::deque< ReBufferAge < ReBufferPtr > >::iterator outputBuffersI;
//mutex protecting access to outputBuffers.
std::mutex m_mutex;
SpinMutex m_mutex;
};

View File

@ -504,7 +504,7 @@ DemodulatorInstancePtr DemodulatorMgr::loadInstance(DataNode *node) {
DataNode *demodTypeNode = node->hasAnother("type")?node->getNext("type"):nullptr;
if (demodTypeNode && demodTypeNode->element()->getDataType() == DATA_INT) {
if (demodTypeNode && demodTypeNode->element()->getDataType() == DataElement::DATA_INT) {
int legacyType = *demodTypeNode;
int legacyStereo = node->hasAnother("stereo") ? (int) *node->getNext("stereo") : 0;
switch (legacyType) { // legacy demod ID
@ -526,7 +526,7 @@ DemodulatorInstancePtr DemodulatorMgr::loadInstance(DataNode *node) {
case 16: type = "I/Q"; break;
default: type = "FM"; break;
}
} else if (demodTypeNode && demodTypeNode->element()->getDataType() == DATA_STRING) {
} else if (demodTypeNode && demodTypeNode->element()->getDataType() == DataElement::DATA_STRING) {
demodTypeNode->element()->get(type);
}

View File

@ -39,13 +39,13 @@ void DemodulatorThread::onBindOutput(std::string name, ThreadQueueBasePtr thread
if (name == "AudioVisualOutput") {
//protects because it may be changed at runtime
std::lock_guard < std::mutex > lock(m_mutexAudioVisOutputQueue);
std::lock_guard < SpinMutex > lock(m_mutexAudioVisOutputQueue);
audioVisOutputQueue = std::static_pointer_cast<DemodulatorThreadOutputQueue>(threadQueue);
}
if (name == "AudioSink") {
std::lock_guard < std::mutex > lock(m_mutexAudioVisOutputQueue);
std::lock_guard < SpinMutex > lock(m_mutexAudioVisOutputQueue);
audioSinkOutputQueue = std::static_pointer_cast<AudioThreadInputQueue>(threadQueue);
}
@ -247,7 +247,7 @@ void DemodulatorThread::run() {
//variable, and works with it with now on until the next while-turn.
DemodulatorThreadOutputQueuePtr localAudioVisOutputQueue = nullptr;
{
std::lock_guard < std::mutex > lock(m_mutexAudioVisOutputQueue);
std::lock_guard < SpinMutex > lock(m_mutexAudioVisOutputQueue);
localAudioVisOutputQueue = audioVisOutputQueue;
}
@ -337,7 +337,7 @@ void DemodulatorThread::run() {
// Capture audioSinkOutputQueue state in a local variable
DemodulatorThreadOutputQueuePtr localAudioSinkOutputQueue = nullptr;
{
std::lock_guard < std::mutex > lock(m_mutexAudioVisOutputQueue);
std::lock_guard < SpinMutex > lock(m_mutexAudioVisOutputQueue);
localAudioSinkOutputQueue = audioSinkOutputQueue;
}

View File

@ -10,6 +10,7 @@
#include "DemodDefs.h"
#include "AudioThread.h"
#include "Modem.h"
#include "SpinMutex.h"
#define DEMOD_VIS_SIZE 2048
#define DEMOD_SIGNAL_MIN -30
@ -70,5 +71,5 @@ protected:
DemodulatorThreadOutputQueuePtr audioSinkOutputQueue = nullptr;
//protects the audioVisOutputQueue dynamic binding change at runtime (in DemodulatorMgr)
std::mutex m_mutexAudioVisOutputQueue;
SpinMutex m_mutexAudioVisOutputQueue;
};

View File

@ -135,7 +135,7 @@ protected:
std::lock_guard < std::mutex > busy_lock(busy_update);
//We will try to distribute 'output' among all 'outputs',
//so 'output' will a-priori be shared among all 'outputs'.
for (VisualOutputQueueTypePtr single_output : outputs) {
//'output' can fail to be given to an single_output,
//using a blocking push, with a timeout

View File

@ -101,9 +101,7 @@ bool SDRThread::init() {
int streamMTU = device->getStreamMTU(stream);
mtuElems.store(streamMTU);
std::cout << "Device Stream MTU: " << mtuElems.load() << std::endl << std::flush;
deviceInfo.load()->setStreamArgs(currentStreamArgs);
deviceConfig.load()->setStreamOpts(currentStreamArgs);
@ -130,14 +128,20 @@ bool SDRThread::init() {
} else {
hasHardwareDC.store(false);
}
device->setGainMode(SOAPY_SDR_RX,0,agc_mode.load());
if (device->hasGainMode(SOAPY_SDR_RX, 0)) {
device->setGainMode(SOAPY_SDR_RX, 0, agc_mode.load());
}
numChannels.store(getOptimalChannelCount(sampleRate.load()));
numElems.store(getOptimalElementCount(sampleRate.load(), TARGET_DISPLAY_FPS));
//fallback if mtuElems was wrong.
//fallback if mtuElems was wrong
if (!mtuElems.load()) {
mtuElems.store(numElems.load());
std::cout << "SDRThread::init(): Device Stream MTU is broken, use " << mtuElems.load() << "instead..." << std::endl << std::flush;
} else {
std::cout << "SDRThread::init(): Device Stream set to MTU: " << mtuElems.load() << std::endl << std::flush;
}
overflowBuffer.data.resize(mtuElems.load());
@ -198,8 +202,15 @@ void SDRThread::assureBufferMinSize(SDRThreadIQData * dataOut, size_t minSize) {
// a 'this.numElems' sized batch of samples (SDRThreadIQData) and push it into iqDataOutQueue.
//this batch of samples is built to represent 1 frame / TARGET_DISPLAY_FPS.
int SDRThread::readStream(SDRThreadIQDataQueuePtr iqDataOutQueue) {
int flags;
long long timeNs;
int flags(0);
long long timeNs(0);
// Supply a huge timeout value to neutralize the readStream 'timeout' effect
// we are not interested in, but some modules may effectively use.
//TODO: use something roughly (1 / TARGET_DISPLAY_FPS) seconds * (factor) instead.?
long timeoutUs = (1 << 30);
int n_read = 0;
int nElems = numElems.load();
@ -247,7 +258,7 @@ int SDRThread::readStream(SDRThreadIQDataQueuePtr iqDataOutQueue) {
//Whatever the number of remaining samples needed to reach nElems, we always try to read a mtElems-size chunk,
//from which SoapySDR effectively returns n_stream_read.
int n_stream_read = device->readStream(stream, buffs, mtElems, flags, timeNs);
int n_stream_read = device->readStream(stream, buffs, mtElems, flags, timeNs, timeoutUs);
readStreamCode = n_stream_read;
@ -437,20 +448,31 @@ void SDRThread::updateSettings() {
}
if (rate_changed.load()) {
device->setSampleRate(SOAPY_SDR_RX,0,sampleRate.load());
// TODO: explore bandwidth setting option to see if this is necessary for others
if (device->getDriverKey() == "bladeRF") {
device->setBandwidth(SOAPY_SDR_RX, 0, sampleRate.load());
}
// Fix for LimeSDR-USB not properly handling samplerate changes while device is
// active.
else if (device->getHardwareKey() == "LimeSDR-USB") {
std::cout << "SDRThread::updateSettings(): Force deactivate / activate limeSDR stream" << std::endl << std::flush;
device->deactivateStream(stream);
device->activateStream(stream);
}
sampleRate.store(device->getSampleRate(SOAPY_SDR_RX,0));
numChannels.store(getOptimalChannelCount(sampleRate.load()));
numElems.store(getOptimalElementCount(sampleRate.load(), TARGET_DISPLAY_FPS));
int streamMTU = device->getStreamMTU(stream);
mtuElems.store(streamMTU);
//fallback if mtuElems was wrong
if (!mtuElems.load()) {
mtuElems.store(numElems.load());
std::cout << "SDRThread::updateSettings(): Device Stream MTU is broken, use " << mtuElems.load() << "instead..." << std::endl << std::flush;
} else {
std::cout << "SDRThread::updateSettings(): Device Stream changing to MTU: " << mtuElems.load() << std::endl << std::flush;
}
overflowBuffer.data.resize(mtuElems.load());
@ -484,7 +506,9 @@ void SDRThread::updateSettings() {
// }
if (agc_mode_changed.load()) {
device->setGainMode(SOAPY_SDR_RX, 0, agc_mode.load());
if (device->hasGainMode(SOAPY_SDR_RX, 0)) {
device->setGainMode(SOAPY_SDR_RX, 0, agc_mode.load());
}
agc_mode_changed.store(false);
if (!agc_mode.load()) {
updateGains();

File diff suppressed because it is too large Load Diff

View File

@ -24,8 +24,6 @@
THE SOFTWARE.
*/
#define USE_FASTLZ 0
#include <vector>
#include <map>
#include <set>
@ -35,40 +33,9 @@
#include <iostream>
#include "tinyxml.h"
#if USE_FASTLZ
#include "fastlz.h"
#endif
using namespace std;
/* type defines */
#define DATA_NULL 0
#define DATA_CHAR 1
#define DATA_UCHAR 2
#define DATA_INT 3
#define DATA_UINT 4
#define DATA_LONG 5
#define DATA_ULONG 6
#define DATA_LONGLONG 7
#define DATA_FLOAT 8
#define DATA_DOUBLE 9
#define DATA_LONGDOUBLE 10
#define DATA_STRING 11
#define DATA_STR_VECTOR 12
#define DATA_CHAR_VECTOR 13
#define DATA_UCHAR_VECTOR 14
#define DATA_INT_VECTOR 15
#define DATA_UINT_VECTOR 16
#define DATA_LONG_VECTOR 17
#define DATA_ULONG_VECTOR 18
#define DATA_LONGLONG_VECTOR 19
#define DATA_FLOAT_VECTOR 20
#define DATA_DOUBLE_VECTOR 21
#define DATA_LONGDOUBLE_VECTOR 22
#define DATA_VOID 23
#define DATA_WSTRING 24
/* map comparison function */
struct string_less : public std::binary_function<std::string,std::string,bool>
{
@ -117,109 +84,431 @@ public:
class DataElement
{
private:
int data_type;
size_t data_size;
unsigned int unit_size;
public :
enum DataElementTypeEnum {
DATA_NULL,
DATA_CHAR,
DATA_UCHAR,
DATA_INT,
DATA_UINT,
DATA_LONG,
DATA_ULONG,
DATA_LONGLONG,
DATA_FLOAT,
DATA_DOUBLE,
DATA_STRING,
DATA_STR_VECTOR,
DATA_CHAR_VECTOR,
DATA_UCHAR_VECTOR,
DATA_INT_VECTOR,
DATA_UINT_VECTOR,
DATA_LONG_VECTOR,
DATA_ULONG_VECTOR,
DATA_LONGLONG_VECTOR,
DATA_FLOAT_VECTOR,
DATA_DOUBLE_VECTOR,
DATA_VOID,
DATA_WSTRING
};
typedef vector<unsigned char> DataElementBuffer;
typedef vector< DataElementBuffer > DataElementBufferVector;
private:
DataElementTypeEnum data_type;
// raw buffer holding data_type element in bytes form.
DataElementBuffer data_val;
//keep the vector of types in a spearate vector of DataElementBuffer.
DataElementBufferVector data_val_vector;
//specializations to extract type: (need to be declared/done OUTSIDE of class scope else "Error: explicit specialization is not allowed in the current scope")
//this is apparently fixed in C++17...
// so we need to workaround it with a partial specialization using a fake Dummy parameter.
//if the exact right determineScalarDataType specialization was not used, throw exception at runtime.
template<typename U, typename Dummy = int >
DataElementTypeEnum determineScalarDataType(const U& type_in) { throw DataTypeMismatchException("determineScalarDataType(U) usage with unsupported type !"); }
template< typename Dummy = int >
DataElementTypeEnum determineScalarDataType(const char& type_in) { return DATA_CHAR; }
template< typename Dummy = int >
DataElementTypeEnum determineScalarDataType(const unsigned char& type_in) { return DATA_UCHAR; }
template< typename Dummy = int >
DataElementTypeEnum determineScalarDataType(const int& type_in) { return DATA_INT; }
template< typename Dummy = int >
DataElementTypeEnum determineScalarDataType(const unsigned int& type_in) { return DATA_UINT; }
template< typename Dummy = int >
DataElementTypeEnum determineScalarDataType(const long& type_in) { return DATA_LONG; }
template< typename Dummy = int >
DataElementTypeEnum determineScalarDataType(const unsigned long& type_in) { return DATA_ULONG; }
template< typename Dummy = int >
DataElementTypeEnum determineScalarDataType(const long long& type_in) { return DATA_LONGLONG; }
template< typename Dummy = int >
DataElementTypeEnum determineScalarDataType(const float& type_in) { return DATA_FLOAT; }
template< typename Dummy = int >
DataElementTypeEnum determineScalarDataType(const double& type_in) { return DATA_DOUBLE; }
//vector versions:
//if the exact right determineVectorDataType specialization was not used, throw exception at runtime.
template<typename V, typename Dummy = int >
DataElementTypeEnum determineVectorDataType(const vector<V>& type_in) { throw DataTypeMismatchException("determineVectorDataType(V) usage with unsupported type !"); }
template< typename Dummy = int >
DataElementTypeEnum determineVectorDataType(const vector<char>& type_in) { return DATA_CHAR_VECTOR; }
template< typename Dummy = int >
DataElementTypeEnum determineVectorDataType(const vector<unsigned char>& type_in) { return DATA_UCHAR_VECTOR; }
template< typename Dummy = int >
DataElementTypeEnum determineVectorDataType(const vector<int>& type_in) { return DATA_INT_VECTOR; }
template< typename Dummy = int >
DataElementTypeEnum determineVectorDataType(const vector<unsigned int>& type_in) { return DATA_UINT_VECTOR; }
template< typename Dummy = int >
DataElementTypeEnum determineVectorDataType(const vector<long>& type_in) { return DATA_LONG_VECTOR; }
template< typename Dummy = int >
DataElementTypeEnum determineVectorDataType(const vector<unsigned long>& type_in) { return DATA_ULONG_VECTOR; }
template< typename Dummy = int >
DataElementTypeEnum determineVectorDataType(const vector<long long>& type_in) { return DATA_LONGLONG_VECTOR; }
template< typename Dummy = int >
DataElementTypeEnum determineVectorDataType(const vector<float>& type_in) { return DATA_FLOAT_VECTOR; }
template< typename Dummy = int >
DataElementTypeEnum determineVectorDataType(const vector<double>& type_in) { return DATA_DOUBLE_VECTOR; }
public:
char *data_val;
void data_init(size_t data_size_in);
public:
DataElement();
DataElement(DataElement &cloneFrom);
~DataElement();
int getDataType();
DataElementTypeEnum getDataType();
char *getDataPointer();
size_t getDataSize();
unsigned int getUnitSize();
/* set overloads */
void set(const char &char_in);
void set(const unsigned char &uchar_in);
void set(const int &int_in);
void set(const unsigned int &uint_in);
void set(const long &long_in);
void set(const unsigned long &ulong_in);
void set(const long long &llong_in);
void set(const float &float_in);
void set(const double &double_in);
void set(const long double &ldouble_in);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
//set overloads :
// general templates : for scalars
template<typename T, typename Dummy = int >
void set(const T& scalar_in) {
data_type = determineScalarDataType<T>(scalar_in);
int unit_size = sizeof(T);
//copy in a temporary variable (needed ?)
T local_copy = scalar_in;
unsigned char* local_copy_ptr = reinterpret_cast<unsigned char*>(&local_copy);
data_val.assign(local_copy_ptr, local_copy_ptr + unit_size);
}
// general templates : for vector of scalars
template<typename T, typename Dummy = int >
void set(const vector<T>& scalar_vector_in) {
data_type = determineVectorDataType<T>(scalar_vector_in);
int unit_size = sizeof(T);
data_val_vector.clear();
DataElementBuffer single_buffer;
for (auto single_element : scalar_vector_in) {
//copy in a temporary variable (needed ?)
T local_copy = single_element;
unsigned char* local_copy_ptr = reinterpret_cast<unsigned char*>(&local_copy);
single_buffer.assign(local_copy_ptr, local_copy_ptr + unit_size);
data_val_vector.push_back(single_buffer);
}
}
//template specialization : for string
template< typename Dummy = int >
void set(const string& str_in) {
data_type = DATA_STRING;
data_val.assign(str_in.begin(), str_in.end());
}
//template specialization : for wstring
template< typename Dummy = int >
void set(const wstring& wstr_in) {
data_type = DATA_WSTRING;
//wchar_t is tricky, the terminating zero is actually a (wchar_t)0 !
//wchar_t is typically 16 bits on windows, and 32 bits on Unix, so use sizeof(wchar_t) everywhere.
size_t maxLenBytes = (wstr_in.length() + 1) * sizeof(wchar_t);
//be paranoid, zero the buffer
char *tmp_str = (char *)::calloc(maxLenBytes, sizeof(char));
//if something awful happens, the last sizeof(wchar_t) is at least zero...
::wcstombs(tmp_str, wstr_in.c_str(), maxLenBytes - sizeof(wchar_t));
data_val.assign(tmp_str, tmp_str + maxLenBytes - sizeof(wchar_t));
::free(tmp_str);
}
//template specialization : for vector<string>
template< typename Dummy = int >
void set(const vector<string>& vector_str_in) {
data_type = DATA_STR_VECTOR;
data_val_vector.clear();
DataElementBuffer single_buffer;
for (auto single_element : vector_str_in) {
single_buffer.assign(single_element.begin(), single_element.end());
data_val_vector.push_back(single_buffer);
}
}
///specific versions
void set(const std::set<string> &strset_in);
void set(const char *data_in, long size_in); /* voids, file chunks anyone? */
void set(const char *data_in); /* strings, stops at NULL, returns as string */
void set(const string &str_in);
void set(const wstring &wstr_in);
void set(vector<string> &strvect_in);
void set(std::set<string> &strset_in);
void set(vector<char> &charvect_in);
void set(vector<unsigned char> &ucharvect_in);
void set(vector<int> &intvect_in);
void set(vector<unsigned int> &uintvect_in);
void set(vector<long> &longvect_in);
void set(vector<unsigned long> &ulongvect_in);
void set(vector<long long> &llongvect_in);
void set(vector<float> &floatvect_in);
void set(vector<double> &doublevect_in);
void set(vector<long double> &ldoublevect_in);
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/* get overloads */
void get(char &char_in);
void get(unsigned char &uchar_in);
void get(int &int_in);
void get(unsigned int &uint_in);
void get(long &long_in);
void get(unsigned long &ulong_in);
void get(long long &long_in);
void get(float &float_in);
void get(double &double_in);
void get(long double &ldouble_in);
void get(char **data_in); /* getting a void or string */
void get(string &str_in);
void get(wstring &wstr_in);
void get(std::set<string> &strset_in);
void get(vector<string> &strvect_in);
void get(vector<char> &charvect_in);
void get(vector<unsigned char> &ucharvect_in);
void get(vector<int> &intvect_in);
void get(vector<unsigned int> &uintvect_in);
void get(vector<long> &longvect_in);
void get(vector<unsigned long> &ulongvect_in);
void get(vector<long long> &llongvect_in);
void get(vector<float> &floatvect_in);
void get(vector<double> &doublevect_in);
void get(vector<long double> &ldoublevect_in);
template<typename T, typename Dummy = int >
void get(T& scalar_out) {
if (getDataSize() == 0) {
throw DataException("Cannot get() the scalar, DataElement is empty !");
}
DataElementTypeEnum storageType = getDataType();
//TODO: smarter way with templates ?
if (storageType == DATA_CHAR) {
char* storage_ptr = reinterpret_cast<char*>(&data_val[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_UCHAR) {
unsigned char* storage_ptr = reinterpret_cast<unsigned char*>(&data_val[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_INT) {
int* storage_ptr = reinterpret_cast<int*>(&data_val[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_UINT) {
unsigned int* storage_ptr = reinterpret_cast<unsigned int*>(&data_val[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_LONG) {
long* storage_ptr = reinterpret_cast<long*>(&data_val[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_ULONG) {
unsigned long* storage_ptr = reinterpret_cast<unsigned long*>(&data_val[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_LONGLONG) {
long long* storage_ptr = reinterpret_cast<long long*>(&data_val[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_FLOAT) {
float* storage_ptr = reinterpret_cast<float*>(&data_val[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_DOUBLE) {
double* storage_ptr = reinterpret_cast<double*>(&data_val[0]);
//constructor-like
scalar_out = T(*storage_ptr);
}
}
// general templates : for vector of scalars
template<typename T, typename Dummy = int >
void get(vector<T>& scalar_vector_out) {
scalar_vector_out.clear();
DataElementBuffer single_buffer;
DataElementTypeEnum storageType = getDataType();
for (auto single_storage_element : data_val_vector) {
if (single_storage_element.empty()) {
throw DataException("Cannot get(vector<scalar>) on single element because it is empty!");
}
T scalar_out;
//TODO: smarter way with templates ?
if (storageType == DATA_CHAR_VECTOR) {
char* storage_ptr = reinterpret_cast<char*>(&single_storage_element[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_UCHAR_VECTOR) {
unsigned char* storage_ptr = reinterpret_cast<unsigned char*>(&single_storage_element[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_INT_VECTOR) {
int* storage_ptr = reinterpret_cast<int*>(&single_storage_element[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_UINT_VECTOR) {
unsigned int* storage_ptr = reinterpret_cast<unsigned int*>(&single_storage_element[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_LONG_VECTOR) {
long* storage_ptr = reinterpret_cast<long*>(&single_storage_element[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_ULONG_VECTOR) {
unsigned long* storage_ptr = reinterpret_cast<unsigned long*>(&single_storage_element[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_LONGLONG_VECTOR) {
long long* storage_ptr = reinterpret_cast<long long*>(&single_storage_element[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_FLOAT_VECTOR) {
float* storage_ptr = reinterpret_cast<float*>(&single_storage_element[0]);
//constructor-like
scalar_out = T(*storage_ptr);
} else if (storageType == DATA_DOUBLE_VECTOR) {
double* storage_ptr = reinterpret_cast<double*>(&single_storage_element[0]);
//constructor-like
scalar_out = T(*storage_ptr);
}
scalar_vector_out.push_back(scalar_out);
} //end for.
}
//template specialization : for string or void* returned as string
template< typename Dummy = int >
void get(string& str_out) {
//reset
str_out.clear();
if (data_type == DATA_NULL) {
//it means TinyXML has parsed an empty tag,
//so return an empty string.
return;
}
if (data_type != DATA_STRING && data_type != DATA_VOID) {
throw(DataTypeMismatchException("Type mismatch, neither a STRING nor a VOID*"));
}
for (auto single_char : data_val) {
str_out.push_back((char)single_char);
}
}
//template specialization : for wstring
template< typename Dummy = int >
void get(wstring& wstr_out) {
//reset
wstr_out.clear();
if (data_type == DATA_NULL) {
//it means TinyXML has parsed an empty tag,
//so return an empty string.
return;
}
if (data_type != DATA_WSTRING) {
throw(DataTypeMismatchException("Type mismatch, not a WSTRING"));
}
if (getDataSize() >= sizeof(wchar_t)) {
//data_val is an array of bytes holding wchar_t characters, plus a terminating (wchar_t)0
//wchar_t is typically 16 bits on windows, and 32 bits on Unix, so use sizeof(wchar_t) everywhere.
size_t maxNbWchars = getDataSize() / sizeof(wchar_t);
//be paranoid, zero the buffer
wchar_t *tmp_wstr = (wchar_t *)::calloc(maxNbWchars + 1, sizeof(wchar_t));
//the last wchar_t is actually zero if anything goes wrong...
::mbstowcs(tmp_wstr, (const char*)&data_val[0], maxNbWchars);
wstr_out.assign(tmp_wstr);
::free(tmp_wstr);
}
}
//template specialization : for vector<string>
template< typename Dummy = int >
void get(vector<string>& vector_str_out) {
if (data_type != DATA_STR_VECTOR) {
throw(DataTypeMismatchException("Type mismatch, not a STRING VECTOR"));
}
vector_str_out.clear();
string single_buffer;
for (auto single_element : data_val_vector) {
single_buffer.assign(single_element.begin(), single_element.end());
vector_str_out.push_back(single_buffer);
}
}
//special versions:
void get(DataElementBuffer& data_out); /* getting a void or string */
void get(std::set<string> &strset_out);
/* special get functions, saves creating unnecessary vars */
int getChar() { char i_get; get(i_get); return i_get; };
unsigned int getUChar() { unsigned char i_get; get(i_get); return i_get; };
int getInt() { int i_get; get(i_get); return i_get; };
unsigned int getUInt() { unsigned int i_get; get(i_get); return i_get; };
int getChar() { char i_get; get(i_get); return i_get; };
unsigned int getUChar() { unsigned char i_get; get(i_get); return i_get; };
int getInt() { int i_get; get(i_get); return i_get; };
unsigned int getUInt() { unsigned int i_get; get(i_get); return i_get; };
long getLong() { long l_get; get(l_get); return l_get; };
unsigned long getULong() { unsigned long l_get; get(l_get); return l_get; };
long long getLongLong() { long long l_get; get(l_get); return l_get; };
float getFloat() { float f_get; get(f_get); return f_get; };
double getDouble() { double d_get; get(d_get); return d_get; };
long double getLongDouble() { long double d_get; get(d_get); return d_get; };
unsigned long getULong() { unsigned long l_get; get(l_get); return l_get; };
long long getLongLong() { long long l_get; get(l_get); return l_get; };
float getFloat() { float f_get; get(f_get); return f_get; };
double getDouble() { double d_get; get(d_get); return d_get; };
std::string toString();
/* serialize functions */
long getSerializedSize();
long getSerialized(char **ser_str);
void setSerialized(char *ser_str);
};
///
class DataNode
{
private:
@ -247,8 +536,8 @@ public:
DataNode *getParentNode() { return parentNode; };
void setParentNode(DataNode &parentNode_in) { parentNode = &parentNode_in; };
int numChildren(); /* Number of children */
int numChildren(const char *name_in); /* Number of children named 'name_in' */
size_t numChildren(); /* Number of children */
size_t numChildren(const char *name_in); /* Number of children named 'name_in' */
DataElement *element(); /* DataElement at this node */
@ -270,7 +559,7 @@ public:
void findAll(const char *name_in, vector<DataNode *> &node_list_out);
// operator string () { string s; element()->get(s); return s; }
operator const char * () { if (element()->getDataType() == DATA_STRING) return element()->getDataPointer(); else return NULL; }
operator const char * () { if (element()->getDataType() == DataElement::DATA_STRING) { return element()->getDataPointer(); } else { return NULL; } }
operator char () { char v; element()->get(v); return v; }
operator unsigned char () { unsigned char v; element()->get(v); return v; }
operator int () { int v; element()->get(v); return v; }
@ -280,8 +569,7 @@ public:
operator long long () { long long v; element()->get(v); return v; }
operator float () { float v; element()->get(v); return v; }
operator double () { double v; element()->get(v); return v; }
operator long double () { long double v; element()->get(v); return v; }
operator vector<char> () { vector<char> v; element()->get(v); return v; }
operator vector<unsigned char> () { vector<unsigned char> v; element()->get(v); return v; }
operator vector<int> () { vector<int> v; element()->get(v); return v; }
@ -290,7 +578,6 @@ public:
operator vector<unsigned long> () { vector<unsigned long> v; element()->get(v); return v; }
operator vector<float> () { vector<float> v; element()->get(v); return v; }
operator vector<double> () { vector<double> v; element()->get(v); return v; }
operator vector<long double> () { vector<long double> v; element()->get(v); return v; }
const string &operator= (const string &s) { element()->set(s); return s; }
const wstring &operator= (const wstring &s) { element()->set(s); return s; }
@ -304,7 +591,6 @@ public:
long long operator= (long long i) { element()->set(i); return i; }
float operator= (float i) { element()->set(i); return i; }
double operator= (double i) { element()->set(i); return i; }
long double operator= (long double i) { element()->set(i); return i; }
vector<char> &operator= (vector<char> &v) { element()->set(v); return v; }
vector<unsigned char> &operator= (vector<unsigned char> &v) { element()->set(v); return v; }
@ -314,8 +600,7 @@ public:
vector<unsigned long> &operator= (vector<unsigned long> &v) { element()->set(v); return v; }
vector<float> &operator= (vector<float> &v) { element()->set(v); return v; }
vector<double> &operator= (vector<double> &v) { element()->set(v); return v; }
vector<long double> &operator= (vector<long double> &v) { element()->set(v); return v; }
DataNode *operator[] (const char *name_in) { return getNext(name_in); }
DataNode *operator[] (int idx) { return child(idx); }
@ -353,16 +638,8 @@ public:
void decodeXMLText(DataNode *elem, const char *in_text, DT_FloatingPointPolicy fpp);
void printXML(); /* print datatree as XML */
long getSerializedSize(DataElement &de_node_names, bool debug=false); /* get serialized size + return node names header */
long getSerialized(char **ser_str, bool debug=false);
void setSerialized(char *ser_str, bool debug=false);
bool LoadFromFileXML(const std::string& filename, DT_FloatingPointPolicy fpp=USE_FLOAT);
bool SaveToFileXML(const std::string& filename);
// bool SaveToFile(const std::string& filename);
// bool LoadFromFile(const std::string& filename);
bool SaveToFile(const std::string& filename, bool compress = true, int compress_level = 2);
bool LoadFromFile(const std::string& filename);
};

View File

@ -9,7 +9,7 @@
#include <OpenGL/OpenGL.h>
#endif
#ifdef __linux__
#if defined(__linux__) || defined(__FreeBSD__)
#include <dlfcn.h>
#endif
@ -60,7 +60,7 @@ void initGLExtensions() {
CGLSetParameter (CGLGetCurrentContext(), kCGLCPSwapInterval, &interval);
#endif
#ifdef __linux__
#if defined(__linux__) || defined(__FreeBSD__)
dlopen("libglx.so",RTLD_LAZY);
void (*glxSwapIntervalEXTFunc) (Display *dpy, GLXDrawable drawable, int interval) = 0;

View File

@ -521,7 +521,7 @@ void GLFont::drawString(const std::wstring& str, int pxHeight, float xpos, float
if (cacheable) {
gcCounter++;
std::lock_guard<std::mutex> lock(cache_busy);
std::lock_guard<SpinMutex> lock(cache_busy);
if (gcCounter > GC_DRAW_COUNT_PERIOD) {
@ -793,7 +793,7 @@ void GLFont::doCacheGC() {
void GLFont::clearCache() {
std::lock_guard<std::mutex> lock(cache_busy);
std::lock_guard<SpinMutex> lock(cache_busy);
std::map<std::wstring, GLFontStringCache * >::iterator cache_iter;

View File

@ -13,6 +13,8 @@
#include "wx/filename.h"
#include "wx/stdpaths.h"
#include "SpinMutex.h"
class GLFontStringCache {
public:
GLFontStringCache();
@ -76,9 +78,6 @@ private:
class GLFont {
public:
enum Align {
GLFONT_ALIGN_LEFT, GLFONT_ALIGN_RIGHT, GLFONT_ALIGN_CENTER, GLFONT_ALIGN_TOP, GLFONT_ALIGN_BOTTOM
};
@ -176,7 +175,7 @@ private:
GLuint texId;
int gcCounter;
std::mutex cache_busy;
SpinMutex cache_busy;
public:

View File

@ -30,7 +30,7 @@ void MouseTracker::OnMouseMoved(wxMouseEvent& event) {
if (isMouseDown || isMouseRightDown) {
#ifndef __APPLE__
#ifndef __linux__
#if !defined(__linux__) && !defined(__FreeBSD__)
if (horizDragLock && vertDragLock) {
target->WarpPointer(originMouseX * ClientSize.x, (1.0 - originMouseY) * ClientSize.y);
mouseX = originMouseX;

27
src/util/SpinMutex.h Normal file
View File

@ -0,0 +1,27 @@
// Copyright (c) Charles J. Cliffe
// SPDX-License-Identifier: GPL-2.0+
#pragma once
#include <atomic>
// A non-recursive Mutex implemented as a spin-lock, implementing the Lockable requirement
class SpinMutex {
public:
SpinMutex() = default;
SpinMutex(const SpinMutex&) = delete;
SpinMutex& operator=(const SpinMutex&) = delete;
~SpinMutex() { lock_state.clear(std::memory_order_release); }
void lock() { while (lock_state.test_and_set(std::memory_order_acquire)); }
bool try_lock() {return !lock_state.test_and_set(std::memory_order_acquire); }
void unlock() { lock_state.clear(std::memory_order_release); }
private:
std::atomic_flag lock_state = ATOMIC_FLAG_INIT;
};

View File

@ -11,6 +11,7 @@
#include <condition_variable>
#include <typeinfo>
#include <iostream>
#include "SpinMutex.h"
#define MIN_ITEM_NB (1)
@ -50,7 +51,7 @@ public:
/*! Destroy safe queue. */
~ThreadBlockingQueue() {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
}
/**
@ -59,7 +60,7 @@ public:
* \param[in] nb max of items
*/
void set_max_num_items(unsigned int max_num_items) {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
if (max_num_items > m_max_num_items) {
//Only raise the existing max size, never reduce it
@ -79,7 +80,7 @@ public:
* \return true if an item was pushed into the queue, else a timeout has occured.
*/
bool push(const value_type& item, std::uint64_t timeout = BLOCKING_INFINITE_TIMEOUT,const char* errorMessage = nullptr) {
std::unique_lock < std::mutex > lock(m_mutex);
std::unique_lock < SpinMutex > lock(m_mutex);
if (timeout == BLOCKING_INFINITE_TIMEOUT) {
m_cond_not_full.wait(lock, [this]() // Lambda funct
@ -113,7 +114,7 @@ public:
* \param[in] item An item.
*/
bool try_push(const value_type& item) {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
if (m_queue.size() >= m_max_num_items) {
return false;
@ -131,7 +132,7 @@ public:
* \return true if get an item from the queue, false if no item is received before the timeout.
*/
bool pop(value_type& item, std::uint64_t timeout = BLOCKING_INFINITE_TIMEOUT, const char* errorMessage = nullptr) {
std::unique_lock < std::mutex > lock(m_mutex);
std::unique_lock < SpinMutex > lock(m_mutex);
if (timeout == BLOCKING_INFINITE_TIMEOUT) {
m_cond_not_empty.wait(lock, [this]() // Lambda funct
@ -166,7 +167,7 @@ public:
* \return False is returned if no item is available.
*/
bool try_pop(value_type& item) {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
if (m_queue.empty()) {
return false;
@ -184,7 +185,7 @@ public:
* \return Number of items in the queue.
*/
size_type size() const {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
return m_queue.size();
}
@ -193,7 +194,7 @@ public:
* \return true if queue is empty.
*/
bool empty() const {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
return m_queue.empty();
}
@ -202,7 +203,7 @@ public:
* \return true if queue is full.
*/
bool full() const {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
return (m_queue.size() >= m_max_num_items);
}
@ -210,7 +211,7 @@ public:
* Remove any items in the queue.
*/
void flush() {
std::lock_guard < std::mutex > lock(m_mutex);
std::lock_guard < SpinMutex > lock(m_mutex);
m_queue.clear();
m_cond_not_full.notify_all();
}
@ -221,8 +222,8 @@ private:
std::deque<T> m_queue;
mutable std::mutex m_mutex;
std::condition_variable m_cond_not_empty;
std::condition_variable m_cond_not_full;
mutable SpinMutex m_mutex;
std::condition_variable_any m_cond_not_empty;
std::condition_variable_any m_cond_not_full;
size_t m_max_num_items = MIN_ITEM_NB;
};