]> git.ipfire.org Git - thirdparty/freeswitch.git/commitdiff
Tweaks
authorSteve Underwood <steveu@coppice.org>
Fri, 20 Jul 2012 23:18:27 +0000 (07:18 +0800)
committerSteve Underwood <steveu@coppice.org>
Fri, 20 Jul 2012 23:18:27 +0000 (07:18 +0800)
libs/spandsp/src/spandsp/fax_modems.h
libs/spandsp/src/spandsp/private/t38_gateway.h
libs/spandsp/src/spandsp/private/v22bis.h
libs/spandsp/src/spandsp/private/v27ter_tx.h
libs/spandsp/src/spandsp/private/v29tx.h
libs/spandsp/src/v22bis_tx.c
libs/spandsp/src/v27ter_tx.c
libs/spandsp/src/v29tx.c

index 100e57eb5c485cb1e25084e0861ebf1bfa135ade..a3f77dcc002a142dae63c0e12e2dcafbc80d3fbb 100644 (file)
@@ -64,6 +64,7 @@ SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx(void *user_data, const int16_t am
 SPAN_DECLARE_NONSTD(int) fax_modems_v17_v21_rx_fillin(void *user_data, int len);
 SPAN_DECLARE_NONSTD(int) fax_modems_v27ter_v21_rx_fillin(void *user_data, int len);
 SPAN_DECLARE_NONSTD(int) fax_modems_v29_v21_rx_fillin(void *user_data, int len);
+
 SPAN_DECLARE(void) fax_modems_start_rx_modem(fax_modems_state_t *s, int which);
 
 SPAN_DECLARE(void) fax_modems_set_tep_mode(fax_modems_state_t *s, int use_tep);
index d7cd549264fb0a6f25439c89152455424ad85fb0..af72e78213f1ce4f654e08f41287180c91037428 100644 (file)
@@ -86,8 +86,8 @@ typedef struct
     uint16_t crc;
     /*! \brief TRUE if non-ECM fill bits are to be stripped when sending image data. */
     int fill_bit_removal;
-    /*! \brief The number of octets to send in each image packet (non-ECM or ECM) at the current
-               rate and the current specified packet interval. */
+    /*! \brief The number of octets to send in each image packet (non-ECM or ECM) at
+               the current rate and the current specified packet interval. */
     int octets_per_data_packet;
 
     /*! \brief Bits into the non-ECM buffer */
index 48e4c427146e26e35a00957ff9461b4cd85ec637..01c37e9aea9f3eacd2e44b37981bbfa6c86c3d70 100644 (file)
@@ -99,13 +99,6 @@ struct v22bis_state_s
     /* Receive section */
     struct
     {
-#if defined(SPANDSP_USE_FIXED_POINTx)
-        /*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
-        int16_t rrc_filter[V22BIS_RX_FILTER_STEPS];
-#else
-        /*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
-        float rrc_filter[V22BIS_RX_FILTER_STEPS];
-#endif
         /*! \brief Current offset into the RRC pulse shaping filter buffer. */
         int rrc_filter_step;
 
@@ -123,20 +116,11 @@ struct v22bis_state_s
         /*! \brief >0 if a signal above the minimum is present. It may or may not be a V.22bis signal. */
         int signal_present;
 
-        /*! \brief A measure of how much mismatch there is between the real constellation,
-            and the decoded symbol positions. */
-        float training_error;
-
         /*! \brief The current phase of the carrier (i.e. the DDS parameter). */
         uint32_t carrier_phase;
         /*! \brief The update rate for the phase of the carrier (i.e. the DDS increment). */
         int32_t carrier_phase_rate;
 
-        /*! \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;
-
         /*! \brief A callback function which may be enabled to report every symbol's
                    constellation position. */
         qam_report_handler_t qam_report;
@@ -150,23 +134,49 @@ struct v22bis_state_s
         int32_t carrier_on_power;
         /*! \brief The power meter level at which carrier off is declared. */
         int32_t carrier_off_power;
+
+        int constellation_state;
+
+#if defined(SPANDSP_USE_FIXED_POINTx)
         /*! \brief The scaling factor accessed by the AGC algorithm. */
         float agc_scaling;
-    
-        int constellation_state;
+        /*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
+        int16_t rrc_filter[V22BIS_RX_FILTER_STEPS];
 
         /*! \brief The current delta factor for updating the equalizer coefficients. */
         float eq_delta;
-#if defined(SPANDSP_USE_FIXED_POINTx)
         /*! \brief The adaptive equalizer coefficients. */
         complexi_t eq_coeff[2*V22BIS_EQUALIZER_LEN + 1];
         /*! \brief The equalizer signal buffer. */
         complexi_t eq_buf[V22BIS_EQUALIZER_MASK + 1];
+
+        /*! \brief A measure of how much mismatch there is between the real constellation,
+                   and the decoded symbol positions. */
+        float training_error;
+        /*! \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 scaling factor accessed by the AGC algorithm. */
+        float agc_scaling;
+        /*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
+        float rrc_filter[V22BIS_RX_FILTER_STEPS];
+
+        /*! \brief The current delta factor for updating the equalizer coefficients. */
+        float eq_delta;
         /*! \brief The adaptive equalizer coefficients. */
         complexf_t eq_coeff[2*V22BIS_EQUALIZER_LEN + 1];
         /*! \brief The equalizer signal buffer. */
         complexf_t eq_buf[V22BIS_EQUALIZER_MASK + 1];
+
+        /*! \brief A measure of how much mismatch there is between the real constellation,
+                   and the decoded symbol positions. */
+        float training_error;
+        /*! \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 Current offset into the equalizer buffer. */
         int eq_step;
@@ -192,11 +202,24 @@ struct v22bis_state_s
     /* Transmit section */
     struct
     {
+#if defined(SPANDSP_USE_FIXED_POINTx)
+        /*! \brief The guard tone level. */
+        int16_t guard_tone_gain;
+        /*! \brief The gain factor needed to achieve the specified output power. */
+        int16_t gain;
+        /*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
+        int16_t rrc_filter_re[V22BIS_TX_FILTER_STEPS];
+        int16_t rrc_filter_im[V22BIS_TX_FILTER_STEPS];
+#else
+        /*! \brief The guard tone level. */
+        float guard_tone_gain;
         /*! \brief The gain factor needed to achieve the specified output power. */
         float gain;
-
         /*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
-        complexf_t rrc_filter[2*V22BIS_TX_FILTER_STEPS];
+        float rrc_filter_re[V22BIS_TX_FILTER_STEPS];
+        float rrc_filter_im[V22BIS_TX_FILTER_STEPS];
+#endif
+
         /*! \brief Current offset into the RRC pulse shaping filter buffer. */
         int rrc_filter_step;
 
@@ -218,7 +241,6 @@ struct v22bis_state_s
         uint32_t guard_phase;
         /*! \brief The update rate for the phase of the guard tone (i.e. the DDS increment). */
         int32_t guard_phase_rate;
-        float guard_tone_gain;
         /*! \brief The current fractional phase of the baud timing. */
         int baud_phase;
         /*! \brief The code number for the current position in the constellation. */
index 18e27e127754860705ba0986a7015c23b9ac5835..5d8d41f842ed737fcb66acf1d35753e2b3c7cdec 100644 (file)
@@ -53,15 +53,18 @@ struct v27ter_tx_state_s
     /*! \brief The gain factor needed to achieve the specified output power at 4800bps. */
     int16_t gain_4800;
     /*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
-    complexi16_t rrc_filter[2*V27TER_TX_FILTER_STEPS];
+    int16_t rrc_filter_re[V27TER_TX_FILTER_STEPS];
+    int16_t rrc_filter_im[V27TER_TX_FILTER_STEPS];
 #else
     /*! \brief The gain factor needed to achieve the specified output power at 2400bps. */
     float gain_2400;
     /*! \brief The gain factor needed to achieve the specified output power at 4800bps. */
     float gain_4800;
     /*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
-    complexf_t rrc_filter[2*V27TER_TX_FILTER_STEPS];
+    float rrc_filter_re[V27TER_TX_FILTER_STEPS];
+    float rrc_filter_im[V27TER_TX_FILTER_STEPS];
 #endif
+
     /*! \brief Current offset into the RRC pulse shaping filter buffer. */
     int rrc_filter_step;
     
index 034631ef87b563d21a593fa76115b7a9a3a4502f..67c2b7098d6198464a551d48248e4353f0988842 100644 (file)
@@ -50,12 +50,13 @@ struct v29_tx_state_s
 #if defined(SPANDSP_USE_FIXED_POINT)
     /*! \brief Gain required to achieve the specified output power, not allowing
                for the size of the current constellation. */
-    float base_gain;
+    int16_t base_gain;
     /*! \brief Gain required to achieve the specified output power, allowing
                for the size of the current constellation. */
-    int32_t gain;
+    int16_t gain;
     /*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
-    complexi16_t rrc_filter[2*V29_TX_FILTER_STEPS];
+    int16_t rrc_filter_re[V29_TX_FILTER_STEPS];
+    int16_t rrc_filter_im[V29_TX_FILTER_STEPS];
 #else
     /*! \brief Gain required to achieve the specified output power, not allowing
                for the size of the current constellation. */
@@ -64,8 +65,10 @@ struct v29_tx_state_s
                for the size of the current constellation. */
     float gain;
     /*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
-    complexf_t rrc_filter[2*V29_TX_FILTER_STEPS];
+    float rrc_filter_re[V29_TX_FILTER_STEPS];
+    float rrc_filter_im[V29_TX_FILTER_STEPS];
 #endif
+
     /*! \brief Current offset into the RRC pulse shaping filter buffer. */
     int rrc_filter_step;
 
index 41c7ed2f385eb52760f0fd13cfb4f0330762ce17..2f8c724f6b706707b22cd0c199d59f9e5dbb0122 100644 (file)
 #include "spandsp/private/v22bis.h"
 
 #if defined(SPANDSP_USE_FIXED_POINTx)
+#define FP_SCALE    FP_Q_6_10
 #include "v22bis_tx_fixed_rrc.h"
 #else
+#define FP_SCALE(x) (x)
 #include "v22bis_tx_floating_rrc.h"
 #endif
 
@@ -246,24 +248,28 @@ static const int phase_steps[4] =
     1, 0, 2, 3
 };
 
+#if defined(SPANDSP_USE_FIXED_POINTx)
+const complexi16_t v22bis_constellation[16] =
+#else
 const complexf_t v22bis_constellation[16] =
+#endif
 {
-    { 1.0f,  1.0f},
-    { 3.0f,  1.0f},     /* 1200bps 00 */
-    { 1.0f,  3.0f},
-    { 3.0f,  3.0f},
-    {-1.0f,  1.0f},
-    {-1.0f,  3.0f},     /* 1200bps 01 */
-    {-3.0f,  1.0f},
-    {-3.0f,  3.0f},
-    {-1.0f, -1.0f},
-    {-3.0f, -1.0f},     /* 1200bps 10 */
-    {-1.0f, -3.0f},
-    {-3.0f, -3.0f},
-    { 1.0f, -1.0f},
-    { 1.0f, -3.0f},     /* 1200bps 11 */
-    { 3.0f, -1.0f},
-    { 3.0f, -3.0f}
+    {FP_SCALE( 1.0f), FP_SCALE( 1.0f)},
+    {FP_SCALE( 3.0f), FP_SCALE( 1.0f)},         /* 1200bps 00 */
+    {FP_SCALE( 1.0f), FP_SCALE( 3.0f)},
+    {FP_SCALE( 3.0f), FP_SCALE( 3.0f)},
+    {FP_SCALE(-1.0f), FP_SCALE( 1.0f)},
+    {FP_SCALE(-1.0f), FP_SCALE( 3.0f)},         /* 1200bps 01 */
+    {FP_SCALE(-3.0f), FP_SCALE( 1.0f)},
+    {FP_SCALE(-3.0f), FP_SCALE( 3.0f)},
+    {FP_SCALE(-1.0f), FP_SCALE(-1.0f)},
+    {FP_SCALE(-3.0f), FP_SCALE(-1.0f)},         /* 1200bps 10 */
+    {FP_SCALE(-1.0f), FP_SCALE(-3.0f)},
+    {FP_SCALE(-3.0f), FP_SCALE(-3.0f)},
+    {FP_SCALE( 1.0f), FP_SCALE(-1.0f)},
+    {FP_SCALE( 1.0f), FP_SCALE(-3.0f)},         /* 1200bps 11 */
+    {FP_SCALE( 3.0f), FP_SCALE(-1.0f)},
+    {FP_SCALE( 3.0f), FP_SCALE(-3.0f)}
 };
 
 static int fake_get_bit(void *user_data)
@@ -308,10 +314,18 @@ static __inline__ int get_scrambled_bit(v22bis_state_t *s)
 }
 /*- End of function --------------------------------------------------------*/
 
+#if defined(SPANDSP_USE_FIXED_POINTx)
+static complexi16_t training_get(v22bis_state_t *s)
+#else
 static complexf_t training_get(v22bis_state_t *s)
+#endif
 {
-    int bits;
+#if defined(SPANDSP_USE_FIXED_POINT)
+    static const complexi16_t zero = {0, 0};
+#else
     static const complexf_t zero = {0.0f, 0.0f};
+#endif
+    int bits;
 
     /* V.22bis training sequence */
     switch (s->tx.training)
@@ -403,8 +417,17 @@ static complexf_t training_get(v22bis_state_t *s)
 }
 /*- End of function --------------------------------------------------------*/
 
+#if defined(SPANDSP_USE_FIXED_POINTx)
+static complexi16_t getbaud(v22bis_state_t *s)
+#else
 static complexf_t getbaud(v22bis_state_t *s)
+#endif
 {
+#if defined(SPANDSP_USE_FIXED_POINTx)
+    static const complexi16_t zero = {0, 0};
+#else
+    static const complexf_t zero = {0.0f, 0.0f};
+#endif
     int bits;
 
     if (s->tx.training)
@@ -419,7 +442,7 @@ static complexf_t getbaud(v22bis_state_t *s)
     if (s->tx.shutdown)
     {
         if (++s->tx.shutdown > 10)
-            return complex_setf(0.0f, 0.0f);
+            return zero;
     }
     /* The first two bits define the quadrant */
     bits = get_scrambled_bit(s);
@@ -441,11 +464,18 @@ static complexf_t getbaud(v22bis_state_t *s)
 
 SPAN_DECLARE_NONSTD(int) v22bis_tx(v22bis_state_t *s, int16_t amp[], int len)
 {
+#if defined(SPANDSP_USE_FIXED_POINTx)
+    complexi16_t v;
+    complexi32_t x;
+    complexi32_t z;
+    int16_t iamp;
+#else
+    complexf_t v;
     complexf_t x;
     complexf_t z;
-    int i;
-    int sample;
     float famp;
+#endif
+    int sample;
 
     if (s->tx.shutdown > 10)
         return 0;
@@ -454,28 +484,42 @@ SPAN_DECLARE_NONSTD(int) v22bis_tx(v22bis_state_t *s, int16_t amp[], int len)
         if ((s->tx.baud_phase += 3) >= 40)
         {
             s->tx.baud_phase -= 40;
-            s->tx.rrc_filter[s->tx.rrc_filter_step] =
-            s->tx.rrc_filter[s->tx.rrc_filter_step + V22BIS_TX_FILTER_STEPS] = getbaud(s);
+            v = getbaud(s);
+            s->tx.rrc_filter_re[s->tx.rrc_filter_step] = v.re;
+            s->tx.rrc_filter_im[s->tx.rrc_filter_step] = v.im;
             if (++s->tx.rrc_filter_step >= V22BIS_TX_FILTER_STEPS)
                 s->tx.rrc_filter_step = 0;
         }
+#if defined(SPANDSP_USE_FIXED_POINTx)
         /* Root raised cosine pulse shaping at baseband */
-        x = complex_setf(0.0f, 0.0f);
-        for (i = 0;  i < V22BIS_TX_FILTER_STEPS;  i++)
+        x.re = vec_circular_dot_prodi16(s->tx.rrc_filter_re, tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->tx.baud_phase], V22BIS_TX_FILTER_STEPS, s->tx.rrc_filter_step) >> 14;
+        x.im = vec_circular_dot_prodi16(s->tx.rrc_filter_im, tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->tx.baud_phase], V22BIS_TX_FILTER_STEPS, s->tx.rrc_filter_step) >> 14;
+        /* Now create and modulate the carrier */
+        z = dds_complexi32(&s->tx.carrier_phase, s->tx.carrier_phase_rate);
+        iamp = (x.re*z.re - x.im*z.im) >> 15;
+        iamp = (int16_t) (((int32_t) iamp*s->tx.gain) >> 11);
+        if (s->tx.guard_phase_rate  &&  (s->tx.rrc_filter_re[s->tx.rrc_filter_step] != 0  ||  s->tx.rrc_filter_im[s->tx.rrc_filter_step] != 0))
         {
-            x.re += tx_pulseshaper[39 - s->tx.baud_phase][i]*s->tx.rrc_filter[i + s->tx.rrc_filter_step].re;
-            x.im += tx_pulseshaper[39 - s->tx.baud_phase][i]*s->tx.rrc_filter[i + s->tx.rrc_filter_step].im;
+            /* Add the guard tone */
+            iamp += dds_mod(&s->tx.guard_phase, s->tx.guard_phase_rate, s->tx.guard_tone_gain, 0);
         }
+        /* Don't bother saturating. We should never clip. */
+        amp[sample] = iamp;
+#else
+        /* Root raised cosine pulse shaping at baseband */
+        x.re = vec_circular_dot_prodf(s->tx.rrc_filter_re, tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->tx.baud_phase], V22BIS_TX_FILTER_STEPS, s->tx.rrc_filter_step);
+        x.im = vec_circular_dot_prodf(s->tx.rrc_filter_im, tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->tx.baud_phase], V22BIS_TX_FILTER_STEPS, s->tx.rrc_filter_step);
         /* Now create and modulate the carrier */
         z = dds_complexf(&s->tx.carrier_phase, s->tx.carrier_phase_rate);
         famp = (x.re*z.re - x.im*z.im)*s->tx.gain;
