diff --git a/libs/spandsp/.update b/libs/spandsp/.update index f493a4799a..1e1ab309d6 100644 --- a/libs/spandsp/.update +++ b/libs/spandsp/.update @@ -1 +1 @@ -Tue Sep 30 23:53:44 EDT 2008 +Tue Sep 30 23:55:26 EDT 2008 diff --git a/libs/spandsp/config-h.in b/libs/spandsp/config-h.in index 0732e147fd..8f84f4277c 100644 --- a/libs/spandsp/config-h.in +++ b/libs/spandsp/config-h.in @@ -257,6 +257,30 @@ /* Enable fixed point processing, where possible, instead of floating point */ #undef SPANDSP_USE_FIXED_POINT +/* Use the MMX instruction set (i386 and x86_64 only). */ +#undef SPANDSP_USE_MMX + +/* Use the SSE instruction set (i386 and x86_64 only). */ +#undef SPANDSP_USE_SSE + +/* Use the SSE2 instruction set (i386 and x86_64 only). */ +#undef SPANDSP_USE_SSE2 + +/* Use the SSE3 instruction set (i386 and x86_64 only). */ +#undef SPANDSP_USE_SSE3 + +/* Use the SSE4A instruction set (i386 and x86_64 only). */ +#undef SPANDSP_USE_SSE4A + +/* Use the SSE4.1 instruction set (i386 and x86_64 only). */ +#undef SPANDSP_USE_SSE4_1 + +/* Use the SSE4.2 instruction set (i386 and x86_64 only). */ +#undef SPANDSP_USE_SSE4_2 + +/* Use the SSE5 instruction set (i386 and x86_64 only). */ +#undef SPANDSP_USE_SSE5 + /* Define to 1 if you have the ANSI C header files. */ #undef STDC_HEADERS diff --git a/libs/spandsp/configure.ac b/libs/spandsp/configure.ac index 6665f8a4f0..fe453dbaf9 100644 --- a/libs/spandsp/configure.ac +++ b/libs/spandsp/configure.ac @@ -16,7 +16,7 @@ # License along with this program; if not, write to the Free Software # Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. # -# $Id: configure.ac,v 1.57 2008/09/12 14:41:55 steveu Exp $ +# $Id: configure.ac,v 1.59 2008/09/16 15:21:52 steveu Exp $ # @start 1 @@ -121,6 +121,13 @@ AC_ARG_ENABLE(tests, [ --enable-tests Build the test programs]) AC_ARG_ENABLE(test_data, [ --enable-test-data Build TIFF test files for some ITU test images]) AC_ARG_ENABLE(mmx, [ --enable-mmx Enable MMX support]) AC_ARG_ENABLE(sse, [ --enable-sse Enable SSE support]) +AC_ARG_ENABLE(sse2, [ --enable-sse2 Enable SSE2 support]) +AC_ARG_ENABLE(sse3, [ --enable-sse3 Enable SSE3 support]) +AC_ARG_ENABLE(sse3, [ --enable-sse3 Enable SSE3 support]) +AC_ARG_ENABLE(sse4_1, [ --enable-sse4-1 Enable SSE4.1 support]) +AC_ARG_ENABLE(sse4_2, [ --enable-sse4-2 Enable SSE4.2 support]) +AC_ARG_ENABLE(sse4a, [ --enable-sse4a Enable SSE4A support]) +AC_ARG_ENABLE(sse5, [ --enable-sse5 Enable SSE5 support]) AC_ARG_ENABLE(fixed_point, [ --enable-fixed-point Enable fixed point support]) AC_FUNC_ERROR_AT_LINE @@ -285,6 +292,24 @@ fi case "${ax_cv_c_compiler_vendor}" in gnu) COMP_VENDOR_CFLAGS="-std=gnu99 -ffast-math -Wall -Wunused-variable -Wwrite-strings -Wstrict-prototypes -Wmissing-prototypes" + if test "$enable_sse5" = "yes" ; then + COMP_VENDOR_CFLAGS="-msse5 $COMP_VENDOR_CFLAGS" + fi + if test "$enable_sse4a" = "yes" ; then + COMP_VENDOR_CFLAGS="-msse4a $COMP_VENDOR_CFLAGS" + fi + if test "$enable_sse4_2" = "yes" ; then + COMP_VENDOR_CFLAGS="-msse42 $COMP_VENDOR_CFLAGS" + fi + if test "$enable_sse4_1" = "yes" ; then + COMP_VENDOR_CFLAGS="-msse41 $COMP_VENDOR_CFLAGS" + fi + if test "$enable_sse3" = "yes" ; then + COMP_VENDOR_CFLAGS="-msse3 $COMP_VENDOR_CFLAGS" + fi + if test "$enable_sse2" = "yes" ; then + COMP_VENDOR_CFLAGS="-msse2 $COMP_VENDOR_CFLAGS" + fi if test "$enable_sse" = "yes" ; then COMP_VENDOR_CFLAGS="-msse $COMP_VENDOR_CFLAGS" fi @@ -302,6 +327,12 @@ gnu) ;; sun) COMP_VENDOR_CFLAGS="-xc99=all -mt -xCC -errwarn=%all -xvpara" + if test "$enable_sse3" = "yes" ; then + COMP_VENDOR_CFLAGS="-native -fast $COMP_VENDOR_CFLAGS" + fi + if test "$enable_sse2" = "yes" ; then + COMP_VENDOR_CFLAGS="-native -fast $COMP_VENDOR_CFLAGS" + fi if test "$enable_sse" = "yes" ; then COMP_VENDOR_CFLAGS="-native -fast $COMP_VENDOR_CFLAGS" fi @@ -323,6 +354,12 @@ AM_CONDITIONAL([COND_TESTS], [test "$enable_tests" = yes]) AM_CONDITIONAL([COND_TESTDATA], [test "$enable_test_data" = yes]) AM_CONDITIONAL([COND_MMX], [test "$enable_mmx" = yes]) AM_CONDITIONAL([COND_SSE], [test "$enable_sse" = yes]) +AM_CONDITIONAL([COND_SSE2], [test "$enable_sse2" = yes]) +AM_CONDITIONAL([COND_SSE3], [test "$enable_sse3" = yes]) +AM_CONDITIONAL([COND_SSE4_1], [test "$enable_sse4_1" = yes]) +AM_CONDITIONAL([COND_SSE4_2], [test "$enable_sse4_2" = yes]) +AM_CONDITIONAL([COND_SSE4A], [test "$enable_sse4a" = yes]) +AM_CONDITIONAL([COND_SSE5], [test "$enable_sse5" = yes]) if test "$enable_fixed_point" = "yes" ; then AC_DEFINE([SPANDSP_USE_FIXED_POINT], [1], [Enable fixed point processing, where possible, instead of floating point]) SPANDSP_USE_FIXED_POINT="#define SPANDSP_USE_FIXED_POINT 1" @@ -336,6 +373,58 @@ AX_MISALIGNED_ACCESS_FAILS([$host], [AC_DEFINE([SPANDSP_MISALIGNED_ACCESS_FAILS], [1], [Do not expect a misaligned memory access to work correctly]) SPANDSP_MISALIGNED_ACCESS_FAILS="#define SPANDSP_MISALIGNED_ACCESS_FAILS 1"], [SPANDSP_MISALIGNED_ACCESS_FAILS="#undef SPANDSP_MISALIGNED_ACCESS_FAILS"]) +if test "$enable_mmx" = "yes" ; then + AC_DEFINE([SPANDSP_USE_MMX], [1], [Use the MMX instruction set (i386 and x86_64 only).]) +fi +if test "$enable_sse" = "yes" ; then + AC_DEFINE([SPANDSP_USE_MMX], [1], [Use the MMX instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE], [1], [Use the SSE instruction set (i386 and x86_64 only).]) +fi +if test "$enable_sse2" = "yes" ; then + AC_DEFINE([SPANDSP_USE_MMX], [1], [Use the MMX instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE], [1], [Use the SSE instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE2], [1], [Use the SSE2 instruction set (i386 and x86_64 only).]) +fi +if test "$enable_sse3" = "yes" ; then + AC_DEFINE([SPANDSP_USE_MMX], [1], [Use the MMX instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE], [1], [Use the SSE instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE2], [1], [Use the SSE2 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE3], [1], [Use the SSE3 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE4_1], [1], [Use the SSE4.1 instruction set (i386 and x86_64 only).]) +fi +if test "$enable_sse4_1" = "yes" ; then + AC_DEFINE([SPANDSP_USE_MMX], [1], [Use the MMX instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE], [1], [Use the SSE instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE2], [1], [Use the SSE2 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE3], [1], [Use the SSE3 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE4_1], [1], [Use the SSE4.1 instruction set (i386 and x86_64 only).]) +fi +if test "$enable_sse4_2" = "yes" ; then + AC_DEFINE([SPANDSP_USE_MMX], [1], [Use the MMX instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE], [1], [Use the SSE instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE2], [1], [Use the SSE2 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE3], [1], [Use the SSE3 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE4_1], [1], [Use the SSE4.1 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE4_2], [1], [Use the SSE4.2 instruction set (i386 and x86_64 only).]) +fi +if test "$enable_sse4a" = "yes" ; then + AC_DEFINE([SPANDSP_USE_MMX], [1], [Use the MMX instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE], [1], [Use the SSE instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE2], [1], [Use the SSE2 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE3], [1], [Use the SSE3 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE4_1], [1], [Use the SSE4.1 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE4_2], [1], [Use the SSE4.2 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE4A], [1], [Use the SSE4A instruction set (i386 and x86_64 only).]) +fi +if test "$enable_sse5" = "yes" ; then + AC_DEFINE([SPANDSP_USE_MMX], [1], [Use the MMX instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE], [1], [Use the SSE instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE2], [1], [Use the SSE2 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE3], [1], [Use the SSE3 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE4_1], [1], [Use the SSE4.1 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE4_2], [1], [Use the SSE4.2 instruction set (i386 and x86_64 only).]) + AC_DEFINE([SPANDSP_USE_SSE5], [1], [Use the SSE5 instruction set (i386 and x86_64 only).]) +fi AC_SUBST(CC_FOR_BUILD) AC_SUBST(CPPFLAGS_FOR_BUILD) diff --git a/libs/spandsp/src/spandsp/at_interpreter.h b/libs/spandsp/src/spandsp/at_interpreter.h index be141b0fb2..f47e2677df 100644 --- a/libs/spandsp/src/spandsp/at_interpreter.h +++ b/libs/spandsp/src/spandsp/at_interpreter.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: at_interpreter.h,v 1.18 2008/06/11 17:52:30 steveu Exp $ + * $Id: at_interpreter.h,v 1.19 2008/09/16 12:45:50 steveu Exp $ */ /*! \file */ @@ -204,6 +204,7 @@ struct at_state_s int rings_indicated; int do_hangup; int silent_dial; + int command_dial; int ok_is_pending; int dte_is_waiting; /*! \brief TRUE if a carrier is presnt. Otherwise FALSE. */ diff --git a/libs/spandsp/src/spandsp/v17rx.h b/libs/spandsp/src/spandsp/v17rx.h index c36de7ff28..d7fb9cc5f5 100644 --- a/libs/spandsp/src/spandsp/v17rx.h +++ b/libs/spandsp/src/spandsp/v17rx.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: v17rx.h,v 1.53 2008/09/08 12:54:32 steveu Exp $ + * $Id: v17rx.h,v 1.54 2008/09/16 13:02:05 steveu Exp $ */ /*! \file */ @@ -290,10 +290,17 @@ typedef struct int32_t carrier_phase_rate; /*! \brief The carrier update rate saved for reuse when using short training. */ int32_t carrier_phase_rate_save; +#if defined(SPANDSP_USE_FIXED_POINTx) /*! \brief The proportional part of the carrier tracking filter. */ float carrier_track_p; /*! \brief The integral part of the carrier tracking filter. */ float carrier_track_i; +#else + /*! \brief The proportional part of the carrier tracking filter. */ + float carrier_track_p; + /*! \brief The integral part of the carrier tracking filter. */ + float carrier_track_i; +#endif /*! \brief A power meter, to measure the HPF'ed signal power in the channel. */ power_meter_t power; @@ -301,10 +308,6 @@ typedef struct int32_t carrier_on_power; /*! \brief The power meter level at which carrier off is declared. */ int32_t carrier_off_power; - /*! \brief The scaling factor accessed by the AGC algorithm. */ - float agc_scaling; - /*! \brief The previous value of agc_scaling, needed to reuse old training. */ - float agc_scaling_save; /*! \brief Current read offset into the equalizer buffer. */ int eq_step; @@ -317,6 +320,11 @@ typedef struct int baud_half; #if defined(SPANDSP_USE_FIXED_POINTx) + /*! \brief The scaling factor accessed by the AGC algorithm. */ + float agc_scaling; + /*! \brief The previous value of agc_scaling, needed to reuse old training. */ + float agc_scaling_save; + /*! \brief The current delta factor for updating the equalizer coefficients. */ float eq_delta; /*! \brief The adaptive equalizer coefficients. */ @@ -335,6 +343,11 @@ typedef struct /*! Baud phase for symbol sync. */ int32_t baud_phase; #else + /*! \brief The scaling factor accessed by the AGC algorithm. */ + float agc_scaling; + /*! \brief The previous value of agc_scaling, needed to reuse old training. */ + float agc_scaling_save; + /*! \brief The current delta factor for updating the equalizer coefficients. */ float eq_delta; /*! \brief The adaptive equalizer coefficients. */ diff --git a/libs/spandsp/src/spandsp/v27ter_rx.h b/libs/spandsp/src/spandsp/v27ter_rx.h index 0a516396be..cc6be878b1 100644 --- a/libs/spandsp/src/spandsp/v27ter_rx.h +++ b/libs/spandsp/src/spandsp/v27ter_rx.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: v27ter_rx.h,v 1.49 2008/09/13 14:59:31 steveu Exp $ + * $Id: v27ter_rx.h,v 1.51 2008/09/16 14:12:23 steveu Exp $ */ /*! \file */ @@ -100,10 +100,12 @@ typedef struct /*! \brief A counter for the number of consecutive bits of repeating pattern through the scrambler. */ int scrambler_pattern_count; - /*! \brief The section of the training data we are currently in. */ - int training_stage; /*! \brief The current step in the table of BC constellation positions. */ int training_bc; + /*! \brief TRUE if the previous trained values are to be reused. */ + int old_train; + /*! \brief The section of the training data we are currently in. */ + int training_stage; /*! \brief A count of how far through the current training step we are. */ int training_count; /*! \brief A measure of how much mismatch there is between the real constellation, @@ -119,8 +121,10 @@ typedef struct int low_samples; /*! \brief A highest magnitude sample seen. */ int16_t high_sample; - /*! \brief TRUE if the previous trained values are to be reused. */ - int old_train; + + /*! \brief The position of the current symbol in the constellation, used for + differential decoding. */ + int constellation_state; /*! \brief The current phase of the carrier (i.e. the DDS parameter). */ uint32_t carrier_phase; @@ -147,11 +151,7 @@ typedef struct /*! \brief The power meter level at which carrier off is declared. */ int32_t carrier_off_power; - /*! \brief The position of the current symbol in the constellation, used for - differential decoding. */ - int constellation_state; - - /*! \brief Current offset into the equalizer buffer. */ + /*! \brief Current read offset into the equalizer buffer. */ int eq_step; /*! \brief Current write offset into the equalizer buffer. */ int eq_put_step; @@ -161,20 +161,20 @@ typedef struct /*! \brief The current half of the baud. */ int baud_half; -#if defined(SPANDSP_USE_FIXED_POINTx) +#if defined(SPANDSP_USE_FIXED_POINT) /*! \brief The scaling factor accessed by the AGC algorithm. */ - float agc_scaling; + int16_t agc_scaling; /*! \brief The previous value of agc_scaling, needed to reuse old training. */ - float agc_scaling_save; + int16_t agc_scaling_save; /*! \brief The current delta factor for updating the equalizer coefficients. */ float eq_delta; /*! \brief The adaptive equalizer coefficients. */ - complexi16_t eq_coeff[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN]; + /*complexi16_t*/ complexf_t eq_coeff[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN]; /*! \brief A saved set of adaptive equalizer coefficients for use after restarts. */ - complexi16_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN]; + /*complexi16_t*/ complexf_t eq_coeff_save[V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN]; /*! \brief The equalizer signal buffer. */ - complexi16_t eq_buf[V27TER_EQUALIZER_MASK + 1]; + /*complexi16_t*/ complexf_t eq_buf[V27TER_EQUALIZER_MASK + 1]; #else /*! \brief The scaling factor accessed by the AGC algorithm. */ float agc_scaling; diff --git a/libs/spandsp/src/spandsp/v29rx.h b/libs/spandsp/src/spandsp/v29rx.h index ab8bbe4207..20671542b6 100644 --- a/libs/spandsp/src/spandsp/v29rx.h +++ b/libs/spandsp/src/spandsp/v29rx.h @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: v29rx.h,v 1.60 2008/09/13 14:10:31 steveu Exp $ + * $Id: v29rx.h,v 1.62 2008/09/16 14:12:23 steveu Exp $ */ /*! \file */ @@ -168,10 +168,12 @@ typedef struct unsigned int scramble_reg; /*! \brief The register for the training scrambler. */ uint8_t training_scramble_reg; - /*! \brief The section of the training data we are currently in. */ - int training_stage; /*! \brief The current step in the table of CD constellation positions. */ int training_cd; + /*! \brief TRUE if the previous trained values are to be reused. */ + int old_train; + /*! \brief The section of the training data we are currently in. */ + int training_stage; /*! \brief A count of how far through the current training step we are. */ int training_count; /*! \brief A measure of how much mismatch there is between the real constellation, @@ -187,8 +189,10 @@ typedef struct int low_samples; /*! \brief A highest magnitude sample seen. */ int16_t high_sample; - /*! \brief TRUE if the previous trained values are to be reused. */ - int old_train; + + /*! \brief The position of the current symbol in the constellation, used for + differential decoding. */ + int constellation_state; /*! \brief The current phase of the carrier (i.e. the DDS parameter). */ uint32_t carrier_phase; @@ -215,11 +219,7 @@ typedef struct /*! \brief The power meter level at which carrier off is declared. */ int32_t carrier_off_power; - /*! \brief The position of the current symbol in the constellation, used for - differential decoding. */ - int constellation_state; - - /*! \brief Current offset into the equalizer buffer. */ + /*! \brief Current read offset into the equalizer buffer. */ int eq_step; /*! \brief Current write offset into the equalizer buffer. */ int eq_put_step; @@ -231,9 +231,9 @@ typedef struct #if defined(SPANDSP_USE_FIXED_POINT) /*! \brief The scaling factor accessed by the AGC algorithm. */ - int32_t agc_scaling; + int16_t agc_scaling; /*! \brief The previous value of agc_scaling, needed to reuse old training. */ - int32_t agc_scaling_save; + int16_t agc_scaling_save; /*! \brief The current delta factor for updating the equalizer coefficients. */ int16_t eq_delta; diff --git a/libs/spandsp/src/spandsp/version.h b/libs/spandsp/src/spandsp/version.h index 2b7aea9dea..eef22ad70e 100644 --- a/libs/spandsp/src/spandsp/version.h +++ b/libs/spandsp/src/spandsp/version.h @@ -30,8 +30,8 @@ /* The date and time of the version are in UTC form. */ -#define SPANDSP_RELEASE_DATE 20080913 -#define SPANDSP_RELEASE_TIME 155039 +#define SPANDSP_RELEASE_DATE 20080916 +#define SPANDSP_RELEASE_TIME 152844 #endif /*- End of file ------------------------------------------------------------*/ diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c index 3ac1b70914..68bbccd43f 100644 --- a/libs/spandsp/src/t30.c +++ b/libs/spandsp/src/t30.c @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: t30.c,v 1.266 2008/09/11 15:13:42 steveu Exp $ + * $Id: t30.c,v 1.267 2008/09/16 12:45:01 steveu Exp $ */ /*! \file */ @@ -682,7 +682,7 @@ static int send_next_ecm_frame(t30_state_t *s) } /*- End of function --------------------------------------------------------*/ -static int send_rr(t30_state_t *s) +static void send_rr(t30_state_t *s) { if (s->current_status != T30_ERR_TX_T5EXP) send_simple_frame(s, T30_RR); diff --git a/libs/spandsp/src/v17rx.c b/libs/spandsp/src/v17rx.c index 60a5cf3a3d..82a3f54a58 100644 --- a/libs/spandsp/src/v17rx.c +++ b/libs/spandsp/src/v17rx.c @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: v17rx.c,v 1.116 2008/09/07 12:45:17 steveu Exp $ + * $Id: v17rx.c,v 1.118 2008/09/16 14:12:23 steveu Exp $ */ /*! \file */ @@ -133,13 +133,6 @@ void v17_rx_signal_cutoff(v17_rx_state_t *s, float cutoff) } /*- End of function --------------------------------------------------------*/ -int v17_rx_equalizer_state(v17_rx_state_t *s, complexf_t **coeffs) -{ - *coeffs = s->eq_coeff; - return V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN; -} -/*- End of function --------------------------------------------------------*/ - static void report_status_change(v17_rx_state_t *s, int status) { if (s->status_handler) @@ -149,37 +142,69 @@ static void report_status_change(v17_rx_state_t *s, int status) } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +int v17_rx_equalizer_state(v17_rx_state_t *s, complexi16_t **coeffs) +#else +int v17_rx_equalizer_state(v17_rx_state_t *s, complexf_t **coeffs) +#endif +{ + *coeffs = s->eq_coeff; + return V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN; +} +/*- End of function --------------------------------------------------------*/ + static void equalizer_save(v17_rx_state_t *s) { +#if defined(SPANDSP_USE_FIXED_POINTx) + cvec_copyi16(s->eq_coeff_save, s->eq_coeff, V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN); +#else cvec_copyf(s->eq_coeff_save, s->eq_coeff, V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN); +#endif } /*- End of function --------------------------------------------------------*/ static void equalizer_restore(v17_rx_state_t *s) { +#if defined(SPANDSP_USE_FIXED_POINTx) + cvec_copyi16(s->eq_coeff, s->eq_coeff_save, V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN); + cvec_zeroi16(s->eq_buf, V17_EQUALIZER_MASK); + s->eq_delta = 32768.0f*EQUALIZER_SLOW_ADAPT_RATIO*EQUALIZER_DELTA/(V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN); +#else cvec_copyf(s->eq_coeff, s->eq_coeff_save, V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN); cvec_zerof(s->eq_buf, V17_EQUALIZER_MASK); + s->eq_delta = EQUALIZER_SLOW_ADAPT_RATIO*EQUALIZER_DELTA/(V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN); +#endif s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1; s->eq_step = 0; - s->eq_delta = EQUALIZER_SLOW_ADAPT_RATIO*EQUALIZER_DELTA/(V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN); } /*- End of function --------------------------------------------------------*/ static void equalizer_reset(v17_rx_state_t *s) { /* Start with an equalizer based on everything being perfect */ +#if defined(SPANDSP_USE_FIXED_POINTx) + cvec_zeroi16(s->eq_coeff, V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN); + s->eq_coeff[V17_EQUALIZER_PRE_LEN] = complex_seti16(3*FP_FACTOR, 0); + cvec_zeroi16(s->eq_buf, V17_EQUALIZER_MASK); + s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN); +#else cvec_zerof(s->eq_coeff, V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN); s->eq_coeff[V17_EQUALIZER_PRE_LEN] = complex_setf(3.0f, 0.0f); cvec_zerof(s->eq_buf, V17_EQUALIZER_MASK); + s->eq_delta = EQUALIZER_DELTA/(V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN); +#endif s->eq_put_step = RX_PULSESHAPER_COEFF_SETS*10/(3*2) - 1; s->eq_step = 0; - s->eq_delta = EQUALIZER_DELTA/(V17_EQUALIZER_PRE_LEN + 1 + V17_EQUALIZER_POST_LEN); } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +static __inline__ complexi16_t equalizer_get(v17_rx_state_t *s) +#else static __inline__ complexf_t equalizer_get(v17_rx_state_t *s) +#endif { int i; int p; @@ -199,7 +224,11 @@ static __inline__ complexf_t equalizer_get(v17_rx_state_t *s) } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +static void tune_equalizer(v17_rx_state_t *s, const complexi16_t *z, const complexi16_t *target) +#else static void tune_equalizer(v17_rx_state_t *s, const complexf_t *z, const complexf_t *target) +#endif { int i; int p; @@ -1080,7 +1109,11 @@ int v17_rx(v17_rx_state_t *s, const int16_t amp[], int len) process_half_baud(s, &zz); #endif } - dds_advancef(&(s->carrier_phase), s->carrier_phase_rate); +#if defined(SPANDSP_USE_FIXED_POINT) + dds_advance(&s->carrier_phase, s->carrier_phase_rate); +#else + dds_advancef(&s->carrier_phase, s->carrier_phase_rate); +#endif } return 0; } diff --git a/libs/spandsp/src/v27ter_rx.c b/libs/spandsp/src/v27ter_rx.c index d196cc5b1e..8f9ca872e4 100644 --- a/libs/spandsp/src/v27ter_rx.c +++ b/libs/spandsp/src/v27ter_rx.c @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: v27ter_rx.c,v 1.102 2008/09/13 14:59:30 steveu Exp $ + * $Id: v27ter_rx.c,v 1.104 2008/09/16 14:12:23 steveu Exp $ */ /*! \file */ @@ -31,10 +31,10 @@ #include #endif +#include #include #include #include -#include #include "floating_fudge.h" #if defined(HAVE_TGMATH_H) #include @@ -71,20 +71,20 @@ signal to a static constellation, even though dealing with differences is all that is necessary. */ -#define CARRIER_NOMINAL_FREQ 1800.0f -#define EQUALIZER_DELTA 0.25f +#define CARRIER_NOMINAL_FREQ 1800.0f +#define EQUALIZER_DELTA 0.25f #if defined(SPANDSP_USE_FIXED_POINT) -#define FP_FACTOR 4096 -#define FP_SHIFT_FACTOR 12 +#define FP_FACTOR 4096 +#define FP_SHIFT_FACTOR 12 #endif /* Segments of the training sequence */ /* V.27ter defines a long and a short sequence. FAX doesn't use the short sequence, so it is not implemented here. */ -#define V27TER_TRAINING_SEG_3_LEN 50 -#define V27TER_TRAINING_SEG_5_LEN 1074 -#define V27TER_TRAINING_SEG_6_LEN 8 +#define V27TER_TRAINING_SEG_3_LEN 50 +#define V27TER_TRAINING_SEG_5_LEN 1074 +#define V27TER_TRAINING_SEG_6_LEN 8 enum { @@ -152,13 +152,6 @@ void v27ter_rx_signal_cutoff(v27ter_rx_state_t *s, float cutoff) } /*- End of function --------------------------------------------------------*/ -int v27ter_rx_equalizer_state(v27ter_rx_state_t *s, complexf_t **coeffs) -{ - *coeffs = s->eq_coeff; - return V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN; -} -/*- End of function --------------------------------------------------------*/ - static void report_status_change(v27ter_rx_state_t *s, int status) { if (s->status_handler) @@ -168,6 +161,17 @@ static void report_status_change(v27ter_rx_state_t *s, int status) } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +int v27ter_rx_equalizer_state(v27ter_rx_state_t *s, complexi16_t **coeffs) +#else +int v27ter_rx_equalizer_state(v27ter_rx_state_t *s, complexf_t **coeffs) +#endif +{ + *coeffs = s->eq_coeff; + return V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN; +} +/*- End of function --------------------------------------------------------*/ + static void equalizer_save(v27ter_rx_state_t *s) { #if defined(SPANDSP_USE_FIXED_POINTx) @@ -183,14 +187,15 @@ static void equalizer_restore(v27ter_rx_state_t *s) #if defined(SPANDSP_USE_FIXED_POINTx) cvec_copyi16(s->eq_coeff, s->eq_coeff_save, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); cvec_zeroi16(s->eq_buf, V27TER_EQUALIZER_MASK); + s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); #else cvec_copyf(s->eq_coeff, s->eq_coeff_save, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); cvec_zerof(s->eq_buf, V27TER_EQUALIZER_MASK); + s->eq_delta = EQUALIZER_DELTA/(V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); #endif s->eq_put_step = (s->bit_rate == 4800) ? RX_PULSESHAPER_4800_COEFF_SETS*5/2 : RX_PULSESHAPER_2400_COEFF_SETS*20/(3*2); s->eq_step = 0; - s->eq_delta = EQUALIZER_DELTA/(V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); } /*- End of function --------------------------------------------------------*/ @@ -201,15 +206,16 @@ static void equalizer_reset(v27ter_rx_state_t *s) cvec_zeroi16(s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); s->eq_coeff[V27TER_EQUALIZER_PRE_LEN] = complex_seti16(1.414f*FP_FACTOR, 0); cvec_zeroi16(s->eq_buf, V27TER_EQUALIZER_MASK); + s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); #else cvec_zerof(s->eq_coeff, V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); s->eq_coeff[V27TER_EQUALIZER_PRE_LEN] = complex_setf(1.414f, 0.0f); cvec_zerof(s->eq_buf, V27TER_EQUALIZER_MASK); + s->eq_delta = EQUALIZER_DELTA/(V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); #endif s->eq_put_step = (s->bit_rate == 4800) ? RX_PULSESHAPER_4800_COEFF_SETS*5/2 : RX_PULSESHAPER_2400_COEFF_SETS*20/(3*2); s->eq_step = 0; - s->eq_delta = EQUALIZER_DELTA/(V27TER_EQUALIZER_PRE_LEN + 1 + V27TER_EQUALIZER_POST_LEN); } /*- End of function --------------------------------------------------------*/ @@ -312,13 +318,66 @@ static void tune_equalizer(v27ter_rx_state_t *s, const complexf_t *z, const comp } /*- End of function --------------------------------------------------------*/ +#if defined(SPANDSP_USE_FIXED_POINTx) +static __inline__ int find_quadrant(const complexi16_t *z) +#else +static __inline__ int find_quadrant(const complexf_t *z) +#endif +{ + int b1; + int b2; + + /* Split the space along the two diagonals. */ + b1 = (z->im > z->re); + b2 = (z->im < -z->re); + return (b2 << 1) | (b1 ^ b2); +} +/*- End of function --------------------------------------------------------*/ + +#if defined(SPANDSP_USE_FIXED_POINTx) +static __inline__ int find_octant(complexi16_t *z) +#else +static __inline__ int find_octant(complexf_t *z) +#endif +{ + float abs_re; + float abs_im; + int b1; + int b2; + int bits; + + /* Are we near an axis or a diagonal? */ + abs_re = fabsf(z->re); + abs_im = fabsf(z->im); + if (abs_im > abs_re*0.4142136f && abs_im < abs_re*2.4142136f) + { + /* Split the space along the two axes. */ + b1 = (z->re < 0.0f); + b2 = (z->im < 0.0f); + bits = (b2 << 2) | ((b1 ^ b2) << 1) | 1; + } + else + { + /* Split the space along the two diagonals. */ + b1 = (z->im > z->re); + b2 = (z->im < -z->re); + bits = (b2 << 2) | ((b1 ^ b2) << 1); + } + return bits; +} +/*- End of function --------------------------------------------------------*/ + #if defined(SPANDSP_USE_FIXED_POINTx) static __inline__ void track_carrier(v27ter_rx_state_t *s, const complexi16_t *z, const complexi16_t *target) #else static __inline__ void track_carrier(v27ter_rx_state_t *s, const complexf_t *z, const complexf_t *target) #endif { +#if defined(SPANDSP_USE_FIXED_POINTx) + int32_t error; +#else float error; +#endif /* For small errors the imaginary part of the difference between the actual and the target positions is proportional to the phase error, for any particular target. However, the @@ -394,55 +453,6 @@ static __inline__ void put_bit(v27ter_rx_state_t *s, int bit) } /*- End of function --------------------------------------------------------*/ -#if defined(SPANDSP_USE_FIXED_POINTx) -static __inline__ int find_quadrant(const complexi16_t *z) -#else -static __inline__ int find_quadrant(const complexf_t *z) -#endif -{ - int b1; - int b2; - - /* Split the space along the two diagonals. */ - b1 = (z->im > z->re); - b2 = (z->im < -z->re); - return (b2 << 1) | (b1 ^ b2); -} -/*- End of function --------------------------------------------------------*/ - -#if defined(SPANDSP_USE_FIXED_POINTx) -static __inline__ int find_octant(complexi16_t *z) -#else -static __inline__ int find_octant(complexf_t *z) -#endif -{ - float abs_re; - float abs_im; - int b1; - int b2; - int bits; - - /* Are we near an axis or a diagonal? */ - abs_re = fabsf(z->re); - abs_im = fabsf(z->im); - if (abs_im > abs_re*0.4142136f && abs_im < abs_re*2.4142136f) - { - /* Split the space along the two axes. */ - b1 = (z->re < 0.0f); - b2 = (z->im < 0.0f); - bits = (b2 << 2) | ((b1 ^ b2) << 1) | 1; - } - else - { - /* Split the space along the two diagonals. */ - b1 = (z->im > z->re); - b2 = (z->im < -z->re); - bits = (b2 << 2) | ((b1 ^ b2) << 1); - } - return bits; -} -/*- End of function --------------------------------------------------------*/ - #if defined(SPANDSP_USE_FIXED_POINTx) static void decode_baud(v27ter_rx_state_t *s, complexi16_t *z) #else @@ -460,25 +470,23 @@ static void decode_baud(v27ter_rx_state_t *s, complexf_t *z) int nearest; int raw_bits; - switch (s->bit_rate) + if (s->bit_rate == 2400) { - case 4800: - default: - nearest = find_octant(z); - raw_bits = phase_steps_4800[(nearest - s->constellation_state) & 7]; - put_bit(s, raw_bits); - put_bit(s, raw_bits >> 1); - put_bit(s, raw_bits >> 2); - s->constellation_state = nearest; - break; - case 2400: nearest = find_quadrant(z); raw_bits = phase_steps_2400[(nearest - s->constellation_state) & 3]; put_bit(s, raw_bits); put_bit(s, raw_bits >> 1); s->constellation_state = nearest; nearest <<= 1; - break; + } + else + { + nearest = find_octant(z); + raw_bits = phase_steps_4800[(nearest - s->constellation_state) & 7]; + put_bit(s, raw_bits); + put_bit(s, raw_bits >> 1); + put_bit(s, raw_bits >> 2); + s->constellation_state = nearest; } track_carrier(s, z, &v27ter_constellation[nearest]); if (--s->eq_skip <= 0) @@ -526,7 +534,7 @@ static __inline__ void symbol_sync(v27ter_rx_state_t *s) } /*- End of function --------------------------------------------------------*/ -#if defined(SPANDSP_USE_FIXED_POINTx) +#if defined(SPANDSP_USE_FIXED_POINT) static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexi16_t *sample) #else static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t *sample) @@ -546,7 +554,12 @@ static __inline__ void process_half_baud(v27ter_rx_state_t *s, const complexf_t /* Add a sample to the equalizer's circular buffer, but don't calculate anything at this time. */ +#if defined(SPANDSP_USE_FIXED_POINT) + s->eq_buf[s->eq_step].re = sample->re/(float) FP_FACTOR; + s->eq_buf[s->eq_step].im = sample->im/(float) FP_FACTOR; +#else s->eq_buf[s->eq_step] = *sample; +#endif s->eq_step = (s->eq_step + 1) & V27TER_EQUALIZER_MASK; /* On alternate insertions we have a whole baud, and must process it. */ @@ -765,16 +778,15 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) int step; int16_t x; int32_t diff; - complexf_t z; #if defined(SPANDSP_USE_FIXED_POINT) - complexi_t zi; -#endif -#if defined(SPANDSP_USE_FIXED_POINTx) - complexi16_t sample; + complexi16_t z; complexi16_t zz; + complexi16_t sample; + complexi32_t zi; #else - complexf_t sample; + complexf_t z; complexf_t zz; + complexf_t sample; #endif int32_t power; @@ -832,8 +844,7 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) continue; } #if defined(IAXMODEM_STUFF) - /* Carrier has dropped, but the put_bit is - pending the signal_present delay. */ + /* Carrier has dropped, but the put_bit is pending the signal_present delay. */ s->carrier_drop_pending = TRUE; #endif } @@ -861,8 +872,8 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) if (s->training_stage == TRAINING_STAGE_SYMBOL_ACQUISITION) { /* Only AGC during the initial training */ -#if defined(SPANDSP_USE_FIXED_POINTx) - s->agc_scaling = (float) FP_FACTOR*(1.0f/RX_PULSESHAPER_4800_GAIN)*1.414f/sqrtf(power); +#if defined(SPANDSP_USE_FIXED_POINT) + s->agc_scaling = (float) FP_FACTOR*32768.0f*(1.0f/RX_PULSESHAPER_4800_GAIN)*1.414f/sqrtf(power); #else s->agc_scaling = (1.0f/RX_PULSESHAPER_4800_GAIN)*1.414f/sqrtf(power); #endif @@ -883,8 +894,11 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) zi.re += (int32_t) rx_pulseshaper_4800[step][j].re*(int32_t) s->rrc_filter[j + s->rrc_filter_step]; zi.im += (int32_t) rx_pulseshaper_4800[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step]; } - sample.re = zi.re*s->agc_scaling; - sample.im = zi.im*s->agc_scaling; + sample.re = ((int32_t) zi.re*(int32_t) s->agc_scaling) >> 15; + sample.im = ((int32_t) zi.im*(int32_t) s->agc_scaling) >> 15; + z = dds_lookup_complexi16(s->carrier_phase); + zz.re = ((int32_t) sample.re*(int32_t) z.re - (int32_t) sample.im*(int32_t) z.im) >> 15; + zz.im = ((int32_t) -sample.re*(int32_t) z.im - (int32_t) sample.im*(int32_t) z.re) >> 15; #else zz.re = rx_pulseshaper_4800[step][0].re*s->rrc_filter[s->rrc_filter_step]; zz.im = rx_pulseshaper_4800[step][0].im*s->rrc_filter[s->rrc_filter_step]; @@ -895,16 +909,17 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) } sample.re = zz.re*s->agc_scaling; sample.im = zz.im*s->agc_scaling; -#endif - /* Shift to baseband - since this is done in a full complex form, the - result is clean, and requires no further filtering, apart from the - equalizer. */ z = dds_lookup_complexf(s->carrier_phase); zz.re = sample.re*z.re - sample.im*z.im; zz.im = -sample.re*z.im - sample.im*z.re; +#endif process_half_baud(s, &zz); } - dds_advancef(&(s->carrier_phase), s->carrier_phase_rate); +#if defined(SPANDSP_USE_FIXED_POINT) + dds_advance(&s->carrier_phase, s->carrier_phase_rate); +#else + dds_advancef(&s->carrier_phase, s->carrier_phase_rate); +#endif } } else @@ -990,8 +1005,8 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) if (s->training_stage == TRAINING_STAGE_SYMBOL_ACQUISITION) { /* Only AGC during the initial training */ -#if defined(SPANDSP_USE_FIXED_POINTx) - s->agc_scaling = (float) FP_FACTOR*(1.0f/RX_PULSESHAPER_2400_GAIN)*1.414f/sqrtf(power); +#if defined(SPANDSP_USE_FIXED_POINT) + s->agc_scaling = (float) FP_FACTOR*32768.0f*(1.0f/RX_PULSESHAPER_2400_GAIN)*1.414f/sqrtf(power); #else s->agc_scaling = (1.0f/RX_PULSESHAPER_2400_GAIN)*1.414f/sqrtf(power); #endif @@ -1012,8 +1027,11 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) zi.re += (int32_t) rx_pulseshaper_2400[step][j].re*(int32_t) s->rrc_filter[j + s->rrc_filter_step]; zi.im += (int32_t) rx_pulseshaper_2400[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step]; } - sample.re = zi.re*s->agc_scaling; - sample.im = zi.im*s->agc_scaling; + sample.re = ((int32_t) zi.re*(int32_t) s->agc_scaling) >> 15; + sample.im = ((int32_t) zi.im*(int32_t) s->agc_scaling) >> 15; + z = dds_lookup_complexi16(s->carrier_phase); + zz.re = ((int32_t) sample.re*(int32_t) z.re - (int32_t) sample.im*(int32_t) z.im) >> 15; + zz.im = ((int32_t) -sample.re*(int32_t) z.im - (int32_t) sample.im*(int32_t) z.re) >> 15; #else zz.re = rx_pulseshaper_2400[step][0].re*s->rrc_filter[s->rrc_filter_step]; zz.im = rx_pulseshaper_2400[step][0].im*s->rrc_filter[s->rrc_filter_step]; @@ -1024,16 +1042,17 @@ int v27ter_rx(v27ter_rx_state_t *s, const int16_t amp[], int len) } sample.re = zz.re*s->agc_scaling; sample.im = zz.im*s->agc_scaling; -#endif - /* Shift to baseband - since this is done in a full complex form, the - result is clean, and requires no further filtering apart from the - equalizer. */ z = dds_lookup_complexf(s->carrier_phase); zz.re = sample.re*z.re - sample.im*z.im; zz.im = -sample.re*z.im - sample.im*z.re; +#endif process_half_baud(s, &zz); } - dds_advancef(&(s->carrier_phase), s->carrier_phase_rate); +#if defined(SPANDSP_USE_FIXED_POINT) + dds_advance(&s->carrier_phase, s->carrier_phase_rate); +#else + dds_advancef(&s->carrier_phase, s->carrier_phase_rate); +#endif } } return 0; @@ -1103,7 +1122,7 @@ int v27ter_rx_restart(v27ter_rx_state_t *s, int bit_rate, int old_train) { s->carrier_phase_rate = dds_phase_ratef(CARRIER_NOMINAL_FREQ); #if defined(SPANDSP_USE_FIXED_POINTx) - s->agc_scaling = (float) FP_FACTOR*0.005f/RX_PULSESHAPER_4800_GAIN; + s->agc_scaling = (float) FP_FACTOR*32768.0f*0.005f/RX_PULSESHAPER_4800_GAIN; #else s->agc_scaling = 0.005f/RX_PULSESHAPER_4800_GAIN; #endif diff --git a/libs/spandsp/src/v29rx.c b/libs/spandsp/src/v29rx.c index 8abd49c3ed..50dba0120f 100644 --- a/libs/spandsp/src/v29rx.c +++ b/libs/spandsp/src/v29rx.c @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: v29rx.c,v 1.138 2008/09/13 15:48:04 steveu Exp $ + * $Id: v29rx.c,v 1.140 2008/09/16 14:12:23 steveu Exp $ */ /*! \file */ @@ -65,19 +65,19 @@ #include "v29rx_floating_rrc.h" #endif -#define CARRIER_NOMINAL_FREQ 1700.0f -#define BAUD_RATE 2400 -#define EQUALIZER_DELTA 0.21f +#define CARRIER_NOMINAL_FREQ 1700.0f +#define BAUD_RATE 2400 +#define EQUALIZER_DELTA 0.21f #if defined(SPANDSP_USE_FIXED_POINT) -#define FP_FACTOR 4096 -#define FP_SHIFT_FACTOR 12 +#define FP_FACTOR 4096 +#define FP_SHIFT_FACTOR 12 #endif /* Segments of the training sequence */ -#define V29_TRAINING_SEG_2_LEN 128 -#define V29_TRAINING_SEG_3_LEN 384 -#define V29_TRAINING_SEG_4_LEN 48 +#define V29_TRAINING_SEG_2_LEN 128 +#define V29_TRAINING_SEG_3_LEN 384 +#define V29_TRAINING_SEG_4_LEN 48 enum { @@ -146,6 +146,12 @@ float v29_rx_symbol_timing_correction(v29_rx_state_t *s) } /*- End of function --------------------------------------------------------*/ +float v29_rx_signal_power(v29_rx_state_t *s) +{ + return power_meter_current_dbm0(&s->power); +} +/*- End of function --------------------------------------------------------*/ + void v29_rx_signal_cutoff(v29_rx_state_t *s, float cutoff) { /* The 0.4 factor allows for the gain of the DC blocker */ @@ -154,9 +160,12 @@ void v29_rx_signal_cutoff(v29_rx_state_t *s, float cutoff) } /*- End of function --------------------------------------------------------*/ -float v29_rx_signal_power(v29_rx_state_t *s) +static void report_status_change(v29_rx_state_t *s, int status) { - return power_meter_current_dbm0(&s->power); + if (s->status_handler) + s->status_handler(s->status_user_data, status); + else if (s->put_bit) + s->put_bit(s->put_bit_user_data, status); } /*- End of function --------------------------------------------------------*/ @@ -171,15 +180,6 @@ int v29_rx_equalizer_state(v29_rx_state_t *s, complexf_t **coeffs) } /*- End of function --------------------------------------------------------*/ -static void report_status_change(v29_rx_state_t *s, int status) -{ - if (s->status_handler) - s->status_handler(s->status_user_data, status); - else if (s->put_bit) - s->put_bit(s->put_bit_user_data, status); -} -/*- End of function --------------------------------------------------------*/ - static void equalizer_save(v29_rx_state_t *s) { #if defined(SPANDSP_USE_FIXED_POINT) @@ -519,7 +519,7 @@ static __inline__ void symbol_sync(v29_rx_state_t *s) v = (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_A + (((s->symbol_sync_low[0] >> 5)*(s->symbol_sync_high[1] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_B + (((s->symbol_sync_low[1] >> 5)*(s->symbol_sync_high[0] >> 4)) >> 15)*SYNC_CROSS_CORR_COEFF_C; - /* Filter away any DC component */ + /* Filter away any DC component */ p = v - s->symbol_sync_dc_filter[1]; s->symbol_sync_dc_filter[1] = s->symbol_sync_dc_filter[0]; s->symbol_sync_dc_filter[0] = v; @@ -541,7 +541,7 @@ static __inline__ void symbol_sync(v29_rx_state_t *s) v = s->symbol_sync_low[1]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_A + s->symbol_sync_low[0]*s->symbol_sync_high[1]*SYNC_CROSS_CORR_COEFF_B + s->symbol_sync_low[1]*s->symbol_sync_high[0]*SYNC_CROSS_CORR_COEFF_C; - /* Filter away any DC component */ + /* Filter away any DC component */ p = v - s->symbol_sync_dc_filter[1]; s->symbol_sync_dc_filter[1] = s->symbol_sync_dc_filter[0]; s->symbol_sync_dc_filter[0] = v; @@ -1026,7 +1026,11 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len) #endif process_half_baud(s, &zz); } - dds_advancef(&(s->carrier_phase), s->carrier_phase_rate); +#if defined(SPANDSP_USE_FIXED_POINT) + dds_advance(&s->carrier_phase, s->carrier_phase_rate); +#else + dds_advancef(&s->carrier_phase, s->carrier_phase_rate); +#endif } return 0; } diff --git a/libs/spandsp/src/vector_float.c b/libs/spandsp/src/vector_float.c index 7e78c9180f..0598ebe7dc 100644 --- a/libs/spandsp/src/vector_float.c +++ b/libs/spandsp/src/vector_float.c @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: vector_float.c,v 1.11 2008/07/02 14:48:26 steveu Exp $ + * $Id: vector_float.c,v 1.12 2008/09/16 15:21:52 steveu Exp $ */ /*! \file */ @@ -44,6 +44,32 @@ #endif #include +#if defined(SPANDSP_USE_MMX) +#include +#endif +#if defined(SPANDSP_USE_SSE) +#include +#endif +#if defined(SPANDSP_USE_SSE2) +#include +#endif +#if defined(SPANDSP_USE_SSE3) +#include +#include +#endif +#if defined(SPANDSP_USE_SSE4_1) +#include +#endif +#if defined(SPANDSP_USE_SSE4_2) +#include +#endif +#if defined(SPANDSP_USE_SSE4A) +#include +#endif +#if defined(SPANDSP_USE_SSE5) +#include +#endif + #include "spandsp/telephony.h" #include "spandsp/vector_float.h" @@ -100,7 +126,7 @@ void vec_zerol(long double z[], int n) int i; for (i = 0; i < n; i++) - z[i] = 0.0; + z[i] = 0.0L; } /*- End of function --------------------------------------------------------*/ #endif @@ -306,6 +332,41 @@ void vec_mull(long double z[], const long double x[], const long double y[], int /*- End of function --------------------------------------------------------*/ #endif +#if defined(__GNUC__) && defined(SPANDSP_USE_SSE2) +float vec_dot_prodf(const float x[], const float y[], int n) +{ + int i; + float z; + __m128 num1, num2, num3, num4; + + z = 0.0f; + if ((i = n & ~3)) + { + num4 = _mm_setzero_ps(); //sets sum to zero + for (i -= 4; i >= 0; i -= 4) + { + num1 = _mm_loadu_ps(x + i); + num2 = _mm_loadu_ps(y + i); + num3 = _mm_mul_ps(num1, num2); + num4 = _mm_add_ps(num4, num3); + } + num4 = _mm_add_ps(_mm_movehl_ps(num4, num4), num4); + num4 = _mm_add_ss(_mm_shuffle_ps(num4, num4, 1), num4); + _mm_store_ss(&z, num4); + } + /* Now deal with the last 1 to 3 elements, which don't fill in an SSE2 register */ + switch (n & 3) + { + case 3: + z += x[n - 3]*y[n - 3]; + case 2: + z += x[n - 2]*y[n - 2]; + case 1: + z += x[n - 1]*y[n - 1]; + } + return z; +} +#else float vec_dot_prodf(const float x[], const float y[], int n) { int i; @@ -317,6 +378,7 @@ float vec_dot_prodf(const float x[], const float y[], int n) return z; } /*- End of function --------------------------------------------------------*/ +#endif double vec_dot_prod(const double x[], const double y[], int n) { @@ -336,7 +398,7 @@ long double vec_dot_prodl(const long double x[], const long double y[], int n) int i; long double z; - z = 0.0; + z = 0.0L; for (i = 0; i < n; i++) z += x[i]*y[i]; return z; diff --git a/libs/spandsp/src/vector_int.c b/libs/spandsp/src/vector_int.c index 3f19eefda4..5ba6f22d15 100644 --- a/libs/spandsp/src/vector_int.c +++ b/libs/spandsp/src/vector_int.c @@ -22,7 +22,7 @@ * License along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: vector_int.c,v 1.12 2008/09/01 16:07:34 steveu Exp $ + * $Id: vector_int.c,v 1.13 2008/09/16 15:21:52 steveu Exp $ */ /*! \file */ @@ -51,7 +51,7 @@ int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n) { int32_t z; -#if defined(__GNUC__) && defined(__i386__) +#if defined(__GNUC__) && defined(SPANDSP_USE_MMX) __asm__ __volatile__( " emms;\n" " pxor %%mm0,%%mm0;\n" @@ -162,7 +162,7 @@ int32_t vec_dot_prodi16(const int16_t x[], const int16_t y[], int n) int32_t vec_min_maxi16(const int16_t x[], int n, int16_t out[]) { -#if defined(__GNUC__) && defined(__i386__) +#if defined(__GNUC__) && defined(SPANDSP_USE_MMX) static const int32_t lower_bound = 0x80008000; static const int32_t upper_bound = 0x7FFF7FFF; int32_t max; diff --git a/libs/spandsp/tests/at_interpreter_tests.c b/libs/spandsp/tests/at_interpreter_tests.c index 1635558a71..c03e5b3731 100644 --- a/libs/spandsp/tests/at_interpreter_tests.c +++ b/libs/spandsp/tests/at_interpreter_tests.c @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: at_interpreter_tests.c,v 1.18 2008/08/17 16:25:52 steveu Exp $ + * $Id: at_interpreter_tests.c,v 1.19 2008/09/16 12:45:25 steveu Exp $ */ /*! \file */ @@ -350,7 +350,7 @@ static const struct command_response_s general_test_seq[] = {"AT+VTX\r", "\r\nOK\r\n"}, /* V.253 10.1.6 - Transmit data state */ {"AT+WS46\r", "\r\nOK\r\n"}, /* 3GPP TS 27.007 5.9 - PCCA STD-101 [17] select wireless network */ {"ATA\r", "\r\nERROR\r\n"}, /* V.250 6.3.5 - Answer */ - {"ATDT -1234567890ABCDPSTW*#+,!@\r", ""}, /* V.250 6.3.1 - Dial */ + {"ATDT -1234567890ABCDPSTW*#+,!@\r;", ""}, /* V.250 6.3.1 - Dial */ {"ATE1\r", "\r\nOK\r\n"}, /* V.250 6.2.4 - Command echo */ {"ATE0\r", "ATE0\r\r\nOK\r\n"}, /* V.250 6.2.4 - Command echo */ {"ATH\r", "\r\nOK\r\n"}, /* V.250 6.3.6 - Hook control */ diff --git a/libs/spandsp/tests/vector_float_tests.c b/libs/spandsp/tests/vector_float_tests.c index 59e6b826a2..ddd7be64b6 100644 --- a/libs/spandsp/tests/vector_float_tests.c +++ b/libs/spandsp/tests/vector_float_tests.c @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: vector_float_tests.c,v 1.9 2008/05/13 13:17:27 steveu Exp $ + * $Id: vector_float_tests.c,v 1.10 2008/09/16 15:21:52 steveu Exp $ */ #if defined(HAVE_CONFIG_H) @@ -49,26 +49,82 @@ static double vec_dot_prod_dumb(const double x[], const double y[], int n) } /*- End of function --------------------------------------------------------*/ -int main(int argc, char *argv[]) +static int test_vec_dot_prod(void) { int i; double x[100]; double y[100]; double zsa; double zsb; + double ratio; for (i = 0; i < 99; i++) { x[i] = rand(); y[i] = rand(); } - zsa = vec_dot_prod(x, y, 99); - zsb = vec_dot_prod_dumb(x, y, 99); - if (zsa != zsb) + for (i = 1; i < 99; i++) { - printf("Tests failed\n"); - exit(2); + zsa = vec_dot_prod(x, y, i); + zsb = vec_dot_prod_dumb(x, y, i); + ratio = zsa/zsb; + if (ratio < 0.9999 || ratio > 1.0001) + { + printf("vec_dot_prod() - %f %f\n", zsa, zsb); + printf("Tests failed\n"); + exit(2); + } } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +static float vec_dot_prodf_dumb(const float x[], const float y[], int n) +{ + int i; + float z; + + z = 0.0; + for (i = 0; i < n; i++) + z += x[i]*y[i]; + return z; +} +/*- End of function --------------------------------------------------------*/ + +static int test_vec_dot_prodf(void) +{ + int i; + float x[100]; + float y[100]; + float zsa; + float zsb; + float ratio; + + for (i = 0; i < 99; i++) + { + x[i] = rand(); + y[i] = rand(); + } + for (i = 1; i < 99; i++) + { + zsa = vec_dot_prodf(x, y, i); + zsb = vec_dot_prodf_dumb(x, y, i); + ratio = zsa/zsb; + if (ratio < 0.9999f || ratio > 1.0001f) + { + printf("vec_dot_prodf() - %e %e\n", zsa, zsb); + printf("Tests failed\n"); + exit(2); + } + } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + test_vec_dot_prod(); + test_vec_dot_prodf(); printf("Tests passed.\n"); return 0; diff --git a/libs/spandsp/tests/vector_int_tests.c b/libs/spandsp/tests/vector_int_tests.c index 04aa0287fb..0c914cdb30 100644 --- a/libs/spandsp/tests/vector_int_tests.c +++ b/libs/spandsp/tests/vector_int_tests.c @@ -22,7 +22,7 @@ * along with this program; if not, write to the Free Software * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. * - * $Id: vector_int_tests.c,v 1.8 2008/05/13 13:17:27 steveu Exp $ + * $Id: vector_int_tests.c,v 1.9 2008/09/16 15:21:52 steveu Exp $ */ #if defined(HAVE_CONFIG_H) @@ -44,8 +44,36 @@ static int32_t vec_dot_prodi16_dumb(const int16_t x[], const int16_t y[], int n) z = 0; for (i = 0; i < n; i++) - z += x[i]*y[i]; - return z; + z += (int32_t) x[i]*(int32_t) y[i]; + return z; +} +/*- End of function --------------------------------------------------------*/ + +static int test_vec_dot_prodi16(void) +{ + int i; + int32_t za; + int32_t zb; + int16_t x[99]; + int16_t y[99]; + + for (i = 0; i < 99; i++) + { + x[i] = rand(); + y[i] = rand(); + } + + for (i = 1; i < 99; i++) + { + za = vec_dot_prodi16(x, y, i); + zb = vec_dot_prodi16_dumb(x, y, i); + if (za != zb) + { + printf("Tests failed\n"); + exit(2); + } + } + return 0; } /*- End of function --------------------------------------------------------*/ @@ -79,7 +107,7 @@ static int32_t vec_min_maxi16_dumb(const int16_t x[], int n, int16_t out[]) } /*- End of function --------------------------------------------------------*/ -int main(int argc, char *argv[]) +static int test_vec_min_maxi16(void) { int i; int32_t za; @@ -95,14 +123,6 @@ int main(int argc, char *argv[]) y[i] = rand(); } - za = vec_dot_prodi16(x, y, 99); - zb = vec_dot_prodi16_dumb(x, y, 99); - if (za != zb) - { - printf("Tests failed\n"); - exit(2); - } - x[42] = -32768; za = vec_min_maxi16_dumb(x, 99, outa); zb = vec_min_maxi16(x, 99, outb); @@ -115,6 +135,15 @@ int main(int argc, char *argv[]) printf("Tests failed\n"); exit(2); } + return 0; +} +/*- End of function --------------------------------------------------------*/ + +int main(int argc, char *argv[]) +{ + test_vec_dot_prodi16(); + test_vec_min_maxi16(); + printf("Tests passed.\n"); return 0; }