More tweaks for spandsp.
This commit is contained in:
parent
2b75169c07
commit
4a200ce3a0
|
@ -258,45 +258,42 @@ SPAN_DECLARE(int) dtmf_rx(dtmf_rx_state_t *s, const int16_t amp[], int samples)
|
|||
Note this is only relevant to VoIP using A-law, u-law or similar.
|
||||
Low bit rate codecs scramble DTMF too much for it to be recognised,
|
||||
and often slip in units larger than a sample. */
|
||||
if (hit != s->in_digit)
|
||||
if (hit != s->in_digit && s->last_hit != s->in_digit)
|
||||
{
|
||||
if (s->last_hit != s->in_digit)
|
||||
/* We have two successive indications that something has changed. */
|
||||
/* To declare digit on, the hits must agree. Otherwise we declare tone off. */
|
||||
hit = (hit && hit == s->last_hit) ? hit : 0;
|
||||
if (s->realtime_callback)
|
||||
{
|
||||
/* We have two successive indications that something has changed. */
|
||||
/* To declare digit on, the hits must agree. Otherwise we declare tone off. */
|
||||
hit = (hit && hit == s->last_hit) ? hit : 0;
|
||||
if (s->realtime_callback)
|
||||
/* Avoid reporting multiple no digit conditions on flaky hits */
|
||||
if (s->in_digit || hit)
|
||||
{
|
||||
/* Avoid reporting multiple no digit conditions on flaky hits */
|
||||
if (s->in_digit || hit)
|
||||
{
|
||||
i = (s->in_digit && !hit) ? -99 : lfastrintf(log10f(s->energy)*10.0f - DTMF_POWER_OFFSET + DBM0_MAX_POWER);
|
||||
s->realtime_callback(s->realtime_callback_data, hit, i, s->duration);
|
||||
s->duration = 0;
|
||||
}
|
||||
i = (s->in_digit && !hit) ? -99 : lfastrintf(log10f(s->energy)*10.0f - DTMF_POWER_OFFSET + DBM0_MAX_POWER);
|
||||
s->realtime_callback(s->realtime_callback_data, hit, i, s->duration);
|
||||
s->duration = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hit)
|
||||
{
|
||||
if (s->current_digits < MAX_DTMF_DIGITS)
|
||||
{
|
||||
s->digits[s->current_digits++] = (char) hit;
|
||||
s->digits[s->current_digits] = '\0';
|
||||
if (s->digits_callback)
|
||||
{
|
||||
s->digits_callback(s->digits_callback_data, s->digits, s->current_digits);
|
||||
s->current_digits = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s->lost_digits++;
|
||||
}
|
||||
}
|
||||
}
|
||||
s->in_digit = hit;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (hit)
|
||||
{
|
||||
if (s->current_digits < MAX_DTMF_DIGITS)
|
||||
{
|
||||
s->digits[s->current_digits++] = (char) hit;
|
||||
s->digits[s->current_digits] = '\0';
|
||||
if (s->digits_callback)
|
||||
{
|
||||
s->digits_callback(s->digits_callback_data, s->digits, s->current_digits);
|
||||
s->current_digits = 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
s->lost_digits++;
|
||||
}
|
||||
}
|
||||
}
|
||||
s->in_digit = hit;
|
||||
}
|
||||
s->last_hit = hit;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
|
@ -333,7 +330,7 @@ SPAN_DECLARE(int) dtmf_rx_fillin(dtmf_rx_state_t *s, int samples)
|
|||
#endif
|
||||
s->current_sample = 0;
|
||||
/* Don't update the hit detection. Pretend it never happened. */
|
||||
/* TODO: Surely we can be a cleverer than this. */
|
||||
/* TODO: Surely we can be cleverer than this. */
|
||||
return 0;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
@ -359,7 +356,7 @@ SPAN_DECLARE(size_t) dtmf_rx_get(dtmf_rx_state_t *s, char *buf, int max)
|
|||
s->current_digits -= max;
|
||||
}
|
||||
buf[max] = '\0';
|
||||
return max;
|
||||
return max;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -417,7 +414,7 @@ SPAN_DECLARE(dtmf_rx_state_t *) dtmf_rx_init(dtmf_rx_state_t *s,
|
|||
if (s == NULL)
|
||||
{
|
||||
if ((s = (dtmf_rx_state_t *) malloc(sizeof (*s))) == NULL)
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
span_log_init(&s->logging, SPAN_LOG_NONE, NULL);
|
||||
|
@ -570,7 +567,7 @@ SPAN_DECLARE(dtmf_tx_state_t *) dtmf_tx_init(dtmf_tx_state_t *s)
|
|||
if (s == NULL)
|
||||
{
|
||||
if ((s = (dtmf_tx_state_t *) malloc(sizeof (*s))) == NULL)
|
||||
return NULL;
|
||||
return NULL;
|
||||
}
|
||||
memset(s, 0, sizeof(*s));
|
||||
if (!dtmf_tx_inited)
|
||||
|
|
|
@ -154,7 +154,8 @@ static void rx_flag_or_abort(hdlc_rx_state_t *s)
|
|||
s->rx_frames++;
|
||||
s->rx_bytes += s->len - s->crc_bytes;
|
||||
s->len -= s->crc_bytes;
|
||||
s->frame_handler(s->frame_user_data, s->buffer, s->len, TRUE);
|
||||
if (s->frame_handler)
|
||||
s->frame_handler(s->frame_user_data, s->buffer, s->len, TRUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -162,7 +163,8 @@ static void rx_flag_or_abort(hdlc_rx_state_t *s)
|
|||
if (s->report_bad_frames)
|
||||
{
|
||||
s->len -= s->crc_bytes;
|
||||
s->frame_handler(s->frame_user_data, s->buffer, s->len, FALSE);
|
||||
if (s->frame_handler)
|
||||
s->frame_handler(s->frame_user_data, s->buffer, s->len, FALSE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -177,7 +179,8 @@ static void rx_flag_or_abort(hdlc_rx_state_t *s)
|
|||
s->len -= s->crc_bytes;
|
||||
else
|
||||
s->len = 0;
|
||||
s->frame_handler(s->frame_user_data, s->buffer, s->len, FALSE);
|
||||
if (s->frame_handler)
|
||||
s->frame_handler(s->frame_user_data, s->buffer, s->len, FALSE);
|
||||
}
|
||||
s->rx_length_errors++;
|
||||
}
|
||||
|
|
|
@ -450,6 +450,151 @@ int main(int argc, char **argv)
|
|||
rx_tag = "";
|
||||
tx_tag = "";
|
||||
}
|
||||
else if (strcmp(modem, "V.34_2400") == 0)
|
||||
{
|
||||
rx_coeff_sets = 192;
|
||||
rx_coeffs_per_filter = 27;
|
||||
rx_excess_bandwidth = 0.25;
|
||||
tx_coeff_sets = 10;
|
||||
tx_coeffs_per_filter = 9;
|
||||
tx_excess_bandwidth = 0.12;
|
||||
carrier = 1600.0;
|
||||
baud_rate = 2400.0;
|
||||
rx_tag = "_2400_low_carrier";
|
||||
tx_tag = "_2400";
|
||||
}
|
||||
else if (strcmp(modem, "V.34_2400_high") == 0)
|
||||
{
|
||||
rx_coeff_sets = 192;
|
||||
rx_coeffs_per_filter = 27;
|
||||
rx_excess_bandwidth = 0.25;
|
||||
tx_coeff_sets = 10;
|
||||
tx_coeffs_per_filter = 9;
|
||||
tx_excess_bandwidth = 0.12;
|
||||
carrier = 1800.0;
|
||||
baud_rate = 2400.0;
|
||||
rx_tag = "_2400_high_carrier";
|
||||
tx_tag = "_2400";
|
||||
}
|
||||
else if (strcmp(modem, "V.34_2743") == 0)
|
||||
{
|
||||
rx_coeff_sets = 192;
|
||||
rx_coeffs_per_filter = 27;
|
||||
rx_excess_bandwidth = 0.25;
|
||||
tx_coeff_sets = 35;
|
||||
tx_coeffs_per_filter = 9;
|
||||
tx_excess_bandwidth = 0.12;
|
||||
carrier = 1646.0;
|
||||
baud_rate = 2400.0*8.0/7.0;
|
||||
rx_tag = "_2743_low_carrier";
|
||||
tx_tag = "_2743";
|
||||
}
|
||||
else if (strcmp(modem, "V.34_2743_high") == 0)
|
||||
{
|
||||
rx_coeff_sets = 192;
|
||||
rx_coeffs_per_filter = 27;
|
||||
rx_excess_bandwidth = 0.25;
|
||||
tx_coeff_sets = 35;
|
||||
tx_coeffs_per_filter = 9;
|
||||
tx_excess_bandwidth = 0.12;
|
||||
carrier = 1829.0;
|
||||
baud_rate = 2400.0*8.0/7.0;
|
||||
rx_tag = "_2743_high_carrier";
|
||||
tx_tag = "_2743";
|
||||
}
|
||||
else if (strcmp(modem, "V.34_2800") == 0)
|
||||
{
|
||||
rx_coeff_sets = 192;
|
||||
rx_coeffs_per_filter = 27;
|
||||
rx_excess_bandwidth = 0.25;
|
||||
tx_coeff_sets = 20;
|
||||
tx_coeffs_per_filter = 9;
|
||||
tx_excess_bandwidth = 0.12;
|
||||
carrier = 1680.0;
|
||||
baud_rate = 2400.0*7.0/6.0;
|
||||
rx_tag = "_2800_low_carrier";
|
||||
tx_tag = "_2800";
|
||||
}
|
||||
else if (strcmp(modem, "V.34_2800_high") == 0)
|
||||
{
|
||||
rx_coeff_sets = 192;
|
||||
rx_coeffs_per_filter = 27;
|
||||
rx_excess_bandwidth = 0.25;
|
||||
tx_coeff_sets = 20;
|
||||
tx_coeffs_per_filter = 9;
|
||||
tx_excess_bandwidth = 0.12;
|
||||
carrier = 1867.0;
|
||||
baud_rate = 2400.0*7.0/6.0;
|
||||
rx_tag = "_2800_high_carrier";
|
||||
tx_tag = "_2800";
|
||||
}
|
||||
else if (strcmp(modem, "V.34_3000") == 0)
|
||||
{
|
||||
rx_coeff_sets = 192;
|
||||
rx_coeffs_per_filter = 27;
|
||||
rx_excess_bandwidth = 0.25;
|
||||
tx_coeff_sets = 8;
|
||||
tx_coeffs_per_filter = 9;
|
||||
tx_excess_bandwidth = 0.12;
|
||||
carrier = 1800.0;
|
||||
baud_rate = 2400.0*5.0/4.0;
|
||||
rx_tag = "_3000_low_carrier";
|
||||
tx_tag = "_3000";
|
||||
}
|
||||
else if (strcmp(modem, "V.34_3000_high") == 0)
|
||||
{
|
||||
rx_coeff_sets = 192;
|
||||
rx_coeffs_per_filter = 27;
|
||||
rx_excess_bandwidth = 0.25;
|
||||
tx_coeff_sets = 8;
|
||||
tx_coeffs_per_filter = 9;
|
||||
tx_excess_bandwidth = 0.12;
|
||||
carrier = 2000.0;
|
||||
baud_rate = 2400.0*5.0/4.0;
|
||||
rx_tag = "_3000_high_carrier";
|
||||
tx_tag = "_3000";
|
||||
}
|
||||
else if (strcmp(modem, "V.34_3200") == 0)
|
||||
{
|
||||
rx_coeff_sets = 192;
|
||||
rx_coeffs_per_filter = 27;
|
||||
rx_excess_bandwidth = 0.25;
|
||||
tx_coeff_sets = 5;
|
||||
tx_coeffs_per_filter = 9;
|
||||
tx_excess_bandwidth = 0.12;
|
||||
carrier = 1829.0;
|
||||
baud_rate = 2400.0*4.0/3.0;
|
||||
rx_tag = "_3200_low_carrier";
|
||||
tx_tag = "_3200";
|
||||
}
|
||||
else if (strcmp(modem, "V.34_3200_high") == 0)
|
||||
{
|
||||
rx_coeff_sets = 192;
|
||||
rx_coeffs_per_filter = 27;
|
||||
rx_excess_bandwidth = 0.25;
|
||||
tx_coeff_sets = 5;
|
||||
tx_coeffs_per_filter = 9;
|
||||
tx_excess_bandwidth = 0.12;
|
||||
carrier = 1920.0;
|
||||
baud_rate = 2400.0*4.0/3.0;
|
||||
rx_tag = "_3200_high_carrier";
|
||||
tx_tag = "_3200";
|
||||
}
|
||||
else if (strcmp(modem, "V.34_3429") == 0)
|
||||
{
|
||||
/* There is only one carrier frequency defined for this baud rate */
|
||||
rx_coeff_sets = 192;
|
||||
rx_coeffs_per_filter = 27;
|
||||
rx_excess_bandwidth = 0.25;
|
||||
tx_coeff_sets = 7;
|
||||
tx_coeffs_per_filter = 9;
|
||||
tx_excess_bandwidth = 0.12;
|
||||
//carrier = 1959.0;
|
||||
carrier = 1959.0;
|
||||
baud_rate = 2400.0*10.0/7.0;
|
||||
rx_tag = "_3429";
|
||||
tx_tag = "_3429";
|
||||
}
|
||||
else
|
||||
{
|
||||
usage();
|
||||
|
|
|
@ -29,9 +29,11 @@
|
|||
/* CNG is 0.5s+-15% of 1100+-38Hz, 3s+-15% off, repeating.
|
||||
|
||||
CED is 0.2s silence, 3.3+-0.7s of 2100+-15Hz, and 75+-20ms of silence.
|
||||
|
||||
|
||||
Calling tone is 0.5s-0.7s of 1300Hz+-15Hz, 1.5s-2.0s off, repeating.
|
||||
|
||||
ANS is 3.3+-0.7s of 2100+-15Hz.
|
||||
|
||||
|
||||
ANS/ is 3.3+-0.7s of 2100+-15Hz, with phase reversals (180+-10 degrees, hopping in <1ms) every 450+-25ms.
|
||||
|
||||
ANSam/ is 2100+-1Hz, with phase reversals (180+-10 degrees, hopping in <1ms) every 450+-25ms, and AM with a sinewave of 15+-0.1Hz.
|
||||
|
@ -92,6 +94,8 @@ SPAN_DECLARE(const char *) modem_connect_tone_to_str(int tone)
|
|||
return "FAX preamble";
|
||||
case MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE:
|
||||
return "FAX CED or preamble";
|
||||
case MODEM_CONNECT_TONES_CALLING_TONE:
|
||||
return "Calling tone";
|
||||
}
|
||||
return "???";
|
||||
}
|
||||
|
@ -202,6 +206,29 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_tx(modem_connect_tones_tx_state_t *
|
|||
}
|
||||
s->duration_timer -= len;
|
||||
break;
|
||||
case MODEM_CONNECT_TONES_CALLING_TONE:
|
||||
for ( ; i < len; i++)
|
||||
{
|
||||
if (s->duration_timer > ms_to_samples(2000))
|
||||
{
|
||||
if ((xlen = i + s->duration_timer - ms_to_samples(2000)) > len)
|
||||
xlen = len;
|
||||
s->duration_timer -= (xlen - i);
|
||||
for ( ; i < xlen; i++)
|
||||
amp[i] = dds_mod(&s->tone_phase, s->tone_phase_rate, s->level, 0);
|
||||
}
|
||||
if (s->duration_timer > 0)
|
||||
{
|
||||
if ((xlen = i + s->duration_timer) > len)
|
||||
xlen = len;
|
||||
s->duration_timer -= (xlen - i);
|
||||
memset(amp + i, 0, sizeof(int16_t)*(xlen - i));
|
||||
i = xlen;
|
||||
}
|
||||
if (s->duration_timer == 0)
|
||||
s->duration_timer = ms_to_samples(600 + 2000);
|
||||
}
|
||||
break;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
@ -274,6 +301,17 @@ SPAN_DECLARE(modem_connect_tones_tx_state_t *) modem_connect_tones_tx_init(modem
|
|||
s->mod_phase = 0;
|
||||
s->hop_timer = ms_to_samples(450);
|
||||
break;
|
||||
case MODEM_CONNECT_TONES_CALLING_TONE:
|
||||
/* 0.6s of 1300Hz+-15Hz + 2.0s of silence repeating. */
|
||||
s->tone_phase_rate = dds_phase_rate(1300.0);
|
||||
s->level = dds_scaling_dbm0(-11);
|
||||
s->duration_timer = ms_to_samples(600 + 2000);
|
||||
s->mod_phase_rate = 0;
|
||||
s->tone_phase = 0;
|
||||
s->mod_phase = 0;
|
||||
s->mod_level = 0;
|
||||
s->hop_timer = 0;
|
||||
break;
|
||||
default:
|
||||
if (alloced)
|
||||
free(s);
|
||||
|
@ -402,6 +440,8 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
|
|||
famp = amp[i];
|
||||
/* A Cauer notch at 1100Hz, spread just wide enough to meet our detection bandwidth
|
||||
criteria. */
|
||||
/* Poles 0.736618498*exp(+-1047/4000 * PI * j)
|
||||
Zeroes exp(+-1099.5 * PI * j) */
|
||||
v1 = 0.792928f*famp + 1.0018744927985f*s->znotch_1 - 0.54196833412465f*s->znotch_2;
|
||||
famp = v1 - 1.2994747954630f*s->znotch_1 + s->znotch_2;
|
||||
s->znotch_2 = s->znotch_1;
|
||||
|
@ -446,6 +486,8 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
|
|||
{
|
||||
famp = amp[i];
|
||||
/* A Cauer bandpass at 15Hz, with which we demodulate the AM signal. */
|
||||
/* Poles 0.9983989*exp(+-15/4000 * PI * j)
|
||||
Zeroes exp(0 * PI * j) */
|
||||
v1 = fabs(famp) + 1.996667f*s->z15hz_1 - 0.9968004f*s->z15hz_2;
|
||||
filtered = 0.001599787f*(v1 - s->z15hz_2);
|
||||
s->z15hz_2 = s->z15hz_1;
|
||||
|
@ -454,8 +496,8 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
|
|||
//printf("%9.1f %10.4f %9d %9d\n", famp, filtered, s->am_level, s->channel_level);
|
||||
/* A Cauer notch at 2100Hz, spread just wide enough to meet our detection bandwidth
|
||||
criteria. */
|
||||
/* This is actually centred at 2095Hz, but gets the balance we want, due
|
||||
to the asymmetric walls of the notch */
|
||||
/* Poles 0.7144255*exp(+-2105.612/4000 * PI * j)
|
||||
Zeroes exp(+-2099.9 * PI * j) */
|
||||
v1 = 0.76000f*famp - 0.1183852f*s->znotch_1 - 0.5104039f*s->znotch_2;
|
||||
famp = v1 + 0.1567596f*s->znotch_1 + s->znotch_2;
|
||||
s->znotch_2 = s->znotch_1;
|
||||
|
@ -543,6 +585,44 @@ SPAN_DECLARE_NONSTD(int) modem_connect_tones_rx(modem_connect_tones_rx_state_t *
|
|||
}
|
||||
}
|
||||
break;
|
||||
case MODEM_CONNECT_TONES_CALLING_TONE:
|
||||
for (i = 0; i < len; i++)
|
||||
{
|
||||
famp = amp[i];
|
||||
/* A Cauer notch at 1300Hz, spread just wide enough to meet our detection bandwidth
|
||||
criteria. */
|
||||
/* Poles 0.736618498*exp(+-1247/4000 * PI * j)
|
||||
Zeroes exp(+-1299.5 * PI * j) */
|
||||
v1 = 0.755582f*famp + 0.820887174515f*s->znotch_1 - 0.541968324778f*s->znotch_2;
|
||||
famp = v1 - 1.0456667108f*s->znotch_1 + s->znotch_2;
|
||||
s->znotch_2 = s->znotch_1;
|
||||
s->znotch_1 = v1;
|
||||
notched = (int16_t) lfastrintf(famp);
|
||||
|
||||
/* Estimate the overall energy in the channel, and the energy in
|
||||
the notch (i.e. overall channel energy - tone energy => noise).
|
||||
Use abs instead of multiply for speed (is it really faster?). */
|
||||
s->channel_level += ((abs(amp[i]) - s->channel_level) >> 5);
|
||||
s->notch_level += ((abs(notched) - s->notch_level) >> 5);
|
||||
if (s->channel_level > 70 && s->notch_level*6 < s->channel_level)
|
||||
{
|
||||
/* There is adequate energy in the channel, and it is mostly at 1300Hz. */
|
||||
if (s->tone_present != MODEM_CONNECT_TONES_CALLING_TONE)
|
||||
{
|
||||
if (++s->tone_cycle_duration >= ms_to_samples(415))
|
||||
report_tone_state(s, MODEM_CONNECT_TONES_CALLING_TONE, lfastrintf(log10f(s->channel_level/32768.0f)*20.0f + DBM0_MAX_POWER + 0.8f));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* If the signal looks wrong, even for a moment, we consider this the
|
||||
end of the tone. */
|
||||
if (s->tone_present == MODEM_CONNECT_TONES_CALLING_TONE)
|
||||
report_tone_state(s, MODEM_CONNECT_TONES_NONE, -99);
|
||||
s->tone_cycle_duration = 0;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
|
|
@ -75,7 +75,10 @@ enum
|
|||
/*! \brief CED tone is the same as ANS tone. FAX preamble in a string of V.21 HDLC flag octets.
|
||||
This is only valid as a tone type to receive. It is never reported as a detected tone
|
||||
type. The report will either be for FAX preamble or CED/ANS tone. */
|
||||
MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE = 7
|
||||
MODEM_CONNECT_TONES_FAX_CED_OR_PREAMBLE = 7,
|
||||
/*! \brief Calling tone is a pure 1300Hz tone, in 0.6s bursts, with 2s silences in between. The
|
||||
bursts repeat for as long as is required. */
|
||||
MODEM_CONNECT_TONES_CALLING_TONE = 8
|
||||
};
|
||||
|
||||
/*! \brief FAX CED tone is the same as ANS tone. */
|
||||
|
|
|
@ -26,7 +26,7 @@
|
|||
#if !defined(_SPANDSP_PRIVATE_SUPER_TONE_RX_H_)
|
||||
#define _SPANDSP_PRIVATE_SUPER_TONE_RX_H_
|
||||
|
||||
#define BINS 128
|
||||
#define SUPER_TONE_BINS 128
|
||||
|
||||
struct super_tone_rx_segment_s
|
||||
{
|
||||
|
@ -41,7 +41,7 @@ struct super_tone_rx_descriptor_s
|
|||
{
|
||||
int used_frequencies;
|
||||
int monitored_frequencies;
|
||||
int pitches[BINS/2][2];
|
||||
int pitches[SUPER_TONE_BINS/2][2];
|
||||
int tones;
|
||||
super_tone_rx_segment_t **tone_list;
|
||||
int *tone_segs;
|
||||
|
@ -55,7 +55,7 @@ struct super_tone_rx_state_s
|
|||
int detected_tone;
|
||||
int rotation;
|
||||
tone_report_func_t tone_callback;
|
||||
void (*segment_callback)(void *data, int f1, int f2, int duration);
|
||||
tone_segment_func_t segment_callback;
|
||||
void *callback_data;
|
||||
super_tone_rx_segment_t segments[11];
|
||||
goertzel_state_t state[];
|
||||
|
|
|
@ -209,7 +209,7 @@ 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_level;
|
||||
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. */
|
||||
|
|
|
@ -118,6 +118,8 @@ struct v8_parms_s
|
|||
{
|
||||
int status;
|
||||
int modem_connect_tone;
|
||||
int send_ci;
|
||||
int v92;
|
||||
int call_function;
|
||||
unsigned int modulations;
|
||||
int protocol;
|
||||
|
|
|
@ -56,11 +56,11 @@
|
|||
#include "spandsp/private/super_tone_rx.h"
|
||||
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
#define DETECTION_THRESHOLD 16439 /* -42dBm0 [((BINS*BINS*32768.0/(1.4142*128.0))*10^((-42 - DBM0_MAX_SINE_POWER)/20.0))^2] */
|
||||
#define DETECTION_THRESHOLD 16439 /* -42dBm0 [((SUPER_TONE_BINS*SUPER_TONE_BINS*32768.0/(1.4142*128.0))*10^((-42 - DBM0_MAX_SINE_POWER)/20.0))^2] */
|
||||
#define TONE_TWIST 4 /* 6dB */
|
||||
#define TONE_TO_TOTAL_ENERGY 64 /* -3dB */
|
||||
#else
|
||||
#define DETECTION_THRESHOLD 2104205.6f /* -42dBm0 [((BINS*BINS*32768.0/1.4142)*10^((-42 - DBM0_MAX_SINE_POWER)/20.0))^2] */
|
||||
#define DETECTION_THRESHOLD 2104205.6f /* -42dBm0 [((SUPER_TONE_BINS*SUPER_TONE_BINS*32768.0/1.4142)*10^((-42 - DBM0_MAX_SINE_POWER)/20.0))^2] */
|
||||
#define TONE_TWIST 3.981f /* 6dB */
|
||||
#define TONE_TO_TOTAL_ENERGY 1.995f /* 3dB */
|
||||
#endif
|
||||
|
@ -86,7 +86,7 @@ static int add_super_tone_freq(super_tone_rx_descriptor_t *desc, int freq)
|
|||
/* Merge these two */
|
||||
desc->pitches[desc->used_frequencies][0] = freq;
|
||||
desc->pitches[desc->used_frequencies][1] = i;
|
||||
make_goertzel_descriptor(&desc->desc[desc->pitches[i][1]], (float) (freq + desc->pitches[i][0])/2, BINS);
|
||||
make_goertzel_descriptor(&desc->desc[desc->pitches[i][1]], (float) (freq + desc->pitches[i][0])/2, SUPER_TONE_BINS);
|
||||
desc->used_frequencies++;
|
||||
return desc->pitches[i][1];
|
||||
}
|
||||
|
@ -97,7 +97,7 @@ static int add_super_tone_freq(super_tone_rx_descriptor_t *desc, int freq)
|
|||
{
|
||||
desc->desc = (goertzel_descriptor_t *) realloc(desc->desc, (desc->monitored_frequencies + 5)*sizeof(goertzel_descriptor_t));
|
||||
}
|
||||
make_goertzel_descriptor(&desc->desc[desc->monitored_frequencies++], (float) freq, BINS);
|
||||
make_goertzel_descriptor(&desc->desc[desc->monitored_frequencies++], (float) freq, SUPER_TONE_BINS);
|
||||
desc->used_frequencies++;
|
||||
return desc->pitches[i][1];
|
||||
}
|
||||
|
@ -162,9 +162,9 @@ static int test_cadence(super_tone_rx_segment_t *pattern,
|
|||
j = (rotation + steps - 2)%steps;
|
||||
if (pattern[j].f1 != test[8].f1 || pattern[j].f2 != test[8].f2)
|
||||
return 0;
|
||||
if (pattern[j].min_duration > test[8].min_duration*BINS
|
||||
if (pattern[j].min_duration > test[8].min_duration*SUPER_TONE_BINS
|
||||
||
|
||||
pattern[j].max_duration < test[8].min_duration*BINS)
|
||||
pattern[j].max_duration < test[8].min_duration*SUPER_TONE_BINS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -172,7 +172,7 @@ static int test_cadence(super_tone_rx_segment_t *pattern,
|
|||
j = (rotation + steps - 1)%steps;
|
||||
if (pattern[j].f1 != test[9].f1 || pattern[j].f2 != test[9].f2)
|
||||
return 0;
|
||||
if (pattern[j].max_duration < test[9].min_duration*BINS)
|
||||
if (pattern[j].max_duration < test[9].min_duration*SUPER_TONE_BINS)
|
||||
return 0;
|
||||
}
|
||||
else
|
||||
|
@ -183,9 +183,9 @@ static int test_cadence(super_tone_rx_segment_t *pattern,
|
|||
j = i + 10 - steps;
|
||||
if (pattern[i].f1 != test[j].f1 || pattern[i].f2 != test[j].f2)
|
||||
return 0;
|
||||
if (pattern[i].min_duration > test[j].min_duration*BINS
|
||||
if (pattern[i].min_duration > test[j].min_duration*SUPER_TONE_BINS
|
||||
||
|
||||
pattern[i].max_duration < test[j].min_duration*BINS)
|
||||
pattern[i].max_duration < test[j].min_duration*SUPER_TONE_BINS)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
@ -313,9 +313,9 @@ static void super_tone_chunk(super_tone_rx_state_t *s)
|
|||
int k1;
|
||||
int k2;
|
||||
#if defined(SPANDSP_USE_FIXED_POINT)
|
||||
int32_t res[BINS/2];
|
||||
int32_t res[SUPER_TONE_BINS/2];
|
||||
#else
|
||||
float res[BINS/2];
|
||||
float res[SUPER_TONE_BINS/2];
|
||||
#endif
|
||||
|
||||
for (i = 0; i < s->desc->monitored_frequencies; i++)
|
||||
|
@ -397,7 +397,7 @@ static void super_tone_chunk(super_tone_rx_state_t *s)
|
|||
s->segment_callback(s->callback_data,
|
||||
s->segments[9].f1,
|
||||
s->segments[9].f2,
|
||||
s->segments[9].min_duration*BINS/8);
|
||||
s->segments[9].min_duration*SUPER_TONE_BINS/8);
|
||||
}
|
||||
memcpy (&s->segments[0], &s->segments[1], 9*sizeof(s->segments[0]));
|
||||
s->segments[9].f1 = k1;
|
||||
|
@ -467,7 +467,7 @@ SPAN_DECLARE(int) super_tone_rx(super_tone_rx_state_t *s, const int16_t amp[], i
|
|||
s->energy += xamp*xamp;
|
||||
#endif
|
||||
}
|
||||
if (s->state[0].current_sample >= BINS)
|
||||
if (s->state[0].current_sample >= SUPER_TONE_BINS)
|
||||
{
|
||||
/* We have finished a Goertzel block. */
|
||||
super_tone_chunk(s);
|
||||
|
|
|
@ -440,9 +440,9 @@ static int set_next_tx_type(t38_gateway_state_t *s)
|
|||
/* There is a handler queued, so that is the next one. */
|
||||
set_tx_handler(s, t->next_tx_handler, t->next_tx_user_data);
|
||||
set_next_tx_handler(s, NULL, NULL);
|
||||
if (t->tx_handler == (span_tx_handler_t) &(silence_gen)
|
||||
if (t->tx_handler == (span_tx_handler_t) &silence_gen
|
||||
||
|
||||
t->tx_handler == (span_tx_handler_t) &(tone_gen))
|
||||
t->tx_handler == (span_tx_handler_t) &tone_gen)
|
||||
{
|
||||
set_rx_active(s, TRUE);
|
||||
}
|
||||
|
|
|
@ -111,7 +111,7 @@ static const struct dtmf_to_ascii_s dtmf_to_ascii[] =
|
|||
{"##8", 'W'},
|
||||
{"##9", 'Z'},
|
||||
{"##0", ' '},
|
||||
#if defined(WIN32) || ( defined(__SVR4) && defined (__sun))
|
||||
#if defined(WIN32) || (defined(__SVR4) && defined (__sun))
|
||||
{"#*1", 'X'}, // (Note 1) 111 1011
|
||||
{"#*2", 'X'}, // (Note 1) 111 1100
|
||||
{"#*3", 'X'}, // (Note 1) 111 1101
|
||||
|
|
|
@ -52,6 +52,9 @@
|
|||
|
||||
#include "spandsp/telephony.h"
|
||||
#include "spandsp/logging.h"
|
||||
#include "spandsp/fast_convert.h"
|
||||
#include "spandsp/math_fixed.h"
|
||||
#include "spandsp/saturated.h"
|
||||
#include "spandsp/complex.h"
|
||||
#include "spandsp/vector_float.h"
|
||||
#include "spandsp/complex_vector_float.h"
|
||||
|
@ -77,12 +80,12 @@
|
|||
#include "v22bis_rx_2400_floating_rrc.h"
|
||||
#endif
|
||||
|
||||
#define ms_to_symbols(t) (((t)*600)/1000)
|
||||
#define ms_to_symbols(t) (((t)*600)/1000)
|
||||
|
||||
/*! The adaption rate coefficient for the equalizer */
|
||||
#define EQUALIZER_DELTA 0.25f
|
||||
#define EQUALIZER_DELTA 0.25f
|
||||
/*! The number of phase shifted coefficient set for the pulse shaping/bandpass filter */
|
||||
#define PULSESHAPER_COEFF_SETS 12
|
||||
#define PULSESHAPER_COEFF_SETS 12
|
||||
|
||||
/*
|
||||
The basic method used by the V.22bis receiver is:
|
||||
|
|
|
@ -310,8 +310,8 @@ static __inline__ int get_scrambled_bit(v22bis_state_t *s)
|
|||
|
||||
static complexf_t training_get(v22bis_state_t *s)
|
||||
{
|
||||
complexf_t z;
|
||||
int bits;
|
||||
static const complexf_t zero = {0.0f, 0.0f};
|
||||
|
||||
/* V.22bis training sequence */
|
||||
switch (s->tx.training)
|
||||
|
@ -329,20 +329,17 @@ static complexf_t training_get(v22bis_state_t *s)
|
|||
case V22BIS_TX_TRAINING_STAGE_INITIAL_SILENCE:
|
||||
/* Silence */
|
||||
s->tx.constellation_state = 0;
|
||||
z = complex_setf(0.0f, 0.0f);
|
||||
break;
|
||||
return zero;
|
||||
case V22BIS_TX_TRAINING_STAGE_U11:
|
||||
/* Send continuous unscrambled ones at 1200bps (i.e. 270 degree phase steps). */
|
||||
/* Only the answering modem sends unscrambled ones. It is the first thing exchanged between the modems. */
|
||||
s->tx.constellation_state = (s->tx.constellation_state + phase_steps[3]) & 3;
|
||||
z = v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
|
||||
break;
|
||||
return v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
|
||||
case V22BIS_TX_TRAINING_STAGE_U0011:
|
||||
/* Continuous unscrambled double dibit 00 11 at 1200bps. This is termed the S1 segment in
|
||||
the V.22bis spec. It is only sent to request or accept 2400bps mode, and lasts 100+-3ms. After this
|
||||
timed burst, we unconditionally change to sending scrambled ones at 1200bps. */
|
||||
s->tx.constellation_state = (s->tx.constellation_state + phase_steps[3*(s->tx.training_count & 1)]) & 3;
|
||||
z = v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
|
||||
if (++s->tx.training_count >= ms_to_symbols(100))
|
||||
{
|
||||
span_log(&s->logging, SPAN_LOG_FLOW, "+++ starting S11 after U0011\n");
|
||||
|
@ -357,7 +354,7 @@ static complexf_t training_get(v22bis_state_t *s)
|
|||
s->tx.training = V22BIS_TX_TRAINING_STAGE_TIMED_S11;
|
||||
}
|
||||
}
|
||||
break;
|
||||
return v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
|
||||
case V22BIS_TX_TRAINING_STAGE_TIMED_S11:
|
||||
/* A timed period of scrambled ones at 1200bps. */
|
||||
if (++s->tx.training_count >= ms_to_symbols(756))
|
||||
|
@ -383,8 +380,7 @@ static complexf_t training_get(v22bis_state_t *s)
|
|||
bits = scramble(s, 1);
|
||||
bits = (bits << 1) | scramble(s, 1);
|
||||
s->tx.constellation_state = (s->tx.constellation_state + phase_steps[bits]) & 3;
|
||||
z = v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
|
||||
break;
|
||||
return v22bis_constellation[(s->tx.constellation_state << 2) | 0x01];
|
||||
case V22BIS_TX_TRAINING_STAGE_S1111:
|
||||
/* Scrambled ones at 2400bps. We send a timed 200ms burst, and switch to normal operation at 2400bps */
|
||||
bits = scramble(s, 1);
|
||||
|
@ -392,7 +388,6 @@ static complexf_t training_get(v22bis_state_t *s)
|
|||
s->tx.constellation_state = (s->tx.constellation_state + phase_steps[bits]) & 3;
|
||||
bits = scramble(s, 1);
|
||||
bits = (bits << 1) | scramble(s, 1);
|
||||
z = v22bis_constellation[(s->tx.constellation_state << 2) | bits];
|
||||
if (++s->tx.training_count >= ms_to_symbols(200))
|
||||
{
|
||||
/* We have completed training. Now handle some real work. */
|
||||
|
@ -402,13 +397,9 @@ static complexf_t training_get(v22bis_state_t *s)
|
|||
v22bis_report_status_change(s, SIG_STATUS_TRAINING_SUCCEEDED);
|
||||
s->tx.current_get_bit = s->get_bit;
|
||||
}
|
||||
break;
|
||||
case V22BIS_TX_TRAINING_STAGE_PARKED:
|
||||
default:
|
||||
z = complex_setf(0.0f, 0.0f);
|
||||
break;
|
||||
return v22bis_constellation[(s->tx.constellation_state << 2) | bits];
|
||||
}
|
||||
return z;
|
||||
return zero;
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
|
@ -476,12 +467,12 @@ SPAN_DECLARE_NONSTD(int) v22bis_tx(v22bis_state_t *s, int16_t amp[], int len)
|
|||
x.im += tx_pulseshaper[39 - s->tx.baud_phase][i]*s->tx.rrc_filter[i + s->tx.rrc_filter_step].im;
|
||||
}
|
||||
/* Now create and modulate the carrier */
|
||||
z = dds_complexf(&(s->tx.carrier_phase), s->tx.carrier_phase_rate);
|
||||
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))
|
||||
{
|
||||
/* Add the guard tone */
|
||||
famp += dds_modf(&(s->tx.guard_phase), s->tx.guard_phase_rate, s->tx.guard_level, 0);
|
||||
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);
|
||||
|
@ -499,20 +490,20 @@ SPAN_DECLARE(void) v22bis_tx_power(v22bis_state_t *s, float power)
|
|||
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_level = l*32768.0f;
|
||||
s->tx.guard_tone_gain = l*32768.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_level = l*32768.0f;
|
||||
s->tx.guard_tone_gain = l*32768.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_level = 0;
|
||||
s->tx.guard_tone_gain = 0;
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
|
|
@ -63,7 +63,8 @@
|
|||
|
||||
enum
|
||||
{
|
||||
V8_WAIT_1S,
|
||||
V8_WAIT_1S, /* Start point when sending CI */
|
||||
V8_AWAIT_ANSAM, /* Start point when sending initial silence */
|
||||
V8_CI_ON,
|
||||
V8_CI_OFF,
|
||||
V8_HEARD_ANSAM,
|
||||
|
@ -100,7 +101,8 @@ enum
|
|||
enum
|
||||
{
|
||||
V8_CI_SYNC_OCTET = 0x00,
|
||||
V8_CM_JM_SYNC_OCTET = 0xE0
|
||||
V8_CM_JM_SYNC_OCTET = 0xE0,
|
||||
V8_V92_SYNC_OCTET = 0x55
|
||||
};
|
||||
|
||||
SPAN_DECLARE(const char *) v8_call_function_to_str(int call_function)
|
||||
|
@ -755,7 +757,24 @@ SPAN_DECLARE_NONSTD(int) v8_tx(v8_state_t *s, int16_t *amp, int max_len)
|
|||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void v8_send_ci(v8_state_t *s)
|
||||
static void send_v92(v8_state_t *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (s->result.v92 >= 0)
|
||||
{
|
||||
/* Send 2 V.92 packets */
|
||||
for (i = 0; i < 2; i++)
|
||||
{
|
||||
v8_put_preamble(s);
|
||||
v8_put_byte(s, V8_V92_SYNC_OCTET);
|
||||
v8_put_byte(s, s->result.v92);
|
||||
}
|
||||
}
|
||||
}
|
||||
/*- End of function --------------------------------------------------------*/
|
||||
|
||||
static void send_ci(v8_state_t *s)
|
||||
{
|
||||
int i;
|
||||
|
||||
|
@ -810,7 +829,7 @@ SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len)
|
|||
if ((s->negotiation_timer -= len) > 0)
|
||||
break;
|
||||
fsk_tx_restart(&s->v21tx, &preset_fsk_specs[FSK_V21CH1]);
|
||||
v8_send_ci(s);
|
||||
send_ci(s);
|
||||
s->state = V8_CI_ON;
|
||||
s->fsk_tx_on = TRUE;
|
||||
break;
|
||||
|
@ -851,12 +870,18 @@ SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len)
|
|||
{
|
||||
/* Try again */
|
||||
fsk_tx_restart(&s->v21tx, &preset_fsk_specs[FSK_V21CH1]);
|
||||
v8_send_ci(s);
|
||||
send_ci(s);
|
||||
s->state = V8_CI_ON;
|
||||
s->fsk_tx_on = TRUE;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case V8_AWAIT_ANSAM:
|
||||
residual_samples = modem_connect_tones_rx(&s->ansam_rx, amp, len);
|
||||
/* Check if an ANSam or ANSam/ tone has been detected */
|
||||
if ((tone = modem_connect_tones_rx_get(&s->ansam_rx)) != MODEM_CONNECT_TONES_NONE)
|
||||
handle_modem_connect_tone(s, tone);
|
||||
break;
|
||||
case V8_HEARD_ANSAM:
|
||||
/* We have heard the ANSam or ANSam/ signal, but we still need to wait for the
|
||||
end of the Te timeout period to comply with the spec. */
|
||||
|
@ -865,6 +890,7 @@ SPAN_DECLARE_NONSTD(int) v8_rx(v8_state_t *s, const int16_t *amp, int len)
|
|||
v8_decode_init(s);
|
||||
s->negotiation_timer = ms_to_samples(5000);
|
||||
fsk_tx_restart(&s->v21tx, &preset_fsk_specs[FSK_V21CH1]);
|
||||
send_v92(s);
|
||||
send_cm_jm(s);
|
||||
s->state = V8_CM_ON;
|
||||
s->fsk_tx_on = TRUE;
|
||||
|
@ -1015,9 +1041,16 @@ SPAN_DECLARE(int) v8_restart(v8_state_t *s, int calling_party, v8_parms_t *parms
|
|||
s->calling_party = calling_party;
|
||||
if (s->calling_party)
|
||||
{
|
||||
s->state = V8_WAIT_1S;
|
||||
s->negotiation_timer = ms_to_samples(1000);
|
||||
s->ci_count = 0;
|
||||
if (s->result.send_ci)
|
||||
{
|
||||
s->state = V8_WAIT_1S;
|
||||
s->negotiation_timer = ms_to_samples(1000);
|
||||
s->ci_count = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
s->state = V8_AWAIT_ANSAM;
|
||||
}
|
||||
modem_connect_tones_rx_init(&s->ansam_rx, MODEM_CONNECT_TONES_ANS_PR, NULL, NULL);
|
||||
fsk_tx_init(&s->v21tx, &preset_fsk_specs[FSK_V21CH1], get_bit, s);
|
||||
}
|
||||
|
|
|
@ -107,8 +107,8 @@ SPAN_DECLARE(void) vec_copyl(long double z[], const long double x[], int n)
|
|||
SPAN_DECLARE(void) vec_negatef(float z[], const float x[], int n)
|
||||
{
|
||||
int i;
|
||||
static const uint32_t mask = 0x80000000;
|
||||
static const float *fmask = (float *) &mask;
|
||||
static const uint32_t mask = 0x80000000;
|
||||
static const float *fmask = (float *) &mask;
|
||||
__m128 n1;
|
||||
__m128 n2;
|
||||
|
||||
|
@ -118,7 +118,7 @@ SPAN_DECLARE(void) vec_negatef(float z[], const float x[], int n)
|
|||
for (i -= 4; i >= 0; i -= 4)
|
||||
{
|
||||
n1 = _mm_loadu_ps(x + i);
|
||||
n1 = _mm_xor_ps(n1, n2);
|
||||
n1 = _mm_xor_ps(n1, n2);
|
||||
_mm_storeu_ps(z + i, n1);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -37,7 +37,7 @@
|
|||
|
||||
typedef struct faxtester_state_s faxtester_state_t;
|
||||
|
||||
typedef void (faxtester_flush_handler_t)(faxtester_state_t *s, void *user_data, int which);
|
||||
typedef void (*faxtester_flush_handler_t)(faxtester_state_t *s, void *user_data, int which);
|
||||
|
||||
/*!
|
||||
FAX tester real time frame handler.
|
||||
|
@ -48,13 +48,13 @@ typedef void (faxtester_flush_handler_t)(faxtester_state_t *s, void *user_data,
|
|||
\param msg The HDLC message.
|
||||
\param len The length of the message.
|
||||
*/
|
||||
typedef void (faxtester_real_time_frame_handler_t)(faxtester_state_t *s,
|
||||
void *user_data,
|
||||
int direction,
|
||||
const uint8_t *msg,
|
||||
int len);
|
||||
typedef void (*faxtester_real_time_frame_handler_t)(faxtester_state_t *s,
|
||||
void *user_data,
|
||||
int direction,
|
||||
const uint8_t *msg,
|
||||
int len);
|
||||
|
||||
typedef void (faxtester_front_end_step_complete_handler_t)(faxtester_state_t *s, void *user_data);
|
||||
typedef void (*faxtester_front_end_step_complete_handler_t)(faxtester_state_t *s, void *user_data);
|
||||
|
||||
/*!
|
||||
FAX tester descriptor.
|
||||
|
@ -64,19 +64,19 @@ struct faxtester_state_s
|
|||
/*! \brief Pointer to our current step in the test. */
|
||||
xmlNodePtr cur;
|
||||
|
||||
faxtester_flush_handler_t *flush_handler;
|
||||
faxtester_flush_handler_t flush_handler;
|
||||
void *flush_user_data;
|
||||
|
||||
/*! \brief A pointer to a callback routine to be called when frames are
|
||||
exchanged. */
|
||||
faxtester_real_time_frame_handler_t *real_time_frame_handler;
|
||||
faxtester_real_time_frame_handler_t real_time_frame_handler;
|
||||
/*! \brief An opaque pointer supplied in real time frame callbacks. */
|
||||
void *real_time_frame_user_data;
|
||||
|
||||
faxtester_front_end_step_complete_handler_t *front_end_step_complete_handler;
|
||||
faxtester_front_end_step_complete_handler_t front_end_step_complete_handler;
|
||||
void *front_end_step_complete_user_data;
|
||||
|
||||
faxtester_front_end_step_complete_handler_t *front_end_step_timeout_handler;
|
||||
faxtester_front_end_step_complete_handler_t front_end_step_timeout_handler;
|
||||
void *front_end_step_timeout_user_data;
|
||||
|
||||
const uint8_t *image_buffer;
|
||||
|
@ -149,7 +149,7 @@ void faxtester_send_hdlc_flags(faxtester_state_t *s, int flags);
|
|||
|
||||
void faxtester_send_hdlc_msg(faxtester_state_t *s, const uint8_t *msg, int len, int crc_ok);
|
||||
|
||||
void faxtester_set_flush_handler(faxtester_state_t *s, faxtester_flush_handler_t *handler, void *user_data);
|
||||
void faxtester_set_flush_handler(faxtester_state_t *s, faxtester_flush_handler_t handler, void *user_data);
|
||||
|
||||
/*! Select whether silent audio will be sent when FAX transmit is idle.
|
||||
\brief Select whether silent audio will be sent when FAX transmit is idle.
|
||||
|
@ -167,11 +167,11 @@ void faxtester_set_transmit_on_idle(faxtester_state_t *s, int transmit_on_idle);
|
|||
*/
|
||||
void faxtester_set_tep_mode(faxtester_state_t *s, int use_tep);
|
||||
|
||||
void faxtester_set_real_time_frame_handler(faxtester_state_t *s, faxtester_real_time_frame_handler_t *handler, void *user_data);
|
||||
void faxtester_set_real_time_frame_handler(faxtester_state_t *s, faxtester_real_time_frame_handler_t handler, void *user_data);
|
||||
|
||||
void faxtester_set_front_end_step_complete_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t *handler, void *user_data);
|
||||
void faxtester_set_front_end_step_complete_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t handler, void *user_data);
|
||||
|
||||
void faxtester_set_front_end_step_timeout_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t *handler, void *user_data);
|
||||
void faxtester_set_front_end_step_timeout_handler(faxtester_state_t *s, faxtester_front_end_step_complete_handler_t handler, void *user_data);
|
||||
|
||||
void faxtester_set_timeout(faxtester_state_t *s, int timeout);
|
||||
|
||||
|
|
|
@ -31,7 +31,7 @@
|
|||
|
||||
#define UDPTL_BUF_MASK 15
|
||||
|
||||
typedef int (udptl_rx_packet_handler_t) (void *user_data, const uint8_t msg[], int len, int seq_no);
|
||||
typedef int (*udptl_rx_packet_handler_t) (void *user_data, const uint8_t msg[], int len, int seq_no);
|
||||
|
||||
typedef struct
|
||||
{
|
||||
|
@ -51,7 +51,7 @@ typedef struct
|
|||
|
||||
struct udptl_state_s
|
||||
{
|
||||
udptl_rx_packet_handler_t *rx_packet_handler;
|
||||
udptl_rx_packet_handler_t rx_packet_handler;
|
||||
void *user_data;
|
||||
|
||||
/*! This option indicates the error correction scheme used in transmitted UDPTL
|
||||
|
|
Loading…
Reference in New Issue