Skip to content

Commit

Permalink
V.29 and V.17 now use the Godard TED module, and their internal Godar…
Browse files Browse the repository at this point in the history
…d TED code has been removed.o
  • Loading branch information
coppice-git committed Mar 28, 2024
1 parent 39cd63d commit 933d40d
Show file tree
Hide file tree
Showing 10 changed files with 42 additions and 284 deletions.
2 changes: 2 additions & 0 deletions src/fax.c
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@
#include "spandsp/fsk.h"
#include "spandsp/modem_connect_tones.h"
#include "spandsp/v8.h"
#include "spandsp/godard.h"
#include "spandsp/v29tx.h"
#include "spandsp/v29rx.h"
#include "spandsp/v27ter_tx.h"
Expand Down Expand Up @@ -111,6 +112,7 @@
#include "spandsp/private/fsk.h"
#include "spandsp/private/modem_connect_tones.h"
#include "spandsp/private/v8.h"
#include "spandsp/private/godard.h"
#if defined(SPANDSP_SUPPORT_V34)
#include "spandsp/private/bitstream.h"
#include "spandsp/private/v34.h"
Expand Down
2 changes: 2 additions & 0 deletions src/fax_modems.c
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,7 @@
#include "spandsp/hdlc.h"
#include "spandsp/silence_gen.h"
#include "spandsp/fsk.h"
#include "spandsp/godard.h"
#include "spandsp/v29tx.h"
#include "spandsp/v29rx.h"
#include "spandsp/v27ter_tx.h"
Expand All @@ -88,6 +89,7 @@
#include "spandsp/private/power_meter.h"
#include "spandsp/private/modem_echo.h"
#include "spandsp/private/fsk.h"
#include "spandsp/private/godard.h"
#if defined(SPANDSP_SUPPORT_V34)
#include "spandsp/private/v34.h"
#endif
Expand Down
10 changes: 5 additions & 5 deletions src/make_modem_godard_descriptor.c
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
/*
* SpanDSP - a series of DSP components for telephony
*
* make_modem_godard_coefficients.c - Create coefficient sets for Godard
* symbol sync. filters as a pair of
* fixed and floating point descriptor
* structures for spandsp.
* make_modem_godard_descriptor.c - Create coefficient sets for Godard
* symbol sync. filters as a pair of
* fixed and floating point descriptor
* structures for spandsp.
*
* Written by Steve Underwood <steveu@coppice.org>
*
Expand Down Expand Up @@ -154,7 +154,7 @@ int main(int argc, char **argv)
printf(" FILE MAY BE OVERWRITTEN DURING FUTURE BUILDS OF THE SOFTWARE */\n");
printf("\n");
printf("\n");
printf("static const godard_timing_sync_descriptor_t godard_desc =\n");
printf("static const godard_ted_descriptor_t godard_desc =\n");
printf("{\n");
printf(" /* %.1f samples/second , %.1fHz carrier, %.1f baud, %.3f alpha */\n",
sample_rate,
Expand Down
24 changes: 2 additions & 22 deletions src/spandsp/private/v17rx.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,15 +86,6 @@ struct v17_rx_state_s
/*! \brief The equalizer signal buffer. */
complexi16_t eq_buf[V17_EQUALIZER_LEN];

/*! Low band edge filter for symbol sync. */
int32_t symbol_sync_low[2];
/*! High band edge filter for symbol sync. */
int32_t symbol_sync_high[2];
/*! DC filter for symbol sync. */
int32_t symbol_sync_dc_filter[2];
/*! Baud phase for symbol sync. */
int32_t baud_phase;

/*! \brief A measure of how much mismatch there is between the real constellation,
and the decoded symbol positions. */
int64_t training_error;
Expand Down Expand Up @@ -123,15 +114,6 @@ struct v17_rx_state_s
/*! \brief The equalizer signal buffer. */
complexf_t eq_buf[V17_EQUALIZER_LEN];

/*! Low band edge filter for symbol sync. */
float symbol_sync_low[2];
/*! High band edge filter for symbol sync. */
float symbol_sync_high[2];
/*! DC filter for symbol sync. */
float symbol_sync_dc_filter[2];
/*! Baud phase for symbol sync. */
float baud_phase;

/*! \brief A measure of how much mismatch there is between the real constellation,
and the decoded symbol positions. */
float training_error;
Expand All @@ -146,6 +128,8 @@ struct v17_rx_state_s
/*! \brief A pointer to the current constellation. */
const complexf_t *constellation;
#endif
godard_ted_state_t godard;

/*! \brief Current offset into the RRC pulse shaping filter buffer. */
int rrc_filter_step;

Expand Down Expand Up @@ -197,10 +181,6 @@ struct v17_rx_state_s
/*! \brief The current half of the baud. */
int baud_half;

/*! \brief The total symbol timing correction since the carrier came up.
This is only for performance analysis purposes. */
int total_baud_timing_correction;

/*! \brief The previous symbol phase angles for the coarse carrier aquisition step. */
int32_t last_angles[2];
/*! \brief History list of phase angle differences for the coarse carrier aquisition step. */
Expand Down
24 changes: 2 additions & 22 deletions src/spandsp/private/v29rx.h
Original file line number Diff line number Diff line change
Expand Up @@ -76,15 +76,6 @@ struct v29_rx_state_s
/*! \brief The equalizer signal buffer. */
complexi16_t eq_buf[V29_EQUALIZER_LEN];

/*! Low band edge filter for symbol sync. */
int32_t symbol_sync_low[2];
/*! High band edge filter for symbol sync. */
int32_t symbol_sync_high[2];
/*! DC filter for symbol sync. */
int32_t symbol_sync_dc_filter[2];
/*! Baud phase for symbol sync. */
int32_t baud_phase;

/*! \brief A measure of how much mismatch there is between the real constellation,
and the decoded symbol positions. */
int32_t training_error;
Expand All @@ -110,15 +101,6 @@ struct v29_rx_state_s
/*! \brief The equalizer signal buffer. */
complexf_t eq_buf[V29_EQUALIZER_LEN];

/*! Low band edge filter for symbol sync. */
float symbol_sync_low[2];
/*! High band edge filter for symbol sync. */
float symbol_sync_high[2];
/*! DC filter for symbol sync. */
float symbol_sync_dc_filter[2];
/*! Baud phase for symbol sync. */
float baud_phase;

/*! \brief A measure of how much mismatch there is between the real constellation,
and the decoded symbol positions. */
float training_error;
Expand All @@ -130,6 +112,8 @@ struct v29_rx_state_s
/*! \brief The root raised cosine (RRC) pulse shaping filter buffer. */
float rrc_filter[V29_RX_FILTER_STEPS];
#endif
godard_ted_state_t godard;

/*! \brief Current offset into the RRC pulse shaping filter buffer. */
int rrc_filter_step;

Expand Down Expand Up @@ -180,10 +164,6 @@ struct v29_rx_state_s
/*! \brief The current half of the baud. */
int baud_half;

/*! \brief The total symbol timing correction since the carrier came up.
This is only for performance analysis purposes. */
int total_baud_timing_correction;

/*! \brief The previous symbol phase angles for the coarse carrier aquisition step. */
int32_t last_angles[2];
/*! \brief History list of phase angle differences for the coarse carrier aquisition step. */
Expand Down
2 changes: 2 additions & 0 deletions src/t31.c
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
#include "spandsp/super_tone_rx.h"
#include "spandsp/fsk.h"
#include "spandsp/modem_connect_tones.h"
#include "spandsp/godard.h"
#include "spandsp/v8.h"
#include "spandsp/v29tx.h"
#include "spandsp/v29rx.h"
Expand Down Expand Up @@ -106,6 +107,7 @@
#include "spandsp/private/fsk.h"
#include "spandsp/private/modem_connect_tones.h"
#include "spandsp/private/v8.h"
#include "spandsp/private/godard.h"
#if defined(SPANDSP_SUPPORT_V34)
#include "spandsp/private/v34.h"
#endif
Expand Down
2 changes: 2 additions & 0 deletions src/t38_gateway.c
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@
#include "spandsp/ssl_fax.h"
#include "spandsp/silence_gen.h"
#include "spandsp/fsk.h"
#include "spandsp/godard.h"
#include "spandsp/v29tx.h"
#include "spandsp/v29rx.h"
#include "spandsp/v27ter_tx.h"
Expand Down Expand Up @@ -109,6 +110,7 @@
#include "spandsp/private/silence_gen.h"
#include "spandsp/private/power_meter.h"
#include "spandsp/private/fsk.h"
#include "spandsp/private/godard.h"
#if defined(SPANDSP_SUPPORT_V34)
#include "spandsp/private/bitstream.h"
#include "spandsp/private/v34.h"
Expand Down
119 changes: 8 additions & 111 deletions src/v17rx.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,12 +68,14 @@
#define SPANDSP_USE_FIXED_POINTx
#endif

#include "spandsp/godard.h"
#include "spandsp/v29rx.h"
#include "spandsp/v17tx.h"
#include "spandsp/v17rx.h"

#include "spandsp/private/logging.h"
#include "spandsp/private/power_meter.h"
#include "spandsp/private/godard.h"
#include "spandsp/private/v17rx.h"

#if defined(SPANDSP_USE_FIXED_POINTx)
Expand Down Expand Up @@ -101,6 +103,7 @@
#include "v17_v32bis_rx_rrc.h"
#include "v17_v32bis_tx_constellation_maps.h"
#include "v17_v32bis_rx_constellation_maps.h"
#include "v17_v32bis_rx_godard.h"

/*! The nominal frequency of the carrier, in Hertz */
#define CARRIER_NOMINAL_FREQ 1800.0f
Expand Down Expand Up @@ -128,23 +131,6 @@
/*! The 16 bit pattern used in the bridge section of the training sequence */
#define V17_BRIDGE_WORD 0x8880

/* Coefficients for the band edge symbol timing synchroniser (alpha = 0.99) */
/* low_edge = 2.0f*M_PI*(CARRIER_NOMINAL_FREQ - BAUD_RATE/2.0f)/SAMPLE_RATE; */
/* high_edge = 2.0f*M_PI*(CARRIER_NOMINAL_FREQ + BAUD_RATE/2.0f)/SAMPLE_RATE; */
#define SIN_LOW_BAND_EDGE 0.453990499f
#define COS_LOW_BAND_EDGE 0.891006542f
#define SIN_HIGH_BAND_EDGE 0.707106781f
#define COS_HIGH_BAND_EDGE -0.707106781f
#define ALPHA 0.99f

#define SYNC_LOW_BAND_EDGE_COEFF_0 FP_SYNC_SCALE(2.0f*ALPHA*COS_LOW_BAND_EDGE)
#define SYNC_LOW_BAND_EDGE_COEFF_1 FP_SYNC_SCALE(-ALPHA*ALPHA)
#define SYNC_LOW_BAND_EDGE_COEFF_2 FP_SYNC_SCALE(-ALPHA*SIN_LOW_BAND_EDGE)
#define SYNC_HIGH_BAND_EDGE_COEFF_0 FP_SYNC_SCALE(2.0f*ALPHA*COS_HIGH_BAND_EDGE)
#define SYNC_HIGH_BAND_EDGE_COEFF_1 FP_SYNC_SCALE(-ALPHA*ALPHA)
#define SYNC_HIGH_BAND_EDGE_COEFF_2 FP_SYNC_SCALE(-ALPHA*SIN_HIGH_BAND_EDGE)
#define SYNC_MIXED_EDGES_COEFF_3 FP_SYNC_SCALE(-ALPHA*ALPHA*(SIN_HIGH_BAND_EDGE*COS_LOW_BAND_EDGE - SIN_LOW_BAND_EDGE*COS_HIGH_BAND_EDGE))

enum
{
TRAINING_STAGE_NORMAL_OPERATION = 0,
Expand Down Expand Up @@ -182,7 +168,7 @@ SPAN_DECLARE(float) v17_rx_carrier_frequency(v17_rx_state_t *s)

SPAN_DECLARE(float) v17_rx_symbol_timing_correction(v17_rx_state_t *s)
{
return (float) s->total_baud_timing_correction/((float) RX_PULSESHAPER_COEFF_SETS*10.0f/3.0f);
return (float) godard_ted_correction(&s->godard)/((float) RX_PULSESHAPER_COEFF_SETS*10.0f/3.0f);
}
/*- End of function --------------------------------------------------------*/

Expand Down Expand Up @@ -603,65 +589,6 @@ static int decode_baud(v17_rx_state_t *s, complexf_t *z)
}
/*- End of function --------------------------------------------------------*/

static __inline__ void symbol_sync(v17_rx_state_t *s)
{
int i;
#if defined(SPANDSP_USE_FIXED_POINTx)
int32_t v;
int32_t p;
#else
float v;
float p;
#endif

/* This routine adapts the position of the half baud samples entering the equalizer. */

/* This symbol sync scheme is based on the technique first described by Dominique Godard in
Passband Timing Recovery in an All-Digital Modem Receiver
IEEE TRANSACTIONS ON COMMUNICATIONS, VOL. COM-26, NO. 5, MAY 1978 */

/* This is slightly rearranged from figure 3b of the Godard paper, as this saves a couple of
maths operations */
#if defined(SPANDSP_USE_FIXED_POINTx)
/* TODO: The scalings used here need more thorough evaluation, to see if overflows are possible. */
/* Cross correlate */
v = (((s->symbol_sync_low[1] >> (FP_SYNC_SHIFT_FACTOR/2))*(s->symbol_sync_high[0] >> (FP_SYNC_SHIFT_FACTOR/2))) >> 14)*SYNC_LOW_BAND_EDGE_COEFF_2
- (((s->symbol_sync_low[0] >> (FP_SYNC_SHIFT_FACTOR/2))*(s->symbol_sync_high[1] >> (FP_SYNC_SHIFT_FACTOR/2))) >> 14)*SYNC_HIGH_BAND_EDGE_COEFF_2
+ (((s->symbol_sync_low[1] >> (FP_SYNC_SHIFT_FACTOR/2))*(s->symbol_sync_high[1] >> (FP_SYNC_SHIFT_FACTOR/2))) >> 14)*SYNC_MIXED_EDGES_COEFF_3;
/* 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;
/* A little integration will now filter away much of the HF noise */
s->baud_phase -= p;
v = labs(s->baud_phase);
#else
/* Cross correlate */
v = s->symbol_sync_low[1]*s->symbol_sync_high[0]*SYNC_LOW_BAND_EDGE_COEFF_2
- s->symbol_sync_low[0]*s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_2
+ s->symbol_sync_low[1]*s->symbol_sync_high[1]*SYNC_MIXED_EDGES_COEFF_3;
/* 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;
/* A little integration will now filter away much of the HF noise */
s->baud_phase -= p;
v = fabsf(s->baud_phase);
#endif
if (v > FP_SYNC_SCALE_32(100.0f))
{
i = (v > FP_SYNC_SCALE_32(1000.0f)) ? 15 : 1;
if (s->baud_phase < FP_SYNC_SCALE_32(0.0f))
i = -i;
/*endif*/
//printf("v = %10.5f %5d - %f %f %d\n", v, i, p, s->baud_phase, s->total_baud_timing_correction);
s->eq_put_step += i;
s->total_baud_timing_correction += i;
}
/*endif*/
}
/*- End of function --------------------------------------------------------*/

#if defined(SPANDSP_USE_FIXED_POINTx)
static void process_half_baud(v17_rx_state_t *s, const complexi16_t *sample)
#else
Expand Down Expand Up @@ -714,7 +641,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample)
/*endif*/