-        if (s->tx.guard_phase_rate  &&  (s->tx.rrc_filter[s->tx.rrc_filter_step].re != 0.0f  ||  s->tx.rrc_filter[s->tx.rrc_filter_step].im != 0.0f))
+        if (s->tx.guard_phase_rate  &&  (s->tx.rrc_filter_re[s->tx.rrc_filter_step] != 0.0f  ||  s->tx.rrc_filter_im[s->tx.rrc_filter_step] != 0.0f))
         {
             /* Add the guard tone */
             famp += dds_modf(&s->tx.guard_phase, s->tx.guard_phase_rate, s->tx.guard_tone_gain, 0);
         }
         /* Don't bother saturating. We should never clip. */
         amp[sample] = (int16_t) lfastrintf(famp);
+#endif
     }
     return sample;
 }
@@ -483,34 +527,49 @@ SPAN_DECLARE_NONSTD(int) v22bis_tx(v22bis_state_t *s, int16_t amp[], int len)
 
 SPAN_DECLARE(void) v22bis_tx_power(v22bis_state_t *s, float power)
 {
-    float l;
+    float sig_power;
+    float guard_tone_power;
+    float sig_gain;
+    float guard_tone_gain;
 
+    /* If is there is a guard tone we need to scale down the signal power a bit, so the aggregate of the signal
+       and guard tone power is the specified power. */
     if (s->tx.guard_phase_rate == dds_phase_ratef(550.0f))
     {
-        l = 1.6f*powf(10.0f, (power - 1.0f - DBM0_MAX_POWER)/20.0f);
-        s->tx.gain = l*32768.0f/(TX_PULSESHAPER_GAIN*3.0f);
-        l = powf(10.0f, (power - 1.0f - 3.0f - DBM0_MAX_POWER)/20.0f);
-        s->tx.guard_tone_gain = l*32768.0f;
+        sig_power = power - 1.0f;
+        guard_tone_power = sig_power - 3.0f;
     }
     else if(s->tx.guard_phase_rate == dds_phase_ratef(1800.0f))
     {
-        l = 1.6f*powf(10.0f, (power - 1.0f - 1.0f - DBM0_MAX_POWER)/20.0f);
-        s->tx.gain = l*32768.0f/(TX_PULSESHAPER_GAIN*3.0f);
-        l = powf(10.0f, (power - 1.0f - 6.0f - DBM0_MAX_POWER)/20.0f);
-        s->tx.guard_tone_gain = l*32768.0f;
+        sig_power = power - 0.55f;
+        guard_tone_power = sig_power - 6.0f;
     }
     else
     {
-        l = 1.6f*powf(10.0f, (power - DBM0_MAX_POWER)/20.0f);
-        s->tx.gain = l*32768.0f/(TX_PULSESHAPER_GAIN*3.0f);
-        s->tx.guard_tone_gain = 0;
+        sig_power = power;
+        guard_tone_power = -9999.0f;
     }
+    sig_gain = 0.4490f*powf(10.0f, (sig_power - DBM0_MAX_POWER)/20.0f)*32768.0f/TX_PULSESHAPER_GAIN;
+    guard_tone_gain = powf(10.0f, (guard_tone_power - DBM0_MAX_POWER)/20.0f)*32768.0f;
+#if defined(SPANDSP_USE_FIXED_POINTx)
+    s->tx.gain = (int16_t) sig_gain;
+    s->tx.guard_tone_gain = (int16_t) guard_tone_gain;
+#else
+    s->tx.gain = sig_gain;
+    s->tx.guard_tone_gain = guard_tone_gain;
+#endif
 }
 /*- End of function --------------------------------------------------------*/
 
 static int v22bis_tx_restart(v22bis_state_t *s)
 {
-    cvec_zerof(s->tx.rrc_filter, sizeof(s->tx.rrc_filter)/sizeof(s->tx.rrc_filter[0]));
+#if defined(SPANDSP_USE_FIXED_POINTx)
+    vec_zeroi16(s->tx.rrc_filter_re, sizeof(s->tx.rrc_filter_re)/sizeof(s->tx.rrc_filter_re[0]));
+    vec_zeroi16(s->tx.rrc_filter_im, sizeof(s->tx.rrc_filter_im)/sizeof(s->tx.rrc_filter_im[0]));
+#else
+    vec_zerof(s->tx.rrc_filter_re, sizeof(s->tx.rrc_filter_re)/sizeof(s->tx.rrc_filter_re[0]));
+    vec_zerof(s->tx.rrc_filter_im, sizeof(s->tx.rrc_filter_im)/sizeof(s->tx.rrc_filter_im[0]));
+#endif
     s->tx.rrc_filter_step = 0;
     s->tx.scramble_reg = 0;
     s->tx.scrambler_pattern_count = 0;
index f2673444ee29b91a6d9d16b98a51477762f05a95..99d534e25c989d1c5a8c84a6dbc043a050a30fe1 100644 (file)
@@ -247,13 +247,16 @@ static complexf_t getbaud(v27ter_tx_state_t *s)
 SPAN_DECLARE_NONSTD(int) v27ter_tx(v27ter_tx_state_t *s, int16_t amp[], int len)
 {
 #if defined(SPANDSP_USE_FIXED_POINT)
-    complexi_t x;
-    complexi_t z;
+    complexi16_t v;
+    complexi32_t x;
+    complexi32_t z;
+    int16_t iamp;
 #else
+    complexf_t v;
     complexf_t x;
     complexf_t z;
+    float famp;
 #endif
-    int i;
     int sample;
 
     if (s->training_step >= V27TER_TRAINING_SHUTDOWN_END)
@@ -271,37 +274,30 @@ SPAN_DECLARE_NONSTD(int) v27ter_tx(v27ter_tx_state_t *s, int16_t amp[], int len)
             if (++s->baud_phase >= 5)
             {
                 s->baud_phase -= 5;
-                s->rrc_filter[s->rrc_filter_step] =
-                s->rrc_filter[s->rrc_filter_step + V27TER_TX_FILTER_STEPS] = getbaud(s);
+                v = getbaud(s);;
+                s->rrc_filter_re[s->rrc_filter_step] = v.re;
+                s->rrc_filter_im[s->rrc_filter_step] = v.im;
                 if (++s->rrc_filter_step >= V27TER_TX_FILTER_STEPS)
                     s->rrc_filter_step = 0;
             }
-            /* Root raised cosine pulse shaping at baseband */
 #if defined(SPANDSP_USE_FIXED_POINT)
-            x = complex_seti(0, 0);
-            for (i = 0;  i < V27TER_TX_FILTER_STEPS;  i++)
-            {
-                x.re += (int32_t) tx_pulseshaper_4800[TX_PULSESHAPER_4800_COEFF_SETS - 1 - s->baud_phase][i]*(int32_t) s->rrc_filter[i + s->rrc_filter_step].re;
-                x.im += (int32_t) tx_pulseshaper_4800[TX_PULSESHAPER_4800_COEFF_SETS - 1 - s->baud_phase][i]*(int32_t) s->rrc_filter[i + s->rrc_filter_step].im;
-            }
+            /* Root raised cosine pulse shaping at baseband */
+            x.re = vec_circular_dot_prodi16(s->rrc_filter_re, tx_pulseshaper_4800[TX_PULSESHAPER_4800_COEFF_SETS - 1 - s->baud_phase], V27TER_TX_FILTER_STEPS, s->rrc_filter_step) >> (10 + 4);
+            x.im = vec_circular_dot_prodi16(s->rrc_filter_im, tx_pulseshaper_4800[TX_PULSESHAPER_4800_COEFF_SETS - 1 - s->baud_phase], V27TER_TX_FILTER_STEPS, s->rrc_filter_step) >> (10 + 4);
             /* Now create and modulate the carrier */
-            x.re >>= 14;
-            x.im >>= 14;
-            z = dds_complexi(&(s->carrier_phase), s->carrier_phase_rate);
+            z = dds_complexi32(&s->carrier_phase, s->carrier_phase_rate);
+            iamp = ((int32_t) x.re*z.re - x.im*z.im) >> 15;
             /* Don't bother saturating. We should never clip. */
-            i = (x.re*z.re - x.im*z.im) >> 15;
-            amp[sample] = (int16_t) ((i*s->gain_4800) >> 15);
+            amp[sample] = (int16_t) (((int32_t) iamp*s->gain_4800) >> 11);
 #else
-            x = complex_setf(0.0f, 0.0f);
-            for (i = 0;  i < V27TER_TX_FILTER_STEPS;  i++)
-            {
-                x.re += tx_pulseshaper_4800[TX_PULSESHAPER_4800_COEFF_SETS - 1 - s->baud_phase][i]*s->rrc_filter[i + s->rrc_filter_step].re;
-                x.im += tx_pulseshaper_4800[TX_PULSESHAPER_4800_COEFF_SETS - 1 - s->baud_phase][i]*s->rrc_filter[i + s->rrc_filter_step].im;
-            }
+            /* Root raised cosine pulse shaping at baseband */
+            x.re = vec_circular_dot_prodf(s->rrc_filter_re, tx_pulseshaper_4800[TX_PULSESHAPER_4800_COEFF_SETS - 1 - s->baud_phase], V27TER_TX_FILTER_STEPS, s->rrc_filter_step);
+            x.im = vec_circular_dot_prodf(s->rrc_filter_im, tx_pulseshaper_4800[TX_PULSESHAPER_4800_COEFF_SETS - 1 - s->baud_phase], V27TER_TX_FILTER_STEPS, s->rrc_filter_step);
             /* Now create and modulate the carrier */
-            z = dds_complexf(&(s->carrier_phase), s->carrier_phase_rate);
+            z = dds_complexf(&s->carrier_phase, s->carrier_phase_rate);
+            famp = x.re*z.re - x.im*z.im;
             /* Don't bother saturating. We should never clip. */
-            amp[sample] = (int16_t) lfastrintf((x.re*z.re - x.im*z.im)*s->gain_4800);
+            amp[sample] = (int16_t) lfastrintf(famp*s->gain_4800);
 #endif
         }
     }
