Tweaks
This commit is contained in:
parent
b5f7443524
commit
e9b4a497cc
|
@ -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);
|
||||
|
|
|
@ -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 */
|
||||
|
|
|
@ -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;
|
||||
/*! \brief The scaling factor accessed by the AGC algorithm. */
|
||||
float agc_scaling;
|
||||
|
||||
int constellation_state;
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINTx)
|
||||
/*! \brief The scaling factor accessed by the AGC algorithm. */
|
||||
float agc_scaling;
|
||||
/*! \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. */
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -63,8 +63,10 @@
|
|||
#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;
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue