diff --git a/CMakeLists.txt b/CMakeLists.txt index 8077584..4042126 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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) @@ -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 @@ -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} @@ -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}) @@ -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() diff --git a/sigutils.pc.in b/sigutils.pc.in index e0dd760..cf1bf0e 100644 --- a/sigutils.pc.in +++ b/sigutils.pc.in @@ -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@ diff --git a/sigutils/block.h b/sigutils/block.h index b5521de..749c339 100644 --- a/sigutils/block.h +++ b/sigutils/block.h @@ -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 @@ -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 */ diff --git a/sigutils/clock.h b/sigutils/clock.h index f2683c8..8e22605 100644 --- a/sigutils/clock.h +++ b/sigutils/clock.h @@ -24,6 +24,10 @@ #include "types.h" #include "block.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + struct sigutils_sampler { SUFLOAT bnor; SUFLOAT period; @@ -282,5 +286,8 @@ SUSDIFF su_clock_detector_read( SUCOMPLEX *buf, size_t size); +#ifdef __cplusplus +} +#endif /* __cplusplus */ #endif /* _SIGUTILS_CLOCK_H */ diff --git a/sigutils/detect.c b/sigutils/detect.c index 9ee1db5..730dc12 100644 --- a/sigutils/detect.c +++ b/sigutils/detect.c @@ -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: @@ -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; diff --git a/sigutils/detect.h b/sigutils/detect.h index 72ba927..a979e19 100644 --- a/sigutils/detect.h +++ b/sigutils/detect.h @@ -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 */ @@ -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; @@ -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, @@ -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, @@ -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 */ diff --git a/sigutils/iir.h b/sigutils/iir.h index d519633..6a3b390 100644 --- a/sigutils/iir.h +++ b/sigutils/iir.h @@ -26,6 +26,14 @@ #define SU_FLOAT_GUARD INFINITY +#ifdef __cplusplus +# ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wreturn-type-c-linkage" +# endif // __clang__ +extern "C" { +#endif /* __cplusplus */ + /* TODO: Builtin filters */ struct sigutils_iir_filt { unsigned int x_size; @@ -106,4 +114,11 @@ SUBOOL su_iir_brickwall_bp_init(su_iir_filt_t *filt, SUSCOUNT n, SUFLOAT bw, SUF /* Destroy filter */ void su_iir_filt_finalize(su_iir_filt_t *filt); +#ifdef __cplusplus +# ifdef __clang__ +# pragma clang diagnostic pop +# endif // __clang__ +} +#endif /* __cplusplus */ + #endif diff --git a/sigutils/modem.c b/sigutils/modem.c index 67df53c..f44cd5f 100644 --- a/sigutils/modem.c +++ b/sigutils/modem.c @@ -198,6 +198,9 @@ __su_modem_set_state_property_from_modem_property( case SU_PROPERTY_TYPE_INTEGER: *state_prop->int_ptr = prop->as_int; break; + + default: + return SU_FALSE; } return SU_TRUE; @@ -364,7 +367,7 @@ su_modem_property_unmarshall( value_size = su_modem_property_get_value_marshalled_size(type); if (ptr + value_size > buffer_size) goto corrupted; - value = (const char *) &as_bytes[ptr]; + value = (const uint8_t *) &as_bytes[ptr]; ptr += value_size; /* All required data is available, initialize property */ diff --git a/sigutils/modem.h b/sigutils/modem.h index 288312f..5e66fcf 100644 --- a/sigutils/modem.h +++ b/sigutils/modem.h @@ -25,6 +25,14 @@ #include "types.h" #include "block.h" +#ifdef __cplusplus +# ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wreturn-type-c-linkage" +# endif // __clang__ +extern "C" { +#endif /* __cplusplus */ + typedef struct sigutils_modem_class su_modem_class_t; struct sigutils_modem_property { @@ -175,4 +183,11 @@ void su_modem_set_signal(su_modem_t *modem, SUFLOAT signal); void su_modem_destroy(su_modem_t *modem); +#ifdef __cplusplus +# ifdef __clang__ +# pragma clang diagnostic pop +# endif // __clang__ +} +#endif /* __cplusplus */ + #endif /* _SIGUTILS_MODEM_H */ diff --git a/sigutils/ncqo.h b/sigutils/ncqo.h index df47b3c..8f8b8cf 100644 --- a/sigutils/ncqo.h +++ b/sigutils/ncqo.h @@ -24,6 +24,15 @@ #include "types.h" #include "sampling.h" +#ifdef __cplusplus +# ifdef __clang__ +# pragma clang diagnostic push +# pragma clang diagnostic ignored "-Wreturn-type-c-linkage" +# endif // __clang__ +extern "C" { +#endif /* __cplusplus */ + + #define SU_NCQO_USE_PRECALC_BUFFER #ifdef SU_NCQO_USE_PRECALC_BUFFER # define SU_NCQO_PRECALC_BUFFER_LEN 1024 @@ -90,7 +99,13 @@ __su_ncqo_step(su_ncqo_t *ncqo) # define SU_VOLK_CALL_STRIDE_BITS 5 # define SU_VOLK_CALL_STRIDE (1 << SU_VOLK_CALL_STRIDE_BITS) # define SU_VOLK_CALL_STRIDE_MASK (SU_VOLK_CALL_STRIDE - 1) +# ifdef __cplusplus +} +# endif /* __cplusplus */ # include +# ifdef __cplusplus +extern "C" { +# endif /* __cplusplus */ #endif #ifdef SU_NCQO_USE_PRECALC_BUFFER @@ -236,4 +251,11 @@ void su_ncqo_inc_freq(su_ncqo_t *ncqo, SUFLOAT delta); /* Get current frequency (normalized freq) */ SUFLOAT su_ncqo_get_freq(const su_ncqo_t *ncqo); +#ifdef __cplusplus +# ifdef __clang__ +# pragma clang diagnostic pop +# endif // __clang__ +} +#endif /* __cplusplus */ + #endif /* _SIGUTILS_NCQO_H */ diff --git a/sigutils/property.h b/sigutils/property.h index 9ff34e9..200006e 100644 --- a/sigutils/property.h +++ b/sigutils/property.h @@ -25,6 +25,10 @@ #include "types.h" +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + enum sigutils_property_type { SU_PROPERTY_TYPE_ANY, SU_PROPERTY_TYPE_BOOL, @@ -86,4 +90,8 @@ su_property_t *__su_property_set_assert_property( void su_property_set_finalize(su_property_set_t *set); +#ifdef __cplusplus +} +#endif /* __cplusplus */ + #endif /* _SIGUTILS_PROPERTY_H */ diff --git a/sigutils/specttuner.c b/sigutils/specttuner.c index 49efc99..86967c9 100644 --- a/sigutils/specttuner.c +++ b/sigutils/specttuner.c @@ -151,6 +151,11 @@ su_specttuner_set_channel_freq( channel->params.f0 = f0; channel->center = 2 * SU_ROUND(f0 / (4 * PI) * window_size); + if (channel->center < 0) + channel->center = 0; + if (channel->center >= window_size) + channel->center = window_size - 2; + if (channel->params.precise) { off = channel->center * (2 * PI) / (SUFLOAT) window_size - f0; off *= channel->decimation; @@ -164,21 +169,26 @@ su_specttuner_set_channel_bandwidth( su_specttuner_channel_t *channel, SUFLOAT bw) { - SUFLOAT actual_bw; SUFLOAT k; unsigned int min_size; unsigned int width; unsigned int window_size = st->params.window_size; - actual_bw = bw * channel->params.guard; + if (bw > 2 * PI) + bw = 2 * PI; - SU_TRYCATCH(actual_bw > 0 && actual_bw < 2 * PI, return SU_FALSE); + /* + * Don't respect guard bands. They are just a hint for the user + * to give her some margin. + */ - k = 1. / (2 * PI / actual_bw); - min_size = SU_CEIL(k * window_size); + k = 1. / (2 * PI / bw); + width = SU_CEIL(k * window_size); - width = SU_CEIL(min_size / channel->params.guard); + /* Accounts for rounding errors */ + if (width > window_size) + width = window_size; SU_TRYCATCH(width <= channel->size, return SU_FALSE); SU_TRYCATCH(width > 1, return SU_FALSE); @@ -203,47 +213,69 @@ su_specttuner_channel_new( unsigned int min_size; SUFLOAT actual_bw; SUFLOAT off; - + SUFLOAT corrbw; + SUBOOL full_spectrum = SU_FALSE; SU_TRYCATCH(params->guard >= 1, goto fail); - SU_TRYCATCH(params->bw > 0 && params->bw < 2 * PI, goto fail); + SU_TRYCATCH(params->bw > 0, goto fail); SU_TRYCATCH(params->f0 >= 0 && params->f0 < 2 * PI, goto fail); + corrbw = params->bw; + + if (corrbw > 2 * PI) + corrbw = 2 * PI; + SU_TRYCATCH(new = calloc(1, sizeof(su_specttuner_channel_t)), goto fail); - actual_bw = params->bw * params->guard; + actual_bw = corrbw * params->guard; - SU_TRYCATCH(actual_bw > 0 && actual_bw < 2 * PI, goto fail); + if (actual_bw >= 2 * PI) { + actual_bw = 2 * PI; + full_spectrum = SU_TRUE; + } new->params = *params; new->index = -1; - /* Tentative configuration */ - new->k = 1. / (2 * PI / actual_bw); - /* - * XXX: THERE IS SOMETHING HERE I COULD NOT FULLY UNDERSTAND - * - * For some reason, if we do not pick an even FFT bin for frequency - * centering, AM components will show up at the decimator output. This - * is probably related to some symmetry condition not being met - * - * TODO: Look into this ASAP - */ - new->center = 2 * SU_ROUND(params->f0 / (4 * PI) * window_size); - min_size = SU_CEIL(new->k * window_size); + if (!full_spectrum) { + /* Tentative configuration */ + new->k = 1. / (2 * PI / actual_bw); + + /* + * XXX: THERE IS SOMETHING HERE I COULD NOT FULLY UNDERSTAND + * + * For some reason, if we do not pick an even FFT bin for frequency + * centering, AM components will show up at the decimator output. This + * is probably related to some symmetry condition not being met + * + * TODO: Look into this ASAP + */ + new->center = 2 * SU_ROUND(params->f0 / (4 * PI) * window_size); + min_size = SU_CEIL(new->k * window_size); - /* Find the nearest power of 2 than can hold all these samples */ - while (n < min_size) - n <<= 1; + /* Find the nearest power of 2 than can hold all these samples */ + while (n < min_size) + n <<= 1; - new->size = n; + new->size = n; + + new->width = SU_CEIL(min_size / params->guard); + new->halfw = new->width >> 1; + } else { + new->center = SU_ROUND(params->f0 / (2 * PI) * window_size); + new->size = window_size; + new->width = SU_CEIL(window_size * 2 * PI / actual_bw); + if (new->width > window_size) + new->width = window_size; + new->halfw = new->width >> 1; + } /* Adjust configuration to new size */ new->decimation = window_size / new->size; new->k = 1. / (new->decimation * new->size); /* - * High precision mode: initialize local oscilator to compensate + * High precision mode: initialize local oscillator to compensate * for rounding errors introduced by bin index calculation */ if (params->precise) { @@ -255,9 +287,6 @@ su_specttuner_channel_new( new->halfsz = new->size >> 1; new->offset = new->size >> 2; - new->width = SU_CEIL(min_size / params->guard); - new->halfw = new->width >> 1; - new->gain = SU_SQRT(1.f / new->size); SU_TRYCATCH(new->width > 0, goto fail); diff --git a/sigutils/taps.h b/sigutils/taps.h index 0d92185..79c1e19 100644 --- a/sigutils/taps.h +++ b/sigutils/taps.h @@ -21,6 +21,10 @@ #ifndef _SIGUTILS_TAPS_H #define _SIGUTILS_TAPS_H +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + #define SU_HAMMING_ALPHA 0.54 #define SU_MAMMING_BETA (1 - SU_HAMMING_ALPHA) @@ -62,5 +66,8 @@ void su_taps_brickwall_lp_init(SUFLOAT *h, SUFLOAT fc, SUSCOUNT size); void su_taps_brickwall_bp_init(SUFLOAT *h, SUFLOAT bw, SUFLOAT if_nor, SUSCOUNT size); +#ifdef __cplusplus +} +#endif /* __cplusplus */ #endif /* _SIGUTILS_TAPS_H */ diff --git a/sigutils/types.h b/sigutils/types.h index a1db9de..d0e5fb8 100644 --- a/sigutils/types.h +++ b/sigutils/types.h @@ -48,13 +48,13 @@ # define SU_C_SGN(x) SUCOMPLEX(SU_SGN(SU_C_REAL(x)), SU_SGN(SU_C_IMAG(x))) #else # define SUCOMPLEX _Complex SUFLOAT -# define SU_C_REAL(c) creal(c) -# define SU_C_IMAG(c) cimag(c) -# define SU_C_ABS SU_ADDSFX(cabs) -# define SU_C_ARG SU_ADDSFX(carg) -# define SU_C_EXP SU_ADDSFX(cexp) -# define SU_C_CONJ SU_ADDSFX(conj) -# define SU_C_SGN(x) (SU_SGN(SU_C_REAL(x)) + I * SU_SGN(SU_C_IMAG(x))) +# define SU_C_REAL(c) (SU_ADDSFX(creal)(c)) +# define SU_C_IMAG(c) (SU_ADDSFX(cimag)(c)) +# define SU_C_ABS SU_ADDSFX(cabs) +# define SU_C_ARG SU_ADDSFX(carg) +# define SU_C_EXP SU_ADDSFX(cexp) +# define SU_C_CONJ SU_ADDSFX(conj) +# define SU_C_SGN(x) (SU_SGN(SU_C_REAL(x)) + I * SU_SGN(SU_C_IMAG(x))) #endif #ifdef _SU_SINGLE_PRECISION diff --git a/src/main.c b/src/main.c index 6de33a4..9c0a366 100644 --- a/src/main.c +++ b/src/main.c @@ -140,8 +140,8 @@ main (int argc, char *argv[], char *envp[]) exit(EXIT_SUCCESS); case 's': - if (sscanf(optarg, "%u", ¶ms.buffer_size) < 0) { - fprintf(stderr, "%s: invalid buffer size `%s'\n", optarg); + if (sscanf(optarg, "%lu", ¶ms.buffer_size) < 0) { + fprintf(stderr, "%s: invalid buffer size `%s'\n", argv[0], optarg); help(argv[0]); exit(EXIT_SUCCESS); } @@ -149,7 +149,7 @@ main (int argc, char *argv[], char *envp[]) case 'r': if (sscanf(optarg, "%lu", ¶ms.fs) < 0) { - fprintf(stderr, "%s: invalid sampling rate `%s'\n", optarg); + fprintf(stderr, "%s: invalid sampling rate `%s'\n", argv[0], optarg); help(argv[0]); exit(EXIT_SUCCESS); } diff --git a/src/tests/costas.c b/src/tests/costas.c index 2341c20..045b3e3 100644 --- a/src/tests/costas.c +++ b/src/tests/costas.c @@ -291,9 +291,9 @@ su_test_costas_qpsk_decision(SUCOMPLEX x) } SUINLINE void -su_swap(char *a, char *b) +su_swap(unsigned char *a, unsigned char *b) { - char tmp; + unsigned char tmp; tmp = *a; *a = *b; diff --git a/testutil/common.c b/testutil/common.c index 7a57455..8348486 100644 --- a/testutil/common.c +++ b/testutil/common.c @@ -236,7 +236,7 @@ su_test_complex_buffer_dump_matlab( goto fail; } - if (fprintf(fp, "\n];\n", arrname) < 0) + if (fprintf(fp, "\n];\n") < 0) goto fail; fclose(fp); @@ -275,7 +275,7 @@ su_test_buffer_dump_matlab( goto fail; } - if (fprintf(fp, "\n];\n", arrname) < 0) + if (fprintf(fp, "\n];\n") < 0) goto fail; fclose(fp); diff --git a/testutil/poolhelper.c b/testutil/poolhelper.c index 53daa46..0dea502 100644 --- a/testutil/poolhelper.c +++ b/testutil/poolhelper.c @@ -121,7 +121,7 @@ su_sigbuf_pool_dump_matlab(const su_sigbuf_pool_t *pool) SU_SYSCALL_ASSERT( fprintf( fp, - "%% %s: %s buffer, %d elements\n", + "%% %s: %s buffer, %lu elements\n", this->name, this->is_complex ? "complex" : "float", this->size)); diff --git a/util/util.c b/util/util.c index 9d2b837..68dc875 100644 --- a/util/util.c +++ b/util/util.c @@ -191,7 +191,7 @@ xalloc_die (void) /* Para manipular arrays de punteros */ int -ptr_list_append_check (void ***list, int *count, void *new) +ptr_list_append_check (void ***list, unsigned int *count, void *new) { int i; void **reallocd_list; @@ -217,13 +217,13 @@ ptr_list_append_check (void ***list, int *count, void *new) } void -ptr_list_append (void ***list, int *count, void *new) +ptr_list_append (void ***list, unsigned int *count, void *new) { (void) ptr_list_append_check (list, count, new); } int -ptr_list_remove_first (void ***list, int *count, void *ptr) +ptr_list_remove_first (void ***list, unsigned int *count, void *ptr) { int i; int found; diff --git a/util/util.h b/util/util.h index e2de13d..a5b7efb 100644 --- a/util/util.h +++ b/util/util.h @@ -79,11 +79,11 @@ #define PTR_LIST_APPEND(name, ptr) \ ptr_list_append ((void ***) &JOIN (name, _list), \ - &JOIN (name, _count), ptr) + &JOIN (name, _count), ptr) #define PTR_LIST_APPEND_CHECK(name, ptr) \ ptr_list_append_check ((void ***) &JOIN (name, _list), \ - &JOIN (name, _count), ptr) + &JOIN (name, _count), ptr) #define PTR_LIST_REMOVE(name, ptr) \ ptr_list_remove_first ((void ***) &JOIN (name, _list), \ @@ -125,9 +125,9 @@ char *vstrbuild (const char *fmt, va_list ap); char *strbuild (const char *fmt, ...); char *str_append_char (char* source, char c); char *fread_line (FILE *fp); -void ptr_list_append (void ***, int *, void *); -int ptr_list_append_check (void ***, int *, void *); -int ptr_list_remove_first (void ***, int *, void *); +void ptr_list_append (void ***, unsigned int *, void *); +int ptr_list_append_check (void ***, unsigned int *, void *); +int ptr_list_remove_first (void ***, unsigned int *, void *); int ptr_list_remove_all (void ***, int *, void *); void errno_save (void);