@@ -312,37 +308,30 @@ SPAN_DECLARE_NONSTD(int) v27ter_tx(v27ter_tx_state_t *s, int16_t amp[], int len)
             if ((s->baud_phase += 3) >= 20)
             {
                 s->baud_phase -= 20;
-                s->rrc_filter[s->rrc_filter_step] =
-                s->rrc_filter[s->rrc_filter_step + V27TER_TX_FILTER_STEPS] = getbaud(s);
+                v = getbaud(s);
+                s->rrc_filter_re[s->rrc_filter_step] = v.re;
+                s->rrc_filter_im[s->rrc_filter_step] = v.im;
                 if (++s->rrc_filter_step >= V27TER_TX_FILTER_STEPS)
                     s->rrc_filter_step = 0;
             }
-            /* Root raised cosine pulse shaping at baseband */
 #if defined(SPANDSP_USE_FIXED_POINT)
-            x = complex_seti(0, 0);
-            for (i = 0;  i < V27TER_TX_FILTER_STEPS;  i++)
-            {
-                x.re += (int32_t) tx_pulseshaper_2400[TX_PULSESHAPER_2400_COEFF_SETS - 1 - s->baud_phase][i]*(int32_t) s->rrc_filter[i + s->rrc_filter_step].re;
-                x.im += (int32_t) tx_pulseshaper_2400[TX_PULSESHAPER_2400_COEFF_SETS - 1 - s->baud_phase][i]*(int32_t) s->rrc_filter[i + s->rrc_filter_step].im;
-            }
+            /* Root raised cosine pulse shaping at baseband */
+            x.re = vec_circular_dot_prodi16(s->rrc_filter_re, tx_pulseshaper_2400[TX_PULSESHAPER_2400_COEFF_SETS - 1 - s->baud_phase], V27TER_TX_FILTER_STEPS, s->rrc_filter_step) >> (10 + 4);
+            x.im = vec_circular_dot_prodi16(s->rrc_filter_im, tx_pulseshaper_2400[TX_PULSESHAPER_2400_COEFF_SETS - 1 - s->baud_phase], V27TER_TX_FILTER_STEPS, s->rrc_filter_step) >> (10 + 4);
             /* Now create and modulate the carrier */
-            x.re >>= 14;
-            x.im >>= 14;
-            z = dds_complexi(&(s->carrier_phase), s->carrier_phase_rate);
+            z = dds_complexi32(&s->carrier_phase, s->carrier_phase_rate);
+            iamp = ((int32_t) x.re*z.re - x.im*z.im) >> 15;
             /* Don't bother saturating. We should never clip. */
-            i = (x.re*z.re - x.im*z.im) >> 15;
-            amp[sample] = (int16_t) ((i*s->gain_2400) >> 15);
+            amp[sample] = (int16_t) (((int32_t) iamp*s->gain_2400) >> 11);
 #else
-            x = complex_setf(0.0f, 0.0f);
-            for (i = 0;  i < V27TER_TX_FILTER_STEPS;  i++)
-            {
-                x.re += tx_pulseshaper_2400[TX_PULSESHAPER_2400_COEFF_SETS - 1 - s->baud_phase][i]*s->rrc_filter[i + s->rrc_filter_step].re;
-                x.im += tx_pulseshaper_2400[TX_PULSESHAPER_2400_COEFF_SETS - 1 - s->baud_phase][i]*s->rrc_filter[i + s->rrc_filter_step].im;
-            }
+            /* Root raised cosine pulse shaping at baseband */
+            x.re = vec_circular_dot_prodf(s->rrc_filter_re, tx_pulseshaper_2400[TX_PULSESHAPER_2400_COEFF_SETS - 1 - s->baud_phase], V27TER_TX_FILTER_STEPS, s->rrc_filter_step);
+            x.im = vec_circular_dot_prodf(s->rrc_filter_im, tx_pulseshaper_2400[TX_PULSESHAPER_2400_COEFF_SETS - 1 - s->baud_phase], V27TER_TX_FILTER_STEPS, s->rrc_filter_step);
             /* Now create and modulate the carrier */