/* Symbol timing synchronisation */
symbol_sync(s);
s->eq_put_step += godard_ted_per_baud(&s->godard);

z = equalizer_get(s);

Expand Down Expand Up @@ -1330,32 +1257,11 @@ SPAN_DECLARE(int) v17_rx(v17_rx_state_t *s, const int16_t amp[], int len)
#if defined(SPANDSP_USE_FIXED_POINTx)
v = vec_circular_dot_prodi16(s->rrc_filter, rx_pulseshaper_re[step], V17_RX_FILTER_STEPS, s->rrc_filter_step) >> 15;
sample.re = (v*s->agc_scaling) >> 10;
/* Symbol timing synchronisation band edge filters */
/* Low Nyquist band edge filter */
v = ((s->symbol_sync_low[0]*SYNC_LOW_BAND_EDGE_COEFF_0) >> FP_SYNC_SHIFT_FACTOR)
+ ((s->symbol_sync_low[1]*SYNC_LOW_BAND_EDGE_COEFF_1) >> FP_SYNC_SHIFT_FACTOR)
+ sample.re;
s->symbol_sync_low[1] = s->symbol_sync_low[0];
s->symbol_sync_low[0] = v;
/* High Nyquist band edge filter */
v = ((s->symbol_sync_high[0]*SYNC_HIGH_BAND_EDGE_COEFF_0) >> FP_SYNC_SHIFT_FACTOR)
+ ((s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_1) >> FP_SYNC_SHIFT_FACTOR)
+ sample.re;
s->symbol_sync_high[1] = s->symbol_sync_high[0];
s->symbol_sync_high[0] = v;
#else
v = vec_circular_dot_prodf(s->rrc_filter, rx_pulseshaper_re[step], V17_RX_FILTER_STEPS, s->rrc_filter_step);
sample.re = v*s->agc_scaling;
/* Symbol timing synchronisation band edge filters */
/* Low Nyquist band edge filter */
v = s->symbol_sync_low[0]*SYNC_LOW_BAND_EDGE_COEFF_0 + s->symbol_sync_low[1]*SYNC_LOW_BAND_EDGE_COEFF_1 + sample.re;
s->symbol_sync_low[1] = s->symbol_sync_low[0];
s->symbol_sync_low[0] = v;
/* High Nyquist band edge filter */
v = s->symbol_sync_high[0]*SYNC_HIGH_BAND_EDGE_COEFF_0 + s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_1 + sample.re;
s->symbol_sync_high[1] = s->symbol_sync_high[0];
s->symbol_sync_high[0] = v;
#endif
godard_ted_rx(&s->godard, sample.re);
/* Put things into the equalization buffer at T/2 rate. The symbol synchronisation
will fiddle the step to align this with the symbols. */
if (s->eq_put_step <= 0)
Expand Down Expand Up @@ -1569,18 +1475,9 @@ SPAN_DECLARE(int) v17_rx_restart(v17_rx_state_t *s, int bit_rate, int short_trai
span_log(&s->logging, SPAN_LOG_FLOW, "Gains %f %f\n", (float) s->agc_scaling_save, (float) s->agc_scaling);
span_log(&s->logging, SPAN_LOG_FLOW, "Phase rates %f %f\n", dds_frequencyf(s->carrier_phase_rate), dds_frequencyf(s->carrier_phase_rate_save));

/* Initialise the working data for symbol timing synchronisation */
for (i = 0; i < 2; i++)
{
s->symbol_sync_low[i] = FP_SCALE(0.0f);
s->symbol_sync_high[i] = FP_SCALE(0.0f);
s->symbol_sync_dc_filter[i] = FP_SCALE(0.0f);
}
/*endfor*/
s->baud_phase = FP_SCALE(0.0f);
s->baud_half = 0;
godard_ted_init(&s->godard, &godard_desc);

s->total_baud_timing_correction = 0;
s->baud_half = 0;

return 0;
}
Expand Down
Loading

0 comments on commit 933d40d

Please sign in to comment.