Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
BatchDrake committed Apr 11, 2020
2 parents 49af399 + a49ad94 commit 050ad2e
Show file tree
Hide file tree
Showing 20 changed files with 300 additions and 140 deletions.
15 changes: 12 additions & 3 deletions CMakeLists.txt
Expand Up @@ -40,6 +40,8 @@ set(MODEMDIR ${SRCDIR}/modems)
set(SIGUTILS_CONFIG_CFLAGS "-D_SU_SINGLE_PRECISION")
if(VOLK_FOUND)
set(SIGUTILS_CONFIG_CFLAGS "${SIGUTILS_CONFIG_CFLAGS} -DHAVE_VOLK=1")
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_VOLK=1")
link_directories(${VOLK_LIBRARY_DIRS})
endif()

if(NOT CMAKE_BUILD_TYPE)
Expand Down Expand Up @@ -136,6 +138,8 @@ set(SIGUTILS_BLOCK_SOURCES

set(SIGUTILS_CODEC_SOURCES ${CODECDIR}/diff.c)
set(SIGUTILS_MODEM_SOURCES ${MODEMDIR}/qpsk.c)

link_directories(${PROJECT_BINARY_DIR} ${SNDFILE_LIBRARY_DIRS} ${FFTW3_LIBRARY_DIRS})

add_library(
sigutils SHARED
Expand All @@ -152,17 +156,24 @@ target_include_directories(sigutils PRIVATE . util ${SRCDIR})

# Required dependencies
target_include_directories(sigutils SYSTEM PUBLIC ${SNDFILE_INCLUDE_DIRS})
target_link_libraries(sigutils ${SNDFILE_LIBRARIES})

target_include_directories(sigutils SYSTEM PUBLIC ${FFTW3_INCLUDE_DIRS})
target_link_libraries(sigutils ${FFTW3_LIBRARIES})

target_link_libraries(sigutils ${CMAKE_THREAD_LIBS_INIT})
target_link_libraries(sigutils m)

# Optional dependencies
if(VOLK_FOUND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_VOLK=1")
target_include_directories(sigutils SYSTEM PUBLIC ${VOLK_INCLUDE_DIRS})
target_link_libraries(sigutils ${VOLK_LIBRARIES})
endif()

install(
FILES ${SIGUTILS_LIB_HEADERS}
DESTINATION include/sigutils)
DESTINATION include/sigutils/sigutils)

install(
FILES ${SIGUTILS_UTIL_HEADERS}
Expand Down Expand Up @@ -214,7 +225,6 @@ target_include_directories(
PRIVATE . util ${SRCDIR} ${TESTDIR} ${TESTUTILDIR})

# Required dependencies
link_directories(sutest ${PROJECT_BINARY_DIR})
target_link_libraries(sutest sigutils)

target_include_directories(sutest SYSTEM PUBLIC ${SNDFILE_INCLUDE_DIRS})
Expand All @@ -228,7 +238,6 @@ target_link_libraries(sutest m)

# Optional dependencies
if(VOLK_FOUND)
set(CMAKE_C_FLAGS "${CMAKE_C_FLAGS} -DHAVE_VOLK=1")
target_include_directories(sutest SYSTEM PUBLIC ${VOLK_INCLUDE_DIRS})
target_link_libraries(sutest ${VOLK_LIBRARIES})
endif()
2 changes: 1 addition & 1 deletion sigutils.pc.in
Expand Up @@ -7,5 +7,5 @@ Name: sigutils
Description: Digital signal processing utility library
URL: http://github.org/BatchDrake/sigutils
Version: @PROJECT_VERSION@
Cflags: -I${includedir} -I${includedir}/sigutils/util @SU_PC_CFLAGS@
Cflags: -I${includedir}/sigutils -I${includedir}/sigutils/util @SU_PC_CFLAGS@
Libs: -L${libdir} -lsigutils @SU_PC_LIBRARIES@
8 changes: 8 additions & 0 deletions sigutils/block.h
Expand Up @@ -28,6 +28,10 @@
#include "types.h"
#include "property.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

#define SU_BLOCK_STREAM_BUFFER_SIZE 4096

#define SU_BLOCK_PORT_READ_END_OF_STREAM 0
Expand Down Expand Up @@ -240,4 +244,8 @@ SUBOOL su_block_class_register(struct sigutils_block_class *classname);

su_block_class_t *su_block_class_lookup(const char *name);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* _SIGUTILS_BLOCK_H */
7 changes: 7 additions & 0 deletions sigutils/clock.h
Expand Up @@ -24,6 +24,10 @@
#include "types.h"
#include "block.h"

#ifdef __cplusplus
extern "C" {
#endif /* __cplusplus */

struct sigutils_sampler {
SUFLOAT bnor;
SUFLOAT period;
Expand Down Expand Up @@ -282,5 +286,8 @@ SUSDIFF su_clock_detector_read(
SUCOMPLEX *buf,
size_t size);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif /* _SIGUTILS_CLOCK_H */
182 changes: 101 additions & 81 deletions sigutils/detect.c
Expand Up @@ -479,6 +479,7 @@ su_channel_detector_new(const struct sigutils_channel_detector_params *params)
/* Mode-specific allocations */
switch (params->mode) {
case SU_CHANNEL_DETECTOR_MODE_SPECTRUM:
case SU_CHANNEL_DETECTOR_MODE_ORDER_ESTIMATION:
break;

case SU_CHANNEL_DETECTOR_MODE_DISCOVERY:
Expand Down Expand Up @@ -993,115 +994,134 @@ su_channel_detector_apply_window(su_channel_detector_t *detector)
{
unsigned int i;

for (i = 0; i < detector->params.window_size; ++i)
for (i = detector->next_to_window; i < detector->ptr; ++i)
detector->window[i] *= detector->window_func[i];

detector->next_to_window = detector->ptr;
}

SUINLINE SUBOOL
su_channel_detector_feed_internal(su_channel_detector_t *detector, SUCOMPLEX x)
SUBOOL
su_channel_detector_exec_fft(su_channel_detector_t *detector)
{
unsigned int i;
SUFLOAT psd;
SUCOMPLEX diff;
SUFLOAT wsizeinv = 1. / detector->params.window_size;
SUFLOAT ac;

/* In nonlinear diff mode, we store something else in the window */
if (detector->params.mode == SU_CHANNEL_DETECTOR_MODE_NONLINEAR_DIFF) {
diff = (x - detector->prev) * detector->params.samp_rate;
detector->prev = x;
x = diff * SU_C_CONJ(diff);
}
if (detector->fft_issued)
return SU_TRUE;

detector->window[detector->ptr++] = x - detector->dc;
detector->fft_issued = SU_TRUE;

if (detector->ptr == detector->params.window_size) {
/* Window is full, perform FFT */
detector->ptr = 0;
switch (detector->params.mode) {
case SU_CHANNEL_DETECTOR_MODE_SPECTRUM:
/* Spectrum mode only */
++detector->iters;
su_channel_detector_apply_window(detector);
SU_FFTW(_execute(detector->fft_plan));

/* ^^^^^^^^^^^^^^^^^^ end of common part ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ */
switch (detector->params.mode) {
case SU_CHANNEL_DETECTOR_MODE_SPECTRUM:
/* Spectrum mode only */
++detector->iters;
su_channel_detector_apply_window(detector);
SU_FFTW(_execute(detector->fft_plan));
for (i = 0; i < detector->params.window_size; ++i)
detector->spect[i] = wsizeinv * SU_C_REAL(detector->fft[i] * SU_C_CONJ(detector->fft[i]));

for (i = 0; i < detector->params.window_size; ++i)
detector->spect[i] = wsizeinv * SU_C_REAL(detector->fft[i] * SU_C_CONJ(detector->fft[i]));
return SU_TRUE;

return SU_TRUE;
case SU_CHANNEL_DETECTOR_MODE_DISCOVERY:
/*
* Channel detection is based on the analysis of the power spectrum
*/
su_channel_detector_apply_window(detector);

case SU_CHANNEL_DETECTOR_MODE_DISCOVERY:
/*
* Channel detection is based on the analysis of the power spectrum
*/
su_channel_detector_apply_window(detector);
SU_FFTW(_execute(detector->fft_plan));

SU_FFTW(_execute(detector->fft_plan));
detector->dc +=
SU_CHANNEL_DETECTOR_DC_ALPHA *
(detector->fft[0] / detector->params.window_size - detector->dc);

detector->dc +=
SU_CHANNEL_DETECTOR_DC_ALPHA *
(detector->fft[0] / detector->params.window_size - detector->dc);
/* Update DC component */
for (i = 0; i < detector->params.window_size; ++i) {
psd = wsizeinv * SU_C_REAL(detector->fft[i] * SU_C_CONJ(detector->fft[i]));
detector->spect[i] += detector->params.alpha * (psd - detector->spect[i]);
}

/* Update DC component */
for (i = 0; i < detector->params.window_size; ++i) {
psd = wsizeinv * SU_C_REAL(detector->fft[i] * SU_C_CONJ(detector->fft[i]));
detector->spect[i] += detector->params.alpha * (psd - detector->spect[i]);
}
return su_channel_perform_discovery(detector);

return su_channel_perform_discovery(detector);
case SU_CHANNEL_DETECTOR_MODE_AUTOCORRELATION:
/*
* Find repetitive patterns in received signal. We find them
* using the Fast Auto-Correlation Technique, which is relies on
* two FFTs - O(2nlog(n)) - rather than its definition - O(n^2)
*/

case SU_CHANNEL_DETECTOR_MODE_AUTOCORRELATION:
/*
* Find repetitive patterns in received signal. We find them
* using the Fast Auto-Correlation Technique, which is relies on
* two FFTs - O(2nlog(n)) - rather than its definition - O(n^2)
*/
/* Don't apply *any* window function */
SU_FFTW(_execute(detector->fft_plan));
for (i = 0; i < detector->params.window_size; ++i)
detector->fft[i] *= SU_C_CONJ(detector->fft[i]);
SU_FFTW(_execute(detector->fft_plan_rev));

/* Average result */
for (i = 0; i < detector->params.window_size; ++i) {
ac = SU_C_REAL(detector->ifft[i] * SU_C_CONJ(detector->ifft[i]));
detector->acorr[i] +=
detector->params.alpha * (ac - detector->acorr[i]);
}

/* Don't apply *any* window function */
SU_FFTW(_execute(detector->fft_plan));
for (i = 0; i < detector->params.window_size; ++i)
detector->fft[i] *= SU_C_CONJ(detector->fft[i]);
SU_FFTW(_execute(detector->fft_plan_rev));

/* Average result */
for (i = 0; i < detector->params.window_size; ++i) {
ac = SU_C_REAL(detector->ifft[i] * SU_C_CONJ(detector->ifft[i]));
detector->acorr[i] +=
detector->params.alpha * (ac - detector->acorr[i]);
}
/* Update baudrate estimation */
return su_channel_detect_baudrate_from_acorr(detector);

/* Update baudrate estimation */
return su_channel_detect_baudrate_from_acorr(detector);
case SU_CHANNEL_DETECTOR_MODE_NONLINEAR_DIFF:
/*
* Compute FFT of the square of the absolute value of the derivative
* of the signal. This will introduce a train of pulses on every
* non-equal symbol transition.
*/
su_taps_apply_blackmann_harris_complex(
detector->window,
detector->params.window_size);

case SU_CHANNEL_DETECTOR_MODE_NONLINEAR_DIFF:
/*
* Compute FFT of the square of the absolute value of the derivative
* of the signal. This will introduce a train of pulses on every
* non-equal symbol transition.
*/
su_taps_apply_blackmann_harris_complex(
detector->window,
detector->params.window_size);
SU_FFTW(_execute(detector->fft_plan));

SU_FFTW(_execute(detector->fft_plan));
for (i = 0; i < detector->params.window_size; ++i) {
psd = SU_C_REAL(detector->fft[i] * SU_C_CONJ(detector->fft[i]));
psd /= detector->params.window_size;
detector->spect[i] += detector->params.alpha * (psd - detector->spect[i]);
}

for (i = 0; i < detector->params.window_size; ++i) {
psd = SU_C_REAL(detector->fft[i] * SU_C_CONJ(detector->fft[i]));
psd /= detector->params.window_size;
detector->spect[i] += detector->params.alpha * (psd - detector->spect[i]);
}
/* Update baudrate estimation */
return su_channel_detect_baudrate_from_nonlinear_diff(detector);

/* Update baudrate estimation */
return su_channel_detect_baudrate_from_nonlinear_diff(detector);
break;

break;
default:
SU_WARNING("Mode not implemented\n");
return SU_FALSE;
}

default:
SU_WARNING("Mode not implemented\n");
return SU_FALSE;
}
return SU_TRUE;
}

SUINLINE SUBOOL
su_channel_detector_feed_internal(su_channel_detector_t *detector, SUCOMPLEX x)
{
SUCOMPLEX diff;

/* In nonlinear diff mode, we store something else in the window */
if (detector->params.mode == SU_CHANNEL_DETECTOR_MODE_NONLINEAR_DIFF) {
diff = (x - detector->prev) * detector->params.samp_rate;
detector->prev = x;
x = diff * SU_C_CONJ(diff);
}

detector->window[detector->ptr++] = x - detector->dc;
detector->fft_issued = SU_FALSE;

if (detector->ptr == detector->params.window_size) {
/* Window is full, perform FFT */
SU_TRYCATCH(
su_channel_detector_exec_fft(detector),
return SU_FALSE);

detector->ptr = 0;
detector->next_to_window = 0;
}

return SU_TRUE;
Expand Down
17 changes: 17 additions & 0 deletions sigutils/detect.h
Expand Up @@ -27,6 +27,10 @@
#include "softtune.h"

#ifdef __cplusplus
# ifdef __clang__
# pragma clang diagnostic push
# pragma clang diagnostic ignored "-Wreturn-type-c-linkage"
# endif // __clang__
extern "C" {
#endif /* __cplusplus */

Expand Down Expand Up @@ -158,6 +162,8 @@ struct sigutils_channel_detector {
su_softtuner_t tuner;
SUCOMPLEX *tuner_buf;
SUSCOUNT ptr; /* Sample in window */
SUBOOL fft_issued;
SUSCOUNT next_to_window;
unsigned int iters;
unsigned int chan_age;
SU_FFTW(_complex) *window_func;
Expand Down Expand Up @@ -226,6 +232,12 @@ su_channel_detector_get_baud(const su_channel_detector_t *cd)
return cd->baud;
}

SUINLINE SUFLOAT
su_channel_detector_get_window_size(const su_channel_detector_t *cd)
{
return cd->params.window_size;
}

/**************************** Peak detector API *****************************/
SUBOOL su_peak_detector_init(
su_peak_detector_t *pd,
Expand Down Expand Up @@ -253,6 +265,8 @@ SUBOOL su_channel_detector_feed(
su_channel_detector_t *detector,
SUCOMPLEX x);

SUBOOL su_channel_detector_exec_fft(su_channel_detector_t *detector);

SUSCOUNT su_channel_detector_feed_bulk(
su_channel_detector_t *detector,
const SUCOMPLEX *signal,
Expand Down Expand Up @@ -282,6 +296,9 @@ struct sigutils_channel *su_channel_detector_lookup_valid_channel(
SUFLOAT fc);

#ifdef __cplusplus
# ifdef __clang__
# pragma clang diagnostic pop
# endif // __clang__
}
#endif /* __cplusplus */

Expand Down

0 comments on commit 050ad2e

Please sign in to comment.