-            z = dds_complexf(&(s->carrier_phase), s->carrier_phase_rate);
+            z = dds_complexf(&s->carrier_phase, s->carrier_phase_rate);
+            famp = x.re*z.re - x.im*z.im;
             /* Don't bother saturating. We should never clip. */
-            amp[sample] = (int16_t) lfastrintf((x.re*z.re - x.im*z.im)*s->gain_2400);
+            amp[sample] = (int16_t) lfastrintf(famp*s->gain_2400);
 #endif
         }
     }
@@ -352,15 +341,15 @@ SPAN_DECLARE_NONSTD(int) v27ter_tx(v27ter_tx_state_t *s, int16_t amp[], int len)
 
 SPAN_DECLARE(void) v27ter_tx_power(v27ter_tx_state_t *s, float power)
 {
-    float l;
+    float gain;
 
-    l = powf(10.0f, (power - DBM0_MAX_POWER)/20.0f)*32768.0f;
+    gain = powf(10.0f, (power - DBM0_MAX_POWER)/20.0f)*32768.0f;
 #if defined(SPANDSP_USE_FIXED_POINT)
-    s->gain_2400 = 16.0f*1.024f*(32767.0f/28828.51f)*l/TX_PULSESHAPER_2400_GAIN;
-    s->gain_4800 = 16.0f*1.024f*(32767.0f/28828.46f)*l/TX_PULSESHAPER_4800_GAIN;
+    s->gain_2400 = (int16_t) (gain/TX_PULSESHAPER_2400_GAIN);
+    s->gain_4800 = (int16_t) (gain/TX_PULSESHAPER_4800_GAIN);
 #else
-    s->gain_2400 = l/TX_PULSESHAPER_2400_GAIN;
-    s->gain_4800 = l/TX_PULSESHAPER_4800_GAIN;
+    s->gain_2400 = gain/TX_PULSESHAPER_2400_GAIN;
+    s->gain_4800 = gain/TX_PULSESHAPER_4800_GAIN;
 #endif
 }
 /*- End of function --------------------------------------------------------*/
