diff --git a/libs/spandsp/.update b/libs/spandsp/.update
index df0d5762bf..0c4f2f72a7 100644
--- a/libs/spandsp/.update
+++ b/libs/spandsp/.update
@@ -1 +1 @@
-Wed Oct 1 00:08:32 EDT 2008
+Mon Oct 5 09:33:55 CDT 2009
diff --git a/libs/spandsp/configure.ac b/libs/spandsp/configure.ac
index d23c63016c..58b7af50d0 100644
--- a/libs/spandsp/configure.ac
+++ b/libs/spandsp/configure.ac
@@ -16,7 +16,7 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
-# $Id: configure.ac,v 1.71 2009/07/12 09:29:18 steveu Exp $
+# $Id: configure.ac,v 1.73 2009/10/03 04:37:25 steveu Exp $
# @start 1
@@ -108,20 +108,20 @@ else
CXXFLAGS=${CXXFLAGS-"-g -O2"}
fi
-AC_DEFUN([REMOVE_FROM_VAR],[
- new_val=""
- removed=0
- for i in $$1; do
- if test "x$i" != "x$2"; then
- new_val="$new_val $i"
- else
- removed=1
- fi
- done
- if test $removed = "1"; then
- echo " removed \"$2\" from $1"
- $1=$new_val
- fi
+AC_DEFUN([REMOVE_FROM_VAR],[
+ new_val=""
+ removed=0
+ for i in $$1; do
+ if test "x$i" != "x$2"; then
+ new_val="$new_val $i"
+ else
+ removed=1
+ fi
+ done
+ if test $removed = "1"; then
+ echo " removed \"$2\" from $1"
+ $1=$new_val
+ fi
])
AC_C_CONST
@@ -146,9 +146,9 @@ AC_ARG_ENABLE(sse4_2, [ --enable-sse4-2 Enable SSE4.2 support])
AC_ARG_ENABLE(sse4a, [ --enable-sse4a Enable SSE4A support])
AC_ARG_ENABLE(sse5, [ --enable-sse5 Enable SSE5 support])
AC_ARG_ENABLE(fixed_point, [ --enable-fixed-point Enable fixed point support])
+# The following is for MSVC, where we may be using a local copy of libtiff, built alongside spandsp
AC_ARG_ENABLE(builtin_tiff,
-[AC_HELP_STRING([--enable-builtin-tiff],[build with builtin libtiff])],[enable_builtin_tiff="$enableval"],[enable_builtin_tiff="no"])
-
+ [AC_HELP_STRING([--enable-builtin-tiff],[build with builtin libtiff])],[enable_builtin_tiff="$enableval"],[enable_builtin_tiff="no"])
AC_FUNC_ERROR_AT_LINE
AC_FUNC_VPRINTF
diff --git a/libs/spandsp/spandsp-sim/line_model.c b/libs/spandsp/spandsp-sim/line_model.c
index 0c1e2564e0..5e09b39fd1 100644
--- a/libs/spandsp/spandsp-sim/line_model.c
+++ b/libs/spandsp/spandsp-sim/line_model.c
@@ -22,7 +22,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: line_model.c,v 1.12 2009/06/01 16:27:12 steveu Exp $
+ * $Id: line_model.c,v 1.14 2009/09/23 16:02:59 steveu Exp $
*/
#if defined(HAVE_CONFIG_H)
@@ -54,7 +54,7 @@
#define NULL (void *) 0
#endif
-float null_line_model[] =
+static const float null_line_model[] =
{
0.0,
0.0,
@@ -187,7 +187,7 @@ float null_line_model[] =
1.0
};
-static float *models[] =
+SPAN_DECLARE_DATA const float *line_models[] =
{
null_line_model, /* 0 */
proakis_line_model,
@@ -225,7 +225,7 @@ static float calc_near_line_filter(one_way_line_model_state_t *s, float v)
s->near_buf_ptr = p;
/* Apply the filter */
- sum = 0;
+ sum = 0.0f;
for (j = 0; j < s->near_filter_len; j++)
{
sum += s->near_filter[j]*s->near_buf[p];
@@ -254,7 +254,7 @@ static float calc_far_line_filter(one_way_line_model_state_t *s, float v)
s->far_buf_ptr = p;
/* Apply the filter */
- sum = 0;
+ sum = 0.0f;
for (j = 0; j < s->far_filter_len; j++)
{
sum += s->far_filter[j]*s->far_buf[p];
@@ -479,10 +479,10 @@ SPAN_DECLARE(one_way_line_model_state_t *) one_way_line_model_init(int model, fl
s->munge = codec_munge_init(codec, rbs_pattern);
- s->near_filter = models[model];
+ s->near_filter = line_models[model];
s->near_filter_len = 129;
- s->far_filter = models[model];
+ s->far_filter = line_models[model];
s->far_filter_len = 129;
/* Put half the noise in each analogue section */
@@ -526,14 +526,14 @@ SPAN_DECLARE(both_ways_line_model_state_t *) both_ways_line_model_init(int model
s->line1.bulk_delay_ptr = 0;
s->line2.bulk_delay_ptr = 0;
- s->line1.near_filter = models[model1];
+ s->line1.near_filter = line_models[model1];
s->line1.near_filter_len = 129;
- s->line2.near_filter = models[model2];
+ s->line2.near_filter = line_models[model2];
s->line2.near_filter_len = 129;
- s->line1.far_filter = models[model1];
+ s->line1.far_filter = line_models[model1];
s->line1.far_filter_len = 129;
- s->line2.far_filter = models[model2];
+ s->line2.far_filter = line_models[model2];
s->line2.far_filter_len = 129;
/* Put half the noise in each analogue section */
diff --git a/libs/spandsp/spandsp-sim/make_line_models.c b/libs/spandsp/spandsp-sim/make_line_models.c
index aabbfd2602..42fac11fa8 100644
--- a/libs/spandsp/spandsp-sim/make_line_models.c
+++ b/libs/spandsp/spandsp-sim/make_line_models.c
@@ -22,7 +22,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: make_line_models.c,v 1.9 2009/02/10 17:49:20 steveu Exp $
+ * $Id: make_line_models.c,v 1.10 2009/09/23 16:02:59 steveu Exp $
*/
/*! \page make_line_models_page Telephony line model construction
@@ -849,7 +849,8 @@ static void generate_ad_edd(void)
offset = (f - edd[l - 1].freq)/(edd[l].freq - edd[l - 1].freq);
delay = (1.0f - offset)*edd[l - 1].edd[k] + offset*edd[l].edd[k];
}
- phase = 2.0f*M_PI*f*delay*0.001f;
+ //phase = 2.0f*M_PI*f*delay*0.001f;
+ phase = 0.0f;
#if defined(HAVE_FFTW3_H)
in[i][0] = amp*cosf(phase);
in[i][1] = amp*sinf(phase);
@@ -874,7 +875,7 @@ static void generate_ad_edd(void)
fprintf(outfile, "/* V.56bis AD-%d, EDD%d */\n", (j == 0) ? 1 : j + 4, k + 1);
- fprintf(outfile, "float ad_%d_edd_%d_model[] =\n", (j == 0) ? 1 : j + 4, k + 1);
+ fprintf(outfile, "const float ad_%d_edd_%d_model[] =\n", (j == 0) ? 1 : j + 4, k + 1);
fprintf(outfile, "{\n");
/* Normalise the filter's gain */
pw = 0.0f;
@@ -955,7 +956,8 @@ static void generate_proakis(void)
/* Linear interpolation */
amp = ((1.0f - offset)*proakis[index].amp + offset*proakis[index + 1].amp)/2.3f;
delay = (1.0f - offset)*proakis[index].delay + offset*proakis[index + 1].delay;
- phase = 2.0f*M_PI*f*delay*0.001f;
+ //phase = 2.0f*M_PI*f*delay*0.001f;
+ phase = 0.0f;
#if defined(HAVE_FFTW3_H)
in[i][0] = amp*cosf(phase);
in[i][1] = amp*sinf(phase);
@@ -978,7 +980,7 @@ static void generate_proakis(void)
fprintf(outfile, "/* Medium range telephone line response\n");
fprintf(outfile, " (from p 537, Digital Communication, John G. Proakis */\n");
- fprintf(outfile, "float proakis_line_model[] =\n");
+ fprintf(outfile, "const float proakis_line_model[] =\n");
fprintf(outfile, "{\n");
/* Normalise the filter's gain */
pw = 0.0f;
diff --git a/libs/spandsp/spandsp-sim/spandsp/line_model.h b/libs/spandsp/spandsp-sim/spandsp/line_model.h
index ebe1592bcc..a8131e2707 100644
--- a/libs/spandsp/spandsp-sim/spandsp/line_model.h
+++ b/libs/spandsp/spandsp-sim/spandsp/line_model.h
@@ -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: line_model.h,v 1.6 2009/05/31 14:47:10 steveu Exp $
+ * $Id: line_model.h,v 1.7 2009/09/23 16:02:59 steveu Exp $
*/
/*! \file */
@@ -132,6 +132,8 @@ extern "C"
{
#endif
+SPAN_DECLARE_DATA extern const float *line_models[];
+
SPAN_DECLARE(void) both_ways_line_model(both_ways_line_model_state_t *s,
int16_t output1[],
const int16_t input1[],
diff --git a/libs/spandsp/spandsp/fax-tests.dtd b/libs/spandsp/spandsp/fax-tests.dtd
index 38dd7cd0d8..beb4eae3ef 100644
--- a/libs/spandsp/spandsp/fax-tests.dtd
+++ b/libs/spandsp/spandsp/fax-tests.dtd
@@ -1,6 +1,7 @@
+
modems.rx_handler = handler;
+ s->modems.rx_handler = rx_handler;
+ s->modems.rx_fillin_handler = fillin_handler;
s->modems.rx_user_data = user_data;
}
/*- End of function --------------------------------------------------------*/
@@ -162,7 +166,7 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
/* The fast modem has trained, so we no longer need to run the slow
one in parallel. */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->v17_rx));
- set_rx_handler(t, (span_rx_handler_t *) &v17_rx, &s->v17_rx);
+ set_rx_handler(t, (span_rx_handler_t *) &v17_rx, (span_rx_fillin_handler_t *) &v17_rx_fillin, &s->v17_rx);
}
else
{
@@ -172,13 +176,26 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
/* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
- set_rx_handler(t, (span_rx_handler_t *) &fsk_rx, &s->v21_rx);
+ set_rx_handler(t, (span_rx_handler_t *) &fsk_rx, (span_rx_fillin_handler_t *) &fsk_rx_fillin, &s->v21_rx);
}
}
return 0;
}
/*- End of function --------------------------------------------------------*/
+static int v17_v21_rx_fillin(void *user_data, int len)
+{
+ fax_state_t *t;
+ fax_modems_state_t *s;
+
+ t = (fax_state_t *) user_data;
+ s = &t->modems;
+ v17_rx_fillin(&s->v17_rx, len);
+ fsk_rx_fillin(&s->v21_rx, len);
+ return 0;
+}
+/*- End of function --------------------------------------------------------*/
+
static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
{
fax_state_t *t;
@@ -192,7 +209,7 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
/* The fast modem has trained, so we no longer need to run the slow
one in parallel. */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->v27ter_rx));
- set_rx_handler(t, (span_rx_handler_t *) &v27ter_rx, &s->v27ter_rx);
+ set_rx_handler(t, (span_rx_handler_t *) &v27ter_rx, (span_rx_fillin_handler_t *) &v27ter_rx_fillin, &s->v27ter_rx);
}
else
{
@@ -202,13 +219,26 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
/* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
- set_rx_handler(t, (span_rx_handler_t *) &fsk_rx, &s->v21_rx);
+ set_rx_handler(t, (span_rx_handler_t *) &fsk_rx, (span_rx_fillin_handler_t *) &fsk_rx_fillin, &s->v21_rx);
}
}
return 0;
}
/*- End of function --------------------------------------------------------*/
+static int v27ter_v21_rx_fillin(void *user_data, int len)
+{
+ fax_state_t *t;
+ fax_modems_state_t *s;
+
+ t = (fax_state_t *) user_data;
+ s = &t->modems;
+ v27ter_rx_fillin(&s->v27ter_rx, len);
+ fsk_rx_fillin(&s->v21_rx, len);
+ return 0;
+}
+/*- End of function --------------------------------------------------------*/
+
static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
{
fax_state_t *t;
@@ -222,7 +252,7 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
/* The fast modem has trained, so we no longer need to run the slow
one in parallel. */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->v29_rx));
- set_rx_handler(t, (span_rx_handler_t *) &v29_rx, &s->v29_rx);
+ set_rx_handler(t, (span_rx_handler_t *) &v29_rx, (span_rx_fillin_handler_t *) &v29_rx_fillin, &s->v29_rx);
}
else
{
@@ -232,13 +262,26 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
/* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
- set_rx_handler(t, (span_rx_handler_t *) &fsk_rx, &s->v21_rx);
+ set_rx_handler(t, (span_rx_handler_t *) &fsk_rx, (span_rx_fillin_handler_t *) &fsk_rx_fillin, &s->v21_rx);
}
}
return 0;
}
/*- End of function --------------------------------------------------------*/
+static int v29_v21_rx_fillin(void *user_data, int len)
+{
+ fax_state_t *t;
+ fax_modems_state_t *s;
+
+ t = (fax_state_t *) user_data;
+ s = &t->modems;
+ v29_rx_fillin(&s->v29_rx, len);
+ fsk_rx_fillin(&s->v21_rx, len);
+ return 0;
+}
+/*- End of function --------------------------------------------------------*/
+
SPAN_DECLARE(int) fax_rx(fax_state_t *s, int16_t *amp, int len)
{
int i;
@@ -276,26 +319,9 @@ SPAN_DECLARE(int) fax_rx_fillin(fax_state_t *s, int len)
write(s->modems.audio_rx_log, amp, len*sizeof(int16_t));
}
#endif
- t30_timer_update(&s->t30, len);
/* Call the fillin function of the current modem (if there is one). */
- switch (s->modems.current_rx_type)
- {
- case T30_MODEM_V21:
- len = fsk_rx_fillin(&s->modems.v21_rx, len);
- break;
- case T30_MODEM_V27TER:
- /* TODO: what about FSK in the early stages */
- len = v27ter_rx_fillin(&s->modems.v27ter_rx, len);
- break;
- case T30_MODEM_V29:
- /* TODO: what about FSK in the early stages */
- len = v29_rx_fillin(&s->modems.v29_rx, len);
- break;
- case T30_MODEM_V17:
- /* TODO: what about FSK in the early stages */
- len = v17_rx_fillin(&s->modems.v17_rx, len);
- break;
- }
+ s->modems.rx_fillin_handler(s->modems.rx_user_data, len);
+ t30_timer_update(&s->t30, len);
return len;
}
/*- End of function --------------------------------------------------------*/
@@ -399,27 +425,27 @@ static void fax_set_rx_type(void *user_data, int type, int bit_rate, int short_t
case T30_MODEM_V21:
fsk_rx_init(&t->v21_rx, &preset_fsk_specs[FSK_V21CH2], TRUE, (put_bit_func_t) hdlc_rx_put_bit, put_bit_user_data);
fsk_rx_signal_cutoff(&t->v21_rx, -45.5f);
- set_rx_handler(s, (span_rx_handler_t *) &fsk_rx, &t->v21_rx);
+ set_rx_handler(s, (span_rx_handler_t *) &fsk_rx, (span_rx_fillin_handler_t *) &fsk_rx_fillin, &t->v21_rx);
break;
case T30_MODEM_V27TER:
v27ter_rx_restart(&t->v27ter_rx, bit_rate, FALSE);
v27ter_rx_set_put_bit(&t->v27ter_rx, put_bit_func, put_bit_user_data);
- set_rx_handler(s, &v27ter_v21_rx, s);
+ set_rx_handler(s, &v27ter_v21_rx, &v27ter_v21_rx_fillin, s);
break;
case T30_MODEM_V29:
v29_rx_restart(&t->v29_rx, bit_rate, FALSE);
v29_rx_set_put_bit(&t->v29_rx, put_bit_func, put_bit_user_data);
- set_rx_handler(s, &v29_v21_rx, s);
+ set_rx_handler(s, &v29_v21_rx, &v29_v21_rx_fillin, s);
break;
case T30_MODEM_V17:
v17_rx_restart(&t->v17_rx, bit_rate, short_train);
v17_rx_set_put_bit(&t->v17_rx, put_bit_func, put_bit_user_data);
- set_rx_handler(s, &v17_v21_rx, s);
+ set_rx_handler(s, &v17_v21_rx, &v17_v21_rx_fillin, s);
break;
case T30_MODEM_DONE:
span_log(&s->logging, SPAN_LOG_FLOW, "FAX exchange complete\n");
default:
- set_rx_handler(s, (span_rx_handler_t *) &span_dummy_rx, s);
+ set_rx_handler(s, (span_rx_handler_t *) &span_dummy_rx, (span_rx_fillin_handler_t *) &span_dummy_rx_fillin, s);
break;
}
}
diff --git a/libs/spandsp/src/fax_modems.c b/libs/spandsp/src/fax_modems.c
index 3ab3e3b151..740569e4e0 100644
--- a/libs/spandsp/src/fax_modems.c
+++ b/libs/spandsp/src/fax_modems.c
@@ -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: fax_modems.c,v 1.5 2009/04/12 03:29:58 steveu Exp $
+ * $Id: fax_modems.c,v 1.6 2009/09/04 14:38:46 steveu Exp $
*/
/*! \file */
@@ -101,6 +101,7 @@ SPAN_DECLARE(int) fax_modems_v17_v21_rx(void *user_data, const int16_t amp[], in
be receiving valid V.21 */
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
s->rx_handler = (span_rx_handler_t *) &fsk_rx;
+ s->rx_fillin_handler = (span_rx_fillin_handler_t *) &fsk_rx_fillin;
s->rx_user_data = &s->v21_rx;
}
return 0;
@@ -131,6 +132,7 @@ SPAN_DECLARE(int) fax_modems_v27ter_v21_rx(void *user_data, const int16_t amp[],
be receiving valid V.21 */
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
s->rx_handler = (span_rx_handler_t *) &fsk_rx;
+ s->rx_fillin_handler = (span_rx_fillin_handler_t *) &fsk_rx_fillin;
s->rx_user_data = &s->v21_rx;
}
return 0;
@@ -161,6 +163,7 @@ SPAN_DECLARE(int) fax_modems_v29_v21_rx(void *user_data, const int16_t amp[], in
be receiving valid V.21 */
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
s->rx_handler = (span_rx_handler_t *) &fsk_rx;
+ s->rx_fillin_handler = (span_rx_fillin_handler_t *) &fsk_rx_fillin;
s->rx_user_data = &s->v21_rx;
}
return 0;
@@ -196,6 +199,7 @@ static void v17_rx_status_handler(void *user_data, int status)
case SIG_STATUS_TRAINING_SUCCEEDED:
span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->v17_rx));
s->rx_handler = (span_rx_handler_t *) &v17_rx;
+ s->rx_fillin_handler = (span_rx_fillin_handler_t *) &v17_rx_fillin;
s->rx_user_data = &s->v17_rx;
break;
}
@@ -212,6 +216,7 @@ static void v27ter_rx_status_handler(void *user_data, int status)
case SIG_STATUS_TRAINING_SUCCEEDED:
span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->v27ter_rx));
s->rx_handler = (span_rx_handler_t *) &v27ter_rx;
+ s->rx_fillin_handler = (span_rx_fillin_handler_t *) &v27ter_rx_fillin;
s->rx_user_data = &s->v27ter_rx;
break;
}
@@ -228,6 +233,7 @@ static void v29_rx_status_handler(void *user_data, int status)
case SIG_STATUS_TRAINING_SUCCEEDED:
span_log(&s->logging, SPAN_LOG_FLOW, "Switching to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->v29_rx));
s->rx_handler = (span_rx_handler_t *) &v29_rx;
+ s->rx_fillin_handler = (span_rx_fillin_handler_t *) &v29_rx_fillin;
s->rx_user_data = &s->v29_rx;
break;
}
@@ -300,6 +306,7 @@ SPAN_DECLARE(fax_modems_state_t *) fax_modems_init(fax_modems_state_t *s,
s->rx_signal_present = FALSE;
s->rx_handler = (span_rx_handler_t *) &span_dummy_rx;
+ s->rx_fillin_handler = (span_rx_fillin_handler_t *) &span_dummy_rx;
s->rx_user_data = NULL;
s->tx_handler = (span_tx_handler_t *) &silence_gen;
s->tx_user_data = &s->silence_gen;
diff --git a/libs/spandsp/src/libspandsp.2005.vcproj b/libs/spandsp/src/libspandsp.2005.vcproj
index 5479159aab..453f519b61 100644
--- a/libs/spandsp/src/libspandsp.2005.vcproj
+++ b/libs/spandsp/src/libspandsp.2005.vcproj
@@ -142,6 +142,7 @@
+
@@ -219,6 +220,7 @@
+
@@ -257,6 +259,7 @@
+
@@ -269,6 +272,7 @@
+
@@ -277,6 +281,7 @@
+
diff --git a/libs/spandsp/src/libspandsp.2008.vcproj b/libs/spandsp/src/libspandsp.2008.vcproj
index 8b18789579..c0bb6f77e9 100644
--- a/libs/spandsp/src/libspandsp.2008.vcproj
+++ b/libs/spandsp/src/libspandsp.2008.vcproj
@@ -212,6 +212,7 @@
+
@@ -289,6 +290,7 @@
+
@@ -327,6 +329,7 @@
+
@@ -339,6 +342,7 @@
+
@@ -347,6 +351,7 @@
+
diff --git a/libs/spandsp/src/libspandsp.dsp b/libs/spandsp/src/libspandsp.dsp
index 6c062168bb..96f955ebf4 100644
--- a/libs/spandsp/src/libspandsp.dsp
+++ b/libs/spandsp/src/libspandsp.dsp
@@ -293,6 +293,10 @@ SOURCE=.\super_tone_tx.c
# End Source File
# Begin Source File
+SOURCE=.\swept_tone.c
+# End Source File
+# Begin Source File
+
SOURCE=.\t4.c
# End Source File
# Begin Source File
@@ -599,6 +603,10 @@ SOURCE=.\spandsp/super_tone_tx.h
# End Source File
# Begin Source File
+SOURCE=.\spandsp/swept_tone.h
+# End Source File
+# Begin Source File
+
SOURCE=.\spandsp/t4.h
# End Source File
# Begin Source File
@@ -751,6 +759,10 @@ SOURCE=.\spandsp/private/dtmf.h
# End Source File
# Begin Source File
+SOURCE=.\spandsp/private/echo.h
+# End Source File
+# Begin Source File
+
SOURCE=.\spandsp/private/fax.h
# End Source File
# Begin Source File
@@ -799,6 +811,10 @@ SOURCE=.\spandsp/private/modem_connect_tones.h
# End Source File
# Begin Source File
+SOURCE=.\spandsp/private/modem_echo.h
+# End Source File
+# Begin Source File
+
SOURCE=.\spandsp/private/noise.h
# End Source File
# Begin Source File
@@ -831,6 +847,10 @@ SOURCE=.\spandsp/private/super_tone_tx.h
# End Source File
# Begin Source File
+SOURCE=.\spandsp/private/swept_tone.h
+# End Source File
+# Begin Source File
+
SOURCE=.\spandsp/private/t30.h
# End Source File
# Begin Source File
diff --git a/libs/spandsp/src/make_modem_filter.c b/libs/spandsp/src/make_modem_filter.c
index ce659b30c3..b158f413c8 100644
--- a/libs/spandsp/src/make_modem_filter.c
+++ b/libs/spandsp/src/make_modem_filter.c
@@ -23,7 +23,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: make_modem_filter.c,v 1.16 2009/07/10 13:15:56 steveu Exp $
+ * $Id: make_modem_filter.c,v 1.17 2009/10/03 04:37:25 steveu Exp $
*/
#if defined(HAVE_CONFIG_H)
@@ -44,7 +44,7 @@
#include
#include
#include
-#if defined(__sunos) || defined(__solaris) || defined(__sun)
+#if defined(__sunos) || defined(__solaris) || defined(__sun)
#include
#endif
diff --git a/libs/spandsp/src/modem_echo.c b/libs/spandsp/src/modem_echo.c
index 8ed03c983b..c31d4cba31 100644
--- a/libs/spandsp/src/modem_echo.c
+++ b/libs/spandsp/src/modem_echo.c
@@ -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: modem_echo.c,v 1.25 2009/02/03 16:28:39 steveu Exp $
+ * $Id: modem_echo.c,v 1.26 2009/09/22 13:11:04 steveu Exp $
*/
/*! \file */
@@ -53,6 +53,8 @@
#include "spandsp/dc_restore.h"
#include "spandsp/modem_echo.h"
+#include "spandsp/private/modem_echo.h"
+
SPAN_DECLARE(modem_echo_can_state_t *) modem_echo_can_create(int len)
{
modem_echo_can_state_t *ec;
diff --git a/libs/spandsp/src/msvc/spandsp.h b/libs/spandsp/src/msvc/spandsp.h
index 81b74f172f..25f705f5ab 100644
--- a/libs/spandsp/src/msvc/spandsp.h
+++ b/libs/spandsp/src/msvc/spandsp.h
@@ -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: spandsp.h.in,v 1.18 2009/04/02 13:43:49 steveu Exp $
+ * $Id: spandsp.h.in,v 1.19 2009/09/22 13:11:04 steveu Exp $
*/
/*! \file */
@@ -69,6 +69,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/libs/spandsp/src/sig_tone.c b/libs/spandsp/src/sig_tone.c
index dea3ed79f3..0183dadedb 100644
--- a/libs/spandsp/src/sig_tone.c
+++ b/libs/spandsp/src/sig_tone.c
@@ -23,7 +23,7 @@
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: sig_tone.c,v 1.32 2009/04/12 14:18:02 steveu Exp $
+ * $Id: sig_tone.c,v 1.33 2009/09/04 14:38:46 steveu Exp $
*/
/*! \file */
@@ -44,14 +44,17 @@
#include "floating_fudge.h"
#include
#include
+#include
#undef SPANDSP_USE_FIXED_POINT
#include "spandsp/telephony.h"
#include "spandsp/fast_convert.h"
#include "spandsp/dc_restore.h"
#include "spandsp/saturated.h"
+#include "spandsp/vector_int.h"
#include "spandsp/complex.h"
#include "spandsp/dds.h"
+#include "spandsp/super_tone_rx.h"
#include "spandsp/sig_tone.h"
#include "spandsp/private/sig_tone.h"
@@ -67,12 +70,12 @@ sig_tone_descriptor_t sig_tones[4] =
{
/* 2280Hz (e.g. AC15, and many other European protocols) */
{2280, 0},
- {-10, -20}, /* -10+-1 dBmO and -20+-1 dBm0 */
- 400*(SAMPLE_RATE/1000), /* 300ms to 550ms */
+ {{-10, -20}, {0, 0}}, /* -10+-1 dBmO and -20+-1 dBm0 */
+ ms_to_samples(400), /* 300ms to 550ms */
- 225*(SAMPLE_RATE/1000),
+ ms_to_samples(225),
- 225*(SAMPLE_RATE/1000),
+ ms_to_samples(225),
TRUE,
24,
@@ -135,12 +138,12 @@ sig_tone_descriptor_t sig_tones[4] =
{
/* 2600Hz (e.g. many US protocols) */
{2600, 0},
- {-8, -8},
- 400*(SAMPLE_RATE/1000),
+ {{-8, -8}, {0, 0}},
+ ms_to_samples(400),
- 225*(SAMPLE_RATE/1000),
+ ms_to_samples(225),
- 225*(SAMPLE_RATE/1000),
+ ms_to_samples(225),
FALSE,
24,
@@ -202,13 +205,13 @@ sig_tone_descriptor_t sig_tones[4] =
},
{
/* 2400Hz/2600Hz (e.g. SS5 and SS5bis) */
- {2400, 2600},
- {-8, -8},
- 400*(SAMPLE_RATE/1000),
+ {2600, 2400},
+ {{-8, -8}, {-8, -8}},
+ ms_to_samples(400),
- 225*(SAMPLE_RATE/1000),
+ ms_to_samples(225),
- 225*(SAMPLE_RATE/1000),
+ ms_to_samples(225),
FALSE,
24,
@@ -276,19 +279,40 @@ SPAN_DECLARE(int) sig_tone_tx(sig_tone_tx_state_t *s, int16_t amp[], int len)
int j;
int n;
int16_t tone;
- int update;
+ int need_update;
int high_low;
for (i = 0; i < len; i += n)
{
- if (s->current_tx_timeout < len - i)
- n = s->current_tx_timeout;
+ if (s->current_tx_timeout)
+ {
+ if (s->current_tx_timeout <= len - i)
+ {
+ n = s->current_tx_timeout;
+ need_update = TRUE;
+ }
+ else
+ {
+ n = len - i;
+ need_update = FALSE;
+ }
+ s->current_tx_timeout -= n;
+ }
else
+ {
n = len - i;
+ need_update = FALSE;
+ }
+ if (!(s->current_tx_tone & SIG_TONE_TX_PASSTHROUGH))
+ vec_zeroi16(&[i], n);
+ /*endif*/
if ((s->current_tx_tone & (SIG_TONE_1_PRESENT || SIG_TONE_2_PRESENT)))
{
/* Are we in the early phase (high tone energy level), or the sustaining
phase (low tone energy level) of tone generation? */
+ /* This doesn't try to get the high/low timing precise, as there is no
+ value in doing so. It works block by block, and the blocks are normally
+ quite short. */
if (s->high_low_timer > 0)
{
if (n > s->high_low_timer)
@@ -301,47 +325,30 @@ SPAN_DECLARE(int) sig_tone_tx(sig_tone_tx_state_t *s, int16_t amp[], int len)
high_low = 1;
}
/*endif*/
- if (s->current_tx_tone & SIG_TONE_TX_PASSTHROUGH)
+ if ((s->current_tx_tone & SIG_TONE_1_PRESENT) && s->phase_rate[0])
{
for (j = i; j < i + n; j++)
{
- tone = dds_mod(&(s->phase_acc[0]), s->phase_rate[0], s->tone_scaling[high_low], 0);
+ tone = dds_mod(&(s->phase_acc[0]), s->phase_rate[0], s->tone_scaling[0][high_low], 0);
amp[j] = saturate(amp[j] + tone);
}
/*endfor*/
}
- else
+ /*endif*/
+ if ((s->current_tx_tone & SIG_TONE_2_PRESENT) && s->phase_rate[1])
{
for (j = i; j < i + n; j++)
- amp[j] = dds_mod(&(s->phase_acc[0]), s->phase_rate[0], s->tone_scaling[high_low], 0);
+ {
+ tone = dds_mod(&(s->phase_acc[1]), s->phase_rate[1], s->tone_scaling[1][high_low], 0);
+ amp[j] = saturate(amp[j] + tone);
+ }
/*endfor*/
}
/*endif*/
}
- else
- {
- /* There is no tone. We either leave the audio in the buffer, or silence it. */
- if (!(s->current_tx_tone & SIG_TONE_TX_PASSTHROUGH))
- {
- /* Zap any audio in the buffer */
- memset(amp + i, 0, sizeof(int16_t)*n);
- }
- /*endif*/
- }
/*endif*/
- if ((s->current_tx_timeout -= n) <= 0)
- {
- if (s->sig_update)
- {
- update = s->sig_update(s->user_data, SIG_TONE_UPDATE_REQUEST);
- if ((update & 0x03) == 0x03)
- s->high_low_timer = s->desc->high_low_timeout;
- /*endif*/
- s->current_tx_tone = update & 0xFFFF;
- s->current_tx_timeout = (update >> 16) & 0xFFFF;
- }
- /*endif*/
- }
+ if (need_update && s->sig_update)
+ s->sig_update(s->user_data, SIG_TONE_TX_UPDATE_REQUEST, 0, 0);
/*endif*/
}
/*endfor*/
@@ -349,17 +356,22 @@ SPAN_DECLARE(int) sig_tone_tx(sig_tone_tx_state_t *s, int16_t amp[], int len)
}
/*- End of function --------------------------------------------------------*/
-SPAN_DECLARE(void) sig_tone_tx_set_mode(sig_tone_tx_state_t *s, int mode)
+SPAN_DECLARE(void) sig_tone_tx_set_mode(sig_tone_tx_state_t *s, int mode, int duration)
{
- if ((mode & 0x03) == 0x03 && !(s->current_tx_tone & SIG_TONE_1_PRESENT))
+ int old_tones;
+ int new_tones;
+
+ old_tones = s->current_tx_tone & (SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT);
+ new_tones = mode & (SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT);
+ if (new_tones && old_tones != new_tones)
s->high_low_timer = s->desc->high_low_timeout;
/*endif*/
- s->current_tx_tone = mode & 0xFFFF;
- s->current_tx_timeout = (mode >> 16) & 0xFFFF;
+ s->current_tx_tone = mode;
+ s->current_tx_timeout = duration;
}
/*- End of function --------------------------------------------------------*/
-SPAN_DECLARE(sig_tone_tx_state_t *) sig_tone_tx_init(sig_tone_tx_state_t *s, int tone_type, sig_tone_func_t sig_update, void *user_data)
+SPAN_DECLARE(sig_tone_tx_state_t *) sig_tone_tx_init(sig_tone_tx_state_t *s, int tone_type, tone_report_func_t sig_update, void *user_data)
{
int i;
@@ -385,7 +397,8 @@ SPAN_DECLARE(sig_tone_tx_state_t *) sig_tone_tx_init(sig_tone_tx_state_t *s, int
s->phase_rate[i] = dds_phase_rate((float) s->desc->tone_freq[i]);
else
s->phase_rate[i] = 0;
- s->tone_scaling[i] = dds_scaling_dbm0((float) s->desc->tone_amp[i]);
+ s->tone_scaling[i][0] = dds_scaling_dbm0((float) s->desc->tone_amp[i][0]);
+ s->tone_scaling[i][1] = dds_scaling_dbm0((float) s->desc->tone_amp[i][1]);
}
return s;
}
@@ -404,6 +417,7 @@ SPAN_DECLARE(int) sig_tone_tx_free(sig_tone_tx_state_t *s)
return 0;
}
/*- End of function --------------------------------------------------------*/
+
SPAN_DECLARE(int) sig_tone_rx(sig_tone_rx_state_t *s, int16_t amp[], int len)
{
#if defined(SPANDSP_USE_FIXED_POINT)
@@ -422,7 +436,7 @@ SPAN_DECLARE(int) sig_tone_rx(sig_tone_rx_state_t *s, int16_t amp[], int len)
for (i = 0; i < len; i++)
{
- if (s->signaling_state_duration < 0xFFFF)
+ if (s->signaling_state_duration < INT_MAX)
s->signaling_state_duration++;
/*endif*/
notched_signal = 0;
@@ -529,7 +543,7 @@ SPAN_DECLARE(int) sig_tone_rx(sig_tone_rx_state_t *s, int16_t amp[], int len)
if (!s->tone_present)
{
if (s->sig_update)
- s->sig_update(s->user_data, SIG_TONE_1_CHANGE | (s->signaling_state_duration << 16));
+ s->sig_update(s->user_data, SIG_TONE_1_CHANGE, 0, s->signaling_state_duration);
/*endif*/
s->signaling_state_duration = 0;
}
@@ -541,15 +555,15 @@ SPAN_DECLARE(int) sig_tone_rx(sig_tone_rx_state_t *s, int16_t amp[], int len)
if (s->tone_present)
{
if (s->sig_update)
- s->sig_update(s->user_data, SIG_TONE_1_CHANGE | SIG_TONE_1_PRESENT | (s->signaling_state_duration << 16));
+ s->sig_update(s->user_data, SIG_TONE_1_CHANGE | SIG_TONE_1_PRESENT, 0, s->signaling_state_duration);
/*endif*/
s->signaling_state_duration = 0;
}
/*endif*/
}
/*endif*/
- /* Notch insertion logic */
-
+
+ /* Notch insertion logic */
/* tone_present and tone_on are equivalent in flat mode */
if (s->tone_present)
{
@@ -590,7 +604,7 @@ SPAN_DECLARE(int) sig_tone_rx(sig_tone_rx_state_t *s, int16_t amp[], int len)
s->tone_persistence_timeout = s->desc->tone_off_check_time;
s->notch_insertion_timeout = s->desc->notch_lag_time;
if (s->sig_update)
- s->sig_update(s->user_data, SIG_TONE_1_CHANGE | SIG_TONE_1_PRESENT | (s->signaling_state_duration << 16));
+ s->sig_update(s->user_data, SIG_TONE_1_CHANGE | SIG_TONE_1_PRESENT, 0, s->signaling_state_duration);
/*endif*/
s->signaling_state_duration = 0;
}
@@ -626,7 +640,7 @@ SPAN_DECLARE(int) sig_tone_rx(sig_tone_rx_state_t *s, int16_t amp[], int len)
s->tone_present = FALSE;
s->tone_persistence_timeout = s->desc->tone_on_check_time;
if (s->sig_update)
- s->sig_update(s->user_data, SIG_TONE_1_CHANGE | (s->signaling_state_duration << 16));
+ s->sig_update(s->user_data, SIG_TONE_1_CHANGE, 0, s->signaling_state_duration);
/*endif*/
s->signaling_state_duration = 0;
}
@@ -648,7 +662,7 @@ SPAN_DECLARE(int) sig_tone_rx(sig_tone_rx_state_t *s, int16_t amp[], int len)
if ((s->current_rx_tone & SIG_TONE_RX_PASSTHROUGH))
{
- if (s->notch_enabled)
+ if ((s->current_rx_tone & SIG_TONE_RX_FILTER_TONE) || s->notch_enabled)
amp[i] = (int16_t) notched_signal;
/*endif*/
}
@@ -663,7 +677,13 @@ SPAN_DECLARE(int) sig_tone_rx(sig_tone_rx_state_t *s, int16_t amp[], int len)
}
/*- End of function --------------------------------------------------------*/
-SPAN_DECLARE(sig_tone_rx_state_t *) sig_tone_rx_init(sig_tone_rx_state_t *s, int tone_type, sig_tone_func_t sig_update, void *user_data)
+SPAN_DECLARE(void) sig_tone_rx_set_mode(sig_tone_rx_state_t *s, int mode, int duration)
+{
+ s->current_rx_tone = mode;
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(sig_tone_rx_state_t *) sig_tone_rx_init(sig_tone_rx_state_t *s, int tone_type, tone_report_func_t sig_update, void *user_data)
{
if (sig_update == NULL || tone_type < 1 || tone_type > 3)
return NULL;
diff --git a/libs/spandsp/src/silence_gen.c b/libs/spandsp/src/silence_gen.c
index fa6529021a..4998f8bc0e 100644
--- a/libs/spandsp/src/silence_gen.c
+++ b/libs/spandsp/src/silence_gen.c
@@ -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: silence_gen.c,v 1.22 2009/06/02 16:03:56 steveu Exp $
+ * $Id: silence_gen.c,v 1.23 2009/09/04 14:38:46 steveu Exp $
*/
/*! \file */
@@ -158,4 +158,10 @@ SPAN_DECLARE(int) span_dummy_mod(void *user_data, int16_t amp[], int len)
return len;
}
/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE_NONSTD(int) span_dummy_rx_fillin(void *user_data, int len)
+{
+ return 0;
+}
+/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/
diff --git a/libs/spandsp/src/spandsp.h.in b/libs/spandsp/src/spandsp.h.in
index f5b7b0fe88..59122b654f 100644
--- a/libs/spandsp/src/spandsp.h.in
+++ b/libs/spandsp/src/spandsp.h.in
@@ -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: spandsp.h.in,v 1.18 2009/04/02 13:43:49 steveu Exp $
+ * $Id: spandsp.h.in,v 1.19 2009/09/22 13:11:04 steveu Exp $
*/
/*! \file */
@@ -66,6 +66,7 @@
#include
#include
#include
+#include
#include
#include
#include
diff --git a/libs/spandsp/src/spandsp/echo.h b/libs/spandsp/src/spandsp/echo.h
index eb423dd0f7..b476909181 100644
--- a/libs/spandsp/src/spandsp/echo.h
+++ b/libs/spandsp/src/spandsp/echo.h
@@ -24,7 +24,7 @@
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: echo.h,v 1.19 2009/02/10 13:06:47 steveu Exp $
+ * $Id: echo.h,v 1.20 2009/09/22 13:11:04 steveu Exp $
*/
/*! \file */
@@ -133,59 +133,7 @@ enum
G.168 echo canceller descriptor. This defines the working state for a line
echo canceller.
*/
-typedef struct
-{
- int tx_power[4];
- int rx_power[3];
- int clean_rx_power;
-
- int rx_power_threshold;
- int nonupdate_dwell;
-
- int curr_pos;
-
- int taps;
- int tap_mask;
- int adaption_mode;
-
- int32_t supp_test1;
- int32_t supp_test2;
- int32_t supp1;
- int32_t supp2;
- int vad;
- int cng;
-
- int16_t geigel_max;
- int geigel_lag;
- int dtd_onset;
- int tap_set;
- int tap_rotate_counter;
-
- int32_t latest_correction; /* Indication of the magnitude of the latest
- adaption, or a code to indicate why adaption
- was skipped, for test purposes */
- int32_t last_acf[28];
- int narrowband_count;
- int narrowband_score;
-
- fir16_state_t fir_state;
- /*! Echo FIR taps (16 bit version) */
- int16_t *fir_taps16[4];
- /*! Echo FIR taps (32 bit version) */
- int32_t *fir_taps32;
-
- /* DC and near DC blocking filter states */
- int32_t tx_hpf[2];
- int32_t rx_hpf[2];
-
- /* Parameters for the optional Hoth noise generator */
- int cng_level;
- int cng_rndnum;
- int cng_filter;
-
- /* Snapshot sample of coeffs used for development */
- int16_t *snapshot;
-} echo_can_state_t;
+typedef struct echo_can_state_s echo_can_state_t;
#if defined(__cplusplus)
extern "C"
diff --git a/libs/spandsp/src/spandsp/expose.h b/libs/spandsp/src/spandsp/expose.h
index 25b671827c..44a3c5c7b5 100644
--- a/libs/spandsp/src/spandsp/expose.h
+++ b/libs/spandsp/src/spandsp/expose.h
@@ -23,7 +23,7 @@
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: expose.h,v 1.13 2009/05/16 03:34:45 steveu Exp $
+ * $Id: expose.h,v 1.14 2009/09/22 13:11:04 steveu Exp $
*/
/*! \file */
@@ -56,6 +56,9 @@
#include
#include
#include
+#include
+#include
+#include
#include
#include
#include
diff --git a/libs/spandsp/src/spandsp/fast_convert.h b/libs/spandsp/src/spandsp/fast_convert.h
index 1620042c2a..ccf275aaf3 100644
--- a/libs/spandsp/src/spandsp/fast_convert.h
+++ b/libs/spandsp/src/spandsp/fast_convert.h
@@ -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: fast_convert.h,v 1.8 2009/07/10 13:15:56 steveu Exp $
+ * $Id: fast_convert.h,v 1.9 2009/10/03 04:37:25 steveu Exp $
*/
#if !defined(_SPANDSP_FAST_CONVERT_H_)
@@ -150,7 +150,7 @@ extern "C"
);
return retval;
}
-#elif defined(__GNUC__) || (__SUNPRO_C >= 0x0590)
+#elif defined(__GNUC__) || (__SUNPRO_C >= 0x0590)
#if defined(__i386__)
/* These routines are guaranteed fast on an i386 machine. Using the built in
@@ -403,7 +403,7 @@ extern "C"
the accuracy issues related to changing the rounding scheme are of little concern
to us. */
- #if !defined(__sgi) && !defined(__sunos) && !defined(__solaris) && !defined(__sun)
+ #if !defined(__sgi) && !defined(__sunos) && !defined(__solaris) && !defined(__sun)
#warning "No usable lrint() and lrintf() functions available."
#warning "Replacing these functions with a simple C cast."
#endif
diff --git a/libs/spandsp/src/spandsp/modem_echo.h b/libs/spandsp/src/spandsp/modem_echo.h
index cc9f06e45e..77ffe6b535 100644
--- a/libs/spandsp/src/spandsp/modem_echo.h
+++ b/libs/spandsp/src/spandsp/modem_echo.h
@@ -25,7 +25,7 @@
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: modem_echo.h,v 1.13 2009/02/03 16:28:41 steveu Exp $
+ * $Id: modem_echo.h,v 1.14 2009/09/22 13:11:04 steveu Exp $
*/
/*! \file */
@@ -84,22 +84,7 @@ minor burden.
Modem line echo canceller descriptor. This defines the working state for a line
echo canceller.
*/
-typedef struct
-{
- int adapt;
- int taps;
-
- fir16_state_t fir_state;
- /*! Echo FIR taps (16 bit version) */
- int16_t *fir_taps16;
- /*! Echo FIR taps (32 bit version) */
- int32_t *fir_taps32;
-
- int tx_power;
- int rx_power;
-
- int curr_pos;
-} modem_echo_can_state_t;
+typedef struct modem_echo_can_state_s modem_echo_can_state_t;
#if defined(__cplusplus)
extern "C"
diff --git a/libs/spandsp/src/spandsp/private/echo.h b/libs/spandsp/src/spandsp/private/echo.h
new file mode 100644
index 0000000000..4a91798315
--- /dev/null
+++ b/libs/spandsp/src/spandsp/private/echo.h
@@ -0,0 +1,94 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * private/echo.h - An echo cancellor, suitable for electrical and acoustic
+ * cancellation. This code does not currently comply with
+ * any relevant standards (e.g. G.164/5/7/8).
+ *
+ * Written by Steve Underwood
+ *
+ * Copyright (C) 2001 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: echo.h,v 1.1 2009/09/22 13:11:04 steveu Exp $
+ */
+
+/*! \file */
+
+#if !defined(_SPANDSP_PRIVATE_ECHO_H_)
+#define _SPANDSP_PRIVATE_ECHO_H_
+
+/*!
+ G.168 echo canceller descriptor. This defines the working state for a line
+ echo canceller.
+*/
+struct echo_can_state_s
+{
+ int tx_power[4];
+ int rx_power[3];
+ int clean_rx_power;
+
+ int rx_power_threshold;
+ int nonupdate_dwell;
+
+ int curr_pos;
+
+ int taps;
+ int tap_mask;
+ int adaption_mode;
+
+ int32_t supp_test1;
+ int32_t supp_test2;
+ int32_t supp1;
+ int32_t supp2;
+ int vad;
+ int cng;
+
+ int16_t geigel_max;
+ int geigel_lag;
+ int dtd_onset;
+ int tap_set;
+ int tap_rotate_counter;
+
+ int32_t latest_correction; /* Indication of the magnitude of the latest
+ adaption, or a code to indicate why adaption
+ was skipped, for test purposes */
+ int32_t last_acf[28];
+ int narrowband_count;
+ int narrowband_score;
+
+ fir16_state_t fir_state;
+ /*! Echo FIR taps (16 bit version) */
+ int16_t *fir_taps16[4];
+ /*! Echo FIR taps (32 bit version) */
+ int32_t *fir_taps32;
+
+ /* DC and near DC blocking filter states */
+ int32_t tx_hpf[2];
+ int32_t rx_hpf[2];
+
+ /* Parameters for the optional Hoth noise generator */
+ int cng_level;
+ int cng_rndnum;
+ int cng_filter;
+
+ /* Snapshot sample of coeffs used for development */
+ int16_t *snapshot;
+};
+
+#endif
+/*- End of file ------------------------------------------------------------*/
diff --git a/libs/spandsp/src/spandsp/private/fax_modems.h b/libs/spandsp/src/spandsp/private/fax_modems.h
index 1eec1c9bbc..a46749c0cf 100644
--- a/libs/spandsp/src/spandsp/private/fax_modems.h
+++ b/libs/spandsp/src/spandsp/private/fax_modems.h
@@ -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: fax_modems.h,v 1.3 2009/03/23 14:17:42 steveu Exp $
+ * $Id: fax_modems.h,v 1.4 2009/09/04 14:38:47 steveu Exp $
*/
/*! \file */
@@ -95,11 +95,9 @@ struct fax_modems_state_s
/*! The current receive signal handler */
span_rx_handler_t *rx_handler;
- void *rx_user_data;
-
/*! The current receive missing signal fill-in handler */
span_rx_fillin_handler_t *rx_fillin_handler;
- void *rx_fillin_user_data;
+ void *rx_user_data;
/*! The current transmit signal handler */
span_tx_handler_t *tx_handler;
diff --git a/libs/spandsp/src/spandsp/private/modem_echo.h b/libs/spandsp/src/spandsp/private/modem_echo.h
new file mode 100644
index 0000000000..082cb8d569
--- /dev/null
+++ b/libs/spandsp/src/spandsp/private/modem_echo.h
@@ -0,0 +1,58 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * private/modem_echo.h - An echo cancellor, suitable for electrical echos in GSTN modems
+ *
+ * Written by Steve Underwood
+ *
+ * Copyright (C) 2001, 2004 Steve Underwood
+ *
+ * Based on a bit from here, a bit from there, eye of toad,
+ * ear of bat, etc - plus, of course, my own 2 cents.
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU Lesser General Public License version 2.1,
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: modem_echo.h,v 1.1 2009/09/22 13:11:04 steveu Exp $
+ */
+
+/*! \file */
+
+#if !defined(_SPANDSP_PRIVATE_MODEM_ECHO_H_)
+#define _SPANDSP_PRIVATE_MODEM_ECHO_H_
+
+/*!
+ Modem line echo canceller descriptor. This defines the working state for a line
+ echo canceller.
+*/
+struct modem_echo_can_state_s
+{
+ int adapt;
+ int taps;
+
+ fir16_state_t fir_state;
+ /*! Echo FIR taps (16 bit version) */
+ int16_t *fir_taps16;
+ /*! Echo FIR taps (32 bit version) */
+ int32_t *fir_taps32;
+
+ int tx_power;
+ int rx_power;
+
+ int curr_pos;
+};
+
+#endif
+/*- End of file ------------------------------------------------------------*/
diff --git a/libs/spandsp/src/spandsp/private/sig_tone.h b/libs/spandsp/src/spandsp/private/sig_tone.h
index a98c8b16b4..edf7a68bb7 100644
--- a/libs/spandsp/src/spandsp/private/sig_tone.h
+++ b/libs/spandsp/src/spandsp/private/sig_tone.h
@@ -23,7 +23,7 @@
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: sig_tone.h,v 1.3 2009/04/12 14:18:02 steveu Exp $
+ * $Id: sig_tone.h,v 1.4 2009/09/04 14:38:47 steveu Exp $
*/
#if !defined(_SPANDSP_PRIVATE_SIG_TONE_H_)
@@ -38,8 +38,8 @@ struct sig_tone_descriptor_s
{
/*! \brief The tones used. */
int tone_freq[2];
- /*! \brief The high and low tone amplitudes. */
- int tone_amp[2];
+ /*! \brief The high and low tone amplitudes for each of the tones. */
+ int tone_amp[2][2];
/*! \brief The delay, in audio samples, before the high level tone drops
to a low level tone. */
@@ -80,7 +80,6 @@ struct sig_tone_descriptor_s
#endif
} tone[2];
-
#if defined(SPANDSP_USE_FIXED_POINT)
/*! \brief Flat mode bandpass bi-quad parameters */
int32_t broad_a[3];
@@ -128,23 +127,23 @@ struct sig_tone_descriptor_s
struct sig_tone_tx_state_s
{
/*! \brief The callback function used to handle signaling changes. */
- sig_tone_func_t sig_update;
+ tone_report_func_t sig_update;
/*! \brief A user specified opaque pointer passed to the callback function. */
void *user_data;
/*! \brief Tone descriptor */
sig_tone_descriptor_t *desc;
- /*! The scaling values for the high and low level tones */
- int16_t tone_scaling[2];
- /*! The sample timer, used to switch between the high and low level tones. */
- int high_low_timer;
-
/*! The phase rates for the one or two tones */
int32_t phase_rate[2];
/*! The phase accumulators for the one or two tones */
uint32_t phase_acc[2];
+ /*! The scaling values for the one or two tones, and the high and low level of each tone */
+ int16_t tone_scaling[2][2];
+ /*! The sample timer, used to switch between the high and low level tones. */
+ int high_low_timer;
+
/*! \brief Current transmit tone */
int current_tx_tone;
/*! \brief Current transmit timeout */
@@ -159,7 +158,7 @@ struct sig_tone_tx_state_s
struct sig_tone_rx_state_s
{
/*! \brief The callback function used to handle signaling changes. */
- sig_tone_func_t sig_update;
+ tone_report_func_t sig_update;
/*! \brief A user specified opaque pointer passed to the callback function. */
void *user_data;
diff --git a/libs/spandsp/src/spandsp/private/swept_tone.h b/libs/spandsp/src/spandsp/private/swept_tone.h
new file mode 100644
index 0000000000..ce8e5a634e
--- /dev/null
+++ b/libs/spandsp/src/spandsp/private/swept_tone.h
@@ -0,0 +1,44 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * private/swept_tone.h - Swept tone generation
+ *
+ * Written by Steve Underwood
+ *
+ * Copyright (C) 2009 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: swept_tone.h,v 1.1 2009/09/22 12:54:33 steveu Exp $
+ */
+
+#if !defined(_SPANDSP_PRIVATE_SWEPT_TONE_H_)
+#define _SPANDSP_PRIVATE_SWEPT_TONE_H_
+
+struct swept_tone_state_s
+{
+ int32_t starting_phase_inc;
+ int32_t phase_inc_step;
+ int scale;
+ int duration;
+ int repeating;
+ int pos;
+ int32_t current_phase_inc;
+ uint32_t phase;
+};
+
+#endif
+/*- End of file ------------------------------------------------------------*/
diff --git a/libs/spandsp/src/spandsp/private/t30.h b/libs/spandsp/src/spandsp/private/t30.h
index 00dbeabff0..958a553c89 100644
--- a/libs/spandsp/src/spandsp/private/t30.h
+++ b/libs/spandsp/src/spandsp/private/t30.h
@@ -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: t30.h,v 1.4 2009/04/12 14:18:02 steveu Exp $
+ * $Id: t30.h,v 1.5 2009/09/20 13:42:29 steveu Exp $
*/
/*! \file */
@@ -221,10 +221,10 @@ struct t30_state_s
/*! \brief A bit map of the OK ECM frames, constructed as a PPR frame. */
uint8_t ecm_frame_map[3 + 32];
- /*! \brief The current page number for receiving, in ECM mode. This is reset at the start of a call. */
- int ecm_rx_page;
- /*! \brief The current page number for sending, in ECM mode. This is reset at the start of a call. */
- int ecm_tx_page;
+ /*! \brief The current page number for receiving, in ECM or non-ECM mode. This is reset at the start of a call. */
+ int rx_page_number;
+ /*! \brief The current page number for sending, in ECM or non-ECM mode. This is reset at the start of a call. */
+ int tx_page_number;
/*! \brief The current block number, in ECM mode */
int ecm_block;
/*! \brief The number of frames in the current block number, in ECM mode */
diff --git a/libs/spandsp/src/spandsp/sig_tone.h b/libs/spandsp/src/spandsp/sig_tone.h
index eecbfdd438..64bcd6f422 100644
--- a/libs/spandsp/src/spandsp/sig_tone.h
+++ b/libs/spandsp/src/spandsp/sig_tone.h
@@ -23,7 +23,7 @@
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: sig_tone.h,v 1.19 2009/04/12 14:18:02 steveu Exp $
+ * $Id: sig_tone.h,v 1.20 2009/09/04 14:38:46 steveu Exp $
*/
/*! \file */
@@ -54,32 +54,39 @@ least supervisory information may be heard.
#if !defined(_SPANDSP_SIG_TONE_H_)
#define _SPANDSP_SIG_TONE_H_
-typedef int (*sig_tone_func_t)(void *user_data, int what);
-
/* The optional tone sets */
enum
{
- /*! European 2280Hz signaling tone */
+ /*! European 2280Hz signaling tone. Tone 1 is 2280Hz. Tone 2 is not used. */
SIG_TONE_2280HZ = 1,
- /*! US 2600Hz signaling tone */
+ /*! US 2600Hz signaling tone. Tone 1 is 2600Hz. Tone 2 is not used. */
SIG_TONE_2600HZ,
- /*! US 2400Hz + 2600Hz signaling tones */
+ /*! US 2400Hz + 2600Hz signaling tones. Tone 1 is 2600Hz. Tone 2 is 2400Hz. */
SIG_TONE_2400HZ_2600HZ
};
+/* Mode control and report bits for transmit and receive */
enum
{
/*! Signaling tone 1 is present */
SIG_TONE_1_PRESENT = 0x001,
+ /*! Signaling tone 1 has changed state (ignored when setting tx mode) */
SIG_TONE_1_CHANGE = 0x002,
/*! Signaling tone 2 is present */
SIG_TONE_2_PRESENT = 0x004,
+ /*! Signaling tone 2 has changed state (ignored when setting tx mode) */
SIG_TONE_2_CHANGE = 0x008,
/*! The media signal is passing through. Tones might be added to it. */
SIG_TONE_TX_PASSTHROUGH = 0x010,
/*! The media signal is passing through. Tones might be extracted from it, if detected. */
- SIG_TONE_RX_PASSTHROUGH = 0x020,
- SIG_TONE_UPDATE_REQUEST = 0x100
+ SIG_TONE_RX_PASSTHROUGH = 0x040,
+ /*! Force filtering of the signaling tone, whether signaling is being detected or not.
+ This is mostly useful for test purposes. */
+ SIG_TONE_RX_FILTER_TONE = 0x080,
+ /*! Request an update of the transmit status, upon timeout of the previous status. */
+ SIG_TONE_TX_UPDATE_REQUEST = 0x100,
+ /*! Request an update of the receiver status, upon timeout of the previous status. */
+ SIG_TONE_RX_UPDATE_REQUEST = 0x200
};
/*!
@@ -106,6 +113,14 @@ extern "C"
\return The number of samples unprocessed. */
SPAN_DECLARE(int) sig_tone_rx(sig_tone_rx_state_t *s, int16_t amp[], int len);
+/*! Set the receive mode.
+ \brief Set the receive mode.
+ \param s The signaling tone context.
+ \param mode The new mode for the receiver.
+ \param duration The duration for this mode, before an update is requested.
+ A duration of zero means forever. */
+SPAN_DECLARE(void) sig_tone_rx_set_mode(sig_tone_rx_state_t *s, int mode, int duration);
+
/*! Initialise a signaling tone receiver context.
\brief Initialise a signaling tone context.
\param s The signaling tone context.
@@ -113,7 +128,7 @@ SPAN_DECLARE(int) sig_tone_rx(sig_tone_rx_state_t *s, int16_t amp[], int len);
\param sig_update Callback function to handle signaling updates.
\param user_data An opaque pointer.
\return A pointer to the signalling tone context, or NULL if there was a problem. */
-SPAN_DECLARE(sig_tone_rx_state_t *) sig_tone_rx_init(sig_tone_rx_state_t *s, int tone_type, sig_tone_func_t sig_update, void *user_data);
+SPAN_DECLARE(sig_tone_rx_state_t *) sig_tone_rx_init(sig_tone_rx_state_t *s, int tone_type, tone_report_func_t sig_update, void *user_data);
/*! Release a signaling tone receiver context.
\brief Release a signaling tone receiver context.
@@ -138,8 +153,10 @@ SPAN_DECLARE(int) sig_tone_tx(sig_tone_tx_state_t *s, int16_t amp[], int len);
/*! Set the tone mode.
\brief Set the tone mode.
\param s The signaling tone context.
- \param mode The new mode for the transmitted tones. */
-SPAN_DECLARE(void) sig_tone_tx_set_mode(sig_tone_tx_state_t *s, int mode);
+ \param mode The new mode for the transmitted tones.
+ \param duration The duration for this mode, before an update is requested.
+ A duration of zero means forever. */
+SPAN_DECLARE(void) sig_tone_tx_set_mode(sig_tone_tx_state_t *s, int mode, int duration);
/*! Initialise a signaling tone transmitter context.
\brief Initialise a signaling tone context.
@@ -148,7 +165,7 @@ SPAN_DECLARE(void) sig_tone_tx_set_mode(sig_tone_tx_state_t *s, int mode);
\param sig_update Callback function to handle signaling updates.
\param user_data An opaque pointer.
\return A pointer to the signalling tone context, or NULL if there was a problem. */
-SPAN_DECLARE(sig_tone_tx_state_t *) sig_tone_tx_init(sig_tone_tx_state_t *s, int tone_type, sig_tone_func_t sig_update, void *user_data);
+SPAN_DECLARE(sig_tone_tx_state_t *) sig_tone_tx_init(sig_tone_tx_state_t *s, int tone_type, tone_report_func_t sig_update, void *user_data);
/*! Release a signaling tone transmitter context.
\brief Release a signaling tone transmitter context.
diff --git a/libs/spandsp/src/spandsp/silence_gen.h b/libs/spandsp/src/spandsp/silence_gen.h
index c7300ec4aa..467408d75b 100644
--- a/libs/spandsp/src/spandsp/silence_gen.h
+++ b/libs/spandsp/src/spandsp/silence_gen.h
@@ -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: silence_gen.h,v 1.18 2009/06/02 16:03:56 steveu Exp $
+ * $Id: silence_gen.h,v 1.19 2009/09/04 14:38:47 steveu Exp $
*/
#if !defined(_SPANDSP_SILENCE_GEN_H_)
@@ -125,6 +125,16 @@ SPAN_DECLARE_NONSTD(int) span_dummy_rx(void *user_data, const int16_t amp[], int
*/
SPAN_DECLARE(int) span_dummy_mod(void *user_data, int16_t amp[], int len);
+/*! A dummy routine to use as a receive fillin callback, when we aren't really
+ trying to process what is received. It just absorbs and ignores the
+ request.
+ \brief Dummy receive fillin callback.
+ \param user_data The context.
+ \param len The length of the signal buffer
+ \return 0.
+*/
+SPAN_DECLARE_NONSTD(int) span_dummy_rx_fillin(void *user_data, int len);
+
#if defined(__cplusplus)
}
#endif
diff --git a/libs/spandsp/src/spandsp/swept_tone.h b/libs/spandsp/src/spandsp/swept_tone.h
new file mode 100644
index 0000000000..414f951fb3
--- /dev/null
+++ b/libs/spandsp/src/spandsp/swept_tone.h
@@ -0,0 +1,59 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * swept_tone.h - Swept tone generation
+ *
+ * Written by Steve Underwood
+ *
+ * Copyright (C) 2009 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: swept_tone.h,v 1.1 2009/09/22 12:54:33 steveu Exp $
+ */
+
+/*! \file */
+
+#if !defined(_SPANDSP_SWEPT_TONE_H_)
+#define _SPANDSP_SWEPT_TONE_H_
+
+/*! \page swept_tone_page The swept tone generator
+\section swept_tone_page_sec_1 What does it do?
+*/
+
+typedef struct swept_tone_state_s swept_tone_state_t;
+
+#if defined(__cplusplus)
+extern "C"
+{
+#endif
+
+SPAN_DECLARE(swept_tone_state_t *) swept_tone_init(swept_tone_state_t *s, float start, float end, float level, int duration, int repeating);
+
+SPAN_DECLARE(int) swept_tone(swept_tone_state_t *s, int16_t amp[], int len);
+
+SPAN_DECLARE(float) swept_tone_current_frequency(swept_tone_state_t *s);
+
+SPAN_DECLARE(int) swept_tone_release(swept_tone_state_t *s);
+
+SPAN_DECLARE(int) swept_tone_free(swept_tone_state_t *s);
+
+#if defined(__cplusplus)
+}
+#endif
+
+#endif
+/*- End of file ------------------------------------------------------------*/
diff --git a/libs/spandsp/src/spandsp/t30.h b/libs/spandsp/src/spandsp/t30.h
index dbd3dec1e2..d0d71f674d 100644
--- a/libs/spandsp/src/spandsp/t30.h
+++ b/libs/spandsp/src/spandsp/t30.h
@@ -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: t30.h,v 1.125 2009/04/12 09:12:10 steveu Exp $
+ * $Id: t30.h,v 1.126 2009/09/21 15:52:39 steveu Exp $
*/
/*! \file */
@@ -524,9 +524,9 @@ typedef struct
int pages_rx;
/*! \brief The number of pages in the file (<0 if not known). */
int pages_in_file;
- /*! \brief The horizontal column-to-column resolution of the page, in pixels per metre */
+ /*! \brief The horizontal column-to-column resolution of the most recent page, in pixels per metre */
int x_resolution;
- /*! \brief The vertical row-to-row resolution of the page, in pixels per metre */
+ /*! \brief The vertical row-to-row resolution of the most recent page, in pixels per metre */
int y_resolution;
/*! \brief The number of horizontal pixels in the most recent page. */
int width;
diff --git a/libs/spandsp/src/spandsp/timing.h b/libs/spandsp/src/spandsp/timing.h
index 735471659f..85f3ce5f43 100644
--- a/libs/spandsp/src/spandsp/timing.h
+++ b/libs/spandsp/src/spandsp/timing.h
@@ -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: timing.h,v 1.13 2008/04/17 14:27:01 steveu Exp $
+ * $Id: timing.h,v 1.14 2009/09/04 14:38:47 steveu Exp $
*/
#if !defined(_SPANDSP_TIMING_H_)
@@ -56,8 +56,8 @@ static __inline__ uint64_t rdtscll(void)
#elif defined(__x86_64__)
static __inline__ uint64_t rdtscll(void)
{
- unsigned int a;
- unsigned int d;
+ uint32_t a;
+ uint32_t d;
/* For x86_64 we need to merge the result in 2 32 bit registers
into one clean 64 bit result. */
diff --git a/libs/spandsp/src/spandsp/version.h b/libs/spandsp/src/spandsp/version.h
index 88a8ab76df..fe4e70aa73 100644
--- a/libs/spandsp/src/spandsp/version.h
+++ b/libs/spandsp/src/spandsp/version.h
@@ -30,9 +30,9 @@
/* The date and time of the version are in UTC form. */
-#define SPANDSP_RELEASE_DATE 20090714
-#define SPANDSP_RELEASE_TIME 135534
-#define SPANDSP_RELEASE_DATETIME_STRING "20090714 135534"
+#define SPANDSP_RELEASE_DATE 20091005
+#define SPANDSP_RELEASE_TIME 132812
+#define SPANDSP_RELEASE_DATETIME_STRING "20091005 132812"
#endif
/*- End of file ------------------------------------------------------------*/
diff --git a/libs/spandsp/src/swept_tone.c b/libs/spandsp/src/swept_tone.c
new file mode 100644
index 0000000000..78555ab8fa
--- /dev/null
+++ b/libs/spandsp/src/swept_tone.c
@@ -0,0 +1,128 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * swept_tone.c - Swept tone generation
+ *
+ * Written by Steve Underwood
+ *
+ * Copyright (C) 2009 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: swept_tone.c,v 1.2 2009/09/23 16:02:59 steveu Exp $
+ */
+
+/*! \file */
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include
+#include
+#include
+#include
+#if defined(HAVE_TGMATH_H)
+#include
+#endif
+#if defined(HAVE_MATH_H)
+#include
+#endif
+#include "floating_fudge.h"
+
+#include "spandsp/telephony.h"
+#include "spandsp/logging.h"
+#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/dds.h"
+
+#include "spandsp/swept_tone.h"
+
+#include "spandsp/private/logging.h"
+#include "spandsp/private/swept_tone.h"
+
+SPAN_DECLARE(swept_tone_state_t *) swept_tone_init(swept_tone_state_t *s, float start, float end, float level, int duration, int repeating)
+{
+ if (s == NULL)
+ {
+ if ((s = (swept_tone_state_t *) malloc(sizeof(*s))) == NULL)
+ return NULL;
+ }
+ memset(s, 0, sizeof(*s));
+ s->current_phase_inc =
+ s->starting_phase_inc = dds_phase_rate(start);
+ s->phase_inc_step = dds_phase_rate((end - start)/(float) duration);
+ s->scale = dds_scaling_dbm0(level);
+ s->duration = duration;
+ s->repeating = repeating;
+ s->pos = 0;
+ s->phase = 0;
+ return s;
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(int) swept_tone(swept_tone_state_t *s, int16_t amp[], int max_len)
+{
+ int i;
+ int len;
+ int chunk_len;
+
+ for (len = 0; len < max_len; )
+ {
+ chunk_len = max_len - len;
+ if (chunk_len > s->duration - s->pos)
+ chunk_len = s->duration - s->pos;
+ for (i = len; i < len + chunk_len; i++)
+ {
+ amp[i] = (dds(&s->phase, s->current_phase_inc)*s->scale) >> 15;
+ s->current_phase_inc += s->phase_inc_step;
+ }
+ len += chunk_len;
+ s->pos += chunk_len;
+ if (s->pos >= s->duration)
+ {
+ if (!s->repeating)
+ break;
+ s->pos = 0;
+ s->current_phase_inc = s->starting_phase_inc;
+ }
+ }
+ return len;
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(float) swept_tone_current_frequency(swept_tone_state_t *s)
+{
+ return dds_frequency(s->current_phase_inc);
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(int) swept_tone_release(swept_tone_state_t *s)
+{
+ return 0;
+}
+/*- End of function --------------------------------------------------------*/
+
+SPAN_DECLARE(int) swept_tone_free(swept_tone_state_t *s)
+{
+ free(s);
+ return 0;
+}
+/*- End of function --------------------------------------------------------*/
+/*- End of file ------------------------------------------------------------*/
diff --git a/libs/spandsp/src/t30.c b/libs/spandsp/src/t30.c
index 6640fd8294..a112dd9fac 100644
--- a/libs/spandsp/src/t30.c
+++ b/libs/spandsp/src/t30.c
@@ -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: t30.c,v 1.301 2009/05/25 12:37:38 steveu Exp $
+ * $Id: t30.c,v 1.303 2009/09/21 15:51:18 steveu Exp $
*/
/*! \file */
@@ -421,7 +421,7 @@ static int tx_start_page(t30_state_t *s)
}
s->ecm_block = 0;
s->error_correcting_mode_retries = 0;
- span_log(&s->logging, SPAN_LOG_FLOW, "Starting page %d of transfer\n", s->ecm_tx_page + 1);
+ span_log(&s->logging, SPAN_LOG_FLOW, "Starting page %d of transfer\n", s->tx_page_number + 1);
return 0;
}
/*- End of function --------------------------------------------------------*/
@@ -431,7 +431,7 @@ static int tx_end_page(t30_state_t *s)
s->retries = 0;
if (t4_tx_end_page(&(s->t4)) == 0)
{
- s->ecm_tx_page++;
+ s->tx_page_number++;
s->ecm_block = 0;
}
return 0;
@@ -470,7 +470,7 @@ static int rx_end_page(t30_state_t *s)
{
if (t4_rx_end_page(&(s->t4)) == 0)
{
- s->ecm_rx_page++;
+ s->rx_page_number++;
s->ecm_block = 0;
}
return 0;
@@ -1042,7 +1042,7 @@ static int send_pps_frame(t30_state_t *s)
frame[1] = CONTROL_FIELD_FINAL_FRAME;
frame[2] = (uint8_t) (T30_PPS | s->dis_received);
frame[3] = (s->ecm_at_page_end) ? ((uint8_t) (s->next_tx_step | s->dis_received)) : T30_NULL;
- frame[4] = (uint8_t) (s->ecm_tx_page & 0xFF);
+ frame[4] = (uint8_t) (s->tx_page_number & 0xFF);
frame[5] = (uint8_t) (s->ecm_block & 0xFF);
frame[6] = (uint8_t) ((s->ecm_frames_this_tx_burst == 0) ? 0 : (s->ecm_frames_this_tx_burst - 1));
span_log(&s->logging, SPAN_LOG_FLOW, "Sending PPS + %s\n", t30_frametype(frame[3]));
@@ -1957,30 +1957,19 @@ static int start_receiving_document(t30_state_t *s)
}
/*- End of function --------------------------------------------------------*/
-static void unexpected_frame(t30_state_t *s, const uint8_t *msg, int len)
-{
- span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s received in state %d\n", t30_frametype(msg[2]), s->state);
- switch (s->state)
- {
- case T30_STATE_F_DOC_ECM:
- case T30_STATE_F_DOC_NON_ECM:
- s->current_status = T30_ERR_RX_INVALCMD;
- break;
- }
-}
-/*- End of function --------------------------------------------------------*/
-
static void unexpected_non_final_frame(t30_state_t *s, const uint8_t *msg, int len)
{
span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %d\n", t30_frametype(msg[2]), s->state);
- s->current_status = T30_ERR_UNEXPECTED;
+ if (s->current_status == T30_ERR_OK)
+ s->current_status = T30_ERR_UNEXPECTED;
}
/*- End of function --------------------------------------------------------*/
static void unexpected_final_frame(t30_state_t *s, const uint8_t *msg, int len)
{
- span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s received in state %d\n", t30_frametype(msg[2]), s->state);
- s->current_status = T30_ERR_UNEXPECTED;
+ span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame in state %d\n", t30_frametype(msg[2]), s->state);
+ if (s->current_status == T30_ERR_OK)
+ s->current_status = T30_ERR_UNEXPECTED;
send_dcn(s);
}
/*- End of function --------------------------------------------------------*/
@@ -1988,7 +1977,8 @@ static void unexpected_final_frame(t30_state_t *s, const uint8_t *msg, int len)
static void unexpected_frame_length(t30_state_t *s, const uint8_t *msg, int len)
{
span_log(&s->logging, SPAN_LOG_FLOW, "Unexpected %s frame length - %d\n", t30_frametype(msg[0]), len);
- s->current_status = T30_ERR_UNEXPECTED;
+ if (s->current_status == T30_ERR_OK)
+ s->current_status = T30_ERR_UNEXPECTED;
send_dcn(s);
}
/*- End of function --------------------------------------------------------*/
@@ -2372,9 +2362,9 @@ static int process_rx_pps(t30_state_t *s, const uint8_t *msg, int len)
}
}
span_log(&s->logging, SPAN_LOG_FLOW, "Received PPS + %s - page %d, block %d, %d frames\n", t30_frametype(msg[3]), page, block, frames);
- if (page != s->ecm_rx_page)
+ if (page != s->rx_page_number)
{
- span_log(&s->logging, SPAN_LOG_FLOW, "ECM rx page mismatch - expected %d, but received %d.\n", s->ecm_rx_page, page);
+ span_log(&s->logging, SPAN_LOG_FLOW, "ECM rx page mismatch - expected %d, but received %d.\n", s->rx_page_number, page);
}
if (block != s->ecm_block)
{
@@ -2645,7 +2635,11 @@ static void process_rx_fnv(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_answering(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ /* We should be sending the TCF data right now */
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_DIS:
/* TODO: This is a fudge to allow for starting up in T.38, where the other end has
@@ -2675,7 +2669,11 @@ static void process_state_answering(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_b(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ /* We should be sending the TCF data right now */
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_DCN:
/* Just ignore any DCN's which appear at this stage. */
@@ -2696,7 +2694,10 @@ static void process_state_b(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_c(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_DCN:
/* Just ignore any DCN's which appear at this stage. */
@@ -2717,8 +2718,11 @@ static void process_state_c(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_d(t30_state_t *s, const uint8_t *msg, int len)
{
+ uint8_t fcf;
+
/* We should be sending the DCS sequence right now */
- switch (msg[2] & 0xFE)
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_DCN:
s->current_status = T30_ERR_TX_BADDCS;
@@ -2740,8 +2744,11 @@ static void process_state_d(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_d_tcf(t30_state_t *s, const uint8_t *msg, int len)
{
+ uint8_t fcf;
+
/* We should be sending the TCF data right now */
- switch (msg[2] & 0xFE)
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_DCN:
s->current_status = T30_ERR_TX_BADDCS;
@@ -2763,7 +2770,10 @@ static void process_state_d_tcf(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_d_post_tcf(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_CFR:
/* Trainability test succeeded. Send the document. */
@@ -2832,8 +2842,11 @@ static void process_state_d_post_tcf(t30_state_t *s, const uint8_t *msg, int len
static void process_state_f_tcf(t30_state_t *s, const uint8_t *msg, int len)
{
+ uint8_t fcf;
+
/* We should be receiving TCF right now, not HDLC messages */
- switch (msg[2] & 0xFE)
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_CRP:
repeat_last_command(s);
@@ -2851,8 +2864,11 @@ static void process_state_f_tcf(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_f_cfr(t30_state_t *s, const uint8_t *msg, int len)
{
+ uint8_t fcf;
+
/* We're waiting for a response to the CFR we sent */
- switch (msg[2] & 0xFE)
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_DCS:
/* If we received another DCS, they must have missed our CFR */
@@ -2874,8 +2890,11 @@ static void process_state_f_cfr(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_f_ftt(t30_state_t *s, const uint8_t *msg, int len)
{
+ uint8_t fcf;
+
/* We're waiting for a response to the FTT we sent */
- switch (msg[2] & 0xFE)
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_DCS:
process_rx_dcs(s, msg, len);
@@ -2896,12 +2915,15 @@ static void process_state_f_ftt(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_f_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int len)
{
+ uint8_t fcf;
+
/* If we are getting HDLC messages, and we have not moved to the _POST_DOC_NON_ECM
state, it looks like either:
- we didn't see the image data carrier properly, or
- they didn't see our T30_CFR, and are repeating the DCS/TCF sequence.
- they didn't see out T30_MCF, and are repeating the end of page message. */
- switch (msg[2] & 0xFE)
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_DIS:
process_rx_dis_dtc(s, msg, len);
@@ -2912,7 +2934,7 @@ static void process_state_f_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int
case T30_MPS:
/* Treat this as a bad quality page. */
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, msg[2] & 0xFE);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->next_rx_step = msg[2] & 0xFE;
queue_phase(s, T30_PHASE_D_TX);
set_state(s, T30_STATE_III_Q_RTN);
@@ -2922,7 +2944,7 @@ static void process_state_f_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int
/* Treat this as a bad quality page. */
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, msg[2] & 0xFE);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
s->next_rx_step = msg[2] & 0xFE;
@@ -2932,7 +2954,7 @@ static void process_state_f_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int
case T30_EOS:
/* Treat this as a bad quality page. */
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, msg[2] & 0xFE);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->next_rx_step = msg[2] & 0xFE;
/* Return to phase B */
queue_phase(s, T30_PHASE_B_TX);
@@ -2943,7 +2965,7 @@ static void process_state_f_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int
/* Treat this as a bad quality page. */
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, msg[2] & 0xFE);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
s->next_rx_step = T30_PRI_EOM;
@@ -2952,7 +2974,7 @@ static void process_state_f_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int
case T30_EOP:
/* Treat this as a bad quality page. */
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, msg[2] & 0xFE);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->next_rx_step = msg[2] & 0xFE;
queue_phase(s, T30_PHASE_D_TX);
set_state(s, T30_STATE_III_Q_RTN);
@@ -2962,7 +2984,7 @@ static void process_state_f_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int
/* Treat this as a bad quality page. */
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, msg[2] & 0xFE);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
s->next_rx_step = msg[2] & 0xFE;
@@ -2980,6 +3002,7 @@ static void process_state_f_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int
break;
default:
/* We don't know what to do with this. */
+ s->current_status = T30_ERR_RX_INVALCMD;
unexpected_final_frame(s, msg, len);
break;
}
@@ -2988,12 +3011,15 @@ static void process_state_f_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int
static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_MPS:
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, msg[2] & 0xFE);
- s->next_rx_step = msg[2] & 0xFE;
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
+ s->next_rx_step = fcf;
queue_phase(s, T30_PHASE_D_TX);
switch (copy_quality(s))
{
@@ -3020,10 +3046,10 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg,
case T30_PRI_MPS:
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, msg[2] & 0xFE);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
- s->next_rx_step = msg[2] & 0xFE;
+ s->next_rx_step = fcf;
switch (copy_quality(s))
{
case T30_COPY_QUALITY_PERFECT:
@@ -3049,8 +3075,8 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg,
case T30_EOM:
case T30_EOS:
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, msg[2] & 0xFE);
- s->next_rx_step = msg[2] & 0xFE;
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
+ s->next_rx_step = fcf;
/* Return to phase B */
queue_phase(s, T30_PHASE_B_TX);
switch (copy_quality(s))
@@ -3078,10 +3104,10 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg,
case T30_PRI_EOM:
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, msg[2] & 0xFE);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
- s->next_rx_step = msg[2] & 0xFE;
+ s->next_rx_step = fcf;
switch (copy_quality(s))
{
case T30_COPY_QUALITY_PERFECT:
@@ -3106,8 +3132,8 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg,
break;
case T30_EOP:
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, msg[2] & 0xFE);
- s->next_rx_step = msg[2] & 0xFE;
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
+ s->next_rx_step = fcf;
queue_phase(s, T30_PHASE_D_TX);
switch (copy_quality(s))
{
@@ -3137,10 +3163,10 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg,
case T30_PRI_EOP:
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, msg[2] & 0xFE);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
- s->next_rx_step = msg[2] & 0xFE;
+ s->next_rx_step = fcf;
switch (copy_quality(s))
{
case T30_COPY_QUALITY_PERFECT:
@@ -3175,6 +3201,7 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg,
break;
default:
/* We don't know what to do with this. */
+ s->current_status = T30_ERR_RX_INVALCMD;
unexpected_final_frame(s, msg, len);
break;
}
@@ -3183,10 +3210,12 @@ static void process_state_f_post_doc_non_ecm(t30_state_t *s, const uint8_t *msg,
static void process_state_f_doc_and_post_doc_ecm(t30_state_t *s, const uint8_t *msg, int len)
{
+ uint8_t fcf;
uint8_t fcf2;
/* This actually handles 2 states - _DOC_ECM and _POST_DOC_ECM - as they are very similar */
- switch (msg[2] & 0xFE)
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_DIS:
process_rx_dis_dtc(s, msg, len);
@@ -3267,6 +3296,7 @@ static void process_state_f_doc_and_post_doc_ecm(t30_state_t *s, const uint8_t *
break;
default:
/* We don't know what to do with this. */
+ s->current_status = T30_ERR_RX_INVALCMD;
unexpected_final_frame(s, msg, len);
break;
}
@@ -3275,7 +3305,10 @@ static void process_state_f_doc_and_post_doc_ecm(t30_state_t *s, const uint8_t *
static void process_state_f_post_rcp_mcf(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_CRP:
repeat_last_command(s);
@@ -3296,7 +3329,10 @@ static void process_state_f_post_rcp_mcf(t30_state_t *s, const uint8_t *msg, int
static void process_state_f_post_rcp_ppr(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_CRP:
repeat_last_command(s);
@@ -3314,7 +3350,10 @@ static void process_state_f_post_rcp_ppr(t30_state_t *s, const uint8_t *msg, int
static void process_state_f_post_rcp_rnr(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_RR:
if (s->receiver_not_ready_count > 0)
@@ -3345,7 +3384,10 @@ static void process_state_f_post_rcp_rnr(t30_state_t *s, const uint8_t *msg, int
static void process_state_r(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_DIS:
process_rx_dis_dtc(s, msg, len);
@@ -3374,7 +3416,10 @@ static void process_state_r(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_t(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_DIS:
process_rx_dis_dtc(s, msg, len);
@@ -3400,7 +3445,10 @@ static void process_state_t(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_i(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_CRP:
repeat_last_command(s);
@@ -3418,7 +3466,10 @@ static void process_state_i(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_ii(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_CRP:
repeat_last_command(s);
@@ -3437,8 +3488,10 @@ static void process_state_ii(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
{
t4_stats_t stats;
+ uint8_t fcf;
- switch (msg[2] & 0xFE)
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_MCF:
switch (s->next_tx_step)
@@ -3447,7 +3500,8 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
case T30_PRI_MPS:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_MCF);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
+ /* Transmit the next page */
if (tx_start_page(s))
{
/* TODO: recover */
@@ -3461,7 +3515,7 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
case T30_EOS:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_MCF);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
t4_tx_release(&(s->t4));
s->operation_in_progress = OPERATION_IN_PROGRESS_NONE;
if (span_log_test(&s->logging, SPAN_LOG_FLOW))
@@ -3475,7 +3529,7 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
case T30_PRI_EOP:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_MCF);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
t4_tx_release(&(s->t4));
s->operation_in_progress = OPERATION_IN_PROGRESS_NONE;
send_dcn(s);
@@ -3488,13 +3542,16 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
}
break;
case T30_RTP:
+#if 0
+ s->rtp_events++;
+#endif
switch (s->next_tx_step)
{
case T30_MPS:
case T30_PRI_MPS:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_RTP);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
if (tx_start_page(s))
{
/* TODO: recover */
@@ -3517,7 +3574,7 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
case T30_EOS:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_RTP);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
t4_tx_release(&(s->t4));
/* TODO: should go back to T, and resend */
return_to_phase_b(s, TRUE);
@@ -3526,22 +3583,35 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
case T30_PRI_EOP:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_RTP);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
t4_tx_release(&(s->t4));
- s->current_status = T30_ERR_TX_INVALRSP;
send_dcn(s);
break;
}
break;
case T30_RTN:
+#if 0
+ s->rtn_events++;
+#endif
switch (s->next_tx_step)
{
case T30_MPS:
case T30_PRI_MPS:
s->retries = 0;
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_RTN);
- /* Send fresh training, and then repeat the last page */
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
+#if 0
+ if (!s->retransmit_capable)
+#endif
+ {
+ /* Send the next page, regardless of the problem with the current one. */
+ if (tx_start_page(s))
+ {
+ /* TODO: recover */
+ break;
+ }
+ }
+ /* Send fresh training */
if (step_fallback_entry(s) < 0)
{
/* We have fallen back as far as we can go. Give up. */
@@ -3558,17 +3628,43 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
case T30_EOS:
s->retries = 0;
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_RTN);
- s->current_status = T30_ERR_TX_INVALRSP;
- return_to_phase_b(s, TRUE);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
+#if 0
+ if (s->retransmit_capable)
+ {
+ /* Wait for DIS */
+ }
+ else
+#endif
+ {
+ return_to_phase_b(s, TRUE);
+ }
break;
case T30_EOP:
case T30_PRI_EOP:
s->retries = 0;
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_RTN);
- s->current_status = T30_ERR_TX_INVALRSP;
- send_dcn(s);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
+#if 0
+ if (s->retransmit_capable)
+ {
+ /* Send fresh training, and then repeat the last page */
+ if (step_fallback_entry(s) < 0)
+ {
+ /* We have fallen back as far as we can go. Give up. */
+ s->current_fallback = 0;
+ s->current_status = T30_ERR_CANNOT_TRAIN;
+ send_dcn(s);
+ break;
+ }
+ queue_phase(s, T30_PHASE_B_TX);
+ restart_sending_document(s);
+ }
+ else
+#endif
+ {
+ send_dcn(s);
+ }
break;
}
break;
@@ -3576,7 +3672,7 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
s->retries = 0;
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, T30_PIP);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
break;
@@ -3584,7 +3680,7 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
s->retries = 0;
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, T30_PIN);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
break;
@@ -3613,6 +3709,7 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
break;
default:
/* We don't know what to do with this. */
+ s->current_status = T30_ERR_TX_INVALRSP;
unexpected_final_frame(s, msg, len);
break;
}
@@ -3621,7 +3718,10 @@ static void process_state_ii_q(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_iii_q_mcf(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_EOP:
case T30_EOM:
@@ -3655,7 +3755,10 @@ static void process_state_iii_q_mcf(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_iii_q_rtp(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_EOP:
case T30_EOM:
@@ -3686,7 +3789,10 @@ static void process_state_iii_q_rtp(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_iii_q_rtn(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_EOP:
case T30_EOM:
@@ -3721,7 +3827,10 @@ static void process_state_iii_q_rtn(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_iv(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_CRP:
repeat_last_command(s);
@@ -3740,8 +3849,10 @@ static void process_state_iv(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_iv_pps_null(t30_state_t *s, const uint8_t *msg, int len)
{
t4_stats_t stats;
+ uint8_t fcf;
- switch (msg[2] & 0xFE)
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_MCF:
s->retries = 0;
@@ -3765,7 +3876,7 @@ static void process_state_iv_pps_null(t30_state_t *s, const uint8_t *msg, int le
case T30_PRI_MPS:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_MCF);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
if (tx_start_page(s))
{
/* TODO: recover */
@@ -3783,7 +3894,7 @@ static void process_state_iv_pps_null(t30_state_t *s, const uint8_t *msg, int le
case T30_EOS:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_MCF);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
t4_tx_release(&(s->t4));
s->operation_in_progress = OPERATION_IN_PROGRESS_NONE;
if (span_log_test(&s->logging, SPAN_LOG_FLOW))
@@ -3797,7 +3908,7 @@ static void process_state_iv_pps_null(t30_state_t *s, const uint8_t *msg, int le
case T30_PRI_EOP:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_MCF);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
t4_tx_release(&(s->t4));
s->operation_in_progress = OPERATION_IN_PROGRESS_NONE;
send_dcn(s);
@@ -3842,8 +3953,10 @@ static void process_state_iv_pps_null(t30_state_t *s, const uint8_t *msg, int le
static void process_state_iv_pps_q(t30_state_t *s, const uint8_t *msg, int len)
{
t4_stats_t stats;
+ uint8_t fcf;
- switch (msg[2] & 0xFE)
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_MCF:
s->retries = 0;
@@ -3867,7 +3980,7 @@ static void process_state_iv_pps_q(t30_state_t *s, const uint8_t *msg, int len)
case T30_PRI_MPS:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_MCF);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
if (tx_start_page(s))
{
/* TODO: recover */
@@ -3885,7 +3998,7 @@ static void process_state_iv_pps_q(t30_state_t *s, const uint8_t *msg, int len)
case T30_EOS:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_MCF);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
t4_tx_release(&(s->t4));
s->operation_in_progress = OPERATION_IN_PROGRESS_NONE;
if (span_log_test(&s->logging, SPAN_LOG_FLOW))
@@ -3899,7 +4012,7 @@ static void process_state_iv_pps_q(t30_state_t *s, const uint8_t *msg, int len)
case T30_PRI_EOP:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_MCF);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
t4_tx_release(&(s->t4));
s->operation_in_progress = OPERATION_IN_PROGRESS_NONE;
send_dcn(s);
@@ -3923,7 +4036,7 @@ static void process_state_iv_pps_q(t30_state_t *s, const uint8_t *msg, int len)
s->retries = 0;
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, T30_PIP);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
break;
@@ -3931,7 +4044,7 @@ static void process_state_iv_pps_q(t30_state_t *s, const uint8_t *msg, int len)
s->retries = 0;
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, T30_PIN);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
break;
@@ -3960,8 +4073,10 @@ static void process_state_iv_pps_q(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_iv_pps_rnr(t30_state_t *s, const uint8_t *msg, int len)
{
t4_stats_t stats;
+ uint8_t fcf;
- switch (msg[2] & 0xFE)
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_MCF:
s->retries = 0;
@@ -3985,7 +4100,7 @@ static void process_state_iv_pps_rnr(t30_state_t *s, const uint8_t *msg, int len
case T30_PRI_MPS:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_MCF);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
if (tx_start_page(s))
{
/* TODO: recover */
@@ -4003,7 +4118,7 @@ static void process_state_iv_pps_rnr(t30_state_t *s, const uint8_t *msg, int len
case T30_EOS:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_MCF);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
t4_tx_release(&(s->t4));
s->operation_in_progress = OPERATION_IN_PROGRESS_NONE;
if (span_log_test(&s->logging, SPAN_LOG_FLOW))
@@ -4017,7 +4132,7 @@ static void process_state_iv_pps_rnr(t30_state_t *s, const uint8_t *msg, int len
case T30_PRI_EOP:
tx_end_page(s);
if (s->phase_d_handler)
- s->phase_d_handler(s, s->phase_d_user_data, T30_MCF);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
t4_tx_release(&(s->t4));
s->operation_in_progress = OPERATION_IN_PROGRESS_NONE;
send_dcn(s);
@@ -4041,7 +4156,7 @@ static void process_state_iv_pps_rnr(t30_state_t *s, const uint8_t *msg, int len
s->retries = 0;
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, T30_PIP);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
break;
@@ -4049,7 +4164,7 @@ static void process_state_iv_pps_rnr(t30_state_t *s, const uint8_t *msg, int len
s->retries = 0;
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, T30_PIN);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
break;
@@ -4073,7 +4188,10 @@ static void process_state_iv_pps_rnr(t30_state_t *s, const uint8_t *msg, int len
static void process_state_iv_ctc(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_CTR:
/* Valid response to a CTC received */
@@ -4100,7 +4218,10 @@ static void process_state_iv_ctc(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_iv_eor(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_RNR:
if (s->timer_t5 == 0)
@@ -4113,7 +4234,7 @@ static void process_state_iv_eor(t30_state_t *s, const uint8_t *msg, int len)
s->retries = 0;
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, T30_PIN);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
break;
@@ -4138,7 +4259,10 @@ static void process_state_iv_eor(t30_state_t *s, const uint8_t *msg, int len)
static void process_state_iv_eor_rnr(t30_state_t *s, const uint8_t *msg, int len)
{
- switch (msg[2] & 0xFE)
+ uint8_t fcf;
+
+ fcf = msg[2] & 0xFE;
+ switch (fcf)
{
case T30_RNR:
if (s->timer_t5 == 0)
@@ -4151,7 +4275,7 @@ static void process_state_iv_eor_rnr(t30_state_t *s, const uint8_t *msg, int len
s->retries = 0;
if (s->phase_d_handler)
{
- s->phase_d_handler(s, s->phase_d_user_data, T30_PIN);
+ s->phase_d_handler(s, s->phase_d_user_data, fcf);
s->timer_t3 = ms_to_samples(DEFAULT_TIMER_T3);
}
break;
@@ -4257,7 +4381,7 @@ static void process_rx_control_msg(t30_state_t *s, const uint8_t *msg, int len)
}
else
{
- unexpected_frame(s, msg, len);
+ unexpected_non_final_frame(s, msg, len);
}
break;
case (T30_SEP & 0xFE):
@@ -4269,7 +4393,7 @@ static void process_rx_control_msg(t30_state_t *s, const uint8_t *msg, int len)
}
else
{
- unexpected_frame(s, msg, len);
+ unexpected_non_final_frame(s, msg, len);
}
break;
case (T30_PSA & 0xFE):
@@ -4280,7 +4404,7 @@ static void process_rx_control_msg(t30_state_t *s, const uint8_t *msg, int len)
}
else
{
- unexpected_frame(s, msg, len);
+ unexpected_non_final_frame(s, msg, len);
}
break;
case (T30_CIA & 0xFE):
@@ -4291,7 +4415,7 @@ static void process_rx_control_msg(t30_state_t *s, const uint8_t *msg, int len)
}
else
{
- unexpected_frame(s, msg, len);
+ unexpected_non_final_frame(s, msg, len);
}
break;
case (T30_ISP & 0xFE):
@@ -4302,7 +4426,7 @@ static void process_rx_control_msg(t30_state_t *s, const uint8_t *msg, int len)
}
else
{
- unexpected_frame(s, msg, len);
+ unexpected_non_final_frame(s, msg, len);
}
break;
case (T30_TSI & 0xFE):
@@ -5956,8 +6080,8 @@ SPAN_DECLARE(void) t30_get_transfer_statistics(t30_state_t *s, t30_stats_t *t)
t->error_correcting_mode = s->error_correcting_mode;
t->error_correcting_mode_retries = s->error_correcting_mode_retries;
t4_get_transfer_statistics(&s->t4, &stats);
- t->pages_tx = s->ecm_tx_page;
- t->pages_rx = s->ecm_rx_page;
+ t->pages_tx = s->tx_page_number;
+ t->pages_rx = s->rx_page_number;
t->pages_in_file = stats.pages_in_file;
t->width = stats.width;
t->length = stats.length;
@@ -5968,6 +6092,10 @@ SPAN_DECLARE(void) t30_get_transfer_statistics(t30_state_t *s, t30_stats_t *t)
t->encoding = stats.encoding;
t->image_size = stats.line_image_size;
t->current_status = s->current_status;
+#if 0
+ t->rtn_events = s->rtn_events;
+ t->rtp_events = s->rtp_events;
+#endif
}
/*- End of function --------------------------------------------------------*/
@@ -6000,9 +6128,13 @@ SPAN_DECLARE(int) t30_restart(t30_state_t *s)
t30_build_dis_or_dtc(s);
memset(&s->rx_info, 0, sizeof(s->rx_info));
release_resources(s);
- /* The ECM page number is only reset at call establishment */
- s->ecm_rx_page = 0;
- s->ecm_tx_page = 0;
+ /* The page number is only reset at call establishment */
+ s->rx_page_number = 0;
+ s->tx_page_number = 0;
+#if 0
+ s->rtn_events = 0;
+ s->rtp_events = 0;
+#endif
s->far_end_detected = FALSE;
s->timer_t0_t1 = ms_to_samples(DEFAULT_TIMER_T0);
if (s->calling_party)
diff --git a/libs/spandsp/src/t31.c b/libs/spandsp/src/t31.c
index c9871a19b2..307a2c38da 100644
--- a/libs/spandsp/src/t31.c
+++ b/libs/spandsp/src/t31.c
@@ -25,7 +25,7 @@
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: t31.c,v 1.151 2009/07/14 13:54:22 steveu Exp $
+ * $Id: t31.c,v 1.152 2009/09/04 14:38:46 steveu Exp $
*/
/*! \file */
@@ -176,12 +176,15 @@ enum
static int restart_modem(t31_state_t *s, int new_modem);
static void hdlc_accept_frame(void *user_data, const uint8_t *msg, int len, int ok);
-static void set_rx_handler(t31_state_t *s, span_rx_handler_t *handler, void *user_data);
+static void set_rx_handler(t31_state_t *s, span_rx_handler_t *rx_handler, span_rx_fillin_handler_t *fillin_handler, void *user_data);
static void set_tx_handler(t31_state_t *s, span_tx_handler_t *handler, void *user_data);
static void set_next_tx_handler(t31_state_t *s, span_tx_handler_t *handler, void *user_data);
static int v17_v21_rx(void *user_data, const int16_t amp[], int len);
+static int v17_v21_rx_fillin(void *user_data, int len);
static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len);
+static int v27ter_v21_rx_fillin(void *user_data, int len);
static int v29_v21_rx(void *user_data, const int16_t amp[], int len);
+static int v29_v21_rx_fillin(void *user_data, int len);
static int silence_rx(void *user_data, const int16_t amp[], int len);
static int cng_rx(void *user_data, const int16_t amp[], int len);
static void non_ecm_put_bit(void *user_data, int bit);
@@ -1527,7 +1530,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
s->at_state.rx_signal_present = FALSE;
s->at_state.rx_trained = FALSE;
s->rx_frame_received = FALSE;
- set_rx_handler(s, (span_rx_handler_t *) &span_dummy_rx, NULL);
+ set_rx_handler(s, (span_rx_handler_t *) &span_dummy_rx, (span_rx_fillin_handler_t *) &span_dummy_rx_fillin, NULL);
use_hdlc = FALSE;
switch (s->modem)
{
@@ -1546,7 +1549,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
/* Do V.21/HDLC receive in parallel. The other end may send its
first message at any time. The CNG tone will continue until
we get a valid preamble. */
- set_rx_handler(s, (span_rx_handler_t *) &cng_rx, s);
+ set_rx_handler(s, (span_rx_handler_t *) &cng_rx, (span_rx_fillin_handler_t *) &span_dummy_rx_fillin, s);
t31_v21_rx(s);
set_tx_handler(s, (span_tx_handler_t *) &modem_connect_tones_tx, &t->connect_tx);
set_next_tx_handler(s, (span_tx_handler_t *) NULL, NULL);
@@ -1559,7 +1562,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
}
else
{
- set_rx_handler(s, (span_rx_handler_t *) &cng_rx, s);
+ set_rx_handler(s, (span_rx_handler_t *) &cng_rx, (span_rx_fillin_handler_t *) &span_dummy_rx_fillin, s);
t31_v21_rx(s);
silence_gen_set(&t->silence_gen, 0);
set_tx_handler(s, (span_tx_handler_t *) &silence_gen, &t->silence_gen);
@@ -1610,7 +1613,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
}
else
{
- set_rx_handler(s, (span_rx_handler_t *) &fsk_rx, &t->v21_rx);
+ set_rx_handler(s, (span_rx_handler_t *) &fsk_rx, (span_rx_fillin_handler_t *) &fsk_rx_fillin, &t->v21_rx);
t31_v21_rx(s);
}
break;
@@ -1652,7 +1655,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
case FAX_MODEM_V17_RX:
if (!s->t38_mode)
{
- set_rx_handler(s, (span_rx_handler_t *) &v17_v21_rx, s);
+ set_rx_handler(s, (span_rx_handler_t *) &v17_v21_rx, (span_rx_fillin_handler_t *) &v17_v21_rx_fillin, s);
v17_rx_restart(&t->v17_rx, s->bit_rate, s->short_train);
/* Allow for +FCERROR/+FRH:3 */
t31_v21_rx(s);
@@ -1689,7 +1692,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
case FAX_MODEM_V27TER_RX:
if (!s->t38_mode)
{
- set_rx_handler(s, (span_rx_handler_t *) &v27ter_v21_rx, s);
+ set_rx_handler(s, (span_rx_handler_t *) &v27ter_v21_rx, (span_rx_fillin_handler_t *) &v27ter_v21_rx_fillin, s);
v27ter_rx_restart(&t->v27ter_rx, s->bit_rate, FALSE);
/* Allow for +FCERROR/+FRH:3 */
t31_v21_rx(s);
@@ -1726,7 +1729,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
case FAX_MODEM_V29_RX:
if (!s->t38_mode)
{
- set_rx_handler(s, (span_rx_handler_t *) &v29_v21_rx, s);
+ set_rx_handler(s, (span_rx_handler_t *) &v29_v21_rx, (span_rx_fillin_handler_t *) &v29_v21_rx_fillin, s);
v29_rx_restart(&t->v29_rx, s->bit_rate, FALSE);
/* Allow for +FCERROR/+FRH:3 */
t31_v21_rx(s);
@@ -1752,7 +1755,7 @@ static int restart_modem(t31_state_t *s, int new_modem)
case FAX_MODEM_SILENCE_RX:
if (!s->t38_mode)
{
- set_rx_handler(s, (span_rx_handler_t *) &silence_rx, s);
+ set_rx_handler(s, (span_rx_handler_t *) &silence_rx, (span_rx_fillin_handler_t *) &span_dummy_rx_fillin, s);
silence_gen_set(&t->silence_gen, 0);
set_tx_handler(s, (span_tx_handler_t *) &silence_gen, &t->silence_gen);
set_next_tx_handler(s, (span_tx_handler_t *) NULL, NULL);
@@ -2113,7 +2116,7 @@ SPAN_DECLARE(int) t31_at_rx(t31_state_t *s, const char *t, int len)
s->at_state.rx_data_bytes = 0;
s->at_state.transmit = FALSE;
s->modem = FAX_MODEM_SILENCE_TX;
- set_rx_handler(s, (span_rx_handler_t *) &span_dummy_rx, NULL);
+ set_rx_handler(s, (span_rx_handler_t *) &span_dummy_rx, (span_rx_fillin_handler_t *) &span_dummy_rx_fillin, NULL);
t31_set_at_rx_mode(s, AT_MODE_OFFHOOK_COMMAND);
at_put_response_code(&s->at_state, AT_RESPONSE_CODE_OK);
}
@@ -2136,9 +2139,13 @@ SPAN_DECLARE(int) t31_at_rx(t31_state_t *s, const char *t, int len)
}
/*- End of function --------------------------------------------------------*/
-static void set_rx_handler(t31_state_t *s, span_rx_handler_t *handler, void *user_data)
+static void set_rx_handler(t31_state_t *s,
+ span_rx_handler_t *rx_handler,
+ span_rx_fillin_handler_t *fillin_handler,
+ void *user_data)
{
- s->audio.modems.rx_handler = handler;
+ s->audio.modems.rx_handler = rx_handler;
+ s->audio.modems.rx_fillin_handler = fillin_handler;
s->audio.modems.rx_user_data = user_data;
}
/*- End of function --------------------------------------------------------*/
@@ -2208,7 +2215,7 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
/* The fast modem has trained, so we no longer need to run the slow
one in parallel. */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.17 (%.2fdBm0)\n", v17_rx_signal_power(&s->v17_rx));
- set_rx_handler(t, (span_rx_handler_t *) &v17_rx, &s->v17_rx);
+ set_rx_handler(t, (span_rx_handler_t *) &v17_rx, (span_rx_fillin_handler_t *) &v17_rx_fillin, &s->v17_rx);
}
else
{
@@ -2218,13 +2225,26 @@ static int v17_v21_rx(void *user_data, const int16_t amp[], int len)
/* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.17 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
- set_rx_handler(t, (span_rx_handler_t *) &fsk_rx, &s->v21_rx);
+ set_rx_handler(t, (span_rx_handler_t *) &fsk_rx, (span_rx_fillin_handler_t *) &fsk_rx_fillin, &s->v21_rx);
}
}
return len;
}
/*- End of function --------------------------------------------------------*/
+static int v17_v21_rx_fillin(void *user_data, int len)
+{
+ t31_state_t *t;
+ fax_modems_state_t *s;
+
+ t = (t31_state_t *) user_data;
+ s = &t->audio.modems;
+ v17_rx_fillin(&s->v17_rx, len);
+ fsk_rx_fillin(&s->v21_rx, len);
+ return 0;
+}
+/*- End of function --------------------------------------------------------*/
+
static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
{
t31_state_t *t;
@@ -2238,7 +2258,7 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
/* The fast modem has trained, so we no longer need to run the slow
one in parallel. */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.27ter (%.2fdBm0)\n", v27ter_rx_signal_power(&s->v27ter_rx));
- set_rx_handler(t, (span_rx_handler_t *) &v27ter_rx, &s->v27ter_rx);
+ set_rx_handler(t, (span_rx_handler_t *) &v27ter_rx, (span_rx_fillin_handler_t *) &v27ter_rx_fillin, &s->v27ter_rx);
}
else
{
@@ -2248,13 +2268,26 @@ static int v27ter_v21_rx(void *user_data, const int16_t amp[], int len)
/* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.27ter + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
- set_rx_handler(t, (span_rx_handler_t *) &fsk_rx, &s->v21_rx);
+ set_rx_handler(t, (span_rx_handler_t *) &fsk_rx, (span_rx_fillin_handler_t *) &fsk_rx_fillin, &s->v21_rx);
}
}
return len;
}
/*- End of function --------------------------------------------------------*/
+static int v27ter_v21_rx_fillin(void *user_data, int len)
+{
+ t31_state_t *t;
+ fax_modems_state_t *s;
+
+ t = (t31_state_t *) user_data;
+ s = &t->audio.modems;
+ v17_rx_fillin(&s->v27ter_rx, len);
+ fsk_rx_fillin(&s->v21_rx, len);
+ return 0;
+}
+/*- End of function --------------------------------------------------------*/
+
static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
{
t31_state_t *t;
@@ -2268,7 +2301,7 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
/* The fast modem has trained, so we no longer need to run the slow
one in parallel. */
span_log(&s->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.29 (%.2fdBm0)\n", v29_rx_signal_power(&s->v29_rx));
- set_rx_handler(t, (span_rx_handler_t *) &v29_rx, &s->v29_rx);
+ set_rx_handler(t, (span_rx_handler_t *) &v29_rx, (span_rx_fillin_handler_t *) &v29_rx_fillin, &s->v29_rx);
}
else
{
@@ -2278,13 +2311,26 @@ static int v29_v21_rx(void *user_data, const int16_t amp[], int len)
/* We have received something, and the fast modem has not trained. We must
be receiving valid V.21 */
span_log(&t->logging, SPAN_LOG_FLOW, "Switching from V.29 + V.21 to V.21 (%.2fdBm0)\n", fsk_rx_signal_power(&s->v21_rx));
- set_rx_handler(t, (span_rx_handler_t *) &fsk_rx, &s->v21_rx);
+ set_rx_handler(t, (span_rx_handler_t *) &fsk_rx, (span_rx_fillin_handler_t *) &fsk_rx_fillin, &s->v21_rx);
}
}
return len;
}
/*- End of function --------------------------------------------------------*/
+static int v29_v21_rx_fillin(void *user_data, int len)
+{
+ t31_state_t *t;
+ fax_modems_state_t *s;
+
+ t = (t31_state_t *) user_data;
+ s = &t->audio.modems;
+ v29_rx_fillin(&s->v29_rx, len);
+ fsk_rx_fillin(&s->v21_rx, len);
+ return 0;
+}
+/*- End of function --------------------------------------------------------*/
+
SPAN_DECLARE(int) t31_rx(t31_state_t *s, int16_t amp[], int len)
{
int i;
diff --git a/libs/spandsp/src/t38_terminal.c b/libs/spandsp/src/t38_terminal.c
index 4ea4dd4579..1e9c70926f 100644
--- a/libs/spandsp/src/t38_terminal.c
+++ b/libs/spandsp/src/t38_terminal.c
@@ -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: t38_terminal.c,v 1.127 2009/07/14 13:54:22 steveu Exp $
+ * $Id: t38_terminal.c,v 1.128 2009/09/04 14:38:46 steveu Exp $
*/
/*! \file */
@@ -93,9 +93,9 @@
enum
{
- T38_CHUNKING_MERGE_FCS_WITH_DATA = 0x0001,
- T38_CHUNKING_WHOLE_FRAMES = 0x0002,
- T38_CHUNKING_ALLOW_TEP_TIME = 0x0004
+ T38_CHUNKING_MERGE_FCS_WITH_DATA = 0x0001,
+ T38_CHUNKING_WHOLE_FRAMES = 0x0002,
+ T38_CHUNKING_ALLOW_TEP_TIME = 0x0004
};
enum
diff --git a/libs/spandsp/tests/Makefile.am b/libs/spandsp/tests/Makefile.am
index 07083318f4..253d398d31 100644
--- a/libs/spandsp/tests/Makefile.am
+++ b/libs/spandsp/tests/Makefile.am
@@ -16,7 +16,7 @@
## along with this program; if not, write to the Free Software
## Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
##
-## $Id: Makefile.am,v 1.116 2009/05/30 15:23:13 steveu Exp $
+## $Id: Makefile.am,v 1.117 2009/09/22 13:11:04 steveu Exp $
AM_CFLAGS = $(COMP_VENDOR_CFLAGS)
AM_LDFLAGS = $(COMP_VENDOR_LDFLAGS)
@@ -99,6 +99,7 @@ noinst_PROGRAMS = adsi_tests \
sig_tone_tests \
super_tone_rx_tests \
super_tone_tx_tests \
+ swept_tone_tests \
t4_tests \
t31_tests \
t38_core_tests \
@@ -273,6 +274,9 @@ super_tone_rx_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR
super_tone_tx_tests_SOURCES = super_tone_tx_tests.c
super_tone_tx_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp
+swept_tone_tests_SOURCES = swept_tone_tests.c
+swept_tone_tests_LDADD = -L$(top_builddir)/spandsp-sim -lspandsp-sim $(LIBDIR) -lspandsp
+
t4_tests_SOURCES = t4_tests.c
t4_tests_LDADD = $(LIBDIR) -lspandsp
diff --git a/libs/spandsp/tests/fax_decode.c b/libs/spandsp/tests/fax_decode.c
index 131244db23..ec5a493f4c 100644
--- a/libs/spandsp/tests/fax_decode.c
+++ b/libs/spandsp/tests/fax_decode.c
@@ -22,7 +22,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: fax_decode.c,v 1.56 2009/05/30 15:23:13 steveu Exp $
+ * $Id: fax_decode.c,v 1.57 2009/09/15 14:01:53 steveu Exp $
*/
/*! \page fax_decode_page FAX decoder
@@ -124,7 +124,7 @@ static void print_frame(const char *io, const uint8_t *fr, int frlen)
type = fr[2] & 0xFE;
if (type == T30_DIS || type == T30_DTC || type == T30_DCS)
t30_decode_dis_dtc_dcs(&t30_dummy, fr, frlen);
- if (type == T30_NSF)
+ if (type == T30_NSF || type == T30_NSS || type == T30_NSC)
{
if (t35_decode(&fr[3], frlen - 3, &country, &vendor, &model))
{
diff --git a/libs/spandsp/tests/line_model_tests.c b/libs/spandsp/tests/line_model_tests.c
index b769e717e6..309e2e7890 100644
--- a/libs/spandsp/tests/line_model_tests.c
+++ b/libs/spandsp/tests/line_model_tests.c
@@ -22,7 +22,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: line_model_tests.c,v 1.27 2009/05/30 15:23:14 steveu Exp $
+ * $Id: line_model_tests.c,v 1.28 2009/09/23 16:02:59 steveu Exp $
*/
/*! \page line_model_tests_page Telephony line model tests
@@ -62,7 +62,7 @@
#define IN_FILE_NAME1 "line_model_test_in1.wav"
#define IN_FILE_NAME2 "line_model_test_in2.wav"
#define OUT_FILE_NAME1 "line_model_one_way_test_out.wav"
-#define OUT_FILE_NAME "line_model_test_out.wav"
+#define OUT_FILE_NAME2 "line_model_two_way_test_out.wav"
int channel_codec;
int rbs_pattern;
@@ -128,10 +128,17 @@ static void test_one_way_model(int line_model_no, int speech_test)
awgn_init_dbm0(&noise1, 1234567, -10.0f);
- if ((inhandle1 = sf_open_telephony_read(IN_FILE_NAME1, 1)) == NULL)
+ if (speech_test)
{
- fprintf(stderr, " Cannot open audio file '%s'\n", IN_FILE_NAME1);
- exit(2);
+ if ((inhandle1 = sf_open_telephony_read(IN_FILE_NAME1, 1)) == NULL)
+ {
+ fprintf(stderr, " Cannot open audio file '%s'\n", IN_FILE_NAME1);
+ exit(2);
+ }
+ }
+ else
+ {
+ inhandle1 = NULL;
}
if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME1, 1)) == NULL)
{
@@ -167,10 +174,13 @@ static void test_one_way_model(int line_model_no, int speech_test)
exit(2);
}
}
- if (sf_close(inhandle1))
+ if (speech_test)
{
- fprintf(stderr, " Cannot close audio file '%s'\n", IN_FILE_NAME1);
- exit(2);
+ if (sf_close(inhandle1))
+ {
+ fprintf(stderr, " Cannot close audio file '%s'\n", IN_FILE_NAME1);
+ exit(2);
+ }
}
if (sf_close(outhandle))
{
@@ -208,19 +218,27 @@ static void test_both_ways_model(int line_model_no, int speech_test)
awgn_init_dbm0(&noise1, 1234567, -10.0f);
awgn_init_dbm0(&noise2, 1234567, -10.0f);
- if ((inhandle1 = sf_open_telephony_read(IN_FILE_NAME1, 1)) == NULL)
+ if (speech_test)
{
- fprintf(stderr, " Cannot open audio file '%s'\n", IN_FILE_NAME1);
- exit(2);
+ if ((inhandle1 = sf_open_telephony_read(IN_FILE_NAME1, 1)) == NULL)
+ {
+ fprintf(stderr, " Cannot open audio file '%s'\n", IN_FILE_NAME1);
+ exit(2);
+ }
+ if ((inhandle2 = sf_open_telephony_read(IN_FILE_NAME2, 1)) == NULL)
+ {
+ fprintf(stderr, " Cannot open audio file '%s'\n", IN_FILE_NAME2);
+ exit(2);
+ }
}
- if ((inhandle2 = sf_open_telephony_read(IN_FILE_NAME2, 1)) == NULL)
+ else
{
- fprintf(stderr, " Cannot open audio file '%s'\n", IN_FILE_NAME2);
- exit(2);
+ inhandle1 =
+ inhandle2 = NULL;
}
- if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME, 2)) == NULL)
+ if ((outhandle = sf_open_telephony_write(OUT_FILE_NAME2, 2)) == NULL)
{
- fprintf(stderr, " Cannot create audio file '%s'\n", OUT_FILE_NAME);
+ fprintf(stderr, " Cannot create audio file '%s'\n", OUT_FILE_NAME2);
exit(2);
}
for (i = 0; i < 10000; i++)
@@ -261,25 +279,80 @@ static void test_both_ways_model(int line_model_no, int speech_test)
exit(2);
}
}
- if (sf_close(inhandle1))
+ if (speech_test)
{
- fprintf(stderr, " Cannot close audio file '%s'\n", IN_FILE_NAME1);
- exit(2);
- }
- if (sf_close(inhandle2))
- {
- fprintf(stderr, " Cannot close audio file '%s'\n", IN_FILE_NAME2);
- exit(2);
+ if (sf_close(inhandle1))
+ {
+ fprintf(stderr, " Cannot close audio file '%s'\n", IN_FILE_NAME1);
+ exit(2);
+ }
+ if (sf_close(inhandle2))
+ {
+ fprintf(stderr, " Cannot close audio file '%s'\n", IN_FILE_NAME2);
+ exit(2);
+ }
}
if (sf_close(outhandle))
{
- fprintf(stderr, " Cannot close audio file '%s'\n", OUT_FILE_NAME);
+ fprintf(stderr, " Cannot close audio file '%s'\n", OUT_FILE_NAME2);
exit(2);
}
both_ways_line_model_release(model);
}
/*- End of function --------------------------------------------------------*/
+static void test_line_filter(int line_model_no)
+{
+ float out;
+ double sumin;
+ double sumout;
+ int i;
+ int j;
+ int p;
+ int ptr;
+ int len;
+ swept_tone_state_t *s;
+ float filter[129];
+ int16_t buf[BLOCK_LEN];
+
+ s = swept_tone_init(NULL, 200.0f, 3900.0f, -10.0f, 120*SAMPLE_RATE, 0);
+ for (j = 0; j < 129; j++)
+ filter[j] = 0.0f;
+ ptr = 0;
+ for (;;)
+ {
+ if ((len = swept_tone(s, buf, BLOCK_LEN)) <= 0)
+ break;
+ sumin = 0.0;
+ sumout = 0.0;
+ for (i = 0; i < len; i++)
+ {
+ /* Add the sample in the filter buffer */
+ p = ptr;
+ filter[p] = buf[i];
+ if (++p == 129)
+ p = 0;
+ ptr = p;
+
+ /* Apply the filter */
+ out = 0.0f;
+ for (j = 0; j < 129; j++)
+ {
+ out += line_models[line_model_no][128 - j]*filter[p];
+ if (++p >= 129)
+ p = 0;
+ }
+ sumin += buf[i]*buf[i];
+ sumout += out*out;
+ }
+ /*endfor*/
+ printf("%7.1f %f\n", swept_tone_current_frequency(s), 10.0*log10(sumout/sumin));
+ }
+ /*endfor*/
+ swept_tone_free(s);
+}
+/*- End of function --------------------------------------------------------*/
+
int main(int argc, char *argv[])
{
int line_model_no;
@@ -319,6 +392,7 @@ int main(int argc, char *argv[])
complexify_tests();
test_one_way_model(line_model_no, speech_test);
test_both_ways_model(line_model_no, speech_test);
+ test_line_filter(line_model_no);
}
/*- End of function --------------------------------------------------------*/
/*- End of file ------------------------------------------------------------*/
diff --git a/libs/spandsp/tests/regression_tests.sh b/libs/spandsp/tests/regression_tests.sh
index 4f77c9c54a..efd02619fb 100755
--- a/libs/spandsp/tests/regression_tests.sh
+++ b/libs/spandsp/tests/regression_tests.sh
@@ -17,7 +17,7 @@
# License along with this program; if not, write to the Free Software
# Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
#
-# $Id: regression_tests.sh,v 1.58 2009/05/19 14:47:02 steveu Exp $
+# $Id: regression_tests.sh,v 1.59 2009/09/22 13:28:18 steveu Exp $
#
ITUTESTS_TIF=../test-data/itu/fax/itutests.tif
@@ -468,6 +468,16 @@ echo super_tone_rx_tests not enabled
#echo super_tone_tx_tests completed OK
echo super_tone_tx_tests not enabled
+#./swept_tone_tests >$STDOUT_DEST 2>$STDERR_DEST
+#RETVAL=$?
+#if [ $RETVAL != 0 ]
+#then
+# echo swept_tone_tests failed!
+# exit $RETVAL
+#fi
+#echo swept_tone_tests completed OK
+echo swept_tone_tests not enabled
+
./t31_tests -r >$STDOUT_DEST 2>$STDERR_DEST
RETVAL=$?
if [ $RETVAL != 0 ]
diff --git a/libs/spandsp/tests/sig_tone_tests.c b/libs/spandsp/tests/sig_tone_tests.c
index e795fc87f9..e2afea4a3d 100644
--- a/libs/spandsp/tests/sig_tone_tests.c
+++ b/libs/spandsp/tests/sig_tone_tests.c
@@ -22,7 +22,7 @@
* along with this program; if not, write to the Free Software
* Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
- * $Id: sig_tone_tests.c,v 1.25 2009/05/30 15:23:14 steveu Exp $
+ * $Id: sig_tone_tests.c,v 1.27 2009/09/23 16:02:59 steveu Exp $
*/
/*! \file */
@@ -58,112 +58,97 @@
static int sampleno = 0;
static int tone_1_present = 0;
static int tone_2_present = 0;
-static int ping = 0;
+static int tx_section = 0;
+static int dial_pulses = 0;
-void map_frequency_response(sig_tone_rx_state_t *s);
-
-static int tx_handler(void *user_data, int what)
+static void tx_handler(void *user_data, int what, int level, int duration)
{
- //printf("What - %d\n", what);
- if ((what & SIG_TONE_UPDATE_REQUEST))
+ sig_tone_tx_state_t *s;
+
+ s = (sig_tone_tx_state_t *) user_data;
+ //printf("What - %d, duration - %d\n", what, duration);
+ if ((what & SIG_TONE_TX_UPDATE_REQUEST))
{
printf("Tx: update request\n");
- /* The signaling processor wants to know what to do next */
- if (sampleno < ms_to_samples(100))
+ /* The sig tone transmit side wants to know what to do next */
+ switch (tx_section)
{
- /* 100ms off-hook */
- printf("100ms off-hook - %d samples\n", 800 - sampleno);
- return 0x02 | ((ms_to_samples(100) - sampleno) << 16);
- }
- else if (sampleno < ms_to_samples(600))
- {
- /* 500ms idle */
- printf("500ms idle - %d samples\n", ms_to_samples(600) - sampleno);
- return 0x02 | SIG_TONE_1_PRESENT | ((ms_to_samples(600) - sampleno) << 16);
- }
- else if (sampleno < ms_to_samples(700))
- {
- /* 100ms seize */
- printf("100ms seize - %d samples\n", ms_to_samples(700) - sampleno);
- return 0x02 | ((ms_to_samples(700) - sampleno) << 16);
- }
- else if (sampleno < ms_to_samples(1700))
- {
- if (ping)
- {
- printf("33ms break - %d samples\n", ms_to_samples(33));
- ping = !ping;
- return 0x02 | (ms_to_samples(33) << 16);
- }
+ case 0:
+ printf("33ms break - %d samples\n", ms_to_samples(33));
+ tx_section++;
+ sig_tone_tx_set_mode(s, SIG_TONE_1_PRESENT, ms_to_samples(33));
+ break;
+ case 1:
+ printf("67ms make - %d samples\n", ms_to_samples(67));
+ if (++dial_pulses == 9)
+ tx_section++;
else
- {
- printf("67ms make - %d samples\n", ms_to_samples(67));
- ping = !ping;
- return 0x02 | SIG_TONE_1_PRESENT | (ms_to_samples(67) << 16);
- }
- /*endif*/
+ tx_section--;
+ sig_tone_tx_set_mode(s, 0, ms_to_samples(67));
+ break;
+ case 2:
+ tx_section++;
+ sig_tone_tx_set_mode(s, SIG_TONE_1_PRESENT, ms_to_samples(600));
+ break;
+ case 3:
+ sig_tone_tx_set_mode(s, SIG_TONE_1_PRESENT | SIG_TONE_TX_PASSTHROUGH, 0);
+ break;
}
- else
- {
- return 0x02 | SIG_TONE_1_PRESENT | ((ms_to_samples(700) - sampleno) << 16) | SIG_TONE_TX_PASSTHROUGH;
- }
- /*endif*/
+ /*endswitch*/
}
/*endif*/
- return 0;
}
/*- End of function --------------------------------------------------------*/
-static int rx_handler(void *user_data, int what)
+static void rx_handler(void *user_data, int what, int level, int duration)
{
- //printf("What - %d\n", what);
+ float ms;
+
+ ms = 1000.0f*(float) duration/(float) SAMPLE_RATE;
+ printf("What - %d, duration - %d\n", what, duration);
if ((what & SIG_TONE_1_CHANGE))
{
tone_1_present = what & SIG_TONE_1_PRESENT;
- printf("Rx: tone 1 is %s after %d samples\n", (tone_1_present) ? "on" : "off", (what >> 16) & 0xFFFF);
+ printf("Rx: tone 1 is %s after %d samples (%fms)\n", (tone_1_present) ? "on" : "off", duration, ms);
}
/*endif*/
if ((what & SIG_TONE_2_CHANGE))
{
tone_2_present = what & SIG_TONE_2_PRESENT;
- printf("Rx: tone 2 is %s after %d samples\n", (tone_2_present) ? "on" : "off", (what >> 16) & 0xFFFF);
+ printf("Rx: tone 2 is %s after %d samples (%fms)\n", (tone_2_present) ? "on" : "off", duration, ms);
}
/*endif*/
- return 0;
}
/*- End of function --------------------------------------------------------*/
-void map_frequency_response(sig_tone_rx_state_t *s)
+static void map_frequency_response(sig_tone_rx_state_t *s)
{
int16_t buf[8192];
- awgn_state_t noise_source;
int i;
- int f;
- uint32_t phase_acc;
- int32_t phase_rate;
- int32_t scaling;
- double sum;
+ int len;
+ double sumin;
+ double sumout;
+ swept_tone_state_t *swept;
/* Things like noise don't highlight the frequency response of the high Q notch
very well. We use a slowly swept frequency to check it. */
- awgn_init_dbm0(&noise_source, 1234567, -10.0f);
- for (f = 1; f < 4000; f++)
+ swept = swept_tone_init(NULL, 200.0f, 3900.0f, -10.0f, 120*SAMPLE_RATE, 0);
+ for (;;)
{
- phase_rate = dds_phase_rate(f);
- scaling = dds_scaling_dbm0(-10);
- phase_acc = 0;
- for (i = 0; i < 8192; i++)
- buf[i] = dds_mod(&phase_acc, phase_rate, scaling, 0);
+ if ((len = swept_tone(swept, buf, SAMPLES_PER_CHUNK)) <= 0)
+ break;
+ sumin = 0.0;
+ for (i = 0; i < len; i++)
+ sumin += (double) buf[i]*(double) buf[i];
+ sig_tone_rx(s, buf, len);
+ sumout = 0.0;
+ for (i = 0; i < len; i++)
+ sumout += (double) buf[i]*(double) buf[i];
/*endfor*/
- sig_tone_rx(s, buf, 8192);
- sum = 0.0;
- for (i = 1000; i < 8192; i++)
- sum += (double) buf[i]*(double) buf[i];
- /*endfor*/
- sum = sqrt(sum);
- printf("%7d %f\n", f, sum);
+ printf("%7.1f %f\n", swept_tone_current_frequency(swept), 10.0*log10(sumout/sumin));
}
/*endfor*/
+ swept_tone_free(swept);
}
/*- End of function --------------------------------------------------------*/
@@ -189,45 +174,56 @@ int main(int argc, char *argv[])
}
/*endif*/
- awgn_init_dbm0(&noise_source, 1234567, -10.0f);
+ awgn_init_dbm0(&noise_source, 1234567, -20.0f);
for (type = 1; type <= 3; type++)
{
sampleno = 0;
tone_1_present = 0;
tone_2_present = 0;
- ping = 0;
+ tx_section = 0;
munge = NULL;
switch (type)
{
case 1:
printf("2280Hz tests.\n");
munge = codec_munge_init(MUNGE_CODEC_ALAW, 0);
- sig_tone_tx_init(&tx_state, SIG_TONE_2280HZ, tx_handler, NULL);
- sig_tone_rx_init(&rx_state, SIG_TONE_2280HZ, rx_handler, NULL);
+ sig_tone_tx_init(&tx_state, SIG_TONE_2280HZ, tx_handler, &tx_state);
+ sig_tone_rx_init(&rx_state, SIG_TONE_2280HZ, rx_handler, &rx_state);
rx_state.current_rx_tone |= SIG_TONE_RX_PASSTHROUGH;
break;
case 2:
- printf("26000Hz tests.\n");
+ printf("2600Hz tests.\n");
munge = codec_munge_init(MUNGE_CODEC_ULAW, 0);
- sig_tone_tx_init(&tx_state, SIG_TONE_2600HZ, tx_handler, NULL);
- sig_tone_rx_init(&rx_state, SIG_TONE_2600HZ, rx_handler, NULL);
+ sig_tone_tx_init(&tx_state, SIG_TONE_2600HZ, tx_handler, &tx_state);
+ sig_tone_rx_init(&rx_state, SIG_TONE_2600HZ, rx_handler, &rx_state);
rx_state.current_rx_tone |= SIG_TONE_RX_PASSTHROUGH;
break;
case 3:
- printf("2400Hz/26000Hz tests.\n");
+ printf("2400Hz/2600Hz tests.\n");
munge = codec_munge_init(MUNGE_CODEC_ULAW, 0);
- sig_tone_tx_init(&tx_state, SIG_TONE_2400HZ_2600HZ, tx_handler, NULL);
- sig_tone_rx_init(&rx_state, SIG_TONE_2400HZ_2600HZ, rx_handler, NULL);
+ sig_tone_tx_init(&tx_state, SIG_TONE_2400HZ_2600HZ, tx_handler, &tx_state);
+ sig_tone_rx_init(&rx_state, SIG_TONE_2400HZ_2600HZ, rx_handler, &rx_state);
rx_state.current_rx_tone |= SIG_TONE_RX_PASSTHROUGH;
break;
}
/*endswitch*/
-
- //map_frequency_response(&rx_state);
+ /* Set to the default of hook condition */
+ sig_tone_rx_set_mode(&rx_state, SIG_TONE_RX_PASSTHROUGH | SIG_TONE_RX_FILTER_TONE, 0);
+ sig_tone_tx_set_mode(&tx_state, SIG_TONE_1_PRESENT | SIG_TONE_2_PRESENT | SIG_TONE_TX_PASSTHROUGH, 0);
- for (sampleno = 0; sampleno < 20000; sampleno += SAMPLES_PER_CHUNK)
+ map_frequency_response(&rx_state);
+
+ sig_tone_rx_set_mode(&rx_state, SIG_TONE_RX_PASSTHROUGH, 0);
+ for (sampleno = 0; sampleno < 30000; sampleno += SAMPLES_PER_CHUNK)
{
+ if (sampleno == 8000)
+ {
+ /* 100ms seize */
+ printf("100ms seize - %d samples\n", ms_to_samples(100));
+ dial_pulses = 0;
+ sig_tone_tx_set_mode(&tx_state, 0, ms_to_samples(100));
+ }
for (i = 0; i < SAMPLES_PER_CHUNK; i++)
amp[i] = awgn(&noise_source);
/*endfor*/
diff --git a/libs/spandsp/tests/swept_tone_tests.c b/libs/spandsp/tests/swept_tone_tests.c
new file mode 100644
index 0000000000..010fbcd3d5
--- /dev/null
+++ b/libs/spandsp/tests/swept_tone_tests.c
@@ -0,0 +1,101 @@
+/*
+ * SpanDSP - a series of DSP components for telephony
+ *
+ * swept_tone_tests.c
+ *
+ * Written by Steve Underwood
+ *
+ * Copyright (C) 2009 Steve Underwood
+ *
+ * All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2, as
+ * published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+ *
+ * $Id: swept_tone_tests.c,v 1.2 2009/09/22 13:28:18 steveu Exp $
+ */
+
+/*! \file */
+
+#if defined(HAVE_CONFIG_H)
+#include "config.h"
+#endif
+
+#include
+#include
+#include
+#include
+#include
+
+#include "spandsp.h"
+#include "spandsp-sim.h"
+
+#define OUTPUT_FILE_NAME "swept_tone.wav"
+
+#define BLOCK_LEN 160
+
+int main(int argc, char *argv[])
+{
+ int i;
+ int j;
+ int outframes;
+ int len;
+ SNDFILE *outhandle;
+ power_meter_t meter;
+ swept_tone_state_t *s;
+ int16_t buf[BLOCK_LEN];
+
+ power_meter_init(&meter, 10);
+
+ if ((outhandle = sf_open_telephony_write(OUTPUT_FILE_NAME, 1)) == NULL)
+ {
+ fprintf(stderr, " Cannot create audio file '%s'\n", OUTPUT_FILE_NAME);
+ exit(2);
+ }
+
+ printf("Test with swept tone.\n");
+ s = swept_tone_init(NULL, 200.0f, 3900.0f, -10.0f, 60*SAMPLE_RATE, 1);
+ for (j = 0; j < 60*SAMPLE_RATE; j += BLOCK_LEN)
+ {
+ len = swept_tone(s, buf, BLOCK_LEN);
+ for (i = 0; i < len; i++)
+ power_meter_update(&meter, buf[i]);
+ outframes = sf_writef_short(outhandle, buf, len);
+ if (outframes != len)
+ {
+ fprintf(stderr, " Error writing audio file\n");
+ exit(2);
+ }
+#if 0
+ printf("Current freq %.1fHz, Level is %fdBOv/%fdBm0\n",
+ swept_tone_current_frequency(s),
+ power_meter_current_dbov(&meter),
+ power_meter_current_dbm0(&meter));
+#else
+ printf("%.1f %f\n",
+ swept_tone_current_frequency(s),
+ power_meter_current_dbm0(&meter));
+#endif
+ }
+
+ if (sf_close(outhandle) != 0)
+ {
+ fprintf(stderr, " Cannot close audio file '%s'\n", OUTPUT_FILE_NAME);
+ exit(2);
+ }
+
+ printf("Tests passed.\n");
+ return 0;
+}
+/*- End of function --------------------------------------------------------*/
+/*- End of file ------------------------------------------------------------*/