mirror of
https://github.com/signalwire/freeswitch.git
synced 2026-10-30 15:14:17 +00:00
update spandsp to use newest snapshot http://www.soft-switch.org/downloads/snapshots/spandsp/spandsp-20080910.tar.gz
git-svn-id: http://svn.freeswitch.org/svn/freeswitch/trunk@9493 d0543943-73ff-0310-b7d9-9358b9ac24b2
This commit is contained in:
1 parent
bc5cf34915
commit
ea964d8fe6
79 files changed
+2804
-1642
No files matched your search
+344
-129
@@ -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.124 2008/07/17 19:12:27 steveu Exp $
|
||||
* $Id: v29rx.c,v 1.135 2008/09/09 16:13:12 steveu Exp $
|
||||
*/
|
||||
|
||||
/*! \file */
|
||||
@@ -48,6 +48,8 @@
|
||||
#include "spandsp/complex.h"
|
||||
#include "spandsp/vector_float.h"
|
||||
#include "spandsp/complex_vector_float.h"
|
||||
#include "spandsp/vector_int.h"
|
||||
#include "spandsp/complex_vector_int.h"
|
||||
#include "spandsp/async.h"
|
||||
#include "spandsp/power_meter.h"
|
||||
#include "spandsp/arctan2.h"
|
||||
@@ -67,6 +69,11 @@
|
||||
#define BAUD_RATE 2400
|
||||
#define EQUALIZER_DELTA 0.21f
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
#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
|
||||
@@ -109,13 +116,23 @@ static const uint8_t space_map_9600[20][20] =
|
||||
};
|
||||
|
||||
/* Coefficients for the band edge symbol timing synchroniser (alpha = 0.99) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 1.829281f /* 2*alpha*cos(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 -1.285907f /* 2*alpha*cos(high_edge) */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */
|
||||
#define SYNC_CROSS_CORR_COEFF_A -0.932131f /* -alpha^2*sin(freq_diff) */
|
||||
#define SYNC_CROSS_CORR_COEFF_B 0.752802f /* alpha*sin(high_edge) */
|
||||
#define SYNC_CROSS_CORR_COEFF_C -0.378857f /* -alpha*sin(low_edge) */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR* 1.829281f)) /* 2*alpha*cos(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*-0.980100f)) /* -alpha^2 */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 ((int)(FP_FACTOR*-1.285907f)) /* 2*alpha*cos(high_edge) */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 ((int)(FP_FACTOR*-0.980100f)) /* -alpha^2 */
|
||||
#define SYNC_CROSS_CORR_COEFF_A ((int)(FP_FACTOR*-0.932131f)) /* -alpha^2*sin(freq_diff) */
|
||||
#define SYNC_CROSS_CORR_COEFF_B ((int)(FP_FACTOR* 0.752802f)) /* alpha*sin(high_edge) */
|
||||
#define SYNC_CROSS_CORR_COEFF_C ((int)(FP_FACTOR*-0.378857f)) /* -alpha*sin(low_edge) */
|
||||
#else
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_0 1.829281f /* 2*alpha*cos(low_edge) */
|
||||
#define SYNC_LOW_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_0 -1.285907f /* 2*alpha*cos(high_edge) */
|
||||
#define SYNC_HIGH_BAND_EDGE_COEFF_1 -0.980100f /* -alpha^2 */
|
||||
#define SYNC_CROSS_CORR_COEFF_A -0.932131f /* -alpha^2*sin(freq_diff) */
|
||||
#define SYNC_CROSS_CORR_COEFF_B 0.752802f /* alpha*sin(high_edge) */
|
||||
#define SYNC_CROSS_CORR_COEFF_C -0.378857f /* -alpha*sin(low_edge) */
|
||||
#endif
|
||||
|
||||
float v29_rx_carrier_frequency(v29_rx_state_t *s)
|
||||
{
|
||||
@@ -143,19 +160,17 @@ float v29_rx_signal_power(v29_rx_state_t *s)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
int v29_rx_equalizer_state(v29_rx_state_t *s, complexi16_t **coeffs)
|
||||
#else
|
||||
int v29_rx_equalizer_state(v29_rx_state_t *s, complexf_t **coeffs)
|
||||
#endif
|
||||
{
|
||||
*coeffs = s->eq_coeff;
|
||||
return V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void equalizer_save(v29_rx_state_t *s)
|
||||
{
|
||||
cvec_copyf(s->eq_coeff_save, s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void report_status_change(v29_rx_state_t *s, int status)
|
||||
{
|
||||
if (s->status_handler)
|
||||
@@ -165,51 +180,105 @@ static void report_status_change(v29_rx_state_t *s, int status)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void equalizer_save(v29_rx_state_t *s)
|
||||
{
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
cvec_copyi16(s->eq_coeff_save, s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
#else
|
||||
cvec_copyf(s->eq_coeff_save, s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
#endif
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void equalizer_restore(v29_rx_state_t *s)
|
||||
{
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
cvec_copyi16(s->eq_coeff, s->eq_coeff_save, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
cvec_zeroi16(s->eq_buf, V29_EQUALIZER_MASK);
|
||||
s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
#else
|
||||
cvec_copyf(s->eq_coeff, s->eq_coeff_save, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
cvec_zerof(s->eq_buf, V29_EQUALIZER_MASK);
|
||||
s->eq_delta = EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_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/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void equalizer_reset(v29_rx_state_t *s)
|
||||
{
|
||||
/* Start with an equalizer based on everything being perfect */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
cvec_zeroi16(s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
s->eq_coeff[V29_EQUALIZER_PRE_LEN] = complex_seti16(3*FP_FACTOR, 0*FP_FACTOR);
|
||||
cvec_zeroi16(s->eq_buf, V29_EQUALIZER_MASK);
|
||||
s->eq_delta = 32768.0f*EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
#else
|
||||
cvec_zerof(s->eq_coeff, V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
s->eq_coeff[V29_EQUALIZER_PRE_LEN] = complex_setf(3.0f, 0.0f);
|
||||
cvec_zerof(s->eq_buf, V29_EQUALIZER_MASK);
|
||||
s->eq_delta = EQUALIZER_DELTA/(V29_EQUALIZER_PRE_LEN + 1 + V29_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/(V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN);
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static __inline__ complexi16_t complex_mul_q4_12(const complexi16_t *x, const complexi16_t *y)
|
||||
{
|
||||
complexi16_t z;
|
||||
|
||||
z.re = ((int32_t) x->re*(int32_t) y->re - (int32_t) x->im*(int32_t) y->im) >> 12;
|
||||
z.im = ((int32_t) x->re*(int32_t) y->im + (int32_t) x->im*(int32_t) y->re) >> 12;
|
||||
return z;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
#endif
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static __inline__ complexi16_t equalizer_get(v29_rx_state_t *s)
|
||||
#else
|
||||
static __inline__ complexf_t equalizer_get(v29_rx_state_t *s)
|
||||
#endif
|
||||
{
|
||||
int i;
|
||||
int p;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
complexi16_t z;
|
||||
complexi16_t z1;
|
||||
#else
|
||||
complexf_t z;
|
||||
complexf_t z1;
|
||||
#endif
|
||||
|
||||
/* Get the next equalized value. */
|
||||
z = complex_setf(0.0f, 0.0f);
|
||||
p = s->eq_step - 1;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
z = complex_seti16(0, 0);
|
||||
for (i = 0; i < V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN; i++)
|
||||
{
|
||||
p = (p - 1) & V29_EQUALIZER_MASK;
|
||||
z1 = complex_mul_q4_12(&s->eq_coeff[i], &s->eq_buf[p]);
|
||||
z = complex_addi16(&z, &z1);
|
||||
}
|
||||
#else
|
||||
z = complex_setf(0.0f, 0.0f);
|
||||
for (i = 0; i < V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN; i++)
|
||||
{
|
||||
p = (p - 1) & V29_EQUALIZER_MASK;
|
||||
z1 = complex_mulf(&s->eq_coeff[i], &s->eq_buf[p]);
|
||||
z = complex_addf(&z, &z1);
|
||||
}
|
||||
#endif
|
||||
return z;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTy)
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static void tune_equalizer(v29_rx_state_t *s, const complexi16_t *z, const complexi16_t *target)
|
||||
#else
|
||||
static void tune_equalizer(v29_rx_state_t *s, const complexf_t *z, const complexf_t *target)
|
||||
@@ -217,24 +286,42 @@ static void tune_equalizer(v29_rx_state_t *s, const complexf_t *z, const complex
|
||||
{
|
||||
int i;
|
||||
int p;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
complexi16_t ez;
|
||||
complexi16_t z1;
|
||||
#else
|
||||
complexf_t ez;
|
||||
complexf_t z1;
|
||||
#endif
|
||||
|
||||
/* Find the x and y mismatch from the exact constellation position. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
ez.re = target->re*FP_FACTOR - z->re;
|
||||
ez.im = target->im*FP_FACTOR - z->im;
|
||||
ez.re = ((int32_t) ez.re*(int32_t) s->eq_delta) >> 15;
|
||||
ez.im = ((int32_t) ez.im*(int32_t) s->eq_delta) >> 15;
|
||||
#else
|
||||
ez = complex_subf(target, z);
|
||||
ez.re *= s->eq_delta;
|
||||
ez.im *= s->eq_delta;
|
||||
#endif
|
||||
|
||||
p = s->eq_step - 1;
|
||||
for (i = 0; i < V29_EQUALIZER_PRE_LEN + 1 + V29_EQUALIZER_POST_LEN; i++)
|
||||
{
|
||||
p = (p - 1) & V29_EQUALIZER_MASK;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
z1 = complex_conji16(&s->eq_buf[p]);
|
||||
z1 = complex_mul_q4_12(&ez, &z1);
|
||||
s->eq_coeff[i] = complex_addi16(&s->eq_coeff[i], &z1);
|
||||
#else
|
||||
z1 = complex_conjf(&s->eq_buf[p]);
|
||||
z1 = complex_mulf(&ez, &z1);
|
||||
s->eq_coeff[i] = complex_addf(&s->eq_coeff[i], &z1);
|
||||
/* Leak a little to tame uncontrolled wandering */
|
||||
s->eq_coeff[i].re *= 0.9999f;
|
||||
s->eq_coeff[i].im *= 0.9999f;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
@@ -253,7 +340,7 @@ static int scrambled_training_bit(v29_rx_state_t *s)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTy)
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static __inline__ int find_quadrant(const complexi16_t *z)
|
||||
#else
|
||||
static __inline__ int find_quadrant(const complexf_t *z)
|
||||
@@ -269,7 +356,7 @@ static __inline__ int find_quadrant(const complexf_t *z)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTy)
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static __inline__ void track_carrier(v29_rx_state_t *s, const complexi16_t *z, const complexi16_t *target)
|
||||
#else
|
||||
static __inline__ void track_carrier(v29_rx_state_t *s, const complexf_t *z, const complexf_t *target)
|
||||
@@ -290,7 +377,12 @@ static __inline__ void track_carrier(v29_rx_state_t *s, const complexf_t *z, con
|
||||
different amplitudes of the various target positions scale things. This isn't all bad,
|
||||
as the angular error for the larger amplitude constellation points is probably
|
||||
a more reliable indicator, and we are weighting it as such. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
error = z->im*target->re - z->re*target->im;
|
||||
error /= (float) FP_FACTOR;
|
||||
#else
|
||||
error = z->im*target->re - z->re*target->im;
|
||||
#endif
|
||||
|
||||
/* Use a proportional-integral approach to tracking the carrier. The PI
|
||||
parameters are coarser at first, until we get precisely on target. Then,
|
||||
@@ -326,7 +418,11 @@ static __inline__ void put_bit(v29_rx_state_t *s, int bit)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
static void decode_baud(v29_rx_state_t *s, complexi16_t *z)
|
||||
#else
|
||||
static void decode_baud(v29_rx_state_t *s, complexf_t *z)
|
||||
#endif
|
||||
{
|
||||
static const uint8_t phase_steps_9600[8] =
|
||||
{
|
||||
@@ -342,57 +438,51 @@ static void decode_baud(v29_rx_state_t *s, complexf_t *z)
|
||||
int re;
|
||||
int im;
|
||||
|
||||
switch (s->bit_rate)
|
||||
if (s->bit_rate == 4800)
|
||||
{
|
||||
case 9600:
|
||||
default:
|
||||
/* 4800 is a special case. */
|
||||
nearest = find_quadrant(z) << 1;
|
||||
raw_bits = phase_steps_4800[((nearest - s->constellation_state) >> 1) & 3];
|
||||
put_bit(s, raw_bits);
|
||||
put_bit(s, raw_bits >> 1);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* 9600 and 7200 are quite similar. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
re = (z->re + 5*FP_FACTOR) >> (FP_SHIFT_FACTOR - 1);
|
||||
im = (z->im + 5*FP_FACTOR) >> (FP_SHIFT_FACTOR - 1);
|
||||
#else
|
||||
re = (int) ((z->re + 5.0f)*2.0f);
|
||||
im = (int) ((z->im + 5.0f)*2.0f);
|
||||
#endif
|
||||
if (re > 19)
|
||||
re = 19;
|
||||
else if (re < 0)
|
||||
re = 0;
|
||||
im = (int) ((z->im + 5.0f)*2.0f);
|
||||
if (im > 19)
|
||||
im = 19;
|
||||
else if (im < 0)
|
||||
im = 0;
|
||||
nearest = space_map_9600[re][im];
|
||||
/* Deal with the amplitude bit */
|
||||
put_bit(s, nearest >> 3);
|
||||
if (s->bit_rate == 9600)
|
||||
{
|
||||
/* Send out the top (amplitude) bit. */
|
||||
put_bit(s, nearest >> 3);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* We can reuse the space map for 9600, but drop the top bit. */
|
||||
nearest &= 7;
|
||||
}
|
||||
raw_bits = phase_steps_9600[(nearest - s->constellation_state) & 7];
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
put_bit(s, raw_bits);
|
||||
raw_bits >>= 1;
|
||||
}
|
||||
break;
|
||||
case 7200:
|
||||
/* We can reuse the space map for 9600, but drop the top bit */
|
||||
re = (int) ((z->re + 5.0f)*2.0f);
|
||||
if (re > 19)
|
||||
re = 19;
|
||||
else if (re < 0)
|
||||
re = 0;
|
||||
im = (int) ((z->im + 5.0f)*2.0f);
|
||||
if (im > 19)
|
||||
im = 19;
|
||||
else if (im < 0)
|
||||
im = 0;
|
||||
nearest = space_map_9600[re][im] & 7;
|
||||
raw_bits = phase_steps_9600[(nearest - s->constellation_state) & 7];
|
||||
for (i = 0; i < 3; i++)
|
||||
{
|
||||
put_bit(s, raw_bits);
|
||||
raw_bits >>= 1;
|
||||
}
|
||||
break;
|
||||
case 4800:
|
||||
nearest = find_quadrant(z) << 1;
|
||||
raw_bits = phase_steps_4800[((nearest - s->constellation_state) >> 1) & 3];
|
||||
put_bit(s, raw_bits);
|
||||
put_bit(s, raw_bits >> 1);
|
||||
break;
|
||||
}
|
||||
|
||||
track_carrier(s, z, &v29_9600_constellation[nearest]);
|
||||
if (--s->eq_skip <= 0)
|
||||
{
|
||||
@@ -406,7 +496,73 @@ static void decode_baud(v29_rx_state_t *s, complexf_t *z)
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static __inline__ void symbol_sync(v29_rx_state_t *s)
|
||||
{
|
||||
int i;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
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. */
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
/* TODO: The scalings used here need more thorough evaluation, to see if overflows are possible. */
|
||||
/* Cross correlate */
|
||||
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 */
|
||||
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 noise */
|
||||
s->baud_phase -= p;
|
||||
if (abs(s->baud_phase) > 50*FP_FACTOR)
|
||||
{
|
||||
if (s->baud_phase > 0)
|
||||
i = (s->baud_phase > 1000*FP_FACTOR) ? 5 : 1;
|
||||
else
|
||||
i = (s->baud_phase < -1000*FP_FACTOR) ? -5 : -1;
|
||||
|
||||
//printf("v = %10.5f %5d - %f %f %d %d\n", v, i, p, s->baud_phase, s->total_baud_timing_correction);
|
||||
s->eq_put_step += i;
|
||||
s->total_baud_timing_correction += i;
|
||||
}
|
||||
#else
|
||||
/* Cross correlate */
|
||||
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 */
|
||||
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 noise */
|
||||
s->baud_phase -= p;
|
||||
if (fabsf(s->baud_phase) > 50.0f)
|
||||
{
|
||||
if (s->baud_phase > 0.0f)
|
||||
i = (s->baud_phase > 1000.0f) ? 5 : 1;
|
||||
else
|
||||
i = (s->baud_phase < -1000.0f) ? -5 : -1;
|
||||
|
||||
//printf("v = %10.5f %5d - %f %f %d %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_POINT)
|
||||
static void process_half_baud(v29_rx_state_t *s, complexi16_t *sample)
|
||||
#else
|
||||
static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
#endif
|
||||
{
|
||||
static const int cdcd_pos[6] =
|
||||
{
|
||||
@@ -414,14 +570,17 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
0, 3,
|
||||
0, 2
|
||||
};
|
||||
complexf_t z;
|
||||
complexf_t zz;
|
||||
#if defined(SPANDSP_USE_FIXED_POINTy)
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
complexf_t z1;
|
||||
complexi16_t z;
|
||||
const complexi16_t *target;
|
||||
static const complexi16_t zero = {0, 0};
|
||||
#else
|
||||
complexf_t z;
|
||||
const complexf_t *target;
|
||||
static const complexf_t zero = {0.0f, 0.0f};
|
||||
#endif
|
||||
float v;
|
||||
float p;
|
||||
int bit;
|
||||
int i;
|
||||
@@ -429,8 +588,7 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
int32_t angle;
|
||||
int32_t ang;
|
||||
|
||||
/* This routine processes every half a baud, as we put things into the equalizer at the T/2 rate.
|
||||
This routine adapts the position of the half baud samples, which the caller takes. */
|
||||
/* This routine processes every half a baud, as we put things into the equalizer at the T/2 rate. */
|
||||
|
||||
/* Add a sample to the equalizer's circular buffer, but don't calculate anything
|
||||
at this time. */
|
||||
@@ -442,29 +600,7 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
return;
|
||||
|
||||
/* Symbol timing synchronisation */
|
||||
/* Cross correlate */
|
||||
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 */
|
||||
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 noise */
|
||||
s->baud_phase -= p;
|
||||
|
||||
if (fabsf(s->baud_phase) > 30.0f)
|
||||
{
|
||||
if (s->baud_phase > 0.0f)
|
||||
i = (s->baud_phase > 1000.0f) ? 5 : 1;
|
||||
else
|
||||
i = (s->baud_phase < -1000.0f) ? -5 : -1;
|
||||
|
||||
//printf("v = %10.5f %5d - %f %f %d %d\n", v, i, p, s->baud_phase, s->total_baud_timing_correction);
|
||||
s->eq_put_step += i;
|
||||
s->total_baud_timing_correction += i;
|
||||
}
|
||||
symbol_sync(s);
|
||||
|
||||
z = equalizer_get(s);
|
||||
|
||||
@@ -477,25 +613,27 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
break;
|
||||
case TRAINING_STAGE_SYMBOL_ACQUISITION:
|
||||
/* Allow time for symbol synchronisation to settle the symbol timing. */
|
||||
target = &z;
|
||||
target = &zero;
|
||||
if (++s->training_count >= 60)
|
||||
{
|
||||
/* Record the current phase angle */
|
||||
s->training_stage = TRAINING_STAGE_LOG_PHASE;
|
||||
s->angles[0] =
|
||||
s->start_angles[0] = arctan2(z.im, z.re);
|
||||
if (s->agc_scaling_save == 0.0f)
|
||||
s->agc_scaling_save = s->agc_scaling;
|
||||
}
|
||||
break;
|
||||
case TRAINING_STAGE_LOG_PHASE:
|
||||
/* Record the current alternate phase angle */
|
||||
target = &z;
|
||||
target = &zero;
|
||||
s->angles[1] =
|
||||
s->start_angles[1] = arctan2(z.im, z.re);
|
||||
s->training_count = 1;
|
||||
s->training_stage = TRAINING_STAGE_WAIT_FOR_CDCD;
|
||||
break;
|
||||
case TRAINING_STAGE_WAIT_FOR_CDCD:
|
||||
target = &z;
|
||||
target = &zero;
|
||||
angle = arctan2(z.im, z.re);
|
||||
/* Look for the initial ABAB sequence to display a phase reversal, which will
|
||||
signal the start of the scrambled CDCD segment */
|
||||
@@ -524,24 +662,36 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
||
|
||||
s->carrier_phase_rate > dds_phase_ratef(CARRIER_NOMINAL_FREQ + 20.0f))
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n");
|
||||
/* Park this modem */
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
break;
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n");
|
||||
/* Park this modem */
|
||||
s->agc_scaling_save = 0.0f;
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
break;
|
||||
}
|
||||
/* Make a step shift in the phase, to pull it into line. We need to rotate the equalizer
|
||||
buffer, as well as the carrier phase, for this to play out nicely. */
|
||||
p = angle*2.0f*3.14159f/(65536.0f*65536.0f);
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
zz = complex_setf(cosf(p), -sinf(p));
|
||||
for (i = 0; i <= V29_EQUALIZER_MASK; i++)
|
||||
{
|
||||
z1 = complex_setf(s->eq_buf[i].re, s->eq_buf[i].im);
|
||||
z1 = complex_mulf(&z1, &zz);
|
||||
s->eq_buf[i].re = z1.re;
|
||||
s->eq_buf[i].im = z1.im;
|
||||
}
|
||||
#else
|
||||
zz = complex_setf(cosf(p), -sinf(p));
|
||||
for (i = 0; i <= V29_EQUALIZER_MASK; i++)
|
||||
s->eq_buf[i] = complex_mulf(&s->eq_buf[i], &zz);
|
||||
#endif
|
||||
s->carrier_phase += angle;
|
||||
/* We have just seen the first bit of the scrambled sequence, so skip it. */
|
||||
bit = scrambled_training_bit(s);
|
||||
s->training_count = 1;
|
||||
s->training_stage = TRAINING_STAGE_TRAIN_ON_CDCD;
|
||||
report_status_change(s, PUTBIT_TRAINING_IN_PROGRESS);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_IN_PROGRESS);
|
||||
break;
|
||||
}
|
||||
if (++s->training_count > V29_TRAINING_SEG_2_LEN)
|
||||
@@ -550,8 +700,9 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
of a real training sequence. */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (sequence failed)\n");
|
||||
/* Park this modem */
|
||||
s->agc_scaling_save = 0.0f;
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
}
|
||||
break;
|
||||
case TRAINING_STAGE_TRAIN_ON_CDCD:
|
||||
@@ -579,8 +730,17 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
track_carrier(s, &z, target);
|
||||
tune_equalizer(s, &z, target);
|
||||
/* Measure the training error */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
z1.re = z.re/(float) FP_FACTOR;
|
||||
z1.im = z.im/(float) FP_FACTOR;
|
||||
zz.re = target->re;
|
||||
zz.im = target->im;
|
||||
zz = complex_subf(&z1, &zz);
|
||||
s->training_error += powerf(&zz);
|
||||
#else
|
||||
zz = complex_subf(&z, target);
|
||||
s->training_error += powerf(&zz);
|
||||
#endif
|
||||
if (++s->training_count >= V29_TRAINING_SEG_3_LEN)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Constellation mismatch %f\n", s->training_error);
|
||||
@@ -595,8 +755,9 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (convergence failed)\n");
|
||||
/* Park this modem */
|
||||
s->agc_scaling_save = 0.0f;
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -607,15 +768,24 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
decode_baud(s, &z);
|
||||
target = &v29_9600_constellation[s->constellation_state];
|
||||
/* Measure the training error */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
z1.re = z.re/(float) FP_FACTOR;
|
||||
z1.im = z.im/(float) FP_FACTOR;
|
||||
zz.re = target->re;
|
||||
zz.im = target->im;
|
||||
zz = complex_subf(&z1, &zz);
|
||||
s->training_error += powerf(&zz);
|
||||
#else
|
||||
zz = complex_subf(&z, target);
|
||||
s->training_error += powerf(&zz);
|
||||
#endif
|
||||
if (++s->training_count >= V29_TRAINING_SEG_4_LEN)
|
||||
{
|
||||
if (s->training_error < 50.0f)
|
||||
{
|
||||
/* We are up and running */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training succeeded (constellation mismatch %f)\n", s->training_error);
|
||||
report_status_change(s, PUTBIT_TRAINING_SUCCEEDED);
|
||||
report_status_change(s, SIG_STATUS_TRAINING_SUCCEEDED);
|
||||
/* Apply some lag to the carrier off condition, to ensure the last few bits get pushed through
|
||||
the processing. */
|
||||
s->signal_present = 60;
|
||||
@@ -629,8 +799,9 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
/* Training has failed */
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "Training failed (constellation mismatch %f)\n", s->training_error);
|
||||
/* Park this modem */
|
||||
report_status_change(s, PUTBIT_TRAINING_FAILED);
|
||||
s->agc_scaling_save = 0.0f;
|
||||
s->training_stage = TRAINING_STAGE_PARKED;
|
||||
report_status_change(s, SIG_STATUS_TRAINING_FAILED);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@@ -638,11 +809,21 @@ static void process_half_baud(v29_rx_state_t *s, complexf_t *sample)
|
||||
default:
|
||||
/* We failed to train! */
|
||||
/* Park here until the carrier drops. */
|
||||
target = &z;
|
||||
target = &zero;
|
||||
break;
|
||||
}
|
||||
if (s->qam_report)
|
||||
{
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
z1.re = z.re/(float) FP_FACTOR;
|
||||
z1.im = z.im/(float) FP_FACTOR;
|
||||
zz.re = target->re;
|
||||
zz.im = target->im;
|
||||
s->qam_report(s->qam_user_data, &z1, &zz, s->constellation_state);
|
||||
#else
|
||||
s->qam_report(s->qam_user_data, &z, target, s->constellation_state);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
@@ -653,14 +834,19 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
||||
int step;
|
||||
int16_t x;
|
||||
int32_t diff;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
complexi16_t z;
|
||||
complexi16_t zz;
|
||||
complexi16_t sample;
|
||||
int32_t v;
|
||||
float y;
|
||||
#else
|
||||
complexf_t z;
|
||||
complexf_t zz;
|
||||
complexf_t sample;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
complexi_t zi;
|
||||
float v;
|
||||
#endif
|
||||
int32_t power;
|
||||
float v;
|
||||
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
@@ -709,7 +895,7 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
||||
/* Count down a short delay, to ensure we push the last
|
||||
few bits through the filters before stopping. */
|
||||
v29_rx_restart(s, s->bit_rate, FALSE);
|
||||
report_status_change(s, PUTBIT_CARRIER_DOWN);
|
||||
report_status_change(s, SIG_STATUS_CARRIER_DOWN);
|
||||
continue;
|
||||
}
|
||||
#if defined(IAXMODEM_STUFF)
|
||||
@@ -728,7 +914,7 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
||||
#if defined(IAXMODEM_STUFF)
|
||||
s->carrier_drop_pending = FALSE;
|
||||
#endif
|
||||
report_status_change(s, PUTBIT_CARRIER_UP);
|
||||
report_status_change(s, SIG_STATUS_CARRIER_UP);
|
||||
}
|
||||
if (s->training_stage == TRAINING_STAGE_PARKED)
|
||||
continue;
|
||||
@@ -741,18 +927,29 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
||||
if (step < 0)
|
||||
step += RX_PULSESHAPER_COEFF_SETS;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
zi.re = (int32_t) rx_pulseshaper[step][0].re*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
||||
v = (int32_t) rx_pulseshaper[step][0].re*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
||||
zi.re += (int32_t) rx_pulseshaper[step][j].re*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.re = zi.re*s->agc_scaling;
|
||||
v += (int32_t) rx_pulseshaper[step][j].re*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
||||
y = v*s->agc_scaling;
|
||||
sample.re = y;
|
||||
#else
|
||||
zz.re = rx_pulseshaper[step][0].re*s->rrc_filter[s->rrc_filter_step];
|
||||
v = rx_pulseshaper[step][0].re*s->rrc_filter[s->rrc_filter_step];
|
||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
||||
zz.re += rx_pulseshaper[step][j].re*s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.re = zz.re*s->agc_scaling;
|
||||
v += rx_pulseshaper[step][j].re*s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.re = v*s->agc_scaling;
|
||||
#endif
|
||||
|
||||
/* Symbol timing synchronisation band edge filters */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
/* Low Nyquist band edge filter */
|
||||
v = ((s->symbol_sync_low[0]*SYNC_LOW_BAND_EDGE_COEFF_0) >> 12) + ((s->symbol_sync_low[1]*SYNC_LOW_BAND_EDGE_COEFF_1) >> 12) + 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) >> 12) + ((s->symbol_sync_high[1]*SYNC_HIGH_BAND_EDGE_COEFF_1) >> 12) + sample.re;
|
||||
s->symbol_sync_high[1] = s->symbol_sync_high[0];
|
||||
s->symbol_sync_high[0] = v;
|
||||
#else
|
||||
/* 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];
|
||||
@@ -761,16 +958,19 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
||||
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
|
||||
/* 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)
|
||||
{
|
||||
if (s->training_stage == TRAINING_STAGE_SYMBOL_ACQUISITION)
|
||||
{
|
||||
/* Only AGC during the initial training */
|
||||
/* Only AGC until we have locked down the setting. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
if (s->agc_scaling_save == 0.0f)
|
||||
s->agc_scaling = (float) FP_FACTOR*(1.0f/RX_PULSESHAPER_GAIN)*5.0f*0.25f/sqrtf(power);
|
||||
#else
|
||||
if (s->agc_scaling_save == 0.0f)
|
||||
s->agc_scaling = (1.0f/RX_PULSESHAPER_GAIN)*5.0f*0.25f/sqrtf(power);
|
||||
}
|
||||
#endif
|
||||
/* Pulse shape while still at the carrier frequency, using a quadrature
|
||||
pair of filters. This results in a properly bandpass filtered complex
|
||||
signal, which can be brought directly to baseband by complex mixing.
|
||||
@@ -778,24 +978,24 @@ int v29_rx(v29_rx_state_t *s, const int16_t amp[], int len)
|
||||
step = -s->eq_put_step;
|
||||
if (step > RX_PULSESHAPER_COEFF_SETS - 1)
|
||||
step = RX_PULSESHAPER_COEFF_SETS - 1;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
zi.im = (int32_t) rx_pulseshaper[step][0].im*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
||||
zi.im += (int32_t) rx_pulseshaper[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.im = zi.im*s->agc_scaling;
|
||||
#else
|
||||
zz.im = rx_pulseshaper[step][0].im*s->rrc_filter[s->rrc_filter_step];
|
||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
||||
zz.im += rx_pulseshaper[step][j].im*s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.im = zz.im*s->agc_scaling;
|
||||
#endif
|
||||
s->eq_put_step += RX_PULSESHAPER_COEFF_SETS*10/(3*2);
|
||||
/* 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. */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
v = (int32_t) rx_pulseshaper[step][0].im*(int32_t) s->rrc_filter[s->rrc_filter_step];
|
||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
||||
v += (int32_t) rx_pulseshaper[step][j].im*(int32_t) s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.im = v*s->agc_scaling;
|
||||
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
|
||||
v = rx_pulseshaper[step][0].im*s->rrc_filter[s->rrc_filter_step];
|
||||
for (j = 1; j < V29_RX_FILTER_STEPS; j++)
|
||||
v += rx_pulseshaper[step][j].im*s->rrc_filter[j + s->rrc_filter_step];
|
||||
sample.im = v*s->agc_scaling;
|
||||
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);
|
||||
@@ -837,7 +1037,7 @@ int v29_rx_restart(v29_rx_state_t *s, int bit_rate, int old_train)
|
||||
s->bit_rate = bit_rate;
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
memset(s->rrc_filter, 0, sizeof(s->rrc_filter));
|
||||
vec_zeroi16(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
|
||||
#else
|
||||
vec_zerof(s->rrc_filter, sizeof(s->rrc_filter)/sizeof(s->rrc_filter[0]));
|
||||
#endif
|
||||
@@ -856,8 +1056,6 @@ int v29_rx_restart(v29_rx_state_t *s, int bit_rate, int old_train)
|
||||
s->old_train = old_train;
|
||||
|
||||
s->carrier_phase = 0;
|
||||
s->carrier_track_i = 8000.0f;
|
||||
s->carrier_track_p = 8000000.0f;
|
||||
|
||||
power_meter_init(&(s->power), 4);
|
||||
|
||||
@@ -872,13 +1070,29 @@ int v29_rx_restart(v29_rx_state_t *s, int bit_rate, int old_train)
|
||||
else
|
||||
{
|
||||
s->carrier_phase_rate = dds_phase_ratef(CARRIER_NOMINAL_FREQ);
|
||||
s->agc_scaling_save = 0.0f;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
s->agc_scaling = (float) FP_FACTOR*0.0017f/RX_PULSESHAPER_GAIN;
|
||||
#else
|
||||
s->agc_scaling = 0.0017f/RX_PULSESHAPER_GAIN;
|
||||
#endif
|
||||
equalizer_reset(s);
|
||||
}
|
||||
s->eq_skip = 0;
|
||||
s->carrier_track_i = 8000.0f;
|
||||
s->carrier_track_p = 8000000.0f;
|
||||
s->last_sample = 0;
|
||||
s->eq_skip = 0;
|
||||
|
||||
/* Initialise the working data for symbol timing synchronisation */
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
s->symbol_sync_low[0] = 0;
|
||||
s->symbol_sync_low[1] = 0;
|
||||
s->symbol_sync_high[0] = 0;
|
||||
s->symbol_sync_high[1] = 0;
|
||||
s->symbol_sync_dc_filter[0] = 0;
|
||||
s->symbol_sync_dc_filter[1] = 0;
|
||||
s->baud_phase = 0;
|
||||
#else
|
||||
s->symbol_sync_low[0] = 0.0f;
|
||||
s->symbol_sync_low[1] = 0.0f;
|
||||
s->symbol_sync_high[0] = 0.0f;
|
||||
@@ -886,6 +1100,7 @@ int v29_rx_restart(v29_rx_state_t *s, int bit_rate, int old_train)
|
||||
s->symbol_sync_dc_filter[0] = 0.0f;
|
||||
s->symbol_sync_dc_filter[1] = 0.0f;
|
||||
s->baud_phase = 0.0f;
|
||||
#endif
|
||||
s->baud_half = 0;
|
||||
|
||||
s->total_baud_timing_correction = 0;
|
||||
|
||||
Reference in new issue
Block a user