@@ -393,9 +382,11 @@ SPAN_DECLARE(int) v27ter_tx_restart(v27ter_tx_state_t *s, int bit_rate, int tep)
         return -1;
     s->bit_rate = bit_rate;
 #if defined(SPANDSP_USE_FIXED_POINT)
-    cvec_zeroi16(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
+    vec_zeroi16(s->rrc_filter_re, sizeof(s->rrc_filter_re)/sizeof(s->rrc_filter_re[0]));
+    vec_zeroi16(s->rrc_filter_im, sizeof(s->rrc_filter_im)/sizeof(s->rrc_filter_im[0]));
 #else
-    cvec_zerof(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
+    vec_zerof(s->rrc_filter_re, sizeof(s->rrc_filter_re)/sizeof(s->rrc_filter_re[0]));
+    vec_zerof(s->rrc_filter_im, sizeof(s->rrc_filter_im)/sizeof(s->rrc_filter_im[0]));
 #endif
     s->rrc_filter_step = 0;
     s->scramble_reg = 0x3C;
index 10007a93fb9cca2658a06cfdb12f86ff254eb703..7604ae4ac14c656be05daef4646a7e1c0ae44a68 100644 (file)
@@ -205,13 +205,16 @@ static __inline__ complexf_t getbaud(v29_tx_state_t *s)
 SPAN_DECLARE_NONSTD(int) v29_tx(v29_tx_state_t *s, int16_t amp[], int len)
 {
 #if defined(SPANDSP_USE_FIXED_POINT)
-    complexi_t x;
-    complexi_t z;
+    complexi16_t v;
+    complexi32_t x;
+    complexi32_t z;
+    int16_t iamp;
 #else
+    complexf_t v;
     complexf_t x;
     complexf_t z;
+    float famp;
 #endif
-    int i;
     int sample;
 
     if (s->training_step >= V29_TRAINING_SHUTDOWN_END)
@@ -224,37 +227,30 @@ SPAN_DECLARE_NONSTD(int) v29_tx(v29_tx_state_t *s, int16_t amp[], int len)
         if ((s->baud_phase += 3) >= 10)
         {
             s->baud_phase -= 10;
-            s->rrc_filter[s->rrc_filter_step] =
-            s->rrc_filter[s->rrc_filter_step + V29_TX_FILTER_STEPS] = getbaud(s);
+            v = getbaud(s);
+            s->rrc_filter_re[s->rrc_filter_step] = v.re;
+            s->rrc_filter_im[s->rrc_filter_step] = v.im;
             if (++s->rrc_filter_step >= V29_TX_FILTER_STEPS)
                 s->rrc_filter_step = 0;
         }
-        /* Root raised cosine pulse shaping at baseband */
 #if defined(SPANDSP_USE_FIXED_POINT)
-        x = complex_seti(0, 0);
-        for (i = 0;  i < V29_TX_FILTER_STEPS;  i++)
-        {
-            x.re += (int32_t) tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase][i]*(int32_t) s->rrc_filter[i + s->rrc_filter_step].re;
-            x.im += (int32_t) tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase][i]*(int32_t) s->rrc_filter[i + s->rrc_filter_step].im;
-        }
+        /* Root raised cosine pulse shaping at baseband */
+        x.re = vec_circular_dot_prodi16(s->rrc_filter_re, tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase], V29_TX_FILTER_STEPS, s->rrc_filter_step) >> 4;
+        x.im = vec_circular_dot_prodi16(s->rrc_filter_im, tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase], V29_TX_FILTER_STEPS, s->rrc_filter_step) >> 4;
         /* Now create and modulate the carrier */
