|
68 | 68 | #define SPANDSP_USE_FIXED_POINTx |
69 | 69 | #endif |
70 | 70 |
|
| 71 | +#include "spandsp/godard.h" |
71 | 72 | #include "spandsp/v29rx.h" |
72 | 73 | #include "spandsp/v17tx.h" |
73 | 74 | #include "spandsp/v17rx.h" |
74 | 75 |
|
75 | 76 | #include "spandsp/private/logging.h" |
76 | 77 | #include "spandsp/private/power_meter.h" |
| 78 | +#include "spandsp/private/godard.h" |
77 | 79 | #include "spandsp/private/v17rx.h" |
78 | 80 |
|
79 | 81 | #if defined(SPANDSP_USE_FIXED_POINTx) |
|
101 | 103 | #include "v17_v32bis_rx_rrc.h" |
102 | 104 | #include "v17_v32bis_tx_constellation_maps.h" |
103 | 105 | #include "v17_v32bis_rx_constellation_maps.h" |
| 106 | +#include "v17_v32bis_rx_godard.h" |
104 | 107 |
|
105 | 108 | /*! The nominal frequency of the carrier, in Hertz */ |
106 | 109 | #define CARRIER_NOMINAL_FREQ 1800.0f |
|
128 | 131 | /*! The 16 bit pattern used in the bridge section of the training sequence */ |
129 | 132 | #define V17_BRIDGE_WORD 0x8880 |
130 | 133 |
|
131 | | -/* Coefficients for the band edge symbol timing synchroniser (alpha = 0.99) */ |
132 | | -/* low_edge = 2.0f*M_PI*(CARRIER_NOMINAL_FREQ - BAUD_RATE/2.0f)/SAMPLE_RATE; */ |
133 | | -/* high_edge = 2.0f*M_PI*(CARRIER_NOMINAL_FREQ + BAUD_RATE/2.0f)/SAMPLE_RATE; */ |
134 | | -#define SIN_LOW_BAND_EDGE 0.453990499f |
135 | | -#define COS_LOW_BAND_EDGE 0.891006542f |
136 | | -#define SIN_HIGH_BAND_EDGE 0.707106781f |
137 | | -#define COS_HIGH_BAND_EDGE -0.707106781f |
138 | | -#define ALPHA 0.99f |
139 | | - |
140 | | -#define SYNC_LOW_BAND_EDGE_COEFF_0 FP_SYNC_SCALE(2.0f*ALPHA*COS_LOW_BAND_EDGE) |
141 | | -#define SYNC_LOW_BAND_EDGE_COEFF_1 FP_SYNC_SCALE(-ALPHA*ALPHA) |
142 | | -#define SYNC_LOW_BAND_EDGE_COEFF_2 FP_SYNC_SCALE(-ALPHA*SIN_LOW_BAND_EDGE) |
143 | | -#define SYNC_HIGH_BAND_EDGE_COEFF_0 FP_SYNC_SCALE(2.0f*ALPHA*COS_HIGH_BAND_EDGE) |
144 | | -#define SYNC_HIGH_BAND_EDGE_COEFF_1 FP_SYNC_SCALE(-ALPHA*ALPHA) |
145 | | -#define SYNC_HIGH_BAND_EDGE_COEFF_2 FP_SYNC_SCALE(-ALPHA*SIN_HIGH_BAND_EDGE) |
146 | | -#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)) |
147 | | - |
148 | 134 | enum |
149 | 135 | { |
150 | 136 | TRAINING_STAGE_NORMAL_OPERATION = 0, |
@@ -182,7 +168,7 @@ SPAN_DECLARE(float) v17_rx_carrier_frequency(v17_rx_state_t *s) |
182 | 168 |
|
183 | 169 | SPAN_DECLARE(float) v17_rx_symbol_timing_correction(v17_rx_state_t *s) |
184 | 170 | { |
185 | | - return (float) s->total_baud_timing_correction/((float) RX_PULSESHAPER_COEFF_SETS*10.0f/3.0f); |
| 171 | + return (float) godard_ted_correction(&s->godard)/((float) RX_PULSESHAPER_COEFF_SETS*10.0f/3.0f); |
186 | 172 | } |
187 | 173 | /*- End of function --------------------------------------------------------*/ |
188 | 174 |
|
@@ -603,65 +589,6 @@ static int decode_baud(v17_rx_state_t *s, complexf_t *z) |
603 | 589 | } |
604 | 590 | /*- End of function --------------------------------------------------------*/ |
605 | 591 |
|
606 | | -static __inline__ void symbol_sync(v17_rx_state_t *s) |
607 | | -{ |
608 | | - int i; |
609 | | -#if defined(SPANDSP_USE_FIXED_POINTx) |
610 | | - int32_t v; |
611 | | - int32_t p; |
612 | | -#else |
613 | | - float v; |
614 | | - float p; |
615 | | -#endif |
616 | | - |
617 | | - /* This routine adapts the position of the half baud samples entering the equalizer. */ |
618 | | - |
619 | | - /* This symbol sync scheme is based on the technique first described by Dominique Godard in |
620 | | - Passband Timing Recovery in an All-Digital Modem Receiver |
621 | | - IEEE TRANSACTIONS ON COMMUNICATIONS, VOL. COM-26, NO. 5, MAY 1978 */ |
622 | | - |
623 | | - /* This is slightly rearranged from figure 3b of the Godard paper, as this saves a couple of |
624 | | - maths operations */ |
625 | | -#if defined(SPANDSP_USE_FIXED_POINTx) |
626 | | - /* TODO: The scalings used here need more thorough evaluation, to see if overflows are possible. */ |
627 | | - /* Cross correlate */ |
628 | | - 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 |
629 | | - - (((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 |
630 | | - + (((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; |
631 | | - /* Filter away any DC component */ |
632 | | - p = v - s->symbol_sync_dc_filter[1]; |
633 | | - s->symbol_sync_dc_filter[1] = s->symbol_sync_dc_filter[0]; |
634 | | - s->symbol_sync_dc_filter[0] = v; |
635 | | - /* A little integration will now filter away much of the HF noise */ |
636 | | - s->baud_phase -= p; |
637 | | - v = labs(s->baud_phase); |
638 | | -#else |
639 | | - /* Cross correlate */ |
640 | | - v = s->symbol_sync_low[1]*s->symbol_sync_high[0]*SYNC_LOW_BAND_EDGE_COEFF_2 |
641 | | - - s->symbol_sync_low[0]*s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_2 |
642 | | - + s->symbol_sync_low[1]*s->symbol_sync_high[1]*SYNC_MIXED_EDGES_COEFF_3; |
643 | | - /* Filter away any DC component */ |
644 | | - p = v - s->symbol_sync_dc_filter[1]; |
645 | | - s->symbol_sync_dc_filter[1] = s->symbol_sync_dc_filter[0]; |
646 | | - s->symbol_sync_dc_filter[0] = v; |
647 | | - /* A little integration will now filter away much of the HF noise */ |
648 | | - s->baud_phase -= p; |
649 | | - v = fabsf(s->baud_phase); |
650 | | -#endif |
651 | | - if (v > FP_SYNC_SCALE_32(100.0f)) |
652 | | - { |
653 | | - i = (v > FP_SYNC_SCALE_32(1000.0f)) ? 15 : 1; |
654 | | - if (s->baud_phase < FP_SYNC_SCALE_32(0.0f)) |
655 | | - i = -i; |
656 | | - /*endif*/ |
657 | | - //printf("v = %10.5f %5d - %f %f %d\n", v, i, p, s->baud_phase, s->total_baud_timing_correction); |
658 | | - s->eq_put_step += i; |
659 | | - s->total_baud_timing_correction += i; |
660 | | - } |
661 | | - /*endif*/ |
662 | | -} |
663 | | -/*- End of function --------------------------------------------------------*/ |
664 | | - |
665 | 592 | #if defined(SPANDSP_USE_FIXED_POINTx) |
666 | 593 | static void process_half_baud(v17_rx_state_t *s, const complexi16_t *sample) |
667 | 594 | #else |
@@ -714,7 +641,7 @@ static void process_half_baud(v17_rx_state_t *s, const complexf_t *sample) |
714 | 641 | /*endif*/ |
715 | 642 |
|
716 | 643 | /* Symbol timing synchronisation */ |
717 | | - symbol_sync(s); |
| 644 | + s->eq_put_step += godard_ted_per_baud(&s->godard); |
718 | 645 |
|
719 | 646 | z = equalizer_get(s); |
720 | 647 |
|
@@ -1330,32 +1257,11 @@ SPAN_DECLARE(int) v17_rx(v17_rx_state_t *s, const int16_t amp[], int len) |
1330 | 1257 | #if defined(SPANDSP_USE_FIXED_POINTx) |
1331 | 1258 | v = vec_circular_dot_prodi16(s->rrc_filter, rx_pulseshaper_re[step], V17_RX_FILTER_STEPS, s->rrc_filter_step) >> 15; |
1332 | 1259 | sample.re = (v*s->agc_scaling) >> 10; |
1333 | | - /* Symbol timing synchronisation band edge filters */ |
1334 | | - /* Low Nyquist band edge filter */ |
1335 | | - v = ((s->symbol_sync_low[0]*SYNC_LOW_BAND_EDGE_COEFF_0) >> FP_SYNC_SHIFT_FACTOR) |
1336 | | - + ((s->symbol_sync_low[1]*SYNC_LOW_BAND_EDGE_COEFF_1) >> FP_SYNC_SHIFT_FACTOR) |
1337 | | - + sample.re; |
1338 | | - s->symbol_sync_low[1] = s->symbol_sync_low[0]; |
1339 | | - s->symbol_sync_low[0] = v; |
1340 | | - /* High Nyquist band edge filter */ |
1341 | | - v = ((s->symbol_sync_high[0]*SYNC_HIGH_BAND_EDGE_COEFF_0) >> FP_SYNC_SHIFT_FACTOR) |
1342 | | - + ((s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_1) >> FP_SYNC_SHIFT_FACTOR) |
1343 | | - + sample.re; |
1344 | | - s->symbol_sync_high[1] = s->symbol_sync_high[0]; |
1345 | | - s->symbol_sync_high[0] = v; |
1346 | 1260 | #else |
1347 | 1261 | v = vec_circular_dot_prodf(s->rrc_filter, rx_pulseshaper_re[step], V17_RX_FILTER_STEPS, s->rrc_filter_step); |
1348 | 1262 | sample.re = v*s->agc_scaling; |
1349 | | - /* Symbol timing synchronisation band edge filters */ |
1350 | | - /* Low Nyquist band edge filter */ |
1351 | | - 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; |
1352 | | - s->symbol_sync_low[1] = s->symbol_sync_low[0]; |
1353 | | - s->symbol_sync_low[0] = v; |
1354 | | - /* High Nyquist band edge filter */ |
1355 | | - 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; |
1356 | | - s->symbol_sync_high[1] = s->symbol_sync_high[0]; |
1357 | | - s->symbol_sync_high[0] = v; |
1358 | 1263 | #endif |
| 1264 | + godard_ted_rx(&s->godard, sample.re); |
1359 | 1265 | /* Put things into the equalization buffer at T/2 rate. The symbol synchronisation |
1360 | 1266 | will fiddle the step to align this with the symbols. */ |
1361 | 1267 | if (s->eq_put_step <= 0) |
@@ -1569,18 +1475,9 @@ SPAN_DECLARE(int) v17_rx_restart(v17_rx_state_t *s, int bit_rate, int short_trai |
1569 | 1475 | span_log(&s->logging, SPAN_LOG_FLOW, "Gains %f %f\n", (float) s->agc_scaling_save, (float) s->agc_scaling); |
1570 | 1476 | 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)); |
1571 | 1477 |
|
1572 | | - /* Initialise the working data for symbol timing synchronisation */ |
1573 | | - for (i = 0; i < 2; i++) |
1574 | | - { |
1575 | | - s->symbol_sync_low[i] = FP_SCALE(0.0f); |
1576 | | - s->symbol_sync_high[i] = FP_SCALE(0.0f); |
1577 | | - s->symbol_sync_dc_filter[i] = FP_SCALE(0.0f); |
1578 | | - } |
1579 | | - /*endfor*/ |
1580 | | - s->baud_phase = FP_SCALE(0.0f); |
1581 | | - s->baud_half = 0; |
| 1478 | + godard_ted_init(&s->godard, &godard_desc); |
1582 | 1479 |
|
1583 | | - s->total_baud_timing_correction = 0; |
| 1480 | + s->baud_half = 0; |
1584 | 1481 |
|
1585 | 1482 | return 0; |
1586 | 1483 | } |
|
0 commit comments