-        x.re >>= 4;
-        x.im >>= 4;
-        z = dds_complexi(&(s->carrier_phase), s->carrier_phase_rate);
+        z = dds_complexi32(&s->carrier_phase, s->carrier_phase_rate);
+        iamp = ((int32_t) x.re*z.re - x.im*z.im) >> 15;
         /* Don't bother saturating. We should never clip. */
-        i = (x.re*z.re - x.im*z.im) >> 15;
-        amp[sample] = (int16_t) ((i*s->gain) >> 15);
+        amp[sample] = (int16_t) (((int32_t) iamp*s->gain) >> 11);
 #else
-        x = complex_setf(0.0f, 0.0f);
-        for (i = 0;  i < V29_TX_FILTER_STEPS;  i++)
-        {
-            x.re += tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase][i]*s->rrc_filter[i + s->rrc_filter_step].re;
-            x.im += tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase][i]*s->rrc_filter[i + s->rrc_filter_step].im;
-        }
+        /* Root raised cosine pulse shaping at baseband */
+        x.re = vec_circular_dot_prodf(s->rrc_filter_re, tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase], V29_TX_FILTER_STEPS, s->rrc_filter_step);
+        x.im = vec_circular_dot_prodf(s->rrc_filter_im, tx_pulseshaper[TX_PULSESHAPER_COEFF_SETS - 1 - s->baud_phase], V29_TX_FILTER_STEPS, s->rrc_filter_step);
         /* Now create and modulate the carrier */
-        z = dds_complexf(&(s->carrier_phase), s->carrier_phase_rate);
+        z = dds_complexf(&s->carrier_phase, s->carrier_phase_rate);
+        famp = x.re*z.re - x.im*z.im;
         /* Don't bother saturating. We should never clip. */
-        amp[sample] = (int16_t) lfastrintf((x.re*z.re - x.im*z.im)*s->gain);
+        amp[sample] = (int16_t) lfastrintf(famp*s->gain);
 #endif
     }
     return sample;
@@ -267,13 +263,13 @@ static void set_working_gain(v29_tx_state_t *s)
     switch (s->bit_rate)
     {
     case 9600:
-        s->gain = 0.387f*s->base_gain*16.0f*32767.0f/30672.52f;
+        s->gain = ((int32_t) FP_Q_4_12(0.387f)*s->base_gain) >> 12;
         break;
     case 7200:
-        s->gain = 0.605f*s->base_gain*16.0f*32767.0f/30672.52f;
+        s->gain = ((int32_t) FP_Q_4_12(0.605f)*s->base_gain) >> 12;
         break;
     case 4800:
-        s->gain = 0.470f*s->base_gain*16.0f*32767.0f/30672.52f;
+        s->gain = ((int32_t) FP_Q_4_12(0.470f)*s->base_gain) >> 12;
         break;
     default:
         break;
@@ -299,10 +295,17 @@ static void set_working_gain(v29_tx_state_t *s)
 
 SPAN_DECLARE(void) v29_tx_power(v29_tx_state_t *s, float power)
 {
+    float gain;
+
     /* The constellation does not maintain constant average power as we change bit rates.
        We need to scale the gain we get here by a bit rate specific scaling factor each
        time we restart the modem. */
-    s->base_gain = powf(10.0f, (power - DBM0_MAX_POWER)/20.0f)*32768.0f/TX_PULSESHAPER_GAIN;
+    gain = powf(10.0f, (power - DBM0_MAX_POWER)/20.0f)*32768.0f/TX_PULSESHAPER_GAIN;
+#if defined(SPANDSP_USE_FIXED_POINT)
+    s->base_gain = (int16_t) gain;
+#else
+    s->base_gain = gain;
+#endif
     set_working_gain(s);
 }
 /*- End of function --------------------------------------------------------*/
@@ -349,9 +352,11 @@ SPAN_DECLARE(int) v29_tx_restart(v29_tx_state_t *s, int bit_rate, int tep)
         return -1;
     }
 #if defined(SPANDSP_USE_FIXED_POINT)
-    cvec_zeroi16(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
+    vec_zeroi16(s->rrc_filter_re, sizeof(s->rrc_filter_re)/sizeof(s->rrc_filter_re[0]));
+    vec_zeroi16(s->rrc_filter_im, sizeof(s->rrc_filter_im)/sizeof(s->rrc_filter_im[0]));
 #else
-    cvec_zerof(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
+    vec_zerof(s->rrc_filter_re, sizeof(s->rrc_filter_re)/sizeof(s->rrc_filter_re[0]));
+    vec_zerof(s->rrc_filter_im, sizeof(s->rrc_filter_im)/sizeof(s->rrc_filter_im[0]));
 #endif
     s->rrc_filter_step = 0;
     s->scramble_reg = 0;